tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

beautify-html.js (110630B)


      1 /* AUTO-GENERATED. DO NOT MODIFY. */
      2 /*
      3 
      4  The MIT License (MIT)
      5 
      6  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
      7 
      8  Permission is hereby granted, free of charge, to any person
      9  obtaining a copy of this software and associated documentation files
     10  (the "Software"), to deal in the Software without restriction,
     11  including without limitation the rights to use, copy, modify, merge,
     12  publish, distribute, sublicense, and/or sell copies of the Software,
     13  and to permit persons to whom the Software is furnished to do so,
     14  subject to the following conditions:
     15 
     16  The above copyright notice and this permission notice shall be
     17  included in all copies or substantial portions of the Software.
     18 
     19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     20  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     22  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     23  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     24  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     25  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     26  SOFTWARE.
     27 
     28 
     29 Style HTML
     30 ---------------
     31 
     32  Written by Nochum Sossonko, (nsossonko@hotmail.com)
     33 
     34  Based on code initially developed by: Einar Lielmanis, <einar@beautifier.io>
     35    https://beautifier.io/
     36 
     37  Usage:
     38    style_html(html_source);
     39 
     40    style_html(html_source, options);
     41 
     42  The options are:
     43    indent_inner_html (default false)  — indent <head> and <body> sections,
     44    indent_size (default 4)          — indentation size,
     45    indent_char (default space)      — character to indent with,
     46    wrap_line_length (default 250)            -  maximum amount of characters per line (0 = disable)
     47    brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "none"
     48            put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are.
     49    inline (defaults to inline tags) - list of tags to be considered inline tags
     50    unformatted (defaults to inline tags) - list of tags, that shouldn't be reformatted
     51    content_unformatted (defaults to ["pre", "textarea"] tags) - list of tags, whose content shouldn't be reformatted
     52    indent_scripts (default normal)  - "keep"|"separate"|"normal"
     53    preserve_newlines (default true) - whether existing line breaks before elements should be preserved
     54                                        Only works before elements, not inside tags or for text.
     55    max_preserve_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk
     56    indent_handlebars (default false) - format and indent {{#foo}} and {{/foo}}
     57    end_with_newline (false)          - end with a newline
     58    extra_liners (default [head,body,/html]) -List of tags that should have an extra newline before them.
     59 
     60    e.g.
     61 
     62    style_html(html_source, {
     63      'indent_inner_html': false,
     64      'indent_size': 2,
     65      'indent_char': ' ',
     66      'wrap_line_length': 78,
     67      'brace_style': 'expand',
     68      'preserve_newlines': true,
     69      'max_preserve_newlines': 5,
     70      'indent_handlebars': false,
     71      'extra_liners': ['/html']
     72    });
     73 */
     74 
     75 (function() {
     76 
     77 /* GENERATED_BUILD_OUTPUT */
     78 var legacy_beautify_html =
     79 /******/ (function(modules) { // webpackBootstrap
     80 /******/ 	// The module cache
     81 /******/ 	var installedModules = {};
     82 /******/
     83 /******/ 	// The require function
     84 /******/ 	function __webpack_require__(moduleId) {
     85 /******/
     86 /******/ 		// Check if module is in cache
     87 /******/ 		if(installedModules[moduleId]) {
     88 /******/ 			return installedModules[moduleId].exports;
     89 /******/ 		}
     90 /******/ 		// Create a new module (and put it into the cache)
     91 /******/ 		var module = installedModules[moduleId] = {
     92 /******/ 			i: moduleId,
     93 /******/ 			l: false,
     94 /******/ 			exports: {}
     95 /******/ 		};
     96 /******/
     97 /******/ 		// Execute the module function
     98 /******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
     99 /******/
    100 /******/ 		// Flag the module as loaded
    101 /******/ 		module.l = true;
    102 /******/
    103 /******/ 		// Return the exports of the module
    104 /******/ 		return module.exports;
    105 /******/ 	}
    106 /******/
    107 /******/
    108 /******/ 	// expose the modules object (__webpack_modules__)
    109 /******/ 	__webpack_require__.m = modules;
    110 /******/
    111 /******/ 	// expose the module cache
    112 /******/ 	__webpack_require__.c = installedModules;
    113 /******/
    114 /******/ 	// define getter function for harmony exports
    115 /******/ 	__webpack_require__.d = function(exports, name, getter) {
    116 /******/ 		if(!__webpack_require__.o(exports, name)) {
    117 /******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
    118 /******/ 		}
    119 /******/ 	};
    120 /******/
    121 /******/ 	// define __esModule on exports
    122 /******/ 	__webpack_require__.r = function(exports) {
    123 /******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
    124 /******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
    125 /******/ 		}
    126 /******/ 		Object.defineProperty(exports, '__esModule', { value: true });
    127 /******/ 	};
    128 /******/
    129 /******/ 	// create a fake namespace object
    130 /******/ 	// mode & 1: value is a module id, require it
    131 /******/ 	// mode & 2: merge all properties of value into the ns
    132 /******/ 	// mode & 4: return value when already ns object
    133 /******/ 	// mode & 8|1: behave like require
    134 /******/ 	__webpack_require__.t = function(value, mode) {
    135 /******/ 		if(mode & 1) value = __webpack_require__(value);
    136 /******/ 		if(mode & 8) return value;
    137 /******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
    138 /******/ 		var ns = Object.create(null);
    139 /******/ 		__webpack_require__.r(ns);
    140 /******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
    141 /******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
    142 /******/ 		return ns;
    143 /******/ 	};
    144 /******/
    145 /******/ 	// getDefaultExport function for compatibility with non-harmony modules
    146 /******/ 	__webpack_require__.n = function(module) {
    147 /******/ 		var getter = module && module.__esModule ?
    148 /******/ 			function getDefault() { return module['default']; } :
    149 /******/ 			function getModuleExports() { return module; };
    150 /******/ 		__webpack_require__.d(getter, 'a', getter);
    151 /******/ 		return getter;
    152 /******/ 	};
    153 /******/
    154 /******/ 	// Object.prototype.hasOwnProperty.call
    155 /******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
    156 /******/
    157 /******/ 	// __webpack_public_path__
    158 /******/ 	__webpack_require__.p = "";
    159 /******/
    160 /******/
    161 /******/ 	// Load entry module and return exports
    162 /******/ 	return __webpack_require__(__webpack_require__.s = 18);
    163 /******/ })
    164 /************************************************************************/
    165 /******/ ([
    166 /* 0 */,
    167 /* 1 */,
    168 /* 2 */
    169 /***/ (function(module, exports, __webpack_require__) {
    170 
    171 "use strict";
    172 /*jshint node:true */
    173 /*
    174  The MIT License (MIT)
    175 
    176  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
    177 
    178  Permission is hereby granted, free of charge, to any person
    179  obtaining a copy of this software and associated documentation files
    180  (the "Software"), to deal in the Software without restriction,
    181  including without limitation the rights to use, copy, modify, merge,
    182  publish, distribute, sublicense, and/or sell copies of the Software,
    183  and to permit persons to whom the Software is furnished to do so,
    184  subject to the following conditions:
    185 
    186  The above copyright notice and this permission notice shall be
    187  included in all copies or substantial portions of the Software.
    188 
    189  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    190  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    191  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    192  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
    193  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
    194  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    195  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    196  SOFTWARE.
    197 */
    198 
    199 
    200 
    201 function OutputLine(parent) {
    202  this.__parent = parent;
    203  this.__character_count = 0;
    204  // use indent_count as a marker for this.__lines that have preserved indentation
    205  this.__indent_count = -1;
    206  this.__alignment_count = 0;
    207  this.__wrap_point_index = 0;
    208  this.__wrap_point_character_count = 0;
    209  this.__wrap_point_indent_count = -1;
    210  this.__wrap_point_alignment_count = 0;
    211 
    212  this.__items = [];
    213 }
    214 
    215 OutputLine.prototype.clone_empty = function() {
    216  var line = new OutputLine(this.__parent);
    217  line.set_indent(this.__indent_count, this.__alignment_count);
    218  return line;
    219 };
    220 
    221 OutputLine.prototype.item = function(index) {
    222  if (index < 0) {
    223    return this.__items[this.__items.length + index];
    224  } else {
    225    return this.__items[index];
    226  }
    227 };
    228 
    229 OutputLine.prototype.has_match = function(pattern) {
    230  for (var lastCheckedOutput = this.__items.length - 1; lastCheckedOutput >= 0; lastCheckedOutput--) {
    231    if (this.__items[lastCheckedOutput].match(pattern)) {
    232      return true;
    233    }
    234  }
    235  return false;
    236 };
    237 
    238 OutputLine.prototype.set_indent = function(indent, alignment) {
    239  if (this.is_empty()) {
    240    this.__indent_count = indent || 0;
    241    this.__alignment_count = alignment || 0;
    242    this.__character_count = this.__parent.get_indent_size(this.__indent_count, this.__alignment_count);
    243  }
    244 };
    245 
    246 OutputLine.prototype._set_wrap_point = function() {
    247  if (this.__parent.wrap_line_length) {
    248    this.__wrap_point_index = this.__items.length;
    249    this.__wrap_point_character_count = this.__character_count;
    250    this.__wrap_point_indent_count = this.__parent.next_line.__indent_count;
    251    this.__wrap_point_alignment_count = this.__parent.next_line.__alignment_count;
    252  }
    253 };
    254 
    255 OutputLine.prototype._should_wrap = function() {
    256  return this.__wrap_point_index &&
    257    this.__character_count > this.__parent.wrap_line_length &&
    258    this.__wrap_point_character_count > this.__parent.next_line.__character_count;
    259 };
    260 
    261 OutputLine.prototype._allow_wrap = function() {
    262  if (this._should_wrap()) {
    263    this.__parent.add_new_line();
    264    var next = this.__parent.current_line;
    265    next.set_indent(this.__wrap_point_indent_count, this.__wrap_point_alignment_count);
    266    next.__items = this.__items.slice(this.__wrap_point_index);
    267    this.__items = this.__items.slice(0, this.__wrap_point_index);
    268 
    269    next.__character_count += this.__character_count - this.__wrap_point_character_count;
    270    this.__character_count = this.__wrap_point_character_count;
    271 
    272    if (next.__items[0] === " ") {
    273      next.__items.splice(0, 1);
    274      next.__character_count -= 1;
    275    }
    276    return true;
    277  }
    278  return false;
    279 };
    280 
    281 OutputLine.prototype.is_empty = function() {
    282  return this.__items.length === 0;
    283 };
    284 
    285 OutputLine.prototype.last = function() {
    286  if (!this.is_empty()) {
    287    return this.__items[this.__items.length - 1];
    288  } else {
    289    return null;
    290  }
    291 };
    292 
    293 OutputLine.prototype.push = function(item) {
    294  this.__items.push(item);
    295  var last_newline_index = item.lastIndexOf('\n');
    296  if (last_newline_index !== -1) {
    297    this.__character_count = item.length - last_newline_index;
    298  } else {
    299    this.__character_count += item.length;
    300  }
    301 };
    302 
    303 OutputLine.prototype.pop = function() {
    304  var item = null;
    305  if (!this.is_empty()) {
    306    item = this.__items.pop();
    307    this.__character_count -= item.length;
    308  }
    309  return item;
    310 };
    311 
    312 
    313 OutputLine.prototype._remove_indent = function() {
    314  if (this.__indent_count > 0) {
    315    this.__indent_count -= 1;
    316    this.__character_count -= this.__parent.indent_size;
    317  }
    318 };
    319 
    320 OutputLine.prototype._remove_wrap_indent = function() {
    321  if (this.__wrap_point_indent_count > 0) {
    322    this.__wrap_point_indent_count -= 1;
    323  }
    324 };
    325 OutputLine.prototype.trim = function() {
    326  while (this.last() === ' ') {
    327    this.__items.pop();
    328    this.__character_count -= 1;
    329  }
    330 };
    331 
    332 OutputLine.prototype.toString = function() {
    333  var result = '';
    334  if (this.is_empty()) {
    335    if (this.__parent.indent_empty_lines) {
    336      result = this.__parent.get_indent_string(this.__indent_count);
    337    }
    338  } else {
    339    result = this.__parent.get_indent_string(this.__indent_count, this.__alignment_count);
    340    result += this.__items.join('');
    341  }
    342  return result;
    343 };
    344 
    345 function IndentStringCache(options, baseIndentString) {
    346  this.__cache = [''];
    347  this.__indent_size = options.indent_size;
    348  this.__indent_string = options.indent_char;
    349  if (!options.indent_with_tabs) {
    350    this.__indent_string = new Array(options.indent_size + 1).join(options.indent_char);
    351  }
    352 
    353  // Set to null to continue support for auto detection of base indent
    354  baseIndentString = baseIndentString || '';
    355  if (options.indent_level > 0) {
    356    baseIndentString = new Array(options.indent_level + 1).join(this.__indent_string);
    357  }
    358 
    359  this.__base_string = baseIndentString;
    360  this.__base_string_length = baseIndentString.length;
    361 }
    362 
    363 IndentStringCache.prototype.get_indent_size = function(indent, column) {
    364  var result = this.__base_string_length;
    365  column = column || 0;
    366  if (indent < 0) {
    367    result = 0;
    368  }
    369  result += indent * this.__indent_size;
    370  result += column;
    371  return result;
    372 };
    373 
    374 IndentStringCache.prototype.get_indent_string = function(indent_level, column) {
    375  var result = this.__base_string;
    376  column = column || 0;
    377  if (indent_level < 0) {
    378    indent_level = 0;
    379    result = '';
    380  }
    381  column += indent_level * this.__indent_size;
    382  this.__ensure_cache(column);
    383  result += this.__cache[column];
    384  return result;
    385 };
    386 
    387 IndentStringCache.prototype.__ensure_cache = function(column) {
    388  while (column >= this.__cache.length) {
    389    this.__add_column();
    390  }
    391 };
    392 
    393 IndentStringCache.prototype.__add_column = function() {
    394  var column = this.__cache.length;
    395  var indent = 0;
    396  var result = '';
    397  if (this.__indent_size && column >= this.__indent_size) {
    398    indent = Math.floor(column / this.__indent_size);
    399    column -= indent * this.__indent_size;
    400    result = new Array(indent + 1).join(this.__indent_string);
    401  }
    402  if (column) {
    403    result += new Array(column + 1).join(' ');
    404  }
    405 
    406  this.__cache.push(result);
    407 };
    408 
    409 function Output(options, baseIndentString) {
    410  this.__indent_cache = new IndentStringCache(options, baseIndentString);
    411  this.raw = false;
    412  this._end_with_newline = options.end_with_newline;
    413  this.indent_size = options.indent_size;
    414  this.wrap_line_length = options.wrap_line_length;
    415  this.indent_empty_lines = options.indent_empty_lines;
    416  this.__lines = [];
    417  this.previous_line = null;
    418  this.current_line = null;
    419  this.next_line = new OutputLine(this);
    420  this.space_before_token = false;
    421  this.non_breaking_space = false;
    422  this.previous_token_wrapped = false;
    423  // initialize
    424  this.__add_outputline();
    425 }
    426 
    427 Output.prototype.__add_outputline = function() {
    428  this.previous_line = this.current_line;
    429  this.current_line = this.next_line.clone_empty();
    430  this.__lines.push(this.current_line);
    431 };
    432 
    433 Output.prototype.get_line_number = function() {
    434  return this.__lines.length;
    435 };
    436 
    437 Output.prototype.get_indent_string = function(indent, column) {
    438  return this.__indent_cache.get_indent_string(indent, column);
    439 };
    440 
    441 Output.prototype.get_indent_size = function(indent, column) {
    442  return this.__indent_cache.get_indent_size(indent, column);
    443 };
    444 
    445 Output.prototype.is_empty = function() {
    446  return !this.previous_line && this.current_line.is_empty();
    447 };
    448 
    449 Output.prototype.add_new_line = function(force_newline) {
    450  // never newline at the start of file
    451  // otherwise, newline only if we didn't just add one or we're forced
    452  if (this.is_empty() ||
    453    (!force_newline && this.just_added_newline())) {
    454    return false;
    455  }
    456 
    457  // if raw output is enabled, don't print additional newlines,
    458  // but still return True as though you had
    459  if (!this.raw) {
    460    this.__add_outputline();
    461  }
    462  return true;
    463 };
    464 
    465 Output.prototype.get_code = function(eol) {
    466  this.trim(true);
    467 
    468  // handle some edge cases where the last tokens
    469  // has text that ends with newline(s)
    470  var last_item = this.current_line.pop();
    471  if (last_item) {
    472    if (last_item[last_item.length - 1] === '\n') {
    473      last_item = last_item.replace(/\n+$/g, '');
    474    }
    475    this.current_line.push(last_item);
    476  }
    477 
    478  if (this._end_with_newline) {
    479    this.__add_outputline();
    480  }
    481 
    482  var sweet_code = this.__lines.join('\n');
    483 
    484  if (eol !== '\n') {
    485    sweet_code = sweet_code.replace(/[\n]/g, eol);
    486  }
    487  return sweet_code;
    488 };
    489 
    490 Output.prototype.set_wrap_point = function() {
    491  this.current_line._set_wrap_point();
    492 };
    493 
    494 Output.prototype.set_indent = function(indent, alignment) {
    495  indent = indent || 0;
    496  alignment = alignment || 0;
    497 
    498  // Next line stores alignment values
    499  this.next_line.set_indent(indent, alignment);
    500 
    501  // Never indent your first output indent at the start of the file
    502  if (this.__lines.length > 1) {
    503    this.current_line.set_indent(indent, alignment);
    504    return true;
    505  }
    506 
    507  this.current_line.set_indent();
    508  return false;
    509 };
    510 
    511 Output.prototype.add_raw_token = function(token) {
    512  for (var x = 0; x < token.newlines; x++) {
    513    this.__add_outputline();
    514  }
    515  this.current_line.set_indent(-1);
    516  this.current_line.push(token.whitespace_before);
    517  this.current_line.push(token.text);
    518  this.space_before_token = false;
    519  this.non_breaking_space = false;
    520  this.previous_token_wrapped = false;
    521 };
    522 
    523 Output.prototype.add_token = function(printable_token) {
    524  this.__add_space_before_token();
    525  this.current_line.push(printable_token);
    526  this.space_before_token = false;
    527  this.non_breaking_space = false;
    528  this.previous_token_wrapped = this.current_line._allow_wrap();
    529 };
    530 
    531 Output.prototype.__add_space_before_token = function() {
    532  if (this.space_before_token && !this.just_added_newline()) {
    533    if (!this.non_breaking_space) {
    534      this.set_wrap_point();
    535    }
    536    this.current_line.push(' ');
    537  }
    538 };
    539 
    540 Output.prototype.remove_indent = function(index) {
    541  var output_length = this.__lines.length;
    542  while (index < output_length) {
    543    this.__lines[index]._remove_indent();
    544    index++;
    545  }
    546  this.current_line._remove_wrap_indent();
    547 };
    548 
    549 Output.prototype.trim = function(eat_newlines) {
    550  eat_newlines = (eat_newlines === undefined) ? false : eat_newlines;
    551 
    552  this.current_line.trim();
    553 
    554  while (eat_newlines && this.__lines.length > 1 &&
    555    this.current_line.is_empty()) {
    556    this.__lines.pop();
    557    this.current_line = this.__lines[this.__lines.length - 1];
    558    this.current_line.trim();
    559  }
    560 
    561  this.previous_line = this.__lines.length > 1 ?
    562    this.__lines[this.__lines.length - 2] : null;
    563 };
    564 
    565 Output.prototype.just_added_newline = function() {
    566  return this.current_line.is_empty();
    567 };
    568 
    569 Output.prototype.just_added_blankline = function() {
    570  return this.is_empty() ||
    571    (this.current_line.is_empty() && this.previous_line.is_empty());
    572 };
    573 
    574 Output.prototype.ensure_empty_line_above = function(starts_with, ends_with) {
    575  var index = this.__lines.length - 2;
    576  while (index >= 0) {
    577    var potentialEmptyLine = this.__lines[index];
    578    if (potentialEmptyLine.is_empty()) {
    579      break;
    580    } else if (potentialEmptyLine.item(0).indexOf(starts_with) !== 0 &&
    581      potentialEmptyLine.item(-1) !== ends_with) {
    582      this.__lines.splice(index + 1, 0, new OutputLine(this));
    583      this.previous_line = this.__lines[this.__lines.length - 2];
    584      break;
    585    }
    586    index--;
    587  }
    588 };
    589 
    590 module.exports.Output = Output;
    591 
    592 
    593 /***/ }),
    594 /* 3 */
    595 /***/ (function(module, exports, __webpack_require__) {
    596 
    597 "use strict";
    598 /*jshint node:true */
    599 /*
    600 
    601  The MIT License (MIT)
    602 
    603  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
    604 
    605  Permission is hereby granted, free of charge, to any person
    606  obtaining a copy of this software and associated documentation files
    607  (the "Software"), to deal in the Software without restriction,
    608  including without limitation the rights to use, copy, modify, merge,
    609  publish, distribute, sublicense, and/or sell copies of the Software,
    610  and to permit persons to whom the Software is furnished to do so,
    611  subject to the following conditions:
    612 
    613  The above copyright notice and this permission notice shall be
    614  included in all copies or substantial portions of the Software.
    615 
    616  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    617  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    618  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    619  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
    620  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
    621  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    622  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    623  SOFTWARE.
    624 */
    625 
    626 
    627 
    628 function Token(type, text, newlines, whitespace_before) {
    629  this.type = type;
    630  this.text = text;
    631 
    632  // comments_before are
    633  // comments that have a new line before them
    634  // and may or may not have a newline after
    635  // this is a set of comments before
    636  this.comments_before = null; /* inline comment*/
    637 
    638 
    639  // this.comments_after =  new TokenStream(); // no new line before and newline after
    640  this.newlines = newlines || 0;
    641  this.whitespace_before = whitespace_before || '';
    642  this.parent = null;
    643  this.next = null;
    644  this.previous = null;
    645  this.opened = null;
    646  this.closed = null;
    647  this.directives = null;
    648 }
    649 
    650 
    651 module.exports.Token = Token;
    652 
    653 
    654 /***/ }),
    655 /* 4 */,
    656 /* 5 */,
    657 /* 6 */
    658 /***/ (function(module, exports, __webpack_require__) {
    659 
    660 "use strict";
    661 /*jshint node:true */
    662 /*
    663 
    664  The MIT License (MIT)
    665 
    666  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
    667 
    668  Permission is hereby granted, free of charge, to any person
    669  obtaining a copy of this software and associated documentation files
    670  (the "Software"), to deal in the Software without restriction,
    671  including without limitation the rights to use, copy, modify, merge,
    672  publish, distribute, sublicense, and/or sell copies of the Software,
    673  and to permit persons to whom the Software is furnished to do so,
    674  subject to the following conditions:
    675 
    676  The above copyright notice and this permission notice shall be
    677  included in all copies or substantial portions of the Software.
    678 
    679  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    680  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    681  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    682  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
    683  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
    684  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    685  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    686  SOFTWARE.
    687 */
    688 
    689 
    690 
    691 function Options(options, merge_child_field) {
    692  this.raw_options = _mergeOpts(options, merge_child_field);
    693 
    694  // Support passing the source text back with no change
    695  this.disabled = this._get_boolean('disabled');
    696 
    697  this.eol = this._get_characters('eol', 'auto');
    698  this.end_with_newline = this._get_boolean('end_with_newline');
    699  this.indent_size = this._get_number('indent_size', 4);
    700  this.indent_char = this._get_characters('indent_char', ' ');
    701  this.indent_level = this._get_number('indent_level');
    702 
    703  this.preserve_newlines = this._get_boolean('preserve_newlines', true);
    704  this.max_preserve_newlines = this._get_number('max_preserve_newlines', 32786);
    705  if (!this.preserve_newlines) {
    706    this.max_preserve_newlines = 0;
    707  }
    708 
    709  this.indent_with_tabs = this._get_boolean('indent_with_tabs', this.indent_char === '\t');
    710  if (this.indent_with_tabs) {
    711    this.indent_char = '\t';
    712 
    713    // indent_size behavior changed after 1.8.6
    714    // It used to be that indent_size would be
    715    // set to 1 for indent_with_tabs. That is no longer needed and
    716    // actually doesn't make sense - why not use spaces? Further,
    717    // that might produce unexpected behavior - tabs being used
    718    // for single-column alignment. So, when indent_with_tabs is true
    719    // and indent_size is 1, reset indent_size to 4.
    720    if (this.indent_size === 1) {
    721      this.indent_size = 4;
    722    }
    723  }
    724 
    725  // Backwards compat with 1.3.x
    726  this.wrap_line_length = this._get_number('wrap_line_length', this._get_number('max_char'));
    727 
    728  this.indent_empty_lines = this._get_boolean('indent_empty_lines');
    729 
    730  // valid templating languages ['django', 'erb', 'handlebars', 'php']
    731  // For now, 'auto' = all off for javascript, all on for html (and inline javascript).
    732  // other values ignored
    733  this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php'], ['auto']);
    734 }
    735 
    736 Options.prototype._get_array = function(name, default_value) {
    737  var option_value = this.raw_options[name];
    738  var result = default_value || [];
    739  if (typeof option_value === 'object') {
    740    if (option_value !== null && typeof option_value.concat === 'function') {
    741      result = option_value.concat();
    742    }
    743  } else if (typeof option_value === 'string') {
    744    result = option_value.split(/[^a-zA-Z0-9_\/\-]+/);
    745  }
    746  return result;
    747 };
    748 
    749 Options.prototype._get_boolean = function(name, default_value) {
    750  var option_value = this.raw_options[name];
    751  var result = option_value === undefined ? !!default_value : !!option_value;
    752  return result;
    753 };
    754 
    755 Options.prototype._get_characters = function(name, default_value) {
    756  var option_value = this.raw_options[name];
    757  var result = default_value || '';
    758  if (typeof option_value === 'string') {
    759    result = option_value.replace(/\\r/, '\r').replace(/\\n/, '\n').replace(/\\t/, '\t');
    760  }
    761  return result;
    762 };
    763 
    764 Options.prototype._get_number = function(name, default_value) {
    765  var option_value = this.raw_options[name];
    766  default_value = parseInt(default_value, 10);
    767  if (isNaN(default_value)) {
    768    default_value = 0;
    769  }
    770  var result = parseInt(option_value, 10);
    771  if (isNaN(result)) {
    772    result = default_value;
    773  }
    774  return result;
    775 };
    776 
    777 Options.prototype._get_selection = function(name, selection_list, default_value) {
    778  var result = this._get_selection_list(name, selection_list, default_value);
    779  if (result.length !== 1) {
    780    throw new Error(
    781      "Invalid Option Value: The option '" + name + "' can only be one of the following values:\n" +
    782      selection_list + "\nYou passed in: '" + this.raw_options[name] + "'");
    783  }
    784 
    785  return result[0];
    786 };
    787 
    788 
    789 Options.prototype._get_selection_list = function(name, selection_list, default_value) {
    790  if (!selection_list || selection_list.length === 0) {
    791    throw new Error("Selection list cannot be empty.");
    792  }
    793 
    794  default_value = default_value || [selection_list[0]];
    795  if (!this._is_valid_selection(default_value, selection_list)) {
    796    throw new Error("Invalid Default Value!");
    797  }
    798 
    799  var result = this._get_array(name, default_value);
    800  if (!this._is_valid_selection(result, selection_list)) {
    801    throw new Error(
    802      "Invalid Option Value: The option '" + name + "' can contain only the following values:\n" +
    803      selection_list + "\nYou passed in: '" + this.raw_options[name] + "'");
    804  }
    805 
    806  return result;
    807 };
    808 
    809 Options.prototype._is_valid_selection = function(result, selection_list) {
    810  return result.length && selection_list.length &&
    811    !result.some(function(item) { return selection_list.indexOf(item) === -1; });
    812 };
    813 
    814 
    815 // merges child options up with the parent options object
    816 // Example: obj = {a: 1, b: {a: 2}}
    817 //          mergeOpts(obj, 'b')
    818 //
    819 //          Returns: {a: 2}
    820 function _mergeOpts(allOptions, childFieldName) {
    821  var finalOpts = {};
    822  allOptions = _normalizeOpts(allOptions);
    823  var name;
    824 
    825  for (name in allOptions) {
    826    if (name !== childFieldName) {
    827      finalOpts[name] = allOptions[name];
    828    }
    829  }
    830 
    831  //merge in the per type settings for the childFieldName
    832  if (childFieldName && allOptions[childFieldName]) {
    833    for (name in allOptions[childFieldName]) {
    834      finalOpts[name] = allOptions[childFieldName][name];
    835    }
    836  }
    837  return finalOpts;
    838 }
    839 
    840 function _normalizeOpts(options) {
    841  var convertedOpts = {};
    842  var key;
    843 
    844  for (key in options) {
    845    var newKey = key.replace(/-/g, "_");
    846    convertedOpts[newKey] = options[key];
    847  }
    848  return convertedOpts;
    849 }
    850 
    851 module.exports.Options = Options;
    852 module.exports.normalizeOpts = _normalizeOpts;
    853 module.exports.mergeOpts = _mergeOpts;
    854 
    855 
    856 /***/ }),
    857 /* 7 */,
    858 /* 8 */
    859 /***/ (function(module, exports, __webpack_require__) {
    860 
    861 "use strict";
    862 /*jshint node:true */
    863 /*
    864 
    865  The MIT License (MIT)
    866 
    867  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
    868 
    869  Permission is hereby granted, free of charge, to any person
    870  obtaining a copy of this software and associated documentation files
    871  (the "Software"), to deal in the Software without restriction,
    872  including without limitation the rights to use, copy, modify, merge,
    873  publish, distribute, sublicense, and/or sell copies of the Software,
    874  and to permit persons to whom the Software is furnished to do so,
    875  subject to the following conditions:
    876 
    877  The above copyright notice and this permission notice shall be
    878  included in all copies or substantial portions of the Software.
    879 
    880  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    881  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    882  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    883  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
    884  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
    885  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    886  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    887  SOFTWARE.
    888 */
    889 
    890 
    891 
    892 var regexp_has_sticky = RegExp.prototype.hasOwnProperty('sticky');
    893 
    894 function InputScanner(input_string) {
    895  this.__input = input_string || '';
    896  this.__input_length = this.__input.length;
    897  this.__position = 0;
    898 }
    899 
    900 InputScanner.prototype.restart = function() {
    901  this.__position = 0;
    902 };
    903 
    904 InputScanner.prototype.back = function() {
    905  if (this.__position > 0) {
    906    this.__position -= 1;
    907  }
    908 };
    909 
    910 InputScanner.prototype.hasNext = function() {
    911  return this.__position < this.__input_length;
    912 };
    913 
    914 InputScanner.prototype.next = function() {
    915  var val = null;
    916  if (this.hasNext()) {
    917    val = this.__input.charAt(this.__position);
    918    this.__position += 1;
    919  }
    920  return val;
    921 };
    922 
    923 InputScanner.prototype.peek = function(index) {
    924  var val = null;
    925  index = index || 0;
    926  index += this.__position;
    927  if (index >= 0 && index < this.__input_length) {
    928    val = this.__input.charAt(index);
    929  }
    930  return val;
    931 };
    932 
    933 // This is a JavaScript only helper function (not in python)
    934 // Javascript doesn't have a match method
    935 // and not all implementation support "sticky" flag.
    936 // If they do not support sticky then both this.match() and this.test() method
    937 // must get the match and check the index of the match.
    938 // If sticky is supported and set, this method will use it.
    939 // Otherwise it will check that global is set, and fall back to the slower method.
    940 InputScanner.prototype.__match = function(pattern, index) {
    941  pattern.lastIndex = index;
    942  var pattern_match = pattern.exec(this.__input);
    943 
    944  if (pattern_match && !(regexp_has_sticky && pattern.sticky)) {
    945    if (pattern_match.index !== index) {
    946      pattern_match = null;
    947    }
    948  }
    949 
    950  return pattern_match;
    951 };
    952 
    953 InputScanner.prototype.test = function(pattern, index) {
    954  index = index || 0;
    955  index += this.__position;
    956 
    957  if (index >= 0 && index < this.__input_length) {
    958    return !!this.__match(pattern, index);
    959  } else {
    960    return false;
    961  }
    962 };
    963 
    964 InputScanner.prototype.testChar = function(pattern, index) {
    965  // test one character regex match
    966  var val = this.peek(index);
    967  pattern.lastIndex = 0;
    968  return val !== null && pattern.test(val);
    969 };
    970 
    971 InputScanner.prototype.match = function(pattern) {
    972  var pattern_match = this.__match(pattern, this.__position);
    973  if (pattern_match) {
    974    this.__position += pattern_match[0].length;
    975  } else {
    976    pattern_match = null;
    977  }
    978  return pattern_match;
    979 };
    980 
    981 InputScanner.prototype.read = function(starting_pattern, until_pattern, until_after) {
    982  var val = '';
    983  var match;
    984  if (starting_pattern) {
    985    match = this.match(starting_pattern);
    986    if (match) {
    987      val += match[0];
    988    }
    989  }
    990  if (until_pattern && (match || !starting_pattern)) {
    991    val += this.readUntil(until_pattern, until_after);
    992  }
    993  return val;
    994 };
    995 
    996 InputScanner.prototype.readUntil = function(pattern, until_after) {
    997  var val = '';
    998  var match_index = this.__position;
    999  pattern.lastIndex = this.__position;
   1000  var pattern_match = pattern.exec(this.__input);
   1001  if (pattern_match) {
   1002    match_index = pattern_match.index;
   1003    if (until_after) {
   1004      match_index += pattern_match[0].length;
   1005    }
   1006  } else {
   1007    match_index = this.__input_length;
   1008  }
   1009 
   1010  val = this.__input.substring(this.__position, match_index);
   1011  this.__position = match_index;
   1012  return val;
   1013 };
   1014 
   1015 InputScanner.prototype.readUntilAfter = function(pattern) {
   1016  return this.readUntil(pattern, true);
   1017 };
   1018 
   1019 InputScanner.prototype.get_regexp = function(pattern, match_from) {
   1020  var result = null;
   1021  var flags = 'g';
   1022  if (match_from && regexp_has_sticky) {
   1023    flags = 'y';
   1024  }
   1025  // strings are converted to regexp
   1026  if (typeof pattern === "string" && pattern !== '') {
   1027    // result = new RegExp(pattern.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), flags);
   1028    result = new RegExp(pattern, flags);
   1029  } else if (pattern) {
   1030    result = new RegExp(pattern.source, flags);
   1031  }
   1032  return result;
   1033 };
   1034 
   1035 InputScanner.prototype.get_literal_regexp = function(literal_string) {
   1036  return RegExp(literal_string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
   1037 };
   1038 
   1039 /* css beautifier legacy helpers */
   1040 InputScanner.prototype.peekUntilAfter = function(pattern) {
   1041  var start = this.__position;
   1042  var val = this.readUntilAfter(pattern);
   1043  this.__position = start;
   1044  return val;
   1045 };
   1046 
   1047 InputScanner.prototype.lookBack = function(testVal) {
   1048  var start = this.__position - 1;
   1049  return start >= testVal.length && this.__input.substring(start - testVal.length, start)
   1050    .toLowerCase() === testVal;
   1051 };
   1052 
   1053 module.exports.InputScanner = InputScanner;
   1054 
   1055 
   1056 /***/ }),
   1057 /* 9 */
   1058 /***/ (function(module, exports, __webpack_require__) {
   1059 
   1060 "use strict";
   1061 /*jshint node:true */
   1062 /*
   1063 
   1064  The MIT License (MIT)
   1065 
   1066  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
   1067 
   1068  Permission is hereby granted, free of charge, to any person
   1069  obtaining a copy of this software and associated documentation files
   1070  (the "Software"), to deal in the Software without restriction,
   1071  including without limitation the rights to use, copy, modify, merge,
   1072  publish, distribute, sublicense, and/or sell copies of the Software,
   1073  and to permit persons to whom the Software is furnished to do so,
   1074  subject to the following conditions:
   1075 
   1076  The above copyright notice and this permission notice shall be
   1077  included in all copies or substantial portions of the Software.
   1078 
   1079  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   1080  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   1081  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   1082  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   1083  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   1084  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   1085  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   1086  SOFTWARE.
   1087 */
   1088 
   1089 
   1090 
   1091 var InputScanner = __webpack_require__(8).InputScanner;
   1092 var Token = __webpack_require__(3).Token;
   1093 var TokenStream = __webpack_require__(10).TokenStream;
   1094 var WhitespacePattern = __webpack_require__(11).WhitespacePattern;
   1095 
   1096 var TOKEN = {
   1097  START: 'TK_START',
   1098  RAW: 'TK_RAW',
   1099  EOF: 'TK_EOF'
   1100 };
   1101 
   1102 var Tokenizer = function(input_string, options) {
   1103  this._input = new InputScanner(input_string);
   1104  this._options = options || {};
   1105  this.__tokens = null;
   1106 
   1107  this._patterns = {};
   1108  this._patterns.whitespace = new WhitespacePattern(this._input);
   1109 };
   1110 
   1111 Tokenizer.prototype.tokenize = function() {
   1112  this._input.restart();
   1113  this.__tokens = new TokenStream();
   1114 
   1115  this._reset();
   1116 
   1117  var current;
   1118  var previous = new Token(TOKEN.START, '');
   1119  var open_token = null;
   1120  var open_stack = [];
   1121  var comments = new TokenStream();
   1122 
   1123  while (previous.type !== TOKEN.EOF) {
   1124    current = this._get_next_token(previous, open_token);
   1125    while (this._is_comment(current)) {
   1126      comments.add(current);
   1127      current = this._get_next_token(previous, open_token);
   1128    }
   1129 
   1130    if (!comments.isEmpty()) {
   1131      current.comments_before = comments;
   1132      comments = new TokenStream();
   1133    }
   1134 
   1135    current.parent = open_token;
   1136 
   1137    if (this._is_opening(current)) {
   1138      open_stack.push(open_token);
   1139      open_token = current;
   1140    } else if (open_token && this._is_closing(current, open_token)) {
   1141      current.opened = open_token;
   1142      open_token.closed = current;
   1143      open_token = open_stack.pop();
   1144      current.parent = open_token;
   1145    }
   1146 
   1147    current.previous = previous;
   1148    previous.next = current;
   1149 
   1150    this.__tokens.add(current);
   1151    previous = current;
   1152  }
   1153 
   1154  return this.__tokens;
   1155 };
   1156 
   1157 
   1158 Tokenizer.prototype._is_first_token = function() {
   1159  return this.__tokens.isEmpty();
   1160 };
   1161 
   1162 Tokenizer.prototype._reset = function() {};
   1163 
   1164 Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // jshint unused:false
   1165  this._readWhitespace();
   1166  var resulting_string = this._input.read(/.+/g);
   1167  if (resulting_string) {
   1168    return this._create_token(TOKEN.RAW, resulting_string);
   1169  } else {
   1170    return this._create_token(TOKEN.EOF, '');
   1171  }
   1172 };
   1173 
   1174 Tokenizer.prototype._is_comment = function(current_token) { // jshint unused:false
   1175  return false;
   1176 };
   1177 
   1178 Tokenizer.prototype._is_opening = function(current_token) { // jshint unused:false
   1179  return false;
   1180 };
   1181 
   1182 Tokenizer.prototype._is_closing = function(current_token, open_token) { // jshint unused:false
   1183  return false;
   1184 };
   1185 
   1186 Tokenizer.prototype._create_token = function(type, text) {
   1187  var token = new Token(type, text,
   1188    this._patterns.whitespace.newline_count,
   1189    this._patterns.whitespace.whitespace_before_token);
   1190  return token;
   1191 };
   1192 
   1193 Tokenizer.prototype._readWhitespace = function() {
   1194  return this._patterns.whitespace.read();
   1195 };
   1196 
   1197 
   1198 
   1199 module.exports.Tokenizer = Tokenizer;
   1200 module.exports.TOKEN = TOKEN;
   1201 
   1202 
   1203 /***/ }),
   1204 /* 10 */
   1205 /***/ (function(module, exports, __webpack_require__) {
   1206 
   1207 "use strict";
   1208 /*jshint node:true */
   1209 /*
   1210 
   1211  The MIT License (MIT)
   1212 
   1213  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
   1214 
   1215  Permission is hereby granted, free of charge, to any person
   1216  obtaining a copy of this software and associated documentation files
   1217  (the "Software"), to deal in the Software without restriction,
   1218  including without limitation the rights to use, copy, modify, merge,
   1219  publish, distribute, sublicense, and/or sell copies of the Software,
   1220  and to permit persons to whom the Software is furnished to do so,
   1221  subject to the following conditions:
   1222 
   1223  The above copyright notice and this permission notice shall be
   1224  included in all copies or substantial portions of the Software.
   1225 
   1226  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   1227  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   1228  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   1229  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   1230  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   1231  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   1232  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   1233  SOFTWARE.
   1234 */
   1235 
   1236 
   1237 
   1238 function TokenStream(parent_token) {
   1239  // private
   1240  this.__tokens = [];
   1241  this.__tokens_length = this.__tokens.length;
   1242  this.__position = 0;
   1243  this.__parent_token = parent_token;
   1244 }
   1245 
   1246 TokenStream.prototype.restart = function() {
   1247  this.__position = 0;
   1248 };
   1249 
   1250 TokenStream.prototype.isEmpty = function() {
   1251  return this.__tokens_length === 0;
   1252 };
   1253 
   1254 TokenStream.prototype.hasNext = function() {
   1255  return this.__position < this.__tokens_length;
   1256 };
   1257 
   1258 TokenStream.prototype.next = function() {
   1259  var val = null;
   1260  if (this.hasNext()) {
   1261    val = this.__tokens[this.__position];
   1262    this.__position += 1;
   1263  }
   1264  return val;
   1265 };
   1266 
   1267 TokenStream.prototype.peek = function(index) {
   1268  var val = null;
   1269  index = index || 0;
   1270  index += this.__position;
   1271  if (index >= 0 && index < this.__tokens_length) {
   1272    val = this.__tokens[index];
   1273  }
   1274  return val;
   1275 };
   1276 
   1277 TokenStream.prototype.add = function(token) {
   1278  if (this.__parent_token) {
   1279    token.parent = this.__parent_token;
   1280  }
   1281  this.__tokens.push(token);
   1282  this.__tokens_length += 1;
   1283 };
   1284 
   1285 module.exports.TokenStream = TokenStream;
   1286 
   1287 
   1288 /***/ }),
   1289 /* 11 */
   1290 /***/ (function(module, exports, __webpack_require__) {
   1291 
   1292 "use strict";
   1293 /*jshint node:true */
   1294 /*
   1295 
   1296  The MIT License (MIT)
   1297 
   1298  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
   1299 
   1300  Permission is hereby granted, free of charge, to any person
   1301  obtaining a copy of this software and associated documentation files
   1302  (the "Software"), to deal in the Software without restriction,
   1303  including without limitation the rights to use, copy, modify, merge,
   1304  publish, distribute, sublicense, and/or sell copies of the Software,
   1305  and to permit persons to whom the Software is furnished to do so,
   1306  subject to the following conditions:
   1307 
   1308  The above copyright notice and this permission notice shall be
   1309  included in all copies or substantial portions of the Software.
   1310 
   1311  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   1312  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   1313  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   1314  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   1315  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   1316  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   1317  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   1318  SOFTWARE.
   1319 */
   1320 
   1321 
   1322 
   1323 var Pattern = __webpack_require__(12).Pattern;
   1324 
   1325 function WhitespacePattern(input_scanner, parent) {
   1326  Pattern.call(this, input_scanner, parent);
   1327  if (parent) {
   1328    this._line_regexp = this._input.get_regexp(parent._line_regexp);
   1329  } else {
   1330    this.__set_whitespace_patterns('', '');
   1331  }
   1332 
   1333  this.newline_count = 0;
   1334  this.whitespace_before_token = '';
   1335 }
   1336 WhitespacePattern.prototype = new Pattern();
   1337 
   1338 WhitespacePattern.prototype.__set_whitespace_patterns = function(whitespace_chars, newline_chars) {
   1339  whitespace_chars += '\\t ';
   1340  newline_chars += '\\n\\r';
   1341 
   1342  this._match_pattern = this._input.get_regexp(
   1343    '[' + whitespace_chars + newline_chars + ']+', true);
   1344  this._newline_regexp = this._input.get_regexp(
   1345    '\\r\\n|[' + newline_chars + ']');
   1346 };
   1347 
   1348 WhitespacePattern.prototype.read = function() {
   1349  this.newline_count = 0;
   1350  this.whitespace_before_token = '';
   1351 
   1352  var resulting_string = this._input.read(this._match_pattern);
   1353  if (resulting_string === ' ') {
   1354    this.whitespace_before_token = ' ';
   1355  } else if (resulting_string) {
   1356    var matches = this.__split(this._newline_regexp, resulting_string);
   1357    this.newline_count = matches.length - 1;
   1358    this.whitespace_before_token = matches[this.newline_count];
   1359  }
   1360 
   1361  return resulting_string;
   1362 };
   1363 
   1364 WhitespacePattern.prototype.matching = function(whitespace_chars, newline_chars) {
   1365  var result = this._create();
   1366  result.__set_whitespace_patterns(whitespace_chars, newline_chars);
   1367  result._update();
   1368  return result;
   1369 };
   1370 
   1371 WhitespacePattern.prototype._create = function() {
   1372  return new WhitespacePattern(this._input, this);
   1373 };
   1374 
   1375 WhitespacePattern.prototype.__split = function(regexp, input_string) {
   1376  regexp.lastIndex = 0;
   1377  var start_index = 0;
   1378  var result = [];
   1379  var next_match = regexp.exec(input_string);
   1380  while (next_match) {
   1381    result.push(input_string.substring(start_index, next_match.index));
   1382    start_index = next_match.index + next_match[0].length;
   1383    next_match = regexp.exec(input_string);
   1384  }
   1385 
   1386  if (start_index < input_string.length) {
   1387    result.push(input_string.substring(start_index, input_string.length));
   1388  } else {
   1389    result.push('');
   1390  }
   1391 
   1392  return result;
   1393 };
   1394 
   1395 
   1396 
   1397 module.exports.WhitespacePattern = WhitespacePattern;
   1398 
   1399 
   1400 /***/ }),
   1401 /* 12 */
   1402 /***/ (function(module, exports, __webpack_require__) {
   1403 
   1404 "use strict";
   1405 /*jshint node:true */
   1406 /*
   1407 
   1408  The MIT License (MIT)
   1409 
   1410  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
   1411 
   1412  Permission is hereby granted, free of charge, to any person
   1413  obtaining a copy of this software and associated documentation files
   1414  (the "Software"), to deal in the Software without restriction,
   1415  including without limitation the rights to use, copy, modify, merge,
   1416  publish, distribute, sublicense, and/or sell copies of the Software,
   1417  and to permit persons to whom the Software is furnished to do so,
   1418  subject to the following conditions:
   1419 
   1420  The above copyright notice and this permission notice shall be
   1421  included in all copies or substantial portions of the Software.
   1422 
   1423  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   1424  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   1425  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   1426  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   1427  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   1428  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   1429  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   1430  SOFTWARE.
   1431 */
   1432 
   1433 
   1434 
   1435 function Pattern(input_scanner, parent) {
   1436  this._input = input_scanner;
   1437  this._starting_pattern = null;
   1438  this._match_pattern = null;
   1439  this._until_pattern = null;
   1440  this._until_after = false;
   1441 
   1442  if (parent) {
   1443    this._starting_pattern = this._input.get_regexp(parent._starting_pattern, true);
   1444    this._match_pattern = this._input.get_regexp(parent._match_pattern, true);
   1445    this._until_pattern = this._input.get_regexp(parent._until_pattern);
   1446    this._until_after = parent._until_after;
   1447  }
   1448 }
   1449 
   1450 Pattern.prototype.read = function() {
   1451  var result = this._input.read(this._starting_pattern);
   1452  if (!this._starting_pattern || result) {
   1453    result += this._input.read(this._match_pattern, this._until_pattern, this._until_after);
   1454  }
   1455  return result;
   1456 };
   1457 
   1458 Pattern.prototype.read_match = function() {
   1459  return this._input.match(this._match_pattern);
   1460 };
   1461 
   1462 Pattern.prototype.until_after = function(pattern) {
   1463  var result = this._create();
   1464  result._until_after = true;
   1465  result._until_pattern = this._input.get_regexp(pattern);
   1466  result._update();
   1467  return result;
   1468 };
   1469 
   1470 Pattern.prototype.until = function(pattern) {
   1471  var result = this._create();
   1472  result._until_after = false;
   1473  result._until_pattern = this._input.get_regexp(pattern);
   1474  result._update();
   1475  return result;
   1476 };
   1477 
   1478 Pattern.prototype.starting_with = function(pattern) {
   1479  var result = this._create();
   1480  result._starting_pattern = this._input.get_regexp(pattern, true);
   1481  result._update();
   1482  return result;
   1483 };
   1484 
   1485 Pattern.prototype.matching = function(pattern) {
   1486  var result = this._create();
   1487  result._match_pattern = this._input.get_regexp(pattern, true);
   1488  result._update();
   1489  return result;
   1490 };
   1491 
   1492 Pattern.prototype._create = function() {
   1493  return new Pattern(this._input, this);
   1494 };
   1495 
   1496 Pattern.prototype._update = function() {};
   1497 
   1498 module.exports.Pattern = Pattern;
   1499 
   1500 
   1501 /***/ }),
   1502 /* 13 */
   1503 /***/ (function(module, exports, __webpack_require__) {
   1504 
   1505 "use strict";
   1506 /*jshint node:true */
   1507 /*
   1508 
   1509  The MIT License (MIT)
   1510 
   1511  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
   1512 
   1513  Permission is hereby granted, free of charge, to any person
   1514  obtaining a copy of this software and associated documentation files
   1515  (the "Software"), to deal in the Software without restriction,
   1516  including without limitation the rights to use, copy, modify, merge,
   1517  publish, distribute, sublicense, and/or sell copies of the Software,
   1518  and to permit persons to whom the Software is furnished to do so,
   1519  subject to the following conditions:
   1520 
   1521  The above copyright notice and this permission notice shall be
   1522  included in all copies or substantial portions of the Software.
   1523 
   1524  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   1525  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   1526  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   1527  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   1528  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   1529  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   1530  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   1531  SOFTWARE.
   1532 */
   1533 
   1534 
   1535 
   1536 function Directives(start_block_pattern, end_block_pattern) {
   1537  start_block_pattern = typeof start_block_pattern === 'string' ? start_block_pattern : start_block_pattern.source;
   1538  end_block_pattern = typeof end_block_pattern === 'string' ? end_block_pattern : end_block_pattern.source;
   1539  this.__directives_block_pattern = new RegExp(start_block_pattern + / beautify( \w+[:]\w+)+ /.source + end_block_pattern, 'g');
   1540  this.__directive_pattern = / (\w+)[:](\w+)/g;
   1541 
   1542  this.__directives_end_ignore_pattern = new RegExp(start_block_pattern + /\sbeautify\signore:end\s/.source + end_block_pattern, 'g');
   1543 }
   1544 
   1545 Directives.prototype.get_directives = function(text) {
   1546  if (!text.match(this.__directives_block_pattern)) {
   1547    return null;
   1548  }
   1549 
   1550  var directives = {};
   1551  this.__directive_pattern.lastIndex = 0;
   1552  var directive_match = this.__directive_pattern.exec(text);
   1553 
   1554  while (directive_match) {
   1555    directives[directive_match[1]] = directive_match[2];
   1556    directive_match = this.__directive_pattern.exec(text);
   1557  }
   1558 
   1559  return directives;
   1560 };
   1561 
   1562 Directives.prototype.readIgnored = function(input) {
   1563  return input.readUntilAfter(this.__directives_end_ignore_pattern);
   1564 };
   1565 
   1566 
   1567 module.exports.Directives = Directives;
   1568 
   1569 
   1570 /***/ }),
   1571 /* 14 */
   1572 /***/ (function(module, exports, __webpack_require__) {
   1573 
   1574 "use strict";
   1575 /*jshint node:true */
   1576 /*
   1577 
   1578  The MIT License (MIT)
   1579 
   1580  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
   1581 
   1582  Permission is hereby granted, free of charge, to any person
   1583  obtaining a copy of this software and associated documentation files
   1584  (the "Software"), to deal in the Software without restriction,
   1585  including without limitation the rights to use, copy, modify, merge,
   1586  publish, distribute, sublicense, and/or sell copies of the Software,
   1587  and to permit persons to whom the Software is furnished to do so,
   1588  subject to the following conditions:
   1589 
   1590  The above copyright notice and this permission notice shall be
   1591  included in all copies or substantial portions of the Software.
   1592 
   1593  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   1594  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   1595  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   1596  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   1597  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   1598  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   1599  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   1600  SOFTWARE.
   1601 */
   1602 
   1603 
   1604 
   1605 var Pattern = __webpack_require__(12).Pattern;
   1606 
   1607 
   1608 var template_names = {
   1609  django: false,
   1610  erb: false,
   1611  handlebars: false,
   1612  php: false
   1613 };
   1614 
   1615 // This lets templates appear anywhere we would do a readUntil
   1616 // The cost is higher but it is pay to play.
   1617 function TemplatablePattern(input_scanner, parent) {
   1618  Pattern.call(this, input_scanner, parent);
   1619  this.__template_pattern = null;
   1620  this._disabled = Object.assign({}, template_names);
   1621  this._excluded = Object.assign({}, template_names);
   1622 
   1623  if (parent) {
   1624    this.__template_pattern = this._input.get_regexp(parent.__template_pattern);
   1625    this._excluded = Object.assign(this._excluded, parent._excluded);
   1626    this._disabled = Object.assign(this._disabled, parent._disabled);
   1627  }
   1628  var pattern = new Pattern(input_scanner);
   1629  this.__patterns = {
   1630    handlebars_comment: pattern.starting_with(/{{!--/).until_after(/--}}/),
   1631    handlebars_unescaped: pattern.starting_with(/{{{/).until_after(/}}}/),
   1632    handlebars: pattern.starting_with(/{{/).until_after(/}}/),
   1633    php: pattern.starting_with(/<\?(?:[=]|php)/).until_after(/\?>/),
   1634    erb: pattern.starting_with(/<%[^%]/).until_after(/[^%]%>/),
   1635    // django coflicts with handlebars a bit.
   1636    django: pattern.starting_with(/{%/).until_after(/%}/),
   1637    django_value: pattern.starting_with(/{{/).until_after(/}}/),
   1638    django_comment: pattern.starting_with(/{#/).until_after(/#}/)
   1639  };
   1640 }
   1641 TemplatablePattern.prototype = new Pattern();
   1642 
   1643 TemplatablePattern.prototype._create = function() {
   1644  return new TemplatablePattern(this._input, this);
   1645 };
   1646 
   1647 TemplatablePattern.prototype._update = function() {
   1648  this.__set_templated_pattern();
   1649 };
   1650 
   1651 TemplatablePattern.prototype.disable = function(language) {
   1652  var result = this._create();
   1653  result._disabled[language] = true;
   1654  result._update();
   1655  return result;
   1656 };
   1657 
   1658 TemplatablePattern.prototype.read_options = function(options) {
   1659  var result = this._create();
   1660  for (var language in template_names) {
   1661    result._disabled[language] = options.templating.indexOf(language) === -1;
   1662  }
   1663  result._update();
   1664  return result;
   1665 };
   1666 
   1667 TemplatablePattern.prototype.exclude = function(language) {
   1668  var result = this._create();
   1669  result._excluded[language] = true;
   1670  result._update();
   1671  return result;
   1672 };
   1673 
   1674 TemplatablePattern.prototype.read = function() {
   1675  var result = '';
   1676  if (this._match_pattern) {
   1677    result = this._input.read(this._starting_pattern);
   1678  } else {
   1679    result = this._input.read(this._starting_pattern, this.__template_pattern);
   1680  }
   1681  var next = this._read_template();
   1682  while (next) {
   1683    if (this._match_pattern) {
   1684      next += this._input.read(this._match_pattern);
   1685    } else {
   1686      next += this._input.readUntil(this.__template_pattern);
   1687    }
   1688    result += next;
   1689    next = this._read_template();
   1690  }
   1691 
   1692  if (this._until_after) {
   1693    result += this._input.readUntilAfter(this._until_pattern);
   1694  }
   1695  return result;
   1696 };
   1697 
   1698 TemplatablePattern.prototype.__set_templated_pattern = function() {
   1699  var items = [];
   1700 
   1701  if (!this._disabled.php) {
   1702    items.push(this.__patterns.php._starting_pattern.source);
   1703  }
   1704  if (!this._disabled.handlebars) {
   1705    items.push(this.__patterns.handlebars._starting_pattern.source);
   1706  }
   1707  if (!this._disabled.erb) {
   1708    items.push(this.__patterns.erb._starting_pattern.source);
   1709  }
   1710  if (!this._disabled.django) {
   1711    items.push(this.__patterns.django._starting_pattern.source);
   1712    items.push(this.__patterns.django_value._starting_pattern.source);
   1713    items.push(this.__patterns.django_comment._starting_pattern.source);
   1714  }
   1715 
   1716  if (this._until_pattern) {
   1717    items.push(this._until_pattern.source);
   1718  }
   1719  this.__template_pattern = this._input.get_regexp('(?:' + items.join('|') + ')');
   1720 };
   1721 
   1722 TemplatablePattern.prototype._read_template = function() {
   1723  var resulting_string = '';
   1724  var c = this._input.peek();
   1725  if (c === '<') {
   1726    var peek1 = this._input.peek(1);
   1727    //if we're in a comment, do something special
   1728    // We treat all comments as literals, even more than preformatted tags
   1729    // we just look for the appropriate close tag
   1730    if (!this._disabled.php && !this._excluded.php && peek1 === '?') {
   1731      resulting_string = resulting_string ||
   1732        this.__patterns.php.read();
   1733    }
   1734    if (!this._disabled.erb && !this._excluded.erb && peek1 === '%') {
   1735      resulting_string = resulting_string ||
   1736        this.__patterns.erb.read();
   1737    }
   1738  } else if (c === '{') {
   1739    if (!this._disabled.handlebars && !this._excluded.handlebars) {
   1740      resulting_string = resulting_string ||
   1741        this.__patterns.handlebars_comment.read();
   1742      resulting_string = resulting_string ||
   1743        this.__patterns.handlebars_unescaped.read();
   1744      resulting_string = resulting_string ||
   1745        this.__patterns.handlebars.read();
   1746    }
   1747    if (!this._disabled.django) {
   1748      // django coflicts with handlebars a bit.
   1749      if (!this._excluded.django && !this._excluded.handlebars) {
   1750        resulting_string = resulting_string ||
   1751          this.__patterns.django_value.read();
   1752      }
   1753      if (!this._excluded.django) {
   1754        resulting_string = resulting_string ||
   1755          this.__patterns.django_comment.read();
   1756        resulting_string = resulting_string ||
   1757          this.__patterns.django.read();
   1758      }
   1759    }
   1760  }
   1761  return resulting_string;
   1762 };
   1763 
   1764 
   1765 module.exports.TemplatablePattern = TemplatablePattern;
   1766 
   1767 
   1768 /***/ }),
   1769 /* 15 */,
   1770 /* 16 */,
   1771 /* 17 */,
   1772 /* 18 */
   1773 /***/ (function(module, exports, __webpack_require__) {
   1774 
   1775 "use strict";
   1776 /*jshint node:true */
   1777 /*
   1778 
   1779  The MIT License (MIT)
   1780 
   1781  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
   1782 
   1783  Permission is hereby granted, free of charge, to any person
   1784  obtaining a copy of this software and associated documentation files
   1785  (the "Software"), to deal in the Software without restriction,
   1786  including without limitation the rights to use, copy, modify, merge,
   1787  publish, distribute, sublicense, and/or sell copies of the Software,
   1788  and to permit persons to whom the Software is furnished to do so,
   1789  subject to the following conditions:
   1790 
   1791  The above copyright notice and this permission notice shall be
   1792  included in all copies or substantial portions of the Software.
   1793 
   1794  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   1795  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   1796  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   1797  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   1798  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   1799  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   1800  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   1801  SOFTWARE.
   1802 */
   1803 
   1804 
   1805 
   1806 var Beautifier = __webpack_require__(19).Beautifier,
   1807  Options = __webpack_require__(20).Options;
   1808 
   1809 function style_html(html_source, options, js_beautify, css_beautify) {
   1810  var beautifier = new Beautifier(html_source, options, js_beautify, css_beautify);
   1811  return beautifier.beautify();
   1812 }
   1813 
   1814 module.exports = style_html;
   1815 module.exports.defaultOptions = function() {
   1816  return new Options();
   1817 };
   1818 
   1819 
   1820 /***/ }),
   1821 /* 19 */
   1822 /***/ (function(module, exports, __webpack_require__) {
   1823 
   1824 "use strict";
   1825 /*jshint node:true */
   1826 /*
   1827 
   1828  The MIT License (MIT)
   1829 
   1830  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
   1831 
   1832  Permission is hereby granted, free of charge, to any person
   1833  obtaining a copy of this software and associated documentation files
   1834  (the "Software"), to deal in the Software without restriction,
   1835  including without limitation the rights to use, copy, modify, merge,
   1836  publish, distribute, sublicense, and/or sell copies of the Software,
   1837  and to permit persons to whom the Software is furnished to do so,
   1838  subject to the following conditions:
   1839 
   1840  The above copyright notice and this permission notice shall be
   1841  included in all copies or substantial portions of the Software.
   1842 
   1843  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   1844  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   1845  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   1846  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   1847  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   1848  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   1849  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   1850  SOFTWARE.
   1851 */
   1852 
   1853 
   1854 
   1855 var Options = __webpack_require__(20).Options;
   1856 var Output = __webpack_require__(2).Output;
   1857 var Tokenizer = __webpack_require__(21).Tokenizer;
   1858 var TOKEN = __webpack_require__(21).TOKEN;
   1859 
   1860 var lineBreak = /\r\n|[\r\n]/;
   1861 var allLineBreaks = /\r\n|[\r\n]/g;
   1862 
   1863 var Printer = function(options, base_indent_string) { //handles input/output and some other printing functions
   1864 
   1865  this.indent_level = 0;
   1866  this.alignment_size = 0;
   1867  this.max_preserve_newlines = options.max_preserve_newlines;
   1868  this.preserve_newlines = options.preserve_newlines;
   1869 
   1870  this._output = new Output(options, base_indent_string);
   1871 
   1872 };
   1873 
   1874 Printer.prototype.current_line_has_match = function(pattern) {
   1875  return this._output.current_line.has_match(pattern);
   1876 };
   1877 
   1878 Printer.prototype.set_space_before_token = function(value, non_breaking) {
   1879  this._output.space_before_token = value;
   1880  this._output.non_breaking_space = non_breaking;
   1881 };
   1882 
   1883 Printer.prototype.set_wrap_point = function() {
   1884  this._output.set_indent(this.indent_level, this.alignment_size);
   1885  this._output.set_wrap_point();
   1886 };
   1887 
   1888 
   1889 Printer.prototype.add_raw_token = function(token) {
   1890  this._output.add_raw_token(token);
   1891 };
   1892 
   1893 Printer.prototype.print_preserved_newlines = function(raw_token) {
   1894  var newlines = 0;
   1895  if (raw_token.type !== TOKEN.TEXT && raw_token.previous.type !== TOKEN.TEXT) {
   1896    newlines = raw_token.newlines ? 1 : 0;
   1897  }
   1898 
   1899  if (this.preserve_newlines) {
   1900    newlines = raw_token.newlines < this.max_preserve_newlines + 1 ? raw_token.newlines : this.max_preserve_newlines + 1;
   1901  }
   1902  for (var n = 0; n < newlines; n++) {
   1903    this.print_newline(n > 0);
   1904  }
   1905 
   1906  return newlines !== 0;
   1907 };
   1908 
   1909 Printer.prototype.traverse_whitespace = function(raw_token) {
   1910  if (raw_token.whitespace_before || raw_token.newlines) {
   1911    if (!this.print_preserved_newlines(raw_token)) {
   1912      this._output.space_before_token = true;
   1913    }
   1914    return true;
   1915  }
   1916  return false;
   1917 };
   1918 
   1919 Printer.prototype.previous_token_wrapped = function() {
   1920  return this._output.previous_token_wrapped;
   1921 };
   1922 
   1923 Printer.prototype.print_newline = function(force) {
   1924  this._output.add_new_line(force);
   1925 };
   1926 
   1927 Printer.prototype.print_token = function(token) {
   1928  if (token.text) {
   1929    this._output.set_indent(this.indent_level, this.alignment_size);
   1930    this._output.add_token(token.text);
   1931  }
   1932 };
   1933 
   1934 Printer.prototype.indent = function() {
   1935  this.indent_level++;
   1936 };
   1937 
   1938 Printer.prototype.get_full_indent = function(level) {
   1939  level = this.indent_level + (level || 0);
   1940  if (level < 1) {
   1941    return '';
   1942  }
   1943 
   1944  return this._output.get_indent_string(level);
   1945 };
   1946 
   1947 var get_type_attribute = function(start_token) {
   1948  var result = null;
   1949  var raw_token = start_token.next;
   1950 
   1951  // Search attributes for a type attribute
   1952  while (raw_token.type !== TOKEN.EOF && start_token.closed !== raw_token) {
   1953    if (raw_token.type === TOKEN.ATTRIBUTE && raw_token.text === 'type') {
   1954      if (raw_token.next && raw_token.next.type === TOKEN.EQUALS &&
   1955        raw_token.next.next && raw_token.next.next.type === TOKEN.VALUE) {
   1956        result = raw_token.next.next.text;
   1957      }
   1958      break;
   1959    }
   1960    raw_token = raw_token.next;
   1961  }
   1962 
   1963  return result;
   1964 };
   1965 
   1966 var get_custom_beautifier_name = function(tag_check, raw_token) {
   1967  var typeAttribute = null;
   1968  var result = null;
   1969 
   1970  if (!raw_token.closed) {
   1971    return null;
   1972  }
   1973 
   1974  if (tag_check === 'script') {
   1975    typeAttribute = 'text/javascript';
   1976  } else if (tag_check === 'style') {
   1977    typeAttribute = 'text/css';
   1978  }
   1979 
   1980  typeAttribute = get_type_attribute(raw_token) || typeAttribute;
   1981 
   1982  // For script and style tags that have a type attribute, only enable custom beautifiers for matching values
   1983  // For those without a type attribute use default;
   1984  if (typeAttribute.search('text/css') > -1) {
   1985    result = 'css';
   1986  } else if (typeAttribute.search(/module|((text|application|dojo)\/(x-)?(javascript|ecmascript|jscript|livescript|(ld\+)?json|method|aspect))/) > -1) {
   1987    result = 'javascript';
   1988  } else if (typeAttribute.search(/(text|application|dojo)\/(x-)?(html)/) > -1) {
   1989    result = 'html';
   1990  } else if (typeAttribute.search(/test\/null/) > -1) {
   1991    // Test only mime-type for testing the beautifier when null is passed as beautifing function
   1992    result = 'null';
   1993  }
   1994 
   1995  return result;
   1996 };
   1997 
   1998 function in_array(what, arr) {
   1999  return arr.indexOf(what) !== -1;
   2000 }
   2001 
   2002 function TagFrame(parent, parser_token, indent_level) {
   2003  this.parent = parent || null;
   2004  this.tag = parser_token ? parser_token.tag_name : '';
   2005  this.indent_level = indent_level || 0;
   2006  this.parser_token = parser_token || null;
   2007 }
   2008 
   2009 function TagStack(printer) {
   2010  this._printer = printer;
   2011  this._current_frame = null;
   2012 }
   2013 
   2014 TagStack.prototype.get_parser_token = function() {
   2015  return this._current_frame ? this._current_frame.parser_token : null;
   2016 };
   2017 
   2018 TagStack.prototype.record_tag = function(parser_token) { //function to record a tag and its parent in this.tags Object
   2019  var new_frame = new TagFrame(this._current_frame, parser_token, this._printer.indent_level);
   2020  this._current_frame = new_frame;
   2021 };
   2022 
   2023 TagStack.prototype._try_pop_frame = function(frame) { //function to retrieve the opening tag to the corresponding closer
   2024  var parser_token = null;
   2025 
   2026  if (frame) {
   2027    parser_token = frame.parser_token;
   2028    this._printer.indent_level = frame.indent_level;
   2029    this._current_frame = frame.parent;
   2030  }
   2031 
   2032  return parser_token;
   2033 };
   2034 
   2035 TagStack.prototype._get_frame = function(tag_list, stop_list) { //function to retrieve the opening tag to the corresponding closer
   2036  var frame = this._current_frame;
   2037 
   2038  while (frame) { //till we reach '' (the initial value);
   2039    if (tag_list.indexOf(frame.tag) !== -1) { //if this is it use it
   2040      break;
   2041    } else if (stop_list && stop_list.indexOf(frame.tag) !== -1) {
   2042      frame = null;
   2043      break;
   2044    }
   2045    frame = frame.parent;
   2046  }
   2047 
   2048  return frame;
   2049 };
   2050 
   2051 TagStack.prototype.try_pop = function(tag, stop_list) { //function to retrieve the opening tag to the corresponding closer
   2052  var frame = this._get_frame([tag], stop_list);
   2053  return this._try_pop_frame(frame);
   2054 };
   2055 
   2056 TagStack.prototype.indent_to_tag = function(tag_list) {
   2057  var frame = this._get_frame(tag_list);
   2058  if (frame) {
   2059    this._printer.indent_level = frame.indent_level;
   2060  }
   2061 };
   2062 
   2063 function Beautifier(source_text, options, js_beautify, css_beautify) {
   2064  //Wrapper function to invoke all the necessary constructors and deal with the output.
   2065  this._source_text = source_text || '';
   2066  options = options || {};
   2067  this._js_beautify = js_beautify;
   2068  this._css_beautify = css_beautify;
   2069  this._tag_stack = null;
   2070 
   2071  // Allow the setting of language/file-type specific options
   2072  // with inheritance of overall settings
   2073  var optionHtml = new Options(options, 'html');
   2074 
   2075  this._options = optionHtml;
   2076 
   2077  this._is_wrap_attributes_force = this._options.wrap_attributes.substr(0, 'force'.length) === 'force';
   2078  this._is_wrap_attributes_force_expand_multiline = (this._options.wrap_attributes === 'force-expand-multiline');
   2079  this._is_wrap_attributes_force_aligned = (this._options.wrap_attributes === 'force-aligned');
   2080  this._is_wrap_attributes_aligned_multiple = (this._options.wrap_attributes === 'aligned-multiple');
   2081  this._is_wrap_attributes_preserve = this._options.wrap_attributes.substr(0, 'preserve'.length) === 'preserve';
   2082  this._is_wrap_attributes_preserve_aligned = (this._options.wrap_attributes === 'preserve-aligned');
   2083 }
   2084 
   2085 Beautifier.prototype.beautify = function() {
   2086 
   2087  // if disabled, return the input unchanged.
   2088  if (this._options.disabled) {
   2089    return this._source_text;
   2090  }
   2091 
   2092  var source_text = this._source_text;
   2093  var eol = this._options.eol;
   2094  if (this._options.eol === 'auto') {
   2095    eol = '\n';
   2096    if (source_text && lineBreak.test(source_text)) {
   2097      eol = source_text.match(lineBreak)[0];
   2098    }
   2099  }
   2100 
   2101  // HACK: newline parsing inconsistent. This brute force normalizes the input.
   2102  source_text = source_text.replace(allLineBreaks, '\n');
   2103 
   2104  var baseIndentString = source_text.match(/^[\t ]*/)[0];
   2105 
   2106  var last_token = {
   2107    text: '',
   2108    type: ''
   2109  };
   2110 
   2111  var last_tag_token = new TagOpenParserToken();
   2112 
   2113  var printer = new Printer(this._options, baseIndentString);
   2114  var tokens = new Tokenizer(source_text, this._options).tokenize();
   2115 
   2116  this._tag_stack = new TagStack(printer);
   2117 
   2118  var parser_token = null;
   2119  var raw_token = tokens.next();
   2120  while (raw_token.type !== TOKEN.EOF) {
   2121 
   2122    if (raw_token.type === TOKEN.TAG_OPEN || raw_token.type === TOKEN.COMMENT) {
   2123      parser_token = this._handle_tag_open(printer, raw_token, last_tag_token, last_token);
   2124      last_tag_token = parser_token;
   2125    } else if ((raw_token.type === TOKEN.ATTRIBUTE || raw_token.type === TOKEN.EQUALS || raw_token.type === TOKEN.VALUE) ||
   2126      (raw_token.type === TOKEN.TEXT && !last_tag_token.tag_complete)) {
   2127      parser_token = this._handle_inside_tag(printer, raw_token, last_tag_token, tokens);
   2128    } else if (raw_token.type === TOKEN.TAG_CLOSE) {
   2129      parser_token = this._handle_tag_close(printer, raw_token, last_tag_token);
   2130    } else if (raw_token.type === TOKEN.TEXT) {
   2131      parser_token = this._handle_text(printer, raw_token, last_tag_token);
   2132    } else {
   2133      // This should never happen, but if it does. Print the raw token
   2134      printer.add_raw_token(raw_token);
   2135    }
   2136 
   2137    last_token = parser_token;
   2138 
   2139    raw_token = tokens.next();
   2140  }
   2141  var sweet_code = printer._output.get_code(eol);
   2142 
   2143  return sweet_code;
   2144 };
   2145 
   2146 Beautifier.prototype._handle_tag_close = function(printer, raw_token, last_tag_token) {
   2147  var parser_token = {
   2148    text: raw_token.text,
   2149    type: raw_token.type
   2150  };
   2151  printer.alignment_size = 0;
   2152  last_tag_token.tag_complete = true;
   2153 
   2154  printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '', true);
   2155  if (last_tag_token.is_unformatted) {
   2156    printer.add_raw_token(raw_token);
   2157  } else {
   2158    if (last_tag_token.tag_start_char === '<') {
   2159      printer.set_space_before_token(raw_token.text[0] === '/', true); // space before />, no space before >
   2160      if (this._is_wrap_attributes_force_expand_multiline && last_tag_token.has_wrapped_attrs) {
   2161        printer.print_newline(false);
   2162      }
   2163    }
   2164    printer.print_token(raw_token);
   2165 
   2166  }
   2167 
   2168  if (last_tag_token.indent_content &&
   2169    !(last_tag_token.is_unformatted || last_tag_token.is_content_unformatted)) {
   2170    printer.indent();
   2171 
   2172    // only indent once per opened tag
   2173    last_tag_token.indent_content = false;
   2174  }
   2175 
   2176  if (!last_tag_token.is_inline_element &&
   2177    !(last_tag_token.is_unformatted || last_tag_token.is_content_unformatted)) {
   2178    printer.set_wrap_point();
   2179  }
   2180 
   2181  return parser_token;
   2182 };
   2183 
   2184 Beautifier.prototype._handle_inside_tag = function(printer, raw_token, last_tag_token, tokens) {
   2185  var wrapped = last_tag_token.has_wrapped_attrs;
   2186  var parser_token = {
   2187    text: raw_token.text,
   2188    type: raw_token.type
   2189  };
   2190 
   2191  printer.set_space_before_token(raw_token.newlines || raw_token.whitespace_before !== '', true);
   2192  if (last_tag_token.is_unformatted) {
   2193    printer.add_raw_token(raw_token);
   2194  } else if (last_tag_token.tag_start_char === '{' && raw_token.type === TOKEN.TEXT) {
   2195    // For the insides of handlebars allow newlines or a single space between open and contents
   2196    if (printer.print_preserved_newlines(raw_token)) {
   2197      raw_token.newlines = 0;
   2198      printer.add_raw_token(raw_token);
   2199    } else {
   2200      printer.print_token(raw_token);
   2201    }
   2202  } else {
   2203    if (raw_token.type === TOKEN.ATTRIBUTE) {
   2204      printer.set_space_before_token(true);
   2205      last_tag_token.attr_count += 1;
   2206    } else if (raw_token.type === TOKEN.EQUALS) { //no space before =
   2207      printer.set_space_before_token(false);
   2208    } else if (raw_token.type === TOKEN.VALUE && raw_token.previous.type === TOKEN.EQUALS) { //no space before value
   2209      printer.set_space_before_token(false);
   2210    }
   2211 
   2212    if (raw_token.type === TOKEN.ATTRIBUTE && last_tag_token.tag_start_char === '<') {
   2213      if (this._is_wrap_attributes_preserve || this._is_wrap_attributes_preserve_aligned) {
   2214        printer.traverse_whitespace(raw_token);
   2215        wrapped = wrapped || raw_token.newlines !== 0;
   2216      }
   2217 
   2218 
   2219      if (this._is_wrap_attributes_force) {
   2220        var force_attr_wrap = last_tag_token.attr_count > 1;
   2221        if (this._is_wrap_attributes_force_expand_multiline && last_tag_token.attr_count === 1) {
   2222          var is_only_attribute = true;
   2223          var peek_index = 0;
   2224          var peek_token;
   2225          do {
   2226            peek_token = tokens.peek(peek_index);
   2227            if (peek_token.type === TOKEN.ATTRIBUTE) {
   2228              is_only_attribute = false;
   2229              break;
   2230            }
   2231            peek_index += 1;
   2232          } while (peek_index < 4 && peek_token.type !== TOKEN.EOF && peek_token.type !== TOKEN.TAG_CLOSE);
   2233 
   2234          force_attr_wrap = !is_only_attribute;
   2235        }
   2236 
   2237        if (force_attr_wrap) {
   2238          printer.print_newline(false);
   2239          wrapped = true;
   2240        }
   2241      }
   2242    }
   2243    printer.print_token(raw_token);
   2244    wrapped = wrapped || printer.previous_token_wrapped();
   2245    last_tag_token.has_wrapped_attrs = wrapped;
   2246  }
   2247  return parser_token;
   2248 };
   2249 
   2250 Beautifier.prototype._handle_text = function(printer, raw_token, last_tag_token) {
   2251  var parser_token = {
   2252    text: raw_token.text,
   2253    type: 'TK_CONTENT'
   2254  };
   2255  if (last_tag_token.custom_beautifier_name) { //check if we need to format javascript
   2256    this._print_custom_beatifier_text(printer, raw_token, last_tag_token);
   2257  } else if (last_tag_token.is_unformatted || last_tag_token.is_content_unformatted) {
   2258    printer.add_raw_token(raw_token);
   2259  } else {
   2260    printer.traverse_whitespace(raw_token);
   2261    printer.print_token(raw_token);
   2262  }
   2263  return parser_token;
   2264 };
   2265 
   2266 Beautifier.prototype._print_custom_beatifier_text = function(printer, raw_token, last_tag_token) {
   2267  var local = this;
   2268  if (raw_token.text !== '') {
   2269 
   2270    var text = raw_token.text,
   2271      _beautifier,
   2272      script_indent_level = 1,
   2273      pre = '',
   2274      post = '';
   2275    if (last_tag_token.custom_beautifier_name === 'javascript' && typeof this._js_beautify === 'function') {
   2276      _beautifier = this._js_beautify;
   2277    } else if (last_tag_token.custom_beautifier_name === 'css' && typeof this._css_beautify === 'function') {
   2278      _beautifier = this._css_beautify;
   2279    } else if (last_tag_token.custom_beautifier_name === 'html') {
   2280      _beautifier = function(html_source, options) {
   2281        var beautifier = new Beautifier(html_source, options, local._js_beautify, local._css_beautify);
   2282        return beautifier.beautify();
   2283      };
   2284    }
   2285 
   2286    if (this._options.indent_scripts === "keep") {
   2287      script_indent_level = 0;
   2288    } else if (this._options.indent_scripts === "separate") {
   2289      script_indent_level = -printer.indent_level;
   2290    }
   2291 
   2292    var indentation = printer.get_full_indent(script_indent_level);
   2293 
   2294    // if there is at least one empty line at the end of this text, strip it
   2295    // we'll be adding one back after the text but before the containing tag.
   2296    text = text.replace(/\n[ \t]*$/, '');
   2297 
   2298    // Handle the case where content is wrapped in a comment or cdata.
   2299    if (last_tag_token.custom_beautifier_name !== 'html' &&
   2300      text[0] === '<' && text.match(/^(<!--|<!\[CDATA\[)/)) {
   2301      var matched = /^(<!--[^\n]*|<!\[CDATA\[)(\n?)([ \t\n]*)([\s\S]*)(-->|]]>)$/.exec(text);
   2302 
   2303      // if we start to wrap but don't finish, print raw
   2304      if (!matched) {
   2305        printer.add_raw_token(raw_token);
   2306        return;
   2307      }
   2308 
   2309      pre = indentation + matched[1] + '\n';
   2310      text = matched[4];
   2311      if (matched[5]) {
   2312        post = indentation + matched[5];
   2313      }
   2314 
   2315      // if there is at least one empty line at the end of this text, strip it
   2316      // we'll be adding one back after the text but before the containing tag.
   2317      text = text.replace(/\n[ \t]*$/, '');
   2318 
   2319      if (matched[2] || matched[3].indexOf('\n') !== -1) {
   2320        // if the first line of the non-comment text has spaces
   2321        // use that as the basis for indenting in null case.
   2322        matched = matched[3].match(/[ \t]+$/);
   2323        if (matched) {
   2324          raw_token.whitespace_before = matched[0];
   2325        }
   2326      }
   2327    }
   2328 
   2329    if (text) {
   2330      if (_beautifier) {
   2331 
   2332        // call the Beautifier if avaliable
   2333        var Child_options = function() {
   2334          this.eol = '\n';
   2335        };
   2336        Child_options.prototype = this._options.raw_options;
   2337        var child_options = new Child_options();
   2338        text = _beautifier(indentation + text, child_options);
   2339      } else {
   2340        // simply indent the string otherwise
   2341        var white = raw_token.whitespace_before;
   2342        if (white) {
   2343          text = text.replace(new RegExp('\n(' + white + ')?', 'g'), '\n');
   2344        }
   2345 
   2346        text = indentation + text.replace(/\n/g, '\n' + indentation);
   2347      }
   2348    }
   2349 
   2350    if (pre) {
   2351      if (!text) {
   2352        text = pre + post;
   2353      } else {
   2354        text = pre + text + '\n' + post;
   2355      }
   2356    }
   2357 
   2358    printer.print_newline(false);
   2359    if (text) {
   2360      raw_token.text = text;
   2361      raw_token.whitespace_before = '';
   2362      raw_token.newlines = 0;
   2363      printer.add_raw_token(raw_token);
   2364      printer.print_newline(true);
   2365    }
   2366  }
   2367 };
   2368 
   2369 Beautifier.prototype._handle_tag_open = function(printer, raw_token, last_tag_token, last_token) {
   2370  var parser_token = this._get_tag_open_token(raw_token);
   2371 
   2372  if ((last_tag_token.is_unformatted || last_tag_token.is_content_unformatted) &&
   2373    !last_tag_token.is_empty_element &&
   2374    raw_token.type === TOKEN.TAG_OPEN && raw_token.text.indexOf('</') === 0) {
   2375    // End element tags for unformatted or content_unformatted elements
   2376    // are printed raw to keep any newlines inside them exactly the same.
   2377    printer.add_raw_token(raw_token);
   2378    parser_token.start_tag_token = this._tag_stack.try_pop(parser_token.tag_name);
   2379  } else {
   2380    printer.traverse_whitespace(raw_token);
   2381    this._set_tag_position(printer, raw_token, parser_token, last_tag_token, last_token);
   2382    if (!parser_token.is_inline_element) {
   2383      printer.set_wrap_point();
   2384    }
   2385    printer.print_token(raw_token);
   2386  }
   2387 
   2388  //indent attributes an auto, forced, aligned or forced-align line-wrap
   2389  if (this._is_wrap_attributes_force_aligned || this._is_wrap_attributes_aligned_multiple || this._is_wrap_attributes_preserve_aligned) {
   2390    parser_token.alignment_size = raw_token.text.length + 1;
   2391  }
   2392 
   2393  if (!parser_token.tag_complete && !parser_token.is_unformatted) {
   2394    printer.alignment_size = parser_token.alignment_size;
   2395  }
   2396 
   2397  return parser_token;
   2398 };
   2399 
   2400 var TagOpenParserToken = function(parent, raw_token) {
   2401  this.parent = parent || null;
   2402  this.text = '';
   2403  this.type = 'TK_TAG_OPEN';
   2404  this.tag_name = '';
   2405  this.is_inline_element = false;
   2406  this.is_unformatted = false;
   2407  this.is_content_unformatted = false;
   2408  this.is_empty_element = false;
   2409  this.is_start_tag = false;
   2410  this.is_end_tag = false;
   2411  this.indent_content = false;
   2412  this.multiline_content = false;
   2413  this.custom_beautifier_name = null;
   2414  this.start_tag_token = null;
   2415  this.attr_count = 0;
   2416  this.has_wrapped_attrs = false;
   2417  this.alignment_size = 0;
   2418  this.tag_complete = false;
   2419  this.tag_start_char = '';
   2420  this.tag_check = '';
   2421 
   2422  if (!raw_token) {
   2423    this.tag_complete = true;
   2424  } else {
   2425    var tag_check_match;
   2426 
   2427    this.tag_start_char = raw_token.text[0];
   2428    this.text = raw_token.text;
   2429 
   2430    if (this.tag_start_char === '<') {
   2431      tag_check_match = raw_token.text.match(/^<([^\s>]*)/);
   2432      this.tag_check = tag_check_match ? tag_check_match[1] : '';
   2433    } else {
   2434      tag_check_match = raw_token.text.match(/^{{(?:[\^]|#\*?)?([^\s}]+)/);
   2435      this.tag_check = tag_check_match ? tag_check_match[1] : '';
   2436 
   2437      // handle "{{#> myPartial}}
   2438      if (raw_token.text === '{{#>' && this.tag_check === '>' && raw_token.next !== null) {
   2439        this.tag_check = raw_token.next.text;
   2440      }
   2441    }
   2442    this.tag_check = this.tag_check.toLowerCase();
   2443 
   2444    if (raw_token.type === TOKEN.COMMENT) {
   2445      this.tag_complete = true;
   2446    }
   2447 
   2448    this.is_start_tag = this.tag_check.charAt(0) !== '/';
   2449    this.tag_name = !this.is_start_tag ? this.tag_check.substr(1) : this.tag_check;
   2450    this.is_end_tag = !this.is_start_tag ||
   2451      (raw_token.closed && raw_token.closed.text === '/>');
   2452 
   2453    // handlebars tags that don't start with # or ^ are single_tags, and so also start and end.
   2454    this.is_end_tag = this.is_end_tag ||
   2455      (this.tag_start_char === '{' && (this.text.length < 3 || (/[^#\^]/.test(this.text.charAt(2)))));
   2456  }
   2457 };
   2458 
   2459 Beautifier.prototype._get_tag_open_token = function(raw_token) { //function to get a full tag and parse its type
   2460  var parser_token = new TagOpenParserToken(this._tag_stack.get_parser_token(), raw_token);
   2461 
   2462  parser_token.alignment_size = this._options.wrap_attributes_indent_size;
   2463 
   2464  parser_token.is_end_tag = parser_token.is_end_tag ||
   2465    in_array(parser_token.tag_check, this._options.void_elements);
   2466 
   2467  parser_token.is_empty_element = parser_token.tag_complete ||
   2468    (parser_token.is_start_tag && parser_token.is_end_tag);
   2469 
   2470  parser_token.is_unformatted = !parser_token.tag_complete && in_array(parser_token.tag_check, this._options.unformatted);
   2471  parser_token.is_content_unformatted = !parser_token.is_empty_element && in_array(parser_token.tag_check, this._options.content_unformatted);
   2472  parser_token.is_inline_element = in_array(parser_token.tag_name, this._options.inline) || parser_token.tag_start_char === '{';
   2473 
   2474  return parser_token;
   2475 };
   2476 
   2477 Beautifier.prototype._set_tag_position = function(printer, raw_token, parser_token, last_tag_token, last_token) {
   2478 
   2479  if (!parser_token.is_empty_element) {
   2480    if (parser_token.is_end_tag) { //this tag is a double tag so check for tag-ending
   2481      parser_token.start_tag_token = this._tag_stack.try_pop(parser_token.tag_name); //remove it and all ancestors
   2482    } else { // it's a start-tag
   2483      // check if this tag is starting an element that has optional end element
   2484      // and do an ending needed
   2485      if (this._do_optional_end_element(parser_token)) {
   2486        if (!parser_token.is_inline_element) {
   2487          printer.print_newline(false);
   2488        }
   2489      }
   2490 
   2491      this._tag_stack.record_tag(parser_token); //push it on the tag stack
   2492 
   2493      if ((parser_token.tag_name === 'script' || parser_token.tag_name === 'style') &&
   2494        !(parser_token.is_unformatted || parser_token.is_content_unformatted)) {
   2495        parser_token.custom_beautifier_name = get_custom_beautifier_name(parser_token.tag_check, raw_token);
   2496      }
   2497    }
   2498  }
   2499 
   2500  if (in_array(parser_token.tag_check, this._options.extra_liners)) { //check if this double needs an extra line
   2501    printer.print_newline(false);
   2502    if (!printer._output.just_added_blankline()) {
   2503      printer.print_newline(true);
   2504    }
   2505  }
   2506 
   2507  if (parser_token.is_empty_element) { //if this tag name is a single tag type (either in the list or has a closing /)
   2508 
   2509    // if you hit an else case, reset the indent level if you are inside an:
   2510    // 'if', 'unless', or 'each' block.
   2511    if (parser_token.tag_start_char === '{' && parser_token.tag_check === 'else') {
   2512      this._tag_stack.indent_to_tag(['if', 'unless', 'each']);
   2513      parser_token.indent_content = true;
   2514      // Don't add a newline if opening {{#if}} tag is on the current line
   2515      var foundIfOnCurrentLine = printer.current_line_has_match(/{{#if/);
   2516      if (!foundIfOnCurrentLine) {
   2517        printer.print_newline(false);
   2518      }
   2519    }
   2520 
   2521    // Don't add a newline before elements that should remain where they are.
   2522    if (parser_token.tag_name === '!--' && last_token.type === TOKEN.TAG_CLOSE &&
   2523      last_tag_token.is_end_tag && parser_token.text.indexOf('\n') === -1) {
   2524      //Do nothing. Leave comments on same line.
   2525    } else {
   2526      if (!(parser_token.is_inline_element || parser_token.is_unformatted)) {
   2527        printer.print_newline(false);
   2528      }
   2529      this._calcluate_parent_multiline(printer, parser_token);
   2530    }
   2531  } else if (parser_token.is_end_tag) { //this tag is a double tag so check for tag-ending
   2532    var do_end_expand = false;
   2533 
   2534    // deciding whether a block is multiline should not be this hard
   2535    do_end_expand = parser_token.start_tag_token && parser_token.start_tag_token.multiline_content;
   2536    do_end_expand = do_end_expand || (!parser_token.is_inline_element &&
   2537      !(last_tag_token.is_inline_element || last_tag_token.is_unformatted) &&
   2538      !(last_token.type === TOKEN.TAG_CLOSE && parser_token.start_tag_token === last_tag_token) &&
   2539      last_token.type !== 'TK_CONTENT'
   2540    );
   2541 
   2542    if (parser_token.is_content_unformatted || parser_token.is_unformatted) {
   2543      do_end_expand = false;
   2544    }
   2545 
   2546    if (do_end_expand) {
   2547      printer.print_newline(false);
   2548    }
   2549  } else { // it's a start-tag
   2550    parser_token.indent_content = !parser_token.custom_beautifier_name;
   2551 
   2552    if (parser_token.tag_start_char === '<') {
   2553      if (parser_token.tag_name === 'html') {
   2554        parser_token.indent_content = this._options.indent_inner_html;
   2555      } else if (parser_token.tag_name === 'head') {
   2556        parser_token.indent_content = this._options.indent_head_inner_html;
   2557      } else if (parser_token.tag_name === 'body') {
   2558        parser_token.indent_content = this._options.indent_body_inner_html;
   2559      }
   2560    }
   2561 
   2562    if (!(parser_token.is_inline_element || parser_token.is_unformatted) &&
   2563      (last_token.type !== 'TK_CONTENT' || parser_token.is_content_unformatted)) {
   2564      printer.print_newline(false);
   2565    }
   2566 
   2567    this._calcluate_parent_multiline(printer, parser_token);
   2568  }
   2569 };
   2570 
   2571 Beautifier.prototype._calcluate_parent_multiline = function(printer, parser_token) {
   2572  if (parser_token.parent && printer._output.just_added_newline() &&
   2573    !((parser_token.is_inline_element || parser_token.is_unformatted) && parser_token.parent.is_inline_element)) {
   2574    parser_token.parent.multiline_content = true;
   2575  }
   2576 };
   2577 
   2578 //To be used for <p> tag special case:
   2579 var p_closers = ['address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'];
   2580 var p_parent_excludes = ['a', 'audio', 'del', 'ins', 'map', 'noscript', 'video'];
   2581 
   2582 Beautifier.prototype._do_optional_end_element = function(parser_token) {
   2583  var result = null;
   2584  // NOTE: cases of "if there is no more content in the parent element"
   2585  // are handled automatically by the beautifier.
   2586  // It assumes parent or ancestor close tag closes all children.
   2587  // https://www.w3.org/TR/html5/syntax.html#optional-tags
   2588  if (parser_token.is_empty_element || !parser_token.is_start_tag || !parser_token.parent) {
   2589    return;
   2590 
   2591  }
   2592 
   2593  if (parser_token.tag_name === 'body') {
   2594    // A head element’s end tag may be omitted if the head element is not immediately followed by a space character or a comment.
   2595    result = result || this._tag_stack.try_pop('head');
   2596 
   2597    //} else if (parser_token.tag_name === 'body') {
   2598    // DONE: A body element’s end tag may be omitted if the body element is not immediately followed by a comment.
   2599 
   2600  } else if (parser_token.tag_name === 'li') {
   2601    // An li element’s end tag may be omitted if the li element is immediately followed by another li element or if there is no more content in the parent element.
   2602    result = result || this._tag_stack.try_pop('li', ['ol', 'ul']);
   2603 
   2604  } else if (parser_token.tag_name === 'dd' || parser_token.tag_name === 'dt') {
   2605    // A dd element’s end tag may be omitted if the dd element is immediately followed by another dd element or a dt element, or if there is no more content in the parent element.
   2606    // A dt element’s end tag may be omitted if the dt element is immediately followed by another dt element or a dd element.
   2607    result = result || this._tag_stack.try_pop('dt', ['dl']);
   2608    result = result || this._tag_stack.try_pop('dd', ['dl']);
   2609 
   2610 
   2611  } else if (parser_token.parent.tag_name === 'p' && p_closers.indexOf(parser_token.tag_name) !== -1) {
   2612    // IMPORTANT: this else-if works because p_closers has no overlap with any other element we look for in this method
   2613    // check for the parent element is an HTML element that is not an <a>, <audio>, <del>, <ins>, <map>, <noscript>, or <video> element,  or an autonomous custom element.
   2614    // To do this right, this needs to be coded as an inclusion of the inverse of the exclusion above.
   2615    // But to start with (if we ignore "autonomous custom elements") the exclusion would be fine.
   2616    var p_parent = parser_token.parent.parent;
   2617    if (!p_parent || p_parent_excludes.indexOf(p_parent.tag_name) === -1) {
   2618      result = result || this._tag_stack.try_pop('p');
   2619    }
   2620  } else if (parser_token.tag_name === 'rp' || parser_token.tag_name === 'rt') {
   2621    // An rt element’s end tag may be omitted if the rt element is immediately followed by an rt or rp element, or if there is no more content in the parent element.
   2622    // An rp element’s end tag may be omitted if the rp element is immediately followed by an rt or rp element, or if there is no more content in the parent element.
   2623    result = result || this._tag_stack.try_pop('rt', ['ruby', 'rtc']);
   2624    result = result || this._tag_stack.try_pop('rp', ['ruby', 'rtc']);
   2625 
   2626  } else if (parser_token.tag_name === 'optgroup') {
   2627    // An optgroup element’s end tag may be omitted if the optgroup element is immediately followed by another optgroup element, or if there is no more content in the parent element.
   2628    // An option element’s end tag may be omitted if the option element is immediately followed by another option element, or if it is immediately followed by an optgroup element, or if there is no more content in the parent element.
   2629    result = result || this._tag_stack.try_pop('optgroup', ['select']);
   2630    //result = result || this._tag_stack.try_pop('option', ['select']);
   2631 
   2632  } else if (parser_token.tag_name === 'option') {
   2633    // An option element’s end tag may be omitted if the option element is immediately followed by another option element, or if it is immediately followed by an optgroup element, or if there is no more content in the parent element.
   2634    result = result || this._tag_stack.try_pop('option', ['select', 'datalist', 'optgroup']);
   2635 
   2636  } else if (parser_token.tag_name === 'colgroup') {
   2637    // DONE: A colgroup element’s end tag may be omitted if the colgroup element is not immediately followed by a space character or a comment.
   2638    // A caption element's end tag may be ommitted if a colgroup, thead, tfoot, tbody, or tr element is started.
   2639    result = result || this._tag_stack.try_pop('caption', ['table']);
   2640 
   2641  } else if (parser_token.tag_name === 'thead') {
   2642    // A colgroup element's end tag may be ommitted if a thead, tfoot, tbody, or tr element is started.
   2643    // A caption element's end tag may be ommitted if a colgroup, thead, tfoot, tbody, or tr element is started.
   2644    result = result || this._tag_stack.try_pop('caption', ['table']);
   2645    result = result || this._tag_stack.try_pop('colgroup', ['table']);
   2646 
   2647    //} else if (parser_token.tag_name === 'caption') {
   2648    // DONE: A caption element’s end tag may be omitted if the caption element is not immediately followed by a space character or a comment.
   2649 
   2650  } else if (parser_token.tag_name === 'tbody' || parser_token.tag_name === 'tfoot') {
   2651    // A thead element’s end tag may be omitted if the thead element is immediately followed by a tbody or tfoot element.
   2652    // A tbody element’s end tag may be omitted if the tbody element is immediately followed by a tbody or tfoot element, or if there is no more content in the parent element.
   2653    // A colgroup element's end tag may be ommitted if a thead, tfoot, tbody, or tr element is started.
   2654    // A caption element's end tag may be ommitted if a colgroup, thead, tfoot, tbody, or tr element is started.
   2655    result = result || this._tag_stack.try_pop('caption', ['table']);
   2656    result = result || this._tag_stack.try_pop('colgroup', ['table']);
   2657    result = result || this._tag_stack.try_pop('thead', ['table']);
   2658    result = result || this._tag_stack.try_pop('tbody', ['table']);
   2659 
   2660    //} else if (parser_token.tag_name === 'tfoot') {
   2661    // DONE: A tfoot element’s end tag may be omitted if there is no more content in the parent element.
   2662 
   2663  } else if (parser_token.tag_name === 'tr') {
   2664    // A tr element’s end tag may be omitted if the tr element is immediately followed by another tr element, or if there is no more content in the parent element.
   2665    // A colgroup element's end tag may be ommitted if a thead, tfoot, tbody, or tr element is started.
   2666    // A caption element's end tag may be ommitted if a colgroup, thead, tfoot, tbody, or tr element is started.
   2667    result = result || this._tag_stack.try_pop('caption', ['table']);
   2668    result = result || this._tag_stack.try_pop('colgroup', ['table']);
   2669    result = result || this._tag_stack.try_pop('tr', ['table', 'thead', 'tbody', 'tfoot']);
   2670 
   2671  } else if (parser_token.tag_name === 'th' || parser_token.tag_name === 'td') {
   2672    // A td element’s end tag may be omitted if the td element is immediately followed by a td or th element, or if there is no more content in the parent element.
   2673    // A th element’s end tag may be omitted if the th element is immediately followed by a td or th element, or if there is no more content in the parent element.
   2674    result = result || this._tag_stack.try_pop('td', ['table', 'thead', 'tbody', 'tfoot', 'tr']);
   2675    result = result || this._tag_stack.try_pop('th', ['table', 'thead', 'tbody', 'tfoot', 'tr']);
   2676  }
   2677 
   2678  // Start element omission not handled currently
   2679  // A head element’s start tag may be omitted if the element is empty, or if the first thing inside the head element is an element.
   2680  // A tbody element’s start tag may be omitted if the first thing inside the tbody element is a tr element, and if the element is not immediately preceded by a tbody, thead, or tfoot element whose end tag has been omitted. (It can’t be omitted if the element is empty.)
   2681  // A colgroup element’s start tag may be omitted if the first thing inside the colgroup element is a col element, and if the element is not immediately preceded by another colgroup element whose end tag has been omitted. (It can’t be omitted if the element is empty.)
   2682 
   2683  // Fix up the parent of the parser token
   2684  parser_token.parent = this._tag_stack.get_parser_token();
   2685 
   2686  return result;
   2687 };
   2688 
   2689 module.exports.Beautifier = Beautifier;
   2690 
   2691 
   2692 /***/ }),
   2693 /* 20 */
   2694 /***/ (function(module, exports, __webpack_require__) {
   2695 
   2696 "use strict";
   2697 /*jshint node:true */
   2698 /*
   2699 
   2700  The MIT License (MIT)
   2701 
   2702  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
   2703 
   2704  Permission is hereby granted, free of charge, to any person
   2705  obtaining a copy of this software and associated documentation files
   2706  (the "Software"), to deal in the Software without restriction,
   2707  including without limitation the rights to use, copy, modify, merge,
   2708  publish, distribute, sublicense, and/or sell copies of the Software,
   2709  and to permit persons to whom the Software is furnished to do so,
   2710  subject to the following conditions:
   2711 
   2712  The above copyright notice and this permission notice shall be
   2713  included in all copies or substantial portions of the Software.
   2714 
   2715  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   2716  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   2717  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   2718  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   2719  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   2720  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   2721  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   2722  SOFTWARE.
   2723 */
   2724 
   2725 
   2726 
   2727 var BaseOptions = __webpack_require__(6).Options;
   2728 
   2729 function Options(options) {
   2730  BaseOptions.call(this, options, 'html');
   2731  if (this.templating.length === 1 && this.templating[0] === 'auto') {
   2732    this.templating = ['django', 'erb', 'handlebars', 'php'];
   2733  }
   2734 
   2735  this.indent_inner_html = this._get_boolean('indent_inner_html');
   2736  this.indent_body_inner_html = this._get_boolean('indent_body_inner_html', true);
   2737  this.indent_head_inner_html = this._get_boolean('indent_head_inner_html', true);
   2738 
   2739  this.indent_handlebars = this._get_boolean('indent_handlebars', true);
   2740  this.wrap_attributes = this._get_selection('wrap_attributes',
   2741    ['auto', 'force', 'force-aligned', 'force-expand-multiline', 'aligned-multiple', 'preserve', 'preserve-aligned']);
   2742  this.wrap_attributes_indent_size = this._get_number('wrap_attributes_indent_size', this.indent_size);
   2743  this.extra_liners = this._get_array('extra_liners', ['head', 'body', '/html']);
   2744 
   2745  // Block vs inline elements
   2746  // https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements
   2747  // https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements
   2748  // https://www.w3.org/TR/html5/dom.html#phrasing-content
   2749  this.inline = this._get_array('inline', [
   2750    'a', 'abbr', 'area', 'audio', 'b', 'bdi', 'bdo', 'br', 'button', 'canvas', 'cite',
   2751    'code', 'data', 'datalist', 'del', 'dfn', 'em', 'embed', 'i', 'iframe', 'img',
   2752    'input', 'ins', 'kbd', 'keygen', 'label', 'map', 'mark', 'math', 'meter', 'noscript',
   2753    'object', 'output', 'progress', 'q', 'ruby', 's', 'samp', /* 'script', */ 'select', 'small',
   2754    'span', 'strong', 'sub', 'sup', 'svg', 'template', 'textarea', 'time', 'u', 'var',
   2755    'video', 'wbr', 'text',
   2756    // obsolete inline tags
   2757    'acronym', 'big', 'strike', 'tt'
   2758  ]);
   2759  this.void_elements = this._get_array('void_elements', [
   2760    // HTLM void elements - aka self-closing tags - aka singletons
   2761    // https://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements
   2762    'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen',
   2763    'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr',
   2764    // NOTE: Optional tags are too complex for a simple list
   2765    // they are hard coded in _do_optional_end_element
   2766 
   2767    // Doctype and xml elements
   2768    '!doctype', '?xml',
   2769 
   2770    // obsolete tags
   2771    // basefont: https://www.computerhope.com/jargon/h/html-basefont-tag.htm
   2772    // isndex: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/isindex
   2773    'basefont', 'isindex'
   2774  ]);
   2775  this.unformatted = this._get_array('unformatted', []);
   2776  this.content_unformatted = this._get_array('content_unformatted', [
   2777    'pre', 'textarea'
   2778  ]);
   2779  this.unformatted_content_delimiter = this._get_characters('unformatted_content_delimiter');
   2780  this.indent_scripts = this._get_selection('indent_scripts', ['normal', 'keep', 'separate']);
   2781 
   2782 }
   2783 Options.prototype = new BaseOptions();
   2784 
   2785 
   2786 
   2787 module.exports.Options = Options;
   2788 
   2789 
   2790 /***/ }),
   2791 /* 21 */
   2792 /***/ (function(module, exports, __webpack_require__) {
   2793 
   2794 "use strict";
   2795 /*jshint node:true */
   2796 /*
   2797 
   2798  The MIT License (MIT)
   2799 
   2800  Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
   2801 
   2802  Permission is hereby granted, free of charge, to any person
   2803  obtaining a copy of this software and associated documentation files
   2804  (the "Software"), to deal in the Software without restriction,
   2805  including without limitation the rights to use, copy, modify, merge,
   2806  publish, distribute, sublicense, and/or sell copies of the Software,
   2807  and to permit persons to whom the Software is furnished to do so,
   2808  subject to the following conditions:
   2809 
   2810  The above copyright notice and this permission notice shall be
   2811  included in all copies or substantial portions of the Software.
   2812 
   2813  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   2814  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   2815  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   2816  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   2817  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   2818  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   2819  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   2820  SOFTWARE.
   2821 */
   2822 
   2823 
   2824 
   2825 var BaseTokenizer = __webpack_require__(9).Tokenizer;
   2826 var BASETOKEN = __webpack_require__(9).TOKEN;
   2827 var Directives = __webpack_require__(13).Directives;
   2828 var TemplatablePattern = __webpack_require__(14).TemplatablePattern;
   2829 var Pattern = __webpack_require__(12).Pattern;
   2830 
   2831 var TOKEN = {
   2832  TAG_OPEN: 'TK_TAG_OPEN',
   2833  TAG_CLOSE: 'TK_TAG_CLOSE',
   2834  ATTRIBUTE: 'TK_ATTRIBUTE',
   2835  EQUALS: 'TK_EQUALS',
   2836  VALUE: 'TK_VALUE',
   2837  COMMENT: 'TK_COMMENT',
   2838  TEXT: 'TK_TEXT',
   2839  UNKNOWN: 'TK_UNKNOWN',
   2840  START: BASETOKEN.START,
   2841  RAW: BASETOKEN.RAW,
   2842  EOF: BASETOKEN.EOF
   2843 };
   2844 
   2845 var directives_core = new Directives(/<\!--/, /-->/);
   2846 
   2847 var Tokenizer = function(input_string, options) {
   2848  BaseTokenizer.call(this, input_string, options);
   2849  this._current_tag_name = '';
   2850 
   2851  // Words end at whitespace or when a tag starts
   2852  // if we are indenting handlebars, they are considered tags
   2853  var templatable_reader = new TemplatablePattern(this._input).read_options(this._options);
   2854  var pattern_reader = new Pattern(this._input);
   2855 
   2856  this.__patterns = {
   2857    word: templatable_reader.until(/[\n\r\t <]/),
   2858    single_quote: templatable_reader.until_after(/'/),
   2859    double_quote: templatable_reader.until_after(/"/),
   2860    attribute: templatable_reader.until(/[\n\r\t =>]|\/>/),
   2861    element_name: templatable_reader.until(/[\n\r\t >\/]/),
   2862 
   2863    handlebars_comment: pattern_reader.starting_with(/{{!--/).until_after(/--}}/),
   2864    handlebars: pattern_reader.starting_with(/{{/).until_after(/}}/),
   2865    handlebars_open: pattern_reader.until(/[\n\r\t }]/),
   2866    handlebars_raw_close: pattern_reader.until(/}}/),
   2867    comment: pattern_reader.starting_with(/<!--/).until_after(/-->/),
   2868    cdata: pattern_reader.starting_with(/<!\[CDATA\[/).until_after(/]]>/),
   2869    // https://en.wikipedia.org/wiki/Conditional_comment
   2870    conditional_comment: pattern_reader.starting_with(/<!\[/).until_after(/]>/),
   2871    processing: pattern_reader.starting_with(/<\?/).until_after(/\?>/)
   2872  };
   2873 
   2874  if (this._options.indent_handlebars) {
   2875    this.__patterns.word = this.__patterns.word.exclude('handlebars');
   2876  }
   2877 
   2878  this._unformatted_content_delimiter = null;
   2879 
   2880  if (this._options.unformatted_content_delimiter) {
   2881    var literal_regexp = this._input.get_literal_regexp(this._options.unformatted_content_delimiter);
   2882    this.__patterns.unformatted_content_delimiter =
   2883      pattern_reader.matching(literal_regexp)
   2884      .until_after(literal_regexp);
   2885  }
   2886 };
   2887 Tokenizer.prototype = new BaseTokenizer();
   2888 
   2889 Tokenizer.prototype._is_comment = function(current_token) { // jshint unused:false
   2890  return false; //current_token.type === TOKEN.COMMENT || current_token.type === TOKEN.UNKNOWN;
   2891 };
   2892 
   2893 Tokenizer.prototype._is_opening = function(current_token) {
   2894  return current_token.type === TOKEN.TAG_OPEN;
   2895 };
   2896 
   2897 Tokenizer.prototype._is_closing = function(current_token, open_token) {
   2898  return current_token.type === TOKEN.TAG_CLOSE &&
   2899    (open_token && (
   2900      ((current_token.text === '>' || current_token.text === '/>') && open_token.text[0] === '<') ||
   2901      (current_token.text === '}}' && open_token.text[0] === '{' && open_token.text[1] === '{')));
   2902 };
   2903 
   2904 Tokenizer.prototype._reset = function() {
   2905  this._current_tag_name = '';
   2906 };
   2907 
   2908 Tokenizer.prototype._get_next_token = function(previous_token, open_token) { // jshint unused:false
   2909  var token = null;
   2910  this._readWhitespace();
   2911  var c = this._input.peek();
   2912 
   2913  if (c === null) {
   2914    return this._create_token(TOKEN.EOF, '');
   2915  }
   2916 
   2917  token = token || this._read_open_handlebars(c, open_token);
   2918  token = token || this._read_attribute(c, previous_token, open_token);
   2919  token = token || this._read_close(c, open_token);
   2920  token = token || this._read_raw_content(c, previous_token, open_token);
   2921  token = token || this._read_content_word(c);
   2922  token = token || this._read_comment_or_cdata(c);
   2923  token = token || this._read_processing(c);
   2924  token = token || this._read_open(c, open_token);
   2925  token = token || this._create_token(TOKEN.UNKNOWN, this._input.next());
   2926 
   2927  return token;
   2928 };
   2929 
   2930 Tokenizer.prototype._read_comment_or_cdata = function(c) { // jshint unused:false
   2931  var token = null;
   2932  var resulting_string = null;
   2933  var directives = null;
   2934 
   2935  if (c === '<') {
   2936    var peek1 = this._input.peek(1);
   2937    // We treat all comments as literals, even more than preformatted tags
   2938    // we only look for the appropriate closing marker
   2939    if (peek1 === '!') {
   2940      resulting_string = this.__patterns.comment.read();
   2941 
   2942      // only process directive on html comments
   2943      if (resulting_string) {
   2944        directives = directives_core.get_directives(resulting_string);
   2945        if (directives && directives.ignore === 'start') {
   2946          resulting_string += directives_core.readIgnored(this._input);
   2947        }
   2948      } else {
   2949        resulting_string = this.__patterns.cdata.read();
   2950      }
   2951    }
   2952 
   2953    if (resulting_string) {
   2954      token = this._create_token(TOKEN.COMMENT, resulting_string);
   2955      token.directives = directives;
   2956    }
   2957  }
   2958 
   2959  return token;
   2960 };
   2961 
   2962 Tokenizer.prototype._read_processing = function(c) { // jshint unused:false
   2963  var token = null;
   2964  var resulting_string = null;
   2965  var directives = null;
   2966 
   2967  if (c === '<') {
   2968    var peek1 = this._input.peek(1);
   2969    if (peek1 === '!' || peek1 === '?') {
   2970      resulting_string = this.__patterns.conditional_comment.read();
   2971      resulting_string = resulting_string || this.__patterns.processing.read();
   2972    }
   2973 
   2974    if (resulting_string) {
   2975      token = this._create_token(TOKEN.COMMENT, resulting_string);
   2976      token.directives = directives;
   2977    }
   2978  }
   2979 
   2980  return token;
   2981 };
   2982 
   2983 Tokenizer.prototype._read_open = function(c, open_token) {
   2984  var resulting_string = null;
   2985  var token = null;
   2986  if (!open_token) {
   2987    if (c === '<') {
   2988 
   2989      resulting_string = this._input.next();
   2990      if (this._input.peek() === '/') {
   2991        resulting_string += this._input.next();
   2992      }
   2993      resulting_string += this.__patterns.element_name.read();
   2994      token = this._create_token(TOKEN.TAG_OPEN, resulting_string);
   2995    }
   2996  }
   2997  return token;
   2998 };
   2999 
   3000 Tokenizer.prototype._read_open_handlebars = function(c, open_token) {
   3001  var resulting_string = null;
   3002  var token = null;
   3003  if (!open_token) {
   3004    if (this._options.indent_handlebars && c === '{' && this._input.peek(1) === '{') {
   3005      if (this._input.peek(2) === '!') {
   3006        resulting_string = this.__patterns.handlebars_comment.read();
   3007        resulting_string = resulting_string || this.__patterns.handlebars.read();
   3008        token = this._create_token(TOKEN.COMMENT, resulting_string);
   3009      } else {
   3010        resulting_string = this.__patterns.handlebars_open.read();
   3011        token = this._create_token(TOKEN.TAG_OPEN, resulting_string);
   3012      }
   3013    }
   3014  }
   3015  return token;
   3016 };
   3017 
   3018 
   3019 Tokenizer.prototype._read_close = function(c, open_token) {
   3020  var resulting_string = null;
   3021  var token = null;
   3022  if (open_token) {
   3023    if (open_token.text[0] === '<' && (c === '>' || (c === '/' && this._input.peek(1) === '>'))) {
   3024      resulting_string = this._input.next();
   3025      if (c === '/') { //  for close tag "/>"
   3026        resulting_string += this._input.next();
   3027      }
   3028      token = this._create_token(TOKEN.TAG_CLOSE, resulting_string);
   3029    } else if (open_token.text[0] === '{' && c === '}' && this._input.peek(1) === '}') {
   3030      this._input.next();
   3031      this._input.next();
   3032      token = this._create_token(TOKEN.TAG_CLOSE, '}}');
   3033    }
   3034  }
   3035 
   3036  return token;
   3037 };
   3038 
   3039 Tokenizer.prototype._read_attribute = function(c, previous_token, open_token) {
   3040  var token = null;
   3041  var resulting_string = '';
   3042  if (open_token && open_token.text[0] === '<') {
   3043 
   3044    if (c === '=') {
   3045      token = this._create_token(TOKEN.EQUALS, this._input.next());
   3046    } else if (c === '"' || c === "'") {
   3047      var content = this._input.next();
   3048      if (c === '"') {
   3049        content += this.__patterns.double_quote.read();
   3050      } else {
   3051        content += this.__patterns.single_quote.read();
   3052      }
   3053      token = this._create_token(TOKEN.VALUE, content);
   3054    } else {
   3055      resulting_string = this.__patterns.attribute.read();
   3056 
   3057      if (resulting_string) {
   3058        if (previous_token.type === TOKEN.EQUALS) {
   3059          token = this._create_token(TOKEN.VALUE, resulting_string);
   3060        } else {
   3061          token = this._create_token(TOKEN.ATTRIBUTE, resulting_string);
   3062        }
   3063      }
   3064    }
   3065  }
   3066  return token;
   3067 };
   3068 
   3069 Tokenizer.prototype._is_content_unformatted = function(tag_name) {
   3070  // void_elements have no content and so cannot have unformatted content
   3071  // script and style tags should always be read as unformatted content
   3072  // finally content_unformatted and unformatted element contents are unformatted
   3073  return this._options.void_elements.indexOf(tag_name) === -1 &&
   3074    (this._options.content_unformatted.indexOf(tag_name) !== -1 ||
   3075      this._options.unformatted.indexOf(tag_name) !== -1);
   3076 };
   3077 
   3078 
   3079 Tokenizer.prototype._read_raw_content = function(c, previous_token, open_token) { // jshint unused:false
   3080  var resulting_string = '';
   3081  if (open_token && open_token.text[0] === '{') {
   3082    resulting_string = this.__patterns.handlebars_raw_close.read();
   3083  } else if (previous_token.type === TOKEN.TAG_CLOSE &&
   3084    previous_token.opened.text[0] === '<' && previous_token.text[0] !== '/') {
   3085    // ^^ empty tag has no content 
   3086    var tag_name = previous_token.opened.text.substr(1).toLowerCase();
   3087    if (tag_name === 'script' || tag_name === 'style') {
   3088      // Script and style tags are allowed to have comments wrapping their content
   3089      // or just have regular content.
   3090      var token = this._read_comment_or_cdata(c);
   3091      if (token) {
   3092        token.type = TOKEN.TEXT;
   3093        return token;
   3094      }
   3095      resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
   3096    } else if (this._is_content_unformatted(tag_name)) {
   3097 
   3098      resulting_string = this._input.readUntil(new RegExp('</' + tag_name + '[\\n\\r\\t ]*?>', 'ig'));
   3099    }
   3100  }
   3101 
   3102  if (resulting_string) {
   3103    return this._create_token(TOKEN.TEXT, resulting_string);
   3104  }
   3105 
   3106  return null;
   3107 };
   3108 
   3109 Tokenizer.prototype._read_content_word = function(c) {
   3110  var resulting_string = '';
   3111  if (this._options.unformatted_content_delimiter) {
   3112    if (c === this._options.unformatted_content_delimiter[0]) {
   3113      resulting_string = this.__patterns.unformatted_content_delimiter.read();
   3114    }
   3115  }
   3116 
   3117  if (!resulting_string) {
   3118    resulting_string = this.__patterns.word.read();
   3119  }
   3120  if (resulting_string) {
   3121    return this._create_token(TOKEN.TEXT, resulting_string);
   3122  }
   3123 };
   3124 
   3125 module.exports.Tokenizer = Tokenizer;
   3126 module.exports.TOKEN = TOKEN;
   3127 
   3128 
   3129 /***/ })
   3130 /******/ ]);
   3131 var style_html = legacy_beautify_html;
   3132 /* Footer */
   3133 if (typeof define === "function" && define.amd) {
   3134    // Add support for AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- )
   3135    define(["require", "./beautify", "./beautify-css"], function(requireamd) {
   3136        var js_beautify = requireamd("./beautify");
   3137        var css_beautify = requireamd("./beautify-css");
   3138 
   3139        return {
   3140            html_beautify: function(html_source, options) {
   3141                return style_html(html_source, options, js_beautify.js_beautify, css_beautify.css_beautify);
   3142            }
   3143        };
   3144    });
   3145 } else if (typeof exports !== "undefined") {
   3146    // Add support for CommonJS. Just put this file somewhere on your require.paths
   3147    // and you will be able to `var html_beautify = require("beautify").html_beautify`.
   3148    var js_beautify = require('./beautify-js.js');
   3149    var css_beautify = require('./beautify-css.js');
   3150 
   3151    exports.html_beautify = function(html_source, options) {
   3152        return style_html(html_source, options, js_beautify.js_beautify, css_beautify.css_beautify);
   3153    };
   3154 } else if (typeof window !== "undefined") {
   3155    // If we're running a web page and don't have either of the above, add our one global
   3156    window.html_beautify = function(html_source, options) {
   3157        return style_html(html_source, options, window.js_beautify, window.css_beautify);
   3158    };
   3159 } else if (typeof global !== "undefined") {
   3160    // If we don't even have window, try global.
   3161    global.html_beautify = function(html_source, options) {
   3162        return style_html(html_source, options, global.js_beautify, global.css_beautify);
   3163    };
   3164 }
   3165 
   3166 }());