zoukankan      html  css  js  c++  java
  • jsbeautifier + CScript/WScript/JavaScript 编程实现 JavaScript、HTML、CSS 代码格式化 js 脚本命令行工具 并集成到 EditPlus

    
    /*
     * Source Code File Name:
     *            Microshaoft.beautify.CScript.js
     * Microshaoft invent for EditPlus user tool by using WScript");
     * Thanks for "http://jsbeautifier.org/" supply \"https://github.com/einars/js-beautify\"");
     * JavaScript Source References:
     * https://github.com/einars/js-beautify/blob/master/beautify-css.js
     * https://github.com/einars/js-beautify/blob/master/beautify-html.js
     * https://github.com/einars/js-beautify/blob/master/beautify.js
     * https://github.com/einars/js-beautify/blob/master/unpackers/javascriptobfuscator_unpacker.js
     * https://github.com/einars/js-beautify/blob/master/unpackers/myobfuscate_unpacker.js
     * https://github.com/einars/js-beautify/blob/master/unpackers/p_a_c_k_e_r_unpacker.js
     * https://github.com/einars/js-beautify/blob/master/unpackers/urlencode_unpacker.js
     * https://github.com/einars/js-beautify/blob/master/tests/sanitytest.js
     * http://jsbeautifier.org/ HTML source
     */
    // add by Microshaoft begin ===========================================================
    //程序开始
    var args  = WScript.Arguments;
    var s = args(0);
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    // Open the file for input.
    var f = fso.OpenTextFile(s, 1);
    s = "";
    // Read from the file and display the results.
    while (!f.AtEndOfStream)
    {
        s += f.ReadAll();
    }
    f.Close();
    //var s = "adsaasd";
    // add by Microshaoft end ===========================================================
    /*jslint onevar: false, plusplus: false */
    /*
     JS Beautifier
    ---------------
      Written by Einar Lielmanis, <einar@jsbeautifier.org>
          http://jsbeautifier.org/
      Originally converted to javascript by Vital, <vital76@gmail.com>
      "End braces on own line" added by Chris J. Shull, <chrisjshull@gmail.com>
      You are free to use this in any way you want, in case you find this useful or working for you.
      Usage:
        js_beautify(js_source_text);
        js_beautify(js_source_text, options);
      The options are:
        indent_size (default 4)          ?? indentation size,
        indent_char (default space)      ?? character to indent with,
        preserve_newlines (default true) ?? whether existing line breaks should be preserved,
        preserve_max_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk,
        jslint_happy (default false) ?? if true, then jslint-stricter mode is enforced.
                jslint_happy   !jslint_happy
                ---------------------------------
                 function ()      function()
        brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "expand-strict"
                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.
                expand-strict: put brace on own line even in such cases:
                    var a =
                    {
                        a: 5,
                        b: 6
                    }
                This mode may break your scripts - e.g "return { a: 1 }" will be broken into two lines, so beware.
        space_before_conditional: should the space before conditional statement be added, "if(true)" vs "if (true)"
        e.g
        js_beautify(js_source_text, {
          'indent_size': 1,
          'indent_char': '\t'
        });
    */
    function js_beautify(js_source_text, options)
    // add by Microshaoft begin ===========================================================::
    //: String
    // add by Microshaoft end ===========================================================
    {
        //return "";
        var input, output, token_text, last_type, last_text, last_last_text, last_word, flags, flag_store, indent_string;
        var whitespace, wordchar, punct, parser_pos, line_starters, digits;
        var prefix, token_type, do_block_just_closed;
        var wanted_newline, just_added_newline, n_newlines;
        var preindent_string = '';
        // Some interpreters have unexpected results with foo = baz || bar;
        options = options ? options : {};
        var opt_brace_style;
        // compatibility
        if (options.space_after_anon_function !== undefined && options.jslint_happy === undefined)
        {
            options.jslint_happy = options.space_after_anon_function;
        }
        if (options.braces_on_own_line !== undefined)
        { //graceful handling of deprecated option
            opt_brace_style = options.braces_on_own_line ? "expand" : "collapse";
        }
        opt_brace_style = options.brace_style ? options.brace_style : (opt_brace_style ? opt_brace_style : "collapse");
        var opt_indent_size = options.indent_size ? options.indent_size : 4;
        var opt_indent_char = options.indent_char ? options.indent_char : ' ';
        var opt_preserve_newlines = typeof options.preserve_newlines === 'undefined' ? true : options.preserve_newlines;
        var opt_max_preserve_newlines = typeof options.max_preserve_newlines === 'undefined' ? false : options.max_preserve_newlines;
        var opt_jslint_happy = options.jslint_happy === 'undefined' ? false : options.jslint_happy;
        var opt_keep_array_indentation = typeof options.keep_array_indentation === 'undefined' ? false : options.keep_array_indentation;
        var opt_space_before_conditional = typeof options.space_before_conditional === 'undefined' ? true : options.space_before_conditional;
        var opt_indent_case = typeof options.indent_case === 'undefined' ? false : options.indent_case;
        just_added_newline = false;
        // cache the source's length.
        var input_length = js_source_text.length;
        function trim_output(eat_newlines)
        {
            eat_newlines = typeof eat_newlines === 'undefined' ? false : eat_newlines;
            while (output.length && (output[output.length - 1] === ' ' || output[output.length - 1] === indent_string || output[output.length - 1] === preindent_string || (eat_newlines && (output[output.length - 1] === '\n' || output[output.length - 1] === '\r'))))
            {
                output.pop();
            }
        }
        function trim(s)
        {
            return s.replace(/^\s\s*|\s\s*$/, '');
        }
        function force_newline()
        {
            var old_keep_array_indentation = opt_keep_array_indentation;
            opt_keep_array_indentation = false;
            print_newline()
            opt_keep_array_indentation = old_keep_array_indentation;
        }
        function print_newline(ignore_repeated)
        {
            flags.eat_next_space = false;
            if (opt_keep_array_indentation && is_array(flags.mode))
            {
                return;
            }
            ignore_repeated = typeof ignore_repeated === 'undefined' ? true : ignore_repeated;
            flags.if_line = false;
            trim_output();
            if (!output.length)
            {
                return; // no newline on start of file
            }
            if (output[output.length - 1] !== "\n" || !ignore_repeated)
            {
                just_added_newline = true;
                output.push("\n");
            }
            if (preindent_string)
            {
                output.push(preindent_string);
            }
            for (var i = 0; i < flags.indentation_level; i += 1)
            {
                output.push(indent_string);
            }
            if (flags.var_line && flags.var_line_reindented)
            {
                output.push(indent_string); // skip space-stuffing, if indenting with a tab
            }
            if (flags.case_body)
            {
                output.push(indent_string);
            }
        }
        function print_single_space()
        {
            if (last_type === 'TK_COMMENT')
            {
                // no you will not print just a space after a comment
                return print_newline(true);
            }
            if (flags.eat_next_space)
            {
                flags.eat_next_space = false;
                return;
            }
            var last_output = ' ';
            if (output.length)
            {
                last_output = output[output.length - 1];
            }
            if (last_output !== ' ' && last_output !== '\n' && last_output !== indent_string)
            { // prevent occassional duplicate space
                output.push(' ');
            }
        }
        function print_token()
        {
            just_added_newline = false;
            flags.eat_next_space = false;
            output.push(token_text);
        }
        function indent()
        {
            flags.indentation_level += 1;
        }
        function remove_indent()
        {
            if (output.length && output[output.length - 1] === indent_string)
            {
                output.pop();
            }
        }
        function set_mode(mode)
        {
            if (flags)
            {
                flag_store.push(flags);
            }
            flags =
            {
                previous_mode: flags ? flags.mode : 'BLOCK',
                mode: mode,
                var_line: false,
                var_line_tainted: false,
                var_line_reindented: false,
                in_html_comment: false,
                if_line: false,
                in_case: false,
                case_body: false,
                eat_next_space: false,
                indentation_baseline: -1,
                indentation_level: (flags ? flags.indentation_level + (flags.case_body ? 1 : 0) + ((flags.var_line && flags.var_line_reindented) ? 1 : 0) : 0),
                ternary_depth: 0
            };
        }
        function is_array(mode)
        {
            return mode === '[EXPRESSION]' || mode === '[INDENTED-EXPRESSION]';
        }
        function is_expression(mode)
        {
            return in_array(mode, ['[EXPRESSION]', '(EXPRESSION)', '(FOR-EXPRESSION)', '(COND-EXPRESSION)']);
        }
        function restore_mode()
        {
            do_block_just_closed = flags.mode === 'DO_BLOCK';
            if (flag_store.length > 0)
            {
                var mode = flags.mode;
                flags = flag_store.pop();
                flags.previous_mode = mode;
            }
        }
        function all_lines_start_with(lines, c)
        {
            for (var i = 0; i < lines.length; i++)
            {
                if (trim(lines[i])[0] != c)
                {
                    return false;
                }
            }
            return true;
        }
        function is_special_word(word)
        {
            return in_array(word, ['case', 'return', 'do', 'if', 'throw', 'else']);
        }
        function in_array(what, arr)
        {
            for (var i = 0; i < arr.length; i += 1)
            {
                if (arr[i] === what)
                {
                    return true;
                }
            }
            return false;
        }
        function look_up(exclude)
        {
            var local_pos = parser_pos;
            var c = input.charAt(local_pos);
            while (in_array(c, whitespace) && c != exclude)
            {
                local_pos++;
                if (local_pos >= input_length) return 0;
                c = input.charAt(local_pos);
            }
            return c;
        }
        function get_next_token()
        {
            n_newlines = 0;
            if (parser_pos >= input_length)
            {
                return ['', 'TK_EOF'];
            }
            wanted_newline = false;
            var c = input.charAt(parser_pos);
            parser_pos += 1;
            var keep_whitespace = opt_keep_array_indentation && is_array(flags.mode);
            if (keep_whitespace)
            {
                //
                // slight mess to allow nice preservation of array indentation and reindent that correctly
                // first time when we get to the arrays:
                // var a = [
                // ....'something'
                // we make note of whitespace_count = 4 into flags.indentation_baseline
                // so we know that 4 whitespaces in original source match indent_level of reindented source
                //
                // and afterwards, when we get to
                //    'something,
                // .......'something else'
                // we know that this should be indented to indent_level + (7 - indentation_baseline) spaces
                //
                var whitespace_count = 0;
                while (in_array(c, whitespace))
                {
                    if (c === "\n")
                    {
                        trim_output();
                        output.push("\n");
                        just_added_newline = true;
                        whitespace_count = 0;
                    }
                    else
                    {
                        if (c === '\t')
                        {
                            whitespace_count += 4;
                        }
                        else if (c === '\r')
                        {
                            // nothing
                        }
                        else
                        {
                            whitespace_count += 1;
                        }
                    }
                    if (parser_pos >= input_length)
                    {
                        return ['', 'TK_EOF'];
                    }
                    c = input.charAt(parser_pos);
                    parser_pos += 1;
                }
                if (flags.indentation_baseline === -1)
                {
                    flags.indentation_baseline = whitespace_count;
                }
                if (just_added_newline)
                {
                    var i;
                    for (i = 0; i < flags.indentation_level + 1; i += 1)
                    {
                        output.push(indent_string);
                    }
                    if (flags.indentation_baseline !== -1)
                    {
                        for (i = 0; i < whitespace_count - flags.indentation_baseline; i++)
                        {
                            output.push(' ');
                        }
                    }
                }
            }
            else
            {
                while (in_array(c, whitespace))
                {
                    if (c === "\n")
                    {
                        n_newlines += ((opt_max_preserve_newlines) ? (n_newlines <= opt_max_preserve_newlines) ? 1 : 0 : 1);
                    }
                    if (parser_pos >= input_length)
                    {
                        return ['', 'TK_EOF'];
                    }
                    c = input.charAt(parser_pos);
                    parser_pos += 1;
                }
                if (opt_preserve_newlines)
                {
                    if (n_newlines > 1)
                    {
                        for (i = 0; i < n_newlines; i += 1)
                        {
                            print_newline(i === 0);
                            just_added_newline = true;
                        }
                    }
                }
                wanted_newline = n_newlines > 0;
            }
            if (in_array(c, wordchar))
            {
                if (parser_pos < input_length)
                {
                    while (in_array(input.charAt(parser_pos), wordchar))
                    {
                        c += input.charAt(parser_pos);
                        parser_pos += 1;
                        if (parser_pos === input_length)
                        {
                            break;
                        }
                    }
                }
                // small and surprisingly unugly hack for 1E-10 representation
                if (parser_pos !== input_length && c.match(/^[0-9]+[Ee]$/) && (input.charAt(parser_pos) === '-' || input.charAt(parser_pos) === '+'))
                {
                    var sign = input.charAt(parser_pos);
                    parser_pos += 1;
                    var t = get_next_token(parser_pos);
                    c += sign + t[0];
                    return [c, 'TK_WORD'];
                }
                if (c === 'in')
                { // hack for 'in' operator
                    return [c, 'TK_OPERATOR'];
                }
                if (wanted_newline && last_type !== 'TK_OPERATOR' && last_type !== 'TK_EQUALS' && !flags.if_line && (opt_preserve_newlines || last_text !== 'var'))
                {
                    print_newline();
                }
                return [c, 'TK_WORD'];
            }
            if (c === '(' || c === '[')
            {
                return [c, 'TK_START_EXPR'];
            }
            if (c === ')' || c === ']')
            {
                return [c, 'TK_END_EXPR'];
            }
            if (c === '{')
            {
                return [c, 'TK_START_BLOCK'];
            }
            if (c === '}')
            {
                return [c, 'TK_END_BLOCK'];
            }
            if (c === ';')
            {
                return [c, 'TK_SEMICOLON'];
            }
            if (c === '/')
            {
                var comment = '';
                // peek for comment /* ... */
                var inline_comment = true;
                if (input.charAt(parser_pos) === '*')
                {
                    parser_pos += 1;
                    if (parser_pos < input_length)
                    {
                        while (!(input.charAt(parser_pos) === '*' && input.charAt(parser_pos + 1) && input.charAt(parser_pos + 1) === '/') && parser_pos < input_length)
                        {
                            c = input.charAt(parser_pos);
                            comment += c;
                            if (c === '\x0d' || c === '\x0a')
                            {
                                inline_comment = false;
                            }
                            parser_pos += 1;
                            if (parser_pos >= input_length)
                            {
                                break;
                            }
                        }
                    }
                    parser_pos += 2;
                    if (inline_comment && n_newlines == 0)
                    {
                        return ['/*' + comment + '*/', 'TK_INLINE_COMMENT'];
                    }
                    else
                    {
                        return ['/*' + comment + '*/', 'TK_BLOCK_COMMENT'];
                    }
                }
                // peek for comment // ...
                if (input.charAt(parser_pos) === '/')
                {
                    comment = c;
                    while (input.charAt(parser_pos) !== '\r' && input.charAt(parser_pos) !== '\n')
                    {
                        comment += input.charAt(parser_pos);
                        parser_pos += 1;
                        if (parser_pos >= input_length)
                        {
                            break;
                        }
                    }
                    parser_pos += 1;
                    if (wanted_newline)
                    {
                        print_newline();
                    }
                    return [comment, 'TK_COMMENT'];
                }
            }
            if (c === "'" || // string
            c === '"' || // string
            (c === '/' && ((last_type === 'TK_WORD' && is_special_word(last_text)) || (last_text === ')' && in_array(flags.previous_mode, ['(COND-EXPRESSION)', '(FOR-EXPRESSION)'])) || (last_type === 'TK_COMMENT' || last_type === 'TK_START_EXPR' || last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_OPERATOR' || last_type === 'TK_EQUALS' || last_type === 'TK_EOF' || last_type === 'TK_SEMICOLON'))))
            { // regexp
                var sep = c;
                var esc = false;
                var resulting_string = c;
                if (parser_pos < input_length)
                {
                    if (sep === '/')
                    {
                        //
                        // handle regexp separately...
                        //
                        var in_char_class = false;
                        while (esc || in_char_class || input.charAt(parser_pos) !== sep)
                        {
                            resulting_string += input.charAt(parser_pos);
                            if (!esc)
                            {
                                esc = input.charAt(parser_pos) === '\\';
                                if (input.charAt(parser_pos) === '[')
                                {
                                    in_char_class = true;
                                }
                                else if (input.charAt(parser_pos) === ']')
                                {
                                    in_char_class = false;
                                }
                            }
                            else
                            {
                                esc = false;
                            }
                            parser_pos += 1;
                            if (parser_pos >= input_length)
                            {
                                // incomplete string/rexp when end-of-file reached.
                                // bail out with what had been received so far.
                                return [resulting_string, 'TK_STRING'];
                            }
                        }
                    }
                    else
                    {
                        //
                        // and handle string also separately
                        //
                        while (esc || input.charAt(parser_pos) !== sep)
                        {
                            resulting_string += input.charAt(parser_pos);
                            if (!esc)
                            {
                                esc = input.charAt(parser_pos) === '\\';
                            }
                            else
                            {
                                esc = false;
                            }
                            parser_pos += 1;
                            if (parser_pos >= input_length)
                            {
                                // incomplete string/rexp when end-of-file reached.
                                // bail out with what had been received so far.
                                return [resulting_string, 'TK_STRING'];
                            }
                        }
                    }
                }
                parser_pos += 1;
                resulting_string += sep;
                if (sep === '/')
                {
                    // regexps may have modifiers /regexp/MOD , so fetch those, too
                    while (parser_pos < input_length && in_array(input.charAt(parser_pos), wordchar))
                    {
                        resulting_string += input.charAt(parser_pos);
                        parser_pos += 1;
                    }
                }
                return [resulting_string, 'TK_STRING'];
            }
            if (c === '#')
            {
                if (output.length === 0 && input.charAt(parser_pos) === '!')
                {
                    // shebang
                    resulting_string = c;
                    while (parser_pos < input_length && c != '\n')
                    {
                        c = input.charAt(parser_pos);
                        resulting_string += c;
                        parser_pos += 1;
                    }
                    output.push(trim(resulting_string) + '\n');
                    print_newline();
                    return get_next_token();
                }
                // Spidermonkey-specific sharp variables for circular references
                // https://developer.mozilla.org/En/Sharp_variables_in_JavaScript
                // http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp around line 1935
                var sharp = '#';
                if (parser_pos < input_length && in_array(input.charAt(parser_pos), digits))
                {
                    do
                    {
                        c = input.charAt(parser_pos);
                        sharp += c;
                        parser_pos += 1;
                    } while (parser_pos < input_length && c !== '#' && c !== '=');
                    if (c === '#')
                    {
                        //
                    }
                    else if (input.charAt(parser_pos) === '[' && input.charAt(parser_pos + 1) === ']')
                    {
                        sharp += '[]';
                        parser_pos += 2;
                    }
                    else if (input.charAt(parser_pos) === '{' && input.charAt(parser_pos + 1) === '}')
                    {
                        sharp += '{}';
                        parser_pos += 2;
                    }
                    return [sharp, 'TK_WORD'];
                }
            }
            if (c === '<' && input.substring(parser_pos - 1, parser_pos + 3) === '<!--')
            {
                parser_pos += 3;
                c = '<!--';
                while (input[parser_pos] != '\n' && parser_pos < input_length)
                {
                    c += input[parser_pos];
                    parser_pos++;
                }
                flags.in_html_comment = true;
                return [c, 'TK_COMMENT'];
            }
            if (c === '-' && flags.in_html_comment && input.substring(parser_pos - 1, parser_pos + 2) === '-->')
            {
                flags.in_html_comment = false;
                parser_pos += 2;
                if (wanted_newline)
                {
                    print_newline();
                }
                return ['-->', 'TK_COMMENT'];
            }
            if (in_array(c, punct))
            {
                while (parser_pos < input_length && in_array(c + input.charAt(parser_pos), punct))
                {
                    c += input.charAt(parser_pos);
                    parser_pos += 1;
                    if (parser_pos >= input_length)
                    {
                        break;
                    }
                }
                if (c === '=')
                {
                    return [c, 'TK_EQUALS'];
                }
                else
                {
                    return [c, 'TK_OPERATOR'];
                }
            }
            return [c, 'TK_UNKNOWN'];
        }
        //----------------------------------
        indent_string = '';
        while (opt_indent_size > 0)
        {
            indent_string += opt_indent_char;
            opt_indent_size -= 1;
        }
        while (js_source_text && (js_source_text[0] === ' ' || js_source_text[0] === '\t'))
        {
            preindent_string += js_source_text[0];
            js_source_text = js_source_text.substring(1);
        }
        input = js_source_text;
        last_word = ''; // last 'TK_WORD' passed
        last_type = 'TK_START_EXPR'; // last token type
        last_text = ''; // last token text
        last_last_text = ''; // pre-last token text
        output = [];
        do_block_just_closed = false;
        whitespace = "\n\r\t ".split('');
        wordchar = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'.split('');
        digits = '0123456789'.split('');
        punct = '+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! !! , : ? ^ ^= |= ::';
        punct += ' <%= <% %> <?= <? ?>'; // try to be a good boy and try not to break the markup language identifiers
        punct = punct.split(' ');
        // words which should always start on new line.
        line_starters = 'continue,try,throw,return,var,if,switch,case,default,for,while,break,function'.split(',');
        // states showing if we are currently in expression (i.e. "if" case) - 'EXPRESSION', or in usual block (like, procedure), 'BLOCK'.
        // some formatting depends on that.
        flag_store = [];
        set_mode('BLOCK');
        parser_pos = 0;
        while (true)
        {
            var t = get_next_token(parser_pos);
            token_text = t[0];
            token_type = t[1];
            if (token_type === 'TK_EOF')
            {
                break;
            }
            switch (token_type)
            {
            case 'TK_START_EXPR':
                if (token_text === '[')
                {
                    if (last_type === 'TK_WORD' || last_text === ')')
                    {
                        // this is array index specifier, break immediately
                        // a[x], fn()[x]
                        if (in_array(last_text, line_starters))
                        {
                            print_single_space();
                        }
                        set_mode('(EXPRESSION)');
                        print_token();
                        break;
                    }
                    if (flags.mode === '[EXPRESSION]' || flags.mode === '[INDENTED-EXPRESSION]')
                    {
                        if (last_last_text === ']' && last_text === ',')
                        {
                            // ], [ goes to new line
                            if (flags.mode === '[EXPRESSION]')
                            {
                                flags.mode = '[INDENTED-EXPRESSION]';
                                if (!opt_keep_array_indentation)
                                {
                                    indent();
                                }
                            }
                            set_mode('[EXPRESSION]');
                            if (!opt_keep_array_indentation)
                            {
                                print_newline();
                            }
                        }
                        else if (last_text === '[')
                        {
                            if (flags.mode === '[EXPRESSION]')
                            {
                                flags.mode = '[INDENTED-EXPRESSION]';
                                if (!opt_keep_array_indentation)
                                {
                                    indent();
                                }
                            }
                            set_mode('[EXPRESSION]');
                            if (!opt_keep_array_indentation)
                            {
                                print_newline();
                            }
                        }
                        else
                        {
                            set_mode('[EXPRESSION]');
                        }
                    }
                    else
                    {
                        set_mode('[EXPRESSION]');
                    }
                }
                else
                {
                    if (last_word === 'for')
                    {
                        set_mode('(FOR-EXPRESSION)');
                    }
                    else if (in_array(last_word, ['if', 'while']))
                    {
                        set_mode('(COND-EXPRESSION)');
                    }
                    else
                    {
                        set_mode('(EXPRESSION)');
                    }
                }
                if (last_text === ';' || last_type === 'TK_START_BLOCK')
                {
                    print_newline();
                }
                else if (last_type === 'TK_END_EXPR' || last_type === 'TK_START_EXPR' || last_type === 'TK_END_BLOCK' || last_text === '.')
                {
                    if (wanted_newline)
                    {
                        print_newline();
                    }
                    // do nothing on (( and )( and ][ and ]( and .(
                }
                else if (last_type !== 'TK_WORD' && last_type !== 'TK_OPERATOR')
                {
                    print_single_space();
                }
                else if (last_word === 'function' || last_word === 'typeof')
                {
                    // function() vs function ()
                    if (opt_jslint_happy)
                    {
                        print_single_space();
                    }
                }
                else if (in_array(last_text, line_starters) || last_text === 'catch')
                {
                    if (opt_space_before_conditional)
                    {
                        print_single_space();
                    }
                }
                print_token();
                break;
            case 'TK_END_EXPR':
                if (token_text === ']')
                {
                    if (opt_keep_array_indentation)
                    {
                        if (last_text === '}')
                        {
                            // trim_output();
                            // print_newline(true);
                            remove_indent();
                            print_token();
                            restore_mode();
                            break;
                        }
                    }
                    else
                    {
                        if (flags.mode === '[INDENTED-EXPRESSION]')
                        {
                            if (last_text === ']')
                            {
                                restore_mode();
                                print_newline();
                                print_token();
                                break;
                            }
                        }
                    }
                }
                restore_mode();
                print_token();
                break;
            case 'TK_START_BLOCK':
                if (last_word === 'do')
                {
                    set_mode('DO_BLOCK');
                }
                else
                {
                    set_mode('BLOCK');
                }
                if (opt_brace_style == "expand" || opt_brace_style == "expand-strict")
                {
                    var empty_braces = false;
                    if (opt_brace_style == "expand-strict")
                    {
                        empty_braces = (look_up() == '}');
                        if (!empty_braces)
                        {
                            print_newline(true);
                        }
                    }
                    else
                    {
                        if (last_type !== 'TK_OPERATOR')
                        {
                            if (last_text === '=' || (is_special_word(last_text) && last_text !== 'else'))
                            {
                                print_single_space();
                            }
                            else
                            {
                                print_newline(true);
                            }
                        }
                    }
                    print_token();
                    if (!empty_braces) indent();
                }
                else
                {
                    if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR')
                    {
                        if (last_type === 'TK_START_BLOCK')
                        {
                            print_newline();
                        }
                        else
                        {
                            print_single_space();
                        }
                    }
                    else
                    {
                        // if TK_OPERATOR or TK_START_EXPR
                        if (is_array(flags.previous_mode) && last_text === ',')
                        {
                            if (last_last_text === '}')
                            {
                                // }, { in array context
                                print_single_space();
                            }
                            else
                            {
                                print_newline(); // [a, b, c, {
                            }
                        }
                    }
                    indent();
                    print_token();
                }
                break;
            case 'TK_END_BLOCK':
                restore_mode();
                if (opt_brace_style == "expand" || opt_brace_style == "expand-strict")
                {
                    if (last_text !== '{')
                    {
                        print_newline();
                    }
                    print_token();
                }
                else
                {
                    if (last_type === 'TK_START_BLOCK')
                    {
                        // nothing
                        if (just_added_newline)
                        {
                            remove_indent();
                        }
                        else
                        {
                            // {}
                            trim_output();
                        }
                    }
                    else
                    {
                        if (is_array(flags.mode) && opt_keep_array_indentation)
                        {
                            // we REALLY need a newline here, but newliner would skip that
                            opt_keep_array_indentation = false;
                            print_newline();
                            opt_keep_array_indentation = true;
                        }
                        else
                        {
                            print_newline();
                        }
                    }
                    print_token();
                }
                break;
            case 'TK_WORD':
                // no, it's not you. even I have problems understanding how this works
                // and what does what.
                if (do_block_just_closed)
                {
                    // do {} ## while ()
                    print_single_space();
                    print_token();
                    print_single_space();
                    do_block_just_closed = false;
                    break;
                }
                if (token_text === 'function')
                {
                    if (flags.var_line)
                    {
                        flags.var_line_reindented = true;
                    }
                    if ((just_added_newline || last_text === ';') && last_text !== '{' && last_type != 'TK_BLOCK_COMMENT' && last_type != 'TK_COMMENT')
                    {
                        // make sure there is a nice clean space of at least one blank line
                        // before a new function definition
                        n_newlines = just_added_newline ? n_newlines : 0;
                        if (!opt_preserve_newlines)
                        {
                            n_newlines = 1;
                        }
                        for (var i = 0; i < 2 - n_newlines; i++)
                        {
                            print_newline(false);
                        }
                    }
                }
                if (token_text === 'case' || token_text === 'default')
                {
                    if (last_text === ':' || flags.case_body)
                    {
                        // switch cases following one another
                        remove_indent();
                    }
                    else
                    {
                        // case statement starts in the same line where switch
                        if (!opt_indent_case) flags.indentation_level--;
                        print_newline();
                        if (!opt_indent_case) flags.indentation_level++;
                    }
                    print_token();
                    flags.in_case = true;
                    flags.case_body = false;
                    break;
                }
                prefix = 'NONE';
                if (last_type === 'TK_END_BLOCK')
                {
                    if (!in_array(token_text.toLowerCase(), ['else', 'catch', 'finally']))
                    {
                        prefix = 'NEWLINE';
                    }
                    else
                    {
                        if (opt_brace_style == "expand" || opt_brace_style == "end-expand" || opt_brace_style == "expand-strict")
                        {
                            prefix = 'NEWLINE';
                        }
                        else
                        {
                            prefix = 'SPACE';
                            print_single_space();
                        }
                    }
                }
                else if (last_type === 'TK_SEMICOLON' && (flags.mode === 'BLOCK' || flags.mode === 'DO_BLOCK'))
                {
                    prefix = 'NEWLINE';
                }
                else if (last_type === 'TK_SEMICOLON' && is_expression(flags.mode))
                {
                    prefix = 'SPACE';
                }
                else if (last_type === 'TK_STRING')
                {
                    prefix = 'NEWLINE';
                }
                else if (last_type === 'TK_WORD')
                {
                    if (last_text === 'else')
                    {
                        // eat newlines between ...else *** some_op...
                        // won't preserve extra newlines in this place (if any), but don't care that much
                        trim_output(true);
                    }
                    prefix = 'SPACE';
                }
                else if (last_type === 'TK_START_BLOCK')
                {
                    prefix = 'NEWLINE';
                }
                else if (last_type === 'TK_END_EXPR')
                {
                    print_single_space();
                    prefix = 'NEWLINE';
                }
                if (in_array(token_text, line_starters) && last_text !== ')')
                {
                    if (last_text == 'else')
                    {
                        prefix = 'SPACE';
                    }
                    else
                    {
                        prefix = 'NEWLINE';
                    }
                    if (token_text === 'function' && (last_text === 'get' || last_text === 'set'))
                    {
                        prefix = 'SPACE';
                    }
                }
                if (flags.if_line && last_type === 'TK_END_EXPR')
                {
                    flags.if_line = false;
                }
                if (in_array(token_text.toLowerCase(), ['else', 'catch', 'finally']))
                {
                    if (last_type !== 'TK_END_BLOCK' || opt_brace_style == "expand" || opt_brace_style == "end-expand" || opt_brace_style == "expand-strict")
                    {
                        print_newline();
                    }
                    else
                    {
                        trim_output(true);
                        print_single_space();
                    }
                }
                else if (prefix === 'NEWLINE')
                {
                    if ((last_type === 'TK_START_EXPR' || last_text === '=' || last_text === ',') && token_text === 'function')
                    {
                        // no need to force newline on 'function': (function
                        // DONOTHING
                    }
                    else if (token_text === 'function' && last_text == 'new')
                    {
                        print_single_space();
                    }
                    else if (is_special_word(last_text))
                    {
                        // no newline between 'return nnn'
                        print_single_space();
                    }
                    else if (last_type !== 'TK_END_EXPR')
                    {
                        if ((last_type !== 'TK_START_EXPR' || token_text !== 'var') && last_text !== ':')
                        {
                            // no need to force newline on 'var': for (var x = 0...)
                            if (token_text === 'if' && last_word === 'else' && last_text !== '{')
                            {
                                // no newline for } else if {
                                print_single_space();
                            }
                            else
                            {
                                flags.var_line = false;
                                flags.var_line_reindented = false;
                                print_newline();
                            }
                        }
                    }
                    else if (in_array(token_text, line_starters) && last_text != ')')
                    {
                        flags.var_line = false;
                        flags.var_line_reindented = false;
                        print_newline();
                    }
                }
                else if (is_array(flags.mode) && last_text === ',' && last_last_text === '}')
                {
                    print_newline(); // }, in lists get a newline treatment
                }
                else if (prefix === 'SPACE')
                {
                    print_single_space();
                }
                print_token();
                last_word = token_text;
                if (token_text === 'var')
                {
                    flags.var_line = true;
                    flags.var_line_reindented = false;
                    flags.var_line_tainted = false;
                }
                if (token_text === 'if')
                {
                    flags.if_line = true;
                }
                if (token_text === 'else')
                {
                    flags.if_line = false;
                }
                break;
            case 'TK_SEMICOLON':
                print_token();
                flags.var_line = false;
                flags.var_line_reindented = false;
                if (flags.mode == 'OBJECT')
                {
                    // OBJECT mode is weird and doesn't get reset too well.
                    flags.mode = 'BLOCK';
                }
                break;
            case 'TK_STRING':
                if (last_type === 'TK_END_EXPR' && in_array(flags.previous_mode, ['(COND-EXPRESSION)', '(FOR-EXPRESSION)']))
                {
                    print_single_space();
                }
                else if (last_type == 'TK_STRING' || last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_SEMICOLON')
                {
                    print_newline();
                }
                else if (last_type === 'TK_WORD')
                {
                    print_single_space();
                }
                print_token();
                break;
            case 'TK_EQUALS':
                if (flags.var_line)
                {
                    // just got an '=' in a var-line, different formatting/line-breaking, etc will now be done
                    flags.var_line_tainted = true;
                }
                print_single_space();
                print_token();
                print_single_space();
                break;
            case 'TK_OPERATOR':
                var space_before = true;
                var space_after = true;
                if (flags.var_line && token_text === ',' && (is_expression(flags.mode)))
                {
                    // do not break on comma, for(var a = 1, b = 2)
                    flags.var_line_tainted = false;
                }
                if (flags.var_line)
                {
                    if (token_text === ',')
                    {
                        if (flags.var_line_tainted)
                        {
                            print_token();
                            flags.var_line_reindented = true;
                            flags.var_line_tainted = false;
                            print_newline();
                            break;
                        }
                        else
                        {
                            flags.var_line_tainted = false;
                        }
                        // } else if (token_text === ':') {
                        // hmm, when does this happen? tests don't catch this
                        // flags.var_line = false;
                    }
                }
                if (is_special_word(last_text))
                {
                    // "return" had a special handling in TK_WORD. Now we need to return the favor
                    print_single_space();
                    print_token();
                    break;
                }
                if (token_text === ':' && flags.in_case)
                {
                    if (opt_indent_case) flags.case_body = true;
                    print_token(); // colon really asks for separate treatment
                    print_newline();
                    flags.in_case = false;
                    break;
                }
                if (token_text === '::')
                {
                    // no spaces around exotic namespacing syntax operator
                    print_token();
                    break;
                }
                if (token_text === ',')
                {
                    if (flags.var_line)
                    {
                        if (flags.var_line_tainted)
                        {
                            print_token();
                            print_newline();
                            flags.var_line_tainted = false;
                        }
                        else
                        {
                            print_token();
                            print_single_space();
                        }
                    }
                    else if (last_type === 'TK_END_BLOCK' && flags.mode !== "(EXPRESSION)")
                    {
                        print_token();
                        if (flags.mode === 'OBJECT' && last_text === '}')
                        {
                            print_newline();
                        }
                        else
                        {
                            print_single_space();
                        }
                    }
                    else
                    {
                        if (flags.mode === 'OBJECT')
                        {
                            print_token();
                            print_newline();
                        }
                        else
                        {
                            // EXPR or DO_BLOCK
                            print_token();
                            print_single_space();
                        }
                    }
                    break;
                    // } else if (in_array(token_text, ['--', '++', '!']) || (in_array(token_text, ['-', '+']) && (in_array(last_type, ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS']) || in_array(last_text, line_starters) || in_array(last_text, ['==', '!=', '+=', '-=', '*=', '/=', '+', '-'])))) {
                }
                else if (in_array(token_text, ['--', '++', '!']) || (in_array(token_text, ['-', '+']) && (in_array(last_type, ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS', 'TK_OPERATOR']) || in_array(last_text, line_starters))))
                {
                    // unary operators (and binary +/- pretending to be unary) special cases
                    space_before = false;
                    space_after = false;
                    if (last_text === ';' && is_expression(flags.mode))
                    {
                        // for (;; ++i)
                        //        ^^^
                        space_before = true;
                    }
                    if (last_type === 'TK_WORD' && in_array(last_text, line_starters))
                    {
                        space_before = true;
                    }
                    if (flags.mode === 'BLOCK' && (last_text === '{' || last_text === ';'))
                    {
                        // { foo; --i }
                        // foo(); --bar;
                        print_newline();
                    }
                }
                else if (token_text === '.')
                {
                    // decimal digits or object.property
                    space_before = false;
                }
                else if (token_text === ':')
                {
                    if (flags.ternary_depth == 0)
                    {
                        flags.mode = 'OBJECT';
                        space_before = false;
                    }
                    else
                    {
                        flags.ternary_depth -= 1;
                    }
                }
                else if (token_text === '?')
                {
                    flags.ternary_depth += 1;
                }
                if (space_before)
                {
                    print_single_space();
                }
                print_token();
                if (space_after)
                {
                    print_single_space();
                }
                if (token_text === '!')
                {
                    // flags.eat_next_space = true;
                }
                break;
            case 'TK_BLOCK_COMMENT':
                var lines = token_text.split(/\x0a|\x0d\x0a/);
                if (all_lines_start_with(lines.slice(1), '*'))
                {
                    // javadoc: reformat and reindent
                    print_newline();
                    output.push(lines[0]);
                    for (i = 1; i < lines.length; i++)
                    {
                        print_newline();
                        output.push(' ');
                        output.push(trim(lines[i]));
                    }
                }
                else
                {
                    // simple block comment: leave intact
                    if (lines.length > 1)
                    {
                        // multiline comment block starts with a new line
                        print_newline();
                    }
                    else
                    {
                        // single-line /* comment */ stays where it is
                        if (last_type === 'TK_END_BLOCK')
                        {
                            print_newline();
                        }
                        else
                        {
                            print_single_space();
                        }
                    }
                    for (i = 0; i < lines.length; i++)
                    {
                        output.push(lines[i]);
                        output.push('\n');
                    }
                }
                if (look_up('\n') != '\n') print_newline();
                break;
            case 'TK_INLINE_COMMENT':
                print_single_space();
                print_token();
                if (is_expression(flags.mode))
                {
                    print_single_space();
                }
                else
                {
                    force_newline();
                }
                break;
            case 'TK_COMMENT':
                // print_newline();
                if (wanted_newline)
                {
                    print_newline();
                }
                else
                {
                    print_single_space();
                }
                print_token();
                if (look_up('\n') != '\n') force_newline();
                break;
            case 'TK_UNKNOWN':
                if (is_special_word(last_text))
                {
                    print_single_space();
                }
                print_token();
                break;
            }
            last_last_text = last_text;
            last_type = token_type;
            last_text = token_text;
        }
        var sweet_code = preindent_string + output.join('').replace(/[\n ]+$/, '');
        return sweet_code;
    }
    // Add support for CommonJS. Just put this file somewhere on your require.paths
    // and you will be able to `var js_beautify = require("beautify").js_beautify`.
    // comments by Microshaoft begin ===========================================================
    /*
        if (typeof exports !== "undefined")
            exports.js_beautify = js_beautify;
    */
    // comments by Microshaoft end ===========================================================
    /*
     Style HTML
    ---------------
      Written by Nochum Sossonko, (nsossonko@hotmail.com)
      Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>
        http://jsbeautifier.org/
      You are free to use this in any way you want, in case you find this useful or working for you.
      Usage:
        style_html(html_source);
        style_html(html_source, options);
      The options are:
        indent_size (default 4)          ?? indentation size,
        indent_char (default space)      ?? character to indent with,
        max_char (default 70)            -  maximum amount of characters per line,
        brace_style (default "collapse") - "collapse" | "expand" | "end-expand"
                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.
        unformatted (default ['a'])      - list of tags, that shouldn't be reformatted
        indent_scripts (default normal)  - "keep"|"separate"|"normal"
        e.g.
        style_html(html_source, {
          'indent_size': 2,
          'indent_char': ' ',
          'max_char': 78,
          'brace_style': 'expand',
          'unformatted': ['a', 'sub', 'sup', 'b', 'i', 'u']
        });
    */
    function style_html(html_source, options)
    {
        //Wrapper function to invoke all the necessary constructors and deal with the output.
        var multi_parser, indent_size, indent_character, max_char, brace_style;
        options = options || {};
        indent_size = options.indent_size || 4;
        indent_character = options.indent_char || ' ';
        brace_style = options.brace_style || 'collapse';
        max_char = options.max_char == 0 ? Infinity : options.max_char || 70;
        var unformatted = options.unformatted || ['a'];
        function Parser()
        {
            this.pos = 0; //Parser position
            this.token = '';
            this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT
            this.tags =
            { //An object to hold tags, their position, and their parent-tags, initiated with default values
                parent: 'parent1',
                parentcount: 1,
                parent1: ''
            };
            this.tag_type = '';
            this.token_text = this.last_token = this.last_text = this.token_type = '';
            this.Utils =
            { //Uilities made available to the various functions
                whitespace: "\n\r\t ".split(''),
                single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed'.split(','),
                //all the single tags for HTML
                extra_liners: 'head,body,/html'.split(','),
                //for tags that need a line of whitespace before them
                in_array: function (what, arr)
                {
                    for (var i = 0; i < arr.length; i++)
                    {
                        if (what === arr[i])
                        {
                            return true;
                        }
                    }
                    return false;
                }
            }
            this.get_content = function ()
            { //function to capture regular content between tags
                var input_char = '';
                var content = [];
                var space = false; //if a space is needed
                while (this.input.charAt(this.pos) !== '<')
                {
                    if (this.pos >= this.input.length)
                    {
                        return content.length ? content.join('') : ['', 'TK_EOF'];
                    }
                    input_char = this.input.charAt(this.pos);
                    this.pos++;
                    this.line_char_count++;
                    if (this.Utils.in_array(input_char, this.Utils.whitespace))
                    {
                        if (content.length)
                        {
                            space = true;
                        }
                        this.line_char_count--;
                        continue; //don't want to insert unnecessary space
                    }
                    else if (space)
                    {
                        if (this.line_char_count >= this.max_char)
                        { //insert a line when the max_char is reached
                            content.push('\n');
                            for (var i = 0; i < this.indent_level; i++)
                            {
                                content.push(this.indent_string);
                            }
                            this.line_char_count = 0;
                        }
                        else
                        {
                            content.push(' ');
                            this.line_char_count++;
                        }
                        space = false;
                    }
                    content.push(input_char); //letter at-a-time (or string) inserted to an array
                }
                return content.length ? content.join('') : '';
            }
            this.get_contents_to = function (name)
            { //get the full content of a script or style to pass to js_beautify
                if (this.pos == this.input.length)
                {
                    return ['', 'TK_EOF'];
                }
                var input_char = '';
                var content = '';
                var reg_match = new RegExp('\<\/' + name + '\\s*\>', 'igm');
                reg_match.lastIndex = this.pos;
                var reg_array = reg_match.exec(this.input);
                var end_script = reg_array ? reg_array.index : this.input.length; //absolute end of script
                if (this.pos < end_script)
                { //get everything in between the script tags
                    content = this.input.substring(this.pos, end_script);
                    this.pos = end_script;
                }
                return content;
            }
            this.record_tag = function (tag)
            { //function to record a tag and its parent in this.tags Object
                if (this.tags[tag + 'count'])
                { //check for the existence of this tag type
                    this.tags[tag + 'count']++;
                    this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
                }
                else
                { //otherwise initialize this tag type
                    this.tags[tag + 'count'] = 1;
                    this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
                }
                this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent)
                this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1')
            }
            this.retrieve_tag = function (tag)
            { //function to retrieve the opening tag to the corresponding closer
                if (this.tags[tag + 'count'])
                { //if the openener is not in the Object we ignore it
                    var temp_parent = this.tags.parent; //check to see if it's a closable tag.
                    while (temp_parent)
                    { //till we reach '' (the initial value);
                        if (tag + this.tags[tag + 'count'] === temp_parent)
                        { //if this is it use it
                            break;
                        }
                        temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree
                    }
                    if (temp_parent)
                    { //if we caught something
                        this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly
                        this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent
                    }
                    delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference...
                    delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself
                    if (this.tags[tag + 'count'] == 1)
                    {
                        delete this.tags[tag + 'count'];
                    }
                    else
                    {
                        this.tags[tag + 'count']--;
                    }
                }
            }
            this.get_tag = function ()
            { //function to get a full tag and parse its type
                var input_char = '';
                var content = [];
                var space = false;
                do
                {
                    if (this.pos >= this.input.length)
                    {
                        return content.length ? content.join('') : ['', 'TK_EOF'];
                    }
                    input_char = this.input.charAt(this.pos);
                    this.pos++;
                    this.line_char_count++;
                    if (this.Utils.in_array(input_char, this.Utils.whitespace))
                    { //don't want to insert unnecessary space
                        space = true;
                        this.line_char_count--;
                        continue;
                    }
                    if (input_char === "'" || input_char === '"')
                    {
                        if (!content[1] || content[1] !== '!')
                        { //if we're in a comment strings don't get treated specially
                            input_char += this.get_unformatted(input_char);
                            space = true;
                        }
                    }
                    if (input_char === '=')
                    { //no space before =
                        space = false;
                    }
                    if (content.length && content[content.length - 1] !== '=' && input_char !== '>' && space)
                    { //no space after = or before >
                        if (this.line_char_count >= this.max_char)
                        {
                            this.print_newline(false, content);
                            this.line_char_count = 0;
                        }
                        else
                        {
                            content.push(' ');
                            this.line_char_count++;
                        }
                        space = false;
                    }
                    content.push(input_char); //inserts character at-a-time (or string)
                } while (input_char !== '>');
                var tag_complete = content.join('');
                var tag_index;
                if (tag_complete.indexOf(' ') != -1)
                { //if there's whitespace, thats where the tag name ends
                    tag_index = tag_complete.indexOf(' ');
                }
                else
                { //otherwise go with the tag ending
                    tag_index = tag_complete.indexOf('>');
                }
                var tag_check = tag_complete.substring(1, tag_index).toLowerCase();
                if (tag_complete.charAt(tag_complete.length - 2) === '/' || this.Utils.in_array(tag_check, this.Utils.single_token))
                { //if this tag name is a single tag type (either in the list or has a closing /)
                    this.tag_type = 'SINGLE';
                }
                else if (tag_check === 'script')
                { //for later script handling
                    this.record_tag(tag_check);
                    this.tag_type = 'SCRIPT';
                }
                else if (tag_check === 'style')
                { //for future style handling (for now it justs uses get_content)
                    this.record_tag(tag_check);
                    this.tag_type = 'STYLE';
                }
                else if (this.Utils.in_array(tag_check, unformatted))
                { // do not reformat the "unformatted" tags
                    var comment = this.get_unformatted('</' + tag_check + '>', tag_complete); //...delegate to get_unformatted function
                    content.push(comment);
                    this.tag_type = 'SINGLE';
                }
                else if (tag_check.charAt(0) === '!')
                { //peek for <!-- comment
                    if (tag_check.indexOf('[if') != -1)
                    { //peek for <!--[if conditional comment
                        if (tag_complete.indexOf('!IE') != -1)
                        { //this type needs a closing --> so...
                            var comment = this.get_unformatted('-->', tag_complete); //...delegate to get_unformatted
                            content.push(comment);
                        }
                        this.tag_type = 'START';
                    }
                    else if (tag_check.indexOf('[endif') != -1)
                    { //peek for <!--[endif end conditional comment
                        this.tag_type = 'END';
                        this.unindent();
                    }
                    else if (tag_check.indexOf('[cdata[') != -1)
                    { //if it's a <[cdata[ comment...
                        var comment = this.get_unformatted(']]>', tag_complete); //...delegate to get_unformatted function
                        content.push(comment);
                        this.tag_type = 'SINGLE'; //<![CDATA[ comments are treated like single tags
                    }
                    else
                    {
                        var comment = this.get_unformatted('-->', tag_complete);
                        content.push(comment);
                        this.tag_type = 'SINGLE';
                    }
                }
                else
                {
                    if (tag_check.charAt(0) === '/')
                    { //this tag is a double tag so check for tag-ending
                        this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors
                        this.tag_type = 'END';
                    }
                    else
                    { //otherwise it's a start-tag
                        this.record_tag(tag_check); //push it on the tag stack
                        this.tag_type = 'START';
                    }
                    if (this.Utils.in_array(tag_check, this.Utils.extra_liners))
                    { //check if this double needs an extra line
                        this.print_newline(true, this.output);
                    }
                }
                return content.join(''); //returns fully formatted tag
            }
            this.get_unformatted = function (delimiter, orig_tag)
            { //function to return unformatted content in its entirety
                if (orig_tag && orig_tag.indexOf(delimiter) != -1)
                {
                    return '';
                }
                var input_char = '';
                var content = '';
                var space = true;
                do
                {
                    if (this.pos >= this.input.length)
                    {
                        return content;
                    }
                    input_char = this.input.charAt(this.pos);
                    this.pos++
                    if (this.Utils.in_array(input_char, this.Utils.whitespace))
                    {
                        if (!space)
                        {
                            this.line_char_count--;
                            continue;
                        }
                        if (input_char === '\n' || input_char === '\r')
                        {
                            content += '\n';
                            /*  Don't change tab indention for unformatted blocks.  If using code for html editing, this will greatly affect <pre> tags if they are specified in the 'unformatted array'
                for (var i=0; i<this.indent_level; i++) {
                  content += this.indent_string;
                }
                space = false; //...and make sure other indentation is erased
                */
                            this.line_char_count = 0;
                            continue;
                        }
                    }
                    content += input_char;
                    this.line_char_count++;
                    space = true;
                } while (content.indexOf(delimiter) == -1);
                return content;
            }
            this.get_token = function ()
            { //initial handler for token-retrieval
                var token;
                if (this.last_token === 'TK_TAG_SCRIPT' || this.last_token === 'TK_TAG_STYLE')
                { //check if we need to format javascript
                    var type = this.last_token.substr(7)
                    token = this.get_contents_to(type);
                    if (typeof token !== 'string')
                    {
                        return token;
                    }
                    return [token, 'TK_' + type];
                }
                if (this.current_mode === 'CONTENT')
                {
                    token = this.get_content();
                    if (typeof token !== 'string')
                    {
                        return token;
                    }
                    else
                    {
                        return [token, 'TK_CONTENT'];
                    }
                }
                if (this.current_mode === 'TAG')
                {
                    token = this.get_tag();
                    if (typeof token !== 'string')
                    {
                        return token;
                    }
                    else
                    {
                        var tag_name_type = 'TK_TAG_' + this.tag_type;
                        return [token, tag_name_type];
                    }
                }
            }
            this.get_full_indent = function (level)
            {
                level = this.indent_level + level || 0;
                if (level < 1) return '';
                return Array(level + 1).join(this.indent_string);
            }
            this.printer = function (js_source, indent_character, indent_size, max_char, brace_style)
            { //handles input/output and some other printing functions
                this.input = js_source || ''; //gets the input for the Parser
                this.output = [];
                this.indent_character = indent_character;
                this.indent_string = '';
                this.indent_size = indent_size;
                this.brace_style = brace_style;
                this.indent_level = 0;
                this.max_char = max_char;
                this.line_char_count = 0; //count to see if max_char was exceeded
                for (var i = 0; i < this.indent_size; i++)
                {
                    this.indent_string += this.indent_character;
                }
                this.print_newline = function (ignore, arr)
                {
                    this.line_char_count = 0;
                    if (!arr || !arr.length)
                    {
                        return;
                    }
                    if (!ignore)
                    { //we might want the extra line
                        while (this.Utils.in_array(arr[arr.length - 1], this.Utils.whitespace))
                        {
                            arr.pop();
                        }
                    }
                    arr.push('\n');
                    for (var i = 0; i < this.indent_level; i++)
                    {
                        arr.push(this.indent_string);
                    }
                }
                this.print_token = function (text)
                {
                    this.output.push(text);
                }
                this.indent = function ()
                {
                    this.indent_level++;
                }
                this.unindent = function ()
                {
                    if (this.indent_level > 0)
                    {
                        this.indent_level--;
                    }
                }
            }
            return this;
        }
        /*_____________________--------------------_____________________*/
        multi_parser = new Parser(); //wrapping functions Parser
        multi_parser.printer(html_source, indent_character, indent_size, max_char, brace_style); //initialize starting values
        while (true)
        {
            var t = multi_parser.get_token();
            multi_parser.token_text = t[0];
            multi_parser.token_type = t[1];
            if (multi_parser.token_type === 'TK_EOF')
            {
                break;
            }
            switch (multi_parser.token_type)
            {
            case 'TK_TAG_START':
                multi_parser.print_newline(false, multi_parser.output);
                multi_parser.print_token(multi_parser.token_text);
                multi_parser.indent();
                multi_parser.current_mode = 'CONTENT';
                break;
            case 'TK_TAG_STYLE':
            case 'TK_TAG_SCRIPT':
                multi_parser.print_newline(false, multi_parser.output);
                multi_parser.print_token(multi_parser.token_text);
                multi_parser.current_mode = 'CONTENT';
                break;
            case 'TK_TAG_END':
                //Print new line only if the tag has no content and has child
                if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '')
                {
                    var tag_name = multi_parser.token_text.match(/\w+/)[0];
                    var tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length - 1].match(/<\s*(\w+)/);
                    if (tag_extracted_from_last_output === null || tag_extracted_from_last_output[1] !== tag_name) multi_parser.print_newline(true, multi_parser.output);
                }
                multi_parser.print_token(multi_parser.token_text);
                multi_parser.current_mode = 'CONTENT';
                break;
            case 'TK_TAG_SINGLE':
                multi_parser.print_newline(false, multi_parser.output);
                multi_parser.print_token(multi_parser.token_text);
                multi_parser.current_mode = 'CONTENT';
                break;
            case 'TK_CONTENT':
                if (multi_parser.token_text !== '')
                {
                    multi_parser.print_token(multi_parser.token_text);
                }
                multi_parser.current_mode = 'TAG';
                break;
            case 'TK_STYLE':
            case 'TK_SCRIPT':
                if (multi_parser.token_text !== '')
                {
                    multi_parser.output.push('\n');
                    var text = multi_parser.token_text;
                    if (multi_parser.token_type == 'TK_SCRIPT')
                    {
                        var _beautifier = typeof js_beautify == 'function' && js_beautify;
                    }
                    else if (multi_parser.token_type == 'TK_STYLE')
                    {
                        var _beautifier = typeof css_beautify == 'function' && css_beautify;
                    }
                    if (options.indent_scripts == "keep")
                    {
                        var script_indent_level = 0;
                    }
                    else if (options.indent_scripts == "separate")
                    {
                        var script_indent_level = -multi_parser.indent_level;
                    }
                    else
                    {
                        var script_indent_level = 1;
                    }
                    var indentation = multi_parser.get_full_indent(script_indent_level);
                    if (_beautifier)
                    {
                        // call the Beautifier if avaliable
                        text = _beautifier(text.replace(/^\s*/, indentation), options);
                    }
                    else
                    {
                        // simply indent the string otherwise
                        var white = text.match(/^\s*/)[0];
                        var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
                        var reindent = multi_parser.get_full_indent(script_indent_level - _level);
                        text = text.replace(/^\s*/, indentation).replace(/\r\n|\r|\n/g, '\n' + reindent).replace(/\s*$/, '');
                    }
                    if (text)
                    {
                        multi_parser.print_token(text);
                        multi_parser.print_newline(true, multi_parser.output);
                    }
                }
                multi_parser.current_mode = 'TAG';
                break;
            }
            multi_parser.last_token = multi_parser.token_type;
            multi_parser.last_text = multi_parser.token_text;
        }
        return multi_parser.output.join('');
    }
    /*
     CSS Beautifier
    ---------------
        Written by Harutyun Amirjanyan, (amirjanyan@gmail.com)
        Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>
            http://jsbeautifier.org/
        You are free to use this in any way you want, in case you find this useful or working for you.
        Usage:
            css_beautify(source_text);
            css_beautify(source_text, options);
        The options are:
            indent_size (default 4)          ?? indentation size,
            indent_char (default space)      ?? character to indent with,
        e.g
        css_beautify(css_source_text, {
          'indent_size': 1,
          'indent_char': '\t'
        });
    */
    // http://www.w3.org/TR/CSS21/syndata.html#tokenization
    // http://www.w3.org/TR/css3-syntax/
    function css_beautify(source_text, options)
    {
        options = options || {};
        var indentSize = options.indent_size || 4;
        var indentCharacter = options.indent_char || ' ';
        // compatibility
        if (typeof indentSize == "string") indentSize = parseInt(indentSize);
        // tokenizer
        var whiteRe = /^\s+$/;
        var wordRe = /[\w$\-_]/;
        var pos = -1,
            ch;
        function next()
        {
            return ch = source_text.charAt(++pos)
        }
        function peek()
        {
            return source_text.charAt(pos + 1)
        }
        function eatString(comma)
        {
            var start = pos;
            while (next())
            {
                if (ch == "\\")
                {
                    next();
                    next();
                }
                else if (ch == comma)
                {
                    break;
                }
                else if (ch == "\n")
                {
                    break;
                }
            }
            return source_text.substring(start, pos + 1);
        }
        function eatWhitespace()
        {
            var start = pos;
            while (whiteRe.test(peek()))
            pos++;
            return pos != start;
        }
        function skipWhitespace()
        {
            var start = pos;
            do{} while (whiteRe.test(next()))
            return pos != start + 1;
        }
        function eatComment()
        {
            var start = pos;
            next();
            while (next())
            {
                if (ch == "*" && peek() == "/")
                {
                    pos++;
                    break;
                }
            }
            return source_text.substring(start, pos + 1);
        }
        function lookBack(str, index)
        {
            return output.slice(-str.length + (index || 0), index).join("").toLowerCase() == str;
        }
        // printer
        var indentString = source_text.match(/^[\r\n]*[\t ]*/)[0];
        var singleIndent = Array(indentSize + 1).join(indentCharacter);
        var indentLevel = 0;
        function indent()
        {
            indentLevel++;
            indentString += singleIndent;
        }
        function outdent()
        {
            indentLevel--;
            indentString = indentString.slice(0, -indentSize);
        }
        //print = {}
        // modified by Microshaoft
        print = {}
        print["{"] = function (ch)
        {
            print.singleSpace();
            output.push(ch);
            print.newLine();
        }
        print["}"] = function (ch)
        {
            print.newLine();
            output.push(ch);
            print.newLine();
        }
        print.newLine = function (keepWhitespace)
        {
            if (!keepWhitespace) while (whiteRe.test(output[output.length - 1]))
            output.pop();
            if (output.length) output.push('\n');
            if (indentString) output.push(indentString);
        }
        print.singleSpace = function ()
        {
            if (output.length && !whiteRe.test(output[output.length - 1])) output.push(' ');
        }
        var output = [];
        if (indentString) output.push(indentString);
        /*_____________________--------------------_____________________*/
        while (true)
        {
            var isAfterSpace = skipWhitespace();
            if (!ch) break;
            if (ch == '{')
            {
                indent();
                print["{"](ch);
            }
            else if (ch == '}')
            {
                outdent();
                print["}"](ch);
            }
            else if (ch == '"' || ch == '\'')
            {
                output.push(eatString(ch))
            }
            else if (ch == ';')
            {
                output.push(ch, '\n', indentString);
            }
            else if (ch == '/' && peek() == '*')
            { // comment
                print.newLine();
                output.push(eatComment(), "\n", indentString);
            }
            else if (ch == '(')
            { // may be a url
                output.push(ch);
                eatWhitespace();
                if (lookBack("url", -1) && next())
                {
                    if (ch != ')' && ch != '"' && ch != '\'') output.push(eatString(')'));
                    else pos--;
                }
            }
            else if (ch == ')')
            {
                output.push(ch);
            }
            else if (ch == ',')
            {
                eatWhitespace();
                output.push(ch);
                print.singleSpace();
            }
            else if (ch == ']')
            {
                output.push(ch);
            }
            else if (ch == '[' || ch == '=')
            { // no whitespace before or after
                eatWhitespace();
                output.push(ch);
            }
            else
            {
                if (isAfterSpace) print.singleSpace();
                output.push(ch);
            }
        }
        var sweetCode = output.join('').replace(/[\n ]+$/, '');
        return sweetCode;
    }
    //if (typeof exports !== "undefined")
    //    exports.css_beautify = css_beautify;
    function unpacker_filter(source)
    {
        var trailing_comments = '';
        var comment = '';
        var found = false;
        do
        {
            found = false;
            if (/^\s*\/\*/.test(source))
            {
                found = true;
                comment = source.substr(0, source.indexOf('*/') + 2);
                source = source.substr(comment.length).replace(/^\s+/, '');
                trailing_comments += comment + "\n";
            }
            else if (/^\s*\/\//.test(source))
            {
                found = true;
                comment = source.match(/^\s*\/\/.*/)[0];
                source = source.substr(comment.length).replace(/^\s+/, '');
                trailing_comments += comment + "\n";
            }
        } while (found);
        if (P_A_C_K_E_R.detect(source))
        {
            // P.A.C.K.E.R unpacking may fail, even though it is detected
            var unpacked = P_A_C_K_E_R.unpack(source);
            if (unpacked != source)
            {
                source = unpacker_filter(unpacked);
            }
        }
        if (Urlencoded.detect(source))
        {
            source = unpacker_filter(Urlencoded.unpack(source))
        }
        if (JavascriptObfuscator.detect(source))
        {
            source = unpacker_filter(JavascriptObfuscator.unpack(source))
        }
        if (MyObfuscate.detect(source))
        {
            source = unpacker_filter(MyObfuscate.unpack(source))
        }
        return trailing_comments + source;
    }
    function looks_like_html(source)
    {
        // <foo> - looks like html
        // <!--\nalert('foo!');\n--> - doesn't look like html
        var trimmed = source; //.replace(/^[ \t\n\r]+/, '');
        var comment_mark = '<!-' + '-';
        return (trimmed && (trimmed.substring(0, 1) === '<' && trimmed.substring(0, 4) !== comment_mark));
    }
    function beautify(source, options)
    {
        //    if (the.beautify_in_progress) return;
        //
        //    store_settings_to_cookie();
        //
        //    the.beautify_in_progress = true;
        //    var opts = {
        //                indent_size: indent_size,
        //                indent_char: indent_char,
        //                preserve_newlines:preserve_newlines,
        //                brace_style: brace_style,
        //                keep_array_indentation:keep_array_indentation,
        //                space_after_anon_function:true,
        //                space_before_conditional: space_before_conditional,
        //                indent_scripts:indent_scripts};
        if (looks_like_html(source))
        {
            // modified by Microshaoft
            return style_html(source, options);
        }
        else
        {
            // modified by Microshaoft
            source = unpacker_filter(source);
            return js_beautify(source, options);
        }
        //    the.beautify_in_progress = false;
    }
    //
    // Unpacker for Dean Edward's p.a.c.k.e.r, a part of javascript beautifier
    // written by Einar Lielmanis <einar@jsbeautifier.org>
    //
    // Coincidentally, it can defeat a couple of other eval-based compressors.
    //
    // usage:
    //
    // if (P_A_C_K_E_R.detect(some_string)) {
    //     var unpacked = P_A_C_K_E_R.unpack(some_string);
    // }
    // 
    //
    var P_A_C_K_E_R =
    {
        detect: function (str)
        {
            return false;//    P_A_C_K_E_R._starts_with(str.toLowerCase().replace(/ +/g, ''), 'eval(function(') || P_A_C_K_E_R._starts_with(str.toLowerCase().replace(/ +/g, ''), 'eval((function(');
        },
        unpack: function (str)
        {
            var unpacked_source = '';
            if (P_A_C_K_E_R.detect(str))
            {
                try
                {
                    eval('unpacked_source = ' + str.substring(4) + ';')
                    if (typeof unpacked_source == 'string' && unpacked_source)
                    {
                        str = unpacked_source;
                    }
                }
                catch (error)
                {
                    // well, it failed. we'll just return the original, instead of crashing on user.
                }
            }
            return str;
        },
        _starts_with: function (str, what)
        {
            return str.substr(0, what.length) === what;
        },
        run_tests: function (sanity_test)
        {
            var t = sanity_test || new SanityTest();
            t.test_function(P_A_C_K_E_R.detect, "P_A_C_K_E_R.detect");
            t.expect('', false);
            t.expect('var a = b', false);
            t.expect('eval(function(p,a,c,k,e,r', true);
            t.expect('eval ( function(p, a, c, k, e, r', true);
            t.test_function(P_A_C_K_E_R.unpack, 'P_A_C_K_E_R.unpack');
            t.expect("eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p}('0 2=1',3,3,'var||a'.split('|'),0,{}))", 'var a=1');
            var starts_with_a = function (what)
                {
                    return P_A_C_K_E_R._starts_with(what, 'a');
                }
            t.test_function(starts_with_a, "P_A_C_K_E_R._starts_with(?, a)");
            t.expect('abc', true);
            t.expect('bcd', false);
            t.expect('a', true);
            t.expect('', false);
            return t;
        }
    }
    //
    // trivial bookmarklet/escaped script detector for the javascript beautifier
    // written by Einar Lielmanis <einar@jsbeautifier.org>
    //
    // usage:
    //
    // if (Urlencoded.detect(some_string)) {
    //     var unpacked = Urlencoded.unpack(some_string);
    // }
    // 
    //
    var Urlencoded =
    {
        detect: function (str)
        {
            // the fact that script doesn't contain any space, but has %20 instead
            // should be sufficient check for now.
    //        if (str.indexOf(' ') == -1)
    //        {
    //            if (str.indexOf('%20') != -1) return true;
    //            if (str.replace(/[^%]+/g, '').length > 3) return true;
    //        }
            return false;
        },
        unpack: function (str)
        {
            if (Urlencoded.detect(str))
            {
                return unescape(str.replace(/\+/g, '%20'));
            }
            return str;
        },
        run_tests: function (sanity_test)
        {
            var t = sanity_test || new SanityTest();
            t.test_function(Urlencoded.detect, "Urlencoded.detect");
            t.expect('', false);
            t.expect('var a = b', false);
            t.expect('var%20a+=+b', true);
            t.expect('var%20a=b', true);
            t.expect('var%20%21%22', true);
            t.test_function(Urlencoded.unpack, 'Urlencoded.unpack');
            t.expect('', '');
            t.expect('abcd', 'abcd');
            t.expect('var a = b', 'var a = b');
            t.expect('var%20a=b', 'var a=b');
            t.expect('var%20a+=+b', 'var a = b');
            return t;
        }
    }
    //
    // simple unpacker/deobfuscator for scripts messed up with javascriptobfuscator.com
    // written by Einar Lielmanis <einar@jsbeautifier.org>
    //
    // usage:
    //
    // if (JavascriptObfuscator.detect(some_string)) {
    //     var unpacked = JavascriptObfuscator.unpack(some_string);
    // }
    // 
    //
    var JavascriptObfuscator =
    {
        detect: function (str)
        {
            return /^var _0x[a-f0-9]+ ?\= ?\[/.test(str);
        },
        unpack: function (str)
        {
            if (JavascriptObfuscator.detect(str))
            {
                var matches = /var (_0x[a-f\d]+) ?\= ?\[(.*?)\];/.exec(str);
                if (matches)
                {
                    var var_name = matches[1];
                    var strings = JavascriptObfuscator._smart_split(matches[2]);
                    var str = str.substring(matches[0].length);
                    for (var k in strings)
                    {
                        str = str.replace(new RegExp(var_name + '\\[' + k + '\\]', 'g'), JavascriptObfuscator._fix_quotes(JavascriptObfuscator._unescape(strings[k])));
                    }
                }
            }
            return str;
        },
        _fix_quotes: function (str)
        {
            var matches = /^"(.*)"$/.exec(str);
            if (matches)
            {
                str = matches[1];
                str = "'" + str.replace(/'/g, "\\'") + "'";
            }
            return str;
        },
        _smart_split: function (str)
        {
            var strings = [];
            var pos = 0;
            while (pos < str.length)
            {
                if (str.charAt(pos) == '"')
                {
                    // new word
                    var word = '';
                    pos += 1;
                    while (pos < str.length)
                    {
                        if (str.charAt(pos) == '"')
                        {
                            break;
                        }
                        if (str.charAt(pos) == '\\')
                        {
                            word += '\\';
                            pos++;
                        }
                        word += str.charAt(pos);
                        pos++;
                    }
                    strings.push('"' + word + '"');
                }
                pos += 1;
            }
            return strings;
        },
        _unescape: function (str)
        {
            // inefficient if used repeatedly or on small strings, but wonderful on single large chunk of text
            for (var i = 32; i < 128; i++)
            {
                str = str.replace(new RegExp('\\\\x' + i.toString(16), 'ig'), String.fromCharCode(i));
            }
            return str;
        },
        run_tests: function (sanity_test)
        {
            var t = sanity_test || new SanityTest();
            t.test_function(JavascriptObfuscator._smart_split, "JavascriptObfuscator._smart_split");
            t.expect('', []);
            t.expect('"a", "b"', ['"a"', '"b"']);
            t.expect('"aaa","bbbb"', ['"aaa"', '"bbbb"']);
            t.expect('"a", "b\\\""', ['"a"', '"b\\\""']);
            t.test_function(JavascriptObfuscator._unescape, 'JavascriptObfuscator._unescape');
            t.expect('\\x40', '@');
            t.expect('\\x10', '\\x10');
            t.expect('\\x1', '\\x1');
            t.expect("\\x61\\x62\\x22\\x63\\x64", 'ab"cd');
            t.test_function(JavascriptObfuscator.detect, 'JavascriptObfuscator.detect');
            t.expect('', false);
            t.expect('abcd', false);
            t.expect('var _0xaaaa', false);
            t.expect('var _0xaaaa = ["a", "b"]', true);
            t.expect('var _0xaaaa=["a", "b"]', true);
            t.expect('var _0x1234=["a","b"]', true);
            return t;
        }
    }
    //
    // simple unpacker/deobfuscator for scripts messed up with myobfuscate.com
    // You really don't want to obfuscate your scripts there: they're tracking
    // your unpackings, your script gets turned into something like this,
    // as of 2011-04-25:
    /*
        var _escape = 'your_script_escaped';
        var _111 = document.createElement('script');
        _111.src = 'http://api.www.myobfuscate.com/?getsrc=ok' +
            '&ref=' + encodeURIComponent(document.referrer) +
            '&url=' + encodeURIComponent(document.URL);
        var 000 = document.getElementsByTagName('head')[0];
        000.appendChild(_111);
        document.write(unescape(_escape));
    */
    //
    // written by Einar Lielmanis <einar@jsbeautifier.org>
    //
    // usage:
    //
    // if (MyObfuscate.detect(some_string)) {
    //     var unpacked = MyObfuscate.unpack(some_string);
    // }
    //
    //
    var MyObfuscate =
    {
        detect: function (str)
        {
            return /^var _?[0O1lI]{3}\=('|\[).*\)\)\);/.test(str);
        },
        unpack: function (str)
        {
            if (MyObfuscate.detect(str))
            {
                var modified_source = str.replace(';eval(', ';unpacked_source = (');
                var unpacked_source = '';
                eval(modified_source);
                if (unpacked_source)
                {
                    if (MyObfuscate.starts_with(unpacked_source, 'var _escape'))
                    {
                        // fetch the urlencoded stuff from the script,
                        var matches = /'([^']*)'/.exec(unpacked_source);
                        var unescaped = unescape(matches[1]);
                        if (MyObfuscate.starts_with(unescaped, '<script>'))
                        {
                            unescaped = unescaped.substr(8, unescaped.length - 8);
                        }
                        if (MyObfuscate.ends_with(unescaped, '</script>'))
                        {
                            unescaped = unescaped.substr(0, unescaped.length - 9);
                        }
                        unpacked_source = unescaped;
                    }
                }
                return unpacked_source ? "// Unpacker warning: be careful when using myobfuscate.com for your projects:\n" + "// scripts obfuscated by the free online version call back home.\n" + "\n//\n" + unpacked_source : str;
            }
            return str;
        },
        starts_with: function (str, what)
        {
            return str.substr(0, what.length) === what;
        },
        ends_with: function (str, what)
        {
            return str.substr(str.length - what.length, what.length) === what;
        },
        run_tests: function (sanity_test)
        {
            var t = sanity_test || new SanityTest();
            return t;
        }
    }
    //
    // simple testing interface
    // written by Einar Lielmanis, einar@jsbeautifier.org
    //
    // usage:
    //
    // var t = new SanityTest(function (x) { return x; }, 'my function');
    // t.expect('input', 'output');
    // t.expect('a', 'a');
    // output_somewhere(t.results()); // good for <pre>, html safe-ish
    // alert(t.results_raw());        // html unescaped
    function SanityTest(func, test_name)
    {
        var test_func = func ||
        function (x)
        {
            return x;
        }
        var test_name = test_name || '';
        var n_failed = 0;
        var n_succeeded = 0;
        var failures = [];
        this.test_function = function (func, name)
        {
            test_func = func;
            test_name = name || '';
        }
        this.expect = function (parameters, expected_value)
        {
            // multi-parameter calls not supported (I don't need them now).
            var result = test_func(parameters);
            // proper array checking is a pain. i'll maybe do it later, compare strings representations instead
            if ((result === expected_value) || (expected_value instanceof Array && result.join(', ') == expected_value.join(', ')))
            {
                n_succeeded += 1;
            }
            else
            {
                n_failed += 1;
                failures.push([test_name, parameters, expected_value, result]);
            }
        }
        this.results_raw = function ()
        {
            var results = '';
            if (n_failed === 0)
            {
                if (n_succeeded === 0)
                {
                    results = 'No tests run.';
                }
                else
                {
                    results = 'All ' + n_succeeded + ' tests passed.';
                }
            }
            else
            {
                for (var i = 0; i < failures.length; i++)
                {
                    var f = failures[i];
                    if (f[0])
                    {
                        f[0] = f[0] + ' ';
                    }
                    results += '---- ' + f[0] + 'input -------\n' + this.prettyprint(f[1]) + '\n';
                    results += '---- ' + f[0] + 'expected ----\n' + this.prettyprint(f[2]) + '\n';
                    results += '---- ' + f[0] + 'output ------\n' + this.prettyprint(f[3]) + '\n\n';
                }
                results += n_failed + ' tests failed.\n';
            }
            return results;
        }
        this.results = function ()
        {
            return this.lazy_escape(this.results_raw());
        }
        this.prettyprint = function (something, quote_strings)
        {
            var type = typeof something;
            switch (type.toLowerCase())
            {
            case 'string':
                if (quote_strings)
                {
                    return "'" + something.replace("'", "\\'") + "'";
                }
                else
                {
                    return something;
                }
            case 'number':
                return '' + something;
            case 'boolean':
                return something ? 'true' : 'false';
            case 'undefined':
                return 'undefined';
            case 'object':
                if (something instanceof Array)
                {
                    var x = [];
                    var expected_index = 0;
                    // modified by Microshaoft
                    for (k in something)
                    //for (var k in something)
                    {
                        if (k == expected_index)
                        {
                            x.push(this.prettyprint(something[k], true));
                            expected_index += 1;
                        }
                        else
                        {
                            x.push('\n' + k + ': ' + this.prettyprint(something[k], true));
                        }
                    }
                    return '[' + x.join(', ') + ']';
                }
                else
                {
                    return 'object: ' + something;
                }
            default:
                return type + ': ' + something;
            }
        }
        this.lazy_escape = function (str)
        {
            return str.replace(/</g, '&lt;').replace(/\>/g, '&gt;').replace(/\n/g, '<br />');
        }
        this.log = function ()
        {
            // comments by Microshaoft begin ======================================================
            //        if (window.console) {
            //            if (console.firebug) {
            //                console.log.apply(console, Array.prototype.slice.call(arguments));
            //            } else {
            //                console.log.call(console, Array.prototype.slice.call(arguments));
            //            }
            //        }
            // comments by Microshaoft end ======================================================
        };
    }
    // add by Microshaoft begin ===========================================================
    WScript.Echo("/*");
    WScript.Echo(" * Beautifyed by using \"Microshaoft.beautify.CScript.js\"");
    WScript.Echo(" * \"Microshaoft.beautify.exe\" is invented for EditPlus user tool by using WScript");
    WScript.Echo(" * Thanks for \"http://jsbeautifier.org/\" supply \"https://github.com/einars/js-beautify\"");
    WScript.Echo(" */");
    var opts =
                {
                    indent_size: 1,
                    indent_char: '\t',
                    preserve_newlines: true,
                    brace_style: "expand-strict",
                    keep_array_indentation: true,
                    space_after_anon_function: true,
                    space_before_conditional: true,
                    indent_scripts: true
                };
    s = beautify(s, opts);
    WScript.Echo(s);
    // add by Microshaoft end ===========================================================
    
    
  • 相关阅读:
    CCF CSP 题解
    CCF CSP 2019032 二十四点
    CCF CSP 2018121 小明上学
    CCF CSP 2019092 小明种苹果(续)
    CCF CSP 2019091 小明种苹果
    CCF CSP 2019121 报数
    CCF CSP 2019031 小中大
    CCF CSP 2020061 线性分类器
    CCF CSP 2020062 稀疏向量
    利用国家气象局的webservice查询天气预报(转载)
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2485221.html
Copyright © 2011-2022 走看看