Difference between revisions of "MediaWiki:Common.js"

From DiVersions
Jump to navigation Jump to search
(Hopefully an older version of paged.js will help with the infinitely added pages.)
 
(88 intermediate revisions by the same user not shown)
Line 206: Line 206:
 
}
 
}
  
 +
function wrap (element, maxWidth, end) {
 +
  if (maxWidth === null) {
 +
    maxWidth = 40;
 +
  }
 +
 +
  if (end === null) {
 +
    end = ' \\';
 +
  }
 +
 +
  var lines = element.textContent.split("\n"),
 +
      wrapped = [];
 +
 +
  for (var l=0; l < lines.length; l++) {
 +
    if (lines[l].length > maxWidth) {
 +
      var line = lines[l];
 +
      wrapped.push(line.substring(0, maxWidth).replace(/\s/g, '&nbsp;'));
 +
      line = line.substring(maxWidth);
 +
 +
      do {
 +
        wrapped.push((end + line.substring(0, maxWidth - end.length).trim()).replace(/\s/g, '&nbsp;'));
 +
        line = line.substring(maxWidth - end.length);
 +
      } while (line.length > 0);
 +
    }
 +
    else {
 +
      wrapped.push(lines[l].replace(/\s/g, '&nbsp;'))
 +
    }
 +
  }
 +
 +
  var codeElement = document.createElement('code');
 +
  codeElement.innerHTML = '<span class="line">' + wrapped.join('</span><span class="line">') + '</span>';
 +
  element.replaceWith(codeElement);
 +
}
 +
 +
function unWikifyReferences () {
 +
  var links = document.querySelectorAll('a');
 +
 +
  for (var i = 0; i < links.length; i++) {
 +
    var a = links[i];
 +
 +
    if (a.href.includes('#cite_note')) {
 +
      var content = a.textContent;
 +
 +
      if (content.startsWith('[') && content.endsWith(']')) {
 +
        a.textContent = content.substring(1, content.length - 1);
 +
      }
 +
    }
 +
  }
 +
}
 +
 +
(function () {
 +
  var links = document.querySelectorAll('a');
 +
 +
  for (var i = 0; i < links.length; i++) {
 +
    var a = links[i];
 +
 +
    if (a.parentElement.tagName == 'B' && a.parentElement.parentElement.parentElement.classList.contains('project-metadata')) {
 +
      a.textContent = a.textContent.replace('https://', '');
 +
    }
 +
  }
 +
})();
  
 
(function () {
 
(function () {
Line 231: Line 291:
 
     }
 
     }
 
   }
 
   }
 +
})();
 +
 +
