function getCounts(langs = []) {
    return {
        langs: langs.length,
        modelLangs: langs.filter(({ models }) => models && !!models.length).length,
        models: langs.map(({ models }) => (models ? models.length : 0)).reduce((a, b) => a + b, 0),
    }
}

function getCounts ( langs = [ ] ) { return { langs : langs . length , modelLangs : langs . filter ( ( { models } ) => models && ! ! models . length ) . length , models : langs . map ( ( { models } ) => ( models ? models . length : 0 ) ) . reduce ( ( a , b ) => a + b , 0 ) , } }

Compute the overall total counts of models and languages


function className(node, value){
    var klass = node.className || '',
        svg   = klass && klass.baseVal !== undefined

    if (value === undefined) return svg ? klass.baseVal : klass
    svg ? (klass.baseVal = value) : (node.className = value)
  }

function className ( node , value ) { var klass = node . className || '' , svg = klass && klass . baseVal !== undefined if ( value === undefined ) return svg ? klass . baseVal : klass svg ? ( klass . baseVal = value ) : ( node . className = value ) }

access className property while respecting SVGAnimatedString


function deserializeValue(value) {
    try {
      return value ?
        value == "true" ||
        ( value == "false" ? false :
          value == "null" ? null :
          +value + "" == value ? +value :
          /^[\[\{]/.test(value) ? $.parseJSON(value) :
          value )
        : value
    } catch(e) {
      return value
    }
  }

function deserializeValue ( value ) { try { return value ? value == "true" || ( value == "false" ? false : value == "null" ? null : + value + "" == value ? + value : / ^[\[\{] / . test ( value ) ? $ . parseJSON ( value ) : value ) : value } catch ( e ) { return value } }

"true"  => true "false" => false "null"  => null "42"    => 42 "42.5"  => 42.5 "08"    => "08" JSON    => parse if valid String  => self

true = > true false = > false null = > null 42 = > 42 42 . 5 = > 42 . 5 08 = > 08 JSON = > parse if valid String = > self


function getHighlightOptions(config, arg) {

  let lang = '';
  if (rLang.test(arg)) {
    arg = arg.replace(rLang, (match, _lang) => {
      lang = _lang;
      return '';
    });
  }

  let line_number = config.line_number;
  if (rLineNumber.test(arg)) {
    arg = arg.replace(rLineNumber, (match, _line_number) => {
      line_number = _line_number === 'true';
      return '';
    });
  }

  let first_line = 1;
  if (rFirstLine.test(arg)) {
    arg = arg.replace(rFirstLine, (match, _first_line) => {
      first_line = _first_line;
      return '';
    });
  }

  let mark = [];
  if (rMark.test(arg)) {
    arg = arg.replace(rMark, (match, _mark) => {
      mark = _mark.split(',').reduce(function getMarkedLines(prev, cur) {
        if (/-/.test(cur)) {
          let a = Number(cur.substr(0, cur.indexOf('-')));
          let b = Number(cur.substr(cur.indexOf('-') + 1));
          if (b < a) { // switch a & b
            const temp = a;
            a = b;
            b = temp;
          }

          for (; a <= b; a++) {
            prev.push(a);
          }

          return prev;
        }

        prev.push(Number(cur));
        return prev;
      }, []);

      return '';
    });
  }

  let caption = '';
  if (rCaptionUrlTitle.test(arg)) {
    const match = arg.match(rCaptionUrlTitle);
    caption = `<span>${match[1]}</span><a href="${match[2]}${match[3]}">${match[4]}</a>`;
  } else if (rCaptionUrl.test(arg)) {
    const match = arg.match(rCaptionUrl);
    caption = `<span>${match[1]}</span><a href="${match[2]}${match[3]}">link</a>`;
  } else if (rCaption.test(arg)) {
    const match = arg.match(rCaption);
    caption = `<span>${match[1]}</span>`;
  }

  return {
    lang,
    firstLine: first_line,
    caption,
    gutter: line_number,
    hljs: config.hljs,
    mark,
    tab: config.tab_replace,
    autoDetect: config.auto_detect
  };
}

function
getHighlightOptions
(
config
,
arg
)
{
let
lang
=
''
;
if
(
rLang
.
test
(
arg
)
)
{
arg
=
arg
.
replace
(
rLang
,
(
match
,
_lang
)
=>
{
lang
=
_lang
;
return
''
;
}
)
;
}
let
line_number
=
config
.
line_number
;
if
(
rLineNumber
.
test
(
arg
)
)
{
arg
=
arg
.
replace
(
rLineNumber
,
(
match
,
_line_number
)
=>
{
line_number
=
_line_number
===
'true'
;
return
''
;
}
)
;
}
let
first_line
=
1
;
if
(
rFirstLine
.
test
(
arg
)
)
{
arg
=
arg
.
replace
(
rFirstLine
,
(
match
,
_first_line
)
=>
{
first_line
=
_first_line
;
return
''
;
}
)
;
}
let
mark
=
[
]
;
if
(
rMark
.
test
(
arg
)
)
{
arg
=
arg
.
replace
(
rMark
,
(
match
,
_mark
)
=>
{
mark
=
_mark
.
split
(
','
)
.
reduce
(
function
getMarkedLines
(
prev
,
cur
)
{
if
(
/
/
.
test
(
cur
)
)
{
let
a
=
Number
(
cur
.
substr
(
0
,
cur
.
indexOf
(
'-'
)
)
)
;
let
b
=
Number
(
cur
.
substr
(
cur
.
indexOf
(
'-'
)
+
1
)
)
;
if
(
b
<
a
)
{
// switch a & b
const
temp
=
a
;
a
=
b
;
b
=
temp
;
}
for
(
;
a
<=
b
;
a
++
)
{
prev
.
push
(
a
)
;
}
return
prev
;
}
prev
.
push
(
Number
(
cur
)
)
;
return
prev
;
}
,
[
]
)
;
return
''
;
}
)
;
}
let
caption
=
''
;
if
(
rCaptionUrlTitle
.
test
(
arg
)
)
{
const
match
=
arg
.
match
(
rCaptionUrlTitle
)
;
caption
=
`
${
match
[
1
]
}
${
match
[
2
]
}
${
match
[
3
]
}
${
match
[
4
]
}
`
;
}
else
if
(
rCaptionUrl
.
test
(
arg
)
)
{
const
match
=
arg
.
match
(
rCaptionUrl
)
;
caption
=
`
${
match
[
1
]
}
${
match
[
2
]
}
${
match
[
3
]
}
`
;
}
else
if
(
rCaption
.
test
(
arg
)
)
{
const
match
=
arg
.
match
(
rCaption
)
;
caption
=
`
${
match
[
1
]
}
`
;
}
return
{
lang
,
firstLine
:
first_line
,
caption
,
gutter
:
line_number
,
hljs
:
config
.
hljs
,
mark
,
tab
:
config
.
tab_replace
,
autoDetect
:
config
.
auto_detect
}
;
}

Code block tag

Syntax:
{% codeblock [title] [lang:language] [url] [link text] [line_number:(true|false)] [highlight:(true|false)] [first_line:number] [mark:#,#-#] %}
code snippet
{% endcodeblock %}


function pipeStream(...args) {
  const src = args.shift();

  return new Promise((resolve, reject) => {
    let stream = src.on('error', reject);
    let target;

    while ((target = args.shift()) != null) {
      stream = stream.pipe(target).on('error', reject);
    }

    stream.on('finish', resolve);
    stream.on('end', resolve);
    stream.on('close', resolve);
  });
}

function pipeStream ( ... args ) { const src = args . shift ( ) ; return new Promise ( ( resolve , reject ) => { let stream = src . on ( 'error' , reject ) ; let target ; while ( ( target = args . shift ( ) ) != null ) { stream = stream . pipe ( target ) . on ( 'error' , reject ) ; } stream . on ( 'finish' , resolve ) ; stream . on ( 'end' , resolve ) ; stream . on ( 'close' , resolve ) ; } ) ; }


function formatNunjucksError(err, input) {
  const match = err.message.match(/Line (\d+), Column \d+/);
  if (!match) return err;
  const errLine = parseInt(match[1], 10);
  if (isNaN(errLine)) return err;

  // trim useless info from Nunjucks Error
  const splited = err.message.replace('(unknown path)', '').split('\n');

  const e = new Error();
  e.name = 'Nunjucks Error';
  e.line = errLine;
  e.location = splited[0];
  e.type = splited[1].trim();
  e.message = getContext(input.split(/\r?\n/), errLine, e.location, e.type).join('\n');
  return e;
}

Provide context for Nunjucks error
@param  {Error}    err Nunjucks error
@param  {string}   str string input for Nunjucks
@return {Error}    New error object with embedded context


function (event, context, responseStatus, physicalResourceId, responseData, reason) {
  return new Promise((resolve, reject) => {
    const https = require('https');
    const { URL } = require('url');

    var responseBody = JSON.stringify({
      Status: responseStatus,
      Reason: reason,
      PhysicalResourceId: physicalResourceId || context.logStreamName,
      StackId: event.StackId,
      RequestId: event.RequestId,
      LogicalResourceId: event.LogicalResourceId,
      Data: responseData
    });

    const parsedUrl = new URL(event.ResponseURL || defaultResponseURL);
    const options = {
      hostname: parsedUrl.hostname,
      port: 443,
      path: parsedUrl.pathname + parsedUrl.search,
      method: 'PUT',
      headers: {
        'Content-Type': '',
        'Content-Length': responseBody.length
      }
    };

    https.request(options)
      .on('error', reject)
      .on('response', res => {
        res.resume();
        if (res.statusCode >= 400) {
          reject(new Error(`Server returned error ${res.statusCode}: ${res.statusMessage}`));
        } else {
          resolve();
        }
      })
      .end(responseBody, 'utf8');
  });
}

function ( event , context , responseStatus , physicalResourceId , responseData , reason ) { return new Promise ( ( resolve , reject ) => { const https = require ( 'https' ) ; const { URL } = require ( 'url' ) ; var responseBody = JSON . stringify ( { Status : responseStatus , Reason : reason , PhysicalResourceId : physicalResourceId || context . logStreamName , StackId : event . StackId , RequestId : event . RequestId , LogicalResourceId : event . LogicalResourceId , Data : responseData } ) ; const parsedUrl = new URL ( event . ResponseURL || defaultResponseURL ) ; const options = { hostname : parsedUrl . hostname , port : 443 , path : parsedUrl . pathname + parsedUrl . search , method : 'PUT' , headers : { 'Content-Type' : '' , 'Content-Length' : responseBody . length } } ; https . request ( options ) . on ( 'error' , reject ) . on ( 'response' , res => { res . resume ( ) ; if ( res . statusCode >= 400 ) { reject ( new Error ( ` ${ res . statusCode } ${ res . statusMessage } ` ) ) ; } else { resolve ( ) ; } } ) . end ( responseBody , 'utf8' ) ; } ) ; }

Upload a CloudFormation response for a Custom Resource

@param {object} event the Lambda event payload received by the handler function
@param {object} context the Lambda context received by the handler function
@param {string} responseStatus the response status, either 'SUCCESS' or 'FAILED'
@param {string} physicalResourceId CloudFormation physical resource ID
@param {object} [responseData] arbitrary response data object
@param {string} [reason] reason for failure, if any, to convey to the user
@returns {Promise} Promise that is resolved on success, or rejected on connection error or HTTP error response


async function getAdopter(name) {
      try {
        const policyResponse = await ecr.getRepositoryPolicy({ repositoryName: name }).promise();
        const policy = JSON.parse(policyResponse.policyText);
        // Search the policy for an adopter marker
        return (policy.Statement || []).find((x) => x.Action === markerStatement.Action) || {};
      } catch (e) {
        if (e.code !== 'RepositoryPolicyNotFoundException') { throw e; }
        return {};
      }
    }


function calculateLineHeight(model, columnWidths) {
        var padding = this.internal.__cell__.padding;
        var fontSize = this.internal.__cell__.table_font_size;
        var scaleFactor = this.internal.scaleFactor;

        return Object.keys(model)
            .map(function (value) {return typeof value === 'object' ? value.text : value})
            .map(function (value) { return this.splitTextToSize(value, columnWidths[value] - padding - padding) }, this)
            .map(function (value) { return this.getLineHeightFactor() * value.length * fontSize / scaleFactor + padding + padding }, this)
            .reduce(function (pv, cv) { return Math.max(pv, cv) }, 0);
    }

function calculateLineHeight ( model , columnWidths ) { var padding = this . internal . __cell__ . padding ; var fontSize = this . internal . __cell__ . table_font_size ; var scaleFactor = this . internal . scaleFactor ; return Object . keys ( model ) . map ( function ( value ) { return typeof value === 'object' ? value . text : value } ) . map ( function ( value ) { return this . splitTextToSize ( value , columnWidths [ value ] - padding - padding ) } , this ) . map ( function ( value ) { return this . getLineHeightFactor ( ) * value . length * fontSize / scaleFactor + padding + padding } , this ) . reduce ( function ( pv , cv ) { return Math . max ( pv , cv ) } , 0 ) ; }

Calculate the height for containing the highest column

@name calculateLineHeight
@function
@param {Object[]} model is the line of data we want to calculate the height of
@param {Integer[]} columnWidths is size of each column
@returns {number} lineHeight
@private


function makeWorker(script) {
        var URL = window.URL || window.webkitURL;
        var Blob = window.Blob;
        var Worker = window.Worker;

        if (!URL || !Blob || !Worker || !script) {
            return null;
        }

        var blob = new Blob([script]);
        var worker = new Worker(URL.createObjectURL(blob));
        return worker;
    }

function makeWorker ( script ) { var URL = window . URL || window . webkitURL ; var Blob = window . Blob ; var Worker = window . Worker ; if ( ! URL || ! Blob || ! Worker || ! script ) { return null ; } var blob = new Blob ( [ script ] ) ; var worker = new Worker ( URL . createObjectURL ( blob ) ) ; return worker ; }

makeWorker is a little wrapper for generating web workers from strings


function monkeyPatch() {
  return {
    transform: (code, id) => {
      var file = id.split('/').pop()

      // Only one define call per module is allowed by requirejs so
      // we have to remove calls that other libraries make
      if (file === 'FileSaver.js') {
        code = code.replace(/define !== null\) && \(define.amd != null/g, '0')
      } else if (file === 'html2canvas.js') {
        code = code.replace(/&&\s+define.amd/g, '&& define.amd && false')
      }

      return code
    }
  }
}

Monkey patching filesaver and html2canvas


function rawjs(opts) {
  opts = opts || {}
  return {
    transform: (code, id) => {
      var variable = opts[id.split('/').pop()]
      if (!variable) return code

      var keepStr = '/*rollup-keeper-start*/window.tmp=' + variable +
        ';/*rollup-keeper-end*/'
      return code + keepStr
    },
    transformBundle: (code) => {
      for (var file in opts) {
        var r = new RegExp(opts[file] + '\\$\\d+', 'g')
        code = code.replace(r, opts[file])
      }
      var re = /\/\*rollup-keeper-start\*\/.*\/\*rollup-keeper-end\*\//g
      return code.replace(re, '')
    }
  }
}

Rollup removes local variables unless used within a module. This plugin makes sure specified local variables are preserved and kept local. This plugin wouldn't be necessary if es2015 modules would be used.

Rollup removes local variables unless used within a module . This plugin makes sure specified local variables are preserved and kept local . This plugin wouldn t be necessary if es2015 modules would be used .


function (tagName, opt) {
    var el = document.createElement(tagName);
    if (opt.className) el.className = opt.className;
    if (opt.innerHTML) {
      el.innerHTML = opt.innerHTML;
      var scripts = el.getElementsByTagName('script');
      for (var i = scripts.length; i-- > 0;) {
        scripts[i].parentNode.removeChild(scripts[i]);
      }
    }
    for (var key in opt.style) {
      el.style[key] = opt.style[key];
    }
    return el;
  }

function ( tagName , opt ) { var el = document . createElement ( tagName ) ; if ( opt . className ) el . className = opt . className ; if ( opt . innerHTML ) { el . innerHTML = opt . innerHTML ; var scripts = el . getElementsByTagName ( 'script' ) ; for ( var i = scripts . length ; i -- > 0 ; ) { scripts [ i ] . parentNode . removeChild ( scripts [ i ] ) ; } } for ( var key in opt . style ) { el . style [ key ] = opt . style [ key ] ; } return el ; }

Create an HTML element with optional className, innerHTML, and style.

@private
@ignore

Create an HTML element with optional className innerHTML and style .


function tr_init() {

			l_desc.dyn_tree = dyn_ltree;
			l_desc.stat_desc = StaticTree.static_l_desc;

			d_desc.dyn_tree = dyn_dtree;
			d_desc.stat_desc = StaticTree.static_d_desc;

			bl_desc.dyn_tree = bl_tree;
			bl_desc.stat_desc = StaticTree.static_bl_desc;

			bi_buf = 0;
			bi_valid = 0;
			last_eob_len = 8; // enough lookahead for inflate

			// Initialize the first block of the first file:
			init_block();
		}

Initialize the tree data structures for a new zlib stream.

Initialize the tree data structures for a new zlib stream .


function _tr_tally(dist, // distance of matched string
		lc // match length-MIN_MATCH or unmatched char (if dist==0)
		) {
			var out_length, in_length, dcode;
			that.pending_buf[d_buf + last_lit * 2] = (dist >>> 8) & 0xff;
			that.pending_buf[d_buf + last_lit * 2 + 1] = dist & 0xff;

			that.pending_buf[l_buf + last_lit] = lc & 0xff;
			last_lit++;

			if (dist === 0) {
				// lc is the unmatched char
				dyn_ltree[lc * 2]++;
			} else {
				matches++;
				// Here, lc is the match length - MIN_MATCH
				dist--; // dist = match distance - 1
				dyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++;
				dyn_dtree[Tree.d_code(dist) * 2]++;
			}

			if ((last_lit & 0x1fff) === 0 && level > 2) {
				// Compute an upper bound for the compressed length
				out_length = last_lit * 8;
				in_length = strstart - block_start;
				for (dcode = 0; dcode < D_CODES; dcode++) {
					out_length += dyn_dtree[dcode * 2] * (5 + Tree.extra_dbits[dcode]);
				}
				out_length >>>= 3;
				if ((matches < Math.floor(last_lit / 2)) && out_length < Math.floor(in_length / 2))
					return true;
			}

			return (last_lit === lit_bufsize - 1);
			// We avoid equality with lit_bufsize because of wraparound at 64K
			// on 16 bit machines and because stored blocks are restricted to
			// 64K-1 bytes.
		}

Save the match info and tally the frequency counts. Return true if the current block must be flushed.

Save the match info and tally the frequency counts . Return true if the current block must be flushed .


function compress_block(ltree, dtree) {
			var dist; // distance of matched string
			var lc; // match length or unmatched char (if dist === 0)
			var lx = 0; // running index in l_buf
			var code; // the code to send
			var extra; // number of extra bits to send

			if (last_lit !== 0) {
				do {
					dist = ((that.pending_buf[d_buf + lx * 2] << 8) & 0xff00) | (that.pending_buf[d_buf + lx * 2 + 1] & 0xff);
					lc = (that.pending_buf[l_buf + lx]) & 0xff;
					lx++;

					if (dist === 0) {
						send_code(lc, ltree); // send a literal byte
					} else {
						// Here, lc is the match length - MIN_MATCH
						code = Tree._length_code[lc];

						send_code(code + LITERALS + 1, ltree); // send the length
						// code
						extra = Tree.extra_lbits[code];
						if (extra !== 0) {
							lc -= Tree.base_length[code];
							send_bits(lc, extra); // send the extra length bits
						}
						dist--; // dist is now the match distance - 1
						code = Tree.d_code(dist);

						send_code(code, dtree); // send the distance code
						extra = Tree.extra_dbits[code];
						if (extra !== 0) {
							dist -= Tree.base_dist[code];
							send_bits(dist, extra); // send the extra distance bits
						}
					} // literal or match pair ?

					// Check that the overlay between pending_buf and d_buf+l_buf is
					// ok:
				} while (lx < last_lit);
			}

			send_code(END_BLOCK, ltree);
			last_eob_len = ltree[END_BLOCK * 2 + 1];
		}

Send the block data compressed using the given Huffman trees


function copy_block(buf, // the input data
		len, // its length
		header // true if block header must be written
		) {
			bi_windup(); // align on byte boundary
			last_eob_len = 8; // enough lookahead for inflate

			if (header) {
				put_short(len);
				put_short(~len);
			}

			that.pending_buf.set(window.subarray(buf, buf + len), that.pending);
			that.pending += len;
		}

function
copy_block
(
buf
,
// the input data
len
,
// its length
header
// true if block header must be written
)
{
bi_windup
(
)
;
// align on byte boundary
last_eob_len
=
8
;
// enough lookahead for inflate
if
(
header
)
{
put_short
(
len
)
;
put_short
(
~
len
)
;
}
that
.
pending_buf
.
set
(
window
.
subarray
(
buf
,
buf
+
len
)
,
that
.
pending
)
;
that
.
pending
+=
len
;
}

Copy a stored block, storing first the length and its one's complement if requested.

Copy a stored block storing first the length and its one s complement if requested .


function _tr_stored_block(buf, // input block
		stored_len, // length of input block
		eof // true if this is the last block for a file
		) {
			send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type
			copy_block(buf, stored_len, true); // with header
		}


function (style) {
        var rxRgb = /rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/;
        var rxRgba = /rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/;
        var rxTransparent = /transparent|rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*0+\s*\)/;

        var r, g, b, a;

        if (style.isCanvasGradient === true) {
            style = style.getColor();
        }

        if (!style) {
            return { r: 0, g: 0, b: 0, a: 0, style: style };
        }

        if (rxTransparent.test(style)) {
            r = 0;
            g = 0;
            b = 0;
            a = 0;
        } else {
            var matches = rxRgb.exec(style);
            if (matches !== null) {
                r = parseInt(matches[1]);
                g = parseInt(matches[2]);
                b = parseInt(matches[3]);
                a = 1;
            } else {
                matches = rxRgba.exec(style);
                if (matches !== null) {
                    r = parseInt(matches[1]);
                    g = parseInt(matches[2]);
                    b = parseInt(matches[3]);
                    a = parseFloat(matches[4]);
                } else {
                    a = 1;

                    if (typeof style === "string" && style.charAt(0) !== '#') {
                        var rgbColor = new RGBColor(style);
                        if (rgbColor.ok) {
                            style = rgbColor.toHex();
                        } else {
                            style = '#000000';
                        }
                    }

                    if (style.length === 4) {
                        r = style.substring(1, 2);
                        r += r;
                        g = style.substring(2, 3);
                        g += g;
                        b = style.substring(3, 4);
                        b += b;
                    } else {
                        r = style.substring(1, 3);
                        g = style.substring(3, 5);
                        b = style.substring(5, 7);
                    }
                    r = parseInt(r, 16);
                    g = parseInt(g, 16);
                    b = parseInt(b, 16);
                }
            }
        }
        return { r: r, g: g, b: b, a: a, style: style };
    }

helper functions
Get the decimal values of r, g, b and a

@name getRGBA
@function
@private
@ignore

helper functions Get the decimal values of r g b and a


function (y) {
        if (this.pageWrapYEnabled) {
            this.lastBreak = 0;
            var manualBreaks = 0;
            var autoBreaks = 0;
            for (var i = 0; i < this.pageBreaks.length; i++) {
                if (y >= this.pageBreaks[i]) {
                    manualBreaks++;
                    if (this.lastBreak === 0) {
                        autoBreaks++;
                    }
                    var spaceBetweenLastBreak = this.pageBreaks[i] - this.lastBreak;
                    this.lastBreak = this.pageBreaks[i];
                    var pagesSinceLastBreak = Math.floor(spaceBetweenLastBreak / this.pageWrapY);
                    autoBreaks += pagesSinceLastBreak;
                }
            }
            if (this.lastBreak === 0) {
                var pagesSinceLastBreak = Math.floor(y / this.pageWrapY) + 1;
                autoBreaks += pagesSinceLastBreak;
            }
            return autoBreaks + manualBreaks;
        } else {
            return this.pdf.internal.getCurrentPageInfo().pageNumber;
        }
    }

function ( y ) { if ( this . pageWrapYEnabled ) { this . lastBreak = 0 ; var manualBreaks = 0 ; var autoBreaks = 0 ; for ( var i = 0 ; i < this . pageBreaks . length ; i ++ ) { if ( y >= this . pageBreaks [ i ] ) { manualBreaks ++ ; if ( this . lastBreak === 0 ) { autoBreaks ++ ; } var spaceBetweenLastBreak = this . pageBreaks [ i ] - this . lastBreak ; this . lastBreak = this . pageBreaks [ i ] ; var pagesSinceLastBreak = Math . floor ( spaceBetweenLastBreak / this . pageWrapY ) ; autoBreaks += pagesSinceLastBreak ; } } if ( this . lastBreak === 0 ) { var pagesSinceLastBreak = Math . floor ( y / this . pageWrapY ) + 1 ; autoBreaks += pagesSinceLastBreak ; } return autoBreaks + manualBreaks ; } else { return this . pdf . internal . getCurrentPageInfo ( ) . pageNumber ; } }

Should only be used if pageWrapYEnabled is true

@name setPageByYPosition
@function
@private
@ignore
@returns One-based Page Number


function (ax, ay, bx, by, cx, cy, dx, dy) {
        var tobx = bx - ax;
        var toby = by - ay;
        var tocx = cx - bx;
        var tocy = cy - by;
        var todx = dx - cx;
        var tody = dy - cy;
        var precision = 40;
        var d, i, px, py, qx, qy, rx, ry, tx, ty, sx, sy, x, y, minx, miny, maxx, maxy, toqx, toqy, torx, tory, totx, toty;
        for (i = 0; i < (precision + 1); i++) {
            d = i / precision;
            px = ax + d * tobx;
            py = ay + d * toby;
            qx = bx + d * tocx;
            qy = by + d * tocy;
            rx = cx + d * todx;
            ry = cy + d * tody;
            toqx = qx - px;
            toqy = qy - py;
            torx = rx - qx;
            tory = ry - qy;

            sx = px + d * toqx;
            sy = py + d * toqy;
            tx = qx + d * torx;
            ty = qy + d * tory;
            totx = tx - sx;
            toty = ty - sy;

            x = sx + d * totx;
            y = sy + d * toty;
            if (i == 0) {
                minx = x;
                miny = y;
                maxx = x;
                maxy = y;
            } else {
                minx = Math.min(minx, x);
                miny = Math.min(miny, y);
                maxx = Math.max(maxx, x);
                maxy = Math.max(maxy, y);
            }
        }
        return new Rectangle(Math.round(minx), Math.round(miny), Math.round(maxx - minx), Math.round(maxy - miny));
    }

function ( ax , ay , bx , by , cx , cy , dx , dy ) { var tobx = bx - ax ; var toby = by - ay ; var tocx = cx - bx ; var tocy = cy - by ; var todx = dx - cx ; var tody = dy - cy ; var precision = 40 ; var d , i , px , py , qx , qy , rx , ry , tx , ty , sx , sy , x , y , minx , miny , maxx , maxy , toqx , toqy , torx , tory , totx , toty ; for ( i = 0 ; i < ( precision + 1 ) ; i ++ ) { d = i / precision ; px = ax + d * tobx ; py = ay + d * toby ; qx = bx + d * tocx ; qy = by + d * tocy ; rx = cx + d * todx ; ry = cy + d * tody ; toqx = qx - px ; toqy = qy - py ; torx = rx - qx ; tory = ry - qy ; sx = px + d * toqx ; sy = py + d * toqy ; tx = qx + d * torx ; ty = qy + d * tory ; totx = tx - sx ; toty = ty - sy ; x = sx + d * totx ; y = sy + d * toty ; if ( i == 0 ) { minx = x ; miny = y ; maxx = x ; maxy = y ; } else { minx = Math . min ( minx , x ) ; miny = Math . min ( miny , y ) ; maxx = Math . max ( maxx , x ) ; maxy = Math . max ( maxy , y ) ; } } return new Rectangle ( Math . round ( minx ) , Math . round ( miny ) , Math . round ( maxx - minx ) , Math . round ( maxy - miny ) ) ; }


function (pageInfo) {
				var pageNumber = pageInfo !== undefined ? pageInfo.pageNumber : 1;
				//set current y position to old margin
				var oldPosition = renderer.y;
				//render all child nodes of the header element
				renderer.y = renderer.pdf.internal.pageSize.getHeight() - renderer.pdf.margins_doc.bottom;
				renderer.pdf.margins_doc.bottom -= footerHeight;

				//check if we have to add page numbers
				var spans = footer.getElementsByTagName('span');
				for (var i = 0; i < spans.length; ++i) {
					//if we find some span element with class pageCounter, set the page
					if ((" " + spans[i].className + " ").replace(/[\n\t]/g, " ").indexOf(" pageCounter ") > -1) {
						spans[i].innerHTML = pageNumber;
					}
					//if we find some span element with class totalPages, set a variable which is replaced after rendering of all pages
					if ((" " + spans[i].className + " ").replace(/[\n\t]/g, " ").indexOf(" totalPages ") > -1) {
						spans[i].innerHTML = '###jsPDFVarTotalPages###';
					}
				}

				//render footer content
				DrillForContent(footer, renderer, elementHandlers);
				//set bottom margin to previous height including the footer height
				renderer.pdf.margins_doc.bottom += footerHeight;
				//important for other plugins (e.g. table) to start rendering at correct position after header
				renderer.y = oldPosition;
			}

Create function render header on every page


function getFont(fontName, fontStyle, options) {
      var key = undefined,
          fontNameLowerCase;
      options = options || {};
      fontName = fontName !== undefined ? fontName : fonts[activeFontKey].fontName;
      fontStyle = fontStyle !== undefined ? fontStyle : fonts[activeFontKey].fontStyle;
      fontNameLowerCase = fontName.toLowerCase();

      if (fontmap[fontNameLowerCase] !== undefined && fontmap[fontNameLowerCase][fontStyle] !== undefined) {
        key = fontmap[fontNameLowerCase][fontStyle];
      } else if (fontmap[fontName] !== undefined && fontmap[fontName][fontStyle] !== undefined) {
        key = fontmap[fontName][fontStyle];
      } else {
        if (options.disableWarning === false) {
          console.warn("Unable to look up font label for font '" + fontName + "', '" + fontStyle + "'. Refer to getFontList() for available fonts.");
        }
      }

      if (!key && !options.noFallback) {
        key = fontmap['times'][fontStyle];

        if (key == null) {
          key = fontmap['times']['normal'];
        }
      }

      return key;
    }

Returns a document-specific font key - a label assigned to a
font name + font type combination at the time the font was added
to the font inventory.

Font key is used as label for the desired font for a block of text
to be added to the PDF document stream.
@private
@function
@param fontName {string} can be undefined on "falthy" to indicate "use current"
@param fontStyle {string} can be undefined on "falthy" to indicate "use current"
@returns {string} Font key.
@ignore

Returns a document - specific font key - a label assigned to a font name + font type combination at the time the font was added to the font inventory .


function calculateFontSpace(text, formObject, fontSize) {
    var font = scope.internal.getFont(formObject.fontName, formObject.fontStyle);
    var width = scope.getStringUnitWidth(text, {
      font: font,
      fontSize: parseFloat(fontSize),
      charSpace: 0
    }) * parseFloat(fontSize);
    var height = scope.getStringUnitWidth("3", {
      font: font,
      fontSize: parseFloat(fontSize),
      charSpace: 0
    }) * parseFloat(fontSize) * 1.5;
    return {
      height: height,
      width: width
    };
  }

function calculateFontSpace ( text , formObject , fontSize ) { var font = scope . internal . getFont ( formObject . fontName , formObject . fontStyle ) ; var width = scope . getStringUnitWidth ( text , { font : font , fontSize : parseFloat ( fontSize ) , charSpace : 0 } ) * parseFloat ( fontSize ) ; var height = scope . getStringUnitWidth ( "3" , { font : font , fontSize : parseFloat ( fontSize ) , charSpace : 0 } ) * parseFloat ( fontSize ) * 1.5 ; return { height : height , width : width } ; }

Small workaround for calculating the TextMetric approximately.

@param text
@param fontsize
@returns {TextMetrics} (Has Height and Width)

Small workaround for calculating the TextMetric approximately .


function YesPushDown(formObject) {
        var xobj = createFormXObject(formObject);
        var stream = [];
        var fontKey = scope.internal.getFont(formObject.fontName, formObject.fontStyle).id;

        var encodedColor = scope.__private__.encodeColorString(formObject.color);

        var calcRes = calculateX(formObject, formObject.caption);
        stream.push("0.749023 g");
        stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re");
        stream.push("f");
        stream.push("BMC");
        stream.push("q");
        stream.push("0 0 1 rg");
        stream.push("/" + fontKey + " " + f2(calcRes.fontSize) + " Tf " + encodedColor);
        stream.push("BT");
        stream.push(calcRes.text);
        stream.push("ET");
        stream.push("Q");
        stream.push("EMC");
        xobj.stream = stream.join("\n");
        return xobj;
      }

function
YesPushDown
(
formObject
)
{
var
xobj
=
createFormXObject
(
formObject
)
;
var
stream
=
[
]
;
var
fontKey
=
scope
.
internal
.
getFont
(
formObject
.
fontName
,
formObject
.
fontStyle
)
.
id
;
var
encodedColor
=
scope
.
__private__
.
encodeColorString
(
formObject
.
color
)
;
var
calcRes
=
calculateX
(
formObject
,
formObject
.
caption
)
;
stream
.
push
(
"0.749023 g"
)
;
stream
.
push
(
"0 0 "
+
f2
(
AcroFormAppearance
.
internal
.
getWidth
(
formObject
)
)
+
" "
+
f2
(
AcroFormAppearance
.
internal
.
getHeight
(
formObject
)
)
+
" re"
)
;
stream
.
push
(
"f"
)
;
stream
.
push
(
"BMC"
)
;
stream
.
push
(
"q"
)
;
stream
.
push
(
"0 0 1 rg"
)
;
stream
.
push
(
"/"
+
fontKey
+
" "
+
f2
(
calcRes
.
fontSize
)
+
" Tf "
+
encodedColor
)
;
stream
.
push
(
"BT"
)
;
stream
.
push
(
calcRes
.
text
)
;
stream
.
push
(
"ET"
)
;
stream
.
push
(
"Q"
)
;
stream
.
push
(
"EMC"
)
;
xobj
.
stream
=
stream
.
join
(
"\n"
)
;
return
xobj
;
}

Returns the standard On Appearance for a CheckBox

@returns {AcroFormXObject}


function OffPushDown(formObject) {
        var xobj = createFormXObject(formObject);
        var stream = [];
        stream.push("0.749023 g");
        stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re");
        stream.push("f");
        xobj.stream = stream.join("\n");
        return xobj;
      }

function
OffPushDown
(
formObject
)
{
var
xobj
=
createFormXObject
(
formObject
)
;
var
stream
=
[
]
;
stream
.
push
(
"0.749023 g"
)
;
stream
.
push
(
"0 0 "
+
f2
(
AcroFormAppearance
.
internal
.
getWidth
(
formObject
)
)
+
" "
+
f2
(
AcroFormAppearance
.
internal
.
getHeight
(
formObject
)
)
+
" re"
)
;
stream
.
push
(
"f"
)
;
xobj
.
stream
=
stream
.
join
(
"\n"
)
;
return
xobj
;
}

Returns the standard Off Appearance for a CheckBox

@returns {AcroFormXObject}


function createDefaultAppearanceStream(formObject) {
      // Set Helvetica to Standard Font (size: auto)
      // Color: Black
      var fontKey = scope.internal.getFont(formObject.fontName, formObject.fontStyle).id;

      var encodedColor = scope.__private__.encodeColorString(formObject.color);

      var fontSize = formObject.fontSize;
      var result = '/' + fontKey + ' ' + fontSize + ' Tf ' + encodedColor;
      return result;
    }

Returns the standard Appearance

@returns {AcroFormXObject}


function splitLongWord(word, widths_array, firstLineMaxLen, maxLen) {
    var answer = []; // 1st, chop off the piece that can fit on the hanging line.

    var i = 0,
        l = word.length,
        workingLen = 0;

    while (i !== l && workingLen + widths_array[i] < firstLineMaxLen) {
      workingLen += widths_array[i];
      i++;
    } // this is first line.

    answer.push(word.slice(0, i)); // 2nd. Split the rest into maxLen pieces.

    var startOfLine = i;
    workingLen = 0;

    while (i !== l) {
      if (workingLen + widths_array[i] > maxLen) {
        answer.push(word.slice(startOfLine, i));
        workingLen = 0;
        startOfLine = i;
      }

      workingLen += widths_array[i];
      i++;
    }

    if (startOfLine !== i) {
      answer.push(word.slice(startOfLine, i));
    }

    return answer;
  }


function splitParagraphIntoLines(text, maxlen, options) {
    // at this time works only on Western scripts, ones with space char
    // separating the words. Feel free to expand.
    if (!options) {
      options = {};
    }

    var line = [],
        lines = [line],
        line_length = options.textIndent || 0,
        separator_length = 0,
        current_word_length = 0,
        word,
        widths_array,
        words = text.split(' '),
        spaceCharWidth = getCharWidthsArray.apply(this, [' ', options])[0],
        i,
        l,
        tmp,
        lineIndent;

    if (options.lineIndent === -1) {
      lineIndent = words[0].length + 2;
    } else {
      lineIndent = options.lineIndent || 0;
    }

    if (lineIndent) {
      var pad = Array(lineIndent).join(" "),
          wrds = [];
      words.map(function (wrd) {
        wrd = wrd.split(/\s*\n/);

        if (wrd.length > 1) {
          wrds = wrds.concat(wrd.map(function (wrd, idx) {
            return (idx && wrd.length ? "\n" : "") + wrd;
          }));
        } else {
          wrds.push(wrd[0]);
        }
      });
      words = wrds;
      lineIndent = getStringUnitWidth.apply(this, [pad, options]);
    }

    for (i = 0, l = words.length; i < l; i++) {
      var force = 0;
      word = words[i];

      if (lineIndent && word[0] == "\n") {
        word = word.substr(1);
        force = 1;
      }

      widths_array = getCharWidthsArray.apply(this, [word, options]);
      current_word_length = getArraySum(widths_array);

      if (line_length + separator_length + current_word_length > maxlen || force) {
        if (current_word_length > maxlen) {
          // this happens when you have space-less long URLs for example.
          // we just chop these to size. We do NOT insert hiphens
          tmp = splitLongWord.apply(this, [word, widths_array, maxlen - (line_length + separator_length), maxlen]); // first line we add to existing line object

          line.push(tmp.shift()); // it's ok to have extra space indicator there
          // last line we make into new line object

          line = [tmp.pop()]; // lines in the middle we apped to lines object as whole lines

          while (tmp.length) {
            lines.push([tmp.shift()]); // single fragment occupies whole line
          }

          current_word_length = getArraySum(widths_array.slice(word.length - (line[0] ? line[0].length : 0)));
        } else {
          // just put it on a new line
          line = [word];
        } // now we attach new line to lines

        lines.push(line);
        line_length = current_word_length + lineIndent;
        separator_length = spaceCharWidth;
      } else {
        line.push(word);
        line_length += separator_length + current_word_length;
        separator_length = spaceCharWidth;
      }
    }

    if (lineIndent) {
      var postProcess = function postProcess(ln, idx) {
        return (idx ? pad : '') + ln.join(" ");
      };
    } else {
      var postProcess = function postProcess(ln) {
        return ln.join(" ");
      };
    }

    return lines.map(postProcess);
  }

Note, all sizing inputs for this function must be in "font measurement units" By default, for PDF, it's "point".

Note all sizing inputs for this function must be in font measurement units By default for PDF it s point .


function bi_flush() {
      if (bi_valid == 16) {
        put_short(bi_buf);
        bi_buf = 0;
        bi_valid = 0;
      } else if (bi_valid >= 8) {
        put_byte(bi_buf & 0xff);
        bi_buf >>>= 8;
        bi_valid -= 8;
      }
    }

Flush the bit buffer, keeping at most 7 bits in it.

Flush the bit buffer keeping at most 7 bits in it .


function GifWriterOutputLZWCodeStream(buf, p, min_code_size, index_stream) {
  buf[p++] = min_code_size;
  var cur_subblock = p++;  // Pointing at the length field.

  var clear_code = 1 << min_code_size;
  var code_mask = clear_code - 1;
  var eoi_code = clear_code + 1;
  var next_code = eoi_code + 1;

  var cur_code_size = min_code_size + 1;  // Number of bits per code.
  var cur_shift = 0;
  // We have at most 12-bit codes, so we should have to hold a max of 19
  // bits here (and then we would write out).
  var cur = 0;

  function emit_bytes_to_buffer(bit_block_size) {
    while (cur_shift >= bit_block_size) {
      buf[p++] = cur & 0xff;
      cur >>= 8; cur_shift -= 8;
      if (p === cur_subblock + 256) {  // Finished a subblock.
        buf[cur_subblock] = 255;
        cur_subblock = p++;
      }
    }
  }

  function emit_code(c) {
    cur |= c << cur_shift;
    cur_shift += cur_code_size;
    emit_bytes_to_buffer(8);
  }

  // I am not an expert on the topic, and I don't want to write a thesis.
  // However, it is good to outline here the basic algorithm and the few data
  // structures and optimizations here that make this implementation fast.
  // The basic idea behind LZW is to build a table of previously seen runs
  // addressed by a short id (herein called output code).  All data is
  // referenced by a code, which represents one or more values from the
  // original input stream.  All input bytes can be referenced as the same
  // value as an output code.  So if you didn't want any compression, you
  // could more or less just output the original bytes as codes (there are
  // some details to this, but it is the idea).  In order to achieve
  // compression, values greater then the input range (codes can be up to
  // 12-bit while input only 8-bit) represent a sequence of previously seen
  // inputs.  The decompressor is able to build the same mapping while
  // decoding, so there is always a shared common knowledge between the
  // encoding and decoder, which is also important for "timing" aspects like
  // how to handle variable bit width code encoding.
  //
  // One obvious but very important consequence of the table system is there
  // is always a unique id (at most 12-bits) to map the runs.  'A' might be
  // 4, then 'AA' might be 10, 'AAA' 11, 'AAAA' 12, etc.  This relationship
  // can be used for an effecient lookup strategy for the code mapping.  We
  // need to know if a run has been seen before, and be able to map that run
  // to the output code.  Since we start with known unique ids (input bytes),
  // and then from those build more unique ids (table entries), we can
  // continue this chain (almost like a linked list) to always have small
  // integer values that represent the current byte chains in the encoder.
  // This means instead of tracking the input bytes (AAAABCD) to know our
  // current state, we can track the table entry for AAAABC (it is guaranteed
  // to exist by the nature of the algorithm) and the next character D.
  // Therefor the tuple of (table_entry, byte) is guaranteed to also be
  // unique.  This allows us to create a simple lookup key for mapping input
  // sequences to codes (table indices) without having to store or search
  // any of the code sequences.  So if 'AAAA' has a table entry of 12, the
  // tuple of ('AAAA', K) for any input byte K will be unique, and can be our
  // key.  This leads to a integer value at most 20-bits, which can always
  // fit in an SMI value and be used as a fast sparse array / object key.

  // Output code for the current contents of the index buffer.
  var ib_code = index_stream[0] & code_mask;  // Load first input index.
  var code_table = { };  // Key'd on our 20-bit "tuple".

  emit_code(clear_code);  // Spec says first code should be a clear code.

  // First index already loaded, process the rest of the stream.
  for (var i = 1, il = index_stream.length; i < il; ++i) {
    var k = index_stream[i] & code_mask;
    var cur_key = ib_code << 8 | k;  // (prev, k) unique tuple.
    var cur_code = code_table[cur_key];  // buffer + k.

    // Check if we have to create a new code table entry.
    if (cur_code === undefined) {  // We don't have buffer + k.
      // Emit index buffer (without k).
      // This is an inline version of emit_code, because this is the core
      // writing routine of the compressor (and V8 cannot inline emit_code
      // because it is a closure here in a different context).  Additionally
      // we can call emit_byte_to_buffer less often, because we can have
      // 30-bits (from our 31-bit signed SMI), and we know our codes will only
      // be 12-bits, so can safely have 18-bits there without overflow.
      // emit_code(ib_code);
      cur |= ib_code << cur_shift;
      cur_shift += cur_code_size;
      while (cur_shift >= 8) {
        buf[p++] = cur & 0xff;
        cur >>= 8; cur_shift -= 8;
        if (p === cur_subblock + 256) {  // Finished a subblock.
          buf[cur_subblock] = 255;
          cur_subblock = p++;
        }
      }

      if (next_code === 4096) {  // Table full, need a clear.
        emit_code(clear_code);
        next_code = eoi_code + 1;
        cur_code_size = min_code_size + 1;
        code_table = { };
      } else {  // Table not full, insert a new entry.
        // Increase our variable bit code sizes if necessary.  This is a bit
        // tricky as it is based on "timing" between the encoding and
        // decoder.  From the encoders perspective this should happen after
        // we've already emitted the index buffer and are about to create the
        // first table entry that would overflow our current code bit size.
        if (next_code >= (1 << cur_code_size)) ++cur_code_size;
        code_table[cur_key] = next_code++;  // Insert into code table.
      }

      ib_code = k;  // Index buffer to single input k.
    } else {
      ib_code = cur_code;  // Index buffer to sequence in code table.
    }
  }

  emit_code(ib_code);  // There will still be something in the index buffer.
  emit_code(eoi_code);  // End Of Information.

  // Flush / finalize the sub-blocks stream to the buffer.
  emit_bytes_to_buffer(1);

  // Finish the sub-blocks, writing out any unfinished lengths and
  // terminating with a sub-block of length 0.  If we have already started
  // but not yet used a sub-block it can just become the terminator.
  if (cur_subblock + 1 === p) {  // Started but unused.
    buf[cur_subblock] = 0;
  } else {  // Started and used, write length and additional terminator block.
    buf[cur_subblock] = p - cur_subblock - 1;
    buf[p++] = 0;
  }
  return p;
}

Main compression routine, palette indexes -> LZW code stream. |index_stream| must have at least one entry.

Main compression routine palette indexes - > LZW code stream . |index_stream| must have at least one entry .


function mapArrayBufferViews(ary) {
    return ary.map(function(chunk) {
      if (chunk.buffer instanceof ArrayBuffer) {
        var buf = chunk.buffer;

        // if this is a subarray, make a copy so we only
        // include the subarray region from the underlying buffer
        if (chunk.byteLength !== buf.byteLength) {
          var copy = new Uint8Array(chunk.byteLength);
          copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength));
          buf = copy.buffer;
        }

        return buf;
      }

      return chunk;
    });
  }

Helper function that maps ArrayBufferViews to ArrayBuffers
Used by BlobBuilder constructor and old browsers that didn't
support it in the Blob constructor.

Helper function that maps ArrayBufferViews to ArrayBuffers Used by BlobBuilder constructor and old browsers that didn t support it in the Blob constructor .


function promptUser() {
    return inquirer.prompt([
        {
            type: "list",
            name: "env",
            message: "Where does your code run?",
            default: ["browser"],
            choices: [
                { name: "Browser", value: "browser" },
                { name: "Node", value: "node" }
            ]
        },
        {
            type: "checkbox",
            name: "images",
            message: "Which ImageTypes should be supported?",
            default: ["jpeg_support", 'bmp_support', 'gif_support', 'webp_support'],
            choices: [
                { name: "Jpeg", value: "jpeg_support" },
                { name: "Bmp", value: "bmp_support" },
                { name: "Gif", value: "gif_support" },
                { name: "WebP", value: "webp_support" }
            ]
        },
        {
            type: "checkbox",
            name: "modules",
            message: "Additional Modules",
            default: ['acroform', 'annotations', 'arabic', 'autoprint', 'context2d',
                'fileloading', 'filters', 'html', 'javascript', 'outline',
                'setlanguage', 'svg', 'total_pages', 'utf8', 'viewerpreferences',
                'xmp_metadata'
            ],
            choices: [
                { name: "Acroform", value: "acroform" },
                { name: "Annotations", value: "annotations" },
                { name: "Arabic Parser", value: "arabic" },
                { name: "Autoprint", value: "autoprint" },
                { name: "Context2d", value: "context2d" },
                { name: "File Loading", value: "fileloading" },
                { name: "Filters", value: "filters" },
                { name: "HTML", value: "html" },
                { name: "Javascript", value: "javascript" },
                { name: "Outline", value: "outline" },
                { name: "Language-Tagging", value: "setlanguage" },
                { name: "SVG", value: "svg" },
                { name: "TotalPages", value: "total_pages" },
                { name: "Unicode", value: "utf8" },
                { name: "ViewerPreferences", value: "viewerpreferences" },
                { name: "XMP Metadata", value: "xmp_metadata" }
            ]
        }
    ]).then(result => {
        console.log(generateFileList([...result.images, ...result.modules]));
    });
}

function
promptUser
(
)
{
return
inquirer
.
prompt
(
[
{
type
:
"list"
,
name
:
"env"
,
message
:
"Where does your code run?"
,
default
:
[
"browser"
]
,
choices
:
[
{
name
:
"Browser"
,
value
:
"browser"
}
,
{
name
:
"Node"
,
value
:
"node"
}
]
}
,
{
type
:
"checkbox"
,
name
:
"images"
,
message
:
"Which ImageTypes should be supported?"
,
default
:
[
"jpeg_support"
,
'bmp_support'
,
'gif_support'
,
'webp_support'
]
,
choices
:
[
{
name
:
"Jpeg"
,
value
:
"jpeg_support"
}
,
{
name
:
"Bmp"
,
value
:
"bmp_support"
}
,
{
name
:
"Gif"
,
value
:
"gif_support"
}
,
{
name
:
"WebP"
,
value
:
"webp_support"
}
]
}
,
{
type
:
"checkbox"
,
name
:
"modules"
,
message
:
"Additional Modules"
,
default
:
[
'acroform'
,
'annotations'
,
'arabic'
,
'autoprint'
,
'context2d'
,
'fileloading'
,
'filters'
,
'html'
,
'javascript'
,
'outline'
,
'setlanguage'
,
'svg'
,
'total_pages'
,
'utf8'
,
'viewerpreferences'
,
'xmp_metadata'
]
,
choices
:
[
{
name
:
"Acroform"
,
value
:
"acroform"
}
,
{
name
:
"Annotations"
,
value
:
"annotations"
}
,
{
name
:
"Arabic Parser"
,
value
:
"arabic"
}
,
{
name
:
"Autoprint"
,
value
:
"autoprint"
}
,
{
name
:
"Context2d"
,
value
:
"context2d"
}
,
{
name
:
"File Loading"
,
value
:
"fileloading"
}
,
{
name
:
"Filters"
,
value
:
"filters"
}
,
{
name
:
"HTML"
,
value
:
"html"
}
,
{
name
:
"Javascript"
,
value
:
"javascript"
}
,
{
name
:
"Outline"
,
value
:
"outline"
}
,
{
name
:
"Language-Tagging"
,
value
:
"setlanguage"
}
,
{
name
:
"SVG"
,
value
:
"svg"
}
,
{
name
:
"TotalPages"
,
value
:
"total_pages"
}
,
{
name
:
"Unicode"
,
value
:
"utf8"
}
,
{
name
:
"ViewerPreferences"
,
value
:
"viewerpreferences"
}
,
{
name
:
"XMP Metadata"
,
value
:
"xmp_metadata"
}
]
}
]
)
.
then
(
result
=>
{
console
.
log
(
generateFileList
(
[
...
result
.
images
,
...
result
.
modules
]
)
)
;
}
)
;
}

Ask use a few questions on command prompt
@returns {Promise} The promise with the result of the prompt


function (imgData) {
		var doc = new jsPDF();

		doc.addImage(imgData, 'JPEG', 10, 10, 50, 50);
		doc.addImage(imgData, 'JPEG', 70, 10, 100, 120);

		doc.save('output.pdf');

	}

function ( imgData ) { var doc = new jsPDF ( ) ; doc . addImage ( imgData , 'JPEG' , 10 , 10 , 50 , 50 ) ; doc . addImage ( imgData , 'JPEG' , 70 , 10 , 100 , 120 ) ; doc . save ( 'output.pdf' ) ; }

Since images are loaded asyncronously, we must wait to create the pdf until we actually have the image data. If we already had the jpeg image binary data loaded into a string, we create the pdf without delay.

Since images are loaded asyncronously we must wait to create the pdf until we actually have the image data . If we already had the jpeg image binary data loaded into a string we create the pdf without delay .


function parseId(url) {
    if (is.empty(url)) {
        return null;
    }

    const regex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/;
    return url.match(regex) ? RegExp.$2 : url;
}


function isSameException(ex1, ex2) {
	  if (isOnlyOneTruthy(ex1, ex2)) return false;
	  ex1 = ex1.values[0];
	  ex2 = ex2.values[0];
	  if (ex1.type !== ex2.type || ex1.value !== ex2.value) return false; // in case both stacktraces are undefined, we can't decide so default to false

	  if (isBothUndefined(ex1.stacktrace, ex2.stacktrace)) return false;
	  return isSameStacktrace(ex1.stacktrace, ex2.stacktrace);
	}

Returns true if the two input exception interfaces have the same content


function isSameStacktrace(stack1, stack2) {
	  if (isOnlyOneTruthy(stack1, stack2)) return false;
	  var frames1 = stack1.frames;
	  var frames2 = stack2.frames; // Exit early if stacktrace is malformed

	  if (frames1 === undefined || frames2 === undefined) return false; // Exit early if frame count differs

	  if (frames1.length !== frames2.length) return false; // Iterate through every frame; bail out if anything differs

	  var a, b;

	  for (var i = 0; i < frames1.length; i++) {
	    a = frames1[i];
	    b = frames2[i];
	    if (a.filename !== b.filename || a.lineno !== b.lineno || a.colno !== b.colno || a['function'] !== b['function']) return false;
	  }

	  return true;
	}

Returns true if the two input stack trace interfaces have the same content


function fill(obj, name, replacement, track) {
	  if (obj == null) return;
	  var orig = obj[name];
	  obj[name] = replacement(orig);
	  obj[name].__raven__ = true;
	  obj[name].__orig__ = orig;

	  if (track) {
	    track.push([obj, name, orig]);
	  }
	}

function fill ( obj , name , replacement , track ) { if ( obj == null ) return ; var orig = obj [ name ] ; obj [ name ] = replacement ( orig ) ; obj [ name ] . __raven__ = true ; obj [ name ] . __orig__ = orig ; if ( track ) { track . push ( [ obj , name , orig ] ) ; } }

Polyfill a method
@param obj object e.g. `document`
@param name method name present on object e.g. `addEventListener`
@param replacement replacement function
@param track {optional} record instrumentation to an array


function safeJoin(input, delimiter) {
	  if (!isArray(input)) return '';
	  var output = [];

	  for (var i = 0; i < input.length; i++) {
	    try {
	      output.push(String(input[i]));
	    } catch (e) {
	      output.push('[value cannot be serialized]');
	    }
	  }

	  return output.join(delimiter);
	}

function
safeJoin
(
input
,
delimiter
)
{
if
(
!
isArray
(
input
)
)
return
''
;
var
output
=
[
]
;
for
(
var
i
=
0
;
i
<
input
.
length
;
i
++
)
{
try
{
output
.
push
(
String
(
input
[
i
]
)
)
;
}
catch
(
e
)
{
output
.
push
(
'[value cannot be serialized]'
)
;
}
}
return
output
.
join
(
delimiter
)
;
}

Join values in array
@param input array of values to be joined together
@param delimiter string to be placed in-between values
@returns {string}


function notifyHandlers(stack, isWindowError) {
	    var exception = null;

	    if (isWindowError && !TraceKit.collectWindowErrors) {
	      return;
	    }

	    for (var i in handlers) {
	      if (handlers.hasOwnProperty(i)) {
	        try {
	          handlers[i].apply(null, [stack].concat(_slice.call(arguments, 2)));
	        } catch (inner) {
	          exception = inner;
	        }
	      }
	    }

	    if (exception) {
	      throw exception;
	    }
	  }

function notifyHandlers ( stack , isWindowError ) { var exception = null ; if ( isWindowError && ! TraceKit . collectWindowErrors ) { return ; } for ( var i in handlers ) { if ( handlers . hasOwnProperty ( i ) ) { try { handlers [ i ] . apply ( null , [ stack ] . concat ( _slice . call ( arguments , 2 ) ) ) ; } catch ( inner ) { exception = inner ; } } } if ( exception ) { throw exception ; } }

Dispatch stack information to all handlers.
@param {Object.<string, *>} stack

Dispatch stack information to all handlers .


function traceKitWindowOnError(msg, url, lineNo, colNo, ex) {
	    var stack = null; // If 'ex' is ErrorEvent, get real Error from inside

	    var exception = utils.isErrorEvent(ex) ? ex.error : ex; // If 'msg' is ErrorEvent, get real message from inside

	    var message = utils.isErrorEvent(msg) ? msg.message : msg;

	    if (lastExceptionStack) {
	      TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(lastExceptionStack, url, lineNo, message);
	      processLastException();
	    } else if (exception && utils.isError(exception)) {
	      // non-string `exception` arg; attempt to extract stack trace
	      // New chrome and blink send along a real error object
	      // Let's just report that like a normal error.
	      // See: https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror
	      stack = TraceKit.computeStackTrace(exception);
	      notifyHandlers(stack, true);
	    } else {
	      var location = {
	        url: url,
	        line: lineNo,
	        column: colNo
	      };
	      var name = undefined;
	      var groups;

	      if ({}.toString.call(message) === '[object String]') {
	        var groups = message.match(ERROR_TYPES_RE);

	        if (groups) {
	          name = groups[1];
	          message = groups[2];
	        }
	      }

	      location.func = UNKNOWN_FUNCTION;
	      stack = {
	        name: name,
	        message: message,
	        url: getLocationHref(),
	        stack: [location]
	      };
	      notifyHandlers(stack, true);
	    }

	    if (_oldOnerrorHandler) {
	      return _oldOnerrorHandler.apply(this, arguments);
	    }

	    return false;
	  }

Ensures all global unhandled exceptions are recorded.
Supported by Gecko and IE.
@param {string} msg Error message.
@param {string} url URL of script that generated the exception.
@param {(number|string)} lineNo The line number at which the error
occurred.
@param {?(number|string)} colNo The column number at which the error
occurred.
@param {?Error} ex The actual Error object.

Ensures all global unhandled exceptions are recorded . Supported by Gecko and IE .


function report(ex, rethrow) {
	    var args = _slice.call(arguments, 1);

	    if (lastExceptionStack) {
	      if (lastException === ex) {
	        return; // already caught by an inner catch block, ignore
	      } else {
	        processLastException();
	      }
	    }

	    var stack = TraceKit.computeStackTrace(ex);
	    lastExceptionStack = stack;
	    lastException = ex;
	    lastArgs = args; // If the stack trace is incomplete, wait for 2 seconds for
	    // slow slow IE to see if onerror occurs or not before reporting
	    // this exception; otherwise, we will end up with an incomplete
	    // stack trace

	    setTimeout(function () {
	      if (lastException === ex) {
	        processLastException();
	      }
	    }, stack.incomplete ? 2000 : 0);

	    if (rethrow !== false) {
	      throw ex; // re-throw to propagate to the top level (and cause window.onerror)
	    }
	  }

Reports an unhandled Error to TraceKit.
@param {Error} ex
@param {?boolean} rethrow If false, do not re-throw the exception.
Only used for window.onerror to not cause an infinite loop of
rethrowing.

Reports an unhandled Error to TraceKit .


function augmentStackTraceWithInitialElement(stackInfo, url, lineNo, message) {
	    var initial = {
	      url: url,
	      line: lineNo
	    };

	    if (initial.url && initial.line) {
	      stackInfo.incomplete = false;

	      if (!initial.func) {
	        initial.func = UNKNOWN_FUNCTION;
	      }

	      if (stackInfo.stack.length > 0) {
	        if (stackInfo.stack[0].url === initial.url) {
	          if (stackInfo.stack[0].line === initial.line) {
	            return false; // already in stack trace
	          } else if (!stackInfo.stack[0].line && stackInfo.stack[0].func === initial.func) {
	            stackInfo.stack[0].line = initial.line;
	            return false;
	          }
	        }
	      }

	      stackInfo.stack.unshift(initial);
	      stackInfo.partial = true;
	      return true;
	    } else {
	      stackInfo.incomplete = true;
	    }

	    return false;
	  }

function
augmentStackTraceWithInitialElement
(
stackInfo
,
url
,
lineNo
,
message
)
{
var
initial
=
{
url
:
url
,
line
:
lineNo
}
;
if
(
initial
.
url
&&
initial
.
line
)
{
stackInfo
.
incomplete
=
false
;
if
(
!
initial
.
func
)
{
initial
.
func
=
UNKNOWN_FUNCTION
;
}
if
(
stackInfo
.
stack
.
length
>
0
)
{
if
(
stackInfo
.
stack
[
0
]
.
url
===
initial
.
url
)
{
if
(
stackInfo
.
stack
[
0
]
.
line
===
initial
.
line
)
{
return
false
;
// already in stack trace
}
else
if
(
!
stackInfo
.
stack
[
0
]
.
line
&&
stackInfo
.
stack
[
0
]
.
func
===
initial
.
func
)
{
stackInfo
.
stack
[
0
]
.
line
=
initial
.
line
;
return
false
;
}
}
}
stackInfo
.
stack
.
unshift
(
initial
)
;
stackInfo
.
partial
=
true
;
return
true
;
}
else
{
stackInfo
.
incomplete
=
true
;
}
return
false
;
}

Adds information about the first frame to incomplete stack traces.
Safari and IE require this to get complete data on the first frame.
@param {Object.<string, *>} stackInfo Stack trace information from
one of the compute* methods.
@param {string} url The URL of the script that caused an error.
@param {(number|string)} lineNo The line number of the script that
caused an error.
@param {string=} message The error generated by the browser, which
hopefully contains the name of the object that caused the error.
@return {boolean} Whether or not the stack information was
augmented.

Adds information about the first frame to incomplete stack traces . Safari and IE require this to get complete data on the first frame .


function computeStackTrace(ex, depth) {
	    var stack = null;
	    depth = depth == null ? 0 : +depth;

	    try {
	      stack = computeStackTraceFromStackProp(ex);

	      if (stack) {
	        return stack;
	      }
	    } catch (e) {
	      if (TraceKit.debug) {
	        throw e;
	      }
	    }

	    try {
	      stack = computeStackTraceByWalkingCallerChain(ex, depth + 1);

	      if (stack) {
	        return stack;
	      }
	    } catch (e) {
	      if (TraceKit.debug) {
	        throw e;
	      }
	    }

	    return {
	      name: ex.name,
	      message: ex.message,
	      url: getLocationHref()
	    };
	  }

function computeStackTrace ( ex , depth ) { var stack = null ; depth = depth == null ? 0 : + depth ; try { stack = computeStackTraceFromStackProp ( ex ) ; if ( stack ) { return stack ; } } catch ( e ) { if ( TraceKit . debug ) { throw e ; } } try { stack = computeStackTraceByWalkingCallerChain ( ex , depth + 1 ) ; if ( stack ) { return stack ; } } catch ( e ) { if ( TraceKit . debug ) { throw e ; } } return { name : ex . name , message : ex . message , url : getLocationHref ( ) } ; }

Computes a stack trace for an exception.
@param {Error} ex
@param {(string|number)=} depth

Computes a stack trace for an exception .


function _promiseRejectionHandler(event) {
	    this._logDebug('debug', 'Raven caught unhandled promise rejection:', event);

	    this.captureException(event.reason, {
	      mechanism: {
	        type: 'onunhandledrejection',
	        handled: false
	      }
	    });
	  }

Callback used for `unhandledrejection` event

@param {PromiseRejectionEvent} event An object containing
promise: the Promise that was rejected
reason: the value with which the Promise was rejected
@return void

Callback used for unhandledrejection event


function captureException(ex, options) {
	    options = objectMerge$1({
	      trimHeadFrames: 0
	    }, options ? options : {});

	    if (isErrorEvent$1(ex) && ex.error) {
	      // If it is an ErrorEvent with `error` property, extract it to get actual Error
	      ex = ex.error;
	    } else if (isDOMError$1(ex) || isDOMException$1(ex)) {
	      // If it is a DOMError or DOMException (which are legacy APIs, but still supported in some browsers)
	      // then we just extract the name and message, as they don't provide anything else
	      // https://developer.mozilla.org/en-US/docs/Web/API/DOMError
	      // https://developer.mozilla.org/en-US/docs/Web/API/DOMException
	      var name = ex.name || (isDOMError$1(ex) ? 'DOMError' : 'DOMException');
	      var message = ex.message ? name + ': ' + ex.message : name;
	      return this.captureMessage(message, objectMerge$1(options, {
	        // neither DOMError or DOMException provide stack trace and we most likely wont get it this way as well
	        // but it's barely any overhead so we may at least try
	        stacktrace: true,
	        trimHeadFrames: options.trimHeadFrames + 1
	      }));
	    } else if (isError$1(ex)) {
	      // we have a real Error object
	      ex = ex;
	    } else if (isPlainObject$1(ex)) {
	      // If it is plain Object, serialize it manually and extract options
	      // This will allow us to group events based on top-level keys
	      // which is much better than creating new group when any key/value change
	      options = this._getCaptureExceptionOptionsFromPlainObject(options, ex);
	      ex = new Error(options.message);
	    } else {
	      // If none of previous checks were valid, then it means that
	      // it's not a DOMError/DOMException
	      // it's not a plain Object
	      // it's not a valid ErrorEvent (one with an error property)
	      // it's not an Error
	      // So bail out and capture it as a simple message:
	      return this.captureMessage(ex, objectMerge$1(options, {
	        stacktrace: true,
	        // if we fall back to captureMessage, default to attempting a new trace
	        trimHeadFrames: options.trimHeadFrames + 1
	      }));
	    } // Store the raw exception object for potential debugging and introspection

	    this._lastCapturedException = ex; // TraceKit.report will re-raise any exception passed to it,
	    // which means you have to wrap it in try/catch. Instead, we
	    // can wrap it here and only re-raise if TraceKit.report
	    // raises an exception different from the one we asked to
	    // report on.

	    try {
	      var stack = tracekit.computeStackTrace(ex);

	      this._handleStackInfo(stack, options);
	    } catch (ex1) {
	      if (ex !== ex1) {
	        throw ex1;
	      }
	    }

	    return this;
	  }

Manually capture an exception and send it over to Sentry

@param {error} ex An exception to be logged
@param {object} options A specific set of options for this error [optional]
@return {Raven}


function _breadcrumbEventHandler(evtName) {
	    var self = this;
	    return function (evt) {
	      // reset keypress timeout; e.g. triggering a 'click' after
	      // a 'keypress' will reset the keypress debounce so that a new
	      // set of keypresses can be recorded
	      self._keypressTimeout = null; // It's possible this handler might trigger multiple times for the same
	      // event (e.g. event propagation through node ancestors). Ignore if we've
	      // already captured the event.

	      if (self._lastCapturedEvent === evt) return;
	      self._lastCapturedEvent = evt; // try/catch both:
	      // - accessing evt.target (see getsentry/raven-js#838, #768)
	      // - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly
	      //   can throw an exception in some circumstances.

	      var target;

	      try {
	        target = htmlTreeAsString$1(evt.target);
	      } catch (e) {
	        target = '<unknown>';
	      }

	      self.captureBreadcrumb({
	        category: 'ui.' + evtName,
	        // e.g. ui.click, ui.input
	        message: target
	      });
	    };
	  }

Wraps addEventListener to capture UI breadcrumbs
@param evtName the event name (e.g. "click")
@returns {Function}
@private


function _captureUrlChange(from, to) {
	    var parsedLoc = parseUrl$1(this._location.href);
	    var parsedTo = parseUrl$1(to);
	    var parsedFrom = parseUrl$1(from); // because onpopstate only tells you the "new" (to) value of location.href, and
	    // not the previous (from) value, we need to track the value of the current URL
	    // state ourselves

	    this._lastHref = to; // Use only the path component of the URL if the URL matches the current
	    // document (almost all the time when using pushState)

	    if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) to = parsedTo.relative;
	    if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) from = parsedFrom.relative;
	    this.captureBreadcrumb({
	      category: 'navigation',
	      data: {
	        to: to,
	        from: from
	      }
	    });
	  }

Captures a breadcrumb of type "navigation", normalizing input URLs
@param to the originating URL
@param from the target URL
@private

Captures a breadcrumb of type navigation normalizing input URLs


function _isRepeatData(current) {
	    var last = this._lastData;
	    if (!last || current.message !== last.message || // defined for captureMessage
	    current.transaction !== last.transaction // defined for captureException/onerror
	    ) return false; // Stacktrace interface (i.e. from captureMessage)

	    if (current.stacktrace || last.stacktrace) {
	      return isSameStacktrace$1(current.stacktrace, last.stacktrace);
	    } else if (current.exception || last.exception) {
	      // Exception interface (i.e. from captureException/onerror)
	      return isSameException$1(current.exception, last.exception);
	    }

	    return true;
	  }

Returns true if the in-process data payload matches the signature
of the previously-sent data

NOTE: This has to be done at this level because TraceKit can generate
data from window.onerror WITHOUT an exception object (IE8, IE9,
other old browsers). This can take the form of an "exception"
data object with a single frame (derived from the onerror args).

Returns true if the in - process data payload matches the signature of the previously - sent data


function getDecimalPlaces(value) {
	  var match = "".concat(value).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);

	  if (!match) {
	    return 0;
	  }

	  return Math.max(0, // Number of digits right of decimal point.
	  (match[1] ? match[1].length : 0) - ( // Adjust for scientific notation.
	  match[2] ? +match[2] : 0));
	}


