This is an automated email from the ASF dual-hosted git repository.
achennaka pushed a commit to branch gh-pages
in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/gh-pages by this push:
new 015e24c98 [site] Remove thirdparty resource references
015e24c98 is described below
commit 015e24c9854239e1bd4f51f18e28482f8b993215
Author: root <[email protected]>
AuthorDate: Mon Feb 10 23:36:31 2025 -0800
[site] Remove thirdparty resource references
This commit updates Kudu website by removing any resource reference
to any thirparty hosted website and replacing them with files in the
local repo. This is needed to ensure the site works as expected once
the CSP blocking is in effect by Apache from March 1.
This commit also reverts commit 55b58c as the approach taken did not
work as expected.
Also updated site_tool script to use the correct command for html-proofer
and removed the verbose option as it is not present anymore.
Change-Id: I5971a406968bc69fc21bbd05618d85e702210539
Reviewed-on: http://gerrit.cloudera.org:8080/22472
Reviewed-by: Alexey Serbin <[email protected]>
Tested-by: Abhishek Chennaka <[email protected]>
---
Gemfile.lock | 4 +-
_includes/bottom_common.html | 8 +-
_includes/top_common.html | 13 +-
...-07-30-building-near-real-time-big-data-lake.md | 21 +-
img/apachekudu_logo_0716_160px.png | Bin 0 -> 8404 bytes
img/apachekudu_logo_0716_290px.png | Bin 0 -> 17306 bytes
img/apachekudu_logo_0716_345px.png | Bin 0 -> 21572 bytes
img/apachekudu_logo_0716_580px.png | Bin 0 -> 38943 bytes
img/apachekudu_logo_0716_690px.png | Bin 0 -> 47047 bytes
img/apachekudu_logo_0716_80px.png | Bin 0 -> 3706 bytes
img/boristyukin.com/nifi_initial.png | Bin 0 -> 138081 bytes
img/boristyukin.com/nifi_rt.png | Bin 0 -> 129932 bytes
img/boristyukin.com/pipelinearchitecture.png | Bin 0 -> 305515 bytes
img/boristyukin.com/query1.png | Bin 0 -> 15619 bytes
img/boristyukin.com/query2.png | Bin 0 -> 15401 bytes
img/boristyukin.com/query3.png | Bin 0 -> 25717 bytes
img/envelope_12px.png | Bin 0 -> 2942 bytes
img/gerrit_mark_16px.png | Bin 0 -> 468 bytes
img/github_mark_16px.png | Bin 0 -> 505 bytes
img/github_mark_light_16px.png | Bin 0 -> 404 bytes
img/jira_mark_16px.png | Bin 0 -> 232 bytes
img/jira_mark_white_16px.png | Bin 0 -> 215 bytes
img/slack_mark_16px.png | Bin 0 -> 769 bytes
img/slack_mark_white_16px.png | Bin 0 -> 479 bytes
img/twitter_mark_16px.png | Bin 0 -> 438 bytes
img/twitter_mark_white_16px.png | Bin 0 -> 399 bytes
js/anchor.js | 322 +++++++++++++++++++++
js/bootstrap.min.js | 7 +
js/jquery.min.js | 6 +
site_tool | 3 +-
30 files changed, 356 insertions(+), 28 deletions(-)
diff --git a/Gemfile.lock b/Gemfile.lock
index 38946cd48..f750f8ad9 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -54,7 +54,7 @@ GEM
kramdown (~> 2.0)
libv8 (3.16.14.19)
liquid (4.0.3)
- listen (3.2.1)
+ listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.4.0)
@@ -101,4 +101,4 @@ DEPENDENCIES
therubyracer
BUNDLED WITH
- 2.1.4
+ 2.5.23
diff --git a/_includes/bottom_common.html b/_includes/bottom_common.html
index 29a1aa00b..b61bfe040 100644
--- a/_includes/bottom_common.html
+++ b/_includes/bottom_common.html
@@ -18,7 +18,7 @@
</div>
</footer>
</div>
- <script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
+ <script src="/js/jquery.min.js"></script>
<script>
// Try to detect touch-screen devices. Note: Many laptops have touch
screens.
$(document).ready(function() {
@@ -29,10 +29,8 @@
}
});
</script>
- <script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"
-
integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
- crossorigin="anonymous"></script>
- <script
src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/3.1.0/anchor.js"></script>
+ <script src="/js/bootstrap.min.js"></script>
+ <script src="/js/anchor.js"></script>
<script>
anchors.options = {
placement: 'right',
diff --git a/_includes/top_common.html b/_includes/top_common.html
index 5e84df44b..bc7c3c5f1 100644
--- a/_includes/top_common.html
+++ b/_includes/top_common.html
@@ -7,15 +7,6 @@
<!-- The above 3 meta tags *must* come first in the head; any other head
content must come *after* these tags -->
<meta name="description" content="A new open source Apache Hadoop
ecosystem project, Apache Kudu completes Hadoop's storage layer to enable fast
analytics on fast data" />
<meta name="author" content="Cloudera" />
- <meta http-equiv="Content-Security-Policy" content="
- default-src 'self';
- script-src 'self' https://kudu.apache.org https://cdn.jsdelivr.net
https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com 'unsafe-inline';
- style-src 'self' https://kudu.apache.org https://fonts.googleapis.com
https://maxcdn.bootstrapcdn.com 'unsafe-inline';
- font-src 'self' https://fonts.gstatic.com
https://maxcdn.bootstrapcdn.com data:;
- img-src 'self' https://kudu.apache.org
https://d3dr9sfxru4sde.cloudfront.net https://www.apache.org data:;
- base-uri 'self';
- form-action 'self';
- ">
<title>Apache Kudu - {{ page.title }}</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
@@ -54,8 +45,8 @@
</button>
{% if page.active_nav != 'home' %}
<a class="logo" href="{{site.github.url}}/"><img
-
src="//d3dr9sfxru4sde.cloudfront.net/i/k/apachekudu_logo_0716_80px.png"
-
srcset="//d3dr9sfxru4sde.cloudfront.net/i/k/apachekudu_logo_0716_80px.png 1x,
//d3dr9sfxru4sde.cloudfront.net/i/k/apachekudu_logo_0716_160px.png 2x"
+ src="/img/apachekudu_logo_0716_80px.png"
+ srcset="/img/apachekudu_logo_0716_80px.png 1x,
/img/apachekudu_logo_0716_160px.png 2x"
alt="Apache Kudu"/></a>
{% endif %}
</div>
diff --git a/_posts/2020-07-30-building-near-real-time-big-data-lake.md
b/_posts/2020-07-30-building-near-real-time-big-data-lake.md
index 81471ff6e..24e3d3839 100644
--- a/_posts/2020-07-30-building-near-real-time-big-data-lake.md
+++ b/_posts/2020-07-30-building-near-real-time-big-data-lake.md
@@ -114,8 +114,8 @@ product you desire and trust. One of these products for us
was Apache NiFi, whic
tremendous value.
After a lot of trials and errors, we decided on this architecture:
-
-<img src="https://boristyukin.com/content/images/pipelinearchitecture.png"
width="100%"/>
+<!--Image downloaded from
https://boristyukin.com/content/images/pipelinearchitecture.png-->
+<img src="/img/boristyukin.com/pipelinearchitecture.png" width="100%"/>
One of the toughest challenges we faced right away was the fact that most of
the Big Data data
engines were not designed to support mutable data but rather immutable
append-only data. All the
@@ -149,7 +149,8 @@ Initial ingest is pretty typical - we use Sqoop to extract
data from Cerner Orac
NiFi helps orchestrate initial load for hundreds of tables. Actually, this
NiFi flow below can
handle initial ingest of hundreds of tables!
-<img src="https://boristyukin.com/content/images/nifi_initial.png"
width="100%" />
+<!--Image downloaded from
https://boristyukin.com/content/images/nifi_initial.png-->
+<img src="/img/boristyukin.com/nifi_initial.png" width="100%" />
Our secret sauce though is
[MetaZoo](http://boristyukin.com/how-to-ingest-a-large-number-of-tables-into-a-big-data-lake-or-why-i-built-metazoo/).
MetaZoo generates optimal parameters for Sqoop (such as a number of mappers,
split-by column, and so
@@ -198,7 +199,8 @@ without much impact.
Below is the NiFi flow than handles real-time streaming from
Oracle/GoldenGate/Kafka and persists
data into Kudu:
-<img src="https://boristyukin.com/content/images/nifi_rt.png" width="100%"/>
+<!--Image downloaded from https://boristyukin.com/content/images/nifi_rt.png-->
+<img src="/img/boristyukin.com/nifi_rt.png" width="100%"/>
1. NiFi flow consumes Kafka messages, produced by GoldenGate. Every table from
every domain has
its own Kafka topic. Topics have only one partition to preserve the original
order of messages.
@@ -231,18 +233,21 @@ scalability of Big Data technology.
Here, I run a query in Impala to count patients, admitted to our hospitals
within the last 7 days,
who are still in the hospitals (not discharged yet):
-
+<!--Image downloaded from https://boristyukin.com/content/images/query1.png-->
+
Then 5 seconds later I run the same query again to see numbers changed - more
patients got admitted
and discharged:
-]
+<!--Image downloaded from https://boristyukin.com/content/images/query2.png-->
+]
This query below counts certain clinical events in the 20B row Kudu table
(which is updated in near
real-time). While it takes 28 seconds to finish, this query would never even
finish I ran it against
our Oracle database. It found 13.7B events:
-
+<!--Image downloaded from https://boristyukin.com/content/images/query3.png-->
+
## Credits
Apache Impala, Apache Kudu and Apache NiFi were the pillars of our real-time
pipeline. Back in 2017,
@@ -254,4 +259,4 @@ We were amazed by all the help, dedication, knowledge
sharing, friendliness, and
NiFi and Kudu developers. Huge thank you to all of you who helped us alone the
way. You guys are
amazing and you are building fantastic products!
-To be continued...
\ No newline at end of file
+To be continued...
diff --git a/img/apachekudu_logo_0716_160px.png
b/img/apachekudu_logo_0716_160px.png
new file mode 100644
index 000000000..3c2bf37c0
Binary files /dev/null and b/img/apachekudu_logo_0716_160px.png differ
diff --git a/img/apachekudu_logo_0716_290px.png
b/img/apachekudu_logo_0716_290px.png
new file mode 100644
index 000000000..6dea3ea03
Binary files /dev/null and b/img/apachekudu_logo_0716_290px.png differ
diff --git a/img/apachekudu_logo_0716_345px.png
b/img/apachekudu_logo_0716_345px.png
new file mode 100644
index 000000000..1afca8976
Binary files /dev/null and b/img/apachekudu_logo_0716_345px.png differ
diff --git a/img/apachekudu_logo_0716_580px.png
b/img/apachekudu_logo_0716_580px.png
new file mode 100644
index 000000000..4a8146fb4
Binary files /dev/null and b/img/apachekudu_logo_0716_580px.png differ
diff --git a/img/apachekudu_logo_0716_690px.png
b/img/apachekudu_logo_0716_690px.png
new file mode 100644
index 000000000..0ecbab7d1
Binary files /dev/null and b/img/apachekudu_logo_0716_690px.png differ
diff --git a/img/apachekudu_logo_0716_80px.png
b/img/apachekudu_logo_0716_80px.png
new file mode 100644
index 000000000..8d9349b2d
Binary files /dev/null and b/img/apachekudu_logo_0716_80px.png differ
diff --git a/img/boristyukin.com/nifi_initial.png
b/img/boristyukin.com/nifi_initial.png
new file mode 100644
index 000000000..cb09230f5
Binary files /dev/null and b/img/boristyukin.com/nifi_initial.png differ
diff --git a/img/boristyukin.com/nifi_rt.png b/img/boristyukin.com/nifi_rt.png
new file mode 100644
index 000000000..69c0e31ae
Binary files /dev/null and b/img/boristyukin.com/nifi_rt.png differ
diff --git a/img/boristyukin.com/pipelinearchitecture.png
b/img/boristyukin.com/pipelinearchitecture.png
new file mode 100644
index 000000000..52ac09f19
Binary files /dev/null and b/img/boristyukin.com/pipelinearchitecture.png differ
diff --git a/img/boristyukin.com/query1.png b/img/boristyukin.com/query1.png
new file mode 100644
index 000000000..e047bc285
Binary files /dev/null and b/img/boristyukin.com/query1.png differ
diff --git a/img/boristyukin.com/query2.png b/img/boristyukin.com/query2.png
new file mode 100644
index 000000000..8c2201ea2
Binary files /dev/null and b/img/boristyukin.com/query2.png differ
diff --git a/img/boristyukin.com/query3.png b/img/boristyukin.com/query3.png
new file mode 100644
index 000000000..9e6562667
Binary files /dev/null and b/img/boristyukin.com/query3.png differ
diff --git a/img/envelope_12px.png b/img/envelope_12px.png
new file mode 100644
index 000000000..3c3f9a52d
Binary files /dev/null and b/img/envelope_12px.png differ
diff --git a/img/gerrit_mark_16px.png b/img/gerrit_mark_16px.png
new file mode 100644
index 000000000..1b399d491
Binary files /dev/null and b/img/gerrit_mark_16px.png differ
diff --git a/img/github_mark_16px.png b/img/github_mark_16px.png
new file mode 100644
index 000000000..2d4c1519a
Binary files /dev/null and b/img/github_mark_16px.png differ
diff --git a/img/github_mark_light_16px.png b/img/github_mark_light_16px.png
new file mode 100644
index 000000000..7726b90b9
Binary files /dev/null and b/img/github_mark_light_16px.png differ
diff --git a/img/jira_mark_16px.png b/img/jira_mark_16px.png
new file mode 100644
index 000000000..89a1b7b1c
Binary files /dev/null and b/img/jira_mark_16px.png differ
diff --git a/img/jira_mark_white_16px.png b/img/jira_mark_white_16px.png
new file mode 100644
index 000000000..721600c13
Binary files /dev/null and b/img/jira_mark_white_16px.png differ
diff --git a/img/slack_mark_16px.png b/img/slack_mark_16px.png
new file mode 100644
index 000000000..13afbc596
Binary files /dev/null and b/img/slack_mark_16px.png differ
diff --git a/img/slack_mark_white_16px.png b/img/slack_mark_white_16px.png
new file mode 100644
index 000000000..cc739599d
Binary files /dev/null and b/img/slack_mark_white_16px.png differ
diff --git a/img/twitter_mark_16px.png b/img/twitter_mark_16px.png
new file mode 100644
index 000000000..bed6f4385
Binary files /dev/null and b/img/twitter_mark_16px.png differ
diff --git a/img/twitter_mark_white_16px.png b/img/twitter_mark_white_16px.png
new file mode 100644
index 000000000..bca2350c2
Binary files /dev/null and b/img/twitter_mark_white_16px.png differ
diff --git a/js/anchor.js b/js/anchor.js
new file mode 100644
index 000000000..e470643e6
--- /dev/null
+++ b/js/anchor.js
@@ -0,0 +1,322 @@
+/**
+ * AnchorJS - v3.1.0 - 2016-02-12
+ * https://github.com/bryanbraun/anchorjs
+ * Copyright (c) 2016 Bryan Braun; Licensed MIT
+ */
+
+function AnchorJS(options) {
+ 'use strict';
+ this.options = options || {};
+ this.elements = [];
+
+ /**
+ * Assigns options to the internal options object, and provides defaults.
+ * @param {Object} opts - Options object
+ */
+ function _applyRemainingDefaultOptions(opts) {
+ opts.icon = opts.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts
characters (and also URLs?), like '#', '¶', '❡', or '§'.
+ opts.visible = opts.hasOwnProperty('visible') ? opts.visible : 'hover'; //
Also accepts 'always' & 'touch'
+ opts.placement = opts.hasOwnProperty('placement') ? opts.placement :
'right'; // Also accepts 'left'
+ opts.class = opts.hasOwnProperty('class') ? opts.class : ''; // Accepts
any class name.
+ // Using Math.floor here will ensure the value is Number-cast and an
integer.
+ opts.truncate = opts.hasOwnProperty('truncate') ?
Math.floor(opts.truncate) : 64; // Accepts any value that can be typecast to a
number.
+ }
+
+ _applyRemainingDefaultOptions(this.options);
+
+ /**
+ * Checks to see if this device supports touch. Uses criteria pulled from
Modernizr:
+ *
https://github.com/Modernizr/Modernizr/blob/da22eb27631fc4957f67607fe6042e85c0a84656/feature-detects/touchevents.js#L40
+ * @return {Boolean} - true if the current device supports touch.
+ */
+ this.isTouchDevice = function() {
+ return !!(('ontouchstart' in window) || window.DocumentTouch && document
instanceof DocumentTouch);
+ };
+
+ /**
+ * Add anchor links to page elements.
+ * @param {String|Array|Nodelist} selector - A CSS selector for targeting
the elements you wish to add anchor links
+ * to. Also accepts an array or
nodeList containing the relavant elements.
+ * @return {this} - The AnchorJS object
+ */
+ this.add = function(selector) {
+ var elements,
+ elsWithIds,
+ idList,
+ elementID,
+ i,
+ index,
+ count,
+ tidyText,
+ newTidyText,
+ readableID,
+ anchor,
+ visibleOptionToUse,
+ indexesToDrop = [];
+
+ // We reapply options here because somebody may have overwritten the
default options object when setting options.
+ // For example, this overwrites all options but visible:
+ //
+ // anchors.options = { visible: 'always'; }
+ _applyRemainingDefaultOptions(this.options);
+
+ visibleOptionToUse = this.options.visible;
+ if (visibleOptionToUse === 'touch') {
+ visibleOptionToUse = this.isTouchDevice() ? 'always' : 'hover';
+ }
+
+ // Provide a sensible default selector, if none is given.
+ if (!selector) {
+ selector = 'h1, h2, h3, h4, h5, h6';
+ }
+
+ elements = _getElements(selector);
+
+ if (elements.length === 0) {
+ return false;
+ }
+
+ _addBaselineStyles();
+
+ // We produce a list of existing IDs so we don't generate a duplicate.
+ elsWithIds = document.querySelectorAll('[id]');
+ idList = [].map.call(elsWithIds, function assign(el) {
+ return el.id;
+ });
+
+ for (i = 0; i < elements.length; i++) {
+ if (this.hasAnchorJSLink(elements[i])) {
+ indexesToDrop.push(i);
+ continue;
+ }
+
+ if (elements[i].hasAttribute('id')) {
+ elementID = elements[i].getAttribute('id');
+ } else {
+ tidyText = this.urlify(elements[i].textContent);
+
+ // Compare our generated ID to existing IDs (and increment it if
needed)
+ // before we add it to the page.
+ newTidyText = tidyText;
+ count = 0;
+ do {
+ if (index !== undefined) {
+ newTidyText = tidyText + '-' + count;
+ }
+
+ index = idList.indexOf(newTidyText);
+ count += 1;
+ } while (index !== -1);
+ index = undefined;
+ idList.push(newTidyText);
+
+ elements[i].setAttribute('id', newTidyText);
+ elementID = newTidyText;
+ }
+
+ readableID = elementID.replace(/-/g, ' ');
+
+ // The following code builds the following DOM structure in a more
effiecient (albeit opaque) way.
+ // '<a class="anchorjs-link ' + this.options.class + '" href="#' +
elementID + '" aria-label="Anchor link for: ' + readableID + '"
data-anchorjs-icon="' + this.options.icon + '"></a>';
+ anchor = document.createElement('a');
+ anchor.className = 'anchorjs-link ' + this.options.class;
+ anchor.href = '#' + elementID;
+ anchor.setAttribute('aria-label', 'Anchor link for: ' + readableID);
+ anchor.setAttribute('data-anchorjs-icon', this.options.icon);
+
+ if (visibleOptionToUse === 'always') {
+ anchor.style.opacity = '1';
+ }
+
+ if (this.options.icon === '\ue9cb') {
+ anchor.style.fontFamily = 'anchorjs-icons';
+ anchor.style.fontStyle = 'normal';
+ anchor.style.fontVariant = 'normal';
+ anchor.style.fontWeight = 'normal';
+ anchor.style.lineHeight = 1;
+
+ // We set lineHeight = 1 here because the `anchorjs-icons` font family
could otherwise affect the
+ // height of the heading. This isn't the case for icons with
`placement: left`, so we restore
+ // line-height: inherit in that case, ensuring they remain positioned
correctly. For more info,
+ // see https://github.com/bryanbraun/anchorjs/issues/39.
+ if (this.options.placement === 'left') {
+ anchor.style.lineHeight = 'inherit';
+ }
+ }
+
+ if (this.options.placement === 'left') {
+ anchor.style.position = 'absolute';
+ anchor.style.marginLeft = '-1em';
+ anchor.style.paddingRight = '0.5em';
+ elements[i].insertBefore(anchor, elements[i].firstChild);
+ } else { // if the option provided is `right` (or anything else).
+ anchor.style.paddingLeft = '0.375em';
+ elements[i].appendChild(anchor);
+ }
+ }
+
+ for (i = 0; i < indexesToDrop.length; i++) {
+ elements.splice(indexesToDrop[i] - i, 1);
+ }
+ this.elements = this.elements.concat(elements);
+
+ return this;
+ };
+
+ /**
+ * Removes all anchorjs-links from elements targed by the selector.
+ * @param {String|Array|Nodelist} selector - A CSS selector string
targeting elements with anchor links,
+ * OR a nodeList / array
containing the DOM elements.
+ * @return {this} - The AnchorJS object
+ */
+ this.remove = function(selector) {
+ var index,
+ domAnchor,
+ elements = _getElements(selector);
+
+ for (var i = 0; i < elements.length; i++) {
+ domAnchor = elements[i].querySelector('.anchorjs-link');
+ if (domAnchor) {
+ // Drop the element from our main list, if it's in there.
+ index = this.elements.indexOf(elements[i]);
+ if (index !== -1) {
+ this.elements.splice(index, 1);
+ }
+ // Remove the anchor from the DOM.
+ elements[i].removeChild(domAnchor);
+ }
+ }
+ return this;
+ };
+
+ /**
+ * Removes all anchorjs links. Mostly used for tests.
+ */
+ this.removeAll = function() {
+ this.remove(this.elements);
+ };
+
+ /**
+ * Urlify - Refine text so it makes a good ID.
+ *
+ * To do this, we remove apostrophes, replace nonsafe characters with
hyphens,
+ * remove extra hyphens, truncate, trim hyphens, and make lowercase.
+ *
+ * @param {String} text - Any text. Usually pulled from the webpage element
we are linking to.
+ * @return {String} - hyphen-delimited text for use in IDs and URLs.
+ */
+ this.urlify = function(text) {
+ // Regex for finding the nonsafe URL characters (many need escaping): &
+$,:;=?@"#{}|^~[`%!']./()*\
+ var nonsafeChars = /[& +$,:;=?@"#{}|^~[`%!'\]\.\/\(\)\*\\]/g,
+ urlText;
+
+ // The reason we include this _applyRemainingDefaultOptions is so urlify
can be called independently,
+ // even after setting options. This can be useful for tests or other
applications.
+ if (!this.options.truncate) {
+ _applyRemainingDefaultOptions(this.options);
+ }
+
+ // Note: we trim hyphens after truncating because truncating can cause
dangling hyphens.
+ // Example string: // " ⚡⚡ Don't forget:
URL fragments should be i18n-friendly, hyphenated, short, and clean."
+ urlText = text.trim() // "⚡⚡ Don't forget:
URL fragments should be i18n-friendly, hyphenated, short, and clean."
+ .replace(/\'/gi, '') // "⚡⚡ Dont forget:
URL fragments should be i18n-friendly, hyphenated, short, and clean."
+ .replace(nonsafeChars, '-') //
"⚡⚡-Dont-forget--URL-fragments-should-be-i18n-friendly--hyphenated--short--and-clean-"
+ .replace(/-{2,}/g, '-') //
"⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-short-and-clean-"
+ .substring(0, this.options.truncate) //
"⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-"
+ .replace(/^-+|-+$/gm, '') //
"⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated"
+ .toLowerCase(); //
"⚡⚡-dont-forget-url-fragments-should-be-i18n-friendly-hyphenated"
+
+ return urlText;
+ };
+
+ /**
+ * Determines if this element already has an AnchorJS link on it.
+ * Uses this technique: http://stackoverflow.com/a/5898748/1154642
+ * @param {HTMLElemnt} el - a DOM node
+ * @return {Boolean} true/false
+ */
+ this.hasAnchorJSLink = function(el) {
+ var hasLeftAnchor = (' ' + el.firstChild.className + ' ').indexOf('
anchorjs-link ') > -1,
+ hasRightAnchor = (' ' + el.lastChild.className + ' ').indexOf('
anchorjs-link ') > -1;
+
+ return hasLeftAnchor || hasRightAnchor;
+ };
+
+ /**
+ * Turns a selector, nodeList, or array of elements into an array of
elements (so we can use array methods).
+ * It also throws errors on any other inputs. Used to handle inputs to .add
and .remove.
+ * @param {String|Array|Nodelist} input - A CSS selector string targeting
elements with anchor links,
+ * OR a nodeList / array
containing the DOM elements.
+ * @return {Array} - An array containing the elements we want.
+ */
+ function _getElements(input) {
+ var elements;
+ if (typeof input === 'string' || input instanceof String) {
+ // See https://davidwalsh.name/nodelist-array for the technique
transforming nodeList -> Array.
+ elements = [].slice.call(document.querySelectorAll(input));
+ // I checked the 'input instanceof NodeList' test in IE9 and modern
browsers and it worked for me.
+ } else if (Array.isArray(input) || input instanceof NodeList) {
+ elements = [].slice.call(input);
+ } else {
+ throw new Error('The selector provided to AnchorJS was invalid.');
+ }
+ return elements;
+ }
+
+ /**
+ * _addBaselineStyles
+ * Adds baseline styles to the page, used by all AnchorJS links irregardless
of configuration.
+ */
+ function _addBaselineStyles() {
+ // We don't want to add global baseline styles if they've been added
before.
+ if (document.head.querySelector('style.anchorjs') !== null) {
+ return;
+ }
+
+ var style = document.createElement('style'),
+ linkRule =
+ ' .anchorjs-link {' +
+ ' opacity: 0;' +
+ ' text-decoration: none;' +
+ ' -webkit-font-smoothing: antialiased;' +
+ ' -moz-osx-font-smoothing: grayscale;' +
+ ' }',
+ hoverRule =
+ ' *:hover > .anchorjs-link,' +
+ ' .anchorjs-link:focus {' +
+ ' opacity: 1;' +
+ ' }',
+ anchorjsLinkFontFace =
+ ' @font-face {' +
+ ' font-family: "anchorjs-icons";' +
+ ' font-style: normal;' +
+ ' font-weight: normal;' + // Icon from icomoon; 10px
wide & 10px tall; 2 empty below & 4 above
+ ' src:
url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOA
[...]
+ ' }',
+ pseudoElContent =
+ ' [data-anchorjs-icon]::after {' +
+ ' content: attr(data-anchorjs-icon);' +
+ ' }',
+ firstStyleEl;
+
+ style.className = 'anchorjs';
+ style.appendChild(document.createTextNode('')); // Necessary for Webkit.
+
+ // We place it in the head with the other style tags, if possible, so as to
+ // not look out of place. We insert before the others so these styles can
be
+ // overridden if necessary.
+ firstStyleEl = document.head.querySelector('[rel="stylesheet"], style');
+ if (firstStyleEl === undefined) {
+ document.head.appendChild(style);
+ } else {
+ document.head.insertBefore(style, firstStyleEl);
+ }
+
+ style.sheet.insertRule(linkRule, style.sheet.cssRules.length);
+ style.sheet.insertRule(hoverRule, style.sheet.cssRules.length);
+ style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length);
+ style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length);
+ }
+}
+
+var anchors = new AnchorJS();
diff --git a/js/bootstrap.min.js b/js/bootstrap.min.js
new file mode 100644
index 000000000..e79c06513
--- /dev/null
+++ b/js/bootstrap.min.js
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under the MIT license
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires
jQuery");+function(a){"use strict";var b=a.fn.jquery.split("
")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new
Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but
lower than version 3")}(jQuery),+function(a){"use strict";function b(){var
a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"
[...]
+d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var
d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return
a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var
b=a(this);c.call(b,b.data()) [...]
\ No newline at end of file
diff --git a/js/jquery.min.js b/js/jquery.min.js
new file mode 100644
index 000000000..f3644431e
--- /dev/null
+++ b/js/jquery.min.js
@@ -0,0 +1,6 @@
+/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. |
jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof
module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw
new Error("jQuery requires a window with a document");return
b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var
c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return
new
m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b
[...]
+
+return!0}function Q(a,b,d,e){if(m.acceptData(a)){var
f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void
0!==d||"string"!=typeof b)return
k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof
b||"function"==typeof
b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void
0!==d&&(g[m.camelCase(b)]=d),"string"==typeof
b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}fu [...]
+return new
Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var
a=Za.propHooks[this.prop];return
a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var
b,c=Za.propHooks[this.prop];return
this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,
[...]
+//# sourceMappingURL=jquery.min.map
\ No newline at end of file
diff --git a/site_tool b/site_tool
index d251b1d02..ca7c08f05 100755
--- a/site_tool
+++ b/site_tool
@@ -122,8 +122,7 @@ def proof(args):
eprint("Could not build site!")
return 1
return subprocess.call(
- [BUNDLE_PATH, "exec", 'htmlproof',
- '--verbose',
+ [BUNDLE_PATH, "exec", 'htmlproofer',
# Dont check the javadocs, old doc versions, or the configuration
# reference files which are extremely large.
'--file-ignore', '/apidocs|releases|configuration_ref|cpp-client-api/',