(function() {
 +
 +
/**
 +
* Heavily of tosser (convert calc expresiion to mm): https://github.com/shyndman/tosser/
 +
*/
 +
 +
/**
 +
* The MIT License (MIT)
 +
*
 +
* Copyright (c) 2015 Scott Hyndman
 +
*
 +
* Permission is hereby granted, free of charge, to any person obtaining a copy
 +
* of this software and associated documentation files (the "Software"), to deal
 +
* in the Software without restriction, including without limitation the rights
 +
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 +
* copies of the Software, and to permit persons to whom the Software is
 +
* furnished to do so, subject to the following conditions:
 +
*
 +
* The above copyright notice and this permission notice shall be included in
 +
* all copies or substantial portions of the Software.
 +
*
 +
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 +
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 +
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 +
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 +
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 +
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 +
* THE SOFTWARE.
 +
*/
 +
 +
'use strict';
 +
var referenceElement;
 +
var units = {
 +
      'mm': (72/25.4)*(96/72), // 25.4mm = 72pt
 +
      'cm': (72/2.54)*(96/72),
 +
      'pt': (96/72),
 +
      'in': 96,
 +
      'px': 1
 +
    },
 +
    calcPattern = /calc\s*\(/g,
 +
    unitReplacementPattern = /(\d+(?:\.\d+)?)(mm|cm|in|pt|px)/gi,
 +
    varReplacementPattern = /var\((.+?)\)/g;
 +
 +
/**
 +
* Evaluates a calc expression.
 +
*
 +
* @param {string} expression A calc expression.
 +
* @return {string} The result of the expression, in px units.
 +
*/
 +
function evaluateCalc (expression) {
 +
  expression = expression
 +
      .trim()
 +
      .replace(/^calc/, '')
 +
      .replace(unitReplacementPattern, function(m, v, unit) {
 +
        return parseFloat(v) * units[unit];
 +
      });
 +
 +
  return eval(expression);
 +
};
 +
 +
function evaluateCalcs (input) {
 +
  if (/calc\s*\(/g.test(input)) { // Test whether there is a calc( in the string
 +
    var rawChunks = input.split(calcPattern),
 +
        chunks = [rawChunks.shift()]; // Add anything untill first calc expression
 +
 +
    for (var i=0; i < rawChunks.length; i++) {
 +
      var chunk = rawChunks[i],
 +
          pos = chunk.lastIndexOf(')'),
 +
          // find last parenthesis in the string. To balance the one removed with
 +
          // the split. Anything before will be parsed / evaluated to mm's every-
 +
          // thing after will be added as a tail.
 +
          body = evaluateCalc(chunk.substr(0, pos)),
 +
          tail = (pos + 1 < chunk.length) ? chunk.substr(pos+1) : "";
 +
 +
      chunks.push(body+tail);
 +
    }
 +
 +
    return chunks.join('');
 +
  } else {
 +
    return input;
 +
  }
 +
}
 +
 +
function fixUnits (input) {
 +
  return input.replace(unitReplacementPattern, function(m, v, unit) {
 +
    return parseFloat(v) * units[unit];
 +
  });
 +
}
 +
 +
/**
 +
* Lookup declaration of given css lookupCssVariable
 +
*
 +
* https://www.broken-links.com/2014/08/28/css-variables-updating-custom-properties-javascript/
 +
*/
 +
function lookupCSSVariable (name) {
 +
    return window.getComputedStyle(referenceElement).getPropertyValue(name);
 +
}
 +
 +
function evaluateCSSVariables (input) {
 +
  while (varReplacementPattern.test(input)) {
 +
    input = input.replace(varReplacementPattern, function (m, name) { return evaluateCalcs(lookupCSSVariable(name).trim()); });
 +
  }
 +
 +
  return input;
 +
}
 +
 +
function cssValueToPx (cssValue, element) {
 +
  referenceElement = (element) ? element : document.body;
 +
  return parseFloat(fixUnits(evaluateCalcs(evaluateCSSVariables(cssValue.trim()))));
 +
}
 +
 +
window.cssValueToPx = cssValueToPx;
 
})();
 
})();
 +
  
  