function round(number, step) {
	  if (step < 1) {
	    var places = getDecimalPlaces(step);
	    return parseFloat(number.toFixed(places));
	  }

	  return Math.round(number / step) * step;
	}

function round ( number , step ) { if ( step < 1 ) { var places = getDecimalPlaces ( step ) ; return parseFloat ( number . toFixed ( places ) ) ; } return Math . round ( number / step ) * step ; }


function RangeTouch(target, options) {
	    _classCallCheck(this, RangeTouch);

	    if (is.element(target)) {
	      // An Element is passed, use it directly
	      this.element = target;
	    } else if (is.string(target)) {
	      // A CSS Selector is passed, fetch it from the DOM
	      this.element = document.querySelector(target);
	    }

	    if (!is.element(this.element) || !is.empty(this.element.rangeTouch)) {
	      return;
	    }

	    this.config = Object.assign({}, defaults, options);
	    this.init();
	  }

Setup a new instance
@param {String|Element} target
@param {Object} options


function setup(target) {
	      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
	      var targets = null;

	      if (is.empty(target) || is.string(target)) {
	        targets = Array.from(document.querySelectorAll(is.string(target) ? target : 'input[type="range"]'));
	      } else if (is.element(target)) {
	        targets = [target];
	      } else if (is.nodeList(target)) {
	        targets = Array.from(target);
	      } else if (is.array(target)) {
	        targets = target.filter(is.element);
	      }

	      if (is.empty(targets)) {
	        return null;
	      }

	      var config = Object.assign({}, defaults, options);

	      if (is.string(target) && config.watch) {
	        // Create an observer instance
	        var observer = new MutationObserver(function (mutations) {
	          Array.from(mutations).forEach(function (mutation) {
	            Array.from(mutation.addedNodes).forEach(function (node) {
	              if (!is.element(node) || !matches(node, target)) {
	                return;
	              } // eslint-disable-next-line no-unused-vars

	              var range = new RangeTouch(node, config);
	            });
	          });
	        }); // Pass in the target node, as well as the observer options

	        observer.observe(document.body, {
	          childList: true,
	          subtree: true
	        });
	      }

	      return targets.map(function (t) {
	        return new RangeTouch(t, options);
	      });
	    }

