[
  {
    "path": ".gitignore",
    "content": "output/\n"
  },
  {
    "path": "Fiddler.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKyyd3FMz631KwQ6A\noKT4lmDkKHvDf0H9NkgP0lcHz1sc9H1KFv8IopWd31Yex/ydKgq4rCklB0Pldy0Dr\n3DRH7IHQqERLeMFP19pT8fhgJokRPu0CdxwZKQ/Mh83y4J1aW6kAvxvXBXIZZZn78\nqDlGFgR94hGlV0P55ZThas/Z9AgMBAAECgYBrclI8LOUdv2b3Jzx+j5IJzYCEL97N\nKlEdciHN+8H4Dmz1GYn1ySaYWXnYg99/HfOU2bHW416/wf2kpmZxjHclQBQdEe36/\ns8gvapWrDso+tkvTNUWd9YVqD9a21YC1oZVzCPn8+RKh4+/ZZlzt/2Hn9qsutkgVH\ncoj+bItN5f5QJBAODPrawzdt7R6noaSRmXH9rTX5PcaEkTBgE7ngkgJKKDyPfoAel\nHwVoB3lpw7/5GPRzpqHzmrsWcqwlb8eWILH8CQQDEp+u2yrJqte1VGr1TdzMHk+oy\nx+DBP6uReYkQCMGQMnMfwPUYkyBbpJAQdJ9iODnk64p2GfuL/q1cty6QgA8DAkEA0\nLS8/QMCNjYXQqgoeRNtxU86iiCyyDRa/MYGH16x5BYIeu3u6E1vWUomzTvP8fXvQm\npBu0LFujuKJbQwS/ExrQJAMJ02Rvy6uGh64CP5E44O/luRdLY2mG8t8Yty15TijMv\n766ierlGImT8IIhlCYVx262FS3Dk2FviBUL8z8qLFkwJBALp7QMOcGzeEG3pmvCie\ntqvEs4Nkw8p8itKF2Bs/5t5+Juy6aZobMFyN+JNtLbtplFBnShGKc+qjWH/F3pWTE\n2s=\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "README.md",
    "content": "[WARNING] 该项目停止维护，愿意维护的同学请联系 welefen@gmail.com，可以把项目转给你。\n\nFiddler\n=======\n\nFiddler for Chrome Extension\n\nvisit http://welefen.github.io/Fiddler/ for more infomation.\n"
  },
  {
    "path": "build.sh",
    "content": "#!/bin/sh\nSTC_PATH=\"/Users/welefen/Develop/git/stc/src\"\npath=`dirname $0`;\nfirst=${path:0:1};\nif [[ $first != '/' ]];then\n    path=$(pwd);\nfi\n\nif [ -d ${path}\"/output\" ];then\n\trm -rf ${path}\"/output\";\nfi\nmkdir ${path}\"/output\";\nif [ ! -f ${path}\"/config.php\" ];then\n\tcp $STC_PATH/config/config.php ${path};\nfi\n#path=$(pwd);\n/usr/local/bin/php $STC_PATH/index.php ${path} test online;\nif [ -f ${path}\"/stc.error.log\" ]; then\n    rm -rf ${path}\"/stc.error.log\";\n    #exit 1;\nfi\ncp src/manifest.json output/src/\ncp -r src/bin output/src/;\nmv output/src/ output/Fiddler;\nif [[ $1 == \"1\" ]];then\n    /usr/local/bin/php clean.php;\n    cd output;\n    zip -r Fiddler.zip Fiddler/;\nfi\n"
  },
  {
    "path": "clean.php",
    "content": "<?php\n$file = \"output/Fiddler/manifest.json\";\n$content = file_get_contents($file);\n$data = json_decode($content, true);\nunset($data[\"plugins\"]);\nunset($data[\"update_url\"]);\n$content = json_encode($data);\nfile_put_contents($file, $content);\n"
  },
  {
    "path": "config.php",
    "content": "<?php\nreturn array (\n\t'TPL_ENGINE' => 'smarty',  //模版引擎，支持Smarty和PHP\n\t'TPL_LEFT_DELIMITER' => '{%',  //smarty左界符\n\t'TPL_RIGHT_DELIMITER' => '%}',  //smarty右界符\n\t'TPL_SUFFIX' => 'tpl',  //模板文件后缀名\n\t'TPL_PATH' => 'src/application/views/tpls/',  //模板目录\n\t'STATIC_PATH' => 'src/',  //静态资源的目录\n\t'FILE_ENCODING' => 'utf-8',  //项目编码\n\t'MOD_DIRS_CHECK' => true,  //目录结构检测\n\t'MOD_FILE_CHECK' => true,  //文件命名和位置检测\n\t'MOD_HTML_REGULAR_CHECK' => true,  //HTML规范检测\n\t'MOD_CSS_REGULAR_CHECK' => true,  //CSS规范检测\n\t\"MOD_EMPTY_CHECK\" => true,  //空文件检测\n\t'MOD_CSS_SPRITES' => false,  //是否进行css sprites\n\t'MOD_CSS_AUTOCOMPLETE' => false,  //css样式自动补全\n\t'MOD_JS_COMBINE' => true,  //JS文件是否启用合并\n\t'MOD_CSS_COMBINE' => true,  //CSS文件是否启用合并\n\t'MOD_HTML_COMPRESS' => true,  //HTML文件是否启用压缩\n\t'MOD_JS_COMPRESS' => true,  //JS文件是否启用压缩\n\t'MOD_CSS_COMPRESS' => true,  //CSS文件是否启用压缩\n\t'MOD_OPTI_IMG' => false,  //是否优化图片\n\t'MOD_XSS_AUTO_FIXED' => false,  //是否进行XSS自动修复\n\t'MOD_IMG_DATAURI' => true,  //将CSS中的图片地址转换为dataURI\n\t'MOD_STATIC_TO_CDN' => false,  //是否将静态资源上线到CDN\n\t'MOD_JS_TPL_REPLACE' => false,  //是否进行前端模版替换\n\t'MOD_STRING_REPLACE' => true,  //是否进行代码替换功能\n\t'MOD_STATIC_VERSION' => 1,  //静态文件版本号，1或者true为query,2为新文件模式\n\t'COMPRESS_JS_USE_JINGCHUANG' => false,\n    'HTML_COMPRESS_OPTIONS' => array('compress_tpl_script'=> true)\n);\n\n\n"
  },
  {
    "path": "plugin/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>English</string>\n\t<key>CFBundleExecutable</key>\n\t<string>chrome_fiddler</string>\n\t<key>CFBundleGetInfoString</key>\n\t<string>420+, Copyright 2006-2009 Apple Inc.</string>\n\t<key>CFBundleIconFile</key>\n\t<string></string>\n\t<key>CFBundleIdentifier</key>\n\t<string>chrome.chrome_fiddler</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BRPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n\t<key>CFPlugInDynamicRegisterFunction</key>\n\t<string></string>\n\t<key>CFPlugInDynamicRegistration</key>\n\t<string>NO</string>\n\t<key>CFPlugInFactories</key>\n\t<dict>\n\t\t<key>00000000-0000-0000-0000-000000000000</key>\n\t\t<string>MyFactoryFunction</string>\n\t</dict>\n\t<key>CFPlugInTypes</key>\n\t<dict>\n\t\t<key>00000000-0000-0000-0000-000000000000</key>\n\t\t<array>\n\t\t\t<string>00000000-0000-0000-0000-000000000000</string>\n\t\t</array>\n\t</dict>\n\t<key>CFPlugInUnloadFunction</key>\n\t<string></string>\n\t<key>WebPluginDescription</key>\n\t<string>Chrome Fiddler Extension Plugin</string>\n\t<key>WebPluginMIMETypes</key>\n\t<dict>\n\t\t<key>application/x-chromefiddler</key>\n\t\t<dict>\n\t\t\t<key>WebPluginExtensions</key>\n\t\t\t<array>\n\t\t\t\t<string>chrome_fiddler</string>\n\t\t\t</array>\n\t\t\t<key>WebPluginTypeDescription</key>\n\t\t\t<string>Chrome Fiddler Extension Plugin</string>\n\t\t</dict>\n\t</dict>\n\t<key>WebPluginName</key>\n\t<string>Chrome Fiddler Extension Plugin</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "plugin/README.md",
    "content": "* prototype from [chrome-screen-capture](http://chrome-screen-capture.googlecode.com/svn/trunk/src/plugin)\n\n## Summary\n\n现阶段主要功能是，弹出系统文件选择框，用户通过选择、确定后，将所选文件或文件夹路径返回\n\n## Methods\n\n    var path = plugin.GetFilePath(initial_path, dialog_title);\n\n弹出文件选择框，返回所选文件路径\n\n* `initial_path` 是文件选择框的初始位置\n* `dialog_title` 是文件选择框上方的标题\n* `path` 是用户所选文件的路径\n\n- - -\n\n    var path = plugin.GetFolderPath(initial_path, dialog_title);\n\n弹出文件夹选择框，返回所选文件夹路径\n\n* `initial_path` 是文件夹选择框的初始位置\n* `dialog_title` 是文件夹选择框上方的标题\n* `path` 是用户所选文件夹的路径\n\n- - -\n\n    var path = plugin.OpenFileDialog(initial_path, option)\n\n**Deprecated.** 此方法是上面两个方法的结合，缺点在于不能对文件选择框的标题进行设置。\n由于前期方法名字起的不好，没准哪天心情不好就去除了，所以标记不建议使用了。\n\n* `initial_path` 是文件或文件夹选择框的初始位置\n* `option` 是 `\"file\"` 则打开文件选择框，是 `\"path\"` 则打开文件夹选择框\n* `path` 是用户所选文件或文件夹的路径\n\n## Example\n\nMac OSX 下的文件 [chrome_fiddler.plugin][1]，Windows 下的文件 [chrome_fiddler.dll][2]，type 为 `application/x-chromefiddler`\n\n[1]: https://github.com/welefen/Fiddler/tree/master/plugin/chrome_fiddler.plugin\n[2]: https://github.com/welefen/Fiddler/blob/master/plugin/chrome_fiddler_vs2008_project/Release/chrome_fiddler.dll\n\n    <!doctype html>\n    <html>\n        <head>\n            <script>\n                window.onload = function(e) {\n                    var plugin = document.getElementById(\"chromefiddler\");\n                };\n            </script>\n        </head>\n        <body>\n            <embed id=\"chromefiddler\" type=\"application/x-chromefiddler\">\n        </body>\n    </html>\n\n"
  },
  {
    "path": "plugin/build_mac.sh",
    "content": "#!/bin/sh\nmkdir -p chrome_fiddler.plugin/Contents/MacOS\ncp -f Info.plist chrome_fiddler.plugin/Contents\ng++ -framework Cocoa -DMAC -Wall \\\n    -DWEBKIT_DARWIN_SDK -lresolv -arch i386 -bundle \\\n    -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/ \\\n    -mmacosx-version-min=10.6 \\\n    -o chrome_fiddler.plugin/Contents/MacOS/chrome_fiddler \\\n    log.cc np_entry.cc npn_entry.cc npp_entry.cc plugin_base.cc \\\n    plugin_factory.cc chrome_fiddler.mm chrome_fiddler_plugin.cc \\\n    chrome_fiddler_script_object.cc script_object_base.cc script_object_factory.cc &&\\\ncp chrome_fiddler.plugin/Contents/MacOS/chrome_fiddler \\\n    ../src/bin/chrome_fiddler.plugin/Contents/MacOS/\n"
  },
  {
    "path": "plugin/chrome_fiddler.mm",
    "content": "#include <string>\n#import <Cocoa/Cocoa.h>\n\n\nstd::string GetFilePathNS(const char* path, const char* dialog_title, bool isFolder) {\n    int runResult;\n    NSString *str = [NSString stringWithUTF8String:path];\n    str = [NSString stringWithFormat:@\"%@%@\", @\"file://\", str];\n    NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];\n\n    NSOpenPanel *op = [NSOpenPanel openPanel];\n\n    if (isFolder) {\n        [op setCanChooseDirectories:YES];\n        [op setCanChooseFiles:NO];\n    } else {\n        [op setCanChooseDirectories:NO];\n        [op setCanChooseFiles:YES];\n    }\n    [op setAllowsMultipleSelection:NO];\n    [op setDirectoryURL:url];\n    [op setTitle:[NSString stringWithUTF8String:dialog_title]];\n\n    runResult = [op runModal];\n\n    if (runResult == NSOKButton) {\n        NSArray *paths = [op URLs];\n        return [[[paths lastObject] path] UTF8String];\n    } else {\n        return [[NSString stringWithUTF8String:path] UTF8String];\n    }\n}\n\nbool IsWritableFile(const char* path) {\n    NSFileManager *fm = [NSFileManager defaultManager];\n    return [fm isWritableFileAtPath:[NSString stringWithUTF8String:path]];\n}\n\n"
  },
  {
    "path": "plugin/chrome_fiddler.plugin/Contents/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>English</string>\n\t<key>CFBundleExecutable</key>\n\t<string>chrome_fiddler</string>\n\t<key>CFBundleGetInfoString</key>\n\t<string>420+, Copyright 2006-2009 Apple Inc.</string>\n\t<key>CFBundleIconFile</key>\n\t<string></string>\n\t<key>CFBundleIdentifier</key>\n\t<string>chrome.chrome_fiddler</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BRPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n\t<key>CFPlugInDynamicRegisterFunction</key>\n\t<string></string>\n\t<key>CFPlugInDynamicRegistration</key>\n\t<string>NO</string>\n\t<key>CFPlugInFactories</key>\n\t<dict>\n\t\t<key>00000000-0000-0000-0000-000000000000</key>\n\t\t<string>MyFactoryFunction</string>\n\t</dict>\n\t<key>CFPlugInTypes</key>\n\t<dict>\n\t\t<key>00000000-0000-0000-0000-000000000000</key>\n\t\t<array>\n\t\t\t<string>00000000-0000-0000-0000-000000000000</string>\n\t\t</array>\n\t</dict>\n\t<key>CFPlugInUnloadFunction</key>\n\t<string></string>\n\t<key>WebPluginDescription</key>\n\t<string>Chrome Fiddler Extension Plugin</string>\n\t<key>WebPluginMIMETypes</key>\n\t<dict>\n\t\t<key>application/x-chromefiddler</key>\n\t\t<dict>\n\t\t\t<key>WebPluginExtensions</key>\n\t\t\t<array>\n\t\t\t\t<string>chrome_fiddler</string>\n\t\t\t</array>\n\t\t\t<key>WebPluginTypeDescription</key>\n\t\t\t<string>Chrome Fiddler Extension Plugin</string>\n\t\t</dict>\n\t</dict>\n\t<key>WebPluginName</key>\n\t<string>Chrome Fiddler Extension Plugin</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "plugin/chrome_fiddler_plugin.cc",
    "content": "#include \"chrome_fiddler_plugin.h\"\n\n#include <string.h>\n\n#include \"log.h\"\n#include \"chrome_fiddler_script_object.h\"\n#include \"script_object_factory.h\"\n\n\nextern Log g_logger;\n\nNPError ChromeFiddlerPlugin::Init(NPP instance, uint16_t mode, int16_t argc, char* argn[],char* argv[], NPSavedData* saved) {\n    g_logger.WriteLog(\"msg\", \"ChromeFiddlerPlugin Init\");\n    script_object_ = NULL;\n\n#ifdef _WINDOWS\n    int bWindowed = 1;\n#else\n    int bWindowed = 0;\n#endif\n\n#ifdef MAC\n    // Select the right drawing model if necessary.\n    NPBool support_core_graphics = false;\n    if (NPN_GetValue(instance, NPNVsupportsCoreGraphicsBool, &support_core_graphics) == NPERR_NO_ERROR && support_core_graphics)\n        NPN_SetValue(instance, NPPVpluginDrawingModel, (void*)NPDrawingModelCoreGraphics);\n    else\n        return NPERR_INCOMPATIBLE_VERSION_ERROR;\n\n    // Select the Cocoa event model.\n    NPBool support_cocoa_events = false;\n    if (NPN_GetValue(instance, NPNVsupportsCocoaBool, &support_cocoa_events) == NPERR_NO_ERROR && support_cocoa_events)\n        NPN_SetValue(instance, NPPVpluginEventModel, (void*)NPEventModelCocoa);\n    else\n        return NPERR_INCOMPATIBLE_VERSION_ERROR;\n#endif\n\n    NPN_SetValue(instance, NPPVpluginWindowBool, (void *)bWindowed);\n    instance->pdata = this;\n    return PluginBase::Init(instance, mode, argc, argn, argv, saved);\n}\n\nNPError ChromeFiddlerPlugin::UnInit(NPSavedData** save) {\n    g_logger.WriteLog(\"msg\", \"ChromeFiddlerPlugin UnInit\");\n    g_logger.CloseLog();\n    PluginBase::UnInit(save);\n    script_object_ = NULL;\n    return NPERR_NO_ERROR;\n}\n\nNPError ChromeFiddlerPlugin::GetValue(NPPVariable variable, void *value) {\n    switch(variable) {\n        case NPPVpluginScriptableNPObject:\n            if (script_object_ == NULL)\n                script_object_ = ScriptObjectFactory::CreateObject(get_npp(), ChromeFiddlerScriptObject::Allocate);\n            if (script_object_ != NULL)\n                *(NPObject**)value = script_object_;\n            else\n                return NPERR_OUT_OF_MEMORY_ERROR;\n            break;\n        case NPPVpluginNeedsXEmbed:\n            *(bool*)value = 1;\n            break;\n        default:\n            return NPERR_GENERIC_ERROR;\n    }\n    return NPERR_NO_ERROR;\n}\n\nNPError ChromeFiddlerPlugin::SetWindow(NPWindow* window) {\n#ifdef _WINDOWS\n    PluginBase::SetWindow(window);\n#endif\n\n    return NPERR_NO_ERROR;\n}\n\n"
  },
  {
    "path": "plugin/chrome_fiddler_plugin.h",
    "content": "#ifndef CHROME_FIDDLER_PLUGIN_H_\n#define CHROME_FIDDLER_PLUGIN_H_\n\n#include \"npapi.h\"\n#include \"npruntime.h\"\n#include \"npfunctions.h\"\n#include \"plugin_base.h\"\n#include \"script_object_base.h\"\n\nclass ChromeFiddlerPlugin : public PluginBase {\npublic:\n    ChromeFiddlerPlugin() {}\n    virtual ~ChromeFiddlerPlugin() {}\n\n    NPError Init(NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved);\n    NPError UnInit(NPSavedData** saved);\n    NPError GetValue(NPPVariable variable, void *value);\n    NPError SetWindow(NPWindow* window);\n\n    static PluginBase* CreateObject() { return new ChromeFiddlerPlugin; }\n\nprivate:\n    ScriptObjectBase* script_object_;\n};\n\n#endif // CHROME_FIDDLER_PLUGIN_H_\n"
  },
  {
    "path": "plugin/chrome_fiddler_script_object.cc",
    "content": "#include \"chrome_fiddler_script_object.h\"\n\n#include <stdlib.h>\n#include <string.h>\n\n#ifdef _WINDOWS\n#include <atlenc.h>\n#include <GdiPlus.h>\n#include <io.h>\n#include <ShlObj.h>\n#elif defined __APPLE__\n#include <libgen.h>\n#include <resolv.h>\n#endif\n\n#include <string>\n\n#include \"log.h\"\n#include \"chrome_fiddler_plugin.h\"\n#include \"utils.h\"\n\n#ifdef _WINDOWS\nusing namespace Gdiplus;\n#define snprintf sprintf_s\nstruct BrowserParam {\n    TCHAR initial_path[MAX_PATH];\n    TCHAR title[MAX_PATH];\n};\n#else\n#define MAX_PATH 260\n#endif\n\nextern Log g_logger;\n\nNPObject* ChromeFiddlerScriptObject::Allocate(NPP npp, NPClass *aClass) {\n    g_logger.WriteLog(\"msg\", \"ChromeFiddlerScriptObject Allocate\");\n    ChromeFiddlerScriptObject* script_object = new ChromeFiddlerScriptObject;\n    if (script_object != NULL)\n        script_object->set_plugin((PluginBase*)npp->pdata);\n    return script_object;\n}\n\nvoid ChromeFiddlerScriptObject::Deallocate() {\n    g_logger.WriteLog(\"msg\", \"ChromeFiddlerScriptObject Deallocate\");\n    delete this;\n}\n\nvoid ChromeFiddlerScriptObject::InitHandler() {\n    FunctionItem item;\n    item.function_name = \"OpenFileDialog\";\n    item.function_pointer = ON_INVOKEHELPER(&ChromeFiddlerScriptObject::OpenFileDialog);\n    AddFunction(item);\n    item.function_name = \"GetFilePath\";\n    item.function_pointer = ON_INVOKEHELPER(&ChromeFiddlerScriptObject::GetFilePath);\n    AddFunction(item);\n    item.function_name = \"GetFolderPath\";\n    item.function_pointer = ON_INVOKEHELPER(&ChromeFiddlerScriptObject::GetFolderPath);\n    AddFunction(item);\n    item.function_name = \"SaveFile\";\n    item.function_pointer = ON_INVOKEHELPER(&ChromeFiddlerScriptObject::SaveFile);\n    AddFunction(item);\n}\n\n#ifdef _WINDOWS\nnamespace {\n\nint WINAPI BrowserCallback(NativeWindow nw, UINT uMsg, LPARAM lParam, LPARAM lpData) {\n    switch (uMsg) {\n    case BFFM_INITIALIZED:\n        BrowserParam* param = (BrowserParam*)lpData;\n        SendMessage(nw, BFFM_SETSELECTION, TRUE, (LPARAM)param->initial_path);\n        SetWindowText(nw, param->title);\n        NativeWindow treeview = FindWindowEx(nw, NULL, L\"SysTreeView32\", NULL);\n        NativeWindow ok_button = FindWindowEx(nw, NULL, L\"Button\", NULL);\n\n        if (treeview && ok_button) {\n            RECT rect_treeview,rect_ok_button;\n\n            GetWindowRect(treeview, &rect_treeview);\n            POINT pt_treeview, pt_button;\n            pt_treeview.x = rect_treeview.left;\n            pt_treeview.y = 0;\n            ScreenToClient(nw, &pt_treeview);\n\n            GetWindowRect(ok_button, &rect_ok_button);\n            pt_button.x = rect_ok_button.left;\n            pt_button.y = rect_ok_button.top;\n            ScreenToClient(nw, &pt_button);\n            MoveWindow(treeview, pt_treeview.x, pt_treeview.x, rect_treeview.right-rect_treeview.left, pt_button.y-2*pt_treeview.x, TRUE);\n        }\n        break;\n    }\n    return 0;\n}\n\n}\n#elif defined __APPLE__\nstd::string GetFilePathNS(const char* path, const char* dialog_title, bool isFolder);\nbool IsWritableFile(const char* path);\n#endif\n\nbool ChromeFiddlerScriptObject::OpenFileDialog(const NPVariant* args, uint32_t argCount, NPVariant* result) {\n    if (argCount < 2 || !NPVARIANT_IS_STRING(args[0]) || !NPVARIANT_IS_STRING(args[1]))\n        return false;\n\n    std::string option(NPVARIANT_TO_STRING(args[1]).UTF8Characters, NPVARIANT_TO_STRING(args[1]).UTF8Length);\n    std::string title = \"Select A Stuff, Buddy\";\n    size_t length = title.length();\n\n    NPVariant dialog_title;\n    STRINGN_TO_NPVARIANT(title.c_str(), length, dialog_title);\n    const NPVariant params[2] = {args[0], dialog_title};\n\n    if (option == \"file\")\n        return GetFilePath(params, 2, result);\n    else\n        return GetFolderPath(params, 2, result);\n}\n\nbool ChromeFiddlerScriptObject::GetFilePath(const NPVariant* args, uint32_t argCount, NPVariant* result) {\n    if (argCount < 2 || !NPVARIANT_IS_STRING(args[0]) || !NPVARIANT_IS_STRING(args[1]))\n        return false;\n\n    std::string path(NPVARIANT_TO_STRING(args[0]).UTF8Characters, NPVARIANT_TO_STRING(args[0]).UTF8Length);\n    std::string title(NPVARIANT_TO_STRING(args[1]).UTF8Characters, NPVARIANT_TO_STRING(args[1]).UTF8Length);\n\n#ifdef _WINDOWS\n    TCHAR display_name[MAX_PATH] = {0};\n    BrowserParam param = {0};\n    BOOL bRet;\n\n    MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, param.initial_path, MAX_PATH);\n    MultiByteToWideChar(CP_UTF8, 0, title.c_str(), -1, param.title, MAX_PATH);\n\n    OPENFILENAME ofn = {0};\n    ofn.lStructSize = sizeof(ofn);\n    ofn.hwndOwner = get_plugin()->get_native_window();\n    ofn.lpstrFilter = _T(\"All Files(*.*)\\0*.*\\0\");\n    ofn.lpstrInitialDir = param.initial_path;\n    ofn.lpstrFile = display_name;\n    ofn.nMaxFile = sizeof(display_name) / sizeof(*display_name);\n    ofn.nFilterIndex = 0;\n    ofn.lpstrTitle = param.title;\n    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;\n\n    bRet = GetOpenFileName(&ofn);\n\n    char utf8[MAX_PATH];\n    WideCharToMultiByte(CP_UTF8, 0, bRet ? display_name : param.initial_path, -1, utf8, MAX_PATH, 0, 0);\n    size_t length = strlen(utf8);\n\n#elif __APPLE__\n    std::string pathStr = GetFilePathNS(path.c_str(), title.c_str(), false);\n    const char* utf8 = pathStr.c_str();\n    size_t length = pathStr.length();\n\n#endif\n\n    char* copy = (char *)NPN_MemAlloc(length + 1);\n    memcpy(copy, utf8, length);\n    copy[length] = 0;\n    STRINGN_TO_NPVARIANT(copy, length, *result);\n\n    return true;\n}\n\nbool ChromeFiddlerScriptObject::GetFolderPath(const NPVariant* args, uint32_t argCount, NPVariant* result) {\n    if (argCount < 2 || !NPVARIANT_IS_STRING(args[0]) || !NPVARIANT_IS_STRING(args[1]))\n        return false;\n\n    std::string path(NPVARIANT_TO_STRING(args[0]).UTF8Characters, NPVARIANT_TO_STRING(args[0]).UTF8Length);\n    std::string title(NPVARIANT_TO_STRING(args[1]).UTF8Characters, NPVARIANT_TO_STRING(args[1]).UTF8Length);\n\n#ifdef _WINDOWS\n    TCHAR display_name[MAX_PATH] = {0};\n    BrowserParam param = {0};\n    BOOL bRet;\n\n    MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, param.initial_path, MAX_PATH);\n    MultiByteToWideChar(CP_UTF8, 0, title.c_str(), -1, param.title, MAX_PATH);\n\n    BROWSEINFO info = {0};\n    info.hwndOwner = get_plugin()->get_native_window();\n    info.lpszTitle = NULL;\n    info.pszDisplayName = display_name;\n    info.lpfn = BrowserCallback;\n    info.ulFlags = BIF_RETURNONLYFSDIRS;\n    info.lParam = (LPARAM)&param;\n\n    bRet = SHGetPathFromIDList(SHBrowseForFolder(&info), display_name);\n\n    char utf8[MAX_PATH];\n    WideCharToMultiByte(CP_UTF8, 0, bRet ? display_name : param.initial_path, -1, utf8, MAX_PATH, 0, 0);\n    size_t length = strlen(utf8);\n\n#elif __APPLE__\n    std::string pathStr = GetFilePathNS(path.c_str(), title.c_str(), true);\n    const char* utf8 = pathStr.c_str();\n    size_t length = pathStr.length();\n\n#endif\n\n    char* copy = (char *)NPN_MemAlloc(length + 1);\n    memcpy(copy, utf8, length);\n    copy[length] = 0;\n    STRINGN_TO_NPVARIANT(copy, length, *result);\n\n    return true;\n}\n\nbool ChromeFiddlerScriptObject::SaveFile(const NPVariant* args, uint32_t argCount, NPVariant* result) {\n    if (argCount < 3 || !NPVARIANT_IS_STRING(args[0]) || !NPVARIANT_IS_STRING(args[1]) || !NPVARIANT_IS_OBJECT(args[2]) || !NPVARIANT_TO_OBJECT(args[2]))\n        return false;\n\n    const char* fileName = NPVARIANT_TO_STRING(args[0]).UTF8Characters;\n    const char* content = NPVARIANT_TO_STRING(args[1]).UTF8Characters;\n    uint32_t length = NPVARIANT_TO_STRING(args[1]).UTF8Length;\n    NPObject* callback = NPVARIANT_TO_OBJECT(args[2]);\n\n#ifdef _WINDOWS\n    TCHAR szWideBuf[MAX_PATH] = { 0 };\n    MultiByteToWideChar(CP_UTF8, 0, fileName, -1, szWideBuf, MAX_PATH);\n    DWORD d = GetFileAttributes(szWideBuf);\n    if (!PathFileExists(szWideBuf) || d & FILE_ATTRIBUTE_DIRECTORY || d & FILE_ATTRIBUTE_READONLY) {\n        g_logger.WriteLog(\"error\", \"SaveFile: Is A Folder\");\n\n#elif defined __APPLE__\n    if (!IsWritableFile(fileName)) {\n        g_logger.WriteLog(\"error\", \"SaveFile: File Is Not Writable\");\n\n#endif\n        InvokeCallback(get_plugin()->get_npp(), callback, \"failure\");\n        return true;\n    }\n\n#ifdef _WINDOWS\n    int len = MultiByteToWideChar(CP_UTF8, 0, fileName, -1, NULL, 0);\n    wchar_t* wstr = new wchar_t[len + 1];\n    memset(wstr, 0, len * 2 + 2);\n    MultiByteToWideChar(CP_UTF8, 0, fileName, -1, wstr, len);\n\n    len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);\n    char* path = new char[len + 1];\n    memset(path, 0, len + 1);\n    WideCharToMultiByte (CP_ACP, 0, wstr, -1, path, len, NULL, NULL);\n\n    delete[] wstr;\n    FILE* out = fopen(path, \"w\");\n\n#elif defined __APPLE__\n    FILE* out = fopen(fileName, \"w\");\n\n#endif\n    if (out) {\n        fwrite(content, length, 1, out);\n        fclose(out);\n        InvokeCallback(get_plugin()->get_npp(), callback, \"success\");\n        return true;\n    }\n\n    g_logger.WriteLog(\"error\", \"SaveFile: File Cannot Open\");\n    InvokeCallback(get_plugin()->get_npp(), callback, \"failure\");\n    return true;\n}\n\n// static\nvoid ChromeFiddlerScriptObject::InvokeCallback(NPP npp, NPObject* callback, const char* param) {\n    NPVariant npParam;\n    STRINGZ_TO_NPVARIANT(param, npParam);\n    NPVariant result;\n    VOID_TO_NPVARIANT(result);\n    NPN_InvokeDefault(npp, callback, &npParam, 1, &result);\n}\n\n"
  },
  {
    "path": "plugin/chrome_fiddler_script_object.h",
    "content": "#ifndef CHROME_FIDDLER_SCRIPT_OBJECT_H_\n#define CHROME_FIDDLER_SCRIPT_OBJECT_H_\n\n#include \"npfunctions.h\"\n#include \"script_object_base.h\"\n\nclass ChromeFiddlerScriptObject: public ScriptObjectBase {\npublic:\n    ChromeFiddlerScriptObject() {}\n    virtual ~ChromeFiddlerScriptObject() {}\n\n    static NPObject* Allocate(NPP npp, NPClass* aClass);\n\n    void Deallocate();\n    void Invalidate() {}\n    bool Construct(const NPVariant* args, uint32_t argCount, NPVariant* result) { return true; }\n    bool OpenFileDialog(const NPVariant* args, uint32_t argCount, NPVariant* result);\n    bool GetFilePath(const NPVariant* args, uint32_t argCount, NPVariant* result);\n    bool GetFolderPath(const NPVariant* args, uint32_t argCount, NPVariant* result);\n    bool SaveFile(const NPVariant* args, uint32_t argCount, NPVariant* result);\n\n    void InitHandler();\n\nprivate:\n    static void InvokeCallback(NPP npp, NPObject* callback, const char* param);\n\n};\n\n#endif    // CHROME_FIDDLER_SCRIPT_OBJECT_H_\n"
  },
  {
    "path": "plugin/chrome_fiddler_vs2008_project/chrome_fiddler/chrome_fiddler.def",
    "content": "LIBRARY\t\"chrome_fiddler\"\r\n\r\nEXPORTS\r\n\tNP_GetEntryPoints     @1\r\n\tNP_Initialize         @2\r\n\tNP_Shutdown           @3\r\n\tNP_GetMIMEDescription @4"
  },
  {
    "path": "plugin/chrome_fiddler_vs2008_project/chrome_fiddler/chrome_fiddler.rc",
    "content": "// Microsoft Visual C++ generated resource script.\r\n//\r\n#include \"resource.h\"\r\n\r\n#define APSTUDIO_READONLY_SYMBOLS\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Generated from the TEXTINCLUDE 2 resource.\r\n//\r\n#include \"winresrc.h\"\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n#undef APSTUDIO_READONLY_SYMBOLS\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n// (л񹲺͹) resources\r\n\r\n#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n#ifdef _WIN32\r\nLANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED\r\n#pragma code_page(936)\r\n#endif //_WIN32\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Dialog\r\n//\r\n\r\nIDD_PREVIEW DIALOGEX 0, 0, 366, 211\r\nSTYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU\r\nEXSTYLE WS_EX_TOOLWINDOW\r\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\r\nBEGIN\r\nEND\r\n\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// DESIGNINFO\r\n//\r\n\r\n#ifdef APSTUDIO_INVOKED\r\nGUIDELINES DESIGNINFO \r\nBEGIN\r\n    IDD_PREVIEW, DIALOG\r\n    BEGIN\r\n        LEFTMARGIN, 7\r\n        RIGHTMARGIN, 359\r\n        TOPMARGIN, 7\r\n        BOTTOMMARGIN, 204\r\n    END\r\nEND\r\n#endif    // APSTUDIO_INVOKED\r\n\r\n#endif    // (л񹲺͹) resources\r\n/////////////////////////////////////////////////////////////////////////////\r\n\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n// Ӣ() resources\r\n\r\n#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n#ifdef _WIN32\r\nLANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r\n#pragma code_page(1252)\r\n#endif //_WIN32\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Version\r\n//\r\n\r\nVS_VERSION_INFO VERSIONINFO\r\n FILEVERSION 1,0,0,1\r\n PRODUCTVERSION 1,0,0,1\r\n FILEFLAGSMASK 0x3fL\r\n#ifdef _DEBUG\r\n FILEFLAGS 0x1L\r\n#else\r\n FILEFLAGS 0x0L\r\n#endif\r\n FILEOS 0x40004L\r\n FILETYPE 0x2L\r\n FILESUBTYPE 0x0L\r\nBEGIN\r\n    BLOCK \"StringFileInfo\"\r\n    BEGIN\r\n        BLOCK \"040904e4\"\r\n        BEGIN\r\n\t\t\tVALUE \"FileDescription\", \"This is a npapi plugin built for Chrome on Windows.\"\r\n            VALUE \"FileOpenName\", \"Chrome Fiddler Plugin\"\r\n            VALUE \"FileVersion\", \"1, 0, 0, 1\"\r\n            VALUE \"InternalName\", \"ChromeFiddlerPlugin\"\r\n            VALUE \"LegalCopyright\", \"Copyright 2013 Ice White\"\r\n            VALUE \"MIMEType\", \"application/x-chromefiddler\"\r\n            VALUE \"OriginalFilename\", \"chrome_fiddler.dll\"\r\n            VALUE \"ProductName\", \"Chrome Fiddler Plugin\"\r\n            VALUE \"ProductVersion\", \"1, 0, 0, 1\"\r\n        END\r\n    END\r\n    BLOCK \"VarFileInfo\"\r\n    BEGIN\r\n        VALUE \"Translation\", 0x409, 1252\r\n    END\r\nEND\r\n\r\n\r\n#ifdef APSTUDIO_INVOKED\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// TEXTINCLUDE\r\n//\r\n\r\n1 TEXTINCLUDE \r\nBEGIN\r\n    \"resource.h\\0\"\r\nEND\r\n\r\n2 TEXTINCLUDE \r\nBEGIN\r\n    \"#include \"\"winresrc.h\"\"\\r\\n\"\r\n    \"\\0\"\r\nEND\r\n\r\n3 TEXTINCLUDE \r\nBEGIN\r\n    \"\\r\\n\"\r\n    \"\\0\"\r\nEND\r\n\r\n#endif    // APSTUDIO_INVOKED\r\n\r\n#endif    // Ӣ() resources\r\n/////////////////////////////////////////////////////////////////////////////\r\n\r\n\r\n\r\n#ifndef APSTUDIO_INVOKED\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Generated from the TEXTINCLUDE 3 resource.\r\n//\r\n\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n#endif    // not APSTUDIO_INVOKED\r\n\r\n"
  },
  {
    "path": "plugin/chrome_fiddler_vs2008_project/chrome_fiddler/chrome_fiddler.vcproj",
    "content": "<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n<VisualStudioProject\r\n\tProjectType=\"Visual C++\"\r\n\tVersion=\"9.00\"\r\n\tName=\"chrome_fiddler\"\r\n\tProjectGUID=\"{DD996793-2B7D-464D-BA6A-0B9CB08557EE}\"\r\n\tRootNamespace=\"chrome_fiddler\"\r\n\tKeyword=\"Win32Proj\"\r\n\tTargetFrameworkVersion=\"196613\"\r\n\t>\r\n\t<Platforms>\r\n\t\t<Platform\r\n\t\t\tName=\"Win32\"\r\n\t\t/>\r\n\t</Platforms>\r\n\t<ToolFiles>\r\n\t</ToolFiles>\r\n\t<Configurations>\r\n\t\t<Configuration\r\n\t\t\tName=\"Debug|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"2\"\r\n\t\t\tCharacterSet=\"1\"\r\n\t\t\t>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"0\"\r\n\t\t\t\tPreprocessorDefinitions=\"DEBUG;WIN32;_WINDOWS;XP_WIN32;MOZILLA_STRICT_API;XPCOM_GLUE;XP_WIN;_X86_;NPSIMPLE_EXPORTS;XULRUNNER_SDK\"\r\n\t\t\t\tMinimalRebuild=\"true\"\r\n\t\t\t\tBasicRuntimeChecks=\"3\"\r\n\t\t\t\tRuntimeLibrary=\"3\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"4\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tLinkIncremental=\"2\"\r\n\t\t\t\tModuleDefinitionFile=\"chrome_fiddler.def\"\r\n\t\t\t\tGenerateDebugInformation=\"true\"\r\n\t\t\t\tSubSystem=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCALinkTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManifestTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXDCMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCBscMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCFxCopTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAppVerifierTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"\r\n\t\t\t/>\r\n\t\t</Configuration>\r\n\t\t<Configuration\r\n\t\t\tName=\"Release|Win32\"\r\n\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\r\n\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\r\n\t\t\tConfigurationType=\"2\"\r\n\t\t\tCharacterSet=\"1\"\r\n\t\t\tWholeProgramOptimization=\"1\"\r\n\t\t\t>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreBuildEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCustomBuildTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXMLDataGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCMIDLTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCCLCompilerTool\"\r\n\t\t\t\tOptimization=\"2\"\r\n\t\t\t\tEnableIntrinsicFunctions=\"true\"\r\n\t\t\t\tPreprocessorDefinitions=\"WIN32;_WINDOWS;XP_WIN32;MOZILLA_STRICT_API;XPCOM_GLUE;XP_WIN;_X86_;NPSIMPLE_EXPORTS\"\r\n\t\t\t\tRuntimeLibrary=\"2\"\r\n\t\t\t\tEnableFunctionLevelLinking=\"true\"\r\n\t\t\t\tUsePrecompiledHeader=\"0\"\r\n\t\t\t\tWarningLevel=\"3\"\r\n\t\t\t\tDebugInformationFormat=\"3\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManagedResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCResourceCompilerTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPreLinkEventTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCLinkerTool\"\r\n\t\t\t\tLinkIncremental=\"1\"\r\n\t\t\t\tModuleDefinitionFile=\"chrome_fiddler.def\"\r\n\t\t\t\tGenerateDebugInformation=\"true\"\r\n\t\t\t\tSubSystem=\"2\"\r\n\t\t\t\tOptimizeReferences=\"2\"\r\n\t\t\t\tEnableCOMDATFolding=\"2\"\r\n\t\t\t\tTargetMachine=\"1\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCALinkTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCManifestTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCXDCMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCBscMakeTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCFxCopTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCAppVerifierTool\"\r\n\t\t\t/>\r\n\t\t\t<Tool\r\n\t\t\t\tName=\"VCPostBuildEventTool\"\r\n\t\t\t/>\r\n\t\t</Configuration>\r\n\t</Configurations>\r\n\t<References>\r\n\t</References>\r\n\t<Files>\r\n\t\t<Filter\r\n\t\t\tName=\"Դļ\"\r\n\t\t\tFilter=\"cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx\"\r\n\t\t\tUniqueIdentifier=\"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}\"\r\n\t\t\t>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\chrome_fiddler.def\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\chrome_fiddler_plugin.cc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\chrome_fiddler_script_object.cc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\log.cc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\np_entry.cc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\npn_entry.cc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\npp_entry.cc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\plugin_base.cc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\plugin_factory.cc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\script_object_base.cc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\script_object_factory.cc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"ͷļ\"\r\n\t\t\tFilter=\"h;hpp;hxx;hm;inl;inc;xsd\"\r\n\t\t\tUniqueIdentifier=\"{93995380-89BD-4b04-88EB-625FBE52EBFB}\"\r\n\t\t\t>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\chrome_fiddler_plugin.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\chrome_fiddler_script_object.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\log.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\npapi.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\npfunctions.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\npruntime.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\nptypes.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\plugin_base.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\plugin_factory.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\resource.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\script_object_base.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\script_object_factory.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\"..\\..\\utils.h\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t\t<Filter\r\n\t\t\tName=\"Դļ\"\r\n\t\t\tFilter=\"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav\"\r\n\t\t\tUniqueIdentifier=\"{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}\"\r\n\t\t\t>\r\n\t\t\t<File\r\n\t\t\t\tRelativePath=\".\\chrome_fiddler.rc\"\r\n\t\t\t\t>\r\n\t\t\t</File>\r\n\t\t</Filter>\r\n\t</Files>\r\n\t<Globals>\r\n\t</Globals>\r\n</VisualStudioProject>\r\n"
  },
  {
    "path": "plugin/chrome_fiddler_vs2008_project/chrome_fiddler/resource.h",
    "content": "//{{NO_DEPENDENCIES}}\r\n// Microsoft Visual C++ generated include file.\r\n// Used by chrome_fiddler.rc\r\n\r\n// ¶һĬֵ\r\n// \r\n#ifdef APSTUDIO_INVOKED\r\n#ifndef APSTUDIO_READONLY_SYMBOLS\r\n#define _APS_NEXT_RESOURCE_VALUE        101\r\n#define _APS_NEXT_COMMAND_VALUE         40001\r\n#define _APS_NEXT_CONTROL_VALUE         1001\r\n#define _APS_NEXT_SYMED_VALUE           101\r\n#endif\r\n#endif\r\n"
  },
  {
    "path": "plugin/chrome_fiddler_vs2008_project/chrome_fiddler.sln",
    "content": "﻿\r\nMicrosoft Visual Studio Solution File, Format Version 10.00\r\n# Visual Studio 2008\r\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"chrome_fiddler\", \"chrome_fiddler\\chrome_fiddler.vcproj\", \"{DD996793-2B7D-464D-BA6A-0B9CB08557EE}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Win32 = Debug|Win32\r\n\t\tRelease|Win32 = Release|Win32\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{DD996793-2B7D-464D-BA6A-0B9CB08557EE}.Debug|Win32.ActiveCfg = Debug|Win32\r\n\t\t{DD996793-2B7D-464D-BA6A-0B9CB08557EE}.Debug|Win32.Build.0 = Debug|Win32\r\n\t\t{DD996793-2B7D-464D-BA6A-0B9CB08557EE}.Release|Win32.ActiveCfg = Release|Win32\r\n\t\t{DD996793-2B7D-464D-BA6A-0B9CB08557EE}.Release|Win32.Build.0 = Release|Win32\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "plugin/log.cc",
    "content": "#include \"log.h\"\n\n#include <stdlib.h>\n\n#ifndef _WINDOWS\n#include <sys/time.h>\n#include <time.h>\n#include <unistd.h>\n#endif\n\n#ifndef _WINDOWS\n#define MAX_PATH 260\n#endif\n\nLog::Log(void) {\n    file_ = NULL;\n}\n\nLog::~Log(void) {\n    if (file_ != NULL)\n        CloseLog();\n}\n\nbool Log::OpenLog(const char* header) {\n    if (file_ != NULL)\n        return false;\n\n#ifdef _WINDOWS\n    char filename[MAX_PATH];\n    GetLocalTime(&time_);\n    sprintf_s(filename, \"C:\\\\Windows\\\\Temp\\\\%s_%d%02d%02d_%d.log\", header, time_.wYear, time_.wMonth, time_.wDay, GetCurrentProcessId());\n#else\n    char filename[MAX_PATH];\n    time_t nowtime = time(NULL);\n    struct tm* time_ = localtime(&nowtime);\n    sprintf(filename, \"/tmp/%s_%d%02d%02d_%d.log\", header, time_->tm_year+1900, time_->tm_mon+1, time_->tm_mday, getpid());\n#endif\n    file_ = fopen(filename, \"a\");\n    if (file_ == NULL)\n        return false;\n    else\n        return true;\n}\n\nbool Log::WriteLog(const char* title, const char* contents) {\n    if (file_ == NULL) {\n        return false;\n    }\n\n#ifdef _WINDOWS\n    GetLocalTime(&time_);\n    if (fprintf(file_, \"[%02d:%02d:%02d %03d] [%s] %s\\n\", time_.wHour, time_.wMinute, time_.wSecond, time_.wMilliseconds, title, contents) > 0) {\n#else\n    timeval nowtime;\n    gettimeofday(&nowtime, NULL);\n    struct tm* time_ = localtime(&nowtime.tv_sec);\n    if (fprintf(file_, \"[%02d:%02d:%02d %ld] [%s] %s\\n\", time_->tm_hour, time_->tm_min, time_->tm_sec, (unsigned long)nowtime.tv_usec, title, contents) > 0) {\n#endif\n        fflush(file_);\n        return true;\n    } else\n        return false;\n}\n\nbool Log::CloseLog() {\n    if (file_ != NULL) {\n        fclose(file_);\n        file_ = NULL;\n    }\n    return true;\n}\n"
  },
  {
    "path": "plugin/log.h",
    "content": "#ifndef LOG_H_\n#define LOG_H_\n\n#include <stdio.h>\n\n#ifdef _WINDOWS\n#include <windows.h>\n#endif\n\nclass Log {\npublic:\n    Log(void);\n    ~Log(void);\n\n    bool OpenLog(const char* header);\n    bool WriteLog(const char* title, const char* contents);\n    bool CloseLog();\n\nprivate:\n    FILE* file_;\n#ifdef _WINDOWS\n    SYSTEMTIME time_;\n#endif\n};\n\n#endif\n"
  },
  {
    "path": "plugin/np_entry.cc",
    "content": "#include <stdio.h>\n\n#include \"log.h\"\n#include \"npapi.h\"\n#include \"npfunctions.h\"\n#include \"plugin_factory.h\"\n\n#ifdef _WINDOWS\n#include <windows.h>\n#include <GdiPlus.h>\nusing namespace Gdiplus;\nULONG_PTR token;\n#pragma comment(lib,\"gdiplus.lib\")\n#endif\n\nextern NPNetscapeFuncs* g_npn_funcs;\n\nLog g_logger;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef HIBYTE\n#define HIBYTE(x) ((((unsigned short)(x)) & 0xff00) >> 8)\n#endif\n\nNPError OSCALL NP_GetEntryPoints(NPPluginFuncs* nppfuncs) {\n    nppfuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;\n    nppfuncs->newp = NPP_New;\n    nppfuncs->destroy = NPP_Destroy;\n    nppfuncs->setwindow = NPP_SetWindow;\n    nppfuncs->newstream = NPP_NewStream;\n    nppfuncs->destroystream = NPP_DestroyStream;\n    nppfuncs->asfile = NPP_StreamAsFile;\n    nppfuncs->writeready = NPP_WriteReady;\n    nppfuncs->write = NPP_Write;\n    nppfuncs->print = NPP_Print;\n    nppfuncs->event = NPP_HandleEvent;\n    nppfuncs->urlnotify = NPP_URLNotify;\n    nppfuncs->getvalue = NPP_GetValue;\n    nppfuncs->setvalue = NPP_SetValue;\n    return NPERR_NO_ERROR;\n}\n\nNPError OSCALL NP_Initialize(NPNetscapeFuncs* npnf\n#if !defined(_WINDOWS) && !defined(WEBKIT_DARWIN_SDK)\n                             , NPPluginFuncs* nppfuncs\n#endif\n                             ) {\n    PluginFactory::Init();\n    g_logger.OpenLog(\"NPAPI\");\n    if(npnf == NULL) {\n        return NPERR_INVALID_FUNCTABLE_ERROR;\n    }\n    if(HIBYTE(npnf->version) > NP_VERSION_MAJOR) {\n        return NPERR_INCOMPATIBLE_VERSION_ERROR;\n    }\n    g_npn_funcs = npnf;\n#if !defined(_WINDOWS) && !defined(WEBKIT_DARWIN_SDK)\n    NP_GetEntryPoints(nppfuncs);\n#endif\n#ifdef _WINDOWS\n    GdiplusStartupInput input;\n    GdiplusStartup(&token, &input, NULL);\n#endif\n    return NPERR_NO_ERROR;\n}\n\nNPError OSCALL NP_Shutdown() {\n#ifdef _WINDOWS\n    GdiplusShutdown(token);\n#endif\n    return NPERR_NO_ERROR;\n}\n\nchar* NP_GetMIMEDescription(void) {\n    return \"application/x-chromefiddler::Fiddler in Chrome\";\n}\n\n// Needs to be present for WebKit based browsers.\nNPError OSCALL NP_GetValue(void* npp, NPPVariable variable, void* value) {\n    return NPP_GetValue((NPP)npp, variable, value);\n}\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "plugin/npapi.h",
    "content": "/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n/* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1/GPL 2.0/LGPL 2.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is mozilla.org code.\n *\n * The Initial Developer of the Original Code is\n * Netscape Communications Corporation.\n * Portions created by the Initial Developer are Copyright (C) 1998\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * Alternatively, the contents of this file may be used under the terms of\n * either the GNU General Public License Version 2 or later (the \"GPL\"), or\n * the GNU Lesser General Public License Version 2.1 or later (the \"LGPL\"),\n * in which case the provisions of the GPL or the LGPL are applicable instead\n * of those above. If you wish to allow use of your version of this file only\n * under the terms of either the GPL or the LGPL, and not to allow others to\n * use your version of this file under the terms of the MPL, indicate your\n * decision by deleting the provisions above and replace them with the notice\n * and other provisions required by the GPL or the LGPL. If you do not delete\n * the provisions above, a recipient may use your version of this file under\n * the terms of any one of the MPL, the GPL or the LGPL.\n *\n * ***** END LICENSE BLOCK ***** */\n\n#ifndef npapi_h_\n#define npapi_h_\n\n#if defined(__OS2__)\n#pragma pack(1)\n#endif\n\n#include \"nptypes.h\"\n\n#if defined(__OS2__) || defined(OS2)\n#ifndef XP_OS2\n#define XP_OS2 1\n#endif\n#endif\n\n#if defined(_WIN32) && !defined(__SYMBIAN32__)\n#include <windef.h>\n#ifndef XP_WIN\n#define XP_WIN 1\n#endif\n#endif\n\n#if defined(__SYMBIAN32__)\n#ifndef XP_SYMBIAN\n#define XP_SYMBIAN 1\n#undef XP_WIN\n#endif\n#endif\n\n#if defined(__APPLE_CC__) && !defined(XP_UNIX)\n#ifndef XP_MACOSX\n#define XP_MACOSX 1\n#endif\n#endif\n\n#if defined(XP_MACOSX) && defined(__LP64__)\n#define NP_NO_QUICKDRAW\n#define NP_NO_CARBON\n#endif\n\n#if defined(XP_MACOSX)\n#include <ApplicationServices/ApplicationServices.h>\n#include <OpenGL/OpenGL.h>\n#ifndef NP_NO_CARBON\n#include <Carbon/Carbon.h>\n#endif\n#endif\n\n#if defined(XP_UNIX)\n#include <stdio.h>\n#if defined(MOZ_X11)\n#include <X11/Xlib.h>\n#include <X11/Xutil.h>\n#endif\n#endif\n\n#if defined(XP_SYMBIAN)\n#include <QEvent>\n#include <QRegion>\n#endif\n\n/*----------------------------------------------------------------------*/\n/*                        Plugin Version Constants                      */\n/*----------------------------------------------------------------------*/\n\n#define NP_VERSION_MAJOR 0\n#define NP_VERSION_MINOR 26\n\n\n/* The OS/2 version of Netscape uses RC_DATA to define the\n   mime types, file extensions, etc that are required.\n   Use a vertical bar to separate types, end types with \\0.\n   FileVersion and ProductVersion are 32bit ints, all other\n   entries are strings that MUST be terminated with a \\0.\n\nAN EXAMPLE:\n\nRCDATA NP_INFO_ProductVersion { 1,0,0,1,}\n\nRCDATA NP_INFO_MIMEType    { \"video/x-video|\",\n                             \"video/x-flick\\0\" }\nRCDATA NP_INFO_FileExtents { \"avi|\",\n                             \"flc\\0\" }\nRCDATA NP_INFO_FileOpenName{ \"MMOS2 video player(*.avi)|\",\n                             \"MMOS2 Flc/Fli player(*.flc)\\0\" }\n\nRCDATA NP_INFO_FileVersion       { 1,0,0,1 }\nRCDATA NP_INFO_CompanyName       { \"Netscape Communications\\0\" }\nRCDATA NP_INFO_FileDescription   { \"NPAVI32 Extension DLL\\0\"\nRCDATA NP_INFO_InternalName      { \"NPAVI32\\0\" )\nRCDATA NP_INFO_LegalCopyright    { \"Copyright Netscape Communications \\251 1996\\0\"\nRCDATA NP_INFO_OriginalFilename  { \"NVAPI32.DLL\" }\nRCDATA NP_INFO_ProductName       { \"NPAVI32 Dynamic Link Library\\0\" }\n*/\n/* RC_DATA types for version info - required */\n#define NP_INFO_ProductVersion      1\n#define NP_INFO_MIMEType            2\n#define NP_INFO_FileOpenName        3\n#define NP_INFO_FileExtents         4\n/* RC_DATA types for version info - used if found */\n#define NP_INFO_FileDescription     5\n#define NP_INFO_ProductName         6\n/* RC_DATA types for version info - optional */\n#define NP_INFO_CompanyName         7\n#define NP_INFO_FileVersion         8\n#define NP_INFO_InternalName        9\n#define NP_INFO_LegalCopyright      10\n#define NP_INFO_OriginalFilename    11\n\n#ifndef RC_INVOKED\n\n/*----------------------------------------------------------------------*/\n/*                       Definition of Basic Types                      */\n/*----------------------------------------------------------------------*/\n\ntypedef unsigned char NPBool;\ntypedef int16_t       NPError;\ntypedef int16_t       NPReason;\ntypedef char*         NPMIMEType;\n\n/*----------------------------------------------------------------------*/\n/*                       Structures and definitions                     */\n/*----------------------------------------------------------------------*/\n\n#if !defined(__LP64__)\n#if defined(XP_MACOSX)\n#pragma options align=mac68k\n#endif\n#endif /* __LP64__ */\n\n/*\n *  NPP is a plug-in's opaque instance handle\n */\ntypedef struct _NPP\n{\n  void* pdata;      /* plug-in private data */\n  void* ndata;      /* netscape private data */\n} NPP_t;\n\ntypedef NPP_t*  NPP;\n\ntypedef struct _NPStream\n{\n  void*    pdata; /* plug-in private data */\n  void*    ndata; /* netscape private data */\n  const    char* url;\n  uint32_t end;\n  uint32_t lastmodified;\n  void*    notifyData;\n  const    char* headers; /* Response headers from host.\n                           * Exists only for >= NPVERS_HAS_RESPONSE_HEADERS.\n                           * Used for HTTP only; NULL for non-HTTP.\n                           * Available from NPP_NewStream onwards.\n                           * Plugin should copy this data before storing it.\n                           * Includes HTTP status line and all headers,\n                           * preferably verbatim as received from server,\n                           * headers formatted as in HTTP (\"Header: Value\"),\n                           * and newlines (\\n, NOT \\r\\n) separating lines.\n                           * Terminated by \\n\\0 (NOT \\n\\n\\0). */\n} NPStream;\n\ntypedef struct _NPByteRange\n{\n  int32_t  offset; /* negative offset means from the end */\n  uint32_t length;\n  struct _NPByteRange* next;\n} NPByteRange;\n\ntypedef struct _NPSavedData\n{\n  int32_t len;\n  void*   buf;\n} NPSavedData;\n\ntypedef struct _NPRect\n{\n  uint16_t top;\n  uint16_t left;\n  uint16_t bottom;\n  uint16_t right;\n} NPRect;\n\ntypedef struct _NPSize\n{\n  int32_t width;\n  int32_t height;\n} NPSize;\n\ntypedef enum {\n  NPFocusNext = 0,\n  NPFocusPrevious = 1\n} NPFocusDirection;\n\n/* Return values for NPP_HandleEvent */\n#define kNPEventNotHandled 0\n#define kNPEventHandled 1\n/* Exact meaning must be spec'd in event model. */\n#define kNPEventStartIME 2\n\n#if defined(XP_UNIX)\n/*\n * Unix specific structures and definitions\n */\n\n/*\n * Callback Structures.\n *\n * These are used to pass additional platform specific information.\n */\nenum {\n  NP_SETWINDOW = 1,\n  NP_PRINT\n};\n\ntypedef struct\n{\n  int32_t type;\n} NPAnyCallbackStruct;\n\ntypedef struct\n{\n  int32_t      type;\n#if defined(MOZ_X11)\n  Display*     display;\n  Visual*      visual;\n  Colormap     colormap;\n  unsigned int depth;\n#endif\n} NPSetWindowCallbackStruct;\n\ntypedef struct\n{\n  int32_t type;\n  FILE* fp;\n} NPPrintCallbackStruct;\n\n#endif /* XP_UNIX */\n\n#if defined(XP_MACOSX)\ntypedef enum {\n#ifndef NP_NO_QUICKDRAW\n  NPDrawingModelQuickDraw = 0,\n#endif\n  NPDrawingModelCoreGraphics = 1,\n  NPDrawingModelOpenGL = 2,\n  NPDrawingModelCoreAnimation = 3,\n  NPDrawingModelInvalidatingCoreAnimation = 4\n} NPDrawingModel;\n\ntypedef enum {\n#ifndef NP_NO_CARBON\n  NPEventModelCarbon = 0,\n#endif\n  NPEventModelCocoa = 1\n} NPEventModel;\n#endif\n\n/*\n *   The following masks are applied on certain platforms to NPNV and\n *   NPPV selectors that pass around pointers to COM interfaces. Newer\n *   compilers on some platforms may generate vtables that are not\n *   compatible with older compilers. To prevent older plugins from\n *   not understanding a new browser's ABI, these masks change the\n *   values of those selectors on those platforms. To remain backwards\n *   compatible with different versions of the browser, plugins can\n *   use these masks to dynamically determine and use the correct C++\n *   ABI that the browser is expecting. This does not apply to Windows\n *   as Microsoft's COM ABI will likely not change.\n */\n\n#define NP_ABI_GCC3_MASK  0x10000000\n/*\n *   gcc 3.x generated vtables on UNIX and OSX are incompatible with\n *   previous compilers.\n */\n#if (defined(XP_UNIX) && defined(__GNUC__) && (__GNUC__ >= 3))\n#define _NP_ABI_MIXIN_FOR_GCC3 NP_ABI_GCC3_MASK\n#else\n#define _NP_ABI_MIXIN_FOR_GCC3 0\n#endif\n\n#if defined(XP_MACOSX)\n#define NP_ABI_MACHO_MASK 0x01000000\n#define _NP_ABI_MIXIN_FOR_MACHO NP_ABI_MACHO_MASK\n#else\n#define _NP_ABI_MIXIN_FOR_MACHO 0\n#endif\n\n#define NP_ABI_MASK (_NP_ABI_MIXIN_FOR_GCC3 | _NP_ABI_MIXIN_FOR_MACHO)\n\n/*\n * List of variable names for which NPP_GetValue shall be implemented\n */\ntypedef enum {\n  NPPVpluginNameString = 1,\n  NPPVpluginDescriptionString,\n  NPPVpluginWindowBool,\n  NPPVpluginTransparentBool,\n  NPPVjavaClass,\n  NPPVpluginWindowSize,\n  NPPVpluginTimerInterval,\n  NPPVpluginScriptableInstance = (10 | NP_ABI_MASK),\n  NPPVpluginScriptableIID = 11,\n  NPPVjavascriptPushCallerBool = 12,\n  NPPVpluginKeepLibraryInMemory = 13,\n  NPPVpluginNeedsXEmbed         = 14,\n\n  /* Get the NPObject for scripting the plugin. Introduced in NPAPI minor version 14.\n   */\n  NPPVpluginScriptableNPObject  = 15,\n\n  /* Get the plugin value (as \\0-terminated UTF-8 string data) for\n   * form submission if the plugin is part of a form. Use\n   * NPN_MemAlloc() to allocate memory for the string data. Introduced\n   * in NPAPI minor version 15.\n   */\n  NPPVformValue = 16,\n\n  NPPVpluginUrlRequestsDisplayedBool = 17,\n\n  /* Checks if the plugin is interested in receiving the http body of\n   * all http requests (including failed ones, http status != 200).\n   */\n  NPPVpluginWantsAllNetworkStreams = 18,\n\n  /* Browsers can retrieve a native ATK accessibility plug ID via this variable. */\n  NPPVpluginNativeAccessibleAtkPlugId = 19,\n\n  /* Checks to see if the plug-in would like the browser to load the \"src\" attribute. */\n  NPPVpluginCancelSrcStream = 20,\n\n  NPPVSupportsAdvancedKeyHandling = 21\n\n#if defined(XP_MACOSX)\n  /* Used for negotiating drawing models */\n  , NPPVpluginDrawingModel = 1000\n  /* Used for negotiating event models */\n  , NPPVpluginEventModel = 1001\n  /* In the NPDrawingModelCoreAnimation drawing model, the browser asks the plug-in for a Core Animation layer. */\n  , NPPVpluginCoreAnimationLayer = 1003\n#endif\n\n#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)\n  , NPPVpluginWindowlessLocalBool = 2002\n#endif\n} NPPVariable;\n\n/*\n * List of variable names for which NPN_GetValue should be implemented.\n */\ntypedef enum {\n  NPNVxDisplay = 1,\n  NPNVxtAppContext,\n  NPNVnetscapeWindow,\n  NPNVjavascriptEnabledBool,\n  NPNVasdEnabledBool,\n  NPNVisOfflineBool,\n\n  NPNVserviceManager = (10 | NP_ABI_MASK),\n  NPNVDOMElement     = (11 | NP_ABI_MASK),\n  NPNVDOMWindow      = (12 | NP_ABI_MASK),\n  NPNVToolkit        = (13 | NP_ABI_MASK),\n  NPNVSupportsXEmbedBool = 14,\n\n  /* Get the NPObject wrapper for the browser window. */\n  NPNVWindowNPObject = 15,\n\n  /* Get the NPObject wrapper for the plugins DOM element. */\n  NPNVPluginElementNPObject = 16,\n\n  NPNVSupportsWindowless = 17,\n\n  NPNVprivateModeBool = 18,\n\n  NPNVsupportsAdvancedKeyHandling = 21\n\n#if defined(XP_MACOSX)\n  /* Used for negotiating drawing models */\n  , NPNVpluginDrawingModel = 1000\n#ifndef NP_NO_QUICKDRAW\n  , NPNVsupportsQuickDrawBool = 2000\n#endif\n  , NPNVsupportsCoreGraphicsBool = 2001\n  , NPNVsupportsOpenGLBool = 2002\n  , NPNVsupportsCoreAnimationBool = 2003\n  , NPNVsupportsInvalidatingCoreAnimationBool = 2004\n#ifndef NP_NO_CARBON\n  , NPNVsupportsCarbonBool = 3000 /* TRUE if the browser supports the Carbon event model */\n#endif\n  , NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */\n#endif\n#if (MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)\n  , NPNVSupportsWindowlessLocal = 2002\n#endif\n} NPNVariable;\n\ntypedef enum {\n  NPNURLVCookie = 501,\n  NPNURLVProxy\n} NPNURLVariable;\n\n/*\n * The type of Toolkit the widgets use\n */\ntypedef enum {\n  NPNVGtk12 = 1,\n  NPNVGtk2\n} NPNToolkitType;\n\n/*\n * The type of a NPWindow - it specifies the type of the data structure\n * returned in the window field.\n */\ntypedef enum {\n  NPWindowTypeWindow = 1,\n  NPWindowTypeDrawable\n} NPWindowType;\n\ntypedef struct _NPWindow\n{\n  void* window;  /* Platform specific window handle */\n                 /* OS/2: x - Position of bottom left corner */\n                 /* OS/2: y - relative to visible netscape window */\n  int32_t  x;      /* Position of top left corner relative */\n  int32_t  y;      /* to a netscape page. */\n  uint32_t width;  /* Maximum window size */\n  uint32_t height;\n  NPRect   clipRect; /* Clipping rectangle in port coordinates */\n#if (defined(XP_UNIX) || defined(XP_SYMBIAN)) && !defined(XP_MACOSX)\n  void * ws_info; /* Platform-dependent additional data */\n#endif /* XP_UNIX */\n  NPWindowType type; /* Is this a window or a drawable? */\n} NPWindow;\n\ntypedef struct _NPImageExpose\n{\n  char*    data;       /* image pointer */\n  int32_t  stride;     /* Stride of data image pointer */\n  int32_t  depth;      /* Depth of image pointer */\n  int32_t  x;          /* Expose x */\n  int32_t  y;          /* Expose y */\n  uint32_t width;      /* Expose width */\n  uint32_t height;     /* Expose height */\n  NPSize   dataSize;   /* Data buffer size */\n  float    translateX; /* translate X matrix value */\n  float    translateY; /* translate Y matrix value */\n  float    scaleX;     /* scale X matrix value */\n  float    scaleY;     /* scale Y matrix value */\n} NPImageExpose;\n\ntypedef struct _NPFullPrint\n{\n  NPBool pluginPrinted;/* Set TRUE if plugin handled fullscreen printing */\n  NPBool printOne;     /* TRUE if plugin should print one copy to default\n                          printer */\n  void* platformPrint; /* Platform-specific printing info */\n} NPFullPrint;\n\ntypedef struct _NPEmbedPrint\n{\n  NPWindow window;\n  void* platformPrint; /* Platform-specific printing info */\n} NPEmbedPrint;\n\ntypedef struct _NPPrint\n{\n  uint16_t mode;               /* NP_FULL or NP_EMBED */\n  union\n  {\n    NPFullPrint fullPrint;   /* if mode is NP_FULL */\n    NPEmbedPrint embedPrint; /* if mode is NP_EMBED */\n  } print;\n} NPPrint;\n\n#if defined(XP_MACOSX)\n#ifndef NP_NO_CARBON\ntypedef EventRecord NPEvent;\n#endif\n#elif defined(XP_SYMBIAN)\ntypedef QEvent NPEvent;\n#elif defined(XP_WIN)\ntypedef struct _NPEvent\n{\n  uint16_t event;\n  uintptr_t wParam;\n  uintptr_t lParam;\n} NPEvent;\n#elif defined(XP_OS2)\ntypedef struct _NPEvent\n{\n  uint32_t event;\n  uint32_t wParam;\n  uint32_t lParam;\n} NPEvent;\n#elif defined(XP_UNIX) && defined(MOZ_X11)\ntypedef XEvent NPEvent;\n#else\ntypedef void*  NPEvent;\n#endif\n\n#if defined(XP_MACOSX)\ntypedef void* NPRegion;\n#ifndef NP_NO_QUICKDRAW\ntypedef RgnHandle NPQDRegion;\n#endif\ntypedef CGPathRef NPCGRegion;\n#elif defined(XP_WIN)\ntypedef HRGN NPRegion;\n#elif defined(XP_UNIX) && defined(MOZ_X11)\ntypedef Region NPRegion;\n#elif defined(XP_SYMBIAN)\ntypedef QRegion* NPRegion;\n#else\ntypedef void *NPRegion;\n#endif\n\ntypedef struct _NPNSString NPNSString;\ntypedef struct _NPNSWindow NPNSWindow;\ntypedef struct _NPNSMenu   NPNSMenu;\n\n#if defined(XP_MACOSX)\ntypedef NPNSMenu NPMenu;\n#else\ntypedef void *NPMenu;\n#endif\n\ntypedef enum {\n  NPCoordinateSpacePlugin = 1,\n  NPCoordinateSpaceWindow,\n  NPCoordinateSpaceFlippedWindow,\n  NPCoordinateSpaceScreen,\n  NPCoordinateSpaceFlippedScreen\n} NPCoordinateSpace;\n\n#if defined(XP_MACOSX)\n\n#ifndef NP_NO_QUICKDRAW\ntypedef struct NP_Port\n{\n  CGrafPtr port;\n  int32_t portx; /* position inside the topmost window */\n  int32_t porty;\n} NP_Port;\n#endif /* NP_NO_QUICKDRAW */\n\n/*\n * NP_CGContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelCoreGraphics\n * as its drawing model.\n */\n\ntypedef struct NP_CGContext\n{\n  CGContextRef context;\n  void *window; /* A WindowRef under the Carbon event model. */\n} NP_CGContext;\n\n/*\n * NP_GLContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelOpenGL as its\n * drawing model.\n */\n\ntypedef struct NP_GLContext\n{\n  CGLContextObj context;\n#ifdef NP_NO_CARBON\n  NPNSWindow *window;\n#else\n  void *window; /* Can be either an NSWindow or a WindowRef depending on the event model */\n#endif\n} NP_GLContext;\n\ntypedef enum {\n  NPCocoaEventDrawRect = 1,\n  NPCocoaEventMouseDown,\n  NPCocoaEventMouseUp,\n  NPCocoaEventMouseMoved,\n  NPCocoaEventMouseEntered,\n  NPCocoaEventMouseExited,\n  NPCocoaEventMouseDragged,\n  NPCocoaEventKeyDown,\n  NPCocoaEventKeyUp,\n  NPCocoaEventFlagsChanged,\n  NPCocoaEventFocusChanged,\n  NPCocoaEventWindowFocusChanged,\n  NPCocoaEventScrollWheel,\n  NPCocoaEventTextInput\n} NPCocoaEventType;\n\ntypedef struct _NPCocoaEvent {\n  NPCocoaEventType type;\n  uint32_t version;\n  union {\n    struct {\n      uint32_t modifierFlags;\n      double   pluginX;\n      double   pluginY;\n      int32_t  buttonNumber;\n      int32_t  clickCount;\n      double   deltaX;\n      double   deltaY;\n      double   deltaZ;\n    } mouse;\n    struct {\n      uint32_t    modifierFlags;\n      NPNSString *characters;\n      NPNSString *charactersIgnoringModifiers;\n      NPBool      isARepeat;\n      uint16_t    keyCode;\n    } key;\n    struct {\n      CGContextRef context;\n      double x;\n      double y;\n      double width;\n      double height;\n    } draw;\n    struct {\n      NPBool hasFocus;\n    } focus;\n    struct {\n      NPNSString *text;\n    } text;\n  } data;\n} NPCocoaEvent;\n\n#ifndef NP_NO_CARBON\n/* Non-standard event types that can be passed to HandleEvent */\nenum NPEventType {\n  NPEventType_GetFocusEvent = (osEvt + 16),\n  NPEventType_LoseFocusEvent,\n  NPEventType_AdjustCursorEvent,\n  NPEventType_MenuCommandEvent,\n  NPEventType_ClippingChangedEvent,\n  NPEventType_ScrollingBeginsEvent = 1000,\n  NPEventType_ScrollingEndsEvent\n};\n#endif /* NP_NO_CARBON */\n\n#endif /* XP_MACOSX */\n\n/*\n * Values for mode passed to NPP_New:\n */\n#define NP_EMBED 1\n#define NP_FULL  2\n\n/*\n * Values for stream type passed to NPP_NewStream:\n */\n#define NP_NORMAL     1\n#define NP_SEEK       2\n#define NP_ASFILE     3\n#define NP_ASFILEONLY 4\n\n#define NP_MAXREADY (((unsigned)(~0)<<1)>>1)\n\n#if !defined(__LP64__)\n#if defined(XP_MACOSX)\n#pragma options align=reset\n#endif\n#endif /* __LP64__ */\n\n/*----------------------------------------------------------------------*/\n/*       Error and Reason Code definitions                              */\n/*----------------------------------------------------------------------*/\n\n/*\n * Values of type NPError:\n */\n#define NPERR_BASE                         0\n#define NPERR_NO_ERROR                    (NPERR_BASE + 0)\n#define NPERR_GENERIC_ERROR               (NPERR_BASE + 1)\n#define NPERR_INVALID_INSTANCE_ERROR      (NPERR_BASE + 2)\n#define NPERR_INVALID_FUNCTABLE_ERROR     (NPERR_BASE + 3)\n#define NPERR_MODULE_LOAD_FAILED_ERROR    (NPERR_BASE + 4)\n#define NPERR_OUT_OF_MEMORY_ERROR         (NPERR_BASE + 5)\n#define NPERR_INVALID_PLUGIN_ERROR        (NPERR_BASE + 6)\n#define NPERR_INVALID_PLUGIN_DIR_ERROR    (NPERR_BASE + 7)\n#define NPERR_INCOMPATIBLE_VERSION_ERROR  (NPERR_BASE + 8)\n#define NPERR_INVALID_PARAM               (NPERR_BASE + 9)\n#define NPERR_INVALID_URL                 (NPERR_BASE + 10)\n#define NPERR_FILE_NOT_FOUND              (NPERR_BASE + 11)\n#define NPERR_NO_DATA                     (NPERR_BASE + 12)\n#define NPERR_STREAM_NOT_SEEKABLE         (NPERR_BASE + 13)\n\n/*\n * Values of type NPReason:\n */\n#define NPRES_BASE          0\n#define NPRES_DONE         (NPRES_BASE + 0)\n#define NPRES_NETWORK_ERR  (NPRES_BASE + 1)\n#define NPRES_USER_BREAK   (NPRES_BASE + 2)\n\n/*\n * Don't use these obsolete error codes any more.\n */\n#define NP_NOERR  NP_NOERR_is_obsolete_use_NPERR_NO_ERROR\n#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR\n#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK\n\n/*\n * Version feature information\n */\n#define NPVERS_HAS_STREAMOUTPUT             8\n#define NPVERS_HAS_NOTIFICATION             9\n#define NPVERS_HAS_LIVECONNECT              9\n#define NPVERS_68K_HAS_LIVECONNECT          11\n#define NPVERS_HAS_WINDOWLESS               11\n#define NPVERS_HAS_XPCONNECT_SCRIPTING      13\n#define NPVERS_HAS_NPRUNTIME_SCRIPTING      14\n#define NPVERS_HAS_FORM_VALUES              15\n#define NPVERS_HAS_POPUPS_ENABLED_STATE     16\n#define NPVERS_HAS_RESPONSE_HEADERS         17\n#define NPVERS_HAS_NPOBJECT_ENUM            18\n#define NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL 19\n#define NPVERS_HAS_ALL_NETWORK_STREAMS      20\n#define NPVERS_HAS_URL_AND_AUTH_INFO        21\n#define NPVERS_HAS_PRIVATE_MODE             22\n#define NPVERS_MACOSX_HAS_COCOA_EVENTS      23\n#define NPVERS_HAS_ADVANCED_KEY_HANDLING    25\n#define NPVERS_HAS_URL_REDIRECT_HANDLING    26\n\n/*----------------------------------------------------------------------*/\n/*                        Function Prototypes                           */\n/*----------------------------------------------------------------------*/\n\n#if defined(__OS2__)\n#define NP_LOADDS _System\n#else\n#define NP_LOADDS\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* NPP_* functions are provided by the plugin and called by the navigator. */\n\n#if defined(XP_UNIX)\nchar* NPP_GetMIMEDescription(void);\n#endif\n\nNPError NP_LOADDS NPP_Initialize(void);\nvoid    NP_LOADDS NPP_Shutdown(void);\nNPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance,\n                          uint16_t mode, int16_t argc, char* argn[],\n                          char* argv[], NPSavedData* saved);\nNPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save);\nNPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window);\nNPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type,\n                                NPStream* stream, NPBool seekable,\n                                uint16_t* stype);\nNPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream,\n                                    NPReason reason);\nint32_t NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream);\nint32_t NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32_t offset,\n                            int32_t len, void* buffer);\nvoid    NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream,\n                                   const char* fname);\nvoid    NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint);\nint16_t NP_LOADDS NPP_HandleEvent(NPP instance, void* event);\nvoid    NP_LOADDS NPP_URLNotify(NPP instance, const char* url,\n                                NPReason reason, void* notifyData);\nNPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value);\nNPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value);\nNPBool  NP_LOADDS NPP_GotFocus(NPP instance, NPFocusDirection direction);\nvoid    NP_LOADDS NPP_LostFocus(NPP instance);\nvoid    NP_LOADDS NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData);\n\n/* NPN_* functions are provided by the navigator and called by the plugin. */\nvoid        NP_LOADDS NPN_Version(int* plugin_major, int* plugin_minor,\n                                  int* netscape_major, int* netscape_minor);\nNPError     NP_LOADDS NPN_GetURLNotify(NPP instance, const char* url,\n                                       const char* target, void* notifyData);\nNPError     NP_LOADDS NPN_GetURL(NPP instance, const char* url,\n                                 const char* target);\nNPError     NP_LOADDS NPN_PostURLNotify(NPP instance, const char* url,\n                                        const char* target, uint32_t len,\n                                        const char* buf, NPBool file,\n                                        void* notifyData);\nNPError     NP_LOADDS NPN_PostURL(NPP instance, const char* url,\n                                  const char* target, uint32_t len,\n                                  const char* buf, NPBool file);\nNPError     NP_LOADDS NPN_RequestRead(NPStream* stream, NPByteRange* rangeList);\nNPError     NP_LOADDS NPN_NewStream(NPP instance, NPMIMEType type,\n                                    const char* target, NPStream** stream);\nint32_t     NP_LOADDS NPN_Write(NPP instance, NPStream* stream, int32_t len,\n                                void* buffer);\nNPError     NP_LOADDS NPN_DestroyStream(NPP instance, NPStream* stream,\n                                        NPReason reason);\nvoid        NP_LOADDS NPN_Status(NPP instance, const char* message);\nconst char* NP_LOADDS NPN_UserAgent(NPP instance);\nvoid*       NP_LOADDS NPN_MemAlloc(uint32_t size);\nvoid        NP_LOADDS NPN_MemFree(void* ptr);\nuint32_t    NP_LOADDS NPN_MemFlush(uint32_t size);\nvoid        NP_LOADDS NPN_ReloadPlugins(NPBool reloadPages);\nNPError     NP_LOADDS NPN_GetValue(NPP instance, NPNVariable variable,\n                                   void *value);\nNPError     NP_LOADDS NPN_SetValue(NPP instance, NPPVariable variable,\n                                   void *value);\nvoid        NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect *invalidRect);\nvoid        NP_LOADDS NPN_InvalidateRegion(NPP instance,\n                                           NPRegion invalidRegion);\nvoid        NP_LOADDS NPN_ForceRedraw(NPP instance);\nvoid        NP_LOADDS NPN_PushPopupsEnabledState(NPP instance, NPBool enabled);\nvoid        NP_LOADDS NPN_PopPopupsEnabledState(NPP instance);\nvoid        NP_LOADDS NPN_PluginThreadAsyncCall(NPP instance,\n                                                void (*func) (void *),\n                                                void *userData);\nNPError     NP_LOADDS NPN_GetValueForURL(NPP instance, NPNURLVariable variable,\n                                         const char *url, char **value,\n                                         uint32_t *len);\nNPError     NP_LOADDS NPN_SetValueForURL(NPP instance, NPNURLVariable variable,\n                                         const char *url, const char *value,\n                                         uint32_t len);\nNPError     NP_LOADDS NPN_GetAuthenticationInfo(NPP instance,\n                                                const char *protocol,\n                                                const char *host, int32_t port,\n                                                const char *scheme,\n                                                const char *realm,\n                                                char **username, uint32_t *ulen,\n                                                char **password,\n                                                uint32_t *plen);\nuint32_t    NP_LOADDS NPN_ScheduleTimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID));\nvoid        NP_LOADDS NPN_UnscheduleTimer(NPP instance, uint32_t timerID);\nNPError     NP_LOADDS NPN_PopUpContextMenu(NPP instance, NPMenu* menu);\nNPBool      NP_LOADDS NPN_ConvertPoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);\nNPBool      NP_LOADDS NPN_HandleEvent(NPP instance, void *event, NPBool handled);\nNPBool      NP_LOADDS NPN_UnfocusInstance(NPP instance, NPFocusDirection direction);\nvoid        NP_LOADDS NPN_URLRedirectResponse(NPP instance, void* notifyData, NPBool allow);\n\n#ifdef __cplusplus\n}  /* end extern \"C\" */\n#endif\n\n#endif /* RC_INVOKED */\n#if defined(__OS2__)\n#pragma pack()\n#endif\n\n#endif /* npapi_h_ */"
  },
  {
    "path": "plugin/npfunctions.h",
    "content": "/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */\n/* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1/GPL 2.0/LGPL 2.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is mozilla.org code.\n *\n * The Initial Developer of the Original Code is\n * Netscape Communications Corporation.\n * Portions created by the Initial Developer are Copyright (C) 1998\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * Alternatively, the contents of this file may be used under the terms of\n * either the GNU General Public License Version 2 or later (the \"GPL\"), or\n * the GNU Lesser General Public License Version 2.1 or later (the \"LGPL\"),\n * in which case the provisions of the GPL or the LGPL are applicable instead\n * of those above. If you wish to allow use of your version of this file only\n * under the terms of either the GPL or the LGPL, and not to allow others to\n * use your version of this file under the terms of the MPL, indicate your\n * decision by deleting the provisions above and replace them with the notice\n * and other provisions required by the GPL or the LGPL. If you do not delete\n * the provisions above, a recipient may use your version of this file under\n * the terms of any one of the MPL, the GPL or the LGPL.\n *\n * ***** END LICENSE BLOCK ***** */\n\n#ifndef npfunctions_h_\n#define npfunctions_h_\n\n#ifdef __OS2__\n#pragma pack(1)\n#define NP_LOADDS _System\n#else\n#define NP_LOADDS\n#endif\n\n#include \"npapi.h\"\n#include \"npruntime.h\"\n\ntypedef void         (* NP_LOADDS NPP_InitializeProcPtr)();\ntypedef void         (* NP_LOADDS NPP_ShutdownProcPtr)();\ntypedef NPError      (* NP_LOADDS NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved);\ntypedef NPError      (* NP_LOADDS NPP_DestroyProcPtr)(NPP instance, NPSavedData** save);\ntypedef NPError      (* NP_LOADDS NPP_SetWindowProcPtr)(NPP instance, NPWindow* window);\ntypedef NPError      (* NP_LOADDS NPP_NewStreamProcPtr)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype);\ntypedef NPError      (* NP_LOADDS NPP_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);\ntypedef int32_t      (* NP_LOADDS NPP_WriteReadyProcPtr)(NPP instance, NPStream* stream);\ntypedef int32_t      (* NP_LOADDS NPP_WriteProcPtr)(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer);\ntypedef void         (* NP_LOADDS NPP_StreamAsFileProcPtr)(NPP instance, NPStream* stream, const char* fname);\ntypedef void         (* NP_LOADDS NPP_PrintProcPtr)(NPP instance, NPPrint* platformPrint);\ntypedef int16_t      (* NP_LOADDS NPP_HandleEventProcPtr)(NPP instance, void* event);\ntypedef void         (* NP_LOADDS NPP_URLNotifyProcPtr)(NPP instance, const char* url, NPReason reason, void* notifyData);\n/* Any NPObjects returned to the browser via NPP_GetValue should be retained\n   by the plugin on the way out. The browser is responsible for releasing. */\ntypedef NPError      (* NP_LOADDS NPP_GetValueProcPtr)(NPP instance, NPPVariable variable, void *ret_value);\ntypedef NPError      (* NP_LOADDS NPP_SetValueProcPtr)(NPP instance, NPNVariable variable, void *value);\n\ntypedef NPError      (*NPN_GetValueProcPtr)(NPP instance, NPNVariable variable, void *ret_value);\ntypedef NPError      (*NPN_SetValueProcPtr)(NPP instance, NPPVariable variable, void *value);\ntypedef NPError      (*NPN_GetURLNotifyProcPtr)(NPP instance, const char* url, const char* window, void* notifyData);\ntypedef NPError      (*NPN_PostURLNotifyProcPtr)(NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file, void* notifyData);\ntypedef NPError      (*NPN_GetURLProcPtr)(NPP instance, const char* url, const char* window);\ntypedef NPError      (*NPN_PostURLProcPtr)(NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file);\ntypedef NPError      (*NPN_RequestReadProcPtr)(NPStream* stream, NPByteRange* rangeList);\ntypedef NPError      (*NPN_NewStreamProcPtr)(NPP instance, NPMIMEType type, const char* window, NPStream** stream);\ntypedef int32_t      (*NPN_WriteProcPtr)(NPP instance, NPStream* stream, int32_t len, void* buffer);\ntypedef NPError      (*NPN_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);\ntypedef void         (*NPN_StatusProcPtr)(NPP instance, const char* message);\n/* Browser manages the lifetime of the buffer returned by NPN_UserAgent, don't\n   depend on it sticking around and don't free it. */\ntypedef const char*  (*NPN_UserAgentProcPtr)(NPP instance);\ntypedef void*        (*NPN_MemAllocProcPtr)(uint32_t size);\ntypedef void         (*NPN_MemFreeProcPtr)(void* ptr);\ntypedef uint32_t     (*NPN_MemFlushProcPtr)(uint32_t size);\ntypedef void         (*NPN_ReloadPluginsProcPtr)(NPBool reloadPages);\ntypedef void*        (*NPN_GetJavaEnvProcPtr)();\ntypedef void*        (*NPN_GetJavaPeerProcPtr)(NPP instance);\ntypedef void         (*NPN_InvalidateRectProcPtr)(NPP instance, NPRect *rect);\ntypedef void         (*NPN_InvalidateRegionProcPtr)(NPP instance, NPRegion region);\ntypedef void         (*NPN_ForceRedrawProcPtr)(NPP instance);\ntypedef NPIdentifier (*NPN_GetStringIdentifierProcPtr)(const NPUTF8* name);\ntypedef void         (*NPN_GetStringIdentifiersProcPtr)(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers);\ntypedef NPIdentifier (*NPN_GetIntIdentifierProcPtr)(int32_t intid);\ntypedef bool         (*NPN_IdentifierIsStringProcPtr)(NPIdentifier identifier);\ntypedef NPUTF8*      (*NPN_UTF8FromIdentifierProcPtr)(NPIdentifier identifier);\ntypedef int32_t      (*NPN_IntFromIdentifierProcPtr)(NPIdentifier identifier);\ntypedef NPObject*    (*NPN_CreateObjectProcPtr)(NPP npp, NPClass *aClass);\ntypedef NPObject*    (*NPN_RetainObjectProcPtr)(NPObject *obj);\ntypedef void         (*NPN_ReleaseObjectProcPtr)(NPObject *obj);\ntypedef bool         (*NPN_InvokeProcPtr)(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result);\ntypedef bool         (*NPN_InvokeDefaultProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result);\ntypedef bool         (*NPN_EvaluateProcPtr)(NPP npp, NPObject *obj, NPString *script, NPVariant *result);\ntypedef bool         (*NPN_GetPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result);\ntypedef bool         (*NPN_SetPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName, const NPVariant *value);\ntypedef bool         (*NPN_RemovePropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);\ntypedef bool         (*NPN_HasPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);\ntypedef bool         (*NPN_HasMethodProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName);\ntypedef void         (*NPN_ReleaseVariantValueProcPtr)(NPVariant *variant);\ntypedef void         (*NPN_SetExceptionProcPtr)(NPObject *obj, const NPUTF8 *message);\ntypedef bool         (*NPN_PushPopupsEnabledStateProcPtr)(NPP npp, NPBool enabled);\ntypedef bool         (*NPN_PopPopupsEnabledStateProcPtr)(NPP npp);\ntypedef bool         (*NPN_EnumerateProcPtr)(NPP npp, NPObject *obj, NPIdentifier **identifier, uint32_t *count);\ntypedef void         (*NPN_PluginThreadAsyncCallProcPtr)(NPP instance, void (*func)(void *), void *userData);\ntypedef bool         (*NPN_ConstructProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result);\ntypedef NPError      (*NPN_GetValueForURLPtr)(NPP npp, NPNURLVariable variable, const char *url, char **value, uint32_t *len);\ntypedef NPError      (*NPN_SetValueForURLPtr)(NPP npp, NPNURLVariable variable, const char *url, const char *value, uint32_t len);\ntypedef NPError      (*NPN_GetAuthenticationInfoPtr)(NPP npp, const char *protocol, const char *host, int32_t port, const char *scheme, const char *realm, char **username, uint32_t *ulen, char **password, uint32_t *plen);\n\ntypedef struct _NPPluginFuncs {\n  uint16_t size;\n  uint16_t version;\n  NPP_NewProcPtr newp;\n  NPP_DestroyProcPtr destroy;\n  NPP_SetWindowProcPtr setwindow;\n  NPP_NewStreamProcPtr newstream;\n  NPP_DestroyStreamProcPtr destroystream;\n  NPP_StreamAsFileProcPtr asfile;\n  NPP_WriteReadyProcPtr writeready;\n  NPP_WriteProcPtr write;\n  NPP_PrintProcPtr print;\n  NPP_HandleEventProcPtr event;\n  NPP_URLNotifyProcPtr urlnotify;\n  void* javaClass;\n  NPP_GetValueProcPtr getvalue;\n  NPP_SetValueProcPtr setvalue;\n} NPPluginFuncs;\n\ntypedef struct _NPNetscapeFuncs {\n  uint16_t size;\n  uint16_t version;\n  NPN_GetURLProcPtr geturl;\n  NPN_PostURLProcPtr posturl;\n  NPN_RequestReadProcPtr requestread;\n  NPN_NewStreamProcPtr newstream;\n  NPN_WriteProcPtr write;\n  NPN_DestroyStreamProcPtr destroystream;\n  NPN_StatusProcPtr status;\n  NPN_UserAgentProcPtr uagent;\n  NPN_MemAllocProcPtr memalloc;\n  NPN_MemFreeProcPtr memfree;\n  NPN_MemFlushProcPtr memflush;\n  NPN_ReloadPluginsProcPtr reloadplugins;\n  NPN_GetJavaEnvProcPtr getJavaEnv;\n  NPN_GetJavaPeerProcPtr getJavaPeer;\n  NPN_GetURLNotifyProcPtr geturlnotify;\n  NPN_PostURLNotifyProcPtr posturlnotify;\n  NPN_GetValueProcPtr getvalue;\n  NPN_SetValueProcPtr setvalue;\n  NPN_InvalidateRectProcPtr invalidaterect;\n  NPN_InvalidateRegionProcPtr invalidateregion;\n  NPN_ForceRedrawProcPtr forceredraw;\n  NPN_GetStringIdentifierProcPtr getstringidentifier;\n  NPN_GetStringIdentifiersProcPtr getstringidentifiers;\n  NPN_GetIntIdentifierProcPtr getintidentifier;\n  NPN_IdentifierIsStringProcPtr identifierisstring;\n  NPN_UTF8FromIdentifierProcPtr utf8fromidentifier;\n  NPN_IntFromIdentifierProcPtr intfromidentifier;\n  NPN_CreateObjectProcPtr createobject;\n  NPN_RetainObjectProcPtr retainobject;\n  NPN_ReleaseObjectProcPtr releaseobject;\n  NPN_InvokeProcPtr invoke;\n  NPN_InvokeDefaultProcPtr invokeDefault;\n  NPN_EvaluateProcPtr evaluate;\n  NPN_GetPropertyProcPtr getproperty;\n  NPN_SetPropertyProcPtr setproperty;\n  NPN_RemovePropertyProcPtr removeproperty;\n  NPN_HasPropertyProcPtr hasproperty;\n  NPN_HasMethodProcPtr hasmethod;\n  NPN_ReleaseVariantValueProcPtr releasevariantvalue;\n  NPN_SetExceptionProcPtr setexception;\n  NPN_PushPopupsEnabledStateProcPtr pushpopupsenabledstate;\n  NPN_PopPopupsEnabledStateProcPtr poppopupsenabledstate;\n  NPN_EnumerateProcPtr enumerate;\n  NPN_PluginThreadAsyncCallProcPtr pluginthreadasynccall;\n  NPN_ConstructProcPtr construct;\n  NPN_GetValueForURLPtr getvalueforurl;\n  NPN_SetValueForURLPtr setvalueforurl;\n  NPN_GetAuthenticationInfoPtr getauthenticationinfo;\n} NPNetscapeFuncs;\n\n#ifdef XP_MACOSX\n/*\n * Mac OS X version(s) of NP_GetMIMEDescription(const char *)\n * These can be called to retreive MIME information from the plugin dynamically\n *\n * Note: For compatibility with Quicktime, BPSupportedMIMEtypes is another way\n *       to get mime info from the plugin only on OSX and may not be supported\n *       in furture version -- use NP_GetMIMEDescription instead\n */\nenum\n{\n kBPSupportedMIMETypesStructVers_1    = 1\n};\ntypedef struct _BPSupportedMIMETypes\n{\n SInt32    structVersion;      /* struct version */\n Handle    typeStrings;        /* STR# formated handle, allocated by plug-in */\n Handle    infoStrings;        /* STR# formated handle, allocated by plug-in */\n} BPSupportedMIMETypes;\nOSErr BP_GetSupportedMIMETypes(BPSupportedMIMETypes *mimeInfo, UInt32 flags);\n#define NP_GETMIMEDESCRIPTION_NAME \"NP_GetMIMEDescription\"\ntypedef const char* (*NP_GetMIMEDescriptionProcPtr)();\ntypedef OSErr (*BP_GetSupportedMIMETypesProcPtr)(BPSupportedMIMETypes*, UInt32);\n#endif\n\n#if defined(_WINDOWS)\n#define OSCALL WINAPI\n#else\n#if defined(__OS2__)\n#define OSCALL _System\n#else\n#define OSCALL\n#endif\n#endif\n\n#if defined(XP_UNIX)\n/* GCC 3.3 and later support the visibility attribute. */\n#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))\n#define NP_VISIBILITY_DEFAULT __attribute__((visibility(\"default\")))\n#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)\n#define NP_VISIBILITY_DEFAULT __global\n#else\n#define NP_VISIBILITY_DEFAULT\n#endif\n#define NP_EXPORT(__type) NP_VISIBILITY_DEFAULT __type\n#endif\n\n#if defined(_WINDOWS) || defined (__OS2__)\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n/* plugin meta member functions */\n#if defined(__OS2__)\ntypedef struct _NPPluginData {   /* Alternate OS2 Plugin interface */\n  char *pMimeTypes;\n  char *pFileExtents;\n  char *pFileOpenTemplate;\n  char *pProductName;\n  char *pProductDescription;\n  unsigned long dwProductVersionMS;\n  unsigned long dwProductVersionLS;\n} NPPluginData;\nNPError OSCALL NP_GetPluginData(NPPluginData * pPluginData);\n#endif\nNPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs);\nNPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs);\nNPError OSCALL NP_Shutdown();\nchar*          NP_GetMIMEDescription();\n#ifdef __cplusplus\n}\n#endif\n#endif\n\n#if defined(__OS2__)\n#pragma pack()\n#endif\n\n#ifdef XP_UNIX\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nNP_EXPORT(char*)   NP_GetPluginVersion();\nNP_EXPORT(char*)   NP_GetMIMEDescription();\n#ifdef XP_MACOSX\nNP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs);\nNP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs);\n#else\nNP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs);\n#endif\nNP_EXPORT(NPError) NP_Shutdown();\nNP_EXPORT(NPError) NP_GetValue(void *future, NPPVariable aVariable, void *aValue);\n#ifdef __cplusplus\n}\n#endif\n#endif\n\n#endif /* npfunctions_h_ */\n"
  },
  {
    "path": "plugin/npn_entry.cc",
    "content": "#include \"npfunctions.h\"\n\nNPNetscapeFuncs* g_npn_funcs;\n\nvoid NP_LOADDS NPN_Version(int* plugin_major, int* plugin_minor, int* netscape_major, int* netscape_minor) {\n    *plugin_major = 1;\n    *plugin_minor = 1;\n    *netscape_major = g_npn_funcs->version >> 8;\n    *netscape_minor = g_npn_funcs->version & 0x00FF;\n}\n\nNPError NP_LOADDS NPN_GetURLNotify(NPP instance, const char* url, const char* target, void* notifyData) {\n    return g_npn_funcs->geturlnotify(instance, url, target, notifyData);\n}\n\nNPError NP_LOADDS NPN_GetURL(NPP instance,const char* url,const char* target) {\n    return g_npn_funcs->geturl(instance, url, target);\n}\n\nNPError NP_LOADDS NPN_PostURLNotify(NPP instance, const char* url, const char* target, uint32_t len, const char* buf, NPBool file, void* notifyData) {\n    return g_npn_funcs->posturlnotify(instance, url, target, len, buf, file, notifyData);\n}\n\nNPError NP_LOADDS NPN_PostURL(NPP instance, const char* url,const char* target, uint32_t len,const char* buf, NPBool file) {\n    return g_npn_funcs->posturl(instance, url, target, len, buf, file);\n}\n\nNPError NP_LOADDS NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) {\n    return g_npn_funcs->requestread(stream, rangeList);\n}\n\nNPError NP_LOADDS NPN_NewStream(NPP instance, NPMIMEType type, const char* target, NPStream** stream) {\n    return g_npn_funcs->newstream(instance, type, target, stream);\n}\n\nint32_t NP_LOADDS NPN_Write(NPP instance, NPStream* stream, int32_t len, void* buffer) {\n    return g_npn_funcs->write(instance, stream, len, buffer);\n}\n\nNPError NP_LOADDS NPN_DestroyStream(NPP instance, NPStream* stream, NPReason reason) {\n    return g_npn_funcs->destroystream(instance, stream, reason);\n}\n\nvoid NP_LOADDS NPN_Status(NPP instance, const char* message) {\n    g_npn_funcs->status(instance, message);\n}\n\nconst char* NP_LOADDS NPN_UserAgent(NPP instance) {\n    return g_npn_funcs->uagent(instance);\n}\n\nvoid* NP_LOADDS NPN_MemAlloc(uint32_t size) {\n    return g_npn_funcs->memalloc(size);\n}\n\nvoid NP_LOADDS NPN_MemFree(void* ptr) {\n    return g_npn_funcs->memfree(ptr);\n}\n\nuint32_t NP_LOADDS NPN_MemFlush(uint32_t size) {\n    return g_npn_funcs->memflush(size);\n}\n\nvoid NP_LOADDS NPN_ReloadPlugins(NPBool reloadPages) {\n    g_npn_funcs->reloadplugins(reloadPages);\n}\n\nNPError NP_LOADDS NPN_GetValue(NPP instance, NPNVariable variable, void *value) {\n    return g_npn_funcs->getvalue(instance, variable, value);\n}\n\nNPError NP_LOADDS NPN_SetValue(NPP instance, NPPVariable variable, void *value) {\n    return g_npn_funcs->setvalue(instance, variable, value);\n}\n\nvoid NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect *invalidRect) {\n    g_npn_funcs->invalidaterect(instance, invalidRect);\n}\n\nvoid NP_LOADDS NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion) {\n    g_npn_funcs->invalidateregion(instance, invalidRegion);\n}\n\nvoid NP_LOADDS NPN_ForceRedraw(NPP instance) {\n    g_npn_funcs->forceredraw(instance);\n}\n\nvoid NP_LOADDS NPN_PushPopupsEnabledState(NPP instance, NPBool enabled) {\n    g_npn_funcs->pushpopupsenabledstate(instance, enabled);\n}\n\nvoid NP_LOADDS NPN_PopPopupsEnabledState(NPP instance) {\n    g_npn_funcs->poppopupsenabledstate(instance);\n}\nvoid NP_LOADDS NPN_PluginThreadAsyncCall(NPP instance,void (*func) (void *), void *userData) {\n    g_npn_funcs->pluginthreadasynccall(instance, func, userData);\n}\n\nNPError NP_LOADDS NPN_GetValueForURL(NPP instance, NPNURLVariable variable, const char *url, char **value, uint32_t *len) {\n    return g_npn_funcs->getvalueforurl(instance, variable, url, value, len);\n}\n\nNPError NP_LOADDS NPN_SetValueForURL(NPP instance, NPNURLVariable variable, const char *url, const char *value, uint32_t len) {\n    return g_npn_funcs->setvalueforurl(instance, variable, url, value, len);\n}\nNPError NP_LOADDS NPN_GetAuthenticationInfo(NPP instance, const char *protocol, const char *host, int32_t port, const char *scheme, const char *realm, char **username, uint32_t *ulen, char **password, uint32_t *plen) {\n    return g_npn_funcs->getauthenticationinfo(instance, protocol, host, port, scheme, realm, username, ulen, password, plen);\n}\n\nNPObject *NPN_CreateObject(NPP npp, NPClass *aClass) {\n    return g_npn_funcs->createobject(npp, aClass);\n}\n\nNPObject *NPN_RetainObject(NPObject *npobj) {\n    return g_npn_funcs->retainobject(npobj);\n}\n\nvoid NPN_ReleaseObject(NPObject *npobj) {\n    g_npn_funcs->releaseobject(npobj);\n}\n\nbool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result) {\n    return g_npn_funcs->invoke(npp, npobj, methodName, args, argCount, result);\n}\n\nbool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result) {\n    return g_npn_funcs->invokeDefault(npp, npobj, args, argCount, result);\n}\n\nbool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script, NPVariant *result) {\n    return g_npn_funcs->evaluate(npp, npobj, script, result);\n}\n\nbool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, NPVariant *result) {\n    return g_npn_funcs->getproperty(npp, npobj, propertyName, result);\n}\n\nbool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, const NPVariant *value) {\n    return g_npn_funcs->setproperty(npp, npobj, propertyName, value);\n}\n\nbool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName) {\n    return g_npn_funcs->removeproperty(npp, npobj, propertyName);\n}\n\nbool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName) {\n    return g_npn_funcs->hasproperty(npp, npobj, propertyName);\n}\n\nbool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName) {\n    return g_npn_funcs->hasmethod(npp, npobj, methodName);\n}\n\nbool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier, uint32_t *count) {\n    return g_npn_funcs->enumerate(npp, npobj, identifier, count);\n}\n\nbool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result) {\n    return g_npn_funcs->construct(npp, npobj, args, argCount, result);\n}\n\nvoid NPN_SetException(NPObject *npobj, const NPUTF8 *message) {\n    g_npn_funcs->setexception(npobj, message);\n}\n\nNPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name) {\n    return g_npn_funcs->getstringidentifier(name);\n}\n\nvoid NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers) {\n    g_npn_funcs->getstringidentifiers(names, nameCount, identifiers);\n}\n\nNPIdentifier NPN_GetIntIdentifier(int32_t intid) {\n    return g_npn_funcs->getintidentifier(intid);\n}\n\nbool NPN_IdentifierIsString(NPIdentifier identifier) {\n    return g_npn_funcs->identifierisstring(identifier);\n}\n\nNPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier) {\n    return g_npn_funcs->utf8fromidentifier(identifier);\n}\n\nint32_t NPN_IntFromIdentifier(NPIdentifier identifier) {\n    return g_npn_funcs->intfromidentifier(identifier);\n}\n\nvoid NPN_ReleaseVariantValue(NPVariant *variant) {\n    g_npn_funcs->releasevariantvalue(variant);\n}\n"
  },
  {
    "path": "plugin/npp_entry.cc",
    "content": "#include \"log.h\"\n#include \"npfunctions.h\"\n#include \"plugin_base.h\"\n#include \"plugin_factory.h\"\n\nextern Log g_logger;\n\n#ifdef XP_UNIX\nchar* NPP_GetMIMEDescription() {\n    return \"\";\n}\n#endif\n\nNPError NP_LOADDS NPP_Initialize() {\n    return NPERR_NO_ERROR;\n}\n\nvoid NP_LOADDS NPP_Shutdown() {\n}\n\nNPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved) {\n    g_logger.WriteLog(\"msg\", \"NPP_New\");\n    PluginBase* pPlugin = PluginFactory::NewPlugin(pluginType);\n    if (pPlugin == NULL)\n        return NPERR_OUT_OF_MEMORY_ERROR;\n    else\n        return pPlugin->Init(instance, mode, argc, argn, argv, saved);\n}\n\nNPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save) {\n    g_logger.WriteLog(\"msg\", \"NPP_Destory\");\n    PluginBase* pPlugin = (PluginBase*)instance->pdata;\n    return pPlugin->UnInit(save);\n}\n\nNPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window) {\n    PluginBase* pPlugin = (PluginBase*)instance->pdata;\n    return pPlugin->SetWindow(window);\n}\n\nNPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype) {\n    PluginBase* pPlugin = (PluginBase*)instance->pdata;\n    return pPlugin->NewStream(type, stream, seekable, stype);\n}\n\nNPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) {\n    PluginBase* pPlugin = (PluginBase*)instance->pdata;\n    return pPlugin->DestroyStream(stream, reason);\n}\n\nint32_t NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream) {\n    PluginBase* pPlugin = (PluginBase*)instance->pdata;\n    return pPlugin->WriteReady(stream);\n}\n\nint32_t NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer) {\n    PluginBase* pPlugin = (PluginBase*)instance->pdata;\n    return pPlugin->Write(stream, offset, len, buffer);\n}\n\nvoid NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) {\n    PluginBase* pPlugin = (PluginBase*)instance->pdata;\n    pPlugin->StreamAsFile(stream, fname);\n}\n\nvoid NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint) {\n    PluginBase* pPlugin = (PluginBase*)instance->pdata;\n    pPlugin->Print(platformPrint);\n}\n\nint16_t NP_LOADDS NPP_HandleEvent(NPP instance, void* event) {\n    PluginBase* pPlugin = (PluginBase*)instance->pdata;\n    return pPlugin->HandleEvent(event);\n}\n\nvoid NP_LOADDS NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) {\n    PluginBase* pPlugin = (PluginBase*)instance->pdata;\n    pPlugin->URLNotify(url, reason, notifyData);\n}\n\nNPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value) {\n    if (instance == NULL) {\n        if (variable == NPPVpluginNameString)\n            *((const char **)value) = \"Chrome Fiddler\";\n        else if (variable == NPPVpluginDescriptionString)\n            *((const char **)value) = \"Chrome Fiddler Plugin\";\n        else\n            return NPERR_GENERIC_ERROR;\n    } else {\n        PluginBase* pPlugin = (PluginBase*)instance->pdata;\n        return pPlugin->GetValue(variable, value);\n    }\n    return NPERR_NO_ERROR;\n}\n\nNPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value) {\n    PluginBase* pPlugin = (PluginBase*)instance->pdata;\n    return pPlugin->SetValue(variable, value);\n}\n"
  },
  {
    "path": "plugin/npruntime.h",
    "content": "/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */\n/*\n * Copyright (c) 2004, Apple Computer, Inc. and The Mozilla Foundation.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the names of Apple Computer, Inc. (\"Apple\") or The Mozilla\n * Foundation (\"Mozilla\") nor the names of their contributors may be used\n * to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS \"AS\n * IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR\n * THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * Revision 1 (March 4, 2004):\n * Initial proposal.\n *\n * Revision 2 (March 10, 2004):\n * All calls into script were made asynchronous.  Results are\n * provided via the NPScriptResultFunctionPtr callback.\n *\n * Revision 3 (March 10, 2004):\n * Corrected comments to not refer to class retain/release FunctionPtrs.\n *\n * Revision 4 (March 11, 2004):\n * Added additional convenience NPN_SetExceptionWithUTF8().\n * Changed NPHasPropertyFunctionPtr and NPHasMethodFunctionPtr to take NPClass\n * pointers instead of NPObject pointers.\n * Added NPIsValidIdentifier().\n *\n * Revision 5 (March 17, 2004):\n * Added context parameter to result callbacks from ScriptObject functions.\n *\n * Revision 6 (March 29, 2004):\n * Renamed functions implemented by user agent to NPN_*.  Removed _ from\n * type names.\n * Renamed \"JavaScript\" types to \"Script\".\n *\n * Revision 7 (April 21, 2004):\n * NPIdentifier becomes a void*, was int32_t\n * Remove NP_IsValidIdentifier, renamed NP_IdentifierFromUTF8 to NP_GetIdentifier\n * Added NPVariant and modified functions to use this new type.\n *\n * Revision 8 (July 9, 2004):\n * Updated to joint Apple-Mozilla license.\n *\n */\n#ifndef _NP_RUNTIME_H_\n#define _NP_RUNTIME_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"nptypes.h\"\n\n/*\n    This API is used to facilitate binding code written in C to script\n    objects.  The API in this header does not assume the presence of a\n    user agent.  That is, it can be used to bind C code to scripting\n    environments outside of the context of a user agent.\n\n    However, the normal use of the this API is in the context of a\n    scripting environment running in a browser or other user agent.\n    In particular it is used to support the extended Netscape\n    script-ability API for plugins (NP-SAP).  NP-SAP is an extension\n    of the Netscape plugin API.  As such we have adopted the use of\n    the \"NP\" prefix for this API.\n\n    The following NP{N|P}Variables were added to the Netscape plugin\n    API (in npapi.h):\n\n    NPNVWindowNPObject\n    NPNVPluginElementNPObject\n    NPPVpluginScriptableNPObject\n\n    These variables are exposed through NPN_GetValue() and\n    NPP_GetValue() (respectively) and are used to establish the\n    initial binding between the user agent and native code.  The DOM\n    objects in the user agent can be examined and manipulated using\n    the NPN_ functions that operate on NPObjects described in this\n    header.\n\n    To the extent possible the assumptions about the scripting\n    language used by the scripting environment have been minimized.\n*/\n\n#define NP_BEGIN_MACRO  do {\n#define NP_END_MACRO    } while (0)\n\n/*\n    Objects (non-primitive data) passed between 'C' and script is\n    always wrapped in an NPObject.  The 'interface' of an NPObject is\n    described by an NPClass.\n*/\ntypedef struct NPObject NPObject;\ntypedef struct NPClass NPClass;\n\ntypedef char NPUTF8;\ntypedef struct _NPString {\n    const NPUTF8 *UTF8Characters;\n    uint32_t UTF8Length;\n} NPString;\n\ntypedef enum {\n    NPVariantType_Void,\n    NPVariantType_Null,\n    NPVariantType_Bool,\n    NPVariantType_Int32,\n    NPVariantType_Double,\n    NPVariantType_String,\n    NPVariantType_Object\n} NPVariantType;\n\ntypedef struct _NPVariant {\n    NPVariantType type;\n    union {\n        bool boolValue;\n        int32_t intValue;\n        double doubleValue;\n        NPString stringValue;\n        NPObject *objectValue;\n    } value;\n} NPVariant;\n\n/*\n    NPN_ReleaseVariantValue is called on all 'out' parameters\n    references.  Specifically it is to be called on variants that own\n    their value, as is the case with all non-const NPVariant*\n    arguments after a successful call to any methods (except this one)\n    in this API.\n\n    After calling NPN_ReleaseVariantValue, the type of the variant\n    will be NPVariantType_Void.\n*/\nvoid NPN_ReleaseVariantValue(NPVariant *variant);\n\n#define NPVARIANT_IS_VOID(_v)    ((_v).type == NPVariantType_Void)\n#define NPVARIANT_IS_NULL(_v)    ((_v).type == NPVariantType_Null)\n#define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool)\n#define NPVARIANT_IS_INT32(_v)   ((_v).type == NPVariantType_Int32)\n#define NPVARIANT_IS_DOUBLE(_v)  ((_v).type == NPVariantType_Double)\n#define NPVARIANT_IS_STRING(_v)  ((_v).type == NPVariantType_String)\n#define NPVARIANT_IS_OBJECT(_v)  ((_v).type == NPVariantType_Object)\n\n#define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue)\n#define NPVARIANT_TO_INT32(_v)   ((_v).value.intValue)\n#define NPVARIANT_TO_DOUBLE(_v)  ((_v).value.doubleValue)\n#define NPVARIANT_TO_STRING(_v)  ((_v).value.stringValue)\n#define NPVARIANT_TO_OBJECT(_v)  ((_v).value.objectValue)\n\n#define VOID_TO_NPVARIANT(_v)                                                 \\\nNP_BEGIN_MACRO                                                                \\\n    (_v).type = NPVariantType_Void;                                           \\\n    (_v).value.objectValue = NULL;                                            \\\nNP_END_MACRO\n\n#define NULL_TO_NPVARIANT(_v)                                                 \\\nNP_BEGIN_MACRO                                                                \\\n    (_v).type = NPVariantType_Null;                                           \\\n    (_v).value.objectValue = NULL;                                            \\\nNP_END_MACRO\n\n#define BOOLEAN_TO_NPVARIANT(_val, _v)                                        \\\nNP_BEGIN_MACRO                                                                \\\n    (_v).type = NPVariantType_Bool;                                           \\\n    (_v).value.boolValue = !!(_val);                                          \\\nNP_END_MACRO\n\n#define INT32_TO_NPVARIANT(_val, _v)                                          \\\nNP_BEGIN_MACRO                                                                \\\n    (_v).type = NPVariantType_Int32;                                          \\\n    (_v).value.intValue = _val;                                               \\\nNP_END_MACRO\n\n#define DOUBLE_TO_NPVARIANT(_val, _v)                                         \\\nNP_BEGIN_MACRO                                                                \\\n    (_v).type = NPVariantType_Double;                                         \\\n    (_v).value.doubleValue = _val;                                            \\\nNP_END_MACRO\n\n#define STRINGZ_TO_NPVARIANT(_val, _v)                                        \\\nNP_BEGIN_MACRO                                                                \\\n    (_v).type = NPVariantType_String;                                         \\\n    NPString str = { _val, strlen(_val) };                                    \\\n    (_v).value.stringValue = str;                                             \\\nNP_END_MACRO\n\n#define STRINGN_TO_NPVARIANT(_val, _len, _v)                                  \\\nNP_BEGIN_MACRO                                                                \\\n    (_v).type = NPVariantType_String;                                         \\\n    NPString str = { _val, _len };                                            \\\n    (_v).value.stringValue = str;                                             \\\nNP_END_MACRO\n\n#define OBJECT_TO_NPVARIANT(_val, _v)                                         \\\nNP_BEGIN_MACRO                                                                \\\n    (_v).type = NPVariantType_Object;                                         \\\n    (_v).value.objectValue = _val;                                            \\\nNP_END_MACRO\n\n\n/*\n  Type mappings (JavaScript types have been used for illustration\n    purposes):\n\n  JavaScript       to             C (NPVariant with type:)\n  undefined                       NPVariantType_Void\n  null                            NPVariantType_Null\n  Boolean                         NPVariantType_Bool\n  Number                          NPVariantType_Double or NPVariantType_Int32\n  String                          NPVariantType_String\n  Object                          NPVariantType_Object\n\n  C (NPVariant with type:)   to   JavaScript\n  NPVariantType_Void              undefined\n  NPVariantType_Null              null\n  NPVariantType_Bool              Boolean\n  NPVariantType_Int32             Number\n  NPVariantType_Double            Number\n  NPVariantType_String            String\n  NPVariantType_Object            Object\n*/\n\ntypedef void *NPIdentifier;\n\n/*\n    NPObjects have methods and properties.  Methods and properties are\n    identified with NPIdentifiers.  These identifiers may be reflected\n    in script.  NPIdentifiers can be either strings or integers, IOW,\n    methods and properties can be identified by either strings or\n    integers (i.e. foo[\"bar\"] vs foo[1]). NPIdentifiers can be\n    compared using ==.  In case of any errors, the requested\n    NPIdentifier(s) will be NULL. NPIdentifier lifetime is controlled\n    by the browser. Plugins do not need to worry about memory management\n    with regards to NPIdentifiers.\n*/\nNPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name);\nvoid NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount,\n                              NPIdentifier *identifiers);\nNPIdentifier NPN_GetIntIdentifier(int32_t intid);\nbool NPN_IdentifierIsString(NPIdentifier identifier);\n\n/*\n    The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed.\n*/\nNPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier);\n\n/*\n    Get the integer represented by identifier. If identifier is not an\n    integer identifier, the behaviour is undefined.\n*/\nint32_t NPN_IntFromIdentifier(NPIdentifier identifier);\n\n/*\n    NPObject behavior is implemented using the following set of\n    callback functions.\n\n    The NPVariant *result argument of these functions (where\n    applicable) should be released using NPN_ReleaseVariantValue().\n*/\ntypedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass);\ntypedef void (*NPDeallocateFunctionPtr)(NPObject *npobj);\ntypedef void (*NPInvalidateFunctionPtr)(NPObject *npobj);\ntypedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name);\ntypedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name,\n                                    const NPVariant *args, uint32_t argCount,\n                                    NPVariant *result);\ntypedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj,\n                                           const NPVariant *args,\n                                           uint32_t argCount,\n                                           NPVariant *result);\ntypedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name);\ntypedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,\n                                         NPVariant *result);\ntypedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name,\n                                         const NPVariant *value);\ntypedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj,\n                                            NPIdentifier name);\ntypedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value,\n                                         uint32_t *count);\ntypedef bool (*NPConstructFunctionPtr)(NPObject *npobj,\n                                       const NPVariant *args,\n                                       uint32_t argCount,\n                                       NPVariant *result);\n\n/*\n    NPObjects returned by create, retain, invoke, and getProperty pass\n    a reference count to the caller.  That is, the callee adds a\n    reference count which passes to the caller.  It is the caller's\n    responsibility to release the returned object.\n\n    NPInvokeFunctionPtr function may return 0 to indicate a void\n    result.\n\n    NPInvalidateFunctionPtr is called by the scripting environment\n    when the native code is shutdown.  Any attempt to message a\n    NPObject instance after the invalidate callback has been\n    called will result in undefined behavior, even if the native code\n    is still retaining those NPObject instances.  (The runtime\n    will typically return immediately, with 0 or NULL, from an attempt\n    to dispatch to a NPObject, but this behavior should not be\n    depended upon.)\n\n    The NPEnumerationFunctionPtr function may pass an array of\n    NPIdentifiers back to the caller. The callee allocs the memory of\n    the array using NPN_MemAlloc(), and it's the caller's responsibility\n    to release it using NPN_MemFree().\n*/\nstruct NPClass\n{\n    uint32_t structVersion;\n    NPAllocateFunctionPtr allocate;\n    NPDeallocateFunctionPtr deallocate;\n    NPInvalidateFunctionPtr invalidate;\n    NPHasMethodFunctionPtr hasMethod;\n    NPInvokeFunctionPtr invoke;\n    NPInvokeDefaultFunctionPtr invokeDefault;\n    NPHasPropertyFunctionPtr hasProperty;\n    NPGetPropertyFunctionPtr getProperty;\n    NPSetPropertyFunctionPtr setProperty;\n    NPRemovePropertyFunctionPtr removeProperty;\n    NPEnumerationFunctionPtr enumerate;\n    NPConstructFunctionPtr construct;\n};\n\n#define NP_CLASS_STRUCT_VERSION      3\n\n#define NP_CLASS_STRUCT_VERSION_ENUM 2\n#define NP_CLASS_STRUCT_VERSION_CTOR 3\n\n#define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass)   \\\n        ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM)\n\n#define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass)   \\\n        ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR)\n\nstruct NPObject {\n    NPClass *_class;\n    uint32_t referenceCount;\n    /*\n     * Additional space may be allocated here by types of NPObjects\n     */\n};\n\n/*\n    If the class has an allocate function, NPN_CreateObject invokes\n    that function, otherwise a NPObject is allocated and\n    returned. This method will initialize the referenceCount member of\n    the NPObject to 1.\n*/\nNPObject *NPN_CreateObject(NPP npp, NPClass *aClass);\n\n/*\n    Increment the NPObject's reference count.\n*/\nNPObject *NPN_RetainObject(NPObject *npobj);\n\n/*\n    Decremented the NPObject's reference count.  If the reference\n    count goes to zero, the class's destroy function is invoke if\n    specified, otherwise the object is freed directly.\n*/\nvoid NPN_ReleaseObject(NPObject *npobj);\n\n/*\n    Functions to access script objects represented by NPObject.\n\n    Calls to script objects are synchronous.  If a function returns a\n    value, it will be supplied via the result NPVariant\n    argument. Successful calls will return true, false will be\n    returned in case of an error.\n\n    Calls made from plugin code to script must be made from the thread\n    on which the plugin was initialized.\n*/\n\nbool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName,\n                const NPVariant *args, uint32_t argCount, NPVariant *result);\nbool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args,\n                       uint32_t argCount, NPVariant *result);\nbool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script,\n                  NPVariant *result);\nbool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,\n                     NPVariant *result);\nbool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName,\n                     const NPVariant *value);\nbool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);\nbool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName);\nbool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName);\nbool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier,\n                   uint32_t *count);\nbool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args,\n                   uint32_t argCount, NPVariant *result);\n\n/*\n    NPN_SetException may be called to trigger a script exception upon\n    return from entry points into NPObjects.  Typical usage:\n\n    NPN_SetException (npobj, message);\n*/\nvoid NPN_SetException(NPObject *npobj, const NPUTF8 *message);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "plugin/nptypes.h",
    "content": "/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n/* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1/GPL 2.0/LGPL 2.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is mozilla.org code.\n *\n * The Initial Developer of the Original Code is\n * mozilla.org.\n * Portions created by the Initial Developer are Copyright (C) 2004\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *   Johnny Stenback <jst@mozilla.org> (Original author)\n *\n * Alternatively, the contents of this file may be used under the terms of\n * either the GNU General Public License Version 2 or later (the \"GPL\"), or\n * the GNU Lesser General Public License Version 2.1 or later (the \"LGPL\"),\n * in which case the provisions of the GPL or the LGPL are applicable instead\n * of those above. If you wish to allow use of your version of this file only\n * under the terms of either the GPL or the LGPL, and not to allow others to\n * use your version of this file under the terms of the MPL, indicate your\n * decision by deleting the provisions above and replace them with the notice\n * and other provisions required by the GPL or the LGPL. If you do not delete\n * the provisions above, a recipient may use your version of this file under\n * the terms of any one of the MPL, the GPL or the LGPL.\n *\n * ***** END LICENSE BLOCK ***** */\n\n/*\n * Header file for ensuring that C99 types ([u]int32_t and bool) and\n * true/false macros are available.\n */\n\n#if defined(WIN32) || defined(OS2)\n  /*\n   * Win32 and OS/2 don't know C99, so define [u]int_16/32 here. The bool\n   * is predefined tho, both in C and C++.\n   */\n  typedef short int16_t;\n  typedef unsigned short uint16_t;\n  typedef int int32_t;\n  typedef unsigned int uint32_t;\n#elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(IRIX) || defined(HPUX)\n  /*\n   * AIX and SunOS ship a inttypes.h header that defines [u]int32_t,\n   * but not bool for C.\n   */\n  #include <inttypes.h>\n\n  #ifndef __cplusplus\n    typedef int bool;\n    #define true   1\n    #define false  0\n  #endif\n#elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD)\n  /*\n   * BSD/OS, FreeBSD, and OpenBSD ship sys/types.h that define int32_t and\n   * u_int32_t.\n   */\n  #include <sys/types.h>\n\n  /*\n   * BSD/OS ships no header that defines uint32_t, nor bool (for C)\n   */\n  #if defined(bsdi)\n  typedef u_int32_t uint32_t;\n\n  #if !defined(__cplusplus)\n    typedef int bool;\n    #define true   1\n    #define false  0\n  #endif\n  #else\n  /*\n   * FreeBSD and OpenBSD define uint32_t and bool.\n   */\n    #include <inttypes.h>\n    #include <stdbool.h>\n  #endif\n#elif defined(BEOS)\n  #include <inttypes.h>\n#else\n  /*\n   * For those that ship a standard C99 stdint.h header file, include\n   * it. Can't do the same for stdbool.h tho, since some systems ship\n   * with a stdbool.h file that doesn't compile!\n   */\n  #include <stdint.h>\n\n  #ifndef __cplusplus\n    #if !defined(__GNUC__) || (__GNUC__ > 2 || __GNUC_MINOR__ > 95)\n      #include <stdbool.h>\n    #else\n      /*\n       * GCC 2.91 can't deal with a typedef for bool, but a #define\n       * works.\n       */\n      #define bool int\n      #define true   1\n      #define false  0\n    #endif\n  #endif\n#endif\n"
  },
  {
    "path": "plugin/plugin_base.cc",
    "content": "#include \"plugin_base.h\"\n\nPluginBase::PluginBase(void) {\n}\n\nPluginBase::~PluginBase(void) {\n}\n\nNPError PluginBase::Init(NPP instance, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved) {\n    npp_ = instance;\n    return NPERR_NO_ERROR;\n}\n\nNPError PluginBase::UnInit(NPSavedData** save) {\n    return NPERR_NO_ERROR;\n}\n\nNPError PluginBase::SetWindow(NPWindow* window) {\n    native_window_ = (NativeWindow)window->window;\n    return NPERR_NO_ERROR;\n}\n\nNPError PluginBase::NewStream(NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype) {\n    return NPERR_NO_ERROR;\n}\n\nNPError PluginBase::DestroyStream(NPStream* stream, NPReason reason) {\n    return NPERR_NO_ERROR;\n}\n\nint32_t PluginBase::WriteReady(NPStream* stream) {\n    return 0;\n}\n\nint32_t PluginBase::Write(NPStream* stream, int32_t offset, int32_t len, void* buffer) {\n    return 0;\n}\n\nvoid PluginBase::StreamAsFile(NPStream* stream, const char* fname) {\n}\n\nvoid PluginBase::Print(NPPrint* platformPrint) {\n}\n\nint16_t PluginBase::HandleEvent(void* event) {\n    return 0;\n}\n\nvoid PluginBase::URLNotify(const char* url, NPReason reason, void* notifyData) {\n}\n\nNPError PluginBase::GetValue(NPPVariable variable, void *value) {\n    return NPERR_NO_ERROR;\n}\n\nNPError PluginBase::SetValue(NPNVariable variable, void *value) {\n    return NPERR_NO_ERROR;\n}\n"
  },
  {
    "path": "plugin/plugin_base.h",
    "content": "#ifndef PLUGIN_BASE_H_\n#define PLUGIN_BASE_H_\n\n#include \"npapi.h\"\n\n#ifdef _WINDOWS\ntypedef HWND NativeWindow;\n#elif defined MAC\n#include \"npapi.h\"\ntypedef NP_CGContext* NativeWindow;\n#endif\n\n\nclass PluginBase {\npublic:\n    PluginBase(void);\n    virtual ~PluginBase(void);\n\n    virtual NPError Init(NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved);\n    virtual NPError UnInit(NPSavedData** save);\n    virtual NPError SetWindow(NPWindow* window);\n    virtual NPError NewStream(NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype);\n    virtual NPError DestroyStream(NPStream* stream, NPReason reason);\n    virtual int32_t WriteReady(NPStream* stream);\n    virtual int32_t Write(NPStream* stream, int32_t offset, int32_t len, void* buffer);\n    virtual void StreamAsFile(NPStream* stream, const char* fname);\n    virtual void Print(NPPrint* platformPrint);\n    virtual int16_t HandleEvent(void* event);\n    virtual void URLNotify(const char* url, NPReason reason, void* notifyData);\n    virtual NPError GetValue(NPPVariable variable, void *value);\n    virtual NPError SetValue(NPNVariable variable, void *value);\n\n    NPP get_npp() const { return npp_; }\n    void set_npp(NPP npp) { npp_ = npp; }\n\n    NativeWindow get_native_window() const { return native_window_; }\n    void set_native_window(NativeWindow nw) { native_window_ = nw; }\n\nprotected:\n    NPP npp_;\n    NativeWindow native_window_;\n};\n\n#endif    // PLUGIN_BASE_H_\n"
  },
  {
    "path": "plugin/plugin_factory.cc",
    "content": "#include \"plugin_factory.h\"\n#include \"chrome_fiddler_plugin.h\"\n\nPluginFactory::PluginTypeMap PluginFactory::plugin_type_map_;\n\nvoid PluginFactory::Init() {\n    PluginTypeItem item;\n    item.mime_type = \"application/x-chromefiddler\";\n    item.constructor = &ChromeFiddlerPlugin::CreateObject;\n    plugin_type_map_.insert(PluginTypeMap::value_type(item.mime_type, item));\n}\n\nPluginBase* PluginFactory::NewPlugin(NPMIMEType pluginType) {\n    PluginBase* plugin = NULL;\n    PluginTypeMap::iterator iter = plugin_type_map_.find(pluginType);\n    if (iter != plugin_type_map_.end())\n        plugin = iter->second.constructor();\n\n    return plugin;\n}\n"
  },
  {
    "path": "plugin/plugin_factory.h",
    "content": "#ifndef PLUGIN_FACTORY_H_\n#define PLUGIN_FACTORY_H_\n\n#include <map>\n#include <string>\n\n#include \"plugin_base.h\"\n\ntypedef PluginBase* (*ConstructorPtr)();\n\nclass PluginFactory {\nprivate:\n    PluginFactory(void);\n    ~PluginFactory(void);\n\npublic:\n    static void Init();\n    static PluginBase* NewPlugin(NPMIMEType pluginType);\n\npublic:\n    struct PluginTypeItem {\n        std::string mime_type;\n        ConstructorPtr constructor;\n    };\n\n    typedef std::map<std::string, PluginTypeItem> PluginTypeMap;\n\nprivate:\n    static PluginTypeMap plugin_type_map_;\n};\n\n#endif\n"
  },
  {
    "path": "plugin/script_object_base.cc",
    "content": "#include \"script_object_base.h\"\n#include \"utils.h\"\n\nbool ScriptObjectBase::HasMethod(NPIdentifier name) {\n    bool ret = false;\n    utils::IdentifiertoString method_name(name);\n    if (method_name.identifier_name()) {\n        FunctionMap::iterator iter = function_map_.find((const char*)method_name);\n        ret = iter != function_map_.end();\n    }\n    return ret;\n}\n\nbool ScriptObjectBase::Invoke(NPIdentifier name,const NPVariant *args, uint32_t argCount,NPVariant *result) {\n    bool ret = false;\n    utils::IdentifiertoString method_name(name);\n    if (method_name.identifier_name()) {\n        FunctionMap::iterator iter = function_map_.find((const char*)method_name);\n        if (iter != function_map_.end())\n            ret = (this->*(iter->second.function_pointer))(args, argCount, result);\n    }\n    return ret;\n}\n\nbool ScriptObjectBase::HasProperty(NPIdentifier name) {\n    bool ret = false;\n    utils::IdentifiertoString property_name(name);\n    if (property_name.identifier_name()) {\n        PropertyMap::iterator iter = property_map_.find((const char*)property_name);\n        ret = iter != property_map_.end();\n    }\n    return ret;\n}\n\nbool ScriptObjectBase::GetProperty(NPIdentifier name, NPVariant *result) {\n    bool ret = false;\n    utils::IdentifiertoString property_name(name);\n    if (property_name.identifier_name()) {\n        PropertyMap::iterator iter = property_map_.find((const char*)property_name);\n        if (iter != property_map_.end()) {\n            *result = iter->second.property_value;\n            ret = true;\n        }\n    }\n    return ret;\n}\n\nbool ScriptObjectBase::SetProperty(NPIdentifier name, const NPVariant *value) {\n    bool ret = false;\n    utils::IdentifiertoString property_name(name);\n    if (property_name.identifier_name()) {\n        PropertyMap::iterator iter = property_map_.find((const char*)property_name);\n        if (iter != property_map_.end()) {\n            iter->second.property_value = *value;\n            ret = true;\n        }\n    }\n    return ret;\n}\nbool ScriptObjectBase::RemoveProperty(NPIdentifier name) {\n    bool ret = false;\n    utils::IdentifiertoString property_name(name);\n    if (property_name.identifier_name()) {\n        PropertyMap::iterator iter = property_map_.find((const char*)property_name);\n        if (iter != property_map_.end()) {\n            property_map_.erase(iter);\n            ret = true;\n        }\n    }\n    return ret;\n}\n\nvoid ScriptObjectBase::AddProperty(PropertyItem& item) {\n    PropertyMap::iterator iter = property_map_.find(item.property_name);\n    if (iter != property_map_.end())\n        return;\n\n    property_map_.insert(PropertyMap::value_type(item.property_name, item));\n}\n\nvoid ScriptObjectBase::AddFunction(FunctionItem& item) {\n    FunctionMap::iterator iter = function_map_.find(item.function_name);\n    if (iter != function_map_.end())\n        return;\n\n    function_map_.insert(FunctionMap::value_type(item.function_name, item));\n}\n"
  },
  {
    "path": "plugin/script_object_base.h",
    "content": "#ifndef SCRIPT_OBJECT_BASE_H_\n#define SCRIPT_OBJECT_BASE_H_\n\n#include <map>\n#include <string>\n\n#include \"npapi.h\"\n#include \"npruntime.h\"\n#include \"plugin_base.h\"\n\nclass ScriptObjectBase : public NPObject {\npublic:\n    ScriptObjectBase(void) {}\n    virtual ~ScriptObjectBase(void) {}\n\n    typedef bool (ScriptObjectBase::*InvokePtr)(const NPVariant *args, uint32_t argCount, NPVariant *result);\n\n    struct FunctionItem {\n        std::string function_name;\n        InvokePtr function_pointer;\n    };\n\n    struct PropertyItem {\n        std::string property_name;\n        NPVariant property_value;\n    };\n\n    virtual void Deallocate() = 0;\n    virtual void Invalidate() = 0;\n    virtual bool HasMethod(NPIdentifier name);\n    virtual bool Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);\n    virtual bool InvokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result) { return false; }\n    virtual bool HasProperty(NPIdentifier name);\n    virtual bool GetProperty(NPIdentifier name, NPVariant *result);\n    virtual bool SetProperty(NPIdentifier name, const NPVariant *value);\n    virtual bool RemoveProperty(NPIdentifier name);\n    virtual bool Enumerate(NPIdentifier **value, uint32_t *count) { return false; }\n    virtual bool Construct(const NPVariant *args, uint32_t argCount, NPVariant *result) = 0;\n    virtual void InitHandler() {}\n\nprotected:\n    void AddProperty(PropertyItem& item);\n    void AddFunction(FunctionItem& item);\n\n    void set_plugin(PluginBase* plug) { plugin_ = plug; }\n    PluginBase* get_plugin() { return plugin_; }\n\nprivate:\n    typedef std::map<std::string, FunctionItem> FunctionMap;\n    typedef std::map<std::string, PropertyItem> PropertyMap;\n    FunctionMap function_map_;\n    PropertyMap property_map_;\n    PluginBase* plugin_;\n\n};\n\n#define ON_INVOKEHELPER(_funPtr) \\\n    static_cast<bool (ScriptObjectBase::*)(const NPVariant *,uint32_t , NPVariant *)>(_funPtr)\n#endif\n"
  },
  {
    "path": "plugin/script_object_factory.cc",
    "content": "#include \"script_object_factory.h\"\n\nNPClass ScriptObjectFactory::npclass_ = {\n    NP_CLASS_STRUCT_VERSION,\n    ScriptObjectFactory::Allocate,\n    ScriptObjectFactory::Deallocate,\n    ScriptObjectFactory::Invalidate,\n    ScriptObjectFactory::HasMethod,\n    ScriptObjectFactory::Invoke,\n    ScriptObjectFactory::InvokeDefault,\n    ScriptObjectFactory::HasProperty,\n    ScriptObjectFactory::GetProperty,\n    ScriptObjectFactory::SetProperty,\n    ScriptObjectFactory::RemoveProperty,\n    ScriptObjectFactory::Enumerate,\n    ScriptObjectFactory::Construct\n};\n\nScriptObjectFactory::ScriptObjectFactory(void) {\n}\n\nScriptObjectFactory::~ScriptObjectFactory(void) {\n}\n\nScriptObjectBase* ScriptObjectFactory::CreateObject(NPP npp, NPAllocateFunctionPtr allocate) {\n    npclass_.allocate = allocate;\n    ScriptObjectBase* object = (ScriptObjectBase*)NPN_CreateObject(npp, &npclass_);\n    if (object) {\n        object->InitHandler();\n    }\n    return object;\n}\n\nNPObject* ScriptObjectFactory::Allocate(NPP npp, NPClass *aClass) {\n    return NULL;\n}\n\nvoid ScriptObjectFactory::Deallocate(NPObject *npobj) {\n    ScriptObjectBase* pObject = (ScriptObjectBase*)npobj;\n    pObject->Deallocate();\n}\n\nvoid ScriptObjectFactory::Invalidate(NPObject *npobj) {\n    ScriptObjectBase* pObject = (ScriptObjectBase*)npobj;\n    pObject->Invalidate();\n}\n\nbool ScriptObjectFactory::HasMethod(NPObject *npobj, NPIdentifier name) {\n    ScriptObjectBase* pObject = (ScriptObjectBase*)npobj;\n    return pObject->HasMethod(name);\n}\n\nbool ScriptObjectFactory::Invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result) {\n    ScriptObjectBase* pObject = (ScriptObjectBase*)npobj;\n    return pObject->Invoke(name, args, argCount, result);\n}\n\nbool ScriptObjectFactory::InvokeDefault(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result) {\n    ScriptObjectBase* pObject = (ScriptObjectBase*)npobj;\n    return pObject->InvokeDefault(args, argCount, result);\n}\n\nbool ScriptObjectFactory::HasProperty(NPObject *npobj, NPIdentifier name) {\n    ScriptObjectBase* pObject = (ScriptObjectBase*)npobj;\n    return pObject->HasProperty(name);\n}\n\nbool ScriptObjectFactory::GetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) {\n    ScriptObjectBase* pObject = (ScriptObjectBase*)npobj;\n    return pObject->GetProperty(name, result);\n}\n\nbool ScriptObjectFactory::SetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value) {\n    ScriptObjectBase* pObject = (ScriptObjectBase*)npobj;\n    return pObject->SetProperty(name, value);\n}\n\nbool ScriptObjectFactory::RemoveProperty(NPObject *npobj, NPIdentifier name) {\n    ScriptObjectBase* pObject = (ScriptObjectBase*)npobj;\n    return pObject->RemoveProperty(name);\n}\n\nbool ScriptObjectFactory::Enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count) {\n    ScriptObjectBase* pObject = (ScriptObjectBase*)npobj;\n    return pObject->Enumerate(value, count);\n}\n\nbool ScriptObjectFactory::Construct(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result) {\n    ScriptObjectBase* pObject = (ScriptObjectBase*)npobj;\n    return pObject->Construct(args, argCount, result);\n}"
  },
  {
    "path": "plugin/script_object_factory.h",
    "content": "#ifndef SCRIPT_OBJECT_FACTORY_H_\n#define SCRIPT_OBJECT_FACTORY_H_\n\n#include \"script_object_base.h\"\n\nclass ScriptObjectFactory {\npublic:\n    ScriptObjectFactory(void);\n    ~ScriptObjectFactory(void);\n\n    static ScriptObjectBase* CreateObject(NPP npp, NPAllocateFunctionPtr allocate);\n\nprivate:\n    static NPObject* Allocate(NPP npp, NPClass *aClass);\n    static void Deallocate(NPObject *npobj);\n    static void Invalidate(NPObject *npobj);\n    static bool HasMethod(NPObject *npobj, NPIdentifier name);\n    static bool Invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);\n    static bool InvokeDefault(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result);\n    static bool HasProperty(NPObject *npobj, NPIdentifier name);\n    static bool GetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result);\n    static bool SetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value);\n    static bool RemoveProperty(NPObject *npobj, NPIdentifier name);\n    static bool Enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count);\n    static bool Construct(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result);\n\nprivate:\n    static NPClass npclass_;\n};\n\n#endif    // SCRIPT_OBJECT_FACTORY_H_"
  },
  {
    "path": "plugin/utils.h",
    "content": "#ifndef UTIL_H_\n#define UTIL_H_\n\n#ifdef _WINDOWS\n#include <windows.h>\n#endif\n\n#include \"npfunctions.h\"\n\nnamespace utils {\n\nclass IdentifiertoString {\npublic:\n    explicit IdentifiertoString(NPIdentifier identifier) : identifier_name_(NULL) {\n        identifier_name_ = NPN_UTF8FromIdentifier(identifier);\n    }\n    const char* identifier_name() const { return identifier_name_; }\n    operator const char*() const { return identifier_name_; }\n    ~IdentifiertoString() { if (identifier_name_) NPN_MemFree(identifier_name_); }\n\nprivate:\n    // Disable evil constructors.\n    IdentifiertoString();\n    IdentifiertoString(const IdentifiertoString&);\n\n    char* identifier_name_;\n};\n\n#ifdef _WINDOWS\nclass Utf8ToUnicode {\npublic:\n    explicit Utf8ToUnicode(const char* utf8data, unsigned int datalen = -1) : buffer_(NULL) {\n        int size = MultiByteToWideChar(CP_UTF8, 0, utf8data, datalen, 0, 0);\n        if (size > 0)\n            buffer_ = new WCHAR[size + 1];\n        if (buffer_) {\n            MultiByteToWideChar(CP_UTF8, 0, utf8data, datalen, buffer_, size);\n            buffer_[size] = 0;\n        }\n    }\n    operator WCHAR*() const { return buffer_; }\n    WCHAR** operator &() { return &buffer_; }\n    ~Utf8ToUnicode() { if (buffer_) delete[] buffer_; }\n\nprivate:\n    Utf8ToUnicode();\n    Utf8ToUnicode(const Utf8ToUnicode&);\n    WCHAR* buffer_;\n};\n#endif\n\n}\n\n#endif\n"
  },
  {
    "path": "src/bin/chrome_fiddler.plugin/Contents/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>English</string>\n\t<key>CFBundleExecutable</key>\n\t<string>chrome_fiddler</string>\n\t<key>CFBundleGetInfoString</key>\n\t<string>420+, Copyright 2006-2009 Apple Inc.</string>\n\t<key>CFBundleIconFile</key>\n\t<string></string>\n\t<key>CFBundleIdentifier</key>\n\t<string>chrome.chrome_fiddler</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BRPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n\t<key>CFPlugInDynamicRegisterFunction</key>\n\t<string></string>\n\t<key>CFPlugInDynamicRegistration</key>\n\t<string>NO</string>\n\t<key>CFPlugInFactories</key>\n\t<dict>\n\t\t<key>00000000-0000-0000-0000-000000000000</key>\n\t\t<string>MyFactoryFunction</string>\n\t</dict>\n\t<key>CFPlugInTypes</key>\n\t<dict>\n\t\t<key>00000000-0000-0000-0000-000000000000</key>\n\t\t<array>\n\t\t\t<string>00000000-0000-0000-0000-000000000000</string>\n\t\t</array>\n\t</dict>\n\t<key>CFPlugInUnloadFunction</key>\n\t<string></string>\n\t<key>WebPluginDescription</key>\n\t<string>Chrome Fiddler Extension Plugin</string>\n\t<key>WebPluginMIMETypes</key>\n\t<dict>\n\t\t<key>application/x-chromefiddler</key>\n\t\t<dict>\n\t\t\t<key>WebPluginExtensions</key>\n\t\t\t<array>\n\t\t\t\t<string>chrome_fiddler</string>\n\t\t\t</array>\n\t\t\t<key>WebPluginTypeDescription</key>\n\t\t\t<string>Chrome Fiddler Extension Plugin</string>\n\t\t</dict>\n\t</dict>\n\t<key>WebPluginName</key>\n\t<string>Chrome Fiddler Extension Plugin</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "src/css/lib/bootstrap.css",
    "content": "/*!\n * Bootstrap v2.3.2\n *\n * Copyright 2012 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Designed and built with all the love in the world @twitter by @mdo and @fat.\n */\n\n.clearfix {\n  *zoom: 1;\n}\n\n.clearfix:before,\n.clearfix:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.clearfix:after {\n  clear: both;\n}\n\n.hide-text {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n\n.input-block-level {\n  display: block;\n  width: 100%;\n  min-height: 30px;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nnav,\nsection {\n  display: block;\n}\n\naudio,\ncanvas,\nvideo {\n  display: inline-block;\n  *display: inline;\n  *zoom: 1;\n}\n\naudio:not([controls]) {\n  display: none;\n}\n\nhtml {\n  font-size: 100%;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\n\na:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\na:hover,\na:active {\n  outline: 0;\n}\n\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nimg {\n  width: auto\\9;\n  height: auto;\n  max-width: 100%;\n  vertical-align: middle;\n  border: 0;\n  -ms-interpolation-mode: bicubic;\n}\n\n#map_canvas img,\n.google-maps img {\n  max-width: none;\n}\n\nbutton,\ninput,\nselect,\ntextarea {\n  margin: 0;\n  font-size: 100%;\n  vertical-align: middle;\n}\n\nbutton,\ninput {\n  *overflow: visible;\n  line-height: normal;\n}\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\n\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  cursor: pointer;\n  -webkit-appearance: button;\n}\n\nlabel,\nselect,\nbutton,\ninput[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"],\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  cursor: pointer;\n}\n\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\n\ninput[type=\"search\"]::-webkit-search-decoration,\ninput[type=\"search\"]::-webkit-search-cancel-button {\n  -webkit-appearance: none;\n}\n\ntextarea {\n  overflow: auto;\n  vertical-align: top;\n}\n\n@media print {\n  * {\n    color: #000 !important;\n    text-shadow: none !important;\n    background: transparent !important;\n    box-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  .ir a:after,\n  a[href^=\"javascript:\"]:after,\n  a[href^=\"#\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  @page  {\n    margin: 0.5cm;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n}\n\nbody {\n  margin: 0;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 20px;\n  color: #333333;\n  background-color: #ffffff;\n}\n\na {\n  color: #0088cc;\n  text-decoration: none;\n}\n\na:hover,\na:focus {\n  color: #005580;\n  text-decoration: underline;\n}\n\n.img-rounded {\n  -webkit-border-radius: 6px;\n     -moz-border-radius: 6px;\n          border-radius: 6px;\n}\n\n.img-polaroid {\n  padding: 4px;\n  background-color: #fff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n     -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.img-circle {\n  -webkit-border-radius: 500px;\n     -moz-border-radius: 500px;\n          border-radius: 500px;\n}\n\n.row {\n  margin-left: -20px;\n  *zoom: 1;\n}\n\n.row:before,\n.row:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.row:after {\n  clear: both;\n}\n\n[class*=\"span\"] {\n  float: left;\n  min-height: 1px;\n  margin-left: 20px;\n}\n\n.container,\n.navbar-static-top .container,\n.navbar-fixed-top .container,\n.navbar-fixed-bottom .container {\n  width: 940px;\n}\n\n.span12 {\n  width: 940px;\n}\n\n.span11 {\n  width: 860px;\n}\n\n.span10 {\n  width: 780px;\n}\n\n.span9 {\n  width: 700px;\n}\n\n.span8 {\n  width: 620px;\n}\n\n.span7 {\n  width: 540px;\n}\n\n.span6 {\n  width: 460px;\n}\n\n.span5 {\n  width: 380px;\n}\n\n.span4 {\n  width: 300px;\n}\n\n.span3 {\n  width: 220px;\n}\n\n.span2 {\n  width: 140px;\n}\n\n.span1 {\n  width: 60px;\n}\n\n.offset12 {\n  margin-left: 980px;\n}\n\n.offset11 {\n  margin-left: 900px;\n}\n\n.offset10 {\n  margin-left: 820px;\n}\n\n.offset9 {\n  margin-left: 740px;\n}\n\n.offset8 {\n  margin-left: 660px;\n}\n\n.offset7 {\n  margin-left: 580px;\n}\n\n.offset6 {\n  margin-left: 500px;\n}\n\n.offset5 {\n  margin-left: 420px;\n}\n\n.offset4 {\n  margin-left: 340px;\n}\n\n.offset3 {\n  margin-left: 260px;\n}\n\n.offset2 {\n  margin-left: 180px;\n}\n\n.offset1 {\n  margin-left: 100px;\n}\n\n.row-fluid {\n  width: 100%;\n  *zoom: 1;\n}\n\n.row-fluid:before,\n.row-fluid:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.row-fluid:after {\n  clear: both;\n}\n\n.row-fluid [class*=\"span\"] {\n  display: block;\n  float: left;\n  width: 100%;\n  min-height: 30px;\n  margin-left: 2.127659574468085%;\n  *margin-left: 2.074468085106383%;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\n.row-fluid [class*=\"span\"]:first-child {\n  margin-left: 0;\n}\n\n.row-fluid .controls-row [class*=\"span\"] + [class*=\"span\"] {\n  margin-left: 2.127659574468085%;\n}\n\n.row-fluid .span12 {\n  width: 100%;\n  *width: 99.94680851063829%;\n}\n\n.row-fluid .span11 {\n  width: 91.48936170212765%;\n  *width: 91.43617021276594%;\n}\n\n.row-fluid .span10 {\n  width: 82.97872340425532%;\n  *width: 82.92553191489361%;\n}\n\n.row-fluid .span9 {\n  width: 74.46808510638297%;\n  *width: 74.41489361702126%;\n}\n\n.row-fluid .span8 {\n  width: 65.95744680851064%;\n  *width: 65.90425531914893%;\n}\n\n.row-fluid .span7 {\n  width: 57.44680851063829%;\n  *width: 57.39361702127659%;\n}\n\n.row-fluid .span6 {\n  width: 48.93617021276595%;\n  *width: 48.88297872340425%;\n}\n\n.row-fluid .span5 {\n  width: 40.42553191489362%;\n  *width: 40.37234042553192%;\n}\n\n.row-fluid .span4 {\n  width: 31.914893617021278%;\n  *width: 31.861702127659576%;\n}\n\n.row-fluid .span3 {\n  width: 23.404255319148934%;\n  *width: 23.351063829787233%;\n}\n\n.row-fluid .span2 {\n  width: 14.893617021276595%;\n  *width: 14.840425531914894%;\n}\n\n.row-fluid .span1 {\n  width: 6.382978723404255%;\n  *width: 6.329787234042553%;\n}\n\n.row-fluid .offset12 {\n  margin-left: 104.25531914893617%;\n  *margin-left: 104.14893617021275%;\n}\n\n.row-fluid .offset12:first-child {\n  margin-left: 102.12765957446808%;\n  *margin-left: 102.02127659574467%;\n}\n\n.row-fluid .offset11 {\n  margin-left: 95.74468085106382%;\n  *margin-left: 95.6382978723404%;\n}\n\n.row-fluid .offset11:first-child {\n  margin-left: 93.61702127659574%;\n  *margin-left: 93.51063829787232%;\n}\n\n.row-fluid .offset10 {\n  margin-left: 87.23404255319149%;\n  *margin-left: 87.12765957446807%;\n}\n\n.row-fluid .offset10:first-child {\n  margin-left: 85.1063829787234%;\n  *margin-left: 84.99999999999999%;\n}\n\n.row-fluid .offset9 {\n  margin-left: 78.72340425531914%;\n  *margin-left: 78.61702127659572%;\n}\n\n.row-fluid .offset9:first-child {\n  margin-left: 76.59574468085106%;\n  *margin-left: 76.48936170212764%;\n}\n\n.row-fluid .offset8 {\n  margin-left: 70.2127659574468%;\n  *margin-left: 70.10638297872339%;\n}\n\n.row-fluid .offset8:first-child {\n  margin-left: 68.08510638297872%;\n  *margin-left: 67.9787234042553%;\n}\n\n.row-fluid .offset7 {\n  margin-left: 61.70212765957446%;\n  *margin-left: 61.59574468085106%;\n}\n\n.row-fluid .offset7:first-child {\n  margin-left: 59.574468085106375%;\n  *margin-left: 59.46808510638297%;\n}\n\n.row-fluid .offset6 {\n  margin-left: 53.191489361702125%;\n  *margin-left: 53.085106382978715%;\n}\n\n.row-fluid .offset6:first-child {\n  margin-left: 51.063829787234035%;\n  *margin-left: 50.95744680851063%;\n}\n\n.row-fluid .offset5 {\n  margin-left: 44.68085106382979%;\n  *margin-left: 44.57446808510638%;\n}\n\n.row-fluid .offset5:first-child {\n  margin-left: 42.5531914893617%;\n  *margin-left: 42.4468085106383%;\n}\n\n.row-fluid .offset4 {\n  margin-left: 36.170212765957444%;\n  *margin-left: 36.06382978723405%;\n}\n\n.row-fluid .offset4:first-child {\n  margin-left: 34.04255319148936%;\n  *margin-left: 33.93617021276596%;\n}\n\n.row-fluid .offset3 {\n  margin-left: 27.659574468085104%;\n  *margin-left: 27.5531914893617%;\n}\n\n.row-fluid .offset3:first-child {\n  margin-left: 25.53191489361702%;\n  *margin-left: 25.425531914893618%;\n}\n\n.row-fluid .offset2 {\n  margin-left: 19.148936170212764%;\n  *margin-left: 19.04255319148936%;\n}\n\n.row-fluid .offset2:first-child {\n  margin-left: 17.02127659574468%;\n  *margin-left: 16.914893617021278%;\n}\n\n.row-fluid .offset1 {\n  margin-left: 10.638297872340425%;\n  *margin-left: 10.53191489361702%;\n}\n\n.row-fluid .offset1:first-child {\n  margin-left: 8.51063829787234%;\n  *margin-left: 8.404255319148938%;\n}\n\n[class*=\"span\"].hide,\n.row-fluid [class*=\"span\"].hide {\n  display: none;\n}\n\n[class*=\"span\"].pull-right,\n.row-fluid [class*=\"span\"].pull-right {\n  float: right;\n}\n\n.container {\n  margin-right: auto;\n  margin-left: auto;\n  *zoom: 1;\n}\n\n.container:before,\n.container:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.container:after {\n  clear: both;\n}\n\n.container-fluid {\n  padding-right: 20px;\n  padding-left: 20px;\n  *zoom: 1;\n}\n\n.container-fluid:before,\n.container-fluid:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.container-fluid:after {\n  clear: both;\n}\n\np {\n  margin: 0 0 10px;\n}\n\n.lead {\n  margin-bottom: 20px;\n  font-size: 21px;\n  font-weight: 200;\n  line-height: 30px;\n}\n\nsmall {\n  font-size: 85%;\n}\n\nstrong {\n  font-weight: bold;\n}\n\nem {\n  font-style: italic;\n}\n\ncite {\n  font-style: normal;\n}\n\n.muted {\n  color: #999999;\n}\n\na.muted:hover,\na.muted:focus {\n  color: #808080;\n}\n\n.text-warning {\n  color: #c09853;\n}\n\na.text-warning:hover,\na.text-warning:focus {\n  color: #a47e3c;\n}\n\n.text-error {\n  color: #b94a48;\n}\n\na.text-error:hover,\na.text-error:focus {\n  color: #953b39;\n}\n\n.text-info {\n  color: #3a87ad;\n}\n\na.text-info:hover,\na.text-info:focus {\n  color: #2d6987;\n}\n\n.text-success {\n  color: #468847;\n}\n\na.text-success:hover,\na.text-success:focus {\n  color: #356635;\n}\n\n.text-left {\n  text-align: left;\n}\n\n.text-right {\n  text-align: right;\n}\n\n.text-center {\n  text-align: center;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n  margin: 10px 0;\n  font-family: inherit;\n  font-weight: bold;\n  line-height: 20px;\n  color: inherit;\n  text-rendering: optimizelegibility;\n}\n\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small {\n  font-weight: normal;\n  line-height: 1;\n  color: #999999;\n}\n\nh1,\nh2,\nh3 {\n  line-height: 40px;\n}\n\nh1 {\n  font-size: 38.5px;\n}\n\nh2 {\n  font-size: 31.5px;\n}\n\nh3 {\n  font-size: 24.5px;\n}\n\nh4 {\n  font-size: 17.5px;\n}\n\nh5 {\n  font-size: 14px;\n}\n\nh6 {\n  font-size: 11.9px;\n}\n\nh1 small {\n  font-size: 24.5px;\n}\n\nh2 small {\n  font-size: 17.5px;\n}\n\nh3 small {\n  font-size: 14px;\n}\n\nh4 small {\n  font-size: 14px;\n}\n\n.page-header {\n  padding-bottom: 9px;\n  margin: 20px 0 30px;\n  border-bottom: 1px solid #eeeeee;\n}\n\nul,\nol {\n  padding: 0;\n  margin: 0 0 10px 25px;\n}\n\nul ul,\nul ol,\nol ol,\nol ul {\n  margin-bottom: 0;\n}\n\nli {\n  line-height: 20px;\n}\n\nul.unstyled,\nol.unstyled {\n  margin-left: 0;\n  list-style: none;\n}\n\nul.inline,\nol.inline {\n  margin-left: 0;\n  list-style: none;\n}\n\nul.inline > li,\nol.inline > li {\n  display: inline-block;\n  *display: inline;\n  padding-right: 5px;\n  padding-left: 5px;\n  *zoom: 1;\n}\n\ndl {\n  margin-bottom: 20px;\n}\n\ndt,\ndd {\n  line-height: 20px;\n}\n\ndt {\n  font-weight: bold;\n}\n\ndd {\n  margin-left: 10px;\n}\n\n.dl-horizontal {\n  *zoom: 1;\n}\n\n.dl-horizontal:before,\n.dl-horizontal:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.dl-horizontal:after {\n  clear: both;\n}\n\n.dl-horizontal dt {\n  float: left;\n  width: 160px;\n  overflow: hidden;\n  clear: left;\n  text-align: right;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.dl-horizontal dd {\n  margin-left: 180px;\n}\n\nhr {\n  margin: 20px 0;\n  border: 0;\n  border-top: 1px solid #eeeeee;\n  border-bottom: 1px solid #ffffff;\n}\n\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #999999;\n}\n\nabbr.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\n\nblockquote {\n  padding: 0 0 0 15px;\n  margin: 0 0 20px;\n  border-left: 5px solid #eeeeee;\n}\n\nblockquote p {\n  margin-bottom: 0;\n  font-size: 17.5px;\n  font-weight: 300;\n  line-height: 1.25;\n}\n\nblockquote small {\n  display: block;\n  line-height: 20px;\n  color: #999999;\n}\n\nblockquote small:before {\n  content: '\\2014 \\00A0';\n}\n\nblockquote.pull-right {\n  float: right;\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid #eeeeee;\n  border-left: 0;\n}\n\nblockquote.pull-right p,\nblockquote.pull-right small {\n  text-align: right;\n}\n\nblockquote.pull-right small:before {\n  content: '';\n}\n\nblockquote.pull-right small:after {\n  content: '\\00A0 \\2014';\n}\n\nq:before,\nq:after,\nblockquote:before,\nblockquote:after {\n  content: \"\";\n}\n\naddress {\n  display: block;\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 20px;\n}\n\ncode,\npre {\n  padding: 0 3px 2px;\n  font-family: Monaco, Menlo, Consolas, \"Courier New\", monospace;\n  font-size: 12px;\n  color: #333333;\n  -webkit-border-radius: 3px;\n     -moz-border-radius: 3px;\n          border-radius: 3px;\n}\n\ncode {\n  padding: 2px 4px;\n  color: #d14;\n  white-space: nowrap;\n  background-color: #f7f7f9;\n  border: 1px solid #e1e1e8;\n}\n\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 20px;\n  word-break: break-all;\n  word-wrap: break-word;\n  white-space: pre;\n  white-space: pre-wrap;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n}\n\npre.prettyprint {\n  margin-bottom: 20px;\n}\n\npre code {\n  padding: 0;\n  color: inherit;\n  white-space: pre;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border: 0;\n}\n\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n\nform {\n  margin: 0 0 20px;\n}\n\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: 40px;\n  color: #333333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\n\nlegend small {\n  font-size: 15px;\n  color: #999999;\n}\n\nlabel,\ninput,\nbutton,\nselect,\ntextarea {\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n}\n\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n\nlabel {\n  display: block;\n  margin-bottom: 5px;\n}\n\nselect,\ntextarea,\ninput[type=\"text\"],\ninput[type=\"password\"],\ninput[type=\"datetime\"],\ninput[type=\"datetime-local\"],\ninput[type=\"date\"],\ninput[type=\"month\"],\ninput[type=\"time\"],\ninput[type=\"week\"],\ninput[type=\"number\"],\ninput[type=\"email\"],\ninput[type=\"url\"],\ninput[type=\"search\"],\ninput[type=\"tel\"],\ninput[type=\"color\"],\n.uneditable-input {\n  display: inline-block;\n  height: 20px;\n  padding: 4px 6px;\n  margin-bottom: 10px;\n  font-size: 14px;\n  line-height: 20px;\n  color: #555555;\n  vertical-align: middle;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n}\n\ninput,\ntextarea,\n.uneditable-input {\n  width: 206px;\n}\n\ntextarea {\n  height: auto;\n}\n\ntextarea,\ninput[type=\"text\"],\ninput[type=\"password\"],\ninput[type=\"datetime\"],\ninput[type=\"datetime-local\"],\ninput[type=\"date\"],\ninput[type=\"month\"],\ninput[type=\"time\"],\ninput[type=\"week\"],\ninput[type=\"number\"],\ninput[type=\"email\"],\ninput[type=\"url\"],\ninput[type=\"search\"],\ninput[type=\"tel\"],\ninput[type=\"color\"],\n.uneditable-input {\n  background-color: #ffffff;\n  border: 1px solid #cccccc;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;\n     -moz-transition: border linear 0.2s, box-shadow linear 0.2s;\n       -o-transition: border linear 0.2s, box-shadow linear 0.2s;\n          transition: border linear 0.2s, box-shadow linear 0.2s;\n}\n\ntextarea:focus,\ninput[type=\"text\"]:focus,\ninput[type=\"password\"]:focus,\ninput[type=\"datetime\"]:focus,\ninput[type=\"datetime-local\"]:focus,\ninput[type=\"date\"]:focus,\ninput[type=\"month\"]:focus,\ninput[type=\"time\"]:focus,\ninput[type=\"week\"]:focus,\ninput[type=\"number\"]:focus,\ninput[type=\"email\"]:focus,\ninput[type=\"url\"]:focus,\ninput[type=\"search\"]:focus,\ninput[type=\"tel\"]:focus,\ninput[type=\"color\"]:focus,\n.uneditable-input:focus {\n  border-color: rgba(82, 168, 236, 0.8);\n  outline: 0;\n  outline: thin dotted \\9;\n  /* IE6-9 */\n\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);\n     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  *margin-top: 0;\n  line-height: normal;\n}\n\ninput[type=\"file\"],\ninput[type=\"image\"],\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"],\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  width: auto;\n}\n\nselect,\ninput[type=\"file\"] {\n  height: 30px;\n  /* In IE7, the height of the select element cannot be changed by height, only font-size */\n\n  *margin-top: 4px;\n  /* For IE7, add top margin to align select with labels */\n\n  line-height: 30px;\n}\n\nselect {\n  width: 220px;\n  background-color: #ffffff;\n  border: 1px solid #cccccc;\n}\n\nselect[multiple],\nselect[size] {\n  height: auto;\n}\n\nselect:focus,\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\n.uneditable-input,\n.uneditable-textarea {\n  color: #999999;\n  cursor: not-allowed;\n  background-color: #fcfcfc;\n  border-color: #cccccc;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);\n     -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);\n}\n\n.uneditable-input {\n  overflow: hidden;\n  white-space: nowrap;\n}\n\n.uneditable-textarea {\n  width: auto;\n  height: auto;\n}\n\ninput:-moz-placeholder,\ntextarea:-moz-placeholder {\n  color: #999999;\n}\n\ninput:-ms-input-placeholder,\ntextarea:-ms-input-placeholder {\n  color: #999999;\n}\n\ninput::-webkit-input-placeholder,\ntextarea::-webkit-input-placeholder {\n  color: #999999;\n}\n\n.radio,\n.checkbox {\n  min-height: 20px;\n  padding-left: 20px;\n}\n\n.radio input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"] {\n  float: left;\n  margin-left: -20px;\n}\n\n.controls > .radio:first-child,\n.controls > .checkbox:first-child {\n  padding-top: 5px;\n}\n\n.radio.inline,\n.checkbox.inline {\n  display: inline-block;\n  padding-top: 5px;\n  margin-bottom: 0;\n  vertical-align: middle;\n}\n\n.radio.inline + .radio.inline,\n.checkbox.inline + .checkbox.inline {\n  margin-left: 10px;\n}\n\n.input-mini {\n  width: 60px;\n}\n\n.input-small {\n  width: 90px;\n}\n\n.input-medium {\n  width: 150px;\n}\n\n.input-large {\n  width: 210px;\n}\n\n.input-xlarge {\n  width: 270px;\n}\n\n.input-xxlarge {\n  width: 530px;\n}\n\ninput[class*=\"span\"],\nselect[class*=\"span\"],\ntextarea[class*=\"span\"],\n.uneditable-input[class*=\"span\"],\n.row-fluid input[class*=\"span\"],\n.row-fluid select[class*=\"span\"],\n.row-fluid textarea[class*=\"span\"],\n.row-fluid .uneditable-input[class*=\"span\"] {\n  float: none;\n  margin-left: 0;\n}\n\n.input-append input[class*=\"span\"],\n.input-append .uneditable-input[class*=\"span\"],\n.input-prepend input[class*=\"span\"],\n.input-prepend .uneditable-input[class*=\"span\"],\n.row-fluid input[class*=\"span\"],\n.row-fluid select[class*=\"span\"],\n.row-fluid textarea[class*=\"span\"],\n.row-fluid .uneditable-input[class*=\"span\"],\n.row-fluid .input-prepend [class*=\"span\"],\n.row-fluid .input-append [class*=\"span\"] {\n  display: inline-block;\n}\n\ninput,\ntextarea,\n.uneditable-input {\n  margin-left: 0;\n}\n\n.controls-row [class*=\"span\"] + [class*=\"span\"] {\n  margin-left: 20px;\n}\n\ninput.span12,\ntextarea.span12,\n.uneditable-input.span12 {\n  width: 926px;\n}\n\ninput.span11,\ntextarea.span11,\n.uneditable-input.span11 {\n  width: 846px;\n}\n\ninput.span10,\ntextarea.span10,\n.uneditable-input.span10 {\n  width: 766px;\n}\n\ninput.span9,\ntextarea.span9,\n.uneditable-input.span9 {\n  width: 686px;\n}\n\ninput.span8,\ntextarea.span8,\n.uneditable-input.span8 {\n  width: 606px;\n}\n\ninput.span7,\ntextarea.span7,\n.uneditable-input.span7 {\n  width: 526px;\n}\n\ninput.span6,\ntextarea.span6,\n.uneditable-input.span6 {\n  width: 446px;\n}\n\ninput.span5,\ntextarea.span5,\n.uneditable-input.span5 {\n  width: 366px;\n}\n\ninput.span4,\ntextarea.span4,\n.uneditable-input.span4 {\n  width: 286px;\n}\n\ninput.span3,\ntextarea.span3,\n.uneditable-input.span3 {\n  width: 206px;\n}\n\ninput.span2,\ntextarea.span2,\n.uneditable-input.span2 {\n  width: 126px;\n}\n\ninput.span1,\ntextarea.span1,\n.uneditable-input.span1 {\n  width: 46px;\n}\n\n.controls-row {\n  *zoom: 1;\n}\n\n.controls-row:before,\n.controls-row:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.controls-row:after {\n  clear: both;\n}\n\n.controls-row [class*=\"span\"],\n.row-fluid .controls-row [class*=\"span\"] {\n  float: left;\n}\n\n.controls-row .checkbox[class*=\"span\"],\n.controls-row .radio[class*=\"span\"] {\n  padding-top: 5px;\n}\n\ninput[disabled],\nselect[disabled],\ntextarea[disabled],\ninput[readonly],\nselect[readonly],\ntextarea[readonly] {\n  cursor: not-allowed;\n  background-color: #eeeeee;\n}\n\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"][readonly],\ninput[type=\"checkbox\"][readonly] {\n  background-color: transparent;\n}\n\n.control-group.warning .control-label,\n.control-group.warning .help-block,\n.control-group.warning .help-inline {\n  color: #c09853;\n}\n\n.control-group.warning .checkbox,\n.control-group.warning .radio,\n.control-group.warning input,\n.control-group.warning select,\n.control-group.warning textarea {\n  color: #c09853;\n}\n\n.control-group.warning input,\n.control-group.warning select,\n.control-group.warning textarea {\n  border-color: #c09853;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.control-group.warning input:focus,\n.control-group.warning select:focus,\n.control-group.warning textarea:focus {\n  border-color: #a47e3c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;\n     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;\n}\n\n.control-group.warning .input-prepend .add-on,\n.control-group.warning .input-append .add-on {\n  color: #c09853;\n  background-color: #fcf8e3;\n  border-color: #c09853;\n}\n\n.control-group.error .control-label,\n.control-group.error .help-block,\n.control-group.error .help-inline {\n  color: #b94a48;\n}\n\n.control-group.error .checkbox,\n.control-group.error .radio,\n.control-group.error input,\n.control-group.error select,\n.control-group.error textarea {\n  color: #b94a48;\n}\n\n.control-group.error input,\n.control-group.error select,\n.control-group.error textarea {\n  border-color: #b94a48;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.control-group.error input:focus,\n.control-group.error select:focus,\n.control-group.error textarea:focus {\n  border-color: #953b39;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;\n     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;\n}\n\n.control-group.error .input-prepend .add-on,\n.control-group.error .input-append .add-on {\n  color: #b94a48;\n  background-color: #f2dede;\n  border-color: #b94a48;\n}\n\n.control-group.success .control-label,\n.control-group.success .help-block,\n.control-group.success .help-inline {\n  color: #468847;\n}\n\n.control-group.success .checkbox,\n.control-group.success .radio,\n.control-group.success input,\n.control-group.success select,\n.control-group.success textarea {\n  color: #468847;\n}\n\n.control-group.success input,\n.control-group.success select,\n.control-group.success textarea {\n  border-color: #468847;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.control-group.success input:focus,\n.control-group.success select:focus,\n.control-group.success textarea:focus {\n  border-color: #356635;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;\n     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;\n}\n\n.control-group.success .input-prepend .add-on,\n.control-group.success .input-append .add-on {\n  color: #468847;\n  background-color: #dff0d8;\n  border-color: #468847;\n}\n\n.control-group.info .control-label,\n.control-group.info .help-block,\n.control-group.info .help-inline {\n  color: #3a87ad;\n}\n\n.control-group.info .checkbox,\n.control-group.info .radio,\n.control-group.info input,\n.control-group.info select,\n.control-group.info textarea {\n  color: #3a87ad;\n}\n\n.control-group.info input,\n.control-group.info select,\n.control-group.info textarea {\n  border-color: #3a87ad;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.control-group.info input:focus,\n.control-group.info select:focus,\n.control-group.info textarea:focus {\n  border-color: #2d6987;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;\n     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;\n}\n\n.control-group.info .input-prepend .add-on,\n.control-group.info .input-append .add-on {\n  color: #3a87ad;\n  background-color: #d9edf7;\n  border-color: #3a87ad;\n}\n\ninput:focus:invalid,\ntextarea:focus:invalid,\nselect:focus:invalid {\n  color: #b94a48;\n  border-color: #ee5f5b;\n}\n\ninput:focus:invalid:focus,\ntextarea:focus:invalid:focus,\nselect:focus:invalid:focus {\n  border-color: #e9322d;\n  -webkit-box-shadow: 0 0 6px #f8b9b7;\n     -moz-box-shadow: 0 0 6px #f8b9b7;\n          box-shadow: 0 0 6px #f8b9b7;\n}\n\n.form-actions {\n  padding: 19px 20px 20px;\n  margin-top: 20px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #e5e5e5;\n  *zoom: 1;\n}\n\n.form-actions:before,\n.form-actions:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.form-actions:after {\n  clear: both;\n}\n\n.help-block,\n.help-inline {\n  color: #595959;\n}\n\n.help-block {\n  display: block;\n  margin-bottom: 10px;\n}\n\n.help-inline {\n  display: inline-block;\n  *display: inline;\n  padding-left: 5px;\n  vertical-align: middle;\n  *zoom: 1;\n}\n\n.input-append,\n.input-prepend {\n  display: inline-block;\n  margin-bottom: 10px;\n  font-size: 0;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n\n.input-append input,\n.input-prepend input,\n.input-append select,\n.input-prepend select,\n.input-append .uneditable-input,\n.input-prepend .uneditable-input,\n.input-append .dropdown-menu,\n.input-prepend .dropdown-menu,\n.input-append .popover,\n.input-prepend .popover {\n  font-size: 14px;\n}\n\n.input-append input,\n.input-prepend input,\n.input-append select,\n.input-prepend select,\n.input-append .uneditable-input,\n.input-prepend .uneditable-input {\n  position: relative;\n  margin-bottom: 0;\n  *margin-left: 0;\n  vertical-align: top;\n  -webkit-border-radius: 0 4px 4px 0;\n     -moz-border-radius: 0 4px 4px 0;\n          border-radius: 0 4px 4px 0;\n}\n\n.input-append input:focus,\n.input-prepend input:focus,\n.input-append select:focus,\n.input-prepend select:focus,\n.input-append .uneditable-input:focus,\n.input-prepend .uneditable-input:focus {\n  z-index: 2;\n}\n\n.input-append .add-on,\n.input-prepend .add-on {\n  display: inline-block;\n  width: auto;\n  height: 20px;\n  min-width: 16px;\n  padding: 4px 5px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  text-align: center;\n  text-shadow: 0 1px 0 #ffffff;\n  background-color: #eeeeee;\n  border: 1px solid #ccc;\n}\n\n.input-append .add-on,\n.input-prepend .add-on,\n.input-append .btn,\n.input-prepend .btn,\n.input-append .btn-group > .dropdown-toggle,\n.input-prepend .btn-group > .dropdown-toggle {\n  vertical-align: top;\n  -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n          border-radius: 0;\n}\n\n.input-append .active,\n.input-prepend .active {\n  background-color: #a9dba9;\n  border-color: #46a546;\n}\n\n.input-prepend .add-on,\n.input-prepend .btn {\n  margin-right: -1px;\n}\n\n.input-prepend .add-on:first-child,\n.input-prepend .btn:first-child {\n  -webkit-border-radius: 4px 0 0 4px;\n     -moz-border-radius: 4px 0 0 4px;\n          border-radius: 4px 0 0 4px;\n}\n\n.input-append input,\n.input-append select,\n.input-append .uneditable-input {\n  -webkit-border-radius: 4px 0 0 4px;\n     -moz-border-radius: 4px 0 0 4px;\n          border-radius: 4px 0 0 4px;\n}\n\n.input-append input + .btn-group .btn:last-child,\n.input-append select + .btn-group .btn:last-child,\n.input-append .uneditable-input + .btn-group .btn:last-child {\n  -webkit-border-radius: 0 4px 4px 0;\n     -moz-border-radius: 0 4px 4px 0;\n          border-radius: 0 4px 4px 0;\n}\n\n.input-append .add-on,\n.input-append .btn,\n.input-append .btn-group {\n  margin-left: -1px;\n}\n\n.input-append .add-on:last-child,\n.input-append .btn:last-child,\n.input-append .btn-group:last-child > .dropdown-toggle {\n  -webkit-border-radius: 0 4px 4px 0;\n     -moz-border-radius: 0 4px 4px 0;\n          border-radius: 0 4px 4px 0;\n}\n\n.input-prepend.input-append input,\n.input-prepend.input-append select,\n.input-prepend.input-append .uneditable-input {\n  -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n          border-radius: 0;\n}\n\n.input-prepend.input-append input + .btn-group .btn,\n.input-prepend.input-append select + .btn-group .btn,\n.input-prepend.input-append .uneditable-input + .btn-group .btn {\n  -webkit-border-radius: 0 4px 4px 0;\n     -moz-border-radius: 0 4px 4px 0;\n          border-radius: 0 4px 4px 0;\n}\n\n.input-prepend.input-append .add-on:first-child,\n.input-prepend.input-append .btn:first-child {\n  margin-right: -1px;\n  -webkit-border-radius: 4px 0 0 4px;\n     -moz-border-radius: 4px 0 0 4px;\n          border-radius: 4px 0 0 4px;\n}\n\n.input-prepend.input-append .add-on:last-child,\n.input-prepend.input-append .btn:last-child {\n  margin-left: -1px;\n  -webkit-border-radius: 0 4px 4px 0;\n     -moz-border-radius: 0 4px 4px 0;\n          border-radius: 0 4px 4px 0;\n}\n\n.input-prepend.input-append .btn-group:first-child {\n  margin-left: 0;\n}\n\ninput.search-query {\n  padding-right: 14px;\n  padding-right: 4px \\9;\n  padding-left: 14px;\n  padding-left: 4px \\9;\n  /* IE7-8 doesn't have border-radius, so don't indent the padding */\n\n  margin-bottom: 0;\n  -webkit-border-radius: 15px;\n     -moz-border-radius: 15px;\n          border-radius: 15px;\n}\n\n/* Allow for input prepend/append in search forms */\n\n.form-search .input-append .search-query,\n.form-search .input-prepend .search-query {\n  -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n          border-radius: 0;\n}\n\n.form-search .input-append .search-query {\n  -webkit-border-radius: 14px 0 0 14px;\n     -moz-border-radius: 14px 0 0 14px;\n          border-radius: 14px 0 0 14px;\n}\n\n.form-search .input-append .btn {\n  -webkit-border-radius: 0 14px 14px 0;\n     -moz-border-radius: 0 14px 14px 0;\n          border-radius: 0 14px 14px 0;\n}\n\n.form-search .input-prepend .search-query {\n  -webkit-border-radius: 0 14px 14px 0;\n     -moz-border-radius: 0 14px 14px 0;\n          border-radius: 0 14px 14px 0;\n}\n\n.form-search .input-prepend .btn {\n  -webkit-border-radius: 14px 0 0 14px;\n     -moz-border-radius: 14px 0 0 14px;\n          border-radius: 14px 0 0 14px;\n}\n\n.form-search input,\n.form-inline input,\n.form-horizontal input,\n.form-search textarea,\n.form-inline textarea,\n.form-horizontal textarea,\n.form-search select,\n.form-inline select,\n.form-horizontal select,\n.form-search .help-inline,\n.form-inline .help-inline,\n.form-horizontal .help-inline,\n.form-search .uneditable-input,\n.form-inline .uneditable-input,\n.form-horizontal .uneditable-input,\n.form-search .input-prepend,\n.form-inline .input-prepend,\n.form-horizontal .input-prepend,\n.form-search .input-append,\n.form-inline .input-append,\n.form-horizontal .input-append {\n  display: inline-block;\n  *display: inline;\n  margin-bottom: 0;\n  vertical-align: middle;\n  *zoom: 1;\n}\n\n.form-search .hide,\n.form-inline .hide,\n.form-horizontal .hide {\n  display: none;\n}\n\n.form-search label,\n.form-inline label,\n.form-search .btn-group,\n.form-inline .btn-group {\n  display: inline-block;\n}\n\n.form-search .input-append,\n.form-inline .input-append,\n.form-search .input-prepend,\n.form-inline .input-prepend {\n  margin-bottom: 0;\n}\n\n.form-search .radio,\n.form-search .checkbox,\n.form-inline .radio,\n.form-inline .checkbox {\n  padding-left: 0;\n  margin-bottom: 0;\n  vertical-align: middle;\n}\n\n.form-search .radio input[type=\"radio\"],\n.form-search .checkbox input[type=\"checkbox\"],\n.form-inline .radio input[type=\"radio\"],\n.form-inline .checkbox input[type=\"checkbox\"] {\n  float: left;\n  margin-right: 3px;\n  margin-left: 0;\n}\n\n.control-group {\n  margin-bottom: 10px;\n}\n\nlegend + .control-group {\n  margin-top: 20px;\n  -webkit-margin-top-collapse: separate;\n}\n\n.form-horizontal .control-group {\n  margin-bottom: 20px;\n  *zoom: 1;\n}\n\n.form-horizontal .control-group:before,\n.form-horizontal .control-group:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.form-horizontal .control-group:after {\n  clear: both;\n}\n\n.form-horizontal .control-label {\n  float: left;\n  width: 160px;\n  padding-top: 5px;\n  text-align: right;\n}\n\n.form-horizontal .controls {\n  *display: inline-block;\n  *padding-left: 20px;\n  margin-left: 180px;\n  *margin-left: 0;\n}\n\n.form-horizontal .controls:first-child {\n  *padding-left: 180px;\n}\n\n.form-horizontal .help-block {\n  margin-bottom: 0;\n}\n\n.form-horizontal input + .help-block,\n.form-horizontal select + .help-block,\n.form-horizontal textarea + .help-block,\n.form-horizontal .uneditable-input + .help-block,\n.form-horizontal .input-prepend + .help-block,\n.form-horizontal .input-append + .help-block {\n  margin-top: 10px;\n}\n\n.form-horizontal .form-actions {\n  padding-left: 180px;\n}\n\ntable {\n  max-width: 100%;\n  background-color: transparent;\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\n.table {\n  width: 100%;\n  margin-bottom: 20px;\n}\n\n.table th,\n.table td {\n  padding: 8px;\n  line-height: 20px;\n  text-align: left;\n  vertical-align: top;\n  border-top: 1px solid #dddddd;\n}\n\n.table th {\n  font-weight: bold;\n}\n\n.table thead th {\n  vertical-align: bottom;\n}\n\n.table caption + thead tr:first-child th,\n.table caption + thead tr:first-child td,\n.table colgroup + thead tr:first-child th,\n.table colgroup + thead tr:first-child td,\n.table thead:first-child tr:first-child th,\n.table thead:first-child tr:first-child td {\n  border-top: 0;\n}\n\n.table tbody + tbody {\n  border-top: 2px solid #dddddd;\n}\n\n.table .table {\n  background-color: #ffffff;\n}\n\n.table-condensed th,\n.table-condensed td {\n  padding: 4px 5px;\n}\n\n.table-bordered {\n  border: 1px solid #dddddd;\n  border-collapse: separate;\n  *border-collapse: collapse;\n  border-left: 0;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n}\n\n.table-bordered th,\n.table-bordered td {\n  border-left: 1px solid #dddddd;\n}\n\n.table-bordered caption + thead tr:first-child th,\n.table-bordered caption + tbody tr:first-child th,\n.table-bordered caption + tbody tr:first-child td,\n.table-bordered colgroup + thead tr:first-child th,\n.table-bordered colgroup + tbody tr:first-child th,\n.table-bordered colgroup + tbody tr:first-child td,\n.table-bordered thead:first-child tr:first-child th,\n.table-bordered tbody:first-child tr:first-child th,\n.table-bordered tbody:first-child tr:first-child td {\n  border-top: 0;\n}\n\n.table-bordered thead:first-child tr:first-child > th:first-child,\n.table-bordered tbody:first-child tr:first-child > td:first-child,\n.table-bordered tbody:first-child tr:first-child > th:first-child {\n  -webkit-border-top-left-radius: 4px;\n          border-top-left-radius: 4px;\n  -moz-border-radius-topleft: 4px;\n}\n\n.table-bordered thead:first-child tr:first-child > th:last-child,\n.table-bordered tbody:first-child tr:first-child > td:last-child,\n.table-bordered tbody:first-child tr:first-child > th:last-child {\n  -webkit-border-top-right-radius: 4px;\n          border-top-right-radius: 4px;\n  -moz-border-radius-topright: 4px;\n}\n\n.table-bordered thead:last-child tr:last-child > th:first-child,\n.table-bordered tbody:last-child tr:last-child > td:first-child,\n.table-bordered tbody:last-child tr:last-child > th:first-child,\n.table-bordered tfoot:last-child tr:last-child > td:first-child,\n.table-bordered tfoot:last-child tr:last-child > th:first-child {\n  -webkit-border-bottom-left-radius: 4px;\n          border-bottom-left-radius: 4px;\n  -moz-border-radius-bottomleft: 4px;\n}\n\n.table-bordered thead:last-child tr:last-child > th:last-child,\n.table-bordered tbody:last-child tr:last-child > td:last-child,\n.table-bordered tbody:last-child tr:last-child > th:last-child,\n.table-bordered tfoot:last-child tr:last-child > td:last-child,\n.table-bordered tfoot:last-child tr:last-child > th:last-child {\n  -webkit-border-bottom-right-radius: 4px;\n          border-bottom-right-radius: 4px;\n  -moz-border-radius-bottomright: 4px;\n}\n\n.table-bordered tfoot + tbody:last-child tr:last-child td:first-child {\n  -webkit-border-bottom-left-radius: 0;\n          border-bottom-left-radius: 0;\n  -moz-border-radius-bottomleft: 0;\n}\n\n.table-bordered tfoot + tbody:last-child tr:last-child td:last-child {\n  -webkit-border-bottom-right-radius: 0;\n          border-bottom-right-radius: 0;\n  -moz-border-radius-bottomright: 0;\n}\n\n.table-bordered caption + thead tr:first-child th:first-child,\n.table-bordered caption + tbody tr:first-child td:first-child,\n.table-bordered colgroup + thead tr:first-child th:first-child,\n.table-bordered colgroup + tbody tr:first-child td:first-child {\n  -webkit-border-top-left-radius: 4px;\n          border-top-left-radius: 4px;\n  -moz-border-radius-topleft: 4px;\n}\n\n.table-bordered caption + thead tr:first-child th:last-child,\n.table-bordered caption + tbody tr:first-child td:last-child,\n.table-bordered colgroup + thead tr:first-child th:last-child,\n.table-bordered colgroup + tbody tr:first-child td:last-child {\n  -webkit-border-top-right-radius: 4px;\n          border-top-right-radius: 4px;\n  -moz-border-radius-topright: 4px;\n}\n\n.table-striped tbody > tr:nth-child(odd) > td,\n.table-striped tbody > tr:nth-child(odd) > th {\n  background-color: #f9f9f9;\n}\n\n.table-hover tbody tr:hover > td,\n.table-hover tbody tr:hover > th {\n  background-color: #f5f5f5;\n}\n\ntable td[class*=\"span\"],\ntable th[class*=\"span\"],\n.row-fluid table td[class*=\"span\"],\n.row-fluid table th[class*=\"span\"] {\n  display: table-cell;\n  float: none;\n  margin-left: 0;\n}\n\n.table td.span1,\n.table th.span1 {\n  float: none;\n  width: 44px;\n  margin-left: 0;\n}\n\n.table td.span2,\n.table th.span2 {\n  float: none;\n  width: 124px;\n  margin-left: 0;\n}\n\n.table td.span3,\n.table th.span3 {\n  float: none;\n  width: 204px;\n  margin-left: 0;\n}\n\n.table td.span4,\n.table th.span4 {\n  float: none;\n  width: 284px;\n  margin-left: 0;\n}\n\n.table td.span5,\n.table th.span5 {\n  float: none;\n  width: 364px;\n  margin-left: 0;\n}\n\n.table td.span6,\n.table th.span6 {\n  float: none;\n  width: 444px;\n  margin-left: 0;\n}\n\n.table td.span7,\n.table th.span7 {\n  float: none;\n  width: 524px;\n  margin-left: 0;\n}\n\n.table td.span8,\n.table th.span8 {\n  float: none;\n  width: 604px;\n  margin-left: 0;\n}\n\n.table td.span9,\n.table th.span9 {\n  float: none;\n  width: 684px;\n  margin-left: 0;\n}\n\n.table td.span10,\n.table th.span10 {\n  float: none;\n  width: 764px;\n  margin-left: 0;\n}\n\n.table td.span11,\n.table th.span11 {\n  float: none;\n  width: 844px;\n  margin-left: 0;\n}\n\n.table td.span12,\n.table th.span12 {\n  float: none;\n  width: 924px;\n  margin-left: 0;\n}\n\n.table tbody tr.success > td {\n  background-color: #dff0d8;\n}\n\n.table tbody tr.error > td {\n  background-color: #f2dede;\n}\n\n.table tbody tr.warning > td {\n  background-color: #fcf8e3;\n}\n\n.table tbody tr.info > td {\n  background-color: #d9edf7;\n}\n\n.table-hover tbody tr.success:hover > td {\n  background-color: #d0e9c6;\n}\n\n.table-hover tbody tr.error:hover > td {\n  background-color: #ebcccc;\n}\n\n.table-hover tbody tr.warning:hover > td {\n  background-color: #faf2cc;\n}\n\n.table-hover tbody tr.info:hover > td {\n  background-color: #c4e3f3;\n}\n\n[class^=\"icon-\"],\n[class*=\" icon-\"] {\n  display: inline-block;\n  width: 14px;\n  height: 14px;\n  margin-top: 1px;\n  *margin-right: .3em;\n  line-height: 14px;\n  vertical-align: text-top;\n  background-image: url(\"../../img/glyphicons-halflings.png\");\n  background-position: 14px 14px;\n  background-repeat: no-repeat;\n}\n\n/* White icons with optional class, or on hover/focus/active states of certain elements */\n\n.icon-white,\n.nav-pills > .active > a > [class^=\"icon-\"],\n.nav-pills > .active > a > [class*=\" icon-\"],\n.nav-list > .active > a > [class^=\"icon-\"],\n.nav-list > .active > a > [class*=\" icon-\"],\n.navbar-inverse .nav > .active > a > [class^=\"icon-\"],\n.navbar-inverse .nav > .active > a > [class*=\" icon-\"],\n.dropdown-menu > li > a:hover > [class^=\"icon-\"],\n.dropdown-menu > li > a:focus > [class^=\"icon-\"],\n.dropdown-menu > li > a:hover > [class*=\" icon-\"],\n.dropdown-menu > li > a:focus > [class*=\" icon-\"],\n.dropdown-menu > .active > a > [class^=\"icon-\"],\n.dropdown-menu > .active > a > [class*=\" icon-\"],\n.dropdown-submenu:hover > a > [class^=\"icon-\"],\n.dropdown-submenu:focus > a > [class^=\"icon-\"],\n.dropdown-submenu:hover > a > [class*=\" icon-\"],\n.dropdown-submenu:focus > a > [class*=\" icon-\"] {\n  background-image: url(\"../../img/glyphicons-halflings-white.png\");\n}\n\n.icon-glass {\n  background-position: 0      0;\n}\n\n.icon-music {\n  background-position: -24px 0;\n}\n\n.icon-search {\n  background-position: -48px 0;\n}\n\n.icon-envelope {\n  background-position: -72px 0;\n}\n\n.icon-heart {\n  background-position: -96px 0;\n}\n\n.icon-star {\n  background-position: -120px 0;\n}\n\n.icon-star-empty {\n  background-position: -144px 0;\n}\n\n.icon-user {\n  background-position: -168px 0;\n}\n\n.icon-film {\n  background-position: -192px 0;\n}\n\n.icon-th-large {\n  background-position: -216px 0;\n}\n\n.icon-th {\n  background-position: -240px 0;\n}\n\n.icon-th-list {\n  background-position: -264px 0;\n}\n\n.icon-ok {\n  background-position: -288px 0;\n}\n\n.icon-remove {\n  background-position: -312px 0;\n}\n\n.icon-zoom-in {\n  background-position: -336px 0;\n}\n\n.icon-zoom-out {\n  background-position: -360px 0;\n}\n\n.icon-off {\n  background-position: -384px 0;\n}\n\n.icon-signal {\n  background-position: -408px 0;\n}\n\n.icon-cog {\n  background-position: -432px 0;\n}\n\n.icon-trash {\n  background-position: -456px 0;\n}\n\n.icon-home {\n  background-position: 0 -24px;\n}\n\n.icon-file {\n  background-position: -24px -24px;\n}\n\n.icon-time {\n  background-position: -48px -24px;\n}\n\n.icon-road {\n  background-position: -72px -24px;\n}\n\n.icon-download-alt {\n  background-position: -96px -24px;\n}\n\n.icon-download {\n  background-position: -120px -24px;\n}\n\n.icon-upload {\n  background-position: -144px -24px;\n}\n\n.icon-inbox {\n  background-position: -168px -24px;\n}\n\n.icon-play-circle {\n  background-position: -192px -24px;\n}\n\n.icon-repeat {\n  background-position: -216px -24px;\n}\n\n.icon-refresh {\n  background-position: -240px -24px;\n}\n\n.icon-list-alt {\n  background-position: -264px -24px;\n}\n\n.icon-lock {\n  background-position: -287px -24px;\n}\n\n.icon-flag {\n  background-position: -312px -24px;\n}\n\n.icon-headphones {\n  background-position: -336px -24px;\n}\n\n.icon-volume-off {\n  background-position: -360px -24px;\n}\n\n.icon-volume-down {\n  background-position: -384px -24px;\n}\n\n.icon-volume-up {\n  background-position: -408px -24px;\n}\n\n.icon-qrcode {\n  background-position: -432px -24px;\n}\n\n.icon-barcode {\n  background-position: -456px -24px;\n}\n\n.icon-tag {\n  background-position: 0 -48px;\n}\n\n.icon-tags {\n  background-position: -25px -48px;\n}\n\n.icon-book {\n  background-position: -48px -48px;\n}\n\n.icon-bookmark {\n  background-position: -72px -48px;\n}\n\n.icon-print {\n  background-position: -96px -48px;\n}\n\n.icon-camera {\n  background-position: -120px -48px;\n}\n\n.icon-font {\n  background-position: -144px -48px;\n}\n\n.icon-bold {\n  background-position: -167px -48px;\n}\n\n.icon-italic {\n  background-position: -192px -48px;\n}\n\n.icon-text-height {\n  background-position: -216px -48px;\n}\n\n.icon-text-width {\n  background-position: -240px -48px;\n}\n\n.icon-align-left {\n  background-position: -264px -48px;\n}\n\n.icon-align-center {\n  background-position: -288px -48px;\n}\n\n.icon-align-right {\n  background-position: -312px -48px;\n}\n\n.icon-align-justify {\n  background-position: -336px -48px;\n}\n\n.icon-list {\n  background-position: -360px -48px;\n}\n\n.icon-indent-left {\n  background-position: -384px -48px;\n}\n\n.icon-indent-right {\n  background-position: -408px -48px;\n}\n\n.icon-facetime-video {\n  background-position: -432px -48px;\n}\n\n.icon-picture {\n  background-position: -456px -48px;\n}\n\n.icon-pencil {\n  background-position: 0 -72px;\n}\n\n.icon-map-marker {\n  background-position: -24px -72px;\n}\n\n.icon-adjust {\n  background-position: -48px -72px;\n}\n\n.icon-tint {\n  background-position: -72px -72px;\n}\n\n.icon-edit {\n  background-position: -96px -72px;\n}\n\n.icon-share {\n  background-position: -120px -72px;\n}\n\n.icon-check {\n  background-position: -144px -72px;\n}\n\n.icon-move {\n  background-position: -168px -72px;\n}\n\n.icon-step-backward {\n  background-position: -192px -72px;\n}\n\n.icon-fast-backward {\n  background-position: -216px -72px;\n}\n\n.icon-backward {\n  background-position: -240px -72px;\n}\n\n.icon-play {\n  background-position: -264px -72px;\n}\n\n.icon-pause {\n  background-position: -288px -72px;\n}\n\n.icon-stop {\n  background-position: -312px -72px;\n}\n\n.icon-forward {\n  background-position: -336px -72px;\n}\n\n.icon-fast-forward {\n  background-position: -360px -72px;\n}\n\n.icon-step-forward {\n  background-position: -384px -72px;\n}\n\n.icon-eject {\n  background-position: -408px -72px;\n}\n\n.icon-chevron-left {\n  background-position: -432px -72px;\n}\n\n.icon-chevron-right {\n  background-position: -456px -72px;\n}\n\n.icon-plus-sign {\n  background-position: 0 -96px;\n}\n\n.icon-minus-sign {\n  background-position: -24px -96px;\n}\n\n.icon-remove-sign {\n  background-position: -48px -96px;\n}\n\n.icon-ok-sign {\n  background-position: -72px -96px;\n}\n\n.icon-question-sign {\n  background-position: -96px -96px;\n}\n\n.icon-info-sign {\n  background-position: -120px -96px;\n}\n\n.icon-screenshot {\n  background-position: -144px -96px;\n}\n\n.icon-remove-circle {\n  background-position: -168px -96px;\n}\n\n.icon-ok-circle {\n  background-position: -192px -96px;\n}\n\n.icon-ban-circle {\n  background-position: -216px -96px;\n}\n\n.icon-arrow-left {\n  background-position: -240px -96px;\n}\n\n.icon-arrow-right {\n  background-position: -264px -96px;\n}\n\n.icon-arrow-up {\n  background-position: -289px -96px;\n}\n\n.icon-arrow-down {\n  background-position: -312px -96px;\n}\n\n.icon-share-alt {\n  background-position: -336px -96px;\n}\n\n.icon-resize-full {\n  background-position: -360px -96px;\n}\n\n.icon-resize-small {\n  background-position: -384px -96px;\n}\n\n.icon-plus {\n  background-position: -408px -96px;\n}\n\n.icon-minus {\n  background-position: -433px -96px;\n}\n\n.icon-asterisk {\n  background-position: -456px -96px;\n}\n\n.icon-exclamation-sign {\n  background-position: 0 -120px;\n}\n\n.icon-gift {\n  background-position: -24px -120px;\n}\n\n.icon-leaf {\n  background-position: -48px -120px;\n}\n\n.icon-fire {\n  background-position: -72px -120px;\n}\n\n.icon-eye-open {\n  background-position: -96px -120px;\n}\n\n.icon-eye-close {\n  background-position: -120px -120px;\n}\n\n.icon-warning-sign {\n  background-position: -144px -120px;\n}\n\n.icon-plane {\n  background-position: -168px -120px;\n}\n\n.icon-calendar {\n  background-position: -192px -120px;\n}\n\n.icon-random {\n  width: 16px;\n  background-position: -216px -120px;\n}\n\n.icon-comment {\n  background-position: -240px -120px;\n}\n\n.icon-magnet {\n  background-position: -264px -120px;\n}\n\n.icon-chevron-up {\n  background-position: -288px -120px;\n}\n\n.icon-chevron-down {\n  background-position: -313px -119px;\n}\n\n.icon-retweet {\n  background-position: -336px -120px;\n}\n\n.icon-shopping-cart {\n  background-position: -360px -120px;\n}\n\n.icon-folder-close {\n  width: 16px;\n  background-position: -384px -120px;\n}\n\n.icon-folder-open {\n  width: 16px;\n  background-position: -408px -120px;\n}\n\n.icon-resize-vertical {\n  background-position: -432px -119px;\n}\n\n.icon-resize-horizontal {\n  background-position: -456px -118px;\n}\n\n.icon-hdd {\n  background-position: 0 -144px;\n}\n\n.icon-bullhorn {\n  background-position: -24px -144px;\n}\n\n.icon-bell {\n  background-position: -48px -144px;\n}\n\n.icon-certificate {\n  background-position: -72px -144px;\n}\n\n.icon-thumbs-up {\n  background-position: -96px -144px;\n}\n\n.icon-thumbs-down {\n  background-position: -120px -144px;\n}\n\n.icon-hand-right {\n  background-position: -144px -144px;\n}\n\n.icon-hand-left {\n  background-position: -168px -144px;\n}\n\n.icon-hand-up {\n  background-position: -192px -144px;\n}\n\n.icon-hand-down {\n  background-position: -216px -144px;\n}\n\n.icon-circle-arrow-right {\n  background-position: -240px -144px;\n}\n\n.icon-circle-arrow-left {\n  background-position: -264px -144px;\n}\n\n.icon-circle-arrow-up {\n  background-position: -288px -144px;\n}\n\n.icon-circle-arrow-down {\n  background-position: -312px -144px;\n}\n\n.icon-globe {\n  background-position: -336px -144px;\n}\n\n.icon-wrench {\n  background-position: -360px -144px;\n}\n\n.icon-tasks {\n  background-position: -384px -144px;\n}\n\n.icon-filter {\n  background-position: -408px -144px;\n}\n\n.icon-briefcase {\n  background-position: -432px -144px;\n}\n\n.icon-fullscreen {\n  background-position: -456px -144px;\n}\n\n.dropup,\n.dropdown {\n  position: relative;\n}\n\n.dropdown-toggle {\n  *margin-bottom: -3px;\n}\n\n.dropdown-toggle:active,\n.open .dropdown-toggle {\n  outline: 0;\n}\n\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  vertical-align: top;\n  border-top: 4px solid #000000;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n  content: \"\";\n}\n\n.dropdown .caret {\n  margin-top: 8px;\n  margin-left: 2px;\n}\n\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  list-style: none;\n  background-color: #ffffff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  *border-right-width: 2px;\n  *border-bottom-width: 2px;\n  -webkit-border-radius: 6px;\n     -moz-border-radius: 6px;\n          border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n     -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  -webkit-background-clip: padding-box;\n     -moz-background-clip: padding;\n          background-clip: padding-box;\n}\n\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n\n.dropdown-menu .divider {\n  *width: 100%;\n  height: 1px;\n  margin: 9px 1px;\n  *margin: -5px 0 5px;\n  overflow: hidden;\n  background-color: #e5e5e5;\n  border-bottom: 1px solid #ffffff;\n}\n\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 20px;\n  color: #333333;\n  white-space: nowrap;\n}\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus,\n.dropdown-submenu:hover > a,\n.dropdown-submenu:focus > a {\n  color: #ffffff;\n  text-decoration: none;\n  background-color: #0081c2;\n  background-image: -moz-linear-gradient(top, #0088cc, #0077b3);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));\n  background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);\n  background-image: -o-linear-gradient(top, #0088cc, #0077b3);\n  background-image: linear-gradient(to bottom, #0088cc, #0077b3);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);\n}\n\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #ffffff;\n  text-decoration: none;\n  background-color: #0081c2;\n  background-image: -moz-linear-gradient(top, #0088cc, #0077b3);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));\n  background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);\n  background-image: -o-linear-gradient(top, #0088cc, #0077b3);\n  background-image: linear-gradient(to bottom, #0088cc, #0077b3);\n  background-repeat: repeat-x;\n  outline: 0;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);\n}\n\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #999999;\n}\n\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  cursor: default;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.open {\n  *z-index: 1000;\n}\n\n.open > .dropdown-menu {\n  display: block;\n}\n\n.dropdown-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 990;\n}\n\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  border-top: 0;\n  border-bottom: 4px solid #000000;\n  content: \"\";\n}\n\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 1px;\n}\n\n.dropdown-submenu {\n  position: relative;\n}\n\n.dropdown-submenu > .dropdown-menu {\n  top: 0;\n  left: 100%;\n  margin-top: -6px;\n  margin-left: -1px;\n  -webkit-border-radius: 0 6px 6px 6px;\n     -moz-border-radius: 0 6px 6px 6px;\n          border-radius: 0 6px 6px 6px;\n}\n\n.dropdown-submenu:hover > .dropdown-menu {\n  display: block;\n}\n\n.dropup .dropdown-submenu > .dropdown-menu {\n  top: auto;\n  bottom: 0;\n  margin-top: 0;\n  margin-bottom: -2px;\n  -webkit-border-radius: 5px 5px 5px 0;\n     -moz-border-radius: 5px 5px 5px 0;\n          border-radius: 5px 5px 5px 0;\n}\n\n.dropdown-submenu > a:after {\n  display: block;\n  float: right;\n  width: 0;\n  height: 0;\n  margin-top: 5px;\n  margin-right: -10px;\n  border-color: transparent;\n  border-left-color: #cccccc;\n  border-style: solid;\n  border-width: 5px 0 5px 5px;\n  content: \" \";\n}\n\n.dropdown-submenu:hover > a:after {\n  border-left-color: #ffffff;\n}\n\n.dropdown-submenu.pull-left {\n  float: none;\n}\n\n.dropdown-submenu.pull-left > .dropdown-menu {\n  left: -100%;\n  margin-left: 10px;\n  -webkit-border-radius: 6px 0 6px 6px;\n     -moz-border-radius: 6px 0 6px 6px;\n          border-radius: 6px 0 6px 6px;\n}\n\n.dropdown .dropdown-menu .nav-header {\n  padding-right: 20px;\n  padding-left: 20px;\n}\n\n.typeahead {\n  z-index: 1051;\n  margin-top: 2px;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n}\n\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, 0.15);\n}\n\n.well-large {\n  padding: 24px;\n  -webkit-border-radius: 6px;\n     -moz-border-radius: 6px;\n          border-radius: 6px;\n}\n\n.well-small {\n  padding: 9px;\n  -webkit-border-radius: 3px;\n     -moz-border-radius: 3px;\n          border-radius: 3px;\n}\n\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity 0.15s linear;\n     -moz-transition: opacity 0.15s linear;\n       -o-transition: opacity 0.15s linear;\n          transition: opacity 0.15s linear;\n}\n\n.fade.in {\n  opacity: 1;\n}\n\n.collapse {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition: height 0.35s ease;\n     -moz-transition: height 0.35s ease;\n       -o-transition: height 0.35s ease;\n          transition: height 0.35s ease;\n}\n\n.collapse.in {\n  height: auto;\n}\n\n.close {\n  float: right;\n  font-size: 20px;\n  font-weight: bold;\n  line-height: 20px;\n  color: #000000;\n  text-shadow: 0 1px 0 #ffffff;\n  opacity: 0.2;\n  filter: alpha(opacity=20);\n}\n\n.close:hover,\n.close:focus {\n  color: #000000;\n  text-decoration: none;\n  cursor: pointer;\n  opacity: 0.4;\n  filter: alpha(opacity=40);\n}\n\nbutton.close {\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n  -webkit-appearance: none;\n}\n\n.btn {\n  display: inline-block;\n  *display: inline;\n  padding: 4px 12px;\n  margin-bottom: 0;\n  *margin-left: .3em;\n  font-size: 14px;\n  line-height: 20px;\n  color: #333333;\n  text-align: center;\n  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);\n  vertical-align: middle;\n  cursor: pointer;\n  background-color: #f5f5f5;\n  *background-color: #e6e6e6;\n  background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));\n  background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);\n  background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);\n  background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);\n  background-repeat: repeat-x;\n  border: 1px solid #cccccc;\n  *border: 0;\n  border-color: #e6e6e6 #e6e6e6 #bfbfbf;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  border-bottom-color: #b3b3b3;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  *zoom: 1;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);\n     -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.btn:hover,\n.btn:focus,\n.btn:active,\n.btn.active,\n.btn.disabled,\n.btn[disabled] {\n  color: #333333;\n  background-color: #e6e6e6;\n  *background-color: #d9d9d9;\n}\n\n.btn:active,\n.btn.active {\n  background-color: #cccccc \\9;\n}\n\n.btn:first-child {\n  *margin-left: 0;\n}\n\n.btn:hover,\n.btn:focus {\n  color: #333333;\n  text-decoration: none;\n  background-position: 0 -15px;\n  -webkit-transition: background-position 0.1s linear;\n     -moz-transition: background-position 0.1s linear;\n       -o-transition: background-position 0.1s linear;\n          transition: background-position 0.1s linear;\n}\n\n.btn:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\n.btn.active,\n.btn:active {\n  background-image: none;\n  outline: 0;\n  -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);\n     -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.btn.disabled,\n.btn[disabled] {\n  cursor: default;\n  background-image: none;\n  opacity: 0.65;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n     -moz-box-shadow: none;\n          box-shadow: none;\n}\n\n.btn-large {\n  padding: 11px 19px;\n  font-size: 17.5px;\n  -webkit-border-radius: 6px;\n     -moz-border-radius: 6px;\n          border-radius: 6px;\n}\n\n.btn-large [class^=\"icon-\"],\n.btn-large [class*=\" icon-\"] {\n  margin-top: 4px;\n}\n\n.btn-small {\n  padding: 2px 10px;\n  font-size: 11.9px;\n  -webkit-border-radius: 3px;\n     -moz-border-radius: 3px;\n          border-radius: 3px;\n}\n\n.btn-small [class^=\"icon-\"],\n.btn-small [class*=\" icon-\"] {\n  margin-top: 0;\n}\n\n.btn-mini [class^=\"icon-\"],\n.btn-mini [class*=\" icon-\"] {\n  margin-top: -1px;\n}\n\n.btn-mini {\n  padding: 0 6px;\n  font-size: 10.5px;\n  -webkit-border-radius: 3px;\n     -moz-border-radius: 3px;\n          border-radius: 3px;\n}\n\n.btn-block {\n  display: block;\n  width: 100%;\n  padding-right: 0;\n  padding-left: 0;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n\n.btn-primary.active,\n.btn-warning.active,\n.btn-danger.active,\n.btn-success.active,\n.btn-info.active,\n.btn-inverse.active {\n  color: rgba(255, 255, 255, 0.75);\n}\n\n.btn-primary {\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #006dcc;\n  *background-color: #0044cc;\n  background-image: -moz-linear-gradient(top, #0088cc, #0044cc);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));\n  background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);\n  background-image: -o-linear-gradient(top, #0088cc, #0044cc);\n  background-image: linear-gradient(to bottom, #0088cc, #0044cc);\n  background-repeat: repeat-x;\n  border-color: #0044cc #0044cc #002a80;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-primary:hover,\n.btn-primary:focus,\n.btn-primary:active,\n.btn-primary.active,\n.btn-primary.disabled,\n.btn-primary[disabled] {\n  color: #ffffff;\n  background-color: #0044cc;\n  *background-color: #003bb3;\n}\n\n.btn-primary:active,\n.btn-primary.active {\n  background-color: #003399 \\9;\n}\n\n.btn-warning {\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #faa732;\n  *background-color: #f89406;\n  background-image: -moz-linear-gradient(top, #fbb450, #f89406);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));\n  background-image: -webkit-linear-gradient(top, #fbb450, #f89406);\n  background-image: -o-linear-gradient(top, #fbb450, #f89406);\n  background-image: linear-gradient(to bottom, #fbb450, #f89406);\n  background-repeat: repeat-x;\n  border-color: #f89406 #f89406 #ad6704;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-warning:hover,\n.btn-warning:focus,\n.btn-warning:active,\n.btn-warning.active,\n.btn-warning.disabled,\n.btn-warning[disabled] {\n  color: #ffffff;\n  background-color: #f89406;\n  *background-color: #df8505;\n}\n\n.btn-warning:active,\n.btn-warning.active {\n  background-color: #c67605 \\9;\n}\n\n.btn-danger {\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #da4f49;\n  *background-color: #bd362f;\n  background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));\n  background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f);\n  background-image: -o-linear-gradient(top, #ee5f5b, #bd362f);\n  background-image: linear-gradient(to bottom, #ee5f5b, #bd362f);\n  background-repeat: repeat-x;\n  border-color: #bd362f #bd362f #802420;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-danger:hover,\n.btn-danger:focus,\n.btn-danger:active,\n.btn-danger.active,\n.btn-danger.disabled,\n.btn-danger[disabled] {\n  color: #ffffff;\n  background-color: #bd362f;\n  *background-color: #a9302a;\n}\n\n.btn-danger:active,\n.btn-danger.active {\n  background-color: #942a25 \\9;\n}\n\n.btn-success {\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #5bb75b;\n  *background-color: #51a351;\n  background-image: -moz-linear-gradient(top, #62c462, #51a351);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));\n  background-image: -webkit-linear-gradient(top, #62c462, #51a351);\n  background-image: -o-linear-gradient(top, #62c462, #51a351);\n  background-image: linear-gradient(to bottom, #62c462, #51a351);\n  background-repeat: repeat-x;\n  border-color: #51a351 #51a351 #387038;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-success:hover,\n.btn-success:focus,\n.btn-success:active,\n.btn-success.active,\n.btn-success.disabled,\n.btn-success[disabled] {\n  color: #ffffff;\n  background-color: #51a351;\n  *background-color: #499249;\n}\n\n.btn-success:active,\n.btn-success.active {\n  background-color: #408140 \\9;\n}\n\n.btn-info {\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #49afcd;\n  *background-color: #2f96b4;\n  background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));\n  background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4);\n  background-image: -o-linear-gradient(top, #5bc0de, #2f96b4);\n  background-image: linear-gradient(to bottom, #5bc0de, #2f96b4);\n  background-repeat: repeat-x;\n  border-color: #2f96b4 #2f96b4 #1f6377;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-info:hover,\n.btn-info:focus,\n.btn-info:active,\n.btn-info.active,\n.btn-info.disabled,\n.btn-info[disabled] {\n  color: #ffffff;\n  background-color: #2f96b4;\n  *background-color: #2a85a0;\n}\n\n.btn-info:active,\n.btn-info.active {\n  background-color: #24748c \\9;\n}\n\n.btn-inverse {\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #363636;\n  *background-color: #222222;\n  background-image: -moz-linear-gradient(top, #444444, #222222);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));\n  background-image: -webkit-linear-gradient(top, #444444, #222222);\n  background-image: -o-linear-gradient(top, #444444, #222222);\n  background-image: linear-gradient(to bottom, #444444, #222222);\n  background-repeat: repeat-x;\n  border-color: #222222 #222222 #000000;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-inverse:hover,\n.btn-inverse:focus,\n.btn-inverse:active,\n.btn-inverse.active,\n.btn-inverse.disabled,\n.btn-inverse[disabled] {\n  color: #ffffff;\n  background-color: #222222;\n  *background-color: #151515;\n}\n\n.btn-inverse:active,\n.btn-inverse.active {\n  background-color: #080808 \\9;\n}\n\nbutton.btn,\ninput[type=\"submit\"].btn {\n  *padding-top: 3px;\n  *padding-bottom: 3px;\n}\n\nbutton.btn::-moz-focus-inner,\ninput[type=\"submit\"].btn::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\n\nbutton.btn.btn-large,\ninput[type=\"submit\"].btn.btn-large {\n  *padding-top: 7px;\n  *padding-bottom: 7px;\n}\n\nbutton.btn.btn-small,\ninput[type=\"submit\"].btn.btn-small {\n  *padding-top: 3px;\n  *padding-bottom: 3px;\n}\n\nbutton.btn.btn-mini,\ninput[type=\"submit\"].btn.btn-mini {\n  *padding-top: 1px;\n  *padding-bottom: 1px;\n}\n\n.btn-link,\n.btn-link:active,\n.btn-link[disabled] {\n  background-color: transparent;\n  background-image: none;\n  -webkit-box-shadow: none;\n     -moz-box-shadow: none;\n          box-shadow: none;\n}\n\n.btn-link {\n  color: #0088cc;\n  cursor: pointer;\n  border-color: transparent;\n  -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n          border-radius: 0;\n}\n\n.btn-link:hover,\n.btn-link:focus {\n  color: #005580;\n  text-decoration: underline;\n  background-color: transparent;\n}\n\n.btn-link[disabled]:hover,\n.btn-link[disabled]:focus {\n  color: #333333;\n  text-decoration: none;\n}\n\n.btn-group {\n  position: relative;\n  display: inline-block;\n  *display: inline;\n  *margin-left: .3em;\n  font-size: 0;\n  white-space: nowrap;\n  vertical-align: middle;\n  *zoom: 1;\n}\n\n.btn-group:first-child {\n  *margin-left: 0;\n}\n\n.btn-group + .btn-group {\n  margin-left: 5px;\n}\n\n.btn-toolbar {\n  margin-top: 10px;\n  margin-bottom: 10px;\n  font-size: 0;\n}\n\n.btn-toolbar > .btn + .btn,\n.btn-toolbar > .btn-group + .btn,\n.btn-toolbar > .btn + .btn-group {\n  margin-left: 5px;\n}\n\n.btn-group > .btn {\n  position: relative;\n  -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n          border-radius: 0;\n}\n\n.btn-group > .btn + .btn {\n  margin-left: -1px;\n}\n\n.btn-group > .btn,\n.btn-group > .dropdown-menu,\n.btn-group > .popover {\n  font-size: 14px;\n}\n\n.btn-group > .btn-mini {\n  font-size: 10.5px;\n}\n\n.btn-group > .btn-small {\n  font-size: 11.9px;\n}\n\n.btn-group > .btn-large {\n  font-size: 17.5px;\n}\n\n.btn-group > .btn:first-child {\n  margin-left: 0;\n  -webkit-border-bottom-left-radius: 4px;\n          border-bottom-left-radius: 4px;\n  -webkit-border-top-left-radius: 4px;\n          border-top-left-radius: 4px;\n  -moz-border-radius-bottomleft: 4px;\n  -moz-border-radius-topleft: 4px;\n}\n\n.btn-group > .btn:last-child,\n.btn-group > .dropdown-toggle {\n  -webkit-border-top-right-radius: 4px;\n          border-top-right-radius: 4px;\n  -webkit-border-bottom-right-radius: 4px;\n          border-bottom-right-radius: 4px;\n  -moz-border-radius-topright: 4px;\n  -moz-border-radius-bottomright: 4px;\n}\n\n.btn-group > .btn.large:first-child {\n  margin-left: 0;\n  -webkit-border-bottom-left-radius: 6px;\n          border-bottom-left-radius: 6px;\n  -webkit-border-top-left-radius: 6px;\n          border-top-left-radius: 6px;\n  -moz-border-radius-bottomleft: 6px;\n  -moz-border-radius-topleft: 6px;\n}\n\n.btn-group > .btn.large:last-child,\n.btn-group > .large.dropdown-toggle {\n  -webkit-border-top-right-radius: 6px;\n          border-top-right-radius: 6px;\n  -webkit-border-bottom-right-radius: 6px;\n          border-bottom-right-radius: 6px;\n  -moz-border-radius-topright: 6px;\n  -moz-border-radius-bottomright: 6px;\n}\n\n.btn-group > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group > .btn:active,\n.btn-group > .btn.active {\n  z-index: 2;\n}\n\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n\n.btn-group > .btn + .dropdown-toggle {\n  *padding-top: 5px;\n  padding-right: 8px;\n  *padding-bottom: 5px;\n  padding-left: 8px;\n  -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);\n     -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.btn-group > .btn-mini + .dropdown-toggle {\n  *padding-top: 2px;\n  padding-right: 5px;\n  *padding-bottom: 2px;\n  padding-left: 5px;\n}\n\n.btn-group > .btn-small + .dropdown-toggle {\n  *padding-top: 5px;\n  *padding-bottom: 4px;\n}\n\n.btn-group > .btn-large + .dropdown-toggle {\n  *padding-top: 7px;\n  padding-right: 12px;\n  *padding-bottom: 7px;\n  padding-left: 12px;\n}\n\n.btn-group.open .dropdown-toggle {\n  background-image: none;\n  -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);\n     -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.btn-group.open .btn.dropdown-toggle {\n  background-color: #e6e6e6;\n}\n\n.btn-group.open .btn-primary.dropdown-toggle {\n  background-color: #0044cc;\n}\n\n.btn-group.open .btn-warning.dropdown-toggle {\n  background-color: #f89406;\n}\n\n.btn-group.open .btn-danger.dropdown-toggle {\n  background-color: #bd362f;\n}\n\n.btn-group.open .btn-success.dropdown-toggle {\n  background-color: #51a351;\n}\n\n.btn-group.open .btn-info.dropdown-toggle {\n  background-color: #2f96b4;\n}\n\n.btn-group.open .btn-inverse.dropdown-toggle {\n  background-color: #222222;\n}\n\n.btn .caret {\n  margin-top: 8px;\n  margin-left: 0;\n}\n\n.btn-large .caret {\n  margin-top: 6px;\n}\n\n.btn-large .caret {\n  border-top-width: 5px;\n  border-right-width: 5px;\n  border-left-width: 5px;\n}\n\n.btn-mini .caret,\n.btn-small .caret {\n  margin-top: 8px;\n}\n\n.dropup .btn-large .caret {\n  border-bottom-width: 5px;\n}\n\n.btn-primary .caret,\n.btn-warning .caret,\n.btn-danger .caret,\n.btn-info .caret,\n.btn-success .caret,\n.btn-inverse .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n\n.btn-group-vertical {\n  display: inline-block;\n  *display: inline;\n  /* IE7 inline-block hack */\n\n  *zoom: 1;\n}\n\n.btn-group-vertical > .btn {\n  display: block;\n  float: none;\n  max-width: 100%;\n  -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n          border-radius: 0;\n}\n\n.btn-group-vertical > .btn + .btn {\n  margin-top: -1px;\n  margin-left: 0;\n}\n\n.btn-group-vertical > .btn:first-child {\n  -webkit-border-radius: 4px 4px 0 0;\n     -moz-border-radius: 4px 4px 0 0;\n          border-radius: 4px 4px 0 0;\n}\n\n.btn-group-vertical > .btn:last-child {\n  -webkit-border-radius: 0 0 4px 4px;\n     -moz-border-radius: 0 0 4px 4px;\n          border-radius: 0 0 4px 4px;\n}\n\n.btn-group-vertical > .btn-large:first-child {\n  -webkit-border-radius: 6px 6px 0 0;\n     -moz-border-radius: 6px 6px 0 0;\n          border-radius: 6px 6px 0 0;\n}\n\n.btn-group-vertical > .btn-large:last-child {\n  -webkit-border-radius: 0 0 6px 6px;\n     -moz-border-radius: 0 0 6px 6px;\n          border-radius: 0 0 6px 6px;\n}\n\n.alert {\n  padding: 8px 35px 8px 14px;\n  margin-bottom: 20px;\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);\n  background-color: #fcf8e3;\n  border: 1px solid #fbeed5;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n}\n\n.alert,\n.alert h4 {\n  color: #c09853;\n}\n\n.alert h4 {\n  margin: 0;\n}\n\n.alert .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  line-height: 20px;\n}\n\n.alert-success {\n  color: #468847;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n\n.alert-success h4 {\n  color: #468847;\n}\n\n.alert-danger,\n.alert-error {\n  color: #b94a48;\n  background-color: #f2dede;\n  border-color: #eed3d7;\n}\n\n.alert-danger h4,\n.alert-error h4 {\n  color: #b94a48;\n}\n\n.alert-info {\n  color: #3a87ad;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n\n.alert-info h4 {\n  color: #3a87ad;\n}\n\n.alert-block {\n  padding-top: 14px;\n  padding-bottom: 14px;\n}\n\n.alert-block > p,\n.alert-block > ul {\n  margin-bottom: 0;\n}\n\n.alert-block p + p {\n  margin-top: 5px;\n}\n\n.nav {\n  margin-bottom: 20px;\n  margin-left: 0;\n  list-style: none;\n}\n\n.nav > li > a {\n  display: block;\n}\n\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n\n.nav > li > a > img {\n  max-width: none;\n}\n\n.nav > .pull-right {\n  float: right;\n}\n\n.nav-header {\n  display: block;\n  padding: 3px 15px;\n  font-size: 11px;\n  font-weight: bold;\n  line-height: 20px;\n  color: #999999;\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);\n  text-transform: uppercase;\n}\n\n.nav li + .nav-header {\n  margin-top: 9px;\n}\n\n.nav-list {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-bottom: 0;\n}\n\n.nav-list > li > a,\n.nav-list .nav-header {\n  margin-right: -15px;\n  margin-left: -15px;\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);\n}\n\n.nav-list > li > a {\n  padding: 3px 15px;\n}\n\n.nav-list > .active > a,\n.nav-list > .active > a:hover,\n.nav-list > .active > a:focus {\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n  background-color: #0088cc;\n}\n\n.nav-list [class^=\"icon-\"],\n.nav-list [class*=\" icon-\"] {\n  margin-right: 2px;\n}\n\n.nav-list .divider {\n  *width: 100%;\n  height: 1px;\n  margin: 9px 1px;\n  *margin: -5px 0 5px;\n  overflow: hidden;\n  background-color: #e5e5e5;\n  border-bottom: 1px solid #ffffff;\n}\n\n.nav-tabs,\n.nav-pills {\n  *zoom: 1;\n}\n\n.nav-tabs:before,\n.nav-pills:before,\n.nav-tabs:after,\n.nav-pills:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.nav-tabs:after,\n.nav-pills:after {\n  clear: both;\n}\n\n.nav-tabs > li,\n.nav-pills > li {\n  float: left;\n}\n\n.nav-tabs > li > a,\n.nav-pills > li > a {\n  padding-right: 12px;\n  padding-left: 12px;\n  margin-right: 2px;\n  line-height: 14px;\n}\n\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n\n.nav-tabs > li {\n  margin-bottom: -1px;\n}\n\n.nav-tabs > li > a {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  line-height: 20px;\n  border: 1px solid transparent;\n  -webkit-border-radius: 4px 4px 0 0;\n     -moz-border-radius: 4px 4px 0 0;\n          border-radius: 4px 4px 0 0;\n}\n\n.nav-tabs > li > a:hover,\n.nav-tabs > li > a:focus {\n  border-color: #eeeeee #eeeeee #dddddd;\n}\n\n.nav-tabs > .active > a,\n.nav-tabs > .active > a:hover,\n.nav-tabs > .active > a:focus {\n  color: #555555;\n  cursor: default;\n  background-color: #ffffff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n}\n\n.nav-pills > li > a {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  margin-top: 2px;\n  margin-bottom: 2px;\n  -webkit-border-radius: 5px;\n     -moz-border-radius: 5px;\n          border-radius: 5px;\n}\n\n.nav-pills > .active > a,\n.nav-pills > .active > a:hover,\n.nav-pills > .active > a:focus {\n  color: #ffffff;\n  background-color: #0088cc;\n}\n\n.nav-stacked > li {\n  float: none;\n}\n\n.nav-stacked > li > a {\n  margin-right: 0;\n}\n\n.nav-tabs.nav-stacked {\n  border-bottom: 0;\n}\n\n.nav-tabs.nav-stacked > li > a {\n  border: 1px solid #ddd;\n  -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n          border-radius: 0;\n}\n\n.nav-tabs.nav-stacked > li:first-child > a {\n  -webkit-border-top-right-radius: 4px;\n          border-top-right-radius: 4px;\n  -webkit-border-top-left-radius: 4px;\n          border-top-left-radius: 4px;\n  -moz-border-radius-topright: 4px;\n  -moz-border-radius-topleft: 4px;\n}\n\n.nav-tabs.nav-stacked > li:last-child > a {\n  -webkit-border-bottom-right-radius: 4px;\n          border-bottom-right-radius: 4px;\n  -webkit-border-bottom-left-radius: 4px;\n          border-bottom-left-radius: 4px;\n  -moz-border-radius-bottomright: 4px;\n  -moz-border-radius-bottomleft: 4px;\n}\n\n.nav-tabs.nav-stacked > li > a:hover,\n.nav-tabs.nav-stacked > li > a:focus {\n  z-index: 2;\n  border-color: #ddd;\n}\n\n.nav-pills.nav-stacked > li > a {\n  margin-bottom: 3px;\n}\n\n.nav-pills.nav-stacked > li:last-child > a {\n  margin-bottom: 1px;\n}\n\n.nav-tabs .dropdown-menu {\n  -webkit-border-radius: 0 0 6px 6px;\n     -moz-border-radius: 0 0 6px 6px;\n          border-radius: 0 0 6px 6px;\n}\n\n.nav-pills .dropdown-menu {\n  -webkit-border-radius: 6px;\n     -moz-border-radius: 6px;\n          border-radius: 6px;\n}\n\n.nav .dropdown-toggle .caret {\n  margin-top: 6px;\n  border-top-color: #0088cc;\n  border-bottom-color: #0088cc;\n}\n\n.nav .dropdown-toggle:hover .caret,\n.nav .dropdown-toggle:focus .caret {\n  border-top-color: #005580;\n  border-bottom-color: #005580;\n}\n\n/* move down carets for tabs */\n\n.nav-tabs .dropdown-toggle .caret {\n  margin-top: 8px;\n}\n\n.nav .active .dropdown-toggle .caret {\n  border-top-color: #fff;\n  border-bottom-color: #fff;\n}\n\n.nav-tabs .active .dropdown-toggle .caret {\n  border-top-color: #555555;\n  border-bottom-color: #555555;\n}\n\n.nav > .dropdown.active > a:hover,\n.nav > .dropdown.active > a:focus {\n  cursor: pointer;\n}\n\n.nav-tabs .open .dropdown-toggle,\n.nav-pills .open .dropdown-toggle,\n.nav > li.dropdown.open.active > a:hover,\n.nav > li.dropdown.open.active > a:focus {\n  color: #ffffff;\n  background-color: #999999;\n  border-color: #999999;\n}\n\n.nav li.dropdown.open .caret,\n.nav li.dropdown.open.active .caret,\n.nav li.dropdown.open a:hover .caret,\n.nav li.dropdown.open a:focus .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n  opacity: 1;\n  filter: alpha(opacity=100);\n}\n\n.tabs-stacked .open > a:hover,\n.tabs-stacked .open > a:focus {\n  border-color: #999999;\n}\n\n.tabbable {\n  *zoom: 1;\n}\n\n.tabbable:before,\n.tabbable:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.tabbable:after {\n  clear: both;\n}\n\n.tab-content {\n  overflow: auto;\n}\n\n.tabs-below > .nav-tabs,\n.tabs-right > .nav-tabs,\n.tabs-left > .nav-tabs {\n  border-bottom: 0;\n}\n\n.tab-content > .tab-pane,\n.pill-content > .pill-pane {\n  display: none;\n}\n\n.tab-content > .active,\n.pill-content > .active {\n  display: block;\n}\n\n.tabs-below > .nav-tabs {\n  border-top: 1px solid #ddd;\n}\n\n.tabs-below > .nav-tabs > li {\n  margin-top: -1px;\n  margin-bottom: 0;\n}\n\n.tabs-below > .nav-tabs > li > a {\n  -webkit-border-radius: 0 0 4px 4px;\n     -moz-border-radius: 0 0 4px 4px;\n          border-radius: 0 0 4px 4px;\n}\n\n.tabs-below > .nav-tabs > li > a:hover,\n.tabs-below > .nav-tabs > li > a:focus {\n  border-top-color: #ddd;\n  border-bottom-color: transparent;\n}\n\n.tabs-below > .nav-tabs > .active > a,\n.tabs-below > .nav-tabs > .active > a:hover,\n.tabs-below > .nav-tabs > .active > a:focus {\n  border-color: transparent #ddd #ddd #ddd;\n}\n\n.tabs-left > .nav-tabs > li,\n.tabs-right > .nav-tabs > li {\n  float: none;\n}\n\n.tabs-left > .nav-tabs > li > a,\n.tabs-right > .nav-tabs > li > a {\n  min-width: 74px;\n  margin-right: 0;\n  margin-bottom: 3px;\n}\n\n.tabs-left > .nav-tabs {\n  float: left;\n  margin-right: 19px;\n  border-right: 1px solid #ddd;\n}\n\n.tabs-left > .nav-tabs > li > a {\n  margin-right: -1px;\n  -webkit-border-radius: 4px 0 0 4px;\n     -moz-border-radius: 4px 0 0 4px;\n          border-radius: 4px 0 0 4px;\n}\n\n.tabs-left > .nav-tabs > li > a:hover,\n.tabs-left > .nav-tabs > li > a:focus {\n  border-color: #eeeeee #dddddd #eeeeee #eeeeee;\n}\n\n.tabs-left > .nav-tabs .active > a,\n.tabs-left > .nav-tabs .active > a:hover,\n.tabs-left > .nav-tabs .active > a:focus {\n  border-color: #ddd transparent #ddd #ddd;\n  *border-right-color: #ffffff;\n}\n\n.tabs-right > .nav-tabs {\n  float: right;\n  margin-left: 19px;\n  border-left: 1px solid #ddd;\n}\n\n.tabs-right > .nav-tabs > li > a {\n  margin-left: -1px;\n  -webkit-border-radius: 0 4px 4px 0;\n     -moz-border-radius: 0 4px 4px 0;\n          border-radius: 0 4px 4px 0;\n}\n\n.tabs-right > .nav-tabs > li > a:hover,\n.tabs-right > .nav-tabs > li > a:focus {\n  border-color: #eeeeee #eeeeee #eeeeee #dddddd;\n}\n\n.tabs-right > .nav-tabs .active > a,\n.tabs-right > .nav-tabs .active > a:hover,\n.tabs-right > .nav-tabs .active > a:focus {\n  border-color: #ddd #ddd #ddd transparent;\n  *border-left-color: #ffffff;\n}\n\n.nav > .disabled > a {\n  color: #999999;\n}\n\n.nav > .disabled > a:hover,\n.nav > .disabled > a:focus {\n  text-decoration: none;\n  cursor: default;\n  background-color: transparent;\n}\n\n.navbar {\n  *position: relative;\n  *z-index: 2;\n  margin-bottom: 20px;\n  overflow: visible;\n}\n\n.navbar-inner {\n  min-height: 40px;\n  padding-right: 20px;\n  padding-left: 20px;\n  background-color: #fafafa;\n  background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));\n  background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2);\n  background-image: -o-linear-gradient(top, #ffffff, #f2f2f2);\n  background-image: linear-gradient(to bottom, #ffffff, #f2f2f2);\n  background-repeat: repeat-x;\n  border: 1px solid #d4d4d4;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);\n  *zoom: 1;\n  -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);\n     -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);\n          box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);\n}\n\n.navbar-inner:before,\n.navbar-inner:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.navbar-inner:after {\n  clear: both;\n}\n\n.navbar .container {\n  width: auto;\n}\n\n.nav-collapse.collapse {\n  height: auto;\n  overflow: visible;\n}\n\n.navbar .brand {\n  display: block;\n  float: left;\n  padding: 10px 20px 10px;\n  margin-left: -20px;\n  font-size: 20px;\n  font-weight: 200;\n  color: #777777;\n  text-shadow: 0 1px 0 #ffffff;\n}\n\n.navbar .brand:hover,\n.navbar .brand:focus {\n  text-decoration: none;\n}\n\n.navbar-text {\n  margin-bottom: 0;\n  line-height: 40px;\n  color: #777777;\n}\n\n.navbar-link {\n  color: #777777;\n}\n\n.navbar-link:hover,\n.navbar-link:focus {\n  color: #333333;\n}\n\n.navbar .divider-vertical {\n  height: 40px;\n  margin: 0 9px;\n  border-right: 1px solid #ffffff;\n  border-left: 1px solid #f2f2f2;\n}\n\n.navbar .btn,\n.navbar .btn-group {\n  margin-top: 5px;\n}\n\n.navbar .btn-group .btn,\n.navbar .input-prepend .btn,\n.navbar .input-append .btn,\n.navbar .input-prepend .btn-group,\n.navbar .input-append .btn-group {\n  margin-top: 0;\n}\n\n.navbar-form {\n  margin-bottom: 0;\n  *zoom: 1;\n}\n\n.navbar-form:before,\n.navbar-form:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.navbar-form:after {\n  clear: both;\n}\n\n.navbar-form input,\n.navbar-form select,\n.navbar-form .radio,\n.navbar-form .checkbox {\n  margin-top: 5px;\n}\n\n.navbar-form input,\n.navbar-form select,\n.navbar-form .btn {\n  display: inline-block;\n  margin-bottom: 0;\n}\n\n.navbar-form input[type=\"image\"],\n.navbar-form input[type=\"checkbox\"],\n.navbar-form input[type=\"radio\"] {\n  margin-top: 3px;\n}\n\n.navbar-form .input-append,\n.navbar-form .input-prepend {\n  margin-top: 5px;\n  white-space: nowrap;\n}\n\n.navbar-form .input-append input,\n.navbar-form .input-prepend input {\n  margin-top: 0;\n}\n\n.navbar-search {\n  position: relative;\n  float: left;\n  margin-top: 5px;\n  margin-bottom: 0;\n}\n\n.navbar-search .search-query {\n  padding: 4px 14px;\n  margin-bottom: 0;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 13px;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-border-radius: 15px;\n     -moz-border-radius: 15px;\n          border-radius: 15px;\n}\n\n.navbar-static-top {\n  position: static;\n  margin-bottom: 0;\n}\n\n.navbar-static-top .navbar-inner {\n  -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n          border-radius: 0;\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n  margin-bottom: 0;\n}\n\n.navbar-fixed-top .navbar-inner,\n.navbar-static-top .navbar-inner {\n  border-width: 0 0 1px;\n}\n\n.navbar-fixed-bottom .navbar-inner {\n  border-width: 1px 0 0;\n}\n\n.navbar-fixed-top .navbar-inner,\n.navbar-fixed-bottom .navbar-inner {\n  padding-right: 0;\n  padding-left: 0;\n  -webkit-border-radius: 0;\n     -moz-border-radius: 0;\n          border-radius: 0;\n}\n\n.navbar-static-top .container,\n.navbar-fixed-top .container,\n.navbar-fixed-bottom .container {\n  width: 940px;\n}\n\n.navbar-fixed-top {\n  top: 0;\n}\n\n.navbar-fixed-top .navbar-inner,\n.navbar-static-top .navbar-inner {\n  -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);\n     -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);\n          box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);\n}\n\n.navbar-fixed-bottom {\n  bottom: 0;\n}\n\n.navbar-fixed-bottom .navbar-inner {\n  -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);\n     -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);\n          box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);\n}\n\n.navbar .nav {\n  position: relative;\n  left: 0;\n  display: block;\n  float: left;\n  margin: 0 10px 0 0;\n}\n\n.navbar .nav.pull-right {\n  float: right;\n  margin-right: 0;\n}\n\n.navbar .nav > li {\n  float: left;\n}\n\n.navbar .nav > li > a {\n  float: none;\n  padding: 10px 15px 10px;\n  color: #777777;\n  text-decoration: none;\n  text-shadow: 0 1px 0 #ffffff;\n}\n\n.navbar .nav .dropdown-toggle .caret {\n  margin-top: 8px;\n}\n\n.navbar .nav > li > a:focus,\n.navbar .nav > li > a:hover {\n  color: #333333;\n  text-decoration: none;\n  background-color: transparent;\n}\n\n.navbar .nav > .active > a,\n.navbar .nav > .active > a:hover,\n.navbar .nav > .active > a:focus {\n  color: #555555;\n  text-decoration: none;\n  background-color: #e5e5e5;\n  -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);\n     -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);\n          box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);\n}\n\n.navbar .btn-navbar {\n  display: none;\n  float: right;\n  padding: 7px 10px;\n  margin-right: 5px;\n  margin-left: 5px;\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #ededed;\n  *background-color: #e5e5e5;\n  background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));\n  background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5);\n  background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5);\n  background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5);\n  background-repeat: repeat-x;\n  border-color: #e5e5e5 #e5e5e5 #bfbfbf;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);\n     -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);\n}\n\n.navbar .btn-navbar:hover,\n.navbar .btn-navbar:focus,\n.navbar .btn-navbar:active,\n.navbar .btn-navbar.active,\n.navbar .btn-navbar.disabled,\n.navbar .btn-navbar[disabled] {\n  color: #ffffff;\n  background-color: #e5e5e5;\n  *background-color: #d9d9d9;\n}\n\n.navbar .btn-navbar:active,\n.navbar .btn-navbar.active {\n  background-color: #cccccc \\9;\n}\n\n.navbar .btn-navbar .icon-bar {\n  display: block;\n  width: 18px;\n  height: 2px;\n  background-color: #f5f5f5;\n  -webkit-border-radius: 1px;\n     -moz-border-radius: 1px;\n          border-radius: 1px;\n  -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);\n     -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);\n          box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);\n}\n\n.btn-navbar .icon-bar + .icon-bar {\n  margin-top: 3px;\n}\n\n.navbar .nav > li > .dropdown-menu:before {\n  position: absolute;\n  top: -7px;\n  left: 9px;\n  display: inline-block;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid #ccc;\n  border-left: 7px solid transparent;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  content: '';\n}\n\n.navbar .nav > li > .dropdown-menu:after {\n  position: absolute;\n  top: -6px;\n  left: 10px;\n  display: inline-block;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #ffffff;\n  border-left: 6px solid transparent;\n  content: '';\n}\n\n.navbar-fixed-bottom .nav > li > .dropdown-menu:before {\n  top: auto;\n  bottom: -7px;\n  border-top: 7px solid #ccc;\n  border-bottom: 0;\n  border-top-color: rgba(0, 0, 0, 0.2);\n}\n\n.navbar-fixed-bottom .nav > li > .dropdown-menu:after {\n  top: auto;\n  bottom: -6px;\n  border-top: 6px solid #ffffff;\n  border-bottom: 0;\n}\n\n.navbar .nav li.dropdown > a:hover .caret,\n.navbar .nav li.dropdown > a:focus .caret {\n  border-top-color: #333333;\n  border-bottom-color: #333333;\n}\n\n.navbar .nav li.dropdown.open > .dropdown-toggle,\n.navbar .nav li.dropdown.active > .dropdown-toggle,\n.navbar .nav li.dropdown.open.active > .dropdown-toggle {\n  color: #555555;\n  background-color: #e5e5e5;\n}\n\n.navbar .nav li.dropdown > .dropdown-toggle .caret {\n  border-top-color: #777777;\n  border-bottom-color: #777777;\n}\n\n.navbar .nav li.dropdown.open > .dropdown-toggle .caret,\n.navbar .nav li.dropdown.active > .dropdown-toggle .caret,\n.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret {\n  border-top-color: #555555;\n  border-bottom-color: #555555;\n}\n\n.navbar .pull-right > li > .dropdown-menu,\n.navbar .nav > li > .dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n\n.navbar .pull-right > li > .dropdown-menu:before,\n.navbar .nav > li > .dropdown-menu.pull-right:before {\n  right: 12px;\n  left: auto;\n}\n\n.navbar .pull-right > li > .dropdown-menu:after,\n.navbar .nav > li > .dropdown-menu.pull-right:after {\n  right: 13px;\n  left: auto;\n}\n\n.navbar .pull-right > li > .dropdown-menu .dropdown-menu,\n.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu {\n  right: 100%;\n  left: auto;\n  margin-right: -1px;\n  margin-left: 0;\n  -webkit-border-radius: 6px 0 6px 6px;\n     -moz-border-radius: 6px 0 6px 6px;\n          border-radius: 6px 0 6px 6px;\n}\n\n.navbar-inverse .navbar-inner {\n  background-color: #1b1b1b;\n  background-image: -moz-linear-gradient(top, #222222, #111111);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));\n  background-image: -webkit-linear-gradient(top, #222222, #111111);\n  background-image: -o-linear-gradient(top, #222222, #111111);\n  background-image: linear-gradient(to bottom, #222222, #111111);\n  background-repeat: repeat-x;\n  border-color: #252525;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);\n}\n\n.navbar-inverse .brand,\n.navbar-inverse .nav > li > a {\n  color: #999999;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n\n.navbar-inverse .brand:hover,\n.navbar-inverse .nav > li > a:hover,\n.navbar-inverse .brand:focus,\n.navbar-inverse .nav > li > a:focus {\n  color: #ffffff;\n}\n\n.navbar-inverse .brand {\n  color: #999999;\n}\n\n.navbar-inverse .navbar-text {\n  color: #999999;\n}\n\n.navbar-inverse .nav > li > a:focus,\n.navbar-inverse .nav > li > a:hover {\n  color: #ffffff;\n  background-color: transparent;\n}\n\n.navbar-inverse .nav .active > a,\n.navbar-inverse .nav .active > a:hover,\n.navbar-inverse .nav .active > a:focus {\n  color: #ffffff;\n  background-color: #111111;\n}\n\n.navbar-inverse .navbar-link {\n  color: #999999;\n}\n\n.navbar-inverse .navbar-link:hover,\n.navbar-inverse .navbar-link:focus {\n  color: #ffffff;\n}\n\n.navbar-inverse .divider-vertical {\n  border-right-color: #222222;\n  border-left-color: #111111;\n}\n\n.navbar-inverse .nav li.dropdown.open > .dropdown-toggle,\n.navbar-inverse .nav li.dropdown.active > .dropdown-toggle,\n.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle {\n  color: #ffffff;\n  background-color: #111111;\n}\n\n.navbar-inverse .nav li.dropdown > a:hover .caret,\n.navbar-inverse .nav li.dropdown > a:focus .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n\n.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret {\n  border-top-color: #999999;\n  border-bottom-color: #999999;\n}\n\n.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret,\n.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret,\n.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n\n.navbar-inverse .navbar-search .search-query {\n  color: #ffffff;\n  background-color: #515151;\n  border-color: #111111;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);\n     -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);\n  -webkit-transition: none;\n     -moz-transition: none;\n       -o-transition: none;\n          transition: none;\n}\n\n.navbar-inverse .navbar-search .search-query:-moz-placeholder {\n  color: #cccccc;\n}\n\n.navbar-inverse .navbar-search .search-query:-ms-input-placeholder {\n  color: #cccccc;\n}\n\n.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder {\n  color: #cccccc;\n}\n\n.navbar-inverse .navbar-search .search-query:focus,\n.navbar-inverse .navbar-search .search-query.focused {\n  padding: 5px 15px;\n  color: #333333;\n  text-shadow: 0 1px 0 #ffffff;\n  background-color: #ffffff;\n  border: 0;\n  outline: 0;\n  -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);\n     -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);\n          box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);\n}\n\n.navbar-inverse .btn-navbar {\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #0e0e0e;\n  *background-color: #040404;\n  background-image: -moz-linear-gradient(top, #151515, #040404);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));\n  background-image: -webkit-linear-gradient(top, #151515, #040404);\n  background-image: -o-linear-gradient(top, #151515, #040404);\n  background-image: linear-gradient(to bottom, #151515, #040404);\n  background-repeat: repeat-x;\n  border-color: #040404 #040404 #000000;\n  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.navbar-inverse .btn-navbar:hover,\n.navbar-inverse .btn-navbar:focus,\n.navbar-inverse .btn-navbar:active,\n.navbar-inverse .btn-navbar.active,\n.navbar-inverse .btn-navbar.disabled,\n.navbar-inverse .btn-navbar[disabled] {\n  color: #ffffff;\n  background-color: #040404;\n  *background-color: #000000;\n}\n\n.navbar-inverse .btn-navbar:active,\n.navbar-inverse .btn-navbar.active {\n  background-color: #000000 \\9;\n}\n\n.breadcrumb {\n  padding: 8px 15px;\n  margin: 0 0 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n}\n\n.breadcrumb > li {\n  display: inline-block;\n  *display: inline;\n  text-shadow: 0 1px 0 #ffffff;\n  *zoom: 1;\n}\n\n.breadcrumb > li > .divider {\n  padding: 0 5px;\n  color: #ccc;\n}\n\n.breadcrumb > .active {\n  color: #999999;\n}\n\n.pagination {\n  margin: 20px 0;\n}\n\n.pagination ul {\n  display: inline-block;\n  *display: inline;\n  margin-bottom: 0;\n  margin-left: 0;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n  *zoom: 1;\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n     -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.pagination ul > li {\n  display: inline;\n}\n\n.pagination ul > li > a,\n.pagination ul > li > span {\n  float: left;\n  padding: 4px 12px;\n  line-height: 20px;\n  text-decoration: none;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-left-width: 0;\n}\n\n.pagination ul > li > a:hover,\n.pagination ul > li > a:focus,\n.pagination ul > .active > a,\n.pagination ul > .active > span {\n  background-color: #f5f5f5;\n}\n\n.pagination ul > .active > a,\n.pagination ul > .active > span {\n  color: #999999;\n  cursor: default;\n}\n\n.pagination ul > .disabled > span,\n.pagination ul > .disabled > a,\n.pagination ul > .disabled > a:hover,\n.pagination ul > .disabled > a:focus {\n  color: #999999;\n  cursor: default;\n  background-color: transparent;\n}\n\n.pagination ul > li:first-child > a,\n.pagination ul > li:first-child > span {\n  border-left-width: 1px;\n  -webkit-border-bottom-left-radius: 4px;\n          border-bottom-left-radius: 4px;\n  -webkit-border-top-left-radius: 4px;\n          border-top-left-radius: 4px;\n  -moz-border-radius-bottomleft: 4px;\n  -moz-border-radius-topleft: 4px;\n}\n\n.pagination ul > li:last-child > a,\n.pagination ul > li:last-child > span {\n  -webkit-border-top-right-radius: 4px;\n          border-top-right-radius: 4px;\n  -webkit-border-bottom-right-radius: 4px;\n          border-bottom-right-radius: 4px;\n  -moz-border-radius-topright: 4px;\n  -moz-border-radius-bottomright: 4px;\n}\n\n.pagination-centered {\n  text-align: center;\n}\n\n.pagination-right {\n  text-align: right;\n}\n\n.pagination-large ul > li > a,\n.pagination-large ul > li > span {\n  padding: 11px 19px;\n  font-size: 17.5px;\n}\n\n.pagination-large ul > li:first-child > a,\n.pagination-large ul > li:first-child > span {\n  -webkit-border-bottom-left-radius: 6px;\n          border-bottom-left-radius: 6px;\n  -webkit-border-top-left-radius: 6px;\n          border-top-left-radius: 6px;\n  -moz-border-radius-bottomleft: 6px;\n  -moz-border-radius-topleft: 6px;\n}\n\n.pagination-large ul > li:last-child > a,\n.pagination-large ul > li:last-child > span {\n  -webkit-border-top-right-radius: 6px;\n          border-top-right-radius: 6px;\n  -webkit-border-bottom-right-radius: 6px;\n          border-bottom-right-radius: 6px;\n  -moz-border-radius-topright: 6px;\n  -moz-border-radius-bottomright: 6px;\n}\n\n.pagination-mini ul > li:first-child > a,\n.pagination-small ul > li:first-child > a,\n.pagination-mini ul > li:first-child > span,\n.pagination-small ul > li:first-child > span {\n  -webkit-border-bottom-left-radius: 3px;\n          border-bottom-left-radius: 3px;\n  -webkit-border-top-left-radius: 3px;\n          border-top-left-radius: 3px;\n  -moz-border-radius-bottomleft: 3px;\n  -moz-border-radius-topleft: 3px;\n}\n\n.pagination-mini ul > li:last-child > a,\n.pagination-small ul > li:last-child > a,\n.pagination-mini ul > li:last-child > span,\n.pagination-small ul > li:last-child > span {\n  -webkit-border-top-right-radius: 3px;\n          border-top-right-radius: 3px;\n  -webkit-border-bottom-right-radius: 3px;\n          border-bottom-right-radius: 3px;\n  -moz-border-radius-topright: 3px;\n  -moz-border-radius-bottomright: 3px;\n}\n\n.pagination-small ul > li > a,\n.pagination-small ul > li > span {\n  padding: 2px 10px;\n  font-size: 11.9px;\n}\n\n.pagination-mini ul > li > a,\n.pagination-mini ul > li > span {\n  padding: 0 6px;\n  font-size: 10.5px;\n}\n\n.pager {\n  margin: 20px 0;\n  text-align: center;\n  list-style: none;\n  *zoom: 1;\n}\n\n.pager:before,\n.pager:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.pager:after {\n  clear: both;\n}\n\n.pager li {\n  display: inline;\n}\n\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  -webkit-border-radius: 15px;\n     -moz-border-radius: 15px;\n          border-radius: 15px;\n}\n\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #999999;\n  cursor: default;\n  background-color: #fff;\n}\n\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  background-color: #000000;\n}\n\n.modal-backdrop.fade {\n  opacity: 0;\n}\n\n.modal-backdrop,\n.modal-backdrop.fade.in {\n  opacity: 0.8;\n  filter: alpha(opacity=80);\n}\n\n.modal {\n  position: fixed;\n  top: 10%;\n  left: 50%;\n  z-index: 1050;\n  width: 560px;\n  margin-left: -280px;\n  background-color: #ffffff;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, 0.3);\n  *border: 1px solid #999;\n  -webkit-border-radius: 6px;\n     -moz-border-radius: 6px;\n          border-radius: 6px;\n  outline: none;\n  -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);\n     -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);\n          box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);\n  -webkit-background-clip: padding-box;\n     -moz-background-clip: padding-box;\n          background-clip: padding-box;\n}\n\n.modal.fade {\n  top: -25%;\n  -webkit-transition: opacity 0.3s linear, top 0.3s ease-out;\n     -moz-transition: opacity 0.3s linear, top 0.3s ease-out;\n       -o-transition: opacity 0.3s linear, top 0.3s ease-out;\n          transition: opacity 0.3s linear, top 0.3s ease-out;\n}\n\n.modal.fade.in {\n  top: 10%;\n}\n\n.modal-header {\n  padding: 9px 15px;\n  border-bottom: 1px solid #eee;\n}\n\n.modal-header .close {\n  margin-top: 2px;\n}\n\n.modal-header h3 {\n  margin: 0;\n  line-height: 30px;\n}\n\n.modal-body {\n  position: relative;\n  max-height: 400px;\n  padding: 15px;\n  overflow-y: auto;\n}\n\n.modal-form {\n  margin-bottom: 0;\n}\n\n.modal-footer {\n  padding: 14px 15px 15px;\n  margin-bottom: 0;\n  text-align: right;\n  background-color: #f5f5f5;\n  border-top: 1px solid #ddd;\n  -webkit-border-radius: 0 0 6px 6px;\n     -moz-border-radius: 0 0 6px 6px;\n          border-radius: 0 0 6px 6px;\n  *zoom: 1;\n  -webkit-box-shadow: inset 0 1px 0 #ffffff;\n     -moz-box-shadow: inset 0 1px 0 #ffffff;\n          box-shadow: inset 0 1px 0 #ffffff;\n}\n\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.modal-footer:after {\n  clear: both;\n}\n\n.modal-footer .btn + .btn {\n  margin-bottom: 0;\n  margin-left: 5px;\n}\n\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n\n.tooltip {\n  position: absolute;\n  z-index: 1030;\n  display: block;\n  font-size: 11px;\n  line-height: 1.4;\n  opacity: 0;\n  filter: alpha(opacity=0);\n  visibility: visible;\n}\n\n.tooltip.in {\n  opacity: 0.8;\n  filter: alpha(opacity=80);\n}\n\n.tooltip.top {\n  padding: 5px 0;\n  margin-top: -3px;\n}\n\n.tooltip.right {\n  padding: 0 5px;\n  margin-left: 3px;\n}\n\n.tooltip.bottom {\n  padding: 5px 0;\n  margin-top: 3px;\n}\n\n.tooltip.left {\n  padding: 0 5px;\n  margin-left: -3px;\n}\n\n.tooltip-inner {\n  max-width: 200px;\n  padding: 8px;\n  color: #ffffff;\n  text-align: center;\n  text-decoration: none;\n  background-color: #000000;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n}\n\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-top-color: #000000;\n  border-width: 5px 5px 0;\n}\n\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-right-color: #000000;\n  border-width: 5px 5px 5px 0;\n}\n\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-left-color: #000000;\n  border-width: 5px 0 5px 5px;\n}\n\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-bottom-color: #000000;\n  border-width: 0 5px 5px;\n}\n\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1010;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  text-align: left;\n  white-space: normal;\n  background-color: #ffffff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  -webkit-border-radius: 6px;\n     -moz-border-radius: 6px;\n          border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n     -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  -webkit-background-clip: padding-box;\n     -moz-background-clip: padding;\n          background-clip: padding-box;\n}\n\n.popover.top {\n  margin-top: -10px;\n}\n\n.popover.right {\n  margin-left: 10px;\n}\n\n.popover.bottom {\n  margin-top: 10px;\n}\n\n.popover.left {\n  margin-left: -10px;\n}\n\n.popover-title {\n  padding: 8px 14px;\n  margin: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 18px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  -webkit-border-radius: 5px 5px 0 0;\n     -moz-border-radius: 5px 5px 0 0;\n          border-radius: 5px 5px 0 0;\n}\n\n.popover-title:empty {\n  display: none;\n}\n\n.popover-content {\n  padding: 9px 14px;\n}\n\n.popover .arrow,\n.popover .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n\n.popover .arrow {\n  border-width: 11px;\n}\n\n.popover .arrow:after {\n  border-width: 10px;\n  content: \"\";\n}\n\n.popover.top .arrow {\n  bottom: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-color: #999;\n  border-top-color: rgba(0, 0, 0, 0.25);\n  border-bottom-width: 0;\n}\n\n.popover.top .arrow:after {\n  bottom: 1px;\n  margin-left: -10px;\n  border-top-color: #ffffff;\n  border-bottom-width: 0;\n}\n\n.popover.right .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-right-color: #999;\n  border-right-color: rgba(0, 0, 0, 0.25);\n  border-left-width: 0;\n}\n\n.popover.right .arrow:after {\n  bottom: -10px;\n  left: 1px;\n  border-right-color: #ffffff;\n  border-left-width: 0;\n}\n\n.popover.bottom .arrow {\n  top: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-bottom-color: #999;\n  border-bottom-color: rgba(0, 0, 0, 0.25);\n  border-top-width: 0;\n}\n\n.popover.bottom .arrow:after {\n  top: 1px;\n  margin-left: -10px;\n  border-bottom-color: #ffffff;\n  border-top-width: 0;\n}\n\n.popover.left .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-left-color: #999;\n  border-left-color: rgba(0, 0, 0, 0.25);\n  border-right-width: 0;\n}\n\n.popover.left .arrow:after {\n  right: 1px;\n  bottom: -10px;\n  border-left-color: #ffffff;\n  border-right-width: 0;\n}\n\n.thumbnails {\n  margin-left: -20px;\n  list-style: none;\n  *zoom: 1;\n}\n\n.thumbnails:before,\n.thumbnails:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.thumbnails:after {\n  clear: both;\n}\n\n.row-fluid .thumbnails {\n  margin-left: 0;\n}\n\n.thumbnails > li {\n  float: left;\n  margin-bottom: 20px;\n  margin-left: 20px;\n}\n\n.thumbnail {\n  display: block;\n  padding: 4px;\n  line-height: 20px;\n  border: 1px solid #ddd;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);\n     -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);\n          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);\n  -webkit-transition: all 0.2s ease-in-out;\n     -moz-transition: all 0.2s ease-in-out;\n       -o-transition: all 0.2s ease-in-out;\n          transition: all 0.2s ease-in-out;\n}\n\na.thumbnail:hover,\na.thumbnail:focus {\n  border-color: #0088cc;\n  -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);\n     -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);\n          box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);\n}\n\n.thumbnail > img {\n  display: block;\n  max-width: 100%;\n  margin-right: auto;\n  margin-left: auto;\n}\n\n.thumbnail .caption {\n  padding: 9px;\n  color: #555555;\n}\n\n.media,\n.media-body {\n  overflow: hidden;\n  *overflow: visible;\n  zoom: 1;\n}\n\n.media,\n.media .media {\n  margin-top: 15px;\n}\n\n.media:first-child {\n  margin-top: 0;\n}\n\n.media-object {\n  display: block;\n}\n\n.media-heading {\n  margin: 0 0 5px;\n}\n\n.media > .pull-left {\n  margin-right: 10px;\n}\n\n.media > .pull-right {\n  margin-left: 10px;\n}\n\n.media-list {\n  margin-left: 0;\n  list-style: none;\n}\n\n.label,\n.badge {\n  display: inline-block;\n  padding: 2px 4px;\n  font-size: 11.844px;\n  font-weight: bold;\n  line-height: 14px;\n  color: #ffffff;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  white-space: nowrap;\n  vertical-align: baseline;\n  background-color: #999999;\n}\n\n.label {\n  -webkit-border-radius: 3px;\n     -moz-border-radius: 3px;\n          border-radius: 3px;\n}\n\n.badge {\n  padding-right: 9px;\n  padding-left: 9px;\n  -webkit-border-radius: 9px;\n     -moz-border-radius: 9px;\n          border-radius: 9px;\n}\n\n.label:empty,\n.badge:empty {\n  display: none;\n}\n\na.label:hover,\na.label:focus,\na.badge:hover,\na.badge:focus {\n  color: #ffffff;\n  text-decoration: none;\n  cursor: pointer;\n}\n\n.label-important,\n.badge-important {\n  background-color: #b94a48;\n}\n\n.label-important[href],\n.badge-important[href] {\n  background-color: #953b39;\n}\n\n.label-warning,\n.badge-warning {\n  background-color: #f89406;\n}\n\n.label-warning[href],\n.badge-warning[href] {\n  background-color: #c67605;\n}\n\n.label-success,\n.badge-success {\n  background-color: #468847;\n}\n\n.label-success[href],\n.badge-success[href] {\n  background-color: #356635;\n}\n\n.label-info,\n.badge-info {\n  background-color: #3a87ad;\n}\n\n.label-info[href],\n.badge-info[href] {\n  background-color: #2d6987;\n}\n\n.label-inverse,\n.badge-inverse {\n  background-color: #333333;\n}\n\n.label-inverse[href],\n.badge-inverse[href] {\n  background-color: #1a1a1a;\n}\n\n.btn .label,\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n\n.btn-mini .label,\n.btn-mini .badge {\n  top: 0;\n}\n\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n@-moz-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n@-ms-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n@-o-keyframes progress-bar-stripes {\n  from {\n    background-position: 0 0;\n  }\n  to {\n    background-position: 40px 0;\n  }\n}\n\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n.progress {\n  height: 20px;\n  margin-bottom: 20px;\n  overflow: hidden;\n  background-color: #f7f7f7;\n  background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));\n  background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9);\n  background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9);\n  background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9);\n  background-repeat: repeat-x;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n     -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n.progress .bar {\n  float: left;\n  width: 0;\n  height: 100%;\n  font-size: 12px;\n  color: #ffffff;\n  text-align: center;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #0e90d2;\n  background-image: -moz-linear-gradient(top, #149bdf, #0480be);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));\n  background-image: -webkit-linear-gradient(top, #149bdf, #0480be);\n  background-image: -o-linear-gradient(top, #149bdf, #0480be);\n  background-image: linear-gradient(to bottom, #149bdf, #0480be);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n     -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n  -webkit-transition: width 0.6s ease;\n     -moz-transition: width 0.6s ease;\n       -o-transition: width 0.6s ease;\n          transition: width 0.6s ease;\n}\n\n.progress .bar + .bar {\n  -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n     -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n          box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n}\n\n.progress-striped .bar {\n  background-color: #149bdf;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  -webkit-background-size: 40px 40px;\n     -moz-background-size: 40px 40px;\n       -o-background-size: 40px 40px;\n          background-size: 40px 40px;\n}\n\n.progress.active .bar {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n     -moz-animation: progress-bar-stripes 2s linear infinite;\n      -ms-animation: progress-bar-stripes 2s linear infinite;\n       -o-animation: progress-bar-stripes 2s linear infinite;\n          animation: progress-bar-stripes 2s linear infinite;\n}\n\n.progress-danger .bar,\n.progress .bar-danger {\n  background-color: #dd514c;\n  background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));\n  background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);\n  background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);\n  background-image: linear-gradient(to bottom, #ee5f5b, #c43c35);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);\n}\n\n.progress-danger.progress-striped .bar,\n.progress-striped .bar-danger {\n  background-color: #ee5f5b;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-success .bar,\n.progress .bar-success {\n  background-color: #5eb95e;\n  background-image: -moz-linear-gradient(top, #62c462, #57a957);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));\n  background-image: -webkit-linear-gradient(top, #62c462, #57a957);\n  background-image: -o-linear-gradient(top, #62c462, #57a957);\n  background-image: linear-gradient(to bottom, #62c462, #57a957);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);\n}\n\n.progress-success.progress-striped .bar,\n.progress-striped .bar-success {\n  background-color: #62c462;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-info .bar,\n.progress .bar-info {\n  background-color: #4bb1cf;\n  background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));\n  background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);\n  background-image: -o-linear-gradient(top, #5bc0de, #339bb9);\n  background-image: linear-gradient(to bottom, #5bc0de, #339bb9);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);\n}\n\n.progress-info.progress-striped .bar,\n.progress-striped .bar-info {\n  background-color: #5bc0de;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-warning .bar,\n.progress .bar-warning {\n  background-color: #faa732;\n  background-image: -moz-linear-gradient(top, #fbb450, #f89406);\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));\n  background-image: -webkit-linear-gradient(top, #fbb450, #f89406);\n  background-image: -o-linear-gradient(top, #fbb450, #f89406);\n  background-image: linear-gradient(to bottom, #fbb450, #f89406);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);\n}\n\n.progress-warning.progress-striped .bar,\n.progress-striped .bar-warning {\n  background-color: #fbb450;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.accordion {\n  margin-bottom: 20px;\n}\n\n.accordion-group {\n  margin-bottom: 2px;\n  border: 1px solid #e5e5e5;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n}\n\n.accordion-heading {\n  border-bottom: 0;\n}\n\n.accordion-heading .accordion-toggle {\n  display: block;\n  padding: 8px 15px;\n}\n\n.accordion-toggle {\n  cursor: pointer;\n}\n\n.accordion-inner {\n  padding: 9px 15px;\n  border-top: 1px solid #e5e5e5;\n}\n\n.carousel {\n  position: relative;\n  margin-bottom: 20px;\n  line-height: 1;\n}\n\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n\n.carousel-inner > .item {\n  position: relative;\n  display: none;\n  -webkit-transition: 0.6s ease-in-out left;\n     -moz-transition: 0.6s ease-in-out left;\n       -o-transition: 0.6s ease-in-out left;\n          transition: 0.6s ease-in-out left;\n}\n\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  line-height: 1;\n}\n\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n\n.carousel-inner > .active {\n  left: 0;\n}\n\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n\n.carousel-inner > .next {\n  left: 100%;\n}\n\n.carousel-inner > .prev {\n  left: -100%;\n}\n\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n\n.carousel-inner > .active.left {\n  left: -100%;\n}\n\n.carousel-inner > .active.right {\n  left: 100%;\n}\n\n.carousel-control {\n  position: absolute;\n  top: 40%;\n  left: 15px;\n  width: 40px;\n  height: 40px;\n  margin-top: -20px;\n  font-size: 60px;\n  font-weight: 100;\n  line-height: 30px;\n  color: #ffffff;\n  text-align: center;\n  background: #222222;\n  border: 3px solid #ffffff;\n  -webkit-border-radius: 23px;\n     -moz-border-radius: 23px;\n          border-radius: 23px;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n\n.carousel-control.right {\n  right: 15px;\n  left: auto;\n}\n\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #ffffff;\n  text-decoration: none;\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n\n.carousel-indicators {\n  position: absolute;\n  top: 15px;\n  right: 15px;\n  z-index: 5;\n  margin: 0;\n  list-style: none;\n}\n\n.carousel-indicators li {\n  display: block;\n  float: left;\n  width: 10px;\n  height: 10px;\n  margin-left: 5px;\n  text-indent: -999px;\n  background-color: #ccc;\n  background-color: rgba(255, 255, 255, 0.25);\n  border-radius: 5px;\n}\n\n.carousel-indicators .active {\n  background-color: #fff;\n}\n\n.carousel-caption {\n  position: absolute;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  padding: 15px;\n  background: #333333;\n  background: rgba(0, 0, 0, 0.75);\n}\n\n.carousel-caption h4,\n.carousel-caption p {\n  line-height: 20px;\n  color: #ffffff;\n}\n\n.carousel-caption h4 {\n  margin: 0 0 5px;\n}\n\n.carousel-caption p {\n  margin-bottom: 0;\n}\n\n.hero-unit {\n  padding: 60px;\n  margin-bottom: 30px;\n  font-size: 18px;\n  font-weight: 200;\n  line-height: 30px;\n  color: inherit;\n  background-color: #eeeeee;\n  -webkit-border-radius: 6px;\n     -moz-border-radius: 6px;\n          border-radius: 6px;\n}\n\n.hero-unit h1 {\n  margin-bottom: 0;\n  font-size: 60px;\n  line-height: 1;\n  letter-spacing: -1px;\n  color: inherit;\n}\n\n.hero-unit li {\n  line-height: 30px;\n}\n\n.pull-right {\n  float: right;\n}\n\n.pull-left {\n  float: left;\n}\n\n.hide {\n  display: none;\n}\n\n.show {\n  display: block;\n}\n\n.invisible {\n  visibility: hidden;\n}\n\n.affix {\n  position: fixed;\n}\n"
  },
  {
    "path": "src/css/lib/fiddler.css",
    "content": "html,body{\n    width: 100%;\n    height: 100%;\n    overflow: hidden;\n}\n.icon.disabled{\n    opacity: 0.4;\n}\n"
  },
  {
    "path": "src/css/lib/shCoreDefault.css",
    "content": "/**\n * SyntaxHighlighter\n * http://alexgorbatchev.com/SyntaxHighlighter\n *\n * SyntaxHighlighter is donationware. If you are using it, please donate.\n * http://alexgorbatchev.com/SyntaxHighlighter/donate.html\n *\n * @version\n * 3.0.83 (July 02 2010)\n * \n * @copyright\n * Copyright (C) 2004-2010 Alex Gorbatchev.\n *\n * @license\n * Dual licensed under the MIT and GPL licenses.\n */\n.syntaxhighlighter a,\n.syntaxhighlighter div,\n.syntaxhighlighter code,\n.syntaxhighlighter table,\n.syntaxhighlighter table td,\n.syntaxhighlighter table tr,\n.syntaxhighlighter table tbody,\n.syntaxhighlighter table thead,\n.syntaxhighlighter table caption,\n.syntaxhighlighter textarea {\n  -moz-border-radius: 0 0 0 0 !important;\n  -webkit-border-radius: 0 0 0 0 !important;\n  background: none !important;\n  border: 0 !important;\n  bottom: auto !important;\n  float: none !important;\n  height: auto !important;\n  left: auto !important;\n  line-height: 1.1em !important;\n  margin: 0 !important;\n  outline: 0 !important;\n  overflow: visible !important;\n  padding: 0 !important;\n  position: static !important;\n  right: auto !important;\n  text-align: left !important;\n  top: auto !important;\n  vertical-align: baseline !important;\n  width: auto !important;\n  box-sizing: content-box !important;\n  font-family: \"Consolas\", \"Bitstream Vera Sans Mono\", \"Courier New\", Courier, monospace !important;\n  font-weight: normal !important;\n  font-style: normal !important;\n  font-size: 1em !important;\n  min-height: inherit !important;\n  min-height: auto !important;\n}\n\n.syntaxhighlighter {\n  width: 100% !important;\n  margin: 1em 0 1em 0 !important;\n  position: relative !important;\n  overflow: auto !important;\n  font-size: 1em !important;\n}\n.syntaxhighlighter.source {\n  overflow: hidden !important;\n}\n.syntaxhighlighter .bold {\n  font-weight: bold !important;\n}\n.syntaxhighlighter .italic {\n  font-style: italic !important;\n}\n.syntaxhighlighter .line {\n  white-space: pre !important;\n}\n.syntaxhighlighter table {\n  width: 100% !important;\n}\n.syntaxhighlighter table caption {\n  text-align: left !important;\n  padding: .5em 0 0.5em 1em !important;\n}\n.syntaxhighlighter table td.code {\n  width: 100% !important;\n}\n.syntaxhighlighter table td.code .container {\n  position: relative !important;\n}\n.syntaxhighlighter table td.code .container textarea {\n  box-sizing: border-box !important;\n  position: absolute !important;\n  left: 0 !important;\n  top: 0 !important;\n  width: 100% !important;\n  height: 100% !important;\n  border: none !important;\n  background: white !important;\n  padding-left: 1em !important;\n  overflow: hidden !important;\n  white-space: pre !important;\n}\n.syntaxhighlighter table td.gutter .line {\n  text-align: right !important;\n  padding: 0 0.5em 0 1em !important;\n}\n.syntaxhighlighter table td.code .line {\n  padding: 0 1em !important;\n}\n.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {\n  padding-left: 0em !important;\n}\n.syntaxhighlighter.show {\n  display: block !important;\n}\n.syntaxhighlighter.collapsed table {\n  display: none !important;\n}\n.syntaxhighlighter.collapsed .toolbar {\n  padding: 0.1em 0.8em 0em 0.8em !important;\n  font-size: 1em !important;\n  position: static !important;\n  width: auto !important;\n  height: auto !important;\n}\n.syntaxhighlighter.collapsed .toolbar span {\n  display: inline !important;\n  margin-right: 1em !important;\n}\n.syntaxhighlighter.collapsed .toolbar span a {\n  padding: 0 !important;\n  display: none !important;\n}\n.syntaxhighlighter.collapsed .toolbar span a.expandSource {\n  display: inline !important;\n}\n.syntaxhighlighter .toolbar {\n  position: absolute !important;\n  right: 1px !important;\n  top: 1px !important;\n  width: 11px !important;\n  height: 11px !important;\n  font-size: 10px !important;\n  z-index: 10 !important;\n}\n.syntaxhighlighter .toolbar span.title {\n  display: inline !important;\n}\n.syntaxhighlighter .toolbar a {\n  display: block !important;\n  text-align: center !important;\n  text-decoration: none !important;\n  padding-top: 1px !important;\n}\n.syntaxhighlighter .toolbar a.expandSource {\n  display: none !important;\n}\n.syntaxhighlighter.ie {\n  font-size: .9em !important;\n  padding: 1px 0 1px 0 !important;\n}\n.syntaxhighlighter.ie .toolbar {\n  line-height: 8px !important;\n}\n.syntaxhighlighter.ie .toolbar a {\n  padding-top: 0px !important;\n}\n.syntaxhighlighter.printing .line.alt1 .content,\n.syntaxhighlighter.printing .line.alt2 .content,\n.syntaxhighlighter.printing .line.highlighted .number,\n.syntaxhighlighter.printing .line.highlighted.alt1 .content,\n.syntaxhighlighter.printing .line.highlighted.alt2 .content {\n  background: none !important;\n}\n.syntaxhighlighter.printing .line .number {\n  color: #bbbbbb !important;\n}\n.syntaxhighlighter.printing .line .content {\n  color: black !important;\n}\n.syntaxhighlighter.printing .toolbar {\n  display: none !important;\n}\n.syntaxhighlighter.printing a {\n  text-decoration: none !important;\n}\n.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {\n  color: black !important;\n}\n.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {\n  color: #008200 !important;\n}\n.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {\n  color: blue !important;\n}\n.syntaxhighlighter.printing .keyword {\n  color: #006699 !important;\n  font-weight: bold !important;\n}\n.syntaxhighlighter.printing .preprocessor {\n  color: gray !important;\n}\n.syntaxhighlighter.printing .variable {\n  color: #aa7700 !important;\n}\n.syntaxhighlighter.printing .value {\n  color: #009900 !important;\n}\n.syntaxhighlighter.printing .functions {\n  color: #ff1493 !important;\n}\n.syntaxhighlighter.printing .constants {\n  color: #0066cc !important;\n}\n.syntaxhighlighter.printing .script {\n  font-weight: bold !important;\n}\n.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {\n  color: gray !important;\n}\n.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {\n  color: #ff1493 !important;\n}\n.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {\n  color: red !important;\n}\n.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {\n  color: black !important;\n}\n\n.syntaxhighlighter {\n  background-color: white !important;\n}\n.syntaxhighlighter .line.alt1 {\n  background-color: white !important;\n}\n.syntaxhighlighter .line.alt2 {\n  background-color: white !important;\n}\n.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {\n  background-color: #e0e0e0 !important;\n}\n.syntaxhighlighter .line.highlighted.number {\n  color: black !important;\n}\n.syntaxhighlighter table caption {\n  color: black !important;\n}\n.syntaxhighlighter .gutter {\n  color: #afafaf !important;\n}\n.syntaxhighlighter .gutter .line {\n  border-right: 3px solid #6ce26c !important;\n}\n.syntaxhighlighter .gutter .line.highlighted {\n  background-color: #6ce26c !important;\n  color: white !important;\n}\n.syntaxhighlighter.printing .line .content {\n  border: none !important;\n}\n.syntaxhighlighter.collapsed {\n  overflow: visible !important;\n}\n.syntaxhighlighter.collapsed .toolbar {\n  color: blue !important;\n  background: white !important;\n  border: 1px solid #6ce26c !important;\n}\n.syntaxhighlighter.collapsed .toolbar a {\n  color: blue !important;\n}\n.syntaxhighlighter.collapsed .toolbar a:hover {\n  color: red !important;\n}\n.syntaxhighlighter .toolbar {\n  color: white !important;\n  background: #6ce26c !important;\n  border: none !important;\n}\n.syntaxhighlighter .toolbar a {\n  color: white !important;\n}\n.syntaxhighlighter .toolbar a:hover {\n  color: black !important;\n}\n.syntaxhighlighter .plain, .syntaxhighlighter .plain a {\n  color: black !important;\n}\n.syntaxhighlighter .comments, .syntaxhighlighter .comments a {\n  color: #008200 !important;\n}\n.syntaxhighlighter .string, .syntaxhighlighter .string a {\n  color: blue !important;\n}\n.syntaxhighlighter .keyword {\n  color: #006699 !important;\n}\n.syntaxhighlighter .preprocessor {\n  color: gray !important;\n}\n.syntaxhighlighter .variable {\n  color: #aa7700 !important;\n}\n.syntaxhighlighter .value {\n  color: #009900 !important;\n}\n.syntaxhighlighter .functions {\n  color: #ff1493 !important;\n}\n.syntaxhighlighter .constants {\n  color: #0066cc !important;\n}\n.syntaxhighlighter .script {\n  font-weight: bold !important;\n  color: #006699 !important;\n  background-color: none !important;\n}\n.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {\n  color: gray !important;\n}\n.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {\n  color: #ff1493 !important;\n}\n.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {\n  color: red !important;\n}\n\n.syntaxhighlighter .keyword {\n  font-weight: bold !important;\n}\n"
  },
  {
    "path": "src/css/lib.css",
    "content": "@import url(\"lib/bootstrap.css\");\n@import url(\"lib/fiddler.css\");\n@import url(\"lib/shCoreDefault.css\");"
  },
  {
    "path": "src/css/page/options.css",
    "content": ".table tr.disabled{\n    background: #eee;\n    color: #999;\n}\n\n#fiddler{\n    padding: 0 2px;\n}\nheader.navbar{\n    margin-bottom: 5px;\n}\n#requestList{\n    position: fixed;\n    top: 50px;\n    left: 2px;\n    right: 2px;\n    bottom: 0px;\n    overflow: auto;\n}\n#requestList tbody tr a.icon-url{\n    display: none;\n}\n#requestList tbody tr.err{\n    color: red;\n}\n#requestList tbody tr.get:hover a.icon-url{\n    display: inline;\n}\n.disable-cache{\n    position: relative;\n    top: -4px;\n}\n#requestDetail{\n    position: fixed;\n    display: block;\n    top: 50px;\n    right: -600px;\n    width: 600px;\n    bottom: 0;\n    background: #fff;\n    border-left:1px solid #dddddd;\n    border-top-right-radius: 4px;\n    -webkit-box-shadow: 0 0 5px 0 #eee;\n    opacity: 0;\n    -webkit-transition: all 0.3s linear;\n}\n#requestDetail.open{\n    right: 2px;\n    opacity: 1;\n}\n#requestDetail .icon-remove{\n    position: absolute;\n    top: 10px;\n    left: 10px;\n    cursor: pointer;\n}\n#requestDetail .hd{\n    background:#fefefe;\n    position:relative;\n    height: 38px;\n    overflow: hidden;\n}\n#requestDetail .tab-content{\n    overflow: auto;\n    position: absolute;\n    top: 38px;\n    bottom: 0;\n    left: 0;\n    right: 0;\n}\n#tab-headers, #tab-preview,#tab-response,#tab-beautify{\n    padding: 10px 20px;\n    width: 550px;\n    word-wrap: break-word;\n}\n#tab-beautify{\n    padding: 0;\n    width: 590px;\n}\n#tab-headers .content .item{\n    width: 550px;\n    word-wrap: break-word;\n}\n#tab-headers .content .item b{\n    color: #666;\n    font-size: 13px;\n}\n#tab-headers .content>b{\n    display: block;\n    margin-top: 5px;\n    font-size: 14px;\n    padding-left: 10px;\n    background: url(../../img/treeDown.png) no-repeat left center;\n    cursor: pointer;\n    margin-left: -10px;\n    -webkit-user-select: none;\n}\n#tab-headers .content>b span.num{\n    display: none;\n    color: #666;\n    font-size: 12px;\n    font-weight: normal;\n}\n#tab-headers .content .headers-list{\n    padding-left: 10px;\n}\n#tab-headers .content>b.treeRight{\n    background-image: url(../../img/treeRight.png);\n}\n#tab-headers .content>b.treeRight .num{\n    display: inline;\n}\n#requestDetail .tab-content .tab-pane{\n    display: none;\n}\n#requestDetail .tab-content .tab-pane.active{\n    display: block;\n}\n#tab-preview img{\n    display: block;\n    margin: auto;\n    box-shadow: 1px 1px 5px #ccc;\n    max-width: 560px;\n    margin-bottom: 5px;\n}\n#tab-preview code{\n    white-space: normal !important;\n}\n#tab-preview .syntaxhighlighter code{\n    width: auto !important;\n}\n#tab-preview .syntaxhighlighter .line{\n    width: 550px !important;\n    overflow: auto !important;\n}\n\n\n\n\n\n#autoResponseList{\n    position: fixed;\n    top: 40px;\n    right: 20px;\n    width: 560px;\n    bottom: 20px;\n    z-index: 1000;\n    background: #fff;\n    left: auto;\n    padding: 10px;\n    max-width: 600px;\n    display: block;;\n    -webkit-transform: scale(0);\n    opacity: 0;\n    -webkit-transition: all 0.3s cubic-bezier(.4,.83,.32,1.33);\n    -webkit-transform-origin: right top;\n}\n#autoResponseList.open{\n    opacity: 1;\n    -webkit-transform: scale(1);\n}\n#autoResponseList .arrow{\n    left: auto;\n    right: 50px;\n}\n#autoResponseList .hd{\n    height: 40px;\n    line-height: 40px;\n    -webkit-user-select: none;\n}\n#autoResponseList .hd label{\n    margin-left: 7px;\n    height: 40px;\n    line-height: 40px;\n}\n#autoResponseList .hd label input{\n    position: relative;\n    top: -2px;\n}\n#autoResponseList .btn-add{\n    position: absolute;\n    right: 10px;\n    top: 15px;\n}\n\n#autoResponseList .rule-list{\n    position: absolute;\n    bottom: 150px;\n    overflow: auto;\n    top: 50px;\n    width: 560px;\n}\n#autoResponseList .rule-list p.pattern{\n    width: 200px;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    white-space: nowrap;\n}\n#autoResponseList .rule-list p.replace{\n    width: 210px;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    white-space: nowrap;\n}\n#autoResponseList .rule-list .rule-check{\n    position: relative;\n    top: -2px;\n}\n\n#autoResponseList .rule-edit{\n    position: absolute;\n    bottom: 10px;\n    left: 10px;\n    right: 10px;\n    background: #fff;\n}\n#autoResponseList .rule-edit .name{\n    display: inline-block;\n    width: 70px;\n    text-align: right;\n    padding-right: 10px;\n}\n#autoResponseList .rule-edit input.rule-pattern-type,\n#autoResponseList .rule-edit input.rule-replace-type{\n    width: 60px;\n    padding-right: 40px;\n    padding-left: 10px;\n}\n#autoResponseList .rule-edit input.rule-pattern,\n#autoResponseList .rule-edit input.rule-replace{\n    margin-left: -30px;\n    width: 226px;\n}\n#autoResponseList .rule-edit .btn-save{\n    position: absolute;\n    right: 10px;\n    bottom: 20px;\n}\n#autoResponseList .rule-edit .btn-select{\n    position:relative;top:-5px;left:-40px\n}\n#autoResponseList .rule-edit .rule-edit-item{\n    position: relative;\n}\n#autoResponseList .rule-edit .dropdown-menu{\n    top: auto;\n    display: none;\n    bottom: 40px;\n    left: 83px;\n    width: 20px;\n    min-width: 110px;\n    -webkit-box-shadow: 0 0 0 #000;\n}\n#autoResponseList .rule-edit .dropdown-menu > li > a{\n    padding: 3px 10px;\n}\n#autoResponseList .rule-edit .dropdown-menu li{\n    position: relative;\n}\n#autoResponseList .rule-edit .dropdown-menu li input[type=\"file\"]{\n    position: absolute;\n    top: 0px;\n    z-index: 100;\n    opacity: 0;\n}\n\n"
  },
  {
    "path": "src/html/background.html",
    "content": "<!DOCTYPE html> \n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Fiddler</title>\n<script type=\"text/javascript\" src=\"../js/page/background.js\"></script>\n</head>\n<body>\n\n\n</body>\n</html>"
  },
  {
    "path": "src/html/devtools.html",
    "content": "<!DOCTYPE html> \n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Fiddler</title>\n<script type=\"text/javascript\" src=\"../js/lib/fiddler.js\"></script>\n<script type=\"text/javascript\" src=\"../js/page/devtools.js\"></script>\n</head>\n<body>\n</body>\n</html>"
  },
  {
    "path": "src/html/options.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<title>Fiddler</title>\n<link href=\"../css/lib.css\" type=\"text/css\" rel=\"stylesheet\" />\n<link href=\"../css/page/options.css\" type=\"text/css\" rel=\"stylesheet\"/>\n</head>\n<body>\n  <div id=\"fiddler\">\n<header id=\"navbar-example\" class=\"navbar navbar-static\">\n  <div class=\"navbar-inner\">\n    <div class=\"container\" style=\"width: auto;\">\n      <a class=\"brand\" href=\"#\">Fiddler</a>\n      <ul class=\"nav\" role=\"navigation\">\n        <li class=\"dropdown\">\n          <a id=\"filterMenuTitle\" href=\"#\" role=\"button\" class=\"dropdown-toggle\" data-toggle=\"dropdown\"><span>Filter ( All )</span> <b class=\"caret\"></b></a>\n          <ul class=\"dropdown-menu\" id=\"filterMenu\">\n            <li class=\"disabled\"><a href=\"#\" data-type=\"\">All</a></li>\n            <li><a href=\"#\" data-type=\"main_frame\">Documents</a></li>\n            <li><a href=\"#\" data-type=\"stylesheet\">Stylesheets</a></li>\n            <li><a href=\"#\" data-type=\"script\">Scripts</a></li>\n            <li><a href=\"#\" data-type=\"image\">Images</a></li>\n            <li><a href=\"#\" data-type=\"xmlhttprequest\">XHR</a></li>\n            <li><a href=\"#\" data-type=\"font\">Font</a></li>\n            <li><a href=\"#\" data-type=\"other\">Other</a></li>\n          </ul>\n        </li>\n        <li class=\"dropdown\">\n          <a href=\"#\" id=\"tools\" role=\"button\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">Tools <b class=\"caret\"></b></a>\n          <ul class=\"dropdown-menu\" role=\"menu\" id=\"toolsMenu\" aria-labelledby=\"tools\">\n            <li role=\"presentation\">\n              <a role=\"menuitem\" tabindex=\"-1\" href=\"#\" class=\"clear\">Clear</a>\n            </li>\n            <li class=\"divider\"></li>\n            <li role=\"presentation\">\n              <a role=\"menuitem\" tabindex=\"-1\" href=\"#\">\n                <label><input type=\"checkbox\" name=\"diable-cache\" id=\"disabledCacheInput\" class=\"disable-cache\" /> \n                Disable Cache</label>\n              </a>\n            </li>\n            <!--<li class=\"divider\"></li>\n            <li role=\"presentation\" class=\"dropdown-submenu\">\n              <a role=\"menuitem\" tabindex=\"-1\" href=\"#\">User Agent</a>\n              <ul class=\"dropdown-menu\">\n                <li class=\"disabled\"><a tabindex=\"-1\" href=\"#\" data-type=\"default\">Default</a></li>\n                <li class=\"divider\"></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"firefox-windows\">Firefox Windows</a></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"firefox-mac\">Firefox Mac</a></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"chrome-windows\">Chrome Windows</a></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"chrome-mac\">Chrome Mac</a></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"chrome-mobile\">Chrome Mobile</a></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"chrome-tablet\">Chrome Tablet</a></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"iphone-ios5\">iPhone iOS 5</a></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"ipad-ios5\">iPad iOS 5</a></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"ie9\">Internet Explorer 9</a></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"ie8\">Internet Explorer 8</a></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"ie7\">Internet Explorer 7</a></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"ie6\">Internet Explorer 6</a></li>\n                <li class=\"divider\"></li>\n                <li><a tabindex=\"-1\" href=\"#\" data-type=\"other\">Other</a></li>\n              </ul>\n            </li>-->\n          </ul>\n        </li>\n        <li class=\"dropdown\">\n          <a href=\"#\" id=\"drop2\" role=\"button\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">Help <b class=\"caret\"></b></a>\n          <ul class=\"dropdown-menu\" role=\"menu\" aria-labelledby=\"drop2\">\n            <li role=\"presentation\"><a role=\"menuitem\" tabindex=\"-1\" href=\"https://github.com/welefen/Fiddler\" target=\"_blank\">Fiddler Help</a></li>\n            <li role=\"presentation\" class=\"divider\"></li>\n            <li role=\"presentation\"><a role=\"menuitem\" tabindex=\"-1\" href=\"https://github.com/welefen/Fiddler\" target=\"_blank\">@Github</a></li>\n            <li role=\"presentation\"><a role=\"menuitem\" tabindex=\"-1\" href=\"https://github.com/welefen/Fiddler/issues\" target=\"_blank\">Feedback</a></li>\n            <li role=\"presentation\" class=\"divider\"></li>\n            <li role=\"presentation\">\n              <a role=\"menuitem\" data-target=\"#aboutModal\" data-toggle=\"modal\" tabindex=\"-1\" href=\"#\">About\n              </a>\n            </li>\n          </ul>\n        </li>\n      </ul>\n      <ul class=\"nav pull-right\">\n        <li id=\"fat-menu\" class=\"dropdown\">\n          <button class=\"btn btn-success btn-primary\" data-toggle=\"popover\" data-placement=\"bottom\" title=\"\" data-original-title=\"Popover on top\" id=\"autoResponseBtn\">Auto Response</button>\n        </li>\n      </ul>\n    </div>\n  </div>\n</header>\n\n\n<div id=\"requestList\">\n<table class=\"table table-bordered table-hover\">\n  <thead>\n    <tr>\n      <th width=\"40\">Type</th>\n      <th width=\"30\">Status</th>\n      <th width=\"30\">Method</th>\n      <th>Url</th>\n      <th width=\"300\">Host</th>\n      <th width=\"100\">Ip</th>\n      <th width=\"40\">Size</th>\n    </tr>\n  </thead>\n  <tbody>\n\n  </tbody>\n</table>\n</div>\n\n<div id=\"requestDetail\">\n  <div class=\"hd\">\n    <i class=\"icon-remove\" class=\"close\"></i>\n    <ul class=\"nav nav-tabs\" id=\"myTab\" style=\"padding-left:36px;\">\n      <li class=\"active\" data-type=\"headers\"><a href=\"#headers\">Headers</a></li>\n      <li data-type=\"preview\"><a href=\"#preview\" >Preview</a></li>\n      <li data-type=\"response\"><a href=\"#response\" >Response</a></li>\n      <li data-type=\"beautify\"><a href=\"#beautify\" >Beautify</a></li>\n    </ul>\n</div>\n   \n  <div class=\"tab-content\">\n    <div class=\"tab-pane active\" id=\"tab-headers\"></div>\n    <div class=\"tab-pane\" id=\"tab-preview\"></div>\n    <div class=\"tab-pane\" id=\"tab-response\"></div>\n    <div class=\"tab-pane\" id=\"tab-beautify\"></div>\n  </div>\n\n </div>\n\n <div id=\"autoResponseList\" class=\"popover bottom fade in\">\n  <div class=\"arrow\"></div>\n  <div class=\"hd\">\n     <label><input type=\"checkbox\" checked id=\"enableAutoResponse\" /> Enable Auto Response</label>\n     <button class=\"btn btn-add\">add</button>\n  </div>\n  <div class=\"rule-list\">\n    <table class=\"table\">\n      <thead>\n        <tr>\n          <th width=\"46\">Enable</th>\n          <th width=\"203\">If Request Matches...</th>\n          <th width=\"214\">The Response With...</th>\n          <th width=\"33\">Edit</th>\n        </tr>\n      </thead>\n      <tbody>\n\n      </tbody>\n    </table>\n  </div>\n\n  <div class=\"rule-edit\">\n    <fieldset>\n      <legend>Rule Editor</legend>\n\n      <div class=\"rule-edit-item\">\n        <span class=\"name\">Pattern:</span> \n        <input id=\"rulePatternType\" type=\"text\" value=\"String\" readonly=\"true\" class=\"rule-input rule-pattern-type\"><a class=\"btn btn-select\" href=\"#\"><i class=\"icon-chevron-down\"></i></a>\n        <input type=\"text\" class=\"rule-pattern rule-value\" id=\"rulePattern\">\n        <ul class=\"dropdown-menu\" id=\"patternMenu\" role=\"menu\" aria-labelledby=\"dropdownMenu\">\n          <li><a tabindex=\"-1\" href=\"#\" data-type=\"string\" data-value=\"http://www.example.com/xxx/a.html\">String</a></li>\n          <li><a tabindex=\"-1\" href=\"#\" data-type=\"regexp\" data-value=\"^http:.*\\.png$\">Regexp</a></li>\n          <li><a tabindex=\"-1\" href=\"#\" data-type=\"method\" data-value=\"POST\">Method</a></li>\n          <li><a tabindex=\"-1\" href=\"#\" data-type=\"header\" data-value=\"accept=text/html\">Header</a></li>\n          </li>\n        </ul>\n      </div>\n\n      <div class=\"rule-edit-item\">\n        <span class=\"name\">Replace:</span> \n        <input id=\"ruleReplaceType\" type=\"text\" value=\"File\" readonly=\"true\" class=\"rule-input rule-replace-type\"><a class=\"btn btn-select\" href=\"#\"><i class=\"icon-chevron-down\"></i></a>\n        <input id=\"ruleReplace\" type=\"text\" class=\"rule-replace rule-value\" id=\"patternInput\">\n        <ul class=\"dropdown-menu\" id=\"replaceMenu\" role=\"menu\" aria-labelledby=\"dropdownMenu\">\n          <li><a tabindex=\"-1\" href=\"#\" data-type=\"delay\" data-value=\"100ms\">Delay</a></li>\n          <li><a tabindex=\"-1\" href=\"#\" data-type=\"header\" data-value=\"newHeader=newValue\">Header</a></li>\n          <li><a tabindex=\"-1\" href=\"#\" data-type=\"cancel\" data-value=\"\">Cancel</a></li>\n          <li><a tabindex=\"-1\" href=\"#\" data-type=\"redirect\" data-value=\"http://www.example.com/foo/bar/x.html\">Redirect</a></li>\n          <li><a tabindex=\"-1\" href=\"#\" data-type=\"path\" data-value=\"file:///Users/welefen/xxx/\">Path</a></li>\n          <li><a tabindex=\"-1\" href=\"#\" data-type=\"file\" data-value=\"file:///Users/welefen/a.js\">File</a>\n          </li>\n        </ul>\n      </div>\n\n      <button class=\"btn btn-large btn-primary btn-save\" type=\"button\">Save</button>\n    </fieldset>\n  </div>\n\n </div>\n</div>\n\n<div id=\"aboutModal\" class=\"modal hide fade\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\" aria-hidden=\"true\">\n  <div class=\"modal-header\">\n    <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n    <h3 id=\"myModalLabel\">About</h3>\n  </div>\n  <div class=\"modal-body\">\n    <p>Fiddler v1.0.1 - by \n      <a href=\"http://www.welefen.com/about\" target=\"_blank\">welefen</a>&nbsp;&nbsp;\n      <a href=\"http://icewhite.us/\" target=\"_blank\">IceWhite</a>\n    </p>\n    <p>Thanks For these Apps: </p>\n    <ul>\n        <li><a href=\"http://twitter.github.io/bootstrap/index.html\">Bootstrap</a></li>\n        <li><a href=\"http://jquery.com/\" target=\"_blank\">jQuery</a></li>\n        <li><a href=\"http://qwrap.com/\" target=\"_blank\">Qwrap</a></li>\n        <li><a href=\"https://github.com/cujojs/when\" target=\"_blank\">When.js</a></li>\n        <li><a href=\"http://jsbeautifier.org/\" target=\"_blank\">JS Beautify</a></li>\n        <li><a href=\"http://alexgorbatchev.com/SyntaxHighlighter/\" target=\"_blank\">Syntax Highlighter</a></li>\n    </ul>\n  </div>\n  <div class=\"modal-footer\">\n    <button class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">Close</button>\n  </div>\n</div>\n\n\n<script id=\"requestItemTpl\" type=\"text/html\">\n<tr class=\" {$lowerMethod} {$err}\" style=\"{$display}\" data-type=\"{$type}\" data-id=\"{$requestId}\" data-pid=\"{$parentRequestId}\">\n    <td>\n        &nbsp;&nbsp;\n        <img src=\"{$img}\" class=\"type\">\n    </td>\n    <td>{$statusCode}</td>\n    <td>{$method}</td>\n    <td class=\"url\">\n        {$shortPath}\n        <a class=\"icon-url\" title=\"open on new tab\" href=\"{$url}\" target=\"_blank\">\n            <i class=\"icon-share\"></i>\n        </a>\n    </td>\n    <td>{$host}</td>\n    <td>{$ip}</td>\n    <td>{$humanSize}</td>\n</tr>\n</script>\n\n<script id=\"ruleItemTpl\" type=\"text/html\">\n<tr>\n    <td><input type=\"checkbox\" {$checked} name=\"ruleCheck\" class=\"rule-check\" /></td>\n    <td><p class=\"pattern\">{$pattern}</p></td>\n    <td><p class=\"replace\">{$replace}</p></td>\n    <td><i class=\"icon icon-edit\"></i> <i class=\"icon icon-remove\"></i></td>\n</tr>\n</script>\n\n<script id=\"headersTpl\" type=\"text/html\">\n<div class=\"content\">\n  <div class=\"item\"><b>Request URL:</b> {$url}</div>\n  <div class=\"item\"><b>Request Method:</b> {$method}</div>\n  <div class=\"item\"><b>Status Code:</b> <span {if ($statusCode >= 400)}style=\"color:red\"{/if}>{$statusCode}</span></div>\n\n  {if(opts.queryUrl)}\n  <b>Query Url <span class=\"num\">({opts.queryUrlLength})</span></b>\n  <div class=\"headers-list\">\n    {for(var name in opts.queryUrl)}\n      <div class=\"item\"><b>{name}:</b> {opts.queryUrl[name]}</div>\n    {/for}\n  </div>\n  {/if}\n\n  {if(opts.formData)}\n  <b>Form Data <span class=\"num\">({opts.formDataLength})</span></b>\n  <div class=\"headers-list\">\n    {for(var name in opts.formData)}\n      <div class=\"item\"><b>{name}:</b> {=opts.formData[name]}</div>\n    {/for}\n  </div>\n  {/if}\n\n  {if(opts.cookie)}\n  <b class=\"treeRight\">Cookie <span class=\"num\">({opts.cookieLength}) {opts.cookieSize}byte</span></b>\n  <div  class=\"headers-list\" style=\"display:none\">\n    {for(var name in opts.cookie)}\n      <div class=\"item\"><b>{name}:</b> {opts.cookie[name]}</div>\n    {/for}\n  </div>\n  {/if}\n\n  <b>Request Headers <span class=\"num\">({opts.requestHeaders.length})</span></b>\n  <div  class=\"headers-list\">\n    {for(var i=0;i<opts.requestHeaders.length;i++)}\n      <div class=\"item\"><b>{opts.requestHeaders[i].name}:</b> {opts.requestHeaders[i].value}</div>\n    {/for}\n  </div>\n  <b>Response Headers <span class=\"num\">({opts.responseHeaders.length})</span></b>\n  <div  class=\"headers-list\">\n    {for(var i=0;i<opts.responseHeaders.length;i++)}\n      <div class=\"item\"><b>{opts.responseHeaders[i].name}:</b> {opts.responseHeaders[i].value}</div>\n    {/for}\n  </div>\n</div>\n</script>\n\n<script id=\"imagePreviewTpl\" type=\"text/html\">\n<div class=\"content\" >\n<div style=\"text-align: center\">\n  <img src=\"{$imgUrl}\" />\n  {$filename}\n</div>\n<table style=\"margin-top:20px;width:100%;\">\n  <tr><td align=\"right\" width=\"40%\" style=\"padding-right:10px;\"><b>Dimensions</b></td><td  width=\"60%\">{$width} x {$height}</td></tr>\n  <tr><td align=\"right\" style=\"padding-right:10px;\"><b>File size</b></td><td>{$filesize}</td></tr>\n  <tr><td align=\"right\" style=\"padding-right:10px;\"><b>URL</b></td><td><a href=\"{$url}\" target=\"_blank\">{$display_url}</a></td></tr>\n</table>\n</div>\n</script>\n<!--<embed type=\"application/x-chromefiddler\" id=\"chromefiddler\" style=\"width:1px;height:1px;opacity:0;\">-->\n<script src=\"../js/lib.js\"></script>\n<script src=\"../js/component.js\"></script>\n<script src=\"../js/page/options.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "src/js/component/config.js",
    "content": "var Fiddler_Config = function(){\n    \"use strict\";\n    var config = {\n        encoding: \"utf-8\",\n        enable_auto_response: true,\n        disable_cache: false,\n        rules: []\n    };\n    var _key = \"Fiddler\";\n    return {\n        init: function(){\n            this.loadConfig();\n        },\n        clearRules: function(){\n            config.rules = [];\n        },\n        getEncoding: function(){\n            return config.encoding;\n        },\n        setEncoding: function(encoding){\n            config.encoding = encoding;\n            return this;\n        },\n        getConfig: function(name){\n            return config[name] || \"\";\n        },\n        setConfig: function(name, value){\n            config[name] = value;\n            this.saveConfig();\n        },\n        addRule: function(data){\n           config.rules.push(data);\n           this.saveConfig();\n        },\n        getRules: function(){\n            return config.rules || [];\n        },\n        loadConfig: function(){\n            var data = localStorage.getItem(_key) || \"{}\";\n            data = JSON.parse(data);\n            Fiddler.mix(config, data, true);\n        },\n        saveConfig: function(){\n            var data = JSON.stringify(config);\n            localStorage.setItem(_key, data);\n        }\n    }\n}();"
  },
  {
    "path": "src/js/component/event.js",
    "content": "/**\n * 事件相关\n * @return {[type]} [description]\n */\nvar Fiddler_Event = function(){\n    \"use strict\";\n    function init(cleanCheckHandler){\n        \n        chrome.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES = 10000;\n\n        chrome.webRequest.onBeforeRequest.addListener(function(details) {\n\n            if (!Fiddler.checkUrl(details.url)) {\n                return {};\n            };\n            var result = Fiddler_Rule.fireSome(\"onBeforeRequest\", details);\n            if (result) {\n                return result;\n            };\n           }, {urls:[\"<all_urls>\"]}, [\"blocking\", \"requestBody\"] \n        );\n        chrome.webRequest.onBeforeSendHeaders.addListener(function(details) {\n            if (!Fiddler.checkUrl(details.url)) {\n                return {};\n            };\n            var result = Fiddler_Rule.fireMerge(\"onBeforeSendHeaders\", details);\n            if (result) {\n                if (result.cancel) {\n                    return {\n                        cancel: true\n                    }\n                };\n                return {\n                    requestHeaders: result.requestHeaders\n                };\n            };\n          }, {urls: [\"<all_urls>\"]}, [\"blocking\", \"requestHeaders\"]\n        );\n        chrome.webRequest.onCompleted.addListener(function(details) {\n            //clean memory cache\n            if (details.type == 'main_frame' && cleanCheckHandler && cleanCheckHandler()) {\n                //chrome.webRequest.handlerBehaviorChanged();\n            };\n\n            if (!Fiddler.checkUrl(details.url)) {\n                return {};\n            };\n            Fiddler_Rule.fire(\"onCompleted\", details);\n        }, {urls: [\"<all_urls>\"]}, [\"responseHeaders\"]);\n    }\n    return {\n        init: init\n    }\n}();"
  },
  {
    "path": "src/js/component/file.js",
    "content": "/**\n * 文件读取相关\n */\nvar Fiddler_File = function(){\n    \"use strict\";\n    /**\n     * [encodeText description]\n     * @param  {[type]} text [description]\n     * @param  {[type]} type [description]\n     * @return {[type]}      [description]\n     */\n    function encodeText(text, type){\n        if (type == 'script') {\n            text = text.replace(/[\\u0080-\\uffff]/g, function($0) {\n                var tmp = $0.charCodeAt(0).toString(16);\n                return \"\\\\u\" + new Array(5 - tmp.length).join('0') + tmp;\n            });\n        };\n        if (type == 'main_frame') {\n            //text = btoa(text)\n        }else{\n            text = encodeURIComponent(text);\n        }\n        return text;\n    }\n    function getMimeType(file) {\n        var idx = file.lastIndexOf(\".\");\n        return (idx == -1) ? \"text/plain\" : MimeTea.cup(file.substring(++idx));\n    }\n    return {\n        /**\n         * get local file content by xhr\n         * @param  {[type]} file [description]\n         * @return {[type]}      [description]\n         */\n        getLocalFile: function(file, encoding, type){\n            var xhr = new XMLHttpRequest();\n            xhr.open('GET', file, false);\n            xhr.send(null);\n            var text = xhr.responseText || xhr.responseXML;\n            if (!text) {\n                return false;\n            };\n            var mimeType = getMimeType(file);\n            if (encoding) {\n                text = \"data:\"+mimeType+\"; \" + encoding + \",\" + encodeText(text, type);\n            };\n            return text;\n        },\n        checkFileExist: function(file){\n            return !!this.getLocalFile(file);\n        },\n        /**\n         * get remote file content\n         * @return {[type]} [description]\n         */\n        getRemoteFile: function(requestId){\n            var detail = Fiddler_Resource.getItem(requestId);\n            var url = detail.url;\n            if (url.indexOf('?') == -1) {\n                url += '?fiddler=' + requestId;\n            }else{\n                url += '&fiddler=' + requestId;\n            }\n            //var headers = Fiddler_Rule.headersToObj(detail.requestHeaders);\n            var method = detail.method;\n            var deferred = when.defer();\n            $.ajax({\n                url: url,\n                method: method,\n                complete: function(data){\n                    data = data.responseText || data.responseXML;\n                    deferred.resolve(data);\n                }\n            })\n            return deferred.promise;\n        }\n    }\n}();"
  },
  {
    "path": "src/js/component/resource.js",
    "content": "/**\n * request resource\n * @return {[type]} [description]\n */\nvar Fiddler_Resource = function(){\n    \"use strict\";\n    var _request = {};\n    var resource = Fiddler.implement({}, Fiddler.CustEvent);\n\n    var parentRequestId = 0;\n    Fiddler.mix(resource, {\n        clearResource: function(){\n            _request = {};\n        },\n        add: function(data, type){\n            var requestId = data.requestId;\n            data[type + \"Time\"] = data.timeStamp;\n            if (!(requestId in _request)) {\n                _request[requestId] = {};\n                Fiddler.mix(_request[requestId], data);\n            }else{\n                for(var name in data){\n                    _request[requestId][name] = data[name];\n                }\n            };\n            if (type == 'onCompleted') {\n                var resourceType = _request[requestId].type;\n                var method = _request[requestId].method;\n                if (resourceType == \"main_frame\" && method == \"GET\" ) {\n                    parentRequestId = requestId;\n                    _request[requestId].parentRequestId = 0;\n                }else{\n                    _request[requestId].parentRequestId = parentRequestId;\n                }\n                //content-size\n                _request[requestId].size = 0;\n                var responseHeaders = _request[requestId].responseHeaders || [];\n                responseHeaders.some(function(item){\n                    if (item.name == 'Content-Length') {\n                        _request[requestId].size = item.value;\n                        return true;\n                    };\n                });\n                //cookie\n                var requestHeaders = _request[requestId].requestHeaders || [];\n                var cookie = '';\n                requestHeaders.some(function(item){\n                    if (item.name == 'Cookie') {\n                        cookie = item.value;\n                        return true;\n                    };\n                });\n                if (cookie) {\n                    _request[requestId].cookieSize = cookie.length;\n                    var cookieObj = {};\n                    cookie = cookie.split(/;\\s*/g);\n                    cookie.forEach(function(item){\n                        item = item.split('=');\n                        cookieObj[item[0]] = unescape(item[1]);\n                    });\n                    _request[requestId].cookieLength = cookie.length;\n                    _request[requestId].cookie = cookieObj;\n                };\n\n                var urlInfo = Fiddler.getUrlDetail(data.url);\n                Fiddler.mix(_request[requestId], urlInfo, true);\n                this.fire(\"onCompleted\", _request[requestId]);\n            };\n        },\n        getItem: function(requestId){\n            return _request[requestId] || {};\n        },\n        getResoure: function(){\n            return _request;\n        },\n        getContent: function(requestId){\n            var deferred = when.defer();\n            var detail = _request[requestId];\n            if (detail.content) {\n                return deferred.resolve(detail.content);\n            }else{\n                Fiddler_File.getRemoteFile(requestId).then(function(data){\n                    _request[requestId].content = data;\n                    deferred.resolve(data);\n                })\n            }\n            return deferred.promise;\n        },\n        setContent: function(url, content){\n            if (!content) {\n                return false;\n            };\n            var getRequestId = 0;\n            for(var requestId in _request){\n                if (_request[requestId]['url'] === url) {\n                    getRequestId = requestId;\n                };\n            };\n            if (getRequestId) {\n                _request[getRequestId].content = content;\n                _request[getRequestId].size = content.length;\n            };\n        },\n        getImgRect: function(url, oldUrl, deferred){\n            if (!deferred) {\n                deferred = when.defer();\n            };\n            var img = new Image();\n            var self = this;\n            img.onload = function(){\n                deferred.resolve({\n                    width: this.width,\n                    height: this.height,\n                    old: url === oldUrl\n                })\n            };\n            img.onerror = function(){\n                if (url == oldUrl) {\n                    deferred.resolve({\n                        width: this.width,\n                        height: this.height\n                    })\n                }else{\n                    return self.getImgRect(oldUrl, oldUrl, deferred);\n                }\n            }\n            img.src = url;\n            return deferred.promise;\n        },\n        getImgUrl: function(requestId){\n            var detail = _request[requestId];\n            var content = detail.content;\n            var ext = Fiddler.getFileExt(detail.url);\n            if (ext && content) {\n                var prefix = content.substr(100);\n                var regexp = /^[\\w\\+\\/\\=]+$/;\n                if (!regexp.test(prefix)) {\n                    content = Base64.encode(content);\n                };\n                return \"data:image/\"+ext+\";base64,\" + content;\n            };\n            return detail.url;\n        },\n        getSize: function(requestId){\n            var deferred = when.defer();\n            var detail = _request[requestId];\n            if (detail.size) {\n                return deferred.resolve(detail.size);\n            }else{\n                if (detail.content) {\n                    _request[requestId].size = detail.content.length;\n                    return deferred.resolve(_request[requestId].size);\n                };\n                var self = this;\n                this.getContent(requestId).then(function(){\n                    return self.getSize(requestId);\n                }).then(function(size){\n                    deferred.resolve(size);\n                })\n            }\n            return deferred.promise;\n        },\n        getQueryData: function(url){\n            var queryUrl = Fiddler.queryUrl(url) || {};\n            var ret = {\n                data: null,\n                length: 0\n            }\n            for(var name in queryUrl){\n                if (queryUrl[name] && queryUrl[name].join) {\n                    queryUrl[name] = \"[\" + queryUrl[name].join(\", \") + \"]\";\n                };\n                ret.length++;\n            };\n            if (ret.length) {\n                ret.data = queryUrl;\n            };\n            return ret;\n        }\n    })\n    return resource;\n}()"
  },
  {
    "path": "src/js/component/rule.js",
    "content": "/**\n * rule\n * @return {[type]} [description]\n */\nvar Fiddler_Rule = function(){\n    \"use strict\";\n    /**\n     * event types\n     * @type {Array}\n     */\n    var eventTypes = [\n        \"onBeforeRequest\",\n        \"onBeforeSendHeaders\",\n        \"onSendHeaders\",\n        \"onHeadersReceived\",\n        \"onBeforeRedirect\",\n        \"onResponseStarted\",\n        \"onErrorOccurred\",\n        \"onCompleted\"\n    ];\n    var rule = Fiddler.implement({}, Fiddler.CustEvent);\n    eventTypes.forEach(function(item){\n        rule[item] = function(callback){\n            this.on(item, callback);\n        }\n    });\n    var _isResouceListening = false;\n\n    var _fileErrorFn = null;\n\n    Fiddler.mix(rule, {\n        match: function(requestInfo, rule){\n            if (rule.patternType == \"Method\") {\n                return this.matchMethod(requestInfo, rule);\n            }else if(rule.patternType == 'Header'){\n                return this.matchHeader(requestInfo, rule);\n            }else{\n                return this.matchUrl(requestInfo, rule);\n            }\n        },\n        matchUrl: function(requestInfo, rule){\n            var url = requestInfo.url;\n            var pattern = rule.pattern;\n            if (rule.patternType == 'String') {\n                return url.indexOf(pattern) >= 0;\n            };\n            if (pattern.indexOf('/') != 0) {\n                pattern = '/' + pattern + '/';\n            };\n            try{\n                pattern.replace(/^\\/(.*)\\/([mig]*)$/g, function(a, b, c) {\n                    pattern = new RegExp(b, c || '');\n                });\n                if (pattern.test(url)) {\n                    return true;\n                };\n            }catch(e){}\n            return false;\n        },\n        matchMethod: function(requestInfo, rule){\n            var method = requestInfo.method;\n            if (rule.replace == requestInfo.url) {\n                return false;\n            };\n            return rule.pattern.toLowerCase() == method.toLowerCase();\n        },\n        matchHeader: function(requestInfo, rule){\n            var pattern = (rule.pattern || \"\").split('=');\n            var hName = pattern.shift().toLowerCase();\n            var hValue = pattern.join('=');\n            var headers = requestInfo.requestHeaders || [];\n            return headers.some(function(item){\n                var name = item.name.toLowerCase();\n                var value = item.value;\n                if (name == hName) {\n                    if (hValue == value) {\n                        return true;\n                    };\n                    if (value.indexOf(hValue) == 0) {\n                        return true;\n                    };\n                };\n                return false;\n            })\n        },\n        /**\n         * file replace\n         * @param  {[type]} pattern  [description]\n         * @param  {[type]} filename [description]\n         * @return {[type]}          [description]\n         */\n        addFileReplaceRule: function(rule){\n            var self = this;\n            this.onBeforeRequest(function(data){\n                var encoding = Fiddler_Config.getEncoding();\n                if (self.match(data.data, rule)) {\n                    var filename = rule.replace;\n                    var content = Fiddler_File.getLocalFile(filename, encoding, data.data.type);\n                    if (content === false) {\n                        self.fire(\"fileError\", filename);\n                        return false;\n                    };\n                    return {\n                        redirectUrl: content\n                    }\n                };\n                return false;\n            })\n        },\n        /**\n         * dir replace\n         * @param  {[type]} urlPrefix [description]\n         * @param  {[type]} filePath  [description]\n         * @return {[type]}           [description]\n         */\n        addDirReplaceRule: function(rule){\n            var self = this;\n            this.onBeforeRequest(function(data){\n                var url = data.data.url;\n                var encoding = Fiddler_Config.getEncoding();\n                var pos = url.indexOf(rule.pattern);\n                if (pos === 0) {\n                    var suffix = url.substr(rule.pattern.length);\n                    var file = Fiddler.pathAdd(rule.replace, suffix);\n                    var content = Fiddler_File.getLocalFile(file, encoding, data.data.type);\n                    if (content === false) {\n                        self.fire(\"fileError\", file);\n                        return false;\n                    };\n                    return {\n                        redirectUrl: content\n                    }\n                };\n                return false;\n            })\n        },\n        /**\n         * url replace\n         * @param  {[type]} urlPrefix    [description]\n         * @param  {[type]} targetPrefix [description]\n         * @return {[type]}              [description]\n         */\n        addUrlReplaceRule: function(rule){\n            var self = this;\n            this.onBeforeRequest(function(data){\n                if (self.match(data.data, rule)) {\n                    var url = rule.replace;\n                    return {\n                        redirectUrl: url\n                    }\n                };\n                return false;\n            })\n        },\n        /**\n         * delay time\n         * @param  {[type]} pattern   [description]\n         * @param  {[type]} delayTime [description]\n         * @return {[type]}           [description]\n         */\n        addDelayRule: function(rule){\n            var self = this;\n            this.onBeforeSendHeaders(function(data){\n                if (self.match(data.data, rule)) {\n                    var delayTime = parseInt(rule.replace, 10) || 0;\n                    Fiddler.delay(delayTime);\n                    return false;\n                };\n                return false;\n            })\n        },\n        /**\n         * cancel rule\n         * @return {[type]} [description]\n         */\n        addCancelRule: function(rule){\n            var self = this;\n            this.onBeforeSendHeaders(function(data){\n                console.log(data.data);\n                if (self.match(data.data, rule)) {\n                    data.data.cancel = true;\n                };\n                return data.data;\n            })\n        },\n        addHeaderRule: function(rule){\n            var self = this;\n            this.onBeforeSendHeaders(function(data){\n                if (self.match(data.data, rule)) {\n                    var headers = data.data.requestHeaders;\n                    var obj = self.headersToObj(headers);\n                    var newH = self.parseHeader(rule.replace);\n                    obj = Fiddler.mix(obj, newH, true);\n                    headers = self.headersToArr(obj);\n                    data.data.requestHeaders = headers;\n                    return data.data;  \n                };\n                return false;\n            })\n        },\n        parseHeader: function(string){\n            string = (string || \"\").split(\";\");\n            var headers = {};\n            string.forEach(function(item){\n                item = item.trim();\n                if (!item) {\n                    return false;\n                };\n                item = item.split('=');\n                var name = item[0].trim().toLowerCase();\n                name = name.substr(0, 1).toUpperCase() + name.substr(1);\n                name = name.replace(/\\-(\\w)/ig, function(a, b) {\n                    return '-' + b.toUpperCase();\n                });\n                var value = item[1].trim();\n                if (!name) {\n                    return false;\n                };\n                headers[name] = value;\n            })\n            return headers;\n        },\n        headersToObj: function(headers){\n            headers = headers || [];\n            var result = {};\n            headers.forEach(function(item){\n                result[item.name] = item.value;\n            });\n            return result;\n        },\n        headersToArr: function(obj){\n            var headers = [];\n            for(var name in obj){\n                headers.push({\n                    name: name,\n                    value: obj[name]\n                });\n            }\n            return headers;\n        },\n        /**\n         * resource listening\n         * @return {[type]} [description]\n         */\n        resouceListening: function(force){\n            if (_isResouceListening && !force) {\n                return false;\n            };\n            _isResouceListening = true;\n            var self = this;\n            eventTypes.forEach(function(item){\n                self[item](function(data){\n                    var detail = data.data;\n                    Fiddler_Resource.add(detail, item);\n                    return false;\n                })\n            });\n        },\n        fileErrorListening: function(callback){\n            if (callback) {\n                _fileErrorFn = callback\n            };\n            this.on(\"fileError\", _fileErrorFn);\n        },\n        disableCacheRule: function(){\n            var self = this;\n            var list = [\"Cache-Control\", \"Pragma\", \"If-Modified-Since\", \"If-None-Match\"];\n            var listData = [\"no-cache\", \"no-cache\", \"\", \"\"];\n            this.onBeforeSendHeaders(function(data){\n                var headers = data.data.requestHeaders;\n                var obj = self.headersToObj(headers);\n                var result = {};\n                for(var name in obj){\n                    if (list.indexOf(name) > -1) {\n                        continue;\n                    };\n                    result[name] = obj[name];\n                }\n                list.forEach(function(item, i){\n                    result[item] = listData[i];\n                })\n                headers = self.headersToArr(result);\n                data.data.requestHeaders = headers;\n                return data.data;\n            })\n        },\n        userAgentRule: function(agent){\n\n        },\n        parseRule: function(rule){\n            var types = {\n                \"File\": \"addFileReplaceRule\",\n                \"Path\": \"addDirReplaceRule\",\n                \"Cancel\": \"addCancelRule\",\n                \"Delay\": \"addDelayRule\",\n                \"Redirect\": \"addUrlReplaceRule\",\n                \"Header\": \"addHeaderRule\"\n            }\n            rule.type = types[rule.replaceType];\n            return rule;\n        },\n        addRule: function(rule){\n            var result = this.parseRule(rule);\n            var type = result.type;\n            if (this[type]) {\n                Fiddler_Config.addRule(result);\n                if (rule.enable) {\n                    this[type](result);\n                };\n            };\n        },\n        saveRules: function(rules, enable){\n            var self = this;\n            this.clearAll();\n            this.resouceListening(true);\n            this.fileErrorListening();\n            if (!enable) {\n                return this;\n            };\n            Fiddler_Config.clearRules();\n            rules = rules || [];\n            rules.forEach(function(item){\n                self.addRule(item);\n            });\n            return this;\n        }\n    })\n    return rule;\n}();"
  },
  {
    "path": "src/js/component.js",
    "content": "(function() {\n    var srcPath = '../js/';\n    document.write('<script src=\"' + srcPath + 'component/config.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'component/event.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'component/file.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'component/resource.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'component/rule.js\"><\\/script>');\n}());"
  },
  {
    "path": "src/js/lib/MimeTea.js",
    "content": "/*!\n * MimeTea JavaScript Library v1.0.1\n * https://github.com/Rosario-Gueli/MimeTea.js\n *\n * Licence\n * https://github.com/Rosario-Gueli/MimeTea.js/blob/master/LICENSE\n *\n * Date: 2013-09-27\n */\n\n\nvar MimeTea = (function(){\n\t\n\tvar Mimes = {\n\t\t\".flv\": \"video/x-flv\",\t\t\t\t// Flash\t \n\t\t\".mp4\": \"video/mp4\",\t\t\t\t// MPEG-4\t \n\t\t\".m3u8\": \"application/x-mpegURL\",\t// iPhone Index\t \n\t\t\".ts\": \"video/MP2T\",\t\t\t\t// iPhone Segment\t \n\t\t\".3gp\": \"video/3gpp\",\t\t\t\t// 3GP Mobile\t \n\t\t\".mov\": \"video/quicktime\",\t\t\t// QuickTime\t \n\t\t\".wmv\": \"video/x-ms-wmv\",\t\t\t// Windows Media\n\t\t\".3dm\": \"x-world/x-3dmf\",\n\t\t\".3dmf\": \"x-world/x-3dmf\",\n\t\t\".a\": \"application/octet-stream\",\n\t\t\".aab\": \"application/x-authorware-bin\",\n\t\t\".aam\": \"application/x-authorware-map\",\n\t\t\".aas\": \"application/x-authorware-seg\",\n\t\t\".abc\": \"text/vnd.abc\",\n\t\t\".acgi\": \"text/html\",\n\t\t\".afl\": \"video/animaflex\",\n\t\t\".ai\": \"application/postscript\",\n\t\t\".aif\": \"audio/aiff\",\n\t\t\".aif\": \"audio/x-aiff\",\n\t\t\".aifc\": \"audio/aiff\",\n\t\t\".aifc\": \"audio/x-aiff\",\n\t\t\".aiff\": \"audio/aiff\",\n\t\t\".aiff\": \"audio/x-aiff\",\n\t\t\".aim\": \"application/x-aim\",\n\t\t\".aip\": \"text/x-audiosoft-intra\",\n\t\t\".ani\": \"application/x-navi-animation\",\n\t\t\".aos\": \"application/x-nokia-9000-communicator-add-on-software\",\n\t\t\".aps\": \"application/mime\",\n\t\t\".arc\": \"application/octet-stream\",\n\t\t\".arj\": \"application/arj\",\n\t\t\".arj\": \"application/octet-stream\",\n\t\t\".art\": \"image/x-jg\",\n\t\t\".asf\": \"video/x-ms-asf\",\n\t\t\".asm\": \"text/x-asm\",\n\t\t\".asp\": \"text/asp\",\n\t\t\".asx\": \"application/x-mplayer2\",\n\t\t\".asx\": \"video/x-ms-asf\",\n\t\t\".asx\": \"video/x-ms-asf-plugin\",\n\t\t\".au\": \"audio/basic\",\n\t\t\".au\": \"audio/x-au\",\n\t\t\".avi\": \"application/x-troff-msvideo\",\n\t\t\".avi\": \"video/avi\",\n\t\t\".avi\": \"video/msvideo\",\n\t\t\".avi\": \"video/x-msvideo\",\n\t\t\".avs\": \"video/avs-video\",\n\t\t\".bcpio\": \"application/x-bcpio\",\n\t\t\".bin\": \"application/mac-binary\",\n\t\t\".bin\": \"application/macbinary\",\n\t\t\".bin\": \"application/octet-stream\",\n\t\t\".bin\": \"application/x-binary\",\n\t\t\".bin\": \"application/x-macbinary\",\n\t\t\".bm\": \"image/bmp\",\n\t\t\".bmp\": \"image/bmp\",\n\t\t\".bmp\": \"image/x-windows-bmp\",\n\t\t\".boo\": \"application/book\",\n\t\t\".book\": \"application/book\",\n\t\t\".boz\": \"application/x-bzip2\",\n\t\t\".bsh\": \"application/x-bsh\",\n\t\t\".bz\": \"application/x-bzip\",\n\t\t\".bz2\": \"application/x-bzip2\",\n\t\t\".c\": \"text/plain\",\n\t\t\".c\": \"text/x-c\",\n\t\t\".c++\": \"text/plain\",\n\t\t\".cat\": \"application/vnd.ms-pki.seccat\",\n\t\t\".cc\": \"text/plain\",\n\t\t\".cc\": \"text/x-c\",\n\t\t\".ccad\": \"application/clariscad\",\n\t\t\".cco\": \"application/x-cocoa\",\n\t\t\".cdf\": \"application/cdf\",\n\t\t\".cdf\": \"application/x-cdf\",\n\t\t\".cdf\": \"application/x-netcdf\",\n\t\t\".cer\": \"application/pkix-cert\",\n\t\t\".cer\": \"application/x-x509-ca-cert\",\n\t\t\".cha\": \"application/x-chat\",\n\t\t\".chat\": \"application/x-chat\",\n\t\t\".class\": \"application/java\",\n\t\t\".class\": \"application/java-byte-code\",\n\t\t\".class\": \"application/x-java-class\",\n\t\t\".com\": \"application/octet-stream\",\n\t\t\".com\": \"text/plain\",\n\t\t\".conf\": \"text/plain\",\n\t\t\".cpio\": \"application/x-cpio\",\n\t\t\".cpp\": \"text/x-c\",\n\t\t\".cpt\": \"application/mac-compactpro\",\n\t\t\".cpt\": \"application/x-compactpro\",\n\t\t\".cpt\": \"application/x-cpt\",\n\t\t\".crl\": \"application/pkcs-crl\",\n\t\t\".crl\": \"application/pkix-crl\",\n\t\t\".crt\": \"application/pkix-cert\",\n\t\t\".crt\": \"application/x-x509-ca-cert\",\n\t\t\".crt\": \"application/x-x509-user-cert\",\n\t\t\".csh\": \"application/x-csh\",\n\t\t\".csh\": \"text/x-script.csh\",\n\t\t\".css\": \"application/x-pointplus\",\n\t\t\".css\": \"text/css\",\n\t\t\".cxx\": \"text/plain\",\n\t\t\".dcr\": \"application/x-director\",\n\t\t\".deepv\": \"application/x-deepv\",\n\t\t\".def\": \"text/plain\",\n\t\t\".der\": \"application/x-x509-ca-cert\",\n\t\t\".dif\": \"video/x-dv\",\n\t\t\".dir\": \"application/x-director\",\n\t\t\".dl\": \"video/dl\",\n\t\t\".dl\": \"video/x-dl\",\n\t\t\".doc\": \"application/msword\",\n\t\t\".dot\": \"application/msword\",\n\t\t\".dp\": \"application/commonground\",\n\t\t\".drw\": \"application/drafting\",\n\t\t\".dump\": \"application/octet-stream\",\n\t\t\".dv\": \"video/x-dv\",\n\t\t\".dvi\": \"application/x-dvi\",\n\t\t\".dwf\": \"drawing/x-dwf (old)\",\n\t\t\".dwf\": \"model/vnd.dwf\",\n\t\t\".dwg\": \"application/acad\",\n\t\t\".dwg\": \"image/vnd.dwg\",\n\t\t\".dwg\": \"image/x-dwg\",\n\t\t\".dxf\": \"application/dxf\",\n\t\t\".dxf\": \"image/vnd.dwg\",\n\t\t\".dxf\": \"image/x-dwg\",\n\t\t\".dxr\": \"application/x-director\",\n\t\t\".el\": \"text/x-script.elisp\",\n\t\t\".elc\": \"application/x-bytecode.elisp (compiled elisp)\",\n\t\t\".elc\": \"application/x-elc\",\n\t\t\".env\": \"application/x-envoy\",\n\t\t\".eps\": \"application/postscript\",\n\t\t\".es\": \"application/x-esrehber\",\n\t\t\".etx\": \"text/x-setext\",\n\t\t\".evy\": \"application/envoy\",\n\t\t\".evy\": \"application/x-envoy\",\n\t\t\".exe\": \"application/octet-stream\",\n\t\t\".f\": \"text/plain\",\n\t\t\".f\": \"text/x-fortran\",\n\t\t\".f77\": \"text/x-fortran\",\n\t\t\".f90\": \"text/plain\",\n\t\t\".f90\": \"text/x-fortran\",\n\t\t\".fdf\": \"application/vnd.fdf\",\n\t\t\".fif\": \"application/fractals\",\n\t\t\".fif\": \"image/fif\",\n\t\t\".fli\": \"video/fli\",\n\t\t\".fli\": \"video/x-fli\",\n\t\t\".flo\": \"image/florian\",\n\t\t\".flx\": \"text/vnd.fmi.flexstor\",\n\t\t\".fmf\": \"video/x-atomic3d-feature\",\n\t\t\".for\": \"text/plain\",\n\t\t\".for\": \"text/x-fortran\",\n\t\t\".fpx\": \"image/vnd.fpx\",\n\t\t\".fpx\": \"image/vnd.net-fpx\",\n\t\t\".frl\": \"application/freeloader\",\n\t\t\".funk\": \"audio/make\",\n\t\t\".g\": \"text/plain\",\n\t\t\".g3\": \"image/g3fax\",\n\t\t\".gif\": \"image/gif\",\n\t\t\".gl\": \"video/gl\",\n\t\t\".gl\": \"video/x-gl\",\n\t\t\".gsd\": \"audio/x-gsm\",\n\t\t\".gsm\": \"audio/x-gsm\",\n\t\t\".gsp\": \"application/x-gsp\",\n\t\t\".gss\": \"application/x-gss\",\n\t\t\".gtar\": \"application/x-gtar\",\n\t\t\".gz\": \"application/x-compressed\",\n\t\t\".gz\": \"application/x-gzip\",\n\t\t\".gzip\": \"application/x-gzip\",\n\t\t\".gzip\": \"multipart/x-gzip\",\n\t\t\".h\": \"text/plain\",\n\t\t\".h\": \"text/x-h\",\n\t\t\".hdf\": \"application/x-hdf\",\n\t\t\".help\": \"application/x-helpfile\",\n\t\t\".hgl\": \"application/vnd.hp-hpgl\",\n\t\t\".hh\": \"text/plain\",\n\t\t\".hh\": \"text/x-h\",\n\t\t\".hlb\": \"text/x-script\",\n\t\t\".hlp\": \"application/hlp\",\n\t\t\".hlp\": \"application/x-helpfile\",\n\t\t\".hlp\": \"application/x-winhelp\",\n\t\t\".hpg\": \"application/vnd.hp-hpgl\",\n\t\t\".hpgl\": \"application/vnd.hp-hpgl\",\n\t\t\".hqx\": \"application/binhex\",\n\t\t\".hqx\": \"application/binhex4\",\n\t\t\".hqx\": \"application/mac-binhex\",\n\t\t\".hqx\": \"application/mac-binhex40\",\n\t\t\".hqx\": \"application/x-binhex40\",\n\t\t\".hqx\": \"application/x-mac-binhex40\",\n\t\t\".hta\": \"application/hta\",\n\t\t\".htc\": \"text/x-component\",\n\t\t\".htm\": \"text/html\",\n\t\t\".html\": \"text/html\",\n\t\t\".htmls\": \"text/html\",\n\t\t\".htt\": \"text/webviewhtml\",\n\t\t\".htx\": \"text/html\",\n\t\t\".ice\": \"x-conference/x-cooltalk\",\n\t\t\".ico\": \"image/x-icon\",\n\t\t\".idc\": \"text/plain\",\n\t\t\".ief\": \"image/ief\",\n\t\t\".iefs\": \"image/ief\",\n\t\t\".iges\": \"application/iges\",\n\t\t\".iges\": \"model/iges\",\n\t\t\".igs\": \"application/iges\",\n\t\t\".igs\": \"model/iges\",\n\t\t\".ima\": \"application/x-ima\",\n\t\t\".imap\": \"application/x-httpd-imap\",\n\t\t\".inf\": \"application/inf\",\n\t\t\".ins\": \"application/x-internett-signup\",\n\t\t\".ip\": \"application/x-ip2\",\n\t\t\".isu\": \"video/x-isvideo\",\n\t\t\".it\": \"audio/it\",\n\t\t\".iv\": \"application/x-inventor\",\n\t\t\".ivr\": \"i-world/i-vrml\",\n\t\t\".ivy\": \"application/x-livescreen\",\n\t\t\".jam\": \"audio/x-jam\",\n\t\t\".jav\": \"text/plain\",\n\t\t\".jav\": \"text/x-java-source\",\n\t\t\".java\": \"text/plain\",\n\t\t\".java\": \"text/x-java-source\",\n\t\t\".jcm\": \"application/x-java-commerce\",\n\t\t\".jfif\": \"image/jpeg\",\n\t\t\".jfif\": \"image/pjpeg\",\n\t\t\".jfif-tbnl\": \"image/jpeg\",\n\t\t\".jpe\": \"image/jpeg\",\n\t\t\".jpe\": \"image/pjpeg\",\n\t\t\".jpeg\": \"image/jpeg\",\n\t\t\".jpeg\": \"image/pjpeg\",\n\t\t\".jpg\": \"image/jpeg\",\n\t\t\".jpg\": \"image/pjpeg\",\n\t\t\".jps\": \"image/x-jps\",\n\t\t\".js\": \"application/x-javascript\",\n\t\t\".jut\": \"image/jutvision\",\n\t\t\".kar\": \"audio/midi\",\n\t\t\".kar\": \"music/x-karaoke\",\n\t\t\".ksh\": \"application/x-ksh\",\n\t\t\".ksh\": \"text/x-script.ksh\",\n\t\t\".la\": \"audio/nspaudio\",\n\t\t\".la\": \"audio/x-nspaudio\",\n\t\t\".lam\": \"audio/x-liveaudio\",\n\t\t\".latex\": \"application/x-latex\",\n\t\t\".lha\": \"application/lha\",\n\t\t\".lha\": \"application/octet-stream\",\n\t\t\".lha\": \"application/x-lha\",\n\t\t\".lhx\": \"application/octet-stream\",\n\t\t\".list\": \"text/plain\",\n\t\t\".lma\": \"audio/nspaudio\",\n\t\t\".lma\": \"audio/x-nspaudio\",\n\t\t\".log\": \"text/plain\",\n\t\t\".lsp\": \"application/x-lisp\",\n\t\t\".lsp\": \"text/x-script.lisp\",\n\t\t\".lst\": \"text/plain\",\n\t\t\".lsx\": \"text/x-la-asf\",\n\t\t\".ltx\": \"application/x-latex\",\n\t\t\".lzh\": \"application/octet-stream\",\n\t\t\".lzh\": \"application/x-lzh\",\n\t\t\".lzx\": \"application/lzx\",\n\t\t\".lzx\": \"application/octet-stream\",\n\t\t\".lzx\": \"application/x-lzx\",\n\t\t\".m\": \"text/plain\",\n\t\t\".m\": \"text/x-m\",\n\t\t\".m1v\": \"video/mpeg\",\n\t\t\".m2a\": \"audio/mpeg\",\n\t\t\".m2v\": \"video/mpeg\",\n\t\t\".m3u\": \"audio/x-mpequrl\",\n\t\t\".man\": \"application/x-troff-man\",\n\t\t\".map\": \"application/x-navimap\",\n\t\t\".mar\": \"text/plain\",\n\t\t\".mbd\": \"application/mbedlet\",\n\t\t\".mc$\": \"application/x-magic-cap-package-1.0\",\n\t\t\".mcd\": \"application/mcad\",\n\t\t\".mcd\": \"application/x-mathcad\",\n\t\t\".mcf\": \"image/vasa\",\n\t\t\".mcf\": \"text/mcf\",\n\t\t\".mcp\": \"application/netmc\",\n\t\t\".me\": \"application/x-troff-me\",\n\t\t\".mht\": \"message/rfc822\",\n\t\t\".mhtml\": \"message/rfc822\",\n\t\t\".mid\": \"application/x-midi\",\n\t\t\".mid\": \"audio/midi\",\n\t\t\".mid\": \"audio/x-mid\",\n\t\t\".mid\": \"audio/x-midi\",\n\t\t\".mid\": \"music/crescendo\",\n\t\t\".mid\": \"x-music/x-midi\",\n\t\t\".midi\": \"application/x-midi\",\n\t\t\".midi\": \"audio/midi\",\n\t\t\".midi\": \"audio/x-mid\",\n\t\t\".midi\": \"audio/x-midi\",\n\t\t\".midi\": \"music/crescendo\",\n\t\t\".midi\": \"x-music/x-midi\",\n\t\t\".mif\": \"application/x-frame\",\n\t\t\".mif\": \"application/x-mif\",\n\t\t\".mime\": \"message/rfc822\",\n\t\t\".mime\": \"www/mime\",\n\t\t\".mjf\": \"audio/x-vnd.audioexplosion.mjuicemediafile\",\n\t\t\".mjpg\": \"video/x-motion-jpeg\",\n\t\t\".mm\": \"application/base64\",\n\t\t\".mm\": \"application/x-meme\",\n\t\t\".mme\": \"application/base64\",\n\t\t\".mod\": \"audio/mod\",\n\t\t\".mod\": \"audio/x-mod\",\n\t\t\".moov\": \"video/quicktime\",\n\t\t\".mov\": \"video/quicktime\",\n\t\t\".movie\": \"video/x-sgi-movie\",\n\t\t\".mp2\": \"audio/mpeg\",\n\t\t\".mp2\": \"audio/x-mpeg\",\n\t\t\".mp2\": \"video/mpeg\",\n\t\t\".mp2\": \"video/x-mpeg\",\n\t\t\".mp2\": \"video/x-mpeq2a\",\n\t\t\".mp3\": \"audio/mpeg3\",\n\t\t\".mp3\": \"audio/x-mpeg-3\",\n\t\t\".mp3\": \"video/mpeg\",\n\t\t\".mp3\": \"video/x-mpeg\",\n\t\t\".mpa\": \"audio/mpeg\",\n\t\t\".mpa\": \"video/mpeg\",\n\t\t\".mpc\": \"application/x-project\",\n\t\t\".mpe\": \"video/mpeg\",\n\t\t\".mpeg\": \"video/mpeg\",\n\t\t\".mpg\": \"audio/mpeg\",\n\t\t\".mpg\": \"video/mpeg\",\n\t\t\".mpga\": \"audio/mpeg\",\n\t\t\".mpp\": \"application/vnd.ms-project\",\n\t\t\".mpt\": \"application/x-project\",\n\t\t\".mpv\": \"application/x-project\",\n\t\t\".mpx\": \"application/x-project\",\n\t\t\".mrc\": \"application/marc\",\n\t\t\".ms\": \"application/x-troff-ms\",\n\t\t\".mv\": \"video/x-sgi-movie\",\n\t\t\".my\": \"audio/make\",\n\t\t\".mzz\": \"application/x-vnd.audioexplosion.mzz\",\n\t\t\".nap\": \"image/naplps\",\n\t\t\".naplps\": \"image/naplps\",\n\t\t\".nc\": \"application/x-netcdf\",\n\t\t\".ncm\": \"application/vnd.nokia.configuration-message\",\n\t\t\".nif\": \"image/x-niff\",\n\t\t\".niff\": \"image/x-niff\",\n\t\t\".nix\": \"application/x-mix-transfer\",\n\t\t\".nsc\": \"application/x-conference\",\n\t\t\".nvd\": \"application/x-navidoc\",\n\t\t\".o\": \"application/octet-stream\",\n\t\t\".oda\": \"application/oda\",\n\t\t\".omc\": \"application/x-omc\",\n\t\t\".omcd\": \"application/x-omcdatamaker\",\n\t\t\".omcr\": \"application/x-omcregerator\",\n\t\t\".p\": \"text/x-pascal\",\n\t\t\".p10\": \"application/pkcs10\",\n\t\t\".p10\": \"application/x-pkcs10\",\n\t\t\".p12\": \"application/pkcs-12\",\n\t\t\".p12\": \"application/x-pkcs12\",\n\t\t\".p7a\": \"application/x-pkcs7-signature\",\n\t\t\".p7c\": \"application/pkcs7-mime\",\n\t\t\".p7c\": \"application/x-pkcs7-mime\",\n\t\t\".p7m\": \"application/pkcs7-mime\",\n\t\t\".p7m\": \"application/x-pkcs7-mime\",\n\t\t\".p7r\": \"application/x-pkcs7-certreqresp\",\n\t\t\".p7s\": \"application/pkcs7-signature\",\n\t\t\".part\": \"application/pro_eng\",\n\t\t\".pas\": \"text/pascal\",\n\t\t\".pbm\": \"image/x-portable-bitmap\",\n\t\t\".pcl\": \"application/vnd.hp-pcl\",\n\t\t\".pcl\": \"application/x-pcl\",\n\t\t\".pct\": \"image/x-pict\",\n\t\t\".pcx\": \"image/x-pcx\",\n\t\t\".pdb\": \"chemical/x-pdb\",\n\t\t\".pdf\": \"application/pdf\",\n\t\t\".pfunk\": \"audio/make\",\n\t\t\".pfunk\": \"audio/make.my.funk\",\n\t\t\".pgm\": \"image/x-portable-graymap\",\n\t\t\".pgm\": \"image/x-portable-greymap\",\n\t\t\".pic\": \"image/pict\",\n\t\t\".pict\": \"image/pict\",\n\t\t\".pkg\": \"application/x-newton-compatible-pkg\",\n\t\t\".pko\": \"application/vnd.ms-pki.pko\",\n\t\t\".pl\": \"text/plain\",\n\t\t\".pl\": \"text/x-script.perl\",\n\t\t\".plx\": \"application/x-pixclscript\",\n\t\t\".pm\": \"image/x-xpixmap\",\n\t\t\".pm\": \"text/x-script.perl-module\",\n\t\t\".pm4\": \"application/x-pagemaker\",\n\t\t\".pm5\": \"application/x-pagemaker\",\n\t\t\".png\": \"image/png\",\n\t\t\".pnm\": \"application/x-portable-anymap\",\n\t\t\".pnm\": \"image/x-portable-anymap\",\n\t\t\".pot\": \"application/mspowerpoint\",\n\t\t\".pot\": \"application/vnd.ms-powerpoint\",\n\t\t\".pov\": \"model/x-pov\",\n\t\t\".ppa\": \"application/vnd.ms-powerpoint\",\n\t\t\".ppm\": \"image/x-portable-pixmap\",\n\t\t\".pps\": \"application/mspowerpoint\",\n\t\t\".pps\": \"application/vnd.ms-powerpoint\",\n\t\t\".ppt\": \"application/mspowerpoint\",\n\t\t\".ppt\": \"application/powerpoint\",\n\t\t\".ppt\": \"application/vnd.ms-powerpoint\",\n\t\t\".ppt\": \"application/x-mspowerpoint\",\n\t\t\".ppz\": \"application/mspowerpoint\",\n\t\t\".pre\": \"application/x-freelance\",\n\t\t\".prt\": \"application/pro_eng\",\n\t\t\".ps\": \"application/postscript\",\n\t\t\".psd\": \"application/octet-stream\",\n\t\t\".pvu\": \"paleovu/x-pv\",\n\t\t\".pwz\": \"application/vnd.ms-powerpoint\",\n\t\t\".py\": \"text/x-script.phyton\",\n\t\t\".pyc\": \"applicaiton/x-bytecode.python\",\n\t\t\".qcp\": \"audio/vnd.qcelp\",\n\t\t\".qd3\": \"x-world/x-3dmf\",\n\t\t\".qd3d\": \"x-world/x-3dmf\",\n\t\t\".qif\": \"image/x-quicktime\",\n\t\t\".qt\": \"video/quicktime\",\n\t\t\".qtc\": \"video/x-qtc\",\n\t\t\".qti\": \"image/x-quicktime\",\n\t\t\".qtif\": \"image/x-quicktime\",\n\t\t\".ra\": \"audio/x-pn-realaudio\",\n\t\t\".ra\": \"audio/x-pn-realaudio-plugin\",\n\t\t\".ra\": \"audio/x-realaudio\",\n\t\t\".ram\": \"audio/x-pn-realaudio\",\n\t\t\".ras\": \"application/x-cmu-raster\",\n\t\t\".ras\": \"image/cmu-raster\",\n\t\t\".ras\": \"image/x-cmu-raster\",\n\t\t\".rast\": \"image/cmu-raster\",\n\t\t\".rexx\": \"text/x-script.rexx\",\n\t\t\".rf\": \"image/vnd.rn-realflash\",\n\t\t\".rgb\": \"image/x-rgb\",\n\t\t\".rm\": \"application/vnd.rn-realmedia\",\n\t\t\".rm\": \"audio/x-pn-realaudio\",\n\t\t\".rmi\": \"audio/mid\",\n\t\t\".rmm\": \"audio/x-pn-realaudio\",\n\t\t\".rmp\": \"audio/x-pn-realaudio\",\n\t\t\".rmp\": \"audio/x-pn-realaudio-plugin\",\n\t\t\".rng\": \"application/ringing-tones\",\n\t\t\".rng\": \"application/vnd.nokia.ringing-tone\",\n\t\t\".rnx\": \"application/vnd.rn-realplayer\",\n\t\t\".roff\": \"application/x-troff\",\n\t\t\".rp\": \"image/vnd.rn-realpix\",\n\t\t\".rpm\": \"audio/x-pn-realaudio-plugin\",\n\t\t\".rt\": \"text/richtext\",\n\t\t\".rt\": \"text/vnd.rn-realtext\",\n\t\t\".rtf\": \"application/rtf\",\n\t\t\".rtf\": \"application/x-rtf\",\n\t\t\".rtf\": \"text/richtext\",\n\t\t\".rtx\": \"application/rtf\",\n\t\t\".rtx\": \"text/richtext\",\n\t\t\".rv\": \"video/vnd.rn-realvideo\",\n\t\t\".s\": \"text/x-asm\",\n\t\t\".s3m\": \"audio/s3m\",\n\t\t\".saveme\": \"application/octet-stream\",\n\t\t\".sbk\": \"application/x-tbook\",\n\t\t\".scm\": \"application/x-lotusscreencam\",\n\t\t\".scm\": \"text/x-script.guile\",\n\t\t\".scm\": \"text/x-script.scheme\",\n\t\t\".scm\": \"video/x-scm\",\n\t\t\".sdml\": \"text/plain\",\n\t\t\".sdp\": \"application/sdp\",\n\t\t\".sdp\": \"application/x-sdp\",\n\t\t\".sdr\": \"application/sounder\",\n\t\t\".sea\": \"application/sea\",\n\t\t\".sea\": \"application/x-sea\",\n\t\t\".set\": \"application/set\",\n\t\t\".sgm\": \"text/sgml\",\n\t\t\".sgm\": \"text/x-sgml\",\n\t\t\".sgml\": \"text/sgml\",\n\t\t\".sgml\": \"text/x-sgml\",\n\t\t\".sh\": \"application/x-bsh\",\n\t\t\".sh\": \"application/x-sh\",\n\t\t\".sh\": \"application/x-shar\",\n\t\t\".sh\": \"text/x-script.sh\",\n\t\t\".shar\": \"application/x-bsh\",\n\t\t\".shar\": \"application/x-shar\",\n\t\t\".shtml\": \"text/html\",\n\t\t\".shtml\": \"text/x-server-parsed-html\",\n\t\t\".sid\": \"audio/x-psid\",\n\t\t\".sit\": \"application/x-sit\",\n\t\t\".sit\": \"application/x-stuffit\",\n\t\t\".skd\": \"application/x-koan\",\n\t\t\".skm\": \"application/x-koan\",\n\t\t\".skp\": \"application/x-koan\",\n\t\t\".skt\": \"application/x-koan\",\n\t\t\".sl\": \"application/x-seelogo\",\n\t\t\".smi\": \"application/smil\",\n\t\t\".smil\": \"application/smil\",\n\t\t\".snd\": \"audio/basic\",\n\t\t\".snd\": \"audio/x-adpcm\",\n\t\t\".sol\": \"application/solids\",\n\t\t\".spc\": \"application/x-pkcs7-certificates\",\n\t\t\".spc\": \"text/x-speech\",\n\t\t\".spl\": \"application/futuresplash\",\n\t\t\".spr\": \"application/x-sprite\",\n\t\t\".sprite\": \"application/x-sprite\",\n\t\t\".src\": \"application/x-wais-source\",\n\t\t\".ssi\": \"text/x-server-parsed-html\",\n\t\t\".ssm\": \"application/streamingmedia\",\n\t\t\".sst\": \"application/vnd.ms-pki.certstore\",\n\t\t\".step\": \"application/step\",\n\t\t\".stl\": \"application/sla\",\n\t\t\".stl\": \"application/vnd.ms-pki.stl\",\n\t\t\".stl\": \"application/x-navistyle\",\n\t\t\".stp\": \"application/step\",\n\t\t\".sv4cpio\": \"application/x-sv4cpio\",\n\t\t\".sv4crc\": \"application/x-sv4crc\",\n\t\t\".svf\": \"image/vnd.dwg\",\n\t\t\".svf\": \"image/x-dwg\",\n\t\t\".svr\": \"application/x-world\",\n\t\t\".svr\": \"x-world/x-svr\",\n\t\t\".swf\": \"application/x-shockwave-flash\",\n\t\t\".t\": \"application/x-troff\",\n\t\t\".talk\": \"text/x-speech\",\n\t\t\".tar\": \"application/x-tar\",\n\t\t\".tbk\": \"application/toolbook\",\n\t\t\".tbk\": \"application/x-tbook\",\n\t\t\".tcl\": \"application/x-tcl\",\n\t\t\".tcl\": \"text/x-script.tcl\",\n\t\t\".tcsh\": \"text/x-script.tcsh\",\n\t\t\".tex\": \"application/x-tex\",\n\t\t\".texi\": \"application/x-texinfo\",\n\t\t\".texinfo\": \"application/x-texinfo\",\n\t\t\".text\": \"application/plain\",\n\t\t\".text\": \"text/plain\",\n\t\t\".tgz\": \"application/gnutar\",\n\t\t\".tgz\": \"application/x-compressed\",\n\t\t\".tif\": \"image/tiff\",\n\t\t\".tif\": \"image/x-tiff\",\n\t\t\".tiff\": \"image/tiff\",\n\t\t\".tiff\": \"image/x-tiff\",\n\t\t\".tr\": \"application/x-troff\",\n\t\t\".tsi\": \"audio/tsp-audio\",\n\t\t\".tsp\": \"application/dsptype\",\n\t\t\".tsp\": \"audio/tsplayer\",\n\t\t\".tsv\": \"text/tab-separated-values\",\n\t\t\".turbot\": \"image/florian\",\n\t\t\".txt\": \"text/plain\",\n\t\t\".uil\": \"text/x-uil\",\n\t\t\".uni\": \"text/uri-list\",\n\t\t\".unis\": \"text/uri-list\",\n\t\t\".unv\": \"application/i-deas\",\n\t\t\".uri\": \"text/uri-list\",\n\t\t\".uris\": \"text/uri-list\",\n\t\t\".ustar\": \"application/x-ustar\",\n\t\t\".ustar\": \"multipart/x-ustar\",\n\t\t\".uu\": \"application/octet-stream\",\n\t\t\".uu\": \"text/x-uuencode\",\n\t\t\".uue\": \"text/x-uuencode\",\n\t\t\".vcd\": \"application/x-cdlink\",\n\t\t\".vcs\": \"text/x-vcalendar\",\n\t\t\".vda\": \"application/vda\",\n\t\t\".vdo\": \"video/vdo\",\n\t\t\".vew\": \"application/groupwise\",\n\t\t\".viv\": \"video/vivo\",\n\t\t\".viv\": \"video/vnd.vivo\",\n\t\t\".vivo\": \"video/vivo\",\n\t\t\".vivo\": \"video/vnd.vivo\",\n\t\t\".vmd\": \"application/vocaltec-media-desc\",\n\t\t\".vmf\": \"application/vocaltec-media-file\",\n\t\t\".voc\": \"audio/voc\",\n\t\t\".voc\": \"audio/x-voc\",\n\t\t\".vos\": \"video/vosaic\",\n\t\t\".vox\": \"audio/voxware\",\n\t\t\".vqe\": \"audio/x-twinvq-plugin\",\n\t\t\".vqf\": \"audio/x-twinvq\",\n\t\t\".vql\": \"audio/x-twinvq-plugin\",\n\t\t\".vrml\": \"application/x-vrml\",\n\t\t\".vrml\": \"model/vrml\",\n\t\t\".vrml\": \"x-world/x-vrml\",\n\t\t\".vrt\": \"x-world/x-vrt\",\n\t\t\".vsd\": \"application/x-visio\",\n\t\t\".vst\": \"application/x-visio\",\n\t\t\".vsw\": \"application/x-visio\",\n\t\t\".w60\": \"application/wordperfect6.0\",\n\t\t\".w61\": \"application/wordperfect6.1\",\n\t\t\".w6w\": \"application/msword\",\n\t\t\".wav\": \"audio/wav\",\n\t\t\".wav\": \"audio/x-wav\",\n\t\t\".wb1\": \"application/x-qpro\",\n\t\t\".wbmp\": \"image/vnd.wap.wbmp\",\n\t\t\".web\": \"application/vnd.xara\",\n\t\t\".wiz\": \"application/msword\",\n\t\t\".wk1\": \"application/x-123\",\n\t\t\".wmf\": \"windows/metafile\",\n\t\t\".wml\": \"text/vnd.wap.wml\",\n\t\t\".wmlc\": \"application/vnd.wap.wmlc\",\n\t\t\".wmls\": \"text/vnd.wap.wmlscript\",\n\t\t\".wmlsc\": \"application/vnd.wap.wmlscriptc\",\n\t\t\".word\": \"application/msword\",\n\t\t\".wp\": \"application/wordperfect\",\n\t\t\".wp5\": \"application/wordperfect\",\n\t\t\".wp5\": \"application/wordperfect6.0\",\n\t\t\".wp6\": \"application/wordperfect\",\n\t\t\".wpd\": \"application/wordperfect\",\n\t\t\".wpd\": \"application/x-wpwin\",\n\t\t\".wq1\": \"application/x-lotus\",\n\t\t\".wri\": \"application/mswrite\",\n\t\t\".wri\": \"application/x-wri\",\n\t\t\".wrl\": \"application/x-world\",\n\t\t\".wrl\": \"model/vrml\",\n\t\t\".wrl\": \"x-world/x-vrml\",\n\t\t\".wrz\": \"model/vrml\",\n\t\t\".wrz\": \"x-world/x-vrml\",\n\t\t\".wsc\": \"text/scriplet\",\n\t\t\".wsrc\": \"application/x-wais-source\",\n\t\t\".wtk\": \"application/x-wintalk\",\n\t\t\".xbm\": \"image/x-xbitmap\",\n\t\t\".xbm\": \"image/x-xbm\",\n\t\t\".xbm\": \"image/xbm\",\n\t\t\".xdr\": \"video/x-amt-demorun\",\n\t\t\".xgz\": \"xgl/drawing\",\n\t\t\".xif\": \"image/vnd.xiff\",\n\t\t\".xl\": \"application/excel\",\n\t\t\".xla\": \"application/excel\",\n\t\t\".xla\": \"application/x-excel\",\n\t\t\".xla\": \"application/x-msexcel\",\n\t\t\".xlb\": \"application/excel\",\n\t\t\".xlb\": \"application/vnd.ms-excel\",\n\t\t\".xlb\": \"application/x-excel\",\n\t\t\".xlc\": \"application/excel\",\n\t\t\".xlc\": \"application/vnd.ms-excel\",\n\t\t\".xlc\": \"application/x-excel\",\n\t\t\".xld\": \"application/excel\",\n\t\t\".xld\": \"application/x-excel\",\n\t\t\".xlk\": \"application/excel\",\n\t\t\".xlk\": \"application/x-excel\",\n\t\t\".xll\": \"application/excel\",\n\t\t\".xll\": \"application/vnd.ms-excel\",\n\t\t\".xll\": \"application/x-excel\",\n\t\t\".xlm\": \"application/excel\",\n\t\t\".xlm\": \"application/vnd.ms-excel\",\n\t\t\".xlm\": \"application/x-excel\",\n\t\t\".xls\": \"application/excel\",\n\t\t\".xls\": \"application/vnd.ms-excel\",\n\t\t\".xls\": \"application/x-excel\",\n\t\t\".xls\": \"application/x-msexcel\",\n\t\t\".xlt\": \"application/excel\",\n\t\t\".xlt\": \"application/x-excel\",\n\t\t\".xlv\": \"application/excel\",\n\t\t\".xlv\": \"application/x-excel\",\n\t\t\".xlw\": \"application/excel\",\n\t\t\".xlw\": \"application/vnd.ms-excel\",\n\t\t\".xlw\": \"application/x-excel\",\n\t\t\".xlw\": \"application/x-msexcel\",\n\t\t\".xm\": \"audio/xm\",\n\t\t\".xml\": \"application/xml\",\n\t\t\".xml\": \"text/xml\",\n\t\t\".xmz\": \"xgl/movie\",\n\t\t\".xpix\": \"application/x-vnd.ls-xpix\",\n\t\t\".xpm\": \"image/x-xpixmap\",\n\t\t\".xpm\": \"image/xpm\",\n\t\t\".x-png\": \"image/png\",\n\t\t\".xsr\": \"video/x-amt-showrun\",\n\t\t\".xwd\": \"image/x-xwd\",\n\t\t\".xwd\": \"image/x-xwindowdump\",\n\t\t\".xyz\": \"chemical/x-pdb\",\n\t\t\".z\": \"application/x-compress\",\n\t\t\".z\": \"application/x-compressed\",\n\t\t\".zip\": \"application/x-compressed\",\n\t\t\".zip\": \"application/x-zip-compressed\",\n\t\t\".zip\": \"application/zip\",\n\t\t\".zip\": \"multipart/x-zip\",\n\t\t\".zoo\": \"application/octet-stream\",\n\t\t\".zsh\": \"text/x-script.zsh\"\n\t};\n\t\n\tfunction spoon(SugarType){\n\t\t// convert to lower case.\n\t\t// remove dots.\n\t\t// pre append one dot.\n\t\t// find in the Mimes list.\n\t\treturn Mimes[\n\t\t\t'.'+SugarType.replace(/\\./g, '').toLowerCase()\n\t\t];\n\t}\n\t\n\tvar Tea = {\n\t   // Empty tea cup here, need to drop some sugar ;)\n\t   // SugarType parameter can be a string or an array of strings.\n\t   cup: function(SugarType){\n\t        // for a single spoon of SugarType, just return the MimeTea cup!\n\t\tif(typeof SugarType === \"string\"){\n\t\t\treturn spoon(SugarType);\n\t\t}\n\t\t\n\t\t// To prevent diabetes, it's better to focus on avoiding weight gain by eating a healthy, well-balanced diet.\n\t\t// Lets check our array of SugarTypes and return an array of MimeTea cups!\n\t\tif( Object.prototype.toString.call( SugarType ) === '[object Array]' ) {\n\t\t\tvar Cups = [];\n\t\t\tfor(var drop in SugarType){\n\t\t\t\tCups.push(spoon(SugarType[drop]));\n\t\t\t}\n\t\t\treturn Cups;\n\t\t}\n\t\treturn false;\n\t   }\n\t};\n\t\n\treturn Tea;\n})();\n\n"
  },
  {
    "path": "src/js/lib/SyntaxHighlighter/shBrushCss.js",
    "content": "/**\n * SyntaxHighlighter\n * http://alexgorbatchev.com/SyntaxHighlighter\n *\n * SyntaxHighlighter is donationware. If you are using it, please donate.\n * http://alexgorbatchev.com/SyntaxHighlighter/donate.html\n *\n * @version\n * 3.0.83 (July 02 2010)\n * \n * @copyright\n * Copyright (C) 2004-2010 Alex Gorbatchev.\n *\n * @license\n * Dual licensed under the MIT and GPL licenses.\n */\n;(function()\n{\n\t// CommonJS\n\ttypeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;\n\n\tfunction Brush()\n\t{\n\t\tfunction getKeywordsCSS(str)\n\t\t{\n\t\t\treturn '\\\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\\\b|\\\\b([a-z_\\\\*]|\\\\*|)') + '(?=:)\\\\b';\n\t\t};\n\t\n\t\tfunction getValuesCSS(str)\n\t\t{\n\t\t\treturn '\\\\b' + str.replace(/ /g, '(?!-)(?!:)\\\\b|\\\\b()') + '\\:\\\\b';\n\t\t};\n\n\t\tvar keywords =\t'ascent azimuth background-attachment background-color background-image background-position ' +\n\t\t\t\t\t\t'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +\n\t\t\t\t\t\t'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +\n\t\t\t\t\t\t'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +\n\t\t\t\t\t\t'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +\n\t\t\t\t\t\t'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +\n\t\t\t\t\t\t'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +\n\t\t\t\t\t\t'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +\n\t\t\t\t\t\t'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +\n\t\t\t\t\t\t'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +\n\t\t\t\t\t\t'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +\n\t\t\t\t\t\t'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +\n\t\t\t\t\t\t'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +\n\t\t\t\t\t\t'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index';\n\n\t\tvar values =\t'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+\n\t\t\t\t\t\t'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+\n\t\t\t\t\t\t'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double '+\n\t\t\t\t\t\t'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+\n\t\t\t\t\t\t'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+\n\t\t\t\t\t\t'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+\n\t\t\t\t\t\t'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+\n\t\t\t\t\t\t'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+\n\t\t\t\t\t\t'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+\n\t\t\t\t\t\t'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+\n\t\t\t\t\t\t'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+\n\t\t\t\t\t\t'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+\n\t\t\t\t\t\t'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+\n\t\t\t\t\t\t'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';\n\n\t\tvar fonts =\t\t'[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif';\n\t\n\t\tthis.regexList = [\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineCComments,\t\tcss: 'comments' },\t// multiline comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },\t// double quoted strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\t// single quoted strings\n\t\t\t{ regex: /\\#[a-fA-F0-9]{3,6}/g,\t\t\t\t\t\t\t\tcss: 'value' },\t\t// html colors\n\t\t\t{ regex: /(-?\\d+)(\\.\\d+)?(px|em|pt|\\:|\\%|)/g,\t\t\t\tcss: 'value' },\t\t// sizes\n\t\t\t{ regex: /!important/g,\t\t\t\t\t\t\t\t\t\tcss: 'color3' },\t// !important\n\t\t\t{ regex: new RegExp(getKeywordsCSS(keywords), 'gm'),\t\tcss: 'keyword' },\t// keywords\n\t\t\t{ regex: new RegExp(getValuesCSS(values), 'g'),\t\t\t\tcss: 'value' },\t\t// values\n\t\t\t{ regex: new RegExp(this.getKeywords(fonts), 'g'),\t\t\tcss: 'color1' }\t\t// fonts\n\t\t\t];\n\n\t\tthis.forHtmlScript({ \n\t\t\tleft: /(&lt;|<)\\s*style.*?(&gt;|>)/gi, \n\t\t\tright: /(&lt;|<)\\/\\s*style\\s*(&gt;|>)/gi \n\t\t\t});\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['css'];\n\n\tSyntaxHighlighter.brushes.CSS = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n"
  },
  {
    "path": "src/js/lib/SyntaxHighlighter/shBrushJScript.js",
    "content": "/**\n * SyntaxHighlighter\n * http://alexgorbatchev.com/SyntaxHighlighter\n *\n * SyntaxHighlighter is donationware. If you are using it, please donate.\n * http://alexgorbatchev.com/SyntaxHighlighter/donate.html\n *\n * @version\n * 3.0.83 (July 02 2010)\n * \n * @copyright\n * Copyright (C) 2004-2010 Alex Gorbatchev.\n *\n * @license\n * Dual licensed under the MIT and GPL licenses.\n */\n;(function()\n{\n\t// CommonJS\n\ttypeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;\n\n\tfunction Brush()\n\t{\n\t\tvar keywords =\t'break case catch continue ' +\n\t\t\t\t\t\t'default delete do else false  ' +\n\t\t\t\t\t\t'for function if in instanceof ' +\n\t\t\t\t\t\t'new null return super switch ' +\n\t\t\t\t\t\t'this throw true try typeof var while with'\n\t\t\t\t\t\t;\n\n\t\tvar r = SyntaxHighlighter.regexLib;\n\t\t\n\t\tthis.regexList = [\n\t\t\t{ regex: r.multiLineDoubleQuotedString,\t\t\t\t\tcss: 'string' },\t\t\t// double quoted strings\n\t\t\t{ regex: r.multiLineSingleQuotedString,\t\t\t\t\tcss: 'string' },\t\t\t// single quoted strings\n\t\t\t{ regex: r.singleLineCComments,\t\t\t\t\t\t\tcss: 'comments' },\t\t\t// one line comments\n\t\t\t{ regex: r.multiLineCComments,\t\t\t\t\t\t\tcss: 'comments' },\t\t\t// multiline comments\n\t\t\t{ regex: /\\s*#.*/gm,\t\t\t\t\t\t\t\t\tcss: 'preprocessor' },\t\t// preprocessor tags like #region and #endregion\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\tcss: 'keyword' }\t\t\t// keywords\n\t\t\t];\n\t\n\t\tthis.forHtmlScript(r.scriptScriptTags);\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['js', 'jscript', 'javascript'];\n\n\tSyntaxHighlighter.brushes.JScript = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n"
  },
  {
    "path": "src/js/lib/SyntaxHighlighter/shCore.js",
    "content": "var XRegExp;\nif (XRegExp) throw Error(\"can't load XRegExp twice in the same frame\"); (function() {\n    function r(f, e) {\n        if (!XRegExp.isRegExp(f)) throw TypeError(\"type RegExp expected\");\n        var a = f._xregexp;\n        f = XRegExp(f.source, t(f) + (e || \"\"));\n        if (a) f._xregexp = {\n            source: a.source,\n            captureNames: a.captureNames ? a.captureNames.slice(0) : null\n        };\n        return f\n    }\n    function t(f) {\n        return (f.global ? \"g\": \"\") + (f.ignoreCase ? \"i\": \"\") + (f.multiline ? \"m\": \"\") + (f.extended ? \"x\": \"\") + (f.sticky ? \"y\": \"\")\n    }\n    function B(f, e, a, b) {\n        var c = u.length,\n        d,\n        h,\n        g;\n        v = true;\n        try {\n            for (; c--;) {\n                g = u[c];\n                if (a & g.scope && (!g.trigger || g.trigger.call(b))) {\n                    g.pattern.lastIndex = e;\n                    if ((h = g.pattern.exec(f)) && h.index === e) {\n                        d = {\n                            output: g.handler.call(b, h, a),\n                            match: h\n                        };\n                        break\n                    }\n                }\n            }\n        } catch(i) {\n            throw i\n        } finally {\n            v = false\n        }\n        return d\n    }\n    function p(f, e, a) {\n        if (Array.prototype.indexOf) return f.indexOf(e, a);\n        for (a = a || 0; a < f.length; a++) if (f[a] === e) return a;\n        return - 1\n    }\n    XRegExp = function(f, e) {\n        var a = [],\n        b = XRegExp.OUTSIDE_CLASS,\n        c = 0,\n        d,\n        h;\n        if (XRegExp.isRegExp(f)) {\n            if (e !== undefined) throw TypeError(\"can't supply flags when constructing one RegExp from another\");\n            return r(f)\n        }\n        if (v) throw Error(\"can't call the XRegExp constructor within token definition functions\");\n        e = e || \"\";\n        for (d = {\n            hasNamedCapture: false,\n            captureNames: [],\n            hasFlag: function(g) {\n                return e.indexOf(g) > -1\n            },\n            setFlag: function(g) {\n                e += g\n            }\n        }; c < f.length;) if (h = B(f, c, b, d)) {\n            a.push(h.output);\n            c += h.match[0].length || 1\n        } else if (h = n.exec.call(z[b], f.slice(c))) {\n            a.push(h[0]);\n            c += h[0].length\n        } else {\n            h = f.charAt(c);\n            if (h === \"[\") b = XRegExp.INSIDE_CLASS;\n            else if (h === \"]\") b = XRegExp.OUTSIDE_CLASS;\n            a.push(h);\n            c++\n        }\n        a = RegExp(a.join(\"\"), n.replace.call(e, w, \"\"));\n        a._xregexp = {\n            source: f,\n            captureNames: d.hasNamedCapture ? d.captureNames: null\n        };\n        return a\n    };\n    XRegExp.version = \"1.5.0\";\n    XRegExp.INSIDE_CLASS = 1;\n    XRegExp.OUTSIDE_CLASS = 2;\n    var C = /\\$(?:(\\d\\d?|[$&`'])|{([$\\w]+)})/g,\n    w = /[^gimy]+|([\\s\\S])(?=[\\s\\S]*\\1)/g,\n    A = /^(?:[?*+]|{\\d+(?:,\\d*)?})\\??/,\n    v = false,\n    u = [],\n    n = {\n        exec: RegExp.prototype.exec,\n        test: RegExp.prototype.test,\n        match: String.prototype.match,\n        replace: String.prototype.replace,\n        split: String.prototype.split\n    },\n    x = n.exec.call(/()??/, \"\")[1] === undefined,\n    D = function() {\n        var f = /^/g;\n        n.test.call(f, \"\");\n        return ! f.lastIndex\n    } (),\n    y = function() {\n        var f = /x/g;\n        n.replace.call(\"x\", f, \"\");\n        return ! f.lastIndex\n    } (),\n    E = RegExp.prototype.sticky !== undefined,\n    z = {};\n    z[XRegExp.INSIDE_CLASS] = /^(?:\\\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\\dA-Fa-f]{2}|u[\\dA-Fa-f]{4}|c[A-Za-z]|[\\s\\S]))/;\n    z[XRegExp.OUTSIDE_CLASS] = /^(?:\\\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\\d*|x[\\dA-Fa-f]{2}|u[\\dA-Fa-f]{4}|c[A-Za-z]|[\\s\\S])|\\(\\?[:=!]|[?*+]\\?|{\\d+(?:,\\d*)?}\\??)/;\n    XRegExp.addToken = function(f, e, a, b) {\n        u.push({\n            pattern: r(f, \"g\" + (E ? \"y\": \"\")),\n            handler: e,\n            scope: a || XRegExp.OUTSIDE_CLASS,\n            trigger: b || null\n        })\n    };\n    XRegExp.cache = function(f, e) {\n        var a = f + \"/\" + (e || \"\");\n        return XRegExp.cache[a] || (XRegExp.cache[a] = XRegExp(f, e))\n    };\n    XRegExp.copyAsGlobal = function(f) {\n        return r(f, \"g\")\n    };\n    XRegExp.escape = function(f) {\n        return f.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\")\n    };\n    XRegExp.execAt = function(f, e, a, b) {\n        e = r(e, \"g\" + (b && E ? \"y\": \"\"));\n        e.lastIndex = a = a || 0;\n        f = e.exec(f);\n        return b ? f && f.index === a ? f: null: f\n    };\n    XRegExp.freezeTokens = function() {\n        XRegExp.addToken = function() {\n            throw Error(\"can't run addToken after freezeTokens\")\n        }\n    };\n    XRegExp.isRegExp = function(f) {\n        return Object.prototype.toString.call(f) === \"[object RegExp]\"\n    };\n    XRegExp.iterate = function(f, e, a, b) {\n        for (var c = r(e, \"g\"), d = -1, h; h = c.exec(f);) {\n            a.call(b, h, ++d, f, c);\n            c.lastIndex === h.index && c.lastIndex++\n        }\n        if (e.global) e.lastIndex = 0\n    };\n    XRegExp.matchChain = function(f, e) {\n        return function a(b, c) {\n            var d = e[c].regex ? e[c] : {\n                regex: e[c]\n            },\n            h = r(d.regex, \"g\"),\n            g = [],\n            i;\n            for (i = 0; i < b.length; i++) XRegExp.iterate(b[i], h,\n            function(k) {\n                g.push(d.backref ? k[d.backref] || \"\": k[0])\n            });\n            return c === e.length - 1 || !g.length ? g: a(g, c + 1)\n        } ([f], 0)\n    };\n    RegExp.prototype.apply = function(f, e) {\n        return this.exec(e[0])\n    };\n    RegExp.prototype.call = function(f, e) {\n        return this.exec(e)\n    };\n    RegExp.prototype.exec = function(f) {\n        var e = n.exec.apply(this, arguments),\n        a;\n        if (e) {\n            if (!x && e.length > 1 && p(e, \"\") > -1) {\n                a = RegExp(this.source, n.replace.call(t(this), \"g\", \"\"));\n                n.replace.call(f.slice(e.index), a,\n                function() {\n                    for (var c = 1; c < arguments.length - 2; c++) if (arguments[c] === undefined) e[c] = undefined\n                })\n            }\n            if (this._xregexp && this._xregexp.captureNames) for (var b = 1; b < e.length; b++) if (a = this._xregexp.captureNames[b - 1]) e[a] = e[b]; ! D && this.global && !e[0].length && this.lastIndex > e.index && this.lastIndex--\n        }\n        return e\n    };\n    if (!D) RegExp.prototype.test = function(f) { (f = n.exec.call(this, f)) && this.global && !f[0].length && this.lastIndex > f.index && this.lastIndex--;\n        return !! f\n    };\n    String.prototype.match = function(f) {\n        XRegExp.isRegExp(f) || (f = RegExp(f));\n        if (f.global) {\n            var e = n.match.apply(this, arguments);\n            f.lastIndex = 0;\n            return e\n        }\n        return f.exec(this)\n    };\n    String.prototype.replace = function(f, e) {\n        var a = XRegExp.isRegExp(f),\n        b,\n        c;\n        if (a && typeof e.valueOf() === \"string\" && e.indexOf(\"${\") === -1 && y) return n.replace.apply(this, arguments);\n        if (a) {\n            if (f._xregexp) b = f._xregexp.captureNames\n        } else f += \"\";\n        if (typeof e === \"function\") c = n.replace.call(this, f,\n        function() {\n            if (b) {\n                arguments[0] = new String(arguments[0]);\n                for (var d = 0; d < b.length; d++) if (b[d]) arguments[0][b[d]] = arguments[d + 1]\n            }\n            if (a && f.global) f.lastIndex = arguments[arguments.length - 2] + arguments[0].length;\n            return e.apply(null, arguments)\n        });\n        else {\n            c = this + \"\";\n            c = n.replace.call(c, f,\n            function() {\n                var d = arguments;\n                return n.replace.call(e, C,\n                function(h, g, i) {\n                    if (g) switch (g) {\n                    case \"$\":\n                        return \"$\";\n                    case \"&\":\n                        return d[0];\n                    case \"`\":\n                        return d[d.length - 1].slice(0, d[d.length - 2]);\n                    case \"'\":\n                        return d[d.length - 1].slice(d[d.length - 2] + d[0].length);\n                    default:\n                        i = \"\";\n                        g = +g;\n                        if (!g) return h;\n                        for (; g > d.length - 3;) {\n                            i = String.prototype.slice.call(g, -1) + i;\n                            g = Math.floor(g / 10)\n                        }\n                        return (g ? d[g] || \"\": \"$\") + i\n                    } else {\n                        g = +i;\n                        if (g <= d.length - 3) return d[g];\n                        g = b ? p(b, i) : -1;\n                        return g > -1 ? d[g + 1] : h\n                    }\n                })\n            })\n        }\n        if (a && f.global) f.lastIndex = 0;\n        return c\n    };\n    String.prototype.split = function(f, e) {\n        if (!XRegExp.isRegExp(f)) return n.split.apply(this, arguments);\n        var a = this + \"\",\n        b = [],\n        c = 0,\n        d,\n        h;\n        if (e === undefined || +e < 0) e = Infinity;\n        else {\n            e = Math.floor( + e);\n            if (!e) return []\n        }\n        for (f = XRegExp.copyAsGlobal(f); d = f.exec(a);) {\n            if (f.lastIndex > c) {\n                b.push(a.slice(c, d.index));\n                d.length > 1 && d.index < a.length && Array.prototype.push.apply(b, d.slice(1));\n                h = d[0].length;\n                c = f.lastIndex;\n                if (b.length >= e) break\n            }\n            f.lastIndex === d.index && f.lastIndex++\n        }\n        if (c === a.length) {\n            if (!n.test.call(f, \"\") || h) b.push(\"\")\n        } else b.push(a.slice(c));\n        return b.length > e ? b.slice(0, e) : b\n    };\n    XRegExp.addToken(/\\(\\?#[^)]*\\)/,\n    function(f) {\n        return n.test.call(A, f.input.slice(f.index + f[0].length)) ? \"\": \"(?:)\"\n    });\n    XRegExp.addToken(/\\((?!\\?)/,\n    function() {\n        this.captureNames.push(null);\n        return \"(\"\n    });\n    XRegExp.addToken(/\\(\\?<([$\\w]+)>/,\n    function(f) {\n        this.captureNames.push(f[1]);\n        this.hasNamedCapture = true;\n        return \"(\"\n    });\n    XRegExp.addToken(/\\\\k<([\\w$]+)>/,\n    function(f) {\n        var e = p(this.captureNames, f[1]);\n        return e > -1 ? \"\\\\\" + (e + 1) + (isNaN(f.input.charAt(f.index + f[0].length)) ? \"\": \"(?:)\") : f[0]\n    });\n    XRegExp.addToken(/\\[\\^?]/,\n    function(f) {\n        return f[0] === \"[]\" ? \"\\\\b\\\\B\": \"[\\\\s\\\\S]\"\n    });\n    XRegExp.addToken(/^\\(\\?([imsx]+)\\)/,\n    function(f) {\n        this.setFlag(f[1]);\n        return \"\"\n    });\n    XRegExp.addToken(/(?:\\s+|#.*)+/,\n    function(f) {\n        return n.test.call(A, f.input.slice(f.index + f[0].length)) ? \"\": \"(?:)\"\n    },\n    XRegExp.OUTSIDE_CLASS,\n    function() {\n        return this.hasFlag(\"x\")\n    });\n    XRegExp.addToken(/\\./,\n    function() {\n        return \"[\\\\s\\\\S]\"\n    },\n    XRegExp.OUTSIDE_CLASS,\n    function() {\n        return this.hasFlag(\"s\")\n    })\n})();\ntypeof exports != \"undefined\" && (exports.XRegExp = XRegExp);\nvar SyntaxHighlighter = function() {\n    function r(a, b) {\n        a.className.indexOf(b) != -1 || (a.className += \" \" + b)\n    }\n    function t(a) {\n        return a.indexOf(\"highlighter_\") == 0 ? a: \"highlighter_\" + a\n    }\n    function B(a) {\n        return e.vars.highlighters[t(a)]\n    }\n    function p(a, b, c) {\n        if (a == null) return null;\n        var d = c != true ? a.childNodes: [a.parentNode],\n        h = {\n            \"#\": \"id\",\n            \".\": \"className\"\n        } [b.substr(0, 1)] || \"nodeName\",\n        g,\n        i;\n        g = h != \"nodeName\" ? b.substr(1) : b.toUpperCase();\n        if ((a[h] || \"\").indexOf(g) != -1) return a;\n        for (a = 0; d && a < d.length && i == null; a++) i = p(d[a], b, c);\n        return i\n    }\n    function C(a, b) {\n        var c = {},\n        d;\n        for (d in a) c[d] = a[d];\n        for (d in b) c[d] = b[d];\n        return c\n    }\n    function w(a, b, c, d) {\n        function h(g) {\n            g = g || window.event;\n            if (!g.target) {\n                g.target = g.srcElement;\n                g.preventDefault = function() {\n                    this.returnValue = false\n                }\n            }\n            c.call(d || window, g)\n        }\n        a.attachEvent ? a.attachEvent(\"on\" + b, h) : a.addEventListener(b, h, false)\n    }\n    function A(a, b) {\n        var c = e.vars.discoveredBrushes,\n        d = null;\n        if (c == null) {\n            c = {};\n            for (var h in e.brushes) {\n                var g = e.brushes[h];\n                d = g.aliases;\n                if (d != null) {\n                    g.brushName = h.toLowerCase();\n                    for (g = 0; g < d.length; g++) c[d[g]] = h\n                }\n            }\n            e.vars.discoveredBrushes = c\n        }\n        d = e.brushes[c[a]];\n        d == null && b != false && window.alert(e.config.strings.alert + (e.config.strings.noBrush + a));\n        return d\n    }\n    function v(a, b) {\n        for (var c = a.split(\"\\n\"), d = 0; d < c.length; d++) c[d] = b(c[d], d);\n        return c.join(\"\\n\")\n    }\n    function u(a, b) {\n        if (a == null || a.length == 0 || a == \"\\n\") return a;\n        a = a.replace(/</g, \"&lt;\");\n        a = a.replace(/ {2,}/g,\n        function(c) {\n            for (var d = \"\", h = 0; h < c.length - 1; h++) d += e.config.space;\n            return d + \" \"\n        });\n        if (b != null) a = v(a,\n        function(c) {\n            if (c.length == 0) return \"\";\n            var d = \"\";\n            c = c.replace(/^(&nbsp;| )+/,\n            function(h) {\n                d = h;\n                return \"\"\n            });\n            if (c.length == 0) return d;\n            return d + '<code class=\"' + b + '\">' + c + \"</code>\"\n        });\n        return a\n    }\n    function n(a, b) {\n        a.split(\"\\n\");\n        for (var c = \"\", d = 0; d < 50; d++) c += \"                    \";\n        return a = v(a,\n        function(h) {\n            if (h.indexOf(\"\\t\") == -1) return h;\n            for (var g = 0; (g = h.indexOf(\"\\t\")) != -1;) h = h.substr(0, g) + c.substr(0, b - g % b) + h.substr(g + 1, h.length);\n            return h\n        })\n    }\n    function x(a) {\n        return a.replace(/^\\s+|\\s+$/g, \"\")\n    }\n    function D(a, b) {\n        if (a.index < b.index) return - 1;\n        else if (a.index > b.index) return 1;\n        else if (a.length < b.length) return - 1;\n        else if (a.length > b.length) return 1;\n        return 0\n    }\n    function y(a, b) {\n        function c(k) {\n            return k[0]\n        }\n        for (var d = null, h = [], g = b.func ? b.func: c; (d = b.regex.exec(a)) != null;) {\n            var i = g(d, b);\n            if (typeof i == \"string\") i = [new e.Match(i, d.index, b.css)];\n            h = h.concat(i)\n        }\n        return h\n    }\n    function E(a) {\n        var b = /(.*)((&gt;|&lt;).*)/;\n        return a.replace(e.regexLib.url,\n        function(c) {\n            var d = \"\",\n            h = null;\n            if (h = b.exec(c)) {\n                c = h[1];\n                d = h[2]\n            }\n            return '<a href=\"' + c + '\">' + c + \"</a>\" + d\n        })\n    }\n    function z() {\n        for (var a = document.getElementsByTagName(\"script\"), b = [], c = 0; c < a.length; c++) a[c].type == \"syntaxhighlighter\" && b.push(a[c]);\n        return b\n    }\n    function f(a) {\n        a = a.target;\n        var b = p(a, \".syntaxhighlighter\", true);\n        a = p(a, \".container\", true);\n        var c = document.createElement(\"textarea\");\n        if (! (!a || !b || p(a, \"textarea\"))) {\n            B(b.id);\n            r(b, \"source\");\n            for (var d = a.childNodes, h = [], g = 0; g < d.length; g++) h.push(d[g].innerText || d[g].textContent);\n            h = h.join(\"\\r\");\n            c.appendChild(document.createTextNode(h));\n            a.appendChild(c);\n            c.focus();\n            c.select();\n            w(c, \"blur\",\n            function() {\n                c.parentNode.removeChild(c);\n                b.className = b.className.replace(\"source\", \"\")\n            })\n        }\n    }\n    if (typeof require != \"undefined\" && typeof XRegExp == \"undefined\") XRegExp = require(\"XRegExp\").XRegExp;\n    var e = {\n        defaults: {\n            \"class-name\": \"\",\n            \"first-line\": 1,\n            \"pad-line-numbers\": false,\n            highlight: null,\n            title: null,\n            \"smart-tabs\": true,\n            \"tab-size\": 4,\n            gutter: true,\n            toolbar: true,\n            \"quick-code\": true,\n            collapse: false,\n            \"auto-links\": true,\n            light: false,\n            \"html-script\": false\n        },\n        config: {\n            space: \"&nbsp;\",\n            useScriptTags: true,\n            bloggerMode: false,\n            stripBrs: false,\n            tagName: \"pre\",\n            strings: {\n                expandSource: \"expand source\",\n                help: \"?\",\n                alert: \"SyntaxHighlighter\\n\\n\",\n                noBrush: \"Can't find brush for: \",\n                brushNotHtmlScript: \"Brush wasn't configured for html-script option: \",\n                aboutDialog: '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /><title>About SyntaxHighlighter</title></head><body style=\"font-family:Geneva,Arial,Helvetica,sans-serif;background-color:#fff;color:#000;font-size:1em;text-align:center;\"><div style=\"text-align:center;margin-top:1.5em;\"><div style=\"font-size:xx-large;\">SyntaxHighlighter</div><div style=\"font-size:.75em;margin-bottom:3em;\"><div>version 3.0.83 (July 02 2010)</div><div><a href=\"http://alexgorbatchev.com/SyntaxHighlighter\" target=\"_blank\" style=\"color:#005896\">http://alexgorbatchev.com/SyntaxHighlighter</a></div><div>JavaScript code syntax highlighter.</div><div>Copyright 2004-2010 Alex Gorbatchev.</div></div><div>If you like this script, please <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2930402\" style=\"color:#005896\">donate</a> to <br/>keep development active!</div></div></body></html>'\n            }\n        },\n        vars: {\n            discoveredBrushes: null,\n            highlighters: {}\n        },\n        brushes: {},\n        regexLib: {\n            multiLineCComments: /\\/\\*[\\s\\S]*?\\*\\//gm,\n            singleLineCComments: /\\/\\/.*$/gm,\n            singleLinePerlComments: /#.*$/gm,\n            doubleQuotedString: /\"([^\\\\\"\\n]|\\\\.)*\"/g,\n            singleQuotedString: /'([^\\\\'\\n]|\\\\.)*'/g,\n            multiLineDoubleQuotedString: new XRegExp('\"([^\\\\\\\\\"]|\\\\\\\\.)*\"', \"gs\"),\n            multiLineSingleQuotedString: new XRegExp(\"'([^\\\\\\\\']|\\\\\\\\.)*'\", \"gs\"),\n            xmlComments: /(&lt;|<)!--[\\s\\S]*?--(&gt;|>)/gm,\n            url: /\\w+:\\/\\/[\\w-.\\/?%&=:@;]*/g,\n            phpScriptTags: {\n                left: /(&lt;|<)\\?=?/g,\n                right: /\\?(&gt;|>)/g\n            },\n            aspScriptTags: {\n                left: /(&lt;|<)%=?/g,\n                right: /%(&gt;|>)/g\n            },\n            scriptScriptTags: {\n                left: /(&lt;|<)\\s*script.*?(&gt;|>)/gi,\n                right: /(&lt;|<)\\/\\s*script\\s*(&gt;|>)/gi\n            }\n        },\n        toolbar: {\n            getHtml: function(a) {\n                function b(i, k) {\n                    return e.toolbar.getButtonHtml(i, k, e.config.strings[k])\n                }\n                for (var c = '<div class=\"toolbar\">', d = e.toolbar.items, h = d.list, g = 0; g < h.length; g++) c += (d[h[g]].getHtml || b)(a, h[g]);\n                c += \"</div>\";\n                return c\n            },\n            getButtonHtml: function(a, b, c) {\n                return '<span><a href=\"#\" class=\"toolbar_item command_' + b + \" \" + b + '\">' + c + \"</a></span>\"\n            },\n            handler: function(a) {\n                var b = a.target,\n                c = b.className || \"\";\n                b = B(p(b, \".syntaxhighlighter\", true).id);\n                var d = function(h) {\n                    return (h = RegExp(h + \"_(\\\\w+)\").exec(c)) ? h[1] : null\n                } (\"command\");\n                b && d && e.toolbar.items[d].execute(b);\n                a.preventDefault()\n            },\n            items: {\n                list: [\"expandSource\", \"help\"],\n                expandSource: {\n                    getHtml: function(a) {\n                        if (a.getParam(\"collapse\") != true) return \"\";\n                        var b = a.getParam(\"title\");\n                        return e.toolbar.getButtonHtml(a, \"expandSource\", b ? b: e.config.strings.expandSource)\n                    },\n                    execute: function(a) {\n                        a = document.getElementById(t(a.id));\n                        a.className = a.className.replace(\"collapsed\", \"\")\n                    }\n                },\n                help: {\n                    execute: function() {\n                        var a = \"scrollbars=0\";\n                        a += \", left=\" + (screen.width - 500) / 2 + \", top=\" + (screen.height - 250) / 2 + \", width=500, height=250\";\n                        a = a.replace(/^,/, \"\");\n                        a = window.open(\"\", \"_blank\", a);\n                        a.focus();\n                        var b = a.document;\n                        b.write(e.config.strings.aboutDialog);\n                        b.close();\n                        a.focus()\n                    }\n                }\n            }\n        },\n        findElements: function(a, b) {\n            var c;\n            if (b) c = [b];\n            else {\n                c = document.getElementsByTagName(e.config.tagName);\n                for (var d = [], h = 0; h < c.length; h++) d.push(c[h]);\n                c = d\n            }\n            c = c;\n            d = [];\n            if (e.config.useScriptTags) c = c.concat(z());\n            if (c.length === 0) return d;\n            for (h = 0; h < c.length; h++) {\n                for (var g = c[h], i = a, k = c[h].className, j = void 0, l = {},\n                m = new XRegExp(\"^\\\\[(?<values>(.*?))\\\\]$\"), s = new XRegExp(\"(?<name>[\\\\w-]+)\\\\s*:\\\\s*(?<value>[\\\\w-%#]+|\\\\[.*?\\\\]|\\\".*?\\\"|'.*?')\\\\s*;?\", \"g\"); (j = s.exec(k)) != null;) {\n                    var o = j.value.replace(/^['\"]|['\"]$/g, \"\");\n                    if (o != null && m.test(o)) {\n                        o = m.exec(o);\n                        o = o.values.length > 0 ? o.values.split(/\\s*,\\s*/) : []\n                    }\n                    l[j.name] = o\n                }\n                g = {\n                    target: g,\n                    params: C(i, l)\n                };\n                g.params.brush != null && d.push(g)\n            }\n            return d\n        },\n        highlight: function(a, b) {\n            var c = this.findElements(a, b),\n            d = null,\n            h = e.config;\n            if (c.length !== 0) for (var g = 0; g < c.length; g++) {\n                b = c[g];\n                var i = b.target,\n                k = b.params,\n                j = k.brush,\n                l;\n                if (j != null) {\n                    if (k[\"html-script\"] == \"true\" || e.defaults[\"html-script\"] == true) {\n                        d = new e.HtmlScript(j);\n                        j = \"htmlscript\"\n                    } else if (d = A(j)) d = new d;\n                    else continue;\n                    l = i.innerHTML;\n                    if (h.useScriptTags) {\n                        l = l;\n                        var m = x(l),\n                        s = false;\n                        if (m.indexOf(\"<![CDATA[\") == 0) {\n                            m = m.substring(9);\n                            s = true\n                        }\n                        var o = m.length;\n                        if (m.indexOf(\"]]\\>\") == o - 3) {\n                            m = m.substring(0, o - 3);\n                            s = true\n                        }\n                        l = s ? m: l\n                    }\n                    if ((i.title || \"\") != \"\") k.title = i.title;\n                    k.brush = j;\n                    d.init(k);\n                    b = d.getDiv(l);\n                    if ((i.id || \"\") != \"\") b.id = i.id;\n                    i.parentNode.replaceChild(b, i)\n                }\n            }\n        },\n        all: function(a) {\n            w(window, \"load\",\n            function() {\n                e.highlight(a)\n            })\n        }\n    };\n    e.all = e.all;\n    e.highlight = e.highlight;\n    e.Match = function(a, b, c) {\n        this.value = a;\n        this.index = b;\n        this.length = a.length;\n        this.css = c;\n        this.brushName = null\n    };\n    e.Match.prototype.toString = function() {\n        return this.value\n    };\n    e.HtmlScript = function(a) {\n        function b(j, l) {\n            for (var m = 0; m < j.length; m++) j[m].index += l\n        }\n        var c = A(a),\n        d,\n        h = new e.brushes.Xml,\n        g = this,\n        i = \"getDiv getHtml init\".split(\" \");\n        if (c != null) {\n            d = new c;\n            for (var k = 0; k < i.length; k++)(function() {\n                var j = i[k];\n                g[j] = function() {\n                    return h[j].apply(h, arguments)\n                }\n            })();\n            d.htmlScript == null ? window.alert(e.config.strings.alert + (e.config.strings.brushNotHtmlScript + a)) : h.regexList.push({\n                regex: d.htmlScript.code,\n                func: function(j) {\n                    for (var l = j.code, m = [], s = d.regexList, o = j.index + j.left.length, F = d.htmlScript, q, G = 0; G < s.length; G++) {\n                        q = y(l, s[G]);\n                        b(q, o);\n                        m = m.concat(q)\n                    }\n                    if (F.left != null && j.left != null) {\n                        q = y(j.left, F.left);\n                        b(q, j.index);\n                        m = m.concat(q)\n                    }\n                    if (F.right != null && j.right != null) {\n                        q = y(j.right, F.right);\n                        b(q, j.index + j[0].lastIndexOf(j.right));\n                        m = m.concat(q)\n                    }\n                    for (j = 0; j < m.length; j++) m[j].brushName = c.brushName;\n                    return m\n                }\n            })\n        }\n    };\n    e.Highlighter = function() {};\n    e.Highlighter.prototype = {\n        getParam: function(a, b) {\n            var c = this.params[a];\n            c = c == null ? b: c;\n            var d = {\n                \"true\": true,\n                \"false\": false\n            } [c];\n            return d == null ? c: d\n        },\n        create: function(a) {\n            return document.createElement(a)\n        },\n        findMatches: function(a, b) {\n            var c = [];\n            if (a != null) for (var d = 0; d < a.length; d++) if (typeof a[d] == \"object\") c = c.concat(y(b, a[d]));\n            return this.removeNestedMatches(c.sort(D))\n        },\n        removeNestedMatches: function(a) {\n            for (var b = 0; b < a.length; b++) if (a[b] !== null) for (var c = a[b], d = c.index + c.length, h = b + 1; h < a.length && a[b] !== null; h++) {\n                var g = a[h];\n                if (g !== null) if (g.index > d) break;\n                else if (g.index == c.index && g.length > c.length) a[b] = null;\n                else if (g.index >= c.index && g.index < d) a[h] = null\n            }\n            return a\n        },\n        figureOutLineNumbers: function(a) {\n            var b = [],\n            c = parseInt(this.getParam(\"first-line\"));\n            v(a,\n            function(d, h) {\n                b.push(h + c)\n            });\n            return b\n        },\n        isLineHighlighted: function(a) {\n            var b = this.getParam(\"highlight\", []);\n            if (typeof b != \"object\" && b.push == null) b = [b];\n            a: {\n                a = a.toString();\n                var c = void 0;\n                for (c = c = Math.max(c || 0, 0); c < b.length; c++) if (b[c] == a) {\n                    b = c;\n                    break a\n                }\n                b = -1\n            }\n            return b != -1\n        },\n        getLineHtml: function(a, b, c) {\n            a = [\"line\", \"number\" + b, \"index\" + a, \"alt\" + (b % 2 == 0 ? 1: 2).toString()];\n            this.isLineHighlighted(b) && a.push(\"highlighted\");\n            b == 0 && a.push(\"break\");\n            return '<div class=\"' + a.join(\" \") + '\">' + c + \"</div>\"\n        },\n        getLineNumbersHtml: function(a, b) {\n            var c = \"\",\n            d = a.split(\"\\n\").length,\n            h = parseInt(this.getParam(\"first-line\")),\n            g = this.getParam(\"pad-line-numbers\");\n            if (g == true) g = (h + d - 1).toString().length;\n            else if (isNaN(g) == true) g = 0;\n            for (var i = 0; i < d; i++) {\n                var k = b ? b[i] : h + i,\n                j;\n                if (k == 0) j = e.config.space;\n                else {\n                    j = g;\n                    for (var l = k.toString(); l.length < j;) l = \"0\" + l;\n                    j = l\n                }\n                a = j;\n                c += this.getLineHtml(i, k, a)\n            }\n            return c\n        },\n        getCodeLinesHtml: function(a, b) {\n            a = x(a);\n            var c = a.split(\"\\n\");\n            this.getParam(\"pad-line-numbers\");\n            var d = parseInt(this.getParam(\"first-line\"));\n            a = \"\";\n            for (var h = this.getParam(\"brush\"), g = 0; g < c.length; g++) {\n                var i = c[g],\n                k = /^(&nbsp;|\\s)+/.exec(i),\n                j = null,\n                l = b ? b[g] : d + g;\n                if (k != null) {\n                    j = k[0].toString();\n                    i = i.substr(j.length);\n                    j = j.replace(\" \", e.config.space)\n                }\n                i = x(i);\n                if (i.length == 0) i = e.config.space;\n                a += this.getLineHtml(g, l, (j != null ? '<code class=\"' + h + ' spaces\">' + j + \"</code>\": \"\") + i)\n            }\n            return a\n        },\n        getTitleHtml: function(a) {\n            return a ? \"<caption>\" + a + \"</caption>\": \"\"\n        },\n        getMatchesHtml: function(a, b) {\n            function c(l) {\n                return (l = l ? l.brushName || g: g) ? l + \" \": \"\"\n            }\n            for (var d = 0, h = \"\", g = this.getParam(\"brush\", \"\"), i = 0; i < b.length; i++) {\n                var k = b[i],\n                j;\n                if (! (k === null || k.length === 0)) {\n                    j = c(k);\n                    h += u(a.substr(d, k.index - d), j + \"plain\") + u(k.value, j + k.css);\n                    d = k.index + k.length + (k.offset || 0)\n                }\n            }\n            h += u(a.substr(d), c() + \"plain\");\n            return h\n        },\n        getHtml: function(a) {\n            var b = \"\",\n            c = [\"syntaxhighlighter\"],\n            d;\n            if (this.getParam(\"light\") == true) this.params.toolbar = this.params.gutter = false;\n            className = \"syntaxhighlighter\";\n            this.getParam(\"collapse\") == true && c.push(\"collapsed\");\n            if ((gutter = this.getParam(\"gutter\")) == false) c.push(\"nogutter\");\n            c.push(this.getParam(\"class-name\"));\n            c.push(this.getParam(\"brush\"));\n            a = a.replace(/^[ ]*[\\n]+|[\\n]*[ ]*$/g, \"\").replace(/\\r/g, \" \");\n            b = this.getParam(\"tab-size\");\n            if (this.getParam(\"smart-tabs\") == true) a = n(a, b);\n            else {\n                for (var h = \"\", g = 0; g < b; g++) h += \" \";\n                a = a.replace(/\\t/g, h)\n            }\n            a = a;\n            a: {\n                b = a = a;\n                h = /<br\\s*\\/?>|&lt;br\\s*\\/?&gt;/gi;\n                if (e.config.bloggerMode == true) b = b.replace(h, \"\\n\");\n                if (e.config.stripBrs == true) b = b.replace(h, \"\");\n                b = b.split(\"\\n\");\n                h = /^\\s*/;\n                g = 1E3;\n                for (var i = 0; i < b.length && g > 0; i++) {\n                    var k = b[i];\n                    if (x(k).length != 0) {\n                        k = h.exec(k);\n                        if (k == null) {\n                            a = a;\n                            break a\n                        }\n                        g = Math.min(k[0].length, g)\n                    }\n                }\n                if (g > 0) for (i = 0; i < b.length; i++) b[i] = b[i].substr(g);\n                a = b.join(\"\\n\")\n            }\n            if (gutter) d = this.figureOutLineNumbers(a);\n            b = this.findMatches(this.regexList, a);\n            b = this.getMatchesHtml(a, b);\n            b = this.getCodeLinesHtml(b, d);\n            if (this.getParam(\"auto-links\")) b = E(b);\n            typeof navigator != \"undefined\" && navigator.userAgent && navigator.userAgent.match(/MSIE/) && c.push(\"ie\");\n            return b = '<div id=\"' + t(this.id) + '\" class=\"' + c.join(\" \") + '\">' + (this.getParam(\"toolbar\") ? e.toolbar.getHtml(this) : \"\") + '<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">' + this.getTitleHtml(this.getParam(\"title\")) + \"<tbody><tr>\" + (gutter ? '<td class=\"gutter\">' + this.getLineNumbersHtml(a) + \"</td>\": \"\") + '<td class=\"code\"><div class=\"container\">' + b + \"</div></td></tr></tbody></table></div>\"\n        },\n        getDiv: function(a) {\n            if (a === null) a = \"\";\n            this.code = a;\n            var b = this.create(\"div\");\n            b.innerHTML = this.getHtml(a);\n            this.getParam(\"toolbar\") && w(p(b, \".toolbar\"), \"click\", e.toolbar.handler);\n            this.getParam(\"quick-code\") && w(p(b, \".code\"), \"dblclick\", f);\n            return b\n        },\n        init: function(a) {\n            this.id = \"\" + Math.round(Math.random() * 1E6).toString();\n            e.vars.highlighters[t(this.id)] = this;\n            this.params = C(e.defaults, a || {});\n            if (this.getParam(\"light\") == true) this.params.toolbar = this.params.gutter = false\n        },\n        getKeywords: function(a) {\n            a = a.replace(/^\\s+|\\s+$/g, \"\").replace(/\\s+/g, \"|\");\n            return \"\\\\b(?:\" + a + \")\\\\b\"\n        },\n        forHtmlScript: function(a) {\n            this.htmlScript = {\n                left: {\n                    regex: a.left,\n                    css: \"script\"\n                },\n                right: {\n                    regex: a.right,\n                    css: \"script\"\n                },\n                code: new XRegExp(\"(?<left>\" + a.left.source + \")(?<code>.*?)(?<right>\" + a.right.source + \")\", \"sgi\")\n            }\n        }\n    };\n    return e\n} ();\ntypeof exports != \"undefined\" && (exports.SyntaxHighlighter = SyntaxHighlighter);"
  },
  {
    "path": "src/js/lib/base64.js",
    "content": "var Base64 = function() {  \n    // private property  \n    _keyStr = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";  \n   \n    // public method for encoding  \n    var encode = function (input) {  \n        var output = \"\";  \n        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;  \n        var i = 0;  \n        input = _utf8_encode(input);  \n        while (i < input.length) {  \n            chr1 = input.charCodeAt(i++);  \n            chr2 = input.charCodeAt(i++);  \n            chr3 = input.charCodeAt(i++);  \n            enc1 = chr1 >> 2;  \n            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);  \n            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);  \n            enc4 = chr3 & 63;  \n            if (isNaN(chr2)) {  \n                enc3 = enc4 = 64;  \n            } else if (isNaN(chr3)) {  \n                enc4 = 64;  \n            }  \n            output = output +  \n            _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +  \n            _keyStr.charAt(enc3) + _keyStr.charAt(enc4);  \n        }  \n        return output;  \n    }  \n   \n    // public method for decoding  \n    var decode = function (input) {  \n        var output = \"\";  \n        var chr1, chr2, chr3;  \n        var enc1, enc2, enc3, enc4;  \n        var i = 0;  \n        input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");  \n        while (i < input.length) {  \n            enc1 = _keyStr.indexOf(input.charAt(i++));  \n            enc2 = _keyStr.indexOf(input.charAt(i++));  \n            enc3 = _keyStr.indexOf(input.charAt(i++));  \n            enc4 = _keyStr.indexOf(input.charAt(i++));  \n            chr1 = (enc1 << 2) | (enc2 >> 4);  \n            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);  \n            chr3 = ((enc3 & 3) << 6) | enc4;  \n            output = output + String.fromCharCode(chr1);  \n            if (enc3 != 64) {  \n                output = output + String.fromCharCode(chr2);  \n            }  \n            if (enc4 != 64) {  \n                output = output + String.fromCharCode(chr3);  \n            }  \n        }  \n        output = _utf8_decode(output);  \n        return output;  \n    }  \n   \n    // private method for UTF-8 encoding  \n    _utf8_encode = function (string) {  \n        string = string.replace(/\\r\\n/g,\"\\n\");  \n        var utftext = \"\";  \n        for (var n = 0; n < string.length; n++) {  \n            var c = string.charCodeAt(n);  \n            if (c < 128) {  \n                utftext += String.fromCharCode(c);  \n            } else if((c > 127) && (c < 2048)) {  \n                utftext += String.fromCharCode((c >> 6) | 192);  \n                utftext += String.fromCharCode((c & 63) | 128);  \n            } else {  \n                utftext += String.fromCharCode((c >> 12) | 224);  \n                utftext += String.fromCharCode(((c >> 6) & 63) | 128);  \n                utftext += String.fromCharCode((c & 63) | 128);  \n            }  \n   \n        }  \n        return utftext;  \n    }  \n   \n    // private method for UTF-8 decoding  \n    _utf8_decode = function (utftext) {  \n        var string = \"\";  \n        var i = 0;  \n        var c = c1 = c2 = 0;  \n        while ( i < utftext.length ) {  \n            c = utftext.charCodeAt(i);  \n            if (c < 128) {  \n                string += String.fromCharCode(c);  \n                i++;  \n            } else if((c > 191) && (c < 224)) {  \n                c2 = utftext.charCodeAt(i+1);  \n                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));  \n                i += 2;  \n            } else {  \n                c2 = utftext.charCodeAt(i+1);  \n                c3 = utftext.charCodeAt(i+2);  \n                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));  \n                i += 3;  \n            }  \n        }  \n        return string;  \n    } \n    return {\n        encode: encode,\n        decode: decode\n    }\n}();"
  },
  {
    "path": "src/js/lib/beautify/beautify_css.js",
    "content": "/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */\n/*\n\n  The MIT License (MIT)\n\n  Copyright (c) 2007-2013 Einar Lielmanis and contributors.\n\n  Permission is hereby granted, free of charge, to any person\n  obtaining a copy of this software and associated documentation files\n  (the \"Software\"), to deal in the Software without restriction,\n  including without limitation the rights to use, copy, modify, merge,\n  publish, distribute, sublicense, and/or sell copies of the Software,\n  and to permit persons to whom the Software is furnished to do so,\n  subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be\n  included in all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\n  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n  SOFTWARE.\n\n\n CSS Beautifier\n---------------\n\n    Written by Harutyun Amirjanyan, (amirjanyan@gmail.com)\n\n    Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>\n        http://jsbeautifier.org/\n\n    Usage:\n        css_beautify(source_text);\n        css_beautify(source_text, options);\n\n    The options are:\n        indent_size (default 4)          — indentation size,\n        indent_char (default space)      — character to indent with,\n\n    e.g\n\n    css_beautify(css_source_text, {\n      'indent_size': 1,\n      'indent_char': '\\t'\n    });\n*/\n\n// http://www.w3.org/TR/CSS21/syndata.html#tokenization\n// http://www.w3.org/TR/css3-syntax/\n\n(function() {\n    function css_beautify(source_text, options) {\n        options = options || {};\n        var indentSize = options.indent_size || 4;\n        var indentCharacter = options.indent_char || ' ';\n\n        // compatibility\n        if (typeof indentSize === \"string\") {\n            indentSize = parseInt(indentSize, 10);\n        }\n\n\n        // tokenizer\n        var whiteRe = /^\\s+$/;\n        var wordRe = /[\\w$\\-_]/;\n\n        var pos = -1,\n            ch;\n\n        function next() {\n            ch = source_text.charAt(++pos);\n            return ch;\n        }\n\n        function peek() {\n            return source_text.charAt(pos + 1);\n        }\n\n        function eatString(comma) {\n            var start = pos;\n            while (next()) {\n                if (ch === \"\\\\\") {\n                    next();\n                    next();\n                } else if (ch === comma) {\n                    break;\n                } else if (ch === \"\\n\") {\n                    break;\n                }\n            }\n            return source_text.substring(start, pos + 1);\n        }\n\n        function eatWhitespace() {\n            var start = pos;\n            while (whiteRe.test(peek())) {\n                pos++;\n            }\n            return pos !== start;\n        }\n\n        function skipWhitespace() {\n            var start = pos;\n            do {} while (whiteRe.test(next()));\n            return pos !== start + 1;\n        }\n\n        function eatComment() {\n            var start = pos;\n            next();\n            while (next()) {\n                if (ch === \"*\" && peek() === \"/\") {\n                    pos++;\n                    break;\n                }\n            }\n\n            return source_text.substring(start, pos + 1);\n        }\n\n\n        function lookBack(str) {\n            return source_text.substring(pos - str.length, pos).toLowerCase() === str;\n        }\n\n        // printer\n        var indentString = source_text.match(/^[\\r\\n]*[\\t ]*/)[0];\n        var singleIndent = Array(indentSize + 1).join(indentCharacter);\n        var indentLevel = 0;\n\n        function indent() {\n            indentLevel++;\n            indentString += singleIndent;\n        }\n\n        function outdent() {\n            indentLevel--;\n            indentString = indentString.slice(0, -indentSize);\n        }\n\n        var print = {};\n        print[\"{\"] = function(ch) {\n            print.singleSpace();\n            output.push(ch);\n            print.newLine();\n        };\n        print[\"}\"] = function(ch) {\n            print.newLine();\n            output.push(ch);\n            print.newLine();\n        };\n\n        print.newLine = function(keepWhitespace) {\n            if (!keepWhitespace) {\n                while (whiteRe.test(output[output.length - 1])) {\n                    output.pop();\n                }\n            }\n\n            if (output.length) {\n                output.push('\\n');\n            }\n            if (indentString) {\n                output.push(indentString);\n            }\n        };\n        print.singleSpace = function() {\n            if (output.length && !whiteRe.test(output[output.length - 1])) {\n                output.push(' ');\n            }\n        };\n        var output = [];\n        if (indentString) {\n            output.push(indentString);\n        }\n        /*_____________________--------------------_____________________*/\n\n        while (true) {\n            var isAfterSpace = skipWhitespace();\n\n            if (!ch) {\n                break;\n            }\n\n\n            if (ch === '{') {\n                indent();\n                print[\"{\"](ch);\n            } else if (ch === '}') {\n                outdent();\n                print[\"}\"](ch);\n            } else if (ch === '\"' || ch === '\\'') {\n                output.push(eatString(ch));\n            } else if (ch === ';') {\n                output.push(ch, '\\n', indentString);\n            } else if (ch === '/' && peek() === '*') { // comment\n                print.newLine();\n                output.push(eatComment(), \"\\n\", indentString);\n            } else if (ch === '(') { // may be a url\n                if (lookBack(\"url\")) {\n                    output.push(ch);\n                    eatWhitespace();\n                    if (next()) {\n                        if (ch !== ')' && ch !== '\"' && ch !== '\\'') {\n                            output.push(eatString(')'));\n                        } else {\n                            pos--;\n                        }\n                    }\n                } else {\n                    if (isAfterSpace) {\n                        print.singleSpace();\n                    }\n                    output.push(ch);\n                    eatWhitespace();\n                }\n            } else if (ch === ')') {\n                output.push(ch);\n            } else if (ch === ',') {\n                eatWhitespace();\n                output.push(ch);\n                print.singleSpace();\n            } else if (ch === ']') {\n                output.push(ch);\n            } else if (ch === '[' || ch === '=') { // no whitespace before or after\n                eatWhitespace();\n                output.push(ch);\n            } else {\n                if (isAfterSpace) {\n                    print.singleSpace();\n                }\n\n                output.push(ch);\n            }\n        }\n\n\n        var sweetCode = output.join('').replace(/[\\n ]+$/, '');\n        return sweetCode;\n    }\n\n    if (typeof define === \"function\") {\n        // Add support for require.js\n        define(function(require, exports, module) {\n            exports.css_beautify = css_beautify;\n        });\n    } else if (typeof exports !== \"undefined\") {\n        // Add support for CommonJS. Just put this file somewhere on your require.paths\n        // and you will be able to `var html_beautify = require(\"beautify\").html_beautify`.\n        exports.css_beautify = css_beautify;\n    } else if (typeof window !== \"undefined\") {\n        // If we're running a web page and don't have either of the above, add our one global\n        window.css_beautify = css_beautify;\n    } else if (typeof global !== \"undefined\") {\n        // If we don't even have window, try global.\n        global.css_beautify = css_beautify;\n    }\n\n}());"
  },
  {
    "path": "src/js/lib/beautify/beautify_html.js",
    "content": "/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */\n/*\n\n  The MIT License (MIT)\n\n  Copyright (c) 2007-2013 Einar Lielmanis and contributors.\n\n  Permission is hereby granted, free of charge, to any person\n  obtaining a copy of this software and associated documentation files\n  (the \"Software\"), to deal in the Software without restriction,\n  including without limitation the rights to use, copy, modify, merge,\n  publish, distribute, sublicense, and/or sell copies of the Software,\n  and to permit persons to whom the Software is furnished to do so,\n  subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be\n  included in all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\n  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n  SOFTWARE.\n\n\n Style HTML\n---------------\n\n  Written by Nochum Sossonko, (nsossonko@hotmail.com)\n\n  Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>\n    http://jsbeautifier.org/\n\n  Usage:\n    style_html(html_source);\n\n    style_html(html_source, options);\n\n  The options are:\n    indent_size (default 4)          — indentation size,\n    indent_char (default space)      — character to indent with,\n    wrap_line_length (default 250)            -  maximum amount of characters per line (0 = disable)\n    brace_style (default \"collapse\") - \"collapse\" | \"expand\" | \"end-expand\"\n            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.\n    unformatted (defaults to inline tags) - list of tags, that shouldn't be reformatted\n    indent_scripts (default normal)  - \"keep\"|\"separate\"|\"normal\"\n    preserve_newlines (default true) - whether existing line breaks before elements should be preserved\n                                        Only works before elements, not inside tags or for text.\n    max_preserve_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk\n\n    e.g.\n\n    style_html(html_source, {\n      'indent_size': 2,\n      'indent_char': ' ',\n      'wrap_line_length': 78,\n      'brace_style': 'expand',\n      'unformatted': ['a', 'sub', 'sup', 'b', 'i', 'u'],\n      'preserve_newlines': true,\n      'max_preserve_newlines': 5\n    });\n*/\n\n(function() {\n\n    function trim(s) {\n        return s.replace(/^\\s+|\\s+$/g, '');\n    }\n\n    function ltrim(s) {\n        return s.replace(/^\\s+/g, '');\n    }\n\n    function style_html(html_source, options, js_beautify, css_beautify) {\n        //Wrapper function to invoke all the necessary constructors and deal with the output.\n\n        var multi_parser,\n            indent_size,\n            indent_character,\n            wrap_line_length,\n            brace_style,\n            unformatted,\n            preserve_newlines,\n            max_preserve_newlines;\n\n        options = options || {};\n\n        // backwards compatibility to 1.3.4\n        if (options.wrap_line_length == undefined && options.max_char != undefined) {\n            options.wrap_line_length = options.max_char;\n        }\n\n        indent_size = parseInt(options.indent_size || 4);\n        indent_character = options.indent_char || ' ';\n        brace_style = options.brace_style || 'collapse';\n        wrap_line_length = options.wrap_line_length === 0 ? 32786 : parseInt(options.wrap_line_length || 250);\n        unformatted = options.unformatted || ['a', 'span', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike', 'font', 'ins', 'del', 'pre', 'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];\n        preserve_newlines = options.preserve_newlines || true;\n        max_preserve_newlines = preserve_newlines ? parseInt(options.max_preserve_newlines || 32786) : 0;\n\n        function Parser() {\n\n            this.pos = 0; //Parser position\n            this.token = '';\n            this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT\n            this.tags = { //An object to hold tags, their position, and their parent-tags, initiated with default values\n                parent: 'parent1',\n                parentcount: 1,\n                parent1: ''\n            };\n            this.tag_type = '';\n            this.token_text = this.last_token = this.last_text = this.token_type = '';\n            this.newlines = 0;\n            this.indent_content = false;\n\n            this.Utils = { //Uilities made available to the various functions\n                whitespace: \"\\n\\r\\t \".split(''),\n                single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed,?php,?,?='.split(','), //all the single tags for HTML\n                extra_liners: 'head,body,/html'.split(','), //for tags that need a line of whitespace before them\n                in_array: function(what, arr) {\n                    for (var i = 0; i < arr.length; i++) {\n                        if (what === arr[i]) {\n                            return true;\n                        }\n                    }\n                    return false;\n                }\n            };\n\n            this.traverse_whitespace = function() {\n                var input_char = '';\n\n                input_char = this.input.charAt(this.pos);\n                if (this.Utils.in_array(input_char, this.Utils.whitespace)) {\n                    this.newlines = 0;\n                    while (this.Utils.in_array(input_char, this.Utils.whitespace)) {\n                        if (preserve_newlines && input_char === '\\n' && this.newlines <= max_preserve_newlines) {\n                            this.newlines += 1;\n                        }\n\n                        this.pos++;\n                        input_char = this.input.charAt(this.pos);\n                    }\n                    return true;\n                }\n                return false;\n            }\n\n            this.get_content = function() { //function to capture regular content between tags\n\n                var input_char = '',\n                    content = [],\n                    space = false; //if a space is needed\n\n                while (this.input.charAt(this.pos) !== '<') {\n                    if (this.pos >= this.input.length) {\n                        return content.length ? content.join('') : ['', 'TK_EOF'];\n                    }\n\n                    if (this.traverse_whitespace()) {\n                        if (content.length) {\n                            space = true;\n                        }\n                        continue; //don't want to insert unnecessary space\n                    }\n\n                    input_char = this.input.charAt(this.pos);\n                    this.pos++;\n\n                    if (space) {\n                        if (this.line_char_count >= this.wrap_line_length) { //insert a line when the wrap_line_length is reached\n                            this.print_newline(false, content);\n                            this.print_indentation(content);\n                        } else {\n                            this.line_char_count++;\n                            content.push(' ');\n                        }\n                        space = false;\n                    }\n                    this.line_char_count++;\n                    content.push(input_char); //letter at-a-time (or string) inserted to an array\n                }\n                return content.length ? content.join('') : '';\n            };\n\n            this.get_contents_to = function(name) { //get the full content of a script or style to pass to js_beautify\n                if (this.pos === this.input.length) {\n                    return ['', 'TK_EOF'];\n                }\n                var input_char = '';\n                var content = '';\n                var reg_match = new RegExp('</' + name + '\\\\s*>', 'igm');\n                reg_match.lastIndex = this.pos;\n                var reg_array = reg_match.exec(this.input);\n                var end_script = reg_array ? reg_array.index : this.input.length; //absolute end of script\n                if (this.pos < end_script) { //get everything in between the script tags\n                    content = this.input.substring(this.pos, end_script);\n                    this.pos = end_script;\n                }\n                return content;\n            };\n\n            this.record_tag = function(tag) { //function to record a tag and its parent in this.tags Object\n                if (this.tags[tag + 'count']) { //check for the existence of this tag type\n                    this.tags[tag + 'count']++;\n                    this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level\n                } else { //otherwise initialize this tag type\n                    this.tags[tag + 'count'] = 1;\n                    this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level\n                }\n                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)\n                this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1')\n            };\n\n            this.retrieve_tag = function(tag) { //function to retrieve the opening tag to the corresponding closer\n                if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it\n                    var temp_parent = this.tags.parent; //check to see if it's a closable tag.\n                    while (temp_parent) { //till we reach '' (the initial value);\n                        if (tag + this.tags[tag + 'count'] === temp_parent) { //if this is it use it\n                            break;\n                        }\n                        temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree\n                    }\n                    if (temp_parent) { //if we caught something\n                        this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly\n                        this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent\n                    }\n                    delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference...\n                    delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself\n                    if (this.tags[tag + 'count'] === 1) {\n                        delete this.tags[tag + 'count'];\n                    } else {\n                        this.tags[tag + 'count']--;\n                    }\n                }\n            };\n\n            this.get_tag = function(peek) { //function to get a full tag and parse its type\n                var input_char = '',\n                    content = [],\n                    comment = '',\n                    space = false,\n                    tag_start, tag_end,\n                    orig_pos = this.pos,\n                    orig_line_char_count = this.line_char_count;\n\n                peek = peek !== undefined ? peek : false;\n\n                do {\n                    if (this.pos >= this.input.length) {\n                        if (peek) {\n                            this.pos = orig_pos;\n                            this.line_char_count = orig_line_char_count;\n                        }\n                        return content.length ? content.join('') : ['', 'TK_EOF'];\n                    }\n\n                    input_char = this.input.charAt(this.pos);\n                    this.pos++;\n\n                    if (this.Utils.in_array(input_char, this.Utils.whitespace)) { //don't want to insert unnecessary space\n                        space = true;\n                        continue;\n                    }\n\n                    if (input_char === \"'\" || input_char === '\"') {\n                        input_char += this.get_unformatted(input_char);\n                        space = true;\n\n                    }\n\n                    if (input_char === '=') { //no space before =\n                        space = false;\n                    }\n\n                    if (content.length && content[content.length - 1] !== '=' && input_char !== '>' && space) {\n                        //no space after = or before >\n                        if (this.line_char_count >= this.wrap_line_length) {\n                            this.print_newline(false, content);\n                            this.print_indentation(content);\n                        } else {\n                            content.push(' ');\n                            this.line_char_count++;\n                        }\n                        space = false;\n                    }\n\n                    if (input_char === '<' && !tag_start) {\n                        tag_start = this.pos - 1;\n                    }\n\n                    this.line_char_count++;\n                    content.push(input_char); //inserts character at-a-time (or string)\n\n                    if (content[1] && content[1] === '!') { //if we're in a comment, do something special\n                        // We treat all comments as literals, even more than preformatted tags\n                        // we just look for the appropriate close tag\n                        content = [this.get_comment(tag_start)];\n                        break;\n                    }\n\n                } while (input_char !== '>');\n\n                var tag_complete = content.join('');\n                var tag_index;\n                if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends\n                    tag_index = tag_complete.indexOf(' ');\n                } else { //otherwise go with the tag ending\n                    tag_index = tag_complete.indexOf('>');\n                }\n                var tag_check = tag_complete.substring(1, tag_index).toLowerCase();\n                if (tag_complete.charAt(tag_complete.length - 2) === '/' ||\n                    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 /)\n                    if (!peek) {\n                        this.tag_type = 'SINGLE';\n                    }\n                } else if (tag_check === 'script') { //for later script handling\n                    if (!peek) {\n                        this.record_tag(tag_check);\n                        this.tag_type = 'SCRIPT';\n                    }\n                } else if (tag_check === 'style') { //for future style handling (for now it justs uses get_content)\n                    if (!peek) {\n                        this.record_tag(tag_check);\n                        this.tag_type = 'STYLE';\n                    }\n                } else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the \"unformatted\" tags\n                    comment = this.get_unformatted('</' + tag_check + '>', tag_complete); //...delegate to get_unformatted function\n                    content.push(comment);\n                    // Preserve collapsed whitespace either before or after this tag.\n                    if (tag_start > 0 && this.Utils.in_array(this.input.charAt(tag_start - 1), this.Utils.whitespace)) {\n                        content.splice(0, 0, this.input.charAt(tag_start - 1));\n                    }\n                    tag_end = this.pos - 1;\n                    if (this.Utils.in_array(this.input.charAt(tag_end + 1), this.Utils.whitespace)) {\n                        content.push(this.input.charAt(tag_end + 1));\n                    }\n                    this.tag_type = 'SINGLE';\n                } else if (tag_check.charAt(0) === '!') { //peek for <! comment\n                    // for comments content is already correct.\n                    if (!peek) {\n                        this.tag_type = 'SINGLE';\n                        this.traverse_whitespace();\n                    }\n                } else if (!peek) {\n                    if (tag_check.charAt(0) === '/') { //this tag is a double tag so check for tag-ending\n                        this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors\n                        this.tag_type = 'END';\n                        this.traverse_whitespace();\n                    } else { //otherwise it's a start-tag\n                        this.record_tag(tag_check); //push it on the tag stack\n                        if (tag_check.toLowerCase() !== 'html') {\n                            this.indent_content = true;\n                        }\n                        this.tag_type = 'START';\n\n                        // Allow preserving of newlines after a start tag\n                        this.traverse_whitespace();\n                    }\n                    if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) { //check if this double needs an extra line\n                        this.print_newline(false, this.output);\n                        if (this.output.length && this.output[this.output.length - 2] !== '\\n') {\n                            this.print_newline(true, this.output);\n                        }\n                    }\n                }\n\n                if (peek) {\n                    this.pos = orig_pos;\n                    this.line_char_count = orig_line_char_count;\n                }\n\n                return content.join(''); //returns fully formatted tag\n            };\n\n            this.get_comment = function(start_pos) { //function to return comment content in its entirety\n                // this is will have very poor perf, but will work for now.\n                var comment = '',\n                    delimiter = '>',\n                    matched = false;\n\n                this.pos = start_pos;\n                input_char = this.input.charAt(this.pos);\n                this.pos++;\n\n                while (this.pos <= this.input.length) {\n                    comment += input_char;\n\n                    // only need to check for the delimiter if the last chars match\n                    if (comment[comment.length - 1] === delimiter[delimiter.length - 1] &&\n                        comment.indexOf(delimiter) !== -1) {\n                        break;\n                    }\n\n                    // only need to search for custom delimiter for the first few characters\n                    if (!matched && comment.length < 10) {\n                        if (comment.indexOf('<![if') === 0) { //peek for <![if conditional comment\n                            delimiter = '<![endif]>';\n                            matched = true;\n                        } else if (comment.indexOf('<![cdata[') === 0) { //if it's a <[cdata[ comment...\n                            delimiter = ']]>';\n                            matched = true;\n                        } else if (comment.indexOf('<![') === 0) { // some other ![ comment? ...\n                            delimiter = ']>';\n                            matched = true;\n                        } else if (comment.indexOf('<!--') === 0) { // <!-- comment ...\n                            delimiter = '-->';\n                            matched = true;\n                        }\n                    }\n\n                    input_char = this.input.charAt(this.pos);\n                    this.pos++;\n                }\n\n                return comment;\n            };\n\n            this.get_unformatted = function(delimiter, orig_tag) { //function to return unformatted content in its entirety\n\n                if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) {\n                    return '';\n                }\n                var input_char = '';\n                var content = '';\n                var space = true;\n                do {\n\n                    if (this.pos >= this.input.length) {\n                        return content;\n                    }\n\n                    input_char = this.input.charAt(this.pos);\n                    this.pos++;\n\n                    if (this.Utils.in_array(input_char, this.Utils.whitespace)) {\n                        if (!space) {\n                            this.line_char_count--;\n                            continue;\n                        }\n                        if (input_char === '\\n' || input_char === '\\r') {\n                            content += '\\n';\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'\n                for (var i=0; i<this.indent_level; i++) {\n                  content += this.indent_string;\n                }\n                space = false; //...and make sure other indentation is erased\n                */\n                            this.line_char_count = 0;\n                            continue;\n                        }\n                    }\n                    content += input_char;\n                    this.line_char_count++;\n                    space = true;\n\n\n                } while (content.toLowerCase().indexOf(delimiter) === -1);\n                return content;\n            };\n\n            this.get_token = function() { //initial handler for token-retrieval\n                var token;\n\n                if (this.last_token === 'TK_TAG_SCRIPT' || this.last_token === 'TK_TAG_STYLE') { //check if we need to format javascript\n                    var type = this.last_token.substr(7);\n                    token = this.get_contents_to(type);\n                    if (typeof token !== 'string') {\n                        return token;\n                    }\n                    return [token, 'TK_' + type];\n                }\n                if (this.current_mode === 'CONTENT') {\n                    token = this.get_content();\n                    if (typeof token !== 'string') {\n                        return token;\n                    } else {\n                        return [token, 'TK_CONTENT'];\n                    }\n                }\n\n                if (this.current_mode === 'TAG') {\n                    token = this.get_tag();\n                    if (typeof token !== 'string') {\n                        return token;\n                    } else {\n                        var tag_name_type = 'TK_TAG_' + this.tag_type;\n                        return [token, tag_name_type];\n                    }\n                }\n            };\n\n            this.get_full_indent = function(level) {\n                level = this.indent_level + level || 0;\n                if (level < 1) {\n                    return '';\n                }\n\n                return Array(level + 1).join(this.indent_string);\n            };\n\n            this.is_unformatted = function(tag_check, unformatted) {\n                //is this an HTML5 block-level link?\n                if (!this.Utils.in_array(tag_check, unformatted)) {\n                    return false;\n                }\n\n                if (tag_check.toLowerCase() !== 'a' || !this.Utils.in_array('a', unformatted)) {\n                    return true;\n                }\n\n                //at this point we have an  tag; is its first child something we want to remain\n                //unformatted?\n                var next_tag = this.get_tag(true /* peek. */ );\n\n                // tets next_tag to see if it is just html tag (no external content)\n                var tag = (next_tag || \"\").match(/^\\s*<\\s*\\/?([a-z]*)\\s*[^>]*>\\s*$/);\n\n                // if next_tag comes back but is not an isolated tag, then\n                // let's treat the 'a' tag as having content\n                // and respect the unformatted option\n                if (!tag || this.Utils.in_array(tag, unformatted)) {\n                    return true;\n                } else {\n                    return false;\n                }\n            };\n\n            this.printer = function(js_source, indent_character, indent_size, wrap_line_length, brace_style) { //handles input/output and some other printing functions\n\n                this.input = js_source || ''; //gets the input for the Parser\n                this.output = [];\n                this.indent_character = indent_character;\n                this.indent_string = '';\n                this.indent_size = indent_size;\n                this.brace_style = brace_style;\n                this.indent_level = 0;\n                this.wrap_line_length = wrap_line_length;\n                this.line_char_count = 0; //count to see if wrap_line_length was exceeded\n\n                for (var i = 0; i < this.indent_size; i++) {\n                    this.indent_string += this.indent_character;\n                }\n\n                this.print_newline = function(force, arr) {\n                    this.line_char_count = 0;\n                    if (!arr || !arr.length) {\n                        return;\n                    }\n                    if (force || (arr[arr.length - 1] !== '\\n')) { //we might want the extra line\n                        arr.push('\\n');\n                    }\n                };\n\n                this.print_indentation = function(arr) {\n                    for (var i = 0; i < this.indent_level; i++) {\n                        arr.push(this.indent_string);\n                        this.line_char_count += this.indent_string.length;\n                    }\n                };\n\n                this.print_token = function(text) {\n                    if (text || text !== '') {\n                        if (this.output.length && this.output[this.output.length - 1] === '\\n') {\n                            this.print_indentation(this.output);\n                            text = ltrim(text);\n                        }\n                    }\n                    this.print_token_raw(text);\n                };\n\n                this.print_token_raw = function(text) {\n                    if (text && text !== '') {\n                        if (text.length > 1 && text[text.length - 1] === '\\n') {\n                            // unformatted tags can grab newlines as their last character\n                            this.output.push(text.slice(0, -1));\n                            this.print_newline(false, this.output);\n                        } else {\n                            this.output.push(text);\n                        }\n                    }\n\n                    for (var n = 0; n < this.newlines; n++) {\n                        this.print_newline(n > 0, this.output);\n                    }\n                    this.newlines = 0;\n                };\n\n                this.indent = function() {\n                    this.indent_level++;\n                };\n\n                this.unindent = function() {\n                    if (this.indent_level > 0) {\n                        this.indent_level--;\n                    }\n                };\n            };\n            return this;\n        }\n\n        /*_____________________--------------------_____________________*/\n\n        multi_parser = new Parser(); //wrapping functions Parser\n        multi_parser.printer(html_source, indent_character, indent_size, wrap_line_length, brace_style); //initialize starting values\n\n        while (true) {\n            var t = multi_parser.get_token();\n            multi_parser.token_text = t[0];\n            multi_parser.token_type = t[1];\n\n            if (multi_parser.token_type === 'TK_EOF') {\n                break;\n            }\n\n            switch (multi_parser.token_type) {\n                case 'TK_TAG_START':\n                    multi_parser.print_newline(false, multi_parser.output);\n                    multi_parser.print_token(multi_parser.token_text);\n                    if (multi_parser.indent_content) {\n                        multi_parser.indent();\n                        multi_parser.indent_content = false;\n                    }\n                    multi_parser.current_mode = 'CONTENT';\n                    break;\n                case 'TK_TAG_STYLE':\n                case 'TK_TAG_SCRIPT':\n                    multi_parser.print_newline(false, multi_parser.output);\n                    multi_parser.print_token(multi_parser.token_text);\n                    multi_parser.current_mode = 'CONTENT';\n                    break;\n                case 'TK_TAG_END':\n                    //Print new line only if the tag has no content and has child\n                    if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '') {\n                        var tag_name = multi_parser.token_text.match(/\\w+/)[0];\n                        var tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length - 1].match(/<\\s*(\\w+)/);\n                        if (tag_extracted_from_last_output === null ||\n                            tag_extracted_from_last_output[1] !== tag_name) {\n                            multi_parser.print_newline(false, multi_parser.output);\n                        }\n                    }\n                    multi_parser.print_token(multi_parser.token_text);\n                    multi_parser.current_mode = 'CONTENT';\n                    break;\n                case 'TK_TAG_SINGLE':\n                    // Don't add a newline before elements that should remain unformatted.\n                    var tag_check = multi_parser.token_text.match(/^\\s*<([a-z]+)/i);\n                    if (!tag_check || !multi_parser.Utils.in_array(tag_check[1], unformatted)) {\n                        multi_parser.print_newline(false, multi_parser.output);\n                    }\n                    multi_parser.print_token(multi_parser.token_text);\n                    multi_parser.current_mode = 'CONTENT';\n                    break;\n                case 'TK_CONTENT':\n                    multi_parser.print_token(multi_parser.token_text);\n                    multi_parser.current_mode = 'TAG';\n                    break;\n                case 'TK_STYLE':\n                case 'TK_SCRIPT':\n                    if (multi_parser.token_text !== '') {\n                        multi_parser.print_newline(false, multi_parser.output);\n                        var text = multi_parser.token_text,\n                            _beautifier,\n                            script_indent_level = 1;\n                        if (multi_parser.token_type === 'TK_SCRIPT') {\n                            _beautifier = typeof js_beautify === 'function' && js_beautify;\n                        } else if (multi_parser.token_type === 'TK_STYLE') {\n                            _beautifier = typeof css_beautify === 'function' && css_beautify;\n                        }\n\n                        if (options.indent_scripts === \"keep\") {\n                            script_indent_level = 0;\n                        } else if (options.indent_scripts === \"separate\") {\n                            script_indent_level = -multi_parser.indent_level;\n                        }\n\n                        var indentation = multi_parser.get_full_indent(script_indent_level);\n                        if (_beautifier) {\n                            // call the Beautifier if avaliable\n                            text = _beautifier(text.replace(/^\\s*/, indentation), options);\n                        } else {\n                            // simply indent the string otherwise\n                            var white = text.match(/^\\s*/)[0];\n                            var _level = white.match(/[^\\n\\r]*$/)[0].split(multi_parser.indent_string).length - 1;\n                            var reindent = multi_parser.get_full_indent(script_indent_level - _level);\n                            text = text.replace(/^\\s*/, indentation)\n                                .replace(/\\r\\n|\\r|\\n/g, '\\n' + reindent)\n                                .replace(/\\s+$/, '');\n                        }\n                        if (text) {\n                            multi_parser.print_token_raw(indentation + trim(text));\n                            multi_parser.print_newline(false, multi_parser.output);\n                        }\n                    }\n                    multi_parser.current_mode = 'TAG';\n                    break;\n            }\n            multi_parser.last_token = multi_parser.token_type;\n            multi_parser.last_text = multi_parser.token_text;\n        }\n        return multi_parser.output.join('');\n    }\n\n    if (typeof define === \"function\") {\n        // Add support for require.js\n        define(function(require, exports, module) {\n            var js_beautify = require('./beautify.js').js_beautify;\n            var css_beautify = require('./beautify-css.js').css_beautify;\n\n            exports.html_beautify = function(html_source, options) {\n                return style_html(html_source, options, js_beautify, css_beautify);\n            };\n        });\n    } else if (typeof exports !== \"undefined\") {\n        // Add support for CommonJS. Just put this file somewhere on your require.paths\n        // and you will be able to `var html_beautify = require(\"beautify\").html_beautify`.\n        var js_beautify = require('./beautify.js').js_beautify;\n        var css_beautify = require('./beautify-css.js').css_beautify;\n\n        exports.html_beautify = function(html_source, options) {\n            return style_html(html_source, options, js_beautify, css_beautify);\n        };\n    } else if (typeof window !== \"undefined\") {\n        // If we're running a web page and don't have either of the above, add our one global\n        window.html_beautify = function(html_source, options) {\n            return style_html(html_source, options, window.js_beautify, window.css_beautify);\n        };\n    } else if (typeof global !== \"undefined\") {\n        // If we don't even have window, try global.\n        global.html_beautify = function(html_source, options) {\n            return style_html(html_source, options, global.js_beautify, global.css_beautify);\n        };\n    }\n\n}());"
  },
  {
    "path": "src/js/lib/beautify/beautify_js.js",
    "content": "/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */\n/*\n\n  The MIT License (MIT)\n\n  Copyright (c) 2007-2013 Einar Lielmanis and contributors.\n\n  Permission is hereby granted, free of charge, to any person\n  obtaining a copy of this software and associated documentation files\n  (the \"Software\"), to deal in the Software without restriction,\n  including without limitation the rights to use, copy, modify, merge,\n  publish, distribute, sublicense, and/or sell copies of the Software,\n  and to permit persons to whom the Software is furnished to do so,\n  subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be\n  included in all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\n  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n  SOFTWARE.\n\n JS Beautifier\n---------------\n\n\n  Written by Einar Lielmanis, <einar@jsbeautifier.org>\n      http://jsbeautifier.org/\n\n  Originally converted to javascript by Vital, <vital76@gmail.com>\n  \"End braces on own line\" added by Chris J. Shull, <chrisjshull@gmail.com>\n  Parsing improvements for brace-less statements by Liam Newman <bitwiseman@gmail.com>\n\n\n  Usage:\n    js_beautify(js_source_text);\n    js_beautify(js_source_text, options);\n\n  The options are:\n    indent_size (default 4)          - indentation size,\n    indent_char (default space)      - character to indent with,\n    preserve_newlines (default true) - whether existing line breaks should be preserved,\n    max_preserve_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk,\n\n    jslint_happy (default false) - if true, then jslint-stricter mode is enforced.\n\n            jslint_happy   !jslint_happy\n            ---------------------------------\n             function ()      function()\n\n    brace_style (default \"collapse\") - \"collapse\" | \"expand\" | \"end-expand\"\n            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.\n\n    space_before_conditional (default true) - should the space before conditional statement be added, \"if(true)\" vs \"if (true)\",\n\n    unescape_strings (default false) - should printable characters in strings encoded in \\xNN notation be unescaped, \"example\" vs \"\\x65\\x78\\x61\\x6d\\x70\\x6c\\x65\"\n\n    wrap_line_length (default unlimited) - lines should wrap at next opportunity after this number of characters.\n          NOTE: This is not a hard limit. Lines will continue until a point where a newline would\n                be preserved if it were present.\n\n    e.g\n\n    js_beautify(js_source_text, {\n      'indent_size': 1,\n      'indent_char': '\\t'\n    });\n\n*/\n\n\n(function() {\n    function js_beautify(js_source_text, options) {\n        \"use strict\";\n        var beautifier = new Beautifier(js_source_text, options);\n        return beautifier.beautify();\n    }\n\n    function Beautifier(js_source_text, options) {\n        \"use strict\";\n        var input, output_lines;\n        var token_text, token_type, last_type, last_last_text, indent_string;\n        var flags, previous_flags, flag_store;\n        var whitespace, wordchar, punct, parser_pos, line_starters, digits;\n        var prefix;\n        var input_wanted_newline;\n        var output_wrapped, output_space_before_token;\n        var input_length, n_newlines, whitespace_before_token;\n        var handlers, MODE, opt;\n        var preindent_string = '';\n\n        whitespace = \"\\n\\r\\t \".split('');\n        wordchar = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'.split('');\n        digits = '0123456789'.split('');\n\n        punct = '+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! !! , : ? ^ ^= |= ::';\n        punct += ' <%= <% %> <?= <? ?>'; // try to be a good boy and try not to break the markup language identifiers\n        punct = punct.split(' ');\n\n        // words which should always start on new line.\n        line_starters = 'continue,try,throw,return,var,if,switch,case,default,for,while,break,function'.split(',');\n\n        MODE = {\n            BlockStatement: 'BlockStatement', // 'BLOCK'\n            Statement: 'Statement', // 'STATEMENT'\n            ObjectLiteral: 'ObjectLiteral', // 'OBJECT',\n            ArrayLiteral: 'ArrayLiteral', //'[EXPRESSION]',\n            ForInitializer: 'ForInitializer', //'(FOR-EXPRESSION)',\n            Conditional: 'Conditional', //'(COND-EXPRESSION)',\n            Expression: 'Expression' //'(EXPRESSION)'\n        };\n\n        handlers = {\n            'TK_START_EXPR': handle_start_expr,\n            'TK_END_EXPR': handle_end_expr,\n            'TK_START_BLOCK': handle_start_block,\n            'TK_END_BLOCK': handle_end_block,\n            'TK_WORD': handle_word,\n            'TK_SEMICOLON': handle_semicolon,\n            'TK_STRING': handle_string,\n            'TK_EQUALS': handle_equals,\n            'TK_OPERATOR': handle_operator,\n            'TK_COMMA': handle_comma,\n            'TK_BLOCK_COMMENT': handle_block_comment,\n            'TK_INLINE_COMMENT': handle_inline_comment,\n            'TK_COMMENT': handle_comment,\n            'TK_DOT': handle_dot,\n            'TK_UNKNOWN': handle_unknown\n        };\n\n        function create_flags(flags_base, mode) {\n            var next_indent_level = 0;\n            if (flags_base) {\n                next_indent_level = flags_base.indentation_level;\n                next_indent_level += (flags_base.var_line && flags_base.var_line_reindented) ? 1 : 0;\n                if (!just_added_newline() &&\n                    flags_base.line_indent_level > next_indent_level) {\n                    next_indent_level = flags_base.line_indent_level;\n                }\n            }\n\n            var next_flags = {\n                mode: mode,\n                parent: flags_base,\n                last_text: flags_base ? flags_base.last_text : '', // last token text\n                last_word: flags_base ? flags_base.last_word : '', // last 'TK_WORD' passed\n                var_line: false,\n                var_line_tainted: false,\n                var_line_reindented: false,\n                in_html_comment: false,\n                multiline_frame: false,\n                if_block: false,\n                do_block: false,\n                do_while: false,\n                in_case_statement: false, // switch(..){ INSIDE HERE }\n                in_case: false, // we're on the exact line with \"case 0:\"\n                case_body: false, // the indented case-action block\n                indentation_level: next_indent_level,\n                line_indent_level: flags_base ? flags_base.line_indent_level : next_indent_level,\n                start_line_index: output_lines.length,\n                ternary_depth: 0\n            }\n            return next_flags;\n        }\n\n        // Using object instead of string to allow for later expansion of info about each line\n\n        function create_output_line() {\n            return {\n                text: []\n            };\n        }\n\n        // Some interpreters have unexpected results with foo = baz || bar;\n        options = options ? options : {};\n        opt = {};\n\n        // compatibility\n        if (options.space_after_anon_function !== undefined && options.jslint_happy === undefined) {\n            options.jslint_happy = options.space_after_anon_function;\n        }\n        if (options.braces_on_own_line !== undefined) { //graceful handling of deprecated option\n            opt.brace_style = options.braces_on_own_line ? \"expand\" : \"collapse\";\n        }\n        opt.brace_style = options.brace_style ? options.brace_style : (opt.brace_style ? opt.brace_style : \"collapse\");\n\n        // graceful handling of deprecated option\n        if (opt.brace_style === \"expand-strict\") {\n            opt.brace_style = \"expand\";\n        }\n\n\n        opt.indent_size = options.indent_size ? parseInt(options.indent_size, 10) : 4;\n        opt.indent_char = options.indent_char ? options.indent_char : ' ';\n        opt.preserve_newlines = (options.preserve_newlines === undefined) ? true : options.preserve_newlines;\n        opt.break_chained_methods = (options.break_chained_methods === undefined) ? false : options.break_chained_methods;\n        opt.max_preserve_newlines = (options.max_preserve_newlines === undefined) ? 0 : parseInt(options.max_preserve_newlines, 10);\n        opt.space_in_paren = (options.space_in_paren === undefined) ? false : options.space_in_paren;\n        opt.jslint_happy = (options.jslint_happy === undefined) ? false : options.jslint_happy;\n        opt.keep_array_indentation = (options.keep_array_indentation === undefined) ? false : options.keep_array_indentation;\n        opt.space_before_conditional = (options.space_before_conditional === undefined) ? true : options.space_before_conditional;\n        opt.unescape_strings = (options.unescape_strings === undefined) ? false : options.unescape_strings;\n        opt.wrap_line_length = (options.wrap_line_length === undefined) ? 0 : parseInt(options.wrap_line_length, 10);\n        opt.e4x = (options.e4x === undefined) ? false : options.e4x;\n\n\n        //----------------------------------\n        indent_string = '';\n        while (opt.indent_size > 0) {\n            indent_string += opt.indent_char;\n            opt.indent_size -= 1;\n        }\n\n        while (js_source_text && (js_source_text.charAt(0) === ' ' || js_source_text.charAt(0) === '\\t')) {\n            preindent_string += js_source_text.charAt(0);\n            js_source_text = js_source_text.substring(1);\n        }\n        input = js_source_text;\n        // cache the source's length.\n        input_length = js_source_text.length;\n\n        last_type = 'TK_START_BLOCK'; // last token type\n        last_last_text = ''; // pre-last token text\n        output_lines = [create_output_line()];\n        output_wrapped = false;\n        output_space_before_token = false;\n        whitespace_before_token = [];\n\n        // Stack of parsing/formatting states, including MODE.\n        // We tokenize, parse, and output in an almost purely a forward-only stream of token input\n        // and formatted output.  This makes the beautifier less accurate than full parsers\n        // but also far more tolerant of syntax errors.\n        //\n        // For example, the default mode is MODE.BlockStatement. If we see a '{' we push a new frame of type\n        // MODE.BlockStatement on the the stack, even though it could be object literal.  If we later\n        // encounter a \":\", we'll switch to to MODE.ObjectLiteral.  If we then see a \";\",\n        // most full parsers would die, but the beautifier gracefully falls back to\n        // MODE.BlockStatement and continues on.\n        flag_store = [];\n        set_mode(MODE.BlockStatement);\n\n        parser_pos = 0;\n\n        this.beautify = function() {\n            /*jshint onevar:true */\n            var t, i, keep_whitespace, sweet_code;\n\n            while (true) {\n                t = get_next_token();\n                token_text = t[0];\n                token_type = t[1];\n\n                if (token_type === 'TK_EOF') {\n                    break;\n                }\n\n                keep_whitespace = opt.keep_array_indentation && is_array(flags.mode);\n                input_wanted_newline = n_newlines > 0;\n\n                if (keep_whitespace) {\n                    for (i = 0; i < n_newlines; i += 1) {\n                        print_newline(i > 0);\n                    }\n                } else {\n                    if (opt.max_preserve_newlines && n_newlines > opt.max_preserve_newlines) {\n                        n_newlines = opt.max_preserve_newlines;\n                    }\n\n                    if (opt.preserve_newlines) {\n                        if (n_newlines > 1) {\n                            print_newline();\n                            for (i = 1; i < n_newlines; i += 1) {\n                                print_newline(true);\n                            }\n                        }\n                    }\n                }\n\n                handlers[token_type]();\n\n                // The cleanest handling of inline comments is to treat them as though they aren't there.\n                // Just continue formatting and the behavior should be logical.\n                // Also ignore unknown tokens.  Again, this should result in better behavior.\n                if (token_type !== 'TK_INLINE_COMMENT' && token_type !== 'TK_COMMENT' &&\n                    token_type !== 'TK_UNKNOWN') {\n                    last_last_text = flags.last_text;\n                    last_type = token_type;\n                    flags.last_text = token_text;\n                }\n            }\n\n\n            sweet_code = output_lines[0].text.join('');\n            for (var line_index = 1; line_index < output_lines.length; line_index++) {\n                sweet_code += '\\n' + output_lines[line_index].text.join('');\n            }\n            sweet_code = sweet_code.replace(/[\\r\\n ]+$/, '');\n            return sweet_code;\n        };\n\n        function trim_output(eat_newlines) {\n            eat_newlines = (eat_newlines === undefined) ? false : eat_newlines;\n\n            if (output_lines.length) {\n                trim_output_line(output_lines[output_lines.length - 1], eat_newlines);\n\n                while (eat_newlines && output_lines.length > 1 &&\n                    output_lines[output_lines.length - 1].text.length === 0) {\n                    output_lines.pop();\n                    trim_output_line(output_lines[output_lines.length - 1], eat_newlines);\n                }\n            }\n        }\n\n        function trim_output_line(line) {\n            while (line.text.length &&\n                (line.text[line.text.length - 1] === ' ' ||\n                    line.text[line.text.length - 1] === indent_string ||\n                    line.text[line.text.length - 1] === preindent_string)) {\n                line.text.pop();\n            }\n        }\n\n        function trim(s) {\n            return s.replace(/^\\s+|\\s+$/g, '');\n        }\n\n        // we could use just string.split, but\n        // IE doesn't like returning empty strings\n\n        function split_newlines(s) {\n            //return s.split(/\\x0d\\x0a|\\x0a/);\n\n            s = s.replace(/\\x0d/g, '');\n            var out = [],\n                idx = s.indexOf(\"\\n\");\n            while (idx !== -1) {\n                out.push(s.substring(0, idx));\n                s = s.substring(idx + 1);\n                idx = s.indexOf(\"\\n\");\n            }\n            if (s.length) {\n                out.push(s);\n            }\n            return out;\n        }\n\n        function just_added_newline() {\n            var line = output_lines[output_lines.length - 1];\n            return line.text.length === 0;\n        }\n\n        function just_added_blankline() {\n            if (just_added_newline()) {\n                if (output_lines.length === 1) {\n                    return true; // start of the file and newline = blank\n                }\n\n                var line = output_lines[output_lines.length - 2];\n                return line.text.length === 0;\n            }\n            return false;\n        }\n\n        function allow_wrap_or_preserved_newline(force_linewrap) {\n            force_linewrap = (force_linewrap === undefined) ? false : force_linewrap;\n            if (opt.wrap_line_length && !force_linewrap) {\n                var line = output_lines[output_lines.length - 1];\n                var proposed_line_length = 0;\n                // never wrap the first token of a line.\n                if (line.text.length > 0) {\n                    proposed_line_length = line.text.join('').length + token_text.length +\n                        (output_space_before_token ? 1 : 0);\n                    if (proposed_line_length >= opt.wrap_line_length) {\n                        force_linewrap = true;\n                    }\n                }\n            }\n            if (((opt.preserve_newlines && input_wanted_newline) || force_linewrap) && !just_added_newline()) {\n                print_newline(false, true);\n\n                // Expressions and array literals already indent their contents.\n                if (!(is_array(flags.mode) || is_expression(flags.mode))) {\n                    output_wrapped = true;\n                }\n            }\n        }\n\n        function print_newline(force_newline, preserve_statement_flags) {\n            output_wrapped = false;\n            output_space_before_token = false;\n\n            if (!preserve_statement_flags) {\n                if (flags.last_text !== ';') {\n                    while (flags.mode === MODE.Statement && !flags.if_block && !flags.do_block) {\n                        restore_mode();\n                    }\n                }\n            }\n\n            if (output_lines.length === 1 && just_added_newline()) {\n                return; // no newline on start of file\n            }\n\n            if (force_newline || !just_added_newline()) {\n                flags.multiline_frame = true;\n                output_lines.push(create_output_line());\n            }\n        }\n\n        function print_token_line_indentation() {\n            if (just_added_newline()) {\n                var line = output_lines[output_lines.length - 1];\n                if (opt.keep_array_indentation && is_array(flags.mode) && input_wanted_newline) {\n                    // prevent removing of this whitespace as redundant\n                    line.text.push('');\n                    for (var i = 0; i < whitespace_before_token.length; i += 1) {\n                        line.text.push(whitespace_before_token[i]);\n                    }\n                } else {\n                    if (preindent_string) {\n                        line.text.push(preindent_string);\n                    }\n\n                    print_indent_string(flags.indentation_level +\n                        (flags.var_line && flags.var_line_reindented ? 1 : 0) +\n                        (output_wrapped ? 1 : 0));\n                }\n            }\n        }\n\n        function print_indent_string(level) {\n            // Never indent your first output indent at the start of the file\n            if (output_lines.length > 1) {\n                var line = output_lines[output_lines.length - 1];\n\n                flags.line_indent_level = level;\n                for (var i = 0; i < level; i += 1) {\n                    line.text.push(indent_string);\n                }\n            }\n        }\n\n        function print_token_space_before() {\n            var line = output_lines[output_lines.length - 1];\n            if (output_space_before_token && line.text.length) {\n                var last_output = line.text[line.text.length - 1];\n                if (last_output !== ' ' && last_output !== indent_string) { // prevent occassional duplicate space\n                    line.text.push(' ');\n                }\n            }\n        }\n\n        function print_token(printable_token) {\n            printable_token = printable_token || token_text;\n            print_token_line_indentation();\n            output_wrapped = false;\n            print_token_space_before();\n            output_space_before_token = false;\n            output_lines[output_lines.length - 1].text.push(printable_token);\n        }\n\n        function indent() {\n            flags.indentation_level += 1;\n        }\n\n        function deindent() {\n            if (flags.indentation_level > 0 &&\n                ((!flags.parent) || flags.indentation_level > flags.parent.indentation_level))\n                flags.indentation_level -= 1;\n        }\n\n        function remove_redundant_indentation(frame) {\n            // This implementation is effective but has some issues:\n            //     - less than great performance due to array splicing\n            //     - can cause line wrap to happen too soon due to indent removal\n            //           after wrap points are calculated\n            // These issues are minor compared to ugly indentation.\n\n            if (frame.multiline_frame) return;\n\n            // remove one indent from each line inside this section\n            var index = frame.start_line_index;\n            var splice_index = 0;\n            var line;\n\n            while (index < output_lines.length) {\n                line = output_lines[index];\n                index++;\n\n                // skip empty lines\n                if (line.text.length === 0) {\n                    continue;\n                }\n\n                // skip the preindent string if present\n                if (preindent_string && line.text[0] === preindent_string) {\n                    splice_index = 1;\n                } else {\n                    splice_index = 0;\n                }\n\n                // remove one indent, if present\n                if (line.text[splice_index] === indent_string) {\n                    line.text.splice(splice_index, 1);\n                }\n            }\n        }\n\n        function set_mode(mode) {\n            if (flags) {\n                flag_store.push(flags);\n                previous_flags = flags;\n            } else {\n                previous_flags = create_flags(null, mode);\n            }\n\n            flags = create_flags(previous_flags, mode);\n        }\n\n        function is_array(mode) {\n            return mode === MODE.ArrayLiteral;\n        }\n\n        function is_expression(mode) {\n            return in_array(mode, [MODE.Expression, MODE.ForInitializer, MODE.Conditional]);\n        }\n\n        function restore_mode() {\n            if (flag_store.length > 0) {\n                previous_flags = flags;\n                flags = flag_store.pop();\n            }\n        }\n\n        function start_of_statement() {\n            if (\n                (flags.last_text === 'do' ||\n                    (flags.last_text === 'else' && token_text !== 'if') ||\n                    (last_type === 'TK_END_EXPR' && (previous_flags.mode === MODE.ForInitializer || previous_flags.mode === MODE.Conditional)))) {\n                // Issue #276:\n                // If starting a new statement with [if, for, while, do], push to a new line.\n                // if (a) if (b) if(c) d(); else e(); else f();\n                allow_wrap_or_preserved_newline(\n                    in_array(token_text, ['do', 'for', 'if', 'while']));\n\n                set_mode(MODE.Statement);\n                // Issue #275:\n                // If starting on a newline, all of a statement should be indented.\n                // if not, use line wrapping logic for indent.\n                if (just_added_newline()) {\n                    indent();\n                    output_wrapped = false;\n                }\n                return true;\n            }\n            return false;\n        }\n\n        function all_lines_start_with(lines, c) {\n            for (var i = 0; i < lines.length; i++) {\n                var line = trim(lines[i]);\n                if (line.charAt(0) !== c) {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        function is_special_word(word) {\n            return in_array(word, ['case', 'return', 'do', 'if', 'throw', 'else']);\n        }\n\n        function in_array(what, arr) {\n            for (var i = 0; i < arr.length; i += 1) {\n                if (arr[i] === what) {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        function unescape_string(s) {\n            var esc = false,\n                out = '',\n                pos = 0,\n                s_hex = '',\n                escaped = 0,\n                c;\n\n            while (esc || pos < s.length) {\n\n                c = s.charAt(pos);\n                pos++;\n\n                if (esc) {\n                    esc = false;\n                    if (c === 'x') {\n                        // simple hex-escape \\x24\n                        s_hex = s.substr(pos, 2);\n                        pos += 2;\n                    } else if (c === 'u') {\n                        // unicode-escape, \\u2134\n                        s_hex = s.substr(pos, 4);\n                        pos += 4;\n                    } else {\n                        // some common escape, e.g \\n\n                        out += '\\\\' + c;\n                        continue;\n                    }\n                    if (!s_hex.match(/^[0123456789abcdefABCDEF]+$/)) {\n                        // some weird escaping, bail out,\n                        // leaving whole string intact\n                        return s;\n                    }\n\n                    escaped = parseInt(s_hex, 16);\n\n                    if (escaped >= 0x00 && escaped < 0x20) {\n                        // leave 0x00...0x1f escaped\n                        if (c === 'x') {\n                            out += '\\\\x' + s_hex;\n                        } else {\n                            out += '\\\\u' + s_hex;\n                        }\n                        continue;\n                    } else if (escaped === 0x22 || escaped === 0x27 || escaped === 0x5c) {\n                        // single-quote, apostrophe, backslash - escape these\n                        out += '\\\\' + String.fromCharCode(escaped);\n                    } else if (c === 'x' && escaped > 0x7e && escaped <= 0xff) {\n                        // we bail out on \\x7f..\\xff,\n                        // leaving whole string escaped,\n                        // as it's probably completely binary\n                        return s;\n                    } else {\n                        out += String.fromCharCode(escaped);\n                    }\n                } else if (c === '\\\\') {\n                    esc = true;\n                } else {\n                    out += c;\n                }\n            }\n            return out;\n        }\n\n        function is_next(find) {\n            var local_pos = parser_pos;\n            var c = input.charAt(local_pos);\n            while (in_array(c, whitespace) && c !== find) {\n                local_pos++;\n                if (local_pos >= input_length) {\n                    return false;\n                }\n                c = input.charAt(local_pos);\n            }\n            return c === find;\n        }\n\n        function get_next_token() {\n            var i, resulting_string;\n\n            n_newlines = 0;\n\n            if (parser_pos >= input_length) {\n                return ['', 'TK_EOF'];\n            }\n\n            input_wanted_newline = false;\n            whitespace_before_token = [];\n\n            var c = input.charAt(parser_pos);\n            parser_pos += 1;\n\n            while (in_array(c, whitespace)) {\n\n                if (c === '\\n') {\n                    n_newlines += 1;\n                    whitespace_before_token = [];\n                } else if (n_newlines) {\n                    if (c === indent_string) {\n                        whitespace_before_token.push(indent_string);\n                    } else if (c !== '\\r') {\n                        whitespace_before_token.push(' ');\n                    }\n                }\n\n                if (parser_pos >= input_length) {\n                    return ['', 'TK_EOF'];\n                }\n\n                c = input.charAt(parser_pos);\n                parser_pos += 1;\n            }\n\n            if (in_array(c, wordchar)) {\n                if (parser_pos < input_length) {\n                    while (in_array(input.charAt(parser_pos), wordchar)) {\n                        c += input.charAt(parser_pos);\n                        parser_pos += 1;\n                        if (parser_pos === input_length) {\n                            break;\n                        }\n                    }\n                }\n\n                // small and surprisingly unugly hack for 1E-10 representation\n                if (parser_pos !== input_length && c.match(/^[0-9]+[Ee]$/) && (input.charAt(parser_pos) === '-' || input.charAt(parser_pos) === '+')) {\n\n                    var sign = input.charAt(parser_pos);\n                    parser_pos += 1;\n\n                    var t = get_next_token();\n                    c += sign + t[0];\n                    return [c, 'TK_WORD'];\n                }\n\n                if (c === 'in') { // hack for 'in' operator\n                    return [c, 'TK_OPERATOR'];\n                }\n                return [c, 'TK_WORD'];\n            }\n\n            if (c === '(' || c === '[') {\n                return [c, 'TK_START_EXPR'];\n            }\n\n            if (c === ')' || c === ']') {\n                return [c, 'TK_END_EXPR'];\n            }\n\n            if (c === '{') {\n                return [c, 'TK_START_BLOCK'];\n            }\n\n            if (c === '}') {\n                return [c, 'TK_END_BLOCK'];\n            }\n\n            if (c === ';') {\n                return [c, 'TK_SEMICOLON'];\n            }\n\n            if (c === '/') {\n                var comment = '';\n                // peek for comment /* ... */\n                var inline_comment = true;\n                if (input.charAt(parser_pos) === '*') {\n                    parser_pos += 1;\n                    if (parser_pos < input_length) {\n                        while (parser_pos < input_length && !(input.charAt(parser_pos) === '*' && input.charAt(parser_pos + 1) && input.charAt(parser_pos + 1) === '/')) {\n                            c = input.charAt(parser_pos);\n                            comment += c;\n                            if (c === \"\\n\" || c === \"\\r\") {\n                                inline_comment = false;\n                            }\n                            parser_pos += 1;\n                            if (parser_pos >= input_length) {\n                                break;\n                            }\n                        }\n                    }\n                    parser_pos += 2;\n                    if (inline_comment && n_newlines === 0) {\n                        return ['/*' + comment + '*/', 'TK_INLINE_COMMENT'];\n                    } else {\n                        return ['/*' + comment + '*/', 'TK_BLOCK_COMMENT'];\n                    }\n                }\n                // peek for comment // ...\n                if (input.charAt(parser_pos) === '/') {\n                    comment = c;\n                    while (input.charAt(parser_pos) !== '\\r' && input.charAt(parser_pos) !== '\\n') {\n                        comment += input.charAt(parser_pos);\n                        parser_pos += 1;\n                        if (parser_pos >= input_length) {\n                            break;\n                        }\n                    }\n                    return [comment, 'TK_COMMENT'];\n                }\n\n            }\n\n\n            if (c === \"'\" || c === '\"' || // string\n                (\n                    (c === '/') || // regexp\n                    (opt.e4x && c === \"<\" && input.slice(parser_pos - 1).match(/^<([-a-zA-Z:0-9_.]+|{[^{}]*}|!\\[CDATA\\[[\\s\\S]*?\\]\\])\\s*([-a-zA-Z:0-9_.]+=('[^']*'|\"[^\"]*\"|{[^{}]*})\\s*)*\\/?\\s*>/)) // xml\n                ) && ( // regex and xml can only appear in specific locations during parsing\n                    (last_type === 'TK_WORD' && is_special_word(flags.last_text)) ||\n                    (last_type === 'TK_END_EXPR' && in_array(previous_flags.mode, [MODE.Conditional, MODE.ForInitializer])) ||\n                    (in_array(last_type, ['TK_COMMENT', 'TK_START_EXPR', 'TK_START_BLOCK',\n                        'TK_END_BLOCK', 'TK_OPERATOR', 'TK_EQUALS', 'TK_EOF', 'TK_SEMICOLON', 'TK_COMMA'\n                    ]))\n                )) {\n\n                var sep = c,\n                    esc = false,\n                    has_char_escapes = false;\n\n                resulting_string = c;\n\n                if (parser_pos < input_length) {\n                    if (sep === '/') {\n                        //\n                        // handle regexp\n                        //\n                        var in_char_class = false;\n                        while (esc || in_char_class || input.charAt(parser_pos) !== sep) {\n                            resulting_string += input.charAt(parser_pos);\n                            if (!esc) {\n                                esc = input.charAt(parser_pos) === '\\\\';\n                                if (input.charAt(parser_pos) === '[') {\n                                    in_char_class = true;\n                                } else if (input.charAt(parser_pos) === ']') {\n                                    in_char_class = false;\n                                }\n                            } else {\n                                esc = false;\n                            }\n                            parser_pos += 1;\n                            if (parser_pos >= input_length) {\n                                // incomplete string/rexp when end-of-file reached.\n                                // bail out with what had been received so far.\n                                return [resulting_string, 'TK_STRING'];\n                            }\n                        }\n                    } else if (opt.e4x && sep === '<') {\n                        //\n                        // handle e4x xml literals\n                        //\n                        var xmlRegExp = /<(\\/?)([-a-zA-Z:0-9_.]+|{[^{}]*}|!\\[CDATA\\[[\\s\\S]*?\\]\\])\\s*([-a-zA-Z:0-9_.]+=('[^']*'|\"[^\"]*\"|{[^{}]*})\\s*)*(\\/?)\\s*>/g;\n                        var xmlStr = input.slice(parser_pos - 1);\n                        var match = xmlRegExp.exec(xmlStr);\n                        if (match && match.index === 0) {\n                            var rootTag = match[2];\n                            var depth = 0;\n                            while (match) {\n                                var isEndTag = !! match[1];\n                                var tagName = match[2];\n                                var isSingletonTag = ( !! match[match.length - 1]) || (tagName.slice(0, 8) === \"![CDATA[\");\n                                if (tagName === rootTag && !isSingletonTag) {\n                                    if (isEndTag) {\n                                        --depth;\n                                    } else {\n                                        ++depth;\n                                    }\n                                }\n                                if (depth <= 0) {\n                                    break;\n                                }\n                                match = xmlRegExp.exec(xmlStr);\n                            }\n                            var xmlLength = match ? match.index + match[0].length : xmlStr.length;\n                            parser_pos += xmlLength - 1;\n                            return [xmlStr.slice(0, xmlLength), \"TK_STRING\"];\n                        }\n                    } else {\n                        //\n                        // handle string\n                        //\n                        while (esc || input.charAt(parser_pos) !== sep) {\n                            resulting_string += input.charAt(parser_pos);\n                            if (esc) {\n                                if (input.charAt(parser_pos) === 'x' || input.charAt(parser_pos) === 'u') {\n                                    has_char_escapes = true;\n                                }\n                                esc = false;\n                            } else {\n                                esc = input.charAt(parser_pos) === '\\\\';\n                            }\n                            parser_pos += 1;\n                            if (parser_pos >= input_length) {\n                                // incomplete string/rexp when end-of-file reached.\n                                // bail out with what had been received so far.\n                                return [resulting_string, 'TK_STRING'];\n                            }\n                        }\n\n                    }\n                }\n\n                parser_pos += 1;\n                resulting_string += sep;\n\n                if (has_char_escapes && opt.unescape_strings) {\n                    resulting_string = unescape_string(resulting_string);\n                }\n\n                if (sep === '/') {\n                    // regexps may have modifiers /regexp/MOD , so fetch those, too\n                    while (parser_pos < input_length && in_array(input.charAt(parser_pos), wordchar)) {\n                        resulting_string += input.charAt(parser_pos);\n                        parser_pos += 1;\n                    }\n                }\n                return [resulting_string, 'TK_STRING'];\n            }\n\n            if (c === '#') {\n\n\n                if (output_lines.length === 1 && output_lines[0].text.length === 0 &&\n                    input.charAt(parser_pos) === '!') {\n                    // shebang\n                    resulting_string = c;\n                    while (parser_pos < input_length && c !== '\\n') {\n                        c = input.charAt(parser_pos);\n                        resulting_string += c;\n                        parser_pos += 1;\n                    }\n                    return [trim(resulting_string) + '\\n', 'TK_UNKNOWN'];\n                }\n\n\n\n                // Spidermonkey-specific sharp variables for circular references\n                // https://developer.mozilla.org/En/Sharp_variables_in_JavaScript\n                // http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp around line 1935\n                var sharp = '#';\n                if (parser_pos < input_length && in_array(input.charAt(parser_pos), digits)) {\n                    do {\n                        c = input.charAt(parser_pos);\n                        sharp += c;\n                        parser_pos += 1;\n                    } while (parser_pos < input_length && c !== '#' && c !== '=');\n                    if (c === '#') {\n                        //\n                    } else if (input.charAt(parser_pos) === '[' && input.charAt(parser_pos + 1) === ']') {\n                        sharp += '[]';\n                        parser_pos += 2;\n                    } else if (input.charAt(parser_pos) === '{' && input.charAt(parser_pos + 1) === '}') {\n                        sharp += '{}';\n                        parser_pos += 2;\n                    }\n                    return [sharp, 'TK_WORD'];\n                }\n            }\n\n            if (c === '<' && input.substring(parser_pos - 1, parser_pos + 3) === '<!--') {\n                parser_pos += 3;\n                c = '<!--';\n                while (input.charAt(parser_pos) !== '\\n' && parser_pos < input_length) {\n                    c += input.charAt(parser_pos);\n                    parser_pos++;\n                }\n                flags.in_html_comment = true;\n                return [c, 'TK_COMMENT'];\n            }\n\n            if (c === '-' && flags.in_html_comment && input.substring(parser_pos - 1, parser_pos + 2) === '-->') {\n                flags.in_html_comment = false;\n                parser_pos += 2;\n                return ['-->', 'TK_COMMENT'];\n            }\n\n            if (c === '.') {\n                return [c, 'TK_DOT'];\n            }\n\n            if (in_array(c, punct)) {\n                while (parser_pos < input_length && in_array(c + input.charAt(parser_pos), punct)) {\n                    c += input.charAt(parser_pos);\n                    parser_pos += 1;\n                    if (parser_pos >= input_length) {\n                        break;\n                    }\n                }\n\n                if (c === ',') {\n                    return [c, 'TK_COMMA'];\n                } else if (c === '=') {\n                    return [c, 'TK_EQUALS'];\n                } else {\n                    return [c, 'TK_OPERATOR'];\n                }\n            }\n\n            return [c, 'TK_UNKNOWN'];\n        }\n\n        function handle_start_expr() {\n            if (start_of_statement()) {\n                // The conditional starts the statement if appropriate.\n            }\n\n            var next_mode = MODE.Expression;\n            if (token_text === '[') {\n\n                if (last_type === 'TK_WORD' || flags.last_text === ')') {\n                    // this is array index specifier, break immediately\n                    // a[x], fn()[x]\n                    if (in_array(flags.last_text, line_starters)) {\n                        output_space_before_token = true;\n                    }\n                    set_mode(next_mode);\n                    print_token();\n                    indent();\n                    if (opt.space_in_paren) {\n                        output_space_before_token = true;\n                    }\n                    return;\n                }\n\n                next_mode = MODE.ArrayLiteral;\n                if (is_array(flags.mode)) {\n                    if (flags.last_text === '[' ||\n                        (flags.last_text === ',' && (last_last_text === ']' || last_last_text === '}'))) {\n                        // ], [ goes to new line\n                        // }, [ goes to new line\n                        if (!opt.keep_array_indentation) {\n                            print_newline();\n                        }\n                    }\n                }\n\n            } else {\n                if (flags.last_text === 'for') {\n                    next_mode = MODE.ForInitializer;\n                } else if (in_array(flags.last_text, ['if', 'while'])) {\n                    next_mode = MODE.Conditional;\n                } else {\n                    // next_mode = MODE.Expression;\n                }\n            }\n\n            if (flags.last_text === ';' || last_type === 'TK_START_BLOCK') {\n                print_newline();\n            } else if (last_type === 'TK_END_EXPR' || last_type === 'TK_START_EXPR' || last_type === 'TK_END_BLOCK' || flags.last_text === '.') {\n                // TODO: Consider whether forcing this is required.  Review failing tests when removed.\n                allow_wrap_or_preserved_newline(input_wanted_newline);\n                output_wrapped = false;\n                // do nothing on (( and )( and ][ and ]( and .(\n            } else if (last_type !== 'TK_WORD' && last_type !== 'TK_OPERATOR') {\n                output_space_before_token = true;\n            } else if (flags.last_word === 'function' || flags.last_word === 'typeof') {\n                // function() vs function ()\n                if (opt.jslint_happy) {\n                    output_space_before_token = true;\n                }\n            } else if (in_array(flags.last_text, line_starters) || flags.last_text === 'catch') {\n                if (opt.space_before_conditional) {\n                    output_space_before_token = true;\n                }\n            }\n\n            // Support of this kind of newline preservation.\n            // a = (b &&\n            //     (c || d));\n            if (token_text === '(') {\n                if (last_type === 'TK_EQUALS' || last_type === 'TK_OPERATOR') {\n                    if (flags.mode !== MODE.ObjectLiteral) {\n                        allow_wrap_or_preserved_newline();\n                    }\n                }\n            }\n\n            set_mode(next_mode);\n            print_token();\n            if (opt.space_in_paren) {\n                output_space_before_token = true;\n            }\n\n            // In all cases, if we newline while inside an expression it should be indented.\n            indent();\n        }\n\n        function handle_end_expr() {\n            // statements inside expressions are not valid syntax, but...\n            // statements must all be closed when their container closes\n            while (flags.mode === MODE.Statement) {\n                restore_mode();\n            }\n\n            if (token_text === ']' && is_array(flags.mode) && flags.multiline_frame && !opt.keep_array_indentation) {\n                print_newline();\n            }\n\n            if (flags.multiline_frame) {\n                allow_wrap_or_preserved_newline();\n            }\n            if (opt.space_in_paren) {\n                output_space_before_token = true;\n            }\n            if (token_text === ']' && opt.keep_array_indentation) {\n                print_token();\n                restore_mode();\n            } else {\n                restore_mode();\n                print_token();\n            }\n            remove_redundant_indentation(previous_flags);\n\n            // do {} while () // no statement required after\n            if (flags.do_while && previous_flags.mode === MODE.Conditional) {\n                previous_flags.mode = MODE.Expression;\n                flags.do_block = false;\n                flags.do_while = false;\n\n            }\n        }\n\n        function handle_start_block() {\n            set_mode(MODE.BlockStatement);\n\n            var empty_braces = is_next('}');\n            var empty_anonymous_function = empty_braces && flags.last_word === 'function' &&\n                last_type === 'TK_END_EXPR';\n\n            if (opt.brace_style === \"expand\") {\n                if (last_type !== 'TK_OPERATOR' &&\n                    (empty_anonymous_function ||\n                        last_type === 'TK_EQUALS' ||\n                        (is_special_word(flags.last_text) && flags.last_text !== 'else'))) {\n                    output_space_before_token = true;\n                } else {\n                    print_newline();\n                }\n            } else { // collapse\n                if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR') {\n                    if (last_type === 'TK_START_BLOCK') {\n                        print_newline();\n                    } else {\n                        output_space_before_token = true;\n                    }\n                } else {\n                    // if TK_OPERATOR or TK_START_EXPR\n                    if (is_array(previous_flags.mode) && flags.last_text === ',') {\n                        if (last_last_text === '}') {\n                            // }, { in array context\n                            output_space_before_token = true;\n                        } else {\n                            print_newline(); // [a, b, c, {\n                        }\n                    }\n                }\n            }\n            print_token();\n            indent();\n        }\n\n        function handle_end_block() {\n            // statements must all be closed when their container closes\n            while (flags.mode === MODE.Statement) {\n                restore_mode();\n            }\n            var empty_braces = last_type === 'TK_START_BLOCK';\n\n            if (opt.brace_style === \"expand\") {\n                if (!empty_braces) {\n                    print_newline();\n                }\n            } else {\n                // skip {}\n                if (!empty_braces) {\n                    if (is_array(flags.mode) && opt.keep_array_indentation) {\n                        // we REALLY need a newline here, but newliner would skip that\n                        opt.keep_array_indentation = false;\n                        print_newline();\n                        opt.keep_array_indentation = true;\n\n                    } else {\n                        print_newline();\n                    }\n                }\n            }\n            restore_mode();\n            print_token();\n        }\n\n        function handle_word() {\n            if (start_of_statement()) {\n                // The conditional starts the statement if appropriate.\n            } else if (input_wanted_newline && !is_expression(flags.mode) &&\n                (last_type !== 'TK_OPERATOR' || (flags.last_text === '--' || flags.last_text === '++')) &&\n                last_type !== 'TK_EQUALS' &&\n                (opt.preserve_newlines || flags.last_text !== 'var')) {\n\n                print_newline();\n            }\n\n            if (flags.do_block && !flags.do_while) {\n                if (token_text === 'while') {\n                    // do {} ## while ()\n                    output_space_before_token = true;\n                    print_token();\n                    output_space_before_token = true;\n                    flags.do_while = true;\n                    return;\n                } else {\n                    // do {} should always have while as the next word.\n                    // if we don't see the expected while, recover\n                    print_newline();\n                    flags.do_block = false;\n                }\n            }\n\n            // if may be followed by else, or not\n            // Bare/inline ifs are tricky\n            // Need to unwind the modes correctly: if (a) if (b) c(); else d(); else e();\n            if (flags.if_block) {\n                if (token_text !== 'else') {\n                    while (flags.mode === MODE.Statement) {\n                        restore_mode();\n                    }\n                    flags.if_block = false;\n                }\n            }\n\n            if (token_text === 'case' || (token_text === 'default' && flags.in_case_statement)) {\n                print_newline();\n                if (flags.case_body || opt.jslint_happy) {\n                    // switch cases following one another\n                    deindent();\n                    flags.case_body = false;\n                }\n                print_token();\n                flags.in_case = true;\n                flags.in_case_statement = true;\n                return;\n            }\n\n            if (token_text === 'function') {\n                if (flags.var_line && last_type !== 'TK_EQUALS') {\n                    flags.var_line_reindented = true;\n                }\n                if ((just_added_newline() || flags.last_text === ';' || flags.last_text === '}') &&\n                    flags.last_text !== '{' && !is_array(flags.mode)) {\n                    // make sure there is a nice clean space of at least one blank line\n                    // before a new function definition, except in arrays\n                    if (!just_added_blankline()) {\n                        print_newline();\n                        print_newline(true);\n                    }\n                }\n                if (last_type === 'TK_WORD') {\n                    if (flags.last_text === 'get' || flags.last_text === 'set' || flags.last_text === 'new' || flags.last_text === 'return') {\n                        output_space_before_token = true;\n                    } else {\n                        print_newline();\n                    }\n                } else if (last_type === 'TK_OPERATOR' || flags.last_text === '=') {\n                    // foo = function\n                    output_space_before_token = true;\n                } else if (is_expression(flags.mode)) {\n                    // (function\n                } else {\n                    print_newline();\n                }\n            }\n\n            if (last_type === 'TK_COMMA' || last_type === 'TK_START_EXPR' || last_type === 'TK_EQUALS' || last_type === 'TK_OPERATOR') {\n                if (flags.mode !== MODE.ObjectLiteral) {\n                    allow_wrap_or_preserved_newline();\n                }\n            }\n\n            if (token_text === 'function') {\n                print_token();\n                flags.last_word = token_text;\n                return;\n            }\n\n            prefix = 'NONE';\n\n            if (last_type === 'TK_END_BLOCK') {\n                if (!in_array(token_text, ['else', 'catch', 'finally'])) {\n                    prefix = 'NEWLINE';\n                } else {\n                    if (opt.brace_style === \"expand\" || opt.brace_style === \"end-expand\") {\n                        prefix = 'NEWLINE';\n                    } else {\n                        prefix = 'SPACE';\n                        output_space_before_token = true;\n                    }\n                }\n            } else if (last_type === 'TK_SEMICOLON' && flags.mode === MODE.BlockStatement) {\n                // TODO: Should this be for STATEMENT as well?\n                prefix = 'NEWLINE';\n            } else if (last_type === 'TK_SEMICOLON' && is_expression(flags.mode)) {\n                prefix = 'SPACE';\n            } else if (last_type === 'TK_STRING') {\n                prefix = 'NEWLINE';\n            } else if (last_type === 'TK_WORD') {\n                prefix = 'SPACE';\n            } else if (last_type === 'TK_START_BLOCK') {\n                prefix = 'NEWLINE';\n            } else if (last_type === 'TK_END_EXPR') {\n                output_space_before_token = true;\n                prefix = 'NEWLINE';\n            }\n\n            if (in_array(token_text, line_starters) && flags.last_text !== ')') {\n                if (flags.last_text === 'else') {\n                    prefix = 'SPACE';\n                } else {\n                    prefix = 'NEWLINE';\n                }\n\n            }\n\n            if (in_array(token_text, ['else', 'catch', 'finally'])) {\n                if (last_type !== 'TK_END_BLOCK' || opt.brace_style === \"expand\" || opt.brace_style === \"end-expand\") {\n                    print_newline();\n                } else {\n                    trim_output(true);\n                    var line = output_lines[output_lines.length - 1];\n                    // If we trimmed and there's something other than a close block before us\n                    // put a newline back in.  Handles '} // comment' scenario.\n                    if (line.text[line.text.length - 1] !== '}') {\n                        print_newline();\n                    }\n                    output_space_before_token = true;\n                }\n            } else if (prefix === 'NEWLINE') {\n                if (is_special_word(flags.last_text)) {\n                    // no newline between 'return nnn'\n                    output_space_before_token = true;\n                } else if (last_type !== 'TK_END_EXPR') {\n                    if ((last_type !== 'TK_START_EXPR' || token_text !== 'var') && flags.last_text !== ':') {\n                        // no need to force newline on 'var': for (var x = 0...)\n                        if (token_text === 'if' && flags.last_word === 'else' && flags.last_text !== '{') {\n                            // no newline for } else if {\n                            output_space_before_token = true;\n                        } else {\n                            flags.var_line = false;\n                            flags.var_line_reindented = false;\n                            print_newline();\n                        }\n                    }\n                } else if (in_array(token_text, line_starters) && flags.last_text !== ')') {\n                    flags.var_line = false;\n                    flags.var_line_reindented = false;\n                    print_newline();\n                }\n            } else if (is_array(flags.mode) && flags.last_text === ',' && last_last_text === '}') {\n                print_newline(); // }, in lists get a newline treatment\n            } else if (prefix === 'SPACE') {\n                output_space_before_token = true;\n            }\n            print_token();\n            flags.last_word = token_text;\n\n            if (token_text === 'var') {\n                flags.var_line = true;\n                flags.var_line_reindented = false;\n                flags.var_line_tainted = false;\n            }\n\n            if (token_text === 'do') {\n                flags.do_block = true;\n            }\n\n            if (token_text === 'if') {\n                flags.if_block = true;\n            }\n        }\n\n        function handle_semicolon() {\n            if (start_of_statement()) {\n                // The conditional starts the statement if appropriate.\n                // Semicolon can be the start (and end) of a statement\n                output_space_before_token = false;\n            }\n            while (flags.mode === MODE.Statement && !flags.if_block && !flags.do_block) {\n                restore_mode();\n            }\n            print_token();\n            flags.var_line = false;\n            flags.var_line_reindented = false;\n            if (flags.mode === MODE.ObjectLiteral) {\n                // if we're in OBJECT mode and see a semicolon, its invalid syntax\n                // recover back to treating this as a BLOCK\n                flags.mode = MODE.BlockStatement;\n            }\n        }\n\n        function handle_string() {\n            if (start_of_statement()) {\n                // The conditional starts the statement if appropriate.\n                // One difference - strings want at least a space before\n                output_space_before_token = true;\n            } else if (last_type === 'TK_WORD') {\n                output_space_before_token = true;\n            } else if (last_type === 'TK_COMMA' || last_type === 'TK_START_EXPR' || last_type === 'TK_EQUALS' || last_type === 'TK_OPERATOR') {\n                if (flags.mode !== MODE.ObjectLiteral) {\n                    allow_wrap_or_preserved_newline();\n                }\n            } else {\n                print_newline();\n            }\n            print_token();\n        }\n\n        function handle_equals() {\n            if (flags.var_line) {\n                // just got an '=' in a var-line, different formatting/line-breaking, etc will now be done\n                flags.var_line_tainted = true;\n            }\n            output_space_before_token = true;\n            print_token();\n            output_space_before_token = true;\n        }\n\n        function handle_comma() {\n            if (flags.var_line) {\n                if (is_expression(flags.mode) || last_type === 'TK_END_BLOCK') {\n                    // do not break on comma, for(var a = 1, b = 2)\n                    flags.var_line_tainted = false;\n                }\n\n                if (flags.var_line) {\n                    flags.var_line_reindented = true;\n                }\n\n                print_token();\n\n                if (flags.var_line_tainted) {\n                    flags.var_line_tainted = false;\n                    print_newline();\n                } else {\n                    output_space_before_token = true;\n                }\n                return;\n            }\n\n            if (last_type === 'TK_END_BLOCK' && flags.mode !== MODE.Expression) {\n                print_token();\n                if (flags.mode === MODE.ObjectLiteral && flags.last_text === '}') {\n                    print_newline();\n                } else {\n                    output_space_before_token = true;\n                }\n            } else {\n                if (flags.mode === MODE.ObjectLiteral) {\n                    print_token();\n                    print_newline();\n                } else {\n                    // EXPR or DO_BLOCK\n                    print_token();\n                    output_space_before_token = true;\n                }\n            }\n        }\n\n        function handle_operator() {\n            var space_before = true;\n            var space_after = true;\n            if (is_special_word(flags.last_text)) {\n                // \"return\" had a special handling in TK_WORD. Now we need to return the favor\n                output_space_before_token = true;\n                print_token();\n                return;\n            }\n\n            // hack for actionscript's import .*;\n            if (token_text === '*' && last_type === 'TK_DOT' && !last_last_text.match(/^\\d+$/)) {\n                print_token();\n                return;\n            }\n\n            if (token_text === ':' && flags.in_case) {\n                flags.case_body = true;\n                indent();\n                print_token();\n                print_newline();\n                flags.in_case = false;\n                return;\n            }\n\n            if (token_text === '::') {\n                // no spaces around exotic namespacing syntax operator\n                print_token();\n                return;\n            }\n\n            // http://www.ecma-international.org/ecma-262/5.1/#sec-7.9.1\n            // if there is a newline between -- or ++ and anything else we should preserve it.\n            if (input_wanted_newline && (token_text === '--' || token_text === '++')) {\n                print_newline();\n            }\n\n            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(flags.last_text, line_starters) || flags.last_text === ','))) {\n                // unary operators (and binary +/- pretending to be unary) special cases\n\n                space_before = false;\n                space_after = false;\n\n                if (flags.last_text === ';' && is_expression(flags.mode)) {\n                    // for (;; ++i)\n                    //        ^^^\n                    space_before = true;\n                }\n\n                if (last_type === 'TK_WORD' && in_array(flags.last_text, line_starters)) {\n                    space_before = true;\n                }\n\n                if ((flags.mode === MODE.BlockStatement || flags.mode === MODE.Statement) && (flags.last_text === '{' || flags.last_text === ';')) {\n                    // { foo; --i }\n                    // foo(); --bar;\n                    print_newline();\n                }\n            } else if (token_text === ':') {\n                if (flags.ternary_depth === 0) {\n                    if (flags.mode === MODE.BlockStatement) {\n                        flags.mode = MODE.ObjectLiteral;\n                    }\n                    space_before = false;\n                } else {\n                    flags.ternary_depth -= 1;\n                }\n            } else if (token_text === '?') {\n                flags.ternary_depth += 1;\n            }\n            output_space_before_token = output_space_before_token || space_before;\n            print_token();\n            output_space_before_token = space_after;\n        }\n\n        function handle_block_comment() {\n            var lines = split_newlines(token_text);\n            var j; // iterator for this case\n            var javadoc = false;\n\n            // block comment starts with a new line\n            print_newline(false, true);\n            if (lines.length > 1) {\n                if (all_lines_start_with(lines.slice(1), '*')) {\n                    javadoc = true;\n                }\n            }\n\n            // first line always indented\n            print_token(lines[0]);\n            for (j = 1; j < lines.length; j++) {\n                print_newline(false, true);\n                if (javadoc) {\n                    // javadoc: reformat and re-indent\n                    print_token(' ' + trim(lines[j]));\n                } else {\n                    // normal comments output raw\n                    output_lines[output_lines.length - 1].text.push(lines[j]);\n                }\n            }\n\n            // for comments of more than one line, make sure there's a new line after\n            print_newline(false, true);\n        }\n\n        function handle_inline_comment() {\n            output_space_before_token = true;\n            print_token();\n            output_space_before_token = true;\n        }\n\n        function handle_comment() {\n            if (input_wanted_newline) {\n                print_newline(false, true);\n            } else {\n                trim_output(true);\n            }\n\n            output_space_before_token = true;\n            print_token();\n            print_newline(false, true);\n        }\n\n        function handle_dot() {\n            if (is_special_word(flags.last_text)) {\n                output_space_before_token = true;\n            } else {\n                // allow preserved newlines before dots in general\n                // force newlines on dots after close paren when break_chained - for bar().baz()\n                allow_wrap_or_preserved_newline(flags.last_text === ')' && opt.break_chained_methods);\n            }\n\n            print_token();\n        }\n\n        function handle_unknown() {\n            print_token();\n\n            if (token_text[token_text.length - 1] === '\\n') {\n                print_newline();\n            }\n        }\n    }\n\n\n    if (typeof define === \"function\") {\n        // Add support for require.js\n        if (typeof define.amd === \"undefined\") {\n            define(function(require, exports, module) {\n                exports.js_beautify = js_beautify;\n            });\n        } else {\n            // if is AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- )\n            define([], function() {\n                return js_beautify;\n            });\n        }\n\n    } else if (typeof exports !== \"undefined\") {\n        // Add support for CommonJS. Just put this file somewhere on your require.paths\n        // and you will be able to `var js_beautify = require(\"beautify\").js_beautify`.\n        exports.js_beautify = js_beautify;\n    } else if (typeof window !== \"undefined\") {\n        // If we're running a web page and don't have either of the above, add our one global\n        window.js_beautify = js_beautify;\n    } else if (typeof global !== \"undefined\") {\n        // If we don't even have window, try global.\n        global.js_beautify = js_beautify;\n    }\n\n}());"
  },
  {
    "path": "src/js/lib/bootstrap.js",
    "content": "/* ===================================================\n * bootstrap-transition.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#transitions\n * ===================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n  /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)\n   * ======================================================= */\n\n  $(function () {\n\n    $.support.transition = (function () {\n\n      var transitionEnd = (function () {\n\n        var el = document.createElement('bootstrap')\n          , transEndEventNames = {\n               'WebkitTransition' : 'webkitTransitionEnd'\n            ,  'MozTransition'    : 'transitionend'\n            ,  'OTransition'      : 'oTransitionEnd otransitionend'\n            ,  'transition'       : 'transitionend'\n            }\n          , name\n\n        for (name in transEndEventNames){\n          if (el.style[name] !== undefined) {\n            return transEndEventNames[name]\n          }\n        }\n\n      }())\n\n      return transitionEnd && {\n        end: transitionEnd\n      }\n\n    })()\n\n  })\n\n}(window.jQuery);/* ==========================================================\n * bootstrap-alert.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#alerts\n * ==========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* ALERT CLASS DEFINITION\n  * ====================== */\n\n  var dismiss = '[data-dismiss=\"alert\"]'\n    , Alert = function (el) {\n        $(el).on('click', dismiss, this.close)\n      }\n\n  Alert.prototype.close = function (e) {\n    var $this = $(this)\n      , selector = $this.attr('data-target')\n      , $parent\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n    }\n\n    $parent = $(selector)\n\n    e && e.preventDefault()\n\n    $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())\n\n    $parent.trigger(e = $.Event('close'))\n\n    if (e.isDefaultPrevented()) return\n\n    $parent.removeClass('in')\n\n    function removeElement() {\n      $parent\n        .trigger('closed')\n        .remove()\n    }\n\n    $.support.transition && $parent.hasClass('fade') ?\n      $parent.on($.support.transition.end, removeElement) :\n      removeElement()\n  }\n\n\n /* ALERT PLUGIN DEFINITION\n  * ======================= */\n\n  var old = $.fn.alert\n\n  $.fn.alert = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('alert')\n      if (!data) $this.data('alert', (data = new Alert(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  $.fn.alert.Constructor = Alert\n\n\n /* ALERT NO CONFLICT\n  * ================= */\n\n  $.fn.alert.noConflict = function () {\n    $.fn.alert = old\n    return this\n  }\n\n\n /* ALERT DATA-API\n  * ============== */\n\n  $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)\n\n}(window.jQuery);/* ============================================================\n * bootstrap-button.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#buttons\n * ============================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ============================================================ */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* BUTTON PUBLIC CLASS DEFINITION\n  * ============================== */\n\n  var Button = function (element, options) {\n    this.$element = $(element)\n    this.options = $.extend({}, $.fn.button.defaults, options)\n  }\n\n  Button.prototype.setState = function (state) {\n    var d = 'disabled'\n      , $el = this.$element\n      , data = $el.data()\n      , val = $el.is('input') ? 'val' : 'html'\n\n    state = state + 'Text'\n    data.resetText || $el.data('resetText', $el[val]())\n\n    $el[val](data[state] || this.options[state])\n\n    // push to event loop to allow forms to submit\n    setTimeout(function () {\n      state == 'loadingText' ?\n        $el.addClass(d).attr(d, d) :\n        $el.removeClass(d).removeAttr(d)\n    }, 0)\n  }\n\n  Button.prototype.toggle = function () {\n    var $parent = this.$element.closest('[data-toggle=\"buttons-radio\"]')\n\n    $parent && $parent\n      .find('.active')\n      .removeClass('active')\n\n    this.$element.toggleClass('active')\n  }\n\n\n /* BUTTON PLUGIN DEFINITION\n  * ======================== */\n\n  var old = $.fn.button\n\n  $.fn.button = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('button')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('button', (data = new Button(this, options)))\n      if (option == 'toggle') data.toggle()\n      else if (option) data.setState(option)\n    })\n  }\n\n  $.fn.button.defaults = {\n    loadingText: 'loading...'\n  }\n\n  $.fn.button.Constructor = Button\n\n\n /* BUTTON NO CONFLICT\n  * ================== */\n\n  $.fn.button.noConflict = function () {\n    $.fn.button = old\n    return this\n  }\n\n\n /* BUTTON DATA-API\n  * =============== */\n\n  $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {\n    var $btn = $(e.target)\n    if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n    $btn.button('toggle')\n  })\n\n}(window.jQuery);/* ==========================================================\n * bootstrap-carousel.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#carousel\n * ==========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* CAROUSEL CLASS DEFINITION\n  * ========================= */\n\n  var Carousel = function (element, options) {\n    this.$element = $(element)\n    this.$indicators = this.$element.find('.carousel-indicators')\n    this.options = options\n    this.options.pause == 'hover' && this.$element\n      .on('mouseenter', $.proxy(this.pause, this))\n      .on('mouseleave', $.proxy(this.cycle, this))\n  }\n\n  Carousel.prototype = {\n\n    cycle: function (e) {\n      if (!e) this.paused = false\n      if (this.interval) clearInterval(this.interval);\n      this.options.interval\n        && !this.paused\n        && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n      return this\n    }\n\n  , getActiveIndex: function () {\n      this.$active = this.$element.find('.item.active')\n      this.$items = this.$active.parent().children()\n      return this.$items.index(this.$active)\n    }\n\n  , to: function (pos) {\n      var activeIndex = this.getActiveIndex()\n        , that = this\n\n      if (pos > (this.$items.length - 1) || pos < 0) return\n\n      if (this.sliding) {\n        return this.$element.one('slid', function () {\n          that.to(pos)\n        })\n      }\n\n      if (activeIndex == pos) {\n        return this.pause().cycle()\n      }\n\n      return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))\n    }\n\n  , pause: function (e) {\n      if (!e) this.paused = true\n      if (this.$element.find('.next, .prev').length && $.support.transition.end) {\n        this.$element.trigger($.support.transition.end)\n        this.cycle(true)\n      }\n      clearInterval(this.interval)\n      this.interval = null\n      return this\n    }\n\n  , next: function () {\n      if (this.sliding) return\n      return this.slide('next')\n    }\n\n  , prev: function () {\n      if (this.sliding) return\n      return this.slide('prev')\n    }\n\n  , slide: function (type, next) {\n      var $active = this.$element.find('.item.active')\n        , $next = next || $active[type]()\n        , isCycling = this.interval\n        , direction = type == 'next' ? 'left' : 'right'\n        , fallback  = type == 'next' ? 'first' : 'last'\n        , that = this\n        , e\n\n      this.sliding = true\n\n      isCycling && this.pause()\n\n      $next = $next.length ? $next : this.$element.find('.item')[fallback]()\n\n      e = $.Event('slide', {\n        relatedTarget: $next[0]\n      , direction: direction\n      })\n\n      if ($next.hasClass('active')) return\n\n      if (this.$indicators.length) {\n        this.$indicators.find('.active').removeClass('active')\n        this.$element.one('slid', function () {\n          var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])\n          $nextIndicator && $nextIndicator.addClass('active')\n        })\n      }\n\n      if ($.support.transition && this.$element.hasClass('slide')) {\n        this.$element.trigger(e)\n        if (e.isDefaultPrevented()) return\n        $next.addClass(type)\n        $next[0].offsetWidth // force reflow\n        $active.addClass(direction)\n        $next.addClass(direction)\n        this.$element.one($.support.transition.end, function () {\n          $next.removeClass([type, direction].join(' ')).addClass('active')\n          $active.removeClass(['active', direction].join(' '))\n          that.sliding = false\n          setTimeout(function () { that.$element.trigger('slid') }, 0)\n        })\n      } else {\n        this.$element.trigger(e)\n        if (e.isDefaultPrevented()) return\n        $active.removeClass('active')\n        $next.addClass('active')\n        this.sliding = false\n        this.$element.trigger('slid')\n      }\n\n      isCycling && this.cycle()\n\n      return this\n    }\n\n  }\n\n\n /* CAROUSEL PLUGIN DEFINITION\n  * ========================== */\n\n  var old = $.fn.carousel\n\n  $.fn.carousel = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('carousel')\n        , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)\n        , action = typeof option == 'string' ? option : options.slide\n      if (!data) $this.data('carousel', (data = new Carousel(this, options)))\n      if (typeof option == 'number') data.to(option)\n      else if (action) data[action]()\n      else if (options.interval) data.pause().cycle()\n    })\n  }\n\n  $.fn.carousel.defaults = {\n    interval: 5000\n  , pause: 'hover'\n  }\n\n  $.fn.carousel.Constructor = Carousel\n\n\n /* CAROUSEL NO CONFLICT\n  * ==================== */\n\n  $.fn.carousel.noConflict = function () {\n    $.fn.carousel = old\n    return this\n  }\n\n /* CAROUSEL DATA-API\n  * ================= */\n\n  $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {\n    var $this = $(this), href\n      , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) //strip for ie7\n      , options = $.extend({}, $target.data(), $this.data())\n      , slideIndex\n\n    $target.carousel(options)\n\n    if (slideIndex = $this.attr('data-slide-to')) {\n      $target.data('carousel').pause().to(slideIndex).cycle()\n    }\n\n    e.preventDefault()\n  })\n\n}(window.jQuery);/* =============================================================\n * bootstrap-collapse.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#collapse\n * =============================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ============================================================ */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* COLLAPSE PUBLIC CLASS DEFINITION\n  * ================================ */\n\n  var Collapse = function (element, options) {\n    this.$element = $(element)\n    this.options = $.extend({}, $.fn.collapse.defaults, options)\n\n    if (this.options.parent) {\n      this.$parent = $(this.options.parent)\n    }\n\n    this.options.toggle && this.toggle()\n  }\n\n  Collapse.prototype = {\n\n    constructor: Collapse\n\n  , dimension: function () {\n      var hasWidth = this.$element.hasClass('width')\n      return hasWidth ? 'width' : 'height'\n    }\n\n  , show: function () {\n      var dimension\n        , scroll\n        , actives\n        , hasData\n\n      if (this.transitioning || this.$element.hasClass('in')) return\n\n      dimension = this.dimension()\n      scroll = $.camelCase(['scroll', dimension].join('-'))\n      actives = this.$parent && this.$parent.find('> .accordion-group > .in')\n\n      if (actives && actives.length) {\n        hasData = actives.data('collapse')\n        if (hasData && hasData.transitioning) return\n        actives.collapse('hide')\n        hasData || actives.data('collapse', null)\n      }\n\n      this.$element[dimension](0)\n      this.transition('addClass', $.Event('show'), 'shown')\n      $.support.transition && this.$element[dimension](this.$element[0][scroll])\n    }\n\n  , hide: function () {\n      var dimension\n      if (this.transitioning || !this.$element.hasClass('in')) return\n      dimension = this.dimension()\n      this.reset(this.$element[dimension]())\n      this.transition('removeClass', $.Event('hide'), 'hidden')\n      this.$element[dimension](0)\n    }\n\n  , reset: function (size) {\n      var dimension = this.dimension()\n\n      this.$element\n        .removeClass('collapse')\n        [dimension](size || 'auto')\n        [0].offsetWidth\n\n      this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')\n\n      return this\n    }\n\n  , transition: function (method, startEvent, completeEvent) {\n      var that = this\n        , complete = function () {\n            if (startEvent.type == 'show') that.reset()\n            that.transitioning = 0\n            that.$element.trigger(completeEvent)\n          }\n\n      this.$element.trigger(startEvent)\n\n      if (startEvent.isDefaultPrevented()) return\n\n      this.transitioning = 1\n\n      this.$element[method]('in')\n\n      $.support.transition && this.$element.hasClass('collapse') ?\n        this.$element.one($.support.transition.end, complete) :\n        complete()\n    }\n\n  , toggle: function () {\n      this[this.$element.hasClass('in') ? 'hide' : 'show']()\n    }\n\n  }\n\n\n /* COLLAPSE PLUGIN DEFINITION\n  * ========================== */\n\n  var old = $.fn.collapse\n\n  $.fn.collapse = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('collapse')\n        , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option)\n      if (!data) $this.data('collapse', (data = new Collapse(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.collapse.defaults = {\n    toggle: true\n  }\n\n  $.fn.collapse.Constructor = Collapse\n\n\n /* COLLAPSE NO CONFLICT\n  * ==================== */\n\n  $.fn.collapse.noConflict = function () {\n    $.fn.collapse = old\n    return this\n  }\n\n\n /* COLLAPSE DATA-API\n  * ================= */\n\n  $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {\n    var $this = $(this), href\n      , target = $this.attr('data-target')\n        || e.preventDefault()\n        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') //strip for ie7\n      , option = $(target).data('collapse') ? 'toggle' : $this.data()\n    $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')\n    $(target).collapse(option)\n  })\n\n}(window.jQuery);/* ============================================================\n * bootstrap-dropdown.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#dropdowns\n * ============================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ============================================================ */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* DROPDOWN CLASS DEFINITION\n  * ========================= */\n\n  var toggle = '[data-toggle=dropdown]'\n    , Dropdown = function (element) {\n        var $el = $(element).on('click.dropdown.data-api', this.toggle)\n        $('html').on('click.dropdown.data-api', function () {\n          $el.parent().removeClass('open')\n        })\n      }\n\n  Dropdown.prototype = {\n\n    constructor: Dropdown\n\n  , toggle: function (e) {\n      var $this = $(this)\n        , $parent\n        , isActive\n\n      if ($this.is('.disabled, :disabled')) return\n\n      $parent = getParent($this)\n\n      isActive = $parent.hasClass('open')\n\n      clearMenus()\n\n      if (!isActive) {\n        if ('ontouchstart' in document.documentElement) {\n          // if mobile we we use a backdrop because click events don't delegate\n          $('<div class=\"dropdown-backdrop\"/>').insertBefore($(this)).on('click', clearMenus)\n        }\n        $parent.toggleClass('open')\n      }\n\n      $this.focus()\n\n      return false\n    }\n\n  , keydown: function (e) {\n      var $this\n        , $items\n        , $active\n        , $parent\n        , isActive\n        , index\n\n      if (!/(38|40|27)/.test(e.keyCode)) return\n\n      $this = $(this)\n\n      e.preventDefault()\n      e.stopPropagation()\n\n      if ($this.is('.disabled, :disabled')) return\n\n      $parent = getParent($this)\n\n      isActive = $parent.hasClass('open')\n\n      if (!isActive || (isActive && e.keyCode == 27)) {\n        if (e.which == 27) $parent.find(toggle).focus()\n        return $this.click()\n      }\n\n      $items = $('[role=menu] li:not(.divider):visible a', $parent)\n\n      if (!$items.length) return\n\n      index = $items.index($items.filter(':focus'))\n\n      if (e.keyCode == 38 && index > 0) index--                                        // up\n      if (e.keyCode == 40 && index < $items.length - 1) index++                        // down\n      if (!~index) index = 0\n\n      $items\n        .eq(index)\n        .focus()\n    }\n\n  }\n\n  function clearMenus() {\n    $('.dropdown-backdrop').remove()\n    $(toggle).each(function () {\n      getParent($(this)).removeClass('open')\n    })\n  }\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n      , $parent\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n    }\n\n    $parent = selector && $(selector)\n\n    if (!$parent || !$parent.length) $parent = $this.parent()\n\n    return $parent\n  }\n\n\n  /* DROPDOWN PLUGIN DEFINITION\n   * ========================== */\n\n  var old = $.fn.dropdown\n\n  $.fn.dropdown = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('dropdown')\n      if (!data) $this.data('dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  $.fn.dropdown.Constructor = Dropdown\n\n\n /* DROPDOWN NO CONFLICT\n  * ==================== */\n\n  $.fn.dropdown.noConflict = function () {\n    $.fn.dropdown = old\n    return this\n  }\n\n\n  /* APPLY TO STANDARD DROPDOWN ELEMENTS\n   * =================================== */\n\n  $(document)\n    .on('click.dropdown.data-api', clearMenus)\n    .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n    .on('click.dropdown.data-api'  , toggle, Dropdown.prototype.toggle)\n    .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)\n\n}(window.jQuery);\n/* =========================================================\n * bootstrap-modal.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#modals\n * =========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================= */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* MODAL CLASS DEFINITION\n  * ====================== */\n\n  var Modal = function (element, options) {\n    this.options = options\n    this.$element = $(element)\n      .delegate('[data-dismiss=\"modal\"]', 'click.dismiss.modal', $.proxy(this.hide, this))\n    this.options.remote && this.$element.find('.modal-body').load(this.options.remote)\n  }\n\n  Modal.prototype = {\n\n      constructor: Modal\n\n    , toggle: function () {\n        return this[!this.isShown ? 'show' : 'hide']()\n      }\n\n    , show: function () {\n        var that = this\n          , e = $.Event('show')\n\n        this.$element.trigger(e)\n\n        if (this.isShown || e.isDefaultPrevented()) return\n\n        this.isShown = true\n\n        this.escape()\n\n        this.backdrop(function () {\n          var transition = $.support.transition && that.$element.hasClass('fade')\n\n          if (!that.$element.parent().length) {\n            that.$element.appendTo(document.body) //don't move modals dom position\n          }\n\n          that.$element.show()\n\n          if (transition) {\n            that.$element[0].offsetWidth // force reflow\n          }\n\n          that.$element\n            .addClass('in')\n            .attr('aria-hidden', false)\n\n          that.enforceFocus()\n\n          transition ?\n            that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :\n            that.$element.focus().trigger('shown')\n\n        })\n      }\n\n    , hide: function (e) {\n        e && e.preventDefault()\n\n        var that = this\n\n        e = $.Event('hide')\n\n        this.$element.trigger(e)\n\n        if (!this.isShown || e.isDefaultPrevented()) return\n\n        this.isShown = false\n\n        this.escape()\n\n        $(document).off('focusin.modal')\n\n        this.$element\n          .removeClass('in')\n          .attr('aria-hidden', true)\n\n        $.support.transition && this.$element.hasClass('fade') ?\n          this.hideWithTransition() :\n          this.hideModal()\n      }\n\n    , enforceFocus: function () {\n        var that = this\n        $(document).on('focusin.modal', function (e) {\n          if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {\n            that.$element.focus()\n          }\n        })\n      }\n\n    , escape: function () {\n        var that = this\n        if (this.isShown && this.options.keyboard) {\n          this.$element.on('keyup.dismiss.modal', function ( e ) {\n            e.which == 27 && that.hide()\n          })\n        } else if (!this.isShown) {\n          this.$element.off('keyup.dismiss.modal')\n        }\n      }\n\n    , hideWithTransition: function () {\n        var that = this\n          , timeout = setTimeout(function () {\n              that.$element.off($.support.transition.end)\n              that.hideModal()\n            }, 500)\n\n        this.$element.one($.support.transition.end, function () {\n          clearTimeout(timeout)\n          that.hideModal()\n        })\n      }\n\n    , hideModal: function () {\n        var that = this\n        this.$element.hide()\n        this.backdrop(function () {\n          that.removeBackdrop()\n          that.$element.trigger('hidden')\n        })\n      }\n\n    , removeBackdrop: function () {\n        this.$backdrop && this.$backdrop.remove()\n        this.$backdrop = null\n      }\n\n    , backdrop: function (callback) {\n        var that = this\n          , animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n        if (this.isShown && this.options.backdrop) {\n          var doAnimate = $.support.transition && animate\n\n          this.$backdrop = $('<div class=\"modal-backdrop ' + animate + '\" />')\n            .appendTo(document.body)\n\n          this.$backdrop.click(\n            this.options.backdrop == 'static' ?\n              $.proxy(this.$element[0].focus, this.$element[0])\n            : $.proxy(this.hide, this)\n          )\n\n          if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n          this.$backdrop.addClass('in')\n\n          if (!callback) return\n\n          doAnimate ?\n            this.$backdrop.one($.support.transition.end, callback) :\n            callback()\n\n        } else if (!this.isShown && this.$backdrop) {\n          this.$backdrop.removeClass('in')\n\n          $.support.transition && this.$element.hasClass('fade')?\n            this.$backdrop.one($.support.transition.end, callback) :\n            callback()\n\n        } else if (callback) {\n          callback()\n        }\n      }\n  }\n\n\n /* MODAL PLUGIN DEFINITION\n  * ======================= */\n\n  var old = $.fn.modal\n\n  $.fn.modal = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('modal')\n        , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)\n      if (!data) $this.data('modal', (data = new Modal(this, options)))\n      if (typeof option == 'string') data[option]()\n      else if (options.show) data.show()\n    })\n  }\n\n  $.fn.modal.defaults = {\n      backdrop: true\n    , keyboard: true\n    , show: true\n  }\n\n  $.fn.modal.Constructor = Modal\n\n\n /* MODAL NO CONFLICT\n  * ================= */\n\n  $.fn.modal.noConflict = function () {\n    $.fn.modal = old\n    return this\n  }\n\n\n /* MODAL DATA-API\n  * ============== */\n\n  $(document).on('click.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n    var $this = $(this)\n      , href = $this.attr('href')\n      , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) //strip for ie7\n      , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())\n\n    e.preventDefault()\n\n    $target\n      .modal(option)\n      .one('hide', function () {\n        $this.focus()\n      })\n  })\n\n}(window.jQuery);\n/* ===========================================================\n * bootstrap-tooltip.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#tooltips\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ===========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* TOOLTIP PUBLIC CLASS DEFINITION\n  * =============================== */\n\n  var Tooltip = function (element, options) {\n    this.init('tooltip', element, options)\n  }\n\n  Tooltip.prototype = {\n\n    constructor: Tooltip\n\n  , init: function (type, element, options) {\n      var eventIn\n        , eventOut\n        , triggers\n        , trigger\n        , i\n\n      this.type = type\n      this.$element = $(element)\n      this.options = this.getOptions(options)\n      this.enabled = true\n\n      triggers = this.options.trigger.split(' ')\n\n      for (i = triggers.length; i--;) {\n        trigger = triggers[i]\n        if (trigger == 'click') {\n          this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n        } else if (trigger != 'manual') {\n          eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'\n          eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'\n          this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n          this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n        }\n      }\n\n      this.options.selector ?\n        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n        this.fixTitle()\n    }\n\n  , getOptions: function (options) {\n      options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)\n\n      if (options.delay && typeof options.delay == 'number') {\n        options.delay = {\n          show: options.delay\n        , hide: options.delay\n        }\n      }\n\n      return options\n    }\n\n  , enter: function (e) {\n      var defaults = $.fn[this.type].defaults\n        , options = {}\n        , self\n\n      this._options && $.each(this._options, function (key, value) {\n        if (defaults[key] != value) options[key] = value\n      }, this)\n\n      self = $(e.currentTarget)[this.type](options).data(this.type)\n\n      if (!self.options.delay || !self.options.delay.show) return self.show()\n\n      clearTimeout(this.timeout)\n      self.hoverState = 'in'\n      this.timeout = setTimeout(function() {\n        if (self.hoverState == 'in') self.show()\n      }, self.options.delay.show)\n    }\n\n  , leave: function (e) {\n      var self = $(e.currentTarget)[this.type](this._options).data(this.type)\n\n      if (this.timeout) clearTimeout(this.timeout)\n      if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n      self.hoverState = 'out'\n      this.timeout = setTimeout(function() {\n        if (self.hoverState == 'out') self.hide()\n      }, self.options.delay.hide)\n    }\n\n  , show: function () {\n      var $tip\n        , pos\n        , actualWidth\n        , actualHeight\n        , placement\n        , tp\n        , e = $.Event('show')\n\n      if (this.hasContent() && this.enabled) {\n        this.$element.trigger(e)\n        if (e.isDefaultPrevented()) return\n        $tip = this.tip()\n        this.setContent()\n\n        if (this.options.animation) {\n          $tip.addClass('fade')\n        }\n\n        placement = typeof this.options.placement == 'function' ?\n          this.options.placement.call(this, $tip[0], this.$element[0]) :\n          this.options.placement\n\n        $tip\n          .detach()\n          .css({ top: 0, left: 0, display: 'block' })\n\n        this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n\n        pos = this.getPosition()\n\n        actualWidth = $tip[0].offsetWidth\n        actualHeight = $tip[0].offsetHeight\n\n        switch (placement) {\n          case 'bottom':\n            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}\n            break\n          case 'top':\n            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}\n            break\n          case 'left':\n            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}\n            break\n          case 'right':\n            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}\n            break\n        }\n\n        this.applyPlacement(tp, placement)\n        this.$element.trigger('shown')\n      }\n    }\n\n  , applyPlacement: function(offset, placement){\n      var $tip = this.tip()\n        , width = $tip[0].offsetWidth\n        , height = $tip[0].offsetHeight\n        , actualWidth\n        , actualHeight\n        , delta\n        , replace\n\n      $tip\n        .offset(offset)\n        .addClass(placement)\n        .addClass('in')\n\n      actualWidth = $tip[0].offsetWidth\n      actualHeight = $tip[0].offsetHeight\n\n      if (placement == 'top' && actualHeight != height) {\n        offset.top = offset.top + height - actualHeight\n        replace = true\n      }\n\n      if (placement == 'bottom' || placement == 'top') {\n        delta = 0\n\n        if (offset.left < 0){\n          delta = offset.left * -2\n          offset.left = 0\n          $tip.offset(offset)\n          actualWidth = $tip[0].offsetWidth\n          actualHeight = $tip[0].offsetHeight\n        }\n\n        this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')\n      } else {\n        this.replaceArrow(actualHeight - height, actualHeight, 'top')\n      }\n\n      if (replace) $tip.offset(offset)\n    }\n\n  , replaceArrow: function(delta, dimension, position){\n      this\n        .arrow()\n        .css(position, delta ? (50 * (1 - delta / dimension) + \"%\") : '')\n    }\n\n  , setContent: function () {\n      var $tip = this.tip()\n        , title = this.getTitle()\n\n      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n      $tip.removeClass('fade in top bottom left right')\n    }\n\n  , hide: function () {\n      var that = this\n        , $tip = this.tip()\n        , e = $.Event('hide')\n\n      this.$element.trigger(e)\n      if (e.isDefaultPrevented()) return\n\n      $tip.removeClass('in')\n\n      function removeWithAnimation() {\n        var timeout = setTimeout(function () {\n          $tip.off($.support.transition.end).detach()\n        }, 500)\n\n        $tip.one($.support.transition.end, function () {\n          clearTimeout(timeout)\n          $tip.detach()\n        })\n      }\n\n      $.support.transition && this.$tip.hasClass('fade') ?\n        removeWithAnimation() :\n        $tip.detach()\n\n      this.$element.trigger('hidden')\n\n      return this\n    }\n\n  , fixTitle: function () {\n      var $e = this.$element\n      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {\n        $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n      }\n    }\n\n  , hasContent: function () {\n      return this.getTitle()\n    }\n\n  , getPosition: function () {\n      var el = this.$element[0]\n      return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {\n        width: el.offsetWidth\n      , height: el.offsetHeight\n      }, this.$element.offset())\n    }\n\n  , getTitle: function () {\n      var title\n        , $e = this.$element\n        , o = this.options\n\n      title = $e.attr('data-original-title')\n        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\n\n      return title\n    }\n\n  , tip: function () {\n      return this.$tip = this.$tip || $(this.options.template)\n    }\n\n  , arrow: function(){\n      return this.$arrow = this.$arrow || this.tip().find(\".tooltip-arrow\")\n    }\n\n  , validate: function () {\n      if (!this.$element[0].parentNode) {\n        this.hide()\n        this.$element = null\n        this.options = null\n      }\n    }\n\n  , enable: function () {\n      this.enabled = true\n    }\n\n  , disable: function () {\n      this.enabled = false\n    }\n\n  , toggleEnabled: function () {\n      this.enabled = !this.enabled\n    }\n\n  , toggle: function (e) {\n      var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this\n      self.tip().hasClass('in') ? self.hide() : self.show()\n    }\n\n  , destroy: function () {\n      this.hide().$element.off('.' + this.type).removeData(this.type)\n    }\n\n  }\n\n\n /* TOOLTIP PLUGIN DEFINITION\n  * ========================= */\n\n  var old = $.fn.tooltip\n\n  $.fn.tooltip = function ( option ) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('tooltip')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.tooltip.Constructor = Tooltip\n\n  $.fn.tooltip.defaults = {\n    animation: true\n  , placement: 'top'\n  , selector: false\n  , template: '<div class=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>'\n  , trigger: 'hover focus'\n  , title: ''\n  , delay: 0\n  , html: false\n  , container: false\n  }\n\n\n /* TOOLTIP NO CONFLICT\n  * =================== */\n\n  $.fn.tooltip.noConflict = function () {\n    $.fn.tooltip = old\n    return this\n  }\n\n}(window.jQuery);\n/* ===========================================================\n * bootstrap-popover.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#popovers\n * ===========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* POPOVER PUBLIC CLASS DEFINITION\n  * =============================== */\n\n  var Popover = function (element, options) {\n    this.init('popover', element, options)\n  }\n\n\n  /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js\n     ========================================== */\n\n  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {\n\n    constructor: Popover\n\n  , setContent: function () {\n      var $tip = this.tip()\n        , title = this.getTitle()\n        , content = this.getContent()\n\n      $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n      $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)\n\n      $tip.removeClass('fade top bottom left right in')\n    }\n\n  , hasContent: function () {\n      return this.getTitle() || this.getContent()\n    }\n\n  , getContent: function () {\n      var content\n        , $e = this.$element\n        , o = this.options\n\n      content = (typeof o.content == 'function' ? o.content.call($e[0]) :  o.content)\n        || $e.attr('data-content')\n\n      return content\n    }\n\n  , tip: function () {\n      if (!this.$tip) {\n        this.$tip = $(this.options.template)\n      }\n      return this.$tip\n    }\n\n  , destroy: function () {\n      this.hide().$element.off('.' + this.type).removeData(this.type)\n    }\n\n  })\n\n\n /* POPOVER PLUGIN DEFINITION\n  * ======================= */\n\n  var old = $.fn.popover\n\n  $.fn.popover = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('popover')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('popover', (data = new Popover(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.popover.Constructor = Popover\n\n  $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {\n    placement: 'right'\n  , trigger: 'click'\n  , content: ''\n  , template: '<div class=\"popover\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'\n  })\n\n\n /* POPOVER NO CONFLICT\n  * =================== */\n\n  $.fn.popover.noConflict = function () {\n    $.fn.popover = old\n    return this\n  }\n\n}(window.jQuery);\n/* =============================================================\n * bootstrap-scrollspy.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#scrollspy\n * =============================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ============================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* SCROLLSPY CLASS DEFINITION\n  * ========================== */\n\n  function ScrollSpy(element, options) {\n    var process = $.proxy(this.process, this)\n      , $element = $(element).is('body') ? $(window) : $(element)\n      , href\n    this.options = $.extend({}, $.fn.scrollspy.defaults, options)\n    this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)\n    this.selector = (this.options.target\n      || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) //strip for ie7\n      || '') + ' .nav li > a'\n    this.$body = $('body')\n    this.refresh()\n    this.process()\n  }\n\n  ScrollSpy.prototype = {\n\n      constructor: ScrollSpy\n\n    , refresh: function () {\n        var self = this\n          , $targets\n\n        this.offsets = $([])\n        this.targets = $([])\n\n        $targets = this.$body\n          .find(this.selector)\n          .map(function () {\n            var $el = $(this)\n              , href = $el.data('target') || $el.attr('href')\n              , $href = /^#\\w/.test(href) && $(href)\n            return ( $href\n              && $href.length\n              && [[ $href.position().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]] ) || null\n          })\n          .sort(function (a, b) { return a[0] - b[0] })\n          .each(function () {\n            self.offsets.push(this[0])\n            self.targets.push(this[1])\n          })\n      }\n\n    , process: function () {\n        var scrollTop = this.$scrollElement.scrollTop() + this.options.offset\n          , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight\n          , maxScroll = scrollHeight - this.$scrollElement.height()\n          , offsets = this.offsets\n          , targets = this.targets\n          , activeTarget = this.activeTarget\n          , i\n\n        if (scrollTop >= maxScroll) {\n          return activeTarget != (i = targets.last()[0])\n            && this.activate ( i )\n        }\n\n        for (i = offsets.length; i--;) {\n          activeTarget != targets[i]\n            && scrollTop >= offsets[i]\n            && (!offsets[i + 1] || scrollTop <= offsets[i + 1])\n            && this.activate( targets[i] )\n        }\n      }\n\n    , activate: function (target) {\n        var active\n          , selector\n\n        this.activeTarget = target\n\n        $(this.selector)\n          .parent('.active')\n          .removeClass('active')\n\n        selector = this.selector\n          + '[data-target=\"' + target + '\"],'\n          + this.selector + '[href=\"' + target + '\"]'\n\n        active = $(selector)\n          .parent('li')\n          .addClass('active')\n\n        if (active.parent('.dropdown-menu').length)  {\n          active = active.closest('li.dropdown').addClass('active')\n        }\n\n        active.trigger('activate')\n      }\n\n  }\n\n\n /* SCROLLSPY PLUGIN DEFINITION\n  * =========================== */\n\n  var old = $.fn.scrollspy\n\n  $.fn.scrollspy = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('scrollspy')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.scrollspy.Constructor = ScrollSpy\n\n  $.fn.scrollspy.defaults = {\n    offset: 10\n  }\n\n\n /* SCROLLSPY NO CONFLICT\n  * ===================== */\n\n  $.fn.scrollspy.noConflict = function () {\n    $.fn.scrollspy = old\n    return this\n  }\n\n\n /* SCROLLSPY DATA-API\n  * ================== */\n\n  $(window).on('load', function () {\n    $('[data-spy=\"scroll\"]').each(function () {\n      var $spy = $(this)\n      $spy.scrollspy($spy.data())\n    })\n  })\n\n}(window.jQuery);/* ========================================================\n * bootstrap-tab.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#tabs\n * ========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* TAB CLASS DEFINITION\n  * ==================== */\n\n  var Tab = function (element) {\n    this.element = $(element)\n  }\n\n  Tab.prototype = {\n\n    constructor: Tab\n\n  , show: function () {\n      var $this = this.element\n        , $ul = $this.closest('ul:not(.dropdown-menu)')\n        , selector = $this.attr('data-target')\n        , previous\n        , $target\n        , e\n\n      if (!selector) {\n        selector = $this.attr('href')\n        selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n      }\n\n      if ( $this.parent('li').hasClass('active') ) return\n\n      previous = $ul.find('.active:last a')[0]\n\n      e = $.Event('show', {\n        relatedTarget: previous\n      })\n\n      $this.trigger(e)\n\n      if (e.isDefaultPrevented()) return\n\n      $target = $(selector)\n\n      this.activate($this.parent('li'), $ul)\n      this.activate($target, $target.parent(), function () {\n        $this.trigger({\n          type: 'shown'\n        , relatedTarget: previous\n        })\n      })\n    }\n\n  , activate: function ( element, container, callback) {\n      var $active = container.find('> .active')\n        , transition = callback\n            && $.support.transition\n            && $active.hasClass('fade')\n\n      function next() {\n        $active\n          .removeClass('active')\n          .find('> .dropdown-menu > .active')\n          .removeClass('active')\n\n        element.addClass('active')\n\n        if (transition) {\n          element[0].offsetWidth // reflow for transition\n          element.addClass('in')\n        } else {\n          element.removeClass('fade')\n        }\n\n        if ( element.parent('.dropdown-menu') ) {\n          element.closest('li.dropdown').addClass('active')\n        }\n\n        callback && callback()\n      }\n\n      transition ?\n        $active.one($.support.transition.end, next) :\n        next()\n\n      $active.removeClass('in')\n    }\n  }\n\n\n /* TAB PLUGIN DEFINITION\n  * ===================== */\n\n  var old = $.fn.tab\n\n  $.fn.tab = function ( option ) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('tab')\n      if (!data) $this.data('tab', (data = new Tab(this)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.tab.Constructor = Tab\n\n\n /* TAB NO CONFLICT\n  * =============== */\n\n  $.fn.tab.noConflict = function () {\n    $.fn.tab = old\n    return this\n  }\n\n\n /* TAB DATA-API\n  * ============ */\n\n  $(document).on('click.tab.data-api', '[data-toggle=\"tab\"], [data-toggle=\"pill\"]', function (e) {\n    e.preventDefault()\n    $(this).tab('show')\n  })\n\n}(window.jQuery);/* =============================================================\n * bootstrap-typeahead.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#typeahead\n * =============================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ============================================================ */\n\n\n!function($){\n\n  \"use strict\"; // jshint ;_;\n\n\n /* TYPEAHEAD PUBLIC CLASS DEFINITION\n  * ================================= */\n\n  var Typeahead = function (element, options) {\n    this.$element = $(element)\n    this.options = $.extend({}, $.fn.typeahead.defaults, options)\n    this.matcher = this.options.matcher || this.matcher\n    this.sorter = this.options.sorter || this.sorter\n    this.highlighter = this.options.highlighter || this.highlighter\n    this.updater = this.options.updater || this.updater\n    this.source = this.options.source\n    this.$menu = $(this.options.menu)\n    this.shown = false\n    this.listen()\n  }\n\n  Typeahead.prototype = {\n\n    constructor: Typeahead\n\n  , select: function () {\n      var val = this.$menu.find('.active').attr('data-value')\n      this.$element\n        .val(this.updater(val))\n        .change()\n      return this.hide()\n    }\n\n  , updater: function (item) {\n      return item\n    }\n\n  , show: function () {\n      var pos = $.extend({}, this.$element.position(), {\n        height: this.$element[0].offsetHeight\n      })\n\n      this.$menu\n        .insertAfter(this.$element)\n        .css({\n          top: pos.top + pos.height\n        , left: pos.left\n        })\n        .show()\n\n      this.shown = true\n      return this\n    }\n\n  , hide: function () {\n      this.$menu.hide()\n      this.shown = false\n      return this\n    }\n\n  , lookup: function (event) {\n      var items\n\n      this.query = this.$element.val()\n\n      if (!this.query || this.query.length < this.options.minLength) {\n        return this.shown ? this.hide() : this\n      }\n\n      items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source\n\n      return items ? this.process(items) : this\n    }\n\n  , process: function (items) {\n      var that = this\n\n      items = $.grep(items, function (item) {\n        return that.matcher(item)\n      })\n\n      items = this.sorter(items)\n\n      if (!items.length) {\n        return this.shown ? this.hide() : this\n      }\n\n      return this.render(items.slice(0, this.options.items)).show()\n    }\n\n  , matcher: function (item) {\n      return ~item.toLowerCase().indexOf(this.query.toLowerCase())\n    }\n\n  , sorter: function (items) {\n      var beginswith = []\n        , caseSensitive = []\n        , caseInsensitive = []\n        , item\n\n      while (item = items.shift()) {\n        if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)\n        else if (~item.indexOf(this.query)) caseSensitive.push(item)\n        else caseInsensitive.push(item)\n      }\n\n      return beginswith.concat(caseSensitive, caseInsensitive)\n    }\n\n  , highlighter: function (item) {\n      var query = this.query.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, '\\\\$&')\n      return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {\n        return '<strong>' + match + '</strong>'\n      })\n    }\n\n  , render: function (items) {\n      var that = this\n\n      items = $(items).map(function (i, item) {\n        i = $(that.options.item).attr('data-value', item)\n        i.find('a').html(that.highlighter(item))\n        return i[0]\n      })\n\n      items.first().addClass('active')\n      this.$menu.html(items)\n      return this\n    }\n\n  , next: function (event) {\n      var active = this.$menu.find('.active').removeClass('active')\n        , next = active.next()\n\n      if (!next.length) {\n        next = $(this.$menu.find('li')[0])\n      }\n\n      next.addClass('active')\n    }\n\n  , prev: function (event) {\n      var active = this.$menu.find('.active').removeClass('active')\n        , prev = active.prev()\n\n      if (!prev.length) {\n        prev = this.$menu.find('li').last()\n      }\n\n      prev.addClass('active')\n    }\n\n  , listen: function () {\n      this.$element\n        .on('focus',    $.proxy(this.focus, this))\n        .on('blur',     $.proxy(this.blur, this))\n        .on('keypress', $.proxy(this.keypress, this))\n        .on('keyup',    $.proxy(this.keyup, this))\n\n      if (this.eventSupported('keydown')) {\n        this.$element.on('keydown', $.proxy(this.keydown, this))\n      }\n\n      this.$menu\n        .on('click', $.proxy(this.click, this))\n        .on('mouseenter', 'li', $.proxy(this.mouseenter, this))\n        .on('mouseleave', 'li', $.proxy(this.mouseleave, this))\n    }\n\n  , eventSupported: function(eventName) {\n      var isSupported = eventName in this.$element\n      if (!isSupported) {\n        this.$element.setAttribute(eventName, 'return;')\n        isSupported = typeof this.$element[eventName] === 'function'\n      }\n      return isSupported\n    }\n\n  , move: function (e) {\n      if (!this.shown) return\n\n      switch(e.keyCode) {\n        case 9: // tab\n        case 13: // enter\n        case 27: // escape\n          e.preventDefault()\n          break\n\n        case 38: // up arrow\n          e.preventDefault()\n          this.prev()\n          break\n\n        case 40: // down arrow\n          e.preventDefault()\n          this.next()\n          break\n      }\n\n      e.stopPropagation()\n    }\n\n  , keydown: function (e) {\n      this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])\n      this.move(e)\n    }\n\n  , keypress: function (e) {\n      if (this.suppressKeyPressRepeat) return\n      this.move(e)\n    }\n\n  , keyup: function (e) {\n      switch(e.keyCode) {\n        case 40: // down arrow\n        case 38: // up arrow\n        case 16: // shift\n        case 17: // ctrl\n        case 18: // alt\n          break\n\n        case 9: // tab\n        case 13: // enter\n          if (!this.shown) return\n          this.select()\n          break\n\n        case 27: // escape\n          if (!this.shown) return\n          this.hide()\n          break\n\n        default:\n          this.lookup()\n      }\n\n      e.stopPropagation()\n      e.preventDefault()\n  }\n\n  , focus: function (e) {\n      this.focused = true\n    }\n\n  , blur: function (e) {\n      this.focused = false\n      if (!this.mousedover && this.shown) this.hide()\n    }\n\n  , click: function (e) {\n      e.stopPropagation()\n      e.preventDefault()\n      this.select()\n      this.$element.focus()\n    }\n\n  , mouseenter: function (e) {\n      this.mousedover = true\n      this.$menu.find('.active').removeClass('active')\n      $(e.currentTarget).addClass('active')\n    }\n\n  , mouseleave: function (e) {\n      this.mousedover = false\n      if (!this.focused && this.shown) this.hide()\n    }\n\n  }\n\n\n  /* TYPEAHEAD PLUGIN DEFINITION\n   * =========================== */\n\n  var old = $.fn.typeahead\n\n  $.fn.typeahead = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('typeahead')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.typeahead.defaults = {\n    source: []\n  , items: 8\n  , menu: '<ul class=\"typeahead dropdown-menu\"></ul>'\n  , item: '<li><a href=\"#\"></a></li>'\n  , minLength: 1\n  }\n\n  $.fn.typeahead.Constructor = Typeahead\n\n\n /* TYPEAHEAD NO CONFLICT\n  * =================== */\n\n  $.fn.typeahead.noConflict = function () {\n    $.fn.typeahead = old\n    return this\n  }\n\n\n /* TYPEAHEAD DATA-API\n  * ================== */\n\n  $(document).on('focus.typeahead.data-api', '[data-provide=\"typeahead\"]', function (e) {\n    var $this = $(this)\n    if ($this.data('typeahead')) return\n    $this.typeahead($this.data())\n  })\n\n}(window.jQuery);\n/* ==========================================================\n * bootstrap-affix.js v2.3.2\n * http://twitter.github.com/bootstrap/javascript.html#affix\n * ==========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* AFFIX CLASS DEFINITION\n  * ====================== */\n\n  var Affix = function (element, options) {\n    this.options = $.extend({}, $.fn.affix.defaults, options)\n    this.$window = $(window)\n      .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))\n      .on('click.affix.data-api',  $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))\n    this.$element = $(element)\n    this.checkPosition()\n  }\n\n  Affix.prototype.checkPosition = function () {\n    if (!this.$element.is(':visible')) return\n\n    var scrollHeight = $(document).height()\n      , scrollTop = this.$window.scrollTop()\n      , position = this.$element.offset()\n      , offset = this.options.offset\n      , offsetBottom = offset.bottom\n      , offsetTop = offset.top\n      , reset = 'affix affix-top affix-bottom'\n      , affix\n\n    if (typeof offset != 'object') offsetBottom = offsetTop = offset\n    if (typeof offsetTop == 'function') offsetTop = offset.top()\n    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()\n\n    affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?\n      false    : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?\n      'bottom' : offsetTop != null && scrollTop <= offsetTop ?\n      'top'    : false\n\n    if (this.affixed === affix) return\n\n    this.affixed = affix\n    this.unpin = affix == 'bottom' ? position.top - scrollTop : null\n\n    this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))\n  }\n\n\n /* AFFIX PLUGIN DEFINITION\n  * ======================= */\n\n  var old = $.fn.affix\n\n  $.fn.affix = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('affix')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('affix', (data = new Affix(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.affix.Constructor = Affix\n\n  $.fn.affix.defaults = {\n    offset: 0\n  }\n\n\n /* AFFIX NO CONFLICT\n  * ================= */\n\n  $.fn.affix.noConflict = function () {\n    $.fn.affix = old\n    return this\n  }\n\n\n /* AFFIX DATA-API\n  * ============== */\n\n  $(window).on('load', function () {\n    $('[data-spy=\"affix\"]').each(function () {\n      var $spy = $(this)\n        , data = $spy.data()\n\n      data.offset = data.offset || {}\n\n      data.offsetBottom && (data.offset.bottom = data.offsetBottom)\n      data.offsetTop && (data.offset.top = data.offsetTop)\n\n      $spy.affix(data)\n    })\n  })\n\n\n}(window.jQuery);"
  },
  {
    "path": "src/js/lib/fiddler.js",
    "content": "/**\n * base library\n * @return {[type]} [description]\n */\nvar Fiddler = function(){\n    var Fiddler = {};\n    Fiddler.isJson = function(string){\n        try{\n            JSON.parse(string);\n            return true;\n        }catch(e){\n            return false;\n        }\n        return false;\n    }\n    Fiddler.isJsonp = function(string){\n        string = string.trim();\n        var pattern = /^[\\w\\.]+\\s*\\(.*\\);?$/;\n        return pattern.test(string);\n    }\n    Fiddler.getFileExt = function(file){\n        if (file.indexOf('?') > -1) {\n            file = file.substr(0, file.indexOf('?'));\n        };\n        var pos = file.lastIndexOf(\".\");\n        return file.substr(pos + 1);\n    }\n    /**\n     * check url is http or https\n     * @param  {[type]} url [description]\n     * @return {[type]}     [description]\n     */\n    Fiddler.checkUrl = function(url){\n        url = url || \"\";\n        if (url.indexOf('?fiddler=') > -1 || url.indexOf('&fiddler=') > -1 ) {\n            return false;\n        };\n        var ignoreList = [\n            'http://hm.baidu.com/',\n            'http://push.zhanzhang.baidu.com/',\n            'http://api.share.baidu.com/',\n            'http://www.ueapp.com/',\n            'http://ueapp.b0.upaiyun.com/'\n        ];\n        var flag = ignoreList.some(function(item){\n            return url.indexOf(item) === 0;\n        })\n        if(flag){\n            return false;\n        }\n        if (url.indexOf('http://') == 0 || url.indexOf('https://') == 0) {\n            return true;\n        };\n        return false;\n    }\n    Fiddler.queryUrl = function (url, key) {\n        if (url.indexOf('?') == -1) {\n            return {};\n        };\n        url = url.replace(/^[^?=]*\\?/ig, '').split('#')[0]; \n        var json = {};\n        url.replace(/(^|&)([^&=]+)=([^&]*)/g, function (a, b, key , value){\n            try {\n                key = decodeURIComponent(key);\n            } catch(e) {}\n            try {\n                value = decodeURIComponent(value);\n            } catch(e) {}\n            if (!(key in json)) {\n                json[key] = /\\[\\]$/.test(key) ? [value] : value; \n            }\n            else if (json[key] instanceof Array) {\n                json[key].push(value);\n            }\n            else {\n                json[key] = [json[key], value];\n            }\n        });\n        return key ? json[key] : json;\n    }\n    Fiddler.bindEvent = function(el, configs){\n        el = $(el);\n        for(var name in configs){\n            var value = configs[name];\n            if (typeof value == 'function') {\n                var obj = {};\n                obj.click = value;\n                value = obj;\n            };\n            for(var type in value){\n                el.delegate(name, type, value[type]);\n            }\n        }\n    }\n    Fiddler.pathAdd = function(prefix, suffix){\n        if (prefix.substr(prefix.length - 1) == '/') {\n            prefix = prefix.substr(0, prefix.length - 1);\n        };\n        if (suffix.substr(0, 1) == '/') {\n            suffix = suffix.substr(1);\n        };\n        return prefix + \"/\" + suffix;\n    }\n    Fiddler.urlAdd = function(prefix, suffix){\n        return prefix + \"/\" + suffix;\n    }\n    Fiddler.truncate = function(string, length, suffix){\n        suffix = suffix || \"...\";\n        if (string.length > length) {\n            return string.substr(0, length) + suffix;\n        };\n        return string;\n    }\n    Fiddler.truncateCenter = function(string, length, suffix){\n        suffix = suffix || \"...\";\n        if (string.length > length) {\n            var p = parseInt(length / 2);\n            var s = length - p;\n            return string.substr(0, p) + suffix + string.substr(string.length - s);\n        };\n        return string;\n    }\n    Fiddler.getHumanSize = function(size){\n        size = size | 0;\n       var list = [\n            [1024 * 1024, \"MB\"],\n            [1024, \"KB\"],\n            [1, \"B\"]\n       ];\n       var hummanSize = '';\n       list.some(function(item){\n            if (size > item[0]) {\n                hummanSize = (size / item[0]).toFixed(1) + item[1];\n                return true;\n            };\n       });\n       return hummanSize || size;\n    }\n    /**\n     * url detail\n     * @param  {[type]} url [description]\n     * @return {[type]}     [description]\n     */\n    Fiddler.getUrlDetail = function(url){\n        var a = document.createElement('a');\n        a.href = url;\n        return {\n            protocol: a.protocol,\n            host: a.protocol + \"//\" + a.hostname + (a.port ? (\":\" + a.port) : \"\"),\n            path: a.pathname\n        }\n    }\n    Fiddler.delay = function(delayTime){\n        var time = new Date * 1;\n        while(true){\n            var endTime = new Date * 1;\n            var sub = endTime - time;\n            if (sub >= delayTime) {\n                return this;\n            };\n        }\n        return this;\n    }\n    Fiddler.mix = function(des, src, mixer) {\n        mixer = mixer || function(d, s){\n            if(typeof d === 'undefined'){\n                return s;\n            }\n        }\n        if(mixer == true){\n            mixer = function(d, s){return s};\n        }       \n        for (var i in src) {\n            var v = mixer(des[i], src[i], i, des, src);\n            if(typeof v !== 'undefined'){\n                des[i] = v;\n            }\n        }\n        return des;\n    };\n\n    Fiddler.CustEvent = function(){\n        var handlers = {};\n        return {\n            on: function(event, handler){\n                if(typeof event === 'object'){\n                    for(var i in event){\n                        this.on(i, event[i]);\n                    }\n                    return;\n                }\n\n                handlers[event] = handlers[event] || [];\n                handlers[event].push(handler);\n            },\n            un: function(event, handler){\n                if(typeof event === 'object'){\n                    for(var i in event){\n                        this.un(i, event[i]);\n                    }\n                    return;\n                }\n\n                var _handlers = handlers[event] || [];\n                _handlers.some(function(o, i){\n                    if(o == handler){\n                        _handlers.splice(i, 1);\n                        return true;\n                    }\n                });\n            },\n            clear: function(event){\n                var _handlers = handlers[event] || [];\n                _handlers.length = 0;\n            },\n            clearAll: function(){\n                handlers = {};\n            },\n            fire: function(event, args){\n                args = args || {};\n                var msg = {\n                    data: args,\n                    type: event,\n                    target: this,\n                    returnValue: true,\n                    preventDefault: function(){\n                        args.returnValue = false;\n                    }\n                };\n                var _handlers = handlers[event] || [];\n                _handlers = _handlers.concat(handlers['*'] || []);\n                _handlers.forEach(function(o){\n                    o(msg);\n                });\n                return msg.returnValue;\n            },\n            fireSome: function(event, args){\n                args = args || {};\n                var msg = {\n                    data: args,\n                    type: event,\n                    target: this,\n                };\n                var _handlers = handlers[event] || [];\n                _handlers = _handlers.concat(handlers['*'] || []);\n                var ret = null;\n                _handlers.some(function(o){\n                    var result = o(msg);\n                    if (result) {\n                        ret = result;\n                        return true;\n                    };\n                });\n                return ret;\n            },\n            fireMerge: function(event, args){\n                args = args || {};\n                var msg = {\n                    data: args,\n                    type: event,\n                    target: this,\n                };\n                var _handlers = handlers[event] || [];\n                _handlers = _handlers.concat(handlers['*'] || []);\n                _handlers.forEach(function(o){\n                    var result = o(msg);\n                    if (result) {\n                        msg.data = result;\n                    };\n                });\n                return msg.data;\n            }\n        };\n    };\n    Fiddler.implement = function(source, proto){\n        if(typeof proto == \"function\"){\n            proto = proto(Fiddler); \n        }\n        return Fiddler.mix(source, proto, true);\n    };\n    Fiddler.encode4Html = function(s){\n        var el = document.createElement('pre');\n        var text = document.createTextNode(s);\n        el.appendChild(text);\n        return el.innerHTML;\n    }\n    //template from qwrap\n    Fiddler.tmpl = (function() {\n        var tmplFuns={};\n        var sArrName = \"sArrCMX\",\n            sLeft = sArrName + '.push(\"';\n        var tags = {\n            '=': {\n                tagG: '=',\n                isBgn: 1,\n                isEnd: 1,\n                sBgn: '\",Fiddler.encode4Html(',\n                sEnd: '),\"'\n            },\n            'js': {\n                tagG: 'js',\n                isBgn: 1,\n                isEnd: 1,\n                sBgn: '\");',\n                sEnd: ';' + sLeft\n            },\n            'js': {\n                tagG: 'js',\n                isBgn: 1,\n                isEnd: 1,\n                sBgn: '\");',\n                sEnd: ';' + sLeft\n            },\n            'if': {\n                tagG: 'if',\n                isBgn: 1,\n                rlt: 1,\n                sBgn: '\");if',\n                sEnd: '{' + sLeft\n            },\n            'elseif': {\n                tagG: 'if',\n                cond: 1,\n                rlt: 1,\n                sBgn: '\");} else if',\n                sEnd: '{' + sLeft\n            },\n            'else': {\n                tagG: 'if',\n                cond: 1,\n                rlt: 2,\n                sEnd: '\");}else{' + sLeft\n            },\n            '/if': {\n                tagG: 'if',\n                isEnd: 1,\n                sEnd: '\");}' + sLeft\n            },\n            'for': {\n                tagG: 'for',\n                isBgn: 1,\n                rlt: 1,\n                sBgn: '\");for',\n                sEnd: '{' + sLeft\n            },\n            '/for': {\n                tagG: 'for',\n                isEnd: 1,\n                sEnd: '\");}' + sLeft\n            },\n            'while': {\n                tagG: 'while',\n                isBgn: 1,\n                rlt: 1,\n                sBgn: '\");while',\n                sEnd: '{' + sLeft\n            },\n            '/while': {\n                tagG: 'while',\n                isEnd: 1,\n                sEnd: '\");}' + sLeft\n            } \n        };\n\n        return function(sTmpl, opts) {\n\n            var fun  = tmplFuns[sTmpl];\n            if (!fun) {\n                var N = -1,\n                    NStat = []; \n                var ss = [\n                    [/\\{strip\\}([\\s\\S]*?)\\{\\/strip\\}/g, function(a, b) {\n                        return b.replace(/[\\r\\n]\\s*\\}/g, \" }\").replace(/[\\r\\n]\\s*/g, \"\");\n                    }],\n                    [/\\\\/g, '\\\\\\\\'],\n                    [/\"/g, '\\\\\"'],\n                    [/\\r/g, '\\\\r'],\n                    [/\\n/g, '\\\\n'], \n                    [\n                        /\\{[\\s\\S]*?\\S\\}/g, \n                        function(a) {\n                            a = a.substr(1, a.length - 2);\n                            for (var i = 0; i < ss2.length; i++) {a = a.replace(ss2[i][0], ss2[i][1]); }\n                            var tagName = a;\n                            if (/^(=|.\\w+)/.test(tagName)) {tagName = RegExp.$1; }\n                            var tag = tags[tagName];\n                            if (tag) {\n                                if (tag.isBgn) {\n                                    var stat = NStat[++N] = {\n                                        tagG: tag.tagG,\n                                        rlt: tag.rlt\n                                    };\n                                }\n                                if (tag.isEnd) {\n                                    if (N < 0) {throw new Error(\"Unexpected Tag: \" + a); }\n                                    stat = NStat[N--];\n                                    if (stat.tagG != tag.tagG) {throw new Error(\"Unmatch Tags: \" + stat.tagG + \"--\" + tagName); }\n                                } else if (!tag.isBgn) {\n                                    if (N < 0) {throw new Error(\"Unexpected Tag:\" + a); }\n                                    stat = NStat[N];\n                                    if (stat.tagG != tag.tagG) {throw new Error(\"Unmatch Tags: \" + stat.tagG + \"--\" + tagName); }\n                                    if (tag.cond && !(tag.cond & stat.rlt)) {throw new Error(\"Unexpected Tag: \" + tagName); }\n                                    stat.rlt = tag.rlt;\n                                }\n                                return (tag.sBgn || '') + a.substr(tagName.length) + (tag.sEnd || '');\n                            } else {\n                                return '\",(' + a + '),\"';\n                            }\n                        }\n                    ]\n                ];\n                var ss2 = [\n                    [/\\\\n/g, '\\n'],\n                    [/\\\\r/g, '\\r'],\n                    [/\\\\\"/g, '\"'],\n                    [/\\\\\\\\/g, '\\\\'],\n                    [/\\$(\\w+)/g, 'opts[\"$1\"]'],\n                    [/print\\(/g, sArrName + '.push(']\n                ];\n                for (var i = 0; i < ss.length; i++) {\n                    sTmpl = sTmpl.replace(ss[i][0], ss[i][1]);\n                }\n                if (N >= 0) {throw new Error(\"Lose end Tag: \" + NStat[N].tagG); }\n                \n                sTmpl = sTmpl.replace(/##7b/g,'{').replace(/##7d/g,'}').replace(/##23/g,'#'); \n                sTmpl = 'var ' + sArrName + '=[];' + sLeft + sTmpl + '\");return ' + sArrName + '.join(\"\");';\n                \n                tmplFuns[sTmpl] = fun = new Function('opts', sTmpl);\n            }\n\n            if (arguments.length > 1) {return fun(opts); }\n            return fun;\n        };\n    }());\n\n    return Fiddler;\n}();"
  },
  {
    "path": "src/js/lib/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v1.10.2\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2013-07-03T13:48Z\n */\n(function( window, undefined ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\"use strict\";\nvar\n    // The deferred used on DOM ready\n    readyList,\n\n    // A central reference to the root jQuery(document)\n    rootjQuery,\n\n    // Support: IE<10\n    // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`\n    core_strundefined = typeof undefined,\n\n    // Use the correct document accordingly with window argument (sandbox)\n    location = window.location,\n    document = window.document,\n    docElem = document.documentElement,\n\n    // Map over jQuery in case of overwrite\n    _jQuery = window.jQuery,\n\n    // Map over the $ in case of overwrite\n    _$ = window.$,\n\n    // [[Class]] -> type pairs\n    class2type = {},\n\n    // List of deleted data cache ids, so we can reuse them\n    core_deletedIds = [],\n\n    core_version = \"1.10.2\",\n\n    // Save a reference to some core methods\n    core_concat = core_deletedIds.concat,\n    core_push = core_deletedIds.push,\n    core_slice = core_deletedIds.slice,\n    core_indexOf = core_deletedIds.indexOf,\n    core_toString = class2type.toString,\n    core_hasOwn = class2type.hasOwnProperty,\n    core_trim = core_version.trim,\n\n    // Define a local copy of jQuery\n    jQuery = function( selector, context ) {\n        // The jQuery object is actually just the init constructor 'enhanced'\n        return new jQuery.fn.init( selector, context, rootjQuery );\n    },\n\n    // Used for matching numbers\n    core_pnum = /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,\n\n    // Used for splitting on whitespace\n    core_rnotwhite = /\\S+/g,\n\n    // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)\n    rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n    // A simple way to check for HTML strings\n    // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n    // Strict HTML recognition (#11290: must start with <)\n    rquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n    // Match a standalone tag\n    rsingleTag = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,\n\n    // JSON RegExp\n    rvalidchars = /^[\\],:{}\\s]*$/,\n    rvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g,\n    rvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[\\da-fA-F]{4})/g,\n    rvalidtokens = /\"[^\"\\\\\\r\\n]*\"|true|false|null|-?(?:\\d+\\.|)\\d+(?:[eE][+-]?\\d+|)/g,\n\n    // Matches dashed string for camelizing\n    rmsPrefix = /^-ms-/,\n    rdashAlpha = /-([\\da-z])/gi,\n\n    // Used by jQuery.camelCase as callback to replace()\n    fcamelCase = function( all, letter ) {\n        return letter.toUpperCase();\n    },\n\n    // The ready event handler\n    completed = function( event ) {\n\n        // readyState === \"complete\" is good enough for us to call the dom ready in oldIE\n        if ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n            detach();\n            jQuery.ready();\n        }\n    },\n    // Clean-up method for dom ready events\n    detach = function() {\n        if ( document.addEventListener ) {\n            document.removeEventListener( \"DOMContentLoaded\", completed, false );\n            window.removeEventListener( \"load\", completed, false );\n\n        } else {\n            document.detachEvent( \"onreadystatechange\", completed );\n            window.detachEvent( \"onload\", completed );\n        }\n    };\n\njQuery.fn = jQuery.prototype = {\n    // The current version of jQuery being used\n    jquery: core_version,\n\n    constructor: jQuery,\n    init: function( selector, context, rootjQuery ) {\n        var match, elem;\n\n        // HANDLE: $(\"\"), $(null), $(undefined), $(false)\n        if ( !selector ) {\n            return this;\n        }\n\n        // Handle HTML strings\n        if ( typeof selector === \"string\" ) {\n            if ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n                // Assume that strings that start and end with <> are HTML and skip the regex check\n                match = [ null, selector, null ];\n\n            } else {\n                match = rquickExpr.exec( selector );\n            }\n\n            // Match html or make sure no context is specified for #id\n            if ( match && (match[1] || !context) ) {\n\n                // HANDLE: $(html) -> $(array)\n                if ( match[1] ) {\n                    context = context instanceof jQuery ? context[0] : context;\n\n                    // scripts is true for back-compat\n                    jQuery.merge( this, jQuery.parseHTML(\n                        match[1],\n                        context && context.nodeType ? context.ownerDocument || context : document,\n                        true\n                    ) );\n\n                    // HANDLE: $(html, props)\n                    if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n                        for ( match in context ) {\n                            // Properties of context are called as methods if possible\n                            if ( jQuery.isFunction( this[ match ] ) ) {\n                                this[ match ]( context[ match ] );\n\n                            // ...and otherwise set as attributes\n                            } else {\n                                this.attr( match, context[ match ] );\n                            }\n                        }\n                    }\n\n                    return this;\n\n                // HANDLE: $(#id)\n                } else {\n                    elem = document.getElementById( match[2] );\n\n                    // Check parentNode to catch when Blackberry 4.6 returns\n                    // nodes that are no longer in the document #6963\n                    if ( elem && elem.parentNode ) {\n                        // Handle the case where IE and Opera return items\n                        // by name instead of ID\n                        if ( elem.id !== match[2] ) {\n                            return rootjQuery.find( selector );\n                        }\n\n                        // Otherwise, we inject the element directly into the jQuery object\n                        this.length = 1;\n                        this[0] = elem;\n                    }\n\n                    this.context = document;\n                    this.selector = selector;\n                    return this;\n                }\n\n            // HANDLE: $(expr, $(...))\n            } else if ( !context || context.jquery ) {\n                return ( context || rootjQuery ).find( selector );\n\n            // HANDLE: $(expr, context)\n            // (which is just equivalent to: $(context).find(expr)\n            } else {\n                return this.constructor( context ).find( selector );\n            }\n\n        // HANDLE: $(DOMElement)\n        } else if ( selector.nodeType ) {\n            this.context = this[0] = selector;\n            this.length = 1;\n            return this;\n\n        // HANDLE: $(function)\n        // Shortcut for document ready\n        } else if ( jQuery.isFunction( selector ) ) {\n            return rootjQuery.ready( selector );\n        }\n\n        if ( selector.selector !== undefined ) {\n            this.selector = selector.selector;\n            this.context = selector.context;\n        }\n\n        return jQuery.makeArray( selector, this );\n    },\n\n    // Start with an empty selector\n    selector: \"\",\n\n    // The default length of a jQuery object is 0\n    length: 0,\n\n    toArray: function() {\n        return core_slice.call( this );\n    },\n\n    // Get the Nth element in the matched element set OR\n    // Get the whole matched element set as a clean array\n    get: function( num ) {\n        return num == null ?\n\n            // Return a 'clean' array\n            this.toArray() :\n\n            // Return just the object\n            ( num < 0 ? this[ this.length + num ] : this[ num ] );\n    },\n\n    // Take an array of elements and push it onto the stack\n    // (returning the new matched element set)\n    pushStack: function( elems ) {\n\n        // Build a new jQuery matched element set\n        var ret = jQuery.merge( this.constructor(), elems );\n\n        // Add the old object onto the stack (as a reference)\n        ret.prevObject = this;\n        ret.context = this.context;\n\n        // Return the newly-formed element set\n        return ret;\n    },\n\n    // Execute a callback for every element in the matched set.\n    // (You can seed the arguments with an array of args, but this is\n    // only used internally.)\n    each: function( callback, args ) {\n        return jQuery.each( this, callback, args );\n    },\n\n    ready: function( fn ) {\n        // Add the callback\n        jQuery.ready.promise().done( fn );\n\n        return this;\n    },\n\n    slice: function() {\n        return this.pushStack( core_slice.apply( this, arguments ) );\n    },\n\n    first: function() {\n        return this.eq( 0 );\n    },\n\n    last: function() {\n        return this.eq( -1 );\n    },\n\n    eq: function( i ) {\n        var len = this.length,\n            j = +i + ( i < 0 ? len : 0 );\n        return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n    },\n\n    map: function( callback ) {\n        return this.pushStack( jQuery.map(this, function( elem, i ) {\n            return callback.call( elem, i, elem );\n        }));\n    },\n\n    end: function() {\n        return this.prevObject || this.constructor(null);\n    },\n\n    // For internal use only.\n    // Behaves like an Array's method, not like a jQuery method.\n    push: core_push,\n    sort: [].sort,\n    splice: [].splice\n};\n\n// Give the init function the jQuery prototype for later instantiation\njQuery.fn.init.prototype = jQuery.fn;\n\njQuery.extend = jQuery.fn.extend = function() {\n    var src, copyIsArray, copy, name, options, clone,\n        target = arguments[0] || {},\n        i = 1,\n        length = arguments.length,\n        deep = false;\n\n    // Handle a deep copy situation\n    if ( typeof target === \"boolean\" ) {\n        deep = target;\n        target = arguments[1] || {};\n        // skip the boolean and the target\n        i = 2;\n    }\n\n    // Handle case when target is a string or something (possible in deep copy)\n    if ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n        target = {};\n    }\n\n    // extend jQuery itself if only one argument is passed\n    if ( length === i ) {\n        target = this;\n        --i;\n    }\n\n    for ( ; i < length; i++ ) {\n        // Only deal with non-null/undefined values\n        if ( (options = arguments[ i ]) != null ) {\n            // Extend the base object\n            for ( name in options ) {\n                src = target[ name ];\n                copy = options[ name ];\n\n                // Prevent never-ending loop\n                if ( target === copy ) {\n                    continue;\n                }\n\n                // Recurse if we're merging plain objects or arrays\n                if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n                    if ( copyIsArray ) {\n                        copyIsArray = false;\n                        clone = src && jQuery.isArray(src) ? src : [];\n\n                    } else {\n                        clone = src && jQuery.isPlainObject(src) ? src : {};\n                    }\n\n                    // Never move original objects, clone them\n                    target[ name ] = jQuery.extend( deep, clone, copy );\n\n                // Don't bring in undefined values\n                } else if ( copy !== undefined ) {\n                    target[ name ] = copy;\n                }\n            }\n        }\n    }\n\n    // Return the modified object\n    return target;\n};\n\njQuery.extend({\n    // Unique for each copy of jQuery on the page\n    // Non-digits removed to match rinlinejQuery\n    expando: \"jQuery\" + ( core_version + Math.random() ).replace( /\\D/g, \"\" ),\n\n    noConflict: function( deep ) {\n        if ( window.$ === jQuery ) {\n            window.$ = _$;\n        }\n\n        if ( deep && window.jQuery === jQuery ) {\n            window.jQuery = _jQuery;\n        }\n\n        return jQuery;\n    },\n\n    // Is the DOM ready to be used? Set to true once it occurs.\n    isReady: false,\n\n    // A counter to track how many items to wait for before\n    // the ready event fires. See #6781\n    readyWait: 1,\n\n    // Hold (or release) the ready event\n    holdReady: function( hold ) {\n        if ( hold ) {\n            jQuery.readyWait++;\n        } else {\n            jQuery.ready( true );\n        }\n    },\n\n    // Handle when the DOM is ready\n    ready: function( wait ) {\n\n        // Abort if there are pending holds or we're already ready\n        if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n            return;\n        }\n\n        // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n        if ( !document.body ) {\n            return setTimeout( jQuery.ready );\n        }\n\n        // Remember that the DOM is ready\n        jQuery.isReady = true;\n\n        // If a normal DOM Ready event fired, decrement, and wait if need be\n        if ( wait !== true && --jQuery.readyWait > 0 ) {\n            return;\n        }\n\n        // If there are functions bound, to execute\n        readyList.resolveWith( document, [ jQuery ] );\n\n        // Trigger any bound ready events\n        if ( jQuery.fn.trigger ) {\n            jQuery( document ).trigger(\"ready\").off(\"ready\");\n        }\n    },\n\n    // See test/unit/core.js for details concerning isFunction.\n    // Since version 1.3, DOM methods and functions like alert\n    // aren't supported. They return false on IE (#2968).\n    isFunction: function( obj ) {\n        return jQuery.type(obj) === \"function\";\n    },\n\n    isArray: Array.isArray || function( obj ) {\n        return jQuery.type(obj) === \"array\";\n    },\n\n    isWindow: function( obj ) {\n        /* jshint eqeqeq: false */\n        return obj != null && obj == obj.window;\n    },\n\n    isNumeric: function( obj ) {\n        return !isNaN( parseFloat(obj) ) && isFinite( obj );\n    },\n\n    type: function( obj ) {\n        if ( obj == null ) {\n            return String( obj );\n        }\n        return typeof obj === \"object\" || typeof obj === \"function\" ?\n            class2type[ core_toString.call(obj) ] || \"object\" :\n            typeof obj;\n    },\n\n    isPlainObject: function( obj ) {\n        var key;\n\n        // Must be an Object.\n        // Because of IE, we also have to check the presence of the constructor property.\n        // Make sure that DOM nodes and window objects don't pass through, as well\n        if ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n            return false;\n        }\n\n        try {\n            // Not own constructor property must be Object\n            if ( obj.constructor &&\n                !core_hasOwn.call(obj, \"constructor\") &&\n                !core_hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n                return false;\n            }\n        } catch ( e ) {\n            // IE8,9 Will throw exceptions on certain host objects #9897\n            return false;\n        }\n\n        // Support: IE<9\n        // Handle iteration over inherited properties before own properties.\n        if ( jQuery.support.ownLast ) {\n            for ( key in obj ) {\n                return core_hasOwn.call( obj, key );\n            }\n        }\n\n        // Own properties are enumerated firstly, so to speed up,\n        // if last one is own, then all properties are own.\n        for ( key in obj ) {}\n\n        return key === undefined || core_hasOwn.call( obj, key );\n    },\n\n    isEmptyObject: function( obj ) {\n        var name;\n        for ( name in obj ) {\n            return false;\n        }\n        return true;\n    },\n\n    error: function( msg ) {\n        throw new Error( msg );\n    },\n\n    // data: string of html\n    // context (optional): If specified, the fragment will be created in this context, defaults to document\n    // keepScripts (optional): If true, will include scripts passed in the html string\n    parseHTML: function( data, context, keepScripts ) {\n        if ( !data || typeof data !== \"string\" ) {\n            return null;\n        }\n        if ( typeof context === \"boolean\" ) {\n            keepScripts = context;\n            context = false;\n        }\n        context = context || document;\n\n        var parsed = rsingleTag.exec( data ),\n            scripts = !keepScripts && [];\n\n        // Single tag\n        if ( parsed ) {\n            return [ context.createElement( parsed[1] ) ];\n        }\n\n        parsed = jQuery.buildFragment( [ data ], context, scripts );\n        if ( scripts ) {\n            jQuery( scripts ).remove();\n        }\n        return jQuery.merge( [], parsed.childNodes );\n    },\n\n    parseJSON: function( data ) {\n        // Attempt to parse using the native JSON parser first\n        if ( window.JSON && window.JSON.parse ) {\n            return window.JSON.parse( data );\n        }\n\n        if ( data === null ) {\n            return data;\n        }\n\n        if ( typeof data === \"string\" ) {\n\n            // Make sure leading/trailing whitespace is removed (IE can't handle it)\n            data = jQuery.trim( data );\n\n            if ( data ) {\n                // Make sure the incoming data is actual JSON\n                // Logic borrowed from http://json.org/json2.js\n                if ( rvalidchars.test( data.replace( rvalidescape, \"@\" )\n                    .replace( rvalidtokens, \"]\" )\n                    .replace( rvalidbraces, \"\")) ) {\n\n                    return ( new Function( \"return \" + data ) )();\n                }\n            }\n        }\n\n        jQuery.error( \"Invalid JSON: \" + data );\n    },\n\n    // Cross-browser xml parsing\n    parseXML: function( data ) {\n        var xml, tmp;\n        if ( !data || typeof data !== \"string\" ) {\n            return null;\n        }\n        try {\n            if ( window.DOMParser ) { // Standard\n                tmp = new DOMParser();\n                xml = tmp.parseFromString( data , \"text/xml\" );\n            } else { // IE\n                xml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n                xml.async = \"false\";\n                xml.loadXML( data );\n            }\n        } catch( e ) {\n            xml = undefined;\n        }\n        if ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n            jQuery.error( \"Invalid XML: \" + data );\n        }\n        return xml;\n    },\n\n    noop: function() {},\n\n    // Evaluates a script in a global context\n    // Workarounds based on findings by Jim Driscoll\n    // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n    globalEval: function( data ) {\n        if ( data && jQuery.trim( data ) ) {\n            // We use execScript on Internet Explorer\n            // We use an anonymous function so that context is window\n            // rather than jQuery in Firefox\n            ( window.execScript || function( data ) {\n                window[ \"eval\" ].call( window, data );\n            } )( data );\n        }\n    },\n\n    // Convert dashed to camelCase; used by the css and data modules\n    // Microsoft forgot to hump their vendor prefix (#9572)\n    camelCase: function( string ) {\n        return string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n    },\n\n    nodeName: function( elem, name ) {\n        return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n    },\n\n    // args is for internal usage only\n    each: function( obj, callback, args ) {\n        var value,\n            i = 0,\n            length = obj.length,\n            isArray = isArraylike( obj );\n\n        if ( args ) {\n            if ( isArray ) {\n                for ( ; i < length; i++ ) {\n                    value = callback.apply( obj[ i ], args );\n\n                    if ( value === false ) {\n                        break;\n                    }\n                }\n            } else {\n                for ( i in obj ) {\n                    value = callback.apply( obj[ i ], args );\n\n                    if ( value === false ) {\n                        break;\n                    }\n                }\n            }\n\n        // A special, fast, case for the most common use of each\n        } else {\n            if ( isArray ) {\n                for ( ; i < length; i++ ) {\n                    value = callback.call( obj[ i ], i, obj[ i ] );\n\n                    if ( value === false ) {\n                        break;\n                    }\n                }\n            } else {\n                for ( i in obj ) {\n                    value = callback.call( obj[ i ], i, obj[ i ] );\n\n                    if ( value === false ) {\n                        break;\n                    }\n                }\n            }\n        }\n\n        return obj;\n    },\n\n    // Use native String.trim function wherever possible\n    trim: core_trim && !core_trim.call(\"\\uFEFF\\xA0\") ?\n        function( text ) {\n            return text == null ?\n                \"\" :\n                core_trim.call( text );\n        } :\n\n        // Otherwise use our own trimming functionality\n        function( text ) {\n            return text == null ?\n                \"\" :\n                ( text + \"\" ).replace( rtrim, \"\" );\n        },\n\n    // results is for internal usage only\n    makeArray: function( arr, results ) {\n        var ret = results || [];\n\n        if ( arr != null ) {\n            if ( isArraylike( Object(arr) ) ) {\n                jQuery.merge( ret,\n                    typeof arr === \"string\" ?\n                    [ arr ] : arr\n                );\n            } else {\n                core_push.call( ret, arr );\n            }\n        }\n\n        return ret;\n    },\n\n    inArray: function( elem, arr, i ) {\n        var len;\n\n        if ( arr ) {\n            if ( core_indexOf ) {\n                return core_indexOf.call( arr, elem, i );\n            }\n\n            len = arr.length;\n            i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n            for ( ; i < len; i++ ) {\n                // Skip accessing in sparse arrays\n                if ( i in arr && arr[ i ] === elem ) {\n                    return i;\n                }\n            }\n        }\n\n        return -1;\n    },\n\n    merge: function( first, second ) {\n        var l = second.length,\n            i = first.length,\n            j = 0;\n\n        if ( typeof l === \"number\" ) {\n            for ( ; j < l; j++ ) {\n                first[ i++ ] = second[ j ];\n            }\n        } else {\n            while ( second[j] !== undefined ) {\n                first[ i++ ] = second[ j++ ];\n            }\n        }\n\n        first.length = i;\n\n        return first;\n    },\n\n    grep: function( elems, callback, inv ) {\n        var retVal,\n            ret = [],\n            i = 0,\n            length = elems.length;\n        inv = !!inv;\n\n        // Go through the array, only saving the items\n        // that pass the validator function\n        for ( ; i < length; i++ ) {\n            retVal = !!callback( elems[ i ], i );\n            if ( inv !== retVal ) {\n                ret.push( elems[ i ] );\n            }\n        }\n\n        return ret;\n    },\n\n    // arg is for internal usage only\n    map: function( elems, callback, arg ) {\n        var value,\n            i = 0,\n            length = elems.length,\n            isArray = isArraylike( elems ),\n            ret = [];\n\n        // Go through the array, translating each of the items to their\n        if ( isArray ) {\n            for ( ; i < length; i++ ) {\n                value = callback( elems[ i ], i, arg );\n\n                if ( value != null ) {\n                    ret[ ret.length ] = value;\n                }\n            }\n\n        // Go through every key on the object,\n        } else {\n            for ( i in elems ) {\n                value = callback( elems[ i ], i, arg );\n\n                if ( value != null ) {\n                    ret[ ret.length ] = value;\n                }\n            }\n        }\n\n        // Flatten any nested arrays\n        return core_concat.apply( [], ret );\n    },\n\n    // A global GUID counter for objects\n    guid: 1,\n\n    // Bind a function to a context, optionally partially applying any\n    // arguments.\n    proxy: function( fn, context ) {\n        var args, proxy, tmp;\n\n        if ( typeof context === \"string\" ) {\n            tmp = fn[ context ];\n            context = fn;\n            fn = tmp;\n        }\n\n        // Quick check to determine if target is callable, in the spec\n        // this throws a TypeError, but we will just return undefined.\n        if ( !jQuery.isFunction( fn ) ) {\n            return undefined;\n        }\n\n        // Simulated bind\n        args = core_slice.call( arguments, 2 );\n        proxy = function() {\n            return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );\n        };\n\n        // Set the guid of unique handler to the same of original handler, so it can be removed\n        proxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n        return proxy;\n    },\n\n    // Multifunctional method to get and set values of a collection\n    // The value/s can optionally be executed if it's a function\n    access: function( elems, fn, key, value, chainable, emptyGet, raw ) {\n        var i = 0,\n            length = elems.length,\n            bulk = key == null;\n\n        // Sets many values\n        if ( jQuery.type( key ) === \"object\" ) {\n            chainable = true;\n            for ( i in key ) {\n                jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n            }\n\n        // Sets one value\n        } else if ( value !== undefined ) {\n            chainable = true;\n\n            if ( !jQuery.isFunction( value ) ) {\n                raw = true;\n            }\n\n            if ( bulk ) {\n                // Bulk operations run against the entire set\n                if ( raw ) {\n                    fn.call( elems, value );\n                    fn = null;\n\n                // ...except when executing function values\n                } else {\n                    bulk = fn;\n                    fn = function( elem, key, value ) {\n                        return bulk.call( jQuery( elem ), value );\n                    };\n                }\n            }\n\n            if ( fn ) {\n                for ( ; i < length; i++ ) {\n                    fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n                }\n            }\n        }\n\n        return chainable ?\n            elems :\n\n            // Gets\n            bulk ?\n                fn.call( elems ) :\n                length ? fn( elems[0], key ) : emptyGet;\n    },\n\n    now: function() {\n        return ( new Date() ).getTime();\n    },\n\n    // A method for quickly swapping in/out CSS properties to get correct calculations.\n    // Note: this method belongs to the css module but it's needed here for the support module.\n    // If support gets modularized, this method should be moved back to the css module.\n    swap: function( elem, options, callback, args ) {\n        var ret, name,\n            old = {};\n\n        // Remember the old values, and insert the new ones\n        for ( name in options ) {\n            old[ name ] = elem.style[ name ];\n            elem.style[ name ] = options[ name ];\n        }\n\n        ret = callback.apply( elem, args || [] );\n\n        // Revert the old values\n        for ( name in options ) {\n            elem.style[ name ] = old[ name ];\n        }\n\n        return ret;\n    }\n});\n\njQuery.ready.promise = function( obj ) {\n    if ( !readyList ) {\n\n        readyList = jQuery.Deferred();\n\n        // Catch cases where $(document).ready() is called after the browser event has already occurred.\n        // we once tried to use readyState \"interactive\" here, but it caused issues like the one\n        // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n        if ( document.readyState === \"complete\" ) {\n            // Handle it asynchronously to allow scripts the opportunity to delay ready\n            setTimeout( jQuery.ready );\n\n        // Standards-based browsers support DOMContentLoaded\n        } else if ( document.addEventListener ) {\n            // Use the handy event callback\n            document.addEventListener( \"DOMContentLoaded\", completed, false );\n\n            // A fallback to window.onload, that will always work\n            window.addEventListener( \"load\", completed, false );\n\n        // If IE event model is used\n        } else {\n            // Ensure firing before onload, maybe late but safe also for iframes\n            document.attachEvent( \"onreadystatechange\", completed );\n\n            // A fallback to window.onload, that will always work\n            window.attachEvent( \"onload\", completed );\n\n            // If IE and not a frame\n            // continually check to see if the document is ready\n            var top = false;\n\n            try {\n                top = window.frameElement == null && document.documentElement;\n            } catch(e) {}\n\n            if ( top && top.doScroll ) {\n                (function doScrollCheck() {\n                    if ( !jQuery.isReady ) {\n\n                        try {\n                            // Use the trick by Diego Perini\n                            // http://javascript.nwbox.com/IEContentLoaded/\n                            top.doScroll(\"left\");\n                        } catch(e) {\n                            return setTimeout( doScrollCheck, 50 );\n                        }\n\n                        // detach all dom ready events\n                        detach();\n\n                        // and execute any waiting functions\n                        jQuery.ready();\n                    }\n                })();\n            }\n        }\n    }\n    return readyList.promise( obj );\n};\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n    class2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n    var length = obj.length,\n        type = jQuery.type( obj );\n\n    if ( jQuery.isWindow( obj ) ) {\n        return false;\n    }\n\n    if ( obj.nodeType === 1 && length ) {\n        return true;\n    }\n\n    return type === \"array\" || type !== \"function\" &&\n        ( length === 0 ||\n        typeof length === \"number\" && length > 0 && ( length - 1 ) in obj );\n}\n\n// All jQuery objects should point back to these\nrootjQuery = jQuery(document);\n/*!\n * Sizzle CSS Selector Engine v1.10.2\n * http://sizzlejs.com/\n *\n * Copyright 2013 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2013-07-03\n */\n(function( window, undefined ) {\n\nvar i,\n    support,\n    cachedruns,\n    Expr,\n    getText,\n    isXML,\n    compile,\n    outermostContext,\n    sortInput,\n\n    // Local document vars\n    setDocument,\n    document,\n    docElem,\n    documentIsHTML,\n    rbuggyQSA,\n    rbuggyMatches,\n    matches,\n    contains,\n\n    // Instance-specific data\n    expando = \"sizzle\" + -(new Date()),\n    preferredDoc = window.document,\n    dirruns = 0,\n    done = 0,\n    classCache = createCache(),\n    tokenCache = createCache(),\n    compilerCache = createCache(),\n    hasDuplicate = false,\n    sortOrder = function( a, b ) {\n        if ( a === b ) {\n            hasDuplicate = true;\n            return 0;\n        }\n        return 0;\n    },\n\n    // General-purpose constants\n    strundefined = typeof undefined,\n    MAX_NEGATIVE = 1 << 31,\n\n    // Instance methods\n    hasOwn = ({}).hasOwnProperty,\n    arr = [],\n    pop = arr.pop,\n    push_native = arr.push,\n    push = arr.push,\n    slice = arr.slice,\n    // Use a stripped-down indexOf if we can't use a native one\n    indexOf = arr.indexOf || function( elem ) {\n        var i = 0,\n            len = this.length;\n        for ( ; i < len; i++ ) {\n            if ( this[i] === elem ) {\n                return i;\n            }\n        }\n        return -1;\n    },\n\n    booleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n    // Regular expressions\n\n    // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n    whitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n    // http://www.w3.org/TR/css3-syntax/#characters\n    characterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n    // Loosely modeled on CSS identifier characters\n    // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n    // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n    identifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n    // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors\n    attributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")\" + whitespace +\n        \"*(?:([*^$|!~]?=)\" + whitespace + \"*(?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|(\" + identifier + \")|)|)\" + whitespace + \"*\\\\]\",\n\n    // Prefer arguments quoted,\n    //   then not containing pseudos/brackets,\n    //   then attribute selectors/non-parenthetical expressions,\n    //   then anything else\n    // These preferences are here to reduce the number of selectors\n    //   needing tokenize in the PSEUDO preFilter\n    pseudos = \":(\" + characterEncoding + \")(?:\\\\(((['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes.replace( 3, 8 ) + \")*)|.*)\\\\)|)\",\n\n    // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n    rtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n    rcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n    rcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n    rsibling = new RegExp( whitespace + \"*[+~]\" ),\n    rattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n    rpseudo = new RegExp( pseudos ),\n    ridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n    matchExpr = {\n        \"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n        \"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n        \"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n        \"ATTR\": new RegExp( \"^\" + attributes ),\n        \"PSEUDO\": new RegExp( \"^\" + pseudos ),\n        \"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n            \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n            \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n        \"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n        // For use in libraries implementing .is()\n        // We use this for POS matching in `select`\n        \"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n            whitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n    },\n\n    rnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n    // Easily-parseable/retrievable ID or TAG or CLASS selectors\n    rquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n    rinputs = /^(?:input|select|textarea|button)$/i,\n    rheader = /^h\\d$/i,\n\n    rescape = /'|\\\\/g,\n\n    // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n    runescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n    funescape = function( _, escaped, escapedWhitespace ) {\n        var high = \"0x\" + escaped - 0x10000;\n        // NaN means non-codepoint\n        // Support: Firefox\n        // Workaround erroneous numeric interpretation of +\"0x\"\n        return high !== high || escapedWhitespace ?\n            escaped :\n            // BMP codepoint\n            high < 0 ?\n                String.fromCharCode( high + 0x10000 ) :\n                // Supplemental Plane codepoint (surrogate pair)\n                String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n    };\n\n// Optimize for push.apply( _, NodeList )\ntry {\n    push.apply(\n        (arr = slice.call( preferredDoc.childNodes )),\n        preferredDoc.childNodes\n    );\n    // Support: Android<4.0\n    // Detect silently failing push.apply\n    arr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n    push = { apply: arr.length ?\n\n        // Leverage slice if possible\n        function( target, els ) {\n            push_native.apply( target, slice.call(els) );\n        } :\n\n        // Support: IE<9\n        // Otherwise append directly\n        function( target, els ) {\n            var j = target.length,\n                i = 0;\n            // Can't trust NodeList.length\n            while ( (target[j++] = els[i++]) ) {}\n            target.length = j - 1;\n        }\n    };\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n    var match, elem, m, nodeType,\n        // QSA vars\n        i, groups, old, nid, newContext, newSelector;\n\n    if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n        setDocument( context );\n    }\n\n    context = context || document;\n    results = results || [];\n\n    if ( !selector || typeof selector !== \"string\" ) {\n        return results;\n    }\n\n    if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {\n        return [];\n    }\n\n    if ( documentIsHTML && !seed ) {\n\n        // Shortcuts\n        if ( (match = rquickExpr.exec( selector )) ) {\n            // Speed-up: Sizzle(\"#ID\")\n            if ( (m = match[1]) ) {\n                if ( nodeType === 9 ) {\n                    elem = context.getElementById( m );\n                    // Check parentNode to catch when Blackberry 4.6 returns\n                    // nodes that are no longer in the document #6963\n                    if ( elem && elem.parentNode ) {\n                        // Handle the case where IE, Opera, and Webkit return items\n                        // by name instead of ID\n                        if ( elem.id === m ) {\n                            results.push( elem );\n                            return results;\n                        }\n                    } else {\n                        return results;\n                    }\n                } else {\n                    // Context is not a document\n                    if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n                        contains( context, elem ) && elem.id === m ) {\n                        results.push( elem );\n                        return results;\n                    }\n                }\n\n            // Speed-up: Sizzle(\"TAG\")\n            } else if ( match[2] ) {\n                push.apply( results, context.getElementsByTagName( selector ) );\n                return results;\n\n            // Speed-up: Sizzle(\".CLASS\")\n            } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {\n                push.apply( results, context.getElementsByClassName( m ) );\n                return results;\n            }\n        }\n\n        // QSA path\n        if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n            nid = old = expando;\n            newContext = context;\n            newSelector = nodeType === 9 && selector;\n\n            // qSA works strangely on Element-rooted queries\n            // We can work around this by specifying an extra ID on the root\n            // and working up from there (Thanks to Andrew Dupont for the technique)\n            // IE 8 doesn't work on object elements\n            if ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n                groups = tokenize( selector );\n\n                if ( (old = context.getAttribute(\"id\")) ) {\n                    nid = old.replace( rescape, \"\\\\$&\" );\n                } else {\n                    context.setAttribute( \"id\", nid );\n                }\n                nid = \"[id='\" + nid + \"'] \";\n\n                i = groups.length;\n                while ( i-- ) {\n                    groups[i] = nid + toSelector( groups[i] );\n                }\n                newContext = rsibling.test( selector ) && context.parentNode || context;\n                newSelector = groups.join(\",\");\n            }\n\n            if ( newSelector ) {\n                try {\n                    push.apply( results,\n                        newContext.querySelectorAll( newSelector )\n                    );\n                    return results;\n                } catch(qsaError) {\n                } finally {\n                    if ( !old ) {\n                        context.removeAttribute(\"id\");\n                    }\n                }\n            }\n        }\n    }\n\n    // All others\n    return select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *  property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *  deleting the oldest entry\n */\nfunction createCache() {\n    var keys = [];\n\n    function cache( key, value ) {\n        // Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n        if ( keys.push( key += \" \" ) > Expr.cacheLength ) {\n            // Only keep the most recent entries\n            delete cache[ keys.shift() ];\n        }\n        return (cache[ key ] = value);\n    }\n    return cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n    fn[ expando ] = true;\n    return fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n    var div = document.createElement(\"div\");\n\n    try {\n        return !!fn( div );\n    } catch (e) {\n        return false;\n    } finally {\n        // Remove from its parent by default\n        if ( div.parentNode ) {\n            div.parentNode.removeChild( div );\n        }\n        // release memory in IE\n        div = null;\n    }\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n    var arr = attrs.split(\"|\"),\n        i = attrs.length;\n\n    while ( i-- ) {\n        Expr.attrHandle[ arr[i] ] = handler;\n    }\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n    var cur = b && a,\n        diff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n            ( ~b.sourceIndex || MAX_NEGATIVE ) -\n            ( ~a.sourceIndex || MAX_NEGATIVE );\n\n    // Use IE sourceIndex if available on both nodes\n    if ( diff ) {\n        return diff;\n    }\n\n    // Check if b follows a\n    if ( cur ) {\n        while ( (cur = cur.nextSibling) ) {\n            if ( cur === b ) {\n                return -1;\n            }\n        }\n    }\n\n    return a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n    return function( elem ) {\n        var name = elem.nodeName.toLowerCase();\n        return name === \"input\" && elem.type === type;\n    };\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n    return function( elem ) {\n        var name = elem.nodeName.toLowerCase();\n        return (name === \"input\" || name === \"button\") && elem.type === type;\n    };\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n    return markFunction(function( argument ) {\n        argument = +argument;\n        return markFunction(function( seed, matches ) {\n            var j,\n                matchIndexes = fn( [], seed.length, argument ),\n                i = matchIndexes.length;\n\n            // Match elements found at the specified indexes\n            while ( i-- ) {\n                if ( seed[ (j = matchIndexes[i]) ] ) {\n                    seed[j] = !(matches[j] = seed[j]);\n                }\n            }\n        });\n    });\n}\n\n/**\n * Detect xml\n * @param {Element|Object} elem An element or a document\n */\nisXML = Sizzle.isXML = function( elem ) {\n    // documentElement is verified for cases where it doesn't yet exist\n    // (such as loading iframes in IE - #4833)\n    var documentElement = elem && (elem.ownerDocument || elem).documentElement;\n    return documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n    var doc = node ? node.ownerDocument || node : preferredDoc,\n        parent = doc.defaultView;\n\n    // If no document and documentElement is available, return\n    if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n        return document;\n    }\n\n    // Set our document\n    document = doc;\n    docElem = doc.documentElement;\n\n    // Support tests\n    documentIsHTML = !isXML( doc );\n\n    // Support: IE>8\n    // If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n    // IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n    // IE6-8 do not support the defaultView property so parent will be undefined\n    if ( parent && parent.attachEvent && parent !== parent.top ) {\n        parent.attachEvent( \"onbeforeunload\", function() {\n            setDocument();\n        });\n    }\n\n    /* Attributes\n    ---------------------------------------------------------------------- */\n\n    // Support: IE<8\n    // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)\n    support.attributes = assert(function( div ) {\n        div.className = \"i\";\n        return !div.getAttribute(\"className\");\n    });\n\n    /* getElement(s)By*\n    ---------------------------------------------------------------------- */\n\n    // Check if getElementsByTagName(\"*\") returns only elements\n    support.getElementsByTagName = assert(function( div ) {\n        div.appendChild( doc.createComment(\"\") );\n        return !div.getElementsByTagName(\"*\").length;\n    });\n\n    // Check if getElementsByClassName can be trusted\n    support.getElementsByClassName = assert(function( div ) {\n        div.innerHTML = \"<div class='a'></div><div class='a i'></div>\";\n\n        // Support: Safari<4\n        // Catch class over-caching\n        div.firstChild.className = \"i\";\n        // Support: Opera<10\n        // Catch gEBCN failure to find non-leading classes\n        return div.getElementsByClassName(\"i\").length === 2;\n    });\n\n    // Support: IE<10\n    // Check if getElementById returns elements by name\n    // The broken getElementById methods don't pick up programatically-set names,\n    // so use a roundabout getElementsByName test\n    support.getById = assert(function( div ) {\n        docElem.appendChild( div ).id = expando;\n        return !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n    });\n\n    // ID find and filter\n    if ( support.getById ) {\n        Expr.find[\"ID\"] = function( id, context ) {\n            if ( typeof context.getElementById !== strundefined && documentIsHTML ) {\n                var m = context.getElementById( id );\n                // Check parentNode to catch when Blackberry 4.6 returns\n                // nodes that are no longer in the document #6963\n                return m && m.parentNode ? [m] : [];\n            }\n        };\n        Expr.filter[\"ID\"] = function( id ) {\n            var attrId = id.replace( runescape, funescape );\n            return function( elem ) {\n                return elem.getAttribute(\"id\") === attrId;\n            };\n        };\n    } else {\n        // Support: IE6/7\n        // getElementById is not reliable as a find shortcut\n        delete Expr.find[\"ID\"];\n\n        Expr.filter[\"ID\"] =  function( id ) {\n            var attrId = id.replace( runescape, funescape );\n            return function( elem ) {\n                var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode(\"id\");\n                return node && node.value === attrId;\n            };\n        };\n    }\n\n    // Tag\n    Expr.find[\"TAG\"] = support.getElementsByTagName ?\n        function( tag, context ) {\n            if ( typeof context.getElementsByTagName !== strundefined ) {\n                return context.getElementsByTagName( tag );\n            }\n        } :\n        function( tag, context ) {\n            var elem,\n                tmp = [],\n                i = 0,\n                results = context.getElementsByTagName( tag );\n\n            // Filter out possible comments\n            if ( tag === \"*\" ) {\n                while ( (elem = results[i++]) ) {\n                    if ( elem.nodeType === 1 ) {\n                        tmp.push( elem );\n                    }\n                }\n\n                return tmp;\n            }\n            return results;\n        };\n\n    // Class\n    Expr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n        if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {\n            return context.getElementsByClassName( className );\n        }\n    };\n\n    /* QSA/matchesSelector\n    ---------------------------------------------------------------------- */\n\n    // QSA and matchesSelector support\n\n    // matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n    rbuggyMatches = [];\n\n    // qSa(:focus) reports false when true (Chrome 21)\n    // We allow this because of a bug in IE8/9 that throws an error\n    // whenever `document.activeElement` is accessed on an iframe\n    // So, we allow :focus to pass through QSA all the time to avoid the IE error\n    // See http://bugs.jquery.com/ticket/13378\n    rbuggyQSA = [];\n\n    if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n        // Build QSA regex\n        // Regex strategy adopted from Diego Perini\n        assert(function( div ) {\n            // Select is set to empty string on purpose\n            // This is to test IE's treatment of not explicitly\n            // setting a boolean content attribute,\n            // since its presence should be enough\n            // http://bugs.jquery.com/ticket/12359\n            div.innerHTML = \"<select><option selected=''></option></select>\";\n\n            // Support: IE8\n            // Boolean attributes and \"value\" are not treated correctly\n            if ( !div.querySelectorAll(\"[selected]\").length ) {\n                rbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n            }\n\n            // Webkit/Opera - :checked should return selected option elements\n            // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n            // IE8 throws error here and will not see later tests\n            if ( !div.querySelectorAll(\":checked\").length ) {\n                rbuggyQSA.push(\":checked\");\n            }\n        });\n\n        assert(function( div ) {\n\n            // Support: Opera 10-12/IE8\n            // ^= $= *= and empty values\n            // Should not select anything\n            // Support: Windows 8 Native Apps\n            // The type attribute is restricted during .innerHTML assignment\n            var input = doc.createElement(\"input\");\n            input.setAttribute( \"type\", \"hidden\" );\n            div.appendChild( input ).setAttribute( \"t\", \"\" );\n\n            if ( div.querySelectorAll(\"[t^='']\").length ) {\n                rbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n            }\n\n            // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n            // IE8 throws error here and will not see later tests\n            if ( !div.querySelectorAll(\":enabled\").length ) {\n                rbuggyQSA.push( \":enabled\", \":disabled\" );\n            }\n\n            // Opera 10-11 does not throw on post-comma invalid pseudos\n            div.querySelectorAll(\"*,:x\");\n            rbuggyQSA.push(\",.*:\");\n        });\n    }\n\n    if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||\n        docElem.mozMatchesSelector ||\n        docElem.oMatchesSelector ||\n        docElem.msMatchesSelector) )) ) {\n\n        assert(function( div ) {\n            // Check to see if it's possible to do matchesSelector\n            // on a disconnected node (IE 9)\n            support.disconnectedMatch = matches.call( div, \"div\" );\n\n            // This should fail with an exception\n            // Gecko does not error, returns false instead\n            matches.call( div, \"[s!='']:x\" );\n            rbuggyMatches.push( \"!=\", pseudos );\n        });\n    }\n\n    rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n    rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n    /* Contains\n    ---------------------------------------------------------------------- */\n\n    // Element contains another\n    // Purposefully does not implement inclusive descendent\n    // As in, an element does not contain itself\n    contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?\n        function( a, b ) {\n            var adown = a.nodeType === 9 ? a.documentElement : a,\n                bup = b && b.parentNode;\n            return a === bup || !!( bup && bup.nodeType === 1 && (\n                adown.contains ?\n                    adown.contains( bup ) :\n                    a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n            ));\n        } :\n        function( a, b ) {\n            if ( b ) {\n                while ( (b = b.parentNode) ) {\n                    if ( b === a ) {\n                        return true;\n                    }\n                }\n            }\n            return false;\n        };\n\n    /* Sorting\n    ---------------------------------------------------------------------- */\n\n    // Document order sorting\n    sortOrder = docElem.compareDocumentPosition ?\n    function( a, b ) {\n\n        // Flag for duplicate removal\n        if ( a === b ) {\n            hasDuplicate = true;\n            return 0;\n        }\n\n        var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );\n\n        if ( compare ) {\n            // Disconnected nodes\n            if ( compare & 1 ||\n                (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n                // Choose the first element that is related to our preferred document\n                if ( a === doc || contains(preferredDoc, a) ) {\n                    return -1;\n                }\n                if ( b === doc || contains(preferredDoc, b) ) {\n                    return 1;\n                }\n\n                // Maintain original order\n                return sortInput ?\n                    ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n                    0;\n            }\n\n            return compare & 4 ? -1 : 1;\n        }\n\n        // Not directly comparable, sort on existence of method\n        return a.compareDocumentPosition ? -1 : 1;\n    } :\n    function( a, b ) {\n        var cur,\n            i = 0,\n            aup = a.parentNode,\n            bup = b.parentNode,\n            ap = [ a ],\n            bp = [ b ];\n\n        // Exit early if the nodes are identical\n        if ( a === b ) {\n            hasDuplicate = true;\n            return 0;\n\n        // Parentless nodes are either documents or disconnected\n        } else if ( !aup || !bup ) {\n            return a === doc ? -1 :\n                b === doc ? 1 :\n                aup ? -1 :\n                bup ? 1 :\n                sortInput ?\n                ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n                0;\n\n        // If the nodes are siblings, we can do a quick check\n        } else if ( aup === bup ) {\n            return siblingCheck( a, b );\n        }\n\n        // Otherwise we need full lists of their ancestors for comparison\n        cur = a;\n        while ( (cur = cur.parentNode) ) {\n            ap.unshift( cur );\n        }\n        cur = b;\n        while ( (cur = cur.parentNode) ) {\n            bp.unshift( cur );\n        }\n\n        // Walk down the tree looking for a discrepancy\n        while ( ap[i] === bp[i] ) {\n            i++;\n        }\n\n        return i ?\n            // Do a sibling check if the nodes have a common ancestor\n            siblingCheck( ap[i], bp[i] ) :\n\n            // Otherwise nodes in our document sort first\n            ap[i] === preferredDoc ? -1 :\n            bp[i] === preferredDoc ? 1 :\n            0;\n    };\n\n    return doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n    return Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n    // Set document vars if needed\n    if ( ( elem.ownerDocument || elem ) !== document ) {\n        setDocument( elem );\n    }\n\n    // Make sure that attribute selectors are quoted\n    expr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n    if ( support.matchesSelector && documentIsHTML &&\n        ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n        ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n        try {\n            var ret = matches.call( elem, expr );\n\n            // IE 9's matchesSelector returns false on disconnected nodes\n            if ( ret || support.disconnectedMatch ||\n                    // As well, disconnected nodes are said to be in a document\n                    // fragment in IE 9\n                    elem.document && elem.document.nodeType !== 11 ) {\n                return ret;\n            }\n        } catch(e) {}\n    }\n\n    return Sizzle( expr, document, null, [elem] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n    // Set document vars if needed\n    if ( ( context.ownerDocument || context ) !== document ) {\n        setDocument( context );\n    }\n    return contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n    // Set document vars if needed\n    if ( ( elem.ownerDocument || elem ) !== document ) {\n        setDocument( elem );\n    }\n\n    var fn = Expr.attrHandle[ name.toLowerCase() ],\n        // Don't get fooled by Object.prototype properties (jQuery #13807)\n        val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n            fn( elem, name, !documentIsHTML ) :\n            undefined;\n\n    return val === undefined ?\n        support.attributes || !documentIsHTML ?\n            elem.getAttribute( name ) :\n            (val = elem.getAttributeNode(name)) && val.specified ?\n                val.value :\n                null :\n        val;\n};\n\nSizzle.error = function( msg ) {\n    throw new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n    var elem,\n        duplicates = [],\n        j = 0,\n        i = 0;\n\n    // Unless we *know* we can detect duplicates, assume their presence\n    hasDuplicate = !support.detectDuplicates;\n    sortInput = !support.sortStable && results.slice( 0 );\n    results.sort( sortOrder );\n\n    if ( hasDuplicate ) {\n        while ( (elem = results[i++]) ) {\n            if ( elem === results[ i ] ) {\n                j = duplicates.push( i );\n            }\n        }\n        while ( j-- ) {\n            results.splice( duplicates[ j ], 1 );\n        }\n    }\n\n    return results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n    var node,\n        ret = \"\",\n        i = 0,\n        nodeType = elem.nodeType;\n\n    if ( !nodeType ) {\n        // If no nodeType, this is expected to be an array\n        for ( ; (node = elem[i]); i++ ) {\n            // Do not traverse comment nodes\n            ret += getText( node );\n        }\n    } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n        // Use textContent for elements\n        // innerText usage removed for consistency of new lines (see #11153)\n        if ( typeof elem.textContent === \"string\" ) {\n            return elem.textContent;\n        } else {\n            // Traverse its children\n            for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n                ret += getText( elem );\n            }\n        }\n    } else if ( nodeType === 3 || nodeType === 4 ) {\n        return elem.nodeValue;\n    }\n    // Do not include comment or processing instruction nodes\n\n    return ret;\n};\n\nExpr = Sizzle.selectors = {\n\n    // Can be adjusted by the user\n    cacheLength: 50,\n\n    createPseudo: markFunction,\n\n    match: matchExpr,\n\n    attrHandle: {},\n\n    find: {},\n\n    relative: {\n        \">\": { dir: \"parentNode\", first: true },\n        \" \": { dir: \"parentNode\" },\n        \"+\": { dir: \"previousSibling\", first: true },\n        \"~\": { dir: \"previousSibling\" }\n    },\n\n    preFilter: {\n        \"ATTR\": function( match ) {\n            match[1] = match[1].replace( runescape, funescape );\n\n            // Move the given value to match[3] whether quoted or unquoted\n            match[3] = ( match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n            if ( match[2] === \"~=\" ) {\n                match[3] = \" \" + match[3] + \" \";\n            }\n\n            return match.slice( 0, 4 );\n        },\n\n        \"CHILD\": function( match ) {\n            /* matches from matchExpr[\"CHILD\"]\n                1 type (only|nth|...)\n                2 what (child|of-type)\n                3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n                4 xn-component of xn+y argument ([+-]?\\d*n|)\n                5 sign of xn-component\n                6 x of xn-component\n                7 sign of y-component\n                8 y of y-component\n            */\n            match[1] = match[1].toLowerCase();\n\n            if ( match[1].slice( 0, 3 ) === \"nth\" ) {\n                // nth-* requires argument\n                if ( !match[3] ) {\n                    Sizzle.error( match[0] );\n                }\n\n                // numeric x and y parameters for Expr.filter.CHILD\n                // remember that false/true cast respectively to 0/1\n                match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n                match[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n            // other types prohibit arguments\n            } else if ( match[3] ) {\n                Sizzle.error( match[0] );\n            }\n\n            return match;\n        },\n\n        \"PSEUDO\": function( match ) {\n            var excess,\n                unquoted = !match[5] && match[2];\n\n            if ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n                return null;\n            }\n\n            // Accept quoted arguments as-is\n            if ( match[3] && match[4] !== undefined ) {\n                match[2] = match[4];\n\n            // Strip excess characters from unquoted arguments\n            } else if ( unquoted && rpseudo.test( unquoted ) &&\n                // Get excess from tokenize (recursively)\n                (excess = tokenize( unquoted, true )) &&\n                // advance to the next closing parenthesis\n                (excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n                // excess is a negative index\n                match[0] = match[0].slice( 0, excess );\n                match[2] = unquoted.slice( 0, excess );\n            }\n\n            // Return only captures needed by the pseudo filter method (type and argument)\n            return match.slice( 0, 3 );\n        }\n    },\n\n    filter: {\n\n        \"TAG\": function( nodeNameSelector ) {\n            var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n            return nodeNameSelector === \"*\" ?\n                function() { return true; } :\n                function( elem ) {\n                    return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n                };\n        },\n\n        \"CLASS\": function( className ) {\n            var pattern = classCache[ className + \" \" ];\n\n            return pattern ||\n                (pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n                classCache( className, function( elem ) {\n                    return pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute(\"class\") || \"\" );\n                });\n        },\n\n        \"ATTR\": function( name, operator, check ) {\n            return function( elem ) {\n                var result = Sizzle.attr( elem, name );\n\n                if ( result == null ) {\n                    return operator === \"!=\";\n                }\n                if ( !operator ) {\n                    return true;\n                }\n\n                result += \"\";\n\n                return operator === \"=\" ? result === check :\n                    operator === \"!=\" ? result !== check :\n                    operator === \"^=\" ? check && result.indexOf( check ) === 0 :\n                    operator === \"*=\" ? check && result.indexOf( check ) > -1 :\n                    operator === \"$=\" ? check && result.slice( -check.length ) === check :\n                    operator === \"~=\" ? ( \" \" + result + \" \" ).indexOf( check ) > -1 :\n                    operator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n                    false;\n            };\n        },\n\n        \"CHILD\": function( type, what, argument, first, last ) {\n            var simple = type.slice( 0, 3 ) !== \"nth\",\n                forward = type.slice( -4 ) !== \"last\",\n                ofType = what === \"of-type\";\n\n            return first === 1 && last === 0 ?\n\n                // Shortcut for :nth-*(n)\n                function( elem ) {\n                    return !!elem.parentNode;\n                } :\n\n                function( elem, context, xml ) {\n                    var cache, outerCache, node, diff, nodeIndex, start,\n                        dir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n                        parent = elem.parentNode,\n                        name = ofType && elem.nodeName.toLowerCase(),\n                        useCache = !xml && !ofType;\n\n                    if ( parent ) {\n\n                        // :(first|last|only)-(child|of-type)\n                        if ( simple ) {\n                            while ( dir ) {\n                                node = elem;\n                                while ( (node = node[ dir ]) ) {\n                                    if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n                                        return false;\n                                    }\n                                }\n                                // Reverse direction for :only-* (if we haven't yet done so)\n                                start = dir = type === \"only\" && !start && \"nextSibling\";\n                            }\n                            return true;\n                        }\n\n                        start = [ forward ? parent.firstChild : parent.lastChild ];\n\n                        // non-xml :nth-child(...) stores cache data on `parent`\n                        if ( forward && useCache ) {\n                            // Seek `elem` from a previously-cached index\n                            outerCache = parent[ expando ] || (parent[ expando ] = {});\n                            cache = outerCache[ type ] || [];\n                            nodeIndex = cache[0] === dirruns && cache[1];\n                            diff = cache[0] === dirruns && cache[2];\n                            node = nodeIndex && parent.childNodes[ nodeIndex ];\n\n                            while ( (node = ++nodeIndex && node && node[ dir ] ||\n\n                                // Fallback to seeking `elem` from the start\n                                (diff = nodeIndex = 0) || start.pop()) ) {\n\n                                // When found, cache indexes on `parent` and break\n                                if ( node.nodeType === 1 && ++diff && node === elem ) {\n                                    outerCache[ type ] = [ dirruns, nodeIndex, diff ];\n                                    break;\n                                }\n                            }\n\n                        // Use previously-cached element index if available\n                        } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n                            diff = cache[1];\n\n                        // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n                        } else {\n                            // Use the same loop as above to seek `elem` from the start\n                            while ( (node = ++nodeIndex && node && node[ dir ] ||\n                                (diff = nodeIndex = 0) || start.pop()) ) {\n\n                                if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n                                    // Cache the index of each encountered element\n                                    if ( useCache ) {\n                                        (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n                                    }\n\n                                    if ( node === elem ) {\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n\n                        // Incorporate the offset, then check against cycle size\n                        diff -= last;\n                        return diff === first || ( diff % first === 0 && diff / first >= 0 );\n                    }\n                };\n        },\n\n        \"PSEUDO\": function( pseudo, argument ) {\n            // pseudo-class names are case-insensitive\n            // http://www.w3.org/TR/selectors/#pseudo-classes\n            // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n            // Remember that setFilters inherits from pseudos\n            var args,\n                fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n                    Sizzle.error( \"unsupported pseudo: \" + pseudo );\n\n            // The user may use createPseudo to indicate that\n            // arguments are needed to create the filter function\n            // just as Sizzle does\n            if ( fn[ expando ] ) {\n                return fn( argument );\n            }\n\n            // But maintain support for old signatures\n            if ( fn.length > 1 ) {\n                args = [ pseudo, pseudo, \"\", argument ];\n                return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n                    markFunction(function( seed, matches ) {\n                        var idx,\n                            matched = fn( seed, argument ),\n                            i = matched.length;\n                        while ( i-- ) {\n                            idx = indexOf.call( seed, matched[i] );\n                            seed[ idx ] = !( matches[ idx ] = matched[i] );\n                        }\n                    }) :\n                    function( elem ) {\n                        return fn( elem, 0, args );\n                    };\n            }\n\n            return fn;\n        }\n    },\n\n    pseudos: {\n        // Potentially complex pseudos\n        \"not\": markFunction(function( selector ) {\n            // Trim the selector passed to compile\n            // to avoid treating leading and trailing\n            // spaces as combinators\n            var input = [],\n                results = [],\n                matcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n            return matcher[ expando ] ?\n                markFunction(function( seed, matches, context, xml ) {\n                    var elem,\n                        unmatched = matcher( seed, null, xml, [] ),\n                        i = seed.length;\n\n                    // Match elements unmatched by `matcher`\n                    while ( i-- ) {\n                        if ( (elem = unmatched[i]) ) {\n                            seed[i] = !(matches[i] = elem);\n                        }\n                    }\n                }) :\n                function( elem, context, xml ) {\n                    input[0] = elem;\n                    matcher( input, null, xml, results );\n                    return !results.pop();\n                };\n        }),\n\n        \"has\": markFunction(function( selector ) {\n            return function( elem ) {\n                return Sizzle( selector, elem ).length > 0;\n            };\n        }),\n\n        \"contains\": markFunction(function( text ) {\n            return function( elem ) {\n                return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n            };\n        }),\n\n        // \"Whether an element is represented by a :lang() selector\n        // is based solely on the element's language value\n        // being equal to the identifier C,\n        // or beginning with the identifier C immediately followed by \"-\".\n        // The matching of C against the element's language value is performed case-insensitively.\n        // The identifier C does not have to be a valid language name.\"\n        // http://www.w3.org/TR/selectors/#lang-pseudo\n        \"lang\": markFunction( function( lang ) {\n            // lang value must be a valid identifier\n            if ( !ridentifier.test(lang || \"\") ) {\n                Sizzle.error( \"unsupported lang: \" + lang );\n            }\n            lang = lang.replace( runescape, funescape ).toLowerCase();\n            return function( elem ) {\n                var elemLang;\n                do {\n                    if ( (elemLang = documentIsHTML ?\n                        elem.lang :\n                        elem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n                        elemLang = elemLang.toLowerCase();\n                        return elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n                    }\n                } while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n                return false;\n            };\n        }),\n\n        // Miscellaneous\n        \"target\": function( elem ) {\n            var hash = window.location && window.location.hash;\n            return hash && hash.slice( 1 ) === elem.id;\n        },\n\n        \"root\": function( elem ) {\n            return elem === docElem;\n        },\n\n        \"focus\": function( elem ) {\n            return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n        },\n\n        // Boolean properties\n        \"enabled\": function( elem ) {\n            return elem.disabled === false;\n        },\n\n        \"disabled\": function( elem ) {\n            return elem.disabled === true;\n        },\n\n        \"checked\": function( elem ) {\n            // In CSS3, :checked should return both checked and selected elements\n            // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n            var nodeName = elem.nodeName.toLowerCase();\n            return (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n        },\n\n        \"selected\": function( elem ) {\n            // Accessing this property makes selected-by-default\n            // options in Safari work properly\n            if ( elem.parentNode ) {\n                elem.parentNode.selectedIndex;\n            }\n\n            return elem.selected === true;\n        },\n\n        // Contents\n        \"empty\": function( elem ) {\n            // http://www.w3.org/TR/selectors/#empty-pseudo\n            // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),\n            //   not comment, processing instructions, or others\n            // Thanks to Diego Perini for the nodeName shortcut\n            //   Greater than \"@\" means alpha characters (specifically not starting with \"#\" or \"?\")\n            for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n                if ( elem.nodeName > \"@\" || elem.nodeType === 3 || elem.nodeType === 4 ) {\n                    return false;\n                }\n            }\n            return true;\n        },\n\n        \"parent\": function( elem ) {\n            return !Expr.pseudos[\"empty\"]( elem );\n        },\n\n        // Element/input types\n        \"header\": function( elem ) {\n            return rheader.test( elem.nodeName );\n        },\n\n        \"input\": function( elem ) {\n            return rinputs.test( elem.nodeName );\n        },\n\n        \"button\": function( elem ) {\n            var name = elem.nodeName.toLowerCase();\n            return name === \"input\" && elem.type === \"button\" || name === \"button\";\n        },\n\n        \"text\": function( elem ) {\n            var attr;\n            // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)\n            // use getAttribute instead to test this case\n            return elem.nodeName.toLowerCase() === \"input\" &&\n                elem.type === \"text\" &&\n                ( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === elem.type );\n        },\n\n        // Position-in-collection\n        \"first\": createPositionalPseudo(function() {\n            return [ 0 ];\n        }),\n\n        \"last\": createPositionalPseudo(function( matchIndexes, length ) {\n            return [ length - 1 ];\n        }),\n\n        \"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n            return [ argument < 0 ? argument + length : argument ];\n        }),\n\n        \"even\": createPositionalPseudo(function( matchIndexes, length ) {\n            var i = 0;\n            for ( ; i < length; i += 2 ) {\n                matchIndexes.push( i );\n            }\n            return matchIndexes;\n        }),\n\n        \"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n            var i = 1;\n            for ( ; i < length; i += 2 ) {\n                matchIndexes.push( i );\n            }\n            return matchIndexes;\n        }),\n\n        \"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n            var i = argument < 0 ? argument + length : argument;\n            for ( ; --i >= 0; ) {\n                matchIndexes.push( i );\n            }\n            return matchIndexes;\n        }),\n\n        \"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n            var i = argument < 0 ? argument + length : argument;\n            for ( ; ++i < length; ) {\n                matchIndexes.push( i );\n            }\n            return matchIndexes;\n        })\n    }\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n    Expr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n    Expr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\nfunction tokenize( selector, parseOnly ) {\n    var matched, match, tokens, type,\n        soFar, groups, preFilters,\n        cached = tokenCache[ selector + \" \" ];\n\n    if ( cached ) {\n        return parseOnly ? 0 : cached.slice( 0 );\n    }\n\n    soFar = selector;\n    groups = [];\n    preFilters = Expr.preFilter;\n\n    while ( soFar ) {\n\n        // Comma and first run\n        if ( !matched || (match = rcomma.exec( soFar )) ) {\n            if ( match ) {\n                // Don't consume trailing commas as valid\n                soFar = soFar.slice( match[0].length ) || soFar;\n            }\n            groups.push( tokens = [] );\n        }\n\n        matched = false;\n\n        // Combinators\n        if ( (match = rcombinators.exec( soFar )) ) {\n            matched = match.shift();\n            tokens.push({\n                value: matched,\n                // Cast descendant combinators to space\n                type: match[0].replace( rtrim, \" \" )\n            });\n            soFar = soFar.slice( matched.length );\n        }\n\n        // Filters\n        for ( type in Expr.filter ) {\n            if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n                (match = preFilters[ type ]( match ))) ) {\n                matched = match.shift();\n                tokens.push({\n                    value: matched,\n                    type: type,\n                    matches: match\n                });\n                soFar = soFar.slice( matched.length );\n            }\n        }\n\n        if ( !matched ) {\n            break;\n        }\n    }\n\n    // Return the length of the invalid excess\n    // if we're just parsing\n    // Otherwise, throw an error or return tokens\n    return parseOnly ?\n        soFar.length :\n        soFar ?\n            Sizzle.error( selector ) :\n            // Cache the tokens\n            tokenCache( selector, groups ).slice( 0 );\n}\n\nfunction toSelector( tokens ) {\n    var i = 0,\n        len = tokens.length,\n        selector = \"\";\n    for ( ; i < len; i++ ) {\n        selector += tokens[i].value;\n    }\n    return selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n    var dir = combinator.dir,\n        checkNonElements = base && dir === \"parentNode\",\n        doneName = done++;\n\n    return combinator.first ?\n        // Check against closest ancestor/preceding element\n        function( elem, context, xml ) {\n            while ( (elem = elem[ dir ]) ) {\n                if ( elem.nodeType === 1 || checkNonElements ) {\n                    return matcher( elem, context, xml );\n                }\n            }\n        } :\n\n        // Check against all ancestor/preceding elements\n        function( elem, context, xml ) {\n            var data, cache, outerCache,\n                dirkey = dirruns + \" \" + doneName;\n\n            // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n            if ( xml ) {\n                while ( (elem = elem[ dir ]) ) {\n                    if ( elem.nodeType === 1 || checkNonElements ) {\n                        if ( matcher( elem, context, xml ) ) {\n                            return true;\n                        }\n                    }\n                }\n            } else {\n                while ( (elem = elem[ dir ]) ) {\n                    if ( elem.nodeType === 1 || checkNonElements ) {\n                        outerCache = elem[ expando ] || (elem[ expando ] = {});\n                        if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {\n                            if ( (data = cache[1]) === true || data === cachedruns ) {\n                                return data === true;\n                            }\n                        } else {\n                            cache = outerCache[ dir ] = [ dirkey ];\n                            cache[1] = matcher( elem, context, xml ) || cachedruns;\n                            if ( cache[1] === true ) {\n                                return true;\n                            }\n                        }\n                    }\n                }\n            }\n        };\n}\n\nfunction elementMatcher( matchers ) {\n    return matchers.length > 1 ?\n        function( elem, context, xml ) {\n            var i = matchers.length;\n            while ( i-- ) {\n                if ( !matchers[i]( elem, context, xml ) ) {\n                    return false;\n                }\n            }\n            return true;\n        } :\n        matchers[0];\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n    var elem,\n        newUnmatched = [],\n        i = 0,\n        len = unmatched.length,\n        mapped = map != null;\n\n    for ( ; i < len; i++ ) {\n        if ( (elem = unmatched[i]) ) {\n            if ( !filter || filter( elem, context, xml ) ) {\n                newUnmatched.push( elem );\n                if ( mapped ) {\n                    map.push( i );\n                }\n            }\n        }\n    }\n\n    return newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n    if ( postFilter && !postFilter[ expando ] ) {\n        postFilter = setMatcher( postFilter );\n    }\n    if ( postFinder && !postFinder[ expando ] ) {\n        postFinder = setMatcher( postFinder, postSelector );\n    }\n    return markFunction(function( seed, results, context, xml ) {\n        var temp, i, elem,\n            preMap = [],\n            postMap = [],\n            preexisting = results.length,\n\n            // Get initial elements from seed or context\n            elems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n            // Prefilter to get matcher input, preserving a map for seed-results synchronization\n            matcherIn = preFilter && ( seed || !selector ) ?\n                condense( elems, preMap, preFilter, context, xml ) :\n                elems,\n\n            matcherOut = matcher ?\n                // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n                postFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n                    // ...intermediate processing is necessary\n                    [] :\n\n                    // ...otherwise use results directly\n                    results :\n                matcherIn;\n\n        // Find primary matches\n        if ( matcher ) {\n            matcher( matcherIn, matcherOut, context, xml );\n        }\n\n        // Apply postFilter\n        if ( postFilter ) {\n            temp = condense( matcherOut, postMap );\n            postFilter( temp, [], context, xml );\n\n            // Un-match failing elements by moving them back to matcherIn\n            i = temp.length;\n            while ( i-- ) {\n                if ( (elem = temp[i]) ) {\n                    matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n                }\n            }\n        }\n\n        if ( seed ) {\n            if ( postFinder || preFilter ) {\n                if ( postFinder ) {\n                    // Get the final matcherOut by condensing this intermediate into postFinder contexts\n                    temp = [];\n                    i = matcherOut.length;\n                    while ( i-- ) {\n                        if ( (elem = matcherOut[i]) ) {\n                            // Restore matcherIn since elem is not yet a final match\n                            temp.push( (matcherIn[i] = elem) );\n                        }\n                    }\n                    postFinder( null, (matcherOut = []), temp, xml );\n                }\n\n                // Move matched elements from seed to results to keep them synchronized\n                i = matcherOut.length;\n                while ( i-- ) {\n                    if ( (elem = matcherOut[i]) &&\n                        (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\n\n                        seed[temp] = !(results[temp] = elem);\n                    }\n                }\n            }\n\n        // Add elements to results, through postFinder if defined\n        } else {\n            matcherOut = condense(\n                matcherOut === results ?\n                    matcherOut.splice( preexisting, matcherOut.length ) :\n                    matcherOut\n            );\n            if ( postFinder ) {\n                postFinder( null, results, matcherOut, xml );\n            } else {\n                push.apply( results, matcherOut );\n            }\n        }\n    });\n}\n\nfunction matcherFromTokens( tokens ) {\n    var checkContext, matcher, j,\n        len = tokens.length,\n        leadingRelative = Expr.relative[ tokens[0].type ],\n        implicitRelative = leadingRelative || Expr.relative[\" \"],\n        i = leadingRelative ? 1 : 0,\n\n        // The foundational matcher ensures that elements are reachable from top-level context(s)\n        matchContext = addCombinator( function( elem ) {\n            return elem === checkContext;\n        }, implicitRelative, true ),\n        matchAnyContext = addCombinator( function( elem ) {\n            return indexOf.call( checkContext, elem ) > -1;\n        }, implicitRelative, true ),\n        matchers = [ function( elem, context, xml ) {\n            return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n                (checkContext = context).nodeType ?\n                    matchContext( elem, context, xml ) :\n                    matchAnyContext( elem, context, xml ) );\n        } ];\n\n    for ( ; i < len; i++ ) {\n        if ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n            matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n        } else {\n            matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n            // Return special upon seeing a positional matcher\n            if ( matcher[ expando ] ) {\n                // Find the next relative operator (if any) for proper handling\n                j = ++i;\n                for ( ; j < len; j++ ) {\n                    if ( Expr.relative[ tokens[j].type ] ) {\n                        break;\n                    }\n                }\n                return setMatcher(\n                    i > 1 && elementMatcher( matchers ),\n                    i > 1 && toSelector(\n                        // If the preceding token was a descendant combinator, insert an implicit any-element `*`\n                        tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n                    ).replace( rtrim, \"$1\" ),\n                    matcher,\n                    i < j && matcherFromTokens( tokens.slice( i, j ) ),\n                    j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n                    j < len && toSelector( tokens )\n                );\n            }\n            matchers.push( matcher );\n        }\n    }\n\n    return elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n    // A counter to specify which element is currently being matched\n    var matcherCachedRuns = 0,\n        bySet = setMatchers.length > 0,\n        byElement = elementMatchers.length > 0,\n        superMatcher = function( seed, context, xml, results, expandContext ) {\n            var elem, j, matcher,\n                setMatched = [],\n                matchedCount = 0,\n                i = \"0\",\n                unmatched = seed && [],\n                outermost = expandContext != null,\n                contextBackup = outermostContext,\n                // We must always have either seed elements or context\n                elems = seed || byElement && Expr.find[\"TAG\"]( \"*\", expandContext && context.parentNode || context ),\n                // Use integer dirruns iff this is the outermost matcher\n                dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);\n\n            if ( outermost ) {\n                outermostContext = context !== document && context;\n                cachedruns = matcherCachedRuns;\n            }\n\n            // Add elements passing elementMatchers directly to results\n            // Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n            for ( ; (elem = elems[i]) != null; i++ ) {\n                if ( byElement && elem ) {\n                    j = 0;\n                    while ( (matcher = elementMatchers[j++]) ) {\n                        if ( matcher( elem, context, xml ) ) {\n                            results.push( elem );\n                            break;\n                        }\n                    }\n                    if ( outermost ) {\n                        dirruns = dirrunsUnique;\n                        cachedruns = ++matcherCachedRuns;\n                    }\n                }\n\n                // Track unmatched elements for set filters\n                if ( bySet ) {\n                    // They will have gone through all possible matchers\n                    if ( (elem = !matcher && elem) ) {\n                        matchedCount--;\n                    }\n\n                    // Lengthen the array for every element, matched or not\n                    if ( seed ) {\n                        unmatched.push( elem );\n                    }\n                }\n            }\n\n            // Apply set filters to unmatched elements\n            matchedCount += i;\n            if ( bySet && i !== matchedCount ) {\n                j = 0;\n                while ( (matcher = setMatchers[j++]) ) {\n                    matcher( unmatched, setMatched, context, xml );\n                }\n\n                if ( seed ) {\n                    // Reintegrate element matches to eliminate the need for sorting\n                    if ( matchedCount > 0 ) {\n                        while ( i-- ) {\n                            if ( !(unmatched[i] || setMatched[i]) ) {\n                                setMatched[i] = pop.call( results );\n                            }\n                        }\n                    }\n\n                    // Discard index placeholder values to get only actual matches\n                    setMatched = condense( setMatched );\n                }\n\n                // Add matches to results\n                push.apply( results, setMatched );\n\n                // Seedless set matches succeeding multiple successful matchers stipulate sorting\n                if ( outermost && !seed && setMatched.length > 0 &&\n                    ( matchedCount + setMatchers.length ) > 1 ) {\n\n                    Sizzle.uniqueSort( results );\n                }\n            }\n\n            // Override manipulation of globals by nested matchers\n            if ( outermost ) {\n                dirruns = dirrunsUnique;\n                outermostContext = contextBackup;\n            }\n\n            return unmatched;\n        };\n\n    return bySet ?\n        markFunction( superMatcher ) :\n        superMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\n    var i,\n        setMatchers = [],\n        elementMatchers = [],\n        cached = compilerCache[ selector + \" \" ];\n\n    if ( !cached ) {\n        // Generate a function of recursive functions that can be used to check each element\n        if ( !group ) {\n            group = tokenize( selector );\n        }\n        i = group.length;\n        while ( i-- ) {\n            cached = matcherFromTokens( group[i] );\n            if ( cached[ expando ] ) {\n                setMatchers.push( cached );\n            } else {\n                elementMatchers.push( cached );\n            }\n        }\n\n        // Cache the compiled function\n        cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n    }\n    return cached;\n};\n\nfunction multipleContexts( selector, contexts, results ) {\n    var i = 0,\n        len = contexts.length;\n    for ( ; i < len; i++ ) {\n        Sizzle( selector, contexts[i], results );\n    }\n    return results;\n}\n\nfunction select( selector, context, results, seed ) {\n    var i, tokens, token, type, find,\n        match = tokenize( selector );\n\n    if ( !seed ) {\n        // Try to minimize operations if there is only one group\n        if ( match.length === 1 ) {\n\n            // Take a shortcut and set the context if the root selector is an ID\n            tokens = match[0] = match[0].slice( 0 );\n            if ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n                    support.getById && context.nodeType === 9 && documentIsHTML &&\n                    Expr.relative[ tokens[1].type ] ) {\n\n                context = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n                if ( !context ) {\n                    return results;\n                }\n                selector = selector.slice( tokens.shift().value.length );\n            }\n\n            // Fetch a seed set for right-to-left matching\n            i = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n            while ( i-- ) {\n                token = tokens[i];\n\n                // Abort if we hit a combinator\n                if ( Expr.relative[ (type = token.type) ] ) {\n                    break;\n                }\n                if ( (find = Expr.find[ type ]) ) {\n                    // Search, expanding context for leading sibling combinators\n                    if ( (seed = find(\n                        token.matches[0].replace( runescape, funescape ),\n                        rsibling.test( tokens[0].type ) && context.parentNode || context\n                    )) ) {\n\n                        // If seed is empty or no tokens remain, we can return early\n                        tokens.splice( i, 1 );\n                        selector = seed.length && toSelector( tokens );\n                        if ( !selector ) {\n                            push.apply( results, seed );\n                            return results;\n                        }\n\n                        break;\n                    }\n                }\n            }\n        }\n    }\n\n    // Compile and execute a filtering function\n    // Provide `match` to avoid retokenization if we modified the selector above\n    compile( selector, match )(\n        seed,\n        context,\n        !documentIsHTML,\n        results,\n        rsibling.test( selector )\n    );\n    return results;\n}\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome<14\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n    // Should return 1, but returns 4 (following)\n    return div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n    div.innerHTML = \"<a href='#'></a>\";\n    return div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n    addHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n        if ( !isXML ) {\n            return elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n        }\n    });\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n    div.innerHTML = \"<input/>\";\n    div.firstChild.setAttribute( \"value\", \"\" );\n    return div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n    addHandle( \"value\", function( elem, name, isXML ) {\n        if ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n            return elem.defaultValue;\n        }\n    });\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n    return div.getAttribute(\"disabled\") == null;\n}) ) {\n    addHandle( booleans, function( elem, name, isXML ) {\n        var val;\n        if ( !isXML ) {\n            return (val = elem.getAttributeNode( name )) && val.specified ?\n                val.value :\n                elem[ name ] === true ? name.toLowerCase() : null;\n        }\n    });\n}\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n})( window );\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n    var object = optionsCache[ options ] = {};\n    jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {\n        object[ flag ] = true;\n    });\n    return object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *  options: an optional list of space-separated options that will change how\n *          the callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *  once:           will ensure the callback list can only be fired once (like a Deferred)\n *\n *  memory:         will keep track of previous values and will call any callback added\n *                  after the list has been fired right away with the latest \"memorized\"\n *                  values (like a Deferred)\n *\n *  unique:         will ensure a callback can only be added once (no duplicate in the list)\n *\n *  stopOnFalse:    interrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n    // Convert options from String-formatted to Object-formatted if needed\n    // (we check in cache first)\n    options = typeof options === \"string\" ?\n        ( optionsCache[ options ] || createOptions( options ) ) :\n        jQuery.extend( {}, options );\n\n    var // Flag to know if list is currently firing\n        firing,\n        // Last fire value (for non-forgettable lists)\n        memory,\n        // Flag to know if list was already fired\n        fired,\n        // End of the loop when firing\n        firingLength,\n        // Index of currently firing callback (modified by remove if needed)\n        firingIndex,\n        // First callback to fire (used internally by add and fireWith)\n        firingStart,\n        // Actual callback list\n        list = [],\n        // Stack of fire calls for repeatable lists\n        stack = !options.once && [],\n        // Fire callbacks\n        fire = function( data ) {\n            memory = options.memory && data;\n            fired = true;\n            firingIndex = firingStart || 0;\n            firingStart = 0;\n            firingLength = list.length;\n            firing = true;\n            for ( ; list && firingIndex < firingLength; firingIndex++ ) {\n                if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n                    memory = false; // To prevent further calls using add\n                    break;\n                }\n            }\n            firing = false;\n            if ( list ) {\n                if ( stack ) {\n                    if ( stack.length ) {\n                        fire( stack.shift() );\n                    }\n                } else if ( memory ) {\n                    list = [];\n                } else {\n                    self.disable();\n                }\n            }\n        },\n        // Actual Callbacks object\n        self = {\n            // Add a callback or a collection of callbacks to the list\n            add: function() {\n                if ( list ) {\n                    // First, we save the current length\n                    var start = list.length;\n                    (function add( args ) {\n                        jQuery.each( args, function( _, arg ) {\n                            var type = jQuery.type( arg );\n                            if ( type === \"function\" ) {\n                                if ( !options.unique || !self.has( arg ) ) {\n                                    list.push( arg );\n                                }\n                            } else if ( arg && arg.length && type !== \"string\" ) {\n                                // Inspect recursively\n                                add( arg );\n                            }\n                        });\n                    })( arguments );\n                    // Do we need to add the callbacks to the\n                    // current firing batch?\n                    if ( firing ) {\n                        firingLength = list.length;\n                    // With memory, if we're not firing then\n                    // we should call right away\n                    } else if ( memory ) {\n                        firingStart = start;\n                        fire( memory );\n                    }\n                }\n                return this;\n            },\n            // Remove a callback from the list\n            remove: function() {\n                if ( list ) {\n                    jQuery.each( arguments, function( _, arg ) {\n                        var index;\n                        while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n                            list.splice( index, 1 );\n                            // Handle firing indexes\n                            if ( firing ) {\n                                if ( index <= firingLength ) {\n                                    firingLength--;\n                                }\n                                if ( index <= firingIndex ) {\n                                    firingIndex--;\n                                }\n                            }\n                        }\n                    });\n                }\n                return this;\n            },\n            // Check if a given callback is in the list.\n            // If no argument is given, return whether or not list has callbacks attached.\n            has: function( fn ) {\n                return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n            },\n            // Remove all callbacks from the list\n            empty: function() {\n                list = [];\n                firingLength = 0;\n                return this;\n            },\n            // Have the list do nothing anymore\n            disable: function() {\n                list = stack = memory = undefined;\n                return this;\n            },\n            // Is it disabled?\n            disabled: function() {\n                return !list;\n            },\n            // Lock the list in its current state\n            lock: function() {\n                stack = undefined;\n                if ( !memory ) {\n                    self.disable();\n                }\n                return this;\n            },\n            // Is it locked?\n            locked: function() {\n                return !stack;\n            },\n            // Call all callbacks with the given context and arguments\n            fireWith: function( context, args ) {\n                if ( list && ( !fired || stack ) ) {\n                    args = args || [];\n                    args = [ context, args.slice ? args.slice() : args ];\n                    if ( firing ) {\n                        stack.push( args );\n                    } else {\n                        fire( args );\n                    }\n                }\n                return this;\n            },\n            // Call all the callbacks with the given arguments\n            fire: function() {\n                self.fireWith( this, arguments );\n                return this;\n            },\n            // To know if the callbacks have already been called at least once\n            fired: function() {\n                return !!fired;\n            }\n        };\n\n    return self;\n};\njQuery.extend({\n\n    Deferred: function( func ) {\n        var tuples = [\n                // action, add listener, listener list, final state\n                [ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n                [ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n                [ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n            ],\n            state = \"pending\",\n            promise = {\n                state: function() {\n                    return state;\n                },\n                always: function() {\n                    deferred.done( arguments ).fail( arguments );\n                    return this;\n                },\n                then: function( /* fnDone, fnFail, fnProgress */ ) {\n                    var fns = arguments;\n                    return jQuery.Deferred(function( newDefer ) {\n                        jQuery.each( tuples, function( i, tuple ) {\n                            var action = tuple[ 0 ],\n                                fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n                            // deferred[ done | fail | progress ] for forwarding actions to newDefer\n                            deferred[ tuple[1] ](function() {\n                                var returned = fn && fn.apply( this, arguments );\n                                if ( returned && jQuery.isFunction( returned.promise ) ) {\n                                    returned.promise()\n                                        .done( newDefer.resolve )\n                                        .fail( newDefer.reject )\n                                        .progress( newDefer.notify );\n                                } else {\n                                    newDefer[ action + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n                                }\n                            });\n                        });\n                        fns = null;\n                    }).promise();\n                },\n                // Get a promise for this deferred\n                // If obj is provided, the promise aspect is added to the object\n                promise: function( obj ) {\n                    return obj != null ? jQuery.extend( obj, promise ) : promise;\n                }\n            },\n            deferred = {};\n\n        // Keep pipe for back-compat\n        promise.pipe = promise.then;\n\n        // Add list-specific methods\n        jQuery.each( tuples, function( i, tuple ) {\n            var list = tuple[ 2 ],\n                stateString = tuple[ 3 ];\n\n            // promise[ done | fail | progress ] = list.add\n            promise[ tuple[1] ] = list.add;\n\n            // Handle state\n            if ( stateString ) {\n                list.add(function() {\n                    // state = [ resolved | rejected ]\n                    state = stateString;\n\n                // [ reject_list | resolve_list ].disable; progress_list.lock\n                }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n            }\n\n            // deferred[ resolve | reject | notify ]\n            deferred[ tuple[0] ] = function() {\n                deferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n                return this;\n            };\n            deferred[ tuple[0] + \"With\" ] = list.fireWith;\n        });\n\n        // Make the deferred a promise\n        promise.promise( deferred );\n\n        // Call given func if any\n        if ( func ) {\n            func.call( deferred, deferred );\n        }\n\n        // All done!\n        return deferred;\n    },\n\n    // Deferred helper\n    when: function( subordinate /* , ..., subordinateN */ ) {\n        var i = 0,\n            resolveValues = core_slice.call( arguments ),\n            length = resolveValues.length,\n\n            // the count of uncompleted subordinates\n            remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n            // the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n            deferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n            // Update function for both resolve and progress values\n            updateFunc = function( i, contexts, values ) {\n                return function( value ) {\n                    contexts[ i ] = this;\n                    values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;\n                    if( values === progressValues ) {\n                        deferred.notifyWith( contexts, values );\n                    } else if ( !( --remaining ) ) {\n                        deferred.resolveWith( contexts, values );\n                    }\n                };\n            },\n\n            progressValues, progressContexts, resolveContexts;\n\n        // add listeners to Deferred subordinates; treat others as resolved\n        if ( length > 1 ) {\n            progressValues = new Array( length );\n            progressContexts = new Array( length );\n            resolveContexts = new Array( length );\n            for ( ; i < length; i++ ) {\n                if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n                    resolveValues[ i ].promise()\n                        .done( updateFunc( i, resolveContexts, resolveValues ) )\n                        .fail( deferred.reject )\n                        .progress( updateFunc( i, progressContexts, progressValues ) );\n                } else {\n                    --remaining;\n                }\n            }\n        }\n\n        // if we're not waiting on anything, resolve the master\n        if ( !remaining ) {\n            deferred.resolveWith( resolveContexts, resolveValues );\n        }\n\n        return deferred.promise();\n    }\n});\njQuery.support = (function( support ) {\n\n    var all, a, input, select, fragment, opt, eventName, isSupported, i,\n        div = document.createElement(\"div\");\n\n    // Setup\n    div.setAttribute( \"className\", \"t\" );\n    div.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\n    // Finish early in limited (non-browser) environments\n    all = div.getElementsByTagName(\"*\") || [];\n    a = div.getElementsByTagName(\"a\")[ 0 ];\n    if ( !a || !a.style || !all.length ) {\n        return support;\n    }\n\n    // First batch of tests\n    select = document.createElement(\"select\");\n    opt = select.appendChild( document.createElement(\"option\") );\n    input = div.getElementsByTagName(\"input\")[ 0 ];\n\n    a.style.cssText = \"top:1px;float:left;opacity:.5\";\n\n    // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n    support.getSetAttribute = div.className !== \"t\";\n\n    // IE strips leading whitespace when .innerHTML is used\n    support.leadingWhitespace = div.firstChild.nodeType === 3;\n\n    // Make sure that tbody elements aren't automatically inserted\n    // IE will insert them into empty tables\n    support.tbody = !div.getElementsByTagName(\"tbody\").length;\n\n    // Make sure that link elements get serialized correctly by innerHTML\n    // This requires a wrapper element in IE\n    support.htmlSerialize = !!div.getElementsByTagName(\"link\").length;\n\n    // Get the style information from getAttribute\n    // (IE uses .cssText instead)\n    support.style = /top/.test( a.getAttribute(\"style\") );\n\n    // Make sure that URLs aren't manipulated\n    // (IE normalizes it by default)\n    support.hrefNormalized = a.getAttribute(\"href\") === \"/a\";\n\n    // Make sure that element opacity exists\n    // (IE uses filter instead)\n    // Use a regex to work around a WebKit issue. See #5145\n    support.opacity = /^0.5/.test( a.style.opacity );\n\n    // Verify style float existence\n    // (IE uses styleFloat instead of cssFloat)\n    support.cssFloat = !!a.style.cssFloat;\n\n    // Check the default checkbox/radio value (\"\" on WebKit; \"on\" elsewhere)\n    support.checkOn = !!input.value;\n\n    // Make sure that a selected-by-default option has a working selected property.\n    // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n    support.optSelected = opt.selected;\n\n    // Tests for enctype support on a form (#6743)\n    support.enctype = !!document.createElement(\"form\").enctype;\n\n    // Makes sure cloning an html5 element does not cause problems\n    // Where outerHTML is undefined, this still works\n    support.html5Clone = document.createElement(\"nav\").cloneNode( true ).outerHTML !== \"<:nav></:nav>\";\n\n    // Will be defined later\n    support.inlineBlockNeedsLayout = false;\n    support.shrinkWrapBlocks = false;\n    support.pixelPosition = false;\n    support.deleteExpando = true;\n    support.noCloneEvent = true;\n    support.reliableMarginRight = true;\n    support.boxSizingReliable = true;\n\n    // Make sure checked status is properly cloned\n    input.checked = true;\n    support.noCloneChecked = input.cloneNode( true ).checked;\n\n    // Make sure that the options inside disabled selects aren't marked as disabled\n    // (WebKit marks them as disabled)\n    select.disabled = true;\n    support.optDisabled = !opt.disabled;\n\n    // Support: IE<9\n    try {\n        delete div.test;\n    } catch( e ) {\n        support.deleteExpando = false;\n    }\n\n    // Check if we can trust getAttribute(\"value\")\n    input = document.createElement(\"input\");\n    input.setAttribute( \"value\", \"\" );\n    support.input = input.getAttribute( \"value\" ) === \"\";\n\n    // Check if an input maintains its value after becoming a radio\n    input.value = \"t\";\n    input.setAttribute( \"type\", \"radio\" );\n    support.radioValue = input.value === \"t\";\n\n    // #11217 - WebKit loses check when the name is after the checked attribute\n    input.setAttribute( \"checked\", \"t\" );\n    input.setAttribute( \"name\", \"t\" );\n\n    fragment = document.createDocumentFragment();\n    fragment.appendChild( input );\n\n    // Check if a disconnected checkbox will retain its checked\n    // value of true after appended to the DOM (IE6/7)\n    support.appendChecked = input.checked;\n\n    // WebKit doesn't clone checked state correctly in fragments\n    support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n    // Support: IE<9\n    // Opera does not clone events (and typeof div.attachEvent === undefined).\n    // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()\n    if ( div.attachEvent ) {\n        div.attachEvent( \"onclick\", function() {\n            support.noCloneEvent = false;\n        });\n\n        div.cloneNode( true ).click();\n    }\n\n    // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)\n    // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n    for ( i in { submit: true, change: true, focusin: true }) {\n        div.setAttribute( eventName = \"on\" + i, \"t\" );\n\n        support[ i + \"Bubbles\" ] = eventName in window || div.attributes[ eventName ].expando === false;\n    }\n\n    div.style.backgroundClip = \"content-box\";\n    div.cloneNode( true ).style.backgroundClip = \"\";\n    support.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n    // Support: IE<9\n    // Iteration over object's inherited properties before its own.\n    for ( i in jQuery( support ) ) {\n        break;\n    }\n    support.ownLast = i !== \"0\";\n\n    // Run tests that need a body at doc ready\n    jQuery(function() {\n        var container, marginDiv, tds,\n            divReset = \"padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;\",\n            body = document.getElementsByTagName(\"body\")[0];\n\n        if ( !body ) {\n            // Return for frameset docs that don't have a body\n            return;\n        }\n\n        container = document.createElement(\"div\");\n        container.style.cssText = \"border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px\";\n\n        body.appendChild( container ).appendChild( div );\n\n        // Support: IE8\n        // Check if table cells still have offsetWidth/Height when they are set\n        // to display:none and there are still other visible table cells in a\n        // table row; if so, offsetWidth/Height are not reliable for use when\n        // determining if an element has been hidden directly using\n        // display:none (it is still safe to use offsets if a parent element is\n        // hidden; don safety goggles and see bug #4512 for more information).\n        div.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n        tds = div.getElementsByTagName(\"td\");\n        tds[ 0 ].style.cssText = \"padding:0;margin:0;border:0;display:none\";\n        isSupported = ( tds[ 0 ].offsetHeight === 0 );\n\n        tds[ 0 ].style.display = \"\";\n        tds[ 1 ].style.display = \"none\";\n\n        // Support: IE8\n        // Check if empty table cells still have offsetWidth/Height\n        support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );\n\n        // Check box-sizing and margin behavior.\n        div.innerHTML = \"\";\n        div.style.cssText = \"box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;\";\n\n        // Workaround failing boxSizing test due to offsetWidth returning wrong value\n        // with some non-1 values of body zoom, ticket #13543\n        jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {\n            support.boxSizing = div.offsetWidth === 4;\n        });\n\n        // Use window.getComputedStyle because jsdom on node.js will break without it.\n        if ( window.getComputedStyle ) {\n            support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n            support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n            // Check if div with explicit width and no margin-right incorrectly\n            // gets computed margin-right based on width of container. (#3333)\n            // Fails in WebKit before Feb 2011 nightlies\n            // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n            marginDiv = div.appendChild( document.createElement(\"div\") );\n            marginDiv.style.cssText = div.style.cssText = divReset;\n            marginDiv.style.marginRight = marginDiv.style.width = \"0\";\n            div.style.width = \"1px\";\n\n            support.reliableMarginRight =\n                !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );\n        }\n\n        if ( typeof div.style.zoom !== core_strundefined ) {\n            // Support: IE<8\n            // Check if natively block-level elements act like inline-block\n            // elements when setting their display to 'inline' and giving\n            // them layout\n            div.innerHTML = \"\";\n            div.style.cssText = divReset + \"width:1px;padding:1px;display:inline;zoom:1\";\n            support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );\n\n            // Support: IE6\n            // Check if elements with layout shrink-wrap their children\n            div.style.display = \"block\";\n            div.innerHTML = \"<div></div>\";\n            div.firstChild.style.width = \"5px\";\n            support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );\n\n            if ( support.inlineBlockNeedsLayout ) {\n                // Prevent IE 6 from affecting layout for positioned elements #11048\n                // Prevent IE from shrinking the body in IE 7 mode #12869\n                // Support: IE<8\n                body.style.zoom = 1;\n            }\n        }\n\n        body.removeChild( container );\n\n        // Null elements to avoid leaks in IE\n        container = div = tds = marginDiv = null;\n    });\n\n    // Null elements to avoid leaks in IE\n    all = select = fragment = opt = a = input = null;\n\n    return support;\n})({});\n\nvar rbrace = /(?:\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/,\n    rmultiDash = /([A-Z])/g;\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ){\n    if ( !jQuery.acceptData( elem ) ) {\n        return;\n    }\n\n    var ret, thisCache,\n        internalKey = jQuery.expando,\n\n        // We have to handle DOM nodes and JS objects differently because IE6-7\n        // can't GC object references properly across the DOM-JS boundary\n        isNode = elem.nodeType,\n\n        // Only DOM nodes need the global jQuery cache; JS object data is\n        // attached directly to the object so GC can occur automatically\n        cache = isNode ? jQuery.cache : elem,\n\n        // Only defining an ID for JS objects if its cache already exists allows\n        // the code to shortcut on the same path as a DOM node with no cache\n        id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n    // Avoid doing any more work than we need to when trying to get data on an\n    // object that has no data at all\n    if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n        return;\n    }\n\n    if ( !id ) {\n        // Only DOM nodes need a new unique ID for each element since their data\n        // ends up in the global cache\n        if ( isNode ) {\n            id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++;\n        } else {\n            id = internalKey;\n        }\n    }\n\n    if ( !cache[ id ] ) {\n        // Avoid exposing jQuery metadata on plain JS objects when the object\n        // is serialized using JSON.stringify\n        cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n    }\n\n    // An object can be passed to jQuery.data instead of a key/value pair; this gets\n    // shallow copied over onto the existing cache\n    if ( typeof name === \"object\" || typeof name === \"function\" ) {\n        if ( pvt ) {\n            cache[ id ] = jQuery.extend( cache[ id ], name );\n        } else {\n            cache[ id ].data = jQuery.extend( cache[ id ].data, name );\n        }\n    }\n\n    thisCache = cache[ id ];\n\n    // jQuery data() is stored in a separate object inside the object's internal data\n    // cache in order to avoid key collisions between internal data and user-defined\n    // data.\n    if ( !pvt ) {\n        if ( !thisCache.data ) {\n            thisCache.data = {};\n        }\n\n        thisCache = thisCache.data;\n    }\n\n    if ( data !== undefined ) {\n        thisCache[ jQuery.camelCase( name ) ] = data;\n    }\n\n    // Check for both converted-to-camel and non-converted data property names\n    // If a data property was specified\n    if ( typeof name === \"string\" ) {\n\n        // First Try to find as-is property data\n        ret = thisCache[ name ];\n\n        // Test for null|undefined property data\n        if ( ret == null ) {\n\n            // Try to find the camelCased property\n            ret = thisCache[ jQuery.camelCase( name ) ];\n        }\n    } else {\n        ret = thisCache;\n    }\n\n    return ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n    if ( !jQuery.acceptData( elem ) ) {\n        return;\n    }\n\n    var thisCache, i,\n        isNode = elem.nodeType,\n\n        // See jQuery.data for more information\n        cache = isNode ? jQuery.cache : elem,\n        id = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n    // If there is already no cache entry for this object, there is no\n    // purpose in continuing\n    if ( !cache[ id ] ) {\n        return;\n    }\n\n    if ( name ) {\n\n        thisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n        if ( thisCache ) {\n\n            // Support array or space separated string names for data keys\n            if ( !jQuery.isArray( name ) ) {\n\n                // try the string as a key before any manipulation\n                if ( name in thisCache ) {\n                    name = [ name ];\n                } else {\n\n                    // split the camel cased version by spaces unless a key with the spaces exists\n                    name = jQuery.camelCase( name );\n                    if ( name in thisCache ) {\n                        name = [ name ];\n                    } else {\n                        name = name.split(\" \");\n                    }\n                }\n            } else {\n                // If \"name\" is an array of keys...\n                // When data is initially created, via (\"key\", \"val\") signature,\n                // keys will be converted to camelCase.\n                // Since there is no way to tell _how_ a key was added, remove\n                // both plain key and camelCase key. #12786\n                // This will only penalize the array argument path.\n                name = name.concat( jQuery.map( name, jQuery.camelCase ) );\n            }\n\n            i = name.length;\n            while ( i-- ) {\n                delete thisCache[ name[i] ];\n            }\n\n            // If there is no data left in the cache, we want to continue\n            // and let the cache object itself get destroyed\n            if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n                return;\n            }\n        }\n    }\n\n    // See jQuery.data for more information\n    if ( !pvt ) {\n        delete cache[ id ].data;\n\n        // Don't destroy the parent cache unless the internal data object\n        // had been the only thing left in it\n        if ( !isEmptyDataObject( cache[ id ] ) ) {\n            return;\n        }\n    }\n\n    // Destroy the cache\n    if ( isNode ) {\n        jQuery.cleanData( [ elem ], true );\n\n    // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n    /* jshint eqeqeq: false */\n    } else if ( jQuery.support.deleteExpando || cache != cache.window ) {\n        /* jshint eqeqeq: true */\n        delete cache[ id ];\n\n    // When all else fails, null\n    } else {\n        cache[ id ] = null;\n    }\n}\n\njQuery.extend({\n    cache: {},\n\n    // The following elements throw uncatchable exceptions if you\n    // attempt to add expando properties to them.\n    noData: {\n        \"applet\": true,\n        \"embed\": true,\n        // Ban all objects except for Flash (which handle expandos)\n        \"object\": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n    },\n\n    hasData: function( elem ) {\n        elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n        return !!elem && !isEmptyDataObject( elem );\n    },\n\n    data: function( elem, name, data ) {\n        return internalData( elem, name, data );\n    },\n\n    removeData: function( elem, name ) {\n        return internalRemoveData( elem, name );\n    },\n\n    // For internal use only.\n    _data: function( elem, name, data ) {\n        return internalData( elem, name, data, true );\n    },\n\n    _removeData: function( elem, name ) {\n        return internalRemoveData( elem, name, true );\n    },\n\n    // A method for determining if a DOM node can handle the data expando\n    acceptData: function( elem ) {\n        // Do not set data on non-element because it will not be cleared (#8335).\n        if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {\n            return false;\n        }\n\n        var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];\n\n        // nodes accept data unless otherwise specified; rejection can be conditional\n        return !noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n    }\n});\n\njQuery.fn.extend({\n    data: function( key, value ) {\n        var attrs, name,\n            data = null,\n            i = 0,\n            elem = this[0];\n\n        // Special expections of .data basically thwart jQuery.access,\n        // so implement the relevant behavior ourselves\n\n        // Gets all values\n        if ( key === undefined ) {\n            if ( this.length ) {\n                data = jQuery.data( elem );\n\n                if ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n                    attrs = elem.attributes;\n                    for ( ; i < attrs.length; i++ ) {\n                        name = attrs[i].name;\n\n                        if ( name.indexOf(\"data-\") === 0 ) {\n                            name = jQuery.camelCase( name.slice(5) );\n\n                            dataAttr( elem, name, data[ name ] );\n                        }\n                    }\n                    jQuery._data( elem, \"parsedAttrs\", true );\n                }\n            }\n\n            return data;\n        }\n\n        // Sets multiple values\n        if ( typeof key === \"object\" ) {\n            return this.each(function() {\n                jQuery.data( this, key );\n            });\n        }\n\n        return arguments.length > 1 ?\n\n            // Sets one value\n            this.each(function() {\n                jQuery.data( this, key, value );\n            }) :\n\n            // Gets one value\n            // Try to fetch any internally stored data first\n            elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;\n    },\n\n    removeData: function( key ) {\n        return this.each(function() {\n            jQuery.removeData( this, key );\n        });\n    }\n});\n\nfunction dataAttr( elem, key, data ) {\n    // If nothing was found internally, try to fetch any\n    // data from the HTML5 data-* attribute\n    if ( data === undefined && elem.nodeType === 1 ) {\n\n        var name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n        data = elem.getAttribute( name );\n\n        if ( typeof data === \"string\" ) {\n            try {\n                data = data === \"true\" ? true :\n                    data === \"false\" ? false :\n                    data === \"null\" ? null :\n                    // Only convert to a number if it doesn't change the string\n                    +data + \"\" === data ? +data :\n                    rbrace.test( data ) ? jQuery.parseJSON( data ) :\n                        data;\n            } catch( e ) {}\n\n            // Make sure we set the data so it isn't changed later\n            jQuery.data( elem, key, data );\n\n        } else {\n            data = undefined;\n        }\n    }\n\n    return data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n    var name;\n    for ( name in obj ) {\n\n        // if the public data object is empty, the private is still empty\n        if ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n            continue;\n        }\n        if ( name !== \"toJSON\" ) {\n            return false;\n        }\n    }\n\n    return true;\n}\njQuery.extend({\n    queue: function( elem, type, data ) {\n        var queue;\n\n        if ( elem ) {\n            type = ( type || \"fx\" ) + \"queue\";\n            queue = jQuery._data( elem, type );\n\n            // Speed up dequeue by getting out quickly if this is just a lookup\n            if ( data ) {\n                if ( !queue || jQuery.isArray(data) ) {\n                    queue = jQuery._data( elem, type, jQuery.makeArray(data) );\n                } else {\n                    queue.push( data );\n                }\n            }\n            return queue || [];\n        }\n    },\n\n    dequeue: function( elem, type ) {\n        type = type || \"fx\";\n\n        var queue = jQuery.queue( elem, type ),\n            startLength = queue.length,\n            fn = queue.shift(),\n            hooks = jQuery._queueHooks( elem, type ),\n            next = function() {\n                jQuery.dequeue( elem, type );\n            };\n\n        // If the fx queue is dequeued, always remove the progress sentinel\n        if ( fn === \"inprogress\" ) {\n            fn = queue.shift();\n            startLength--;\n        }\n\n        if ( fn ) {\n\n            // Add a progress sentinel to prevent the fx queue from being\n            // automatically dequeued\n            if ( type === \"fx\" ) {\n                queue.unshift( \"inprogress\" );\n            }\n\n            // clear up the last queue stop function\n            delete hooks.stop;\n            fn.call( elem, next, hooks );\n        }\n\n        if ( !startLength && hooks ) {\n            hooks.empty.fire();\n        }\n    },\n\n    // not intended for public consumption - generates a queueHooks object, or returns the current one\n    _queueHooks: function( elem, type ) {\n        var key = type + \"queueHooks\";\n        return jQuery._data( elem, key ) || jQuery._data( elem, key, {\n            empty: jQuery.Callbacks(\"once memory\").add(function() {\n                jQuery._removeData( elem, type + \"queue\" );\n                jQuery._removeData( elem, key );\n            })\n        });\n    }\n});\n\njQuery.fn.extend({\n    queue: function( type, data ) {\n        var setter = 2;\n\n        if ( typeof type !== \"string\" ) {\n            data = type;\n            type = \"fx\";\n            setter--;\n        }\n\n        if ( arguments.length < setter ) {\n            return jQuery.queue( this[0], type );\n        }\n\n        return data === undefined ?\n            this :\n            this.each(function() {\n                var queue = jQuery.queue( this, type, data );\n\n                // ensure a hooks for this queue\n                jQuery._queueHooks( this, type );\n\n                if ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n                    jQuery.dequeue( this, type );\n                }\n            });\n    },\n    dequeue: function( type ) {\n        return this.each(function() {\n            jQuery.dequeue( this, type );\n        });\n    },\n    // Based off of the plugin by Clint Helfers, with permission.\n    // http://blindsignals.com/index.php/2009/07/jquery-delay/\n    delay: function( time, type ) {\n        time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n        type = type || \"fx\";\n\n        return this.queue( type, function( next, hooks ) {\n            var timeout = setTimeout( next, time );\n            hooks.stop = function() {\n                clearTimeout( timeout );\n            };\n        });\n    },\n    clearQueue: function( type ) {\n        return this.queue( type || \"fx\", [] );\n    },\n    // Get a promise resolved when queues of a certain type\n    // are emptied (fx is the type by default)\n    promise: function( type, obj ) {\n        var tmp,\n            count = 1,\n            defer = jQuery.Deferred(),\n            elements = this,\n            i = this.length,\n            resolve = function() {\n                if ( !( --count ) ) {\n                    defer.resolveWith( elements, [ elements ] );\n                }\n            };\n\n        if ( typeof type !== \"string\" ) {\n            obj = type;\n            type = undefined;\n        }\n        type = type || \"fx\";\n\n        while( i-- ) {\n            tmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n            if ( tmp && tmp.empty ) {\n                count++;\n                tmp.empty.add( resolve );\n            }\n        }\n        resolve();\n        return defer.promise( obj );\n    }\n});\nvar nodeHook, boolHook,\n    rclass = /[\\t\\r\\n\\f]/g,\n    rreturn = /\\r/g,\n    rfocusable = /^(?:input|select|textarea|button|object)$/i,\n    rclickable = /^(?:a|area)$/i,\n    ruseDefault = /^(?:checked|selected)$/i,\n    getSetAttribute = jQuery.support.getSetAttribute,\n    getSetInput = jQuery.support.input;\n\njQuery.fn.extend({\n    attr: function( name, value ) {\n        return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );\n    },\n\n    removeAttr: function( name ) {\n        return this.each(function() {\n            jQuery.removeAttr( this, name );\n        });\n    },\n\n    prop: function( name, value ) {\n        return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );\n    },\n\n    removeProp: function( name ) {\n        name = jQuery.propFix[ name ] || name;\n        return this.each(function() {\n            // try/catch handles cases where IE balks (such as removing a property on window)\n            try {\n                this[ name ] = undefined;\n                delete this[ name ];\n            } catch( e ) {}\n        });\n    },\n\n    addClass: function( value ) {\n        var classes, elem, cur, clazz, j,\n            i = 0,\n            len = this.length,\n            proceed = typeof value === \"string\" && value;\n\n        if ( jQuery.isFunction( value ) ) {\n            return this.each(function( j ) {\n                jQuery( this ).addClass( value.call( this, j, this.className ) );\n            });\n        }\n\n        if ( proceed ) {\n            // The disjunction here is for better compressibility (see removeClass)\n            classes = ( value || \"\" ).match( core_rnotwhite ) || [];\n\n            for ( ; i < len; i++ ) {\n                elem = this[ i ];\n                cur = elem.nodeType === 1 && ( elem.className ?\n                    ( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n                    \" \"\n                );\n\n                if ( cur ) {\n                    j = 0;\n                    while ( (clazz = classes[j++]) ) {\n                        if ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n                            cur += clazz + \" \";\n                        }\n                    }\n                    elem.className = jQuery.trim( cur );\n\n                }\n            }\n        }\n\n        return this;\n    },\n\n    removeClass: function( value ) {\n        var classes, elem, cur, clazz, j,\n            i = 0,\n            len = this.length,\n            proceed = arguments.length === 0 || typeof value === \"string\" && value;\n\n        if ( jQuery.isFunction( value ) ) {\n            return this.each(function( j ) {\n                jQuery( this ).removeClass( value.call( this, j, this.className ) );\n            });\n        }\n        if ( proceed ) {\n            classes = ( value || \"\" ).match( core_rnotwhite ) || [];\n\n            for ( ; i < len; i++ ) {\n                elem = this[ i ];\n                // This expression is here for better compressibility (see addClass)\n                cur = elem.nodeType === 1 && ( elem.className ?\n                    ( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n                    \"\"\n                );\n\n                if ( cur ) {\n                    j = 0;\n                    while ( (clazz = classes[j++]) ) {\n                        // Remove *all* instances\n                        while ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n                            cur = cur.replace( \" \" + clazz + \" \", \" \" );\n                        }\n                    }\n                    elem.className = value ? jQuery.trim( cur ) : \"\";\n                }\n            }\n        }\n\n        return this;\n    },\n\n    toggleClass: function( value, stateVal ) {\n        var type = typeof value;\n\n        if ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n            return stateVal ? this.addClass( value ) : this.removeClass( value );\n        }\n\n        if ( jQuery.isFunction( value ) ) {\n            return this.each(function( i ) {\n                jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n            });\n        }\n\n        return this.each(function() {\n            if ( type === \"string\" ) {\n                // toggle individual class names\n                var className,\n                    i = 0,\n                    self = jQuery( this ),\n                    classNames = value.match( core_rnotwhite ) || [];\n\n                while ( (className = classNames[ i++ ]) ) {\n                    // check each className given, space separated list\n                    if ( self.hasClass( className ) ) {\n                        self.removeClass( className );\n                    } else {\n                        self.addClass( className );\n                    }\n                }\n\n            // Toggle whole class name\n            } else if ( type === core_strundefined || type === \"boolean\" ) {\n                if ( this.className ) {\n                    // store className if set\n                    jQuery._data( this, \"__className__\", this.className );\n                }\n\n                // If the element has a class name or if we're passed \"false\",\n                // then remove the whole classname (if there was one, the above saved it).\n                // Otherwise bring back whatever was previously saved (if anything),\n                // falling back to the empty string if nothing was stored.\n                this.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n            }\n        });\n    },\n\n    hasClass: function( selector ) {\n        var className = \" \" + selector + \" \",\n            i = 0,\n            l = this.length;\n        for ( ; i < l; i++ ) {\n            if ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n                return true;\n            }\n        }\n\n        return false;\n    },\n\n    val: function( value ) {\n        var ret, hooks, isFunction,\n            elem = this[0];\n\n        if ( !arguments.length ) {\n            if ( elem ) {\n                hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n                if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n                    return ret;\n                }\n\n                ret = elem.value;\n\n                return typeof ret === \"string\" ?\n                    // handle most common string cases\n                    ret.replace(rreturn, \"\") :\n                    // handle cases where value is null/undef or number\n                    ret == null ? \"\" : ret;\n            }\n\n            return;\n        }\n\n        isFunction = jQuery.isFunction( value );\n\n        return this.each(function( i ) {\n            var val;\n\n            if ( this.nodeType !== 1 ) {\n                return;\n            }\n\n            if ( isFunction ) {\n                val = value.call( this, i, jQuery( this ).val() );\n            } else {\n                val = value;\n            }\n\n            // Treat null/undefined as \"\"; convert numbers to string\n            if ( val == null ) {\n                val = \"\";\n            } else if ( typeof val === \"number\" ) {\n                val += \"\";\n            } else if ( jQuery.isArray( val ) ) {\n                val = jQuery.map(val, function ( value ) {\n                    return value == null ? \"\" : value + \"\";\n                });\n            }\n\n            hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n            // If set returns undefined, fall back to normal setting\n            if ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n                this.value = val;\n            }\n        });\n    }\n});\n\njQuery.extend({\n    valHooks: {\n        option: {\n            get: function( elem ) {\n                // Use proper attribute retrieval(#6932, #12072)\n                var val = jQuery.find.attr( elem, \"value\" );\n                return val != null ?\n                    val :\n                    elem.text;\n            }\n        },\n        select: {\n            get: function( elem ) {\n                var value, option,\n                    options = elem.options,\n                    index = elem.selectedIndex,\n                    one = elem.type === \"select-one\" || index < 0,\n                    values = one ? null : [],\n                    max = one ? index + 1 : options.length,\n                    i = index < 0 ?\n                        max :\n                        one ? index : 0;\n\n                // Loop through all the selected options\n                for ( ; i < max; i++ ) {\n                    option = options[ i ];\n\n                    // oldIE doesn't update selected after form reset (#2551)\n                    if ( ( option.selected || i === index ) &&\n                            // Don't return options that are disabled or in a disabled optgroup\n                            ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n                            ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n                        // Get the specific value for the option\n                        value = jQuery( option ).val();\n\n                        // We don't need an array for one selects\n                        if ( one ) {\n                            return value;\n                        }\n\n                        // Multi-Selects return an array\n                        values.push( value );\n                    }\n                }\n\n                return values;\n            },\n\n            set: function( elem, value ) {\n                var optionSet, option,\n                    options = elem.options,\n                    values = jQuery.makeArray( value ),\n                    i = options.length;\n\n                while ( i-- ) {\n                    option = options[ i ];\n                    if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {\n                        optionSet = true;\n                    }\n                }\n\n                // force browsers to behave consistently when non-matching value is set\n                if ( !optionSet ) {\n                    elem.selectedIndex = -1;\n                }\n                return values;\n            }\n        }\n    },\n\n    attr: function( elem, name, value ) {\n        var hooks, ret,\n            nType = elem.nodeType;\n\n        // don't get/set attributes on text, comment and attribute nodes\n        if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n            return;\n        }\n\n        // Fallback to prop when attributes are not supported\n        if ( typeof elem.getAttribute === core_strundefined ) {\n            return jQuery.prop( elem, name, value );\n        }\n\n        // All attributes are lowercase\n        // Grab necessary hook if one is defined\n        if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n            name = name.toLowerCase();\n            hooks = jQuery.attrHooks[ name ] ||\n                ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n        }\n\n        if ( value !== undefined ) {\n\n            if ( value === null ) {\n                jQuery.removeAttr( elem, name );\n\n            } else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n                return ret;\n\n            } else {\n                elem.setAttribute( name, value + \"\" );\n                return value;\n            }\n\n        } else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n            return ret;\n\n        } else {\n            ret = jQuery.find.attr( elem, name );\n\n            // Non-existent attributes return null, we normalize to undefined\n            return ret == null ?\n                undefined :\n                ret;\n        }\n    },\n\n    removeAttr: function( elem, value ) {\n        var name, propName,\n            i = 0,\n            attrNames = value && value.match( core_rnotwhite );\n\n        if ( attrNames && elem.nodeType === 1 ) {\n            while ( (name = attrNames[i++]) ) {\n                propName = jQuery.propFix[ name ] || name;\n\n                // Boolean attributes get special treatment (#10870)\n                if ( jQuery.expr.match.bool.test( name ) ) {\n                    // Set corresponding property to false\n                    if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n                        elem[ propName ] = false;\n                    // Support: IE<9\n                    // Also clear defaultChecked/defaultSelected (if appropriate)\n                    } else {\n                        elem[ jQuery.camelCase( \"default-\" + name ) ] =\n                            elem[ propName ] = false;\n                    }\n\n                // See #9699 for explanation of this approach (setting first, then removal)\n                } else {\n                    jQuery.attr( elem, name, \"\" );\n                }\n\n                elem.removeAttribute( getSetAttribute ? name : propName );\n            }\n        }\n    },\n\n    attrHooks: {\n        type: {\n            set: function( elem, value ) {\n                if ( !jQuery.support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n                    // Setting the type on a radio button after the value resets the value in IE6-9\n                    // Reset value to default in case type is set after value during creation\n                    var val = elem.value;\n                    elem.setAttribute( \"type\", value );\n                    if ( val ) {\n                        elem.value = val;\n                    }\n                    return value;\n                }\n            }\n        }\n    },\n\n    propFix: {\n        \"for\": \"htmlFor\",\n        \"class\": \"className\"\n    },\n\n    prop: function( elem, name, value ) {\n        var ret, hooks, notxml,\n            nType = elem.nodeType;\n\n        // don't get/set properties on text, comment and attribute nodes\n        if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n            return;\n        }\n\n        notxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n        if ( notxml ) {\n            // Fix name and attach hooks\n            name = jQuery.propFix[ name ] || name;\n            hooks = jQuery.propHooks[ name ];\n        }\n\n        if ( value !== undefined ) {\n            return hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n                ret :\n                ( elem[ name ] = value );\n\n        } else {\n            return hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n                ret :\n                elem[ name ];\n        }\n    },\n\n    propHooks: {\n        tabIndex: {\n            get: function( elem ) {\n                // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n                // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n                // Use proper attribute retrieval(#12072)\n                var tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n                return tabindex ?\n                    parseInt( tabindex, 10 ) :\n                    rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n                        0 :\n                        -1;\n            }\n        }\n    }\n});\n\n// Hooks for boolean attributes\nboolHook = {\n    set: function( elem, value, name ) {\n        if ( value === false ) {\n            // Remove boolean attributes when set to false\n            jQuery.removeAttr( elem, name );\n        } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n            // IE<8 needs the *property* name\n            elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );\n\n        // Use defaultChecked and defaultSelected for oldIE\n        } else {\n            elem[ jQuery.camelCase( \"default-\" + name ) ] = elem[ name ] = true;\n        }\n\n        return name;\n    }\n};\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n    var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;\n\n    jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?\n        function( elem, name, isXML ) {\n            var fn = jQuery.expr.attrHandle[ name ],\n                ret = isXML ?\n                    undefined :\n                    /* jshint eqeqeq: false */\n                    (jQuery.expr.attrHandle[ name ] = undefined) !=\n                        getter( elem, name, isXML ) ?\n\n                        name.toLowerCase() :\n                        null;\n            jQuery.expr.attrHandle[ name ] = fn;\n            return ret;\n        } :\n        function( elem, name, isXML ) {\n            return isXML ?\n                undefined :\n                elem[ jQuery.camelCase( \"default-\" + name ) ] ?\n                    name.toLowerCase() :\n                    null;\n        };\n});\n\n// fix oldIE attroperties\nif ( !getSetInput || !getSetAttribute ) {\n    jQuery.attrHooks.value = {\n        set: function( elem, value, name ) {\n            if ( jQuery.nodeName( elem, \"input\" ) ) {\n                // Does not return so that setAttribute is also used\n                elem.defaultValue = value;\n            } else {\n                // Use nodeHook if defined (#1954); otherwise setAttribute is fine\n                return nodeHook && nodeHook.set( elem, value, name );\n            }\n        }\n    };\n}\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n    // Use this for any attribute in IE6/7\n    // This fixes almost every IE6/7 issue\n    nodeHook = {\n        set: function( elem, value, name ) {\n            // Set the existing or create a new attribute node\n            var ret = elem.getAttributeNode( name );\n            if ( !ret ) {\n                elem.setAttributeNode(\n                    (ret = elem.ownerDocument.createAttribute( name ))\n                );\n            }\n\n            ret.value = value += \"\";\n\n            // Break association with cloned elements by also using setAttribute (#9646)\n            return name === \"value\" || value === elem.getAttribute( name ) ?\n                value :\n                undefined;\n        }\n    };\n    jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords =\n        // Some attributes are constructed with empty-string values when not defined\n        function( elem, name, isXML ) {\n            var ret;\n            return isXML ?\n                undefined :\n                (ret = elem.getAttributeNode( name )) && ret.value !== \"\" ?\n                    ret.value :\n                    null;\n        };\n    jQuery.valHooks.button = {\n        get: function( elem, name ) {\n            var ret = elem.getAttributeNode( name );\n            return ret && ret.specified ?\n                ret.value :\n                undefined;\n        },\n        set: nodeHook.set\n    };\n\n    // Set contenteditable to false on removals(#10429)\n    // Setting to empty string throws an error as an invalid value\n    jQuery.attrHooks.contenteditable = {\n        set: function( elem, value, name ) {\n            nodeHook.set( elem, value === \"\" ? false : value, name );\n        }\n    };\n\n    // Set width and height to auto instead of 0 on empty string( Bug #8150 )\n    // This is for removals\n    jQuery.each([ \"width\", \"height\" ], function( i, name ) {\n        jQuery.attrHooks[ name ] = {\n            set: function( elem, value ) {\n                if ( value === \"\" ) {\n                    elem.setAttribute( name, \"auto\" );\n                    return value;\n                }\n            }\n        };\n    });\n}\n\n\n// Some attributes require a special call on IE\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !jQuery.support.hrefNormalized ) {\n    // href/src property should get the full normalized URL (#10299/#12915)\n    jQuery.each([ \"href\", \"src\" ], function( i, name ) {\n        jQuery.propHooks[ name ] = {\n            get: function( elem ) {\n                return elem.getAttribute( name, 4 );\n            }\n        };\n    });\n}\n\nif ( !jQuery.support.style ) {\n    jQuery.attrHooks.style = {\n        get: function( elem ) {\n            // Return undefined in the case of empty string\n            // Note: IE uppercases css property names, but if we were to .toLowerCase()\n            // .cssText, that would destroy case senstitivity in URL's, like in \"background\"\n            return elem.style.cssText || undefined;\n        },\n        set: function( elem, value ) {\n            return ( elem.style.cssText = value + \"\" );\n        }\n    };\n}\n\n// Safari mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !jQuery.support.optSelected ) {\n    jQuery.propHooks.selected = {\n        get: function( elem ) {\n            var parent = elem.parentNode;\n\n            if ( parent ) {\n                parent.selectedIndex;\n\n                // Make sure that it also works with optgroups, see #5701\n                if ( parent.parentNode ) {\n                    parent.parentNode.selectedIndex;\n                }\n            }\n            return null;\n        }\n    };\n}\n\njQuery.each([\n    \"tabIndex\",\n    \"readOnly\",\n    \"maxLength\",\n    \"cellSpacing\",\n    \"cellPadding\",\n    \"rowSpan\",\n    \"colSpan\",\n    \"useMap\",\n    \"frameBorder\",\n    \"contentEditable\"\n], function() {\n    jQuery.propFix[ this.toLowerCase() ] = this;\n});\n\n// IE6/7 call enctype encoding\nif ( !jQuery.support.enctype ) {\n    jQuery.propFix.enctype = \"encoding\";\n}\n\n// Radios and checkboxes getter/setter\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n    jQuery.valHooks[ this ] = {\n        set: function( elem, value ) {\n            if ( jQuery.isArray( value ) ) {\n                return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n            }\n        }\n    };\n    if ( !jQuery.support.checkOn ) {\n        jQuery.valHooks[ this ].get = function( elem ) {\n            // Support: Webkit\n            // \"\" is returned instead of \"on\" if a value isn't specified\n            return elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n        };\n    }\n});\nvar rformElems = /^(?:input|select|textarea)$/i,\n    rkeyEvent = /^key/,\n    rmouseEvent = /^(?:mouse|contextmenu)|click/,\n    rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n    rtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n    return true;\n}\n\nfunction returnFalse() {\n    return false;\n}\n\nfunction safeActiveElement() {\n    try {\n        return document.activeElement;\n    } catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n    global: {},\n\n    add: function( elem, types, handler, data, selector ) {\n        var tmp, events, t, handleObjIn,\n            special, eventHandle, handleObj,\n            handlers, type, namespaces, origType,\n            elemData = jQuery._data( elem );\n\n        // Don't attach events to noData or text/comment nodes (but allow plain objects)\n        if ( !elemData ) {\n            return;\n        }\n\n        // Caller can pass in an object of custom data in lieu of the handler\n        if ( handler.handler ) {\n            handleObjIn = handler;\n            handler = handleObjIn.handler;\n            selector = handleObjIn.selector;\n        }\n\n        // Make sure that the handler has a unique ID, used to find/remove it later\n        if ( !handler.guid ) {\n            handler.guid = jQuery.guid++;\n        }\n\n        // Init the element's event structure and main handler, if this is the first\n        if ( !(events = elemData.events) ) {\n            events = elemData.events = {};\n        }\n        if ( !(eventHandle = elemData.handle) ) {\n            eventHandle = elemData.handle = function( e ) {\n                // Discard the second event of a jQuery.event.trigger() and\n                // when an event is called after a page has unloaded\n                return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?\n                    jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n                    undefined;\n            };\n            // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n            eventHandle.elem = elem;\n        }\n\n        // Handle multiple events separated by a space\n        types = ( types || \"\" ).match( core_rnotwhite ) || [\"\"];\n        t = types.length;\n        while ( t-- ) {\n            tmp = rtypenamespace.exec( types[t] ) || [];\n            type = origType = tmp[1];\n            namespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n            // There *must* be a type, no attaching namespace-only handlers\n            if ( !type ) {\n                continue;\n            }\n\n            // If event changes its type, use the special event handlers for the changed type\n            special = jQuery.event.special[ type ] || {};\n\n            // If selector defined, determine special event api type, otherwise given type\n            type = ( selector ? special.delegateType : special.bindType ) || type;\n\n            // Update special based on newly reset type\n            special = jQuery.event.special[ type ] || {};\n\n            // handleObj is passed to all event handlers\n            handleObj = jQuery.extend({\n                type: type,\n                origType: origType,\n                data: data,\n                handler: handler,\n                guid: handler.guid,\n                selector: selector,\n                needsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n                namespace: namespaces.join(\".\")\n            }, handleObjIn );\n\n            // Init the event handler queue if we're the first\n            if ( !(handlers = events[ type ]) ) {\n                handlers = events[ type ] = [];\n                handlers.delegateCount = 0;\n\n                // Only use addEventListener/attachEvent if the special events handler returns false\n                if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n                    // Bind the global event handler to the element\n                    if ( elem.addEventListener ) {\n                        elem.addEventListener( type, eventHandle, false );\n\n                    } else if ( elem.attachEvent ) {\n                        elem.attachEvent( \"on\" + type, eventHandle );\n                    }\n                }\n            }\n\n            if ( special.add ) {\n                special.add.call( elem, handleObj );\n\n                if ( !handleObj.handler.guid ) {\n                    handleObj.handler.guid = handler.guid;\n                }\n            }\n\n            // Add to the element's handler list, delegates in front\n            if ( selector ) {\n                handlers.splice( handlers.delegateCount++, 0, handleObj );\n            } else {\n                handlers.push( handleObj );\n            }\n\n            // Keep track of which events have ever been used, for event optimization\n            jQuery.event.global[ type ] = true;\n        }\n\n        // Nullify elem to prevent memory leaks in IE\n        elem = null;\n    },\n\n    // Detach an event or set of events from an element\n    remove: function( elem, types, handler, selector, mappedTypes ) {\n        var j, handleObj, tmp,\n            origCount, t, events,\n            special, handlers, type,\n            namespaces, origType,\n            elemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n        if ( !elemData || !(events = elemData.events) ) {\n            return;\n        }\n\n        // Once for each type.namespace in types; type may be omitted\n        types = ( types || \"\" ).match( core_rnotwhite ) || [\"\"];\n        t = types.length;\n        while ( t-- ) {\n            tmp = rtypenamespace.exec( types[t] ) || [];\n            type = origType = tmp[1];\n            namespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n            // Unbind all events (on this namespace, if provided) for the element\n            if ( !type ) {\n                for ( type in events ) {\n                    jQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n                }\n                continue;\n            }\n\n            special = jQuery.event.special[ type ] || {};\n            type = ( selector ? special.delegateType : special.bindType ) || type;\n            handlers = events[ type ] || [];\n            tmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n            // Remove matching events\n            origCount = j = handlers.length;\n            while ( j-- ) {\n                handleObj = handlers[ j ];\n\n                if ( ( mappedTypes || origType === handleObj.origType ) &&\n                    ( !handler || handler.guid === handleObj.guid ) &&\n                    ( !tmp || tmp.test( handleObj.namespace ) ) &&\n                    ( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n                    handlers.splice( j, 1 );\n\n                    if ( handleObj.selector ) {\n                        handlers.delegateCount--;\n                    }\n                    if ( special.remove ) {\n                        special.remove.call( elem, handleObj );\n                    }\n                }\n            }\n\n            // Remove generic event handler if we removed something and no more handlers exist\n            // (avoids potential for endless recursion during removal of special event handlers)\n            if ( origCount && !handlers.length ) {\n                if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n                    jQuery.removeEvent( elem, type, elemData.handle );\n                }\n\n                delete events[ type ];\n            }\n        }\n\n        // Remove the expando if it's no longer used\n        if ( jQuery.isEmptyObject( events ) ) {\n            delete elemData.handle;\n\n            // removeData also checks for emptiness and clears the expando if empty\n            // so use it instead of delete\n            jQuery._removeData( elem, \"events\" );\n        }\n    },\n\n    trigger: function( event, data, elem, onlyHandlers ) {\n        var handle, ontype, cur,\n            bubbleType, special, tmp, i,\n            eventPath = [ elem || document ],\n            type = core_hasOwn.call( event, \"type\" ) ? event.type : event,\n            namespaces = core_hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n        cur = tmp = elem = elem || document;\n\n        // Don't do events on text and comment nodes\n        if ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n            return;\n        }\n\n        // focus/blur morphs to focusin/out; ensure we're not firing them right now\n        if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n            return;\n        }\n\n        if ( type.indexOf(\".\") >= 0 ) {\n            // Namespaced trigger; create a regexp to match event type in handle()\n            namespaces = type.split(\".\");\n            type = namespaces.shift();\n            namespaces.sort();\n        }\n        ontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n        // Caller can pass in a jQuery.Event object, Object, or just an event type string\n        event = event[ jQuery.expando ] ?\n            event :\n            new jQuery.Event( type, typeof event === \"object\" && event );\n\n        // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n        event.isTrigger = onlyHandlers ? 2 : 3;\n        event.namespace = namespaces.join(\".\");\n        event.namespace_re = event.namespace ?\n            new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n            null;\n\n        // Clean up the event in case it is being reused\n        event.result = undefined;\n        if ( !event.target ) {\n            event.target = elem;\n        }\n\n        // Clone any incoming data and prepend the event, creating the handler arg list\n        data = data == null ?\n            [ event ] :\n            jQuery.makeArray( data, [ event ] );\n\n        // Allow special events to draw outside the lines\n        special = jQuery.event.special[ type ] || {};\n        if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n            return;\n        }\n\n        // Determine event propagation path in advance, per W3C events spec (#9951)\n        // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n        if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n            bubbleType = special.delegateType || type;\n            if ( !rfocusMorph.test( bubbleType + type ) ) {\n                cur = cur.parentNode;\n            }\n            for ( ; cur; cur = cur.parentNode ) {\n                eventPath.push( cur );\n                tmp = cur;\n            }\n\n            // Only add window if we got to document (e.g., not plain obj or detached DOM)\n            if ( tmp === (elem.ownerDocument || document) ) {\n                eventPath.push( tmp.defaultView || tmp.parentWindow || window );\n            }\n        }\n\n        // Fire handlers on the event path\n        i = 0;\n        while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n            event.type = i > 1 ?\n                bubbleType :\n                special.bindType || type;\n\n            // jQuery handler\n            handle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n            if ( handle ) {\n                handle.apply( cur, data );\n            }\n\n            // Native handler\n            handle = ontype && cur[ ontype ];\n            if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {\n                event.preventDefault();\n            }\n        }\n        event.type = type;\n\n        // If nobody prevented the default action, do it now\n        if ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n            if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n                jQuery.acceptData( elem ) ) {\n\n                // Call a native DOM method on the target with the same name name as the event.\n                // Can't use an .isFunction() check here because IE6/7 fails that test.\n                // Don't do default actions on window, that's where global variables be (#6170)\n                if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\n                    // Don't re-trigger an onFOO event when we call its FOO() method\n                    tmp = elem[ ontype ];\n\n                    if ( tmp ) {\n                        elem[ ontype ] = null;\n                    }\n\n                    // Prevent re-triggering of the same event, since we already bubbled it above\n                    jQuery.event.triggered = type;\n                    try {\n                        elem[ type ]();\n                    } catch ( e ) {\n                        // IE<9 dies on focus/blur to hidden element (#1486,#12518)\n                        // only reproducible on winXP IE8 native, not IE9 in IE8 mode\n                    }\n                    jQuery.event.triggered = undefined;\n\n                    if ( tmp ) {\n                        elem[ ontype ] = tmp;\n                    }\n                }\n            }\n        }\n\n        return event.result;\n    },\n\n    dispatch: function( event ) {\n\n        // Make a writable jQuery.Event from the native event object\n        event = jQuery.event.fix( event );\n\n        var i, ret, handleObj, matched, j,\n            handlerQueue = [],\n            args = core_slice.call( arguments ),\n            handlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n            special = jQuery.event.special[ event.type ] || {};\n\n        // Use the fix-ed jQuery.Event rather than the (read-only) native event\n        args[0] = event;\n        event.delegateTarget = this;\n\n        // Call the preDispatch hook for the mapped type, and let it bail if desired\n        if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n            return;\n        }\n\n        // Determine handlers\n        handlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n        // Run delegates first; they may want to stop propagation beneath us\n        i = 0;\n        while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n            event.currentTarget = matched.elem;\n\n            j = 0;\n            while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n                // Triggered event must either 1) have no namespace, or\n                // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n                if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n                    event.handleObj = handleObj;\n                    event.data = handleObj.data;\n\n                    ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n                            .apply( matched.elem, args );\n\n                    if ( ret !== undefined ) {\n                        if ( (event.result = ret) === false ) {\n                            event.preventDefault();\n                            event.stopPropagation();\n                        }\n                    }\n                }\n            }\n        }\n\n        // Call the postDispatch hook for the mapped type\n        if ( special.postDispatch ) {\n            special.postDispatch.call( this, event );\n        }\n\n        return event.result;\n    },\n\n    handlers: function( event, handlers ) {\n        var sel, handleObj, matches, i,\n            handlerQueue = [],\n            delegateCount = handlers.delegateCount,\n            cur = event.target;\n\n        // Find delegate handlers\n        // Black-hole SVG <use> instance trees (#13180)\n        // Avoid non-left-click bubbling in Firefox (#3861)\n        if ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n            /* jshint eqeqeq: false */\n            for ( ; cur != this; cur = cur.parentNode || this ) {\n                /* jshint eqeqeq: true */\n\n                // Don't check non-elements (#13208)\n                // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n                if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n                    matches = [];\n                    for ( i = 0; i < delegateCount; i++ ) {\n                        handleObj = handlers[ i ];\n\n                        // Don't conflict with Object.prototype properties (#13203)\n                        sel = handleObj.selector + \" \";\n\n                        if ( matches[ sel ] === undefined ) {\n                            matches[ sel ] = handleObj.needsContext ?\n                                jQuery( sel, this ).index( cur ) >= 0 :\n                                jQuery.find( sel, this, null, [ cur ] ).length;\n                        }\n                        if ( matches[ sel ] ) {\n                            matches.push( handleObj );\n                        }\n                    }\n                    if ( matches.length ) {\n                        handlerQueue.push({ elem: cur, handlers: matches });\n                    }\n                }\n            }\n        }\n\n        // Add the remaining (directly-bound) handlers\n        if ( delegateCount < handlers.length ) {\n            handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n        }\n\n        return handlerQueue;\n    },\n\n    fix: function( event ) {\n        if ( event[ jQuery.expando ] ) {\n            return event;\n        }\n\n        // Create a writable copy of the event object and normalize some properties\n        var i, prop, copy,\n            type = event.type,\n            originalEvent = event,\n            fixHook = this.fixHooks[ type ];\n\n        if ( !fixHook ) {\n            this.fixHooks[ type ] = fixHook =\n                rmouseEvent.test( type ) ? this.mouseHooks :\n                rkeyEvent.test( type ) ? this.keyHooks :\n                {};\n        }\n        copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n        event = new jQuery.Event( originalEvent );\n\n        i = copy.length;\n        while ( i-- ) {\n            prop = copy[ i ];\n            event[ prop ] = originalEvent[ prop ];\n        }\n\n        // Support: IE<9\n        // Fix target property (#1925)\n        if ( !event.target ) {\n            event.target = originalEvent.srcElement || document;\n        }\n\n        // Support: Chrome 23+, Safari?\n        // Target should not be a text node (#504, #13143)\n        if ( event.target.nodeType === 3 ) {\n            event.target = event.target.parentNode;\n        }\n\n        // Support: IE<9\n        // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)\n        event.metaKey = !!event.metaKey;\n\n        return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n    },\n\n    // Includes some event props shared by KeyEvent and MouseEvent\n    props: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n    fixHooks: {},\n\n    keyHooks: {\n        props: \"char charCode key keyCode\".split(\" \"),\n        filter: function( event, original ) {\n\n            // Add which for key events\n            if ( event.which == null ) {\n                event.which = original.charCode != null ? original.charCode : original.keyCode;\n            }\n\n            return event;\n        }\n    },\n\n    mouseHooks: {\n        props: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n        filter: function( event, original ) {\n            var body, eventDoc, doc,\n                button = original.button,\n                fromElement = original.fromElement;\n\n            // Calculate pageX/Y if missing and clientX/Y available\n            if ( event.pageX == null && original.clientX != null ) {\n                eventDoc = event.target.ownerDocument || document;\n                doc = eventDoc.documentElement;\n                body = eventDoc.body;\n\n                event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n                event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n            }\n\n            // Add relatedTarget, if necessary\n            if ( !event.relatedTarget && fromElement ) {\n                event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n            }\n\n            // Add which for click: 1 === left; 2 === middle; 3 === right\n            // Note: button is not normalized, so don't use it\n            if ( !event.which && button !== undefined ) {\n                event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n            }\n\n            return event;\n        }\n    },\n\n    special: {\n        load: {\n            // Prevent triggered image.load events from bubbling to window.load\n            noBubble: true\n        },\n        focus: {\n            // Fire native event if possible so blur/focus sequence is correct\n            trigger: function() {\n                if ( this !== safeActiveElement() && this.focus ) {\n                    try {\n                        this.focus();\n                        return false;\n                    } catch ( e ) {\n                        // Support: IE<9\n                        // If we error on focus to hidden element (#1486, #12518),\n                        // let .trigger() run the handlers\n                    }\n                }\n            },\n            delegateType: \"focusin\"\n        },\n        blur: {\n            trigger: function() {\n                if ( this === safeActiveElement() && this.blur ) {\n                    this.blur();\n                    return false;\n                }\n            },\n            delegateType: \"focusout\"\n        },\n        click: {\n            // For checkbox, fire native event so checked state will be right\n            trigger: function() {\n                if ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n                    this.click();\n                    return false;\n                }\n            },\n\n            // For cross-browser consistency, don't fire native .click() on links\n            _default: function( event ) {\n                return jQuery.nodeName( event.target, \"a\" );\n            }\n        },\n\n        beforeunload: {\n            postDispatch: function( event ) {\n\n                // Even when returnValue equals to undefined Firefox will still show alert\n                if ( event.result !== undefined ) {\n                    event.originalEvent.returnValue = event.result;\n                }\n            }\n        }\n    },\n\n    simulate: function( type, elem, event, bubble ) {\n        // Piggyback on a donor event to simulate a different one.\n        // Fake originalEvent to avoid donor's stopPropagation, but if the\n        // simulated event prevents default then we do the same on the donor.\n        var e = jQuery.extend(\n            new jQuery.Event(),\n            event,\n            {\n                type: type,\n                isSimulated: true,\n                originalEvent: {}\n            }\n        );\n        if ( bubble ) {\n            jQuery.event.trigger( e, null, elem );\n        } else {\n            jQuery.event.dispatch.call( elem, e );\n        }\n        if ( e.isDefaultPrevented() ) {\n            event.preventDefault();\n        }\n    }\n};\n\njQuery.removeEvent = document.removeEventListener ?\n    function( elem, type, handle ) {\n        if ( elem.removeEventListener ) {\n            elem.removeEventListener( type, handle, false );\n        }\n    } :\n    function( elem, type, handle ) {\n        var name = \"on\" + type;\n\n        if ( elem.detachEvent ) {\n\n            // #8545, #7054, preventing memory leaks for custom events in IE6-8\n            // detachEvent needed property on element, by name of that event, to properly expose it to GC\n            if ( typeof elem[ name ] === core_strundefined ) {\n                elem[ name ] = null;\n            }\n\n            elem.detachEvent( name, handle );\n        }\n    };\n\njQuery.Event = function( src, props ) {\n    // Allow instantiation without the 'new' keyword\n    if ( !(this instanceof jQuery.Event) ) {\n        return new jQuery.Event( src, props );\n    }\n\n    // Event object\n    if ( src && src.type ) {\n        this.originalEvent = src;\n        this.type = src.type;\n\n        // Events bubbling up the document may have been marked as prevented\n        // by a handler lower down the tree; reflect the correct value.\n        this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||\n            src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;\n\n    // Event type\n    } else {\n        this.type = src;\n    }\n\n    // Put explicitly provided properties onto the event object\n    if ( props ) {\n        jQuery.extend( this, props );\n    }\n\n    // Create a timestamp if incoming event doesn't have one\n    this.timeStamp = src && src.timeStamp || jQuery.now();\n\n    // Mark it as fixed\n    this[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n    isDefaultPrevented: returnFalse,\n    isPropagationStopped: returnFalse,\n    isImmediatePropagationStopped: returnFalse,\n\n    preventDefault: function() {\n        var e = this.originalEvent;\n\n        this.isDefaultPrevented = returnTrue;\n        if ( !e ) {\n            return;\n        }\n\n        // If preventDefault exists, run it on the original event\n        if ( e.preventDefault ) {\n            e.preventDefault();\n\n        // Support: IE\n        // Otherwise set the returnValue property of the original event to false\n        } else {\n            e.returnValue = false;\n        }\n    },\n    stopPropagation: function() {\n        var e = this.originalEvent;\n\n        this.isPropagationStopped = returnTrue;\n        if ( !e ) {\n            return;\n        }\n        // If stopPropagation exists, run it on the original event\n        if ( e.stopPropagation ) {\n            e.stopPropagation();\n        }\n\n        // Support: IE\n        // Set the cancelBubble property of the original event to true\n        e.cancelBubble = true;\n    },\n    stopImmediatePropagation: function() {\n        this.isImmediatePropagationStopped = returnTrue;\n        this.stopPropagation();\n    }\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n    mouseenter: \"mouseover\",\n    mouseleave: \"mouseout\"\n}, function( orig, fix ) {\n    jQuery.event.special[ orig ] = {\n        delegateType: fix,\n        bindType: fix,\n\n        handle: function( event ) {\n            var ret,\n                target = this,\n                related = event.relatedTarget,\n                handleObj = event.handleObj;\n\n            // For mousenter/leave call the handler if related is outside the target.\n            // NB: No relatedTarget if the mouse left/entered the browser window\n            if ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n                event.type = handleObj.origType;\n                ret = handleObj.handler.apply( this, arguments );\n                event.type = fix;\n            }\n            return ret;\n        }\n    };\n});\n\n// IE submit delegation\nif ( !jQuery.support.submitBubbles ) {\n\n    jQuery.event.special.submit = {\n        setup: function() {\n            // Only need this for delegated form submit events\n            if ( jQuery.nodeName( this, \"form\" ) ) {\n                return false;\n            }\n\n            // Lazy-add a submit handler when a descendant form may potentially be submitted\n            jQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n                // Node name check avoids a VML-related crash in IE (#9807)\n                var elem = e.target,\n                    form = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n                if ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n                    jQuery.event.add( form, \"submit._submit\", function( event ) {\n                        event._submit_bubble = true;\n                    });\n                    jQuery._data( form, \"submitBubbles\", true );\n                }\n            });\n            // return undefined since we don't need an event listener\n        },\n\n        postDispatch: function( event ) {\n            // If form was submitted by the user, bubble the event up the tree\n            if ( event._submit_bubble ) {\n                delete event._submit_bubble;\n                if ( this.parentNode && !event.isTrigger ) {\n                    jQuery.event.simulate( \"submit\", this.parentNode, event, true );\n                }\n            }\n        },\n\n        teardown: function() {\n            // Only need this for delegated form submit events\n            if ( jQuery.nodeName( this, \"form\" ) ) {\n                return false;\n            }\n\n            // Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n            jQuery.event.remove( this, \"._submit\" );\n        }\n    };\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !jQuery.support.changeBubbles ) {\n\n    jQuery.event.special.change = {\n\n        setup: function() {\n\n            if ( rformElems.test( this.nodeName ) ) {\n                // IE doesn't fire change on a check/radio until blur; trigger it on click\n                // after a propertychange. Eat the blur-change in special.change.handle.\n                // This still fires onchange a second time for check/radio after blur.\n                if ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n                    jQuery.event.add( this, \"propertychange._change\", function( event ) {\n                        if ( event.originalEvent.propertyName === \"checked\" ) {\n                            this._just_changed = true;\n                        }\n                    });\n                    jQuery.event.add( this, \"click._change\", function( event ) {\n                        if ( this._just_changed && !event.isTrigger ) {\n                            this._just_changed = false;\n                        }\n                        // Allow triggered, simulated change events (#11500)\n                        jQuery.event.simulate( \"change\", this, event, true );\n                    });\n                }\n                return false;\n            }\n            // Delegated event; lazy-add a change handler on descendant inputs\n            jQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n                var elem = e.target;\n\n                if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n                    jQuery.event.add( elem, \"change._change\", function( event ) {\n                        if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n                            jQuery.event.simulate( \"change\", this.parentNode, event, true );\n                        }\n                    });\n                    jQuery._data( elem, \"changeBubbles\", true );\n                }\n            });\n        },\n\n        handle: function( event ) {\n            var elem = event.target;\n\n            // Swallow native change events from checkbox/radio, we already triggered them above\n            if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n                return event.handleObj.handler.apply( this, arguments );\n            }\n        },\n\n        teardown: function() {\n            jQuery.event.remove( this, \"._change\" );\n\n            return !rformElems.test( this.nodeName );\n        }\n    };\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !jQuery.support.focusinBubbles ) {\n    jQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n        // Attach a single capturing handler while someone wants focusin/focusout\n        var attaches = 0,\n            handler = function( event ) {\n                jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n            };\n\n        jQuery.event.special[ fix ] = {\n            setup: function() {\n                if ( attaches++ === 0 ) {\n                    document.addEventListener( orig, handler, true );\n                }\n            },\n            teardown: function() {\n                if ( --attaches === 0 ) {\n                    document.removeEventListener( orig, handler, true );\n                }\n            }\n        };\n    });\n}\n\njQuery.fn.extend({\n\n    on: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n        var type, origFn;\n\n        // Types can be a map of types/handlers\n        if ( typeof types === \"object\" ) {\n            // ( types-Object, selector, data )\n            if ( typeof selector !== \"string\" ) {\n                // ( types-Object, data )\n                data = data || selector;\n                selector = undefined;\n            }\n            for ( type in types ) {\n                this.on( type, selector, data, types[ type ], one );\n            }\n            return this;\n        }\n\n        if ( data == null && fn == null ) {\n            // ( types, fn )\n            fn = selector;\n            data = selector = undefined;\n        } else if ( fn == null ) {\n            if ( typeof selector === \"string\" ) {\n                // ( types, selector, fn )\n                fn = data;\n                data = undefined;\n            } else {\n                // ( types, data, fn )\n                fn = data;\n                data = selector;\n                selector = undefined;\n            }\n        }\n        if ( fn === false ) {\n            fn = returnFalse;\n        } else if ( !fn ) {\n            return this;\n        }\n\n        if ( one === 1 ) {\n            origFn = fn;\n            fn = function( event ) {\n                // Can use an empty set, since event contains the info\n                jQuery().off( event );\n                return origFn.apply( this, arguments );\n            };\n            // Use same guid so caller can remove using origFn\n            fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n        }\n        return this.each( function() {\n            jQuery.event.add( this, types, fn, data, selector );\n        });\n    },\n    one: function( types, selector, data, fn ) {\n        return this.on( types, selector, data, fn, 1 );\n    },\n    off: function( types, selector, fn ) {\n        var handleObj, type;\n        if ( types && types.preventDefault && types.handleObj ) {\n            // ( event )  dispatched jQuery.Event\n            handleObj = types.handleObj;\n            jQuery( types.delegateTarget ).off(\n                handleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n                handleObj.selector,\n                handleObj.handler\n            );\n            return this;\n        }\n        if ( typeof types === \"object\" ) {\n            // ( types-object [, selector] )\n            for ( type in types ) {\n                this.off( type, selector, types[ type ] );\n            }\n            return this;\n        }\n        if ( selector === false || typeof selector === \"function\" ) {\n            // ( types [, fn] )\n            fn = selector;\n            selector = undefined;\n        }\n        if ( fn === false ) {\n            fn = returnFalse;\n        }\n        return this.each(function() {\n            jQuery.event.remove( this, types, fn, selector );\n        });\n    },\n\n    trigger: function( type, data ) {\n        return this.each(function() {\n            jQuery.event.trigger( type, data, this );\n        });\n    },\n    triggerHandler: function( type, data ) {\n        var elem = this[0];\n        if ( elem ) {\n            return jQuery.event.trigger( type, data, elem, true );\n        }\n    }\n});\nvar isSimple = /^.[^:#\\[\\.,]*$/,\n    rparentsprev = /^(?:parents|prev(?:Until|All))/,\n    rneedsContext = jQuery.expr.match.needsContext,\n    // methods guaranteed to produce a unique set when starting from a unique set\n    guaranteedUnique = {\n        children: true,\n        contents: true,\n        next: true,\n        prev: true\n    };\n\njQuery.fn.extend({\n    find: function( selector ) {\n        var i,\n            ret = [],\n            self = this,\n            len = self.length;\n\n        if ( typeof selector !== \"string\" ) {\n            return this.pushStack( jQuery( selector ).filter(function() {\n                for ( i = 0; i < len; i++ ) {\n                    if ( jQuery.contains( self[ i ], this ) ) {\n                        return true;\n                    }\n                }\n            }) );\n        }\n\n        for ( i = 0; i < len; i++ ) {\n            jQuery.find( selector, self[ i ], ret );\n        }\n\n        // Needed because $( selector, context ) becomes $( context ).find( selector )\n        ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n        ret.selector = this.selector ? this.selector + \" \" + selector : selector;\n        return ret;\n    },\n\n    has: function( target ) {\n        var i,\n            targets = jQuery( target, this ),\n            len = targets.length;\n\n        return this.filter(function() {\n            for ( i = 0; i < len; i++ ) {\n                if ( jQuery.contains( this, targets[i] ) ) {\n                    return true;\n                }\n            }\n        });\n    },\n\n    not: function( selector ) {\n        return this.pushStack( winnow(this, selector || [], true) );\n    },\n\n    filter: function( selector ) {\n        return this.pushStack( winnow(this, selector || [], false) );\n    },\n\n    is: function( selector ) {\n        return !!winnow(\n            this,\n\n            // If this is a positional/relative selector, check membership in the returned set\n            // so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n            typeof selector === \"string\" && rneedsContext.test( selector ) ?\n                jQuery( selector ) :\n                selector || [],\n            false\n        ).length;\n    },\n\n    closest: function( selectors, context ) {\n        var cur,\n            i = 0,\n            l = this.length,\n            ret = [],\n            pos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n                jQuery( selectors, context || this.context ) :\n                0;\n\n        for ( ; i < l; i++ ) {\n            for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n                // Always skip document fragments\n                if ( cur.nodeType < 11 && (pos ?\n                    pos.index(cur) > -1 :\n\n                    // Don't pass non-elements to Sizzle\n                    cur.nodeType === 1 &&\n                        jQuery.find.matchesSelector(cur, selectors)) ) {\n\n                    cur = ret.push( cur );\n                    break;\n                }\n            }\n        }\n\n        return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );\n    },\n\n    // Determine the position of an element within\n    // the matched set of elements\n    index: function( elem ) {\n\n        // No argument, return index in parent\n        if ( !elem ) {\n            return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n        }\n\n        // index in selector\n        if ( typeof elem === \"string\" ) {\n            return jQuery.inArray( this[0], jQuery( elem ) );\n        }\n\n        // Locate the position of the desired element\n        return jQuery.inArray(\n            // If it receives a jQuery object, the first element is used\n            elem.jquery ? elem[0] : elem, this );\n    },\n\n    add: function( selector, context ) {\n        var set = typeof selector === \"string\" ?\n                jQuery( selector, context ) :\n                jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),\n            all = jQuery.merge( this.get(), set );\n\n        return this.pushStack( jQuery.unique(all) );\n    },\n\n    addBack: function( selector ) {\n        return this.add( selector == null ?\n            this.prevObject : this.prevObject.filter(selector)\n        );\n    }\n});\n\nfunction sibling( cur, dir ) {\n    do {\n        cur = cur[ dir ];\n    } while ( cur && cur.nodeType !== 1 );\n\n    return cur;\n}\n\njQuery.each({\n    parent: function( elem ) {\n        var parent = elem.parentNode;\n        return parent && parent.nodeType !== 11 ? parent : null;\n    },\n    parents: function( elem ) {\n        return jQuery.dir( elem, \"parentNode\" );\n    },\n    parentsUntil: function( elem, i, until ) {\n        return jQuery.dir( elem, \"parentNode\", until );\n    },\n    next: function( elem ) {\n        return sibling( elem, \"nextSibling\" );\n    },\n    prev: function( elem ) {\n        return sibling( elem, \"previousSibling\" );\n    },\n    nextAll: function( elem ) {\n        return jQuery.dir( elem, \"nextSibling\" );\n    },\n    prevAll: function( elem ) {\n        return jQuery.dir( elem, \"previousSibling\" );\n    },\n    nextUntil: function( elem, i, until ) {\n        return jQuery.dir( elem, \"nextSibling\", until );\n    },\n    prevUntil: function( elem, i, until ) {\n        return jQuery.dir( elem, \"previousSibling\", until );\n    },\n    siblings: function( elem ) {\n        return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n    },\n    children: function( elem ) {\n        return jQuery.sibling( elem.firstChild );\n    },\n    contents: function( elem ) {\n        return jQuery.nodeName( elem, \"iframe\" ) ?\n            elem.contentDocument || elem.contentWindow.document :\n            jQuery.merge( [], elem.childNodes );\n    }\n}, function( name, fn ) {\n    jQuery.fn[ name ] = function( until, selector ) {\n        var ret = jQuery.map( this, fn, until );\n\n        if ( name.slice( -5 ) !== \"Until\" ) {\n            selector = until;\n        }\n\n        if ( selector && typeof selector === \"string\" ) {\n            ret = jQuery.filter( selector, ret );\n        }\n\n        if ( this.length > 1 ) {\n            // Remove duplicates\n            if ( !guaranteedUnique[ name ] ) {\n                ret = jQuery.unique( ret );\n            }\n\n            // Reverse order for parents* and prev-derivatives\n            if ( rparentsprev.test( name ) ) {\n                ret = ret.reverse();\n            }\n        }\n\n        return this.pushStack( ret );\n    };\n});\n\njQuery.extend({\n    filter: function( expr, elems, not ) {\n        var elem = elems[ 0 ];\n\n        if ( not ) {\n            expr = \":not(\" + expr + \")\";\n        }\n\n        return elems.length === 1 && elem.nodeType === 1 ?\n            jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n            jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n                return elem.nodeType === 1;\n            }));\n    },\n\n    dir: function( elem, dir, until ) {\n        var matched = [],\n            cur = elem[ dir ];\n\n        while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n            if ( cur.nodeType === 1 ) {\n                matched.push( cur );\n            }\n            cur = cur[dir];\n        }\n        return matched;\n    },\n\n    sibling: function( n, elem ) {\n        var r = [];\n\n        for ( ; n; n = n.nextSibling ) {\n            if ( n.nodeType === 1 && n !== elem ) {\n                r.push( n );\n            }\n        }\n\n        return r;\n    }\n});\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n    if ( jQuery.isFunction( qualifier ) ) {\n        return jQuery.grep( elements, function( elem, i ) {\n            /* jshint -W018 */\n            return !!qualifier.call( elem, i, elem ) !== not;\n        });\n\n    }\n\n    if ( qualifier.nodeType ) {\n        return jQuery.grep( elements, function( elem ) {\n            return ( elem === qualifier ) !== not;\n        });\n\n    }\n\n    if ( typeof qualifier === \"string\" ) {\n        if ( isSimple.test( qualifier ) ) {\n            return jQuery.filter( qualifier, elements, not );\n        }\n\n        qualifier = jQuery.filter( qualifier, elements );\n    }\n\n    return jQuery.grep( elements, function( elem ) {\n        return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n    });\n}\nfunction createSafeFragment( document ) {\n    var list = nodeNames.split( \"|\" ),\n        safeFrag = document.createDocumentFragment();\n\n    if ( safeFrag.createElement ) {\n        while ( list.length ) {\n            safeFrag.createElement(\n                list.pop()\n            );\n        }\n    }\n    return safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n        \"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n    rinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n    rnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n    rleadingWhitespace = /^\\s+/,\n    rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n    rtagName = /<([\\w:]+)/,\n    rtbody = /<tbody/i,\n    rhtml = /<|&#?\\w+;/,\n    rnoInnerhtml = /<(?:script|style|link)/i,\n    manipulation_rcheckableType = /^(?:checkbox|radio)$/i,\n    // checked=\"checked\" or checked\n    rchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n    rscriptType = /^$|\\/(?:java|ecma)script/i,\n    rscriptTypeMasked = /^true\\/(.*)/,\n    rcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n    // We have to close these tags to support XHTML (#13200)\n    wrapMap = {\n        option: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n        legend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n        area: [ 1, \"<map>\", \"</map>\" ],\n        param: [ 1, \"<object>\", \"</object>\" ],\n        thead: [ 1, \"<table>\", \"</table>\" ],\n        tr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n        col: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n        td: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n        // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n        // unless wrapped in a div with non-breaking characters in front of it.\n        _default: jQuery.support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X<div>\", \"</div>\"  ]\n    },\n    safeFragment = createSafeFragment( document ),\n    fragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\njQuery.fn.extend({\n    text: function( value ) {\n        return jQuery.access( this, function( value ) {\n            return value === undefined ?\n                jQuery.text( this ) :\n                this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n        }, null, value, arguments.length );\n    },\n\n    append: function() {\n        return this.domManip( arguments, function( elem ) {\n            if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n                var target = manipulationTarget( this, elem );\n                target.appendChild( elem );\n            }\n        });\n    },\n\n    prepend: function() {\n        return this.domManip( arguments, function( elem ) {\n            if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n                var target = manipulationTarget( this, elem );\n                target.insertBefore( elem, target.firstChild );\n            }\n        });\n    },\n\n    before: function() {\n        return this.domManip( arguments, function( elem ) {\n            if ( this.parentNode ) {\n                this.parentNode.insertBefore( elem, this );\n            }\n        });\n    },\n\n    after: function() {\n        return this.domManip( arguments, function( elem ) {\n            if ( this.parentNode ) {\n                this.parentNode.insertBefore( elem, this.nextSibling );\n            }\n        });\n    },\n\n    // keepData is for internal use only--do not document\n    remove: function( selector, keepData ) {\n        var elem,\n            elems = selector ? jQuery.filter( selector, this ) : this,\n            i = 0;\n\n        for ( ; (elem = elems[i]) != null; i++ ) {\n\n            if ( !keepData && elem.nodeType === 1 ) {\n                jQuery.cleanData( getAll( elem ) );\n            }\n\n            if ( elem.parentNode ) {\n                if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n                    setGlobalEval( getAll( elem, \"script\" ) );\n                }\n                elem.parentNode.removeChild( elem );\n            }\n        }\n\n        return this;\n    },\n\n    empty: function() {\n        var elem,\n            i = 0;\n\n        for ( ; (elem = this[i]) != null; i++ ) {\n            // Remove element nodes and prevent memory leaks\n            if ( elem.nodeType === 1 ) {\n                jQuery.cleanData( getAll( elem, false ) );\n            }\n\n            // Remove any remaining nodes\n            while ( elem.firstChild ) {\n                elem.removeChild( elem.firstChild );\n            }\n\n            // If this is a select, ensure that it displays empty (#12336)\n            // Support: IE<9\n            if ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n                elem.options.length = 0;\n            }\n        }\n\n        return this;\n    },\n\n    clone: function( dataAndEvents, deepDataAndEvents ) {\n        dataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n        deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n        return this.map( function () {\n            return jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n        });\n    },\n\n    html: function( value ) {\n        return jQuery.access( this, function( value ) {\n            var elem = this[0] || {},\n                i = 0,\n                l = this.length;\n\n            if ( value === undefined ) {\n                return elem.nodeType === 1 ?\n                    elem.innerHTML.replace( rinlinejQuery, \"\" ) :\n                    undefined;\n            }\n\n            // See if we can take a shortcut and just use innerHTML\n            if ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n                ( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n                ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n                !wrapMap[ ( rtagName.exec( value ) || [\"\", \"\"] )[1].toLowerCase() ] ) {\n\n                value = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n                try {\n                    for (; i < l; i++ ) {\n                        // Remove element nodes and prevent memory leaks\n                        elem = this[i] || {};\n                        if ( elem.nodeType === 1 ) {\n                            jQuery.cleanData( getAll( elem, false ) );\n                            elem.innerHTML = value;\n                        }\n                    }\n\n                    elem = 0;\n\n                // If using innerHTML throws an exception, use the fallback method\n                } catch(e) {}\n            }\n\n            if ( elem ) {\n                this.empty().append( value );\n            }\n        }, null, value, arguments.length );\n    },\n\n    replaceWith: function() {\n        var\n            // Snapshot the DOM in case .domManip sweeps something relevant into its fragment\n            args = jQuery.map( this, function( elem ) {\n                return [ elem.nextSibling, elem.parentNode ];\n            }),\n            i = 0;\n\n        // Make the changes, replacing each context element with the new content\n        this.domManip( arguments, function( elem ) {\n            var next = args[ i++ ],\n                parent = args[ i++ ];\n\n            if ( parent ) {\n                // Don't use the snapshot next if it has moved (#13810)\n                if ( next && next.parentNode !== parent ) {\n                    next = this.nextSibling;\n                }\n                jQuery( this ).remove();\n                parent.insertBefore( elem, next );\n            }\n        // Allow new content to include elements from the context set\n        }, true );\n\n        // Force removal if there was no new content (e.g., from empty arguments)\n        return i ? this : this.remove();\n    },\n\n    detach: function( selector ) {\n        return this.remove( selector, true );\n    },\n\n    domManip: function( args, callback, allowIntersection ) {\n\n        // Flatten any nested arrays\n        args = core_concat.apply( [], args );\n\n        var first, node, hasScripts,\n            scripts, doc, fragment,\n            i = 0,\n            l = this.length,\n            set = this,\n            iNoClone = l - 1,\n            value = args[0],\n            isFunction = jQuery.isFunction( value );\n\n        // We can't cloneNode fragments that contain checked, in WebKit\n        if ( isFunction || !( l <= 1 || typeof value !== \"string\" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {\n            return this.each(function( index ) {\n                var self = set.eq( index );\n                if ( isFunction ) {\n                    args[0] = value.call( this, index, self.html() );\n                }\n                self.domManip( args, callback, allowIntersection );\n            });\n        }\n\n        if ( l ) {\n            fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this );\n            first = fragment.firstChild;\n\n            if ( fragment.childNodes.length === 1 ) {\n                fragment = first;\n            }\n\n            if ( first ) {\n                scripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n                hasScripts = scripts.length;\n\n                // Use the original fragment for the last item instead of the first because it can end up\n                // being emptied incorrectly in certain situations (#8070).\n                for ( ; i < l; i++ ) {\n                    node = fragment;\n\n                    if ( i !== iNoClone ) {\n                        node = jQuery.clone( node, true, true );\n\n                        // Keep references to cloned scripts for later restoration\n                        if ( hasScripts ) {\n                            jQuery.merge( scripts, getAll( node, \"script\" ) );\n                        }\n                    }\n\n                    callback.call( this[i], node, i );\n                }\n\n                if ( hasScripts ) {\n                    doc = scripts[ scripts.length - 1 ].ownerDocument;\n\n                    // Reenable scripts\n                    jQuery.map( scripts, restoreScript );\n\n                    // Evaluate executable scripts on first document insertion\n                    for ( i = 0; i < hasScripts; i++ ) {\n                        node = scripts[ i ];\n                        if ( rscriptType.test( node.type || \"\" ) &&\n                            !jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n                            if ( node.src ) {\n                                // Hope ajax is available...\n                                jQuery._evalUrl( node.src );\n                            } else {\n                                jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n                            }\n                        }\n                    }\n                }\n\n                // Fix #11809: Avoid leaking memory\n                fragment = first = null;\n            }\n        }\n\n        return this;\n    }\n});\n\n// Support: IE<8\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n    return jQuery.nodeName( elem, \"table\" ) &&\n        jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, \"tr\" ) ?\n\n        elem.getElementsByTagName(\"tbody\")[0] ||\n            elem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n        elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n    elem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n    return elem;\n}\nfunction restoreScript( elem ) {\n    var match = rscriptTypeMasked.exec( elem.type );\n    if ( match ) {\n        elem.type = match[1];\n    } else {\n        elem.removeAttribute(\"type\");\n    }\n    return elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n    var elem,\n        i = 0;\n    for ( ; (elem = elems[i]) != null; i++ ) {\n        jQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n    }\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n    if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n        return;\n    }\n\n    var type, i, l,\n        oldData = jQuery._data( src ),\n        curData = jQuery._data( dest, oldData ),\n        events = oldData.events;\n\n    if ( events ) {\n        delete curData.handle;\n        curData.events = {};\n\n        for ( type in events ) {\n            for ( i = 0, l = events[ type ].length; i < l; i++ ) {\n                jQuery.event.add( dest, type, events[ type ][ i ] );\n            }\n        }\n    }\n\n    // make the cloned public data object a copy from the original\n    if ( curData.data ) {\n        curData.data = jQuery.extend( {}, curData.data );\n    }\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n    var nodeName, e, data;\n\n    // We do not need to do anything for non-Elements\n    if ( dest.nodeType !== 1 ) {\n        return;\n    }\n\n    nodeName = dest.nodeName.toLowerCase();\n\n    // IE6-8 copies events bound via attachEvent when using cloneNode.\n    if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) {\n        data = jQuery._data( dest );\n\n        for ( e in data.events ) {\n            jQuery.removeEvent( dest, e, data.handle );\n        }\n\n        // Event data gets referenced instead of copied if the expando gets copied too\n        dest.removeAttribute( jQuery.expando );\n    }\n\n    // IE blanks contents when cloning scripts, and tries to evaluate newly-set text\n    if ( nodeName === \"script\" && dest.text !== src.text ) {\n        disableScript( dest ).text = src.text;\n        restoreScript( dest );\n\n    // IE6-10 improperly clones children of object elements using classid.\n    // IE10 throws NoModificationAllowedError if parent is null, #12132.\n    } else if ( nodeName === \"object\" ) {\n        if ( dest.parentNode ) {\n            dest.outerHTML = src.outerHTML;\n        }\n\n        // This path appears unavoidable for IE9. When cloning an object\n        // element in IE9, the outerHTML strategy above is not sufficient.\n        // If the src has innerHTML and the destination does not,\n        // copy the src.innerHTML into the dest.innerHTML. #10324\n        if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n            dest.innerHTML = src.innerHTML;\n        }\n\n    } else if ( nodeName === \"input\" && manipulation_rcheckableType.test( src.type ) ) {\n        // IE6-8 fails to persist the checked state of a cloned checkbox\n        // or radio button. Worse, IE6-7 fail to give the cloned element\n        // a checked appearance if the defaultChecked value isn't also set\n\n        dest.defaultChecked = dest.checked = src.checked;\n\n        // IE6-7 get confused and end up setting the value of a cloned\n        // checkbox/radio button to an empty string instead of \"on\"\n        if ( dest.value !== src.value ) {\n            dest.value = src.value;\n        }\n\n    // IE6-8 fails to return the selected option to the default selected\n    // state when cloning options\n    } else if ( nodeName === \"option\" ) {\n        dest.defaultSelected = dest.selected = src.defaultSelected;\n\n    // IE6-8 fails to set the defaultValue to the correct value when\n    // cloning other types of input fields\n    } else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n        dest.defaultValue = src.defaultValue;\n    }\n}\n\njQuery.each({\n    appendTo: \"append\",\n    prependTo: \"prepend\",\n    insertBefore: \"before\",\n    insertAfter: \"after\",\n    replaceAll: \"replaceWith\"\n}, function( name, original ) {\n    jQuery.fn[ name ] = function( selector ) {\n        var elems,\n            i = 0,\n            ret = [],\n            insert = jQuery( selector ),\n            last = insert.length - 1;\n\n        for ( ; i <= last; i++ ) {\n            elems = i === last ? this : this.clone(true);\n            jQuery( insert[i] )[ original ]( elems );\n\n            // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()\n            core_push.apply( ret, elems.get() );\n        }\n\n        return this.pushStack( ret );\n    };\n});\n\nfunction getAll( context, tag ) {\n    var elems, elem,\n        i = 0,\n        found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n            typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || \"*\" ) :\n            undefined;\n\n    if ( !found ) {\n        for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n            if ( !tag || jQuery.nodeName( elem, tag ) ) {\n                found.push( elem );\n            } else {\n                jQuery.merge( found, getAll( elem, tag ) );\n            }\n        }\n    }\n\n    return tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n        jQuery.merge( [ context ], found ) :\n        found;\n}\n\n// Used in buildFragment, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n    if ( manipulation_rcheckableType.test( elem.type ) ) {\n        elem.defaultChecked = elem.checked;\n    }\n}\n\njQuery.extend({\n    clone: function( elem, dataAndEvents, deepDataAndEvents ) {\n        var destElements, node, clone, i, srcElements,\n            inPage = jQuery.contains( elem.ownerDocument, elem );\n\n        if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n            clone = elem.cloneNode( true );\n\n        // IE<=8 does not properly clone detached, unknown element nodes\n        } else {\n            fragmentDiv.innerHTML = elem.outerHTML;\n            fragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n        }\n\n        if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&\n                (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\n            // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n            destElements = getAll( clone );\n            srcElements = getAll( elem );\n\n            // Fix all IE cloning issues\n            for ( i = 0; (node = srcElements[i]) != null; ++i ) {\n                // Ensure that the destination node is not null; Fixes #9587\n                if ( destElements[i] ) {\n                    fixCloneNodeIssues( node, destElements[i] );\n                }\n            }\n        }\n\n        // Copy the events from the original to the clone\n        if ( dataAndEvents ) {\n            if ( deepDataAndEvents ) {\n                srcElements = srcElements || getAll( elem );\n                destElements = destElements || getAll( clone );\n\n                for ( i = 0; (node = srcElements[i]) != null; i++ ) {\n                    cloneCopyEvent( node, destElements[i] );\n                }\n            } else {\n                cloneCopyEvent( elem, clone );\n            }\n        }\n\n        // Preserve script evaluation history\n        destElements = getAll( clone, \"script\" );\n        if ( destElements.length > 0 ) {\n            setGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n        }\n\n        destElements = srcElements = node = null;\n\n        // Return the cloned set\n        return clone;\n    },\n\n    buildFragment: function( elems, context, scripts, selection ) {\n        var j, elem, contains,\n            tmp, tag, tbody, wrap,\n            l = elems.length,\n\n            // Ensure a safe fragment\n            safe = createSafeFragment( context ),\n\n            nodes = [],\n            i = 0;\n\n        for ( ; i < l; i++ ) {\n            elem = elems[ i ];\n\n            if ( elem || elem === 0 ) {\n\n                // Add nodes directly\n                if ( jQuery.type( elem ) === \"object\" ) {\n                    jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n                // Convert non-html into a text node\n                } else if ( !rhtml.test( elem ) ) {\n                    nodes.push( context.createTextNode( elem ) );\n\n                // Convert html into DOM nodes\n                } else {\n                    tmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\n                    // Deserialize a standard representation\n                    tag = ( rtagName.exec( elem ) || [\"\", \"\"] )[1].toLowerCase();\n                    wrap = wrapMap[ tag ] || wrapMap._default;\n\n                    tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[2];\n\n                    // Descend through wrappers to the right content\n                    j = wrap[0];\n                    while ( j-- ) {\n                        tmp = tmp.lastChild;\n                    }\n\n                    // Manually add leading whitespace removed by IE\n                    if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n                        nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n                    }\n\n                    // Remove IE's autoinserted <tbody> from table fragments\n                    if ( !jQuery.support.tbody ) {\n\n                        // String was a <table>, *may* have spurious <tbody>\n                        elem = tag === \"table\" && !rtbody.test( elem ) ?\n                            tmp.firstChild :\n\n                            // String was a bare <thead> or <tfoot>\n                            wrap[1] === \"<table>\" && !rtbody.test( elem ) ?\n                                tmp :\n                                0;\n\n                        j = elem && elem.childNodes.length;\n                        while ( j-- ) {\n                            if ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n                                elem.removeChild( tbody );\n                            }\n                        }\n                    }\n\n                    jQuery.merge( nodes, tmp.childNodes );\n\n                    // Fix #12392 for WebKit and IE > 9\n                    tmp.textContent = \"\";\n\n                    // Fix #12392 for oldIE\n                    while ( tmp.firstChild ) {\n                        tmp.removeChild( tmp.firstChild );\n                    }\n\n                    // Remember the top-level container for proper cleanup\n                    tmp = safe.lastChild;\n                }\n            }\n        }\n\n        // Fix #11356: Clear elements from fragment\n        if ( tmp ) {\n            safe.removeChild( tmp );\n        }\n\n        // Reset defaultChecked for any radios and checkboxes\n        // about to be appended to the DOM in IE 6/7 (#8060)\n        if ( !jQuery.support.appendChecked ) {\n            jQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n        }\n\n        i = 0;\n        while ( (elem = nodes[ i++ ]) ) {\n\n            // #4087 - If origin and destination elements are the same, and this is\n            // that element, do not do anything\n            if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n                continue;\n            }\n\n            contains = jQuery.contains( elem.ownerDocument, elem );\n\n            // Append to fragment\n            tmp = getAll( safe.appendChild( elem ), \"script\" );\n\n            // Preserve script evaluation history\n            if ( contains ) {\n                setGlobalEval( tmp );\n            }\n\n            // Capture executables\n            if ( scripts ) {\n                j = 0;\n                while ( (elem = tmp[ j++ ]) ) {\n                    if ( rscriptType.test( elem.type || \"\" ) ) {\n                        scripts.push( elem );\n                    }\n                }\n            }\n        }\n\n        tmp = null;\n\n        return safe;\n    },\n\n    cleanData: function( elems, /* internal */ acceptData ) {\n        var elem, type, id, data,\n            i = 0,\n            internalKey = jQuery.expando,\n            cache = jQuery.cache,\n            deleteExpando = jQuery.support.deleteExpando,\n            special = jQuery.event.special;\n\n        for ( ; (elem = elems[i]) != null; i++ ) {\n\n            if ( acceptData || jQuery.acceptData( elem ) ) {\n\n                id = elem[ internalKey ];\n                data = id && cache[ id ];\n\n                if ( data ) {\n                    if ( data.events ) {\n                        for ( type in data.events ) {\n                            if ( special[ type ] ) {\n                                jQuery.event.remove( elem, type );\n\n                            // This is a shortcut to avoid jQuery.event.remove's overhead\n                            } else {\n                                jQuery.removeEvent( elem, type, data.handle );\n                            }\n                        }\n                    }\n\n                    // Remove cache only if it was not already removed by jQuery.event.remove\n                    if ( cache[ id ] ) {\n\n                        delete cache[ id ];\n\n                        // IE does not allow us to delete expando properties from nodes,\n                        // nor does it have a removeAttribute function on Document nodes;\n                        // we must handle all of these cases\n                        if ( deleteExpando ) {\n                            delete elem[ internalKey ];\n\n                        } else if ( typeof elem.removeAttribute !== core_strundefined ) {\n                            elem.removeAttribute( internalKey );\n\n                        } else {\n                            elem[ internalKey ] = null;\n                        }\n\n                        core_deletedIds.push( id );\n                    }\n                }\n            }\n        }\n    },\n\n    _evalUrl: function( url ) {\n        return jQuery.ajax({\n            url: url,\n            type: \"GET\",\n            dataType: \"script\",\n            async: false,\n            global: false,\n            \"throws\": true\n        });\n    }\n});\njQuery.fn.extend({\n    wrapAll: function( html ) {\n        if ( jQuery.isFunction( html ) ) {\n            return this.each(function(i) {\n                jQuery(this).wrapAll( html.call(this, i) );\n            });\n        }\n\n        if ( this[0] ) {\n            // The elements to wrap the target around\n            var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n            if ( this[0].parentNode ) {\n                wrap.insertBefore( this[0] );\n            }\n\n            wrap.map(function() {\n                var elem = this;\n\n                while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n                    elem = elem.firstChild;\n                }\n\n                return elem;\n            }).append( this );\n        }\n\n        return this;\n    },\n\n    wrapInner: function( html ) {\n        if ( jQuery.isFunction( html ) ) {\n            return this.each(function(i) {\n                jQuery(this).wrapInner( html.call(this, i) );\n            });\n        }\n\n        return this.each(function() {\n            var self = jQuery( this ),\n                contents = self.contents();\n\n            if ( contents.length ) {\n                contents.wrapAll( html );\n\n            } else {\n                self.append( html );\n            }\n        });\n    },\n\n    wrap: function( html ) {\n        var isFunction = jQuery.isFunction( html );\n\n        return this.each(function(i) {\n            jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n        });\n    },\n\n    unwrap: function() {\n        return this.parent().each(function() {\n            if ( !jQuery.nodeName( this, \"body\" ) ) {\n                jQuery( this ).replaceWith( this.childNodes );\n            }\n        }).end();\n    }\n});\nvar iframe, getStyles, curCSS,\n    ralpha = /alpha\\([^)]*\\)/i,\n    ropacity = /opacity\\s*=\\s*([^)]*)/,\n    rposition = /^(top|right|bottom|left)$/,\n    // swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n    // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n    rdisplayswap = /^(none|table(?!-c[ea]).+)/,\n    rmargin = /^margin/,\n    rnumsplit = new RegExp( \"^(\" + core_pnum + \")(.*)$\", \"i\" ),\n    rnumnonpx = new RegExp( \"^(\" + core_pnum + \")(?!px)[a-z%]+$\", \"i\" ),\n    rrelNum = new RegExp( \"^([+-])=(\" + core_pnum + \")\", \"i\" ),\n    elemdisplay = { BODY: \"block\" },\n\n    cssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n    cssNormalTransform = {\n        letterSpacing: 0,\n        fontWeight: 400\n    },\n\n    cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ],\n    cssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n    // shortcut for names that are not vendor prefixed\n    if ( name in style ) {\n        return name;\n    }\n\n    // check for vendor prefixed names\n    var capName = name.charAt(0).toUpperCase() + name.slice(1),\n        origName = name,\n        i = cssPrefixes.length;\n\n    while ( i-- ) {\n        name = cssPrefixes[ i ] + capName;\n        if ( name in style ) {\n            return name;\n        }\n    }\n\n    return origName;\n}\n\nfunction isHidden( elem, el ) {\n    // isHidden might be called from jQuery#filter function;\n    // in that case, element will be second argument\n    elem = el || elem;\n    return jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n}\n\nfunction showHide( elements, show ) {\n    var display, elem, hidden,\n        values = [],\n        index = 0,\n        length = elements.length;\n\n    for ( ; index < length; index++ ) {\n        elem = elements[ index ];\n        if ( !elem.style ) {\n            continue;\n        }\n\n        values[ index ] = jQuery._data( elem, \"olddisplay\" );\n        display = elem.style.display;\n        if ( show ) {\n            // Reset the inline display of this element to learn if it is\n            // being hidden by cascaded rules or not\n            if ( !values[ index ] && display === \"none\" ) {\n                elem.style.display = \"\";\n            }\n\n            // Set elements which have been overridden with display: none\n            // in a stylesheet to whatever the default browser style is\n            // for such an element\n            if ( elem.style.display === \"\" && isHidden( elem ) ) {\n                values[ index ] = jQuery._data( elem, \"olddisplay\", css_defaultDisplay(elem.nodeName) );\n            }\n        } else {\n\n            if ( !values[ index ] ) {\n                hidden = isHidden( elem );\n\n                if ( display && display !== \"none\" || !hidden ) {\n                    jQuery._data( elem, \"olddisplay\", hidden ? display : jQuery.css( elem, \"display\" ) );\n                }\n            }\n        }\n    }\n\n    // Set the display of most of the elements in a second loop\n    // to avoid the constant reflow\n    for ( index = 0; index < length; index++ ) {\n        elem = elements[ index ];\n        if ( !elem.style ) {\n            continue;\n        }\n        if ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n            elem.style.display = show ? values[ index ] || \"\" : \"none\";\n        }\n    }\n\n    return elements;\n}\n\njQuery.fn.extend({\n    css: function( name, value ) {\n        return jQuery.access( this, function( elem, name, value ) {\n            var len, styles,\n                map = {},\n                i = 0;\n\n            if ( jQuery.isArray( name ) ) {\n                styles = getStyles( elem );\n                len = name.length;\n\n                for ( ; i < len; i++ ) {\n                    map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n                }\n\n                return map;\n            }\n\n            return value !== undefined ?\n                jQuery.style( elem, name, value ) :\n                jQuery.css( elem, name );\n        }, name, value, arguments.length > 1 );\n    },\n    show: function() {\n        return showHide( this, true );\n    },\n    hide: function() {\n        return showHide( this );\n    },\n    toggle: function( state ) {\n        if ( typeof state === \"boolean\" ) {\n            return state ? this.show() : this.hide();\n        }\n\n        return this.each(function() {\n            if ( isHidden( this ) ) {\n                jQuery( this ).show();\n            } else {\n                jQuery( this ).hide();\n            }\n        });\n    }\n});\n\njQuery.extend({\n    // Add in style property hooks for overriding the default\n    // behavior of getting and setting a style property\n    cssHooks: {\n        opacity: {\n            get: function( elem, computed ) {\n                if ( computed ) {\n                    // We should always get a number back from opacity\n                    var ret = curCSS( elem, \"opacity\" );\n                    return ret === \"\" ? \"1\" : ret;\n                }\n            }\n        }\n    },\n\n    // Don't automatically add \"px\" to these possibly-unitless properties\n    cssNumber: {\n        \"columnCount\": true,\n        \"fillOpacity\": true,\n        \"fontWeight\": true,\n        \"lineHeight\": true,\n        \"opacity\": true,\n        \"order\": true,\n        \"orphans\": true,\n        \"widows\": true,\n        \"zIndex\": true,\n        \"zoom\": true\n    },\n\n    // Add in properties whose names you wish to fix before\n    // setting or getting the value\n    cssProps: {\n        // normalize float css property\n        \"float\": jQuery.support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n    },\n\n    // Get and set the style property on a DOM Node\n    style: function( elem, name, value, extra ) {\n        // Don't set styles on text and comment nodes\n        if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n            return;\n        }\n\n        // Make sure that we're working with the right name\n        var ret, type, hooks,\n            origName = jQuery.camelCase( name ),\n            style = elem.style;\n\n        name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n        // gets hook for the prefixed version\n        // followed by the unprefixed version\n        hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n        // Check if we're setting a value\n        if ( value !== undefined ) {\n            type = typeof value;\n\n            // convert relative number strings (+= or -=) to relative numbers. #7345\n            if ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n                value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n                // Fixes bug #9237\n                type = \"number\";\n            }\n\n            // Make sure that NaN and null values aren't set. See: #7116\n            if ( value == null || type === \"number\" && isNaN( value ) ) {\n                return;\n            }\n\n            // If a number was passed in, add 'px' to the (except for certain CSS properties)\n            if ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n                value += \"px\";\n            }\n\n            // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,\n            // but it would mean to define eight (for every problematic property) identical functions\n            if ( !jQuery.support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0 ) {\n                style[ name ] = \"inherit\";\n            }\n\n            // If a hook was provided, use that value, otherwise just set the specified value\n            if ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\n                // Wrapped to prevent IE from throwing errors when 'invalid' values are provided\n                // Fixes bug #5509\n                try {\n                    style[ name ] = value;\n                } catch(e) {}\n            }\n\n        } else {\n            // If a hook was provided get the non-computed value from there\n            if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n                return ret;\n            }\n\n            // Otherwise just get the value from the style object\n            return style[ name ];\n        }\n    },\n\n    css: function( elem, name, extra, styles ) {\n        var num, val, hooks,\n            origName = jQuery.camelCase( name );\n\n        // Make sure that we're working with the right name\n        name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n        // gets hook for the prefixed version\n        // followed by the unprefixed version\n        hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n        // If a hook was provided get the computed value from there\n        if ( hooks && \"get\" in hooks ) {\n            val = hooks.get( elem, true, extra );\n        }\n\n        // Otherwise, if a way to get the computed value exists, use that\n        if ( val === undefined ) {\n            val = curCSS( elem, name, styles );\n        }\n\n        //convert \"normal\" to computed value\n        if ( val === \"normal\" && name in cssNormalTransform ) {\n            val = cssNormalTransform[ name ];\n        }\n\n        // Return, converting to number if forced or a qualifier was provided and val looks numeric\n        if ( extra === \"\" || extra ) {\n            num = parseFloat( val );\n            return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n        }\n        return val;\n    }\n});\n\n// NOTE: we've included the \"window\" in window.getComputedStyle\n// because jsdom on node.js will break without it.\nif ( window.getComputedStyle ) {\n    getStyles = function( elem ) {\n        return window.getComputedStyle( elem, null );\n    };\n\n    curCSS = function( elem, name, _computed ) {\n        var width, minWidth, maxWidth,\n            computed = _computed || getStyles( elem ),\n\n            // getPropertyValue is only needed for .css('filter') in IE9, see #12537\n            ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,\n            style = elem.style;\n\n        if ( computed ) {\n\n            if ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n                ret = jQuery.style( elem, name );\n            }\n\n            // A tribute to the \"awesome hack by Dean Edwards\"\n            // Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n            // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n            // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n            if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n                // Remember the original values\n                width = style.width;\n                minWidth = style.minWidth;\n                maxWidth = style.maxWidth;\n\n                // Put in the new values to get a computed value out\n                style.minWidth = style.maxWidth = style.width = ret;\n                ret = computed.width;\n\n                // Revert the changed values\n                style.width = width;\n                style.minWidth = minWidth;\n                style.maxWidth = maxWidth;\n            }\n        }\n\n        return ret;\n    };\n} else if ( document.documentElement.currentStyle ) {\n    getStyles = function( elem ) {\n        return elem.currentStyle;\n    };\n\n    curCSS = function( elem, name, _computed ) {\n        var left, rs, rsLeft,\n            computed = _computed || getStyles( elem ),\n            ret = computed ? computed[ name ] : undefined,\n            style = elem.style;\n\n        // Avoid setting ret to empty string here\n        // so we don't default to auto\n        if ( ret == null && style && style[ name ] ) {\n            ret = style[ name ];\n        }\n\n        // From the awesome hack by Dean Edwards\n        // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n        // If we're not dealing with a regular pixel number\n        // but a number that has a weird ending, we need to convert it to pixels\n        // but not position css attributes, as those are proportional to the parent element instead\n        // and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n        if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n            // Remember the original values\n            left = style.left;\n            rs = elem.runtimeStyle;\n            rsLeft = rs && rs.left;\n\n            // Put in the new values to get a computed value out\n            if ( rsLeft ) {\n                rs.left = elem.currentStyle.left;\n            }\n            style.left = name === \"fontSize\" ? \"1em\" : ret;\n            ret = style.pixelLeft + \"px\";\n\n            // Revert the changed values\n            style.left = left;\n            if ( rsLeft ) {\n                rs.left = rsLeft;\n            }\n        }\n\n        return ret === \"\" ? \"auto\" : ret;\n    };\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n    var matches = rnumsplit.exec( value );\n    return matches ?\n        // Guard against undefined \"subtract\", e.g., when used as in cssHooks\n        Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n        value;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n    var i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n        // If we already have the right measurement, avoid augmentation\n        4 :\n        // Otherwise initialize for horizontal or vertical properties\n        name === \"width\" ? 1 : 0,\n\n        val = 0;\n\n    for ( ; i < 4; i += 2 ) {\n        // both box models exclude margin, so add it if we want it\n        if ( extra === \"margin\" ) {\n            val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n        }\n\n        if ( isBorderBox ) {\n            // border-box includes padding, so remove it if we want content\n            if ( extra === \"content\" ) {\n                val -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n            }\n\n            // at this point, extra isn't border nor margin, so remove border\n            if ( extra !== \"margin\" ) {\n                val -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n            }\n        } else {\n            // at this point, extra isn't content, so add padding\n            val += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n            // at this point, extra isn't content nor padding, so add border\n            if ( extra !== \"padding\" ) {\n                val += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n            }\n        }\n    }\n\n    return val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n    // Start with offset property, which is equivalent to the border-box value\n    var valueIsBorderBox = true,\n        val = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n        styles = getStyles( elem ),\n        isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n    // some non-html elements return undefined for offsetWidth, so check for null/undefined\n    // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n    // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n    if ( val <= 0 || val == null ) {\n        // Fall back to computed then uncomputed css if necessary\n        val = curCSS( elem, name, styles );\n        if ( val < 0 || val == null ) {\n            val = elem.style[ name ];\n        }\n\n        // Computed unit is not pixels. Stop here and return.\n        if ( rnumnonpx.test(val) ) {\n            return val;\n        }\n\n        // we need the check for style in case a browser which returns unreliable values\n        // for getComputedStyle silently falls back to the reliable elem.style\n        valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );\n\n        // Normalize \"\", auto, and prepare for extra\n        val = parseFloat( val ) || 0;\n    }\n\n    // use the active box-sizing model to add/subtract irrelevant styles\n    return ( val +\n        augmentWidthOrHeight(\n            elem,\n            name,\n            extra || ( isBorderBox ? \"border\" : \"content\" ),\n            valueIsBorderBox,\n            styles\n        )\n    ) + \"px\";\n}\n\n// Try to determine the default display value of an element\nfunction css_defaultDisplay( nodeName ) {\n    var doc = document,\n        display = elemdisplay[ nodeName ];\n\n    if ( !display ) {\n        display = actualDisplay( nodeName, doc );\n\n        // If the simple way fails, read from inside an iframe\n        if ( display === \"none\" || !display ) {\n            // Use the already-created iframe if possible\n            iframe = ( iframe ||\n                jQuery(\"<iframe frameborder='0' width='0' height='0'/>\")\n                .css( \"cssText\", \"display:block !important\" )\n            ).appendTo( doc.documentElement );\n\n            // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n            doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;\n            doc.write(\"<!doctype html><html><body>\");\n            doc.close();\n\n            display = actualDisplay( nodeName, doc );\n            iframe.detach();\n        }\n\n        // Store the correct default display\n        elemdisplay[ nodeName ] = display;\n    }\n\n    return display;\n}\n\n// Called ONLY from within css_defaultDisplay\nfunction actualDisplay( name, doc ) {\n    var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n        display = jQuery.css( elem[0], \"display\" );\n    elem.remove();\n    return display;\n}\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n    jQuery.cssHooks[ name ] = {\n        get: function( elem, computed, extra ) {\n            if ( computed ) {\n                // certain elements can have dimension info if we invisibly show them\n                // however, it must have a current display style that would benefit from this\n                return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, \"display\" ) ) ?\n                    jQuery.swap( elem, cssShow, function() {\n                        return getWidthOrHeight( elem, name, extra );\n                    }) :\n                    getWidthOrHeight( elem, name, extra );\n            }\n        },\n\n        set: function( elem, value, extra ) {\n            var styles = extra && getStyles( elem );\n            return setPositiveNumber( elem, value, extra ?\n                augmentWidthOrHeight(\n                    elem,\n                    name,\n                    extra,\n                    jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n                    styles\n                ) : 0\n            );\n        }\n    };\n});\n\nif ( !jQuery.support.opacity ) {\n    jQuery.cssHooks.opacity = {\n        get: function( elem, computed ) {\n            // IE uses filters for opacity\n            return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n                ( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n                computed ? \"1\" : \"\";\n        },\n\n        set: function( elem, value ) {\n            var style = elem.style,\n                currentStyle = elem.currentStyle,\n                opacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n                filter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n            // IE has trouble with opacity if it does not have layout\n            // Force it by setting the zoom level\n            style.zoom = 1;\n\n            // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n            // if value === \"\", then remove inline opacity #12685\n            if ( ( value >= 1 || value === \"\" ) &&\n                    jQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n                    style.removeAttribute ) {\n\n                // Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n                // if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n                // style.removeAttribute is IE Only, but so apparently is this code path...\n                style.removeAttribute( \"filter\" );\n\n                // if there is no filter style applied in a css rule or unset inline opacity, we are done\n                if ( value === \"\" || currentStyle && !currentStyle.filter ) {\n                    return;\n                }\n            }\n\n            // otherwise, set new filter values\n            style.filter = ralpha.test( filter ) ?\n                filter.replace( ralpha, opacity ) :\n                filter + \" \" + opacity;\n        }\n    };\n}\n\n// These hooks cannot be added until DOM ready because the support test\n// for it is not run until after DOM ready\njQuery(function() {\n    if ( !jQuery.support.reliableMarginRight ) {\n        jQuery.cssHooks.marginRight = {\n            get: function( elem, computed ) {\n                if ( computed ) {\n                    // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n                    // Work around by temporarily setting element display to inline-block\n                    return jQuery.swap( elem, { \"display\": \"inline-block\" },\n                        curCSS, [ elem, \"marginRight\" ] );\n                }\n            }\n        };\n    }\n\n    // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n    // getComputedStyle returns percent when specified for top/left/bottom/right\n    // rather than make the css module depend on the offset module, we just check for it here\n    if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {\n        jQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n            jQuery.cssHooks[ prop ] = {\n                get: function( elem, computed ) {\n                    if ( computed ) {\n                        computed = curCSS( elem, prop );\n                        // if curCSS returns percentage, fallback to offset\n                        return rnumnonpx.test( computed ) ?\n                            jQuery( elem ).position()[ prop ] + \"px\" :\n                            computed;\n                    }\n                }\n            };\n        });\n    }\n\n});\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n    jQuery.expr.filters.hidden = function( elem ) {\n        // Support: Opera <= 12.12\n        // Opera reports offsetWidths and offsetHeights less than zero on some elements\n        return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||\n            (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, \"display\" )) === \"none\");\n    };\n\n    jQuery.expr.filters.visible = function( elem ) {\n        return !jQuery.expr.filters.hidden( elem );\n    };\n}\n\n// These hooks are used by animate to expand properties\njQuery.each({\n    margin: \"\",\n    padding: \"\",\n    border: \"Width\"\n}, function( prefix, suffix ) {\n    jQuery.cssHooks[ prefix + suffix ] = {\n        expand: function( value ) {\n            var i = 0,\n                expanded = {},\n\n                // assumes a single number if not a string\n                parts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n            for ( ; i < 4; i++ ) {\n                expanded[ prefix + cssExpand[ i ] + suffix ] =\n                    parts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n            }\n\n            return expanded;\n        }\n    };\n\n    if ( !rmargin.test( prefix ) ) {\n        jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n    }\n});\nvar r20 = /%20/g,\n    rbracket = /\\[\\]$/,\n    rCRLF = /\\r?\\n/g,\n    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n    rsubmittable = /^(?:input|select|textarea|keygen)/i;\n\njQuery.fn.extend({\n    serialize: function() {\n        return jQuery.param( this.serializeArray() );\n    },\n    serializeArray: function() {\n        return this.map(function(){\n            // Can add propHook for \"elements\" to filter or add form elements\n            var elements = jQuery.prop( this, \"elements\" );\n            return elements ? jQuery.makeArray( elements ) : this;\n        })\n        .filter(function(){\n            var type = this.type;\n            // Use .is(\":disabled\") so that fieldset[disabled] works\n            return this.name && !jQuery( this ).is( \":disabled\" ) &&\n                rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n                ( this.checked || !manipulation_rcheckableType.test( type ) );\n        })\n        .map(function( i, elem ){\n            var val = jQuery( this ).val();\n\n            return val == null ?\n                null :\n                jQuery.isArray( val ) ?\n                    jQuery.map( val, function( val ){\n                        return { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n                    }) :\n                    { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n        }).get();\n    }\n});\n\n//Serialize an array of form elements or a set of\n//key/values into a query string\njQuery.param = function( a, traditional ) {\n    var prefix,\n        s = [],\n        add = function( key, value ) {\n            // If value is a function, invoke it and return its value\n            value = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n            s[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n        };\n\n    // Set traditional to true for jQuery <= 1.3.2 behavior.\n    if ( traditional === undefined ) {\n        traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n    }\n\n    // If an array was passed in, assume that it is an array of form elements.\n    if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n        // Serialize the form elements\n        jQuery.each( a, function() {\n            add( this.name, this.value );\n        });\n\n    } else {\n        // If traditional, encode the \"old\" way (the way 1.3.2 or older\n        // did it), otherwise encode params recursively.\n        for ( prefix in a ) {\n            buildParams( prefix, a[ prefix ], traditional, add );\n        }\n    }\n\n    // Return the resulting serialization\n    return s.join( \"&\" ).replace( r20, \"+\" );\n};\n\nfunction buildParams( prefix, obj, traditional, add ) {\n    var name;\n\n    if ( jQuery.isArray( obj ) ) {\n        // Serialize array item.\n        jQuery.each( obj, function( i, v ) {\n            if ( traditional || rbracket.test( prefix ) ) {\n                // Treat each array item as a scalar.\n                add( prefix, v );\n\n            } else {\n                // Item is non-scalar (array or object), encode its numeric index.\n                buildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n            }\n        });\n\n    } else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n        // Serialize object item.\n        for ( name in obj ) {\n            buildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n        }\n\n    } else {\n        // Serialize scalar item.\n        add( prefix, obj );\n    }\n}\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n    \"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n    \"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n    // Handle event binding\n    jQuery.fn[ name ] = function( data, fn ) {\n        return arguments.length > 0 ?\n            this.on( name, null, data, fn ) :\n            this.trigger( name );\n    };\n});\n\njQuery.fn.extend({\n    hover: function( fnOver, fnOut ) {\n        return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n    },\n\n    bind: function( types, data, fn ) {\n        return this.on( types, null, data, fn );\n    },\n    unbind: function( types, fn ) {\n        return this.off( types, null, fn );\n    },\n\n    delegate: function( selector, types, data, fn ) {\n        return this.on( types, selector, data, fn );\n    },\n    undelegate: function( selector, types, fn ) {\n        // ( namespace ) or ( selector, types [, fn] )\n        return arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n    }\n});\nvar\n    // Document location\n    ajaxLocParts,\n    ajaxLocation,\n    ajax_nonce = jQuery.now(),\n\n    ajax_rquery = /\\?/,\n    rhash = /#.*$/,\n    rts = /([?&])_=[^&]*/,\n    rheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n    // #7653, #8125, #8152: local protocol detection\n    rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n    rnoContent = /^(?:GET|HEAD)$/,\n    rprotocol = /^\\/\\//,\n    rurl = /^([\\w.+-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n    // Keep a copy of the old load method\n    _load = jQuery.fn.load,\n\n    /* Prefilters\n     * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n     * 2) These are called:\n     *    - BEFORE asking for a transport\n     *    - AFTER param serialization (s.data is a string if s.processData is true)\n     * 3) key is the dataType\n     * 4) the catchall symbol \"*\" can be used\n     * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n     */\n    prefilters = {},\n\n    /* Transports bindings\n     * 1) key is the dataType\n     * 2) the catchall symbol \"*\" can be used\n     * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n     */\n    transports = {},\n\n    // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n    allTypes = \"*/\".concat(\"*\");\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n    ajaxLocation = location.href;\n} catch( e ) {\n    // Use the href attribute of an A element\n    // since IE will modify it given document.location\n    ajaxLocation = document.createElement( \"a\" );\n    ajaxLocation.href = \"\";\n    ajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n    // dataTypeExpression is optional and defaults to \"*\"\n    return function( dataTypeExpression, func ) {\n\n        if ( typeof dataTypeExpression !== \"string\" ) {\n            func = dataTypeExpression;\n            dataTypeExpression = \"*\";\n        }\n\n        var dataType,\n            i = 0,\n            dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];\n\n        if ( jQuery.isFunction( func ) ) {\n            // For each dataType in the dataTypeExpression\n            while ( (dataType = dataTypes[i++]) ) {\n                // Prepend if requested\n                if ( dataType[0] === \"+\" ) {\n                    dataType = dataType.slice( 1 ) || \"*\";\n                    (structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\n                // Otherwise append\n                } else {\n                    (structure[ dataType ] = structure[ dataType ] || []).push( func );\n                }\n            }\n        }\n    };\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n    var inspected = {},\n        seekingTransport = ( structure === transports );\n\n    function inspect( dataType ) {\n        var selected;\n        inspected[ dataType ] = true;\n        jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n            var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n            if( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n                options.dataTypes.unshift( dataTypeOrTransport );\n                inspect( dataTypeOrTransport );\n                return false;\n            } else if ( seekingTransport ) {\n                return !( selected = dataTypeOrTransport );\n            }\n        });\n        return selected;\n    }\n\n    return inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n    var deep, key,\n        flatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n    for ( key in src ) {\n        if ( src[ key ] !== undefined ) {\n            ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n        }\n    }\n    if ( deep ) {\n        jQuery.extend( true, target, deep );\n    }\n\n    return target;\n}\n\njQuery.fn.load = function( url, params, callback ) {\n    if ( typeof url !== \"string\" && _load ) {\n        return _load.apply( this, arguments );\n    }\n\n    var selector, response, type,\n        self = this,\n        off = url.indexOf(\" \");\n\n    if ( off >= 0 ) {\n        selector = url.slice( off, url.length );\n        url = url.slice( 0, off );\n    }\n\n    // If it's a function\n    if ( jQuery.isFunction( params ) ) {\n\n        // We assume that it's the callback\n        callback = params;\n        params = undefined;\n\n    // Otherwise, build a param string\n    } else if ( params && typeof params === \"object\" ) {\n        type = \"POST\";\n    }\n\n    // If we have elements to modify, make the request\n    if ( self.length > 0 ) {\n        jQuery.ajax({\n            url: url,\n\n            // if \"type\" variable is undefined, then \"GET\" method will be used\n            type: type,\n            dataType: \"html\",\n            data: params\n        }).done(function( responseText ) {\n\n            // Save response for use in complete callback\n            response = arguments;\n\n            self.html( selector ?\n\n                // If a selector was specified, locate the right elements in a dummy div\n                // Exclude scripts to avoid IE 'Permission Denied' errors\n                jQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n                // Otherwise use the full result\n                responseText );\n\n        }).complete( callback && function( jqXHR, status ) {\n            self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n        });\n    }\n\n    return this;\n};\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ){\n    jQuery.fn[ type ] = function( fn ){\n        return this.on( type, fn );\n    };\n});\n\njQuery.extend({\n\n    // Counter for holding the number of active queries\n    active: 0,\n\n    // Last-Modified header cache for next request\n    lastModified: {},\n    etag: {},\n\n    ajaxSettings: {\n        url: ajaxLocation,\n        type: \"GET\",\n        isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n        global: true,\n        processData: true,\n        async: true,\n        contentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n        /*\n        timeout: 0,\n        data: null,\n        dataType: null,\n        username: null,\n        password: null,\n        cache: null,\n        throws: false,\n        traditional: false,\n        headers: {},\n        */\n\n        accepts: {\n            \"*\": allTypes,\n            text: \"text/plain\",\n            html: \"text/html\",\n            xml: \"application/xml, text/xml\",\n            json: \"application/json, text/javascript\"\n        },\n\n        contents: {\n            xml: /xml/,\n            html: /html/,\n            json: /json/\n        },\n\n        responseFields: {\n            xml: \"responseXML\",\n            text: \"responseText\",\n            json: \"responseJSON\"\n        },\n\n        // Data converters\n        // Keys separate source (or catchall \"*\") and destination types with a single space\n        converters: {\n\n            // Convert anything to text\n            \"* text\": String,\n\n            // Text to html (true = no transformation)\n            \"text html\": true,\n\n            // Evaluate text as a json expression\n            \"text json\": jQuery.parseJSON,\n\n            // Parse text as xml\n            \"text xml\": jQuery.parseXML\n        },\n\n        // For options that shouldn't be deep extended:\n        // you can add your own custom options here if\n        // and when you create one that shouldn't be\n        // deep extended (see ajaxExtend)\n        flatOptions: {\n            url: true,\n            context: true\n        }\n    },\n\n    // Creates a full fledged settings object into target\n    // with both ajaxSettings and settings fields.\n    // If target is omitted, writes into ajaxSettings.\n    ajaxSetup: function( target, settings ) {\n        return settings ?\n\n            // Building a settings object\n            ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n            // Extending ajaxSettings\n            ajaxExtend( jQuery.ajaxSettings, target );\n    },\n\n    ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n    ajaxTransport: addToPrefiltersOrTransports( transports ),\n\n    // Main method\n    ajax: function( url, options ) {\n\n        // If url is an object, simulate pre-1.5 signature\n        if ( typeof url === \"object\" ) {\n            options = url;\n            url = undefined;\n        }\n\n        // Force options to be an object\n        options = options || {};\n\n        var // Cross-domain detection vars\n            parts,\n            // Loop variable\n            i,\n            // URL without anti-cache param\n            cacheURL,\n            // Response headers as string\n            responseHeadersString,\n            // timeout handle\n            timeoutTimer,\n\n            // To know if global events are to be dispatched\n            fireGlobals,\n\n            transport,\n            // Response headers\n            responseHeaders,\n            // Create the final options object\n            s = jQuery.ajaxSetup( {}, options ),\n            // Callbacks context\n            callbackContext = s.context || s,\n            // Context for global events is callbackContext if it is a DOM node or jQuery collection\n            globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n                jQuery( callbackContext ) :\n                jQuery.event,\n            // Deferreds\n            deferred = jQuery.Deferred(),\n            completeDeferred = jQuery.Callbacks(\"once memory\"),\n            // Status-dependent callbacks\n            statusCode = s.statusCode || {},\n            // Headers (they are sent all at once)\n            requestHeaders = {},\n            requestHeadersNames = {},\n            // The jqXHR state\n            state = 0,\n            // Default abort message\n            strAbort = \"canceled\",\n            // Fake xhr\n            jqXHR = {\n                readyState: 0,\n\n                // Builds headers hashtable if needed\n                getResponseHeader: function( key ) {\n                    var match;\n                    if ( state === 2 ) {\n                        if ( !responseHeaders ) {\n                            responseHeaders = {};\n                            while ( (match = rheaders.exec( responseHeadersString )) ) {\n                                responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n                            }\n                        }\n                        match = responseHeaders[ key.toLowerCase() ];\n                    }\n                    return match == null ? null : match;\n                },\n\n                // Raw string\n                getAllResponseHeaders: function() {\n                    return state === 2 ? responseHeadersString : null;\n                },\n\n                // Caches the header\n                setRequestHeader: function( name, value ) {\n                    var lname = name.toLowerCase();\n                    if ( !state ) {\n                        name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n                        requestHeaders[ name ] = value;\n                    }\n                    return this;\n                },\n\n                // Overrides response content-type header\n                overrideMimeType: function( type ) {\n                    if ( !state ) {\n                        s.mimeType = type;\n                    }\n                    return this;\n                },\n\n                // Status-dependent callbacks\n                statusCode: function( map ) {\n                    var code;\n                    if ( map ) {\n                        if ( state < 2 ) {\n                            for ( code in map ) {\n                                // Lazy-add the new callback in a way that preserves old ones\n                                statusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n                            }\n                        } else {\n                            // Execute the appropriate callbacks\n                            jqXHR.always( map[ jqXHR.status ] );\n                        }\n                    }\n                    return this;\n                },\n\n                // Cancel the request\n                abort: function( statusText ) {\n                    var finalText = statusText || strAbort;\n                    if ( transport ) {\n                        transport.abort( finalText );\n                    }\n                    done( 0, finalText );\n                    return this;\n                }\n            };\n\n        // Attach deferreds\n        deferred.promise( jqXHR ).complete = completeDeferred.add;\n        jqXHR.success = jqXHR.done;\n        jqXHR.error = jqXHR.fail;\n\n        // Remove hash character (#7531: and string promotion)\n        // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n        // Handle falsy url in the settings object (#10093: consistency with old signature)\n        // We also use the url parameter if available\n        s.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n        // Alias method option to type as per ticket #12004\n        s.type = options.method || options.type || s.method || s.type;\n\n        // Extract dataTypes list\n        s.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( core_rnotwhite ) || [\"\"];\n\n        // A cross-domain request is in order when we have a protocol:host:port mismatch\n        if ( s.crossDomain == null ) {\n            parts = rurl.exec( s.url.toLowerCase() );\n            s.crossDomain = !!( parts &&\n                ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n                    ( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n                        ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n            );\n        }\n\n        // Convert data if not already a string\n        if ( s.data && s.processData && typeof s.data !== \"string\" ) {\n            s.data = jQuery.param( s.data, s.traditional );\n        }\n\n        // Apply prefilters\n        inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n        // If request was aborted inside a prefilter, stop there\n        if ( state === 2 ) {\n            return jqXHR;\n        }\n\n        // We can fire global events as of now if asked to\n        fireGlobals = s.global;\n\n        // Watch for a new set of requests\n        if ( fireGlobals && jQuery.active++ === 0 ) {\n            jQuery.event.trigger(\"ajaxStart\");\n        }\n\n        // Uppercase the type\n        s.type = s.type.toUpperCase();\n\n        // Determine if request has content\n        s.hasContent = !rnoContent.test( s.type );\n\n        // Save the URL in case we're toying with the If-Modified-Since\n        // and/or If-None-Match header later on\n        cacheURL = s.url;\n\n        // More options handling for requests with no content\n        if ( !s.hasContent ) {\n\n            // If data is available, append data to url\n            if ( s.data ) {\n                cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n                // #9682: remove data so that it's not used in an eventual retry\n                delete s.data;\n            }\n\n            // Add anti-cache in url if needed\n            if ( s.cache === false ) {\n                s.url = rts.test( cacheURL ) ?\n\n                    // If there is already a '_' parameter, set its value\n                    cacheURL.replace( rts, \"$1_=\" + ajax_nonce++ ) :\n\n                    // Otherwise add one to the end\n                    cacheURL + ( ajax_rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ajax_nonce++;\n            }\n        }\n\n        // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n        if ( s.ifModified ) {\n            if ( jQuery.lastModified[ cacheURL ] ) {\n                jqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n            }\n            if ( jQuery.etag[ cacheURL ] ) {\n                jqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n            }\n        }\n\n        // Set the correct header, if data is being sent\n        if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n            jqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n        }\n\n        // Set the Accepts header for the server, depending on the dataType\n        jqXHR.setRequestHeader(\n            \"Accept\",\n            s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n                s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n                s.accepts[ \"*\" ]\n        );\n\n        // Check for headers option\n        for ( i in s.headers ) {\n            jqXHR.setRequestHeader( i, s.headers[ i ] );\n        }\n\n        // Allow custom headers/mimetypes and early abort\n        if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n            // Abort if not done already and return\n            return jqXHR.abort();\n        }\n\n        // aborting is no longer a cancellation\n        strAbort = \"abort\";\n\n        // Install callbacks on deferreds\n        for ( i in { success: 1, error: 1, complete: 1 } ) {\n            jqXHR[ i ]( s[ i ] );\n        }\n\n        // Get transport\n        transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n        // If no transport, we auto-abort\n        if ( !transport ) {\n            done( -1, \"No Transport\" );\n        } else {\n            jqXHR.readyState = 1;\n\n            // Send global event\n            if ( fireGlobals ) {\n                globalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n            }\n            // Timeout\n            if ( s.async && s.timeout > 0 ) {\n                timeoutTimer = setTimeout(function() {\n                    jqXHR.abort(\"timeout\");\n                }, s.timeout );\n            }\n\n            try {\n                state = 1;\n                transport.send( requestHeaders, done );\n            } catch ( e ) {\n                // Propagate exception as error if not done\n                if ( state < 2 ) {\n                    done( -1, e );\n                // Simply rethrow otherwise\n                } else {\n                    throw e;\n                }\n            }\n        }\n\n        // Callback for when everything is done\n        function done( status, nativeStatusText, responses, headers ) {\n            var isSuccess, success, error, response, modified,\n                statusText = nativeStatusText;\n\n            // Called once\n            if ( state === 2 ) {\n                return;\n            }\n\n            // State is \"done\" now\n            state = 2;\n\n            // Clear timeout if it exists\n            if ( timeoutTimer ) {\n                clearTimeout( timeoutTimer );\n            }\n\n            // Dereference transport for early garbage collection\n            // (no matter how long the jqXHR object will be used)\n            transport = undefined;\n\n            // Cache response headers\n            responseHeadersString = headers || \"\";\n\n            // Set readyState\n            jqXHR.readyState = status > 0 ? 4 : 0;\n\n            // Determine if successful\n            isSuccess = status >= 200 && status < 300 || status === 304;\n\n            // Get response data\n            if ( responses ) {\n                response = ajaxHandleResponses( s, jqXHR, responses );\n            }\n\n            // Convert no matter what (that way responseXXX fields are always set)\n            response = ajaxConvert( s, response, jqXHR, isSuccess );\n\n            // If successful, handle type chaining\n            if ( isSuccess ) {\n\n                // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n                if ( s.ifModified ) {\n                    modified = jqXHR.getResponseHeader(\"Last-Modified\");\n                    if ( modified ) {\n                        jQuery.lastModified[ cacheURL ] = modified;\n                    }\n                    modified = jqXHR.getResponseHeader(\"etag\");\n                    if ( modified ) {\n                        jQuery.etag[ cacheURL ] = modified;\n                    }\n                }\n\n                // if no content\n                if ( status === 204 || s.type === \"HEAD\" ) {\n                    statusText = \"nocontent\";\n\n                // if not modified\n                } else if ( status === 304 ) {\n                    statusText = \"notmodified\";\n\n                // If we have data, let's convert it\n                } else {\n                    statusText = response.state;\n                    success = response.data;\n                    error = response.error;\n                    isSuccess = !error;\n                }\n            } else {\n                // We extract error from statusText\n                // then normalize statusText and status for non-aborts\n                error = statusText;\n                if ( status || !statusText ) {\n                    statusText = \"error\";\n                    if ( status < 0 ) {\n                        status = 0;\n                    }\n                }\n            }\n\n            // Set data for the fake xhr object\n            jqXHR.status = status;\n            jqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n            // Success/Error\n            if ( isSuccess ) {\n                deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n            } else {\n                deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n            }\n\n            // Status-dependent callbacks\n            jqXHR.statusCode( statusCode );\n            statusCode = undefined;\n\n            if ( fireGlobals ) {\n                globalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n                    [ jqXHR, s, isSuccess ? success : error ] );\n            }\n\n            // Complete\n            completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n            if ( fireGlobals ) {\n                globalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n                // Handle the global AJAX counter\n                if ( !( --jQuery.active ) ) {\n                    jQuery.event.trigger(\"ajaxStop\");\n                }\n            }\n        }\n\n        return jqXHR;\n    },\n\n    getJSON: function( url, data, callback ) {\n        return jQuery.get( url, data, callback, \"json\" );\n    },\n\n    getScript: function( url, callback ) {\n        return jQuery.get( url, undefined, callback, \"script\" );\n    }\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n    jQuery[ method ] = function( url, data, callback, type ) {\n        // shift arguments if data argument was omitted\n        if ( jQuery.isFunction( data ) ) {\n            type = type || callback;\n            callback = data;\n            data = undefined;\n        }\n\n        return jQuery.ajax({\n            url: url,\n            type: method,\n            dataType: type,\n            data: data,\n            success: callback\n        });\n    };\n});\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n    var firstDataType, ct, finalDataType, type,\n        contents = s.contents,\n        dataTypes = s.dataTypes;\n\n    // Remove auto dataType and get content-type in the process\n    while( dataTypes[ 0 ] === \"*\" ) {\n        dataTypes.shift();\n        if ( ct === undefined ) {\n            ct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n        }\n    }\n\n    // Check if we're dealing with a known content-type\n    if ( ct ) {\n        for ( type in contents ) {\n            if ( contents[ type ] && contents[ type ].test( ct ) ) {\n                dataTypes.unshift( type );\n                break;\n            }\n        }\n    }\n\n    // Check to see if we have a response for the expected dataType\n    if ( dataTypes[ 0 ] in responses ) {\n        finalDataType = dataTypes[ 0 ];\n    } else {\n        // Try convertible dataTypes\n        for ( type in responses ) {\n            if ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n                finalDataType = type;\n                break;\n            }\n            if ( !firstDataType ) {\n                firstDataType = type;\n            }\n        }\n        // Or just use first one\n        finalDataType = finalDataType || firstDataType;\n    }\n\n    // If we found a dataType\n    // We add the dataType to the list if needed\n    // and return the corresponding response\n    if ( finalDataType ) {\n        if ( finalDataType !== dataTypes[ 0 ] ) {\n            dataTypes.unshift( finalDataType );\n        }\n        return responses[ finalDataType ];\n    }\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n    var conv2, current, conv, tmp, prev,\n        converters = {},\n        // Work with a copy of dataTypes in case we need to modify it for conversion\n        dataTypes = s.dataTypes.slice();\n\n    // Create converters map with lowercased keys\n    if ( dataTypes[ 1 ] ) {\n        for ( conv in s.converters ) {\n            converters[ conv.toLowerCase() ] = s.converters[ conv ];\n        }\n    }\n\n    current = dataTypes.shift();\n\n    // Convert to each sequential dataType\n    while ( current ) {\n\n        if ( s.responseFields[ current ] ) {\n            jqXHR[ s.responseFields[ current ] ] = response;\n        }\n\n        // Apply the dataFilter if provided\n        if ( !prev && isSuccess && s.dataFilter ) {\n            response = s.dataFilter( response, s.dataType );\n        }\n\n        prev = current;\n        current = dataTypes.shift();\n\n        if ( current ) {\n\n            // There's only work to do if current dataType is non-auto\n            if ( current === \"*\" ) {\n\n                current = prev;\n\n            // Convert response if prev dataType is non-auto and differs from current\n            } else if ( prev !== \"*\" && prev !== current ) {\n\n                // Seek a direct converter\n                conv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n                // If none found, seek a pair\n                if ( !conv ) {\n                    for ( conv2 in converters ) {\n\n                        // If conv2 outputs current\n                        tmp = conv2.split( \" \" );\n                        if ( tmp[ 1 ] === current ) {\n\n                            // If prev can be converted to accepted input\n                            conv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n                                converters[ \"* \" + tmp[ 0 ] ];\n                            if ( conv ) {\n                                // Condense equivalence converters\n                                if ( conv === true ) {\n                                    conv = converters[ conv2 ];\n\n                                // Otherwise, insert the intermediate dataType\n                                } else if ( converters[ conv2 ] !== true ) {\n                                    current = tmp[ 0 ];\n                                    dataTypes.unshift( tmp[ 1 ] );\n                                }\n                                break;\n                            }\n                        }\n                    }\n                }\n\n                // Apply converter (if not an equivalence)\n                if ( conv !== true ) {\n\n                    // Unless errors are allowed to bubble, catch and return them\n                    if ( conv && s[ \"throws\" ] ) {\n                        response = conv( response );\n                    } else {\n                        try {\n                            response = conv( response );\n                        } catch ( e ) {\n                            return { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    return { state: \"success\", data: response };\n}\n// Install script dataType\njQuery.ajaxSetup({\n    accepts: {\n        script: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n    },\n    contents: {\n        script: /(?:java|ecma)script/\n    },\n    converters: {\n        \"text script\": function( text ) {\n            jQuery.globalEval( text );\n            return text;\n        }\n    }\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n    if ( s.cache === undefined ) {\n        s.cache = false;\n    }\n    if ( s.crossDomain ) {\n        s.type = \"GET\";\n        s.global = false;\n    }\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n    // This transport only deals with cross domain requests\n    if ( s.crossDomain ) {\n\n        var script,\n            head = document.head || jQuery(\"head\")[0] || document.documentElement;\n\n        return {\n\n            send: function( _, callback ) {\n\n                script = document.createElement(\"script\");\n\n                script.async = true;\n\n                if ( s.scriptCharset ) {\n                    script.charset = s.scriptCharset;\n                }\n\n                script.src = s.url;\n\n                // Attach handlers for all browsers\n                script.onload = script.onreadystatechange = function( _, isAbort ) {\n\n                    if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n                        // Handle memory leak in IE\n                        script.onload = script.onreadystatechange = null;\n\n                        // Remove the script\n                        if ( script.parentNode ) {\n                            script.parentNode.removeChild( script );\n                        }\n\n                        // Dereference the script\n                        script = null;\n\n                        // Callback if not abort\n                        if ( !isAbort ) {\n                            callback( 200, \"success\" );\n                        }\n                    }\n                };\n\n                // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending\n                // Use native DOM manipulation to avoid our domManip AJAX trickery\n                head.insertBefore( script, head.firstChild );\n            },\n\n            abort: function() {\n                if ( script ) {\n                    script.onload( undefined, true );\n                }\n            }\n        };\n    }\n});\nvar oldCallbacks = [],\n    rjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n    jsonp: \"callback\",\n    jsonpCallback: function() {\n        var callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( ajax_nonce++ ) );\n        this[ callback ] = true;\n        return callback;\n    }\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n    var callbackName, overwritten, responseContainer,\n        jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n            \"url\" :\n            typeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n        );\n\n    // Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n    if ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n        // Get callback name, remembering preexisting value associated with it\n        callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n            s.jsonpCallback() :\n            s.jsonpCallback;\n\n        // Insert callback into url or form data\n        if ( jsonProp ) {\n            s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n        } else if ( s.jsonp !== false ) {\n            s.url += ( ajax_rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n        }\n\n        // Use data converter to retrieve json after script execution\n        s.converters[\"script json\"] = function() {\n            if ( !responseContainer ) {\n                jQuery.error( callbackName + \" was not called\" );\n            }\n            return responseContainer[ 0 ];\n        };\n\n        // force json dataType\n        s.dataTypes[ 0 ] = \"json\";\n\n        // Install callback\n        overwritten = window[ callbackName ];\n        window[ callbackName ] = function() {\n            responseContainer = arguments;\n        };\n\n        // Clean-up function (fires after converters)\n        jqXHR.always(function() {\n            // Restore preexisting value\n            window[ callbackName ] = overwritten;\n\n            // Save back as free\n            if ( s[ callbackName ] ) {\n                // make sure that re-using the options doesn't screw things around\n                s.jsonpCallback = originalSettings.jsonpCallback;\n\n                // save the callback name for future use\n                oldCallbacks.push( callbackName );\n            }\n\n            // Call if it was a function and we have a response\n            if ( responseContainer && jQuery.isFunction( overwritten ) ) {\n                overwritten( responseContainer[ 0 ] );\n            }\n\n            responseContainer = overwritten = undefined;\n        });\n\n        // Delegate to script\n        return \"script\";\n    }\n});\nvar xhrCallbacks, xhrSupported,\n    xhrId = 0,\n    // #5280: Internet Explorer will keep connections alive if we don't abort on unload\n    xhrOnUnloadAbort = window.ActiveXObject && function() {\n        // Abort all pending requests\n        var key;\n        for ( key in xhrCallbacks ) {\n            xhrCallbacks[ key ]( undefined, true );\n        }\n    };\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n    try {\n        return new window.XMLHttpRequest();\n    } catch( e ) {}\n}\n\nfunction createActiveXHR() {\n    try {\n        return new window.ActiveXObject(\"Microsoft.XMLHTTP\");\n    } catch( e ) {}\n}\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject ?\n    /* Microsoft failed to properly\n     * implement the XMLHttpRequest in IE7 (can't request local files),\n     * so we use the ActiveXObject when it is available\n     * Additionally XMLHttpRequest can be disabled in IE7/IE8 so\n     * we need a fallback.\n     */\n    function() {\n        return !this.isLocal && createStandardXHR() || createActiveXHR();\n    } :\n    // For all other browsers, use the standard XMLHttpRequest object\n    createStandardXHR;\n\n// Determine support properties\nxhrSupported = jQuery.ajaxSettings.xhr();\njQuery.support.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nxhrSupported = jQuery.support.ajax = !!xhrSupported;\n\n// Create transport if the browser can provide an xhr\nif ( xhrSupported ) {\n\n    jQuery.ajaxTransport(function( s ) {\n        // Cross domain only allowed if supported through XMLHttpRequest\n        if ( !s.crossDomain || jQuery.support.cors ) {\n\n            var callback;\n\n            return {\n                send: function( headers, complete ) {\n\n                    // Get a new xhr\n                    var handle, i,\n                        xhr = s.xhr();\n\n                    // Open the socket\n                    // Passing null username, generates a login popup on Opera (#2865)\n                    if ( s.username ) {\n                        xhr.open( s.type, s.url, s.async, s.username, s.password );\n                    } else {\n                        xhr.open( s.type, s.url, s.async );\n                    }\n\n                    // Apply custom fields if provided\n                    if ( s.xhrFields ) {\n                        for ( i in s.xhrFields ) {\n                            xhr[ i ] = s.xhrFields[ i ];\n                        }\n                    }\n\n                    // Override mime type if needed\n                    if ( s.mimeType && xhr.overrideMimeType ) {\n                        xhr.overrideMimeType( s.mimeType );\n                    }\n\n                    // X-Requested-With header\n                    // For cross-domain requests, seeing as conditions for a preflight are\n                    // akin to a jigsaw puzzle, we simply never set it to be sure.\n                    // (it can always be set on a per-request basis or even using ajaxSetup)\n                    // For same-domain requests, won't change header if already provided.\n                    if ( !s.crossDomain && !headers[\"X-Requested-With\"] ) {\n                        headers[\"X-Requested-With\"] = \"XMLHttpRequest\";\n                    }\n\n                    // Need an extra try/catch for cross domain requests in Firefox 3\n                    try {\n                        for ( i in headers ) {\n                            xhr.setRequestHeader( i, headers[ i ] );\n                        }\n                    } catch( err ) {}\n\n                    // Do send the request\n                    // This may raise an exception which is actually\n                    // handled in jQuery.ajax (so no try/catch here)\n                    xhr.send( ( s.hasContent && s.data ) || null );\n\n                    // Listener\n                    callback = function( _, isAbort ) {\n                        var status, responseHeaders, statusText, responses;\n\n                        // Firefox throws exceptions when accessing properties\n                        // of an xhr when a network error occurred\n                        // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)\n                        try {\n\n                            // Was never called and is aborted or complete\n                            if ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\n                                // Only called once\n                                callback = undefined;\n\n                                // Do not keep as active anymore\n                                if ( handle ) {\n                                    xhr.onreadystatechange = jQuery.noop;\n                                    if ( xhrOnUnloadAbort ) {\n                                        delete xhrCallbacks[ handle ];\n                                    }\n                                }\n\n                                // If it's an abort\n                                if ( isAbort ) {\n                                    // Abort it manually if needed\n                                    if ( xhr.readyState !== 4 ) {\n                                        xhr.abort();\n                                    }\n                                } else {\n                                    responses = {};\n                                    status = xhr.status;\n                                    responseHeaders = xhr.getAllResponseHeaders();\n\n                                    // When requesting binary data, IE6-9 will throw an exception\n                                    // on any attempt to access responseText (#11426)\n                                    if ( typeof xhr.responseText === \"string\" ) {\n                                        responses.text = xhr.responseText;\n                                    }\n\n                                    // Firefox throws an exception when accessing\n                                    // statusText for faulty cross-domain requests\n                                    try {\n                                        statusText = xhr.statusText;\n                                    } catch( e ) {\n                                        // We normalize with Webkit giving an empty statusText\n                                        statusText = \"\";\n                                    }\n\n                                    // Filter status for non standard behaviors\n\n                                    // If the request is local and we have data: assume a success\n                                    // (success with no data won't get notified, that's the best we\n                                    // can do given current implementations)\n                                    if ( !status && s.isLocal && !s.crossDomain ) {\n                                        status = responses.text ? 200 : 404;\n                                    // IE - #1450: sometimes returns 1223 when it should be 204\n                                    } else if ( status === 1223 ) {\n                                        status = 204;\n                                    }\n                                }\n                            }\n                        } catch( firefoxAccessException ) {\n                            if ( !isAbort ) {\n                                complete( -1, firefoxAccessException );\n                            }\n                        }\n\n                        // Call complete if needed\n                        if ( responses ) {\n                            complete( status, statusText, responses, responseHeaders );\n                        }\n                    };\n\n                    if ( !s.async ) {\n                        // if we're in sync mode we fire the callback\n                        callback();\n                    } else if ( xhr.readyState === 4 ) {\n                        // (IE6 & IE7) if it's in cache and has been\n                        // retrieved directly we need to fire the callback\n                        setTimeout( callback );\n                    } else {\n                        handle = ++xhrId;\n                        if ( xhrOnUnloadAbort ) {\n                            // Create the active xhrs callbacks list if needed\n                            // and attach the unload handler\n                            if ( !xhrCallbacks ) {\n                                xhrCallbacks = {};\n                                jQuery( window ).unload( xhrOnUnloadAbort );\n                            }\n                            // Add to list of active xhrs callbacks\n                            xhrCallbacks[ handle ] = callback;\n                        }\n                        xhr.onreadystatechange = callback;\n                    }\n                },\n\n                abort: function() {\n                    if ( callback ) {\n                        callback( undefined, true );\n                    }\n                }\n            };\n        }\n    });\n}\nvar fxNow, timerId,\n    rfxtypes = /^(?:toggle|show|hide)$/,\n    rfxnum = new RegExp( \"^(?:([+-])=|)(\" + core_pnum + \")([a-z%]*)$\", \"i\" ),\n    rrun = /queueHooks$/,\n    animationPrefilters = [ defaultPrefilter ],\n    tweeners = {\n        \"*\": [function( prop, value ) {\n            var tween = this.createTween( prop, value ),\n                target = tween.cur(),\n                parts = rfxnum.exec( value ),\n                unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n                // Starting value computation is required for potential unit mismatches\n                start = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n                    rfxnum.exec( jQuery.css( tween.elem, prop ) ),\n                scale = 1,\n                maxIterations = 20;\n\n            if ( start && start[ 3 ] !== unit ) {\n                // Trust units reported by jQuery.css\n                unit = unit || start[ 3 ];\n\n                // Make sure we update the tween properties later on\n                parts = parts || [];\n\n                // Iteratively approximate from a nonzero starting point\n                start = +target || 1;\n\n                do {\n                    // If previous iteration zeroed out, double until we get *something*\n                    // Use a string for doubling factor so we don't accidentally see scale as unchanged below\n                    scale = scale || \".5\";\n\n                    // Adjust and apply\n                    start = start / scale;\n                    jQuery.style( tween.elem, prop, start + unit );\n\n                // Update scale, tolerating zero or NaN from tween.cur()\n                // And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n                } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n            }\n\n            // Update tween properties\n            if ( parts ) {\n                start = tween.start = +start || +target || 0;\n                tween.unit = unit;\n                // If a +=/-= token was provided, we're doing a relative animation\n                tween.end = parts[ 1 ] ?\n                    start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n                    +parts[ 2 ];\n            }\n\n            return tween;\n        }]\n    };\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n    setTimeout(function() {\n        fxNow = undefined;\n    });\n    return ( fxNow = jQuery.now() );\n}\n\nfunction createTween( value, prop, animation ) {\n    var tween,\n        collection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n        index = 0,\n        length = collection.length;\n    for ( ; index < length; index++ ) {\n        if ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\n            // we're done with this property\n            return tween;\n        }\n    }\n}\n\nfunction Animation( elem, properties, options ) {\n    var result,\n        stopped,\n        index = 0,\n        length = animationPrefilters.length,\n        deferred = jQuery.Deferred().always( function() {\n            // don't match elem in the :animated selector\n            delete tick.elem;\n        }),\n        tick = function() {\n            if ( stopped ) {\n                return false;\n            }\n            var currentTime = fxNow || createFxNow(),\n                remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n                // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n                temp = remaining / animation.duration || 0,\n                percent = 1 - temp,\n                index = 0,\n                length = animation.tweens.length;\n\n            for ( ; index < length ; index++ ) {\n                animation.tweens[ index ].run( percent );\n            }\n\n            deferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n            if ( percent < 1 && length ) {\n                return remaining;\n            } else {\n                deferred.resolveWith( elem, [ animation ] );\n                return false;\n            }\n        },\n        animation = deferred.promise({\n            elem: elem,\n            props: jQuery.extend( {}, properties ),\n            opts: jQuery.extend( true, { specialEasing: {} }, options ),\n            originalProperties: properties,\n            originalOptions: options,\n            startTime: fxNow || createFxNow(),\n            duration: options.duration,\n            tweens: [],\n            createTween: function( prop, end ) {\n                var tween = jQuery.Tween( elem, animation.opts, prop, end,\n                        animation.opts.specialEasing[ prop ] || animation.opts.easing );\n                animation.tweens.push( tween );\n                return tween;\n            },\n            stop: function( gotoEnd ) {\n                var index = 0,\n                    // if we are going to the end, we want to run all the tweens\n                    // otherwise we skip this part\n                    length = gotoEnd ? animation.tweens.length : 0;\n                if ( stopped ) {\n                    return this;\n                }\n                stopped = true;\n                for ( ; index < length ; index++ ) {\n                    animation.tweens[ index ].run( 1 );\n                }\n\n                // resolve when we played the last frame\n                // otherwise, reject\n                if ( gotoEnd ) {\n                    deferred.resolveWith( elem, [ animation, gotoEnd ] );\n                } else {\n                    deferred.rejectWith( elem, [ animation, gotoEnd ] );\n                }\n                return this;\n            }\n        }),\n        props = animation.props;\n\n    propFilter( props, animation.opts.specialEasing );\n\n    for ( ; index < length ; index++ ) {\n        result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n        if ( result ) {\n            return result;\n        }\n    }\n\n    jQuery.map( props, createTween, animation );\n\n    if ( jQuery.isFunction( animation.opts.start ) ) {\n        animation.opts.start.call( elem, animation );\n    }\n\n    jQuery.fx.timer(\n        jQuery.extend( tick, {\n            elem: elem,\n            anim: animation,\n            queue: animation.opts.queue\n        })\n    );\n\n    // attach callbacks from options\n    return animation.progress( animation.opts.progress )\n        .done( animation.opts.done, animation.opts.complete )\n        .fail( animation.opts.fail )\n        .always( animation.opts.always );\n}\n\nfunction propFilter( props, specialEasing ) {\n    var index, name, easing, value, hooks;\n\n    // camelCase, specialEasing and expand cssHook pass\n    for ( index in props ) {\n        name = jQuery.camelCase( index );\n        easing = specialEasing[ name ];\n        value = props[ index ];\n        if ( jQuery.isArray( value ) ) {\n            easing = value[ 1 ];\n            value = props[ index ] = value[ 0 ];\n        }\n\n        if ( index !== name ) {\n            props[ name ] = value;\n            delete props[ index ];\n        }\n\n        hooks = jQuery.cssHooks[ name ];\n        if ( hooks && \"expand\" in hooks ) {\n            value = hooks.expand( value );\n            delete props[ name ];\n\n            // not quite $.extend, this wont overwrite keys already present.\n            // also - reusing 'index' from above because we have the correct \"name\"\n            for ( index in value ) {\n                if ( !( index in props ) ) {\n                    props[ index ] = value[ index ];\n                    specialEasing[ index ] = easing;\n                }\n            }\n        } else {\n            specialEasing[ name ] = easing;\n        }\n    }\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n    tweener: function( props, callback ) {\n        if ( jQuery.isFunction( props ) ) {\n            callback = props;\n            props = [ \"*\" ];\n        } else {\n            props = props.split(\" \");\n        }\n\n        var prop,\n            index = 0,\n            length = props.length;\n\n        for ( ; index < length ; index++ ) {\n            prop = props[ index ];\n            tweeners[ prop ] = tweeners[ prop ] || [];\n            tweeners[ prop ].unshift( callback );\n        }\n    },\n\n    prefilter: function( callback, prepend ) {\n        if ( prepend ) {\n            animationPrefilters.unshift( callback );\n        } else {\n            animationPrefilters.push( callback );\n        }\n    }\n});\n\nfunction defaultPrefilter( elem, props, opts ) {\n    /* jshint validthis: true */\n    var prop, value, toggle, tween, hooks, oldfire,\n        anim = this,\n        orig = {},\n        style = elem.style,\n        hidden = elem.nodeType && isHidden( elem ),\n        dataShow = jQuery._data( elem, \"fxshow\" );\n\n    // handle queue: false promises\n    if ( !opts.queue ) {\n        hooks = jQuery._queueHooks( elem, \"fx\" );\n        if ( hooks.unqueued == null ) {\n            hooks.unqueued = 0;\n            oldfire = hooks.empty.fire;\n            hooks.empty.fire = function() {\n                if ( !hooks.unqueued ) {\n                    oldfire();\n                }\n            };\n        }\n        hooks.unqueued++;\n\n        anim.always(function() {\n            // doing this makes sure that the complete handler will be called\n            // before this completes\n            anim.always(function() {\n                hooks.unqueued--;\n                if ( !jQuery.queue( elem, \"fx\" ).length ) {\n                    hooks.empty.fire();\n                }\n            });\n        });\n    }\n\n    // height/width overflow pass\n    if ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n        // Make sure that nothing sneaks out\n        // Record all 3 overflow attributes because IE does not\n        // change the overflow attribute when overflowX and\n        // overflowY are set to the same value\n        opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n        // Set display property to inline-block for height/width\n        // animations on inline elements that are having width/height animated\n        if ( jQuery.css( elem, \"display\" ) === \"inline\" &&\n                jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n            // inline-level elements accept inline-block;\n            // block-level elements need to be inline with layout\n            if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === \"inline\" ) {\n                style.display = \"inline-block\";\n\n            } else {\n                style.zoom = 1;\n            }\n        }\n    }\n\n    if ( opts.overflow ) {\n        style.overflow = \"hidden\";\n        if ( !jQuery.support.shrinkWrapBlocks ) {\n            anim.always(function() {\n                style.overflow = opts.overflow[ 0 ];\n                style.overflowX = opts.overflow[ 1 ];\n                style.overflowY = opts.overflow[ 2 ];\n            });\n        }\n    }\n\n\n    // show/hide pass\n    for ( prop in props ) {\n        value = props[ prop ];\n        if ( rfxtypes.exec( value ) ) {\n            delete props[ prop ];\n            toggle = toggle || value === \"toggle\";\n            if ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n                continue;\n            }\n            orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n        }\n    }\n\n    if ( !jQuery.isEmptyObject( orig ) ) {\n        if ( dataShow ) {\n            if ( \"hidden\" in dataShow ) {\n                hidden = dataShow.hidden;\n            }\n        } else {\n            dataShow = jQuery._data( elem, \"fxshow\", {} );\n        }\n\n        // store state if its toggle - enables .stop().toggle() to \"reverse\"\n        if ( toggle ) {\n            dataShow.hidden = !hidden;\n        }\n        if ( hidden ) {\n            jQuery( elem ).show();\n        } else {\n            anim.done(function() {\n                jQuery( elem ).hide();\n            });\n        }\n        anim.done(function() {\n            var prop;\n            jQuery._removeData( elem, \"fxshow\" );\n            for ( prop in orig ) {\n                jQuery.style( elem, prop, orig[ prop ] );\n            }\n        });\n        for ( prop in orig ) {\n            tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n            if ( !( prop in dataShow ) ) {\n                dataShow[ prop ] = tween.start;\n                if ( hidden ) {\n                    tween.end = tween.start;\n                    tween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n                }\n            }\n        }\n    }\n}\n\nfunction Tween( elem, options, prop, end, easing ) {\n    return new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n    constructor: Tween,\n    init: function( elem, options, prop, end, easing, unit ) {\n        this.elem = elem;\n        this.prop = prop;\n        this.easing = easing || \"swing\";\n        this.options = options;\n        this.start = this.now = this.cur();\n        this.end = end;\n        this.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n    },\n    cur: function() {\n        var hooks = Tween.propHooks[ this.prop ];\n\n        return hooks && hooks.get ?\n            hooks.get( this ) :\n            Tween.propHooks._default.get( this );\n    },\n    run: function( percent ) {\n        var eased,\n            hooks = Tween.propHooks[ this.prop ];\n\n        if ( this.options.duration ) {\n            this.pos = eased = jQuery.easing[ this.easing ](\n                percent, this.options.duration * percent, 0, 1, this.options.duration\n            );\n        } else {\n            this.pos = eased = percent;\n        }\n        this.now = ( this.end - this.start ) * eased + this.start;\n\n        if ( this.options.step ) {\n            this.options.step.call( this.elem, this.now, this );\n        }\n\n        if ( hooks && hooks.set ) {\n            hooks.set( this );\n        } else {\n            Tween.propHooks._default.set( this );\n        }\n        return this;\n    }\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n    _default: {\n        get: function( tween ) {\n            var result;\n\n            if ( tween.elem[ tween.prop ] != null &&\n                (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n                return tween.elem[ tween.prop ];\n            }\n\n            // passing an empty string as a 3rd parameter to .css will automatically\n            // attempt a parseFloat and fallback to a string if the parse fails\n            // so, simple values such as \"10px\" are parsed to Float.\n            // complex values such as \"rotate(1rad)\" are returned as is.\n            result = jQuery.css( tween.elem, tween.prop, \"\" );\n            // Empty strings, null, undefined and \"auto\" are converted to 0.\n            return !result || result === \"auto\" ? 0 : result;\n        },\n        set: function( tween ) {\n            // use step hook for back compat - use cssHook if its there - use .style if its\n            // available and use plain properties where available\n            if ( jQuery.fx.step[ tween.prop ] ) {\n                jQuery.fx.step[ tween.prop ]( tween );\n            } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n                jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n            } else {\n                tween.elem[ tween.prop ] = tween.now;\n            }\n        }\n    }\n};\n\n// Support: IE <=9\n// Panic based approach to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n    set: function( tween ) {\n        if ( tween.elem.nodeType && tween.elem.parentNode ) {\n            tween.elem[ tween.prop ] = tween.now;\n        }\n    }\n};\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n    var cssFn = jQuery.fn[ name ];\n    jQuery.fn[ name ] = function( speed, easing, callback ) {\n        return speed == null || typeof speed === \"boolean\" ?\n            cssFn.apply( this, arguments ) :\n            this.animate( genFx( name, true ), speed, easing, callback );\n    };\n});\n\njQuery.fn.extend({\n    fadeTo: function( speed, to, easing, callback ) {\n\n        // show any hidden elements after setting opacity to 0\n        return this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n            // animate to the value specified\n            .end().animate({ opacity: to }, speed, easing, callback );\n    },\n    animate: function( prop, speed, easing, callback ) {\n        var empty = jQuery.isEmptyObject( prop ),\n            optall = jQuery.speed( speed, easing, callback ),\n            doAnimation = function() {\n                // Operate on a copy of prop so per-property easing won't be lost\n                var anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n                // Empty animations, or finishing resolves immediately\n                if ( empty || jQuery._data( this, \"finish\" ) ) {\n                    anim.stop( true );\n                }\n            };\n            doAnimation.finish = doAnimation;\n\n        return empty || optall.queue === false ?\n            this.each( doAnimation ) :\n            this.queue( optall.queue, doAnimation );\n    },\n    stop: function( type, clearQueue, gotoEnd ) {\n        var stopQueue = function( hooks ) {\n            var stop = hooks.stop;\n            delete hooks.stop;\n            stop( gotoEnd );\n        };\n\n        if ( typeof type !== \"string\" ) {\n            gotoEnd = clearQueue;\n            clearQueue = type;\n            type = undefined;\n        }\n        if ( clearQueue && type !== false ) {\n            this.queue( type || \"fx\", [] );\n        }\n\n        return this.each(function() {\n            var dequeue = true,\n                index = type != null && type + \"queueHooks\",\n                timers = jQuery.timers,\n                data = jQuery._data( this );\n\n            if ( index ) {\n                if ( data[ index ] && data[ index ].stop ) {\n                    stopQueue( data[ index ] );\n                }\n            } else {\n                for ( index in data ) {\n                    if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n                        stopQueue( data[ index ] );\n                    }\n                }\n            }\n\n            for ( index = timers.length; index--; ) {\n                if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n                    timers[ index ].anim.stop( gotoEnd );\n                    dequeue = false;\n                    timers.splice( index, 1 );\n                }\n            }\n\n            // start the next in the queue if the last step wasn't forced\n            // timers currently will call their complete callbacks, which will dequeue\n            // but only if they were gotoEnd\n            if ( dequeue || !gotoEnd ) {\n                jQuery.dequeue( this, type );\n            }\n        });\n    },\n    finish: function( type ) {\n        if ( type !== false ) {\n            type = type || \"fx\";\n        }\n        return this.each(function() {\n            var index,\n                data = jQuery._data( this ),\n                queue = data[ type + \"queue\" ],\n                hooks = data[ type + \"queueHooks\" ],\n                timers = jQuery.timers,\n                length = queue ? queue.length : 0;\n\n            // enable finishing flag on private data\n            data.finish = true;\n\n            // empty the queue first\n            jQuery.queue( this, type, [] );\n\n            if ( hooks && hooks.stop ) {\n                hooks.stop.call( this, true );\n            }\n\n            // look for any active animations, and finish them\n            for ( index = timers.length; index--; ) {\n                if ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n                    timers[ index ].anim.stop( true );\n                    timers.splice( index, 1 );\n                }\n            }\n\n            // look for any animations in the old queue and finish them\n            for ( index = 0; index < length; index++ ) {\n                if ( queue[ index ] && queue[ index ].finish ) {\n                    queue[ index ].finish.call( this );\n                }\n            }\n\n            // turn off finishing flag\n            delete data.finish;\n        });\n    }\n});\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n    var which,\n        attrs = { height: type },\n        i = 0;\n\n    // if we include width, step value is 1 to do all cssExpand values,\n    // if we don't include width, step value is 2 to skip over Left and Right\n    includeWidth = includeWidth? 1 : 0;\n    for( ; i < 4 ; i += 2 - includeWidth ) {\n        which = cssExpand[ i ];\n        attrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n    }\n\n    if ( includeWidth ) {\n        attrs.opacity = attrs.width = type;\n    }\n\n    return attrs;\n}\n\n// Generate shortcuts for custom animations\njQuery.each({\n    slideDown: genFx(\"show\"),\n    slideUp: genFx(\"hide\"),\n    slideToggle: genFx(\"toggle\"),\n    fadeIn: { opacity: \"show\" },\n    fadeOut: { opacity: \"hide\" },\n    fadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n    jQuery.fn[ name ] = function( speed, easing, callback ) {\n        return this.animate( props, speed, easing, callback );\n    };\n});\n\njQuery.speed = function( speed, easing, fn ) {\n    var opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n        complete: fn || !fn && easing ||\n            jQuery.isFunction( speed ) && speed,\n        duration: speed,\n        easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n    };\n\n    opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n        opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n    // normalize opt.queue - true/undefined/null -> \"fx\"\n    if ( opt.queue == null || opt.queue === true ) {\n        opt.queue = \"fx\";\n    }\n\n    // Queueing\n    opt.old = opt.complete;\n\n    opt.complete = function() {\n        if ( jQuery.isFunction( opt.old ) ) {\n            opt.old.call( this );\n        }\n\n        if ( opt.queue ) {\n            jQuery.dequeue( this, opt.queue );\n        }\n    };\n\n    return opt;\n};\n\njQuery.easing = {\n    linear: function( p ) {\n        return p;\n    },\n    swing: function( p ) {\n        return 0.5 - Math.cos( p*Math.PI ) / 2;\n    }\n};\n\njQuery.timers = [];\njQuery.fx = Tween.prototype.init;\njQuery.fx.tick = function() {\n    var timer,\n        timers = jQuery.timers,\n        i = 0;\n\n    fxNow = jQuery.now();\n\n    for ( ; i < timers.length; i++ ) {\n        timer = timers[ i ];\n        // Checks the timer has not already been removed\n        if ( !timer() && timers[ i ] === timer ) {\n            timers.splice( i--, 1 );\n        }\n    }\n\n    if ( !timers.length ) {\n        jQuery.fx.stop();\n    }\n    fxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n    if ( timer() && jQuery.timers.push( timer ) ) {\n        jQuery.fx.start();\n    }\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n    if ( !timerId ) {\n        timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n    }\n};\n\njQuery.fx.stop = function() {\n    clearInterval( timerId );\n    timerId = null;\n};\n\njQuery.fx.speeds = {\n    slow: 600,\n    fast: 200,\n    // Default speed\n    _default: 400\n};\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n    jQuery.expr.filters.animated = function( elem ) {\n        return jQuery.grep(jQuery.timers, function( fn ) {\n            return elem === fn.elem;\n        }).length;\n    };\n}\njQuery.fn.offset = function( options ) {\n    if ( arguments.length ) {\n        return options === undefined ?\n            this :\n            this.each(function( i ) {\n                jQuery.offset.setOffset( this, options, i );\n            });\n    }\n\n    var docElem, win,\n        box = { top: 0, left: 0 },\n        elem = this[ 0 ],\n        doc = elem && elem.ownerDocument;\n\n    if ( !doc ) {\n        return;\n    }\n\n    docElem = doc.documentElement;\n\n    // Make sure it's not a disconnected DOM node\n    if ( !jQuery.contains( docElem, elem ) ) {\n        return box;\n    }\n\n    // If we don't have gBCR, just use 0,0 rather than error\n    // BlackBerry 5, iOS 3 (original iPhone)\n    if ( typeof elem.getBoundingClientRect !== core_strundefined ) {\n        box = elem.getBoundingClientRect();\n    }\n    win = getWindow( doc );\n    return {\n        top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),\n        left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )\n    };\n};\n\njQuery.offset = {\n\n    setOffset: function( elem, options, i ) {\n        var position = jQuery.css( elem, \"position\" );\n\n        // set position first, in-case top/left are set even on static elem\n        if ( position === \"static\" ) {\n            elem.style.position = \"relative\";\n        }\n\n        var curElem = jQuery( elem ),\n            curOffset = curElem.offset(),\n            curCSSTop = jQuery.css( elem, \"top\" ),\n            curCSSLeft = jQuery.css( elem, \"left\" ),\n            calculatePosition = ( position === \"absolute\" || position === \"fixed\" ) && jQuery.inArray(\"auto\", [curCSSTop, curCSSLeft]) > -1,\n            props = {}, curPosition = {}, curTop, curLeft;\n\n        // need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n        if ( calculatePosition ) {\n            curPosition = curElem.position();\n            curTop = curPosition.top;\n            curLeft = curPosition.left;\n        } else {\n            curTop = parseFloat( curCSSTop ) || 0;\n            curLeft = parseFloat( curCSSLeft ) || 0;\n        }\n\n        if ( jQuery.isFunction( options ) ) {\n            options = options.call( elem, i, curOffset );\n        }\n\n        if ( options.top != null ) {\n            props.top = ( options.top - curOffset.top ) + curTop;\n        }\n        if ( options.left != null ) {\n            props.left = ( options.left - curOffset.left ) + curLeft;\n        }\n\n        if ( \"using\" in options ) {\n            options.using.call( elem, props );\n        } else {\n            curElem.css( props );\n        }\n    }\n};\n\n\njQuery.fn.extend({\n\n    position: function() {\n        if ( !this[ 0 ] ) {\n            return;\n        }\n\n        var offsetParent, offset,\n            parentOffset = { top: 0, left: 0 },\n            elem = this[ 0 ];\n\n        // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n        if ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n            // we assume that getBoundingClientRect is available when computed position is fixed\n            offset = elem.getBoundingClientRect();\n        } else {\n            // Get *real* offsetParent\n            offsetParent = this.offsetParent();\n\n            // Get correct offsets\n            offset = this.offset();\n            if ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n                parentOffset = offsetParent.offset();\n            }\n\n            // Add offsetParent borders\n            parentOffset.top  += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n            parentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n        }\n\n        // Subtract parent offsets and element margins\n        // note: when an element has margin: auto the offsetLeft and marginLeft\n        // are the same in Safari causing offset.left to incorrectly be 0\n        return {\n            top:  offset.top  - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n            left: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true)\n        };\n    },\n\n    offsetParent: function() {\n        return this.map(function() {\n            var offsetParent = this.offsetParent || docElem;\n            while ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\") === \"static\" ) ) {\n                offsetParent = offsetParent.offsetParent;\n            }\n            return offsetParent || docElem;\n        });\n    }\n});\n\n\n// Create scrollLeft and scrollTop methods\njQuery.each( {scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\"}, function( method, prop ) {\n    var top = /Y/.test( prop );\n\n    jQuery.fn[ method ] = function( val ) {\n        return jQuery.access( this, function( elem, method, val ) {\n            var win = getWindow( elem );\n\n            if ( val === undefined ) {\n                return win ? (prop in win) ? win[ prop ] :\n                    win.document.documentElement[ method ] :\n                    elem[ method ];\n            }\n\n            if ( win ) {\n                win.scrollTo(\n                    !top ? val : jQuery( win ).scrollLeft(),\n                    top ? val : jQuery( win ).scrollTop()\n                );\n\n            } else {\n                elem[ method ] = val;\n            }\n        }, method, val, arguments.length, null );\n    };\n});\n\nfunction getWindow( elem ) {\n    return jQuery.isWindow( elem ) ?\n        elem :\n        elem.nodeType === 9 ?\n            elem.defaultView || elem.parentWindow :\n            false;\n}\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n    jQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n        // margin is only for outerHeight, outerWidth\n        jQuery.fn[ funcName ] = function( margin, value ) {\n            var chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n                extra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n            return jQuery.access( this, function( elem, type, value ) {\n                var doc;\n\n                if ( jQuery.isWindow( elem ) ) {\n                    // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n                    // isn't a whole lot we can do. See pull request at this URL for discussion:\n                    // https://github.com/jquery/jquery/pull/764\n                    return elem.document.documentElement[ \"client\" + name ];\n                }\n\n                // Get document width or height\n                if ( elem.nodeType === 9 ) {\n                    doc = elem.documentElement;\n\n                    // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n                    // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n                    return Math.max(\n                        elem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n                        elem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n                        doc[ \"client\" + name ]\n                    );\n                }\n\n                return value === undefined ?\n                    // Get width or height on the element, requesting but not forcing parseFloat\n                    jQuery.css( elem, type, extra ) :\n\n                    // Set width or height on the element\n                    jQuery.style( elem, type, value, extra );\n            }, type, chainable ? margin : undefined, chainable, null );\n        };\n    });\n});\n// Limit scope pollution from any deprecated API\n// (function() {\n\n// The number of elements contained in the matched element set\njQuery.fn.size = function() {\n    return this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n// })();\nif ( typeof module === \"object\" && module && typeof module.exports === \"object\" ) {\n    // Expose jQuery as module.exports in loaders that implement the Node\n    // module pattern (including browserify). Do not create the global, since\n    // the user will be storing it themselves locally, and globals are frowned\n    // upon in the Node module world.\n    module.exports = jQuery;\n} else {\n    // Otherwise expose jQuery to the global object as usual\n    window.jQuery = window.$ = jQuery;\n\n    // Register as a named AMD module, since jQuery can be concatenated with other\n    // files that may use define, but not via a proper concatenation script that\n    // understands anonymous AMD modules. A named AMD is safest and most robust\n    // way to register. Lowercase jquery is used because AMD module names are\n    // derived from file names, and jQuery is normally delivered in a lowercase\n    // file name. Do this after creating the global so that if an AMD module wants\n    // to call noConflict to hide this version of jQuery, it will work.\n    if ( typeof define === \"function\" && define.amd ) {\n        define( \"jquery\", [], function () { return jQuery; } );\n    }\n}\n\n})( window );"
  },
  {
    "path": "src/js/lib/when.js",
    "content": "/** @license MIT License (c) copyright 2011-2013 original author or authors */\n\n/**\n * A lightweight CommonJS Promises/A and when() implementation\n * when is part of the cujo.js family of libraries (http://cujojs.com/)\n *\n * Licensed under the MIT License at:\n * http://www.opensource.org/licenses/mit-license.php\n *\n * @author Brian Cavalier\n * @author John Hann\n * @version 2.2.0\n */\n(function(define, global) { 'use strict';\ndefine(function () {\n\n    // Public API\n\n    when.promise   = promise;    // Create a pending promise\n    when.resolve   = resolve;    // Create a resolved promise\n    when.reject    = reject;     // Create a rejected promise\n    when.defer     = defer;      // Create a {promise, resolver} pair\n\n    when.join      = join;       // Join 2 or more promises\n\n    when.all       = all;        // Resolve a list of promises\n    when.map       = map;        // Array.map() for promises\n    when.reduce    = reduce;     // Array.reduce() for promises\n    when.settle    = settle;     // Settle a list of promises\n\n    when.any       = any;        // One-winner race\n    when.some      = some;       // Multi-winner race\n\n    when.isPromise = isPromise;  // Determine if a thing is a promise\n\n\n    /**\n     * Register an observer for a promise or immediate value.\n     *\n     * @param {*} promiseOrValue\n     * @param {function?} [onFulfilled] callback to be called when promiseOrValue is\n     *   successfully fulfilled.  If promiseOrValue is an immediate value, callback\n     *   will be invoked immediately.\n     * @param {function?} [onRejected] callback to be called when promiseOrValue is\n     *   rejected.\n     * @param {function?} [onProgress] callback to be called when progress updates\n     *   are issued for promiseOrValue.\n     * @returns {Promise} a new {@link Promise} that will complete with the return\n     *   value of callback or errback or the completion value of promiseOrValue if\n     *   callback and/or errback is not supplied.\n     */\n    function when(promiseOrValue, onFulfilled, onRejected, onProgress) {\n        // Get a trusted promise for the input promiseOrValue, and then\n        // register promise handlers\n        return resolve(promiseOrValue).then(onFulfilled, onRejected, onProgress);\n    }\n\n    /**\n     * Trusted Promise constructor.  A Promise created from this constructor is\n     * a trusted when.js promise.  Any other duck-typed promise is considered\n     * untrusted.\n     * @constructor\n     * @name Promise\n     */\n    function Promise(then, inspect) {\n        this.then = then;\n        this.inspect = inspect;\n    }\n\n    Promise.prototype = {\n        /**\n         * Register a rejection handler.  Shortcut for .then(undefined, onRejected)\n         * @param {function?} onRejected\n         * @return {Promise}\n         */\n        otherwise: function(onRejected) {\n            return this.then(undef, onRejected);\n        },\n\n        /**\n         * Ensures that onFulfilledOrRejected will be called regardless of whether\n         * this promise is fulfilled or rejected.  onFulfilledOrRejected WILL NOT\n         * receive the promises' value or reason.  Any returned value will be disregarded.\n         * onFulfilledOrRejected may throw or return a rejected promise to signal\n         * an additional error.\n         * @param {function} onFulfilledOrRejected handler to be called regardless of\n         *  fulfillment or rejection\n         * @returns {Promise}\n         */\n        ensure: function(onFulfilledOrRejected) {\n            return this.then(injectHandler, injectHandler)['yield'](this);\n\n            function injectHandler() {\n                return resolve(onFulfilledOrRejected());\n            }\n        },\n\n        /**\n         * Shortcut for .then(function() { return value; })\n         * @param  {*} value\n         * @return {Promise} a promise that:\n         *  - is fulfilled if value is not a promise, or\n         *  - if value is a promise, will fulfill with its value, or reject\n         *    with its reason.\n         */\n        'yield': function(value) {\n            return this.then(function() {\n                return value;\n            });\n        },\n\n        /**\n         * Assumes that this promise will fulfill with an array, and arranges\n         * for the onFulfilled to be called with the array as its argument list\n         * i.e. onFulfilled.apply(undefined, array).\n         * @param {function} onFulfilled function to receive spread arguments\n         * @return {Promise}\n         */\n        spread: function(onFulfilled) {\n            return this.then(function(array) {\n                // array may contain promises, so resolve its contents.\n                return all(array, function(array) {\n                    return onFulfilled.apply(undef, array);\n                });\n            });\n        },\n\n        /**\n         * Shortcut for .then(onFulfilledOrRejected, onFulfilledOrRejected)\n         * @deprecated\n         */\n        always: function(onFulfilledOrRejected, onProgress) {\n            return this.then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress);\n        }\n    };\n\n    /**\n     * Returns a resolved promise. The returned promise will be\n     *  - fulfilled with promiseOrValue if it is a value, or\n     *  - if promiseOrValue is a promise\n     *    - fulfilled with promiseOrValue's value after it is fulfilled\n     *    - rejected with promiseOrValue's reason after it is rejected\n     * @param  {*} value\n     * @return {Promise}\n     */\n    function resolve(value) {\n        return promise(function(resolve) {\n            resolve(value);\n        });\n    }\n\n    /**\n     * Returns a rejected promise for the supplied promiseOrValue.  The returned\n     * promise will be rejected with:\n     * - promiseOrValue, if it is a value, or\n     * - if promiseOrValue is a promise\n     *   - promiseOrValue's value after it is fulfilled\n     *   - promiseOrValue's reason after it is rejected\n     * @param {*} promiseOrValue the rejected value of the returned {@link Promise}\n     * @return {Promise} rejected {@link Promise}\n     */\n    function reject(promiseOrValue) {\n        return when(promiseOrValue, rejected);\n    }\n\n    /**\n     * Creates a {promise, resolver} pair, either or both of which\n     * may be given out safely to consumers.\n     * The resolver has resolve, reject, and progress.  The promise\n     * has then plus extended promise API.\n     *\n     * @return {{\n     * promise: Promise,\n     * resolve: function:Promise,\n     * reject: function:Promise,\n     * notify: function:Promise\n     * resolver: {\n     *  resolve: function:Promise,\n     *  reject: function:Promise,\n     *  notify: function:Promise\n     * }}}\n     */\n    function defer() {\n        var deferred, pending, resolved;\n\n        // Optimize object shape\n        deferred = {\n            promise: undef, resolve: undef, reject: undef, notify: undef,\n            resolver: { resolve: undef, reject: undef, notify: undef }\n        };\n\n        deferred.promise = pending = _promise(makeDeferred);\n\n        return deferred;\n\n        function makeDeferred(resolvePending, rejectPending, notifyPending) {\n            deferred.resolve = deferred.resolver.resolve = function(value) {\n                if(resolved) {\n                    return resolve(value);\n                }\n                resolved = true;\n                resolvePending(value);\n                return pending;\n            };\n\n            deferred.reject  = deferred.resolver.reject  = function(reason) {\n                if(resolved) {\n                    return resolve(rejected(reason));\n                }\n                resolved = true;\n                rejectPending(reason);\n                return pending;\n            };\n\n            deferred.notify  = deferred.resolver.notify  = function(update) {\n                notifyPending(update);\n                return update;\n            };\n        }\n    }\n\n    /**\n     * Creates a new promise whose fate is determined by resolver.\n     * @param {function} resolver function(resolve, reject, notify)\n     * @returns {Promise} promise whose fate is determine by resolver\n     */\n    function promise(resolver) {\n        return _promise(resolver, monitorApi.PromiseStatus && monitorApi.PromiseStatus());\n    }\n\n    /**\n     * Creates a new promise, linked to parent, whose fate is determined\n     * by resolver.\n     * @param {function} resolver function(resolve, reject, notify)\n     * @param {Promise?} status promise from which the new promise is begotten\n     * @returns {Promise} promise whose fate is determine by resolver\n     * @private\n     */\n    function _promise(resolver, status) {\n        var self, value, handlers = [];\n\n        self = new Promise(then, inspect);\n\n        // Call the provider resolver to seal the promise's fate\n        //try {\n            resolver(promiseResolve, promiseReject, promiseNotify);\n        //} catch(e) {\n           // promiseReject(e);\n       // }\n\n        // Return the promise\n        return self;\n\n        /**\n         * Register handlers for this promise.\n         * @param [onFulfilled] {Function} fulfillment handler\n         * @param [onRejected] {Function} rejection handler\n         * @param [onProgress] {Function} progress handler\n         * @return {Promise} new Promise\n         */\n        function then(onFulfilled, onRejected, onProgress) {\n            var next = _promise(function(resolve, reject, notify) {\n                // if not resolved, push onto handlers, otherwise execute asap\n                // but not in the current stack\n                handlers ? handlers.push(run) : enqueue(function() { run(value); });\n\n                function run(p) {\n                    p.then(onFulfilled, onRejected, onProgress)\n                        .then(resolve, reject, notify);\n                }\n\n            }, status && status.observed());\n\n            return next;\n        }\n\n        function inspect() {\n            return value ? value.inspect() : toPendingState();\n        }\n\n        /**\n         * Transition from pre-resolution state to post-resolution state, notifying\n         * all listeners of the ultimate fulfillment or rejection\n         * @param {*|Promise} val resolution value\n         */\n        function promiseResolve(val) {\n            if(!handlers) {\n                return;\n            }\n\n            value = coerce(val);\n            scheduleHandlers(handlers, value);\n            handlers = undef;\n\n            if (status) {\n                value.then(\n                    function () { status.fulfilled(); },\n                    function(r) { status.rejected(r); }\n                );\n            }\n        }\n\n        /**\n         * Reject this promise with the supplied reason, which will be used verbatim.\n         * @param {*} reason reason for the rejection\n         */\n        function promiseReject(reason) {\n            promiseResolve(rejected(reason));\n        }\n\n        /**\n         * Issue a progress event, notifying all progress listeners\n         * @param {*} update progress event payload to pass to all listeners\n         */\n        function promiseNotify(update) {\n            if(handlers) {\n                scheduleHandlers(handlers, progressing(update));\n            }\n        }\n    }\n\n    /**\n     * Coerces x to a trusted Promise\n     *\n     * @private\n     * @param {*} x thing to coerce\n     * @returns {Promise} Guaranteed to return a trusted Promise.  If x\n     *   is trusted, returns x, otherwise, returns a new, trusted, already-resolved\n     *   Promise whose resolution value is:\n     *   * the resolution value of x if it's a foreign promise, or\n     *   * x if it's a value\n     */\n    function coerce(x) {\n        if(x instanceof Promise) {\n            return x;\n        }\n\n        if (!(x === Object(x) && 'then' in x)) {\n            return fulfilled(x);\n        }\n\n        return promise(function(resolve, reject, notify) {\n            enqueue(function() {\n                //try {\n                    // We must check and assimilate in the same tick, but not the\n                    // current tick, careful only to access promiseOrValue.then once.\n                    var untrustedThen = x.then;\n\n                    if(typeof untrustedThen === 'function') {\n                        fcall(untrustedThen, x, resolve, reject, notify);\n                    } else {\n                        // It's a value, create a fulfilled wrapper\n                        resolve(fulfilled(x));\n                    }\n\n                //} catch(e) {\n                    // Something went wrong, reject\n                //    reject(e);\n                //}\n            });\n        });\n    }\n\n    /**\n     * Create an already-fulfilled promise for the supplied value\n     * @private\n     * @param {*} value\n     * @return {Promise} fulfilled promise\n     */\n    function fulfilled(value) {\n        var self = new Promise(function (onFulfilled) {\n            //try {\n                return typeof onFulfilled == 'function'\n                    ? coerce(onFulfilled(value)) : self;\n            //} catch (e) {\n             //   return rejected(e);\n            //}\n        }, function() {\n            return toFulfilledState(value);\n        });\n\n        return self;\n    }\n\n    /**\n     * Create an already-rejected promise with the supplied rejection reason.\n     * @private\n     * @param {*} reason\n     * @return {Promise} rejected promise\n     */\n    function rejected(reason) {\n        var self = new Promise(function (_, onRejected) {\n            //try {\n                return typeof onRejected == 'function'\n                    ? coerce(onRejected(reason)) : self;\n            //} catch (e) {\n             //   return rejected(e);\n            //}\n        }, function() {\n            return toRejectedState(reason);\n        });\n\n        return self;\n    }\n\n    /**\n     * Create a progress promise with the supplied update.\n     * @private\n     * @param {*} update\n     * @return {Promise} progress promise\n     */\n    function progressing(update) {\n        var self = new Promise(function (_, __, onProgress) {\n            //try {\n                return typeof onProgress == 'function'\n                    ? progressing(onProgress(update)) : self;\n            //} catch (e) {\n            //    return progressing(e);\n            //}\n        });\n\n        return self;\n    }\n\n    /**\n     * Schedule a task that will process a list of handlers\n     * in the next queue drain run.\n     * @private\n     * @param {Array} handlers queue of handlers to execute\n     * @param {*} value passed as the only arg to each handler\n     */\n    function scheduleHandlers(handlers, value) {\n        enqueue(function() {\n            var handler, i = 0;\n            while (handler = handlers[i++]) {\n                handler(value);\n            }\n        });\n    }\n\n    /**\n     * Determines if promiseOrValue is a promise or not\n     *\n     * @param {*} promiseOrValue anything\n     * @returns {boolean} true if promiseOrValue is a {@link Promise}\n     */\n    function isPromise(promiseOrValue) {\n        return promiseOrValue && typeof promiseOrValue.then === 'function';\n    }\n\n    /**\n     * Initiates a competitive race, returning a promise that will resolve when\n     * howMany of the supplied promisesOrValues have resolved, or will reject when\n     * it becomes impossible for howMany to resolve, for example, when\n     * (promisesOrValues.length - howMany) + 1 input promises reject.\n     *\n     * @param {Array} promisesOrValues array of anything, may contain a mix\n     *      of promises and values\n     * @param howMany {number} number of promisesOrValues to resolve\n     * @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then()\n     * @param {function?} [onRejected] DEPRECATED, use returnedPromise.then()\n     * @param {function?} [onProgress] DEPRECATED, use returnedPromise.then()\n     * @returns {Promise} promise that will resolve to an array of howMany values that\n     *  resolved first, or will reject with an array of\n     *  (promisesOrValues.length - howMany) + 1 rejection reasons.\n     */\n    function some(promisesOrValues, howMany, onFulfilled, onRejected, onProgress) {\n\n        return when(promisesOrValues, function(promisesOrValues) {\n\n            return promise(resolveSome).then(onFulfilled, onRejected, onProgress);\n\n            function resolveSome(resolve, reject, notify) {\n                var toResolve, toReject, values, reasons, fulfillOne, rejectOne, len, i;\n\n                len = promisesOrValues.length >>> 0;\n\n                toResolve = Math.max(0, Math.min(howMany, len));\n                values = [];\n\n                toReject = (len - toResolve) + 1;\n                reasons = [];\n\n                // No items in the input, resolve immediately\n                if (!toResolve) {\n                    resolve(values);\n\n                } else {\n                    rejectOne = function(reason) {\n                        reasons.push(reason);\n                        if(!--toReject) {\n                            fulfillOne = rejectOne = identity;\n                            reject(reasons);\n                        }\n                    };\n\n                    fulfillOne = function(val) {\n                        // This orders the values based on promise resolution order\n                        values.push(val);\n                        if (!--toResolve) {\n                            fulfillOne = rejectOne = identity;\n                            resolve(values);\n                        }\n                    };\n\n                    for(i = 0; i < len; ++i) {\n                        if(i in promisesOrValues) {\n                            when(promisesOrValues[i], fulfiller, rejecter, notify);\n                        }\n                    }\n                }\n\n                function rejecter(reason) {\n                    rejectOne(reason);\n                }\n\n                function fulfiller(val) {\n                    fulfillOne(val);\n                }\n            }\n        });\n    }\n\n    /**\n     * Initiates a competitive race, returning a promise that will resolve when\n     * any one of the supplied promisesOrValues has resolved or will reject when\n     * *all* promisesOrValues have rejected.\n     *\n     * @param {Array|Promise} promisesOrValues array of anything, may contain a mix\n     *      of {@link Promise}s and values\n     * @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then()\n     * @param {function?} [onRejected] DEPRECATED, use returnedPromise.then()\n     * @param {function?} [onProgress] DEPRECATED, use returnedPromise.then()\n     * @returns {Promise} promise that will resolve to the value that resolved first, or\n     * will reject with an array of all rejected inputs.\n     */\n    function any(promisesOrValues, onFulfilled, onRejected, onProgress) {\n\n        function unwrapSingleResult(val) {\n            return onFulfilled ? onFulfilled(val[0]) : val[0];\n        }\n\n        return some(promisesOrValues, 1, unwrapSingleResult, onRejected, onProgress);\n    }\n\n    /**\n     * Return a promise that will resolve only once all the supplied promisesOrValues\n     * have resolved. The resolution value of the returned promise will be an array\n     * containing the resolution values of each of the promisesOrValues.\n     * @memberOf when\n     *\n     * @param {Array|Promise} promisesOrValues array of anything, may contain a mix\n     *      of {@link Promise}s and values\n     * @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then()\n     * @param {function?} [onRejected] DEPRECATED, use returnedPromise.then()\n     * @param {function?} [onProgress] DEPRECATED, use returnedPromise.then()\n     * @returns {Promise}\n     */\n    function all(promisesOrValues, onFulfilled, onRejected, onProgress) {\n        return _map(promisesOrValues, identity).then(onFulfilled, onRejected, onProgress);\n    }\n\n    /**\n     * Joins multiple promises into a single returned promise.\n     * @return {Promise} a promise that will fulfill when *all* the input promises\n     * have fulfilled, or will reject when *any one* of the input promises rejects.\n     */\n    function join(/* ...promises */) {\n        return _map(arguments, identity);\n    }\n\n    /**\n     * Settles all input promises such that they are guaranteed not to\n     * be pending once the returned promise fulfills. The returned promise\n     * will always fulfill, except in the case where `array` is a promise\n     * that rejects.\n     * @param {Array|Promise} array or promise for array of promises to settle\n     * @returns {Promise} promise that always fulfills with an array of\n     *  outcome snapshots for each input promise.\n     */\n    function settle(array) {\n        return _map(array, toFulfilledState, toRejectedState);\n    }\n\n    /**\n     * Promise-aware array map function, similar to `Array.prototype.map()`,\n     * but input array may contain promises or values.\n     * @param {Array|Promise} array array of anything, may contain promises and values\n     * @param {function} mapFunc map function which may return a promise or value\n     * @returns {Promise} promise that will fulfill with an array of mapped values\n     *  or reject if any input promise rejects.\n     */\n    function map(array, mapFunc) {\n        return _map(array, mapFunc);\n    }\n\n    /**\n     * Internal map that allows a fallback to handle rejections\n     * @param {Array|Promise} array array of anything, may contain promises and values\n     * @param {function} mapFunc map function which may return a promise or value\n     * @param {function?} fallback function to handle rejected promises\n     * @returns {Promise} promise that will fulfill with an array of mapped values\n     *  or reject if any input promise rejects.\n     */\n    function _map(array, mapFunc, fallback) {\n        return when(array, function(array) {\n\n            return promise(resolveMap);\n\n            function resolveMap(resolve, reject, notify) {\n                var results, len, toResolve, i;\n\n                // Since we know the resulting length, we can preallocate the results\n                // array to avoid array expansions.\n                toResolve = len = array.length >>> 0;\n                results = [];\n\n                if(!toResolve) {\n                    resolve(results);\n                    return;\n                }\n\n                // Since mapFunc may be async, get all invocations of it into flight\n                for(i = 0; i < len; i++) {\n                    if(i in array) {\n                        resolveOne(array[i], i);\n                    } else {\n                        --toResolve;\n                    }\n                }\n\n                function resolveOne(item, i) {\n                    when(item, mapFunc, fallback).then(function(mapped) {\n                        results[i] = mapped;\n\n                        if(!--toResolve) {\n                            resolve(results);\n                        }\n                    }, reject, notify);\n                }\n            }\n        });\n    }\n\n    /**\n     * Traditional reduce function, similar to `Array.prototype.reduce()`, but\n     * input may contain promises and/or values, and reduceFunc\n     * may return either a value or a promise, *and* initialValue may\n     * be a promise for the starting value.\n     *\n     * @param {Array|Promise} promise array or promise for an array of anything,\n     *      may contain a mix of promises and values.\n     * @param {function} reduceFunc reduce function reduce(currentValue, nextValue, index, total),\n     *      where total is the total number of items being reduced, and will be the same\n     *      in each call to reduceFunc.\n     * @returns {Promise} that will resolve to the final reduced value\n     */\n    function reduce(promise, reduceFunc /*, initialValue */) {\n        var args = fcall(slice, arguments, 1);\n\n        return when(promise, function(array) {\n            var total;\n\n            total = array.length;\n\n            // Wrap the supplied reduceFunc with one that handles promises and then\n            // delegates to the supplied.\n            args[0] = function (current, val, i) {\n                return when(current, function (c) {\n                    return when(val, function (value) {\n                        return reduceFunc(c, value, i, total);\n                    });\n                });\n            };\n\n            return reduceArray.apply(array, args);\n        });\n    }\n\n    // Snapshot states\n\n    /**\n     * Creates a fulfilled state snapshot\n     * @private\n     * @param {*} x any value\n     * @returns {{state:'fulfilled',value:*}}\n     */\n    function toFulfilledState(x) {\n        return { state: 'fulfilled', value: x };\n    }\n\n    /**\n     * Creates a rejected state snapshot\n     * @private\n     * @param {*} x any reason\n     * @returns {{state:'rejected',reason:*}}\n     */\n    function toRejectedState(x) {\n        return { state: 'rejected', reason: x };\n    }\n\n    /**\n     * Creates a pending state snapshot\n     * @private\n     * @returns {{state:'pending'}}\n     */\n    function toPendingState() {\n        return { state: 'pending' };\n    }\n\n    //\n    // Utilities, etc.\n    //\n\n    var reduceArray, slice, fcall, nextTick, handlerQueue,\n        setTimeout, funcProto, call, arrayProto, monitorApi, undef;\n\n    //\n    // Shared handler queue processing\n    //\n    // Credit to Twisol (https://github.com/Twisol) for suggesting\n    // this type of extensible queue + trampoline approach for\n    // next-tick conflation.\n\n    handlerQueue = [];\n\n    /**\n     * Enqueue a task. If the queue is not currently scheduled to be\n     * drained, schedule it.\n     * @param {function} task\n     */\n    function enqueue(task) {\n        if(handlerQueue.push(task) === 1) {\n            nextTick(drainQueue);\n        }\n    }\n\n    /**\n     * Drain the handler queue entirely, being careful to allow the\n     * queue to be extended while it is being processed, and to continue\n     * processing until it is truly empty.\n     */\n    function drainQueue() {\n        var task, i = 0;\n\n        while(task = handlerQueue[i++]) {\n            task();\n        }\n\n        handlerQueue = [];\n    }\n\n    //\n    // Capture function and array utils\n    //\n    /*global setImmediate,process,vertx*/\n\n    // Allow attaching the monitor to when() if env has no console\n    monitorApi = typeof console != 'undefined' ? console : when;\n\n    // capture setTimeout to avoid being caught by fake timers used in time based tests\n    setTimeout = global.setTimeout;\n    // Prefer setImmediate, cascade to node, vertx and finally setTimeout\n    nextTick = typeof setImmediate === 'function' ? setImmediate.bind(global)\n        : typeof process === 'object' && process.nextTick ? process.nextTick\n        : typeof vertx === 'object' ? vertx.runOnLoop // vert.x\n            : function(task) { setTimeout(task, 0); }; // fallback\n\n    // Safe function calls\n    funcProto = Function.prototype;\n    call = funcProto.call;\n    fcall = funcProto.bind\n        ? call.bind(call)\n        : function(f, context) {\n            return f.apply(context, slice.call(arguments, 2));\n        };\n\n    // Safe array ops\n    arrayProto = [];\n    slice = arrayProto.slice;\n\n    // ES5 reduce implementation if native not available\n    // See: http://es5.github.com/#x15.4.4.21 as there are many\n    // specifics and edge cases.  ES5 dictates that reduce.length === 1\n    // This implementation deviates from ES5 spec in the following ways:\n    // 1. It does not check if reduceFunc is a Callable\n    reduceArray = arrayProto.reduce ||\n        function(reduceFunc /*, initialValue */) {\n            /*jshint maxcomplexity: 7*/\n            var arr, args, reduced, len, i;\n\n            i = 0;\n            arr = Object(this);\n            len = arr.length >>> 0;\n            args = arguments;\n\n            // If no initialValue, use first item of array (we know length !== 0 here)\n            // and adjust i to start at second item\n            if(args.length <= 1) {\n                // Skip to the first real element in the array\n                for(;;) {\n                    if(i in arr) {\n                        reduced = arr[i++];\n                        break;\n                    }\n\n                    // If we reached the end of the array without finding any real\n                    // elements, it's a TypeError\n                    if(++i >= len) {\n                        throw new TypeError();\n                    }\n                }\n            } else {\n                // If initialValue provided, use it\n                reduced = args[1];\n            }\n\n            // Do the actual reduce\n            for(;i < len; ++i) {\n                if(i in arr) {\n                    reduced = reduceFunc(reduced, arr[i], i, arr);\n                }\n            }\n\n            return reduced;\n        };\n\n    function identity(x) {\n        return x;\n    }\n\n    return when;\n});\n})(\n    typeof define === 'function' && define.amd ? define : function (factory) { window.when = factory(); },\n    this\n);"
  },
  {
    "path": "src/js/lib.js",
    "content": "(function() {\n    var srcPath = '../js/';\n    document.write('<script src=\"' + srcPath + 'lib/jquery.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'lib/bootstrap.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'lib/fiddler.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'lib/when.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'lib/base64.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'lib/MimeTea.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'lib/beautify/beautify_css.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'lib/beautify/beautify_js.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'lib/beautify/beautify_html.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'lib/SyntaxHighlighter/shCore.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'lib/SyntaxHighlighter/shBrushCss.js\"><\\/script>');\n    document.write('<script src=\"' + srcPath + 'lib/SyntaxHighlighter/shBrushJScript.js\"><\\/script>');\n\n}());"
  },
  {
    "path": "src/js/page/background.js",
    "content": "chrome.browserAction.onClicked.addListener(function(){\n    var url = chrome.extension.getURL(\"html/options.html\");\n    window.open(url, \"fiddler_option_page\");\n});"
  },
  {
    "path": "src/js/page/devtools.js",
    "content": "var _initAdd = false;\nfunction addListener(){\n    if (_initAdd) {\n      return true;\n    };\n    _initAdd = true;\n    chrome.devtools.network.onRequestFinished.addListener(function(request) {\n        var url = request.request.url;\n        if (!Fiddler.checkUrl(url)) {\n              return true;\n        };\n        request.getContent(function(content){\n              var data = {\n                  method: \"requestContent\",\n                  url: url,\n                  content: content\n              }\n              chrome.runtime.sendMessage(data, function(response) {\n                  \n              });\n        }); \n  });\n};\n\n//devtools page open after options page\nchrome.runtime.sendMessage({\n  method: \"token\",\n  value: \"devtools\"\n}, function(response) {\n    if (response.result == 'ok') {\n        addListener();\n    };\n});\n"
  },
  {
    "path": "src/js/page/options.js",
    "content": "$(function(){\n    \"use strict\";\n    /**\n     * get item html\n     * @param  {[type]} data [description]\n     * @return {[type]}      [description]\n     */\n    function getItemHtml(data){\n        var currentType = $('#filterMenu li.disabled a').data('type');\n        data.display = (currentType == data.type || currentType == '') ? \"\" : 'display:none';\n        data.err = data.statusCode >= 400 ? \"err\" : \"\";\n        data.img = getTypeFile(data.type);\n        data.lowerMethod = data.method.toLowerCase();\n        data.shortPath = Fiddler.truncate(data.path, 50);\n        data.humanSize = Fiddler.getHumanSize(data.size) || '-';\n        var html = Fiddler.tmpl($('#requestItemTpl').html(), data).trim();\n        return html;\n    }\n    function getItemRuleHtml(data){\n        var pattern = data.patternType + \": \" + data.pattern;\n        var replace = data.replaceType + \": \" + data.replace;\n        var html = $('#ruleItemTpl').html().trim();\n        html = Fiddler.tmpl(html, {\n            pattern: pattern,\n            replace: replace,\n            checked: data.enable ? \"checked\" : \"\"\n        });\n        return html;\n    }\n    function getTypeFile(type){\n        var list = {\n            \"image\": \"img.png\",\n            \"script\": \"js.png\",\n            \"stylesheet\": \"css.png\",\n            \"main_frame\": \"html.png\",\n            \"sub_frame\": \"html.png\",\n            \"xmlhttprequest\": \"xhr.png\"\n        }\n        var file = list[type] || \"blank.png\";\n        return \"../img/icon/\" + file;\n    }\n    /**\n     * a request complete event\n     * @return {[type]} [description]\n     */\n    function bindCompleteEvent(){\n        var table = $('#requestList table tbody');\n        Fiddler_Resource.on(\"onCompleted\", function(detail){\n            var data = detail.data;\n            var html = getItemHtml(data);\n            if (html) {\n                $(html).appendTo(table);\n                $('#requestList')[0].scrollTop = 1000000;\n            };\n        })\n    }\n    function bindRequestEvent(){\n        var currentEl = null;\n        var detaultTab = 'headers';\n        var cbs = {\n            \"headers\" : function(requestId){\n                var detail = Fiddler_Resource.getItem(requestId);\n                //query url\n                var queryInfo = Fiddler_Resource.getQueryData(detail.url)\n                detail.queryUrl = queryInfo.data;\n                detail.queryUrlLength = queryInfo.length;\n                //form data\n                var requestBody = detail.requestBody;\n                if (requestBody) {\n                    if (requestBody.formData) {\n                        var length = 0;\n                        for(var name in requestBody.formData){\n                            length++;\n                            if (requestBody.formData[name].length == 1) {\n                                requestBody.formData[name] = requestBody.formData[name][0];\n                            }else{\n                                requestBody.formData[name] = \"[\" + requestBody.formData[name].join(\",\") + \"]\";\n                            }\n                        }\n                        detail.formData = requestBody.formData;\n                        detail.formDataLength = length;\n                    }else if(requestBody.raw){\n                        try{\n                            var buf = requestBody.raw[0].bytes;\n                            var bufView = new Uint8Array(buf);\n                            var result =  String.fromCharCode.apply(null, bufView);\n                            var formData = Fiddler_Resource.getQueryData(\"?\" + result);\n                            detail.formData = formData.data;\n                            detail.formDataLength = formData.length;\n                        }catch(e){}\n                    }\n                };\n                detail.requestHeaders = detail.requestHeaders || [];\n                var html = Fiddler.tmpl($('#headersTpl').html(), detail);\n                $('#tab-headers').html(html)\n            },\n            \"preview\": function(requestId){\n                var detail = Fiddler_Resource.getItem(requestId);\n                var type = detail.type;\n                if (type == 'image') {\n                    Fiddler_Resource.getSize(requestId).then(function(size){\n                        var imgUrl = Fiddler_Resource.getImgUrl(requestId);\n                        Fiddler_Resource.getImgRect(imgUrl, detail.url).then(function(rect){\n                            var filename = detail.url.match(/([^\\/\\?\\#]+)(?:[\\?\\#].*)?$/)[1];\n                            var html = Fiddler.tmpl($('#imagePreviewTpl').html(), {\n                                imgUrl: rect.old ? detail.url : imgUrl,\n                                url: detail.url,\n                                filename: filename,\n                                width: rect.width,\n                                height: rect.height,\n                                filesize: Fiddler.getHumanSize(size),\n                                display_url: Fiddler.truncateCenter(detail.url, 30)\n                            });\n                            $('#tab-preview').html(html)\n                        })\n                    })\n                }else if(type == 'script'){\n                    Fiddler_Resource.getContent(requestId).then(function(content){\n                        content = content || \"\";\n                        var html = '<div class=\"content\"> <pre class=\"brush: js;gutter: false\">'+Fiddler.encode4Html(content)+'</pre> </div>';\n                        $('#tab-preview').html(html);\n                        SyntaxHighlighter.highlight();\n                    })\n                }else if(type == 'stylesheet'){\n                    Fiddler_Resource.getContent(requestId).then(function(content){\n                        content = content || \"\";\n                        var html = '<div class=\"content\"> <pre class=\"brush: css;gutter: false\">'+Fiddler.encode4Html(content)+'</pre> </div>';\n                        $('#tab-preview').html(html);\n                        SyntaxHighlighter.highlight();\n                    })\n                }\n            },\n            \"response\": function(requestId){\n                var detail = Fiddler_Resource.getItem(requestId);\n                var method = detail.method;\n                if (method == 'POST') {\n                    $('#tab-response').html(\"can't show POST request response\");\n                    return true;\n                }; \n                Fiddler_Resource.getContent(requestId).then(function(content){\n                    content = content || \"\";\n                    content = Fiddler.encode4Html(content);\n                    $('#tab-response').html(content)\n                })\n            },\n            \"beautify\": function(requestId){\n                var detail = Fiddler_Resource.getItem(requestId);\n                var type = detail.type;\n                if (type == 'script') {\n                    Fiddler_Resource.getContent(requestId).then(function(content){\n                        content = content || \"\";\n                        content = Fiddler.encode4Html(js_beautify(content));\n                        var html = '<div class=\"content\" style=\"padding-left:0\"> <pre class=\"brush: js\">'+ (content) +'</pre> </div>';\n                        $('#tab-beautify').html(html);\n                        SyntaxHighlighter.highlight();\n                    })\n                }else if(type == 'stylesheet'){\n                    Fiddler_Resource.getContent(requestId).then(function(content){\n                        content = content || \"\";\n                        content = Fiddler.encode4Html(css_beautify(content));\n                        var html = '<div class=\"content\" style=\"padding-left:0\"> <pre class=\"brush: css\">'+ (content) +'</pre> </div>';\n                        $('#tab-beautify').html(html);\n                        SyntaxHighlighter.highlight();\n                    })\n                }\n            }\n        }\n        var showTypeList = {\n            \"image\": [\"headers\", \"preview\"],\n            \"script\": [\"headers\", \"preview\", \"response\", \"beautify\"],\n            \"stylesheet\": [\"headers\", \"preview\", \"response\", \"beautify\"],\n            \"main_frame\": [\"headers\", \"response\"],\n            \"sub_frame\": [\"headers\", \"response\"],\n            \"xmlhttprequest\": [\"headers\", \"response\"]\n        };\n        Fiddler.bindEvent($('#requestList'), {\n            'tbody tr td.url': function(){\n                var tr = $(this).parents('tr');\n                $('#autoResponseList').removeClass('open');  \n                currentEl && currentEl.removeClass('info');\n                tr.addClass('info');\n                currentEl = tr;\n                var detailEl = $('#requestDetail');\n                if (!detailEl.hasClass('open')) {\n                    detailEl.addClass('open');\n                };\n                detailEl.find('.nav-tabs li').removeClass('active').hide();\n                detailEl.find('.nav-tabs li[data-type=\"'+detaultTab+'\"]').addClass('active').show();\n                $('#tab-headers,#tab-preview,#tab-response,#tab-beautify').removeClass('active').html('');\n                var requestId = currentEl.attr('data-id');\n                var detail = Fiddler_Resource.getItem(requestId);\n                var showTypes = showTypeList[detail.type] || [];\n                showTypes.forEach(function(item){\n                    detailEl.find('.nav-tabs li[data-type=\"'+item+'\"]').show();\n                })\n                var el = $('#tab-' + detaultTab).addClass('active').show();\n                if (!el.html()) {\n                    cbs[detaultTab] && cbs[detaultTab](requestId);\n                };\n            },\n            'tbody tr a': function(e){\n                e.stopPropagation();\n            },\n            'tbody tr td img.type': function(){\n                $('#autoResponseList').addClass('open');\n                $('#autoResponseList button.btn-add').trigger('click');\n                var requestId = $(this).parents('tr').attr('data-id');\n                var detail = Fiddler_Resource.getItem(requestId);\n                var url = detail.url;\n                $('#rulePattern').val(url);\n            }\n        });\n        Fiddler.bindEvent($('#requestDetail'), {\n            'i.icon-remove': function(){\n                currentEl && currentEl.removeClass('info');\n                $('#tab-headers,#tab-preview,#tab-response,#tab-beautify').html(\"\");\n                $('#requestDetail').removeClass('open');\n            },\n            '.nav-tabs li a': function(e){\n                e.preventDefault();\n                var li = $(this).parents('li');\n                if (li.hasClass('active')) {\n                    return true;\n                };\n                $('#requestDetail .nav-tabs li.active').removeClass('active');\n                li.addClass('active');\n                $('#requestDetail .tab-content .active').removeClass('active').hide();;\n                var type = li.attr('data-type');\n                var el = $('#tab-' + type).addClass('active').show();\n                if (!el.html()) {\n                    cbs[type] && cbs[type](currentEl.attr('data-id'));\n                };\n            },\n            '#tab-headers .content>b': function(){\n                var open = !$(this).hasClass('treeRight');\n                var next = $(this).next();\n                if (open) {\n                    $(this).addClass('treeRight');\n                    next.hide();\n                }else{\n                    $(this).removeClass('treeRight');\n                    next.show();\n                }\n            }\n        })\n    }\n    var hideTypes = {\n        \"string\": [],\n        \"regexp\": [\"path\"],\n        \"method\": [\"path\"],\n        \"header\": [\"file\", \"path\", \"redirect\"]\n    }\n    /**\n     * auto response event\n     * @return {[type]} [description]\n     */\n    function bindAutoResponseEvent(){\n        Fiddler.bindEvent($('#autoResponseList'), {\n            '.rule-edit-item a.btn-select': function(e){\n                e.preventDefault();\n                if ($(this).hasClass('disabled')) {\n                    return false;\n                };\n                var menu = $(this).parents('.rule-edit-item').find('.dropdown-menu');\n                var hide = menu.css('display') == 'none';\n                if (hide) {\n                    menu.slideDown();\n                }else{\n                    menu.slideUp();\n                }\n            },\n            '#patternMenu li a': function(e){\n                e.preventDefault();\n                var type = $(this).attr('data-type');\n                var hides = hideTypes[type] || [];\n                var replaceA = $('#replaceMenu li a')\n                replaceA.show();\n                hides.forEach(function(item){\n                    $('#replaceMenu li a[data-type=\"'+item+'\"]').hide();\n                });\n                replaceA.each(function(){\n                    var $this = $(this);\n                    if ($this.css('display') != 'none') {\n                        $('#ruleReplaceType').val($this.html());\n                    };\n                })\n            },\n            '.dropdown-menu li a': function(e){\n                e.preventDefault();\n                var value = $(this).html().trim();\n                var edit = $(this).parents('.rule-edit-item');\n                edit.find('input.rule-input').val(value);\n                edit.find(\".dropdown-menu\").slideUp();\n                var defaultValue = $(this).data('value');\n                edit.find(\"input.rule-value\").val(defaultValue);\n            },\n            'button.btn-add': function(){\n                if ($(this).hasClass('disabled')) {\n                    return false;\n                };\n                $('#autoResponseList .rule-list tbody tr').removeClass('info');\n                setRuleEditEnable(true);\n                $('#autoResponseList .rule-pattern').val('StringToMatch[6]').select();\n                $('#autoResponseList .rule-replace').val('');\n                $('#rulePatternType').val('String');\n                $('#ruleReplaceType').val('File');\n            },\n            '.btn-save': function(){\n                if ($(this).hasClass('disabled')) {\n                    return false;\n                };\n                var data = {\n                    patternType: $('#rulePatternType').val().trim(),\n                    pattern: $('#rulePattern').val().trim(),\n                    replaceType: $('#ruleReplaceType').val().trim(),\n                    replace: $('#ruleReplace').val().trim(),\n                    enable: true\n                }\n                if (!data.pattern) {\n                    return $('#rulePattern').focus();\n                };\n                if (!data.replace && data.replaceType != 'Cancel') {\n                    return $('#ruleReplace').focus();\n                };\n                var tr = $('#autoResponseList .rule-list tbody tr.info');\n                if (tr.length) {\n                    tr.find('p.pattern').html(data.patternType + \": \" + data.pattern);\n                    tr.find('p.replace').html(data.replaceType + \": \" + data.replace);\n                    tr.attr('data-info', JSON.stringify(data));\n                }else{\n                    var item = $(getItemRuleHtml(data));\n                    item.attr('data-info', JSON.stringify(data));\n                    item.appendTo($('#autoResponseList .rule-list tbody'));\n                }\n                $('#rulePattern').val('');\n                $('#ruleReplace').val('');\n                saveRules();\n            },\n            '.rule-check': function(){\n                saveRules();\n            },\n            '.icon-edit': function(e){\n                e.preventDefault();\n                if ($(this).hasClass('disabled')) {\n                    return false;\n                };\n                var tr = $(this).parents('tr');\n                $('#autoResponseList .rule-list tbody tr').removeClass('info');\n                tr.addClass('info');\n                var data = JSON.parse(tr.attr('data-info'));\n                $('#rulePatternType').val(data.patternType);\n                $('#rulePattern').val(data.pattern);\n                $('#ruleReplaceType').val(data.replaceType);\n                $('#ruleReplace').val(data.replace);\n            },\n            '.icon-remove': function(e){\n                if ($(this).hasClass('disabled')) {\n                    return false;\n                };\n                var tr = $(this).parents('tr');\n                tr.remove();\n                saveRules();\n            },\n            //select file or path\n            '#ruleReplace': function(){\n                if ($(this).hasClass('disabled')) {\n                    return false;\n                };\n                var type = $('#ruleReplaceType').val();\n                if (type != 'File' && type != 'Path') {\n                    return true;\n                };\n                var path = openFiles(type);\n                if (path && path != '/') {\n                    path = \"file://\" + path;\n                    $(this).val(path);\n                };\n            }\n        });\n        $(document.body).click(function(e){\n            var target = e.target;\n            $('#replaceMenu,#patternMenu').each(function(){\n                var item = $(this).parents('.rule-edit-item');\n                if ($.contains(item[0], target)) {\n                    return true;\n                }else{\n                    $(this).slideUp();\n                }\n            });\n        })\n        $('#autoResponseBtn').click(function(){\n            $('#autoResponseList').toggleClass('open');  \n        });\n        $('#enableAutoResponse').click(function(){\n            var checked = !!this.checked;\n            Fiddler_Config.setConfig(\"enable_auto_response\", checked);\n            setRuleEditEnable(checked);\n            setRuleListEnable(checked);\n            $('#autoResponseList button.btn-add')[checked ? \"removeClass\" : \"addClass\"](\"disabled\");\n            saveRules();\n        });\n    }\n    var userAgents = {\n        \"firefox-windows\": \"\",\n        \"firefox-mac\": \"\",\n        \"chrome-windows\": \"\",\n        \"chrome-mac\": \"\",\n        \"chrome-mobile\": \"\",\n        \"chrome-tablet\": \"\",\n        \"iphone-ios5\": \"\",\n        \"ipad-ios5\": \"\",\n        \"ie10\": \"\",\n        \"ie9\": \"\",\n        \"ie8\": \"\",\n        \"ie7\": \"\",\n        \"ie6\": \"\"\n    };\n    \n    function setRuleEditEnable(enable){\n        var ruleEdit = $('#autoResponseList .rule-edit');\n        var input = ruleEdit.find('.rule-input,.rule-value');\n        var btn = ruleEdit.find('.btn-select');\n        var btnSave = ruleEdit.find('.btn-save');\n        btn[!enable ? \"addClass\" : \"removeClass\"](\"disabled\");\n        btnSave[!enable ? \"addClass\" : \"removeClass\"](\"disabled\");\n        input.each(function(){\n            this.disabled = !enable;\n        })\n    }\n    function setRuleListEnable(enable){\n        var list = $('#autoResponseList .rule-list tbody tr');\n        list[enable ? \"removeClass\" : \"addClass\"](\"disabled\");\n        list.each(function(){\n            $(this).find('input.rule-check')[0].disabled = !enable;\n            $(this).find('i.icon').each(function(){\n                $(this)[enable ? \"removeClass\" : \"addClass\"](\"disabled\");\n            })\n        });\n    }\n    function saveRules(){\n        var rules = [];\n        $('#autoResponseList .rule-list tbody tr').each(function(){\n            var data = JSON.parse($(this).attr('data-info') || \"{}\");\n            var checked = $(this).find('.rule-check')[0].checked;\n            data.enable = checked;\n            rules.push(data);\n        });\n        var enable = $('#enableAutoResponse')[0].checked;\n        Fiddler_Rule.saveRules(rules, enable);\n        var checked = $('#disabledCacheInput')[0].checked;\n        if (checked) {\n            Fiddler_Rule.disableCacheRule();\n        };\n    }\n    function initData(){\n        Fiddler_Config.init();\n        var rules = Fiddler_Config.getRules();\n        var parent = $('#autoResponseList .rule-list tbody');\n        rules.forEach(function(item){\n            var html = $(getItemRuleHtml(item));\n            html.attr('data-info', JSON.stringify(item));\n            html.appendTo(parent);\n        });\n        var disableCache = Fiddler_Config.getConfig(\"disable_cache\");\n        if (disableCache) {\n            $('#disabledCacheInput')[0].checked = true;\n        };\n        var enable = Fiddler_Config.getConfig(\"enable_auto_response\");\n        if (!enable) {\n            $('#enableAutoResponse')[0].checked = false;\n            $('#enableAutoResponse').trigger('click');\n            $('#enableAutoResponse').trigger('click');\n        }else{\n            saveRules();\n        }\n    }\n    /**\n     * open file by npapi\n     * @param  {[type]} type [description]\n     * @return {[type]}      [description]\n     */\n    function openFiles(type){\n        try{\n            var FindFile =  document.getElementById(\"chromefiddler\");\n            var path = FindFile.OpenFileDialog(\"/\", type.toLowerCase());\n            return path;\n        }catch(e){\n            return '';\n        }\n    }\n    function clearRequest(){\n        $('#requestList tbody').html('');\n        $('#requestDetail').removeClass('open');\n        Fiddler_Resource.clearResource();\n    }\n    function initTools(){\n        Fiddler.bindEvent($('#toolsMenu'), {\n            'a.clear': function(e){\n                e.preventDefault();\n                clearRequest();\n            },\n            'input.disable-cache': function(e){\n                var checked = this.checked;\n                Fiddler_Config.setConfig(\"disable_cache\", checked);\n                saveRules();\n            }\n        })\n    }\n    function initFilter(){\n        Fiddler.bindEvent($('#filterMenu'), {\n            'li a': function(e){\n                e.preventDefault();\n                var type = $(this).data('type');\n                var html = $(this).html();\n                $('#filterMenuTitle span').html('Filter ( '+html+' )');\n                $('#filterMenu li').removeClass('disabled');\n                var li = $(this).parents('li');\n                li.addClass('disabled');\n                var list = $('#requestList tbody tr');\n                if (type == '') {\n                    list.show();\n                }else{\n                    list.each(function(){\n                        var $this = $(this);\n                        var trtype = $this.data('type');\n                        if (type == trtype) {\n                            $this.show();\n                        }else{\n                            $this.hide();\n                        }\n                    })\n                }\n            }\n        })\n    }\n    /**\n     * read file error\n     * @param  {[type]} data [description]\n     * @return {[type]}      [description]\n     */\n    function fileErrorCallback(data){\n        var file = data.data;\n        alert(\"Fiddler: read file `\"+ file + \"` data error, please check\");\n    }\n    function getContentFromDevTools(){\n        chrome.runtime.onMessage.addListener(function(request) {\n            var method = request.method;\n            if (method == 'requestContent') {\n                Fiddler_Resource.setContent(request.url, request.content);\n            };\n        });\n        chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {\n            if (request.method == 'token' && request.value == 'devtools') {\n                sendResponse({\n                    result: \"ok\"\n                })\n            };\n        });\n    }\n    function init(){\n        Fiddler_Rule.resouceListening();\n        Fiddler_Rule.fileErrorListening(fileErrorCallback);\n        Fiddler_Event.init(function(){\n            return $('#disabledCacheInput')[0].checked;\n        });\n        bindCompleteEvent();\n        bindRequestEvent();\n        bindAutoResponseEvent();\n        initData();\n        initFilter();\n        initTools();\n        getContentFromDevTools();\n        /*chrome.browsingData.remove({\n          \"since\": (new Date()).getTime() - 1000 * 60 * 60 * 24 * 7\n        }, {\n          \"cache\": true,\n        }, function(){\n            \n        });*/\n    }\n    \n    init();\n});\n"
  },
  {
    "path": "src/manifest.json",
    "content": "{\n  \"manifest_version\": 2,\n  \"name\": \"Fiddler\",\n  \"version\": \"1.0.6\",\n  \"description\": \"Fiddler for chrome extension\",\n  \"background\": {\n  \t\"page\": \"html/background.html\"\n  },\n  \"content_security_policy\": \"script-src 'self' 'unsafe-eval'; object-src 'self'\",\n  \"homepage_url\":\"http://welefen.github.io/Fiddler/\",\n  \"browser_action\": {\n    \"default_icon\": \"img/icon_16.png\",\n    \"default_title\": \"Fiddler\"\n  },\n  \"permissions\": [\n    \"tabs\",\n    \"<all_urls>\",\n    \"webRequestBlocking\", \n    \"webRequest\",\n    \"browsingData\"\n  ],\n  \"plugins\": [\n    { \"path\": \"bin/chrome_fiddler.plugin/\" },\n    { \"path\": \"bin/chrome_fiddler.dll\" }\n  ],\n  \"icons\": {\n    \"128\": \"img/icon_128.png\",\n    \"48\": \"img/icon_48.png\",\n    \"16\": \"img/icon_16.png\"\n  },\n  \"options_page\":\"html/options.html\",\n  \"devtools_page\": \"html/devtools.html\",\n  \"update_url\": \"http://fiddler.ueapp.com/update.xml\"\n}\n"
  },
  {
    "path": "test/css/base.css",
    "content": "*{\n    padding: 0;\n    margin: 0;\n}\n.div1, .div2, .div3{\n    width: 306px;\n    height: 97px;\n    background-color: red;\n}\n.div1{\n    background-image: url(../img/btn_login_qq_selected.png);\n}\n.div2{\n    background-image: url(../img/btn_login_weibo_selected.png);\n}\n.div3{\n    background-image: url(../img/btn_login_visitor_selected.png);\n}"
  },
  {
    "path": "test/index.html",
    "content": "<html>\n<head>\n    <title></title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"css/base.css\" />\n</head>\n<body>\n<div class=\"div1\"></div>\n<div class=\"div2\"></div>\n<div class=\"div3\"></div>\n</body>\n</html>"
  }
]