Line 253: Line 428:
 
       paged = urlParameters.get('paged');
 
       paged = urlParameters.get('paged');
 
       prevent = urlParameters.get('prevent');
 
       prevent = urlParameters.get('prevent');
 +
      etherstyles = urlParameters.get('etherstyles');
 
   if (paged == 'paged' && prevent !== 'prevent') {
 
   if (paged == 'paged' && prevent !== 'prevent') {
     /* mw.loader.load('https://unpkg.com/pagedjs/dist/paged.polyfill.js'); */
+
    /*
     mw.loader.load('https://unpkg.com/pagedjs@0.1.29/dist/paged.polyfill.js');
+
    var pre = document.querySelectorAll('pre');
 +
    while (pre.length > 0) {
 +
      wrap(pre[0], 50, '                        ');
 +
      pre = document.querySelectorAll('pre');
 +
    }
 +
    */
 +
 
 +
    unWikifyReferences();
 +
    /* mw.loader.load('https://unpkg.com/pagedjs@0.1.40/dist/paged.polyfill.js'); */
 +
     /* mw.loader.load('https://unpkg.com/pagedjs@0.1.33/dist/paged.polyfill.js'); */
 +
     /* mw.loader.load('https://unpkg.com/pagedjs@0.1.28/dist/paged.polyfill.js'); */
 +
   
 +
    const pagedPreviewCSS = ":root{--color-background:whitesmoke;--color-pageBox:#666;--color-paper:white;--color-marginBox:transparent}@media screen{body{background-color:var(--color-background)}.pagedjs_pages{display:flex;width:calc(var(--pagedjs-width) * 2);flex:0;flex-wrap:wrap;margin:0 auto}.pagedjs_page{background-color:var(--color-paper);box-shadow:0 0 0 1px var(--color-pageBox);margin:0;flex-shrink:0;flex-grow:0;margin-top:10mm}.pagedjs_first_page{margin-left:var(--pagedjs-width)}.pagedjs_page:last-of-type{margin-bottom:10mm}.pagedjs_margin-bottom,.pagedjs_margin-bottom-center,.pagedjs_margin-bottom-left,.pagedjs_margin-bottom-left-corner-holder,.pagedjs_margin-bottom-right,.pagedjs_margin-bottom-right-corner-holder,.pagedjs_margin-left,.pagedjs_margin-left-bottom,.pagedjs_margin-left-middle,.pagedjs_margin-left-top,.pagedjs_margin-right,.pagedjs_margin-right-bottom,.pagedjs_margin-right-middle,.pagedjs_margin-right-top,.pagedjs_margin-top,.pagedjs_margin-top-center,.pagedjs_margin-top-left,.pagedjs_margin-top-left-corner-holder,.pagedjs_margin-top-right,.pagedjs_margin-top-right-corner-holder{box-shadow:0 0 0 1px inset var(--color-marginBox)}}";
 +
    previewStyles = document.createElement('style');
 +
    previewStyles.textContent = pagedPreviewCSS;
 +
    document.head.appendChild(previewStyles);
 +
 +
    if (etherstyles == 'etherstyles') {
 +
      window.setTimeout(function () {
 +
        window.PagedConfig={auto:false};
 +
        jQuery.getScript('https://unpkg.com/pagedjs/dist/paged.polyfill.js').then(function () {
 +
 
 +
 
 +
function snapToGrid (node) {
 +
  var lineHeight = cssValueToPx('var(--line-height)', node),
 +
      height = node.getBoundingClientRect().height,
 +
      newDesiredHeight = Math.ceil(height/lineHeight) * lineHeight,
 +
      style = window.getComputedStyle(node),
 +
      borderTop = cssValueToPx(style.borderTopWidth, node),
 +
      borderBottom = cssValueToPx(style.borderBottomWidth, node);
 +
 
 +
  node.style.height = (newDesiredHeight - (borderTop + borderBottom)) + 'px'
 +
}
  
 +
 +
var classElemFloat = 'elem-float-top';
 +
 +
////////////////////////////////////////////////////////////////
 +
 +
function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }
 +
 +
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
 +
 +
function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 +
 +
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
 +
 +
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
 +
 +
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
 +
 +
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
 +
 +
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
 +
 +
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
 +
 +
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
 +
 +
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
 +
 +
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
 +
 +
var elemFloatTop = /*#__PURE__*/function (_Paged$Handler) {
 +
  _inherits(elemFloatTop, _Paged$Handler);
 +
 +
  var _super = _createSuper(elemFloatTop);
 +
 +
  function elemFloatTop(chunker, polisher, caller) {
 +
    var _this;
 +
 +
    _classCallCheck(this, elemFloatTop);
 +
 +
    _this = _super.call(this, chunker, polisher, caller);
 +
    _this.floatPageEls = [];
 +
    _this.token;
 +
    return _this;
 +
  }
 +
 +
  _createClass(elemFloatTop, [{
 +
    key: "layoutNode",
 +
    value: function layoutNode(node) {
 +
      // If you find a float page element, move it in the array,
 +
      if (node.nodeType == 1 && node.classList.contains(classElemFloat) && node.style.display != "none") {
 +
        var clone = node.cloneNode(true);
 +
        this.floatPageEls.push(clone); // Remove the element from the flow by hiding it.
 +
 +
        node.style.display = "none";
 +
      }
 +
    }
 +
  }, {
 +
    key: "beforePageLayout",
 +
    value: function beforePageLayout(page, content, breakToken) {
 +
      // If there is an element in the floatPageEls array,
 +
      if (this.floatPageEls.length >= 1) {
 +
        // Put the first element on the page.
 +
        var inserted = page.element.querySelector(".pagedjs_page_content").insertAdjacentElement('afterbegin', this.floatPageEls[0]);
 +
        if (inserted.classList.contains('snap')) {
 +
          snapToGrid(inserted);
 +
        }
 +
        this.floatPageEls.shift();
 +
      }
 +
    }
 +
  }]);
 +
 +
  return elemFloatTop;
 +
}(Paged.Handler);
 +
 +
 +
///////////////////////////////////////////////////////////////
 +
 +
Paged.registerHandlers(elemFloatTop);
 +
 +
var links = document.querySelectorAll('a');
 +
for (var i=0;i<links.length;i++){
 +
  try {
 +
    var url = new URL(links[i].href);
 +
    if (links[i].parentNode.parentNode.classList.contains('nav')) {
 +
      continue;
 +
    }
 +
 +
    if (url.hash && url.hash != '#' && !url.hash.startsWith('#cite')) {
 +
      links[i].href = url.hash;
 +
      links[i].dataset.wordLink = true;
 +
    }
 +
  } catch (e) {
 +
    console.log(e);
 +
    console.log(links[i]);
 +
  }
 +
}
 +
 +
window.PagedPolyfill.preview();
 +
        });
 +
      }, 4000);
 +
    } else {
 +
      mw.loader.load('https://unpkg.com/pagedjs/dist/paged.polyfill.js');
 +
    }
 
   }
 
   }
 
})();
 
})();
Line 287: Line 598:
  
 
(function () {
 
(function () {
   loadEtherStyle('https://pad.constantvzw.org/p/diversions.css/export/txt', 7500);
+
   var urlParameters = new URLSearchParams(window.location.search),
 +
      etherstyles = urlParameters.get('etherstyles');
 +
  if (etherstyles == 'etherstyles') {
 +
    loadEtherStyle('https://pad.constantvzw.org/p/diversions.css/export/txt', 7500);
 +
  }
 +
})();
 +
 
 +
(function () {
 +
  var link = document.querySelector('.printfooter a');
 +
  link.textContent = link.textContent + '&paged=paged';
 
})();
 
})();

