AMP for WP – Accelerated Mobile Pages - Version 0.9.97.2

Version Description

(29th June 2018)

Download this release

Release Info

Developer mohammed_kaludi
Plugin Icon 128x128 AMP for WP – Accelerated Mobile Pages
Version 0.9.97.2
Comparing to
See all releases

Code changes from version 0.9.97.1 to 0.9.97.2

Files changed (28) hide show
  1. README.md +6 -1
  2. accelerated-moblie-pages.php +2 -2
  3. components/post-pagination/post-pagination.php +0 -22
  4. images/feature-1.png +0 -0
  5. images/layouts-7.png +0 -0
  6. images/layouts-8.png +0 -0
  7. images/layouts-9.png +0 -0
  8. images/wpf.png +0 -0
  9. includes/amp-consent/consent.php +3 -0
  10. includes/options/admin-config.php +21 -28
  11. includes/options/extensions/checkbox_hierarchy/checkbox_hierarchy/field_checkbox_hierarchy.css +1 -0
  12. includes/options/extensions/checkbox_hierarchy/checkbox_hierarchy/field_checkbox_hierarchy.js +54 -0
  13. includes/options/extensions/checkbox_hierarchy/checkbox_hierarchy/field_checkbox_hierarchy.min.js +1 -0
  14. includes/options/extensions/checkbox_hierarchy/checkbox_hierarchy/field_checkbox_hierarchy.php +210 -0
  15. includes/options/extensions/checkbox_hierarchy/checkbox_hierarchy/field_checkbox_hierarchy.scss +13 -0
  16. includes/options/extensions/checkbox_hierarchy/extension_checkbox_hierarchy.php +110 -0
  17. includes/vendor/amp/includes/embeds/class-amp-wistia-embed.php +103 -0
  18. includes/vendor/amp/includes/sanitizers/class-amp-allowed-tags-generated.php +10776 -0
  19. includes/vendor/amp/includes/sanitizers/class-amp-rule-spec.php +154 -0
  20. includes/vendor/amp/includes/sanitizers/class-amp-tag-and-attribute-sanitizer.php +1643 -0
  21. pagebuilder/modules/adsense-ad-module.php +77 -0
  22. pagebuilder/modules/code-module.php +58 -0
  23. pagebuilder/modules/contact-form-shortcode-module.php +169 -0
  24. readme.txt +6 -1
  25. templates/design-manager/design-1/elements/content.php +0 -13
  26. templates/design-manager/design-2/elements/content.php +1 -13
  27. templates/design-manager/design-3/elements/content.php +1 -13
  28. templates/features.php +84 -84
README.md CHANGED
@@ -4,7 +4,7 @@ Tags: AMP, accelerated mobile pages, mobile, amp project, google amp, amp wp, go
4
  Donate link: https://www.paypal.me/Kaludi/25
5
  Requires at least: 3.0
6
  Tested up to: 4.9.5
7
- Stable tag: 0.9.97.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -183,6 +183,11 @@ You can contact us from [here](https://ampforwp.com/contact/)
183
 
184
  == Changelog ==
185
 
 
 
 
 
 
186
  = 0.9.96.1 (21st June 2018) =
187
  * Fixed: Pagination on Homepage and Archive pages not working for some cases.
188
 
4
  Donate link: https://www.paypal.me/Kaludi/25
5
  Requires at least: 3.0
6
  Tested up to: 4.9.5
7
+ Stable tag: 0.9.97.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
183
 
184
  == Changelog ==
185
 
186
+ = 0.9.97.2 (29th June 2018) =
187
+ * Fixed: GDPR not wroking properly for NON EU countries.
188
+ * Fixed: no-index in robot meta reporting an error in Search Console.
189
+ * Fixed: 2nd page or more blank in Post Pagination.
190
+
191
  = 0.9.96.1 (21st June 2018) =
192
  * Fixed: Pagination on Homepage and Archive pages not working for some cases.
193
 
accelerated-moblie-pages.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Accelerated Mobile Pages
4
  Plugin URI: https://wordpress.org/plugins/accelerated-mobile-pages/
5
  Description: AMP for WP - Accelerated Mobile Pages for WordPress
6
- Version: 0.9.97.1
7
  Author: Ahmed Kaludi, Mohammed Kaludi
8
  Author URI: https://ampforwp.com/
9
  Donate link: https://www.paypal.me/Kaludi/25
@@ -19,7 +19,7 @@ define('AMPFORWP_PLUGIN_DIR_URI', plugin_dir_url(__FILE__));
19
  define('AMPFORWP_DISQUS_URL',plugin_dir_url(__FILE__).'includes/disqus.html');
20
  define('AMPFORWP_IMAGE_DIR',plugin_dir_url(__FILE__).'images');
21
  define('AMPFORWP_MAIN_PLUGIN_DIR', plugin_dir_path( __DIR__ ) );
22
- define('AMPFORWP_VERSION','0.9.97.1');
23
 
24
  // any changes to AMP_QUERY_VAR should be refelected here
25
  function ampforwp_generate_endpoint(){
3
  Plugin Name: Accelerated Mobile Pages
4
  Plugin URI: https://wordpress.org/plugins/accelerated-mobile-pages/
5
  Description: AMP for WP - Accelerated Mobile Pages for WordPress
6
+ Version: 0.9.97.2
7
  Author: Ahmed Kaludi, Mohammed Kaludi
8
  Author URI: https://ampforwp.com/
9
  Donate link: https://www.paypal.me/Kaludi/25
19
  define('AMPFORWP_DISQUS_URL',plugin_dir_url(__FILE__).'includes/disqus.html');
20
  define('AMPFORWP_IMAGE_DIR',plugin_dir_url(__FILE__).'images');
21
  define('AMPFORWP_MAIN_PLUGIN_DIR', plugin_dir_path( __DIR__ ) );
22
+ define('AMPFORWP_VERSION','0.9.97.2');
23
 
24
  // any changes to AMP_QUERY_VAR should be refelected here
25
  function ampforwp_generate_endpoint(){
components/post-pagination/post-pagination.php CHANGED
@@ -157,25 +157,3 @@ function amp_paginated_post_rel_canonical(){
157
  if($post_paginated_page){?>
158
  <link rel="canonical" href="<?php echo $new_canonical_url.$post_paginated_page ?>/" /><?php }
159
  }
160
-
161
- add_filter('ampforwp_modify_the_content','ampforwp_post_paginated_content');
162
- function ampforwp_post_paginated_content($content){
163
- global $redux_builder_amp;
164
- $ampforwp_new_content = $ampforwp_the_content = $checker = '';
165
- $ampforwp_the_content = $content;
166
- $checker = preg_match('/<!--nextpage-->/', $ampforwp_the_content);
167
- if ( 1 === $checker ) {
168
- $ampforwp_new_content = explode('<!--nextpage-->', $ampforwp_the_content);
169
- $queried_var = get_query_var('page');
170
- if ( $queried_var > 1 ) {
171
- $queried_var = $queried_var -1 ;
172
- }
173
- else {
174
- $queried_var = 0;
175
- }
176
- return $ampforwp_new_content[$queried_var];
177
- }
178
- else {
179
- return $ampforwp_the_content;
180
- }
181
- }
157
  if($post_paginated_page){?>
158
  <link rel="canonical" href="<?php echo $new_canonical_url.$post_paginated_page ?>/" /><?php }
159
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
images/feature-1.png ADDED
Binary file
images/layouts-7.png ADDED
Binary file
images/layouts-8.png ADDED
Binary file
images/layouts-9.png ADDED
Binary file
images/wpf.png ADDED
Binary file
includes/amp-consent/consent.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php
2
+ echo '{"promptIfUnknown": true}' ;
3
+ ?>
includes/options/admin-config.php CHANGED
@@ -1788,8 +1788,15 @@ Redux::setArgs( "redux_builder_amp", $args );
1788
  'title' => __('Advanced Indexing', 'accelerated-mobile-pages'),
1789
  'indent' => true,
1790
  'layout_type' => 'accordion',
1791
- 'accordion-open'=> 0,
1792
  ),
 
 
 
 
 
 
 
1793
  array(
1794
  'id' => 'ampforwp-robots-archive-sub-pages-sitewide',
1795
  'type' => 'switch',
@@ -1797,7 +1804,8 @@ Redux::setArgs( "redux_builder_amp", $args );
1797
  'tooltip-subtitle' => __("Such as /page/2 so on and so forth",'accelerated-mobile-pages'),
1798
  'default' => 0,
1799
  'on' => 'index',
1800
- 'off' => 'noindex'
 
1801
  ),
1802
  array(
1803
  'id' => 'ampforwp-robots-archive-author-pages',
@@ -1806,7 +1814,8 @@ Redux::setArgs( "redux_builder_amp", $args );
1806
  'tooltip-subtitle' => __("Enable it to set Indexing for Author Archives",'accelerated-mobile-pages'),
1807
  'default' => 1,
1808
  'on' => 'index',
1809
- 'off' => 'noindex'
 
1810
 
1811
  ),
1812
  array(
@@ -1816,7 +1825,8 @@ Redux::setArgs( "redux_builder_amp", $args );
1816
  'tooltip-subtitle' => __("Enable it to set Indexing for Date Archives",'accelerated-mobile-pages'),
1817
  'default' => 1,
1818
  'on' => 'index',
1819
- 'off' => 'noindex'
 
1820
 
1821
  ),
1822
  array(
@@ -1826,7 +1836,8 @@ Redux::setArgs( "redux_builder_amp", $args );
1826
  'tooltip-subtitle' => __("Enable it to set Indexing for Categories",'accelerated-mobile-pages'),
1827
  'default' => 1,
1828
  'on' => 'index',
1829
- 'off' => 'noindex'
 
1830
  ),
1831
  array(
1832
  'id' => 'ampforwp-robots-archive-tag-pages',
@@ -1835,7 +1846,8 @@ Redux::setArgs( "redux_builder_amp", $args );
1835
  'tooltip-subtitle' => __("Enable it to set Indexing for Tags",'accelerated-mobile-pages'),
1836
  'default' => 1,
1837
  'on' => 'index',
1838
- 'off' => 'noindex'
 
1839
  ),
1840
 
1841
 
@@ -2510,6 +2522,7 @@ function ampforwp_add_sd_fields($fields){
2510
  'indent' => true,
2511
  'layout_type' => 'accordion',
2512
  'accordion-open'=> 1,
 
2513
  ),
2514
 
2515
  array(
@@ -2520,6 +2533,7 @@ function ampforwp_add_sd_fields($fields){
2520
  'tooltip-subtitle' => __('Show notifications on all of your AMP pages for cookie purposes, or anything else.', 'accelerated-mobile-pages'),
2521
  'true' => 'Enabled',
2522
  'false' => 'Disabled',
 
2523
  ),
2524
  array(
2525
  'class' => 'child_opt child_opt_arrow',
@@ -2553,28 +2567,7 @@ function ampforwp_add_sd_fields($fields){
2553
  'type' => 'switch',
2554
  'title' => __('GDPR Compliancy', 'accelerated-mobile-pages'),
2555
  'default' => 0,
2556
- ),
2557
- array(
2558
- 'class' => 'child_opt',
2559
- 'id' =>'audience-for-amp-gdpr-compliance',
2560
- 'type' => 'select',
2561
- 'title' => __('GDPR Visibility', 'accelerated-mobile-pages'),
2562
- 'tooltip-subtitle' => __('Select the option to which you want to display GDPR. ', 'accelerated-mobile-pages'),
2563
- 'options' => array('1' => 'Globally',
2564
- '2' => 'For European Union',
2565
- '3' => 'Handpicked EU Countries'
2566
- ),
2567
- 'default' => 2,
2568
- 'required' => array('amp-gdpr-compliance-switch', '=' , '1'),
2569
- ),
2570
- array(
2571
- 'class' => 'child_opt',
2572
- 'id' =>'amp-gdpr-compliance-privacy-geo-location',
2573
- 'type' => 'checkbox',
2574
- 'title' => __('Select Countries for GDPR', 'accelerated-mobile-pages'),'tooltip-subtitle' => __('Select the Countries to which you want to display GDPR, If checked None it displayed for all EU countries. ', 'accelerated-mobile-pages'),
2575
- 'default' => 0,
2576
- 'options' => $eu_iso_codes,
2577
- 'required' => array('audience-for-amp-gdpr-compliance', '=' , '3'),
2578
  ),
2579
  array(
2580
  'id' => 'gdpr-type',
1788
  'title' => __('Advanced Indexing', 'accelerated-mobile-pages'),
1789
  'indent' => true,
1790
  'layout_type' => 'accordion',
1791
+ 'accordion-open'=> 1,
1792
  ),
1793
+ array(
1794
+ 'id' => 'amp-inspection-tool',
1795
+ 'type' => 'switch',
1796
+ 'title' => __('URL Inspection Tool Compatibility', 'accelerated-mobile-pages'),
1797
+ 'tooltip-subtitle' => __("You can read about it <a target='_blank' href='https://webmasters.googleblog.com/2018/06/new-url-inspection-tool-more-in-search.html'>here</a>",'accelerated-mobile-pages'),
1798
+ 'default' => 1,
1799
+ ),
1800
  array(
1801
  'id' => 'ampforwp-robots-archive-sub-pages-sitewide',
1802
  'type' => 'switch',
1804
  'tooltip-subtitle' => __("Such as /page/2 so on and so forth",'accelerated-mobile-pages'),
1805
  'default' => 0,
1806
  'on' => 'index',
1807
+ 'off' => 'noindex',
1808
+ 'required' => array('amp-inspection-tool', '=' , '0'),
1809
  ),
1810
  array(
1811
  'id' => 'ampforwp-robots-archive-author-pages',
1814
  'tooltip-subtitle' => __("Enable it to set Indexing for Author Archives",'accelerated-mobile-pages'),
1815
  'default' => 1,
1816
  'on' => 'index',
1817
+ 'off' => 'noindex',
1818
+ 'required' => array('amp-inspection-tool', '=' , '0'),
1819
 
1820
  ),
1821
  array(
1825
  'tooltip-subtitle' => __("Enable it to set Indexing for Date Archives",'accelerated-mobile-pages'),
1826
  'default' => 1,
1827
  'on' => 'index',
1828
+ 'off' => 'noindex',
1829
+ 'required' => array('amp-inspection-tool', '=' , '0'),
1830
 
1831
  ),
1832
  array(
1836
  'tooltip-subtitle' => __("Enable it to set Indexing for Categories",'accelerated-mobile-pages'),
1837
  'default' => 1,
1838
  'on' => 'index',
1839
+ 'off' => 'noindex',
1840
+ 'required' => array('amp-inspection-tool', '=' , '0'),
1841
  ),
1842
  array(
1843
  'id' => 'ampforwp-robots-archive-tag-pages',
1846
  'tooltip-subtitle' => __("Enable it to set Indexing for Tags",'accelerated-mobile-pages'),
1847
  'default' => 1,
1848
  'on' => 'index',
1849
+ 'off' => 'noindex',
1850
+ 'required' => array('amp-inspection-tool', '=' , '0'),
1851
  ),
1852
 
1853
 
2522
  'indent' => true,
2523
  'layout_type' => 'accordion',
2524
  'accordion-open'=> 1,
2525
+ 'required' => array('amp-gdpr-compliance-switch', '=' , '0')
2526
  ),
2527
 
2528
  array(
2533
  'tooltip-subtitle' => __('Show notifications on all of your AMP pages for cookie purposes, or anything else.', 'accelerated-mobile-pages'),
2534
  'true' => 'Enabled',
2535
  'false' => 'Disabled',
2536
+ 'required' => array('amp-gdpr-compliance-switch', '=' , '0')
2537
  ),
2538
  array(
2539
  'class' => 'child_opt child_opt_arrow',
2567
  'type' => 'switch',
2568
  'title' => __('GDPR Compliancy', 'accelerated-mobile-pages'),
2569
  'default' => 0,
2570
+ 'tooltip-subtitle' => 'Currently It is available to only EEA countries. Check <a href="https://github.com/ampproject/amphtml/blob/master/extensions/amp-geo/0.1/amp-geo-presets.js" target="_blank">here</a> for the list of EEA Countries'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2571
  ),
2572
  array(
2573
  'id' => 'gdpr-type',
includes/options/extensions/checkbox_hierarchy/checkbox_hierarchy/field_checkbox_hierarchy.css ADDED
@@ -0,0 +1 @@
 
1
+ .redux-container-checkbox_hierarchy label{vertical-align:top;width:100%}.redux-container-checkbox_hierarchy label .field-desc{margin-top:0;float:left;width:93%;clear:none}.redux-container-checkbox_hierarchy ul.inner-child{padding-left:25px;}
includes/options/extensions/checkbox_hierarchy/checkbox_hierarchy/field_checkbox_hierarchy.js ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Redux Checkbox
3
+ * Dependencies : jquery
4
+ * Feature added by : Dovy Paukstys
5
+ * Date : 17 June 2014
6
+ */
7
+
8
+ /*global redux_change, wp, redux*/
9
+
10
+ (function( $ ) {
11
+ "use strict";
12
+ redux.field_objects = redux.field_objects || {};
13
+ redux.field_objects.checkbox_hierarchy = redux.field_objects.checkbox_hierarchy || {};
14
+
15
+ $( document ).ready(
16
+ function() {
17
+ redux.field_objects.checkbox_hierarchy.init();
18
+ }
19
+ );
20
+
21
+ redux.field_objects.checkbox_hierarchy.init = function( selector ) {
22
+ if ( !selector ) {
23
+ selector = $( document ).find( ".redux-group-tab:visible" ).find( '.redux-container-checkbox_hierarchy:visible' );
24
+ }
25
+
26
+ $( selector ).each(
27
+ function() {
28
+ var el = $( this );
29
+ var parent = el;
30
+ if ( !el.hasClass( 'redux-field-container' ) ) {
31
+ parent = el.parents( '.redux-field-container:first' );
32
+ }
33
+ if ( parent.is( ":hidden" ) ) { // Skip hidden fields
34
+ return;
35
+ }
36
+ if ( parent.hasClass( 'redux-field-init' ) ) {
37
+ parent.removeClass( 'redux-field-init' );
38
+ } else {
39
+ return;
40
+ }
41
+ el.find( '.checkbox' ).on(
42
+ 'click', function( e ) {
43
+ var val = 0;
44
+ if ( $( this ).is( ':checked' ) ) {
45
+ val = $( this ).parent().find( '.checkbox-check' ).attr( 'data-val' );
46
+ }
47
+ $( this ).parent().find( '.checkbox-check' ).val( val );
48
+ redux_change( $( this ) );
49
+ }
50
+ );
51
+ }
52
+ );
53
+ };
54
+ })( jQuery );
includes/options/extensions/checkbox_hierarchy/checkbox_hierarchy/field_checkbox_hierarchy.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){"use strict";redux.field_objects=redux.field_objects||{},redux.field_objects.checkbox_hierarchy=redux.field_objects.checkbox_hierarchy||{},e(document).ready(function(){redux.field_objects.checkbox_hierarchy.init()}),redux.field_objects.checkbox_hierarchy.init=function(i){i||(i=e(document).find(".redux-group-tab:visible").find(".redux-container-checkbox_hierarchy:visible")),e(i).each(function(){var i=e(this),c=i;i.hasClass("redux-field-container")||(c=i.parents(".redux-field-container:first")),c.is(":hidden")||c.hasClass("redux-field-init")&&(c.removeClass("redux-field-init"),i.find(".checkbox").on("click",function(i){var c=0;e(this).is(":checked")&&(c=e(this).parent().find(".checkbox-check").attr("data-val")),e(this).parent().find(".checkbox-check").val(c),redux_change(e(this))}))})}}(jQuery);
includes/options/extensions/checkbox_hierarchy/checkbox_hierarchy/field_checkbox_hierarchy.php ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Redux Framework is free software: you can redistribute it and/or modify
4
+ * it under the terms of the GNU General Public License as published by
5
+ * the Free Software Foundation, either version 2 of the License, or
6
+ * any later version.
7
+ * Redux Framework is distributed in the hope that it will be useful,
8
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ * GNU General Public License for more details.
11
+ * You should have received a copy of the GNU General Public License
12
+ * along with Redux Framework. If not, see <http://www.gnu.org/licenses/>.
13
+ *
14
+ * @package ReduxFramework
15
+ * @subpackage Field_Checkbox
16
+ * @author Daniel J Griffiths (Ghost1227)
17
+ * @author Dovy Paukstys
18
+ * @version 3.0.0
19
+ */
20
+ // Exit if accessed directly
21
+ if ( !defined ( 'ABSPATH' ) ) {
22
+ exit;
23
+ }
24
+ // Don't duplicate me!
25
+ if ( !class_exists ( 'ReduxFramework_checkbox_hierarchy' ) ) {
26
+ /**
27
+ * Main ReduxFramework_checkbox class
28
+ *
29
+ * @since 1.0.0
30
+ */
31
+ class ReduxFramework_checkbox_hierarchy {
32
+ /**
33
+ * Field Constructor.
34
+ * Required - must call the parent constructor, then assign field and value to vars, and obviously call the render field function
35
+ *
36
+ * @since 1.0.0
37
+ * @access public
38
+ * @return void
39
+ */
40
+ function __construct ( $field = array(), $value = '', $parent ) {
41
+ $this->parent = $parent;
42
+ $this->field = $field;
43
+ $this->value = $value;
44
+
45
+ if ( defined('AMPFORWP_VERSION') ) {
46
+ $this->time = AMPFORWP_VERSION;
47
+ }
48
+ if ( empty( $this->extension_dir ) ) {
49
+ $this->extension_dir = trailingslashit( str_replace( '\\', '/', dirname( __FILE__ ) ) );
50
+ $this->extension_url = site_url( str_replace( trailingslashit( str_replace( '\\', '/', ABSPATH ) ), '', $this->extension_dir ) );
51
+ }
52
+ }
53
+ /**
54
+ * Field Render Function.
55
+ * Takes the vars and outputs the HTML for the field in the settings
56
+ *
57
+ * @since 1.0.0
58
+ * @access public
59
+ * @return void
60
+ */
61
+ public function render () {
62
+ if( !empty( $this->field['data'] ) && empty( $this->field['options'] ) ) {
63
+ if (empty($this->field['args'])) {
64
+ $this->field['args'] = array();
65
+ }
66
+ $this->field['options'] = $this->parent->get_wordpress_data($this->field['data'], $this->field['args']);
67
+ if (empty($this->field['options'])) {
68
+ return;
69
+ }
70
+ }
71
+ $this->field[ 'data_class' ] = ( isset ( $this->field[ 'multi_layout' ] ) ) ? 'data-' . $this->field[ 'multi_layout' ] : 'data-full';
72
+ if ( !empty ( $this->field[ 'options' ] ) && ( is_array ( $this->field[ 'options' ] ) || is_array ( $this->field[ 'default' ] ) ) ) {
73
+ echo '<ul class="' . $this->field[ 'data_class' ] . '">';
74
+ if ( !isset ( $this->value ) ) {
75
+ $this->value = array();
76
+ }
77
+
78
+ if ( empty ( $this->field[ 'options' ] ) && isset ( $this->field[ 'default' ] ) && is_array ( $this->field[ 'default' ] ) ) {
79
+ $this->field[ 'options' ] = $this->field[ 'default' ];
80
+ }
81
+ if($this->field[ 'options' ]['set_category_hirarchy']==1){
82
+ $this->wp_dropdown_cats_cat();
83
+ echo "</ul>";
84
+ return ;
85
+ }
86
+ foreach ( $this->field[ 'options' ] as $k => $v ) {
87
+ if ( empty ( $this->value[ $k ] ) ) {
88
+ $this->value[ $k ] = "";
89
+ }
90
+ echo '<li>';
91
+ echo '<label for="' . strtr ( $this->parent->args[ 'opt_name' ] . '[' . $this->field[ 'id' ] . '][' . $k . ']', array(
92
+ '[' => '_',
93
+ ']' => ''
94
+ ) ) . '_' . array_search ( $k, array_keys ( $this->field[ 'options' ] ) ) . '">';
95
+ echo '<input type="hidden" class="checkbox-check" data-val="1" name="' . $this->field[ 'name' ] . '[' . $k . ']' . $this->field[ 'name_suffix' ] . '" value="' . $this->value[ $k ] . '" ' . '/>';
96
+ echo '<input type="checkbox" class="checkbox ' . $this->field[ 'class' ] . '" id="' . strtr ( $this->parent->args[ 'opt_name' ] . '[' . $this->field[ 'id' ] . '][' . $k . ']', array(
97
+ '[' => '_',
98
+ ']' => ''
99
+ ) ) . '_' . array_search ( $k, array_keys ( $this->field[ 'options' ] ) ) . '" value="1" ' . checked ( $this->value[ $k ], '1', false ) . '/>';
100
+ echo ' ' . $v['name'] . '</label>';
101
+
102
+ if(isset($v['child']) && count($v['child']) > 0){
103
+ echo '<ul class="' . $this->field[ 'data_class' ] . ' inner-child">';
104
+ foreach ( $v['child'] as $childKey => $childValue ) {
105
+ if ( empty ( $this->value[ $childKey ] ) ) {
106
+ $this->value[ $childKey ] = "";
107
+ }
108
+ echo '<li>';
109
+ echo '<label for="' . strtr ( $this->parent->args[ 'opt_name' ] . '[' . $this->field[ 'id' ] . '][' . $childKey . ']', array(
110
+ '[' => '_',
111
+ ']' => ''
112
+ ) ) . '_' . array_search ( $childKey, array_keys ( $this->field[ 'options' ] ) ) . '">';
113
+ echo '<input type="hidden" class="checkbox-check" data-val="1" name="' . $this->field[ 'name' ] . '[' . $childKey . ']' . $this->field[ 'name_suffix' ] . '" value="' . $this->value[ $childKey ] . '" ' . '/>';
114
+ echo '<input type="checkbox" class="checkbox ' . $this->field[ 'class' ] . '" id="' . strtr ( $this->parent->args[ 'opt_name' ] . '[' . $this->field[ 'id' ] . '][' . $childKey . ']', array(
115
+ '[' => '_',
116
+ ']' => ''
117
+ ) ) . '_' . array_search ( $childKey, array_keys ( $this->field[ 'options' ] ) ) . '" value="1" ' . checked ( $this->value[ $childKey ], '1', false ) . '/>';
118
+ echo ' <span>' . $childValue . '</span></label>';
119
+ echo '</li>';
120
+ }
121
+ echo '</ul>';
122
+ }
123
+
124
+ echo '</li>';
125
+ }
126
+ echo '</ul>';
127
+ } else if ( empty ( $this->field[ 'data' ] ) ) {
128
+ echo (!empty ( $this->field[ 'desc' ] ) ) ? ' <ul class="data-full"><li><label for="' . strtr ( $this->parent->args[ 'opt_name' ] . '[' . $this->field[ 'id' ] . ']', array(
129
+ '[' => '_',
130
+ ']' => ''
131
+ ) ) . '">' : '';
132
+ // Got the "Checked" status as "0" or "1" then insert it as the "value" option
133
+ //$ch_value = 1; // checked($this->value, '1', false) == "" ? "0" : "1";
134
+ echo '<input type="hidden" class="checkbox-check" data-val="1" name="' . $this->field[ 'name' ] . $this->field[ 'name_suffix' ] . '" value="' . $this->value . '" ' . '/>';
135
+ echo '<input type="checkbox" id="' . strtr ( $this->parent->args[ 'opt_name' ] . '[' . $this->field[ 'id' ] . ']', array(
136
+ '[' => '_',
137
+ ']' => ''
138
+ ) ) . '" value="1" class="checkbox ' . $this->field[ 'class' ] . '" ' . checked ( $this->value, '1', false ) . '/>';
139
+ echo isset( $this->field[ 'label' ] ) ? ' ' . $this->field[ 'label' ] : '';
140
+ echo '</label></li></ul>';
141
+ }
142
+ }
143
+ function wp_dropdown_cats_cat( $currentcat = 0, $currentparent = 0, $parent = 0, $level = 0, $categories = 0 ) {
144
+
145
+ //$this->parent->args[ 'opt_name' ] = 'redux_builder_amp';
146
+
147
+
148
+ if (!$categories )
149
+ $categories = get_categories( );//array('hide_empty' => 0)
150
+
151
+ if ( $categories ) {
152
+ foreach ( $categories as $category ) {
153
+ if ( $currentcat != $category->term_id && $parent == $category->parent) {
154
+ $pad = str_repeat( '&#8211; ', $level );
155
+ $category->name = esc_html( $category->name );
156
+ /*echo "\n\t<option value='$category->term_id'";
157
+ if ( $currentparent == $category->term_id )
158
+ echo " selected='selected'";
159
+ echo ">$pad$category->name</option>";*/
160
+
161
+
162
+ echo '<li><label for="' . strtr ( $this->parent->args[ 'opt_name' ] . '[' . $this->field[ 'id' ] . '][' . $category->term_id . ']', array(
163
+ '[' => '_',
164
+ ']' => ''
165
+ ) ) . '_' . array_search ( $category->term_id, array_keys ( $this->field[ 'options' ] ) ) . '">';
166
+ echo '<input type="hidden" class="checkbox-check" data-val="1" name="' . $this->field[ 'name' ] . '[' . $category->term_id . ']' . $this->field[ 'name_suffix' ] . '" value="' . $this->value[ $category->term_id ] . '" ' . '/>';
167
+ echo '<input type="checkbox" class="checkbox ' . $this->field[ 'class' ] . '" id="' . strtr ( $this->parent->args[ 'opt_name' ] . '[' . $this->field[ 'id' ] . '][' . $category->term_id . ']', array(
168
+ '[' => '_',
169
+ ']' => ''
170
+ ) ) . '_' . array_search ( $category->term_id, array_keys ( $this->field[ 'options' ] ) ) . '" value="1" ' . checked ( $this->value[$category->term_id], '1', false ) . '/>';
171
+ echo ' <span>' .$pad. $category->name . '</span></label></li>';
172
+
173
+
174
+
175
+ $this->wp_dropdown_cats_cat( $currentcat, $currentparent, $category->term_id, $level +1, $categories );
176
+ }
177
+ }
178
+ } else {
179
+ return false;
180
+ }
181
+ }
182
+ /**
183
+ * Enqueue Function.
184
+ * If this field requires any scripts, or css define this function and register/enqueue the scripts/css
185
+ *
186
+ * @since 1.0.0
187
+ * @access public
188
+ * @return void
189
+ */
190
+ public function enqueue () {
191
+ if ($this->parent->args['dev_mode']) {
192
+ wp_enqueue_style (
193
+ 'redux-field-checkbox-hierarchy-css',
194
+ $this->extension_url . 'field_checkbox_hierarchy.css',
195
+ array(),
196
+ $this->time, //time (),
197
+ 'all'
198
+ );
199
+ }
200
+ //
201
+ wp_enqueue_script (
202
+ 'redux-field-checkbox-hierarchy-js',
203
+ $this->extension_url . 'field_checkbox_hierarchy' . Redux_Functions::isMin () . '.js',
204
+ array( 'jquery', 'redux-js' ),
205
+ $this->time, //time (),
206
+ true
207
+ );
208
+ }
209
+ }
210
+ }
includes/options/extensions/checkbox_hierarchy/checkbox_hierarchy/field_checkbox_hierarchy.scss ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .redux-container-checkbox_hierarchy {
2
+ label {
3
+ vertical-align: top;
4
+ width: 100%;
5
+
6
+ .field-desc {
7
+ margin-top: 0;
8
+ float: left;
9
+ width: 93%;
10
+ clear: none;
11
+ }
12
+ }
13
+ }
includes/options/extensions/checkbox_hierarchy/extension_checkbox_hierarchy.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Redux Framework is free software: you can redistribute it and/or modify
4
+ * it under the terms of the GNU General Public License as published by
5
+ * the Free Software Foundation, either version 2 of the License, or
6
+ * any later version.
7
+ *
8
+ * Redux Framework is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ * GNU General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU General Public License
14
+ * along with Redux Framework. If not, see <http://www.gnu.org/licenses/>.
15
+ *
16
+ * @package ReduxFramework
17
+ * @author Dovy Paukstys (dovy)
18
+ * @version 3.0.0
19
+ */
20
+ // Exit if accessed directly
21
+ if( !defined( 'ABSPATH' ) ) exit;
22
+ // Don't duplicate me!
23
+ if( !class_exists( 'ReduxFramework_extension_checkbox_hierarchy' ) ) {
24
+ /**
25
+ * Main ReduxFramework checkbox_hierarchy extension class
26
+ *
27
+ * @since 3.1.6
28
+ */
29
+ class ReduxFramework_extension_checkbox_hierarchy {
30
+
31
+ // Set the version number of your extension here
32
+ public static $version = '1.0.0';
33
+ // Set the name of your extension here
34
+ public $ext_name = 'Checkbox hierarchy';
35
+
36
+ // Set the minumum required version of Redux here (optional).
37
+ // Leave blank to require no minimum version.
38
+ // This allows you to specify a minimum required version of Redux in the event
39
+ // you do not want to support older versions.
40
+ public $min_redux_version = '3.0.0';
41
+ // Protected vars
42
+ protected $parent;
43
+ public $extension_url;
44
+ public $extension_dir;
45
+ public static $theInstance;
46
+ /**
47
+ * Class Constructor. Defines the args for the extions class
48
+ *
49
+ * @since 1.0.0
50
+ * @access public
51
+ * @param array $sections Panel sections.
52
+ * @param array $args Class constructor arguments.
53
+ * @param array $extra_tabs Extra panel tabs.
54
+ * @return void
55
+ */
56
+ public function __construct( $parent ) {
57
+
58
+ $this->parent = $parent;
59
+
60
+ if (is_admin() && !$this->is_minimum_version()) {
61
+ return;
62
+ }
63
+
64
+ if ( empty( $this->extension_dir ) ) {
65
+ $this->extension_dir = trailingslashit( str_replace( '\\', '/', dirname( __FILE__ ) ) );
66
+ $this->extension_url = site_url( str_replace( trailingslashit( str_replace( '\\', '/', ABSPATH ) ), '', $this->extension_dir ) );
67
+ }
68
+
69
+ $this->field_name = 'checkbox_hierarchy';
70
+ self::$theInstance = $this;
71
+ add_filter( 'redux/'.$this->parent->args['opt_name'].'/field/class/'.$this->field_name, array( &$this, 'overload_field_path' ) ); // Adds the local field
72
+ }
73
+ public function getInstance() {
74
+ return self::$theInstance;
75
+ }
76
+ // Forces the use of the embeded field path vs what the core typically would use
77
+ public function overload_field_path($field) {
78
+ return dirname(__FILE__).'/'.$this->field_name.'/field_'.$this->field_name.'.php';
79
+ }
80
+ private function is_minimum_version () {
81
+ $redux_ver = ReduxFramework::$_version;
82
+ if ($this->min_redux_version != '') {
83
+ if (version_compare($redux_ver, $this->min_redux_version) < 0) {
84
+ $msg = '<strong>' . esc_html__( 'The', 'redux-framework') . ' ' . $this->ext_name . ' ' . esc_html__('extension requires', 'redux-framework') . ' Redux Framework ' . esc_html__('version', 'redux-framework') . ' ' . $this->min_redux_version . ' ' . esc_html__('or higher.','redux-framework' ) . '</strong>&nbsp;&nbsp;' . esc_html__( 'You are currently running', 'redux-framework') . ' Redux Framework ' . esc_html__('version','redux-framework' ) . ' ' . $redux_ver . '.<br/><br/>' . esc_html__('This field will not render in your option panel, and featuress of this extension will not be available until the latest version of','redux-framework' ) . ' Redux Framework ' . esc_html__('has been installed.','redux-framework' );
85
+
86
+ $data = array(
87
+ 'parent' => $this->parent,
88
+ 'type' => 'error',
89
+ 'msg' => $msg,
90
+ 'id' => $this->ext_name . '_notice_' . self::$version,
91
+ 'dismiss' => false
92
+ );
93
+
94
+ if (method_exists('Redux_Admin_Notices', 'set_notice')) {
95
+ Redux_Admin_Notices::set_notice($data);
96
+ } else {
97
+ echo '<div class="error">';
98
+ echo '<p>';
99
+ echo $msg;
100
+ echo '</p>';
101
+ echo '</div>';
102
+ }
103
+ return false;
104
+ }
105
+ }
106
+
107
+ return true;
108
+ }
109
+ } // class
110
+ } // if
includes/vendor/amp/includes/embeds/class-amp-wistia-embed.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once( AMP__DIR__ . '/includes/embeds/class-amp-base-embed-handler.php' );
4
+
5
+ class AMP_Wistia_Embed_Handler extends AMP_Base_Embed_Handler {
6
+ const SHORT_URL_HOST = 'wistia.com';
7
+ const URL_PATTERN = '#https?:\/\/(?:www|support|fast)\.wistia\.com/(?:v/|embed/|medias/)(?:medias/)?#i';
8
+ const RATIO = 0.5625;
9
+
10
+ protected $DEFAULT_WIDTH = 512;
11
+ protected $DEFAULT_HEIGHT = 360;
12
+
13
+ private static $script_slug = 'amp-wistia-player';
14
+ private static $script_src = 'https://cdn.ampproject.org/v0/amp-wistia-player-0.1.js';
15
+
16
+ function __construct( $args = array() ) {
17
+ parent::__construct( $args );
18
+
19
+ if ( isset( $this->args['content_max_width'] ) ) {
20
+ $max_width = $this->args['content_max_width'];
21
+ $this->args['width'] = $max_width;
22
+ $this->args['height'] = round( $max_width * self::RATIO );
23
+ }
24
+ }
25
+
26
+ function register_embed() {
27
+ wp_embed_register_handler( 'amp-wistia-player', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
28
+ add_shortcode( 'wistia', array( $this, 'shortcode' ) );
29
+ }
30
+
31
+ public function unregister_embed() {
32
+ wp_embed_unregister_handler( 'amp-wistia-player', -1 );
33
+ remove_shortcode( 'wistia' );
34
+ }
35
+
36
+ public function get_scripts() {
37
+ if ( ! $this->did_convert_elements ) {
38
+ return array();
39
+ }
40
+
41
+ return array( self::$script_slug => self::$script_src );
42
+ }
43
+
44
+ public function shortcode( $attr ) {
45
+ $url = false;
46
+ $video_id = false;
47
+ if ( isset( $attr[0] ) ) {
48
+ $url = ltrim( $attr[0] , '=' );
49
+ } elseif ( function_exists( 'shortcode_new_to_old_params' ) ) {
50
+ $url = shortcode_new_to_old_params( $attr );
51
+ }
52
+
53
+ if ( empty( $url ) ) {
54
+ return '';
55
+ }
56
+
57
+ $video_id = $this->get_video_id_from_url( $url );
58
+
59
+ return $this->render( array(
60
+ 'url' => $url,
61
+ 'video_id' => $video_id,
62
+ ) );
63
+ }
64
+
65
+ public function oembed( $matches, $attr, $url, $rawattr ) {
66
+ return $this->shortcode( array( $url ) );
67
+ }
68
+
69
+ public function render( $args ) {
70
+ $args = wp_parse_args( $args, array(
71
+ 'video_id' => false,
72
+ ) );
73
+
74
+ if ( empty( $args['video_id'] ) ) {
75
+ return AMP_HTML_Utils::build_tag( 'a', array( 'href' => esc_url( $args['url'] ), 'class' => 'amp-wp-embed-fallback' ), esc_html( $args['url'] ) );
76
+ }
77
+
78
+ $this->did_convert_elements = true;
79
+ $attrs = array(
80
+ 'data-media-hashed-id' => $args['video_id'],
81
+ 'width' => $this->args['width'],
82
+ 'height' => $this->args['height'],
83
+ 'layout' => 'responsive',
84
+ );
85
+ $attrs = ampforwp_amp_consent_check($attrs);
86
+ return AMP_HTML_Utils::build_tag(
87
+ 'amp-wistia-player',$attrs);
88
+ }
89
+
90
+ private function get_video_id_from_url( $url ) {
91
+ $video_id = false;
92
+ $parsed_url = parse_url( $url );
93
+
94
+ if ( self::SHORT_URL_HOST === substr( $parsed_url['host'], -strlen( self::SHORT_URL_HOST ) ) ) {
95
+ $parts = explode( '/', $parsed_url['path'] );
96
+ if ( ! empty( $parts ) ) {
97
+ $video_id = end($parts);
98
+ }
99
+ }
100
+
101
+ return $video_id;
102
+ }
103
+ }
includes/vendor/amp/includes/sanitizers/class-amp-allowed-tags-generated.php ADDED
@@ -0,0 +1,10776 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generated by amphtml-update.py - do not edit.
4
+ *
5
+ * This is a list of HTML tags and attributes that are allowed by the
6
+ * AMP specification. Note that tag names have been converted to lowercase.
7
+ *
8
+ * Note: This file only contains tags that are relevant to the `body` of
9
+ * an AMP page. To include additional elements modify the variable
10
+ * `mandatory_parent_blacklist` in the amp_wp_build.py script.
11
+ *
12
+ * phpcs:ignoreFile
13
+ */
14
+ class AMP_Allowed_Tags_Generated {
15
+
16
+ private static $spec_file_revision = 595;
17
+ private static $minimum_validator_revision_required = 322;
18
+
19
+ private static $allowed_tags = array(
20
+ 'a' => array(
21
+ array(
22
+ 'attr_spec_list' => array(
23
+ '[href]' => array(),
24
+ 'border' => array(),
25
+ 'download' => array(),
26
+ 'href' => array(
27
+ 'blacklisted_value_regex' => '__amp_source_origin',
28
+ 'value_url' => array(
29
+ 'allow_empty' => true,
30
+ 'allow_relative' => true,
31
+ 'allowed_protocol' => array(
32
+ 'ftp',
33
+ 'geo',
34
+ 'http',
35
+ 'https',
36
+ 'mailto',
37
+ 'maps',
38
+ 'bbmi',
39
+ 'fb-messenger',
40
+ 'intent',
41
+ 'line',
42
+ 'skype',
43
+ 'sms',
44
+ 'snapchat',
45
+ 'tel',
46
+ 'tg',
47
+ 'threema',
48
+ 'twitter',
49
+ 'viber',
50
+ 'whatsapp',
51
+ ),
52
+ ),
53
+ ),
54
+ 'hreflang' => array(),
55
+ 'media' => array(),
56
+ 'name' => array(),
57
+ 'referrerpolicy' => array(),
58
+ 'rel' => array(
59
+ 'blacklisted_value_regex' => '(^|\\s)(components|dns-prefetch|import|manifest|preconnect|prefetch|preload|prerender|serviceworker|stylesheet|subresource|)(\\s|$)',
60
+ ),
61
+ 'role' => array(),
62
+ 'tabindex' => array(),
63
+ 'target' => array(
64
+ 'value_regex' => '(_blank|_self|_top)',
65
+ ),
66
+ 'type' => array(
67
+ 'value_casei' => 'text/html',
68
+ ),
69
+ ),
70
+ 'tag_spec' => array(
71
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#links',
72
+ ),
73
+ ),
74
+ ),
75
+ 'abbr' => array(
76
+ array(
77
+ 'attr_spec_list' => array(),
78
+ 'tag_spec' => array(),
79
+ ),
80
+ ),
81
+ 'acronym' => array(
82
+ array(
83
+ 'attr_spec_list' => array(),
84
+ 'tag_spec' => array(),
85
+ ),
86
+ ),
87
+ 'address' => array(
88
+ array(
89
+ 'attr_spec_list' => array(),
90
+ 'tag_spec' => array(),
91
+ ),
92
+ ),
93
+ 'amp-3q-player' => array(
94
+ array(
95
+ 'attr_spec_list' => array(
96
+ 'autoplay' => array(
97
+ 'value' => '',
98
+ ),
99
+ 'data-id' => array(
100
+ 'mandatory' => true,
101
+ ),
102
+ 'media' => array(),
103
+ 'noloading' => array(
104
+ 'value' => '',
105
+ ),
106
+ ),
107
+ 'tag_spec' => array(
108
+ 'requires_extension' => array(
109
+ 'amp-3q-player',
110
+ ),
111
+ ),
112
+ ),
113
+ ),
114
+ 'amp-accordion' => array(
115
+ array(
116
+ 'attr_spec_list' => array(
117
+ 'disable-session-states' => array(
118
+ 'value' => '',
119
+ ),
120
+ 'expand-single-section' => array(
121
+ 'value' => '',
122
+ ),
123
+ ),
124
+ 'tag_spec' => array(
125
+ 'requires_extension' => array(
126
+ 'amp-accordion',
127
+ ),
128
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-accordion',
129
+ ),
130
+ ),
131
+ ),
132
+ 'amp-ad' => array(
133
+ array(
134
+ 'attr_spec_list' => array(
135
+ 'alt' => array(),
136
+ 'json' => array(),
137
+ 'media' => array(),
138
+ 'noloading' => array(
139
+ 'value' => '',
140
+ ),
141
+ 'rtc-config' => array(),
142
+ 'src' => array(
143
+ 'blacklisted_value_regex' => '__amp_source_origin',
144
+ 'value_url' => array(
145
+ 'allow_relative' => true,
146
+ 'allowed_protocol' => array(
147
+ 'https',
148
+ ),
149
+ ),
150
+ ),
151
+ 'template' => array(),
152
+ 'type' => array(
153
+ 'mandatory' => true,
154
+ ),
155
+ ),
156
+ 'tag_spec' => array(
157
+ 'also_requires_tag_warning' => array(
158
+ 'amp-ad extension .js script',
159
+ ),
160
+ 'disallowed_ancestor' => array(
161
+ 'amp-app-banner',
162
+ ),
163
+ 'requires_extension' => array(
164
+ 'amp-ad',
165
+ ),
166
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-ad',
167
+ ),
168
+ ),
169
+ array(
170
+ 'attr_spec_list' => array(
171
+ 'alt' => array(),
172
+ 'data-multi-size' => array(
173
+ 'dispatch_key' => 2,
174
+ 'mandatory' => true,
175
+ 'value' => '',
176
+ ),
177
+ 'json' => array(),
178
+ 'media' => array(),
179
+ 'noloading' => array(
180
+ 'value' => '',
181
+ ),
182
+ 'rtc-config' => array(),
183
+ 'src' => array(
184
+ 'blacklisted_value_regex' => '__amp_source_origin',
185
+ 'value_url' => array(
186
+ 'allow_relative' => true,
187
+ 'allowed_protocol' => array(
188
+ 'https',
189
+ ),
190
+ ),
191
+ ),
192
+ 'type' => array(
193
+ 'mandatory' => true,
194
+ ),
195
+ ),
196
+ 'tag_spec' => array(
197
+ 'also_requires_tag_warning' => array(
198
+ 'amp-ad extension .js script',
199
+ ),
200
+ 'disallowed_ancestor' => array(
201
+ 'amp-app-banner',
202
+ 'amp-carousel',
203
+ 'amp-fx-flying-carpet',
204
+ 'amp-lightbox',
205
+ 'amp-sticky-ad',
206
+ ),
207
+ 'requires_extension' => array(
208
+ 'amp-ad',
209
+ ),
210
+ 'spec_name' => 'amp-ad with data-multi-size attribute',
211
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-ad',
212
+ ),
213
+ ),
214
+ array(
215
+ 'attr_spec_list' => array(
216
+ 'alt' => array(),
217
+ 'data-enable-refresh' => array(
218
+ 'dispatch_key' => 2,
219
+ 'mandatory' => true,
220
+ 'value' => '',
221
+ ),
222
+ 'json' => array(),
223
+ 'media' => array(),
224
+ 'noloading' => array(
225
+ 'value' => '',
226
+ ),
227
+ 'src' => array(
228
+ 'blacklisted_value_regex' => '__amp_source_origin',
229
+ 'value_url' => array(
230
+ 'allow_relative' => true,
231
+ 'allowed_protocol' => array(
232
+ 'https',
233
+ ),
234
+ ),
235
+ ),
236
+ 'type' => array(
237
+ 'mandatory' => true,
238
+ ),
239
+ ),
240
+ 'tag_spec' => array(
241
+ 'also_requires_tag_warning' => array(
242
+ 'amp-ad extension .js script',
243
+ ),
244
+ 'disallowed_ancestor' => array(
245
+ 'amp-app-banner',
246
+ 'amp-fx-flying-carpet',
247
+ 'amp-lightbox',
248
+ ),
249
+ 'requires_extension' => array(
250
+ 'amp-ad',
251
+ ),
252
+ 'spec_name' => 'amp-ad with data-enable-refresh attribute',
253
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-ad',
254
+ ),
255
+ ),
256
+ ),
257
+ 'amp-analytics' => array(
258
+ array(
259
+ 'attr_spec_list' => array(
260
+ 'config' => array(
261
+ 'blacklisted_value_regex' => '__amp_source_origin',
262
+ 'value_url' => array(
263
+ 'allow_empty' => true,
264
+ 'allow_relative' => true,
265
+ 'allowed_protocol' => array(
266
+ 'https',
267
+ ),
268
+ ),
269
+ ),
270
+ 'type' => array(),
271
+ ),
272
+ 'tag_spec' => array(
273
+ 'requires_extension' => array(
274
+ 'amp-analytics',
275
+ ),
276
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-analytics',
277
+ ),
278
+ ),
279
+ ),
280
+ 'amp-anim' => array(
281
+ array(
282
+ 'attr_spec_list' => array(
283
+ 'alt' => array(),
284
+ 'attribution' => array(),
285
+ 'controls' => array(),
286
+ 'media' => array(),
287
+ 'noloading' => array(
288
+ 'value' => '',
289
+ ),
290
+ 'src' => array(
291
+ 'alternative_names' => array(
292
+ 'srcset',
293
+ ),
294
+ 'blacklisted_value_regex' => '__amp_source_origin',
295
+ 'mandatory' => true,
296
+ 'value_url' => array(
297
+ 'allow_relative' => true,
298
+ 'allowed_protocol' => array(
299
+ 'data',
300
+ 'http',
301
+ 'https',
302
+ ),
303
+ ),
304
+ ),
305
+ ),
306
+ 'tag_spec' => array(
307
+ 'requires_extension' => array(
308
+ 'amp-anim',
309
+ ),
310
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-anim',
311
+ ),
312
+ ),
313
+ ),
314
+ 'amp-animation' => array(
315
+ array(
316
+ 'attr_spec_list' => array(
317
+ 'media' => array(),
318
+ 'noloading' => array(
319
+ 'value' => '',
320
+ ),
321
+ 'trigger' => array(
322
+ 'value' => 'visibility',
323
+ ),
324
+ ),
325
+ 'tag_spec' => array(
326
+ 'requires_extension' => array(
327
+ 'amp-animation',
328
+ ),
329
+ ),
330
+ ),
331
+ ),
332
+ 'amp-apester-media' => array(
333
+ array(
334
+ 'attr_spec_list' => array(
335
+ 'data-apester-channel-token' => array(
336
+ 'value_regex' => '[0-9a-zA-Z]+',
337
+ ),
338
+ 'data-apester-media-id' => array(
339
+ 'value_regex' => '[0-9a-zA-Z]+',
340
+ ),
341
+ 'media' => array(),
342
+ 'noloading' => array(
343
+ 'value' => '',
344
+ ),
345
+ ),
346
+ 'tag_spec' => array(
347
+ 'requires_extension' => array(
348
+ 'amp-apester-media',
349
+ ),
350
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-apester-media',
351
+ ),
352
+ ),
353
+ ),
354
+ 'amp-app-banner' => array(
355
+ array(
356
+ 'attr_spec_list' => array(
357
+ 'id' => array(
358
+ 'mandatory' => true,
359
+ ),
360
+ 'media' => array(),
361
+ 'noloading' => array(
362
+ 'value' => '',
363
+ ),
364
+ ),
365
+ 'tag_spec' => array(
366
+ 'mandatory_parent' => 'body',
367
+ 'requires_extension' => array(
368
+ 'amp-app-banner',
369
+ ),
370
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-app-banner',
371
+ 'unique' => true,
372
+ ),
373
+ ),
374
+ ),
375
+ 'amp-audio' => array(
376
+ array(
377
+ 'attr_spec_list' => array(
378
+ 'album' => array(),
379
+ 'artist' => array(),
380
+ 'artwork' => array(),
381
+ 'autoplay' => array(
382
+ 'value' => '',
383
+ ),
384
+ 'controls' => array(),
385
+ 'controlslist' => array(),
386
+ 'loop' => array(
387
+ 'value' => '',
388
+ ),
389
+ 'media' => array(),
390
+ 'muted' => array(
391
+ 'value' => '',
392
+ ),
393
+ 'noloading' => array(
394
+ 'value' => '',
395
+ ),
396
+ 'preload' => array(
397
+ 'value_regex_casei' => '(auto|metadata|none|)',
398
+ ),
399
+ 'src' => array(
400
+ 'blacklisted_value_regex' => '__amp_source_origin',
401
+ 'value_url' => array(
402
+ 'allow_relative' => true,
403
+ 'allowed_protocol' => array(
404
+ 'https',
405
+ ),
406
+ ),
407
+ ),
408
+ ),
409
+ 'tag_spec' => array(
410
+ 'disallowed_ancestor' => array(
411
+ 'amp-story',
412
+ ),
413
+ 'requires_extension' => array(
414
+ 'amp-audio',
415
+ ),
416
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-audio',
417
+ ),
418
+ ),
419
+ array(
420
+ 'attr_spec_list' => array(
421
+ 'album' => array(),
422
+ 'artist' => array(),
423
+ 'artwork' => array(),
424
+ 'autoplay' => array(
425
+ 'mandatory' => true,
426
+ 'value' => '',
427
+ ),
428
+ 'controls' => array(),
429
+ 'controlslist' => array(),
430
+ 'loop' => array(
431
+ 'value' => '',
432
+ ),
433
+ 'media' => array(),
434
+ 'muted' => array(
435
+ 'value' => '',
436
+ ),
437
+ 'noloading' => array(
438
+ 'value' => '',
439
+ ),
440
+ 'src' => array(
441
+ 'blacklisted_value_regex' => '__amp_source_origin',
442
+ 'value_url' => array(
443
+ 'allow_relative' => true,
444
+ 'allowed_protocol' => array(
445
+ 'https',
446
+ ),
447
+ ),
448
+ ),
449
+ ),
450
+ 'tag_spec' => array(
451
+ 'mandatory_ancestor' => 'amp-story',
452
+ 'requires_extension' => array(
453
+ 'amp-audio',
454
+ ),
455
+ 'spec_name' => 'amp-story >> amp-audio',
456
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-audio',
457
+ ),
458
+ ),
459
+ ),
460
+ 'amp-auto-ads' => array(
461
+ array(
462
+ 'attr_spec_list' => array(
463
+ 'media' => array(),
464
+ 'noloading' => array(
465
+ 'value' => '',
466
+ ),
467
+ 'type' => array(
468
+ 'mandatory' => true,
469
+ ),
470
+ ),
471
+ 'tag_spec' => array(
472
+ 'mandatory_parent' => 'body',
473
+ 'requires_extension' => array(
474
+ 'amp-auto-ads',
475
+ ),
476
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-auto-ads',
477
+ ),
478
+ ),
479
+ ),
480
+ 'amp-beopinion' => array(
481
+ array(
482
+ 'attr_spec_list' => array(
483
+ 'data-account' => array(
484
+ 'mandatory' => true,
485
+ 'value_regex_casei' => '[0-9a-f]{24}',
486
+ ),
487
+ 'data-content' => array(
488
+ 'value_regex_casei' => '[0-9a-f]{24}',
489
+ ),
490
+ 'data-my-content' => array(
491
+ 'value_regex' => '0|1',
492
+ ),
493
+ 'data-name' => array(),
494
+ 'media' => array(),
495
+ 'noloading' => array(
496
+ 'value' => '',
497
+ ),
498
+ ),
499
+ 'tag_spec' => array(
500
+ 'requires_extension' => array(
501
+ 'amp-beopinion',
502
+ ),
503
+ ),
504
+ ),
505
+ ),
506
+ 'amp-bind-macro' => array(
507
+ array(
508
+ 'attr_spec_list' => array(
509
+ 'arguments' => array(),
510
+ 'expression' => array(
511
+ 'mandatory' => true,
512
+ ),
513
+ 'id' => array(
514
+ 'mandatory' => true,
515
+ ),
516
+ ),
517
+ 'tag_spec' => array(
518
+ 'requires_extension' => array(
519
+ 'amp-bind',
520
+ ),
521
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-bind',
522
+ ),
523
+ ),
524
+ ),
525
+ 'amp-bodymovin-animation' => array(
526
+ array(
527
+ 'attr_spec_list' => array(
528
+ 'loop' => array(
529
+ 'value_regex_casei' => '(false|number|true)',
530
+ ),
531
+ 'noautoplay' => array(
532
+ 'value' => '',
533
+ ),
534
+ 'src' => array(
535
+ 'mandatory' => true,
536
+ 'value_url' => array(
537
+ 'allow_relative' => false,
538
+ 'allowed_protocol' => array(
539
+ 'https',
540
+ ),
541
+ ),
542
+ ),
543
+ ),
544
+ 'tag_spec' => array(
545
+ 'requires_extension' => array(
546
+ 'amp-bodymovin-animation',
547
+ ),
548
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-bodymovin-animation',
549
+ ),
550
+ ),
551
+ ),
552
+ 'amp-brid-player' => array(
553
+ array(
554
+ 'attr_spec_list' => array(
555
+ 'autoplay' => array(),
556
+ 'data-outstream' => array(
557
+ 'value_regex' => '[0-9]+',
558
+ ),
559
+ 'data-partner' => array(
560
+ 'mandatory' => true,
561
+ 'value_regex' => '[0-9]+',
562
+ ),
563
+ 'data-player' => array(
564
+ 'mandatory' => true,
565
+ 'value_regex' => '[0-9]+',
566
+ ),
567
+ 'data-playlist' => array(
568
+ 'value_regex' => '[0-9]+',
569
+ ),
570
+ 'data-video' => array(
571
+ 'value_regex' => '[0-9]+',
572
+ ),
573
+ 'media' => array(),
574
+ 'noloading' => array(
575
+ 'value' => '',
576
+ ),
577
+ ),
578
+ 'tag_spec' => array(
579
+ 'requires_extension' => array(
580
+ 'amp-brid-player',
581
+ ),
582
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-brid-player',
583
+ ),
584
+ ),
585
+ ),
586
+ 'amp-brightcove' => array(
587
+ array(
588
+ 'attr_spec_list' => array(
589
+ '[data-account]' => array(),
590
+ '[data-embed]' => array(),
591
+ '[data-player-id]' => array(),
592
+ '[data-player]' => array(),
593
+ '[data-playlist-id]' => array(),
594
+ '[data-video-id]' => array(),
595
+ 'data-account' => array(
596
+ 'mandatory' => true,
597
+ ),
598
+ 'media' => array(),
599
+ 'noloading' => array(
600
+ 'value' => '',
601
+ ),
602
+ ),
603
+ 'tag_spec' => array(
604
+ 'requires_extension' => array(
605
+ 'amp-brightcove',
606
+ ),
607
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-brightcove',
608
+ ),
609
+ ),
610
+ ),
611
+ 'amp-byside-content' => array(
612
+ array(
613
+ 'attr_spec_list' => array(
614
+ 'data-label' => array(
615
+ 'mandatory' => true,
616
+ ),
617
+ 'data-webcare-id' => array(
618
+ 'mandatory' => true,
619
+ ),
620
+ 'media' => array(),
621
+ 'noloading' => array(
622
+ 'value' => '',
623
+ ),
624
+ ),
625
+ 'tag_spec' => array(
626
+ 'requires_extension' => array(
627
+ 'amp-byside-content',
628
+ ),
629
+ ),
630
+ ),
631
+ ),
632
+ 'amp-call-tracking' => array(
633
+ array(
634
+ 'attr_spec_list' => array(
635
+ 'config' => array(
636
+ 'blacklisted_value_regex' => '__amp_source_origin',
637
+ 'mandatory' => true,
638
+ 'value_url' => array(
639
+ 'allow_relative' => false,
640
+ 'allowed_protocol' => array(
641
+ 'https',
642
+ ),
643
+ ),
644
+ ),
645
+ 'media' => array(),
646
+ 'noloading' => array(
647
+ 'value' => '',
648
+ ),
649
+ ),
650
+ 'tag_spec' => array(
651
+ 'requires_extension' => array(
652
+ 'amp-call-tracking',
653
+ ),
654
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-call-tracking',
655
+ ),
656
+ ),
657
+ ),
658
+ 'amp-carousel' => array(
659
+ array(
660
+ 'attr_spec_list' => array(
661
+ '[slide]' => array(),
662
+ 'arrows' => array(
663
+ 'value' => '',
664
+ ),
665
+ 'autoplay' => array(
666
+ 'value' => '',
667
+ ),
668
+ 'controls' => array(),
669
+ 'delay' => array(
670
+ 'value_regex' => '[0-9]+',
671
+ ),
672
+ 'dots' => array(
673
+ 'value' => '',
674
+ ),
675
+ 'lightbox' => array(),
676
+ 'lightbox-exclude' => array(
677
+ 'value' => '',
678
+ ),
679
+ 'lightbox-thumbnail-id' => array(
680
+ 'value_regex_casei' => '^[a-z][a-z\\d_-]*',
681
+ ),
682
+ 'loop' => array(
683
+ 'value' => '',
684
+ ),
685
+ 'media' => array(),
686
+ 'noloading' => array(
687
+ 'value' => '',
688
+ ),
689
+ 'type' => array(
690
+ 'value_regex' => 'slides|carousel',
691
+ ),
692
+ ),
693
+ 'tag_spec' => array(
694
+ 'requires_extension' => array(
695
+ 'amp-carousel',
696
+ ),
697
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-carousel',
698
+ ),
699
+ ),
700
+ ),
701
+ 'amp-consent' => array(
702
+ array(
703
+ 'attr_spec_list' => array(
704
+ 'media' => array(),
705
+ 'noloading' => array(
706
+ 'value' => '',
707
+ ),
708
+ ),
709
+ 'tag_spec' => array(
710
+ 'requires_extension' => array(
711
+ 'amp-consent',
712
+ ),
713
+ 'unique' => true,
714
+ ),
715
+ ),
716
+ ),
717
+ 'amp-dailymotion' => array(
718
+ array(
719
+ 'attr_spec_list' => array(
720
+ 'autoplay' => array(),
721
+ 'data-endscreen-enable' => array(
722
+ 'value_regex' => 'true|false',
723
+ ),
724
+ 'data-info' => array(
725
+ 'value_regex' => 'true|false',
726
+ ),
727
+ 'data-mute' => array(
728
+ 'value_regex' => 'true|false',
729
+ ),
730
+ 'data-sharing-enable' => array(
731
+ 'value_regex' => 'true|false',
732
+ ),
733
+ 'data-start' => array(
734
+ 'value_regex' => '[0-9]+',
735
+ ),
736
+ 'data-ui-highlight' => array(
737
+ 'value_regex_casei' => '([0-9a-f]{3}){1,2}',
738
+ ),
739
+ 'data-ui-logo' => array(
740
+ 'value_regex' => 'true|false',
741
+ ),
742
+ 'data-videoid' => array(
743
+ 'mandatory' => true,
744
+ 'value_regex_casei' => '[a-z0-9]+',
745
+ ),
746
+ 'media' => array(),
747
+ 'noloading' => array(
748
+ 'value' => '',
749
+ ),
750
+ ),
751
+ 'tag_spec' => array(
752
+ 'requires_extension' => array(
753
+ 'amp-dailymotion',
754
+ ),
755
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-dailymotion',
756
+ ),
757
+ ),
758
+ ),
759
+ 'amp-date-picker' => array(
760
+ array(
761
+ 'attr_spec_list' => array(
762
+ 'allow-blocked-ranges' => array(
763
+ 'value' => '',
764
+ ),
765
+ 'blocked' => array(),
766
+ 'day-size' => array(
767
+ 'value_regex' => '[0-9]+',
768
+ ),
769
+ 'first-day-of-week' => array(
770
+ 'value_regex' => '[0-6]',
771
+ ),
772
+ 'format' => array(),
773
+ 'fullscreen' => array(
774
+ 'value' => '',
775
+ ),
776
+ 'highlighted' => array(),
777
+ 'input-selector' => array(),
778
+ 'locale' => array(),
779
+ 'max' => array(),
780
+ 'media' => array(),
781
+ 'min' => array(),
782
+ 'mode' => array(
783
+ 'value_casei' => 'static',
784
+ ),
785
+ 'month-format' => array(),
786
+ 'noloading' => array(
787
+ 'value' => '',
788
+ ),
789
+ 'number-of-months' => array(
790
+ 'value_regex' => '[0-9]+',
791
+ ),
792
+ 'open-after-clear' => array(
793
+ 'value' => '',
794
+ ),
795
+ 'open-after-select' => array(
796
+ 'value' => '',
797
+ ),
798
+ 'src' => array(
799
+ 'blacklisted_value_regex' => '__amp_source_origin',
800
+ 'value_url' => array(
801
+ 'allow_relative' => true,
802
+ 'allowed_protocol' => array(
803
+ 'https',
804
+ ),
805
+ ),
806
+ ),
807
+ 'type' => array(
808
+ 'value_casei' => 'single',
809
+ ),
810
+ 'week-day-format' => array(),
811
+ ),
812
+ 'tag_spec' => array(
813
+ 'requires_extension' => array(
814
+ 'amp-date-picker',
815
+ ),
816
+ 'spec_name' => 'amp-date-picker[type=single][mode=static]',
817
+ ),
818
+ ),
819
+ array(
820
+ 'attr_spec_list' => array(
821
+ 'allow-blocked-ranges' => array(
822
+ 'value' => '',
823
+ ),
824
+ 'blocked' => array(),
825
+ 'day-size' => array(
826
+ 'value_regex' => '[0-9]+',
827
+ ),
828
+ 'first-day-of-week' => array(
829
+ 'value_regex' => '[0-6]',
830
+ ),
831
+ 'format' => array(),
832
+ 'highlighted' => array(),
833
+ 'input-selector' => array(),
834
+ 'locale' => array(),
835
+ 'max' => array(),
836
+ 'media' => array(),
837
+ 'min' => array(),
838
+ 'mode' => array(
839
+ 'mandatory' => true,
840
+ 'value_casei' => 'overlay',
841
+ ),
842
+ 'month-format' => array(),
843
+ 'noloading' => array(
844
+ 'value' => '',
845
+ ),
846
+ 'number-of-months' => array(
847
+ 'value_regex' => '[0-9]+',
848
+ ),
849
+ 'open-after-clear' => array(
850
+ 'value' => '',
851
+ ),
852
+ 'open-after-select' => array(
853
+ 'value' => '',
854
+ ),
855
+ 'src' => array(
856
+ 'blacklisted_value_regex' => '__amp_source_origin',
857
+ 'value_url' => array(
858
+ 'allow_relative' => true,
859
+ 'allowed_protocol' => array(
860
+ 'https',
861
+ ),
862
+ ),
863
+ ),
864
+ 'type' => array(
865
+ 'value_casei' => 'single',
866
+ ),
867
+ 'week-day-format' => array(),
868
+ ),
869
+ 'tag_spec' => array(
870
+ 'requires_extension' => array(
871
+ 'amp-date-picker',
872
+ ),
873
+ 'spec_name' => 'amp-date-picker[type=single][mode=overlay]',
874
+ ),
875
+ ),
876
+ array(
877
+ 'attr_spec_list' => array(
878
+ 'allow-blocked-ranges' => array(
879
+ 'value' => '',
880
+ ),
881
+ 'blocked' => array(),
882
+ 'day-size' => array(
883
+ 'value_regex' => '[0-9]+',
884
+ ),
885
+ 'end-input-selector' => array(),
886
+ 'first-day-of-week' => array(
887
+ 'value_regex' => '[0-6]',
888
+ ),
889
+ 'format' => array(),
890
+ 'fullscreen' => array(
891
+ 'value' => '',
892
+ ),
893
+ 'highlighted' => array(),
894
+ 'locale' => array(),
895
+ 'max' => array(),
896
+ 'media' => array(),
897
+ 'min' => array(),
898
+ 'mode' => array(
899
+ 'value_casei' => 'static',
900
+ ),
901
+ 'month-format' => array(),
902
+ 'noloading' => array(
903
+ 'value' => '',
904
+ ),
905
+ 'number-of-months' => array(
906
+ 'value_regex' => '[0-9]+',
907
+ ),
908
+ 'open-after-clear' => array(
909
+ 'value' => '',
910
+ ),
911
+ 'open-after-select' => array(
912
+ 'value' => '',
913
+ ),
914
+ 'src' => array(
915
+ 'blacklisted_value_regex' => '__amp_source_origin',
916
+ 'value_url' => array(
917
+ 'allow_relative' => true,
918
+ 'allowed_protocol' => array(
919
+ 'https',
920
+ ),
921
+ ),
922
+ ),
923
+ 'start-input-selector' => array(),
924
+ 'type' => array(
925
+ 'mandatory' => true,
926
+ 'value_casei' => 'range',
927
+ ),
928
+ 'week-day-format' => array(),
929
+ ),
930
+ 'tag_spec' => array(
931
+ 'requires_extension' => array(
932
+ 'amp-date-picker',
933
+ ),
934
+ 'spec_name' => 'amp-date-picker[type=range][mode=static]',
935
+ ),
936
+ ),
937
+ array(
938
+ 'attr_spec_list' => array(
939
+ 'allow-blocked-ranges' => array(
940
+ 'value' => '',
941
+ ),
942
+ 'blocked' => array(),
943
+ 'day-size' => array(
944
+ 'value_regex' => '[0-9]+',
945
+ ),
946
+ 'end-input-selector' => array(),
947
+ 'first-day-of-week' => array(
948
+ 'value_regex' => '[0-6]',
949
+ ),
950
+ 'format' => array(),
951
+ 'highlighted' => array(),
952
+ 'locale' => array(),
953
+ 'max' => array(),
954
+ 'media' => array(),
955
+ 'min' => array(),
956
+ 'mode' => array(
957
+ 'mandatory' => true,
958
+ 'value_casei' => 'overlay',
959
+ ),
960
+ 'month-format' => array(),
961
+ 'noloading' => array(
962
+ 'value' => '',
963
+ ),
964
+ 'number-of-months' => array(
965
+ 'value_regex' => '[0-9]+',
966
+ ),
967
+ 'open-after-clear' => array(
968
+ 'value' => '',
969
+ ),
970
+ 'open-after-select' => array(
971
+ 'value' => '',
972
+ ),
973
+ 'src' => array(
974
+ 'blacklisted_value_regex' => '__amp_source_origin',
975
+ 'value_url' => array(
976
+ 'allow_relative' => true,
977
+ 'allowed_protocol' => array(
978
+ 'https',
979
+ ),
980
+ ),
981
+ ),
982
+ 'start-input-selector' => array(),
983
+ 'type' => array(
984
+ 'mandatory' => true,
985
+ 'value_casei' => 'range',
986
+ ),
987
+ 'week-day-format' => array(),
988
+ ),
989
+ 'tag_spec' => array(
990
+ 'requires_extension' => array(
991
+ 'amp-date-picker',
992
+ ),
993
+ 'spec_name' => 'amp-date-picker[type=range][mode=overlay]',
994
+ ),
995
+ ),
996
+ ),
997
+ 'amp-document-recommendations' => array(
998
+ array(
999
+ 'attr_spec_list' => array(),
1000
+ 'tag_spec' => array(
1001
+ 'mandatory_parent' => 'body',
1002
+ 'requires_extension' => array(
1003
+ 'amp-document-recommendations',
1004
+ ),
1005
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-document-recommendations',
1006
+ ),
1007
+ ),
1008
+ ),
1009
+ 'amp-embed' => array(
1010
+ array(
1011
+ 'attr_spec_list' => array(
1012
+ 'alt' => array(),
1013
+ 'json' => array(),
1014
+ 'media' => array(),
1015
+ 'noloading' => array(
1016
+ 'value' => '',
1017
+ ),
1018
+ 'rtc-config' => array(),
1019
+ 'src' => array(
1020
+ 'blacklisted_value_regex' => '__amp_source_origin',
1021
+ 'value_url' => array(
1022
+ 'allow_relative' => true,
1023
+ 'allowed_protocol' => array(
1024
+ 'https',
1025
+ ),
1026
+ ),
1027
+ ),
1028
+ 'template' => array(),
1029
+ 'type' => array(
1030
+ 'mandatory' => true,
1031
+ ),
1032
+ ),
1033
+ 'tag_spec' => array(
1034
+ 'also_requires_tag_warning' => array(
1035
+ 'amp-ad extension .js script',
1036
+ ),
1037
+ 'disallowed_ancestor' => array(
1038
+ 'amp-app-banner',
1039
+ ),
1040
+ 'requires_extension' => array(
1041
+ 'amp-ad',
1042
+ ),
1043
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-ad',
1044
+ ),
1045
+ ),
1046
+ array(
1047
+ 'attr_spec_list' => array(
1048
+ 'alt' => array(),
1049
+ 'data-multi-size' => array(
1050
+ 'dispatch_key' => 2,
1051
+ 'mandatory' => true,
1052
+ 'value' => '',
1053
+ ),
1054
+ 'json' => array(),
1055
+ 'media' => array(),
1056
+ 'noloading' => array(
1057
+ 'value' => '',
1058
+ ),
1059
+ 'rtc-config' => array(),
1060
+ 'src' => array(
1061
+ 'blacklisted_value_regex' => '__amp_source_origin',
1062
+ 'value_url' => array(
1063
+ 'allow_relative' => true,
1064
+ 'allowed_protocol' => array(
1065
+ 'https',
1066
+ ),
1067
+ ),
1068
+ ),
1069
+ 'type' => array(
1070
+ 'mandatory' => true,
1071
+ ),
1072
+ ),
1073
+ 'tag_spec' => array(
1074
+ 'also_requires_tag_warning' => array(
1075
+ 'amp-ad extension .js script',
1076
+ ),
1077
+ 'disallowed_ancestor' => array(
1078
+ 'amp-app-banner',
1079
+ 'amp-carousel',
1080
+ 'amp-fx-flying-carpet',
1081
+ 'amp-lightbox',
1082
+ 'amp-sticky-ad',
1083
+ ),
1084
+ 'requires_extension' => array(
1085
+ 'amp-ad',
1086
+ ),
1087
+ 'spec_name' => 'amp-embed with data-multi-size attribute',
1088
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-ad',
1089
+ ),
1090
+ ),
1091
+ ),
1092
+ 'amp-experiment' => array(
1093
+ array(
1094
+ 'attr_spec_list' => array(),
1095
+ 'tag_spec' => array(
1096
+ 'requires_extension' => array(
1097
+ 'amp-experiment',
1098
+ ),
1099
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-experiment',
1100
+ 'unique' => true,
1101
+ ),
1102
+ ),
1103
+ ),
1104
+ 'amp-facebook' => array(
1105
+ array(
1106
+ 'attr_spec_list' => array(
1107
+ 'data-href' => array(
1108
+ 'mandatory' => true,
1109
+ ),
1110
+ 'media' => array(),
1111
+ 'noloading' => array(
1112
+ 'value' => '',
1113
+ ),
1114
+ ),
1115
+ 'tag_spec' => array(
1116
+ 'requires_extension' => array(
1117
+ 'amp-facebook',
1118
+ ),
1119
+ ),
1120
+ ),
1121
+ ),
1122
+ 'amp-facebook-comments' => array(
1123
+ array(
1124
+ 'attr_spec_list' => array(
1125
+ 'data-href' => array(
1126
+ 'mandatory' => true,
1127
+ ),
1128
+ 'media' => array(),
1129
+ 'noloading' => array(
1130
+ 'value' => '',
1131
+ ),
1132
+ ),
1133
+ 'tag_spec' => array(
1134
+ 'requires_extension' => array(
1135
+ 'amp-facebook-comments',
1136
+ ),
1137
+ ),
1138
+ ),
1139
+ ),
1140
+ 'amp-facebook-like' => array(
1141
+ array(
1142
+ 'attr_spec_list' => array(
1143
+ 'data-href' => array(
1144
+ 'mandatory' => true,
1145
+ 'value_url' => array(
1146
+ 'allow_relative' => false,
1147
+ 'allowed_protocol' => array(
1148
+ 'http',
1149
+ 'https',
1150
+ ),
1151
+ ),
1152
+ ),
1153
+ 'media' => array(),
1154
+ 'noloading' => array(
1155
+ 'value' => '',
1156
+ ),
1157
+ ),
1158
+ 'tag_spec' => array(
1159
+ 'requires_extension' => array(
1160
+ 'amp-facebook-like',
1161
+ ),
1162
+ ),
1163
+ ),
1164
+ ),
1165
+ 'amp-facebook-page' => array(
1166
+ array(
1167
+ 'attr_spec_list' => array(
1168
+ 'data-href' => array(
1169
+ 'mandatory' => true,
1170
+ 'value_url' => array(
1171
+ 'allow_relative' => false,
1172
+ 'allowed_protocol' => array(
1173
+ 'http',
1174
+ 'https',
1175
+ ),
1176
+ ),
1177
+ ),
1178
+ 'media' => array(),
1179
+ 'noloading' => array(
1180
+ 'value' => '',
1181
+ ),
1182
+ ),
1183
+ 'tag_spec' => array(
1184
+ 'requires_extension' => array(
1185
+ 'amp-facebook-page',
1186
+ ),
1187
+ ),
1188
+ ),
1189
+ ),
1190
+ 'amp-fit-text' => array(
1191
+ array(
1192
+ 'attr_spec_list' => array(
1193
+ 'max-font-size' => array(),
1194
+ 'media' => array(),
1195
+ 'min-font-size' => array(),
1196
+ 'noloading' => array(
1197
+ 'value' => '',
1198
+ ),
1199
+ ),
1200
+ 'tag_spec' => array(
1201
+ 'requires_extension' => array(
1202
+ 'amp-fit-text',
1203
+ ),
1204
+ ),
1205
+ ),
1206
+ ),
1207
+ 'amp-font' => array(
1208
+ array(
1209
+ 'attr_spec_list' => array(
1210
+ 'font-family' => array(
1211
+ 'mandatory' => true,
1212
+ ),
1213
+ 'font-style' => array(),
1214
+ 'font-variant' => array(),
1215
+ 'font-weight' => array(),
1216
+ 'media' => array(),
1217
+ 'noloading' => array(
1218
+ 'value' => '',
1219
+ ),
1220
+ 'on-error-add-class' => array(),
1221
+ 'on-error-remove-class' => array(),
1222
+ 'on-load-add-class' => array(),
1223
+ 'on-load-remove-class' => array(),
1224
+ 'timeout' => array(
1225
+ 'value_regex' => '[0-9]+',
1226
+ ),
1227
+ ),
1228
+ 'tag_spec' => array(
1229
+ 'requires_extension' => array(
1230
+ 'amp-font',
1231
+ ),
1232
+ ),
1233
+ ),
1234
+ ),
1235
+ 'amp-fx-flying-carpet' => array(
1236
+ array(
1237
+ 'attr_spec_list' => array(
1238
+ 'height' => array(
1239
+ 'mandatory' => true,
1240
+ ),
1241
+ 'media' => array(),
1242
+ 'noloading' => array(
1243
+ 'value' => '',
1244
+ ),
1245
+ ),
1246
+ 'tag_spec' => array(
1247
+ 'requires_extension' => array(
1248
+ 'amp-fx-flying-carpet',
1249
+ ),
1250
+ ),
1251
+ ),
1252
+ ),
1253
+ 'amp-gfycat' => array(
1254
+ array(
1255
+ 'attr_spec_list' => array(
1256
+ 'data-gfyid' => array(
1257
+ 'mandatory' => true,
1258
+ ),
1259
+ 'media' => array(),
1260
+ 'noautoplay' => array(
1261
+ 'value' => '',
1262
+ ),
1263
+ 'noloading' => array(
1264
+ 'value' => '',
1265
+ ),
1266
+ ),
1267
+ 'tag_spec' => array(
1268
+ 'requires_extension' => array(
1269
+ 'amp-gfycat',
1270
+ ),
1271
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-gfycat',
1272
+ ),
1273
+ ),
1274
+ ),
1275
+ 'amp-gist' => array(
1276
+ array(
1277
+ 'attr_spec_list' => array(
1278
+ 'data-gistid' => array(
1279
+ 'mandatory' => true,
1280
+ ),
1281
+ 'media' => array(),
1282
+ 'noloading' => array(
1283
+ 'value' => '',
1284
+ ),
1285
+ ),
1286
+ 'tag_spec' => array(
1287
+ 'requires_extension' => array(
1288
+ 'amp-gist',
1289
+ ),
1290
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-gist',
1291
+ ),
1292
+ ),
1293
+ ),
1294
+ 'amp-hulu' => array(
1295
+ array(
1296
+ 'attr_spec_list' => array(
1297
+ 'data-eid' => array(
1298
+ 'mandatory' => true,
1299
+ ),
1300
+ 'media' => array(),
1301
+ 'noloading' => array(
1302
+ 'value' => '',
1303
+ ),
1304
+ ),
1305
+ 'tag_spec' => array(
1306
+ 'requires_extension' => array(
1307
+ 'amp-hulu',
1308
+ ),
1309
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-hulu',
1310
+ ),
1311
+ ),
1312
+ ),
1313
+ 'amp-iframe' => array(
1314
+ array(
1315
+ 'attr_spec_list' => array(
1316
+ '[src]' => array(),
1317
+ 'allow' => array(),
1318
+ 'allowfullscreen' => array(
1319
+ 'value' => '',
1320
+ ),
1321
+ 'allowpaymentrequest' => array(
1322
+ 'value' => '',
1323
+ ),
1324
+ 'allowtransparency' => array(
1325
+ 'value' => '',
1326
+ ),
1327
+ 'frameborder' => array(
1328
+ 'value_regex' => '0|1',
1329
+ ),
1330
+ 'media' => array(),
1331
+ 'noloading' => array(
1332
+ 'value' => '',
1333
+ ),
1334
+ 'referrerpolicy' => array(),
1335
+ 'resizable' => array(
1336
+ 'value' => '',
1337
+ ),
1338
+ 'sandbox' => array(),
1339
+ 'scrolling' => array(
1340
+ 'value_regex' => 'auto|yes|no',
1341
+ ),
1342
+ 'src' => array(
1343
+ 'blacklisted_value_regex' => '__amp_source_origin',
1344
+ 'value_url' => array(
1345
+ 'allow_relative' => true,
1346
+ 'allowed_protocol' => array(
1347
+ 'data',
1348
+ 'https',
1349
+ ),
1350
+ ),
1351
+ ),
1352
+ 'srcdoc' => array(),
1353
+ ),
1354
+ 'tag_spec' => array(
1355
+ 'requires_extension' => array(
1356
+ 'amp-iframe',
1357
+ ),
1358
+ ),
1359
+ ),
1360
+ ),
1361
+ 'amp-ima-video' => array(
1362
+ array(
1363
+ 'attr_spec_list' => array(
1364
+ 'autoplay' => array(
1365
+ 'value' => '',
1366
+ ),
1367
+ 'data-src' => array(
1368
+ 'blacklisted_value_regex' => '__amp_source_origin',
1369
+ 'value_url' => array(
1370
+ 'allow_relative' => true,
1371
+ 'allowed_protocol' => array(
1372
+ 'https',
1373
+ ),
1374
+ ),
1375
+ ),
1376
+ 'data-tag' => array(
1377
+ 'mandatory' => true,
1378
+ 'value_url' => array(
1379
+ 'allow_relative' => true,
1380
+ 'allowed_protocol' => array(
1381
+ 'https',
1382
+ ),
1383
+ ),
1384
+ ),
1385
+ 'media' => array(),
1386
+ 'noloading' => array(
1387
+ 'value' => '',
1388
+ ),
1389
+ ),
1390
+ 'tag_spec' => array(
1391
+ 'requires_extension' => array(
1392
+ 'amp-ima-video',
1393
+ ),
1394
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-ima-video',
1395
+ ),
1396
+ ),
1397
+ ),
1398
+ 'amp-image-lightbox' => array(
1399
+ array(
1400
+ 'attr_spec_list' => array(
1401
+ 'controls' => array(),
1402
+ 'media' => array(),
1403
+ 'noloading' => array(
1404
+ 'value' => '',
1405
+ ),
1406
+ ),
1407
+ 'tag_spec' => array(
1408
+ 'requires_extension' => array(
1409
+ 'amp-image-lightbox',
1410
+ ),
1411
+ ),
1412
+ ),
1413
+ ),
1414
+ 'amp-img' => array(
1415
+ array(
1416
+ 'attr_spec_list' => array(
1417
+ '[alt]' => array(),
1418
+ '[attribution]' => array(),
1419
+ '[src]' => array(),
1420
+ '[srcset]' => array(),
1421
+ 'alt' => array(),
1422
+ 'attribution' => array(),
1423
+ 'lightbox' => array(),
1424
+ 'lightbox-exclude' => array(
1425
+ 'value' => '',
1426
+ ),
1427
+ 'lightbox-thumbnail-id' => array(
1428
+ 'value_regex_casei' => '^[a-z][a-z\\d_-]*',
1429
+ ),
1430
+ 'media' => array(),
1431
+ 'noloading' => array(
1432
+ 'value' => '',
1433
+ ),
1434
+ 'placeholder' => array(),
1435
+ 'src' => array(
1436
+ 'alternative_names' => array(
1437
+ 'srcset',
1438
+ ),
1439
+ 'blacklisted_value_regex' => '__amp_source_origin',
1440
+ 'mandatory' => true,
1441
+ 'value_url' => array(
1442
+ 'allow_relative' => true,
1443
+ 'allowed_protocol' => array(
1444
+ 'data',
1445
+ 'http',
1446
+ 'https',
1447
+ ),
1448
+ ),
1449
+ ),
1450
+ ),
1451
+ 'tag_spec' => array(
1452
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-img',
1453
+ ),
1454
+ ),
1455
+ ),
1456
+ 'amp-imgur' => array(
1457
+ array(
1458
+ 'attr_spec_list' => array(
1459
+ 'data-imgur-id' => array(
1460
+ 'mandatory' => true,
1461
+ ),
1462
+ 'media' => array(),
1463
+ 'noloading' => array(
1464
+ 'value' => '',
1465
+ ),
1466
+ ),
1467
+ 'tag_spec' => array(
1468
+ 'requires_extension' => array(
1469
+ 'amp-imgur',
1470
+ ),
1471
+ ),
1472
+ ),
1473
+ ),
1474
+ 'amp-instagram' => array(
1475
+ array(
1476
+ 'attr_spec_list' => array(
1477
+ 'alt' => array(),
1478
+ 'data-shortcode' => array(
1479
+ 'mandatory' => true,
1480
+ ),
1481
+ 'media' => array(),
1482
+ 'noloading' => array(
1483
+ 'value' => '',
1484
+ ),
1485
+ ),
1486
+ 'tag_spec' => array(
1487
+ 'requires_extension' => array(
1488
+ 'amp-instagram',
1489
+ ),
1490
+ ),
1491
+ ),
1492
+ ),
1493
+ 'amp-install-serviceworker' => array(
1494
+ array(
1495
+ 'attr_spec_list' => array(
1496
+ 'data-iframe-src' => array(
1497
+ 'blacklisted_value_regex' => '__amp_source_origin',
1498
+ 'value_url' => array(
1499
+ 'allow_relative' => true,
1500
+ 'allowed_protocol' => array(
1501
+ 'https',
1502
+ ),
1503
+ ),
1504
+ ),
1505
+ 'src' => array(
1506
+ 'blacklisted_value_regex' => '__amp_source_origin',
1507
+ 'mandatory' => true,
1508
+ 'value_url' => array(
1509
+ 'allow_relative' => true,
1510
+ 'allowed_protocol' => array(
1511
+ 'https',
1512
+ ),
1513
+ ),
1514
+ ),
1515
+ ),
1516
+ 'tag_spec' => array(
1517
+ 'requires_extension' => array(
1518
+ 'amp-install-serviceworker',
1519
+ ),
1520
+ ),
1521
+ ),
1522
+ ),
1523
+ 'amp-izlesene' => array(
1524
+ array(
1525
+ 'attr_spec_list' => array(
1526
+ 'data-videoid' => array(
1527
+ 'mandatory' => true,
1528
+ 'value_regex' => '[0-9]+',
1529
+ ),
1530
+ 'media' => array(),
1531
+ 'noloading' => array(
1532
+ 'value' => '',
1533
+ ),
1534
+ ),
1535
+ 'tag_spec' => array(
1536
+ 'requires_extension' => array(
1537
+ 'amp-izlesene',
1538
+ ),
1539
+ ),
1540
+ ),
1541
+ ),
1542
+ 'amp-jwplayer' => array(
1543
+ array(
1544
+ 'attr_spec_list' => array(
1545
+ 'data-media-id' => array(
1546
+ 'value_regex_casei' => '[0-9a-z]{8}',
1547
+ ),
1548
+ 'data-player-id' => array(
1549
+ 'mandatory' => true,
1550
+ 'value_regex_casei' => '[0-9a-z]{8}',
1551
+ ),
1552
+ 'data-playlist-id' => array(
1553
+ 'value_regex_casei' => '[0-9a-z]{8}',
1554
+ ),
1555
+ ),
1556
+ 'tag_spec' => array(
1557
+ 'requires_extension' => array(
1558
+ 'amp-jwplayer',
1559
+ ),
1560
+ ),
1561
+ ),
1562
+ ),
1563
+ 'amp-kaltura-player' => array(
1564
+ array(
1565
+ 'attr_spec_list' => array(
1566
+ 'data-partner' => array(
1567
+ 'mandatory' => true,
1568
+ ),
1569
+ 'media' => array(),
1570
+ 'noloading' => array(
1571
+ 'value' => '',
1572
+ ),
1573
+ ),
1574
+ 'tag_spec' => array(
1575
+ 'requires_extension' => array(
1576
+ 'amp-kaltura-player',
1577
+ ),
1578
+ ),
1579
+ ),
1580
+ ),
1581
+ 'amp-layout' => array(
1582
+ array(
1583
+ 'attr_spec_list' => array(
1584
+ 'media' => array(),
1585
+ 'noloading' => array(
1586
+ 'value' => '',
1587
+ ),
1588
+ ),
1589
+ 'tag_spec' => array(
1590
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-layout',
1591
+ ),
1592
+ ),
1593
+ ),
1594
+ 'amp-lightbox' => array(
1595
+ array(
1596
+ 'attr_spec_list' => array(
1597
+ 'controls' => array(),
1598
+ 'from' => array(),
1599
+ 'media' => array(),
1600
+ 'noloading' => array(
1601
+ 'value' => '',
1602
+ ),
1603
+ 'scrollable' => array(),
1604
+ ),
1605
+ 'tag_spec' => array(
1606
+ 'requires_extension' => array(
1607
+ 'amp-lightbox',
1608
+ ),
1609
+ ),
1610
+ ),
1611
+ ),
1612
+ 'amp-list' => array(
1613
+ array(
1614
+ 'attr_spec_list' => array(
1615
+ '[src]' => array(),
1616
+ '[state]' => array(),
1617
+ 'credentials' => array(),
1618
+ 'items' => array(),
1619
+ 'max-items' => array(),
1620
+ 'media' => array(),
1621
+ 'noloading' => array(
1622
+ 'value' => '',
1623
+ ),
1624
+ 'reset-on-refresh' => array(
1625
+ 'value' => '',
1626
+ ),
1627
+ 'single-item' => array(),
1628
+ 'src' => array(
1629
+ 'blacklisted_value_regex' => '__amp_source_origin',
1630
+ 'mandatory' => true,
1631
+ 'value_url' => array(
1632
+ 'allow_relative' => true,
1633
+ 'allowed_protocol' => array(
1634
+ 'https',
1635
+ ),
1636
+ ),
1637
+ ),
1638
+ 'template' => array(),
1639
+ ),
1640
+ 'tag_spec' => array(
1641
+ 'requires_extension' => array(
1642
+ 'amp-list',
1643
+ ),
1644
+ ),
1645
+ ),
1646
+ array(
1647
+ 'attr_spec_list' => array(
1648
+ '[src]' => array(
1649
+ 'mandatory' => true,
1650
+ ),
1651
+ 'credentials' => array(),
1652
+ 'items' => array(),
1653
+ 'max-items' => array(),
1654
+ 'media' => array(),
1655
+ 'noloading' => array(
1656
+ 'value' => '',
1657
+ ),
1658
+ 'single-item' => array(),
1659
+ 'src' => array(
1660
+ 'blacklisted_value_regex' => '__amp_source_origin',
1661
+ 'value_url' => array(
1662
+ 'allow_relative' => true,
1663
+ 'allowed_protocol' => array(
1664
+ 'https',
1665
+ ),
1666
+ ),
1667
+ ),
1668
+ 'template' => array(),
1669
+ ),
1670
+ 'tag_spec' => array(
1671
+ 'requires_extension' => array(
1672
+ 'amp-list',
1673
+ ),
1674
+ 'spec_name' => 'AMP-LIST [SRC]',
1675
+ ),
1676
+ ),
1677
+ ),
1678
+ 'amp-live-list' => array(
1679
+ array(
1680
+ 'attr_spec_list' => array(
1681
+ 'data-max-items-per-page' => array(
1682
+ 'mandatory' => true,
1683
+ 'value_regex' => '\\d+',
1684
+ ),
1685
+ 'data-poll-interval' => array(
1686
+ 'value_regex' => '\\d{5,}',
1687
+ ),
1688
+ 'disabled' => array(
1689
+ 'value' => '',
1690
+ ),
1691
+ 'id' => array(
1692
+ 'mandatory' => true,
1693
+ ),
1694
+ 'sort' => array(
1695
+ 'value_regex' => 'ascending',
1696
+ ),
1697
+ ),
1698
+ 'tag_spec' => array(
1699
+ 'requires_extension' => array(
1700
+ 'amp-live-list',
1701
+ ),
1702
+ ),
1703
+ ),
1704
+ ),
1705
+ 'amp-mathml' => array(
1706
+ array(
1707
+ 'attr_spec_list' => array(
1708
+ 'data-formula' => array(
1709
+ 'mandatory' => true,
1710
+ ),
1711
+ 'inline' => array(),
1712
+ 'media' => array(),
1713
+ 'noloading' => array(
1714
+ 'value' => '',
1715
+ ),
1716
+ ),
1717
+ 'tag_spec' => array(
1718
+ 'requires_extension' => array(
1719
+ 'amp-mathml',
1720
+ ),
1721
+ ),
1722
+ ),
1723
+ ),
1724
+ 'amp-nexxtv-player' => array(
1725
+ array(
1726
+ 'attr_spec_list' => array(
1727
+ 'data-client' => array(
1728
+ 'mandatory' => true,
1729
+ ),
1730
+ 'data-mediaid' => array(
1731
+ 'mandatory' => true,
1732
+ 'value_regex' => '[^=/?:]+',
1733
+ ),
1734
+ 'data-mode' => array(
1735
+ 'value_regex' => 'api|static',
1736
+ ),
1737
+ 'data-origin' => array(
1738
+ 'value_url' => array(
1739
+ 'allow_empty' => true,
1740
+ 'allowed_protocol' => array(
1741
+ 'https',
1742
+ 'http',
1743
+ ),
1744
+ ),
1745
+ ),
1746
+ 'data-streamtype' => array(
1747
+ 'value_regex' => 'album|audio|live|playlist|playlist-marked|video',
1748
+ ),
1749
+ 'media' => array(),
1750
+ 'noloading' => array(
1751
+ 'value' => '',
1752
+ ),
1753
+ ),
1754
+ 'tag_spec' => array(
1755
+ 'requires_extension' => array(
1756
+ 'amp-nexxtv-player',
1757
+ ),
1758
+ ),
1759
+ ),
1760
+ ),
1761
+ 'amp-o2-player' => array(
1762
+ array(
1763
+ 'attr_spec_list' => array(
1764
+ 'data-bcid' => array(
1765
+ 'mandatory' => true,
1766
+ ),
1767
+ 'data-pid' => array(
1768
+ 'mandatory' => true,
1769
+ ),
1770
+ 'media' => array(),
1771
+ 'noloading' => array(
1772
+ 'value' => '',
1773
+ ),
1774
+ ),
1775
+ 'tag_spec' => array(
1776
+ 'requires_extension' => array(
1777
+ 'amp-o2-player',
1778
+ ),
1779
+ ),
1780
+ ),
1781
+ ),
1782
+ 'amp-ooyala-player' => array(
1783
+ array(
1784
+ 'attr_spec_list' => array(
1785
+ 'data-embedcode' => array(
1786
+ 'mandatory' => true,
1787
+ ),
1788
+ 'data-pcode' => array(
1789
+ 'mandatory' => true,
1790
+ ),
1791
+ 'data-playerid' => array(
1792
+ 'mandatory' => true,
1793
+ ),
1794
+ 'media' => array(),
1795
+ 'noloading' => array(
1796
+ 'value' => '',
1797
+ ),
1798
+ ),
1799
+ 'tag_spec' => array(
1800
+ 'requires_extension' => array(
1801
+ 'amp-ooyala-player',
1802
+ ),
1803
+ ),
1804
+ ),
1805
+ ),
1806
+ 'amp-pinterest' => array(
1807
+ array(
1808
+ 'attr_spec_list' => array(
1809
+ 'alt' => array(),
1810
+ 'data-do' => array(
1811
+ 'mandatory' => true,
1812
+ ),
1813
+ 'media' => array(),
1814
+ 'noloading' => array(
1815
+ 'value' => '',
1816
+ ),
1817
+ ),
1818
+ 'tag_spec' => array(
1819
+ 'requires_extension' => array(
1820
+ 'amp-pinterest',
1821
+ ),
1822
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-pinterest',
1823
+ ),
1824
+ ),
1825
+ ),
1826
+ 'amp-pixel' => array(
1827
+ array(
1828
+ 'attr_spec_list' => array(
1829
+ 'allow-ssr-img' => array(),
1830
+ 'media' => array(),
1831
+ 'noloading' => array(
1832
+ 'value' => '',
1833
+ ),
1834
+ 'referrerpolicy' => array(
1835
+ 'value' => 'no-referrer',
1836
+ ),
1837
+ 'src' => array(
1838
+ 'blacklisted_value_regex' => '__amp_source_origin',
1839
+ 'mandatory' => true,
1840
+ 'value_url' => array(
1841
+ 'allow_empty' => true,
1842
+ 'allow_relative' => true,
1843
+ 'allowed_protocol' => array(
1844
+ 'https',
1845
+ ),
1846
+ ),
1847
+ ),
1848
+ ),
1849
+ 'tag_spec' => array(
1850
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-pixel',
1851
+ ),
1852
+ ),
1853
+ ),
1854
+ 'amp-playbuzz' => array(
1855
+ array(
1856
+ 'attr_spec_list' => array(
1857
+ 'data-comments' => array(
1858
+ 'value_regex_casei' => '(false|true)',
1859
+ ),
1860
+ 'data-item' => array(),
1861
+ 'data-item-info' => array(
1862
+ 'value_regex_casei' => '(false|true)',
1863
+ ),
1864
+ 'data-share-buttons' => array(
1865
+ 'value_regex_casei' => '(false|true)',
1866
+ ),
1867
+ 'media' => array(),
1868
+ 'noloading' => array(
1869
+ 'value' => '',
1870
+ ),
1871
+ 'src' => array(),
1872
+ ),
1873
+ 'tag_spec' => array(
1874
+ 'requires_extension' => array(
1875
+ 'amp-playbuzz',
1876
+ ),
1877
+ ),
1878
+ ),
1879
+ ),
1880
+ 'amp-position-observer' => array(
1881
+ array(
1882
+ 'attr_spec_list' => array(
1883
+ 'intersection-ratios' => array(
1884
+ 'value_regex' => '^([0]*?\\.\\d*$|1$|0$)|([0]*?\\.\\d*|1|0)\\s{1}([0]*?\\.\\d*$|1$|0$)',
1885
+ ),
1886
+ 'media' => array(),
1887
+ 'noloading' => array(
1888
+ 'value' => '',
1889
+ ),
1890
+ 'target' => array(),
1891
+ 'viewport-margins' => array(
1892
+ 'value_regex' => '^(\\d+$|\\d+px$|\\d+vh$)|((\\d+|\\d+px|\\d+vh)\\s{1}(\\d+$|\\d+px$|\\d+vh$))',
1893
+ ),
1894
+ ),
1895
+ 'tag_spec' => array(
1896
+ 'requires_extension' => array(
1897
+ 'amp-position-observer',
1898
+ ),
1899
+ ),
1900
+ ),
1901
+ ),
1902
+ 'amp-reach-player' => array(
1903
+ array(
1904
+ 'attr_spec_list' => array(
1905
+ 'data-embed-id' => array(
1906
+ 'mandatory' => true,
1907
+ 'value_regex' => '[0-9a-z-]+',
1908
+ ),
1909
+ 'media' => array(),
1910
+ 'noloading' => array(
1911
+ 'value' => '',
1912
+ ),
1913
+ ),
1914
+ 'tag_spec' => array(
1915
+ 'requires_extension' => array(
1916
+ 'amp-reach-player',
1917
+ ),
1918
+ ),
1919
+ ),
1920
+ ),
1921
+ 'amp-reddit' => array(
1922
+ array(
1923
+ 'attr_spec_list' => array(
1924
+ 'data-embedlive' => array(
1925
+ 'value_regex_casei' => '(false|true)',
1926
+ ),
1927
+ 'data-embedparent' => array(
1928
+ 'value_regex_casei' => '(false|true)',
1929
+ ),
1930
+ 'data-embedtype' => array(
1931
+ 'mandatory' => true,
1932
+ 'value_regex_casei' => '(comment|post)',
1933
+ ),
1934
+ 'data-src' => array(
1935
+ 'mandatory' => true,
1936
+ ),
1937
+ 'media' => array(),
1938
+ 'noloading' => array(
1939
+ 'value' => '',
1940
+ ),
1941
+ ),
1942
+ 'tag_spec' => array(
1943
+ 'requires_extension' => array(
1944
+ 'amp-reddit',
1945
+ ),
1946
+ ),
1947
+ ),
1948
+ ),
1949
+ 'amp-riddle-quiz' => array(
1950
+ array(
1951
+ 'attr_spec_list' => array(
1952
+ 'data-riddle-id' => array(
1953
+ 'mandatory' => true,
1954
+ 'value_regex' => '[0-9]+',
1955
+ ),
1956
+ 'media' => array(),
1957
+ 'noloading' => array(
1958
+ 'value' => '',
1959
+ ),
1960
+ ),
1961
+ 'tag_spec' => array(
1962
+ 'requires_extension' => array(
1963
+ 'amp-riddle-quiz',
1964
+ ),
1965
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-riddle-quiz',
1966
+ ),
1967
+ ),
1968
+ ),
1969
+ 'amp-selector' => array(
1970
+ array(
1971
+ 'attr_spec_list' => array(
1972
+ '[disabled]' => array(),
1973
+ '[selected]' => array(),
1974
+ 'disabled' => array(
1975
+ 'value' => '',
1976
+ ),
1977
+ 'form' => array(),
1978
+ 'keyboard-select-mode' => array(
1979
+ 'value_regex_casei' => 'focus|none|select',
1980
+ ),
1981
+ 'media' => array(),
1982
+ 'multiple' => array(
1983
+ 'value' => '',
1984
+ ),
1985
+ 'name' => array(
1986
+ 'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
1987
+ ),
1988
+ 'noloading' => array(
1989
+ 'value' => '',
1990
+ ),
1991
+ ),
1992
+ 'tag_spec' => array(
1993
+ 'disallowed_ancestor' => array(
1994
+ 'amp-selector',
1995
+ ),
1996
+ 'requires_extension' => array(
1997
+ 'amp-selector',
1998
+ ),
1999
+ ),
2000
+ ),
2001
+ ),
2002
+ 'amp-sidebar' => array(
2003
+ array(
2004
+ 'attr_spec_list' => array(
2005
+ 'media' => array(),
2006
+ 'noloading' => array(
2007
+ 'value' => '',
2008
+ ),
2009
+ 'side' => array(
2010
+ 'value_regex' => '(left|right)',
2011
+ ),
2012
+ ),
2013
+ 'tag_spec' => array(
2014
+ 'mandatory_parent' => 'body',
2015
+ 'requires_extension' => array(
2016
+ 'amp-sidebar',
2017
+ ),
2018
+ ),
2019
+ ),
2020
+ ),
2021
+ 'amp-social-share' => array(
2022
+ array(
2023
+ 'attr_spec_list' => array(
2024
+ 'data-share-endpoint' => array(
2025
+ 'blacklisted_value_regex' => '__amp_source_origin',
2026
+ 'value_url' => array(
2027
+ 'allow_relative' => false,
2028
+ 'allowed_protocol' => array(
2029
+ 'ftp',
2030
+ 'http',
2031
+ 'https',
2032
+ 'mailto',
2033
+ 'bbmi',
2034
+ 'fb-messenger',
2035
+ 'intent',
2036
+ 'line',
2037
+ 'skype',
2038
+ 'sms',
2039
+ 'snapchat',
2040
+ 'tel',
2041
+ 'tg',
2042
+ 'threema',
2043
+ 'viber',
2044
+ 'whatsapp',
2045
+ ),
2046
+ ),
2047
+ ),
2048
+ 'media' => array(),
2049
+ 'noloading' => array(
2050
+ 'value' => '',
2051
+ ),
2052
+ 'type' => array(
2053
+ 'mandatory' => true,
2054
+ ),
2055
+ ),
2056
+ 'tag_spec' => array(
2057
+ 'requires_extension' => array(
2058
+ 'amp-social-share',
2059
+ ),
2060
+ ),
2061
+ ),
2062
+ ),
2063
+ 'amp-soundcloud' => array(
2064
+ array(
2065
+ 'attr_spec_list' => array(
2066
+ 'data-color' => array(
2067
+ 'value_regex_casei' => '([0-9a-f]{3}){1,2}',
2068
+ ),
2069
+ 'data-playlistid' => array(
2070
+ 'value_regex' => '[0-9]+',
2071
+ ),
2072
+ 'data-secret-token' => array(
2073
+ 'value_regex' => '[A-Za-z0-9_-]+',
2074
+ ),
2075
+ 'data-trackid' => array(
2076
+ 'value_regex' => '[0-9]+',
2077
+ ),
2078
+ 'data-visual' => array(
2079
+ 'value_regex' => 'true|false',
2080
+ ),
2081
+ 'media' => array(),
2082
+ 'noloading' => array(
2083
+ 'value' => '',
2084
+ ),
2085
+ ),
2086
+ 'tag_spec' => array(
2087
+ 'requires_extension' => array(
2088
+ 'amp-soundcloud',
2089
+ ),
2090
+ ),
2091
+ ),
2092
+ ),
2093
+ 'amp-springboard-player' => array(
2094
+ array(
2095
+ 'attr_spec_list' => array(
2096
+ 'data-content-id' => array(
2097
+ 'mandatory' => true,
2098
+ ),
2099
+ 'data-domain' => array(
2100
+ 'mandatory' => true,
2101
+ ),
2102
+ 'data-items' => array(
2103
+ 'mandatory' => true,
2104
+ ),
2105
+ 'data-mode' => array(
2106
+ 'mandatory' => true,
2107
+ 'value_regex_casei' => 'playlist|video',
2108
+ ),
2109
+ 'data-player-id' => array(
2110
+ 'mandatory' => true,
2111
+ 'value_regex_casei' => '[a-z0-9]+',
2112
+ ),
2113
+ 'data-site-id' => array(
2114
+ 'mandatory' => true,
2115
+ 'value_regex' => '[0-9]+',
2116
+ ),
2117
+ 'media' => array(),
2118
+ 'noloading' => array(
2119
+ 'value' => '',
2120
+ ),
2121
+ ),
2122
+ 'tag_spec' => array(
2123
+ 'requires_extension' => array(
2124
+ 'amp-springboard-player',
2125
+ ),
2126
+ ),
2127
+ ),
2128
+ ),
2129
+ 'amp-state' => array(
2130
+ array(
2131
+ 'attr_spec_list' => array(
2132
+ '[src]' => array(),
2133
+ 'credentials' => array(),
2134
+ 'id' => array(
2135
+ 'mandatory' => true,
2136
+ ),
2137
+ 'overridable' => array(),
2138
+ 'src' => array(
2139
+ 'blacklisted_value_regex' => '__amp_source_origin',
2140
+ 'value_url' => array(
2141
+ 'allow_relative' => true,
2142
+ 'allowed_protocol' => array(
2143
+ 'https',
2144
+ ),
2145
+ ),
2146
+ ),
2147
+ ),
2148
+ 'tag_spec' => array(
2149
+ 'requires_extension' => array(
2150
+ 'amp-bind',
2151
+ ),
2152
+ 'spec_name' => 'amp-state',
2153
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-bind',
2154
+ ),
2155
+ ),
2156
+ ),
2157
+ 'amp-sticky-ad' => array(
2158
+ array(
2159
+ 'attr_spec_list' => array(
2160
+ 'media' => array(),
2161
+ 'noloading' => array(
2162
+ 'value' => '',
2163
+ ),
2164
+ ),
2165
+ 'tag_spec' => array(
2166
+ 'disallowed_ancestor' => array(
2167
+ 'amp-app-banner',
2168
+ ),
2169
+ 'requires_extension' => array(
2170
+ 'amp-sticky-ad',
2171
+ ),
2172
+ 'unique' => true,
2173
+ ),
2174
+ ),
2175
+ ),
2176
+ 'amp-story' => array(
2177
+ array(
2178
+ 'attr_spec_list' => array(
2179
+ 'background-audio' => array(
2180
+ 'value_url' => array(
2181
+ 'allowed_protocol' => array(
2182
+ 'http',
2183
+ 'https',
2184
+ ),
2185
+ ),
2186
+ ),
2187
+ 'bookend-config-src' => array(
2188
+ 'value_url' => array(
2189
+ 'allowed_protocol' => array(
2190
+ 'http',
2191
+ 'https',
2192
+ ),
2193
+ ),
2194
+ ),
2195
+ 'standalone' => array(
2196
+ 'mandatory' => true,
2197
+ 'value' => '',
2198
+ ),
2199
+ ),
2200
+ 'tag_spec' => array(
2201
+ 'mandatory_parent' => 'body',
2202
+ 'requires_extension' => array(
2203
+ 'amp-story',
2204
+ ),
2205
+ ),
2206
+ ),
2207
+ ),
2208
+ 'amp-story-auto-ads' => array(
2209
+ array(
2210
+ 'attr_spec_list' => array(),
2211
+ 'tag_spec' => array(
2212
+ 'mandatory_parent' => 'amp-story',
2213
+ 'requires_extension' => array(
2214
+ 'amp-story-auto-ads',
2215
+ ),
2216
+ 'spec_url' => 'https://github.com/ampproject/amphtml/blob/master/extensions/amp-story/amp-story-auto-ads.md',
2217
+ 'unique' => true,
2218
+ ),
2219
+ ),
2220
+ ),
2221
+ 'amp-story-cta-layer' => array(
2222
+ array(
2223
+ 'attr_spec_list' => array(),
2224
+ 'tag_spec' => array(
2225
+ 'mandatory_ancestor' => 'amp-story-page',
2226
+ ),
2227
+ ),
2228
+ ),
2229
+ 'amp-story-grid-layer' => array(
2230
+ array(
2231
+ 'attr_spec_list' => array(
2232
+ 'template' => array(
2233
+ 'mandatory' => true,
2234
+ 'value_regex' => '(fill|horizontal|vertical|thirds)',
2235
+ ),
2236
+ ),
2237
+ 'tag_spec' => array(
2238
+ 'mandatory_ancestor' => 'amp-story-page',
2239
+ ),
2240
+ ),
2241
+ ),
2242
+ 'amp-story-page' => array(
2243
+ array(
2244
+ 'attr_spec_list' => array(
2245
+ 'auto-advance-after' => array(),
2246
+ 'background-audio' => array(
2247
+ 'value_url' => array(
2248
+ 'allowed_protocol' => array(
2249
+ 'http',
2250
+ 'https',
2251
+ ),
2252
+ ),
2253
+ ),
2254
+ 'id' => array(
2255
+ 'mandatory' => true,
2256
+ ),
2257
+ ),
2258
+ 'tag_spec' => array(
2259
+ 'mandatory_parent' => 'amp-story',
2260
+ 'requires_extension' => array(
2261
+ 'amp-story',
2262
+ ),
2263
+ ),
2264
+ ),
2265
+ ),
2266
+ 'amp-timeago' => array(
2267
+ array(
2268
+ 'attr_spec_list' => array(
2269
+ 'cutoff' => array(
2270
+ 'value_regex' => '\\d+',
2271
+ ),
2272
+ 'datetime' => array(
2273
+ 'mandatory' => true,
2274
+ 'value_regex' => '\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d(:[0-5]\\d(\\.\\d+)?)?(Z|[+-][0-1][0-9]:[0-5][0-9])',
2275
+ ),
2276
+ 'locale' => array(),
2277
+ 'media' => array(),
2278
+ 'noloading' => array(
2279
+ 'value' => '',
2280
+ ),
2281
+ ),
2282
+ 'tag_spec' => array(
2283
+ 'requires_extension' => array(
2284
+ 'amp-timeago',
2285
+ ),
2286
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-timeago',
2287
+ ),
2288
+ ),
2289
+ ),
2290
+ 'amp-twitter' => array(
2291
+ array(
2292
+ 'attr_spec_list' => array(
2293
+ 'data-tweetid' => array(
2294
+ 'mandatory' => true,
2295
+ ),
2296
+ 'media' => array(),
2297
+ 'noloading' => array(
2298
+ 'value' => '',
2299
+ ),
2300
+ ),
2301
+ 'tag_spec' => array(
2302
+ 'requires_extension' => array(
2303
+ 'amp-twitter',
2304
+ ),
2305
+ ),
2306
+ ),
2307
+ ),
2308
+ 'amp-user-notification' => array(
2309
+ array(
2310
+ 'attr_spec_list' => array(
2311
+ 'data-dismiss-href' => array(
2312
+ 'value_url' => array(
2313
+ 'allow_empty' => false,
2314
+ 'allow_relative' => false,
2315
+ 'allowed_protocol' => array(
2316
+ 'https',
2317
+ ),
2318
+ ),
2319
+ ),
2320
+ 'data-show-if-href' => array(
2321
+ 'value_url' => array(
2322
+ 'allow_empty' => false,
2323
+ 'allow_relative' => false,
2324
+ 'allowed_protocol' => array(
2325
+ 'https',
2326
+ ),
2327
+ ),
2328
+ ),
2329
+ 'enctype' => array(
2330
+ 'value' => 'application/x-www-form-urlencoded',
2331
+ ),
2332
+ 'media' => array(),
2333
+ 'noloading' => array(
2334
+ 'value' => '',
2335
+ ),
2336
+ ),
2337
+ 'tag_spec' => array(
2338
+ 'requires_extension' => array(
2339
+ 'amp-user-notification',
2340
+ ),
2341
+ ),
2342
+ ),
2343
+ ),
2344
+ 'amp-video' => array(
2345
+ array(
2346
+ 'attr_spec_list' => array(
2347
+ '[album]' => array(),
2348
+ '[alt]' => array(),
2349
+ '[artist]' => array(),
2350
+ '[artwork]' => array(),
2351
+ '[attribution]' => array(),
2352
+ '[controls]' => array(),
2353
+ '[controlslist]' => array(),
2354
+ '[loop]' => array(),
2355
+ '[poster]' => array(),
2356
+ '[preload]' => array(),
2357
+ '[src]' => array(),
2358
+ '[title]' => array(),
2359
+ 'album' => array(),
2360
+ 'alt' => array(),
2361
+ 'artist' => array(),
2362
+ 'artwork' => array(),
2363
+ 'attribution' => array(),
2364
+ 'autoplay' => array(
2365
+ 'value' => '',
2366
+ ),
2367
+ 'controls' => array(
2368
+ 'value' => '',
2369
+ ),
2370
+ 'controlslist' => array(),
2371
+ 'crossorigin' => array(),
2372
+ 'disableremoteplayback' => array(
2373
+ 'value' => '',
2374
+ ),
2375
+ 'lightbox' => array(),
2376
+ 'lightbox-exclude' => array(
2377
+ 'value' => '',
2378
+ ),
2379
+ 'lightbox-thumbnail-id' => array(
2380
+ 'value_regex_casei' => '^[a-z][a-z\\d_-]*',
2381
+ ),
2382
+ 'loop' => array(
2383
+ 'value' => '',
2384
+ ),
2385
+ 'media' => array(),
2386
+ 'muted' => array(
2387
+ 'value' => '',
2388
+ ),
2389
+ 'noloading' => array(
2390
+ 'value' => '',
2391
+ ),
2392
+ 'placeholder' => array(),
2393
+ 'poster' => array(),
2394
+ 'preload' => array(
2395
+ 'value_regex' => '(none|metadata|auto|)',
2396
+ ),
2397
+ 'src' => array(
2398
+ 'blacklisted_value_regex' => '__amp_source_origin',
2399
+ 'value_url' => array(
2400
+ 'allow_relative' => true,
2401
+ 'allowed_protocol' => array(
2402
+ 'https',
2403
+ ),
2404
+ ),
2405
+ ),
2406
+ ),
2407
+ 'tag_spec' => array(
2408
+ 'also_requires_tag_warning' => array(
2409
+ 'amp-video extension .js script',
2410
+ ),
2411
+ 'disallowed_ancestor' => array(
2412
+ 'amp-story',
2413
+ ),
2414
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-video',
2415
+ ),
2416
+ ),
2417
+ array(
2418
+ 'attr_spec_list' => array(
2419
+ '[album]' => array(),
2420
+ '[alt]' => array(),
2421
+ '[artist]' => array(),
2422
+ '[artwork]' => array(),
2423
+ '[attribution]' => array(),
2424
+ '[controls]' => array(),
2425
+ '[controlslist]' => array(),
2426
+ '[loop]' => array(),
2427
+ '[poster]' => array(),
2428
+ '[preload]' => array(),
2429
+ '[src]' => array(),
2430
+ '[title]' => array(),
2431
+ 'album' => array(),
2432
+ 'alt' => array(),
2433
+ 'artist' => array(),
2434
+ 'artwork' => array(),
2435
+ 'attribution' => array(),
2436
+ 'autoplay' => array(
2437
+ 'value' => '',
2438
+ ),
2439
+ 'controls' => array(
2440
+ 'value' => '',
2441
+ ),
2442
+ 'controlslist' => array(),
2443
+ 'crossorigin' => array(),
2444
+ 'disableremoteplayback' => array(
2445
+ 'value' => '',
2446
+ ),
2447
+ 'loop' => array(
2448
+ 'value' => '',
2449
+ ),
2450
+ 'media' => array(),
2451
+ 'muted' => array(
2452
+ 'value' => '',
2453
+ ),
2454
+ 'noloading' => array(
2455
+ 'value' => '',
2456
+ ),
2457
+ 'placeholder' => array(),
2458
+ 'poster' => array(
2459
+ 'mandatory' => true,
2460
+ ),
2461
+ 'preload' => array(
2462
+ 'value_regex' => '(none|metadata|auto|)',
2463
+ ),
2464
+ 'src' => array(
2465
+ 'blacklisted_value_regex' => '__amp_source_origin',
2466
+ 'value_url' => array(
2467
+ 'allow_relative' => true,
2468
+ 'allowed_protocol' => array(
2469
+ 'https',
2470
+ ),
2471
+ ),
2472
+ ),
2473
+ ),
2474
+ 'tag_spec' => array(
2475
+ 'mandatory_ancestor' => 'amp-story',
2476
+ 'requires_extension' => array(
2477
+ 'amp-video',
2478
+ ),
2479
+ 'spec_name' => 'amp-story >> amp-video',
2480
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-video',
2481
+ ),
2482
+ ),
2483
+ ),
2484
+ 'amp-vimeo' => array(
2485
+ array(
2486
+ 'attr_spec_list' => array(
2487
+ 'data-videoid' => array(
2488
+ 'mandatory' => true,
2489
+ 'value_regex' => '[0-9]+',
2490
+ ),
2491
+ 'media' => array(),
2492
+ 'noloading' => array(
2493
+ 'value' => '',
2494
+ ),
2495
+ ),
2496
+ 'tag_spec' => array(
2497
+ 'requires_extension' => array(
2498
+ 'amp-vimeo',
2499
+ ),
2500
+ ),
2501
+ ),
2502
+ ),
2503
+ 'amp-vine' => array(
2504
+ array(
2505
+ 'attr_spec_list' => array(
2506
+ 'data-vineid' => array(
2507
+ 'mandatory' => true,
2508
+ ),
2509
+ 'media' => array(),
2510
+ 'noloading' => array(
2511
+ 'value' => '',
2512
+ ),
2513
+ ),
2514
+ 'tag_spec' => array(
2515
+ 'requires_extension' => array(
2516
+ 'amp-vine',
2517
+ ),
2518
+ ),
2519
+ ),
2520
+ ),
2521
+ 'amp-vk' => array(
2522
+ array(
2523
+ 'attr_spec_list' => array(
2524
+ 'data-embedtype' => array(
2525
+ 'mandatory' => true,
2526
+ ),
2527
+ 'media' => array(),
2528
+ 'noloading' => array(
2529
+ 'value' => '',
2530
+ ),
2531
+ ),
2532
+ 'tag_spec' => array(
2533
+ 'requires_extension' => array(
2534
+ 'amp-vk',
2535
+ ),
2536
+ ),
2537
+ ),
2538
+ ),
2539
+ 'amp-web-push' => array(
2540
+ array(
2541
+ 'attr_spec_list' => array(
2542
+ 'helper-iframe-url' => array(
2543
+ 'mandatory' => true,
2544
+ 'value_url' => array(
2545
+ 'allow_relative' => false,
2546
+ 'allowed_protocol' => array(
2547
+ 'https',
2548
+ ),
2549
+ ),
2550
+ ),
2551
+ 'id' => array(
2552
+ 'mandatory' => true,
2553
+ 'value_regex' => 'amp-web-push',
2554
+ ),
2555
+ 'media' => array(),
2556
+ 'noloading' => array(
2557
+ 'value' => '',
2558
+ ),
2559
+ 'permission-dialog-url' => array(
2560
+ 'mandatory' => true,
2561
+ 'value_url' => array(
2562
+ 'allow_relative' => false,
2563
+ 'allowed_protocol' => array(
2564
+ 'https',
2565
+ ),
2566
+ ),
2567
+ ),
2568
+ 'service-worker-url' => array(
2569
+ 'mandatory' => true,
2570
+ 'value_url' => array(
2571
+ 'allow_relative' => false,
2572
+ 'allowed_protocol' => array(
2573
+ 'https',
2574
+ ),
2575
+ ),
2576
+ ),
2577
+ ),
2578
+ 'tag_spec' => array(
2579
+ 'requires_extension' => array(
2580
+ 'amp-web-push',
2581
+ ),
2582
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-web-push',
2583
+ ),
2584
+ ),
2585
+ ),
2586
+ 'amp-web-push-widget' => array(
2587
+ array(
2588
+ 'attr_spec_list' => array(
2589
+ 'media' => array(),
2590
+ 'noloading' => array(
2591
+ 'value' => '',
2592
+ ),
2593
+ 'visibility' => array(
2594
+ 'mandatory' => true,
2595
+ 'value_regex' => '(blocked|subscribed|unsubscribed)',
2596
+ ),
2597
+ ),
2598
+ 'tag_spec' => array(
2599
+ 'requires_extension' => array(
2600
+ 'amp-web-push',
2601
+ ),
2602
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-web-push',
2603
+ ),
2604
+ ),
2605
+ ),
2606
+ 'amp-wistia-player' => array(
2607
+ array(
2608
+ 'attr_spec_list' => array(
2609
+ 'data-media-hashed-id' => array(
2610
+ 'mandatory' => true,
2611
+ 'value_regex' => '[0-9a-zA-Z]+',
2612
+ ),
2613
+ 'media' => array(),
2614
+ 'noloading' => array(
2615
+ 'value' => '',
2616
+ ),
2617
+ ),
2618
+ 'tag_spec' => array(
2619
+ 'requires_extension' => array(
2620
+ 'amp-wistia-player',
2621
+ ),
2622
+ ),
2623
+ ),
2624
+ ),
2625
+ 'amp-youtube' => array(
2626
+ array(
2627
+ 'attr_spec_list' => array(
2628
+ '[data-videoid]' => array(),
2629
+ 'autoplay' => array(),
2630
+ 'credentials' => array(
2631
+ 'value_regex_casei' => '(include|omit)',
2632
+ ),
2633
+ 'data-live-channelid' => array(
2634
+ 'value_regex' => '[^=/?:]+',
2635
+ ),
2636
+ 'data-videoid' => array(
2637
+ 'value_regex' => '[^=/?:]+',
2638
+ ),
2639
+ 'lightbox' => array(),
2640
+ 'lightbox-exclude' => array(
2641
+ 'value' => '',
2642
+ ),
2643
+ 'lightbox-thumbnail-id' => array(
2644
+ 'value_regex_casei' => '^[a-z][a-z\\d_-]*',
2645
+ ),
2646
+ 'media' => array(),
2647
+ 'noloading' => array(
2648
+ 'value' => '',
2649
+ ),
2650
+ ),
2651
+ 'tag_spec' => array(
2652
+ 'requires_extension' => array(
2653
+ 'amp-youtube',
2654
+ ),
2655
+ ),
2656
+ ),
2657
+ ),
2658
+ 'article' => array(
2659
+ array(
2660
+ 'attr_spec_list' => array(),
2661
+ 'tag_spec' => array(),
2662
+ ),
2663
+ ),
2664
+ 'aside' => array(
2665
+ array(
2666
+ 'attr_spec_list' => array(),
2667
+ 'tag_spec' => array(),
2668
+ ),
2669
+ ),
2670
+ 'audio' => array(
2671
+ array(
2672
+ 'attr_spec_list' => array(
2673
+ 'autoplay' => array(),
2674
+ 'controls' => array(),
2675
+ 'loop' => array(),
2676
+ 'muted' => array(),
2677
+ 'preload' => array(),
2678
+ 'src' => array(
2679
+ 'blacklisted_value_regex' => '__amp_source_origin',
2680
+ 'value_url' => array(
2681
+ 'allow_relative' => false,
2682
+ 'allowed_protocol' => array(
2683
+ 'data',
2684
+ 'https',
2685
+ ),
2686
+ ),
2687
+ ),
2688
+ ),
2689
+ 'tag_spec' => array(
2690
+ 'mandatory_ancestor' => 'noscript',
2691
+ 'mandatory_ancestor_suggested_alternative' => 'amp-audio',
2692
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-audio',
2693
+ ),
2694
+ ),
2695
+ ),
2696
+ 'b' => array(
2697
+ array(
2698
+ 'attr_spec_list' => array(),
2699
+ 'tag_spec' => array(),
2700
+ ),
2701
+ ),
2702
+ 'base' => array(
2703
+ array(
2704
+ 'attr_spec_list' => array(
2705
+ 'href' => array(
2706
+ 'value' => '/',
2707
+ ),
2708
+ 'target' => array(
2709
+ 'value_regex_casei' => '(_blank|_self|_top)',
2710
+ ),
2711
+ ),
2712
+ 'tag_spec' => array(
2713
+ 'mandatory_parent' => 'head',
2714
+ 'unique' => true,
2715
+ ),
2716
+ ),
2717
+ ),
2718
+ 'bdi' => array(
2719
+ array(
2720
+ 'attr_spec_list' => array(),
2721
+ 'tag_spec' => array(),
2722
+ ),
2723
+ ),
2724
+ 'bdo' => array(
2725
+ array(
2726
+ 'attr_spec_list' => array(
2727
+ 'dir' => array(),
2728
+ ),
2729
+ 'tag_spec' => array(),
2730
+ ),
2731
+ ),
2732
+ 'big' => array(
2733
+ array(
2734
+ 'attr_spec_list' => array(),
2735
+ 'tag_spec' => array(),
2736
+ ),
2737
+ ),
2738
+ 'blockquote' => array(
2739
+ array(
2740
+ 'attr_spec_list' => array(
2741
+ 'align' => array(),
2742
+ 'cite' => array(
2743
+ 'blacklisted_value_regex' => '__amp_source_origin',
2744
+ 'value_url' => array(
2745
+ 'allow_empty' => true,
2746
+ 'allow_relative' => true,
2747
+ 'allowed_protocol' => array(
2748
+ 'http',
2749
+ 'https',
2750
+ ),
2751
+ ),
2752
+ ),
2753
+ ),
2754
+ 'tag_spec' => array(),
2755
+ ),
2756
+ ),
2757
+ 'body' => array(
2758
+ array(
2759
+ 'attr_spec_list' => array(),
2760
+ 'tag_spec' => array(
2761
+ 'mandatory' => true,
2762
+ 'mandatory_parent' => 'html',
2763
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#required-markup',
2764
+ 'unique' => true,
2765
+ ),
2766
+ ),
2767
+ ),
2768
+ 'br' => array(
2769
+ array(
2770
+ 'attr_spec_list' => array(),
2771
+ 'tag_spec' => array(),
2772
+ ),
2773
+ ),
2774
+ 'button' => array(
2775
+ array(
2776
+ 'attr_spec_list' => array(
2777
+ '[disabled]' => array(),
2778
+ '[type]' => array(),
2779
+ '[value]' => array(),
2780
+ 'disabled' => array(
2781
+ 'value' => '',
2782
+ ),
2783
+ 'name' => array(
2784
+ 'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
2785
+ ),
2786
+ 'role' => array(),
2787
+ 'tabindex' => array(),
2788
+ 'type' => array(),
2789
+ 'value' => array(),
2790
+ ),
2791
+ 'tag_spec' => array(),
2792
+ ),
2793
+ array(
2794
+ 'attr_spec_list' => array(
2795
+ 'name' => array(
2796
+ 'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
2797
+ ),
2798
+ 'open-button' => array(
2799
+ 'value' => '',
2800
+ ),
2801
+ 'role' => array(),
2802
+ 'tabindex' => array(),
2803
+ 'type' => array(),
2804
+ 'value' => array(),
2805
+ ),
2806
+ 'tag_spec' => array(
2807
+ 'mandatory_ancestor' => 'amp-app-banner',
2808
+ 'spec_name' => 'amp-app-banner button[open-button]',
2809
+ ),
2810
+ ),
2811
+ ),
2812
+ 'caption' => array(
2813
+ array(
2814
+ 'attr_spec_list' => array(),
2815
+ 'tag_spec' => array(),
2816
+ ),
2817
+ ),
2818
+ 'center' => array(
2819
+ array(
2820
+ 'attr_spec_list' => array(),
2821
+ 'tag_spec' => array(),
2822
+ ),
2823
+ ),
2824
+ 'circle' => array(
2825
+ array(
2826
+ 'attr_spec_list' => array(
2827
+ 'alignment-baseline' => array(),
2828
+ 'baseline-shift' => array(),
2829
+ 'clip' => array(),
2830
+ 'clip-path' => array(),
2831
+ 'clip-rule' => array(),
2832
+ 'color' => array(),
2833
+ 'color-interpolation' => array(),
2834
+ 'color-interpolation-filters' => array(),
2835
+ 'color-profile' => array(),
2836
+ 'color-rendering' => array(),
2837
+ 'cursor' => array(),
2838
+ 'cx' => array(),
2839
+ 'cy' => array(),
2840
+ 'direction' => array(),
2841
+ 'display' => array(),
2842
+ 'dominant-baseline' => array(),
2843
+ 'enable-background' => array(),
2844
+ 'externalresourcesrequired' => array(),
2845
+ 'fill' => array(),
2846
+ 'fill-opacity' => array(),
2847
+ 'fill-rule' => array(),
2848
+ 'filter' => array(),
2849
+ 'flood-color' => array(),
2850
+ 'flood-opacity' => array(),
2851
+ 'font-family' => array(),
2852
+ 'font-size' => array(),
2853
+ 'font-size-adjust' => array(),
2854
+ 'font-stretch' => array(),
2855
+ 'font-style' => array(),
2856
+ 'font-variant' => array(),
2857
+ 'font-weight' => array(),
2858
+ 'glyph-orientation-horizontal' => array(),
2859
+ 'glyph-orientation-vertical' => array(),
2860
+ 'image-rendering' => array(),
2861
+ 'kerning' => array(),
2862
+ 'letter-spacing' => array(),
2863
+ 'lighting-color' => array(),
2864
+ 'marker-end' => array(),
2865
+ 'marker-mid' => array(),
2866
+ 'marker-start' => array(),
2867
+ 'mask' => array(),
2868
+ 'opacity' => array(),
2869
+ 'overflow' => array(),
2870
+ 'pointer-events' => array(),
2871
+ 'r' => array(),
2872
+ 'requiredextensions' => array(),
2873
+ 'requiredfeatures' => array(),
2874
+ 'shape-rendering' => array(),
2875
+ 'sketch:type' => array(),
2876
+ 'stop-color' => array(),
2877
+ 'stop-opacity' => array(),
2878
+ 'stroke' => array(),
2879
+ 'stroke-dasharray' => array(),
2880
+ 'stroke-dashoffset' => array(),
2881
+ 'stroke-linecap' => array(),
2882
+ 'stroke-linejoin' => array(),
2883
+ 'stroke-miterlimit' => array(),
2884
+ 'stroke-opacity' => array(),
2885
+ 'stroke-width' => array(),
2886
+ 'style' => array(
2887
+ 'blacklisted_value_regex' => '!important',
2888
+ ),
2889
+ 'systemlanguage' => array(),
2890
+ 'text-anchor' => array(),
2891
+ 'text-decoration' => array(),
2892
+ 'text-rendering' => array(),
2893
+ 'transform' => array(),
2894
+ 'unicode-bidi' => array(),
2895
+ 'vector-effect' => array(),
2896
+ 'visibility' => array(),
2897
+ 'word-spacing' => array(),
2898
+ 'writing-mode' => array(),
2899
+ 'xml:lang' => array(),
2900
+ 'xml:space' => array(),
2901
+ 'xmlns' => array(),
2902
+ 'xmlns:xlink' => array(),
2903
+ ),
2904
+ 'tag_spec' => array(
2905
+ 'mandatory_ancestor' => 'svg',
2906
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
2907
+ ),
2908
+ ),
2909
+ ),
2910
+ 'cite' => array(
2911
+ array(
2912
+ 'attr_spec_list' => array(),
2913
+ 'tag_spec' => array(),
2914
+ ),
2915
+ ),
2916
+ 'clippath' => array(
2917
+ array(
2918
+ 'attr_spec_list' => array(
2919
+ 'alignment-baseline' => array(),
2920
+ 'baseline-shift' => array(),
2921
+ 'clip' => array(),
2922
+ 'clip-path' => array(),
2923
+ 'clip-rule' => array(),
2924
+ 'clippathunits' => array(),
2925
+ 'color' => array(),
2926
+ 'color-interpolation' => array(),
2927
+ 'color-interpolation-filters' => array(),
2928
+ 'color-profile' => array(),
2929
+ 'color-rendering' => array(),
2930
+ 'cursor' => array(),
2931
+ 'direction' => array(),
2932
+ 'display' => array(),
2933
+ 'dominant-baseline' => array(),
2934
+ 'enable-background' => array(),
2935
+ 'externalresourcesrequired' => array(),
2936
+ 'fill' => array(),
2937
+ 'fill-opacity' => array(),
2938
+ 'fill-rule' => array(),
2939
+ 'filter' => array(),
2940
+ 'flood-color' => array(),
2941
+ 'flood-opacity' => array(),
2942
+ 'font-family' => array(),
2943
+ 'font-size' => array(),
2944
+ 'font-size-adjust' => array(),
2945
+ 'font-stretch' => array(),
2946
+ 'font-style' => array(),
2947
+ 'font-variant' => array(),
2948
+ 'font-weight' => array(),
2949
+ 'glyph-orientation-horizontal' => array(),
2950
+ 'glyph-orientation-vertical' => array(),
2951
+ 'image-rendering' => array(),
2952
+ 'kerning' => array(),
2953
+ 'letter-spacing' => array(),
2954
+ 'lighting-color' => array(),
2955
+ 'marker-end' => array(),
2956
+ 'marker-mid' => array(),
2957
+ 'marker-start' => array(),
2958
+ 'mask' => array(),
2959
+ 'opacity' => array(),
2960
+ 'overflow' => array(),
2961
+ 'pointer-events' => array(),
2962
+ 'requiredextensions' => array(),
2963
+ 'requiredfeatures' => array(),
2964
+ 'shape-rendering' => array(),
2965
+ 'stop-color' => array(),
2966
+ 'stop-opacity' => array(),
2967
+ 'stroke' => array(),
2968
+ 'stroke-dasharray' => array(),
2969
+ 'stroke-dashoffset' => array(),
2970
+ 'stroke-linecap' => array(),
2971
+ 'stroke-linejoin' => array(),
2972
+ 'stroke-miterlimit' => array(),
2973
+ 'stroke-opacity' => array(),
2974
+ 'stroke-width' => array(),
2975
+ 'style' => array(
2976
+ 'blacklisted_value_regex' => '!important',
2977
+ ),
2978
+ 'systemlanguage' => array(),
2979
+ 'text-anchor' => array(),
2980
+ 'text-decoration' => array(),
2981
+ 'text-rendering' => array(),
2982
+ 'transform' => array(),
2983
+ 'unicode-bidi' => array(),
2984
+ 'vector-effect' => array(),
2985
+ 'visibility' => array(),
2986
+ 'word-spacing' => array(),
2987
+ 'writing-mode' => array(),
2988
+ 'xml:lang' => array(),
2989
+ 'xml:space' => array(),
2990
+ 'xmlns' => array(),
2991
+ 'xmlns:xlink' => array(),
2992
+ ),
2993
+ 'tag_spec' => array(
2994
+ 'mandatory_ancestor' => 'svg',
2995
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
2996
+ ),
2997
+ ),
2998
+ ),
2999
+ 'code' => array(
3000
+ array(
3001
+ 'attr_spec_list' => array(),
3002
+ 'tag_spec' => array(),
3003
+ ),
3004
+ ),
3005
+ 'col' => array(
3006
+ array(
3007
+ 'attr_spec_list' => array(
3008
+ 'span' => array(),
3009
+ ),
3010
+ 'tag_spec' => array(),
3011
+ ),
3012
+ ),
3013
+ 'colgroup' => array(
3014
+ array(
3015
+ 'attr_spec_list' => array(
3016
+ 'span' => array(),
3017
+ ),
3018
+ 'tag_spec' => array(),
3019
+ ),
3020
+ ),
3021
+ 'data' => array(
3022
+ array(
3023
+ 'attr_spec_list' => array(),
3024
+ 'tag_spec' => array(),
3025
+ ),
3026
+ ),
3027
+ 'datalist' => array(
3028
+ array(
3029
+ 'attr_spec_list' => array(),
3030
+ 'tag_spec' => array(
3031
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
3032
+ ),
3033
+ ),
3034
+ ),
3035
+ 'dd' => array(
3036
+ array(
3037
+ 'attr_spec_list' => array(),
3038
+ 'tag_spec' => array(),
3039
+ ),
3040
+ ),
3041
+ 'defs' => array(
3042
+ array(
3043
+ 'attr_spec_list' => array(
3044
+ 'alignment-baseline' => array(),
3045
+ 'baseline-shift' => array(),
3046
+ 'clip' => array(),
3047
+ 'clip-path' => array(),
3048
+ 'clip-rule' => array(),
3049
+ 'color' => array(),
3050
+ 'color-interpolation' => array(),
3051
+ 'color-interpolation-filters' => array(),
3052
+ 'color-profile' => array(),
3053
+ 'color-rendering' => array(),
3054
+ 'cursor' => array(),
3055
+ 'direction' => array(),
3056
+ 'display' => array(),
3057
+ 'dominant-baseline' => array(),
3058
+ 'enable-background' => array(),
3059
+ 'externalresourcesrequired' => array(),
3060
+ 'fill' => array(),
3061
+ 'fill-opacity' => array(),
3062
+ 'fill-rule' => array(),
3063
+ 'filter' => array(),
3064
+ 'flood-color' => array(),
3065
+ 'flood-opacity' => array(),
3066
+ 'font-family' => array(),
3067
+ 'font-size' => array(),
3068
+ 'font-size-adjust' => array(),
3069
+ 'font-stretch' => array(),
3070
+ 'font-style' => array(),
3071
+ 'font-variant' => array(),
3072
+ 'font-weight' => array(),
3073
+ 'glyph-orientation-horizontal' => array(),
3074
+ 'glyph-orientation-vertical' => array(),
3075
+ 'image-rendering' => array(),
3076
+ 'kerning' => array(),
3077
+ 'letter-spacing' => array(),
3078
+ 'lighting-color' => array(),
3079
+ 'marker-end' => array(),
3080
+ 'marker-mid' => array(),
3081
+ 'marker-start' => array(),
3082
+ 'mask' => array(),
3083
+ 'opacity' => array(),
3084
+ 'overflow' => array(),
3085
+ 'pointer-events' => array(),
3086
+ 'requiredextensions' => array(),
3087
+ 'requiredfeatures' => array(),
3088
+ 'shape-rendering' => array(),
3089
+ 'stop-color' => array(),
3090
+ 'stop-opacity' => array(),
3091
+ 'stroke' => array(),
3092
+ 'stroke-dasharray' => array(),
3093
+ 'stroke-dashoffset' => array(),
3094
+ 'stroke-linecap' => array(),
3095
+ 'stroke-linejoin' => array(),
3096
+ 'stroke-miterlimit' => array(),
3097
+ 'stroke-opacity' => array(),
3098
+ 'stroke-width' => array(),
3099
+ 'style' => array(
3100
+ 'blacklisted_value_regex' => '!important',
3101
+ ),
3102
+ 'systemlanguage' => array(),
3103
+ 'text-anchor' => array(),
3104
+ 'text-decoration' => array(),
3105
+ 'text-rendering' => array(),
3106
+ 'transform' => array(),
3107
+ 'unicode-bidi' => array(),
3108
+ 'vector-effect' => array(),
3109
+ 'visibility' => array(),
3110
+ 'word-spacing' => array(),
3111
+ 'writing-mode' => array(),
3112
+ 'xml:lang' => array(),
3113
+ 'xml:space' => array(),
3114
+ 'xmlns' => array(),
3115
+ 'xmlns:xlink' => array(),
3116
+ ),
3117
+ 'tag_spec' => array(
3118
+ 'mandatory_ancestor' => 'svg',
3119
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
3120
+ ),
3121
+ ),
3122
+ ),
3123
+ 'del' => array(
3124
+ array(
3125
+ 'attr_spec_list' => array(
3126
+ 'cite' => array(
3127
+ 'blacklisted_value_regex' => '__amp_source_origin',
3128
+ 'value_url' => array(
3129
+ 'allow_empty' => true,
3130
+ 'allow_relative' => true,
3131
+ 'allowed_protocol' => array(
3132
+ 'http',
3133
+ 'https',
3134
+ ),
3135
+ ),
3136
+ ),
3137
+ 'datetime' => array(),
3138
+ ),
3139
+ 'tag_spec' => array(),
3140
+ ),
3141
+ ),
3142
+ 'desc' => array(
3143
+ array(
3144
+ 'attr_spec_list' => array(
3145
+ 'style' => array(
3146
+ 'blacklisted_value_regex' => '!important',
3147
+ ),
3148
+ 'xml:lang' => array(),
3149
+ 'xml:space' => array(),
3150
+ 'xmlns' => array(),
3151
+ 'xmlns:xlink' => array(),
3152
+ ),
3153
+ 'tag_spec' => array(
3154
+ 'mandatory_ancestor' => 'svg',
3155
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
3156
+ ),
3157
+ ),
3158
+ ),
3159
+ 'dfn' => array(
3160
+ array(
3161
+ 'attr_spec_list' => array(),
3162
+ 'tag_spec' => array(),
3163
+ ),
3164
+ ),
3165
+ 'dir' => array(
3166
+ array(
3167
+ 'attr_spec_list' => array(),
3168
+ 'tag_spec' => array(),
3169
+ ),
3170
+ ),
3171
+ 'div' => array(
3172
+ array(
3173
+ 'attr_spec_list' => array(
3174
+ 'align' => array(),
3175
+ ),
3176
+ 'tag_spec' => array(),
3177
+ ),
3178
+ array(
3179
+ 'attr_spec_list' => array(
3180
+ 'align' => array(),
3181
+ 'submitting' => array(
3182
+ 'dispatch_key' => 1,
3183
+ 'mandatory' => true,
3184
+ ),
3185
+ ),
3186
+ 'tag_spec' => array(
3187
+ 'mandatory_parent' => 'form',
3188
+ 'spec_name' => 'FORM > DIV [submitting]',
3189
+ ),
3190
+ ),
3191
+ array(
3192
+ 'attr_spec_list' => array(
3193
+ 'align' => array(),
3194
+ 'submit-success' => array(
3195
+ 'mandatory' => true,
3196
+ ),
3197
+ ),
3198
+ 'tag_spec' => array(
3199
+ 'mandatory_parent' => 'form',
3200
+ 'spec_name' => 'FORM > DIV [submit-success]',
3201
+ ),
3202
+ ),
3203
+ array(
3204
+ 'attr_spec_list' => array(
3205
+ 'align' => array(),
3206
+ 'submit-success' => array(
3207
+ 'mandatory' => true,
3208
+ ),
3209
+ 'template' => array(
3210
+ 'mandatory' => true,
3211
+ ),
3212
+ ),
3213
+ 'tag_spec' => array(
3214
+ 'mandatory_parent' => 'form',
3215
+ 'spec_name' => 'FORM > DIV [submit-success][template]',
3216
+ ),
3217
+ ),
3218
+ array(
3219
+ 'attr_spec_list' => array(
3220
+ 'align' => array(),
3221
+ 'submit-error' => array(
3222
+ 'mandatory' => true,
3223
+ ),
3224
+ ),
3225
+ 'tag_spec' => array(
3226
+ 'mandatory_parent' => 'form',
3227
+ 'spec_name' => 'FORM > DIV [submit-error]',
3228
+ ),
3229
+ ),
3230
+ array(
3231
+ 'attr_spec_list' => array(
3232
+ 'align' => array(),
3233
+ 'submit-error' => array(
3234
+ 'mandatory' => true,
3235
+ ),
3236
+ 'template' => array(
3237
+ 'mandatory' => true,
3238
+ ),
3239
+ ),
3240
+ 'tag_spec' => array(
3241
+ 'mandatory_parent' => 'form',
3242
+ 'spec_name' => 'FORM > DIV [submit-error][template]',
3243
+ ),
3244
+ ),
3245
+ ),
3246
+ 'dl' => array(
3247
+ array(
3248
+ 'attr_spec_list' => array(),
3249
+ 'tag_spec' => array(),
3250
+ ),
3251
+ ),
3252
+ 'dt' => array(
3253
+ array(
3254
+ 'attr_spec_list' => array(),
3255
+ 'tag_spec' => array(),
3256
+ ),
3257
+ ),
3258
+ 'ellipse' => array(
3259
+ array(
3260
+ 'attr_spec_list' => array(
3261
+ 'alignment-baseline' => array(),
3262
+ 'baseline-shift' => array(),
3263
+ 'clip' => array(),
3264
+ 'clip-path' => array(),
3265
+ 'clip-rule' => array(),
3266
+ 'color' => array(),
3267
+ 'color-interpolation' => array(),
3268
+ 'color-interpolation-filters' => array(),
3269
+ 'color-profile' => array(),
3270
+ 'color-rendering' => array(),
3271
+ 'cursor' => array(),
3272
+ 'cx' => array(),
3273
+ 'cy' => array(),
3274
+ 'direction' => array(),
3275
+ 'display' => array(),
3276
+ 'dominant-baseline' => array(),
3277
+ 'enable-background' => array(),
3278
+ 'externalresourcesrequired' => array(),
3279
+ 'fill' => array(),
3280
+ 'fill-opacity' => array(),
3281
+ 'fill-rule' => array(),
3282
+ 'filter' => array(),
3283
+ 'flood-color' => array(),
3284
+ 'flood-opacity' => array(),
3285
+ 'font-family' => array(),
3286
+ 'font-size' => array(),
3287
+ 'font-size-adjust' => array(),
3288
+ 'font-stretch' => array(),
3289
+ 'font-style' => array(),
3290
+ 'font-variant' => array(),
3291
+ 'font-weight' => array(),
3292
+ 'glyph-orientation-horizontal' => array(),
3293
+ 'glyph-orientation-vertical' => array(),
3294
+ 'image-rendering' => array(),
3295
+ 'kerning' => array(),
3296
+ 'letter-spacing' => array(),
3297
+ 'lighting-color' => array(),
3298
+ 'marker-end' => array(),
3299
+ 'marker-mid' => array(),
3300
+ 'marker-start' => array(),
3301
+ 'mask' => array(),
3302
+ 'opacity' => array(),
3303
+ 'overflow' => array(),
3304
+ 'pointer-events' => array(),
3305
+ 'requiredextensions' => array(),
3306
+ 'requiredfeatures' => array(),
3307
+ 'rx' => array(),
3308
+ 'ry' => array(),
3309
+ 'shape-rendering' => array(),
3310
+ 'sketch:type' => array(),
3311
+ 'stop-color' => array(),
3312
+ 'stop-opacity' => array(),
3313
+ 'stroke' => array(),
3314
+ 'stroke-dasharray' => array(),
3315
+ 'stroke-dashoffset' => array(),
3316
+ 'stroke-linecap' => array(),
3317
+ 'stroke-linejoin' => array(),
3318
+ 'stroke-miterlimit' => array(),
3319
+ 'stroke-opacity' => array(),
3320
+ 'stroke-width' => array(),
3321
+ 'style' => array(
3322
+ 'blacklisted_value_regex' => '!important',
3323
+ ),
3324
+ 'systemlanguage' => array(),
3325
+ 'text-anchor' => array(),
3326
+ 'text-decoration' => array(),
3327
+ 'text-rendering' => array(),
3328
+ 'transform' => array(),
3329
+ 'unicode-bidi' => array(),
3330
+ 'vector-effect' => array(),
3331
+ 'visibility' => array(),
3332
+ 'word-spacing' => array(),
3333
+ 'writing-mode' => array(),
3334
+ 'xml:lang' => array(),
3335
+ 'xml:space' => array(),
3336
+ 'xmlns' => array(),
3337
+ 'xmlns:xlink' => array(),
3338
+ ),
3339
+ 'tag_spec' => array(
3340
+ 'mandatory_ancestor' => 'svg',
3341
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
3342
+ ),
3343
+ ),
3344
+ ),
3345
+ 'em' => array(
3346
+ array(
3347
+ 'attr_spec_list' => array(),
3348
+ 'tag_spec' => array(),
3349
+ ),
3350
+ ),
3351
+ 'fecolormatrix' => array(
3352
+ array(
3353
+ 'attr_spec_list' => array(
3354
+ 'alignment-baseline' => array(),
3355
+ 'baseline-shift' => array(),
3356
+ 'clip' => array(),
3357
+ 'clip-path' => array(),
3358
+ 'clip-rule' => array(),
3359
+ 'color' => array(),
3360
+ 'color-interpolation' => array(),
3361
+ 'color-interpolation-filters' => array(),
3362
+ 'color-profile' => array(),
3363
+ 'color-rendering' => array(),
3364
+ 'cursor' => array(),
3365
+ 'direction' => array(),
3366
+ 'display' => array(),
3367
+ 'dominant-baseline' => array(),
3368
+ 'enable-background' => array(),
3369
+ 'fill' => array(),
3370
+ 'fill-opacity' => array(),
3371
+ 'fill-rule' => array(),
3372
+ 'filter' => array(),
3373
+ 'flood-color' => array(),
3374
+ 'flood-opacity' => array(),
3375
+ 'font-family' => array(),
3376
+ 'font-size' => array(),
3377
+ 'font-size-adjust' => array(),
3378
+ 'font-stretch' => array(),
3379
+ 'font-style' => array(),
3380
+ 'font-variant' => array(),
3381
+ 'font-weight' => array(),
3382
+ 'glyph-orientation-horizontal' => array(),
3383
+ 'glyph-orientation-vertical' => array(),
3384
+ 'height' => array(),
3385
+ 'image-rendering' => array(),
3386
+ 'in' => array(),
3387
+ 'kerning' => array(),
3388
+ 'letter-spacing' => array(),
3389
+ 'lighting-color' => array(),
3390
+ 'marker-end' => array(),
3391
+ 'marker-mid' => array(),
3392
+ 'marker-start' => array(),
3393
+ 'mask' => array(),
3394
+ 'opacity' => array(),
3395
+ 'overflow' => array(),
3396
+ 'pointer-events' => array(),
3397
+ 'result' => array(),
3398
+ 'shape-rendering' => array(),
3399
+ 'stop-color' => array(),
3400
+ 'stop-opacity' => array(),
3401
+ 'stroke' => array(),
3402
+ 'stroke-dasharray' => array(),
3403
+ 'stroke-dashoffset' => array(),
3404
+ 'stroke-linecap' => array(),
3405
+ 'stroke-linejoin' => array(),
3406
+ 'stroke-miterlimit' => array(),
3407
+ 'stroke-opacity' => array(),
3408
+ 'stroke-width' => array(),
3409
+ 'style' => array(
3410
+ 'blacklisted_value_regex' => '!important',
3411
+ ),
3412
+ 'text-anchor' => array(),
3413
+ 'text-decoration' => array(),
3414
+ 'text-rendering' => array(),
3415
+ 'type' => array(),
3416
+ 'unicode-bidi' => array(),
3417
+ 'values' => array(),
3418
+ 'vector-effect' => array(),
3419
+ 'visibility' => array(),
3420
+ 'width' => array(),
3421
+ 'word-spacing' => array(),
3422
+ 'writing-mode' => array(),
3423
+ 'x' => array(),
3424
+ 'xml:lang' => array(),
3425
+ 'xml:space' => array(),
3426
+ 'xmlns' => array(),
3427
+ 'xmlns:xlink' => array(),
3428
+ 'y' => array(),
3429
+ ),
3430
+ 'tag_spec' => array(
3431
+ 'mandatory_ancestor' => 'svg',
3432
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
3433
+ ),
3434
+ ),
3435
+ ),
3436
+ 'fecomposite' => array(
3437
+ array(
3438
+ 'attr_spec_list' => array(
3439
+ 'alignment-baseline' => array(),
3440
+ 'baseline-shift' => array(),
3441
+ 'clip' => array(),
3442
+ 'clip-path' => array(),
3443
+ 'clip-rule' => array(),
3444
+ 'color' => array(),
3445
+ 'color-interpolation' => array(),
3446
+ 'color-interpolation-filters' => array(),
3447
+ 'color-profile' => array(),
3448
+ 'color-rendering' => array(),
3449
+ 'cursor' => array(),
3450
+ 'direction' => array(),
3451
+ 'display' => array(),
3452
+ 'dominant-baseline' => array(),
3453
+ 'enable-background' => array(),
3454
+ 'fill' => array(),
3455
+ 'fill-opacity' => array(),
3456
+ 'fill-rule' => array(),
3457
+ 'filter' => array(),
3458
+ 'flood-color' => array(),
3459
+ 'flood-opacity' => array(),
3460
+ 'font-family' => array(),
3461
+ 'font-size' => array(),
3462
+ 'font-size-adjust' => array(),
3463
+ 'font-stretch' => array(),
3464
+ 'font-style' => array(),
3465
+ 'font-variant' => array(),
3466
+ 'font-weight' => array(),
3467
+ 'glyph-orientation-horizontal' => array(),
3468
+ 'glyph-orientation-vertical' => array(),
3469
+ 'height' => array(),
3470
+ 'image-rendering' => array(),
3471
+ 'in' => array(),
3472
+ 'in2' => array(),
3473
+ 'k1' => array(),
3474
+ 'k2' => array(),
3475
+ 'k3' => array(),
3476
+ 'k4' => array(),
3477
+ 'kerning' => array(),
3478
+ 'letter-spacing' => array(),
3479
+ 'lighting-color' => array(),
3480
+ 'marker-end' => array(),
3481
+ 'marker-mid' => array(),
3482
+ 'marker-start' => array(),
3483
+ 'mask' => array(),
3484
+ 'opacity' => array(),
3485
+ 'operator' => array(),
3486
+ 'overflow' => array(),
3487
+ 'pointer-events' => array(),
3488
+ 'result' => array(),
3489
+ 'shape-rendering' => array(),
3490
+ 'stop-color' => array(),
3491
+ 'stop-opacity' => array(),
3492
+ 'stroke' => array(),
3493
+ 'stroke-dasharray' => array(),
3494
+ 'stroke-dashoffset' => array(),
3495
+ 'stroke-linecap' => array(),
3496
+ 'stroke-linejoin' => array(),
3497
+ 'stroke-miterlimit' => array(),
3498
+ 'stroke-opacity' => array(),
3499
+ 'stroke-width' => array(),
3500
+ 'style' => array(
3501
+ 'blacklisted_value_regex' => '!important',
3502
+ ),
3503
+ 'text-anchor' => array(),
3504
+ 'text-decoration' => array(),
3505
+ 'text-rendering' => array(),
3506
+ 'unicode-bidi' => array(),
3507
+ 'vector-effect' => array(),
3508
+ 'visibility' => array(),
3509
+ 'width' => array(),
3510
+ 'word-spacing' => array(),
3511
+ 'writing-mode' => array(),
3512
+ 'x' => array(),
3513
+ 'xml:lang' => array(),
3514
+ 'xml:space' => array(),
3515
+ 'xmlns' => array(),
3516
+ 'xmlns:xlink' => array(),
3517
+ 'y' => array(),
3518
+ ),
3519
+ 'tag_spec' => array(
3520
+ 'mandatory_ancestor' => 'svg',
3521
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
3522
+ ),
3523
+ ),
3524
+ ),
3525
+ 'feflood' => array(
3526
+ array(
3527
+ 'attr_spec_list' => array(
3528
+ 'alignment-baseline' => array(),
3529
+ 'baseline-shift' => array(),
3530
+ 'clip' => array(),
3531
+ 'clip-path' => array(),
3532
+ 'clip-rule' => array(),
3533
+ 'color' => array(),
3534
+ 'color-interpolation' => array(),
3535
+ 'color-interpolation-filters' => array(),
3536
+ 'color-profile' => array(),
3537
+ 'color-rendering' => array(),
3538
+ 'cursor' => array(),
3539
+ 'direction' => array(),
3540
+ 'display' => array(),
3541
+ 'dominant-baseline' => array(),
3542
+ 'enable-background' => array(),
3543
+ 'fill' => array(),
3544
+ 'fill-opacity' => array(),
3545
+ 'fill-rule' => array(),
3546
+ 'filter' => array(),
3547
+ 'flood-color' => array(),
3548
+ 'flood-opacity' => array(),
3549
+ 'font-family' => array(),
3550
+ 'font-size' => array(),
3551
+ 'font-size-adjust' => array(),
3552
+ 'font-stretch' => array(),
3553
+ 'font-style' => array(),
3554
+ 'font-variant' => array(),
3555
+ 'font-weight' => array(),
3556
+ 'glyph-orientation-horizontal' => array(),
3557
+ 'glyph-orientation-vertical' => array(),
3558
+ 'height' => array(),
3559
+ 'image-rendering' => array(),
3560
+ 'kerning' => array(),
3561
+ 'letter-spacing' => array(),
3562
+ 'lighting-color' => array(),
3563
+ 'marker-end' => array(),
3564
+ 'marker-mid' => array(),
3565
+ 'marker-start' => array(),
3566
+ 'mask' => array(),
3567
+ 'opacity' => array(),
3568
+ 'overflow' => array(),
3569
+ 'pointer-events' => array(),
3570
+ 'result' => array(),
3571
+ 'shape-rendering' => array(),
3572
+ 'stop-color' => array(),
3573
+ 'stop-opacity' => array(),
3574
+ 'stroke' => array(),
3575
+ 'stroke-dasharray' => array(),
3576
+ 'stroke-dashoffset' => array(),
3577
+ 'stroke-linecap' => array(),
3578
+ 'stroke-linejoin' => array(),
3579
+ 'stroke-miterlimit' => array(),
3580
+ 'stroke-opacity' => array(),
3581
+ 'stroke-width' => array(),
3582
+ 'style' => array(
3583
+ 'blacklisted_value_regex' => '!important',
3584
+ ),
3585
+ 'text-anchor' => array(),
3586
+ 'text-decoration' => array(),
3587
+ 'text-rendering' => array(),
3588
+ 'unicode-bidi' => array(),
3589
+ 'vector-effect' => array(),
3590
+ 'visibility' => array(),
3591
+ 'width' => array(),
3592
+ 'word-spacing' => array(),
3593
+ 'writing-mode' => array(),
3594
+ 'x' => array(),
3595
+ 'xml:lang' => array(),
3596
+ 'xml:space' => array(),
3597
+ 'xmlns' => array(),
3598
+ 'xmlns:xlink' => array(),
3599
+ 'y' => array(),
3600
+ ),
3601
+ 'tag_spec' => array(
3602
+ 'mandatory_ancestor' => 'svg',
3603
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
3604
+ ),
3605
+ ),
3606
+ ),
3607
+ 'fegaussianblur' => array(
3608
+ array(
3609
+ 'attr_spec_list' => array(
3610
+ 'alignment-baseline' => array(),
3611
+ 'baseline-shift' => array(),
3612
+ 'clip' => array(),
3613
+ 'clip-path' => array(),
3614
+ 'clip-rule' => array(),
3615
+ 'color' => array(),
3616
+ 'color-interpolation' => array(),
3617
+ 'color-interpolation-filters' => array(),
3618
+ 'color-profile' => array(),
3619
+ 'color-rendering' => array(),
3620
+ 'cursor' => array(),
3621
+ 'direction' => array(),
3622
+ 'display' => array(),
3623
+ 'dominant-baseline' => array(),
3624
+ 'edgemode' => array(),
3625
+ 'enable-background' => array(),
3626
+ 'fill' => array(),
3627
+ 'fill-opacity' => array(),
3628
+ 'fill-rule' => array(),
3629
+ 'filter' => array(),
3630
+ 'flood-color' => array(),
3631
+ 'flood-opacity' => array(),
3632
+ 'font-family' => array(),
3633
+ 'font-size' => array(),
3634
+ 'font-size-adjust' => array(),
3635
+ 'font-stretch' => array(),
3636
+ 'font-style' => array(),
3637
+ 'font-variant' => array(),
3638
+ 'font-weight' => array(),
3639
+ 'glyph-orientation-horizontal' => array(),
3640
+ 'glyph-orientation-vertical' => array(),
3641
+ 'height' => array(),
3642
+ 'image-rendering' => array(),
3643
+ 'in' => array(),
3644
+ 'kerning' => array(),
3645
+ 'letter-spacing' => array(),
3646
+ 'lighting-color' => array(),
3647
+ 'marker-end' => array(),
3648
+ 'marker-mid' => array(),
3649
+ 'marker-start' => array(),
3650
+ 'mask' => array(),
3651
+ 'opacity' => array(),
3652
+ 'overflow' => array(),
3653
+ 'pointer-events' => array(),
3654
+ 'result' => array(),
3655
+ 'shape-rendering' => array(),
3656
+ 'stddeviation' => array(),
3657
+ 'stop-color' => array(),
3658
+ 'stop-opacity' => array(),
3659
+ 'stroke' => array(),
3660
+ 'stroke-dasharray' => array(),
3661
+ 'stroke-dashoffset' => array(),
3662
+ 'stroke-linecap' => array(),
3663
+ 'stroke-linejoin' => array(),
3664
+ 'stroke-miterlimit' => array(),
3665
+ 'stroke-opacity' => array(),
3666
+ 'stroke-width' => array(),
3667
+ 'style' => array(
3668
+ 'blacklisted_value_regex' => '!important',
3669
+ ),
3670
+ 'text-anchor' => array(),
3671
+ 'text-decoration' => array(),
3672
+ 'text-rendering' => array(),
3673
+ 'unicode-bidi' => array(),
3674
+ 'vector-effect' => array(),
3675
+ 'visibility' => array(),
3676
+ 'width' => array(),
3677
+ 'word-spacing' => array(),
3678
+ 'writing-mode' => array(),
3679
+ 'x' => array(),
3680
+ 'xml:lang' => array(),
3681
+ 'xml:space' => array(),
3682
+ 'xmlns' => array(),
3683
+ 'xmlns:xlink' => array(),
3684
+ 'y' => array(),
3685
+ ),
3686
+ 'tag_spec' => array(
3687
+ 'mandatory_ancestor' => 'svg',
3688
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
3689
+ ),
3690
+ ),
3691
+ ),
3692
+ 'femerge' => array(
3693
+ array(
3694
+ 'attr_spec_list' => array(
3695
+ 'alignment-baseline' => array(),
3696
+ 'baseline-shift' => array(),
3697
+ 'clip' => array(),
3698
+ 'clip-path' => array(),
3699
+ 'clip-rule' => array(),
3700
+ 'color' => array(),
3701
+ 'color-interpolation' => array(),
3702
+ 'color-interpolation-filters' => array(),
3703
+ 'color-profile' => array(),
3704
+ 'color-rendering' => array(),
3705
+ 'cursor' => array(),
3706
+ 'direction' => array(),
3707
+ 'display' => array(),
3708
+ 'dominant-baseline' => array(),
3709
+ 'enable-background' => array(),
3710
+ 'fill' => array(),
3711
+ 'fill-opacity' => array(),
3712
+ 'fill-rule' => array(),
3713
+ 'filter' => array(),
3714
+ 'flood-color' => array(),
3715
+ 'flood-opacity' => array(),
3716
+ 'font-family' => array(),
3717
+ 'font-size' => array(),
3718
+ 'font-size-adjust' => array(),
3719
+ 'font-stretch' => array(),
3720
+ 'font-style' => array(),
3721
+ 'font-variant' => array(),
3722
+ 'font-weight' => array(),
3723
+ 'glyph-orientation-horizontal' => array(),
3724
+ 'glyph-orientation-vertical' => array(),
3725
+ 'height' => array(),
3726
+ 'image-rendering' => array(),
3727
+ 'kerning' => array(),
3728
+ 'letter-spacing' => array(),
3729
+ 'lighting-color' => array(),
3730
+ 'marker-end' => array(),
3731
+ 'marker-mid' => array(),
3732
+ 'marker-start' => array(),
3733
+ 'mask' => array(),
3734
+ 'opacity' => array(),
3735
+ 'overflow' => array(),
3736
+ 'pointer-events' => array(),
3737
+ 'result' => array(),
3738
+ 'shape-rendering' => array(),
3739
+ 'stop-color' => array(),
3740
+ 'stop-opacity' => array(),
3741
+ 'stroke' => array(),
3742
+ 'stroke-dasharray' => array(),
3743
+ 'stroke-dashoffset' => array(),
3744
+ 'stroke-linecap' => array(),
3745
+ 'stroke-linejoin' => array(),
3746
+ 'stroke-miterlimit' => array(),
3747
+ 'stroke-opacity' => array(),
3748
+ 'stroke-width' => array(),
3749
+ 'style' => array(
3750
+ 'blacklisted_value_regex' => '!important',
3751
+ ),
3752
+ 'text-anchor' => array(),
3753
+ 'text-decoration' => array(),
3754
+ 'text-rendering' => array(),
3755
+ 'unicode-bidi' => array(),
3756
+ 'vector-effect' => array(),
3757
+ 'visibility' => array(),
3758
+ 'width' => array(),
3759
+ 'word-spacing' => array(),
3760
+ 'writing-mode' => array(),
3761
+ 'x' => array(),
3762
+ 'xml:lang' => array(),
3763
+ 'xml:space' => array(),
3764
+ 'xmlns' => array(),
3765
+ 'xmlns:xlink' => array(),
3766
+ 'y' => array(),
3767
+ ),
3768
+ 'tag_spec' => array(
3769
+ 'mandatory_ancestor' => 'svg',
3770
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
3771
+ ),
3772
+ ),
3773
+ ),
3774
+ 'femergenode' => array(
3775
+ array(
3776
+ 'attr_spec_list' => array(
3777
+ 'in' => array(),
3778
+ 'style' => array(
3779
+ 'blacklisted_value_regex' => '!important',
3780
+ ),
3781
+ 'xml:lang' => array(),
3782
+ 'xml:space' => array(),
3783
+ 'xmlns' => array(),
3784
+ 'xmlns:xlink' => array(),
3785
+ ),
3786
+ 'tag_spec' => array(
3787
+ 'mandatory_ancestor' => 'svg',
3788
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
3789
+ ),
3790
+ ),
3791
+ ),
3792
+ 'feoffset' => array(
3793
+ array(
3794
+ 'attr_spec_list' => array(
3795
+ 'alignment-baseline' => array(),
3796
+ 'baseline-shift' => array(),
3797
+ 'clip' => array(),
3798
+ 'clip-path' => array(),
3799
+ 'clip-rule' => array(),
3800
+ 'color' => array(),
3801
+ 'color-interpolation' => array(),
3802
+ 'color-interpolation-filters' => array(),
3803
+ 'color-profile' => array(),
3804
+ 'color-rendering' => array(),
3805
+ 'cursor' => array(),
3806
+ 'direction' => array(),
3807
+ 'display' => array(),
3808
+ 'dominant-baseline' => array(),
3809
+ 'dx' => array(),
3810
+ 'dy' => array(),
3811
+ 'enable-background' => array(),
3812
+ 'fill' => array(),
3813
+ 'fill-opacity' => array(),
3814
+ 'fill-rule' => array(),
3815
+ 'filter' => array(),
3816
+ 'flood-color' => array(),
3817
+ 'flood-opacity' => array(),
3818
+ 'font-family' => array(),
3819
+ 'font-size' => array(),
3820
+ 'font-size-adjust' => array(),
3821
+ 'font-stretch' => array(),
3822
+ 'font-style' => array(),
3823
+ 'font-variant' => array(),
3824
+ 'font-weight' => array(),
3825
+ 'glyph-orientation-horizontal' => array(),
3826
+ 'glyph-orientation-vertical' => array(),
3827
+ 'height' => array(),
3828
+ 'image-rendering' => array(),
3829
+ 'in' => array(),
3830
+ 'kerning' => array(),
3831
+ 'letter-spacing' => array(),
3832
+ 'lighting-color' => array(),
3833
+ 'marker-end' => array(),
3834
+ 'marker-mid' => array(),
3835
+ 'marker-start' => array(),
3836
+ 'mask' => array(),
3837
+ 'opacity' => array(),
3838
+ 'overflow' => array(),
3839
+ 'pointer-events' => array(),
3840
+ 'result' => array(),
3841
+ 'shape-rendering' => array(),
3842
+ 'stop-color' => array(),
3843
+ 'stop-opacity' => array(),
3844
+ 'stroke' => array(),
3845
+ 'stroke-dasharray' => array(),
3846
+ 'stroke-dashoffset' => array(),
3847
+ 'stroke-linecap' => array(),
3848
+ 'stroke-linejoin' => array(),
3849
+ 'stroke-miterlimit' => array(),
3850
+ 'stroke-opacity' => array(),
3851
+ 'stroke-width' => array(),
3852
+ 'style' => array(
3853
+ 'blacklisted_value_regex' => '!important',
3854
+ ),
3855
+ 'text-anchor' => array(),
3856
+ 'text-decoration' => array(),
3857
+ 'text-rendering' => array(),
3858
+ 'unicode-bidi' => array(),
3859
+ 'vector-effect' => array(),
3860
+ 'visibility' => array(),
3861
+ 'width' => array(),
3862
+ 'word-spacing' => array(),
3863
+ 'writing-mode' => array(),
3864
+ 'x' => array(),
3865
+ 'xml:lang' => array(),
3866
+ 'xml:space' => array(),
3867
+ 'xmlns' => array(),
3868
+ 'xmlns:xlink' => array(),
3869
+ 'y' => array(),
3870
+ ),
3871
+ 'tag_spec' => array(
3872
+ 'mandatory_ancestor' => 'svg',
3873
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
3874
+ ),
3875
+ ),
3876
+ ),
3877
+ 'fieldset' => array(
3878
+ array(
3879
+ 'attr_spec_list' => array(
3880
+ '[disabled]' => array(),
3881
+ 'disabled' => array(),
3882
+ 'name' => array(
3883
+ 'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
3884
+ ),
3885
+ ),
3886
+ 'tag_spec' => array(),
3887
+ ),
3888
+ ),
3889
+ 'figcaption' => array(
3890
+ array(
3891
+ 'attr_spec_list' => array(),
3892
+ 'tag_spec' => array(),
3893
+ ),
3894
+ ),
3895
+ 'figure' => array(
3896
+ array(
3897
+ 'attr_spec_list' => array(),
3898
+ 'tag_spec' => array(),
3899
+ ),
3900
+ ),
3901
+ 'filter' => array(
3902
+ array(
3903
+ 'attr_spec_list' => array(
3904
+ 'alignment-baseline' => array(),
3905
+ 'baseline-shift' => array(),
3906
+ 'clip' => array(),
3907
+ 'clip-path' => array(),
3908
+ 'clip-rule' => array(),
3909
+ 'color' => array(),
3910
+ 'color-interpolation' => array(),
3911
+ 'color-interpolation-filters' => array(),
3912
+ 'color-profile' => array(),
3913
+ 'color-rendering' => array(),
3914
+ 'cursor' => array(),
3915
+ 'direction' => array(),
3916
+ 'display' => array(),
3917
+ 'dominant-baseline' => array(),
3918
+ 'enable-background' => array(),
3919
+ 'externalresourcesrequired' => array(),
3920
+ 'fill' => array(),
3921
+ 'fill-opacity' => array(),
3922
+ 'fill-rule' => array(),
3923
+ 'filter' => array(),
3924
+ 'filterres' => array(),
3925
+ 'filterunits' => array(),
3926
+ 'flood-color' => array(),
3927
+ 'flood-opacity' => array(),
3928
+ 'font-family' => array(),
3929
+ 'font-size' => array(),
3930
+ 'font-size-adjust' => array(),
3931
+ 'font-stretch' => array(),
3932
+ 'font-style' => array(),
3933
+ 'font-variant' => array(),
3934
+ 'font-weight' => array(),
3935
+ 'glyph-orientation-horizontal' => array(),
3936
+ 'glyph-orientation-vertical' => array(),
3937
+ 'height' => array(),
3938
+ 'image-rendering' => array(),
3939
+ 'kerning' => array(),
3940
+ 'letter-spacing' => array(),
3941
+ 'lighting-color' => array(),
3942
+ 'marker-end' => array(),
3943
+ 'marker-mid' => array(),
3944
+ 'marker-start' => array(),
3945
+ 'mask' => array(),
3946
+ 'opacity' => array(),
3947
+ 'overflow' => array(),
3948
+ 'pointer-events' => array(),
3949
+ 'primitiveunits' => array(),
3950
+ 'shape-rendering' => array(),
3951
+ 'stop-color' => array(),
3952
+ 'stop-opacity' => array(),
3953
+ 'stroke' => array(),
3954
+ 'stroke-dasharray' => array(),
3955
+ 'stroke-dashoffset' => array(),
3956
+ 'stroke-linecap' => array(),
3957
+ 'stroke-linejoin' => array(),
3958
+ 'stroke-miterlimit' => array(),
3959
+ 'stroke-opacity' => array(),
3960
+ 'stroke-width' => array(),
3961
+ 'style' => array(
3962
+ 'blacklisted_value_regex' => '!important',
3963
+ ),
3964
+ 'text-anchor' => array(),
3965
+ 'text-decoration' => array(),
3966
+ 'text-rendering' => array(),
3967
+ 'unicode-bidi' => array(),
3968
+ 'vector-effect' => array(),
3969
+ 'visibility' => array(),
3970
+ 'width' => array(),
3971
+ 'word-spacing' => array(),
3972
+ 'writing-mode' => array(),
3973
+ 'x' => array(),
3974
+ 'xlink:actuate' => array(),
3975
+ 'xlink:arcrole' => array(),
3976
+ 'xlink:href' => array(
3977
+ 'alternative_names' => array(
3978
+ 'href',
3979
+ ),
3980
+ 'value_url' => array(
3981
+ 'allow_empty' => false,
3982
+ 'allow_relative' => true,
3983
+ 'allowed_protocol' => array(
3984
+ 'http',
3985
+ 'https',
3986
+ ),
3987
+ ),
3988
+ ),
3989
+ 'xlink:role' => array(),
3990
+ 'xlink:show' => array(),
3991
+ 'xlink:title' => array(),
3992
+ 'xlink:type' => array(),
3993
+ 'xml:lang' => array(),
3994
+ 'xml:space' => array(),
3995
+ 'xmlns' => array(),
3996
+ 'xmlns:xlink' => array(),
3997
+ 'y' => array(),
3998
+ ),
3999
+ 'tag_spec' => array(
4000
+ 'mandatory_ancestor' => 'svg',
4001
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
4002
+ ),
4003
+ ),
4004
+ ),
4005
+ 'footer' => array(
4006
+ array(
4007
+ 'attr_spec_list' => array(),
4008
+ 'tag_spec' => array(),
4009
+ ),
4010
+ ),
4011
+ 'foreignobject' => array(
4012
+ array(
4013
+ 'attr_spec_list' => array(
4014
+ 'alignment-baseline' => array(),
4015
+ 'baseline-shift' => array(),
4016
+ 'clip' => array(),
4017
+ 'clip-path' => array(),
4018
+ 'clip-rule' => array(),
4019
+ 'color' => array(),
4020
+ 'color-interpolation' => array(),
4021
+ 'color-interpolation-filters' => array(),
4022
+ 'color-profile' => array(),
4023
+ 'color-rendering' => array(),
4024
+ 'cursor' => array(),
4025
+ 'direction' => array(),
4026
+ 'display' => array(),
4027
+ 'dominant-baseline' => array(),
4028
+ 'enable-background' => array(),
4029
+ 'externalresourcesrequired' => array(),
4030
+ 'fill' => array(),
4031
+ 'fill-opacity' => array(),
4032
+ 'fill-rule' => array(),
4033
+ 'filter' => array(),
4034
+ 'flood-color' => array(),
4035
+ 'flood-opacity' => array(),
4036
+ 'font-family' => array(),
4037
+ 'font-size' => array(),
4038
+ 'font-size-adjust' => array(),
4039
+ 'font-stretch' => array(),
4040
+ 'font-style' => array(),
4041
+ 'font-variant' => array(),
4042
+ 'font-weight' => array(),
4043
+ 'glyph-orientation-horizontal' => array(),
4044
+ 'glyph-orientation-vertical' => array(),
4045
+ 'height' => array(),
4046
+ 'image-rendering' => array(),
4047
+ 'kerning' => array(),
4048
+ 'letter-spacing' => array(),
4049
+ 'lighting-color' => array(),
4050
+ 'marker-end' => array(),
4051
+ 'marker-mid' => array(),
4052
+ 'marker-start' => array(),
4053
+ 'mask' => array(),
4054
+ 'opacity' => array(),
4055
+ 'overflow' => array(),
4056
+ 'pointer-events' => array(),
4057
+ 'requiredextensions' => array(),
4058
+ 'requiredfeatures' => array(),
4059
+ 'shape-rendering' => array(),
4060
+ 'stop-color' => array(),
4061
+ 'stop-opacity' => array(),
4062
+ 'stroke' => array(),
4063
+ 'stroke-dasharray' => array(),
4064
+ 'stroke-dashoffset' => array(),
4065
+ 'stroke-linecap' => array(),
4066
+ 'stroke-linejoin' => array(),
4067
+ 'stroke-miterlimit' => array(),
4068
+ 'stroke-opacity' => array(),
4069
+ 'stroke-width' => array(),
4070
+ 'style' => array(
4071
+ 'blacklisted_value_regex' => '!important',
4072
+ ),
4073
+ 'systemlanguage' => array(),
4074
+ 'text-anchor' => array(),
4075
+ 'text-decoration' => array(),
4076
+ 'text-rendering' => array(),
4077
+ 'transform' => array(),
4078
+ 'unicode-bidi' => array(),
4079
+ 'vector-effect' => array(),
4080
+ 'visibility' => array(),
4081
+ 'width' => array(),
4082
+ 'word-spacing' => array(),
4083
+ 'writing-mode' => array(),
4084
+ 'x' => array(),
4085
+ 'xml:lang' => array(),
4086
+ 'xml:space' => array(),
4087
+ 'xmlns' => array(),
4088
+ 'xmlns:xlink' => array(),
4089
+ 'y' => array(),
4090
+ ),
4091
+ 'tag_spec' => array(
4092
+ 'mandatory_ancestor' => 'svg',
4093
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
4094
+ ),
4095
+ ),
4096
+ ),
4097
+ 'form' => array(
4098
+ array(
4099
+ 'attr_spec_list' => array(
4100
+ 'accept' => array(),
4101
+ 'accept-charset' => array(),
4102
+ 'action' => array(
4103
+ 'blacklisted_value_regex' => '__amp_source_origin',
4104
+ 'mandatory' => true,
4105
+ 'value_url' => array(
4106
+ 'allow_relative' => true,
4107
+ 'allowed_protocol' => array(
4108
+ 'https',
4109
+ ),
4110
+ ),
4111
+ ),
4112
+ 'action-xhr' => array(
4113
+ 'blacklisted_value_regex' => '__amp_source_origin',
4114
+ 'value_url' => array(
4115
+ 'allow_relative' => true,
4116
+ 'allowed_protocol' => array(
4117
+ 'https',
4118
+ ),
4119
+ ),
4120
+ ),
4121
+ 'autocomplete' => array(),
4122
+ 'custom-validation-reporting' => array(
4123
+ 'value_regex' => '(show-first-on-submit|show-all-on-submit|as-you-go|interact-and-submit)',
4124
+ ),
4125
+ 'enctype' => array(),
4126
+ 'method' => array(
4127
+ 'value_casei' => 'get',
4128
+ ),
4129
+ 'name' => array(),
4130
+ 'novalidate' => array(),
4131
+ 'target' => array(
4132
+ 'mandatory' => true,
4133
+ 'value_regex_casei' => '(_blank|_top)',
4134
+ ),
4135
+ 'verify-xhr' => array(
4136
+ 'blacklisted_value_regex' => '__amp_source_origin',
4137
+ 'value_url' => array(
4138
+ 'allow_relative' => true,
4139
+ 'allowed_protocol' => array(
4140
+ 'https',
4141
+ ),
4142
+ ),
4143
+ ),
4144
+ ),
4145
+ 'tag_spec' => array(
4146
+ 'disallowed_ancestor' => array(
4147
+ 'amp-app-banner',
4148
+ ),
4149
+ 'requires_extension' => array(
4150
+ 'amp-form',
4151
+ ),
4152
+ 'spec_name' => 'FORM [method=GET]',
4153
+ ),
4154
+ ),
4155
+ array(
4156
+ 'attr_spec_list' => array(
4157
+ 'accept' => array(),
4158
+ 'accept-charset' => array(),
4159
+ 'action-xhr' => array(
4160
+ 'blacklisted_value_regex' => '__amp_source_origin',
4161
+ 'mandatory' => true,
4162
+ 'value_url' => array(
4163
+ 'allow_relative' => true,
4164
+ 'allowed_protocol' => array(
4165
+ 'https',
4166
+ ),
4167
+ ),
4168
+ ),
4169
+ 'autocomplete' => array(),
4170
+ 'custom-validation-reporting' => array(
4171
+ 'value_regex' => '(show-first-on-submit|show-all-on-submit|as-you-go)',
4172
+ ),
4173
+ 'enctype' => array(),
4174
+ 'method' => array(
4175
+ 'dispatch_key' => 2,
4176
+ 'mandatory' => true,
4177
+ 'value_casei' => 'post',
4178
+ ),
4179
+ 'name' => array(),
4180
+ 'novalidate' => array(),
4181
+ 'target' => array(
4182
+ 'mandatory' => true,
4183
+ 'value_regex_casei' => '(_blank|_top)',
4184
+ ),
4185
+ 'verify-xhr' => array(
4186
+ 'blacklisted_value_regex' => '__amp_source_origin',
4187
+ 'value_url' => array(
4188
+ 'allow_relative' => true,
4189
+ 'allowed_protocol' => array(
4190
+ 'https',
4191
+ ),
4192
+ ),
4193
+ ),
4194
+ ),
4195
+ 'tag_spec' => array(
4196
+ 'disallowed_ancestor' => array(
4197
+ 'amp-app-banner',
4198
+ ),
4199
+ 'requires_extension' => array(
4200
+ 'amp-form',
4201
+ ),
4202
+ 'spec_name' => 'FORM [method=POST]',
4203
+ ),
4204
+ ),
4205
+ ),
4206
+ 'g' => array(
4207
+ array(
4208
+ 'attr_spec_list' => array(
4209
+ 'alignment-baseline' => array(),
4210
+ 'baseline-shift' => array(),
4211
+ 'clip' => array(),
4212
+ 'clip-path' => array(),
4213
+ 'clip-rule' => array(),
4214
+ 'color' => array(),
4215
+ 'color-interpolation' => array(),
4216
+ 'color-interpolation-filters' => array(),
4217
+ 'color-profile' => array(),
4218
+ 'color-rendering' => array(),
4219
+ 'cursor' => array(),
4220
+ 'direction' => array(),
4221
+ 'display' => array(),
4222
+ 'dominant-baseline' => array(),
4223
+ 'enable-background' => array(),
4224
+ 'externalresourcesrequired' => array(),
4225
+ 'fill' => array(),
4226
+ 'fill-opacity' => array(),
4227
+ 'fill-rule' => array(),
4228
+ 'filter' => array(),
4229
+ 'flood-color' => array(),
4230
+ 'flood-opacity' => array(),
4231
+ 'font-family' => array(),
4232
+ 'font-size' => array(),
4233
+ 'font-size-adjust' => array(),
4234
+ 'font-stretch' => array(),
4235
+ 'font-style' => array(),
4236
+ 'font-variant' => array(),
4237
+ 'font-weight' => array(),
4238
+ 'glyph-orientation-horizontal' => array(),
4239
+ 'glyph-orientation-vertical' => array(),
4240
+ 'image-rendering' => array(),
4241
+ 'kerning' => array(),
4242
+ 'letter-spacing' => array(),
4243
+ 'lighting-color' => array(),
4244
+ 'marker-end' => array(),
4245
+ 'marker-mid' => array(),
4246
+ 'marker-start' => array(),
4247
+ 'mask' => array(),
4248
+ 'opacity' => array(),
4249
+ 'overflow' => array(),
4250
+ 'pointer-events' => array(),
4251
+ 'requiredextensions' => array(),
4252
+ 'requiredfeatures' => array(),
4253
+ 'shape-rendering' => array(),
4254
+ 'stop-color' => array(),
4255
+ 'stop-opacity' => array(),
4256
+ 'stroke' => array(),
4257
+ 'stroke-dasharray' => array(),
4258
+ 'stroke-dashoffset' => array(),
4259
+ 'stroke-linecap' => array(),
4260
+ 'stroke-linejoin' => array(),
4261
+ 'stroke-miterlimit' => array(),
4262
+ 'stroke-opacity' => array(),
4263
+ 'stroke-width' => array(),
4264
+ 'style' => array(
4265
+ 'blacklisted_value_regex' => '!important',
4266
+ ),
4267
+ 'systemlanguage' => array(),
4268
+ 'text-anchor' => array(),
4269
+ 'text-decoration' => array(),
4270
+ 'text-rendering' => array(),
4271
+ 'transform' => array(),
4272
+ 'unicode-bidi' => array(),
4273
+ 'vector-effect' => array(),
4274
+ 'visibility' => array(),
4275
+ 'word-spacing' => array(),
4276
+ 'writing-mode' => array(),
4277
+ 'xml:lang' => array(),
4278
+ 'xml:space' => array(),
4279
+ 'xmlns' => array(),
4280
+ 'xmlns:xlink' => array(),
4281
+ ),
4282
+ 'tag_spec' => array(
4283
+ 'mandatory_ancestor' => 'svg',
4284
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
4285
+ ),
4286
+ ),
4287
+ ),
4288
+ 'glyph' => array(
4289
+ array(
4290
+ 'attr_spec_list' => array(
4291
+ 'alignment-baseline' => array(),
4292
+ 'arabic-form' => array(),
4293
+ 'baseline-shift' => array(),
4294
+ 'clip' => array(),
4295
+ 'clip-path' => array(),
4296
+ 'clip-rule' => array(),
4297
+ 'color' => array(),
4298
+ 'color-interpolation' => array(),
4299
+ 'color-interpolation-filters' => array(),
4300
+ 'color-profile' => array(),
4301
+ 'color-rendering' => array(),
4302
+ 'cursor' => array(),
4303
+ 'd' => array(),
4304
+ 'direction' => array(),
4305
+ 'display' => array(),
4306
+ 'dominant-baseline' => array(),
4307
+ 'enable-background' => array(),
4308
+ 'fill' => array(),
4309
+ 'fill-opacity' => array(),
4310
+ 'fill-rule' => array(),
4311
+ 'filter' => array(),
4312
+ 'flood-color' => array(),
4313
+ 'flood-opacity' => array(),
4314
+ 'font-family' => array(),
4315
+ 'font-size' => array(),
4316
+ 'font-size-adjust' => array(),
4317
+ 'font-stretch' => array(),
4318
+ 'font-style' => array(),
4319
+ 'font-variant' => array(),
4320
+ 'font-weight' => array(),
4321
+ 'glyph-name' => array(),
4322
+ 'glyph-orientation-horizontal' => array(),
4323
+ 'glyph-orientation-vertical' => array(),
4324
+ 'horiz-adv-x' => array(),
4325
+ 'image-rendering' => array(),
4326
+ 'kerning' => array(),
4327
+ 'letter-spacing' => array(),
4328
+ 'lighting-color' => array(),
4329
+ 'marker-end' => array(),
4330
+ 'marker-mid' => array(),
4331
+ 'marker-start' => array(),
4332
+ 'mask' => array(),
4333
+ 'opacity' => array(),
4334
+ 'orientation' => array(),
4335
+ 'overflow' => array(),
4336
+ 'pointer-events' => array(),
4337
+ 'shape-rendering' => array(),
4338
+ 'stop-color' => array(),
4339
+ 'stop-opacity' => array(),
4340
+ 'stroke' => array(),
4341
+ 'stroke-dasharray' => array(),
4342
+ 'stroke-dashoffset' => array(),
4343
+ 'stroke-linecap' => array(),
4344
+ 'stroke-linejoin' => array(),
4345
+ 'stroke-miterlimit' => array(),
4346
+ 'stroke-opacity' => array(),
4347
+ 'stroke-width' => array(),
4348
+ 'style' => array(
4349
+ 'blacklisted_value_regex' => '!important',
4350
+ ),
4351
+ 'text-anchor' => array(),
4352
+ 'text-decoration' => array(),
4353
+ 'text-rendering' => array(),
4354
+ 'unicode' => array(),
4355
+ 'unicode-bidi' => array(),
4356
+ 'vector-effect' => array(),
4357
+ 'vert-adv-y' => array(),
4358
+ 'vert-origin-x' => array(),
4359
+ 'vert-origin-y' => array(),
4360
+ 'visibility' => array(),
4361
+ 'word-spacing' => array(),
4362
+ 'writing-mode' => array(),
4363
+ 'xml:lang' => array(),
4364
+ 'xml:space' => array(),
4365
+ 'xmlns' => array(),
4366
+ 'xmlns:xlink' => array(),
4367
+ ),
4368
+ 'tag_spec' => array(
4369
+ 'mandatory_ancestor' => 'svg',
4370
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
4371
+ ),
4372
+ ),
4373
+ ),
4374
+ 'glyphref' => array(
4375
+ array(
4376
+ 'attr_spec_list' => array(
4377
+ 'alignment-baseline' => array(),
4378
+ 'baseline-shift' => array(),
4379
+ 'clip' => array(),
4380
+ 'clip-path' => array(),
4381
+ 'clip-rule' => array(),
4382
+ 'color' => array(),
4383
+ 'color-interpolation' => array(),
4384
+ 'color-interpolation-filters' => array(),
4385
+ 'color-profile' => array(),
4386
+ 'color-rendering' => array(),
4387
+ 'cursor' => array(),
4388
+ 'direction' => array(),
4389
+ 'display' => array(),
4390
+ 'dominant-baseline' => array(),
4391
+ 'dx' => array(),
4392
+ 'dy' => array(),
4393
+ 'enable-background' => array(),
4394
+ 'fill' => array(),
4395
+ 'fill-opacity' => array(),
4396
+ 'fill-rule' => array(),
4397
+ 'filter' => array(),
4398
+ 'flood-color' => array(),
4399
+ 'flood-opacity' => array(),
4400
+ 'font-family' => array(),
4401
+ 'font-size' => array(),
4402
+ 'font-size-adjust' => array(),
4403
+ 'font-stretch' => array(),
4404
+ 'font-style' => array(),
4405
+ 'font-variant' => array(),
4406
+ 'font-weight' => array(),
4407
+ 'format' => array(),
4408
+ 'glyph-orientation-horizontal' => array(),
4409
+ 'glyph-orientation-vertical' => array(),
4410
+ 'glyphref' => array(),
4411
+ 'image-rendering' => array(),
4412
+ 'kerning' => array(),
4413
+ 'letter-spacing' => array(),
4414
+ 'lighting-color' => array(),
4415
+ 'marker-end' => array(),
4416
+ 'marker-mid' => array(),
4417
+ 'marker-start' => array(),
4418
+ 'mask' => array(),
4419
+ 'opacity' => array(),
4420
+ 'overflow' => array(),
4421
+ 'pointer-events' => array(),
4422
+ 'shape-rendering' => array(),
4423
+ 'stop-color' => array(),
4424
+ 'stop-opacity' => array(),
4425
+ 'stroke' => array(),
4426
+ 'stroke-dasharray' => array(),
4427
+ 'stroke-dashoffset' => array(),
4428
+ 'stroke-linecap' => array(),
4429
+ 'stroke-linejoin' => array(),
4430
+ 'stroke-miterlimit' => array(),
4431
+ 'stroke-opacity' => array(),
4432
+ 'stroke-width' => array(),
4433
+ 'style' => array(
4434
+ 'blacklisted_value_regex' => '!important',
4435
+ ),
4436
+ 'text-anchor' => array(),
4437
+ 'text-decoration' => array(),
4438
+ 'text-rendering' => array(),
4439
+ 'unicode-bidi' => array(),
4440
+ 'vector-effect' => array(),
4441
+ 'visibility' => array(),
4442
+ 'word-spacing' => array(),
4443
+ 'writing-mode' => array(),
4444
+ 'x' => array(),
4445
+ 'xlink:actuate' => array(),
4446
+ 'xlink:arcrole' => array(),
4447
+ 'xlink:href' => array(
4448
+ 'alternative_names' => array(
4449
+ 'href',
4450
+ ),
4451
+ 'value_url' => array(
4452
+ 'allow_empty' => false,
4453
+ 'allow_relative' => true,
4454
+ 'allowed_protocol' => array(
4455
+ 'http',
4456
+ 'https',
4457
+ ),
4458
+ ),
4459
+ ),
4460
+ 'xlink:role' => array(),
4461
+ 'xlink:show' => array(),
4462
+ 'xlink:title' => array(),
4463
+ 'xlink:type' => array(),
4464
+ 'xml:lang' => array(),
4465
+ 'xml:space' => array(),
4466
+ 'xmlns' => array(),
4467
+ 'xmlns:xlink' => array(),
4468
+ 'y' => array(),
4469
+ ),
4470
+ 'tag_spec' => array(
4471
+ 'mandatory_ancestor' => 'svg',
4472
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
4473
+ ),
4474
+ ),
4475
+ ),
4476
+ 'h1' => array(
4477
+ array(
4478
+ 'attr_spec_list' => array(
4479
+ 'align' => array(),
4480
+ ),
4481
+ 'tag_spec' => array(),
4482
+ ),
4483
+ ),
4484
+ 'h2' => array(
4485
+ array(
4486
+ 'attr_spec_list' => array(
4487
+ 'align' => array(),
4488
+ ),
4489
+ 'tag_spec' => array(),
4490
+ ),
4491
+ ),
4492
+ 'h3' => array(
4493
+ array(
4494
+ 'attr_spec_list' => array(
4495
+ 'align' => array(),
4496
+ ),
4497
+ 'tag_spec' => array(),
4498
+ ),
4499
+ ),
4500
+ 'h4' => array(
4501
+ array(
4502
+ 'attr_spec_list' => array(
4503
+ 'align' => array(),
4504
+ ),
4505
+ 'tag_spec' => array(),
4506
+ ),
4507
+ ),
4508
+ 'h5' => array(
4509
+ array(
4510
+ 'attr_spec_list' => array(
4511
+ 'align' => array(),
4512
+ ),
4513
+ 'tag_spec' => array(),
4514
+ ),
4515
+ ),
4516
+ 'h6' => array(
4517
+ array(
4518
+ 'attr_spec_list' => array(
4519
+ 'align' => array(),
4520
+ ),
4521
+ 'tag_spec' => array(),
4522
+ ),
4523
+ ),
4524
+ 'head' => array(
4525
+ array(
4526
+ 'attr_spec_list' => array(),
4527
+ 'tag_spec' => array(
4528
+ 'mandatory' => true,
4529
+ 'mandatory_parent' => 'html',
4530
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#required-markup',
4531
+ 'unique' => true,
4532
+ ),
4533
+ ),
4534
+ ),
4535
+ 'header' => array(
4536
+ array(
4537
+ 'attr_spec_list' => array(),
4538
+ 'tag_spec' => array(),
4539
+ ),
4540
+ ),
4541
+ 'hgroup' => array(
4542
+ array(
4543
+ 'attr_spec_list' => array(),
4544
+ 'tag_spec' => array(),
4545
+ ),
4546
+ ),
4547
+ 'hkern' => array(
4548
+ array(
4549
+ 'attr_spec_list' => array(
4550
+ 'g1' => array(),
4551
+ 'g2' => array(),
4552
+ 'k' => array(),
4553
+ 'style' => array(
4554
+ 'blacklisted_value_regex' => '!important',
4555
+ ),
4556
+ 'u1' => array(),
4557
+ 'u2' => array(),
4558
+ 'xml:lang' => array(),
4559
+ 'xml:space' => array(),
4560
+ 'xmlns' => array(),
4561
+ 'xmlns:xlink' => array(),
4562
+ ),
4563
+ 'tag_spec' => array(
4564
+ 'mandatory_ancestor' => 'svg',
4565
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
4566
+ ),
4567
+ ),
4568
+ ),
4569
+ 'hr' => array(
4570
+ array(
4571
+ 'attr_spec_list' => array(),
4572
+ 'tag_spec' => array(),
4573
+ ),
4574
+ ),
4575
+ 'html' => array(
4576
+ array(
4577
+ 'attr_spec_list' => array(
4578
+ '\\u26a1' => array(
4579
+ 'alternative_names' => array(
4580
+ 'amp',
4581
+ ),
4582
+ 'mandatory' => true,
4583
+ 'value' => '',
4584
+ ),
4585
+ ),
4586
+ 'tag_spec' => array(
4587
+ 'mandatory' => true,
4588
+ 'mandatory_parent' => '!doctype',
4589
+ 'spec_name' => 'html \\u26a1 for top-level html',
4590
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#required-markup',
4591
+ 'unique' => true,
4592
+ ),
4593
+ ),
4594
+ ),
4595
+ 'i' => array(
4596
+ array(
4597
+ 'attr_spec_list' => array(),
4598
+ 'tag_spec' => array(),
4599
+ ),
4600
+ ),
4601
+ 'iframe' => array(
4602
+ array(
4603
+ 'attr_spec_list' => array(
4604
+ 'frameborder' => array(
4605
+ 'value_regex' => '0|1',
4606
+ ),
4607
+ 'height' => array(),
4608
+ 'name' => array(),
4609
+ 'referrerpolicy' => array(),
4610
+ 'resizable' => array(
4611
+ 'value' => '',
4612
+ ),
4613
+ 'sandbox' => array(),
4614
+ 'scrolling' => array(
4615
+ 'value_regex' => 'auto|yes|no',
4616
+ ),
4617
+ 'src' => array(
4618
+ 'blacklisted_value_regex' => '__amp_source_origin',
4619
+ 'value_url' => array(
4620
+ 'allow_relative' => false,
4621
+ 'allowed_protocol' => array(
4622
+ 'data',
4623
+ 'https',
4624
+ ),
4625
+ ),
4626
+ ),
4627
+ 'srcdoc' => array(),
4628
+ 'width' => array(),
4629
+ ),
4630
+ 'tag_spec' => array(
4631
+ 'mandatory_ancestor' => 'noscript',
4632
+ 'mandatory_ancestor_suggested_alternative' => 'amp-iframe',
4633
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-iframe',
4634
+ ),
4635
+ ),
4636
+ ),
4637
+ 'image' => array(
4638
+ array(
4639
+ 'attr_spec_list' => array(
4640
+ 'alignment-baseline' => array(),
4641
+ 'baseline-shift' => array(),
4642
+ 'clip' => array(),
4643
+ 'clip-path' => array(),
4644
+ 'clip-rule' => array(),
4645
+ 'color' => array(),
4646
+ 'color-interpolation' => array(),
4647
+ 'color-interpolation-filters' => array(),
4648
+ 'color-profile' => array(),
4649
+ 'color-rendering' => array(),
4650
+ 'cursor' => array(),
4651
+ 'direction' => array(),
4652
+ 'display' => array(),
4653
+ 'dominant-baseline' => array(),
4654
+ 'enable-background' => array(),
4655
+ 'externalresourcesrequired' => array(),
4656
+ 'fill' => array(),
4657
+ 'fill-opacity' => array(),
4658
+ 'fill-rule' => array(),
4659
+ 'filter' => array(),
4660
+ 'flood-color' => array(),
4661
+ 'flood-opacity' => array(),
4662
+ 'font-family' => array(),
4663
+ 'font-size' => array(),
4664
+ 'font-size-adjust' => array(),
4665
+ 'font-stretch' => array(),
4666
+ 'font-style' => array(),
4667
+ 'font-variant' => array(),
4668
+ 'font-weight' => array(),
4669
+ 'glyph-orientation-horizontal' => array(),
4670
+ 'glyph-orientation-vertical' => array(),
4671
+ 'height' => array(),
4672
+ 'image-rendering' => array(),
4673
+ 'kerning' => array(),
4674
+ 'letter-spacing' => array(),
4675
+ 'lighting-color' => array(),
4676
+ 'marker-end' => array(),
4677
+ 'marker-mid' => array(),
4678
+ 'marker-start' => array(),
4679
+ 'mask' => array(),
4680
+ 'opacity' => array(),
4681
+ 'overflow' => array(),
4682
+ 'pointer-events' => array(),
4683
+ 'preserveaspectratio' => array(),
4684
+ 'requiredextensions' => array(),
4685
+ 'requiredfeatures' => array(),
4686
+ 'shape-rendering' => array(),
4687
+ 'stop-color' => array(),
4688
+ 'stop-opacity' => array(),
4689
+ 'stroke' => array(),
4690
+ 'stroke-dasharray' => array(),
4691
+ 'stroke-dashoffset' => array(),
4692
+ 'stroke-linecap' => array(),
4693
+ 'stroke-linejoin' => array(),
4694
+ 'stroke-miterlimit' => array(),
4695
+ 'stroke-opacity' => array(),
4696
+ 'stroke-width' => array(),
4697
+ 'style' => array(
4698
+ 'blacklisted_value_regex' => '!important',
4699
+ ),
4700
+ 'systemlanguage' => array(),
4701
+ 'text-anchor' => array(),
4702
+ 'text-decoration' => array(),
4703
+ 'text-rendering' => array(),
4704
+ 'transform' => array(),
4705
+ 'unicode-bidi' => array(),
4706
+ 'vector-effect' => array(),
4707
+ 'visibility' => array(),
4708
+ 'width' => array(),
4709
+ 'word-spacing' => array(),
4710
+ 'writing-mode' => array(),
4711
+ 'x' => array(),
4712
+ 'xlink:actuate' => array(),
4713
+ 'xlink:arcrole' => array(),
4714
+ 'xlink:href' => array(
4715
+ 'alternative_names' => array(
4716
+ 'href',
4717
+ ),
4718
+ 'blacklisted_value_regex' => '(^|\\s)data:image\\/svg\\+xml',
4719
+ 'value_url' => array(
4720
+ 'allow_empty' => false,
4721
+ 'allow_relative' => true,
4722
+ 'allowed_protocol' => array(
4723
+ 'data',
4724
+ 'http',
4725
+ 'https',
4726
+ ),
4727
+ ),
4728
+ ),
4729
+ 'xlink:role' => array(),
4730
+ 'xlink:show' => array(),
4731
+ 'xlink:title' => array(),
4732
+ 'xlink:type' => array(),
4733
+ 'xml:lang' => array(),
4734
+ 'xml:space' => array(),
4735
+ 'xmlns' => array(),
4736
+ 'xmlns:xlink' => array(),
4737
+ 'y' => array(),
4738
+ ),
4739
+ 'tag_spec' => array(
4740
+ 'mandatory_ancestor' => 'svg',
4741
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
4742
+ ),
4743
+ ),
4744
+ ),
4745
+ 'img' => array(
4746
+ array(
4747
+ 'attr_spec_list' => array(
4748
+ 'alt' => array(),
4749
+ 'border' => array(),
4750
+ 'height' => array(),
4751
+ 'ismap' => array(),
4752
+ 'longdesc' => array(
4753
+ 'blacklisted_value_regex' => '__amp_source_origin',
4754
+ 'value_url' => array(
4755
+ 'allow_relative' => true,
4756
+ 'allowed_protocol' => array(
4757
+ 'http',
4758
+ 'https',
4759
+ ),
4760
+ ),
4761
+ ),
4762
+ 'src' => array(
4763
+ 'alternative_names' => array(
4764
+ 'srcset',
4765
+ ),
4766
+ 'blacklisted_value_regex' => '__amp_source_origin',
4767
+ 'mandatory' => true,
4768
+ 'value_url' => array(
4769
+ 'allow_relative' => true,
4770
+ 'allowed_protocol' => array(
4771
+ 'data',
4772
+ 'https',
4773
+ ),
4774
+ ),
4775
+ ),
4776
+ 'width' => array(),
4777
+ ),
4778
+ 'tag_spec' => array(
4779
+ 'mandatory_ancestor' => 'noscript',
4780
+ 'mandatory_ancestor_suggested_alternative' => 'amp-img',
4781
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-img',
4782
+ ),
4783
+ ),
4784
+ ),
4785
+ 'input' => array(
4786
+ array(
4787
+ 'attr_spec_list' => array(
4788
+ '[accept]' => array(),
4789
+ '[accesskey]' => array(),
4790
+ '[autocomplete]' => array(),
4791
+ '[checked]' => array(),
4792
+ '[disabled]' => array(),
4793
+ '[height]' => array(),
4794
+ '[inputmode]' => array(),
4795
+ '[max]' => array(),
4796
+ '[maxlength]' => array(),
4797
+ '[min]' => array(),
4798
+ '[minlength]' => array(),
4799
+ '[multiple]' => array(),
4800
+ '[pattern]' => array(),
4801
+ '[placeholder]' => array(),
4802
+ '[readonly]' => array(),
4803
+ '[required]' => array(),
4804
+ '[selectiondirection]' => array(),
4805
+ '[size]' => array(),
4806
+ '[spellcheck]' => array(),
4807
+ '[step]' => array(),
4808
+ '[type]' => array(),
4809
+ '[value]' => array(),
4810
+ '[width]' => array(),
4811
+ 'accept' => array(),
4812
+ 'accesskey' => array(),
4813
+ 'autocomplete' => array(),
4814
+ 'autofocus' => array(),
4815
+ 'checked' => array(),
4816
+ 'disabled' => array(),
4817
+ 'height' => array(),
4818
+ 'inputmode' => array(),
4819
+ 'list' => array(),
4820
+ 'max' => array(),
4821
+ 'maxlength' => array(),
4822
+ 'min' => array(),
4823
+ 'minlength' => array(),
4824
+ 'multiple' => array(),
4825
+ 'name' => array(
4826
+ 'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
4827
+ ),
4828
+ 'pattern' => array(),
4829
+ 'placeholder' => array(),
4830
+ 'readonly' => array(),
4831
+ 'required' => array(),
4832
+ 'selectiondirection' => array(),
4833
+ 'size' => array(),
4834
+ 'spellcheck' => array(),
4835
+ 'step' => array(),
4836
+ 'tabindex' => array(),
4837
+ 'type' => array(
4838
+ 'blacklisted_value_regex' => '(^|\\s)(button|file|image|password|)(\\s|$)',
4839
+ ),
4840
+ 'value' => array(),
4841
+ 'width' => array(),
4842
+ ),
4843
+ 'tag_spec' => array(
4844
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
4845
+ ),
4846
+ ),
4847
+ ),
4848
+ 'ins' => array(
4849
+ array(
4850
+ 'attr_spec_list' => array(
4851
+ 'cite' => array(
4852
+ 'blacklisted_value_regex' => '__amp_source_origin',
4853
+ 'value_url' => array(
4854
+ 'allow_empty' => true,
4855
+ 'allow_relative' => true,
4856
+ 'allowed_protocol' => array(
4857
+ 'http',
4858
+ 'https',
4859
+ ),
4860
+ ),
4861
+ ),
4862
+ 'datetime' => array(),
4863
+ ),
4864
+ 'tag_spec' => array(),
4865
+ ),
4866
+ ),
4867
+ 'kbd' => array(
4868
+ array(
4869
+ 'attr_spec_list' => array(),
4870
+ 'tag_spec' => array(),
4871
+ ),
4872
+ ),
4873
+ 'label' => array(
4874
+ array(
4875
+ 'attr_spec_list' => array(
4876
+ 'for' => array(),
4877
+ ),
4878
+ 'tag_spec' => array(
4879
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
4880
+ ),
4881
+ ),
4882
+ ),
4883
+ 'legend' => array(
4884
+ array(
4885
+ 'attr_spec_list' => array(),
4886
+ 'tag_spec' => array(),
4887
+ ),
4888
+ ),
4889
+ 'li' => array(
4890
+ array(
4891
+ 'attr_spec_list' => array(
4892
+ 'value' => array(
4893
+ 'value_regex' => '[0-9]*',
4894
+ ),
4895
+ ),
4896
+ 'tag_spec' => array(),
4897
+ ),
4898
+ ),
4899
+ 'line' => array(
4900
+ array(
4901
+ 'attr_spec_list' => array(
4902
+ 'alignment-baseline' => array(),
4903
+ 'baseline-shift' => array(),
4904
+ 'clip' => array(),
4905
+ 'clip-path' => array(),
4906
+ 'clip-rule' => array(),
4907
+ 'color' => array(),
4908
+ 'color-interpolation' => array(),
4909
+ 'color-interpolation-filters' => array(),
4910
+ 'color-profile' => array(),
4911
+ 'color-rendering' => array(),
4912
+ 'cursor' => array(),
4913
+ 'direction' => array(),
4914
+ 'display' => array(),
4915
+ 'dominant-baseline' => array(),
4916
+ 'enable-background' => array(),
4917
+ 'externalresourcesrequired' => array(),
4918
+ 'fill' => array(),
4919
+ 'fill-opacity' => array(),
4920
+ 'fill-rule' => array(),
4921
+ 'filter' => array(),
4922
+ 'flood-color' => array(),
4923
+ 'flood-opacity' => array(),
4924
+ 'font-family' => array(),
4925
+ 'font-size' => array(),
4926
+ 'font-size-adjust' => array(),
4927
+ 'font-stretch' => array(),
4928
+ 'font-style' => array(),
4929
+ 'font-variant' => array(),
4930
+ 'font-weight' => array(),
4931
+ 'glyph-orientation-horizontal' => array(),
4932
+ 'glyph-orientation-vertical' => array(),
4933
+ 'image-rendering' => array(),
4934
+ 'kerning' => array(),
4935
+ 'letter-spacing' => array(),
4936
+ 'lighting-color' => array(),
4937
+ 'marker-end' => array(),
4938
+ 'marker-mid' => array(),
4939
+ 'marker-start' => array(),
4940
+ 'mask' => array(),
4941
+ 'opacity' => array(),
4942
+ 'overflow' => array(),
4943
+ 'pointer-events' => array(),
4944
+ 'requiredextensions' => array(),
4945
+ 'requiredfeatures' => array(),
4946
+ 'shape-rendering' => array(),
4947
+ 'sketch:type' => array(),
4948
+ 'stop-color' => array(),
4949
+ 'stop-opacity' => array(),
4950
+ 'stroke' => array(),
4951
+ 'stroke-dasharray' => array(),
4952
+ 'stroke-dashoffset' => array(),
4953
+ 'stroke-linecap' => array(),
4954
+ 'stroke-linejoin' => array(),
4955
+ 'stroke-miterlimit' => array(),
4956
+ 'stroke-opacity' => array(),
4957
+ 'stroke-width' => array(),
4958
+ 'style' => array(
4959
+ 'blacklisted_value_regex' => '!important',
4960
+ ),
4961
+ 'systemlanguage' => array(),
4962
+ 'text-anchor' => array(),
4963
+ 'text-decoration' => array(),
4964
+ 'text-rendering' => array(),
4965
+ 'transform' => array(),
4966
+ 'unicode-bidi' => array(),
4967
+ 'vector-effect' => array(),
4968
+ 'visibility' => array(),
4969
+ 'word-spacing' => array(),
4970
+ 'writing-mode' => array(),
4971
+ 'x1' => array(),
4972
+ 'x2' => array(),
4973
+ 'xml:lang' => array(),
4974
+ 'xml:space' => array(),
4975
+ 'xmlns' => array(),
4976
+ 'xmlns:xlink' => array(),
4977
+ 'y1' => array(),
4978
+ 'y2' => array(),
4979
+ ),
4980
+ 'tag_spec' => array(
4981
+ 'mandatory_ancestor' => 'svg',
4982
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
4983
+ ),
4984
+ ),
4985
+ ),
4986
+ 'lineargradient' => array(
4987
+ array(
4988
+ 'attr_spec_list' => array(
4989
+ 'alignment-baseline' => array(),
4990
+ 'baseline-shift' => array(),
4991
+ 'clip' => array(),
4992
+ 'clip-path' => array(),
4993
+ 'clip-rule' => array(),
4994
+ 'color' => array(),
4995
+ 'color-interpolation' => array(),
4996
+ 'color-interpolation-filters' => array(),
4997
+ 'color-profile' => array(),
4998
+ 'color-rendering' => array(),
4999
+ 'cursor' => array(),
5000
+ 'direction' => array(),
5001
+ 'display' => array(),
5002
+ 'dominant-baseline' => array(),
5003
+ 'enable-background' => array(),
5004
+ 'externalresourcesrequired' => array(),
5005
+ 'fill' => array(),
5006
+ 'fill-opacity' => array(),
5007
+ 'fill-rule' => array(),
5008
+ 'filter' => array(),
5009
+ 'flood-color' => array(),
5010
+ 'flood-opacity' => array(),
5011
+ 'font-family' => array(),
5012
+ 'font-size' => array(),
5013
+ 'font-size-adjust' => array(),
5014
+ 'font-stretch' => array(),
5015
+ 'font-style' => array(),
5016
+ 'font-variant' => array(),
5017
+ 'font-weight' => array(),
5018
+ 'glyph-orientation-horizontal' => array(),
5019
+ 'glyph-orientation-vertical' => array(),
5020
+ 'gradienttransform' => array(),
5021
+ 'gradientunits' => array(),
5022
+ 'image-rendering' => array(),
5023
+ 'kerning' => array(),
5024
+ 'letter-spacing' => array(),
5025
+ 'lighting-color' => array(),
5026
+ 'marker-end' => array(),
5027
+ 'marker-mid' => array(),
5028
+ 'marker-start' => array(),
5029
+ 'mask' => array(),
5030
+ 'opacity' => array(),
5031
+ 'overflow' => array(),
5032
+ 'pointer-events' => array(),
5033
+ 'shape-rendering' => array(),
5034
+ 'spreadmethod' => array(),
5035
+ 'stop-color' => array(),
5036
+ 'stop-opacity' => array(),
5037
+ 'stroke' => array(),
5038
+ 'stroke-dasharray' => array(),
5039
+ 'stroke-dashoffset' => array(),
5040
+ 'stroke-linecap' => array(),
5041
+ 'stroke-linejoin' => array(),
5042
+ 'stroke-miterlimit' => array(),
5043
+ 'stroke-opacity' => array(),
5044
+ 'stroke-width' => array(),
5045
+ 'style' => array(
5046
+ 'blacklisted_value_regex' => '!important',
5047
+ ),
5048
+ 'text-anchor' => array(),
5049
+ 'text-decoration' => array(),
5050
+ 'text-rendering' => array(),
5051
+ 'unicode-bidi' => array(),
5052
+ 'vector-effect' => array(),
5053
+ 'visibility' => array(),
5054
+ 'word-spacing' => array(),
5055
+ 'writing-mode' => array(),
5056
+ 'x1' => array(),
5057
+ 'x2' => array(),
5058
+ 'xlink:actuate' => array(),
5059
+ 'xlink:arcrole' => array(),
5060
+ 'xlink:href' => array(
5061
+ 'alternative_names' => array(
5062
+ 'href',
5063
+ ),
5064
+ 'value_url' => array(
5065
+ 'allow_empty' => false,
5066
+ 'allow_relative' => true,
5067
+ 'allowed_protocol' => array(
5068
+ 'http',
5069
+ 'https',
5070
+ ),
5071
+ ),
5072
+ ),
5073
+ 'xlink:role' => array(),
5074
+ 'xlink:show' => array(),
5075
+ 'xlink:title' => array(),
5076
+ 'xlink:type' => array(),
5077
+ 'xml:lang' => array(),
5078
+ 'xml:space' => array(),
5079
+ 'xmlns' => array(),
5080
+ 'xmlns:xlink' => array(),
5081
+ 'y1' => array(),
5082
+ 'y2' => array(),
5083
+ ),
5084
+ 'tag_spec' => array(
5085
+ 'mandatory_ancestor' => 'svg',
5086
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
5087
+ ),
5088
+ ),
5089
+ ),
5090
+ 'link' => array(
5091
+ array(
5092
+ 'attr_spec_list' => array(
5093
+ 'charset' => array(
5094
+ 'value_casei' => 'utf-8',
5095
+ ),
5096
+ 'color' => array(),
5097
+ 'crossorigin' => array(),
5098
+ 'href' => array(),
5099
+ 'hreflang' => array(),
5100
+ 'media' => array(),
5101
+ 'rel' => array(
5102
+ 'blacklisted_value_regex' => '(^|\\s)(canonical|components|import|manifest|preload|serviceworker|stylesheet|subresource|)(\\s|$)',
5103
+ 'mandatory' => true,
5104
+ ),
5105
+ 'sizes' => array(),
5106
+ 'target' => array(),
5107
+ 'type' => array(),
5108
+ ),
5109
+ 'tag_spec' => array(
5110
+ 'disallowed_ancestor' => array(
5111
+ 'template',
5112
+ ),
5113
+ 'spec_name' => 'link rel=',
5114
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5115
+ ),
5116
+ ),
5117
+ array(
5118
+ 'attr_spec_list' => array(
5119
+ 'charset' => array(
5120
+ 'value_casei' => 'utf-8',
5121
+ ),
5122
+ 'color' => array(),
5123
+ 'crossorigin' => array(),
5124
+ 'href' => array(
5125
+ 'blacklisted_value_regex' => '__amp_source_origin',
5126
+ 'mandatory' => true,
5127
+ 'value_url' => array(
5128
+ 'allow_relative' => true,
5129
+ 'allowed_protocol' => array(
5130
+ 'http',
5131
+ 'https',
5132
+ ),
5133
+ ),
5134
+ ),
5135
+ 'hreflang' => array(),
5136
+ 'media' => array(),
5137
+ 'rel' => array(
5138
+ 'dispatch_key' => 2,
5139
+ 'mandatory' => true,
5140
+ 'value_casei' => 'canonical',
5141
+ ),
5142
+ 'sizes' => array(),
5143
+ 'target' => array(),
5144
+ 'type' => array(),
5145
+ ),
5146
+ 'tag_spec' => array(
5147
+ 'mandatory' => true,
5148
+ 'mandatory_parent' => 'head',
5149
+ 'spec_name' => 'link rel=canonical',
5150
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#required-markup',
5151
+ 'unique' => true,
5152
+ ),
5153
+ ),
5154
+ array(
5155
+ 'attr_spec_list' => array(
5156
+ 'charset' => array(
5157
+ 'value_casei' => 'utf-8',
5158
+ ),
5159
+ 'color' => array(),
5160
+ 'crossorigin' => array(),
5161
+ 'href' => array(
5162
+ 'blacklisted_value_regex' => '__amp_source_origin',
5163
+ 'mandatory' => true,
5164
+ 'value_url' => array(
5165
+ 'allow_relative' => true,
5166
+ 'allowed_protocol' => array(
5167
+ 'https',
5168
+ ),
5169
+ ),
5170
+ ),
5171
+ 'hreflang' => array(),
5172
+ 'media' => array(),
5173
+ 'rel' => array(
5174
+ 'dispatch_key' => 2,
5175
+ 'mandatory' => true,
5176
+ 'value_casei' => 'manifest',
5177
+ ),
5178
+ 'sizes' => array(),
5179
+ 'target' => array(),
5180
+ 'type' => array(),
5181
+ ),
5182
+ 'tag_spec' => array(
5183
+ 'mandatory_parent' => 'head',
5184
+ 'spec_name' => 'link rel=manifest',
5185
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5186
+ ),
5187
+ ),
5188
+ array(
5189
+ 'attr_spec_list' => array(
5190
+ 'as' => array(),
5191
+ 'charset' => array(
5192
+ 'value_casei' => 'utf-8',
5193
+ ),
5194
+ 'color' => array(),
5195
+ 'crossorigin' => array(),
5196
+ 'href' => array(),
5197
+ 'hreflang' => array(),
5198
+ 'media' => array(),
5199
+ 'rel' => array(
5200
+ 'dispatch_key' => 2,
5201
+ 'mandatory' => true,
5202
+ 'value_casei' => 'preload',
5203
+ ),
5204
+ 'sizes' => array(),
5205
+ 'target' => array(),
5206
+ 'type' => array(),
5207
+ ),
5208
+ 'tag_spec' => array(
5209
+ 'disallowed_ancestor' => array(
5210
+ 'template',
5211
+ ),
5212
+ 'spec_name' => 'link rel=preload',
5213
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5214
+ ),
5215
+ ),
5216
+ array(
5217
+ 'attr_spec_list' => array(
5218
+ 'async' => array(),
5219
+ 'crossorigin' => array(),
5220
+ 'href' => array(
5221
+ 'mandatory' => true,
5222
+ 'value_regex' => 'https://cdn\\.materialdesignicons\\.com/([0-9]+\\.?)+/css/materialdesignicons\\.min\\.css|https://cloud\\.typography\\.com/[0-9]*/[0-9]*/css/fonts\\.css|https://fast\\.fonts\\.net/.*|https://fonts\\.googleapis\\.com/css\\?.*|https://fonts\\.googleapis\\.com/icon\\?.*|https://fonts\\.googleapis\\.com/earlyaccess/.*\\.css|https://maxcdn\\.bootstrapcdn\\.com/font-awesome/([0-9]+\\.?)+/css/font-awesome\\.min\\.css(\\?.*)?|https://use\\.fontawesome\\.com/releases/v([0-9]+\\.?)+/css/(all|brands|solids|fontawesome)\\.css|https://use\\.typekit\\.net/[\\w\\p{L}\\p{N}_]+\\.css',
5223
+ ),
5224
+ 'integrity' => array(),
5225
+ 'media' => array(),
5226
+ 'rel' => array(
5227
+ 'dispatch_key' => 2,
5228
+ 'mandatory' => true,
5229
+ 'value_casei' => 'stylesheet',
5230
+ ),
5231
+ 'type' => array(
5232
+ 'value_casei' => 'text/css',
5233
+ ),
5234
+ ),
5235
+ 'tag_spec' => array(
5236
+ 'mandatory_parent' => 'head',
5237
+ 'spec_name' => 'link rel=stylesheet for fonts',
5238
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#custom-fonts',
5239
+ ),
5240
+ ),
5241
+ array(
5242
+ 'attr_spec_list' => array(
5243
+ 'charset' => array(
5244
+ 'value_casei' => 'utf-8',
5245
+ ),
5246
+ 'color' => array(),
5247
+ 'crossorigin' => array(),
5248
+ 'href' => array(
5249
+ 'mandatory' => true,
5250
+ ),
5251
+ 'hreflang' => array(),
5252
+ 'itemprop' => array(
5253
+ 'dispatch_key' => 2,
5254
+ 'mandatory' => true,
5255
+ 'value_casei' => 'sameas',
5256
+ ),
5257
+ 'media' => array(),
5258
+ 'sizes' => array(),
5259
+ 'target' => array(),
5260
+ 'type' => array(),
5261
+ ),
5262
+ 'tag_spec' => array(
5263
+ 'spec_name' => 'link itemprop=sameAs',
5264
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5265
+ ),
5266
+ ),
5267
+ array(
5268
+ 'attr_spec_list' => array(
5269
+ 'charset' => array(
5270
+ 'value_casei' => 'utf-8',
5271
+ ),
5272
+ 'color' => array(),
5273
+ 'crossorigin' => array(),
5274
+ 'href' => array(
5275
+ 'mandatory' => true,
5276
+ ),
5277
+ 'hreflang' => array(),
5278
+ 'itemprop' => array(
5279
+ 'mandatory' => true,
5280
+ ),
5281
+ 'media' => array(),
5282
+ 'sizes' => array(),
5283
+ 'target' => array(),
5284
+ 'type' => array(),
5285
+ ),
5286
+ 'tag_spec' => array(
5287
+ 'spec_name' => 'link itemprop=',
5288
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5289
+ ),
5290
+ ),
5291
+ array(
5292
+ 'attr_spec_list' => array(
5293
+ 'charset' => array(
5294
+ 'value_casei' => 'utf-8',
5295
+ ),
5296
+ 'color' => array(),
5297
+ 'crossorigin' => array(),
5298
+ 'href' => array(
5299
+ 'mandatory' => true,
5300
+ ),
5301
+ 'hreflang' => array(),
5302
+ 'media' => array(),
5303
+ 'property' => array(
5304
+ 'mandatory' => true,
5305
+ ),
5306
+ 'sizes' => array(),
5307
+ 'target' => array(),
5308
+ 'type' => array(),
5309
+ ),
5310
+ 'tag_spec' => array(
5311
+ 'spec_name' => 'link property=',
5312
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5313
+ ),
5314
+ ),
5315
+ ),
5316
+ 'listing' => array(
5317
+ array(
5318
+ 'attr_spec_list' => array(),
5319
+ 'tag_spec' => array(),
5320
+ ),
5321
+ ),
5322
+ 'main' => array(
5323
+ array(
5324
+ 'attr_spec_list' => array(),
5325
+ 'tag_spec' => array(),
5326
+ ),
5327
+ ),
5328
+ 'mark' => array(
5329
+ array(
5330
+ 'attr_spec_list' => array(),
5331
+ 'tag_spec' => array(),
5332
+ ),
5333
+ ),
5334
+ 'marker' => array(
5335
+ array(
5336
+ 'attr_spec_list' => array(
5337
+ 'alignment-baseline' => array(),
5338
+ 'baseline-shift' => array(),
5339
+ 'clip' => array(),
5340
+ 'clip-path' => array(),
5341
+ 'clip-rule' => array(),
5342
+ 'color' => array(),
5343
+ 'color-interpolation' => array(),
5344
+ 'color-interpolation-filters' => array(),
5345
+ 'color-profile' => array(),
5346
+ 'color-rendering' => array(),
5347
+ 'cursor' => array(),
5348
+ 'direction' => array(),
5349
+ 'display' => array(),
5350
+ 'dominant-baseline' => array(),
5351
+ 'enable-background' => array(),
5352
+ 'externalresourcesrequired' => array(),
5353
+ 'fill' => array(),
5354
+ 'fill-opacity' => array(),
5355
+ 'fill-rule' => array(),
5356
+ 'filter' => array(),
5357
+ 'flood-color' => array(),
5358
+ 'flood-opacity' => array(),
5359
+ 'font-family' => array(),
5360
+ 'font-size' => array(),
5361
+ 'font-size-adjust' => array(),
5362
+ 'font-stretch' => array(),
5363
+ 'font-style' => array(),
5364
+ 'font-variant' => array(),
5365
+ 'font-weight' => array(),
5366
+ 'glyph-orientation-horizontal' => array(),
5367
+ 'glyph-orientation-vertical' => array(),
5368
+ 'image-rendering' => array(),
5369
+ 'kerning' => array(),
5370
+ 'letter-spacing' => array(),
5371
+ 'lighting-color' => array(),
5372
+ 'marker-end' => array(),
5373
+ 'marker-mid' => array(),
5374
+ 'marker-start' => array(),
5375
+ 'markerheight' => array(),
5376
+ 'markerunits' => array(),
5377
+ 'markerwidth' => array(),
5378
+ 'mask' => array(),
5379
+ 'opacity' => array(),
5380
+ 'orient' => array(),
5381
+ 'overflow' => array(),
5382
+ 'pointer-events' => array(),
5383
+ 'preserveaspectratio' => array(),
5384
+ 'refx' => array(),
5385
+ 'refy' => array(),
5386
+ 'shape-rendering' => array(),
5387
+ 'stop-color' => array(),
5388
+ 'stop-opacity' => array(),
5389
+ 'stroke' => array(),
5390
+ 'stroke-dasharray' => array(),
5391
+ 'stroke-dashoffset' => array(),
5392
+ 'stroke-linecap' => array(),
5393
+ 'stroke-linejoin' => array(),
5394
+ 'stroke-miterlimit' => array(),
5395
+ 'stroke-opacity' => array(),
5396
+ 'stroke-width' => array(),
5397
+ 'style' => array(
5398
+ 'blacklisted_value_regex' => '!important',
5399
+ ),
5400
+ 'text-anchor' => array(),
5401
+ 'text-decoration' => array(),
5402
+ 'text-rendering' => array(),
5403
+ 'transform' => array(),
5404
+ 'unicode-bidi' => array(),
5405
+ 'vector-effect' => array(),
5406
+ 'viewbox' => array(),
5407
+ 'visibility' => array(),
5408
+ 'word-spacing' => array(),
5409
+ 'writing-mode' => array(),
5410
+ 'xml:lang' => array(),
5411
+ 'xml:space' => array(),
5412
+ 'xmlns' => array(),
5413
+ 'xmlns:xlink' => array(),
5414
+ ),
5415
+ 'tag_spec' => array(
5416
+ 'mandatory_ancestor' => 'svg',
5417
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
5418
+ ),
5419
+ ),
5420
+ ),
5421
+ 'mask' => array(
5422
+ array(
5423
+ 'attr_spec_list' => array(
5424
+ 'alignment-baseline' => array(),
5425
+ 'baseline-shift' => array(),
5426
+ 'clip' => array(),
5427
+ 'clip-path' => array(),
5428
+ 'clip-rule' => array(),
5429
+ 'color' => array(),
5430
+ 'color-interpolation' => array(),
5431
+ 'color-interpolation-filters' => array(),
5432
+ 'color-profile' => array(),
5433
+ 'color-rendering' => array(),
5434
+ 'cursor' => array(),
5435
+ 'direction' => array(),
5436
+ 'display' => array(),
5437
+ 'dominant-baseline' => array(),
5438
+ 'enable-background' => array(),
5439
+ 'externalresourcesrequired' => array(),
5440
+ 'fill' => array(),
5441
+ 'fill-opacity' => array(),
5442
+ 'fill-rule' => array(),
5443
+ 'filter' => array(),
5444
+ 'flood-color' => array(),
5445
+ 'flood-opacity' => array(),
5446
+ 'font-family' => array(),
5447
+ 'font-size' => array(),
5448
+ 'font-size-adjust' => array(),
5449
+ 'font-stretch' => array(),
5450
+ 'font-style' => array(),
5451
+ 'font-variant' => array(),
5452
+ 'font-weight' => array(),
5453
+ 'glyph-orientation-horizontal' => array(),
5454
+ 'glyph-orientation-vertical' => array(),
5455
+ 'height' => array(),
5456
+ 'image-rendering' => array(),
5457
+ 'kerning' => array(),
5458
+ 'letter-spacing' => array(),
5459
+ 'lighting-color' => array(),
5460
+ 'marker-end' => array(),
5461
+ 'marker-mid' => array(),
5462
+ 'marker-start' => array(),
5463
+ 'mask' => array(),
5464
+ 'maskcontentunits' => array(),
5465
+ 'maskunits' => array(),
5466
+ 'opacity' => array(),
5467
+ 'overflow' => array(),
5468
+ 'pointer-events' => array(),
5469
+ 'requiredextensions' => array(),
5470
+ 'requiredfeatures' => array(),
5471
+ 'shape-rendering' => array(),
5472
+ 'stop-color' => array(),
5473
+ 'stop-opacity' => array(),
5474
+ 'stroke' => array(),
5475
+ 'stroke-dasharray' => array(),
5476
+ 'stroke-dashoffset' => array(),
5477
+ 'stroke-linecap' => array(),
5478
+ 'stroke-linejoin' => array(),
5479
+ 'stroke-miterlimit' => array(),
5480
+ 'stroke-opacity' => array(),
5481
+ 'stroke-width' => array(),
5482
+ 'style' => array(
5483
+ 'blacklisted_value_regex' => '!important',
5484
+ ),
5485
+ 'systemlanguage' => array(),
5486
+ 'text-anchor' => array(),
5487
+ 'text-decoration' => array(),
5488
+ 'text-rendering' => array(),
5489
+ 'unicode-bidi' => array(),
5490
+ 'vector-effect' => array(),
5491
+ 'visibility' => array(),
5492
+ 'width' => array(),
5493
+ 'word-spacing' => array(),
5494
+ 'writing-mode' => array(),
5495
+ 'x' => array(),
5496
+ 'xml:lang' => array(),
5497
+ 'xml:space' => array(),
5498
+ 'xmlns' => array(),
5499
+ 'xmlns:xlink' => array(),
5500
+ 'y' => array(),
5501
+ ),
5502
+ 'tag_spec' => array(
5503
+ 'mandatory_ancestor' => 'svg',
5504
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
5505
+ ),
5506
+ ),
5507
+ ),
5508
+ 'meta' => array(
5509
+ array(
5510
+ 'attr_spec_list' => array(
5511
+ 'charset' => array(
5512
+ 'dispatch_key' => 1,
5513
+ 'mandatory' => true,
5514
+ 'value_casei' => 'utf-8',
5515
+ ),
5516
+ ),
5517
+ 'tag_spec' => array(
5518
+ 'mandatory' => true,
5519
+ 'mandatory_parent' => 'head',
5520
+ 'spec_name' => 'meta charset=utf-8',
5521
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#required-markup',
5522
+ 'unique' => true,
5523
+ ),
5524
+ ),
5525
+ array(
5526
+ 'attr_spec_list' => array(
5527
+ 'content' => array(
5528
+ 'mandatory' => true,
5529
+ 'value_properties' => array(
5530
+ 'height' => array(),
5531
+ 'initial-scale' => array(),
5532
+ 'maximum-scale' => array(),
5533
+ 'minimum-scale' => array(
5534
+ 'mandatory' => true,
5535
+ 'value_double' => 1.0,
5536
+ ),
5537
+ 'shrink-to-fit' => array(),
5538
+ 'user-scalable' => array(),
5539
+ 'viewport-fit' => array(),
5540
+ 'width' => array(
5541
+ 'mandatory' => true,
5542
+ 'value' => 'device-width',
5543
+ ),
5544
+ ),
5545
+ ),
5546
+ 'name' => array(
5547
+ 'dispatch_key' => 2,
5548
+ 'mandatory' => true,
5549
+ 'value' => 'viewport',
5550
+ ),
5551
+ ),
5552
+ 'tag_spec' => array(
5553
+ 'mandatory' => true,
5554
+ 'mandatory_parent' => 'head',
5555
+ 'spec_name' => 'meta name=viewport',
5556
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#required-markup',
5557
+ 'unique' => true,
5558
+ ),
5559
+ ),
5560
+ array(
5561
+ 'attr_spec_list' => array(
5562
+ 'content' => array(
5563
+ 'mandatory' => true,
5564
+ 'value_properties' => array(
5565
+ 'chrome' => array(
5566
+ 'value' => '1',
5567
+ ),
5568
+ 'ie' => array(
5569
+ 'value' => 'edge',
5570
+ ),
5571
+ ),
5572
+ ),
5573
+ 'http-equiv' => array(
5574
+ 'dispatch_key' => 2,
5575
+ 'mandatory' => true,
5576
+ 'value_casei' => 'x-ua-compatible',
5577
+ ),
5578
+ ),
5579
+ 'tag_spec' => array(
5580
+ 'mandatory_ancestor' => 'head',
5581
+ 'spec_name' => 'meta http-equiv=X-UA-Compatible',
5582
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5583
+ ),
5584
+ ),
5585
+ array(
5586
+ 'attr_spec_list' => array(
5587
+ 'content' => array(
5588
+ 'mandatory' => true,
5589
+ 'value_regex' => '.*app-id=.*',
5590
+ ),
5591
+ 'name' => array(
5592
+ 'dispatch_key' => 2,
5593
+ 'mandatory' => true,
5594
+ 'value_casei' => 'apple-itunes-app',
5595
+ ),
5596
+ ),
5597
+ 'tag_spec' => array(
5598
+ 'mandatory_parent' => 'head',
5599
+ 'spec_name' => 'meta name=apple-itunes-app',
5600
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5601
+ ),
5602
+ ),
5603
+ array(
5604
+ 'attr_spec_list' => array(
5605
+ 'content' => array(
5606
+ 'mandatory' => true,
5607
+ ),
5608
+ 'name' => array(
5609
+ 'dispatch_key' => 2,
5610
+ 'mandatory' => true,
5611
+ 'value_casei' => 'amp-experiments-opt-in',
5612
+ ),
5613
+ ),
5614
+ 'tag_spec' => array(
5615
+ 'mandatory_parent' => 'head',
5616
+ 'spec_name' => 'meta name=amp-experiments-opt-in',
5617
+ ),
5618
+ ),
5619
+ array(
5620
+ 'attr_spec_list' => array(
5621
+ 'content' => array(
5622
+ 'mandatory' => true,
5623
+ 'value_url' => array(
5624
+ 'allowed_protocol' => array(
5625
+ 'https',
5626
+ ),
5627
+ ),
5628
+ ),
5629
+ 'name' => array(
5630
+ 'dispatch_key' => 2,
5631
+ 'mandatory' => true,
5632
+ 'value_casei' => 'amp-3p-iframe-src',
5633
+ ),
5634
+ ),
5635
+ 'tag_spec' => array(
5636
+ 'mandatory_parent' => 'head',
5637
+ 'spec_name' => 'meta name=amp-3p-iframe-src',
5638
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-ad',
5639
+ ),
5640
+ ),
5641
+ array(
5642
+ 'attr_spec_list' => array(
5643
+ 'content' => array(
5644
+ 'mandatory' => true,
5645
+ ),
5646
+ 'name' => array(
5647
+ 'dispatch_key' => 2,
5648
+ 'mandatory' => true,
5649
+ 'value_casei' => 'amp-experiment-token',
5650
+ ),
5651
+ ),
5652
+ 'tag_spec' => array(
5653
+ 'mandatory_parent' => 'head',
5654
+ 'spec_name' => 'meta name=amp-experiment-token',
5655
+ ),
5656
+ ),
5657
+ array(
5658
+ 'attr_spec_list' => array(
5659
+ 'content' => array(
5660
+ 'mandatory' => true,
5661
+ ),
5662
+ 'name' => array(
5663
+ 'dispatch_key' => 2,
5664
+ 'mandatory' => true,
5665
+ 'value_casei' => 'amp-link-variable-allowed-origin',
5666
+ ),
5667
+ ),
5668
+ 'tag_spec' => array(
5669
+ 'mandatory_parent' => 'head',
5670
+ 'spec_name' => 'meta name=amp-link-variable-allowed-origin',
5671
+ ),
5672
+ ),
5673
+ array(
5674
+ 'attr_spec_list' => array(
5675
+ 'content' => array(
5676
+ 'mandatory' => true,
5677
+ ),
5678
+ 'name' => array(
5679
+ 'dispatch_key' => 2,
5680
+ 'mandatory' => true,
5681
+ 'value_casei' => 'amp-google-client-id-api',
5682
+ ),
5683
+ ),
5684
+ 'tag_spec' => array(
5685
+ 'mandatory_parent' => 'head',
5686
+ 'spec_name' => 'meta name=amp-google-clientid-id-api',
5687
+ ),
5688
+ ),
5689
+ array(
5690
+ 'attr_spec_list' => array(
5691
+ 'name' => array(
5692
+ 'dispatch_key' => 2,
5693
+ 'mandatory' => true,
5694
+ 'value_casei' => 'amp-ad-doubleclick-sra',
5695
+ ),
5696
+ ),
5697
+ 'tag_spec' => array(
5698
+ 'mandatory_parent' => 'head',
5699
+ 'spec_name' => 'meta name=amp-ad-doubleclick-sra',
5700
+ ),
5701
+ ),
5702
+ array(
5703
+ 'attr_spec_list' => array(
5704
+ 'content' => array(),
5705
+ 'itemprop' => array(),
5706
+ 'name' => array(
5707
+ 'blacklisted_value_regex' => '(^|\\s)(amp-.*|amp4ads-.*|apple-itunes-app|content-disposition|revisit-after|viewport)(\\s|$)',
5708
+ ),
5709
+ 'property' => array(),
5710
+ 'scheme' => array(),
5711
+ ),
5712
+ 'tag_spec' => array(
5713
+ 'spec_name' => 'meta name= and content=',
5714
+ ),
5715
+ ),
5716
+ array(
5717
+ 'attr_spec_list' => array(
5718
+ 'content' => array(
5719
+ 'mandatory' => true,
5720
+ 'value_casei' => 'text/html; charset=utf-8',
5721
+ ),
5722
+ 'http-equiv' => array(
5723
+ 'dispatch_key' => 2,
5724
+ 'mandatory' => true,
5725
+ 'value_casei' => 'content-type',
5726
+ ),
5727
+ ),
5728
+ 'tag_spec' => array(
5729
+ 'mandatory_ancestor' => 'head',
5730
+ 'spec_name' => 'meta http-equiv=Content-Type',
5731
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5732
+ ),
5733
+ ),
5734
+ array(
5735
+ 'attr_spec_list' => array(
5736
+ 'content' => array(
5737
+ 'mandatory' => true,
5738
+ ),
5739
+ 'http-equiv' => array(
5740
+ 'dispatch_key' => 2,
5741
+ 'mandatory' => true,
5742
+ 'value_casei' => 'content-language',
5743
+ ),
5744
+ ),
5745
+ 'tag_spec' => array(
5746
+ 'mandatory_ancestor' => 'head',
5747
+ 'spec_name' => 'meta http-equiv=content-language',
5748
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5749
+ ),
5750
+ ),
5751
+ array(
5752
+ 'attr_spec_list' => array(
5753
+ 'content' => array(
5754
+ 'mandatory' => true,
5755
+ ),
5756
+ 'http-equiv' => array(
5757
+ 'dispatch_key' => 2,
5758
+ 'mandatory' => true,
5759
+ 'value_casei' => 'pics-label',
5760
+ ),
5761
+ ),
5762
+ 'tag_spec' => array(
5763
+ 'mandatory_ancestor' => 'head',
5764
+ 'spec_name' => 'meta http-equiv=pics-label',
5765
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5766
+ ),
5767
+ ),
5768
+ array(
5769
+ 'attr_spec_list' => array(
5770
+ 'content' => array(
5771
+ 'mandatory' => true,
5772
+ ),
5773
+ 'http-equiv' => array(
5774
+ 'dispatch_key' => 2,
5775
+ 'mandatory' => true,
5776
+ 'value_casei' => 'imagetoolbar',
5777
+ ),
5778
+ ),
5779
+ 'tag_spec' => array(
5780
+ 'mandatory_ancestor' => 'head',
5781
+ 'spec_name' => 'meta http-equiv=imagetoolbar',
5782
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5783
+ ),
5784
+ ),
5785
+ array(
5786
+ 'attr_spec_list' => array(
5787
+ 'content' => array(
5788
+ 'mandatory' => true,
5789
+ 'value_casei' => 'text/css',
5790
+ ),
5791
+ 'http-equiv' => array(
5792
+ 'dispatch_key' => 2,
5793
+ 'mandatory' => true,
5794
+ 'value_casei' => 'content-style-type',
5795
+ ),
5796
+ ),
5797
+ 'tag_spec' => array(
5798
+ 'mandatory_ancestor' => 'head',
5799
+ 'spec_name' => 'meta http-equiv=Content-Style-Type',
5800
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5801
+ ),
5802
+ ),
5803
+ array(
5804
+ 'attr_spec_list' => array(
5805
+ 'content' => array(
5806
+ 'mandatory' => true,
5807
+ 'value_casei' => 'text/javascript',
5808
+ ),
5809
+ 'http-equiv' => array(
5810
+ 'dispatch_key' => 2,
5811
+ 'mandatory' => true,
5812
+ 'value_casei' => 'content-script-type',
5813
+ ),
5814
+ ),
5815
+ 'tag_spec' => array(
5816
+ 'mandatory_ancestor' => 'head',
5817
+ 'spec_name' => 'meta http-equiv=Content-Script-Type',
5818
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5819
+ ),
5820
+ ),
5821
+ array(
5822
+ 'attr_spec_list' => array(
5823
+ 'content' => array(
5824
+ 'mandatory' => true,
5825
+ ),
5826
+ 'http-equiv' => array(
5827
+ 'dispatch_key' => 2,
5828
+ 'mandatory' => true,
5829
+ 'value_casei' => 'origin-trial',
5830
+ ),
5831
+ ),
5832
+ 'tag_spec' => array(
5833
+ 'mandatory_ancestor' => 'head',
5834
+ 'spec_name' => 'meta http-equiv=origin-trial',
5835
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5836
+ ),
5837
+ ),
5838
+ array(
5839
+ 'attr_spec_list' => array(
5840
+ 'content' => array(
5841
+ 'mandatory' => true,
5842
+ ),
5843
+ 'http-equiv' => array(
5844
+ 'dispatch_key' => 2,
5845
+ 'mandatory' => true,
5846
+ 'value_casei' => 'resource-type',
5847
+ ),
5848
+ ),
5849
+ 'tag_spec' => array(
5850
+ 'mandatory_ancestor' => 'head',
5851
+ 'spec_name' => 'meta http-equiv=resource-type',
5852
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5853
+ ),
5854
+ ),
5855
+ array(
5856
+ 'attr_spec_list' => array(
5857
+ 'content' => array(
5858
+ 'mandatory' => true,
5859
+ 'value_regex_casei' => '(off|on)',
5860
+ ),
5861
+ 'http-equiv' => array(
5862
+ 'dispatch_key' => 2,
5863
+ 'mandatory' => true,
5864
+ 'value_casei' => 'x-dns-prefetch-control',
5865
+ ),
5866
+ ),
5867
+ 'tag_spec' => array(
5868
+ 'mandatory_ancestor' => 'head',
5869
+ 'spec_name' => 'meta http-equiv=x-dns-prefetch-control',
5870
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#html-tags',
5871
+ ),
5872
+ ),
5873
+ array(
5874
+ 'attr_spec_list' => array(
5875
+ 'content' => array(
5876
+ 'mandatory' => true,
5877
+ ),
5878
+ 'name' => array(
5879
+ 'dispatch_key' => 2,
5880
+ 'mandatory' => true,
5881
+ 'value_casei' => 'amp-ad-enable-refresh',
5882
+ ),
5883
+ ),
5884
+ 'tag_spec' => array(
5885
+ 'mandatory_ancestor' => 'head',
5886
+ 'spec_name' => 'meta name=amp-ad-enable-refresh',
5887
+ ),
5888
+ ),
5889
+ array(
5890
+ 'attr_spec_list' => array(
5891
+ 'content' => array(
5892
+ 'mandatory' => true,
5893
+ ),
5894
+ 'name' => array(
5895
+ 'dispatch_key' => 2,
5896
+ 'mandatory' => true,
5897
+ 'value_casei' => 'amp-to-amp-navigation',
5898
+ ),
5899
+ ),
5900
+ 'tag_spec' => array(
5901
+ 'mandatory_parent' => 'head',
5902
+ 'spec_name' => 'meta name=amp-to-amp-navigation',
5903
+ 'unique' => true,
5904
+ ),
5905
+ ),
5906
+ ),
5907
+ 'metadata' => array(
5908
+ array(
5909
+ 'attr_spec_list' => array(
5910
+ 'style' => array(
5911
+ 'blacklisted_value_regex' => '!important',
5912
+ ),
5913
+ 'xml:lang' => array(),
5914
+ 'xml:space' => array(),
5915
+ 'xmlns' => array(),
5916
+ 'xmlns:xlink' => array(),
5917
+ ),
5918
+ 'tag_spec' => array(
5919
+ 'mandatory_ancestor' => 'svg',
5920
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
5921
+ ),
5922
+ ),
5923
+ ),
5924
+ 'meter' => array(
5925
+ array(
5926
+ 'attr_spec_list' => array(
5927
+ 'high' => array(),
5928
+ 'low' => array(),
5929
+ 'max' => array(),
5930
+ 'min' => array(),
5931
+ 'optimum' => array(),
5932
+ 'value' => array(),
5933
+ ),
5934
+ 'tag_spec' => array(),
5935
+ ),
5936
+ ),
5937
+ 'multicol' => array(
5938
+ array(
5939
+ 'attr_spec_list' => array(),
5940
+ 'tag_spec' => array(),
5941
+ ),
5942
+ ),
5943
+ 'nav' => array(
5944
+ array(
5945
+ 'attr_spec_list' => array(),
5946
+ 'tag_spec' => array(),
5947
+ ),
5948
+ array(
5949
+ 'attr_spec_list' => array(
5950
+ 'toolbar' => array(
5951
+ 'dispatch_key' => 1,
5952
+ 'mandatory' => true,
5953
+ ),
5954
+ 'toolbar-target' => array(
5955
+ 'mandatory' => true,
5956
+ ),
5957
+ ),
5958
+ 'tag_spec' => array(
5959
+ 'mandatory_parent' => 'amp-sidebar',
5960
+ 'spec_name' => 'amp-sidebar > nav',
5961
+ ),
5962
+ ),
5963
+ ),
5964
+ 'nextid' => array(
5965
+ array(
5966
+ 'attr_spec_list' => array(),
5967
+ 'tag_spec' => array(),
5968
+ ),
5969
+ ),
5970
+ 'nobr' => array(
5971
+ array(
5972
+ 'attr_spec_list' => array(),
5973
+ 'tag_spec' => array(),
5974
+ ),
5975
+ ),
5976
+ 'noscript' => array(
5977
+ array(
5978
+ 'attr_spec_list' => array(),
5979
+ 'tag_spec' => array(
5980
+ 'mandatory' => true,
5981
+ 'mandatory_parent' => 'head',
5982
+ 'spec_name' => 'noscript enclosure for boilerplate',
5983
+ 'spec_url' => 'https://github.com/ampproject/amphtml/blob/master/spec/amp-boilerplate.md',
5984
+ 'unique' => true,
5985
+ ),
5986
+ ),
5987
+ array(
5988
+ 'attr_spec_list' => array(),
5989
+ 'tag_spec' => array(
5990
+ 'disallowed_ancestor' => array(
5991
+ 'noscript',
5992
+ ),
5993
+ 'mandatory_ancestor' => 'body',
5994
+ ),
5995
+ ),
5996
+ ),
5997
+ 'o:p' => array(
5998
+ array(
5999
+ 'attr_spec_list' => array(),
6000
+ 'tag_spec' => array(),
6001
+ ),
6002
+ ),
6003
+ 'ol' => array(
6004
+ array(
6005
+ 'attr_spec_list' => array(
6006
+ 'reversed' => array(
6007
+ 'value' => '',
6008
+ ),
6009
+ 'start' => array(
6010
+ 'value_regex' => '[0-9]*',
6011
+ ),
6012
+ 'type' => array(
6013
+ 'value_regex' => '[1AaIi]',
6014
+ ),
6015
+ ),
6016
+ 'tag_spec' => array(),
6017
+ ),
6018
+ ),
6019
+ 'optgroup' => array(
6020
+ array(
6021
+ 'attr_spec_list' => array(
6022
+ '[disabled]' => array(),
6023
+ '[label]' => array(),
6024
+ 'disabled' => array(),
6025
+ 'label' => array(),
6026
+ ),
6027
+ 'tag_spec' => array(
6028
+ 'mandatory_parent' => 'select',
6029
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
6030
+ ),
6031
+ ),
6032
+ ),
6033
+ 'option' => array(
6034
+ array(
6035
+ 'attr_spec_list' => array(
6036
+ '[disabled]' => array(),
6037
+ '[label]' => array(),
6038
+ '[selected]' => array(),
6039
+ '[value]' => array(),
6040
+ 'disabled' => array(),
6041
+ 'label' => array(),
6042
+ 'selected' => array(),
6043
+ 'value' => array(),
6044
+ ),
6045
+ 'tag_spec' => array(
6046
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
6047
+ ),
6048
+ ),
6049
+ ),
6050
+ 'output' => array(
6051
+ array(
6052
+ 'attr_spec_list' => array(
6053
+ 'for' => array(),
6054
+ 'form' => array(),
6055
+ 'name' => array(
6056
+ 'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
6057
+ ),
6058
+ ),
6059
+ 'tag_spec' => array(),
6060
+ ),
6061
+ ),
6062
+ 'p' => array(
6063
+ array(
6064
+ 'attr_spec_list' => array(
6065
+ 'align' => array(),
6066
+ ),
6067
+ 'tag_spec' => array(),
6068
+ ),
6069
+ ),
6070
+ 'path' => array(
6071
+ array(
6072
+ 'attr_spec_list' => array(
6073
+ 'alignment-baseline' => array(),
6074
+ 'baseline-shift' => array(),
6075
+ 'clip' => array(),
6076
+ 'clip-path' => array(),
6077
+ 'clip-rule' => array(),
6078
+ 'color' => array(),
6079
+ 'color-interpolation' => array(),
6080
+ 'color-interpolation-filters' => array(),
6081
+ 'color-profile' => array(),
6082
+ 'color-rendering' => array(),
6083
+ 'cursor' => array(),
6084
+ 'd' => array(),
6085
+ 'direction' => array(),
6086
+ 'display' => array(),
6087
+ 'dominant-baseline' => array(),
6088
+ 'enable-background' => array(),
6089
+ 'externalresourcesrequired' => array(),
6090
+ 'fill' => array(),
6091
+ 'fill-opacity' => array(),
6092
+ 'fill-rule' => array(),
6093
+ 'filter' => array(),
6094
+ 'flood-color' => array(),
6095
+ 'flood-opacity' => array(),
6096
+ 'font-family' => array(),
6097
+ 'font-size' => array(),
6098
+ 'font-size-adjust' => array(),
6099
+ 'font-stretch' => array(),
6100
+ 'font-style' => array(),
6101
+ 'font-variant' => array(),
6102
+ 'font-weight' => array(),
6103
+ 'glyph-orientation-horizontal' => array(),
6104
+ 'glyph-orientation-vertical' => array(),
6105
+ 'image-rendering' => array(),
6106
+ 'kerning' => array(),
6107
+ 'letter-spacing' => array(),
6108
+ 'lighting-color' => array(),
6109
+ 'marker-end' => array(),
6110
+ 'marker-mid' => array(),
6111
+ 'marker-start' => array(),
6112
+ 'mask' => array(),
6113
+ 'opacity' => array(),
6114
+ 'overflow' => array(),
6115
+ 'pathlength' => array(),
6116
+ 'pointer-events' => array(),
6117
+ 'requiredextensions' => array(),
6118
+ 'requiredfeatures' => array(),
6119
+ 'shape-rendering' => array(),
6120
+ 'sketch:type' => array(),
6121
+ 'stop-color' => array(),
6122
+ 'stop-opacity' => array(),
6123
+ 'stroke' => array(),
6124
+ 'stroke-dasharray' => array(),
6125
+ 'stroke-dashoffset' => array(),
6126
+ 'stroke-linecap' => array(),
6127
+ 'stroke-linejoin' => array(),
6128
+ 'stroke-miterlimit' => array(),
6129
+ 'stroke-opacity' => array(),
6130
+ 'stroke-width' => array(),
6131
+ 'style' => array(
6132
+ 'blacklisted_value_regex' => '!important',
6133
+ ),
6134
+ 'systemlanguage' => array(),
6135
+ 'text-anchor' => array(),
6136
+ 'text-decoration' => array(),
6137
+ 'text-rendering' => array(),
6138
+ 'transform' => array(),
6139
+ 'unicode-bidi' => array(),
6140
+ 'vector-effect' => array(),
6141
+ 'visibility' => array(),
6142
+ 'word-spacing' => array(),
6143
+ 'writing-mode' => array(),
6144
+ 'xml:lang' => array(),
6145
+ 'xml:space' => array(),
6146
+ 'xmlns' => array(),
6147
+ 'xmlns:xlink' => array(),
6148
+ ),
6149
+ 'tag_spec' => array(
6150
+ 'mandatory_ancestor' => 'svg',
6151
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
6152
+ ),
6153
+ ),
6154
+ ),
6155
+ 'pattern' => array(
6156
+ array(
6157
+ 'attr_spec_list' => array(
6158
+ 'alignment-baseline' => array(),
6159
+ 'baseline-shift' => array(),
6160
+ 'clip' => array(),
6161
+ 'clip-path' => array(),
6162
+ 'clip-rule' => array(),
6163
+ 'color' => array(),
6164
+ 'color-interpolation' => array(),
6165
+ 'color-interpolation-filters' => array(),
6166
+ 'color-profile' => array(),
6167
+ 'color-rendering' => array(),
6168
+ 'cursor' => array(),
6169
+ 'direction' => array(),
6170
+ 'display' => array(),
6171
+ 'dominant-baseline' => array(),
6172
+ 'enable-background' => array(),
6173
+ 'externalresourcesrequired' => array(),
6174
+ 'fill' => array(),
6175
+ 'fill-opacity' => array(),
6176
+ 'fill-rule' => array(),
6177
+ 'filter' => array(),
6178
+ 'flood-color' => array(),
6179
+ 'flood-opacity' => array(),
6180
+ 'font-family' => array(),
6181
+ 'font-size' => array(),
6182
+ 'font-size-adjust' => array(),
6183
+ 'font-stretch' => array(),
6184
+ 'font-style' => array(),
6185
+ 'font-variant' => array(),
6186
+ 'font-weight' => array(),
6187
+ 'glyph-orientation-horizontal' => array(),
6188
+ 'glyph-orientation-vertical' => array(),
6189
+ 'height' => array(),
6190
+ 'image-rendering' => array(),
6191
+ 'kerning' => array(),
6192
+ 'letter-spacing' => array(),
6193
+ 'lighting-color' => array(),
6194
+ 'marker-end' => array(),
6195
+ 'marker-mid' => array(),
6196
+ 'marker-start' => array(),
6197
+ 'mask' => array(),
6198
+ 'opacity' => array(),
6199
+ 'overflow' => array(),
6200
+ 'patterncontentunits' => array(),
6201
+ 'patterntransform' => array(),
6202
+ 'patternunits' => array(),
6203
+ 'pointer-events' => array(),
6204
+ 'preserveaspectratio' => array(),
6205
+ 'requiredextensions' => array(),
6206
+ 'requiredfeatures' => array(),
6207
+ 'shape-rendering' => array(),
6208
+ 'stop-color' => array(),
6209
+ 'stop-opacity' => array(),
6210
+ 'stroke' => array(),
6211
+ 'stroke-dasharray' => array(),
6212
+ 'stroke-dashoffset' => array(),
6213
+ 'stroke-linecap' => array(),
6214
+ 'stroke-linejoin' => array(),
6215
+ 'stroke-miterlimit' => array(),
6216
+ 'stroke-opacity' => array(),
6217
+ 'stroke-width' => array(),
6218
+ 'style' => array(
6219
+ 'blacklisted_value_regex' => '!important',
6220
+ ),
6221
+ 'systemlanguage' => array(),
6222
+ 'text-anchor' => array(),
6223
+ 'text-decoration' => array(),
6224
+ 'text-rendering' => array(),
6225
+ 'unicode-bidi' => array(),
6226
+ 'vector-effect' => array(),
6227
+ 'viewbox' => array(),
6228
+ 'visibility' => array(),
6229
+ 'width' => array(),
6230
+ 'word-spacing' => array(),
6231
+ 'writing-mode' => array(),
6232
+ 'x' => array(),
6233
+ 'xlink:actuate' => array(),
6234
+ 'xlink:arcrole' => array(),
6235
+ 'xlink:href' => array(
6236
+ 'alternative_names' => array(
6237
+ 'href',
6238
+ ),
6239
+ 'value_url' => array(
6240
+ 'allow_empty' => false,
6241
+ 'allow_relative' => true,
6242
+ 'allowed_protocol' => array(
6243
+ 'http',
6244
+ 'https',
6245
+ ),
6246
+ ),
6247
+ ),
6248
+ 'xlink:role' => array(),
6249
+ 'xlink:show' => array(),
6250
+ 'xlink:title' => array(),
6251
+ 'xlink:type' => array(),
6252
+ 'xml:lang' => array(),
6253
+ 'xml:space' => array(),
6254
+ 'xmlns' => array(),
6255
+ 'xmlns:xlink' => array(),
6256
+ 'y' => array(),
6257
+ ),
6258
+ 'tag_spec' => array(
6259
+ 'mandatory_ancestor' => 'svg',
6260
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
6261
+ ),
6262
+ ),
6263
+ ),
6264
+ 'polygon' => array(
6265
+ array(
6266
+ 'attr_spec_list' => array(
6267
+ 'alignment-baseline' => array(),
6268
+ 'baseline-shift' => array(),
6269
+ 'clip' => array(),
6270
+ 'clip-path' => array(),
6271
+ 'clip-rule' => array(),
6272
+ 'color' => array(),
6273
+ 'color-interpolation' => array(),
6274
+ 'color-interpolation-filters' => array(),
6275
+ 'color-profile' => array(),
6276
+ 'color-rendering' => array(),
6277
+ 'cursor' => array(),
6278
+ 'direction' => array(),
6279
+ 'display' => array(),
6280
+ 'dominant-baseline' => array(),
6281
+ 'enable-background' => array(),
6282
+ 'externalresourcesrequired' => array(),
6283
+ 'fill' => array(),
6284
+ 'fill-opacity' => array(),
6285
+ 'fill-rule' => array(),
6286
+ 'filter' => array(),
6287
+ 'flood-color' => array(),
6288
+ 'flood-opacity' => array(),
6289
+ 'font-family' => array(),
6290
+ 'font-size' => array(),
6291
+ 'font-size-adjust' => array(),
6292
+ 'font-stretch' => array(),
6293
+ 'font-style' => array(),
6294
+ 'font-variant' => array(),
6295
+ 'font-weight' => array(),
6296
+ 'glyph-orientation-horizontal' => array(),
6297
+ 'glyph-orientation-vertical' => array(),
6298
+ 'image-rendering' => array(),
6299
+ 'kerning' => array(),
6300
+ 'letter-spacing' => array(),
6301
+ 'lighting-color' => array(),
6302
+ 'marker-end' => array(),
6303
+ 'marker-mid' => array(),
6304
+ 'marker-start' => array(),
6305
+ 'mask' => array(),
6306
+ 'opacity' => array(),
6307
+ 'overflow' => array(),
6308
+ 'pointer-events' => array(),
6309
+ 'points' => array(),
6310
+ 'requiredextensions' => array(),
6311
+ 'requiredfeatures' => array(),
6312
+ 'shape-rendering' => array(),
6313
+ 'sketch:type' => array(),
6314
+ 'stop-color' => array(),
6315
+ 'stop-opacity' => array(),
6316
+ 'stroke' => array(),
6317
+ 'stroke-dasharray' => array(),
6318
+ 'stroke-dashoffset' => array(),
6319
+ 'stroke-linecap' => array(),
6320
+ 'stroke-linejoin' => array(),
6321
+ 'stroke-miterlimit' => array(),
6322
+ 'stroke-opacity' => array(),
6323
+ 'stroke-width' => array(),
6324
+ 'style' => array(
6325
+ 'blacklisted_value_regex' => '!important',
6326
+ ),
6327
+ 'systemlanguage' => array(),
6328
+ 'text-anchor' => array(),
6329
+ 'text-decoration' => array(),
6330
+ 'text-rendering' => array(),
6331
+ 'transform' => array(),
6332
+ 'unicode-bidi' => array(),
6333
+ 'vector-effect' => array(),
6334
+ 'visibility' => array(),
6335
+ 'word-spacing' => array(),
6336
+ 'writing-mode' => array(),
6337
+ 'xml:lang' => array(),
6338
+ 'xml:space' => array(),
6339
+ 'xmlns' => array(),
6340
+ 'xmlns:xlink' => array(),
6341
+ ),
6342
+ 'tag_spec' => array(
6343
+ 'mandatory_ancestor' => 'svg',
6344
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
6345
+ ),
6346
+ ),
6347
+ ),
6348
+ 'polyline' => array(
6349
+ array(
6350
+ 'attr_spec_list' => array(
6351
+ 'alignment-baseline' => array(),
6352
+ 'baseline-shift' => array(),
6353
+ 'clip' => array(),
6354
+ 'clip-path' => array(),
6355
+ 'clip-rule' => array(),
6356
+ 'color' => array(),
6357
+ 'color-interpolation' => array(),
6358
+ 'color-interpolation-filters' => array(),
6359
+ 'color-profile' => array(),
6360
+ 'color-rendering' => array(),
6361
+ 'cursor' => array(),
6362
+ 'direction' => array(),
6363
+ 'display' => array(),
6364
+ 'dominant-baseline' => array(),
6365
+ 'enable-background' => array(),
6366
+ 'externalresourcesrequired' => array(),
6367
+ 'fill' => array(),
6368
+ 'fill-opacity' => array(),
6369
+ 'fill-rule' => array(),
6370
+ 'filter' => array(),
6371
+ 'flood-color' => array(),
6372
+ 'flood-opacity' => array(),
6373
+ 'font-family' => array(),
6374
+ 'font-size' => array(),
6375
+ 'font-size-adjust' => array(),
6376
+ 'font-stretch' => array(),
6377
+ 'font-style' => array(),
6378
+ 'font-variant' => array(),
6379
+ 'font-weight' => array(),
6380
+ 'glyph-orientation-horizontal' => array(),
6381
+ 'glyph-orientation-vertical' => array(),
6382
+ 'image-rendering' => array(),
6383
+ 'kerning' => array(),
6384
+ 'letter-spacing' => array(),
6385
+ 'lighting-color' => array(),
6386
+ 'marker-end' => array(),
6387
+ 'marker-mid' => array(),
6388
+ 'marker-start' => array(),
6389
+ 'mask' => array(),
6390
+ 'opacity' => array(),
6391
+ 'overflow' => array(),
6392
+ 'pointer-events' => array(),
6393
+ 'points' => array(),
6394
+ 'requiredextensions' => array(),
6395
+ 'requiredfeatures' => array(),
6396
+ 'shape-rendering' => array(),
6397
+ 'sketch:type' => array(),
6398
+ 'stop-color' => array(),
6399
+ 'stop-opacity' => array(),
6400
+ 'stroke' => array(),
6401
+ 'stroke-dasharray' => array(),
6402
+ 'stroke-dashoffset' => array(),
6403
+ 'stroke-linecap' => array(),
6404
+ 'stroke-linejoin' => array(),
6405
+ 'stroke-miterlimit' => array(),
6406
+ 'stroke-opacity' => array(),
6407
+ 'stroke-width' => array(),
6408
+ 'style' => array(
6409
+ 'blacklisted_value_regex' => '!important',
6410
+ ),
6411
+ 'systemlanguage' => array(),
6412
+ 'text-anchor' => array(),
6413
+ 'text-decoration' => array(),
6414
+ 'text-rendering' => array(),
6415
+ 'transform' => array(),
6416
+ 'unicode-bidi' => array(),
6417
+ 'vector-effect' => array(),
6418
+ 'visibility' => array(),
6419
+ 'word-spacing' => array(),
6420
+ 'writing-mode' => array(),
6421
+ 'xml:lang' => array(),
6422
+ 'xml:space' => array(),
6423
+ 'xmlns' => array(),
6424
+ 'xmlns:xlink' => array(),
6425
+ ),
6426
+ 'tag_spec' => array(
6427
+ 'mandatory_ancestor' => 'svg',
6428
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
6429
+ ),
6430
+ ),
6431
+ ),
6432
+ 'pre' => array(
6433
+ array(
6434
+ 'attr_spec_list' => array(),
6435
+ 'tag_spec' => array(),
6436
+ ),
6437
+ ),
6438
+ 'progress' => array(
6439
+ array(
6440
+ 'attr_spec_list' => array(
6441
+ 'max' => array(),
6442
+ 'value' => array(),
6443
+ ),
6444
+ 'tag_spec' => array(),
6445
+ ),
6446
+ ),
6447
+ 'q' => array(
6448
+ array(
6449
+ 'attr_spec_list' => array(
6450
+ 'cite' => array(
6451
+ 'blacklisted_value_regex' => '__amp_source_origin',
6452
+ 'value_url' => array(
6453
+ 'allow_empty' => true,
6454
+ 'allow_relative' => true,
6455
+ 'allowed_protocol' => array(
6456
+ 'http',
6457
+ 'https',
6458
+ ),
6459
+ ),
6460
+ ),
6461
+ ),
6462
+ 'tag_spec' => array(),
6463
+ ),
6464
+ ),
6465
+ 'radialgradient' => array(
6466
+ array(
6467
+ 'attr_spec_list' => array(
6468
+ 'alignment-baseline' => array(),
6469
+ 'baseline-shift' => array(),
6470
+ 'clip' => array(),
6471
+ 'clip-path' => array(),
6472
+ 'clip-rule' => array(),
6473
+ 'color' => array(),
6474
+ 'color-interpolation' => array(),
6475
+ 'color-interpolation-filters' => array(),
6476
+ 'color-profile' => array(),
6477
+ 'color-rendering' => array(),
6478
+ 'cursor' => array(),
6479
+ 'cx' => array(),
6480
+ 'cy' => array(),
6481
+ 'direction' => array(),
6482
+ 'display' => array(),
6483
+ 'dominant-baseline' => array(),
6484
+ 'enable-background' => array(),
6485
+ 'externalresourcesrequired' => array(),
6486
+ 'fill' => array(),
6487
+ 'fill-opacity' => array(),
6488
+ 'fill-rule' => array(),
6489
+ 'filter' => array(),
6490
+ 'flood-color' => array(),
6491
+ 'flood-opacity' => array(),
6492
+ 'font-family' => array(),
6493
+ 'font-size' => array(),
6494
+ 'font-size-adjust' => array(),
6495
+ 'font-stretch' => array(),
6496
+ 'font-style' => array(),
6497
+ 'font-variant' => array(),
6498
+ 'font-weight' => array(),
6499
+ 'fr' => array(),
6500
+ 'fx' => array(),
6501
+ 'fy' => array(),
6502
+ 'glyph-orientation-horizontal' => array(),
6503
+ 'glyph-orientation-vertical' => array(),
6504
+ 'gradienttransform' => array(),
6505
+ 'gradientunits' => array(),
6506
+ 'image-rendering' => array(),
6507
+ 'kerning' => array(),
6508
+ 'letter-spacing' => array(),
6509
+ 'lighting-color' => array(),
6510
+ 'marker-end' => array(),
6511
+ 'marker-mid' => array(),
6512
+ 'marker-start' => array(),
6513
+ 'mask' => array(),
6514
+ 'opacity' => array(),
6515
+ 'overflow' => array(),
6516
+ 'pointer-events' => array(),
6517
+ 'r' => array(),
6518
+ 'shape-rendering' => array(),
6519
+ 'spreadmethod' => array(),
6520
+ 'stop-color' => array(),
6521
+ 'stop-opacity' => array(),
6522
+ 'stroke' => array(),
6523
+ 'stroke-dasharray' => array(),
6524
+ 'stroke-dashoffset' => array(),
6525
+ 'stroke-linecap' => array(),
6526
+ 'stroke-linejoin' => array(),
6527
+ 'stroke-miterlimit' => array(),
6528
+ 'stroke-opacity' => array(),
6529
+ 'stroke-width' => array(),
6530
+ 'style' => array(
6531
+ 'blacklisted_value_regex' => '!important',
6532
+ ),
6533
+ 'text-anchor' => array(),
6534
+ 'text-decoration' => array(),
6535
+ 'text-rendering' => array(),
6536
+ 'unicode-bidi' => array(),
6537
+ 'vector-effect' => array(),
6538
+ 'visibility' => array(),
6539
+ 'word-spacing' => array(),
6540
+ 'writing-mode' => array(),
6541
+ 'xlink:actuate' => array(),
6542
+ 'xlink:arcrole' => array(),
6543
+ 'xlink:href' => array(
6544
+ 'alternative_names' => array(
6545
+ 'href',
6546
+ ),
6547
+ 'value_url' => array(
6548
+ 'allow_empty' => false,
6549
+ 'allow_relative' => true,
6550
+ 'allowed_protocol' => array(
6551
+ 'http',
6552
+ 'https',
6553
+ ),
6554
+ ),
6555
+ ),
6556
+ 'xlink:role' => array(),
6557
+ 'xlink:show' => array(),
6558
+ 'xlink:title' => array(),
6559
+ 'xlink:type' => array(),
6560
+ 'xml:lang' => array(),
6561
+ 'xml:space' => array(),
6562
+ 'xmlns' => array(),
6563
+ 'xmlns:xlink' => array(),
6564
+ ),
6565
+ 'tag_spec' => array(
6566
+ 'mandatory_ancestor' => 'svg',
6567
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
6568
+ ),
6569
+ ),
6570
+ ),
6571
+ 'rb' => array(
6572
+ array(
6573
+ 'attr_spec_list' => array(),
6574
+ 'tag_spec' => array(),
6575
+ ),
6576
+ ),
6577
+ 'rect' => array(
6578
+ array(
6579
+ 'attr_spec_list' => array(
6580
+ 'alignment-baseline' => array(),
6581
+ 'baseline-shift' => array(),
6582
+ 'clip' => array(),
6583
+ 'clip-path' => array(),
6584
+ 'clip-rule' => array(),
6585
+ 'color' => array(),
6586
+ 'color-interpolation' => array(),
6587
+ 'color-interpolation-filters' => array(),
6588
+ 'color-profile' => array(),
6589
+ 'color-rendering' => array(),
6590
+ 'cursor' => array(),
6591
+ 'direction' => array(),
6592
+ 'display' => array(),
6593
+ 'dominant-baseline' => array(),
6594
+ 'enable-background' => array(),
6595
+ 'externalresourcesrequired' => array(),
6596
+ 'fill' => array(),
6597
+ 'fill-opacity' => array(),
6598
+ 'fill-rule' => array(),
6599
+ 'filter' => array(),
6600
+ 'flood-color' => array(),
6601
+ 'flood-opacity' => array(),
6602
+ 'font-family' => array(),
6603
+ 'font-size' => array(),
6604
+ 'font-size-adjust' => array(),
6605
+ 'font-stretch' => array(),
6606
+ 'font-style' => array(),
6607
+ 'font-variant' => array(),
6608
+ 'font-weight' => array(),
6609
+ 'glyph-orientation-horizontal' => array(),
6610
+ 'glyph-orientation-vertical' => array(),
6611
+ 'height' => array(),
6612
+ 'image-rendering' => array(),
6613
+ 'kerning' => array(),
6614
+ 'letter-spacing' => array(),
6615
+ 'lighting-color' => array(),
6616
+ 'marker-end' => array(),
6617
+ 'marker-mid' => array(),
6618
+ 'marker-start' => array(),
6619
+ 'mask' => array(),
6620
+ 'opacity' => array(),
6621
+ 'overflow' => array(),
6622
+ 'pointer-events' => array(),
6623
+ 'requiredextensions' => array(),
6624
+ 'requiredfeatures' => array(),
6625
+ 'rx' => array(),
6626
+ 'ry' => array(),
6627
+ 'shape-rendering' => array(),
6628
+ 'sketch:type' => array(),
6629
+ 'stop-color' => array(),
6630
+ 'stop-opacity' => array(),
6631
+ 'stroke' => array(),
6632
+ 'stroke-dasharray' => array(),
6633
+ 'stroke-dashoffset' => array(),
6634
+ 'stroke-linecap' => array(),
6635
+ 'stroke-linejoin' => array(),
6636
+ 'stroke-miterlimit' => array(),
6637
+ 'stroke-opacity' => array(),
6638
+ 'stroke-width' => array(),
6639
+ 'style' => array(
6640
+ 'blacklisted_value_regex' => '!important',
6641
+ ),
6642
+ 'systemlanguage' => array(),
6643
+ 'text-anchor' => array(),
6644
+ 'text-decoration' => array(),
6645
+ 'text-rendering' => array(),
6646
+ 'transform' => array(),
6647
+ 'unicode-bidi' => array(),
6648
+ 'vector-effect' => array(),
6649
+ 'visibility' => array(),
6650
+ 'width' => array(),
6651
+ 'word-spacing' => array(),
6652
+ 'writing-mode' => array(),
6653
+ 'x' => array(),
6654
+ 'xml:lang' => array(),
6655
+ 'xml:space' => array(),
6656
+ 'xmlns' => array(),
6657
+ 'xmlns:xlink' => array(),
6658
+ 'y' => array(),
6659
+ ),
6660
+ 'tag_spec' => array(
6661
+ 'mandatory_ancestor' => 'svg',
6662
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
6663
+ ),
6664
+ ),
6665
+ ),
6666
+ 'rp' => array(
6667
+ array(
6668
+ 'attr_spec_list' => array(),
6669
+ 'tag_spec' => array(),
6670
+ ),
6671
+ ),
6672
+ 'rt' => array(
6673
+ array(
6674
+ 'attr_spec_list' => array(),
6675
+ 'tag_spec' => array(),
6676
+ ),
6677
+ ),
6678
+ 'rtc' => array(
6679
+ array(
6680
+ 'attr_spec_list' => array(),
6681
+ 'tag_spec' => array(),
6682
+ ),
6683
+ ),
6684
+ 'ruby' => array(
6685
+ array(
6686
+ 'attr_spec_list' => array(),
6687
+ 'tag_spec' => array(),
6688
+ ),
6689
+ ),
6690
+ 's' => array(
6691
+ array(
6692
+ 'attr_spec_list' => array(),
6693
+ 'tag_spec' => array(),
6694
+ ),
6695
+ ),
6696
+ 'samp' => array(
6697
+ array(
6698
+ 'attr_spec_list' => array(),
6699
+ 'tag_spec' => array(),
6700
+ ),
6701
+ ),
6702
+ 'script' => array(
6703
+ array(
6704
+ 'attr_spec_list' => array(
6705
+ 'async' => array(
6706
+ 'mandatory' => true,
6707
+ 'value' => '',
6708
+ ),
6709
+ 'nonce' => array(),
6710
+ 'src' => array(
6711
+ 'dispatch_key' => 2,
6712
+ 'mandatory' => true,
6713
+ 'value' => 'https://cdn.ampproject.org/v0.js',
6714
+ ),
6715
+ 'type' => array(
6716
+ 'value_casei' => 'text/javascript',
6717
+ ),
6718
+ ),
6719
+ 'cdata' => array(
6720
+ 'blacklisted_cdata_regex' => array(
6721
+ 'error_message' => 'contents',
6722
+ 'regex' => '.',
6723
+ ),
6724
+ ),
6725
+ 'tag_spec' => array(
6726
+ 'mandatory' => true,
6727
+ 'mandatory_parent' => 'head',
6728
+ 'spec_name' => 'amphtml engine v0.js script',
6729
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#required-markup',
6730
+ 'unique' => true,
6731
+ ),
6732
+ ),
6733
+ array(
6734
+ 'attr_spec_list' => array(
6735
+ 'nonce' => array(),
6736
+ 'type' => array(
6737
+ 'dispatch_key' => 2,
6738
+ 'mandatory' => true,
6739
+ 'value_casei' => 'application/ld+json',
6740
+ ),
6741
+ ),
6742
+ 'cdata' => array(
6743
+ 'blacklisted_cdata_regex' => array(
6744
+ 'error_message' => 'html comments',
6745
+ 'regex' => '<!--',
6746
+ ),
6747
+ ),
6748
+ 'tag_spec' => array(
6749
+ 'spec_name' => 'script type=application/ld+json',
6750
+ ),
6751
+ ),
6752
+ array(
6753
+ 'attr_spec_list' => array(
6754
+ 'id' => array(
6755
+ 'dispatch_key' => 2,
6756
+ 'mandatory' => true,
6757
+ 'value_casei' => 'amp-rtc',
6758
+ ),
6759
+ 'nonce' => array(),
6760
+ 'type' => array(
6761
+ 'mandatory' => true,
6762
+ 'value_casei' => 'application/json',
6763
+ ),
6764
+ ),
6765
+ 'cdata' => array(
6766
+ 'blacklisted_cdata_regex' => array(
6767
+ 'error_message' => 'html comments',
6768
+ 'regex' => '<!--',
6769
+ ),
6770
+ ),
6771
+ 'tag_spec' => array(
6772
+ 'mandatory_parent' => 'head',
6773
+ 'spec_name' => 'script id=amp-rtc',
6774
+ 'unique' => true,
6775
+ ),
6776
+ ),
6777
+ array(
6778
+ 'attr_spec_list' => array(
6779
+ 'type' => array(
6780
+ 'dispatch_key' => 3,
6781
+ 'mandatory' => true,
6782
+ 'value_casei' => 'application/json',
6783
+ ),
6784
+ ),
6785
+ 'cdata' => array(
6786
+ 'blacklisted_cdata_regex' => array(
6787
+ 'error_message' => 'html comments',
6788
+ 'regex' => '<!--',
6789
+ ),
6790
+ ),
6791
+ 'tag_spec' => array(
6792
+ 'mandatory_parent' => 'amp-ima-video',
6793
+ 'spec_name' => 'amp-ima-video > script[type=application/json]',
6794
+ ),
6795
+ ),
6796
+ array(
6797
+ 'attr_spec_list' => array(
6798
+ 'async' => array(
6799
+ 'mandatory' => true,
6800
+ 'value' => '',
6801
+ ),
6802
+ 'nonce' => array(),
6803
+ 'type' => array(
6804
+ 'value_casei' => 'text/javascript',
6805
+ ),
6806
+ ),
6807
+ 'tag_spec' => array(
6808
+ 'extension_spec' => array(
6809
+ 'allowed_versions' => array(
6810
+ '0.1',
6811
+ 'latest',
6812
+ ),
6813
+ 'name' => 'amp-3q-player',
6814
+ ),
6815
+ ),
6816
+ ),
6817
+ array(
6818
+ 'attr_spec_list' => array(
6819
+ 'async' => array(
6820
+ 'mandatory' => true,
6821
+ 'value' => '',
6822
+ ),
6823
+ 'nonce' => array(),
6824
+ 'type' => array(
6825
+ 'value_casei' => 'text/javascript',
6826
+ ),
6827
+ ),
6828
+ 'tag_spec' => array(
6829
+ 'extension_spec' => array(
6830
+ 'allowed_versions' => array(
6831
+ '0.1',
6832
+ 'latest',
6833
+ ),
6834
+ 'name' => 'amp-access-laterpay',
6835
+ 'requires_usage' => 3,
6836
+ ),
6837
+ 'requires_extension' => array(
6838
+ 'amp-access',
6839
+ ),
6840
+ ),
6841
+ ),
6842
+ array(
6843
+ 'attr_spec_list' => array(
6844
+ 'async' => array(
6845
+ 'mandatory' => true,
6846
+ 'value' => '',
6847
+ ),
6848
+ 'nonce' => array(),
6849
+ 'type' => array(
6850
+ 'value_casei' => 'text/javascript',
6851
+ ),
6852
+ ),
6853
+ 'tag_spec' => array(
6854
+ 'extension_spec' => array(
6855
+ 'allowed_versions' => array(
6856
+ '0.1',
6857
+ 'latest',
6858
+ ),
6859
+ 'name' => 'amp-access-scroll',
6860
+ 'requires_usage' => 3,
6861
+ ),
6862
+ 'requires_extension' => array(
6863
+ 'amp-access',
6864
+ ),
6865
+ ),
6866
+ ),
6867
+ array(
6868
+ 'attr_spec_list' => array(
6869
+ 'async' => array(
6870
+ 'mandatory' => true,
6871
+ 'value' => '',
6872
+ ),
6873
+ 'nonce' => array(),
6874
+ 'type' => array(
6875
+ 'value_casei' => 'text/javascript',
6876
+ ),
6877
+ ),
6878
+ 'tag_spec' => array(
6879
+ 'extension_spec' => array(
6880
+ 'allowed_versions' => array(
6881
+ '0.1',
6882
+ 'latest',
6883
+ ),
6884
+ 'deprecated_allow_duplicates' => true,
6885
+ 'name' => 'amp-access',
6886
+ 'requires_usage' => 2,
6887
+ ),
6888
+ ),
6889
+ ),
6890
+ array(
6891
+ 'attr_spec_list' => array(
6892
+ 'id' => array(
6893
+ 'dispatch_key' => 2,
6894
+ 'mandatory' => true,
6895
+ 'value' => 'amp-access',
6896
+ ),
6897
+ 'nonce' => array(),
6898
+ 'type' => array(
6899
+ 'mandatory' => true,
6900
+ 'value_casei' => 'application/json',
6901
+ ),
6902
+ ),
6903
+ 'cdata' => array(
6904
+ 'blacklisted_cdata_regex' => array(
6905
+ 'error_message' => 'html comments',
6906
+ 'regex' => '<!--',
6907
+ ),
6908
+ ),
6909
+ 'tag_spec' => array(
6910
+ 'mandatory_parent' => 'head',
6911
+ 'requires_extension' => array(
6912
+ 'amp-access',
6913
+ 'amp-analytics',
6914
+ ),
6915
+ 'spec_name' => 'amp-access extension .json script',
6916
+ 'unique' => true,
6917
+ ),
6918
+ ),
6919
+ array(
6920
+ 'attr_spec_list' => array(
6921
+ 'async' => array(
6922
+ 'mandatory' => true,
6923
+ 'value' => '',
6924
+ ),
6925
+ 'nonce' => array(),
6926
+ 'type' => array(
6927
+ 'value_casei' => 'text/javascript',
6928
+ ),
6929
+ ),
6930
+ 'tag_spec' => array(
6931
+ 'extension_spec' => array(
6932
+ 'allowed_versions' => array(
6933
+ '0.1',
6934
+ 'latest',
6935
+ ),
6936
+ 'deprecated_allow_duplicates' => true,
6937
+ 'name' => 'amp-accordion',
6938
+ 'requires_usage' => 2,
6939
+ ),
6940
+ ),
6941
+ ),
6942
+ array(
6943
+ 'attr_spec_list' => array(
6944
+ 'async' => array(
6945
+ 'mandatory' => true,
6946
+ 'value' => '',
6947
+ ),
6948
+ 'nonce' => array(),
6949
+ 'type' => array(
6950
+ 'value_casei' => 'text/javascript',
6951
+ ),
6952
+ ),
6953
+ 'tag_spec' => array(
6954
+ 'extension_spec' => array(
6955
+ 'allowed_versions' => array(
6956
+ '0.1',
6957
+ 'latest',
6958
+ ),
6959
+ 'deprecated_allow_duplicates' => true,
6960
+ 'name' => 'amp-ad',
6961
+ 'requires_usage' => 2,
6962
+ ),
6963
+ 'spec_name' => 'amp-ad extension .js script',
6964
+ ),
6965
+ ),
6966
+ array(
6967
+ 'attr_spec_list' => array(
6968
+ 'async' => array(
6969
+ 'mandatory' => true,
6970
+ 'value' => '',
6971
+ ),
6972
+ 'nonce' => array(),
6973
+ 'type' => array(
6974
+ 'value_casei' => 'text/javascript',
6975
+ ),
6976
+ ),
6977
+ 'tag_spec' => array(
6978
+ 'extension_spec' => array(
6979
+ 'allowed_versions' => array(
6980
+ '0.1',
6981
+ 'latest',
6982
+ ),
6983
+ 'deprecated_allow_duplicates' => true,
6984
+ 'name' => 'amp-analytics',
6985
+ 'requires_usage' => 2,
6986
+ ),
6987
+ ),
6988
+ ),
6989
+ array(
6990
+ 'attr_spec_list' => array(
6991
+ 'nonce' => array(),
6992
+ 'type' => array(
6993
+ 'dispatch_key' => 3,
6994
+ 'mandatory' => true,
6995
+ 'value_casei' => 'application/json',
6996
+ ),
6997
+ ),
6998
+ 'cdata' => array(
6999
+ 'blacklisted_cdata_regex' => array(
7000
+ 'error_message' => 'html comments',
7001
+ 'regex' => '<!--',
7002
+ ),
7003
+ ),
7004
+ 'tag_spec' => array(
7005
+ 'mandatory_parent' => 'amp-analytics',
7006
+ 'requires_extension' => array(
7007
+ 'amp-analytics',
7008
+ ),
7009
+ 'spec_name' => 'amp-analytics extension .json script',
7010
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-analytics',
7011
+ ),
7012
+ ),
7013
+ array(
7014
+ 'attr_spec_list' => array(
7015
+ 'async' => array(
7016
+ 'mandatory' => true,
7017
+ 'value' => '',
7018
+ ),
7019
+ 'nonce' => array(),
7020
+ 'type' => array(
7021
+ 'value_casei' => 'text/javascript',
7022
+ ),
7023
+ ),
7024
+ 'tag_spec' => array(
7025
+ 'extension_spec' => array(
7026
+ 'allowed_versions' => array(
7027
+ '0.1',
7028
+ 'latest',
7029
+ ),
7030
+ 'deprecated_allow_duplicates' => true,
7031
+ 'name' => 'amp-anim',
7032
+ 'requires_usage' => 2,
7033
+ ),
7034
+ ),
7035
+ ),
7036
+ array(
7037
+ 'attr_spec_list' => array(
7038
+ 'async' => array(
7039
+ 'mandatory' => true,
7040
+ 'value' => '',
7041
+ ),
7042
+ 'nonce' => array(),
7043
+ 'type' => array(
7044
+ 'value_casei' => 'text/javascript',
7045
+ ),
7046
+ ),
7047
+ 'tag_spec' => array(
7048
+ 'extension_spec' => array(
7049
+ 'allowed_versions' => array(
7050
+ '0.1',
7051
+ 'latest',
7052
+ ),
7053
+ 'name' => 'amp-animation',
7054
+ ),
7055
+ ),
7056
+ ),
7057
+ array(
7058
+ 'attr_spec_list' => array(
7059
+ 'nonce' => array(),
7060
+ 'type' => array(
7061
+ 'dispatch_key' => 3,
7062
+ 'mandatory' => true,
7063
+ 'value_casei' => 'application/json',
7064
+ ),
7065
+ ),
7066
+ 'cdata' => array(
7067
+ 'blacklisted_cdata_regex' => array(
7068
+ 'error_message' => 'html comments',
7069
+ 'regex' => '<!--',
7070
+ ),
7071
+ ),
7072
+ 'tag_spec' => array(
7073
+ 'mandatory_parent' => 'amp-animation',
7074
+ 'requires_extension' => array(
7075
+ 'amp-animation',
7076
+ ),
7077
+ 'spec_name' => 'amp-animation extension .json script',
7078
+ ),
7079
+ ),
7080
+ array(
7081
+ 'attr_spec_list' => array(
7082
+ 'async' => array(
7083
+ 'mandatory' => true,
7084
+ 'value' => '',
7085
+ ),
7086
+ 'nonce' => array(),
7087
+ 'type' => array(
7088
+ 'value_casei' => 'text/javascript',
7089
+ ),
7090
+ ),
7091
+ 'tag_spec' => array(
7092
+ 'extension_spec' => array(
7093
+ 'allowed_versions' => array(
7094
+ '0.1',
7095
+ 'latest',
7096
+ ),
7097
+ 'deprecated_allow_duplicates' => true,
7098
+ 'name' => 'amp-apester-media',
7099
+ 'requires_usage' => 2,
7100
+ ),
7101
+ ),
7102
+ ),
7103
+ array(
7104
+ 'attr_spec_list' => array(
7105
+ 'async' => array(
7106
+ 'mandatory' => true,
7107
+ 'value' => '',
7108
+ ),
7109
+ 'nonce' => array(),
7110
+ 'type' => array(
7111
+ 'value_casei' => 'text/javascript',
7112
+ ),
7113
+ ),
7114
+ 'tag_spec' => array(
7115
+ 'extension_spec' => array(
7116
+ 'allowed_versions' => array(
7117
+ '0.1',
7118
+ 'latest',
7119
+ ),
7120
+ 'deprecated_allow_duplicates' => true,
7121
+ 'name' => 'amp-app-banner',
7122
+ ),
7123
+ ),
7124
+ ),
7125
+ array(
7126
+ 'attr_spec_list' => array(
7127
+ 'async' => array(
7128
+ 'mandatory' => true,
7129
+ 'value' => '',
7130
+ ),
7131
+ 'nonce' => array(),
7132
+ 'type' => array(
7133
+ 'value_casei' => 'text/javascript',
7134
+ ),
7135
+ ),
7136
+ 'tag_spec' => array(
7137
+ 'extension_spec' => array(
7138
+ 'allowed_versions' => array(
7139
+ '0.1',
7140
+ 'latest',
7141
+ ),
7142
+ 'deprecated_allow_duplicates' => true,
7143
+ 'name' => 'amp-audio',
7144
+ 'requires_usage' => 2,
7145
+ ),
7146
+ ),
7147
+ ),
7148
+ array(
7149
+ 'attr_spec_list' => array(
7150
+ 'async' => array(
7151
+ 'mandatory' => true,
7152
+ 'value' => '',
7153
+ ),
7154
+ 'nonce' => array(),
7155
+ 'type' => array(
7156
+ 'value_casei' => 'text/javascript',
7157
+ ),
7158
+ ),
7159
+ 'tag_spec' => array(
7160
+ 'extension_spec' => array(
7161
+ 'allowed_versions' => array(
7162
+ '0.1',
7163
+ 'latest',
7164
+ ),
7165
+ 'name' => 'amp-auto-ads',
7166
+ ),
7167
+ ),
7168
+ ),
7169
+ array(
7170
+ 'attr_spec_list' => array(
7171
+ 'async' => array(
7172
+ 'mandatory' => true,
7173
+ 'value' => '',
7174
+ ),
7175
+ 'nonce' => array(),
7176
+ 'type' => array(
7177
+ 'value_casei' => 'text/javascript',
7178
+ ),
7179
+ ),
7180
+ 'tag_spec' => array(
7181
+ 'extension_spec' => array(
7182
+ 'allowed_versions' => array(
7183
+ '0.1',
7184
+ 'latest',
7185
+ ),
7186
+ 'name' => 'amp-beopinion',
7187
+ ),
7188
+ ),
7189
+ ),
7190
+ array(
7191
+ 'attr_spec_list' => array(
7192
+ 'async' => array(
7193
+ 'mandatory' => true,
7194
+ 'value' => '',
7195
+ ),
7196
+ 'nonce' => array(),
7197
+ 'type' => array(
7198
+ 'value_casei' => 'text/javascript',
7199
+ ),
7200
+ ),
7201
+ 'tag_spec' => array(
7202
+ 'extension_spec' => array(
7203
+ 'allowed_versions' => array(
7204
+ '0.1',
7205
+ 'latest',
7206
+ ),
7207
+ 'name' => 'amp-bind',
7208
+ 'requires_usage' => 3,
7209
+ ),
7210
+ ),
7211
+ ),
7212
+ array(
7213
+ 'attr_spec_list' => array(
7214
+ 'nonce' => array(),
7215
+ 'type' => array(
7216
+ 'dispatch_key' => 3,
7217
+ 'mandatory' => true,
7218
+ 'value_casei' => 'application/json',
7219
+ ),
7220
+ ),
7221
+ 'cdata' => array(
7222
+ 'blacklisted_cdata_regex' => array(
7223
+ 'error_message' => 'html comments',
7224
+ 'regex' => '<!--',
7225
+ ),
7226
+ ),
7227
+ 'tag_spec' => array(
7228
+ 'mandatory_parent' => 'amp-state',
7229
+ 'requires_extension' => array(
7230
+ 'amp-bind',
7231
+ ),
7232
+ 'spec_name' => 'amp-bind extension .json script',
7233
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-bind',
7234
+ ),
7235
+ ),
7236
+ array(
7237
+ 'attr_spec_list' => array(
7238
+ 'async' => array(
7239
+ 'mandatory' => true,
7240
+ 'value' => '',
7241
+ ),
7242
+ 'nonce' => array(),
7243
+ 'type' => array(
7244
+ 'value_casei' => 'text/javascript',
7245
+ ),
7246
+ ),
7247
+ 'tag_spec' => array(
7248
+ 'extension_spec' => array(
7249
+ 'allowed_versions' => array(
7250
+ '0.1',
7251
+ 'latest',
7252
+ ),
7253
+ 'name' => 'amp-bodymovin-animation',
7254
+ ),
7255
+ ),
7256
+ ),
7257
+ array(
7258
+ 'attr_spec_list' => array(
7259
+ 'async' => array(
7260
+ 'mandatory' => true,
7261
+ 'value' => '',
7262
+ ),
7263
+ 'nonce' => array(),
7264
+ 'type' => array(
7265
+ 'value_casei' => 'text/javascript',
7266
+ ),
7267
+ ),
7268
+ 'tag_spec' => array(
7269
+ 'extension_spec' => array(
7270
+ 'allowed_versions' => array(
7271
+ '0.1',
7272
+ 'latest',
7273
+ ),
7274
+ 'deprecated_allow_duplicates' => true,
7275
+ 'name' => 'amp-brid-player',
7276
+ 'requires_usage' => 2,
7277
+ ),
7278
+ ),
7279
+ ),
7280
+ array(
7281
+ 'attr_spec_list' => array(
7282
+ 'async' => array(
7283
+ 'mandatory' => true,
7284
+ 'value' => '',
7285
+ ),
7286
+ 'nonce' => array(),
7287
+ 'type' => array(
7288
+ 'value_casei' => 'text/javascript',
7289
+ ),
7290
+ ),
7291
+ 'tag_spec' => array(
7292
+ 'extension_spec' => array(
7293
+ 'allowed_versions' => array(
7294
+ '0.1',
7295
+ 'latest',
7296
+ ),
7297
+ 'deprecated_allow_duplicates' => true,
7298
+ 'name' => 'amp-brightcove',
7299
+ 'requires_usage' => 2,
7300
+ ),
7301
+ ),
7302
+ ),
7303
+ array(
7304
+ 'attr_spec_list' => array(
7305
+ 'async' => array(
7306
+ 'mandatory' => true,
7307
+ 'value' => '',
7308
+ ),
7309
+ 'nonce' => array(),
7310
+ 'type' => array(
7311
+ 'value_casei' => 'text/javascript',
7312
+ ),
7313
+ ),
7314
+ 'tag_spec' => array(
7315
+ 'extension_spec' => array(
7316
+ 'allowed_versions' => array(
7317
+ '0.1',
7318
+ 'latest',
7319
+ ),
7320
+ 'name' => 'amp-byside-content',
7321
+ ),
7322
+ ),
7323
+ ),
7324
+ array(
7325
+ 'attr_spec_list' => array(
7326
+ 'async' => array(
7327
+ 'mandatory' => true,
7328
+ 'value' => '',
7329
+ ),
7330
+ 'nonce' => array(),
7331
+ 'type' => array(
7332
+ 'value_casei' => 'text/javascript',
7333
+ ),
7334
+ ),
7335
+ 'tag_spec' => array(
7336
+ 'extension_spec' => array(
7337
+ 'allowed_versions' => array(
7338
+ '0.1',
7339
+ 'latest',
7340
+ ),
7341
+ 'name' => 'amp-call-tracking',
7342
+ 'requires_usage' => 2,
7343
+ ),
7344
+ ),
7345
+ ),
7346
+ array(
7347
+ 'attr_spec_list' => array(
7348
+ 'async' => array(
7349
+ 'mandatory' => true,
7350
+ 'value' => '',
7351
+ ),
7352
+ 'nonce' => array(),
7353
+ 'type' => array(
7354
+ 'value_casei' => 'text/javascript',
7355
+ ),
7356
+ ),
7357
+ 'tag_spec' => array(
7358
+ 'extension_spec' => array(
7359
+ 'allowed_versions' => array(
7360
+ '0.1',
7361
+ 'latest',
7362
+ ),
7363
+ 'deprecated_allow_duplicates' => true,
7364
+ 'name' => 'amp-carousel',
7365
+ 'requires_usage' => 2,
7366
+ ),
7367
+ ),
7368
+ ),
7369
+ array(
7370
+ 'attr_spec_list' => array(
7371
+ 'async' => array(
7372
+ 'mandatory' => true,
7373
+ 'value' => '',
7374
+ ),
7375
+ 'nonce' => array(),
7376
+ 'type' => array(
7377
+ 'value_casei' => 'text/javascript',
7378
+ ),
7379
+ ),
7380
+ 'tag_spec' => array(
7381
+ 'extension_spec' => array(
7382
+ 'allowed_versions' => array(
7383
+ '0.1',
7384
+ 'latest',
7385
+ ),
7386
+ 'name' => 'amp-consent',
7387
+ ),
7388
+ ),
7389
+ ),
7390
+ array(
7391
+ 'attr_spec_list' => array(
7392
+ 'nonce' => array(),
7393
+ 'type' => array(
7394
+ 'dispatch_key' => 3,
7395
+ 'mandatory' => true,
7396
+ 'value_casei' => 'application/json',
7397
+ ),
7398
+ ),
7399
+ 'cdata' => array(
7400
+ 'blacklisted_cdata_regex' => array(
7401
+ 'error_message' => 'html comments',
7402
+ 'regex' => '<!--',
7403
+ ),
7404
+ ),
7405
+ 'tag_spec' => array(
7406
+ 'mandatory_parent' => 'amp-consent',
7407
+ 'requires_extension' => array(
7408
+ 'amp-consent',
7409
+ ),
7410
+ 'spec_name' => 'amp-consent extension .json script',
7411
+ 'unique' => true,
7412
+ ),
7413
+ ),
7414
+ array(
7415
+ 'attr_spec_list' => array(
7416
+ 'async' => array(
7417
+ 'mandatory' => true,
7418
+ 'value' => '',
7419
+ ),
7420
+ 'nonce' => array(),
7421
+ 'type' => array(
7422
+ 'value_casei' => 'text/javascript',
7423
+ ),
7424
+ ),
7425
+ 'tag_spec' => array(
7426
+ 'extension_spec' => array(
7427
+ 'allowed_versions' => array(
7428
+ '0.1',
7429
+ 'latest',
7430
+ ),
7431
+ 'deprecated_allow_duplicates' => true,
7432
+ 'name' => 'amp-dailymotion',
7433
+ 'requires_usage' => 2,
7434
+ ),
7435
+ ),
7436
+ ),
7437
+ array(
7438
+ 'attr_spec_list' => array(
7439
+ 'async' => array(
7440
+ 'mandatory' => true,
7441
+ 'value' => '',
7442
+ ),
7443
+ 'nonce' => array(),
7444
+ 'type' => array(
7445
+ 'value_casei' => 'text/javascript',
7446
+ ),
7447
+ ),
7448
+ 'tag_spec' => array(
7449
+ 'extension_spec' => array(
7450
+ 'allowed_versions' => array(
7451
+ '0.1',
7452
+ 'latest',
7453
+ ),
7454
+ 'name' => 'amp-date-picker',
7455
+ ),
7456
+ ),
7457
+ ),
7458
+ array(
7459
+ 'attr_spec_list' => array(),
7460
+ 'tag_spec' => array(
7461
+ 'extension_spec' => array(
7462
+ 'allowed_versions' => array(
7463
+ '0.1',
7464
+ 'latest',
7465
+ ),
7466
+ 'name' => 'amp-document-recommendations',
7467
+ ),
7468
+ ),
7469
+ ),
7470
+ array(
7471
+ 'attr_spec_list' => array(
7472
+ 'recommendations' => array(
7473
+ 'dispatch_key' => 3,
7474
+ 'mandatory' => true,
7475
+ 'value_casei' => 'application/json',
7476
+ ),
7477
+ ),
7478
+ 'tag_spec' => array(
7479
+ 'mandatory_parent' => 'amp-document-recommendations',
7480
+ 'requires_extension' => array(
7481
+ 'amp-document-recommendations',
7482
+ ),
7483
+ 'spec_name' => 'amp-document-recommendations extension .json configuration',
7484
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-document-recommendations',
7485
+ ),
7486
+ ),
7487
+ array(
7488
+ 'attr_spec_list' => array(
7489
+ 'async' => array(
7490
+ 'mandatory' => true,
7491
+ 'value' => '',
7492
+ ),
7493
+ 'nonce' => array(),
7494
+ 'type' => array(
7495
+ 'value_casei' => 'text/javascript',
7496
+ ),
7497
+ ),
7498
+ 'tag_spec' => array(
7499
+ 'extension_spec' => array(
7500
+ 'allowed_versions' => array(
7501
+ '0.1',
7502
+ 'latest',
7503
+ ),
7504
+ 'deprecated_allow_duplicates' => true,
7505
+ 'name' => 'amp-dynamic-css-classes',
7506
+ 'requires_usage' => 3,
7507
+ ),
7508
+ ),
7509
+ ),
7510
+ array(
7511
+ 'attr_spec_list' => array(
7512
+ 'async' => array(
7513
+ 'mandatory' => true,
7514
+ 'value' => '',
7515
+ ),
7516
+ 'nonce' => array(),
7517
+ 'type' => array(
7518
+ 'value_casei' => 'text/javascript',
7519
+ ),
7520
+ ),
7521
+ 'tag_spec' => array(
7522
+ 'extension_spec' => array(
7523
+ 'allowed_versions' => array(
7524
+ '0.1',
7525
+ 'latest',
7526
+ ),
7527
+ 'deprecated_allow_duplicates' => true,
7528
+ 'name' => 'amp-experiment',
7529
+ 'requires_usage' => 2,
7530
+ ),
7531
+ ),
7532
+ ),
7533
+ array(
7534
+ 'attr_spec_list' => array(
7535
+ 'nonce' => array(),
7536
+ 'type' => array(
7537
+ 'dispatch_key' => 3,
7538
+ 'mandatory' => true,
7539
+ 'value_casei' => 'application/json',
7540
+ ),
7541
+ ),
7542
+ 'cdata' => array(
7543
+ 'blacklisted_cdata_regex' => array(
7544
+ 'error_message' => 'html comments',
7545
+ 'regex' => '<!--',
7546
+ ),
7547
+ ),
7548
+ 'tag_spec' => array(
7549
+ 'mandatory_parent' => 'amp-experiment',
7550
+ 'spec_name' => 'amp-experiment extension .json script',
7551
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-experiment',
7552
+ ),
7553
+ ),
7554
+ array(
7555
+ 'attr_spec_list' => array(
7556
+ 'async' => array(
7557
+ 'mandatory' => true,
7558
+ 'value' => '',
7559
+ ),
7560
+ 'nonce' => array(),
7561
+ 'type' => array(
7562
+ 'value_casei' => 'text/javascript',
7563
+ ),
7564
+ ),
7565
+ 'tag_spec' => array(
7566
+ 'extension_spec' => array(
7567
+ 'allowed_versions' => array(
7568
+ '0.1',
7569
+ 'latest',
7570
+ ),
7571
+ 'name' => 'amp-facebook-comments',
7572
+ ),
7573
+ ),
7574
+ ),
7575
+ array(
7576
+ 'attr_spec_list' => array(
7577
+ 'async' => array(
7578
+ 'mandatory' => true,
7579
+ 'value' => '',
7580
+ ),
7581
+ 'nonce' => array(),
7582
+ 'type' => array(
7583
+ 'value_casei' => 'text/javascript',
7584
+ ),
7585
+ ),
7586
+ 'tag_spec' => array(
7587
+ 'extension_spec' => array(
7588
+ 'allowed_versions' => array(
7589
+ '0.1',
7590
+ 'latest',
7591
+ ),
7592
+ 'name' => 'amp-facebook-like',
7593
+ ),
7594
+ ),
7595
+ ),
7596
+ array(
7597
+ 'attr_spec_list' => array(
7598
+ 'async' => array(
7599
+ 'mandatory' => true,
7600
+ 'value' => '',
7601
+ ),
7602
+ 'nonce' => array(),
7603
+ 'type' => array(
7604
+ 'value_casei' => 'text/javascript',
7605
+ ),
7606
+ ),
7607
+ 'tag_spec' => array(
7608
+ 'extension_spec' => array(
7609
+ 'allowed_versions' => array(
7610
+ '0.1',
7611
+ 'latest',
7612
+ ),
7613
+ 'name' => 'amp-facebook-page',
7614
+ ),
7615
+ ),
7616
+ ),
7617
+ array(
7618
+ 'attr_spec_list' => array(
7619
+ 'async' => array(
7620
+ 'mandatory' => true,
7621
+ 'value' => '',
7622
+ ),
7623
+ 'nonce' => array(),
7624
+ 'type' => array(
7625
+ 'value_casei' => 'text/javascript',
7626
+ ),
7627
+ ),
7628
+ 'tag_spec' => array(
7629
+ 'extension_spec' => array(
7630
+ 'allowed_versions' => array(
7631
+ '0.1',
7632
+ 'latest',
7633
+ ),
7634
+ 'deprecated_allow_duplicates' => true,
7635
+ 'name' => 'amp-facebook',
7636
+ 'requires_usage' => 2,
7637
+ ),
7638
+ ),
7639
+ ),
7640
+ array(
7641
+ 'attr_spec_list' => array(
7642
+ 'async' => array(
7643
+ 'mandatory' => true,
7644
+ 'value' => '',
7645
+ ),
7646
+ 'nonce' => array(),
7647
+ 'type' => array(
7648
+ 'value_casei' => 'text/javascript',
7649
+ ),
7650
+ ),
7651
+ 'tag_spec' => array(
7652
+ 'extension_spec' => array(
7653
+ 'allowed_versions' => array(
7654
+ '0.1',
7655
+ 'latest',
7656
+ ),
7657
+ 'deprecated_allow_duplicates' => true,
7658
+ 'name' => 'amp-fit-text',
7659
+ 'requires_usage' => 2,
7660
+ ),
7661
+ ),
7662
+ ),
7663
+ array(
7664
+ 'attr_spec_list' => array(
7665
+ 'async' => array(
7666
+ 'mandatory' => true,
7667
+ 'value' => '',
7668
+ ),
7669
+ 'nonce' => array(),
7670
+ 'type' => array(
7671
+ 'value_casei' => 'text/javascript',
7672
+ ),
7673
+ ),
7674
+ 'tag_spec' => array(
7675
+ 'extension_spec' => array(
7676
+ 'allowed_versions' => array(
7677
+ '0.1',
7678
+ 'latest',
7679
+ ),
7680
+ 'deprecated_allow_duplicates' => true,
7681
+ 'name' => 'amp-font',
7682
+ 'requires_usage' => 2,
7683
+ ),
7684
+ ),
7685
+ ),
7686
+ array(
7687
+ 'attr_spec_list' => array(
7688
+ 'async' => array(
7689
+ 'mandatory' => true,
7690
+ 'value' => '',
7691
+ ),
7692
+ 'nonce' => array(),
7693
+ 'type' => array(
7694
+ 'value_casei' => 'text/javascript',
7695
+ ),
7696
+ ),
7697
+ 'tag_spec' => array(
7698
+ 'extension_spec' => array(
7699
+ 'allowed_versions' => array(
7700
+ '0.1',
7701
+ 'latest',
7702
+ ),
7703
+ 'deprecated_allow_duplicates' => true,
7704
+ 'name' => 'amp-form',
7705
+ 'requires_usage' => 2,
7706
+ ),
7707
+ ),
7708
+ ),
7709
+ array(
7710
+ 'attr_spec_list' => array(
7711
+ 'async' => array(
7712
+ 'mandatory' => true,
7713
+ 'value' => '',
7714
+ ),
7715
+ 'nonce' => array(),
7716
+ 'type' => array(
7717
+ 'value_casei' => 'text/javascript',
7718
+ ),
7719
+ ),
7720
+ 'tag_spec' => array(
7721
+ 'extension_spec' => array(
7722
+ 'allowed_versions' => array(
7723
+ '0.1',
7724
+ 'latest',
7725
+ ),
7726
+ 'name' => 'amp-fx-collection',
7727
+ 'requires_usage' => 3,
7728
+ ),
7729
+ ),
7730
+ ),
7731
+ array(
7732
+ 'attr_spec_list' => array(
7733
+ 'async' => array(
7734
+ 'mandatory' => true,
7735
+ 'value' => '',
7736
+ ),
7737
+ 'nonce' => array(),
7738
+ 'type' => array(
7739
+ 'value_casei' => 'text/javascript',
7740
+ ),
7741
+ ),
7742
+ 'tag_spec' => array(
7743
+ 'extension_spec' => array(
7744
+ 'allowed_versions' => array(
7745
+ '0.1',
7746
+ 'latest',
7747
+ ),
7748
+ 'deprecated_allow_duplicates' => true,
7749
+ 'name' => 'amp-fx-flying-carpet',
7750
+ 'requires_usage' => 2,
7751
+ ),
7752
+ ),
7753
+ ),
7754
+ array(
7755
+ 'attr_spec_list' => array(
7756
+ 'async' => array(
7757
+ 'mandatory' => true,
7758
+ 'value' => '',
7759
+ ),
7760
+ 'nonce' => array(),
7761
+ 'type' => array(
7762
+ 'value_casei' => 'text/javascript',
7763
+ ),
7764
+ ),
7765
+ 'tag_spec' => array(
7766
+ 'extension_spec' => array(
7767
+ 'allowed_versions' => array(
7768
+ '0.1',
7769
+ 'latest',
7770
+ ),
7771
+ 'deprecated_allow_duplicates' => true,
7772
+ 'name' => 'amp-gfycat',
7773
+ 'requires_usage' => 2,
7774
+ ),
7775
+ ),
7776
+ ),
7777
+ array(
7778
+ 'attr_spec_list' => array(
7779
+ 'async' => array(
7780
+ 'mandatory' => true,
7781
+ 'value' => '',
7782
+ ),
7783
+ 'nonce' => array(),
7784
+ 'type' => array(
7785
+ 'value_casei' => 'text/javascript',
7786
+ ),
7787
+ ),
7788
+ 'tag_spec' => array(
7789
+ 'extension_spec' => array(
7790
+ 'allowed_versions' => array(
7791
+ '0.1',
7792
+ 'latest',
7793
+ ),
7794
+ 'name' => 'amp-gist',
7795
+ ),
7796
+ ),
7797
+ ),
7798
+ array(
7799
+ 'attr_spec_list' => array(
7800
+ 'async' => array(
7801
+ 'mandatory' => true,
7802
+ 'value' => '',
7803
+ ),
7804
+ 'nonce' => array(),
7805
+ 'type' => array(
7806
+ 'value_casei' => 'text/javascript',
7807
+ ),
7808
+ ),
7809
+ 'tag_spec' => array(
7810
+ 'extension_spec' => array(
7811
+ 'allowed_versions' => array(
7812
+ '0.1',
7813
+ 'latest',
7814
+ ),
7815
+ 'name' => 'amp-hulu',
7816
+ ),
7817
+ ),
7818
+ ),
7819
+ array(
7820
+ 'attr_spec_list' => array(
7821
+ 'async' => array(
7822
+ 'mandatory' => true,
7823
+ 'value' => '',
7824
+ ),
7825
+ 'nonce' => array(),
7826
+ 'type' => array(
7827
+ 'value_casei' => 'text/javascript',
7828
+ ),
7829
+ ),
7830
+ 'tag_spec' => array(
7831
+ 'extension_spec' => array(
7832
+ 'allowed_versions' => array(
7833
+ '0.1',
7834
+ 'latest',
7835
+ ),
7836
+ 'deprecated_allow_duplicates' => true,
7837
+ 'name' => 'amp-iframe',
7838
+ 'requires_usage' => 2,
7839
+ ),
7840
+ ),
7841
+ ),
7842
+ array(
7843
+ 'attr_spec_list' => array(
7844
+ 'async' => array(
7845
+ 'mandatory' => true,
7846
+ 'value' => '',
7847
+ ),
7848
+ 'nonce' => array(),
7849
+ 'type' => array(
7850
+ 'value_casei' => 'text/javascript',
7851
+ ),
7852
+ ),
7853
+ 'tag_spec' => array(
7854
+ 'extension_spec' => array(
7855
+ 'allowed_versions' => array(
7856
+ '0.1',
7857
+ 'latest',
7858
+ ),
7859
+ 'name' => 'amp-ima-video',
7860
+ ),
7861
+ ),
7862
+ ),
7863
+ array(
7864
+ 'attr_spec_list' => array(
7865
+ 'async' => array(
7866
+ 'mandatory' => true,
7867
+ 'value' => '',
7868
+ ),
7869
+ 'nonce' => array(),
7870
+ 'type' => array(
7871
+ 'value_casei' => 'text/javascript',
7872
+ ),
7873
+ ),
7874
+ 'tag_spec' => array(
7875
+ 'extension_spec' => array(
7876
+ 'allowed_versions' => array(
7877
+ '0.1',
7878
+ 'latest',
7879
+ ),
7880
+ 'deprecated_allow_duplicates' => true,
7881
+ 'name' => 'amp-image-lightbox',
7882
+ 'requires_usage' => 2,
7883
+ ),
7884
+ ),
7885
+ ),
7886
+ array(
7887
+ 'attr_spec_list' => array(
7888
+ 'async' => array(
7889
+ 'mandatory' => true,
7890
+ 'value' => '',
7891
+ ),
7892
+ 'nonce' => array(),
7893
+ 'type' => array(
7894
+ 'value_casei' => 'text/javascript',
7895
+ ),
7896
+ ),
7897
+ 'tag_spec' => array(
7898
+ 'extension_spec' => array(
7899
+ 'allowed_versions' => array(
7900
+ '0.1',
7901
+ 'latest',
7902
+ ),
7903
+ 'name' => 'amp-imgur',
7904
+ ),
7905
+ ),
7906
+ ),
7907
+ array(
7908
+ 'attr_spec_list' => array(
7909
+ 'async' => array(
7910
+ 'mandatory' => true,
7911
+ 'value' => '',
7912
+ ),
7913
+ 'nonce' => array(),
7914
+ 'type' => array(
7915
+ 'value_casei' => 'text/javascript',
7916
+ ),
7917
+ ),
7918
+ 'tag_spec' => array(
7919
+ 'extension_spec' => array(
7920
+ 'allowed_versions' => array(
7921
+ '0.1',
7922
+ 'latest',
7923
+ ),
7924
+ 'deprecated_allow_duplicates' => true,
7925
+ 'name' => 'amp-instagram',
7926
+ 'requires_usage' => 2,
7927
+ ),
7928
+ ),
7929
+ ),
7930
+ array(
7931
+ 'attr_spec_list' => array(
7932
+ 'async' => array(
7933
+ 'mandatory' => true,
7934
+ 'value' => '',
7935
+ ),
7936
+ 'nonce' => array(),
7937
+ 'type' => array(
7938
+ 'value_casei' => 'text/javascript',
7939
+ ),
7940
+ ),
7941
+ 'tag_spec' => array(
7942
+ 'extension_spec' => array(
7943
+ 'allowed_versions' => array(
7944
+ '0.1',
7945
+ 'latest',
7946
+ ),
7947
+ 'deprecated_allow_duplicates' => true,
7948
+ 'name' => 'amp-install-serviceworker',
7949
+ 'requires_usage' => 2,
7950
+ ),
7951
+ ),
7952
+ ),
7953
+ array(
7954
+ 'attr_spec_list' => array(
7955
+ 'async' => array(
7956
+ 'mandatory' => true,
7957
+ 'value' => '',
7958
+ ),
7959
+ 'nonce' => array(),
7960
+ 'type' => array(
7961
+ 'value_casei' => 'text/javascript',
7962
+ ),
7963
+ ),
7964
+ 'tag_spec' => array(
7965
+ 'extension_spec' => array(
7966
+ 'allowed_versions' => array(
7967
+ '0.1',
7968
+ 'latest',
7969
+ ),
7970
+ 'name' => 'amp-izlesene',
7971
+ 'requires_usage' => 2,
7972
+ ),
7973
+ ),
7974
+ ),
7975
+ array(
7976
+ 'attr_spec_list' => array(
7977
+ 'async' => array(
7978
+ 'mandatory' => true,
7979
+ 'value' => '',
7980
+ ),
7981
+ 'nonce' => array(),
7982
+ 'type' => array(
7983
+ 'value_casei' => 'text/javascript',
7984
+ ),
7985
+ ),
7986
+ 'tag_spec' => array(
7987
+ 'extension_spec' => array(
7988
+ 'allowed_versions' => array(
7989
+ '0.1',
7990
+ 'latest',
7991
+ ),
7992
+ 'deprecated_allow_duplicates' => true,
7993
+ 'name' => 'amp-jwplayer',
7994
+ 'requires_usage' => 2,
7995
+ ),
7996
+ ),
7997
+ ),
7998
+ array(
7999
+ 'attr_spec_list' => array(
8000
+ 'async' => array(
8001
+ 'mandatory' => true,
8002
+ 'value' => '',
8003
+ ),
8004
+ 'nonce' => array(),
8005
+ 'type' => array(
8006
+ 'value_casei' => 'text/javascript',
8007
+ ),
8008
+ ),
8009
+ 'tag_spec' => array(
8010
+ 'extension_spec' => array(
8011
+ 'allowed_versions' => array(
8012
+ '0.1',
8013
+ 'latest',
8014
+ ),
8015
+ 'deprecated_allow_duplicates' => true,
8016
+ 'name' => 'amp-kaltura-player',
8017
+ 'requires_usage' => 2,
8018
+ ),
8019
+ ),
8020
+ ),
8021
+ array(
8022
+ 'attr_spec_list' => array(
8023
+ 'async' => array(
8024
+ 'mandatory' => true,
8025
+ 'value' => '',
8026
+ ),
8027
+ 'nonce' => array(),
8028
+ 'type' => array(
8029
+ 'value_casei' => 'text/javascript',
8030
+ ),
8031
+ ),
8032
+ 'tag_spec' => array(
8033
+ 'extension_spec' => array(
8034
+ 'allowed_versions' => array(
8035
+ '0.1',
8036
+ 'latest',
8037
+ ),
8038
+ 'name' => 'amp-lightbox-gallery',
8039
+ 'requires_usage' => 3,
8040
+ ),
8041
+ ),
8042
+ ),
8043
+ array(
8044
+ 'attr_spec_list' => array(
8045
+ 'async' => array(
8046
+ 'mandatory' => true,
8047
+ 'value' => '',
8048
+ ),
8049
+ 'nonce' => array(),
8050
+ 'type' => array(
8051
+ 'value_casei' => 'text/javascript',
8052
+ ),
8053
+ ),
8054
+ 'tag_spec' => array(
8055
+ 'extension_spec' => array(
8056
+ 'allowed_versions' => array(
8057
+ '0.1',
8058
+ 'latest',
8059
+ ),
8060
+ 'deprecated_allow_duplicates' => true,
8061
+ 'name' => 'amp-lightbox',
8062
+ 'requires_usage' => 2,
8063
+ ),
8064
+ ),
8065
+ ),
8066
+ array(
8067
+ 'attr_spec_list' => array(
8068
+ 'async' => array(
8069
+ 'mandatory' => true,
8070
+ 'value' => '',
8071
+ ),
8072
+ 'nonce' => array(),
8073
+ 'type' => array(
8074
+ 'value_casei' => 'text/javascript',
8075
+ ),
8076
+ ),
8077
+ 'tag_spec' => array(
8078
+ 'extension_spec' => array(
8079
+ 'allowed_versions' => array(
8080
+ '0.1',
8081
+ 'latest',
8082
+ ),
8083
+ 'deprecated_allow_duplicates' => true,
8084
+ 'name' => 'amp-list',
8085
+ 'requires_usage' => 2,
8086
+ ),
8087
+ ),
8088
+ ),
8089
+ array(
8090
+ 'attr_spec_list' => array(
8091
+ 'async' => array(
8092
+ 'mandatory' => true,
8093
+ 'value' => '',
8094
+ ),
8095
+ 'nonce' => array(),
8096
+ 'type' => array(
8097
+ 'value_casei' => 'text/javascript',
8098
+ ),
8099
+ ),
8100
+ 'tag_spec' => array(
8101
+ 'extension_spec' => array(
8102
+ 'allowed_versions' => array(
8103
+ '0.1',
8104
+ 'latest',
8105
+ ),
8106
+ 'name' => 'amp-live-list',
8107
+ 'requires_usage' => 2,
8108
+ ),
8109
+ 'mandatory_parent' => 'head',
8110
+ 'unique_warning' => true,
8111
+ ),
8112
+ ),
8113
+ array(
8114
+ 'attr_spec_list' => array(
8115
+ 'async' => array(
8116
+ 'mandatory' => true,
8117
+ 'value' => '',
8118
+ ),
8119
+ 'nonce' => array(),
8120
+ 'type' => array(
8121
+ 'value_casei' => 'text/javascript',
8122
+ ),
8123
+ ),
8124
+ 'tag_spec' => array(
8125
+ 'extension_spec' => array(
8126
+ 'allowed_versions' => array(
8127
+ '0.1',
8128
+ 'latest',
8129
+ ),
8130
+ 'name' => 'amp-mathml',
8131
+ ),
8132
+ ),
8133
+ ),
8134
+ array(
8135
+ 'attr_spec_list' => array(
8136
+ 'async' => array(
8137
+ 'mandatory' => true,
8138
+ 'value' => '',
8139
+ ),
8140
+ 'nonce' => array(),
8141
+ 'type' => array(
8142
+ 'value_casei' => 'text/javascript',
8143
+ ),
8144
+ ),
8145
+ 'tag_spec' => array(
8146
+ 'extension_spec' => array(
8147
+ 'allowed_versions' => array(
8148
+ '0.1',
8149
+ 'latest',
8150
+ ),
8151
+ 'deprecated_allow_duplicates' => true,
8152
+ 'is_custom_template' => true,
8153
+ 'name' => 'amp-mustache',
8154
+ 'requires_usage' => 2,
8155
+ ),
8156
+ ),
8157
+ ),
8158
+ array(
8159
+ 'attr_spec_list' => array(
8160
+ 'async' => array(
8161
+ 'mandatory' => true,
8162
+ 'value' => '',
8163
+ ),
8164
+ 'nonce' => array(),
8165
+ 'type' => array(
8166
+ 'value_casei' => 'text/javascript',
8167
+ ),
8168
+ ),
8169
+ 'tag_spec' => array(
8170
+ 'extension_spec' => array(
8171
+ 'allowed_versions' => array(
8172
+ '0.1',
8173
+ 'latest',
8174
+ ),
8175
+ 'name' => 'amp-nexxtv-player',
8176
+ ),
8177
+ ),
8178
+ ),
8179
+ array(
8180
+ 'attr_spec_list' => array(
8181
+ 'async' => array(
8182
+ 'mandatory' => true,
8183
+ 'value' => '',
8184
+ ),
8185
+ 'nonce' => array(),
8186
+ 'type' => array(
8187
+ 'value_casei' => 'text/javascript',
8188
+ ),
8189
+ ),
8190
+ 'tag_spec' => array(
8191
+ 'extension_spec' => array(
8192
+ 'allowed_versions' => array(
8193
+ '0.1',
8194
+ 'latest',
8195
+ ),
8196
+ 'deprecated_allow_duplicates' => true,
8197
+ 'name' => 'amp-o2-player',
8198
+ 'requires_usage' => 2,
8199
+ ),
8200
+ ),
8201
+ ),
8202
+ array(
8203
+ 'attr_spec_list' => array(
8204
+ 'async' => array(
8205
+ 'mandatory' => true,
8206
+ 'value' => '',
8207
+ ),
8208
+ 'nonce' => array(),
8209
+ 'type' => array(
8210
+ 'value_casei' => 'text/javascript',
8211
+ ),
8212
+ ),
8213
+ 'tag_spec' => array(
8214
+ 'extension_spec' => array(
8215
+ 'allowed_versions' => array(
8216
+ '0.1',
8217
+ 'latest',
8218
+ ),
8219
+ 'name' => 'amp-ooyala-player',
8220
+ ),
8221
+ ),
8222
+ ),
8223
+ array(
8224
+ 'attr_spec_list' => array(
8225
+ 'async' => array(
8226
+ 'mandatory' => true,
8227
+ 'value' => '',
8228
+ ),
8229
+ 'nonce' => array(),
8230
+ 'type' => array(
8231
+ 'value_casei' => 'text/javascript',
8232
+ ),
8233
+ ),
8234
+ 'tag_spec' => array(
8235
+ 'extension_spec' => array(
8236
+ 'allowed_versions' => array(
8237
+ '0.1',
8238
+ 'latest',
8239
+ ),
8240
+ 'deprecated_allow_duplicates' => true,
8241
+ 'name' => 'amp-pinterest',
8242
+ 'requires_usage' => 2,
8243
+ ),
8244
+ ),
8245
+ ),
8246
+ array(
8247
+ 'attr_spec_list' => array(
8248
+ 'async' => array(
8249
+ 'mandatory' => true,
8250
+ 'value' => '',
8251
+ ),
8252
+ 'nonce' => array(),
8253
+ 'type' => array(
8254
+ 'value_casei' => 'text/javascript',
8255
+ ),
8256
+ ),
8257
+ 'tag_spec' => array(
8258
+ 'extension_spec' => array(
8259
+ 'allowed_versions' => array(
8260
+ '0.1',
8261
+ 'latest',
8262
+ ),
8263
+ 'name' => 'amp-playbuzz',
8264
+ ),
8265
+ ),
8266
+ ),
8267
+ array(
8268
+ 'attr_spec_list' => array(
8269
+ 'async' => array(
8270
+ 'mandatory' => true,
8271
+ 'value' => '',
8272
+ ),
8273
+ 'nonce' => array(),
8274
+ 'type' => array(
8275
+ 'value_casei' => 'text/javascript',
8276
+ ),
8277
+ ),
8278
+ 'tag_spec' => array(
8279
+ 'extension_spec' => array(
8280
+ 'allowed_versions' => array(
8281
+ '0.1',
8282
+ 'latest',
8283
+ ),
8284
+ 'name' => 'amp-position-observer',
8285
+ ),
8286
+ ),
8287
+ ),
8288
+ array(
8289
+ 'attr_spec_list' => array(
8290
+ 'async' => array(
8291
+ 'mandatory' => true,
8292
+ 'value' => '',
8293
+ ),
8294
+ 'nonce' => array(),
8295
+ 'type' => array(
8296
+ 'value_casei' => 'text/javascript',
8297
+ ),
8298
+ ),
8299
+ 'tag_spec' => array(
8300
+ 'extension_spec' => array(
8301
+ 'allowed_versions' => array(
8302
+ '0.1',
8303
+ 'latest',
8304
+ ),
8305
+ 'deprecated_allow_duplicates' => true,
8306
+ 'name' => 'amp-reach-player',
8307
+ 'requires_usage' => 2,
8308
+ ),
8309
+ ),
8310
+ ),
8311
+ array(
8312
+ 'attr_spec_list' => array(
8313
+ 'async' => array(
8314
+ 'mandatory' => true,
8315
+ 'value' => '',
8316
+ ),
8317
+ 'nonce' => array(),
8318
+ 'type' => array(
8319
+ 'value_casei' => 'text/javascript',
8320
+ ),
8321
+ ),
8322
+ 'tag_spec' => array(
8323
+ 'extension_spec' => array(
8324
+ 'allowed_versions' => array(
8325
+ '0.1',
8326
+ 'latest',
8327
+ ),
8328
+ 'deprecated_allow_duplicates' => true,
8329
+ 'name' => 'amp-reddit',
8330
+ ),
8331
+ ),
8332
+ ),
8333
+ array(
8334
+ 'attr_spec_list' => array(
8335
+ 'async' => array(
8336
+ 'mandatory' => true,
8337
+ 'value' => '',
8338
+ ),
8339
+ 'nonce' => array(),
8340
+ 'type' => array(
8341
+ 'value_casei' => 'text/javascript',
8342
+ ),
8343
+ ),
8344
+ 'tag_spec' => array(
8345
+ 'extension_spec' => array(
8346
+ 'allowed_versions' => array(
8347
+ '0.1',
8348
+ 'latest',
8349
+ ),
8350
+ 'name' => 'amp-riddle-quiz',
8351
+ ),
8352
+ ),
8353
+ ),
8354
+ array(
8355
+ 'attr_spec_list' => array(
8356
+ 'async' => array(
8357
+ 'mandatory' => true,
8358
+ 'value' => '',
8359
+ ),
8360
+ 'nonce' => array(),
8361
+ 'type' => array(
8362
+ 'value_casei' => 'text/javascript',
8363
+ ),
8364
+ ),
8365
+ 'tag_spec' => array(
8366
+ 'extension_spec' => array(
8367
+ 'allowed_versions' => array(
8368
+ '0.1',
8369
+ 'latest',
8370
+ ),
8371
+ 'name' => 'amp-selector',
8372
+ 'requires_usage' => 2,
8373
+ ),
8374
+ ),
8375
+ ),
8376
+ array(
8377
+ 'attr_spec_list' => array(
8378
+ 'async' => array(
8379
+ 'mandatory' => true,
8380
+ 'value' => '',
8381
+ ),
8382
+ 'nonce' => array(),
8383
+ 'type' => array(
8384
+ 'value_casei' => 'text/javascript',
8385
+ ),
8386
+ ),
8387
+ 'tag_spec' => array(
8388
+ 'extension_spec' => array(
8389
+ 'allowed_versions' => array(
8390
+ '0.1',
8391
+ 'latest',
8392
+ ),
8393
+ 'deprecated_allow_duplicates' => true,
8394
+ 'name' => 'amp-sidebar',
8395
+ 'requires_usage' => 2,
8396
+ ),
8397
+ ),
8398
+ ),
8399
+ array(
8400
+ 'attr_spec_list' => array(
8401
+ 'async' => array(
8402
+ 'mandatory' => true,
8403
+ 'value' => '',
8404
+ ),
8405
+ 'nonce' => array(),
8406
+ 'type' => array(
8407
+ 'value_casei' => 'text/javascript',
8408
+ ),
8409
+ ),
8410
+ 'tag_spec' => array(
8411
+ 'extension_spec' => array(
8412
+ 'allowed_versions' => array(
8413
+ '0.1',
8414
+ 'latest',
8415
+ ),
8416
+ 'deprecated_allow_duplicates' => true,
8417
+ 'name' => 'amp-social-share',
8418
+ 'requires_usage' => 2,
8419
+ ),
8420
+ ),
8421
+ ),
8422
+ array(
8423
+ 'attr_spec_list' => array(
8424
+ 'async' => array(
8425
+ 'mandatory' => true,
8426
+ 'value' => '',
8427
+ ),
8428
+ 'nonce' => array(),
8429
+ 'type' => array(
8430
+ 'value_casei' => 'text/javascript',
8431
+ ),
8432
+ ),
8433
+ 'tag_spec' => array(
8434
+ 'extension_spec' => array(
8435
+ 'allowed_versions' => array(
8436
+ '0.1',
8437
+ 'latest',
8438
+ ),
8439
+ 'deprecated_allow_duplicates' => true,
8440
+ 'name' => 'amp-soundcloud',
8441
+ 'requires_usage' => 2,
8442
+ ),
8443
+ ),
8444
+ ),
8445
+ array(
8446
+ 'attr_spec_list' => array(
8447
+ 'async' => array(
8448
+ 'mandatory' => true,
8449
+ 'value' => '',
8450
+ ),
8451
+ 'nonce' => array(),
8452
+ 'type' => array(
8453
+ 'value_casei' => 'text/javascript',
8454
+ ),
8455
+ ),
8456
+ 'tag_spec' => array(
8457
+ 'extension_spec' => array(
8458
+ 'allowed_versions' => array(
8459
+ '0.1',
8460
+ 'latest',
8461
+ ),
8462
+ 'deprecated_allow_duplicates' => true,
8463
+ 'name' => 'amp-springboard-player',
8464
+ 'requires_usage' => 2,
8465
+ ),
8466
+ ),
8467
+ ),
8468
+ array(
8469
+ 'attr_spec_list' => array(
8470
+ 'async' => array(
8471
+ 'mandatory' => true,
8472
+ 'value' => '',
8473
+ ),
8474
+ 'nonce' => array(),
8475
+ 'type' => array(
8476
+ 'value_casei' => 'text/javascript',
8477
+ ),
8478
+ ),
8479
+ 'tag_spec' => array(
8480
+ 'extension_spec' => array(
8481
+ 'allowed_versions' => array(
8482
+ '0.1',
8483
+ '1.0',
8484
+ 'latest',
8485
+ ),
8486
+ 'deprecated_versions' => array(
8487
+ '0.1',
8488
+ ),
8489
+ 'name' => 'amp-sticky-ad',
8490
+ 'requires_usage' => 2,
8491
+ ),
8492
+ ),
8493
+ ),
8494
+ array(
8495
+ 'attr_spec_list' => array(
8496
+ 'async' => array(
8497
+ 'mandatory' => true,
8498
+ 'value' => '',
8499
+ ),
8500
+ 'nonce' => array(),
8501
+ 'type' => array(
8502
+ 'value_casei' => 'text/javascript',
8503
+ ),
8504
+ ),
8505
+ 'tag_spec' => array(
8506
+ 'extension_spec' => array(
8507
+ 'allowed_versions' => array(
8508
+ '0.1',
8509
+ 'latest',
8510
+ ),
8511
+ 'name' => 'amp-story-auto-ads',
8512
+ ),
8513
+ ),
8514
+ ),
8515
+ array(
8516
+ 'attr_spec_list' => array(
8517
+ 'nonce' => array(),
8518
+ 'type' => array(
8519
+ 'dispatch_key' => 3,
8520
+ 'mandatory' => true,
8521
+ 'value_casei' => 'application/json',
8522
+ ),
8523
+ ),
8524
+ 'cdata' => array(
8525
+ 'blacklisted_cdata_regex' => array(
8526
+ 'error_message' => 'html comments',
8527
+ 'regex' => '<!--',
8528
+ ),
8529
+ ),
8530
+ 'tag_spec' => array(
8531
+ 'mandatory_parent' => 'amp-story-auto-ads',
8532
+ 'requires_extension' => array(
8533
+ 'amp-story-auto-ads',
8534
+ ),
8535
+ 'spec_name' => 'amp-story-auto-ads config script',
8536
+ 'spec_url' => 'https://github.com/ampproject/amphtml/blob/master/extensions/amp-story/amp-story-auto-ads.md',
8537
+ ),
8538
+ ),
8539
+ array(
8540
+ 'attr_spec_list' => array(
8541
+ 'async' => array(
8542
+ 'mandatory' => true,
8543
+ 'value' => '',
8544
+ ),
8545
+ 'nonce' => array(),
8546
+ 'type' => array(
8547
+ 'value_casei' => 'text/javascript',
8548
+ ),
8549
+ ),
8550
+ 'tag_spec' => array(
8551
+ 'extension_spec' => array(
8552
+ 'allowed_versions' => array(
8553
+ '0.1',
8554
+ 'latest',
8555
+ ),
8556
+ 'name' => 'amp-story',
8557
+ ),
8558
+ ),
8559
+ ),
8560
+ array(
8561
+ 'attr_spec_list' => array(
8562
+ 'async' => array(
8563
+ 'mandatory' => true,
8564
+ 'value' => '',
8565
+ ),
8566
+ 'nonce' => array(),
8567
+ 'type' => array(
8568
+ 'value_casei' => 'text/javascript',
8569
+ ),
8570
+ ),
8571
+ 'tag_spec' => array(
8572
+ 'extension_spec' => array(
8573
+ 'allowed_versions' => array(
8574
+ '0.1',
8575
+ 'latest',
8576
+ ),
8577
+ 'name' => 'amp-subscriptions',
8578
+ 'requires_usage' => 3,
8579
+ ),
8580
+ ),
8581
+ ),
8582
+ array(
8583
+ 'attr_spec_list' => array(
8584
+ 'id' => array(
8585
+ 'dispatch_key' => 2,
8586
+ 'mandatory' => true,
8587
+ 'value' => 'amp-subscriptions',
8588
+ ),
8589
+ 'nonce' => array(),
8590
+ 'type' => array(
8591
+ 'mandatory' => true,
8592
+ 'value_casei' => 'application/json',
8593
+ ),
8594
+ ),
8595
+ 'cdata' => array(
8596
+ 'blacklisted_cdata_regex' => array(
8597
+ 'error_message' => 'html comments',
8598
+ 'regex' => '<!--',
8599
+ ),
8600
+ ),
8601
+ 'tag_spec' => array(
8602
+ 'mandatory_parent' => 'head',
8603
+ 'requires_extension' => array(
8604
+ 'amp-subscriptions',
8605
+ ),
8606
+ 'spec_name' => 'amp-subscriptions extension .json script',
8607
+ 'unique' => true,
8608
+ ),
8609
+ ),
8610
+ array(
8611
+ 'attr_spec_list' => array(
8612
+ 'async' => array(
8613
+ 'mandatory' => true,
8614
+ 'value' => '',
8615
+ ),
8616
+ 'nonce' => array(),
8617
+ 'type' => array(
8618
+ 'value_casei' => 'text/javascript',
8619
+ ),
8620
+ ),
8621
+ 'tag_spec' => array(
8622
+ 'extension_spec' => array(
8623
+ 'allowed_versions' => array(
8624
+ '0.1',
8625
+ 'latest',
8626
+ ),
8627
+ 'name' => 'amp-subscriptions-google',
8628
+ 'requires_usage' => 3,
8629
+ ),
8630
+ 'requires_extension' => array(
8631
+ 'amp-subscriptions',
8632
+ ),
8633
+ ),
8634
+ ),
8635
+ array(
8636
+ 'attr_spec_list' => array(
8637
+ 'async' => array(
8638
+ 'mandatory' => true,
8639
+ 'value' => '',
8640
+ ),
8641
+ 'nonce' => array(),
8642
+ 'type' => array(
8643
+ 'value_casei' => 'text/javascript',
8644
+ ),
8645
+ ),
8646
+ 'tag_spec' => array(
8647
+ 'extension_spec' => array(
8648
+ 'allowed_versions' => array(
8649
+ '0.1',
8650
+ 'latest',
8651
+ ),
8652
+ 'name' => 'amp-timeago',
8653
+ ),
8654
+ ),
8655
+ ),
8656
+ array(
8657
+ 'attr_spec_list' => array(
8658
+ 'async' => array(
8659
+ 'mandatory' => true,
8660
+ 'value' => '',
8661
+ ),
8662
+ 'nonce' => array(),
8663
+ 'type' => array(
8664
+ 'value_casei' => 'text/javascript',
8665
+ ),
8666
+ ),
8667
+ 'tag_spec' => array(
8668
+ 'extension_spec' => array(
8669
+ 'allowed_versions' => array(
8670
+ '0.1',
8671
+ 'latest',
8672
+ ),
8673
+ 'deprecated_allow_duplicates' => true,
8674
+ 'name' => 'amp-twitter',
8675
+ 'requires_usage' => 2,
8676
+ ),
8677
+ ),
8678
+ ),
8679
+ array(
8680
+ 'attr_spec_list' => array(
8681
+ 'async' => array(
8682
+ 'mandatory' => true,
8683
+ 'value' => '',
8684
+ ),
8685
+ 'nonce' => array(),
8686
+ 'type' => array(
8687
+ 'value_casei' => 'text/javascript',
8688
+ ),
8689
+ ),
8690
+ 'tag_spec' => array(
8691
+ 'extension_spec' => array(
8692
+ 'allowed_versions' => array(
8693
+ '0.1',
8694
+ 'latest',
8695
+ ),
8696
+ 'deprecated_allow_duplicates' => true,
8697
+ 'name' => 'amp-user-notification',
8698
+ 'requires_usage' => 2,
8699
+ ),
8700
+ ),
8701
+ ),
8702
+ array(
8703
+ 'attr_spec_list' => array(
8704
+ 'async' => array(
8705
+ 'mandatory' => true,
8706
+ 'value' => '',
8707
+ ),
8708
+ 'nonce' => array(),
8709
+ 'type' => array(
8710
+ 'value_casei' => 'text/javascript',
8711
+ ),
8712
+ ),
8713
+ 'tag_spec' => array(
8714
+ 'extension_spec' => array(
8715
+ 'allowed_versions' => array(
8716
+ '0.1',
8717
+ 'latest',
8718
+ ),
8719
+ 'name' => 'amp-video',
8720
+ 'requires_usage' => 3,
8721
+ ),
8722
+ 'spec_name' => 'amp-video extension .js script',
8723
+ ),
8724
+ ),
8725
+ array(
8726
+ 'attr_spec_list' => array(
8727
+ 'async' => array(
8728
+ 'mandatory' => true,
8729
+ 'value' => '',
8730
+ ),
8731
+ 'nonce' => array(),
8732
+ 'type' => array(
8733
+ 'value_casei' => 'text/javascript',
8734
+ ),
8735
+ ),
8736
+ 'tag_spec' => array(
8737
+ 'extension_spec' => array(
8738
+ 'allowed_versions' => array(
8739
+ '0.1',
8740
+ 'latest',
8741
+ ),
8742
+ 'deprecated_allow_duplicates' => true,
8743
+ 'name' => 'amp-vimeo',
8744
+ 'requires_usage' => 2,
8745
+ ),
8746
+ ),
8747
+ ),
8748
+ array(
8749
+ 'attr_spec_list' => array(
8750
+ 'async' => array(
8751
+ 'mandatory' => true,
8752
+ 'value' => '',
8753
+ ),
8754
+ 'nonce' => array(),
8755
+ 'type' => array(
8756
+ 'value_casei' => 'text/javascript',
8757
+ ),
8758
+ ),
8759
+ 'tag_spec' => array(
8760
+ 'extension_spec' => array(
8761
+ 'allowed_versions' => array(
8762
+ '0.1',
8763
+ 'latest',
8764
+ ),
8765
+ 'deprecated_allow_duplicates' => true,
8766
+ 'name' => 'amp-vine',
8767
+ 'requires_usage' => 2,
8768
+ ),
8769
+ ),
8770
+ ),
8771
+ array(
8772
+ 'attr_spec_list' => array(
8773
+ 'async' => array(
8774
+ 'mandatory' => true,
8775
+ 'value' => '',
8776
+ ),
8777
+ 'nonce' => array(),
8778
+ 'type' => array(
8779
+ 'value_casei' => 'text/javascript',
8780
+ ),
8781
+ ),
8782
+ 'tag_spec' => array(
8783
+ 'extension_spec' => array(
8784
+ 'allowed_versions' => array(
8785
+ '0.1',
8786
+ 'latest',
8787
+ ),
8788
+ 'name' => 'amp-vk',
8789
+ ),
8790
+ ),
8791
+ ),
8792
+ array(
8793
+ 'attr_spec_list' => array(
8794
+ 'async' => array(
8795
+ 'mandatory' => true,
8796
+ 'value' => '',
8797
+ ),
8798
+ 'nonce' => array(),
8799
+ 'type' => array(
8800
+ 'value_casei' => 'text/javascript',
8801
+ ),
8802
+ ),
8803
+ 'tag_spec' => array(
8804
+ 'extension_spec' => array(
8805
+ 'allowed_versions' => array(
8806
+ '0.1',
8807
+ 'latest',
8808
+ ),
8809
+ 'name' => 'amp-web-push',
8810
+ ),
8811
+ ),
8812
+ ),
8813
+ array(
8814
+ 'attr_spec_list' => array(
8815
+ 'async' => array(
8816
+ 'mandatory' => true,
8817
+ 'value' => '',
8818
+ ),
8819
+ 'nonce' => array(),
8820
+ 'type' => array(
8821
+ 'value_casei' => 'text/javascript',
8822
+ ),
8823
+ ),
8824
+ 'tag_spec' => array(
8825
+ 'extension_spec' => array(
8826
+ 'allowed_versions' => array(
8827
+ '0.1',
8828
+ 'latest',
8829
+ ),
8830
+ 'name' => 'amp-wistia-player',
8831
+ ),
8832
+ ),
8833
+ ),
8834
+ array(
8835
+ 'attr_spec_list' => array(
8836
+ 'async' => array(
8837
+ 'mandatory' => true,
8838
+ 'value' => '',
8839
+ ),
8840
+ 'nonce' => array(),
8841
+ 'type' => array(
8842
+ 'value_casei' => 'text/javascript',
8843
+ ),
8844
+ ),
8845
+ 'tag_spec' => array(
8846
+ 'extension_spec' => array(
8847
+ 'allowed_versions' => array(
8848
+ '0.1',
8849
+ 'latest',
8850
+ ),
8851
+ 'deprecated_allow_duplicates' => true,
8852
+ 'name' => 'amp-youtube',
8853
+ 'requires_usage' => 2,
8854
+ ),
8855
+ ),
8856
+ ),
8857
+ ),
8858
+ 'section' => array(
8859
+ array(
8860
+ 'attr_spec_list' => array(),
8861
+ 'tag_spec' => array(
8862
+ 'disallowed_ancestor' => array(
8863
+ 'amp-accordion',
8864
+ ),
8865
+ ),
8866
+ ),
8867
+ array(
8868
+ 'attr_spec_list' => array(
8869
+ 'expanded' => array(
8870
+ 'value' => '',
8871
+ ),
8872
+ ),
8873
+ 'tag_spec' => array(
8874
+ 'mandatory_parent' => 'amp-accordion',
8875
+ 'spec_name' => 'amp-accordion > section',
8876
+ ),
8877
+ ),
8878
+ ),
8879
+ 'select' => array(
8880
+ array(
8881
+ 'attr_spec_list' => array(
8882
+ '[autofocus]' => array(),
8883
+ '[disabled]' => array(),
8884
+ '[multiple]' => array(),
8885
+ '[required]' => array(),
8886
+ '[size]' => array(),
8887
+ 'autofocus' => array(),
8888
+ 'disabled' => array(),
8889
+ 'multiple' => array(),
8890
+ 'name' => array(
8891
+ 'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
8892
+ ),
8893
+ 'required' => array(),
8894
+ 'size' => array(),
8895
+ ),
8896
+ 'tag_spec' => array(
8897
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
8898
+ ),
8899
+ ),
8900
+ ),
8901
+ 'slot' => array(
8902
+ array(
8903
+ 'attr_spec_list' => array(
8904
+ 'name' => array(),
8905
+ ),
8906
+ 'tag_spec' => array(),
8907
+ ),
8908
+ ),
8909
+ 'small' => array(
8910
+ array(
8911
+ 'attr_spec_list' => array(),
8912
+ 'tag_spec' => array(),
8913
+ ),
8914
+ ),
8915
+ 'solidcolor' => array(
8916
+ array(
8917
+ 'attr_spec_list' => array(
8918
+ 'alignment-baseline' => array(),
8919
+ 'baseline-shift' => array(),
8920
+ 'clip' => array(),
8921
+ 'clip-path' => array(),
8922
+ 'clip-rule' => array(),
8923
+ 'color' => array(),
8924
+ 'color-interpolation' => array(),
8925
+ 'color-interpolation-filters' => array(),
8926
+ 'color-profile' => array(),
8927
+ 'color-rendering' => array(),
8928
+ 'cursor' => array(),
8929
+ 'direction' => array(),
8930
+ 'display' => array(),
8931
+ 'dominant-baseline' => array(),
8932
+ 'enable-background' => array(),
8933
+ 'fill' => array(),
8934
+ 'fill-opacity' => array(),
8935
+ 'fill-rule' => array(),
8936
+ 'filter' => array(),
8937
+ 'flood-color' => array(),
8938
+ 'flood-opacity' => array(),
8939
+ 'font-family' => array(),
8940
+ 'font-size' => array(),
8941
+ 'font-size-adjust' => array(),
8942
+ 'font-stretch' => array(),
8943
+ 'font-style' => array(),
8944
+ 'font-variant' => array(),
8945
+ 'font-weight' => array(),
8946
+ 'glyph-orientation-horizontal' => array(),
8947
+ 'glyph-orientation-vertical' => array(),
8948
+ 'image-rendering' => array(),
8949
+ 'kerning' => array(),
8950
+ 'letter-spacing' => array(),
8951
+ 'lighting-color' => array(),
8952
+ 'marker-end' => array(),
8953
+ 'marker-mid' => array(),
8954
+ 'marker-start' => array(),
8955
+ 'mask' => array(),
8956
+ 'opacity' => array(),
8957
+ 'overflow' => array(),
8958
+ 'pointer-events' => array(),
8959
+ 'shape-rendering' => array(),
8960
+ 'solid-color' => array(),
8961
+ 'solid-opacity' => array(),
8962
+ 'stop-color' => array(),
8963
+ 'stop-opacity' => array(),
8964
+ 'stroke' => array(),
8965
+ 'stroke-dasharray' => array(),
8966
+ 'stroke-dashoffset' => array(),
8967
+ 'stroke-linecap' => array(),
8968
+ 'stroke-linejoin' => array(),
8969
+ 'stroke-miterlimit' => array(),
8970
+ 'stroke-opacity' => array(),
8971
+ 'stroke-width' => array(),
8972
+ 'style' => array(
8973
+ 'blacklisted_value_regex' => '!important',
8974
+ ),
8975
+ 'text-anchor' => array(),
8976
+ 'text-decoration' => array(),
8977
+ 'text-rendering' => array(),
8978
+ 'unicode-bidi' => array(),
8979
+ 'vector-effect' => array(),
8980
+ 'visibility' => array(),
8981
+ 'word-spacing' => array(),
8982
+ 'writing-mode' => array(),
8983
+ 'xml:lang' => array(),
8984
+ 'xml:space' => array(),
8985
+ 'xmlns' => array(),
8986
+ 'xmlns:xlink' => array(),
8987
+ ),
8988
+ 'tag_spec' => array(
8989
+ 'mandatory_ancestor' => 'svg',
8990
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
8991
+ ),
8992
+ ),
8993
+ ),
8994
+ 'source' => array(
8995
+ array(
8996
+ 'attr_spec_list' => array(
8997
+ '[src]' => array(),
8998
+ '[type]' => array(),
8999
+ 'media' => array(),
9000
+ 'src' => array(
9001
+ 'blacklisted_value_regex' => '__amp_source_origin',
9002
+ 'value_url' => array(
9003
+ 'allow_relative' => true,
9004
+ 'allowed_protocol' => array(
9005
+ 'https',
9006
+ ),
9007
+ ),
9008
+ ),
9009
+ 'type' => array(),
9010
+ ),
9011
+ 'tag_spec' => array(
9012
+ 'mandatory_parent' => 'amp-video',
9013
+ 'spec_name' => 'amp-video > source',
9014
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-video',
9015
+ ),
9016
+ ),
9017
+ array(
9018
+ 'attr_spec_list' => array(
9019
+ '[src]' => array(),
9020
+ '[type]' => array(),
9021
+ 'media' => array(),
9022
+ 'src' => array(
9023
+ 'blacklisted_value_regex' => '__amp_source_origin',
9024
+ 'value_url' => array(
9025
+ 'allow_relative' => true,
9026
+ 'allowed_protocol' => array(
9027
+ 'https',
9028
+ ),
9029
+ ),
9030
+ ),
9031
+ 'type' => array(),
9032
+ ),
9033
+ 'tag_spec' => array(
9034
+ 'mandatory_parent' => 'amp-audio',
9035
+ 'spec_name' => 'amp-audio > source',
9036
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-audio',
9037
+ ),
9038
+ ),
9039
+ array(
9040
+ 'attr_spec_list' => array(
9041
+ 'media' => array(),
9042
+ 'src' => array(
9043
+ 'blacklisted_value_regex' => '__amp_source_origin',
9044
+ 'mandatory' => true,
9045
+ 'value_url' => array(
9046
+ 'allow_relative' => true,
9047
+ 'allowed_protocol' => array(
9048
+ 'https',
9049
+ ),
9050
+ ),
9051
+ ),
9052
+ 'type' => array(
9053
+ 'mandatory' => true,
9054
+ ),
9055
+ ),
9056
+ 'tag_spec' => array(
9057
+ 'mandatory_parent' => 'audio',
9058
+ 'spec_name' => 'audio > source',
9059
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-audio',
9060
+ ),
9061
+ ),
9062
+ array(
9063
+ 'attr_spec_list' => array(
9064
+ 'media' => array(),
9065
+ 'src' => array(
9066
+ 'blacklisted_value_regex' => '__amp_source_origin',
9067
+ 'mandatory' => true,
9068
+ 'value_url' => array(
9069
+ 'allow_relative' => true,
9070
+ 'allowed_protocol' => array(
9071
+ 'https',
9072
+ ),
9073
+ ),
9074
+ ),
9075
+ 'type' => array(
9076
+ 'mandatory' => true,
9077
+ ),
9078
+ ),
9079
+ 'tag_spec' => array(
9080
+ 'mandatory_parent' => 'video',
9081
+ 'spec_name' => 'video > source',
9082
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-video',
9083
+ ),
9084
+ ),
9085
+ array(
9086
+ 'attr_spec_list' => array(
9087
+ '[src]' => array(),
9088
+ '[type]' => array(),
9089
+ 'media' => array(),
9090
+ 'src' => array(
9091
+ 'blacklisted_value_regex' => '__amp_source_origin',
9092
+ 'value_url' => array(
9093
+ 'allow_relative' => true,
9094
+ 'allowed_protocol' => array(
9095
+ 'https',
9096
+ ),
9097
+ ),
9098
+ ),
9099
+ 'type' => array(),
9100
+ ),
9101
+ 'tag_spec' => array(
9102
+ 'mandatory_parent' => 'amp-ima-video',
9103
+ 'requires_extension' => array(
9104
+ 'amp-ima-video',
9105
+ ),
9106
+ 'spec_name' => 'amp-ima-video > source',
9107
+ ),
9108
+ ),
9109
+ ),
9110
+ 'spacer' => array(
9111
+ array(
9112
+ 'attr_spec_list' => array(),
9113
+ 'tag_spec' => array(),
9114
+ ),
9115
+ ),
9116
+ 'span' => array(
9117
+ array(
9118
+ 'attr_spec_list' => array(),
9119
+ 'tag_spec' => array(),
9120
+ ),
9121
+ ),
9122
+ 'stop' => array(
9123
+ array(
9124
+ 'attr_spec_list' => array(
9125
+ 'offset' => array(),
9126
+ 'stop-color' => array(),
9127
+ 'stop-opacity' => array(),
9128
+ 'style' => array(
9129
+ 'blacklisted_value_regex' => '!important',
9130
+ ),
9131
+ ),
9132
+ 'tag_spec' => array(
9133
+ 'mandatory_ancestor' => 'lineargradient',
9134
+ 'spec_name' => 'lineargradient > stop',
9135
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
9136
+ ),
9137
+ ),
9138
+ array(
9139
+ 'attr_spec_list' => array(
9140
+ 'offset' => array(),
9141
+ 'stop-color' => array(),
9142
+ 'stop-opacity' => array(),
9143
+ 'style' => array(
9144
+ 'blacklisted_value_regex' => '!important',
9145
+ ),
9146
+ ),
9147
+ 'tag_spec' => array(
9148
+ 'mandatory_ancestor' => 'radialgradient',
9149
+ 'spec_name' => 'radialgradient > stop',
9150
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
9151
+ ),
9152
+ ),
9153
+ ),
9154
+ 'strike' => array(
9155
+ array(
9156
+ 'attr_spec_list' => array(),
9157
+ 'tag_spec' => array(),
9158
+ ),
9159
+ ),
9160
+ 'strong' => array(
9161
+ array(
9162
+ 'attr_spec_list' => array(),
9163
+ 'tag_spec' => array(),
9164
+ ),
9165
+ ),
9166
+ 'style' => array(
9167
+ array(
9168
+ 'attr_spec_list' => array(
9169
+ 'amp-custom' => array(
9170
+ 'mandatory' => true,
9171
+ 'value' => '',
9172
+ ),
9173
+ 'nonce' => array(),
9174
+ 'type' => array(
9175
+ 'value_casei' => 'text/css',
9176
+ ),
9177
+ ),
9178
+ 'cdata' => array(
9179
+ 'blacklisted_cdata_regex' => array(
9180
+ 'error_message' => 'CSS !important',
9181
+ 'regex' => '!important',
9182
+ ),
9183
+ 'max_bytes' => 50000,
9184
+ 'max_bytes_spec_url' => 'https://www.ampproject.org/docs/reference/spec#maximum-size',
9185
+ ),
9186
+ 'tag_spec' => array(
9187
+ 'mandatory_parent' => 'head',
9188
+ 'spec_name' => 'style amp-custom',
9189
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#stylesheets',
9190
+ 'unique' => true,
9191
+ ),
9192
+ ),
9193
+ array(
9194
+ 'attr_spec_list' => array(
9195
+ 'amp-boilerplate' => array(
9196
+ 'dispatch_key' => 3,
9197
+ 'mandatory' => true,
9198
+ 'value' => '',
9199
+ ),
9200
+ 'nonce' => array(),
9201
+ ),
9202
+ 'cdata' => array(
9203
+ 'cdata_regex' => '\\s*body{-webkit-animation:-amp-start\\s+8s\\s+steps\\(1,end\\)\\s+0s\\s+1\\s+normal\\s+both;-moz-animation:-amp-start\\s+8s\\s+steps\\(1,end\\)\\s+0s\\s+1\\s+normal\\s+both;-ms-animation:-amp-start\\s+8s\\s+steps\\(1,end\\)\\s+0s\\s+1\\s+normal\\s+both;animation:-amp-start\\s+8s\\s+steps\\(1,end\\)\\s+0s\\s+1\\s+normal\\s+both}@-webkit-keyframes\\s+-amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes\\s+-amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes\\s+-amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes\\s+-amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes\\s+-amp-start{from{visibility:hidden}to{visibility:visible}}\\s*',
9204
+ ),
9205
+ 'tag_spec' => array(
9206
+ 'mandatory_alternatives' => 'head > style[amp-boilerplate]',
9207
+ 'mandatory_parent' => 'head',
9208
+ 'spec_name' => 'head > style[amp-boilerplate]',
9209
+ 'spec_url' => 'https://github.com/ampproject/amphtml/blob/master/spec/amp-boilerplate.md',
9210
+ 'unique' => true,
9211
+ ),
9212
+ ),
9213
+ array(
9214
+ 'attr_spec_list' => array(
9215
+ 'amp-boilerplate' => array(
9216
+ 'dispatch_key' => 3,
9217
+ 'mandatory' => true,
9218
+ 'value' => '',
9219
+ ),
9220
+ 'nonce' => array(),
9221
+ ),
9222
+ 'cdata' => array(
9223
+ 'cdata_regex' => '\\s*body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}\\s*',
9224
+ ),
9225
+ 'tag_spec' => array(
9226
+ 'mandatory_alternatives' => 'noscript > style[amp-boilerplate]',
9227
+ 'mandatory_ancestor' => 'head',
9228
+ 'mandatory_parent' => 'noscript',
9229
+ 'spec_name' => 'noscript > style[amp-boilerplate]',
9230
+ 'spec_url' => 'https://github.com/ampproject/amphtml/blob/master/spec/amp-boilerplate.md',
9231
+ 'unique' => true,
9232
+ ),
9233
+ ),
9234
+ array(
9235
+ 'attr_spec_list' => array(
9236
+ 'amp-keyframes' => array(
9237
+ 'dispatch_key' => 1,
9238
+ 'mandatory' => true,
9239
+ 'value' => '',
9240
+ ),
9241
+ ),
9242
+ 'cdata' => array(
9243
+ 'max_bytes' => 500000,
9244
+ 'max_bytes_spec_url' => 'https://www.ampproject.org/docs/reference/spec#keyframes-stylesheet',
9245
+ ),
9246
+ 'tag_spec' => array(
9247
+ 'mandatory_parent' => 'body',
9248
+ 'spec_name' => 'style[amp-keyframes]',
9249
+ 'unique' => true,
9250
+ ),
9251
+ ),
9252
+ ),
9253
+ 'sub' => array(
9254
+ array(
9255
+ 'attr_spec_list' => array(),
9256
+ 'tag_spec' => array(),
9257
+ ),
9258
+ ),
9259
+ 'sup' => array(
9260
+ array(
9261
+ 'attr_spec_list' => array(),
9262
+ 'tag_spec' => array(),
9263
+ ),
9264
+ ),
9265
+ 'svg' => array(
9266
+ array(
9267
+ 'attr_spec_list' => array(
9268
+ 'alignment-baseline' => array(),
9269
+ 'baseline-shift' => array(),
9270
+ 'clip' => array(),
9271
+ 'clip-path' => array(),
9272
+ 'clip-rule' => array(),
9273
+ 'color' => array(),
9274
+ 'color-interpolation' => array(),
9275
+ 'color-interpolation-filters' => array(),
9276
+ 'color-profile' => array(),
9277
+ 'color-rendering' => array(),
9278
+ 'contentscripttype' => array(),
9279
+ 'contentstyletype' => array(),
9280
+ 'cursor' => array(),
9281
+ 'direction' => array(),
9282
+ 'display' => array(),
9283
+ 'dominant-baseline' => array(),
9284
+ 'enable-background' => array(),
9285
+ 'externalresourcesrequired' => array(),
9286
+ 'fill' => array(),
9287
+ 'fill-opacity' => array(),
9288
+ 'fill-rule' => array(),
9289
+ 'filter' => array(),
9290
+ 'flood-color' => array(),
9291
+ 'flood-opacity' => array(),
9292
+ 'font-family' => array(),
9293
+ 'font-size' => array(),
9294
+ 'font-size-adjust' => array(),
9295
+ 'font-stretch' => array(),
9296
+ 'font-style' => array(),
9297
+ 'font-variant' => array(),
9298
+ 'font-weight' => array(),
9299
+ 'glyph-orientation-horizontal' => array(),
9300
+ 'glyph-orientation-vertical' => array(),
9301
+ 'height' => array(),
9302
+ 'image-rendering' => array(),
9303
+ 'kerning' => array(),
9304
+ 'letter-spacing' => array(),
9305
+ 'lighting-color' => array(),
9306
+ 'marker-end' => array(),
9307
+ 'marker-mid' => array(),
9308
+ 'marker-start' => array(),
9309
+ 'mask' => array(),
9310
+ 'opacity' => array(),
9311
+ 'overflow' => array(),
9312
+ 'pointer-events' => array(),
9313
+ 'preserveaspectratio' => array(),
9314
+ 'requiredextensions' => array(),
9315
+ 'requiredfeatures' => array(),
9316
+ 'shape-rendering' => array(),
9317
+ 'stop-color' => array(),
9318
+ 'stop-opacity' => array(),
9319
+ 'stroke' => array(),
9320
+ 'stroke-dasharray' => array(),
9321
+ 'stroke-dashoffset' => array(),
9322
+ 'stroke-linecap' => array(),
9323
+ 'stroke-linejoin' => array(),
9324
+ 'stroke-miterlimit' => array(),
9325
+ 'stroke-opacity' => array(),
9326
+ 'stroke-width' => array(),
9327
+ 'systemlanguage' => array(),
9328
+ 'text-anchor' => array(),
9329
+ 'text-decoration' => array(),
9330
+ 'text-rendering' => array(),
9331
+ 'unicode-bidi' => array(),
9332
+ 'vector-effect' => array(),
9333
+ 'version' => array(
9334
+ 'value_regex' => '(1.0|1.1)',
9335
+ ),
9336
+ 'viewbox' => array(),
9337
+ 'visibility' => array(),
9338
+ 'width' => array(),
9339
+ 'word-spacing' => array(),
9340
+ 'writing-mode' => array(),
9341
+ 'x' => array(),
9342
+ 'xml:lang' => array(),
9343
+ 'xml:space' => array(),
9344
+ 'xmlns' => array(),
9345
+ 'xmlns:xlink' => array(),
9346
+ 'y' => array(),
9347
+ 'zoomandpan' => array(),
9348
+ ),
9349
+ 'tag_spec' => array(
9350
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
9351
+ ),
9352
+ ),
9353
+ ),
9354
+ 'switch' => array(
9355
+ array(
9356
+ 'attr_spec_list' => array(
9357
+ 'alignment-baseline' => array(),
9358
+ 'baseline-shift' => array(),
9359
+ 'clip' => array(),
9360
+ 'clip-path' => array(),
9361
+ 'clip-rule' => array(),
9362
+ 'color' => array(),
9363
+ 'color-interpolation' => array(),
9364
+ 'color-interpolation-filters' => array(),
9365
+ 'color-profile' => array(),
9366
+ 'color-rendering' => array(),
9367
+ 'cursor' => array(),
9368
+ 'direction' => array(),
9369
+ 'display' => array(),
9370
+ 'dominant-baseline' => array(),
9371
+ 'enable-background' => array(),
9372
+ 'fill' => array(),
9373
+ 'fill-opacity' => array(),
9374
+ 'fill-rule' => array(),
9375
+ 'filter' => array(),
9376
+ 'flood-color' => array(),
9377
+ 'flood-opacity' => array(),
9378
+ 'font-family' => array(),
9379
+ 'font-size' => array(),
9380
+ 'font-size-adjust' => array(),
9381
+ 'font-stretch' => array(),
9382
+ 'font-style' => array(),
9383
+ 'font-variant' => array(),
9384
+ 'font-weight' => array(),
9385
+ 'glyph-orientation-horizontal' => array(),
9386
+ 'glyph-orientation-vertical' => array(),
9387
+ 'image-rendering' => array(),
9388
+ 'kerning' => array(),
9389
+ 'letter-spacing' => array(),
9390
+ 'lighting-color' => array(),
9391
+ 'marker-end' => array(),
9392
+ 'marker-mid' => array(),
9393
+ 'marker-start' => array(),
9394
+ 'mask' => array(),
9395
+ 'opacity' => array(),
9396
+ 'overflow' => array(),
9397
+ 'pointer-events' => array(),
9398
+ 'requiredextensions' => array(),
9399
+ 'requiredfeatures' => array(),
9400
+ 'shape-rendering' => array(),
9401
+ 'stop-color' => array(),
9402
+ 'stop-opacity' => array(),
9403
+ 'stroke' => array(),
9404
+ 'stroke-dasharray' => array(),
9405
+ 'stroke-dashoffset' => array(),
9406
+ 'stroke-linecap' => array(),
9407
+ 'stroke-linejoin' => array(),
9408
+ 'stroke-miterlimit' => array(),
9409
+ 'stroke-opacity' => array(),
9410
+ 'stroke-width' => array(),
9411
+ 'style' => array(
9412
+ 'blacklisted_value_regex' => '!important',
9413
+ ),
9414
+ 'systemlanguage' => array(),
9415
+ 'text-anchor' => array(),
9416
+ 'text-decoration' => array(),
9417
+ 'text-rendering' => array(),
9418
+ 'unicode-bidi' => array(),
9419
+ 'vector-effect' => array(),
9420
+ 'visibility' => array(),
9421
+ 'word-spacing' => array(),
9422
+ 'writing-mode' => array(),
9423
+ 'xml:lang' => array(),
9424
+ 'xml:space' => array(),
9425
+ 'xmlns' => array(),
9426
+ 'xmlns:xlink' => array(),
9427
+ ),
9428
+ 'tag_spec' => array(
9429
+ 'mandatory_ancestor' => 'svg',
9430
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
9431
+ ),
9432
+ ),
9433
+ ),
9434
+ 'symbol' => array(
9435
+ array(
9436
+ 'attr_spec_list' => array(
9437
+ 'alignment-baseline' => array(),
9438
+ 'baseline-shift' => array(),
9439
+ 'clip' => array(),
9440
+ 'clip-path' => array(),
9441
+ 'clip-rule' => array(),
9442
+ 'color' => array(),
9443
+ 'color-interpolation' => array(),
9444
+ 'color-interpolation-filters' => array(),
9445
+ 'color-profile' => array(),
9446
+ 'color-rendering' => array(),
9447
+ 'cursor' => array(),
9448
+ 'direction' => array(),
9449
+ 'display' => array(),
9450
+ 'dominant-baseline' => array(),
9451
+ 'enable-background' => array(),
9452
+ 'externalresourcesrequired' => array(),
9453
+ 'fill' => array(),
9454
+ 'fill-opacity' => array(),
9455
+ 'fill-rule' => array(),
9456
+ 'filter' => array(),
9457
+ 'flood-color' => array(),
9458
+ 'flood-opacity' => array(),
9459
+ 'font-family' => array(),
9460
+ 'font-size' => array(),
9461
+ 'font-size-adjust' => array(),
9462
+ 'font-stretch' => array(),
9463
+ 'font-style' => array(),
9464
+ 'font-variant' => array(),
9465
+ 'font-weight' => array(),
9466
+ 'glyph-orientation-horizontal' => array(),
9467
+ 'glyph-orientation-vertical' => array(),
9468
+ 'image-rendering' => array(),
9469
+ 'kerning' => array(),
9470
+ 'letter-spacing' => array(),
9471
+ 'lighting-color' => array(),
9472
+ 'marker-end' => array(),
9473
+ 'marker-mid' => array(),
9474
+ 'marker-start' => array(),
9475
+ 'mask' => array(),
9476
+ 'opacity' => array(),
9477
+ 'overflow' => array(),
9478
+ 'pointer-events' => array(),
9479
+ 'preserveaspectratio' => array(),
9480
+ 'shape-rendering' => array(),
9481
+ 'stop-color' => array(),
9482
+ 'stop-opacity' => array(),
9483
+ 'stroke' => array(),
9484
+ 'stroke-dasharray' => array(),
9485
+ 'stroke-dashoffset' => array(),
9486
+ 'stroke-linecap' => array(),
9487
+ 'stroke-linejoin' => array(),
9488
+ 'stroke-miterlimit' => array(),
9489
+ 'stroke-opacity' => array(),
9490
+ 'stroke-width' => array(),
9491
+ 'style' => array(
9492
+ 'blacklisted_value_regex' => '!important',
9493
+ ),
9494
+ 'text-anchor' => array(),
9495
+ 'text-decoration' => array(),
9496
+ 'text-rendering' => array(),
9497
+ 'unicode-bidi' => array(),
9498
+ 'vector-effect' => array(),
9499
+ 'viewbox' => array(),
9500
+ 'visibility' => array(),
9501
+ 'word-spacing' => array(),
9502
+ 'writing-mode' => array(),
9503
+ 'xml:lang' => array(),
9504
+ 'xml:space' => array(),
9505
+ 'xmlns' => array(),
9506
+ 'xmlns:xlink' => array(),
9507
+ ),
9508
+ 'tag_spec' => array(
9509
+ 'mandatory_ancestor' => 'svg',
9510
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
9511
+ ),
9512
+ ),
9513
+ ),
9514
+ 'table' => array(
9515
+ array(
9516
+ 'attr_spec_list' => array(
9517
+ 'align' => array(),
9518
+ 'bgcolor' => array(),
9519
+ 'border' => array(
9520
+ 'value_regex' => '0|1',
9521
+ ),
9522
+ 'cellpadding' => array(),
9523
+ 'cellspacing' => array(),
9524
+ 'sortable' => array(),
9525
+ 'width' => array(),
9526
+ ),
9527
+ 'tag_spec' => array(),
9528
+ ),
9529
+ ),
9530
+ 'tbody' => array(
9531
+ array(
9532
+ 'attr_spec_list' => array(),
9533
+ 'tag_spec' => array(),
9534
+ ),
9535
+ ),
9536
+ 'td' => array(
9537
+ array(
9538
+ 'attr_spec_list' => array(
9539
+ 'align' => array(),
9540
+ 'bgcolor' => array(),
9541
+ 'colspan' => array(),
9542
+ 'headers' => array(),
9543
+ 'height' => array(),
9544
+ 'rowspan' => array(),
9545
+ 'valign' => array(),
9546
+ 'width' => array(),
9547
+ ),
9548
+ 'tag_spec' => array(),
9549
+ ),
9550
+ ),
9551
+ 'template' => array(
9552
+ array(
9553
+ 'attr_spec_list' => array(
9554
+ 'type' => array(
9555
+ 'mandatory' => true,
9556
+ 'value' => 'amp-mustache',
9557
+ ),
9558
+ ),
9559
+ 'tag_spec' => array(
9560
+ 'disallowed_ancestor' => array(
9561
+ 'template',
9562
+ 'amp-story-auto-ads',
9563
+ 'form > div [submit-success][template]',
9564
+ 'form > div [submit-error][template]',
9565
+ ),
9566
+ 'requires_extension' => array(
9567
+ 'amp-mustache',
9568
+ ),
9569
+ ),
9570
+ ),
9571
+ array(
9572
+ 'attr_spec_list' => array(
9573
+ 'type' => array(
9574
+ 'mandatory' => true,
9575
+ 'value' => 'amp-mustache',
9576
+ ),
9577
+ ),
9578
+ 'tag_spec' => array(
9579
+ 'mandatory_parent' => 'amp-story-auto-ads',
9580
+ 'requires_extension' => array(
9581
+ 'amp-mustache',
9582
+ ),
9583
+ 'spec_name' => 'amp-story-auto-ads > template',
9584
+ ),
9585
+ ),
9586
+ ),
9587
+ 'text' => array(
9588
+ array(
9589
+ 'attr_spec_list' => array(
9590
+ 'alignment-baseline' => array(),
9591
+ 'baseline-shift' => array(),
9592
+ 'clip' => array(),
9593
+ 'clip-path' => array(),
9594
+ 'clip-rule' => array(),
9595
+ 'color' => array(),
9596
+ 'color-interpolation' => array(),
9597
+ 'color-interpolation-filters' => array(),
9598
+ 'color-profile' => array(),
9599
+ 'color-rendering' => array(),
9600
+ 'cursor' => array(),
9601
+ 'direction' => array(),
9602
+ 'display' => array(),
9603
+ 'dominant-baseline' => array(),
9604
+ 'dx' => array(),
9605
+ 'dy' => array(),
9606
+ 'enable-background' => array(),
9607
+ 'externalresourcesrequired' => array(),
9608
+ 'fill' => array(),
9609
+ 'fill-opacity' => array(),
9610
+ 'fill-rule' => array(),
9611
+ 'filter' => array(),
9612
+ 'flood-color' => array(),
9613
+ 'flood-opacity' => array(),
9614
+ 'font-family' => array(),
9615
+ 'font-size' => array(),
9616
+ 'font-size-adjust' => array(),
9617
+ 'font-stretch' => array(),
9618
+ 'font-style' => array(),
9619
+ 'font-variant' => array(),
9620
+ 'font-weight' => array(),
9621
+ 'glyph-orientation-horizontal' => array(),
9622
+ 'glyph-orientation-vertical' => array(),
9623
+ 'image-rendering' => array(),
9624
+ 'kerning' => array(),
9625
+ 'lengthadjust' => array(),
9626
+ 'letter-spacing' => array(),
9627
+ 'lighting-color' => array(),
9628
+ 'marker-end' => array(),
9629
+ 'marker-mid' => array(),
9630
+ 'marker-start' => array(),
9631
+ 'mask' => array(),
9632
+ 'opacity' => array(),
9633
+ 'overflow' => array(),
9634
+ 'pointer-events' => array(),
9635
+ 'requiredextensions' => array(),
9636
+ 'requiredfeatures' => array(),
9637
+ 'rotate' => array(),
9638
+ 'shape-rendering' => array(),
9639
+ 'stop-color' => array(),
9640
+ 'stop-opacity' => array(),
9641
+ 'stroke' => array(),
9642
+ 'stroke-dasharray' => array(),
9643
+ 'stroke-dashoffset' => array(),
9644
+ 'stroke-linecap' => array(),
9645
+ 'stroke-linejoin' => array(),
9646
+ 'stroke-miterlimit' => array(),
9647
+ 'stroke-opacity' => array(),
9648
+ 'stroke-width' => array(),
9649
+ 'style' => array(
9650
+ 'blacklisted_value_regex' => '!important',
9651
+ ),
9652
+ 'systemlanguage' => array(),
9653
+ 'text-anchor' => array(),
9654
+ 'text-decoration' => array(),
9655
+ 'text-rendering' => array(),
9656
+ 'textlength' => array(),
9657
+ 'transform' => array(),
9658
+ 'unicode-bidi' => array(),
9659
+ 'vector-effect' => array(),
9660
+ 'visibility' => array(),
9661
+ 'word-spacing' => array(),
9662
+ 'writing-mode' => array(),
9663
+ 'x' => array(),
9664
+ 'xml:lang' => array(),
9665
+ 'xml:space' => array(),
9666
+ 'xmlns' => array(),
9667
+ 'xmlns:xlink' => array(),
9668
+ 'y' => array(),
9669
+ ),
9670
+ 'tag_spec' => array(
9671
+ 'mandatory_ancestor' => 'svg',
9672
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
9673
+ ),
9674
+ ),
9675
+ ),
9676
+ 'textarea' => array(
9677
+ array(
9678
+ 'attr_spec_list' => array(
9679
+ '[autocomplete]' => array(),
9680
+ '[autofocus]' => array(),
9681
+ '[cols]' => array(),
9682
+ '[disabled]' => array(),
9683
+ '[maxlength]' => array(),
9684
+ '[minlength]' => array(),
9685
+ '[placeholder]' => array(),
9686
+ '[readonly]' => array(),
9687
+ '[required]' => array(),
9688
+ '[rows]' => array(),
9689
+ '[selectiondirection]' => array(),
9690
+ '[selectionend]' => array(),
9691
+ '[selectionstart]' => array(),
9692
+ '[spellcheck]' => array(),
9693
+ '[wrap]' => array(),
9694
+ 'autocomplete' => array(),
9695
+ 'autofocus' => array(),
9696
+ 'cols' => array(),
9697
+ 'disabled' => array(),
9698
+ 'maxlength' => array(),
9699
+ 'minlength' => array(),
9700
+ 'name' => array(
9701
+ 'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
9702
+ ),
9703
+ 'placeholder' => array(),
9704
+ 'readonly' => array(),
9705
+ 'required' => array(),
9706
+ 'rows' => array(),
9707
+ 'selectiondirection' => array(),
9708
+ 'selectionend' => array(),
9709
+ 'selectionstart' => array(),
9710
+ 'spellcheck' => array(),
9711
+ 'wrap' => array(),
9712
+ ),
9713
+ 'tag_spec' => array(
9714
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-form',
9715
+ ),
9716
+ ),
9717
+ ),
9718
+ 'textpath' => array(
9719
+ array(
9720
+ 'attr_spec_list' => array(
9721
+ 'alignment-baseline' => array(),
9722
+ 'baseline-shift' => array(),
9723
+ 'clip' => array(),
9724
+ 'clip-path' => array(),
9725
+ 'clip-rule' => array(),
9726
+ 'color' => array(),
9727
+ 'color-interpolation' => array(),
9728
+ 'color-interpolation-filters' => array(),
9729
+ 'color-profile' => array(),
9730
+ 'color-rendering' => array(),
9731
+ 'cursor' => array(),
9732
+ 'direction' => array(),
9733
+ 'display' => array(),
9734
+ 'dominant-baseline' => array(),
9735
+ 'enable-background' => array(),
9736
+ 'externalresourcesrequired' => array(),
9737
+ 'fill' => array(),
9738
+ 'fill-opacity' => array(),
9739
+ 'fill-rule' => array(),
9740
+ 'filter' => array(),
9741
+ 'flood-color' => array(),
9742
+ 'flood-opacity' => array(),
9743
+ 'font-family' => array(),
9744
+ 'font-size' => array(),
9745
+ 'font-size-adjust' => array(),
9746
+ 'font-stretch' => array(),
9747
+ 'font-style' => array(),
9748
+ 'font-variant' => array(),
9749
+ 'font-weight' => array(),
9750
+ 'glyph-orientation-horizontal' => array(),
9751
+ 'glyph-orientation-vertical' => array(),
9752
+ 'image-rendering' => array(),
9753
+ 'kerning' => array(),
9754
+ 'letter-spacing' => array(),
9755
+ 'lighting-color' => array(),
9756
+ 'marker-end' => array(),
9757
+ 'marker-mid' => array(),
9758
+ 'marker-start' => array(),
9759
+ 'mask' => array(),
9760
+ 'method' => array(),
9761
+ 'opacity' => array(),
9762
+ 'overflow' => array(),
9763
+ 'pointer-events' => array(),
9764
+ 'requiredextensions' => array(),
9765
+ 'requiredfeatures' => array(),
9766
+ 'shape-rendering' => array(),
9767
+ 'spacing' => array(),
9768
+ 'startoffset' => array(),
9769
+ 'stop-color' => array(),
9770
+ 'stop-opacity' => array(),
9771
+ 'stroke' => array(),
9772
+ 'stroke-dasharray' => array(),
9773
+ 'stroke-dashoffset' => array(),
9774
+ 'stroke-linecap' => array(),
9775
+ 'stroke-linejoin' => array(),
9776
+ 'stroke-miterlimit' => array(),
9777
+ 'stroke-opacity' => array(),
9778
+ 'stroke-width' => array(),
9779
+ 'style' => array(
9780
+ 'blacklisted_value_regex' => '!important',
9781
+ ),
9782
+ 'systemlanguage' => array(),
9783
+ 'text-anchor' => array(),
9784
+ 'text-decoration' => array(),
9785
+ 'text-rendering' => array(),
9786
+ 'unicode-bidi' => array(),
9787
+ 'vector-effect' => array(),
9788
+ 'visibility' => array(),
9789
+ 'word-spacing' => array(),
9790
+ 'writing-mode' => array(),
9791
+ 'xlink:actuate' => array(),
9792
+ 'xlink:arcrole' => array(),
9793
+ 'xlink:href' => array(
9794
+ 'alternative_names' => array(
9795
+ 'href',
9796
+ ),
9797
+ 'value_url' => array(
9798
+ 'allow_empty' => false,
9799
+ 'allow_relative' => true,
9800
+ 'allowed_protocol' => array(
9801
+ 'http',
9802
+ 'https',
9803
+ ),
9804
+ ),
9805
+ ),
9806
+ 'xlink:role' => array(),
9807
+ 'xlink:show' => array(),
9808
+ 'xlink:title' => array(),
9809
+ 'xlink:type' => array(),
9810
+ 'xml:lang' => array(),
9811
+ 'xml:space' => array(),
9812
+ 'xmlns' => array(),
9813
+ 'xmlns:xlink' => array(),
9814
+ ),
9815
+ 'tag_spec' => array(
9816
+ 'mandatory_ancestor' => 'svg',
9817
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
9818
+ ),
9819
+ ),
9820
+ ),
9821
+ 'tfoot' => array(
9822
+ array(
9823
+ 'attr_spec_list' => array(),
9824
+ 'tag_spec' => array(),
9825
+ ),
9826
+ ),
9827
+ 'th' => array(
9828
+ array(
9829
+ 'attr_spec_list' => array(
9830
+ 'abbr' => array(),
9831
+ 'align' => array(),
9832
+ 'bgcolor' => array(),
9833
+ 'colspan' => array(),
9834
+ 'headers' => array(),
9835
+ 'height' => array(),
9836
+ 'rowspan' => array(),
9837
+ 'scope' => array(),
9838
+ 'sorted' => array(),
9839
+ 'valign' => array(),
9840
+ 'width' => array(),
9841
+ ),
9842
+ 'tag_spec' => array(),
9843
+ ),
9844
+ ),
9845
+ 'thead' => array(
9846
+ array(
9847
+ 'attr_spec_list' => array(),
9848
+ 'tag_spec' => array(),
9849
+ ),
9850
+ ),
9851
+ 'time' => array(
9852
+ array(
9853
+ 'attr_spec_list' => array(
9854
+ 'datetime' => array(),
9855
+ ),
9856
+ 'tag_spec' => array(),
9857
+ ),
9858
+ ),
9859
+ 'title' => array(
9860
+ array(
9861
+ 'attr_spec_list' => array(),
9862
+ 'tag_spec' => array(
9863
+ 'spec_name' => 'title',
9864
+ ),
9865
+ ),
9866
+ array(
9867
+ 'attr_spec_list' => array(
9868
+ 'style' => array(
9869
+ 'blacklisted_value_regex' => '!important',
9870
+ ),
9871
+ 'xml:lang' => array(),
9872
+ 'xml:space' => array(),
9873
+ 'xmlns' => array(),
9874
+ 'xmlns:xlink' => array(),
9875
+ ),
9876
+ 'tag_spec' => array(
9877
+ 'mandatory_ancestor' => 'svg',
9878
+ 'spec_name' => 'svg title',
9879
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
9880
+ ),
9881
+ ),
9882
+ ),
9883
+ 'tr' => array(
9884
+ array(
9885
+ 'attr_spec_list' => array(
9886
+ 'align' => array(),
9887
+ 'bgcolor' => array(),
9888
+ 'height' => array(),
9889
+ 'valign' => array(),
9890
+ ),
9891
+ 'tag_spec' => array(),
9892
+ ),
9893
+ ),
9894
+ 'track' => array(
9895
+ array(
9896
+ 'attr_spec_list' => array(
9897
+ 'default' => array(
9898
+ 'value' => '',
9899
+ ),
9900
+ 'kind' => array(
9901
+ 'value_regex' => '(captions|descriptions|chapters|metadata)',
9902
+ ),
9903
+ 'label' => array(),
9904
+ 'src' => array(
9905
+ 'blacklisted_value_regex' => '__amp_source_origin',
9906
+ 'mandatory' => true,
9907
+ 'value_url' => array(
9908
+ 'allow_relative' => false,
9909
+ 'allowed_protocol' => array(
9910
+ 'https',
9911
+ ),
9912
+ ),
9913
+ ),
9914
+ 'srclang' => array(),
9915
+ ),
9916
+ 'tag_spec' => array(
9917
+ 'mandatory_parent' => 'audio',
9918
+ 'spec_name' => 'audio > track',
9919
+ ),
9920
+ ),
9921
+ array(
9922
+ 'attr_spec_list' => array(
9923
+ 'default' => array(
9924
+ 'value' => '',
9925
+ ),
9926
+ 'kind' => array(
9927
+ 'mandatory' => true,
9928
+ 'value_casei' => 'subtitles',
9929
+ ),
9930
+ 'label' => array(),
9931
+ 'src' => array(
9932
+ 'blacklisted_value_regex' => '__amp_source_origin',
9933
+ 'mandatory' => true,
9934
+ 'value_url' => array(
9935
+ 'allow_relative' => false,
9936
+ 'allowed_protocol' => array(
9937
+ 'https',
9938
+ ),
9939
+ ),
9940
+ ),
9941
+ 'srclang' => array(
9942
+ 'mandatory' => true,
9943
+ ),
9944
+ ),
9945
+ 'tag_spec' => array(
9946
+ 'mandatory_parent' => 'audio',
9947
+ 'spec_name' => 'audio > track[kind=subtitles]',
9948
+ ),
9949
+ ),
9950
+ array(
9951
+ 'attr_spec_list' => array(
9952
+ 'default' => array(
9953
+ 'value' => '',
9954
+ ),
9955
+ 'kind' => array(
9956
+ 'value_regex' => '(captions|descriptions|chapters|metadata)',
9957
+ ),
9958
+ 'label' => array(),
9959
+ 'src' => array(
9960
+ 'blacklisted_value_regex' => '__amp_source_origin',
9961
+ 'mandatory' => true,
9962
+ 'value_url' => array(
9963
+ 'allow_relative' => false,
9964
+ 'allowed_protocol' => array(
9965
+ 'https',
9966
+ ),
9967
+ ),
9968
+ ),
9969
+ 'srclang' => array(),
9970
+ ),
9971
+ 'tag_spec' => array(
9972
+ 'mandatory_parent' => 'video',
9973
+ 'spec_name' => 'video > track',
9974
+ ),
9975
+ ),
9976
+ array(
9977
+ 'attr_spec_list' => array(
9978
+ 'default' => array(
9979
+ 'value' => '',
9980
+ ),
9981
+ 'kind' => array(
9982
+ 'mandatory' => true,
9983
+ 'value_casei' => 'subtitles',
9984
+ ),
9985
+ 'label' => array(),
9986
+ 'src' => array(
9987
+ 'blacklisted_value_regex' => '__amp_source_origin',
9988
+ 'mandatory' => true,
9989
+ 'value_url' => array(
9990
+ 'allow_relative' => false,
9991
+ 'allowed_protocol' => array(
9992
+ 'https',
9993
+ ),
9994
+ ),
9995
+ ),
9996
+ 'srclang' => array(
9997
+ 'mandatory' => true,
9998
+ ),
9999
+ ),
10000
+ 'tag_spec' => array(
10001
+ 'mandatory_parent' => 'video',
10002
+ 'spec_name' => 'video > track[kind=subtitles]',
10003
+ ),
10004
+ ),
10005
+ array(
10006
+ 'attr_spec_list' => array(
10007
+ '[label]' => array(),
10008
+ '[src]' => array(),
10009
+ '[srclang]' => array(),
10010
+ 'default' => array(
10011
+ 'value' => '',
10012
+ ),
10013
+ 'kind' => array(
10014
+ 'value_regex' => '(captions|descriptions|chapters|metadata)',
10015
+ ),
10016
+ 'label' => array(),
10017
+ 'src' => array(
10018
+ 'blacklisted_value_regex' => '__amp_source_origin',
10019
+ 'mandatory' => true,
10020
+ 'value_url' => array(
10021
+ 'allow_relative' => false,
10022
+ 'allowed_protocol' => array(
10023
+ 'https',
10024
+ ),
10025
+ ),
10026
+ ),
10027
+ 'srclang' => array(),
10028
+ ),
10029
+ 'tag_spec' => array(
10030
+ 'mandatory_parent' => 'amp-audio',
10031
+ 'spec_name' => 'amp-audio > track',
10032
+ ),
10033
+ ),
10034
+ array(
10035
+ 'attr_spec_list' => array(
10036
+ '[label]' => array(),
10037
+ '[src]' => array(),
10038
+ '[srclang]' => array(),
10039
+ 'default' => array(
10040
+ 'value' => '',
10041
+ ),
10042
+ 'kind' => array(
10043
+ 'mandatory' => true,
10044
+ 'value_casei' => 'subtitles',
10045
+ ),
10046
+ 'label' => array(),
10047
+ 'src' => array(
10048
+ 'blacklisted_value_regex' => '__amp_source_origin',
10049
+ 'mandatory' => true,
10050
+ 'value_url' => array(
10051
+ 'allow_relative' => false,
10052
+ 'allowed_protocol' => array(
10053
+ 'https',
10054
+ ),
10055
+ ),
10056
+ ),
10057
+ 'srclang' => array(
10058
+ 'mandatory' => true,
10059
+ ),
10060
+ ),
10061
+ 'tag_spec' => array(
10062
+ 'mandatory_parent' => 'amp-audio',
10063
+ 'spec_name' => 'amp-audio > track[kind=subtitles]',
10064
+ ),
10065
+ ),
10066
+ array(
10067
+ 'attr_spec_list' => array(
10068
+ '[label]' => array(),
10069
+ '[src]' => array(),
10070
+ '[srclang]' => array(),
10071
+ 'default' => array(
10072
+ 'value' => '',
10073
+ ),
10074
+ 'kind' => array(
10075
+ 'value_regex' => '(captions|descriptions|chapters|metadata)',
10076
+ ),
10077
+ 'label' => array(),
10078
+ 'src' => array(
10079
+ 'blacklisted_value_regex' => '__amp_source_origin',
10080
+ 'mandatory' => true,
10081
+ 'value_url' => array(
10082
+ 'allow_relative' => false,
10083
+ 'allowed_protocol' => array(
10084
+ 'https',
10085
+ ),
10086
+ ),
10087
+ ),
10088
+ 'srclang' => array(),
10089
+ ),
10090
+ 'tag_spec' => array(
10091
+ 'mandatory_parent' => 'amp-video',
10092
+ 'spec_name' => 'amp-video > track',
10093
+ ),
10094
+ ),
10095
+ array(
10096
+ 'attr_spec_list' => array(
10097
+ '[label]' => array(),
10098
+ '[src]' => array(),
10099
+ '[srclang]' => array(),
10100
+ 'default' => array(
10101
+ 'value' => '',
10102
+ ),
10103
+ 'kind' => array(
10104
+ 'mandatory' => true,
10105
+ 'value_casei' => 'subtitles',
10106
+ ),
10107
+ 'label' => array(),
10108
+ 'src' => array(
10109
+ 'blacklisted_value_regex' => '__amp_source_origin',
10110
+ 'mandatory' => true,
10111
+ 'value_url' => array(
10112
+ 'allow_relative' => false,
10113
+ 'allowed_protocol' => array(
10114
+ 'https',
10115
+ ),
10116
+ ),
10117
+ ),
10118
+ 'srclang' => array(
10119
+ 'mandatory' => true,
10120
+ ),
10121
+ ),
10122
+ 'tag_spec' => array(
10123
+ 'mandatory_parent' => 'amp-video',
10124
+ 'spec_name' => 'amp-video > track[kind=subtitles]',
10125
+ ),
10126
+ ),
10127
+ array(
10128
+ 'attr_spec_list' => array(
10129
+ '[label]' => array(),
10130
+ '[src]' => array(),
10131
+ '[srclang]' => array(),
10132
+ 'default' => array(
10133
+ 'value' => '',
10134
+ ),
10135
+ 'kind' => array(
10136
+ 'mandatory' => true,
10137
+ 'value_casei' => 'subtitles',
10138
+ ),
10139
+ 'label' => array(),
10140
+ 'src' => array(
10141
+ 'blacklisted_value_regex' => '__amp_source_origin',
10142
+ 'mandatory' => true,
10143
+ 'value_url' => array(
10144
+ 'allow_relative' => false,
10145
+ 'allowed_protocol' => array(
10146
+ 'https',
10147
+ ),
10148
+ ),
10149
+ ),
10150
+ 'srclang' => array(
10151
+ 'mandatory' => true,
10152
+ ),
10153
+ ),
10154
+ 'tag_spec' => array(
10155
+ 'mandatory_parent' => 'amp-ima-video',
10156
+ 'spec_name' => 'amp-ima-video > track[kind=subtitles]',
10157
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-ima-video',
10158
+ ),
10159
+ ),
10160
+ ),
10161
+ 'tref' => array(
10162
+ array(
10163
+ 'attr_spec_list' => array(
10164
+ 'alignment-baseline' => array(),
10165
+ 'baseline-shift' => array(),
10166
+ 'clip' => array(),
10167
+ 'clip-path' => array(),
10168
+ 'clip-rule' => array(),
10169
+ 'color' => array(),
10170
+ 'color-interpolation' => array(),
10171
+ 'color-interpolation-filters' => array(),
10172
+ 'color-profile' => array(),
10173
+ 'color-rendering' => array(),
10174
+ 'cursor' => array(),
10175
+ 'direction' => array(),
10176
+ 'display' => array(),
10177
+ 'dominant-baseline' => array(),
10178
+ 'enable-background' => array(),
10179
+ 'externalresourcesrequired' => array(),
10180
+ 'fill' => array(),
10181
+ 'fill-opacity' => array(),
10182
+ 'fill-rule' => array(),
10183
+ 'filter' => array(),
10184
+ 'flood-color' => array(),
10185
+ 'flood-opacity' => array(),
10186
+ 'font-family' => array(),
10187
+ 'font-size' => array(),
10188
+ 'font-size-adjust' => array(),
10189
+ 'font-stretch' => array(),
10190
+ 'font-style' => array(),
10191
+ 'font-variant' => array(),
10192
+ 'font-weight' => array(),
10193
+ 'glyph-orientation-horizontal' => array(),
10194
+ 'glyph-orientation-vertical' => array(),
10195
+ 'image-rendering' => array(),
10196
+ 'kerning' => array(),
10197
+ 'letter-spacing' => array(),
10198
+ 'lighting-color' => array(),
10199
+ 'marker-end' => array(),
10200
+ 'marker-mid' => array(),
10201
+ 'marker-start' => array(),
10202
+ 'mask' => array(),
10203
+ 'opacity' => array(),
10204
+ 'overflow' => array(),
10205
+ 'pointer-events' => array(),
10206
+ 'requiredextensions' => array(),
10207
+ 'requiredfeatures' => array(),
10208
+ 'shape-rendering' => array(),
10209
+ 'stop-color' => array(),
10210
+ 'stop-opacity' => array(),
10211
+ 'stroke' => array(),
10212
+ 'stroke-dasharray' => array(),
10213
+ 'stroke-dashoffset' => array(),
10214
+ 'stroke-linecap' => array(),
10215
+ 'stroke-linejoin' => array(),
10216
+ 'stroke-miterlimit' => array(),
10217
+ 'stroke-opacity' => array(),
10218
+ 'stroke-width' => array(),
10219
+ 'style' => array(
10220
+ 'blacklisted_value_regex' => '!important',
10221
+ ),
10222
+ 'systemlanguage' => array(),
10223
+ 'text-anchor' => array(),
10224
+ 'text-decoration' => array(),
10225
+ 'text-rendering' => array(),
10226
+ 'unicode-bidi' => array(),
10227
+ 'vector-effect' => array(),
10228
+ 'visibility' => array(),
10229
+ 'word-spacing' => array(),
10230
+ 'writing-mode' => array(),
10231
+ 'xlink:actuate' => array(),
10232
+ 'xlink:arcrole' => array(),
10233
+ 'xlink:href' => array(
10234
+ 'alternative_names' => array(
10235
+ 'href',
10236
+ ),
10237
+ 'value_url' => array(
10238
+ 'allow_empty' => false,
10239
+ 'allow_relative' => true,
10240
+ 'allowed_protocol' => array(
10241
+ 'http',
10242
+ 'https',
10243
+ ),
10244
+ ),
10245
+ ),
10246
+ 'xlink:role' => array(),
10247
+ 'xlink:show' => array(),
10248
+ 'xlink:title' => array(),
10249
+ 'xlink:type' => array(),
10250
+ 'xml:lang' => array(),
10251
+ 'xml:space' => array(),
10252
+ 'xmlns' => array(),
10253
+ 'xmlns:xlink' => array(),
10254
+ ),
10255
+ 'tag_spec' => array(
10256
+ 'mandatory_ancestor' => 'svg',
10257
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
10258
+ ),
10259
+ ),
10260
+ ),
10261
+ 'tspan' => array(
10262
+ array(
10263
+ 'attr_spec_list' => array(
10264
+ 'alignment-baseline' => array(),
10265
+ 'baseline-shift' => array(),
10266
+ 'clip' => array(),
10267
+ 'clip-path' => array(),
10268
+ 'clip-rule' => array(),
10269
+ 'color' => array(),
10270
+ 'color-interpolation' => array(),
10271
+ 'color-interpolation-filters' => array(),
10272
+ 'color-profile' => array(),
10273
+ 'color-rendering' => array(),
10274
+ 'cursor' => array(),
10275
+ 'direction' => array(),
10276
+ 'display' => array(),
10277
+ 'dominant-baseline' => array(),
10278
+ 'dx' => array(),
10279
+ 'dy' => array(),
10280
+ 'enable-background' => array(),
10281
+ 'externalresourcesrequired' => array(),
10282
+ 'fill' => array(),
10283
+ 'fill-opacity' => array(),
10284
+ 'fill-rule' => array(),
10285
+ 'filter' => array(),
10286
+ 'flood-color' => array(),
10287
+ 'flood-opacity' => array(),
10288
+ 'font-family' => array(),
10289
+ 'font-size' => array(),
10290
+ 'font-size-adjust' => array(),
10291
+ 'font-stretch' => array(),
10292
+ 'font-style' => array(),
10293
+ 'font-variant' => array(),
10294
+ 'font-weight' => array(),
10295
+ 'glyph-orientation-horizontal' => array(),
10296
+ 'glyph-orientation-vertical' => array(),
10297
+ 'image-rendering' => array(),
10298
+ 'kerning' => array(),
10299
+ 'lengthadjust' => array(),
10300
+ 'letter-spacing' => array(),
10301
+ 'lighting-color' => array(),
10302
+ 'marker-end' => array(),
10303
+ 'marker-mid' => array(),
10304
+ 'marker-start' => array(),
10305
+ 'mask' => array(),
10306
+ 'opacity' => array(),
10307
+ 'overflow' => array(),
10308
+ 'pointer-events' => array(),
10309
+ 'requiredextensions' => array(),
10310
+ 'requiredfeatures' => array(),
10311
+ 'rotate' => array(),
10312
+ 'shape-rendering' => array(),
10313
+ 'stop-color' => array(),
10314
+ 'stop-opacity' => array(),
10315
+ 'stroke' => array(),
10316
+ 'stroke-dasharray' => array(),
10317
+ 'stroke-dashoffset' => array(),
10318
+ 'stroke-linecap' => array(),
10319
+ 'stroke-linejoin' => array(),
10320
+ 'stroke-miterlimit' => array(),
10321
+ 'stroke-opacity' => array(),
10322
+ 'stroke-width' => array(),
10323
+ 'style' => array(
10324
+ 'blacklisted_value_regex' => '!important',
10325
+ ),
10326
+ 'systemlanguage' => array(),
10327
+ 'text-anchor' => array(),
10328
+ 'text-decoration' => array(),
10329
+ 'text-rendering' => array(),
10330
+ 'textlength' => array(),
10331
+ 'unicode-bidi' => array(),
10332
+ 'vector-effect' => array(),
10333
+ 'visibility' => array(),
10334
+ 'word-spacing' => array(),
10335
+ 'writing-mode' => array(),
10336
+ 'x' => array(),
10337
+ 'xml:lang' => array(),
10338
+ 'xml:space' => array(),
10339
+ 'xmlns' => array(),
10340
+ 'xmlns:xlink' => array(),
10341
+ 'y' => array(),
10342
+ ),
10343
+ 'tag_spec' => array(
10344
+ 'mandatory_ancestor' => 'svg',
10345
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
10346
+ ),
10347
+ ),
10348
+ ),
10349
+ 'tt' => array(
10350
+ array(
10351
+ 'attr_spec_list' => array(),
10352
+ 'tag_spec' => array(),
10353
+ ),
10354
+ ),
10355
+ 'u' => array(
10356
+ array(
10357
+ 'attr_spec_list' => array(),
10358
+ 'tag_spec' => array(),
10359
+ ),
10360
+ ),
10361
+ 'ul' => array(
10362
+ array(
10363
+ 'attr_spec_list' => array(),
10364
+ 'tag_spec' => array(),
10365
+ ),
10366
+ ),
10367
+ 'use' => array(
10368
+ array(
10369
+ 'attr_spec_list' => array(
10370
+ 'alignment-baseline' => array(),
10371
+ 'baseline-shift' => array(),
10372
+ 'clip' => array(),
10373
+ 'clip-path' => array(),
10374
+ 'clip-rule' => array(),
10375
+ 'color' => array(),
10376
+ 'color-interpolation' => array(),
10377
+ 'color-interpolation-filters' => array(),
10378
+ 'color-profile' => array(),
10379
+ 'color-rendering' => array(),
10380
+ 'cursor' => array(),
10381
+ 'direction' => array(),
10382
+ 'display' => array(),
10383
+ 'dominant-baseline' => array(),
10384
+ 'enable-background' => array(),
10385
+ 'externalresourcesrequired' => array(),
10386
+ 'fill' => array(),
10387
+ 'fill-opacity' => array(),
10388
+ 'fill-rule' => array(),
10389
+ 'filter' => array(),
10390
+ 'flood-color' => array(),
10391
+ 'flood-opacity' => array(),
10392
+ 'font-family' => array(),
10393
+ 'font-size' => array(),
10394
+ 'font-size-adjust' => array(),
10395
+ 'font-stretch' => array(),
10396
+ 'font-style' => array(),
10397
+ 'font-variant' => array(),
10398
+ 'font-weight' => array(),
10399
+ 'glyph-orientation-horizontal' => array(),
10400
+ 'glyph-orientation-vertical' => array(),
10401
+ 'height' => array(),
10402
+ 'image-rendering' => array(),
10403
+ 'kerning' => array(),
10404
+ 'letter-spacing' => array(),
10405
+ 'lighting-color' => array(),
10406
+ 'marker-end' => array(),
10407
+ 'marker-mid' => array(),
10408
+ 'marker-start' => array(),
10409
+ 'mask' => array(),
10410
+ 'opacity' => array(),
10411
+ 'overflow' => array(),
10412
+ 'pointer-events' => array(),
10413
+ 'requiredextensions' => array(),
10414
+ 'requiredfeatures' => array(),
10415
+ 'shape-rendering' => array(),
10416
+ 'stop-color' => array(),
10417
+ 'stop-opacity' => array(),
10418
+ 'stroke' => array(),
10419
+ 'stroke-dasharray' => array(),
10420
+ 'stroke-dashoffset' => array(),
10421
+ 'stroke-linecap' => array(),
10422
+ 'stroke-linejoin' => array(),
10423
+ 'stroke-miterlimit' => array(),
10424
+ 'stroke-opacity' => array(),
10425
+ 'stroke-width' => array(),
10426
+ 'style' => array(
10427
+ 'blacklisted_value_regex' => '!important',
10428
+ ),
10429
+ 'systemlanguage' => array(),
10430
+ 'text-anchor' => array(),
10431
+ 'text-decoration' => array(),
10432
+ 'text-rendering' => array(),
10433
+ 'transform' => array(),
10434
+ 'unicode-bidi' => array(),
10435
+ 'vector-effect' => array(),
10436
+ 'visibility' => array(),
10437
+ 'width' => array(),
10438
+ 'word-spacing' => array(),
10439
+ 'writing-mode' => array(),
10440
+ 'x' => array(),
10441
+ 'xlink:actuate' => array(),
10442
+ 'xlink:arcrole' => array(),
10443
+ 'xlink:href' => array(
10444
+ 'alternative_names' => array(
10445
+ 'href',
10446
+ ),
10447
+ 'value_url' => array(
10448
+ 'allow_empty' => false,
10449
+ 'allow_relative' => true,
10450
+ 'allowed_protocol' => array(
10451
+ 'http',
10452
+ 'https',
10453
+ ),
10454
+ ),
10455
+ ),
10456
+ 'xlink:role' => array(),
10457
+ 'xlink:show' => array(),
10458
+ 'xlink:title' => array(),
10459
+ 'xlink:type' => array(),
10460
+ 'xml:lang' => array(),
10461
+ 'xml:space' => array(),
10462
+ 'xmlns' => array(),
10463
+ 'xmlns:xlink' => array(),
10464
+ 'y' => array(),
10465
+ ),
10466
+ 'tag_spec' => array(
10467
+ 'mandatory_ancestor' => 'svg',
10468
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
10469
+ ),
10470
+ ),
10471
+ ),
10472
+ 'var' => array(
10473
+ array(
10474
+ 'attr_spec_list' => array(),
10475
+ 'tag_spec' => array(),
10476
+ ),
10477
+ ),
10478
+ 'video' => array(
10479
+ array(
10480
+ 'attr_spec_list' => array(
10481
+ 'autoplay' => array(),
10482
+ 'controls' => array(),
10483
+ 'height' => array(),
10484
+ 'loop' => array(),
10485
+ 'muted' => array(),
10486
+ 'playsinline' => array(),
10487
+ 'poster' => array(),
10488
+ 'preload' => array(),
10489
+ 'src' => array(
10490
+ 'blacklisted_value_regex' => '__amp_source_origin',
10491
+ 'value_url' => array(
10492
+ 'allow_relative' => false,
10493
+ 'allowed_protocol' => array(
10494
+ 'data',
10495
+ 'https',
10496
+ ),
10497
+ ),
10498
+ ),
10499
+ 'width' => array(),
10500
+ ),
10501
+ 'tag_spec' => array(
10502
+ 'mandatory_ancestor' => 'noscript',
10503
+ 'mandatory_ancestor_suggested_alternative' => 'amp-video',
10504
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/components/amp-video',
10505
+ ),
10506
+ ),
10507
+ ),
10508
+ 'view' => array(
10509
+ array(
10510
+ 'attr_spec_list' => array(
10511
+ 'externalresourcesrequired' => array(),
10512
+ 'preserveaspectratio' => array(),
10513
+ 'style' => array(
10514
+ 'blacklisted_value_regex' => '!important',
10515
+ ),
10516
+ 'viewbox' => array(),
10517
+ 'viewtarget' => array(),
10518
+ 'xml:lang' => array(),
10519
+ 'xml:space' => array(),
10520
+ 'xmlns' => array(),
10521
+ 'xmlns:xlink' => array(),
10522
+ 'zoomandpan' => array(),
10523
+ ),
10524
+ 'tag_spec' => array(
10525
+ 'mandatory_ancestor' => 'svg',
10526
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
10527
+ ),
10528
+ ),
10529
+ ),
10530
+ 'vkern' => array(
10531
+ array(
10532
+ 'attr_spec_list' => array(
10533
+ 'g1' => array(),
10534
+ 'g2' => array(),
10535
+ 'k' => array(),
10536
+ 'style' => array(
10537
+ 'blacklisted_value_regex' => '!important',
10538
+ ),
10539
+ 'u1' => array(),
10540
+ 'u2' => array(),
10541
+ 'xml:lang' => array(),
10542
+ 'xml:space' => array(),
10543
+ 'xmlns' => array(),
10544
+ 'xmlns:xlink' => array(),
10545
+ ),
10546
+ 'tag_spec' => array(
10547
+ 'mandatory_ancestor' => 'svg',
10548
+ 'spec_url' => 'https://www.ampproject.org/docs/reference/spec#svg',
10549
+ ),
10550
+ ),
10551
+ ),
10552
+ 'wbr' => array(
10553
+ array(
10554
+ 'attr_spec_list' => array(),
10555
+ 'tag_spec' => array(),
10556
+ ),
10557
+ ),
10558
+ 'xmp' => array(
10559
+ array(
10560
+ 'attr_spec_list' => array(),
10561
+ 'tag_spec' => array(),
10562
+ ),
10563
+ ),
10564
+ );
10565
+
10566
+ private static $layout_allowed_attrs = array(
10567
+ '[height]' => array(),
10568
+ '[width]' => array(),
10569
+ 'height' => array(),
10570
+ 'heights' => array(),
10571
+ 'layout' => array(),
10572
+ 'sizes' => array(),
10573
+ 'width' => array(),
10574
+ );
10575
+
10576
+
10577
+ private static $globally_allowed_attrs = array(
10578
+ '[aria-activedescendant]' => array(),
10579
+ '[aria-atomic]' => array(),
10580
+ '[aria-autocomplete]' => array(),
10581
+ '[aria-busy]' => array(),
10582
+ '[aria-checked]' => array(),
10583
+ '[aria-controls]' => array(),
10584
+ '[aria-describedby]' => array(),
10585
+ '[aria-disabled]' => array(),
10586
+ '[aria-dropeffect]' => array(),
10587
+ '[aria-expanded]' => array(),
10588
+ '[aria-flowto]' => array(),
10589
+ '[aria-grabbed]' => array(),
10590
+ '[aria-haspopup]' => array(),
10591
+ '[aria-hidden]' => array(),
10592
+ '[aria-invalid]' => array(),
10593
+ '[aria-label]' => array(),
10594
+ '[aria-labelledby]' => array(),
10595
+ '[aria-level]' => array(),
10596
+ '[aria-live]' => array(),
10597
+ '[aria-multiline]' => array(),
10598
+ '[aria-multiselectable]' => array(),
10599
+ '[aria-orientation]' => array(),
10600
+ '[aria-owns]' => array(),
10601
+ '[aria-posinset]' => array(),
10602
+ '[aria-pressed]' => array(),
10603
+ '[aria-readonly]' => array(),
10604
+ '[aria-relevant]' => array(),
10605
+ '[aria-required]' => array(),
10606
+ '[aria-selected]' => array(),
10607
+ '[aria-setsize]' => array(),
10608
+ '[aria-sort]' => array(),
10609
+ '[aria-valuemax]' => array(),
10610
+ '[aria-valuemin]' => array(),
10611
+ '[aria-valuenow]' => array(),
10612
+ '[aria-valuetext]' => array(),
10613
+ '[class]' => array(),
10614
+ '[hidden]' => array(),
10615
+ '[text]' => array(),
10616
+ 'about' => array(),
10617
+ 'accesskey' => array(),
10618
+ 'amp-access' => array(),
10619
+ 'amp-access-behavior' => array(),
10620
+ 'amp-access-hide' => array(),
10621
+ 'amp-access-id' => array(),
10622
+ 'amp-access-loader' => array(),
10623
+ 'amp-access-loading' => array(),
10624
+ 'amp-access-off' => array(),
10625
+ 'amp-access-on' => array(),
10626
+ 'amp-access-show' => array(),
10627
+ 'amp-access-style' => array(),
10628
+ 'amp-access-template' => array(),
10629
+ 'amp-fx' => array(
10630
+ 'value_casei' => 'parallax',
10631
+ ),
10632
+ 'aria-activedescendant' => array(),
10633
+ 'aria-atomic' => array(),
10634
+ 'aria-autocomplete' => array(),
10635
+ 'aria-busy' => array(),
10636
+ 'aria-checked' => array(),
10637
+ 'aria-controls' => array(),
10638
+ 'aria-current' => array(),
10639
+ 'aria-describedby' => array(),
10640
+ 'aria-disabled' => array(),
10641
+ 'aria-dropeffect' => array(),
10642
+ 'aria-expanded' => array(),
10643
+ 'aria-flowto' => array(),
10644
+ 'aria-grabbed' => array(),
10645
+ 'aria-haspopup' => array(),
10646
+ 'aria-hidden' => array(),
10647
+ 'aria-invalid' => array(),
10648
+ 'aria-label' => array(),
10649
+ 'aria-labelledby' => array(),
10650
+ 'aria-level' => array(),
10651
+ 'aria-live' => array(),
10652
+ 'aria-multiline' => array(),
10653
+ 'aria-multiselectable' => array(),
10654
+ 'aria-orientation' => array(),
10655
+ 'aria-owns' => array(),
10656
+ 'aria-posinset' => array(),
10657
+ 'aria-pressed' => array(),
10658
+ 'aria-readonly' => array(),
10659
+ 'aria-relevant' => array(),
10660
+ 'aria-required' => array(),
10661
+ 'aria-selected' => array(),
10662
+ 'aria-setsize' => array(),
10663
+ 'aria-sort' => array(),
10664
+ 'aria-valuemax' => array(),
10665
+ 'aria-valuemin' => array(),
10666
+ 'aria-valuenow' => array(),
10667
+ 'aria-valuetext' => array(),
10668
+ 'class' => array(
10669
+ 'blacklisted_value_regex' => '(^|\\W)i-amphtml-',
10670
+ ),
10671
+ 'content' => array(),
10672
+ 'datatype' => array(),
10673
+ 'dir' => array(),
10674
+ 'draggable' => array(),
10675
+ 'fallback' => array(
10676
+ 'value' => '',
10677
+ ),
10678
+ 'hidden' => array(
10679
+ 'value' => '',
10680
+ ),
10681
+ 'i-amp-access-id' => array(),
10682
+ 'id' => array(
10683
+ 'blacklisted_value_regex' => '(^|\\s)(__amp_\\S*|__count__|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|__noSuchMethod__|__parent__|__proto__|__AMP_\\S*|\\$p|\\$proxy|acceptCharset|addEventListener|appendChild|assignedSlot|attachShadow|AMP|baseURI|checkValidity|childElementCount|childNodes|classList|className|clientHeight|clientLeft|clientTop|clientWidth|compareDocumentPosition|computedName|computedRole|contentEditable|createShadowRoot|enqueAction|firstChild|firstElementChild|getAnimations|getAttribute|getAttributeNS|getAttributeNode|getAttributeNodeNS|getBoundingClientRect|getClientRects|getDestinationInsertionPoints|getElementsByClassName|getElementsByTagName|getElementsByTagNameNS|getRootNode|hasAttribute|hasAttributeNS|hasAttributes|hasChildNodes|hasPointerCapture|i-amphtml-\\S*|innerHTML|innerText|inputMode|insertAdjacentElement|insertAdjacentHTML|insertAdjacentText|isContentEditable|isDefaultNamespace|isEqualNode|isSameNode|lastChild|lastElementChild|lookupNamespaceURI|namespaceURI|nextElementSibling|nextSibling|nodeName|nodeType|nodeValue|offsetHeight|offsetLeft|offsetParent|offsetTop|offsetWidth|outerHTML|outerText|ownerDocument|parentElement|parentNode|previousElementSibling|previousSibling|querySelector|querySelectorAll|releasePointerCapture|removeAttribute|removeAttributeNS|removeAttributeNode|removeChild|removeEventListener|replaceChild|reportValidity|requestPointerLock|scrollHeight|scrollIntoView|scrollIntoViewIfNeeded|scrollLeft|scrollWidth|setAttribute|setAttributeNS|setAttributeNode|setAttributeNodeNS|setPointerCapture|shadowRoot|styleMap|tabIndex|tagName|textContent|toString|valueOf|(webkit|ms|moz|o)dropzone|(webkit|moz|ms|o)MatchesSelector|(webkit|moz|ms|o)RequestFullScreen|(webkit|moz|ms|o)RequestFullscreen)(\\s|$)',
10684
+ ),
10685
+ 'inlist' => array(),
10686
+ 'itemid' => array(),
10687
+ 'itemprop' => array(),
10688
+ 'itemref' => array(),
10689
+ 'itemscope' => array(),
10690
+ 'itemtype' => array(),
10691
+ 'lang' => array(),
10692
+ 'lightbox' => array(),
10693
+ 'on' => array(),
10694
+ 'overflow' => array(),
10695
+ 'placeholder' => array(
10696
+ 'value' => '',
10697
+ ),
10698
+ 'prefix' => array(),
10699
+ 'property' => array(),
10700
+ 'rel' => array(
10701
+ 'blacklisted_value_regex' => '(^|\\s)(canonical|components|dns-prefetch|import|manifest|preconnect|preload|prerender|serviceworker|stylesheet|subresource)(\\s|$)',
10702
+ ),
10703
+ 'resource' => array(),
10704
+ 'rev' => array(),
10705
+ 'role' => array(),
10706
+ 'subscriptions-action' => array(),
10707
+ 'subscriptions-actions' => array(
10708
+ 'value' => '',
10709
+ ),
10710
+ 'subscriptions-dialog' => array(
10711
+ 'value' => '',
10712
+ ),
10713
+ 'subscriptions-display' => array(),
10714
+ 'subscriptions-section' => array(
10715
+ 'value_regex_casei' => '(actions|content|content-not-granted)',
10716
+ ),
10717
+ 'subscriptions-service' => array(),
10718
+ 'tabindex' => array(),
10719
+ 'title' => array(),
10720
+ 'translate' => array(),
10721
+ 'typeof' => array(),
10722
+ 'validation-for' => array(),
10723
+ 'visible-when-invalid' => array(
10724
+ 'value_regex' => '(badInput|customError|patternMismatch|rangeOverflow|rangeUnderflow|stepMismatch|tooLong|typeMismatch|valueMissing)',
10725
+ ),
10726
+ 'vocab' => array(),
10727
+ );
10728
+
10729
+
10730
+ /**
10731
+ * Get allowed tags.
10732
+ *
10733
+ * @since 0.5
10734
+ * @return array Allowed tags.
10735
+ */
10736
+ public static function get_allowed_tags() {
10737
+ return self::$allowed_tags;
10738
+ }
10739
+
10740
+ /**
10741
+ * Get allowed tag.
10742
+ *
10743
+ * Get the rules for a single tag so that the entire data structure needn't be passed around.
10744
+ *
10745
+ * @since 0.7
10746
+ * @param string $node_name Tag name.
10747
+ * @return array|null Allowed tag, or null if the tag does not exist.
10748
+ */
10749
+ public static function get_allowed_tag( $node_name ) {
10750
+ if ( isset( self::$allowed_tags[ $node_name ] ) ) {
10751
+ return self::$allowed_tags[ $node_name ];
10752
+ }
10753
+ return null;
10754
+ }
10755
+
10756
+ /**
10757
+ * Get list of globally-allowed attributes.
10758
+ *
10759
+ * @since 0.5
10760
+ * @return array Allowed tag.
10761
+ */
10762
+ public static function get_allowed_attributes() {
10763
+ return self::$globally_allowed_attrs;
10764
+ }
10765
+
10766
+ /**
10767
+ * Get layout attributes.
10768
+ *
10769
+ * @since 0.5
10770
+ * @return array Allowed tag.
10771
+ */
10772
+ public static function get_layout_attributes() {
10773
+ return self::$layout_allowed_attrs;
10774
+ }
10775
+
10776
+ }
includes/vendor/amp/includes/sanitizers/class-amp-rule-spec.php ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class AMP_Rule_Spec
4
+ *
5
+ * @package AMP
6
+ */
7
+
8
+ /**
9
+ * Class AMP_Rule_Spec
10
+ *
11
+ * Set of constants used throughout the sanitizer.
12
+ */
13
+ abstract class AMP_Rule_Spec {
14
+
15
+ /**
16
+ * AMP rule_spec types
17
+ */
18
+ const ATTR_SPEC_LIST = 'attr_spec_list';
19
+ const TAG_SPEC = 'tag_spec';
20
+ const CDATA = 'cdata';
21
+
22
+ /**
23
+ * AMP attr_spec value check results.
24
+ *
25
+ * In 0.7 these changed from strings to integers to speed up comparisons.
26
+ */
27
+ const PASS = 1;
28
+ const FAIL = 0;
29
+ const NOT_APPLICABLE = -1;
30
+
31
+ /**
32
+ * HTML Element Tag rule names
33
+ */
34
+ const DISALLOWED_ANCESTOR = 'disallowed_ancestor';
35
+ const MANDATORY_ANCESTOR = 'mandatory_ancestor';
36
+ const MANDATORY_PARENT = 'mandatory_parent';
37
+
38
+ /**
39
+ * HTML Element Attribute rule names
40
+ */
41
+ const ALLOW_EMPTY = 'allow_empty';
42
+ const ALLOW_RELATIVE = 'allow_relative';
43
+ const ALLOWED_PROTOCOL = 'allowed_protocol';
44
+ const ALTERNATIVE_NAMES = 'alternative_names';
45
+ const BLACKLISTED_VALUE_REGEX = 'blacklisted_value_regex';
46
+ const DISALLOWED_DOMAIN = 'disallowed_domain';
47
+ const MANDATORY = 'mandatory';
48
+ const VALUE = 'value';
49
+ const VALUE_CASEI = 'value_casei';
50
+ const VALUE_REGEX = 'value_regex';
51
+ const VALUE_REGEX_CASEI = 'value_regex_casei';
52
+ const VALUE_PROPERTIES = 'value_properties';
53
+ const VALUE_URL = 'value_url';
54
+
55
+ /**
56
+ * If a node type listed here is invalid, it and it's subtree will be
57
+ * removed if it is invalid. This is mainly because any children will be
58
+ * non-functional without this parent.
59
+ *
60
+ * If a tag is not listed here, it will be replaced by its children if it
61
+ * is invalid.
62
+ *
63
+ * @todo There are other nodes that should probably be listed here as well.
64
+ *
65
+ * @var array
66
+ */
67
+ public static $node_types_to_remove_if_invalid = array(
68
+ 'form',
69
+ 'input',
70
+ 'link',
71
+ 'meta',
72
+ 'style',
73
+ // Include 'script' here?
74
+ );
75
+
76
+ /**
77
+ * It is mentioned in the documentation in several places that data-*
78
+ * is generally allowed, but there is no specific rule for it in the
79
+ * protoascii file, so we include it here.
80
+ *
81
+ * @var array
82
+ */
83
+ public static $whitelisted_attr_regex = array(
84
+ '@^data-[a-zA-Z][\\w:.-]*$@uis',
85
+ '(update|item|pagination|option|selected|disabled)', // Allowed for live reference points.
86
+ );
87
+
88
+ /**
89
+ * List of boolean attributes.
90
+ *
91
+ * @since 0.7
92
+ * @var array
93
+ */
94
+ public static $boolean_attributes = array(
95
+ 'allowfullscreen',
96
+ 'async',
97
+ 'autofocus',
98
+ 'autoplay',
99
+ 'checked',
100
+ 'compact',
101
+ 'controls',
102
+ 'declare',
103
+ 'default',
104
+ 'defaultchecked',
105
+ 'defaultmuted',
106
+ 'defaultselected',
107
+ 'defer',
108
+ 'disabled',
109
+ 'draggable',
110
+ 'enabled',
111
+ 'formnovalidate',
112
+ 'hidden',
113
+ 'indeterminate',
114
+ 'inert',
115
+ 'ismap',
116
+ 'itemscope',
117
+ 'loop',
118
+ 'multiple',
119
+ 'muted',
120
+ 'nohref',
121
+ 'noresize',
122
+ 'noshade',
123
+ 'novalidate',
124
+ 'nowrap',
125
+ 'open',
126
+ 'pauseonexit',
127
+ 'readonly',
128
+ 'required',
129
+ 'reversed',
130
+ 'scoped',
131
+ 'seamless',
132
+ 'selected',
133
+ 'sortable',
134
+ 'spellcheck',
135
+ 'translate',
136
+ 'truespeed',
137
+ 'typemustmatch',
138
+ 'visible',
139
+ );
140
+
141
+ /**
142
+ * Additional allowed tags.
143
+ *
144
+ * @var array
145
+ */
146
+ public static $additional_allowed_tags = array(
147
+
148
+ // An experimental tag with no protoascii.
149
+ 'amp-share-tracking' => array(
150
+ 'attr_spec_list' => array(),
151
+ 'tag_spec' => array(),
152
+ ),
153
+ );
154
+ }
includes/vendor/amp/includes/sanitizers/class-amp-tag-and-attribute-sanitizer.php ADDED
@@ -0,0 +1,1643 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class AMP_Tag_And_Attribute_Sanitizer
4
+ *
5
+ * @package AMP
6
+ */
7
+
8
+ /**
9
+ * Strips the tags and attributes from the content that are not allowed by the AMP spec.
10
+ *
11
+ * Allowed tags array is generated from this protocol buffer:
12
+ *
13
+ * https://github.com/ampproject/amphtml/blob/master/validator/validator-main.protoascii
14
+ * by the python script in amp-wp/bin/amp_wp_build.py. See the comment at the top
15
+ * of that file for instructions to generate class-amp-allowed-tags-generated.php.
16
+ *
17
+ * @todo Need to check the following items that are not yet checked by this sanitizer:
18
+ *
19
+ * - `also_requires_attr` - if one attribute is present, this requires another.
20
+ * - `ChildTagSpec` - Places restrictions on the number and type of child tags.
21
+ * - `if_value_regex` - if one attribute value matches, this places a restriction
22
+ * on another attribute/value.
23
+ * - `mandatory_oneof` - Within the context of the tag, exactly one of the attributes
24
+ * must be present.
25
+ */
26
+ class AMP_Tag_And_Attribute_Sanitizer extends AMP_Base_Sanitizer {
27
+
28
+ /**
29
+ * Allowed tags.
30
+ *
31
+ * @since 0.5
32
+ *
33
+ * @var string[]
34
+ */
35
+ protected $allowed_tags;
36
+
37
+ /**
38
+ * Globally-allowed attributes.
39
+ *
40
+ * @since 0.5
41
+ *
42
+ * @var array[][]
43
+ */
44
+ protected $globally_allowed_attributes;
45
+
46
+ /**
47
+ * Layout-allowed attributes.
48
+ *
49
+ * @since 0.5
50
+ *
51
+ * @var string[]
52
+ */
53
+ protected $layout_allowed_attributes;
54
+
55
+ /**
56
+ * Mapping of alternative names back to their primary names.
57
+ *
58
+ * @since 0.7
59
+ * @var array
60
+ */
61
+ protected $rev_alternate_attr_name_lookup = array();
62
+
63
+ /**
64
+ * Stack.
65
+ *
66
+ * @since 0.5
67
+ *
68
+ * @var DOMElement[]
69
+ */
70
+ private $stack = array();
71
+
72
+ /**
73
+ * Default args.
74
+ *
75
+ * @since 0.5
76
+ *
77
+ * @var array
78
+ */
79
+ protected $DEFAULT_ARGS = array();
80
+
81
+ /**
82
+ * AMP script components that are discovered being required through sanitization.
83
+ *
84
+ * @var string[]
85
+ */
86
+ protected $script_components = array();
87
+
88
+ /**
89
+ * AMP_Tag_And_Attribute_Sanitizer constructor.
90
+ *
91
+ * @since 0.5
92
+ *
93
+ * @param DOMDocument $dom DOM.
94
+ * @param array $args Args.
95
+ */
96
+ public function __construct( $dom, $args = array() ) {
97
+ $this->DEFAULT_ARGS = array(
98
+ 'amp_allowed_tags' => AMP_Allowed_Tags_Generated::get_allowed_tags(),
99
+ 'amp_globally_allowed_attributes' => AMP_Allowed_Tags_Generated::get_allowed_attributes(),
100
+ 'amp_layout_allowed_attributes' => AMP_Allowed_Tags_Generated::get_layout_attributes(),
101
+ 'amp_bind_placeholder_prefix' => AMP_DOM_Utils::get_amp_bind_placeholder_prefix(),
102
+ );
103
+
104
+ parent::__construct( $dom, $args );
105
+
106
+ if ( ! empty( $this->args['allow_dirty_styles'] ) ) {
107
+
108
+ // Allow style attribute on all elements.
109
+ $this->args['amp_globally_allowed_attributes']['style'] = array();
110
+
111
+ // Allow style elements.
112
+ $this->args['amp_allowed_tags']['style'][] = array(
113
+ 'attr_spec_list' => array(
114
+ 'type' => array(
115
+ 'value_casei' => 'text/css',
116
+ ),
117
+ ),
118
+ 'cdata' => array(),
119
+ 'tag_spec' => array(
120
+ 'spec_name' => 'style for Customizer preview',
121
+ ),
122
+ );
123
+
124
+ // Allow stylesheet links.
125
+ $this->args['amp_allowed_tags']['link'][] = array(
126
+ 'attr_spec_list' => array(
127
+ 'async' => array(),
128
+ 'crossorigin' => array(),
129
+ 'href' => array(
130
+ 'mandatory' => true,
131
+ ),
132
+ 'integrity' => array(),
133
+ 'media' => array(),
134
+ 'rel' => array(
135
+ 'dispatch_key' => 2,
136
+ 'mandatory' => true,
137
+ 'value_casei' => 'stylesheet',
138
+ ),
139
+ 'type' => array(
140
+ 'value_casei' => 'text/css',
141
+ ),
142
+ ),
143
+ 'tag_spec' => array(
144
+ 'spec_name' => 'link rel=stylesheet for Customizer preview', // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
145
+ ),
146
+ );
147
+ }
148
+
149
+ // Allow scripts if requested.
150
+ if ( ! empty( $this->args['allow_dirty_scripts'] ) ) {
151
+ $this->args['amp_allowed_tags']['script'][] = array(
152
+ 'attr_spec_list' => array(
153
+ 'type' => array(),
154
+ 'src' => array(),
155
+ 'async' => array(),
156
+ 'defer' => array(),
157
+ ),
158
+ 'cdata' => array(),
159
+ 'tag_spec' => array(
160
+ 'spec_name' => 'scripts for Customizer preview',
161
+ ),
162
+ );
163
+ }
164
+
165
+ // Prepare whitelists.
166
+ $this->allowed_tags = $this->args['amp_allowed_tags'];
167
+ foreach ( AMP_Rule_Spec::$additional_allowed_tags as $tag_name => $tag_rule_spec ) {
168
+ $this->allowed_tags[ $tag_name ][] = $tag_rule_spec;
169
+ }
170
+
171
+ // @todo Do the same for body when !use_document_element?
172
+ if ( ! empty( $this->args['use_document_element'] ) ) {
173
+ foreach ( $this->allowed_tags['html'] as &$rule_spec ) {
174
+ unset( $rule_spec[ AMP_Rule_Spec::TAG_SPEC ][ AMP_Rule_Spec::MANDATORY_PARENT ] );
175
+ }
176
+ }
177
+
178
+ foreach ( $this->allowed_tags as &$tag_specs ) {
179
+ foreach ( $tag_specs as &$tag_spec ) {
180
+ if ( isset( $tag_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ] ) ) {
181
+ $tag_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ] = $this->process_alternate_names( $tag_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ] );
182
+ }
183
+ }
184
+ }
185
+ $this->globally_allowed_attributes = $this->process_alternate_names( $this->args['amp_globally_allowed_attributes'] );
186
+ $this->layout_allowed_attributes = $this->process_alternate_names( $this->args['amp_layout_allowed_attributes'] );
187
+ }
188
+
189
+ /**
190
+ * Return array of values that would be valid as an HTML `script` element.
191
+ *
192
+ * Array keys are AMP element names and array values are their respective
193
+ * Javascript URLs from https://cdn.ampproject.org
194
+ *
195
+ * @since 0.7
196
+ * @see amp_register_default_scripts()
197
+ *
198
+ * @return array() Returns component name as array key and true as value (or JavaScript URL string),
199
+ * respectively. When true then the default component script URL will be used.
200
+ * Will return an empty array if sanitization has yet to be run
201
+ * or if it did not find any HTML elements to convert to AMP equivalents.
202
+ */
203
+ public function get_scripts() {
204
+ $scriptArray = array_fill_keys( $this->script_components, true );
205
+ foreach ( $scriptArray as $ext_key=>$ext_value ) {
206
+ $scriptArray[$ext_key] = sprintf(
207
+ 'https://cdn.ampproject.org/v0/%s-%s.js',
208
+ $ext_key,
209
+ 'latest'
210
+ );
211
+ }
212
+ if(count($scriptArray)>0){
213
+ remove_filter('the_content', 'wpautop');
214
+ }
215
+ return $scriptArray;
216
+ }
217
+
218
+ /**
219
+ * Process alternative names in attribute spec list.
220
+ *
221
+ * @since 0.7
222
+ *
223
+ * @param array $attr_spec_list Attribute spec list.
224
+ * @return array Modified attribute spec list.
225
+ */
226
+ private function process_alternate_names( $attr_spec_list ) {
227
+ foreach ( $attr_spec_list as $attr_name => &$attr_spec ) {
228
+ if ( '[' === $attr_name[0] ) {
229
+ $placeholder_attr_name = $this->args['amp_bind_placeholder_prefix'] . trim( $attr_name, '[]' );
230
+ if ( ! isset( $attr_spec[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] ) ) {
231
+ $attr_spec[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] = array();
232
+ }
233
+ $attr_spec[ AMP_Rule_Spec::ALTERNATIVE_NAMES ][] = $placeholder_attr_name;
234
+ }
235
+
236
+ // Save all alternative names in lookup to improve performance.
237
+ if ( isset( $attr_spec[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] ) ) {
238
+ foreach ( $attr_spec[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] as $alternative_name ) {
239
+ $this->rev_alternate_attr_name_lookup[ $alternative_name ] = $attr_name;
240
+ }
241
+ }
242
+ }
243
+ return $attr_spec_list;
244
+ }
245
+
246
+ /**
247
+ * Sanitize the <video> elements from the HTML contained in this instance's DOMDocument.
248
+ *
249
+ * @since 0.5
250
+ */
251
+ public function sanitize() {
252
+
253
+ // Add root of content to the stack.
254
+ $this->stack[] = $this->get_body_node();
255
+
256
+ /**
257
+ * This loop traverses through the DOM tree iteratively.
258
+ */
259
+ while ( ! empty( $this->stack ) ) {
260
+
261
+ // Get the next node to process.
262
+ $node = array_pop( $this->stack );
263
+
264
+ /**
265
+ * Process this node.
266
+ */
267
+ $this->process_node( $node );
268
+
269
+ /*
270
+ * Push child nodes onto the stack, if any exist.
271
+ * if node was removed, then it's parentNode value is null.
272
+ */
273
+ if ( $node->parentNode ) {
274
+ $child = $node->firstChild;
275
+ while ( $child ) {
276
+ $this->stack[] = $child;
277
+ $child = $child->nextSibling;
278
+ }
279
+ }
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Process a node by sanitizing and/or validating it per.
285
+ *
286
+ * @param DOMNode $node Node.
287
+ */
288
+ private function process_node( $node ) {
289
+
290
+ // Don't process text or comment nodes.
291
+ if ( XML_TEXT_NODE === $node->nodeType || XML_COMMENT_NODE === $node->nodeType || XML_CDATA_SECTION_NODE === $node->nodeType ) {
292
+ return;
293
+ }
294
+
295
+ // Remove nodes with tags that have not been whitelisted.
296
+ if ( ! $this->is_amp_allowed_tag( $node ) ) {
297
+
298
+ // If it's not an allowed tag, replace the node with it's children.
299
+ $this->replace_node_with_children( $node );
300
+
301
+ // Return early since this node no longer exists.
302
+ return;
303
+ }
304
+
305
+ /**
306
+ * Node is now an element.
307
+ *
308
+ * @var DOMElement $node
309
+ */
310
+
311
+ /*
312
+ * Compile a list of rule_specs to validate for this node
313
+ * based on tag name of the node.
314
+ */
315
+ $rule_spec_list_to_validate = array();
316
+ $rule_spec_list = array();
317
+ if ( isset( $this->allowed_tags[ $node->nodeName ] ) ) {
318
+ $rule_spec_list = $this->allowed_tags[ $node->nodeName ];
319
+ }
320
+ foreach ( $rule_spec_list as $id => $rule_spec ) {
321
+ if ( $this->validate_tag_spec_for_node( $node, $rule_spec[ AMP_Rule_Spec::TAG_SPEC ] ) ) {
322
+
323
+ // Expand extension_spec into a set of attr_spec_list.
324
+ if ( isset( $rule_spec[ AMP_Rule_Spec::TAG_SPEC ]['extension_spec'] ) ) {
325
+ $extension_spec = $rule_spec[ AMP_Rule_Spec::TAG_SPEC ]['extension_spec'];
326
+ $custom_attr = 'amp-mustache' === $extension_spec['name'] ? 'custom-template' : 'custom-element';
327
+
328
+ $rule_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ][ $custom_attr ] = array(
329
+ AMP_Rule_Spec::VALUE => $extension_spec['name'],
330
+ AMP_Rule_Spec::MANDATORY => true,
331
+ );
332
+
333
+ $rule_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ]['src'] = array(
334
+ AMP_Rule_Spec::VALUE_REGEX => implode( '', array(
335
+ '^',
336
+ preg_quote( 'https://cdn.ampproject.org/v0/' . $extension_spec['name'] . '-' ),
337
+ '(' . implode( '|', $extension_spec['allowed_versions'] ) . ')',
338
+ '\.js$',
339
+ ) ),
340
+ );
341
+ }
342
+
343
+ $rule_spec_list_to_validate[ $id ] = $rule_spec;
344
+ }
345
+ }
346
+
347
+ // If no valid rule_specs exist, then remove this node and return.
348
+ if ( empty( $rule_spec_list_to_validate ) ) {
349
+ $this->remove_node( $node );
350
+ return;
351
+ }
352
+
353
+ // The remaining validations all have to do with attributes.
354
+ $attr_spec_list = array();
355
+ $tag_spec = array();
356
+ $cdata = array();
357
+
358
+ /*
359
+ * If we have exactly one rule_spec, use it's attr_spec_list
360
+ * to validate the node's attributes.
361
+ */
362
+ if ( 1 === count( $rule_spec_list_to_validate ) ) {
363
+ $rule_spec = array_pop( $rule_spec_list_to_validate );
364
+ $attr_spec_list = $rule_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ];
365
+ $tag_spec = $rule_spec[ AMP_Rule_Spec::TAG_SPEC ];
366
+ if ( isset( $rule_spec[ AMP_Rule_Spec::CDATA ] ) ) {
367
+ $cdata = $rule_spec[ AMP_Rule_Spec::CDATA ];
368
+ }
369
+ } else {
370
+ /*
371
+ * If there is more than one valid rule_spec for this node,
372
+ * then try to deduce which one is intended by inspecting
373
+ * the node's attributes.
374
+ */
375
+
376
+ /*
377
+ * Get a score from each attr_spec_list by seeing how many
378
+ * attributes and values match the node.
379
+ */
380
+ $attr_spec_scores = array();
381
+ foreach ( $rule_spec_list_to_validate as $spec_id => $rule_spec ) {
382
+ $attr_spec_scores[ $spec_id ] = $this->validate_attr_spec_list_for_node( $node, $rule_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ] );
383
+ }
384
+
385
+ // Remove all spec lists that didn't match.
386
+ $attr_spec_scores = array_filter( $attr_spec_scores );
387
+
388
+ // If no attribute spec lists match, then the element must be removed.
389
+ if ( empty( $attr_spec_scores ) ) {
390
+ $this->remove_node( $node );
391
+ return;
392
+ }
393
+
394
+ // Get the key(s) to the highest score(s).
395
+ $spec_ids_sorted = array_keys( $attr_spec_scores, max( $attr_spec_scores ), true );
396
+
397
+ // If there is exactly one attr_spec with a max score, use that one.
398
+ if ( 1 === count( $spec_ids_sorted ) ) {
399
+ $attr_spec_list = $rule_spec_list_to_validate[ $spec_ids_sorted[0] ][ AMP_Rule_Spec::ATTR_SPEC_LIST ];
400
+ $tag_spec = $rule_spec_list_to_validate[ $spec_ids_sorted[0] ][ AMP_Rule_Spec::TAG_SPEC ];
401
+ if ( isset( $rule_spec_list_to_validate[ $spec_ids_sorted[0] ][ AMP_Rule_Spec::CDATA ] ) ) {
402
+ $cdata = $rule_spec_list_to_validate[ $spec_ids_sorted[0] ][ AMP_Rule_Spec::CDATA ];
403
+ }
404
+ } else {
405
+ // This should not happen very often, but...
406
+ // If we're here, then we're not sure which spec should
407
+ // be used. Let's use the top scoring ones.
408
+ foreach ( $spec_ids_sorted as $id ) {
409
+ $spec_list = isset( $rule_spec_list_to_validate[ $id ][ AMP_Rule_Spec::ATTR_SPEC_LIST ] ) ? $rule_spec_list_to_validate[ $id ][ AMP_Rule_Spec::ATTR_SPEC_LIST ] : null;
410
+ if ( ! $this->is_missing_mandatory_attribute( $spec_list, $node ) ) {
411
+ $attr_spec_list = array_merge( $attr_spec_list, $spec_list );
412
+ $tag_spec = array_merge(
413
+ $tag_spec,
414
+ $rule_spec_list_to_validate[ $id ][ AMP_Rule_Spec::TAG_SPEC ]
415
+ );
416
+ if ( isset( $rule_spec_list_to_validate[ $id ][ AMP_Rule_Spec::CDATA ] ) ) {
417
+ $cdata = array_merge( $cdata, $rule_spec_list_to_validate[ $id ][ AMP_Rule_Spec::CDATA ] );
418
+ }
419
+ }
420
+ }
421
+ $first_spec = reset( $rule_spec_list_to_validate );
422
+ if ( empty( $attr_spec_list ) && isset( $first_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ] ) ) {
423
+ $attr_spec_list = $first_spec[ AMP_Rule_Spec::ATTR_SPEC_LIST ];
424
+ }
425
+ }
426
+ } // End if().
427
+
428
+ if ( ! empty( $attr_spec_list ) && $this->is_missing_mandatory_attribute( $attr_spec_list, $node ) ) {
429
+ $this->remove_node( $node );
430
+ return;
431
+ }
432
+
433
+ // Remove element if it has illegal CDATA.
434
+ if ( ! empty( $cdata ) && $node instanceof DOMElement ) {
435
+ $validity = $this->validate_cdata_for_node( $node, $cdata );
436
+ if ( is_wp_error( $validity ) ) {
437
+ $this->remove_node( $node );
438
+ return;
439
+ }
440
+ }
441
+
442
+ $merged_attr_spec_list = array_merge(
443
+ $this->globally_allowed_attributes,
444
+ $attr_spec_list
445
+ );
446
+
447
+ // Identify any remaining disallowed attributes.
448
+ $disallowed_attributes = $this->get_disallowed_attributes_in_node( $node, $merged_attr_spec_list );
449
+
450
+ // Identify attribute values that don't conform to the attr_spec.
451
+ $disallowed_attributes = $this->sanitize_disallowed_attribute_values_in_node( $node, $merged_attr_spec_list, $disallowed_attributes );
452
+
453
+ // If $disallowed_attributes is false then the entire element should be removed.
454
+ if ( false === $disallowed_attributes ) {
455
+ $this->remove_node( $node );
456
+ return;
457
+ }
458
+
459
+ // Remove all invalid attributes.
460
+ foreach ( $disallowed_attributes as $disallowed_attribute ) {
461
+ $this->remove_invalid_attribute( $node, $disallowed_attribute );
462
+ }
463
+
464
+ // Add required AMP component scripts if the element is still in the document.
465
+ if ( $node->parentNode ) {
466
+ if ( ! empty( $tag_spec['also_requires_tag_warning'] ) ) {
467
+ $this->script_components[] = strtok( $tag_spec['also_requires_tag_warning'][0], ' ' );
468
+ }
469
+ if ( ! empty( $tag_spec['requires_extension'] ) ) {
470
+ $this->script_components = array_merge( $this->script_components, $tag_spec['requires_extension'] );
471
+ }
472
+
473
+ // Check if element needs amp-bind component.
474
+ if ( $node instanceof DOMElement && ! in_array( 'amp-bind', $this->script_components, true ) ) {
475
+ foreach ( $node->attributes as $name => $value ) {
476
+ $is_bind_attribute = (
477
+ '[' === $name[0]
478
+ ||
479
+ ( isset( $this->rev_alternate_attr_name_lookup[ $name ] ) && '[' === $this->rev_alternate_attr_name_lookup[ $name ][0] )
480
+ );
481
+ if ( $is_bind_attribute ) {
482
+ $this->script_components[] = 'amp-bind';
483
+ break;
484
+ }
485
+ }
486
+ }
487
+ }
488
+ }
489
+
490
+ /**
491
+ * Whether a node is missing a mandatory attribute.
492
+ *
493
+ * @param array $attr_spec The attribute specification.
494
+ * @param DOMElement $node The DOMElement of the node to check.
495
+ * @return boolean $is_missing boolean Whether a required attribute is missing.
496
+ */
497
+ public function is_missing_mandatory_attribute( $attr_spec, $node ) {
498
+ if ( ! is_array( $attr_spec ) ) {
499
+ return false;
500
+ }
501
+ foreach ( $attr_spec as $attr_name => $attr_spec_rule_value ) {
502
+ if ( '\u' === substr( $attr_name, 0, 2 ) ) {
503
+ $attr_name = html_entity_decode( '&#x' . substr( $attr_name, 2 ) . ';' ); // Probably ⚡.
504
+ }
505
+ $is_mandatory = isset( $attr_spec_rule_value[ AMP_Rule_Spec::MANDATORY ] ) ? ( true === $attr_spec_rule_value[ AMP_Rule_Spec::MANDATORY ] ) : false;
506
+ $attribute_exists = false;
507
+ if ( method_exists( $node, 'hasAttribute' ) ) {
508
+ $attribute_exists = $node->hasAttribute( $attr_name );
509
+ if ( ! $attribute_exists && ! empty( $attr_spec_rule_value[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] ) ) {
510
+ foreach ( $attr_spec_rule_value[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] as $alternative_attr_name ) {
511
+ if ( $node->hasAttribute( $alternative_attr_name ) ) {
512
+ $attribute_exists = true;
513
+ break;
514
+ }
515
+ }
516
+ }
517
+ }
518
+ if ( $is_mandatory && ! $attribute_exists ) {
519
+ return true;
520
+ }
521
+ }
522
+ return false;
523
+ }
524
+
525
+ /**
526
+ * Validate element for its CDATA.
527
+ *
528
+ * @since 0.7
529
+ *
530
+ * @param DOMElement $element Element.
531
+ * @param array $cdata_spec CDATA.
532
+ * @return true|WP_Error True when valid or error when invalid.
533
+ */
534
+ private function validate_cdata_for_node( $element, $cdata_spec ) {
535
+ if ( isset( $cdata_spec['blacklisted_cdata_regex'] ) ) {
536
+ if ( preg_match( '@' . $cdata_spec['blacklisted_cdata_regex']['regex'] . '@u', $element->textContent ) ) {
537
+ return new WP_Error( $cdata_spec['blacklisted_cdata_regex']['error_message'] );
538
+ }
539
+ }
540
+ return true;
541
+ }
542
+
543
+ /**
544
+ * Determines is a node is currently valid per its tag specification.
545
+ *
546
+ * Checks to see if a node's placement with the DOM is be valid for the
547
+ * given tag_spec. If there are restrictions placed on the type of node
548
+ * that can be an immediate parent or an ancestor of this node, then make
549
+ * sure those restrictions are met.
550
+ *
551
+ * @since 0.5
552
+ *
553
+ * @param DOMNode $node The node to validate.
554
+ * @param array $tag_spec The specification.
555
+ * @return boolean $valid Whether the node's placement is valid.
556
+ */
557
+ private function validate_tag_spec_for_node( $node, $tag_spec ) {
558
+
559
+ if ( ! empty( $tag_spec[ AMP_Rule_Spec::MANDATORY_PARENT ] ) && ! $this->has_parent( $node, $tag_spec[ AMP_Rule_Spec::MANDATORY_PARENT ] ) ) {
560
+ return false;
561
+ }
562
+
563
+ // Extension scripts must be in the head.
564
+ if ( isset( $tag_spec['extension_spec'] ) && ! $this->has_parent( $node, 'head' ) ) {
565
+ return false;
566
+ }
567
+
568
+ if ( ! empty( $tag_spec[ AMP_Rule_Spec::DISALLOWED_ANCESTOR ] ) ) {
569
+ foreach ( $tag_spec[ AMP_Rule_Spec::DISALLOWED_ANCESTOR ] as $disallowed_ancestor_node_name ) {
570
+ if ( $this->has_ancestor( $node, $disallowed_ancestor_node_name ) ) {
571
+ return false;
572
+ }
573
+ }
574
+ }
575
+
576
+ if ( ! empty( $tag_spec[ AMP_Rule_Spec::MANDATORY_ANCESTOR ] ) && ! $this->has_ancestor( $node, $tag_spec[ AMP_Rule_Spec::MANDATORY_ANCESTOR ] ) ) {
577
+ return false;
578
+ }
579
+
580
+ return true;
581
+ }
582
+
583
+ /**
584
+ * Checks to see if a spec is potentially valid.
585
+ *
586
+ * Checks the given node based on the attributes present in the node.
587
+ *
588
+ * @note This can be a very expensive function. Use it sparingly.
589
+ *
590
+ * @param DOMNode $node Node.
591
+ * @param array[] $attr_spec_list Attribute Spec list.
592
+ *
593
+ * @return float Number of times the attribute spec list matched. If there was a mismatch, then 0 is returned. 0.5 is returned if there is an implicit match.
594
+ */
595
+ private function validate_attr_spec_list_for_node( $node, $attr_spec_list ) {
596
+ /*
597
+ * If node has no attributes there is no point in continuing, but if none of attributes
598
+ * in the spec list are mandatory, then we give this a score.
599
+ */
600
+ if ( ! $node->hasAttributes() ) {
601
+ foreach ( $attr_spec_list as $attr_name => $attr_spec_rule ) {
602
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::MANDATORY ] ) ) {
603
+ return 0;
604
+ }
605
+ }
606
+ return 0.5;
607
+ }
608
+
609
+ if ( ! $node instanceof DOMElement ) {
610
+ /*
611
+ * A DOMNode is not valid for checks so might
612
+ * as well bail here is not an DOMElement.
613
+ */
614
+ return 0;
615
+ }
616
+
617
+ foreach ( $node->attributes as $attr_name => $attr_node ) {
618
+ if ( ! isset( $attr_spec_list[ $attr_name ][ AMP_Rule_Spec::ALTERNATIVE_NAMES ] ) ) {
619
+ continue;
620
+ }
621
+ foreach ( $attr_spec_list[ $attr_name ][ AMP_Rule_Spec::ALTERNATIVE_NAMES ] as $attr_alt_name ) {
622
+ $attr_spec_list[ $attr_alt_name ] = $attr_spec_list[ $attr_name ];
623
+ }
624
+ }
625
+
626
+ $score = 0;
627
+
628
+ /*
629
+ * Keep track of how many of the attribute spec rules are mandatory,
630
+ * because if none are mandatory, then we will let this rule have a
631
+ * score since all the invalid attributes can just be removed.
632
+ */
633
+ $mandatory_count = 0;
634
+
635
+ /*
636
+ * Iterate through each attribute rule in this attr spec list and run
637
+ * the series of tests. Each filter is given a `$node`, an `$attr_name`,
638
+ * and an `$attr_spec_rule`. If the `$attr_spec_rule` seems to be valid
639
+ * for the given node, then the filter should increment the score by one.
640
+ */
641
+ foreach ( $attr_spec_list as $attr_name => $attr_spec_rule ) {
642
+
643
+ // If attr spec rule is empty, then it allows anything.
644
+ if ( empty( $attr_spec_rule ) && $node->hasAttribute( $attr_name ) ) {
645
+ $score++;
646
+ continue;
647
+ }
648
+
649
+ // If a mandatory attribute is required, and attribute exists, pass.
650
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::MANDATORY ] ) ) {
651
+ $mandatory_count++;
652
+ $result = $this->check_attr_spec_rule_mandatory( $node, $attr_name, $attr_spec_rule );
653
+ if ( AMP_Rule_Spec::PASS === $result ) {
654
+ $score++;
655
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
656
+ return 0;
657
+ }
658
+ }
659
+
660
+ /*
661
+ * Check 'value' - case sensitive
662
+ * Given attribute's value must exactly equal value of the rule to pass.
663
+ */
664
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE ] ) ) {
665
+ $result = $this->check_attr_spec_rule_value( $node, $attr_name, $attr_spec_rule );
666
+ if ( AMP_Rule_Spec::PASS === $result ) {
667
+ $score++;
668
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
669
+ return 0;
670
+ }
671
+ }
672
+
673
+ /*
674
+ * Check 'value_regex' - case sensitive regex match
675
+ * Given attribute's value must be a case insensitive match to regex pattern
676
+ * specified by the value of rule to pass.
677
+ */
678
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_REGEX ] ) ) {
679
+ $result = $this->check_attr_spec_rule_value_regex( $node, $attr_name, $attr_spec_rule );
680
+ if ( AMP_Rule_Spec::PASS === $result ) {
681
+ $score++;
682
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
683
+ return 0;
684
+ }
685
+ }
686
+
687
+ /*
688
+ * Check 'value_casei' - case insensitive
689
+ * Given attribute's value must be a case insensitive match to the value of
690
+ * the rule to pass.
691
+ */
692
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_CASEI ] ) ) {
693
+ $result = $this->check_attr_spec_rule_value_casei( $node, $attr_name, $attr_spec_rule );
694
+ if ( AMP_Rule_Spec::PASS === $result ) {
695
+ $score++;
696
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
697
+ return 0;
698
+ }
699
+ }
700
+
701
+ /*
702
+ * Check 'value_regex_casei' - case insensitive regex match
703
+ * Given attribute's value must be a case insensitive match to the regex
704
+ * pattern specified by the value of the rule to pass.
705
+ */
706
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_REGEX_CASEI ] ) ) {
707
+ $result = $this->check_attr_spec_rule_value_regex_casei( $node, $attr_name, $attr_spec_rule );
708
+ if ( AMP_Rule_Spec::PASS === $result ) {
709
+ $score++;
710
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
711
+ return 0;
712
+ }
713
+ }
714
+
715
+ /*
716
+ * If given attribute's value is a URL with a protocol, the protocol must
717
+ * be in the array specified by the rule's value to pass.
718
+ */
719
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOWED_PROTOCOL ] ) ) {
720
+ $result = $this->check_attr_spec_rule_allowed_protocol( $node, $attr_name, $attr_spec_rule );
721
+ if ( AMP_Rule_Spec::PASS === $result ) {
722
+ $score++;
723
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
724
+ return 0;
725
+ }
726
+ }
727
+
728
+ /*
729
+ * If given attribute's value is a URL with a host, the host must
730
+ * be valid
731
+ */
732
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ] ) ) {
733
+ $result = $this->check_attr_spec_rule_valid_url( $node, $attr_name, $attr_spec_rule );
734
+ if ( AMP_Rule_Spec::PASS === $result ) {
735
+ $score++;
736
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
737
+ return 0;
738
+ }
739
+ }
740
+
741
+ /*
742
+ * If the given attribute's value is *not* a relative path, and the rule's
743
+ * value is `false`, then pass.
744
+ */
745
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOW_RELATIVE ] ) ) {
746
+ $result = $this->check_attr_spec_rule_disallowed_relative( $node, $attr_name, $attr_spec_rule );
747
+ if ( AMP_Rule_Spec::PASS === $result ) {
748
+ $score++;
749
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
750
+ return 0;
751
+ }
752
+ }
753
+
754
+ /*
755
+ * If the given attribute's value exists, is non-empty and the rule's value
756
+ * is false, then pass.
757
+ */
758
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOW_EMPTY ] ) ) {
759
+ $result = $this->check_attr_spec_rule_disallowed_empty( $node, $attr_name, $attr_spec_rule );
760
+ if ( AMP_Rule_Spec::PASS === $result ) {
761
+ $score++;
762
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
763
+ return 0;
764
+ }
765
+ }
766
+
767
+ /*
768
+ * If the given attribute's value is a URL and does not match any of the list
769
+ * of domains in the value of the rule, then pass.
770
+ */
771
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::DISALLOWED_DOMAIN ] ) ) {
772
+ $result = $this->check_attr_spec_rule_disallowed_domain( $node, $attr_name, $attr_spec_rule );
773
+ if ( AMP_Rule_Spec::PASS === $result ) {
774
+ $score++;
775
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
776
+ return 0;
777
+ }
778
+ }
779
+
780
+ /*
781
+ * If the attribute's value exists and does not match the regex specified
782
+ * by the rule's value, then pass.
783
+ */
784
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::BLACKLISTED_VALUE_REGEX ] ) ) {
785
+ $result = $this->check_attr_spec_rule_blacklisted_value_regex( $node, $attr_name, $attr_spec_rule );
786
+ if ( AMP_Rule_Spec::PASS === $result ) {
787
+ $score++;
788
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
789
+ return 0;
790
+ }
791
+ }
792
+
793
+ // If the attribute's value exists and it matches the value properties spec.
794
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_PROPERTIES ] ) && $node->hasAttribute( $attr_name ) ) {
795
+ $result = $this->check_attr_spec_rule_value_properties( $node, $attr_name, $attr_spec_rule );
796
+ if ( AMP_Rule_Spec::PASS === $result ) {
797
+ $score++;
798
+ } elseif ( AMP_Rule_Spec::FAIL === $result ) {
799
+ return 0;
800
+ }
801
+ }
802
+ }
803
+
804
+ // Give the spec a score if it doesn't have any mandatory attributes.
805
+ if ( 0 === $mandatory_count && 0 === $score ) {
806
+ $score = 0.5;
807
+ }
808
+
809
+ return $score;
810
+ }
811
+
812
+ /**
813
+ * Remove attributes from $node that are not listed in $allowed_attrs.
814
+ *
815
+ * @param DOMNode $node Node.
816
+ * @param array[] $attr_spec_list Attribute spec list.
817
+ * @return DOMAttr[] Attributes to remove.
818
+ */
819
+ private function get_disallowed_attributes_in_node( $node, $attr_spec_list ) {
820
+
821
+ if ( ! $node instanceof DOMElement ) {
822
+ /**
823
+ * If $node is only a DOMNode and not a DOMElement we can't
824
+ * remove an attribute from it anyway. So bail out now.
825
+ */
826
+ return array();
827
+ }
828
+
829
+ /*
830
+ * We can't remove attributes inside the 'foreach' loop without
831
+ * breaking the iteration. So we keep track of the attributes to
832
+ * remove in the first loop, then remove them in the second loop.
833
+ */
834
+ $attrs_to_remove = array();
835
+ foreach ( $node->attributes as $attr_name => $attr_node ) {
836
+ if ( ! $this->is_amp_allowed_attribute( $attr_name, $attr_spec_list ) ) {
837
+ $attrs_to_remove[] = $attr_node;
838
+ }
839
+ }
840
+
841
+ return $attrs_to_remove;
842
+ }
843
+
844
+ /**
845
+ * Remove invalid AMP attributes values from $node that have been implicitly disallowed.
846
+ *
847
+ * Allowed values are found $this->globally_allowed_attributes and in parameter $attr_spec_list
848
+ *
849
+ * @param DOMNode $node Node.
850
+ * @param array[][] $attr_spec_list Attribute spec list.
851
+ * @param DOMAttr[] $attributes_pending_removal Attributes pending removal.
852
+ * @return DOMAttr[]|false Attributes to remove, or false if the element itself should be removed.
853
+ */
854
+ private function sanitize_disallowed_attribute_values_in_node( $node, $attr_spec_list, $attributes_pending_removal ) {
855
+
856
+ if ( ! $node instanceof DOMElement ) {
857
+ /*
858
+ * If $node is only a DOMNode and not a DOMElement we can't
859
+ * remove an attribute from it anyway. So bail out now.
860
+ */
861
+ return $attributes_pending_removal;
862
+ }
863
+
864
+ return $this->delegated_sanitize_disallowed_attribute_values_in_node(
865
+ $node,
866
+ array_merge(
867
+ $this->globally_allowed_attributes,
868
+ $attr_spec_list
869
+ ),
870
+ $attributes_pending_removal
871
+ );
872
+ }
873
+
874
+ /**
875
+ * Remove attributes values from $node that have been disallowed by AMP.
876
+ *
877
+ * @see $this->sanitize_disallowed_attribute_values_in_node() which delegates to this method
878
+ *
879
+ * @param DOMElement $node Node.
880
+ * @param array[][] $attr_spec_list Attribute spec list.
881
+ * @param DOMAttr[] $attributes_pending_removal Attributes pending removal.
882
+ * @return DOMAttr[]|false Attributes to remove, or false if the element itself should be removed.
883
+ */
884
+ private function delegated_sanitize_disallowed_attribute_values_in_node( $node, $attr_spec_list, $attributes_pending_removal ) {
885
+ $attrs_to_remove = array();
886
+
887
+ foreach ( $attr_spec_list as $attr_name => $attr_val ) {
888
+ if ( isset( $attr_spec_list[ $attr_name ][ AMP_Rule_Spec::ALTERNATIVE_NAMES ] ) ) {
889
+ foreach ( $attr_spec_list[ $attr_name ][ AMP_Rule_Spec::ALTERNATIVE_NAMES ] as $attr_alt_name ) {
890
+ $attr_spec_list[ $attr_alt_name ] = $attr_spec_list[ $attr_name ];
891
+ }
892
+ }
893
+ }
894
+
895
+ foreach ( $node->attributes as $attr_name => $attr_node ) {
896
+
897
+ if ( ! isset( $attr_spec_list[ $attr_name ] ) || in_array( $attr_node, $attributes_pending_removal, true ) ) {
898
+ continue;
899
+ }
900
+
901
+ $should_remove_node = false;
902
+ $attr_spec_rule = $attr_spec_list[ $attr_name ];
903
+
904
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE ] ) &&
905
+ AMP_Rule_Spec::FAIL === $this->check_attr_spec_rule_value( $node, $attr_name, $attr_spec_rule ) ) {
906
+ $should_remove_node = true;
907
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_CASEI ] ) &&
908
+ AMP_Rule_Spec::FAIL === $this->check_attr_spec_rule_value_casei( $node, $attr_name, $attr_spec_rule ) ) {
909
+ $should_remove_node = true;
910
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_REGEX ] ) &&
911
+ AMP_Rule_Spec::FAIL === $this->check_attr_spec_rule_value_regex( $node, $attr_name, $attr_spec_rule ) ) {
912
+ $should_remove_node = true;
913
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_REGEX_CASEI ] ) &&
914
+ AMP_Rule_Spec::FAIL === $this->check_attr_spec_rule_value_regex_casei( $node, $attr_name, $attr_spec_rule ) ) {
915
+ $should_remove_node = true;
916
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOWED_PROTOCOL ] ) &&
917
+ AMP_Rule_Spec::FAIL === $this->check_attr_spec_rule_allowed_protocol( $node, $attr_name, $attr_spec_rule ) ) {
918
+ $should_remove_node = true;
919
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ] ) &&
920
+ AMP_Rule_Spec::FAIL === $this->check_attr_spec_rule_valid_url( $node, $attr_name, $attr_spec_rule ) ) {
921
+ $should_remove_node = true;
922
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOW_RELATIVE ] ) &&
923
+ AMP_Rule_Spec::FAIL === $this->check_attr_spec_rule_disallowed_relative( $node, $attr_name, $attr_spec_rule ) ) {
924
+ $should_remove_node = true;
925
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOW_EMPTY ] ) &&
926
+ AMP_Rule_Spec::FAIL === $this->check_attr_spec_rule_disallowed_empty( $node, $attr_name, $attr_spec_rule ) ) {
927
+ $should_remove_node = true;
928
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::DISALLOWED_DOMAIN ] ) &&
929
+ AMP_Rule_Spec::FAIL === $this->check_attr_spec_rule_disallowed_domain( $node, $attr_name, $attr_spec_rule ) ) {
930
+ $should_remove_node = true;
931
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::BLACKLISTED_VALUE_REGEX ] ) &&
932
+ AMP_Rule_Spec::FAIL === $this->check_attr_spec_rule_blacklisted_value_regex( $node, $attr_name, $attr_spec_rule ) ) {
933
+ $should_remove_node = true;
934
+ }
935
+
936
+ if ( $should_remove_node ) {
937
+ $is_mandatory =
938
+ isset( $attr_spec_rule[ AMP_Rule_Spec::MANDATORY ] )
939
+ ? (bool) $attr_spec_rule[ AMP_Rule_Spec::MANDATORY ]
940
+ : false;
941
+
942
+ if ( $is_mandatory ) {
943
+ $this->remove_node( $node );
944
+ return false;
945
+ }
946
+
947
+ $attrs_to_remove[] = $attr_node;
948
+ }
949
+ }
950
+
951
+ // Remove the disallowed values.
952
+ foreach ( $attrs_to_remove as $attr_node ) {
953
+ if ( isset( $attr_spec_list[ $attr_node->nodeName ][ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOW_EMPTY ] ) &&
954
+ ( true === $attr_spec_list[ $attr_node->nodeName ][ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOW_EMPTY ] ) ) {
955
+ $attr_node->nodeValue = '';
956
+ } else {
957
+ $attributes_pending_removal[] = $attr_node;
958
+ }
959
+ }
960
+
961
+ return $attributes_pending_removal;
962
+ }
963
+
964
+ /**
965
+ * Check if attribute is mandatory determine whether it exists in $node.
966
+ *
967
+ * When checking for the given attribute it also checks valid alternates.
968
+ *
969
+ * @param DOMElement $node Node.
970
+ * @param string $attr_name Attribute name.
971
+ * @param array[] $attr_spec_rule Attribute spec rule.
972
+ *
973
+ * @return string:
974
+ * - AMP_Rule_Spec::PASS - $attr_name is mandatory and it exists
975
+ * - AMP_Rule_Spec::FAIL - $attr_name is mandatory, but doesn't exist
976
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name is not mandatory
977
+ */
978
+ private function check_attr_spec_rule_mandatory( $node, $attr_name, $attr_spec_rule ) {
979
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::MANDATORY ] ) && ( $attr_spec_rule[ AMP_Rule_Spec::MANDATORY ] ) ) {
980
+ if ( $node->hasAttribute( $attr_name ) ) {
981
+ return AMP_Rule_Spec::PASS;
982
+ } else {
983
+ // Check if an alternative name list is specified.
984
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] ) ) {
985
+ foreach ( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] as $alt_name ) {
986
+ if ( $node->hasAttribute( $alt_name ) ) {
987
+ return AMP_Rule_Spec::PASS;
988
+ }
989
+ }
990
+ }
991
+ return AMP_Rule_Spec::FAIL;
992
+ }
993
+ }
994
+ return AMP_Rule_Spec::NOT_APPLICABLE;
995
+ }
996
+
997
+ /**
998
+ * Check if attribute has a value rule determine if its value is valid.
999
+ *
1000
+ * Checks for value validity by matches against valid values.
1001
+ *
1002
+ * @param DOMElement $node Node.
1003
+ * @param string $attr_name Attribute name.
1004
+ * @param array $attr_spec_rule Attribute spec rule.
1005
+ *
1006
+ * @return string:
1007
+ * - AMP_Rule_Spec::PASS - $attr_name has a value that matches the rule.
1008
+ * - AMP_Rule_Spec::FAIL - $attr_name has a value that does *not* match rule.
1009
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name does not exist or there
1010
+ * is no rule for this attribute.
1011
+ */
1012
+ private function check_attr_spec_rule_value( $node, $attr_name, $attr_spec_rule ) {
1013
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE ] ) ) {
1014
+ if ( $node->hasAttribute( $attr_name ) ) {
1015
+ if ( $this->check_matching_attribute_value( $attr_name, $node->getAttribute( $attr_name ), $attr_spec_rule[ AMP_Rule_Spec::VALUE ] ) ) {
1016
+ return AMP_Rule_Spec::PASS;
1017
+ } else {
1018
+ return AMP_Rule_Spec::FAIL;
1019
+ }
1020
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] ) ) {
1021
+ foreach ( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] as $alternative_name ) {
1022
+ if ( $node->hasAttribute( $alternative_name ) ) {
1023
+ if ( $this->check_matching_attribute_value( $attr_name, $node->getAttribute( $alternative_name ), $attr_spec_rule[ AMP_Rule_Spec::VALUE ] ) ) {
1024
+ return AMP_Rule_Spec::PASS;
1025
+ } else {
1026
+ return AMP_Rule_Spec::FAIL;
1027
+ }
1028
+ }
1029
+ }
1030
+ }
1031
+ }
1032
+ return AMP_Rule_Spec::NOT_APPLICABLE;
1033
+ }
1034
+
1035
+ /**
1036
+ * Check that an attribute's value matches is given spec value.
1037
+ *
1038
+ * This takes into account boolean attributes where value can match name (e.g. selected="selected").
1039
+ *
1040
+ * @since 0.7.0
1041
+ *
1042
+ * @param string $attr_name Attribute name.
1043
+ * @param string $attr_value Attribute value.
1044
+ * @param string $spec_value Attribute spec value.
1045
+ * @return bool Is value valid.
1046
+ */
1047
+ private function check_matching_attribute_value( $attr_name, $attr_value, $spec_value ) {
1048
+ if ( $spec_value === $attr_value ) {
1049
+ return true;
1050
+ }
1051
+
1052
+ // Check for boolean attribute.
1053
+ return (
1054
+ '' === $spec_value
1055
+ &&
1056
+ in_array( $attr_name, AMP_Rule_Spec::$boolean_attributes, true )
1057
+ &&
1058
+ strtolower( $attr_value ) === strtolower( $attr_name )
1059
+ );
1060
+ }
1061
+
1062
+ /**
1063
+ * Check if attribute has a value rule determine if its value matches ignoring case.
1064
+ *
1065
+ * @param DOMElement $node Node.
1066
+ * @param string $attr_name Attribute name.
1067
+ * @param array[]|string[] $attr_spec_rule Attribute spec rule.
1068
+ *
1069
+ * @return string:
1070
+ * - AMP_Rule_Spec::PASS - $attr_name has a value that matches the rule.
1071
+ * - AMP_Rule_Spec::FAIL - $attr_name has a value that does *not* match rule.
1072
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name does not exist or there
1073
+ * is no rule for this attribute.
1074
+ */
1075
+ private function check_attr_spec_rule_value_casei( $node, $attr_name, $attr_spec_rule ) {
1076
+ /**
1077
+ * Check 'value_casei' - case insensitive
1078
+ */
1079
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_CASEI ] ) ) {
1080
+ $rule_value = strtolower( $attr_spec_rule[ AMP_Rule_Spec::VALUE_CASEI ] );
1081
+ if ( $node->hasAttribute( $attr_name ) ) {
1082
+ $attr_value = strtolower( $node->getAttribute( $attr_name ) );
1083
+ if ( $attr_value === (string) $rule_value ) {
1084
+ return AMP_Rule_Spec::PASS;
1085
+ } else {
1086
+ return AMP_Rule_Spec::FAIL;
1087
+ }
1088
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] ) ) {
1089
+ foreach ( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] as $alternative_name ) {
1090
+ if ( $node->hasAttribute( $alternative_name ) ) {
1091
+ $attr_value = strtolower( $node->getAttribute( $alternative_name ) );
1092
+ if ( $attr_value === (string) $rule_value ) {
1093
+ return AMP_Rule_Spec::PASS;
1094
+ } else {
1095
+ return AMP_Rule_Spec::FAIL;
1096
+ }
1097
+ }
1098
+ }
1099
+ }
1100
+ }
1101
+ return AMP_Rule_Spec::NOT_APPLICABLE;
1102
+ }
1103
+
1104
+ /**
1105
+ * Check if attribute has a regex value rule determine if it matches.
1106
+ *
1107
+ * @param DOMElement $node Node.
1108
+ * @param string $attr_name Attribute name.
1109
+ * @param array[]|string[] $attr_spec_rule Attribute spec rule.
1110
+ *
1111
+ * @return string:
1112
+ * - AMP_Rule_Spec::PASS - $attr_name has a value that matches the rule.
1113
+ * - AMP_Rule_Spec::FAIL - $attr_name has a value that does *not* match rule.
1114
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name does not exist or there
1115
+ * is no rule for this attribute.
1116
+ */
1117
+ private function check_attr_spec_rule_value_regex( $node, $attr_name, $attr_spec_rule ) {
1118
+ // Check 'value_regex' - case sensitive regex match.
1119
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_REGEX ] ) && $node->hasAttribute( $attr_name ) ) {
1120
+ $rule_value = $attr_spec_rule[ AMP_Rule_Spec::VALUE_REGEX ];
1121
+
1122
+ /*
1123
+ * The regex pattern has '^' and '$' though they are not in the AMP spec.
1124
+ * Leaving them out would allow both '_blank' and 'yyy_blankzzz' to be
1125
+ * matched by a regex rule of '(_blank|_self|_top)'. As the AMP JS validator
1126
+ * only accepts '_blank' we leave it this way for now.
1127
+ */
1128
+ if ( preg_match( '@^' . $rule_value . '$@u', $node->getAttribute( $attr_name ) ) ) {
1129
+ return AMP_Rule_Spec::PASS;
1130
+ } else {
1131
+ return AMP_Rule_Spec::FAIL;
1132
+ }
1133
+ }
1134
+ return AMP_Rule_Spec::NOT_APPLICABLE;
1135
+ }
1136
+
1137
+ /**
1138
+ * Check if attribute has a case-insensitive regex value rule determine if it matches.
1139
+ *
1140
+ * @param DOMElement $node Node.
1141
+ * @param string $attr_name Attribute name.
1142
+ * @param array[]|string[] $attr_spec_rule Attribute spec rule.
1143
+ *
1144
+ * @return string:
1145
+ * - AMP_Rule_Spec::PASS - $attr_name has a value that matches the rule.
1146
+ * - AMP_Rule_Spec::FAIL - $attr_name has a value that does *not* match rule.
1147
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name does not exist or there
1148
+ * is no rule for this attribute.
1149
+ */
1150
+ private function check_attr_spec_rule_value_regex_casei( $node, $attr_name, $attr_spec_rule ) {
1151
+ /**
1152
+ * Check 'value_regex_casei' - case insensitive regex match
1153
+ */
1154
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_REGEX_CASEI ] ) && $node->hasAttribute( $attr_name ) ) {
1155
+ $rule_value = $attr_spec_rule[ AMP_Rule_Spec::VALUE_REGEX_CASEI ];
1156
+
1157
+ // See note above regarding the '^' and '$' that are added here.
1158
+ if ( preg_match( '/^' . $rule_value . '$/ui', $node->getAttribute( $attr_name ) ) ) {
1159
+ return AMP_Rule_Spec::PASS;
1160
+ } else {
1161
+ return AMP_Rule_Spec::FAIL;
1162
+ }
1163
+ }
1164
+ return AMP_Rule_Spec::NOT_APPLICABLE;
1165
+ }
1166
+
1167
+ /**
1168
+ * Check if attribute has a valid host value
1169
+ *
1170
+ * @since 0.7
1171
+ *
1172
+ * @param DOMElement $node Node.
1173
+ * @param string $attr_name Attribute name.
1174
+ * @param array[]|string[] $attr_spec_rule Attribute spec rule.
1175
+ *
1176
+ * @return string:
1177
+ * - AMP_Rule_Spec::PASS - $attr_name has a value that matches the rule.
1178
+ * - AMP_Rule_Spec::FAIL - $attr_name has a value that does *not* match rule.
1179
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name does not exist or there
1180
+ * is no rule for this attribute.
1181
+ */
1182
+ private function check_attr_spec_rule_valid_url( $node, $attr_name, $attr_spec_rule ) {
1183
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ] ) ) {
1184
+ if ( $node->hasAttribute( $attr_name ) ) {
1185
+ $urls_to_test = preg_split( '/\s*,\s*/', $node->getAttribute( $attr_name ) );
1186
+ foreach ( $urls_to_test as $url ) {
1187
+ $url = urldecode( $url );
1188
+ // Check if the host contains invalid chars.
1189
+ $url_host = wp_parse_url( $url, PHP_URL_HOST );
1190
+ if ( $url_host && preg_match( '/[!"#$%&\'()*+,\/:;<=>?@[\]^`{|}~\s]/i', $url_host ) ) {
1191
+ return AMP_Rule_Spec::FAIL;
1192
+ }
1193
+
1194
+ // Check if the protocol contains invalid chars.
1195
+ $dots_pos = strpos( $url, ':' );
1196
+ if ( false !== $dots_pos && preg_match( '/[!"#$%&\'()*+,\/:;<=>?@[\]^`{|}~\s]/i', substr( $url, 0, $dots_pos ) ) ) {
1197
+ return AMP_Rule_Spec::FAIL;
1198
+ }
1199
+ }
1200
+
1201
+ return AMP_Rule_Spec::PASS;
1202
+ }
1203
+ }
1204
+
1205
+ return AMP_Rule_Spec::NOT_APPLICABLE;
1206
+ }
1207
+
1208
+ /**
1209
+ * Check if attribute has a protocol value rule determine if it matches.
1210
+ *
1211
+ * @param DOMElement $node Node.
1212
+ * @param string $attr_name Attribute name.
1213
+ * @param array[]|string[] $attr_spec_rule Attribute spec rule.
1214
+ *
1215
+ * @return string:
1216
+ * - AMP_Rule_Spec::PASS - $attr_name has a value that matches the rule.
1217
+ * - AMP_Rule_Spec::FAIL - $attr_name has a value that does *not* match rule.
1218
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name does not exist or there
1219
+ * is no rule for this attribute.
1220
+ */
1221
+ private function check_attr_spec_rule_allowed_protocol( $node, $attr_name, $attr_spec_rule ) {
1222
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOWED_PROTOCOL ] ) ) {
1223
+ if ( $node->hasAttribute( $attr_name ) ) {
1224
+ $urls_to_test = preg_split( '/\s*,\s*/', $node->getAttribute( $attr_name ) );
1225
+ foreach ( $urls_to_test as $url ) {
1226
+ /*
1227
+ * This seems to be an acceptable check since the AMP validator
1228
+ * will allow a URL with no protocol to pass validation.
1229
+ */
1230
+ $url_scheme = AMP_WP_Utils::parse_url( $url, PHP_URL_SCHEME );
1231
+ if ( $url_scheme ) {
1232
+ if ( ! in_array( strtolower( $url_scheme ), $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOWED_PROTOCOL ], true ) ) {
1233
+ return AMP_Rule_Spec::FAIL;
1234
+ }
1235
+ }
1236
+ }
1237
+ return AMP_Rule_Spec::PASS;
1238
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] ) ) {
1239
+ foreach ( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] as $alternative_name ) {
1240
+ if ( $node->hasAttribute( $alternative_name ) ) {
1241
+ $urls_to_test = preg_split( '/\s*,\s*/', $node->getAttribute( $alternative_name ) );
1242
+ foreach ( $urls_to_test as $url ) {
1243
+ /*
1244
+ * This seems to be an acceptable check since the AMP validator
1245
+ * will allow a URL with no protocol to pass validation.
1246
+ */
1247
+ $url_scheme = AMP_WP_Utils::parse_url( $url, PHP_URL_SCHEME );
1248
+ if ( $url_scheme ) {
1249
+ if ( ! in_array( strtolower( $url_scheme ), $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOWED_PROTOCOL ], true ) ) {
1250
+ return AMP_Rule_Spec::FAIL;
1251
+ }
1252
+ }
1253
+ }
1254
+ return AMP_Rule_Spec::PASS;
1255
+ }
1256
+ }
1257
+ }
1258
+ }
1259
+ return AMP_Rule_Spec::NOT_APPLICABLE;
1260
+ }
1261
+
1262
+ /**
1263
+ * Check if attribute has disallowed relative value rule determine if disallowed relative value matches.
1264
+ *
1265
+ * @param DOMElement $node Node.
1266
+ * @param string $attr_name Attribute name.
1267
+ * @param array[]|string[] $attr_spec_rule Attribute spec rule.
1268
+ *
1269
+ * @return string:
1270
+ * - AMP_Rule_Spec::PASS - $attr_name has a value that matches the rule.
1271
+ * - AMP_Rule_Spec::FAIL - $attr_name has a value that does *not* match rule.
1272
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name does not exist or there
1273
+ * is no rule for this attribute.
1274
+ */
1275
+ private function check_attr_spec_rule_disallowed_relative( $node, $attr_name, $attr_spec_rule ) {
1276
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOW_RELATIVE ] ) && ! ( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOW_RELATIVE ] ) ) {
1277
+ if ( $node->hasAttribute( $attr_name ) ) {
1278
+ $urls_to_test = preg_split( '/\s*,\s*/', $node->getAttribute( $attr_name ) );
1279
+ foreach ( $urls_to_test as $url ) {
1280
+ $parsed_url = AMP_WP_Utils::parse_url( $url );
1281
+
1282
+ /*
1283
+ * The JS AMP validator seems to consider 'relative' to mean
1284
+ * *protocol* relative, not *host* relative for this rule. So,
1285
+ * a url with an empty 'scheme' is considered "relative" by AMP.
1286
+ * ie. '//domain.com/path' and '/path' should both be considered
1287
+ * relative for purposes of AMP validation.
1288
+ */
1289
+ if ( empty( $parsed_url['scheme'] ) ) {
1290
+ return AMP_Rule_Spec::FAIL;
1291
+ }
1292
+ }
1293
+ return AMP_Rule_Spec::PASS;
1294
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] ) ) {
1295
+ foreach ( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] as $alternative_name ) {
1296
+ if ( $node->hasAttribute( $alternative_name ) ) {
1297
+ $urls_to_test = preg_split( '/\s*,\s*/', $node->getAttribute( $alternative_name ) );
1298
+ foreach ( $urls_to_test as $url ) {
1299
+ $parsed_url = AMP_WP_Utils::parse_url( $url );
1300
+ if ( empty( $parsed_url['scheme'] ) ) {
1301
+ return AMP_Rule_Spec::FAIL;
1302
+ }
1303
+ }
1304
+ }
1305
+ }
1306
+ return AMP_Rule_Spec::PASS;
1307
+ }
1308
+ }
1309
+ return AMP_Rule_Spec::NOT_APPLICABLE;
1310
+ }
1311
+
1312
+ /**
1313
+ * Check if attribute has disallowed empty value rule determine if value is empty.
1314
+ *
1315
+ * @param DOMElement $node Node.
1316
+ * @param string $attr_name Attribute name.
1317
+ * @param array[]|string[] $attr_spec_rule Attribute spec rule.
1318
+ *
1319
+ * @return string:
1320
+ * - AMP_Rule_Spec::PASS - $attr_name has a value that matches the rule.
1321
+ * - AMP_Rule_Spec::FAIL - $attr_name has a value that does *not* match rule.
1322
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name does not exist or there
1323
+ * is no rule for this attribute.
1324
+ */
1325
+ private function check_attr_spec_rule_disallowed_empty( $node, $attr_name, $attr_spec_rule ) {
1326
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOW_EMPTY ] ) && ! ( $attr_spec_rule[ AMP_Rule_Spec::VALUE_URL ][ AMP_Rule_Spec::ALLOW_EMPTY ] ) && $node->hasAttribute( $attr_name ) ) {
1327
+ $attr_value = $node->getAttribute( $attr_name );
1328
+ if ( empty( $attr_value ) ) {
1329
+ return AMP_Rule_Spec::FAIL;
1330
+ }
1331
+ return AMP_Rule_Spec::PASS;
1332
+ }
1333
+ return AMP_Rule_Spec::NOT_APPLICABLE;
1334
+ }
1335
+
1336
+ /**
1337
+ * Check if attribute has disallowed domain value rule determine if value matches.
1338
+ *
1339
+ * @param DOMElement $node Node.
1340
+ * @param string $attr_name Attribute name.
1341
+ * @param array[]|string[] $attr_spec_rule Attribute spec rule.
1342
+ *
1343
+ * @return string:
1344
+ * - AMP_Rule_Spec::PASS - $attr_name has a value that matches the rule.
1345
+ * - AMP_Rule_Spec::FAIL - $attr_name has a value that does *not* match rule.
1346
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name does not exist or there
1347
+ * is no rule for this attribute.
1348
+ */
1349
+ private function check_attr_spec_rule_disallowed_domain( $node, $attr_name, $attr_spec_rule ) {
1350
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::DISALLOWED_DOMAIN ] ) && $node->hasAttribute( $attr_name ) ) {
1351
+ $attr_value = $node->getAttribute( $attr_name );
1352
+ $url_domain = AMP_WP_Utils::parse_url( $attr_value, PHP_URL_HOST );
1353
+ if ( ! empty( $url_domain ) ) {
1354
+ foreach ( $attr_spec_rule[ AMP_Rule_Spec::DISALLOWED_DOMAIN ] as $disallowed_domain ) {
1355
+ if ( strtolower( $url_domain ) === strtolower( $disallowed_domain ) ) {
1356
+
1357
+ // Found a disallowed domain, fail validation.
1358
+ return AMP_Rule_Spec::FAIL;
1359
+ }
1360
+ }
1361
+ return AMP_Rule_Spec::PASS;
1362
+ }
1363
+ }
1364
+ return AMP_Rule_Spec::NOT_APPLICABLE;
1365
+ }
1366
+
1367
+ /**
1368
+ * Check if attribute has blacklisted value via regex match determine if value matches.
1369
+ *
1370
+ * @since 0.5
1371
+ *
1372
+ * @param DOMElement $node Node.
1373
+ * @param string $attr_name Attribute name.
1374
+ * @param array[]|string[] $attr_spec_rule Attribute spec rule.
1375
+ *
1376
+ * @return string:
1377
+ * - AMP_Rule_Spec::PASS - $attr_name has a value that matches the rule.
1378
+ * - AMP_Rule_Spec::FAIL - $attr_name has a value that does *not* match rule.
1379
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name does not exist or there
1380
+ * is no rule for this attribute.
1381
+ */
1382
+ private function check_attr_spec_rule_blacklisted_value_regex( $node, $attr_name, $attr_spec_rule ) {
1383
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::BLACKLISTED_VALUE_REGEX ] ) ) {
1384
+ $pattern = '/' . $attr_spec_rule[ AMP_Rule_Spec::BLACKLISTED_VALUE_REGEX ] . '/u';
1385
+ if ( $node->hasAttribute( $attr_name ) ) {
1386
+ $attr_value = $node->getAttribute( $attr_name );
1387
+ if ( preg_match( $pattern, $attr_value ) ) {
1388
+ return AMP_Rule_Spec::FAIL;
1389
+ } else {
1390
+ return AMP_Rule_Spec::PASS;
1391
+ }
1392
+ } elseif ( isset( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] ) ) {
1393
+ foreach ( $attr_spec_rule[ AMP_Rule_Spec::ALTERNATIVE_NAMES ] as $alternative_name ) {
1394
+ if ( $node->hasAttribute( $alternative_name ) ) {
1395
+ $attr_value = $node->getAttribute( $alternative_name );
1396
+ if ( preg_match( $pattern, $attr_value ) ) {
1397
+ return AMP_Rule_Spec::FAIL;
1398
+ } else {
1399
+ return AMP_Rule_Spec::PASS;
1400
+ }
1401
+ }
1402
+ }
1403
+ }
1404
+ }
1405
+ return AMP_Rule_Spec::NOT_APPLICABLE;
1406
+ }
1407
+
1408
+ /**
1409
+ * Check if attribute has valid properties.
1410
+ *
1411
+ * @since 0.7
1412
+ *
1413
+ * @param DOMElement $node Node.
1414
+ * @param string $attr_name Attribute name.
1415
+ * @param array[]|string[] $attr_spec_rule Attribute spec rule.
1416
+ *
1417
+ * @return string:
1418
+ * - AMP_Rule_Spec::PASS - $attr_name has a value that matches the rule.
1419
+ * - AMP_Rule_Spec::FAIL - $attr_name has a value that does *not* match rule.
1420
+ * - AMP_Rule_Spec::NOT_APPLICABLE - $attr_name does not exist or there
1421
+ * is no rule for this attribute.
1422
+ */
1423
+ private function check_attr_spec_rule_value_properties( $node, $attr_name, $attr_spec_rule ) {
1424
+ if ( isset( $attr_spec_rule[ AMP_Rule_Spec::VALUE_PROPERTIES ] ) && $node->hasAttribute( $attr_name ) ) {
1425
+ $properties = array();
1426
+ foreach ( explode( ',', $node->getAttribute( $attr_name ) ) as $pair ) {
1427
+ $pair_parts = explode( '=', $pair, 2 );
1428
+ if ( 2 !== count( $pair_parts ) ) {
1429
+ return 0;
1430
+ }
1431
+ $properties[ strtolower( $pair_parts[0] ) ] = $pair_parts[1];
1432
+ }
1433
+
1434
+ // Fail if there are unrecognized properties.
1435
+ if ( count( array_diff( array_keys( $properties ), array_keys( $attr_spec_rule[ AMP_Rule_Spec::VALUE_PROPERTIES ] ) ) ) > 0 ) {
1436
+ return AMP_Rule_Spec::FAIL;
1437
+ }
1438
+
1439
+ foreach ( $attr_spec_rule[ AMP_Rule_Spec::VALUE_PROPERTIES ] as $prop_name => $property_spec ) {
1440
+
1441
+ // Mandatory property is missing.
1442
+ if ( ! empty( $property_spec['mandatory'] ) && ! isset( $properties[ $prop_name ] ) ) {
1443
+ return AMP_Rule_Spec::FAIL;
1444
+ }
1445
+
1446
+ if ( ! isset( $properties[ $prop_name ] ) ) {
1447
+ continue;
1448
+ }
1449
+
1450
+ $prop_value = $properties[ $prop_name ];
1451
+
1452
+ // Required value is absent, so fail.
1453
+ $required_value = null;
1454
+ if ( isset( $property_spec['value'] ) ) {
1455
+ $required_value = $property_spec['value'];
1456
+ } elseif ( isset( $property_spec['value_double'] ) ) {
1457
+ $required_value = $property_spec['value_double'];
1458
+ $prop_value = (double) $prop_value;
1459
+ }
1460
+ if ( isset( $required_value ) && $prop_value !== $required_value ) {
1461
+ return AMP_Rule_Spec::FAIL;
1462
+ }
1463
+ }
1464
+ return AMP_Rule_Spec::PASS;
1465
+ }
1466
+ return AMP_Rule_Spec::NOT_APPLICABLE;
1467
+ }
1468
+
1469
+ /**
1470
+ * Determine if the supplied attribute name is allowed for AMP.
1471
+ *
1472
+ * @since 0.5
1473
+ *
1474
+ * @param string $attr_name Attribute name.
1475
+ * @param array[]|string[] $attr_spec_list Attribute spec list.
1476
+ * @return bool Return true if attribute name is valid for this attr_spec_list, false otherwise.
1477
+ */
1478
+ private function is_amp_allowed_attribute( $attr_name, $attr_spec_list ) {
1479
+ if ( isset( $this->globally_allowed_attributes[ $attr_name ] ) || isset( $this->layout_allowed_attributes[ $attr_name ] ) || isset( $attr_spec_list[ $attr_name ] ) ) {
1480
+ return true;
1481
+ } else {
1482
+ foreach ( AMP_Rule_Spec::$whitelisted_attr_regex as $whitelisted_attr_regex ) {
1483
+ if ( preg_match( $whitelisted_attr_regex, $attr_name ) ) {
1484
+ return true;
1485
+ }
1486
+ }
1487
+ }
1488
+
1489
+ $is_allowed_alt_name_attr = (
1490
+ isset( $this->rev_alternate_attr_name_lookup[ $attr_name ] )
1491
+ &&
1492
+ isset( $attr_spec_list[ $this->rev_alternate_attr_name_lookup[ $attr_name ] ] )
1493
+ );
1494
+ if ( $is_allowed_alt_name_attr ) {
1495
+ return true;
1496
+ }
1497
+
1498
+ return false;
1499
+ }
1500
+
1501
+ /**
1502
+ * Determine if the supplied $node's HTML tag is allowed for AMP.
1503
+ *
1504
+ * @since 0.5
1505
+ *
1506
+ * @param DOMNode $node Node.
1507
+ * @return bool Return true if the specified node's name is an AMP allowed tag, false otherwise.
1508
+ */
1509
+ private function is_amp_allowed_tag( $node ) {
1510
+ if ( ! $node instanceof DOMElement ) {
1511
+ return false;
1512
+ }
1513
+ /**
1514
+ * Return true if node is an allowed tags or is a text or comment node.
1515
+ */
1516
+ return (
1517
+ ( XML_TEXT_NODE === $node->nodeType ) ||
1518
+ isset( $this->allowed_tags[ $node->nodeName ] ) ||
1519
+ ( XML_COMMENT_NODE === $node->nodeType ) ||
1520
+ ( XML_CDATA_SECTION_NODE === $node->nodeType )
1521
+ );
1522
+ }
1523
+
1524
+ /**
1525
+ * Determine if the supplied $node has a parent with the specified tag name.
1526
+ *
1527
+ * @since 0.5
1528
+ *
1529
+ * @param DOMNode $node Node.
1530
+ * @param string $parent_tag_name Parent tag name.
1531
+ * @return bool Return true if given node has direct parent with the given name, false otherwise.
1532
+ */
1533
+ private function has_parent( $node, $parent_tag_name ) {
1534
+ if ( $node && $node->parentNode && ( $node->parentNode->nodeName === $parent_tag_name ) ) {
1535
+ return true;
1536
+ }
1537
+ return false;
1538
+ }
1539
+
1540
+ /**
1541
+ * Determine if the supplied $node has an ancestor with the specified tag name.
1542
+ *
1543
+ * @since 0.5
1544
+ *
1545
+ * @todo The $ancestor_tag_name here is not sufficient as it is not just a tag name but an entire selector that is used.
1546
+ * @param DOMNode $node Node.
1547
+ * @param string $ancestor_tag_name Ancestor tag name.
1548
+ * @return bool Return true if given node has any ancestor with the give name, false otherwise.
1549
+ */
1550
+ private function has_ancestor( $node, $ancestor_tag_name ) {
1551
+ if ( $this->get_ancestor_with_tag_name( $node, $ancestor_tag_name ) ) {
1552
+ return true;
1553
+ }
1554
+ return false;
1555
+ }
1556
+
1557
+ /**
1558
+ * Get the first ancestor node matching the specified tag name for the supplied $node.
1559
+ *
1560
+ * @since 0.5
1561
+ *
1562
+ * @param DOMNode $node Node.
1563
+ * @param string $ancestor_tag_name Ancestor tag name.
1564
+ * @return DOMNode|null Returns an ancestor node for the name specified, or null if not found.
1565
+ */
1566
+ private function get_ancestor_with_tag_name( $node, $ancestor_tag_name ) {
1567
+ while ( $node && $node->parentNode ) {
1568
+ $node = $node->parentNode;
1569
+ if ( $node->nodeName === $ancestor_tag_name ) {
1570
+ return $node;
1571
+ }
1572
+ }
1573
+ return null;
1574
+ }
1575
+
1576
+ /**
1577
+ * Replaces the given node with it's child nodes, if any
1578
+ *
1579
+ * Also adds them to the stack for processing by the sanitize() function.
1580
+ *
1581
+ * @since 0.3.3
1582
+ *
1583
+ * @param DOMNode $node Node.
1584
+ */
1585
+ private function replace_node_with_children( $node ) {
1586
+
1587
+ if ( ! $node->hasChildNodes() || ! $node->parentNode ) {
1588
+ // If node has no children or no parent, just remove the node.
1589
+ $this->remove_node( $node );
1590
+
1591
+ } else {
1592
+ /*
1593
+ * If node has children, replace it with them and push children onto stack
1594
+ *
1595
+ * Create a DOM fragment to hold the children
1596
+ */
1597
+ $fragment = $this->dom->createDocumentFragment();
1598
+
1599
+ // Add all children to fragment/stack.
1600
+ $child = $node->firstChild;
1601
+ while ( $child ) {
1602
+ $fragment->appendChild( $child );
1603
+ $this->stack[] = $child;
1604
+ $child = $node->firstChild;
1605
+ }
1606
+
1607
+ // Replace node with fragment.
1608
+ $node->parentNode->replaceChild( $fragment, $node );
1609
+
1610
+ }
1611
+ }
1612
+
1613
+ /**
1614
+ * Removes a node from its parent node.
1615
+ *
1616
+ * If removing the node makes the parent node empty, then it will remove the parent
1617
+ * too. It will Continue until a non-empty parent or the 'body' element is reached.
1618
+ *
1619
+ * @since 0.5
1620
+ *
1621
+ * @param DOMNode $node Node.
1622
+ */
1623
+ private function remove_node( $node ) {
1624
+ /**
1625
+ * Parent.
1626
+ *
1627
+ * @var DOMNode $parent
1628
+ */
1629
+ /*
1630
+ $parent = $node->parentNode;
1631
+ if ( $node && $parent ) {
1632
+ $this->remove_invalid_child( $node );
1633
+ }
1634
+ while ( $parent && ! $parent->hasChildNodes() && $this->root_element !== $parent ) {
1635
+ $node = $parent;
1636
+ $parent = $parent->parentNode;
1637
+ if ( $parent ) {
1638
+ $parent->removeChild( $node );
1639
+ }
1640
+ }
1641
+ */
1642
+ }
1643
+ }
pagebuilder/modules/adsense-ad-module.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $output = '<amp-ad class="amp-ad-1"
4
+ type="adsense"
5
+ {{if_condition_ad_size_option==300x250}}width="300"{{ifend_condition_ad_size_option_300x250}}
6
+ {{if_condition_ad_size_option==336x280}}width="336"{{ifend_condition_ad_size_option_336x280}}
7
+ {{if_condition_ad_size_option==728x90}}width="728"{{ifend_condition_ad_size_option_728x90}}
8
+ {{if_condition_ad_size_option==300x600}}width="300"{{ifend_condition_ad_size_option_300x600}}
9
+ {{if_condition_ad_size_option==320x100}}width="320"{{ifend_condition_ad_size_option_320x100}}
10
+ {{if_condition_ad_size_option==200x50}}width="200"{{ifend_condition_ad_size_option_200x50}}
11
+ {{if_condition_ad_size_option==320x50}}width="320"{{ifend_condition_ad_size_option_320x50}}
12
+ {{if_condition_ad_size_option==responsive}}width="100vw"{{ifend_condition_ad_size_option_responsive}}
13
+
14
+ {{if_condition_ad_size_option==300x250}}height="250"{{ifend_condition_ad_size_option_300x250}}
15
+ {{if_condition_ad_size_option==336x280}}height="280"{{ifend_condition_ad_size_option_336x280}}
16
+ {{if_condition_ad_size_option==728x90}}height="90"{{ifend_condition_ad_size_option_728x90}}
17
+ {{if_condition_ad_size_option==300x600}}height="600"{{ifend_condition_ad_size_option_300x600}}
18
+ {{if_condition_ad_size_option==320x100}}height="100"{{ifend_condition_ad_size_option_320x100}}
19
+ {{if_condition_ad_size_option==200x50}}height="50"{{ifend_condition_ad_size_option_200x50}}
20
+ {{if_condition_ad_size_option==320x50}}height="50"{{ifend_condition_ad_size_option_320x50}}
21
+ {{if_condition_ad_size_option==responsive}}height="320"{{ifend_condition_ad_size_option_responsive}}
22
+
23
+ data-ad-client="{{data_ad_client}}"
24
+ data-ad-slot="{{data_ad_slot}}"
25
+ {{if_condition_ad_size_option==responsive}}data-auto-format="rspv"
26
+ data-full-width>
27
+ <div overflow></div{{ifend_condition_ad_size_option_responsive}}></amp-ad>';
28
+ $css ='';
29
+ return array(
30
+ 'label' =>'Advertisement',
31
+ 'name' =>'adsense-ad',
32
+ 'default_tab'=> 'customizer',
33
+ 'fields' => array(
34
+ array(
35
+ 'type' =>'select',
36
+ 'name' =>'ad_size_option',
37
+ 'label' =>"Ad Size",
38
+ 'tab' =>'customizer',
39
+ 'default' =>'336x280',
40
+ 'options_details'=>array(
41
+ '300x250' =>'300x250',
42
+ '336x280' =>'336x280',
43
+ '728x90' =>'728x90',
44
+ '300x600' =>'300x600',
45
+ '320x100' =>'320x100',
46
+ '200x50' =>'200x50',
47
+ '320x50' =>'320x50',
48
+ 'responsive' =>'Responsive'
49
+ ),
50
+ 'content_type'=>'html',
51
+ ),
52
+ array(
53
+ 'type' => 'text',
54
+ 'name' => "data_ad_client",
55
+ 'label' => 'Data AD Client',
56
+ 'tab' => 'customizer',
57
+ 'default' => '',
58
+ 'helpmessage' => 'e.g. ca-pub-0497xxxxxxxxxx12',
59
+ 'content_type' => 'html',
60
+ ),
61
+ array(
62
+ 'type' => 'text',
63
+ 'name' => "data_ad_slot",
64
+ 'label' => 'Data AD Slot',
65
+ 'tab' => 'customizer',
66
+ 'default' => '',
67
+ 'helpmessage' => 'e.g. 896xxxxx12',
68
+ 'content_type' => 'html',
69
+ ),
70
+ ),
71
+ 'front_template'=> $output,
72
+ 'front_css'=> $css,
73
+ 'front_common_css'=>'',
74
+ );
75
+
76
+
77
+ ?>
pagebuilder/modules/code-module.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ add_filter("ampforwp_extension_pagebuilder_module_template", 'ampforwp_code_module_replacement',10,3);
4
+ function ampforwp_code_module_replacement($moduleFrontHtml,$moduleTemplate, $contentArray){
5
+ if($moduleTemplate['name']==='code'){
6
+ if(isset($moduleTemplate['fields']) && count($moduleTemplate['fields']) > 0) {
7
+ foreach ($moduleTemplate['fields'] as $key => $field) {
8
+ if(!empty($contentArray) && !isset($contentArray[$field['name']])){
9
+ $replace = getdefaultValue($field['name'], $moduleTemplate['fields']);
10
+ }else{
11
+ $replace = $contentArray[$field['name']];
12
+ }
13
+
14
+ $moduleFrontHtml = str_replace('{{'.$field['name'].'}}', $replace, $moduleFrontHtml);
15
+ $moduleFrontHtml = ampforwp_replaceIfContentConditional($field['name'], $replace, $moduleFrontHtml);
16
+ }
17
+ $moduleFrontHtml = htmlspecialchars_decode($moduleFrontHtml);
18
+ }
19
+
20
+ }
21
+ return $moduleFrontHtml;
22
+ }
23
+ function ampforwp_runCompleteCode($moduleFrontHtml){
24
+ if(!empty($moduleFrontHtml)){
25
+ return eval( "?>". $moduleFrontHtml . "<?php " );
26
+ }
27
+ }
28
+
29
+ $output = '{{code_content}}';
30
+ $css = '
31
+ ';
32
+ return array(
33
+ 'label' =>'Code',
34
+ 'name' =>'code',
35
+ 'default_tab'=> 'customizer',
36
+ 'tabs' => array(
37
+ 'customizer'=>'Content',
38
+ 'design'=>'Design',
39
+ 'advanced' => 'Advanced'
40
+ ),
41
+ 'fields' => array(
42
+ array(
43
+ 'type' => 'textarea',
44
+ 'name' => "code_content",
45
+ 'label' => 'Enter your code here',
46
+ 'tab' => 'customizer',
47
+ 'default' => '',
48
+ 'helpmessage' => 'please Insert only HTML Codes',
49
+ 'content_type' => 'html',
50
+ ),
51
+ ),
52
+ 'front_template'=> $output,
53
+ 'front_css'=> $css,
54
+ 'front_common_css'=>'',
55
+ );
56
+
57
+
58
+ ?>
pagebuilder/modules/contact-form-shortcode-module.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $output = '
3
+ {{if_condition_form_type==contact-form-7}}
4
+ [contact-form-7 id="{{cf7_form_id}}"]
5
+ {{ifend_condition_form_type_contact-form-7}}
6
+
7
+ {{if_condition_form_type==gravityform}}
8
+ [gravityform id="{{gf_form_id}}" title="true" description="true"]
9
+ {{ifend_condition_form_type_gravityform}}
10
+
11
+ {{if_condition_form_type==wpforms}}
12
+ [wpforms id="{{wp_form_id}}"]
13
+ {{ifend_condition_form_type_wpforms}}
14
+
15
+ {{if_condition_form_type==ninja_form}}
16
+ [ninja_form id="{{nj_forms_id}}"]
17
+ {{ifend_condition_form_type_ninja_form}}
18
+ ';
19
+
20
+ $css = '';
21
+ $formSupported = array();
22
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
23
+ if(is_plugin_active('amp-cf7/amp-cf7.php')){
24
+ $formSupported = array_merge($formSupported, array('contact-form-7'=>'Contact Form 7'));
25
+
26
+ $args = array('post_type' => 'wpcf7_contact_form', 'posts_per_page' => -1);
27
+ $cf7Forms = get_posts( $args );
28
+ $form_titles = wp_list_pluck( $cf7Forms , 'post_title' );
29
+ $form_id = wp_list_pluck( $cf7Forms , 'ID' );
30
+ $cf7formArray = array();
31
+ if(count($form_titles)>0){
32
+ foreach ($form_titles as $key => $formName) {
33
+ $cf7formArray[$form_id[$key]] = $formName;
34
+ }
35
+ }
36
+ $cf7FormsList = array(array(
37
+ 'type' =>'select',
38
+ 'name' =>'cf7_form_id',
39
+ 'label' =>"Select Form",
40
+ 'tab' =>'customizer',
41
+ 'default' =>'',
42
+ 'options_details'=>$cf7formArray,
43
+ 'content_type'=>'html',
44
+ 'required' => array('form_type' => 'contact-form-7'),
45
+ ));
46
+
47
+ }
48
+ if(is_plugin_active('amp-gravity-forms/amp-gravity-forms.php')){
49
+ $formSupported = array_merge($formSupported, array('gravityform'=>'Gravity Form'));
50
+
51
+ $apbGFforms = RGFormsModel::get_forms();
52
+ $grvtyformArray = array();
53
+ if(count($apbGFforms)){
54
+ foreach( $apbGFforms as $form ):
55
+ $grvtyformArray[$form->id] = $form->title;
56
+ endforeach;
57
+ }
58
+ $gravityFormsList = array(array(
59
+ 'type' =>'select',
60
+ 'name' =>'gf_form_id',
61
+ 'label' =>"Select Form",
62
+ 'tab' =>'customizer',
63
+ 'default' =>'',
64
+ 'options_details'=>$grvtyformArray,
65
+ 'content_type'=>'html',
66
+ 'required' => array('form_type' => 'gravityform'),
67
+ ));
68
+ }
69
+ if(is_plugin_active('amp-wp-forms/amp-wpforms.php')){
70
+ $formSupported = array_merge($formSupported, array('wpforms'=>'WP Forms'));
71
+
72
+ //$args = apply_filters( 'wpforms_modal_select', array() );
73
+ // No ID provided, get multiple forms
74
+ $defaults = array(
75
+ 'post_type' => 'wpforms',
76
+ 'orderby' => 'id',
77
+ 'order' => 'ASC',
78
+ 'no_found_rows' => true,
79
+ 'nopaging' => true,
80
+ );
81
+ $args = wp_parse_args( $args, $defaults );
82
+ $args['post_type'] = 'wpforms';
83
+ $forms = get_posts( $args );
84
+ $wpformsArray = array();
85
+ if(count($forms)){
86
+ foreach( $forms as $form ):
87
+ $wpformsArray[$form->id] = $form->post_title;
88
+ endforeach;
89
+ }
90
+ $wpformsList = array(array(
91
+ 'type' =>'select',
92
+ 'name' =>'wp_forms_id',
93
+ 'label' =>"Select Form",
94
+ 'tab' =>'customizer',
95
+ 'default' =>'',
96
+ 'options_details'=>$wpformsArray,
97
+ 'content_type'=>'html',
98
+ 'required' => array('form_type' => 'wpforms'),
99
+ ));
100
+ }
101
+ if(is_plugin_active('amp-ninja-forms/amp-ninja-forms.php')){
102
+ $formSupported = array_merge($formSupported, array('ninja_form'=>'Ninja Forms'));
103
+
104
+ $ninjaforms_modified = array();
105
+
106
+ if ( get_option( 'ninja_forms_load_deprecated', false ) ) {
107
+ $forms = Ninja_Forms()->forms()->get_all();
108
+
109
+ foreach ( $forms as $form_id ) {
110
+ $ninjaforms_modified[ $form_id ] = Ninja_Forms()->form( $form_id )->get_setting( 'form_title' );;
111
+ }
112
+ } else {
113
+ $forms = Ninja_Forms()->form()->get_forms();
114
+ foreach ( $forms as $index => $form ) {
115
+ $ninjaforms_modified[ $form->get_id() ] = $form->get_setting( 'title' );
116
+ }
117
+ }
118
+ $ninjaFormList = array(array(
119
+ 'type' =>'select',
120
+ 'name' =>'nj_forms_id',
121
+ 'label' =>"Select Form",
122
+ 'tab' =>'customizer',
123
+ 'default' =>'',
124
+ 'options_details'=>$ninjaforms_modified,
125
+ 'content_type'=>'html',
126
+ 'required' => array('form_type' => 'ninja_form'),
127
+ ));
128
+ }
129
+
130
+ $formFields = array(
131
+ array(
132
+ 'type' =>'select',
133
+ 'name' =>'form_type',
134
+ 'label' =>"Select Form",
135
+ 'tab' =>'customizer',
136
+ 'default' =>'',
137
+ 'options_details'=>$formSupported,
138
+ 'content_type'=>'html',
139
+ 'helpmessage' => 'This module requires <a href="https://ampforwp.com/contact-form-7" target="_blank">AMP Contact Form 7</a> or <a href="https://ampforwp.com/gravity-forms/" target="_blank">AMP Gravity Forms</a> Extension. <a target="_blank" href="https://ampforwp.com/extensions/">View all the Extensions</a>'
140
+ ),
141
+ );
142
+ if(isset($cf7FormsList)){
143
+ $formFields = array_merge($formFields, $cf7FormsList);
144
+ }
145
+ if(isset($gravityFormsList)){
146
+ $formFields = array_merge($formFields, $gravityFormsList);
147
+ }
148
+ if(isset($wpformsList)){
149
+ $formFields = array_merge($formFields, $wpformsList);
150
+ }
151
+ if(isset($ninjaFormList)){
152
+ $formFields = array_merge($formFields, $ninjaFormList);
153
+ }
154
+ return array(
155
+ 'label' =>'Contact Forms',
156
+ 'name' =>'contact-form-shortcode',
157
+ 'default_tab'=> 'customizer',
158
+ 'tabs' => array(
159
+ 'customizer'=>'Content',
160
+ 'design'=>'Design',
161
+ 'advanced' => 'Advanced',
162
+ 'layout' => 'Layout'
163
+ ),
164
+ 'fields' => $formFields,
165
+ 'front_template'=> $output,
166
+ 'front_common_css'=>'',
167
+ );
168
+
169
+ ?>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: AMP, accelerated mobile pages, mobile, amp project, google amp, amp wp, go
4
  Donate link: https://www.paypal.me/Kaludi/25
5
  Requires at least: 3.0
6
  Tested up to: 4.9.5
7
- Stable tag: 0.9.97.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -183,6 +183,11 @@ You can contact us from [here](https://ampforwp.com/contact/)
183
 
184
  == Changelog ==
185
 
 
 
 
 
 
186
  = 0.9.96.1 (21st June 2018) =
187
  * Fixed: Pagination on Homepage and Archive pages not working for some cases.
188
 
4
  Donate link: https://www.paypal.me/Kaludi/25
5
  Requires at least: 3.0
6
  Tested up to: 4.9.5
7
+ Stable tag: 0.9.97.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
183
 
184
  == Changelog ==
185
 
186
+ = 0.9.97.2 (29th June 2018) =
187
+ * Fixed: GDPR not wroking properly for NON EU countries.
188
+ * Fixed: no-index in robot meta reporting an error in Search Console.
189
+ * Fixed: 2nd page or more blank in Post Pagination.
190
+
191
  = 0.9.96.1 (21st June 2018) =
192
  * Fixed: Pagination on Homepage and Archive pages not working for some cases.
193
 
templates/design-manager/design-1/elements/content.php CHANGED
@@ -36,19 +36,6 @@
36
  );
37
  $ampforwp_the_content = $sanitizer_obj->get_amp_content();
38
  }
39
- else {
40
- if($redux_builder_amp['amp-pagination']) {
41
- $ampforwp_new_content = explode('<!--nextpage-->', $ampforwp_the_content);
42
- $queried_var = get_query_var('page');
43
- if ( $queried_var > 1 ) {
44
- $queried_var = $queried_var -1 ;
45
- }
46
- else {
47
- $queried_var = 0;
48
- }
49
- $ampforwp_the_content = $ampforwp_new_content[$queried_var];
50
- } //#1015 Pegazee
51
- }
52
 
53
  //Filter to modify the Content
54
  $ampforwp_the_content = apply_filters('ampforwp_modify_the_content', $ampforwp_the_content);
36
  );
37
  $ampforwp_the_content = $sanitizer_obj->get_amp_content();
38
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  //Filter to modify the Content
41
  $ampforwp_the_content = apply_filters('ampforwp_modify_the_content', $ampforwp_the_content);
templates/design-manager/design-2/elements/content.php CHANGED
@@ -36,19 +36,7 @@
36
  );
37
  $ampforwp_the_content = $sanitizer_obj->get_amp_content();
38
  }
39
- else {
40
- if($redux_builder_amp['amp-pagination']) {
41
- $ampforwp_new_content = explode('<!--nextpage-->', $ampforwp_the_content);
42
- $queried_var = get_query_var('page');
43
- if ( $queried_var > 1 ) {
44
- $queried_var = $queried_var -1 ;
45
- }
46
- else{
47
- $queried_var = 0;
48
- }
49
- $ampforwp_the_content = $ampforwp_new_content[$queried_var];
50
- } //#1015 Pegazee
51
- }
52
 
53
  //Filter to modify the Content
54
  $ampforwp_the_content = apply_filters('ampforwp_modify_the_content', $ampforwp_the_content);
36
  );
37
  $ampforwp_the_content = $sanitizer_obj->get_amp_content();
38
  }
39
+
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  //Filter to modify the Content
42
  $ampforwp_the_content = apply_filters('ampforwp_modify_the_content', $ampforwp_the_content);
templates/design-manager/design-3/elements/content.php CHANGED
@@ -37,19 +37,7 @@
37
  );
38
  $ampforwp_the_content = $sanitizer_obj->get_amp_content();
39
  }
40
- else {
41
- if($redux_builder_amp['amp-pagination']) {
42
- $ampforwp_new_content = explode('<!--nextpage-->', $ampforwp_the_content);
43
- $queried_var = get_query_var('page');
44
- if ( $queried_var > 1 ) {
45
- $queried_var = $queried_var -1 ;
46
- }
47
- else{
48
- $queried_var = 0;
49
- }
50
- $ampforwp_the_content = $ampforwp_new_content[$queried_var];
51
- }//#1015 pegazee
52
- }
53
 
54
  //Filter to modify the Content
55
  $ampforwp_the_content = apply_filters('ampforwp_modify_the_content', $ampforwp_the_content);
37
  );
38
  $ampforwp_the_content = $sanitizer_obj->get_amp_content();
39
  }
40
+
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  //Filter to modify the Content
43
  $ampforwp_the_content = apply_filters('ampforwp_modify_the_content', $ampforwp_the_content);
templates/features.php CHANGED
@@ -2898,6 +2898,9 @@ function ampforwp_talking_to_robots() {
2898
  $meta_content = '';
2899
  }
2900
  $meta_content = apply_filters('ampforwp_robots_meta', $meta_content);
 
 
 
2901
  if ( $meta_content ) {
2902
  if ( ( is_archive() && $talk_to_robots ) || is_singular() || is_home() ) {
2903
  echo '<meta name="robots" content="' . esc_attr($meta_content) . '"/>';
@@ -4094,7 +4097,21 @@ function ampforwp_post_pagination( $args = '' ) {
4094
 
4095
  wp_reset_postdata();
4096
  global $page, $numpages, $multipage, $more, $redux_builder_amp;
4097
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4098
  $defaults = array(
4099
  'before' => '<div class="ampforwp_post_pagination" ><p>' . '<span>' . ampforwp_translation($redux_builder_amp['amp-translator-page-text'], 'Page') . ':</span>',
4100
  'after' => '</p></div>',
@@ -4188,14 +4205,25 @@ function ampforwp_post_pagination( $args = '' ) {
4188
  function ampforwp_post_paginated_link_generator( $i ) {
4189
  global $wp_rewrite;
4190
  $post = get_post();
 
 
 
 
4191
  $query_args = array();
4192
  if ( 1 == $i ) {
4193
  $url = get_permalink();
 
 
 
4194
  } else {
4195
- if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
4196
  $url = add_query_arg( 'page', $i, get_permalink() );
4197
- elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') == $post->ID )
4198
- $url = trailingslashit(get_permalink()) . user_trailingslashit("$wp_rewrite->pagination_base/" . $i, 'single_paged');
 
 
 
 
4199
  else
4200
  $url = trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged');
4201
  }
@@ -4213,6 +4241,35 @@ function ampforwp_post_paginated_link_generator( $i ) {
4213
  $url = add_query_arg(AMPFORWP_AMP_QUERY_VAR,'1',$url);
4214
  return '<a href="' . esc_url( $url ) . '">';
4215
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4216
 
4217
  add_filter('ampforwp_modify_rel_canonical','ampforwp_modify_rel_amphtml_paginated_post');
4218
  function ampforwp_modify_rel_amphtml_paginated_post($url) {
@@ -4664,7 +4721,10 @@ function ampforwp_dev_mode_remove_amphtml(){
4664
  // Add noindex,nofollow in the AMP
4665
  if ( ! function_exists('ampforwp_dev_mode_add_noindex') ) {
4666
  function ampforwp_dev_mode_add_noindex() {
4667
- echo '<meta name="robots" content="noindex,nofollow"/>';
 
 
 
4668
  }
4669
  }
4670
  // Notice for Dev Mode
@@ -6570,19 +6630,15 @@ if ( ! function_exists('ampforwp_gdpr_data') ) {
6570
  function ampforwp_gdpr_data( $data ) {
6571
  global $redux_builder_amp;
6572
  if ( empty( $data['amp_component_scripts']['amp-consent'] ) ) {
6573
- $data['amp_component_scripts']['amp-consent'] = 'https://cdn.ampproject.org/v0/amp-consent-0.1.js';
6574
  }
6575
  if ( empty( $data['amp_component_scripts']['amp-form'] ) ) {
6576
- $data['amp_component_scripts']['amp-form'] = 'https://cdn.ampproject.org/v0/amp-form-0.1.js';
6577
- }
6578
- if(isset( $redux_builder_amp['audience-for-amp-gdpr-compliance'] ) && ($redux_builder_amp['audience-for-amp-gdpr-compliance'] == '2' || $redux_builder_amp['audience-for-amp-gdpr-compliance'] == '3')){
6579
- if ( empty( $data['amp_component_scripts']['amp-geo'] ) ) {
6580
- $data['amp_component_scripts']['amp-geo'] = 'https://cdn.ampproject.org/v0/amp-geo-0.1.js';
6581
- }
6582
- }
6583
- if ( empty( $data['amp_component_scripts']['amp-bind'] ) ) {
6584
- $data['amp_component_scripts']['amp-bind'] = 'https://cdn.ampproject.org/v0/amp-bind-0.1.js';
6585
  }
 
 
 
 
6586
  return $data;
6587
  }
6588
  }
@@ -6608,72 +6664,25 @@ if ( ! function_exists('ampforwp_gdpr_amp_consent') ) {
6608
  if(isset($redux_builder_amp['amp-gdpr-compliance-privacy-page-button-text']) && $redux_builder_amp['amp-gdpr-compliance-privacy-page-button-text']){
6609
  $privacy_button_text = $redux_builder_amp['amp-gdpr-compliance-privacy-page-button-text'];
6610
  }
 
 
 
6611
 
6612
- $all_eu_countries = $redux_builder_amp['amp-gdpr-compliance-privacy-geo-location'];
6613
- if(isset($redux_builder_amp['audience-for-amp-gdpr-compliance']) && $redux_builder_amp['audience-for-amp-gdpr-compliance']){
6614
- ///////////////////////////
6615
- // Start For Only EU Countries //
6616
- ///////////////////////////
6617
- if($redux_builder_amp['audience-for-amp-gdpr-compliance'] === '2'){?>
6618
- <amp-geo layout="nodisplay">
6619
- <script type="application/json">
6620
- {
6621
- "AmpBind": true,
6622
- "ISOCountryGroups": {
6623
- "eu": [ <?php echo '"'.implode('","', array_keys($all_eu_countries)).'"';?> ] ,
6624
- "noneu": [ "unknown" ]
6625
- }
6626
- }
6627
- </script>
6628
- </amp-geo>
6629
-
6630
- <?php
6631
- ///////////////////////////////
6632
- // End For Only EU Countries //
6633
- ///////////////////////////////
6634
- }
6635
-
6636
- /////////////////////////////
6637
- // Start For Custom EU Countries //
6638
- /////////////////////////////
6639
- if($redux_builder_amp['audience-for-amp-gdpr-compliance'] === '3'){
6640
- ?>
6641
- <amp-geo layout="nodisplay">
6642
- <script type="application/json">
6643
  {
6644
- "AmpBind": true,
6645
  "ISOCountryGroups": {
6646
- "eu": [ <?php $eu_countries = array_filter($redux_builder_amp['amp-gdpr-compliance-privacy-geo-location']);
6647
- if(NULL == $eu_countries || 0 == count($eu_countries)){
6648
- echo '"'.implode('","', array_keys($all_eu_countries)).'"';?> ] ,<?php
6649
- }
6650
- else{
6651
- echo '"'.implode('","', array_keys($eu_countries)).'"';
6652
- ?> ] ,<?php } ?>
6653
- "noneu": [ "unknown" ]
6654
- }
6655
  }
6656
- </script>
6657
- </amp-geo>
6658
-
6659
- <amp-state id="ampGeo">
6660
- <script type="application/json">{
6661
- "ISOCountry":[ <?php echo '"'.implode('","', array_keys($all_eu_countries)).'"';?> ] ,
6662
- "eu": true
6663
- }
6664
- </script>
6665
- </amp-state>
6666
- <?php }
6667
- /////////////////////////////
6668
- // END Custom EU Countries //
6669
- /////////////////////////////
6670
- ?>
6671
-
6672
  <amp-consent id="ampforwpConsent" layout="nodisplay">
6673
  <script type="application/json">{
6674
  "consents": {
6675
  "consent1": {
6676
- "checkConsentHref": "<?php echo admin_url('admin-ajax.php?action=ampforwp_check_consent_href_process');?>",
6677
  "promptUI": "gdpr_c"
6678
  }
6679
  },
@@ -6710,18 +6719,16 @@ if ( ! function_exists('ampforwp_gdpr_amp_consent') ) {
6710
  </amp-consent>
6711
 
6712
  <?php }
6713
- }
6714
  }
6715
 
6716
  // AMP GDPR compliancy Styling
6717
  if ( ! function_exists('ampforwp_gdpr_css') ) {
6718
  function ampforwp_gdpr_css(){
6719
  global $redux_builder_amp;
6720
- if($redux_builder_amp['audience-for-amp-gdpr-compliance'] == '2' || $redux_builder_amp['audience-for-amp-gdpr-compliance'] == '3'){ ?>
6721
- #ampforwpConsent{visibility: hidden}
6722
- .amp-geo-group-eu #ampforwpConsent{visibility: visible} <?php }
6723
  // GDPR popup Design
6724
  if($redux_builder_amp['gdpr-type'] == '1'){?>
 
6725
  .gdpr{position: fixed; top: 0; bottom: 0; left: 0; right: 0; background: rgba(0, 0, 0, 0.7);color: #333;z-index:9999999;line-height:1.3}
6726
  .gdpr_w{padding: 2rem;background: #fff;max-width: 700px;width: 95%;position: relative;margin: 5% auto;text-align: center;}
6727
  .gdpr_t{margin-bottom:15px;}
@@ -6860,13 +6867,6 @@ if ( ! function_exists('ampforwp_gdpr_css') ) {
6860
  }
6861
  }
6862
 
6863
- // Consent Submission
6864
- add_action('wp_ajax_ampforwp_check_consent_href_process','ampforwp_check_consent_href_process');
6865
- add_action('wp_ajax_nopriv_ampforwp_check_consent_href_process','ampforwp_check_consent_href_process');
6866
- function ampforwp_check_consent_href_process(){
6867
- echo '{"promptIfUnknown": true}';
6868
- wp_die();
6869
- }
6870
  // Consent Submission
6871
  add_action('wp_ajax_amp_consent_submission','amp_consent_submission');
6872
  add_action('wp_ajax_nopriv_amp_consent_submission','amp_consent_submission');
2898
  $meta_content = '';
2899
  }
2900
  $meta_content = apply_filters('ampforwp_robots_meta', $meta_content);
2901
+ if ( isset($redux_builder_amp['amp-inspection-tool']) && true == $redux_builder_amp['amp-inspection-tool'] ) {
2902
+ $talk_to_robots = $meta_content = '';
2903
+ }
2904
  if ( $meta_content ) {
2905
  if ( ( is_archive() && $talk_to_robots ) || is_singular() || is_home() ) {
2906
  echo '<meta name="robots" content="' . esc_attr($meta_content) . '"/>';
4097
 
4098
  wp_reset_postdata();
4099
  global $page, $numpages, $multipage, $more, $redux_builder_amp;
4100
+ if ( ampforwp_is_front_page() ) {
4101
+ $id = ampforwp_get_frontpage_id();
4102
+ $content_post = get_post($id);
4103
+ $content = $content_post->post_content;
4104
+ $checker = preg_match('/<!--nextpage-->/', $content);
4105
+ if ( 1 === $checker ) {
4106
+ $multipage = $more = 1;
4107
+ $ampforwp_new_content = explode('<!--nextpage-->', $content);
4108
+ $queried_var = get_query_var('paged');
4109
+ if ( $queried_var > 1 ) {
4110
+ $page = $queried_var;
4111
+ }
4112
+ $numpages = count($ampforwp_new_content);
4113
+ }
4114
+ }
4115
  $defaults = array(
4116
  'before' => '<div class="ampforwp_post_pagination" ><p>' . '<span>' . ampforwp_translation($redux_builder_amp['amp-translator-page-text'], 'Page') . ':</span>',
4117
  'after' => '</p></div>',
4205
  function ampforwp_post_paginated_link_generator( $i ) {
4206
  global $wp_rewrite;
4207
  $post = get_post();
4208
+ if ( ampforwp_is_front_page() ) {
4209
+ $id = ampforwp_get_frontpage_id();
4210
+ $post = get_post($id);
4211
+ }
4212
  $query_args = array();
4213
  if ( 1 == $i ) {
4214
  $url = get_permalink();
4215
+ if(ampforwp_is_front_page()){
4216
+ $url = get_home_url();
4217
+ }
4218
  } else {
4219
+ if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) ) {
4220
  $url = add_query_arg( 'page', $i, get_permalink() );
4221
+ if(ampforwp_is_front_page()){
4222
+ $url = add_query_arg( 'page', $i, get_home_url() );
4223
+ }
4224
+ }
4225
+ elseif ( ampforwp_is_front_page() )
4226
+ $url = trailingslashit(get_home_url()) . user_trailingslashit("$wp_rewrite->pagination_base/" . $i, 'single_paged');
4227
  else
4228
  $url = trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged');
4229
  }
4241
  $url = add_query_arg(AMPFORWP_AMP_QUERY_VAR,'1',$url);
4242
  return '<a href="' . esc_url( $url ) . '">';
4243
  }
4244
+ // Modify the content to make Pagination work on Pages and FrontPage #2253
4245
+ add_filter('ampforwp_modify_the_content','ampforwp_post_paginated_content');
4246
+ function ampforwp_post_paginated_content($content){
4247
+ if ( is_page() || ampforwp_is_front_page() ){
4248
+ global $redux_builder_amp, $page, $multipage;
4249
+ $ampforwp_new_content = $ampforwp_the_content = $checker = '';
4250
+ $ampforwp_the_content = $content;
4251
+ $checker = preg_match('/<!--nextpage-->/', $ampforwp_the_content);
4252
+ if ( 1 === $checker ) {
4253
+ $multipage = 1;
4254
+ $ampforwp_new_content = explode('<!--nextpage-->', $ampforwp_the_content);
4255
+ $queried_var = get_query_var('page');
4256
+ if ( ampforwp_is_front_page() ) {
4257
+ $queried_var = get_query_var('paged');
4258
+ }
4259
+ if ( $queried_var > 1 ) {
4260
+ $queried_var = $queried_var -1 ;
4261
+ }
4262
+ else {
4263
+ $queried_var = 0;
4264
+ }
4265
+ return $ampforwp_new_content[$queried_var];
4266
+ }
4267
+ else {
4268
+ return $ampforwp_the_content;
4269
+ }
4270
+ }
4271
+ return $content;
4272
+ }
4273
 
4274
  add_filter('ampforwp_modify_rel_canonical','ampforwp_modify_rel_amphtml_paginated_post');
4275
  function ampforwp_modify_rel_amphtml_paginated_post($url) {
4721
  // Add noindex,nofollow in the AMP
4722
  if ( ! function_exists('ampforwp_dev_mode_add_noindex') ) {
4723
  function ampforwp_dev_mode_add_noindex() {
4724
+ global $redux_builder_amp;
4725
+ if ( isset($redux_builder_amp['amp-inspection-tool']) && false == $redux_builder_amp['amp-inspection-tool'] ) {
4726
+ echo '<meta name="robots" content="noindex,nofollow"/>';
4727
+ }
4728
  }
4729
  }
4730
  // Notice for Dev Mode
6630
  function ampforwp_gdpr_data( $data ) {
6631
  global $redux_builder_amp;
6632
  if ( empty( $data['amp_component_scripts']['amp-consent'] ) ) {
6633
+ $data['amp_component_scripts']['amp-consent'] = 'https://cdn.ampproject.org/v0/amp-consent-0.1.js';
6634
  }
6635
  if ( empty( $data['amp_component_scripts']['amp-form'] ) ) {
6636
+ $data['amp_component_scripts']['amp-form'] = 'https://cdn.ampproject.org/v0/amp-form-0.1.js';
 
 
 
 
 
 
 
 
6637
  }
6638
+ if ( empty( $data['amp_component_scripts']['amp-geo'] ) ) {
6639
+ $data['amp_component_scripts']['amp-geo'] = 'https://cdn.ampproject.org/v0/amp-geo-0.1.js';
6640
+ }
6641
+
6642
  return $data;
6643
  }
6644
  }
6664
  if(isset($redux_builder_amp['amp-gdpr-compliance-privacy-page-button-text']) && $redux_builder_amp['amp-gdpr-compliance-privacy-page-button-text']){
6665
  $privacy_button_text = $redux_builder_amp['amp-gdpr-compliance-privacy-page-button-text'];
6666
  }
6667
+ $gdpr_countries = array("AT","BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU", "IS", "IE", "IT", "LV", "LI", "LT", "LU", "MT", "NL", "NO", "PL", "PT", "RO", "SK", "SI", "ES", "SE", "GB", "AX", "IC", "EA", "GF", "PF", "TF", "GI", "GP", "GG", "JE", "MQ", "YT", "NC", "RE", "BL", "MF", "PM", "SJ", "VA", "WF", "EZ", "CH");
6668
+ $gdpr_countries = apply_filters( 'ampforwp_gdpr_country_list' , $gdpr_countries );
6669
+ ?>
6670
 
6671
+ <amp-geo layout="nodisplay">
6672
+ <script type="application/json">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6673
  {
 
6674
  "ISOCountryGroups": {
6675
+ "eea":[ <?php echo '"'.implode('","', array_values($gdpr_countries)).'"';?> ]
6676
+ }
 
 
 
 
 
 
 
6677
  }
6678
+ </script>
6679
+ </amp-geo>
6680
+
 
 
 
 
 
 
 
 
 
 
 
 
 
6681
  <amp-consent id="ampforwpConsent" layout="nodisplay">
6682
  <script type="application/json">{
6683
  "consents": {
6684
  "consent1": {
6685
+ "promptIfUnknownForGeoGroup": "eea",
6686
  "promptUI": "gdpr_c"
6687
  }
6688
  },
6719
  </amp-consent>
6720
 
6721
  <?php }
6722
+
6723
  }
6724
 
6725
  // AMP GDPR compliancy Styling
6726
  if ( ! function_exists('ampforwp_gdpr_css') ) {
6727
  function ampforwp_gdpr_css(){
6728
  global $redux_builder_amp;
 
 
 
6729
  // GDPR popup Design
6730
  if($redux_builder_amp['gdpr-type'] == '1'){?>
6731
+
6732
  .gdpr{position: fixed; top: 0; bottom: 0; left: 0; right: 0; background: rgba(0, 0, 0, 0.7);color: #333;z-index:9999999;line-height:1.3}
6733
  .gdpr_w{padding: 2rem;background: #fff;max-width: 700px;width: 95%;position: relative;margin: 5% auto;text-align: center;}
6734
  .gdpr_t{margin-bottom:15px;}
6867
  }
6868
  }
6869
 
 
 
 
 
 
 
 
6870
  // Consent Submission
6871
  add_action('wp_ajax_amp_consent_submission','amp_consent_submission');
6872
  add_action('wp_ajax_nopriv_amp_consent_submission','amp_consent_submission');