Setup multiple instances
@param {String|Element|NodeList|Array} target
@param {Object} options


function toggleListener(element, event, callback) {
	  var _this = this;

	  var toggle = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
	  var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
	  var capture = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;

	  // Bail if no element, event, or callback
	  if (!element || !('addEventListener' in element) || is$1.empty(event) || !is$1.function(callback)) {
	    return;
	  } // Allow multiple events

	  var events = event.split(' '); // Build options
	  // Default to just the capture boolean for browsers with no passive listener support

	  var options = capture; // If passive events listeners are supported

	  if (supportsPassiveListeners) {
	    options = {
	      // Whether the listener can be passive (i.e. default never prevented)
	      passive: passive,
	      // Whether the listener is a capturing listener or not
	      capture: capture
	    };
	  } // If a single node is passed, bind the event listener

	  events.forEach(function (type) {
	    if (_this && _this.eventListeners && toggle) {
	      // Cache event listener
	      _this.eventListeners.push({
	        element: element,
	        type: type,
	        callback: callback,
	        options: options
	      });
	    }

	    element[toggle ? 'addEventListener' : 'removeEventListener'](type, callback, options);
	  });
	}


function on(element) {
	  var events = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
	  var callback = arguments.length > 2 ? arguments[2] : undefined;
	  var passive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
	  var capture = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
	  toggleListener.call(this, element, events, callback, true, passive, capture);
	}