Latest revision as of 17:45, 3 December 2020

var API_URL = 'https://diversions.constantvzw.org/wiki/api.php';

/**
 * Make an api url with the given parameters
 * @param {object} parameters parameters for the url
 */
function makeApiUrl(parameters) {
  var params = new URLSearchParams();

  for (k in parameters) {
    params.append(k, parameters[k]);
  }

  return API_URL + '?' + params.toString();
}

/**
 * Fetches the given url, parses data as json
 * @param {string} url url to fetch
 */
function getJSON (url) {
  return new Promise(function (resolve, reject) {
    fetch(url, {
      method: "GET"
    }).then(function (response) {
      if (response.ok) {
        response.json().then(resolve); //.catch(reject);
      }
      else {
        reject();
      }
    });//.catch(reject);
  });
}



/**
 * Fetches a list of revisions from the wiki api
 * Returns a promise
 * Promise is revolved with a list of revions:
 * Array<Shape<
 *  comment: string
​ *  parentid: integer
​ *  revid: integer
​​ *  timestamp: string
​​ *  user: string
 * >>
 * @param {string} title Title of the lemma
 */
function getRevisions (title) {
  return new Promise(function (resolve, reject) {
    getJSON(makeApiUrl({
      action: 'query',
      prop: 'revisions',
      rvslots: '*',
      rvprop: ['timestamp', 'user', 'comment', 'ids'].join('|'),
      rvlimit: 500,
      format: 'json',
      'titles': title
    })).then(function (data) {
      try {
        var pages = data['query']['pages'],
            keys = Object.keys(pages),
            page = pages[keys[0]],
            revisions = page['revisions'];

        resolve(revisions);
      }
      catch(e) {
        reject(e);
      }
    });
  });
}

