Easy Table of Contents - Version 1.7.1

Version Description

02/18/2020 = * BUG: Sanitize the excluded heading string before saving post meta.

Download this release

Release Info

Developer shazahm1@hotmail.com
Plugin Icon 128x128 Easy Table of Contents
Version 1.7.1
Comparing to
See all releases

Code changes from version 2.0-rc10 to 1.7.1

README.txt CHANGED
@@ -2,10 +2,10 @@
2
  Contributors: shazahm1@hotmail.com
3
  Donate link: http://connections-pro.com/
4
  Tags: table of contents, toc
5
- Requires at least: 5.2
6
  Tested up to: 5.3
7
- Requires PHP: 5.6.20
8
- Stable tag: 1.7
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -17,9 +17,6 @@ A user friendly, featured focused plugin which allows you to insert a table of c
17
 
18
  = Features =
19
  * Automatically generate a table of contents for your posts, pages and custom post types by parsing its contents for headers.
20
- * Supports the `<!--nextpage-->` tag.
21
- * Supports the Rank Math plugin.
22
- * Supports the Classic Editor, Gutenberg, Elementor, WPBakery Page Builder and Visual Composer page editors.
23
  * Optionally enable for pages and/or posts. Custom post types are supported, as long as their content is output with the `the_content()` template tag.
24
  * Optionally auto insert the table of contents into the page, selectable by enabled post type.
25
  * Provides many easy to understand options to configure when and where to insert the table of contents.
@@ -46,9 +43,13 @@ Here are links to documentation pages for several of the premium templates for t
46
 
47
  = Roadmap =
48
  * Fragment caching for improved performance.
49
- * Improve SEO by adding options to add nofollow to TOC link and wrap TOC nav in noindex tag.
50
- * Improve accessibility.
51
- * Add Bullet and Arrow options for list counter style.
 
 
 
 
52
 
53
  = Credit =
54
 
@@ -89,44 +90,8 @@ Easy Table Contents is a fork of the excellent [Table of Contents Plus](https://
89
 
90
  == Changelog ==
91
 
92
- = 2.0 02/01/2020 =
93
- * NEW: Major rewrite of all code and processing logic to make it faster and more reliable.
94
- * NEW: Support for the <!--nextpage--> tag.
95
- * NEW: Introduce helper functions for devs.
96
- * NEW: Support WPML.
97
- * NEW: Support Polylang.
98
- * NEW: Add filter to support the Rank Math plugin.
99
- * NEW: Introduce the `ez_toc_maybe_apply_the_content_filter` filter.
100
- * TWEAK: Improve translation compatibility.
101
- * TWEAK: Rework widget logic to allow multi-line TOC items, improve active item highlighting while removing the use of the jQuery Waypoints library.
102
- * TWEAK Add additional classes to TOC list items.
103
- * TWEAK: Add WOFF2 format for icon format and change font references in CSS.
104
- * TWEAK: Add font-display: swap for toggle icon.
105
- * TWEAK: Update JS Cookie to 2.2.1.
106
- * TWEAK: Update jQuery Smooth Scroll to 2.2.0.
107
- * TWEAK: Allow forward slash and angle brackets in headings and alternate headings.
108
- * TWEAK: Allow forward slash in excluded headings.
109
- * TWEAK: Remove new line/returns when matching excluded headings.
110
- * TWEAK: Simple transient cache to ensure a post is only processed once per request for a TOC.
111
- * TWEAK: Improve sanitization of alternate headings field value.
112
- * TWEAK: Deal with non-breaking-spaces in alternate headings.
113
- * TWEAK: Add the ability to exclude by selector content eligible to be included in the TOC.
114
- * TWEAK: Change the shortcode priority to a higher value.
115
- * TWEAK: Add filter to remove shortcodes from the content prior to the `the_content` filter being run to exclude shortcode content from being eligible as TOC items.
116
- * TWEAK: Add compatibility filters to remove shortcodes for Connections and Striking theme to remove them from eligible TOC item content.
117
- * TWEAK: Do not execute if root current filter is the `wp_head` or `get_the_excerpt` filters.
118
- * TWEAK: Add filter to exclude content by selector.
119
- * TWEAK: Move in-page anchor to after the heading instead of wrapping the heading to prevent conflicts with theme styling.
120
- * TWEAK: Utilize the `ez_toc_exclude_by_selector` filter the exclude the JetPack share buttons from eligible headings.
121
- * TWEAK: Remove the Elegant Themes Bloom plugin node from the post content before extracting headings.
122
- * TWEAK: Add compatibility filter for the Visual Composer plugin.
123
- * I18N: Add wpml-config.xml file.
124
- * BUG: Correct option misspelling.
125
- * BUG: Do not need to run values for alternate and exclude headings thru `wp_unslash()` because `update_post_meta()` already does.
126
- * BUG: Do not need to run `stripslashes()` when escaping the alternate heading value.
127
  * BUG: Sanitize the excluded heading string before saving post meta.
128
- * DEV: Change PHP keywords to comply with PSR2.
129
- * DEV:Bump minimum PHP version to 5.6.20 which matches WP core.
130
 
131
  = 1.7 05/09/2018 =
132
  * NEW: Introduce the `ez_toc_shortcode` filter.
@@ -307,6 +272,3 @@ Requires WordPress >= 4.4 and PHP >= 5.3. PHP version >= 7.1 recommended.
307
 
308
  = 1.7 =
309
  Requires WordPress >= 4.4 and PHP >= 5.3. PHP version >= 7.1 recommended.
310
-
311
- = 2.0-rc4 =
312
- Requires WordPress >= 5.0 and PHP version >= 5.6.20 (>= 7.1 is recommended).
2
  Contributors: shazahm1@hotmail.com
3
  Donate link: http://connections-pro.com/
4
  Tags: table of contents, toc
5
+ Requires at least: 4.4
6
  Tested up to: 5.3
7
+ Requires PHP: 5.3
8
+ Stable tag: 1.7.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
17
 
18
  = Features =
19
  * Automatically generate a table of contents for your posts, pages and custom post types by parsing its contents for headers.
 
 
 
20
  * Optionally enable for pages and/or posts. Custom post types are supported, as long as their content is output with the `the_content()` template tag.
21
  * Optionally auto insert the table of contents into the page, selectable by enabled post type.
22
  * Provides many easy to understand options to configure when and where to insert the table of contents.
43
 
44
  = Roadmap =
45
  * Fragment caching for improved performance.
46
+ * Support for `<!--nextpage-->`.
47
+ * Customizer support.
48
+
49
+ = Requirements =
50
+
51
+ * **WordPress version:** >= 3.2
52
+ * **PHP version:** >= 5.2.4
53
 
54
  = Credit =
55
 
90
 
91
  == Changelog ==
92
 
93
+ = 1.7.1 02/18/2020 =
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  * BUG: Sanitize the excluded heading string before saving post meta.
 
 
95
 
96
  = 1.7 05/09/2018 =
97
  * NEW: Introduce the `ez_toc_shortcode` filter.
272
 
273
  = 1.7 =
274
  Requires WordPress >= 4.4 and PHP >= 5.3. PHP version >= 7.1 recommended.
 
 
 
assets/css/screen.css CHANGED
@@ -12,9 +12,10 @@
12
  width: auto;
13
  }
14
 
15
- div.ez-toc-widget-container {
16
- padding: 0;
17
  position: relative;
 
18
  }
19
 
20
  #ez-toc-container.ez-toc-light-blue {
@@ -33,17 +34,8 @@ div.ez-toc-widget-container {
33
  background: none transparent;
34
  }
35
 
36
- div.ez-toc-widget-container ul {
37
- display: block;
38
- }
39
-
40
- div.ez-toc-widget-container li {
41
- border: none;
42
- padding: 0;
43
- }
44
-
45
- div.ez-toc-widget-container ul.ez-toc-list {
46
- padding: 10px;
47
  }
48
 
49
  #ez-toc-container ul ul,
@@ -60,10 +52,11 @@ div.ez-toc-widget-container ul.ez-toc-list {
60
  #ez-toc-container ul,
61
  #ez-toc-container li,
62
  #ez-toc-container ul li,
63
- div.ez-toc-widget-container,
64
- div.ez-toc-widget-container li {
65
  background: none;
66
- list-style: none none;
 
67
  line-height: 1.6;
68
  margin: 0;
69
  overflow: hidden;
12
  width: auto;
13
  }
14
 
15
+ .ez-toc-widget-container {
16
+ /*padding: 0 10px;*/
17
  position: relative;
18
+ white-space: nowrap;
19
  }
20
 
21
  #ez-toc-container.ez-toc-light-blue {
34
  background: none transparent;
35
  }
36
 
37
+ .ez-toc-widget-container ul.ez-toc-list {
38
+ padding: 0 10px;
 
 
 
 
 
 
 
 
 
39
  }
40
 
41
  #ez-toc-container ul ul,
52
  #ez-toc-container ul,
53
  #ez-toc-container li,
54
  #ez-toc-container ul li,
55
+ .ez-toc-widget-container,
56
+ .ez-toc-widget-container li {
57
  background: none;
58
+ list-style-type: none;
59
+ list-style: none;
60
  line-height: 1.6;
61
  margin: 0;
62
  overflow: hidden;
assets/css/screen.min.css CHANGED
@@ -1 +1 @@
1
- #ez-toc-container{background:#F9F9F9;border:1px solid #AAA;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);display:table;margin-bottom:1em;padding:10px;position:relative;width:auto}div.ez-toc-widget-container{padding:0;position:relative;}#ez-toc-container.ez-toc-light-blue{background:#EDF6FF}#ez-toc-container.ez-toc-white{background:#FFF}#ez-toc-container.ez-toc-black{background:#000}#ez-toc-container.ez-toc-transparent{background:none}div.ez-toc-widget-container ul{display:block}div.ez-toc-widget-container li{border:none;padding:0}div.ez-toc-widget-container ul.ez-toc-list{padding:10px}#ez-toc-container ul ul,.ez-toc div.ez-toc-widget-container ul ul{margin-left:1.5em}#ez-toc-container li,#ez-toc-container ul{padding:0}#ez-toc-container li,#ez-toc-container ul,#ez-toc-container ul li,div.ez-toc-widget-container,div.ez-toc-widget-container li{background:0 0;list-style:none;line-height:1.6;margin:0;overflow:hidden;z-index:1}.btn.active,.ez-toc-btn,.ez-toc-btn-default.active,.ez-toc-btn-default:active,.ez-toc-btn:active{background-image:none}#ez-toc-container p.ez-toc-title{text-align:left;line-height:1.45;margin:0;padding:0}.ez-toc-title-container{display:table;width:100%}.ez-toc-title,.ez-toc-title-toggle{display:table-cell;text-align:left;vertical-align:middle}#ez-toc-container.ez-toc-black p.ez-toc-title{color:#FFF}#ez-toc-container div.ez-toc-title-container+ul.ez-toc-list{margin-top:1em}.ez-toc-wrap-left{float:left;margin-right:10px}.ez-toc-wrap-right{float:right;margin-left:10px}#ez-toc-container a{color:#444;text-decoration:none;text-shadow:none}#ez-toc-container a:visited{color:#9f9f9f}#ez-toc-container a:hover{text-decoration:underline}#ez-toc-container.ez-toc-black a,#ez-toc-container.ez-toc-black a:visited{color:#FFF}#ez-toc-container a.ez-toc-toggle{color:#444}#ez-toc-container.counter-flat ul,#ez-toc-container.counter-hierarchy ul,.ez-toc-widget-container.counter-flat ul,.ez-toc-widget-container.counter-hierarchy ul{counter-reset:item}#ez-toc-container.counter-numeric li,.ez-toc-widget-container.counter-numeric li{list-style-type:decimal;list-style-position:inside}#ez-toc-container.counter-decimal ul.ez-toc-list li a::before,.ez-toc-widget-container.counter-decimal ul.ez-toc-list li a::before{content:counters(item,".") ". ";counter-increment:item}#ez-toc-container.counter-roman li a::before,.ez-toc-widget-container.counter-roman ul.ez-toc-list li a::before{content:counters(item,".",upper-roman) ". ";counter-increment:item}.ez-toc-widget-container ul.ez-toc-list li::before{content:' ';position:absolute;left:0;right:0;height:30px;line-height:30px;z-index:-1}.ez-toc-widget-container ul.ez-toc-list li.active::before{background-color:#EDEDED}.ez-toc-widget-container li.active>a{font-weight:900}.ez-toc-btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;border:1px solid transparent;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.ez-toc-btn:focus{outline:#333 dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.ez-toc-btn:focus,.ez-toc-btn:hover{color:#333;text-decoration:none}.ez-toc-btn.active,.ez-toc-btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.ez-toc-btn-default{color:#333;background-color:#fff;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.ez-toc-btn-default.active,.ez-toc-btn-default:active,.ez-toc-btn-default:focus,.ez-toc-btn-default:hover{color:#333;background-color:#ebebeb;border-color:#adadad}.ez-toc-btn-sm,.ez-toc-btn-xs{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.ez-toc-glyphicon,[class*=ez-toc-icon-]{font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ez-toc-btn-xs{padding:1px 5px}.ez-toc-btn-default:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.ez-toc-btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#e0e0e0));background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-moz-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);background-repeat:repeat-x;border-color:#ccc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.ez-toc-btn-default:focus,.ez-toc-btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.ez-toc-btn-default.active,.ez-toc-btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.ez-toc-pull-right{float:right!important;margin-left:10px}.ez-toc-glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings'}.ez-toc-glyphicon:empty{width:1em}.ez-toc-toggle i.ez-toc-glyphicon{font-size:16px;margin-left:2px}[class*=ez-toc-icon-]{font-family:ez-toc-icomoon!important;speak:none;font-variant:normal;text-transform:none}.ez-toc-icon-toggle:before{content:"\e87a"}
1
+ #ez-toc-container{background:#F9F9F9;border:1px solid #AAA;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);display:table;margin-bottom:1em;padding:10px;position:relative;width:auto}.ez-toc-widget-container{position:relative;white-space:nowrap}#ez-toc-container.ez-toc-light-blue{background:#EDF6FF}#ez-toc-container.ez-toc-white{background:#FFF}#ez-toc-container.ez-toc-black{background:#000}#ez-toc-container.ez-toc-transparent{background:none}.ez-toc-widget-container ul.ez-toc-list{padding:0 10px}#ez-toc-container ul ul,.ez-toc div.ez-toc-widget-container ul ul{margin-left:1.5em}#ez-toc-container li,#ez-toc-container ul{padding:0}#ez-toc-container li,#ez-toc-container ul,#ez-toc-container ul li,.ez-toc-widget-container,.ez-toc-widget-container li{background:0 0;list-style:none;line-height:1.6;margin:0;overflow:hidden;z-index:1}.btn.active,.ez-toc-btn,.ez-toc-btn-default.active,.ez-toc-btn-default:active,.ez-toc-btn:active{background-image:none}#ez-toc-container p.ez-toc-title{text-align:left;line-height:1.45;margin:0;padding:0}.ez-toc-title-container{display:table;width:100%}.ez-toc-title,.ez-toc-title-toggle{display:table-cell;text-align:left;vertical-align:middle}#ez-toc-container.ez-toc-black p.ez-toc-title{color:#FFF}#ez-toc-container div.ez-toc-title-container+ul.ez-toc-list{margin-top:1em}.ez-toc-wrap-left{float:left;margin-right:10px}.ez-toc-wrap-right{float:right;margin-left:10px}#ez-toc-container a{color:#444;text-decoration:none;text-shadow:none}#ez-toc-container a:visited{color:#9f9f9f}#ez-toc-container a:hover{text-decoration:underline}#ez-toc-container.ez-toc-black a,#ez-toc-container.ez-toc-black a:visited{color:#FFF}#ez-toc-container a.ez-toc-toggle{color:#444}#ez-toc-container.counter-flat ul,#ez-toc-container.counter-hierarchy ul,.ez-toc-widget-container.counter-flat ul,.ez-toc-widget-container.counter-hierarchy ul{counter-reset:item}#ez-toc-container.counter-numeric li,.ez-toc-widget-container.counter-numeric li{list-style-type:decimal;list-style-position:inside}#ez-toc-container.counter-decimal ul.ez-toc-list li a::before,.ez-toc-widget-container.counter-decimal ul.ez-toc-list li a::before{content:counters(item,".") ". ";counter-increment:item}#ez-toc-container.counter-roman li a::before,.ez-toc-widget-container.counter-roman ul.ez-toc-list li a::before{content:counters(item,".",upper-roman) ". ";counter-increment:item}.ez-toc-widget-container ul.ez-toc-list li::before{content:' ';position:absolute;left:0;right:0;height:30px;line-height:30px;z-index:-1}.ez-toc-widget-container ul.ez-toc-list li.active::before{background-color:#EDEDED}.ez-toc-widget-container li.active>a{font-weight:900}.ez-toc-btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;border:1px solid transparent;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.ez-toc-btn:focus{outline:#333 dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.ez-toc-btn:focus,.ez-toc-btn:hover{color:#333;text-decoration:none}.ez-toc-btn.active,.ez-toc-btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.ez-toc-btn-default{color:#333;background-color:#fff;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.ez-toc-btn-default.active,.ez-toc-btn-default:active,.ez-toc-btn-default:focus,.ez-toc-btn-default:hover{color:#333;background-color:#ebebeb;border-color:#adadad}.ez-toc-btn-sm,.ez-toc-btn-xs{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.ez-toc-glyphicon,[class*=ez-toc-icon-]{font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ez-toc-btn-xs{padding:1px 5px}.ez-toc-btn-default:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.ez-toc-btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left 0,left 100%,from(#fff),to(#e0e0e0));background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-moz-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);background-repeat:repeat-x;border-color:#ccc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.ez-toc-btn-default:focus,.ez-toc-btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.ez-toc-btn-default.active,.ez-toc-btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.ez-toc-pull-right{float:right!important;margin-left:10px}.ez-toc-glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings'}.ez-toc-glyphicon:empty{width:1em}.ez-toc-toggle i.ez-toc-glyphicon{font-size:16px;margin-left:2px}[class*=ez-toc-icon-]{font-family:ez-toc-icomoon!important;speak:none;font-variant:normal;text-transform:none}.ez-toc-icon-toggle:before{content:"\e87a"}
assets/js/front.js CHANGED
@@ -1,4 +1,4 @@
1
- jQuery( function( $ ) {
2
 
3
  if ( typeof ezTOC != 'undefined' ) {
4
 
@@ -99,11 +99,8 @@ jQuery( function( $ ) {
99
  if ( target ) {
100
  $.smoothScroll( {
101
  scrollTarget: target,
102
- offset: offset,
103
- beforeScroll: deactivateSetActiveEzTocListElement,
104
- afterScroll: function() { setActiveEzTocListElement(); activateSetActiveEzTocListElement(); }
105
  } );
106
-
107
  }
108
  }
109
  } );
@@ -170,127 +167,54 @@ jQuery( function( $ ) {
170
  } );
171
  }
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
 
174
- // ======================================
175
- // Set active heading in ez-toc-widget list
176
- // ======================================
177
-
178
- var headings = $( 'span.ez-toc-section' ).toArray();
179
- var headingToListElementLinkMap = getHeadingToListElementLinkMap( headings );
180
- var listElementLinks = $.map( headingToListElementLinkMap, function ( value, key ) {
181
- return value
182
- } );
183
- var scrollOffset = getScrollOffset();
184
-
185
- activateSetActiveEzTocListElement();
186
-
187
- function setActiveEzTocListElement() {
188
- var activeHeading = getActiveHeading( scrollOffset, headings );
189
- if ( activeHeading ) {
190
- var activeListElementLink = headingToListElementLinkMap[ activeHeading.id ];
191
- removeStyleFromNonActiveListElement( activeListElementLink, listElementLinks );
192
- setStyleForActiveListElementElement( activeListElementLink );
193
- }
194
- };
195
-
196
- function activateSetActiveEzTocListElement() {
197
- if ( headings.length > 0 && $('.ez-toc-widget-container').length) {
198
- $( window ).on( 'load resize scroll', setActiveEzTocListElement );
199
- }
200
- }
201
-
202
- function deactivateSetActiveEzTocListElement() {
203
- $( window ).off( 'load resize scroll', setActiveEzTocListElement );
204
- }
205
-
206
- function getEzTocListElementLinkByHeading( heading ) {
207
- return $( '.ez-toc-widget-container .ez-toc-list a[href="#' + $( heading ).attr( 'id' ) + '"]' );
208
- }
209
-
210
- function getHeadingToListElementLinkMap( headings ) {
211
- return headings.reduce( function ( map, heading ) {
212
- map[ heading.id ] = getEzTocListElementLinkByHeading( heading );
213
- return map;
214
- }, {} );
215
- }
216
-
217
- function getScrollOffset() {
218
- var scrollOffset = 5; // so if smooth offset is off, the correct title is set as active
219
- if ( typeof ezTOC.smooth_scroll != 'undefined' && parseInt( ezTOC.smooth_scroll ) === 1 ) {
220
- scrollOffset = ( typeof ezTOC.scroll_offset != 'undefined' ) ? parseInt( ezTOC.scroll_offset ) : 30;
221
- }
222
-
223
- var adminbar = $( '#wpadminbar' );
224
-
225
- if ( adminbar.length ) {
226
- scrollOffset += adminbar.height();
227
- }
228
- return scrollOffset;
229
- }
230
-
231
- function getActiveHeading( topOffset, headings ) {
232
- var scrollTop = $( window ).scrollTop();
233
- var relevantOffset = scrollTop + topOffset + 1;
234
- var activeHeading = headings[ 0 ];
235
- var closestHeadingAboveOffset = relevantOffset - $( activeHeading ).offset().top;
236
- headings.forEach( function ( section ) {
237
- var topOffset = relevantOffset - $( section ).offset().top;
238
- if ( topOffset > 0 && topOffset < closestHeadingAboveOffset ) {
239
- closestHeadingAboveOffset = topOffset;
240
- activeHeading = section;
241
- }
242
- } );
243
- return activeHeading;
244
- }
245
-
246
- function removeStyleFromNonActiveListElement( activeListElementLink, listElementLinks ) {
247
- listElementLinks.forEach( function ( listElementLink ) {
248
- if ( activeListElementLink !== listElementLink && listElementLink.parent().hasClass( 'active' ) ) {
249
- listElementLink.parent().removeClass( 'active' );
250
- }
251
- } );
252
- }
253
-
254
- function correctActiveListElementBackgroundColorHeight( activeListElement ) {
255
- var listElementHeight = getListElementHeightWithoutUlChildren( activeListElement );
256
- addListElementBackgroundColorHeightStyleToHead( listElementHeight );
257
- }
258
-
259
- function getListElementHeightWithoutUlChildren( listElement ) {
260
- var $listElement = $( listElement );
261
- var content = $listElement.html();
262
- // Adding list item with class '.active' to get the real height.
263
- // When adding a class to an existing element and using jQuery(..).height() directly afterwards,
264
- // the height is the 'old' height. The height might change due to text-wraps when setting the text-weight bold for example
265
- // When adding a new item, the height is calculated correctly.
266
- // But only when it might be visible (so display:none; is not possible...)
267
- // But because it get's directly removed afterwards it never will be rendered by the browser
268
- // (at least in my tests in FF, Chrome, IE11 and Edge)
269
- $listElement.parent().append( '<li id="ez-toc-height-test" class="active">' + content + '</li>' );
270
- var height = jQuery( '#ez-toc-height-test' ).height();
271
- jQuery( '#ez-toc-height-test' ).remove();
272
- return height - $listElement.children( 'ul' ).first().height();
273
- }
274
-
275
- function addListElementBackgroundColorHeightStyleToHead( listElementHeight ) {
276
- // Remove existing
277
- $( '#ez-toc-active-height' ).remove();
278
- // jQuery(..).css(..) doesn't work, because ::before is a pseudo element and not part of the DOM
279
- // Workaround is to add it to head
280
- $( '<style id="ez-toc-active-height">' +
281
- '.ez-toc-widget-container ul.ez-toc-list li.active::before {' +
282
- // 'line-heigh:' + listElementHeight + 'px; ' +
283
- 'height:' + listElementHeight + 'px;' +
284
- '} </style>' )
285
- .appendTo( 'head' );
286
- }
287
-
288
- function setStyleForActiveListElementElement( activeListElementLink ) {
289
- var activeListElement = activeListElementLink.parent();
290
- if ( !activeListElement.hasClass( 'active' ) ) {
291
- activeListElement.addClass( 'active' );
292
- }
293
- correctActiveListElementBackgroundColorHeight( activeListElement );
294
- }
295
- }
296
  } );
1
+ jQuery( document ).ready( function( $ ) {
2
 
3
  if ( typeof ezTOC != 'undefined' ) {
4
 
99
  if ( target ) {
100
  $.smoothScroll( {
101
  scrollTarget: target,
102
+ offset: offset
 
 
103
  } );
 
104
  }
105
  }
106
  } );
167
  } );
168
  }
169
 
170
+ // ======================================
171
+ // Waypoints helper functions
172
+ // ======================================
173
+
174
+ // Get link by section or article id
175
+ function getRelatedNavigation( element ) {
176
+ return $( '.ez-toc-widget-container .ez-toc-list a[href="#' + $( element ).attr( 'id' ) + '"]' );
177
+ }
178
+
179
+ function getScrollOffset( element ) {
180
+
181
+ var scrollOffset = ( typeof ezTOC.scroll_offset != 'undefined' ) ? parseInt( ezTOC.scroll_offset ) : 30;
182
+ var offset = $( element ).height() + scrollOffset;
183
+
184
+ var adminbar = $( '#wpadminbar' );
185
+
186
+ if ( 0 === adminbar.length ) {
187
+
188
+ offset = offset-30;
189
+ }
190
+
191
+ return parseInt( offset );
192
+ }
193
+
194
+ // ======================================
195
+ // Waypoints
196
+ // ======================================
197
+
198
+ $('span.ez-toc-section')
199
+ .waypoint( function( direction ) {
200
+ // Highlight element when related content is 10% percent from the bottom - remove if below.
201
+ var item = getRelatedNavigation( this.element ).toggleClass( 'active', direction === 'down' );
202
+ item.toggleClass( 'active', direction === 'down' ).parent().toggleClass( 'active', direction === 'down' );
203
+ }, {
204
+ offset: '90%' //
205
+ });
206
+ $('span.ez-toc-section')
207
+ .waypoint( function( direction ) {
208
+ // Highlight element when bottom of related content is 30px from the top - remove if less.
209
+ var item = getRelatedNavigation( this.element ).toggleClass( 'active', direction === 'up' );
210
+ item.toggleClass( 'active', direction === 'up' ).parent().toggleClass( 'active', direction === 'up' );
211
+ }, {
212
+ offset: getScrollOffset( this.element )
213
+ });
214
+
215
+
216
+ var div_height = $('.ez-toc-widget-container ul.ez-toc-list li').css('line-height');
217
 
218
+ $('<style>.ez-toc-widget-container ul.ez-toc-list li::before{line-height:' + div_height + ';height:' + div_height + '}</style>').appendTo('head');
219
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  } );
assets/js/front.min.js CHANGED
@@ -1 +1,6 @@
1
- jQuery(function(l){if("undefined"!=typeof ezTOC){if(0!==l(".ez-toc-widget-container.ez-toc-affix").length){var e=30;void 0!==ezTOC.scroll_offset&&(e=ezTOC.scroll_offset),l(ezTOC.affixSelector).stick_in_parent({inner_scrolling:!1,offset_top:parseInt(e)})}if(l.fn.shrinkTOCWidth=function(){l(this).css({width:"auto",display:"table"}),/MSIE 7\./.test(navigator.userAgent)&&l(this).css("width","")},1==ezTOC.smooth_scroll){var a=hostname=pathname=qs=hash=null;l("body a").click(function(e){if(hostname=l(this).prop("hostname"),pathname=l(this).prop("pathname"),qs=l(this).prop("search"),hash=l(this).prop("hash"),0<pathname.length&&"/"!=pathname.charAt(0)&&(pathname="/"+pathname),window.location.hostname==hostname&&window.location.pathname==pathname&&window.location.search==qs&&""!==hash){var t=hash.replace(/([ !"$%&'()*+,.\/:;<=>?@[\]^`{|}~])/g,"\\$1");if(0<l(t).length?a=hash:(anchor=hash,anchor=anchor.replace("#",""),a='a[name="'+anchor+'"]',0==l(a).length&&(a="")),void 0!==ezTOC.scroll_offset)var i=-1*ezTOC.scroll_offset;else{var o=l("#wpadminbar");i=0<o.length&&o.is(":visible")?-30:0}a&&l.smoothScroll({scrollTarget:a,offset:i,beforeScroll:h,afterScroll:function(){s(),n()}})}})}if(void 0!==ezTOC.visibility_hide_by_default){var t=l("a.ez-toc-toggle"),i=ezTOC.visibility_hide_by_default;Cookies&&1==Cookies.get("ezTOC_hidetoc")?t.data("visible",!1):t.data("visible",!0),i&&t.data("visible",!1),t.data("visible")||l("ul.ez-toc-list").hide(),t.click(function(e){e.preventDefault(),l(this).data("visible")?(l(this).data("visible",!1),Cookies&&(i?Cookies.set("ezTOC_hidetoc",null,{path:"/"}):Cookies.set("ezTOC_hidetoc","1",{expires:30,path:"/"})),l("ul.ez-toc-list").hide("fast")):(l(this).data("visible",!0),Cookies&&(i?Cookies.set("ezTOC_hidetoc","1",{expires:30,path:"/"}):Cookies.set("ezTOC_hidetoc",null,{path:"/"})),l("ul.ez-toc-list").show("fast"))})}var r=l("span.ez-toc-section").toArray(),c=r.reduce(function(e,t){return e[t.id]=l('.ez-toc-widget-container .ez-toc-list a[href="#'+l(t).attr("id")+'"]'),e},{}),f=l.map(c,function(e,t){return e}),d=function(){var e=5;void 0!==ezTOC.smooth_scroll&&1===parseInt(ezTOC.smooth_scroll)&&(e=void 0!==ezTOC.scroll_offset?parseInt(ezTOC.scroll_offset):30);var t=l("#wpadminbar");t.length&&(e+=t.height());return e}();function s(){var e,t,i,o,a,s,n=(e=d,t=r,i=l(window).scrollTop()+e+1,o=t[0],a=i-l(o).offset().top,t.forEach(function(e){var t=i-l(e).offset().top;0<t&&t<a&&(a=t,o=e)}),o);if(n){var h=c[n.id];s=h,f.forEach(function(e){s!==e&&e.parent().hasClass("active")&&e.parent().removeClass("active")}),function(e){var t=e.parent();t.hasClass("active")||t.addClass("active");i=t,o=function(e){var t=l(e),i=t.html();t.parent().append('<li id="ez-toc-height-test" class="active">'+i+"</li>");var o=jQuery("#ez-toc-height-test").height();return jQuery("#ez-toc-height-test").remove(),o-t.children("ul").first().height()}(i),l("#ez-toc-active-height").remove(),l('<style id="ez-toc-active-height">.ez-toc-widget-container ul.ez-toc-list li.active::before {height:'+o+"px;} </style>").appendTo("head");var i,o}(h)}}function n(){0<r.length&&l(".ez-toc-widget-container").length&&l(window).on("load resize scroll",s)}function h(){l(window).off("load resize scroll",s)}n()}});
 
 
 
 
 
1
+ jQuery(document).ready(function(a){if("undefined"!=typeof ezTOC){var f=function(b){return a('.ez-toc-widget-container .ez-toc-list a[href="#'+a(b).attr("id")+'"]')};if(0!==a(".ez-toc-widget-container.ez-toc-affix").length){var c=30;"undefined"!=typeof ezTOC.scroll_offset&&(c=ezTOC.scroll_offset);a(ezTOC.affixSelector).stick_in_parent({inner_scrolling:!1,offset_top:parseInt(c)})}a.fn.shrinkTOCWidth=function(){a(this).css({width:"auto",display:"table"});/MSIE 7\./.test(navigator.userAgent)&&a(this).css("width",
2
+ "")};if(1==ezTOC.smooth_scroll){var d=hostname=pathname=qs=hash=null;a("body a").click(function(b){hostname=a(this).prop("hostname");pathname=a(this).prop("pathname");qs=a(this).prop("search");hash=a(this).prop("hash");0<pathname.length&&"/"!=pathname.charAt(0)&&(pathname="/"+pathname);window.location.hostname==hostname&&window.location.pathname==pathname&&window.location.search==qs&&""!==hash&&(b=hash.replace(/([ !"$%&'()*+,.\/:;<=>?@[\]^`{|}~])/g,"\\$1"),0<a(b).length?d=hash:(anchor=hash,anchor=
3
+ anchor.replace("#",""),d='a[name="'+anchor+'"]',0==a(d).length&&(d="")),"undefined"!=typeof ezTOC.scroll_offset?b=-1*ezTOC.scroll_offset:(b=a("#wpadminbar"),b=0<b.length?b.is(":visible")?-30:0:0),d&&a.smoothScroll({scrollTarget:d,offset:b}))})}if("undefined"!=typeof ezTOC.visibility_hide_by_default){c=a("a.ez-toc-toggle");var e=ezTOC.visibility_hide_by_default;Cookies?1==Cookies.get("ezTOC_hidetoc")?c.data("visible",!1):c.data("visible",!0):c.data("visible",!0);e&&c.data("visible",!1);c.data("visible")||
4
+ a("ul.ez-toc-list").hide();c.click(function(b){b.preventDefault();a(this).data("visible")?(a(this).data("visible",!1),Cookies&&(e?Cookies.set("ezTOC_hidetoc",null,{path:"/"}):Cookies.set("ezTOC_hidetoc","1",{expires:30,path:"/"})),a("ul.ez-toc-list").hide("fast")):(a(this).data("visible",!0),Cookies&&(e?Cookies.set("ezTOC_hidetoc","1",{expires:30,path:"/"}):Cookies.set("ezTOC_hidetoc",null,{path:"/"})),a("ul.ez-toc-list").show("fast"))})}a("span.ez-toc-section").waypoint(function(a){f(this.element).toggleClass("active",
5
+ "down"===a).toggleClass("active","down"===a).parent().toggleClass("active","down"===a)},{offset:"90%"});a("span.ez-toc-section").waypoint(function(a){f(this.element).toggleClass("active","up"===a).toggleClass("active","up"===a).parent().toggleClass("active","up"===a)},{offset:function(b){var c="undefined"!=typeof ezTOC.scroll_offset?parseInt(ezTOC.scroll_offset):30;b=a(b).height()+c;0===a("#wpadminbar").length&&(b-=30);return parseInt(b)}(this.element)});c=a(".ez-toc-widget-container ul.ez-toc-list li").css("line-height");
6
+ a("<style>.ez-toc-widget-container ul.ez-toc-list li::before{line-height:"+c+";height:"+c+"}</style>").appendTo("head")}});
easy-table-of-contents.php CHANGED
@@ -3,13 +3,13 @@
3
  * Plugin Name: Easy Table of Contents
4
  * Plugin URI: http://connections-pro.com/
5
  * Description: Adds a user friendly and fully automatic way to create and display a table of contents generated from the page content.
6
- * Version: 2.0-rc10
7
  * Author: Steven A. Zahm
8
  * Author URI: http://connections-pro.com/
9
  * Text Domain: easy-table-of-contents
10
  * Domain Path: /languages
11
  *
12
- * Copyright 2020 Steven A. Zahm ( email : helpdesk@connections-pro.com )
13
  *
14
  * Easy Table of Contents is free software; you can redistribute it and/or modify
15
  * it under the terms of the GNU General Public License, version 2, as
@@ -26,11 +26,9 @@
26
  * @package Easy Table of Contents
27
  * @category Plugin
28
  * @author Steven A. Zahm
29
- * @version 2.0-rc10
30
  */
31
 
32
- use function Easy_Plugins\Table_Of_Contents\String\mb_find_replace;
33
-
34
  // Exit if accessed directly
35
  if ( ! defined( 'ABSPATH' ) ) exit;
36
 
@@ -47,7 +45,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
47
  * @since 1.0
48
  * @var string
49
  */
50
- const VERSION = '2.0-rc10';
51
 
52
  /**
53
  * Stores the instance of this class.
@@ -61,10 +59,15 @@ if ( ! class_exists( 'ezTOC' ) ) {
61
  private static $instance;
62
 
63
  /**
64
- * @since 2.0
 
 
 
 
 
65
  * @var array
66
  */
67
- private static $store = array();
68
 
69
  /**
70
  * A dummy constructor to prevent the class from being loaded more than once.
@@ -129,12 +132,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
129
  require_once( EZ_TOC_PATH . 'includes/class.admin.php' );
130
  }
131
 
132
- require_once( EZ_TOC_PATH . 'includes/class.post.php' );
133
  require_once( EZ_TOC_PATH . 'includes/class.widget-toc.php' );
134
- require_once( EZ_TOC_PATH . 'includes/inc.functions.php' );
135
- require_once( EZ_TOC_PATH . 'includes/inc.string-functions.php' );
136
-
137
- require_once( EZ_TOC_PATH . 'includes/inc.plugin-compatibility.php' );
138
  }
139
 
140
  /**
@@ -150,7 +148,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
150
  add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueueScripts' ) );
151
 
152
  // Run after shortcodes are interpreted (priority 10).
153
- add_filter( 'the_content', array( __CLASS__, 'the_content' ), 99999 );
154
  add_shortcode( 'ez-toc', array( __CLASS__, 'shortcode' ) );
155
  add_shortcode( apply_filters( 'ez_toc_shortcode', 'toc' ), array( __CLASS__, 'shortcode' ) );
156
  }
@@ -200,13 +198,11 @@ if ( ! class_exists( 'ezTOC' ) ) {
200
  } else {
201
 
202
  // Load the default language files
203
- load_plugin_textdomain( $domain, false, $languagesDirectory );
204
  }
205
  }
206
 
207
  /**
208
- * Call back for the `wp_enqueue_scripts` action.
209
- *
210
  * Register and enqueue CSS and javascript files for frontend.
211
  *
212
  * @access private
@@ -216,17 +212,18 @@ if ( ! class_exists( 'ezTOC' ) ) {
216
  public static function enqueueScripts() {
217
 
218
  // If SCRIPT_DEBUG is set and TRUE load the non-minified JS files, otherwise, load the minified files.
219
- $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
220
 
221
  $js_vars = array();
222
 
223
  wp_register_style( 'ez-icomoon', EZ_TOC_URL . "vendor/icomoon/style$min.css", array(), ezTOC::VERSION );
224
  wp_register_style( 'ez-toc', EZ_TOC_URL . "assets/css/screen$min.css", array( 'ez-icomoon' ), ezTOC::VERSION );
225
 
226
- wp_register_script( 'js-cookie', EZ_TOC_URL . "vendor/js-cookie/js.cookie$min.js", array(), '2.2.1', TRUE );
227
- wp_register_script( 'jquery-smooth-scroll', EZ_TOC_URL . "vendor/smooth-scroll/jquery.smooth-scroll$min.js", array( 'jquery' ), '2.2.0', TRUE );
228
  wp_register_script( 'jquery-sticky-kit', EZ_TOC_URL . "vendor/sticky-kit/jquery.sticky-kit$min.js", array( 'jquery' ), '1.9.2', TRUE );
229
- wp_register_script( 'ez-toc-js', EZ_TOC_URL . "assets/js/front$min.js", array( 'jquery-smooth-scroll', 'js-cookie', 'jquery-sticky-kit'), ezTOC::VERSION, TRUE );
 
230
 
231
  if ( ! ezTOC_Option::get( 'exclude_css' ) ) {
232
 
@@ -236,7 +233,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
236
 
237
  if ( ezTOC_Option::get( 'smooth_scroll' ) ) {
238
 
239
- $js_vars['smooth_scroll'] = true;
240
  }
241
 
242
  //wp_enqueue_script( 'ez-toc-js' );
@@ -245,7 +242,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
245
 
246
  $width = ezTOC_Option::get( 'width' ) != 'custom' ? ezTOC_Option::get( 'width' ) : ezTOC_Option::get( 'width_custom' ) . ezTOC_Option::get( 'width_custom_units' );
247
 
248
- $js_vars['visibility_hide_by_default'] = ezTOC_Option::get( 'visibility_hide_by_default' ) ? true : false;
249
 
250
  $js_vars['width'] = esc_js( $width );
251
  }
@@ -310,7 +307,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
310
  $css .= '}';
311
  }
312
 
313
- if ( 'custom' == ezTOC_Option::get( 'theme' ) ) {
314
 
315
  $css .= 'div#ez-toc-container p.ez-toc-title {color: ' . ezTOC_Option::get( 'custom_title_colour' ) . ';}';
316
  //$css .= 'div#ez-toc-container p.ez-toc-title a,div#ez-toc-container ul.ez-toc-list a {color: ' . ezTOC_Option::get( 'custom_link_colour' ) . ';}';
@@ -326,6 +323,505 @@ if ( ! class_exists( 'ezTOC' ) ) {
326
  }
327
  }
328
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329
  /**
330
  * Array search deep.
331
  *
@@ -344,47 +840,38 @@ if ( ! class_exists( 'ezTOC' ) ) {
344
  foreach ( new RecursiveIteratorIterator( new RecursiveArrayIterator( $array ) ) as $key => $value ) {
345
 
346
  if ( $search === ${${"mode"}} ) {
347
- return true;
348
  }
349
  }
350
 
351
- return false;
352
  }
353
 
354
  /**
355
  * Returns true if the table of contents is eligible to be printed, false otherwise.
356
  *
357
- * NOTE: Must bve use only within the loop.
358
- *
359
  * @access public
360
  * @since 1.0
361
  * @static
362
  *
363
- * @param WP_Post $post
364
- *
365
  * @return bool
366
  */
367
- public static function is_eligible( $post ) {
368
 
369
- global $wp_current_filter;
370
 
371
- if ( empty( $post ) || ! $post instanceof WP_Post ) {
372
- return false;
373
- }
374
-
375
- // Do not execute if root filter is one of those in the array.
376
- if ( in_array( $wp_current_filter[0], array( 'get_the_excerpt', 'wp_head' ), true ) ) {
377
 
378
- return false;
 
379
  }
380
 
381
- if ( has_shortcode( $post->post_content, apply_filters( 'ez_toc_shortcode', 'toc' ) ) ||
382
- has_shortcode( $post->post_content, 'ez-toc' ) ) {
383
- return true;
384
  }
385
 
386
  if ( is_front_page() && ! ezTOC_Option::get( 'include_homepage' ) ) {
387
- return false;
388
  }
389
 
390
  $type = get_post_type( $post->ID );
@@ -396,70 +883,204 @@ if ( ! class_exists( 'ezTOC' ) ) {
396
 
397
  if ( ezTOC_Option::get( 'restrict_path' ) ) {
398
 
 
 
 
 
 
 
 
 
 
399
  /**
400
  * @link https://wordpress.org/support/topic/restrict-path-logic-does-not-work-correctly?
401
  */
402
- if ( false !== strpos( ezTOC_Option::get( 'restrict_path' ), $_SERVER['REQUEST_URI'] ) ) {
403
 
404
- return false;
405
 
406
  } else {
407
 
408
- return true;
409
  }
410
 
411
  } else {
412
 
413
- if ( $insert && 1 == get_post_meta( $post->ID, '_ez-toc-disabled', true ) ) {
414
 
415
- return false;
416
 
417
- } elseif ( $insert && 0 == get_post_meta( $post->ID, '_ez-toc-disabled', true ) ) {
418
 
419
- return true;
420
 
421
- } elseif ( $enabled && 1 == get_post_meta( $post->ID, '_ez-toc-insert', true ) ) {
422
 
423
- return true;
424
  }
425
 
426
- return false;
 
427
  }
428
 
429
  } else {
430
 
431
- return false;
432
  }
433
  }
434
 
435
  /**
436
- * Get TOC from store and if not in store process post and add it to the store.
437
  *
438
- * @since 2.0
 
 
439
  *
440
- * @param int $id
441
  *
442
- * @return ezTOC_Post|null
443
  */
444
- public static function get( $id ) {
445
 
446
- $post = null;
447
 
448
- if ( isset( self::$store[ $id ] ) && self::$store[ $id ] instanceof ezTOC_Post ) {
 
 
 
449
 
450
- $post = self::$store[ $id ];
451
 
452
- } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
 
454
- $post = ezTOC_Post::get( get_the_ID() );
 
 
455
 
456
- if ( $post instanceof ezTOC_Post ) {
 
 
457
 
458
- self::$store[ $id ] = $post;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460
  }
461
 
462
- return $post;
463
  }
464
 
465
  /**
@@ -469,67 +1090,27 @@ if ( ! class_exists( 'ezTOC' ) ) {
469
  *
470
  * @access private
471
  * @since 1.3
 
472
  *
473
  * @param array|string $atts Shortcode attributes array or empty string.
474
  * @param string $content The enclosed content (if the shortcode is used in its enclosing form)
475
  * @param string $tag Shortcode name.
476
  *
477
- * @return string
478
  */
479
  public static function shortcode( $atts, $content, $tag ) {
480
 
481
- static $run = true;
482
- $html = '';
483
 
484
  if ( $run ) {
485
 
486
- if ( is_null( $post = self::get( get_the_ID() ) ) ) {
487
-
488
- return $content;
489
- }
490
-
491
- $html = $post->getTOC();
492
- $run = false;
493
  }
494
 
495
- return $html;
496
- }
497
-
498
- /**
499
- * Whether or not apply `the_content` filter.
500
- *
501
- * @since 2.0
502
- *
503
- * @return bool
504
- */
505
- private static function maybeApplyTheContentFilter() {
506
-
507
- $apply = true;
508
-
509
- global $wp_current_filter;
510
-
511
- // Do not execute if root current filter is one of those in the array.
512
- if ( in_array( $wp_current_filter[0], array( 'get_the_excerpt', 'init', 'wp_head' ), true ) ) {
513
-
514
- $apply = false;
515
- }
516
-
517
- // bail if feed, search or archive
518
- if ( is_feed() || is_search() || is_archive() ) {
519
-
520
- $apply = false;
521
- }
522
-
523
- /**
524
- * Whether or not to apply `the_content` filter callback.
525
- *
526
- * @see ezTOC::the_content()
527
- *
528
- * @since 2.0
529
- *
530
- * @param bool $apply
531
- */
532
- return apply_filters( 'ez_toc_maybe_apply_the_content_filter', $apply );
533
  }
534
 
535
  /**
@@ -548,60 +1129,69 @@ if ( ! class_exists( 'ezTOC' ) ) {
548
  */
549
  public static function the_content( $content ) {
550
 
551
- if ( ! self::maybeApplyTheContentFilter() ) {
552
-
553
  return $content;
554
  }
555
 
556
  // bail if post not eligible and widget is not active
557
- $is_eligible = self::is_eligible( get_post() );
558
 
559
  if ( ! $is_eligible && ! is_active_widget( false, false, 'ezw_tco' ) ) {
560
 
561
  return $content;
562
  }
563
 
564
- if ( is_null( $post = self::get( get_the_ID() ) ) ) {
 
 
 
 
 
 
 
 
 
 
565
 
566
- return $content;
567
- }
 
 
 
568
 
569
  // bail if no headings found
570
- if ( ! $post->hasTOCItems() ) {
571
 
572
  return $content;
573
  }
574
 
575
- $find = $post->getHeadings();
576
- $replace = $post->getHeadingsWithAnchors();
577
- $html = $post->getTOC();
578
-
579
  // if shortcode used or post not eligible, return content with anchored headings
580
  if ( strpos( $content, 'ez-toc-container' ) || ! $is_eligible ) {
581
 
582
- return mb_find_replace( $find, $replace, $content );
583
  }
584
 
585
  // else also add toc to content
586
  switch ( ezTOC_Option::get( 'position' ) ) {
587
 
588
  case 'top':
589
- $content = $html . mb_find_replace( $find, $replace, $content );
590
  break;
591
 
592
  case 'bottom':
593
- $content = mb_find_replace( $find, $replace, $content ) . $html;
594
  break;
595
 
596
  case 'after':
597
  $replace[0] = $replace[0] . $html;
598
- $content = mb_find_replace( $find, $replace, $content );
599
  break;
600
 
601
  case 'before':
602
  default:
603
  $replace[0] = $html . $replace[0];
604
- $content = mb_find_replace( $find, $replace, $content );
605
  }
606
 
607
  return $content;
@@ -629,3 +1219,50 @@ if ( ! class_exists( 'ezTOC' ) ) {
629
  // Start Easy Table of Contents.
630
  add_action( 'plugins_loaded', 'ezTOC' );
631
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  * Plugin Name: Easy Table of Contents
4
  * Plugin URI: http://connections-pro.com/
5
  * Description: Adds a user friendly and fully automatic way to create and display a table of contents generated from the page content.
6
+ * Version: 1.7.1
7
  * Author: Steven A. Zahm
8
  * Author URI: http://connections-pro.com/
9
  * Text Domain: easy-table-of-contents
10
  * Domain Path: /languages
11
  *
12
+ * Copyright 2018 Steven A. Zahm ( email : helpdesk@connections-pro.com )
13
  *
14
  * Easy Table of Contents is free software; you can redistribute it and/or modify
15
  * it under the terms of the GNU General Public License, version 2, as
26
  * @package Easy Table of Contents
27
  * @category Plugin
28
  * @author Steven A. Zahm
29
+ * @version 1.7.1
30
  */
31
 
 
 
32
  // Exit if accessed directly
33
  if ( ! defined( 'ABSPATH' ) ) exit;
34
 
45
  * @since 1.0
46
  * @var string
47
  */
48
+ const VERSION = '1.7.1';
49
 
50
  /**
51
  * Stores the instance of this class.
59
  private static $instance;
60
 
61
  /**
62
+ * Keeps a track of used anchors for collision detecting.
63
+ *
64
+ * @access private
65
+ * @since 1.0
66
+ * @static
67
+ *
68
  * @var array
69
  */
70
+ private static $collision_collector = array();
71
 
72
  /**
73
  * A dummy constructor to prevent the class from being loaded more than once.
132
  require_once( EZ_TOC_PATH . 'includes/class.admin.php' );
133
  }
134
 
 
135
  require_once( EZ_TOC_PATH . 'includes/class.widget-toc.php' );
 
 
 
 
136
  }
137
 
138
  /**
148
  add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueueScripts' ) );
149
 
150
  // Run after shortcodes are interpreted (priority 10).
151
+ add_filter( 'the_content', array( __CLASS__, 'the_content' ), 100 );
152
  add_shortcode( 'ez-toc', array( __CLASS__, 'shortcode' ) );
153
  add_shortcode( apply_filters( 'ez_toc_shortcode', 'toc' ), array( __CLASS__, 'shortcode' ) );
154
  }
198
  } else {
199
 
200
  // Load the default language files
201
+ load_plugin_textdomain( $domain, FALSE, $languagesDirectory );
202
  }
203
  }
204
 
205
  /**
 
 
206
  * Register and enqueue CSS and javascript files for frontend.
207
  *
208
  * @access private
212
  public static function enqueueScripts() {
213
 
214
  // If SCRIPT_DEBUG is set and TRUE load the non-minified JS files, otherwise, load the minified files.
215
+ $min = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
216
 
217
  $js_vars = array();
218
 
219
  wp_register_style( 'ez-icomoon', EZ_TOC_URL . "vendor/icomoon/style$min.css", array(), ezTOC::VERSION );
220
  wp_register_style( 'ez-toc', EZ_TOC_URL . "assets/css/screen$min.css", array( 'ez-icomoon' ), ezTOC::VERSION );
221
 
222
+ wp_register_script( 'js-cookie', EZ_TOC_URL . "vendor/js-cookie/js.cookie$min.js", array(), '2.0.3', TRUE );
223
+ wp_register_script( 'jquery-smooth-scroll', EZ_TOC_URL . "vendor/smooth-scroll/jquery.smooth-scroll$min.js", array( 'jquery' ), '1.5.5', TRUE );
224
  wp_register_script( 'jquery-sticky-kit', EZ_TOC_URL . "vendor/sticky-kit/jquery.sticky-kit$min.js", array( 'jquery' ), '1.9.2', TRUE );
225
+ wp_register_script( 'jquery-waypoints', EZ_TOC_URL . "vendor/waypoints/jquery.waypoints$min.js", array( 'jquery' ), '1.9.2', TRUE );
226
+ wp_register_script( 'ez-toc-js', EZ_TOC_URL . "assets/js/front$min.js", array( 'jquery-smooth-scroll', 'js-cookie', 'jquery-sticky-kit', 'jquery-waypoints' ), ezTOC::VERSION, TRUE );
227
 
228
  if ( ! ezTOC_Option::get( 'exclude_css' ) ) {
229
 
233
 
234
  if ( ezTOC_Option::get( 'smooth_scroll' ) ) {
235
 
236
+ $js_vars['smooth_scroll'] = TRUE;
237
  }
238
 
239
  //wp_enqueue_script( 'ez-toc-js' );
242
 
243
  $width = ezTOC_Option::get( 'width' ) != 'custom' ? ezTOC_Option::get( 'width' ) : ezTOC_Option::get( 'width_custom' ) . ezTOC_Option::get( 'width_custom_units' );
244
 
245
+ $js_vars['visibility_hide_by_default'] = ezTOC_Option::get( 'visibility_hide_by_default' ) ? TRUE : FALSE;
246
 
247
  $js_vars['width'] = esc_js( $width );
248
  }
307
  $css .= '}';
308
  }
309
 
310
+ if ( 'custom' == ezTOC_Option::get( 'theme' ) ) {
311
 
312
  $css .= 'div#ez-toc-container p.ez-toc-title {color: ' . ezTOC_Option::get( 'custom_title_colour' ) . ';}';
313
  //$css .= 'div#ez-toc-container p.ez-toc-title a,div#ez-toc-container ul.ez-toc-list a {color: ' . ezTOC_Option::get( 'custom_link_colour' ) . ';}';
323
  }
324
  }
325
 
326
+ /**
327
+ * Returns a URL to be used as the destination anchor target.
328
+ *
329
+ * @access private
330
+ * @since 1.0
331
+ * @static
332
+ *
333
+ * @param string $title
334
+ *
335
+ * @return bool|string
336
+ */
337
+ private static function url_anchor_target( $title ) {
338
+
339
+ $return = FALSE;
340
+
341
+ if ( $title ) {
342
+
343
+ // WP entity encodes the post content.
344
+ $return = html_entity_decode( $title, ENT_QUOTES, get_option( 'blog_charset' ) );
345
+
346
+ $return = trim( strip_tags( $return ) );
347
+
348
+ // Convert accented characters to ASCII.
349
+ $return = remove_accents( $return );
350
+
351
+ // replace newlines with spaces (eg when headings are split over multiple lines)
352
+ $return = str_replace( array( "\r", "\n", "\n\r", "\r\n" ), ' ', $return );
353
+
354
+ // Remove `&amp;` and `&nbsp;` NOTE: in order to strip "hidden" `&nbsp;`,
355
+ // title needs to be converted to HTML entities.
356
+ // @link https://stackoverflow.com/a/21801444/5351316
357
+ $return = htmlentities2( $return );
358
+ $return = str_replace( array( '&amp;', '&nbsp;' ), ' ', $return );
359
+ $return = html_entity_decode( $return, ENT_QUOTES, get_option( 'blog_charset' ) );
360
+
361
+ // remove non alphanumeric chars
362
+ $return = preg_replace( '/[^a-zA-Z0-9 \-_]*/', '', $return );
363
+
364
+ // convert spaces to _
365
+ $return = preg_replace( '/\s+/', '_', $return );
366
+
367
+ // remove trailing - and _
368
+ $return = rtrim( $return, '-_' );
369
+
370
+ // lowercase everything?
371
+ if ( ezTOC_Option::get( 'lowercase' ) ) {
372
+
373
+ $return = strtolower( $return );
374
+ }
375
+
376
+ // if blank, then prepend with the fragment prefix
377
+ // blank anchors normally appear on sites that don't use the latin charset
378
+ if ( ! $return ) {
379
+
380
+ $return = ( ezTOC_Option::get( 'fragment_prefix' ) ) ? ezTOC_Option::get( 'fragment_prefix' ) : '_';
381
+ }
382
+
383
+ // hyphenate?
384
+ if ( ezTOC_Option::get( 'hyphenate' ) ) {
385
+
386
+ $return = str_replace( '_', '-', $return );
387
+ $return = str_replace( '--', '-', $return );
388
+ }
389
+ }
390
+
391
+ if ( array_key_exists( $return, self::$collision_collector ) ) {
392
+
393
+ self::$collision_collector[ $return ]++;
394
+ $return .= '-' . self::$collision_collector[ $return ];
395
+
396
+ } else {
397
+
398
+ self::$collision_collector[ $return ] = 1;
399
+ }
400
+
401
+ return apply_filters( 'ez_toc_url_anchor_target', $return, $title );
402
+ }
403
+
404
+ /**
405
+ * Generates a nested unordered list for the table of contents.
406
+ *
407
+ * @access private
408
+ * @since 1.0
409
+ * @static
410
+ *
411
+ * @param array $matches
412
+ * @param array $headings Array of headers to be considered for a TOC item.
413
+ *
414
+ * @return string
415
+ */
416
+ private static function build_hierarchy( &$matches, $headings ) {
417
+
418
+ $current_depth = 100; // headings can't be larger than h6 but 100 as a default to be sure
419
+ $html = '';
420
+ $numbered_items = array();
421
+ $numbered_items_min = NULL;
422
+
423
+ // reset the internal collision collection
424
+ self::$collision_collector = array();
425
+
426
+ // find the minimum heading to establish our baseline
427
+ for ( $i = 0; $i < count( $matches ); $i ++ ) {
428
+ if ( $current_depth > $matches[ $i ][2] ) {
429
+ $current_depth = (int) $matches[ $i ][2];
430
+ }
431
+ }
432
+
433
+ $numbered_items[ $current_depth ] = 0;
434
+ $numbered_items_min = $current_depth;
435
+
436
+ for ( $i = 0; $i < count( $matches ); $i ++ ) {
437
+
438
+ if ( $current_depth == (int) $matches[ $i ][2] ) {
439
+
440
+ $html .= '<li>';
441
+ }
442
+
443
+ // start lists
444
+ if ( $current_depth != (int) $matches[ $i ][2] ) {
445
+
446
+ for ( $current_depth; $current_depth < (int) $matches[ $i ][2]; $current_depth++ ) {
447
+
448
+ $numbered_items[ $current_depth + 1 ] = 0;
449
+ $html .= '<ul><li>';
450
+ }
451
+ }
452
+
453
+ // list item
454
+ if ( in_array( $matches[ $i ][2], $headings ) ) {
455
+
456
+ //$title = apply_filters( 'ez_toc_title', strip_tags( wp_kses_post( $matches[ $i ][0] ) ) );
457
+ $title = strip_tags( apply_filters( 'ez_toc_title', $matches[ $i ][0] ), apply_filters( 'ez_toc_title_allowable_tags', '' ) );
458
+
459
+ //$html .= '<a href="#' . self::url_anchor_target( $title ) . '">';
460
+ $html .= sprintf(
461
+ '<a href="%1$s" title="%2$s">',
462
+ esc_url( '#' . self::url_anchor_target( $matches[ $i ][0] ) ),
463
+ esc_attr( strip_tags( $title ) )
464
+ );
465
+
466
+ //if ( 'decimal' == ezTOC_Option::get( 'counter' ) ) {
467
+ //
468
+ // // attach leading numbers when lower in hierarchy
469
+ // $html .= '<span class="ez-toc-number ez-toc-depth_' . ( $current_depth - $numbered_items_min + 1 ) . '">';
470
+ //
471
+ // for ( $j = $numbered_items_min; $j < $current_depth; $j ++ ) {
472
+ //
473
+ // $number = ( $numbered_items[ $j ] ) ? $numbered_items[ $j ] : 0;
474
+ // $html .= $number . '.';
475
+ // }
476
+ //
477
+ // $html .= ( $numbered_items[ $current_depth ] + 1 ) . '</span> ';
478
+ // $numbered_items[ $current_depth ] ++;
479
+ //}
480
+
481
+ $html .= $title . '</a>';
482
+ }
483
+
484
+ // end lists
485
+ if ( $i != count( $matches ) - 1 ) {
486
+
487
+ if ( $current_depth > (int) $matches[ $i + 1 ][2] ) {
488
+
489
+ for ( $current_depth; $current_depth > (int) $matches[ $i + 1 ][2]; $current_depth-- ) {
490
+
491
+ $html .= '</li></ul>';
492
+ $numbered_items[ $current_depth ] = 0;
493
+ }
494
+ }
495
+
496
+ if ( $current_depth == (int) @$matches[ $i + 1 ][2] ) {
497
+
498
+ $html .= '</li>';
499
+ }
500
+
501
+ } else {
502
+
503
+ // this is the last item, make sure we close off all tags
504
+ for ( $current_depth; $current_depth >= $numbered_items_min; $current_depth -- ) {
505
+
506
+ $html .= '</li>';
507
+
508
+ if ( $current_depth != $numbered_items_min ) {
509
+ $html .= '</ul>';
510
+ }
511
+ }
512
+ }
513
+ }
514
+
515
+ return $html;
516
+ }
517
+
518
+ /**
519
+ * Returns a string with all items from the $find array replaced with their matching
520
+ * items in the $replace array. This does a one to one replacement (rather than globally).
521
+ *
522
+ * This function is multibyte safe.
523
+ *
524
+ * $find and $replace are arrays, $string is the haystack. All variables are passed by reference.
525
+ *
526
+ * @access private
527
+ * @since 1.0
528
+ * @static
529
+ *
530
+ * @param bool $find
531
+ * @param bool $replace
532
+ * @param string $string
533
+ *
534
+ * @return mixed|string
535
+ */
536
+ private static function mb_find_replace( &$find = FALSE, &$replace = FALSE, &$string = '' ) {
537
+
538
+ if ( is_array( $find ) && is_array( $replace ) && $string ) {
539
+
540
+ // check if multibyte strings are supported
541
+ if ( function_exists( 'mb_strpos' ) ) {
542
+
543
+ for ( $i = 0; $i < count( $find ); $i ++ ) {
544
+
545
+ $string = mb_substr(
546
+ $string,
547
+ 0,
548
+ mb_strpos( $string, $find[ $i ] )
549
+ ) . // everything before $find
550
+ $replace[ $i ] . // its replacement
551
+ mb_substr(
552
+ $string,
553
+ mb_strpos( $string, $find[ $i ] ) + mb_strlen( $find[ $i ] )
554
+ ) // everything after $find
555
+ ;
556
+ }
557
+
558
+ } else {
559
+
560
+ for ( $i = 0; $i < count( $find ); $i ++ ) {
561
+
562
+ $string = substr_replace(
563
+ $string,
564
+ $replace[ $i ],
565
+ strpos( $string, $find[ $i ] ),
566
+ strlen( $find[ $i ] )
567
+ );
568
+ }
569
+ }
570
+ }
571
+
572
+ return $string;
573
+ }
574
+
575
+ /**
576
+ * This function extracts headings from the html formatted $content. It will pull out
577
+ * only the required headings as specified in the options. For all qualifying headings,
578
+ * this function populates the $find and $replace arrays (both passed by reference)
579
+ * with what to search and replace with.
580
+ *
581
+ * Returns a HTML formatted string of list items for each qualifying heading. This
582
+ * is everything between and NOT including <ul> and </ul>
583
+ *
584
+ * @access private
585
+ * @since 1.0
586
+ * @static
587
+ *
588
+ * @param array $find
589
+ * @param array $replace
590
+ * @param WP_Post $post
591
+ *
592
+ * @return bool|string
593
+ */
594
+ public static function extract_headings( &$find, &$replace, $post ) {
595
+
596
+ $matches = array();
597
+ $anchor = '';
598
+ $items = '';
599
+
600
+ $headings = get_post_meta( $post->ID, '_ez-toc-heading-levels', TRUE );
601
+ $exclude = get_post_meta( $post->ID, '_ez-toc-exclude', TRUE );
602
+ $altText = get_post_meta( $post->ID, '_ez-toc-alttext', TRUE );
603
+
604
+ if ( ! is_array( $headings ) ) {
605
+
606
+ $headings = array();
607
+ }
608
+
609
+ if ( empty( $headings ) ) {
610
+
611
+ $headings = ezTOC_Option::get( 'heading_levels', array() );
612
+ }
613
+
614
+ if ( empty( $exclude ) ) {
615
+
616
+ $exclude = ezTOC_Option::get( 'exclude' );
617
+ }
618
+
619
+ // reset the internal collision collection as the_content may have been triggered elsewhere
620
+ // eg by themes or other plugins that need to read in content such as metadata fields in
621
+ // the head html tag, or to provide descriptions to twitter/facebook
622
+ self::$collision_collector = array();
623
+
624
+ $content = apply_filters( 'ez_toc_extract_headings_content', $post->post_content );
625
+
626
+ if ( is_array( $find ) && is_array( $replace ) && $content ) {
627
+
628
+ // get all headings
629
+ // the html spec allows for a maximum of 6 heading depths
630
+ if ( preg_match_all( '/(<h([1-6]{1})[^>]*>).*<\/h\2>/msuU', $content, $matches, PREG_SET_ORDER ) ) {
631
+
632
+ // remove undesired headings (if any) as defined by heading_levels
633
+ if ( count( $headings ) != 6 ) {
634
+
635
+ $new_matches = array();
636
+
637
+ for ( $i = 0; $i < count( $matches ); $i ++ ) {
638
+
639
+ if ( in_array( $matches[ $i ][2], $headings ) ) {
640
+
641
+ $new_matches[] = $matches[ $i ];
642
+ }
643
+ }
644
+ $matches = $new_matches;
645
+ }
646
+
647
+ // remove specific headings if provided via the 'exclude' property
648
+ if ( $exclude ) {
649
+
650
+ $excluded_headings = explode( '|', $exclude );
651
+ $excluded_count = count( $excluded_headings );
652
+
653
+ if ( $excluded_count > 0 ) {
654
+
655
+ for ( $j = 0; $j < $excluded_count; $j++ ) {
656
+
657
+ $excluded_headings[ $j ] = preg_quote( $excluded_headings[ $j ] );
658
+
659
+ // escape some regular expression characters
660
+ // others: http://www.php.net/manual/en/regexp.reference.meta.php
661
+ $excluded_headings[ $j ] = str_replace(
662
+ array( '\*' ),
663
+ array( '.*' ),
664
+ trim( $excluded_headings[ $j ] )
665
+ );
666
+ }
667
+
668
+ $new_matches = array();
669
+
670
+ for ( $i = 0; $i < count( $matches ); $i++ ) {
671
+
672
+ $found = FALSE;
673
+
674
+ for ( $j = 0; $j < $excluded_count; $j++ ) {
675
+
676
+ // Since WP manipulates the post content it is required that the excluded header and
677
+ // the actual header be manipulated similarly so a match can be made.
678
+ $pattern = html_entity_decode(
679
+ wptexturize( $excluded_headings[ $j ] ),
680
+ ENT_NOQUOTES,
681
+ get_option( 'blog_charset' )
682
+ );
683
+
684
+ $against = html_entity_decode(
685
+ wptexturize( strip_tags( $matches[ $i ][0] ) ),
686
+ ENT_NOQUOTES,
687
+ get_option( 'blog_charset' )
688
+ );
689
+
690
+ if ( @preg_match( '/^' . $pattern . '$/imU', $against ) ) {
691
+
692
+ $found = TRUE;
693
+ break;
694
+ }
695
+ }
696
+
697
+ if ( ! $found ) {
698
+
699
+ $new_matches[] = $matches[ $i ];
700
+ }
701
+ }
702
+
703
+ if ( count( $matches ) != count( $new_matches ) ) {
704
+
705
+ $matches = $new_matches;
706
+ }
707
+ }
708
+ }
709
+
710
+ // remove empty headings
711
+ $new_matches = array();
712
+
713
+ for ( $i = 0; $i < count( $matches ); $i ++ ) {
714
+
715
+ if ( trim( strip_tags( $matches[ $i ][0] ) ) != FALSE ) {
716
+
717
+ $new_matches[] = $matches[ $i ];
718
+ }
719
+ }
720
+
721
+ if ( count( $matches ) != count( $new_matches ) ) {
722
+
723
+ $matches = $new_matches;
724
+ }
725
+
726
+ $toc = $matches;
727
+
728
+ // Replace headers with toc alt text.
729
+ if ( $altText ) {
730
+
731
+ $alt_headings = array();
732
+ $split_headings = preg_split( '/\r\n|[\r\n]/', $altText );
733
+ $split_headings_count = count( $split_headings );
734
+
735
+ if ( $split_headings ) {
736
+
737
+ for ( $k = 0; $k < $split_headings_count; $k++ ) {
738
+
739
+ $explode_headings = explode( '|', $split_headings[ $k ] );
740
+
741
+ if ( 0 < strlen( $explode_headings[0] ) && 0 < strlen( $explode_headings[1] ) ) {
742
+
743
+ $alt_headings[ $explode_headings[0] ] = $explode_headings[1];
744
+ }
745
+ }
746
+
747
+ }
748
+
749
+ if ( 0 < count( $alt_headings ) ) {
750
+
751
+ for ( $i = 0; $i < count( $toc ); $i++ ) {
752
+
753
+ foreach ( $alt_headings as $original_heading => $alt_heading ) {
754
+
755
+ $original_heading = preg_quote( $original_heading );
756
+
757
+ // escape some regular expression characters
758
+ // others: http://www.php.net/manual/en/regexp.reference.meta.php
759
+ $original_heading = str_replace(
760
+ array( '\*' ),
761
+ array( '.*' ),
762
+ trim( $original_heading )
763
+ );
764
+
765
+ if ( @preg_match( '/^' . $original_heading . '$/imU', strip_tags( $toc[ $i ][0] ) ) ) {
766
+
767
+ //$matches[ $i ][0] = str_replace( $original_heading, $alt_heading, $matches[ $i ][0] );
768
+ $toc[ $i ][0] = $alt_heading;
769
+ }
770
+ }
771
+ }
772
+ }
773
+ }
774
+
775
+ // check minimum number of headings
776
+ if ( count( $matches ) >= ezTOC_Option::get( 'start' ) ) {
777
+
778
+ for ( $i = 0; $i < count( $matches ); $i++ ) {
779
+
780
+ // get anchor and add to find and replace arrays
781
+ $anchor = isset( $toc[ $i ][0] ) ? self::url_anchor_target( $toc[ $i ][0] ) : self::url_anchor_target( $matches[ $i ][0] );
782
+ $find[] = $matches[ $i ][0];
783
+ $replace[] = str_replace(
784
+ array(
785
+ $matches[ $i ][1], // start of heading
786
+ '</h' . $matches[ $i ][2] . '>' // end of heading
787
+ ),
788
+ array(
789
+ $matches[ $i ][1] . '<span class="ez-toc-section" id="' . $anchor . '">',
790
+ '</span></h' . $matches[ $i ][2] . '>'
791
+ ),
792
+ $matches[ $i ][0]
793
+ );
794
+
795
+ // assemble flat list
796
+ if ( ! ezTOC_Option::get( 'show_hierarchy' ) ) {
797
+
798
+ $items .= '<li><a href="' . esc_url( '#' . $anchor ) . '">';
799
+ //$title = apply_filters( 'ez_toc_title', strip_tags( wp_kses_post( $toc[ $i ][0] ) ) );
800
+ $title = strip_tags( apply_filters( 'ez_toc_title', $matches[ $i ][0] ), apply_filters( 'ez_toc_title_allowable_tags', '' ) );
801
+
802
+ //if ( 'decimal' == ezTOC_Option::get( 'counter' ) ) {
803
+ //
804
+ // $items .= count( $replace ) . ' ';
805
+ //}
806
+
807
+ $items .= $title . '</a></li>';
808
+ }
809
+ }
810
+
811
+ // build a hierarchical toc?
812
+ // we could have tested for $items but that var can be quite large in some cases
813
+ if ( ezTOC_Option::get( 'show_hierarchy' ) ) {
814
+
815
+ $items = self::build_hierarchy( $toc, $headings );
816
+ }
817
+
818
+ }
819
+ }
820
+ }
821
+
822
+ return $items;
823
+ }
824
+
825
  /**
826
  * Array search deep.
827
  *
840
  foreach ( new RecursiveIteratorIterator( new RecursiveArrayIterator( $array ) ) as $key => $value ) {
841
 
842
  if ( $search === ${${"mode"}} ) {
843
+ return TRUE;
844
  }
845
  }
846
 
847
+ return FALSE;
848
  }
849
 
850
  /**
851
  * Returns true if the table of contents is eligible to be printed, false otherwise.
852
  *
 
 
853
  * @access public
854
  * @since 1.0
855
  * @static
856
  *
 
 
857
  * @return bool
858
  */
859
+ public static function is_eligible() {
860
 
861
+ global $wp_query;
862
 
863
+ $post = $wp_query->post;
 
 
 
 
 
864
 
865
+ if ( empty( $post ) ) {
866
+ return FALSE;
867
  }
868
 
869
+ if ( has_shortcode( $post->post_content, 'toc' ) || has_shortcode( $post->post_content, 'ez-toc' ) ) {
870
+ return TRUE;
 
871
  }
872
 
873
  if ( is_front_page() && ! ezTOC_Option::get( 'include_homepage' ) ) {
874
+ return FALSE;
875
  }
876
 
877
  $type = get_post_type( $post->ID );
883
 
884
  if ( ezTOC_Option::get( 'restrict_path' ) ) {
885
 
886
+ //if ( strpos( $_SERVER['REQUEST_URI'], ezTOC_Option::get( 'restrict_path' ) ) === 0 ) {
887
+ //
888
+ // return TRUE;
889
+ //
890
+ //} else {
891
+ //
892
+ // return FALSE;
893
+ //}
894
+
895
  /**
896
  * @link https://wordpress.org/support/topic/restrict-path-logic-does-not-work-correctly?
897
  */
898
+ if ( FALSE !== strpos( ezTOC_Option::get( 'restrict_path' ), $_SERVER['REQUEST_URI'] ) ) {
899
 
900
+ return FALSE;
901
 
902
  } else {
903
 
904
+ return TRUE;
905
  }
906
 
907
  } else {
908
 
909
+ if ( $insert && 1 == get_post_meta( $post->ID, '_ez-toc-disabled', TRUE ) ) {
910
 
911
+ return FALSE;
912
 
913
+ } elseif ( $insert && 0 == get_post_meta( $post->ID, '_ez-toc-disabled', TRUE ) ) {
914
 
915
+ return TRUE;
916
 
917
+ } elseif ( $enabled && 1 == get_post_meta( $post->ID, '_ez-toc-insert', TRUE ) ) {
918
 
919
+ return TRUE;
920
  }
921
 
922
+ return FALSE;
923
+ //return TRUE;
924
  }
925
 
926
  } else {
927
 
928
+ return FALSE;
929
  }
930
  }
931
 
932
  /**
933
+ * Build the table of contents.
934
  *
935
+ * @access private
936
+ * @since 1.3
937
+ * @static
938
  *
939
+ * @param WP_Post $post The page/post content.
940
  *
941
+ * @return array
942
  */
943
+ public static function build( $post ) {
944
 
945
+ $css_classes = '';
946
 
947
+ $html = '';
948
+ $find = array();
949
+ $replace = array();
950
+ $items = self::extract_headings( $find, $replace, $post );
951
 
952
+ if ( $items ) {
953
 
954
+ // wrapping css classes
955
+ switch ( ezTOC_Option::get( 'wrapping' ) ) {
956
+
957
+ case 'left':
958
+ $css_classes .= ' ez-toc-wrap-left';
959
+ break;
960
+
961
+ case 'right':
962
+ $css_classes .= ' ez-toc-wrap-right';
963
+ break;
964
+
965
+ case 'none':
966
+ default:
967
+ // do nothing
968
+ }
969
+
970
+ if ( ezTOC_Option::get( 'show_hierarchy' ) ) {
971
+
972
+ $css_classes .= ' counter-hierarchy';
973
+
974
+ } else {
975
+
976
+ $css_classes .= ' counter-flat';
977
+ }
978
+
979
+ switch ( ezTOC_Option::get( 'counter' ) ) {
980
+
981
+ case 'numeric':
982
+ $css_classes .= ' counter-numeric';
983
+ break;
984
+
985
+ case 'roman':
986
+ $css_classes .= ' counter-roman';
987
+ break;
988
+
989
+ case 'decimal':
990
+ $css_classes .= ' counter-decimal';
991
+ break;
992
+ }
993
+
994
+ // colour themes
995
+ switch ( ezTOC_Option::get( 'theme' ) ) {
996
 
997
+ case 'light-blue':
998
+ $css_classes .= ' ez-toc-light-blue';
999
+ break;
1000
 
1001
+ case 'white':
1002
+ $css_classes .= ' ez-toc-white';
1003
+ break;
1004
 
1005
+ case 'black':
1006
+ $css_classes .= ' ez-toc-black';
1007
+ break;
1008
+
1009
+ case 'transparent':
1010
+ $css_classes .= ' ez-toc-transparent';
1011
+ break;
1012
+
1013
+ case 'grey':
1014
+ $css_classes .= ' ez-toc-grey';
1015
+ break;
1016
+
1017
+ default:
1018
+ // do nothing
1019
+ }
1020
+
1021
+ if ( ezTOC_Option::get( 'css_container_class' ) ) {
1022
+
1023
+ $css_classes .= ' ' . ezTOC_Option::get( 'css_container_class' );
1024
+ }
1025
+
1026
+ $css_classes = trim( $css_classes );
1027
+
1028
+ // an empty class="" is invalid markup!
1029
+ if ( ! $css_classes ) {
1030
+
1031
+ $css_classes = ' ';
1032
  }
1033
+
1034
+ // add container, toc title and list items
1035
+ $html .= '<div id="ez-toc-container" class="' . $css_classes . '">' . PHP_EOL;
1036
+
1037
+ if ( ezTOC_Option::get( 'show_heading_text' ) ) {
1038
+
1039
+ $toc_title = ezTOC_Option::get( 'heading_text' );
1040
+
1041
+ if ( strpos( $toc_title, '%PAGE_TITLE%' ) !== FALSE ) {
1042
+
1043
+ $toc_title = str_replace( '%PAGE_TITLE%', get_the_title(), $toc_title );
1044
+ }
1045
+
1046
+ if ( strpos( $toc_title, '%PAGE_NAME%' ) !== FALSE ) {
1047
+
1048
+ $toc_title = str_replace( '%PAGE_NAME%', get_the_title(), $toc_title );
1049
+ }
1050
+
1051
+ $html .= '<div class="ez-toc-title-container">' . PHP_EOL;
1052
+
1053
+ $html .= '<p class="ez-toc-title">' . esc_html( htmlentities( $toc_title, ENT_COMPAT, 'UTF-8' ) ). '</p>' . PHP_EOL;
1054
+
1055
+ $html .= '<span class="ez-toc-title-toggle">';
1056
+
1057
+ if ( ezTOC_Option::get( 'visibility' ) ) {
1058
+
1059
+ $html .= '<a class="ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle"><i class="ez-toc-glyphicon ez-toc-icon-toggle"></i></a>';
1060
+ }
1061
+
1062
+ $html .= '</span>';
1063
+
1064
+ $html .= '</div>' . PHP_EOL;
1065
+ }
1066
+
1067
+ ob_start();
1068
+ do_action( 'ez_toc_before' );
1069
+ $html .= ob_get_clean();
1070
+
1071
+ $html .= '<nav><ul class="ez-toc-list">' . $items . '</ul></nav>';
1072
+
1073
+ ob_start();
1074
+ do_action( 'ez_toc_after' );
1075
+ $html .= ob_get_clean();
1076
+
1077
+ $html .= '</div>' . PHP_EOL;
1078
+
1079
+ // Enqueue the script.
1080
+ wp_enqueue_script( 'ez-toc-js' );
1081
  }
1082
 
1083
+ return array( 'find' => $find, 'replace' => $replace, 'content' => $html );
1084
  }
1085
 
1086
  /**
1090
  *
1091
  * @access private
1092
  * @since 1.3
1093
+ * @static
1094
  *
1095
  * @param array|string $atts Shortcode attributes array or empty string.
1096
  * @param string $content The enclosed content (if the shortcode is used in its enclosing form)
1097
  * @param string $tag Shortcode name.
1098
  *
1099
+ * @return mixed
1100
  */
1101
  public static function shortcode( $atts, $content, $tag ) {
1102
 
1103
+ static $run = TRUE;
1104
+ $out = '';
1105
 
1106
  if ( $run ) {
1107
 
1108
+ $args = self::build( get_post( get_the_ID() ) );
1109
+ $out = $args['content'];
1110
+ $run = FALSE;
 
 
 
 
1111
  }
1112
 
1113
+ return $out;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1114
  }
1115
 
1116
  /**
1129
  */
1130
  public static function the_content( $content ) {
1131
 
1132
+ // bail if feed, search or archive
1133
+ if ( is_feed() || is_search() || is_archive() ) {
1134
  return $content;
1135
  }
1136
 
1137
  // bail if post not eligible and widget is not active
1138
+ $is_eligible = self::is_eligible();
1139
 
1140
  if ( ! $is_eligible && ! is_active_widget( false, false, 'ezw_tco' ) ) {
1141
 
1142
  return $content;
1143
  }
1144
 
1145
+ /*
1146
+ * get_post() does not return post_content filtered via `the_content` filter, which is good otherwise this
1147
+ * might cause an infinite loop.
1148
+ *
1149
+ * Since the ezTOC `the_content` filter is added at priority 100, it should run last in most situations
1150
+ * and already be filtered by other plugins/themes which ezTOC should take into account when building the
1151
+ * TOC. So, take the post content past via `the_content` filter callback and replace the post_content with
1152
+ * it before building the TOC.
1153
+ */
1154
+ $post = get_post( get_the_ID() );
1155
+ $post->post_content = $content;
1156
 
1157
+ // build toc
1158
+ $args = self::build( $post );
1159
+ $find = $args['find'];
1160
+ $replace = $args['replace'];
1161
+ $html = $args['content'];
1162
 
1163
  // bail if no headings found
1164
+ if ( empty( $find ) ) {
1165
 
1166
  return $content;
1167
  }
1168
 
 
 
 
 
1169
  // if shortcode used or post not eligible, return content with anchored headings
1170
  if ( strpos( $content, 'ez-toc-container' ) || ! $is_eligible ) {
1171
 
1172
+ return self::mb_find_replace( $find, $replace, $content );
1173
  }
1174
 
1175
  // else also add toc to content
1176
  switch ( ezTOC_Option::get( 'position' ) ) {
1177
 
1178
  case 'top':
1179
+ $content = $html . self::mb_find_replace( $find, $replace, $content );
1180
  break;
1181
 
1182
  case 'bottom':
1183
+ $content = self::mb_find_replace( $find, $replace, $content ) . $html;
1184
  break;
1185
 
1186
  case 'after':
1187
  $replace[0] = $replace[0] . $html;
1188
+ $content = self::mb_find_replace( $find, $replace, $content );
1189
  break;
1190
 
1191
  case 'before':
1192
  default:
1193
  $replace[0] = $html . $replace[0];
1194
+ $content = self::mb_find_replace( $find, $replace, $content );
1195
  }
1196
 
1197
  return $content;
1219
  // Start Easy Table of Contents.
1220
  add_action( 'plugins_loaded', 'ezTOC' );
1221
  }
1222
+
1223
+
1224
+ /**
1225
+ * Returns a HTML formatted string of the table of contents without the surrounding UL or OL
1226
+ * tags to enable the theme editor to supply their own ID and/or classes to the outer list.
1227
+ *
1228
+ * There are three optional parameters you can feed this function with:
1229
+ *
1230
+ * - $content is the entire content with headings. If blank, will default to the current $post
1231
+ *
1232
+ * - $link is the URL to prefix the anchor with. If provided a string, will use it as the prefix.
1233
+ * If set to true then will try to obtain the permalink from the $post object.
1234
+ *
1235
+ * - $apply_eligibility bool, defaults to false. When set to true, will apply the check to
1236
+ * see if bit of content has the prerequisites needed for a TOC, eg minimum number of headings
1237
+ * enabled post type, etc.
1238
+ */
1239
+ //function toc_get_index( $content = '', $prefix_url = '', $apply_eligibility = FALSE ) {
1240
+ //
1241
+ // global $wp_query, $tic;
1242
+ //
1243
+ // $return = '';
1244
+ // $find = $replace = array();
1245
+ // $proceed = TRUE;
1246
+ //
1247
+ // if ( ! $content ) {
1248
+ // $post = get_post( $wp_query->post->ID );
1249
+ // $content = wptexturize( $post->post_content );
1250
+ // }
1251
+ //
1252
+ // if ( $apply_eligibility ) {
1253
+ // if ( ! $tic->is_eligible() ) {
1254
+ // $proceed = FALSE;
1255
+ // }
1256
+ // } else {
1257
+ // $tic->set_option( array( 'start' => 0 ) );
1258
+ // }
1259
+ //
1260
+ // if ( $proceed ) {
1261
+ // $return = $tic->extract_headings( $find, $replace, $content );
1262
+ // if ( $prefix_url ) {
1263
+ // $return = str_replace( 'href="#', 'href="' . $prefix_url . '#', $return );
1264
+ // }
1265
+ // }
1266
+ //
1267
+ // return $return;
1268
+ //}
includes/class.admin.php CHANGED
@@ -72,7 +72,7 @@ if ( ! class_exists( 'ezTOC_Admin' ) ) {
72
  */
73
  public function registerScripts() {
74
 
75
- wp_register_script( 'cn_toc_admin_script', EZ_TOC_URL . 'assets/js/admin.js', array( 'jquery', 'wp-color-picker' ), ezTOC::VERSION, true );
76
  wp_register_style( 'cn_toc_admin_style', EZ_TOC_URL . 'assets/css/admin.css', array( 'wp-color-picker' ), ezTOC::VERSION );
77
  }
78
 
@@ -160,11 +160,11 @@ if ( ! class_exists( 'ezTOC_Admin' ) ) {
160
  // Add an nonce field so we can check for it on save.
161
  wp_nonce_field( 'ez_toc_save', '_ez_toc_nonce' );
162
 
163
- $suppress = get_post_meta( $post->ID, '_ez-toc-disabled', true ) == 1 ? true : false;
164
- $insert = get_post_meta( $post->ID, '_ez-toc-insert', true ) == 1 ? true : false;
165
- $headings = get_post_meta( $post->ID, '_ez-toc-heading-levels', true );
166
- $exclude = get_post_meta( $post->ID, '_ez-toc-exclude', true );
167
- $altText = get_post_meta( $post->ID, '_ez-toc-alttext', true );
168
 
169
  if ( ! is_array( $headings ) ) {
170
 
@@ -345,21 +345,21 @@ if ( ! class_exists( 'ezTOC_Admin' ) ) {
345
  // Checkboxes are present if checked, absent if not.
346
  if ( isset( $_REQUEST['ez-toc-settings']['disabled-toc'] ) ) {
347
 
348
- update_post_meta( $post_id, '_ez-toc-disabled', true );
349
 
350
  } else {
351
 
352
- update_post_meta( $post_id, '_ez-toc-disabled', false );
353
 
354
  }
355
 
356
  if ( isset( $_REQUEST['ez-toc-settings']['insert-toc'] ) ) {
357
 
358
- update_post_meta( $post_id, '_ez-toc-insert', true );
359
 
360
  } else {
361
 
362
- update_post_meta( $post_id, '_ez-toc-insert', false );
363
  }
364
 
365
  if ( isset( $_REQUEST['ez-toc-settings']['heading-levels'] ) && ! empty( $_REQUEST['ez-toc-settings']['heading-levels'] ) ) {
@@ -384,21 +384,14 @@ if ( ! class_exists( 'ezTOC_Admin' ) ) {
384
 
385
  if ( is_string( $_REQUEST['ez-toc-settings']['alttext'] ) ) {
386
 
387
- $alttext = trim( $_REQUEST['ez-toc-settings']['alttext'] );
388
 
389
  } else {
390
 
391
  $alttext = '';
392
  }
393
 
394
- /*
395
- * This is basically `esc_html()` but does not encode quotes.
396
- * This is to allow angle brackets and such which `wp_kses_post` would strip as "evil" scripts.
397
- */
398
- $alttext = wp_check_invalid_utf8( $alttext );
399
- $alttext = _wp_specialchars( $alttext, ENT_NOQUOTES );
400
-
401
- update_post_meta( $post_id, '_ez-toc-alttext', wp_kses_post( $alttext ) );
402
 
403
  } else {
404
 
@@ -409,7 +402,7 @@ if ( ! class_exists( 'ezTOC_Admin' ) ) {
409
 
410
  if ( is_string( $_REQUEST['ez-toc-settings']['exclude'] ) ) {
411
 
412
- $exclude = trim( $_REQUEST['ez-toc-settings']['exclude'] );
413
 
414
  } else {
415
 
72
  */
73
  public function registerScripts() {
74
 
75
+ wp_register_script( 'cn_toc_admin_script', EZ_TOC_URL . 'assets/js/admin.js', array( 'jquery', 'wp-color-picker' ), ezTOC::VERSION, TRUE );
76
  wp_register_style( 'cn_toc_admin_style', EZ_TOC_URL . 'assets/css/admin.css', array( 'wp-color-picker' ), ezTOC::VERSION );
77
  }
78
 
160
  // Add an nonce field so we can check for it on save.
161
  wp_nonce_field( 'ez_toc_save', '_ez_toc_nonce' );
162
 
163
+ $suppress = get_post_meta( $post->ID, '_ez-toc-disabled', TRUE ) == 1 ? TRUE : FALSE;
164
+ $insert = get_post_meta( $post->ID, '_ez-toc-insert', TRUE ) == 1 ? TRUE : FALSE;
165
+ $headings = get_post_meta( $post->ID, '_ez-toc-heading-levels', TRUE );
166
+ $exclude = get_post_meta( $post->ID, '_ez-toc-exclude', TRUE );
167
+ $altText = get_post_meta( $post->ID, '_ez-toc-alttext', TRUE );
168
 
169
  if ( ! is_array( $headings ) ) {
170
 
345
  // Checkboxes are present if checked, absent if not.
346
  if ( isset( $_REQUEST['ez-toc-settings']['disabled-toc'] ) ) {
347
 
348
+ update_post_meta( $post_id, '_ez-toc-disabled', TRUE );
349
 
350
  } else {
351
 
352
+ update_post_meta( $post_id, '_ez-toc-disabled', FALSE );
353
 
354
  }
355
 
356
  if ( isset( $_REQUEST['ez-toc-settings']['insert-toc'] ) ) {
357
 
358
+ update_post_meta( $post_id, '_ez-toc-insert', TRUE );
359
 
360
  } else {
361
 
362
+ update_post_meta( $post_id, '_ez-toc-insert', FALSE );
363
  }
364
 
365
  if ( isset( $_REQUEST['ez-toc-settings']['heading-levels'] ) && ! empty( $_REQUEST['ez-toc-settings']['heading-levels'] ) ) {
384
 
385
  if ( is_string( $_REQUEST['ez-toc-settings']['alttext'] ) ) {
386
 
387
+ $alttext = wp_unslash( trim( $_REQUEST['ez-toc-settings']['alttext'] ) );
388
 
389
  } else {
390
 
391
  $alttext = '';
392
  }
393
 
394
+ update_post_meta( $post_id, '_ez-toc-alttext', wp_kses_data( $alttext ) );
 
 
 
 
 
 
 
395
 
396
  } else {
397
 
402
 
403
  if ( is_string( $_REQUEST['ez-toc-settings']['exclude'] ) ) {
404
 
405
+ $exclude = wp_unslash( trim( $_REQUEST['ez-toc-settings']['exclude'] ) );
406
 
407
  } else {
408
 
includes/class.options.php CHANGED
@@ -21,7 +21,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
21
  */
22
  public static function register() {
23
 
24
- if ( false === get_option( 'ez-toc-settings' ) ) {
25
 
26
  add_option( 'ez-toc-settings', self::getDefaults() );
27
  }
@@ -47,20 +47,20 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
47
  'ez_toc_settings_' . $section,
48
  array(
49
  'section' => $section,
50
- 'id' => isset( $option['id'] ) ? $option['id'] : null,
51
  'desc' => ! empty( $option['desc'] ) ? $option['desc'] : '',
52
- 'name' => isset( $option['name'] ) ? $option['name'] : null,
53
- 'size' => isset( $option['size'] ) ? $option['size'] : null,
54
  'options' => isset( $option['options'] ) ? $option['options'] : '',
55
  'default' => isset( $option['default'] ) ? $option['default'] : '',
56
- 'min' => isset( $option['min'] ) ? $option['min'] : null,
57
- 'max' => isset( $option['max'] ) ? $option['max'] : null,
58
- 'step' => isset( $option['step'] ) ? $option['step'] : null,
59
- 'chosen' => isset( $option['chosen'] ) ? $option['chosen'] : null,
60
- 'placeholder' => isset( $option['placeholder'] ) ? $option['placeholder'] : null,
61
- 'allow_blank' => isset( $option['allow_blank'] ) ? $option['allow_blank'] : true,
62
- 'readonly' => isset( $option['readonly'] ) ? $option['readonly'] : false,
63
- 'faux' => isset( $option['faux'] ) ? $option['faux'] : false,
64
  )
65
  );
66
  }
@@ -102,7 +102,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
102
  foreach ( $input as $key => $value ) {
103
 
104
  // Get the setting type (checkbox, select, etc)
105
- $type = isset( $registered[ $sectionID ][ $key ]['type'] ) ? $registered[ $sectionID ][ $key ]['type'] : false;
106
 
107
  if ( $type ) {
108
 
@@ -202,7 +202,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
202
  'name' => __( 'Display Header Label', 'easy-table-of-contents' ),
203
  'desc' => __( 'Show header text above the table of contents.', 'easy-table-of-contents' ),
204
  'type' => 'checkbox',
205
- 'default' => true,
206
  ),
207
  'heading_text' => array(
208
  'id' => 'heading_text',
@@ -216,7 +216,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
216
  'name' => __( 'Toggle View', 'easy-table-of-contents' ),
217
  'desc' => __( 'Allow the user to toggle the visibility of the table of contents.', 'easy-table-of-contents' ),
218
  'type' => 'checkbox',
219
- 'default' => true,
220
  ),
221
  //'visibility_show' => array(
222
  // 'id' => 'visibility_show',
@@ -237,14 +237,14 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
237
  'name' => __( 'Initial View', 'easy-table-of-contents' ),
238
  'desc' => __( 'Initially hide the table of contents.', 'easy-table-of-contents' ),
239
  'type' => 'checkbox',
240
- 'default' => false,
241
  ),
242
  'show_hierarchy' => array(
243
  'id' => 'show_hierarchy',
244
  'name' => __( 'Show as Hierarchy', 'easy-table-of-contents' ),
245
  'desc' => '',
246
  'type' => 'checkbox',
247
- 'default' => true,
248
  ),
249
  'counter' => array(
250
  'id' => 'counter',
@@ -264,7 +264,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
264
  'name' => __( 'Smooth Scroll', 'easy-table-of-contents' ),
265
  'desc' => '',
266
  'type' => 'checkbox',
267
- 'default' => true,
268
  ),
269
  )
270
  ),
@@ -436,35 +436,35 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
436
  'name' => __( 'Lowercase', 'easy-table-of-contents' ),
437
  'desc' => __( 'Ensure anchors are in lowercase.', 'easy-table-of-contents' ),
438
  'type' => 'checkbox',
439
- 'default' => false,
440
  ),
441
  'hyphenate' => array(
442
  'id' => 'hyphenate',
443
  'name' => __( 'Hyphenate', 'easy-table-of-contents' ),
444
  'desc' => __( 'Use - rather than _ in anchors.', 'easy-table-of-contents' ),
445
  'type' => 'checkbox',
446
- 'default' => false,
447
  ),
448
  'include_homepage' => array(
449
  'id' => 'include_homepage',
450
  'name' => __( 'Homepage', 'easy-table-of-contents' ),
451
  'desc' => __( 'Show the table of contents for qualifying items on the homepage.', 'easy-table-of-contents' ),
452
  'type' => 'checkbox',
453
- 'default' => false,
454
  ),
455
  'exclude_css' => array(
456
  'id' => 'exclude_css',
457
  'name' => __( 'CSS', 'easy-table-of-contents' ),
458
  'desc' => __( "Prevent the loading the core CSS styles. When selected, the appearance options from above will be ignored.", 'easy-table-of-contents' ),
459
  'type' => 'checkbox',
460
- 'default' => false,
461
  ),
462
  //'bullet_spacing' => array(
463
  // 'id' => 'bullet_spacing',
464
  // 'name' => __( 'Theme Bullets', 'easy-table-of-contents' ),
465
  // 'desc' => __( 'If your theme includes background images for unordered list elements, enable this option to support them.', 'easy-table-of-contents' ),
466
  // 'type' => 'checkbox',
467
- // 'default' => false,
468
  //),
469
  'heading_levels' => array(
470
  'id' => 'heading_levels',
@@ -564,19 +564,19 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
564
  'fragment_prefix' => 'i',
565
  'position' => 'before',
566
  'start' => 4,
567
- 'show_heading_text' => true,
568
  'heading_text' => 'Table of Contents',
569
  'enabled_post_types' => array( 'page' ),
570
  'auto_insert_post_types' => array(),
571
- 'show_hierarchy' => true,
572
  'counter' => 'decimal',
573
- 'smooth_scroll' => true,
574
  'smooth_scroll_offset' => 30,
575
- 'mobile_smooth_scroll_offset' => 0,
576
- 'visibility' => true,
577
  //'visibility_show' => 'show',
578
  //'visibility_hide' => 'hide',
579
- 'visibility_hide_by_default' => false,
580
  'width' => 'auto',
581
  'width_custom' => 275,
582
  'width_custom_units' => 'px',
@@ -593,16 +593,16 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
593
  'custom_link_colour' => '#428bca',
594
  'custom_link_hover_colour' => '#2a6496',
595
  'custom_link_visited_colour' => '#428bca',
596
- 'lowercase' => false,
597
- 'hyphenate' => false,
598
- //'bullet_spacing' => false,
599
- 'include_homepage' => false,
600
- 'exclude_css' => false,
601
  'exclude' => '',
602
  'heading_levels' => array( '1', '2', '3', '4', '5', '6' ),
603
  'restrict_path' => '',
604
  'css_container_class' => '',
605
- //'show_toc_in_widget_only' => false,
606
  //'show_toc_in_widget_only_post_types' => array(),
607
  'widget_affix_selector' => '',
608
  );
@@ -636,11 +636,11 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
636
  * @static
637
  *
638
  * @param string $key
639
- * @param bool|false $default
640
  *
641
  * @return mixed
642
  */
643
- public static function get( $key, $default = false ) {
644
 
645
  $options = self::getOptions();
646
 
@@ -658,11 +658,11 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
658
  * @static
659
  *
660
  * @param string $key
661
- * @param bool|false $value
662
  *
663
  * @return bool
664
  */
665
- public static function set( $key, $value = false ) {
666
 
667
  if ( empty( $value ) ) {
668
 
@@ -807,25 +807,25 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
807
  * @param array $args Arguments passed by the setting
808
  * @param null $value
809
  */
810
- public static function text( $args, $value = null ) {
811
 
812
  if ( is_null( $value ) ) {
813
 
814
  $value = self::get( $args['id'], $args['default'] );
815
  }
816
 
817
- if ( isset( $args['faux'] ) && true === $args['faux'] ) {
818
 
819
- $args['readonly'] = true;
820
  $value = isset( $args['default'] ) ? $args['default'] : '';
821
  $name = '';
822
 
823
  } else {
824
 
825
- $name = ' name="ez-toc-settings[' . $args['id'] . ']"';
826
  }
827
 
828
- $readonly = isset( $args['readonly'] ) && $args['readonly'] === true ? ' readonly="readonly"' : '';
829
  $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
830
 
831
  $html = '<input type="text" class="' . $size . '-text" id="ez-toc-settings[' . $args['id'] . ']"' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '"' . $readonly . '/>';
@@ -850,7 +850,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
850
  * @param array $args Arguments passed by the setting
851
  * @param null $value
852
  */
853
- public static function textarea( $args, $value = null ) {
854
 
855
  $html = '';
856
 
@@ -859,18 +859,18 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
859
  $value = self::get( $args['id'], $args['default'] );
860
  }
861
 
862
- if ( isset( $args['faux'] ) && true === $args['faux'] ) {
863
 
864
- $args['readonly'] = true;
865
  $value = isset( $args['default'] ) ? $args['default'] : '';
866
  $name = '';
867
 
868
  } else {
869
 
870
- $name = ' name="ez-toc-settings[' . $args['id'] . ']"';
871
  }
872
 
873
- $readonly = isset( $args['readonly'] ) && $args['readonly'] === true ? ' readonly="readonly"' : '';
874
  $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
875
 
876
  if ( 0 < strlen( $args['desc'] ) ) {
@@ -878,7 +878,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
878
  $html .= '<label for="ez-toc-settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
879
  }
880
 
881
- $html .= '<textarea rows="10" cols="50" class="' . $size . '-text" id="ez-toc-settings[' . $args['id'] . ']"' . $name . $readonly . '/>' . esc_textarea( $value ) . '</textarea>';
882
 
883
  echo $html;
884
  }
@@ -898,18 +898,18 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
898
 
899
  $value = self::get( $args['id'], $args['default'] );
900
 
901
- if ( isset( $args['faux'] ) && true === $args['faux'] ) {
902
 
903
- $args['readonly'] = true;
904
  $value = isset( $args['default'] ) ? $args['default'] : '';
905
  $name = '';
906
 
907
  } else {
908
 
909
- $name = ' name="ez-toc-settings[' . $args['id'] . ']"';
910
  }
911
 
912
- $readonly = isset( $args['readonly'] ) && $args['readonly'] === true ? ' readonly="readonly"' : '';
913
  $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
914
 
915
  $html = '<input type="number" class="' . $size . '-text" id="ez-toc-settings[' . $args['id'] . ']"' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '"' . $readonly . '/>';
@@ -934,23 +934,23 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
934
  * @param array $args Arguments passed by the setting
935
  * @param null $value
936
  */
937
- public static function checkbox( $args, $value = null ) {
938
 
939
  if ( is_null( $value ) ) {
940
 
941
  $value = self::get( $args['id'], $args['default'] );
942
  }
943
 
944
- if ( isset( $args['faux'] ) && true === $args['faux'] ) {
945
 
946
  $name = '';
947
 
948
  } else {
949
 
950
- $name = ' name="ez-toc-settings[' . $args['id'] . ']"';
951
  }
952
 
953
- $checked = $value ? checked( 1, $value, false ) : '';
954
 
955
  $html = '<input type="checkbox" id="ez-toc-settings[' . $args['id'] . ']"' . $name . ' value="1" ' . $checked . '/>';
956
 
@@ -974,7 +974,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
974
  * @param array $args Arguments passed by the setting
975
  * @param null $value
976
  */
977
- public static function checkboxgroup( $args, $value = null ) {
978
 
979
  if ( is_null( $value ) ) {
980
 
@@ -991,10 +991,10 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
991
 
992
  } else {
993
 
994
- $enabled = null;
995
  }
996
 
997
- echo '<input name="ez-toc-settings[' . $args['id'] . '][' . $key . ']" id="ez-toc-settings[' . $args['id'] . '][' . $key . ']" type="checkbox" value="' . $key . '" ' . checked( $option, $enabled, false ) . '/>&nbsp;';
998
  echo '<label for="ez-toc-settings[' . $args['id'] . '][' . $key . ']">' . $option . '</label><br/>';
999
 
1000
  endforeach;
@@ -1023,7 +1023,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
1023
 
1024
  foreach ( $args['options'] as $key => $option ) {
1025
 
1026
- echo '<input name="ez-toc-settings[' . $args['id'] . ']"" id="ez-toc-settings[' . $args['id'] . '][' . $key . ']" type="radio" value="' . $key . '" ' . checked( $key, $value, false ) . '/>&nbsp;';
1027
  echo '<label for="ez-toc-settings[' . $args['id'] . '][' . $key . ']">' . $option . '</label><br/>';
1028
  }
1029
 
@@ -1063,7 +1063,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
1063
  $html = '<select id="ez-toc-settings[' . $args['id'] . ']" name="ez-toc-settings[' . $args['id'] . ']" ' . $chosen . 'data-placeholder="' . $placeholder . '" />';
1064
 
1065
  foreach ( $args['options'] as $option => $name ) {
1066
- $selected = selected( $option, $value, false );
1067
  $html .= '<option value="' . $option . '" ' . $selected . '>' . $name . '</option>';
1068
  }
1069
 
@@ -1112,7 +1112,7 @@ if ( ! class_exists( 'ezTOC_Option' ) ) {
1112
 
1113
  foreach ( $group['options'] as $option => $name ) {
1114
 
1115
- $selected = selected( $option, $value, false );
1116
  $html .= '<option value="' . $option . '" ' . $selected . '>' . $name . '</option>';
1117
  }
1118
 
21
  */
22
  public static function register() {
23
 
24
+ if ( FALSE === get_option( 'ez-toc-settings' ) ) {
25
 
26
  add_option( 'ez-toc-settings', self::getDefaults() );
27
  }
47
  'ez_toc_settings_' . $section,
48
  array(
49
  'section' => $section,
50
+ 'id' => isset( $option['id'] ) ? $option['id'] : NULL,
51
  'desc' => ! empty( $option['desc'] ) ? $option['desc'] : '',
52
+ 'name' => isset( $option['name'] ) ? $option['name'] : NULL,
53
+ 'size' => isset( $option['size'] ) ? $option['size'] : NULL,
54
  'options' => isset( $option['options'] ) ? $option['options'] : '',
55
  'default' => isset( $option['default'] ) ? $option['default'] : '',
56
+ 'min' => isset( $option['min'] ) ? $option['min'] : NULL,
57
+ 'max' => isset( $option['max'] ) ? $option['max'] : NULL,
58
+ 'step' => isset( $option['step'] ) ? $option['step'] : NULL,
59
+ 'chosen' => isset( $option['chosen'] ) ? $option['chosen'] : NULL,
60
+ 'placeholder' => isset( $option['placeholder'] ) ? $option['placeholder'] : NULL,
61
+ 'allow_blank' => isset( $option['allow_blank'] ) ? $option['allow_blank'] : TRUE,
62
+ 'readonly' => isset( $option['readonly'] ) ? $option['readonly'] : FALSE,
63
+ 'faux' => isset( $option['faux'] ) ? $option['faux'] : FALSE,
64
  )
65
  );
66
  }
102
  foreach ( $input as $key => $value ) {
103
 
104
  // Get the setting type (checkbox, select, etc)
105
+ $type = isset( $registered[ $sectionID ][ $key ]['type'] ) ? $registered[ $sectionID ][ $key ]['type'] : FALSE;
106
 
107
  if ( $type ) {
108
 
202
  'name' => __( 'Display Header Label', 'easy-table-of-contents' ),
203
  'desc' => __( 'Show header text above the table of contents.', 'easy-table-of-contents' ),
204
  'type' => 'checkbox',
205
+ 'default' => TRUE,
206
  ),
207
  'heading_text' => array(
208
  'id' => 'heading_text',
216
  'name' => __( 'Toggle View', 'easy-table-of-contents' ),
217
  'desc' => __( 'Allow the user to toggle the visibility of the table of contents.', 'easy-table-of-contents' ),
218
  'type' => 'checkbox',
219
+ 'default' => TRUE,
220
  ),
221
  //'visibility_show' => array(
222
  // 'id' => 'visibility_show',
237
  'name' => __( 'Initial View', 'easy-table-of-contents' ),
238
  'desc' => __( 'Initially hide the table of contents.', 'easy-table-of-contents' ),
239
  'type' => 'checkbox',
240
+ 'default' => FALSE,
241
  ),
242
  'show_hierarchy' => array(
243
  'id' => 'show_hierarchy',
244
  'name' => __( 'Show as Hierarchy', 'easy-table-of-contents' ),
245
  'desc' => '',
246
  'type' => 'checkbox',
247
+ 'default' => TRUE,
248
  ),
249
  'counter' => array(
250
  'id' => 'counter',
264
  'name' => __( 'Smooth Scroll', 'easy-table-of-contents' ),
265
  'desc' => '',
266
  'type' => 'checkbox',
267
+ 'default' => TRUE,
268
  ),
269
  )
270
  ),
436
  'name' => __( 'Lowercase', 'easy-table-of-contents' ),
437
  'desc' => __( 'Ensure anchors are in lowercase.', 'easy-table-of-contents' ),
438
  'type' => 'checkbox',
439
+ 'default' => FALSE,
440
  ),
441
  'hyphenate' => array(
442
  'id' => 'hyphenate',
443
  'name' => __( 'Hyphenate', 'easy-table-of-contents' ),
444
  'desc' => __( 'Use - rather than _ in anchors.', 'easy-table-of-contents' ),
445
  'type' => 'checkbox',
446
+ 'default' => FALSE,
447
  ),
448
  'include_homepage' => array(
449
  'id' => 'include_homepage',
450
  'name' => __( 'Homepage', 'easy-table-of-contents' ),
451
  'desc' => __( 'Show the table of contents for qualifying items on the homepage.', 'easy-table-of-contents' ),
452
  'type' => 'checkbox',
453
+ 'default' => FALSE,
454
  ),
455
  'exclude_css' => array(
456
  'id' => 'exclude_css',
457
  'name' => __( 'CSS', 'easy-table-of-contents' ),
458
  'desc' => __( "Prevent the loading the core CSS styles. When selected, the appearance options from above will be ignored.", 'easy-table-of-contents' ),
459
  'type' => 'checkbox',
460
+ 'default' => FALSE,
461
  ),
462
  //'bullet_spacing' => array(
463
  // 'id' => 'bullet_spacing',
464
  // 'name' => __( 'Theme Bullets', 'easy-table-of-contents' ),
465
  // 'desc' => __( 'If your theme includes background images for unordered list elements, enable this option to support them.', 'easy-table-of-contents' ),
466
  // 'type' => 'checkbox',
467
+ // 'default' => FALSE,
468
  //),
469
  'heading_levels' => array(
470
  'id' => 'heading_levels',
564
  'fragment_prefix' => 'i',
565
  'position' => 'before',
566
  'start' => 4,
567
+ 'show_heading_text' => TRUE,
568
  'heading_text' => 'Table of Contents',
569
  'enabled_post_types' => array( 'page' ),
570
  'auto_insert_post_types' => array(),
571
+ 'show_hierarchy' => TRUE,
572
  'counter' => 'decimal',
573
+ 'smooth_scroll' => TRUE,
574
  'smooth_scroll_offset' => 30,
575
+ 'moile_smooth_scroll_offset' => 0,
576
+ 'visibility' => TRUE,
577
  //'visibility_show' => 'show',
578
  //'visibility_hide' => 'hide',
579
+ 'visibility_hide_by_default' => FALSE,
580
  'width' => 'auto',
581
  'width_custom' => 275,
582
  'width_custom_units' => 'px',
593
  'custom_link_colour' => '#428bca',
594
  'custom_link_hover_colour' => '#2a6496',
595
  'custom_link_visited_colour' => '#428bca',
596
+ 'lowercase' => FALSE,
597
+ 'hyphenate' => FALSE,
598
+ //'bullet_spacing' => FALSE,
599
+ 'include_homepage' => FALSE,
600
+ 'exclude_css' => FALSE,
601
  'exclude' => '',
602
  'heading_levels' => array( '1', '2', '3', '4', '5', '6' ),
603
  'restrict_path' => '',
604
  'css_container_class' => '',
605
+ //'show_toc_in_widget_only' => FALSE,
606
  //'show_toc_in_widget_only_post_types' => array(),
607
  'widget_affix_selector' => '',
608
  );
636
  * @static
637
  *
638
  * @param string $key
639
+ * @param bool|FALSE $default
640
  *
641
  * @return mixed
642
  */
643
+ public static function get( $key, $default = FALSE ) {
644
 
645
  $options = self::getOptions();
646
 
658
  * @static
659
  *
660
  * @param string $key
661
+ * @param bool|FALSE $value
662
  *
663
  * @return bool
664
  */
665
+ public static function set( $key, $value = FALSE ) {
666
 
667
  if ( empty( $value ) ) {
668
 
807
  * @param array $args Arguments passed by the setting
808
  * @param null $value
809
  */
810
+ public static function text( $args, $value = NULL ) {
811
 
812
  if ( is_null( $value ) ) {
813
 
814
  $value = self::get( $args['id'], $args['default'] );
815
  }
816
 
817
+ if ( isset( $args['faux'] ) && TRUE === $args['faux'] ) {
818
 
819
+ $args['readonly'] = TRUE;
820
  $value = isset( $args['default'] ) ? $args['default'] : '';
821
  $name = '';
822
 
823
  } else {
824
 
825
+ $name = 'name="ez-toc-settings[' . $args['id'] . ']"';
826
  }
827
 
828
+ $readonly = isset( $args['readonly'] ) && $args['readonly'] === TRUE ? ' readonly="readonly"' : '';
829
  $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
830
 
831
  $html = '<input type="text" class="' . $size . '-text" id="ez-toc-settings[' . $args['id'] . ']"' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '"' . $readonly . '/>';
850
  * @param array $args Arguments passed by the setting
851
  * @param null $value
852
  */
853
+ public static function textarea( $args, $value = NULL ) {
854
 
855
  $html = '';
856
 
859
  $value = self::get( $args['id'], $args['default'] );
860
  }
861
 
862
+ if ( isset( $args['faux'] ) && TRUE === $args['faux'] ) {
863
 
864
+ $args['readonly'] = TRUE;
865
  $value = isset( $args['default'] ) ? $args['default'] : '';
866
  $name = '';
867
 
868
  } else {
869
 
870
+ $name = 'name="ez-toc-settings[' . $args['id'] . ']"';
871
  }
872
 
873
+ $readonly = isset( $args['readonly'] ) && $args['readonly'] === TRUE ? ' readonly="readonly"' : '';
874
  $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
875
 
876
  if ( 0 < strlen( $args['desc'] ) ) {
878
  $html .= '<label for="ez-toc-settings[' . $args['id'] . ']"> ' . $args['desc'] . '</label>';
879
  }
880
 
881
+ $html .= '<textarea rows="10" cols="50" class="' . $size . '-text" id="ez-toc-settings[' . $args['id'] . ']"' . $name . $readonly . '/>' . esc_textarea( stripslashes( $value ) ) . '</textarea>';
882
 
883
  echo $html;
884
  }
898
 
899
  $value = self::get( $args['id'], $args['default'] );
900
 
901
+ if ( isset( $args['faux'] ) && TRUE === $args['faux'] ) {
902
 
903
+ $args['readonly'] = TRUE;
904
  $value = isset( $args['default'] ) ? $args['default'] : '';
905
  $name = '';
906
 
907
  } else {
908
 
909
+ $name = 'name="ez-toc-settings[' . $args['id'] . ']"';
910
  }
911
 
912
+ $readonly = isset( $args['readonly'] ) && $args['readonly'] === TRUE ? ' readonly="readonly"' : '';
913
  $size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
914
 
915
  $html = '<input type="number" class="' . $size . '-text" id="ez-toc-settings[' . $args['id'] . ']"' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '"' . $readonly . '/>';
934
  * @param array $args Arguments passed by the setting
935
  * @param null $value
936
  */
937
+ public static function checkbox( $args, $value = NULL ) {
938
 
939
  if ( is_null( $value ) ) {
940
 
941
  $value = self::get( $args['id'], $args['default'] );
942
  }
943
 
944
+ if ( isset( $args['faux'] ) && TRUE === $args['faux'] ) {
945
 
946
  $name = '';
947
 
948
  } else {
949
 
950
+ $name = 'name="ez-toc-settings[' . $args['id'] . ']"';
951
  }
952
 
953
+ $checked = $value ? checked( 1, $value, FALSE ) : '';
954
 
955
  $html = '<input type="checkbox" id="ez-toc-settings[' . $args['id'] . ']"' . $name . ' value="1" ' . $checked . '/>';
956
 
974
  * @param array $args Arguments passed by the setting
975
  * @param null $value
976
  */
977
+ public static function checkboxgroup( $args, $value = NULL ) {
978
 
979
  if ( is_null( $value ) ) {
980
 
991
 
992
  } else {
993
 
994
+ $enabled = NULL;
995
  }
996
 
997
+ echo '<input name="ez-toc-settings[' . $args['id'] . '][' . $key . ']" id="ez-toc-settings[' . $args['id'] . '][' . $key . ']" type="checkbox" value="' . $key . '" ' . checked( $option, $enabled, FALSE ) . '/>&nbsp;';
998
  echo '<label for="ez-toc-settings[' . $args['id'] . '][' . $key . ']">' . $option . '</label><br/>';
999
 
1000
  endforeach;
1023
 
1024
  foreach ( $args['options'] as $key => $option ) {
1025
 
1026
+ echo '<input name="ez-toc-settings[' . $args['id'] . ']"" id="ez-toc-settings[' . $args['id'] . '][' . $key . ']" type="radio" value="' . $key . '" ' . checked( $key, $value, FALSE ) . '/>&nbsp;';
1027
  echo '<label for="ez-toc-settings[' . $args['id'] . '][' . $key . ']">' . $option . '</label><br/>';
1028
  }
1029
 
1063
  $html = '<select id="ez-toc-settings[' . $args['id'] . ']" name="ez-toc-settings[' . $args['id'] . ']" ' . $chosen . 'data-placeholder="' . $placeholder . '" />';
1064
 
1065
  foreach ( $args['options'] as $option => $name ) {
1066
+ $selected = selected( $option, $value, FALSE );
1067
  $html .= '<option value="' . $option . '" ' . $selected . '>' . $name . '</option>';
1068
  }
1069
 
1112
 
1113
  foreach ( $group['options'] as $option => $name ) {
1114
 
1115
+ $selected = selected( $option, $value, FALSE );
1116
  $html .= '<option value="' . $option . '" ' . $selected . '>' . $name . '</option>';
1117
  }
1118
 
includes/class.post.php DELETED
@@ -1,1185 +0,0 @@
1
- <?php
2
-
3
- class ezTOC_Post {
4
-
5
- /**
6
- * @since 2.0
7
- * @var int
8
- */
9
- private $queriedObjectID;
10
-
11
- /**
12
- * @since 2.0
13
- * @var WP_Post
14
- */
15
- private $post;
16
-
17
- /**
18
- * @since 2.0
19
- * @var false|string
20
- */
21
- private $permalink;
22
-
23
- /**
24
- * The post content broken into pages by user inserting `<!--nextpage-->` into the post content.
25
- * @see ezTOC_Post::extractPages()
26
- * @since 2.0
27
- * @var array
28
- */
29
- private $pages = array();
30
-
31
- /**
32
- * The user defined heading levels to be included in the TOC.
33
- * @see ezTOC_Post::getHeadingLevels()
34
- * @since 2.0
35
- * @var array
36
- */
37
- private $headingLevels = array();
38
-
39
- /**
40
- * Keeps a track of used anchors for collision detecting.
41
- * @see ezTOC_Post::generateHeadingIDFromTitle()
42
- * @since 2.0
43
- * @var array
44
- */
45
- private $collision_collector = array();
46
-
47
- /**
48
- * @var bool
49
- */
50
- private $hasTOCItems = false;
51
-
52
- /**
53
- * ezTOC_Post constructor.
54
- *
55
- * @since 2.0
56
- *
57
- * @param WP_Post $post
58
- * @param bool $apply_content_filter Whether or not to apply the `the_content` filter on the post content.
59
- */
60
- public function __construct( WP_Post $post, $apply_content_filter = true ) {
61
-
62
- $this->post = $post;
63
- $this->permalink = get_permalink( $post );
64
- $this->queriedObjectID = get_queried_object_id();
65
-
66
- if ( $apply_content_filter ) {
67
-
68
- $this->applyContentFilter()->process();
69
-
70
- } else {
71
-
72
- $this->process();
73
- }
74
- }
75
-
76
- /**
77
- * @access public
78
- * @since 2.0
79
- *
80
- * @param $id
81
- *
82
- * @return ezTOC_Post|null
83
- */
84
- public static function get( $id ) {
85
-
86
- $post = get_post( $id );
87
-
88
- if ( ! $post instanceof WP_Post ) {
89
-
90
- return null;
91
- }
92
-
93
- return new static( $post );
94
- }
95
-
96
- /**
97
- * Process post content for headings.
98
- *
99
- * This must be run after object init or after @see ezTOC_Post::applyContentFilter().
100
- *
101
- * @since 2.0
102
- *
103
- * @return static
104
- */
105
- private function process() {
106
-
107
- $this->processPages();
108
-
109
- return $this;
110
- }
111
-
112
- /**
113
- * Apply `the_content` filter to the post content.
114
- *
115
- * @since 2.0
116
- *
117
- * @return static
118
- */
119
- private function applyContentFilter() {
120
-
121
- add_filter( 'strip_shortcodes_tagnames', array( __CLASS__, 'stripShortcodes' ), 10, 2 );
122
-
123
- /*
124
- * Ensure the ezTOC content filter is not applied when running `the_content` filter.
125
- */
126
- remove_filter( 'the_content', array( 'ezTOC', 'the_content' ), 99999 );
127
-
128
- $this->post->post_content = apply_filters( 'the_content', strip_shortcodes( $this->post->post_content ) );
129
-
130
- add_filter( 'the_content', array( 'ezTOC', 'the_content' ), 99999 );
131
-
132
- remove_filter( 'strip_shortcodes_tagnames', array( __CLASS__, 'stripShortcodes' ) );
133
-
134
- return $this;
135
- }
136
-
137
- /**
138
- * Callback for the `strip_shortcodes_tagnames` filter.
139
- *
140
- * Strip the shortcodes so their content is no processed for headings.
141
- *
142
- * @see ezTOC_Post::applyContentFilter()
143
- *
144
- * @since 2.0
145
- *
146
- * @param array $tags_to_remove Array of shortcode tags to remove.
147
- * @param string $content Content shortcodes are being removed from.
148
- *
149
- * @return array
150
- */
151
- public static function stripShortcodes( $tags_to_remove, $content ) {
152
-
153
- //error_log( var_export( $tags_to_remove, true ) );
154
-
155
- /*
156
- * Ensure the ezTOC shortcodes are not processed when applying `the_content` filter
157
- * otherwise an infinite loop may occur.
158
- */
159
- $tags_to_remove = apply_filters(
160
- 'ez_toc_strip_shortcodes_tagnames',
161
- array(
162
- 'ez-toc',
163
- apply_filters( 'ez_toc_shortcode', 'toc' ),
164
- ),
165
- $content
166
- );
167
-
168
- //error_log( var_export( $tags_to_remove, true ) );
169
-
170
- return $tags_to_remove;
171
- }
172
-
173
- /**
174
- * This is a work around for theme's and plugins
175
- * which break the WordPress global $wp_query var by unsetting it
176
- * or overwriting it which breaks the method call
177
- * that `get_query_var()` uses to return the query variable.
178
- *
179
- * @access protected
180
- * @since 2.0
181
- *
182
- * @return int
183
- */
184
- protected function getCurrentPage() {
185
-
186
- global $wp_query;
187
-
188
- // Check to see if the global `$wp_query` var is an instance of WP_Query and that the get() method is callable.
189
- // If it is then when can simply use the get_query_var() function.
190
- if ( $wp_query instanceof WP_Query && is_callable( array( $wp_query, 'get' ) ) ) {
191
-
192
- $page = get_query_var( 'page', 1 );
193
-
194
- return 1 > $page ? 1 : $page;
195
-
196
- // If a theme or plugin broke the global `$wp_query` var, check to see if the $var was parsed and saved in $GLOBALS['wp_query']->query_vars.
197
- } elseif ( isset( $GLOBALS['wp_query']->query_vars[ 'page' ] ) ) {
198
-
199
- return $GLOBALS['wp_query']->query_vars[ 'page' ];
200
-
201
- // We should not reach this, but if we do, lets check the original parsed query vars in $GLOBALS['wp_the_query']->query_vars.
202
- } elseif ( isset( $GLOBALS['wp_the_query']->query_vars[ 'page' ] ) ) {
203
-
204
- return $GLOBALS['wp_the_query']->query_vars[ 'page' ];
205
-
206
- // Ok, if all else fails, check the $_REQUEST super global.
207
- } elseif ( isset( $_REQUEST[ 'page' ] ) ) {
208
-
209
- return $_REQUEST[ 'page' ];
210
- }
211
-
212
- // Finally, return the $default if it was supplied.
213
- return 1;
214
- }
215
-
216
- /**
217
- * Get the number of page the post has.
218
- *
219
- * @access protected
220
- * @since 2.0
221
- *
222
- * @return int
223
- */
224
- protected function getNumberOfPages() {
225
-
226
- return count( $this->pages );
227
- }
228
-
229
- /**
230
- * Whether or not the post has multiple pages.
231
- *
232
- * @access protected
233
- * @since 2.0
234
- *
235
- * @return bool
236
- */
237
- protected function isMultipage() {
238
-
239
- return 1 < $this->getNumberOfPages();
240
- }
241
-
242
- /**
243
- * Parse the post content and headings.
244
- *
245
- * @access private
246
- * @since 2.0
247
- */
248
- private function processPages() {
249
-
250
- if ( ! class_exists( 'TagFilter' ) ) {
251
-
252
- require_once( EZ_TOC_PATH . 'includes/vendor/ultimate-web-scraper/tag_filter.php' );
253
- }
254
-
255
- $split = preg_split( '/<!--nextpage-->/msuU', $this->post->post_content );
256
- $pages = array();
257
-
258
- if ( is_array( $split ) ) {
259
-
260
- $page = 1;
261
-
262
- $tagFilterOptions = TagFilter::GetHTMLOptions();
263
-
264
- // Set custom TagFilter options.
265
- $tagFilterOptions['charset'] = get_option( 'blog_charset' );
266
- //$tagFilterOptions['output_mode'] = 'xml';
267
-
268
- foreach ( $split as $content ) {
269
-
270
- $html = TagFilter::Explode( $content, $tagFilterOptions );
271
-
272
- /**
273
- * @since 2.0
274
- *
275
- * @param $selectors array Array of classes/id selector to exclude from TOC.
276
- * @param $content string Post content.
277
- */
278
- $selectors = apply_filters( 'ez_toc_exclude_by_selector', array(), $content );
279
-
280
- $nodes = $html->Find( implode( ',', $selectors ) );
281
-
282
- foreach ( $nodes['ids'] as $id ) {
283
-
284
- $html->Remove( $id );
285
- }
286
-
287
- $eligibleContent = $html->Implode( 0, $tagFilterOptions );
288
-
289
- /**
290
- * TagFilter::Implode() writes br tags as `<br>` while WP normalizes to `<br />`.
291
- * Normalize `$eligibleContent` to match WP.
292
- *
293
- * @see wpautop()
294
- */
295
- //$eligibleContent = str_replace( array( '<br>', '<br/>' ), array( '<br />' ), $eligibleContent );
296
- $eligibleContent = \Easy_Plugins\Table_Of_Contents\String\force_balance_tags( $eligibleContent );
297
-
298
- $pages[ $page ] = array(
299
- 'headings' => $this->extractHeadings( $eligibleContent ),
300
- 'content' => $content,
301
- );
302
-
303
- $page++;
304
- }
305
-
306
- }
307
-
308
- $this->pages = $pages;
309
- }
310
-
311
- /**
312
- * Get the post's parse content and headings.
313
- *
314
- * @access public
315
- * @since 2.0
316
- *
317
- * @return array
318
- */
319
- public function getPages() {
320
-
321
- return $this->pages;
322
- }
323
-
324
- /**
325
- * Extract the posts content for headings.
326
- *
327
- * @access private
328
- * @since 2.0
329
- *
330
- * @param string $content
331
- *
332
- * @return array
333
- */
334
- private function extractHeadings( $content ) {
335
-
336
- $matches = array();
337
-
338
- // reset the internal collision collection as the_content may have been triggered elsewhere
339
- // eg by themes or other plugins that need to read in content such as metadata fields in
340
- // the head html tag, or to provide descriptions to twitter/facebook
341
- /** @todo does this need to be used??? */
342
- //self::$collision_collector = array();
343
-
344
- $content = apply_filters( 'ez_toc_extract_headings_content', wptexturize( $content ) );
345
-
346
- // get all headings
347
- // the html spec allows for a maximum of 6 heading depths
348
- if ( preg_match_all( '/(<h([1-6]{1})[^>]*>)(.*)<\/h\2>/msuU', $content, $matches, PREG_SET_ORDER ) ) {
349
-
350
- $minimum = absint( ezTOC_Option::get( 'start' ) );
351
-
352
- $this->removeHeadings( $matches );
353
- $this->excludeHeadings( $matches );
354
- $this->removeEmptyHeadings( $matches );
355
-
356
- if ( count( $matches ) >= $minimum ) {
357
-
358
- $this->alternateHeadings( $matches );
359
- $this->headingIDs( $matches );
360
- $this->hasTOCItems = true;
361
-
362
- } else {
363
-
364
- return array();
365
- }
366
-
367
- }
368
-
369
- return $matches;
370
- }
371
-
372
- /**
373
- * Get the heading levels to be included in the TOC.
374
- *
375
- * @access private
376
- * @since 2.0
377
- *
378
- * @return array
379
- */
380
- private function getHeadingLevels() {
381
-
382
- $levels = get_post_meta( $this->post->ID, '_ez-toc-heading-levels', true );
383
-
384
- if ( ! is_array( $levels ) ) {
385
-
386
- $levels = array();
387
- }
388
-
389
- if ( empty( $levels ) ) {
390
-
391
- $levels = ezTOC_Option::get( 'heading_levels', array() );
392
- }
393
-
394
- $this->headingLevels = $levels;
395
-
396
- return $this->headingLevels;
397
- }
398
-
399
- /**
400
- * Remove the heading levels as defined by user settings from the TOC heading matches.
401
- *
402
- * @see ezTOC_Post::extractHeadings()
403
- *
404
- * @access private
405
- * @since 2.0
406
- *
407
- * @param array $matches The heading from the post content extracted with preg_match_all().
408
- *
409
- * @return array
410
- */
411
- private function removeHeadings( &$matches ) {
412
-
413
- $levels = $this->getHeadingLevels();
414
-
415
- if ( count( $levels ) != 6 ) {
416
-
417
- $new_matches = array();
418
- $count = count( $matches );
419
-
420
- for ( $i = 0; $i < $count; $i++ ) {
421
-
422
- if ( in_array( $matches[ $i ][2], $levels ) ) {
423
-
424
- $new_matches[] = $matches[ $i ];
425
- }
426
- }
427
-
428
- $matches = $new_matches;
429
- }
430
-
431
- return $matches;
432
- }
433
-
434
- /**
435
- * Exclude the heading, by title, as defined by the user settings from the TOC matches.
436
- *
437
- * @see ezTOC_Post::extractHeadings()
438
- *
439
- * @access private
440
- * @since 2.0
441
- *
442
- * @param array $matches The headings from the post content extracted with preg_match_all().
443
- *
444
- * @return array
445
- */
446
- private function excludeHeadings( &$matches ) {
447
-
448
- $exclude = get_post_meta( $this->post->ID, '_ez-toc-exclude', true );
449
-
450
- if ( empty( $exclude ) ) {
451
-
452
- $exclude = ezTOC_Option::get( 'exclude' );
453
- }
454
-
455
- if ( $exclude ) {
456
-
457
- $excluded_headings = explode( '|', $exclude );
458
- $excluded_count = count( $excluded_headings );
459
-
460
- if ( $excluded_count > 0 ) {
461
-
462
- for ( $j = 0; $j < $excluded_count; $j++ ) {
463
-
464
- $excluded_headings[ $j ] = preg_quote( $excluded_headings[ $j ] );
465
-
466
- // escape some regular expression characters
467
- // others: http://www.php.net/manual/en/regexp.reference.meta.php
468
- $excluded_headings[ $j ] = str_replace(
469
- array( '\*', '/', '%' ),
470
- array( '.*', '\/', '\%' ),
471
- trim( $excluded_headings[ $j ] )
472
- );
473
- }
474
-
475
- $new_matches = array();
476
- $count = count( $matches );
477
-
478
- for ( $i = 0; $i < $count; $i++ ) {
479
-
480
- $found = false;
481
-
482
- for ( $j = 0; $j < $excluded_count; $j++ ) {
483
-
484
- // Since WP manipulates the post content it is required that the excluded header and
485
- // the actual header be manipulated similarly so a match can be made.
486
- $pattern = html_entity_decode(
487
- wptexturize( $excluded_headings[ $j ] ),
488
- ENT_NOQUOTES,
489
- get_option( 'blog_charset' )
490
- );
491
-
492
- $against = html_entity_decode(
493
- wptexturize( strip_tags( str_replace( array( "\r", "\n" ), ' ', $matches[ $i ][0] ) ) ),
494
- ENT_NOQUOTES,
495
- get_option( 'blog_charset' )
496
- );
497
-
498
- if ( @preg_match( '/^' . $pattern . '$/imU', $against ) ) {
499
-
500
- $found = true;
501
- break;
502
- }
503
- }
504
-
505
- if ( ! $found ) {
506
-
507
- $new_matches[] = $matches[ $i ];
508
- }
509
- }
510
-
511
- if ( count( $matches ) != count( $new_matches ) ) {
512
-
513
- $matches = $new_matches;
514
- }
515
- }
516
- }
517
-
518
- return $matches;
519
- }
520
-
521
- /**
522
- * Return the alternate headings added by the user, saved in the post meta.
523
- *
524
- * The result is an associative array where the `key` is the original post heading
525
- * and the `value` is the alternate heading.
526
- *
527
- * @access private
528
- * @since 2.0
529
- *
530
- * @return array
531
- */
532
- private function getAlternateHeadings() {
533
-
534
- $alternates = array();
535
- $value = get_post_meta( $this->post->ID, '_ez-toc-alttext', true );
536
-
537
- if ( $value ) {
538
-
539
- $headings = preg_split( '/\r\n|[\r\n]/', $value );
540
- $count = count( $headings );
541
-
542
- if ( $headings ) {
543
-
544
- for ( $k = 0; $k < $count; $k++ ) {
545
-
546
- $heading = explode( '|', $headings[ $k ] );
547
-
548
- if ( 0 < strlen( $heading[0] ) && 0 < strlen( $heading[1] ) ) {
549
-
550
- $alternates[ $heading[0] ] = $heading[1];
551
- }
552
- }
553
-
554
- }
555
-
556
- }
557
-
558
- return $alternates;
559
- }
560
-
561
- /**
562
- * Add the alternate headings to the array.
563
- *
564
- * @see ezTOC_Post::extractHeadings()
565
- *
566
- * @access private
567
- * @since 2.0
568
- *
569
- * @param array $matches The heading from the post content extracted with preg_match_all().
570
- *
571
- * @return array
572
- */
573
- private function alternateHeadings( &$matches ) {
574
-
575
- $alt_headings = $this->getAlternateHeadings();
576
- $count = count( $matches );
577
-
578
- if ( 0 < count( $alt_headings ) ) {
579
-
580
- for ( $i = 0; $i < $count; $i++ ) {
581
-
582
- foreach ( $alt_headings as $original_heading => $alt_heading ) {
583
-
584
- // Cleanup and texturize so alt heading can match heading in post content.
585
- $original_heading = wptexturize( trim( $original_heading ) );
586
-
587
- // Deal with special characters such as non-breakable space.
588
- $original_heading = str_replace(
589
- array( "\xc2\xa0" ),
590
- array( ' ' ),
591
- $original_heading
592
- );
593
-
594
- // Escape for regular expression.
595
- $original_heading = preg_quote( $original_heading );
596
-
597
- // Escape for regular expression some other characters: http://www.php.net/manual/en/regexp.reference.meta.php
598
- $original_heading = str_replace(
599
- array( '\*', '/', '%' ),
600
- array( '.*', '\/', '\%' ),
601
- $original_heading
602
- );
603
-
604
- // Cleanup subject so alt heading can match heading in post content.
605
- $subject = strip_tags( $matches[ $i ][0] );
606
-
607
- // Deal with special characters such as non-breakable space.
608
- $subject = str_replace(
609
- array( "\xc2\xa0" ),
610
- array( ' ' ),
611
- $subject
612
- );
613
-
614
- if ( @preg_match( '/^' . $original_heading . '$/imU', $subject ) ) {
615
-
616
- $matches[ $i ]['alternate'] = $alt_heading;
617
- }
618
- }
619
- }
620
- }
621
-
622
- return $matches;
623
- }
624
-
625
- /**
626
- * Add the heading `id` to the array.
627
- *
628
- * @see ezTOC_Post::extractHeadings()
629
- *
630
- * @access private
631
- * @since 2.0
632
- *
633
- * @param array $matches The heading from the post content extracted with preg_match_all().
634
- *
635
- * @return mixed
636
- */
637
- private function headingIDs( &$matches ) {
638
-
639
- $count = count( $matches );
640
-
641
- for ( $i = 0; $i < $count; $i++ ) {
642
-
643
- $matches[ $i ]['id'] = $this->generateHeadingIDFromTitle( $matches[ $i ][0] );
644
- }
645
-
646
- return $matches;
647
- }
648
-
649
- /**
650
- * Create unique heading ID from heading string.
651
- *
652
- * @access private
653
- * @since 2.0
654
- *
655
- * @param string $heading
656
- *
657
- * @return bool|string
658
- */
659
- private function generateHeadingIDFromTitle( $heading ) {
660
-
661
- $return = false;
662
-
663
- if ( $heading ) {
664
-
665
- // WP entity encodes the post content.
666
- $return = html_entity_decode( $heading, ENT_QUOTES, get_option( 'blog_charset' ) );
667
-
668
- $return = trim( strip_tags( $return ) );
669
-
670
- // Convert accented characters to ASCII.
671
- $return = remove_accents( $return );
672
-
673
- // replace newlines with spaces (eg when headings are split over multiple lines)
674
- $return = str_replace( array( "\r", "\n", "\n\r", "\r\n" ), ' ', $return );
675
-
676
- // Remove `&amp;` and `&nbsp;` NOTE: in order to strip "hidden" `&nbsp;`,
677
- // title needs to be converted to HTML entities.
678
- // @link https://stackoverflow.com/a/21801444/5351316
679
- $return = htmlentities2( $return );
680
- $return = str_replace( array( '&amp;', '&nbsp;' ), ' ', $return );
681
- $return = html_entity_decode( $return, ENT_QUOTES, get_option( 'blog_charset' ) );
682
-
683
- // remove non alphanumeric chars
684
- $return = preg_replace( '/[^a-zA-Z0-9 \-_]*/', '', $return );
685
-
686
- // convert spaces to _
687
- $return = preg_replace( '/\s+/', '_', $return );
688
-
689
- // remove trailing - and _
690
- $return = rtrim( $return, '-_' );
691
-
692
- // lowercase everything?
693
- if ( ezTOC_Option::get( 'lowercase' ) ) {
694
-
695
- $return = strtolower( $return );
696
- }
697
-
698
- // if blank, then prepend with the fragment prefix
699
- // blank anchors normally appear on sites that don't use the latin charset
700
- if ( ! $return ) {
701
-
702
- $return = ( ezTOC_Option::get( 'fragment_prefix' ) ) ? ezTOC_Option::get( 'fragment_prefix' ) : '_';
703
- }
704
-
705
- // hyphenate?
706
- if ( ezTOC_Option::get( 'hyphenate' ) ) {
707
-
708
- $return = str_replace( '_', '-', $return );
709
- $return = str_replace( '--', '-', $return );
710
- }
711
- }
712
-
713
- if ( array_key_exists( $return, $this->collision_collector ) ) {
714
-
715
- $this->collision_collector[ $return ]++;
716
- $return .= '-' . $this->collision_collector[ $return ];
717
-
718
- } else {
719
-
720
- $this->collision_collector[ $return ] = 1;
721
- }
722
-
723
- return apply_filters( 'ez_toc_url_anchor_target', $return, $heading );
724
- }
725
-
726
- /**
727
- * Remove any empty headings from the TOC.
728
- *
729
- * @access private
730
- * @since 2.0
731
- *
732
- * @param array $matches The heading from the post content extracted with preg_match_all().
733
- *
734
- * @return array
735
- */
736
- private function removeEmptyHeadings( &$matches ) {
737
-
738
- $new_matches = array();
739
- $count = count( $matches );
740
-
741
- for ( $i = 0; $i < $count; $i ++ ) {
742
-
743
- if ( trim( strip_tags( $matches[ $i ][0] ) ) != false ) {
744
-
745
- $new_matches[] = $matches[ $i ];
746
- }
747
- }
748
-
749
- if ( count( $matches ) != count( $new_matches ) ) {
750
-
751
- $matches = $new_matches;
752
- }
753
-
754
- return $matches;
755
- }
756
-
757
- /**
758
- * Whether or not the post has TOC items.
759
- *
760
- * @see ezTOC_Post::extractHeadings()
761
- *
762
- * @access public
763
- * @since 2.0
764
- *
765
- * @return bool
766
- */
767
- public function hasTOCItems() {
768
-
769
- return $this->hasTOCItems;
770
- }
771
-
772
- /**
773
- * Get the headings of the current page of the post.
774
- *
775
- * @access public
776
- * @since 2.0
777
- *
778
- * @param int|null $page
779
- *
780
- * @return array
781
- */
782
- public function getHeadings( $page = null ) {
783
-
784
- $headings = array();
785
-
786
- if ( is_null( $page ) ) {
787
-
788
- $page = $this->getCurrentPage();
789
- }
790
-
791
- if ( isset( $this->pages[ $page ] ) ) {
792
-
793
- $headings = wp_list_pluck( $this->pages[ $page ]['headings'], 0 );
794
- }
795
-
796
- return $headings;
797
- }
798
-
799
- /**
800
- * Get the heading with in page anchors of the current page of the post.
801
- *
802
- * @access public
803
- * @since 2.0
804
- *
805
- * @param int|null $page
806
- *
807
- * @return array
808
- */
809
- public function getHeadingsWithAnchors( $page = null ) {
810
-
811
- $headings = array();
812
-
813
- if ( is_null( $page ) ) {
814
-
815
- $page = $this->getCurrentPage();
816
- }
817
-
818
- if ( isset( $this->pages[ $page ] ) ) {
819
-
820
- $matches = $this->pages[ $page ]['headings'];
821
- $count = count( $matches );
822
-
823
- for ( $i = 0; $i < $count; $i++ ) {
824
-
825
- $anchor = $matches[ $i ]['id'];
826
- $headings[] = str_replace(
827
- array(
828
- $matches[ $i ][1], // start of heading
829
- '</h' . $matches[ $i ][2] . '>' // end of heading
830
- ),
831
- array(
832
- $matches[ $i ][1],
833
- '<span class="ez-toc-section" id="' . $anchor . '"></span></h' . $matches[ $i ][2] . '>'
834
- ),
835
- $matches[ $i ][0]
836
- );
837
- }
838
- }
839
-
840
- return $headings;
841
- }
842
-
843
- /**
844
- * Get the post TOC list.
845
- *
846
- * @access public
847
- * @since 2.0
848
- *
849
- * @return string
850
- */
851
- public function getTOCList() {
852
-
853
- $html = '';
854
-
855
- if ( $this->hasTOCItems ) {
856
-
857
- foreach ( $this->pages as $page => $attribute ) {
858
-
859
- $html .= $this->createTOC( $page, $attribute['headings'] );
860
- }
861
-
862
- $html = '<ul class="ez-toc-list ez-toc-list-level-1">' . $html . '</ul>';
863
- }
864
-
865
- return $html;
866
- }
867
-
868
- /**
869
- * Get the post TOC content block.
870
- *
871
- * @access public
872
- * @since 2.0
873
- *
874
- * @return string
875
- */
876
- public function getTOC() {
877
-
878
- $css_classes = '';
879
- $html = '';
880
-
881
- if ( $this->hasTOCItems() ) {
882
-
883
- // wrapping css classes
884
- switch ( ezTOC_Option::get( 'wrapping' ) ) {
885
-
886
- case 'left':
887
- $css_classes .= ' ez-toc-wrap-left';
888
- break;
889
-
890
- case 'right':
891
- $css_classes .= ' ez-toc-wrap-right';
892
- break;
893
-
894
- case 'none':
895
- default:
896
- // do nothing
897
- }
898
-
899
- if ( ezTOC_Option::get( 'show_hierarchy' ) ) {
900
-
901
- $css_classes .= ' counter-hierarchy';
902
-
903
- } else {
904
-
905
- $css_classes .= ' counter-flat';
906
- }
907
-
908
- switch ( ezTOC_Option::get( 'counter' ) ) {
909
-
910
- case 'numeric':
911
- $css_classes .= ' counter-numeric';
912
- break;
913
-
914
- case 'roman':
915
- $css_classes .= ' counter-roman';
916
- break;
917
-
918
- case 'decimal':
919
- $css_classes .= ' counter-decimal';
920
- break;
921
- }
922
-
923
- // colour themes
924
- switch ( ezTOC_Option::get( 'theme' ) ) {
925
-
926
- case 'light-blue':
927
- $css_classes .= ' ez-toc-light-blue';
928
- break;
929
-
930
- case 'white':
931
- $css_classes .= ' ez-toc-white';
932
- break;
933
-
934
- case 'black':
935
- $css_classes .= ' ez-toc-black';
936
- break;
937
-
938
- case 'transparent':
939
- $css_classes .= ' ez-toc-transparent';
940
- break;
941
-
942
- case 'grey':
943
- $css_classes .= ' ez-toc-grey';
944
- break;
945
-
946
- default:
947
- // do nothing
948
- }
949
-
950
- if ( ezTOC_Option::get( 'css_container_class' ) ) {
951
-
952
- $css_classes .= ' ' . ezTOC_Option::get( 'css_container_class' );
953
- }
954
-
955
- $css_classes = trim( $css_classes );
956
-
957
- // an empty class="" is invalid markup!
958
- if ( ! $css_classes ) {
959
-
960
- $css_classes = ' ';
961
- }
962
-
963
- // add container, toc title and list items
964
- $html .= '<div id="ez-toc-container" class="' . $css_classes . '">' . PHP_EOL;
965
-
966
- if ( ezTOC_Option::get( 'show_heading_text' ) ) {
967
-
968
- $toc_title = ezTOC_Option::get( 'heading_text' );
969
-
970
- if ( strpos( $toc_title, '%PAGE_TITLE%' ) !== false ) {
971
-
972
- $toc_title = str_replace( '%PAGE_TITLE%', get_the_title(), $toc_title );
973
- }
974
-
975
- if ( strpos( $toc_title, '%PAGE_NAME%' ) !== false ) {
976
-
977
- $toc_title = str_replace( '%PAGE_NAME%', get_the_title(), $toc_title );
978
- }
979
-
980
- $html .= '<div class="ez-toc-title-container">' . PHP_EOL;
981
-
982
- $html .= '<p class="ez-toc-title">' . esc_html__( htmlentities( $toc_title, ENT_COMPAT, 'UTF-8' ), 'easy-table-of-contents' ). '</p>' . PHP_EOL;
983
-
984
- $html .= '<span class="ez-toc-title-toggle">';
985
-
986
- if ( ezTOC_Option::get( 'visibility' ) ) {
987
-
988
- $html .= '<a class="ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle"><i class="ez-toc-glyphicon ez-toc-icon-toggle"></i></a>';
989
- }
990
-
991
- $html .= '</span>';
992
-
993
- $html .= '</div>' . PHP_EOL;
994
- }
995
-
996
- ob_start();
997
- do_action( 'ez_toc_before' );
998
- $html .= ob_get_clean();
999
-
1000
- $html .= '<nav>' . $this->getTOCList() . '</nav>';
1001
-
1002
- ob_start();
1003
- do_action( 'ez_toc_after' );
1004
- $html .= ob_get_clean();
1005
-
1006
- $html .= '</div>' . PHP_EOL;
1007
-
1008
- // Enqueue the script.
1009
- wp_enqueue_script( 'ez-toc-js' );
1010
- }
1011
-
1012
- return $html;
1013
- }
1014
-
1015
- /**
1016
- * Displays the post's TOC.
1017
- *
1018
- * @access public
1019
- * @since 2.0
1020
- */
1021
- public function toc() {
1022
-
1023
- echo $this->getTOC();
1024
- }
1025
-
1026
- /**
1027
- * Generate the TOC list items for a given page within a post.
1028
- *
1029
- * @access private
1030
- * @since 2.0
1031
- *
1032
- * @param int $page The page of the post to create the TOC items for.
1033
- * @param array $matches The heading from the post content extracted with preg_match_all().
1034
- *
1035
- * @return string The HTML list of TOC items.
1036
- */
1037
- private function createTOC( $page, $matches ) {
1038
-
1039
- // Whether or not the TOC should be built flat or hierarchical.
1040
- $hierarchical = ezTOC_Option::get( 'show_hierarchy' );
1041
- $html = '';
1042
-
1043
- if ( $hierarchical ) {
1044
-
1045
- $current_depth = 100; // headings can't be larger than h6 but 100 as a default to be sure
1046
- $numbered_items = array();
1047
- $numbered_items_min = null;
1048
-
1049
- // reset the internal collision collection
1050
- /** @todo does this need to be used??? */
1051
- //self::$collision_collector = array();
1052
-
1053
- // find the minimum heading to establish our baseline
1054
- for ( $i = 0; $i < count( $matches ); $i ++ ) {
1055
- if ( $current_depth > $matches[ $i ][2] ) {
1056
- $current_depth = (int) $matches[ $i ][2];
1057
- }
1058
- }
1059
-
1060
- $numbered_items[ $current_depth ] = 0;
1061
- $numbered_items_min = $current_depth;
1062
-
1063
- for ( $i = 0; $i < count( $matches ); $i ++ ) {
1064
-
1065
- $level = $matches[ $i ][2];
1066
- $count = $i + 1;
1067
-
1068
- if ( $current_depth == (int) $matches[ $i ][2] ) {
1069
-
1070
- $html .= '<li class="ez-toc-page-' . $page . ' ez-toc-heading-level-' . $current_depth . '">';
1071
- }
1072
-
1073
- // start lists
1074
- if ( $current_depth != (int) $matches[ $i ][2] ) {
1075
-
1076
- for ( $current_depth; $current_depth < (int) $matches[ $i ][2]; $current_depth++ ) {
1077
-
1078
- $numbered_items[ $current_depth + 1 ] = 0;
1079
- $html .= '<ul class="ez-toc-list-level-' . $level . '"><li class="ez-toc-heading-level-' . $level . '">';
1080
- }
1081
- }
1082
-
1083
- $title = isset( $matches[ $i ]['alternate'] ) ? $matches[ $i ]['alternate'] : $matches[ $i ][0];
1084
- $title = strip_tags( apply_filters( 'ez_toc_title', $title ), apply_filters( 'ez_toc_title_allowable_tags', '' ) );
1085
-
1086
- $html .= $this->createTOCItemAnchor( $page, $matches[ $i ]['id'], $title, $count );
1087
-
1088
- // end lists
1089
- if ( $i != count( $matches ) - 1 ) {
1090
-
1091
- if ( $current_depth > (int) $matches[ $i + 1 ][2] ) {
1092
-
1093
- for ( $current_depth; $current_depth > (int) $matches[ $i + 1 ][2]; $current_depth-- ) {
1094
-
1095
- $html .= '</li></ul>';
1096
- $numbered_items[ $current_depth ] = 0;
1097
- }
1098
- }
1099
-
1100
- if ( $current_depth == (int) @$matches[ $i + 1 ][2] ) {
1101
-
1102
- $html .= '</li>';
1103
- }
1104
-
1105
- } else {
1106
-
1107
- // this is the last item, make sure we close off all tags
1108
- for ( $current_depth; $current_depth >= $numbered_items_min; $current_depth-- ) {
1109
-
1110
- $html .= '</li>';
1111
-
1112
- if ( $current_depth != $numbered_items_min ) {
1113
- $html .= '</ul>';
1114
- }
1115
- }
1116
- }
1117
- }
1118
-
1119
- } else {
1120
-
1121
- for ( $i = 0; $i < count( $matches ); $i++ ) {
1122
-
1123
- $count = $i + 1;
1124
-
1125
- $title = isset( $matches[ $i ]['alternate'] ) ? $matches[ $i ]['alternate'] : $matches[ $i ][0];
1126
- $title = strip_tags( apply_filters( 'ez_toc_title', $title ), apply_filters( 'ez_toc_title_allowable_tags', '' ) );
1127
-
1128
- $html .= '<li class="ez-toc-page-' . $page . '">';
1129
-
1130
- $html .= $this->createTOCItemAnchor( $page, $matches[ $i ]['id'], $title, $count );
1131
-
1132
- $html .= '</li>';
1133
- }
1134
- }
1135
-
1136
- return $html;
1137
- }
1138
-
1139
- /**
1140
- * @access private
1141
- * @since 2.0
1142
- *
1143
- * @param int $page
1144
- * @param string $id
1145
- * @param string $title
1146
- * @param int $count
1147
- *
1148
- * @return string
1149
- */
1150
- private function createTOCItemAnchor( $page, $id, $title, $count ) {
1151
-
1152
- return sprintf(
1153
- '<a class="ez-toc-link ez-toc-heading-' . $count . '" href="%1$s" title="%2$s">' . $title . '</a>',
1154
- esc_url( $this->createTOCItemURL( $id, $page ) ),
1155
- esc_attr( strip_tags( $title ) )
1156
- );
1157
- }
1158
-
1159
- /**
1160
- * @access private
1161
- * @since 2.0
1162
- *
1163
- * @param string $id
1164
- * @param int $page
1165
- *
1166
- * @return string
1167
- */
1168
- private function createTOCItemURL( $id, $page ) {
1169
-
1170
- $current_post = $this->post->ID === $this->queriedObjectID;
1171
- $current_page = $this->getCurrentPage();
1172
-
1173
- if ( $page === $current_page && $current_post ) {
1174
-
1175
- return '#' . $id;
1176
-
1177
- } elseif ( 1 === $page ) {
1178
-
1179
- return $this->permalink . '#' . $id;
1180
-
1181
- }
1182
-
1183
- return $this->permalink . $page . '/#' . $id;
1184
- }
1185
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class.widget-toc.php CHANGED
@@ -138,76 +138,74 @@ if ( ! class_exists( 'ezTOC_Widget' ) ) {
138
 
139
  if ( is_404() || is_archive() || is_search() || ( ! is_front_page() && is_home() ) ) return;
140
 
141
- //global $wp_query;
142
 
143
- //$find = $replace = array();
144
- //$post = get_post( $wp_query->post->ID );
145
- //$post = ezTOC_Post::get( get_the_ID() );//->applyContentFilter()->process();
146
- $post = ezTOC::get( get_the_ID() );
147
 
148
  /*
149
  * Ensure the ezTOC content filter is not applied when running `the_content` filter.
150
  */
151
- //remove_filter( 'the_content', array( 'ezTOC', 'the_content' ), 100 );
152
- //$post->post_content = apply_filters( 'the_content', $post->post_content );
153
- //add_filter( 'the_content', array( 'ezTOC', 'the_content' ), 100 );
154
-
155
- if ( $post->hasTOCItems() ) {
156
-
157
- $css_classes = '';
 
 
 
 
158
 
159
- /**
160
- * @var string $before_widget
161
- * @var string $after_widget
162
- * @var string $before_title
163
- * @var string $after_title
164
- */
165
- extract( $args );
166
 
167
- $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
168
- //$items = ezTOC::extract_headings( $find, $replace, $post );
169
 
170
- if ( false !== strpos( $title, '%PAGE_TITLE%' ) || false !== strpos( $title, '%PAGE_NAME%' ) ) {
 
171
 
172
- $title = str_replace( '%PAGE_TITLE%', get_the_title(), $title );
173
- }
174
 
175
- if ( ezTOC_Option::get( 'show_hierarchy' ) ) {
176
 
177
- $css_classes = ' counter-hierarchy';
178
 
179
- } else {
 
180
 
181
- $css_classes .= ' counter-flat';
182
- }
183
 
184
- switch ( ezTOC_Option::get( 'counter' ) ) {
 
 
185
 
186
- case 'numeric':
187
- $css_classes .= ' counter-numeric';
188
- break;
189
 
190
- case 'roman':
191
- $css_classes .= ' counter-roman';
192
- break;
 
193
 
194
- case 'decimal':
195
- $css_classes .= ' counter-decimal';
196
- break;
197
- }
198
 
199
- if ( $instance['affix'] ) {
 
200
 
201
- $css_classes .= ' ez-toc-affix';
202
- }
203
 
204
- $css_classes = trim( $css_classes );
 
205
 
206
- // an empty class="" is invalid markup!
207
- if ( ! $css_classes ) {
208
 
209
- $css_classes = ' ';
210
- }
211
 
212
  echo $before_widget;
213
 
@@ -257,7 +255,7 @@ if ( ! class_exists( 'ezTOC_Widget' ) ) {
257
  <?php
258
  }
259
 
260
- echo '<nav>'. PHP_EOL . $post->getTOCList() . '</nav>' . PHP_EOL;
261
 
262
  do_action( 'ez_toc_after_widget' );
263
 
138
 
139
  if ( is_404() || is_archive() || is_search() || ( ! is_front_page() && is_home() ) ) return;
140
 
141
+ global $wp_query;
142
 
143
+ $css_classes = '';
144
+
145
+ $find = $replace = array();
146
+ $post = get_post( $wp_query->post->ID );
147
 
148
  /*
149
  * Ensure the ezTOC content filter is not applied when running `the_content` filter.
150
  */
151
+ remove_filter( 'the_content', array( 'ezTOC', 'the_content' ), 100 );
152
+ $post->post_content = apply_filters( 'the_content', $post->post_content );
153
+ add_filter( 'the_content', array( 'ezTOC', 'the_content' ), 100 );
154
+
155
+ /**
156
+ * @var string $before_widget
157
+ * @var string $after_widget
158
+ * @var string $before_title
159
+ * @var string $after_title
160
+ */
161
+ extract( $args );
162
 
163
+ $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
164
+ $items = ezTOC::extract_headings( $find, $replace, $post );
 
 
 
 
 
165
 
166
+ if ( FALSE !== strpos( $title, '%PAGE_TITLE%' ) || FALSE !== strpos( $title, '%PAGE_NAME%' ) ) {
 
167
 
168
+ $title = str_replace( '%PAGE_TITLE%', get_the_title(), $title );
169
+ }
170
 
171
+ if ( ezTOC_Option::get( 'show_hierarchy' ) ) {
 
172
 
173
+ $css_classes = ' counter-hierarchy';
174
 
175
+ } else {
176
 
177
+ $css_classes .= ' counter-flat';
178
+ }
179
 
180
+ switch ( ezTOC_Option::get( 'counter' ) ) {
 
181
 
182
+ case 'numeric':
183
+ $css_classes .= ' counter-numeric';
184
+ break;
185
 
186
+ case 'roman':
187
+ $css_classes .= ' counter-roman';
188
+ break;
189
 
190
+ case 'decimal':
191
+ $css_classes .= ' counter-decimal';
192
+ break;
193
+ }
194
 
195
+ if ( $instance['affix'] ) {
 
 
 
196
 
197
+ $css_classes .= ' ez-toc-affix';
198
+ }
199
 
200
+ $css_classes = trim( $css_classes );
 
201
 
202
+ // an empty class="" is invalid markup!
203
+ if ( ! $css_classes ) {
204
 
205
+ $css_classes = ' ';
206
+ }
207
 
208
+ if ( $items ) {
 
209
 
210
  echo $before_widget;
211
 
255
  <?php
256
  }
257
 
258
+ echo '<nav><ul class="ez-toc-list">'. PHP_EOL . $items . '</ul></nav>' . PHP_EOL;
259
 
260
  do_action( 'ez_toc_after_widget' );
261
 
includes/inc.functions.php DELETED
@@ -1,92 +0,0 @@
1
- <?php
2
-
3
- // Exit if accessed directly
4
- if ( ! defined( 'ABSPATH' ) ) exit;
5
-
6
- /**
7
- * Get the current post's TOC list or supplied post's TOC list.
8
- *
9
- * @access public
10
- * @since 2.0
11
- *
12
- * @param int|null|WP_Post $post An instance of WP_Post or post ID. Defaults to current post.
13
- * @param bool $apply_content_filter Whether or not to apply `the_content` filter when processing post for headings.
14
- *
15
- * @return string
16
- */
17
- function get_ez_toc_list( $post = null, $apply_content_filter = true ) {
18
-
19
- if ( ! $post instanceof WP_Post ) {
20
-
21
- $post = get_post( $post );
22
- }
23
-
24
- if ( $apply_content_filter ) {
25
-
26
- $ezPost = new ezTOC_Post( $post );
27
-
28
- } else {
29
-
30
- $ezPost = new ezTOC_Post( $post, false );
31
- }
32
-
33
- return $ezPost->getTOCList();
34
- }
35
-
36
- /**
37
- * Display the current post's TOC list or supplied post's TOC list.
38
- *
39
- * @access public
40
- * @since 2.0
41
- *
42
- * @param null|WP_Post $post An instance of WP_Post
43
- * @param bool $apply_content_filter Whether or not to apply `the_content` filter when processing post for headings.
44
- */
45
- function ez_toc_list( $post = null, $apply_content_filter = true ) {
46
-
47
- echo get_ez_toc_list( $post, $apply_content_filter );
48
- }
49
-
50
- /**
51
- * Get the current post's TOC content block or supplied post's TOC content block.
52
- *
53
- * @access public
54
- * @since 2.0
55
- *
56
- * @param int|null|WP_Post $post An instance of WP_Post or post ID. Defaults to current post.
57
- * @param bool $apply_content_filter Whether or not to apply `the_content` filter when processing post for headings.
58
- *
59
- * @return string
60
- */
61
- function get_ez_toc_block( $post = null, $apply_content_filter = true ) {
62
-
63
- if ( ! $post instanceof WP_Post ) {
64
-
65
- $post = get_post( $post );
66
- }
67
-
68
- if ( $apply_content_filter ) {
69
-
70
- $ezPost = new ezTOC_Post( $post );
71
-
72
- } else {
73
-
74
- $ezPost = new ezTOC_Post( $post, false );
75
- }
76
-
77
- return $ezPost->getTOC();
78
- }
79
-
80
- /**
81
- * Display the current post's TOC content or supplied post's TOC content.
82
- *
83
- * @access public
84
- * @since 2.0
85
- *
86
- * @param null|WP_Post $post An instance of WP_Post
87
- * @param bool $apply_content_filter Whether or not to apply `the_content` filter when processing post for headings.
88
- */
89
- function ez_toc_block( $post = null, $apply_content_filter = true ) {
90
-
91
- echo get_ez_toc_block( $post, $apply_content_filter );
92
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/inc.plugin-compatibility.php DELETED
@@ -1,192 +0,0 @@
1
- <?php
2
- /**
3
- * Filter to add plugins to the TOC list.
4
- *
5
- * @link https://rankmath.com/kb/filters-hooks-api-developer/#add-toc-plugin
6
- *
7
- * @since 2.0
8
- *
9
- * @param array TOC plugins.
10
- */
11
- add_filter(
12
- 'rank_math/researches/toc_plugins',
13
- function( $toc_plugins ) {
14
-
15
- $toc_plugins[ EZ_TOC_BASE_NAME ] = 'Easy Table of Contents';
16
-
17
- return $toc_plugins;
18
- }
19
- );
20
-
21
- /**
22
- * Filter to remove Connections Business Directory related shortcodes from being processed as eligible TOC items.
23
- *
24
- * @since 2.0
25
- */
26
- add_filter(
27
- 'ez_toc_strip_shortcodes_tagnames',
28
- function( $tags_to_remove ) {
29
-
30
- $shortcodes = array (
31
- 'connections_form',
32
- 'cn_multi_category_search',
33
- 'cn_widget',
34
- 'cn_carousel',
35
- 'connections_categories',
36
- 'connections_link_view',
37
- 'connections_link_edit',
38
- 'connections_login',
39
- 'siteshot',
40
- 'connections',
41
- 'upcoming_list',
42
- 'cn-mapblock',
43
- 'connections_vcard',
44
- 'connections_qtip',
45
- 'cn_thumb',
46
- 'cn_thumbr',
47
- );
48
-
49
- $tags_to_remove = array_merge( $tags_to_remove, $shortcodes );
50
-
51
- return $tags_to_remove;
52
- }
53
- );
54
-
55
-
56
- /**
57
- * Filter to remove Striking theme related shortcodes from being processed as eligible TOC items.
58
- *
59
- * @since 2.0
60
- */
61
- add_filter(
62
- 'ez_toc_strip_shortcodes_tagnames',
63
- function( $tags_to_remove ) {
64
-
65
- $shortcodes = array (
66
- 'iconbox',
67
- 'toggle',
68
- );
69
-
70
- $tags_to_remove = array_merge( $tags_to_remove, $shortcodes );
71
-
72
- return $tags_to_remove;
73
- }
74
- );
75
-
76
- /**
77
- * Remove the JetPack share buttons node from the post content before extracting headings.
78
- *
79
- * @since 2.0
80
- */
81
- add_filter(
82
- 'ez_toc_exclude_by_selector',
83
- function( $selectors ) {
84
-
85
- $selectors['jetpack-sharedaddy'] = '.sharedaddy';
86
-
87
- return $selectors;
88
- }
89
- );
90
-
91
- /**
92
- * Remove the Elegant Themes Bloom plugin node from the post content before extracting headings.
93
- *
94
- * @since 2.0
95
- */
96
- add_filter(
97
- 'ez_toc_exclude_by_selector',
98
- function( $selectors ) {
99
-
100
- $selectors['elegant-themes-bloom'] = '.et_bloom_below_post';
101
-
102
- return $selectors;
103
- }
104
- );
105
-
106
- /**
107
- * Do not allow `the_content` TOC callback to run when editing a page in Visual Composer.
108
- *
109
- * @link https://wordpress.org/support/topic/correct-method-to-determine-if-using-frontend-editor/#post-12404679
110
- *
111
- * @since 2.0
112
- */
113
- add_filter(
114
- 'ez_toc_maybe_apply_the_content_filter',
115
- function( $apply ) {
116
-
117
- if ( function_exists( 'vchelper' ) ) {
118
-
119
- //$sourceId = intval( vchelper( "Request" )->input( 'vcv-source-id' ) );
120
- //
121
- //if ( $sourceId === get_the_ID() ) {
122
- //
123
- // $apply = false;
124
- //}
125
-
126
- if ( vchelper( 'Frontend' )->isPageEditable() ) {
127
-
128
- $apply = false;
129
- }
130
- }
131
-
132
- return $apply;
133
- }
134
- );
135
-
136
- /**
137
- * Do not allow `the_content` TOC callback to run when editing a page in WPBakery Page Builder.
138
- *
139
- * @link https://wordpress.org/support/topic/correct-method-to-determine-if-using-frontend-editor/#post-12404679
140
- *
141
- * @since 2.0
142
- */
143
- add_filter(
144
- 'ez_toc_maybe_apply_the_content_filter',
145
- function( $apply ) {
146
-
147
- if ( function_exists( 'vc_is_page_editable' ) ) {
148
-
149
- if ( vc_is_page_editable() ) {
150
-
151
- $apply = false;
152
- }
153
- }
154
-
155
- return $apply;
156
- }
157
- );
158
-
159
- /**
160
- * Filter to remove WPBakery Page Builder related shortcodes from being processed as eligible TOC items.
161
- *
162
- * @since 2.0
163
- */
164
- add_filter(
165
- 'ez_toc_strip_shortcodes_tagnames',
166
- function( $tags_to_remove ) {
167
-
168
- $shortcodes = array (
169
- 'vc_tta_section',
170
- );
171
-
172
- $tags_to_remove = array_merge( $tags_to_remove, $shortcodes );
173
-
174
- return $tags_to_remove;
175
- }
176
- );
177
-
178
- /**
179
- * Exclude the TOC shortcodes from being processed in the admin in the Divi Theme by Elegant Themes.
180
- *
181
- * @since 2.0
182
- */
183
- add_action(
184
- 'et_pb_admin_excluded_shortcodes',
185
- function( $shortcodes ) {
186
-
187
- $shortcodes[] = 'ez-toc';
188
- $shortcodes[] = apply_filters( 'ez_toc_shortcode', 'toc' );
189
-
190
- return $shortcodes;
191
- }
192
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/inc.string-functions.php DELETED
@@ -1,296 +0,0 @@
1
- <?php
2
-
3
- namespace Easy_Plugins\Table_Of_Contents\String;
4
-
5
- /**
6
- * Pulled from WordPress formatting functions.
7
- *
8
- * Edited to add space before self closing tags.
9
- *
10
- * @since 2.0
11
- *
12
- * @param string $text
13
- *
14
- * @return string|string[]
15
- */
16
- function force_balance_tags( $text ) {
17
- $tagstack = array();
18
- $stacksize = 0;
19
- $tagqueue = '';
20
- $newtext = '';
21
- // Known single-entity/self-closing tags
22
- $single_tags = array( 'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param', 'source' );
23
- // Tags that can be immediately nested within themselves
24
- $nestable_tags = array( 'blockquote', 'div', 'object', 'q', 'span' );
25
-
26
- // WP bug fix for comments - in case you REALLY meant to type '< !--'
27
- $text = str_replace( '< !--', '< !--', $text );
28
- // WP bug fix for LOVE <3 (and other situations with '<' before a number)
29
- $text = preg_replace( '#<([0-9]{1})#', '&lt;$1', $text );
30
-
31
- /**
32
- * Matches supported tags.
33
- *
34
- * To get the pattern as a string without the comments paste into a PHP
35
- * REPL like `php -a`.
36
- *
37
- * @see https://html.spec.whatwg.org/#elements-2
38
- * @see https://w3c.github.io/webcomponents/spec/custom/#valid-custom-element-name
39
- *
40
- * @example
41
- * ~# php -a
42
- * php > $s = [paste copied contents of expression below including parentheses];
43
- * php > echo $s;
44
- */
45
- $tag_pattern = (
46
- '#<' . // Start with an opening bracket.
47
- '(/?)' . // Group 1 - If it's a closing tag it'll have a leading slash.
48
- '(' . // Group 2 - Tag name.
49
- // Custom element tags have more lenient rules than HTML tag names.
50
- '(?:[a-z](?:[a-z0-9._]*)-(?:[a-z0-9._-]+)+)' .
51
- '|' .
52
- // Traditional tag rules approximate HTML tag names.
53
- '(?:[\w:]+)' .
54
- ')' .
55
- '(?:' .
56
- // We either immediately close the tag with its '>' and have nothing here.
57
- '\s*' .
58
- '(/?)' . // Group 3 - "attributes" for empty tag.
59
- '|' .
60
- // Or we must start with space characters to separate the tag name from the attributes (or whitespace).
61
- '(\s+)' . // Group 4 - Pre-attribute whitespace.
62
- '([^>]*)' . // Group 5 - Attributes.
63
- ')' .
64
- '>#' // End with a closing bracket.
65
- );
66
-
67
- while ( preg_match( $tag_pattern, $text, $regex ) ) {
68
- $full_match = $regex[0];
69
- $has_leading_slash = ! empty( $regex[1] );
70
- $tag_name = $regex[2];
71
- $tag = strtolower( $tag_name );
72
- $is_single_tag = in_array( $tag, $single_tags, true );
73
- $pre_attribute_ws = isset( $regex[4] ) ? $regex[4] : '';
74
- $attributes = trim( isset( $regex[5] ) ? $regex[5] : $regex[3] );
75
- $has_self_closer = '/' === substr( $attributes, -1 );
76
-
77
- $newtext .= $tagqueue;
78
-
79
- $i = strpos( $text, $full_match );
80
- $l = strlen( $full_match );
81
-
82
- // Clear the shifter.
83
- $tagqueue = '';
84
- if ( $has_leading_slash ) { // End Tag.
85
- // If too many closing tags.
86
- if ( $stacksize <= 0 ) {
87
- $tag = '';
88
- // Or close to be safe $tag = '/' . $tag.
89
-
90
- // If stacktop value = tag close value, then pop.
91
- } elseif ( $tagstack[ $stacksize - 1 ] === $tag ) { // Found closing tag.
92
- $tag = '</' . $tag . '>'; // Close Tag.
93
- array_pop( $tagstack );
94
- $stacksize--;
95
- } else { // Closing tag not at top, search for it.
96
- for ( $j = $stacksize - 1; $j >= 0; $j-- ) {
97
- if ( $tagstack[ $j ] === $tag ) {
98
- // Add tag to tagqueue.
99
- for ( $k = $stacksize - 1; $k >= $j; $k-- ) {
100
- $tagqueue .= '</' . array_pop( $tagstack ) . '>';
101
- $stacksize--;
102
- }
103
- break;
104
- }
105
- }
106
- $tag = '';
107
- }
108
- } else { // Begin Tag.
109
- if ( $has_self_closer ) { // If it presents itself as a self-closing tag...
110
- // ...but it isn't a known single-entity self-closing tag, then don't let it be treated as such and
111
- // immediately close it with a closing tag (the tag will encapsulate no text as a result)
112
- if ( ! $is_single_tag ) {
113
- $attributes = trim( substr( $attributes, 0, -1 ) ) . "></$tag";
114
- }
115
- } elseif ( $is_single_tag ) { // ElseIf it's a known single-entity tag but it doesn't close itself, do so
116
- $pre_attribute_ws = ' ';
117
- $attributes .= 0 < strlen( $attributes ) ? ' /' : '/'; // EDIT: If there are attributes, add space before closing tag to match how WP insert br, hr and img tags.
118
- } else { // It's not a single-entity tag.
119
- // If the top of the stack is the same as the tag we want to push, close previous tag.
120
- if ( $stacksize > 0 && ! in_array( $tag, $nestable_tags, true ) && $tagstack[ $stacksize - 1 ] === $tag ) {
121
- $tagqueue = '</' . array_pop( $tagstack ) . '>';
122
- $stacksize--;
123
- }
124
- $stacksize = array_push( $tagstack, $tag );
125
- }
126
-
127
- // Attributes.
128
- if ( $has_self_closer && $is_single_tag ) {
129
- // We need some space - avoid <br/> and prefer <br />.
130
- $pre_attribute_ws = ' ';
131
- }
132
-
133
- $tag = '<' . $tag . $pre_attribute_ws . $attributes . '>';
134
- // If already queuing a close tag, then put this tag on too.
135
- if ( ! empty( $tagqueue ) ) {
136
- $tagqueue .= $tag;
137
- $tag = '';
138
- }
139
- }
140
- $newtext .= substr( $text, 0, $i ) . $tag;
141
- $text = substr( $text, $i + $l );
142
- }
143
-
144
- // Clear Tag Queue.
145
- $newtext .= $tagqueue;
146
-
147
- // Add remaining text.
148
- $newtext .= $text;
149
-
150
- while ( $x = array_pop( $tagstack ) ) {
151
- $newtext .= '</' . $x . '>'; // Add remaining tags to close.
152
- }
153
-
154
- // WP fix for the bug with HTML comments.
155
- $newtext = str_replace( '< !--', '<!--', $newtext );
156
- $newtext = str_replace( '< !--', '< !--', $newtext );
157
-
158
- return $newtext;
159
- }
160
-
161
- /**
162
- * Multibyte substr_replace(). The mbstring library does not come with a multibyte equivalent of substr_replace().
163
- * This function behaves exactly like substr_replace() even when the arguments are arrays.
164
- *
165
- * @link https://gist.github.com/stemar/8287074
166
- *
167
- * @since 2.0
168
- *
169
- * @param $string
170
- * @param $replacement
171
- * @param $start
172
- * @param null $length
173
- *
174
- * @return array|string
175
- */
176
- function mb_substr_replace( $string, $replacement, $start, $length = null ) {
177
-
178
- if ( is_array( $string ) ) {
179
-
180
- $num = count( $string );
181
-
182
- // $replacement
183
- $replacement = is_array( $replacement ) ? array_slice( $replacement, 0, $num ) : array_pad( array( $replacement ), $num, $replacement );
184
-
185
- // $start
186
- if ( is_array( $start ) ) {
187
- $start = array_slice( $start, 0, $num );
188
- foreach ( $start as $key => $value ) {
189
- $start[ $key ] = is_int( $value ) ? $value : 0;
190
- }
191
- } else {
192
- $start = array_pad( array( $start ), $num, $start );
193
- }
194
-
195
- // $length
196
- if ( ! isset( $length ) ) {
197
- $length = array_fill( 0, $num, 0 );
198
- } elseif ( is_array( $length ) ) {
199
- $length = array_slice( $length, 0, $num );
200
- foreach ( $length as $key => $value ) {
201
- $length[ $key ] = isset( $value ) ? ( is_int( $value ) ? $value : $num ) : 0;
202
- }
203
- } else {
204
- $length = array_pad( array( $length ), $num, $length );
205
- }
206
-
207
- // Recursive call
208
- return array_map( __FUNCTION__, $string, $replacement, $start, $length );
209
- }
210
-
211
- preg_match_all( '/./us', (string) $string, $smatches );
212
- preg_match_all( '/./us', (string) $replacement, $rmatches );
213
-
214
- if ( $length === null ) {
215
-
216
- $length = mb_strlen( $string );
217
- }
218
-
219
- array_splice( $smatches[0], $start, $length, $rmatches[0] );
220
-
221
- return join( $smatches[0] );
222
- }
223
-
224
- /**
225
- * Returns a string with all items from the $find array replaced with their matching
226
- * items in the $replace array. This does a one to one replacement (rather than globally).
227
- *
228
- * This function is multibyte safe.
229
- *
230
- * $find and $replace are arrays, $string is the haystack. All variables are passed by reference.
231
- *
232
- * @since 1.0
233
- *
234
- * @param bool $find
235
- * @param bool $replace
236
- * @param string $string
237
- *
238
- * @return mixed|string
239
- */
240
- function mb_find_replace( &$find = false, &$replace = false, &$string = '' ) {
241
-
242
- if ( is_array( $find ) && is_array( $replace ) && $string ) {
243
-
244
- // check if multibyte strings are supported
245
- if ( function_exists( 'mb_strpos' ) ) {
246
-
247
- //for ( $i = 0; $i < count( $find ); $i ++ ) {
248
- //
249
- // $string = mb_substr(
250
- // $string,
251
- // 0,
252
- // mb_strpos( $string, $find[ $i ] )
253
- // ) . // everything before $find
254
- // $replace[ $i ] . // its replacement
255
- // mb_substr(
256
- // $string,
257
- // mb_strpos( $string, $find[ $i ] ) + mb_strlen( $find[ $i ] )
258
- // ) // everything after $find
259
- // ;
260
- //}
261
-
262
- for ( $i = 0; $i < count( $find ); $i ++ ) {
263
-
264
- $start = mb_strpos( $string, $find[ $i ] );
265
- $length = mb_strlen( $find[ $i ] );
266
-
267
- /*
268
- * `mb_strpos()` can return `false`. Only process `mb_substr_replace()` if position in string is found.
269
- */
270
- if ( is_int( $start ) ) {
271
-
272
- $string = mb_substr_replace( $string, $replace[ $i ], $start, $length );
273
- }
274
-
275
- }
276
-
277
- } else {
278
-
279
- for ( $i = 0; $i < count( $find ); $i ++ ) {
280
-
281
- $start = strpos( $string, $find[ $i ] );
282
- $length = strlen( $find[ $i ] );
283
-
284
- /*
285
- * `strpos()` can return `false`. Only process `substr_replace()` if position in string is found.
286
- */
287
- if ( is_int( $start ) ) {
288
-
289
- $string = substr_replace( $string, $replace[ $i ], $start, $length );
290
- }
291
- }
292
- }
293
- }
294
-
295
- return $string;
296
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/ultimate-web-scraper/cacert.pem DELETED
@@ -1,3314 +0,0 @@
1
- ##
2
- ## Bundle of CA Root Certificates
3
- ##
4
- ## Certificate data from Mozilla as of: Wed Jun 20 03:12:06 2018 GMT
5
- ##
6
- ## This is a bundle of X.509 certificates of public Certificate Authorities
7
- ## (CA). These were automatically extracted from Mozilla's root certificates
8
- ## file (certdata.txt). This file can be found in the mozilla source tree:
9
- ## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt
10
- ##
11
- ## It contains the certificates in PEM format and therefore
12
- ## can be directly used with curl / libcurl / php_curl, or with
13
- ## an Apache+mod_ssl webserver for SSL client authentication.
14
- ## Just configure this file as the SSLCACertificateFile.
15
- ##
16
- ## Conversion done with mk-ca-bundle.pl version 1.27.
17
- ## SHA256: c80f571d9f4ebca4a91e0ad3a546f263153d71afffc845c6f8f52ce9d1a2e8ec
18
- ##
19
-
20
-
21
- GlobalSign Root CA
22
- ==================
23
- -----BEGIN CERTIFICATE-----
24
- MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
25
- GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
26
- b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
27
- BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
28
- VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
29
- DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
30
- THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
31
- Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
32
- c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
33
- gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
34
- HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
35
- AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
36
- Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
37
- j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
38
- hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
39
- X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
40
- -----END CERTIFICATE-----
41
-
42
- GlobalSign Root CA - R2
43
- =======================
44
- -----BEGIN CERTIFICATE-----
45
- MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv
46
- YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
47
- bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
48
- aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
49
- bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6
50
- ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp
51
- s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN
52
- S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL
53
- TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C
54
- ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
55
- FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i
56
- YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN
57
- BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
58
- 9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu
59
- 01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7
60
- 9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
61
- TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
62
- -----END CERTIFICATE-----
63
-
64
- Verisign Class 3 Public Primary Certification Authority - G3
65
- ============================================================
66
- -----BEGIN CERTIFICATE-----
67
- MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
68
- UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
69
- cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
70
- IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
71
- dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
72
- CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
73
- dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
74
- cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
75
- Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
76
- ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
77
- EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
78
- cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
79
- EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
80
- 055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
81
- ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
82
- j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
83
- /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
84
- xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
85
- t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
86
- -----END CERTIFICATE-----
87
-
88
- Entrust.net Premium 2048 Secure Server CA
89
- =========================================
90
- -----BEGIN CERTIFICATE-----
91
- MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
92
- ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp
93
- bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
94
- BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx
95
- NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
96
- d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
97
- MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
98
- ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
99
- MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL
100
- Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr
101
- hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW
102
- nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi
103
- VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E
104
- BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ
105
- KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy
106
- T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
107
- zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT
108
- J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e
109
- nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE=
110
- -----END CERTIFICATE-----
111
-
112
- Baltimore CyberTrust Root
113
- =========================
114
- -----BEGIN CERTIFICATE-----
115
- MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE
116
- ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li
117
- ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC
118
- SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs
119
- dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME
120
- uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB
121
- UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C
122
- G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9
123
- XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr
124
- l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI
125
- VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB
126
- BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh
127
- cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5
128
- hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa
129
- Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
130
- RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
131
- -----END CERTIFICATE-----
132
-
133
- AddTrust External Root
134
- ======================
135
- -----BEGIN CERTIFICATE-----
136
- MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
137
- QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD
138
- VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw
139
- NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU
140
- cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg
141
- Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821
142
- +iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw
143
- Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo
144
- aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy
145
- 2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7
146
- 7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P
147
- BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL
148
- VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk
149
- VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB
150
- IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl
151
- j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
152
- 6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355
153
- e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u
154
- G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
155
- -----END CERTIFICATE-----
156
-
157
- Entrust Root Certification Authority
158
- ====================================
159
- -----BEGIN CERTIFICATE-----
160
- MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV
161
- BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw
162
- b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG
163
- A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0
164
- MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu
165
- MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu
166
- Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v
167
- dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
168
- ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz
169
- A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww
170
- Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68
171
- j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN
172
- rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw
173
- DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1
174
- MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH
175
- hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
176
- A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM
177
- Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa
178
- v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS
179
- W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0
180
- tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8
181
- -----END CERTIFICATE-----
182
-
183
- GeoTrust Global CA
184
- ==================
185
- -----BEGIN CERTIFICATE-----
186
- MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
187
- Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw
188
- MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
189
- LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
190
- CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo
191
- BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet
192
- 8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc
193
- T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU
194
- vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD
195
- AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk
196
- DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q
197
- zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4
198
- d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2
199
- mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p
200
- XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm
201
- Mw==
202
- -----END CERTIFICATE-----
203
-
204
- GeoTrust Universal CA
205
- =====================
206
- -----BEGIN CERTIFICATE-----
207
- MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
208
- R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1
209
- MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu
210
- Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
211
- ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t
212
- JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e
213
- RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs
214
- 7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d
215
- 8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V
216
- qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga
217
- Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB
218
- Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu
219
- KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08
220
- ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0
221
- XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB
222
- hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
223
- aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2
224
- qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL
225
- oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK
226
- xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF
227
- KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2
228
- DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK
229
- xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU
230
- p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI
231
- P/rmMuGNG2+k5o7Y+SlIis5z/iw=
232
- -----END CERTIFICATE-----
233
-
234
- GeoTrust Universal CA 2
235
- =======================
236
- -----BEGIN CERTIFICATE-----
237
- MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
238
- R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0
239
- MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg
240
- SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA
241
- A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0
242
- DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17
243
- j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q
244
- JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a
245
- QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2
246
- WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP
247
- 20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn
248
- ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC
249
- SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG
250
- 8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2
251
- +/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E
252
- BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
253
- dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ
254
- 4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+
255
- mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq
256
- A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg
257
- Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP
258
- pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d
259
- FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp
260
- gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm
261
- X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
262
- -----END CERTIFICATE-----
263
-
264
- Visa eCommerce Root
265
- ===================
266
- -----BEGIN CERTIFICATE-----
267
- MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG
268
- EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug
269
- QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2
270
- WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm
271
- VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
272
- bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL
273
- F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b
274
- RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0
275
- TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI
276
- /k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs
277
- GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
278
- MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc
279
- CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW
280
- YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz
281
- zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu
282
- YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
283
- 398znM/jra6O1I7mT1GvFpLgXPYHDw==
284
- -----END CERTIFICATE-----
285
-
286
- Comodo AAA Services root
287
- ========================
288
- -----BEGIN CERTIFICATE-----
289
- MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
290
- R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
291
- TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw
292
- MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl
293
- c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
294
- BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
295
- ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG
296
- C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs
297
- i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW
298
- Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH
299
- Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK
300
- Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f
301
- BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl
302
- cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz
303
- LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm
304
- 7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
305
- Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z
306
- 8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C
307
- 12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
308
- -----END CERTIFICATE-----
309
-
310
- QuoVadis Root CA
311
- ================
312
- -----BEGIN CERTIFICATE-----
313
- MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE
314
- ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
315
- eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz
316
- MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp
317
- cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD
318
- EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
319
- AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk
320
- J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL
321
- F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL
322
- YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen
323
- AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w
324
- PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y
325
- ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7
326
- MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj
327
- YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs
328
- ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
329
- Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW
330
- Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu
331
- BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw
332
- FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0
333
- aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6
334
- tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo
335
- fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul
336
- LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x
337
- gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi
338
- 5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi
339
- 5nrQNiOKSnQ2+Q==
340
- -----END CERTIFICATE-----
341
-
342
- QuoVadis Root CA 2
343
- ==================
344
- -----BEGIN CERTIFICATE-----
345
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy
353
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm
364
- 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
- +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
- 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
- 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
- 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
- 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
- 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
371
- -----END CERTIFICATE-----
372
-
373
- QuoVadis Root CA 3
374
- ==================
375
- -----BEGIN CERTIFICATE-----
376
- MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
377
- EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx
378
- OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
379
- aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
380
- DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg
381
- DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij
382
- KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K
383
- DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv
384
- BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp
385
- p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8
386
- nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX
387
- MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM
388
- Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz
389
- uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT
390
- BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj
391
- YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
392
- aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB
393
- BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD
394
- VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4
395
- ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE
396
- AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV
397
- qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s
398
- hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z
399
- POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2
400
- Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp
401
- 8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC
402
- bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu
403
- g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p
404
- vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr
405
- qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=
406
- -----END CERTIFICATE-----
407
-
408
- Security Communication Root CA
409
- ==============================
410
- -----BEGIN CERTIFICATE-----
411
- MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
412
- U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
413
- HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
414
- U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
415
- ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw
416
- 8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM
417
- DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX
418
- 5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd
419
- DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2
420
- JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw
421
- DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g
422
- 0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a
423
- mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ
424
- s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ
425
- 6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi
426
- FL39vmwLAw==
427
- -----END CERTIFICATE-----
428
-
429
- Sonera Class 2 Root CA
430
- ======================
431
- -----BEGIN CERTIFICATE-----
432
- MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
433
- U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw
434
- NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
435
- IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3
436
- /Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT
437
- dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG
438
- f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P
439
- tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH
440
- nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT
441
- XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt
442
- 0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI
443
- cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph
444
- Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx
445
- EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH
446
- llpwrN9M
447
- -----END CERTIFICATE-----
448
-
449
- XRamp Global CA Root
450
- ====================
451
- -----BEGIN CERTIFICATE-----
452
- MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE
453
- BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj
454
- dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
455
- dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx
456
- HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg
457
- U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
458
- dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu
459
- IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx
460
- foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE
461
- zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs
462
- AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry
463
- xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
464
- EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap
465
- oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC
466
- AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc
467
- /Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
468
- qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n
469
- nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz
470
- 8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw=
471
- -----END CERTIFICATE-----
472
-
473
- Go Daddy Class 2 CA
474
- ===================
475
- -----BEGIN CERTIFICATE-----
476
- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY
477
- VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp
478
- ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG
479
- A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
480
- RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD
481
- ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
482
- 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32
483
- qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j
484
- YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY
485
- vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O
486
- BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o
487
- atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu
488
- MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG
489
- A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim
490
- PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt
491
- I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
492
- HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI
493
- Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b
494
- vZ8=
495
- -----END CERTIFICATE-----
496
-
497
- Starfield Class 2 CA
498
- ====================
499
- -----BEGIN CERTIFICATE-----
500
- MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc
501
- U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg
502
- Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo
503
- MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG
504
- A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG
505
- SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY
506
- bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ
507
- JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm
508
- epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN
509
- F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF
510
- MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f
511
- hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo
512
- bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g
513
- QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs
514
- afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM
515
- PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
516
- xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD
517
- KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3
518
- QBFGmh95DmK/D5fs4C8fF5Q=
519
- -----END CERTIFICATE-----
520
-
521
- Taiwan GRCA
522
- ===========
523
- -----BEGIN CERTIFICATE-----
524
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7
534
- Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t
535
- 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
- O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8
537
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy
548
- +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
549
- -----END CERTIFICATE-----
550
-
551
- DigiCert Assured ID Root CA
552
- ===========================
553
- -----BEGIN CERTIFICATE-----
554
- MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG
555
- EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
556
- IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx
557
- MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
558
- ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew
559
- ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO
560
- 9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy
561
- UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW
562
- /lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy
563
- oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf
564
- GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF
565
- 66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq
566
- hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc
567
- EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn
568
- SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i
569
- 8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
570
- +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
571
- -----END CERTIFICATE-----
572
-
573
- DigiCert Global Root CA
574
- =======================
575
- -----BEGIN CERTIFICATE-----
576
- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG
577
- EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
578
- HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw
579
- MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
580
- dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq
581
- hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn
582
- TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5
583
- BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H
584
- 4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y
585
- 7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB
586
- o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm
587
- 8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF
588
- BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr
589
- EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt
590
- tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886
591
- UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
592
- CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
593
- -----END CERTIFICATE-----
594
-
595
- DigiCert High Assurance EV Root CA
596
- ==================================
597
- -----BEGIN CERTIFICATE-----
598
- MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
599
- EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
600
- KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
601
- MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
602
- MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
603
- Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
604
- Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
605
- OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
606
- MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
607
- NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
608
- h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
609
- Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
610
- JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
611
- V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
612
- myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
613
- mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
614
- vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
615
- -----END CERTIFICATE-----
616
-
617
- Certplus Class 2 Primary CA
618
- ===========================
619
- -----BEGIN CERTIFICATE-----
620
- MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE
621
- BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN
622
- OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy
623
- dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
624
- ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR
625
- 5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ
626
- Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO
627
- YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e
628
- e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME
629
- CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ
630
- YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t
631
- L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD
632
- P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R
633
- TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+
634
- 7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW
635
- //1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
636
- l7+ijrRU
637
- -----END CERTIFICATE-----
638
-
639
- DST Root CA X3
640
- ==============
641
- -----BEGIN CERTIFICATE-----
642
- MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK
643
- ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X
644
- DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1
645
- cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD
646
- ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT
647
- rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9
648
- UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy
649
- xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d
650
- utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T
651
- AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ
652
- MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug
653
- dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE
654
- GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw
655
- RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS
656
- fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
657
- -----END CERTIFICATE-----
658
-
659
- SwissSign Gold CA - G2
660
- ======================
661
- -----BEGIN CERTIFICATE-----
662
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend
672
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
688
- -----END CERTIFICATE-----
689
-
690
- SwissSign Silver CA - G2
691
- ========================
692
- -----BEGIN CERTIFICATE-----
693
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5
703
- 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
- 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
- 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
- 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
- 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
- tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
709
- 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
- 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
- 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
- 3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx
713
- /uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa
714
- 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
- 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
- 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
- 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
- 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
719
- -----END CERTIFICATE-----
720
-
721
- GeoTrust Primary Certification Authority
722
- ========================================
723
- -----BEGIN CERTIFICATE-----
724
- MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG
725
- EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD
726
- ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx
727
- CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ
728
- cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
729
- CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN
730
- b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9
731
- nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge
732
- RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt
733
- tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
734
- AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI
735
- hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K
736
- Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN
737
- NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa
738
- Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG
739
- 1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
740
- -----END CERTIFICATE-----
741
-
742
- thawte Primary Root CA
743
- ======================
744
- -----BEGIN CERTIFICATE-----
745
- MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE
746
- BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
747
- aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
748
- cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3
749
- MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg
750
- SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv
751
- KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT
752
- FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs
753
- oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ
754
- 1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc
755
- q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K
756
- aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p
757
- afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
758
- VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF
759
- AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE
760
- uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
761
- xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89
762
- jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH
763
- z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA==
764
- -----END CERTIFICATE-----
765
-
766
- VeriSign Class 3 Public Primary Certification Authority - G5
767
- ============================================================
768
- -----BEGIN CERTIFICATE-----
769
- MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
770
- BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
771
- ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
772
- IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp
773
- ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB
774
- yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln
775
- biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh
776
- dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt
777
- YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
778
- ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz
779
- j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD
780
- Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
781
- Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r
782
- fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/
783
- BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
784
- Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
785
- aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
786
- SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+
787
- X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE
788
- KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC
789
- Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE
790
- ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
791
- -----END CERTIFICATE-----
792
-
793
- SecureTrust CA
794
- ==============
795
- -----BEGIN CERTIFICATE-----
796
- MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG
797
- EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy
798
- dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe
799
- BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC
800
- ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX
801
- OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t
802
- DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH
803
- GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b
804
- 01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH
805
- ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/
806
- BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj
807
- aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
808
- KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu
809
- SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf
810
- mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ
811
- nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
812
- 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
813
- -----END CERTIFICATE-----
814
-
815
- Secure Global CA
816
- ================
817
- -----BEGIN CERTIFICATE-----
818
- MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG
819
- EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH
820
- bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg
821
- MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg
822
- Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx
823
- YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ
824
- bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g
825
- 8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV
826
- HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi
827
- 0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
828
- EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn
829
- oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA
830
- MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+
831
- OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn
832
- CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5
833
- 3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
834
- f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
835
- -----END CERTIFICATE-----
836
-
837
- COMODO Certification Authority
838
- ==============================
839
- -----BEGIN CERTIFICATE-----
840
- MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE
841
- BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
842
- A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1
843
- dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb
844
- MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD
845
- T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
846
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH
847
- +7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww
848
- xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV
849
- 4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA
850
- 1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI
851
- rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E
852
- BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k
853
- b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC
854
- AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP
855
- OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
856
- RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc
857
- IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN
858
- +8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ==
859
- -----END CERTIFICATE-----
860
-
861
- Network Solutions Certificate Authority
862
- =======================================
863
- -----BEGIN CERTIFICATE-----
864
- MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG
865
- EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr
866
- IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx
867
- MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
868
- MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
869
- CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx
870
- jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT
871
- aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT
872
- crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc
873
- /Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB
874
- AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP
875
- BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv
876
- bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA
877
- A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q
878
- 4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/
879
- GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
880
- wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD
881
- ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
882
- -----END CERTIFICATE-----
883
-
884
- COMODO ECC Certification Authority
885
- ==================================
886
- -----BEGIN CERTIFICATE-----
887
- MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC
888
- R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
889
- ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB
890
- dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix
891
- GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
892
- Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo
893
- b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X
894
- 4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni
895
- wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E
896
- BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG
897
- FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA
898
- U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
899
- -----END CERTIFICATE-----
900
-
901
- OISTE WISeKey Global Root GA CA
902
- ===============================
903
- -----BEGIN CERTIFICATE-----
904
- MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE
905
- BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG
906
- A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH
907
- bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD
908
- VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw
909
- IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5
910
- IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9
911
- Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg
912
- Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD
913
- d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ
914
- /yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R
915
- LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
916
- AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
917
- KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm
918
- MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4
919
- +vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
920
- hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY
921
- okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0=
922
- -----END CERTIFICATE-----
923
-
924
- Certigna
925
- ========
926
- -----BEGIN CERTIFICATE-----
927
- MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw
928
- EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3
929
- MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI
930
- Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q
931
- XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH
932
- GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p
933
- ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg
934
- DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf
935
- Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ
936
- tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ
937
- BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J
938
- SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA
939
- hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+
940
- ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu
941
- PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
942
- 1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
943
- WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
944
- -----END CERTIFICATE-----
945
-
946
- Deutsche Telekom Root CA 2
947
- ==========================
948
- -----BEGIN CERTIFICATE-----
949
- MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT
950
- RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG
951
- A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5
952
- MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G
953
- A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS
954
- b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5
955
- bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI
956
- KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY
957
- AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK
958
- Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV
959
- jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV
960
- HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr
961
- E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy
962
- zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8
963
- rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G
964
- dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
965
- Cm26OWMohpLzGITY+9HPBVZkVw==
966
- -----END CERTIFICATE-----
967
-
968
- Cybertrust Global Root
969
- ======================
970
- -----BEGIN CERTIFICATE-----
971
- MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li
972
- ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4
973
- MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD
974
- ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
975
- +Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW
976
- 0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL
977
- AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin
978
- 89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT
979
- 8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP
980
- BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2
981
- MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G
982
- A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO
983
- lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi
984
- 5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2
985
- hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T
986
- X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
987
- WL1WMRJOEcgh4LMRkWXbtKaIOM5V
988
- -----END CERTIFICATE-----
989
-
990
- ePKI Root Certification Authority
991
- =================================
992
- -----BEGIN CERTIFICATE-----
993
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O
1003
- 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
- ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao
1005
- 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
- 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
- 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
- MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
1009
- 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
- 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
- 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
- xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP
1013
- 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
- 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
- xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx
1016
- 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
- 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
- BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw=
1019
- -----END CERTIFICATE-----
1020
-
1021
- certSIGN ROOT CA
1022
- ================
1023
- -----BEGIN CERTIFICATE-----
1024
- MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD
1025
- VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa
1026
- Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE
1027
- CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I
1028
- JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH
1029
- rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2
1030
- ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD
1031
- 0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943
1032
- AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
1033
- Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB
1034
- AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8
1035
- SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0
1036
- x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt
1037
- vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz
1038
- TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD
1039
- -----END CERTIFICATE-----
1040
-
1041
- GeoTrust Primary Certification Authority - G3
1042
- =============================================
1043
- -----BEGIN CERTIFICATE-----
1044
- MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE
1045
- BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0
1046
- IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy
1047
- eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz
1048
- NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo
1049
- YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT
1050
- LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI
1051
- hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j
1052
- K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE
1053
- c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C
1054
- IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu
1055
- dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC
1056
- MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr
1057
- 2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9
1058
- cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE
1059
- Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
1060
- AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s
1061
- t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt
1062
- -----END CERTIFICATE-----
1063
-
1064
- thawte Primary Root CA - G2
1065
- ===========================
1066
- -----BEGIN CERTIFICATE-----
1067
- MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC
1068
- VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu
1069
- IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg
1070
- Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV
1071
- MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG
1072
- b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt
1073
- IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS
1074
- LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5
1075
- 8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
1076
- mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN
1077
- G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K
1078
- rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
1079
- -----END CERTIFICATE-----
1080
-
1081
- thawte Primary Root CA - G3
1082
- ===========================
1083
- -----BEGIN CERTIFICATE-----
1084
- MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE
1085
- BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
1086
- aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
1087
- cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w
1088
- ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
1089
- d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD
1090
- VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG
1091
- A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
1092
- MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At
1093
- P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC
1094
- +BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY
1095
- 7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW
1096
- vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E
1097
- BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ
1098
- KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK
1099
- A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
1100
- t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC
1101
- 8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm
1102
- er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A=
1103
- -----END CERTIFICATE-----
1104
-
1105
- GeoTrust Primary Certification Authority - G2
1106
- =============================================
1107
- -----BEGIN CERTIFICATE-----
1108
- MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC
1109
- VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu
1110
- Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD
1111
- ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1
1112
- OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
1113
- MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl
1114
- b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG
1115
- BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc
1116
- KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD
1117
- VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+
1118
- EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m
1119
- ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2
1120
- npaqBA+K
1121
- -----END CERTIFICATE-----
1122
-
1123
- VeriSign Universal Root Certification Authority
1124
- ===============================================
1125
- -----BEGIN CERTIFICATE-----
1126
- MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE
1127
- BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
1128
- ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
1129
- IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u
1130
- IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV
1131
- UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
1132
- cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
1133
- IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0
1134
- aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj
1135
- 1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP
1136
- MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72
1137
- 9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I
1138
- AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR
1139
- tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G
1140
- CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O
1141
- a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
1142
- DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3
1143
- Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx
1144
- Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx
1145
- P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P
1146
- wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4
1147
- mJO37M2CYfE45k+XmCpajQ==
1148
- -----END CERTIFICATE-----
1149
-
1150
- VeriSign Class 3 Public Primary Certification Authority - G4
1151
- ============================================================
1152
- -----BEGIN CERTIFICATE-----
1153
- MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC
1154
- VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3
1155
- b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz
1156
- ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj
1157
- YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL
1158
- MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
1159
- cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo
1160
- b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5
1161
- IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8
1162
- Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz
1163
- rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB
1164
- /zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw
1165
- HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u
1166
- Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD
1167
- A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx
1168
- AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
1169
- -----END CERTIFICATE-----
1170
-
1171
- NetLock Arany (Class Gold) Főtanúsítvány
1172
- ========================================
1173
- -----BEGIN CERTIFICATE-----
1174
- MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G
1175
- A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610
1176
- dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB
1177
- cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx
1178
- MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO
1179
- ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv
1180
- biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6
1181
- c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu
1182
- 0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw
1183
- /HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk
1184
- H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw
1185
- fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1
1186
- neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB
1187
- BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW
1188
- qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta
1189
- YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
1190
- bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna
1191
- NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
1192
- dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
1193
- -----END CERTIFICATE-----
1194
-
1195
- Staat der Nederlanden Root CA - G2
1196
- ==================================
1197
- -----BEGIN CERTIFICATE-----
1198
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN
1218
- 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
- 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
- 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
- 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
- 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
- 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
1224
- 66+KAQ==
1225
- -----END CERTIFICATE-----
1226
-
1227
- Hongkong Post Root CA 1
1228
- =======================
1229
- -----BEGIN CERTIFICATE-----
1230
- MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT
1231
- DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx
1232
- NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n
1233
- IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF
1234
- AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1
1235
- ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr
1236
- auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh
1237
- qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY
1238
- V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV
1239
- HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i
1240
- h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio
1241
- l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei
1242
- IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps
1243
- T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT
1244
- c4afU9hDDl3WY4JxHYB0yvbiAmvZWg==
1245
- -----END CERTIFICATE-----
1246
-
1247
- SecureSign RootCA11
1248
- ===================
1249
- -----BEGIN CERTIFICATE-----
1250
- MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi
1251
- SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS
1252
- b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw
1253
- KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1
1254
- cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL
1255
- TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO
1256
- wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq
1257
- g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP
1258
- O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA
1259
- bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX
1260
- t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh
1261
- OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r
1262
- bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ
1263
- Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01
1264
- y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061
1265
- lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=
1266
- -----END CERTIFICATE-----
1267
-
1268
- Microsec e-Szigno Root CA 2009
1269
- ==============================
1270
- -----BEGIN CERTIFICATE-----
1271
- MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER
1272
- MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv
1273
- c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
1274
- dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE
1275
- BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt
1276
- U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw
1277
- DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA
1278
- fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG
1279
- 0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA
1280
- pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm
1281
- 1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC
1282
- AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf
1283
- QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE
1284
- FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o
1285
- lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX
1286
- I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
1287
- tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02
1288
- yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi
1289
- LXpUq3DDfSJlgnCW
1290
- -----END CERTIFICATE-----
1291
-
1292
- GlobalSign Root CA - R3
1293
- =======================
1294
- -----BEGIN CERTIFICATE-----
1295
- MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv
1296
- YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
1297
- bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
1298
- aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
1299
- bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt
1300
- iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ
1301
- 0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3
1302
- rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl
1303
- OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2
1304
- xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
1305
- FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7
1306
- lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8
1307
- EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E
1308
- bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18
1309
- YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r
1310
- kpeDMdmztcpHWD9f
1311
- -----END CERTIFICATE-----
1312
-
1313
- Autoridad de Certificacion Firmaprofesional CIF A62634068
1314
- =========================================================
1315
- -----BEGIN CERTIFICATE-----
1316
- MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA
1317
- BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
1318
- MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw
1319
- QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB
1320
- NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD
1321
- Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P
1322
- B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY
1323
- 7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH
1324
- ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI
1325
- plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX
1326
- MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX
1327
- LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK
1328
- bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU
1329
- vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud
1330
- EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH
1331
- DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
1332
- cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA
1333
- bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx
1334
- ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx
1335
- 51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk
1336
- R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP
1337
- T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f
1338
- Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl
1339
- osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR
1340
- crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR
1341
- saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD
1342
- KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi
1343
- 6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
1344
- -----END CERTIFICATE-----
1345
-
1346
- Izenpe.com
1347
- ==========
1348
- -----BEGIN CERTIFICATE-----
1349
- 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
- EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz
1351
- 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
- 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
- 03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK
1354
- 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
- +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
- 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
- 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
- F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK
1359
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga
1368
- 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
- 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
- g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5
1371
- 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
- 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
- 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
- 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
- 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
1376
- -----END CERTIFICATE-----
1377
-
1378
- Chambers of Commerce Root - 2008
1379
- ================================
1380
- -----BEGIN CERTIFICATE-----
1381
- MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD
1382
- MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
1383
- bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
1384
- QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy
1385
- Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl
1386
- ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF
1387
- EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl
1388
- cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
1389
- AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA
1390
- XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj
1391
- h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/
1392
- ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk
1393
- NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g
1394
- D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331
1395
- lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ
1396
- 0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
1397
- ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2
1398
- EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI
1399
- G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ
1400
- BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh
1401
- bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh
1402
- bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC
1403
- CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH
1404
- AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1
1405
- wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH
1406
- 3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU
1407
- RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6
1408
- M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1
1409
- YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF
1410
- 9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK
1411
- zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG
1412
- nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
1413
- OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ
1414
- -----END CERTIFICATE-----
1415
-
1416
- Global Chambersign Root - 2008
1417
- ==============================
1418
- -----BEGIN CERTIFICATE-----
1419
- MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD
1420
- MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
1421
- bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
1422
- QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx
1423
- NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg
1424
- Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ
1425
- QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
1426
- aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf
1427
- VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf
1428
- XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0
1429
- ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB
1430
- /gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA
1431
- TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M
1432
- H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe
1433
- Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF
1434
- HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
1435
- wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB
1436
- AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT
1437
- BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE
1438
- BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm
1439
- aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm
1440
- aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp
1441
- 1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0
1442
- dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG
1443
- /5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6
1444
- ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s
1445
- dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg
1446
- 9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH
1447
- foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du
1448
- qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr
1449
- P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq
1450
- c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
1451
- 09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
1452
- -----END CERTIFICATE-----
1453
-
1454
- Go Daddy Root Certificate Authority - G2
1455
- ========================================
1456
- -----BEGIN CERTIFICATE-----
1457
- MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
1458
- B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu
1459
- MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
1460
- MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
1461
- b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G
1462
- A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
1463
- hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq
1464
- 9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD
1465
- +qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd
1466
- fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl
1467
- NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC
1468
- MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9
1469
- BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac
1470
- vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r
1471
- 5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV
1472
- N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
1473
- LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1
1474
- -----END CERTIFICATE-----
1475
-
1476
- Starfield Root Certificate Authority - G2
1477
- =========================================
1478
- -----BEGIN CERTIFICATE-----
1479
- MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
1480
- B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
1481
- b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
1482
- eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw
1483
- DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg
1484
- VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB
1485
- dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv
1486
- W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs
1487
- bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk
1488
- N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf
1489
- ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU
1490
- JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
1491
- AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol
1492
- TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx
1493
- 4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw
1494
- F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
1495
- pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ
1496
- c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
1497
- -----END CERTIFICATE-----
1498
-
1499
- Starfield Services Root Certificate Authority - G2
1500
- ==================================================
1501
- -----BEGIN CERTIFICATE-----
1502
- MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
1503
- B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
1504
- b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl
1505
- IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV
1506
- BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT
1507
- dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg
1508
- Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
1509
- AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2
1510
- h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa
1511
- hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP
1512
- LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB
1513
- rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
1514
- AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG
1515
- SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP
1516
- E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy
1517
- xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
1518
- iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza
1519
- YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6
1520
- -----END CERTIFICATE-----
1521
-
1522
- AffirmTrust Commercial
1523
- ======================
1524
- -----BEGIN CERTIFICATE-----
1525
- MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS
1526
- BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw
1527
- MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
1528
- bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF
1529
- AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb
1530
- DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV
1531
- C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6
1532
- BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww
1533
- MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV
1534
- HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
1535
- AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG
1536
- hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi
1537
- qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv
1538
- 0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh
1539
- sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
1540
- -----END CERTIFICATE-----
1541
-
1542
- AffirmTrust Networking
1543
- ======================
1544
- -----BEGIN CERTIFICATE-----
1545
- MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS
1546
- BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw
1547
- MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
1548
- bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF
1549
- AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE
1550
- Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI
1551
- dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24
1552
- /PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb
1553
- h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV
1554
- HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
1555
- AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu
1556
- UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6
1557
- 12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23
1558
- WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9
1559
- /ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
1560
- -----END CERTIFICATE-----
1561
-
1562
- AffirmTrust Premium
1563
- ===================
1564
- -----BEGIN CERTIFICATE-----
1565
- MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS
1566
- BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy
1567
- OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy
1568
- dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
1569
- MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn
1570
- BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV
1571
- 5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs
1572
- +7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd
1573
- GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R
1574
- p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI
1575
- S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04
1576
- 6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5
1577
- /bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo
1578
- +Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB
1579
- /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv
1580
- MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
1581
- Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC
1582
- 6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S
1583
- L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK
1584
- +4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV
1585
- BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg
1586
- IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60
1587
- g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb
1588
- zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw==
1589
- -----END CERTIFICATE-----
1590
-
1591
- AffirmTrust Premium ECC
1592
- =======================
1593
- -----BEGIN CERTIFICATE-----
1594
- MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV
1595
- BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx
1596
- MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U
1597
- cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA
1598
- IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ
1599
- N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW
1600
- BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK
1601
- BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X
1602
- 57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM
1603
- eQ==
1604
- -----END CERTIFICATE-----
1605
-
1606
- Certum Trusted Network CA
1607
- =========================
1608
- -----BEGIN CERTIFICATE-----
1609
- MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK
1610
- ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv
1611
- biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy
1612
- MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU
1613
- ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
1614
- MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
1615
- AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC
1616
- l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J
1617
- J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4
1618
- fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0
1619
- cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB
1620
- Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw
1621
- DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj
1622
- jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1
1623
- mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj
1624
- Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
1625
- 03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
1626
- -----END CERTIFICATE-----
1627
-
1628
- TWCA Root Certification Authority
1629
- =================================
1630
- -----BEGIN CERTIFICATE-----
1631
- MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ
1632
- VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh
1633
- dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG
1634
- EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB
1635
- IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
1636
- AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx
1637
- QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC
1638
- oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP
1639
- 4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r
1640
- y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB
1641
- BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG
1642
- 9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC
1643
- mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW
1644
- QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY
1645
- T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny
1646
- Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
1647
- -----END CERTIFICATE-----
1648
-
1649
- Security Communication RootCA2
1650
- ==============================
1651
- -----BEGIN CERTIFICATE-----
1652
- MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
1653
- U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh
1654
- dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC
1655
- SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy
1656
- aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
1657
- ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++
1658
- +T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R
1659
- 3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV
1660
- spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K
1661
- EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8
1662
- QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB
1663
- CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj
1664
- u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk
1665
- 3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q
1666
- tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29
1667
- mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
1668
- -----END CERTIFICATE-----
1669
-
1670
- EC-ACC
1671
- ======
1672
- -----BEGIN CERTIFICATE-----
1673
- MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE
1674
- BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w
1675
- ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD
1676
- VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE
1677
- CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT
1678
- BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7
1679
- MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt
1680
- SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl
1681
- Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh
1682
- cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND
1683
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK
1684
- w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT
1685
- ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4
1686
- HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a
1687
- E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw
1688
- 0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
1689
- BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD
1690
- VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0
1691
- Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l
1692
- dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ
1693
- lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa
1694
- Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe
1695
- l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2
1696
- E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D
1697
- 5EI=
1698
- -----END CERTIFICATE-----
1699
-
1700
- Hellenic Academic and Research Institutions RootCA 2011
1701
- =======================================================
1702
- -----BEGIN CERTIFICATE-----
1703
- MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT
1704
- O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y
1705
- aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
1706
- IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT
1707
- AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
1708
- IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo
1709
- IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
1710
- AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI
1711
- 1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa
1712
- 71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u
1713
- 8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH
1714
- 3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/
1715
- MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8
1716
- MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu
1717
- b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt
1718
- XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
1719
- TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD
1720
- /md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N
1721
- 7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4
1722
- -----END CERTIFICATE-----
1723
-
1724
- Actalis Authentication Root CA
1725
- ==============================
1726
- -----BEGIN CERTIFICATE-----
1727
- MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM
1728
- BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE
1729
- AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky
1730
- MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz
1731
- IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
1732
- IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ
1733
- wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa
1734
- by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6
1735
- zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f
1736
- YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2
1737
- oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l
1738
- EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7
1739
- hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8
1740
- EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5
1741
- jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY
1742
- iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
1743
- ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI
1744
- WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0
1745
- JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx
1746
- K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+
1747
- Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC
1748
- 4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo
1749
- 2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz
1750
- lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem
1751
- OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9
1752
- vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
1753
- -----END CERTIFICATE-----
1754
-
1755
- Trustis FPS Root CA
1756
- ===================
1757
- -----BEGIN CERTIFICATE-----
1758
- MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG
1759
- EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290
1760
- IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV
1761
- BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ
1762
- KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ
1763
- RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk
1764
- H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa
1765
- cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt
1766
- o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA
1767
- AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd
1768
- BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c
1769
- GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC
1770
- yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P
1771
- 8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV
1772
- l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl
1773
- iB6XzCGcKQENZetX2fNXlrtIzYE=
1774
- -----END CERTIFICATE-----
1775
-
1776
- Buypass Class 2 Root CA
1777
- =======================
1778
- -----BEGIN CERTIFICATE-----
1779
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs
1792
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
1803
- rJgWVqA=
1804
- -----END CERTIFICATE-----
1805
-
1806
- Buypass Class 3 Root CA
1807
- =======================
1808
- -----BEGIN CERTIFICATE-----
1809
- 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
- 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
- DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
1812
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
1823
- 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
- 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
- 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
- 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
- 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
- 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
- KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz
1830
- 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
- UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe
1832
- 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
1833
- Cp/HuZc=
1834
- -----END CERTIFICATE-----
1835
-
1836
- T-TeleSec GlobalRoot Class 3
1837
- ============================
1838
- -----BEGIN CERTIFICATE-----
1839
- MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
1840
- IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
1841
- cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx
1842
- MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
1843
- dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
1844
- ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3
1845
- DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK
1846
- 9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU
1847
- NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF
1848
- iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W
1849
- 0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA
1850
- MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr
1851
- AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb
1852
- fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT
1853
- ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h
1854
- P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
1855
- e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw==
1856
- -----END CERTIFICATE-----
1857
-
1858
- EE Certification Centre Root CA
1859
- ===============================
1860
- -----BEGIN CERTIFICATE-----
1861
- MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG
1862
- EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy
1863
- dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw
1864
- MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB
1865
- UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy
1866
- ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
1867
- DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM
1868
- TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2
1869
- rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw
1870
- 93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN
1871
- P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T
1872
- AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ
1873
- MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF
1874
- BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj
1875
- xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM
1876
- lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
1877
- uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU
1878
- 3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM
1879
- dcGWxZ0=
1880
- -----END CERTIFICATE-----
1881
-
1882
- D-TRUST Root Class 3 CA 2 2009
1883
- ==============================
1884
- -----BEGIN CERTIFICATE-----
1885
- MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK
1886
- DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe
1887
- Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE
1888
- LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw
1889
- DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD
1890
- ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA
1891
- BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv
1892
- KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z
1893
- p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC
1894
- AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ
1895
- 4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y
1896
- eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw
1897
- MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G
1898
- PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw
1899
- OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm
1900
- 2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
1901
- o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV
1902
- dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph
1903
- X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I=
1904
- -----END CERTIFICATE-----
1905
-
1906
- D-TRUST Root Class 3 CA 2 EV 2009
1907
- =================================
1908
- -----BEGIN CERTIFICATE-----
1909
- MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK
1910
- DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw
1911
- OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK
1912
- DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw
1913
- OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS
1914
- egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh
1915
- zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T
1916
- 7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60
1917
- sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35
1918
- 11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv
1919
- cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v
1920
- ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El
1921
- MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp
1922
- b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh
1923
- c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+
1924
- PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
1925
- nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX
1926
- ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA
1927
- NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv
1928
- w9y4AyHqnxbxLFS1
1929
- -----END CERTIFICATE-----
1930
-
1931
- CA Disig Root R2
1932
- ================
1933
- -----BEGIN CERTIFICATE-----
1934
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
1958
- 7+ZtsH8tZ/3zbBt1RqPlShfppNcL
1959
- -----END CERTIFICATE-----
1960
-
1961
- ACCVRAIZ1
1962
- =========
1963
- -----BEGIN CERTIFICATE-----
1964
- MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB
1965
- SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1
1966
- MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH
1967
- UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
1968
- DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM
1969
- jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0
1970
- RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD
1971
- aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ
1972
- 0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG
1973
- WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7
1974
- 8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR
1975
- 5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J
1976
- 9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK
1977
- Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw
1978
- Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu
1979
- Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
1980
- VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM
1981
- Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA
1982
- QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh
1983
- AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA
1984
- YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj
1985
- AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA
1986
- IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk
1987
- aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0
1988
- dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2
1989
- MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI
1990
- hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E
1991
- R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN
1992
- YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49
1993
- nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ
1994
- TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3
1995
- sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
1996
- I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg
1997
- Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd
1998
- 3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p
1999
- EfbRD0tVNEYqi4Y7
2000
- -----END CERTIFICATE-----
2001
-
2002
- TWCA Global Root CA
2003
- ===================
2004
- -----BEGIN CERTIFICATE-----
2005
- MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT
2006
- CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD
2007
- QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK
2008
- EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg
2009
- Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C
2010
- nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV
2011
- r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR
2012
- Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV
2013
- tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W
2014
- KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99
2015
- sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p
2016
- yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn
2017
- kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI
2018
- zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC
2019
- AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g
2020
- cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
2021
- LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M
2022
- 8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg
2023
- /eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg
2024
- lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP
2025
- A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m
2026
- i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8
2027
- EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3
2028
- zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0=
2029
- -----END CERTIFICATE-----
2030
-
2031
- TeliaSonera Root CA v1
2032
- ======================
2033
- -----BEGIN CERTIFICATE-----
2034
- MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE
2035
- CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4
2036
- MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW
2037
- VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+
2038
- 6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA
2039
- 3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k
2040
- B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn
2041
- Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH
2042
- oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3
2043
- F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ
2044
- oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7
2045
- gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc
2046
- TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB
2047
- AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW
2048
- DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm
2049
- zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
2050
- 0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW
2051
- pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV
2052
- G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc
2053
- c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT
2054
- JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2
2055
- qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6
2056
- Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems
2057
- WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
2058
- -----END CERTIFICATE-----
2059
-
2060
- E-Tugra Certification Authority
2061
- ===============================
2062
- -----BEGIN CERTIFICATE-----
2063
- MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w
2064
- DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls
2065
- ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
2066
- ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw
2067
- NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx
2068
- QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl
2069
- cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD
2070
- DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
2071
- MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd
2072
- hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K
2073
- CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g
2074
- ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ
2075
- BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0
2076
- E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz
2077
- rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq
2078
- jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
2079
- rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5
2080
- dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB
2081
- /wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG
2082
- MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK
2083
- kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO
2084
- XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807
2085
- VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo
2086
- a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc
2087
- dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV
2088
- KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT
2089
- Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0
2090
- 8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G
2091
- C7TbO6Orb1wdtn7os4I07QZcJA==
2092
- -----END CERTIFICATE-----
2093
-
2094
- T-TeleSec GlobalRoot Class 2
2095
- ============================
2096
- -----BEGIN CERTIFICATE-----
2097
- MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
2098
- IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
2099
- cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx
2100
- MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
2101
- dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
2102
- ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3
2103
- DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ
2104
- SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F
2105
- vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970
2106
- 2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV
2107
- WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA
2108
- MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy
2109
- YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4
2110
- r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf
2111
- vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR
2112
- 3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
2113
- 9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg==
2114
- -----END CERTIFICATE-----
2115
-
2116
- Atos TrustedRoot 2011
2117
- =====================
2118
- -----BEGIN CERTIFICATE-----
2119
- MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU
2120
- cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4
2121
- MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG
2122
- A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV
2123
- hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr
2124
- 54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+
2125
- DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320
2126
- HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR
2127
- z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R
2128
- l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ
2129
- bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
2130
- CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h
2131
- k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh
2132
- TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9
2133
- 61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G
2134
- 3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
2135
- -----END CERTIFICATE-----
2136
-
2137
- QuoVadis Root CA 1 G3
2138
- =====================
2139
- -----BEGIN CERTIFICATE-----
2140
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN
2148
- 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
- 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
- 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
- 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
- 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
- t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
2154
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
2164
- hMJKzRwuJIczYOXD
2165
- -----END CERTIFICATE-----
2166
-
2167
- QuoVadis Root CA 2 G3
2168
- =====================
2169
- -----BEGIN CERTIFICATE-----
2170
- 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
- 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
- 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
- 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
- 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
- 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
- NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t
2177
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz
2189
- 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
- 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
- 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
- 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
- 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
2194
- O3jtZsSOeWmD3n+M
2195
- -----END CERTIFICATE-----
2196
-
2197
- QuoVadis Root CA 3 G3
2198
- =====================
2199
- -----BEGIN CERTIFICATE-----
2200
- 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
- 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
- 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
- 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
- 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
- IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL
2206
- 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
- 6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3
2208
- 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
- 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
- 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
- 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
- dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt
2213
- 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
- AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI
2215
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
2224
- PpxxVJkES/1Y+Zj0
2225
- -----END CERTIFICATE-----
2226
-
2227
- DigiCert Assured ID Root G2
2228
- ===========================
2229
- -----BEGIN CERTIFICATE-----
2230
- MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG
2231
- EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
2232
- IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw
2233
- MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
2234
- ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw
2235
- ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH
2236
- 35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq
2237
- bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw
2238
- VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP
2239
- YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn
2240
- lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO
2241
- w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv
2242
- 0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz
2243
- d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW
2244
- hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M
2245
- jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
2246
- IhNzbM8m9Yop5w==
2247
- -----END CERTIFICATE-----
2248
-
2249
- DigiCert Assured ID Root G3
2250
- ===========================
2251
- -----BEGIN CERTIFICATE-----
2252
- MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV
2253
- UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD
2254
- VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1
2255
- MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
2256
- d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ
2257
- BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb
2258
- RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs
2259
- KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF
2260
- UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy
2261
- YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy
2262
- 1vUhZscv6pZjamVFkpUBtA==
2263
- -----END CERTIFICATE-----
2264
-
2265
- DigiCert Global Root G2
2266
- =======================
2267
- -----BEGIN CERTIFICATE-----
2268
- MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG
2269
- EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
2270
- HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx
2271
- MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
2272
- dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq
2273
- hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ
2274
- kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO
2275
- 3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV
2276
- BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM
2277
- UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB
2278
- o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu
2279
- 5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr
2280
- F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U
2281
- WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH
2282
- QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/
2283
- iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
2284
- MrY=
2285
- -----END CERTIFICATE-----
2286
-
2287
- DigiCert Global Root G3
2288
- =======================
2289
- -----BEGIN CERTIFICATE-----
2290
- MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV
2291
- UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD
2292
- VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw
2293
- MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
2294
- aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C
2295
- AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O
2296
- YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP
2297
- BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp
2298
- Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y
2299
- 3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34
2300
- VOKa5Vt8sycX
2301
- -----END CERTIFICATE-----
2302
-
2303
- DigiCert Trusted Root G4
2304
- ========================
2305
- -----BEGIN CERTIFICATE-----
2306
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr
2324
- 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
- 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
- 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
- 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
- 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
- 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
- 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
2331
- 82Z+
2332
- -----END CERTIFICATE-----
2333
-
2334
- COMODO RSA Certification Authority
2335
- ==================================
2336
- -----BEGIN CERTIFICATE-----
2337
- MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE
2338
- BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
2339
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg
2357
- 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
- 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
- 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
- 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
- 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
- 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
2363
- LaZRfyHBNVOFBkpdn627G190
2364
- -----END CERTIFICATE-----
2365
-
2366
- USERTrust RSA Certification Authority
2367
- =====================================
2368
- -----BEGIN CERTIFICATE-----
2369
- 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
- BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
2371
- 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
- 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
- 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
- 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
- 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
- 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
- Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn
2378
- 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
- +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
- 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
- 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
- lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8
2383
- 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
- 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
- BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
2386
- MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW
2387
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
2395
- Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9
2396
- -----END CERTIFICATE-----
2397
-
2398
- USERTrust ECC Certification Authority
2399
- =====================================
2400
- -----BEGIN CERTIFICATE-----
2401
- MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC
2402
- VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
2403
- aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
2404
- biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC
2405
- VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
2406
- aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
2407
- biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2
2408
- 0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez
2409
- nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV
2410
- HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB
2411
- HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu
2412
- 9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
2413
- -----END CERTIFICATE-----
2414
-
2415
- GlobalSign ECC Root CA - R4
2416
- ===========================
2417
- -----BEGIN CERTIFICATE-----
2418
- MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb
2419
- R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
2420
- EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
2421
- R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
2422
- EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl
2423
- OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P
2424
- AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV
2425
- MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF
2426
- JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q=
2427
- -----END CERTIFICATE-----
2428
-
2429
- GlobalSign ECC Root CA - R5
2430
- ===========================
2431
- -----BEGIN CERTIFICATE-----
2432
- MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb
2433
- R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
2434
- EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
2435
- R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
2436
- EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6
2437
- SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS
2438
- h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
2439
- BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx
2440
- uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7
2441
- yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3
2442
- -----END CERTIFICATE-----
2443
-
2444
- Staat der Nederlanden Root CA - G3
2445
- ==================================
2446
- -----BEGIN CERTIFICATE-----
2447
- MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE
2448
- 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
- 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
- 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
- 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
- olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t
2453
- 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
- EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K
2455
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
2472
- -----END CERTIFICATE-----
2473
-
2474
- Staat der Nederlanden EV Root CA
2475
- ================================
2476
- -----BEGIN CERTIFICATE-----
2477
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx
2490
- 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
- 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
- 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
- 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
- c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq
2495
- 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
- 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
- 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
- 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
- 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
- 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
2501
- eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg==
2502
- -----END CERTIFICATE-----
2503
-
2504
- IdenTrust Commercial Root CA 1
2505
- ==============================
2506
- -----BEGIN CERTIFICATE-----
2507
- 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
- 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
- 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
- MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB
2511
- 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
- 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
- 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
- 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
- XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl
2516
- 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
- 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
- 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
- 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
- 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
- AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI
2522
- 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
- 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
- ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt
2525
- 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
- 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
- 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
- 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
- 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
- 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
2531
- cGzM7vRX+Bi6hG6H
2532
- -----END CERTIFICATE-----
2533
-
2534
- IdenTrust Public Sector Root CA 1
2535
- =================================
2536
- -----BEGIN CERTIFICATE-----
2537
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ
2561
- 3Wl9af0AVqW3rLatt8o+Ae+c
2562
- -----END CERTIFICATE-----
2563
-
2564
- Entrust Root Certification Authority - G2
2565
- =========================================
2566
- -----BEGIN CERTIFICATE-----
2567
- MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV
2568
- BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy
2569
- bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug
2570
- b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw
2571
- HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT
2572
- DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx
2573
- OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s
2574
- eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi
2575
- MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP
2576
- /vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz
2577
- HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU
2578
- s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y
2579
- TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx
2580
- AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6
2581
- 0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z
2582
- iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
2583
- Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi
2584
- nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+
2585
- vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO
2586
- e4pIb4tF9g==
2587
- -----END CERTIFICATE-----
2588
-
2589
- Entrust Root Certification Authority - EC1
2590
- ==========================================
2591
- -----BEGIN CERTIFICATE-----
2592
- MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx
2593
- FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn
2594
- YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl
2595
- ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
2596
- IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw
2597
- FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs
2598
- LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg
2599
- dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
2600
- IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy
2601
- AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef
2602
- 9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
2603
- FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h
2604
- vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8
2605
- kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
2606
- -----END CERTIFICATE-----
2607
-
2608
- CFCA EV ROOT
2609
- ============
2610
- -----BEGIN CERTIFICATE-----
2611
- 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
- CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB
2613
- IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw
2614
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
2626
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX
2634
- 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
- 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
2636
- -----END CERTIFICATE-----
2637
-
2638
- Certinomis - Root CA
2639
- ====================
2640
- -----BEGIN CERTIFICATE-----
2641
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng
2663
- 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
- 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
- cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr
2666
- hkIGuUE=
2667
- -----END CERTIFICATE-----
2668
-
2669
- OISTE WISeKey Global Root GB CA
2670
- ===============================
2671
- -----BEGIN CERTIFICATE-----
2672
- MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG
2673
- EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
2674
- ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw
2675
- MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD
2676
- VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds
2677
- b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX
2678
- scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP
2679
- rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk
2680
- 9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o
2681
- Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg
2682
- GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
2683
- /zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI
2684
- hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD
2685
- dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0
2686
- VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui
2687
- HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
2688
- Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
2689
- -----END CERTIFICATE-----
2690
-
2691
- SZAFIR ROOT CA2
2692
- ===============
2693
- -----BEGIN CERTIFICATE-----
2694
- MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG
2695
- A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV
2696
- BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ
2697
- BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD
2698
- VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q
2699
- qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK
2700
- DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE
2701
- 2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ
2702
- ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi
2703
- ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
2704
- AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC
2705
- AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5
2706
- O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67
2707
- oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul
2708
- 4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6
2709
- +/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
2710
- -----END CERTIFICATE-----
2711
-
2712
- Certum Trusted Network CA 2
2713
- ===========================
2714
- -----BEGIN CERTIFICATE-----
2715
- MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE
2716
- BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1
2717
- bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y
2718
- ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ
2719
- TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl
2720
- cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB
2721
- IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9
2722
- 7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o
2723
- CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b
2724
- Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p
2725
- uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130
2726
- GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ
2727
- 9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB
2728
- Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye
2729
- hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM
2730
- BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
2731
- AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI
2732
- hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW
2733
- Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA
2734
- L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo
2735
- clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM
2736
- pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb
2737
- w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo
2738
- J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm
2739
- ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX
2740
- is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7
2741
- zAYspsbiDrW5viSP
2742
- -----END CERTIFICATE-----
2743
-
2744
- Hellenic Academic and Research Institutions RootCA 2015
2745
- =======================================================
2746
- -----BEGIN CERTIFICATE-----
2747
- MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT
2748
- BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0
2749
- aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl
2750
- YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx
2751
- MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg
2752
- QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV
2753
- BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw
2754
- MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv
2755
- bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh
2756
- iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+
2757
- 6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd
2758
- FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr
2759
- i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F
2760
- GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2
2761
- fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu
2762
- iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc
2763
- Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
2764
- AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI
2765
- hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+
2766
- D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM
2767
- d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y
2768
- d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn
2769
- 82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb
2770
- davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F
2771
- Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt
2772
- J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa
2773
- JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q
2774
- p/UsQu0yrbYhnr68
2775
- -----END CERTIFICATE-----
2776
-
2777
- Hellenic Academic and Research Institutions ECC RootCA 2015
2778
- ===========================================================
2779
- -----BEGIN CERTIFICATE-----
2780
- MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0
2781
- aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u
2782
- cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj
2783
- aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw
2784
- MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj
2785
- IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD
2786
- VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290
2787
- Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP
2788
- dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK
2789
- Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
2790
- BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA
2791
- GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn
2792
- dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR
2793
- -----END CERTIFICATE-----
2794
-
2795
- Certplus Root CA G1
2796
- ===================
2797
- -----BEGIN CERTIFICATE-----
2798
- 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
- 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
- Fw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhD
2801
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
2822
- qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo=
2823
- -----END CERTIFICATE-----
2824
-
2825
- Certplus Root CA G2
2826
- ===================
2827
- -----BEGIN CERTIFICATE-----
2828
- MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4xCzAJBgNVBAYT
2829
- AkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjAeFw0x
2830
- NDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0
2831
- cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IA
2832
- BM0PW1aC3/BFGtat93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uN
2833
- Am8xIk0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0PAQH/BAQD
2834
- AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMB8GA1Ud
2835
- IwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqGSM49BAMDA2gAMGUCMHD+sAvZ94OX7PNV
2836
- HdTcswYO/jOYnYs5kGuUIe22113WTNchp+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjl
2837
- vPl5adytRSv3tjFzzAalU5ORGpOucGpnutee5WEaXw==
2838
- -----END CERTIFICATE-----
2839
-
2840
- OpenTrust Root CA G1
2841
- ====================
2842
- -----BEGIN CERTIFICATE-----
2843
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- n6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPwvFEVVJSmdz7QdFG9
2855
- URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYYEQRVzXR7z2FwefR7LFxckvzluFqr
2856
- TJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
2857
- /zAdBgNVHQ4EFgQUl0YhVyE12jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/Px
2858
- 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
- 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
- uVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbSFXJfLkur1J1juONI5f6ELlgK
2861
- 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
- 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
- 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
- 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
- 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
- 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
2867
- OXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj1oxx
2868
- -----END CERTIFICATE-----
2869
-
2870
- OpenTrust Root CA G2
2871
- ====================
2872
- -----BEGIN CERTIFICATE-----
2873
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- SmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eAiN1nE28daCSLT7d0geX0
2896
- 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
2897
- u7JwqkwR3v98KzfUetF3NI/n+UL3PIEMS1IK
2898
- -----END CERTIFICATE-----
2899
-
2900
- OpenTrust Root CA G3
2901
- ====================
2902
- -----BEGIN CERTIFICATE-----
2903
- MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAxCzAJBgNVBAYT
2904
- AkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEczMB4X
2905
- DTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9w
2906
- ZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQA
2907
- IgNiAARK7liuTcpm3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5B
2908
- ta1doYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4GA1UdDwEB
2909
- /wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAf
2910
- BgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAKBggqhkjOPQQDAwNpADBmAjEAj6jcnboM
2911
- BBf6Fek9LykBl7+BFjNAk2z8+e2AcG+qj9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta
2912
- 3U1fJAuwACEl74+nBCZx4nxp5V2a+EEfOzmTk51V6s2N8fvB
2913
- -----END CERTIFICATE-----
2914
-
2915
- ISRG Root X1
2916
- ============
2917
- -----BEGIN CERTIFICATE-----
2918
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY
2933
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
2942
- m+kXQ99b21/+jh5Xos1AnX5iItreGCc=
2943
- -----END CERTIFICATE-----
2944
-
2945
- AC RAIZ FNMT-RCM
2946
- ================
2947
- -----BEGIN CERTIFICATE-----
2948
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
2962
- FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o
2963
- 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
- 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
- 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
- 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
- Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW
2968
- +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
- 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
- 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
- 5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG
2972
- 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
2973
- -----END CERTIFICATE-----
2974
-
2975
- Amazon Root CA 1
2976
- ================
2977
- -----BEGIN CERTIFICATE-----
2978
- MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD
2979
- VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1
2980
- MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv
2981
- bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
2982
- ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH
2983
- FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ
2984
- gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t
2985
- dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce
2986
- VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
2987
- /zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3
2988
- DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM
2989
- CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy
2990
- 8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa
2991
- 2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2
2992
- xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5
2993
- -----END CERTIFICATE-----
2994
-
2995
- Amazon Root CA 2
2996
- ================
2997
- -----BEGIN CERTIFICATE-----
2998
- MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD
2999
- VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1
3000
- MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv
3001
- bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
3002
- ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4
3003
- kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp
3004
- N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9
3005
- AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd
3006
- fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx
3007
- kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS
3008
- btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0
3009
- Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN
3010
- c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+
3011
- 3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw
3012
- DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA
3013
- A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
3014
- +gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE
3015
- YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW
3016
- xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ
3017
- gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW
3018
- aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV
3019
- Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3
3020
- KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi
3021
- JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw=
3022
- -----END CERTIFICATE-----
3023
-
3024
- Amazon Root CA 3
3025
- ================
3026
- -----BEGIN CERTIFICATE-----
3027
- MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG
3028
- EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy
3029
- NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ
3030
- MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB
3031
- f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr
3032
- Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43
3033
- rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc
3034
- eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==
3035
- -----END CERTIFICATE-----
3036
-
3037
- Amazon Root CA 4
3038
- ================
3039
- -----BEGIN CERTIFICATE-----
3040
- MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG
3041
- EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy
3042
- NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ
3043
- MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN
3044
- /sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri
3045
- 83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
3046
- HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA
3047
- MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1
3048
- AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==
3049
- -----END CERTIFICATE-----
3050
-
3051
- LuxTrust Global Root 2
3052
- ======================
3053
- -----BEGIN CERTIFICATE-----
3054
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF
3064
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I
3079
- 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
3080
- -----END CERTIFICATE-----
3081
-
3082
- TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1
3083
- =============================================
3084
- -----BEGIN CERTIFICATE-----
3085
- MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT
3086
- D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr
3087
- IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g
3088
- TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp
3089
- ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD
3090
- VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt
3091
- c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth
3092
- bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11
3093
- IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
3094
- MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8
3095
- 6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc
3096
- wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0
3097
- 3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9
3098
- WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU
3099
- ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
3100
- KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh
3101
- AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc
3102
- lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R
3103
- e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j
3104
- q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
3105
- -----END CERTIFICATE-----
3106
-
3107
- GDCA TrustAUTH R5 ROOT
3108
- ======================
3109
- -----BEGIN CERTIFICATE-----
3110
- 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
- BgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8wHQYDVQQD
3112
- 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
- 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
- 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
- AQEFAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJjDp6L3TQs
3116
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- +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
- 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
- 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
- 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
- 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
- aaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g==
3135
- -----END CERTIFICATE-----
3136
-
3137
- TrustCor RootCert CA-1
3138
- ======================
3139
- -----BEGIN CERTIFICATE-----
3140
- MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYDVQQGEwJQQTEP
3141
- MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig
3142
- U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp
3143
- dHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkx
3144
- MjMxMTcyMzE2WjCBpDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFu
3145
- YW1hIENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUGA1UECwwe
3146
- VHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZUcnVzdENvciBSb290Q2Vy
3147
- dCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv463leLCJhJrMxnHQFgKq1mq
3148
- jQCj/IDHUHuO1CAmujIS2CNUSSUQIpidRtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4
3149
- pQa81QBeCQryJ3pS/C3Vseq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0
3150
- JEsq1pme9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CVEY4h
3151
- gLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorWhnAbJN7+KIor0Gqw
3152
- /Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/DeOxCbeKyKsZn3MzUOcwHwYDVR0j
3153
- BBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
3154
- AYYwDQYJKoZIhvcNAQELBQADggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5
3155
- mDo4Nvu7Zp5I/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf
3156
- ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZyonnMlo2HD6C
3157
- qFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djtsL1Ac59v2Z3kf9YKVmgenFK+P
3158
- 3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdNzl/HHk484IkzlQsPpTLWPFp5LBk=
3159
- -----END CERTIFICATE-----
3160
-
3161
- TrustCor RootCert CA-2
3162
- ======================
3163
- -----BEGIN CERTIFICATE-----
3164
- MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNVBAYTAlBBMQ8w
3165
- DQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQwIgYDVQQKDBtUcnVzdENvciBT
3166
- eXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0
3167
- eTEfMB0GA1UEAwwWVHJ1c3RDb3IgUm9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEy
3168
- MzExNzI2MzlaMIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5h
3169
- bWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U
3170
- cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0
3171
- IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnIG7CKqJiJJWQdsg4foDSq8Gb
3172
- ZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9Nk
3173
- RvRUqdw6VC0xK5mC8tkq1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1
3174
- oYxOdqHp2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nKDOOb
3175
- XUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hapeaz6LMvYHL1cEksr1
3176
- /p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF3wP+TfSvPd9cW436cOGlfifHhi5q
3177
- jxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQP
3178
- eSghYA2FFn3XVDjxklb9tTNMg9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+Ctg
3179
- rKAmrhQhJ8Z3mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh
3180
- 8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAdBgNVHQ4EFgQU
3181
- 2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6UnrybPZx9mCAZ5YwwYrIwDwYD
3182
- VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/h
3183
- Osh80QA9z+LqBrWyOrsGS2h60COXdKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnp
3184
- kpfbsEZC89NiqpX+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv
3185
- 2wnL/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RXCI/hOWB3
3186
- S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYaZH9bDTMJBzN7Bj8RpFxw
3187
- PIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dv
3188
- DDqPys/cA8GiCcjl/YBeyGBCARsaU1q7N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYU
3189
- RpFHmygk71dSTlxCnKr3Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANE
3190
- xdqtvArBAs8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp5KeX
3191
- RKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu1uwJ
3192
- -----END CERTIFICATE-----
3193
-
3194
- TrustCor ECA-1
3195
- ==============
3196
- -----BEGIN CERTIFICATE-----
3197
- MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYDVQQGEwJQQTEP
3198
- MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig
3199
- U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp
3200
- dHkxFzAVBgNVBAMMDlRydXN0Q29yIEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3Mjgw
3201
- N1owgZwxCzAJBgNVBAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5
3202
- MSQwIgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29y
3203
- IENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3IgRUNBLTEwggEiMA0GCSqG
3204
- SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb3w9U73NjKYKtR8aja+3+XzP4Q1HpGjOR
3205
- MRegdMTUpwHmspI+ap3tDvl0mEDTPwOABoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23
3206
- xFUfJ3zSCNV2HykVh0A53ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmc
3207
- p0yJF4OuowReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/wZ0+
3208
- fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZFZtS6mFjBAgMBAAGj
3209
- YzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAfBgNVHSMEGDAWgBREnkj1zG1I1KBL
3210
- f/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF
3211
- AAOCAQEABT41XBVwm8nHc2FvcivUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u
3212
- /ukZMjgDfxT2AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F
3213
- hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50soIipX1TH0Xs
3214
- J5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BIWJZpTdwHjFGTot+fDz2LYLSC
3215
- jaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1WitJ/X5g==
3216
- -----END CERTIFICATE-----
3217
-
3218
- SSL.com Root Certification Authority RSA
3219
- ========================================
3220
- -----BEGIN CERTIFICATE-----
3221
- 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
- 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
- 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
- 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
- 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
- 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
- ggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2RxFdHaxh3a3by/ZPkPQ/C
3228
- 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
- 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
- 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
- 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
- fBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93EJNyAKoFBbZQ+yODJ
3233
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- Pb9s2KJELtFOt3JY04kTlf5Eq/jXixtunLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406y
3246
- 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
3247
- WuuA8ShYIc2wBlX7Jz9TkHCpBB5XJ7k=
3248
- -----END CERTIFICATE-----
3249
-
3250
- SSL.com Root Certification Authority ECC
3251
- ========================================
3252
- -----BEGIN CERTIFICATE-----
3253
- MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxDjAMBgNV
3254
- BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xMTAv
3255
- BgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEy
3256
- MTgxNDAzWhcNNDEwMjEyMTgxNDAzWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO
3257
- BgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv
3258
- bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IA
3259
- BEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor+
3260
- 8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPgCemB+vNH06NjMGEwHQYDVR0OBBYEFILR
3261
- hXMw5zUE044CkvvlpNHEIejNMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTT
3262
- jgKS++Wk0cQh6M0wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCW
3263
- e+0F+S8Tkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+gA0z
3264
- 5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl
3265
- -----END CERTIFICATE-----
3266
-
3267
- SSL.com EV Root Certification Authority RSA R2
3268
- ==============================================
3269
- -----BEGIN CERTIFICATE-----
3270
- MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVTMQ4w
3271
- DAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9u
3272
- MTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy
3273
- MB4XDTE3MDUzMTE4MTQzN1oXDTQyMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI
3274
- DAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYD
3275
- VQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMIICIjAN
3276
- BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvqM0fNTPl9fb69LT3w23jh
3277
- hqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssufOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7w
3278
- cXHswxzpY6IXFJ3vG2fThVUCAtZJycxa4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTO
3279
- Zw+oz12WGQvE43LrrdF9HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+
3280
- B6KjBSYRaZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcAb9Zh
3281
- CBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQGp8hLH94t2S42Oim
3282
- 9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQVPWKchjgGAGYS5Fl2WlPAApiiECto
3283
- RHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMOpgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+Slm
3284
- JuwgUHfbSguPvuUCYHBBXtSuUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48
3285
- +qvWBkofZ6aYMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
3286
- HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa49QaAJadz20Zp
3287
- qJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBWs47LCp1Jjr+kxJG7ZhcFUZh1
3288
- ++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nx
3289
- Y/hoLVUE0fKNsKTPvDxeH3jnpaAgcLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2G
3290
- guDKBAdRUNf/ktUM79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDz
3291
- OFSz/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXtll9ldDz7
3292
- CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEmKf7GUmG6sXP/wwyc5Wxq
3293
- lD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKKQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreR
3294
- rwU7ZcegbLHNYhLDkBvjJc40vG93drEQw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1
3295
- hlMYegouCRw2n5H9gooiS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX
3296
- 9hwJ1C07mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
3297
- -----END CERTIFICATE-----
3298
-
3299
- SSL.com EV Root Certification Authority ECC
3300
- ===========================================
3301
- -----BEGIN CERTIFICATE-----
3302
- MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNV
3303
- BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAy
3304
- BgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYw
3305
- MjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx
3306
- EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NM
3307
- LmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB
3308
- BAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc/R/fALhBYlzccBYy
3309
- 3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1KthkuWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0O
3310
- BBYEFFvKXuXe0oGqzagtZFG22XKbl+ZPMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe
3311
- 5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJ
3312
- N+vp1RPZytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZgh5Mm
3313
- m7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
3314
- -----END CERTIFICATE-----
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/ultimate-web-scraper/crc32_stream.php DELETED
@@ -1,99 +0,0 @@
1
- <?php
2
- // CRC32 stream class.
3
- // (C) 2016 CubicleSoft. All Rights Reserved.
4
- //
5
- // Direct port from the CubicleSoft C++ implementation.
6
-
7
- class CRC32Stream
8
- {
9
- private $open, $crctable, $datareflect, $crcreflect, $firstcrc, $currcrc, $finalxor;
10
- private static $revlookup = array(0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240, 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244, 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242, 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241, 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251, 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255);
11
-
12
- // PKZip, gzip, AUTODIN II, Ethernet, and FDDI.
13
- public static $default = array("poly" => 0x04C11DB7, "start" => 0xFFFFFFFF, "xor" => 0xFFFFFFFF, "refdata" => 1, "refcrc" => 1);
14
-
15
- public function __construct()
16
- {
17
- $this->open = false;
18
- }
19
-
20
- public function Init($options = false)
21
- {
22
- if ($options === false) $options = self::$default;
23
-
24
- $this->crctable = array();
25
- $poly = $this->LIM32($options["poly"]);
26
- for ($x = 0; $x < 256; $x++)
27
- {
28
- $c = $this->SHL32($x, 24);
29
- for ($y = 0; $y < 8; $y++) $c = $this->SHL32($c, 1) ^ ($c & 0x80000000 ? $poly : 0);
30
- $this->crctable[$x] = $c;
31
- }
32
-
33
- $this->datareflect = $options["refdata"];
34
- $this->crcreflect = $options["refcrc"];
35
- $this->firstcrc = $options["start"];
36
- $this->currcrc = $options["start"];
37
- $this->finalxor = $options["xor"];
38
- $this->open = true;
39
- }
40
-
41
- public function AddData($data)
42
- {
43
- if (!$this->open) return false;
44
-
45
- $y = strlen($data);
46
- for ($x < 0; $x < $y; $x++)
47
- {
48
- if ($this->datareflect) $this->currcrc = $this->SHL32($this->currcrc, 8) ^ $this->crctable[$this->SHR32($this->currcrc, 24) ^ self::$revlookup[ord($data{$x})]];
49
- else $this->currcrc = $this->SHL32($this->currcrc, 8) ^ $this->crctable[$this->SHR32($this->currcrc, 24) ^ ord($data{$x})];
50
- }
51
-
52
- return true;
53
- }
54
-
55
- public function Finalize()
56
- {
57
- if (!$this->open) return false;
58
-
59
- if ($this->crcreflect)
60
- {
61
- $tempcrc = $this->currcrc;
62
- $this->currcrc = self::$revlookup[$this->SHR32($tempcrc, 24)] | $this->SHL32(self::$revlookup[$this->SHR32($tempcrc, 16) & 0xFF], 8) | $this->SHL32(self::$revlookup[$this->SHR32($tempcrc, 8) & 0xFF], 16) | $this->SHL32(self::$revlookup[$this->LIM32($tempcrc & 0xFF)], 24);
63
- }
64
- $result = $this->currcrc ^ $this->finalxor;
65
-
66
- $this->currcrc = $this->firstcrc;
67
-
68
- return $result;
69
- }
70
-
71
- // These functions are a hacky, but effective way of enforcing unsigned 32-bit integers onto a generic signed int.
72
- // Allow bitwise operations to work across platforms. Minimum integer size must be 32-bit.
73
- private function SHR32($num, $bits)
74
- {
75
- $num = (int)$num;
76
- if ($bits < 0) $bits = 0;
77
-
78
- if ($num < 0 && $bits)
79
- {
80
- $num = ($num >> 1) & 0x7FFFFFFF;
81
- $bits--;
82
- }
83
-
84
- return $this->LIM32($num >> $bits);
85
- }
86
-
87
- private function SHL32($num, $bits)
88
- {
89
- if ($bits < 0) $bits = 0;
90
-
91
- return $this->LIM32((int)$num << $bits);
92
- }
93
-
94
- private function LIM32($num)
95
- {
96
- return (int)((int)$num & 0xFFFFFFFF);
97
- }
98
- }
99
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/ultimate-web-scraper/deflate_stream.php DELETED
@@ -1,365 +0,0 @@
1
- <?php
2
- // Deflate stream class. Default is RFC1951 (raw deflate). Supports RFC1950 (ZLIB) and RFC1952 (gzip).
3
- // (C) 2016 CubicleSoft. All Rights Reserved.
4
-
5
- class DeflateStream
6
- {
7
- private $open, $fp, $filter, $compress, $indata, $outdata, $options;
8
- private static $supported;
9
-
10
- public function __construct()
11
- {
12
- $this->open = false;
13
- }
14
-
15
- public function __destruct()
16
- {
17
- $this->Finalize();
18
- }
19
-
20
- public static function IsSupported()
21
- {
22
- if (!is_bool(self::$supported))
23
- {
24
- self::$supported = function_exists("stream_filter_append") && function_exists("stream_filter_remove") && function_exists("gzcompress");
25
- if (self::$supported)
26
- {
27
- $data = self::Compress("test");
28
- if ($data === false || $data === "") self::$supported = false;
29
- else
30
- {
31
- $data = self::Uncompress($data);
32
- if ($data === false || $data !== "test") self::$supported = false;
33
- }
34
- }
35
- }
36
-
37
- return self::$supported;
38
- }
39
-
40
- public static function Compress($data, $compresslevel = -1, $options = array())
41
- {
42
- $ds = new DeflateStream;
43
- if (!$ds->Init("wb", $compresslevel, $options)) return false;
44
- if (!$ds->Write($data)) return false;
45
- if (!$ds->Finalize()) return false;
46
- $data = $ds->Read();
47
-
48
- return $data;
49
- }
50
-
51
- public static function Uncompress($data, $options = array("type" => "auto"))
52
- {
53
- $ds = new DeflateStream;
54
- if (!$ds->Init("rb", -1, $options)) return false;
55
- if (!$ds->Write($data)) return false;
56
- if (!$ds->Finalize()) return false;
57
- $data = $ds->Read();
58
-
59
- return $data;
60
- }
61
-
62
- public function Init($mode, $compresslevel = -1, $options = array())
63
- {
64
- if ($mode !== "rb" && $mode !== "wb") return false;
65
- if ($this->open) $this->Finalize();
66
-
67
- $this->fp = fopen("php://memory", "w+b");
68
- if ($this->fp === false) return false;
69
- $this->compress = ($mode == "wb");
70
- if (!isset($options["type"])) $options["type"] = "rfc1951";
71
-
72
- if ($options["type"] == "rfc1950") $options["type"] = "zlib";
73
- else if ($options["type"] == "rfc1952") $options["type"] = "gzip";
74
-
75
- if ($options["type"] != "zlib" && $options["type"] != "gzip" && ($this->compress || $options["type"] != "auto")) $options["type"] = "raw";
76
- $this->options = $options;
77
-
78
- // Add the deflate filter.
79
- if ($this->compress) $this->filter = stream_filter_append($this->fp, "zlib.deflate", STREAM_FILTER_WRITE, $compresslevel);
80
- else $this->filter = stream_filter_append($this->fp, "zlib.inflate", STREAM_FILTER_READ);
81
-
82
- $this->open = true;
83
- $this->indata = "";
84
- $this->outdata = "";
85
-
86
- if ($this->compress)
87
- {
88
- if ($this->options["type"] == "zlib")
89
- {
90
- $this->outdata .= "\x78\x9C";
91
- $this->options["a"] = 1;
92
- $this->options["b"] = 0;
93
- }
94
- else if ($this->options["type"] == "gzip")
95
- {
96
- if (!class_exists("CRC32Stream", false)) require_once str_replace("\\", "/", dirname(__FILE__)) . "/crc32_stream.php";
97
-
98
- $this->options["crc32"] = new CRC32Stream();
99
- $this->options["crc32"]->Init();
100
- $this->options["bytes"] = 0;
101
-
102
- $this->outdata .= "\x1F\x8B\x08";
103
- $flags = 0;
104
- if (isset($this->options["filename"])) $flags |= 0x08;
105
- if (isset($this->options["comment"])) $flags |= 0x10;
106
- $this->outdata .= chr($flags);
107
- $this->outdata .= "\x00\x00\x00\x00";
108
- $this->outdata .= "\x00";
109
- $this->outdata .= "\x03";
110
-
111
- if (isset($this->options["filename"])) $this->outdata .= str_replace("\x00", " ", $this->options["filename"]) . "\x00";
112
- if (isset($this->options["comment"])) $this->outdata .= str_replace("\x00", " ", $this->options["comment"]) . "\x00";
113
- }
114
- }
115
- else
116
- {
117
- $this->options["header"] = false;
118
- }
119
-
120
- return true;
121
- }
122
-
123
- public function Read()
124
- {
125
- $result = $this->outdata;
126
- $this->outdata = "";
127
-
128
- return $result;
129
- }
130
-
131
- public function Write($data)
132
- {
133
- if (!$this->open) return false;
134
-
135
- if ($this->compress)
136
- {
137
- if ($this->options["type"] == "zlib")
138
- {
139
- // Adler-32.
140
- $y = strlen($data);
141
- for ($x = 0; $x < $y; $x++)
142
- {
143
- $this->options["a"] = ($this->options["a"] + ord($data{$x})) % 65521;
144
- $this->options["b"] = ($this->options["b"] + $this->options["a"]) % 65521;
145
- }
146
- }
147
- else if ($this->options["type"] == "gzip")
148
- {
149
- $this->options["crc32"]->AddData($data);
150
- $this->options["bytes"] = $this->ADD32($this->options["bytes"], strlen($data));
151
- }
152
-
153
- $this->indata .= $data;
154
- while (strlen($this->indata) >= 65536)
155
- {
156
- fwrite($this->fp, substr($this->indata, 0, 65536));
157
- $this->indata = substr($this->indata, 65536);
158
-
159
- $this->ProcessOutput();
160
- }
161
- }
162
- else
163
- {
164
- $this->indata .= $data;
165
- $this->ProcessInput();
166
- }
167
-
168
- return true;
169
- }
170
-
171
- // Finalizes the stream.
172
- public function Finalize()
173
- {
174
- if (!$this->open) return false;
175
-
176
- if (!$this->compress) $this->ProcessInput(true);
177
-
178
- if (strlen($this->indata) > 0)
179
- {
180
- fwrite($this->fp, $this->indata);
181
- $this->indata = "";
182
- }
183
-
184
- // Removing the filter pushes the last buffer into the stream.
185
- stream_filter_remove($this->filter);
186
- $this->filter = false;
187
-
188
- $this->ProcessOutput();
189
-
190
- fclose($this->fp);
191
-
192
- if ($this->compress)
193
- {
194
- if ($this->options["type"] == "zlib") $this->outdata .= pack("N", $this->SHL32($this->options["b"], 16) | $this->options["a"]);
195
- else if ($this->options["type"] == "gzip") $this->outdata .= pack("V", $this->options["crc32"]->Finalize()) . pack("V", $this->options["bytes"]);
196
- }
197
-
198
- $this->open = false;
199
-
200
- return true;
201
- }
202
-
203
- private function ProcessOutput()
204
- {
205
- rewind($this->fp);
206
-
207
- // Hack! Because ftell() on a stream with a filter is still broken even under the latest PHP a mere 4 years later.
208
- // See: https://bugs.php.net/bug.php?id=49874
209
- ob_start();
210
- fpassthru($this->fp);
211
- $this->outdata .= ob_get_contents();
212
- ob_end_clean();
213
-
214
- rewind($this->fp);
215
- ftruncate($this->fp, 0);
216
- }
217
-
218
- private function ProcessInput($final = false)
219
- {
220
- // Automatically determine the type of data based on the header signature.
221
- if ($this->options["type"] == "auto")
222
- {
223
- if (strlen($this->indata) >= 3)
224
- {
225
- $zlibtest = unpack("n", substr($this->indata, 0, 2));
226
-
227
- if (substr($this->indata, 0, 3) === "\x1F\x8B\x08") $this->options["type"] = "gzip";
228
- else if ((ord($this->indata{0}) & 0x0F) == 8 && ((ord($this->indata{0}) & 0xF0) >> 4) < 8 && $zlibtest[1] % 31 == 0) $this->options["type"] = "zlib";
229
- else $this->options["type"] = "raw";
230
- }
231
- else if ($final) $this->options["type"] = "raw";
232
- }
233
-
234
- if ($this->options["type"] == "gzip")
235
- {
236
- if (!$this->options["header"])
237
- {
238
- if (strlen($this->indata) >= 10)
239
- {
240
- $idcm = substr($this->indata, 0, 3);
241
- $flg = ord($this->indata{3});
242
-
243
- if ($idcm !== "\x1F\x8B\x08") $this->options["type"] = "ignore";
244
- else
245
- {
246
- // Calculate the number of bytes to skip. If flags are set, the size can be dynamic.
247
- $size = 10;
248
- $y = strlen($this->indata);
249
-
250
- // FLG.FEXTRA
251
- if ($size && ($flg & 0x04))
252
- {
253
- if ($size + 2 >= $y) $size = 0;
254
- else
255
- {
256
- $xlen = unpack("v", substr($this->indata, $size, 2));
257
- $size = ($size + 2 + $xlen <= $y ? $size + 2 + $xlen : 0);
258
- }
259
- }
260
-
261
- // FLG.FNAME
262
- if ($size && ($flg & 0x08))
263
- {
264
- $pos = strpos($this->indata, "\x00", $size);
265
- $size = ($pos !== false ? $pos + 1 : 0);
266
- }
267
-
268
- // FLG.FCOMMENT
269
- if ($size && ($flg & 0x10))
270
- {
271
- $pos = strpos($this->indata, "\x00", $size);
272
- $size = ($pos !== false ? $pos + 1 : 0);
273
- }
274
-
275
- // FLG.FHCRC
276
- if ($size && ($flg & 0x02)) $size = ($size + 2 <= $y ? $size + 2 : 0);
277
-
278
- if ($size)
279
- {
280
- $this->indata = substr($this->indata, $size);
281
- $this->options["header"] = true;
282
- }
283
- }
284
- }
285
- }
286
-
287
- if ($this->options["header"] && strlen($this->indata) > 8)
288
- {
289
- fwrite($this->fp, substr($this->indata, 0, -8));
290
- $this->indata = substr($this->indata, -8);
291
-
292
- $this->ProcessOutput();
293
- }
294
-
295
- if ($final) $this->indata = "";
296
- }
297
- else if ($this->options["type"] == "zlib")
298
- {
299
- if (!$this->options["header"])
300
- {
301
- if (strlen($this->indata) >= 2)
302
- {
303
- $cmf = ord($this->indata{0});
304
- $flg = ord($this->indata{1});
305
- $cm = $cmf & 0x0F;
306
- $cinfo = ($cmf & 0xF0) >> 4;
307
-
308
- // Compression method 'deflate' ($cm = 8), window size - 8 ($cinfo < 8), no preset dictionaries ($flg bit 5), checksum validates.
309
- if ($cm != 8 || $cinfo > 7 || ($flg & 0x20) || (($cmf << 8 | $flg) % 31) != 0) $this->options["type"] = "ignore";
310
- else
311
- {
312
- $this->indata = substr($this->indata, 2);
313
- $this->options["header"] = true;
314
- }
315
- }
316
- }
317
-
318
- if ($this->options["header"] && strlen($this->indata) > 4)
319
- {
320
- fwrite($this->fp, substr($this->indata, 0, -4));
321
- $this->indata = substr($this->indata, -4);
322
-
323
- $this->ProcessOutput();
324
- }
325
-
326
- if ($final) $this->indata = "";
327
- }
328
-
329
- if ($this->options["type"] == "raw")
330
- {
331
- fwrite($this->fp, $this->indata);
332
- $this->indata = "";
333
-
334
- $this->ProcessOutput();
335
- }
336
-
337
- // Only set when an unrecoverable header error has occurred for gzip or zlib.
338
- if ($this->options["type"] == "ignore") $this->indata = "";
339
- }
340
-
341
- private function SHL32($num, $bits)
342
- {
343
- if ($bits < 0) $bits = 0;
344
-
345
- return $this->LIM32((int)$num << $bits);
346
- }
347
-
348
- private function LIM32($num)
349
- {
350
- return (int)((int)$num & 0xFFFFFFFF);
351
- }
352
-
353
- private function ADD32($num, $num2)
354
- {
355
- $num = (int)$num;
356
- $num2 = (int)$num2;
357
- $add = ((($num >> 30) & 0x03) + (($num2 >> 30) & 0x03));
358
- $num = ((int)($num & 0x3FFFFFFF) + (int)($num2 & 0x3FFFFFFF));
359
- if ($num & 0x40000000) $add++;
360
- $num = (int)(($num & 0x3FFFFFFF) | (($add & 0x03) << 30));
361
-
362
- return $num;
363
- }
364
- }
365
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/ultimate-web-scraper/emulate_curl.php DELETED
@@ -1,1423 +0,0 @@
1
- <?php
2
- // CubicleSoft PHP HTTP cURL emulation functions.
3
- // (C) 2016 CubicleSoft. All Rights Reserved.
4
-
5
- // cURL HTTP emulation support requires:
6
- // The CubicleSoft PHP HTTP functions.
7
- // The CubicleSoft Web Browser state emulation class.
8
- if (!function_exists("curl_init"))
9
- {
10
- if (!class_exists("HTTP", false)) require_once str_replace("\\", "/", dirname(__FILE__)) . "/http.php";
11
-
12
- global $curl_error__map, $curl_init__map, $curl_multi_init__map;
13
-
14
- // Constants based on PHP 5.4.0 and libcurl 7.25.0.
15
- $curl_error__map = array(
16
- 0 => "CURLE_OK",
17
- 1 => "CURLE_UNSUPPORTED_PROTOCOL",
18
- 2 => "CURLE_FAILED_INIT",
19
- 3 => "CURLE_URL_MALFORMAT",
20
- 4 => "CURLE_NOT_BUILT_IN",
21
- 5 => "CURLE_COULDNT_RESOLVE_PROXY",
22
- 6 => "CURLE_COULDNT_RESOLVE_HOST",
23
- 7 => "CURLE_COULDNT_CONNECT",
24
- 8 => "CURLE_FTP_WEIRD_SERVER_REPLY",
25
- 9 => "CURLE_REMOTE_ACCESS_DENIED",
26
- 10 => "CURLE_FTP_ACCEPT_FAILED",
27
- 11 => "CURLE_FTP_WEIRD_PASS_REPLY",
28
- 12 => "CURLE_FTP_ACCEPT_TIMEOUT",
29
- 13 => "CURLE_FTP_WEIRD_PASV_REPLY",
30
- 14 => "CURLE_FTP_WEIRD_227_FORMAT",
31
- 15 => "CURLE_FTP_CANT_GET_HOST",
32
- 17 => "CURLE_FTP_COULDNT_SET_TYPE",
33
- 18 => "CURLE_PARTIAL_FILE",
34
- 19 => "CURLE_FTP_COULDNT_RETR_FILE",
35
- 21 => "CURLE_QUOTE_ERROR",
36
- 22 => "CURLE_HTTP_RETURNED_ERROR",
37
- 23 => "CURLE_WRITE_ERROR",
38
- 25 => "CURLE_UPLOAD_FAILED",
39
- 26 => "CURLE_READ_ERROR",
40
- 27 => "CURLE_OUT_OF_MEMORY",
41
- 28 => "CURLE_OPERATION_TIMEDOUT",
42
- 30 => "CURLE_FTP_PORT_FAILED",
43
- 31 => "CURLE_FTP_COULDNT_USE_REST",
44
- 33 => "CURLE_RANGE_ERROR",
45
- 34 => "CURLE_HTTP_POST_ERROR",
46
- 35 => "CURLE_SSL_CONNECT_ERROR",
47
- 36 => "CURLE_BAD_DOWNLOAD_RESUME",
48
- 37 => "CURLE_FILE_COULDNT_READ_FILE",
49
- 38 => "CURLE_LDAP_CANNOT_BIND",
50
- 39 => "CURLE_LDAP_SEARCH_FAILED",
51
- 41 => "CURLE_FUNCTION_NOT_FOUND",
52
- 42 => "CURLE_ABORTED_BY_CALLBACK",
53
- 43 => "CURLE_BAD_FUNCTION_ARGUMENT",
54
- 45 => "CURLE_INTERFACE_FAILED",
55
- 47 => "CURLE_TOO_MANY_REDIRECTS",
56
- 48 => "CURLE_UNKNOWN_OPTION",
57
- 49 => "CURLE_TELNET_OPTION_SYNTAX",
58
- 51 => "CURLE_PEER_FAILED_VERIFICATION",
59
- 52 => "CURLE_GOT_NOTHING",
60
- 53 => "CURLE_SSL_ENGINE_NOTFOUND",
61
- 54 => "CURLE_SSL_ENGINE_SETFAILED",
62
- 55 => "CURLE_SEND_ERROR",
63
- 56 => "CURLE_RECV_ERROR",
64
- 58 => "CURLE_SSL_CERTPROBLEM",
65
- 59 => "CURLE_SSL_CIPHER",
66
- 60 => "CURLE_SSL_CACERT",
67
- 61 => "CURLE_BAD_CONTENT_ENCODING",
68
- 62 => "CURLE_LDAP_INVALID_URL",
69
- 63 => "CURLE_FILESIZE_EXCEEDED",
70
- 64 => "CURLE_USE_SSL_FAILED",
71
- 65 => "CURLE_SEND_FAIL_REWIND",
72
- 66 => "CURLE_SSL_ENGINE_INITFAILED",
73
- 67 => "CURLE_LOGIN_DENIED",
74
- 68 => "CURLE_TFTP_NOTFOUND",
75
- 69 => "CURLE_TFTP_PERM",
76
- 70 => "CURLE_REMOTE_DISK_FULL",
77
- 71 => "CURLE_TFTP_ILLEGAL",
78
- 72 => "CURLE_TFTP_UNKNOWNID",
79
- 73 => "CURLE_REMOTE_FILE_EXISTS",
80
- 74 => "CURLE_TFTP_NOSUCHUSER",
81
- 75 => "CURLE_CONV_FAILED",
82
- 76 => "CURLE_CONV_REQD",
83
- 77 => "CURLE_SSL_CACERT_BADFILE",
84
- 78 => "CURLE_REMOTE_FILE_NOT_FOUND",
85
- 79 => "CURLE_SSH",
86
- 80 => "CURLE_SSL_SHUTDOWN_FAILED",
87
- 81 => "CURLE_AGAIN",
88
- 82 => "CURLE_SSL_CRL_BADFILE",
89
- 83 => "CURLE_SSL_ISSUER_ERROR",
90
- 84 => "CURLE_FTP_PRET_FAILED",
91
- 85 => "CURLE_RTSP_CSEQ_ERROR",
92
- 86 => "CURLE_RTSP_SESSION_ERROR",
93
- 87 => "CURLE_FTP_BAD_FILE_LIST",
94
- 88 => "CURLE_CHUNK_FAILED",
95
- );
96
-
97
- // Define constants in the same order as the official PHP cURL extension with the same integer values.
98
- // Additional defines exist in some locations because they will likely be defined in a future version of PHP.
99
- // DO NOT rely on these constants existing in the official PHP extension!
100
-
101
- // Constants for curl_setopt().
102
- define("CURLOPT_IPRESOLVE", 113);
103
- define("CURL_IPRESOLVE_WHATEVER", 0);
104
- define("CURL_IPRESOLVE_V4", 1);
105
- define("CURL_IPRESOLVE_V6", 2);
106
- define("CURLOPT_DNS_USE_GLOBAL_CACHE", 91); // DEPRECATED, do not use!
107
- define("CURLOPT_DNS_CACHE_TIMEOUT", 92);
108
- define("CURLOPT_PORT", 3);
109
- define("CURLOPT_FILE", 10001);
110
- define("CURLOPT_READDATA", 10009);
111
- define("CURLOPT_INFILE", 10009);
112
- define("CURLOPT_INFILESIZE", 14);
113
- define("CURLOPT_URL", 10002);
114
- define("CURLOPT_PROXY", 10004);
115
- define("CURLOPT_VERBOSE", 41);
116
- define("CURLOPT_HEADER", 42);
117
- define("CURLOPT_HTTPHEADER", 10023);
118
- define("CURLOPT_NOPROGRESS", 43);
119
- define("CURLOPT_PROGRESSFUNCTION", 20056);
120
- define("CURLOPT_NOBODY", 44);
121
- define("CURLOPT_FAILONERROR", 45);
122
- define("CURLOPT_UPLOAD", 46);
123
- define("CURLOPT_POST", 47);
124
- define("CURLOPT_FTPLISTONLY", 48);
125
- define("CURLOPT_FTPAPPEND", 50);
126
- define("CURLOPT_NETRC", 51);
127
- define("CURLOPT_FOLLOWLOCATION", 52);
128
- define("CURLOPT_PUT", 54);
129
- define("CURLOPT_USERPWD", 10005);
130
- define("CURLOPT_PROXYUSERPWD", 10006);
131
- define("CURLOPT_RANGE", 10007);
132
- define("CURLOPT_TIMEOUT", 13);
133
- define("CURLOPT_TIMEOUT_MS", 155);
134
- define("CURLOPT_POSTFIELDS", 10015);
135
- define("CURLOPT_REFERER", 10016);
136
- define("CURLOPT_USERAGENT", 10018);
137
- define("CURLOPT_FTPPORT", 10017);
138
- define("CURLOPT_FTP_USE_EPSV", 85);
139
- define("CURLOPT_LOW_SPEED_LIMIT", 19);
140
- define("CURLOPT_LOW_SPEED_TIME", 20);
141
- define("CURLOPT_RESUME_FROM", 21);
142
- define("CURLOPT_COOKIE", 10022);
143
- define("CURLOPT_COOKIESESSION", 96);
144
- define("CURLOPT_AUTOREFERER", 58);
145
- define("CURLOPT_SSLCERT", 10025);
146
- define("CURLOPT_SSLCERTPASSWD", 10026);
147
- define("CURLOPT_WRITEHEADER", 10029);
148
- define("CURLOPT_SSL_VERIFYHOST", 81);
149
- define("CURLOPT_COOKIEFILE", 10031);
150
- define("CURLOPT_SSLVERSION", 32);
151
- define("CURLOPT_TIMECONDITION", 33);
152
- define("CURLOPT_TIMEVALUE", 34);
153
- define("CURLOPT_CUSTOMREQUEST", 10036);
154
- define("CURLOPT_STDERR", 10037);
155
- define("CURLOPT_TRANSFERTEXT", 53);
156
- define("CURLOPT_RETURNTRANSFER", 19913);
157
- define("CURLOPT_QUOTE", 10028);
158
- define("CURLOPT_POSTQUOTE", 10039);
159
- define("CURLOPT_INTERFACE", 10062);
160
- define("CURLOPT_KRB4LEVEL", 10063);
161
- define("CURLOPT_HTTPPROXYTUNNEL", 61);
162
- define("CURLOPT_FILETIME", 69);
163
- define("CURLOPT_WRITEFUNCTION", 20011);
164
- define("CURLOPT_READFUNCTION", 20012);
165
- define("CURLOPT_HEADERFUNCTION", 20079);
166
- define("CURLOPT_MAXREDIRS", 68);
167
- define("CURLOPT_MAXCONNECTS", 71);
168
- define("CURLOPT_CLOSEPOLICY", 72);
169
- define("CURLOPT_FRESH_CONNECT", 74);
170
- define("CURLOPT_FORBID_REUSE", 75);
171
- define("CURLOPT_RANDOM_FILE", 10076);
172
- define("CURLOPT_EGDSOCKET", 10077);
173
- define("CURLOPT_CONNECTTIMEOUT", 78);
174
- define("CURLOPT_CONNECTTIMEOUT_MS", 156);
175
- define("CURLOPT_SSL_VERIFYPEER", 64);
176
- define("CURLOPT_CAINFO", 10065);
177
- define("CURLOPT_CAPATH", 10097);
178
- define("CURLOPT_COOKIEJAR", 10082);
179
- define("CURLOPT_SSL_CIPHER_LIST", 10083);
180
- define("CURLOPT_BINARYTRANSFER", 19914);
181
- define("CURLOPT_NOSIGNAL", 99);
182
- define("CURLOPT_PROXYTYPE", 101);
183
- define("CURLOPT_BUFFERSIZE", 98);
184
- define("CURLOPT_HTTPGET", 80);
185
- define("CURLOPT_HTTP_VERSION", 84);
186
- define("CURLOPT_SSLKEY", 10087);
187
- define("CURLOPT_SSLKEYTYPE", 10088);
188
- define("CURLOPT_SSLKEYPASSWD", 10026);
189
- define("CURLOPT_SSLENGINE", 10089);
190
- define("CURLOPT_SSLENGINE_DEFAULT", 90);
191
- define("CURLOPT_SSLCERTTYPE", 10086);
192
- define("CURLOPT_CRLF", 27);
193
- define("CURLOPT_ENCODING", 10102);
194
- define("CURLOPT_PROXYPORT", 59);
195
- define("CURLOPT_UNRESTRICTED_AUTH", 105);
196
- define("CURLOPT_FTP_USE_EPRT", 106);
197
- define("CURLOPT_TCP_NODELAY", 121);
198
- define("CURLOPT_HTTP200ALIASES", 10104);
199
- define("CURL_TIMECOND_NONE", 0);
200
- define("CURL_TIMECOND_IFMODSINCE", 1);
201
- define("CURL_TIMECOND_IFUNMODSINCE", 2);
202
- define("CURL_TIMECOND_LASTMOD", 3);
203
- define("CURLOPT_MAX_RECV_SPEED_LARGE", 30146);
204
- define("CURLOPT_MAX_SEND_SPEED_LARGE", 30145);
205
- define("CURLOPT_HTTPAUTH", 107);
206
- define("CURLAUTH_NONE", 0);
207
- define("CURLAUTH_BASIC", 1);
208
- define("CURLAUTH_DIGEST", 2);
209
- define("CURLAUTH_GSSNEGOTIATE", 4);
210
- define("CURLAUTH_NTLM", 8);
211
- define("CURLAUTH_DIGEST_IE", 16);
212
- define("CURLAUTH_NTLM_WB", 32);
213
- define("CURLAUTH_ANY", -17);
214
- define("CURLAUTH_ANYSAFE", -18);
215
- define("CURLOPT_PROXYAUTH", 111);
216
- define("CURLOPT_FTP_CREATE_MISSING_DIRS", 110);
217
- define("CURLOPT_PRIVATE", 10103);
218
-
219
- // Constants effecting the way CURLOPT_CLOSEPOLICY works.
220
- define("CURLCLOSEPOLICY_LEAST_RECENTLY_USED", 2);
221
- define("CURLCLOSEPOLICY_LEAST_TRAFFIC", 3);
222
- define("CURLCLOSEPOLICY_SLOWEST", 4);
223
- define("CURLCLOSEPOLICY_CALLBACK", 5);
224
- define("CURLCLOSEPOLICY_OLDEST", 1);
225
-
226
- // Info constants.
227
- define("CURLINFO_EFFECTIVE_URL", 0x100000 + 1);
228
- define("CURLINFO_HTTP_CODE", 0x200000 + 2);
229
- define("CURLINFO_RESPONSE_CODE", 0x200000 + 2);
230
- define("CURLINFO_HEADER_SIZE", 0x200000 + 11);
231
- define("CURLINFO_REQUEST_SIZE", 0x200000 + 12);
232
- define("CURLINFO_TOTAL_TIME", 0x300000 + 3);
233
- define("CURLINFO_NAMELOOKUP_TIME", 0x300000 + 4);
234
- define("CURLINFO_CONNECT_TIME", 0x300000 + 5);
235
- define("CURLINFO_PRETRANSFER_TIME", 0x300000 + 6);
236
- define("CURLINFO_SIZE_UPLOAD", 0x300000 + 7);
237
- define("CURLINFO_SIZE_DOWNLOAD", 0x300000 + 8);
238
- define("CURLINFO_SPEED_DOWNLOAD", 0x300000 + 9);
239
- define("CURLINFO_SPEED_UPLOAD", 0x300000 + 10);
240
- define("CURLINFO_FILETIME", 0x200000 + 14);
241
- define("CURLINFO_SSL_VERIFYRESULT", 0x200000 + 14);
242
- define("CURLINFO_CONTENT_LENGTH_DOWNLOAD", 0x300000 + 15);
243
- define("CURLINFO_CONTENT_LENGTH_UPLOAD", 0x300000 + 16);
244
- define("CURLINFO_STARTTRANSFER_TIME", 0x300000 + 17);
245
- define("CURLINFO_CONTENT_TYPE", 0x100000 + 18);
246
- define("CURLINFO_REDIRECT_TIME", 0x300000 + 19);
247
- define("CURLINFO_REDIRECT_COUNT", 0x200000 + 20);
248
- define("CURLINFO_HEADER_OUT", 2);
249
- define("CURLINFO_PRIVATE", 0x100000 + 21);
250
- define("CURLINFO_CERTINFO", 0x400000 + 34);
251
- define("CURLINFO_REDIRECT_URL", 0x100000 + 31);
252
-
253
- // cURL compile-time constants (curl_version).
254
- define("CURL_VERSION_IPV6", 1);
255
- define("CURL_VERSION_KERBEROS4", 2);
256
- define("CURL_VERSION_SSL", 4);
257
- define("CURL_VERSION_LIBZ", 8);
258
- define("CURL_VERSION_NTLM", 16);
259
- define("CURL_VERSION_GSSNEGOTIATE", 32);
260
- define("CURL_VERSION_DEBUG", 64);
261
- define("CURL_VERSION_ASYNCHDNS", 128);
262
- define("CURL_VERSION_SPNEGO", 256);
263
- define("CURL_VERSION_LARGEFILE", 512);
264
- define("CURL_VERSION_IDN", 1024);
265
- define("CURL_VERSION_SSPI", 2048);
266
- define("CURL_VERSION_CONV", 4096);
267
- define("CURL_VERSION_CURLDEBUG", 8192);
268
- define("CURL_VERSION_TLSAUTH_SRP", 16384);
269
- define("CURL_VERSION_NTLM_WB", 32768);
270
-
271
- // Version constants.
272
- define("CURLVERSION_NOW", 3);
273
-
274
- // Error constants.
275
- foreach ($curl_error__map as $num => $name)
276
- {
277
- if (!defined($name)) define($name, $num);
278
- }
279
-
280
- // Dear PHP devs: Comment your code. Thanks.
281
- define("CURLPROXY_HTTP", 0);
282
- define("CURLPROXY_HTTP_1_0", 1);
283
- define("CURLPROXY_SOCKS4", 4);
284
- define("CURLPROXY_SOCKS5", 5);
285
- define("CURLPROXY_SOCKS4A", 6);
286
- define("CURLPROXY_SOCKS5_HOSTNAME", 7);
287
-
288
- define("CURL_NETRC_OPTIONAL", 1);
289
- define("CURL_NETRC_IGNORED", 0);
290
- define("CURL_NETRC_REQUIRED", 2);
291
-
292
- define("CURL_HTTP_VERSION_NONE", 0);
293
- define("CURL_HTTP_VERSION_1_0", 1);
294
- define("CURL_HTTP_VERSION_1_1", 2);
295
-
296
- define("CURLM_CALL_MULTI_PERFORM", -1);
297
- define("CURLM_OK", 0);
298
- define("CURLM_BAD_HANDLE", 1);
299
- define("CURLM_BAD_EASY_HANDLE", 2);
300
- define("CURLM_OUT_OF_MEMORY", 3);
301
- define("CURLM_INTERNAL_ERROR", 4);
302
- define("CURLM_BAD_SOCKET", 5);
303
- define("CURLM_UNKNOWN_OPTION", 6);
304
-
305
- define("CURLMSG_DONE", 1);
306
-
307
- define("CURLOPT_FTPSSLAUTH", 129);
308
- define("CURLFTPAUTH_DEFAULT", 0);
309
- define("CURLFTPAUTH_SSL", 1);
310
- define("CURLFTPAUTH_TLS", 2);
311
- define("CURLOPT_FTP_SSL", 119);
312
- define("CURLFTPSSL_NONE", 0);
313
- define("CURLFTPSSL_TRY", 1);
314
- define("CURLFTPSSL_CONTROL", 2);
315
- define("CURLFTPSSL_ALL", 3);
316
- define("CURLUSESSL_NONE", 0);
317
- define("CURLUSESSL_TRY", 1);
318
- define("CURLUSESSL_CONTROL", 2);
319
- define("CURLUSESSL_ALL", 3);
320
-
321
- define("CURLOPT_CERTINFO", 172);
322
- define("CURLOPT_POSTREDIR", 161);
323
-
324
- define("CURLSSH_AUTH_ANY", -1);
325
- define("CURLSSH_AUTH_NONE", 0);
326
- define("CURLSSH_AUTH_PUBLICKEY", 1);
327
- define("CURLSSH_AUTH_PASSWORD", 2);
328
- define("CURLSSH_AUTH_HOST", 4);
329
- define("CURLSSH_AUTH_KEYBOARD", 8);
330
- define("CURLSSH_AUTH_DEFAULT", -1);
331
- define("CURLOPT_SSH_AUTH_TYPES", 151);
332
- define("CURLOPT_KEYPASSWD", 10026);
333
- define("CURLOPT_SSH_PUBLIC_KEYFILE", 10152);
334
- define("CURLOPT_SSH_PRIVATE_KEYFILE", 10153);
335
- define("CURLOPT_SSH_HOST_PUBLIC_KEY_MD5", 10162);
336
-
337
- define("CURLOPT_REDIR_PROTOCOLS", 182);
338
- define("CURLOPT_PROTOCOLS", 181);
339
- define("CURLPROTO_HTTP", 1);
340
- define("CURLPROTO_HTTPS", 2);
341
- define("CURLPROTO_FTP", 4);
342
- define("CURLPROTO_FTPS", 8);
343
- define("CURLPROTO_SCP", 16);
344
- define("CURLPROTO_SFTP", 32);
345
- define("CURLPROTO_TELNET", 64);
346
- define("CURLPROTO_LDAP", 128);
347
- define("CURLPROTO_LDAPS", 256);
348
- define("CURLPROTO_DICT", 512);
349
- define("CURLPROTO_FILE", 1024);
350
- define("CURLPROTO_TFTP", 2048);
351
- define("CURLPROTO_ALL", -1);
352
-
353
- define("CURLOPT_FTP_FILEMETHOD", 138);
354
- define("CURLOPT_FTP_SKIP_PASV_IP", 137);
355
-
356
- define("CURLFTPMETHOD_DEFAULT", 0);
357
- define("CURLFTPMETHOD_MULTICWD", 1);
358
- define("CURLFTPMETHOD_NOCWD", 2);
359
- define("CURLFTPMETHOD_SINGLECWD", 3);
360
-
361
- // Emulation internal use ONLY. DO NOT USE!
362
- define("CURLOPT_DEBUGFUNCTION", 20094);
363
- define("CURLOPT_DEBUGDATA", 10095);
364
-
365
- // Internal functions used by the public emulation routines.
366
- $curl_init__map = array();
367
- function get_curl_init_key($ch)
368
- {
369
- ob_start();
370
- echo $ch;
371
- ob_end_clean();
372
-
373
- return ob_get_contents();
374
- }
375
-
376
- function get_check_curl_init_key($ch)
377
- {
378
- global $curl_init__map;
379
-
380
- $key = get_curl_init_key($ch);
381
- if (!isset($curl_init__map[$key])) throw new Exception(HTTP::HTTPTranslate("cURL Emulator: Unable to find key mapping for resource."));
382
-
383
- return $key;
384
- }
385
-
386
- // Public emulation functions.
387
- function curl_version($age = CURLVERSION_NOW)
388
- {
389
- $curlversion = "7.25.0";
390
- $curlvernum = explode(".", $curlversion);
391
-
392
- $result = array(
393
- "version_number" => (($curlvernum[0] << 16) | ($curlvernum[1] << 8) | $curlvernum[2]),
394
- "age" => $age,
395
- "features" => CURL_VERSION_IPV6 | (defined("OPENSSL_VERSION_TEXT") ? CURL_VERSION_SSL : 0) | CURL_VERSION_DEBUG | CURL_VERSION_CURLDEBUG | CURL_VERSION_LARGEFILE | CURL_VERSION_IDN | CURL_VERSION_CONV,
396
- "ssl_version_number" => 0,
397
- "version" => $curlversion,
398
- "host" => "i386-pc-win32",
399
- "ssl_version" => (defined("OPENSSL_VERSION_TEXT") ? implode("/", array_slice(explode(" ", OPENSSL_VERSION_TEXT), 0, 2)) : ""),
400
- "libz_version" => "",
401
- "protocols" => array("http", "https")
402
- );
403
-
404
- return $result;
405
- }
406
-
407
- function curl_init($url = false)
408
- {
409
- global $curl_init__map;
410
-
411
- // Evil hack to create a "resource" so that is_resource() works.
412
- // get_resource_type() will reveal its true identity but only an idiot would ever call that function.
413
- $ch = fopen(__FILE__, "rb");
414
- $key = get_curl_init_key($ch);
415
- $options = array(
416
- CURLOPT_NOPROGRESS => true,
417
- CURLOPT_VERBOSE => false,
418
- CURLOPT_DNS_USE_GLOBAL_CACHE => true,
419
- CURLOPT_DNS_CACHE_TIMEOUT => 120,
420
- CURLOPT_MAXREDIRS => 20,
421
- CURLOPT_URL => $url
422
- );
423
-
424
- if (!class_exists("WebBrowser", false)) require_once str_replace("\\", "/", dirname(__FILE__)) . "/web_browser.php";
425
-
426
- $curl_init__map[$key] = array("self" => $ch, "method" => "GET", "options" => $options, "browser" => new WebBrowser(), "errorno" => CURLE_OK, "errorinfo" => "");
427
-
428
- return $ch;
429
- }
430
-
431
- function curl_errno($ch)
432
- {
433
- global $curl_init__map;
434
-
435
- $key = get_check_curl_init_key($ch);
436
-
437
- return $curl_init__map[$key]["errorno"];
438
- }
439
-
440
- function curl_error($ch)
441
- {
442
- global $curl_init__map;
443
-
444
- $key = get_check_curl_init_key($ch);
445
-
446
- return ($curl_init__map[$key]["errorinfo"] == "" ? "" : $curl_error__map[$curl_init__map[$key]["errorno"]] . " - " . $curl_init__map[$key]["errorinfo"]);
447
- }
448
-
449
- function curl_copy_handle($ch)
450
- {
451
- global $curl_init__map;
452
-
453
- $key = get_check_curl_init_key($ch);
454
-
455
- $ch = fopen(__FILE__, "rb");
456
- $key2 = get_curl_init_key($resource);
457
- $curl_init__map[$key2] = $curl_init__map[$key];
458
-
459
- return $ch;
460
- }
461
-
462
- function curl_close($ch)
463
- {
464
- global $curl_init__map;
465
-
466
- $key = get_check_curl_init_key($ch);
467
- unset($curl_init__map[$key]);
468
- fclose($ch);
469
- }
470
-
471
- function curl_setopt($ch, $option, $value)
472
- {
473
- global $curl_init__map;
474
-
475
- $key = get_check_curl_init_key($ch);
476
-
477
- if ($option != CURLINFO_HEADER_OUT)
478
- {
479
- if ($value === null) unset($curl_init__map[$key]["options"][$option]);
480
- else
481
- {
482
- if ($option == CURLOPT_HTTPGET && $value) $curl_init__map[$key]["method"] = "GET";
483
- else if ($option == CURLOPT_NOBODY && $value) $curl_init__map[$key]["method"] = "HEAD";
484
- else if ($option == CURLOPT_POST && $value) $curl_init__map[$key]["method"] = "POST";
485
- else if ($option == CURLOPT_PUT && $value) $curl_init__map[$key]["method"] = "PUT";
486
- else if ($option == CURLOPT_CUSTOMREQUEST) $curl_init__map[$key]["method"] = $value;
487
-
488
- $curl_init__map[$key]["options"][$option] = $value;
489
- }
490
- }
491
- else if ((bool)$value)
492
- {
493
- $curl_init__map[$key]["options"]["__CURLINFO_HEADER_OUT"] = true;
494
- }
495
- else
496
- {
497
- unset($curl_init__map[$key]["options"]["__CURLINFO_HEADER_OUT"]);
498
- }
499
-
500
- $curl_init__map[$key]["errorno"] = CURLE_OK;
501
- $curl_init__map[$key]["errorinfo"] = "";
502
-
503
- return true;
504
- }
505
-
506
- function curl_setopt_array($ch, $options)
507
- {
508
- foreach ($options as $option => $value)
509
- {
510
- if (!curl_setopt($ch, $option, $value)) return false;
511
- }
512
-
513
- return true;
514
- }
515
-
516
- function curl_exec($ch)
517
- {
518
- global $curl_init__map;
519
-
520
- $key = get_check_curl_init_key($ch);
521
-
522
- // Set allowed protocols.
523
- $allowedprotocols = array("http" => true, "https" => true);
524
- if (isset($curl_init__map[$key]["options"][CURLOPT_PROTOCOLS]))
525
- {
526
- $allowedprotocols["http"] = (bool)($curl_init__map[$key]["options"][CURLOPT_PROTOCOLS] & CURLPROTO_HTTP);
527
- $allowedprotocols["https"] = (bool)($curl_init__map[$key]["options"][CURLOPT_PROTOCOLS] & CURLPROTO_HTTPS);
528
- }
529
- $curl_init__map[$key]["browser"]->SetState(array("allowedprotocols" => $allowedprotocols));
530
-
531
- // Set allowed redirect protocols.
532
- $allowedprotocols = array("http" => true, "https" => true);
533
- if (isset($curl_init__map[$key]["options"][CURLOPT_REDIR_PROTOCOLS]))
534
- {
535
- $allowedprotocols["http"] = (bool)($curl_init__map[$key]["options"][CURLOPT_REDIR_PROTOCOLS] & CURLPROTO_HTTP);
536
- $allowedprotocols["https"] = (bool)($curl_init__map[$key]["options"][CURLOPT_REDIR_PROTOCOLS] & CURLPROTO_HTTPS);
537
- }
538
- $curl_init__map[$key]["browser"]->SetState(array("allowedredirprotocols" => $allowedprotocols));
539
-
540
- // Load cookies. Violates the PHP/cURL definition a lot. Whatever.
541
- if (isset($curl_init__map[$key]["options"][CURLOPT_COOKIEFILE]) && is_string($curl_init__map[$key]["options"][CURLOPT_COOKIEFILE]) && $curl_init__map[$key]["options"][CURLOPT_COOKIEFILE] != "")
542
- {
543
- $data = @unserialize(@file_get_contents($curl_init__map[$key]["options"][CURLOPT_COOKIEFILE]));
544
- if ($data !== false && is_array($data))
545
- {
546
- // Load the WebBrowser() object with the cookies.
547
- $curl_init__map[$key]["browser"]->SetState(array("cookies" => $data));
548
- }
549
- $curl_init__map[$key]["options"][CURLOPT_COOKIEFILE] = "";
550
- }
551
- if (isset($curl_init__map[$key]["options"][CURLOPT_COOKIESESSION]) && $curl_init__map[$key]["options"][CURLOPT_COOKIESESSION]) $curl_init__map[$key]["browser"]->DeleteSessionCookies();
552
-
553
- // Set the autoreferer setting.
554
- $curl_init__map[$key]["browser"]->SetState(array("autoreferer" => (isset($curl_init__map[$key]["options"][CURLOPT_AUTOREFERER]) && $curl_init__map[$key]["options"][CURLOPT_AUTOREFERER])));
555
-
556
- // Set the Referer.
557
- if (isset($curl_init__map[$key]["options"][CURLOPT_REFERER]) && is_string($curl_init__map[$key]["options"][CURLOPT_REFERER]))
558
- {
559
- $curl_init__map[$key]["browser"]->SetState(array("referer" => $curl_init__map[$key]["options"][CURLOPT_REFERER]));
560
- }
561
-
562
- // Set the followlocation and maxfollow settings.
563
- $curl_init__map[$key]["browser"]->SetState(array("followlocation" => (isset($curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION]) && $curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION])));
564
- $curl_init__map[$key]["browser"]->SetState(array("maxfollow" => (isset($curl_init__map[$key]["options"][CURLOPT_MAXREDIRS]) ? $curl_init__map[$key]["options"][CURLOPT_MAXREDIRS] : 20)));
565
-
566
- // Set up the options array.
567
- $options = array();
568
-
569
- // Set connect and total timeout options.
570
- if (isset($curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT]) || isset($curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT_MS]))
571
- {
572
- $timeout = (isset($curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT]) ? $curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT] : 0) + ((isset($curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT_MS]) ? $curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT_MS] : 0) / 1000);
573
- if ($timeout > 0)
574
- {
575
- $options["connecttimeout"] = $timeout;
576
- $options["proxyconnecttimeout"] = $timeout;
577
- }
578
- }
579
- if (isset($curl_init__map[$key]["options"][CURLOPT_TIMEOUT]) || isset($curl_init__map[$key]["options"][CURLOPT_TIMEOUT_MS]))
580
- {
581
- $timeout = (isset($curl_init__map[$key]["options"][CURLOPT_TIMEOUT]) ? $curl_init__map[$key]["options"][CURLOPT_TIMEOUT] : 0) + ((isset($curl_init__map[$key]["options"][CURLOPT_TIMEOUT_MS]) ? $curl_init__map[$key]["options"][CURLOPT_TIMEOUT_MS] : 0) / 1000);
582
- if ($timeout > 0)
583
- {
584
- $options["connecttimeout"] = $timeout;
585
- $options["proxyconnecttimeout"] = $timeout;
586
- }
587
- }
588
-
589
- // Set proxy options.
590
- if (isset($curl_init__map[$key]["options"][CURLOPT_PROXY]))
591
- {
592
- if (isset($curl_init__map[$key]["options"][CURLOPT_PROXYTYPE]) && $curl_init__map[$key]["options"][CURLOPT_PROXYTYPE] != CURLPROXY_HTTP)
593
- {
594
- $curl_init__map[$key]["errorno"] = CURLE_UNSUPPORTED_PROTOCOL;
595
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("CURLOPT_PROXYTYPE option is unsupported.");
596
-
597
- return false;
598
- }
599
-
600
- $proxyurl = $curl_init__map[$key]["options"][CURLOPT_PROXY];
601
- $proxyport = (int)(isset($curl_init__map[$key]["options"][CURLOPT_PROXYPORT]) ? $curl_init__map[$key]["options"][CURLOPT_PROXYPORT] : false);
602
- if ($proxyport < 1 || $proxyport > 65535) $proxyport = false;
603
- if (strpos($proxyurl, "://") === false) $proxyurl = ($proxyport == 443 ? "https://" : "http://") . $proxyurl;
604
-
605
- $proxyurl = HTTP::ExtractURL($proxyurl);
606
- if ($proxyport !== false) $proxyurl["port"] = $proxyport;
607
- if (isset($curl_init__map[$key]["options"][CURLOPT_PROXYUSERPWD]))
608
- {
609
- $userpass = explode(":", $curl_init__map[$key]["options"][CURLOPT_PROXYUSERPWD]);
610
- if (count($userpass) == 2)
611
- {
612
- $proxyurl["loginusername"] = urldecode($userpass[0]);
613
- $proxyurl["loginpassword"] = urldecode($userpass[1]);
614
- }
615
- }
616
- $options["proxyurl"] = HTTP::CondenseURL($proxyurl);
617
-
618
- if (isset($curl_init__map[$key]["options"][CURLOPT_HTTPPROXYTUNNEL])) $options["proxyconnect"] = $curl_init__map[$key]["options"][CURLOPT_HTTPPROXYTUNNEL];
619
- }
620
-
621
- // Set SSL options.
622
- $options["sslopts"] = array();
623
- $options["sslopts"]["verify_peer"] = (isset($curl_init__map[$key]["options"][CURLOPT_SSL_VERIFYPEER]) ? $curl_init__map[$key]["options"][CURLOPT_SSL_VERIFYPEER] : true);
624
- if (isset($curl_init__map[$key]["options"][CURLOPT_CAINFO])) $options["sslopts"]["cafile"] = $curl_init__map[$key]["options"][CURLOPT_CAINFO];
625
- if (isset($curl_init__map[$key]["options"][CURLOPT_CAPATH])) $options["sslopts"]["capath"] = $curl_init__map[$key]["options"][CURLOPT_CAPATH];
626
- if (!isset($options["sslopts"]["cafile"]) && !isset($options["sslopts"]["capath"])) $options["sslopts"]["auto_cainfo"] = true;
627
- if (isset($curl_init__map[$key]["options"][CURLOPT_SSLCERT]) && isset($curl_init__map[$key]["options"][CURLOPT_SSLKEY]))
628
- {
629
- if ($curl_init__map[$key]["options"][CURLOPT_SSLCERT] !== $curl_init__map[$key]["options"][CURLOPT_SSLKEY])
630
- {
631
- $curl_init__map[$key]["errorno"] = CURLE_SSL_CONNECT_ERROR;
632
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("CURLOPT_SSLCERT and CURLOPT_SSLKEY must be identical.");
633
-
634
- return false;
635
- }
636
- $certpass = (isset($curl_init__map[$key]["options"][CURLOPT_SSLCERTPASSWD]) ? $curl_init__map[$key]["options"][CURLOPT_SSLCERTPASSWD] : false);
637
- $keypass = (isset($curl_init__map[$key]["options"][CURLOPT_SSLKEYPASSWD]) ? $curl_init__map[$key]["options"][CURLOPT_SSLKEYPASSWD] : false);
638
- if ($certpass !== $keypass)
639
- {
640
- $curl_init__map[$key]["errorno"] = CURLE_SSL_CONNECT_ERROR;
641
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("CURLOPT_SSLCERTPASSWD and CURLOPT_SSLKEYPASSWD must be identical.");
642
-
643
- return false;
644
- }
645
- $certtype = strtoupper(isset($curl_init__map[$key]["options"][CURLOPT_SSLCERTTYPE]) ? $curl_init__map[$key]["options"][CURLOPT_SSLCERTTYPE] : "PEM");
646
- $keytype = strtoupper(isset($curl_init__map[$key]["options"][CURLOPT_SSLKEYTYPE]) ? $curl_init__map[$key]["options"][CURLOPT_SSLKEYTYPE] : "PEM");
647
- if ($certpass !== $keypass || $cert !== "PEM")
648
- {
649
- $curl_init__map[$key]["errorno"] = CURLE_SSL_CONNECT_ERROR;
650
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("CURLOPT_SSLCERTTYPE and CURLOPT_SSLKEYTYPE must be PEM format.");
651
-
652
- return false;
653
- }
654
-
655
- $options["sslopts"]["local_cert"] = $curl_init__map[$key]["options"][CURLOPT_SSLCERT];
656
- if ($certpass !== false) $options["sslopts"]["passphrase"] = $certpass;
657
- }
658
- if (isset($curl_init__map[$key]["options"][CURLOPT_SSL_CIPHER_LIST])) $options["sslopts"]["ciphers"] = $curl_init__map[$key]["options"][CURLOPT_SSL_CIPHER_LIST];
659
- $options["sslopts"]["auto_cn_match"] = true;
660
- $options["sslopts"]["auto_sni"] = true;
661
- $options["sslopts"]["capture_peer_cert"] = (isset($curl_init__map[$key]["options"][CURLOPT_CERTINFO]) ? $curl_init__map[$key]["options"][CURLOPT_CERTINFO] : false);
662
-
663
- // Set the method.
664
- if (isset($curl_init__map[$key]["options"][CURLOPT_UPLOAD]) && (bool)$curl_init__map[$key]["options"][CURLOPT_UPLOAD]) $options["method"] = "PUT";
665
- else $options["method"] = $curl_init__map[$key]["method"];
666
-
667
- // Set the HTTP version.
668
- if (isset($curl_init__map[$key]["options"][CURLOPT_HTTP_VERSION]))
669
- {
670
- if ($curl_init__map[$key]["options"][CURLOPT_HTTP_VERSION] == CURL_HTTP_VERSION_1_0) $options["httpver"] = "1.0";
671
- else if ($curl_init__map[$key]["options"][CURLOPT_HTTP_VERSION] == CURL_HTTP_VERSION_1_1) $options["httpver"] = "1.1";
672
- }
673
-
674
- // Set rate limits.
675
- if (isset($curl_init__map[$key]["options"][CURLOPT_MAX_RECV_SPEED_LARGE])) $options["recvratelimit"] = $curl_init__map[$key]["options"][CURLOPT_MAX_RECV_SPEED_LARGE];
676
- if (isset($curl_init__map[$key]["options"][CURLOPT_MAX_SEND_SPEED_LARGE])) $options["sendratelimit"] = $curl_init__map[$key]["options"][CURLOPT_MAX_SEND_SPEED_LARGE];
677
-
678
- // Set headers.
679
- $options["headers"] = array();
680
- $options["headers"]["Accept"] = "*/*";
681
- if (isset($curl_init__map[$key]["options"][CURLOPT_HTTPHEADER]) && is_array($curl_init__map[$key]["options"][CURLOPT_HTTPHEADER]))
682
- {
683
- foreach ($curl_init__map[$key]["options"][CURLOPT_HTTPHEADER] as $header)
684
- {
685
- $pos = strpos($header, ":");
686
- if ($pos !== false)
687
- {
688
- $val = ltrim(substr($header, $pos + 1));
689
- if ($val == "") unset($options["headers"][HTTP::HeaderNameCleanup(substr($header, 0, $pos))]);
690
- else $options["headers"][HTTP::HeaderNameCleanup(substr($header, 0, $pos))] = $val;
691
- }
692
- }
693
- }
694
- if (isset($curl_init__map[$key]["options"][CURLOPT_USERAGENT])) $options["headers"]["User-Agent"] = $curl_init__map[$key]["options"][CURLOPT_USERAGENT];
695
- if (isset($curl_init__map[$key]["options"][CURLOPT_COOKIE])) $options["headers"]["Cookie"] = $curl_init__map[$key]["options"][CURLOPT_COOKIE];
696
- if (isset($curl_init__map[$key]["options"][CURLOPT_RANGE])) $options["headers"]["Range"] = "bytes=" . $curl_init__map[$key]["options"][CURLOPT_RANGE];
697
- if (isset($curl_init__map[$key]["options"][CURLOPT_RESUME_FROM])) $options["headers"]["Range"] = "bytes=" . $curl_init__map[$key]["options"][CURLOPT_RESUME_FROM] . "-";
698
- if (isset($curl_init__map[$key]["options"][CURLOPT_TIMECONDITION]) && isset($curl_init__map[$key]["options"][CURLOPT_TIMEVALUE]))
699
- {
700
- if ($curl_init__map[$key]["options"][CURLOPT_TIMECONDITION] == CURL_TIMECOND_IFMODSINCE) $options["headers"]["If-Modified-Since"] = gmdate("D, d M Y H:i:s", $curl_init__map[$key]["options"][CURLOPT_TIMEVALUE]) . " GMT";
701
- else if ($curl_init__map[$key]["options"][CURLOPT_TIMECONDITION] == CURL_TIMECOND_IFUNMODSINCE) $options["headers"]["If-Unmodified-Since"] = gmdate("D, d M Y H:i:s", $curl_init__map[$key]["options"][CURLOPT_TIMEVALUE]) . " GMT";
702
- }
703
-
704
- // Set POST variables and files.
705
- if (isset($curl_init__map[$key]["options"][CURLOPT_POSTFIELDS]))
706
- {
707
- $postvars = $curl_init__map[$key]["options"][CURLOPT_POSTFIELDS];
708
- if (is_string($postvars))
709
- {
710
- $postvars2 = array();
711
- $postvars = explode("&", $postvars);
712
- foreach ($postvars as $postvar)
713
- {
714
- $pos = strpos($postvar, "=");
715
- if ($pos === false)
716
- {
717
- $name = urldecode($postvar);
718
- $val = "";
719
- }
720
- else
721
- {
722
- $name = urldecode(substr($postvar, 0, $pos));
723
- $val = urldecode(substr($postvar, $pos + 1));
724
- }
725
-
726
- if (!isset($postvars2[$name])) $postvars2[$name] = array();
727
- $postvars2[$name][] = $val;
728
- }
729
- $postvars = $postvars2;
730
- unset($postvars2);
731
- }
732
-
733
- foreach ($postvars as $name => $vals)
734
- {
735
- if (is_string($vals) || is_numeric($vals)) $vals = array($vals);
736
- foreach ($vals as $num => $val)
737
- {
738
- // Move files to their own array.
739
- if (substr($val, 0, 1) == "@")
740
- {
741
- $pos = strrpos($val, ";type=");
742
- if ($pos === false) $mimetype = "";
743
- else
744
- {
745
- $mimetype = substr($val, $pos + 6);
746
- $val = substr($val, 0, $pos);
747
- }
748
-
749
- $val = substr($val, 1);
750
- if (file_exists($val))
751
- {
752
- if (!isset($options["files"])) $options["files"] = array();
753
- $options["files"][] = array(
754
- "name" => $name,
755
- "filename" => HTTP::FilenameSafe(HTTP::ExtractFilename($val)),
756
- "type" => $mimetype,
757
- "datafile" => $val
758
- );
759
-
760
- unset($vals[$num]);
761
- }
762
- }
763
- }
764
-
765
- if (!count($vals)) unset($postvars[$name]);
766
- else $postvars[$name] = $vals;
767
- }
768
-
769
- $options["postvars"] = $postvars;
770
- $options["method"] = "POST";
771
- }
772
-
773
- // Process the URL.
774
- if (!isset($curl_init__map[$key]["options"][CURLOPT_URL]) || !is_string($curl_init__map[$key]["options"][CURLOPT_URL]) || $curl_init__map[$key]["options"][CURLOPT_URL] == "")
775
- {
776
- $curl_init__map[$key]["errorno"] = CURLE_URL_MALFORMAT;
777
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("No CURLOPT_URL option specified.");
778
-
779
- return false;
780
- }
781
- $url = HTTP::ExtractURL($curl_init__map[$key]["options"][CURLOPT_URL]);
782
- if ($url["scheme"] == "")
783
- {
784
- $curl_init__map[$key]["errorno"] = CURLE_URL_MALFORMAT;
785
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("CURLOPT_URL does not have a scheme.");
786
-
787
- return false;
788
- }
789
- if ($url["host"] == "")
790
- {
791
- $curl_init__map[$key]["errorno"] = CURLE_URL_MALFORMAT;
792
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("CURLOPT_URL does not specify a valid host.");
793
-
794
- return false;
795
- }
796
- if (isset($curl_init__map[$key]["options"][CURLOPT_PORT]) && (int)$curl_init__map[$key]["options"][CURLOPT_PORT] > 0 && (int)$curl_init__map[$key]["options"][CURLOPT_PORT] < 65536)
797
- {
798
- $url["port"] = (int)$curl_init__map[$key]["options"][CURLOPT_PORT];
799
- }
800
- if (isset($curl_init__map[$key]["options"][CURLOPT_USERPWD]))
801
- {
802
- $userpass = explode(":", $curl_init__map[$key]["options"][CURLOPT_USERPWD]);
803
- if (count($userpass) == 2)
804
- {
805
- $url["loginusername"] = urldecode($userpass[0]);
806
- $url["loginpassword"] = urldecode($userpass[1]);
807
- }
808
- }
809
- else if (isset($curl_init__map[$key]["options"][CURLOPT_NETRC]) && $curl_init__map[$key]["options"][CURLOPT_NETRC])
810
- {
811
- $data = @file_get_contents("~/.netrc");
812
- if ($data !== false)
813
- {
814
- $lines = explode("\n", $data);
815
- unset($data);
816
- $host = false;
817
- $user = false;
818
- $password = false;
819
- foreach ($lines as $line)
820
- {
821
- $line = trim($line);
822
- if (substr($line, 0, 8) == "machine ") $host = trim(substr($line, 8));
823
- if (substr($line, 0, 6) == "login ") $user = trim(substr($line, 6));
824
- if (substr($line, 0, 9) == "password ") $password = trim(substr($line, 9));
825
-
826
- if ($host !== false && $user !== false && $password !== false)
827
- {
828
- if ($host === $url["host"] || (isset($options["headers"]["Host"]) && $host === $options["headers"]["Host"]))
829
- {
830
- $url["loginusername"] = $user;
831
- $url["loginpassword"] = $password;
832
- }
833
-
834
- $host = false;
835
- $user = false;
836
- $password = false;
837
- }
838
- }
839
- unset($lines);
840
- }
841
- }
842
-
843
- // Condense URL.
844
- $url = HTTP::CondenseURL($url);
845
-
846
- // Set up internal callbacks.
847
- $options["read_headers_callback"] = "internal_curl_read_headers_callback";
848
- $options["read_headers_callback_opts"] = $key;
849
-
850
- if (!isset($curl_init__map[$key]["options"][CURLOPT_NOBODY]) || !$curl_init__map[$key]["options"][CURLOPT_NOBODY])
851
- {
852
- $options["read_body_callback"] = "internal_curl_read_body_callback";
853
- $options["read_body_callback_opts"] = $key;
854
- }
855
-
856
- if ($options["method"] != "GET" && $options["method"] != "POST")
857
- {
858
- $options["write_body_callback"] = "internal_curl_write_body_callback";
859
- $options["write_body_callback_opts"] = $key;
860
- }
861
-
862
- $options["debug_callback"] = "internal_curl_debug_callback";
863
- $options["debug_callback_opts"] = $key;
864
-
865
- // Remove weird callback results.
866
- unset($curl_init__map[$key]["rawproxyheaders"]);
867
- unset($curl_init__map[$key]["rawheaders"]);
868
- unset($curl_init__map[$key]["returnresponse"]);
869
- unset($curl_init__map[$key]["returnheader"]);
870
- unset($curl_init__map[$key]["returnbody"]);
871
- unset($curl_init__map[$key]["filetime"]);
872
- $curl_init__map[$key]["outputbody"] = false;
873
-
874
- // Process the request.
875
- $options["profile"] = "";
876
- $result = $curl_init__map[$key]["browser"]->Process($url, $options);
877
- $curl_init__map[$key]["lastresult"] = $result;
878
-
879
- // Deal with cookies.
880
- if (!isset($curl_init__map[$key]["options"][CURLOPT_COOKIEFILE]) || !is_string($curl_init__map[$key]["options"][CURLOPT_COOKIEFILE]))
881
- {
882
- // Delete all cookies for another run later.
883
- $curl_init__map[$key]["browser"]->SetState(array("cookies" => array()));
884
- }
885
- else if (isset($curl_init__map[$key]["options"][CURLOPT_COOKIEJAR]))
886
- {
887
- // Write out cookies here. Another violation of how cURL does things. Another - whatever.
888
- $state = $curl_init__map[$key]["browser"]->GetState();
889
- file_put_contents($curl_init__map[$key]["options"][CURLOPT_COOKIEJAR], serialize($state["cookies"]));
890
- }
891
-
892
- // Process the response.
893
- if (!$result["success"])
894
- {
895
- if ($result["errorcode"] == "allowed_protocols")
896
- {
897
- $curl_init__map[$key]["errorno"] = CURLE_UNSUPPORTED_PROTOCOL;
898
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("The cURL emulation layer does not support the protocol or was redirected to an unsupported protocol by the host. %s", $result["error"]);
899
- }
900
- else if ($result["errorcode"] == "allowed_redir_protocols")
901
- {
902
- $curl_init__map[$key]["errorno"] = CURLE_UNSUPPORTED_PROTOCOL;
903
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("The cURL emulation layer was redirected to an unsupported protocol by the host. %s", $result["error"]);
904
- }
905
- else if ($result["errorcode"] == "retrievewebpage")
906
- {
907
- if ($result["info"]["errorcode"] == "timeout_exceeded")
908
- {
909
- $curl_init__map[$key]["errorno"] = CURLE_OPERATION_TIMEDOUT;
910
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("The operation timed out. %s", $result["error"]);
911
- }
912
- else if ($result["info"]["errorcode"] == "get_response_line")
913
- {
914
- $curl_init__map[$key]["errorno"] = CURLE_READ_ERROR;
915
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("Unable to get the response line. %s", $result["error"]);
916
- }
917
- else if ($result["info"]["errorcode"] == "read_header_callback")
918
- {
919
- $curl_init__map[$key]["errorno"] = CURLE_READ_ERROR;
920
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("A read error occurred in the read header callback. %s", $result["error"]);
921
- }
922
- else if ($result["info"]["errorcode"] == "read_body_callback")
923
- {
924
- $curl_init__map[$key]["errorno"] = CURLE_READ_ERROR;
925
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("A read error occurred in the read body callback. %s", $result["error"]);
926
- }
927
- else if ($result["info"]["errorcode"] == "function_check")
928
- {
929
- $curl_init__map[$key]["errorno"] = CURLE_FUNCTION_NOT_FOUND;
930
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("A required function was not found. %s", $result["error"]);
931
- }
932
- else if ($result["info"]["errorcode"] == "protocol_check")
933
- {
934
- $curl_init__map[$key]["errorno"] = CURLE_UNSUPPORTED_PROTOCOL;
935
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("The cURL emulation layer does not support the protocol or was redirected to an unsupported protocol by the host. %s", $result["error"]);
936
- }
937
- else if ($result["info"]["errorcode"] == "transport_not_installed")
938
- {
939
- $curl_init__map[$key]["errorno"] = CURLE_NOT_BUILT_IN;
940
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("The cURL emulation layer attempted to use a required transport to connect to a host but failed. %s", $result["error"]);
941
- }
942
- else if ($result["info"]["errorcode"] == "proxy_transport_not_installed")
943
- {
944
- $curl_init__map[$key]["errorno"] = CURLE_NOT_BUILT_IN;
945
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("The cURL emulation layer attempted to use a required transport to connect to a proxy but failed. %s", $result["error"]);
946
- }
947
- else if ($result["info"]["errorcode"] == "proxy_connect")
948
- {
949
- $curl_init__map[$key]["errorno"] = CURLE_COULDNT_CONNECT;
950
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("Unable to connect to the proxy. %s", $result["error"]);
951
- }
952
- else if ($result["info"]["errorcode"] == "proxy_connect_tunnel")
953
- {
954
- $curl_init__map[$key]["errorno"] = CURLE_COULDNT_CONNECT;
955
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("Unable to open a tunnel through the connected proxy. %s", $result["error"]);
956
- }
957
- else if ($result["info"]["errorcode"] == "connect_failed")
958
- {
959
- $curl_init__map[$key]["errorno"] = CURLE_COULDNT_CONNECT;
960
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("Unable to connect to the host. %s", $result["error"]);
961
- }
962
- else if ($result["info"]["errorcode"] == "write_body_callback")
963
- {
964
- $curl_init__map[$key]["errorno"] = CURLE_WRITE_ERROR;
965
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("A write error occurred in the write body callback. %s", $result["error"]);
966
- }
967
- else if ($result["info"]["errorcode"] == "file_open")
968
- {
969
- $curl_init__map[$key]["errorno"] = CURLE_FILE_COULDNT_READ_FILE;
970
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("Unable to open file for upload. %s", $result["error"]);
971
- }
972
- else if ($result["info"]["errorcode"] == "file_read")
973
- {
974
- $curl_init__map[$key]["errorno"] = CURLE_READ_ERROR;
975
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("A read error occurred while uploading a file. %s", $result["error"]);
976
- }
977
- else
978
- {
979
- $curl_init__map[$key]["errorno"] = CURLE_HTTP_RETURNED_ERROR;
980
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("An error occurred. %s", $result["error"]);
981
- }
982
- }
983
-
984
- return false;
985
- }
986
-
987
- if (isset($curl_init__map[$key]["returnresponse"]) && $curl_init__map[$key]["returnresponse"]["code"] >= 400 && isset($curl_init__map[$key]["options"][CURLOPT_FAILONERROR]) && $curl_init__map[$key]["options"][CURLOPT_FAILONERROR])
988
- {
989
- $curl_init__map[$key]["errorno"] = CURLE_HTTP_RETURNED_ERROR;
990
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("A HTTP error occurred. %s", $curl_init__map[$key]["returnresponse"]["line"]);
991
-
992
- return false;
993
- }
994
-
995
- if (isset($curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION]) && $curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION] && isset($result["headers"]["Location"]))
996
- {
997
- $curl_init__map[$key]["errorno"] = CURLE_TOO_MANY_REDIRECTS;
998
- $curl_init__map[$key]["errorinfo"] = HTTP::HTTPTranslate("Too many redirects took place.");
999
-
1000
- return false;
1001
- }
1002
-
1003
- if (isset($curl_init__map[$key]["options"][CURLOPT_RETURNTRANSFER]) && $curl_init__map[$key]["options"][CURLOPT_RETURNTRANSFER])
1004
- {
1005
- return (isset($curl_init__map[$key]["returnheader"]) ? $curl_init__map[$key]["returnheader"] . "\r\n" : "") . (isset($curl_init__map[$key]["returnbody"]) ? $curl_init__map[$key]["returnbody"] : "");
1006
- }
1007
-
1008
- return true;
1009
- }
1010
-
1011
- // Internal functions used by curl_exec().
1012
- function internal_curl_debug_callback($type, $data, $key)
1013
- {
1014
- global $curl_init__map;
1015
-
1016
- ob_start();
1017
-
1018
- if ($type == "proxypeercert")
1019
- {
1020
- if (isset($curl_init__map[$key]["options"][CURLOPT_CERTINFO]) && $curl_init__map[$key]["options"][CURLOPT_CERTINFO])
1021
- {
1022
- echo HTTP::HTTPTranslate("Proxy SSL Certificate:\n");
1023
- var_dump($data);
1024
- echo "\n";
1025
- }
1026
- }
1027
- else if ($type == "peercert")
1028
- {
1029
- if (isset($curl_init__map[$key]["options"][CURLOPT_CERTINFO]) && $curl_init__map[$key]["options"][CURLOPT_CERTINFO])
1030
- {
1031
- echo HTTP::HTTPTranslate("Peer SSL Certificate:\n");
1032
- var_dump($data);
1033
- echo "\n";
1034
- }
1035
- }
1036
- else if ($type == "rawproxyheaders")
1037
- {
1038
- if (isset($curl_init__map[$key]["options"]["__CURLINFO_HEADER_OUT"]) && $curl_init__map[$key]["options"]["__CURLINFO_HEADER_OUT"])
1039
- {
1040
- $curl_init__map[$key]["rawproxyheaders"] = $data;
1041
-
1042
- echo HTTP::HTTPTranslate("Raw Proxy Headers:\n");
1043
- echo $data;
1044
- }
1045
- }
1046
- else if ($type == "rawheaders")
1047
- {
1048
- if (isset($curl_init__map[$key]["options"]["__CURLINFO_HEADER_OUT"]) && $curl_init__map[$key]["options"]["__CURLINFO_HEADER_OUT"])
1049
- {
1050
- $curl_init__map[$key]["rawheaders"] = $data;
1051
-
1052
- echo HTTP::HTTPTranslate("Raw Headers:\n");
1053
- echo $data;
1054
- }
1055
- }
1056
- else if ($type == "rawsend")
1057
- {
1058
- echo HTTP::HTTPTranslate("Sent:\n");
1059
- echo $data;
1060
- }
1061
- else if ($type == "rawrecv")
1062
- {
1063
- echo HTTP::HTTPTranslate("Received:\n");
1064
- echo $data;
1065
- echo "\n";
1066
- }
1067
-
1068
- $output = ob_get_contents();
1069
- ob_end_clean();
1070
-
1071
- if ($output !== "" && isset($curl_init__map[$key]["options"][CURLOPT_VERBOSE]) && $curl_init__map[$key]["options"][CURLOPT_VERBOSE])
1072
- {
1073
- if (isset($curl_init__map[$key]["options"][CURLOPT_STDERR]) && is_resource($curl_init__map[$key]["options"][CURLOPT_STDERR])) fwrite($curl_init__map[$key]["options"][CURLOPT_STDERR], $output);
1074
- else if (defined("STDERR")) fwrite(STDERR, $output);
1075
- else echo $output;
1076
- }
1077
- }
1078
-
1079
- function internal_curl_write_body_callback(&$body, &$bodysize, $key)
1080
- {
1081
- global $curl_init__map;
1082
-
1083
- if (!$bodysize)
1084
- {
1085
- if (!isset($curl_init__map[$key]["options"][CURLOPT_INFILESIZE])) return false;
1086
- $bodysize = $curl_init__map[$key]["options"][CURLOPT_INFILESIZE];
1087
- }
1088
- else if (isset($curl_init__map[$key]["options"][CURLOPT_READFUNCTION]))
1089
- {
1090
- $bodysize2 = ($bodysize > 32768 ? 32768 : $bodysize);
1091
- $bodysize3 = $bodysize2;
1092
- $body = $curl_init__map[$key]["options"][CURLOPT_READFUNCTION]($curl_init__map[$key]["self"], $curl_init__map[$key]["options"][CURLOPT_INFILE], $bodysize2);
1093
- if ($bodysize3 < strlen($body))
1094
- {
1095
- if (isset($curl_init__map[$key]["options"][CURLOPT_VERBOSE]) && $curl_init__map[$key]["options"][CURLOPT_VERBOSE])
1096
- {
1097
- $output = HTTP::HTTPTranslate("An error occurred in the read function callback while reading the data to send/upload to the host.");
1098
-
1099
- if (isset($curl_init__map[$key]["options"][CURLOPT_STDERR]) && is_resource($curl_init__map[$key]["options"][CURLOPT_STDERR])) fwrite($curl_init__map[$key]["options"][CURLOPT_STDERR], $output);
1100
- else if (defined("STDERR")) fwrite(STDERR, $output);
1101
- else echo $output;
1102
- }
1103
-
1104
- return false;
1105
- }
1106
- }
1107
- else
1108
- {
1109
- if (!isset($curl_init__map[$key]["options"][CURLOPT_INFILE]) || !is_resource($curl_init__map[$key]["options"][CURLOPT_INFILE])) return false;
1110
- if ($bodysize > 32768) $body = fread($curl_init__map[$key]["options"][CURLOPT_INFILE], 32768);
1111
- else $body = fread($curl_init__map[$key]["options"][CURLOPT_INFILE], $bodysize);
1112
- if ($body === false)
1113
- {
1114
- if (isset($curl_init__map[$key]["options"][CURLOPT_VERBOSE]) && $curl_init__map[$key]["options"][CURLOPT_VERBOSE])
1115
- {
1116
- $output = HTTP::HTTPTranslate("An error occurred while reading the data to send/upload to the host.");
1117
-
1118
- if (isset($curl_init__map[$key]["options"][CURLOPT_STDERR]) && is_resource($curl_init__map[$key]["options"][CURLOPT_STDERR])) fwrite($curl_init__map[$key]["options"][CURLOPT_STDERR], $output);
1119
- else if (defined("STDERR")) fwrite(STDERR, $output);
1120
- else echo $output;
1121
- }
1122
-
1123
- return false;
1124
- }
1125
- }
1126
-
1127
- return true;
1128
- }
1129
-
1130
- function internal_curl_read_headers_callback(&$response, &$headers, $key)
1131
- {
1132
- global $curl_init__map;
1133
-
1134
- if (isset($curl_init__map[$key]["returnresponse"])) $data = "";
1135
- else
1136
- {
1137
- $data = $response["line"] . "\r\n";
1138
-
1139
- $curl_init__map[$key]["returnresponse"] = $response;
1140
- }
1141
-
1142
- if ($response["code"] >= 400 && isset($curl_init__map[$key]["options"][CURLOPT_FAILONERROR]) && $curl_init__map[$key]["options"][CURLOPT_FAILONERROR]) return true;
1143
-
1144
- foreach ($headers as $name => $vals)
1145
- {
1146
- foreach ($vals as $val) $data .= $name . ": " . $val . "\r\n";
1147
- }
1148
-
1149
- if (isset($curl_init__map[$key]["options"][CURLOPT_HEADER]) && $curl_init__map[$key]["options"][CURLOPT_HEADER])
1150
- {
1151
- if (isset($curl_init__map[$key]["options"][CURLOPT_VERBOSE]) && $curl_init__map[$key]["options"][CURLOPT_VERBOSE])
1152
- {
1153
- if (isset($curl_init__map[$key]["options"][CURLOPT_STDERR]) && is_resource($curl_init__map[$key]["options"][CURLOPT_STDERR])) fwrite($curl_init__map[$key]["options"][CURLOPT_STDERR], HTTP::HTTPTranslate("Header:\n") . $data);
1154
- else if (defined("STDERR")) fwrite(STDERR, HTTP::HTTPTranslate("Header:\n") . $data);
1155
- else echo HTTP::HTTPTranslate("Header:\n") . $data;
1156
- }
1157
- }
1158
-
1159
- if (!isset($headers["Location"]) || !isset($curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION]) || !$curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION])
1160
- {
1161
- if (isset($curl_init__map[$key]["options"][CURLOPT_HEADER]) && $curl_init__map[$key]["options"][CURLOPT_HEADER])
1162
- {
1163
- if (isset($curl_init__map[$key]["options"][CURLOPT_WRITEHEADER]) && is_resource($curl_init__map[$key]["options"][CURLOPT_WRITEHEADER]))
1164
- {
1165
- fwrite($curl_init__map[$key]["options"][CURLOPT_WRITEHEADER], $data);
1166
- }
1167
- else if (isset($curl_init__map[$key]["options"][CURLOPT_RETURNTRANSFER]) && $curl_init__map[$key]["options"][CURLOPT_RETURNTRANSFER])
1168
- {
1169
- if (!isset($curl_init__map[$key]["returnheader"])) $curl_init__map[$key]["returnheader"] = $data;
1170
- else $curl_init__map[$key]["returnheader"] .= $data;
1171
- }
1172
- else if (!$curl_init__map[$key]["outputbody"])
1173
- {
1174
- if (isset($curl_init__map[$key]["options"][CURLOPT_FILE]) && is_resource($curl_init__map[$key]["options"][CURLOPT_FILE])) fwrite($curl_init__map[$key]["options"][CURLOPT_FILE], $data);
1175
- else echo $data;
1176
- }
1177
- }
1178
-
1179
- if (isset($curl_init__map[$key]["options"][CURLOPT_HEADERFUNCTION]) && $curl_init__map[$key]["options"][CURLOPT_HEADERFUNCTION])
1180
- {
1181
- $curl_init__map[$key]["options"][CURLOPT_HEADERFUNCTION]($curl_init__map[$key]["self"], $data);
1182
- }
1183
- }
1184
-
1185
- return true;
1186
- }
1187
-
1188
- function internal_curl_read_body_callback(&$response, $data, $key)
1189
- {
1190
- global $curl_init__map;
1191
-
1192
- if ($response["code"] >= 400 && isset($curl_init__map[$key]["options"][CURLOPT_FAILONERROR]) && $curl_init__map[$key]["options"][CURLOPT_FAILONERROR]) return true;
1193
-
1194
- if (!isset($headers["Location"]) || !isset($curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION]) || !$curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION])
1195
- {
1196
- if (!isset($curl_init__map[$key]["returnbody"])) $curl_init__map[$key]["returnbody"] = "";
1197
-
1198
- if (isset($curl_init__map[$key]["options"][CURLOPT_RETURNTRANSFER]) && $curl_init__map[$key]["options"][CURLOPT_RETURNTRANSFER]) $curl_init__map[$key]["returnbody"] .= $data;
1199
- else
1200
- {
1201
- if (isset($curl_init__map[$key]["options"][CURLOPT_FILE]) && is_resource($curl_init__map[$key]["options"][CURLOPT_FILE])) fwrite($curl_init__map[$key]["options"][CURLOPT_FILE], $data);
1202
- else echo $data;
1203
-
1204
- $curl_init__map[$key]["outputbody"] = true;
1205
- }
1206
-
1207
- if (isset($curl_init__map[$key]["options"][CURLOPT_VERBOSE]) && $curl_init__map[$key]["options"][CURLOPT_VERBOSE])
1208
- {
1209
- if (isset($curl_init__map[$key]["options"][CURLOPT_STDERR]) && is_resource($curl_init__map[$key]["options"][CURLOPT_STDERR])) fwrite($curl_init__map[$key]["options"][CURLOPT_STDERR], HTTP::HTTPTranslate("Body:\n") . $data);
1210
- else if (defined("STDERR")) fwrite(STDERR, HTTP::HTTPTranslate("Body:\n") . $data);
1211
- else echo HTTP::HTTPTranslate("Body:\n") . $data;
1212
- }
1213
-
1214
- if (isset($curl_init__map[$key]["options"][CURLOPT_WRITEFUNCTION]) && $curl_init__map[$key]["options"][CURLOPT_WRITEFUNCTION])
1215
- {
1216
- $datasize = strlen($data);
1217
- $size = $curl_init__map[$key]["options"][CURLOPT_WRITEFUNCTION]($curl_init__map[$key]["self"], $data);
1218
- if ($size != $datasize)
1219
- {
1220
- if (isset($curl_init__map[$key]["options"][CURLOPT_VERBOSE]) && $curl_init__map[$key]["options"][CURLOPT_VERBOSE])
1221
- {
1222
- $output = HTTP::HTTPTranslate("An error occurred in the write function callback while writing the data received from the host.");
1223
-
1224
- if (isset($curl_init__map[$key]["options"][CURLOPT_STDERR]) && is_resource($curl_init__map[$key]["options"][CURLOPT_STDERR])) fwrite($curl_init__map[$key]["options"][CURLOPT_STDERR], $output);
1225
- else if (defined("STDERR")) fwrite(STDERR, $output);
1226
- else echo $output;
1227
- }
1228
-
1229
- return false;
1230
- }
1231
- }
1232
- }
1233
-
1234
- return true;
1235
- }
1236
-
1237
- function curl_getinfo($ch, $opt = 0)
1238
- {
1239
- global $curl_init__map;
1240
-
1241
- $key = get_check_curl_init_key($ch);
1242
-
1243
- if (!isset($curl_init__map[$key]["lastresult"])) return false;
1244
-
1245
- $result = array(
1246
- "url" => $curl_init__map[$key]["lastresult"]["url"],
1247
- "content_type" => (isset($curl_init__map[$key]["lastresult"]["headers"]) && isset($curl_init__map[$key]["lastresult"]["headers"]["Content-Type"]) ? $curl_init__map[$key]["lastresult"]["headers"]["Content-Type"][0] : null),
1248
- "http_code" => (isset($curl_init__map[$key]["lastresult"]["response"]) && isset($curl_init__map[$key]["lastresult"]["response"]["code"]) ? (int)$curl_init__map[$key]["lastresult"]["response"]["code"] : null),
1249
- "header_size" => (isset($curl_init__map[$key]["lastresult"]["rawrecvheadersize"]) ? $curl_init__map[$key]["lastresult"]["rawrecvheadersize"] : 0),
1250
- "request_size" => (isset($curl_init__map[$key]["lastresult"]["totalrawsendsize"]) ? $curl_init__map[$key]["lastresult"]["totalrawsendsize"] : 0),
1251
- "filetime" => (isset($curl_init__map[$key]["options"][CURLOPT_FILETIME]) && $curl_init__map[$key]["options"][CURLOPT_FILETIME] && isset($curl_init__map[$key]["lastresult"]["headers"]) && isset($curl_init__map[$key]["lastresult"]["headers"]["Last-Modified"]) ? HTTP::GetDateTimestamp($curl_init__map[$key]["lastresult"]["headers"]["Last-Modified"][0]) : -1),
1252
- "ssl_verify_result" => 0,
1253
- "redirect_count" => (isset($curl_init__map[$key]["lastresult"]["numredirects"]) ? $curl_init__map[$key]["lastresult"]["numredirects"] : 0),
1254
- "total_time" => (isset($curl_init__map[$key]["lastresult"]["startts"]) && isset($curl_init__map[$key]["lastresult"]["endts"]) ? $curl_init__map[$key]["lastresult"]["endts"] - $curl_init__map[$key]["lastresult"]["startts"] : 0),
1255
- "namelookup_time" => (isset($curl_init__map[$key]["lastresult"]["startts"]) && isset($curl_init__map[$key]["lastresult"]["connected"]) ? ($curl_init__map[$key]["lastresult"]["connected"] - $curl_init__map[$key]["lastresult"]["startts"]) / 2 : 0),
1256
- "connect_time" => (isset($curl_init__map[$key]["lastresult"]["startts"]) && isset($curl_init__map[$key]["lastresult"]["connected"]) ? ($curl_init__map[$key]["lastresult"]["connected"] - $curl_init__map[$key]["lastresult"]["startts"]) / 2 : 0),
1257
- "pretransfer_time" => (isset($curl_init__map[$key]["lastresult"]["connected"]) && isset($curl_init__map[$key]["lastresult"]["sendstart"]) ? $curl_init__map[$key]["lastresult"]["sendstart"] - $curl_init__map[$key]["lastresult"]["connected"] : 0),
1258
- "size_upload" => (isset($curl_init__map[$key]["lastresult"]["rawsendsize"]) && isset($curl_init__map[$key]["lastresult"]["rawsendheadersize"]) ? $curl_init__map[$key]["lastresult"]["rawsendsize"] - $curl_init__map[$key]["lastresult"]["rawsendheadersize"] : 0),
1259
- "size_download" => (isset($curl_init__map[$key]["lastresult"]["rawrecvsize"]) && isset($curl_init__map[$key]["lastresult"]["rawrecvheadersize"]) ? $curl_init__map[$key]["lastresult"]["rawrecvsize"] - $curl_init__map[$key]["lastresult"]["rawrecvheadersize"] : 0)
1260
- );
1261
-
1262
- $result["speed_download"] = (isset($curl_init__map[$key]["lastresult"]["recvstart"]) && isset($curl_init__map[$key]["lastresult"]["endts"]) && $curl_init__map[$key]["lastresult"]["endts"] - $curl_init__map[$key]["lastresult"]["recvstart"] > 0 ? $result["size_download"] / ($curl_init__map[$key]["lastresult"]["endts"] - $curl_init__map[$key]["lastresult"]["recvstart"]) : 0);
1263
- $result["speed_upload"] = (isset($curl_init__map[$key]["lastresult"]["sendstart"]) && isset($curl_init__map[$key]["lastresult"]["recvstart"]) && $curl_init__map[$key]["lastresult"]["recvstart"] - $curl_init__map[$key]["lastresult"]["sendstart"] > 0 ? $result["size_upload"] / ($curl_init__map[$key]["lastresult"]["recvstart"] - $curl_init__map[$key]["lastresult"]["sendstart"]) : 0);
1264
- $result["download_content_length"] = (isset($curl_init__map[$key]["lastresult"]["headers"]) && isset($curl_init__map[$key]["lastresult"]["headers"]["Content-Length"]) ? $curl_init__map[$key]["lastresult"]["headers"]["Content-Length"][0] : -1);
1265
- $result["upload_content_length"] = $result["size_upload"];
1266
- $result["starttransfer_time"] = (isset($curl_init__map[$key]["lastresult"]["startts"]) && isset($curl_init__map[$key]["lastresult"]["sendstart"]) ? $curl_init__map[$key]["lastresult"]["sendstart"] - $curl_init__map[$key]["lastresult"]["startts"] : 0);
1267
- $result["redirect_time"] = (isset($curl_init__map[$key]["lastresult"]["firstreqts"]) && isset($curl_init__map[$key]["lastresult"]["redirectts"]) ? $curl_init__map[$key]["lastresult"]["redirectts"] - $curl_init__map[$key]["lastresult"]["firstreqts"] : 0);
1268
- if (isset($curl_init__map[$key]["rawheaders"])) $result["request_header"] = $curl_init__map[$key]["rawheaders"];
1269
-
1270
- if ($opt == 0) return $result;
1271
-
1272
- $tempmap = array(
1273
- CURLINFO_EFFECTIVE_URL => "url",
1274
- CURLINFO_HTTP_CODE => "http_code",
1275
- CURLINFO_FILETIME => "filetime",
1276
- CURLINFO_TOTAL_TIME => "total_time",
1277
- CURLINFO_NAMELOOKUP_TIME => "namelookup_time",
1278
- CURLINFO_CONNECT_TIME => "connect_time",
1279
- CURLINFO_PRETRANSFER_TIME => "pretransfer_time",
1280
- CURLINFO_STARTTRANSFER_TIME => "starttransfer_time",
1281
- CURLINFO_REDIRECT_TIME => "redirect_time",
1282
- CURLINFO_SIZE_UPLOAD => "size_upload",
1283
- CURLINFO_SIZE_DOWNLOAD => "size_download",
1284
- CURLINFO_SPEED_DOWNLOAD => "speed_download",
1285
- CURLINFO_SPEED_UPLOAD => "speed_upload",
1286
- CURLINFO_HEADER_SIZE => "header_size",
1287
- CURLINFO_HEADER_OUT => "request_header",
1288
- CURLINFO_REQUEST_SIZE => "request_size",
1289
- CURLINFO_SSL_VERIFYRESULT => "ssl_verify_result",
1290
- CURLINFO_CONTENT_LENGTH_DOWNLOAD => "download_content_length",
1291
- CURLINFO_CONTENT_LENGTH_UPLOAD => "upload_content_length",
1292
- CURLINFO_CONTENT_TYPE => "content_type",
1293
- );
1294
- if (!isset($tempmap[$opt]) || !isset($result[$tempmap[$opt]])) return false;
1295
-
1296
- return $result[$tempmap[$opt]];
1297
- }
1298
-
1299
- // These functions really just cheat and do requests in serial. Laziness at its finest!
1300
- $curl_multi_init__map = array();
1301
- function get_curl_multi_init_key($mh)
1302
- {
1303
- ob_start();
1304
- echo $mh;
1305
- ob_end_clean();
1306
-
1307
- return ob_get_contents();
1308
- }
1309
-
1310
- function get_check_curl_multi_init_key($ch)
1311
- {
1312
- global $curl_init__map;
1313
-
1314
- $key = get_curl_multi_init_key($ch);
1315
- if (!isset($curl_multi_init__map[$key])) throw new Exception(HTTP::HTTPTranslate("cURL Emulator: Unable to find key mapping for resource."));
1316
-
1317
- return $key;
1318
- }
1319
-
1320
- function curl_multi_init()
1321
- {
1322
- global $curl_multi_init__map;
1323
-
1324
- // Another evil hack to create a "resource" so that is_resource() works.
1325
- $mh = fopen(__FILE__, "rb");
1326
- $key = get_curl_multi_init_key($mh);
1327
- $curl_multi_init__map[$key] = array("self" => $mh, "handles" => array(), "messages" => array());
1328
-
1329
- return $mh;
1330
- }
1331
-
1332
- function curl_multi_add_handle($mh, $ch)
1333
- {
1334
- global $curl_multi_init__map;
1335
-
1336
- $key = get_check_curl_multi_init_key($mh);
1337
- $key2 = get_check_curl_init_key($ch);
1338
-
1339
- $curl_multi_init__map[$key]["handles"][$key2] = $ch;
1340
-
1341
- return 0;
1342
- }
1343
-
1344
- function curl_multi_remove_handle($mh, $ch)
1345
- {
1346
- global $curl_multi_init__map;
1347
-
1348
- $key = get_check_curl_multi_init_key($mh);
1349
- $key2 = get_check_curl_init_key($ch);
1350
-
1351
- unset($curl_multi_init__map[$key]["handles"][$key2]);
1352
-
1353
- return 0;
1354
- }
1355
-
1356
- function curl_multi_close($mh)
1357
- {
1358
- global $curl_multi_init__map;
1359
-
1360
- $key = get_check_curl_multi_init_key($mh);
1361
-
1362
- unset($curl_multi_init__map[$key]);
1363
- }
1364
-
1365
- function curl_multi_getcontent($ch)
1366
- {
1367
- global $curl_init__map;
1368
-
1369
- $key = get_check_curl_init_key($ch);
1370
-
1371
- if (isset($curl_init__map[$key]["options"][CURLOPT_RETURNTRANSFER]) && $curl_init__map[$key]["options"][CURLOPT_RETURNTRANSFER])
1372
- {
1373
- return (isset($curl_init__map[$key]["returnheader"]) ? $curl_init__map[$key]["returnheader"] . "\r\n" : "") . (isset($curl_init__map[$key]["returnbody"]) ? $curl_init__map[$key]["returnbody"] : "");
1374
- }
1375
- }
1376
-
1377
- function curl_multi_exec($mh, &$still_running)
1378
- {
1379
- global $curl_multi_init__map;
1380
-
1381
- $key = get_check_curl_multi_init_key($mh);
1382
-
1383
- foreach ($curl_multi_init__map[$key]["handles"] as $key2 => $ch)
1384
- {
1385
- curl_exec($ch);
1386
- $curl_multi_init__map[$key]["messages"][] = array(
1387
- "msg" => CURLMSG_DONE,
1388
- "result" => curl_errno($ch),
1389
- "handle" => $ch
1390
- );
1391
- unset($curl_multi_init__map[$key]["handles"][$key2]);
1392
- }
1393
-
1394
- $still_running = 0;
1395
-
1396
- return CURLM_OK;
1397
- }
1398
-
1399
- function curl_multi_select($mh, $timeout = 1.0)
1400
- {
1401
- global $curl_multi_init__map;
1402
-
1403
- $key = get_check_curl_multi_init_key($mh);
1404
-
1405
- if (!count($curl_multi_init__map[$key]["handles"])) return -1;
1406
-
1407
- return count($curl_multi_init__map[$key]["handles"]);
1408
- }
1409
-
1410
- function curl_multi_info_read($mh, &$msgs_in_queue = NULL)
1411
- {
1412
- global $curl_multi_init__map;
1413
-
1414
- $key = get_check_curl_multi_init_key($mh);
1415
-
1416
- $msgs_in_queue = count($curl_multi_init__map[$key]["messages"]);
1417
- if (!$msgs_in_queue) return false;
1418
- $msgs_in_queue--;
1419
-
1420
- return array_shift($curl_multi_init__map[$key]["messages"]);
1421
- }
1422
- }
1423
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/ultimate-web-scraper/http.php DELETED
@@ -1,1810 +0,0 @@
1
- <?php
2
- // CubicleSoft PHP HTTP class.
3
- // (C) 2018 CubicleSoft. All Rights Reserved.
4
-
5
- class HTTP
6
- {
7
- // RFC 3986 delimeter splitting implementation.
8
- public static function ExtractURL($url)
9
- {
10
- $result = array(
11
- "scheme" => "",
12
- "authority" => "",
13
- "login" => "",
14
- "loginusername" => "",
15
- "loginpassword" => "",
16
- "host" => "",
17
- "port" => "",
18
- "path" => "",
19
- "query" => "",
20
- "queryvars" => array(),
21
- "fragment" => ""
22
- );
23
-
24
- $url = str_replace("&amp;", "&", $url);
25
-
26
- $pos = strpos($url, "#");
27
- if ($pos !== false)
28
- {
29
- $result["fragment"] = substr($url, $pos + 1);
30
- $url = substr($url, 0, $pos);
31
- }
32
-
33
- $pos = strpos($url, "?");
34
- if ($pos !== false)
35
- {
36
- $result["query"] = str_replace(" ", "+", substr($url, $pos + 1));
37
- $url = substr($url, 0, $pos);
38
- $vars = explode("&", $result["query"]);
39
- foreach ($vars as $var)
40
- {
41
- $pos = strpos($var, "=");
42
- if ($pos === false)
43
- {
44
- $name = $var;
45
- $value = "";
46
- }
47
- else
48
- {
49
- $name = substr($var, 0, $pos);
50
- $value = urldecode(substr($var, $pos + 1));
51
- }
52
- $name = urldecode($name);
53
- if (!isset($result["queryvars"][$name])) $result["queryvars"][$name] = array();
54
- $result["queryvars"][$name][] = $value;
55
- }
56
- }
57
-
58
- $url = str_replace("\\", "/", $url);
59
-
60
- $pos = strpos($url, ":");
61
- $pos2 = strpos($url, "/");
62
- if ($pos !== false && ($pos2 === false || $pos < $pos2))
63
- {
64
- $result["scheme"] = strtolower(substr($url, 0, $pos));
65
- $url = substr($url, $pos + 1);
66
- }
67
-
68
- if (substr($url, 0, 2) != "//") $result["path"] = $url;
69
- else
70
- {
71
- $url = substr($url, 2);
72
- $pos = strpos($url, "/");
73
- if ($pos !== false)
74
- {
75
- $result["path"] = substr($url, $pos);
76
- $url = substr($url, 0, $pos);
77
- }
78
- $result["authority"] = $url;
79
-
80
- $pos = strpos($url, "@");
81
- if ($pos !== false)
82
- {
83
- $result["login"] = substr($url, 0, $pos);
84
- $url = substr($url, $pos + 1);
85
- $pos = strpos($result["login"], ":");
86
- if ($pos === false) $result["loginusername"] = urldecode($result["login"]);
87
- else
88
- {
89
- $result["loginusername"] = urldecode(substr($result["login"], 0, $pos));
90
- $result["loginpassword"] = urldecode(substr($result["login"], $pos + 1));
91
- }
92
- }
93
-
94
- $pos = strpos($url, "]");
95
- if (substr($url, 0, 1) == "[" && $pos !== false)
96
- {
97
- // IPv6 literal address.
98
- $result["host"] = substr($url, 0, $pos + 1);
99
- $url = substr($url, $pos + 1);
100
-
101
- $pos = strpos($url, ":");
102
- if ($pos !== false)
103
- {
104
- $result["port"] = substr($url, $pos + 1);
105
- $url = substr($url, 0, $pos);
106
- }
107
- }
108
- else
109
- {
110
- // Normal host[:port].
111
- $pos = strpos($url, ":");
112
- if ($pos !== false)
113
- {
114
- $result["port"] = substr($url, $pos + 1);
115
- $url = substr($url, 0, $pos);
116
- }
117
-
118
- $result["host"] = $url;
119
- }
120
- }
121
-
122
- return $result;
123
- }
124
-
125
- // Takes a ExtractURL() array and condenses it into a string.
126
- public static function CondenseURL($data)
127
- {
128
- $result = "";
129
- if (isset($data["host"]) && $data["host"] != "")
130
- {
131
- if (isset($data["scheme"]) && $data["scheme"] != "") $result = $data["scheme"] . "://";
132
- if (isset($data["loginusername"]) && $data["loginusername"] != "" && isset($data["loginpassword"])) $result .= rawurlencode($data["loginusername"]) . ($data["loginpassword"] != "" ? ":" . rawurlencode($data["loginpassword"]) : "") . "@";
133
- else if (isset($data["login"]) && $data["login"] != "") $result .= $data["login"] . "@";
134
-
135
- $result .= $data["host"];
136
- if (isset($data["port"]) && $data["port"] != "") $result .= ":" . $data["port"];
137
-
138
- if (isset($data["path"]))
139
- {
140
- $data["path"] = str_replace("\\", "/", $data["path"]);
141
- if (substr($data["path"], 0, 1) != "/") $data["path"] = "/" . $data["path"];
142
- $result .= $data["path"];
143
- }
144
- }
145
- else if (isset($data["authority"]) && $data["authority"] != "")
146
- {
147
- if (isset($data["scheme"]) && $data["scheme"] != "") $result = $data["scheme"] . "://";
148
-
149
- $result .= $data["authority"];
150
-
151
- if (isset($data["path"]))
152
- {
153
- $data["path"] = str_replace("\\", "/", $data["path"]);
154
- if (substr($data["path"], 0, 1) != "/") $data["path"] = "/" . $data["path"];
155
- $result .= $data["path"];
156
- }
157
- }
158
- else if (isset($data["path"]))
159
- {
160
- if (isset($data["scheme"]) && $data["scheme"] != "") $result = $data["scheme"] . ":";
161
-
162
- $result .= $data["path"];
163
- }
164
-
165
- if (isset($data["query"]))
166
- {
167
- if ($data["query"] != "") $result .= "?" . $data["query"];
168
- }
169
- else if (isset($data["queryvars"]))
170
- {
171
- $data["query"] = array();
172
- foreach ($data["queryvars"] as $key => $vals)
173
- {
174
- if (is_string($vals)) $vals = array($vals);
175
- foreach ($vals as $val) $data["query"][] = urlencode($key) . "=" . urlencode($val);
176
- }
177
- $data["query"] = implode("&", $data["query"]);
178
-
179
- if ($data["query"] != "") $result .= "?" . $data["query"];
180
- }
181
-
182
- if (isset($data["fragment"]) && $data["fragment"] != "") $result .= "#" . $data["fragment"];
183
-
184
- return $result;
185
- }
186
-
187
- public static function ConvertRelativeToAbsoluteURL($baseurl, $relativeurl)
188
- {
189
- $relative = (is_array($relativeurl) ? $relativeurl : self::ExtractURL($relativeurl));
190
- $base = (is_array($baseurl) ? $baseurl : self::ExtractURL($baseurl));
191
-
192
- if ($relative["host"] != "" || ($relative["scheme"] != "" && $relative["scheme"] != $base["scheme"]))
193
- {
194
- if ($relative["scheme"] == "") $relative["scheme"] = $base["scheme"];
195
-
196
- return self::CondenseURL($relative);
197
- }
198
-
199
- $result = array(
200
- "scheme" => $base["scheme"],
201
- "loginusername" => $base["loginusername"],
202
- "loginpassword" => $base["loginpassword"],
203
- "host" => $base["host"],
204
- "port" => $base["port"],
205
- "path" => "",
206
- "query" => $relative["query"],
207
- "fragment" => $relative["fragment"]
208
- );
209
-
210
- if ($relative["path"] == "") $result["path"] = $base["path"];
211
- else if (substr($relative["path"], 0, 1) == "/") $result["path"] = $relative["path"];
212
- else
213
- {
214
- $abspath = explode("/", $base["path"]);
215
- array_pop($abspath);
216
- $relpath = explode("/", $relative["path"]);
217
- foreach ($relpath as $piece)
218
- {
219
- if ($piece == ".")
220
- {
221
- }
222
- else if ($piece == "..") array_pop($abspath);
223
- else $abspath[] = $piece;
224
- }
225
-
226
- $abspath = implode("/", $abspath);
227
- if (substr($abspath, 0, 1) != "/") $abspath = "/" . $abspath;
228
-
229
- $result["path"] = $abspath;
230
- }
231
-
232
- return self::CondenseURL($result);
233
- }
234
-
235
- public static function GetUserAgent($type)
236
- {
237
- $type = strtolower($type);
238
-
239
- if ($type == "ie") $type = "ie11";
240
-
241
- if ($type == "ie6") return "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)";
242
- else if ($type == "ie7") return "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)";
243
- else if ($type == "ie8") return "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1)";
244
- else if ($type == "ie9") return "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
245
- else if ($type == "ie10") return "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)";
246
- else if ($type == "ie11") return "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko";
247
- else if ($type == "firefox") return "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0";
248
- else if ($type == "opera") return "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.16";
249
- else if ($type == "safari") return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2";
250
- else if ($type == "chrome") return "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";
251
-
252
- return "";
253
- }
254
-
255
- public static function GetSSLCiphers($type = "intermediate")
256
- {
257
- $type = strtolower($type);
258
-
259
- // Cipher list last updated May 3, 2017.
260
- if ($type == "modern") return "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256";
261
- else if ($type == "old") return "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP";
262
-
263
- return "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";
264
- }
265
-
266
- public static function GetSafeSSLOpts($cafile = true, $cipherstype = "intermediate")
267
- {
268
- // Result array last updated May 3, 2017.
269
- $result = array(
270
- "ciphers" => self::GetSSLCiphers($cipherstype),
271
- "disable_compression" => true,
272
- "allow_self_signed" => false,
273
- "verify_peer" => true,
274
- "verify_depth" => 5
275
- );
276
-
277
- if ($cafile === true) $result["auto_cainfo"] = true;
278
- else if ($cafile !== false) $result["cafile"] = $cafile;
279
-
280
- return $result;
281
- }
282
-
283
- // Reasonably parses RFC1123, RFC850, and asctime() dates.
284
- public static function GetDateTimestamp($httpdate)
285
- {
286
- $timestamp_map = array(
287
- "jan" => 1, "feb" => 2, "mar" => 3, "apr" => 4, "may" => 5, "jun" => 6,
288
- "jul" => 7, "aug" => 8, "sep" => 9, "oct" => 10, "nov" => 11, "dec" => 12
289
- );
290
-
291
- $year = false;
292
- $month = false;
293
- $day = false;
294
- $hour = false;
295
- $min = false;
296
- $sec = false;
297
-
298
- $items = explode(" ", preg_replace('/\s+/', " ", str_replace("-", " ", strtolower($httpdate))));
299
- foreach ($items as $item)
300
- {
301
- if ($item != "")
302
- {
303
- if (strpos($item, ":") !== false)
304
- {
305
- $item = explode(":", $item);
306
- $hour = (int)(count($item) > 0 ? array_shift($item) : 0);
307
- $min = (int)(count($item) > 0 ? array_shift($item) : 0);
308
- $sec = (int)(count($item) > 0 ? array_shift($item) : 0);
309
-
310
- if ($hour > 23) $hour = 23;
311
- if ($min > 59) $min = 59;
312
- if ($sec > 59) $sec = 59;
313
- }
314
- else if (is_numeric($item))
315
- {
316
- if (strlen($item) >= 4) $year = (int)$item;
317
- else if ($day === false) $day = (int)$item;
318
- else $year = substr(date("Y"), 0, 2) . substr($item, -2);
319
- }
320
- else
321
- {
322
- $item = substr($item, 0, 3);
323
- if (isset($timestamp_map[$item])) $month = $timestamp_map[$item];
324
- }
325
- }
326
- }
327
-
328
- if ($year === false || $month === false || $day === false || $hour === false || $min === false || $sec === false) return false;
329
-
330
- return gmmktime($hour, $min, $sec, $month, $day, $year);
331
- }
332
-
333
- public static function HTTPTranslate()
334
- {
335
- $args = func_get_args();
336
- if (!count($args)) return "";
337
-
338
- return call_user_func_array((defined("CS_TRANSLATE_FUNC") && function_exists(CS_TRANSLATE_FUNC) ? CS_TRANSLATE_FUNC : "sprintf"), $args);
339
- }
340
-
341
- public static function HeaderNameCleanup($name)
342
- {
343
- return preg_replace('/\s+/', "-", ucwords(strtolower(trim(preg_replace('/[^A-Za-z0-9 ]/', " ", $name)))));
344
- }
345
-
346
- private static function HeaderValueCleanup($value)
347
- {
348
- return str_replace(array("\r", "\n"), array("", ""), $value);
349
- }
350
-
351
- public static function NormalizeHeaders($headers)
352
- {
353
- $result = array();
354
- foreach ($headers as $name => $val)
355
- {
356
- $val = self::HeaderValueCleanup($val);
357
- if ($val != "") $result[self::HeaderNameCleanup($name)] = $val;
358
- }
359
-
360
- return $result;
361
- }
362
-
363
- public static function MergeRawHeaders(&$headers, $rawheaders)
364
- {
365
- foreach ($rawheaders as $name => $val)
366
- {
367
- $val = self::HeaderValueCleanup($val);
368
- if ($val != "")
369
- {
370
- $name2 = self::HeaderNameCleanup($name);
371
- if (isset($headers[$name2])) unset($headers[$name2]);
372
-
373
- $headers[$name] = $val;
374
- }
375
- }
376
- }
377
-
378
- public static function ExtractHeader($data)
379
- {
380
- $result = array();
381
- $data = trim($data);
382
- while ($data != "")
383
- {
384
- // Extract name/value pair.
385
- $pos = strpos($data, "=");
386
- $pos2 = strpos($data, ";");
387
- if (($pos !== false && $pos2 === false) || ($pos !== false && $pos2 !== false && $pos < $pos2))
388
- {
389
- $name = trim(substr($data, 0, $pos));
390
- $data = trim(substr($data, $pos + 1));
391
- if (ord($data[0]) == ord("\""))
392
- {
393
- $pos = strpos($data, "\"", 1);
394
- if ($pos !== false)
395
- {
396
- $value = substr($data, 1, $pos - 1);
397
- $data = trim(substr($data, $pos + 1));
398
- $pos = strpos($data, ";");
399
- if ($pos !== false) $data = substr($data, $pos + 1);
400
- else $data = "";
401
- }
402
- else
403
- {
404
- $value = $data;
405
- $data = "";
406
- }
407
- }
408
- else
409
- {
410
- $pos = strpos($data, ";");
411
- if ($pos !== false)
412
- {
413
- $value = trim(substr($data, 0, $pos));
414
- $data = substr($data, $pos + 1);
415
- }
416
- else
417
- {
418
- $value = $data;
419
- $data = "";
420
- }
421
- }
422
- }
423
- else if ($pos2 !== false)
424
- {
425
- $name = "";
426
- $value = trim(substr($data, 0, $pos2));
427
- $data = substr($data, $pos2 + 1);
428
- }
429
- else
430
- {
431
- $name = "";
432
- $value = $data;
433
- $data = "";
434
- }
435
-
436
- if ($name != "" || $value != "") $result[strtolower($name)] = $value;
437
-
438
- $data = trim($data);
439
- }
440
-
441
- return $result;
442
- }
443
-
444
- private static function ProcessSSLOptions(&$options, $key, $host)
445
- {
446
- if (isset($options[$key]["auto_cainfo"]))
447
- {
448
- unset($options[$key]["auto_cainfo"]);
449
-
450
- $cainfo = ini_get("curl.cainfo");
451
- if ($cainfo !== false && strlen($cainfo) > 0) $options[$key]["cafile"] = $cainfo;
452
- else if (file_exists(str_replace("\\", "/", dirname(__FILE__)) . "/cacert.pem")) $options[$key]["cafile"] = str_replace("\\", "/", dirname(__FILE__)) . "/cacert.pem";
453
- }
454
-
455
- if (isset($options[$key]["auto_cn_match"]))
456
- {
457
- unset($options[$key]["auto_cn_match"]);
458
-
459
- if (!isset($options["headers"]["Host"])) $options[$key]["CN_match"] = $host;
460
- else
461
- {
462
- $info = self::ExtractURL("https://" . $options["headers"]["Host"]);
463
- $options[$key]["CN_match"] = $info["host"];
464
- }
465
- }
466
-
467
- if (isset($options[$key]["auto_sni"]))
468
- {
469
- unset($options[$key]["auto_sni"]);
470
-
471
- $options[$key]["SNI_enabled"] = true;
472
- if (!isset($options["headers"]["Host"])) $options[$key]["SNI_server_name"] = $host;
473
- else
474
- {
475
- $info = self::ExtractURL("https://" . $options["headers"]["Host"]);
476
- $options[$key]["SNI_server_name"] = $info["host"];
477
- }
478
- }
479
- }
480
-
481
- // Swiped from str_basics.php so this file can be standalone.
482
- public static function ExtractFilename($dirfile)
483
- {
484
- $dirfile = str_replace("\\", "/", $dirfile);
485
- $pos = strrpos($dirfile, "/");
486
- if ($pos !== false) $dirfile = substr($dirfile, $pos + 1);
487
-
488
- return $dirfile;
489
- }
490
-
491
- public static function FilenameSafe($filename)
492
- {
493
- return preg_replace('/[_]+/', "_", preg_replace('/[^A-Za-z0-9_.\-]/', "_", $filename));
494
- }
495
-
496
- public static function GetTimeLeft($start, $limit)
497
- {
498
- if ($limit === false) return false;
499
-
500
- $difftime = microtime(true) - $start;
501
- if ($difftime >= $limit) return 0;
502
-
503
- return $limit - $difftime;
504
- }
505
-
506
- private static function ProcessRateLimit($size, $start, $limit, $async)
507
- {
508
- $difftime = microtime(true) - $start;
509
- if ($difftime > 0.0)
510
- {
511
- if ($size / $difftime > $limit)
512
- {
513
- // Sleeping for some amount of time will equalize the rate.
514
- // So, solve this for $x: $size / ($x + $difftime) = $limit
515
- $amount = ($size - ($limit * $difftime)) / $limit;
516
- $amount += 0.001;
517
-
518
- if ($async) return microtime(true) + $amount;
519
- else usleep($amount * 1000000);
520
- }
521
- }
522
-
523
- return -1.0;
524
- }
525
-
526
- private static function GetDecodedBody(&$autodecode_ds, $body)
527
- {
528
- if ($autodecode_ds !== false)
529
- {
530
- $autodecode_ds->Write($body);
531
- $body = $autodecode_ds->Read();
532
- }
533
-
534
- return $body;
535
- }
536
-
537
- private static function StreamTimedOut($fp)
538
- {
539
- if (!function_exists("stream_get_meta_data")) return false;
540
-
541
- $info = stream_get_meta_data($fp);
542
-
543
- return $info["timed_out"];
544
- }
545
-
546
- public static function InitResponseState($fp, $debug, $options, $startts, $timeout, $result, $close, $nextread, $client = true)
547
- {
548
- $state = array(
549
- "fp" => $fp,
550
- "type" => "response",
551
- "async" => (isset($options["async"]) ? $options["async"] : false),
552
- "debug" => $debug,
553
- "startts" => $startts,
554
- "timeout" => $timeout,
555
- "waituntil" => -1.0,
556
- "rawdata" => "",
557
- "data" => "",
558
- "rawsize" => 0,
559
- "rawrecvheadersize" => 0,
560
- "numheaders" => 0,
561
- "autodecode" => (!isset($options["auto_decode"]) || $options["auto_decode"]),
562
-
563
- "state" => ($client ? "response_line" : "request_line"),
564
-
565
- "options" => $options,
566
- "result" => $result,
567
- "close" => $close,
568
- "nextread" => $nextread,
569
- "client" => $client
570
- );
571
-
572
- $state["result"]["recvstart"] = microtime(true);
573
- $state["result"]["response"] = false;
574
- $state["result"]["headers"] = false;
575
- $state["result"]["body"] = false;
576
-
577
- return $state;
578
- }
579
-
580
- // Handles partially read input. Also deals with the hacky workaround to the second bugfix in ProcessState__WriteData().
581
- private static function ProcessState__InternalRead(&$state, $size, $endchar = false)
582
- {
583
- $y = strlen($state["nextread"]);
584
-
585
- do
586
- {
587
- if ($size <= $y)
588
- {
589
- if ($endchar === false) $pos = $size;
590
- else
591
- {
592
- $pos = strpos($state["nextread"], $endchar);
593
- if ($pos === false || $pos > $size) $pos = $size;
594
- else $pos++;
595
- }
596
-
597
- $data = substr($state["nextread"], 0, $pos);
598
- $state["nextread"] = (string)substr($state["nextread"], $pos);
599
-
600
- return $data;
601
- }
602
-
603
- if ($endchar !== false)
604
- {
605
- $pos = strpos($state["nextread"], $endchar);
606
- if ($pos !== false)
607
- {
608
- $data = substr($state["nextread"], 0, $pos + 1);
609
- $state["nextread"] = (string)substr($state["nextread"], $pos + 1);
610
-
611
- return $data;
612
- }
613
- }
614
-
615
- if ($state["debug"]) $data2 = fread($state["fp"], $size);
616
- else $data2 = @fread($state["fp"], $size);
617
-
618
- if ($data2 === false || $data2 === "")
619
- {
620
- if ($state["nextread"] === "") return $data2;
621
-
622
- if ($state["async"] && $endchar !== false && $data2 === "") return "";
623
-
624
- $data = $state["nextread"];
625
- $state["nextread"] = "";
626
-
627
- return $data;
628
- }
629
-
630
- $state["nextread"] .= $data2;
631
-
632
- $y = strlen($state["nextread"]);
633
- } while (!$state["async"] || ($size <= $y) || ($endchar !== false && strpos($state["nextread"], $endchar) !== false));
634
-
635
- if ($endchar !== false) return "";
636
-
637
- $data = $state["nextread"];
638
- $state["nextread"] = "";
639
-
640
- return $data;
641
- }
642
-
643
- // Reads one line.
644
- private static function ProcessState__ReadLine(&$state)
645
- {
646
- while (strpos($state["data"], "\n") === false)
647
- {
648
- $data2 = self::ProcessState__InternalRead($state, 116000, "\n");
649
-
650
- if ($data2 === false || $data2 === "")
651
- {
652
- if (feof($state["fp"])) return array("success" => false, "error" => self::HTTPTranslate("Remote peer disconnected."), "errorcode" => "peer_disconnected");
653
- else if ($state["async"]) return array("success" => false, "error" => self::HTTPTranslate("Non-blocking read returned no data."), "errorcode" => "no_data");
654
- else if ($data2 === false) return array("success" => false, "error" => self::HTTPTranslate("Underlying stream encountered a read error."), "errorcode" => "stream_read_error");
655
- }
656
- $pos = strpos($data2, "\n");
657
- if ($pos === false)
658
- {
659
- if (feof($state["fp"])) return array("success" => false, "error" => self::HTTPTranslate("Remote peer disconnected."), "errorcode" => "peer_disconnected");
660
- if (self::StreamTimedOut($state["fp"])) return array("success" => false, "error" => self::HTTPTranslate("Underlying stream timed out."), "errorcode" => "stream_timeout_exceeded");
661
-
662
- $pos = strlen($data2);
663
- }
664
- if ($state["timeout"] !== false && self::GetTimeLeft($state["startts"], $state["timeout"]) == 0) return array("success" => false, "error" => self::HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded");
665
- if (isset($state["options"]["readlinelimit"]) && strlen($state["data"]) + $pos > $state["options"]["readlinelimit"]) return array("success" => false, "error" => self::HTTPTranslate("Read line exceeded limit."), "errorcode" => "read_line_limit_exceeded");
666
-
667
- $state["rawsize"] += strlen($data2);
668
- $state["data"] .= $data2;
669
-
670
- if (isset($state["options"]["recvlimit"]) && $state["options"]["recvlimit"] < $state["rawsize"]) return array("success" => false, "error" => self::HTTPTranslate("Received data exceeded limit."), "errorcode" => "receive_limit_exceeded");
671
- if (isset($state["options"]["recvratelimit"])) $state["waituntil"] = self::ProcessRateLimit($state["rawsize"], $state["recvstart"], $state["options"]["recvratelimit"], $state["async"]);
672
-
673
- if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("rawrecv", $data2, &$state["options"]["debug_callback_opts"]));
674
- else if ($state["debug"]) $state["rawdata"] .= $data2;
675
- }
676
-
677
- return array("success" => true);
678
- }
679
-
680
- // Reads data in.
681
- private static function ProcessState__ReadBodyData(&$state)
682
- {
683
- while ($state["sizeleft"] === false || $state["sizeleft"] > 0)
684
- {
685
- $data2 = self::ProcessState__InternalRead($state, ($state["sizeleft"] === false || $state["sizeleft"] > 65536 ? 65536 : $state["sizeleft"]));
686
-
687
- if ($data2 === false) return array("success" => false, "error" => self::HTTPTranslate("Underlying stream encountered a read error."), "errorcode" => "stream_read_error");
688
- if ($data2 === "")
689
- {
690
- if (feof($state["fp"])) return array("success" => false, "error" => self::HTTPTranslate("Remote peer disconnected."), "errorcode" => "peer_disconnected");
691
- if (self::StreamTimedOut($state["fp"])) return array("success" => false, "error" => self::HTTPTranslate("Underlying stream timed out."), "errorcode" => "stream_timeout_exceeded");
692
-
693
- if ($state["async"]) return array("success" => false, "error" => self::HTTPTranslate("Non-blocking read returned no data."), "errorcode" => "no_data");
694
- }
695
- if ($state["timeout"] !== false && self::GetTimeLeft($state["startts"], $state["timeout"]) == 0) return array("success" => false, "error" => self::HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded");
696
-
697
- $tempsize = strlen($data2);
698
- $state["rawsize"] += $tempsize;
699
- if ($state["sizeleft"] !== false) $state["sizeleft"] -= $tempsize;
700
-
701
- if ($state["result"]["response"]["code"] == 100 || !isset($state["options"]["read_body_callback"]) || !is_callable($state["options"]["read_body_callback"])) $state["result"]["body"] .= self::GetDecodedBody($state["autodecode_ds"], $data2);
702
- else if (!call_user_func_array($state["options"]["read_body_callback"], array($state["result"][($state["client"] ? "response" : "request")], self::GetDecodedBody($state["autodecode_ds"], $data2), &$state["options"]["read_body_callback_opts"]))) return array("success" => false, "error" => self::HTTPTranslate("Read body callback returned with a failure condition."), "errorcode" => "read_body_callback");
703
-
704
- if (isset($state["options"]["recvlimit"]) && $state["options"]["recvlimit"] < $state["rawsize"]) return array("success" => false, "error" => self::HTTPTranslate("Received data exceeded limit."), "errorcode" => "receive_limit_exceeded");
705
-
706
- if (isset($state["options"]["recvratelimit"]))
707
- {
708
- $state["waituntil"] = self::ProcessRateLimit($state["rawsize"], $state["recvstart"], $state["options"]["recvratelimit"], $state["async"]);
709
- if (microtime(true) < $state["waituntil"]) return array("success" => false, "error" => self::HTTPTranslate("Rate limit for non-blocking connection has not been reached."), "errorcode" => "no_data");
710
- }
711
-
712
- if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("rawrecv", $data2, &$state["options"]["debug_callback_opts"]));
713
- else if ($state["debug"]) $state["rawdata"] .= $data2;
714
- }
715
-
716
- return array("success" => true);
717
- }
718
-
719
- // Writes data out.
720
- private static function ProcessState__WriteData(&$state, $prefix)
721
- {
722
- if ($state[$prefix . "data"] !== "")
723
- {
724
- // Serious bug in PHP core for non-blocking SSL sockets: https://bugs.php.net/bug.php?id=72333
725
- if ($state["secure"] && $state["async"])
726
- {
727
- // This is a huge hack that has a pretty good chance of blocking on the socket.
728
- // Peeling off up to just 4KB at a time helps to minimize that possibility. It's better than guaranteed failure of the socket though.
729
- @stream_set_blocking($state["fp"], 1);
730
- if ($state["debug"]) $result = fwrite($state["fp"], (strlen($state[$prefix . "data"]) > 4096 ? substr($state[$prefix . "data"], 0, 4096) : $state[$prefix . "data"]));
731
- else $result = @fwrite($state["fp"], (strlen($state[$prefix . "data"]) > 4096 ? substr($state[$prefix . "data"], 0, 4096) : $state[$prefix . "data"]));
732
- @stream_set_blocking($state["fp"], 0);
733
- }
734
- else
735
- {
736
- if ($state["debug"]) $result = fwrite($state["fp"], $state[$prefix . "data"]);
737
- else $result = @fwrite($state["fp"], $state[$prefix . "data"]);
738
- }
739
-
740
- if ($result === false || feof($state["fp"])) return array("success" => false, "error" => self::HTTPTranslate("A fwrite() failure occurred. Most likely cause: Connection failure."), "errorcode" => "fwrite_failed");
741
-
742
- // Serious bug in PHP core for all socket types: https://bugs.php.net/bug.php?id=73535
743
- if ($result === 0)
744
- {
745
- // Temporarily switch to non-blocking sockets and test a one byte read (doesn't matter if data is available or not).
746
- // This is a bigger hack than the first hack above.
747
- if (!$state["async"]) @stream_set_blocking($state["fp"], 0);
748
-
749
- if ($state["debug"]) $data2 = fread($state["fp"], 1);
750
- else $data2 = @fread($state["fp"], 1);
751
-
752
- if ($data2 === false) return array("success" => false, "error" => self::HTTPTranslate("Underlying stream encountered a read error."), "errorcode" => "stream_read_error");
753
- if ($data2 === "" && feof($state["fp"])) return array("success" => false, "error" => self::HTTPTranslate("Remote peer disconnected."), "errorcode" => "peer_disconnected");
754
-
755
- if ($data2 !== "") $state["nextread"] .= $data2;
756
-
757
- if (!$state["async"]) @stream_set_blocking($state["fp"], 1);
758
- }
759
-
760
- if ($state["timeout"] !== false && self::GetTimeLeft($state["startts"], $state["timeout"]) == 0) return array("success" => false, "error" => self::HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded");
761
-
762
- $data2 = (string)substr($state[$prefix . "data"], 0, $result);
763
- $state[$prefix . "data"] = (string)substr($state[$prefix . "data"], $result);
764
-
765
- $state["result"]["rawsend" . $prefix . "size"] += $result;
766
-
767
- if (isset($state["options"]["sendratelimit"]))
768
- {
769
- $state["waituntil"] = self::ProcessRateLimit($state["result"]["rawsendsize"], $state["result"]["connected"], $state["options"]["sendratelimit"], $state["async"]);
770
- if (microtime(true) < $state["waituntil"]) return array("success" => false, "error" => self::HTTPTranslate("Rate limit for non-blocking connection has not been reached."), "errorcode" => "no_data");
771
- }
772
-
773
- if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("rawsend", $data2, &$state["options"]["debug_callback_opts"]));
774
- else if ($state["debug"]) $state["result"]["rawsend"] .= $data2;
775
-
776
- if ($state["async"] && strlen($state[$prefix . "data"])) return array("success" => false, "error" => self::HTTPTranslate("Non-blocking write did not send all data."), "errorcode" => "no_data");
777
- }
778
-
779
- return array("success" => true);
780
- }
781
-
782
- public static function ForceClose(&$state)
783
- {
784
- if ($state["fp"] !== false)
785
- {
786
- @fclose($state["fp"]);
787
- $state["fp"] = false;
788
- }
789
-
790
- if (isset($state["currentfile"]) && $state["currentfile"] !== false)
791
- {
792
- if ($state["currentfile"]["fp"] !== false) @fclose($state["currentfile"]["fp"]);
793
- $state["currentfile"] = false;
794
- }
795
- }
796
-
797
- private static function CleanupErrorState(&$state, $result)
798
- {
799
- if (!$result["success"] && $result["errorcode"] !== "no_data")
800
- {
801
- self::ForceClose($state);
802
-
803
- $state["error"] = $result;
804
- }
805
-
806
- return $result;
807
- }
808
-
809
- public static function WantRead(&$state)
810
- {
811
- return ($state["type"] === "response" || $state["state"] === "proxy_connect_response" || $state["state"] === "receive_switch" || $state["state"] === "connecting_enable_crypto" || $state["state"] === "proxy_connect_enable_crypto");
812
- }
813
-
814
- public static function WantWrite(&$state)
815
- {
816
- return (!self::WantRead($state) || $state["state"] === "connecting_enable_crypto" || $state["state"] === "proxy_connect_enable_crypto");
817
- }
818
-
819
- public static function ProcessState(&$state)
820
- {
821
- if (isset($state["error"])) return $state["error"];
822
-
823
- if ($state["timeout"] !== false && self::GetTimeLeft($state["startts"], $state["timeout"]) == 0) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded"));
824
- if (microtime(true) < $state["waituntil"]) return array("success" => false, "error" => self::HTTPTranslate("Rate limit for non-blocking connection has not been reached."), "errorcode" => "no_data");
825
-
826
- if ($state["type"] === "request")
827
- {
828
- while ($state["state"] !== "done")
829
- {
830
- switch ($state["state"])
831
- {
832
- case "connecting":
833
- {
834
- if (function_exists("stream_select") && $state["async"])
835
- {
836
- $readfp = NULL;
837
- $writefp = array($state["fp"]);
838
- $exceptfp = array($state["fp"]);
839
- if ($state["debug"]) $result = stream_select($readfp, $writefp, $exceptfp, 0);
840
- else $result = @stream_select($readfp, $writefp, $exceptfp, 0);
841
- if ($result === false || count($exceptfp)) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("A stream_select() failure occurred. Most likely cause: Connection failure."), "errorcode" => "stream_select_failed"));
842
-
843
- if (!count($writefp)) return array("success" => false, "error" => self::HTTPTranslate("Connection not established yet."), "errorcode" => "no_data");
844
- }
845
-
846
- // Deal with failed connections that hang applications.
847
- if (isset($state["options"]["streamtimeout"]) && $state["options"]["streamtimeout"] !== false && function_exists("stream_set_timeout")) @stream_set_timeout($state["fp"], $state["options"]["streamtimeout"]);
848
-
849
- // Switch to the next state.
850
- if ($state["async"] && function_exists("stream_socket_client") && (($state["useproxy"] && $state["proxysecure"]) || (!$state["useproxy"] && $state["secure"]))) $state["state"] = "connecting_enable_crypto";
851
- else $state["state"] = "connection_ready";
852
-
853
- break;
854
- }
855
- case "connecting_enable_crypto":
856
- {
857
- // This is only used by clients that connect asynchronously via SSL.
858
- if ($state["debug"]) $result = stream_socket_enable_crypto($state["fp"], true, STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);
859
- else $result = @stream_socket_enable_crypto($state["fp"], true, STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);
860
-
861
- if ($result === false) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("A stream_socket_enable_crypto() failure occurred. Most likely cause: Connection failure or incompatible crypto setup."), "errorcode" => "stream_socket_enable_crypto_failed"));
862
- else if ($result === true) $state["state"] = "connection_ready";
863
-
864
- break;
865
- }
866
- case "connection_ready":
867
- {
868
- // Handle peer certificate retrieval.
869
- if (function_exists("stream_context_get_options"))
870
- {
871
- $contextopts = stream_context_get_options($state["fp"]);
872
- if ($state["useproxy"])
873
- {
874
- if ($state["proxysecure"] && isset($state["options"]["proxysslopts"]) && is_array($state["options"]["proxysslopts"]))
875
- {
876
- if (isset($state["options"]["peer_cert_callback"]) && is_callable($state["options"]["peer_cert_callback"]))
877
- {
878
- if (isset($contextopts["ssl"]["peer_certificate"]) && !call_user_func_array($state["options"]["peer_cert_callback"], array("proxypeercert", $contextopts["ssl"]["peer_certificate"], &$state["options"]["peer_cert_callback_opts"]))) return array("success" => false, "error" => self::HTTPTranslate("Peer certificate callback returned with a failure condition."), "errorcode" => "peer_cert_callback");
879
- if (isset($contextopts["ssl"]["peer_certificate_chain"]) && !call_user_func_array($state["options"]["peer_cert_callback"], array("proxypeercertchain", $contextopts["ssl"]["peer_certificate_chain"], &$state["options"]["peer_cert_callback_opts"]))) return array("success" => false, "error" => self::HTTPTranslate("Peer certificate callback returned with a failure condition."), "errorcode" => "peer_cert_callback");
880
- }
881
- }
882
- }
883
- else
884
- {
885
- if ($state["secure"] && isset($state["options"]["sslopts"]) && is_array($state["options"]["sslopts"]))
886
- {
887
- if (isset($state["options"]["peer_cert_callback"]) && is_callable($state["options"]["peer_cert_callback"]))
888
- {
889
- if (isset($contextopts["ssl"]["peer_certificate"]) && !call_user_func_array($state["options"]["peer_cert_callback"], array("peercert", $contextopts["ssl"]["peer_certificate"], &$state["options"]["peer_cert_callback_opts"]))) return array("success" => false, "error" => self::HTTPTranslate("Peer certificate callback returned with a failure condition."), "errorcode" => "peer_cert_callback");
890
- if (isset($contextopts["ssl"]["peer_certificate_chain"]) && !call_user_func_array($state["options"]["peer_cert_callback"], array("peercertchain", $contextopts["ssl"]["peer_certificate_chain"], &$state["options"]["peer_cert_callback_opts"]))) return array("success" => false, "error" => self::HTTPTranslate("Peer certificate callback returned with a failure condition."), "errorcode" => "peer_cert_callback");
891
- }
892
- }
893
- }
894
- }
895
-
896
- $state["result"]["connected"] = microtime(true);
897
-
898
- // Switch to the correct state.
899
- if ($state["proxyconnect"])
900
- {
901
- $state["result"]["rawsendproxysize"] = 0;
902
- $state["result"]["rawsendproxyheadersize"] = strlen($state["proxydata"]);
903
-
904
- $state["state"] = "proxy_connect_send";
905
- }
906
- else
907
- {
908
- $state["result"]["sendstart"] = microtime(true);
909
-
910
- $state["state"] = "send_data";
911
- }
912
-
913
- break;
914
- }
915
- case "proxy_connect_send":
916
- {
917
- // Send the HTTP CONNECT request to the proxy.
918
- $result = self::ProcessState__WriteData($state, "proxy");
919
- if (!$result["success"]) return self::CleanupErrorState($state, $result);
920
-
921
- // Prepare the state for handling the response from the proxy server.
922
- $options2 = array();
923
- if (isset($state["options"]["async"])) $options2["async"] = $state["options"]["async"];
924
- if (isset($state["options"]["recvratelimit"])) $options2["recvratelimit"] = $state["options"]["recvratelimit"];
925
- if (isset($state["options"]["debug_callback"]))
926
- {
927
- $options2["debug_callback"] = $state["options"]["debug_callback"];
928
- $options2["debug_callback_opts"] = $state["options"]["debug_callback_opts"];
929
- }
930
- $state["proxyresponse"] = self::InitResponseState($state["fp"], $state["debug"], $options2, $state["startts"], $state["timeout"], $state["result"], false, $state["nextread"]);
931
-
932
- $state["state"] = "proxy_connect_response";
933
-
934
- break;
935
- }
936
- case "proxy_connect_response":
937
- {
938
- // Recursively call this function to handle the proxy response.
939
- $result = self::ProcessState($state["proxyresponse"]);
940
- if (!$result["success"]) return self::CleanupErrorState($state, $result);
941
-
942
- $state["result"]["rawrecvsize"] += $result["rawrecvsize"];
943
- $state["result"]["rawrecvheadersize"] += $result["rawrecvheadersize"];
944
-
945
- if (substr($result["response"]["code"], 0, 1) != "2") return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("Expected a 200 response from the CONNECT request. Received: %s.", $result["response"]["line"]), "info" => $result, "errorcode" => "proxy_connect_tunnel_failed"));
946
-
947
- // Proxy connect tunnel established. Proceed normally.
948
- $state["result"]["sendstart"] = microtime(true);
949
-
950
- if ($state["secure"]) $state["state"] = "proxy_connect_enable_crypto";
951
- else $state["state"] = "send_data";
952
-
953
- break;
954
- }
955
- case "proxy_connect_enable_crypto":
956
- {
957
- if ($state["debug"]) $result = stream_socket_enable_crypto($state["fp"], true, STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);
958
- else $result = @stream_socket_enable_crypto($state["fp"], true, STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT);
959
-
960
- if ($result === false) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("A stream_socket_enable_crypto() failure occurred. Most likely cause: Tunnel connection failure or incompatible crypto setup."), "errorcode" => "stream_socket_enable_crypto_failed"));
961
- else if ($result === true)
962
- {
963
- // Handle peer certificate retrieval.
964
- if (function_exists("stream_context_get_options"))
965
- {
966
- $contextopts = stream_context_get_options($state["fp"]);
967
-
968
- if (isset($state["options"]["sslopts"]) && is_array($state["options"]["sslopts"]))
969
- {
970
- if (isset($state["options"]["peer_cert_callback"]) && is_callable($state["options"]["peer_cert_callback"]))
971
- {
972
- if (isset($contextopts["ssl"]["peer_certificate"]) && !call_user_func_array($state["options"]["peer_cert_callback"], array("peercert", $contextopts["ssl"]["peer_certificate"], &$state["options"]["peer_cert_callback_opts"]))) return array("success" => false, "error" => self::HTTPTranslate("Peer certificate callback returned with a failure condition."), "errorcode" => "peer_cert_callback");
973
- if (isset($contextopts["ssl"]["peer_certificate_chain"]) && !call_user_func_array($state["options"]["peer_cert_callback"], array("peercertchain", $contextopts["ssl"]["peer_certificate_chain"], &$state["options"]["peer_cert_callback_opts"]))) return array("success" => false, "error" => self::HTTPTranslate("Peer certificate callback returned with a failure condition."), "errorcode" => "peer_cert_callback");
974
- }
975
- }
976
- }
977
-
978
- // Secure connection established.
979
- $state["state"] = "send_data";
980
- }
981
-
982
- break;
983
- }
984
- case "send_data":
985
- {
986
- // Send the queued data.
987
- $result = self::ProcessState__WriteData($state, "");
988
- if (!$result["success"]) return self::CleanupErrorState($state, $result);
989
-
990
- // Queue up more data.
991
- if (isset($state["options"]["write_body_callback"]) && is_callable($state["options"]["write_body_callback"]))
992
- {
993
- if ($state["bodysize"] === false || $state["bodysize"] > 0)
994
- {
995
- $bodysize2 = $state["bodysize"];
996
- $result = call_user_func_array($state["options"]["write_body_callback"], array(&$state["data"], &$bodysize2, &$state["options"]["write_body_callback_opts"]));
997
- if (!$result || ($state["bodysize"] !== false && strlen($state["data"]) > $state["bodysize"])) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("HTTP write body callback function failed."), "errorcode" => "write_body_callback"));
998
-
999
- if ($state["bodysize"] === false)
1000
- {
1001
- if ($state["data"] !== "" && $state["chunked"]) $state["data"] = dechex(strlen($state["data"])) . "\r\n" . $state["data"] . "\r\n";
1002
-
1003
- // When $bodysize2 is set to true, it is the last chunk.
1004
- if ($bodysize2 === true)
1005
- {
1006
- if ($state["chunked"])
1007
- {
1008
- $state["data"] .= "0\r\n";
1009
-
1010
- // Allow the body callback function to append additional headers to the content to send.
1011
- // It is up to the callback function to correctly format the extra headers.
1012
- $result = call_user_func_array($state["options"]["write_body_callback"], array(&$state["data"], &$bodysize2, &$state["options"]["write_body_callback_opts"]));
1013
- if (!$result) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("HTTP write body callback function failed."), "errorcode" => "write_body_callback"));
1014
-
1015
- $state["data"] .= "\r\n";
1016
- }
1017
-
1018
- $state["bodysize"] = 0;
1019
- }
1020
- }
1021
- else
1022
- {
1023
- $state["bodysize"] -= strlen($state["data"]);
1024
- }
1025
- }
1026
- }
1027
- else if (isset($state["options"]["files"]) && $state["bodysize"] > 0)
1028
- {
1029
- // Select the next file to upload.
1030
- if ($state["currentfile"] === false && count($state["options"]["files"]))
1031
- {
1032
- $state["currentfile"] = array_shift($state["options"]["files"]);
1033
-
1034
- $name = self::HeaderValueCleanup($state["currentfile"]["name"]);
1035
- $name = str_replace("\"", "", $name);
1036
- $filename = self::FilenameSafe(self::ExtractFilename($state["currentfile"]["filename"]));
1037
- $type = self::HeaderValueCleanup($state["currentfile"]["type"]);
1038
-
1039
- $state["data"] = "--" . $state["mime"] . "\r\n";
1040
- $state["data"] .= "Content-Disposition: form-data; name=\"" . $name . "\"; filename=\"" . $filename . "\"\r\n";
1041
- $state["data"] .= "Content-Type: " . $type . "\r\n";
1042
- $state["data"] .= "\r\n";
1043
-
1044
- if (!isset($state["currentfile"]["datafile"]))
1045
- {
1046
- $state["data"] .= $state["currentfile"]["data"];
1047
- $state["data"] .= "\r\n";
1048
-
1049
- $state["currentfile"] = false;
1050
- }
1051
- else
1052
- {
1053
- $state["currentfile"]["fp"] = @fopen($state["currentfile"]["datafile"], "rb");
1054
- if ($state["currentfile"]["fp"] === false) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("The file '%s' does not exist.", $state["currentfile"]["datafile"]), "errorcode" => "file_does_not_exist"));
1055
- }
1056
- }
1057
-
1058
- // Process the next chunk of file information.
1059
- if ($state["currentfile"] !== false && isset($state["currentfile"]["fp"]))
1060
- {
1061
- // Read/Write up to 65K at a time.
1062
- if ($state["currentfile"]["filesize"] >= 65536)
1063
- {
1064
- $data2 = fread($state["currentfile"]["fp"], 65536);
1065
- if ($data2 === false || strlen($data2) !== 65536) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("A read error was encountered with the file '%s'.", $state["currentfile"]["datafile"]), "errorcode" => "file_read"));
1066
-
1067
- $state["data"] .= $data2;
1068
-
1069
- $state["currentfile"]["filesize"] -= 65536;
1070
- }
1071
- else
1072
- {
1073
- // Read in the rest.
1074
- if ($state["currentfile"]["filesize"] > 0)
1075
- {
1076
- $data2 = fread($state["currentfile"]["fp"], $state["currentfile"]["filesize"]);
1077
- if ($data2 === false || strlen($data2) != $state["currentfile"]["filesize"]) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("A read error was encountered with the file '%s'.", $state["currentfile"]["datafile"]), "errorcode" => "file_read"));
1078
-
1079
- $state["data"] .= $data2;
1080
- }
1081
-
1082
- $state["data"] .= "\r\n";
1083
-
1084
- fclose($state["currentfile"]["fp"]);
1085
-
1086
- $state["currentfile"] = false;
1087
- }
1088
- }
1089
-
1090
- // If there is no more data, write out the closing MIME line.
1091
- if ($state["data"] === "") $state["data"] = "--" . $state["mime"] . "--\r\n";
1092
-
1093
- $state["bodysize"] -= strlen($state["data"]);
1094
- }
1095
- else if ($state["bodysize"] === false || $state["bodysize"] > 0)
1096
- {
1097
- return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("A weird internal HTTP error that should never, ever happen...just happened."), "errorcode" => "impossible"));
1098
- }
1099
-
1100
- // All done sending data.
1101
- if ($state["data"] === "")
1102
- {
1103
- if ($state["client"]) $state["state"] = "receive_switch";
1104
- else
1105
- {
1106
- $state["result"]["endts"] = microtime(true);
1107
-
1108
- if ($state["close"]) fclose($state["fp"]);
1109
- else $state["result"]["fp"] = $state["fp"];
1110
-
1111
- return $state["result"];
1112
- }
1113
- }
1114
-
1115
- break;
1116
- }
1117
- case "receive_switch":
1118
- {
1119
- if (function_exists("stream_select") && $state["async"])
1120
- {
1121
- $readfp = array($state["fp"]);
1122
- $writefp = NULL;
1123
- $exceptfp = NULL;
1124
- if ($state["debug"]) $result = stream_select($readfp, $writefp, $exceptfp, 0);
1125
- else $result = @stream_select($readfp, $writefp, $exceptfp, 0);
1126
- if ($result === false) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("A stream_select() failure occurred. Most likely cause: Connection failure."), "errorcode" => "stream_select_failed"));
1127
-
1128
- if (!count($readfp)) return array("success" => false, "error" => self::HTTPTranslate("Connection not fully established yet."), "errorcode" => "no_data");
1129
- }
1130
-
1131
- $state["state"] = "done";
1132
-
1133
- break;
1134
- }
1135
- }
1136
- }
1137
-
1138
- // The request has been sent. Change the state to a response state.
1139
- $state = self::InitResponseState($state["fp"], $state["debug"], $state["options"], $state["startts"], $state["timeout"], $state["result"], $state["close"], $state["nextread"]);
1140
-
1141
- // Run one cycle.
1142
- return self::ProcessState($state);
1143
- }
1144
- else if ($state["type"] === "response")
1145
- {
1146
- while ($state["state"] !== "done")
1147
- {
1148
- switch ($state["state"])
1149
- {
1150
- case "response_line":
1151
- {
1152
- $result = self::ProcessState__ReadLine($state);
1153
- if (!$result["success"]) return self::CleanupErrorState($state, $result);
1154
-
1155
- // Parse the response line.
1156
- $pos = strpos($state["data"], "\n");
1157
- if ($pos === false) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("Unable to retrieve response line."), "errorcode" => "get_response_line"));
1158
- $line = trim(substr($state["data"], 0, $pos));
1159
- $state["data"] = substr($state["data"], $pos + 1);
1160
- $state["rawrecvheadersize"] += $pos + 1;
1161
- $response = explode(" ", $line, 3);
1162
-
1163
- $state["result"]["response"] = array(
1164
- "line" => $line,
1165
- "httpver" => strtoupper($response[0]),
1166
- "code" => $response[1],
1167
- "meaning" => (isset($response[2]) ? $response[2] : "")
1168
- );
1169
-
1170
- $state["state"] = "headers";
1171
- $state["result"]["headers"] = array();
1172
- $state["lastheader"] = "";
1173
-
1174
- break;
1175
- }
1176
- case "request_line":
1177
- {
1178
- // Server mode only.
1179
- $result = self::ProcessState__ReadLine($state);
1180
- if (!$result["success"]) return self::CleanupErrorState($state, $result);
1181
-
1182
- // Parse the request line.
1183
- $pos = strpos($state["data"], "\n");
1184
- if ($pos === false) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("Unable to retrieve request line."), "errorcode" => "get_request_line"));
1185
- $line = trim(substr($state["data"], 0, $pos));
1186
- $state["data"] = substr($state["data"], $pos + 1);
1187
- $state["rawrecvheadersize"] += $pos + 1;
1188
-
1189
- $request = $line;
1190
- $pos = strpos($request, " ");
1191
- if ($pos === false) $pos = strlen($request);
1192
- $method = (string)substr($request, 0, $pos);
1193
- $request = trim(substr($request, $pos));
1194
-
1195
- $pos = strrpos($request, " ");
1196
- if ($pos === false) $pos = strlen($request);
1197
- $path = trim(substr($request, 0, $pos));
1198
- if ($path === "") $path = "/";
1199
- $version = (string)substr($request, $pos + 1);
1200
-
1201
- $state["result"]["request"] = array(
1202
- "line" => $line,
1203
- "method" => strtoupper($method),
1204
- "path" => $path,
1205
- "httpver" => strtoupper($version),
1206
- );
1207
-
1208
- // Fake the response line to bypass some client-only code.
1209
- $state["result"]["response"] = array(
1210
- "line" => "200",
1211
- "httpver" => "",
1212
- "code" => 200,
1213
- "meaning" => ""
1214
- );
1215
-
1216
- $state["state"] = "headers";
1217
- $state["result"]["headers"] = array();
1218
- $state["lastheader"] = "";
1219
-
1220
- break;
1221
- }
1222
- case "headers":
1223
- case "body_chunked_headers":
1224
- {
1225
- $result = self::ProcessState__ReadLine($state);
1226
- if (!$result["success"] && ($state["state"] === "headers" || ($result["errorcode"] !== "stream_read_error" && $result["errorcode"] !== "peer_disconnected"))) return self::CleanupErrorState($state, $result);
1227
-
1228
- $pos = strpos($state["data"], "\n");
1229
- if ($pos === false) $pos = strlen($state["data"]);
1230
- $header = rtrim(substr($state["data"], 0, $pos));
1231
- $state["data"] = substr($state["data"], $pos + 1);
1232
- $state["rawrecvheadersize"] += $pos + 1;
1233
- if ($header != "")
1234
- {
1235
- if ($state["lastheader"] != "" && (substr($header, 0, 1) == " " || substr($header, 0, 1) == "\t")) $state["result"]["headers"][$state["lastheader"]][count($state["result"]["headers"][$state["lastheader"]]) - 1] .= $header;
1236
- else
1237
- {
1238
- $pos = strpos($header, ":");
1239
- if ($pos === false) $pos = strlen($header);
1240
- $state["lastheader"] = self::HeaderNameCleanup(substr($header, 0, $pos));
1241
- if (!isset($state["result"]["headers"][$state["lastheader"]])) $state["result"]["headers"][$state["lastheader"]] = array();
1242
- $state["result"]["headers"][$state["lastheader"]][] = ltrim(substr($header, $pos + 1));
1243
- }
1244
-
1245
- $state["numheaders"]++;
1246
- if (isset($state["options"]["maxheaders"]) && $state["numheaders"] > $state["options"]["maxheaders"]) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("The number of headers exceeded the limit."), "errorcode" => "headers_limit_exceeded"));
1247
- }
1248
- else
1249
- {
1250
- if ($state["result"]["response"]["code"] != 100 && isset($state["options"]["read_headers_callback"]) && is_callable($state["options"]["read_headers_callback"]))
1251
- {
1252
- if (!call_user_func_array($state["options"]["read_headers_callback"], array(&$state["result"][($state["client"] ? "response" : "request")], &$state["result"]["headers"], &$state["options"]["read_headers_callback_opts"]))) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("Read headers callback returned with a failure condition."), "errorcode" => "read_header_callback"));
1253
- }
1254
-
1255
- // Additional headers (optional) are the last bit of data in a chunked response.
1256
- if ($state["state"] === "body_chunked_headers") $state["state"] = "body_finalize";
1257
- else
1258
- {
1259
- $state["result"]["body"] = "";
1260
-
1261
- // Handle 100 Continue below OR WebSocket among other things by letting the caller handle reading the body.
1262
- if ($state["result"]["response"]["code"] == 100 || $state["result"]["response"]["code"] == 101) $state["state"] = "done";
1263
- else
1264
- {
1265
- // Determine if decoding the content is possible and necessary.
1266
- if ($state["autodecode"] && !isset($state["result"]["headers"]["Content-Encoding"]) || (strtolower($state["result"]["headers"]["Content-Encoding"][0]) != "gzip" && strtolower($state["result"]["headers"]["Content-Encoding"][0]) != "deflate")) $state["autodecode"] = false;
1267
- if (!$state["autodecode"]) $state["autodecode_ds"] = false;
1268
- else
1269
- {
1270
- if (!class_exists("DeflateStream", false)) require_once str_replace("\\", "/", dirname(__FILE__)) . "/deflate_stream.php";
1271
-
1272
- // Since servers and browsers do everything wrong, ignore the encoding claim and attempt to auto-detect the encoding.
1273
- $state["autodecode_ds"] = new DeflateStream();
1274
- $state["autodecode_ds"]->Init("rb", -1, array("type" => "auto"));
1275
- }
1276
-
1277
- // Use the appropriate state for handling the next bit of input.
1278
- if (isset($state["result"]["headers"]["Transfer-Encoding"]) && strtolower($state["result"]["headers"]["Transfer-Encoding"][0]) == "chunked")
1279
- {
1280
- $state["state"] = "body_chunked_size";
1281
- }
1282
- else
1283
- {
1284
- $state["sizeleft"] = (isset($state["result"]["headers"]["Content-Length"]) ? (double)preg_replace('/[^0-9]/', "", $state["result"]["headers"]["Content-Length"][0]) : false);
1285
- $state["state"] = ($state["sizeleft"] !== false || $state["client"] ? "body_content" : "done");
1286
- }
1287
-
1288
- // Let servers have a chance to alter limits before processing the input body.
1289
- if (!$state["client"] && $state["state"] !== "done") return array("success" => false, "error" => self::HTTPTranslate("Intermission for adjustments to limits."), "errorcode" => "no_data");
1290
- }
1291
- }
1292
- }
1293
-
1294
- break;
1295
- }
1296
- case "body_chunked_size":
1297
- {
1298
- $result = self::ProcessState__ReadLine($state);
1299
- if (!$result["success"]) return self::CleanupErrorState($state, $result);
1300
-
1301
- $pos = strpos($state["data"], "\n");
1302
- if ($pos === false) $pos = strlen($state["data"]);
1303
- $line = trim(substr($state["data"], 0, $pos));
1304
- $state["data"] = substr($state["data"], $pos + 1);
1305
- $pos = strpos($line, ";");
1306
- if ($pos === false) $pos = strlen($line);
1307
- $size = hexdec(substr($line, 0, $pos));
1308
- if ($size < 0) $size = 0;
1309
-
1310
- // Retrieve content.
1311
- $size2 = $size;
1312
- $size3 = min(strlen($state["data"]), $size);
1313
- if ($size3 > 0)
1314
- {
1315
- $data2 = substr($state["data"], 0, $size3);
1316
- $state["data"] = substr($state["data"], $size3);
1317
- $size2 -= $size3;
1318
-
1319
- if ($state["result"]["response"]["code"] == 100 || !isset($state["options"]["read_body_callback"]) || !is_callable($state["options"]["read_body_callback"])) $state["result"]["body"] .= self::GetDecodedBody($state["autodecode_ds"], $data2);
1320
- else if (!call_user_func_array($state["options"]["read_body_callback"], array($state["result"][($state["client"] ? "response" : "request")], self::GetDecodedBody($state["autodecode_ds"], $data2), &$state["options"]["read_body_callback_opts"]))) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("Read body callback returned with a failure condition."), "errorcode" => "read_body_callback"));
1321
- }
1322
-
1323
- $state["chunksize"] = $size;
1324
- $state["sizeleft"] = $size2;
1325
- $state["state"] = "body_chunked_data";
1326
-
1327
- break;
1328
- }
1329
- case "body_chunked_data":
1330
- {
1331
- $result = self::ProcessState__ReadBodyData($state);
1332
- if (!$result["success"]) return self::CleanupErrorState($state, $result);
1333
-
1334
- if ($state["chunksize"] > 0) $state["state"] = "body_chunked_skipline";
1335
- else
1336
- {
1337
- $state["lastheader"] = "";
1338
- $state["state"] = "body_chunked_headers";
1339
- }
1340
-
1341
- break;
1342
- }
1343
- case "body_chunked_skipline":
1344
- {
1345
- $result = self::ProcessState__ReadLine($state);
1346
- if (!$result["success"]) return self::CleanupErrorState($state, $result);
1347
-
1348
- // Ignore one newline.
1349
- $pos = strpos($state["data"], "\n");
1350
- if ($pos === false) $pos = strlen($state["data"]);
1351
- $state["data"] = substr($state["data"], $pos + 1);
1352
-
1353
- $state["state"] = "body_chunked_size";
1354
-
1355
- break;
1356
- }
1357
- case "body_content":
1358
- {
1359
- $result = self::ProcessState__ReadBodyData($state);
1360
- if (!$result["success"] && (($state["sizeleft"] !== false && $state["sizeleft"] > 0) || ($state["sizeleft"] === false && $result["errorcode"] !== "stream_read_error" && $result["errorcode"] !== "peer_disconnected" && $result["errorcode"] !== "stream_timeout_exceeded"))) return self::CleanupErrorState($state, $result);
1361
-
1362
- $state["state"] = "body_finalize";
1363
-
1364
- break;
1365
- }
1366
- case "body_finalize":
1367
- {
1368
- if ($state["autodecode_ds"] !== false)
1369
- {
1370
- $state["autodecode_ds"]->Finalize();
1371
- $data2 = $state["autodecode_ds"]->Read();
1372
-
1373
- if ($state["result"]["response"]["code"] == 100 || !isset($state["options"]["read_body_callback"]) || !is_callable($state["options"]["read_body_callback"])) $state["result"]["body"] .= $data2;
1374
- else if (!call_user_func_array($state["options"]["read_body_callback"], array($state["result"][($state["client"] ? "response" : "request")], $data2, &$state["options"]["read_body_callback_opts"]))) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("Read body callback returned with a failure condition."), "errorcode" => "read_body_callback"));
1375
- }
1376
-
1377
- $state["state"] = "done";
1378
-
1379
- break;
1380
- }
1381
- }
1382
-
1383
- // Handle HTTP 100 Continue status codes.
1384
- if ($state["state"] === "done" && $state["result"]["response"]["code"] == 100)
1385
- {
1386
- $state["autodecode"] = (!isset($state["options"]["auto_decode"]) || $state["options"]["auto_decode"]);
1387
- $state["state"] = "response";
1388
- $state["result"]["response"] = false;
1389
- $state["result"]["headers"] = false;
1390
- $state["result"]["body"] = false;
1391
- }
1392
- }
1393
-
1394
- if ($state["debug"]) $state["result"]["rawrecv"] .= $state["rawdata"];
1395
- $state["result"]["rawrecvsize"] += $state["rawsize"];
1396
- $state["result"]["rawrecvheadersize"] += $state["rawrecvheadersize"];
1397
- $state["result"]["endts"] = microtime(true);
1398
-
1399
- if ($state["close"] || ($state["client"] && isset($state["result"]["headers"]["Connection"]) && strtolower($state["result"]["headers"]["Connection"][0]) === "close")) fclose($state["fp"]);
1400
- else $state["result"]["fp"] = $state["fp"];
1401
-
1402
- return $state["result"];
1403
- }
1404
- else
1405
- {
1406
- return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("Invalid 'type' in state tracker."), "errorcode" => "invalid_type"));
1407
- }
1408
- }
1409
-
1410
- public static function RawFileSize($fileorname)
1411
- {
1412
- if (is_resource($fileorname)) $fp = $fileorname;
1413
- else
1414
- {
1415
- $fp = @fopen($fileorname, "rb");
1416
- if ($fp === false) return 0;
1417
- }
1418
-
1419
- if (PHP_INT_SIZE < 8)
1420
- {
1421
- $pos = 0;
1422
- $size = 1073741824;
1423
- fseek($fp, 0, SEEK_SET);
1424
- while ($size > 1)
1425
- {
1426
- if (fseek($fp, $size, SEEK_CUR) === -1) break;
1427
-
1428
- if (fgetc($fp) === false)
1429
- {
1430
- fseek($fp, -$size, SEEK_CUR);
1431
- $size = (int)($size / 2);
1432
- }
1433
- else
1434
- {
1435
- fseek($fp, -1, SEEK_CUR);
1436
- $pos += $size;
1437
- }
1438
- }
1439
-
1440
- if ($size > 1)
1441
- {
1442
- // Unfortunately, fseek() failed for some reason. Going to have to do this the old-fashioned way.
1443
- do
1444
- {
1445
- $data = fread($fp, 10485760);
1446
- if ($data === false) $data = "";
1447
- $pos += strlen($data);
1448
- } while ($data !== "");
1449
- }
1450
- else
1451
- {
1452
- while (fgetc($fp) !== false) $pos++;
1453
- }
1454
- }
1455
- else
1456
- {
1457
- fseek($fp, 0, SEEK_END);
1458
- $pos = ftell($fp);
1459
- }
1460
-
1461
- if (!is_resource($fileorname)) fclose($fp);
1462
-
1463
- return $pos;
1464
- }
1465
-
1466
- public static function RetrieveWebpage($url, $options = array())
1467
- {
1468
- $startts = microtime(true);
1469
- $timeout = (isset($options["timeout"]) ? $options["timeout"] : false);
1470
-
1471
- if (!function_exists("stream_socket_client") && !function_exists("fsockopen")) return array("success" => false, "error" => self::HTTPTranslate("The functions 'stream_socket_client' and 'fsockopen' do not exist."), "errorcode" => "function_check");
1472
-
1473
- // Process the URL.
1474
- $url = trim($url);
1475
- $url = self::ExtractURL($url);
1476
-
1477
- if ($url["scheme"] != "http" && $url["scheme"] != "https") return array("success" => false, "error" => self::HTTPTranslate("RetrieveWebpage() only supports the 'http' and 'https' protocols."), "errorcode" => "protocol_check");
1478
-
1479
- $secure = ($url["scheme"] == "https");
1480
- $async = (isset($options["async"]) ? $options["async"] : false);
1481
- $protocol = ($secure && !$async ? (isset($options["protocol"]) ? strtolower($options["protocol"]) : "ssl") : "tcp");
1482
- if (function_exists("stream_get_transports") && !in_array($protocol, stream_get_transports())) return array("success" => false, "error" => self::HTTPTranslate("The desired transport protocol '%s' is not installed.", $protocol), "errorcode" => "transport_not_installed");
1483
- $host = str_replace(" ", "-", self::HeaderValueCleanup($url["host"]));
1484
- if ($host == "") return array("success" => false, "error" => self::HTTPTranslate("Invalid URL."));
1485
- $port = ((int)$url["port"] ? (int)$url["port"] : ($secure ? 443 : 80));
1486
- $defaultport = ((!$secure && $port == 80) || ($secure && $port == 443));
1487
- $path = ($url["path"] == "" ? "/" : $url["path"]);
1488
- $query = $url["query"];
1489
- $username = $url["loginusername"];
1490
- $password = $url["loginpassword"];
1491
-
1492
- // Cleanup input headers.
1493
- if (!isset($options["headers"])) $options["headers"] = array();
1494
- $options["headers"] = self::NormalizeHeaders($options["headers"]);
1495
- if (isset($options["rawheaders"])) self::MergeRawHeaders($options["headers"], $options["rawheaders"]);
1496
-
1497
- // Process the proxy URL (if specified).
1498
- $useproxy = (isset($options["proxyurl"]) && trim($options["proxyurl"]) != "");
1499
- $proxysecure = false;
1500
- $proxyconnect = false;
1501
- $proxydata = "";
1502
- if ($useproxy)
1503
- {
1504
- $proxyurl = trim($options["proxyurl"]);
1505
- $proxyurl = self::ExtractURL($proxyurl);
1506
-
1507
- $proxysecure = ($proxyurl["scheme"] == "https");
1508
- if ($proxysecure && $secure) return array("success" => false, "error" => self::HTTPTranslate("The PHP SSL sockets implementation does not support tunneled SSL/TLS connections over SSL/TLS."), "errorcode" => "multi_ssl_tunneling_not_supported");
1509
- $proxyprotocol = ($proxysecure && !$async ? (isset($options["proxyprotocol"]) ? strtolower($options["proxyprotocol"]) : "ssl") : "tcp");
1510
- if (function_exists("stream_get_transports") && !in_array($proxyprotocol, stream_get_transports())) return array("success" => false, "error" => self::HTTPTranslate("The desired transport proxy protocol '%s' is not installed.", $proxyprotocol), "errorcode" => "proxy_transport_not_installed");
1511
- $proxyhost = str_replace(" ", "-", self::HeaderValueCleanup($proxyurl["host"]));
1512
- if ($proxyhost === "") return array("success" => false, "error" => self::HTTPTranslate("The specified proxy URL is not a URL. Prefix 'proxyurl' with http:// or https://"), "errorcode" => "invalid_proxy_url");
1513
- $proxyport = ((int)$proxyurl["port"] ? (int)$proxyurl["port"] : ($proxysecure ? 443 : 80));
1514
- $proxypath = ($proxyurl["path"] == "" ? "/" : $proxyurl["path"]);
1515
- $proxyusername = $proxyurl["loginusername"];
1516
- $proxypassword = $proxyurl["loginpassword"];
1517
-
1518
- // Open a tunnel instead of letting the proxy modify the request (HTTP CONNECT).
1519
- $proxyconnect = (isset($options["proxyconnect"]) && $options["proxyconnect"] ? $options["proxyconnect"] : false);
1520
- if ($proxyconnect)
1521
- {
1522
- $proxydata = "CONNECT " . $host . ":" . $port . " HTTP/1.1\r\n";
1523
- if (isset($options["headers"]["User-Agent"])) $proxydata .= "User-Agent: " . $options["headers"]["User-Agent"] . "\r\n";
1524
- $proxydata .= "Host: " . $host . ($defaultport ? "" : ":" . $port) . "\r\n";
1525
- $proxydata .= "Proxy-Connection: keep-alive\r\n";
1526
- if ($proxyusername != "") $proxydata .= "Proxy-Authorization: BASIC " . base64_encode($proxyusername . ":" . $proxypassword) . "\r\n";
1527
- if (!isset($options["proxyheaders"])) $options["proxyheaders"] = array();
1528
- $options["proxyheaders"] = self::NormalizeHeaders($options["proxyheaders"]);
1529
- if (isset($options["rawproxyheaders"])) self::MergeRawHeaders($options["proxyheaders"], $options["rawproxyheaders"]);
1530
-
1531
- unset($options["proxyheaders"]["Accept-Encoding"]);
1532
- foreach ($options["proxyheaders"] as $name => $val)
1533
- {
1534
- if ($name != "Content-Type" && $name != "Content-Length" && $name != "Proxy-Connection" && $name != "Host") $proxydata .= $name . ": " . $val . "\r\n";
1535
- }
1536
-
1537
- $proxydata .= "\r\n";
1538
- if (isset($options["debug_callback"]) && is_callable($options["debug_callback"])) call_user_func_array($options["debug_callback"], array("rawproxyheaders", $proxydata, &$options["debug_callback_opts"]));
1539
- }
1540
- }
1541
-
1542
- // Process the method.
1543
- if (!isset($options["method"]))
1544
- {
1545
- if ((isset($options["write_body_callback"]) && is_callable($options["write_body_callback"])) || isset($options["body"])) $options["method"] = "PUT";
1546
- else if (isset($options["postvars"]) || (isset($options["files"]) && count($options["files"]))) $options["method"] = "POST";
1547
- else $options["method"] = "GET";
1548
- }
1549
- $options["method"] = preg_replace('/[^A-Z]/', "", strtoupper($options["method"]));
1550
-
1551
- // Process the HTTP version.
1552
- if (!isset($options["httpver"])) $options["httpver"] = "1.1";
1553
- $options["httpver"] = preg_replace('/[^0-9.]/', "", $options["httpver"]);
1554
-
1555
- // Process the request.
1556
- $data = $options["method"] . " ";
1557
- $data .= ($useproxy && !$proxyconnect ? $url["scheme"] . "://" . $host . ":" . $port : "") . $path . ($query != "" ? "?" . $query : "");
1558
- $data .= " HTTP/" . $options["httpver"] . "\r\n";
1559
-
1560
- // Process the headers.
1561
- if ($useproxy && !$proxyconnect && $proxyusername != "") $data .= "Proxy-Authorization: BASIC " . base64_encode($proxyusername . ":" . $proxypassword) . "\r\n";
1562
- if ($username != "") $data .= "Authorization: BASIC " . base64_encode($username . ":" . $password) . "\r\n";
1563
- $ver = explode(".", $options["httpver"]);
1564
- if ((int)$ver[0] > 1 || ((int)$ver[0] == 1 && (int)$ver[1] >= 1))
1565
- {
1566
- if (!isset($options["headers"]["Host"])) $options["headers"]["Host"] = $host . ($defaultport ? "" : ":" . $port);
1567
- $data .= "Host: " . $options["headers"]["Host"] . "\r\n";
1568
- }
1569
-
1570
- if (!isset($options["headers"]["Connection"])) $options["headers"]["Connection"] = "close";
1571
- $data .= "Connection: " . $options["headers"]["Connection"] . "\r\n";
1572
-
1573
- foreach ($options["headers"] as $name => $val)
1574
- {
1575
- if ($name != "Content-Type" && $name != "Content-Length" && $name != "Connection" && $name != "Host") $data .= $name . ": " . $val . "\r\n";
1576
- }
1577
-
1578
- if (isset($options["files"]) && !count($options["files"])) unset($options["files"]);
1579
-
1580
- // Process the body.
1581
- $mime = "";
1582
- $body = "";
1583
- $bodysize = 0;
1584
- if (isset($options["write_body_callback"]) && is_callable($options["write_body_callback"]))
1585
- {
1586
- if (isset($options["headers"]["Content-Type"])) $data .= "Content-Type: " . $options["headers"]["Content-Type"] . "\r\n";
1587
-
1588
- call_user_func_array($options["write_body_callback"], array(&$body, &$bodysize, &$options["write_body_callback_opts"]));
1589
- }
1590
- else if (isset($options["body"]))
1591
- {
1592
- if (isset($options["headers"]["Content-Type"])) $data .= "Content-Type: " . $options["headers"]["Content-Type"] . "\r\n";
1593
-
1594
- $body = $options["body"];
1595
- $bodysize = strlen($body);
1596
- unset($options["body"]);
1597
- }
1598
- else if ((isset($options["files"]) && count($options["files"])) || (isset($options["headers"]["Content-Type"]) && stripos($options["headers"]["Content-Type"], "multipart/form-data") !== false))
1599
- {
1600
- $mime = "--------" . substr(sha1(uniqid(mt_rand(), true)), 0, 25);
1601
- $data .= "Content-Type: multipart/form-data; boundary=" . $mime . "\r\n";
1602
- if (isset($options["postvars"]))
1603
- {
1604
- foreach ($options["postvars"] as $name => $val)
1605
- {
1606
- $name = self::HeaderValueCleanup($name);
1607
- $name = str_replace("\"", "", $name);
1608
-
1609
- if (!is_array($val))
1610
- {
1611
- if (is_string($val) || is_numeric($val)) $val = array($val);
1612
- else return array("success" => false, "error" => "A supplied 'postvars' value is an invalid type. Expected string, numeric, or array.", "errorcode" => "invalid_postvars_value", "info" => array("name" => $name, "val" => $val));
1613
- }
1614
-
1615
- foreach ($val as $val2)
1616
- {
1617
- $body .= "--" . $mime . "\r\n";
1618
- $body .= "Content-Disposition: form-data; name=\"" . $name . "\"\r\n";
1619
- $body .= "\r\n";
1620
- $body .= $val2 . "\r\n";
1621
- }
1622
- }
1623
-
1624
- unset($options["postvars"]);
1625
- }
1626
-
1627
- $bodysize = strlen($body);
1628
-
1629
- // Only count the amount of data to send.
1630
- if (!isset($options["files"])) $options["files"] = array();
1631
- foreach ($options["files"] as $num => $info)
1632
- {
1633
- $name = self::HeaderValueCleanup($info["name"]);
1634
- $name = str_replace("\"", "", $name);
1635
- $filename = self::FilenameSafe(self::ExtractFilename($info["filename"]));
1636
- $type = self::HeaderValueCleanup($info["type"]);
1637
-
1638
- $body2 = "--" . $mime . "\r\n";
1639
- $body2 .= "Content-Disposition: form-data; name=\"" . $name . "\"; filename=\"" . $filename . "\"\r\n";
1640
- $body2 .= "Content-Type: " . $type . "\r\n";
1641
- $body2 .= "\r\n";
1642
-
1643
- $info["filesize"] = (isset($info["datafile"]) ? self::RawFileSize($info["datafile"]) : strlen($info["data"]));
1644
- $bodysize += strlen($body2) + $info["filesize"] + 2;
1645
-
1646
- $options["files"][$num] = $info;
1647
- }
1648
-
1649
- $body2 = "--" . $mime . "--\r\n";
1650
- $bodysize += strlen($body2);
1651
- }
1652
- else
1653
- {
1654
- if (isset($options["postvars"]))
1655
- {
1656
- foreach ($options["postvars"] as $name => $val)
1657
- {
1658
- $name = self::HeaderValueCleanup($name);
1659
-
1660
- if (!is_array($val))
1661
- {
1662
- if (is_string($val) || is_numeric($val)) $val = array($val);
1663
- else return array("success" => false, "error" => "A supplied 'postvars' value is an invalid type. Expected string, numeric, or array.", "errorcode" => "invalid_postvars_value", "info" => array("name" => $name, "val" => $val));
1664
- }
1665
-
1666
- foreach ($val as $val2) $body .= ($body != "" ? "&" : "") . urlencode($name) . "=" . urlencode($val2);
1667
- }
1668
-
1669
- unset($options["postvars"]);
1670
- }
1671
-
1672
- if ($body != "") $data .= "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n";
1673
-
1674
- $bodysize = strlen($body);
1675
- }
1676
- if (($bodysize === false && strlen($body) > 0) || ($bodysize !== false && $bodysize < strlen($body))) $bodysize = strlen($body);
1677
-
1678
- // Finalize the headers.
1679
- if ($bodysize === false) $data .= "Transfer-Encoding: chunked\r\n";
1680
- else if ($bodysize > 0 || $body != "" || $options["method"] == "POST") $data .= "Content-Length: " . $bodysize . "\r\n";
1681
- $data .= "\r\n";
1682
- if (isset($options["debug_callback"]) && is_callable($options["debug_callback"])) call_user_func_array($options["debug_callback"], array("rawheaders", $data, &$options["debug_callback_opts"]));
1683
- $rawheadersize = strlen($data);
1684
-
1685
- // Finalize the initial data to be sent.
1686
- $data .= $body;
1687
- if ($bodysize !== false) $bodysize -= strlen($body);
1688
- $body = "";
1689
- $result = array("success" => true, "rawsendsize" => 0, "rawsendheadersize" => $rawheadersize, "rawrecvsize" => 0, "rawrecvheadersize" => 0, "startts" => $startts);
1690
- $debug = (isset($options["debug"]) && $options["debug"]);
1691
- if ($debug)
1692
- {
1693
- $result["rawsend"] = "";
1694
- $result["rawrecv"] = "";
1695
- }
1696
-
1697
- if ($timeout !== false && self::GetTimeLeft($startts, $timeout) == 0) return array("success" => false, "error" => self::HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded");
1698
-
1699
- // Connect to the target server.
1700
- $errornum = 0;
1701
- $errorstr = "";
1702
- if (isset($options["fp"]) && is_resource($options["fp"]))
1703
- {
1704
- $fp = $options["fp"];
1705
- unset($options["fp"]);
1706
-
1707
- $useproxy = false;
1708
- $proxyconnect = false;
1709
- $proxydata = "";
1710
- }
1711
- else if ($useproxy)
1712
- {
1713
- if (!isset($options["proxyconnecttimeout"])) $options["proxyconnecttimeout"] = 10;
1714
- $timeleft = self::GetTimeLeft($startts, $timeout);
1715
- if ($timeleft !== false) $options["proxyconnecttimeout"] = min($options["proxyconnecttimeout"], $timeleft);
1716
- if (!function_exists("stream_socket_client"))
1717
- {
1718
- if ($debug) $fp = fsockopen($proxyprotocol . "://" . $proxyhost, $proxyport, $errornum, $errorstr, $options["proxyconnecttimeout"]);
1719
- else $fp = @fsockopen($proxyprotocol . "://" . $proxyhost, $proxyport, $errornum, $errorstr, $options["proxyconnecttimeout"]);
1720
- }
1721
- else
1722
- {
1723
- $context = @stream_context_create();
1724
- if (isset($options["source_ip"])) $context["socket"] = array("bindto" => $options["source_ip"] . ":0");
1725
- if ($proxysecure)
1726
- {
1727
- if (!isset($options["proxysslopts"]) || !is_array($options["proxysslopts"])) $options["proxysslopts"] = self::GetSafeSSLOpts();
1728
- self::ProcessSSLOptions($options, "proxysslopts", $host);
1729
- foreach ($options["proxysslopts"] as $key => $val) @stream_context_set_option($context, "ssl", $key, $val);
1730
- }
1731
- else if ($secure)
1732
- {
1733
- if (!isset($options["sslopts"]) || !is_array($options["sslopts"])) $options["sslopts"] = self::GetSafeSSLOpts();
1734
- self::ProcessSSLOptions($options, "sslopts", $host);
1735
- foreach ($options["sslopts"] as $key => $val) @stream_context_set_option($context, "ssl", $key, $val);
1736
- }
1737
-
1738
- if ($debug) $fp = stream_socket_client($proxyprotocol . "://" . $proxyhost . ":" . $proxyport, $errornum, $errorstr, $options["proxyconnecttimeout"], ($async ? STREAM_CLIENT_ASYNC_CONNECT : STREAM_CLIENT_CONNECT), $context);
1739
- else $fp = @stream_socket_client($proxyprotocol . "://" . $proxyhost . ":" . $proxyport, $errornum, $errorstr, $options["proxyconnecttimeout"], ($async ? STREAM_CLIENT_ASYNC_CONNECT : STREAM_CLIENT_CONNECT), $context);
1740
- }
1741
-
1742
- if ($fp === false) return array("success" => false, "error" => self::HTTPTranslate("Unable to establish a connection to '%s'.", ($proxysecure ? $proxyprotocol . "://" : "") . $proxyhost . ":" . $proxyport), "info" => $errorstr . " (" . $errornum . ")", "errorcode" => "proxy_connect");
1743
- }
1744
- else
1745
- {
1746
- if (!isset($options["connecttimeout"])) $options["connecttimeout"] = 10;
1747
- $timeleft = self::GetTimeLeft($startts, $timeout);
1748
- if ($timeleft !== false) $options["connecttimeout"] = min($options["connecttimeout"], $timeleft);
1749
- if (!function_exists("stream_socket_client"))
1750
- {
1751
- if ($debug) $fp = fsockopen($protocol . "://" . $host, $port, $errornum, $errorstr, $options["connecttimeout"]);
1752
- else $fp = @fsockopen($protocol . "://" . $host, $port, $errornum, $errorstr, $options["connecttimeout"]);
1753
- }
1754
- else
1755
- {
1756
- $context = @stream_context_create();
1757
- if (isset($options["source_ip"])) $context["socket"] = array("bindto" => $options["source_ip"] . ":0");
1758
- if ($secure)
1759
- {
1760
- if (!isset($options["sslopts"]) || !is_array($options["sslopts"])) $options["sslopts"] = self::GetSafeSSLOpts();
1761
- self::ProcessSSLOptions($options, "sslopts", $host);
1762
- foreach ($options["sslopts"] as $key => $val) @stream_context_set_option($context, "ssl", $key, $val);
1763
- }
1764
-
1765
- if ($debug) $fp = stream_socket_client($protocol . "://" . $host . ":" . $port, $errornum, $errorstr, $options["connecttimeout"], ($async ? STREAM_CLIENT_ASYNC_CONNECT : STREAM_CLIENT_CONNECT), $context);
1766
- else $fp = @stream_socket_client($protocol . "://" . $host . ":" . $port, $errornum, $errorstr, $options["connecttimeout"], ($async ? STREAM_CLIENT_ASYNC_CONNECT : STREAM_CLIENT_CONNECT), $context);
1767
- }
1768
-
1769
- if ($fp === false) return array("success" => false, "error" => self::HTTPTranslate("Unable to establish a connection to '%s'.", ($secure ? $protocol . "://" : "") . $host . ":" . $port), "info" => $errorstr . " (" . $errornum . ")", "errorcode" => "connect_failed");
1770
- }
1771
-
1772
- if (function_exists("stream_set_blocking")) @stream_set_blocking($fp, ($async ? 0 : 1));
1773
-
1774
- // Initialize the connection request state array.
1775
- $state = array(
1776
- "fp" => $fp,
1777
- "type" => "request",
1778
- "async" => $async,
1779
- "debug" => $debug,
1780
- "startts" => $startts,
1781
- "timeout" => $timeout,
1782
- "waituntil" => -1.0,
1783
- "mime" => $mime,
1784
- "data" => $data,
1785
- "bodysize" => $bodysize,
1786
- "chunked" => ($bodysize === false),
1787
- "secure" => $secure,
1788
- "useproxy" => $useproxy,
1789
- "proxysecure" => $proxysecure,
1790
- "proxyconnect" => $proxyconnect,
1791
- "proxydata" => $proxydata,
1792
- "currentfile" => false,
1793
-
1794
- "state" => "connecting",
1795
-
1796
- "options" => $options,
1797
- "result" => $result,
1798
- "close" => ($options["headers"]["Connection"] === "close"),
1799
- "nextread" => "",
1800
- "client" => true
1801
- );
1802
-
1803
- // Return the state for async calls. Caller must call ProcessState().
1804
- if ($state["async"]) return array("success" => true, "state" => $state);
1805
-
1806
- // Run through all of the valid states and return the result.
1807
- return self::ProcessState($state);
1808
- }
1809
- }
1810
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/ultimate-web-scraper/multi_async_helper.php DELETED
@@ -1,302 +0,0 @@
1
- <?php
2
- // CubicleSoft PHP multiple asynchronous helper class.
3
- // (C) 2015 CubicleSoft. All Rights Reserved.
4
-
5
- class MultiAsyncHelper
6
- {
7
- private $objs, $queuedobjs, $limit;
8
-
9
- public function __construct()
10
- {
11
- $this->objs = array();
12
- $this->queuedobjs = array();
13
- $this->limit = false;
14
- }
15
-
16
- public function SetConcurrencyLimit($limit)
17
- {
18
- $this->limit = $limit;
19
- }
20
-
21
- public function Set($key, $obj, $callback)
22
- {
23
- if (is_callable($callback))
24
- {
25
- $this->queuedobjs[$key] = array(
26
- "obj" => $obj,
27
- "callback" => $callback
28
- );
29
-
30
- unset($this->objs[$key]);
31
- }
32
- }
33
-
34
- public function NumObjects()
35
- {
36
- return count($this->queuedobjs) + count($this->objs);
37
- }
38
-
39
- public function GetObject($key)
40
- {
41
- if (isset($this->queuedobjs[$key])) $result = $this->queuedobjs[$key]["obj"];
42
- else if (isset($this->objs[$key])) $result = $this->objs[$key]["obj"];
43
- else $result = false;
44
-
45
- return $result;
46
- }
47
-
48
- // To be able to change a callback on the fly.
49
- public function SetCallback($key, $callback)
50
- {
51
- if (is_callable($callback))
52
- {
53
- if (isset($this->queuedobjs[$key])) $this->queuedobjs[$key]["callback"] = $callback;
54
- else if (isset($this->objs[$key])) $this->objs[$key]["callback"] = $callback;
55
- }
56
- }
57
-
58
- private function InternalDetach($key, $cleanup)
59
- {
60
- if (isset($this->queuedobjs[$key]))
61
- {
62
- call_user_func_array($this->queuedobjs[$key]["callback"], array("cleanup", &$cleanup, $key, &$this->queuedobjs[$key]["obj"]));
63
- $result = $this->queuedobjs[$key]["obj"];
64
- unset($this->queuedobjs[$key]);
65
- }
66
- else if (isset($this->objs[$key]))
67
- {
68
- call_user_func_array($this->objs[$key]["callback"], array("cleanup", &$cleanup, $key, &$this->objs[$key]["obj"]));
69
- $result = $this->objs[$key]["obj"];
70
- unset($this->objs[$key]);
71
- }
72
- else
73
- {
74
- $result = false;
75
- }
76
-
77
- return $result;
78
- }
79
-
80
- public function Detach($key)
81
- {
82
- return $this->InternalDetach($key, false);
83
- }
84
-
85
- public function Remove($key)
86
- {
87
- return $this->InternalDetach($key, true);
88
- }
89
-
90
- // A few default functions for direct file/socket handles.
91
- public static function ReadOnly($mode, &$data, $key, $fp)
92
- {
93
- switch ($mode)
94
- {
95
- case "init":
96
- case "update":
97
- {
98
- // Move to/Keep in the live queue.
99
- if (is_resource($fp)) $data = true;
100
-
101
- break;
102
- }
103
- case "read":
104
- case "write":
105
- case "writefps":
106
- {
107
- break;
108
- }
109
- case "readfps":
110
- {
111
- $data[$key] = $fp;
112
-
113
- break;
114
- }
115
- case "cleanup":
116
- {
117
- if ($data === true) @fclose($fp);
118
-
119
- break;
120
- }
121
- }
122
- }
123
-
124
- public static function WriteOnly($mode, &$data, $key, $fp)
125
- {
126
- switch ($mode)
127
- {
128
- case "init":
129
- case "update":
130
- {
131
- // Move to/Keep in the live queue.
132
- if (is_resource($fp)) $data = true;
133
-
134
- break;
135
- }
136
- case "read":
137
- case "readfps":
138
- case "write":
139
- {
140
- break;
141
- }
142
- case "writefps":
143
- {
144
- $data[$key] = $fp;
145
-
146
- break;
147
- }
148
- case "cleanup":
149
- {
150
- if ($data === true) @fclose($fp);
151
-
152
- break;
153
- }
154
- }
155
- }
156
-
157
- public static function ReadAndWrite($mode, &$data, $key, $fp)
158
- {
159
- switch ($mode)
160
- {
161
- case "init":
162
- case "update":
163
- {
164
- // Move to/Keep in the live queue.
165
- if (is_resource($fp)) $data = true;
166
-
167
- break;
168
- }
169
- case "read":
170
- case "write":
171
- {
172
- break;
173
- }
174
- case "readfps":
175
- case "writefps":
176
- {
177
- $data[$key] = $fp;
178
-
179
- break;
180
- }
181
- case "cleanup":
182
- {
183
- if ($data === true) @fclose($fp);
184
-
185
- break;
186
- }
187
- }
188
- }
189
-
190
- public function Wait($timeout = false)
191
- {
192
- // Move queued objects to live.
193
- $result2 = array("success" => true, "read" => array(), "write" => array(), "removed" => array(), "new" => array());
194
- while (count($this->queuedobjs) && ($this->limit === false || count($this->objs) < $this->limit))
195
- {
196
- $info = reset($this->queuedobjs);
197
- $key = key($this->queuedobjs);
198
- unset($this->queuedobjs[$key]);
199
-
200
- $result2["new"][$key] = $key;
201
-
202
- $keep = false;
203
- call_user_func_array($info["callback"], array("init", &$keep, $key, &$info["obj"]));
204
-
205
- $this->objs[$key] = $info;
206
-
207
- if (!$keep) $result2["removed"][$key] = $this->Remove($key);
208
- }
209
-
210
- // Walk the objects looking for read and write handles.
211
- $readfps = array();
212
- $writefps = array();
213
- $exceptfps = NULL;
214
- foreach ($this->objs as $key => &$info)
215
- {
216
- $keep = false;
217
- call_user_func_array($info["callback"], array("update", &$keep, $key, &$info["obj"]));
218
-
219
- if (!$keep) $result2["removed"][$key] = $this->Remove($key);
220
- else
221
- {
222
- call_user_func_array($info["callback"], array("readfps", &$readfps, $key, &$info["obj"]));
223
- call_user_func_array($info["callback"], array("writefps", &$writefps, $key, &$info["obj"]));
224
- }
225
- }
226
- if (!count($readfps)) $readfps = NULL;
227
- if (!count($writefps)) $writefps = NULL;
228
-
229
- // Wait for something to happen.
230
- if (isset($readfps) || isset($writefps))
231
- {
232
- if ($timeout === false) $timeout = NULL;
233
- $readfps2 = $readfps;
234
- $writefps2 = $writefps;
235
- $result = @stream_select($readfps, $writefps, $exceptfps, $timeout);
236
- if ($result === false) return array("success" => false, "error" => self::MAHTranslate("Wait() failed due to stream_select() failure. Most likely cause: Connection failure."), "errorcode" => "stream_select_failed");
237
- else if ($result > 0)
238
- {
239
- if (isset($readfps))
240
- {
241
- $readfps3 = array();
242
- foreach ($readfps as $key => $fp)
243
- {
244
- if (!isset($readfps2[$key]) || $readfps2[$key] !== $fp)
245
- {
246
- foreach ($readfps2 as $key2 => $fp2)
247
- {
248
- if ($fp === $fp2) $key = $key2;
249
- }
250
- }
251
-
252
- if (isset($this->objs[$key]))
253
- {
254
- call_user_func_array($this->objs[$key]["callback"], array("read", &$fp, $key, &$this->objs[$key]["obj"]));
255
-
256
- $readfps3[$key] = $fp;
257
- }
258
- }
259
-
260
- $result2["read"] = $readfps3;
261
- }
262
-
263
- if (isset($writefps))
264
- {
265
- $writefps3 = array();
266
- foreach ($writefps as $key => $fp)
267
- {
268
- if (!isset($writefps2[$key]) || $writefps2[$key] !== $fp)
269
- {
270
- foreach ($writefps2 as $key2 => $fp2)
271
- {
272
- if ($fp === $fp2) $key = $key2;
273
- }
274
- }
275
-
276
- if (isset($this->objs[$key]))
277
- {
278
- call_user_func_array($this->objs[$key]["callback"], array("write", &$fp, $key, &$this->objs[$key]["obj"]));
279
-
280
- $readfps3[$key] = $fp;
281
- }
282
- }
283
-
284
- $result2["write"] = $writefps3;
285
- }
286
- }
287
- }
288
-
289
- $result2["numleft"] = count($this->queuedobjs) + count($this->objs);
290
-
291
- return $result2;
292
- }
293
-
294
- public static function MAHTranslate()
295
- {
296
- $args = func_get_args();
297
- if (!count($args)) return "";
298
-
299
- return call_user_func_array((defined("CS_TRANSLATE_FUNC") && function_exists(CS_TRANSLATE_FUNC) ? CS_TRANSLATE_FUNC : "sprintf"), $args);
300
- }
301
- }
302
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/ultimate-web-scraper/simple_html_dom.php DELETED
@@ -1,975 +0,0 @@
1
- <?php
2
- /*******************************************************************************
3
- Version: 1.11 ($Rev: 175 $)
4
- Website: http://sourceforge.net/projects/simplehtmldom/
5
- Author: S.C. Chen <me578022@gmail.com>
6
- Acknowledge: Jose Solorzano (https://sourceforge.net/projects/php-html/)
7
- Contributions by:
8
- Yousuke Kumakura (Attribute filters)
9
- Vadim Voituk (Negative indexes supports of "find" method)
10
- Antcs (Constructor with automatically load contents either text or file/url)
11
- Licensed under The MIT License
12
- Redistributions of files must retain the above copyright notice.
13
- *******************************************************************************/
14
-
15
- define('HDOM_TYPE_ELEMENT', 1);
16
- define('HDOM_TYPE_COMMENT', 2);
17
- define('HDOM_TYPE_TEXT', 3);
18
- define('HDOM_TYPE_ENDTAG', 4);
19
- define('HDOM_TYPE_ROOT', 5);
20
- define('HDOM_TYPE_UNKNOWN', 6);
21
- define('HDOM_QUOTE_DOUBLE', 0);
22
- define('HDOM_QUOTE_SINGLE', 1);
23
- define('HDOM_QUOTE_NO', 3);
24
- define('HDOM_INFO_BEGIN', 0);
25
- define('HDOM_INFO_END', 1);
26
- define('HDOM_INFO_QUOTE', 2);
27
- define('HDOM_INFO_SPACE', 3);
28
- define('HDOM_INFO_TEXT', 4);
29
- define('HDOM_INFO_INNER', 5);
30
- define('HDOM_INFO_OUTER', 6);
31
- define('HDOM_INFO_ENDSPACE',7);
32
-
33
- // helper functions
34
- // -----------------------------------------------------------------------------
35
- // get html dom form file
36
- function file_get_html() {
37
- $dom = new simple_html_dom;
38
- $args = func_get_args();
39
- $dom->load(call_user_func_array('file_get_contents', $args), true);
40
- return $dom;
41
- }
42
-
43
- // get html dom form string
44
- function str_get_html($str, $lowercase=true) {
45
- $dom = new simple_html_dom;
46
- $dom->load($str, $lowercase);
47
- return $dom;
48
- }
49
-
50
- // dump html dom tree
51
- function dump_html_tree($node, $show_attr=true, $deep=0) {
52
- $lead = str_repeat(' ', $deep);
53
- echo $lead.$node->tag;
54
- if ($show_attr && count($node->attr)>0) {
55
- echo '(';
56
- foreach($node->attr as $k=>$v)
57
- echo "[$k]=>\"".$node->$k.'", ';
58
- echo ')';
59
- }
60
- echo "\n";
61
-
62
- foreach($node->nodes as $c)
63
- dump_html_tree($c, $show_attr, $deep+1);
64
- }
65
-
66
- // get dom form file (deprecated)
67
- function file_get_dom() {
68
- $dom = new simple_html_dom;
69
- $args = func_get_args();
70
- $dom->load(call_user_func_array('file_get_contents', $args), true);
71
- return $dom;
72
- }
73
-
74
- // get dom form string (deprecated)
75
- function str_get_dom($str, $lowercase=true) {
76
- $dom = new simple_html_dom;
77
- $dom->load($str, $lowercase);
78
- return $dom;
79
- }
80
-
81
- // simple html dom node
82
- // -----------------------------------------------------------------------------
83
- class simple_html_dom_node {
84
- public $nodetype = HDOM_TYPE_TEXT;
85
- public $tag = 'text';
86
- public $attr = array();
87
- public $children = array();
88
- public $nodes = array();
89
- public $parent = null;
90
- public $_ = array();
91
- private $dom = null;
92
-
93
- function __construct($dom) {
94
- $this->dom = $dom;
95
- $dom->nodes[] = $this;
96
- }
97
-
98
- function __destruct() {
99
- $this->clear();
100
- }
101
-
102
- function __toString() {
103
- return $this->outertext();
104
- }
105
-
106
- // clean up memory due to php5 circular references memory leak...
107
- function clear() {
108
- $this->dom = null;
109
- $this->nodes = null;
110
- $this->parent = null;
111
- $this->children = null;
112
- }
113
-
114
- // dump node's tree
115
- function dump($show_attr=true) {
116
- dump_html_tree($this, $show_attr);
117
- }
118
-
119
- // returns the parent of node
120
- function parent() {
121
- return $this->parent;
122
- }
123
-
124
- // returns children of node
125
- function children($idx=-1) {
126
- if ($idx===-1) return $this->children;
127
- if (isset($this->children[$idx])) return $this->children[$idx];
128
- return null;
129
- }
130
-
131
- // returns the first child of node
132
- function first_child() {
133
- if (count($this->children)>0) return $this->children[0];
134
- return null;
135
- }
136
-
137
- // returns the last child of node
138
- function last_child() {
139
- if (($count=count($this->children))>0) return $this->children[$count-1];
140
- return null;
141
- }
142
-
143
- // returns the next sibling of node
144
- function next_sibling() {
145
- if ($this->parent===null) return null;
146
- $idx = 0;
147
- $count = count($this->parent->children);
148
- while ($idx<$count && $this!==$this->parent->children[$idx])
149
- ++$idx;
150
- if (++$idx>=$count) return null;
151
- return $this->parent->children[$idx];
152
- }
153
-
154
- // returns the previous sibling of node
155
- function prev_sibling() {
156
- if ($this->parent===null) return null;
157
- $idx = 0;
158
- $count = count($this->parent->children);
159
- while ($idx<$count && $this!==$this->parent->children[$idx])
160
- ++$idx;
161
- if (--$idx<0) return null;
162
- return $this->parent->children[$idx];
163
- }
164
-
165
- // get dom node's inner html
166
- function innertext() {
167
- if (isset($this->_[HDOM_INFO_INNER])) return $this->_[HDOM_INFO_INNER];
168
- if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
169
-
170
- $ret = '';
171
- foreach($this->nodes as $n)
172
- $ret .= $n->outertext();
173
- return $ret;
174
- }
175
-
176
- // get dom node's outer text (with tag)
177
- function outertext() {
178
- if ($this->tag==='root') return $this->innertext();
179
-
180
- // trigger callback
181
- if ($this->dom->callback!==null)
182
- call_user_func_array($this->dom->callback, array($this));
183
-
184
- if (isset($this->_[HDOM_INFO_OUTER])) return $this->_[HDOM_INFO_OUTER];
185
- if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
186
-
187
- // render begin tag
188
- $ret = $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]->makeup();
189
-
190
- // render inner text
191
- if (isset($this->_[HDOM_INFO_INNER]))
192
- $ret .= $this->_[HDOM_INFO_INNER];
193
- else {
194
- foreach($this->nodes as $n)
195
- $ret .= $n->outertext();
196
- }
197
-
198
- // render end tag
199
- if(isset($this->_[HDOM_INFO_END]) && $this->_[HDOM_INFO_END]!=0)
200
- $ret .= '</'.$this->tag.'>';
201
- return $ret;
202
- }
203
-
204
- // get dom node's plain text
205
- function text() {
206
- if (isset($this->_[HDOM_INFO_INNER])) return $this->_[HDOM_INFO_INNER];
207
- switch ($this->nodetype) {
208
- case HDOM_TYPE_TEXT: return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
209
- case HDOM_TYPE_COMMENT: return '';
210
- case HDOM_TYPE_UNKNOWN: return '';
211
- }
212
- if (strcasecmp($this->tag, 'script')===0) return '';
213
- if (strcasecmp($this->tag, 'style')===0) return '';
214
-
215
- $ret = '';
216
- foreach($this->nodes as $n)
217
- $ret .= $n->text();
218
- return $ret;
219
- }
220
-
221
- function xmltext() {
222
- $ret = $this->innertext();
223
- $ret = str_ireplace('<![CDATA[', '', $ret);
224
- $ret = str_replace(']]>', '', $ret);
225
- return $ret;
226
- }
227
-
228
- // build node's text with tag
229
- function makeup() {
230
- // text, comment, unknown
231
- if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
232
-
233
- $ret = '<'.$this->tag;
234
- $i = -1;
235
-
236
- foreach($this->attr as $key=>$val) {
237
- ++$i;
238
-
239
- // skip removed attribute
240
- if ($val===null || $val===false)
241
- continue;
242
-
243
- $ret .= $this->_[HDOM_INFO_SPACE][$i][0];
244
- //no value attr: nowrap, checked selected...
245
- if ($val===true)
246
- $ret .= $key;
247
- else {
248
- switch($this->_[HDOM_INFO_QUOTE][$i]) {
249
- case HDOM_QUOTE_DOUBLE: $quote = '"'; break;
250
- case HDOM_QUOTE_SINGLE: $quote = '\''; break;
251
- default: $quote = '';
252
- }
253
- $ret .= $key.$this->_[HDOM_INFO_SPACE][$i][1].'='.$this->_[HDOM_INFO_SPACE][$i][2].$quote.$val.$quote;
254
- }
255
- }
256
- $ret = $this->dom->restore_noise($ret);
257
- return $ret . $this->_[HDOM_INFO_ENDSPACE] . '>';
258
- }
259
-
260
- // find elements by css selector
261
- function find($selector, $idx=null) {
262
- $selectors = $this->parse_selector($selector);
263
- if (($count=count($selectors))===0) return array();
264
- $found_keys = array();
265
-
266
- // find each selector
267
- for ($c=0; $c<$count; ++$c) {
268
- if (($levle=count($selectors[0]))===0) return array();
269
- if (!isset($this->_[HDOM_INFO_BEGIN])) return array();
270
-
271
- $head = array($this->_[HDOM_INFO_BEGIN]=>1);
272
-
273
- // handle descendant selectors, no recursive!
274
- for ($l=0; $l<$levle; ++$l) {
275
- $ret = array();
276
- foreach($head as $k=>$v) {
277
- $n = ($k===-1) ? $this->dom->root : $this->dom->nodes[$k];
278
- $n->seek($selectors[$c][$l], $ret);
279
- }
280
- $head = $ret;
281
- }
282
-
283
- foreach($head as $k=>$v) {
284
- if (!isset($found_keys[$k]))
285
- $found_keys[$k] = 1;
286
- }
287
- }
288
-
289
- // sort keys
290
- ksort($found_keys);
291
-
292
- $found = array();
293
- foreach($found_keys as $k=>$v)
294
- $found[] = $this->dom->nodes[$k];
295
-
296
- // return nth-element or array
297
- if (is_null($idx)) return $found;
298
- else if ($idx<0) $idx = count($found) + $idx;
299
- return (isset($found[$idx])) ? $found[$idx] : null;
300
- }
301
-
302
- // seek for given conditions
303
- protected function seek($selector, &$ret) {
304
- list($tag, $key, $val, $exp, $no_key) = $selector;
305
-
306
- // xpath index
307
- if ($tag && $key && is_numeric($key)) {
308
- $count = 0;
309
- foreach ($this->children as $c) {
310
- if ($tag==='*' || $tag===$c->tag) {
311
- if (++$count==$key) {
312
- $ret[$c->_[HDOM_INFO_BEGIN]] = 1;
313
- return;
314
- }
315
- }
316
- }
317
- return;
318
- }
319
-
320
- $end = (!empty($this->_[HDOM_INFO_END])) ? $this->_[HDOM_INFO_END] : 0;
321
- if ($end==0) {
322
- $parent = $this->parent;
323
- while (!isset($parent->_[HDOM_INFO_END]) && $parent!==null) {
324
- $end -= 1;
325
- $parent = $parent->parent;
326
- }
327
- $end += $parent->_[HDOM_INFO_END];
328
- }
329
-
330
- for($i=$this->_[HDOM_INFO_BEGIN]+1; $i<$end; ++$i) {
331
- $node = $this->dom->nodes[$i];
332
- $pass = true;
333
-
334
- if ($tag==='*' && !$key) {
335
- if (in_array($node, $this->children, true))
336
- $ret[$i] = 1;
337
- continue;
338
- }
339
-
340
- // compare tag
341
- if ($tag && $tag!=$node->tag && $tag!=='*') {$pass=false;}
342
- // compare key
343
- if ($pass && $key) {
344
- if ($no_key) {
345
- if (isset($node->attr[$key])) $pass=false;
346
- }
347
- else if (!isset($node->attr[$key])) $pass=false;
348
- }
349
- // compare value
350
- if ($pass && $key && $val && $val!=='*') {
351
- $check = $this->match($exp, $val, $node->attr[$key]);
352
- // handle multiple class
353
- if (!$check && strcasecmp($key, 'class')===0) {
354
- foreach(explode(' ',$node->attr[$key]) as $k) {
355
- $check = $this->match($exp, $val, $k);
356
- if ($check) break;
357
- }
358
- }
359
- if (!$check) $pass = false;
360
- }
361
- if ($pass) $ret[$i] = 1;
362
- unset($node);
363
- }
364
- }
365
-
366
- protected function match($exp, $pattern, $value) {
367
- switch ($exp) {
368
- case '=':
369
- return ($value===$pattern);
370
- case '!=':
371
- return ($value!==$pattern);
372
- case '^=':
373
- return preg_match("/^".preg_quote($pattern,'/')."/", $value);
374
- case '$=':
375
- return preg_match("/".preg_quote($pattern,'/')."$/", $value);
376
- case '*=':
377
- if ($pattern[0]=='/')
378
- return preg_match($pattern, $value);
379
- return preg_match("/".$pattern."/i", $value);
380
- }
381
- return false;
382
- }
383
-
384
- protected function parse_selector($selector_string) {
385
- // pattern of CSS selectors, modified from mootools
386
- $pattern = "/([\w\-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is";
387
- preg_match_all($pattern, trim($selector_string).' ', $matches, PREG_SET_ORDER);
388
- $selectors = array();
389
- $result = array();
390
- //print_r($matches);
391
-
392
- foreach ($matches as $m) {
393
- $m[0] = trim($m[0]);
394
- if ($m[0]==='' || $m[0]==='/' || $m[0]==='//') continue;
395
- // for borwser grnreated xpath
396
- if ($m[1]==='tbody') continue;
397
-
398
- list($tag, $key, $val, $exp, $no_key) = array($m[1], null, null, '=', false);
399
- if(!empty($m[2])) {$key='id'; $val=$m[2];}
400
- if(!empty($m[3])) {$key='class'; $val=$m[3];}
401
- if(!empty($m[4])) {$key=$m[4];}
402
- if(!empty($m[5])) {$exp=$m[5];}
403
- if(!empty($m[6])) {$val=$m[6];}
404
-
405
- // convert to lowercase
406
- if ($this->dom->lowercase) {$tag=strtolower($tag); $key=strtolower($key);}
407
- //elements that do NOT have the specified attribute
408
- if (isset($key[0]) && $key[0]==='!') {$key=substr($key, 1); $no_key=true;}
409
-
410
- $result[] = array($tag, $key, $val, $exp, $no_key);
411
- if (trim($m[7])===',') {
412
- $selectors[] = $result;
413
- $result = array();
414
- }
415
- }
416
- if (count($result)>0)
417
- $selectors[] = $result;
418
- return $selectors;
419
- }
420
-
421
- function __get($name) {
422
- if (isset($this->attr[$name])) return $this->attr[$name];
423
- switch($name) {
424
- case 'outertext': return $this->outertext();
425
- case 'innertext': return $this->innertext();
426
- case 'plaintext': return $this->text();
427
- case 'xmltext': return $this->xmltext();
428
- default: return array_key_exists($name, $this->attr);
429
- }
430
- }
431
-
432
- function __set($name, $value) {
433
- switch($name) {
434
- case 'outertext': return $this->_[HDOM_INFO_OUTER] = $value;
435
- case 'innertext':
436
- if (isset($this->_[HDOM_INFO_TEXT])) return $this->_[HDOM_INFO_TEXT] = $value;
437
- return $this->_[HDOM_INFO_INNER] = $value;
438
- }
439
- if (!isset($this->attr[$name])) {
440
- $this->_[HDOM_INFO_SPACE][] = array(' ', '', '');
441
- $this->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE;
442
- }
443
- $this->attr[$name] = $value;
444
- }
445
-
446
- function __isset($name) {
447
- switch($name) {
448
- case 'outertext': return true;
449
- case 'innertext': return true;
450
- case 'plaintext': return true;
451
- }
452
- //no value attr: nowrap, checked selected...
453
- return (array_key_exists($name, $this->attr)) ? true : isset($this->attr[$name]);
454
- }
455
-
456
- function __unset($name) {
457
- if (isset($this->attr[$name]))
458
- unset($this->attr[$name]);
459
- }
460
-
461
- // camel naming conventions
462
- function getAllAttributes() {return $this->attr;}
463
- function getAttribute($name) {return $this->__get($name);}
464
- function setAttribute($name, $value) {$this->__set($name, $value);}
465
- function hasAttribute($name) {return $this->__isset($name);}
466
- function removeAttribute($name) {$this->__set($name, null);}
467
- function getElementById($id) {return $this->find("#$id", 0);}
468
- function getElementsById($id, $idx=null) {return $this->find("#$id", $idx);}
469
- function getElementByTagName($name) {return $this->find($name, 0);}
470
- function getElementsByTagName($name, $idx=null) {return $this->find($name, $idx);}
471
- function parentNode() {return $this->parent();}
472
- function childNodes($idx=-1) {return $this->children($idx);}
473
- function firstChild() {return $this->first_child();}
474
- function lastChild() {return $this->last_child();}
475
- function nextSibling() {return $this->next_sibling();}
476
- function previousSibling() {return $this->prev_sibling();}
477
- }
478
-
479
- // simple html dom parser
480
- // -----------------------------------------------------------------------------
481
- class simple_html_dom {
482
- public $root = null;
483
- public $nodes = array();
484
- public $callback = null;
485
- public $lowercase = false;
486
- protected $pos;
487
- protected $doc;
488
- protected $char;
489
- protected $size;
490
- protected $cursor;
491
- protected $parent;
492
- protected $noise = array();
493
- protected $token_blank = " \t\r\n";
494
- protected $token_equal = ' =/>';
495
- protected $token_slash = " />\r\n\t";
496
- protected $token_attr = ' >';
497
- // use isset instead of in_array, performance boost about 30%...
498
- protected $self_closing_tags = array('img'=>1, 'br'=>1, 'input'=>1, 'meta'=>1, 'link'=>1, 'hr'=>1, 'base'=>1, 'embed'=>1, 'spacer'=>1);
499
- protected $block_tags = array('root'=>1, 'body'=>1, 'form'=>1, 'div'=>1, 'span'=>1, 'table'=>1);
500
- protected $optional_closing_tags = array(
501
- 'tr'=>array('tr'=>1, 'td'=>1, 'th'=>1),
502
- 'th'=>array('th'=>1),
503
- 'td'=>array('td'=>1),
504
- 'li'=>array('li'=>1),
505
- 'dt'=>array('dt'=>1, 'dd'=>1),
506
- 'dd'=>array('dd'=>1, 'dt'=>1),
507
- 'dl'=>array('dd'=>1, 'dt'=>1),
508
- 'p'=>array('p'=>1),
509
- 'nobr'=>array('nobr'=>1),
510
- );
511
-
512
- function __construct($str=null) {
513
- if ($str) {
514
- if (preg_match("/^http:\/\//i",$str) || is_file($str))
515
- $this->load_file($str);
516
- else
517
- $this->load($str);
518
- }
519
- }
520
-
521
- function __destruct() {
522
- $this->clear();
523
- }
524
-
525
- // load html from string
526
- function load($str, $lowercase=true) {
527
- // prepare
528
- $this->prepare($str, $lowercase);
529
- // strip out comments
530
- $this->remove_noise("'<!--(.*?)-->'is");
531
- // strip out cdata
532
- $this->remove_noise("'<!\[CDATA\[(.*?)\]\]>'is", true);
533
- // strip out <style> tags
534
- $this->remove_noise("'<\s*style[^>]*[^/]>(.*?)<\s*/\s*style\s*>'is");
535
- $this->remove_noise("'<\s*style\s*>(.*?)<\s*/\s*style\s*>'is");
536
- // strip out <script> tags
537
- $this->remove_noise("'<\s*script[^>]*[^/]>(.*?)<\s*/\s*script\s*>'is");
538
- $this->remove_noise("'<\s*script\s*>(.*?)<\s*/\s*script\s*>'is");
539
- // strip out preformatted tags
540
- $this->remove_noise("'<\s*(?:code)[^>]*>(.*?)<\s*/\s*(?:code)\s*>'is");
541
- // strip out server side scripts
542
- $this->remove_noise("'(<\?)(.*?)(\?>)'s", true);
543
- // strip smarty scripts
544
- $this->remove_noise("'(\{\w)(.*?)(\})'s", true);
545
-
546
- // parsing
547
- while ($this->parse());
548
- // end
549
- $this->root->_[HDOM_INFO_END] = $this->cursor;
550
- }
551
-
552
- // load html from file
553
- function load_file() {
554
- $args = func_get_args();
555
- $this->load(call_user_func_array('file_get_contents', $args), true);
556
- }
557
-
558
- // set callback function
559
- function set_callback($function_name) {
560
- $this->callback = $function_name;
561
- }
562
-
563
- // remove callback function
564
- function remove_callback() {
565
- $this->callback = null;
566
- }
567
-
568
- // save dom as string
569
- function save($filepath='') {
570
- $ret = $this->root->innertext();
571
- if ($filepath!=='') file_put_contents($filepath, $ret);
572
- return $ret;
573
- }
574
-
575
- // find dom node by css selector
576
- function find($selector, $idx=null) {
577
- return $this->root->find($selector, $idx);
578
- }
579
-
580
- // clean up memory due to php5 circular references memory leak...
581
- function clear() {
582
- foreach($this->nodes as $n) {$n->clear(); $n = null;}
583
- if (isset($this->parent)) {$this->parent->clear(); unset($this->parent);}
584
- if (isset($this->root)) {$this->root->clear(); unset($this->root);}
585
- unset($this->doc);
586
- unset($this->noise);
587
- }
588
-
589
- function dump($show_attr=true) {
590
- $this->root->dump($show_attr);
591
- }
592
-
593
- // prepare HTML data and init everything
594
- protected function prepare($str, $lowercase=true) {
595
- $this->clear();
596
- $this->doc = $str;
597
- $this->pos = 0;
598
- $this->cursor = 1;
599
- $this->noise = array();
600
- $this->nodes = array();
601
- $this->lowercase = $lowercase;
602
- $this->root = new simple_html_dom_node($this);
603
- $this->root->tag = 'root';
604
- $this->root->_[HDOM_INFO_BEGIN] = -1;
605
- $this->root->nodetype = HDOM_TYPE_ROOT;
606
- $this->parent = $this->root;
607
- // set the length of content
608
- $this->size = strlen($str);
609
- if ($this->size>0) $this->char = $this->doc[0];
610
- }
611
-
612
- // parse html content
613
- protected function parse() {
614
- if (($s = $this->copy_until_char('<'))==='')
615
- return $this->read_tag();
616
-
617
- // text
618
- $node = new simple_html_dom_node($this);
619
- ++$this->cursor;
620
- $node->_[HDOM_INFO_TEXT] = $s;
621
- $this->link_nodes($node, false);
622
- return true;
623
- }
624
-
625
- // read tag info
626
- protected function read_tag() {
627
- if ($this->char!=='<') {
628
- $this->root->_[HDOM_INFO_END] = $this->cursor;
629
- return false;
630
- }
631
- $begin_tag_pos = $this->pos;
632
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
633
-
634
- // end tag
635
- if ($this->char==='/') {
636
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
637
- $this->skip($this->token_blank_t);
638
- $tag = $this->copy_until_char('>');
639
-
640
- // skip attributes in end tag
641
- if (($pos = strpos($tag, ' '))!==false)
642
- $tag = substr($tag, 0, $pos);
643
-
644
- $parent_lower = strtolower($this->parent->tag);
645
- $tag_lower = strtolower($tag);
646
-
647
- if ($parent_lower!==$tag_lower) {
648
- if (isset($this->optional_closing_tags[$parent_lower]) && isset($this->block_tags[$tag_lower])) {
649
- $this->parent->_[HDOM_INFO_END] = 0;
650
- $org_parent = $this->parent;
651
-
652
- while (($this->parent->parent) && strtolower($this->parent->tag)!==$tag_lower)
653
- $this->parent = $this->parent->parent;
654
-
655
- if (strtolower($this->parent->tag)!==$tag_lower) {
656
- $this->parent = $org_parent; // restore origonal parent
657
- if ($this->parent->parent) $this->parent = $this->parent->parent;
658
- $this->parent->_[HDOM_INFO_END] = $this->cursor;
659
- return $this->as_text_node($tag);
660
- }
661
- }
662
- else if (($this->parent->parent) && isset($this->block_tags[$tag_lower])) {
663
- $this->parent->_[HDOM_INFO_END] = 0;
664
- $org_parent = $this->parent;
665
-
666
- while (($this->parent->parent) && strtolower($this->parent->tag)!==$tag_lower)
667
- $this->parent = $this->parent->parent;
668
-
669
- if (strtolower($this->parent->tag)!==$tag_lower) {
670
- $this->parent = $org_parent; // restore origonal parent
671
- $this->parent->_[HDOM_INFO_END] = $this->cursor;
672
- return $this->as_text_node($tag);
673
- }
674
- }
675
- else if (($this->parent->parent) && strtolower($this->parent->parent->tag)===$tag_lower) {
676
- $this->parent->_[HDOM_INFO_END] = 0;
677
- $this->parent = $this->parent->parent;
678
- }
679
- else
680
- return $this->as_text_node($tag);
681
- }
682
-
683
- $this->parent->_[HDOM_INFO_END] = $this->cursor;
684
- if ($this->parent->parent) $this->parent = $this->parent->parent;
685
-
686
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
687
- return true;
688
- }
689
-
690
- $node = new simple_html_dom_node($this);
691
- $node->_[HDOM_INFO_BEGIN] = $this->cursor;
692
- ++$this->cursor;
693
- $tag = $this->copy_until($this->token_slash);
694
-
695
- // doctype, cdata & comments...
696
- if (isset($tag[0]) && $tag[0]==='!') {
697
- $node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until_char('>');
698
-
699
- if (isset($tag[2]) && $tag[1]==='-' && $tag[2]==='-') {
700
- $node->nodetype = HDOM_TYPE_COMMENT;
701
- $node->tag = 'comment';
702
- } else {
703
- $node->nodetype = HDOM_TYPE_UNKNOWN;
704
- $node->tag = 'unknown';
705
- }
706
-
707
- if ($this->char==='>') $node->_[HDOM_INFO_TEXT].='>';
708
- $this->link_nodes($node, true);
709
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
710
- return true;
711
- }
712
-
713
- // text
714
- if ($pos=strpos($tag, '<')!==false) {
715
- $tag = '<' . substr($tag, 0, -1);
716
- $node->_[HDOM_INFO_TEXT] = $tag;
717
- $this->link_nodes($node, false);
718
- $this->char = $this->doc[--$this->pos]; // prev
719
- return true;
720
- }
721
-
722
- if (!preg_match("/^[\w\-:]+$/", $tag)) {
723
- $node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until('<>');
724
- if ($this->char==='<') {
725
- $this->link_nodes($node, false);
726
- return true;
727
- }
728
-
729
- if ($this->char==='>') $node->_[HDOM_INFO_TEXT].='>';
730
- $this->link_nodes($node, false);
731
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
732
- return true;
733
- }
734
-
735
- // begin tag
736
- $node->nodetype = HDOM_TYPE_ELEMENT;
737
- $tag_lower = strtolower($tag);
738
- $node->tag = ($this->lowercase) ? $tag_lower : $tag;
739
-
740
- // handle optional closing tags
741
- if (isset($this->optional_closing_tags[$tag_lower]) ) {
742
- while (isset($this->optional_closing_tags[$tag_lower][strtolower($this->parent->tag)])) {
743
- $this->parent->_[HDOM_INFO_END] = 0;
744
- $this->parent = $this->parent->parent;
745
- }
746
- $node->parent = $this->parent;
747
- }
748
-
749
- $guard = 0; // prevent infinity loop
750
- $space = array($this->copy_skip($this->token_blank), '', '');
751
-
752
- // attributes
753
- do {
754
- if ($this->char!==null && $space[0]==='') break;
755
- $name = $this->copy_until($this->token_equal);
756
- if($guard===$this->pos) {
757
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
758
- continue;
759
- }
760
- $guard = $this->pos;
761
-
762
- // handle endless '<'
763
- if($this->pos>=$this->size-1 && $this->char!=='>') {
764
- $node->nodetype = HDOM_TYPE_TEXT;
765
- $node->_[HDOM_INFO_END] = 0;
766
- $node->_[HDOM_INFO_TEXT] = '<'.$tag . $space[0] . $name;
767
- $node->tag = 'text';
768
- $this->link_nodes($node, false);
769
- return true;
770
- }
771
-
772
- // handle mismatch '<'
773
- if($this->doc[$this->pos-1]=='<') {
774
- $node->nodetype = HDOM_TYPE_TEXT;
775
- $node->tag = 'text';
776
- $node->attr = array();
777
- $node->_[HDOM_INFO_END] = 0;
778
- $node->_[HDOM_INFO_TEXT] = substr($this->doc, $begin_tag_pos, $this->pos-$begin_tag_pos-1);
779
- $this->pos -= 2;
780
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
781
- $this->link_nodes($node, false);
782
- return true;
783
- }
784
-
785
- if ($name!=='/' && $name!=='') {
786
- $space[1] = $this->copy_skip($this->token_blank);
787
- $name = $this->restore_noise($name);
788
- if ($this->lowercase) $name = strtolower($name);
789
- if ($this->char==='=') {
790
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
791
- $this->parse_attr($node, $name, $space);
792
- }
793
- else {
794
- //no value attr: nowrap, checked selected...
795
- $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_NO;
796
- $node->attr[$name] = true;
797
- if ($this->char!='>') $this->char = $this->doc[--$this->pos]; // prev
798
- }
799
- $node->_[HDOM_INFO_SPACE][] = $space;
800
- $space = array($this->copy_skip($this->token_blank), '', '');
801
- }
802
- else
803
- break;
804
- } while($this->char!=='>' && $this->char!=='/');
805
-
806
- $this->link_nodes($node, true);
807
- $node->_[HDOM_INFO_ENDSPACE] = $space[0];
808
-
809
- // check self closing
810
- if ($this->copy_until_char_escape('>')==='/') {
811
- $node->_[HDOM_INFO_ENDSPACE] .= '/';
812
- $node->_[HDOM_INFO_END] = 0;
813
- }
814
- else {
815
- // reset parent
816
- if (!isset($this->self_closing_tags[strtolower($node->tag)])) $this->parent = $node;
817
- }
818
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
819
- return true;
820
- }
821
-
822
- // parse attributes
823
- protected function parse_attr($node, $name, &$space) {
824
- $space[2] = $this->copy_skip($this->token_blank);
825
- switch($this->char) {
826
- case '"':
827
- $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE;
828
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
829
- $node->attr[$name] = $this->restore_noise($this->copy_until_char_escape('"'));
830
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
831
- break;
832
- case '\'':
833
- $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_SINGLE;
834
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
835
- $node->attr[$name] = $this->restore_noise($this->copy_until_char_escape('\''));
836
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
837
- break;
838
- default:
839
- $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_NO;
840
- $node->attr[$name] = $this->restore_noise($this->copy_until($this->token_attr));
841
- }
842
- }
843
-
844
- // link node's parent
845
- protected function link_nodes(&$node, $is_child) {
846
- $node->parent = $this->parent;
847
- $this->parent->nodes[] = $node;
848
- if ($is_child)
849
- $this->parent->children[] = $node;
850
- }
851
-
852
- // as a text node
853
- protected function as_text_node($tag) {
854
- $node = new simple_html_dom_node($this);
855
- ++$this->cursor;
856
- $node->_[HDOM_INFO_TEXT] = '</' . $tag . '>';
857
- $this->link_nodes($node, false);
858
- $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
859
- return true;
860
- }
861
-
862
- protected function skip($chars) {
863
- $this->pos += strspn($this->doc, $chars, $this->pos);
864
- $this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
865
- }
866
-
867
- protected function copy_skip($chars) {
868
- $pos = $this->pos;
869
- $len = strspn($this->doc, $chars, $pos);
870
- $this->pos += $len;
871
- $this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
872
- if ($len===0) return '';
873
- return substr($this->doc, $pos, $len);
874
- }
875
-
876
- protected function copy_until($chars) {
877
- $pos = $this->pos;
878
- $len = strcspn($this->doc, $chars, $pos);
879
- $this->pos += $len;
880
- $this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
881
- return substr($this->doc, $pos, $len);
882
- }
883
-
884
- protected function copy_until_char($char) {
885
- if ($this->char===null) return '';
886
-
887
- if (($pos = strpos($this->doc, $char, $this->pos))===false) {
888
- $ret = substr($this->doc, $this->pos, $this->size-$this->pos);
889
- $this->char = null;
890
- $this->pos = $this->size;
891
- return $ret;
892
- }
893
-
894
- if ($pos===$this->pos) return '';
895
- $pos_old = $this->pos;
896
- $this->char = $this->doc[$pos];
897
- $this->pos = $pos;
898
- return substr($this->doc, $pos_old, $pos-$pos_old);
899
- }
900
-
901
- protected function copy_until_char_escape($char) {
902
- if ($this->char===null) return '';
903
-
904
- $start = $this->pos;
905
- while(1) {
906
- if (($pos = strpos($this->doc, $char, $start))===false) {
907
- $ret = substr($this->doc, $this->pos, $this->size-$this->pos);
908
- $this->char = null;
909
- $this->pos = $this->size;
910
- return $ret;
911
- }
912
-
913
- if ($pos===$this->pos) return '';
914
-
915
- if ($this->doc[$pos-1]==='\\') {
916
- $start = $pos+1;
917
- continue;
918
- }
919
-
920
- $pos_old = $this->pos;
921
- $this->char = $this->doc[$pos];
922
- $this->pos = $pos;
923
- return substr($this->doc, $pos_old, $pos-$pos_old);
924
- }
925
- }
926
-
927
- // remove noise from html content
928
- protected function remove_noise($pattern, $remove_tag=false) {
929
- $count = preg_match_all($pattern, $this->doc, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
930
-
931
- for ($i=$count-1; $i>-1; --$i) {
932
- $key = '___noise___'.sprintf('% 3d', count($this->noise)+100);
933
- $idx = ($remove_tag) ? 0 : 1;
934
- $this->noise[$key] = $matches[$i][$idx][0];
935
- $this->doc = substr_replace($this->doc, $key, $matches[$i][$idx][1], strlen($matches[$i][$idx][0]));
936
- }
937
-
938
- // reset the length of content
939
- $this->size = strlen($this->doc);
940
- if ($this->size>0) $this->char = $this->doc[0];
941
- }
942
-
943
- // restore noise to html content
944
- function restore_noise($text) {
945
- while(($pos=strpos($text, '___noise___'))!==false) {
946
- $key = '___noise___'.$text[$pos+11].$text[$pos+12].$text[$pos+13];
947
- if (isset($this->noise[$key]))
948
- $text = substr($text, 0, $pos).$this->noise[$key].substr($text, $pos+14);
949
- }
950
- return $text;
951
- }
952
-
953
- function __toString() {
954
- return $this->root->innertext();
955
- }
956
-
957
- function __get($name) {
958
- switch($name) {
959
- case 'outertext': return $this->root->innertext();
960
- case 'innertext': return $this->root->innertext();
961
- case 'plaintext': return $this->root->text();
962
- }
963
- }
964
-
965
- // camel naming conventions
966
- function childNodes($idx=-1) {return $this->root->childNodes($idx);}
967
- function firstChild() {return $this->root->first_child();}
968
- function lastChild() {return $this->root->last_child();}
969
- function getElementById($id) {return $this->find("#$id", 0);}
970
- function getElementsById($id, $idx=null) {return $this->find("#$id", $idx);}
971
- function getElementByTagName($name) {return $this->find($name, 0);}
972
- function getElementsByTagName($name, $idx=-1) {return $this->find($name, $idx);}
973
- function loadFile() {$args = func_get_args();$this->load(call_user_func_array('file_get_contents', $args), true);}
974
- }
975
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/ultimate-web-scraper/tag_filter.php DELETED
@@ -1,3260 +0,0 @@
1
- <?php
2
- // CubicleSoft PHP Tag Filter class. Can repair broken HTML.
3
- // (C) 2018 CubicleSoft. All Rights Reserved.
4
-
5
- class TagFilterStream
6
- {
7
- protected $lastcontent, $lastresult, $final, $options, $stack;
8
-
9
- public function __construct($options = array())
10
- {
11
- $this->Init($options);
12
- }
13
-
14
- public function Init($options = array())
15
- {
16
- if (!isset($options["keep_attr_newlines"])) $options["keep_attr_newlines"] = false;
17
- if (!isset($options["keep_comments"])) $options["keep_comments"] = false;
18
- if (!isset($options["allow_namespaces"])) $options["allow_namespaces"] = true;
19
- if (!isset($options["process_attrs"])) $options["process_attrs"] = array();
20
- if (!isset($options["charset"])) $options["charset"] = "UTF-8";
21
- $options["charset"] = strtoupper($options["charset"]);
22
- if (!isset($options["charset_tags"])) $options["charset_tags"] = true;
23
- if (!isset($options["charset_attrs"])) $options["charset_attrs"] = true;
24
- if (!isset($options["tag_name_map"])) $options["tag_name_map"] = array();
25
- if (!isset($options["untouched_tag_attr_keys"])) $options["untouched_tag_attr_keys"] = array();
26
- if (!isset($options["void_tags"])) $options["void_tags"] = array();
27
- if (!isset($options["alt_tag_content_rules"])) $options["alt_tag_content_rules"] = array();
28
- if (!isset($options["pre_close_tags"])) $options["pre_close_tags"] = array();
29
- if (!isset($options["output_mode"])) $options["output_mode"] = "html";
30
- if (!isset($options["lowercase_tags"])) $options["lowercase_tags"] = true;
31
- if (!isset($options["lowercase_attrs"])) $options["lowercase_attrs"] = true;
32
- $options["tag_num"] = 0;
33
-
34
- $this->lastcontent = "";
35
- $this->lastresult = "";
36
- $this->final = false;
37
- $this->options = $options;
38
- $this->stack = array();
39
- }
40
-
41
- public function Process($content)
42
- {
43
- if ($this->lastcontent !== "") $content = $this->lastcontent . $content;
44
-
45
- $result = $this->lastresult;
46
- $this->lastresult = "";
47
- $tag = false;
48
- $a = ord("A");
49
- $a2 = ord("a");
50
- $f = ord("F");
51
- $f2 = ord("f");
52
- $z = ord("Z");
53
- $z2 = ord("z");
54
- $hyphen = ord("-");
55
- $underscore = ord("_");
56
- $period = ord(".");
57
- $colon = ord(":");
58
- $zero = ord("0");
59
- $nine = ord("9");
60
- $cx = 0;
61
- $cy = strlen($content);
62
- while ($cx < $cy)
63
- {
64
- if ($tag)
65
- {
66
- $firstcx = $cx;
67
-
68
- // First character is '<'. Extract all non-alpha chars.
69
- $prefix = "";
70
- $startpos = $cx + 1;
71
- for ($x = $startpos; $x < $cy; $x++)
72
- {
73
- $val = ord($content{$x});
74
- if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2))
75
- {
76
- if ($x > $cx + 1) $prefix = ltrim(substr($content, $cx + 1, $x - $cx - 1));
77
- $startpos = $x;
78
-
79
- break;
80
- }
81
- }
82
-
83
- if ($prefix === "") $open = true;
84
- else
85
- {
86
- if ($prefix{0} === "!")
87
- {
88
- // !DOCTYPE vs. comment.
89
- if (substr($prefix, 0, 3) !== "!--")
90
- {
91
- $prefix = "!";
92
- $open = true;
93
- }
94
- else
95
- {
96
- // Comment.
97
- $pos = strpos($content, "!--", $cx);
98
- $pos2 = strpos($content, "-->", $pos + 3);
99
- if ($pos2 === false)
100
- {
101
- if (!$this->final)
102
- {
103
- $cx = $firstcx;
104
-
105
- break;
106
- }
107
-
108
- $pos2 = $cy;
109
- }
110
-
111
- if ($this->options["keep_comments"])
112
- {
113
- $content2 = substr($content, $pos + 3, $pos2 - $pos - 3);
114
- if ($this->options["charset"] === "UTF-8" && !self::IsValidUTF8($content2)) $content2 = self::MakeValidUTF8($content2);
115
- $content2 = "<!-- " . trim(htmlspecialchars($content2, ENT_COMPAT | ENT_HTML5, $this->options["charset"])) . " -->";
116
-
117
- // Let a callback handle any necessary changes.
118
- if (isset($this->options["content_callback"]) && is_callable($this->options["content_callback"])) call_user_func_array($this->options["content_callback"], array($this->stack, $result, &$content2, $this->options));
119
-
120
- $result .= $content2;
121
- }
122
- $cx = $pos2 + 3;
123
-
124
- $tag = false;
125
-
126
- continue;
127
- }
128
- }
129
- else if ($prefix{0} === "/")
130
- {
131
- // Close tag.
132
- $prefix = "/";
133
- $open = false;
134
- }
135
- else if ($prefix{0} === "<")
136
- {
137
- // Stray less than. Encode and reset.
138
- $content2 = "&lt;";
139
-
140
- // Let a callback handle any necessary changes.
141
- if (isset($this->options["content_callback"]) && is_callable($this->options["content_callback"])) call_user_func_array($this->options["content_callback"], array($this->stack, $result, &$content2, $this->options));
142
-
143
- $result .= $content2;
144
- $cx++;
145
-
146
- continue;
147
- }
148
- else
149
- {
150
- // Unknown. Encode it.
151
- $data = substr($content, $cx, strpos($content, $prefix, $cx) + strlen($prefix) - $cx);
152
- $content2 = $data;
153
- if ($this->options["charset"] === "UTF-8" && !self::IsValidUTF8($content2)) $content2 = self::MakeValidUTF8($content2);
154
- $content2 = htmlspecialchars($content2, ENT_COMPAT | ENT_HTML5, $this->options["charset"]);
155
-
156
- // Let a callback handle any necessary changes.
157
- if (isset($this->options["content_callback"]) && is_callable($this->options["content_callback"])) call_user_func_array($this->options["content_callback"], array($this->stack, $result, &$content2, $this->options));
158
-
159
- $result .= $content2;
160
- $cx += strlen($data);
161
-
162
- $tag = false;
163
-
164
- continue;
165
- }
166
- }
167
-
168
- // Read the tag name.
169
- $tagname = "";
170
- $parse = false;
171
- $cx = $startpos;
172
- for (; $cx < $cy; $cx++)
173
- {
174
- $val = ord($content{$cx});
175
- if ($val > 127) $parse = true;
176
- else if (!(($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2) || ($cx > $startpos && (($val >= $zero && $val <= $nine) || $val == $hyphen || $val == $underscore || $val == $period)) || ($this->options["allow_namespaces"] && $val == $colon))) break;
177
- }
178
- $tagname = substr($content, $startpos, $cx - $startpos);
179
- if ($parse)
180
- {
181
- if ($this->options["charset_tags"] && $this->options["charset"] === "UTF-8") $tagname = (self::IsValidUTF8($tagname) ? $tagname : self::MakeValidUTF8($tagname));
182
- else $tagname = preg_replace(($this->options["allow_namespaces"] ? '/[^A-Za-z0-9:._-]/' : '/[^A-Za-z0-9._-]/'), "", $tagname);
183
- }
184
- $tagname = rtrim($tagname, "._-:");
185
- if (!$this->options["charset_tags"]) $tagname = preg_replace('/[^A-Za-z0-9:]/', "", $tagname);
186
- $outtagname = ($this->options["lowercase_tags"] ? strtolower($tagname) : $tagname);
187
- $tagname = strtolower($tagname);
188
-
189
- // Close open tags in the stack that match the set of tags to look for to close.
190
- if ($open && isset($this->options["pre_close_tags"][$tagname]))
191
- {
192
- // Find matches.
193
- $info2 = $this->options["pre_close_tags"][$tagname];
194
- $limit = (isset($info2["_limit"]) ? $info2["_limit"] : array());
195
- if (is_string($limit)) $limit = array($limit => true);
196
-
197
- // Unwind the stack.
198
- do
199
- {
200
- $found = false;
201
- foreach ($this->stack as $info)
202
- {
203
- if (isset($info2[$info["tag_name"]]))
204
- {
205
- $found = true;
206
-
207
- break;
208
- }
209
-
210
- if (isset($limit[$info["tag_name"]])) break;
211
- }
212
-
213
- if ($found)
214
- {
215
- do
216
- {
217
- // Let a callback handle any necessary changes.
218
- $attrs = array();
219
- if (isset($this->options["tag_callback"]) && is_callable($this->options["tag_callback"])) $funcresult = call_user_func_array($this->options["tag_callback"], array($this->stack, &$result, false, "/" . $this->stack[0]["tag_name"], &$attrs, $this->options));
220
- else $funcresult = array();
221
-
222
- if (!isset($funcresult["keep_tag"])) $funcresult["keep_tag"] = true;
223
-
224
- $info = array_shift($this->stack);
225
-
226
- $result = $info["result"] . ($funcresult["keep_tag"] ? $info["open_tag"] : "") . ($info["keep_interior"] ? $result : "");
227
- if ($info["close_tag"] && $funcresult["keep_tag"]) $result .= "</" . $info["out_tag_name"] . ">" . $info["post_tag"];
228
- } while (!isset($info2[$info["tag_name"]]));
229
- }
230
- } while ($found);
231
- }
232
-
233
- // Process attributes/properties until a closing condition is encountered.
234
- $state = "name";
235
- $voidtag = false;
236
- $attrs = array();
237
- do
238
- {
239
- if ($state === "name")
240
- {
241
- // Find attribute key/property.
242
- for ($x = $cx; $x < $cy; $x++)
243
- {
244
- if ($content{$x} === ">" || $content{$x} === "<")
245
- {
246
- $cx = $x;
247
-
248
- $state = "exit";
249
-
250
- break;
251
- }
252
- else if ($content{$x} === "/")
253
- {
254
- $pos = strpos($content, ">", $x + 1);
255
- if ($pos !== false && trim(substr($content, $x + 1, $pos - $x - 1)) === "")
256
- {
257
- $cx = $pos;
258
- $voidtag = true;
259
-
260
- $state = "exit";
261
-
262
- break;
263
- }
264
- }
265
- else if ($content{$x} === "\"" || $content{$x} === "'" || $content{$x} === "`")
266
- {
267
- $pos = strpos($content, $content{$x}, $x + 1);
268
- if ($pos === false) $content .= $content{$x};
269
- else if (isset($this->options["untouched_tag_attr_keys"][$tagname]))
270
- {
271
- $keyname = substr($content, $x, $pos - $x + 1);
272
- $cx = $pos + 1;
273
-
274
- $state = "equals";
275
- }
276
- else
277
- {
278
- $keyname = substr($content, $x + 1, $pos - $x - 1);
279
- if ($this->options["lowercase_attrs"]) $keyname = strtolower($keyname);
280
- if (preg_match('/<\s*\/\s*' . $tagname . '(\s*|\s+.+?)>/is', strtolower($keyname)) || (count($this->stack) && preg_match('/<\s*\/\s*' . $this->stack[0]["tag_name"] . '(\s*|\s+.+?)>/is', strtolower($keyname))))
281
- {
282
- // Found a matching close tag within the key name. Bail out.
283
- $state = "exit";
284
-
285
- break;
286
- }
287
- else
288
- {
289
- $keyname = preg_replace('/[^' . ($this->options["lowercase_attrs"] ? "" : "A-Z") . 'a-z' . ($this->options["allow_namespaces"] ? ":" : "") . ']/', "", $keyname);
290
- if ($this->options["allow_namespaces"]) $keyname = rtrim($keyname, ":");
291
- $cx = $pos + 1;
292
-
293
- $state = "equals";
294
- }
295
- }
296
-
297
- break;
298
- }
299
- else
300
- {
301
- $val = ord($content{$x});
302
- if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2))
303
- {
304
- $cx = $x;
305
- $parse = false;
306
-
307
- for (; $cx < $cy; $cx++)
308
- {
309
- if ($content{$cx} === " " || $content{$cx} === "=" || $content{$cx} === "\"" || $content{$cx} === "'" || $content{$cx} === "`" || $content{$cx} === ">" || $content{$cx} === "<" || $content{$cx} === "/" || $content{$cx} === "\0" || $content{$cx} === "\r" || $content{$cx} === "\n" || $content{$cx} === "\t") break;
310
- else if (ord($content{$cx}) > 127) $parse = true;
311
- }
312
-
313
- $keyname = substr($content, $x, $cx - $x);
314
- if ($parse && $this->options["charset_attrs"] && $this->options["charset"] === "UTF-8")
315
- {
316
- $keyname = preg_replace(($this->options["allow_namespaces"] ? '/[^A-Za-z0-9:._\-\x80-\xFF]/' : '/[^A-Za-z0-9._\-\x80-\xFF]/'), "", $keyname);
317
- if (!self::IsValidUTF8($keyname)) $keyname = self::MakeValidUTF8($keyname);
318
- }
319
- else
320
- {
321
- $keyname = preg_replace(($this->options["allow_namespaces"] ? '/[^A-Za-z0-9:._-]/' : '/[^A-Za-z0-9._-]/'), "", $keyname);
322
- }
323
- $keyname = rtrim($keyname, "._-:");
324
- if (!isset($this->options["untouched_tag_attr_keys"][$tagname]) && $this->options["lowercase_attrs"]) $keyname = strtolower($keyname);
325
-
326
- $state = "equals";
327
-
328
- break;
329
- }
330
- }
331
- }
332
-
333
- if ($state === "name")
334
- {
335
- $cx = $cy;
336
-
337
- $state = "exit";
338
- }
339
- }
340
- else if ($state === "equals")
341
- {
342
- // Find the equals sign OR the start of the next attribute/property.
343
- for ($x = $cx; $x < $cy; $x++)
344
- {
345
- if ($content{$x} === ">" || $content{$x} === "<")
346
- {
347
- $cx = $x;
348
-
349
- $attrs[$keyname] = true;
350
-
351
- $state = "exit";
352
-
353
- break;
354
- }
355
- else if ($content{$x} === "=")
356
- {
357
- $cx = $x + 1;
358
-
359
- $state = "value";
360
-
361
- break;
362
- }
363
- else if ($content{$x} === "\"" || $content{$x} === "'")
364
- {
365
- $cx = $x;
366
-
367
- $attrs[$keyname] = true;
368
-
369
- $state = "name";
370
-
371
- break;
372
- }
373
- else
374
- {
375
- $val = ord($content{$x});
376
- if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2) || ($val >= $zero && $val <= $nine))
377
- {
378
- $cx = $x;
379
-
380
- $attrs[$keyname] = true;
381
-
382
- $state = "name";
383
-
384
- break;
385
- }
386
- }
387
- }
388
-
389
- if ($state === "equals")
390
- {
391
- $cx = $cy;
392
-
393
- $attrs[$keyname] = true;
394
-
395
- $state = "exit";
396
- }
397
- }
398
- else if ($state === "value")
399
- {
400
- for ($x = $cx; $x < $cy; $x++)
401
- {
402
- if ($content{$x} === ">" || $content{$x} === "<")
403
- {
404
- $cx = $x;
405
-
406
- $attrs[$keyname] = true;
407
-
408
- $state = "exit";
409
-
410
- break;
411
- }
412
- else if ($content{$x} === "\"" || $content{$x} === "'" || $content{$x} === "`")
413
- {
414
- $pos = strpos($content, $content{$x}, $x + 1);
415
- if ($pos === false) $content .= $content{$x};
416
- else
417
- {
418
- $value = substr($content, $x + 1, $pos - $x - 1);
419
- $cx = $pos + 1;
420
-
421
- $state = "name";
422
- }
423
-
424
- break;
425
- }
426
- else if ($content{$x} !== "\0" && $content{$x} !== "\r" && $content{$x} !== "\n" && $content{$x} !== "\t" && $content{$x} !== " ")
427
- {
428
- $cx = $x;
429
-
430
- for (; $cx < $cy; $cx++)
431
- {
432
- if ($content{$cx} === "\0" || $content{$cx} === "\r" || $content{$cx} === "\n" || $content{$cx} === "\t" || $content{$cx} === " " || $content{$cx} === "<" || $content{$cx} === ">")
433
- {
434
- break;
435
- }
436
- }
437
-
438
- $value = substr($content, $x, $cx - $x);
439
-
440
- $state = "name";
441
-
442
- break;
443
- }
444
- }
445
-
446
- if ($state === "value")
447
- {
448
- $cx = $cy;
449
-
450
- $attrs[$keyname] = true;
451
-
452
- $state = "exit";
453
- }
454
-
455
- if ($state === "name")
456
- {
457
- if ($this->options["charset"] === "UTF-8" && !self::IsValidUTF8($value)) $value = self::MakeValidUTF8($value);
458
- $value = html_entity_decode($value, ENT_QUOTES | ENT_HTML5, $this->options["charset"]);
459
-
460
- // Decode remaining entities.
461
- $value2 = "";
462
- $vx = 0;
463
- $vy = strlen($value);
464
- while ($vx < $vy)
465
- {
466
- $pos = strpos($value, "&#", $vx);
467
- $pos2 = strpos($value, "\\", $vx);
468
- if ($pos === false) $pos = $vy;
469
- if ($pos2 === false) $pos2 = $vy;
470
- if ($pos < $pos2)
471
- {
472
- // &#32 or &#x20 (optional trailing semi-colon)
473
- $value2 .= substr($value, $vx, $pos - $vx);
474
- $vx = $pos + 2;
475
- if ($vx < $vy)
476
- {
477
- if ($value{$vx} == "x" || $value{$vx} == "X")
478
- {
479
- $vx++;
480
- if ($vx < $vy)
481
- {
482
- for ($x = $vx; $x < $vy; $x++)
483
- {
484
- $val = ord($value{$x});
485
- if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
486
- }
487
-
488
- $num = hexdec(substr($value, $vx, $x - $vx));
489
- $vx = $x;
490
- if ($vx < $vy && $value{$vx} == ";") $vx++;
491
-
492
- $value2 .= self::UTF8Chr($num);
493
- }
494
- }
495
- else
496
- {
497
- for ($x = $vx; $x < $vy; $x++)
498
- {
499
- $val = ord($value{$x});
500
- if (!($val >= $zero && $val <= $nine)) break;
501
- }
502
-
503
- $num = (int)substr($value, $vx, $x - $vx);
504
- $vx = $x;
505
- if ($vx < $vy && $value{$vx} == ";") $vx++;
506
-
507
- $value2 .= self::UTF8Chr($num);
508
- }
509
- }
510
- }
511
- else if ($pos2 < $pos)
512
- {
513
- // Unicode (e.g. \0020)
514
- $value2 .= substr($value, $vx, $pos2 - $vx);
515
- $vx = $pos2 + 1;
516
- if ($vx >= $vy) $value2 .= "\\";
517
- else
518
- {
519
- for ($x = $vx; $x < $vy; $x++)
520
- {
521
- $val = ord($value{$x});
522
- if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
523
- }
524
-
525
- if ($x > $vx)
526
- {
527
- $num = hexdec(substr($value, $vx, $x - $vx));
528
- $vx = $x;
529
-
530
- $value2 .= self::UTF8Chr($num);
531
- }
532
- else
533
- {
534
- $value2 .= "\\";
535
- }
536
- }
537
- }
538
- else
539
- {
540
- $value2 .= substr($value, $vx);
541
- $vx = $vy;
542
- }
543
- }
544
- $value = $value2;
545
-
546
- if (!$this->options["keep_attr_newlines"]) $value = str_replace(array("\r\n", "\r", "\n"), " ", $value);
547
-
548
- if (isset($this->options["process_attrs"][$keyname]))
549
- {
550
- $type = $this->options["process_attrs"][$keyname];
551
- if ($type === "classes")
552
- {
553
- $classes = explode(" ", $value);
554
- $value = array();
555
- foreach ($classes as $class)
556
- {
557
- if ($class !== "") $value[$class] = $class;
558
- }
559
- }
560
- else if ($type === "uri")
561
- {
562
- $value = str_replace(array("\0", "\r", "\n", "\t", " "), "", $value);
563
- $pos = strpos($value, ":");
564
- if ($pos !== false) $value = preg_replace('/[^a-z]/', "", strtolower(substr($value, 0, $pos))) . substr($value, $pos);
565
- }
566
- }
567
-
568
- $attrs[$keyname] = $value;
569
- }
570
- }
571
- } while ($cx < $cy && $state !== "exit");
572
-
573
- // Break out of the loop if the end of the stream has been reached but not finalized and most likely in the middle of a tag.
574
- if ($cx >= $cy && !$this->final)
575
- {
576
- $cx = $firstcx;
577
-
578
- break;
579
- }
580
-
581
- unset($attrs[""]);
582
-
583
- if ($cx < $cy && $content{$cx} === ">") $cx++;
584
-
585
- if (isset($this->options["tag_name_map"][$prefix . $tagname])) $outtagname = $tagname = $this->options["tag_name_map"][$prefix . $tagname];
586
-
587
- if ($tagname != "")
588
- {
589
- if ($open)
590
- {
591
- if ($voidtag && isset($this->options["void_tags"][$tagname])) $voidtag = false;
592
- $this->options["tag_num"]++;
593
-
594
- // Let a callback handle any necessary changes.
595
- if (isset($this->options["tag_callback"]) && is_callable($this->options["tag_callback"])) $funcresult = call_user_func_array($this->options["tag_callback"], array($this->stack, &$result, $open, $prefix . $tagname, &$attrs, $this->options));
596
- else $funcresult = array();
597
-
598
- if (!isset($funcresult["keep_tag"])) $funcresult["keep_tag"] = true;
599
- if (!isset($funcresult["keep_interior"])) $funcresult["keep_interior"] = true;
600
- if (!isset($funcresult["pre_tag"])) $funcresult["pre_tag"] = "";
601
- if (!isset($funcresult["post_tag"])) $funcresult["post_tag"] = "";
602
- if (!isset($funcresult["state"])) $funcresult["state"] = false;
603
- }
604
-
605
- if ($open && $funcresult["keep_tag"])
606
- {
607
- $opentag = $funcresult["pre_tag"];
608
- $opentag .= "<" . $prefix . $outtagname;
609
- foreach ($attrs as $key => $val)
610
- {
611
- $opentag .= " " . $key;
612
-
613
- if (is_array($val)) $val = implode(" ", $val);
614
- if (is_string($val))
615
- {
616
- if ($this->options["charset"] === "UTF-8" && !self::IsValidUTF8($val)) $val = self::MakeValidUTF8($val);
617
- $opentag .= "=\"" . htmlspecialchars($val, ENT_COMPAT | ENT_HTML5, $this->options["charset"]) . "\"";
618
- }
619
- }
620
- if (($voidtag || isset($this->options["void_tags"][$tagname])) && $this->options["output_mode"] === "xml")
621
- {
622
- $opentag .= " /";
623
-
624
- $voidtag = false;
625
- }
626
- $opentag .= ">";
627
-
628
- if (!isset($this->options["void_tags"][$tagname]) && $prefix === "")
629
- {
630
- array_unshift($this->stack, array("tag_num" => $this->options["tag_num"], "tag_name" => $tagname, "out_tag_name" => $outtagname, "attrs" => $attrs, "result" => $result, "open_tag" => $opentag, "close_tag" => true, "keep_interior" => $funcresult["keep_interior"], "post_tag" => $funcresult["post_tag"], "state" => $funcresult["state"]));
631
- $result = "";
632
-
633
- if ($voidtag) $open = false;
634
- }
635
- else
636
- {
637
- $result .= $opentag;
638
- $result .= $funcresult["post_tag"];
639
- }
640
- }
641
-
642
- if ((!$open || !$funcresult["keep_tag"]) && !isset($this->options["void_tags"][$tagname]))
643
- {
644
- if ($open)
645
- {
646
- array_unshift($this->stack, array("tag_num" => $this->options["tag_num"], "tag_name" => $tagname, "out_tag_name" => $outtagname, "attrs" => $attrs, "result" => $result, "open_tag" => "", "close_tag" => false, "keep_interior" => $funcresult["keep_interior"], "post_tag" => $funcresult["post_tag"], "state" => $funcresult["state"]));
647
- $result = "";
648
- }
649
-
650
- if (!$open)
651
- {
652
- $found = false;
653
- foreach ($this->stack as $info)
654
- {
655
- if ($tagname === $info["tag_name"])
656
- {
657
- $found = true;
658
-
659
- break;
660
- }
661
- }
662
-
663
- if ($found)
664
- {
665
- do
666
- {
667
- // Let a callback handle any necessary changes.
668
- $attrs = array();
669
- if (isset($this->options["tag_callback"]) && is_callable($this->options["tag_callback"])) $funcresult = call_user_func_array($this->options["tag_callback"], array($this->stack, &$result, false, "/" . $this->stack[0]["tag_name"], &$attrs, $this->options));
670
- else $funcresult = array();
671
-
672
- // Force close tag to be kept if the stream already output the open tag.
673
- if (!isset($funcresult["keep_tag"]) || ($info["close_tag"] && $info["open_tag"] == "")) $funcresult["keep_tag"] = true;
674
-
675
- $info = array_shift($this->stack);
676
-
677
- $result = $info["result"] . ($funcresult["keep_tag"] ? $info["open_tag"] : "") . ($info["keep_interior"] ? $result : "");
678
- if ($info["close_tag"] && $funcresult["keep_tag"]) $result .= "</" . $info["out_tag_name"] . ">" . $info["post_tag"];
679
- } while ($tagname !== $info["tag_name"]);
680
- }
681
- }
682
- }
683
- }
684
-
685
- //echo "Current output:\n" . $result . "\n\n";
686
- //echo "Prefix: " . $prefix . "\n\n";
687
- //echo "Tag: " . $tagname . "\n\n";
688
- //echo "Attrs:\n";
689
- //var_dump($attrs);
690
- //
691
- //echo "Tag stack:\n";
692
- //var_dump($this->stack);
693
- //
694
- //echo "\n\n";
695
- //echo $content . "\n";
696
- //exit();
697
-
698
- $tag = false;
699
- }
700
- else
701
- {
702
- $regular = true;
703
-
704
- // Special content handler for certain tags.
705
- if (count($this->stack) && isset($this->options["alt_tag_content_rules"][$this->stack[0]["tag_name"]]) && is_callable($this->options["alt_tag_content_rules"][$this->stack[0]["tag_name"]]))
706
- {
707
- $content2 = "";
708
-
709
- // Expected to return true until the function is no longer interested in the data.
710
- if (call_user_func_array($this->options["alt_tag_content_rules"][$this->stack[0]["tag_name"]], array($this->stack, $this->final, &$tag, &$content, &$cx, $cy, &$content2, $this->options))) $regular = false;
711
- else if (!$this->final)
712
- {
713
- // Let a callback handle any necessary changes.
714
- if (isset($this->options["content_callback"]) && is_callable($this->options["content_callback"])) call_user_func_array($this->options["content_callback"], array($this->stack, $result, &$content2, $this->options));
715
-
716
- $result .= $content2;
717
-
718
- break;
719
- }
720
- }
721
-
722
- if ($regular)
723
- {
724
- // Regular content.
725
- $pos = strpos($content, "<", $cx);
726
- if ($pos === false)
727
- {
728
- $content2 = str_replace(">", "&gt;", substr($content, $cx));
729
- $cx = $cy;
730
- }
731
- else
732
- {
733
- $content2 = str_replace(">", "&gt;", substr($content, $cx, $pos - $cx));
734
- $cx = $pos;
735
-
736
- $tag = true;
737
- }
738
- }
739
-
740
- // Let a callback handle any necessary changes.
741
- if (isset($this->options["content_callback"]) && is_callable($this->options["content_callback"])) call_user_func_array($this->options["content_callback"], array($this->stack, $result, &$content2, $this->options));
742
-
743
- $result .= $content2;
744
- }
745
- }
746
-
747
- if ($this->final)
748
- {
749
- while (count($this->stack))
750
- {
751
- // Let a callback handle any necessary changes.
752
- $attrs = array();
753
- if (isset($this->options["tag_callback"]) && is_callable($this->options["tag_callback"])) $funcresult = call_user_func_array($this->options["tag_callback"], array($this->stack, &$result, false, "/" . $this->stack[0]["tag_name"], &$attrs, $this->options));
754
- else $funcresult = array();
755
-
756
- $info = array_shift($this->stack);
757
-
758
- // Force close tag to be kept if the stream already output the open tag.
759
- if (!isset($funcresult["keep_tag"]) || ($info["close_tag"] && $info["open_tag"] == "")) $funcresult["keep_tag"] = true;
760
-
761
- $result = $info["result"] . ($funcresult["keep_tag"] ? $info["open_tag"] : "") . ($info["keep_interior"] ? $result : "");
762
- if ($info["close_tag"] && $funcresult["keep_tag"]) $result .= "</" . $info["out_tag_name"] . ">" . $info["post_tag"];
763
- }
764
- }
765
- else
766
- {
767
- $this->lastcontent = ($cx < $cy ? substr($content, $cx) : "");
768
- $this->lastresult = $result;
769
- $result = "";
770
- }
771
-
772
- return $result;
773
- }
774
-
775
- public function Finalize()
776
- {
777
- $this->final = true;
778
- }
779
-
780
- // To cleanly figure out how far in to flush output, call GetStack(true), use TagFilter::GetParentPos(), and call GetResult().
781
- public function GetStack($invert = false)
782
- {
783
- return ($invert ? array_reverse($this->stack) : $this->stack);
784
- }
785
-
786
- // Returns the result so far up to the specified stack position and flushes the stored output to keep RAM usage low.
787
- // NOTE: Callback functions returning 'keep_tag' of false for the closing tag won't work for tags that were already output using this function.
788
- public function GetResult($invertedstackpos)
789
- {
790
- $y = count($this->stack);
791
- $pos = $y - $invertedstackpos - 1;
792
- if ($pos < 0) $pos = 0;
793
-
794
- $result = "";
795
- for ($x = $y - 1; $x >= $pos; $x--)
796
- {
797
- $result .= $this->stack[$x]["result"] . $this->stack[$x]["open_tag"];
798
-
799
- $this->stack[$x]["result"] = "";
800
- $this->stack[$x]["open_tag"] = "";
801
- }
802
-
803
- if (!$pos)
804
- {
805
- $result .= $this->lastresult;
806
- $this->lastresult = "";
807
- }
808
-
809
- return $result;
810
- }
811
-
812
- public static function MakeValidUTF8($data)
813
- {
814
- $result = "";
815
- $x = 0;
816
- $y = strlen($data);
817
- while ($x < $y)
818
- {
819
- $tempchr = ord($data[$x]);
820
- if ($y - $x > 1) $tempchr2 = ord($data[$x + 1]);
821
- else $tempchr2 = 0x00;
822
- if ($y - $x > 2) $tempchr3 = ord($data[$x + 2]);
823
- else $tempchr3 = 0x00;
824
- if ($y - $x > 3) $tempchr4 = ord($data[$x + 3]);
825
- else $tempchr4 = 0x00;
826
- if (($tempchr >= 0x20 && $tempchr <= 0x7E) || $tempchr == 0x09 || $tempchr == 0x0A || $tempchr == 0x0D)
827
- {
828
- // ASCII minus control and special characters.
829
- $result .= chr($tempchr);
830
- $x++;
831
- }
832
- else if (($tempchr >= 0xC2 && $tempchr <= 0xDF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF))
833
- {
834
- // Non-overlong (2 bytes).
835
- $result .= chr($tempchr);
836
- $result .= chr($tempchr2);
837
- $x += 2;
838
- }
839
- else if ($tempchr == 0xE0 && ($tempchr2 >= 0xA0 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF))
840
- {
841
- // Non-overlong (3 bytes).
842
- $result .= chr($tempchr);
843
- $result .= chr($tempchr2);
844
- $result .= chr($tempchr3);
845
- $x += 3;
846
- }
847
- else if ((($tempchr >= 0xE1 && $tempchr <= 0xEC) || $tempchr == 0xEE || $tempchr == 0xEF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF))
848
- {
849
- // Normal/straight (3 bytes).
850
- $result .= chr($tempchr);
851
- $result .= chr($tempchr2);
852
- $result .= chr($tempchr3);
853
- $x += 3;
854
- }
855
- else if ($tempchr == 0xED && ($tempchr2 >= 0x80 && $tempchr2 <= 0x9F) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF))
856
- {
857
- // Non-surrogates (3 bytes).
858
- $result .= chr($tempchr);
859
- $result .= chr($tempchr2);
860
- $result .= chr($tempchr3);
861
- $x += 3;
862
- }
863
- else if ($tempchr == 0xF0 && ($tempchr2 >= 0x90 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF))
864
- {
865
- // Planes 1-3 (4 bytes).
866
- $result .= chr($tempchr);
867
- $result .= chr($tempchr2);
868
- $result .= chr($tempchr3);
869
- $result .= chr($tempchr4);
870
- $x += 4;
871
- }
872
- else if (($tempchr >= 0xF1 && $tempchr <= 0xF3) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF))
873
- {
874
- // Planes 4-15 (4 bytes).
875
- $result .= chr($tempchr);
876
- $result .= chr($tempchr2);
877
- $result .= chr($tempchr3);
878
- $result .= chr($tempchr4);
879
- $x += 4;
880
- }
881
- else if ($tempchr == 0xF4 && ($tempchr2 >= 0x80 && $tempchr2 <= 0x8F) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF))
882
- {
883
- // Plane 16 (4 bytes).
884
- $result .= chr($tempchr);
885
- $result .= chr($tempchr2);
886
- $result .= chr($tempchr3);
887
- $result .= chr($tempchr4);
888
- $x += 4;
889
- }
890
- else $x++;
891
- }
892
-
893
- return $result;
894
- }
895
-
896
- public static function IsValidUTF8($data)
897
- {
898
- $x = 0;
899
- $y = strlen($data);
900
- while ($x < $y)
901
- {
902
- $tempchr = ord($data{$x});
903
- if (($tempchr >= 0x20 && $tempchr <= 0x7E) || $tempchr == 0x09 || $tempchr == 0x0A || $tempchr == 0x0D) $x++;
904
- else if ($tempchr < 0xC2) return false;
905
- else
906
- {
907
- $left = $y - $x;
908
- if ($left > 1) $tempchr2 = ord($data{$x + 1});
909
- else return false;
910
-
911
- if (($tempchr >= 0xC2 && $tempchr <= 0xDF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF)) $x += 2;
912
- else
913
- {
914
- if ($left > 2) $tempchr3 = ord($data{$x + 2});
915
- else return false;
916
-
917
- if ($tempchr3 < 0x80 || $tempchr3 > 0xBF) return false;
918
-
919
- if ($tempchr == 0xE0 && ($tempchr2 >= 0xA0 && $tempchr2 <= 0xBF)) $x += 3;
920
- else if ((($tempchr >= 0xE1 && $tempchr <= 0xEC) || $tempchr == 0xEE || $tempchr == 0xEF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF)) $x += 3;
921
- else if ($tempchr == 0xED && ($tempchr2 >= 0x80 && $tempchr2 <= 0x9F)) $x += 3;
922
- else
923
- {
924
- if ($left > 3) $tempchr4 = ord($data{$x + 3});
925
- else return false;
926
-
927
- if ($tempchr4 < 0x80 || $tempchr4 > 0xBF) return false;
928
-
929
- if ($tempchr == 0xF0 && ($tempchr2 >= 0x90 && $tempchr2 <= 0xBF)) $x += 4;
930
- else if (($tempchr >= 0xF1 && $tempchr <= 0xF3) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF)) $x += 4;
931
- else if ($tempchr == 0xF4 && ($tempchr2 >= 0x80 && $tempchr2 <= 0x8F)) $x += 4;
932
- else return false;
933
- }
934
- }
935
- }
936
- }
937
-
938
- return true;
939
- }
940
-
941
- public static function UTF8Chr($num)
942
- {
943
- if ($num < 0 || ($num >= 0xD800 && $num <= 0xDFFF) || ($num >= 0xFDD0 && $num <= 0xFDEF) || ($num & 0xFFFE) == 0xFFFE) return "";
944
-
945
- if ($num <= 0x7F) $result = chr($num);
946
- else if ($num <= 0x7FF) $result = chr(0xC0 | ($num >> 6)) . chr(0x80 | ($num & 0x3F));
947
- else if ($num <= 0xFFFF) $result = chr(0xE0 | ($num >> 12)) . chr(0x80 | (($num >> 6) & 0x3F)) . chr(0x80 | ($num & 0x3F));
948
- else if ($num <= 0x10FFFF) $result = chr(0xF0 | ($num >> 18)) . chr(0x80 | (($num >> 12) & 0x3F)) . chr(0x80 | (($num >> 6) & 0x3F)) . chr(0x80 | ($num & 0x3F));
949
- else $result = "";
950
-
951
- return $result;
952
- }
953
- }
954
-
955
- // Accessing the data in TagFilterNodes (with an 's') via objects is not the most performance-friendly method of access.
956
- // The classes TagFilterNode and TagFilterNodeIterator defer method calls to the referenced TagFilterNodes instance.
957
- // Removed/replaced nodes in the original data will result in undefined behavior with object reuse.
958
- class TagFilterNode
959
- {
960
- private $tfn, $id;
961
-
962
- public function __construct($tfn, $rootid)
963
- {
964
- $this->tfn = $tfn;
965
- $this->id = $rootid;
966
- }
967
-
968
- public function __get($key)
969
- {
970
- return (isset($this->tfn->nodes[$this->id]) && isset($this->tfn->nodes[$this->id]["attrs"]) && isset($this->tfn->nodes[$this->id]["attrs"][$key]) ? $this->tfn->nodes[$this->id]["attrs"][$key] : false);
971
- }
972
-
973
- public function __set($key, $val)
974
- {
975
- if (isset($this->tfn->nodes[$this->id]) && isset($this->tfn->nodes[$this->id]["attrs"]))
976
- {
977
- if (is_array($val)) $this->tfn->nodes[$this->id]["attrs"][$key] = $val;
978
- else if (isset($this->tfn->nodes[$this->id]["attrs"][$key]) && is_array($this->tfn->nodes[$this->id]["attrs"][$key])) $this->tfn->nodes[$this->id]["attrs"][$key][(string)$val] = (string)$val;
979
- else $this->tfn->nodes[$this->id]["attrs"][$key] = (string)$val;
980
- }
981
- }
982
-
983
- public function __isset($key)
984
- {
985
- return (isset($this->tfn->nodes[$this->id]) && isset($this->tfn->nodes[$this->id]["attrs"]) && isset($this->tfn->nodes[$this->id]["attrs"][$key]));
986
- }
987
-
988
- public function __unset($key)
989
- {
990
- if (isset($this->tfn->nodes[$this->id]) && isset($this->tfn->nodes[$this->id]["attrs"])) unset($this->tfn->nodes[$this->id]["attrs"][$key]);
991
- }
992
-
993
- public function __toString()
994
- {
995
- return $this->tfn->GetOuterHTML($this->id);
996
- }
997
-
998
- public function __debugInfo()
999
- {
1000
- $result = (isset($this->tfn->nodes[$this->id]) ? $this->tfn->nodes[$this->id] : array());
1001
- $result["id"] = $this->id;
1002
-
1003
- return $result;
1004
- }
1005
-
1006
- public function ID()
1007
- {
1008
- return $this->id;
1009
- }
1010
-
1011
- public function Node()
1012
- {
1013
- return (isset($this->tfn->nodes[$this->id]) ? $this->tfn->nodes[$this->id] : false);
1014
- }
1015
-
1016
- public function Type()
1017
- {
1018
- return (isset($this->tfn->nodes[$this->id]) ? $this->tfn->nodes[$this->id]["type"] : false);
1019
- }
1020
-
1021
- public function Tag()
1022
- {
1023
- return $this->tfn->GetTag($this->id);
1024
- }
1025
-
1026
- public function Text($val = null)
1027
- {
1028
- if ($val !== null) $this->tfn->SetText($this->id, $val);
1029
- else return $this->tfn->GetText($this->id);
1030
- }
1031
-
1032
- public function AddClass($name, $attr = "class")
1033
- {
1034
- if (isset($this->tfn->nodes[$this->id]) && isset($this->tfn->nodes[$this->id]["attrs"]))
1035
- {
1036
- if (!isset($this->tfn->nodes[$this->id]["attrs"][$attr]) || !is_array($this->tfn->nodes[$this->id]["attrs"][$attr])) $this->tfn->nodes[$this->id]["attrs"][$attr] = array();
1037
-
1038
- $this->tfn->nodes[$this->id]["attrs"][$attr][$name] = $name;
1039
- }
1040
- }
1041
-
1042
- public function RemoveClass($name, $attr = "class")
1043
- {
1044
- if (isset($this->tfn->nodes[$this->id]) && isset($this->tfn->nodes[$this->id]["attrs"]))
1045
- {
1046
- if (isset($this->tfn->nodes[$this->id]["attrs"][$attr]) && is_array($this->tfn->nodes[$this->id]["attrs"][$attr])) unset($this->tfn->nodes[$this->id]["attrs"][$attr][$name]);
1047
- }
1048
- }
1049
-
1050
- public function Parent()
1051
- {
1052
- return $this->tfn->GetParent($this->id);
1053
- }
1054
-
1055
- public function ParentPos()
1056
- {
1057
- return (isset($this->tfn->nodes[$this->id]) ? $this->tfn->nodes[$this->id]["parentpos"] : false);
1058
- }
1059
-
1060
- // Passing true to this method has the potential to leak RAM. Passing false is preferred, use with caution.
1061
- public function Children($objects = false)
1062
- {
1063
- return $this->tfn->GetChildren($this->id, $objects);
1064
- }
1065
-
1066
- public function Child($pos)
1067
- {
1068
- return $this->tfn->GetChild($this->id, $pos);
1069
- }
1070
-
1071
- public function PrevSibling()
1072
- {
1073
- return $this->tfn->GetPrevSibling($this->id);
1074
- }
1075
-
1076
- public function NextSibling()
1077
- {
1078
- return $this->tfn->GetNextSibling($this->id);
1079
- }
1080
-
1081
- public function Find($query, $cachequery = true, $firstmatch = false)
1082
- {
1083
- $result = $this->tfn->Find($query, $this->id, $cachequery, $firstmatch);
1084
- if (!$result["success"]) return $result;
1085
-
1086
- return new TagFilterNodeIterator($this->tfn, $result["ids"]);
1087
- }
1088
-
1089
- public function Implode($options = array())
1090
- {
1091
- return $this->tfn->Implode($this->id, $options);
1092
- }
1093
-
1094
- public function GetOuterHTML($mode = "html")
1095
- {
1096
- return $this->tfn->GetOuterHTML($this->id, $mode);
1097
- }
1098
-
1099
- // Set functions ruin the object.
1100
- public function SetOuterHTML($src)
1101
- {
1102
- return $this->tfn->SetOuterHTML($this->id, $src);
1103
- }
1104
-
1105
- public function GetInnerHTML($mode = "html")
1106
- {
1107
- return $this->tfn->GetInnerHTML($this->id, $mode);
1108
- }
1109
-
1110
- public function SetInnerHTML($src)
1111
- {
1112
- return $this->tfn->SetInnerHTML($this->id, $src);
1113
- }
1114
-
1115
- public function GetPlainText()
1116
- {
1117
- return $this->tfn->GetPlainText($this->id);
1118
- }
1119
-
1120
- // Set functions ruin the object.
1121
- public function SetPlainText($src)
1122
- {
1123
- return $this->tfn->SetPlainText($this->id, $src);
1124
- }
1125
- }
1126
-
1127
- class TagFilterNodeIterator implements Iterator, Countable
1128
- {
1129
- private $tfn, $ids, $x, $y;
1130
-
1131
- public function __construct($tfn, $ids)
1132
- {
1133
- $this->tfn = $tfn;
1134
- $this->ids = $ids;
1135
- $this->x = 0;
1136
- $this->y = count($ids);
1137
- }
1138
-
1139
- public function rewind()
1140
- {
1141
- $this->x = 0;
1142
- }
1143
-
1144
- public function valid()
1145
- {
1146
- return ($this->x < $this->y);
1147
- }
1148
-
1149
- public function current()
1150
- {
1151
- return $this->tfn->Get($this->ids[$this->x]);
1152
- }
1153
-
1154
- public function key()
1155
- {
1156
- return $this->ids[$this->x];
1157
- }
1158
-
1159
- public function next()
1160
- {
1161
- $this->x++;
1162
- }
1163
-
1164
- public function count()
1165
- {
1166
- return $this->y;
1167
- }
1168
-
1169
- public function Filter($query, $cachequery = true)
1170
- {
1171
- $result = $this->tfn->Filter($this->ids, $query, $cachequery);
1172
- if (!$result["success"]) return $result;
1173
-
1174
- return new TagFilterNodeIterator($this->tfn, $result["ids"]);
1175
- }
1176
- }
1177
-
1178
- // Output from TagFilter::Explode().
1179
- class TagFilterNodes
1180
- {
1181
- public $nodes, $nextid;
1182
- private $queries;
1183
-
1184
- public function __construct()
1185
- {
1186
- $this->nodes = array(
1187
- array(
1188
- "type" => "root",
1189
- "parent" => false,
1190
- "parentpos" => false,
1191
- "children" => array()
1192
- )
1193
- );
1194
-
1195
- $this->nextid = 1;
1196
- $this->queries = array();
1197
- }
1198
-
1199
- // Makes a selector suitable for Find() and Filter() by altering or removing rules. Query is not cached.
1200
- public static function MakeValidSelector($query)
1201
- {
1202
- if (!is_array($query)) $result = TagFilter::ParseSelector($query, true);
1203
- else if (isset($query["success"]) && isset($query["tokens"]))
1204
- {
1205
- $result = $query;
1206
- $result["tokens"] = TagFilter::ReorderSelectorTokens(array_reverse($result["tokens"]), true);
1207
- }
1208
- else
1209
- {
1210
- $result = array("success" => true, "tokens" => TagFilter::ReorderSelectorTokens(array_reverse($query), true));
1211
- }
1212
-
1213
- // Alter certain CSS3 tokens to equivalent tokens.
1214
- foreach ($result["tokens"] as $num => $rules)
1215
- {
1216
- foreach ($rules as $num2 => $rule)
1217
- {
1218
- if ($rule["type"] === "pseudo-class")
1219
- {
1220
- if ($rule["pseudo"] === "link") $result["tokens"][$num][$num2] = array("not" => false, "type" => "element", "namespace" => false, "tag" => "a");
1221
- else if ($rule["pseudo"] === "disabled") $result["tokens"][$num][$num2] = array("not" => false, "type" => "attr", "namespace" => false, "attr" => "disabled", "cmp" => false);
1222
- else if ($rule["pseudo"] === "enabled") $result["tokens"][$num][$num2] = array("not" => false, "type" => "attr", "namespace" => false, "attr" => "enabled", "cmp" => false);
1223
- else if ($rule["pseudo"] === "checked") $result["tokens"][$num][$num2] = array("not" => false, "type" => "attr", "namespace" => false, "attr" => "checked", "cmp" => false);
1224
- }
1225
- }
1226
- }
1227
-
1228
- // Reorder the tokens so that the order is simple for output.
1229
- $tokens = TagFilter::ReorderSelectorTokens(array_reverse($result["tokens"]), true, array("element" => array(), "id" => array(), "class" => array(), "attr" => array(), "pseudo-class" => array(), "pseudo-element" => array()), false);
1230
-
1231
- // Generate a duplicate-free Find()-safe string.
1232
- $result = array();
1233
- foreach ($tokens as $rules)
1234
- {
1235
- $groups = array();
1236
- $strs = array();
1237
- $rules = array_reverse($rules);
1238
- $y = count($rules);
1239
- for ($x = 0; $x < $y; $x++)
1240
- {
1241
- $str = "";
1242
-
1243
- if (isset($rules[$x]["not"]) && $rules[$x]["not"]) $str .= ":not(";
1244
-
1245
- switch ($rules[$x]["type"])
1246
- {
1247
- case "id": $str .= "#" . $rules[$x]["id"]; $valid = true; break;
1248
- case "element": $str .= ($rules[$x]["namespace"] !== false ? $rules[$x]["namespace"] . "|" : "") . strtolower($rules[$x]["tag"]); $valid = true; break;
1249
- case "class": $str .= "." . $rules[$x]["class"]; $valid = true; break;
1250
- case "attr": $str .= "[" . ($rules[$x]["namespace"] !== false ? $rules[$x]["namespace"] . "|" : "") . strtolower($rules[$x]["attr"]) . ($rules[$x]["cmp"] !== false ? $rules[$x]["cmp"] . "\"" . str_replace("\"", "\\\"", $rules[$x]["val"]) . "\"" : "") . "]"; $valid = true; break;
1251
- case "pseudo-class":
1252
- {
1253
- $pc = $rules[$x]["pseudo"];
1254
- $valid = ($pc === "first-child" || $pc === "last-child" || $pc === "only-child" || $pc === "nth-child" || $pc === "nth-last-child" || $pc === "first-child-all" || $pc === "last-child-all" || $pc === "only-child-all" || $pc === "nth-child-all" || $pc === "nth-last-child-all" || $pc === "first-of-type" || $pc === "last-of-type" || $pc === "only-of-type" || $pc === "nth-of-type" || $pc === "nth-last-of-type" || $pc === "empty");
1255
-
1256
- if ($valid && substr($rules[$x]["pseudo"], 0, 4) === "nth-" && (!isset($rules[$x]["a"]) || !isset($rules[$x]["b"]))) $valid = false;
1257
-
1258
- break;
1259
- }
1260
- case "combine":
1261
- {
1262
- switch ($rules[$x]["combine"])
1263
- {
1264
- case "prev-parent": $groups[] = implode("", $strs); $groups[] = ">"; $strs = array(); $valid = true; break;
1265
- case "any-parent": $groups[] = implode("", $strs); $strs = array(); $valid = true; break;
1266
- case "prev-sibling": $groups[] = implode("", $strs); $groups[] = "+"; $strs = array(); $valid = true; break;
1267
- case "any-prev-sibling": $groups[] = implode("", $strs); $groups[] = "~"; $strs = array(); $valid = true; break;
1268
- default: $valid = false;
1269
- }
1270
-
1271
- break;
1272
- }
1273
- default: $valid = false; break;
1274
- }
1275
-
1276
- if (!$valid) break;
1277
-
1278
- if (isset($rules[$x]["not"]) && $rules[$x]["not"]) $str .= ")";
1279
-
1280
- $strs[$str] = $str;
1281
- }
1282
-
1283
- if ($x == $y)
1284
- {
1285
- if (count($strs)) $groups[] = implode("", $strs);
1286
- $str = implode(" ", $groups);
1287
- $result[$str] = $str;
1288
- }
1289
- }
1290
-
1291
- return implode(", ", $result);
1292
- }
1293
-
1294
- public function Find($query, $id = 0, $cachequery = true, $firstmatch = false)
1295
- {
1296
- $id = (int)$id;
1297
- if (!isset($this->nodes[$id])) return array("success" => false, "error" => "Invalid initial ID.", "errorcode" => "invalid_init_id");
1298
-
1299
- if (isset($this->queries[$query])) $result = $this->queries[$query];
1300
- else
1301
- {
1302
- if (!is_array($query)) $result = TagFilter::ParseSelector($query, true);
1303
- else if (isset($query["success"]) && isset($result["selector"]) && isset($query["tokens"]))
1304
- {
1305
- $result = $query;
1306
- $result["tokens"] = TagFilter::ReorderSelectorTokens($result["tokens"], true);
1307
-
1308
- $query = $result["selector"];
1309
- }
1310
- else
1311
- {
1312
- $result = array("success" => true, "tokens" => TagFilter::ReorderSelectorTokens($query, true));
1313
-
1314
- $cachequery = false;
1315
- }
1316
-
1317
- if ($cachequery)
1318
- {
1319
- foreach ($this->queries as $key => $val)
1320
- {
1321
- if (count($this->queries) < 25) break;
1322
-
1323
- unset($this->queries[$key]);
1324
- }
1325
-
1326
- $this->queries[$query] = $result;
1327
- }
1328
- }
1329
-
1330
- if (!$result["success"]) return $result;
1331
-
1332
- $rules = $result["tokens"];
1333
- $numrules = count($rules);
1334
-
1335
- $result = array();
1336
- $childcache = array();
1337
- $oftypecache = array();
1338
- $rootid = $id;
1339
- $pos = 0;
1340
- $maxpos = (isset($this->nodes[$id]["children"]) && is_array($this->nodes[$id]["children"]) ? count($this->nodes[$id]["children"]) : 0);
1341
- do
1342
- {
1343
- if (!$pos && $this->nodes[$id]["type"] === "element")
1344
- {
1345
- // Attempt to match a rule.
1346
- for ($x = 0; $x < $numrules; $x++)
1347
- {
1348
- $id2 = $id;
1349
- $y = count($rules[$x]);
1350
- for ($x2 = 0; $x2 < $y; $x2++)
1351
- {
1352
- if ($this->nodes[$id2]["type"] === "content" || $this->nodes[$id2]["type"] === "comment")
1353
- {
1354
- // Always backtrack at non-element nodes since the rules are element based.
1355
- $backtrack = !(isset($rules[$x][$x2]["not"]) && $rules[$x][$x2]["not"]);
1356
- }
1357
- else if (isset($rules[$x][$x2]["namespace"]) && $rules[$x][$x2]["namespace"] !== false && $rules[$x][$x2]["namespace"] !== "*" && (($rules[$x][$x2]["namespace"] === "" && strpos($this->nodes[$id2]["tag"], ":") !== false) || ($rules[$x][$x2]["namespace"] !== "" && strcasecmp(substr($this->nodes[$id2]["tag"], 0, strlen($rules[$x][$x2]["namespace"]) + 1), $rules[$x][$x2]["namespace"] . ":") !== 0)))
1358
- {
1359
- $backtrack = true;
1360
- }
1361
- else
1362
- {
1363
- switch ($rules[$x][$x2]["type"])
1364
- {
1365
- case "id": $backtrack = (!isset($this->nodes[$id2]["attrs"]["id"]) || $this->nodes[$id2]["attrs"]["id"] !== $rules[$x][$x2]["id"]); break;
1366
- case "element": $backtrack = (strcasecmp($this->nodes[$id2]["tag"], (isset($rules[$x][$x2]["namespace"]) && $rules[$x][$x2]["namespace"] !== false ? $rules[$x][$x2]["namespace"] . ":" : "") . $rules[$x][$x2]["tag"]) !== 0); break;
1367
- case "class": $backtrack = (!isset($this->nodes[$id2]["attrs"]["class"]) || !isset($this->nodes[$id2]["attrs"]["class"][$rules[$x][$x2]["class"]])); break;
1368
- case "attr":
1369
- {
1370
- $attr = strtolower($rules[$x][$x2]["attr"]);
1371
- if (!isset($this->nodes[$id2]["attrs"][$attr])) $backtrack = true;
1372
- else
1373
- {
1374
- $val = $this->nodes[$id2]["attrs"][$attr];
1375
- if (is_array($val)) $val = implode(" ", $val);
1376
-
1377
- switch ($rules[$x][$x2]["cmp"])
1378
- {
1379
- case "=": $backtrack = ($val !== $rules[$x][$x2]["val"]); break;
1380
- case "^=": $backtrack = ($rules[$x][$x2]["val"] === "" || substr($val, 0, strlen($rules[$x][$x2]["val"])) !== $rules[$x][$x2]["val"]); break;
1381
- case "$=": $backtrack = ($rules[$x][$x2]["val"] === "" || substr($val, -strlen($rules[$x][$x2]["val"])) !== $rules[$x][$x2]["val"]); break;
1382
- case "*=": $backtrack = ($rules[$x][$x2]["val"] === "" || strpos($val, $rules[$x][$x2]["val"]) === false); break;
1383
- case "~=": $backtrack = ($rules[$x][$x2]["val"] === "" || strpos($rules[$x][$x2]["val"], " ") !== false || strpos(" " . $val . " ", " " . $rules[$x][$x2]["val"] . " ") === false); break;
1384
- case "|=": $backtrack = ($rules[$x][$x2]["val"] === "" || ($val !== $rules[$x][$x2]["val"] && substr($val, 0, strlen($rules[$x][$x2]["val"]) + 1) !== $rules[$x][$x2]["val"] . "-")); break;
1385
- default: $backtrack = false; break;
1386
- }
1387
- }
1388
-
1389
- break;
1390
- }
1391
- case "pseudo-class":
1392
- {
1393
- // Handle various bits of common code.
1394
- $pid = $this->nodes[$id2]["parent"];
1395
- $pnum = count($this->nodes[$pid]["children"]);
1396
-
1397
- $nth = (substr($rules[$x][$x2]["pseudo"], 0, 4) === "nth-");
1398
- if ($nth && (!isset($rules[$x][$x2]["a"]) || !isset($rules[$x][$x2]["b"]))) return array("success" => false, "error" => "Pseudo-class ':" . $rules[$x][$x2]["pseudo"] . "(n)' requires an expression for 'n'.", "errorcode" => "missing_pseudo_class_expression");
1399
-
1400
- if (substr($rules[$x][$x2]["pseudo"], -6) === "-child")
1401
- {
1402
- if (!isset($childcache[$id2]))
1403
- {
1404
- $children = 0;
1405
- foreach ($this->nodes[$pid]["children"] as $id3)
1406
- {
1407
- if ($this->nodes[$id3]["type"] === "element")
1408
- {
1409
- $childcache[$id3] = array("cx" => $children);
1410
-
1411
- $children++;
1412
- }
1413
- }
1414
-
1415
- foreach ($this->nodes[$pid]["children"] as $id3)
1416
- {
1417
- if ($this->nodes[$id3]["type"] === "element") $childcache[$id3]["cy"] = $children;
1418
- }
1419
- }
1420
-
1421
- $cx = $childcache[$id2]["cx"];
1422
- $cy = $childcache[$id2]["cy"];
1423
- }
1424
-
1425
- if (substr($rules[$x][$x2]["pseudo"], -8) === "-of-type")
1426
- {
1427
- if (!isset($oftypecache[$id2]))
1428
- {
1429
- $types = array();
1430
- foreach ($this->nodes[$pid]["children"] as $id3)
1431
- {
1432
- if ($this->nodes[$id3]["type"] === "element")
1433
- {
1434
- $tag = $this->nodes[$id3]["tag"];
1435
- if (!isset($types[$tag])) $types[$tag] = 0;
1436
-
1437
- $oftypecache[$id3] = array("tx" => $types[$tag]);
1438
-
1439
- $types[$tag]++;
1440
- }
1441
- }
1442
-
1443
- foreach ($this->nodes[$pid]["children"] as $id3)
1444
- {
1445
- if ($this->nodes[$id3]["type"] === "element")
1446
- {
1447
- $tag = $this->nodes[$id3]["tag"];
1448
- $oftypecache[$id3]["ty"] = $types[$tag];
1449
- }
1450
- }
1451
- }
1452
-
1453
- $tx = $oftypecache[$id2]["tx"];
1454
- $ty = $oftypecache[$id2]["ty"];
1455
- }
1456
-
1457
- switch ($rules[$x][$x2]["pseudo"])
1458
- {
1459
- case "first-child": $backtrack = ($cx !== 0); break;
1460
- case "last-child": $backtrack = ($cx !== $cy - 1); break;
1461
- case "only-child": $backtrack = ($cy !== 1); break;
1462
- case "nth-child": $px = $cx; break;
1463
- case "nth-last-child": $px = $cy - $cx - 1; break;
1464
- case "first-child-all": $backtrack = ($this->nodes[$id2]["parentpos"] !== 0); break;
1465
- case "last-child-all": $backtrack = ($this->nodes[$id2]["parentpos"] !== $pnum - 1); break;
1466
- case "only-child-all": $backtrack = ($pnum !== 1); break;
1467
- case "nth-child-all": $px = $this->nodes[$id2]["parentpos"]; break;
1468
- case "nth-last-child-all": $px = $pnum - $this->nodes[$id2]["parentpos"] - 1; break;
1469
- case "first-of-type": $backtrack = ($tx !== 0); break;
1470
- case "last-of-type": $backtrack = ($tx !== $ty - 1); break;
1471
- case "only-of-type": $backtrack = ($ty !== 1); break;
1472
- case "nth-of-type": $px = $tx; break;
1473
- case "nth-last-of-type": $px = $ty - $tx - 1; break;
1474
- case "empty":
1475
- {
1476
- $backtrack = false;
1477
- foreach ($this->nodes[$id2]["children"] as $id3)
1478
- {
1479
- if ($this->nodes[$id3]["type"] === "element" || ($this->nodes[$id3]["type"] === "content" && trim($this->nodes[$id3]["text"]) !== ""))
1480
- {
1481
- $backtrack = true;
1482
-
1483
- break;
1484
- }
1485
- }
1486
-
1487
- break;
1488
- }
1489
- default: return array("success" => false, "error" => "Unknown/Unsupported pseudo-class ':" . $rules[$x][$x2]["pseudo"] . "'.", "errorcode" => "unknown_unsupported_pseudo_class");
1490
- }
1491
-
1492
- if ($nth)
1493
- {
1494
- // Calculated expression: a * n + b - 1 = x
1495
- // Solved for n: n = (x + 1 - b) / a
1496
- // Where 'n' is a non-negative integer. When 'a' is 0, solve for 'b' instead.
1497
- $pa = $rules[$x][$x2]["a"];
1498
- $pb = $rules[$x][$x2]["b"];
1499
-
1500
- if ($pa == 0) $backtrack = ($pb != $px + 1);
1501
- else
1502
- {
1503
- $pn = (($px + 1 - $pb) / $pa);
1504
-
1505
- $backtrack = ($pn < 0 || $pn - (int)$pn > 0.000001);
1506
- }
1507
- }
1508
-
1509
- break;
1510
- }
1511
- case "pseudo-element": return array("success" => false, "error" => "Pseudo-elements are not supported. Found '::" . $rules[$x][$x2]["pseudo"] . "'.", "errorcode" => "unsupported_selector_type");
1512
- case "combine":
1513
- {
1514
- switch ($rules[$x][$x2]["combine"])
1515
- {
1516
- case "prev-parent":
1517
- case "any-parent":
1518
- {
1519
- $backtrack = ($id2 === $rootid || !$this->nodes[$id2]["parent"]);
1520
- if (!$backtrack) $id2 = $this->nodes[$id2]["parent"];
1521
-
1522
- break;
1523
- }
1524
- case "prev-sibling":
1525
- case "any-prev-sibling":
1526
- {
1527
- $backtrack = ($this->nodes[$id2]["parentpos"] == 0);
1528
- if (!$backtrack) $id2 = $this->nodes[$this->nodes[$id2]["parent"]]["children"][$this->nodes[$id2]["parentpos"] - 1];
1529
-
1530
- break;
1531
- }
1532
- default: return array("success" => false, "error" => "Unknown combiner " . $rules[$x][$x2]["pseudo"] . ".", "errorcode" => "unknown_combiner");
1533
- }
1534
-
1535
- // For unknown parent/sibling combiners such as '~', use the rule stack to allow for backtracking to try another path if a match fails (e.g. h1 p ~ p).
1536
- $rules[$x][$x2]["lastid"] = $id2;
1537
-
1538
- break;
1539
- }
1540
- default: return array("success" => false, "error" => "Unknown selector type '" . $rules[$x][$x2]["type"] . "'.", "errorcode" => "unknown_selector_type");
1541
- }
1542
- }
1543
-
1544
- if (isset($rules[$x][$x2]["not"]) && $rules[$x][$x2]["not"]) $backtrack = !$backtrack;
1545
-
1546
- // Backtrack through the rule to an unknown parent/sibling combiner.
1547
- if ($backtrack)
1548
- {
1549
- if ($x2)
1550
- {
1551
- for ($x2--; $x2; $x2--)
1552
- {
1553
- if ($rules[$x][$x2]["type"] === "combine")
1554
- {
1555
- if ($rules[$x][$x2]["combine"] === "any-parent")
1556
- {
1557
- $id2 = $rules[$x][$x2]["lastid"];
1558
- if ($id2 !== $rootid && $this->nodes[$id2]["parent"])
1559
- {
1560
- $id2 = $this->nodes[$id2]["parent"];
1561
- $rules[$x][$x2]["lastid"] = $id2;
1562
-
1563
- break;
1564
- }
1565
- }
1566
- else if ($rules[$x][$x2]["combine"] === "any-prev-sibling")
1567
- {
1568
- $id2 = $rules[$x][$x2]["lastid"];
1569
- if ($this->nodes[$id2]["parentpos"] != 0)
1570
- {
1571
- $id2 = $this->nodes[$this->nodes[$id2]["parent"]]["children"][$this->nodes[$id2]["parentpos"] - 1];
1572
- $rules[$x][$x2]["lastid"] = $id2;
1573
-
1574
- break;
1575
- }
1576
- }
1577
- }
1578
- }
1579
- }
1580
-
1581
- if (!$x2) break;
1582
- }
1583
- }
1584
-
1585
- // Match found.
1586
- if ($x2 === $y)
1587
- {
1588
- $result[] = $id;
1589
-
1590
- if ($firstmatch) return array("success" => true, "ids" => $result);
1591
-
1592
- break;
1593
- }
1594
- }
1595
- }
1596
-
1597
- if ($pos >= $maxpos)
1598
- {
1599
- if ($rootid === $id) break;
1600
-
1601
- $pos = $this->nodes[$id]["parentpos"] + 1;
1602
- $id = $this->nodes[$id]["parent"];
1603
- $maxpos = count($this->nodes[$id]["children"]);
1604
- }
1605
- else
1606
- {
1607
- $id = $this->nodes[$id]["children"][$pos];
1608
- $pos = 0;
1609
- $maxpos = (isset($this->nodes[$id]["children"]) && is_array($this->nodes[$id]["children"]) ? count($this->nodes[$id]["children"]) : 0);
1610
- }
1611
- } while (1);
1612
-
1613
- return array("success" => true, "ids" => $result);
1614
- }
1615
-
1616
- // Filter results from Find() based on a matching query.
1617
- public function Filter($ids, $query, $cachequery = true)
1618
- {
1619
- if (!is_array($ids)) $ids = array($ids);
1620
-
1621
- // Handle lazy chaining from both Find() and Filter().
1622
- if (isset($ids["success"]))
1623
- {
1624
- if (!$ids["success"]) return $ids;
1625
- if (!isset($ids["ids"])) return array("success" => false, "error" => "Bad filter input.", "invalid_filter_ids");
1626
-
1627
- $ids = $ids["ids"];
1628
- }
1629
-
1630
- $ids2 = array();
1631
- if (is_string($query) && strtolower(substr($query, 0, 10)) === "/contains:")
1632
- {
1633
- $query = substr($query, 10);
1634
- foreach ($ids as $id)
1635
- {
1636
- if (strpos($this->GetPlainText($id), $query) !== false) $ids2[] = $id;
1637
- }
1638
- }
1639
- else if (is_string($query) && strtolower(substr($query, 0, 11)) === "/~contains:")
1640
- {
1641
- $query = substr($query, 11);
1642
- foreach ($ids as $id)
1643
- {
1644
- if (stripos($this->GetPlainText($id), $query) !== false) $ids2[] = $id;
1645
- }
1646
- }
1647
- else
1648
- {
1649
- foreach ($ids as $id)
1650
- {
1651
- $result = $this->Find($query, $id, $cachequery, true);
1652
- if ($result["success"] && count($result["ids"])) $ids2[] = $id;
1653
- }
1654
- }
1655
-
1656
- return array("success" => true, "ids" => $ids2);
1657
- }
1658
-
1659
- // Convert all or some of the nodes back into a string.
1660
- public function Implode($id, $options = array())
1661
- {
1662
- $id = (int)$id;
1663
- if (!isset($this->nodes[$id])) return "";
1664
-
1665
- if (!isset($options["include_id"])) $options["include_id"] = true;
1666
- if (!isset($options["types"])) $options["types"] = "element,content,comment";
1667
- if (!isset($options["output_mode"])) $options["output_mode"] = "html";
1668
- if (!isset($options["post_elements"])) $options["post_elements"] = array();
1669
- if (!isset($options["no_content_elements"])) $options["no_content_elements"] = array("script" => true, "style" => true);
1670
- if (!isset($options["charset"])) $options["charset"] = "UTF-8";
1671
- $options["charset"] = strtoupper($options["charset"]);
1672
-
1673
- $types2 = explode(",", $options["types"]);
1674
- $types = array();
1675
- foreach ($types2 as $type)
1676
- {
1677
- $type = trim($type);
1678
- if ($type !== "") $types[$type] = true;
1679
- }
1680
-
1681
- $result = "";
1682
- $include = (bool)$options["include_id"];
1683
- $rootid = $id;
1684
- $pos = 0;
1685
- $maxpos = (isset($this->nodes[$id]["children"]) && is_array($this->nodes[$id]["children"]) ? count($this->nodes[$id]["children"]) : 0);
1686
- do
1687
- {
1688
- if (!$pos && isset($types[$this->nodes[$id]["type"]]))
1689
- {
1690
- switch ($this->nodes[$id]["type"])
1691
- {
1692
- case "element":
1693
- {
1694
- if ($include || $rootid != $id)
1695
- {
1696
- $result .= "<" . $this->nodes[$id]["tag"];
1697
- foreach ($this->nodes[$id]["attrs"] as $key => $val)
1698
- {
1699
- $result .= " " . $key;
1700
-
1701
- if (is_array($val)) $val = implode(" ", $val);
1702
- if (is_string($val)) $result .= "=\"" . htmlspecialchars($val, ENT_COMPAT | ENT_HTML5, $options["charset"]) . "\"";
1703
- }
1704
- $result .= (!$maxpos && $options["output_mode"] === "xml" ? " />" : ">");
1705
- }
1706
-
1707
- break;
1708
- }
1709
- case "content":
1710
- case "comment":
1711
- {
1712
- if (isset($types["element"]) || !isset($this->nodes[$this->nodes[$id]["parent"]]["tag"]) || !isset($options["no_content_elements"][$this->nodes[$this->nodes[$id]["parent"]]["tag"]])) $result .= $this->nodes[$id]["text"];
1713
-
1714
- break;
1715
- }
1716
- default: break;
1717
- }
1718
- }
1719
-
1720
- if ($pos >= $maxpos)
1721
- {
1722
- if ($this->nodes[$id]["type"] === "element" && is_array($this->nodes[$id]["children"]))
1723
- {
1724
- if (($include || $rootid != $id) && isset($types[$this->nodes[$id]["type"]])) $result .= "</" . $this->nodes[$id]["tag"] . ">";
1725
- }
1726
-
1727
- if ($this->nodes[$id]["type"] === "element" && isset($options["post_elements"][$this->nodes[$id]["tag"]])) $result .= $options["post_elements"][$this->nodes[$id]["tag"]];
1728
-
1729
- if ($rootid === $id) break;
1730
-
1731
- $pos = $this->nodes[$id]["parentpos"] + 1;
1732
- $id = $this->nodes[$id]["parent"];
1733
- $maxpos = count($this->nodes[$id]["children"]);
1734
- }
1735
- else
1736
- {
1737
- $id = $this->nodes[$id]["children"][$pos];
1738
- $pos = 0;
1739
- $maxpos = (isset($this->nodes[$id]["children"]) && is_array($this->nodes[$id]["children"]) ? count($this->nodes[$id]["children"]) : 0);
1740
- }
1741
- } while (1);
1742
-
1743
- return $result;
1744
- }
1745
-
1746
- // Object-oriented access methods. Only Get() supports multiple IDs.
1747
- public function Get($id = 0)
1748
- {
1749
- if (is_array($id))
1750
- {
1751
- if (isset($id["success"]) && $id["ids"]) $id = $id["ids"];
1752
-
1753
- $result = array();
1754
- foreach ($id as $id2) $result[] = $this->Get($id2);
1755
-
1756
- return $result;
1757
- }
1758
-
1759
- return ($id !== false && isset($this->nodes[$id]) ? new TagFilterNode($this, $id) : false);
1760
- }
1761
-
1762
- public function GetParent($id)
1763
- {
1764
- return ($id !== false && isset($this->nodes[$id]) && isset($this->nodes[$this->nodes[$id]["parent"]]) ? new TagFilterNode($this, $this->nodes[$id]["parent"]) : false);
1765
- }
1766
-
1767
- public function GetChildren($id, $objects = false)
1768
- {
1769
- if (!isset($this->nodes[$id]) || !isset($this->nodes[$id]["children"]) || !is_array($this->nodes[$id]["children"])) return false;
1770
-
1771
- return ($objects ? $this->Get($this->nodes[$id]["children"]) : $this->nodes[$id]["children"]);
1772
- }
1773
-
1774
- public function GetChild($id, $pos)
1775
- {
1776
- if (!isset($this->nodes[$id]) || !isset($this->nodes[$id]["children"]) || !is_array($this->nodes[$id]["children"])) return false;
1777
-
1778
- $pos = (int)$pos;
1779
- $y = count($this->nodes[$id]["children"]);
1780
- if ($pos < 0) $pos = $y + $pos;
1781
- if ($pos < 0 || $pos > $y - 1) return false;
1782
-
1783
- return $this->Get($this->nodes[$id]["children"][$pos]);
1784
- }
1785
-
1786
- public function GetPrevSibling($id)
1787
- {
1788
- if (!isset($this->nodes[$id]) || $this->nodes[$id]["parentpos"] == 0) return false;
1789
-
1790
- return $this->Get($this->nodes[$this->nodes[$id]["parent"]]["children"][$this->nodes[$id]["parentpos"] - 1]);
1791
- }
1792
-
1793
- public function GetNextSibling($id)
1794
- {
1795
- if ($id === false || !isset($this->nodes[$id]) || $this->nodes[$id]["parentpos"] >= count($this->nodes[$this->nodes[$id]["parent"]]["children"]) - 1) return false;
1796
-
1797
- return $this->Get($this->nodes[$this->nodes[$id]["parent"]]["children"][$this->nodes[$id]["parentpos"] + 1]);
1798
- }
1799
-
1800
- public function GetTag($id)
1801
- {
1802
- return (isset($this->nodes[$id]) && $this->nodes[$id]["type"] === "element" ? $this->nodes[$id]["tag"] : false);
1803
- }
1804
-
1805
- public function SetText($id, $val)
1806
- {
1807
- if (isset($this->nodes[$id]) && ($this->nodes[$id]["type"] === "content" || $this->nodes[$id]["type"] === "comment")) $this->nodes[$id]["text"] = (string)$val;
1808
- }
1809
-
1810
- public function GetText($id)
1811
- {
1812
- return (isset($this->nodes[$id]) && ($this->nodes[$id]["type"] === "content" || $this->nodes[$id]["type"] === "comment") ? $this->nodes[$id]["text"] : false);
1813
- }
1814
-
1815
- public function Move($src, $newpid, $newpos)
1816
- {
1817
- $newpid = (int)$newpid;
1818
- if (!isset($this->nodes[$newpid]) || !isset($this->nodes[$newpid]["children"]) || !is_array($this->nodes[$newpid]["children"])) return false;
1819
-
1820
- $newpos = (is_bool($newpos) ? count($this->nodes[$newpid]["children"]) : (int)$newpos);
1821
- if ($newpos < 0) $newpos = count($this->nodes[$newpid]["children"]) + $newpos;
1822
- if ($newpos < 0) $newpos = 0;
1823
- if ($newpos > count($this->nodes[$newpid]["children"])) $newpos = count($this->nodes[$newpid]["children"]);
1824
-
1825
- if ($src instanceof TagFilterNodes)
1826
- {
1827
- if ($src === $this) return false;
1828
-
1829
- // Bulk node import. Doesn't remove source nodes.
1830
- foreach ($src->nodes as $id => $node)
1831
- {
1832
- if ($node["type"] === "element" || $node["type"] === "content" || $node["type"] === "comment")
1833
- {
1834
- $node["parent"] += $this->nextid - 1;
1835
-
1836
- if (isset($node["children"]) && is_array($node["children"]))
1837
- {
1838
- foreach ($node["children"] as $pos => $id2) $node["children"][$pos] += $this->nextid - 1;
1839
- }
1840
-
1841
- $this->nodes[$id + $this->nextid - 1] = $node;
1842
- }
1843
- }
1844
-
1845
- // Merge root children.
1846
- foreach ($src->nodes[0]["children"] as $pos => $id)
1847
- {
1848
- $this->nodes[$id + $this->nextid - 1]["parent"] = $newpid;
1849
- array_splice($this->nodes[$newpid]["children"], $newpos + $pos, 0, array($id + $this->nextid - 1));
1850
- }
1851
-
1852
- $this->RealignChildren($newpid, $newpos);
1853
-
1854
- $this->nextid += $src->nextid - 1;
1855
- }
1856
- else if (is_array($src))
1857
- {
1858
- // Attach the array to the position if it is valid.
1859
- if (!isset($src["type"])) return false;
1860
-
1861
- switch ($src["type"])
1862
- {
1863
- case "element":
1864
- {
1865
- if (!isset($src["tag"]) || !isset($src["attrs"]) || !is_array($src["attrs"]) || !isset($src["children"])) return false;
1866
-
1867
- $src["tag"] = (string)$src["tag"];
1868
- $src["parent"] = $newpid;
1869
-
1870
- break;
1871
- }
1872
- case "content":
1873
- case "comment":
1874
- {
1875
- if (!isset($src["text"]) || isset($src["children"])) return false;
1876
-
1877
- $src["text"] = (string)$src["text"];
1878
-
1879
- break;
1880
- }
1881
- default: return false;
1882
- }
1883
-
1884
- array_splice($this->nodes[$newpid]["children"], $newpos, 0, array($this->nextid));
1885
- $this->RealignChildren($newpid, $newpos);
1886
- $this->nextid++;
1887
- }
1888
- else if (is_string($src))
1889
- {
1890
- return $this->Move(TagFilter::Explode($src, TagFilter::GetHTMLOptions()), $newpid, $newpos);
1891
- }
1892
- else
1893
- {
1894
- // Reparents an internal id.
1895
- $id = (int)$src;
1896
-
1897
- if (!$id || !isset($this->nodes[$id])) return false;
1898
-
1899
- // Don't allow reparenting to a child node.
1900
- $id2 = $newpid;
1901
- while ($id2)
1902
- {
1903
- if ($id === $id2) return false;
1904
-
1905
- $id2 = $this->nodes[$id2]["parent"];
1906
- }
1907
-
1908
- // Detach.
1909
- array_splice($this->nodes[$this->nodes[$id]["parent"]]["children"], $this->nodes[$id]["parentpos"], 1);
1910
- $this->RealignChildren($this->nodes[$id]["parent"], $this->nodes[$id]["parentpos"]);
1911
-
1912
- // Attach.
1913
- array_splice($this->nodes[$newpid]["children"], $newpos, 0, array($id));
1914
- $this->RealignChildren($newpid, $newpos);
1915
- }
1916
-
1917
- return true;
1918
- }
1919
-
1920
- // When $keepchildren is true, the node's children are moved into the parent of the node being removed.
1921
- public function Remove($id, $keepchildren = false)
1922
- {
1923
- $id = (int)$id;
1924
- if (!isset($this->nodes[$id])) return;
1925
-
1926
- if (!$id)
1927
- {
1928
- if (!$keepchildren)
1929
- {
1930
- // Reset all nodes.
1931
- $this->nodes = array(
1932
- array(
1933
- "type" => "root",
1934
- "parent" => false,
1935
- "parentpos" => false,
1936
- "children" => array()
1937
- )
1938
- );
1939
-
1940
- $this->nextid = 1;
1941
- }
1942
- }
1943
- else
1944
- {
1945
- // Detach the node from the parent.
1946
- $pid = $this->nodes[$id]["parent"];
1947
- $pos = $this->nodes[$id]["parentpos"];
1948
-
1949
- if ($keepchildren)
1950
- {
1951
- // Reparent the children and attach them to the new parent.
1952
- if (isset($this->nodes[$id]["children"]) && is_array($this->nodes[$id]["children"]))
1953
- {
1954
- foreach ($this->nodes[$id]["children"] as $cid) $this->nodes[$cid]["parent"] = $pid;
1955
- array_splice($this->nodes[$pid]["children"], $pos, 1, $this->nodes[$id]["children"]);
1956
- }
1957
- else
1958
- {
1959
- array_splice($this->nodes[$pid]["children"], $pos, 1);
1960
- }
1961
-
1962
- $this->RealignChildren($pid, $pos);
1963
-
1964
- unset($this->nodes[$id]);
1965
- }
1966
- else
1967
- {
1968
- array_splice($this->nodes[$pid]["children"], $pos, 1);
1969
-
1970
- $this->RealignChildren($pid, $pos);
1971
-
1972
- // Remove node and all children.
1973
- $rootid = $id;
1974
- $pos = (isset($this->nodes[$id]["children"]) && is_array($this->nodes[$id]["children"]) ? count($this->nodes[$id]["children"]) : 0);
1975
- do
1976
- {
1977
- if (!$pos)
1978
- {
1979
- $pid = $this->nodes[$id]["parent"];
1980
- $pos = $this->nodes[$id]["parentpos"];
1981
-
1982
- unset($this->nodes[$id]);
1983
- if ($rootid === $id) break;
1984
-
1985
- $id = $pid;
1986
- }
1987
- else
1988
- {
1989
- $id = $this->nodes[$id]["children"][$pos - 1];
1990
- $pos = (isset($this->nodes[$id]["children"]) && is_array($this->nodes[$id]["children"]) ? count($this->nodes[$id]["children"]) : 0);
1991
- }
1992
- } while (1);
1993
- }
1994
- }
1995
- }
1996
-
1997
- public function Replace($id, $src, $inneronly = false)
1998
- {
1999
- $id = (int)$id;
2000
- if (!isset($this->nodes[$id])) return false;
2001
-
2002
- if ($inneronly)
2003
- {
2004
- // Remove children.
2005
- if (!isset($this->nodes[$id]["children"]) || !is_array($this->nodes[$id]["children"])) return false;
2006
-
2007
- while (count($this->nodes[$id]["children"])) $this->Remove($this->nodes[$id]["children"][0]);
2008
-
2009
- $newpid = $id;
2010
- $newpos = 0;
2011
- }
2012
- else
2013
- {
2014
- $newpid = $this->nodes[$id]["parent"];
2015
- $newpos = $this->nodes[$id]["parentpos"];
2016
-
2017
- $this->Remove($id);
2018
- }
2019
-
2020
- return $this->Move($src, $newpid, $newpos);
2021
- }
2022
-
2023
- private static function SplitAt_CopyNode($nodes, &$pid, $node)
2024
- {
2025
- // Copy the node.
2026
- $node["parent"] = $pid;
2027
- $node["parentpos"] = count($nodes->nodes[$pid]["children"]);
2028
- if (isset($node["children"])) $node["children"] = (is_array($node["children"]) ? array() : false);
2029
-
2030
- // Attach the node.
2031
- $nodes->nodes[$nodes->nextid] = $node;
2032
- $nodes->nodes[$pid]["children"][] = $nodes->nextid;
2033
-
2034
- $pid = $nodes->nextid;
2035
-
2036
- $nodes->nextid++;
2037
- }
2038
-
2039
- public function SplitAt($ids, $keepidparents = false)
2040
- {
2041
- $ids2 = array();
2042
- if (!is_array($ids)) $ids = array($ids);
2043
- foreach ($ids as $id) $ids2[(int)$id] = true;
2044
- unset($ids2[0]);
2045
-
2046
- $result = array();
2047
-
2048
- // Walk the entire set of nodes, cloning until an ID match occurs (if any).
2049
- $newnodes = new TagFilterNodes();
2050
- $newpid = 0;
2051
- $id = 0;
2052
- $pos = 0;
2053
- $maxpos = (isset($this->nodes[$id]["children"]) && is_array($this->nodes[$id]["children"]) ? count($this->nodes[$id]["children"]) : 0);
2054
- do
2055
- {
2056
- if (!$pos)
2057
- {
2058
- if (isset($ids2[$id]) && count($newnodes->nodes[0]["children"]))
2059
- {
2060
- // Found an ID match.
2061
- $result[] = $newnodes;
2062
- $newnodes = new TagFilterNodes();
2063
- $newpid = 0;
2064
-
2065
- if ($keepidparents instanceof TagFilterNodes)
2066
- {
2067
- $newnodes = clone $keepidparents;
2068
- $newpid = $newnodes->nextid - 1;
2069
- }
2070
- else if ($keepidparents)
2071
- {
2072
- $stack = array();
2073
- $id2 = $this->nodes[$id]["parent"];
2074
- while ($id2)
2075
- {
2076
- $stack[] = $id2;
2077
-
2078
- $id2 = $this->nodes[$id2]["parent"];
2079
- }
2080
- $stack = array_reverse($stack);
2081
- foreach ($stack as $id2)
2082
- {
2083
- self::SplitAt_CopyNode($newnodes, $newpid, $this->nodes[$id2]);
2084
- }
2085
- }
2086
- }
2087
-
2088
- if ($id) self::SplitAt_CopyNode($newnodes, $newpid, $this->nodes[$id]);
2089
- }
2090
-
2091
- if ($pos >= $maxpos)
2092
- {
2093
- if (!$id) break;
2094
-
2095
- if (isset($ids2[$id]))
2096
- {
2097
- // Start a new set of nodes.
2098
- $result[] = $newnodes;
2099
- $newnodes = new TagFilterNodes();
2100
- $newpid = 0;
2101
-
2102
- $stack = array();
2103
- $id2 = $this->nodes[$id]["parent"];
2104
- while ($id2)
2105
- {
2106
- $stack[] = $id2;
2107
-
2108
- $id2 = $this->nodes[$id2]["parent"];
2109
- }
2110
- $stack = array_reverse($stack);
2111
- foreach ($stack as $id2)
2112
- {
2113
- self::SplitAt_CopyNode($newnodes, $newpid, $this->nodes[$id2]);
2114
- }
2115
- }
2116
- else
2117
- {
2118
- $newpid = $newnodes->nodes[$newpid]["parent"];
2119
- }
2120
-
2121
- $pos = $this->nodes[$id]["parentpos"] + 1;
2122
- $id = $this->nodes[$id]["parent"];
2123
- $maxpos = count($this->nodes[$id]["children"]);
2124
- }
2125
- else
2126
- {
2127
- $id = $this->nodes[$id]["children"][$pos];
2128
- $pos = 0;
2129
- $maxpos = (isset($this->nodes[$id]["children"]) && is_array($this->nodes[$id]["children"]) ? count($this->nodes[$id]["children"]) : 0);
2130
- }
2131
- } while (1);
2132
-
2133
- if (!count($result) || count($newnodes->nodes[0]["children"])) $result[] = $newnodes;
2134
-
2135
- return $result;
2136
- }
2137
-
2138
- public function GetOuterHTML($id, $mode = "html")
2139
- {
2140
- return $this->Implode($id, array("output_mode" => $mode));
2141
- }
2142
-
2143
- public function SetOuterHTML($id, $src)
2144
- {
2145
- return $this->Replace($id, $src);
2146
- }
2147
-
2148
- public function GetInnerHTML($id, $mode = "html")
2149
- {
2150
- return $this->Implode($id, array("include_id" => false, "output_mode" => $mode));
2151
- }
2152
-
2153
- public function SetInnerHTML($id, $src)
2154
- {
2155
- return $this->Replace($id, $src, true);
2156
- }
2157
-
2158
- public function GetPlainText($id)
2159
- {
2160
- return $this->Implode($id, array("types" => "content", "post_elements" => array("p" => "\n\n", "br" => "\n")));
2161
- }
2162
-
2163
- public function SetPlainText($id, $src)
2164
- {
2165
- // Convert $src to a string.
2166
- if ($src instanceof TagFilterNodes)
2167
- {
2168
- $src = $src->GetPlainText(0);
2169
- }
2170
- else if (is_array($src))
2171
- {
2172
- $temp = new TagFilterNodes();
2173
- $temp->Move($src, 0, 0);
2174
-
2175
- $src = $temp->GetPlainText(0);
2176
- }
2177
- else if (!is_string($src))
2178
- {
2179
- $src = $this->GetPlainText((int)$src);
2180
- }
2181
-
2182
- $src = array(
2183
- "type" => "content",
2184
- "text" => (string)$src,
2185
- "parent" => false,
2186
- "parentpos" => false
2187
- );
2188
-
2189
- return $this->Replace($id, $src, true);
2190
- }
2191
-
2192
- private function RealignChildren($id, $pos)
2193
- {
2194
- $y = count($this->nodes[$id]["children"]);
2195
- for ($x = $pos; $x < $y; $x++) $this->nodes[$this->nodes[$id]["children"][$x]]["parentpos"] = $x;
2196
- }
2197
- }
2198
-
2199
- class TagFilter
2200
- {
2201
- // Internal callback function for extracting interior content of HTML 'script' and 'style' tags.
2202
- public static function HTMLSpecialTagContentCallback($stack, $final, &$tag, &$content, &$cx, $cy, &$content2, $options)
2203
- {
2204
- if (preg_match('/<\s*\/\s*' . $stack[0]["tag_name"] . '(\s*|\s+.+?)>/is', $content, $matches, PREG_OFFSET_CAPTURE, $cx))
2205
- {
2206
- $pos = $matches[0][1];
2207
-
2208
- $content2 = substr($content, $cx, $pos - $cx);
2209
- $cx = $pos;
2210
- $tag = true;
2211
-
2212
- return true;
2213
- }
2214
- else
2215
- {
2216
- if ($final)
2217
- {
2218
- $content2 = substr($content, $cx);
2219
- $cx = $cy;
2220
- }
2221
-
2222
- return false;
2223
- }
2224
- }
2225
-
2226
- public static function GetHTMLOptions()
2227
- {
2228
- $result = array(
2229
- "tag_name_map" => array(
2230
- "!doctype" => "DOCTYPE"
2231
- ),
2232
- "untouched_tag_attr_keys" => array(
2233
- "doctype" => true,
2234
- ),
2235
- "void_tags" => array(
2236
- "DOCTYPE" => true,
2237
- "area" => true,
2238
- "base" => true,
2239
- "bgsound" => true,
2240
- "br" => true,
2241
- "col" => true,
2242
- "embed" => true,
2243
- "hr" => true,
2244
- "img" => true,
2245
- "input" => true,
2246
- "keygen" => true,
2247
- "link" => true,
2248
- "menuitem" => true,
2249
- "meta" => true,
2250
- "param" => true,
2251
- "source" => true,
2252
- "track" => true,
2253
- "wbr" => true
2254
- ),
2255
- // Alternate tag internal content rules for specialized tags.
2256
- "alt_tag_content_rules" => array(
2257
- "script" => __CLASS__ . "::HTMLSpecialTagContentCallback",
2258
- "style" => __CLASS__ . "::HTMLSpecialTagContentCallback"
2259
- ),
2260
- // Stored as a map for open tag elements.
2261
- // For example, '"address" => array("p" => true)' means: When an open 'address' tag is encountered,
2262
- // look for an open 'p' tag anywhere (no '_limit') in the tag stack. Apply a closing '</p>' tag for all matches.
2263
- //
2264
- // If '_limit' is defined as a string or an array, then stack walking stops as soon as one of the specified tags is encountered.
2265
- "pre_close_tags" => array(
2266
- "body" => array("body" => true, "head" => true),
2267
-
2268
- "address" => array("p" => true),
2269
- "article" => array("p" => true),
2270
- "aside" => array("p" => true),
2271
- "blockquote" => array("p" => true),
2272
- "div" => array("p" => true),
2273
- "dl" => array("p" => true),
2274
- "fieldset" => array("p" => true),
2275
- "footer" => array("p" => true),
2276
- "form" => array("p" => true),
2277
- "h1" => array("p" => true),
2278
- "h2" => array("p" => true),
2279
- "h3" => array("p" => true),
2280
- "h4" => array("p" => true),
2281
- "h5" => array("p" => true),
2282
- "h6" => array("p" => true),
2283
- "header" => array("p" => true),
2284
- "hr" => array("p" => true),
2285
- "menu" => array("p" => true),
2286
- "nav" => array("p" => true),
2287
- "ol" => array("p" => true),
2288
- "pre" => array("p" => true),
2289
- "section" => array("p" => true),
2290
- "table" => array("p" => true),
2291
- "ul" => array("p" => true),
2292
- "p" => array("p" => true),
2293
-
2294
- "tbody" => array("_limit" => "table", "thead" => true, "tr" => true, "th" => true, "td" => true),
2295
- "tr" => array("_limit" => "table", "tr" => true, "th" => true, "td" => true),
2296
- "th" => array("_limit" => "table", "th" => true, "td" => true),
2297
- "td" => array("_limit" => "table", "th" => true, "td" => true),
2298
- "tfoot" => array("_limit" => "table", "thead" => true, "tbody" => true, "tr" => true, "th" => true, "td" => true),
2299
-
2300
- "optgroup" => array("optgroup" => true, "option" => true),
2301
- "option" => array("option" => true),
2302
-
2303
- "dd" => array("_limit" => "dl", "dd" => true, "dt" => true),
2304
- "dt" => array("_limit" => "dl", "dd" => true, "dt" => true),
2305
-
2306
- "colgroup" => array("colgroup" => true),
2307
-
2308
- "li" => array("_limit" => array("ul" => true, "ol" => true, "menu" => true, "dir" => true), "li" => true),
2309
- ),
2310
- "process_attrs" => array(
2311
- "class" => "classes",
2312
- "href" => "uri",
2313
- "src" => "uri",
2314
- "dynsrc" => "uri",
2315
- "lowsrc" => "uri",
2316
- "background" => "uri",
2317
- ),
2318
- "keep_attr_newlines" => false,
2319
- "keep_comments" => false,
2320
- "allow_namespaces" => true,
2321
- "charset" => "UTF-8",
2322
- "charset_tags" => true,
2323
- "charset_attrs" => true,
2324
- "output_mode" => "html",
2325
- "lowercase_tags" => true,
2326
- "lowercase_attrs" => true,
2327
- );
2328
-
2329
- return $result;
2330
- }
2331
-
2332
- public static function Run($content, $options = array())
2333
- {
2334
- $tfs = new TagFilterStream($options);
2335
- $tfs->Finalize();
2336
- $result = $tfs->Process($content);
2337
-
2338
- // Clean up output.
2339
- $result = trim($result);
2340
- $result = self::CleanupResults($result);
2341
-
2342
- if (function_exists("gc_mem_caches")) gc_mem_caches();
2343
-
2344
- return $result;
2345
- }
2346
-
2347
- public static function CleanupResults($content)
2348
- {
2349
- $result = str_replace("\r\n", "\n", $content);
2350
- $result = str_replace("\r", "\n", $result);
2351
- while (strpos($result, "\n\n\n") !== false) $result = str_replace("\n\n\n", "\n\n", $result);
2352
-
2353
- return $result;
2354
- }
2355
-
2356
- public static function ExplodeTagCallback($stack, &$content, $open, $tagname, &$attrs, $options)
2357
- {
2358
- if ($open)
2359
- {
2360
- $pid = (count($options["data"]->stackmap) ? $options["data"]->stackmap[0] : 0);
2361
-
2362
- $tagname2 = (isset($options["tag_name_map"][strtolower($tagname)]) ? $options["tag_name_map"][strtolower($tagname)] : $tagname);
2363
-
2364
- $options["nodes"]->nodes[$options["nodes"]->nextid] = array(
2365
- "type" => "element",
2366
- "tag" => $tagname,
2367
- "attrs" => $attrs,
2368
- "parent" => $pid,
2369
- "parentpos" => count($options["nodes"]->nodes[$pid]["children"]),
2370
- "children" => (isset($options["void_tags"][$tagname2]) ? false : array())
2371
- );
2372
-
2373
- $options["nodes"]->nodes[$pid]["children"][] = $options["nodes"]->nextid;
2374
-
2375
- // Append non-void tags to the ID stack.
2376
- if (!isset($options["void_tags"][$tagname2])) array_unshift($options["data"]->stackmap, $options["nodes"]->nextid);
2377
-
2378
- $options["nodes"]->nextid++;
2379
- }
2380
- else
2381
- {
2382
- array_shift($options["data"]->stackmap);
2383
- }
2384
-
2385
- return array("keep_tag" => false, "keep_interior" => false);
2386
- }
2387
-
2388
- public static function ExplodeContentCallback($stack, $result, &$content, $options)
2389
- {
2390
- if ($content === "") return;
2391
-
2392
- $type = (substr($content, 0, 5) === "<!-- " ? "comment" : "content");
2393
- $pid = (count($options["data"]->stackmap) ? $options["data"]->stackmap[0] : 0);
2394
- $parentpos = count($options["nodes"]->nodes[$pid]["children"]);
2395
-
2396
- if ($parentpos && $options["nodes"]->nodes[$options["nodes"]->nodes[$pid]["children"][$parentpos - 1]]["type"] == $type) $options["nodes"]->nodes[$options["nodes"]->nodes[$pid]["children"][$parentpos - 1]]["text"] .= $content;
2397
- else
2398
- {
2399
- $options["nodes"]->nodes[$options["nodes"]->nextid] = array(
2400
- "type" => $type,
2401
- "text" => $content,
2402
- "parent" => $pid,
2403
- "parentpos" => $parentpos
2404
- );
2405
-
2406
- $options["nodes"]->nodes[$pid]["children"][] = $options["nodes"]->nextid;
2407
-
2408
- $options["nodes"]->nextid++;
2409
- }
2410
-
2411
- $content = "";
2412
- }
2413
-
2414
- public static function Explode($content, $options = array())
2415
- {
2416
- $options["tag_callback"] = __CLASS__ . "::ExplodeTagCallback";
2417
- $options["content_callback"] = __CLASS__ . "::ExplodeContentCallback";
2418
- $options["nodes"] = new TagFilterNodes();
2419
- $options["data"] = new stdClass();
2420
- $options["data"]->stackmap = array();
2421
-
2422
- self::Run($content, $options);
2423
-
2424
- return $options["nodes"];
2425
- }
2426
-
2427
- public static function HTMLPurifyTagCallback($stack, &$content, $open, $tagname, &$attrs, $options)
2428
- {
2429
- if ($open)
2430
- {
2431
- if ($tagname === "script") return array("keep_tag" => false, "keep_interior" => false);
2432
- if ($tagname === "style") return array("keep_tag" => false, "keep_interior" => false);
2433
-
2434
- if (isset($attrs["src"]) && substr($attrs["src"], 0, 11) === "javascript:") return array("keep_tag" => false, "keep_interior" => false);
2435
- if (isset($attrs["href"]) && substr($attrs["href"], 0, 11) === "javascript:") return array("keep_tag" => false);
2436
-
2437
- if (!isset($options["htmlpurify"]["allowed_tags"][$tagname])) return array("keep_tag" => false);
2438
-
2439
- if (!isset($options["htmlpurify"]["allowed_attrs"][$tagname])) $attrs = array();
2440
- else
2441
- {
2442
- // For classes, "class" needs to be specified as an allowed attribute.
2443
- foreach ($attrs as $attr => $val)
2444
- {
2445
- if (!isset($options["htmlpurify"]["allowed_attrs"][$tagname][$attr])) unset($attrs[$attr]);
2446
- }
2447
- }
2448
-
2449
- if (isset($options["htmlpurify"]["required_attrs"][$tagname]))
2450
- {
2451
- foreach ($options["htmlpurify"]["required_attrs"][$tagname] as $attr => $val)
2452
- {
2453
- if (!isset($attrs[$attr])) return array("keep_tag" => false);
2454
- }
2455
- }
2456
-
2457
- if (isset($attrs["class"]))
2458
- {
2459
- if (!isset($options["htmlpurify"]["allowed_classes"][$tagname])) unset($attrs["class"]);
2460
- else
2461
- {
2462
- foreach ($attrs["class"] as $class)
2463
- {
2464
- if (!isset($options["htmlpurify"]["allowed_classes"][$tagname][$class])) unset($attrs["class"][$class]);
2465
- }
2466
-
2467
- if (!count($attrs["class"])) unset($attrs["class"]);
2468
- }
2469
- }
2470
- }
2471
- else
2472
- {
2473
- if (isset($options["htmlpurify"]["remove_empty"][substr($tagname, 1)]) && trim(str_replace(array("&nbsp;", "\xC2\xA0"), " ", $content)) === "")
2474
- {
2475
- if ($content !== "") $content = " ";
2476
-
2477
- return array("keep_tag" => false);
2478
- }
2479
- }
2480
-
2481
- return array();
2482
- }
2483
-
2484
- private static function Internal_NormalizeHTMLPurifyOptions($value)
2485
- {
2486
- if (is_string($value))
2487
- {
2488
- $opts = explode(",", $value);
2489
- $value = array();
2490
- foreach ($opts as $opt)
2491
- {
2492
- $opt = (string)trim($opt);
2493
- if ($opt !== "") $value[$opt] = true;
2494
- }
2495
- }
2496
-
2497
- return $value;
2498
- }
2499
-
2500
- public static function NormalizeHTMLPurifyOptions($purifyopts)
2501
- {
2502
- if (!isset($purifyopts["allowed_tags"])) $purifyopts["allowed_tags"] = array();
2503
- if (!isset($purifyopts["allowed_attrs"])) $purifyopts["allowed_attrs"] = array();
2504
- if (!isset($purifyopts["required_attrs"])) $purifyopts["required_attrs"] = array();
2505
- if (!isset($purifyopts["allowed_classes"])) $purifyopts["allowed_classes"] = array();
2506
- if (!isset($purifyopts["remove_empty"])) $purifyopts["remove_empty"] = array();
2507
-
2508
- $purifyopts["allowed_tags"] = self::Internal_NormalizeHTMLPurifyOptions($purifyopts["allowed_tags"]);
2509
- foreach ($purifyopts["allowed_attrs"] as $key => $val) $purifyopts["allowed_attrs"][$key] = self::Internal_NormalizeHTMLPurifyOptions($val);
2510
- foreach ($purifyopts["required_attrs"] as $key => $val) $purifyopts["required_attrs"][$key] = self::Internal_NormalizeHTMLPurifyOptions($val);
2511
- foreach ($purifyopts["allowed_classes"] as $key => $val) $purifyopts["allowed_classes"][$key] = self::Internal_NormalizeHTMLPurifyOptions($val);
2512
- $purifyopts["remove_empty"] = self::Internal_NormalizeHTMLPurifyOptions($purifyopts["remove_empty"]);
2513
-
2514
- return $purifyopts;
2515
- }
2516
-
2517
- public static function HTMLPurify($content, $htmloptions, $purifyopts)
2518
- {
2519
- $htmloptions["tag_callback"] = __CLASS__ . "::HTMLPurifyTagCallback";
2520
- $htmloptions["htmlpurify"] = self::NormalizeHTMLPurifyOptions($purifyopts);
2521
-
2522
- return self::Run($content, $htmloptions);
2523
- }
2524
-
2525
- public static function ReorderSelectorTokens($tokens, $splitrules, $order = array("pseudo-element" => array(), "pseudo-class" => array(), "attr" => array(), "class" => array(), "element" => array(), "id" => array()), $endnots = true)
2526
- {
2527
- // Collapse split rules.
2528
- if (count($tokens) && !isset($tokens[0]["type"]) && isset($tokens[0][0]["type"]))
2529
- {
2530
- $tokens2 = array();
2531
- foreach ($tokens as $rules)
2532
- {
2533
- if (count($tokens2)) $tokens2[] = array("type" => "combine", "combine" => "or");
2534
- $rules = array_reverse($rules);
2535
- foreach ($rules as $rule) $tokens2[] = $rule;
2536
- }
2537
-
2538
- $tokens = $tokens2;
2539
- }
2540
-
2541
- $result = array();
2542
- $rules = array();
2543
- $selector = $order;
2544
- foreach ($tokens as $token)
2545
- {
2546
- if ($token["type"] != "combine") array_unshift($selector[$token["type"]], $token);
2547
- else
2548
- {
2549
- foreach ($selector as $vals)
2550
- {
2551
- foreach ($vals as $token2)
2552
- {
2553
- if (($endnots && $token2["not"]) || (!$endnots && !$token2["not"])) array_unshift($result, $token2);
2554
- }
2555
-
2556
- foreach ($vals as $token2)
2557
- {
2558
- if (($endnots && !$token2["not"]) || (!$endnots && $token2["not"])) array_unshift($result, $token2);
2559
- }
2560
- }
2561
-
2562
- if (!$splitrules || $token["combine"] != "or") array_unshift($result, $token);
2563
- else if ($token["combine"] == "or")
2564
- {
2565
- if (count($result)) $rules[] = $result;
2566
-
2567
- $result = array();
2568
- }
2569
-
2570
- $selector = $order;
2571
- }
2572
- }
2573
-
2574
- foreach ($selector as $vals)
2575
- {
2576
- foreach ($vals as $token2)
2577
- {
2578
- if (($endnots && $token2["not"]) || (!$endnots && !$token2["not"])) array_unshift($result, $token2);
2579
- }
2580
-
2581
- foreach ($vals as $token2)
2582
- {
2583
- if (($endnots && !$token2["not"]) || (!$endnots && $token2["not"])) array_unshift($result, $token2);
2584
- }
2585
- }
2586
-
2587
- if ($splitrules)
2588
- {
2589
- if (count($result)) $rules[] = $result;
2590
-
2591
- $result = $rules;
2592
- }
2593
- else
2594
- {
2595
- // Ignore a stray group combiner at the end.
2596
- if (count($result) && $result[0]["type"] == "combine" && $result[0]["combine"] == "or") array_shift($result);
2597
- }
2598
-
2599
- return $result;
2600
- }
2601
-
2602
- public static function ParseSelector($query, $splitrules = false)
2603
- {
2604
- // Tokenize query into individual action steps.
2605
- $query = trim($query);
2606
- $tokens = array();
2607
- $lastor = 0;
2608
- $a = ord("A");
2609
- $a2 = ord("a");
2610
- $f = ord("F");
2611
- $f2 = ord("f");
2612
- $z = ord("Z");
2613
- $z2 = ord("z");
2614
- $backslash = ord("\\");
2615
- $hyphen = ord("-");
2616
- $underscore = ord("_");
2617
- $pipe = ord("|");
2618
- $asterisk = ord("*");
2619
- $colon = ord(":");
2620
- $period = ord(".");
2621
- $zero = ord("0");
2622
- $nine = ord("9");
2623
- $cr = ord("\r");
2624
- $nl = ord("\n");
2625
- $ff = ord("\f");
2626
- $cx = 0;
2627
- $cy = strlen($query);
2628
- $state = "next_selector";
2629
- do
2630
- {
2631
- $currcx = $cx;
2632
- $currstate = $state;
2633
-
2634
- switch ($state)
2635
- {
2636
- case "next_selector":
2637
- {
2638
- // This state is necessary to handle the :not(selector) function.
2639
- $token = array("not" => false);
2640
- }
2641
- case "selector":
2642
- {
2643
- if ($cx >= $cy) break;
2644
-
2645
- switch ($query{$cx})
2646
- {
2647
- case "#":
2648
- {
2649
- $token["type"] = "id";
2650
- $state = "ident_name";
2651
- $allownamespace = false;
2652
- $identasterisk = false;
2653
- $allowperiod = false;
2654
- $namespace = false;
2655
- $range = true;
2656
- $ident = "";
2657
- $nextstate = "selector_ident_result";
2658
- $cx++;
2659
-
2660
- break;
2661
- }
2662
- case ".":
2663
- {
2664
- $token["type"] = "class";
2665
- $state = "ident";
2666
- $allownamespace = false;
2667
- $identasterisk = false;
2668
- $allowperiod = false;
2669
- $nextstate = "selector_ident_result";
2670
- $cx++;
2671
-
2672
- break;
2673
- }
2674
- case "[":
2675
- {
2676
- $token["type"] = "attr";
2677
- $state = "ident";
2678
- $state2 = "attr";
2679
- $allownamespace = true;
2680
- $identasterisk = false;
2681
- $allowperiod = false;
2682
- $nextstate = "selector_ident_result";
2683
- $cx++;
2684
-
2685
- // Find a non-whitespace character.
2686
- while ($cx < $cy && ($query{$cx} == " " || $query{$cx} == "\t" || $query{$cx} == "\r" || $query{$cx} == "\n" || $query{$cx} == "\f")) $cx++;
2687
-
2688
- break;
2689
- }
2690
- case ":":
2691
- {
2692
- $cx++;
2693
- if ($cx >= $cy || $query{$cx} != ":") $token["type"] = "pseudo-class";
2694
- else
2695
- {
2696
- $token["type"] = "pseudo-element";
2697
- $cx++;
2698
- }
2699
-
2700
- $state = "ident";
2701
- $allownamespace = true;
2702
- $identasterisk = false;
2703
- $allowperiod = false;
2704
- $nextstate = "selector_ident_result";
2705
-
2706
- break;
2707
- }
2708
- case ",":
2709
- case "+":
2710
- case ">":
2711
- case "~":
2712
- case " ":
2713
- case "\r":
2714
- case "\n":
2715
- case "\t":
2716
- case "\f":
2717
- {
2718
- $state = "combine";
2719
-
2720
- break;
2721
- }
2722
- default:
2723
- {
2724
- $token["type"] = "element";
2725
- $state = "ident";
2726
- $allownamespace = true;
2727
- $identasterisk = true;
2728
- $allowperiod = false;
2729
- $nextstate = "selector_ident_result";
2730
-
2731
- break;
2732
- }
2733
- }
2734
-
2735
- break;
2736
- }
2737
- case "selector_ident_result":
2738
- {
2739
- switch ($token["type"])
2740
- {
2741
- case "id":
2742
- {
2743
- $token["id"] = $ident;
2744
- $tokens[] = $token;
2745
- $state = ($token["not"] ? "negate_close" : "next_selector");
2746
-
2747
- break;
2748
- }
2749
- case "class":
2750
- {
2751
- $token["class"] = $ident;
2752
- $tokens[] = $token;
2753
- $state = ($token["not"] ? "negate_close" : "next_selector");
2754
-
2755
- break;
2756
- }
2757
- case "element":
2758
- {
2759
- $token["namespace"] = $namespace;
2760
- $token["tag"] = $ident;
2761
- $tokens[] = $token;
2762
- $state = ($token["not"] ? "negate_close" : "next_selector");
2763
-
2764
- break;
2765
- }
2766
- case "attr":
2767
- {
2768
- if ($state2 == "attr")
2769
- {
2770
- $token["namespace"] = $namespace;
2771
- $token[$state2] = $ident;
2772
-
2773
- // Find a non-whitespace character.
2774
- while ($cx < $cy && ($query{$cx} == " " || $query{$cx} == "\t" || $query{$cx} == "\r" || $query{$cx} == "\n" || $query{$cx} == "\f")) $cx++;
2775
-
2776
- if ($cx >= $cy || $query{$cx} == "]")
2777
- {
2778
- $token["cmp"] = false;
2779
- $tokens[] = $token;
2780
- $state = ($token["not"] ? "negate_close" : "next_selector");
2781
- $cx++;
2782
- }
2783
- else
2784
- {
2785
- if ($query{$cx} == "=")
2786
- {
2787
- $token["cmp"] = "=";
2788
- $cx++;
2789
- }
2790
- else if ($cx + 1 < $cy && ($query{$cx} == "^" || $query{$cx} == "$" || $query{$cx} == "*" || $query{$cx} == "~" || $query{$cx} == "|") && $query{$cx + 1} == "=")
2791
- {
2792
- $token["cmp"] = substr($query, $cx, 2);
2793
- $cx += 2;
2794
- }
2795
- else
2796
- {
2797
- return array("success" => false, "error" => "Unknown or invalid attribute comparison operator '" . $query{$cx} . "' detected at position " . $cx . ".", "errorcode" => "invalid_attr_compare", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
2798
- }
2799
-
2800
- // Find a non-whitespace character.
2801
- while ($cx < $cy && ($query{$cx} == " " || $query{$cx} == "\t" || $query{$cx} == "\r" || $query{$cx} == "\n" || $query{$cx} == "\f")) $cx++;
2802
-
2803
- if ($cx < $cy && ($query{$cx} == "\"" || $query{$cx} == "'"))
2804
- {
2805
- $state = "string";
2806
- $endchr = ord($query{$cx});
2807
- $cx++;
2808
- }
2809
- else
2810
- {
2811
- $state = "ident";
2812
- $allownamespace = false;
2813
- $identasterisk = false;
2814
- $allowperiod = false;
2815
- }
2816
-
2817
- $state2 = "val";
2818
- $nextstate = "selector_ident_result";
2819
- }
2820
- }
2821
- else if ($state2 == "val")
2822
- {
2823
- $token[$state2] = $ident;
2824
-
2825
- // Find a non-whitespace character.
2826
- while ($cx < $cy && ($query{$cx} == " " || $query{$cx} == "\t" || $query{$cx} == "\r" || $query{$cx} == "\n" || $query{$cx} == "\f")) $cx++;
2827
-
2828
- $tokens[] = $token;
2829
- $state = ($token["not"] ? "negate_close" : "next_selector");
2830
-
2831
- if ($cx < $cy && $query{$cx} == "]") $cx++;
2832
- }
2833
-
2834
- break;
2835
- }
2836
- case "pseudo-class":
2837
- case "pseudo-element":
2838
- {
2839
- $ident = strtolower($ident);
2840
-
2841
- // Deal with CSS1 and CSS2 compatibility.
2842
- if ($ident === "first-line" || $ident === "first-letter" || $ident === "before" || $ident === "after") $token["type"] = "pseudo-element";
2843
-
2844
- if ($token["type"] == "pseudo-class" && $ident == "not")
2845
- {
2846
- if ($token["not"]) return array("success" => false, "error" => "Invalid :not() embedded inside another :not() detected at position " . $cx . ".", "errorcode" => "invalid_not", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
2847
- if ($cx >= $cy || $query{$cx} != "(") return array("success" => false, "error" => "Missing '(' detected at position " . $cx . ".", "errorcode" => "invalid_not", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
2848
-
2849
- unset($token["type"]);
2850
- $token["not"] = true;
2851
-
2852
- $state = "selector";
2853
- $cx++;
2854
-
2855
- // Find a non-whitespace character.
2856
- while ($cx < $cy && ($query{$cx} == " " || $query{$cx} == "\t" || $query{$cx} == "\r" || $query{$cx} == "\n" || $query{$cx} == "\f")) $cx++;
2857
- }
2858
- else
2859
- {
2860
- $token["pseudo"] = $ident;
2861
-
2862
- if ($cx < $cy && $query{$cx} == "(")
2863
- {
2864
- $token["expression"] = "";
2865
- $ident = "";
2866
- $state = "pseudo_expression";
2867
- $cx++;
2868
- }
2869
- else
2870
- {
2871
- $token["expression"] = false;
2872
- $tokens[] = $token;
2873
- $state = ($token["not"] ? "negate_close" : "next_selector");
2874
- }
2875
- }
2876
-
2877
- break;
2878
- }
2879
- }
2880
-
2881
- break;
2882
- }
2883
- case "negate_close":
2884
- {
2885
- // Find a non-whitespace character.
2886
- while ($cx < $cy && ($query{$cx} == " " || $query{$cx} == "\t" || $query{$cx} == "\r" || $query{$cx} == "\n" || $query{$cx} == "\f")) $cx++;
2887
-
2888
- if ($cx < $cy && $query{$cx} != ")") return array("success" => false, "error" => "Invalid :not() close character '" . $query{$cx} . "' detected at position " . $cx . ".", "errorcode" => "invalid_negate_close", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
2889
-
2890
- $cx++;
2891
- $state = "next_selector";
2892
-
2893
- break;
2894
- }
2895
- case "pseudo_expression":
2896
- {
2897
- $token["expression"] .= $ident;
2898
-
2899
- // Find a non-whitespace character.
2900
- while ($cx < $cy && ($query{$cx} == " " || $query{$cx} == "\t" || $query{$cx} == "\r" || $query{$cx} == "\n" || $query{$cx} == "\f")) $cx++;
2901
-
2902
- if ($cx >= $cy) break;
2903
-
2904
- if ($query{$cx} == ")")
2905
- {
2906
- if (substr($token["pseudo"], 0, 4) === "nth-")
2907
- {
2908
- // Convert the expression to an+b syntax.
2909
- $exp = strtolower($token["expression"]);
2910
-
2911
- if ($exp == "even") $exp = "2n";
2912
- else if ($exp == "odd") $exp = "2n+1";
2913
- else
2914
- {
2915
- do
2916
- {
2917
- $currexp = $exp;
2918
-
2919
- $exp = str_replace(array("++", "+-", "-+", "--"), array("+", "-", "-", "+"), $exp);
2920
-
2921
- } while ($currexp !== $exp);
2922
- }
2923
-
2924
- if (substr($exp, 0, 2) == "-n") $exp = "-1n" . substr($exp, 2);
2925
- else if (substr($exp, 0, 2) == "+n") $exp = "1n" . substr($exp, 2);
2926
- else if (substr($exp, 0, 1) == "n") $exp = "1n" . substr($exp, 1);
2927
-
2928
- $pos = strpos($exp, "n");
2929
- if ($pos === false)
2930
- {
2931
- $token["a"] = 0;
2932
- $token["b"] = (double)$exp;
2933
- }
2934
- else
2935
- {
2936
- $token["a"] = (double)$exp;
2937
- $token["b"] = (double)substr($exp, $pos + 1);
2938
- }
2939
-
2940
- $token["expression"] = $token["a"] . "n" . ($token["b"] < 0 ? $token["b"] : "+" . $token["b"]);
2941
- }
2942
-
2943
- $tokens[] = $token;
2944
- $state = ($token["not"] ? "negate_close" : "next_selector");
2945
- $cx++;
2946
- }
2947
- else if ($query{$cx} == "+" || $query{$cx} == "-")
2948
- {
2949
- $ident = $query{$cx};
2950
- $cx++;
2951
- }
2952
- else if ($query{$cx} == "\"" || $query{$cx} == "'")
2953
- {
2954
- $state = "string";
2955
- $endchr = ord($query{$cx});
2956
- $cx++;
2957
- }
2958
- else
2959
- {
2960
- $val = ord($query{$cx});
2961
-
2962
- $state = ($val >= $zero && $val <= $nine ? "ident_name" : "ident");
2963
- $allownamespace = false;
2964
- $identasterisk = false;
2965
- $allowperiod = ($val >= $zero && $val <= $nine);
2966
- $namespace = false;
2967
- $range = true;
2968
- $ident = "";
2969
-
2970
- $nextstate = "pseudo_expression";
2971
- }
2972
-
2973
- break;
2974
- }
2975
- case "string":
2976
- {
2977
- $startcx = $cx;
2978
- $ident = "";
2979
-
2980
- for (; $cx < $cy; $cx++)
2981
- {
2982
- $val = ord($query{$cx});
2983
-
2984
- if ($val == $endchr)
2985
- {
2986
- $cx++;
2987
-
2988
- break;
2989
- }
2990
- else if ($val == $backslash)
2991
- {
2992
- // Escape sequence.
2993
- if ($cx + 1 >= $cy) $ident .= "\\";
2994
- else
2995
- {
2996
- $cx++;
2997
- $val = ord($query{$cx});
2998
-
2999
- if (($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))
3000
- {
3001
- // Unicode (e.g. \0020)
3002
- for ($x = $cx + 1; $x < $cy; $x++)
3003
- {
3004
- $val = ord($query{$x});
3005
- if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
3006
- }
3007
-
3008
- $num = hexdec(substr($query, $cx, $x - $cx));
3009
- $cx = $x - 1;
3010
-
3011
- $ident .= TagFilterStream::UTF8Chr($num);
3012
-
3013
- // Skip one optional \r\n OR a single whitespace char.
3014
- if ($cx + 2 < $cy && $query{$cx + 1} == "\r" && $query{$cx + 2} == "\n") $cx += 2;
3015
- else if ($cx + 1 < $cy && ($query{$cx + 1} == " " || $query{$cx + 1} == "\r" || $query{$cx + 1} == "\n" || $query{$cx + 1} == "\t" || $query{$cx + 1} == "\f")) $cx++;
3016
- }
3017
- else
3018
- {
3019
- $ident .= $query{$cx};
3020
- }
3021
- }
3022
- }
3023
- else
3024
- {
3025
- $ident .= $query{$cx};
3026
- }
3027
- }
3028
-
3029
- $state = $nextstate;
3030
-
3031
- break;
3032
- }
3033
- case "ident":
3034
- {
3035
- $namespace = false;
3036
- $range = false;
3037
-
3038
- if ($cx >= $cy) break;
3039
-
3040
- if ($query{$cx} != "-") $ident = "";
3041
- else
3042
- {
3043
- $ident = "-";
3044
- $cx++;
3045
- }
3046
-
3047
- $state = "ident_name";
3048
-
3049
- break;
3050
- }
3051
- case "ident_name":
3052
- {
3053
- // Find the first invalid character.
3054
- $startcx = $cx;
3055
- for (; $cx < $cy; $cx++)
3056
- {
3057
- $val = ord($query{$cx});
3058
-
3059
- if ($val != $period && ($val < $zero || $val > $nine)) $allowperiod = false;
3060
-
3061
- if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2) || $val == $underscore || $val > 127)
3062
- {
3063
- $ident .= $query{$cx};
3064
- }
3065
- else if ($allowperiod && $val == $period)
3066
- {
3067
- $allowperiod = false;
3068
-
3069
- $ident .= ".";
3070
- }
3071
- else if ($val == $hyphen || ($val >= $zero && $val <= $nine))
3072
- {
3073
- // Only allowed AFTER the first character.
3074
- if (!$range) return array("success" => false, "error" => "Invalid identifier character '" . $query{$cx} . "' detected at position " . $cx . ".", "errorcode" => "invalid_ident", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
3075
-
3076
- $allowperiod = false;
3077
-
3078
- $ident .= $query{$cx};
3079
- }
3080
- else if ($val == $backslash)
3081
- {
3082
- // Escape sequence.
3083
- if ($cx + 1 >= $cy) $ident .= "\\";
3084
- else
3085
- {
3086
- $cx++;
3087
- $val = ord($query{$cx});
3088
-
3089
- if (($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))
3090
- {
3091
- // Unicode (e.g. \0020)
3092
- for ($x = $cx + 1; $x < $cy; $x++)
3093
- {
3094
- $val = ord($query{$x});
3095
- if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
3096
- }
3097
-
3098
- $num = hexdec(substr($query, $cx, $x - $cx));
3099
- $cx = $x - 1;
3100
-
3101
- $ident .= TagFilterStream::UTF8Chr($num);
3102
-
3103
- // Skip one optional \r\n OR a single whitespace char.
3104
- if ($cx + 2 < $cy && $query{$cx + 1} == "\r" && $query{$cx + 2} == "\n") $cx += 2;
3105
- else if ($cx + 1 < $cy && ($query{$cx + 1} == " " || $query{$cx + 1} == "\r" || $query{$cx + 1} == "\n" || $query{$cx + 1} == "\t" || $query{$cx + 1} == "\f")) $cx++;
3106
- }
3107
- else if ($val != $cr && $val != $nl && $val != $ff)
3108
- {
3109
- $ident .= $query{$cx};
3110
- }
3111
- }
3112
- }
3113
- else if ($allownamespace && $val == $pipe && ($cx + 1 >= $cy || $query{$cx + 1} != "="))
3114
- {
3115
- // Handle namespaces (rare).
3116
- if ($ident != "")
3117
- {
3118
- $namespace = $ident;
3119
- $ident = "";
3120
- }
3121
-
3122
- $allownamespace = false;
3123
- }
3124
- else if ($val == $asterisk)
3125
- {
3126
- // Handle wildcard (*) characters.
3127
- if ($allownamespace && $cx + 1 < $cy && $query{$cx + 1} == "|")
3128
- {
3129
- // Wildcard namespace (*|).
3130
- $namespace = "*";
3131
- $allownamespace = false;
3132
- $cx++;
3133
- }
3134
- else if ($identasterisk)
3135
- {
3136
- if ($ident != "") return array("success" => false, "error" => "Invalid identifier wildcard character '*' detected at position " . $cx . ".", "errorcode" => "invalid_wildcard_ident", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
3137
-
3138
- $ident = "*";
3139
- $cx++;
3140
-
3141
- break;
3142
- }
3143
- else
3144
- {
3145
- // End of ident.
3146
- break;
3147
- }
3148
- }
3149
- else
3150
- {
3151
- // End of ident.
3152
- break;
3153
- }
3154
-
3155
- $range = true;
3156
- }
3157
-
3158
- if ($ident == "") return array("success" => false, "error" => "Missing or invalid identifier at position " . $cx . ".", "errorcode" => "missing_ident", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
3159
-
3160
- $state = $nextstate;
3161
-
3162
- break;
3163
- }
3164
- case "combine":
3165
- {
3166
- $token = array("type" => "combine");
3167
-
3168
- // Find a non-whitespace character.
3169
- while ($cx < $cy && ($query{$cx} == " " || $query{$cx} == "\t" || $query{$cx} == "\r" || $query{$cx} == "\n" || $query{$cx} == "\f")) $cx++;
3170
-
3171
- if ($cx < $cy)
3172
- {
3173
- switch ($query{$cx})
3174
- {
3175
- case ",":
3176
- {
3177
- $token["combine"] = "or";
3178
- $lastor = count($tokens);
3179
- $cx++;
3180
-
3181
- break;
3182
- }
3183
- case "+":
3184
- {
3185
- $token["combine"] = "prev-sibling";
3186
- $cx++;
3187
-
3188
- break;
3189
- }
3190
- case ">":
3191
- {
3192
- $token["combine"] = "prev-parent";
3193
- $cx++;
3194
-
3195
- break;
3196
- }
3197
- case "~":
3198
- {
3199
- $token["combine"] = "any-prev-sibling";
3200
- $cx++;
3201
-
3202
- break;
3203
- }
3204
- default:
3205
- {
3206
- $token["combine"] = "any-parent";
3207
-
3208
- break;
3209
- }
3210
- }
3211
-
3212
- if (!count($tokens) || $tokens[count($tokens) - 1]["type"] == "combine") return array("success" => false, "error" => "Invalid combiner '" . $token["type"] . "' detected at position " . $cx . ".", "errorcode" => "invalid_combiner", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
3213
-
3214
- $tokens[] = $token;
3215
-
3216
- // Find a non-whitespace character.
3217
- while ($cx < $cy && ($query{$cx} == " " || $query{$cx} == "\t" || $query{$cx} == "\r" || $query{$cx} == "\n" || $query{$cx} == "\f")) $cx++;
3218
- }
3219
-
3220
- $state = "next_selector";
3221
-
3222
- break;
3223
- }
3224
- }
3225
- } while ($currstate !== $state || $currcx !== $cx);
3226
-
3227
- return array("success" => true, "selector" => $query, "tokens" => self::ReorderSelectorTokens($tokens, $splitrules), "splitrules" => $splitrules);
3228
- }
3229
-
3230
- public static function GetParentPos($stack, $tagname, $start = 0, $attrs = array())
3231
- {
3232
- $y = count($stack);
3233
- for ($x = $start; $x < $y; $x++)
3234
- {
3235
- if ($stack[$x]["tag_name"] === $tagname)
3236
- {
3237
- $found = true;
3238
- foreach ($attrs as $key => $val)
3239
- {
3240
- if (!isset($stack[$x]["attrs"][$key])) $found = false;
3241
- else if (is_string($stack[$x]["attrs"][$key]) && is_string($val) && stripos($stack[$x]["attrs"][$key], $val) === false) $found = false;
3242
- else if (is_array($stack[$x]["attrs"][$key]))
3243
- {
3244
- if (is_string($val)) $val = explode(" ", $val);
3245
-
3246
- foreach ($val as $val2)
3247
- {
3248
- if ($val2 !== "" && !isset($stack[$x]["attrs"][$key][$val2])) $found = false;
3249
- }
3250
- }
3251
- }
3252
-
3253
- if ($found) return $x;
3254
- }
3255
- }
3256
-
3257
- return false;
3258
- }
3259
- }
3260
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/ultimate-web-scraper/web_browser.php DELETED
@@ -1,1189 +0,0 @@
1
- <?php
2
- // CubicleSoft PHP web browser state emulation class.
3
- // (C) 2016 CubicleSoft. All Rights Reserved.
4
-
5
- // Requires the CubicleSoft PHP HTTP class for HTTP/HTTPS.
6
- class WebBrowser
7
- {
8
- private $data, $html;
9
-
10
- public function __construct($prevstate = array())
11
- {
12
- if (!class_exists("HTTP", false)) require_once str_replace("\\", "/", dirname(__FILE__)) . "/http.php";
13
-
14
- $this->ResetState();
15
- $this->SetState($prevstate);
16
- $this->html = false;
17
- }
18
-
19
- public function ResetState()
20
- {
21
- $this->data = array(
22
- "allowedprotocols" => array("http" => true, "https" => true),
23
- "allowedredirprotocols" => array("http" => true, "https" => true),
24
- "hostauths" => array(),
25
- "cookies" => array(),
26
- "referer" => "",
27
- "autoreferer" => true,
28
- "useragent" => "firefox",
29
- "followlocation" => true,
30
- "maxfollow" => 20,
31
- "extractforms" => false,
32
- "httpopts" => array(),
33
- );
34
- }
35
-
36
- public function SetState($options = array())
37
- {
38
- $this->data = array_merge($this->data, $options);
39
- }
40
-
41
- public function GetState()
42
- {
43
- return $this->data;
44
- }
45
-
46
- public function ProcessState(&$state)
47
- {
48
- while ($state["state"] !== "done")
49
- {
50
- switch ($state["state"])
51
- {
52
- case "initialize":
53
- {
54
- if (!isset($this->data["allowedprotocols"][$state["urlinfo"]["scheme"]]) || !$this->data["allowedprotocols"][$state["urlinfo"]["scheme"]])
55
- {
56
- return array("success" => false, "error" => self::WBTranslate("Protocol '%s' is not allowed in '%s'.", $state["urlinfo"]["scheme"], $state["url"]), "errorcode" => "allowed_protocols");
57
- }
58
-
59
- $filename = HTTP::ExtractFilename($state["urlinfo"]["path"]);
60
- $pos = strrpos($filename, ".");
61
- $fileext = ($pos !== false ? strtolower(substr($filename, $pos + 1)) : "");
62
-
63
- // Set up some standard headers.
64
- $headers = array();
65
- $profile = strtolower($state["profile"]);
66
- $tempprofile = explode("-", $profile);
67
- if (count($tempprofile) == 2)
68
- {
69
- $profile = $tempprofile[0];
70
- $fileext = $tempprofile[1];
71
- }
72
- if (substr($profile, 0, 2) == "ie" || ($profile == "auto" && substr($this->data["useragent"], 0, 2) == "ie"))
73
- {
74
- if ($fileext == "css") $headers["Accept"] = "text/css";
75
- else if ($fileext == "png" || $fileext == "jpg" || $fileext == "jpeg" || $fileext == "gif" || $fileext == "svg") $headers["Accept"] = "image/png, image/svg+xml, image/*;q=0.8, */*;q=0.5";
76
- else if ($fileext == "js") $headers["Accept"] = "application/javascript, */*;q=0.8";
77
- else if ($this->data["referer"] != "" || $fileext == "" || $fileext == "html" || $fileext == "xhtml" || $fileext == "xml") $headers["Accept"] = "text/html, application/xhtml+xml, */*";
78
- else $headers["Accept"] = "*/*";
79
-
80
- $headers["Accept-Language"] = "en-US";
81
- $headers["User-Agent"] = HTTP::GetUserAgent(substr($profile, 0, 2) == "ie" ? $profile : $this->data["useragent"]);
82
- }
83
- else if ($profile == "firefox" || ($profile == "auto" && $this->data["useragent"] == "firefox"))
84
- {
85
- if ($fileext == "css") $headers["Accept"] = "text/css,*/*;q=0.1";
86
- else if ($fileext == "png" || $fileext == "jpg" || $fileext == "jpeg" || $fileext == "gif" || $fileext == "svg") $headers["Accept"] = "image/png,image/*;q=0.8,*/*;q=0.5";
87
- else if ($fileext == "js") $headers["Accept"] = "*/*";
88
- else $headers["Accept"] = "text/html, application/xhtml+xml, */*";
89
-
90
- $headers["Accept-Language"] = "en-us,en;q=0.5";
91
- $headers["Cache-Control"] = "max-age=0";
92
- $headers["User-Agent"] = HTTP::GetUserAgent("firefox");
93
- }
94
- else if ($profile == "opera" || ($profile == "auto" && $this->data["useragent"] == "opera"))
95
- {
96
- // Opera has the right idea: Just send the same thing regardless of the request type.
97
- $headers["Accept"] = "text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1";
98
- $headers["Accept-Language"] = "en-US,en;q=0.9";
99
- $headers["Cache-Control"] = "no-cache";
100
- $headers["User-Agent"] = HTTP::GetUserAgent("opera");
101
- }
102
- else if ($profile == "safari" || $profile == "chrome" || ($profile == "auto" && ($this->data["useragent"] == "safari" || $this->data["useragent"] == "chrome")))
103
- {
104
- if ($fileext == "css") $headers["Accept"] = "text/css,*/*;q=0.1";
105
- else if ($fileext == "png" || $fileext == "jpg" || $fileext == "jpeg" || $fileext == "gif" || $fileext == "svg" || $fileext == "js") $headers["Accept"] = "*/*";
106
- else $headers["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
107
-
108
- $headers["Accept-Charset"] = "ISO-8859-1,utf-8;q=0.7,*;q=0.3";
109
- $headers["Accept-Language"] = "en-US,en;q=0.8";
110
- $headers["User-Agent"] = HTTP::GetUserAgent($profile == "safari" || $profile == "chrome" ? $profile : $this->data["useragent"]);
111
- }
112
-
113
- if ($this->data["referer"] != "") $headers["Referer"] = $this->data["referer"];
114
-
115
- // Generate the final headers array.
116
- $headers = array_merge($headers, $state["httpopts"]["headers"], $state["tempoptions"]["headers"]);
117
-
118
- // Calculate the host and reverse host and remove port information.
119
- $host = (isset($headers["Host"]) ? $headers["Host"] : $state["urlinfo"]["host"]);
120
- $pos = strpos($host, "]");
121
- if (substr($host, 0, 1) == "[" && $pos !== false)
122
- {
123
- $host = substr($host, 0, $pos + 1);
124
- }
125
- else
126
- {
127
- $pos = strpos($host, ":");
128
- if ($pos !== false) $host = substr($host, 0, $pos);
129
- }
130
- $dothost = $host;
131
- $dothost = strtolower($dothost);
132
- if (substr($dothost, 0, 1) != ".") $dothost = "." . $dothost;
133
- $state["dothost"] = $dothost;
134
-
135
- // Append Authorization header.
136
- if (isset($headers["Authorization"])) $this->data["hostauths"][$host] = $headers["Authorization"];
137
- else if (isset($this->data["hostauths"][$host])) $headers["Authorization"] = $this->data["hostauths"][$host];
138
-
139
- // Append cookies and delete old, invalid cookies.
140
- $secure = ($state["urlinfo"]["scheme"] == "https");
141
- $cookiepath = $state["urlinfo"]["path"];
142
- if ($cookiepath == "") $cookiepath = "/";
143
- $pos = strrpos($cookiepath, "/");
144
- if ($pos !== false) $cookiepath = substr($cookiepath, 0, $pos + 1);
145
- $state["cookiepath"] = $cookiepath;
146
- $cookies = array();
147
- foreach ($this->data["cookies"] as $domain => $paths)
148
- {
149
- if (strlen($dothost) >= strlen($domain) && substr($dothost, -strlen($domain)) === $domain)
150
- {
151
- foreach ($paths as $path => $cookies2)
152
- {
153
- if (substr($cookiepath, 0, strlen($path)) == $path)
154
- {
155
- foreach ($cookies2 as $num => $info)
156
- {
157
- if (isset($info["expires_ts"]) && $this->GetExpiresTimestamp($info["expires_ts"]) < time()) unset($this->data["cookies"][$domain][$path][$num]);
158
- else if ($secure || !isset($info["secure"])) $cookies[$info["name"]] = $info["value"];
159
- }
160
-
161
- if (!count($this->data["cookies"][$domain][$path])) unset($this->data["cookies"][$domain][$path]);
162
- }
163
- }
164
-
165
- if (!count($this->data["cookies"][$domain])) unset($this->data["cookies"][$domain]);
166
- }
167
- }
168
-
169
- $cookies2 = array();
170
- foreach ($cookies as $name => $value) $cookies2[] = rawurlencode($name) . "=" . rawurlencode($value);
171
- $headers["Cookie"] = implode("; ", $cookies2);
172
- if ($headers["Cookie"] == "") unset($headers["Cookie"]);
173
-
174
- // Generate the final options array.
175
- $state["options"] = array_merge($state["httpopts"], $state["tempoptions"]);
176
- $state["options"]["headers"] = $headers;
177
- if ($state["timeout"] !== false) $state["options"]["timeout"] = HTTP::GetTimeLeft($state["startts"], $state["timeout"]);
178
-
179
- // Let a callback handle any additional state changes.
180
- if (isset($state["options"]["pre_retrievewebpage_callback"]) && is_callable($state["options"]["pre_retrievewebpage_callback"]) && !call_user_func_array($state["options"]["pre_retrievewebpage_callback"], array(&$state)))
181
- {
182
- return array("success" => false, "error" => self::WBTranslate("Pre-RetrieveWebpage callback returned with a failure condition for '%s'.", $state["url"]), "errorcode" => "pre_retrievewebpage_callback");
183
- }
184
-
185
- // Process the request.
186
- $result = HTTP::RetrieveWebpage($state["url"], $state["options"]);
187
- $result["url"] = $state["url"];
188
- unset($state["options"]["files"]);
189
- unset($state["options"]["body"]);
190
- unset($state["tempoptions"]["headers"]["Content-Type"]);
191
- $result["options"] = $state["options"];
192
- $result["firstreqts"] = $state["startts"];
193
- $result["numredirects"] = $state["numredirects"];
194
- $result["redirectts"] = $state["redirectts"];
195
- if (isset($result["rawsendsize"])) $state["totalrawsendsize"] += $result["rawsendsize"];
196
- $result["totalrawsendsize"] = $state["totalrawsendsize"];
197
- if (!$result["success"]) return array("success" => false, "error" => self::WBTranslate("Unable to retrieve content. %s", $result["error"]), "info" => $result, "state" => $state, "errorcode" => "retrievewebpage");
198
-
199
- if (isset($state["options"]["async"]) && $state["options"]["async"])
200
- {
201
- $state["async"] = true;
202
- $state["httpstate"] = $result["state"];
203
-
204
- $state["state"] = "process_async";
205
- }
206
- else
207
- {
208
- $state["result"] = $result;
209
-
210
- $state["state"] = "post_retrieval";
211
- }
212
-
213
- break;
214
- }
215
- case "process_async":
216
- {
217
- // Run a cycle of the HTTP state processor.
218
- $result = HTTP::ProcessState($state["httpstate"]);
219
- if (!$result["success"]) return $result;
220
-
221
- $result["url"] = $state["url"];
222
- $result["options"] = $state["options"];
223
- unset($result["options"]["files"]);
224
- unset($result["options"]["body"]);
225
- $result["firstreqts"] = $state["startts"];
226
- $result["numredirects"] = $state["numredirects"];
227
- $result["redirectts"] = $state["redirectts"];
228
- if (isset($result["rawsendsize"])) $state["totalrawsendsize"] += $result["rawsendsize"];
229
- $result["totalrawsendsize"] = $state["totalrawsendsize"];
230
-
231
- $state["httpstate"] = false;
232
- $state["result"] = $result;
233
-
234
- $state["state"] = "post_retrieval";
235
-
236
- break;
237
- }
238
- case "post_retrieval":
239
- {
240
- // Set up structures for another round.
241
- if ($this->data["autoreferer"]) $this->data["referer"] = $state["url"];
242
- if (isset($state["result"]["headers"]["Location"]) && $this->data["followlocation"])
243
- {
244
- $state["redirectts"] = microtime(true);
245
-
246
- unset($state["tempoptions"]["method"]);
247
- unset($state["tempoptions"]["write_body_callback"]);
248
- unset($state["tempoptions"]["body"]);
249
- unset($state["tempoptions"]["postvars"]);
250
- unset($state["tempoptions"]["files"]);
251
-
252
- $state["tempoptions"]["headers"]["Referer"] = $state["url"];
253
- $state["url"] = $state["result"]["headers"]["Location"][0];
254
-
255
- // Generate an absolute URL.
256
- if ($this->data["referer"] != "") $state["url"] = HTTP::ConvertRelativeToAbsoluteURL($this->data["referer"], $state["url"]);
257
-
258
- $urlinfo2 = HTTP::ExtractURL($state["url"]);
259
-
260
- if (!isset($this->data["allowedredirprotocols"][$urlinfo2["scheme"]]) || !$this->data["allowedredirprotocols"][$urlinfo2["scheme"]])
261
- {
262
- return array("success" => false, "error" => self::WBTranslate("Protocol '%s' is not allowed. Server attempted to redirect to '%s'.", $urlinfo2["scheme"], $state["url"]), "info" => $state["result"], "errorcode" => "allowed_redir_protocols");
263
- }
264
-
265
- if ($urlinfo2["host"] != $state["urlinfo"]["host"])
266
- {
267
- unset($state["tempoptions"]["headers"]["Host"]);
268
- unset($state["httpopts"]["headers"]["Host"]);
269
-
270
- unset($state["httpopts"]["headers"]["Authorization"]);
271
- unset($state["tempoptions"]["headers"]["Authorization"]);
272
- }
273
-
274
- $state["urlinfo"] = $urlinfo2;
275
- $state["numredirects"]++;
276
- }
277
-
278
- // Handle any 'Set-Cookie' headers.
279
- if (isset($state["result"]["headers"]["Set-Cookie"]))
280
- {
281
- foreach ($state["result"]["headers"]["Set-Cookie"] as $cookie)
282
- {
283
- $items = explode(";", $cookie);
284
- $item = trim(array_shift($items));
285
- if ($item != "")
286
- {
287
- $cookie2 = array();
288
- $pos = strpos($item, "=");
289
- if ($pos === false)
290
- {
291
- $cookie2["name"] = urldecode($item);
292
- $cookie2["value"] = "";
293
- }
294
- else
295
- {
296
- $cookie2["name"] = urldecode(substr($item, 0, $pos));
297
- $cookie2["value"] = urldecode(substr($item, $pos + 1));
298
- }
299
-
300
- $cookie = array();
301
- foreach ($items as $item)
302
- {
303
- $item = trim($item);
304
- if ($item != "")
305
- {
306
- $pos = strpos($item, "=");
307
- if ($pos === false) $cookie[strtolower(trim(urldecode($item)))] = "";
308
- else $cookie[strtolower(trim(urldecode(substr($item, 0, $pos))))] = urldecode(substr($item, $pos + 1));
309
- }
310
- }
311
- $cookie = array_merge($cookie, $cookie2);
312
-
313
- if (isset($cookie["expires"]))
314
- {
315
- $ts = HTTP::GetDateTimestamp($cookie["expires"]);
316
- $cookie["expires_ts"] = gmdate("Y-m-d H:i:s", ($ts === false ? time() - 24 * 60 * 60 : $ts));
317
- }
318
- else if (isset($cookie["max-age"]))
319
- {
320
- $cookie["expires_ts"] = gmdate("Y-m-d H:i:s", time() + (int)$cookie["max-age"]);
321
- }
322
- else
323
- {
324
- unset($cookie["expires_ts"]);
325
- }
326
-
327
- if (!isset($cookie["domain"])) $cookie["domain"] = $state["dothost"];
328
- if (!isset($cookie["path"])) $cookie["path"] = $state["cookiepath"];
329
-
330
- $this->SetCookie($cookie);
331
- }
332
- }
333
- }
334
-
335
- if ($state["numfollow"] > 0) $state["numfollow"]--;
336
-
337
- // If this is a redirect, handle it by starting over.
338
- if (isset($state["result"]["headers"]["Location"]) && $this->data["followlocation"] && $state["numfollow"])
339
- {
340
- $state["result"] = false;
341
-
342
- $state["state"] = "initialize";
343
- }
344
- else
345
- {
346
- $state["result"]["numredirects"] = $state["numredirects"];
347
- $state["result"]["redirectts"] = $state["redirectts"];
348
-
349
- // Extract the forms from the page in a parsed format.
350
- // Call WebBrowser::GenerateFormRequest() to prepare an actual request for Process().
351
- if ($this->data["extractforms"]) $state["result"]["forms"] = $this->ExtractForms($state["result"]["url"], $state["result"]["body"], (isset($state["tempoptions"]["extractforms_hint"]) ? $state["tempoptions"]["extractforms_hint"] : false));
352
-
353
- $state["state"] = "done";
354
- }
355
-
356
- break;
357
- }
358
- }
359
- }
360
-
361
- return $state["result"];
362
- }
363
-
364
- public function Process($url, $tempoptions = array())
365
- {
366
- $startts = microtime(true);
367
- $redirectts = $startts;
368
-
369
- // Handle older function call: Process($url, $profile, $tempoptions)
370
- if (is_string($tempoptions))
371
- {
372
- $args = func_get_args();
373
- if (count($args) < 3) $tempoptions = array();
374
- else $tempoptions = $args[2];
375
-
376
- $tempoptions["profile"] = $args[1];
377
- }
378
-
379
- $profile = (isset($tempoptions["profile"]) ? $tempoptions["profile"] : "auto");
380
-
381
- if (isset($tempoptions["timeout"])) $timeout = $tempoptions["timeout"];
382
- else if (isset($this->data["httpopts"]["timeout"])) $timeout = $this->data["httpopts"]["timeout"];
383
- else $timeout = false;
384
-
385
- // Deal with possible application hanging issues.
386
- if (isset($tempoptions["streamtimeout"])) $streamtimeout = $tempoptions["streamtimeout"];
387
- else if (isset($this->data["httpopts"]["streamtimeout"])) $streamtimeout = $this->data["httpopts"]["streamtimeout"];
388
- else $streamtimeout = 300;
389
- $tempoptions["streamtimeout"] = $streamtimeout;
390
-
391
- if (!isset($this->data["httpopts"]["headers"])) $this->data["httpopts"]["headers"] = array();
392
- $this->data["httpopts"]["headers"] = HTTP::NormalizeHeaders($this->data["httpopts"]["headers"]);
393
- unset($this->data["httpopts"]["method"]);
394
- unset($this->data["httpopts"]["write_body_callback"]);
395
- unset($this->data["httpopts"]["body"]);
396
- unset($this->data["httpopts"]["postvars"]);
397
- unset($this->data["httpopts"]["files"]);
398
-
399
- $httpopts = $this->data["httpopts"];
400
- $numfollow = $this->data["maxfollow"];
401
- $numredirects = 0;
402
- $totalrawsendsize = 0;
403
-
404
- if (!isset($tempoptions["headers"])) $tempoptions["headers"] = array();
405
- $tempoptions["headers"] = HTTP::NormalizeHeaders($tempoptions["headers"]);
406
- if (isset($tempoptions["headers"]["Referer"])) $this->data["referer"] = $tempoptions["headers"]["Referer"];
407
-
408
- // If a referrer is specified, use it to generate an absolute URL.
409
- if ($this->data["referer"] != "") $url = HTTP::ConvertRelativeToAbsoluteURL($this->data["referer"], $url);
410
-
411
- $urlinfo = HTTP::ExtractURL($url);
412
-
413
- // Initialize the process state array.
414
- $state = array(
415
- "async" => false,
416
- "startts" => $startts,
417
- "redirectts" => $redirectts,
418
- "timeout" => $timeout,
419
- "tempoptions" => $tempoptions,
420
- "httpopts" => $httpopts,
421
- "numfollow" => $numfollow,
422
- "numredirects" => $numredirects,
423
- "totalrawsendsize" => $totalrawsendsize,
424
- "profile" => $profile,
425
- "url" => $url,
426
- "urlinfo" => $urlinfo,
427
-
428
- "state" => "initialize",
429
- "httpstate" => false,
430
- "result" => false,
431
- );
432
-
433
- // Run at least one state cycle to properly initialize the state array.
434
- $result = $this->ProcessState($state);
435
-
436
- // Return the state for async calls. Caller must call ProcessState().
437
- if ($state["async"]) return array("success" => true, "state" => $state);
438
-
439
- return $result;
440
- }
441
-
442
- // Implements the correct MultiAsyncHelper responses for WebBrowser instances.
443
- public function ProcessAsync__Handler($mode, &$data, $key, &$info)
444
- {
445
- switch ($mode)
446
- {
447
- case "init":
448
- {
449
- if ($info["init"]) $data = $info["keep"];
450
- else
451
- {
452
- $info["result"] = $this->Process($info["url"], $info["tempoptions"]);
453
- if (!$info["result"]["success"])
454
- {
455
- $info["keep"] = false;
456
-
457
- if (is_callable($info["callback"])) call_user_func_array($info["callback"], array($key, $info["url"], $info["result"]));
458
- }
459
- else
460
- {
461
- $info["state"] = $info["result"]["state"];
462
-
463
- // Move to the live queue.
464
- $data = true;
465
- }
466
- }
467
-
468
- break;
469
- }
470
- case "update":
471
- case "read":
472
- case "write":
473
- {
474
- if ($info["keep"])
475
- {
476
- $info["result"] = $this->ProcessState($info["state"]);
477
- if ($info["result"]["success"] || $info["result"]["errorcode"] !== "no_data") $info["keep"] = false;
478
-
479
- if (is_callable($info["callback"])) call_user_func_array($info["callback"], array($key, $info["url"], $info["result"]));
480
-
481
- if ($mode === "update") $data = $info["keep"];
482
- }
483
-
484
- break;
485
- }
486
- case "readfps":
487
- {
488
- if ($info["state"]["httpstate"] !== false && HTTP::WantRead($info["state"]["httpstate"])) $data[$key] = $info["state"]["httpstate"]["fp"];
489
-
490
- break;
491
- }
492
- case "writefps":
493
- {
494
- if ($info["state"]["httpstate"] !== false && HTTP::WantWrite($info["state"]["httpstate"])) $data[$key] = $info["state"]["httpstate"]["fp"];
495
-
496
- break;
497
- }
498
- case "cleanup":
499
- {
500
- // When true, caller is removing. Otherwise, detaching from the queue.
501
- if ($data === true)
502
- {
503
- if (isset($info["state"]))
504
- {
505
- if ($info["state"]["httpstate"] !== false) HTTP::ForceClose($info["state"]["httpstate"]);
506
-
507
- unset($info["state"]);
508
- }
509
-
510
- $info["keep"] = false;
511
- }
512
-
513
- break;
514
- }
515
- }
516
- }
517
-
518
- public function ProcessAsync($helper, $key, $callback, $url, $tempoptions = array())
519
- {
520
- $tempoptions["async"] = true;
521
-
522
- // Handle older function call: ProcessAsync($helper, $key, $callback, $url, $profile, $tempoptions)
523
- if (is_string($tempoptions))
524
- {
525
- $args = func_get_args();
526
- if (count($args) < 6) $tempoptions = array();
527
- else $tempoptions = $args[5];
528
-
529
- $tempoptions["profile"] = $args[4];
530
- }
531
-
532
- $profile = (isset($tempoptions["profile"]) ? $tempoptions["profile"] : "auto");
533
-
534
- $info = array(
535
- "init" => false,
536
- "keep" => true,
537
- "callback" => $callback,
538
- "url" => $url,
539
- "tempoptions" => $tempoptions,
540
- "result" => false
541
- );
542
-
543
- $helper->Set($key, $info, array($this, "ProcessAsync__Handler"));
544
-
545
- return array("success" => true);
546
- }
547
-
548
- public function ExtractForms($baseurl, $data, $hint = false)
549
- {
550
- $result = array();
551
-
552
- $lasthint = "";
553
- $hintmap = array();
554
- if ($this->html === false)
555
- {
556
- if (!class_exists("simple_html_dom", false)) require_once str_replace("\\", "/", dirname(__FILE__)) . "/simple_html_dom.php";
557
-
558
- $this->html = new simple_html_dom();
559
- }
560
- $this->html->load($data);
561
- $rows = $this->html->find("label[for]");
562
- foreach ($rows as $row)
563
- {
564
- $hintmap[trim($row->for)] = trim($row->plaintext);
565
- }
566
- $html5rows = $this->html->find("input[form],textarea[form],select[form],button[form],datalist[id]" . ($hint !== false ? "," . $hint : ""));
567
- $rows = $this->html->find("form");
568
- foreach ($rows as $row)
569
- {
570
- $info = array();
571
- if (isset($row->id)) $info["id"] = trim($row->id);
572
- if (isset($row->name)) $info["name"] = (string)$row->name;
573
- $info["action"] = (isset($row->action) ? HTTP::ConvertRelativeToAbsoluteURL($baseurl, (string)$row->action) : $baseurl);
574
- $info["method"] = (isset($row->method) && strtolower(trim($row->method)) == "post" ? "post" : "get");
575
- if ($info["method"] == "post") $info["enctype"] = (isset($row->enctype) ? strtolower($row->enctype) : "application/x-www-form-urlencoded");
576
- if (isset($row->{"accept-charset"})) $info["accept-charset"] = (string)$row->{"accept-charset"};
577
-
578
- $fields = array();
579
- $rows2 = $row->find("input,textarea,select,button" . ($hint !== false ? "," . $hint : ""));
580
- foreach ($rows2 as $row2)
581
- {
582
- if (!isset($row2->form))
583
- {
584
- if (isset($row2->id) && $row2->id != "" && isset($hintmap[trim($row2->id)])) $lasthint = $hintmap[trim($row2->id)];
585
-
586
- $this->ExtractFieldFromDOM($fields, $row2, $lasthint);
587
- }
588
- }
589
-
590
- // Handle HTML5.
591
- if (isset($info["id"]) && $info["id"] != "")
592
- {
593
- foreach ($html5rows as $row2)
594
- {
595
- if (strpos(" " . $info["id"] . " ", " " . $row2->form . " ") !== false)
596
- {
597
- if (isset($hintmap[$info["id"]])) $lasthint = $hintmap[$info["id"]];
598
-
599
- $this->ExtractFieldFromDOM($fields, $row2, $lasthint);
600
- }
601
- }
602
- }
603
-
604
- $form = new WebBrowserForm();
605
- $form->info = $info;
606
- $form->fields = $fields;
607
- $result[] = $form;
608
- }
609
-
610
- return $result;
611
- }
612
-
613
- private function ExtractFieldFromDOM(&$fields, $row, &$lasthint)
614
- {
615
- switch ($row->tag)
616
- {
617
- case "input":
618
- {
619
- if (!isset($row->name) && ($row->type === "submit" || $row->type === "image")) $row->name = "";
620
-
621
- if (isset($row->name) && is_string($row->name))
622
- {
623
- $field = array(
624
- "id" => (isset($row->id) ? (string)$row->id : false),
625
- "type" => "input." . (isset($row->type) ? strtolower($row->type) : "text"),
626
- "name" => $row->name,
627
- "value" => (isset($row->value) ? html_entity_decode($row->value, ENT_COMPAT, "UTF-8") : "")
628
- );
629
- if ($field["type"] == "input.radio" || $field["type"] == "input.checkbox")
630
- {
631
- $field["checked"] = (isset($row->checked));
632
-
633
- if ($field["value"] === "") $field["value"] = "on";
634
- }
635
-
636
- if (isset($row->placeholder)) $field["hint"] = trim($row->placeholder);
637
- else if ($field["type"] == "input.submit" || $field["type"] == "input.image") $field["hint"] = $field["type"] . "|" . $field["value"];
638
- else if ($lasthint !== "") $field["hint"] = $lasthint;
639
-
640
- $fields[] = $field;
641
-
642
- $lasthint = "";
643
- }
644
-
645
- break;
646
- }
647
- case "textarea":
648
- {
649
- if (isset($row->name) && is_string($row->name))
650
- {
651
- $field = array(
652
- "id" => (isset($row->id) ? (string)$row->id : false),
653
- "type" => "textarea",
654
- "name" => $row->name,
655
- "value" => html_entity_decode($row->innertext, ENT_COMPAT, "UTF-8")
656
- );
657
-
658
- if (isset($row->placeholder)) $field["hint"] = trim($row->placeholder);
659
- else if ($lasthint !== "") $field["hint"] = $lasthint;
660
-
661
- $fields[] = $field;
662
-
663
- $lasthint = "";
664
- }
665
-
666
- break;
667
- }
668
- case "select":
669
- {
670
- if (isset($row->name) && is_string($row->name))
671
- {
672
- if (isset($row->multiple))
673
- {
674
- // Change the type into multiple checkboxes.
675
- $rows = $row->find("option");
676
- foreach ($rows as $row2)
677
- {
678
- $field = array(
679
- "id" => (isset($row->id) ? (string)$row->id : false),
680
- "type" => "input.checkbox",
681
- "name" => $row->name,
682
- "value" => (isset($row2->value) ? html_entity_decode($row2->value, ENT_COMPAT, "UTF-8") : ""),
683
- "display" => (string)$row2->innertext
684
- );
685
- if ($lasthint !== "") $field["hint"] = $lasthint;
686
-
687
- $fields[] = $field;
688
- }
689
- }
690
- else
691
- {
692
- $val = false;
693
- $options = array();
694
- $rows = $row->find("option");
695
- foreach ($rows as $row2)
696
- {
697
- $options[$row2->value] = (string)$row2->innertext;
698
-
699
- if ($val === false && isset($row2->selected)) $val = html_entity_decode($row2->value, ENT_COMPAT, "UTF-8");
700
- }
701
- if ($val === false && count($options))
702
- {
703
- $val = array_keys($options);
704
- $val = $val[0];
705
- }
706
- if ($val === false) $val = "";
707
-
708
- $field = array(
709
- "id" => (isset($row->id) ? (string)$row->id : false),
710
- "type" => "select",
711
- "name" => $row->name,
712
- "value" => $val,
713
- "options" => $options
714
- );
715
- if ($lasthint !== "") $field["hint"] = $lasthint;
716
-
717
- $fields[] = $field;
718
- }
719
-
720
- $lasthint = "";
721
- }
722
-
723
- break;
724
- }
725
- case "button":
726
- {
727
- if (isset($row->name) && is_string($row->name))
728
- {
729
- $field = array(
730
- "id" => (isset($row->id) ? (string)$row->id : false),
731
- "type" => "button." . (isset($row->type) ? strtolower($row->type) : "submit"),
732
- "name" => $row->name,
733
- "value" => (isset($row->value) ? html_entity_decode($row->value, ENT_COMPAT, "UTF-8") : "")
734
- );
735
- $field["hint"] = (trim($row->plaintext) !== "" ? trim($row->plaintext) : "button|" . $field["value"]);
736
-
737
- $fields[] = $field;
738
-
739
- $lasthint = "";
740
- }
741
-
742
- break;
743
- }
744
- case "datalist":
745
- {
746
- // Do nothing since browsers don't actually enforce this tag's values.
747
-
748
- break;
749
- }
750
- default:
751
- {
752
- // Hint for the next element.
753
- $lasthint = (string)$row->plaintext;
754
-
755
- break;
756
- }
757
- }
758
- }
759
-
760
- public static function InteractiveFormFill($forms, $showselected = false)
761
- {
762
- if (!is_array($forms)) $forms = array($forms);
763
-
764
- if (!count($forms)) return false;
765
-
766
- if (count($forms) == 1) $form = reset($forms);
767
- else
768
- {
769
- echo self::WBTranslate("There are multiple forms available to fill out:\n");
770
- foreach ($forms as $num => $form)
771
- {
772
- echo self::WBTranslate("\t%d:\n", $num + 1);
773
- foreach ($form->info as $key => $val) echo self::WBTranslate("\t\t%s: %s\n", $key, $val);
774
- echo self::WBTranslate("\t\tfields: %d\n", count($form->GetVisibleFields(false)));
775
- echo self::WBTranslate("\t\tbuttons: %d\n", count($form->GetVisibleFields(true)) - count($form->GetVisibleFields(false)));
776
- echo "\n";
777
- }
778
-
779
- do
780
- {
781
- echo self::WBTranslate("Select: ");
782
-
783
- $num = (int)trim(fgets(STDIN)) - 1;
784
- } while (!isset($forms[$num]));
785
-
786
- $form = $forms[$num];
787
- }
788
-
789
- if ($showselected)
790
- {
791
- echo self::WBTranslate("Selected form:\n");
792
- foreach ($form->info as $key => $val) echo self::WBTranslate("\t%s: %s\n", $key, $val);
793
- echo "\n";
794
- }
795
-
796
- if (count($form->GetVisibleFields(false)))
797
- {
798
- echo self::WBTranslate("Select form fields by field number to edit a field. When ready to submit the form, leave 'Field number' empty.\n\n");
799
-
800
- do
801
- {
802
- echo self::WBTranslate("Editable form fields:\n");
803
- foreach ($form->fields as $num => $field)
804
- {
805
- if ($field["type"] == "input.hidden" || $field["type"] == "input.submit" || $field["type"] == "input.image" || $field["type"] == "input.button" || substr($field["type"], 0, 7) == "button.") continue;
806
-
807
- echo self::WBTranslate("\t%d: %s - %s\n", $num + 1, $field["name"], (is_array($field["value"]) ? json_encode($field["value"], JSON_PRETTY_PRINT) : $field["value"]) . (($field["type"] == "input.radio" || $field["type"] == "input.checkbox") ? ($field["checked"] ? self::WBTranslate(" [Y]") : self::WBTranslate(" [N]")) : "") . (isset($field["hint"]) && $field["hint"] !== "" ? " [" . $field["hint"] . "]" : ""));
808
- }
809
- echo "\n";
810
-
811
- do
812
- {
813
- echo self::WBTranslate("Field number: ");
814
-
815
- $num = trim(fgets(STDIN));
816
- if ($num === "") break;
817
-
818
- $num = (int)$num - 1;
819
- } while (!isset($form->fields[$num]) || $form->fields[$num]["type"] == "input.hidden" || $form->fields[$num]["type"] == "input.submit" || $form->fields[$num]["type"] == "input.image" || $form->fields[$num]["type"] == "input.button" || substr($form->fields[$num]["type"], 0, 7) == "button.");
820
-
821
- if ($num === "")
822
- {
823
- echo "\n";
824
-
825
- break;
826
- }
827
-
828
- $field = $form->fields[$num];
829
- $prefix = (isset($field["hint"]) && $field["hint"] !== "" ? $field["hint"] . " | " : "") . $field["name"];
830
-
831
- if ($field["type"] == "select")
832
- {
833
- echo self::WBTranslate("[%s] Options:\n", $prefix);
834
- foreach ($field["options"] as $key => $val)
835
- {
836
- echo self::WBTranslate("\t%s: %s\n");
837
- }
838
-
839
- do
840
- {
841
- echo self::WBTranslate("[%s] Select: ", $prefix);
842
-
843
- $select = rtrim(fgets(STDIN));
844
- } while (!isset($field["options"][$select]));
845
-
846
- $form->fields[$num]["value"] = $select;
847
- }
848
- else if ($field["type"] == "input.radio")
849
- {
850
- $form->SetFormValue($field["name"], $field["value"], true, "input.radio");
851
- }
852
- else if ($field["type"] == "input.checkbox")
853
- {
854
- $form->fields[$num]["checked"] = !$field["checked"];
855
- }
856
- else if ($field["type"] == "input.file")
857
- {
858
- do
859
- {
860
- echo self::WBTranslate("[%s] Filename: ", $prefix);
861
-
862
- $filename = rtrim(fgets(STDIN));
863
- } while ($filename !== "" && !file_exists($filename));
864
-
865
- if ($filename === "") $form->fields[$num]["value"] = "";
866
- else
867
- {
868
- $form->fields[$num]["value"] = array(
869
- "filename" => $filename,
870
- "type" => "application/octet-stream",
871
- "datafile" => $filename
872
- );
873
- }
874
- }
875
- else
876
- {
877
- echo self::WBTranslate("[%s] New value: ", $prefix);
878
-
879
- $form->fields[$num]["value"] = rtrim(fgets(STDIN));
880
- }
881
-
882
- echo "\n";
883
-
884
- } while (1);
885
- }
886
-
887
- $submitoptions = array(array("name" => self::WBTranslate("Default action"), "value" => self::WBTranslate("Might not work"), "hint" => "Default action"));
888
- foreach ($form->fields as $num => $field)
889
- {
890
- if ($field["type"] != "input.submit" && $field["type"] != "input.image" && $field["type"] != "input.button" && $field["type"] != "button.submit") continue;
891
-
892
- $submitoptions[] = $field;
893
- }
894
-
895
- if (count($submitoptions) <= 2) $num = count($submitoptions) - 1;
896
- else
897
- {
898
- echo self::WBTranslate("Available submit buttons:\n");
899
- foreach ($submitoptions as $num => $field)
900
- {
901
- echo self::WBTranslate("\t%d: %s - %s\n", $num, $field["name"], $field["value"] . (isset($field["hint"]) && $field["hint"] !== "" ? " [" . $field["hint"] . "]" : ""));
902
- }
903
- echo "\n";
904
-
905
- do
906
- {
907
- echo self::WBTranslate("Select: ");
908
-
909
- $num = (int)fgets(STDIN);
910
- } while (!isset($submitoptions[$num]));
911
-
912
- echo "\n";
913
- }
914
-
915
- $result = $form->GenerateFormRequest(($num ? $submitoptions[$num]["name"] : false), ($num ? $submitoptions[$num]["value"] : false));
916
-
917
- return $result;
918
- }
919
-
920
- public function GetCookies()
921
- {
922
- return $this->data["cookies"];
923
- }
924
-
925
- public function SetCookie($cookie)
926
- {
927
- if (!isset($cookie["domain"]) || !isset($cookie["path"]) || !isset($cookie["name"]) || !isset($cookie["value"])) return array("success" => false, "error" => self::WBTranslate("SetCookie() requires 'domain', 'path', 'name', and 'value' to be options."), "errorcode" => "missing_information");
928
-
929
- $cookie["domain"] = strtolower($cookie["domain"]);
930
- if (substr($cookie["domain"], 0, 1) != ".") $cookie["domain"] = "." . $cookie["domain"];
931
-
932
- $cookie["path"] = str_replace("\\", "/", $cookie["path"]);
933
- if (substr($cookie["path"], -1) != "/") $cookie["path"] = "/";
934
-
935
- if (!isset($this->data["cookies"][$cookie["domain"]])) $this->data["cookies"][$cookie["domain"]] = array();
936
- if (!isset($this->data["cookies"][$cookie["domain"]][$cookie["path"]])) $this->data["cookies"][$cookie["domain"]][$cookie["path"]] = array();
937
- $this->data["cookies"][$cookie["domain"]][$cookie["path"]][$cookie["name"]] = $cookie;
938
-
939
- return array("success" => true);
940
- }
941
-
942
- // Simulates closing a web browser.
943
- public function DeleteSessionCookies()
944
- {
945
- foreach ($this->data["cookies"] as $domain => $paths)
946
- {
947
- foreach ($paths as $path => $cookies)
948
- {
949
- foreach ($cookies as $num => $info)
950
- {
951
- if (!isset($info["expires_ts"])) unset($this->data["cookies"][$domain][$path][$num]);
952
- }
953
-
954
- if (!count($this->data["cookies"][$domain][$path])) unset($this->data["cookies"][$domain][$path]);
955
- }
956
-
957
- if (!count($this->data["cookies"][$domain])) unset($this->data["cookies"][$domain]);
958
- }
959
- }
960
-
961
- public function DeleteCookies($domainpattern, $pathpattern, $namepattern)
962
- {
963
- foreach ($this->data["cookies"] as $domain => $paths)
964
- {
965
- if ($domainpattern == "" || substr($domain, -strlen($domainpattern)) == $domainpattern)
966
- {
967
- foreach ($paths as $path => $cookies)
968
- {
969
- if ($pathpattern == "" || substr($path, 0, strlen($pathpattern)) == $pathpattern)
970
- {
971
- foreach ($cookies as $num => $info)
972
- {
973
- if ($namepattern == "" || strpos($info["name"], $namepattern) !== false) unset($this->data["cookies"][$domain][$path][$num]);
974
- }
975
-
976
- if (!count($this->data["cookies"][$domain][$path])) unset($this->data["cookies"][$domain][$path]);
977
- }
978
- }
979
-
980
- if (!count($this->data["cookies"][$domain])) unset($this->data["cookies"][$domain]);
981
- }
982
- }
983
- }
984
-
985
- private function GetExpiresTimestamp($ts)
986
- {
987
- $year = (int)substr($ts, 0, 4);
988
- $month = (int)substr($ts, 5, 2);
989
- $day = (int)substr($ts, 8, 2);
990
- $hour = (int)substr($ts, 11, 2);
991
- $min = (int)substr($ts, 14, 2);
992
- $sec = (int)substr($ts, 17, 2);
993
-
994
- return gmmktime($hour, $min, $sec, $month, $day, $year);
995
- }
996
-
997
- public static function WBTranslate()
998
- {
999
- $args = func_get_args();
1000
- if (!count($args)) return "";
1001
-
1002
- return call_user_func_array((defined("CS_TRANSLATE_FUNC") && function_exists(CS_TRANSLATE_FUNC) ? CS_TRANSLATE_FUNC : "sprintf"), $args);
1003
- }
1004
- }
1005
-
1006
- class WebBrowserForm
1007
- {
1008
- public $info, $fields;
1009
-
1010
- public function __construct()
1011
- {
1012
- $this->info = array();
1013
- $this->fields = array();
1014
- }
1015
-
1016
- public function FindFormFields($name = false, $value = false, $type = false)
1017
- {
1018
- $fields = array();
1019
- foreach ($this->fields as $num => $field)
1020
- {
1021
- if (($type === false || $field["type"] === $type) && ($name === false || $field["name"] === $name) && ($value === false || $field["value"] === $value))
1022
- {
1023
- $fields[] = $field;
1024
- }
1025
- }
1026
-
1027
- return $fields;
1028
- }
1029
-
1030
- public function GetHintMap()
1031
- {
1032
- $result = array();
1033
- foreach ($this->fields as $num => $field)
1034
- {
1035
- if (isset($field["hint"])) $result[$field["hint"]] = $field["name"];
1036
- }
1037
-
1038
- return $result;
1039
- }
1040
-
1041
- public function GetVisibleFields($submit)
1042
- {
1043
- $result = array();
1044
- foreach ($this->fields as $num => $field)
1045
- {
1046
- if ($field["type"] == "input.hidden" || (!$submit && ($field["type"] == "input.submit" || $field["type"] == "input.image" || $field["type"] == "input.button" || substr($field["type"], 0, 7) == "button."))) continue;
1047
-
1048
- $result[$num] = $field;
1049
- }
1050
-
1051
- return $result;
1052
- }
1053
-
1054
- public function GetFormValue($name, $checkval = false, $type = false)
1055
- {
1056
- $val = false;
1057
- foreach ($this->fields as $field)
1058
- {
1059
- if (($type === false || $field["type"] === $type) && $field["name"] === $name)
1060
- {
1061
- if (is_string($checkval))
1062
- {
1063
- if ($checkval === $field["value"])
1064
- {
1065
- if ($field["type"] == "input.radio" || $field["type"] == "input.checkbox") $val = $field["checked"];
1066
- else $val = $field["value"];
1067
- }
1068
- }
1069
- else if (($field["type"] != "input.radio" && $field["type"] != "input.checkbox") || $field["checked"])
1070
- {
1071
- $val = $field["value"];
1072
- }
1073
- }
1074
- }
1075
-
1076
- return $val;
1077
- }
1078
-
1079
- public function SetFormValue($name, $value, $checked = false, $type = false, $create = false)
1080
- {
1081
- $result = false;
1082
- foreach ($this->fields as $num => $field)
1083
- {
1084
- if (($type === false || $field["type"] === $type) && $field["name"] === $name)
1085
- {
1086
- if ($field["type"] == "input.radio")
1087
- {
1088
- $this->fields[$num]["checked"] = ($field["value"] === $value ? $checked : false);
1089
- $result = true;
1090
- }
1091
- else if ($field["type"] == "input.checkbox")
1092
- {
1093
- if ($field["value"] === $value) $this->fields[$num]["checked"] = $checked;
1094
- $result = true;
1095
- }
1096
- else if ($field["type"] != "select" || !isset($field["options"]) || isset($field["options"][$value]))
1097
- {
1098
- $this->fields[$num]["value"] = $value;
1099
- $result = true;
1100
- }
1101
- }
1102
- }
1103
-
1104
- // Add the field if it doesn't exist.
1105
- if (!$result && $create)
1106
- {
1107
- $this->fields[] = array(
1108
- "id" => false,
1109
- "type" => ($type !== false ? $type : "input.text"),
1110
- "name" => $name,
1111
- "value" => $value,
1112
- "checked" => $checked
1113
- );
1114
- }
1115
-
1116
- return $result;
1117
- }
1118
-
1119
- public function GenerateFormRequest($submitname = false, $submitvalue = false)
1120
- {
1121
- $method = $this->info["method"];
1122
- $fields = array();
1123
- $files = array();
1124
- foreach ($this->fields as $field)
1125
- {
1126
- if ($field["type"] == "input.file")
1127
- {
1128
- if (is_array($field["value"]))
1129
- {
1130
- $field["value"]["name"] = $field["name"];
1131
- $files[] = $field["value"];
1132
- $method = "post";
1133
- }
1134
- }
1135
- else if ($field["type"] == "input.reset" || $field["type"] == "button.reset")
1136
- {
1137
- }
1138
- else if ($field["type"] == "input.submit" || $field["type"] == "input.image" || $field["type"] == "button.submit")
1139
- {
1140
- if (($submitname === false || $field["name"] === $submitname) && ($submitvalue === false || $field["value"] === $submitvalue))
1141
- {
1142
- if ($submitname !== "")
1143
- {
1144
- if (!isset($fields[$field["name"]])) $fields[$field["name"]] = array();
1145
- $fields[$field["name"]][] = $field["value"];
1146
- }
1147
-
1148
- if ($field["type"] == "input.image")
1149
- {
1150
- if (!isset($fields["x"])) $fields["x"] = array();
1151
- $fields["x"][] = "1";
1152
-
1153
- if (!isset($fields["y"])) $fields["y"] = array();
1154
- $fields["y"][] = "1";
1155
- }
1156
- }
1157
- }
1158
- else if (($field["type"] != "input.radio" && $field["type"] != "input.checkbox") || $field["checked"])
1159
- {
1160
- if (!isset($fields[$field["name"]])) $fields[$field["name"]] = array();
1161
- $fields[$field["name"]][] = $field["value"];
1162
- }
1163
- }
1164
-
1165
- if ($method == "get")
1166
- {
1167
- $url = HTTP::ExtractURL($this->info["action"]);
1168
- unset($url["query"]);
1169
- $url["queryvars"] = $fields;
1170
- $result = array(
1171
- "url" => HTTP::CondenseURL($url),
1172
- "options" => array()
1173
- );
1174
- }
1175
- else
1176
- {
1177
- $result = array(
1178
- "url" => $this->info["action"],
1179
- "options" => array(
1180
- "postvars" => $fields,
1181
- "files" => $files
1182
- )
1183
- );
1184
- }
1185
-
1186
- return $result;
1187
- }
1188
- }
1189
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/ultimate-web-scraper/websocket.php DELETED
@@ -1,654 +0,0 @@
1
- <?php
2
- // CubicleSoft PHP WebSocket class.
3
- // (C) 2017 CubicleSoft. All Rights Reserved.
4
-
5
- // Implements RFC 6455 (WebSocket protocol).
6
- // Requires the CubicleSoft PHP HTTP/HTTPS class.
7
- // Requires the CubicleSoft PHP WebBrowser class.
8
- class WebSocket
9
- {
10
- private $fp, $client, $extensions, $csprng, $state, $closemode;
11
- private $readdata, $maxreadframesize, $readmessages, $maxreadmessagesize;
12
- private $writedata, $writemessages, $keepalive, $lastkeepalive, $keepalivesent;
13
- private $rawrecvsize, $rawsendsize;
14
-
15
- const KEY_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
16
-
17
- const STATE_CONNECTING = 0;
18
- const STATE_OPEN = 1;
19
- const STATE_CLOSE = 2;
20
-
21
- const CLOSE_IMMEDIATELY = 0;
22
- const CLOSE_AFTER_CURRENT_MESSAGE = 1;
23
- const CLOSE_AFTER_ALL_MESSAGES = 2;
24
-
25
- const FRAMETYPE_CONTINUATION = 0x00;
26
- const FRAMETYPE_TEXT = 0x01;
27
- const FRAMETYPE_BINARY = 0x02;
28
-
29
- const FRAMETYPE_CONNECTION_CLOSE = 0x08;
30
- const FRAMETYPE_PING = 0x09;
31
- const FRAMETYPE_PONG = 0x0A;
32
-
33
- public function __construct()
34
- {
35
- $this->Reset();
36
- }
37
-
38
- public function __destruct()
39
- {
40
- $this->Disconnect();
41
- }
42
-
43
- public function Reset()
44
- {
45
- $this->fp = false;
46
- $this->client = true;
47
- $this->extensions = array();
48
- $this->csprng = false;
49
- $this->state = self::STATE_CONNECTING;
50
- $this->closemode = self::CLOSE_IMMEDIATELY;
51
- $this->readdata = "";
52
- $this->maxreadframesize = 2000000;
53
- $this->readmessages = array();
54
- $this->maxreadmessagesize = 10000000;
55
- $this->writedata = "";
56
- $this->writemessages = array();
57
- $this->keepalive = 30;
58
- $this->lastkeepalive = time();
59
- $this->keepalivesent = false;
60
- $this->rawrecvsize = 0;
61
- $this->rawsendsize = 0;
62
- }
63
-
64
- public function SetServerMode()
65
- {
66
- $this->client = false;
67
- }
68
-
69
- public function SetClientMode()
70
- {
71
- $this->client = true;
72
- }
73
-
74
- public function SetExtensions($extensions)
75
- {
76
- $this->extensions = (array)$extensions;
77
- }
78
-
79
- public function SetCloseMode($mode)
80
- {
81
- $this->closemode = $mode;
82
- }
83
-
84
- public function SetKeepAliveTimeout($keepalive)
85
- {
86
- $this->keepalive = (int)$keepalive;
87
- }
88
-
89
- public function GetKeepAliveTimeout()
90
- {
91
- return $this->keepalive;
92
- }
93
-
94
- public function SetMaxReadFrameSize($maxsize)
95
- {
96
- $this->maxreadframesize = (is_bool($maxsize) ? false : (int)$maxsize);
97
- }
98
-
99
- public function SetMaxReadMessageSize($maxsize)
100
- {
101
- $this->maxreadmessagesize = (is_bool($maxsize) ? false : (int)$maxsize);
102
- }
103
-
104
- public function GetRawRecvSize()
105
- {
106
- return $this->rawrecvsize;
107
- }
108
-
109
- public function GetRawSendSize()
110
- {
111
- return $this->rawsendsize;
112
- }
113
-
114
- public function Connect($url, $origin, $options = array(), $web = false)
115
- {
116
- $this->Disconnect();
117
-
118
- if (class_exists("CSPRNG", false) && $this->csprng === false) $this->csprng = new CSPRNG();
119
-
120
- if (isset($options["connected_fp"]) && is_resource($options["connected_fp"])) $this->fp = $options["connected_fp"];
121
- else
122
- {
123
- if (!class_exists("WebBrowser", false)) require_once str_replace("\\", "/", dirname(__FILE__)) . "/web_browser.php";
124
-
125
- // Use WebBrowser to initiate the connection.
126
- if ($web === false) $web = new WebBrowser();
127
-
128
- // Transform URL.
129
- $url2 = HTTP::ExtractURL($url);
130
- if ($url2["scheme"] != "ws" && $url2["scheme"] != "wss") return array("success" => false, "error" => self::WSTranslate("WebSocket::Connect() only supports the 'ws' and 'wss' protocols."), "errorcode" => "protocol_check");
131
- $url2["scheme"] = str_replace("ws", "http", $url2["scheme"]);
132
- $url2 = HTTP::CondenseURL($url2);
133
-
134
- // Generate correct request headers.
135
- if (!isset($options["headers"])) $options["headers"] = array();
136
- $options["headers"]["Connection"] = "keep-alive, Upgrade";
137
- if ($origin != "") $options["headers"]["Origin"] = $origin;
138
- $options["headers"]["Pragma"] = "no-cache";
139
- $key = base64_encode($this->PRNGBytes(16));
140
- $options["headers"]["Sec-WebSocket-Key"] = $key;
141
- $options["headers"]["Sec-WebSocket-Version"] = "13";
142
- $options["headers"]["Upgrade"] = "websocket";
143
-
144
- // No async support for connecting at this time. Async mode is enabled AFTER connecting though.
145
- unset($options["async"]);
146
-
147
- // Connect to the WebSocket.
148
- $result = $web->Process($url2, $options);
149
- if (!$result["success"]) return $result;
150
- if ($result["response"]["code"] != 101) return array("success" => false, "error" => self::WSTranslate("WebSocket::Connect() failed to connect to the WebSocket. Server returned: %s %s", $result["response"]["code"], $result["response"]["meaning"]), "errorcode" => "incorrect_server_response");
151
- if (!isset($result["headers"]["Sec-Websocket-Accept"])) return array("success" => false, "error" => self::WSTranslate("Server failed to include a 'Sec-WebSocket-Accept' header in its response to the request."), "errorcode" => "missing_server_websocket_accept_header");
152
-
153
- // Verify the Sec-WebSocket-Accept response.
154
- if ($result["headers"]["Sec-Websocket-Accept"][0] !== base64_encode(sha1($key . self::KEY_GUID, true))) return array("success" => false, "error" => self::WSTranslate("The server's 'Sec-WebSocket-Accept' header is invalid."), "errorcode" => "invalid_server_websocket_accept_header");
155
-
156
- $this->fp = $result["fp"];
157
- }
158
-
159
- // Enable non-blocking mode.
160
- stream_set_blocking($this->fp, 0);
161
-
162
- $this->state = self::STATE_OPEN;
163
-
164
- $this->readdata = "";
165
- $this->readmessages = array();
166
- $this->writedata = "";
167
- $this->writemessages = array();
168
- $this->lastkeepalive = time();
169
- $this->keepalivesent = false;
170
- $this->rawrecvsize = 0;
171
- $this->rawsendsize = 0;
172
-
173
- return array("success" => true);
174
- }
175
-
176
- public function Disconnect()
177
- {
178
- if ($this->fp !== false && $this->state === self::STATE_OPEN)
179
- {
180
- if ($this->closemode === self::CLOSE_IMMEDIATELY) $this->writemessages = array();
181
- else if ($this->closemode === self::CLOSE_AFTER_CURRENT_MESSAGE) $this->writemessages = array_slice($this->writemessages, 0, 1);
182
-
183
- $this->state = self::STATE_CLOSE;
184
-
185
- $this->Write("", self::FRAMETYPE_CONNECTION_CLOSE, true, $this->client);
186
-
187
- $this->Wait($this->client ? false : 0);
188
- }
189
-
190
- if ($this->fp !== false)
191
- {
192
- @fclose($this->fp);
193
-
194
- $this->fp = false;
195
- }
196
-
197
- $this->state = self::STATE_CONNECTING;
198
- $this->readdata = "";
199
- $this->readmessages = array();
200
- $this->writedata = "";
201
- $this->writemessages = array();
202
- $this->lastkeepalive = time();
203
- $this->keepalivesent = false;
204
- }
205
-
206
- // Reads the next message or message fragment (depending on $finished). Returns immediately unless $wait is not false.
207
- public function Read($finished = true, $wait = false)
208
- {
209
- if ($this->fp === false || $this->state === self::STATE_CONNECTING) return array("success" => false, "error" => self::WSTranslate("Connection not established."), "errorcode" => "no_connection");
210
-
211
- if ($wait)
212
- {
213
- while (!count($this->readmessages) || ($finished && !$this->readmessages[0]["fin"]))
214
- {
215
- $result = $this->Wait();
216
- if (!$result["success"]) return $result;
217
- }
218
- }
219
-
220
- $data = false;
221
-
222
- if (count($this->readmessages))
223
- {
224
- if ($finished)
225
- {
226
- if ($this->readmessages[0]["fin"]) $data = array_shift($this->readmessages);
227
- }
228
- else
229
- {
230
- $data = $this->readmessages[0];
231
-
232
- $this->readmessages[0]["payload"] = "";
233
- }
234
- }
235
-
236
- return array("success" => true, "data" => $data);
237
- }
238
-
239
- // Adds the message to the write queue. Returns immediately unless $wait is not false.
240
- public function Write($message, $frametype, $last = true, $wait = false, $pos = false)
241
- {
242
- if ($this->fp === false || $this->state === self::STATE_CONNECTING) return array("success" => false, "error" => self::WSTranslate("Connection not established."), "errorcode" => "no_connection");
243
-
244
- $message = (string)$message;
245
-
246
- $y = count($this->writemessages);
247
- $lastcompleted = (!$y || $this->writemessages[$y - 1]["fin"]);
248
- if ($frametype >= 0x08 || $lastcompleted)
249
- {
250
- if ($frametype >= 0x08) $last = true;
251
- else $pos = false;
252
-
253
- $frame = array(
254
- "fin" => (bool)$last,
255
- "framessent" => 0,
256
- "opcode" => $frametype,
257
- "payloads" => array($message)
258
- );
259
-
260
- array_splice($this->writemessages, ($pos !== false ? $pos : $y), 0, array($frame));
261
- }
262
- else
263
- {
264
- if ($frametype !== $this->writemessages[$y - 1]["opcode"]) return array("success" => false, "error" => self::WSTranslate("Mismatched frame type (opcode) specified."), "errorcode" => "mismatched_frame_type");
265
-
266
- $this->writemessages[$y - 1]["fin"] = (bool)$last;
267
- $this->writemessages[$y - 1]["payloads"][] = $message;
268
- }
269
-
270
- if ($wait)
271
- {
272
- while ($this->NeedsWrite())
273
- {
274
- $result = $this->Wait();
275
- if (!$result["success"]) return $result;
276
- }
277
- }
278
-
279
- return array("success" => true);
280
- }
281
-
282
- public function NeedsWrite()
283
- {
284
- $this->FillWriteData();
285
-
286
- return ($this->writedata !== "");
287
- }
288
-
289
- public function NumWriteMessages()
290
- {
291
- return count($this->writemessages);
292
- }
293
-
294
- // Dangerous but allows for stream_select() calls on multiple, separate stream handles.
295
- public function GetStream()
296
- {
297
- return $this->fp;
298
- }
299
-
300
- // Waits until one or more events time out, handles reading and writing, processes the queues (handle control types automatically), and returns the latest status.
301
- public function Wait($timeout = false)
302
- {
303
- if ($this->fp === false || $this->state === self::STATE_CONNECTING) return array("success" => false, "error" => self::WSTranslate("Connection not established."), "errorcode" => "no_connection");
304
-
305
- $result = $this->ProcessReadData();
306
- if (!$result["success"]) return $result;
307
-
308
- $this->FillWriteData();
309
-
310
- $readfp = array($this->fp);
311
- $writefp = ($this->writedata !== "" ? array($this->fp) : NULL);
312
- $exceptfp = NULL;
313
- if ($timeout === false || $timeout > $this->keepalive) $timeout = $this->keepalive;
314
- $result = @stream_select($readfp, $writefp, $exceptfp, $timeout);
315
- if ($result === false) return array("success" => false, "error" => self::WSTranslate("Wait() failed due to stream_select() failure. Most likely cause: Connection failure."), "errorcode" => "stream_select_failed");
316
-
317
- // Process queues and timeouts.
318
- $result = $this->ProcessQueuesAndTimeoutState(($result > 0 && count($readfp)), ($result > 0 && $writefp !== NULL && count($writefp)));
319
-
320
- return $result;
321
- }
322
-
323
- // A mostly internal function. Useful for managing multiple simultaneous WebSocket connections.
324
- public function ProcessQueuesAndTimeoutState($read, $write, $readsize = 65536)
325
- {
326
- if ($this->fp === false || $this->state === self::STATE_CONNECTING) return array("success" => false, "error" => self::WSTranslate("Connection not established."), "errorcode" => "no_connection");
327
-
328
- if ($read)
329
- {
330
- $result = @fread($this->fp, $readsize);
331
- if ($result === false || ($result === "" && feof($this->fp))) return array("success" => false, "error" => self::WSTranslate("ProcessQueuesAndTimeoutState() failed due to fread() failure. Most likely cause: Connection failure."), "errorcode" => "fread_failed");
332
-
333
- if ($result !== "")
334
- {
335
- $this->rawrecvsize += strlen($result);
336
- $this->readdata .= $result;
337
-
338
- if ($this->maxreadframesize !== false && strlen($this->readdata) > $this->maxreadframesize) return array("success" => false, "error" => self::WSTranslate("ProcessQueuesAndTimeoutState() failed due to peer sending a single frame exceeding %s bytes of data.", $this->maxreadframesize), "errorcode" => "max_read_frame_size_exceeded");
339
-
340
- $result = $this->ProcessReadData();
341
- if (!$result["success"]) return $result;
342
-
343
- $this->lastkeepalive = time();
344
- $this->keepalivesent = false;
345
- }
346
- }
347
-
348
- if ($write)
349
- {
350
- $result = @fwrite($this->fp, $this->writedata);
351
- if ($result === false || ($this->writedata === "" && feof($this->fp))) return array("success" => false, "error" => self::WSTranslate("ProcessQueuesAndTimeoutState() failed due to fwrite() failure. Most likely cause: Connection failure."), "errorcode" => "fwrite_failed");
352
-
353
- if ($result)
354
- {
355
- $this->rawsendsize += $result;
356
- $this->writedata = (string)substr($this->writedata, $result);
357
-
358
- $this->lastkeepalive = time();
359
- $this->keepalivesent = false;
360
- }
361
- }
362
-
363
- // Handle timeout state.
364
- if ($this->lastkeepalive < time() - $this->keepalive)
365
- {
366
- if ($this->keepalivesent) return array("success" => false, "error" => self::WSTranslate("ProcessQueuesAndTimeoutState() failed due to non-response from peer to ping frame. Most likely cause: Connection failure."), "errorcode" => "ping_failed");
367
- else
368
- {
369
- $result = $this->Write(time(), self::FRAMETYPE_PING, true, false, 0);
370
- if (!$result["success"]) return $result;
371
-
372
- $this->lastkeepalive = time();
373
- $this->keepalivesent = true;
374
- }
375
- }
376
-
377
- return array("success" => true);
378
- }
379
-
380
- protected function ProcessReadData()
381
- {
382
- while (($frame = $this->ReadFrame()) !== false)
383
- {
384
- // Verify that the opcode is probably valid.
385
- if (($frame["opcode"] >= 0x03 && $frame["opcode"] <= 0x07) || $frame["opcode"] >= 0x0B) return array("success" => false, "error" => self::WSTranslate("Invalid frame detected. Bad opcode 0x%02X.", $frame["opcode"]), "errorcode" => "bad_frame_opcode");
386
-
387
- // No extension support (yet).
388
- if ($frame["rsv1"] || $frame["rsv2"] || $frame["rsv3"]) return array("success" => false, "error" => self::WSTranslate("Invalid frame detected. One or more reserved extension bits are set."), "errorcode" => "bad_reserved_bits_set");
389
-
390
- if ($frame["opcode"] >= 0x08)
391
- {
392
- // Handle the control frame.
393
- if (!$frame["fin"]) return array("success" => false, "error" => self::WSTranslate("Invalid frame detected. Fragmented control frame was received."), "errorcode" => "bad_control_frame");
394
-
395
- if ($frame["opcode"] === self::FRAMETYPE_CONNECTION_CLOSE)
396
- {
397
- if ($this->state === self::STATE_CLOSE)
398
- {
399
- // Already sent the close state.
400
- @fclose($this->fp);
401
- $this->fp = false;
402
-
403
- return array("success" => false, "error" => self::WSTranslate("Connection closed by peer."), "errorcode" => "connection_closed");
404
- }
405
- else
406
- {
407
- // Change the state to close and send the connection close response to the peer at the appropriate time.
408
- if ($this->closemode === self::CLOSE_IMMEDIATELY) $this->writemessages = array();
409
- else if ($this->closemode === self::CLOSE_AFTER_CURRENT_MESSAGE) $this->writemessages = array_slice($this->writemessages, 0, 1);
410
-
411
- $this->state = self::STATE_CLOSE;
412
-
413
- $result = $this->Write("", self::FRAMETYPE_CONNECTION_CLOSE);
414
- if (!$result["success"]) return $result;
415
- }
416
- }
417
- else if ($frame["opcode"] === self::FRAMETYPE_PING)
418
- {
419
- if ($this->state !== self::STATE_CLOSE)
420
- {
421
- // Received a ping. Respond with a pong with the same payload.
422
- $result = $this->Write($frame["payload"], self::FRAMETYPE_PONG, true, false, 0);
423
- if (!$result["success"]) return $result;
424
- }
425
- }
426
- else if ($frame["opcode"] === self::FRAMETYPE_PONG)
427
- {
428
- // Do nothing.
429
- }
430
- }
431
- else
432
- {
433
- // Add this frame to the read message queue.
434
- $lastcompleted = (!count($this->readmessages) || $this->readmessages[count($this->readmessages) - 1]["fin"]);
435
- if ($lastcompleted)
436
- {
437
- // Make sure the new frame is the start of a fragment or is not fragemented.
438
- if ($frame["opcode"] === self::FRAMETYPE_CONTINUATION) return array("success" => false, "error" => self::WSTranslate("Invalid frame detected. Fragment continuation frame was received at the start of a fragment."), "errorcode" => "bad_continuation_frame");
439
-
440
- $this->readmessages[] = $frame;
441
- }
442
- else
443
- {
444
- // Make sure the frame is a continuation frame.
445
- if ($frame["opcode"] !== self::FRAMETYPE_CONTINUATION) return array("success" => false, "error" => self::WSTranslate("Invalid frame detected. Fragment continuation frame was not received for a fragment."), "errorcode" => "missing_continuation_frame");
446
-
447
- $this->readmessages[count($this->readmessages) - 1]["fin"] = $frame["fin"];
448
- $this->readmessages[count($this->readmessages) - 1]["payload"] .= $frame["payload"];
449
- }
450
-
451
- if ($this->maxreadmessagesize !== false && strlen($this->readmessages[count($this->readmessages) - 1]["payload"]) > $this->maxreadmessagesize) return array("success" => false, "error" => self::WSTranslate("Peer sent a single message exceeding %s bytes of data.", $this->maxreadmessagesize), "errorcode" => "max_read_message_size_exceeded");
452
- }
453
-
454
- //var_dump($frame);
455
- }
456
-
457
- return array("success" => true);
458
- }
459
-
460
- // Parses the current input data to see if there is enough information to extract a single frame.
461
- // Does not do any error checking beyond loading the frame and decoding any masked data.
462
- protected function ReadFrame()
463
- {
464
- if (strlen($this->readdata) < 2) return false;
465
-
466
- $chr = ord($this->readdata{0});
467
- $fin = (($chr & 0x80) ? true : false);
468
- $rsv1 = (($chr & 0x40) ? true : false);
469
- $rsv2 = (($chr & 0x20) ? true : false);
470
- $rsv3 = (($chr & 0x10) ? true : false);
471
- $opcode = $chr & 0x0F;
472
-
473
- $chr = ord($this->readdata{1});
474
- $mask = (($chr & 0x80) ? true : false);
475
- $length = $chr & 0x7F;
476
- if ($length == 126) $start = 4;
477
- else if ($length == 127) $start = 10;
478
- else $start = 2;
479
-
480
- if (strlen($this->readdata) < $start + ($mask ? 4 : 0)) return false;
481
-
482
- // Frame minus payload calculated.
483
- if ($length == 126) $length = self::UnpackInt(substr($this->readdata, 2, 2));
484
- else if ($length == 127) $length = self::UnpackInt(substr($this->readdata, 2, 8));
485
-
486
- if ($mask)
487
- {
488
- $maskingkey = substr($this->readdata, $start, 4);
489
- $start += 4;
490
- }
491
-
492
- if (strlen($this->readdata) < $start + $length) return false;
493
-
494
- $payload = substr($this->readdata, $start, $length);
495
-
496
- $this->readdata = substr($this->readdata, $start + $length);
497
-
498
- if ($mask)
499
- {
500
- // Decode the payload.
501
- for ($x = 0; $x < $length; $x++)
502
- {
503
- $payload{$x} = chr(ord($payload{$x}) ^ ord($maskingkey{$x % 4}));
504
- }
505
- }
506
-
507
- $result = array(
508
- "fin" => $fin,
509
- "rsv1" => $rsv1,
510
- "rsv2" => $rsv2,
511
- "rsv3" => $rsv3,
512
- "opcode" => $opcode,
513
- "mask" => $mask,
514
- "payload" => $payload
515
- );
516
-
517
- return $result;
518
- }
519
-
520
- // Converts messages in the queue to a data stream of frames.
521
- protected function FillWriteData()
522
- {
523
- while (strlen($this->writedata) < 65536 && count($this->writemessages) && count($this->writemessages[0]["payloads"]))
524
- {
525
- $payload = array_shift($this->writemessages[0]["payloads"]);
526
-
527
- $fin = ($this->writemessages[0]["fin"] && !count($this->writemessages[0]["payloads"]));
528
-
529
- if ($this->writemessages[0]["framessent"] === 0) $opcode = $this->writemessages[0]["opcode"];
530
- else $opcode = self::FRAMETYPE_CONTINUATION;
531
-
532
- $this->WriteFrame($fin, $opcode, $payload);
533
-
534
- $this->writemessages[0]["framessent"]++;
535
-
536
- if ($fin) array_shift($this->writemessages);
537
- }
538
- }
539
-
540
- // Generates the actual frame data to be sent.
541
- protected function WriteFrame($fin, $opcode, $payload)
542
- {
543
- $rsv1 = false;
544
- $rsv2 = false;
545
- $rsv3 = false;
546
- $mask = $this->client;
547
-
548
- $data = chr(($fin ? 0x80 : 0x00) | ($rsv1 ? 0x40 : 0x00) | ($rsv2 ? 0x20 : 0x00) | ($rsv3 ? 0x10 : 0x00) | ($opcode & 0x0F));
549
-
550
- if (strlen($payload) < 126) $length = strlen($payload);
551
- else if (strlen($payload) < 65536) $length = 126;
552
- else $length = 127;
553
-
554
- $data .= chr(($mask ? 0x80 : 0x00) | ($length & 0x7F));
555
-
556
- if ($length === 126) $data .= pack("n", strlen($payload));
557
- else if ($length === 127) $data .= self::PackInt64(strlen($payload));
558
-
559
- if ($mask)
560
- {
561
- $maskingkey = $this->PRNGBytes(4);
562
- $data .= $maskingkey;
563
-
564
- // Encode the payload.
565
- $y = strlen($payload);
566
- for ($x = 0; $x < $y; $x++)
567
- {
568
- $payload{$x} = chr(ord($payload{$x}) ^ ord($maskingkey{$x % 4}));
569
- }
570
- }
571
-
572
- $data .= $payload;
573
-
574
- $this->writedata .= $data;
575
- }
576
-
577
- // This function follows the specification IF CSPRNG is available, but it isn't necessary to do so.
578
- protected function PRNGBytes($length)
579
- {
580
- if ($this->csprng !== false) $result = $this->csprng->GetBytes($length);
581
- else
582
- {
583
- $result = "";
584
- while (strlen($result) < $length) $result .= chr(mt_rand(0, 255));
585
- }
586
-
587
- return $result;
588
- }
589
-
590
- public static function UnpackInt($data)
591
- {
592
- if ($data === false) return false;
593
-
594
- if (strlen($data) == 2) $result = unpack("n", $data);
595
- else if (strlen($data) == 4) $result = unpack("N", $data);
596
- else if (strlen($data) == 8)
597
- {
598
- $result = 0;
599
- for ($x = 0; $x < 8; $x++)
600
- {
601
- $result = ($result * 256) + ord($data{$x});
602
- }
603
-
604
- return $result;
605
- }
606
- else return false;
607
-
608
- return $result[1];
609
- }
610
-
611
- public static function PackInt64($num)
612
- {
613
- $result = "";
614
-
615
- if (is_int(2147483648)) $floatlim = 9223372036854775808;
616
- else $floatlim = 2147483648;
617
-
618
- if (is_float($num))
619
- {
620
- $num = floor($num);
621
- if ($num < (double)$floatlim) $num = (int)$num;
622
- }
623
-
624
- while (is_float($num))
625
- {
626
- $byte = (int)fmod($num, 256);
627
- $result = chr($byte) . $result;
628
-
629
- $num = floor($num / 256);
630
- if (is_float($num) && $num < (double)$floatlim) $num = (int)$num;
631
- }
632
-
633
- while ($num > 0)
634
- {
635
- $byte = $num & 0xFF;
636
- $result = chr($byte) . $result;
637
- $num = $num >> 8;
638
- }
639
-
640
- $result = str_pad($result, 8, "\x00", STR_PAD_LEFT);
641
- $result = substr($result, -8);
642
-
643
- return $result;
644
- }
645
-
646
- public static function WSTranslate()
647
- {
648
- $args = func_get_args();
649
- if (!count($args)) return "";
650
-
651
- return call_user_func_array((defined("CS_TRANSLATE_FUNC") && function_exists(CS_TRANSLATE_FUNC) ? CS_TRANSLATE_FUNC : "sprintf"), $args);
652
- }
653
- }
654
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/icomoon/fonts/ez-toc-icomoon.woff2 DELETED
Binary file
vendor/icomoon/style.css CHANGED
@@ -1,12 +1,10 @@
1
  @font-face {
2
- font-display: swap;
3
  font-family: 'ez-toc-icomoon';
4
- src:url('fonts/ez-toc-icomoon.eot');
5
- src:url('fonts/ez-toc-icomoon.eot?#iefix') format('embedded-opentype'),
6
- url('fonts/ez-toc-icomoon.woff2') format('woff2'),
7
- url('fonts/ez-toc-icomoon.woff') format('woff'),
8
- url('fonts/ez-toc-icomoon.ttf') format('truetype'),
9
- url('fonts/ez-toc-icomoon.svg#ez-toc-icomoon') format('svg');
10
  font-weight: normal;
11
  font-style: normal;
12
  }
1
  @font-face {
 
2
  font-family: 'ez-toc-icomoon';
3
+ src:url('fonts/ez-toc-icomoon.eot?-5j7dhv');
4
+ src:url('fonts/ez-toc-icomoon.eot?#iefix-5j7dhv') format('embedded-opentype'),
5
+ url('fonts/ez-toc-icomoon.ttf?-5j7dhv') format('truetype'),
6
+ url('fonts/ez-toc-icomoon.woff?-5j7dhv') format('woff'),
7
+ url('fonts/ez-toc-icomoon.svg?-5j7dhv#ez-toc-icomoon') format('svg');
 
8
  font-weight: normal;
9
  font-style: normal;
10
  }
vendor/js-cookie/js.cookie.js CHANGED
@@ -1,25 +1,20 @@
1
  /*!
2
- * JavaScript Cookie v2.2.1
3
  * https://github.com/js-cookie/js-cookie
4
  *
5
  * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
6
  * Released under the MIT license
7
  */
8
- ;(function (factory) {
9
- var registeredInModuleLoader;
10
  if (typeof define === 'function' && define.amd) {
11
  define(factory);
12
- registeredInModuleLoader = true;
13
- }
14
- if (typeof exports === 'object') {
15
  module.exports = factory();
16
- registeredInModuleLoader = true;
17
- }
18
- if (!registeredInModuleLoader) {
19
- var OldCookies = window.Cookies;
20
  var api = window.Cookies = factory();
21
  api.noConflict = function () {
22
- window.Cookies = OldCookies;
23
  return api;
24
  };
25
  }
@@ -36,128 +31,109 @@
36
  return result;
37
  }
38
 
39
- function decode (s) {
40
- return s.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent);
41
- }
42
-
43
  function init (converter) {
44
- function api() {}
 
45
 
46
- function set (key, value, attributes) {
47
- if (typeof document === 'undefined') {
48
- return;
49
- }
50
 
51
- attributes = extend({
52
- path: '/'
53
- }, api.defaults, attributes);
 
54
 
55
- if (typeof attributes.expires === 'number') {
56
- attributes.expires = new Date(new Date() * 1 + attributes.expires * 864e+5);
57
- }
58
-
59
- // We're using "expires" because "max-age" is not supported by IE
60
- attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
61
-
62
- try {
63
- var result = JSON.stringify(value);
64
- if (/^[\{\[]/.test(result)) {
65
- value = result;
66
  }
67
- } catch (e) {}
68
 
69
- value = converter.write ?
70
- converter.write(value, key) :
71
- encodeURIComponent(String(value))
72
- .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
 
 
73
 
74
- key = encodeURIComponent(String(key))
75
- .replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent)
76
- .replace(/[\(\)]/g, escape);
77
 
78
- var stringifiedAttributes = '';
79
- for (var attributeName in attributes) {
80
- if (!attributes[attributeName]) {
81
- continue;
82
- }
83
- stringifiedAttributes += '; ' + attributeName;
84
- if (attributes[attributeName] === true) {
85
- continue;
86
- }
87
 
88
- // Considers RFC 6265 section 5.2:
89
- // ...
90
- // 3. If the remaining unparsed-attributes contains a %x3B (";")
91
- // character:
92
- // Consume the characters of the unparsed-attributes up to,
93
- // not including, the first %x3B (";") character.
94
- // ...
95
- stringifiedAttributes += '=' + attributes[attributeName].split(';')[0];
96
  }
97
 
98
- return (document.cookie = key + '=' + value + stringifiedAttributes);
99
- }
100
 
101
- function get (key, json) {
102
- if (typeof document === 'undefined') {
103
- return;
104
  }
105
 
106
- var jar = {};
107
  // To prevent the for loop in the first place assign an empty array
108
- // in case there are no cookies at all.
 
109
  var cookies = document.cookie ? document.cookie.split('; ') : [];
 
110
  var i = 0;
111
 
112
  for (; i < cookies.length; i++) {
113
  var parts = cookies[i].split('=');
 
114
  var cookie = parts.slice(1).join('=');
115
 
116
- if (!json && cookie.charAt(0) === '"') {
117
  cookie = cookie.slice(1, -1);
118
  }
119
 
120
  try {
121
- var name = decode(parts[0]);
122
- cookie = (converter.read || converter)(cookie, name) ||
123
- decode(cookie);
124
 
125
- if (json) {
126
  try {
127
  cookie = JSON.parse(cookie);
128
  } catch (e) {}
129
  }
130
 
131
- jar[name] = cookie;
132
-
133
  if (key === name) {
 
134
  break;
135
  }
 
 
 
 
136
  } catch (e) {}
137
  }
138
 
139
- return key ? jar[key] : jar;
140
  }
141
 
142
- api.set = set;
143
- api.get = function (key) {
144
- return get(key, false /* read as raw */);
145
- };
146
- api.getJSON = function (key) {
147
- return get(key, true /* read as json */);
148
  };
 
 
149
  api.remove = function (key, attributes) {
150
- set(key, '', extend(attributes, {
151
  expires: -1
152
  }));
153
  };
154
 
155
- api.defaults = {};
156
-
157
  api.withConverter = init;
158
 
159
  return api;
160
  }
161
 
162
- return init(function () {});
163
  }));
1
  /*!
2
+ * JavaScript Cookie v2.0.3
3
  * https://github.com/js-cookie/js-cookie
4
  *
5
  * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
6
  * Released under the MIT license
7
  */
8
+ (function (factory) {
 
9
  if (typeof define === 'function' && define.amd) {
10
  define(factory);
11
+ } else if (typeof exports === 'object') {
 
 
12
  module.exports = factory();
13
+ } else {
14
+ var _OldCookies = window.Cookies;
 
 
15
  var api = window.Cookies = factory();
16
  api.noConflict = function () {
17
+ window.Cookies = _OldCookies;
18
  return api;
19
  };
20
  }
31
  return result;
32
  }
33
 
 
 
 
 
34
  function init (converter) {
35
+ function api (key, value, attributes) {
36
+ var result;
37
 
38
+ // Write
 
 
 
39
 
40
+ if (arguments.length > 1) {
41
+ attributes = extend({
42
+ path: '/'
43
+ }, api.defaults, attributes);
44
 
45
+ if (typeof attributes.expires === 'number') {
46
+ var expires = new Date();
47
+ expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
48
+ attributes.expires = expires;
 
 
 
 
 
 
 
49
  }
 
50
 
51
+ try {
52
+ result = JSON.stringify(value);
53
+ if (/^[\{\[]/.test(result)) {
54
+ value = result;
55
+ }
56
+ } catch (e) {}
57
 
58
+ value = encodeURIComponent(String(value));
59
+ value = value.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
 
60
 
61
+ key = encodeURIComponent(String(key));
62
+ key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
63
+ key = key.replace(/[\(\)]/g, escape);
 
 
 
 
 
 
64
 
65
+ return (document.cookie = [
66
+ key, '=', value,
67
+ attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE
68
+ attributes.path && '; path=' + attributes.path,
69
+ attributes.domain && '; domain=' + attributes.domain,
70
+ attributes.secure ? '; secure' : ''
71
+ ].join(''));
 
72
  }
73
 
74
+ // Read
 
75
 
76
+ if (!key) {
77
+ result = {};
 
78
  }
79
 
 
80
  // To prevent the for loop in the first place assign an empty array
81
+ // in case there are no cookies at all. Also prevents odd result when
82
+ // calling "get()"
83
  var cookies = document.cookie ? document.cookie.split('; ') : [];
84
+ var rdecode = /(%[0-9A-Z]{2})+/g;
85
  var i = 0;
86
 
87
  for (; i < cookies.length; i++) {
88
  var parts = cookies[i].split('=');
89
+ var name = parts[0].replace(rdecode, decodeURIComponent);
90
  var cookie = parts.slice(1).join('=');
91
 
92
+ if (cookie.charAt(0) === '"') {
93
  cookie = cookie.slice(1, -1);
94
  }
95
 
96
  try {
97
+ cookie = converter && converter(cookie, name) || cookie.replace(rdecode, decodeURIComponent);
 
 
98
 
99
+ if (this.json) {
100
  try {
101
  cookie = JSON.parse(cookie);
102
  } catch (e) {}
103
  }
104
 
 
 
105
  if (key === name) {
106
+ result = cookie;
107
  break;
108
  }
109
+
110
+ if (!key) {
111
+ result[name] = cookie;
112
+ }
113
  } catch (e) {}
114
  }
115
 
116
+ return result;
117
  }
118
 
119
+ api.get = api.set = api;
120
+ api.getJSON = function () {
121
+ return api.apply({
122
+ json: true
123
+ }, [].slice.call(arguments));
 
124
  };
125
+ api.defaults = {};
126
+
127
  api.remove = function (key, attributes) {
128
+ api(key, '', extend(attributes, {
129
  expires: -1
130
  }));
131
  };
132
 
 
 
133
  api.withConverter = init;
134
 
135
  return api;
136
  }
137
 
138
+ return init();
139
  }));
vendor/js-cookie/js.cookie.min.js CHANGED
@@ -1,8 +1,2 @@
1
- /*!
2
- * JavaScript Cookie v2.2.1
3
- * https://github.com/js-cookie/js-cookie
4
- *
5
- * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
6
- * Released under the MIT license
7
- */
8
- !function(factory){var registeredInModuleLoader;if("function"==typeof define&&define.amd&&(define(factory),registeredInModuleLoader=!0),"object"==typeof exports&&(module.exports=factory(),registeredInModuleLoader=!0),!registeredInModuleLoader){var OldCookies=window.Cookies,api=window.Cookies=factory();api.noConflict=function(){return window.Cookies=OldCookies,api}}}((function(){function extend(){for(var i=0,result={};i<arguments.length;i++){var attributes=arguments[i];for(var key in attributes)result[key]=attributes[key]}return result}function decode(s){return s.replace(/(%[0-9A-Z]{2})+/g,decodeURIComponent)}function init(converter){function api(){}function set(key,value,attributes){if("undefined"!=typeof document){"number"==typeof(attributes=extend({path:"/"},api.defaults,attributes)).expires&&(attributes.expires=new Date(1*new Date+864e5*attributes.expires)),attributes.expires=attributes.expires?attributes.expires.toUTCString():"";try{var result=JSON.stringify(value);/^[\{\[]/.test(result)&&(value=result)}catch(e){}value=converter.write?converter.write(value,key):encodeURIComponent(String(value)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),key=encodeURIComponent(String(key)).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent).replace(/[\(\)]/g,escape);var stringifiedAttributes="";for(var attributeName in attributes)attributes[attributeName]&&(stringifiedAttributes+="; "+attributeName,!0!==attributes[attributeName]&&(stringifiedAttributes+="="+attributes[attributeName].split(";")[0]));return document.cookie=key+"="+value+stringifiedAttributes}}function get(key,json){if("undefined"!=typeof document){for(var jar={},cookies=document.cookie?document.cookie.split("; "):[],i=0;i<cookies.length;i++){var parts=cookies[i].split("="),cookie=parts.slice(1).join("=");json||'"'!==cookie.charAt(0)||(cookie=cookie.slice(1,-1));try{var name=decode(parts[0]);if(cookie=(converter.read||converter)(cookie,name)||decode(cookie),json)try{cookie=JSON.parse(cookie)}catch(e){}if(jar[name]=cookie,key===name)break}catch(e){}}return key?jar[key]:jar}}return api.set=set,api.get=function(key){return get(key,!1)},api.getJSON=function(key){return get(key,!0)},api.remove=function(key,attributes){set(key,"",extend(attributes,{expires:-1}))},api.defaults={},api.withConverter=init,api}return init((function(){}))}));
1
+ /*! js-cookie v2.0.3 | MIT */
2
+ !function(a){if("function"==typeof define&&define.amd)define(a);else if("object"==typeof exports)module.exports=a();else{var b=window.Cookies,c=window.Cookies=a(window.jQuery);c.noConflict=function(){return window.Cookies=b,c}}}(function(){function a(){for(var a=0,b={};a<arguments.length;a++){var c=arguments[a];for(var d in c)b[d]=c[d]}return b}function b(c){function d(b,e,f){var g;if(arguments.length>1){if(f=a({path:"/"},d.defaults,f),"number"==typeof f.expires){var h=new Date;h.setMilliseconds(h.getMilliseconds()+864e5*f.expires),f.expires=h}try{g=JSON.stringify(e),/^[\{\[]/.test(g)&&(e=g)}catch(i){}return e=encodeURIComponent(String(e)),e=e.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),b=encodeURIComponent(String(b)),b=b.replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent),b=b.replace(/[\(\)]/g,escape),document.cookie=[b,"=",e,f.expires&&"; expires="+f.expires.toUTCString(),f.path&&"; path="+f.path,f.domain&&"; domain="+f.domain,f.secure?"; secure":""].join("")}b||(g={});for(var j=document.cookie?document.cookie.split("; "):[],k=/(%[0-9A-Z]{2})+/g,l=0;l<j.length;l++){var m=j[l].split("="),n=m[0].replace(k,decodeURIComponent),o=m.slice(1).join("=");'"'===o.charAt(0)&&(o=o.slice(1,-1));try{if(o=c&&c(o,n)||o.replace(k,decodeURIComponent),this.json)try{o=JSON.parse(o)}catch(i){}if(b===n){g=o;break}b||(g[n]=o)}catch(i){}}return g}return d.get=d.set=d,d.getJSON=function(){return d.apply({json:!0},[].slice.call(arguments))},d.defaults={},d.remove=function(b,c){d(b,"",a(c,{expires:-1}))},d.withConverter=b,d}return b()});
 
 
 
 
 
 
vendor/smooth-scroll/jquery.smooth-scroll.js CHANGED
@@ -1,170 +1,144 @@
1
- (function($) {
2
- var version = '2.2.0';
3
- var optionOverrides = {};
4
- var defaults = {
5
- exclude: [],
6
- excludeWithin: [],
7
- offset: 0,
8
-
9
- // one of 'top' or 'left'
10
- direction: 'top',
11
-
12
- // if set, bind click events through delegation
13
- // supported since jQuery 1.4.2
14
- delegateSelector: null,
15
-
16
- // jQuery set of elements you wish to scroll (for $.smoothScroll).
17
- // if null (default), $('html, body').firstScrollable() is used.
18
- scrollElement: null,
19
-
20
- // only use if you want to override default behavior
21
- scrollTarget: null,
22
-
23
- // automatically focus the target element after scrolling to it
24
- autoFocus: false,
25
-
26
- // fn(opts) function to be called before scrolling occurs.
27
- // `this` is the element(s) being scrolled
28
- beforeScroll: function() {},
29
-
30
- // fn(opts) function to be called after scrolling occurs.
31
- // `this` is the triggering element
32
- afterScroll: function() {},
33
-
34
- // easing name. jQuery comes with "swing" and "linear." For others, you'll need an easing plugin
35
- // from jQuery UI or elsewhere
36
- easing: 'swing',
37
-
38
- // speed can be a number or 'auto'
39
- // if 'auto', the speed will be calculated based on the formula:
40
- // (current scroll position - target scroll position) / autoCoeffic
41
- speed: 400,
42
-
43
- // coefficient for "auto" speed
44
- autoCoefficient: 2,
45
-
46
- // $.fn.smoothScroll only: whether to prevent the default click action
47
- preventDefault: true
48
- };
49
-
50
- var getScrollable = function(opts) {
51
- var scrollable = [];
52
- var scrolled = false;
53
- var dir = opts.dir && opts.dir === 'left' ? 'scrollLeft' : 'scrollTop';
54
-
55
- this.each(function() {
56
- var el = $(this);
57
-
58
- if (this === document || this === window) {
59
- return;
60
- }
61
-
62
- if (document.scrollingElement && (this === document.documentElement || this === document.body)) {
63
- scrollable.push(document.scrollingElement);
64
-
65
- return false;
66
- }
67
-
68
- if (el[dir]() > 0) {
69
- scrollable.push(this);
70
- } else {
71
- // if scroll(Top|Left) === 0, nudge the element 1px and see if it moves
72
- el[dir](1);
73
- scrolled = el[dir]() > 0;
74
-
75
- if (scrolled) {
76
- scrollable.push(this);
77
- }
78
- // then put it back, of course
79
- el[dir](0);
80
- }
81
- });
82
-
83
- if (!scrollable.length) {
84
- this.each(function() {
85
- // If no scrollable elements and <html> has scroll-behavior:smooth because
86
- // "When this property is specified on the root element, it applies to the viewport instead."
87
- // and "The scroll-behavior property of the … body element is *not* propagated to the viewport."
88
- // → https://drafts.csswg.org/cssom-view/#propdef-scroll-behavior
89
- if (this === document.documentElement && $(this).css('scrollBehavior') === 'smooth') {
90
- scrollable = [this];
91
- }
92
 
93
- // If still no scrollable elements, fall back to <body>,
94
  // if it's in the jQuery collection
95
  // (doing this because Safari sets scrollTop async,
96
  // so can't set it to 1 and immediately get the value.)
97
- if (!scrollable.length && this.nodeName === 'BODY') {
98
- scrollable = [this];
 
 
 
 
99
  }
100
- });
101
- }
102
 
103
- // Use the first scrollable element if we're calling firstScrollable()
104
- if (opts.el === 'first' && scrollable.length > 1) {
105
- scrollable = [scrollable[0]];
106
- }
107
-
108
- return scrollable;
109
- };
110
 
111
- var rRelative = /^([\-\+]=)(\d+)/;
 
112
 
113
  $.fn.extend({
114
  scrollable: function(dir) {
115
  var scrl = getScrollable.call(this, {dir: dir});
116
-
117
  return this.pushStack(scrl);
118
  },
119
  firstScrollable: function(dir) {
120
  var scrl = getScrollable.call(this, {el: 'first', dir: dir});
121
-
122
  return this.pushStack(scrl);
123
  },
124
 
125
  smoothScroll: function(options, extra) {
126
  options = options || {};
127
 
128
- if (options === 'options') {
129
- if (!extra) {
130
  return this.first().data('ssOpts');
131
  }
132
-
133
  return this.each(function() {
134
- var $this = $(this);
135
- var opts = $.extend($this.data('ssOpts') || {}, extra);
136
 
137
  $(this).data('ssOpts', opts);
138
  });
139
  }
140
 
141
- var opts = $.extend({}, $.fn.smoothScroll.defaults, options);
142
-
143
- var clickHandler = function(event) {
144
- var escapeSelector = function(str) {
145
- return str.replace(/(:|\.|\/)/g, '\\$1');
146
- };
147
-
148
- var link = this;
149
- var $link = $(this);
150
- var thisOpts = $.extend({}, opts, $link.data('ssOpts') || {});
151
- var exclude = opts.exclude;
152
- var excludeWithin = thisOpts.excludeWithin;
153
- var elCounter = 0;
154
- var ewlCounter = 0;
155
- var include = true;
156
- var clickOpts = {};
157
- var locationPath = $.smoothScroll.filterPath(location.pathname);
158
- var linkPath = $.smoothScroll.filterPath(link.pathname);
159
- var hostMatch = location.hostname === link.hostname || !link.hostname;
160
- var pathMatch = thisOpts.scrollTarget || (linkPath === locationPath);
161
- var thisHash = escapeSelector(link.hash);
162
-
163
- if (thisHash && !$(thisHash).length) {
164
- include = false;
165
- }
166
-
167
- if (!thisOpts.scrollTarget && (!hostMatch || !pathMatch || !thisHash)) {
168
  include = false;
169
  } else {
170
  while (include && elCounter < exclude.length) {
@@ -172,108 +146,61 @@
172
  include = false;
173
  }
174
  }
175
-
176
- while (include && ewlCounter < excludeWithin.length) {
177
  if ($link.closest(excludeWithin[ewlCounter++]).length) {
178
  include = false;
179
  }
180
  }
181
  }
182
 
183
- if (include) {
184
- if (thisOpts.preventDefault) {
 
185
  event.preventDefault();
186
  }
187
 
188
- $.extend(clickOpts, thisOpts, {
189
  scrollTarget: thisOpts.scrollTarget || thisHash,
190
  link: link
191
  });
192
 
193
- $.smoothScroll(clickOpts);
194
  }
195
- };
196
-
197
- if (options.delegateSelector !== null) {
198
- this
199
- .off('click.smoothscroll', options.delegateSelector)
200
- .on('click.smoothscroll', options.delegateSelector, clickHandler);
201
- } else {
202
- this
203
- .off('click.smoothscroll')
204
- .on('click.smoothscroll', clickHandler);
205
- }
206
 
207
  return this;
208
  }
209
  });
210
 
211
- var getExplicitOffset = function(val) {
212
- var explicit = {relative: ''};
213
- var parts = typeof val === 'string' && rRelative.exec(val);
214
-
215
- if (typeof val === 'number') {
216
- explicit.px = val;
217
- } else if (parts) {
218
- explicit.relative = parts[1];
219
- explicit.px = parseFloat(parts[2]) || 0;
220
- }
221
-
222
- return explicit;
223
- };
224
-
225
- var onAfterScroll = function(opts) {
226
- var $tgt = $(opts.scrollTarget);
227
-
228
- if (opts.autoFocus && $tgt.length) {
229
- $tgt[0].focus();
230
-
231
- if (!$tgt.is(document.activeElement)) {
232
- $tgt.prop({tabIndex: -1});
233
- $tgt[0].focus();
234
- }
235
- }
236
-
237
- opts.afterScroll.call(opts.link, opts);
238
- };
239
-
240
  $.smoothScroll = function(options, px) {
241
- if (options === 'options' && typeof px === 'object') {
242
  return $.extend(optionOverrides, px);
243
  }
244
- var opts, $scroller, speed, delta;
245
- var explicitOffset = getExplicitOffset(options);
246
- var scrollTargetOffset = {};
247
- var scrollerOffset = 0;
248
- var offPos = 'offset';
249
- var scrollDir = 'scrollTop';
250
- var aniProps = {};
251
- var aniOpts = {};
252
-
253
- if (explicitOffset.px) {
254
  opts = $.extend({link: null}, $.fn.smoothScroll.defaults, optionOverrides);
 
255
  } else {
256
  opts = $.extend({link: null}, $.fn.smoothScroll.defaults, options || {}, optionOverrides);
257
-
258
  if (opts.scrollElement) {
259
  offPos = 'position';
260
-
261
  if (opts.scrollElement.css('position') === 'static') {
262
  opts.scrollElement.css('position', 'relative');
263
  }
264
  }
265
-
266
- if (px) {
267
- explicitOffset = getExplicitOffset(px);
268
- }
269
  }
270
 
271
  scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir;
272
 
273
- if (opts.scrollElement) {
274
  $scroller = opts.scrollElement;
275
-
276
- if (!explicitOffset.px && !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName)) {
277
  scrollerOffset = $scroller[scrollDir]();
278
  }
279
  } else {
@@ -283,21 +210,24 @@
283
  // beforeScroll callback function must fire before calculating offset
284
  opts.beforeScroll.call($scroller, opts);
285
 
286
- scrollTargetOffset = explicitOffset.px ? explicitOffset : {
287
- relative: '',
288
- px: ($(opts.scrollTarget)[offPos]() && $(opts.scrollTarget)[offPos]()[opts.direction]) || 0
289
- };
290
-
291
- aniProps[scrollDir] = scrollTargetOffset.relative + (scrollTargetOffset.px + scrollerOffset + opts.offset);
292
 
 
293
  speed = opts.speed;
294
 
295
  // automatically calculate the speed of the scroll based on distance / coefficient
296
  if (speed === 'auto') {
297
 
298
- // $scroller[scrollDir]() is position before scroll, aniProps[scrollDir] is position after
299
  // When delta is greater, speed will be greater.
300
- delta = Math.abs(aniProps[scrollDir] - $scroller[scrollDir]());
 
 
 
301
 
302
  // Divide the delta by the coefficient
303
  speed = delta / opts.autoCoefficient;
@@ -307,7 +237,7 @@
307
  duration: speed,
308
  easing: opts.easing,
309
  complete: function() {
310
- onAfterScroll(opts);
311
  }
312
  };
313
 
@@ -318,21 +248,25 @@
318
  if ($scroller.length) {
319
  $scroller.stop().animate(aniProps, aniOpts);
320
  } else {
321
- onAfterScroll(opts);
322
  }
323
  };
324
 
325
  $.smoothScroll.version = version;
326
  $.smoothScroll.filterPath = function(string) {
327
  string = string || '';
328
-
329
  return string
330
- .replace(/^\//, '')
331
- .replace(/(?:index|default).[a-zA-Z]{3,4}$/, '')
332
- .replace(/\/$/, '');
333
  };
334
 
335
  // default options
336
  $.fn.smoothScroll.defaults = defaults;
337
 
338
- })(jQuery);
 
 
 
 
 
1
+ /*!
2
+ * jQuery Smooth Scroll - v1.5.5 - 2015-02-19
3
+ * https://github.com/kswedberg/jquery-smooth-scroll
4
+ * Copyright (c) 2015 Karl Swedberg
5
+ * Licensed MIT (https://github.com/kswedberg/jquery-smooth-scroll/blob/master/LICENSE-MIT)
6
+ */
7
+
8
+ (function (factory) {
9
+ if (typeof define === 'function' && define.amd) {
10
+ // AMD. Register as an anonymous module.
11
+ define(['jquery'], factory);
12
+ } else if (typeof module === 'object' && module.exports) {
13
+ // CommonJS
14
+ factory(require('jquery'));
15
+ } else {
16
+ // Browser globals
17
+ factory(jQuery);
18
+ }
19
+ }(function ($) {
20
+
21
+ var version = '1.5.5',
22
+ optionOverrides = {},
23
+ defaults = {
24
+ exclude: [],
25
+ excludeWithin:[],
26
+ offset: 0,
27
+
28
+ // one of 'top' or 'left'
29
+ direction: 'top',
30
+
31
+ // jQuery set of elements you wish to scroll (for $.smoothScroll).
32
+ // if null (default), $('html, body').firstScrollable() is used.
33
+ scrollElement: null,
34
+
35
+ // only use if you want to override default behavior
36
+ scrollTarget: null,
37
+
38
+ // fn(opts) function to be called before scrolling occurs.
39
+ // `this` is the element(s) being scrolled
40
+ beforeScroll: function() {},
41
+
42
+ // fn(opts) function to be called after scrolling occurs.
43
+ // `this` is the triggering element
44
+ afterScroll: function() {},
45
+ easing: 'swing',
46
+ speed: 400,
47
+
48
+ // coefficient for "auto" speed
49
+ autoCoefficient: 2,
50
+
51
+ // $.fn.smoothScroll only: whether to prevent the default click action
52
+ preventDefault: true
53
+ },
54
+
55
+ getScrollable = function(opts) {
56
+ var scrollable = [],
57
+ scrolled = false,
58
+ dir = opts.dir && opts.dir === 'left' ? 'scrollLeft' : 'scrollTop';
59
+
60
+ this.each(function() {
61
+
62
+ if (this === document || this === window) { return; }
63
+ var el = $(this);
64
+ if ( el[dir]() > 0 ) {
65
+ scrollable.push(this);
66
+ } else {
67
+ // if scroll(Top|Left) === 0, nudge the element 1px and see if it moves
68
+ el[dir](1);
69
+ scrolled = el[dir]() > 0;
70
+ if ( scrolled ) {
71
+ scrollable.push(this);
72
+ }
73
+ // then put it back, of course
74
+ el[dir](0);
75
+ }
76
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
+ // If no scrollable elements, fall back to <body>,
79
  // if it's in the jQuery collection
80
  // (doing this because Safari sets scrollTop async,
81
  // so can't set it to 1 and immediately get the value.)
82
+ if (!scrollable.length) {
83
+ this.each(function() {
84
+ if (this.nodeName === 'BODY') {
85
+ scrollable = [this];
86
+ }
87
+ });
88
  }
 
 
89
 
90
+ // Use the first scrollable element if we're calling firstScrollable()
91
+ if ( opts.el === 'first' && scrollable.length > 1 ) {
92
+ scrollable = [ scrollable[0] ];
93
+ }
 
 
 
94
 
95
+ return scrollable;
96
+ };
97
 
98
  $.fn.extend({
99
  scrollable: function(dir) {
100
  var scrl = getScrollable.call(this, {dir: dir});
 
101
  return this.pushStack(scrl);
102
  },
103
  firstScrollable: function(dir) {
104
  var scrl = getScrollable.call(this, {el: 'first', dir: dir});
 
105
  return this.pushStack(scrl);
106
  },
107
 
108
  smoothScroll: function(options, extra) {
109
  options = options || {};
110
 
111
+ if ( options === 'options' ) {
112
+ if ( !extra ) {
113
  return this.first().data('ssOpts');
114
  }
 
115
  return this.each(function() {
116
+ var $this = $(this),
117
+ opts = $.extend($this.data('ssOpts') || {}, extra);
118
 
119
  $(this).data('ssOpts', opts);
120
  });
121
  }
122
 
123
+ var opts = $.extend({}, $.fn.smoothScroll.defaults, options),
124
+ locationPath = $.smoothScroll.filterPath(location.pathname);
125
+
126
+ this
127
+ .unbind('click.smoothscroll')
128
+ .bind('click.smoothscroll', function(event) {
129
+ var link = this,
130
+ $link = $(this),
131
+ thisOpts = $.extend({}, opts, $link.data('ssOpts') || {}),
132
+ exclude = opts.exclude,
133
+ excludeWithin = thisOpts.excludeWithin,
134
+ elCounter = 0, ewlCounter = 0,
135
+ include = true,
136
+ clickOpts = {},
137
+ hostMatch = ((location.hostname === link.hostname) || !link.hostname),
138
+ pathMatch = thisOpts.scrollTarget || ( $.smoothScroll.filterPath(link.pathname) === locationPath ),
139
+ thisHash = escapeSelector(link.hash);
140
+
141
+ if ( !thisOpts.scrollTarget && (!hostMatch || !pathMatch || !thisHash) ) {
 
 
 
 
 
 
 
 
142
  include = false;
143
  } else {
144
  while (include && elCounter < exclude.length) {
146
  include = false;
147
  }
148
  }
149
+ while ( include && ewlCounter < excludeWithin.length ) {
 
150
  if ($link.closest(excludeWithin[ewlCounter++]).length) {
151
  include = false;
152
  }
153
  }
154
  }
155
 
156
+ if ( include ) {
157
+
158
+ if ( thisOpts.preventDefault ) {
159
  event.preventDefault();
160
  }
161
 
162
+ $.extend( clickOpts, thisOpts, {
163
  scrollTarget: thisOpts.scrollTarget || thisHash,
164
  link: link
165
  });
166
 
167
+ $.smoothScroll( clickOpts );
168
  }
169
+ });
 
 
 
 
 
 
 
 
 
 
170
 
171
  return this;
172
  }
173
  });
174
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  $.smoothScroll = function(options, px) {
176
+ if ( options === 'options' && typeof px === 'object' ) {
177
  return $.extend(optionOverrides, px);
178
  }
179
+ var opts, $scroller, scrollTargetOffset, speed, delta,
180
+ scrollerOffset = 0,
181
+ offPos = 'offset',
182
+ scrollDir = 'scrollTop',
183
+ aniProps = {},
184
+ aniOpts = {};
185
+
186
+ if (typeof options === 'number') {
 
 
187
  opts = $.extend({link: null}, $.fn.smoothScroll.defaults, optionOverrides);
188
+ scrollTargetOffset = options;
189
  } else {
190
  opts = $.extend({link: null}, $.fn.smoothScroll.defaults, options || {}, optionOverrides);
 
191
  if (opts.scrollElement) {
192
  offPos = 'position';
 
193
  if (opts.scrollElement.css('position') === 'static') {
194
  opts.scrollElement.css('position', 'relative');
195
  }
196
  }
 
 
 
 
197
  }
198
 
199
  scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir;
200
 
201
+ if ( opts.scrollElement ) {
202
  $scroller = opts.scrollElement;
203
+ if ( !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName) ) {
 
204
  scrollerOffset = $scroller[scrollDir]();
205
  }
206
  } else {
210
  // beforeScroll callback function must fire before calculating offset
211
  opts.beforeScroll.call($scroller, opts);
212
 
213
+ scrollTargetOffset = (typeof options === 'number') ? options :
214
+ px ||
215
+ ( $(opts.scrollTarget)[offPos]() &&
216
+ $(opts.scrollTarget)[offPos]()[opts.direction] ) ||
217
+ 0;
 
218
 
219
+ aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset;
220
  speed = opts.speed;
221
 
222
  // automatically calculate the speed of the scroll based on distance / coefficient
223
  if (speed === 'auto') {
224
 
225
+ // $scroller.scrollTop() is position before scroll, aniProps[scrollDir] is position after
226
  // When delta is greater, speed will be greater.
227
+ delta = aniProps[scrollDir] - $scroller.scrollTop();
228
+ if(delta < 0) {
229
+ delta *= -1;
230
+ }
231
 
232
  // Divide the delta by the coefficient
233
  speed = delta / opts.autoCoefficient;
237
  duration: speed,
238
  easing: opts.easing,
239
  complete: function() {
240
+ opts.afterScroll.call(opts.link, opts);
241
  }
242
  };
243
 
248
  if ($scroller.length) {
249
  $scroller.stop().animate(aniProps, aniOpts);
250
  } else {
251
+ opts.afterScroll.call(opts.link, opts);
252
  }
253
  };
254
 
255
  $.smoothScroll.version = version;
256
  $.smoothScroll.filterPath = function(string) {
257
  string = string || '';
 
258
  return string
259
+ .replace(/^\//,'')
260
+ .replace(/(?:index|default).[a-zA-Z]{3,4}$/,'')
261
+ .replace(/\/$/,'');
262
  };
263
 
264
  // default options
265
  $.fn.smoothScroll.defaults = defaults;
266
 
267
+ function escapeSelector (str) {
268
+ return str.replace(/(:|\.|\/)/g,'\\$1');
269
+ }
270
+
271
+ }));
272
+
vendor/smooth-scroll/jquery.smooth-scroll.min.js CHANGED
@@ -1 +1,22 @@
1
- !function($){var version="2.2.0",optionOverrides={},defaults={exclude:[],excludeWithin:[],offset:0,direction:"top",delegateSelector:null,scrollElement:null,scrollTarget:null,autoFocus:!1,beforeScroll:function(){},afterScroll:function(){},easing:"swing",speed:400,autoCoefficient:2,preventDefault:!0},getScrollable=function(opts){var scrollable=[],scrolled=!1,dir=opts.dir&&"left"===opts.dir?"scrollLeft":"scrollTop";return this.each((function(){var el=$(this);if(this!==document&&this!==window)return!document.scrollingElement||this!==document.documentElement&&this!==document.body?void(el[dir]()>0?scrollable.push(this):(el[dir](1),(scrolled=el[dir]()>0)&&scrollable.push(this),el[dir](0))):(scrollable.push(document.scrollingElement),!1)})),scrollable.length||this.each((function(){this===document.documentElement&&"smooth"===$(this).css("scrollBehavior")&&(scrollable=[this]),scrollable.length||"BODY"!==this.nodeName||(scrollable=[this])})),"first"===opts.el&&scrollable.length>1&&(scrollable=[scrollable[0]]),scrollable},rRelative=/^([\-\+]=)(\d+)/;$.fn.extend({scrollable:function(dir){var scrl=getScrollable.call(this,{dir:dir});return this.pushStack(scrl)},firstScrollable:function(dir){var scrl=getScrollable.call(this,{el:"first",dir:dir});return this.pushStack(scrl)},smoothScroll:function(options,extra){if("options"===(options=options||{}))return extra?this.each((function(){var $this=$(this),opts=$.extend($this.data("ssOpts")||{},extra);$(this).data("ssOpts",opts)})):this.first().data("ssOpts");var opts=$.extend({},$.fn.smoothScroll.defaults,options),clickHandler=function(event){var escapeSelector=function(str){return str.replace(/(:|\.|\/)/g,"\\$1")},link=this,$link=$(this),thisOpts=$.extend({},opts,$link.data("ssOpts")||{}),exclude=opts.exclude,excludeWithin=thisOpts.excludeWithin,elCounter=0,ewlCounter=0,include=!0,clickOpts={},locationPath=$.smoothScroll.filterPath(location.pathname),linkPath=$.smoothScroll.filterPath(this.pathname),hostMatch=location.hostname===this.hostname||!this.hostname,pathMatch=thisOpts.scrollTarget||linkPath===locationPath,thisHash=escapeSelector(this.hash);if(thisHash&&!$(thisHash).length&&(include=!1),thisOpts.scrollTarget||hostMatch&&pathMatch&&thisHash){for(;include&&elCounter<exclude.length;)$link.is(escapeSelector(exclude[elCounter++]))&&(include=!1);for(;include&&ewlCounter<excludeWithin.length;)$link.closest(excludeWithin[ewlCounter++]).length&&(include=!1)}else include=!1;include&&(thisOpts.preventDefault&&event.preventDefault(),$.extend(clickOpts,thisOpts,{scrollTarget:thisOpts.scrollTarget||thisHash,link:this}),$.smoothScroll(clickOpts))};return null!==options.delegateSelector?this.off("click.smoothscroll",options.delegateSelector).on("click.smoothscroll",options.delegateSelector,clickHandler):this.off("click.smoothscroll").on("click.smoothscroll",clickHandler),this}});var getExplicitOffset=function(val){var explicit={relative:""},parts="string"==typeof val&&rRelative.exec(val);return"number"==typeof val?explicit.px=val:parts&&(explicit.relative=parts[1],explicit.px=parseFloat(parts[2])||0),explicit},onAfterScroll=function(opts){var $tgt=$(opts.scrollTarget);opts.autoFocus&&$tgt.length&&($tgt[0].focus(),$tgt.is(document.activeElement)||($tgt.prop({tabIndex:-1}),$tgt[0].focus())),opts.afterScroll.call(opts.link,opts)};$.smoothScroll=function(options,px){if("options"===options&&"object"==typeof px)return $.extend(optionOverrides,px);var opts,$scroller,speed,delta,explicitOffset=getExplicitOffset(options),scrollTargetOffset={},scrollerOffset=0,offPos="offset",scrollDir="scrollTop",aniProps={},aniOpts={};explicitOffset.px?opts=$.extend({link:null},$.fn.smoothScroll.defaults,optionOverrides):((opts=$.extend({link:null},$.fn.smoothScroll.defaults,options||{},optionOverrides)).scrollElement&&(offPos="position","static"===opts.scrollElement.css("position")&&opts.scrollElement.css("position","relative")),px&&(explicitOffset=getExplicitOffset(px))),scrollDir="left"===opts.direction?"scrollLeft":scrollDir,opts.scrollElement?($scroller=opts.scrollElement,explicitOffset.px||/^(?:HTML|BODY)$/.test($scroller[0].nodeName)||(scrollerOffset=$scroller[scrollDir]())):$scroller=$("html, body").firstScrollable(opts.direction),opts.beforeScroll.call($scroller,opts),scrollTargetOffset=explicitOffset.px?explicitOffset:{relative:"",px:$(opts.scrollTarget)[offPos]()&&$(opts.scrollTarget)[offPos]()[opts.direction]||0},aniProps[scrollDir]=scrollTargetOffset.relative+(scrollTargetOffset.px+scrollerOffset+opts.offset),"auto"===(speed=opts.speed)&&(speed=(delta=Math.abs(aniProps[scrollDir]-$scroller[scrollDir]()))/opts.autoCoefficient),aniOpts={duration:speed,easing:opts.easing,complete:function(){onAfterScroll(opts)}},opts.step&&(aniOpts.step=opts.step),$scroller.length?$scroller.stop().animate(aniProps,aniOpts):onAfterScroll(opts)},$.smoothScroll.version="2.2.0",$.smoothScroll.filterPath=function(string){return(string=string||"").replace(/^\//,"").replace(/(?:index|default).[a-zA-Z]{3,4}$/,"").replace(/\/$/,"")},$.fn.smoothScroll.defaults=defaults}(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery Smooth Scroll - v1.5.5 - 2015-02-19
3
+ * https://github.com/kswedberg/jquery-smooth-scroll
4
+ * Copyright (c) 2015 Karl Swedberg
5
+ * Licensed MIT (https://github.com/kswedberg/jquery-smooth-scroll/blob/master/LICENSE-MIT)
6
+ */
7
+ (function(a){if(typeof define==="function"&&define.amd){define(["jquery"],a);
8
+ }else{if(typeof module==="object"&&module.exports){a(require("jquery"));}else{a(jQuery);}}}(function(d){var b="1.5.5",f={},e={exclude:[],excludeWithin:[],offset:0,direction:"top",scrollElement:null,scrollTarget:null,beforeScroll:function(){},afterScroll:function(){},easing:"swing",speed:400,autoCoefficient:2,preventDefault:true},a=function(i){var j=[],h=false,g=i.dir&&i.dir==="left"?"scrollLeft":"scrollTop";
9
+ this.each(function(){if(this===document||this===window){return;}var k=d(this);if(k[g]()>0){j.push(this);}else{k[g](1);h=k[g]()>0;if(h){j.push(this);}k[g](0);
10
+ }});if(!j.length){this.each(function(){if(this.nodeName==="BODY"){j=[this];}});}if(i.el==="first"&&j.length>1){j=[j[0]];}return j;};d.fn.extend({scrollable:function(g){var h=a.call(this,{dir:g});
11
+ return this.pushStack(h);},firstScrollable:function(g){var h=a.call(this,{el:"first",dir:g});return this.pushStack(h);},smoothScroll:function(h,g){h=h||{};
12
+ if(h==="options"){if(!g){return this.first().data("ssOpts");}return this.each(function(){var l=d(this),k=d.extend(l.data("ssOpts")||{},g);d(this).data("ssOpts",k);
13
+ });}var i=d.extend({},d.fn.smoothScroll.defaults,h),j=d.smoothScroll.filterPath(location.pathname);this.unbind("click.smoothscroll").bind("click.smoothscroll",function(m){var u=this,t=d(this),o=d.extend({},i,t.data("ssOpts")||{}),n=i.exclude,r=o.excludeWithin,v=0,q=0,l=true,w={},p=((location.hostname===u.hostname)||!u.hostname),k=o.scrollTarget||(d.smoothScroll.filterPath(u.pathname)===j),s=c(u.hash);
14
+ if(!o.scrollTarget&&(!p||!k||!s)){l=false;}else{while(l&&v<n.length){if(t.is(c(n[v++]))){l=false;}}while(l&&q<r.length){if(t.closest(r[q++]).length){l=false;
15
+ }}}if(l){if(o.preventDefault){m.preventDefault();}d.extend(w,o,{scrollTarget:o.scrollTarget||s,link:u});d.smoothScroll(w);}});return this;}});d.smoothScroll=function(r,m){if(r==="options"&&typeof m==="object"){return d.extend(f,m);
16
+ }var g,h,q,i,n,p=0,j="offset",l="scrollTop",o={},k={};if(typeof r==="number"){g=d.extend({link:null},d.fn.smoothScroll.defaults,f);q=r;}else{g=d.extend({link:null},d.fn.smoothScroll.defaults,r||{},f);
17
+ if(g.scrollElement){j="position";if(g.scrollElement.css("position")==="static"){g.scrollElement.css("position","relative");}}}l=g.direction==="left"?"scrollLeft":l;
18
+ if(g.scrollElement){h=g.scrollElement;if(!(/^(?:HTML|BODY)$/).test(h[0].nodeName)){p=h[l]();}}else{h=d("html, body").firstScrollable(g.direction);}g.beforeScroll.call(h,g);
19
+ q=(typeof r==="number")?r:m||(d(g.scrollTarget)[j]()&&d(g.scrollTarget)[j]()[g.direction])||0;o[l]=q+p+g.offset;i=g.speed;if(i==="auto"){n=o[l]-h.scrollTop();
20
+ if(n<0){n*=-1;}i=n/g.autoCoefficient;}k={duration:i,easing:g.easing,complete:function(){g.afterScroll.call(g.link,g);}};if(g.step){k.step=g.step;}if(h.length){h.stop().animate(o,k);
21
+ }else{g.afterScroll.call(g.link,g);}};d.smoothScroll.version=b;d.smoothScroll.filterPath=function(g){g=g||"";return g.replace(/^\//,"").replace(/(?:index|default).[a-zA-Z]{3,4}$/,"").replace(/\/$/,"");
22
+ };d.fn.smoothScroll.defaults=e;function c(g){return g.replace(/(:|\.|\/)/g,"\\$1");}}));
vendor/waypoints/jquery.waypoints.js ADDED
@@ -0,0 +1,662 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ Waypoints - 4.0.1
3
+ Copyright © 2011-2016 Caleb Troughton
4
+ Licensed under the MIT license.
5
+ https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6
+ */
7
+ (function() {
8
+ 'use strict'
9
+
10
+ var keyCounter = 0
11
+ var allWaypoints = {}
12
+
13
+ /* http://imakewebthings.com/waypoints/api/waypoint */
14
+ function Waypoint(options) {
15
+ if (!options) {
16
+ throw new Error('No options passed to Waypoint constructor')
17
+ }
18
+ if (!options.element) {
19
+ throw new Error('No element option passed to Waypoint constructor')
20
+ }
21
+ if (!options.handler) {
22
+ throw new Error('No handler option passed to Waypoint constructor')
23
+ }
24
+
25
+ this.key = 'waypoint-' + keyCounter
26
+ this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
27
+ this.element = this.options.element
28
+ this.adapter = new Waypoint.Adapter(this.element)
29
+ this.callback = options.handler
30
+ this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
31
+ this.enabled = this.options.enabled
32
+ this.triggerPoint = null
33
+ this.group = Waypoint.Group.findOrCreate({
34
+ name: this.options.group,
35
+ axis: this.axis
36
+ })
37
+ this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
38
+
39
+ if (Waypoint.offsetAliases[this.options.offset]) {
40
+ this.options.offset = Waypoint.offsetAliases[this.options.offset]
41
+ }
42
+ this.group.add(this)
43
+ this.context.add(this)
44
+ allWaypoints[this.key] = this
45
+ keyCounter += 1
46
+ }
47
+
48
+ /* Private */
49
+ Waypoint.prototype.queueTrigger = function(direction) {
50
+ this.group.queueTrigger(this, direction)
51
+ }
52
+
53
+ /* Private */
54
+ Waypoint.prototype.trigger = function(args) {
55
+ if (!this.enabled) {
56
+ return
57
+ }
58
+ if (this.callback) {
59
+ this.callback.apply(this, args)
60
+ }
61
+ }
62
+
63
+ /* Public */
64
+ /* http://imakewebthings.com/waypoints/api/destroy */
65
+ Waypoint.prototype.destroy = function() {
66
+ this.context.remove(this)
67
+ this.group.remove(this)
68
+ delete allWaypoints[this.key]
69
+ }
70
+
71
+ /* Public */
72
+ /* http://imakewebthings.com/waypoints/api/disable */
73
+ Waypoint.prototype.disable = function() {
74
+ this.enabled = false
75
+ return this
76
+ }
77
+
78
+ /* Public */
79
+ /* http://imakewebthings.com/waypoints/api/enable */
80
+ Waypoint.prototype.enable = function() {
81
+ this.context.refresh()
82
+ this.enabled = true
83
+ return this
84
+ }
85
+
86
+ /* Public */
87
+ /* http://imakewebthings.com/waypoints/api/next */
88
+ Waypoint.prototype.next = function() {
89
+ return this.group.next(this)
90
+ }
91
+
92
+ /* Public */
93
+ /* http://imakewebthings.com/waypoints/api/previous */
94
+ Waypoint.prototype.previous = function() {
95
+ return this.group.previous(this)
96
+ }
97
+
98
+ /* Private */
99
+ Waypoint.invokeAll = function(method) {
100
+ var allWaypointsArray = []
101
+ for (var waypointKey in allWaypoints) {
102
+ allWaypointsArray.push(allWaypoints[waypointKey])
103
+ }
104
+ for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
105
+ allWaypointsArray[i][method]()
106
+ }
107
+ }
108
+
109
+ /* Public */
110
+ /* http://imakewebthings.com/waypoints/api/destroy-all */
111
+ Waypoint.destroyAll = function() {
112
+ Waypoint.invokeAll('destroy')
113
+ }
114
+
115
+ /* Public */
116
+ /* http://imakewebthings.com/waypoints/api/disable-all */
117
+ Waypoint.disableAll = function() {
118
+ Waypoint.invokeAll('disable')
119
+ }
120
+
121
+ /* Public */
122
+ /* http://imakewebthings.com/waypoints/api/enable-all */
123
+ Waypoint.enableAll = function() {
124
+ Waypoint.Context.refreshAll()
125
+ for (var waypointKey in allWaypoints) {
126
+ allWaypoints[waypointKey].enabled = true
127
+ }
128
+ return this
129
+ }
130
+
131
+ /* Public */
132
+ /* http://imakewebthings.com/waypoints/api/refresh-all */
133
+ Waypoint.refreshAll = function() {
134
+ Waypoint.Context.refreshAll()
135
+ }
136
+
137
+ /* Public */
138
+ /* http://imakewebthings.com/waypoints/api/viewport-height */
139
+ Waypoint.viewportHeight = function() {
140
+ return window.innerHeight || document.documentElement.clientHeight
141
+ }
142
+
143
+ /* Public */
144
+ /* http://imakewebthings.com/waypoints/api/viewport-width */
145
+ Waypoint.viewportWidth = function() {
146
+ return document.documentElement.clientWidth
147
+ }
148
+
149
+ Waypoint.adapters = []
150
+
151
+ Waypoint.defaults = {
152
+ context: window,
153
+ continuous: true,
154
+ enabled: true,
155
+ group: 'default',
156
+ horizontal: false,
157
+ offset: 0
158
+ }
159
+
160
+ Waypoint.offsetAliases = {
161
+ 'bottom-in-view': function() {
162
+ return this.context.innerHeight() - this.adapter.outerHeight()
163
+ },
164
+ 'right-in-view': function() {
165
+ return this.context.innerWidth() - this.adapter.outerWidth()
166
+ }
167
+ }
168
+
169
+ window.Waypoint = Waypoint
170
+ }())
171
+ ;(function() {
172
+ 'use strict'
173
+
174
+ function requestAnimationFrameShim(callback) {
175
+ window.setTimeout(callback, 1000 / 60)
176
+ }
177
+
178
+ var keyCounter = 0
179
+ var contexts = {}
180
+ var Waypoint = window.Waypoint
181
+ var oldWindowLoad = window.onload
182
+
183
+ /* http://imakewebthings.com/waypoints/api/context */
184
+ function Context(element) {
185
+ this.element = element
186
+ this.Adapter = Waypoint.Adapter
187
+ this.adapter = new this.Adapter(element)
188
+ this.key = 'waypoint-context-' + keyCounter
189
+ this.didScroll = false
190
+ this.didResize = false
191
+ this.oldScroll = {
192
+ x: this.adapter.scrollLeft(),
193
+ y: this.adapter.scrollTop()
194
+ }
195
+ this.waypoints = {
196
+ vertical: {},
197
+ horizontal: {}
198
+ }
199
+
200
+ element.waypointContextKey = this.key
201
+ contexts[element.waypointContextKey] = this
202
+ keyCounter += 1
203
+ if (!Waypoint.windowContext) {
204
+ Waypoint.windowContext = true
205
+ Waypoint.windowContext = new Context(window)
206
+ }
207
+
208
+ this.createThrottledScrollHandler()
209
+ this.createThrottledResizeHandler()
210
+ }
211
+
212
+ /* Private */
213
+ Context.prototype.add = function(waypoint) {
214
+ var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
215
+ this.waypoints[axis][waypoint.key] = waypoint
216
+ this.refresh()
217
+ }
218
+
219
+ /* Private */
220
+ Context.prototype.checkEmpty = function() {
221
+ var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
222
+ var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
223
+ var isWindow = this.element == this.element.window
224
+ if (horizontalEmpty && verticalEmpty && !isWindow) {
225
+ this.adapter.off('.waypoints')
226
+ delete contexts[this.key]
227
+ }
228
+ }
229
+
230
+ /* Private */
231
+ Context.prototype.createThrottledResizeHandler = function() {
232
+ var self = this
233
+
234
+ function resizeHandler() {
235
+ self.handleResize()
236
+ self.didResize = false
237
+ }
238
+
239
+ this.adapter.on('resize.waypoints', function() {
240
+ if (!self.didResize) {
241
+ self.didResize = true
242
+ Waypoint.requestAnimationFrame(resizeHandler)
243
+ }
244
+ })
245
+ }
246
+
247
+ /* Private */
248
+ Context.prototype.createThrottledScrollHandler = function() {
249
+ var self = this
250
+ function scrollHandler() {
251
+ self.handleScroll()
252
+ self.didScroll = false
253
+ }
254
+
255
+ this.adapter.on('scroll.waypoints', function() {
256
+ if (!self.didScroll || Waypoint.isTouch) {
257
+ self.didScroll = true
258
+ Waypoint.requestAnimationFrame(scrollHandler)
259
+ }
260
+ })
261
+ }
262
+
263
+ /* Private */
264
+ Context.prototype.handleResize = function() {
265
+ Waypoint.Context.refreshAll()
266
+ }
267
+
268
+ /* Private */
269
+ Context.prototype.handleScroll = function() {
270
+ var triggeredGroups = {}
271
+ var axes = {
272
+ horizontal: {
273
+ newScroll: this.adapter.scrollLeft(),
274
+ oldScroll: this.oldScroll.x,
275
+ forward: 'right',
276
+ backward: 'left'
277
+ },
278
+ vertical: {
279
+ newScroll: this.adapter.scrollTop(),
280
+ oldScroll: this.oldScroll.y,
281
+ forward: 'down',
282
+ backward: 'up'
283
+ }
284
+ }
285
+
286
+ for (var axisKey in axes) {
287
+ var axis = axes[axisKey]
288
+ var isForward = axis.newScroll > axis.oldScroll
289
+ var direction = isForward ? axis.forward : axis.backward
290
+
291
+ for (var waypointKey in this.waypoints[axisKey]) {
292
+ var waypoint = this.waypoints[axisKey][waypointKey]
293
+ if (waypoint.triggerPoint === null) {
294
+ continue
295
+ }
296
+ var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
297
+ var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
298
+ var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
299
+ var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
300
+ if (crossedForward || crossedBackward) {
301
+ waypoint.queueTrigger(direction)
302
+ triggeredGroups[waypoint.group.id] = waypoint.group
303
+ }
304
+ }
305
+ }
306
+
307
+ for (var groupKey in triggeredGroups) {
308
+ triggeredGroups[groupKey].flushTriggers()
309
+ }
310
+
311
+ this.oldScroll = {
312
+ x: axes.horizontal.newScroll,
313
+ y: axes.vertical.newScroll
314
+ }
315
+ }
316
+
317
+ /* Private */
318
+ Context.prototype.innerHeight = function() {
319
+ /*eslint-disable eqeqeq */
320
+ if (this.element == this.element.window) {
321
+ return Waypoint.viewportHeight()
322
+ }
323
+ /*eslint-enable eqeqeq */
324
+ return this.adapter.innerHeight()
325
+ }
326
+
327
+ /* Private */
328
+ Context.prototype.remove = function(waypoint) {
329
+ delete this.waypoints[waypoint.axis][waypoint.key]
330
+ this.checkEmpty()
331
+ }
332
+
333
+ /* Private */
334
+ Context.prototype.innerWidth = function() {
335
+ /*eslint-disable eqeqeq */
336
+ if (this.element == this.element.window) {
337
+ return Waypoint.viewportWidth()
338
+ }
339
+ /*eslint-enable eqeqeq */
340
+ return this.adapter.innerWidth()
341
+ }
342
+
343
+ /* Public */
344
+ /* http://imakewebthings.com/waypoints/api/context-destroy */
345
+ Context.prototype.destroy = function() {
346
+ var allWaypoints = []
347
+ for (var axis in this.waypoints) {
348
+ for (var waypointKey in this.waypoints[axis]) {
349
+ allWaypoints.push(this.waypoints[axis][waypointKey])
350
+ }
351
+ }
352
+ for (var i = 0, end = allWaypoints.length; i < end; i++) {
353
+ allWaypoints[i].destroy()
354
+ }
355
+ }
356
+
357
+ /* Public */
358
+ /* http://imakewebthings.com/waypoints/api/context-refresh */
359
+ Context.prototype.refresh = function() {
360
+ /*eslint-disable eqeqeq */
361
+ var isWindow = this.element == this.element.window
362
+ /*eslint-enable eqeqeq */
363
+ var contextOffset = isWindow ? undefined : this.adapter.offset()
364
+ var triggeredGroups = {}
365
+ var axes
366
+
367
+ this.handleScroll()
368
+ axes = {
369
+ horizontal: {
370
+ contextOffset: isWindow ? 0 : contextOffset.left,
371
+ contextScroll: isWindow ? 0 : this.oldScroll.x,
372
+ contextDimension: this.innerWidth(),
373
+ oldScroll: this.oldScroll.x,
374
+ forward: 'right',
375
+ backward: 'left',
376
+ offsetProp: 'left'
377
+ },
378
+ vertical: {
379
+ contextOffset: isWindow ? 0 : contextOffset.top,
380
+ contextScroll: isWindow ? 0 : this.oldScroll.y,
381
+ contextDimension: this.innerHeight(),
382
+ oldScroll: this.oldScroll.y,
383
+ forward: 'down',
384
+ backward: 'up',
385
+ offsetProp: 'top'
386
+ }
387
+ }
388
+
389
+ for (var axisKey in axes) {
390
+ var axis = axes[axisKey]
391
+ for (var waypointKey in this.waypoints[axisKey]) {
392
+ var waypoint = this.waypoints[axisKey][waypointKey]
393
+ var adjustment = waypoint.options.offset
394
+ var oldTriggerPoint = waypoint.triggerPoint
395
+ var elementOffset = 0
396
+ var freshWaypoint = oldTriggerPoint == null
397
+ var contextModifier, wasBeforeScroll, nowAfterScroll
398
+ var triggeredBackward, triggeredForward
399
+
400
+ if (waypoint.element !== waypoint.element.window) {
401
+ elementOffset = waypoint.adapter.offset()[axis.offsetProp]
402
+ }
403
+
404
+ if (typeof adjustment === 'function') {
405
+ adjustment = adjustment.apply(waypoint)
406
+ }
407
+ else if (typeof adjustment === 'string') {
408
+ adjustment = parseFloat(adjustment)
409
+ if (waypoint.options.offset.indexOf('%') > - 1) {
410
+ adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
411
+ }
412
+ }
413
+
414
+ contextModifier = axis.contextScroll - axis.contextOffset
415
+ waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment)
416
+ wasBeforeScroll = oldTriggerPoint < axis.oldScroll
417
+ nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
418
+ triggeredBackward = wasBeforeScroll && nowAfterScroll
419
+ triggeredForward = !wasBeforeScroll && !nowAfterScroll
420
+
421
+ if (!freshWaypoint && triggeredBackward) {
422
+ waypoint.queueTrigger(axis.backward)
423
+ triggeredGroups[waypoint.group.id] = waypoint.group
424
+ }
425
+ else if (!freshWaypoint && triggeredForward) {
426
+ waypoint.queueTrigger(axis.forward)
427
+ triggeredGroups[waypoint.group.id] = waypoint.group
428
+ }
429
+ else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
430
+ waypoint.queueTrigger(axis.forward)
431
+ triggeredGroups[waypoint.group.id] = waypoint.group
432
+ }
433
+ }
434
+ }
435
+
436
+ Waypoint.requestAnimationFrame(function() {
437
+ for (var groupKey in triggeredGroups) {
438
+ triggeredGroups[groupKey].flushTriggers()
439
+ }
440
+ })
441
+
442
+ return this
443
+ }
444
+
445
+ /* Private */
446
+ Context.findOrCreateByElement = function(element) {
447
+ return Context.findByElement(element) || new Context(element)
448
+ }
449
+
450
+ /* Private */
451
+ Context.refreshAll = function() {
452
+ for (var contextId in contexts) {
453
+ contexts[contextId].refresh()
454
+ }
455
+ }
456
+
457
+ /* Public */
458
+ /* http://imakewebthings.com/waypoints/api/context-find-by-element */
459
+ Context.findByElement = function(element) {
460
+ return contexts[element.waypointContextKey]
461
+ }
462
+
463
+ window.onload = function() {
464
+ if (oldWindowLoad) {
465
+ oldWindowLoad()
466
+ }
467
+ Context.refreshAll()
468
+ }
469
+
470
+
471
+ Waypoint.requestAnimationFrame = function(callback) {
472
+ var requestFn = window.requestAnimationFrame ||
473
+ window.mozRequestAnimationFrame ||
474
+ window.webkitRequestAnimationFrame ||
475
+ requestAnimationFrameShim
476
+ requestFn.call(window, callback)
477
+ }
478
+ Waypoint.Context = Context
479
+ }())
480
+ ;(function() {
481
+ 'use strict'
482
+
483
+ function byTriggerPoint(a, b) {
484
+ return a.triggerPoint - b.triggerPoint
485
+ }
486
+
487
+ function byReverseTriggerPoint(a, b) {
488
+ return b.triggerPoint - a.triggerPoint
489
+ }
490
+
491
+ var groups = {
492
+ vertical: {},
493
+ horizontal: {}
494
+ }
495
+ var Waypoint = window.Waypoint
496
+
497
+ /* http://imakewebthings.com/waypoints/api/group */
498
+ function Group(options) {
499
+ this.name = options.name
500
+ this.axis = options.axis
501
+ this.id = this.name + '-' + this.axis
502
+ this.waypoints = []
503
+ this.clearTriggerQueues()
504
+ groups[this.axis][this.name] = this
505
+ }
506
+
507
+ /* Private */
508
+ Group.prototype.add = function(waypoint) {
509
+ this.waypoints.push(waypoint)
510
+ }
511
+
512
+ /* Private */
513
+ Group.prototype.clearTriggerQueues = function() {
514
+ this.triggerQueues = {
515
+ up: [],
516
+ down: [],
517
+ left: [],
518
+ right: []
519
+ }
520
+ }
521
+
522
+ /* Private */
523
+ Group.prototype.flushTriggers = function() {
524
+ for (var direction in this.triggerQueues) {
525
+ var waypoints = this.triggerQueues[direction]
526
+ var reverse = direction === 'up' || direction === 'left'
527
+ waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
528
+ for (var i = 0, end = waypoints.length; i < end; i += 1) {
529
+ var waypoint = waypoints[i]
530
+ if (waypoint.options.continuous || i === waypoints.length - 1) {
531
+ waypoint.trigger([direction])
532
+ }
533
+ }
534
+ }
535
+ this.clearTriggerQueues()
536
+ }
537
+
538
+ /* Private */
539
+ Group.prototype.next = function(waypoint) {
540
+ this.waypoints.sort(byTriggerPoint)
541
+ var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
542
+ var isLast = index === this.waypoints.length - 1
543
+ return isLast ? null : this.waypoints[index + 1]
544
+ }
545
+
546
+ /* Private */
547
+ Group.prototype.previous = function(waypoint) {
548
+ this.waypoints.sort(byTriggerPoint)
549
+ var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
550
+ return index ? this.waypoints[index - 1] : null
551
+ }
552
+
553
+ /* Private */
554
+ Group.prototype.queueTrigger = function(waypoint, direction) {
555
+ this.triggerQueues[direction].push(waypoint)
556
+ }
557
+
558
+ /* Private */
559
+ Group.prototype.remove = function(waypoint) {
560
+ var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
561
+ if (index > -1) {
562
+ this.waypoints.splice(index, 1)
563
+ }
564
+ }
565
+
566
+ /* Public */
567
+ /* http://imakewebthings.com/waypoints/api/first */
568
+ Group.prototype.first = function() {
569
+ return this.waypoints[0]
570
+ }
571
+
572
+ /* Public */
573
+ /* http://imakewebthings.com/waypoints/api/last */
574
+ Group.prototype.last = function() {
575
+ return this.waypoints[this.waypoints.length - 1]
576
+ }
577
+
578
+ /* Private */
579
+ Group.findOrCreate = function(options) {
580
+ return groups[options.axis][options.name] || new Group(options)
581
+ }
582
+
583
+ Waypoint.Group = Group
584
+ }())
585
+ ;(function() {
586
+ 'use strict'
587
+
588
+ var $ = window.jQuery
589
+ var Waypoint = window.Waypoint
590
+
591
+ function JQueryAdapter(element) {
592
+ this.$element = $(element)
593
+ }
594
+
595
+ $.each([
596
+ 'innerHeight',
597
+ 'innerWidth',
598
+ 'off',
599
+ 'offset',
600
+ 'on',
601
+ 'outerHeight',
602
+ 'outerWidth',
603
+ 'scrollLeft',
604
+ 'scrollTop'
605
+ ], function(i, method) {
606
+ JQueryAdapter.prototype[method] = function() {
607
+ var args = Array.prototype.slice.call(arguments)
608
+ return this.$element[method].apply(this.$element, args)
609
+ }
610
+ })
611
+
612
+ $.each([
613
+ 'extend',
614
+ 'inArray',
615
+ 'isEmptyObject'
616
+ ], function(i, method) {
617
+ JQueryAdapter[method] = $[method]
618
+ })
619
+
620
+ Waypoint.adapters.push({
621
+ name: 'jquery',
622
+ Adapter: JQueryAdapter
623
+ })
624
+ Waypoint.Adapter = JQueryAdapter
625
+ }())
626
+ ;(function() {
627
+ 'use strict'
628
+
629
+ var Waypoint = window.Waypoint
630
+
631
+ function createExtension(framework) {
632
+ return function() {
633
+ var waypoints = []
634
+ var overrides = arguments[0]
635
+
636
+ if (framework.isFunction(arguments[0])) {
637
+ overrides = framework.extend({}, arguments[1])
638
+ overrides.handler = arguments[0]
639
+ }
640
+
641
+ this.each(function() {
642
+ var options = framework.extend({}, overrides, {
643
+ element: this
644
+ })
645
+ if (typeof options.context === 'string') {
646
+ options.context = framework(this).closest(options.context)[0]
647
+ }
648
+ waypoints.push(new Waypoint(options))
649
+ })
650
+
651
+ return waypoints
652
+ }
653
+ }
654
+
655
+ if (window.jQuery) {
656
+ window.jQuery.fn.waypoint = createExtension(window.jQuery)
657
+ }
658
+ if (window.Zepto) {
659
+ window.Zepto.fn.waypoint = createExtension(window.Zepto)
660
+ }
661
+ }())
662
+ ;
vendor/waypoints/jquery.waypoints.min.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /*!
2
+ Waypoints - 4.0.1
3
+ Copyright © 2011-2016 Caleb Troughton
4
+ Licensed under the MIT license.
5
+ https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
6
+ */
7
+ !function(){"use strict";function t(o){if(!o)throw new Error("No options passed to Waypoint constructor");if(!o.element)throw new Error("No element option passed to Waypoint constructor");if(!o.handler)throw new Error("No handler option passed to Waypoint constructor");this.key="waypoint-"+e,this.options=t.Adapter.extend({},t.defaults,o),this.element=this.options.element,this.adapter=new t.Adapter(this.element),this.callback=o.handler,this.axis=this.options.horizontal?"horizontal":"vertical",this.enabled=this.options.enabled,this.triggerPoint=null,this.group=t.Group.findOrCreate({name:this.options.group,axis:this.axis}),this.context=t.Context.findOrCreateByElement(this.options.context),t.offsetAliases[this.options.offset]&&(this.options.offset=t.offsetAliases[this.options.offset]),this.group.add(this),this.context.add(this),i[this.key]=this,e+=1}var e=0,i={};t.prototype.queueTrigger=function(t){this.group.queueTrigger(this,t)},t.prototype.trigger=function(t){this.enabled&&this.callback&&this.callback.apply(this,t)},t.prototype.destroy=function(){this.context.remove(this),this.group.remove(this),delete i[this.key]},t.prototype.disable=function(){return this.enabled=!1,this},t.prototype.enable=function(){return this.context.refresh(),this.enabled=!0,this},t.prototype.next=function(){return this.group.next(this)},t.prototype.previous=function(){return this.group.previous(this)},t.invokeAll=function(t){var e=[];for(var o in i)e.push(i[o]);for(var n=0,r=e.length;r>n;n++)e[n][t]()},t.destroyAll=function(){t.invokeAll("destroy")},t.disableAll=function(){t.invokeAll("disable")},t.enableAll=function(){t.Context.refreshAll();for(var e in i)i[e].enabled=!0;return this},t.refreshAll=function(){t.Context.refreshAll()},t.viewportHeight=function(){return window.innerHeight||document.documentElement.clientHeight},t.viewportWidth=function(){return document.documentElement.clientWidth},t.adapters=[],t.defaults={context:window,continuous:!0,enabled:!0,group:"default",horizontal:!1,offset:0},t.offsetAliases={"bottom-in-view":function(){return this.context.innerHeight()-this.adapter.outerHeight()},"right-in-view":function(){return this.context.innerWidth()-this.adapter.outerWidth()}},window.Waypoint=t}(),function(){"use strict";function t(t){window.setTimeout(t,1e3/60)}function e(t){this.element=t,this.Adapter=n.Adapter,this.adapter=new this.Adapter(t),this.key="waypoint-context-"+i,this.didScroll=!1,this.didResize=!1,this.oldScroll={x:this.adapter.scrollLeft(),y:this.adapter.scrollTop()},this.waypoints={vertical:{},horizontal:{}},t.waypointContextKey=this.key,o[t.waypointContextKey]=this,i+=1,n.windowContext||(n.windowContext=!0,n.windowContext=new e(window)),this.createThrottledScrollHandler(),this.createThrottledResizeHandler()}var i=0,o={},n=window.Waypoint,r=window.onload;e.prototype.add=function(t){var e=t.options.horizontal?"horizontal":"vertical";this.waypoints[e][t.key]=t,this.refresh()},e.prototype.checkEmpty=function(){var t=this.Adapter.isEmptyObject(this.waypoints.horizontal),e=this.Adapter.isEmptyObject(this.waypoints.vertical),i=this.element==this.element.window;t&&e&&!i&&(this.adapter.off(".waypoints"),delete o[this.key])},e.prototype.createThrottledResizeHandler=function(){function t(){e.handleResize(),e.didResize=!1}var e=this;this.adapter.on("resize.waypoints",function(){e.didResize||(e.didResize=!0,n.requestAnimationFrame(t))})},e.prototype.createThrottledScrollHandler=function(){function t(){e.handleScroll(),e.didScroll=!1}var e=this;this.adapter.on("scroll.waypoints",function(){(!e.didScroll||n.isTouch)&&(e.didScroll=!0,n.requestAnimationFrame(t))})},e.prototype.handleResize=function(){n.Context.refreshAll()},e.prototype.handleScroll=function(){var t={},e={horizontal:{newScroll:this.adapter.scrollLeft(),oldScroll:this.oldScroll.x,forward:"right",backward:"left"},vertical:{newScroll:this.adapter.scrollTop(),oldScroll:this.oldScroll.y,forward:"down",backward:"up"}};for(var i in e){var o=e[i],n=o.newScroll>o.oldScroll,r=n?o.forward:o.backward;for(var s in this.waypoints[i]){var a=this.waypoints[i][s];if(null!==a.triggerPoint){var l=o.oldScroll<a.triggerPoint,h=o.newScroll>=a.triggerPoint,p=l&&h,u=!l&&!h;(p||u)&&(a.queueTrigger(r),t[a.group.id]=a.group)}}}for(var c in t)t[c].flushTriggers();this.oldScroll={x:e.horizontal.newScroll,y:e.vertical.newScroll}},e.prototype.innerHeight=function(){return this.element==this.element.window?n.viewportHeight():this.adapter.innerHeight()},e.prototype.remove=function(t){delete this.waypoints[t.axis][t.key],this.checkEmpty()},e.prototype.innerWidth=function(){return this.element==this.element.window?n.viewportWidth():this.adapter.innerWidth()},e.prototype.destroy=function(){var t=[];for(var e in this.waypoints)for(var i in this.waypoints[e])t.push(this.waypoints[e][i]);for(var o=0,n=t.length;n>o;o++)t[o].destroy()},e.prototype.refresh=function(){var t,e=this.element==this.element.window,i=e?void 0:this.adapter.offset(),o={};this.handleScroll(),t={horizontal:{contextOffset:e?0:i.left,contextScroll:e?0:this.oldScroll.x,contextDimension:this.innerWidth(),oldScroll:this.oldScroll.x,forward:"right",backward:"left",offsetProp:"left"},vertical:{contextOffset:e?0:i.top,contextScroll:e?0:this.oldScroll.y,contextDimension:this.innerHeight(),oldScroll:this.oldScroll.y,forward:"down",backward:"up",offsetProp:"top"}};for(var r in t){var s=t[r];for(var a in this.waypoints[r]){var l,h,p,u,c,d=this.waypoints[r][a],f=d.options.offset,w=d.triggerPoint,y=0,g=null==w;d.element!==d.element.window&&(y=d.adapter.offset()[s.offsetProp]),"function"==typeof f?f=f.apply(d):"string"==typeof f&&(f=parseFloat(f),d.options.offset.indexOf("%")>-1&&(f=Math.ceil(s.contextDimension*f/100))),l=s.contextScroll-s.contextOffset,d.triggerPoint=Math.floor(y+l-f),h=w<s.oldScroll,p=d.triggerPoint>=s.oldScroll,u=h&&p,c=!h&&!p,!g&&u?(d.queueTrigger(s.backward),o[d.group.id]=d.group):!g&&c?(d.queueTrigger(s.forward),o[d.group.id]=d.group):g&&s.oldScroll>=d.triggerPoint&&(d.queueTrigger(s.forward),o[d.group.id]=d.group)}}return n.requestAnimationFrame(function(){for(var t in o)o[t].flushTriggers()}),this},e.findOrCreateByElement=function(t){return e.findByElement(t)||new e(t)},e.refreshAll=function(){for(var t in o)o[t].refresh()},e.findByElement=function(t){return o[t.waypointContextKey]},window.onload=function(){r&&r(),e.refreshAll()},n.requestAnimationFrame=function(e){var i=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||t;i.call(window,e)},n.Context=e}(),function(){"use strict";function t(t,e){return t.triggerPoint-e.triggerPoint}function e(t,e){return e.triggerPoint-t.triggerPoint}function i(t){this.name=t.name,this.axis=t.axis,this.id=this.name+"-"+this.axis,this.waypoints=[],this.clearTriggerQueues(),o[this.axis][this.name]=this}var o={vertical:{},horizontal:{}},n=window.Waypoint;i.prototype.add=function(t){this.waypoints.push(t)},i.prototype.clearTriggerQueues=function(){this.triggerQueues={up:[],down:[],left:[],right:[]}},i.prototype.flushTriggers=function(){for(var i in this.triggerQueues){var o=this.triggerQueues[i],n="up"===i||"left"===i;o.sort(n?e:t);for(var r=0,s=o.length;s>r;r+=1){var a=o[r];(a.options.continuous||r===o.length-1)&&a.trigger([i])}}this.clearTriggerQueues()},i.prototype.next=function(e){this.waypoints.sort(t);var i=n.Adapter.inArray(e,this.waypoints),o=i===this.waypoints.length-1;return o?null:this.waypoints[i+1]},i.prototype.previous=function(e){this.waypoints.sort(t);var i=n.Adapter.inArray(e,this.waypoints);return i?this.waypoints[i-1]:null},i.prototype.queueTrigger=function(t,e){this.triggerQueues[e].push(t)},i.prototype.remove=function(t){var e=n.Adapter.inArray(t,this.waypoints);e>-1&&this.waypoints.splice(e,1)},i.prototype.first=function(){return this.waypoints[0]},i.prototype.last=function(){return this.waypoints[this.waypoints.length-1]},i.findOrCreate=function(t){return o[t.axis][t.name]||new i(t)},n.Group=i}(),function(){"use strict";function t(t){this.$element=e(t)}var e=window.jQuery,i=window.Waypoint;e.each(["innerHeight","innerWidth","off","offset","on","outerHeight","outerWidth","scrollLeft","scrollTop"],function(e,i){t.prototype[i]=function(){var t=Array.prototype.slice.call(arguments);return this.$element[i].apply(this.$element,t)}}),e.each(["extend","inArray","isEmptyObject"],function(i,o){t[o]=e[o]}),i.adapters.push({name:"jquery",Adapter:t}),i.Adapter=t}(),function(){"use strict";function t(t){return function(){var i=[],o=arguments[0];return t.isFunction(arguments[0])&&(o=t.extend({},arguments[1]),o.handler=arguments[0]),this.each(function(){var n=t.extend({},o,{element:this});"string"==typeof n.context&&(n.context=t(this).closest(n.context)[0]),i.push(new e(n))}),i}}var e=window.Waypoint;window.jQuery&&(window.jQuery.fn.waypoint=t(window.jQuery)),window.Zepto&&(window.Zepto.fn.waypoint=t(window.Zepto))}();
wpml-config.xml DELETED
@@ -1,7 +0,0 @@
1
- <wpml-config>
2
- <admin-texts>
3
- <key name="ez-toc-settings">
4
- <key name="heading_text"/>
5
- </key>
6
- </admin-texts>
7
- </wpml-config>