function on ( element ) { var events = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : '' ; var callback = arguments . length > 2 ? arguments [ 2 ] : undefined ; var passive = arguments . length > 3 && arguments [ 3 ] !== undefined ? arguments [ 3 ] : true ; var capture = arguments . length > 4 && arguments [ 4 ] !== undefined ? arguments [ 4 ] : false ; toggleListener . call ( this , element , events , callback , true , passive , capture ) ; }


function once(element) {
	  var _this2 = this;

	  var events = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
	  var callback = arguments.length > 2 ? arguments[2] : undefined;
	  var passive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
	  var capture = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;

	  var onceCallback = function onceCallback() {
	    off(element, events, onceCallback, passive, capture);

	    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
	      args[_key] = arguments[_key];
	    }

	    callback.apply(_this2, args);
	  };

	  toggleListener.call(this, element, events, onceCallback, true, passive, capture);
	}

function once ( element ) { var _this2 = this ; var events = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : '' ; var callback = arguments . length > 2 ? arguments [ 2 ] : undefined ; var passive = arguments . length > 3 && arguments [ 3 ] !== undefined ? arguments [ 3 ] : true ; var capture = arguments . length > 4 && arguments [ 4 ] !== undefined ? arguments [ 4 ] : false ; var onceCallback = function onceCallback ( ) { off ( element , events , onceCallback , passive , capture ) ; for ( var _len = arguments . length , args = new Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) { args [ _key ] = arguments [ _key ] ; } callback . apply ( _this2 , args ) ; } ; toggleListener . call ( this , element , events , onceCallback , true , passive , capture ) ; }