/**
 * Fetches a parsed revision from the api
 * Returns a promise
 * Promise is resolved with a dictionary containing the text
 * and display title of the lemma.
 * @param {int} revid Id of the revision 
 */
function getRevision (revid) {
  return new Promise(function (resolve, reject) {
    getJSON(makeApiUrl({
      action: 'parse',
      oldid: revid,
      format: 'json'
    })).then(function (data) {
      try {
        var title = data['parse']['displaytitle'],
            text = Object.values(data['parse']['text'])[0];
        resolve({ title: title, html: text });
      } catch (e) {
        reject(e);
      }
    });
  });
}

function makeTimelineEntry (revision) {

  var entry = document.createElement('section');
  entry.classList.add('timeline--entry');
  entry.dataset.revid = revision.revid;
  
  var entryData = document.createElement('section');
  entryData.classList.add('timeline--entry--data');

  var user = document.createElement('span');
  user.classList.add('timeline--user');
  user.append(document.createTextNode(revision.user));

  var timestamp = document.createElement('span');
  timestamp.classList.add('timeline--timestamp');
  timestamp.append(document.createTextNode(revision.timestamp));

  var comment = document.createElement('span');
  comment.classList.add('timeline--comment');
  comment.append(document.createTextNode(revision.comment));

  entryData.append(user, timestamp, comment);
  entry.append(entryData);

  entry.addEventListener('click', function () {
    showRevision(revision.revid);
  })

  return entry;
}

function makeRevision (revid) {
  var revision = document.createElement('section');
  revision.classList.add('revisions--revision', 'mw-body-content');
  revision.dataset.revid = revid;
  return revision;
}

// Maybe rename?
function makeRevisionStubs (revisions) {
  var container = document.getElementById('content');
  // container.classList.add('revisions');

  for (var i = 1; i < revisions.length; i++) {
    container.append(makeRevision(revisions[i].revid));
  }
}

function makeTimeline (revisions) {
  var timeline = document.createElement('section');
  timeline.classList.add('timeline');
  
  for (var i=0; i < revisions.length; i++) {
    if (i==0) {
      revisions[i].revid = 'current';
    }
    timeline.appendChild(makeTimelineEntry(revisions[i]));
  }

  return timeline;
}

function showRevision (revid) {
  var node = document.querySelector('.revisions--revision[data-revid="'+ revid + '"]'),
      current = document.querySelector('.timeline--entry[data-revid="'+ revid + '"]'),
      previous = document.querySelector('.timeline--entry.active');
  if (previous) {
    previous.classList.remove('active');
  }

  current.classList.add('active');

  node.scrollIntoView();
  if (! node.dataset.loaded) {
    node.dataset.loading = true;
    getRevision(revid).then(function (revision) {
      delete node.dataset.loading;
      node.dataset.loaded = true;
      node.innerHTML = revision.html;
      showRevision(revid);
    });
  }
}



/**
 * Transforms the content content div into the container for the revisions.
 */
function restructurePage () {
  var contentContainer = document.getElementById('content'),
      panel = makeRevision('current');

  panel.dataset.loaded = true;

  while(contentContainer.firstChild) {
    if (contentContainer.firstChild.classList) {
      contentContainer.firstChild.classList.remove('mw-body');
    }
    panel.appendChild(contentContainer.firstChild);
  }

  contentContainer.classList.add('revisions');
  contentContainer.appendChild(panel);
}