function unbindListeners() {
	  if (this && this.eventListeners) {
	    this.eventListeners.forEach(function (item) {
	      var element = item.element,
	          type = item.type,
	          callback = item.callback,
	          options = item.options;
	      element.removeEventListener(type, callback, options);
	    });
	    this.eventListeners = [];
	  }
	}

function unbindListeners ( ) { if ( this && this . eventListeners ) { this . eventListeners . forEach ( function ( item ) { var element = item . element , type = item . type , callback = item . callback , options = item . options ; element . removeEventListener ( type , callback , options ) ; } ) ; this . eventListeners = [ ] ; } }


function getDeep(object, path) {
	  return path.split('.').reduce(function (obj, key) {
	    return obj && obj[key];
	  }, object);
	}

function getDeep ( object , path ) { return path . split ( '.' ) . reduce ( function ( obj , key ) { return obj && obj [ key ] ; } , object ) ; }


function extend() {
	  var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

	  for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
	    sources[_key - 1] = arguments[_key];
	  }

	  if (!sources.length) {
	    return target;
	  }

	  var source = sources.shift();

	  if (!is$1.object(source)) {
	    return target;
	  }

	  Object.keys(source).forEach(function (key) {
	    if (is$1.object(source[key])) {
	      if (!Object.keys(target).includes(key)) {
	        Object.assign(target, _defineProperty({}, key, {}));
	      }

	      extend(target[key], source[key]);
	    } else {
	      Object.assign(target, _defineProperty({}, key, source[key]));
	    }
	  });
	  return extend.apply(void 0, [target].concat(sources));
	}

function extend ( ) { var target = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : { } ; for ( var _len = arguments . length , sources = new Array ( _len > 1 ? _len - 1 : 0 ) , _key = 1 ; _key < _len ; _key ++ ) { sources [ _key - 1 ] = arguments [ _key ] ; } if ( ! sources . length ) { return target ; } var source = sources . shift ( ) ; if ( ! is$1 . object ( source ) ) { return target ; } Object . keys ( source ) . forEach ( function ( key ) { if ( is$1 . object ( source [ key ] ) ) { if ( ! Object . keys ( target ) . includes ( key ) ) { Object . assign ( target , _defineProperty ( { } , key , { } ) ) ; } extend ( target [ key ] , source [ key ] ) ; } else { Object . assign ( target , _defineProperty ( { } , key , source [ key ] ) ) ; } } ) ; return extend . apply ( void 0 , [ target ] . concat ( sources ) ) ; }

Deep extend destination object with N more objects


function createElement(type, attributes, text) {
	  // Create a new <element>
	  var element = document.createElement(type); // Set all passed attributes

	  if (is$1.object(attributes)) {
	    setAttributes(element, attributes);
	  } // Add text node

	  if (is$1.string(text)) {
	    element.innerText = text;
	  } // Return built element

	  return element;
	}

function
createElement
(
type
,
attributes
,
text
)
{
// Create a new <element>
var
element
=
document
.
createElement
(
type
)
;
// Set all passed attributes
if
(
is$1
.
object
(
attributes
)
)
{
setAttributes
(
element
,
attributes
)
;
}
// Add text node
if
(
is$1
.
string
(
text
)
)
{
element
.
innerText
=
text
;
}
// Return built element
return
element
;
}