function wrap (element, maxWidth, end) {
  if (maxWidth === null) {
    maxWidth = 40;
  }

  if (end === null) {
    end = ' \\';
  }

  var lines = element.textContent.split("\n"),
      wrapped = [];

  for (var l=0; l < lines.length; l++) {
    if (lines[l].length > maxWidth) {
      var line = lines[l];
      wrapped.push(line.substring(0, maxWidth).replace(/\s/g, '&nbsp;'));
      line = line.substring(maxWidth);

      do {
        wrapped.push((end + line.substring(0, maxWidth - end.length).trim()).replace(/\s/g, '&nbsp;'));
        line = line.substring(maxWidth - end.length);
      } while (line.length > 0);
    }
    else {
      wrapped.push(lines[l].replace(/\s/g, '&nbsp;'))
    }
  }

  var codeElement = document.createElement('code');
  codeElement.innerHTML = '<span class="line">' + wrapped.join('</span><span class="line">') + '</span>';
  element.replaceWith(codeElement);
}

function unWikifyReferences () {
  var links = document.querySelectorAll('a');

  for (var i = 0; i < links.length; i++) {
    var a = links[i];

    if (a.href.includes('#cite_note')) {
      var content = a.textContent;

      if (content.startsWith('[') && content.endsWith(']')) {
        a.textContent = content.substring(1, content.length - 1);
      }
    }
  }
}

(function () {
  var links = document.querySelectorAll('a');

  for (var i = 0; i < links.length; i++) {
    var a = links[i];

    if (a.parentElement.tagName == 'B' && a.parentElement.parentElement.parentElement.classList.contains('project-metadata')) {
      a.textContent = a.textContent.replace('https://', '');
    }
  }
})();

(function () {
  return;
  var urlParameters = new URLSearchParams(window.location.search),
      title = urlParameters.get('title'),
      paged = urlParameters.get('paged');


  if (!paged || paged != 'paged') {
    restructurePage();

    if (title) {
      getRevisions(title).then(function (revisions) {
        var container = document.getElementById('content');
      
        container.parentElement.appendChild(makeTimeline(revisions));
      
        for (var i = 0; i < revisions.length; i++) {
          container.append(makeRevision(revisions[i].revid));
        }

        showRevision('current');
      });
    }
  }
})();