function insertAfter(element, target) {
	  if (!is$1.element(element) || !is$1.element(target)) {
	    return;
	  }

	  target.parentNode.insertBefore(element, target.nextSibling);
	}

function insertAfter ( element , target ) { if ( ! is$1 . element ( element ) || ! is$1 . element ( target ) ) { return ; } target . parentNode . insertBefore ( element , target . nextSibling ) ; }


function insertElement(type, parent, attributes, text) {
	  if (!is$1.element(parent)) {
	    return;
	  }

	  parent.appendChild(createElement(type, attributes, text));
	}

function insertElement ( type , parent , attributes , text ) { if ( ! is$1 . element ( parent ) ) { return ; } parent . appendChild ( createElement ( type , attributes , text ) ) ; }


function emptyElement(element) {
	  if (!is$1.element(element)) {
	    return;
	  }

	  var length = element.childNodes.length;

	  while (length > 0) {
	    element.removeChild(element.lastChild);
	    length -= 1;
	  }
	}

function emptyElement ( element ) { if ( ! is$1 . element ( element ) ) { return ; } var length = element . childNodes . length ; while ( length > 0 ) { element . removeChild ( element . lastChild ) ; length -= 1 ; } }


function getAttributesFromSelector(sel, existingAttributes) {
	  // For example:
	  // '.test' to { class: 'test' }
	  // '#test' to { id: 'test' }
	  // '[data-test="test"]' to { 'data-test': 'test' }
	  if (!is$1.string(sel) || is$1.empty(sel)) {
	    return {};
	  }

	  var attributes = {};
	  var existing = extend({}, existingAttributes);
	  sel.split(',').forEach(function (s) {
	    // Remove whitespace
	    var selector = s.trim();
	    var className = selector.replace('.', '');
	    var stripped = selector.replace(/[[\]]/g, ''); // Get the parts and value

	    var parts = stripped.split('=');

	    var _parts = _slicedToArray(parts, 1),
	        key = _parts[0];

	    var value = parts.length > 1 ? parts[1].replace(/["']/g, '') : ''; // Get the first character

	    var start = selector.charAt(0);

	    switch (start) {
	      case '.':
	        // Add to existing classname
	        if (is$1.string(existing.class)) {
	          attributes.class = "".concat(existing.class, " ").concat(className);
	        } else {
	          attributes.class = className;
	        }

	        break;

	      case '#':
	        // ID selector
	        attributes.id = selector.replace('#', '');
	        break;

	      case '[':
	        // Attribute selector
	        attributes[key] = value;
	        break;

	      default:
	        break;
	    }
	  });
	  return extend(existing, attributes);
	}

Get an attribute object from a string selector


function toggleClass(element, className, force) {
	  if (is$1.nodeList(element)) {
	    return Array.from(element).map(function (e) {
	      return toggleClass(e, className, force);
	    });
	  }

	  if (is$1.element(element)) {
	    var method = 'toggle';

	    if (typeof force !== 'undefined') {
	      method = force ? 'add' : 'remove';
	    }

	    element.classList[method](className);
	    return element.classList.contains(className);
	  }

	  return false;
	}

function toggleClass ( element , className , force ) { if ( is$1 . nodeList ( element ) ) { return Array . from ( element ) . map ( function ( e ) { return toggleClass ( e , className , force ) ; } ) ; } if ( is$1 . element ( element ) ) { var method = 'toggle' ; if ( typeof force !== 'undefined' ) { method = force ? 'add' : 'remove' ; } element . classList [ method ] ( className ) ; return element . classList . contains ( className ) ; } return false ; }

Mirror Element.classList.toggle, with IE compatibility for "force" argument

Mirror Element . classList . toggle with IE compatibility for force argument


function hasClass(element, className) {
	  return is$1.element(element) && element.classList.contains(className);
	}

function hasClass ( element , className ) { return is$1 . element ( element ) && element . classList . contains ( className ) ; }


function matches$1(element, selector) {

	  function match() {
	    return Array.from(document.querySelectorAll(selector)).includes(this);
	  }

	  var matches = match;
	  return matches.call(element, selector);
	}

function matches$1 ( element , selector ) { function match ( ) { return Array . from ( document . querySelectorAll ( selector ) ) . includes ( this ) ; } var matches = match ; return matches . call ( element , selector ) ; }


function trapFocus() {
	  var element = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
	  var toggle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

	  if (!is$1.element(element)) {
	    return;
	  }

	  var focusable = getElements.call(this, 'button:not(:disabled), input:not(:disabled), [tabindex]');
	  var first = focusable[0];
	  var last = focusable[focusable.length - 1];

	  var trap = function trap(event) {
	    // Bail if not tab key or not fullscreen
	    if (event.key !== 'Tab' || event.keyCode !== 9) {
	      return;
	    } // Get the current focused element

	    var focused = document.activeElement;

	    if (focused === last && !event.shiftKey) {
	      // Move focus to first element that can be tabbed if Shift isn't used
	      first.focus();
	      event.preventDefault();
	    } else if (focused === first && event.shiftKey) {
	      // Move focus to last element that can be tabbed if Shift is used
	      last.focus();
	      event.preventDefault();
	    }
	  };

	  toggleListener.call(this, this.elements.container, 'keydown', trap, toggle, false);
	}


function setFocus() {
	  var element = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
	  var tabFocus = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

	  if (!is$1.element(element)) {
	    return;
	  } // Set regular focus

	  element.focus({
	    preventScroll: true
	  }); // If we want to mimic keyboard focus via tab

	  if (tabFocus) {
	    toggleClass(element, this.config.classNames.tabFocus);
	  }
	}


function repaint(element) {
	  setTimeout(function () {
	    try {
	      toggleHidden(element, true);
	      element.offsetHeight; // eslint-disable-line

	      toggleHidden(element, false);
	    } catch (e) {// Do nothing
	    }
	  }, 0);
	}

function
repaint
(
element
)
{
setTimeout
(
function
(
)
{
try
{
toggleHidden
(
element
,
true
)
;
element
.
offsetHeight
;
// eslint-disable-line
toggleHidden
(
element
,
false
)
;
}
catch
(
e
)
{
// Do nothing
}
}
,
0
)
;
}


function check(type, provider, playsinline) {
	    var canPlayInline = browser.isIPhone && playsinline && support.playsinline;
	    var api = support[type] || provider !== 'html5';
	    var ui = api && support.rangeInput && (type !== 'video' || !browser.isIPhone || canPlayInline);
	    return {
	      api: api,
	      ui: ui
	    };
	  }

function check ( type , provider , playsinline ) { var canPlayInline = browser . isIPhone && playsinline && support . playsinline ; var api = support [ type ] || provider !== 'html5' ; var ui = api && support . rangeInput && ( type !== 'video' || ! browser . isIPhone || canPlayInline ) ; return { api : api , ui : ui } ; }

Check for support Basic functionality vs full UI


function setAspectRatio(input) {
	  if (!this.isVideo) {
	    return {};
	  }

	  var ratio = getAspectRatio.call(this, input);

	  var _ref = is$1.array(ratio) ? ratio : [0, 0],
	      _ref2 = _slicedToArray(_ref, 2),
	      w = _ref2[0],
	      h = _ref2[1];

	  var padding = 100 / w * h;
	  this.elements.wrapper.style.paddingBottom = "".concat(padding, "%"); // For Vimeo we have an extra <div> to hide the standard controls and UI

	  if (this.isVimeo && this.supported.ui) {
	    var height = 240;
	    var offset = (height - padding) / (height / 50);
	    this.media.style.transform = "translateY(-".concat(offset, "%)");
	  } else if (this.isHTML5) {
	    this.elements.wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null);
	  }

	  return {
	    padding: padding,
	    ratio: ratio
	  };
	}

Set aspect ratio for responsive container


function getQualityOptions() {
	    // Get sizes from <source> elements
	    return html5.getSources.call(this).map(function (source) {
	      return Number(source.getAttribute('size'));
	    }).filter(Boolean);
	  }

function
getQualityOptions
(
)
{
// Get sizes from <source> elements
return
html5
.
getSources
.
call
(
this
)
.
map
(
function
(
source
)
{
return
Number
(
source
.
getAttribute
(
'size'
)
)
;
}
)
.
filter
(
Boolean
)
;
}


function closest(array, value) {
	  if (!is$1.array(array) || !array.length) {
	    return null;
	  }

	  return array.reduce(function (prev, curr) {
	    return Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev;
	  });
	}

function closest ( array , value ) { if ( ! is$1 . array ( array ) || ! array . length ) { return null ; } return array . reduce ( function ( prev , curr ) { return Math . abs ( curr - value ) < Math . abs ( prev - value ) ? curr : prev ; } ) ; }


function replaceAll() {
	  var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
	  var find = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
	  var replace = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
	  return input.replace(new RegExp(find.toString().replace(/([.*+?^=!:${}()|[\]/\\])/g, '\\$1'), 'g'), replace.toString());
	}

function replaceAll ( ) { var input = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : '' ; var find = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : '' ; var replace = arguments . length > 2 && arguments [ 2 ] !== undefined ? arguments [ 2 ] : '' ; return input . replace ( new RegExp ( find . toString ( ) . replace ( / ([.*+?^=!:${}()|[\]/\\]) / g , '\\$1' ) , 'g' ) , replace . toString ( ) ) ; }

Replace all occurances of a string in a string


function toTitleCase() {
	  var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
	  return input.toString().replace(/\w\S*/g, function (text) {
	    return text.charAt(0).toUpperCase() + text.substr(1).toLowerCase();
	  });
	}

function toTitleCase ( ) { var input = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : '' ; return input . toString ( ) . replace ( / \w\S* / g , function ( text ) { return text . charAt ( 0 ) . toUpperCase ( ) + text . substr ( 1 ) . toLowerCase ( ) ; } ) ; }


function stripHTML(source) {
	  var fragment = document.createDocumentFragment();
	  var element = document.createElement('div');
	  fragment.appendChild(element);
	  element.innerHTML = source;
	  return fragment.firstChild.innerText;
	}

function stripHTML ( source ) { var fragment = document . createDocumentFragment ( ) ; var element = document . createElement ( 'div' ) ; fragment . appendChild ( element ) ; element . innerHTML = source ; return fragment . firstChild . innerText ; }


function getHTML(element) {
	  var wrapper = document.createElement('div');
	  wrapper.appendChild(element);
	  return wrapper.innerHTML;
	}

function getHTML ( element ) { var wrapper = document . createElement ( 'div' ) ; wrapper . appendChild ( element ) ; return wrapper . innerHTML ; }

Like outerHTML, but also works for DocumentFragment

Like outerHTML but also works for DocumentFragment


function formatTime() {
	  var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
	  var displayHours = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
	  var inverted = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;

	  // Bail if the value isn't a number
	  if (!is$1.number(time)) {
	    return formatTime(null, displayHours, inverted);
	  } // Format time component to add leading zero

	  var format = function format(value) {
	    return "0".concat(value).slice(-2);
	  }; // Breakdown to hours, mins, secs

	  var hours = getHours(time);
	  var mins = getMinutes(time);
	  var secs = getSeconds(time); // Do we need to display hours?

	  if (displayHours || hours > 0) {
	    hours = "".concat(hours, ":");
	  } else {
	    hours = '';
	  } // Render

	  return "".concat(inverted && time > 0 ? '-' : '').concat(hours).concat(format(mins), ":").concat(format(secs));
	}


function getIconUrl() {
	    var url = new URL(this.config.iconUrl, window.location);
	    var cors = url.host !== window.location.host || browser.isIE && !window.svg4everybody;
	    return {
	      url: this.config.iconUrl,
	      cors: cors
	    };
	  }

function getIconUrl ( ) { var url = new URL ( this . config . iconUrl , window . location ) ; var cors = url . host !== window . location . host || browser . isIE && ! window . svg4everybody ; return { url : this . config . iconUrl , cors : cors } ; }


function findElements() {
	    try {
	      this.elements.controls = getElement.call(this, this.config.selectors.controls.wrapper); // Buttons

	      this.elements.buttons = {
	        play: getElements.call(this, this.config.selectors.buttons.play),
	        pause: getElement.call(this, this.config.selectors.buttons.pause),
	        restart: getElement.call(this, this.config.selectors.buttons.restart),
	        rewind: getElement.call(this, this.config.selectors.buttons.rewind),
	        fastForward: getElement.call(this, this.config.selectors.buttons.fastForward),
	        mute: getElement.call(this, this.config.selectors.buttons.mute),
	        pip: getElement.call(this, this.config.selectors.buttons.pip),
	        airplay: getElement.call(this, this.config.selectors.buttons.airplay),
	        settings: getElement.call(this, this.config.selectors.buttons.settings),
	        captions: getElement.call(this, this.config.selectors.buttons.captions),
	        fullscreen: getElement.call(this, this.config.selectors.buttons.fullscreen)
	      }; // Progress

	      this.elements.progress = getElement.call(this, this.config.selectors.progress); // Inputs

	      this.elements.inputs = {
	        seek: getElement.call(this, this.config.selectors.inputs.seek),
	        volume: getElement.call(this, this.config.selectors.inputs.volume)
	      }; // Display

	      this.elements.display = {
	        buffer: getElement.call(this, this.config.selectors.display.buffer),
	        currentTime: getElement.call(this, this.config.selectors.display.currentTime),
	        duration: getElement.call(this, this.config.selectors.display.duration)
	      }; // Seek tooltip

	      if (is$1.element(this.elements.progress)) {
	        this.elements.display.seekTooltip = this.elements.progress.querySelector(".".concat(this.config.classNames.tooltip));
	      }

	      return true;
	    } catch (error) {
	      // Log it
	      this.debug.warn('It looks like there is a problem with your custom controls HTML', error); // Restore native video controls

	      this.toggleNativeControls(true);
	      return false;
	    }
	  }


function createLabel(key) {
	    var attr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
	    var text = i18n.get(key, this.config);
	    var attributes = Object.assign({}, attr, {
	      class: [attr.class, this.config.classNames.hidden].filter(Boolean).join(' ')
	    });
	    return createElement('span', attributes, text);
	  }

function
createLabel
(
key
)
{
var
attr
=
arguments
.
length
>
1
&&
arguments
[
1
]
!==
undefined
arguments
[
1
]
:
{
}
;
var
text
=
i18n
.
get
(
key
,
this
.
config
)
;
var
attributes
=
Object
.
assign
(
{
}
,
attr
,
{
class
:
[
attr
.
class
,
this
.
config
.
classNames
.
hidden
]
.
filter
(
Boolean
)
.
join
(
' '
)
}
)
;
return
createElement
(
'span'
,
attributes
,
text
)
;
}


function createBadge(text) {
	    if (is$1.empty(text)) {
	      return null;
	    }

	    var badge = createElement('span', {
	      class: this.config.classNames.menu.value
	    });
	    badge.appendChild(createElement('span', {
	      class: this.config.classNames.menu.badge
	    }, text));
	    return badge;
	  }

function createBadge ( text ) { if ( is$1 . empty ( text ) ) { return null ; } var badge = createElement ( 'span' , { class : this . config . classNames . menu . value } ) ; badge . appendChild ( createElement ( 'span' , { class : this . config . classNames . menu . badge } , text ) ) ; return badge ; }


function createTime(type, attrs) {
	    var attributes = getAttributesFromSelector(this.config.selectors.display[type], attrs);
	    var container = createElement('div', extend(attributes, {
	      class: "".concat(attributes.class ? attributes.class : '', " ").concat(this.config.classNames.display.time, " ").trim(),
	      'aria-label': i18n.get(type, this.config)
	    }), '00:00'); // Reference for updates

	    this.elements.display[type] = container;
	    return container;
	  }

function
createTime
(
type
,
attrs
)
{
var
attributes
=
getAttributesFromSelector
(
this
.
config
.
selectors
.
display
[
type
]
,
attrs
)
;
var
container
=
createElement
(
'div'
,
extend
(
attributes
,
{
class
:
""
.
concat
(
attributes
.
class
attributes
.
class
:
''
,
" "
)
.
concat
(
this
.
config
.
classNames
.
display
.
time
,
" "
)
.
trim
(
)
,
'aria-label'
:
i18n
.
get
(
type
,
this
.
config
)
}
)
,
'00:00'
)
;
// Reference for updates
this
.
elements
.
display
[
type
]
=
container
;
return
container
;
}