(function() {

/** 
* Heavily of tosser (convert calc expresiion to mm): https://github.com/shyndman/tosser/
*/

/**
 * The MIT License (MIT)
 * 
 * Copyright (c) 2015 Scott Hyndman
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
*/

'use strict';
var referenceElement;
var units = {
      'mm': (72/25.4)*(96/72), // 25.4mm = 72pt
      'cm': (72/2.54)*(96/72),
      'pt': (96/72),
      'in': 96,
      'px': 1 
    },
    calcPattern = /calc\s*\(/g,
    unitReplacementPattern = /(\d+(?:\.\d+)?)(mm|cm|in|pt|px)/gi,
    varReplacementPattern = /var\((.+?)\)/g;

/**
 * Evaluates a calc expression.
 *
 * @param {string} expression A calc expression.
 * @return {string} The result of the expression, in px units.
 */
function evaluateCalc (expression) {
  expression = expression
      .trim()
      .replace(/^calc/, '')
      .replace(unitReplacementPattern, function(m, v, unit) {
        return parseFloat(v) * units[unit];
      });

  return eval(expression);
};

function evaluateCalcs (input) {
  if (/calc\s*\(/g.test(input)) { // Test whether there is a calc( in the string
    var rawChunks = input.split(calcPattern),
        chunks = [rawChunks.shift()]; // Add anything untill first calc expression

    for (var i=0; i < rawChunks.length; i++) {
      var chunk = rawChunks[i],
          pos = chunk.lastIndexOf(')'),
          // find last parenthesis in the string. To balance the one removed with
          // the split. Anything before will be parsed / evaluated to mm's every-
          // thing after will be added as a tail.
          body = evaluateCalc(chunk.substr(0, pos)),
          tail = (pos + 1 < chunk.length) ? chunk.substr(pos+1) : "";

      chunks.push(body+tail);
    }

    return chunks.join('');
  } else {
    return input;
  }
}

function fixUnits (input) {
  return input.replace(unitReplacementPattern, function(m, v, unit) {
    return parseFloat(v) * units[unit];
  });
}

/**
 * Lookup declaration of given css lookupCssVariable
 * 
 * https://www.broken-links.com/2014/08/28/css-variables-updating-custom-properties-javascript/
 */
function lookupCSSVariable (name) {
    return window.getComputedStyle(referenceElement).getPropertyValue(name);
}

function evaluateCSSVariables (input) {
  while (varReplacementPattern.test(input)) {
    input = input.replace(varReplacementPattern, function (m, name) { return evaluateCalcs(lookupCSSVariable(name).trim()); });
  }

  return input;
}

function cssValueToPx (cssValue, element) {
  referenceElement = (element) ? element : document.body;
  return parseFloat(fixUnits(evaluateCalcs(evaluateCSSVariables(cssValue.trim()))));
}

window.cssValueToPx = cssValueToPx;
})();



/**
- Get revisions
- Generate the timeline
  <section>
    <section class="timeline--entry" data-revision="{data}" data-time="{time}">
      <span class="timeline--user">{ user }</span>
      <span class="timeline--timestamp">{ timestamp }</span>
      <span class="timeline--comment">{ comment }</span>
    </section>
  </section>
- Generate the panels, maybe do not render them all
- <section data-revision="{revision}"></section>

*/

(function () {
  var urlParameters = new URLSearchParams(window.location.search),
      paged = urlParameters.get('paged');
      prevent = urlParameters.get('prevent');
      etherstyles = urlParameters.get('etherstyles');
  if (paged == 'paged' && prevent !== 'prevent') {
    /*
    var pre = document.querySelectorAll('pre');
    while (pre.length > 0) {
      wrap(pre[0], 50, '                        ');
      pre = document.querySelectorAll('pre');
    }
    */

    unWikifyReferences();
    /* mw.loader.load('https://unpkg.com/pagedjs@0.1.40/dist/paged.polyfill.js'); */
    /* mw.loader.load('https://unpkg.com/pagedjs@0.1.33/dist/paged.polyfill.js'); */
    /* mw.loader.load('https://unpkg.com/pagedjs@0.1.28/dist/paged.polyfill.js'); */
    
    const pagedPreviewCSS = ":root{--color-background:whitesmoke;--color-pageBox:#666;--color-paper:white;--color-marginBox:transparent}@media screen{body{background-color:var(--color-background)}.pagedjs_pages{display:flex;width:calc(var(--pagedjs-width) * 2);flex:0;flex-wrap:wrap;margin:0 auto}.pagedjs_page{background-color:var(--color-paper);box-shadow:0 0 0 1px var(--color-pageBox);margin:0;flex-shrink:0;flex-grow:0;margin-top:10mm}.pagedjs_first_page{margin-left:var(--pagedjs-width)}.pagedjs_page:last-of-type{margin-bottom:10mm}.pagedjs_margin-bottom,.pagedjs_margin-bottom-center,.pagedjs_margin-bottom-left,.pagedjs_margin-bottom-left-corner-holder,.pagedjs_margin-bottom-right,.pagedjs_margin-bottom-right-corner-holder,.pagedjs_margin-left,.pagedjs_margin-left-bottom,.pagedjs_margin-left-middle,.pagedjs_margin-left-top,.pagedjs_margin-right,.pagedjs_margin-right-bottom,.pagedjs_margin-right-middle,.pagedjs_margin-right-top,.pagedjs_margin-top,.pagedjs_margin-top-center,.pagedjs_margin-top-left,.pagedjs_margin-top-left-corner-holder,.pagedjs_margin-top-right,.pagedjs_margin-top-right-corner-holder{box-shadow:0 0 0 1px inset var(--color-marginBox)}}";
    previewStyles = document.createElement('style');
    previewStyles.textContent = pagedPreviewCSS;
    document.head.appendChild(previewStyles);
 
    if (etherstyles == 'etherstyles') {
      window.setTimeout(function () {
        window.PagedConfig={auto:false};
        jQuery.getScript('https://unpkg.com/pagedjs/dist/paged.polyfill.js').then(function () {


function snapToGrid (node) {
  var lineHeight = cssValueToPx('var(--line-height)', node),
      height = node.getBoundingClientRect().height,
      newDesiredHeight = Math.ceil(height/lineHeight) * lineHeight,
      style = window.getComputedStyle(node),
      borderTop = cssValueToPx(style.borderTopWidth, node),
      borderBottom = cssValueToPx(style.borderBottomWidth, node);

  node.style.height = (newDesiredHeight - (borderTop + borderBottom)) + 'px'
}


var classElemFloat = 'elem-float-top';

////////////////////////////////////////////////////////////////

function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }

function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

var elemFloatTop = /*#__PURE__*/function (_Paged$Handler) {
  _inherits(elemFloatTop, _Paged$Handler);

  var _super = _createSuper(elemFloatTop);

  function elemFloatTop(chunker, polisher, caller) {
    var _this;

    _classCallCheck(this, elemFloatTop);

    _this = _super.call(this, chunker, polisher, caller);
    _this.floatPageEls = [];
    _this.token;
    return _this;
  }

  _createClass(elemFloatTop, [{
    key: "layoutNode",
    value: function layoutNode(node) {
      // If you find a float page element, move it in the array,
      if (node.nodeType == 1 && node.classList.contains(classElemFloat) && node.style.display != "none") {
        var clone = node.cloneNode(true);
        this.floatPageEls.push(clone); // Remove the element from the flow by hiding it.

        node.style.display = "none";
      }
    }
  }, {
    key: "beforePageLayout",
    value: function beforePageLayout(page, content, breakToken) {
      // If there is an element in the floatPageEls array,
      if (this.floatPageEls.length >= 1) {
        // Put the first element on the page.
        var inserted = page.element.querySelector(".pagedjs_page_content").insertAdjacentElement('afterbegin', this.floatPageEls[0]);
        if (inserted.classList.contains('snap')) {
          snapToGrid(inserted);
        }
        this.floatPageEls.shift();
      }
    }
  }]);

  return elemFloatTop;
}(Paged.Handler);


///////////////////////////////////////////////////////////////

Paged.registerHandlers(elemFloatTop);

var links = document.querySelectorAll('a');
for (var i=0;i<links.length;i++){
  try {
    var url = new URL(links[i].href);
    if (links[i].parentNode.parentNode.classList.contains('nav')) {
      continue;
    }

    if (url.hash && url.hash != '#' && !url.hash.startsWith('#cite')) {
      links[i].href = url.hash;
      links[i].dataset.wordLink = true;
    }
  } catch (e) {
    console.log(e);
    console.log(links[i]);
  }
}

window.PagedPolyfill.preview();
        });
      }, 4000);
    } else {
      mw.loader.load('https://unpkg.com/pagedjs/dist/paged.polyfill.js');
    }
  }
})();

function loadEtherStyle(url, interval) {
  function load(url) {
    fetch(url)
      .then(function(r) { return r.text()})
      .then(function (styles) {
        var el = document.createElement('style');
        el.appendChild(document.createTextNode(styles));
        el.setAttribute('data-type', 'etherstyle');
        document.head.appendChild(el);
        window.requestAnimationFrame(function () {
          var styles = document.querySelectorAll('[data-type="etherstyle"]');
          for (var i=0;i<(styles.length-1);i++) {
            styles[i].remove();
          }
        });
      });
  }

  load(url);
  var urlParameters = new URLSearchParams(window.location.search),
      reload = urlParameters.get('reload');
  if (reload == 'reload') {
    window.setInterval(function () { load(url); }, interval);
  }
}

(function () {
  var urlParameters = new URLSearchParams(window.location.search),
      etherstyles = urlParameters.get('etherstyles');
  if (etherstyles == 'etherstyles') {
    loadEtherStyle('https://pad.constantvzw.org/p/diversions.css/export/txt', 7500);
  }
})();

(function () {
  var link = document.querySelector('.printfooter a');
  link.textContent = link.textContent + '&paged=paged';
})();