diff --git a/README.md b/README.md index 7939d80d545ca3c00f06ee82a4093e52d1aba47c..8a81fba2ef1426f18221848fa0a8761daeee22a8 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,10 @@ project and request to have your language added. Languages which reach 100% translated are are significantly reviewed will be made available on the osTicket download page. +The software can also be translated in place in our [JIPT site] +(http://jipt.i18n.osticket.com). Once you have a Crowdin account, login and +translate the software in your browser! + Localizing strings in new code requires usage of a [few rules](setup/doc/i18n.md). License diff --git a/WHATSNEW.md b/WHATSNEW.md index c580634d187b26330c7fcecc42b29e55386ca6fc..4523347765df7bf305e94ea25973092fae0b4518 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -1,3 +1,17 @@ +osTicket v1.9.5.1 +================= +### Improvements + * Fix file.php to serve files added to system before osTicket v1.9.1 + * Fix file.php to serve files if client panel or system is offline + * Fix popover download of inline images + * Avoid de-duplicating zero-length files + * Send new message alert to team members if not assigned to an agent + * Fix import of users to organization not setting the organization + * Fix redactor toolbar showing over the date picker (#1450, thanks @Chefkeks) + +### Performance and Security + * Fix XSS vulnerability in client language selection + osTicket v1.9.5 =============== ### Enhancements diff --git a/assets/default/css/theme.css b/assets/default/css/theme.css index b8ca14066d9c2c2188eeb23b997675659ea893b8..5b98eaee93d60bc9f6732c12cd2e3e39d24ca10d 100644 --- a/assets/default/css/theme.css +++ b/assets/default/css/theme.css @@ -300,9 +300,20 @@ body { height: 71px; padding: 0 20px; } -#header #logo { - width: 220px; - height: 71px; +#logo { + height: 100%; +} +#header #logo img { + max-height: 65px; + max-width: 380px; + width: auto; + height: auto; + vertical-align: middle; +} +.valign-helper { + height: 100%; + display: inline-block; + vertical-align: middle; } #header p { width: 400px; @@ -398,6 +409,7 @@ body { text-indent: -9999px; margin: 0 auto; background: url('../images/poweredby.png') top left no-repeat; + background-size: auto 20px; } .front-page-button { } diff --git a/assets/default/images/poweredby.png b/assets/default/images/poweredby.png index 18cfcdd4050cde428500032d52db74609ae9e10f..9b2915505a144a89e12338f081b30dcd032b4e40 100644 Binary files a/assets/default/images/poweredby.png and b/assets/default/images/poweredby.png differ diff --git a/bootstrap.php b/bootstrap.php index 2085a4fbc1909d4c00ab79424e405f4c6ebd78b0..ef78830715a162dd91118d3edb8e600159adc8fd 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -95,9 +95,9 @@ class Bootstrap { define('THREAD_ENTRY_EMAIL_TABLE', $prefix.'thread_entry_email'); define('TICKET_TABLE',$prefix.'ticket'); - define('TICKET_LOCK_TABLE',$prefix.'ticket_lock'); + define('LOCK_TABLE',$prefix.'lock'); define('TICKET_EVENT_TABLE',$prefix.'ticket_event'); - define('TICKET_COLLABORATOR_TABLE', $prefix.'ticket_collaborator'); + define('THREAD_COLLABORATOR_TABLE', $prefix.'thread_collaborator'); define('TICKET_STATUS_TABLE', $prefix.'ticket_status'); define('TICKET_PRIORITY_TABLE',$prefix.'ticket_priority'); diff --git a/client.inc.php b/client.inc.php index 2faee156f11c1c34aebffaf72d13bd15b3dd1655..0a572ed1cfb82278c620945c00d32fb60e712427 100644 --- a/client.inc.php +++ b/client.inc.php @@ -29,7 +29,7 @@ define('OSTCLIENTINC',TRUE); define('ASSETS_PATH',ROOT_PATH.'assets/default/'); //Check the status of the HelpDesk. -if (!in_array(strtolower(basename($_SERVER['SCRIPT_NAME'])), array('logo.php',)) +if (!in_array(strtolower(basename($_SERVER['SCRIPT_NAME'])), array('logo.php','file.php')) && !(is_object($ost) && $ost->isSystemOnline())) { include(ROOT_DIR.'offline.php'); exit; diff --git a/css/filedrop.css b/css/filedrop.css index 96dca339e9736b699b9249ef44c799c0584eacd7..67512b1cfd4157c28d8ada167c2019fe3d36ed9e 100644 --- a/css/filedrop.css +++ b/css/filedrop.css @@ -64,9 +64,9 @@ padding-left: 10px; float: right; } -.redactor_box + .filedrop .dropzone, -.redactor_box + div > .filedrop .dropzone, -.redactor_box + div > .filedrop .files { +.redactor-box + .filedrop .dropzone, +.redactor-box + div > .filedrop .dropzone, +.redactor-box + div > .filedrop .files { border-top-width: 1px; border-top-left-radius: 0; border-top-right-radius: 0; @@ -75,6 +75,7 @@ .tooltip-preview img { max-width: 300px; max-height: 300px; + z-index:11; } /* Bootstrap 3.2 progress-bar */ diff --git a/css/redactor.css b/css/redactor.css index d11d73b9b662f337472cc9fc0331d0ac67132d44..dd2b3d91e98942c25886dcac1a63a8ac91dee951 100644 --- a/css/redactor.css +++ b/css/redactor.css @@ -11,310 +11,145 @@ font-weight: normal; font-style: normal; } -/* =Selection ------------------------------------------------------------------------------*/ -.redactor_box ::selection { - background: #ffff9e; -} -.redactor_box ::-moz-selection { - background: #ffff9e; -} -.redactor_box img::selection { - background: transparent; -} -.redactor_box img::-moz-selection { - background: transparent; -} /* - BOX + Box */ -.redactor_box { +.redactor-box { position: relative; overflow: visible; background: #fff; } -.redactor_box iframe { +.redactor-box iframe, +.redactor-box textarea { display: block; + position: relative; margin: 0; padding: 0; + width: 100%; +} +.redactor-box iframe { border: 1px solid #eee; } -.redactor_box textarea { - position: relative; - display: block; +.redactor-box textarea { overflow: auto; - margin: 0; - padding: 0; - width: 100%; outline: none; border: none; - background-color: #222; + background-color: #111; box-shadow: none; color: #ccc; font-size: 13px; font-family: Menlo, Monaco, monospace, sans-serif; resize: none; } -.redactor_box textarea:focus { +.redactor-box textarea:focus { outline: none; } -.redactor_box, -.redactor_box textarea { +/* + Z-index setup +*/ +.redactor-editor, +.redactor-box { + background: #fff; +} +.redactor-editor, +.redactor-box, +.redactor-box textarea { z-index: auto !important; } -.redactor_box_fullscreen { +.redactor-box-fullscreen { z-index: 99 !important; } -#redactor_modal_overlay, -#redactor_modal, -.redactor_dropdown { - z-index: 100 !important; +.redactor-toolbar, +.redactor-dropdown { + z-index: 1 !important; +} +#redactor-modal-overlay, +#redactor-modal-box, +#redactor-modal { + z-index: 11 !important; } /* - AIR - + Resize */ -body .redactor_air { - position: absolute; - z-index: 502; +.redactor-resize { + background: #f4f4f4; + padding: 4px 0 3px 0; + cursor: move; + border: 1px solid #e3e3e3; + border-top: none; +} +.redactor-resize div { + width: 30px; + margin: auto; + border-top: 1px solid #bbb; + border-bottom: 1px solid #fff; } /* - FULLSCREEN + Fullscreen */ -body .redactor_box_fullscreen { +body .redactor-box-fullscreen { position: fixed; top: 0; left: 0; width: 100%; } /* - LINK TOOLTIP + Utils */ -.redactor-link-tooltip { - position: absolute; - z-index: 49999; - padding: 10px; - line-height: 1; - display: inline-block; - background-color: #000; - color: #555 !important; -} -.redactor-link-tooltip, -.redactor-link-tooltip a { - font-size: 12px; - font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; -} -.redactor-link-tooltip a { - color: #ccc; - margin: 0 5px; - text-decoration: none; -} -.redactor-link-tooltip a:hover { - color: #fff; +.body-hidden { + overflow: hidden; } /* - IMAGE BOX + Editor */ -#redactor-image-box img { - width: 100%; -} -.redactor_editor { +.redactor-editor { position: relative; overflow: auto; margin: 0 !important; - padding: 10px 10px; - padding-bottom: 5px; + padding: 10px; outline: none; - background: none; - background: #fff; - box-shadow: none !important; white-space: normal; border: 1px solid #eee; -} -.redactor_editor:focus { - outline: none; -} -.redactor_editor div, -.redactor_editor p, -.redactor_editor ul, -.redactor_editor ol, -.redactor_editor table, -.redactor_editor dl, -.redactor_editor blockquote, -.redactor_editor pre, -.redactor_editor h1, -.redactor_editor h2, -.redactor_editor h3, -.redactor_editor h4, -.redactor_editor h5, -.redactor_editor h6 { + border-top: none; font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; -} -.redactor_editor code, -.redactor_editor pre { - font-family: Menlo, Monaco, monospace, sans-serif; -} -.redactor_editor div, -.redactor_editor p, -.redactor_editor ul, -.redactor_editor ol, -.redactor_editor table, -.redactor_editor dl, -.redactor_editor blockquote, -.redactor_editor pre { font-size: 14px; line-height: 1.6em; } -.redactor_editor a { - color: #15c !important; - text-decoration: underline !important; -} -.redactor_editor .redactor_placeholder { - color: #999 !important; - display: block !important; +.redactor-editor:focus { + outline: none; } /* - TYPOGRAPHY + Placeholder */ -.redactor_editor object, -.redactor_editor embed, -.redactor_editor video, -.redactor_editor img { - max-width: 100%; - width: auto; -} -.redactor_editor video, -.redactor_editor img { - height: auto; -} -.redactor_editor p, -.redactor_editor ul, -.redactor_editor ol, -.redactor_editor table, -.redactor_editor dl, -.redactor_editor blockquote, -.redactor_editor pre { - margin: 0; - margin-bottom: 10px !important; - border: none; - background: none !important; - box-shadow: none !important; -} -.redactor_editor iframe, -.redactor_editor object, -.redactor_editor hr { - margin-bottom: 15px !important; -} -.redactor_editor blockquote { - color: #777; - padding: 10px 20px; - font-style: italic !important; - border-left: 5px solid #eeeeee; -} -[dir="rtl"] .redactor_editor blockquote { - border-left: none; - border-right: 5px solid #eeeeee; -} -.redactor_editor ul, -.redactor_editor ol { - padding-left: 2em !important; -} -.redactor_editor ul ul, -.redactor_editor ol ol, -.redactor_editor ul ol, -.redactor_editor ol ul { - margin: 2px !important; - padding: 0 !important; - padding-left: 2em !important; - border: none; -} -.redactor_editor dl dt { - font-weight: bold; -} -.redactor_editor dd { - margin-left: 1em; -} -.redactor_editor table { - border-collapse: collapse; - font-size: 1em !important; -} -.redactor_editor table td { - padding: 5px !important; - border: 1px solid #ddd; - vertical-align: top; -} -.redactor_editor table thead td { - border-bottom: 2px solid #000 !important; - font-weight: bold !important; -} -.redactor_editor code { - background-color: #d8d7d7 !important; +.redactor-placeholder { + position: relative; } -.redactor_editor pre { - overflow: auto; - padding: 1em !important; - border: 1px solid #ddd !important; - border-radius: 3px !important; - background: #f8f8f8 !important; - white-space: pre; - font-size: 90% !important; +.redactor-placeholder:after { + position: absolute; + top: 20px; + left: 20px; + content: attr(placeholder); + color: #999 !important; + font-weight: normal !important; } -.redactor_editor hr { - display: block; - height: 1px; - border: 0; - border-top: 1px solid #ccc; +.redactor-placeholder[dir=rtl]:after { + left: initial; + right: 20px; } -/* - HEADERS -*/ -.redactor_editor h1, -.redactor_editor h2, -.redactor_editor h3, -.redactor_editor h4, -.redactor_editor h5, -.redactor_editor h6 { - margin-top: 0 !important; - padding: 0 !important; - background: none; - color: #000; - font-weight: bold; + +/* Placeholder in linebreaks mode */ +.redactor-linebreaks.redactor-placeholder:after { + top: 10px; + left: 10px; } -.redactor_editor h1 { - font-size: 36px !important; - line-height: 1.111em !important; - margin-bottom: .15em !important; -} -.redactor_editor h2 { - font-size: 30px !important; - line-height: 1.111em !important; - margin-bottom: .25em !important; -} -.redactor_editor h3 { - font-size: 24px !important; - line-height: 1.333em !important; - margin-bottom: .2em !important; -} -.redactor_editor h4 { - font-size: 18px !important; - line-height: 1.5em !important; - margin-bottom: .2em !important; -} -.redactor_editor h5 { - font-size: 1em !important; - line-height: 1.6em !important; - margin-bottom: .25em !important; -} -.redactor_editor h6 { - font-size: .8em !important; - line-height: 1.6em !important; - text-transform: uppercase; - margin-bottom: .3em !important; +.redactor-linebreaks.redactor-placeholder[dir=rtl]:after { + left: initial; + right: 10px; } /* - TOOLBAR + Toolbar */ -.redactor_toolbar { +.redactor-toolbar { position: relative; top: 0; left: 0; @@ -322,31 +157,28 @@ body .redactor_box_fullscreen { padding: 0 !important; list-style: none !important; font-size: 14px !important; - font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; line-height: 1 !important; background: #fff; border: none; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); z-index: 1; } -.redactor_toolbar:after { +.redactor-toolbar:after { content: ""; display: table; /* clear: both; */ } -.redactor_toolbar.redactor-toolbar-overflow { +.redactor-toolbar.redactor-toolbar-overflow { overflow-y: auto; height: 29px; white-space: nowrap; } -.redactor_toolbar.redactor-toolbar-external { +.redactor-toolbar.redactor-toolbar-external { + z-index: 999; box-shadow: none; border: 1px solid rgba(0, 0, 0, 0.1); } -body .redactor_air .redactor_toolbar { - padding-right: 2px !important; -} -.redactor_toolbar li { +.redactor-toolbar li { vertical-align: top; display: inline-block; margin: 0 !important; @@ -357,7 +189,7 @@ body .redactor_air .redactor_toolbar { -moz-box-sizing: content-box; box-sizing: content-box; } -.redactor_toolbar li a { +.redactor-toolbar li a { display: block; color: #333; text-align: center; @@ -371,57 +203,45 @@ body .redactor_air .redactor_toolbar { -moz-box-sizing: content-box; box-sizing: content-box; } -.redactor_toolbar li a:hover { +.redactor-toolbar li a:hover { outline: none; background-color: #1f78d8; color: #fff; - text-decoration: none; } -.redactor_toolbar li a:hover i:before { +.redactor-toolbar li a:hover i:before { color: #fff; } -.redactor_toolbar li a:active, -.redactor_toolbar li a.redactor_act { +.redactor-toolbar li a:active, +.redactor-toolbar li a.redactor-act { outline: none; background-color: #ccc; color: #444; } -.redactor_toolbar li a.redactor-btn-image { +.redactor-toolbar li a.redactor-btn-image { width: 14px; height: 14px; background-position: center center; background-repeat: no-repeat; } -.redactor_button_disabled { +.redactor-toolbar li a.fa-redactor-btn { + display: inline-block; + padding: 9px 10px 8px 10px; + line-height: 1; +} +.redactor-toolbar li a.redactor-button-disabled { filter: alpha(opacity=30); -moz-opacity: 0.3; opacity: 0.3; } -.redactor_button_disabled:hover { +.redactor-toolbar li a.redactor-button-disabled:hover { + color: #333; outline: none; background-color: transparent !important; cursor: default; } -.redactor_toolbar li a.fa-redactor-btn { - display: inline-block; - padding: 9px 10px 8px 10px; - line-height: 1; -} -.redactor_toolbar.redactor-toolbar-typewriter { - box-shadow: none; - background: rgba(240, 240, 240, 0.9); -} -.redactor_toolbar.redactor-toolbar-typewriter li a:hover { - outline: none; - background-color: #1f78d8; - color: #fff; -} -.redactor_toolbar.redactor-toolbar-typewriter li a:active, -.redactor_toolbar.redactor-toolbar-typewriter li a.redactor_act { - outline: none; - background-color: #ccc; - color: #444; -} +/* + Icons +*/ .re-icon { font-family: 'RedactorFont'; speak: none; @@ -535,192 +355,192 @@ body .redactor_air .redactor_toolbar { content: "\e61f"; } /* - Toolbar classes + Toolbar tooltip */ -.redactor_format_blockquote { - padding-left: 10px; - color: #666 !important; - font-style: italic; -} -.redactor_format_pre { - font-family: monospace, sans-serif; -} -.redactor_format_h1, -.redactor_format_h2, -.redactor_format_h3, -.redactor_format_h4, -.redactor_format_h5 { - font-weight: bold; +.redactor-toolbar-tooltip { + position: absolute; + z-index: 100; + text-align: center; + top: 0; + left: 0; + background: #000; + color: #fff; + padding: 5px 8px; + line-height: 1; + font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; + font-size: 12px; + border-radius: 2px; } -.redactor_format_h1 { - font-size: 30px; - line-height: 36px; +/* + Dropdown +*/ +.redactor-dropdown { + position: absolute; + top: 28px; + left: 0; + padding: 0; + min-width: 220px; + max-height: 254px; + overflow: auto; + background-color: #fff; + box-shadow: 0 1px 7px rgba(0, 0, 0, 0.25); + font-size: 14px; + font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; + line-height: 1.6em; } -.redactor_format_h2 { - font-size: 24px; - line-height: 36px; +.redactor-dropdown a { + display: block; + padding: 10px 15px; + color: #000; + text-decoration: none; + border-bottom: 1px solid rgba(0, 0, 0, 0.07); } -.redactor_format_h3 { - font-size: 20px; - line-height: 30px; +.redactor-dropdown a:last-child { + border-bottom: none; } -.redactor_format_h4 { - font-size: 16px; - line-height: 26px; +.redactor-dropdown a:hover { + background-color: #1f78d8; + color: #fff !important; + text-decoration: none; } -.redactor_format_h5 { - font-size: 14px; - line-height: 23px; +/* + IMAGE BOX +*/ +#redactor-image-box { + position: relative; + max-width: 100%; + display: inline-block; + line-height: 0; + outline: 1px dashed rgba(0, 0, 0, 0.6); } -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h1, -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h2, -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h3, -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h4, -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h5 { - font-size: 1em; - line-height: 1.6em; - text-transform: uppercase; +#redactor-image-editter { + position: absolute; + z-index: 5; + top: 50%; + left: 50%; + margin-top: -11px; + margin-left: -18px; + line-height: 1; + background-color: #000; + color: #fff; + font-size: 11px; + padding: 7px 10px; + cursor: pointer; } -.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h2 { - font-size: .85em; +#redactor-image-resizer { + position: absolute; + z-index: 2; + line-height: 1; + cursor: nw-resize; + bottom: -4px; + right: -5px; + border: 1px solid #fff; + background-color: #000; + width: 8px; + height: 8px; } /* - Typewriter + LINK TOOLTIP */ -.redactor_editor.redactor-editor-typewriter { - background: #f5f5f5 !important; - padding: 25px 50px !important; -} -.redactor_editor.redactor-editor-typewriter div, -.redactor_editor.redactor-editor-typewriter p, -.redactor_editor.redactor-editor-typewriter ul, -.redactor_editor.redactor-editor-typewriter ol, -.redactor_editor.redactor-editor-typewriter table, -.redactor_editor.redactor-editor-typewriter dl, -.redactor_editor.redactor-editor-typewriter blockquote, -.redactor_editor.redactor-editor-typewriter pre, -.redactor_editor.redactor-editor-typewriter h1, -.redactor_editor.redactor-editor-typewriter h2, -.redactor_editor.redactor-editor-typewriter h3, -.redactor_editor.redactor-editor-typewriter h4, -.redactor_editor.redactor-editor-typewriter h5, -.redactor_editor.redactor-editor-typewriter h6 { - font-family: 'Courier New', 'Lucida Console', Consolas, Monaco, monospace, sans-serif; - font-size: 18px !important; - line-height: 1.5em !important; - margin-bottom: 1.5em !important; -} -.redactor_editor.redactor-editor-typewriter h2 { - font-size: 14px !important; +.redactor-link-tooltip { + position: absolute; + z-index: 49999; + padding: 10px; + line-height: 1; + display: inline-block; + background-color: #000; + color: #555 !important; } -.redactor_editor.redactor-editor-typewriter h1, -.redactor_editor.redactor-editor-typewriter h2, -.redactor_editor.redactor-editor-typewriter h3, -.redactor_editor.redactor-editor-typewriter h4, -.redactor_editor.redactor-editor-typewriter h5, -.redactor_editor.redactor-editor-typewriter h6 { - text-transform: uppercase; +.redactor-link-tooltip, +.redactor-link-tooltip a { + font-size: 12px; + font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; +} +.redactor-link-tooltip a { + color: #ccc; + margin: 0 5px; + text-decoration: none; } -.redactor_editor.redactor-editor-typewriter a { - color: #000 !important; - text-decoration: underline !important; +.redactor-link-tooltip a:hover { + color: #fff; } /* - WYM + DROPAREA */ -.redactor_editor.redactor_editor_wym { - padding: 10px 7px 0 7px !important; - background: #f6f6f6 !important; -} -.redactor_editor.redactor_editor_wym div, -.redactor_editor.redactor_editor_wym p, -.redactor_editor.redactor_editor_wym ul, -.redactor_editor.redactor_editor_wym ol, -.redactor_editor.redactor_editor_wym table, -.redactor_editor.redactor_editor_wym dl, -.redactor_editor.redactor_editor_wym pre, -.redactor_editor.redactor_editor_wym h1, -.redactor_editor.redactor_editor_wym h2, -.redactor_editor.redactor_editor_wym h3, -.redactor_editor.redactor_editor_wym h4, -.redactor_editor.redactor_editor_wym h5, -.redactor_editor.redactor_editor_wym h6, -.redactor_editor.redactor_editor_wym blockquote { - margin-top: 0; - margin-bottom: 5px !important; - padding: 10px !important; - border: 1px solid #e4e4e4 !important; - background-color: #fff !important; - z-index: 0; -} -.redactor_editor.redactor_editor_wym blockquote:before { - content: ''; -} -.redactor_editor.redactor_editor_wym img { +#redactor-droparea { position: relative; - z-index: 1; -} -.redactor_editor.redactor_editor_wym div { - border: 1px dotted #aaa !important; + overflow: hidden; + padding: 140px 20px; + border: 3px dashed rgba(0, 0, 0, 0.1); } -.redactor_editor.redactor_editor_wym pre { - border: 2px dashed #e4e4e4 !important; - background-color: #f8f8f8 !important; +#redactor-droparea.drag-hover { + background: rgba(200, 222, 250, 0.75); } -.redactor_editor.redactor_editor_wym ul, -.redactor_editor.redactor_editor_wym ol { - padding-left: 2em !important; +#redactor-droparea.drag-drop { + background: rgba(250, 248, 200, 0.5); } -.redactor_editor.redactor_editor_wym ul li ul, -.redactor_editor.redactor_editor_wym ol li ul, -.redactor_editor.redactor_editor_wym ul li ol, -.redactor_editor.redactor_editor_wym ol li ol { - border: none !important; +#redactor-droparea-placeholder { + text-align: center; + font-size: 12px; + color: rgba(0, 0, 0, 0.7); } /* - DROPDOWN + PROGRESS */ -.redactor_dropdown { - position: absolute; - top: 28px; +#redactor-progress { + position: fixed; + top: 0; left: 0; - padding: 10px; - width: 200px; - background-color: #fff; - box-shadow: 0 1px 5px #bbb; - font-size: 13px; - font-family: Helvetica, Arial, Verdana, Tahoma, sans-serif; - line-height: 21px; + width: 100%; + z-index: 1000000; + height: 10px; } -.redactor-toolbar-typewriter .redactor_dropdown { - font-family: 'Courier New', 'Lucida Console', Consolas, Monaco, monospace, sans-serif; - background-color: #f5f5f5; +#redactor-progress span { + display: block; + width: 100%; + height: 100%; + background-color: #3d58a8; + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; + background-size: 40px 40px; } -.redactor_separator_drop { - padding: 0 !important; - border-top: 1px solid #ddd; - font-size: 0; - line-height: 0; +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } } -.redactor_dropdown a { - display: block; - padding: 3px 5px; - color: #000; - text-decoration: none; +@-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } } -.redactor_dropdown a:hover { - background-color: #dde4ef; - color: #444 !important; - text-decoration: none; +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } } /* MODAL */ -#redactor_modal_overlay { +#redactor-modal-overlay { position: fixed; top: 0; left: 0; margin: auto; + overflow: auto; width: 100%; height: 100%; background-color: #000 !important; @@ -728,140 +548,163 @@ body .redactor_air .redactor_toolbar { -moz-opacity: 0.3; opacity: 0.3; } -#redactor_modal { +#redactor-modal-box { position: fixed; - top: 50%; - left: 50%; + top: 0; + left: 0; + bottom: 0; + right: 0; + overflow-x: hidden; + overflow-y: auto; +} +#redactor-modal { + position: relative; + margin: auto; + margin-bottom: 20px; padding: 0; background: #fff; color: #000; - font-size: 12px !important; + font-size: 14px !important; font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; - box-shadow: 0 1px 10px rgba(0, 0, 0, 0.5); + box-shadow: 0 1px 70px rgba(0, 0, 0, 0.5); } -#redactor_modal header { - padding: 20px 30px 5px 30px; - font-size: 16px; +#redactor-modal header { + padding: 30px 40px 5px 40px; + font-size: 18px; + font-weight: bold; } -#redactor_modal section { - padding: 20px 30px; +#redactor-modal section { + padding: 30px 40px 50px 40px; } -#redactor_modal label { - display: block !important; +#redactor-modal label { + display: block; float: none !important; - margin: 10px 0 3px 0 !important; - padding: 0 !important; - font-size: 12px !important; -} -#redactor_modal footer:after { - content: ""; - display: table; - clear: both; -} -#redactor_modal footer div { - float: left; + margin: 15px 0 3px 0 !important; + padding: 0; } -#redactor_modal input[type="radio"], -#redactor_modal input[type="checkbox"] { +#redactor-modal input[type="radio"], +#redactor-modal input[type="checkbox"] { position: relative; top: -1px; } -#redactor_modal input[type="text"], -#redactor_modal input[type="password"], -#redactor_modal input[type="email"], -#redactor_modal textarea { +#redactor-modal select { + width: 100%; +} +#redactor-modal input[type="text"], +#redactor-modal input[type="password"], +#redactor-modal input[type="email"], +#redactor-modal input[type="url"], +#redactor-modal textarea { position: relative; z-index: 2; margin: 0; - padding: 1px 2px; - height: 23px; + padding: 5px 4px; + height: 28px; border: 1px solid #ccc; border-radius: 1px; background-color: white; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset; color: #333; - font-size: 13px; + width: 100%; + font-size: 14px; font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif; - line-height: 1; -moz-transition: border 0.3s ease-in; transition: border 0.3s ease-in; } -#redactor_modal textarea { - display: block; - margin-top: 4px; - line-height: 1.4em; -} -#redactor_modal input:focus, -#redactor_modal textarea:focus { +#redactor-modal input[type="text"]:focus, +#redactor-modal input[type="password"]:focus, +#redactor-modal input[type="email"]:focus, +#redactor-modal input[type="url"]:focus, +#redactor-modal textarea:focus { outline: none; border-color: #5ca9e4; box-shadow: 0 0 0 2px rgba(70, 161, 231, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2) inset; } -#redactor_modal_close { - position: absolute; - top: 5px; - right: 3px; - width: 20px; - height: 20px; - color: #999; - font-size: 26px; - cursor: pointer; +#redactor-modal input[type="text"].redactor-input-error, +#redactor-modal input[type="password"].redactor-input-error, +#redactor-modal input[type="email"].redactor-input-error, +#redactor-modal input[type="url"].redactor-input-error, +#redactor-modal textarea.redactor-input-error { + border-color: #e82f2f; + box-shadow: 0 0 0 2px rgba(232, 47, 47, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2) inset; } -#redactor_modal_close:hover { - color: #000; +#redactor-modal textarea { + display: block; + margin-top: 4px; + line-height: 1.4em; } -.redactor_input { - width: 99%; - font-size: 14px; +/* + Tabs in Modal +*/ +#redactor-modal-tabber { + margin-bottom: 15px; + font-size: 12px; } -.redactor_modal_box { - overflow: auto; - margin-bottom: 10px; - height: 350px; +#redactor-modal-tabber a { + border: 1px solid #ddd; + line-height: 1; + padding: 8px 15px; + margin-right: -1px; + text-decoration: none; + color: #000; } -#redactor_image_box { - overflow: auto; - margin-bottom: 10px; - height: 270px; +#redactor-modal-tabber a:hover { + background-color: #1f78d8; + border-color: #1f78d8; + color: #fff; } -#redactor_image_box_select { - display: block; - margin-bottom: 15px !important; - width: 200px; +#redactor-modal-tabber a.active { + cursor: default; + background-color: #ddd; + border-color: #ddd; + color: rgba(0, 0, 0, 0.6); } -#redactor_image_box img { - margin-right: 10px; - margin-bottom: 10px; - max-width: 100px; - cursor: pointer; +/* + List in Modal +*/ +#redactor-modal #redactor-modal-list { + margin-left: 0; + padding-left: 0; + list-style: none; + max-height: 250px; + overflow-x: scroll; } -#redactor_tabs { - margin-bottom: 18px; +#redactor-modal #redactor-modal-list li { + border-bottom: 1px solid #ddd; } -#redactor_tabs a { - display: inline-block; - margin-right: 2px; - padding: 4px 14px; - border: 1px solid #d2d2d2; - border-radius: 3px; - background: #fff; +#redactor-modal #redactor-modal-list li:last-child { + border-bottom: none; +} +#redactor-modal #redactor-modal-list a { + padding: 10px 5px; color: #000; text-decoration: none; - line-height: 1; + font-size: 13px; + display: block; + position: relative; } -#redactor_tabs a:hover, -#redactor_tabs a.redactor_tabs_act { - border-color: #eee; - color: #999 !important; - text-decoration: none !important; +#redactor-modal #redactor-modal-list a:hover { + background-color: #eee; } -.redactor_modal_btn_hidden { - display: none; +#redactor-modal-close { + position: absolute; + top: 10px; + right: 10px; + width: 30px; + height: 30px; + text-align: right; + color: #bbb; + font-size: 30px; + font-weight: 300; + cursor: pointer; } -#redactor_modal footer button { +#redactor-modal-close:hover { + color: #000; +} +#redactor-modal footer button { position: relative; width: 100%; - padding: 10px 16px; + padding: 14px 16px; margin: 0; outline: none; border: none; @@ -875,110 +718,230 @@ body .redactor_air .redactor_toolbar { line-height: 1; cursor: pointer; } -#redactor_modal footer button:hover { +#redactor-modal footer button:hover { color: #777; background: none; background: #bbb; text-decoration: none; } -#redactor_modal footer button.redactor_modal_delete_btn { +#redactor-modal footer button.redactor-modal-delete-btn { background: none; color: #fff; background-color: #b52525; } -#redactor_modal footer button.redactor_modal_delete_btn:hover { +#redactor-modal footer button.redactor-modal-delete-btn:hover { color: rgba(255, 255, 255, 0.6); background-color: #881b1b; } -#redactor_modal footer button.redactor_modal_action_btn { +#redactor-modal footer button.redactor-modal-action-btn { background: none; color: #fff; background-color: #2461b5; } -#redactor_modal footer button.redactor_modal_action_btn:hover { +#redactor-modal footer button.redactor-modal-action-btn:hover { color: rgba(255, 255, 255, 0.6); background-color: #1a4580; } -/* Drag and Drop Area */ -.redactor_droparea { - position: relative; - margin: auto; - margin-bottom: 5px; - width: 100%; +/* + ############################################## + + DROPDOWN FORMATTING + + ############################################## +*/ +.redactor-dropdown .redactor-formatting-blockquote { + color: rgba(0, 0, 0, 0.4); + font-style: italic; } -.redactor_droparea .redactor_dropareabox { - position: relative; - z-index: 1; - padding: 60px 0; - width: 99%; - border: 1px dashed #ddd; - background: #fff; - text-align: center; +.redactor-dropdown .redactor-formatting-pre { + font-family: monospace, sans-serif; } -.redactor_droparea .redactor_dropareabox, -.redactor_dropalternative { - color: #555; - font-size: 12px; +.redactor-dropdown .redactor-formatting-h1 { + font-size: 36px; + line-height: 36px; + font-weight: bold; } -.redactor_dropalternative { - margin: 4px 0 2px 0; +.redactor-dropdown .redactor-formatting-h2 { + font-size: 24px; + line-height: 36px; + font-weight: bold; } -.redactor_dropareabox.hover { - border-color: #aaa; - background: #efe3b8; +.redactor-dropdown .redactor-formatting-h3 { + font-size: 21px; + line-height: 30px; + font-weight: bold; } -.redactor_dropareabox.error { - border-color: #dcc3c3; - background: #f7e5e5; +.redactor-dropdown .redactor-formatting-h4 { + font-size: 18px; + line-height: 26px; + font-weight: bold; } -.redactor_dropareabox.drop { - border-color: #e0e5d6; - background: #f4f4ee; +.redactor-dropdown .redactor-formatting-h5 { + font-size: 16px; + line-height: 23px; + font-weight: bold; } -/* =ProgressBar ------------------------------------------------------------------------------*/ -#redactor-progress { - position: fixed; - top: 0; - left: 0; +/* + ############################################## + + CONTENT STYLES + + ############################################## +*/ +.redactor-editor code, +.redactor-editor pre { + font-family: Menlo, Monaco, monospace, sans-serif; +} +.redactor-editor div, +.redactor-editor p, +.redactor-editor ul, +.redactor-editor ol, +.redactor-editor table, +.redactor-editor dl, +.redactor-editor blockquote, +.redactor-editor pre { + font-size: 14px; + line-height: 1.6em; +} +.redactor-editor a { + color: #15c; + text-decoration: underline; +} +.redactor-editor object, +.redactor-editor embed, +.redactor-editor video, +.redactor-editor img { + max-width: 100%; + width: auto; +} +.redactor-editor video, +.redactor-editor img { + height: auto; +} +.redactor-editor div, +.redactor-editor p, +.redactor-editor ul, +.redactor-editor ol, +.redactor-editor table, +.redactor-editor dl, +.redactor-editor figure, +.redactor-editor blockquote, +.redactor-editor pre { + margin: 0; + margin-bottom: 15px; + border: none; + background: none; + box-shadow: none; +} +.redactor-editor iframe, +.redactor-editor object, +.redactor-editor hr { + margin-bottom: 15px; +} +.redactor-editor iframe { + width: auto; +} +.redactor-editor blockquote { + margin-left: 1.6em !important; + padding-left: 0; + color: #777; + font-style: italic; +} +.redactor-editor ul, +.redactor-editor ol { + padding-left: 2em; +} +.redactor-editor ul ul, +.redactor-editor ol ol, +.redactor-editor ul ol, +.redactor-editor ol ul { + margin: 2px; + padding: 0; + padding-left: 2em; + border: none; +} +.redactor-editor dl dt { + font-weight: bold; +} +.redactor-editor dd { + margin-left: 1em; +} +.redactor-editor table { + border-collapse: collapse; + font-size: 1em; width: 100%; - z-index: 1000000; - height: 10px; } -#redactor-progress span { +.redactor-editor table td, +.redactor-editor table th { + padding: 5px; + border: 1px solid #ddd; + vertical-align: top; +} +.redactor-editor table thead td, +.redactor-editor table th { + font-weight: bold; + border-bottom-color: #888; +} +.redactor-editor code { + background-color: #d8d7d7; +} +.redactor-editor pre { + overflow: auto; + padding: 1em; + border: 1px solid #ddd; + border-radius: 3px; + background: #f8f8f8; + white-space: pre; + font-size: 90%; +} +.redactor-editor hr { display: block; - width: 100%; - height: 100%; - background-color: #3d58a8; - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); - -webkit-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; - background-size: 40px 40px; + height: 1px; + border: 0; + border-top: 1px solid #ccc; } -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } +.redactor-editor h1, +.redactor-editor h2, +.redactor-editor h3, +.redactor-editor h4, +.redactor-editor h5, +.redactor-editor h6 { + font-weight: bold; + color: #000; + padding: 0; + background: none; + text-rendering: optimizeLegibility; + margin: 0 0 .5em 0; } -@-o-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } +.redactor-editor h1, +.redactor-editor h2, +.redactor-editor h3, +.redactor-editor h4 { + line-height: 1.3; } -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } +.redactor-editor h1 { + font-size: 36px; +} +.redactor-editor h2 { + font-size: 24px; + margin-bottom: .7em; +} +.redactor-editor h3 { + font-size: 21px; +} +.redactor-editor h4 { + font-size: 18px; +} +.redactor-editor h5 { + font-size: 16px; +} +.redactor-editor h6 { + font-size: 12px; + text-transform: uppercase; +} +.redactor-dropdown *, +#redactor-modal * { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } diff --git a/css/rtl.css b/css/rtl.css index c61f0b9fd1b494a4ffd1f6781ec307f102d915a5..64c4d086bb36824e3247659718138e4e78cebc01 100644 --- a/css/rtl.css +++ b/css/rtl.css @@ -86,7 +86,7 @@ border-left: none; border-right: 1px solid rgba(0,0,0,0.7); } -.rtl [class^="icon-"].pull-left, [class*=" icon-"].pull-left { +.rtl [class^="icon-"].pull-left, [class*=" icon-"].pull-right { margin-right: 0; margin-left: 0.3em; } diff --git a/include/ajax.draft.php b/include/ajax.draft.php index fa9d5c9b638f7ea81af2a8f78a94d1331591197c..5795b24e3f00e562059819db2c5369522416251b 100644 --- a/include/ajax.draft.php +++ b/include/ajax.draft.php @@ -61,6 +61,21 @@ class DraftAjaxAPI extends AjaxController { unset($_FILES['file']); $file = AttachmentFile::format($_FILES['image']); + # Allow for data-uri uploaded files + $fp = fopen($file[0]['tmp_name'], 'rb'); + if (fread($fp, 5) == 'data:') { + $data = 'data:'; + while ($block = fread($fp, 8192)) + $data .= $block; + $file[0] = Format::parseRfc2397($data); + list(,$ext) = explode('/', $file[0]['type'], 2); + $file[0] += array( + 'name' => Misc::randCode(8).'.'.$ext, + 'size' => strlen($file[0]['data']), + ); + } + fclose($fp); + # TODO: Detect unacceptable attachment extension # TODO: Verify content-type and check file-content to ensure image $type = $file[0]['type']; @@ -79,8 +94,14 @@ class DraftAjaxAPI extends AjaxController { )) ); + if (isset($file[0]['tmp_name'])) { + $ids = $draft->attachments->upload($file); + } + else { + $ids = $draft->attachments->save($file[0]); + } - if (!($ids = $draft->attachments->upload($file))) { + if (!$ids) { if ($file[0]['error']) { return Http::response(403, JsonDataEncoder::encode(array( @@ -92,7 +113,7 @@ class DraftAjaxAPI extends AjaxController { return Http::response(500, 'Unable to attach image'); } - $id = $ids[0]; + $id = (is_array($ids)) ? $ids[0] : $ids; } else { $type = explode('/', $_POST['contentType']); @@ -318,11 +339,23 @@ class DraftAjaxAPI extends AjaxController { if (!$thisstaff) Http::response(403, "Login required for file queries"); + if (isset($_GET['threadId']) && is_numeric($_GET['threadId']) + && ($thread = Thread::lookup($_GET['threadId'])) + && ($object = $thread->getObject()) + && ($thisstaff->canAccess($object)) + ) { + $union = ' UNION SELECT f.id, a.`type` FROM '.THREAD_TABLE.' t + JOIN '.THREAD_ENTRY_TABLE.' th ON (th.thread_id = t.id) + JOIN '.ATTACHMENT_TABLE.' a ON (a.object_id = th.id AND a.`type` = \'H\') + JOIN '.FILE_TABLE.' f ON (a.file_id = f.id) + WHERE t.id='.db_input($_GET['threadId']); + } + $sql = 'SELECT distinct f.id, COALESCE(a.type, f.ft) FROM '.FILE_TABLE .' f LEFT JOIN '.ATTACHMENT_TABLE.' a ON (a.file_id = f.id) - WHERE (a.`type` IN (\'C\', \'F\', \'T\', \'P\') OR f.ft = \'L\') - AND f.`type` LIKE \'image/%\''; - if (!($res = db_query($sql))) + WHERE (a.`type` IN (\'C\', \'F\', \'T\', \'P\') OR f.ft = \'L\')' + .' AND f.`type` LIKE \'image/%\''; + if (!($res = db_query($sql.$union))) Http::response(500, 'Unable to lookup files'); $files = array(); @@ -332,12 +365,15 @@ class DraftAjaxAPI extends AjaxController { 'T' => __('Email Templates'), 'L' => __('Logos'), 'P' => __('Pages'), + 'H' => __('This Thread'), ); while (list($id, $type) = db_fetch_row($res)) { $f = AttachmentFile::lookup($id); $url = $f->getDownloadUrl(); $files[] = array( - 'thumb'=>$url.'&s=128', + // Don't send special sizing for thread items 'cause they + // should be cached already by the client + 'thumb'=>$url.($type != 'H' ? '&s=128' : ''), 'image'=>$url, 'title'=>$f->getName(), 'folder'=>$folders[$type] diff --git a/include/ajax.orgs.php b/include/ajax.orgs.php index aa6937bc38f9c96312ee53be6da45737b795c4e6..7c849e6db88bd31267ebd2ab67a9aabb0e1d6e09 100644 --- a/include/ajax.orgs.php +++ b/include/ajax.orgs.php @@ -185,7 +185,8 @@ class OrgsAjaxAPI extends AjaxController { ); if ($_POST) { - $status = User::importFromPost($_POST['pasted']); + $status = User::importFromPost($_POST['pasted'], + array('org_id'=>$org_id)); if (is_string($status)) $info['error'] = $status; else diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index 8d7228dea69f4c74eb6eb464be1cf6bcdf5aa766..e13128529cc4fa4ba26d8b3cc0f1d03c4d7bb489 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -131,7 +131,10 @@ class TicketsAjaxAPI extends AjaxController { if(!$tid || !is_numeric($tid) || !$id || !is_numeric($id) || !$thisstaff) return $this->json_encode(array('id'=>0, 'retry'=>true)); - $lock= TicketLock::lookup($id, $tid); + if (!($ticket = Ticket::lookup($tid))) + return $this->json_encode(array('id'=>0, 'retry'=>true)); + + $lock = $ticket->getLock(); if(!$lock || !$lock->getStaffId() || $lock->isExpired()) //Said lock doesn't exist or is is expired return self::acquireLock($tid); //acquire the lock @@ -147,21 +150,31 @@ class TicketsAjaxAPI extends AjaxController { function releaseLock($tid, $id=0) { global $thisstaff; - if($id && is_numeric($id)){ //Lock Id provided! + if (!($ticket = Ticket::lookup($tid))) { + return 0; + } - $lock = TicketLock::lookup($id, $tid); - //Already gone? - if(!$lock || !$lock->getStaffId() || $lock->isExpired()) //Said lock doesn't exist or is is expired + if ($id) { + // Fetch the lock from the ticket + if (!($lock = $ticket->getLock())) { return 1; - - //make sure the user actually owns the lock before releasing it. - return ($lock->getStaffId()==$thisstaff->getId() && $lock->release())?1:0; - - }elseif($tid){ //release all the locks the user owns on the ticket. - return TicketLock::removeStaffLocks($thisstaff->getId(),$tid)?1:0; + } + // Identify the lock by the ID number + if ($lock->getId() != $id) { + return 0; + } + // You have to own the lock + if ($lock->getStaffId() != $thisstaff->getId()) { + return 0; + } + // Can't be expired + if ($lock->isExpired()) { + return 1; + } + return $lock->release() ? 1 : 0; } - return 0; + return Lock::removeStaffLocks($thisstaff->getId(), $ticket) ? 1 : 0; } function previewTicket ($tid) { @@ -785,9 +798,11 @@ class TicketsAjaxAPI extends AjaxController { } function triggerThreadAction($ticket_id, $thread_id, $action) { - $thread = ThreadEntry::lookup($thread_id, $ticket_id); + $thread = ThreadEntry::lookup($thread_id); if (!$thread) Http::response(404, 'No such ticket thread entry'); + if ($thread->getThread()->getObjectId() != $ticket_id) + Http::response(404, 'No such ticket thread entry'); $valid = false; foreach ($thread->getActions() as $group=>$list) { diff --git a/include/api.tickets.php b/include/api.tickets.php index d80b1582889f7bf3f944eea9808a3f675f6008f2..d70eda638a31f69bc9841d47d0714c127232a9ef 100644 --- a/include/api.tickets.php +++ b/include/api.tickets.php @@ -80,7 +80,8 @@ class TicketApiController extends ApiController { } // Validate and save immediately try { - $file['id'] = $fileField->uploadAttachment($file); + $F = $fileField->uploadAttachment($file); + $file['id'] = $F->getId(); } catch (FileUploadError $ex) { $file['error'] = $file['name'] . ': ' . $ex->getMessage(); @@ -150,14 +151,29 @@ class TicketApiController extends ApiController { if (!$data) $data = $this->getEmailRequest(); - if (($thread = ThreadEntry::lookupByEmailHeaders($data)) - && ($t=$thread->getTicket()) - && ($data['staffId'] - || !$t->isClosed() - || $t->isReopenable()) - && $thread->postEmail($data)) { - return $thread->getTicket(); + $seen = false; + if (($entry = ThreadEntry::lookupByEmailHeaders($data, $seen)) + && ($message = $entry->postEmail($data)) + ) { + if ($message instanceof ThreadEntry) { + return $message->getThread()->getObject(); + } + else if ($seen) { + // Email has been processed previously + return $entry->getThread()->getObject(); + } } + + // Allow continuation of thread without initial message or note + elseif (($thread = Thread::lookupByEmailHeaders($data)) + && ($message = $thread->postEmail($data)) + ) { + return $thread->getObject(); + } + + // All emails which do not appear to be part of an existing thread + // will always create new "Tickets". All other objects will need to + // be created via the web interface or the API return $this->createTicket($data); } diff --git a/include/class.api.php b/include/class.api.php index a1fed6764a7d7b9816243b22fa51c79ed2f4d6a7..c998cf244a6ddc314dfaa983a99cc03cfa7d81ce 100644 --- a/include/class.api.php +++ b/include/class.api.php @@ -345,7 +345,7 @@ class ApiXmlDataParser extends XmlDataParser { unset($value[":text"]); } if (isset($value['encoding'])) - $value['body'] = Format::utf8encode($value['body'], $value['encoding']); + $value['body'] = Charset::utf8($value['body'], $value['encoding']); if (!strcasecmp($value['type'], 'text/html')) $value = new HtmlThreadEntryBody($value['body']); diff --git a/include/class.attachment.php b/include/class.attachment.php index 9126cff8c0c7f9f68b6071dae3c50dc09e38c7ca..748266003819edd0fbde1f248b0afdf15657a8a8 100644 --- a/include/class.attachment.php +++ b/include/class.attachment.php @@ -16,36 +16,37 @@ require_once(INCLUDE_DIR.'class.ticket.php'); require_once(INCLUDE_DIR.'class.file.php'); -class Attachment { - var $id; - var $file_id; +class Attachment extends VerySimpleModel { + static $meta = array( + 'table' => ATTACHMENT_TABLE, + 'pk' => array('id'), + 'select_related' => array('file'), + 'joins' => array( + 'thread_entry' => array( + 'constraint' => array( + 'type' => "'H'", + 'object_id' => 'ThreadEntry.id', + ), + ), + 'file' => array( + 'constraint' => array( + 'file_id' => 'AttachmentFile.id', + ), + ), + ), + ); - var $ht; var $object; - function Attachment($id) { - - $sql = 'SELECT a.* FROM '.ATTACHMENT_TABLE.' a ' - . 'WHERE a.id='.db_input($id); - if (!($res=db_query($sql)) || !db_num_rows($res)) - return; - - $this->ht = db_fetch_array($res); - $this->file = $this->object = null; - } - function getId() { - return $this->ht['id']; + return $this->id; } function getFileId() { - return $this->ht['file_id']; + return $this->file_id; } function getFile() { - if(!$this->file && $this->getFileId()) - $this->file = AttachmentFile::lookup($this->getFileId()); - return $this->file; } @@ -66,44 +67,23 @@ class Attachment { return $this->object; } - static function getIdByFileHash($hash, $objectId=0) { - $sql='SELECT a.id FROM '.ATTACHMENT_TABLE.' a ' - .' INNER JOIN '.FILE_TABLE.' f ON(f.id=a.file_id) ' - .' WHERE f.`key`='.db_input($hash); + static function lookupByFileHash($hash, $objectId=0) { + $file = static::objects() + ->filter(array('file__key' => $hash)); + if ($objectId) - $sql.=' AND a.object_id='.db_input($objectId); + $file->filter(array('object_id' => $objectId)); - return db_result(db_query($sql)); + return $file->first(); } static function lookup($var, $objectId=0) { - - $id = is_numeric($var) ? $var : self::getIdByFileHash($var, - $objectId); - - return ($id - && is_numeric($id) - && ($attach = new Attachment($id, $objectId)) - && $attach->getId()==$id - ) ? $attach : null; + return (is_string($var)) + ? static::lookupByFileHash($var, $objectId) + : parent::lookup($var); } } -class AttachmentModel extends VerySimpleModel { - static $meta = array( - 'table' => ATTACHMENT_TABLE, - 'pk' => array('id'), - 'joins' => array( - 'thread' => array( - 'constraint' => array( - 'object_id' => 'ThreadEntryModel.id', - 'type' => "'H'", - ), - ), - ), - ); -} - class GenericAttachment extends VerySimpleModel { static $meta = array( 'table' => ATTACHMENT_TABLE, @@ -132,24 +112,26 @@ class GenericAttachments { $fileId = $file; elseif (is_array($file) && isset($file['id'])) $fileId = $file['id']; - elseif (!($fileId = AttachmentFile::upload($file))) + elseif ($F = AttachmentFile::upload($file)) + $fileId = $F->getId(); + else continue; $_inline = isset($file['inline']) ? $file['inline'] : $inline; - $sql ='INSERT INTO '.ATTACHMENT_TABLE - .' SET `type`='.db_input($this->getType()) - .',object_id='.db_input($this->getId()) - .',file_id='.db_input($fileId) - .',inline='.db_input($_inline ? 1 : 0); + $att = Attachment::create(array( + 'type' => $this->getType(), + 'object_id' => $this->getId(), + 'file_id' => $fileId, + 'inline' => $_inline ? 1 : 0, + )); if ($lang) - $sql .= ',lang='.db_input($lang); + $att->lang = $lang; // File may already be associated with the draft (in the // event it was deleted and re-added) - if (db_query($sql, function($errno) { return $errno != 1062; }) - || db_errno() == 1062) - $i[] = $fileId; + $att->save(); + $i[] = $fileId; } return $i; @@ -161,15 +143,18 @@ class GenericAttachments { $fileId = $file; elseif (is_array($file) && isset($file['id'])) $fileId = $file['id']; - elseif (!($fileId = AttachmentFile::save($file))) + elseif ($file = AttachmentFile::create($file)) + $fileId = $file->getId(); + else return false; - $sql ='INSERT INTO '.ATTACHMENT_TABLE - .' SET `type`='.db_input($this->getType()) - .',object_id='.db_input($this->getId()) - .',file_id='.db_input($fileId) - .',inline='.db_input($inline ? 1 : 0); - if (!db_query($sql) || !db_affected_rows()) + $att = Attachment::create(array( + 'type' => $this->getType(), + 'object_id' => $this->getId(), + 'file_id' => $fileId, + 'inline' => $inline ? 1 : 0, + )); + if (!$att->save()) return false; return $fileId; @@ -181,51 +166,29 @@ class GenericAttachments { function count($lang=false) { return count($this->getSeparates($lang)); } function _getList($separate=false, $inlines=false, $lang=false) { - if(!isset($this->attachments)) { - $this->attachments = array(); - $sql='SELECT f.id, f.size, f.`key`, f.signature, f.name ' - .', a.inline, a.lang, a.id as attach_id ' - .' FROM '.FILE_TABLE.' f ' - .' INNER JOIN '.ATTACHMENT_TABLE.' a ON(f.id=a.file_id) ' - .' WHERE a.`type`='.db_input($this->getType()) - .' AND a.object_id='.db_input($this->getId()); - if(($res=db_query($sql)) && db_num_rows($res)) { - while($rec=db_fetch_array($res)) { - $rec['download_url'] = AttachmentFile::generateDownloadUrl( - $rec['id'], $rec['key'], $rec['signature']); - $this->attachments[] = $rec; - } - } - } - $attachments = array(); - foreach ($this->attachments as $a) { - if (($a['inline'] != $separate || $a['inline'] == $inlines) - && $lang == $a['lang']) { - $a['file_id'] = $a['id']; - $a['hash'] = md5($a['file_id'].session_id().$a['key']); - $attachments[] = $a; - } - } - return $attachments; + return Attachment::objects()->filter(array( + 'type' => $this->getType(), + 'object_id' => $this->getId(), + )); } function delete($file_id) { - $deleted = 0; - $sql='DELETE FROM '.ATTACHMENT_TABLE - .' WHERE object_id='.db_input($this->getId()) - .' AND `type`='.db_input($this->getType()) - .' AND file_id='.db_input($file_id); - return db_query($sql) && db_affected_rows() > 0; + return Attachment::objects()->filter(array( + 'type' => $this->getType(), + 'object_id' => $this->getId(), + 'file_id' => $file_id, + ))->delete(); } function deleteAll($inline_only=false){ - $deleted=0; - $sql='DELETE FROM '.ATTACHMENT_TABLE - .' WHERE object_id='.db_input($this->getId()) - .' AND `type`='.db_input($this->getType()); + $objects = Attachment::objects()->filter(array( + 'type' => $this->getType(), + 'object_id' => $this->getId(), + )); if ($inline_only) - $sql .= ' AND inline = 1'; - return db_query($sql) && db_affected_rows() > 0; + $objects->filter(array('inline' => 1)); + + return $objects->delete(); } function deleteInlines() { diff --git a/include/class.auth.php b/include/class.auth.php index b115258952323bd069ece521c8643b7211f5fa45..192c3af7079265b5d99527390ca497db9bd45fe2 100644 --- a/include/class.auth.php +++ b/include/class.auth.php @@ -1050,8 +1050,10 @@ class AuthTokenAuthentication extends UserAuthenticationBackend { $user = null; switch ($matches['type']) { case 'c': //Collaborator - $criteria = array( 'userId' => $matches['id'], - 'ticketId' => $matches['tid']); + $criteria = array( + 'user_id' => $matches['id'], + 'thread__ticket__ticket_id' => $matches['tid'] + ); if (($c = Collaborator::lookup($criteria)) && ($c->getTicketId() == $matches['tid'])) $user = new ClientSession($c); @@ -1102,8 +1104,9 @@ class AccessLinkAuthentication extends UserAuthenticationBackend { $user = $ticket->getOwner(); // Collaborator? elseif (!($user = Collaborator::lookup(array( - 'userId' => $user->getId(), - 'ticketId' => $ticket->getId())))) + 'user_id' => $user->getId(), + 'thread__ticket__ticket_id' => $ticket->getId()) + ))) return false; //Bro, we don't know you! return $user; diff --git a/include/class.banlist.php b/include/class.banlist.php index ae7b894479f4e3c56c51c30487bf1cd8fc16e2c2..02c4ff2c79592cfc9660cd5d51b88f71ab769ff5 100644 --- a/include/class.banlist.php +++ b/include/class.banlist.php @@ -25,8 +25,31 @@ class Banlist { return self::getSystemBanList()->removeRule('email','equal',$email); } - function isbanned($email) { - return TicketFilter::isBanned($email); + /** + * Quick function to determine if the received email-address is in the + * banlist. Returns the filter of the filter that has the address + * blacklisted and FALSE if the email is not blacklisted. + * + */ + static function isBanned($addr) { + + if (!($filter=self::getFilter())) + return false; + + $sql='SELECT filter.id ' + .' FROM '.FILTER_TABLE.' filter' + .' INNER JOIN '.FILTER_RULE_TABLE.' rule' + .' ON (filter.id=rule.filter_id)' + .' WHERE filter.id='.db_input($filter->getId()) + .' AND filter.isactive' + .' AND rule.isactive ' + .' AND rule.what="email"' + .' AND rule.val='.db_input($addr); + + if (($res=db_query($sql)) && db_num_rows($res)) + return $filter; + + return false; } function includes($email) { @@ -61,7 +84,7 @@ class Banlist { return new Filter(self::ensureSystemBanList()); } - function getFilter() { + static function getFilter() { return self::getSystemBanList(); } } diff --git a/include/class.canned.php b/include/class.canned.php index ca1354332107d391b4f55a512fd5a3a149d8a117..5a396b8bd2d8b7284cdfb69ab3f01d88385f8340 100644 --- a/include/class.canned.php +++ b/include/class.canned.php @@ -50,12 +50,10 @@ class Canned { if(!$id && !($id=$this->getId())) return false; - $sql='SELECT canned.*, count(attach.file_id) as attachments, ' - .' count(filter.id) as filters ' + $sql='SELECT canned.*, count(attach.file_id) as attachments ' .' FROM '.CANNED_TABLE.' canned ' .' LEFT JOIN '.ATTACHMENT_TABLE.' attach ON (attach.object_id=canned.canned_id AND attach.`type`=\'C\' AND NOT attach.inline) ' - .' LEFT JOIN '.FILTER_TABLE.' filter ON (canned.canned_id = filter.canned_response_id) ' .' WHERE canned.canned_id='.db_input($id) .' GROUP BY canned.canned_id'; @@ -86,8 +84,38 @@ class Canned { return $this->isEnabled(); } + function getFilters() { + + if (!isset($this->_filters)) { + $this->_filters = array(); + $cid = sprintf('"canned_id":%d', $this->getId()); + $sql='SELECT filter.id, filter.name ' + .' FROM '.FILTER_TABLE.' filter' + .' INNER JOIN '.FILTER_ACTION_TABLE.' action' + .' ON (filter.id=action.filter_id)' + .' WHERE action.type="canned"' + ." AND action.configuration LIKE '%$cid%'"; + + if (($res=db_query($sql)) && db_num_rows($res)) + while (list($id, $name) = db_fetch_row($res)) + $this->_filters[$id] = $name; + } + + return $this->_filters; + } + + function getAttachedFiles($inlines=false) { + return AttachmentFile::objects() + ->filter(array( + 'attachments__type'=>'C', + 'attachments__object_id'=>$this->getId(), + 'attachments__inline' => $inlines, + )) + ->all(); + } + function getNumFilters() { - return $this->ht['filters']; + return count($this->getFilters()); } function getTitle() { @@ -130,11 +158,18 @@ class Canned { if ($cb && is_callable($cb)) $resp = $cb($resp); - $resp['files'] = $this->attachments->getSeparates(); + $resp['files'] = array(); + foreach ($this->getAttachedFiles(!$html) as $file) { + $resp['files'][] = array( + 'id' => $file->id, + 'name' => $file->name, + 'size' => $file->size, + 'download_url' => $file->getDownloadUrl(), + ); + } // strip html if (!$html) { $resp['response'] = Format::html2text($resp['response'], 90); - $resp['files'] += $this->attachments->getInlines(); } return Format::json_encode($resp); break; @@ -175,19 +210,6 @@ class Canned { return $this->getHashtable(); } - function getFilters() { - if (!$this->_filters) { - $this->_filters = array(); - $res = db_query( - 'SELECT name FROM '.FILTER_TABLE - .' WHERE canned_response_id = '.db_input($this->getId()) - .' ORDER BY name'); - while ($row = db_fetch_row($res)) - $this->_filters[] = $row[0]; - } - return $this->_filters; - } - function update($vars, &$errors) { if(!$this->save($this->getId(),$vars,$errors)) diff --git a/include/class.charset.php b/include/class.charset.php new file mode 100644 index 0000000000000000000000000000000000000000..5411e6b4abcb1347a0e22998678b13d57fe119d3 --- /dev/null +++ b/include/class.charset.php @@ -0,0 +1,75 @@ +<?php +/********************************************************************* + class.charset.php + + Charset util class + + Copyright (c) 2015 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ + +class Charset { + + const UTF8 = 'utf-8'; + + // Cleanup invalid charsets + // Thanks in part to https://github.com/mikel/mail/commit/88457e + static function normalize($charset) { + + $match = array(); + switch (true) { + // Windows charsets - force correct format + case preg_match('`^Windows-?(\d+)$`', $charset, $match): + return 'Windows-'.$match[1]; + // ks_c_5601-1987: Korean alias for cp949 + case preg_match('`^ks_c_5601-1987`', $charset): + return 'cp949'; + // Incorrect, bogus, ambiguous or empty charsets + // ISO-8859-1 is assumed + case preg_match('`^(default|x-user-defined|iso|us-ascii)`', $charset): + case preg_match('`^\s*$`', $charset): + return 'ISO-8859-1'; + } + + // Hmmmm + return $charset; + } + + // Translate characters ($text) from one encoding ($from) to another ($to) + static function transcode($text, $from, $to) { + + //Try auto-detecting charset/encoding + if (!$from && function_exists('mb_detect_encoding')) + $from = mb_detect_encoding($text); + + // Normalize bogus or ambiguous charsets + $from = self::normalize(trim($from)); + $to = self::normalize(trim($to)); + + $original = $text; + if (function_exists('iconv')) + $text = iconv($from, $to.'//IGNORE', $text); + elseif (function_exists('mb_convert_encoding')) + $text = mb_convert_encoding($text, $to, $from); + elseif (!strcasecmp($to, 'utf-8') + && function_exists('utf8_encode') + && !strcasecmp($from, 'ISO-8859-1')) + $text = utf8_encode($text); + + // If $text is false, then we have a (likely) invalid charset, use + // the original text and assume 8-bit (latin-1 / iso-8859-1) + // encoding + return (!$text && $original) ? $original : $text; + } + + //Wrapper for utf-8 transcoding. + function utf8($text, $charset=null) { + return self::transcode($text, $charset, self::UTF8); + } +} +?> diff --git a/include/class.client.php b/include/class.client.php index e353b977aaab06a3c3667b5d7f8e053987e120b1..25efc2ca60132537015107d13d273b913bc13ee7 100644 --- a/include/class.client.php +++ b/include/class.client.php @@ -15,7 +15,8 @@ **********************************************************************/ require_once INCLUDE_DIR.'class.user.php'; -abstract class TicketUser { +abstract class TicketUser +implements EmailContact, ITicketUser { static private $token_regex = '/^(?P<type>\w{1})(?P<algo>\d+)x(?P<hash>.*)$/i'; @@ -43,7 +44,7 @@ abstract class TicketUser { return sprintf('%s/view.php?%s', $cfg->getBaseUrl(), Http::build_query( - array('auth' => $this->getAuthToken()), + array('auth' => $this->getTicket()->getAuthToken($this)), false ) ); @@ -54,51 +55,8 @@ abstract class TicketUser { } - function sendAccessLink() { - global $ost; - - if (!($ticket = $this->getTicket()) - || !($email = $ost->getConfig()->getDefaultEmail()) - || !($content = Page::lookupByType('access-link'))) - return; - - $vars = array( - 'url' => $ost->getConfig()->getBaseUrl(), - 'ticket' => $this->getTicket(), - 'user' => $this, - 'recipient' => $this); - - $lang = false; - if (is_callable(array($this, 'getLanguage'))) - $lang = $this->getLanguage(UserAccount::LANG_MAILOUTS); - $msg = $ost->replaceTemplateVariables(array( - 'subj' => $content->getLocalName($lang), - 'body' => $content->getLocalBody($lang), - ), $vars); - - $email->send($this->getEmail(), Format::striptags($msg['subj']), - $msg['body']); - } - - protected function getAuthToken($algo=1) { - - //Format: // <user type><algo id used>x<pack of uid & tid><hash of the algo> - $authtoken = sprintf('%s%dx%s', - ($this->isOwner() ? 'o' : 'c'), - $algo, - Base32::encode(pack('VV',$this->getId(), $this->getTicketId()))); - - switch($algo) { - case 1: - $authtoken .= substr(base64_encode( - md5($this->getId().$this->getTicket()->getCreateDate().$this->getTicketId().SECRET_SALT, true)), 8); - break; - default: - return null; - } - - return $authtoken; - } + function getId() { return ($this->user) ? $this->user->getId() : null; } + function getEmail() { return ($this->user) ? $this->user->getEmail() : null; } static function lookupByToken($token) { @@ -112,6 +70,10 @@ abstract class TicketUser { Base32::decode(strtolower(substr($matches['hash'], 0, 13)))); $user = null; + if (!($ticket = Ticket::lookup($matches['tid']))) + // Require a ticket for now + return null; + switch ($matches['type']) { case 'c': //Collaborator c if (($user = Collaborator::lookup($matches['uid'])) @@ -119,17 +81,16 @@ abstract class TicketUser { $user = null; break; case 'o': //Ticket owner - if (($ticket = Ticket::lookup($matches['tid']))) { - if (($user = $ticket->getOwner()) - && $user->getId() != $matches['uid']) - $user = null; + if (($user = $ticket->getOwner()) + && $user->getId() != $matches['uid']) { + $user = null; } break; } if (!$user - || !$user instanceof TicketUser - || strcasecmp($user->getAuthToken($matches['algo']), $token)) + || !$user instanceof ITicketUser + || strcasecmp($ticket->getAuthToken($user, $matches['algo']), $token)) return false; return $user; @@ -213,10 +174,13 @@ class EndUser extends BaseAuthenticatedUser { $u = $this; // Traverse the $user properties of all nested user objects to get // to the User instance with the custom data - while (isset($u->user)) + while (isset($u->user)) { $u = $u->user; - if (method_exists($u, 'getVar')) - return $u->getVar($tag); + if (method_exists($u, 'getVar')) { + if ($rv = $u->getVar($tag)) + return $rv; + } + } } function getId() { @@ -286,8 +250,10 @@ class EndUser extends BaseAuthenticatedUser { $where = ' WHERE ticket.user_id = '.db_input($this->getId()) .' OR collab.user_id = '.db_input($this->getId()).' '; - $join = 'LEFT JOIN '.TICKET_COLLABORATOR_TABLE.' collab - ON (collab.ticket_id=ticket.ticket_id + $join = 'LEFT JOIN '.THREAD_TABLE.' thread + ON (ticket.ticket_id = thread.object_id and thread.object_type = \'T\') + LEFT JOIN '.THREAD_COLLABORATOR_TABLE.' collab + ON (collab.thread_id=thread.id AND collab.user_id = '.db_input($this->getId()).' ) '; $sql = 'SELECT \'open\', count( ticket.ticket_id ) AS tickets ' @@ -427,4 +393,19 @@ class ClientAccount extends UserAccount { } } +// Used by the email system +interface EmailContact { + // function getId() + // function getName() + // function getEmail() +} + +interface ITicketUser { + function isOwner(); + function flagGuest(); + function isGuest(); + function getUserId(); + function getTicketId(); + function getTicket(); +} ?> diff --git a/include/class.collaborator.php b/include/class.collaborator.php index 20e827c065a17d9d5a7207293b171c10b96dfc47..c457f1cd3cf4feac927e6076a428bc6a90ca4766 100644 --- a/include/class.collaborator.php +++ b/include/class.collaborator.php @@ -16,159 +16,142 @@ require_once(INCLUDE_DIR . 'class.user.php'); require_once(INCLUDE_DIR . 'class.client.php'); -class Collaborator extends TicketUser { +class Collaborator +extends VerySimpleModel +implements EmailContact, ITicketUser { - var $ht; - - var $user; - var $ticket; - - function __construct($id) { - $this->load($id); - parent::__construct($this->getUser()); - } - - function load($id) { - - if(!$id && !($id=$this->getId())) - return; - - $sql='SELECT * FROM '.TICKET_COLLABORATOR_TABLE - .' WHERE id='.db_input($id); - - $this->ht = db_fetch_array(db_query($sql)); - $this->ticket = null; - } - - function reload() { - return $this->load(); - } + static $meta = array( + 'table' => THREAD_COLLABORATOR_TABLE, + 'pk' => array('id'), + 'select_related' => array('user'), + 'joins' => array( + 'thread' => array( + 'constraint' => array('thread_id' => 'Thread.id'), + ), + 'user' => array( + 'constraint' => array('user_id' => 'User.id'), + ), + ), + ); function __toString() { return Format::htmlchars(sprintf('%s <%s>', $this->getName(), - $this->getEmail())); + $this->getEmail())); } function getId() { - return $this->ht['id']; + return $this->id; } function isActive() { - return ($this->ht['isactive']); + return $this->isactive; } function getCreateDate() { - return $this->ht['created']; + return $this->created; } function getTicketId() { - return $this->ht['ticket_id']; + if ($this->thread->object_type == ObjectModel::OBJECT_TYPE_TICKET) + return $this->thread->object_id; } function getTicket() { - if(!$this->ticket && $this->getTicketId()) - $this->ticket = Ticket::lookup($this->getTicketId()); - - return $this->ticket; + // TODO: Change to $this->thread->ticket when Ticket goes to ORM + if ($id = $this->getTicketId()) + return Ticket::lookup($id); } - function getUserId() { - return $this->ht['user_id']; + function getUser() { + return $this->user; } - function getUser() { + // EmailContact interface + function getEmail() { + return $this->user->getEmail(); + } + function getName() { + return $this->user->getName(); + } - if(!$this->user && $this->getUserId()) - $this->user = User::lookup($this->getUserId()); + // VariableReplacer interface + function getVar($what) { + global $cfg; - return $this->user; + switch (strtolower($what)) { + case 'ticket_link': + return sprintf('%s/view.php?%s', + $cfg->getBaseUrl(), + Http::build_query( + // TODO: Chance to $this->getTicket when + array('auth' => $this->getTicket()->getAuthToken($this)), + false + ) + ); + break; + } } - function remove() { + // ITicketUser interface + var $_isguest; - $sql='DELETE FROM '.TICKET_COLLABORATOR_TABLE - .' WHERE id='.db_input($this->getId()) - .' LIMIT 1'; + function isOwner() { + return false; + } + function flagGuest() { + $this->_isguest = true; + } + function isGuest() { + return $this->_isguest; + } + function getUserId() { + return $this->user_id; + } - return (db_query($sql) && db_affected_rows()); + function save($refetch=false) { + if ($this->dirty) + $this->updated = SqlFunction::NOW(); + return parent::save($refetch || $this->dirty); } static function add($info, &$errors) { - if (!$info || !$info['ticketId'] || !$info['userId']) + if (!$info || !$info['threadId'] || !$info['userId']) $errors['err'] = __('Invalid or missing information'); - elseif (($c=self::lookup($info))) + elseif ($c = static::lookup(array( + 'thread_id' => $info['threadId'], + 'user_id' => $info['userId'], + ))) $errors['err'] = sprintf(__('%s is already a collaborator'), $c->getName()); if ($errors) return false; - $sql='INSERT INTO '.TICKET_COLLABORATOR_TABLE - .' SET updated=NOW() ' - .' ,isactive='.db_input(isset($info['isactive']) ? $info['isactive'] : 0) - .' ,ticket_id='.db_input($info['ticketId']) - .' ,user_id='.db_input($info['userId']); - - if(db_query($sql) && ($id=db_insert_id())) - return self::lookup($id); + $collab = static::create(array( + 'isactive' => isset($info['isactive']) ? $info['isactive'] : 0, + 'thread_id' => $info['threadId'], + 'user_id' => $info['userId'], + )); + if ($collab->save(true)) + return $collab; $errors['err'] = __('Unable to add collaborator. Internal error'); return false; } - static function forTicket($tid, $criteria=array()) { - - $collaborators = array(); + static function forThread($tid, $criteria=array()) { - $sql='SELECT id FROM '.TICKET_COLLABORATOR_TABLE - .' WHERE ticket_id='.db_input($tid); + $collaborators = static::objects() + ->filter(array('thread_id' => $tid)); - if(isset($criteria['isactive'])) - $sql.=' AND isactive='.db_input($criteria['isactive']); + if (isset($criteria['isactive'])) + $collaborators->filter(array('isactive' => $criteria['isactive'])); - //TODO: sort by name of the user - - if(($res=db_query($sql)) && db_num_rows($res)) - while(list($id)=db_fetch_row($res)) - $collaborators[] = self::lookup($id); + // TODO: sort by name of the user + $collaborators->order_by('user__name'); return $collaborators; } - - static function getIdByInfo($info) { - - $sql='SELECT id FROM '.TICKET_COLLABORATOR_TABLE - .' WHERE ticket_id='.db_input($info['ticketId']) - .' AND user_id='.db_input($info['userId']); - - return db_result(db_query($sql)); - } - - static function lookup($criteria) { - - $id = is_numeric($criteria) - ? $criteria : self::getIdByInfo($criteria); - - return ($id - && ($c = new Collaborator($id)) - && $c->getId() == $id) - ? $c : null; - } -} - -class TicketCollaborator extends VerySimpleModel { - static $meta = array( - 'table' => TICKET_COLLABORATOR_TABLE, - 'pk' => array('id'), - 'joins' => array( - 'ticket' => array( - 'constraint' => array('ticket_id' => 'TicketModel.ticket_id'), - ), - 'user' => array( - 'constraint' => array('user_id' => 'User.id'), - ), - ), - ); } ?> diff --git a/include/class.config.php b/include/class.config.php index fc488ee4619d4e5fdc8edf5761f8253546e07a18..7ddc58855f0b68cb5f56f98ad893c43222e79e85 100644 --- a/include/class.config.php +++ b/include/class.config.php @@ -1096,6 +1096,13 @@ class OsticketConfig extends Config { return $this->getLogoId('client'); } + function getStaffLogoId() { + return $this->getLogoId('staff'); + } + function getStaffLogo() { + return $this->getLogo('staff'); + } + function updatePagesSettings($vars, &$errors) { global $ost; @@ -1111,7 +1118,7 @@ class OsticketConfig extends Config { ; // Pass elseif ($logo['error']) $errors['logo'] = $logo['error']; - elseif (!($id = AttachmentFile::uploadLogo($logo, $error))) + elseif (!AttachmentFile::uploadLogo($logo, $error)) $errors['logo'] = sprintf(__('Unable to upload logo image: %s'), $error); } @@ -1139,6 +1146,9 @@ class OsticketConfig extends Config { 'client_logo_id' => ( (is_numeric($vars['selected-logo']) && $vars['selected-logo']) ? $vars['selected-logo'] : false), + 'staff_logo_id' => ( + (is_numeric($vars['selected-logo-scp']) && $vars['selected-logo-scp']) + ? $vars['selected-logo-scp'] : false), )); } diff --git a/include/class.cron.php b/include/class.cron.php index f231ac5b3db00695cfa0a0a1045ff62d0bec9745..94e1af314a5e97bb957c212ef40ec3765004a360 100644 --- a/include/class.cron.php +++ b/include/class.cron.php @@ -27,9 +27,11 @@ class Cron { function TicketMonitor() { require_once(INCLUDE_DIR.'class.ticket.php'); - require_once(INCLUDE_DIR.'class.lock.php'); Ticket::checkOverdue(); //Make stale tickets overdue - TicketLock::cleanup(); //Remove expired locks + // Cleanup any expired locks + require_once(INCLUDE_DIR.'class.lock.php'); + Lock::cleanup(); + } function PurgeLogs() { @@ -54,7 +56,7 @@ class Cron { $chance = rand(1,2000); switch ($chance) { case 42: - @db_query('OPTIMIZE TABLE '.TICKET_LOCK_TABLE); + @db_query('OPTIMIZE TABLE '.LOCK_TABLE); break; case 242: @db_query('OPTIMIZE TABLE '.SYSLOG_TABLE); diff --git a/include/class.csrf.php b/include/class.csrf.php index 94f103cb8277013ef4131035968cb0775487b6eb..a1c3aed21392d5932b6b1edb31108cc6d3bedf8a 100644 --- a/include/class.csrf.php +++ b/include/class.csrf.php @@ -53,12 +53,15 @@ Class CSRF { return $this->name; } - function getToken() { + function rotate() { + $this->csrf['token'] = sha1(session_id().Crypto::random(16).SECRET_SALT); + $this->csrf['time'] = time(); + } - if(!$this->csrf['token'] || $this->isExpired()) { + function getToken() { - $this->csrf['token'] = sha1(session_id().Crypto::random(16).SECRET_SALT); - $this->csrf['time'] = time(); + if (!$this->csrf['token'] || $this->isExpired()) { + $this->rotate(); } else { //Reset the timer $this->csrf['time'] = time(); diff --git a/include/class.draft.php b/include/class.draft.php index d777338d2296f39352dbe2488587a9b11f30ec1b..659325ede98dd6281a83857f92d5b4f989f9df96 100644 --- a/include/class.draft.php +++ b/include/class.draft.php @@ -62,11 +62,13 @@ class Draft extends VerySimpleModel { $body = Format::localizeInlineImages($body); $matches = array(); if (preg_match_all('/"cid:([\\w.-]{32})"/', $body, $matches)) { - foreach ($matches[1] as $hash) { - if ($file_id = AttachmentFile::getIdByHash($hash)) - $attachments[] = array( - 'id' => $file_id, - 'inline' => true); + $files = AttachmentFile::objects() + ->filter(array('key__in' => $matches[1])); + foreach ($files as $F) { + $attachments[] = array( + 'id' => $F->getId(), + 'inline' => true + ); } } return $attachments; @@ -86,14 +88,19 @@ class Draft extends VerySimpleModel { // Purge current attachments $this->attachments->deleteInlines(); - foreach ($matches[1] as $hash) - if ($file = AttachmentFile::getIdByHash($hash)) - $this->attachments->upload($file, true); + foreach (AttachmentFile::objects() + ->filter(array('key__in' => $matches[1])) + as $F + ) { + $this->attachments->upload($F->getId(), true); + } } function setBody($body) { // Change file.php urls back to content-id's - $body = Format::sanitize($body, false); + $body = Format::sanitize($body, false, + // Preserve annotation information, if any + 'img=data-annotations,data-orig-annotated-image-src'); $this->body = $body ?: ' '; $this->updated = SqlFunction::NOW(); diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php index 2021ff656aba5a6fd1e93862e9e0fe21485e1af5..110f28377666a11ed1acf476fec8f4f095fdd0bc 100644 --- a/include/class.dynamic_forms.php +++ b/include/class.dynamic_forms.php @@ -223,23 +223,25 @@ class DynamicForm extends VerySimpleModel { return false; } // New translations (?) - foreach ($vars['trans'] as $lang=>$parts) { - if (!Internationalization::isLanguageInstalled($lang)) - continue; - foreach ($parts as $T => $content) { - $content = trim($content); - if (!$content) + if ($vars['trans'] && is_array($vars['trans'])) { + foreach ($vars['trans'] as $lang=>$parts) { + if (!Internationalization::isLanguageInstalled($lang)) continue; - $t = CustomDataTranslation::create(array( - 'type' => 'phrase', - 'object_hash' => $tags[$T], - 'lang' => $lang, - 'text' => $content, - 'agent_id' => $thisstaff->getId(), - 'updated' => SqlFunction::NOW(), - )); - if (!$t->save()) - return false; + foreach ($parts as $T => $content) { + $content = trim($content); + if (!$content) + continue; + $t = CustomDataTranslation::create(array( + 'type' => 'phrase', + 'object_hash' => $tags[$T], + 'lang' => $lang, + 'text' => $content, + 'agent_id' => $thisstaff->getId(), + 'updated' => SqlFunction::NOW(), + )); + if (!$t->save()) + return false; + } } } return true; @@ -790,8 +792,6 @@ class DynamicFormEntry extends VerySimpleModel { 'ordering' => array('sort'), 'pk' => array('id'), 'select_related' => array('form'), - 'fields' => array('id', 'form_id', 'object_type', 'object_id', - 'sort', 'extra', 'updated', 'created'), 'joins' => array( 'form' => array( 'null' => true, @@ -1296,10 +1296,17 @@ class SelectionField extends FormField { return $this->getList()->getForm(); } function getSubFields() { + $fields = new ListObject(array( + new TextboxField(array( + // XXX: i18n: Change to a better word when the UI changes + 'label' => '['.__('Abbrev').']', + 'id' => 'abb', + )) + )); $form = $this->getList()->getForm(); - if ($form) - return $form->getFields(); - return array(); + if ($form && ($F = $form->getFields())) + $fields->extend($F); + return $fields; } function toString($items) { @@ -1406,9 +1413,21 @@ class SelectionField extends FormField { } function getFilterData() { + // Start with the filter data for the list item as the [0] index $data = array(parent::getFilterData()); - if (($v = $this->getClean()) instanceof DynamicListItem) { - $data = array_merge($data, $v->getFilterData()); + if (($v = $this->getClean())) { + // Add in the properties for all selected list items in sub + // labeled by their field id + foreach ($v as $id=>$L) { + if (!($li = DynamicListItem::lookup($id))) + continue; + foreach ($li->getFilterData() as $prop=>$value) { + if (!isset($data[$prop])) + $data[$prop] = $value; + else + $data[$prop] .= " $value"; + } + } } return $data; } @@ -1475,9 +1494,9 @@ class TypeaheadSelectionWidget extends ChoicesWidget { foreach ($this->field->getList()->getItems() as $i) $source[] = array( 'value' => $i->getValue(), 'id' => $i->getId(), - 'info' => sprintf('%s %s', + 'info' => sprintf('%s%s', $i->getValue(), - (($extra= $i->getAbbrev()) ? "-- $extra" : '')), + (($extra= $i->getAbbrev()) ? " — $extra" : '')), ); ?> <span style="display:inline-block"> @@ -1498,6 +1517,7 @@ class TypeaheadSelectionWidget extends ChoicesWidget { $('input#<?php echo $this->name; ?>_id') .attr('name', '<?php echo $this->name; ?>[' + item['id'] + ']') .val(item['value']); + return false; } }); }); @@ -1516,8 +1536,12 @@ class TypeaheadSelectionWidget extends ChoicesWidget { function getEnteredValue() { // Used to verify typeahead fields $data = $this->field->getSource(); - if (isset($data[$this->name.'_name'])) - return trim($data[$this->name.'_name']); + if (isset($data[$this->name.'_name'])) { + // Drop the extra part, if any + $v = $data[$this->name.'_name']; + $v = substr($v, 0, strrpos($v, ' — ')); + return trim($v); + } return parent::getValue(); } } diff --git a/include/class.export.php b/include/class.export.php index 51aec30250c6921671b3f76fbdaf0c9a3323b55d..a45699d3a8f498949e49456f790a766360aa52fb 100644 --- a/include/class.export.php +++ b/include/class.export.php @@ -317,13 +317,13 @@ class DatabaseExporter { FAQ_TOPIC_TABLE, FAQ_CATEGORY_TABLE, DRAFT_TABLE, CANNED_TABLE, TICKET_TABLE, ATTACHMENT_TABLE, THREAD_TABLE, THREAD_ENTRY_TABLE, THREAD_ENTRY_EMAIL_TABLE, - TICKET_LOCK_TABLE, TICKET_EVENT_TABLE, TICKET_PRIORITY_TABLE, + LOCK_TABLE, TICKET_EVENT_TABLE, TICKET_PRIORITY_TABLE, EMAIL_TABLE, EMAIL_TEMPLATE_TABLE, EMAIL_TEMPLATE_GRP_TABLE, FILTER_TABLE, FILTER_RULE_TABLE, SLA_TABLE, API_KEY_TABLE, TIMEZONE_TABLE, SESSION_TABLE, PAGE_TABLE, FORM_SEC_TABLE, FORM_FIELD_TABLE, LIST_TABLE, LIST_ITEM_TABLE, FORM_ENTRY_TABLE, FORM_ANSWER_TABLE, USER_TABLE, USER_EMAIL_TABLE, - PLUGIN_TABLE, TICKET_COLLABORATOR_TABLE, + PLUGIN_TABLE, THREAD_COLLABORATOR_TABLE, USER_ACCOUNT_TABLE, ORGANIZATION_TABLE, NOTE_TABLE ); diff --git a/include/class.file.php b/include/class.file.php index 2c2ab0fc69a37f19c3cda28e49b2cfa22d7bd925..78cbed9c8e9d634cf828a34d5ab28c532804c3fb 100644 --- a/include/class.file.php +++ b/include/class.file.php @@ -14,43 +14,17 @@ require_once(INCLUDE_DIR.'class.signal.php'); require_once(INCLUDE_DIR.'class.error.php'); -class AttachmentFile { - - var $id; - var $ht; - - function AttachmentFile($id) { - $this->id =0; - return ($this->load($id)); - } - - function load($id=0) { - - if(!$id && !($id=$this->getId())) - return false; - - $sql='SELECT f.id, f.type, size, name, `key`, signature, ft, bk, f.created, ' - .' count(DISTINCT a.object_id) as canned, ' - .' count(DISTINCT t.id) as entries ' - .' FROM '.FILE_TABLE.' f ' - .' LEFT JOIN '.ATTACHMENT_TABLE.' a - ON(a.file_id=f.id) ' - .' LEFT JOIN '.ATTACHMENT_TABLE.' t - ON(t.file_id = f.id) ' - .' WHERE f.id='.db_input($id) - .' GROUP BY f.id'; - if(!($res=db_query($sql)) || !db_num_rows($res)) - return false; - - $this->ht=db_fetch_array($res); - $this->id =$this->ht['id']; - - return true; - } - - function reload() { - return $this->load(); - } +class AttachmentFile extends VerySimpleModel { + + static $meta = array( + 'table' => FILE_TABLE, + 'pk' => array('id'), + 'joins' => array( + 'attachments' => array( + 'reverse' => 'Attachment.file' + ), + ), + ); function getHashtable() { return $this->ht; @@ -61,15 +35,15 @@ class AttachmentFile { } function getNumEntries() { - return $this->ht['entries']; + return $this->attachments->count(); } function isCanned() { - return ($this->ht['canned']); + return $this->getNumEntries(); } function isInUse() { - return ($this->getNumEntries() || $this->isCanned()); + return $this->getNumEntries(); } function getId() { @@ -77,11 +51,11 @@ class AttachmentFile { } function getType() { - return $this->ht['type']; + return $this->type; } function getBackend() { - return $this->ht['bk']; + return $this->bk; } function getMime() { @@ -89,25 +63,25 @@ class AttachmentFile { } function getSize() { - return $this->ht['size']; + return $this->size; } function getName() { - return $this->ht['name']; + return $this->name; } function getKey() { - return $this->ht['key']; + return $this->key; } - function getSignature() { - $sig = $this->ht['signature']; - if (!$sig) return $this->getKey(); + function getSignature($cascade=false) { + $sig = $this->signature; + if (!$sig && $cascade) return $this->getKey(); return $sig; } function lastModified() { - return $this->ht['created']; + return $this->created; } function open() { @@ -145,8 +119,7 @@ class AttachmentFile { function delete() { - $sql='DELETE FROM '.FILE_TABLE.' WHERE id='.db_input($this->getId()).' LIMIT 1'; - if(!db_query($sql) || !db_affected_rows()) + if (!parent::delete()) return false; if ($bk = $this->open()) @@ -156,7 +129,7 @@ class AttachmentFile { } function makeCacheable($ttl=86400) { - Http::cacheable($this->getSignature(), $this->lastModified(), $ttl); + Http::cacheable($this->getSignature(true), $this->lastModified(), $ttl); } function display($scale=false) { @@ -298,7 +271,7 @@ class AttachmentFile { } /* Function assumes the files types have been validated */ - function upload($file, $ft='T') { + static function upload($file, $ft='T', $deduplicate=true) { if(!$file['name'] || $file['error'] || !is_uploaded_file($file['tmp_name'])) return false; @@ -314,10 +287,10 @@ class AttachmentFile { 'tmp_name'=>$file['tmp_name'], ); - return AttachmentFile::save($info, $ft); + return static::create($info, $ft, $deduplicate); } - function uploadLogo($file, &$error, $aspect_ratio=3) { + static function uploadLogo($file, &$error, $aspect_ratio=2) { /* Borrowed in part from * http://salman-w.blogspot.com/2009/04/crop-to-fit-image-using-aspphp.html */ @@ -342,14 +315,19 @@ class AttachmentFile { $source_aspect_ratio = $source_width / $source_height; if ($source_aspect_ratio >= $aspect_ratio) - return self::upload($file, 'L'); + return self::upload($file, 'L', false); $error = __('Image is too square. Upload a wider image'); return false; } - function save(&$file, $ft='T') { - + static function create(&$file, $ft='T', $deduplicate=true) { + if (isset($file['encoding'])) { + switch ($file['encoding']) { + case 'base64': + $file['data'] = base64_decode($file['data']); + } + } if (isset($file['data'])) { // Allow a callback function to delay or avoid reading or // fetching ihe file contents @@ -362,17 +340,19 @@ class AttachmentFile { $file['key'] = $key; } - if (isset($file['size'])) { + if (isset($file['size']) && $file['size'] > 0) { // Check and see if the file is already on record - $sql = 'SELECT id, `key` FROM '.FILE_TABLE - .' WHERE signature='.db_input($file['signature']) - .' AND size='.db_input($file['size']); - - // If the record exists in the database already, a file with the - // same hash and size is already on file -- just return its ID - if (list($id, $key) = db_fetch_row(db_query($sql))) { - $file['key'] = $key; - return $id; + $existing = static::objects()->filter(array( + 'signature' => $file['signature'], + 'size' => $file['size'] + ))->first(); + + // If the record exists in the database already, a file with + // the same hash and size is already on file -- just return + // the file + if ($deduplicate && $existing) { + $file['key'] = $existing->key; + return $existing; } } elseif (!isset($file['data'])) { @@ -393,20 +373,19 @@ class AttachmentFile { if (!$file['type']) $file['type'] = 'application/octet-stream'; - $sql='INSERT INTO '.FILE_TABLE.' SET created=NOW() ' - .',type='.db_input(strtolower($file['type'])) - .',name='.db_input($file['name']) - .',`key`='.db_input($file['key']) - .',ft='.db_input($ft ?: 'T') - .',signature='.db_input($file['signature']); - if (isset($file['size'])) - $sql .= ',size='.db_input($file['size']); + $f = parent::create(array( + 'type' => strtolower($file['type']), + 'name' => $file['name'], + 'key' => $file['key'], + 'ft' => $ft ?: 'T', + 'signature' => $file['signature'], + )); - if (!(db_query($sql) && ($id = db_insert_id()))) - return false; + if (isset($file['size'])) + $f->size = $file['size']; - if (!($f = AttachmentFile::lookup($id))) + if (!$f->save()) return false; // Note that this is preferred over $f->open() because the file does @@ -440,26 +419,22 @@ class AttachmentFile { return false; } - $sql = 'UPDATE '.FILE_TABLE.' SET bk='.db_input($bk->getBkChar()); + $f->bk = $bk->getBkChar(); if (!isset($file['size'])) { if ($size = $bk->getSize()) - $file['size'] = $size; + $f->size = $size; // Prefer mb_strlen, because mbstring.func_overload will // automatically prefer it if configured. elseif (extension_loaded('mbstring')) - $file['size'] = mb_strlen($file['data'], '8bit'); + $f->size = mb_strlen($file['data'], '8bit'); // bootstrap.php include a compat version of mb_strlen else - $file['size'] = strlen($file['data']); - - $sql .= ', `size`='.db_input($file['size']); + $f->size = strlen($file['data']); } - $sql .= ' WHERE id='.db_input($f->getId()); - db_query($sql); - - return $f->getId(); + $f->save(); + return $f; } /** @@ -523,10 +498,8 @@ class AttachmentFile { return false; } - $sql = 'UPDATE '.FILE_TABLE.' SET bk=' - .db_input($target->getBkChar()) - .' WHERE id='.db_input($this->getId()); - if (!db_query($sql) || db_affected_rows()!=1) + $this->bk = $target->getBkChar(); + if (!$this->save()) return false; return $source->unlink(); @@ -554,31 +527,20 @@ class AttachmentFile { return FileStorageBackend::lookup($char, $file); } - /* Static functions */ - function getIdByHash($hash) { + static function lookupByHash($hash) { + static $keyCache = array(); - $sql='SELECT id FROM '.FILE_TABLE.' WHERE `key`='.db_input($hash); - if(($res=db_query($sql)) && db_num_rows($res)) - list($id)=db_fetch_row($res); + if (isset($keyCache[$hash])) + return $keyCache[$hash]; - return $id; + // Cache a negative lookup if no such file exists + return $keyCache[$hash] = parent::lookup(array('key' => $hash)); } - function lookup($id) { - - $id = is_numeric($id)?$id:AttachmentFile::getIdByHash($id); - - return ($id && ($file = new AttachmentFile($id)) && $file->getId()==$id)?$file:null; - } - - static function create($info, &$errors) { - if (isset($info['encoding'])) { - switch ($info['encoding']) { - case 'base64': - $info['data'] = base64_decode($info['data']); - } - } - return self::save($info); + static function lookup($id) { + return is_numeric($id) + ? parent::lookup($id) + : static::lookupByHash($id); } /* @@ -620,35 +582,31 @@ class AttachmentFile { * Removes files and associated meta-data for files which no ticket, * canned-response, or faq point to any more. */ - /* static */ function deleteOrphans() { + static function deleteOrphans() { // XXX: Allow plugins to define filetypes which do not represent // files attached to tickets or other things in the attachment // table and are not logos - //FIXME: Just user straight up left join - $sql = 'SELECT id FROM '.FILE_TABLE.' WHERE id NOT IN (' - .'SELECT file_id FROM '.ATTACHMENT_TABLE - .") AND `ft` = 'T' AND TIMESTAMPDIFF(DAY, `created`, CURRENT_TIMESTAMP) > 1"; - - if (!($res = db_query($sql))) - return false; - - while (list($id) = db_fetch_row($res)) - if (($file = self::lookup($id)) && !$file->delete()) + $files = static::objects() + ->filter(array( + 'attachments__object_id__isnull' => true, + 'ft' => 'T', + 'created__gt' => new DateTime('now -1 day'), + )); + + foreach ($files as $f) { + if (!$f->delete()) break; + } return true; } /* static */ function allLogos() { - $sql = 'SELECT id FROM '.FILE_TABLE.' WHERE ft="L" - ORDER BY created'; - $logos = array(); - $res = db_query($sql); - while (list($id) = db_fetch_row($res)) - $logos[] = AttachmentFile::lookup($id); - return $logos; + return static::objects() + ->filter(array('ft' => 'L')) + ->order_by('created'); } } diff --git a/include/class.filter.php b/include/class.filter.php index 7a2ced7e2d7012b0980ba0940ea5a6d2e03f7c38..9647481cc3cbb9e4e07c9204bc728e848351be9c 100644 --- a/include/class.filter.php +++ b/include/class.filter.php @@ -503,18 +503,8 @@ class Filter { .',email_id='.db_input($emailId) .',match_all_rules='.db_input($vars['match_all_rules']) .',stop_onmatch='.db_input(isset($vars['stop_onmatch'])?1:0) - .',reject_ticket='.db_input(isset($vars['reject_ticket'])?1:0) .',notes='.db_input(Format::sanitize($vars['notes'])); - - //Auto assign ID is overloaded... - if($vars['assign'] && $vars['assign'][0]=='s') - $sql.=',team_id=0,staff_id='.db_input(preg_replace("/[^0-9]/", "",$vars['assign'])); - elseif($vars['assign'] && $vars['assign'][0]=='t') - $sql.=',staff_id=0,team_id='.db_input(preg_replace("/[^0-9]/", "",$vars['assign'])); - else - $sql.=',staff_id=0,team_id=0 '; //no auto-assignment! - if($id) { $sql='UPDATE '.FILTER_TABLE.' SET '.$sql.' WHERE id='.db_input($id); if(!db_query($sql)) @@ -543,8 +533,16 @@ class Filter { return; foreach ($vars['actions'] as $sort=>$v) { - $info = substr($v, 1); - switch ($v[0]) { + if (is_array($v)) { + $info = $v['type']; + $sort = $v['sort'] ?: $sort; + $action = 'N'; + } else { + $action = $v[0]; + $info = substr($v, 1); + } + + switch ($action) { case 'N': # new filter action $I = FilterAction::create(array( 'type'=>$info, @@ -806,51 +804,6 @@ class TicketFilter { return db_query($sql); } - /** - * Quick function to determine if the received email-address is - * indicated by an active email filter to be banned. Returns the id of - * the filter that has the address blacklisted and FALSE if the email is - * not blacklisted. - * - * XXX: If more detailed matching is to be supported, perhaps this - * should receive an array like the constructor and - * Filter::matches() method. - * Peter - Let's keep it as a quick scan for obviously banned emails. - */ - /* static */ - function isBanned($addr) { - - $sql='SELECT filter.id, what, how, UPPER(val) ' - .' FROM '.FILTER_TABLE.' filter' - .' INNER JOIN '.FILTER_RULE_TABLE.' rule' - .' ON (filter.id=rule.filter_id)' - .' WHERE filter.reject_ticket' - .' AND filter.match_all_rules=0' - .' AND filter.email_id=0' - .' AND filter.isactive' - .' AND rule.isactive ' - .' AND rule.what="email"' - .' AND LOCATE(rule.val,'.db_input($addr).')'; - - if(!($res=db_query($sql)) || !db_num_rows($res)) - return false; - - # XXX: Use MB_xxx function for proper unicode support - $addr = strtoupper($addr); - $how=array('equal' => array('strcmp', 0), - 'contains' => array('strpos', null, false)); - - while ($row=db_fetch_array($res)) { - list($func, $pos, $neg) = $how[$row['how']]; - if (!$func) continue; - $result = call_user_func($func, $addr, $row['val']); - if (($neg === null && $result === $pos) || $result !== $neg) - return $row['id']; - } - - return false; - } - /** * Simple true/false if the headers of the email indicate that the email * is an automatic response. diff --git a/include/class.format.php b/include/class.format.php index 9e6c8998538bdfbe908693ece1cf9428a151bee8..02402cf70c45f7739d103fa7d462f7e4bede45b0 100644 --- a/include/class.format.php +++ b/include/class.format.php @@ -14,6 +14,7 @@ vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ +include_once INCLUDE_DIR.'class.charset.php'; class Format { @@ -40,47 +41,13 @@ class Format { return $size; } - /* encode text into desired encoding - taking into accout charset when available. */ - function encode($text, $charset=null, $encoding='utf-8') { - - //Try auto-detecting charset/encoding - if (!$charset && function_exists('mb_detect_encoding')) - $charset = mb_detect_encoding($text); - - // Cleanup - incorrect, bogus, or ambiguous charsets - // ISO-8859-1 is assumed for empty charset. - if (!$charset || in_array(strtolower(trim($charset)), - array('default','x-user-defined','iso','us-ascii'))) - $charset = 'ISO-8859-1'; - - $original = $text; - if (function_exists('iconv')) - $text = iconv($charset, $encoding.'//IGNORE', $text); - elseif (function_exists('mb_convert_encoding')) - $text = mb_convert_encoding($text, $encoding, $charset); - elseif (!strcasecmp($encoding, 'utf-8') - && function_exists('utf8_encode') - && !strcasecmp($charset, 'ISO-8859-1')) - $text = utf8_encode($text); - - // If $text is false, then we have a (likely) invalid charset, use - // the original text and assume 8-bit (latin-1 / iso-8859-1) - // encoding - return (!$text && $original) ? $original : $text; - } - - //Wrapper for utf-8 encoding. - function utf8encode($text, $charset=null) { - return Format::encode($text, $charset, 'utf-8'); - } - function mimedecode($text, $encoding='UTF-8') { if(function_exists('imap_mime_header_decode') && ($parts = imap_mime_header_decode($text))) { $str =''; foreach ($parts as $part) - $str.= Format::encode($part->text, $part->charset, $encoding); + $str.= Charset::transcode($part->text, $part->charset, $encoding); $text = $str; } elseif($text[0] == '=' && function_exists('iconv_mime_decode')) { @@ -105,7 +72,7 @@ class Format { $filename, $match)) // XXX: Currently we don't care about the language component. // The encoding hint is sufficient. - return self::utf8encode(urldecode($match[3]), $match[1]); + return Charset::utf8(urldecode($match[3]), $match[1]); else return $filename; } @@ -233,7 +200,7 @@ class Format { } } - function safe_html($html) { + function safe_html($html, $spec=false) { // Remove HEAD and STYLE sections $html = preg_replace( array(':<(head|style|script).+?</\1>:is', # <head> and <style> sections @@ -252,7 +219,7 @@ class Format { 'schemes' => 'href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; *:file, http, https; src: cid, http, https, data', 'hook_tag' => function($e, $a=0) { return Format::__html_cleanup($e, $a); }, 'elements' => '*+iframe', - 'spec' => 'iframe=-*,height,width,type,src(match="`^(https?:)?//(www\.)?(youtube|dailymotion|vimeo)\.com/`i"),frameborder; div=data-mid', + 'spec' => 'iframe=-*,height,width,type,src(match="`^(https?:)?//(www\.)?(youtube|dailymotion|vimeo)\.com/`i"),frameborder; div=data-mid'.($spec ? '; '.$spec : ''), ); return Format::html($html, $config); @@ -265,10 +232,10 @@ class Format { 'src="cid:$1', $text); } - function sanitize($text, $striptags=false) { + function sanitize($text, $striptags=false, $spec=false) { //balance and neutralize unsafe tags. - $text = Format::safe_html($text); + $text = Format::safe_html($text, $spec); $text = self::localizeInlineImages($text); @@ -410,10 +377,19 @@ class Format { function viewableImages($html, $script=false) { + $cids = $images = array(); + // Try and get information for all the files in one query + if (preg_match_all('/"cid:([\w._-]{32})"/', $html, $cids)) { + foreach (AttachmentFile::objects() + ->filter(array('key__in' => $cids[1])) + as $file + ) { + $images[strtolower($file->getKey())] = $file; + } + } return preg_replace_callback('/"cid:([\w._-]{32})"/', - function($match) use ($script) { - $hash = $match[1]; - if (!($file = AttachmentFile::lookup($hash))) + function($match) use ($script, $images) { + if (!($file = $images[strtolower($match[1])])) return $match[0]; return sprintf('"%s" data-cid="%s"', $file->getDownloadUrl(false, 'inline', $script), $match[1]); @@ -670,7 +646,7 @@ class Format { $contents = base64_decode($contents); } if ($output_encoding && $charset) - $contents = Format::encode($contents, $charset, $output_encoding); + $contents = Charset::transcode($contents, $charset, $output_encoding); return array( 'data' => $contents, diff --git a/include/class.forms.php b/include/class.forms.php index dfccf962c5d1e307fec038fd028f400c889de122..3345669da755517199ec6a29d75ac76d8aa0147d 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -761,17 +761,6 @@ class FormField { return null; } - /** - * Indicates if the field provides for searching for something other - * than keywords. For instance, textbox fields can have hits by keyword - * searches alone, but selection fields should provide the option to - * match a specific value or set of values and therefore need to - * participate on any search builder. - */ - function hasSpecialSearch() { - return true; - } - function getConfigurationForm($source=null) { if (!$this->_cform) { $type = static::getFieldType($this->get('type')); @@ -880,10 +869,6 @@ class TextboxField extends FormField { ); } - function hasSpecialSearch() { - return false; - } - function validateEntry($value) { parent::validateEntry($value); $config = $this->getConfiguration(); @@ -955,10 +940,6 @@ class TextareaField extends FormField { ); } - function hasSpecialSearch() { - return false; - } - function display($value) { $config = $this->getConfiguration(); if ($config['html']) @@ -1011,10 +992,6 @@ class PhoneField extends FormField { ); } - function hasSpecialSearch() { - return false; - } - function validateEntry($value) { parent::validateEntry($value); $config = $this->getConfiguration(); @@ -1447,9 +1424,6 @@ class ThreadEntryField extends FormField { function isPresentationOnly() { return true; } - function hasSpecialSearch() { - return false; - } function getConfigurationOptions() { global $cfg; @@ -1904,10 +1878,6 @@ class FileUploadField extends FormField { ); } - function hasSpecialSearch() { - return false; - } - /** * Called from the ajax handler for async uploads via web clients. */ @@ -1929,10 +1899,10 @@ class FileUploadField extends FormField { if (!$bypass && $file['size'] > $config['size']) Http::response(413, 'File is too large'); - if (!($id = AttachmentFile::upload($file))) + if (!($F = AttachmentFile::upload($file))) Http::response(500, 'Unable to store file: '. $file['error']); - return $id; + return $F->getId(); } /** @@ -1972,10 +1942,10 @@ class FileUploadField extends FormField { if ($file['size'] > $config['size']) throw new FileUploadError(__('File size is too large')); - if (!$id = AttachmentFile::save($file)) + if (!$F = AttachmentFile::create($file)) throw new FileUploadError(__('Unable to save file')); - return $id; + return $F; } function isValidFileType($name, $type=false) { @@ -2718,7 +2688,8 @@ class FileUploadWidget extends Widget { if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES[$this->name])) { foreach (AttachmentFile::format($_FILES[$this->name]) as $file) { try { - $ids[] = $this->field->uploadFile($file); + $F = $this->field->uploadFile($file); + $ids[] = $F->getId(); } catch (FileUploadError $ex) {} } diff --git a/include/class.group.php b/include/class.group.php index 3bbf296f5ecbfaf2173311ac1f23a4124b31746b..24e955f7ce28bffb5e9b804544a65436f96d753a 100644 --- a/include/class.group.php +++ b/include/class.group.php @@ -90,7 +90,7 @@ class Group extends VerySimpleModel { } function isEnabled() { - $this->get('flags') & self::FLAG_ENABLED !== 0; + return ($this->get('flags') & self::FLAG_ENABLED !== 0); } function isActive(){ diff --git a/include/class.i18n.php b/include/class.i18n.php index 4b764717a82cdc7a51651f7f6eb3bc6f11c8d333..e0fcd9e11b9d864f66326bd9735abb244dfcd77a 100644 --- a/include/class.i18n.php +++ b/include/class.i18n.php @@ -382,6 +382,8 @@ class Internationalization { static function getCurrentLocale() { global $thisstaff, $cfg; + // FIXME: Move this majic elsewhere - see upgrade bug note in + // class.staff.php if ($thisstaff) { return $thisstaff->getLocale() ?: self::getCurrentLanguage(); diff --git a/include/class.list.php b/include/class.list.php index f8b457fb8e371bffc1deeb1c7886494964286a0f..5f4ce5aeac6ebb60037dcc1f80807d3ac6a9d336 100644 --- a/include/class.list.php +++ b/include/class.list.php @@ -741,6 +741,15 @@ class DynamicListItem extends VerySimpleModel implements CustomListItem { } } + function getFilterData() { + $data = array(); + foreach ($this->getConfigurationForm()->getFields() as $F) { + $data['.'.$F->get('id')] = $F->toString($F->value); + } + $data['.abb'] = (string) $this->get('extra'); + return $data; + } + function getTranslateTag($subtag) { return _H(sprintf('listitem.%s.%s', $subtag, $this->id)); } diff --git a/include/class.lock.php b/include/class.lock.php index 6e0588978e29b71d125b0602388923b50edc6898..e4870d4652801659d68e6c77bc6d231991f378ea 100644 --- a/include/class.lock.php +++ b/include/class.lock.php @@ -18,14 +18,19 @@ * Mainly used as a helper... */ -class TicketLock extends VerySimpleModel { +class Lock extends VerySimpleModel { static $meta = array( - 'table' => TICKET_LOCK_TABLE, + 'table' => LOCK_TABLE, 'pk' => array('lock_id'), 'joins' => array( 'ticket' => array( - 'constraint' => array('ticket_id' => 'TicketModel.ticket_id'), + 'reverse' => 'TicketModel.lock', + 'list' => false, + ), + 'task' => array( + 'reverse' => 'Task.lock', + 'list' => false, ), 'staff' => array( 'constraint' => array('staff_id' => 'Staff.staff_id'), @@ -69,6 +74,10 @@ class TicketLock extends VerySimpleModel { return (time()>$this->expiretime); } + function getCode() { + return $this->code; + } + //Renew existing lock. function renew($lockTime=0) { global $cfg; @@ -89,58 +98,55 @@ class TicketLock extends VerySimpleModel { } /* ----------------------- Static functions ---------------------------*/ - static function lookup($id, $tid=false) { - if ($tid) - return parent::lookup(array('lock_id' => $id, 'ticket_id' => $tid)); + static function lookup($id, $object=false) { + if ($object instanceof Ticket) + return parent::lookup(array('lock_id' => $id, 'ticket__ticket_id' => $object->getId())); + elseif ($object instanceof Task) + return parent::lookup(array('lock_id' => $id, 'task__id' => $object->getId())); else return parent::lookup($id); } //Create a ticket lock...this function assumes the caller checked for access & validity of ticket & staff x-ship. - static function acquire($ticketId, $staffId, $lockTime) { + static function acquire($staffId, $lockTime) { - if (!$ticketId or !$staffId or !$lockTime) - return 0; - - // Cleanup any expired locks on the ticket. - static::objects()->filter(array( - 'ticket_id' => $ticketId, - 'expire__lt' => SqlFunction::NOW() - ))->delete(); + if (!$staffId or !$lockTime) + return null; // Create the new lock. $lock = parent::create(array( 'created' => SqlFunction::NOW(), - 'ticket_id' => $ticketId, 'staff_id' => $staffId, 'expire' => SqlExpression::plus( SqlFunction::NOW(), SqlInterval::MINUTE($lockTime) ), + 'code' => Misc::randCode(10) )); if ($lock->save(true)) return $lock; } - static function create($ticketId, $staffId, $lockTime) { - if ($lock = self::acquire($ticketId, $staffId, $lockTime)) + static function create($staffId, $lockTime) { + if ($lock = self::acquire($staffId, $lockTime)) return $lock; } // Simply remove ALL locks a user (staff) holds on a ticket(s). - static function removeStaffLocks($staffId, $ticketId=0) { + static function removeStaffLocks($staffId, $object=false) { $locks = static::objects()->filter(array( 'staff_id' => $staffId, )); - if ($ticketId) - $locks->filter(array('ticket_id' => $ticketId)); + if ($object instanceof Ticket) + $locks->filter(array('ticket__ticket_id' => $object->getId())); + elseif ($object instanceof Task) + $locks->filter(array('task__id' => $object->getId())); return $locks->delete(); } - // Called via cron static function cleanup() { - static::objects()->filter(array( + return static::objects()->filter(array( 'expire__lt' => SqlFunction::NOW() ))->delete(); } diff --git a/include/class.mailer.php b/include/class.mailer.php index a3093c203a14eac9f8e7a2082830f715352b2128..b5d759cb43801c662bac5a96049cf0a402984772 100644 --- a/include/class.mailer.php +++ b/include/class.mailer.php @@ -79,15 +79,200 @@ class Mailer { return $this->attachments; } - function addAttachment($attachment) { + function addAttachment(Attachment $attachment) { // XXX: This looks too assuming; however, the attachment processor // in the ::send() method seems hard coded to expect this format - $this->attachments[$attachment['file_id']] = $attachment; + $this->attachments[$attachment->file_id] = $attachment->file; + } + + function addFile(AttachmentFile $file) { + // XXX: This looks too assuming; however, the attachment processor + // in the ::send() method seems hard coded to expect this format + $this->attachments[$file->file_id] = $file; } function addAttachments($attachments) { - foreach ($attachments as $a) - $this->addAttachment($a); + foreach ($attachments as $a) { + if ($a instanceof Attachment) + $this->addAttachment($a); + elseif ($a instanceof AttachmentFile) + $this->addFile($a); + } + } + + /** + * getMessageId + * + * Generates a unique message ID for an outbound message. Optionally, + * the recipient can be used to create a tag for the message ID where + * the user-id and thread-entry-id are encoded in the message-id so + * the message can be threaded if it is replied to without any other + * indicator of the thread to which it belongs. This tag is signed with + * the secret-salt of the installation to guard against false positives. + * + * Parameters: + * $recipient - (EmailContact|null) recipient of the message. The ID of + * the recipient is placed in the message id TAG section so it can + * be recovered if the email replied to directly by the end user. + * $options - (array) - options passed to ::send(). If it includes a + * 'thread' element, the threadId will be recorded in the TAG + * + * Returns: + * (string) - email message id, without leading and trailing <> chars. + * See the Format below for the structure. + * + * Format: + * VA-B-C, with dash separators and A-C explained below: + * + * V: Version code of the generated Message-Id + * A: Predictable random code — used for loop detection (sysid) + * B: Random data for unique identifier (rand) + * C: TAG: Base64(Pack(userid, entryId, threadId, type, Signature)), + * '=' chars discarded + * where Signature is: + * Signed Tag value, last 5 chars from + * HMAC(sha1, Tag + rand + sysid, SECRET_SALT), + * where Tag is: + * pack(userId, entryId, threadId, type) + */ + function getMessageId($recipient, $options=array(), $version='B') { + $tag = ''; + $rand = Misc::randCode(5, + // RFC822 specifies the LHS of the addr-spec can have any char + // except the specials — ()<>@,;:\".[], dash is reserved as the + // section separator, and + is reserved for historical reasons + 'abcdefghiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_='); + $sig = $this->getEmail()?$this->getEmail()->getEmail():'@osTicketMailer'; + $sysid = static::getSystemMessageIdCode(); + // Create a tag for the outbound email + $entry = (isset($options['thread']) && $options['thread'] instanceof ThreadEntry) + ? $options['thread'] : false; + $thread = $entry ? $entry->getThread() + : (isset($options['thread']) && $options['thread'] instanceof Thread + ? $options['thread'] : false); + $tag = pack('VVVa', + $recipient instanceof EmailContact ? $recipient->getUserId() : 0, + $entry ? $entry->getId() : 0, + $thread ? $thread->getId() : 0, + ($recipient instanceof Staff ? 'S' + : ($recipient instanceof TicketOwner ? 'U' + : ($recipient instanceof Collaborator ? 'C' + : '?'))) + ); + // Sign the tag with the system secret salt + $tag .= substr(hash_hmac('sha1', $tag.$rand.$sysid, SECRET_SALT, true), -5); + $tag = str_replace('=','',base64_encode($tag)); + return sprintf('B%s-%s-%s-%s', + $sysid, $rand, $tag, $sig); + } + + /** + * decodeMessageId + * + * Decodes a message-id generated by osTicket using the ::getMessageId() + * method of this class. This will digest the received message-id token + * and return an array with some information about it. + * + * Parameters: + * $mid - (string) message-id from an email Message-Id, In-Reply-To, and + * References header. + * + * Returns: + * (array) of information containing all or some of the following keys + * 'loopback' - (bool) true or false if the message originated by + * this osTicket installation. + * 'version' - (string|FALSE) version code of the message id + * 'code' - (string) unique but predictable help desk message-id + * 'id' - (string) random characters serving as the unique id + * 'entryId' - (int) thread-entry-id from which the message originated + * 'threadId' - (int) thread-id from which the message originated + * 'staffId' - (int|null) staff the email was originally sent to + * 'userId' - (int|null) user the email was originally sent to + * 'userClass' - (string) class of user the email was sent to + * 'U' - TicketOwner + * 'S' - Staff + * 'C' - Collborator + * '?' - Something else + */ + static function decodeMessageId($mid) { + // Drop <> tokens + $mid = trim($mid, '<> '); + // Drop email domain on rhs + list($lhs, $sig) = explode('@', $mid, 2); + // LHS should be tokenized by '-' + $parts = explode('-', $lhs); + + $rv = array('loopback' => false, 'version' => false); + + // There should be at least two tokens if the message was sent by + // this system. Otherwise, there's nothing to be detected + if (count($parts) < 2) + return $rv; + + $decoders = array( + 'A' => function($id, $tag) use ($sig) { + // Old format was VA-B-C-D@sig, where C was the packed tag and D + // was blank + $format = 'Vuid/VentryId/auserClass'; + $chksig = substr(hash_hmac('sha1', $tag.$id, SECRET_SALT), -10); + if ($tag && $sig == $chksig && ($tag = base64_decode($tag))) { + // Find user and ticket id + return unpack($format, $tag); + } + return false; + }, + 'B' => function($id, $tag) { + $format = 'Vuid/VentryId/VthreadId/auserClass/a*sig'; + if ($tag && ($tag = base64_decode($tag))) { + $info = unpack($format, $tag); + $sysid = static::getSystemMessageIdCode(); + $shorttag = substr($tag, 0, 13); + $chksig = substr(hash_hmac('sha1', $shorttag.$id.$sysid, + SECRET_SALT, true), -5); + if ($chksig == $info['sig']) { + return $info; + } + } + return false; + }, + ); + + // Detect the MessageId version, which should be the first char + $rv['version'] = @$parts[0][0]; + if (!isset($decoders[$rv['version']])) + // invalid version code + return null; + + // Drop the leading version code + list($rv['code'], $rv['id'], $tag) = $parts; + $rv['code'] = substr($rv['code'], 1); + + // Verify tag signature and unpack the tag + $info = $decoders[$rv['version']]($rv['id'], $tag); + if ($info === false) + return $rv; + + $rv += $info; + + // Attempt to make the user-id more specific + $classes = array( + 'S' => 'staffId', 'U' => 'userId', 'C' => 'userId', + ); + if (isset($classes[$rv['userClass']])) + $rv[$classes[$rv['userClass']]] = $rv['uid']; + + // Round-trip detection - the first section is the local + // system's message-id code + $rv['loopback'] = (0 === strcasecmp($rv['code'], + static::getSystemMessageIdCode())); + + return $rv; + } + + static function getSystemMessageIdCode() { + return substr(str_replace('+', '=', + base64_encode(md5('mail'.SECRET_SALT, true))), + 0, 6); } function send($to, $subject, $message, $options=null) { @@ -97,22 +282,30 @@ class Mailer { require_once (PEAR_DIR.'Mail.php'); // PEAR Mail package require_once (PEAR_DIR.'Mail/mime.php'); // PEAR Mail_Mime packge + $messageId = $this->getMessageId($to, $options); + + if (is_object($to) && is_callable(array($to, 'getEmail'))) { + // Add personal name if available + if (is_callable(array($to, 'getName'))) { + $to = sprintf('"%s" <%s>', + $to->getName()->getOriginal(), $to->getEmail() + ); + } + else { + $to = $to->getEmail(); + } + } + //do some cleanup $to = preg_replace("/(\r\n|\r|\n)/s",'', trim($to)); $subject = preg_replace("/(\r\n|\r|\n)/s",'', trim($subject)); - /* Message ID - generated for each outgoing email */ - $messageId = sprintf('<%s-%s-%s>', - substr(md5('mail'.SECRET_SALT), -9), - Misc::randCode(9), - ($this->getEmail()?$this->getEmail()->getEmail():'@osTicketMailer')); - $headers = array ( 'From' => $this->getFromAddress(), 'To' => $to, 'Subject' => $subject, 'Date'=> date('D, d M Y H:i:s O'), - 'Message-ID' => $messageId, + 'Message-ID' => "<{$messageId}>", 'X-Mailer' =>'osTicket Mailer', ); @@ -155,6 +348,27 @@ class Mailer { } } + // Make the best effort to add In-Reply-To and References headers + if (isset($options['thread']) + && $options['thread'] instanceof ThreadEntry + ) { + if ($references = $options['thread']->getEmailReferences()) + $headers += array('References' => $references); + if ($irt = $options['thread']->getEmailMessageId()) { + // This is an response from an email, like and autoresponse. + // Web posts will not have a email message-id + $headers += array('In-Reply-To' => $irt); + } + elseif ($parent = $options['thread']->getParent()) { + // Use the parent item as the email information source. This + // will apply for staff replies + $headers += array( + 'In-Reply-To' => $parent->getEmailMessageId(), + 'References' => $parent->getEmailReferences(), + ); + } + } + // Use Mail_mime default initially $eol = null; @@ -180,17 +394,16 @@ class Mailer { // then assume that it needs html processing to create a valid text // body $isHtml = true; - $mid_token = (isset($options['thread'])) - ? $options['thread']->asMessageId($to) : ''; if (!(isset($options['text']) && $options['text'])) { $tag = ''; if ($cfg && $cfg->stripQuotedReply() && (!isset($options['reply-tag']) || $options['reply-tag'])) - $tag = $cfg->getReplySeparator() . '<br/><br/>'; - $message = "<div style=\"display:none\" - data-mid=\"$mid_token\">$tag</div>$message"; + $tag = '<div>'.$cfg->getReplySeparator() . '<br/><br/></div>'; + // Embed the data-mid in such a way that it should be included + // in a response + $message = "<div data-mid=\"$messageId\">{$tag}{$message}</div>"; $txtbody = rtrim(Format::html2text($message, 90, false)) - . ($mid_token ? "\nRef-Mid: $mid_token\n" : ''); + . ($messageId ? "\nRef-Mid: $messageId\n" : ''); $mime->setTXTBody($txtbody); } else { @@ -211,7 +424,14 @@ class Mailer { $self = $this; $message = preg_replace_callback('/cid:([\w.-]{32})/', function($match) use ($domain, $mime, $self) { - if (!($file = AttachmentFile::lookup($match[1]))) + $file = false; + foreach ($self->attachments as $id=>$F) { + if (strcasecmp($F->getKey(), $match[1]) === 0) { + $file = $F; + break; + } + } + if (!$file) return $match[0]; $mime->addHTMLImage($file->getData(), $file->getType(), $file->getName(), false, @@ -225,12 +445,9 @@ class Mailer { } //XXX: Attachments if(($attachments=$this->getAttachments())) { - foreach($attachments as $attachment) { - if ($attachment['file_id'] - && ($file=AttachmentFile::lookup($attachment['file_id']))) { - $mime->addAttachment($file->getData(), - $file->getType(), $file->getName(),false); - } + foreach($attachments as $id=>$file) { + $mime->addAttachment($file->getData(), + $file->getType(), $file->getName(),false); } } diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php index 77725c0729e9100733aacfc3c6d58feebb64d032..db9026228caa6f024c57c43f906fce5cae683eab 100644 --- a/include/class.mailfetch.php +++ b/include/class.mailfetch.php @@ -19,6 +19,7 @@ require_once(INCLUDE_DIR.'class.ticket.php'); require_once(INCLUDE_DIR.'class.dept.php'); require_once(INCLUDE_DIR.'class.email.php'); require_once(INCLUDE_DIR.'class.filter.php'); +require_once(INCLUDE_DIR.'class.banlist.php'); require_once(INCLUDE_DIR.'tnef_decoder.php'); class MailFetcher { @@ -206,7 +207,7 @@ class MailFetcher { //Convert text to desired encoding..defaults to utf8 function mime_encode($text, $charset=null, $encoding='utf-8') { //Thank in part to afterburner - return Format::encode($text, $charset, $encoding); + return Charset::transcode($text, $charset, $encoding); } function mailbox_encode($mailbox) { @@ -240,7 +241,7 @@ class MailFetcher { if (function_exists('mb_detect_encoding')) if (($src_enc = mb_detect_encoding($text)) && (strcasecmp($src_enc, 'ASCII') !== 0)) - return Format::encode($text, $src_enc, $encoding); + return Charset::transcode($text, $src_enc, $encoding); // Handle ASCII text and RFC-2047 encoding $str = ''; @@ -600,7 +601,7 @@ class MailFetcher { } //Is the email address banned? - if($mailinfo['email'] && TicketFilter::isBanned($mailinfo['email'])) { + if($mailinfo['email'] && Banlist::isBanned($mailinfo['email'])) { //We need to let admin know... $ost->logWarning(_S('Ticket denied'), sprintf(_S('Banned email — %s'),$mailinfo['email']), false); @@ -720,23 +721,31 @@ class MailFetcher { Signal::send('mail.processed', $this, $vars); $seen = false; - if (($thread = ThreadEntry::lookupByEmailHeaders($vars, $seen)) - && ($t=$thread->getTicket()) - && ($vars['staffId'] - || !$t->isClosed() - || $t->isReopenable()) - && ($message = $thread->postEmail($vars))) { + if (($entry = ThreadEntry::lookupByEmailHeaders($vars, $seen)) + && ($message = $entry->postEmail($vars)) + ) { if (!$message instanceof ThreadEntry) // Email has been processed previously return $message; - $ticket = $message->getTicket(); - } elseif ($seen) { + // NOTE: This might not be a "ticket" + $ticket = $message->getThread()->getObject(); + } + elseif ($seen) { // Already processed, but for some reason (like rejection), no // thread item was created. Ignore the email return true; - } elseif (($ticket=Ticket::create($vars, $errors, 'Email'))) { + } + // Allow continuation of thread without initial message or note + elseif (($thread = Thread::lookupByEmailHeaders($vars)) + && ($message = $entry->postEmail($vars)) + ) { + // NOTE: This might not be a "ticket" + $ticket = $thread->getObject(); + } + elseif (($ticket=Ticket::create($vars, $errors, 'Email'))) { $message = $ticket->getLastMessage(); - } else { + } + else { //Report success if the email was absolutely rejected. if(isset($errors['errno']) && $errors['errno'] == 403) { // Never process this email again! diff --git a/include/class.mailparse.php b/include/class.mailparse.php index c2b51d7f07b46523bebc22292388d8bc494ecc62..5c9cdf4d636fd04b4cdb4d894ca06b036eae8b37 100644 --- a/include/class.mailparse.php +++ b/include/class.mailparse.php @@ -335,7 +335,7 @@ class Mail_Parse { $content = $struct->body; //Encode to desired encoding - ONLY if charset is known?? if (isset($struct->ctype_parameters['charset'])) - $content = Format::encode($content, + $content = Charset::transcode($content, $struct->ctype_parameters['charset'], $this->charset); return $content; @@ -358,7 +358,7 @@ class Mail_Parse { function mime_encode($text, $charset=null, $encoding='utf-8') { - return Format::encode($text, $charset, $encoding); + return Charset::transcode($text, $charset, $encoding); } function getAttachments($part=null){ diff --git a/include/class.misc.php b/include/class.misc.php index b515507c8610a30448ff10cb7246128360d672c9..eba8ced024af3a5fbbc6a795d73f077223a67731 100644 --- a/include/class.misc.php +++ b/include/class.misc.php @@ -16,14 +16,30 @@ class Misc { - function randCode($count=8, $chars=false) { - $chars = $chars ? $chars - : 'abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.'; - $data = ''; - $m = strlen($chars) - 1; - for ($i=0; $i < $count; $i++) - $data .= $chars[mt_rand(0,$m)]; - return $data; + function randCode($len=8, $chars=false) { + $chars = $chars ?: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_='; + + // Determine the number of bits we need + $char_count = strlen($chars); + $bits_per_char = ceil(log($char_count, 2)); + $bytes = ceil(4 * $len / floor(32 / $bits_per_char)); + // Pad to 4 byte boundary + $bytes += (4 - ($bytes % 4)) % 4; + + // Fetch some random data blocks + $data = Crypto::random($bytes); + + $mask = (1 << $bits_per_char) - 1; + $loops = (int) (32 / $bits_per_char); + $output = ''; + $ints = unpack('V*', $data); + foreach ($ints as $int) { + for ($i = $loops; $i > 0; $i--) { + $output .= $chars[($int & $mask) % $char_count]; + $int >>= $bits_per_char; + } + } + return substr($output, 0, $len); } function __rand_seed($value=0) { diff --git a/include/class.organization.php b/include/class.organization.php index fbaa19df50dd8328b900e2c235421a3148862c15..e13329507aba063361ad6cd834554f89b37f18cd 100644 --- a/include/class.organization.php +++ b/include/class.organization.php @@ -370,6 +370,7 @@ class Organization extends OrganizationModel { $org->addDynamicData($vars); } + Signal::send('organization.created', $org); return $org; } diff --git a/include/class.orm.php b/include/class.orm.php index 110e0d68268c39ad0241eca768b578c61b3d56c9..c004ab455bd3c43252cdcb42947b78aaf2c1befe 100644 --- a/include/class.orm.php +++ b/include/class.orm.php @@ -92,10 +92,13 @@ class ModelMeta implements ArrayAccess { $j['null'] = true; } // XXX: Make this better (ie. composite keys) - $keys = array_keys($j['constraint']); - $foreign = $j['constraint'][$keys[0]]; - $j['fkey'] = explode('.', $foreign); - $j['local'] = $keys[0]; + foreach ($j['constraint'] as $local => $foreign) { + list($class, $field) = explode('.', $foreign); + if ($local[0] == "'" || $field[0] == "'" || !class_exists($class)) + continue; + $j['fkey'] = array($class, $field); + $j['local'] = $local; + } } function offsetGet($field) { @@ -173,12 +176,25 @@ class VerySimpleModel { return $v; } // Support relationships - elseif (isset($j['fkey']) - && ($class = $j['fkey'][0]) - && class_exists($class)) { + elseif (isset($j['fkey'])) { + $criteria = array(); + foreach ($j['constraint'] as $local => $foreign) { + list($klas,$F) = explode('.', $foreign); + if (class_exists($klas)) + $class = $klas; + if ($local[0] == "'") { + $criteria[$F] = trim($local,"'"); + } + elseif ($foreign[0] == "'") { + // Does not affect the local model + continue; + } + else { + $criteria[$F] = $this->ht[$local]; + } + } try { - $v = $this->ht[$field] = $class::lookup( - array($j['fkey'][1] => $this->ht[$j['local']])); + $v = $this->ht[$field] = $class::lookup($criteria); } catch (DoesNotExist $e) { $v = null; @@ -189,6 +205,7 @@ class VerySimpleModel { elseif (isset($this->__deferred__[$field])) { // Fetch deferred field $row = static::objects()->filter($this->getPk()) + // XXX: Seems like all the deferred fields should be fetched ->values_flat($field) ->one(); if ($row) @@ -256,8 +273,8 @@ class VerySimpleModel { // replaced in the dirty array if (!array_key_exists($field, $this->dirty)) $this->dirty[$field] = $old; - $this->ht[$field] = $value; } + $this->ht[$field] = $value; } function __set($field, $value) { return $this->set($field, $value); @@ -324,10 +341,13 @@ class VerySimpleModel { $criteria = array(); foreach (func_get_args() as $i=>$f) $criteria[static::$meta['pk'][$i]] = $f; + + // Only consult cache for PK lookup, which is assumed if the + // values are passed as args rather than an array + if ($cached = ModelInstanceManager::checkCache(get_called_class(), + $criteria)) + return $cached; } - if ($cached = ModelInstanceManager::checkCache(get_called_class(), - $criteria)) - return $cached; try { return static::objects()->filter($criteria)->one(); } @@ -361,8 +381,17 @@ class VerySimpleModel { $ex = DbEngine::save($this); try { $ex->execute(); - if ($ex->affected_rows() != 1) - return false; + if ($ex->affected_rows() != 1) { + // This doesn't really signify an error. It just means that + // the database believe that the row did not change. For + // inserts though, it's a deal breaker + if ($this->__new__) + return false; + else + // No need to reload the record if requested — the + // database didn't update anything + $refetch = false; + } } catch (OrmException $e) { return false; @@ -388,7 +417,8 @@ class VerySimpleModel { // Uncache so that the lookup will not be short-cirtuited to // return this object ModelInstanceManager::uncache($this); - $self = static::lookup($this->get('pk')); + $self = call_user_func_array(array(get_class($this), 'lookup'), + $this->get('pk')); $this->ht = $self->ht; } if ($wasnew) @@ -454,9 +484,6 @@ class AnnotatedModel { function __call($what, $how) { return call_user_func_array(array($this->model, $what), $how); } - static function __callStatic($what, $how) { - return call_user_func_array(array($this->model, $what), $how); - } } class SqlFunction { @@ -651,7 +678,7 @@ class SqlAggregate extends SqlFunction { } } -class QuerySet implements IteratorAggregate, ArrayAccess, Serializable { +class QuerySet implements IteratorAggregate, ArrayAccess, Serializable, Countable { var $model; var $constraints = array(); @@ -674,6 +701,7 @@ class QuerySet implements IteratorAggregate, ArrayAccess, Serializable { var $params; var $query; + var $count; function __construct($model) { $this->model = $model; @@ -798,9 +826,16 @@ class QuerySet implements IteratorAggregate, ArrayAccess, Serializable { } function count() { + // Defer to the iterator if fetching already started + if (isset($this->_iterator)) { + return $this->_iterator->count(); + } + elseif (isset($this->_count)) { + return $this->_count; + } $class = $this->compiler; $compiler = new $class(); - return $compiler->compileCount($this); + return $this->_count = $compiler->compileCount($this); } /** @@ -930,7 +965,7 @@ class QuerySet implements IteratorAggregate, ArrayAccess, Serializable { class DoesNotExist extends Exception {} class ObjectNotUnique extends Exception {} -abstract class ResultSet implements Iterator, ArrayAccess { +abstract class ResultSet implements Iterator, ArrayAccess, Countable { var $resource; var $position = 0; var $queryset; @@ -985,6 +1020,11 @@ abstract class ResultSet implements Iterator, ArrayAccess { function offsetSet($a, $b) { throw new Exception(sprintf(__('%s is read-only'), get_class($this))); } + + // Countable interface + function count() { + return count($this->asArray()); + } } class ModelInstanceManager extends ResultSet { @@ -1688,7 +1728,6 @@ class MySqlCompiler extends SqlCompiler { // Support local constraint // field_name => "'constant'" elseif ($foreign[0] == "'" && !$right) { - die(); $constraints[] = sprintf("%s.%s = %s", $table, $this->quote($local), $this->input(trim($foreign, '\'"'), self::SLOT_JOINS) @@ -1741,7 +1780,7 @@ class MySqlCompiler extends SqlCompiler { elseif ($what instanceof SqlFunction) { return $what->toSql($this); } - elseif ($what === null) { + elseif (!isset($what)) { return 'NULL'; } else { @@ -1839,6 +1878,7 @@ class MySqlCompiler extends SqlCompiler { // Compile the field listing $fields = array(); + $group_by = array(); $table = $this->quote($model::$meta['table']).' '.$rootAlias; // Handle related tables if ($queryset->related) { @@ -1890,6 +1930,7 @@ class MySqlCompiler extends SqlCompiler { elseif ($queryset->values) { foreach ($queryset->values as $alias=>$v) { list($f) = $this->getField($v, $model); + $unaliased = $f; if ($f instanceof SqlFunction) $fields[$f->toSql($this, $model, $alias)] = true; else { @@ -1897,6 +1938,10 @@ class MySqlCompiler extends SqlCompiler { $f .= ' AS '.$this->quote($alias); $fields[$f] = true; } + // If there are annotations, add in these fields to the + // GROUP BY clause + if ($queryset->annotations) + $group_by[] = $unaliased; } } // Simple selection from one table @@ -1914,7 +1959,6 @@ class MySqlCompiler extends SqlCompiler { } } $fields = array_keys($fields); - $group_by = array(); // Add in annotations if ($queryset->annotations) { foreach ($queryset->annotations as $alias=>$A) { @@ -1930,8 +1974,11 @@ class MySqlCompiler extends SqlCompiler { $fields[] = $T; } } - foreach ($model::$meta['pk'] as $pk) - $group_by[] = $rootAlias .'.'. $pk; + // If no group by has been set yet, use the root model pk + if (!$group_by) { + foreach ($model::$meta['pk'] as $pk) + $group_by[] = $rootAlias .'.'. $pk; + } } // Add in SELECT extras if (isset($queryset->extra['select'])) { @@ -2029,7 +2076,7 @@ class MySqlCompiler extends SqlCompiler { $set = implode(', ', $set); list($where, $having) = $this->getWhereHavingClause($queryset); $joins = $this->getJoins($queryset); - $sql = 'UPDATE '.$this->quote($table).' SET '.$set.$joins.$where; + $sql = 'UPDATE '.$this->quote($table).$joins.' SET '.$set.$where; return new MysqlExecutor($sql, $this->params); } @@ -2105,6 +2152,10 @@ class MysqlExecutor { $types .= 'd'; elseif (is_string($p)) $types .= 's'; + elseif ($p instanceof DateTime) { + $types .= 's'; + $p = $p->format('Y-m-d h:i:s'); + } // TODO: Emit error if param is null $ps[] = &$p; } diff --git a/include/class.ostsession.php b/include/class.ostsession.php index 94df679d2792046fda2b7373e598851f147a501b..b300f16ec7a826443e3e1fb52530a7c88bd6486b 100644 --- a/include/class.ostsession.php +++ b/include/class.ostsession.php @@ -69,6 +69,23 @@ class osTicketSession { $this->destroy($oldId); } + static function destroyCookie() { + setcookie(session_name(), 'deleted', 1, + ini_get('session.cookie_path'), + ini_get('session.cookie_domain'), + ini_get('session.cookie_secure'), + ini_get('session.cookie_httponly')); + } + + static function renewCookie($baseTime=false, $window=false) { + setcookie(session_name(), session_id(), + ($baseTime ?: time()) + ($window ?: SESSION_TTL), + ini_get('session.cookie_path'), + ini_get('session.cookie_domain'), + ini_get('session.cookie_secure'), + ini_get('session.cookie_httponly')); + } + function open($save_path, $session_name){ return (true); } diff --git a/include/class.page.php b/include/class.page.php index 7e7d8d7898bc347e7232ca1b1b73439fba3c4188..e55df9d728484beb9fa0661a6e6bce5688e91ab1 100644 --- a/include/class.page.php +++ b/include/class.page.php @@ -237,6 +237,9 @@ class Page extends VerySimpleModel { catch (DoesNotExist $ex) { return null; } + catch (InconsistentModelException $ex) { + return null; + } } function update($vars, &$errors) { diff --git a/include/class.search.php b/include/class.search.php index 538aa7fddf51f48650c9a8ed114c28a4ddef3b23..5436ff519333b7ff3e578703fc13672cd194ed34 100644 --- a/include/class.search.php +++ b/include/class.search.php @@ -197,7 +197,12 @@ class SearchInterface { // Tickets, which can be edited as well // Knowledgebase articles (FAQ and canned responses) // Users, organizations - Signal::connect('model.created', array($this, 'createModel')); + Signal::connect('threadentry.created', array($this, 'createModel')); + Signal::connect('ticket.created', array($this, 'createModel')); + Signal::connect('user.created', array($this, 'createModel')); + Signal::connect('organization.created', array($this, 'createModel')); + Signal::connect('model.created', array($this, 'createModel'), 'FAQ'); + Signal::connect('model.updated', array($this, 'updateModel')); #Signal::connect('model.deleted', array($this, 'deleteModel')); } diff --git a/include/class.staff.php b/include/class.staff.php index 165cce5bc2bdf7b774759cd372eb97908472adbf..955785bd885ec8c72b47540400968b87d56f4a0c 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -24,12 +24,11 @@ include_once(INCLUDE_DIR.'class.user.php'); include_once(INCLUDE_DIR.'class.auth.php'); class Staff extends VerySimpleModel -implements AuthenticatedUser { +implements AuthenticatedUser, EmailContact { static $meta = array( 'table' => STAFF_TABLE, 'pk' => array('staff_id'), - 'select_related' => array('group'), 'joins' => array( 'dept' => array( 'constraint' => array('dept_id' => 'Dept.id'), @@ -151,6 +150,13 @@ implements AuthenticatedUser { && $this->passwd_change>($cfg->getPasswdResetPeriod()*30*24*60*60)); } + function canAccess($something) { + if ($something instanceof RestrictedAccess) + return $something->checkStaffPerm($this); + + return true; + } + function isPasswdChangeDue() { return $this->isPasswdResetDue(); } @@ -166,6 +172,9 @@ implements AuthenticatedUser { function getId() { return $this->staff_id; } + function getUserId() { + return $this->getId(); + } function getEmail() { return $this->email; @@ -293,7 +302,9 @@ implements AuthenticatedUser { } function getLocale() { - return $this->locale; + //XXX: isset is required here to avoid possible crash when upgrading + // installation where locale column doesn't exist yet. + return isset($this->locale) ? $this->locale : 0; } function getRole($dept=null) { @@ -634,7 +645,7 @@ implements AuthenticatedUser { return $row ? $row[0] : 0; } - function getIdByEmail($email) { + static function getIdByEmail($email) { $row = static::objects()->filter(array('email' => $email)) ->values_flat('staff_id')->first(); return $row ? $row[0] : 0; @@ -836,4 +847,8 @@ implements AuthenticatedUser { return false; } } + +interface RestrictedAccess { + function checkStaffPerm($staff); +} ?> diff --git a/include/class.task.php b/include/class.task.php index 54da8170f882a43bc4d4935835be8ee505f051b6..eaf7ffcb9a00fae180b392fb6b42a535d8863494 100644 --- a/include/class.task.php +++ b/include/class.task.php @@ -25,6 +25,10 @@ class TaskModel extends VerySimpleModel { 'dept' => array( 'constraint' => array('dept_id' => 'Dept.id'), ), + 'lock' => array( + 'constraint' => array('lock_id' => 'Lock.lock_id'), + 'null' => true, + ), 'staff' => array( 'constraint' => array('staff_id' => 'Staff.staff_id'), 'null' => true, @@ -225,9 +229,11 @@ class Task extends TaskModel { return $this->getThread()->getEntry($id); } - function getThreadEntries($type, $order='') { - return $this->getThread()->getEntries( - array('type' => $type, 'order' => $order)); + function getThreadEntries($type=false) { + $thread = $this->getThread()->getEntries(); + if ($type && is_array($type)) + $thread->filter(array('type__in' => $type)); + return $thread; } function getForm() { @@ -437,7 +443,7 @@ class Task extends TaskModel { // Create a thread + message. $thread = TaskThread::create($task); $thread->addDescription($vars); - Signal::send('model.created', $task); + Signal::send('task.created', $task); return $task; } @@ -574,10 +580,12 @@ class TaskThread extends ObjectThread { static function create($task) { $id = is_object($task) ? $task->getId() : $task; - return parent::create(array( + $thread = parent::create(array( 'object_id' => $id, 'object_type' => ObjectModel::OBJECT_TYPE_TASK )); + if ($thread->save()) + return $thread; } } diff --git a/include/class.thread.php b/include/class.thread.php index d3abcf411210dc6154f38d09a8a68a530838f71d..e90fc095f92f4d718b0626beef1d60749c9ff485 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -17,78 +17,45 @@ include_once(INCLUDE_DIR.'class.ticket.php'); include_once(INCLUDE_DIR.'class.draft.php'); -class ThreadModel extends VerySimpleModel { +//Ticket thread. +class Thread extends VerySimpleModel { static $meta = array( 'table' => THREAD_TABLE, 'pk' => array('id'), 'joins' => array( 'ticket' => array( 'constraint' => array( - 'object_id' => 'TicketModel.ticket_id', 'object_type' => "'T'", + 'object_id' => 'TicketModel.ticket_id', ), ), + 'task' => array( + 'constraint' => array( + 'object_type' => "'A'", + 'object_id' => 'Task.id', + ), + ), + 'collaborators' => array( + 'reverse' => 'Collaborator.thread', + ), 'entries' => array( - 'reverse' => 'ThreadEntryModel.thread', + 'reverse' => 'ThreadEntry.thread', ), ), ); -} - -//Ticket thread. -class Thread { - - var $ht; - - function Thread($criteria) { - $this->load($criteria); - } - function load($criteria=null) { - - if (!$criteria && !($criteria=$this->getId())) - return null; - - $sql='SELECT thread.* ' - .' ,count(DISTINCT a.id) as attachments ' - .' ,count(DISTINCT entry.id) as entries ' - .' FROM '.THREAD_TABLE.' thread ' - .' LEFT JOIN '.THREAD_ENTRY_TABLE.' entry - ON (entry.thread_id = thread.id) ' - .' LEFT JOIN '.ATTACHMENT_TABLE.' a - ON (a.object_id=entry.id AND a.`type` = "H") '; - - if (is_numeric($criteria)) - $sql.= ' WHERE thread.id='.db_input($criteria); - else - $sql.= sprintf(' WHERE thread.object_id=%d AND - thread.object_type=%s', - $criteria['object_id'], - db_input($criteria['object_type'])); - - $sql.= ' GROUP BY thread.id'; - - $this->ht = array(); - if (($res=db_query($sql)) && db_num_rows($res)) - $this->ht = db_fetch_array($res); - - return ($this->ht); - } - - function reload() { - return $this->load(); - } + var $_object; function getId() { - return $this->ht['id']; + return $this->id; } function getObjectId() { - return $this->ht['object_id']; + return $this->object_id; } function getObjectType() { - return $this->ht['object_type']; + return $this->object_type; } function getObject() { @@ -101,190 +68,360 @@ class Thread { } function getNumAttachments() { - return $this->ht['attachments']; + return Attachment::objects()->filter(array( + 'thread_entry__thread' => $this + ))->count(); } function getNumEntries() { - return $this->ht['entries']; - } - - function getEntries($criteria) { - - if (!$criteria['order'] || !in_array($criteria['order'], array('DESC','ASC'))) - $criteria['order'] = 'ASC'; - - $sql='SELECT entry.* - , COALESCE(user.name, - IF(staff.staff_id, - CONCAT_WS(" ", staff.firstname, staff.lastname), - NULL)) as name ' - .' ,count(DISTINCT attach.id) as attachments ' - .' FROM '.THREAD_ENTRY_TABLE.' entry ' - .' LEFT JOIN '.USER_TABLE.' user - ON (entry.user_id=user.id) ' - .' LEFT JOIN '.STAFF_TABLE.' staff - ON (entry.staff_id=staff.staff_id) ' - .' LEFT JOIN '.ATTACHMENT_TABLE.' attach - ON (attach.object_id = entry.id AND attach.`type`="H") ' - .' WHERE entry.thread_id='.db_input($this->getId()); - - if ($criteria['type'] && is_array($criteria['type'])) - $sql.=' AND entry.`type` IN (' - .implode(',', db_input($criteria['type'])).')'; - elseif ($criteria['type']) - $sql.=' AND entry.`type` = '.db_input($criteria['type']); - - $sql.=' GROUP BY entry.id ' - .' ORDER BY entry.created '.$criteria['order']; - - if ($criteria['limit']) - $sql.=' LIMIT '.$criteria['limit']; - - $entries = array(); - if(($res=db_query($sql)) && db_num_rows($res)) { - while($rec=db_fetch_array($res)) { - $rec['body'] = ThreadEntryBody::fromFormattedText($rec['body'], $rec['format']); - $entries[] = $rec; - } - } + return $this->entries->count(); + } - return $entries; + function getEntries($criteria=false) { + $base = $this->entries->annotate(array( + 'has_attachments' => SqlAggregate::COUNT('attachments', false, + new Q(array('attachments__inline'=>0))) + )); + if ($criteria) + $base->filter($criteria); + return $base; } function getEntry($id) { return ThreadEntry::lookup($id, $this->getId()); } + /** + * postEmail + * + * After some security and sanity checks, attaches the body and subject + * of the message in reply to this thread item + * + * Parameters: + * mailinfo - (array) of information about the email, with at least the + * following keys + * - mid - (string) email message-id + * - name - (string) personal name of email originator + * - email - (string<email>) originating email address + * - subject - (string) email subject line (decoded) + * - body - (string) email message body (decoded) + */ + function postEmail($mailinfo) { + global $ost; - function deleteAttachments() { + // +==================+===================+=============+ + // | Orig Thread-Type | Reply Thread-Type | Requires | + // +==================+===================+=============+ + // | * | Message (M) | From: Owner | + // | * | Note (N) | From: Staff | + // | Response (R) | Message (M) | | + // | Message (M) | Response (R) | From: Staff | + // +------------------+-------------------+-------------+ + + if (!$object = $this->getObject()) { + // How should someone find this thread? + return false; + } + elseif ($object instanceof Ticket && ( + !$mailinfo['staffId'] + && $object->isClosed() + && !$object->isReopenable() + )) { + // Ticket is closed, not reopenable, and email was not submitted + // by an agent. Email cannot be submitted + return false; + } + + // Mail sent by this system will have a message-id format of + // <code-random-mailbox@domain.tld> + // where code is a predictable string based on the SECRET_SALT of + // this osTicket installation. If this incoming mail matches the + // code, then it very likely originated from this system and looped + @list($code) = explode('-', $mailinfo['mid'], 2); + if (0 === strcasecmp(ltrim($code, '<'), substr(md5('mail'.SECRET_SALT), -9))) { + // This mail was sent by this system. It was received due to + // some kind of mail delivery loop. It should not be considered + // a response to an existing thread entry + if ($ost) $ost->log(LOG_ERR, _S('Email loop detected'), sprintf( + _S('It appears as though <%s> is being used as a forwarded or fetched email account and is also being used as a user / system account. Please correct the loop or seek technical assistance.'), + $mailinfo['email']), + + // This is quite intentional -- don't continue the loop + false, + // Force the message, even if logging is disabled + true); + return true; + } + + $vars = array( + 'mid' => $mailinfo['mid'], + 'header' => $mailinfo['header'], + 'poster' => $mailinfo['name'], + 'origin' => 'Email', + 'source' => 'Email', + 'ip' => '', + 'reply_to' => $this, + 'recipients' => $mailinfo['recipients'], + 'to-email-id' => $mailinfo['to-email-id'], + ); + + // XXX: Is this necessary? + if ($object instanceof Ticket) + $vars['ticketId'] = $object->getId(); + if ($object instanceof Task) + $vars['taskId'] = $object->getId(); + + $errors = array(); + + if (isset($mailinfo['attachments'])) + $vars['attachments'] = $mailinfo['attachments']; + + $body = $mailinfo['message']; + $poster = $mailinfo['email']; + + // Disambiguate if the user happens also to be a staff member of the + // system. The current ticket owner should _always_ post messages + // instead of notes or responses + if ($mailinfo['userId'] || ( + $object instanceof Ticket + && strcasecmp($mailinfo['email'], $object->getEmail()) == 0 + )) { + $vars['message'] = $body; + $vars['userId'] = $mailinfo['userId'] ?: $object->getUserId(); + $vars['origin'] = 'Email'; + + if ($object instanceof Threadable) + return $object->postThreadEntry('M', $vars); + elseif ($this instanceof ObjectThread) + $this->addMessage($vars, $errors); + else + throw new Exception('Cannot continue discussion with abstract thread'); + } + // XXX: Consider collaborator role + elseif ($mailinfo['staffId'] + || ($mailinfo['staffId'] = Staff::getIdByEmail($mailinfo['email']))) { + $vars['staffId'] = $mailinfo['staffId']; + $vars['poster'] = Staff::lookup($mailinfo['staffId']); + $vars['note'] = $body; + + if ($object instanceof Threadable) + return $object->postThreadEntry('N', $vars); + elseif ($this instanceof ObjectThread) + return $this->addNote($vars, $errors); + else + throw new Exception('Cannot continue discussion with abstract thread'); + } + elseif (Email::getIdByEmail($mailinfo['email'])) { + // Don't process the email -- it came FROM this system + return true; + } + // Support the mail parsing system declaring a thread-type + elseif (isset($mailinfo['thread-type'])) { + switch ($mailinfo['thread-type']) { + case 'N': + $vars['note'] = $body; + $vars['poster'] = $poster; + if ($object instanceof Threadable) + return $object->postThreadEntry('N', $vars); + elseif ($this instanceof ObjectThread) + return $this->addNote($vars, $errors); + else + throw new Exception('Cannot continue discussion with abstract thread'); + } + } + // TODO: Consider security constraints + else { + //XXX: Are we potentially leaking the email address to + // collaborators? + // Try not to destroy the format of the body + $body->prepend(sprintf('Received From: %s', $mailinfo['email'])); + $vars['message'] = $body; + $vars['userId'] = 0; //Unknown user! //XXX: Assume ticket owner? + $vars['origin'] = 'Email'; + if ($object instanceof Threadable) + return $object->postThreadEntry('M', $vars); + elseif ($this instanceof ObjectThread) + return $this->addMessage($vars, $errors); + else + throw new Exception('Cannot continue discussion with abstract thread'); + } + // Currently impossible, but indicate that this thread object could + // not append the incoming email. + return false; + } - // Clear reference table - $sql = 'DELETE `a`.* FROM '.ATTACHMENT_TABLE. ' `a` ' - . 'INNER JOIN '.THREAD_ENTRY_TABLE.' `e` - ON(`e`.id = `a`.object_id AND `a`.`type`= "H") ' - . ' WHERE `e`.thread_id='.db_input($this->getId()); + function deleteAttachments() { + $deleted = Attachment::objects()->filter(array( + 'thread_entry__thread' => $this, + ))->delete(); - $deleted=0; - if (($res=db_query($sql)) && ($deleted=db_affected_rows())) + if ($deleted) AttachmentFile::deleteOrphans(); return $deleted; } + function removeCollaborators() { + return Collaborator::objects() + ->filter(array('thread_id'=>$this->getId())) + ->delete(); + } + + /** + * Function: lookupByEmailHeaders + * + * Attempt to locate a thread by the email headers. It should be + * considered a secondary lookup to ThreadEntry::lookupByEmailHeaders(), + * which should find an actual thread entry, which should be possible + * for all email communcation which is associated with a thread entry. + * The only time where this is useful is for threads which triggered + * email communication without a thread entry, for instance, like + * tickets created without an initial message. + */ + function lookupByEmailHeaders(&$mailinfo) { + $possibles = array(); + foreach (array('in-reply-to', 'references') as $header) { + $matches = array(); + if (!isset($mailinfo[$header]) || !$mailinfo[$header]) + continue; + // Header may have multiple entries (usually separated by + // spaces ( ) + elseif (!preg_match_all('/<[^>@]+@[^>]+>/', $mailinfo[$header], + $matches)) + continue; + + // The References header will have the most recent message-id + // (parent) on the far right. + // @see rfc 1036, section 2.2.5 + // @see http://www.jwz.org/doc/threading.html + $possibles = array_merge($possibles, array_reverse($matches[0])); + } + + // Add the message id if it is embedded in the body + $match = array(); + if (preg_match('`(?:data-mid="|Ref-Mid: )([^"\s]*)(?:$|")`', + $mailinfo['message'], $match) + && !in_array($match[1], $possibles) + ) { + $possibles[] = $match[1]; + } + + foreach ($possibles as $mid) { + // Attempt to detect the ticket and user ids from the + // message-id header. If the message originated from + // osTicket, the Mailer class can break it apart. If it came + // from this help desk, the 'loopback' property will be set + // to true. + $mid_info = Mailer::decodeMessageId($mid); + if ($mid_info['loopback'] && isset($mid_info['uid']) + && @$mid_info['threadId'] + && ($t = Thread::lookup($mid_info['threadId'])) + ) { + if (@$mid_info['userId']) { + $mailinfo['userId'] = $mid_info['userId']; + } + elseif (@$mid_info['staffId']) { + $mailinfo['staffId'] = $mid_info['staffId']; + } + // ThreadEntry was positively identified + return $t; + } + } + + return null; + } + function delete() { //Self delete - $sql = 'DELETE FROM '.THREAD_TABLE.' WHERE - id='.db_input($this->getId()); - - if (!db_query($sql) || !db_affected_rows()) + if (!parent::delete()) return false; // Clear email meta data (header..etc) - $sql = 'UPDATE '.THREAD_ENTRY_EMAIL_TABLE.' email ' - . 'INNER JOIN '.THREAD_ENTRY_TABLE.' entry - ON (entry.id = email.thread_entry_id) ' - . 'SET email.headers = null ' - . 'WHERE entry.thread_id = '.db_input($this->getId()); - db_query($sql); + ThreadEntryEmailInfo::objects() + ->filter(array('thread_entry__thread' => $this)) + ->update(array('headers' => null)); // Mass delete entries $this->deleteAttachments(); - $sql = 'DELETE FROM '.THREAD_ENTRY_TABLE - . ' WHERE thread_id='.db_input($this->getId()); - db_query($sql); + $this->removeCollaborators(); + + $this->entries->delete(); return true; } static function create($vars) { - - if (!$vars || !$vars['object_id'] || !$vars['object_type']) - return false; - - $sql = 'INSERT INTO '.THREAD_TABLE.' SET created=NOW() ' - .', object_id='.db_input($vars['object_id']) - .', object_type='.db_input($vars['object_type']); - - if (db_query($sql)) - return static::lookup(db_insert_id()); - - return null; + $inst = parent::create($vars); + $inst->created = SqlFunction::NOW(); + return $inst; } +} - static function lookup($id) { - - return ($id - && ($thread = new Thread($id)) - && $thread->getId() - ) - ? $thread : null; - } +class ThreadEntryEmailInfo extends VerySimpleModel { + static $meta = array( + 'table' => THREAD_ENTRY_EMAIL_TABLE, + 'pk' => array('id'), + 'joins' => array( + 'thread_entry' => array( + 'constraint' => array('thread_entry_id' => 'ThreadEntry.id'), + ), + ), + ); } -class ThreadEntryModel extends VerySimpleModel { +class ThreadEntry extends VerySimpleModel { static $meta = array( 'table' => THREAD_ENTRY_TABLE, 'pk' => array('id'), + 'select_related' => array('staff', 'user', 'email_info'), 'joins' => array( 'thread' => array( - 'constraint' => array('thread_id' => 'ThreadModel.id'), + 'constraint' => array('thread_id' => 'Thread.id'), + ), + 'parent' => array( + 'constraint' => array('pid' => 'ThreadEntry.id'), + 'null' => true, + ), + 'children' => array( + 'reverse' => 'ThreadEntry.parent', + ), + 'email_info' => array( + 'reverse' => 'ThreadEntryEmailInfo.thread_entry', + 'list' => false, ), 'attachments' => array( - 'reverse' => 'AttachmentModel.thread', + 'reverse' => 'Attachment.thread_entry', + 'null' => true, + ), + 'staff' => array( + 'constraint' => array('staff_id' => 'Staff.staff_id'), + 'null' => true, + ), + 'user' => array( + 'constraint' => array('user_id' => 'User.id'), 'null' => true, ), ), ); -} - -class ThreadEntry { - var $id; - var $ht; + const FLAG_ORIGINAL_MESSAGE = 0x0001; - var $thread; - var $attachments; + var $_headers; + var $_thread; var $_actions; + var $_attachments; - function ThreadEntry($id, $threadId=0, $type='') { - $this->load($id, $threadId, $type); - } - - function load($id=0, $threadId=0, $type='') { - - if (!$id && !($id=$this->getId())) - return false; - - $sql='SELECT entry.*, email.mid, email.headers ' - .' ,count(DISTINCT attach.id) as attachments ' - .' FROM '.THREAD_ENTRY_TABLE.' entry ' - .' LEFT JOIN '.THREAD_ENTRY_EMAIL_TABLE.' email - ON (email.thread_entry_id=entry.id) ' - .' LEFT JOIN '.ATTACHMENT_TABLE.' attach - ON (attach.object_id=entry.id AND attach.`type` = "H") ' - .' WHERE entry.id='.db_input($id); - - if ($type) - $sql.=' AND entry.type='.db_input($type); - - if ($threadId) - $sql.=' AND entry.thread_id='.db_input($threadId); - - $sql.=' GROUP BY entry.id '; - - if (!($res=db_query($sql)) || !db_num_rows($res)) + function postEmail($mailinfo) { + if (!($thread = $this->getThread())) + // Kind of hard to continue a discussion without a thread ... return false; - $this->ht = db_fetch_array($res); - $this->id = $this->ht['id']; - $this->attachments = new GenericAttachments($this->id, 'H'); - - return true; - } + elseif ($this->getEmailMessageId() == $mailinfo['mid']) + // Reporting success so the email can be moved or deleted. + return true; - function reload() { - return $this->load(); + return $thread->postEmail($mailinfo); } function getId() { @@ -292,27 +429,32 @@ class ThreadEntry { } function getPid() { - return $this->ht['pid']; + return $this->get('pid', 0); + } + + function getParent() { + if ($this->getPid()) + return ThreadEntry::lookup($this->getPid()); } function getType() { - return $this->ht['type']; + return $this->type; } function getSource() { - return $this->ht['source']; + return $this->source; } function getPoster() { - return $this->ht['poster']; + return $this->poster; } function getTitle() { - return $this->ht['title']; + return $this->title; } function getBody() { - return ThreadEntryBody::fromFormattedText($this->ht['body'], $this->ht['format']); + return ThreadEntryBody::fromFormattedText($this->body, $this->format); } function setBody($body) { @@ -325,36 +467,37 @@ class ThreadEntry { $body = new TextThreadEntryBody($body); } - $sql='UPDATE '.THREAD_ENTRY_TABLE.' SET updated=NOW()' - .',format='.db_input($body->getType()) - .',body='.db_input((string) $body) - .' WHERE id='.db_input($this->getId()); - return db_query($sql) && db_affected_rows(); + $this->format = $body->getType(); + $this->body = (string) $body; + return $this->save(); } function getCreateDate() { - return $this->ht['created']; + return $this->created; } function getUpdateDate() { - return $this->ht['updated']; + return $this->updated; } function getNumAttachments() { - return $this->ht['attachments']; + return $this->attachments->count(); } function getEmailMessageId() { - return $this->ht['mid']; + if ($this->email_info) + return $this->email_info->mid; } function getEmailHeaderArray() { require_once(INCLUDE_DIR.'class.mailparse.php'); - if (!isset($this->ht['@headers'])) - $this->ht['@headers'] = Mail_Parse::splitHeaders($this->ht['headers']); - - return $this->ht['@headers']; + if (!isset($this->_headers) && $this->email_info + && isset($this->email_info->headers) + ) { + $this->_headers = Mail_Parse::splitHeaders($this->email_info->headers); + } + return $this->_headers; } function getEmailReferences($include_mid=true) { @@ -362,32 +505,11 @@ class ThreadEntry { $headers = self::getEmailHeaderArray(); if (isset($headers['References']) && $headers['References']) $references = $headers['References']." "; - if ($include_mid) - $references .= $this->getEmailMessageId(); + if ($include_mid && ($mid = $this->getEmailMessageId())) + $references .= $mid; return $references; } - function getTaggedEmailReferences($prefix, $refId) { - - $ref = "+$prefix".Base32::encode(pack('VV', $this->getId(), $refId)); - - $mid = substr_replace($this->getEmailMessageId(), - $ref, strpos($this->getEmailMessageId(), '@'), 0); - - return sprintf('%s %s', $this->getEmailReferences(false), $mid); - } - - function getEmailReferencesForUser($user) { - return $this->getTaggedEmailReferences('u', - ($user instanceof Collaborator) - ? $user->getUserId() - : $user->getId()); - } - - function getEmailReferencesForStaff($staff) { - return $this->getTaggedEmailReferences('s', $staff->getId()); - } - function getUIDFromEmailReference($ref) { $info = unpack('Vtid/Vuid', @@ -399,43 +521,46 @@ class ThreadEntry { } function getThreadId() { - return $this->ht['thread_id']; + return $this->thread_id; } function getThread() { - if(!$this->thread && $this->getThreadId()) - $this->thread = Thread::lookup($this->getThreadId()); + if (!isset($this->_thread) && $this->thread_id) + // TODO: Consider typing the thread based on its type field + $this->_thread = ObjectThread::lookup($this->getThreadId()); - return $this->thread; + return $this->_thread; } function getStaffId() { - return $this->ht['staff_id']; + return isset($this->staff_id) ? $this->staff_id : 0; } function getStaff() { - - if(!$this->staff && $this->getStaffId()) - $this->staff = Staff::lookup($this->getStaffId()); - return $this->staff; } function getUserId() { - return $this->ht['user_id']; + return isset($this->user_id) ? $this->user_id : 0; } function getUser() { + return $this->user; + } - if (!isset($this->user)) - $this->user = User::lookup($this->getUserId()); + function getName() { + if ($this->staff_id) + return $this->staff->getName(); + if ($this->user_id) + return $this->user->getName(); - return $this->user; + return $this->poster; } function getEmailHeader() { - return $this->ht['headers']; + if ($this->email_info) + return $this->email_info->headers; } function isAutoReply() { @@ -460,6 +585,16 @@ class ThreadEntry { return ($this->isAutoReply() || $this->isBounce()); } + function hasFlag($flag) { + return ($this->get('flags', 0) & $flag) != 0; + } + function clearFlag($flag) { + return $this->set('flags', $this->get('flags') & ~$flag); + } + function setFlag($flag) { + return $this->set('flags', $this->get('flags') | $flag); + } + //Web uploads - caller is expected to format, validate and set any errors. function uploadFiles($files) { @@ -472,9 +607,9 @@ class ThreadEntry { continue; if(!$file['error'] - && ($id=AttachmentFile::upload($file)) - && $this->saveAttachment($id)) - $uploaded[]=$id; + && ($F=AttachmentFile::upload($file)) + && $this->saveAttachment($F)) + $uploaded[]= $F->getId(); else { if(!$file['error']) $error = sprintf(__('Unable to upload file - %s'),$file['name']); @@ -514,8 +649,8 @@ class ThreadEntry { if(!$attachment || !is_array($attachment)) return null; - $id=0; - if ($attachment['error'] || !($id=$this->saveAttachment($attachment))) { + $A=null; + if ($attachment['error'] || !($A=$this->saveAttachment($attachment))) { $error = $attachment['error']; if(!$error) $error = sprintf(_S('Unable to import attachment - %s'), @@ -525,7 +660,7 @@ class ThreadEntry { _S('File Import Error'), $error, _S('SYSTEM'), false); } - return $id; + return $A; } /* @@ -536,28 +671,47 @@ class ThreadEntry { $inline = is_array($file) && @$file['inline']; - return $this->attachments->save($file, $inline); + if (is_numeric($file)) + $fileId = $file; + elseif ($file instanceof AttachmentFile) + $fileId = $file->getId(); + elseif ($F = AttachmentFile::create($file)) + $fileId = $F->getId(); + elseif (is_array($file) && isset($file['id'])) + $fileId = $file['id']; + else + return false; + + $att = Attachment::create(array( + 'type' => 'H', + 'object_id' => $this->getId(), + 'file_id' => $fileId, + 'inline' => $inline ? 1 : 0, + )); + if (!$att->save()) + return false; + return $att; } function saveAttachments($files) { - $ids=array(); + $attachments = array(); foreach ($files as $file) - if (($id=$this->saveAttachment($file))) - $ids[] = $id; + if (($A = $this->saveAttachment($file))) + $attachments[] = $A; - return $ids; + return $attachments; } function getAttachments() { - return $this->attachments->getAll(false); + return $this->attachments; } function getAttachmentUrls() { $json = array(); - foreach ($this->getAttachments() as $att) { - $json[$att['key']] = array( - 'download_url' => $att['download_url'], - 'filename' => $att['name'], + foreach ($this->attachments as $att) { + $json[$att->file->getKey()] = array( + 'download_url' => $att->file->getDownloadUrl(), + 'filename' => $att->file->name, ); } @@ -565,146 +719,30 @@ class ThreadEntry { } function getAttachmentsLinks($file='attachment.php', $target='_blank', $separator=' ') { + // TODO: Move this to the respective UI templates $str=''; - foreach ($this->getAttachments() as $att ) { - if ($att['inline']) continue; + foreach ($this->attachments as $att ) { + if ($att->inline) continue; $size = ''; - if ($att['size']) - $size=sprintf('<em>(%s)</em>', Format::file_size($att['size'])); + if ($att->file->size) + $size=sprintf('<em>(%s)</em>', Format::file_size($att->file->size)); - $str.=sprintf('<a class="Icon file no-pjax" href="%s" target="%s">%s</a>%s %s', - $att['download_url'], $target, Format::htmlchars($att['name']), $size, $separator); + $str .= sprintf( + '<a class="Icon file no-pjax" href="%s" target="%s">%s</a>%s %s', + $att->file->getDownloadUrl(), $target, + Format::htmlchars($att->file->name), $size, $separator); } return $str; } - /** - * postEmail - * - * After some security and sanity checks, attaches the body and subject - * of the message in reply to this thread item - * - * Parameters: - * mailinfo - (array) of information about the email, with at least the - * following keys - * - mid - (string) email message-id - * - name - (string) personal name of email originator - * - email - (string<email>) originating email address - * - subject - (string) email subject line (decoded) - * - body - (string) email message body (decoded) - */ - function postEmail($mailinfo) { - global $ost; - - // +==================+===================+=============+ - // | Orig Thread-Type | Reply Thread-Type | Requires | - // +==================+===================+=============+ - // | * | Message (M) | From: Owner | - // | * | Note (N) | From: Staff | - // | Response (R) | Message (M) | | - // | Message (M) | Response (R) | From: Staff | - // +------------------+-------------------+-------------+ - - if (!$ticket = $this->getTicket()) - // Kind of hard to continue a discussion without a ticket ... - return false; - - // Make sure the email is NOT already fetched... (undeleted emails) - elseif ($this->getEmailMessageId() == $mailinfo['mid']) - // Reporting success so the email can be moved or deleted. - return true; - - // Mail sent by this system will have a message-id format of - // <code-random-mailbox@domain.tld> - // where code is a predictable string based on the SECRET_SALT of - // this osTicket installation. If this incoming mail matches the - // code, then it very likely originated from this system and looped - @list($code) = explode('-', $mailinfo['mid'], 2); - if (0 === strcasecmp(ltrim($code, '<'), substr(md5('mail'.SECRET_SALT), -9))) { - // This mail was sent by this system. It was received due to - // some kind of mail delivery loop. It should not be considered - // a response to an existing thread entry - if ($ost) $ost->log(LOG_ERR, _S('Email loop detected'), sprintf( - _S('It appears as though <%s> is being used as a forwarded or fetched email account and is also being used as a user / system account. Please correct the loop or seek technical assistance.'), - $mailinfo['email']), - - // This is quite intentional -- don't continue the loop - false, - // Force the message, even if logging is disabled - true); - return true; - } - - $vars = array( - 'mid' => $mailinfo['mid'], - 'header' => $mailinfo['header'], - 'ticketId' => $ticket->getId(), - 'poster' => $mailinfo['name'], - 'origin' => 'Email', - 'source' => 'Email', - 'ip' => '', - 'reply_to' => $this, - 'recipients' => $mailinfo['recipients'], - 'to-email-id' => $mailinfo['to-email-id'], - ); - $errors = array(); - - if (isset($mailinfo['attachments'])) - $vars['attachments'] = $mailinfo['attachments']; - - $body = $mailinfo['message']; - - // Disambiguate if the user happens also to be a staff member of the - // system. The current ticket owner should _always_ post messages - // instead of notes or responses - if ($mailinfo['userId'] - || strcasecmp($mailinfo['email'], $ticket->getEmail()) == 0) { - $vars['message'] = $body; - $vars['userId'] = $mailinfo['userId'] ? $mailinfo['userId'] : $ticket->getUserId(); - return $ticket->postMessage($vars, 'Email'); - } - // XXX: Consider collaborator role - elseif ($mailinfo['staffId'] - || ($mailinfo['staffId'] = Staff::getIdByEmail($mailinfo['email']))) { - $vars['staffId'] = $mailinfo['staffId']; - $poster = Staff::lookup($mailinfo['staffId']); - $vars['note'] = $body; - return $ticket->postNote($vars, $errors, $poster); - } - elseif (Email::getIdByEmail($mailinfo['email'])) { - // Don't process the email -- it came FROM this system - return true; - } - // Support the mail parsing system declaring a thread-type - elseif (isset($mailinfo['thread-type'])) { - switch ($mailinfo['thread-type']) { - case 'N': - $vars['note'] = $body; - $poster = $mailinfo['email']; - return $ticket->postNote($vars, $errors, $poster); - } - } - // TODO: Consider security constraints - else { - //XXX: Are we potentially leaking the email address to - // collaborators? - $vars['message'] = sprintf("Received From: %s\n\n%s", - $mailinfo['email'], $body); - $vars['userId'] = 0; //Unknown user! //XXX: Assume ticket owner? - return $ticket->postMessage($vars, 'Email'); - } - // Currently impossible, but indicate that this thread object could - // not append the incoming email. - return false; - } /* Returns file names with id as key */ function getFiles() { $files = array(); - foreach($this->getAttachments() as $attachment) - $files[$attachment['file_id']] = $attachment['name']; + foreach($this->attachments as $attachment) + $files[$attachment->file_id] = $attachment->file->name; return $files; } @@ -733,13 +771,15 @@ class ThreadEntry { if (!$id || !$mid) return false; - $sql='INSERT INTO '.THREAD_ENTRY_EMAIL_TABLE - .' SET thread_entry_id='.db_input($id) - .', mid='.db_input($mid); + $this->email_info = ThreadEntryEmailInfo::create(array( + 'thread_entry_id' => $id, + 'mid' => $mid, + )); + if ($header) - $sql .= ', headers='.db_input($header); + $this->email_info->headers = trim($header); - return db_query($sql) ? db_insert_id() : 0; + return $this->email_info->save(); } /* variables */ @@ -769,14 +809,6 @@ class ThreadEntry { return false; } - static function lookup($id, $tid=0, $type='') { - return ($id - && is_numeric($id) - && ($e = new ThreadEntry($id, $tid, $type)) - && $e->getId()==$id - )?$e:null; - } - /** * Parameters: * mailinfo (hash<String>) email header information. Must include keys @@ -793,16 +825,15 @@ class ThreadEntry { function lookupByEmailHeaders(&$mailinfo, &$seen=false) { // Search for messages using the References header, then the // in-reply-to header - $search = 'SELECT thread_entry_id, mid FROM '.THREAD_ENTRY_EMAIL_TABLE - . ' WHERE mid=%s ' - . ' ORDER BY thread_entry_id DESC'; - - if (list($id, $mid) = db_fetch_row(db_query( - sprintf($search, db_input($mailinfo['mid']))))) { + if ($entry = ThreadEntry::objects() + ->filter(array('email_info__mid' => $mailinfo['mid'])) + ->first() + ) { $seen = true; - return ThreadEntry::lookup($id); + return $entry; } + $possibles = array(); foreach (array('in-reply-to', 'references') as $header) { $matches = array(); if (!isset($mailinfo[$header]) || !$mailinfo[$header]) @@ -817,41 +848,73 @@ class ThreadEntry { // (parent) on the far right. // @see rfc 1036, section 2.2.5 // @see http://www.jwz.org/doc/threading.html - $thread = null; - foreach (array_reverse($matches[0]) as $mid) { - //Try to determine if it's a reply to a tagged email. - $ref = null; - if (strpos($mid, '+')) { - list($left, $right) = explode('@',$mid); - list($left, $ref) = explode('+', $left); - $mid = "$left@$right"; + $possibles = array_merge($possibles, array_reverse($matches[0])); + } + + // Add the message id if it is embedded in the body + $match = array(); + if (preg_match('`(?:data-mid="|Ref-Mid: )([^"\s]*)(?:$|")`', + $mailinfo['message'], $match) + && !in_array($match[1], $possibles) + ) { + $possibles[] = $match[1]; + } + + $thread = null; + foreach ($possibles as $mid) { + // Attempt to detect the ticket and user ids from the + // message-id header. If the message originated from + // osTicket, the Mailer class can break it apart. If it came + // from this help desk, the 'loopback' property will be set + // to true. + $mid_info = Mailer::decodeMessageId($mid); + if ($mid_info['loopback'] && isset($mid_info['uid']) + && @$mid_info['entryId'] + && ($t = ThreadEntry::lookup($mid_info['entryId'])) + && ($t->thread_id == $mid_info['threadId']) + ) { + if (@$mid_info['userId']) { + $mailinfo['userId'] = $mid_info['userId']; } - $res = db_query(sprintf($search, db_input($mid))); - while (list($id) = db_fetch_row($res)) { - if (!($t = ThreadEntry::lookup($id))) - continue; - // Capture the first match thread item - if (!$thread) - $thread = $t; - // We found a match - see if we can ID the user. - // XXX: Check access of ref is enough? - if ($ref && ($uid = $t->getUIDFromEmailReference($ref))) { - if ($ref[0] =='s') //staff - $mailinfo['staffId'] = $uid; - else // user or collaborator. - $mailinfo['userId'] = $uid; - - // Best possible case — found the thread and the - // user - return $t; - } + elseif (@$mid_info['staffId']) { + $mailinfo['staffId'] = $mid_info['staffId']; + } + // ThreadEntry was positively identified + return $t; + } + + // Try to determine if it's a reply to a tagged email. + // (Deprecated) + $ref = null; + if (strpos($mid, '+')) { + list($left, $right) = explode('@',$mid); + list($left, $ref) = explode('+', $left); + $mid = "$left@$right"; + } + $entries = ThreadEntry::objects() + ->filter(array('email_info__mid' => $mid)); + foreach ($entries as $t) { + // Capture the first match thread item + if (!$thread) + $thread = $t; + // We found a match - see if we can ID the user. + // XXX: Check access of ref is enough? + if ($ref && ($uid = $t->getUIDFromEmailReference($ref))) { + if ($ref[0] =='s') //staff + $mailinfo['staffId'] = $uid; + else // user or collaborator. + $mailinfo['userId'] = $uid; + + // Best possible case — found the thread and the + // user + return $t; } } - // Second best case — found a thread but couldn't identify the - // user from the header. Return the first thread entry matched - if ($thread) - return $thread; } + // Second best case — found a thread but couldn't identify the + // user from the header. Return the first thread entry matched + if ($thread) + return $thread; // Search for ticket by the [#123456] in the subject line // This is the last resort - emails must match to avoid message @@ -880,6 +943,8 @@ class ThreadEntry { } // Search for the message-id token in the body + // *DEPRECATED* the current algo on outgoing mail will use + // Mailer::getMessageId as the message id tagged here if (preg_match('`(?:data-mid="|Ref-Mid: )([^"\s]*)(?:$|")`', $mailinfo['message'], $match)) if ($thread = ThreadEntry::lookupByRefMessageId($match[1], @@ -891,7 +956,9 @@ class ThreadEntry { /** * Find a thread entry from a message-id created from the - * ::asMessageId() method + * ::asMessageId() method. + * + * *DEPRECATED* use Mailer::decodeMessageId() instead */ function lookupByRefMessageId($mid, $from) { $mid = trim($mid, '<>'); @@ -909,36 +976,7 @@ class ThreadEntry { if (!$thread) return false; - if (0 === strcasecmp($thread->asMessageId($from, $ver), $mid)) - return $thread; - } - - /** - * Get an email message-id that can be used to represent this thread - * entry. The same message-id can be passed to ::lookupByRefMessageId() - * to find this thread entry - * - * Formats: - * Initial (version <null>) - * <$:b32(thread-id)$:md5(to-addr.ticket-num.ticket-id)@:md5(url)> - * thread-id - thread-id, little-endian INT, packed - * :b32() - base32 encoded - * to-addr - individual email recipient - * ticket-num - external ticket number - * ticket-id - internal ticket id - * :md5() - last 10 hex chars of MD5 sum - * url - helpdesk URL - */ - function asMessageId($to, $version=false) { - global $ost; - - $domain = md5($ost->getConfig()->getURL()); - $ticket = $this->getThread()->getObject(); - return sprintf('$%s$%s@%s', - base64_encode(pack('V', $this->getId())), - substr(md5($to . $ticket->getNumber() . $ticket->getId()), -10), - substr($domain, -10) - ); + return $thread; } //new entry ... we're trusting the caller to check validity of the data. @@ -987,36 +1025,36 @@ class ThreadEntry { if ($poster && is_object($poster)) $poster = (string) $poster; - $sql=' INSERT INTO '.THREAD_ENTRY_TABLE.' SET `created` = NOW() ' - .' ,`type` = '.db_input($vars['type']) - .' ,`thread_id` = '.db_input($vars['threadId']) - .' ,`title` = '.db_input(Format::sanitize($vars['title'], true)) - .' ,`format` = '.db_input($vars['body']->getType()) - .' ,`staff_id` = '.db_input($vars['staffId']) - .' ,`user_id` = '.db_input($vars['userId']) - .' ,`poster` = '.db_input($poster) - .' ,`source` = '.db_input($vars['source']); + $entry = parent::create(array( + 'created' => SqlFunction::NOW(), + 'type' => $vars['type'], + 'thread_id' => $vars['threadId'], + 'title' => Format::sanitize($vars['title'], true), + 'format' => $vars['body']->getType(), + 'staff_id' => $vars['staffId'], + 'user_id' => $vars['userId'], + 'poster' => $poster, + 'source' => $vars['source'], + )); if (!isset($vars['attachments']) || !$vars['attachments']) // Otherwise, body will be configured in a block below (after // inline attachments are saved and updated in the database) - $sql.=' ,body='.db_input($body); + $entry->body = $body; if (isset($vars['pid'])) - $sql.=' ,pid='.db_input($vars['pid']); + $entry->pid = $vars['pid']; // Check if 'reply_to' is in the $vars as the previous ThreadEntry // instance. If the body of the previous message is found in the new // body, strip it out. elseif (isset($vars['reply_to']) && $vars['reply_to'] instanceof ThreadEntry) - $sql.=' ,pid='.db_input($vars['reply_to']->getId()); + $entry->pid = $vars['reply_to']->getId(); if ($vars['ip_address']) - $sql.=' ,ip_address='.db_input($vars['ip_address']); + $entry->ip_address = $vars['ip_address']; - //echo $sql; - if (!db_query($sql) - || !($entry=self::lookup(db_insert_id(), $vars['threadId']))) + if (!$entry->save()) return false; /************* ATTACHMENTS *****************/ @@ -1050,31 +1088,24 @@ class ThreadEntry { } } - $sql = 'UPDATE '.THREAD_ENTRY_TABLE - .' SET body='.db_input($body) - .' WHERE `id`='.db_input($entry->getId()); - - if (!db_query($sql) || !db_affected_rows()) + $entry->body = $body; + if (!$entry->save()) return false; } - // Email message id (required for all thread posts) - if (!isset($vars['mid'])) - $vars['mid'] = sprintf('<%s@%s>', - Misc::randCode(24), substr(md5($cfg->getUrl()), -10)); - + // Save mail message id, if available $entry->saveEmailInfo($vars); // Inline images (attached to the draft) $entry->saveAttachments(Draft::getAttachmentIds($body)); - Signal::send('model.created', $entry); + Signal::send('threadentry.created', $entry); return $entry; } static function add($vars) { - return ($entry=self::create($vars)) ? $entry->getId() : 0; + return self::create($vars); } // Extensible thread entry actions ------------------------ @@ -1266,19 +1297,26 @@ class TextThreadEntryBody extends ThreadEntryBody { return Format::stripEmptyLines($this->body); } + function prepend($what) { + $this->body = $what . "\n\n" . $this->body; + } + function display($output=false) { if ($this->isEmpty()) return '(empty)'; + $escaped = Format::htmlchars($this->body); switch ($output) { case 'html': + return '<div style="white-space:pre-wrap">' + .Format::clickableurls($escaped).'</div>'; case 'email': return '<div style="white-space:pre-wrap">' - .Format::htmlchars($this->body).'</div>'; + .$escaped.'</div>'; case 'pdf': - return nl2br($this->body); + return nl2br($escaped); default: - return '<pre>'.$this->body.'</pre>'; + return '<pre>'.$escaped.'</pre>'; } } } @@ -1313,6 +1351,10 @@ class HtmlThreadEntryBody extends ThreadEntryBody { return Format::searchable($body); } + function prepend($what) { + $this->body = sprintf('<div>%s<br/><br/></div>%s', $what, $this->body); + } + function display($output=false) { if ($this->isEmpty()) return '(empty)'; @@ -1334,16 +1376,12 @@ class MessageThreadEntry extends ThreadEntry { const ENTRY_TYPE = 'M'; - function MessageThreadEntry($id, $threadId=0) { - parent::ThreadEntry($id, $threadId, self::ENTRY_TYPE); - } - function getSubject() { return $this->getTitle(); } static function create($vars, &$errors) { - return self::lookup(self::add($vars, $errors)); + return static::add($vars, $errors); } static function add($vars, &$errors) { @@ -1365,16 +1403,6 @@ class MessageThreadEntry extends ThreadEntry { return parent::add($vars); } - - static function lookup($id, $tid=0) { - - return ($id - && is_numeric($id) - && ($m = new MessageThreadEntry($id, $tid)) - && $m->getId()==$id - )?$m:null; - } - } /* thread entry of type response */ @@ -1382,10 +1410,6 @@ class ResponseThreadEntry extends ThreadEntry { const ENTRY_TYPE = 'R'; - function ResponseThreadEntry($id, $threadId=0) { - parent::ThreadEntry($id, $threadId, self::ENTRY_TYPE); - } - function getSubject() { return $this->getTitle(); } @@ -1395,7 +1419,7 @@ class ResponseThreadEntry extends ThreadEntry { } static function create($vars, &$errors) { - return self::lookup(self::add($vars, $errors)); + return static::add($vars, $errors); } static function add($vars, &$errors) { @@ -1419,31 +1443,18 @@ class ResponseThreadEntry extends ThreadEntry { return parent::add($vars); } - - static function lookup($id, $tid=0) { - - return ($id - && is_numeric($id) - && ($r = new ResponseThreadEntry($id, $tid)) - && $r->getId()==$id - )?$r:null; - } } /* Thread entry of type note (Internal Note) */ class NoteThreadEntry extends ThreadEntry { const ENTRY_TYPE = 'N'; - function NoteThreadEntry($id, $threadId=0) { - parent::ThreadEntry($id, $threadId, self::ENTRY_TYPE); - } - function getMessage() { return $this->getBody(); } static function create($vars, &$errors) { - return self::lookup(self::add($vars, $errors)); + return self::add($vars, $errors); } static function add($vars, &$errors) { @@ -1462,68 +1473,67 @@ class NoteThreadEntry extends ThreadEntry { return parent::add($vars); } - - static function lookup($id, $tid=0) { - - return ($id - && is_numeric($id) - && ($n = new NoteThreadEntry($id, $tid)) - && $n->getId()==$id - )?$n:null; - } } // Object specific thread utils. class ObjectThread extends Thread { private $_entries = array(); - function __construct($id) { + static $types = array( + ObjectModel::OBJECT_TYPE_TASK => 'TaskThread', + ); + + var $counts; - parent::__construct($id); + function getCounts() { + if (!isset($this->counts) && $this->getId()) { + $this->counts = array(); - if ($this->getId()) { - $sql= ' SELECT `type`, count(DISTINCT e.id) as count ' - .' FROM '.THREAD_TABLE. ' t ' - .' INNER JOIN '.THREAD_ENTRY_TABLE. ' e ON (e.thread_id = t.id) ' - .' WHERE t.id='.db_input($this->getId()) - .' GROUP BY e.`type`'; + $stuff = $this->entries + ->values_flat('type') + ->annotate(array( + 'count' => SqlAggregate::COUNT('id') + )); - if (($res=db_query($sql)) && db_num_rows($res)) { - while ($row=db_fetch_row($res)) - $this->_entries[$row[0]] = $row[1]; + foreach ($stuff as $row) { + list($type, $count) = $row; + $this->counts[$type] = $count; } } + return $this->counts; } function getNumMessages() { - return $this->_entries[MessageThreadEntry::ENTRY_TYPE]; + $this->getCounts(); + return $this->counts[MessageThreadEntry::ENTRY_TYPE]; } function getNumResponses() { - return $this->_entries[ResponseThreadEntry::ENTRY_TYPE]; + $this->getCounts(); + return $this->counts[ResponseThreadEntry::ENTRY_TYPE]; } function getNumNotes() { - return $this->_entries[NoteThreadEntry::ENTRY_TYPE]; + $this->getCounts(); + return $this->counts[NoteThreadEntry::ENTRY_TYPE]; } function getMessages() { - return $this->getEntries(array( - 'type' => MessageThreadEntry::ENTRY_TYPE)); + return $this->entries->filter(array( + 'type' => MessageThreadEntry::ENTRY_TYPE + )); } function getLastMessage() { - - $criteria = array( - 'type' => MessageThreadEntry::ENTRY_TYPE, - 'order' => 'DESC', - 'limit' => 1); - - return $this->getEntry($criteria); + return $this->entries->filter(array( + 'type' => MessageThreadEntry::ENTRY_TYPE + )) + ->order_by('-id') + ->first(); } function getEntry($var) { - + // XXX: PUNT if (is_numeric($var)) $id = $var; else { @@ -1537,13 +1547,15 @@ class ObjectThread extends Thread { } function getResponses() { - return $this->getEntries(array( - 'type' => ResponseThreadEntry::ENTRY_TYPE)); + return $this->entries->filter(array( + 'type' => ResponseThreadEntry::ENTRY_TYPE + )); } function getNotes() { - return $this->getEntries(array( - 'type' => NoteThreadEntry::ENTRY_TYPE)); + return $this->entries->filter(array( + 'type' => NoteThreadEntry::ENTRY_TYPE + )); } function addNote($vars, &$errors) { @@ -1572,33 +1584,37 @@ class ObjectThread extends Thread { function getVar($name) { switch ($name) { case 'original': - $entries = $this->getEntries(array( - 'type' => MessageThreadEntry::ENTRY_TYPE, - 'order' => 'ASC', - 'limit' => 1)); - if ($entries && $entries[0]) - return (string) $entries[0]['body']; + $entry = $this->entries->filter(array( + 'type' => MessageThreadEntry::ENTRY_TYPE, + 'flags__hasbit' => ThreadEntry::FLAG_ORIGINAL_MESSAGE, + )) + ->order_by('id') + ->first(); + if ($entry) + return $entry->getBody(); break; case 'last_message': case 'lastmessage': - $entries = $this->getEntries(array( - 'type' => MessageThreadEntry::ENTRY_TYPE, - 'order' => 'DESC', - 'limit' => 1)); - if ($entries && $entries[0]) - return (string) $entries[0]['body']; + $entry = $this->getLastMessage(); + if ($entry) + return $entry->getBody(); break; } } - static function lookup($criteria) { + static function lookup($criteria, $type=false) { + if (!$type) + return parent::lookup($criteria); + + $class = false; + if (isset(self::$types[$type])) + $class = self::$types[$type]; + if (!class_exists($class)) + $class = get_called_class(); - return ($criteria - && ($t= new static($criteria)) - && $t->getId() - ) ? $t : null; + return $class::lookup($criteria); } } @@ -1607,10 +1623,12 @@ class TicketThread extends ObjectThread { static function create($ticket) { $id = is_object($ticket) ? $ticket->getId() : $ticket; - return parent::create(array( + $thread = parent::create(array( 'object_id' => $id, 'object_type' => ObjectModel::OBJECT_TYPE_TICKET )); + if ($thread->save()) + return $thread; } } @@ -1689,4 +1707,8 @@ abstract class ThreadEntryAction { ); } } + +interface Threadable { + function postThreadEntry($type, $vars); +} ?> diff --git a/include/class.ticket.php b/include/class.ticket.php index 07c8bfebdf10e7a520974ab0732204a9040f7701..5df9f9a82de862e52128542f5907323e852ee41b 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -43,16 +43,11 @@ class TicketModel extends VerySimpleModel { 'user' => array( 'constraint' => array('user_id' => 'User.id') ), - 'collaborators' => array( - 'reverse' => 'TicketCollaborator.ticket', - 'null' => true, - ), 'status' => array( 'constraint' => array('status_id' => 'TicketStatus.id') ), 'lock' => array( - 'reverse' => 'TicketLock.ticket', - 'list' => false, + 'constraint' => array('lock_id' => 'Lock.lock_id'), 'null' => true, ), 'dept' => array( @@ -75,7 +70,7 @@ class TicketModel extends VerySimpleModel { 'null' => true, ), 'thread' => array( - 'reverse' => 'ThreadModel.ticket', + 'reverse' => 'Thread.ticket', 'list' => false, 'null' => true, ), @@ -216,7 +211,8 @@ class TicketCData extends VerySimpleModel { TicketCData::$meta['table'] = TABLE_PREFIX . 'ticket__cdata'; -class Ticket { +class Ticket +implements RestrictedAccess, Threadable { var $id; var $number; @@ -246,14 +242,14 @@ class Ticket { if (!$id && !($id=$this->getId())) return false; - $sql='SELECT ticket.*, thread.id as thread_id, lock_id, dept.name as dept_name ' + $sql='SELECT ticket.*, thread.id as thread_id, ticket.lock_id, dept.name as dept_name ' .' ,count(distinct attach.id) as attachments' .' ,count(distinct task.id) as tasks' .' FROM '.TICKET_TABLE.' ticket ' .' LEFT JOIN '.DEPT_TABLE.' dept ON (ticket.dept_id=dept.id) ' .' LEFT JOIN '.SLA_TABLE.' sla ON (ticket.sla_id=sla.id AND sla.isactive=1) ' - .' LEFT JOIN '.TICKET_LOCK_TABLE.' tlock - ON ( ticket.ticket_id=tlock.ticket_id AND tlock.expire>NOW()) ' + .' LEFT JOIN '.LOCK_TABLE.' tlock + ON ( ticket.lock_id=tlock.lock_id AND tlock.expire>NOW()) ' .' LEFT JOIN '.TASK_TABLE.' task ON ( task.object_id = ticket.ticket_id AND task.object_type="T" ) ' .' LEFT JOIN '.THREAD_TABLE.' thread @@ -296,7 +292,7 @@ class Ticket { function loadDynamicData() { if (!$this->_answers) { - foreach (DynamicFormEntry::forTicket($this->getId(), true) as $form) { + foreach (DynamicFormEntry::forTicket($this->getThreadId(), true) as $form) { foreach ($form->getAnswers() as $answer) { $tag = mb_strtolower($answer->getField()->get('name')) ?: 'field.' . $answer->getField()->get('id'); @@ -441,7 +437,8 @@ class Ticket { return $this->getEmail(); } - function getAuthToken() { + // Deprecated + function getOldAuthToken() { # XXX: Support variable email address (for CCs) return md5($this->getId() . strtolower($this->getEmail()) . SECRET_SALT); } @@ -536,11 +533,10 @@ class Ticket { // fallback if the logic in ::setStatus fails. function setStatusId($id) { $sql = 'UPDATE '.TICKET_TABLE.' SET updated=NOW() '. - ' ,status_id='.db_input($status->getId()) . + ' ,status_id='.db_input($id) . ' WHERE ticket_id='.db_input($this->getId()); - if (!db_query($sql) || !db_affected_rows()) - return false; + return (db_query($sql) && db_affected_rows()); } function getStatus() { @@ -619,6 +615,9 @@ class Ticket { } function getLock() { + if (!isset($this->tlock) && $this->ht['lock_id']) + $this->tlock = Lock::lookup($this->ht['lock_id']); + return $this->tlock; } @@ -638,11 +637,34 @@ class Ticket { return $lock; } //No lock on the ticket or it is expired - $this->tlock = TicketLock::acquire($this->getId(), $staffId, $lockTime); //Create a new lock.. + $this->tlock = Lock::acquire($staffId, $lockTime); //Create a new lock.. + + if ($this->tlock) { + $sql = 'UPDATE '.TICKET_TABLE.' SET `lock_id` = ' + .db_input($this->tlock->getId()) + .' WHERE `ticket_id` = '. db_input($this->getId()); + db_query($sql); + } + //load and return the newly created lock if any! return $this->tlock; } + function releaseLock($staffId=false) { + if (!($lock = $this->getLock())) + return false; + + if ($staffId && $lock->staff_id != $staffId) + return false; + + if (!$lock->delete()) + return false; + + $sql = 'UPDATE '.TICKET_TABLE.' SET `lock_id` = 0 WHERE `ticket_id` = ' + . db_input($this->getId()); + return ($res = db_query($sql)) && db_affected_rows($res); + } + function getDept() { global $cfg; @@ -818,7 +840,7 @@ class Ticket { } function getThreadCount() { - return $this->getNumMessages() + $this->getNumResponses(); + return $this->getClientThread()->count(); } function getNumMessages() { @@ -834,15 +856,15 @@ class Ticket { } function getMessages() { - return $this->getThreadEntries('M'); + return $this->getThreadEntries(array('M')); } function getResponses() { - return $this->getThreadEntries('R'); + return $this->getThreadEntries(array('R')); } function getNotes() { - return $this->getThreadEntries('N'); + return $this->getThreadEntries(array('N')); } function getClientThread() { @@ -853,9 +875,11 @@ class Ticket { return $this->getThread()->getEntry($id); } - function getThreadEntries($type, $order='') { - return $this->getThread()->getEntries( - array( 'type' => $type, 'order' => $order)); + function getThreadEntries($type=false) { + $thread = $this->getThread()->getEntries(); + if ($type && is_array($type)) + $thread->filter(array('type__in' => $type)); + return $thread; } //Collaborators @@ -879,10 +903,10 @@ class Ticket { function getCollaborators($criteria=array()) { if ($criteria) - return Collaborator::forTicket($this->getId(), $criteria); + return Collaborator::forThread($this->getThreadId(), $criteria); if (!isset($this->collaborators)) - $this->collaborators = Collaborator::forTicket($this->getId()); + $this->collaborators = Collaborator::forThread($this->getThreadId()); return $this->collaborators; } @@ -939,7 +963,7 @@ class Ticket { return null; $vars = array_merge(array( - 'ticketId' => $this->getId(), + 'threadId' => $this->getThreadId(), 'userId' => $user->getId()), $vars); if (!($c=Collaborator::add($vars, $errors))) return null; @@ -973,20 +997,24 @@ class Ticket { //statuses $cids = null; if($vars['cid'] && ($cids=array_filter($vars['cid']))) { - $sql='UPDATE '.TICKET_COLLABORATOR_TABLE - .' SET updated=NOW(), isactive=1 ' - .' WHERE ticket_id='.db_input($this->getId()) - .' AND id IN('.implode(',', db_input($cids)).')'; - db_query($sql); + $this->getThread()->collaborators->filter(array( + 'thread_id' => $this->getThreadId(), + 'id__in' => $cids + ))->update(array( + 'updated' => SqlFunction::NOW(), + 'isactive' => 1, + )); } - $sql='UPDATE '.TICKET_COLLABORATOR_TABLE - .' SET updated=NOW(), isactive=0 ' - .' WHERE ticket_id='.db_input($this->getId()); - if($cids) - $sql.=' AND id NOT IN('.implode(',', db_input($cids)).')'; - - db_query($sql); + if ($cids) { + $this->getThread()->collaborators->filter(array( + 'thread_id' => $this->getThreadId(), + Q::not(array('id__in' => $cids)) + ))->update(array( + 'updated' => SqlFunction::NOW(), + 'isactive' => 0, + )); + } unset($this->ht['active_collaborators']); $this->collaborators = null; @@ -994,6 +1022,51 @@ class Ticket { return true; } + function getAuthToken($user, $algo=1) { + + //Format: // <user type><algo id used>x<pack of uid & tid><hash of the algo> + $authtoken = sprintf('%s%dx%s', + ($user->getId() == $this->getOwnerId() ? 'o' : 'c'), + $algo, + Base32::encode(pack('VV',$user->getId(), $this->getId()))); + + switch($algo) { + case 1: + $authtoken .= substr(base64_encode( + md5($user->getId().$this->getCreateDate().$this->getId().SECRET_SALT, true)), 8); + break; + default: + return null; + } + + return $authtoken; + } + + function sendAccessLink($user) { + global $ost; + + if (!($email = $ost->getConfig()->getDefaultEmail()) + || !($content = Page::lookupByType('access-link'))) + return; + + $vars = array( + 'url' => $ost->getConfig()->getBaseUrl(), + 'ticket' => $this, + 'user' => $user, + 'recipient' => $user, + ); + + $lang = $user->getLanguage(UserAccount::LANG_MAILOUTS); + $msg = $ost->replaceTemplateVariables(array( + 'subj' => $content->getLocalName($lang), + 'body' => $content->getLocalBody($lang), + ), $vars); + + $email->send($user, Format::striptags($msg['subj']), + $msg['body']); + } + + /* -------------------- Setters --------------------- */ function setLastMsgId($msgid) { return $this->lastMsgId=$msgid; @@ -1271,6 +1344,11 @@ class Ticket { 'thread'=>$message ); } + else { + $options += array( + 'thread' => $this->getThread(), + ); + } //Send auto response - if enabled. if($autorespond @@ -1284,7 +1362,7 @@ class Ticket { 'signature' => ($dept && $dept->isPublic())?$dept->getSignature():'') ); - $email->sendAutoReply($this->getEmail(), $msg['subj'], $msg['body'], + $email->sendAutoReply($this->getOwner(), $msg['subj'], $msg['body'], null, $options); } @@ -1330,7 +1408,7 @@ class Ticket { foreach( $recipients as $k=>$staff) { if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue; $alert = $this->replaceVars($msg, array('recipient' => $staff)); - $email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null, $options); + $email->sendAlert($staff, $alert['subj'], $alert['body'], null, $options); $sentlist[] = $staff->getEmail(); } } @@ -1359,7 +1437,7 @@ class Ticket { $msg = $this->replaceVars($msg->asArray(), array('signature' => ($dept && $dept->isPublic())?$dept->getSignature():'')); - $email->sendAutoReply($this->getEmail(), $msg['subj'], $msg['body']); + $email->sendAutoReply($this->getOwner(), $msg['subj'], $msg['body']); } $user = $this->getOwner(); @@ -1421,9 +1499,8 @@ class Ticket { 'thread' => $entry); foreach ($recipients as $recipient) { if ($uid == $recipient->getUserId()) continue; - $options['references'] = $entry->getEmailReferencesForUser($recipient); $notice = $this->replaceVars($msg, array('recipient' => $recipient)); - $email->send($recipient->getEmail(), $notice['subj'], $notice['body'], $attachments, + $email->send($recipient, $notice['subj'], $notice['body'], $attachments, $options); } @@ -1497,9 +1574,8 @@ class Ticket { $options = array( 'inreplyto'=>$message->getEmailMessageId(), - 'references' => $message->getEmailReferencesForUser($user), 'thread'=>$message); - $email->sendAutoReply($user->getEmail(), $msg['subj'], $msg['body'], + $email->sendAutoReply($user, $msg['subj'], $msg['body'], null, $options); } } @@ -1562,7 +1638,7 @@ class Ticket { foreach( $recipients as $k=>$staff) { if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue; $alert = $this->replaceVars($msg, array('recipient' => $staff)); - $email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null, $options); + $email->sendAlert($staff, $alert['subj'], $alert['body'], null, $options); $sentlist[] = $staff->getEmail(); } } @@ -1611,7 +1687,7 @@ class Ticket { foreach( $recipients as $k=>$staff) { if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue; $alert = $this->replaceVars($msg, array('recipient' => $staff)); - $email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null); + $email->sendAlert($staff, $alert['subj'], $alert['body'], null); $sentlist[] = $staff->getEmail(); } @@ -1638,7 +1714,7 @@ class Ticket { return $this->getPhoneNumber(); break; case 'auth_token': - return $this->getAuthToken(); + return $this->getOldAuthToken(); break; case 'client_link': return sprintf('%s/view.php?t=%s', @@ -1802,7 +1878,7 @@ class Ticket { foreach( $recipients as $k=>$staff) { if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue; $alert = $this->replaceVars($msg, array('recipient' => $staff)); - $email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null, $options); + $email->sendAlert($staff, $alert['subj'], $alert['body'], null, $options); $sentlist[] = $staff->getEmail(); } } @@ -1928,7 +2004,8 @@ class Ticket { function postMessage($vars, $origin='', $alerts=true) { global $cfg; - $vars['origin'] = $origin; + if ($origin) + $vars['origin'] = $origin; if(isset($vars['ip'])) $vars['ip_address'] = $vars['ip']; elseif(!$vars['ip_address'] && $_SERVER['REMOTE_ADDR']) @@ -2013,8 +2090,12 @@ class Ticket { //Assigned staff if any...could be the last respondent - if($this->isAssigned() && ($staff=$this->getStaff())) - $recipients[]=$staff; + if ($this->isAssigned()) { + if ($staff = $this->getStaff()) + $recipients[] = $staff; + elseif ($team = $this->getTeam()) + $recipients = array_merge($recipients, $team->getMembers()); + } //Dept manager if($cfg->alertDeptManagerONNewMessage() && $dept && ($manager=$dept->getManager())) @@ -2034,7 +2115,7 @@ class Ticket { foreach( $recipients as $k=>$staff) { if(!$staff || !$staff->getEmail() || !$staff->isAvailable() || in_array($staff->getEmail(), $sentlist)) continue; $alert = $this->replaceVars($msg, array('recipient' => $staff)); - $email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null, $options); + $email->sendAlert($staff, $alert['subj'], $alert['body'], null, $options); $sentlist[] = $staff->getEmail(); } } @@ -2095,7 +2176,7 @@ class Ticket { 'inreplyto'=>$response->getEmailMessageId(), 'references'=>$response->getEmailReferences(), 'thread'=>$response); - $email->sendAutoReply($this->getEmail(), $msg['subj'], $msg['body'], $attachments, + $email->sendAutoReply($this, $msg['subj'], $msg['body'], $attachments, $options); } @@ -2158,7 +2239,7 @@ class Ticket { $variables + array('recipient' => $this->getOwner())); $attachments = $cfg->emailAttachments()?$response->getAttachments():array(); - $email->send($this->getEmail(), $msg['subj'], $msg['body'], $attachments, + $email->send($this->getOwner(), $msg['subj'], $msg['body'], $attachments, $options); } @@ -2221,18 +2302,21 @@ class Ticket { ); } - function postNote($vars, &$errors, $poster, $alert=true) { + function postNote($vars, &$errors, $poster=false, $alert=true) { global $cfg, $thisstaff; //Who is posting the note - staff or system? $vars['staffId'] = 0; - $vars['poster'] = 'SYSTEM'; if($poster && is_object($poster)) { $vars['staffId'] = $poster->getId(); $vars['poster'] = $poster->getName(); - }elseif($poster) { //string + } + elseif ($poster) { //string $vars['poster'] = $poster; } + elseif (!isset($vars['poster'])) { + $vars['poster'] = 'SYSTEM'; + } if(!($note=$this->getThread()->addNote($vars, $errors))) return null; @@ -2305,7 +2389,7 @@ class Ticket { ) continue; $alert = $this->replaceVars($msg, array('recipient' => $staff)); - $email->sendAlert($staff->getEmail(), $alert['subj'], $alert['body'], null, $options); + $email->sendAlert($staff, $alert['subj'], $alert['body'], null, $options); $sentlist[$staff->getEmail()] = 1; } } @@ -2313,6 +2397,19 @@ class Ticket { return $note; } + // Threadable interface + function postThreadEntry($type, $vars) { + $errors = array(); + switch ($type) { + case 'M': + return $this->postMessage($vars, $vars['origin']); + case 'N': + return $this->postNote($vars, $errors); + case 'R': + return $this->postReply($vars, $errors); + } + } + //Print ticket... export the ticket thread as PDF. function pdfExport($psize='Letter', $notes=false) { global $thisstaff; @@ -2669,8 +2766,8 @@ class Ticket { try { // Make sure the email address is not banned - if (TicketFilter::isBanned($vars['email'])) { - throw new RejectedException(Banlist::getFilter(), $vars); + if (($filter=Banlist::isBanned($vars['email']))) { + throw new RejectedException($filter, $vars); } // Init ticket filters... @@ -2689,7 +2786,7 @@ class Ticket { * * $autorespond and $alertstaff overrides config settings... */ - static function create(&$vars, &$errors, $origin, $autorespond=true, + static function create($vars, &$errors, $origin, $autorespond=true, $alertstaff=true) { global $ost, $cfg, $thisclient, $_FILES; @@ -3051,6 +3148,14 @@ class Ticket { $vars['userId'] = $ticket->getUserId(); $message = $ticket->postMessage($vars , $origin, false); + // If a message was posted, flag it as the orignal message. This + // needs to be done on new ticket, so as to otherwise separate the + // concept from the first message entry in a thread. + if ($message instanceof ThreadEntry) { + $message->setFlag(ThreadEntry::FLAG_ORIGINAL_MESSAGE); + $message->save(); + } + // Configure service-level-agreement for this ticket $ticket->selectSLAId($vars['slaId']); @@ -3125,7 +3230,7 @@ class Ticket { $ticket->logEvent('created'); // Fire post-create signal (for extra email sending, searching) - Signal::send('model.created', $ticket); + Signal::send('ticket.created', $ticket); /* Phew! ... time for tea (KETEPA) */ @@ -3191,16 +3296,10 @@ class Ticket { } $ticket->reload(); - $dept = $ticket->getDept(); - - // See if we need to skip auto-response. - $autorespond = isset($create_vars['autorespond']) - ? $create_vars['autorespond'] : true; - if (!$autorespond + if(!$cfg->notifyONNewStaffTicket() || !isset($vars['alertuser']) - || !$dept->autoRespONNewTicket() - || !$cfg->notifyONNewStaffTicket()) + || !($dept=$ticket->getDept())) return $ticket; //No alerts. //Send Notice to user --- if requested AND enabled!! @@ -3233,14 +3332,17 @@ class Ticket { ) ); - $references = $ticket->getLastMessage()->getEmailMessageId(); + $references = array(); + $message = $ticket->getLastMessage(); + if (isset($message)) + $references[] = $message->getEmailMessageId(); if (isset($response)) - $references = array($response->getEmailMessageId(), $references); + $references[] = $response->getEmailMessageId(); $options = array( 'references' => $references, - 'thread' => $ticket->getLastMessage() + 'thread' => $message ?: $ticket->getThread(), ); - $email->send($ticket->getEmail(), $msg['subj'], $msg['body'], $attachments, + $email->send($ticket->getOwner(), $msg['subj'], $msg['body'], $attachments, $options); } diff --git a/include/class.topic.php b/include/class.topic.php index eda6a2a69b3c9e59af82745855cf30ef5d62c8d4..9daeb7f07dd33b1e6493d4f85dc1b0b062ce834d 100644 --- a/include/class.topic.php +++ b/include/class.topic.php @@ -135,6 +135,7 @@ class Topic extends VerySimpleModel { function getForms() { if (!isset($this->_forms)) { + $this->_forms = array(); foreach ($this->forms->select_related('form') as $F) { $extra = JsonDataParser::decode($F->extra) ?: array(); $F->form->disableFields($extra['disable'] ?: array()); diff --git a/include/class.translation.php b/include/class.translation.php index 67037d2c02fb979d2f3006c96a3733f32f8cc30f..cb8bcee9a3996bce4b494a870cc097690522c0ce 100644 --- a/include/class.translation.php +++ b/include/class.translation.php @@ -576,7 +576,7 @@ class Translation extends gettext_reader implements Serializable { if (!$this->encode) return $string; - return Format::encode($string, 'utf-8', $this->charset); + return Charset::transcode($string, 'utf-8', $this->charset); } static function buildHashFile($mofile, $outfile=false, $return=false) { @@ -626,9 +626,8 @@ class Translation extends gettext_reader implements Serializable { } if ($charset && strcasecmp($charset, 'utf-8') !== 0) { foreach ($table as $orig=>$trans) { - // Format::encode defaults to UTF-8 output - $table[Format::encode($orig, $charset)] = - Format::encode($trans, $charset); + $table[Charset::utf8($orig, $charset)] = + Charset::utf8($trans, $charset); unset($table[$orig]); } } diff --git a/include/class.upgrader.php b/include/class.upgrader.php index 6246e542d0b524b3dec26364297a506d9aab18ce..63fba34d852d31d41c6a970528f4fbe9d35ac722 100644 --- a/include/class.upgrader.php +++ b/include/class.upgrader.php @@ -348,7 +348,8 @@ class StreamUpgrader extends SetupWizard { if (!isset($this->task)) { $class = (include $task_file); if (!is_string($class) || !class_exists($class)) - return $ost->logError("Bogus migration task", "{$this->phash}:{$class}") ; + return $ost->logError("Bogus migration task", + "{$this->phash}:{$class}"); //FIXME: This can cause crash $this->task = new $class(); if (isset($_SESSION['ost_upgrader']['task'][$this->phash])) $this->task->wakeup($_SESSION['ost_upgrader']['task'][$this->phash]); diff --git a/include/class.user.php b/include/class.user.php index 5db55087c1538f53bd2acb0311c3022165d2c7dc..3a5fd1c29e205db10434a235315117b808de74c2 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -178,6 +178,7 @@ class User extends UserModel { catch (OrmException $e) { return null; } + Signal::send('user.created', $user); } return $user; @@ -245,6 +246,11 @@ class User extends UserModel { $form->save(); } + function getLanguage($flags=false) { + if ($acct = $this->getAccount()) + return $acct->getLanguage($flags); + } + function to_json() { $info = array( @@ -716,9 +722,9 @@ class PersonsName { $r = explode(' ', $name); $size = count($r); - + //check if name is bad format (ex: J.Everybody), and fix them - if($size==1 && mb_strpos($r[0], '.') !== false) + if($size==1 && mb_strpos($r[0], '.') !== false) { $r = explode('.', $name); $size = count($r); diff --git a/include/class.usersession.php b/include/class.usersession.php index 1d0b8e0b1862b9c2ddfadac651074415ce6127b7..004eda9ee5e55ac7910990829102720eeaa42ae6 100644 --- a/include/class.usersession.php +++ b/include/class.usersession.php @@ -133,6 +133,8 @@ class ClientSession extends EndUser { } function refreshSession($force=false){ + global $cfg; + $time = $this->session->getLastUpdate($this->token); // Deadband session token updates to once / 30-seconds if (!$force && time() - $time < 30) @@ -140,6 +142,8 @@ class ClientSession extends EndUser { $this->token = $this->getSessionToken(); //TODO: separate expire time from hash?? + + osTicketSession::renewCookie($time, $cfg->getClientSessionTimeout()); } function getSession() { @@ -179,12 +183,16 @@ class StaffSession extends Staff { } function refreshSession($force=false){ + global $cfg; + $time = $this->session->getLastUpdate($this->token); // Deadband session token updates to once / 30-seconds if (!$force && time() - $time < 30) return; $this->token=$this->getSessionToken(); + + osTicketSession::renewCookie($time, $cfg->getStaffSessionTimeout()); } function getSession() { diff --git a/include/client/header.inc.php b/include/client/header.inc.php index 1c3f00dbd0cb09990c64306267527b75a5a67181..34cd76f4056355f180c5af257cf9192f56cc7009 100644 --- a/include/client/header.inc.php +++ b/include/client/header.inc.php @@ -40,6 +40,7 @@ if (($lang = Internationalization::getCurrentLanguage()) <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/filedrop.field.js"></script> <script src="<?php echo ROOT_PATH; ?>scp/js/bootstrap-typeahead.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor.min.js"></script> + <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-plugins.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-osticket.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-fonts.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/chosen.jquery.min.js"></script> @@ -52,11 +53,6 @@ if (($lang = Internationalization::getCurrentLanguage()) <body> <div id="container"> <div id="header"> - <a class="pull-left" id="logo" href="<?php echo ROOT_PATH; ?>index.php" - title="<?php echo __('Support Center'); ?>"><img src="<?php - echo ROOT_PATH; ?>logo.php" border=0 alt="<?php - echo $ost->getConfig()->getTitle(); ?>" - style="height: 5em"></a> <div class="pull-right flush-right"> <p> <?php @@ -99,6 +95,12 @@ if (($all_langs = Internationalization::getConfiguredSystemLanguages()) } ?> </p> </div> + <a class="pull-left" id="logo" href="<?php echo ROOT_PATH; ?>index.php" + title="<?php echo __('Support Center'); ?>"> + <span class="valign-helper"></span> + <img src="<?php echo ROOT_PATH; ?>logo.php" border=0 alt="<?php + echo $ost->getConfig()->getTitle(); ?>"> + </a> </div> <div class="clear"></div> <?php diff --git a/include/client/templates/ticket-print.tmpl.php b/include/client/templates/ticket-print.tmpl.php index 67e24a1700af259f8e802017fd405675527d9dd7..a1173b217b48111ebc8857129cd9c8e4fe74a56a 100644 --- a/include/client/templates/ticket-print.tmpl.php +++ b/include/client/templates/ticket-print.tmpl.php @@ -198,30 +198,29 @@ $types = array('M', 'R'); if ($thread = $ticket->getThreadEntries($types)) { $threadTypes=array('M'=>'message','R'=>'response', 'N'=>'note'); foreach ($thread as $entry) { ?> - <div class="thread-entry <?php echo $threadTypes[$entry['thread_type']]; ?>"> + <div class="thread-entry <?php echo $threadTypes[$entry->type]; ?>"> <table class="header"><tr><td> <span><?php - echo Format::datetime($entry['created']);?></span> + echo Format::datetime($entry->created);?></span> <span style="padding:0 1em" class="faded title"><?php - echo Format::truncate($entry['title'], 100); ?></span> + echo Format::truncate($entry->title, 100); ?></span> </td> <td class="flush-right faded title" style="white-space:no-wrap"> <?php - echo Format::htmlchars($entry['name'] ?: $entry['poster']); ?></span> + echo Format::htmlchars($entry->getName()); ?></span> </td> </tr></table> <div class="thread-body"> - <div><?php echo $entry['body']->display('pdf'); ?></div> + <div><?php echo $entry->getBody()->display('pdf'); ?></div> </div> <?php - if ($entry['attachments'] - && ($tentry = $ticket->getThreadEntry($entry['id'])) - && ($files = $tentry->getAttachments())) { ?> + if ($entry->has_attachments + && ($files = $entry->attachments)) { ?> <div class="info"> -<?php foreach ($files as $F) { ?> +<?php foreach ($files as $A) { ?> <div> - <span><?php echo $F['name']; ?></span> - <span class="faded">(<?php echo Format::file_size($F['size']); ?>)</span> + <span><?php echo Format::htmlchars($A->file->name); ?></span> + <span class="faded">(<?php echo Format::file_size($A->file->size); ?>)</span> </div> <?php } ?> </div> diff --git a/include/client/tickets.inc.php b/include/client/tickets.inc.php index d88ec62d51a78227497452396abf93111a0a9a10..76412f7e3b49e8921a432cc4f65369fcb46d1007 100644 --- a/include/client/tickets.inc.php +++ b/include/client/tickets.inc.php @@ -45,7 +45,7 @@ $$x=' class="'.strtolower($_REQUEST['order'] ?: 'desc').'" '; // Add visibility constraints $tickets->filter(Q::any(array( 'user_id' => $thisclient->getId(), - 'collaborators__user_id' => $thisclient->getId(), + 'thread__collaborators__user_id' => $thisclient->getId(), ))); // Perform basic search diff --git a/include/client/view.inc.php b/include/client/view.inc.php index fe2f1b8aa481d93f4178743bfe4808ce82cda4e8..bc331dee94d8eab2efc2a64d6cbdc72ac74b3de4 100644 --- a/include/client/view.inc.php +++ b/include/client/view.inc.php @@ -114,24 +114,23 @@ if($ticket->getThreadCount() && ($thread=$ticket->getClientThread())) { foreach($thread as $entry) { //Making sure internal notes are not displayed due to backend MISTAKES! - if(!$threadType[$entry['type']]) continue; - $poster = $entry['poster']; - if($entry['type']=='R' && ($cfg->hideStaffName() || !$entry['staff_id'])) + if(!$threadType[$entry->type]) continue; + $poster = $entry->poster; + if($entry->type=='R' && ($cfg->hideStaffName() || !$entry->staff_id)) $poster = ' '; ?> - <table class="thread-entry <?php echo $threadType[$entry['type']]; ?>" cellspacing="0" cellpadding="1" width="800" border="0"> + <table class="thread-entry <?php echo $threadType[$entry->type]; ?>" cellspacing="0" cellpadding="1" width="800" border="0"> <tr><th><div> -<?php echo Format::datetime($entry['created']); ?> +<?php echo Format::datetime($entry->created); ?> <span class="textra"></span> <span><?php echo $poster; ?></span> </div> </th></tr> - <tr><td class="thread-body"><div><?php echo Format::clickableurls($entry['body']->toHtml()); ?></div></td></tr> + <tr><td class="thread-body"><div><?php echo Format::clickableurls($entry->getBody()->toHtml()); ?></div></td></tr> <?php - if($entry['attachments'] - && ($tentry=$ticket->getThreadEntry($entry['id'])) - && ($urls = $tentry->getAttachmentUrls()) - && ($links=$tentry->getAttachmentsLinks())) { ?> + if($entry->has_attachments + && ($urls = $entry->getAttachmentUrls()) + && ($links = $entry->getAttachmentsLinks())) { ?> <tr><td class="info"><?php echo $links; ?></td></tr> <?php } if ($urls) { ?> diff --git a/include/i18n/en_US/file.yaml b/include/i18n/en_US/file.yaml index b6b9ac906fe09b8a61aa32c1c07f46138cc811ee..0464b6a23d6f2e600b2242880089133d65fdc214 100644 --- a/include/i18n/en_US/file.yaml +++ b/include/i18n/en_US/file.yaml @@ -14,220 +14,169 @@ type: image/png encoding: base64 data: | - iVBORw0KGgoAAAANSUhEUgAAAO8AAAAkCAYAAABhX23OAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz - AAAHYQAAB2EBlcO4tgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABOFSURB - VHic7Zx5fFXVtce/69whA0kAgRASJplEEetstc62Sh2rFp+tWsfSoqW19lmH9j2spX2+Dmqdi0qd - eA9BqUN9KNbxKQiKihPzEEJIIASSkOTe5J5z1vtj70tOLjcTAeXB/X0+9/M5e+1pnXvO2mva+4iq - kkEGOwN3xgkn+xq52Qnph+Hj//1O9+UrR2p28d3x+uqz8ics2/xV87e3w/mqGcjg/y+0qWFwZOjF - Z4SKvv2LxGs/36RZRa9Fhk84Oie//7NfNW/7AjLCm8FOw/HqqjReifTYP4rvSnjI93II90AKDjwu - MeOb133V/O3tyAhvBjuNUMPWd6ldugJAcgcjOcUAOD3HhLVh7d3N008a+5UyuJcjI7z7Gv5xTkni - 8UOOcKcOPCU+tWRwt8aaVF3nbVs6R+tX+ThZ28mS3R9xwmHH3/YO//WNId1lOYP0kEzAai/HXYNy - 3H4l/6qOc76TW1IseSP740RAffBd1ebNjX7DunXSXLPMTyR+Fb3ywy86PfaDQ3o35+ZPx4uNCw04 - U0KFJ7bUeTHUi+OWzV4br9l8VP6EDzIBrF2MjPDupah/qKgwO3/oVMkdfKJTdFpvie7Xfgcvhr/l - w2a/flWpk9N/qnPWoDthsp+27QOFeW7P4TeDc4XT77gSp/eh4ETTj6seXvmL6/z6leX47vRIzdon - mVRd183by4CM8O6FEHGnHXSD5hZNCg/6zhDJLupad/Xwqxfi131Rj+8tEHUfdmNba8L+5nDC1UIn - t/DCUN7IMU7hiUMlu38XxvXR2Ab8bSvWeXUrp0cvnntr1xjLIBUZ4d2L0Dy1aKyTN+yPoZKzj5W8 - kQXdHtBPoA2laFMVktVPyS5skkhBdneG1KZqvI1vPBM+/+nx3eZvF0BEfgwcCTynqv/Yif63AYfa - 4mOq+twuZK9dhL+siTLYjZhakpuIFExxBpw+LjzgrAORXRSHdCJI/ggkfwSAAN0SXNxG3LVPrUnE - l/1sV794InIQcGcXuvwC8/4/aMvjRaRQVZu6OPVxwLfs9btd7Nst7NPCKyIHq+pn7dQfBCxXVfdL - ZKtLaPpryTlO7oBfh4ddMUay+/fYoYGfAL8Jwnm7nxn18De9VevXr1oGfhW+7+LFstRriog49T6e - eqo/yb2qasNumL03cEYX2k8BVgIeEAKqgObdwFe3ISIXAOcC76rqw0l6WESut9cK1ALrgHdUdY+8 - kV0FEQkBj2FMprbwEHAh5sHuUYg9NKgkkpX7ULjkjANDA8YNN4pxR/hbFiH5w5HdLLx+/UrfWzdz - hcaqb45OWPelmY5BFoBUrZkVuE6tU1WtFJHRwNeAN3TP9SFvA8ZiUrstwgvciDEhAHoB5wH3ish1 - qvrml8tjBh1iloTc2NjJ4YKhV4T2v3SgRPdLL7UWfs1iwn2/3rU5/CaCeduO4FW9Xaub3pkbyUlc - ymXrurzoi0gEGAWMBhqAxapa0UbbKMbHHIjRmqXAF6o6n4BZLyIlwPpA1xGquj5lrCyMDHwO9AO2 - pJkvy/I1CqPcVqnqqk7eVxgYESBtVNWtgfq+wCFAPvCFHdtPGeMYjOAC9BSRA+y1GwbqVHVGSofR - wEsiMkZV451hNIPdj6anTzpdmg9/JFx0SrHT55hQR+01VgFdtPi1eSt+9QJCA8Z1orFHonTGOupX - 3RG5/NMHO+7QGiIiwE+A/wCCJr8nIrOB61S1KtD+CuD3wICUoWpFZBYwoYvacwywyF77GPM5OVcE - uBX4FRBJ4fsz4PS2FpjAvU0DLrOkZcDxtq4IeBQ4M6XbWhGZqKov2/4/BX4bqD/X/gDK0vq8qrpU - RL7ASPz7AYaKgG8AhcAnwLzknyUiJ2Ns8kSgfSHQX1U/Tbmx01T1tUB5kL2xXIzJviyl/bGqOl9E - DgZOAKpVdWag/uuY1Xgj8Lqq1qbek12xjsWs1u9h/J3OwBORIbZvPvCxqr5vxxwCRFR1h7FEZIzl - s7KT87SNVy4b4NaUzw6H9zvCGXp5RML5HfdxG3BXT8Ppc3Snp9FELe7y+wiVnLNjXXwTkl3YQkjU - +s3LH1jlJaouzbm6bGGnJ2mNh4Gr09BDwHjgKBE5TFVrROQ0jDCkszR6AgW72Ox9kbZ96Kz2BNfi - T7QI7gbgDFXdLCL9gMUYGUoigVkghgJzRGQcMA+4u70J2gtLxoDtmXcR+T7wDFCEMS8uBv4hIr1t - kx9gBDuIa4G/BgkiMgC4JVC+BPgbxnypBf4sIpNSxvm9DelfC2zCmFaISLaITAe+h/mDioC5NtAU - nPM24C5bVODXwOWY1bYjnINZ7aNAI3CjiEy1K2ME+HMb/R7CPJSdx6yL8rznL5nmxRIrQwMv/Hpo - 6Pc7J7h+E4mVD4ETJtT/1E5NpYk63OX3os1bcApGtx5uyyKQFkWv25ZvTXz6m1o/tmHizgquiBwH - XBUg/Qk4CfNcktp2KPCf9nocLYL7MtAXIwBJof7LzvDRBm/jaRFcBf4AnAhcBEylbaHybf+bgBss - rQYjuKW2PIUWwX0LYzYXYt7JJO7D+OinALMC9LmWdgpwUVrNKyI9MFr3E1seDFwPnKSqMdvsaRH5 - EXA7MAmYY2/4zcBQpwLrRWSQqpZZ2mnAq3bcocAE4FRV9Szt78B8EXkhcMOjgRJVvTaF1euB+ap6 - X4D3hRhBPcOWjwKOBs4O+BNPichUOre3+5uqekmgPF1EngTOVdXnRSTPphg2BXgYA1SoavX2Xg8U - 5jVFc2Y7OSUjJJwdQ7IaiORtlWjvKon22ux7bjN+zCMR9yVe3sdvrjrcySke7fQdl9/ZjRYa34Rf - 8wn+lvfRps1EDryxldC1Bb/2c7zSGWiiFid/JIRaMkJ+3RK0uRpnvyNMueKlVV7F3J6ozsj+UeVr - bY3ZCUykRRjfUtUb7fXbIpKDWfwALhGRG4Cg+3YocIiqvgG8bn+7EsH37AlVvSlQnpXaOIAaq4zu - sOU4cE4yo2H956ClMSVplYrI74EfAYMwfvJgVX1TRIJm0MZgHGq78Nroa3/MH3M9MFlVt9nqHwL3 - BwQ3iUeApdY/eBX4JVarisghGNN0PnABLSvjacA99vo64J6k4AKoqiciTwPfpuUB5gf6BHENJpCw - Haq6SESKRCRXVRuBK4G7UwMBGJ/j8DRjpuJvaWh3Y/yh54EngEtpnWO8EqMNWnDtpnpvar/LHT/+ - dGjgxd+Q7CIHrwn1m8BvJiRhxImabYZOhI5FDkDRhjIjsDWL0fhGSxfCg8fTodB7jSTWPLFO65b2 - VkJNIpGo37AmlPj4pnp1oltxQmGnYMyw8ODxDn6zJlbc/4XWlz4V7V3xR8a3PLOdRDCQ815KXbDc - AzgIoxxuwZjURcDrIvIBcLuqvthNXlIxLHDdlbPJgzEBYDAa+2JVfSdQPxRaPdoJInJNG2ONpgPX - LgwMEpGXMSq/ElgBXKmq5YF2I4DZqZ2toK0A9lfV5SLSKCJF1s+7CHPjHwAzaBHeQ4CP7fUBQKP1 - A1IZrwmUq4OBCwBrrocxf0Aqaw7mAXwGDMdEE1OxJg0tHcrS0JYD+9vrZ4BXsMJrI4wnYxayVsid - UFXROK3fxayd8bjTY8jhTtFpvSXSs91o8Xb4CfzG8pjWr6rQhtUNGt9cpIkt/fBdoxXDJt4jWX0J - D70EyRve9ljq41cv3OBWzP1UE1X3ZfXaOIf1A6OJHHdspE/lItYPjCYK5ErpMfj28KALHY1vrHGX - 31PqeXU3ZE+o3FVaLnja6KOUus8Alxbl0ldV59gX/S5MVgRMmu8FEVkAnN8JP7RD2Oc3MEDqSk76 - 1gDPAqTuchuaUm5vl1nvdurATlSmqh2FFrOBbW3UbcMEDMD4IqdjtNEZmFWxWURURPrbdssCgYVe - QAWtBRXgNYyAJJGq8ZN9a9P0BfgdLX96b9suHd+dQUMaWhwbHVXVBhFZYgMrH2EiiC+n0fQA2A0K - 32qc1q84XP3eNUQLDnHCPfuSMyCPUG7EQfFVBXUdvEYHL75Z3W0Vmqgtpal6gfiUqhOeJOGsS0L9 - T8XpezzasBZ3zeOECk8mVHJ224cE/Ca8zfPifs3n70us9Cbx3Bgqpye2Fl2vPdw89fT7jFfPnTbi - Ful/ynfCRaf38avfX+qtm7nRxb0055rK9ekH3ik0Bq5Tjw0W03oDUQWAqj4mIi8AN2HM7mQA4Bhg - JiaY2S2oqisiMVqi350IMmxHGPO+JPs+ICILVDX5LgdTUQlgMkZDp0PqgpZ2ss5gMUbTpFPj+wPJ - vNcc4Kci8iEm95bM+c0GzsasRnMDfddhcnrzO8lHEOVANDXNlQZlmNTCihR6arqhLfRjx9W3mNYa - OZkS+AhjQt9CB7BCfHuy3Di134Cwhnt7vsa9LC+e6+Q1csWa7QtT08PDRzl5B0xwsvv8THqOPcAp - OCDk1y3Br3gZor2IHDwZiaR/z7SxLOZu+t+1Eltfpn7i3yI/+Hghdw3Kac71bka4UUWei2b758Wb - so9xZ5z6cGjUT4+U7MICd+1T7/pbFr0U7VX+h0j3zeRUrMBYRWCEL4jU8vZnp6pbgJusj3gH8GNb - dbyI9GkVZ9h5lGJMdYCjaB3HaQ+LMQHOezH7JfKAmSJyjN12GVRIEWCBqnZkyQSFu5WV1lnhnY+J - Lr8aJIrISMxOlS2Yi49FZH/gm7R27GdjzJ0G4N8C9DfsuF0WXqvRN4nIEaq6qJ2mCzCRylThPTFN - 23Q4AfNQgvgOgQdq01hTRGQ/TMqiU0n8IHInVFVgNQwAsw6Oeo8fdBZZff+FnEEHREZcPtrJP6BA - Y+X4Wz/Gq/0c6XkgocHfZcfsiaL1qxvcqnmlGi8vlfjWZyOx2lmtjuL9vCwWhcnxR4unOb7+qTkm - 9eG8kg3h4Vf28betjrtr/vaqX79pUtbE8mXsHszEPBeAU5PP0QZLfxxo96a1bs7BBAE/AFDVWhH5 - bUrbVvnYbmAhLcL7CxF51b7bDnAYxq38SZp+01W1zJr3R2MUxNcwLtV1lueFti459rzgXgoRGQaM - VdXnLSnoLp4gIjmqGhOR/gIsUdUDO7obEfkLJtE81ZoWw4AngVtV9a1Au0cwZtDZwU3e1txBVc8N - 0BzMgjALeDSZI7bBrvLkKioiS1W1df7C0A/DBLUmquqHlpYFHKGq82w5H3gHmKSqb1vaoRjTq1BV - T2vnnl8BqoG/qOoCSzseE7A6WVXrA21vxATA5qjqEx39n+2h+eHi852eB98R6nfiEMkfmaVNVfhb - FqGNZUjecJw+RyORVHdK0W2rtrlV75ZKbEOZ21T992yXZ5hYujXtJCloerBoGCHnPDvUkqzKirlM - Tm/67wrYIOdCWk7kgFm8+tIihB5wmKp+KiKPYdJIFcBSYCvG501+DWSFqm4PXsqOO6wGpdlhdTiB - TRqqGrL0oXaO4DazzRgfNop5NwfatnNpOZjwS1X9o6WfjnEjkyvrd1X1WfvuvU+L4qwAPsS4poMw - Adj/UdWz7DhnAi8F+Ki3v6Kw/QM7gxswu2FmikgvzIowUVU/SWk3Ezhedzyd8TQmmr0dquqLyLcx - u1hesblTFxOwmBJompZHVf1IRC4FfmMflovxj5/DJLlR1W32j/ydiPza1i/HhOw7+kjay5hTJ7eL - yK1ADsbUHxcUXIvpmFxduk0HXYKgp4SHXd0PcbLc5fdCtBehvschxakbchR/26oav/q91RqrWKnx - ytnR5vhLXLupvqsnTrImVq6mJRe+26GqCRE5DxPwO8qSg67MJuCHqRt8bJtUl2cLJte/q3hba9+r - vwLJrxj0DTTpcNehqs4VkXuAn1nSIyKyyGrwC4D7McI6ADgrpXtwf8AcjGV6rC3n2V/mPO+ugoic - AVyoqhO6O5b72JhnwmNvuxA/gbfxtZStiorWr9nsbflghTaWLfEby5/J0vX/ZIJ2b0PIVwRrfZ2J - MaGLMbGMz4BnVXVzoF0f2+5IjBKIYuIOnwD/bdOCwXHzadmzD3CnqtaltBmAya2C0by3p9QXAd8F - DgRKMNr3U+BxVa2xbS6jxXefm7T4bF0WJnWUXEs/VNUXbF0PO/ZBwEiMNq0E3gZe0dY7FaOWzyMw - VsliYHFGeHcRrFsw2UacdxqN0/oVRwuOnhHe/4oTtHkrWr8KZ7+Wg0/e6sfqtG7xBeGry1+HzMPb - l5H5emQ3YM18rPmn3RVcgHAidILT+8ghABrbgGT1bVXvew3V4avXv5YR3Awywts9nCUib2LMn6s6 - aNspSLT3mU7BqMEAum3lDsIrSGcPVGSwl2Of/pJGd6Hmm0dd/u5Re5CcAcPNJgvFr19FKHxeYEIX - /HhqACeDfRQZzbsHIf5o8RDpOWYggFf1DqTsi/Brl7g0bZ6btnMG+xwywrsHIZxVdGGoz5FDtLEc - v2JuAzklS4L1WvPxlrDWzGurfwb7FjLCuwdBw72OcNe/sMktffoR3Prjw30Obzmb58XQ5rp5XFXV - 2T3ZGezlyAjvHgRpKP0kHP9gdOTS+T+UnKJzJG+UPbmkuKunVboNS29of4QM9iVkAlZ7EMJXr0p+ - NQLJLj4m+f1lr/Kfzeo1TMm+prKzxxgz2AeQEd49EE0PDxwVGTx+lDbX4G94cZ021zwTueT9+79q - vjLYs5AR3j0Seq638S2PileedN26W3OuWb8rz9FmsJfg/wBsHf7rZZG4/wAAAABJRU5ErkJggg== - -- key: 6fe1efdea357534d238b86e7860a7c5a - name: kangaroo.png - type: image/png - encoding: base64 - data: | - iVBORw0KGgoAAAANSUhEUgAAAKEAAABbCAYAAAAbWOXJAAAapklEQVR4Ae1dCbxU9XU+d5mHIIss - sggIyioKuCGgIKBCg0uJZmnTJqkmbUzTxuyNWdyiaYzRtDGkUWObJjatNWo1SWMFRQRBQRaVRRbZ - kX2V/d2t33fuezAzb96bmTd35s3Mu//fD94sd+5y7rnnf853zvn+RoAh8Ygl0IISMFvw2PGhYwmo - BGIlbKWKEDjHsl55cHin+LvfzbpdoRvYhe4g/n1lScDfvULcJY9LsG+dyOlnijX4erEH/IlIol3K - hfhb5ouz5DGR4wek5tqfi9GhV8r3Ub4xYp8wSnGW/76cN34sYrURs+tg8d59VvztS6BgvcW+9G/F - GjBZxD2uSuqu+Z3UXPWP4m9+TfwPtkjN5B+JGMWZOGNLWP56E+0ZHtsvRpeBYp07Waz+V0lwYIN4 - G14WZ87d4q16VsQ7If7WNyQx5cdinnWpGF0Hiff8LeK994JYg66L9lzq9hYrYVHEWsY7NQwJDm0X - CTwR3xHjjP5iX3Kr0P/z3vm1nrg18lNiDfyQvjbadBJ75M3iLnxYzN6XidHuzMgvrjj2NfLTjHcY - lQSMtl3F37MSCggl5PBdKKQPqzhBp2mdmi/8bPhd3f8mrKbYbaGI01M+j+pNrIRRSbJC9mN0HiAC - q0ffD05eeNaEitucAWV0xTz3GjE69km5GiPRVqyhN4q38rfibZ6b8l0Ub2IljEKKFbQPo/sFEjhH - xd+7GpYvkXTmUEQELBaUMNOw+k1EBH26uPMflAB+ZZQjVsIopVkB+zJh5Ywz+gkhmJRoF4pptO8p - RrehGa/C6NhbzDOhwLuWq38oESbaYiXMKPIq/tC0w6l1zR8kOLIbimjhH4KVI7uAG/YQ47TOmS8e - vzO6DVHr6a18WtzVz2ferhmfxkrYDKFV+k+sAVPCQINgtAWABPiff3CzGFDCpgahHbWeXq24836o - GGNT2+f6XQzR5CqppO3oUwWHtonAegTH9kmArILUHsYWfriV3Q4WpSP+dRFp1y2c5vC3XIZR00Hs - y/5enJe+oedmX4Ro+OguYQDS1DBO766W0Dr/z8TbMk+cl2+XxHWPiNn53KZ+lvW7OGOSVUQIGpFn - DQBr+O+/Kf7OtyT4YKsIpiexTxMD0IXUnI7XSHsxowDsTZwjEpw4FComFJYQiEFlhL9FrI2+Ff2y - lh2BnHjuZgkATFvDPwHYZpWYnfpL4pr7Gz0tf/96Cfa/h+BlilrB2j9+QYy2XSQxdXpBihgrYaMi - hz7BCffWviD+ptlQxCNinnGumH2gRD0vBozRO/Sf0nKuJ3cHxz2gdTy+X3xYzWDn2+LveEtvtmA6 - Y9rMxLRIfM5of9bJn5XiBR8id9G/6LWJi4eEabyeF4k18tNinXN1zqfgb18szsyv4+GzoLwPiNnr - 4px/m7xhrITJ0uBrKI+35TVkD/4Dlm+hGJ36iTXkBuBnk2Epzk7fOu/3wdE9iDCXibdupnhb54uB - zIV59gRYo7+AhRyW9/7y+QEfJG/Vc8gNwxc8uFXTd8QFrUHXismomEFKniOAL+nMvRcP2NtiX/w3 - Yg37OB7OTnntJVbCJHExme8ufgTwxeti9Bgu9gV/KeY5V2X1lZJ2kddLKqS/YZa4yNkGmOqsfldq - Cs3oMiiv/WTbOHCPiQ+ld9/6pQTAB2nJzaHT1OpxOi14wAXxVj2v+1fAu89Y5J2R4uvUF1a+F1yR - rjhEHTCe4WCxEkIoPsqavKW/QJL+/9QiWHDUrf4T4fclg7kZpBfVRx5uIqyv+/avoCRrFEKxh3+y - 4PIpBk/e+hmolnkuDDz6jhN72EdUCVOB6mguJDjxgfg83to/quuhe4W/zHwz/WCzzxgx+14OS4ns - TNJo1UoYHNuLG/9r8Zb/J+CJnrBCn0M5E+AL+EgtMpDP9Ta+An/tEQkQrdqDrhdz4FTcwPPCQCiH - k6K/R9/Tg4WlHyrA/XhNnHLT03E57K7Zm/gHN0mAmcXbtkjkwEb4xe+LsIIHAZk97ttiQSHrR+tU - QvhhHsBa583piGSPiX3hZ8QG7KBRbr1kWvIvpk/13ZY/qVAQC0rNnhfCSkMZCSjXtA/9N0yDtD7B - kZ0oUn0vTMURgG7TEdPhKFU+s/twRO4t9FDVyxBFEsHxg8hXHxV3wU80/ZeYeE/9t/CLW1mjUwAo - goWdDDqswTegmPPzWtR5UiLl9AIPiL9jqXiMznetQHEpoCHFI5HnZRBBmAjYHv06BlBUOLP3KETx - 5+Dz1Erpcrgswla1v/2omKjmTlz2xZOnhKtoHYNPogefy33nV2J0Hig1BFmTpoSylAIUjD4U/7H0 - KjgBa0KgHBCPQUyyXgkBPotVU5aXkHxS3or/RmZmo9iw0smjVSghy4/c+T/Swk370i8Inf4Wn6KS - 70Iur01LLZ7Q6uWyfZlt4+/fIO7Sf4UvOFYsYJLJo6qVkAl6BWXffRrWZJwkJj8EkDha+CNZmPHr - zBIgPunOuRcYrC/22G80MABVq4TeuhfFQe0bnWF7wl1iD7kR01f+YGxmscaf5ioBtg04r96N1tFl - MAIPwm89v8FPq04Jg8M7xEEE5qNbzEQKyh779UgyHQ0k1xo+QPW1v2MJAiLCKyjUYB4c/qgCz3QP - CGUx8uZf+qT0UVEWpi0D9F0RtXvvzRCjTQepuf4xTQ1mEltVRccESZ3XHxTDrRVr7FfFHvphCAUO - fDMHCz9ZRWwNvq6Ze6jQnwFSIYSlGRZkcgSQkGY/mF2px1DRlSe1UDQH+XEqXO0RzDrHNIDijKMw - EuAkq98EsUfABwds1NioCkvIzEBo/X4P63eN2Jd/Ddav8CoVDzidIF/cmpQwALDsvIZ+462vi4mS - fnv0l2DBRkKpoEQp7QBQKfh4gmwPK4cCVg95aJpiOZtG7olQEWkds4zsW2TZQUt/7a35PazfQ2Lg - 6bUn3QvrB9+vAOtXfz20gB4yDnafVDih/vtq/OttnC3uK3co9lgz9WdQwiubvkzKWYHwNgVF7BWr - hExPOQv+WXxMwaxwsTH9RmH96qXub3sTftDekpdZ1R+/tH8D4KdPoFr6ARRujEBZ1g/F7Ni3ZKdQ - eUrIlNvq34lLOgskDmxQVdhDpoUOcWRiC1B18qJG0wazDyUfuDAdJUAE4c9xJvGghCxZs8ff0aDA - oNiXX1FK6CM/SuXzkeS3BkwVa8xXYP2if2JZVuVtmoN0Xh8xUYpU0uGeEI8pxbORJWlGfV8+50oc - 1Zn1LfFRZGBfcTty6DdH4srkcw7ctjKUkCQ9CBIIPDPcT1zzIIKFa3H6xbEULpq8WevHWkLmZks5 - nCWPakVP0RUQD3TtjK9iNvGk5oZfaMFDKa8z+Vhlr4T0zZw3/gllSctQtfsRsUehr6Fd9+RriPQ1 - awt9FGgaidO0HyTSnWfZmbviKZSVPSk1N/0my5aFfe0h8nVnfUfMHhdi+v1OXdFpYfss5Ndlq4SE - XdzFj6Eg8xmg7MMkccPjKDgYXci1Zv8trIL75k+1g0469sKUOD77byLawlv7v5raMnpdlF+ApaDw - 7pwbp1z2DMOlsUd8GhVEt+LsizOb5COWslPCAFOv1tJh6qWA7Cu+iVq/j50CSfO5ujy39VY+g8rg - l3FYQ/s+tMUxz300Z3OFmeZ8D2DvcSg+YJFcISZgcw5K9q2BKFjNdmDgee6in2kRb2L8d8U676Zs - vyjZ92WlhD6CARaaar/FkA+jceavtS+2FNIgJ5/zxkM4FCJToPv2+R8vxWGF/qf72g/CdJgWo16a - 83GdBQ+rT2d2PqfJ3wRHEYDgGD46B20Uk5aTAvLEy0IJ/e1LtQPM37YQAOkESUz8Xtj91aRoo/uS - Clj70jeRhkLqCXV7FuhzzTMbJtqjOyL2hKnfobuBUv4wywADCJ4Y7XrL4UDE9Vik0ebGJ5rc2kcx - rPPqXVpqz5bOUj1cTZ5U2pdQQmBie9fqFMSGFG3mZnom1ykhbYe5vtUOMDSTk26M/avsWU1c96hY - YAct2UDaiVM/882CMnnOaUaHs7TXpJjnwJJ8slt5q57BAXELCMVgKtYiWzTUZxveuhn6ez6sTVF3 - eGvgZ4KuIzi6E+lH9HaADLMcByUgAZpSXJTb8DWnIl4YyRJ5Q4z2eE2OEpBsq5KybJxdaPmWRSHh - HRzdq0wG3rbFwPpma6Ww2XsMiLmRIkordCymsILaQ0qJq5zNoLPggxhCIqh3Q67UKGK2wEc3nYPa - umA7GoC0GrrOm8Nrq3f2wIttqc6sb6MB6kMAl/80o5gCyNpd9HPxQJBO+l/eVzKvsv2yHIdOx+Qv - Dg5uEZc5WL0BsI57VohgemSCOiCNBUt0qHxo11NlZEVFW7xmYhuKaSCHGPB7yhQN5AZAV+VsIU8L - OFvYfSXwTQLkeMmFwk5/E85xoTwmOQuVvbdkVCARODiamajXBLwm5ZEDxc2yRt7S6I3N+ThNbOiB - ycol3EQGrPpqFG5P+ZImBIUCTQ0tLpgJ/hjcowQCNi2bSvsBqYAdBDn+plcRMffHw40GqZ6XILV5 - ddqW5fM2pZTLmYcSeBQf0nk1cQECRWJtGBWH04WW66DRRuktSB9BeIDrYYDhk4qnN1WtCm5qQKU1 - oXCnoxSoA0BmdOWDUIc9p1TYlJtQJHmQqIh8eh6wRn/zHAQ8G3EdOF+15DjH8InRoMAcPE0Sk+6B - QcS5RTxUMcD57CPdqANyCQefWH1qVT4Gel4MTse0kPwHORkm//KzhLoODDJqCFeBRiR9+FsXiDP7 - DlyfLQm0VSotRxk2PKWfd4oSqrM85z7csLlhbygzBpUylPvlkK7PQfIiD9MWO9WELZAsM2JJkboQ - vOl1g6VICBCsoTeFoG0O/lj9T3P5yxmEisc2x+Dw9nAWYbsmFD18sPEgs0iUJVD8iwdEP+d5wSc3 - eM5sYvLxHR92uEU1Ux9umN1AMMXGeWfhT8Tqe4UkUEnelK+Yy7mXcptUJeSRIQC2RHpoCjexZIB9 - 0WfEjJiWIpILZDtkXb+t9tySNYurD6HyhW2ROu3T6sKvDdnqcaPV6tQdndYd1sa++HNhIBJxIObv - fAfA93QEXUvF7D9RaXhNUPXqjIBjgS5JZxkuVsMcLsvgg+M4d7J58dzwQOi5s08G1CQGrLc9+QFV - smT5cWp3XrtfyHxggQsmgYySWvrkjcr8dUMlrDthjRrnP6BTsjXso/CVpoXN1/QNSznok1KpDm3F - dLpBMUTyLQcH0OHPm0YLQec7SYnogLMWzgLW6O9dhUzEfaesIN0GtkwCW2PpvxWxtSdBkPvWv6PS - 53mkxUaEJWZsQG9kaBsnvlPlTNuGTArOC19UK66sV+gpTh4apLzyXcjhgFo/QkuVOBpVQl6MBitY - 24IC1RtHoSKgMIDlmbAwYXQX0WVjSuF05GPaomULABv5B8CHh9WEgqP7YB08+JcIgECjxgVemFMm - b4tGtTrdoqQc2B6BWKv/JA2euL8Tz35SSYB0OuaUh6nQOu9GhSuinLJUVsueCP0+PAT2qL8LadYy - PLRUGmKTxEWNLoPDyDWNn4U0HkpiCbb9xNWo70sGpDFbuUv/DdzRPw0VnT58gUSVEd3FZu2mSSWs - 3yPzuGQs4JPnb1sAaOUQfI7uSnJjdB0IAQwUIZyDNTIMxRiBe9EyhT43dkPfC/8Y5KD/gxwwGilz - v+QoQSONf3gbPsPn9ItAOGmC+sIgH2CXASKM8lBmr4ULvAFsYl/6eIjtYdoy2cuKDIfZ5/Iw6MER - A1hQgrT+qv8Jz0VMZSewL/l8pIUJJI70lv1GfJApkfeF5VBkGNAAo16AsNShDIGLvr8gpJxr1wVs - qV+Cok7CVqmzCzmha+d+X1m6Elfeiesmq1U4tJWB2Y/1M8VC74Y9+st4OOFnVvDISQlTrg89pETh - lfAR0wWZO7ULi9McQFdWn2jJt0G4pk64tHL0czxE2FAOlTm3pc/GiBmQg1JXQNFYH0gISCPCpCmW - 5+DvXgmIA9XUG2fpDTf7jVcOGfKuJE/HWnUNMNhHUYD6VoAp7BGfCmnecuh5SLneTG8QzPjbQCO3 - 8ild+41cMfZw0MhhOqRCEA/1961R14HW2t/zLmaVzeFDA2tsohooAVdArzNp/2RW4MpJ3vL/gq96 - KxT6FlhuyLFucJ0559V7wul3PEiF2MpQBSN/JUy/aFouTJfBkR3amSYn4Gg7WKhFQVJsTEWik01a - XQLhJFAkiwD/MRrNBonA8im+B+Ysb/1L6juZ4JCxyFZFNvmkwRpArs/mguCSDr+JKhgb/qyBiNEg - 5FHgUOXa8JJWdrPAloGGdcGfh0UH2msRHsDDw+mi9SDYPC984PQa8UAyuBhzm1awJD80/JWPfhYH - LBEMrBKoblbqj/rzhbvhLn4UADQCFPiXjH5zTe/V76Kc/xauhMW4OlgEkv8wq0J8j6/JSMVlUTn1 - GlDmk4NVN7jp7DXxwfHHYQ5ANmEQlBRKEmqBfty8/xD4eNuBMyL578GPI/ZpoaOPZEqaX6639ml7 - 5+zgs2wK1Bfsv+UDmJh0H/LSU05tCRyWVlJXSkL1DlfZtEfflmIhFaDG1MzuNwuWkfR1BPuraZSH - EkLpCFN4aLQOmNJDREtLZpDXGdbMAoVHynq7VFLePLCPEtMMYH3N7iOgeKC9pV+YJ11tgxtKBQLE - 4sHq8eYHxz/QAIC+npXn/lkRpFQkLNlHxG607YbDAaCBxdOpGrAS+a81Uk9ZTQm0xQgInfnIYuF6 - EuO+Bet4RYNTrYYPWkYJMcXSOvjvL0Kwg3/gcCZOxtJ95pDNs8cpIJtSz0fFg3JySvYxzXFqDMnH - sWQqp1tG6wUMKoUGXkh38S/xOn0ISDDJhwCKUsigQrsoveK1GnSKFYhur9Ytwd6OJOumGCNyv0QA - rAs+Aaz2s+o/F3L8cv5t6ZSQvh2jYER1zGsyyIAnFAYl/SbCwoxWfycl0kMQQ0zQ429o8QDMMhIn - 670qaiFE5gywgDv6Gq0i4gdvITLeWsVt9r8KxQRIoXXqg3OsC64iuItKXI51g73lT+F4ANbx0Gk0 - DWiJxw4ASfmb5ir1BnmludaIklxGcOxy3kXJlJDWheteKN5Ihx5+lRI6MhuTHLEy8iSHNBWPlLeA - cJiI59oZBKBNrlLZiB/WpKBpfcFTQ6WjbxcgpaeL4CBCt7i2CKwdc60p1rfJHTb/S1aPs8MtQAWP - h3VRSKOrEBasIRn8dWkJnE+zrrP5p9VivyyZErKC2IOTXoOFVwwCq2nwC5XNWz8LlnIGrORyTD+d - FfKwEGSYPRBgNKf9kVM4fDJWbDNo0bQeFJi9xORI0UWkcdONlkzy46FTKg2m8fgwsriilQ1cdWkG - ozyDN5zroyUNTrMuezuwpoegzs9gB9iEu1VJ0lnek37W+Mu6KZzlWuwd5nHJRU1iRnvc7WLR2pGn - Ju0haHyHRf6GD5eNf614lE4JYZGMDNx0zLMShjGRarPQAaas7snTcy43B0A5U3xcq8NjrSBSfazP - YzRpXnabRrZG28657CnepgUkUBIl1OJWZAysYR9rcIlM4FuoZEmM/Vre1onlUcyxarCDIINV4Mwb - 61oZ3WB17cIB6gYnHH8QuQRKo4ScEgHMmmlTsaby2FuBtFrO0yMxPGBuLti4uDyXrtOBShj78n8I - MyjN8R0jF2u8w3wkUBIlZNpNuPQqlypNGlqhjZQUVxzPNljowAJRTrd05Bkp2+geM1ijFyteNvGV - 9felUUJAEboqEXPFyQMrYGLOzAmI9RZiVcpVT6Os6X6Nmls0ok2+hvh1wRJAdUFxh/Z57F4BOGRs - gwOx4EArbnIoRQq8Y8iK9FEMLVbABqKs6A+KroTE/NggxSrj9KFl96gwMRI51MOdOKzTdhTVMOnn - Eb9vWQkUXwnBJciq30y5XX/fWiT0AZ0k1cw1Jo6AUzf7ZlshmNuYTKrl86IqoZYzYe1gZiZSUnN1 - 0gswTee08iQyHwIop5JL2KtFYYpxHUVVQlZgE8sjv0z60FImYHu58EwHXEMDEA9bCeJRfRIorhKi - DJ90IpmW8iJsw3Iuo1P/rFLVnl1COexliUfVSaBoSkhmBuaFTfKrJMDCkDZ81AVqT0oOdYA+2jvD - fpQeaXuJ31aDBIqnhOCyYRukmVItHIqMHWNcM0P9QfDZZBtcwZx9wkopkm3j+PuKk0DRlNBDcSYz - IZkW1GNZl7BOENXKKf0imcSnjU7LAPEgtRePqpRAcZQQ/ptOxWxKImtX0vBRwczFlxktE3zOVifo - HwDrAopRi85XnXSO8cvSSqAoSsjK6ExTMZvmSVurfDHA+zSVl+V6yVRALFEb7LNsG39dmRIojhKC - eVUVJylLwkDFnX0XenExTbOoFP0VRrehTUsNdYIeejLYQUcOxHhUpwSKo4RcIZKNS3X9wWSCddBf - 4m2dJ9YYLAEL9nhmULIxh2rKD03mFtjB4lG9Eoi8ikYZtACpcJ0MXSkTXDC6FglYSNtMuFP7O0jm - Q1+R1c9NDXfFkwCoh2jzT1Pbxd9VtgSiV0JUUOvUi+AjQFDBqTdx9Q9OFTAg2mXvMFs8mypkZasn - y/UTk76fMeVX2WKPzz5ZAtErIauoj+5CS7ELThVS1qay8XOlgGD/OjHHfiX5PFJfQ1HdhdORaRmC - 1tCJqd/F76pOApErIbG/mmm/hPJdklFYhG7oK3KabWy4q59Di+Y85WaOq2Yak1L1fB65Epo9RjYu - HZ2KZyKVN+pk0JK+MXPKXHvDGvlXIfF3+gbx+6qTQFGi48akxDU8dMmwRmhtA+CLzotfVj6aBMgs - 49E6JFBaJWQqj2yu4FlJHyT/qf0DaM/AUJ/Aau5a9p++Ufy+KiUQ+XTcqJRAd0FmKnPgFEzFp/j1 - COO4YCb1ljymxa+MpEmgGY/WI4GSKaG/ZzU4B/eLDUb94PhBZUnQxnX2D6OYgRRo2gAfZ0Zaj/bV - XWnplBCERCxidWbfCW7BPVDCrcrJpwsrYqFAs2/DbrxWdzda6QWXRglBnM5Sf1K8kQzSAnZo9BgO - RobBALP7tlLRx5ddL4HSUMNx6QjQAetSCBEQmNeffPy3OiRQGiWsDlnFV1EkCZQUoinSNcS7rXAJ - xEpY4TewGk4/VsJquIsVfg3/DzCNE81QZqVqAAAAAElFTkSuQmCC + iVBORw0KGgoAAAANSUhEUgAAANoAAAAoCAYAAACYR+TJAAAKQ2lDQ1BJQ0MgcHJvZmlsZQAAeNqd + U3dYk/cWPt/3ZQ9WQtjwsZdsgQAiI6wIyBBZohCSAGGEEBJAxYWIClYUFRGcSFXEgtUKSJ2I4qAo + uGdBiohai1VcOO4f3Ke1fXrv7e371/u855zn/M55zw+AERImkeaiagA5UoU8Otgfj09IxMm9gAIV + SOAEIBDmy8JnBcUAAPADeXh+dLA//AGvbwACAHDVLiQSx+H/g7pQJlcAIJEA4CIS5wsBkFIAyC5U + yBQAyBgAsFOzZAoAlAAAbHl8QiIAqg0A7PRJPgUA2KmT3BcA2KIcqQgAjQEAmShHJAJAuwBgVYFS + LALAwgCgrEAiLgTArgGAWbYyRwKAvQUAdo5YkA9AYACAmUIszAAgOAIAQx4TzQMgTAOgMNK/4Klf + cIW4SAEAwMuVzZdL0jMUuJXQGnfy8ODiIeLCbLFCYRcpEGYJ5CKcl5sjE0jnA0zODAAAGvnRwf44 + P5Dn5uTh5mbnbO/0xaL+a/BvIj4h8d/+vIwCBAAQTs/v2l/l5dYDcMcBsHW/a6lbANpWAGjf+V0z + 2wmgWgrQevmLeTj8QB6eoVDIPB0cCgsL7SViob0w44s+/zPhb+CLfvb8QB7+23rwAHGaQJmtwKOD + /XFhbnauUo7nywRCMW735yP+x4V//Y4p0eI0sVwsFYrxWIm4UCJNx3m5UpFEIcmV4hLpfzLxH5b9 + CZN3DQCshk/ATrYHtctswH7uAQKLDljSdgBAfvMtjBoLkQAQZzQyefcAAJO/+Y9AKwEAzZek4wAA + vOgYXKiUF0zGCAAARKCBKrBBBwzBFKzADpzBHbzAFwJhBkRADCTAPBBCBuSAHAqhGJZBGVTAOtgE + tbADGqARmuEQtMExOA3n4BJcgetwFwZgGJ7CGLyGCQRByAgTYSE6iBFijtgizggXmY4EImFINJKA + pCDpiBRRIsXIcqQCqUJqkV1II/ItchQ5jVxA+pDbyCAyivyKvEcxlIGyUQPUAnVAuagfGorGoHPR + dDQPXYCWomvRGrQePYC2oqfRS+h1dAB9io5jgNExDmaM2WFcjIdFYIlYGibHFmPlWDVWjzVjHVg3 + dhUbwJ5h7wgkAouAE+wIXoQQwmyCkJBHWExYQ6gl7CO0EroIVwmDhDHCJyKTqE+0JXoS+cR4Yjqx + kFhGrCbuIR4hniVeJw4TX5NIJA7JkuROCiElkDJJC0lrSNtILaRTpD7SEGmcTCbrkG3J3uQIsoCs + IJeRt5APkE+S+8nD5LcUOsWI4kwJoiRSpJQSSjVlP+UEpZ8yQpmgqlHNqZ7UCKqIOp9aSW2gdlAv + U4epEzR1miXNmxZDy6Qto9XQmmlnafdoL+l0ugndgx5Fl9CX0mvoB+nn6YP0dwwNhg2Dx0hiKBlr + GXsZpxi3GS+ZTKYF05eZyFQw1zIbmWeYD5hvVVgq9ip8FZHKEpU6lVaVfpXnqlRVc1U/1XmqC1Sr + VQ+rXlZ9pkZVs1DjqQnUFqvVqR1Vu6k2rs5Sd1KPUM9RX6O+X/2C+mMNsoaFRqCGSKNUY7fGGY0h + FsYyZfFYQtZyVgPrLGuYTWJbsvnsTHYF+xt2L3tMU0NzqmasZpFmneZxzQEOxrHg8DnZnErOIc4N + znstAy0/LbHWaq1mrX6tN9p62r7aYu1y7Rbt69rvdXCdQJ0snfU6bTr3dQm6NrpRuoW623XP6j7T + Y+t56Qn1yvUO6d3RR/Vt9KP1F+rv1u/RHzcwNAg2kBlsMThj8MyQY+hrmGm40fCE4agRy2i6kcRo + o9FJoye4Ju6HZ+M1eBc+ZqxvHGKsNN5l3Gs8YWJpMtukxKTF5L4pzZRrmma60bTTdMzMyCzcrNis + yeyOOdWca55hvtm82/yNhaVFnMVKizaLx5balnzLBZZNlvesmFY+VnlW9VbXrEnWXOss623WV2xQ + G1ebDJs6m8u2qK2brcR2m23fFOIUjynSKfVTbtox7PzsCuya7AbtOfZh9iX2bfbPHcwcEh3WO3Q7 + fHJ0dcx2bHC866ThNMOpxKnD6VdnG2ehc53zNRemS5DLEpd2lxdTbaeKp26fesuV5RruutK10/Wj + m7ub3K3ZbdTdzD3Ffav7TS6bG8ldwz3vQfTw91jicczjnaebp8LzkOcvXnZeWV77vR5Ps5wmntYw + bcjbxFvgvct7YDo+PWX6zukDPsY+Ap96n4e+pr4i3z2+I37Wfpl+B/ye+zv6y/2P+L/hefIW8U4F + YAHBAeUBvYEagbMDawMfBJkEpQc1BY0FuwYvDD4VQgwJDVkfcpNvwBfyG/ljM9xnLJrRFcoInRVa + G/owzCZMHtYRjobPCN8Qfm+m+UzpzLYIiOBHbIi4H2kZmRf5fRQpKjKqLupRtFN0cXT3LNas5Fn7 + Z72O8Y+pjLk722q2cnZnrGpsUmxj7Ju4gLiquIF4h/hF8ZcSdBMkCe2J5MTYxD2J43MC52yaM5zk + mlSWdGOu5dyiuRfm6c7Lnnc8WTVZkHw4hZgSl7I/5YMgQlAvGE/lp25NHRPyhJuFT0W+oo2iUbG3 + uEo8kuadVpX2ON07fUP6aIZPRnXGMwlPUit5kRmSuSPzTVZE1t6sz9lx2S05lJyUnKNSDWmWtCvX + MLcot09mKyuTDeR55m3KG5OHyvfkI/lz89sVbIVM0aO0Uq5QDhZML6greFsYW3i4SL1IWtQz32b+ + 6vkjC4IWfL2QsFC4sLPYuHhZ8eAiv0W7FiOLUxd3LjFdUrpkeGnw0n3LaMuylv1Q4lhSVfJqedzy + jlKD0qWlQyuCVzSVqZTJy26u9Fq5YxVhlWRV72qX1VtWfyoXlV+scKyorviwRrjm4ldOX9V89Xlt + 2treSrfK7etI66Trbqz3Wb+vSr1qQdXQhvANrRvxjeUbX21K3nShemr1js20zcrNAzVhNe1bzLas + 2/KhNqP2ep1/XctW/a2rt77ZJtrWv913e/MOgx0VO97vlOy8tSt4V2u9RX31btLugt2PGmIbur/m + ft24R3dPxZ6Pe6V7B/ZF7+tqdG9s3K+/v7IJbVI2jR5IOnDlm4Bv2pvtmne1cFoqDsJB5cEn36Z8 + e+NQ6KHOw9zDzd+Zf7f1COtIeSvSOr91rC2jbaA9ob3v6IyjnR1eHUe+t/9+7zHjY3XHNY9XnqCd + KD3x+eSCk+OnZKeenU4/PdSZ3Hn3TPyZa11RXb1nQ8+ePxd07ky3X/fJ897nj13wvHD0Ivdi2yW3 + S609rj1HfnD94UivW2/rZffL7Vc8rnT0Tes70e/Tf/pqwNVz1/jXLl2feb3vxuwbt24m3Ry4Jbr1 + +Hb27Rd3Cu5M3F16j3iv/L7a/eoH+g/qf7T+sWXAbeD4YMBgz8NZD+8OCYee/pT/04fh0kfMR9Uj + RiONj50fHxsNGr3yZM6T4aeypxPPyn5W/3nrc6vn3/3i+0vPWPzY8Av5i8+/rnmp83Lvq6mvOscj + xx+8znk98ab8rc7bfe+477rfx70fmSj8QP5Q89H6Y8en0E/3Pud8/vwv94Tz+4A5JREAAAAZdEVY + dFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAADKGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAA + AAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4g + PHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENv + cmUgNS42LWMwMTQgNzkuMTU2Nzk3LCAyMDE0LzA4LzIwLTA5OjUzOjAyICAgICAgICAiPiA8cmRm + OlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1u + cyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5h + ZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8x + LjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jl + c291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNCAoTWFj + aW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo2RTJDOTVERUE2NzMxMUU0QkRDRERG + OTFGQUY5NERBNSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo2RTJDOTVERkE2NzMxMUU0QkRD + RERGOTFGQUY5NERBNSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAu + aWlkOkNGQTc0RTRGQTY3MTExRTRCRENEREY5MUZBRjk0REE1IiBzdFJlZjpkb2N1bWVudElEPSJ4 + bXAuZGlkOkNGQTc0RTUwQTY3MTExRTRCRENEREY5MUZBRjk0REE1Ii8+IDwvcmRmOkRlc2NyaXB0 + aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+i/72ygAAFwtJ + REFUeNrsXQmcU9XVPy97MslkZoBhcRiQXTY30M+tKCqoLQr287O2LvUr1taFuiButUoVwa32U4tS + tNU6VkRUpCwFZdEyqGyCoKyC7IsCM8zCTJKX992b/G9z5k6SyQxQccz5/Q4kk5f37rv3/M/5n3Pv + uzGGDx9OWTk2pNp00tju71Oxfy9RxP1da35LoZOF7hd6m9DtjT6DJTTfpNI1Hrr6rTyy2SyyGc1j + bG1Z887KEZILhJ4n9MdCr2j0t6NC80xauN5NP5sSpLAAXXMBmRRH1j6+1+ISWig0V6hdaA0i0r4m + RjQFmV2N/rY/SktEJBv6Rj5ZAmQtfVGKWlmgZeW7Ka2Enip0gNDThLYX6gXgJLuJCA0JPSh0ldDp + QmcJPZDBue34X4K0otGUUQBtxlYX7SuzU492YYpEm1fHZ4H2/ZCOQq8U+r9Cu2X4nd5CrxK6TOhI + oQvSHJsjdBgD87tCxwn9bUZXkhAVADt0yCBfjtnsQJbN0Zq/eITeLnQhDL9bE84hI+BcoffjfMnk + V4iSHDr3A9gNR7OgSbO3OemJ0hwqyo02y4HIAq35SmuhU4X+QehxR8BOHgGNvAA5naSbRULvTRO5 + fi00P+2ZnRbVfuOgSYt91Ca3eeVlWerY/OUEoW8K7XWEz3sucru9QmsBuNZpHHY/ipf6H0xHG7cd + tNGUtR5qF8gCLSvfHZFR5pWjADIlPuR8mcrvKF7NHJuS3wrqWOiPxnKz5lTSz1LH5i2SKvb/lq4t + 49FSocuFVrG/y0JJyzpHylTMI/7JNWn+Gg9FIgYZRvMdlGxEO+ZcX+Rwvv1zaspk8ZGT9UJ/InSH + 0A5Cfyn0MuR338Tvz4q792CU5q300KSVXpq20U1uQSGN5jysWcs+hryeEaWS7aeQGfYKq2t09U3m + Sncl+bucPC7/D93Cw0K/BFVcR/FCST8R56aTXQDMb8bQ9OVeB/30pQK6ZUaQJi73kddhkcdhNe+x + zZr3sSPSo28+FKSQPUxeq9H+XUaOntrfSoVOBACDR7n544W+Voca+qIhcSMhGcUOltvpwDYXPVjq + pzmbXFQVMsjvsqh7qwiZAmPR5o2zLNCOKXphCGuzbLT6QDH1z98Se52hBIReo/1NRpShFF9i1eYo + N/05oaMSrRGRKydKq9Z7aPGXbuqQH6EFW1z0aGkOtfNHYzQxJycesU3r+zG2jrPPPjtr4ceQTJu/ + jN7c3Yv6t9gk3HzGfvAsipfdlZQBeN8gtmwQ2uIoNFcu0xpBatWICMJyneLjc3LJFFedtclNCwXQ + DFeUct0ierVonqs+shHtO5mnWZTnqooXRSyPMN6MXL5cMe9i7x8SugSv5SLhJ4S+kcF4y/zqddBM + WczIo3g53ym0EvleWwCbUPRYVucMgg5OWOGlzbudVCgiWY+2iXWL31eQZYF2DIrdiFJV2EM1NUHy + 2EOZ0EdZNj+Rvf9A6KvaMWuEVlN8gjmdyEnuB1jK6KPEKpByRMoigPZMoYOEzo4BPSpAGDTpqz1O + yndaFGoZiRU5viVwyfbKJWHt8X6P0HlCD2WBlpWY+O21tKKiDZXs7EvDO39IVOtv6CuDKb4eUclf + EcW4dKHU6xSJGWNJ7FWeyLFCIpRW2qrIVmc+TMp2FFemU+Ixm3zyWLu27nDRsMl5tO2gnVp4o3JS + rR3FJ7cjoLAp/QvFV5pIqlsg1I32ygi6sQndKCPyPUIHMor7Q6HbskDLSkwsEUgcJMvdtSjxGxSf + B04pMpqpsCcXD7+b5JiuGrXULyrP8CdyWp9LRNz7Vh6dKCjf1WcJjB2yxZsQe4DGUJNdYVnHILlq + 34o9QrOdCiI0fm6AVm53Uve2kViORvFV/3JRcxXOkEpk5NwEGnq+9DcUfyLgeaE3ZaljVo6KFLiq + 6f293ejk4A7qJZRC/lRgywOFU/JP0DtdTk55sVgZ3no34rYecxy00X3zAvTkh35qL6jfrA1uqg4b + tLfSRsN619DICyqIDsRmltuJ5rSMNSnX3EWe6KFFS3z01moPFbc0FcgI+RwBNA1JLvLClpR4ts3b + xC6MasA2G4ioR0qOR1/3htOYkQVaejFgHE5441CK4zw4pgZe/sgkGDaTdtQEaFVZEfUK7I1HtuTz + anLerC9e70SOpYukYd1TmqPbmkltwrdMnJUbGvteIGadnVrLAoZBMza6Y2sPDwig5XssGjmgUtyx + QFe1USWgsFrkZPO31xjjV232hm+elidyS4odx0r2ivZVMMM3Wd6nRH4mFyqvB9jy0f+VhzF+/+mF + Jj1QSDoJ78dlgdawyIF+AbmPfNRkNMWfOubSh+LrCtvjmHuO1MWjAlTHuStosizzi4jWOXd3qs16 + 5PxYAK+/BP3S5QYth0uAzE4vUtvwzc/MzA3dMy1IhYFoK59hFQtweW12K9LKZ8mnpTe38kUj87Y6 + 6eqSAiq58oAE2xLqWjt4+QbXzoF3Fckqia9Lcag4V+BRgMwFgMi2PATwe1ieJp3So5R4UFRSzztQ + xJEg/COcl5uasiXCtyftGchIL7xkgZaiJkHxeakO+D+ZlRegsuVMasiHCzbhkD0isjkcoXQ5Gl+o + uzJJHiTb9QDpS+0s2i0i2WgBshee+Wcu3f52sLA437zJYYs9qNmeXU1WKhdELXqyYzA6f/J6N3nf + yaNHz68oL3k9v3zSp15budO6tmNh5BZxgT7RulFqi9DHKb5iRJev2Wt5g59KQOP91mOY5aRLlreh + oKNsZX8WaA1LhNHFAymo40F4bhn9dh+NRjgNk0q2nUJ3dyolR2xezZbMiyr5RPtMVtz+hqoglylR + 03jA5jHXThBU8Tdv5p3RLt98zmWnU6JW7D5ehNHI/OgHQi+RGo7SvccHzXFTRd72xT47Ld7uFDQx + +nSv9qERpmlExeeTjThVlH0nH9EZIvRPQs8Qep2WI/GczcXed6L4lgt2ODu5hOwfSbpGPsg6GNS5 + EBGzEuOwgOJPEDRE5eWzcpeC1gbhjMZT3W3yLqb4FEYhJaY45IqbSayCeSL6upOGp4vhhGXbKhxI + 4E5Fw2ajAnQ1xedLFiPBrkySmwxC4ufFRRfBMxHj2TZQCJWgy/0kihFWNzID9uM7HtzoHlAiGTH6 + w5PIuaD54PLEDKEV2rkeg9QFXHkTqNUg5CgWqnL/IqpXsj4TnZWDqt16FvpT8X0bixTqfD9Bn8g2 + TqP4igx5zotwDjlIq5IAoq2KHsQ2wjEMizYfyqdQ1B4HWn1pzSIPp42yUjcGxRIlkgbeT97oxI37 + 7dGLH2tDVSFqL0A2MeCyegnKJ/OJW4R+peV316P6N1YAcV+uK/Z96phvXmUYNCIUNraJjr3CqA/0 + c4T+Hbb0IcXXXHLiymueSk4CrVTylyRAk1H3Tqq/rlPJ+aCl6ebMJBt5WihfFvU663vpwOQTB1cB + LJSkDbcBL4MQuXW5BBpz1g54hufRsHFo6A/YF+aC56vQLp/efQmeiosc7GcovmJbGtZz8Ew34/xS + RqHkK68lH6Eowd9Hwzgi8DQSpHKB6inaNVbCGBaCNkmP2RlG9Q067yAGWFI+ObHaUTtHKdq0Eu/v + pvgTwF6W00zIsFLGI4vM0y5jfxsF4C/CoPXANS9k1El6Zjm5LOeb5gh9T2crPns4vgayvnhx7yrq + 7sBruYJe31pgNaLKcrl1wNx1Hvq6yqAWvugdIpJJkM1FW3UHVItctQrRcYzI32blui3pDM+14s26 + L0k0JTi0ezDGNyJXK2ugH6sBvFSFjEdhX+lkEwJDOrb2qAYy2cbhuN92AN1Z7PO1yC27o997wLb6 + MMefTuw2Vv3xwuD7ITH9mnmIFwGaAgBAgUxGmXnoQB869jp45hA6rC8rRZ/DrnUuXgcQZj0wCAmy + VxjIViJihRCmS9AZNawzR6DthGh0Hgy4I8ArwfUZPj8L9+DHvT2C9pgwjn0wns4ZdKDJvNcQtHUN + /laItso5rCmMZnTRvH47vJ5XnzlYdMh0xoojKQo2RXj9OXKi8+E4uLwf619LgMwfpWcXBOgOkZcV + 5kT7ipzsBqyavysJyLi8ChuQ7OFarfT+dZrvLUDfR/DdTMryqaLdTRrIwmAf0vFeTvENgl5GEAil + yKsJx93I3s9gICMUuM5iTOVGRNp+lHjWjkA3n4TTHwU6ydv+IWzyMRnAbBqXlSf+OUBwKYtiA+EB + BlBiTuZVUK7zcazirPcBBAvx/nSA6DgYnZIilieqDVwmIcKqBbK34yZPR0fXgmLeC24dZmBdC8ow + EufoBk49HG0/kRLPa/XC69sZWO9GJD8XFLWxMgYU/GJQChWxBsHYlXC2MJgZ63v1EkVBGW9ov4x8 + rupk+Vke67dFLMdxalFlmDDX7VRg0stLfDRiZi4V5ETJZov1h4zab7Ponk7URPh/w4Gq0v09bCx1 + 2YExuVyjpI2VdhTfVYuLvO5QsJp3wEKuR1/7KTEXpwC7A06fb6mwBIGhlqUQQ9jnEsR/xucm0oH7 + 2OeXgc08AVBxfv82qq6ynWNtWpiewOZiPsYJlFwEo1WG8QSjAv+CJyAY+Hn4PiHctka+5Ee0LAcF + zUfkCLLKTU8WyWYgD8oBdVHn7AvA1eD9bniqqYiKqkjwGXJMFzzcNIo/Zi/lF6BxUqaD6hJKyr8H + jcmkEiVlBSKjicgyjh1zIRzWp4whqByvJ/N+y+twDSNKZREP5bkrUj11ncv6bQOjXkq+ghFVknyo + sspG729wk0O89gv6KGhfbxZJM5nMXQ5wdUI0+yuucS6i1kMYlwKNtklb2UlNm2dUEW0oi/wERvKH + RpxnLyLqWJa3rkH/8F2ZrwAzI7CoKUnONQfjrXLYAazAY9Oofcqq40fa+4VAqQNAURu+fAC6wkUB + KIhOkZ7ld5TYzKUVDP51RM5LAJb+aNQq5FmqQ6URLoMx2+BVclg0PJ55osXMkDuyyPlfQr9Ah0Qx + cH4WbXjeVsverwPou2cItDVaZfIreNDj4Ei2Aswnw1ANROm+rJ/rgGx3rZ/6BPZQBxnNzGT5eOw+ + XWj3FvytQouwm9UPR7y+1EevrfBSt8KIfMjSYP2c6Y9R7IET6gJ28BGi29OgwA9Cv4ZDLEXutohS + T/hnKgO19y828vs5oHCqOCEDxK2M5hPslK+gcSJCWgw0NXgdSDLFogctRzqgmUk4MyWpvtUk8YJ8 + mYsbYVkZ2xkAFQE8Hty0pFq9GchXs5vYDzAb7Caq0ebPYVRuzeBVudjDotNadJqdEhOmZXAIqhrY + 1GkOI0W/mYxGqDbOBv3pDCrbB+1cC+fzbxe+rSZIJwmQPdBjNrltIhDEtjaoVxDpxhzcSlYUUVMP + cSrqsqhip5OmLPNRm6CpnmS2sXvONNLwe3KysRwIynUhxrIf6NcQRqFuo6Yt6LWSzBeWN2Gu7Uyt + uJGD6jdpQON7UJ5M6ZauJSSQwgYoHdD0J3H7sGO2gAIUwxt3YJ6UYED5DIg1GAgJtAsQZfbAsNTj + GpeyyPI5wBVm1aOhmpdWJfUIrq+ik51NKJbDq/pxzmHw+upzB77fF/dRgOiod17LDJN30gocUlow + x7KLRc1P4HRuYMWHxeiXuGVZBj3ebS4V+feSJwYyX6r9Q05gxq6KKCGWa8f7TdDEjfsdNHWdm7ol + Hrw0KbGPSKZbHPjQLxGqOxkbAfX9EH1cjP44mxUq5Fj8jNQGPU13aA0adArRE1wnItwKxoTsWn4b + TTO1E4EtOdk42lI4iaQfDmeGX0B1V05/wOY0urLqk5rPuZs1YjXL81ReUgxjUw8QVgJop2LgPmIA + Ixjkj9g1OqEs+3fMY1SnqFBtYZ3XD/mi+rwnpiD+D0UJZTDDWBXUjkJJi0Z4XHkdvpXAVez1Iq04 + oXKOH+P1W/yERd5yOiF/CwUdNYhkSUGWx2jtJ1o0V3SwtoG2r2fONBPphrL2duQ8x1H9XYgt9P9c + FAcG4thBKBI1FWARbQ4srwnnmozCiZJWqBr6WGSv0Sqm51BijvU8phdCJSv7I2MuViqg6RHtFFCO + GZSYLFbVmXkoOowAsEYjInxGdTeGmcGqbCsAKL+WtO/FgPRi8xSfsoLMYHjal1BS/RI31Z0VDyop + +S5eVSjoXI7OnIr3OwGGtuiEq1DQmQCDeQMFlx4awBsCmerH8ej8AByIassb7DiZp/0axwTQHx/z + k97deQHZZIVR5mWpn64eDFrzCcZFT8C3/dtowgZ1KYjQ0O61tGi7M7YhDptbU1XEJ6jhX4wZiHH8 + G6L1xygu/ZRSTw6vQtFiHPK6V5sY0bZo76/Ui0cNyE4Uq9bAKZ7O7ukOfFamFUb8aP/BJkRd7vTq + RTQTIGuPEnl/Nmh34vUXoD3f4MQ/RKm9J5uzuZV1/GIt4VRzEPuYR5WylHmteYisB2A4l6IM3x3H + PIUKYStWwg1o9zIJ8x8ReJqrMdfRlk1BvIF5lyls3mskuPyzrBwdSJHDeZk3/Bz9dA2ilWrLSPQB + LzYt00rAdSY8fSKiUcSVbkB7s2rwSxq1LmARLU6xQgYF2obpmtOraH+1TS9elYKdXN+AERUxdlMC + wy9HSlCUIb02DyOivaM5thEZOkNi/bEL9vCA5hgeRMSNUt1fzDmN+IZDDYv+U1VdU0U0O7zyGNBC + H6pvryKiKPkH+PdQeCknjOUDzLVwyrIPA9QJ3p3TnHsBiFAS7zQFCf7lMCwXQDoV0UyVjX+BXGoT + 1V/w+WcY+TA4gjDuYwaLIiHc6yx4Nzeu8RoKFJ3wnWT7In6BaOCD55Pnuhn53n5QlTlJuP0sRlPn + 1DtrbUBGMj8KJfs1enw6+rg1aNBE7dtD2HRHwlRFVJPlfS3+y3F6HOd7CqX7aUnusxBRvzMM/iPm + zGR0/i3GIdkcRFdEDNIjdyNlJhywmhrxwFFORPt3gZUMgN2Uau1xsqLUe3CkoxgGHgdrmwinoxYr + 3I97GA9nWgvHq3LQpWwMq8Ei/GyObSRs23AkSRI/gDG7YDzJ+Ms6JJPqB+xCaeZilkKTnWNdms7d + gGs4cY2wdo1DlGSSV5MV6HhV3g8nuR95nr/AoRisoPBRkukOLgeIPW8EGYWBM7WBVoWYICWW/nxG + 9dc9ilbKByutnhgki0UnXjkbT/U3S+0Bz0z1HIPovbJaG4UOGeTIq7NJzjR4+IdhsM/CQZXhPs7E + Z53Qj7ezs74AYF8LYxwHOhrBmA1GtChE5J1+GEAz0bczKbG+Uzq43yBfPwjwtYCTXKhNKei07hk4 + 1n54LwPG78HGRiHVUG7pf3AvB9i95QLYJQxoW3Ddi1hlcyzavsSRogppZZBM0xGYH8lEDveBSktL + co/WdZRBmClKwHciAvZktLH+8qV4XrYYzOJXyPsKcA/TEMnmJLnGAET3KKIti10GnV0UotM6hmhr + uZ3naYT8ZDP+vxWqj/Er8O472N9Vbv40CkvJtlAoA1DHaP3r1wo7XgYeu8aylCwHXXyeAYRYvsur + sQVUdwlWnsbedgAEvBB1C6q/j+C+nmJTKMEU1dmWWj89DGcYYHiS2tGhNcBNWTkakoNcU4FsM6hl + OlkJauZCbql2oUo1l3MDBvt60n+dU9DGLifU0iWbamjMnIAAWj1f8Bqi86WY9mgBYG8GZVua4rrL + KfEj8TKnaQew7AOdn03JN9eZjmJWGPf1FauETkB08lP9Xxldiuv9CP93ZhVIdc2ZSGWm438LbdDp + /9tIawYgWrVE27347icomJ2DirkfTlQeuxXnfF875yK061ZKTI3JlGm+8fLLL/dCaIygkRuzuDji + IqnGL+Ehd8L7f5rswOvKRjXl/HZUIStRwa0vQZNGTw/SmNIc6hA0m0OfGnAwakOVCkrMJza4o1Ga + ftQLN3ZEMy/YQjWoqtVA21ogcMnjy/5fgAEAs+CvmHNdSv0AAAAASUVORK5CYII= diff --git a/include/i18n/en_US/filter.yaml b/include/i18n/en_US/filter.yaml index da95a9869e9037cdd5eb2c46307de32706128821..95da7ae6bbe1d53f92b537e03e7c5a3a91f6d44e 100644 --- a/include/i18n/en_US/filter.yaml +++ b/include/i18n/en_US/filter.yaml @@ -8,8 +8,6 @@ # Fields: # isactive - (bool:0|1) true or false if the filter is initially enabled # execorder - (int) order the filters should be executed in (lowest first) -# reject_ticket - (bool:0|1) if a ticket matches the filter it should be -# rejected (ie. not be created). # name - (string) Descriptive name for the filter # notes - (string) Administrative notes (viewable internally only) # rules - (list<FilterRule>) List of rules for the filter @@ -19,19 +17,25 @@ # what - (enum<email|>) field to check # how - (enum<equals|contains|dncontain>) how to check for <val> # val - (string) search value +# +# Fields for FilterAction +# type - type of filter action +# --- - isactive: 1 execorder: 99 - reject_ticket: 1 - # NOTE: Don't translate 'Email' - target: Email - # NOTE: Don't translate 'SYSTEM BAN LIST' - name: SYSTEM BAN LIST + match_all_rules: 0 + email_id: 0 + target: Email #notrans + name: SYSTEM BAN LIST #notrans notes: | Internal list for email banning. Do not remove rules: - isactive: 1 - what: email - how: equal - val: test@example.com + what: email #notrans + how: equal #notrans + val: test@example.com #notrans + actions: + - sort: 1 + type: reject #notrans diff --git a/include/i18n/en_US/help/tips/staff.department.yaml b/include/i18n/en_US/help/tips/staff.department.yaml index 2d91cb5383194e81be920c328837ef031b6709cc..ec16a46a1f13e2ad790f2ca9216fe447b5654ad8 100644 --- a/include/i18n/en_US/help/tips/staff.department.yaml +++ b/include/i18n/en_US/help/tips/staff.department.yaml @@ -47,7 +47,7 @@ sla: Service Level Agreement for tickets routed to this Department. links: - title: Manage SLA Plans - href: /scp/slaplans.php + href: /scp/slas.php manager: title: Department Manager diff --git a/include/staff/cannedresponse.inc.php b/include/staff/cannedresponse.inc.php index 518ad1165310fbf99ee148e5d259c6146e782677..407c5ba89466beb080c2356f7aa8113546bce33b 100644 --- a/include/staff/cannedresponse.inc.php +++ b/include/staff/cannedresponse.inc.php @@ -93,10 +93,10 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); </div> <?php $attachments = $canned_form->getField('attachments'); - if ($canned && ($files=$canned->attachments->getSeparates())) { + if ($canned && ($files=$canned->getAttachedFiles())) { $ids = array(); foreach ($files as $f) - $ids[] = $f['id']; + $ids[] = $f->id; $attachments->value = $ids; } print $attachments->render(); ?> diff --git a/include/staff/header.inc.php b/include/staff/header.inc.php index ba294007755d41549bf35c9806bf32215f6df1e8..dd9945a1eaf27fe2d48024df9ea5c722b2c83f29 100644 --- a/include/staff/header.inc.php +++ b/include/staff/header.inc.php @@ -27,7 +27,7 @@ if (($lang = Internationalization::getCurrentLanguage()) <script type="text/javascript" src="./js/tips.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor.min.js"></script> <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-osticket.js"></script> - <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-fonts.js"></script> + <script type="text/javascript" src="<?php echo ROOT_PATH; ?>js/redactor-plugins.js"></script> <script type="text/javascript" src="./js/bootstrap-typeahead.js"></script> <script type="text/javascript" src="./js/jquery.translatable.js"></script> <link rel="stylesheet" href="<?php echo ROOT_PATH ?>css/thread.css" media="all"> @@ -65,8 +65,7 @@ if (($lang = Internationalization::getCurrentLanguage()) echo sprintf('<div id="notice_bar">%s</div>', $ost->getNotice()); ?> <div id="header"> - <a href="index.php" class="no-pjax pull-left" id="logo">osTicket — <?php echo __('Customer Support System'); ?></a> - <p id="info" class="pull-right"><?php echo sprintf(__('Welcome, %s.'), '<strong>'.$thisstaff->getFirstName().'</strong>'); ?> + <p id="info" class="pull-right no-pjax"><?php echo sprintf(__('Welcome, %s.'), '<strong>'.$thisstaff->getFirstName().'</strong>'); ?> <?php if($thisstaff->isAdmin() && !defined('ADMINPAGE')) { ?> | <a href="admin.php" class="no-pjax"><?php echo __('Admin Panel'); ?></a> @@ -76,6 +75,10 @@ if (($lang = Internationalization::getCurrentLanguage()) | <a href="profile.php"><?php echo __('My Preferences'); ?></a> | <a href="logout.php?auth=<?php echo $ost->getLinkToken(); ?>" class="no-pjax"><?php echo __('Log Out'); ?></a> </p> + <a href="index.php" class="no-pjax" id="logo"> + <span class="valign-helper"></span> + <img src="logo.php" alt="osTicket — <?php echo __('Customer Support System'); ?>"/> + </a> </div> <div id="pjax-container" class="<?php if ($_POST) echo 'no-pjax'; ?>"> <?php } else { diff --git a/include/staff/login.tpl.php b/include/staff/login.tpl.php index a979d6a64e9114ad6ad65425c7dff3af4f98c5cc..cbb5b589499552516ea20f60b8bd90917ff2d445 100644 --- a/include/staff/login.tpl.php +++ b/include/staff/login.tpl.php @@ -3,7 +3,10 @@ include_once(INCLUDE_DIR.'staff/login.header.php'); $info = ($_POST && $errors)?Format::htmlchars($_POST):array(); ?> <div id="loginBox"> - <h1 id="logo"><a href="index.php">osTicket :: <?php echo __('Staff Control Panel');?></a></h1> + <h1 id="logo"><a href="index.php"> + <span class="valign-helper"></span> + <img src="logo.php?login" alt="osTicket :: <?php echo __('Staff Control Panel');?>" /> + </a></h1> <h3><?php echo Format::htmlchars($msg); ?></h3> <div class="banner"><small><?php echo ($content) ? Format::display($content->getLocalBody()) : ''; ?></small></div> <form action="login.php" method="post"> diff --git a/include/staff/settings-pages.inc.php b/include/staff/settings-pages.inc.php index 3bf1c78776adc2bc90b9604175591bd3ff969202..4d9910b4e2c9e04cd5d41fc40ddde1961f0e1abf 100644 --- a/include/staff/settings-pages.inc.php +++ b/include/staff/settings-pages.inc.php @@ -107,49 +107,74 @@ $pages = Page::getPages(); <tbody> <tr> <td colspan="2"> - <label style="display:block"> +<table style="width:100%"> + <thead><tr> + <th>Client</th> + <th>Staff</th> + <th>Logo</th> + </tr></thead> + <tbody> + <tr> + <td> <input type="radio" name="selected-logo" value="0" style="margin-left: 1em" <?php if (!$ost->getConfig()->getClientLogoId()) echo 'checked="checked"'; ?>/> - <img src="../assets/default/images/logo.png" + </td><td> + <input type="radio" name="selected-logo-scp" value="0" + style="margin-left: 1em" + <?php if (!$ost->getConfig()->getStaffLogoId()) + echo 'checked="checked"'; ?>/> + </td><td> + <img src="<?php echo ROOT_PATH; ?>assets/default/images/logo.png" alt="Default Logo" valign="middle" style="box-shadow: 0 0 0.5em rgba(0,0,0,0.5); margin: 0.5em; height: 5em; vertical-align: middle"/> - </label> - </td></tr> - <tr> - <th colspan="2"> - <em><?php echo __('Use a custom logo'); ?> <i class="help-tip icon-question-sign" href="#upload_a_new_logo"></i></em> - </th> + <img src="<?php echo ROOT_PATH; ?>scp/images/ost-logo.png" + alt="Default Logo" valign="middle" + style="box-shadow: 0 0 0.5em rgba(0,0,0,0.5); + margin: 0.5em; height: 5em; + vertical-align: middle"/> + </td> </tr> - <tr><td colspan="2"> - <?php - $current = $ost->getConfig()->getClientLogoId(); - foreach (AttachmentFile::allLogos() as $logo) { ?> - <div> - <label> + <tr><th colspan="3"> + <em><?php echo __('Use a custom logo'); ?> <i class="help-tip icon-question-sign" href="#upload_a_new_logo"></i></em> + </th></tr> + <?php + $current = $ost->getConfig()->getClientLogoId(); + $currentScp = $ost->getConfig()->getStaffLogoId(); + foreach (AttachmentFile::allLogos() as $logo) { ?> + <tr> + <td> <input type="radio" name="selected-logo" style="margin-left: 1em" value="<?php echo $logo->getId(); ?>" <?php if ($logo->getId() == $current) echo 'checked="checked"'; ?>/> + </td><td> + <input type="radio" name="selected-logo-scp" + style="margin-left: 1em" value="<?php + echo $logo->getId(); ?>" <?php + if ($logo->getId() == $currentScp) + echo 'checked="checked"'; ?>/> + </td><td> <img src="<?php echo $logo->getDownloadUrl(); ?>" alt="Custom Logo" valign="middle" style="box-shadow: 0 0 0.5em rgba(0,0,0,0.5); margin: 0.5em; height: 5em; vertical-align: middle;"/> - </label> - <?php if ($logo->getId() != $current) { ?> + <?php if ($logo->getId() != $current && $logo->getId() != $currentScp) { ?> <label> <input type="checkbox" name="delete-logo[]" value="<?php echo $logo->getId(); ?>"/> <?php echo __('Delete'); ?> </label> <?php } ?> - </div> - <?php } ?> - <br/> + </td> + </tr> +<?php } ?> + </tbody> +</table> <b><?php echo __('Upload a new logo'); ?>:</b> <input type="file" name="logo[]" size="30" value="" /> <font class="error"><br/><?php echo $errors['logo']; ?></font> diff --git a/include/staff/slaplans.inc.php b/include/staff/slaplans.inc.php index 46264ec98dfa061e98f45a787da722c72d3833e5..dbe5cabb84478acb1d50b3b7601e69d3e25e6c67 100644 --- a/include/staff/slaplans.inc.php +++ b/include/staff/slaplans.inc.php @@ -34,6 +34,7 @@ $count = SLA::objects()->count(); $qstr = '&'. Http::build_query($qs); $qs += array('sort' => $_REQUEST['sort'], 'order' => $_REQUEST['order']); +$pageNav = new Pagenate($count, $page, PAGE_LIMIT); $pageNav->setURL('slas.php', $qs); $showing = $pageNav->showing().' '._N('SLA plan', 'SLA plans', $count); $qstr .= '&order='.($order=='DESC' ? 'ASC' : 'DESC'); diff --git a/include/staff/templates/task-view.tmpl.php b/include/staff/templates/task-view.tmpl.php index 6020b7a3eadfbec200c2f88ef25fff82ba010340..a9a4c72170780e61cd2edd7ada25a4ab30a6ab3b 100644 --- a/include/staff/templates/task-view.tmpl.php +++ b/include/staff/templates/task-view.tmpl.php @@ -212,32 +212,31 @@ foreach (DynamicFormEntry::forObject($task->getId(), $types = array('M', 'R', 'N'); if(($thread=$task->getThreadEntries($types))) { foreach($thread as $entry) { ?> - <table class="thread-entry <?php echo $threadTypes[$entry['type']]; ?>" cellspacing="0" cellpadding="1" width="940" border="0"> + <table class="thread-entry <?php echo $threadTypes[$entry->type]; ?>" cellspacing="0" cellpadding="1" width="940" border="0"> <tr> <th colspan="4" width="100%"> <div> <span class="pull-left"> <span style="display:inline-block"><?php - echo Format::datetime($entry['created']);?></span> + echo Format::datetime($entry->created);?></span> <span style="display:inline-block;padding:0 1em" class="faded title"><?php - echo Format::truncate($entry['title'], 100); ?></span> + echo Format::truncate($entry->title, 100); ?></span> </span> <span class="pull-right" style="white-space:no-wrap;display:inline-block"> <span style="vertical-align:middle;" class="textra"></span> <span style="vertical-align:middle;" class="tmeta faded title"><?php - echo Format::htmlchars($entry['name'] ?: $entry['poster']); ?></span> + echo Format::htmlchars($entry->getName()); ?></span> </span> </div> </th> </tr> <tr><td colspan="4" class="thread-body" id="thread-id-<?php - echo $entry['id']; ?>"><div><?php - echo $entry['body']->toHtml(); ?></div></td></tr> + echo $entry->getId(); ?>"><div><?php + echo $entry->getBody()->toHtml(); ?></div></td></tr> <?php $urls = null; - if($entry['attachments'] - && ($tentry = $task->getThreadEntry($entry['id'])) + if($entry->has_attachments && ($urls = $tentry->getAttachmentUrls()) && ($links = $tentry->getAttachmentsLinks())) {?> <tr> @@ -246,7 +245,7 @@ foreach (DynamicFormEntry::forObject($task->getId(), } if ($urls) { ?> <script type="text/javascript"> - $('#thread-id-<?php echo $entry['id']; ?>') + $('#thread-id-<?php echo $entry->getId(); ?>') .data('urls', <?php echo JsonDataEncoder::encode($urls); ?>) .data('id', <?php echo $entry['id']; ?>); @@ -255,8 +254,8 @@ foreach (DynamicFormEntry::forObject($task->getId(), } ?> </table> <?php - if ($entry['type'] == 'M') - $msgId = $entry['id']; + if ($entry->type == 'M') + $msgId = $entry->getId(); } } else { echo '<p>'.__('Error fetching thread - get technical help.').'</p>'; diff --git a/include/staff/templates/thread-email-headers.tmpl.php b/include/staff/templates/thread-email-headers.tmpl.php index 6e2f45809e0e9dc7d985b92eff1252fcb52ca7a0..a84216ab46be6c4816a679ada4a1e77ff96e5216 100644 --- a/include/staff/templates/thread-email-headers.tmpl.php +++ b/include/staff/templates/thread-email-headers.tmpl.php @@ -3,7 +3,7 @@ <hr/> <pre style="max-height: 300px; overflow-y: scroll"> -<?php echo $headers; ?> +<?php echo Format::htmlchars($headers); ?> </pre> <hr> diff --git a/include/staff/templates/ticket-print.tmpl.php b/include/staff/templates/ticket-print.tmpl.php index e283e4e8f2da193598e1096b8d1cbe0eb86d00e4..11323c4a14b60077e7e208cc41f0b1434726882e 100644 --- a/include/staff/templates/ticket-print.tmpl.php +++ b/include/staff/templates/ticket-print.tmpl.php @@ -222,29 +222,28 @@ if ($this->includenotes) if ($thread = $ticket->getThreadEntries($types)) { $threadTypes=array('M'=>'message','R'=>'response', 'N'=>'note'); foreach ($thread as $entry) { ?> - <div class="thread-entry <?php echo $threadTypes[$entry['thread_type']]; ?>"> + <div class="thread-entry <?php echo $threadTypes[$entry->type]; ?>"> <table class="header" style="width:100%"><tr><td> <span><?php - echo Format::datetime($entry['created']);?></span> + echo Format::datetime($entry->created);?></span> <span style="padding:0 1em" class="faded title"><?php - echo Format::truncate($entry['title'], 100); ?></span> + echo Format::truncate($entry->title, 100); ?></span> </td> <td class="flush-right faded title" style="white-space:no-wrap"> <?php - echo Format::htmlchars($entry['name'] ?: $entry['poster']); ?></span> + echo Format::htmlchars($entry->getName()); ?></span> </td> </tr></table> <div class="thread-body"> - <div><?php echo $entry['body']->display('pdf'); ?></div> + <div><?php echo $entry->getBody()->display('pdf'); ?></div> <?php - if ($entry['attachments'] - && ($tentry = $ticket->getThreadEntry($entry['id'])) - && ($files = $tentry->getAttachments())) { ?> + if ($entry->has_attachments + && ($files = $entry->attachments)) { ?> <div class="info"> -<?php foreach ($files as $F) { ?> +<?php foreach ($files as $A) { ?> <div> - <span><?php echo $F['name']; ?></span> - <span class="faded">(<?php echo Format::file_size($F['size']); ?>)</span> + <span><?php echo Format::htmlchars($A->file->name); ?></span> + <span class="faded">(<?php echo Format::file_size($A->file->size); ?>)</span> </div> <?php } ?> </div> diff --git a/include/staff/templates/tickets.tmpl.php b/include/staff/templates/tickets.tmpl.php index 6e6b6cf5c383bfceaca595fa135c478b887bb862..ce48d471b659a6ae2b0cb2fb95bc9a646bd90066 100644 --- a/include/staff/templates/tickets.tmpl.php +++ b/include/staff/templates/tickets.tmpl.php @@ -49,8 +49,8 @@ if ($results) { .' LEFT JOIN '.THREAD_ENTRY_TABLE.' entry ON (entry.thread_id=thread.id) ' .' LEFT JOIN '.ATTACHMENT_TABLE.' attach ON (attach.object_id=entry.id AND attach.`type` = "H") ' - .' LEFT JOIN '.TICKET_COLLABORATOR_TABLE.' collab - ON ( ticket.ticket_id=collab.ticket_id) ' + .' LEFT JOIN '.THREAD_COLLABORATOR_TABLE.' collab + ON ( thread.id=collab.thread_id) ' .' WHERE ticket.ticket_id IN ('.implode(',', db_input(array_keys($results))).') GROUP BY ticket.ticket_id'; $ids_res = db_query($counts_sql); diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index 5bda5f6374998dd31bf662c8fe8a37b3e8375eb1..0560eaf00ce70eacee1048f45dd9903a13368843 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -43,7 +43,7 @@ if (!$errors['err']) { if ($lock && $lock->getStaffId()!=$thisstaff->getId()) $errors['err'] = sprintf(__('This ticket is currently locked by %s'), $lock->getStaffName()); - elseif (($emailBanned=TicketFilter::isBanned($ticket->getEmail()))) + elseif (($emailBanned=Banlist::isBanned($ticket->getEmail()))) $errors['err'] = __('Email is in banlist! Must be removed before any reply/response'); } @@ -376,8 +376,7 @@ foreach (DynamicFormEntry::forTicket($ticket->getId()) as $form) { <div class="clear"></div> <h2 style="padding:10px 0 5px 0; font-size:11pt;"><?php echo Format::htmlchars($ticket->getSubject()); ?></h2> <?php -$tcount = $ticket->getThreadCount(); -$tcount+= $ticket->getNumNotes(); +$tcount = $ticket->getThreadEntries($types)->count(); ?> <ul class="tabs threads" id="ticket_tabs" > <li class="active"><a href="#ticket_thread"><?php echo sprintf(__('Ticket Thread (%d)'), $tcount); ?></a></li> @@ -390,32 +389,31 @@ $tcount+= $ticket->getNumNotes(); ?></a></li> </ul> <div id="ticket_tabs_container"> - <div id="ticket_thread" class="tab_content"> + <div id="ticket_thread" data-thread-id="<?php echo $ticket->getThread()->getId(); ?>" class="tab_content"> <?php $threadTypes=array('M'=>'message','R'=>'response', 'N'=>'note'); /* -------- Messages & Responses & Notes (if inline)-------------*/ $types = array('M', 'R', 'N'); if(($thread=$ticket->getThreadEntries($types))) { - foreach($thread as $entry) { - $tentry = $ticket->getThreadEntry($entry['id']); ?> - <table class="thread-entry <?php echo $threadTypes[$entry['type']]; ?>" cellspacing="0" cellpadding="1" width="940" border="0"> + foreach($thread as $entry) { ?> + <table class="thread-entry <?php echo $threadTypes[$entry->type]; ?>" cellspacing="0" cellpadding="1" width="940" border="0"> <tr> <th colspan="4" width="100%"> <div> <span class="pull-left"> <span style="display:inline-block"><?php - echo Format::datetime($entry['created']);?></span> + echo Format::datetime($entry->created);?></span> <span style="display:inline-block;padding:0 1em" class="faded title"><?php - echo Format::truncate($entry['title'], 100); ?></span> + echo Format::truncate($entry->title, 100); ?></span> </span> -<?php if ($tentry->hasActions()) { - $actions = $tentry->getActions(); ?> - <div class="pull-right"> - <span class="action-button pull-right" data-dropdown="#entry-action-more-<?php echo $entry['id']; ?>"> + <div class="pull-right"> +<?php if ($entry->hasActions()) { + $actions = $entry->getActions(); ?> + <span class="action-button pull-right" data-dropdown="#entry-action-more-<?php echo $entry->getId(); ?>"> <i class="icon-caret-down"></i> <span ><i class="icon-cog"></i></span> </span> - <div id="entry-action-more-<?php echo $entry['id']; ?>" class="action-dropdown anchor-right"> + <div id="entry-action-more-<?php echo $entry->getId(); ?>" class="action-dropdown anchor-right"> <ul class="title"> <?php foreach ($actions as $group => $list) { foreach ($list as $id => $action) { ?> @@ -434,36 +432,47 @@ $tcount+= $ticket->getNumNotes(); <span style="vertical-align:middle;" class="textra"></span> <span style="vertical-align:middle;" class="tmeta faded title"><?php - echo Format::htmlchars($entry['name'] ?: $entry['poster']); ?></span> + echo Format::htmlchars($entry->getName()); ?></span> </span> </div> </th> </tr> <tr><td colspan="4" class="thread-body" id="thread-id-<?php - echo $entry['id']; ?>"><div><?php - echo Format::clickableurls($entry['body']->toHtml()); ?></div></td></tr> + echo $entry->getId(); ?>"><div><?php + echo $entry->getBody()->toHtml(); ?></div></td></tr> <?php $urls = null; - if($entry['attachments'] - && ($urls = $tentry->getAttachmentUrls()) - && ($links = $tentry->getAttachmentsLinks())) {?> + if ($entry->has_attachments + && ($urls = $entry->getAttachmentUrls())) { ?> <tr> - <td class="info" colspan="4"><?php echo $links; ?></td> + <td class="info" colspan="4"><?php + foreach ($entry->attachments as $A) { + if ($A->inline) continue; + $size = ''; + if ($A->file->size) + $size = sprintf('<em>(%s)</em>', + Format::file_size($A->file->size)); +?> + <a class="Icon file no-pjax" href="<?php echo $A->file->getDownloadUrl(); + ?>" target="_blank"><?php echo Format::htmlchars($A->file->name); + ?></a><?php echo $size;?> +<?php } ?> + </td> </tr> <?php } if ($urls) { ?> <script type="text/javascript"> - $('#thread-id-<?php echo $entry['id']; ?>') + $('#thread-id-<?php echo $entry->getId(); ?>') .data('urls', <?php echo JsonDataEncoder::encode($urls); ?>) - .data('id', <?php echo $entry['id']; ?>); + .data('id', <?php echo $entry->getId(); ?>); </script> <?php } ?> </table> <?php - if ($entry['type'] == 'M') - $msgId = $entry['id']; + if ($entry->type == 'M') + $msgId = $entry->getId(); } } else { echo '<p><em>'.__('No entries have been posted to this ticket.').'</em></p>'; @@ -505,6 +514,7 @@ $tcount+= $ticket->getNumNotes(); <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>"> <input type="hidden" name="msgId" value="<?php echo $msgId; ?>"> <input type="hidden" name="a" value="reply"> + <input type="hidden" name="lockCode" value="<?php echo $ticket->getLock()->getCode(); ?>"> <span class="error"></span> <table style="width:100%" border="0" cellspacing="0" cellpadding="3"> <tbody id="to_sec"> @@ -693,6 +703,7 @@ $tcount+= $ticket->getNumNotes(); <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>"> <input type="hidden" name="locktime" value="<?php echo $cfg->getLockTime(); ?>"> <input type="hidden" name="a" value="postnote"> + <input type="hidden" name="lockCode" value="<?php echo $ticket->getLock()->getCode(); ?>"> <table width="100%" border="0" cellspacing="0" cellpadding="3"> <?php if($errors['postnote']) {?> @@ -1059,4 +1070,18 @@ $(function() { }(); <?php } ?> }); + +<?php +// Hover support for all inline images +$urls = array(); +foreach (AttachmentFile::objects()->filter(array( + 'attachments__thread_entry__thread__id' => $ticket->getThreadId(), + 'attachments__inline' => true, +)) as $file) { + $urls[strtolower($file->getKey())] = array( + 'download_url' => $file->getDownloadUrl(), + 'filename' => $file->name, + ); +} ?> +$.showImagesInline(<?php echo JsonDataEncoder::encode($urls); ?>); </script> diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php index a0095521d522506be52a71d9a35efddae416837f..9f74d1cb1e56af233bda2eb89cbd8ac34af26728 100644 --- a/include/staff/tickets.inc.php +++ b/include/staff/tickets.inc.php @@ -106,7 +106,7 @@ $tickets->filter(Q::any($visibility)); // Add in annotations $tickets->annotate(array( - 'collab_count' => SqlAggregate::COUNT('collaborators'), + 'collab_count' => SqlAggregate::COUNT('thread__collaborators'), 'attachment_count' => SqlAggregate::COUNT('thread__entries__attachments'), 'thread_count' => SqlAggregate::COUNT('thread__entries'), )); diff --git a/include/tnef_decoder.php b/include/tnef_decoder.php index e0f7869ba82b4ce554ada486efbfb1ae9cc4bb67..70e455851fc69d236f822ed033fdb7e731219f57 100644 --- a/include/tnef_decoder.php +++ b/include/tnef_decoder.php @@ -341,7 +341,7 @@ class TnefAttributeStreamReader extends TnefStreamReader { /* Read and truncate to length. */ $text = substr($this->_getx($datalen), 0, $length); if ($type == self::TypeUnicode) { - $text = Format::encode($text, 'ucs2'); + $text = Charset::utf8($text, 'ucs2'); } return $text; @@ -543,7 +543,7 @@ class TnefMessage extends AbstractTnefObject { // Transcode it if ($encoding && $charset) - $body = Format::encode($body, $charset, $encoding); + $body = Charset::transcode($body, $charset, $encoding); return $body; } diff --git a/include/upgrader/streams/core.sig b/include/upgrader/streams/core.sig index 3cbda6fa0ad2b31ab58b8b2c3201f386774c454a..68f58c5ebd07db09e5e22e9d52f6f4a4c63a1c17 100644 --- a/include/upgrader/streams/core.sig +++ b/include/upgrader/streams/core.sig @@ -1 +1 @@ -a22c2b4ff54ce5aa61e94124a73e6eac +9143a511719555e8f8f09b49523bd022 diff --git a/include/upgrader/streams/core/15b30765-dd0022fb.task.php b/include/upgrader/streams/core/15b30765-dd0022fb.task.php index 4d7eac01ff94a7622a16b118b5c567d41d3a9af0..0bf1576190be9a1eb3cd3de3a60f87115fa99e00 100644 --- a/include/upgrader/streams/core/15b30765-dd0022fb.task.php +++ b/include/upgrader/streams/core/15b30765-dd0022fb.task.php @@ -188,7 +188,7 @@ class AttachmentMigrater extends MigrationTask { # TODO: Get the size and mime/type of each file. # # NOTE: If filesize() fails and file_get_contents() doesn't, - # then the AttachmentFile::save() method will automatically + # then the AttachmentFile::create() method will automatically # estimate the filesize based on the length of the string data # received in $info['data'] -- ie. no need to do that here. # @@ -228,9 +228,9 @@ class AttachmentMigrater extends MigrationTask { return $this->errorList; } - // This is the AttachmentFile::save() method from osTicket 1.7.6. It's + // This is the AttachmentFile::create() method from osTicket 1.7.6. It's // been ported here so that further changes to the %file table and the - // AttachmentFile::save() method do not affect upgrades from osTicket + // AttachmentFile::create() method do not affect upgrades from osTicket // 1.6 to osTicket 1.8 and beyond. function saveAttachment($file) { diff --git a/include/upgrader/streams/core/1ee831c8-36f6b328.task.php b/include/upgrader/streams/core/1ee831c8-36f6b328.task.php index ef8cd369069ee874343ebf3083a3d4c2c688a17c..d507553358cb17a25ecef590cf3c127f89dbedc7 100644 --- a/include/upgrader/streams/core/1ee831c8-36f6b328.task.php +++ b/include/upgrader/streams/core/1ee831c8-36f6b328.task.php @@ -37,7 +37,8 @@ class GroupRoles extends MigrationTask { $ht['permissions'] = $perms; - $role = Role::__create($ht); + $errors = array(); + $role = Role::__create($ht, $errors); $group->role_id = $role->getId(); $group->save(); } diff --git a/include/upgrader/streams/core/2d590ffa-9143a511.patch.sql b/include/upgrader/streams/core/2d590ffa-9143a511.patch.sql new file mode 100644 index 0000000000000000000000000000000000000000..2ef8275451131a38d2e7775b1a0d4b143d243e7e --- /dev/null +++ b/include/upgrader/streams/core/2d590ffa-9143a511.patch.sql @@ -0,0 +1,52 @@ +/* + * @signature 9143a511719555e8f8f09b49523bd022 + * @version v1.9.6 + * @title All collaborators have threads + * + * This patch renames the %ticket_lock table to just %lock, which allows for + * it to be considered more flexible. Instead, it joins the lock to the + * ticket and task objects directly. + * + * It also redefines the collaborator table to link to a thread rather than + * to a ticket, which allows any object in the system with a thread to + * theoretically have collaborators. + */ + +ALTER TABLE `%TABLE_PREFIX%ticket` + ADD `lock_id` int(11) unsigned NOT NULL default '0' AFTER `email_id`; + +RENAME TABLE `%TABLE_PREFIX%ticket_lock` TO `%TABLE_PREFIX%lock`; +ALTER TABLE `%TABLE_PREFIX%lock` + DROP COLUMN `ticket_id`, + ADD `code` varchar(20) AFTER `expire`; + +-- Drop all the current locks as they do not point to anything now +TRUNCATE TABLE `%TABLE_PREFIX%lock`; + +RENAME TABLE `%TABLE_PREFIX%ticket_collaborator` TO `%TABLE_PREFIX%thread_collaborator`; +ALTER TABLE `%TABLE_PREFIX%thread_collaborator` + CHANGE `ticket_id` `thread_id` int(11) unsigned NOT NULL DEFAULT '0'; + +ALTER TABLE `%TABLE_PREFIX%task` + ADD `lock_id` int(11) unsigned NOT NULL DEFAULT '0' AFTER `team_id`; + +ALTER TABLE `%TABLE_PREFIX%thread_entry` + ADD `flags` int(11) unsigned NOT NULL default '0' AFTER `type`; + +-- Set the ORIGINAL_MESSAGE flag to all the first messages of each thread +CREATE TABLE `%TABLE_PREFIX%_orig_msg_ids` + (id INT NOT NULL, PRIMARY KEY (id)) + SELECT min(id) as id FROM `%TABLE_PREFIX%thread_entry` + WHERE type = 'M' + GROUP BY thread_id; + +UPDATE `%TABLE_PREFIX%thread_entry` A1 + JOIN `%TABLE_PREFIX%_orig_msg_ids` A2 ON (A1.id = A2.id) + SET A1.`flags` = 1 ; + +DROP TABLE `%TABLE_PREFIX%_orig_msg_ids`; + +-- Finished with patch +UPDATE `%TABLE_PREFIX%config` + SET `value` = '9143a511719555e8f8f09b49523bd022' + WHERE `key` = 'schema_signature' AND `namespace` = 'core'; diff --git a/include/upgrader/streams/core/5cd0a25a-a22c2b4f.cleanup.sql b/include/upgrader/streams/core/5cd0a25a-2d590ffa.cleanup.sql similarity index 79% rename from include/upgrader/streams/core/5cd0a25a-a22c2b4f.cleanup.sql rename to include/upgrader/streams/core/5cd0a25a-2d590ffa.cleanup.sql index dd4a3f887dee2d7a24c557287cf94052c4fd2640..409ff700c9de2ed17bb740b268cd37efa8a3c601 100644 --- a/include/upgrader/streams/core/5cd0a25a-a22c2b4f.cleanup.sql +++ b/include/upgrader/streams/core/5cd0a25a-2d590ffa.cleanup.sql @@ -1,11 +1,11 @@ /** - * @signature 0e47d678f50874fa0d33e1e3759f657e + * @signature 2d590ffab4a6a928f08cc97aace1399e * @version v1.9.6 * @title Make fields disable-able per help topic */ ALTER TABLE `%TABLE_PREFIX%help_topic` - DROP `form_id` int(10) unsigned NOT NULL default '0'; + DROP `form_id`; ALTER TABLE `%TABLE_PREFIX%filter` DROP `reject_ticket`, diff --git a/include/upgrader/streams/core/5cd0a25a-a22c2b4f.patch.sql b/include/upgrader/streams/core/5cd0a25a-2d590ffa.patch.sql similarity index 95% rename from include/upgrader/streams/core/5cd0a25a-a22c2b4f.patch.sql rename to include/upgrader/streams/core/5cd0a25a-2d590ffa.patch.sql index 509c83519cff637457c87a20df6b68c1db00de6a..49ffc43951ad6a90037a46d23eb98c43429bfd13 100644 --- a/include/upgrader/streams/core/5cd0a25a-a22c2b4f.patch.sql +++ b/include/upgrader/streams/core/5cd0a25a-2d590ffa.patch.sql @@ -1,5 +1,5 @@ /** - * @signature a22c2b4ff54ce5aa61e94124a73e6eac + * @signature 2d590ffab4a6a928f08cc97aace1399e * @version v1.9.6 * @title Make fields disable-able per help topic * @@ -104,7 +104,8 @@ CREATE TABLE `%TABLE_PREFIX%help_topic_form` ( `form_id` int(10) unsigned NOT NULL default 0, `sort` int(10) unsigned NOT NULL default 1, `extra` text, - PRIMARY KEY (`topic_id`, `form_id`) + PRIMARY KEY (`id`), + KEY `topic-form` (`topic_id`, `form_id`) ) DEFAULT CHARSET=utf8; -- Handle A4 / A3 / A2 / A1 help topics. For these, consider the forms @@ -129,10 +130,7 @@ insert into `%TABLE_PREFIX%help_topic_form` join `%TABLE_PREFIX%help_topic` A2 where A1.`type` = 'T'; -ALTER TABLE `%TABLE_PREFIX%help_topic` - DROP `form_id` int(10) unsigned NOT NULL default '0'; - -- Finished with patch UPDATE `%TABLE_PREFIX%config` - SET `value` = 'a22c2b4ff54ce5aa61e94124a73e6eac' + SET `value` = '2d590ffab4a6a928f08cc97aace1399e' WHERE `key` = 'schema_signature' AND `namespace` = 'core'; diff --git a/include/upgrader/streams/core/5cd0a25a-a22c2b4f.task.php b/include/upgrader/streams/core/5cd0a25a-2d590ffa.task.php similarity index 86% rename from include/upgrader/streams/core/5cd0a25a-a22c2b4f.task.php rename to include/upgrader/streams/core/5cd0a25a-2d590ffa.task.php index 0379bd4becece7cb4cf4688acfc891b1c08098ca..f18c0cab94359c5af4e6a2994685514b2a96f88b 100644 --- a/include/upgrader/streams/core/5cd0a25a-a22c2b4f.task.php +++ b/include/upgrader/streams/core/5cd0a25a-2d590ffa.task.php @@ -1,6 +1,6 @@ <?php -class InstructionPorter extends MigrationTask { +class InstructionsPorter extends MigrationTask { var $description = "Converting custom form instructions to HTML"; function run($max_time) { diff --git a/include/upgrader/streams/core/8f99b8bf-03ff59bf.task.php b/include/upgrader/streams/core/8f99b8bf-03ff59bf.task.php index f7bb36f7db2da78056a307b730543f6cc43ad5b0..cd41e131bdc7617503aa789d731e538ad0fb7db5 100644 --- a/include/upgrader/streams/core/8f99b8bf-03ff59bf.task.php +++ b/include/upgrader/streams/core/8f99b8bf-03ff59bf.task.php @@ -19,17 +19,8 @@ class SequenceLoader extends MigrationTask { .'(SELECT MAX(ticket_id)+1 FROM '.TICKET_TABLE.') ' .'WHERE `id`=1'); - require_once(INCLUDE_DIR . 'class.list.php'); - - $lists = $i18n->getTemplate('list.yaml')->getData(); - foreach ($lists as $l) { - DynamicList::create($l); - } - - $statuses = $i18n->getTemplate('ticket_status.yaml')->getData(); - foreach ($statuses as $s) { - TicketStatus::__create($s); - } + // list.yaml and ticket_status.yaml import moved to + // core/b26f29a6-1ee831c8.task.php // Initialize MYSQL search backend MysqlSearchBackend::__init(); diff --git a/include/upgrader/streams/core/934954de-f1ccd3bb.task.php b/include/upgrader/streams/core/934954de-f1ccd3bb.task.php new file mode 100644 index 0000000000000000000000000000000000000000..041bfad9a33730283e1203d6711bbafcaa27a548 --- /dev/null +++ b/include/upgrader/streams/core/934954de-f1ccd3bb.task.php @@ -0,0 +1,24 @@ +<?php + +class FileImport extends MigrationTask { + var $description = "Import core osTicket attachment files"; + + function run($runtime) { + $i18n = new Internationalization('en_US'); + $files = $i18n->getTemplate('file.yaml')->getData(); + foreach ($files as $f) { + if (!($file = AttachmentFile::create($f))) + continue; + + // Ensure the new files are never deleted (attached to Disk) + $sql ='INSERT INTO '.ATTACHMENT_TABLE + .' SET object_id=0, `type`=\'D\', inline=1' + .', file_id='.db_input($file->getId()); + db_query($sql); + } + } +} + +return 'FileImport'; + +?> diff --git a/include/upgrader/streams/core/b26f29a6-1ee831c8.task.php b/include/upgrader/streams/core/b26f29a6-1ee831c8.task.php index ba6d63515b8bee4a3535185464103057ce66a7fa..19bed1964633046d1152708ca9b4574210738783 100644 --- a/include/upgrader/streams/core/b26f29a6-1ee831c8.task.php +++ b/include/upgrader/streams/core/b26f29a6-1ee831c8.task.php @@ -69,6 +69,20 @@ class IntlMigrator extends MigrationTask { // Add in new custom date format flag $cfg->set('date_formats', $touched ? 'custom' : '' ); + + // Moved here from core/8f99b8bf-03ff59bf.task.php + require_once(INCLUDE_DIR . 'class.list.php'); + $i18n = new Internationalization($cfg->get('system_language', 'en_US')); + $lists = $i18n->getTemplate('list.yaml')->getData(); + foreach ($lists as $l) { + DynamicList::create($l); + } + + $statuses = $i18n->getTemplate('ticket_status.yaml')->getData(); + foreach ($statuses as $s) { + TicketStatus::__create($s); + } + } } diff --git a/include/upgrader/streams/core/d51f303a-dad45ca2.task.php b/include/upgrader/streams/core/d51f303a-dad45ca2.task.php index 309f68e836e9f808a47fd3e69f6f143642226597..03a77f61d6349db29cd3d058ffa629afc388f53f 100644 --- a/include/upgrader/streams/core/d51f303a-dad45ca2.task.php +++ b/include/upgrader/streams/core/d51f303a-dad45ca2.task.php @@ -16,16 +16,7 @@ class NewHtmlTemplate extends MigrationTask { EmailTemplateGroup::create($t, $errors); } - $files = $i18n->getTemplate('file.yaml')->getData(); - foreach ($files as $f) { - $id = AttachmentFile::create($f, $errors); - - // Ensure the new files are never deleted (attached to Disk) - $sql ='INSERT INTO '.ATTACHMENT_TABLE - .' SET object_id=0, `type`=\'D\', inline=1' - .', file_id='.db_input($id); - db_query($sql); - } + // NOTE: Core files import moved to 934954de-f1ccd3bb.task.php } } return 'NewHtmlTemplate'; diff --git a/include/upgrader/streams/core/dad45ca2-61c9d5d7.task.php b/include/upgrader/streams/core/dad45ca2-61c9d5d7.task.php index 98d128fbdaed3a1a4a57fe3af06cd0fbb99c591e..9f046b3e68716184692821096d20498955be0a0a 100644 --- a/include/upgrader/streams/core/dad45ca2-61c9d5d7.task.php +++ b/include/upgrader/streams/core/dad45ca2-61c9d5d7.task.php @@ -11,9 +11,50 @@ class DynamicFormLoader extends MigrationTask { function run($max_time) { $i18n = new Internationalization('en_US'); $forms = $i18n->getTemplate('form.yaml')->getData(); - foreach ($forms as $f) + foreach ($forms as &$f) { + // Only import forms which exist at this stage. + if (!in_array($f['type'], array('U', 'T', 'C', 'O'))) + continue; + + if ($f['fields']) { + foreach($f['fields'] as &$field) { + $flags = $field['flags']; + // Edit mask + $field['edit_mask'] = $this->f2m($flags); + // private + if (!($flags & DynamicFormField::FLAG_CLIENT_VIEW)) + $field['private'] = true; + // required + if (($flags & DynamicFormField::FLAG_CLIENT_REQUIRED) + || ($flags & DynamicFormField::FLAG_AGENT_REQUIRED)) + $field['required'] = true; + + unset($field['flags']); + } + unset($field); + } + DynamicForm::create($f); + } + unset($f); } + + function f2m($flags) { + $masks = array( + 1 => DynamicFormField::FLAG_MASK_DELETE, + 2 => DynamicFormField::FLAG_MASK_NAME, + 4 => DynamicFormField::FLAG_MASK_VIEW, + 8 => DynamicFormField::FLAG_MASK_REQUIRE + ); + + $mask = 0; + foreach ($masks as $k => $v) + if (($flags & $v) != 0) + $mask += $k; + + return $mask; + } + } return 'DynamicFormLoader'; diff --git a/js/fabric.min.js b/js/fabric.min.js new file mode 100644 index 0000000000000000000000000000000000000000..dbcd34b8697579c8b766d39959771260dfaa7ade --- /dev/null +++ b/js/fabric.min.js @@ -0,0 +1,8 @@ +/* build: `node build.js modules=ALL exclude=gestures,cufon,json minifier=uglifyjs` *//*! Fabric.js Copyright 2008-2014, Printio (Juriy Zaytsev, Maxim Chernyak) */var fabric=fabric||{version:"1.4.13"};typeof exports!="undefined"&&(exports.fabric=fabric),typeof document!="undefined"&&typeof window!="undefined"?(fabric.document=document,fabric.window=window):(fabric.document=require("jsdom").jsdom("<!DOCTYPE html><html><head></head><body></body></html>"),fabric.document.createWindow?fabric.window=fabric.document.createWindow():fabric.window=fabric.document.parentWindow),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,fabric.isLikelyNode=typeof Buffer!="undefined"&&typeof window=="undefined",fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width"],fabric.DPI=96,fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",function(){function e(e,t){if(!this.__eventListeners[e])return;t?fabric.util.removeFromArray(this.__eventListeners[e],t):this.__eventListeners[e].length=0}function t(e,t){this.__eventListeners||(this.__eventListeners={});if(arguments.length===1)for(var n in e)this.on(n,e[n]);else this.__eventListeners[e]||(this.__eventListeners[e]=[]),this.__eventListeners[e].push(t);return this}function n(t,n){if(!this.__eventListeners)return;if(arguments.length===0)this.__eventListeners={};else if(arguments.length===1&&typeof arguments[0]=="object")for(var r in t)e.call(this,r,t[r]);else e.call(this,t,n);return this}function r(e,t){if(!this.__eventListeners)return;var n=this.__eventListeners[e];if(!n)return;for(var r=0,i=n.length;r<i;r++)n[r].call(this,t||{});return this}fabric.Observable={observe:t,stopObserving:n,fire:r,on:t,off:n,trigger:r}}(),fabric.Collection={add:function(){this._objects.push.apply(this._objects,arguments);for(var e=0,t=arguments.length;e<t;e++)this._onObjectAdded(arguments[e]);return this.renderOnAddRemove&&this.renderAll(),this},insertAt:function(e,t,n){var r=this.getObjects();return n?r[t]=e:r.splice(t,0,e),this._onObjectAdded(e),this.renderOnAddRemove&&this.renderAll(),this},remove:function(){var e=this.getObjects(),t;for(var n=0,r=arguments.length;n<r;n++)t=e.indexOf(arguments[n]),t!==-1&&(e.splice(t,1),this._onObjectRemoved(arguments[n]));return this.renderOnAddRemove&&this.renderAll(),this},forEachObject:function(e,t){var n=this.getObjects(),r=n.length;while(r--)e.call(t,n[r],r,n);return this},getObjects:function(e){return typeof e=="undefined"?this._objects:this._objects.filter(function(t){return t.type===e})},item:function(e){return this.getObjects()[e]},isEmpty:function(){return this.getObjects().length===0},size:function(){return this.getObjects().length},contains:function(e){return this.getObjects().indexOf(e)>-1},complexity:function(){return this.getObjects().reduce(function(e,t){return e+=t.complexity?t.complexity():0,e},0)}},function(e){var t=Math.sqrt,n=Math.atan2,r=Math.PI/180;fabric.util={removeFromArray:function(e,t){var n=e.indexOf(t);return n!==-1&&e.splice(n,1),e},getRandomInt:function(e,t){return Math.floor(Math.random()*(t-e+1))+e},degreesToRadians:function(e){return e*r},radiansToDegrees:function(e){return e/r},rotatePoint:function(e,t,n){var r=Math.sin(n),i=Math.cos(n);e.subtractEquals(t);var s=e.x*i-e.y*r,o=e.x*r+e.y*i;return(new fabric.Point(s,o)).addEquals(t)},transformPoint:function(e,t,n){return n?new fabric.Point(t[0]*e.x+t[1]*e.y,t[2]*e.x+t[3]*e.y):new fabric.Point(t[0]*e.x+t[1]*e.y+t[4],t[2]*e.x+t[3]*e.y+t[5])},invertTransform:function(e){var t=e.slice(),n=1/(e[0]*e[3]-e[1]*e[2]);t=[n*e[3],-n*e[1],-n*e[2],n*e[0],0,0];var r=fabric.util.transformPoint({x:e[4],y:e[5]},t);return t[4]=-r.x,t[5]=-r.y,t},toFixed:function(e,t){return parseFloat(Number(e).toFixed(t))},parseUnit:function(e,t){var n=/\D{0,2}$/.exec(e),r=parseFloat(e);t||(t=fabric.Text.DEFAULT_SVG_FONT_SIZE);switch(n[0]){case"mm":return r*fabric.DPI/25.4;case"cm":return r*fabric.DPI/2.54;case"in":return r*fabric.DPI;case"pt":return r*fabric.DPI/72;case"pc":return r*fabric.DPI/72*12;case"em":return r*t;default:return r}},falseFunction:function(){return!1},getKlass:function(e,t){return e=fabric.util.string.camelize(e.charAt(0).toUpperCase()+e.slice(1)),fabric.util.resolveNamespace(t)[e]},resolveNamespace:function(t){if(!t)return fabric;var n=t.split("."),r=n.length,i=e||fabric.window;for(var s=0;s<r;++s)i=i[n[s]];return i},loadImage:function(e,t,n,r){if(!e){t&&t.call(n,e);return}var i=fabric.util.createImage();i.onload=function(){t&&t.call(n,i),i=i.onload=i.onerror=null},i.onerror=function(){fabric.log("Error loading "+i.src),t&&t.call(n,null,!0),i=i.onload=i.onerror=null},e.indexOf("data")!==0&&typeof r!="undefined"&&(i.crossOrigin=r),i.src=e},enlivenObjects:function(e,t,n,r){function i(){++o===u&&t&&t(s)}e=e||[];var s=[],o=0,u=e.length;if(!u){t&&t(s);return}e.forEach(function(e,t){if(!e||!e.type){i();return}var o=fabric.util.getKlass(e.type,n);o.async?o.fromObject(e,function(n,o){o||(s[t]=n,r&&r(e,s[t])),i()}):(s[t]=o.fromObject(e),r&&r(e,s[t]),i())})},groupSVGElements:function(e,t,n){var r;return r=new fabric.PathGroup(e,t),typeof n!="undefined"&&r.setSourcePath(n),r},populateWithProperties:function(e,t,n){if(n&&Object.prototype.toString.call(n)==="[object Array]")for(var r=0,i=n.length;r<i;r++)n[r]in e&&(t[n[r]]=e[n[r]])},drawDashedLine:function(e,r,i,s,o,u){var a=s-r,f=o-i,l=t(a*a+f*f),c=n(f,a),h=u.length,p=0,d=!0;e.save(),e.translate(r,i),e.moveTo(0,0),e.rotate(c),r=0;while(l>r)r+=u[p++%h],r>l&&(r=l),e[d?"lineTo":"moveTo"](r,0),d=!d;e.restore()},createCanvasElement:function(e){return e||(e=fabric.document.createElement("canvas")),!e.getContext&&typeof G_vmlCanvasManager!="undefined"&&G_vmlCanvasManager.initElement(e),e},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(e){var t=e.prototype;for(var n=t.stateProperties.length;n--;){var r=t.stateProperties[n],i=r.charAt(0).toUpperCase()+r.slice(1),s="set"+i,o="get"+i;t[o]||(t[o]=function(e){return new Function('return this.get("'+e+'")')}(r)),t[s]||(t[s]=function(e){return new Function("value",'return this.set("'+e+'", value)')}(r))}},clipContext:function(e,t){t.save(),t.beginPath(),e.clipTo(t),t.clip()},multiplyTransformMatrices:function(e,t){var n=[[e[0],e[2],e[4]],[e[1],e[3],e[5]],[0,0,1]],r=[[t[0],t[2],t[4]],[t[1],t[3],t[5]],[0,0,1]],i=[];for(var s=0;s<3;s++){i[s]=[];for(var o=0;o<3;o++){var u=0;for(var a=0;a<3;a++)u+=n[s][a]*r[a][o];i[s][o]=u}}return[i[0][0],i[1][0],i[0][1],i[1][1],i[0][2],i[1][2]]},getFunctionBody:function(e){return(String(e).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(e,t,n,r){r>0&&(t>r?t-=r:t=0,n>r?n-=r:n=0);var i=!0,s=e.getImageData(t,n,r*2||1,r*2||1);for(var o=3,u=s.data.length;o<u;o+=4){var a=s.data[o];i=a<=0;if(i===!1)break}return s=null,i}}}(typeof exports!="undefined"?exports:this),function(){function i(t,n,i,u,a,f,l){var c=r.call(arguments);if(e[c])return e[c];var h=Math.PI,p=l*h/180,d=Math.sin(p),v=Math.cos(p),m=0,g=0;i=Math.abs(i),u=Math.abs(u);var y=-v*t*.5-d*n*.5,b=-v*n*.5+d*t*.5,w=i*i,E=u*u,S=b*b,x=y*y,T=w*E-w*S-E*x,N=0;if(T<0){var C=Math.sqrt(1-T/(w*E));i*=C,u*=C}else N=(a===f?-1:1)*Math.sqrt(T/(w*S+E*x));var k=N*i*b/u,L=-N*u*y/i,A=v*k-d*L+t*.5,O=d*k+v*L+n*.5,M=o(1,0,(y-k)/i,(b-L)/u),_=o((y-k)/i,(b-L)/u,(-y-k)/i,(-b-L)/u);f===0&&_>0?_-=2*h:f===1&&_<0&&(_+=2*h);var D=Math.ceil(Math.abs(_/h*2)),P=[],H=_/D,B=8/3*Math.sin(H/4)*Math.sin(H/4)/Math.sin(H/2),j=M+H;for(var F=0;F<D;F++)P[F]=s(M,j,v,d,i,u,A,O,B,m,g),m=P[F][4],g=P[F][5],M=j,j+=H;return e[c]=P,P}function s(e,n,i,s,o,u,a,f,l,c,h){var p=r.call(arguments);if(t[p])return t[p];var d=Math.cos(e),v=Math.sin(e),m=Math.cos(n),g=Math.sin(n),y=i*o*m-s*u*g+a,b=s*o*m+i*u*g+f,w=c+l*(-i*o*v-s*u*d),E=h+l*(-s*o*v+i*u*d),S=y+l*(i*o*g+s*u*m),x=b+l*(s*o*g-i*u*m);return t[p]=[w,E,S,x,y,b],t[p]}function o(e,t,n,r){var i=Math.atan2(t,e),s=Math.atan2(r,n);return s>=i?s-i:2*Math.PI-(i-s)}function u(e,t,i,s,o,u,a,f){var l=r.call(arguments);if(n[l])return n[l];var c=Math.sqrt,h=Math.min,p=Math.max,d=Math.abs,v=[],m=[[],[]],g,y,b,w,E,S,x,T;y=6*e-12*i+6*o,g=-3*e+9*i-9*o+3*a,b=3*i-3*e;for(var N=0;N<2;++N){N>0&&(y=6*t-12*s+6*u,g=-3*t+9*s-9*u+3*f,b=3*s-3*t);if(d(g)<1e-12){if(d(y)<1e-12)continue;w=-b/y,0<w&&w<1&&v.push(w);continue}x=y*y-4*b*g;if(x<0)continue;T=c(x),E=(-y+T)/(2*g),0<E&&E<1&&v.push(E),S=(-y-T)/(2*g),0<S&&S<1&&v.push(S)}var C,k,L=v.length,A=L,O;while(L--)w=v[L],O=1-w,C=O*O*O*e+3*O*O*w*i+3*O*w*w*o+w*w*w*a,m[0][L]=C,k=O*O*O*t+3*O*O*w*s+3*O*w*w*u+w*w*w*f,m[1][L]=k;m[0][A]=e,m[1][A]=t,m[0][A+1]=a,m[1][A+1]=f;var M=[{x:h.apply(null,m[0]),y:h.apply(null,m[1])},{x:p.apply(null,m[0]),y:p.apply(null,m[1])}];return n[l]=M,M}var e={},t={},n={},r=Array.prototype.join;fabric.util.drawArc=function(e,t,n,r){var s=r[0],o=r[1],u=r[2],a=r[3],f=r[4],l=r[5],c=r[6],h=[[],[],[],[]],p=i(l-t,c-n,s,o,a,f,u);for(var d=0,v=p.length;d<v;d++)h[d][0]=p[d][0]+t,h[d][1]=p[d][1]+n,h[d][2]=p[d][2]+t,h[d][3]=p[d][3]+n,h[d][4]=p[d][4]+t,h[d][5]=p[d][5]+n,e.bezierCurveTo.apply(e,h[d])},fabric.util.getBoundsOfArc=function(e,t,n,r,s,o,a,f,l){var c=0,h=0,p=[],d=[],v=i(f-e,l-t,n,r,o,a,s);for(var m=0,g=v.length;m<g;m++)p=u(c,h,v[m][0],v[m][1],v[m][2],v[m][3],v[m][4],v[m][5]),p[0].x+=e,p[0].y+=t,p[1].x+=e,p[1].y+=t,d.push(p[0]),d.push(p[1]),c=v[m][4],h=v[m][5];return d},fabric.util.getBoundsOfCurve=u}(),function(){function t(t,n){var r=e.call(arguments,2),i=[];for(var s=0,o=t.length;s<o;s++)i[s]=r.length?t[s][n].apply(t[s],r):t[s][n].call(t[s]);return i}function n(e,t){return i(e,t,function(e,t){return e>=t})}function r(e,t){return i(e,t,function(e,t){return e<t})}function i(e,t,n){if(!e||e.length===0)return;var r=e.length-1,i=t?e[r][t]:e[r];if(t)while(r--)n(e[r][t],i)&&(i=e[r][t]);else while(r--)n(e[r],i)&&(i=e[r]);return i}var e=Array.prototype.slice;Array.prototype.indexOf||(Array.prototype.indexOf=function(e){if(this===void 0||this===null)throw new TypeError;var t=Object(this),n=t.length>>>0;if(n===0)return-1;var r=0;arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:r!==0&&r!==Number.POSITIVE_INFINITY&&r!==Number.NEGATIVE_INFINITY&&(r=(r>0||-1)*Math.floor(Math.abs(r))));if(r>=n)return-1;var i=r>=0?r:Math.max(n-Math.abs(r),0);for(;i<n;i++)if(i in t&&t[i]===e)return i;return-1}),Array.prototype.forEach||(Array.prototype.forEach=function(e,t){for(var n=0,r=this.length>>>0;n<r;n++)n in this&&e.call(t,this[n],n,this)}),Array.prototype.map||(Array.prototype.map=function(e,t){var n=[];for(var r=0,i=this.length>>>0;r<i;r++)r in this&&(n[r]=e.call(t,this[r],r,this));return n}),Array.prototype.every||(Array.prototype.every=function(e,t){for(var n=0,r=this.length>>>0;n<r;n++)if(n in this&&!e.call(t,this[n],n,this))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(e,t){for(var n=0,r=this.length>>>0;n<r;n++)if(n in this&&e.call(t,this[n],n,this))return!0;return!1}),Array.prototype.filter||(Array.prototype.filter=function(e,t){var n=[],r;for(var i=0,s=this.length>>>0;i<s;i++)i in this&&(r=this[i],e.call(t,r,i,this)&&n.push(r));return n}),Array.prototype.reduce||(Array.prototype.reduce=function(e){var t=this.length>>>0,n=0,r;if(arguments.length>1)r=arguments[1];else do{if(n in this){r=this[n++];break}if(++n>=t)throw new TypeError}while(!0);for(;n<t;n++)n in this&&(r=e.call(null,r,this[n],n,this));return r}),fabric.util.array={invoke:t,min:r,max:n}}(),function(){function e(e,t){for(var n in t)e[n]=t[n];return e}function t(t){return e({},t)}fabric.util.object={extend:e,clone:t}}(),function(){function e(e){return e.replace(/-+(.)?/g,function(e,t){return t?t.toUpperCase():""})}function t(e,t){return e.charAt(0).toUpperCase()+(t?e.slice(1):e.slice(1).toLowerCase())}function n(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\xA0]+/,"").replace(/[\s\xA0]+$/,"")}),fabric.util.string={camelize:e,capitalize:t,escapeXml:n}}(),function(){var e=Array.prototype.slice,t=Function.prototype.apply,n=function(){};Function.prototype.bind||(Function.prototype.bind=function(r){var i=this,s=e.call(arguments,1),o;return s.length?o=function(){return t.call(i,this instanceof n?this:r,s.concat(e.call(arguments)))}:o=function(){return t.call(i,this instanceof n?this:r,arguments)},n.prototype=this.prototype,o.prototype=new n,o})}(),function(){function i(){}function s(t){var n=this.constructor.superclass.prototype[t];return arguments.length>1?n.apply(this,e.call(arguments,1)):n.call(this)}function o(){function u(){this.initialize.apply(this,arguments)}var n=null,o=e.call(arguments,0);typeof o[0]=="function"&&(n=o.shift()),u.superclass=n,u.subclasses=[],n&&(i.prototype=n.prototype,u.prototype=new i,n.subclasses.push(u));for(var a=0,f=o.length;a<f;a++)r(u,o[a],n);return u.prototype.initialize||(u.prototype.initialize=t),u.prototype.constructor=u,u.prototype.callSuper=s,u}var e=Array.prototype.slice,t=function(){},n=function(){for(var e in{toString:1})if(e==="toString")return!1;return!0}(),r=function(e,t,r){for(var i in t)i in e.prototype&&typeof e.prototype[i]=="function"&&(t[i]+"").indexOf("callSuper")>-1?e.prototype[i]=function(e){return function(){var n=this.constructor.superclass;this.constructor.superclass=r;var i=t[e].apply(this,arguments);this.constructor.superclass=n;if(e!=="initialize")return i}}(i):e.prototype[i]=t[i],n&&(t.toString!==Object.prototype.toString&&(e.prototype.toString=t.toString),t.valueOf!==Object.prototype.valueOf&&(e.prototype.valueOf=t.valueOf))};fabric.util.createClass=o}(),function(){function t(e){var t=Array.prototype.slice.call(arguments,1),n,r,i=t.length;for(r=0;r<i;r++){n=typeof e[t[r]];if(!/^(?:function|object|unknown)$/.test(n))return!1}return!0}function s(e,t){return{handler:t,wrappedHandler:o(e,t)}}function o(e,t){return function(r){t.call(n(e),r||fabric.window.event)}}function u(e,t){return function(n){if(c[e]&&c[e][t]){var r=c[e][t];for(var i=0,s=r.length;i<s;i++)r[i].call(this,n||fabric.window.event)}}}function d(t,n){t||(t=fabric.window.event);var r=t.target||(typeof t.srcElement!==e?t.srcElement:null),i=fabric.util.getScrollLeftTop(r,n);return{x:v(t)+i.left,y:m(t)+i.top}}function g(e,t,n){var r=e.type==="touchend"?"changedTouches":"touches";return e[r]&&e[r][0]?e[r][0][t]-(e[r][0][t]-e[r][0][n])||e[n]:e[n]}var e="unknown",n,r,i=function(){var e=0;return function(t){return t.__uniqueID||(t.__uniqueID="uniqueID__"+e++)}}();(function(){var e={};n=function(t){return e[t]},r=function(t,n){e[t]=n}})();var a=t(fabric.document.documentElement,"addEventListener","removeEventListener")&&t(fabric.window,"addEventListener","removeEventListener"),f=t(fabric.document.documentElement,"attachEvent","detachEvent")&&t(fabric.window,"attachEvent","detachEvent"),l={},c={},h,p;a?(h=function(e,t,n){e.addEventListener(t,n,!1)},p=function(e,t,n){e.removeEventListener(t,n,!1)}):f?(h=function(e,t,n){var o=i(e);r(o,e),l[o]||(l[o]={}),l[o][t]||(l[o][t]=[]);var u=s(o,n);l[o][t].push(u),e.attachEvent("on"+t,u.wrappedHandler)},p=function(e,t,n){var r=i(e),s;if(l[r]&&l[r][t])for(var o=0,u=l[r][t].length;o<u;o++)s=l[r][t][o],s&&s.handler===n&&(e.detachEvent("on"+t,s.wrappedHandler),l[r][t][o]=null)}):(h=function(e,t,n){var r=i(e);c[r]||(c[r]={});if(!c[r][t]){c[r][t]=[];var s=e["on"+t];s&&c[r][t].push(s),e["on"+t]=u(r,t)}c[r][t].push(n)},p=function(e,t,n){var r=i(e);if(c[r]&&c[r][t]){var s=c[r][t];for(var o=0,u=s.length;o<u;o++)s[o]===n&&s.splice(o,1)}}),fabric.util.addListener=h,fabric.util.removeListener=p;var v=function(t){return typeof t.clientX!==e?t.clientX:0},m=function(t){return typeof t.clientY!==e?t.clientY:0};fabric.isTouchSupported&&(v=function(e){return g(e,"pageX","clientX")},m=function(e){return g(e,"pageY","clientY")}),fabric.util.getPointer=d,fabric.util.object.extend(fabric.util,fabric.Observable)}(),function(){function e(e,t){var n=e.style;if(!n)return e;if(typeof t=="string")return e.style.cssText+=";"+t,t.indexOf("opacity")>-1?s(e,t.match(/opacity:\s*(\d?\.?\d*)/)[1]):e;for(var r in t)if(r==="opacity")s(e,t[r]);else{var i=r==="float"||r==="cssFloat"?typeof n.styleFloat=="undefined"?"cssFloat":"styleFloat":r;n[i]=t[r]}return e}var t=fabric.document.createElement("div"),n=typeof t.style.opacity=="string",r=typeof t.style.filter=="string",i=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,s=function(e){return e};n?s=function(e,t){return e.style.opacity=t,e}:r&&(s=function(e,t){var n=e.style;return e.currentStyle&&!e.currentStyle.hasLayout&&(n.zoom=1),i.test(n.filter)?(t=t>=.9999?"":"alpha(opacity="+t*100+")",n.filter=n.filter.replace(i,t)):n.filter+=" alpha(opacity="+t*100+")",e}),fabric.util.setStyle=e}(),function(){function t(e){return typeof e=="string"?fabric.document.getElementById(e):e}function s(e,t){var n=fabric.document.createElement(e);for(var r in t)r==="class"?n.className=t[r]:r==="for"?n.htmlFor=t[r]:n.setAttribute(r,t[r]);return n}function o(e,t){e&&(" "+e.className+" ").indexOf(" "+t+" ")===-1&&(e.className+=(e.className?" ":"")+t)}function u(e,t,n){return typeof t=="string"&&(t=s(t,n)),e.parentNode&&e.parentNode.replaceChild(t,e),t.appendChild(e),t}function a(e,t){var n,r,i=0,s=0,o=fabric.document.documentElement,u=fabric.document.body||{scrollLeft:0,scrollTop:0};r=e;while(e&&e.parentNode&&!n)e=e.parentNode,e.nodeType===1&&fabric.util.getElementStyle(e,"position")==="fixed"&&(n=e),e.nodeType===1&&r!==t&&fabric.util.getElementStyle(e,"position")==="absolute"?(i=0,s=0):e===fabric.document?(i=u.scrollLeft||o.scrollLeft||0,s=u.scrollTop||o.scrollTop||0):(i+=e.scrollLeft||0,s+=e.scrollTop||0);return{left:i,top:s}}function f(e){var t,n=e&&e.ownerDocument,r={left:0,top:0},i={left:0,top:0},s,o={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!n)return{left:0,top:0};for(var u in o)i[o[u]]+=parseInt(l(e,u),10)||0;return t=n.documentElement,typeof e.getBoundingClientRect!="undefined"&&(r=e.getBoundingClientRect()),s=fabric.util.getScrollLeftTop(e,null),{left:r.left+s.left-(t.clientLeft||0)+i.left,top:r.top+s.top-(t.clientTop||0)+i.top}}var e=Array.prototype.slice,n,r=function(t){return e.call(t,0)};try{n=r(fabric.document.childNodes)instanceof Array}catch(i){}n||(r=function(e){var t=new Array(e.length),n=e.length;while(n--)t[n]=e[n];return t});var l;fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?l=function(e,t){var n=fabric.document.defaultView.getComputedStyle(e,null);return n?n[t]:undefined}:l=function(e,t){var n=e.style[t];return!n&&e.currentStyle&&(n=e.currentStyle[t]),n},function(){function n(e){return typeof e.onselectstart!="undefined"&&(e.onselectstart=fabric.util.falseFunction),t?e.style[t]="none":typeof e.unselectable=="string"&&(e.unselectable="on"),e}function r(e){return typeof e.onselectstart!="undefined"&&(e.onselectstart=null),t?e.style[t]="":typeof e.unselectable=="string"&&(e.unselectable=""),e}var e=fabric.document.documentElement.style,t="userSelect"in e?"userSelect":"MozUserSelect"in e?"MozUserSelect":"WebkitUserSelect"in e?"WebkitUserSelect":"KhtmlUserSelect"in e?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=n,fabric.util.makeElementSelectable=r}(),function(){function e(e,t){var n=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),i=!0;r.onload=r.onreadystatechange=function(e){if(i){if(typeof this.readyState=="string"&&this.readyState!=="loaded"&&this.readyState!=="complete")return;i=!1,t(e||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=e,n.appendChild(r)}fabric.util.getScript=e}(),fabric.util.getById=t,fabric.util.toArray=r,fabric.util.makeElement=s,fabric.util.addClass=o,fabric.util.wrapElement=u,fabric.util.getScrollLeftTop=a,fabric.util.getElementOffset=f,fabric.util.getElementStyle=l}(),function(){function e(e,t){return e+(/\?/.test(e)?"&":"?")+t}function n(){}function r(r,i){i||(i={});var s=i.method?i.method.toUpperCase():"GET",o=i.onComplete||function(){},u=t(),a;return u.onreadystatechange=function(){u.readyState===4&&(o(u),u.onreadystatechange=n)},s==="GET"&&(a=null,typeof i.parameters=="string"&&(r=e(r,i.parameters))),u.open(s,r,!0),(s==="POST"||s==="PUT")&&u.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),u.send(a),u}var t=function(){var e=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}];for(var t=e.length;t--;)try{var n=e[t]();if(n)return e[t]}catch(r){}}();fabric.util.request=r}(),fabric.log=function(){},fabric.warn=function(){},typeof console!="undefined"&&["log","warn"].forEach(function(e){typeof console[e]!="undefined"&&typeof console[e].apply=="function"&&(fabric[e]=function(){return console[e].apply(console,arguments)})}),function(){function e(e){n(function(t){e||(e={});var r=t||+(new Date),i=e.duration||500,s=r+i,o,u=e.onChange||function(){},a=e.abort||function(){return!1},f=e.easing||function(e,t,n,r){return-n*Math.cos(e/r*(Math.PI/2))+n+t},l="startValue"in e?e.startValue:0,c="endValue"in e?e.endValue:100,h=e.byValue||c-l;e.onStart&&e.onStart(),function p(t){o=t||+(new Date);var c=o>s?i:o-r;if(a()){e.onComplete&&e.onComplete();return}u(f(c,l,h,i));if(o>s){e.onComplete&&e.onComplete();return}n(p)}(r)})}function n(){return t.apply(fabric.window,arguments)}var t=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(e){fabric.window.setTimeout(e,1e3/60)};fabric.util.animate=e,fabric.util.requestAnimFrame=n}(),function(){function e(e,t,n,r){return e<Math.abs(t)?(e=t,r=n/4):r=n/(2*Math.PI)*Math.asin(t/e),{a:e,c:t,p:n,s:r}}function t(e,t,n){return e.a*Math.pow(2,10*(t-=1))*Math.sin((t*n-e.s)*2*Math.PI/e.p)}function n(e,t,n,r){return n*((e=e/r-1)*e*e+1)+t}function r(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e+t:n/2*((e-=2)*e*e+2)+t}function i(e,t,n,r){return n*(e/=r)*e*e*e+t}function s(e,t,n,r){return-n*((e=e/r-1)*e*e*e-1)+t}function o(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e*e+t:-n/2*((e-=2)*e*e*e-2)+t}function u(e,t,n,r){return n*(e/=r)*e*e*e*e+t}function a(e,t,n,r){return n*((e=e/r-1)*e*e*e*e+1)+t}function f(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e*e*e+t:n/2*((e-=2)*e*e*e*e+2)+t}function l(e,t,n,r){return-n*Math.cos(e/r*(Math.PI/2))+n+t}function c(e,t,n,r){return n*Math.sin(e/r*(Math.PI/2))+t}function h(e,t,n,r){return-n/2*(Math.cos(Math.PI*e/r)-1)+t}function p(e,t,n,r){return e===0?t:n*Math.pow(2,10*(e/r-1))+t}function d(e,t,n,r){return e===r?t+n:n*(-Math.pow(2,-10*e/r)+1)+t}function v(e,t,n,r){return e===0?t:e===r?t+n:(e/=r/2,e<1?n/2*Math.pow(2,10*(e-1))+t:n/2*(-Math.pow(2,-10*--e)+2)+t)}function m(e,t,n,r){return-n*(Math.sqrt(1-(e/=r)*e)-1)+t}function g(e,t,n,r){return n*Math.sqrt(1-(e=e/r-1)*e)+t}function y(e,t,n,r){return e/=r/2,e<1?-n/2*(Math.sqrt(1-e*e)-1)+t:n/2*(Math.sqrt(1-(e-=2)*e)+1)+t}function b(n,r,i,s){var o=1.70158,u=0,a=i;if(n===0)return r;n/=s;if(n===1)return r+i;u||(u=s*.3);var f=e(a,i,u,o);return-t(f,n,s)+r}function w(t,n,r,i){var s=1.70158,o=0,u=r;if(t===0)return n;t/=i;if(t===1)return n+r;o||(o=i*.3);var a=e(u,r,o,s);return a.a*Math.pow(2,-10*t)*Math.sin((t*i-a.s)*2*Math.PI/a.p)+a.c+n}function E(n,r,i,s){var o=1.70158,u=0,a=i;if(n===0)return r;n/=s/2;if(n===2)return r+i;u||(u=s*.3*1.5);var f=e(a,i,u,o);return n<1?-0.5*t(f,n,s)+r:f.a*Math.pow(2,-10*(n-=1))*Math.sin((n*s-f.s)*2*Math.PI/f.p)*.5+f.c+r}function S(e,t,n,r,i){return i===undefined&&(i=1.70158),n*(e/=r)*e*((i+1)*e-i)+t}function x(e,t,n,r,i){return i===undefined&&(i=1.70158),n*((e=e/r-1)*e*((i+1)*e+i)+1)+t}function T(e,t,n,r,i){return i===undefined&&(i=1.70158),e/=r/2,e<1?n/2*e*e*(((i*=1.525)+1)*e-i)+t:n/2*((e-=2)*e*(((i*=1.525)+1)*e+i)+2)+t}function N(e,t,n,r){return n-C(r-e,0,n,r)+t}function C(e,t,n,r){return(e/=r)<1/2.75?n*7.5625*e*e+t:e<2/2.75?n*(7.5625*(e-=1.5/2.75)*e+.75)+t:e<2.5/2.75?n*(7.5625*(e-=2.25/2.75)*e+.9375)+t:n*(7.5625*(e-=2.625/2.75)*e+.984375)+t}function k(e,t,n,r){return e<r/2?N(e*2,0,n,r)*.5+t:C(e*2-r,0,n,r)*.5+n*.5+t}fabric.util.ease={easeInQuad:function(e,t,n,r){return n*(e/=r)*e+t},easeOutQuad:function(e,t,n,r){return-n*(e/=r)*(e-2)+t},easeInOutQuad:function(e,t,n,r){return e/=r/2,e<1?n/2*e*e+t:-n/2*(--e*(e-2)-1)+t},easeInCubic:function(e,t,n,r){return n*(e/=r)*e*e+t},easeOutCubic:n,easeInOutCubic:r,easeInQuart:i,easeOutQuart:s,easeInOutQuart:o,easeInQuint:u,easeOutQuint:a,easeInOutQuint:f,easeInSine:l,easeOutSine:c,easeInOutSine:h,easeInExpo:p,easeOutExpo:d,easeInOutExpo:v,easeInCirc:m,easeOutCirc:g,easeInOutCirc:y,easeInElastic:b,easeOutElastic:w,easeInOutElastic:E,easeInBack:S,easeOutBack:x,easeInOutBack:T,easeInBounce:N,easeOutBounce:C,easeInOutBounce:k}}(),function(e){"use strict";function l(e){return e in a?a[e]:e}function c(e,n,r,i){var s=Object.prototype.toString.call(n)==="[object Array]",a;return e!=="fill"&&e!=="stroke"||n!=="none"?e==="strokeDashArray"?n=n.replace(/,/g," ").split(/\s+/).map(function(e){return parseFloat(e)}):e==="transformMatrix"?r&&r.transformMatrix?n=u(r.transformMatrix,t.parseTransformAttribute(n)):n=t.parseTransformAttribute(n):e==="visible"?(n=n==="none"||n==="hidden"?!1:!0,r&&r.visible===!1&&(n=!1)):e==="originX"?n=n==="start"?"left":n==="end"?"right":"center":a=s?n.map(o):o(n,i):n="",!s&&isNaN(a)?n:a}function h(e){for(var n in f){if(!e[n]||typeof e[f[n]]=="undefined")continue;if(e[n].indexOf("url(")===0)continue;var r=new t.Color(e[n]);e[n]=r.setAlpha(s(r.getAlpha()*e[f[n]],2)).toRgba()}return e}function p(e,t){var n,r;e.replace(/;$/,"").split(";").forEach(function(e){var i=e.split(":");n=l(i[0].trim().toLowerCase()),r=c(n,i[1].trim()),t[n]=r})}function d(e,t){var n,r;for(var i in e){if(typeof e[i]=="undefined")continue;n=l(i.toLowerCase()),r=c(n,e[i]),t[n]=r}}function v(e,n){var r={};for(var i in t.cssRules[n])if(m(e,i.split(" ")))for(var s in t.cssRules[n][i])r[s]=t.cssRules[n][i][s];return r}function m(e,t){var n,r=!0;return n=y(e,t.pop()),n&&t.length&&(r=g(e,t)),n&&r&&t.length===0}function g(e,t){var n,r=!0;while(e.parentNode&&e.parentNode.nodeType===1&&t.length)r&&(n=t.pop()),e=e.parentNode,r=y(e,n);return t.length===0}function y(e,t){var n=e.nodeName,r=e.getAttribute("class"),i=e.getAttribute("id"),s;s=new RegExp("^"+n,"i"),t=t.replace(s,""),i&&t.length&&(s=new RegExp("#"+i+"(?![a-zA-Z\\-]+)","i"),t=t.replace(s,""));if(r&&t.length){r=r.split(" ");for(var o=r.length;o--;)s=new RegExp("\\."+r[o]+"(?![a-zA-Z\\-]+)","i"),t=t.replace(s,"")}return t.length===0}function b(e){var t=e.getElementsByTagName("use");while(t.length){var n=t[0],r=n.getAttribute("xlink:href").substr(1),i=n.getAttribute("x")||0,s=n.getAttribute("y")||0,o=e.getElementById(r).cloneNode(!0),u=(o.getAttribute("transform")||"")+" translate("+i+", "+s+")",a;for(var f=0,l=n.attributes,c=l.length;f<c;f++){var h=l.item(f);if(h.nodeName==="x"||h.nodeName==="y"||h.nodeName==="xlink:href")continue;h.nodeName==="transform"?u=h.nodeValue+" "+u:o.setAttribute(h.nodeName,h.nodeValue)}o.setAttribute("transform",u),o.setAttribute("instantiated_by_use","1"),o.removeAttribute("id"),a=n.parentNode,a.replaceChild(o,n)}}function w(e,n,r){var i=new RegExp("^\\s*("+t.reNum+"+)\\s*,?"+"\\s*("+t.reNum+"+)\\s*,?"+"\\s*("+t.reNum+"+)\\s*,?"+"\\s*("+t.reNum+"+)\\s*"+"$"),s=e.getAttribute("viewBox"),o=1,u=1,a=0,f=0,l,c,h,p;if(!s||!(s=s.match(i)))return;a=-parseFloat(s[1]),f=-parseFloat(s[2]),l=parseFloat(s[3]),c=parseFloat(s[4]),n&&n!==l&&(o=n/l),r&&r!==c&&(u=r/c),u=o=o>u?u:o;if(o===1&&u===1&&a===0&&f===0)return;h="matrix("+o+" 0"+" 0 "+u+" "+a*o+" "+f*u+")";if(e.tagName==="svg"){p=e.ownerDocument.createElement("g");while(e.firstChild!=null)p.appendChild(e.firstChild);e.appendChild(p)}else p=e,h+=p.getAttribute("transform");p.setAttribute("transform",h)}function S(e){var n=e.objects,i=e.options;return n=n.map(function(e){return t[r(e.type)].fromObject(e)}),{objects:n,options:i}}function x(e,t,n){t[n]&&t[n].toSVG&&e.push('<pattern x="0" y="0" id="',n,'Pattern" ','width="',t[n].source.width,'" height="',t[n].source.height,'" patternUnits="userSpaceOnUse">','<image x="0" y="0" ','width="',t[n].source.width,'" height="',t[n].source.height,'" xlink:href="',t[n].source.src,'"></image></pattern>')}var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.string.capitalize,i=t.util.object.clone,s=t.util.toFixed,o=t.util.parseUnit,u=t.util.multiplyTransformMatrices,a={cx:"left",x:"left",r:"radius",cy:"top",y:"top",display:"visible",visibility:"visible",transform:"transformMatrix","fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"originX"},f={stroke:"strokeOpacity",fill:"fillOpacity"};t.cssRules={},t.gradientDefs={},t.parseTransformAttribute=function(){function e(e,t){var n=t[0];e[0]=Math.cos(n),e[1]=Math.sin(n),e[2]=-Math.sin(n),e[3]=Math.cos(n)}function n(e,t){var n=t[0],r=t.length===2?t[1]:t[0];e[0]=n,e[3]=r}function r(e,n){e[2]=Math.tan(t.util.degreesToRadians(n[0]))}function i(e,n){e[1]=Math.tan(t.util.degreesToRadians(n[0]))}function s(e,t){e[4]=t[0],t.length===2&&(e[5]=t[1])}var o=[1,0,0,1,0,0],u=t.reNum,a="(?:\\s+,?\\s*|,\\s*)",f="(?:(skewX)\\s*\\(\\s*("+u+")\\s*\\))",l="(?:(skewY)\\s*\\(\\s*("+u+")\\s*\\))",c="(?:(rotate)\\s*\\(\\s*("+u+")(?:"+a+"("+u+")"+a+"("+u+"))?\\s*\\))",h="(?:(scale)\\s*\\(\\s*("+u+")(?:"+a+"("+u+"))?\\s*\\))",p="(?:(translate)\\s*\\(\\s*("+u+")(?:"+a+"("+u+"))?\\s*\\))",d="(?:(matrix)\\s*\\(\\s*("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+"\\s*\\))",v="(?:"+d+"|"+p+"|"+h+"|"+c+"|"+f+"|"+l+")",m="(?:"+v+"(?:"+a+v+")*"+")",g="^\\s*(?:"+m+"?)\\s*$",y=new RegExp(g),b=new RegExp(v,"g");return function(u){var a=o.concat(),f=[];if(!u||u&&!y.test(u))return a;u.replace(b,function(u){var l=(new RegExp(v)).exec(u).filter(function(e){return e!==""&&e!=null}),c=l[1],h=l.slice(2).map(parseFloat);switch(c){case"translate":s(a,h);break;case"rotate":h[0]=t.util.degreesToRadians(h[0]),e(a,h);break;case"scale":n(a,h);break;case"skewX":r(a,h);break;case"skewY":i(a,h);break;case"matrix":a=h}f.push(a.concat()),a=o.concat()});var l=f[0];while(f.length>1)f.shift(),l=t.util.multiplyTransformMatrices(l,f[0]);return l}}(),t.parseSVGDocument=function(){function r(e,t){while(e&&(e=e.parentNode))if(t.test(e.nodeName)&&!e.getAttribute("instantiated_by_use"))return!0;return!1}var e=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/,n=/^(symbol|image|marker|pattern|view)$/;return function(s,u,a){if(!s)return;b(s);var f=new Date,l=t.Object.__uid++,c=o(s.getAttribute("width")||"100%"),h=o(s.getAttribute("height")||"100%");w(s,c,h);var p=t.util.toArray(s.getElementsByTagName("*"));if(p.length===0&&t.isLikelyNode){p=s.selectNodes('//*[name(.)!="svg"]');var d=[];for(var v=0,m=p.length;v<m;v++)d[v]=p[v];p=d}var g=p.filter(function(t){return n.test(t.tagName)&&w(t,0,0),e.test(t.tagName)&&!r(t,/^(?:pattern|defs|symbol)$/)});if(!g||g&&!g.length){u&&u([],{});return}var y={width:c,height:h,widthAttr:c,heightAttr:h,svgUid:l};t.gradientDefs[l]=t.getGradientDefs(s),t.cssRules[l]=t.getCSSRules(s),t.parseElements(g,function(e){t.documentParsingTime=new Date-f,u&&u(e,y)},i(y),a)}}();var E={has:function(e,t){t(!1)},get:function(){},set:function(){}};n(t,{parseFontDeclaration:function(e,n){var r="(normal|italic)?\\s*(normal|small-caps)?\\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*("+t.reNum+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+t.reNum+"))?\\s+(.*)",i=e.match(r);if(!i)return;var s=i[1],u=i[3],a=i[4],f=i[5],l=i[6];s&&(n.fontStyle=s),u&&(n.fontWeight=isNaN(parseFloat(u))?u:parseFloat(u)),a&&(n.fontSize=o(a)),l&&(n.fontFamily=l),f&&(n.lineHeight=f==="normal"?1:f)},getGradientDefs:function(e){var t=e.getElementsByTagName("linearGradient"),n=e.getElementsByTagName("radialGradient"),r,i,s=0,o,u,a=[],f={},l={};a.length=t.length+n.length,i=t.length;while(i--)a[s++]=t[i];i=n.length;while(i--)a[s++]=n[i];while(s--)r=a[s],u=r.getAttribute("xlink:href"),o=r.getAttribute("id"),u&&(l[o]=u.substr(1)),f[o]=r;for(o in l){var c=f[l[o]].cloneNode(!0);r=f[o];while(c.firstChild)r.appendChild(c.firstChild)}return f},parseAttributes:function(e,r,i){if(!e)return;var s,o={},u;typeof i=="undefined"&&(i=e.getAttribute("svgUid")),e.parentNode&&/^symbol|[g|a]$/i.test(e.parentNode.nodeName)&&(o=t.parseAttributes(e.parentNode,r,i)),u=o&&o.fontSize||e.getAttribute("font-size" +)||t.Text.DEFAULT_SVG_FONT_SIZE;var a=r.reduce(function(t,n){return s=e.getAttribute(n),s&&(n=l(n),s=c(n,s,o,u),t[n]=s),t},{});return a=n(a,n(v(e,i),t.parseStyleAttribute(e))),a.font&&t.parseFontDeclaration(a.font,a),h(n(o,a))},parseElements:function(e,n,r,i){(new t.ElementsParser(e,n,r,i)).parse()},parseStyleAttribute:function(e){var t={},n=e.getAttribute("style");return n?(typeof n=="string"?p(n,t):d(n,t),t):t},parsePointsAttribute:function(e){if(!e)return null;e=e.replace(/,/g," ").trim(),e=e.split(/\s+/);var t=[],n,r;n=0,r=e.length;for(;n<r;n+=2)t.push({x:parseFloat(e[n]),y:parseFloat(e[n+1])});return t},getCSSRules:function(e){var n=e.getElementsByTagName("style"),r={},i;for(var s=0,o=n.length;s<o;s++){var u=n[s].textContent;u=u.replace(/\/\*[\s\S]*?\*\//g,"");if(u.trim()==="")continue;i=u.match(/[^{]*\{[\s\S]*?\}/g),i=i.map(function(e){return e.trim()}),i.forEach(function(e){var n=e.match(/([\s\S]*?)\s*\{([^}]*)\}/),i={},s=n[2].trim(),o=s.replace(/;$/,"").split(/\s*;\s*/);for(var u=0,a=o.length;u<a;u++){var f=o[u].split(/\s*:\s*/),h=l(f[0]),p=c(h,f[1],f[0]);i[h]=p}e=n[1],e.split(",").forEach(function(e){e=e.replace(/^svg/i,"").trim();if(e==="")return;r[e]=t.util.object.clone(i)})})}return r},loadSVGFromURL:function(e,n,r){function i(i){var s=i.responseXML;s&&!s.documentElement&&t.window.ActiveXObject&&i.responseText&&(s=new ActiveXObject("Microsoft.XMLDOM"),s.async="false",s.loadXML(i.responseText.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i,"")));if(!s||!s.documentElement)return;t.parseSVGDocument(s.documentElement,function(r,i){E.set(e,{objects:t.util.array.invoke(r,"toObject"),options:i}),n(r,i)},r)}e=e.replace(/^\n\s*/,"").trim(),E.has(e,function(r){r?E.get(e,function(e){var t=S(e);n(t.objects,t.options)}):new t.util.request(e,{method:"get",onComplete:i})})},loadSVGFromString:function(e,n,r){e=e.trim();var i;if(typeof DOMParser!="undefined"){var s=new DOMParser;s&&s.parseFromString&&(i=s.parseFromString(e,"text/xml"))}else t.window.ActiveXObject&&(i=new ActiveXObject("Microsoft.XMLDOM"),i.async="false",i.loadXML(e.replace(/<!DOCTYPE[\s\S]*?(\[[\s\S]*\])*?>/i,"")));t.parseSVGDocument(i.documentElement,function(e,t){n(e,t)},r)},createSVGFontFacesMarkup:function(e){var t="";for(var n=0,r=e.length;n<r;n++){if(e[n].type!=="text"||!e[n].path)continue;t+=["@font-face {","font-family: ",e[n].fontFamily,"; ","src: url('",e[n].path,"')","}"].join("")}return t&&(t=['<style type="text/css">',"<![CDATA[",t,"]]>","</style>"].join("")),t},createSVGRefElementsMarkup:function(e){var t=[];return x(t,e,"backgroundColor"),x(t,e,"overlayColor"),t.join("")}})}(typeof exports!="undefined"?exports:this),fabric.ElementsParser=function(e,t,n,r){this.elements=e,this.callback=t,this.options=n,this.reviver=r,this.svgUid=n&&n.svgUid||0},fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},fabric.ElementsParser.prototype.createObjects=function(){for(var e=0,t=this.elements.length;e<t;e++)this.elements[e].setAttribute("svgUid",this.svgUid),function(e,t){setTimeout(function(){e.createObject(e.elements[t],t)},0)}(this,e)},fabric.ElementsParser.prototype.createObject=function(e,t){var n=fabric[fabric.util.string.capitalize(e.tagName)];if(n&&n.fromElement)try{this._createObject(n,e,t)}catch(r){fabric.log(r)}else this.checkIfDone()},fabric.ElementsParser.prototype._createObject=function(e,t,n){if(e.async)e.fromElement(t,this.createCallback(n,t),this.options);else{var r=e.fromElement(t,this.options);this.resolveGradient(r,"fill"),this.resolveGradient(r,"stroke"),this.reviver&&this.reviver(t,r),this.instances[n]=r,this.checkIfDone()}},fabric.ElementsParser.prototype.createCallback=function(e,t){var n=this;return function(r){n.resolveGradient(r,"fill"),n.resolveGradient(r,"stroke"),n.reviver&&n.reviver(t,r),n.instances[e]=r,n.checkIfDone()}},fabric.ElementsParser.prototype.resolveGradient=function(e,t){var n=e.get(t);if(!/^url\(/.test(n))return;var r=n.slice(5,n.length-1);fabric.gradientDefs[this.svgUid][r]&&e.set(t,fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][r],e))},fabric.ElementsParser.prototype.checkIfDone=function(){--this.numElements===0&&(this.instances=this.instances.filter(function(e){return e!=null}),this.callback(this.instances))},function(e){"use strict";function n(e,t){this.x=e,this.y=t}var t=e.fabric||(e.fabric={});if(t.Point){t.warn("fabric.Point is already defined");return}t.Point=n,n.prototype={constructor:n,add:function(e){return new n(this.x+e.x,this.y+e.y)},addEquals:function(e){return this.x+=e.x,this.y+=e.y,this},scalarAdd:function(e){return new n(this.x+e,this.y+e)},scalarAddEquals:function(e){return this.x+=e,this.y+=e,this},subtract:function(e){return new n(this.x-e.x,this.y-e.y)},subtractEquals:function(e){return this.x-=e.x,this.y-=e.y,this},scalarSubtract:function(e){return new n(this.x-e,this.y-e)},scalarSubtractEquals:function(e){return this.x-=e,this.y-=e,this},multiply:function(e){return new n(this.x*e,this.y*e)},multiplyEquals:function(e){return this.x*=e,this.y*=e,this},divide:function(e){return new n(this.x/e,this.y/e)},divideEquals:function(e){return this.x/=e,this.y/=e,this},eq:function(e){return this.x===e.x&&this.y===e.y},lt:function(e){return this.x<e.x&&this.y<e.y},lte:function(e){return this.x<=e.x&&this.y<=e.y},gt:function(e){return this.x>e.x&&this.y>e.y},gte:function(e){return this.x>=e.x&&this.y>=e.y},lerp:function(e,t){return new n(this.x+(e.x-this.x)*t,this.y+(e.y-this.y)*t)},distanceFrom:function(e){var t=this.x-e.x,n=this.y-e.y;return Math.sqrt(t*t+n*n)},midPointFrom:function(e){return new n(this.x+(e.x-this.x)/2,this.y+(e.y-this.y)/2)},min:function(e){return new n(Math.min(this.x,e.x),Math.min(this.y,e.y))},max:function(e){return new n(Math.max(this.x,e.x),Math.max(this.y,e.y))},toString:function(){return this.x+","+this.y},setXY:function(e,t){this.x=e,this.y=t},setFromPoint:function(e){this.x=e.x,this.y=e.y},swap:function(e){var t=this.x,n=this.y;this.x=e.x,this.y=e.y,e.x=t,e.y=n}}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function n(e){this.status=e,this.points=[]}var t=e.fabric||(e.fabric={});if(t.Intersection){t.warn("fabric.Intersection is already defined");return}t.Intersection=n,t.Intersection.prototype={appendPoint:function(e){this.points.push(e)},appendPoints:function(e){this.points=this.points.concat(e)}},t.Intersection.intersectLineLine=function(e,r,i,s){var o,u=(s.x-i.x)*(e.y-i.y)-(s.y-i.y)*(e.x-i.x),a=(r.x-e.x)*(e.y-i.y)-(r.y-e.y)*(e.x-i.x),f=(s.y-i.y)*(r.x-e.x)-(s.x-i.x)*(r.y-e.y);if(f!==0){var l=u/f,c=a/f;0<=l&&l<=1&&0<=c&&c<=1?(o=new n("Intersection"),o.points.push(new t.Point(e.x+l*(r.x-e.x),e.y+l*(r.y-e.y)))):o=new n}else u===0||a===0?o=new n("Coincident"):o=new n("Parallel");return o},t.Intersection.intersectLinePolygon=function(e,t,r){var i=new n,s=r.length;for(var o=0;o<s;o++){var u=r[o],a=r[(o+1)%s],f=n.intersectLineLine(e,t,u,a);i.appendPoints(f.points)}return i.points.length>0&&(i.status="Intersection"),i},t.Intersection.intersectPolygonPolygon=function(e,t){var r=new n,i=e.length;for(var s=0;s<i;s++){var o=e[s],u=e[(s+1)%i],a=n.intersectLinePolygon(o,u,t);r.appendPoints(a.points)}return r.points.length>0&&(r.status="Intersection"),r},t.Intersection.intersectPolygonRectangle=function(e,r,i){var s=r.min(i),o=r.max(i),u=new t.Point(o.x,s.y),a=new t.Point(s.x,o.y),f=n.intersectLinePolygon(s,u,e),l=n.intersectLinePolygon(u,o,e),c=n.intersectLinePolygon(o,a,e),h=n.intersectLinePolygon(a,s,e),p=new n;return p.appendPoints(f.points),p.appendPoints(l.points),p.appendPoints(c.points),p.appendPoints(h.points),p.points.length>0&&(p.status="Intersection"),p}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function n(e){e?this._tryParsingColor(e):this.setSource([0,0,0,1])}function r(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+(t-e)*6*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var t=e.fabric||(e.fabric={});if(t.Color){t.warn("fabric.Color is already defined.");return}t.Color=n,t.Color.prototype={_tryParsingColor:function(e){var t;e in n.colorNameMap&&(e=n.colorNameMap[e]);if(e==="transparent"){this.setSource([255,255,255,0]);return}t=n.sourceFromHex(e),t||(t=n.sourceFromRgb(e)),t||(t=n.sourceFromHsl(e)),t&&this.setSource(t)},_rgbToHsl:function(e,n,r){e/=255,n/=255,r/=255;var i,s,o,u=t.util.array.max([e,n,r]),a=t.util.array.min([e,n,r]);o=(u+a)/2;if(u===a)i=s=0;else{var f=u-a;s=o>.5?f/(2-u-a):f/(u+a);switch(u){case e:i=(n-r)/f+(n<r?6:0);break;case n:i=(r-e)/f+2;break;case r:i=(e-n)/f+4}i/=6}return[Math.round(i*360),Math.round(s*100),Math.round(o*100)]},getSource:function(){return this._source},setSource:function(e){this._source=e},toRgb:function(){var e=this.getSource();return"rgb("+e[0]+","+e[1]+","+e[2]+")"},toRgba:function(){var e=this.getSource();return"rgba("+e[0]+","+e[1]+","+e[2]+","+e[3]+")"},toHsl:function(){var e=this.getSource(),t=this._rgbToHsl(e[0],e[1],e[2]);return"hsl("+t[0]+","+t[1]+"%,"+t[2]+"%)"},toHsla:function(){var e=this.getSource(),t=this._rgbToHsl(e[0],e[1],e[2]);return"hsla("+t[0]+","+t[1]+"%,"+t[2]+"%,"+e[3]+")"},toHex:function(){var e=this.getSource(),t,n,r;return t=e[0].toString(16),t=t.length===1?"0"+t:t,n=e[1].toString(16),n=n.length===1?"0"+n:n,r=e[2].toString(16),r=r.length===1?"0"+r:r,t.toUpperCase()+n.toUpperCase()+r.toUpperCase()},getAlpha:function(){return this.getSource()[3]},setAlpha:function(e){var t=this.getSource();return t[3]=e,this.setSource(t),this},toGrayscale:function(){var e=this.getSource(),t=parseInt((e[0]*.3+e[1]*.59+e[2]*.11).toFixed(0),10),n=e[3];return this.setSource([t,t,t,n]),this},toBlackWhite:function(e){var t=this.getSource(),n=(t[0]*.3+t[1]*.59+t[2]*.11).toFixed(0),r=t[3];return e=e||127,n=Number(n)<Number(e)?0:255,this.setSource([n,n,n,r]),this},overlayWith:function(e){e instanceof n||(e=new n(e));var t=[],r=this.getAlpha(),i=.5,s=this.getSource(),o=e.getSource();for(var u=0;u<3;u++)t.push(Math.round(s[u]*(1-i)+o[u]*i));return t[3]=r,this.setSource(t),this}},t.Color.reRGBa=/^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/,t.Color.reHSLa=/^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/,t.Color.reHex=/^#?([0-9a-f]{6}|[0-9a-f]{3})$/i,t.Color.colorNameMap={aqua:"#00FFFF",black:"#000000",blue:"#0000FF",fuchsia:"#FF00FF",gray:"#808080",green:"#008000",lime:"#00FF00",maroon:"#800000",navy:"#000080",olive:"#808000",orange:"#FFA500",purple:"#800080",red:"#FF0000",silver:"#C0C0C0",teal:"#008080",white:"#FFFFFF",yellow:"#FFFF00"},t.Color.fromRgb=function(e){return n.fromSource(n.sourceFromRgb(e))},t.Color.sourceFromRgb=function(e){var t=e.match(n.reRGBa);if(t){var r=parseInt(t[1],10)/(/%$/.test(t[1])?100:1)*(/%$/.test(t[1])?255:1),i=parseInt(t[2],10)/(/%$/.test(t[2])?100:1)*(/%$/.test(t[2])?255:1),s=parseInt(t[3],10)/(/%$/.test(t[3])?100:1)*(/%$/.test(t[3])?255:1);return[parseInt(r,10),parseInt(i,10),parseInt(s,10),t[4]?parseFloat(t[4]):1]}},t.Color.fromRgba=n.fromRgb,t.Color.fromHsl=function(e){return n.fromSource(n.sourceFromHsl(e))},t.Color.sourceFromHsl=function(e){var t=e.match(n.reHSLa);if(!t)return;var i=(parseFloat(t[1])%360+360)%360/360,s=parseFloat(t[2])/(/%$/.test(t[2])?100:1),o=parseFloat(t[3])/(/%$/.test(t[3])?100:1),u,a,f;if(s===0)u=a=f=o;else{var l=o<=.5?o*(s+1):o+s-o*s,c=o*2-l;u=r(c,l,i+1/3),a=r(c,l,i),f=r(c,l,i-1/3)}return[Math.round(u*255),Math.round(a*255),Math.round(f*255),t[4]?parseFloat(t[4]):1]},t.Color.fromHsla=n.fromHsl,t.Color.fromHex=function(e){return n.fromSource(n.sourceFromHex(e))},t.Color.sourceFromHex=function(e){if(e.match(n.reHex)){var t=e.slice(e.indexOf("#")+1),r=t.length===3,i=r?t.charAt(0)+t.charAt(0):t.substring(0,2),s=r?t.charAt(1)+t.charAt(1):t.substring(2,4),o=r?t.charAt(2)+t.charAt(2):t.substring(4,6);return[parseInt(i,16),parseInt(s,16),parseInt(o,16),1]}},t.Color.fromSource=function(e){var t=new n;return t.setSource(e),t}}(typeof exports!="undefined"?exports:this),function(){function e(e){var t=e.getAttribute("style"),n=e.getAttribute("offset"),r,i,s;n=parseFloat(n)/(/%$/.test(n)?100:1),n=n<0?0:n>1?1:n;if(t){var o=t.split(/\s*;\s*/);o[o.length-1]===""&&o.pop();for(var u=o.length;u--;){var a=o[u].split(/\s*:\s*/),f=a[0].trim(),l=a[1].trim();f==="stop-color"?r=l:f==="stop-opacity"&&(s=l)}}return r||(r=e.getAttribute("stop-color")||"rgb(0,0,0)"),s||(s=e.getAttribute("stop-opacity")),r=new fabric.Color(r),i=r.getAlpha(),s=isNaN(parseFloat(s))?1:parseFloat(s),s*=i,{offset:n,color:r.toRgb(),opacity:s}}function t(e){return{x1:e.getAttribute("x1")||0,y1:e.getAttribute("y1")||0,x2:e.getAttribute("x2")||"100%",y2:e.getAttribute("y2")||0}}function n(e){return{x1:e.getAttribute("fx")||e.getAttribute("cx")||"50%",y1:e.getAttribute("fy")||e.getAttribute("cy")||"50%",r1:0,x2:e.getAttribute("cx")||"50%",y2:e.getAttribute("cy")||"50%",r2:e.getAttribute("r")||"50%"}}function r(e,t,n){var r,i=0,s=1,o="";for(var u in t){r=parseFloat(t[u],10),typeof t[u]=="string"&&/^\d+%$/.test(t[u])?s=.01:s=1;if(u==="x1"||u==="x2"||u==="r2")s*=n==="objectBoundingBox"?e.width:1,i=n==="objectBoundingBox"?e.left||0:0;else if(u==="y1"||u==="y2")s*=n==="objectBoundingBox"?e.height:1,i=n==="objectBoundingBox"?e.top||0:0;t[u]=r*s+i}if(e.type==="ellipse"&&t.r2!==null&&n==="objectBoundingBox"&&e.rx!==e.ry){var a=e.ry/e.rx;o=" scale(1, "+a+")",t.y1&&(t.y1/=a),t.y2&&(t.y2/=a)}return o}fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(e){e||(e={});var t={};this.id=fabric.Object.__uid++,this.type=e.type||"linear",t={x1:e.coords.x1||0,y1:e.coords.y1||0,x2:e.coords.x2||0,y2:e.coords.y2||0},this.type==="radial"&&(t.r1=e.coords.r1||0,t.r2=e.coords.r2||0),this.coords=t,this.colorStops=e.colorStops.slice(),e.gradientTransform&&(this.gradientTransform=e.gradientTransform),this.offsetX=e.offsetX||this.offsetX,this.offsetY=e.offsetY||this.offsetY},addColorStop:function(e){for(var t in e){var n=new fabric.Color(e[t]);this.colorStops.push({offset:t,color:n.toRgb(),opacity:n.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY}},toSVG:function(e){var t=fabric.util.object.clone(this.coords),n,r;this.colorStops.sort(function(e,t){return e.offset-t.offset});if(!e.group||e.group.type!=="path-group")for(var i in t)if(i==="x1"||i==="x2"||i==="r2")t[i]+=this.offsetX-e.width/2;else if(i==="y1"||i==="y2")t[i]+=this.offsetY-e.height/2;r='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"',this.gradientTransform&&(r+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '),this.type==="linear"?n=["<linearGradient ",r,' x1="',t.x1,'" y1="',t.y1,'" x2="',t.x2,'" y2="',t.y2,'">\n']:this.type==="radial"&&(n=["<radialGradient ",r,' cx="',t.x2,'" cy="',t.y2,'" r="',t.r2,'" fx="',t.x1,'" fy="',t.y1,'">\n']);for(var s=0;s<this.colorStops.length;s++)n.push("<stop ",'offset="',this.colorStops[s].offset*100+"%",'" style="stop-color:',this.colorStops[s].color,this.colorStops[s].opacity!=null?";stop-opacity: "+this.colorStops[s].opacity:";",'"/>\n');return n.push(this.type==="linear"?"</linearGradient>\n":"</radialGradient>\n"),n.join("")},toLive:function(e,t){var n,r=fabric.util.object.clone(this.coords);if(!this.type)return;if(t.group&&t.group.type==="path-group")for(var i in r)if(i==="x1"||i==="x2")r[i]+=-this.offsetX+t.width/2;else if(i==="y1"||i==="y2")r[i]+=-this.offsetY+t.height/2;this.type==="linear"?n=e.createLinearGradient(r.x1,r.y1,r.x2,r.y2):this.type==="radial"&&(n=e.createRadialGradient(r.x1,r.y1,r.r1,r.x2,r.y2,r.r2));for(var s=0,o=this.colorStops.length;s<o;s++){var u=this.colorStops[s].color,a=this.colorStops[s].opacity,f=this.colorStops[s].offset;typeof a!="undefined"&&(u=(new fabric.Color(u)).setAlpha(a).toRgba()),n.addColorStop(parseFloat(f),u)}return n}}),fabric.util.object.extend(fabric.Gradient,{fromElement:function(i,s){var o=i.getElementsByTagName("stop"),u=i.nodeName==="linearGradient"?"linear":"radial",a=i.getAttribute("gradientUnits")||"objectBoundingBox",f=i.getAttribute("gradientTransform"),l=[],c={},h;u==="linear"?c=t(i):u==="radial"&&(c=n(i));for(var p=o.length;p--;)l.push(e(o[p]));h=r(s,c,a);var d=new fabric.Gradient({type:u,coords:c,colorStops:l,offsetX:-s.left,offsetY:-s.top});if(f||h!=="")d.gradientTransform=fabric.parseTransformAttribute((f||"")+h);return d},forObject:function(e,t){return t||(t={}),r(e,t.coords,"userSpaceOnUse"),new fabric.Gradient(t)}})}(),fabric.Pattern=fabric.util.createClass({repeat:"repeat",offsetX:0,offsetY:0,initialize:function(e){e||(e={}),this.id=fabric.Object.__uid++;if(e.source)if(typeof e.source=="string")if(typeof fabric.util.getFunctionBody(e.source)!="undefined")this.source=new Function(fabric.util.getFunctionBody(e.source));else{var t=this;this.source=fabric.util.createImage(),fabric.util.loadImage(e.source,function(e){t.source=e})}else this.source=e.source;e.repeat&&(this.repeat=e.repeat),e.offsetX&&(this.offsetX=e.offsetX),e.offsetY&&(this.offsetY=e.offsetY)},toObject:function(){var e;return typeof this.source=="function"?e=String(this.source):typeof this.source.src=="string"&&(e=this.source.src),{source:e,repeat:this.repeat,offsetX:this.offsetX,offsetY:this.offsetY}},toSVG:function(e){var t=typeof this.source=="function"?this.source():this.source,n=t.width/e.getWidth(),r=t.height/e.getHeight(),i=this.offsetX/e.getWidth(),s=this.offsetY/e.getHeight(),o="";if(this.repeat==="repeat-x"||this.repeat==="no-repeat")r=1;if(this.repeat==="repeat-y"||this.repeat==="no-repeat")n=1;return t.src?o=t.src:t.toDataURL&&(o=t.toDataURL()),'<pattern id="SVGID_'+this.id+'" x="'+i+'" y="'+s+'" width="'+n+'" height="'+r+'">\n'+'<image x="0" y="0"'+' width="'+t.width+'" height="'+t.height+'" xlink:href="'+o+'"></image>\n'+"</pattern>\n"},toLive:function(e){var t=typeof this.source=="function"?this.source():this.source;if(!t)return"";if(typeof t.src!="undefined"){if(!t.complete)return"";if(t.naturalWidth===0||t.naturalHeight===0)return""}return e.createPattern(t,this.repeat)}}),function(e){"use strict";var t=e.fabric||(e.fabric={});if(t.Shadow){t.warn("fabric.Shadow is already defined.");return}t.Shadow=t.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,initialize:function(e){typeof e=="string"&&(e=this._parseShadow(e));for(var n in e)this[n]=e[n];this.id=t.Object.__uid++},_parseShadow:function(e){var n=e.trim(),r=t.Shadow.reOffsetsAndBlur.exec(n)||[],i=n.replace(t.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:i.trim(),offsetX:parseInt(r[1],10)||0,offsetY:parseInt(r[2],10)||0,blur:parseInt(r[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(e){var t="SourceAlpha",n=40,r=40;return e&&(e.fill===this.color||e.stroke===this.color)&&(t="SourceGraphic"),e.width&&e.height&&(n=Math.abs(this.offsetX/e.getWidth())*100+20,r=Math.abs(this.offsetY/e.getHeight())*100+20),'<filter id="SVGID_'+this.id+'" y="-'+r+'%" height="'+(100+2*r)+'%" '+'x="-'+n+'%" width="'+(100+2*n)+'%" '+">\n"+' <feGaussianBlur in="'+t+'" stdDeviation="'+(this.blur?this.blur/3:0)+'"></feGaussianBlur>\n'+' <feOffset dx="'+this.offsetX+'" dy="'+this.offsetY+'"></feOffset>\n'+" <feMerge>\n"+" <feMergeNode></feMergeNode>\n"+' <feMergeNode in="SourceGraphic"></feMergeNode>\n'+" </feMerge>\n"+"</filter>\n"},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY};var e={},n=t.Shadow.prototype;return this.color!==n.color&&(e.color=this.color),this.blur!==n.blur&&(e.blur=this.blur),this.offsetX!==n.offsetX&&(e.offsetX=this.offsetX),this.offsetY!==n.offsetY&&(e.offsetY=this.offsetY),e}}),t.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/}(typeof exports!="undefined"?exports:this),function(){"use strict";if(fabric.StaticCanvas){fabric.warn("fabric.StaticCanvas is already defined.");return}var e=fabric.util.object.extend,t=fabric.util.getElementOffset,n=fabric.util.removeFromArray,r=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(e,t){t||(t={}),this._initStatic(e,t),fabric.StaticCanvas.activeInstance=this},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!0,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,preserveObjectStacking:!1,viewportTransform:[1,0,0,1,0,0],onBeforeScaleRotate:function(){},_initStatic:function(e,t){this._objects=[],this._createLowerCanvas(e),this._initOptions(t),this._setImageSmoothing(),t.overlayImage&&this.setOverlayImage(t.overlayImage,this.renderAll.bind(this)),t.backgroundImage&&this.setBackgroundImage(t.backgroundImage,this.renderAll.bind(this)),t.backgroundColor&&this.setBackgroundColor(t.backgroundColor,this.renderAll.bind(this)),t.overlayColor&&this.setOverlayColor(t.overlayColor,this.renderAll.bind(this)),this.calcOffset()},calcOffset:function(){return this._offset=t(this.lowerCanvasEl),this},setOverlayImage:function(e,t,n){return this.__setBgOverlayImage("overlayImage",e,t,n)},setBackgroundImage:function(e,t,n){return this.__setBgOverlayImage("backgroundImage",e,t,n)},setOverlayColor:function(e,t){return this.__setBgOverlayColor("overlayColor",e,t)},setBackgroundColor:function(e,t){return this.__setBgOverlayColor("backgroundColor",e,t)},_setImageSmoothing:function(){var e=this.getContext();e.imageSmoothingEnabled=this.imageSmoothingEnabled,e.webkitImageSmoothingEnabled=this.imageSmoothingEnabled,e.mozImageSmoothingEnabled=this.imageSmoothingEnabled,e.msImageSmoothingEnabled=this.imageSmoothingEnabled,e.oImageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(e,t,n,r){return typeof t=="string"?fabric.util.loadImage(t,function(t){this[e]=new fabric.Image(t,r),n&&n()},this,r&&r.crossOrigin):(this[e]=t,n&&n()),this},__setBgOverlayColor:function(e,t,n){if(t&&t.source){var r=this;fabric.util.loadImage(t.source,function(i){r[e]=new fabric.Pattern({source:i,repeat:t.repeat,offsetX:t.offsetX,offsetY:t.offsetY}),n&&n()})}else this[e]=t,n&&n();return this},_createCanvasElement:function(){var e=fabric.document.createElement("canvas");e.style||(e.style={});if(!e)throw r;return this._initCanvasElement(e),e},_initCanvasElement:function(e){fabric.util.createCanvasElement(e);if(typeof e.getContext=="undefined")throw r},_initOptions:function(e){for(var t in e)this[t]=e[t];this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0;if(!this.lowerCanvasEl.style)return;this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice()},_createLowerCanvas:function(e){this.lowerCanvasEl=fabric.util.getById(e)||this._createCanvasElement(),this._initCanvasElement(this.lowerCanvasEl),fabric.util.addClass(this.lowerCanvasEl,"lower-canvas"),this.interactive&&this._applyCanvasStyle(this.lowerCanvasEl),this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(e,t){return this.setDimensions({width:e},t)},setHeight:function(e,t){return this.setDimensions({height:e},t)},setDimensions:function(e,t){var n;t=t||{};for(var r in e)n=e[r],t.cssOnly||(this._setBackstoreDimension(r,e[r]),n+="px"),t.backstoreOnly||this._setCssDimension(r,n);return t.cssOnly||this.renderAll(),this.calcOffset(),this},_setBackstoreDimension:function(e,t){return this.lowerCanvasEl[e]=t,this.upperCanvasEl&&(this.upperCanvasEl[e]=t),this.cacheCanvasEl&&(this.cacheCanvasEl[e]=t),this[e]=t,this},_setCssDimension:function(e,t){return this.lowerCanvasEl.style[e]=t,this.upperCanvasEl&&(this.upperCanvasEl.style[e]=t),this.wrapperEl&&(this.wrapperEl.style[e]=t),this},getZoom:function(){return Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(e){this.viewportTransform=e,this.renderAll();for(var t=0,n=this._objects.length;t<n;t++)this._objects[t].setCoords();return this},zoomToPoint:function(e,t){var n=e;e=fabric.util.transformPoint(e,fabric.util.invertTransform(this.viewportTransform)),this.viewportTransform[0]=t,this.viewportTransform[3]=t;var r=fabric.util.transformPoint(e,this.viewportTransform);this.viewportTransform[4]+=n.x-r.x,this.viewportTransform[5]+=n.y-r.y,this.renderAll();for(var i=0,s=this._objects.length;i<s;i++)this._objects[i].setCoords();return this},setZoom:function(e){return this.zoomToPoint(new fabric.Point(0,0),e),this},absolutePan:function(e){this.viewportTransform[4]=-e.x,this.viewportTransform[5]=-e.y,this.renderAll();for(var t=0,n=this._objects.length;t<n;t++)this._objects[t].setCoords();return this},relativePan:function(e){return this.absolutePan(new fabric.Point(-e.x-this.viewportTransform[4],-e.y-this.viewportTransform[5]))},getElement:function(){return this.lowerCanvasEl},getActiveObject:function(){return null},getActiveGroup:function(){return null},_draw:function(e,t){if(!t)return;e.save();var n=this.viewportTransform;e.transform(n[0],n[1],n[2],n[3],n[4],n[5]),this._shouldRenderObject(t)&&t.render(e),e.restore(),this.controlsAboveOverlay||t._renderControls(e)},_shouldRenderObject:function(e){return e?e!==this.getActiveGroup()||!this.preserveObjectStacking:!1},_onObjectAdded:function(e){this.stateful&&e.setupState(),e.canvas=this,e.setCoords(),this.fire("object:added",{target:e}),e.fire("added")},_onObjectRemoved:function(e){this.getActiveObject()===e&&(this.fire("before:selection:cleared",{target:e}),this._discardActiveObject(),this.fire("selection:cleared")),this.fire("object:removed",{target:e}),e.fire("removed")},clearContext:function(e){return e.clearRect(0,0,this.width,this.height),this},getContext:function(){return this.contextContainer},clear:function(){return this._objects.length=0,this.discardActiveGroup&&this.discardActiveGroup(),this.discardActiveObject&&this.discardActiveObject(),this.clearContext(this.contextContainer),this.contextTop&&this.clearContext(this.contextTop),this.fire("canvas:cleared"),this.renderAll(),this},renderAll:function(e){var t=this[e===!0&&this.interactive?"contextTop":"contextContainer"],n=this.getActiveGroup();return this.contextTop&&this.selection&&!this._groupSelector&&this.clearContext(this.contextTop),e||this.clearContext(t),this.fire("before:render"),this.clipTo&&fabric.util.clipContext(this,t),this._renderBackground(t),this._renderObjects(t,n),this._renderActiveGroup(t,n),this.clipTo&&t.restore(),this._renderOverlay(t),this.controlsAboveOverlay&&this.interactive&&this.drawControls(t),this.fire("after:render"),this},_renderObjects:function(e,t){var n,r;if(!t||this.preserveObjectStacking)for(n=0,r=this._objects.length;n<r;++n)this._draw(e,this._objects[n]);else for(n=0,r=this._objects.length;n<r;++n)this._objects[n]&&!t.contains(this._objects[n])&&this._draw(e,this._objects[n])},_renderActiveGroup:function(e,t){if(t){var n=[];this.forEachObject(function(e){t.contains(e)&&n.push(e)}),t._set("objects",n),this._draw(e,t)}},_renderBackground:function(e){this.backgroundColor&&(e.fillStyle=this.backgroundColor.toLive?this.backgroundColor.toLive(e):this.backgroundColor,e.fillRect(this.backgroundColor.offsetX||0,this.backgroundColor.offsetY||0,this.width,this.height)),this.backgroundImage&&this._draw(e,this.backgroundImage)},_renderOverlay:function(e){this.overlayColor&&(e.fillStyle=this.overlayColor.toLive?this.overlayColor.toLive(e):this.overlayColor,e.fillRect(this.overlayColor.offsetX||0,this.overlayColor.offsetY||0,this.width,this.height)),this.overlayImage&&this._draw(e,this.overlayImage)},renderTop:function(){var e=this.contextTop||this.contextContainer;this.clearContext(e),this.selection&&this._groupSelector&&this._drawSelection();var t=this.getActiveGroup();return t&&t.render(e),this._renderOverlay(e),this.fire("after:render"),this},getCenter:function(){return{top:this.getHeight()/2,left:this.getWidth()/2}},centerObjectH:function(e){return this._centerObject(e,new fabric.Point(this.getCenter().left,e.getCenterPoint().y)),this.renderAll(),this},centerObjectV:function(e){return this._centerObject(e,new fabric.Point(e.getCenterPoint().x,this.getCenter().top)),this.renderAll(),this},centerObject:function(e){var t=this.getCenter();return this._centerObject(e,new fabric.Point(t.left,t.top)),this.renderAll(),this},_centerObject:function(e,t){return e.setPositionByOrigin(t,"center","center"),this},toDatalessJSON:function(e){return this.toDatalessObject(e)},toObject:function(e){return this._toObjectMethod("toObject",e)},toDatalessObject:function(e){return this._toObjectMethod("toDatalessObject",e)},_toObjectMethod:function(t,n){var r=this.getActiveGroup();r&&this.discardActiveGroup();var i={objects:this._toObjects(t,n)};return e(i,this.__serializeBgOverlay()),fabric.util.populateWithProperties(this,i,n),r&&(this.setActiveGroup(new fabric.Group(r.getObjects(),{originX:"center",originY:"center"})),r.forEachObject(function(e){e.set("active",!0)}),this._currentTransform&&(this._currentTransform.target=this.getActiveGroup())),i},_toObjects:function(e,t){return this.getObjects().map(function(n){return this._toObject(n,e,t)},this)},_toObject:function(e,t,n){var r;this.includeDefaultValues||(r=e.includeDefaultValues,e.includeDefaultValues=!1);var i=e[t](n);return this.includeDefaultValues||(e.includeDefaultValues=r),i},__serializeBgOverlay:function(){var e={background:this.backgroundColor&&this.backgroundColor.toObject?this.backgroundColor.toObject():this.backgroundColor};return this.overlayColor&&(e.overlay=this.overlayColor.toObject?this.overlayColor.toObject():this.overlayColor),this.backgroundImage&&(e.backgroundImage=this.backgroundImage.toObject()),this.overlayImage&&(e.overlayImage=this.overlayImage.toObject()),e},svgViewportTransformation:!0,toSVG:function(e,t){e||(e={});var n=[];return this._setSVGPreamble(n,e),this._setSVGHeader(n,e),this._setSVGBgOverlayColor(n,"backgroundColor"),this._setSVGBgOverlayImage(n,"backgroundImage"),this._setSVGObjects(n,t),this._setSVGBgOverlayColor(n,"overlayColor"),this._setSVGBgOverlayImage(n,"overlayImage"),n.push("</svg>"),n.join("")},_setSVGPreamble:function(e,t){t.suppressPreamble||e.push('<?xml version="1.0" encoding="',t.encoding||"UTF-8",'" standalone="no" ?>','<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ','"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')},_setSVGHeader:function(e,t){var n,r,i;t.viewBox?(n=t.viewBox.width,r=t.viewBox.height):(n=this.width,r=this.height,this.svgViewportTransformation||(i=this.viewportTransform,n/=i[0],r/=i[3])),e.push("<svg ",'xmlns="http://www.w3.org/2000/svg" ','xmlns:xlink="http://www.w3.org/1999/xlink" ','version="1.1" ','width="',n,'" ','height="',r,'" ',this.backgroundColor&&!this.backgroundColor.toLive?'style="background-color: '+this.backgroundColor+'" ':null,t.viewBox?'viewBox="'+t.viewBox.x+" "+t.viewBox.y+" "+t.viewBox.width+" "+t.viewBox.height+'" ':null,'xml:space="preserve">',"<desc>Created with Fabric.js ",fabric.version,"</desc>","<defs>",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"</defs>")},_setSVGObjects:function(e,t){var n=this.getActiveGroup();n&&this.discardActiveGroup();for(var r=0,i=this.getObjects(),s=i.length;r<s;r++)e.push(i[r].toSVG(t));n&&(this.setActiveGroup(new fabric.Group(n.getObjects())),n.forEachObject(function(e){e.set("active",!0)}))},_setSVGBgOverlayImage:function(e,t){this[t]&&this[t].toSVG&&e.push(this[t].toSVG())},_setSVGBgOverlayColor:function(e,t){this[t]&&this[t].source?e.push('<rect x="',this[t].offsetX,'" y="',this[t].offsetY,'" ','width="',this[t].repeat==="repeat-y"||this[t].repeat==="no-repeat"?this[t].source.width:this.width,'" height="',this[t].repeat==="repeat-x"||this[t].repeat==="no-repeat"?this[t].source.height:this.height,'" fill="url(#'+t+'Pattern)"',"></rect>"):this[t]&&t==="overlayColor"&&e.push('<rect x="0" y="0" ','width="',this.width,'" height="',this.height,'" fill="',this[t],'"',"></rect>")},sendToBack:function(e){return n(this._objects,e),this._objects.unshift(e),this.renderAll&&this.renderAll()},bringToFront:function(e){return n(this._objects,e),this._objects.push(e),this.renderAll&&this.renderAll()},sendBackwards:function(e,t){var r=this._objects.indexOf(e);if(r!==0){var i=this._findNewLowerIndex(e,r,t);n(this._objects,e),this._objects.splice(i,0,e),this.renderAll&&this.renderAll()}return this},_findNewLowerIndex:function(e,t,n){var r;if(n){r=t;for(var i=t-1;i>=0;--i){var s=e.intersectsWithObject(this._objects[i])||e.isContainedWithinObject +(this._objects[i])||this._objects[i].isContainedWithinObject(e);if(s){r=i;break}}}else r=t-1;return r},bringForward:function(e,t){var r=this._objects.indexOf(e);if(r!==this._objects.length-1){var i=this._findNewUpperIndex(e,r,t);n(this._objects,e),this._objects.splice(i,0,e),this.renderAll&&this.renderAll()}return this},_findNewUpperIndex:function(e,t,n){var r;if(n){r=t;for(var i=t+1;i<this._objects.length;++i){var s=e.intersectsWithObject(this._objects[i])||e.isContainedWithinObject(this._objects[i])||this._objects[i].isContainedWithinObject(e);if(s){r=i;break}}}else r=t+1;return r},moveTo:function(e,t){return n(this._objects,e),this._objects.splice(t,0,e),this.renderAll&&this.renderAll()},dispose:function(){return this.clear(),this.interactive&&this.removeListeners(),this},toString:function(){return"#<fabric.Canvas ("+this.complexity()+"): "+"{ objects: "+this.getObjects().length+" }>"}}),e(fabric.StaticCanvas.prototype,fabric.Observable),e(fabric.StaticCanvas.prototype,fabric.Collection),e(fabric.StaticCanvas.prototype,fabric.DataURLExporter),e(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(e){var t=fabric.util.createCanvasElement();if(!t||!t.getContext)return null;var n=t.getContext("2d");if(!n)return null;switch(e){case"getImageData":return typeof n.getImageData!="undefined";case"setLineDash":return typeof n.setLineDash!="undefined";case"toDataURL":return typeof t.toDataURL!="undefined";case"toDataURLWithQuality":try{return t.toDataURL("image/jpeg",0),!0}catch(r){}return!1;default:return null}}}),fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject}(),fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",setShadow:function(e){return this.shadow=new fabric.Shadow(e),this},_setBrushStyles:function(){var e=this.canvas.contextTop;e.strokeStyle=this.color,e.lineWidth=this.width,e.lineCap=this.strokeLineCap,e.lineJoin=this.strokeLineJoin},_setShadow:function(){if(!this.shadow)return;var e=this.canvas.contextTop;e.shadowColor=this.shadow.color,e.shadowBlur=this.shadow.blur,e.shadowOffsetX=this.shadow.offsetX,e.shadowOffsetY=this.shadow.offsetY},_resetShadow:function(){var e=this.canvas.contextTop;e.shadowColor="",e.shadowBlur=e.shadowOffsetX=e.shadowOffsetY=0}}),function(){fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(e){this.canvas=e,this._points=[]},onMouseDown:function(e){this._prepareForDrawing(e),this._captureDrawingPath(e),this._render()},onMouseMove:function(e){this._captureDrawingPath(e),this.canvas.clearContext(this.canvas.contextTop),this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(e){var t=new fabric.Point(e.x,e.y);this._reset(),this._addPoint(t),this.canvas.contextTop.moveTo(t.x,t.y)},_addPoint:function(e){this._points.push(e)},_reset:function(){this._points.length=0,this._setBrushStyles(),this._setShadow()},_captureDrawingPath:function(e){var t=new fabric.Point(e.x,e.y);this._addPoint(t)},_render:function(){var e=this.canvas.contextTop,t=this.canvas.viewportTransform,n=this._points[0],r=this._points[1];e.save(),e.transform(t[0],t[1],t[2],t[3],t[4],t[5]),e.beginPath(),this._points.length===2&&n.x===r.x&&n.y===r.y&&(n.x-=.5,r.x+=.5),e.moveTo(n.x,n.y);for(var i=1,s=this._points.length;i<s;i++){var o=n.midPointFrom(r);e.quadraticCurveTo(n.x,n.y,o.x,o.y),n=this._points[i],r=this._points[i+1]}e.lineTo(n.x,n.y),e.stroke(),e.restore()},convertPointsToSVGPath:function(e){var t=[],n=new fabric.Point(e[0].x,e[0].y),r=new fabric.Point(e[1].x,e[1].y);t.push("M ",e[0].x," ",e[0].y," ");for(var i=1,s=e.length;i<s;i++){var o=n.midPointFrom(r);t.push("Q ",n.x," ",n.y," ",o.x," ",o.y," "),n=new fabric.Point(e[i].x,e[i].y),i+1<e.length&&(r=new fabric.Point(e[i+1].x,e[i+1].y))}return t.push("L ",n.x," ",n.y," "),t},createPath:function(e){var t=new fabric.Path(e,{fill:null,stroke:this.color,strokeWidth:this.width,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,originX:"center",originY:"center"});return this.shadow&&(this.shadow.affectStroke=!0,t.setShadow(this.shadow)),t},_finalizeAndAddPath:function(){var e=this.canvas.contextTop;e.closePath();var t=this.convertPointsToSVGPath(this._points).join("");if(t==="M 0 0 Q 0 0 0 0 L 0 0"){this.canvas.renderAll();return}var n=this.createPath(t);this.canvas.add(n),n.setCoords(),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderAll(),this.canvas.fire("path:created",{path:n})}})}(),fabric.CircleBrush=fabric.util.createClass(fabric.BaseBrush,{width:10,initialize:function(e){this.canvas=e,this.points=[]},drawDot:function(e){var t=this.addPoint(e),n=this.canvas.contextTop,r=this.canvas.viewportTransform;n.save(),n.transform(r[0],r[1],r[2],r[3],r[4],r[5]),n.fillStyle=t.fill,n.beginPath(),n.arc(t.x,t.y,t.radius,0,Math.PI*2,!1),n.closePath(),n.fill(),n.restore()},onMouseDown:function(e){this.points.length=0,this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.drawDot(e)},onMouseMove:function(e){this.drawDot(e)},onMouseUp:function(){var e=this.canvas.renderOnAddRemove;this.canvas.renderOnAddRemove=!1;var t=[];for(var n=0,r=this.points.length;n<r;n++){var i=this.points[n],s=new fabric.Circle({radius:i.radius,left:i.x,top:i.y,originX:"center",originY:"center",fill:i.fill});this.shadow&&s.setShadow(this.shadow),t.push(s)}var o=new fabric.Group(t,{originX:"center",originY:"center"});o.canvas=this.canvas,this.canvas.add(o),this.canvas.fire("path:created",{path:o}),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderOnAddRemove=e,this.canvas.renderAll()},addPoint:function(e){var t=new fabric.Point(e.x,e.y),n=fabric.util.getRandomInt(Math.max(0,this.width-20),this.width+20)/2,r=(new fabric.Color(this.color)).setAlpha(fabric.util.getRandomInt(0,100)/100).toRgba();return t.radius=n,t.fill=r,this.points.push(t),t}}),fabric.SprayBrush=fabric.util.createClass(fabric.BaseBrush,{width:10,density:20,dotWidth:1,dotWidthVariance:1,randomOpacity:!1,optimizeOverlapping:!0,initialize:function(e){this.canvas=e,this.sprayChunks=[]},onMouseDown:function(e){this.sprayChunks.length=0,this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.addSprayChunk(e),this.render()},onMouseMove:function(e){this.addSprayChunk(e),this.render()},onMouseUp:function(){var e=this.canvas.renderOnAddRemove;this.canvas.renderOnAddRemove=!1;var t=[];for(var n=0,r=this.sprayChunks.length;n<r;n++){var i=this.sprayChunks[n];for(var s=0,o=i.length;s<o;s++){var u=new fabric.Rect({width:i[s].width,height:i[s].width,left:i[s].x+1,top:i[s].y+1,originX:"center",originY:"center",fill:this.color});this.shadow&&u.setShadow(this.shadow),t.push(u)}}this.optimizeOverlapping&&(t=this._getOptimizedRects(t));var a=new fabric.Group(t,{originX:"center",originY:"center"});a.canvas=this.canvas,this.canvas.add(a),this.canvas.fire("path:created",{path:a}),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderOnAddRemove=e,this.canvas.renderAll()},_getOptimizedRects:function(e){var t={},n;for(var r=0,i=e.length;r<i;r++)n=e[r].left+""+e[r].top,t[n]||(t[n]=e[r]);var s=[];for(n in t)s.push(t[n]);return s},render:function(){var e=this.canvas.contextTop;e.fillStyle=this.color;var t=this.canvas.viewportTransform;e.save(),e.transform(t[0],t[1],t[2],t[3],t[4],t[5]);for(var n=0,r=this.sprayChunkPoints.length;n<r;n++){var i=this.sprayChunkPoints[n];typeof i.opacity!="undefined"&&(e.globalAlpha=i.opacity),e.fillRect(i.x,i.y,i.width,i.width)}e.restore()},addSprayChunk:function(e){this.sprayChunkPoints=[];var t,n,r,i=this.width/2;for(var s=0;s<this.density;s++){t=fabric.util.getRandomInt(e.x-i,e.x+i),n=fabric.util.getRandomInt(e.y-i,e.y+i),this.dotWidthVariance?r=fabric.util.getRandomInt(Math.max(1,this.dotWidth-this.dotWidthVariance),this.dotWidth+this.dotWidthVariance):r=this.dotWidth;var o=new fabric.Point(t,n);o.width=r,this.randomOpacity&&(o.opacity=fabric.util.getRandomInt(0,100)/100),this.sprayChunkPoints.push(o)}this.sprayChunks.push(this.sprayChunkPoints)}}),fabric.PatternBrush=fabric.util.createClass(fabric.PencilBrush,{getPatternSrc:function(){var e=20,t=5,n=fabric.document.createElement("canvas"),r=n.getContext("2d");return n.width=n.height=e+t,r.fillStyle=this.color,r.beginPath(),r.arc(e/2,e/2,e/2,0,Math.PI*2,!1),r.closePath(),r.fill(),n},getPatternSrcFunction:function(){return String(this.getPatternSrc).replace("this.color",'"'+this.color+'"')},getPattern:function(){return this.canvas.contextTop.createPattern(this.source||this.getPatternSrc(),"repeat")},_setBrushStyles:function(){this.callSuper("_setBrushStyles"),this.canvas.contextTop.strokeStyle=this.getPattern()},createPath:function(e){var t=this.callSuper("createPath",e);return t.stroke=new fabric.Pattern({source:this.source||this.getPatternSrcFunction()}),t}}),function(){var e=fabric.util.getPointer,t=fabric.util.degreesToRadians,n=fabric.util.radiansToDegrees,r=Math.atan2,i=Math.abs,s=.5;fabric.Canvas=fabric.util.createClass(fabric.StaticCanvas,{initialize:function(e,t){t||(t={}),this._initStatic(e,t),this._initInteractive(),this._createCacheCanvas(),fabric.Canvas.activeInstance=this},uniScaleTransform:!1,centeredScaling:!1,centeredRotation:!1,interactive:!0,selection:!0,selectionColor:"rgba(100, 100, 255, 0.3)",selectionDashArray:[],selectionBorderColor:"rgba(255, 255, 255, 0.3)",selectionLineWidth:1,hoverCursor:"move",moveCursor:"move",defaultCursor:"default",freeDrawingCursor:"crosshair",rotationCursor:"crosshair",containerClass:"canvas-container",perPixelTargetFind:!1,targetFindTolerance:0,skipTargetFind:!1,_initInteractive:function(){this._currentTransform=null,this._groupSelector=null,this._initWrapperElement(),this._createUpperCanvas(),this._initEventListeners(),this.freeDrawingBrush=fabric.PencilBrush&&new fabric.PencilBrush(this),this.calcOffset()},_resetCurrentTransform:function(e){var t=this._currentTransform;t.target.set({scaleX:t.original.scaleX,scaleY:t.original.scaleY,left:t.original.left,top:t.original.top}),this._shouldCenterTransform(e,t.target)?t.action==="rotate"?this._setOriginToCenter(t.target):(t.originX!=="center"&&(t.originX==="right"?t.mouseXSign=-1:t.mouseXSign=1),t.originY!=="center"&&(t.originY==="bottom"?t.mouseYSign=-1:t.mouseYSign=1),t.originX="center",t.originY="center"):(t.originX=t.original.originX,t.originY=t.original.originY)},containsPoint:function(e,t){var n=this.getPointer(e,!0),r=this._normalizePointer(t,n);return t.containsPoint(r)||t._findTargetCorner(n)},_normalizePointer:function(e,t){var n=this.getActiveGroup(),r=t.x,i=t.y,s=n&&e.type!=="group"&&n.contains(e),o;return s&&(o=new fabric.Point(n.left,n.top),o=fabric.util.transformPoint(o,this.viewportTransform,!0),r-=o.x,i-=o.y),{x:r,y:i}},isTargetTransparent:function(e,t,n){var r=e.hasBorders,i=e.transparentCorners;e.hasBorders=e.transparentCorners=!1,this._draw(this.contextCache,e),e.hasBorders=r,e.transparentCorners=i;var s=fabric.util.isTransparent(this.contextCache,t,n,this.targetFindTolerance);return this.clearContext(this.contextCache),s},_shouldClearSelection:function(e,t){var n=this.getActiveGroup(),r=this.getActiveObject();return!t||t&&n&&!n.contains(t)&&n!==t&&!e.shiftKey||t&&!t.evented||t&&!t.selectable&&r&&r!==t},_shouldCenterTransform:function(e,t){if(!t)return;var n=this._currentTransform,r;return n.action==="scale"||n.action==="scaleX"||n.action==="scaleY"?r=this.centeredScaling||t.centeredScaling:n.action==="rotate"&&(r=this.centeredRotation||t.centeredRotation),r?!e.altKey:e.altKey},_getOriginFromCorner:function(e,t){var n={x:e.originX,y:e.originY};if(t==="ml"||t==="tl"||t==="bl")n.x="right";else if(t==="mr"||t==="tr"||t==="br")n.x="left";if(t==="tl"||t==="mt"||t==="tr")n.y="bottom";else if(t==="bl"||t==="mb"||t==="br")n.y="top";return n},_getActionFromCorner:function(e,t){var n="drag";return t&&(n=t==="ml"||t==="mr"?"scaleX":t==="mt"||t==="mb"?"scaleY":t==="mtr"?"rotate":"scale"),n},_setupCurrentTransform:function(e,n){if(!n)return;var r=this.getPointer(e),i=n._findTargetCorner(this.getPointer(e,!0)),s=this._getActionFromCorner(n,i),o=this._getOriginFromCorner(n,i);this._currentTransform={target:n,action:s,scaleX:n.scaleX,scaleY:n.scaleY,offsetX:r.x-n.left,offsetY:r.y-n.top,originX:o.x,originY:o.y,ex:r.x,ey:r.y,left:n.left,top:n.top,theta:t(n.angle),width:n.width*n.scaleX,mouseXSign:1,mouseYSign:1},this._currentTransform.original={left:n.left,top:n.top,scaleX:n.scaleX,scaleY:n.scaleY,originX:o.x,originY:o.y},this._resetCurrentTransform(e)},_translateObject:function(e,t){var n=this._currentTransform.target;n.get("lockMovementX")||n.set("left",e-this._currentTransform.offsetX),n.get("lockMovementY")||n.set("top",t-this._currentTransform.offsetY)},_scaleObject:function(e,t,n){var r=this._currentTransform,i=r.target,s=i.get("lockScalingX"),o=i.get("lockScalingY"),u=i.get("lockScalingFlip");if(s&&o)return;var a=i.translateToOriginPoint(i.getCenterPoint(),r.originX,r.originY),f=i.toLocalPoint(new fabric.Point(e,t),r.originX,r.originY);this._setLocalMouse(f,r),this._setObjectScale(f,r,s,o,n,u),i.setPositionByOrigin(a,r.originX,r.originY)},_setObjectScale:function(e,t,n,r,i,s){var o=t.target,u=!1,a=!1,f=o.stroke?o.strokeWidth:0;t.newScaleX=e.x/(o.width+f/2),t.newScaleY=e.y/(o.height+f/2),s&&t.newScaleX<=0&&t.newScaleX<o.scaleX&&(u=!0),s&&t.newScaleY<=0&&t.newScaleY<o.scaleY&&(a=!0),i==="equally"&&!n&&!r?u||a||this._scaleObjectEqually(e,o,t):i?i==="x"&&!o.get("lockUniScaling")?u||n||o.set("scaleX",t.newScaleX):i==="y"&&!o.get("lockUniScaling")&&(a||r||o.set("scaleY",t.newScaleY)):(u||n||o.set("scaleX",t.newScaleX),a||r||o.set("scaleY",t.newScaleY)),u||a||this._flipObject(t,i)},_scaleObjectEqually:function(e,t,n){var r=e.y+e.x,i=t.stroke?t.strokeWidth:0,s=(t.height+i/2)*n.original.scaleY+(t.width+i/2)*n.original.scaleX;n.newScaleX=n.original.scaleX*r/s,n.newScaleY=n.original.scaleY*r/s,t.set("scaleX",n.newScaleX),t.set("scaleY",n.newScaleY)},_flipObject:function(e,t){e.newScaleX<0&&t!=="y"&&(e.originX==="left"?e.originX="right":e.originX==="right"&&(e.originX="left")),e.newScaleY<0&&t!=="x"&&(e.originY==="top"?e.originY="bottom":e.originY==="bottom"&&(e.originY="top"))},_setLocalMouse:function(e,t){var n=t.target;t.originX==="right"?e.x*=-1:t.originX==="center"&&(e.x*=t.mouseXSign*2,e.x<0&&(t.mouseXSign=-t.mouseXSign)),t.originY==="bottom"?e.y*=-1:t.originY==="center"&&(e.y*=t.mouseYSign*2,e.y<0&&(t.mouseYSign=-t.mouseYSign)),i(e.x)>n.padding?e.x<0?e.x+=n.padding:e.x-=n.padding:e.x=0,i(e.y)>n.padding?e.y<0?e.y+=n.padding:e.y-=n.padding:e.y=0},_rotateObject:function(e,t){var i=this._currentTransform;if(i.target.get("lockRotation"))return;var s=r(i.ey-i.top,i.ex-i.left),o=r(t-i.top,e-i.left),u=n(o-s+i.theta);u<0&&(u=360+u),i.target.angle=u%360},setCursor:function(e){this.upperCanvasEl.style.cursor=e},_resetObjectTransform:function(e){e.scaleX=1,e.scaleY=1,e.setAngle(0)},_drawSelection:function(){var e=this.contextTop,t=this._groupSelector,n=t.left,r=t.top,o=i(n),u=i(r);e.fillStyle=this.selectionColor,e.fillRect(t.ex-(n>0?0:-n),t.ey-(r>0?0:-r),o,u),e.lineWidth=this.selectionLineWidth,e.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var a=t.ex+s-(n>0?0:o),f=t.ey+s-(r>0?0:u);e.beginPath(),fabric.util.drawDashedLine(e,a,f,a+o,f,this.selectionDashArray),fabric.util.drawDashedLine(e,a,f+u-1,a+o,f+u-1,this.selectionDashArray),fabric.util.drawDashedLine(e,a,f,a,f+u,this.selectionDashArray),fabric.util.drawDashedLine(e,a+o-1,f,a+o-1,f+u,this.selectionDashArray),e.closePath(),e.stroke()}else e.strokeRect(t.ex+s-(n>0?0:o),t.ey+s-(r>0?0:u),o,u)},_isLastRenderedObject:function(e){return this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e,!0))},findTarget:function(e,t){if(this.skipTargetFind)return;if(this._isLastRenderedObject(e))return this.lastRenderedObjectWithControlsAboveOverlay;var n=this.getActiveGroup();if(n&&!t&&this.containsPoint(e,n))return n;var r=this._searchPossibleTargets(e);return this._fireOverOutEvents(r),r},_fireOverOutEvents:function(e){e?this._hoveredTarget!==e&&(this.fire("mouse:over",{target:e}),e.fire("mouseover"),this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget}),this._hoveredTarget.fire("mouseout")),this._hoveredTarget=e):this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget}),this._hoveredTarget.fire("mouseout"),this._hoveredTarget=null)},_checkTarget:function(e,t,n){if(t&&t.visible&&t.evented&&this.containsPoint(e,t)){if(!this.perPixelTargetFind&&!t.perPixelTargetFind||!!t.isEditing)return!0;var r=this.isTargetTransparent(t,n.x,n.y);if(!r)return!0}},_searchPossibleTargets:function(e){var t,n=this.getPointer(e,!0),r=this._objects.length;while(r--)if(this._checkTarget(e,this._objects[r],n)){this.relatedTarget=this._objects[r],t=this._objects[r];break}return t},getPointer:function(t,n,r){r||(r=this.upperCanvasEl);var i=e(t,r),s=r.getBoundingClientRect(),o=s.width||0,u=s.height||0,a;if(!o||!u)"top"in s&&"bottom"in s&&(u=Math.abs(s.top-s.bottom)),"right"in s&&"left"in s&&(o=Math.abs(s.right-s.left));return this.calcOffset(),i.x=i.x-this._offset.left,i.y=i.y-this._offset.top,n||(i=fabric.util.transformPoint(i,fabric.util.invertTransform(this.viewportTransform))),o===0||u===0?a={width:1,height:1}:a={width:r.width/o,height:r.height/u},{x:i.x*a.width,y:i.y*a.height}},_createUpperCanvas:function(){var e=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl=this._createCanvasElement(),fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+e),this.wrapperEl.appendChild(this.upperCanvasEl),this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl),this._applyCanvasStyle(this.upperCanvasEl),this.contextTop=this.upperCanvasEl.getContext("2d")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement(),this.cacheCanvasEl.setAttribute("width",this.width),this.cacheCanvasEl.setAttribute("height",this.height),this.contextCache=this.cacheCanvasEl.getContext("2d")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,"div",{"class":this.containerClass}),fabric.util.setStyle(this.wrapperEl,{width:this.getWidth()+"px",height:this.getHeight()+"px",position:"relative"}),fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(e){var t=this.getWidth()||e.width,n=this.getHeight()||e.height;fabric.util.setStyle(e,{position:"absolute",width:t+"px",height:n+"px",left:0,top:0}),e.width=t,e.height=n,fabric.util.makeElementUnselectable(e)},_copyCanvasStyle:function(e,t){t.style.cssText=e.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(e){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=e,e.set("active",!0)},setActiveObject:function(e,t){return this._setActiveObject(e),this.renderAll(),this.fire("object:selected",{target:e,e:t}),e.fire("selected",{e:t}),this},getActiveObject:function(){return this._activeObject},_discardActiveObject:function(){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=null},discardActiveObject:function(e){return this._discardActiveObject(),this.renderAll(),this.fire("selection:cleared",{e:e}),this},_setActiveGroup:function(e){this._activeGroup=e,e&&e.set("active",!0)},setActiveGroup:function(e,t){return this._setActiveGroup(e),e&&(this.fire("object:selected",{target:e,e:t}),e.fire("selected",{e:t})),this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var e=this.getActiveGroup();e&&e.destroy(),this.setActiveGroup(null)},discardActiveGroup:function(e){return this._discardActiveGroup(),this.fire("selection:cleared",{e:e}),this},deactivateAll:function(){var e=this.getObjects(),t=0,n=e.length;for(;t<n;t++)e[t].set("active",!1);return this._discardActiveGroup(),this._discardActiveObject(),this},deactivateAllWithDispatch:function(e){var t=this.getActiveGroup()||this.getActiveObject();return t&&this.fire("before:selection:cleared",{target:t,e:e}),this.deactivateAll(),t&&this.fire("selection:cleared",{e:e}),this},drawControls:function(e){var t=this.getActiveGroup();t?this._drawGroupControls(e,t):this._drawObjectsControls(e)},_drawGroupControls:function(e,t){t._renderControls(e)},_drawObjectsControls:function(e){for(var t=0,n=this._objects.length;t<n;++t){if(!this._objects[t]||!this._objects[t].active)continue;this._objects[t]._renderControls(e),this.lastRenderedObjectWithControlsAboveOverlay=this._objects[t]}}});for(var o in fabric.StaticCanvas)o!=="prototype"&&(fabric.Canvas[o]=fabric.StaticCanvas[o]);fabric.isTouchSupported&&(fabric.Canvas.prototype._setCursorFromEvent=function(){}),fabric.Element=fabric.Canvas}(),function(){var e={mt:0,tr:1,mr:2,br:3,mb:4,bl:5,ml:6,tl:7},t=fabric.util.addListener,n=fabric.util.removeListener;fabric.util.object.extend(fabric.Canvas.prototype,{cursorMap:["n-resize","ne-resize","e-resize","se-resize","s-resize","sw-resize","w-resize","nw-resize"],_initEventListeners:function(){this._bindEvents(),t(fabric.window,"resize",this._onResize),t(this.upperCanvasEl,"mousedown",this._onMouseDown),t(this.upperCanvasEl,"mousemove",this._onMouseMove),t(this.upperCanvasEl,"mousewheel",this._onMouseWheel),t(this.upperCanvasEl,"touchstart",this._onMouseDown),t(this.upperCanvasEl,"touchmove",this._onMouseMove),typeof Event!="undefined"&&"add"in Event&&(Event.add(this.upperCanvasEl,"gesture",this._onGesture),Event.add(this.upperCanvasEl,"drag",this._onDrag),Event.add(this.upperCanvasEl,"orientation",this._onOrientationChange),Event.add(this.upperCanvasEl,"shake",this._onShake),Event.add(this.upperCanvasEl,"longpress",this._onLongPress))},_bindEvents:function(){this._onMouseDown=this._onMouseDown.bind(this),this._onMouseMove=this._onMouseMove.bind(this),this._onMouseUp=this._onMouseUp.bind(this),this._onResize=this._onResize.bind(this),this._onGesture=this._onGesture.bind(this),this._onDrag=this._onDrag.bind(this),this._onShake=this._onShake.bind(this),this._onLongPress=this._onLongPress.bind(this),this._onOrientationChange=this._onOrientationChange.bind(this),this._onMouseWheel=this._onMouseWheel.bind(this)},removeListeners:function(){n(fabric.window,"resize",this._onResize),n(this.upperCanvasEl,"mousedown",this._onMouseDown),n(this.upperCanvasEl,"mousemove",this._onMouseMove),n(this.upperCanvasEl,"mousewheel",this._onMouseWheel),n(this.upperCanvasEl,"touchstart",this._onMouseDown),n(this.upperCanvasEl,"touchmove",this._onMouseMove),typeof Event!="undefined"&&"remove"in Event&&(Event.remove(this.upperCanvasEl,"gesture",this._onGesture),Event.remove(this.upperCanvasEl,"drag",this._onDrag),Event.remove(this.upperCanvasEl,"orientation",this._onOrientationChange),Event.remove(this.upperCanvasEl,"shake",this._onShake),Event.remove(this.upperCanvasEl,"longpress",this._onLongPress))},_onGesture:function(e,t){this.__onTransformGesture&&this.__onTransformGesture(e,t)},_onDrag:function(e,t){this.__onDrag&&this.__onDrag(e,t)},_onMouseWheel:function(e,t){this.__onMouseWheel&&this.__onMouseWheel(e,t)},_onOrientationChange:function(e,t){this.__onOrientationChange&&this.__onOrientationChange(e,t)},_onShake:function(e,t){this.__onShake&&this.__onShake(e,t)},_onLongPress:function(e,t){this.__onLongPress&&this.__onLongPress(e,t)},_onMouseDown:function(e){this.__onMouseDown(e),t(fabric.document,"touchend",this._onMouseUp),t(fabric.document,"touchmove",this._onMouseMove),n(this.upperCanvasEl,"mousemove",this._onMouseMove),n(this.upperCanvasEl,"touchmove",this._onMouseMove),e.type==="touchstart"?n(this.upperCanvasEl,"mousedown",this._onMouseDown):(t(fabric.document,"mouseup",this._onMouseUp),t(fabric.document,"mousemove",this._onMouseMove))},_onMouseUp:function(e){this.__onMouseUp(e),n(fabric.document,"mouseup",this._onMouseUp),n(fabric.document,"touchend",this._onMouseUp),n(fabric.document,"mousemove",this._onMouseMove),n(fabric.document,"touchmove",this._onMouseMove),t(this.upperCanvasEl,"mousemove",this._onMouseMove),t(this.upperCanvasEl,"touchmove",this._onMouseMove);if(e.type==="touchend"){var r=this;setTimeout(function(){t(r.upperCanvasEl,"mousedown",r._onMouseDown)},400)}},_onMouseMove:function(e){!this.allowTouchScrolling&&e.preventDefault&&e.preventDefault(),this.__onMouseMove(e)},_onResize:function(){this.calcOffset()},_shouldRender:function(e,t){var n=this.getActiveGroup()||this.getActiveObject();return!!(e&&(e.isMoving||e!==n)||!e&&!!n||!e&&!n&&!this._groupSelector||t&&this._previousPointer&&this.selection&&(t.x!==this._previousPointer.x||t.y!==this._previousPointer.y))},__onMouseUp:function(e){var t;if(this.isDrawingMode&&this._isCurrentlyDrawing){this._onMouseUpInDrawingMode(e);return}this._currentTransform?(this._finalizeCurrentTransform(),t=this._currentTransform.target):t=this.findTarget(e,!0);var n=this._shouldRender(t,this.getPointer(e));this._maybeGroupObjects(e),t&&(t.isMoving=!1),n&&this.renderAll(),this._handleCursorAndEvent(e,t)},_handleCursorAndEvent:function(e,t){this._setCursorFromEvent(e,t);var n=this;setTimeout(function(){n._setCursorFromEvent(e,t)},50),this.fire("mouse:up",{target:t,e:e}),t&&t.fire("mouseup",{e:e})},_finalizeCurrentTransform:function(){var e=this._currentTransform,t=e.target;t._scaling&&(t._scaling=!1),t.setCoords(),this.stateful&&t.hasStateChanged()&&(this.fire("object:modified",{target:t}),t.fire("modified")),this._restoreOriginXY(t)},_restoreOriginXY:function(e){if(this._previousOriginX&&this._previousOriginY){var t=e.translateToOriginPoint(e.getCenterPoint(),this._previousOriginX,this._previousOriginY);e.originX=this._previousOriginX,e.originY=this._previousOriginY,e.left=t.x,e.top=t.y,this._previousOriginX=null,this._previousOriginY=null}},_onMouseDownInDrawingMode:function(e){this._isCurrentlyDrawing=!0,this.discardActiveObject(e).renderAll(),this.clipTo&&fabric.util.clipContext(this,this.contextTop);var t=fabric.util.invertTransform(this.viewportTransform),n=fabric.util.transformPoint(this.getPointer(e,!0),t);this.freeDrawingBrush.onMouseDown(n),this.fire("mouse:down",{e:e});var r=this.findTarget(e);typeof r!="undefined"&&r.fire("mousedown",{e:e,target:r})},_onMouseMoveInDrawingMode:function(e){if(this._isCurrentlyDrawing){var t=fabric.util.invertTransform(this.viewportTransform),n=fabric.util.transformPoint(this.getPointer(e,!0),t);this.freeDrawingBrush.onMouseMove(n)}this.setCursor(this.freeDrawingCursor),this.fire("mouse:move",{e:e});var r=this.findTarget(e);typeof r!="undefined"&&r.fire("mousemove",{e:e,target:r})},_onMouseUpInDrawingMode:function(e){this._isCurrentlyDrawing=!1,this.clipTo&&this.contextTop.restore(),this.freeDrawingBrush.onMouseUp(),this.fire("mouse:up",{e:e});var t=this.findTarget(e);typeof t!="undefined"&&t.fire("mouseup",{e:e,target:t})},__onMouseDown:function(e){var t="which"in e?e.which===1:e.button===1;if(!t&&!fabric.isTouchSupported)return;if(this.isDrawingMode){this._onMouseDownInDrawingMode(e);return}if(this._currentTransform)return;var n=this.findTarget(e),r=this.getPointer(e,!0);this._previousPointer=r;var i=this._shouldRender(n,r),s=this._shouldGroup(e,n);this._shouldClearSelection(e,n)?this._clearSelection(e,n,r):s&&(this._handleGrouping(e,n),n=this.getActiveGroup()),n&&n.selectable&&!s&&(this._beforeTransform(e,n),this._setupCurrentTransform(e,n)),i&&this.renderAll(),this.fire("mouse:down",{target:n,e:e}),n&&n.fire("mousedown",{e:e})},_beforeTransform:function(e,t){var n;this.stateful&&t.saveState(),(n=t._findTargetCorner(this.getPointer(e)))&&this.onBeforeScaleRotate(t),t!==this.getActiveGroup()&&t!==this.getActiveObject()&&(this.deactivateAll(),this.setActiveObject(t,e))},_clearSelection:function(e,t,n){this.deactivateAllWithDispatch(e),t&&t.selectable?this.setActiveObject(t,e):this.selection&&(this._groupSelector={ex:n.x,ey:n.y,top:0,left:0})},_setOriginToCenter:function(e){this._previousOriginX=this._currentTransform.target.originX,this._previousOriginY=this._currentTransform.target.originY;var t=e.getCenterPoint();e.originX="center",e.originY="center",e.left=t.x,e.top=t.y,this._currentTransform.left=e.left,this._currentTransform.top=e.top},_setCenterToOrigin:function(e){var t=e.translateToOriginPoint(e.getCenterPoint(),this._previousOriginX,this._previousOriginY);e.originX=this._previousOriginX,e.originY=this._previousOriginY,e.left=t.x,e.top=t.y,this._previousOriginX=null,this._previousOriginY=null},__onMouseMove:function(e){var t,n;if(this.isDrawingMode){this._onMouseMoveInDrawingMode(e);return}if(typeof e.touches!="undefined"&&e.touches.length>1)return;var r=this._groupSelector;r?(n=this.getPointer(e,!0),r.left=n.x-r.ex,r.top=n.y-r.ey,this.renderTop()):this._currentTransform?this._transformObject(e):(t=this.findTarget(e),!t||t&&!t.selectable?this.setCursor(this.defaultCursor):this._setCursorFromEvent(e,t)),this.fire("mouse:move",{target:t,e:e}),t&&t.fire("mousemove",{e:e})},_transformObject:function(e){var t=this.getPointer(e),n=this._currentTransform;n.reset=!1,n.target.isMoving=!0,this._beforeScaleTransform(e,n),this._performTransformAction(e,n,t),this.renderAll()},_performTransformAction:function(e,t,n){var r=n.x,i=n.y,s=t.target,o=t.action;o==="rotate"?(this._rotateObject(r,i),this._fire("rotating",s,e)):o==="scale"?(this._onScale(e,t,r,i),this._fire("scaling",s,e)):o==="scaleX"?(this._scaleObject(r,i,"x"),this._fire("scaling",s,e)):o==="scaleY"?(this._scaleObject(r,i,"y"),this._fire("scaling",s,e)):(this._translateObject(r,i),this._fire("moving",s,e),this.setCursor(this.moveCursor))},_fire:function(e,t,n){this.fire("object:"+e,{target:t,e:n}),t.fire(e,{e:n})},_beforeScaleTransform:function(e,t){if(t.action==="scale"||t.action==="scaleX"||t.action==="scaleY"){var n=this._shouldCenterTransform(e,t.target);if(n&&(t.originX!=="center"||t.originY!=="center")||!n&&t.originX==="center"&&t.originY==="center")this._resetCurrentTransform(e),t.reset=!0}},_onScale:function(e,t,n,r){(e.shiftKey||this.uniScaleTransform)&&!t.target.get("lockUniScaling")?(t.currentAction="scale",this._scaleObject(n,r)):(!t.reset&&t.currentAction==="scale"&&this._resetCurrentTransform(e,t.target),t.currentAction="scaleEqually",this._scaleObject(n,r,"equally"))},_setCursorFromEvent:function(e,t){if(!t||!t.selectable)return this.setCursor(this.defaultCursor),!1;var n=this.getActiveGroup(),r=t._findTargetCorner&&(!n||!n.contains(t))&&t._findTargetCorner(this.getPointer(e,!0));return r?this._setCornerCursor(r,t):this.setCursor(t.hoverCursor||this.hoverCursor),!0},_setCornerCursor:function(t,n){if(t in e)this.setCursor(this._getRotatedCornerCursor(t,n));else{if(t!=="mtr"||!n.hasRotatingPoint)return this.setCursor(this.defaultCursor),!1;this.setCursor(this.rotationCursor)}},_getRotatedCornerCursor:function(t,n){var r=Math.round(n.getAngle()%360/45);return r<0&&(r+=8),r+=e[t],r%=8,this.cursorMap[r]}})}(),function(){var e=Math.min,t=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(e,t){var n=this.getActiveObject();return e.shiftKey&&(this.getActiveGroup()||n&&n!==t)&&this.selection},_handleGrouping:function(e,t){if(t===this.getActiveGroup()){t=this.findTarget(e,!0);if(!t||t.isType("group"))return}this.getActiveGroup()?this._updateActiveGroup(t,e):this._createActiveGroup(t,e),this._activeGroup&&this._activeGroup.saveCoords()},_updateActiveGroup:function(e,t){var n=this.getActiveGroup();if(n.contains(e)){n.removeWithUpdate(e),this._resetObjectTransform(n),e.set("active",!1);if(n.size()===1){this.discardActiveGroup(t),this.setActiveObject(n.item(0));return}}else n.addWithUpdate(e),this._resetObjectTransform(n);this.fire("selection:created",{target:n,e:t}),n.set("active",!0)},_createActiveGroup:function(e,t){if(this._activeObject&&e!==this._activeObject){var n=this._createGroup(e);n.addWithUpdate(),this.setActiveGroup(n),this._activeObject=null,this.fire("selection:created",{target:n,e:t})}e.set("active",!0)},_createGroup:function(e){var t=this.getObjects(),n=t.indexOf(this._activeObject)<t.indexOf(e),r=n?[this._activeObject,e]:[e,this._activeObject];return new fabric.Group(r,{canvas:this})},_groupSelectedObjects:function(e){var t=this._collectObjects();t.length===1?this.setActiveObject(t[0],e):t.length>1&&(t=new fabric.Group(t.reverse(),{canvas:this}),t.addWithUpdate(),this.setActiveGroup(t,e),t.saveCoords(),this.fire("selection:created",{target:t}),this.renderAll())},_collectObjects:function(){var n=[],r,i=this._groupSelector.ex,s=this._groupSelector.ey,o=i+this._groupSelector.left,u=s+this._groupSelector.top,a=new fabric.Point(e(i,o),e(s,u)),f=new fabric.Point(t(i,o),t(s,u)), +l=i===o&&s===u;for(var c=this._objects.length;c--;){r=this._objects[c];if(!r||!r.selectable||!r.visible)continue;if(r.intersectsWithRect(a,f)||r.isContainedWithinRect(a,f)||r.containsPoint(a)||r.containsPoint(f)){r.set("active",!0),n.push(r);if(l)break}}return n},_maybeGroupObjects:function(e){this.selection&&this._groupSelector&&this._groupSelectedObjects(e);var t=this.getActiveGroup();t&&(t.setObjectsCoords().setCoords(),t.isMoving=!1,this.setCursor(this.defaultCursor)),this._groupSelector=null,this._currentTransform=null}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(e){e||(e={});var t=e.format||"png",n=e.quality||1,r=e.multiplier||1,i={left:e.left,top:e.top,width:e.width,height:e.height};return r!==1?this.__toDataURLWithMultiplier(t,n,i,r):this.__toDataURL(t,n,i)},__toDataURL:function(e,t,n){this.renderAll(!0);var r=this.upperCanvasEl||this.lowerCanvasEl,i=this.__getCroppedCanvas(r,n);e==="jpg"&&(e="jpeg");var s=fabric.StaticCanvas.supports("toDataURLWithQuality")?(i||r).toDataURL("image/"+e,t):(i||r).toDataURL("image/"+e);return this.contextTop&&this.clearContext(this.contextTop),this.renderAll(),i&&(i=null),s},__getCroppedCanvas:function(e,t){var n,r,i="left"in t||"top"in t||"width"in t||"height"in t;return i&&(n=fabric.util.createCanvasElement(),r=n.getContext("2d"),n.width=t.width||this.width,n.height=t.height||this.height,r.drawImage(e,-t.left||0,-t.top||0)),n},__toDataURLWithMultiplier:function(e,t,n,r){var i=this.getWidth(),s=this.getHeight(),o=i*r,u=s*r,a=this.getActiveObject(),f=this.getActiveGroup(),l=this.contextTop||this.contextContainer;r>1&&this.setWidth(o).setHeight(u),l.scale(r,r),n.left&&(n.left*=r),n.top&&(n.top*=r),n.width?n.width*=r:r<1&&(n.width=o),n.height?n.height*=r:r<1&&(n.height=u),f?this._tempRemoveBordersControlsFromGroup(f):a&&this.deactivateAll&&this.deactivateAll(),this.renderAll(!0);var c=this.__toDataURL(e,t,n);return this.width=i,this.height=s,l.scale(1/r,1/r),this.setWidth(i).setHeight(s),f?this._restoreBordersControlsOnGroup(f):a&&this.setActiveObject&&this.setActiveObject(a),this.contextTop&&this.clearContext(this.contextTop),this.renderAll(),c},toDataURLWithMultiplier:function(e,t,n){return this.toDataURL({format:e,multiplier:t,quality:n})},_tempRemoveBordersControlsFromGroup:function(e){e.origHasControls=e.hasControls,e.origBorderColor=e.borderColor,e.hasControls=!0,e.borderColor="rgba(0,0,0,0)",e.forEachObject(function(e){e.origBorderColor=e.borderColor,e.borderColor="rgba(0,0,0,0)"})},_restoreBordersControlsOnGroup:function(e){e.hideControls=e.origHideControls,e.borderColor=e.origBorderColor,e.forEachObject(function(e){e.borderColor=e.origBorderColor,delete e.origBorderColor})}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(e,t,n){return this.loadFromJSON(e,t,n)},loadFromJSON:function(e,t,n){if(!e)return;var r=typeof e=="string"?JSON.parse(e):e;this.clear();var i=this;return this._enlivenObjects(r.objects,function(){i._setBgOverlay(r,t)},n),this},_setBgOverlay:function(e,t){var n=this,r={backgroundColor:!1,overlayColor:!1,backgroundImage:!1,overlayImage:!1};if(!e.backgroundImage&&!e.overlayImage&&!e.background&&!e.overlay){t&&t();return}var i=function(){r.backgroundImage&&r.overlayImage&&r.backgroundColor&&r.overlayColor&&(n.renderAll(),t&&t())};this.__setBgOverlay("backgroundImage",e.backgroundImage,r,i),this.__setBgOverlay("overlayImage",e.overlayImage,r,i),this.__setBgOverlay("backgroundColor",e.background,r,i),this.__setBgOverlay("overlayColor",e.overlay,r,i),i()},__setBgOverlay:function(e,t,n,r){var i=this;if(!t){n[e]=!0;return}e==="backgroundImage"||e==="overlayImage"?fabric.Image.fromObject(t,function(t){i[e]=t,n[e]=!0,r&&r()}):this["set"+fabric.util.string.capitalize(e,!0)](t,function(){n[e]=!0,r&&r()})},_enlivenObjects:function(e,t,n){var r=this;if(!e||e.length===0){t&&t();return}var i=this.renderOnAddRemove;this.renderOnAddRemove=!1,fabric.util.enlivenObjects(e,function(e){e.forEach(function(e,t){r.insertAt(e,t,!0)}),r.renderOnAddRemove=i,t&&t()},null,n)},_toDataURL:function(e,t){this.clone(function(n){t(n.toDataURL(e))})},_toDataURLWithMultiplier:function(e,t,n){this.clone(function(r){n(r.toDataURLWithMultiplier(e,t))})},clone:function(e,t){var n=JSON.stringify(this.toJSON(t));this.cloneWithoutData(function(t){t.loadFromJSON(n,function(){e&&e(t)})})},cloneWithoutData:function(e){var t=fabric.document.createElement("canvas");t.width=this.getWidth(),t.height=this.getHeight();var n=new fabric.Canvas(t);n.clipTo=this.clipTo,this.backgroundImage?(n.setBackgroundImage(this.backgroundImage.src,function(){n.renderAll(),e&&e(n)}),n.backgroundImageOpacity=this.backgroundImageOpacity,n.backgroundImageStretch=this.backgroundImageStretch):e&&e(n)}}),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.toFixed,i=t.util.string.capitalize,s=t.util.degreesToRadians,o=t.StaticCanvas.supports("setLineDash");if(t.Object)return;t.Object=t.util.createClass({type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:!1,flipY:!1,opacity:1,angle:0,cornerSize:12,transparentCorners:!0,hoverCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",cornerColor:"rgba(102,153,255,0.5)",centeredScaling:!1,centeredRotation:!0,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:!0,evented:!0,visible:!0,hasControls:!0,hasBorders:!0,hasRotatingPoint:!0,rotatingPointOffset:40,perPixelTargetFind:!1,includeDefaultValues:!0,clipTo:null,lockMovementX:!1,lockMovementY:!1,lockRotation:!1,lockScalingX:!1,lockScalingY:!1,lockUniScaling:!1,lockScalingFlip:!1,stateProperties:"top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor".split(" "),initialize:function(e){e&&this.setOptions(e)},_initGradient:function(e){e.fill&&e.fill.colorStops&&!(e.fill instanceof t.Gradient)&&this.set("fill",new t.Gradient(e.fill))},_initPattern:function(e){e.fill&&e.fill.source&&!(e.fill instanceof t.Pattern)&&this.set("fill",new t.Pattern(e.fill)),e.stroke&&e.stroke.source&&!(e.stroke instanceof t.Pattern)&&this.set("stroke",new t.Pattern(e.stroke))},_initClipping:function(e){if(!e.clipTo||typeof e.clipTo!="string")return;var n=t.util.getFunctionBody(e.clipTo);typeof n!="undefined"&&(this.clipTo=new Function("ctx",n))},setOptions:function(e){for(var t in e)this.set(t,e[t]);this._initGradient(e),this._initPattern(e),this._initClipping(e)},transform:function(e,t){this.group&&this.group.transform(e,t);var n=t?this._getLeftTopCoords():this.getCenterPoint();e.translate(n.x,n.y),e.rotate(s(this.angle)),e.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1))},toObject:function(e){var n=t.Object.NUM_FRACTION_DIGITS,i={type:this.type,originX:this.originX,originY:this.originY,left:r(this.left,n),top:r(this.top,n),width:r(this.width,n),height:r(this.height,n),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:r(this.strokeWidth,n),strokeDashArray:this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:r(this.strokeMiterLimit,n),scaleX:r(this.scaleX,n),scaleY:r(this.scaleY,n),angle:r(this.getAngle(),n),flipX:this.flipX,flipY:this.flipY,opacity:r(this.opacity,n),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor,fillRule:this.fillRule,globalCompositeOperation:this.globalCompositeOperation};return this.includeDefaultValues||(i=this._removeDefaultValues(i)),t.util.populateWithProperties(this,i,e),i},toDatalessObject:function(e){return this.toObject(e)},_removeDefaultValues:function(e){var n=t.util.getKlass(e.type).prototype,r=n.stateProperties;return r.forEach(function(t){e[t]===n[t]&&delete e[t]}),e},toString:function(){return"#<fabric."+i(this.type)+">"},get:function(e){return this[e]},_setObject:function(e){for(var t in e)this._set(t,e[t])},set:function(e,t){return typeof e=="object"?this._setObject(e):typeof t=="function"&&e!=="clipTo"?this._set(e,t(this.get(e))):this._set(e,t),this},_set:function(e,n){var i=e==="scaleX"||e==="scaleY";return i&&(n=this._constrainScale(n)),e==="scaleX"&&n<0?(this.flipX=!this.flipX,n*=-1):e==="scaleY"&&n<0?(this.flipY=!this.flipY,n*=-1):e==="width"||e==="height"?this.minScaleLimit=r(Math.min(.1,1/Math.max(this.width,this.height)),2):e==="shadow"&&n&&!(n instanceof t.Shadow)&&(n=new t.Shadow(n)),this[e]=n,this},toggle:function(e){var t=this.get(e);return typeof t=="boolean"&&this.set(e,!t),this},setSourcePath:function(e){return this.sourcePath=e,this},getViewportTransform:function(){return this.canvas&&this.canvas.viewportTransform?this.canvas.viewportTransform:[1,0,0,1,0,0]},render:function(e,n){if(this.width===0&&this.height===0||!this.visible)return;e.save(),this._setupCompositeOperation(e),n||this.transform(e),this._setStrokeStyles(e),this._setFillStyles(e),this.group&&this.group.type==="path-group"&&e.translate(-this.group.width/2,-this.group.height/2),this.transformMatrix&&e.transform.apply(e,this.transformMatrix),this._setOpacity(e),this._setShadow(e),this.clipTo&&t.util.clipContext(this,e),this._render(e,n),this.clipTo&&e.restore(),this._removeShadow(e),this._restoreCompositeOperation(e),e.restore()},_setOpacity:function(e){this.group&&this.group._setOpacity(e),e.globalAlpha*=this.opacity},_setStrokeStyles:function(e){this.stroke&&(e.lineWidth=this.strokeWidth,e.lineCap=this.strokeLineCap,e.lineJoin=this.strokeLineJoin,e.miterLimit=this.strokeMiterLimit,e.strokeStyle=this.stroke.toLive?this.stroke.toLive(e,this):this.stroke)},_setFillStyles:function(e){this.fill&&(e.fillStyle=this.fill.toLive?this.fill.toLive(e,this):this.fill)},_renderControls:function(e,n){var r=this.getViewportTransform();e.save();if(this.active&&!n){var i;this.group&&(i=t.util.transformPoint(this.group.getCenterPoint(),r),e.translate(i.x,i.y),e.rotate(s(this.group.angle))),i=t.util.transformPoint(this.getCenterPoint(),r,null!=this.group),this.group&&(i.x*=this.group.scaleX,i.y*=this.group.scaleY),e.translate(i.x,i.y),e.rotate(s(this.angle)),this.drawBorders(e),this.drawControls(e)}e.restore()},_setShadow:function(e){if(!this.shadow)return;var t=this.canvas&&this.canvas._currentMultiplier||1;e.shadowColor=this.shadow.color,e.shadowBlur=this.shadow.blur*t*(this.scaleX+this.scaleY)/2,e.shadowOffsetX=this.shadow.offsetX*t*this.scaleX,e.shadowOffsetY=this.shadow.offsetY*t*this.scaleY},_removeShadow:function(e){if(!this.shadow)return;e.shadowColor="",e.shadowBlur=e.shadowOffsetX=e.shadowOffsetY=0},_renderFill:function(e){if(!this.fill)return;e.save();if(this.fill.gradientTransform){var t=this.fill.gradientTransform;e.transform.apply(e,t)}this.fill.toLive&&e.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0),this.fillRule==="evenodd"?e.fill("evenodd"):e.fill(),e.restore(),this.shadow&&!this.shadow.affectStroke&&this._removeShadow(e)},_renderStroke:function(e){if(!this.stroke||this.strokeWidth===0)return;e.save();if(this.strokeDashArray)1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray),o?(e.setLineDash(this.strokeDashArray),this._stroke&&this._stroke(e)):this._renderDashedStroke&&this._renderDashedStroke(e),e.stroke();else{if(this.stroke.gradientTransform){var t=this.stroke.gradientTransform;e.transform.apply(e,t)}this._stroke?this._stroke(e):e.stroke()}this._removeShadow(e),e.restore()},clone:function(e,n){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(n),e):new t.Object(this.toObject(n))},cloneAsImage:function(e){var n=this.toDataURL();return t.util.loadImage(n,function(n){e&&e(new t.Image(n))}),this},toDataURL:function(e){e||(e={});var n=t.util.createCanvasElement(),r=this.getBoundingRect();n.width=r.width,n.height=r.height,t.util.wrapElement(n,"div");var i=new t.Canvas(n);e.format==="jpg"&&(e.format="jpeg"),e.format==="jpeg"&&(i.backgroundColor="#fff");var s={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",!1),this.setPositionByOrigin(new t.Point(n.width/2,n.height/2),"center","center");var o=this.canvas;i.add(this);var u=i.toDataURL(e);return this.set(s).setCoords(),this.canvas=o,i.dispose(),i=null,u},isType:function(e){return this.type===e},complexity:function(){return 0},toJSON:function(e){return this.toObject(e)},setGradient:function(e,n){n||(n={});var r={colorStops:[]};r.type=n.type||(n.r1||n.r2?"radial":"linear"),r.coords={x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2};if(n.r1||n.r2)r.coords.r1=n.r1,r.coords.r2=n.r2;for(var i in n.colorStops){var s=new t.Color(n.colorStops[i]);r.colorStops.push({offset:i,color:s.toRgb(),opacity:s.getAlpha()})}return this.set(e,t.Gradient.forObject(this,r))},setPatternFill:function(e){return this.set("fill",new t.Pattern(e))},setShadow:function(e){return this.set("shadow",e?new t.Shadow(e):null)},setColor:function(e){return this.set("fill",e),this},setAngle:function(e){var t=(this.originX!=="center"||this.originY!=="center")&&this.centeredRotation;return t&&this._setOriginToCenter(),this.set("angle",e),t&&this._resetOrigin(),this},centerH:function(){return this.canvas.centerObjectH(this),this},centerV:function(){return this.canvas.centerObjectV(this),this},center:function(){return this.canvas.centerObject(this),this},remove:function(){return this.canvas.remove(this),this},getLocalPointer:function(e,t){t=t||this.canvas.getPointer(e);var n=this.translateToOriginPoint(this.getCenterPoint(),"left","top");return{x:t.x-n.x,y:t.y-n.y}},_setupCompositeOperation:function(e){this.globalCompositeOperation&&(this._prevGlobalCompositeOperation=e.globalCompositeOperation,e.globalCompositeOperation=this.globalCompositeOperation)},_restoreCompositeOperation:function(e){this.globalCompositeOperation&&this._prevGlobalCompositeOperation&&(e.globalCompositeOperation=this._prevGlobalCompositeOperation)}}),t.util.createAccessors(t.Object),t.Object.prototype.rotate=t.Object.prototype.setAngle,n(t.Object.prototype,t.Observable),t.Object.NUM_FRACTION_DIGITS=2,t.Object.__uid=0}(typeof exports!="undefined"?exports:this),function(){var e=fabric.util.degreesToRadians;fabric.util.object.extend(fabric.Object.prototype,{translateToCenterPoint:function(t,n,r){var i=t.x,s=t.y,o=this.stroke?this.strokeWidth:0;return n==="left"?i=t.x+(this.getWidth()+o*this.scaleX)/2:n==="right"&&(i=t.x-(this.getWidth()+o*this.scaleX)/2),r==="top"?s=t.y+(this.getHeight()+o*this.scaleY)/2:r==="bottom"&&(s=t.y-(this.getHeight()+o*this.scaleY)/2),fabric.util.rotatePoint(new fabric.Point(i,s),t,e(this.angle))},translateToOriginPoint:function(t,n,r){var i=t.x,s=t.y,o=this.stroke?this.strokeWidth:0;return n==="left"?i=t.x-(this.getWidth()+o*this.scaleX)/2:n==="right"&&(i=t.x+(this.getWidth()+o*this.scaleX)/2),r==="top"?s=t.y-(this.getHeight()+o*this.scaleY)/2:r==="bottom"&&(s=t.y+(this.getHeight()+o*this.scaleY)/2),fabric.util.rotatePoint(new fabric.Point(i,s),t,e(this.angle))},getCenterPoint:function(){var e=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(e,this.originX,this.originY)},getPointByOrigin:function(e,t){var n=this.getCenterPoint();return this.translateToOriginPoint(n,e,t)},toLocalPoint:function(t,n,r){var i=this.getCenterPoint(),s=this.stroke?this.strokeWidth:0,o,u;return n&&r?(n==="left"?o=i.x-(this.getWidth()+s*this.scaleX)/2:n==="right"?o=i.x+(this.getWidth()+s*this.scaleX)/2:o=i.x,r==="top"?u=i.y-(this.getHeight()+s*this.scaleY)/2:r==="bottom"?u=i.y+(this.getHeight()+s*this.scaleY)/2:u=i.y):(o=this.left,u=this.top),fabric.util.rotatePoint(new fabric.Point(t.x,t.y),i,-e(this.angle)).subtractEquals(new fabric.Point(o,u))},setPositionByOrigin:function(e,t,n){var r=this.translateToCenterPoint(e,t,n),i=this.translateToOriginPoint(r,this.originX,this.originY);this.set("left",i.x),this.set("top",i.y)},adjustPosition:function(t){var n=e(this.angle),r=this.getWidth()/2,i=Math.cos(n)*r,s=Math.sin(n)*r,o=this.getWidth(),u=Math.cos(n)*o,a=Math.sin(n)*o;this.originX==="center"&&t==="left"||this.originX==="right"&&t==="center"?(this.left-=i,this.top-=s):this.originX==="left"&&t==="center"||this.originX==="center"&&t==="right"?(this.left+=i,this.top+=s):this.originX==="left"&&t==="right"?(this.left+=u,this.top+=a):this.originX==="right"&&t==="left"&&(this.left-=u,this.top-=a),this.setCoords(),this.originX=t},_setOriginToCenter:function(){this._originalOriginX=this.originX,this._originalOriginY=this.originY;var e=this.getCenterPoint();this.originX="center",this.originY="center",this.left=e.x,this.top=e.y},_resetOrigin:function(){var e=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX,this.originY=this._originalOriginY,this.left=e.x,this.top=e.y,this._originalOriginX=null,this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","center")}})}(),function(){var e=fabric.util.degreesToRadians;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(e,t){var n=this.oCoords,r=new fabric.Point(n.tl.x,n.tl.y),i=new fabric.Point(n.tr.x,n.tr.y),s=new fabric.Point(n.bl.x,n.bl.y),o=new fabric.Point(n.br.x,n.br.y),u=fabric.Intersection.intersectPolygonRectangle([r,i,o,s],e,t);return u.status==="Intersection"},intersectsWithObject:function(e){function t(e){return{tl:new fabric.Point(e.tl.x,e.tl.y),tr:new fabric.Point(e.tr.x,e.tr.y),bl:new fabric.Point(e.bl.x,e.bl.y),br:new fabric.Point(e.br.x,e.br.y)}}var n=t(this.oCoords),r=t(e.oCoords),i=fabric.Intersection.intersectPolygonPolygon([n.tl,n.tr,n.br,n.bl],[r.tl,r.tr,r.br,r.bl]);return i.status==="Intersection"},isContainedWithinObject:function(e){var t=e.getBoundingRect(),n=new fabric.Point(t.left,t.top),r=new fabric.Point(t.left+t.width,t.top+t.height);return this.isContainedWithinRect(n,r)},isContainedWithinRect:function(e,t){var n=this.getBoundingRect();return n.left>=e.x&&n.left+n.width<=t.x&&n.top>=e.y&&n.top+n.height<=t.y},containsPoint:function(e){var t=this._getImageLines(this.oCoords),n=this._findCrossPoints(e,t);return n!==0&&n%2===1},_getImageLines:function(e){return{topline:{o:e.tl,d:e.tr},rightline:{o:e.tr,d:e.br},bottomline:{o:e.br,d:e.bl},leftline:{o:e.bl,d:e.tl}}},_findCrossPoints:function(e,t){var n,r,i,s,o,u,a=0,f;for(var l in t){f=t[l];if(f.o.y<e.y&&f.d.y<e.y)continue;if(f.o.y>=e.y&&f.d.y>=e.y)continue;f.o.x===f.d.x&&f.o.x>=e.x?(o=f.o.x,u=e.y):(n=0,r=(f.d.y-f.o.y)/(f.d.x-f.o.x),i=e.y-n*e.x,s=f.o.y-r*f.o.x,o=-(i-s)/(n-r),u=i+n*o),o>=e.x&&(a+=1);if(a===2)break}return a},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){this.oCoords||this.setCoords();var e=[this.oCoords.tl.x,this.oCoords.tr.x,this.oCoords.br.x,this.oCoords.bl.x],t=fabric.util.array.min(e),n=fabric.util.array.max(e),r=Math.abs(t-n),i=[this.oCoords.tl.y,this.oCoords.tr.y,this.oCoords.br.y,this.oCoords.bl.y],s=fabric.util.array.min(i),o=fabric.util.array.max(i),u=Math.abs(s-o);return{left:t,top:s,width:r,height:u}},getWidth:function(){return this.width*this.scaleX},getHeight:function(){return this.height*this.scaleY},_constrainScale:function(e){return Math.abs(e)<this.minScaleLimit?e<0?-this.minScaleLimit:this.minScaleLimit:e},scale:function(e){return e=this._constrainScale(e),e<0&&(this.flipX=!this.flipX,this.flipY=!this.flipY,e*=-1),this.scaleX=e,this.scaleY=e,this.setCoords(),this},scaleToWidth:function(e){var t=this.getBoundingRectWidth()/this.getWidth();return this.scale(e/this.width/t)},scaleToHeight:function(e){var t=this.getBoundingRectHeight()/this.getHeight();return this.scale(e/this.height/t)},setCoords:function(){var t=this.strokeWidth,n=e(this.angle),r=this.getViewportTransform(),i=function(e){return fabric.util.transformPoint(e,r)},s=this.width,o,u=this.height,a,f=this.strokeLineCap==="round"||this.strokeLineCap==="square",l=this.type==="line"&&this.width===0,c=this.type==="line"&&this.height===0,h=l||c,p=f&&c||!h,d=f&&l||!h;l?s=t:c&&(u=t),p&&(s+=s>0?t:-t),d&&(u+=u>0?t:-t),o=s*this.scaleX+2*this.padding,a=u*this.scaleY+2*this.padding,o<0&&(o=Math.abs(o));var v=Math.sqrt(Math.pow(o/2,2)+Math.pow(a/2,2)),m=Math.atan(isFinite(a/o)?a/o:0),g=Math.cos(m+n)*v,y=Math.sin(m+n)*v,b=Math.sin(n),w=Math.cos(n),E=this.getCenterPoint(),S=new fabric.Point(o,a),x=new fabric.Point(E.x-g,E.y-y),T=new fabric.Point(x.x+S.x*w,x.y+S.x*b),N=new fabric.Point(x.x-S.y*b,x.y+S.y*w),C=new fabric.Point(x.x+S.x/2*w,x.y+S.x/2*b),k=i(x),L=i(T),A=i(new fabric.Point(T.x-S.y*b,T.y+S.y*w)),O=i(N),M=i(new fabric.Point(x.x-S.y/2*b,x.y+S.y/2*w)),_=i(C),D=i(new fabric.Point(T.x-S.y/2*b,T.y+S.y/2*w)),P=i(new fabric.Point(N.x+S.x/2*w,N.y+S.x/2*b)),H=i(new fabric.Point(C.x,C.y));return this.oCoords={tl:k,tr:L,br:A,bl:O,ml:M,mt:_,mr:D,mb:P,mtr:H},this._setCornerCoords&&this._setCornerCoords(),this}})}(),fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){return this.group?fabric.StaticCanvas.prototype.sendToBack.call(this.group,this):this.canvas.sendToBack(this),this},bringToFront:function(){return this.group?fabric.StaticCanvas.prototype.bringToFront.call(this.group,this):this.canvas.bringToFront(this),this},sendBackwards:function(e){return this.group?fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,e):this.canvas.sendBackwards(this,e),this},bringForward:function(e){return this.group?fabric.StaticCanvas.prototype.bringForward.call(this.group,this,e):this.canvas.bringForward(this,e),this},moveTo:function(e){return this.group?fabric.StaticCanvas.prototype.moveTo.call(this.group,this,e):this.canvas.moveTo(this,e),this}}),fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(){var e=this.fill?this.fill.toLive?"url(#SVGID_"+this.fill.id+")":this.fill:"none",t=this.fillRule,n=this.stroke?this.stroke.toLive?"url(#SVGID_"+this.stroke.id+")":this.stroke:"none",r=this.strokeWidth?this.strokeWidth:"0",i=this.strokeDashArray?this.strokeDashArray.join(" "):"",s=this.strokeLineCap?this.strokeLineCap:"butt",o=this.strokeLineJoin?this.strokeLineJoin:"miter",u=this.strokeMiterLimit?this.strokeMiterLimit:"4",a=typeof this.opacity!="undefined"?this.opacity:"1",f=this.visible?"":" visibility: hidden;",l=this.shadow&&this.type!=="text"?"filter: url(#SVGID_"+this.shadow.id+");":"";return["stroke: ",n,"; ","stroke-width: ",r,"; ","stroke-dasharray: ",i,"; ","stroke-linecap: ",s,"; ","stroke-linejoin: ",o,"; ","stroke-miterlimit: ",u,"; ","fill: ",e,"; ","fill-rule: ",t,"; ","opacity: ",a,";",l,f].join("")},getSvgTransform:function(){if(this.group&&this.group.type==="path-group")return"";var e=fabric.util.toFixed,t=this.getAngle(),n=!this.canvas||this.canvas.svgViewportTransformation?this.getViewportTransform():[1,0,0,1,0,0],r=fabric.util.transformPoint(this.getCenterPoint(),n),i=fabric.Object.NUM_FRACTION_DIGITS,s=this.type==="path-group"?"":"translate("+e(r.x,i)+" "+e(r.y,i)+")",o=t!==0?" rotate("+e(t,i)+")":"",u=this.scaleX===1&&this.scaleY===1&&n[0]===1&&n[3]===1?"":" scale("+e(this.scaleX*n[0],i)+" "+e(this.scaleY*n[3],i)+")",a=this.type==="path-group"?this.width*n[0]:0,f=this.flipX?" matrix(-1 0 0 1 "+a+" 0) ":"",l=this.type==="path-group"?this.height*n[3]:0,c=this.flipY?" matrix(1 0 0 -1 0 "+l+")":"";return[s,o,u,f,c].join("")},getSvgTransformMatrix:function(){return this.transformMatrix?" matrix("+this.transformMatrix.join(" ")+")":""},_createBaseSVGMarkup:function(){var e=[];return this.fill&&this.fill.toLive&&e.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!1)),this.shadow&&e.push(this.shadow.toSVG(this)),e}}),fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(e){return this.get(e)!==this.originalState[e]},this)},saveState:function(e){return this.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),e&&e.stateProperties&&e.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),this},setupState:function(){return this.originalState={},this.saveState(),this}}),function(){var e=fabric.util.degreesToRadians,t=function(){return typeof G_vmlCanvasManager!="undefined"};fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(e){if(!this.hasControls||!this.active)return!1;var t=e.x,n=e.y,r,i;for(var s in this.oCoords){if(!this.isControlVisible(s))continue;if(s==="mtr"&&!this.hasRotatingPoint)continue;if(!(!this.get("lockUniScaling")||s!=="mt"&&s!=="mr"&&s!=="mb"&&s!=="ml"))continue;i=this._getImageLines(this.oCoords[s].corner),r=this._findCrossPoints({x:t,y:n},i);if(r!==0&&r%2===1)return this.__corner=s,s}return!1},_setCornerCoords:function(){var t=this.oCoords,n=e(this.angle),r=e(45-this.angle),i=Math.sqrt(2*Math.pow(this.cornerSize,2))/2,s=i*Math.cos(r),o=i*Math.sin(r),u=Math.sin(n),a=Math.cos(n);t.tl.corner={tl:{x:t.tl.x-o,y:t.tl.y-s},tr:{x:t.tl.x+s,y:t.tl.y-o},bl:{x:t.tl.x-s,y:t.tl.y+o},br:{x:t.tl.x+o,y:t.tl.y+s}},t.tr.corner={tl:{x:t.tr.x-o,y:t.tr.y-s},tr:{x:t.tr.x+s,y:t.tr.y-o},br:{x:t.tr.x+o,y:t.tr.y+s},bl:{x:t.tr.x-s,y:t.tr.y+o}},t.bl.corner={tl:{x:t.bl.x-o,y:t.bl.y-s},bl:{x:t.bl.x-s,y:t.bl.y+o},br:{x:t.bl.x+o,y:t.bl.y+s},tr:{x:t.bl.x+s,y:t.bl.y-o}},t.br.corner={tr:{x:t.br.x+s,y:t.br.y-o},bl:{x:t.br.x-s,y:t.br.y+o},br:{x:t.br.x+o,y:t.br.y+s},tl:{x:t.br.x-o,y:t.br.y-s}},t.ml.corner={tl:{x:t.ml.x-o,y:t.ml.y-s},tr:{x:t.ml.x+s,y:t.ml.y-o},bl:{x:t.ml.x-s,y:t.ml.y+o},br:{x:t.ml.x+o,y:t.ml.y+s}},t.mt.corner={tl:{x:t.mt.x-o,y:t.mt.y-s},tr:{x:t.mt.x+s,y:t.mt.y-o},bl:{x:t.mt.x-s,y:t.mt.y+o},br:{x:t.mt.x+o,y:t.mt.y+s}},t.mr.corner={tl:{x:t.mr.x-o,y:t.mr.y-s},tr:{x:t.mr.x+s,y:t.mr.y-o},bl:{x:t.mr.x-s,y:t.mr.y+o},br:{x:t.mr.x+o,y:t.mr.y+s}},t.mb.corner={tl:{x:t.mb.x-o,y:t.mb.y-s},tr:{x:t.mb.x+s,y:t.mb.y-o},bl:{x:t.mb.x-s,y:t.mb.y+o},br:{x:t.mb.x+o,y:t.mb.y+s}},t.mtr.corner={tl:{x:t.mtr.x-o+u*this.rotatingPointOffset,y:t.mtr.y-s-a*this.rotatingPointOffset},tr:{x:t.mtr.x+s+u*this.rotatingPointOffset,y:t.mtr.y-o-a*this.rotatingPointOffset},bl:{x:t.mtr.x-s+u*this.rotatingPointOffset,y:t.mtr.y+o-a*this.rotatingPointOffset},br:{x:t.mtr.x+o+u*this.rotatingPointOffset,y:t.mtr.y+s-a*this.rotatingPointOffset}}},drawBorders:function(e){if(!this.hasBorders)return this;var t=this.padding,n=t*2,r=this.getViewportTransform();e.save(),e.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,e.strokeStyle=this.borderColor;var i=1/this._constrainScale(this.scaleX),s=1/this._constrainScale(this.scaleY);e.lineWidth=1/this.borderScaleFactor;var o=this.getWidth(),u=this.getHeight(),a=this.strokeWidth,f=this.strokeLineCap==="round"||this.strokeLineCap==="square",l=this.type==="line"&&this.width===0,c=this.type==="line"&&this.height===0,h=l||c,p=f&&c||!h,d=f&&l||!h;l?o=a/i:c&&(u=a/s),p&&(o+=a/i),d&&(u+=a/s);var v=fabric.util.transformPoint(new fabric.Point(o,u),r,!0),m=v.x,g=v.y;this.group&&(m*=this.group.scaleX,g*=this.group.scaleY),e.strokeRect(~~(-(m/2)-t)-.5,~~(-(g/2)-t)-.5,~~(m+n)+1,~~(g+n)+1);if(this.hasRotatingPoint&&this.isControlVisible("mtr")&&!this.get("lockRotation")&&this.hasControls){var y=(-g-t*2)/2;e.beginPath(),e.moveTo(0,y),e.lineTo(0,y-this.rotatingPointOffset),e.closePath(),e.stroke()}return e.restore(),this},drawControls:function(e){if(!this.hasControls)return this;var t=this.cornerSize,n=t/2,r=this.getViewportTransform(),i=this.strokeWidth,s=this.width,o=this.height,u=this.strokeLineCap==="round"||this.strokeLineCap==="square",a=this.type==="line"&&this.width===0,f=this.type==="line"&&this.height===0,l=a||f,c=u&&f||!l,h=u&&a||!l;a?s=i:f&&(o=i),c&&(s+=i),h&&(o+=i),s*=this.scaleX,o*=this.scaleY;var p=fabric.util.transformPoint(new fabric.Point(s,o),r,!0),d=p.x,v=p.y,m=-(d/2),g=-(v/2),y=this.padding,b=n,w=n-t,E=this.transparentCorners?"strokeRect":"fillRect";return e.save(),e.lineWidth=1,e.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,e.strokeStyle=e.fillStyle=this.cornerColor,this._drawControl("tl",e,E,m-b-y,g-b-y),this._drawControl("tr",e,E,m+d-b+y,g-b-y),this._drawControl("bl",e,E,m-b-y,g+v+w+y),this._drawControl("br",e,E,m+d+w+y,g+v+w+y),this.get("lockUniScaling")||(this._drawControl("mt",e,E,m+d/2-b,g-b-y),this._drawControl("mb",e,E,m+d/2-b,g+v+w+y),this._drawControl("mr",e,E,m+d+w+y,g+v/2-b),this._drawControl("ml",e,E,m-b-y,g+v/2-b)),this.hasRotatingPoint&&this._drawControl("mtr",e,E,m+d/2-b,g-this.rotatingPointOffset-this.cornerSize/2-y),e.restore(),this},_drawControl:function(e,n,r,i,s){var o=this.cornerSize;this.isControlVisible(e)&&(t()||this.transparentCorners||n.clearRect(i,s,o,o),n[r](i,s,o,o))},isControlVisible:function(e){return this._getControlsVisibility()[e]},setControlVisible:function(e,t){return this._getControlsVisibility()[e]=t,this},setControlsVisibility:function(e){e||(e={});for(var t in e)this.setControlVisible(t,e[t]);return this},_getControlsVisibility:function(){return this._controlsVisibility||(this._controlsVisibility={tl:!0,tr:!0,br:!0,bl:!0,ml:!0,mt:!0,mr:!0,mb:!0,mtr:!0}),this._controlsVisibility}})}(),fabric.util.object.extend(fabric.StaticCanvas.prototype,{FX_DURATION:500,fxCenterObjectH:function(e,t){t=t||{};var n=function(){},r=t.onComplete||n,i=t.onChange||n,s=this;return fabric.util.animate({startValue:e.get("left"),endValue:this.getCenter().left,duration:this.FX_DURATION,onChange:function(t){e.set("left",t),s.renderAll(),i()},onComplete:function(){e.setCoords(),r()}}),this},fxCenterObjectV:function(e,t){t=t||{};var n=function(){},r=t.onComplete||n,i=t.onChange||n,s=this;return fabric.util.animate({startValue:e.get("top"),endValue:this.getCenter().top,duration:this.FX_DURATION,onChange:function(t){e.set("top",t),s.renderAll(),i()},onComplete:function(){e.setCoords(),r()}}),this},fxRemove:function(e,t){t=t||{};var n=function(){},r=t.onComplete||n,i=t.onChange||n,s=this;return fabric.util.animate({startValue:e.get("opacity"),endValue:0,duration:this.FX_DURATION,onStart:function(){e.set("active",!1)},onChange:function(t){e.set("opacity",t),s.renderAll(),i()},onComplete:function(){s.remove(e),r()}}),this}}),fabric.util.object.extend(fabric.Object.prototype,{animate:function(){if(arguments[0]&&typeof arguments[0]=="object"){var e=[],t,n;for(t in arguments[0])e.push(t);for(var r=0,i=e.length;r<i;r++)t=e[r],n=r!==i-1,this._animate(t,arguments[0][t],arguments[1],n)}else this._animate.apply(this,arguments);return this},_animate:function(e,t,n,r){var i=this,s;t=t.toString(),n?n=fabric.util.object.clone(n):n={},~e.indexOf(".")&&(s=e.split("."));var o=s?this.get(s[0])[s[1]]:this.get(e);"from"in n||(n.from=o),~t.indexOf("=")?t=o+parseFloat(t.replace("=","")):t=parseFloat(t),fabric.util.animate({startValue:n.from,endValue:t,byValue:n.by,easing:n.easing,duration:n.duration,abort:n.abort&&function(){return n.abort.call(i)},onChange:function(t){s?i[s[0]][s[1]]=t:i.set(e,t);if(r)return;n.onChange&&n.onChange()},onComplete:function(){if(r)return;i.setCoords(),n.onComplete&&n.onComplete()}})}}),function(e){"use strict";function s(e,t){var n=e.origin,r=e.axis1,i=e.axis2,s=e.dimension,o=t.nearest,u=t.center,a=t.farthest;return function(){switch(this.get(n)){case o:return Math.min(this.get(r),this.get(i));case u:return Math.min(this.get(r),this.get(i))+.5*this.get(s);case a:return Math.max(this.get(r),this.get(i))}}}var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r={x1:1,x2:1,y1:1,y2:1},i=t.StaticCanvas.supports("setLineDash");if(t.Line){t.warn("fabric.Line is already defined");return}t.Line=t.util.createClass(t.Object,{type:"line",x1:0,y1:0,x2:0,y2:0,initialize:function(e,t){t=t||{},e||(e=[0,0,0,0]),this.callSuper("initialize",t),this.set("x1",e[0]),this.set("y1",e[1]),this.set("x2",e[2]),this.set("y2",e[3]),this._setWidthHeight(t)},_setWidthHeight:function(e){e||(e={}),this.width=Math.abs(this.x2-this.x1),this.height=Math.abs(this.y2-this.y1),this.left="left"in e?e.left:this._getLeftToOriginX(),this.top="top"in e?e.top:this._getTopToOriginY()},_set:function(e,t){return this.callSuper("_set",e,t),typeof r[e]!="undefined"&&this._setWidthHeight(),this},_getLeftToOriginX:s({origin:"originX",axis1:"x1",axis2:"x2",dimension:"width"},{nearest:"left",center:"center",farthest:"right"}),_getTopToOriginY:s({origin:"originY",axis1:"y1",axis2:"y2",dimension:"height"},{nearest:"top",center:"center",farthest +:"bottom"}),_render:function(e,t){e.beginPath();if(t){var n=this.getCenterPoint();e.translate(n.x-this.strokeWidth/2,n.y-this.strokeWidth/2)}if(!this.strokeDashArray||this.strokeDashArray&&i){var r=this.calcLinePoints();e.moveTo(r.x1,r.y1),e.lineTo(r.x2,r.y2)}e.lineWidth=this.strokeWidth;var s=e.strokeStyle;e.strokeStyle=this.stroke||e.fillStyle,this.stroke&&this._renderStroke(e),e.strokeStyle=s},_renderDashedStroke:function(e){var n=this.calcLinePoints();e.beginPath(),t.util.drawDashedLine(e,n.x1,n.y1,n.x2,n.y2,this.strokeDashArray),e.closePath()},toObject:function(e){return n(this.callSuper("toObject",e),this.calcLinePoints())},calcLinePoints:function(){var e=this.x1<=this.x2?-1:1,t=this.y1<=this.y2?-1:1,n=e*this.width*.5,r=t*this.height*.5,i=e*this.width*-0.5,s=t*this.height*-0.5;return{x1:n,x2:i,y1:r,y2:s}},toSVG:function(e){var t=this._createBaseSVGMarkup(),n={x1:this.x1,x2:this.x2,y1:this.y1,y2:this.y2};if(!this.group||this.group.type!=="path-group")n=this.calcLinePoints();return t.push("<line ",'x1="',n.x1,'" y1="',n.y1,'" x2="',n.x2,'" y2="',n.y2,'" style="',this.getSvgStyles(),'" transform="',this.getSvgTransform(),this.getSvgTransformMatrix(),'"/>\n'),e?e(t.join("")):t.join("")},complexity:function(){return 1}}),t.Line.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),t.Line.fromElement=function(e,r){var i=t.parseAttributes(e,t.Line.ATTRIBUTE_NAMES),s=[i.x1||0,i.y1||0,i.x2||0,i.y2||0];return new t.Line(s,n(i,r))},t.Line.fromObject=function(e){var n=[e.x1,e.y1,e.x2,e.y2];return new t.Line(n,e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function i(e){return"radius"in e&&e.radius>0}var t=e.fabric||(e.fabric={}),n=Math.PI,r=t.util.object.extend;if(t.Circle){t.warn("fabric.Circle is already defined.");return}t.Circle=t.util.createClass(t.Object,{type:"circle",radius:0,startAngle:0,endAngle:n*2,initialize:function(e){e=e||{},this.callSuper("initialize",e),this.set("radius",e.radius||0),this.startAngle=e.startAngle||this.startAngle,this.endAngle=e.endAngle||this.endAngle},_set:function(e,t){return this.callSuper("_set",e,t),e==="radius"&&this.setRadius(t),this},toObject:function(e){return r(this.callSuper("toObject",e),{radius:this.get("radius"),startAngle:this.startAngle,endAngle:this.endAngle})},toSVG:function(e){var t=this._createBaseSVGMarkup(),r=0,i=0,s=(this.endAngle-this.startAngle)%(2*n);if(s===0)this.group&&this.group.type==="path-group"&&(r=this.left+this.radius,i=this.top+this.radius),t.push("<circle ",'cx="'+r+'" cy="'+i+'" ','r="',this.radius,'" style="',this.getSvgStyles(),'" transform="',this.getSvgTransform()," ",this.getSvgTransformMatrix(),'"/>\n');else{var o=Math.cos(this.startAngle)*this.radius,u=Math.sin(this.startAngle)*this.radius,a=Math.cos(this.endAngle)*this.radius,f=Math.sin(this.endAngle)*this.radius,l=s>n?"1":"0";t.push('<path d="M '+o+" "+u," A "+this.radius+" "+this.radius," 0 ",+l+" 1"," "+a+" "+f,'" style="',this.getSvgStyles(),'" transform="',this.getSvgTransform()," ",this.getSvgTransformMatrix(),'"/>\n')}return e?e(t.join("")):t.join("")},_render:function(e,t){e.beginPath(),e.arc(t?this.left+this.radius:0,t?this.top+this.radius:0,this.radius,this.startAngle,this.endAngle,!1),this._renderFill(e),this._renderStroke(e)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(e){this.radius=e,this.set("width",e*2).set("height",e*2)},complexity:function(){return 1}}),t.Circle.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),t.Circle.fromElement=function(e,n){n||(n={});var s=t.parseAttributes(e,t.Circle.ATTRIBUTE_NAMES);if(!i(s))throw new Error("value of `r` attribute is required and can not be negative");s.left=s.left||0,s.top=s.top||0;var o=new t.Circle(r(s,n));return o.left-=o.radius,o.top-=o.radius,o},t.Circle.fromObject=function(e){return new t.Circle(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={});if(t.Triangle){t.warn("fabric.Triangle is already defined");return}t.Triangle=t.util.createClass(t.Object,{type:"triangle",initialize:function(e){e=e||{},this.callSuper("initialize",e),this.set("width",e.width||100).set("height",e.height||100)},_render:function(e){var t=this.width/2,n=this.height/2;e.beginPath(),e.moveTo(-t,n),e.lineTo(0,-n),e.lineTo(t,n),e.closePath(),this._renderFill(e),this._renderStroke(e)},_renderDashedStroke:function(e){var n=this.width/2,r=this.height/2;e.beginPath(),t.util.drawDashedLine(e,-n,r,0,-r,this.strokeDashArray),t.util.drawDashedLine(e,0,-r,n,r,this.strokeDashArray),t.util.drawDashedLine(e,n,r,-n,r,this.strokeDashArray),e.closePath()},toSVG:function(e){var t=this._createBaseSVGMarkup(),n=this.width/2,r=this.height/2,i=[-n+" "+r,"0 "+ -r,n+" "+r].join(",");return t.push("<polygon ",'points="',i,'" style="',this.getSvgStyles(),'" transform="',this.getSvgTransform(),'"/>'),e?e(t.join("")):t.join("")},complexity:function(){return 1}}),t.Triangle.fromObject=function(e){return new t.Triangle(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=Math.PI*2,r=t.util.object.extend;if(t.Ellipse){t.warn("fabric.Ellipse is already defined.");return}t.Ellipse=t.util.createClass(t.Object,{type:"ellipse",rx:0,ry:0,initialize:function(e){e=e||{},this.callSuper("initialize",e),this.set("rx",e.rx||0),this.set("ry",e.ry||0)},_set:function(e,t){this.callSuper("_set",e,t);switch(e){case"rx":this.rx=t,this.set("width",t*2);break;case"ry":this.ry=t,this.set("height",t*2)}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(e){return r(this.callSuper("toObject",e),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(e){var t=this._createBaseSVGMarkup(),n=0,r=0;return this.group&&this.group.type==="path-group"&&(n=this.left+this.rx,r=this.top+this.ry),t.push("<ellipse ",'cx="',n,'" cy="',r,'" ','rx="',this.rx,'" ry="',this.ry,'" style="',this.getSvgStyles(),'" transform="',this.getSvgTransform(),this.getSvgTransformMatrix(),'"/>\n'),e?e(t.join("")):t.join("")},_render:function(e,t){e.beginPath(),e.save(),e.transform(1,0,0,this.ry/this.rx,0,0),e.arc(t?this.left+this.rx:0,t?(this.top+this.ry)*this.rx/this.ry:0,this.rx,0,n,!1),e.restore(),this._renderFill(e),this._renderStroke(e)},complexity:function(){return 1}}),t.Ellipse.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),t.Ellipse.fromElement=function(e,n){n||(n={});var i=t.parseAttributes(e,t.Ellipse.ATTRIBUTE_NAMES);i.left=i.left||0,i.top=i.top||0;var s=new t.Ellipse(r(i,n));return s.top-=s.ry,s.left-=s.rx,s},t.Ellipse.fromObject=function(e){return new t.Ellipse(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;if(t.Rect){console.warn("fabric.Rect is already defined");return}var r=t.Object.prototype.stateProperties.concat();r.push("rx","ry","x","y"),t.Rect=t.util.createClass(t.Object,{stateProperties:r,type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(e){e=e||{},this.callSuper("initialize",e),this._initRxRy()},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(e,t){if(this.width===1&&this.height===1){e.fillRect(0,0,1,1);return}var n=this.rx?Math.min(this.rx,this.width/2):0,r=this.ry?Math.min(this.ry,this.height/2):0,i=this.width,s=this.height,o=t?this.left:-this.width/2,u=t?this.top:-this.height/2,a=n!==0||r!==0,f=.4477152502;e.beginPath(),e.moveTo(o+n,u),e.lineTo(o+i-n,u),a&&e.bezierCurveTo(o+i-f*n,u,o+i,u+f*r,o+i,u+r),e.lineTo(o+i,u+s-r),a&&e.bezierCurveTo(o+i,u+s-f*r,o+i-f*n,u+s,o+i-n,u+s),e.lineTo(o+n,u+s),a&&e.bezierCurveTo(o+f*n,u+s,o,u+s-f*r,o,u+s-r),e.lineTo(o,u+r),a&&e.bezierCurveTo(o,u+f*r,o+f*n,u,o+n,u),e.closePath(),this._renderFill(e),this._renderStroke(e)},_renderDashedStroke:function(e){var n=-this.width/2,r=-this.height/2,i=this.width,s=this.height;e.beginPath(),t.util.drawDashedLine(e,n,r,n+i,r,this.strokeDashArray),t.util.drawDashedLine(e,n+i,r,n+i,r+s,this.strokeDashArray),t.util.drawDashedLine(e,n+i,r+s,n,r+s,this.strokeDashArray),t.util.drawDashedLine(e,n,r+s,n,r,this.strokeDashArray),e.closePath()},toObject:function(e){var t=n(this.callSuper("toObject",e),{rx:this.get("rx")||0,ry:this.get("ry")||0});return this.includeDefaultValues||this._removeDefaultValues(t),t},toSVG:function(e){var t=this._createBaseSVGMarkup(),n=this.left,r=this.top;if(!this.group||this.group.type!=="path-group")n=-this.width/2,r=-this.height/2;return t.push("<rect ",'x="',n,'" y="',r,'" rx="',this.get("rx"),'" ry="',this.get("ry"),'" width="',this.width,'" height="',this.height,'" style="',this.getSvgStyles(),'" transform="',this.getSvgTransform(),this.getSvgTransformMatrix(),'"/>\n'),e?e(t.join("")):t.join("")},complexity:function(){return 1}}),t.Rect.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),t.Rect.fromElement=function(e,r){if(!e)return null;r=r||{};var i=t.parseAttributes(e,t.Rect.ATTRIBUTE_NAMES);return i.left=i.left||0,i.top=i.top||0,new t.Rect(n(r?t.util.object.clone(r):{},i))},t.Rect.fromObject=function(e){return new t.Rect(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={});if(t.Polyline){t.warn("fabric.Polyline is already defined");return}t.Polyline=t.util.createClass(t.Object,{type:"polyline",points:null,minX:0,minY:0,initialize:function(e,n){return t.Polygon.prototype.initialize.call(this,e,n)},_calcDimensions:function(){return t.Polygon.prototype._calcDimensions.call(this)},_applyPointOffset:function(){return t.Polygon.prototype._applyPointOffset.call(this)},toObject:function(e){return t.Polygon.prototype.toObject.call(this,e)},toSVG:function(e){return t.Polygon.prototype.toSVG.call(this,e)},_render:function(e){t.Polygon.prototype.commonRender.call(this,e),this._renderFill(e),this._renderStroke(e)},_renderDashedStroke:function(e){var n,r;e.beginPath();for(var i=0,s=this.points.length;i<s;i++)n=this.points[i],r=this.points[i+1]||n,t.util.drawDashedLine(e,n.x,n.y,r.x,r.y,this.strokeDashArray)},complexity:function(){return this.get("points").length}}),t.Polyline.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat(),t.Polyline.fromElement=function(e,n){if(!e)return null;n||(n={});var r=t.parsePointsAttribute(e.getAttribute("points")),i=t.parseAttributes(e,t.Polyline.ATTRIBUTE_NAMES);return r===null?null:new t.Polyline(r,t.util.object.extend(i,n))},t.Polyline.fromObject=function(e){var n=e.points;return new t.Polyline(n,e,!0)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.array.min,i=t.util.array.max,s=t.util.toFixed;if(t.Polygon){t.warn("fabric.Polygon is already defined");return}t.Polygon=t.util.createClass(t.Object,{type:"polygon",points:null,minX:0,minY:0,initialize:function(e,t){t=t||{},this.points=e,this.callSuper("initialize",t),this._calcDimensions(),"top"in t||(this.top=this.minY),"left"in t||(this.left=this.minX)},_calcDimensions:function(){var e=this.points,t=r(e,"x"),n=r(e,"y"),s=i(e,"x"),o=i(e,"y");this.width=s-t||1,this.height=o-n||1,this.minX=t,this.minY=n},_applyPointOffset:function(){this.points.forEach(function(e){e.x-=this.minX+this.width/2,e.y-=this.minY+this.height/2},this)},toObject:function(e){return n(this.callSuper("toObject",e),{points:this.points.concat()})},toSVG:function(e){var t=[],n=this._createBaseSVGMarkup();for(var r=0,i=this.points.length;r<i;r++)t.push(s(this.points[r].x,2),",",s(this.points[r].y,2)," ");return n.push("<",this.type," ",'points="',t.join(""),'" style="',this.getSvgStyles(),'" transform="',this.getSvgTransform()," ",this.getSvgTransformMatrix(),'"/>\n'),e?e(n.join("")):n.join("")},_render:function(e){this.commonRender(e),this._renderFill(e);if(this.stroke||this.strokeDashArray)e.closePath(),this._renderStroke(e)},commonRender:function(e){var t;e.beginPath(),this._applyPointOffset&&((!this.group||this.group.type!=="path-group")&&this._applyPointOffset(),this._applyPointOffset=null),e.moveTo(this.points[0].x,this.points[0].y);for(var n=0,r=this.points.length;n<r;n++)t=this.points[n],e.lineTo(t.x,t.y)},_renderDashedStroke:function(e){t.Polyline.prototype._renderDashedStroke.call(this,e),e.closePath()},complexity:function(){return this.points.length}}),t.Polygon.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat(),t.Polygon.fromElement=function(e,r){if(!e)return null;r||(r={});var i=t.parsePointsAttribute(e.getAttribute("points")),s=t.parseAttributes(e,t.Polygon.ATTRIBUTE_NAMES);return i===null?null:new t.Polygon(i,n(s,r))},t.Polygon.fromObject=function(e){return new t.Polygon(e.points,e,!0)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.array.min,r=t.util.array.max,i=t.util.object.extend,s=Object.prototype.toString,o=t.util.drawArc,u={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7},a={m:"l",M:"L"};if(t.Path){t.warn("fabric.Path is already defined");return}t.Path=t.util.createClass(t.Object,{type:"path",path:null,minX:0,minY:0,initialize:function(e,t){t=t||{},this.setOptions(t);if(!e)throw new Error("`path` argument is required");var n=s.call(e)==="[object Array]";this.path=n?e:e.match&&e.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);if(!this.path)return;n||(this.path=this._parsePath());var r=this._parseDimensions();this.minX=r.left,this.minY=r.top,this.width=r.width,this.height=r.height,r.left+=this.originX==="center"?this.width/2:this.originX==="right"?this.width:0,r.top+=this.originY==="center"?this.height/2:this.originY==="bottom"?this.height:0,this.top=this.top||r.top,this.left=this.left||r.left,this.pathOffset=this.pathOffset||{x:this.minX+this.width/2,y:this.minY+this.height/2},t.sourcePath&&this.setSourcePath(t.sourcePath)},_render:function(e){var t,n=null,r=0,i=0,s=0,u=0,a=0,f=0,l,c,h,p,d=-this.pathOffset.x,v=-this.pathOffset.y;this.group&&this.group.type==="path-group"&&(d=0,v=0),e.beginPath();for(var m=0,g=this.path.length;m<g;++m){t=this.path[m];switch(t[0]){case"l":s+=t[1],u+=t[2],e.lineTo(s+d,u+v);break;case"L":s=t[1],u=t[2],e.lineTo(s+d,u+v);break;case"h":s+=t[1],e.lineTo(s+d,u+v);break;case"H":s=t[1],e.lineTo(s+d,u+v);break;case"v":u+=t[1],e.lineTo(s+d,u+v);break;case"V":u=t[1],e.lineTo(s+d,u+v);break;case"m":s+=t[1],u+=t[2],r=s,i=u,e.moveTo(s+d,u+v);break;case"M":s=t[1],u=t[2],r=s,i=u,e.moveTo(s+d,u+v);break;case"c":l=s+t[5],c=u+t[6],a=s+t[3],f=u+t[4],e.bezierCurveTo(s+t[1]+d,u+t[2]+v,a+d,f+v,l+d,c+v),s=l,u=c;break;case"C":s=t[5],u=t[6],a=t[3],f=t[4],e.bezierCurveTo(t[1]+d,t[2]+v,a+d,f+v,s+d,u+v);break;case"s":l=s+t[3],c=u+t[4],a=a?2*s-a:s,f=f?2*u-f:u,e.bezierCurveTo(a+d,f+v,s+t[1]+d,u+t[2]+v,l+d,c+v),a=s+t[1],f=u+t[2],s=l,u=c;break;case"S":l=t[3],c=t[4],a=2*s-a,f=2*u-f,e.bezierCurveTo(a+d,f+v,t[1]+d,t[2]+v,l+d,c+v),s=l,u=c,a=t[1],f=t[2];break;case"q":l=s+t[3],c=u+t[4],a=s+t[1],f=u+t[2],e.quadraticCurveTo(a+d,f+v,l+d,c+v),s=l,u=c;break;case"Q":l=t[3],c=t[4],e.quadraticCurveTo(t[1]+d,t[2]+v,l+d,c+v),s=l,u=c,a=t[1],f=t[2];break;case"t":l=s+t[1],c=u+t[2],n[0].match(/[QqTt]/)===null?(a=s,f=u):n[0]==="t"?(a=2*s-h,f=2*u-p):n[0]==="q"&&(a=2*s-a,f=2*u-f),h=a,p=f,e.quadraticCurveTo(a+d,f+v,l+d,c+v),s=l,u=c,a=s+t[1],f=u+t[2];break;case"T":l=t[1],c=t[2],a=2*s-a,f=2*u-f,e.quadraticCurveTo(a+d,f+v,l+d,c+v),s=l,u=c;break;case"a":o(e,s+d,u+v,[t[1],t[2],t[3],t[4],t[5],t[6]+s+d,t[7]+u+v]),s+=t[6],u+=t[7];break;case"A":o(e,s+d,u+v,[t[1],t[2],t[3],t[4],t[5],t[6]+d,t[7]+v]),s=t[6],u=t[7];break;case"z":case"Z":s=r,u=i,e.closePath()}n=t}this._renderFill(e),this._renderStroke(e)},render:function(e,n){if(!this.visible)return;e.save(),this._setupCompositeOperation(e),n||this.transform(e),this._setStrokeStyles(e),this._setFillStyles(e),this.group&&this.group.type==="path-group"&&e.translate(-this.group.width/2,-this.group.height/2),this.transformMatrix&&e.transform.apply(e,this.transformMatrix),this._setOpacity(e),this._setShadow(e),this.clipTo&&t.util.clipContext(this,e),this._render(e,n),this.clipTo&&e.restore(),this._removeShadow(e),this._restoreCompositeOperation(e),e.restore()},toString:function(){return"#<fabric.Path ("+this.complexity()+'): { "top": '+this.top+', "left": '+this.left+" }>"},toObject:function(e){var t=i(this.callSuper("toObject",e),{path:this.path.map(function(e){return e.slice()}),pathOffset:this.pathOffset});return this.sourcePath&&(t.sourcePath=this.sourcePath),this.transformMatrix&&(t.transformMatrix=this.transformMatrix),t},toDatalessObject:function(e){var t=this.toObject(e);return this.sourcePath&&(t.path=this.sourcePath),delete t.sourcePath,t},toSVG:function(e){var t=[],n=this._createBaseSVGMarkup(),r="";for(var i=0,s=this.path.length;i<s;i++)t.push(this.path[i].join(" "));var o=t.join(" ");if(!this.group||this.group.type!=="path-group")r="translate("+ -this.pathOffset.x+", "+ -this.pathOffset.y+")";return n.push("<path ",'d="',o,'" style="',this.getSvgStyles(),'" transform="',this.getSvgTransform(),r,this.getSvgTransformMatrix(),'" stroke-linecap="round" ',"/>\n"),e?e(n.join("")):n.join("")},complexity:function(){return this.path.length},_parsePath:function(){var e=[],t=[],n,r,i=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/ig,s,o;for(var f=0,l,c=this.path.length;f<c;f++){n=this.path[f],o=n.slice(1).trim(),t.length=0;while(s=i.exec(o))t.push(s[0]);l=[n.charAt(0)];for(var h=0,p=t.length;h<p;h++)r=parseFloat(t[h]),isNaN(r)||l.push(r);var d=l[0],v=u[d.toLowerCase()],m=a[d]||d;if(l.length-1>v)for(var g=1,y=l.length;g<y;g+=v)e.push([d].concat(l.slice(g,g+v))),d=m;else e.push(l)}return e},_parseDimensions:function(){var e=[],i=[],s,o=null,u=0,a=0,f=0,l=0,c=0,h=0,p,d,v,m,g;for(var y=0,b=this.path.length;y<b;++y){s=this.path[y];switch(s[0]){case"l":f+=s[1],l+=s[2],g=[];break;case"L":f=s[1],l=s[2],g=[];break;case"h":f+=s[1],g=[];break;case"H":f=s[1],g=[];break;case"v":l+=s[1],g=[];break;case"V":l=s[1],g=[];break;case"m":f+=s[1],l+=s[2],u=f,a=l,g=[];break;case"M":f=s[1],l=s[2],u=f,a=l,g=[];break;case"c":p=f+s[5],d=l+s[6],c=f+s[3],h=l+s[4],g=t.util.getBoundsOfCurve(f,l,f+s[1],l+s[2],c,h,p,d),f=p,l=d;break;case"C":f=s[5],l=s[6],c=s[3],h=s[4],g=t.util.getBoundsOfCurve(f,l,s[1],s[2],c,h,f,l);break;case"s":p=f+s[3],d=l+s[4],c=c?2*f-c:f,h=h?2*l-h:l,g=t.util.getBoundsOfCurve(f,l,c,h,f+s[1],l+s[2],p,d),c=f+s[1],h=l+s[2],f=p,l=d;break;case"S":p=s[3],d=s[4],c=2*f-c,h=2*l-h,g=t.util.getBoundsOfCurve(f,l,c,h,s[1],s[2],p,d),f=p,l=d,c=s[1],h=s[2];break;case"q":p=f+s[3],d=l+s[4],c=f+s[1],h=l+s[2],g=t.util.getBoundsOfCurve(f,l,c,h,c,h,p,d),f=p,l=d;break;case"Q":c=s[1],h=s[2],g=t.util.getBoundsOfCurve(f,l,c,h,c,h,s[3],s[4]),f=s[3],l=s[4];break;case"t":p=f+s[1],d=l+s[2],o[0].match(/[QqTt]/)===null?(c=f,h=l):o[0]==="t"?(c=2*f-v,h=2*l-m):o[0]==="q"&&(c=2*f-c,h=2*l-h),v=c,m=h,g=t.util.getBoundsOfCurve(f,l,c,h,c,h,p,d),f=p,l=d,c=f+s[1],h=l+s[2];break;case"T":p=s[1],d=s[2],c=2*f-c,h=2*l-h,g=t.util.getBoundsOfCurve(f,l,c,h,c,h,p,d),f=p,l=d;break;case"a":g=t.util.getBoundsOfArc(f,l,s[1],s[2],s[3],s[4],s[5],s[6]+f,s[7]+l),f+=s[6],l+=s[7];break;case"A":g=t.util.getBoundsOfArc(f,l,s[1],s[2],s[3],s[4],s[5],s[6],s[7]),f=s[6],l=s[7];break;case"z":case"Z":f=u,l=a}o=s,g.forEach(function(t){e.push(t.x),i.push(t.y)}),e.push(f),i.push(l)}var w=n(e),E=n(i),S=r(e),x=r(i),T=S-w,N=x-E,C={left:w,top:E,width:T,height:N};return C}}),t.Path.fromObject=function(e,n){typeof e.path=="string"?t.loadSVGFromURL(e.path,function(r){var i=r[0],s=e.path;delete e.path,t.util.object.extend(i,e),i.setSourcePath(s),n(i)}):n(new t.Path(e.path,e))},t.Path.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat(["d"]),t.Path.fromElement=function(e,n,r){var s=t.parseAttributes(e,t.Path.ATTRIBUTE_NAMES);n&&n(new t.Path(s.d,i(s,r)))},t.Path.async=!0}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.array.invoke,i=t.Object.prototype.toObject;if(t.PathGroup){t.warn("fabric.PathGroup is already defined");return}t.PathGroup=t.util.createClass(t.Path,{type:"path-group",fill:"",initialize:function(e,t){t=t||{},this.paths=e||[];for(var n=this.paths.length;n--;)this.paths[n].group=this;this.setOptions(t),t.widthAttr&&(this.scaleX=t.widthAttr/t.width),t.heightAttr&&(this.scaleY=t.heightAttr/t.height),this.setCoords(),t.sourcePath&&this.setSourcePath(t.sourcePath)},render:function(e){if(!this.visible)return;e.save();var n=this.transformMatrix;n&&e.transform(n[0],n[1],n[2],n[3],n[4],n[5]),this.transform(e),this._setShadow(e),this.clipTo&&t.util.clipContext(this,e);for(var r=0,i=this.paths.length;r<i;++r)this.paths[r].render(e,!0);this.clipTo&&e.restore(),this._removeShadow(e),e.restore()},_set:function(e,t){if(e==="fill"&&t&&this.isSameColor()){var n=this.paths.length;while(n--)this.paths[n]._set(e,t)}return this.callSuper("_set",e,t)},toObject:function(e){var t=n(i.call(this,e),{paths:r(this.getObjects(),"toObject",e)});return this.sourcePath&&(t.sourcePath=this.sourcePath),t},toDatalessObject:function(e){var t=this.toObject(e);return this.sourcePath&&(t.paths=this.sourcePath),t},toSVG:function(e){var t=this.getObjects(),n="translate("+this.left+" "+this.top+")",r=["<g ",'style="',this.getSvgStyles(),'" ','transform="',n,this.getSvgTransform(),'" ',">\n"];for(var i=0,s=t.length;i<s;i++)r.push(t[i].toSVG(e));return r.push("</g>\n"),e?e(r.join("")):r.join("")},toString:function(){return"#<fabric.PathGroup ("+this.complexity()+"): { top: "+this.top+", left: "+this.left+" }>"},isSameColor:function(){var e=(this.getObjects()[0].get("fill")||"").toLowerCase();return this.getObjects().every(function(t){return(t.get("fill")||"").toLowerCase()===e})},complexity:function(){return this.paths.reduce(function(e,t){return e+(t&&t.complexity?t.complexity():0)},0)},getObjects:function(){return this.paths}}),t.PathGroup.fromObject=function(e,n){typeof e.paths=="string"?t.loadSVGFromURL(e.paths,function(r){var i=e.paths;delete e.paths;var s=t.util.groupSVGElements(r,e,i);n(s)}):t.util.enlivenObjects(e.paths,function(r){delete e.paths,n(new t.PathGroup(r,e))})},t.PathGroup.async=!0}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.array.min,i=t.util.array.max,s=t.util.array.invoke;if(t.Group)return;var o={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};t.Group=t.util.createClass(t.Object,t.Collection,{type:"group",initialize:function(e,t){t=t||{},this._objects=e||[];for(var n=this._objects.length;n--;)this._objects[n].group=this;this.originalState={},this.callSuper("initialize"),t.originX&&(this.originX=t.originX),t.originY&&(this.originY=t.originY),this._calcBounds(),this._updateObjectsCoords(),this.callSuper("initialize",t),this.setCoords(),this.saveCoords()},_updateObjectsCoords:function(){this.forEachObject(this._updateObjectCoords,this)},_updateObjectCoords:function(e){var t=e.getLeft(),n=e.getTop(),r=this.getCenterPoint();e.set({originalLeft:t,originalTop:n,left:t-r.x,top:n-r.y}),e.setCoords(),e.__origHasControls=e.hasControls,e.hasControls=!1},toString:function(){return"#<fabric.Group: ("+this.complexity()+")>"},addWithUpdate:function(e){return this._restoreObjectsState(),e&&(this._objects.push(e),e.group=this),this.forEachObject(this._setObjectActive,this),this._calcBounds(),this._updateObjectsCoords(),this},_setObjectActive:function(e){e.set("active",!0),e.group=this},removeWithUpdate:function(e){return this._moveFlippedObject(e),this._restoreObjectsState(),this.forEachObject(this._setObjectActive,this),this.remove(e),this._calcBounds(),this._updateObjectsCoords(),this},_onObjectAdded:function(e){e.group=this},_onObjectRemoved:function(e){delete e.group,e.set("active",!1)},delegatedProperties:{fill:!0,opacity:!0,fontFamily:!0,fontWeight:!0,fontSize:!0,fontStyle:!0,lineHeight:!0,textDecoration:!0,textAlign:!0,backgroundColor:!0},_set:function(e,t){if(e in this.delegatedProperties){var n=this._objects.length;while(n--)this._objects[n].set(e,t)}this.callSuper("_set",e,t)},toObject:function(e){return n(this.callSuper("toObject",e),{objects:s(this._objects,"toObject",e)})},render:function(e){if(!this.visible)return;e.save(),this.clipTo&&t.util.clipContext(this,e);for(var n=0,r=this._objects.length;n<r;n++)this._renderObject(this._objects[n],e);this.clipTo&&e.restore(),e.restore()},_renderControls:function(e,t){this.callSuper("_renderControls",e,t);for(var n=0,r=this._objects.length;n<r;n++)this._objects[n]._renderControls(e)},_renderObject:function(e,t){var n=e.hasRotatingPoint;if(!e.visible)return;e.hasRotatingPoint=!1,e.render(t),e.hasRotatingPoint=n},_restoreObjectsState:function(){return this._objects.forEach(this._restoreObjectState,this),this},_moveFlippedObject:function(e){var t=e.get("originX"),n=e.get("originY"),r=e.getCenterPoint();e.set({originX:"center",originY:"center",left:r.x,top:r.y}),this._toggleFlipping(e);var i=e.getPointByOrigin(t,n);return e.set({originX:t,originY:n,left:i.x,top:i.y}),this},_toggleFlipping:function(e){this.flipX&&(e.toggle("flipX"),e.set("left",-e.get("left")),e.setAngle(-e.getAngle())),this.flipY&&(e.toggle("flipY"),e.set("top",-e.get("top")),e.setAngle(-e.getAngle()))},_restoreObjectState:function(e){return this._setObjectPosition(e),e.setCoords(),e.hasControls=e.__origHasControls,delete e.__origHasControls,e.set("active",!1),e.setCoords(),delete e.group,this},_setObjectPosition:function(e){var t=this.getCenterPoint(),n=this._getRotatedLeftTop(e);e.set({angle:e.getAngle()+this.getAngle(),left:t.x+n.left,top:t.y+n.top,scaleX:e.get("scaleX")*this.get("scaleX"),scaleY:e.get("scaleY")*this.get("scaleY")})},_getRotatedLeftTop:function(e){var t=this.getAngle()*(Math.PI/180);return{left:-Math.sin(t)*e.getTop()*this.get("scaleY")+Math.cos(t)*e.getLeft()*this.get("scaleX"),top:Math.cos(t)*e.getTop()*this.get("scaleY")+Math.sin(t)*e.getLeft()*this.get("scaleX")}},destroy:function(){return this._objects.forEach(this._moveFlippedObject,this),this._restoreObjectsState()},saveCoords:function(){return this._originalLeft=this.get("left"),this._originalTop=this.get("top"),this},hasMoved:function(){return this._originalLeft!==this.get("left")||this._originalTop!==this.get("top")},setObjectsCoords:function(){return this.forEachObject(function(e){e.setCoords()}),this},_calcBounds:function(e){var t=[],n=[],r;for(var i=0,s=this._objects.length;i<s;++i){r=this._objects[i],r.setCoords();for(var o in r.oCoords)t.push(r.oCoords[o].x),n.push(r.oCoords[o].y)}this.set(this._getBounds(t,n,e))},_getBounds:function(e,n,s){var o=t.util.invertTransform(this.getViewportTransform()),u=t.util.transformPoint(new t.Point(r(e),r(n)),o),a=t.util.transformPoint(new t.Point(i(e),i(n)),o),f={width:a.x-u.x||0,height:a.y-u.y||0};return s||(f.left=u.x||0,f.top=u.y||0,this.originX==="center"&&(f.left+=f.width/2),this.originX==="right"&&(f.left+=f.width),this.originY==="center"&&(f.top+=f.height/2),this.originY==="bottom"&&(f.top+=f.height)),f},toSVG:function(e){var t=["<g ",'transform="',this.getSvgTransform(),'">\n'];for(var n=0,r=this._objects.length;n<r;n++)t.push(this._objects[n].toSVG(e));return t.push("</g>\n"),e?e(t.join("")):t.join("")},get:function(e){if(e in o){if(this[e])return this[e];for(var t=0,n=this._objects.length;t<n;t++)if(this._objects[t][e])return!0;return!1}return e in this.delegatedProperties?this._objects[0]&&this._objects[0].get(e):this[e]}}),t.Group.fromObject=function(e,n){t.util.enlivenObjects(e.objects,function(r){delete e.objects,n&&n(new t.Group(r,e))})},t.Group.async=!0}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=fabric.util.object.extend;e.fabric||(e.fabric={});if(e.fabric.Image){fabric.warn("fabric.Image is already defined.");return}fabric.Image=fabric.util.createClass(fabric.Object,{type:"image",crossOrigin:"",alignX:"none",alignY:"none",meetOrSlice:"meet",_lastScaleX:1,_lastScaleY:1,initialize:function(e,t){t||(t={}),this.filters=[],this.resizeFilters=[],this.callSuper("initialize",t),this._initElement(e,t),this._initConfig(t),t.filters&&(this.filters=t.filters,this.applyFilters())},getElement:function(){return this._element},setElement:function(e,t,n){return this._element=e,this._originalElement=e,this._initConfig(n),this.filters.length!==0?this.applyFilters(t):t&&t(),this},setCrossOrigin:function(e){return this.crossOrigin=e,this._element.crossOrigin=e,this},getOriginalSize:function(){var e=this.getElement();return{width:e.width,height:e.height}},_stroke:function(e){e.save(),this._setStrokeStyles(e),e.beginPath(),e.strokeRect(-this.width/2,-this.height/2,this.width,this.height),e.closePath(),e.restore()},_renderDashedStroke:function(e){var t=-this.width/2,n=-this.height/2,r=this.width,i=this.height;e.save(),this._setStrokeStyles(e),e.beginPath(),fabric.util.drawDashedLine(e,t,n,t+r,n,this.strokeDashArray),fabric.util.drawDashedLine(e,t+r,n,t+r,n+i,this.strokeDashArray),fabric.util.drawDashedLine(e,t+r,n+i,t,n+i,this.strokeDashArray),fabric.util.drawDashedLine(e,t,n+i,t,n,this.strokeDashArray),e.closePath(),e.restore()},toObject:function(e){return t(this.callSuper("toObject",e),{src:this._originalElement.src||this._originalElement._src,filters:this.filters.map(function(e){return e&&e.toObject()}),crossOrigin:this.crossOrigin,alignX:this.alignX,alignY:this.alignY,meetOrSlice:this.meetOrSlice})},toSVG:function(e){var t=[],n=-this.width/2,r=-this.height/2,i="none";this.group&&this.group.type==="path-group"&&(n=this.left,r=this.top),this.alignX!=="none"&&this.alignY!=="none"&&(i="x"+this.alignX+"Y"+this.alignY+" "+this.meetOrSlice),t.push('<g transform="',this.getSvgTransform(),this.getSvgTransformMatrix(),'">\n','<image xlink:href="',this.getSvgSrc(),'" x="',n,'" y="',r,'" style="',this.getSvgStyles(),'" width="',this.width,'" height="',this.height,'" preserveAspectRatio="',i,'"',"></image>\n");if(this.stroke||this.strokeDashArray){var s=this.fill;this.fill=null,t.push("<rect ",'x="',n,'" y="',r,'" width="',this.width,'" height="',this.height,'" style="',this.getSvgStyles(),'"/>\n'),this.fill=s}return t.push("</g>\n"),e?e(t.join("")):t.join("")},getSrc:function(){if(this.getElement())return this.getElement().src||this.getElement()._src},setSrc:function(e,t,n){fabric.util.loadImage(e,function(e){return this.setElement(e,t,n)},this,n&&n.crossOrigin)},toString:function(){return'#<fabric.Image: { src: "'+this.getSrc()+'" }>'},clone:function(e,t){this.constructor.fromObject(this.toObject(t),e)},applyFilters:function(e,t,n,r){t=t||this.filters,n=n||this._originalElement;if(!n)return;var i=n,s=fabric.util.createCanvasElement(),o=fabric.util.createImage(),u=this;return s.width=i.width,s.height=i.height,s.getContext("2d").drawImage(i,0,0,i.width,i.height),t.length===0?(this._element=n,e&&e(),s):(t.forEach(function(e){e&&e.applyTo(s,e.scaleX||u.scaleX,e.scaleY||u.scaleY),!r&&e.type==="Resize"&&(u.width*=e.scaleX,u.height*=e.scaleY)}),o.width=s.width,o.height=s.height,fabric.isLikelyNode?(o.src=s.toBuffer(undefined,fabric.Image.pngCompression),u._element=o,!r&&(u._filteredEl=o),e&&e()):(o.onload=function(){u._element=o,!r&&(u._filteredEl=o),e&&e(),o.onload=s=i=null},o.src=s.toDataURL("image/png")),s)},_render:function(e,t){var n,r,i=this._findMargins(),s;n=t?this.left:-this.width/2,r=t?this.top:-this.height/2,this.meetOrSlice==="slice"&&(e.beginPath(),e.rect(n,r,this.width,this.height),e.clip()),this.isMoving===!1&&this.resizeFilters.length&&this._needsResize()?(this._lastScaleX=this.scaleX,this._lastScaleY=this.scaleY,s=this.applyFilters(null,this.resizeFilters,this._filteredEl||this._originalElement,!0)):s=this._element,s&&e.drawImage(s,n+i.marginX,r+i.marginY,i.width,i.height),this._renderStroke(e)},_needsResize:function(){return this.scaleX!==this._lastScaleX||this.scaleY!==this._lastScaleY},_findMargins:function(){var e=this.width,t=this.height,n,r,i=0,s=0;if(this.alignX!=="none"||this.alignY!=="none")n=[this.width/this._element.width,this.height/this._element.height],r=this.meetOrSlice==="meet"?Math.min.apply(null,n):Math.max.apply(null,n),e=this._element.width*r,t=this._element.height*r,this.alignX==="Mid"&&(i=(this.width-e)/2),this.alignX==="Max"&&(i=this.width-e),this.alignY==="Mid"&&(s=(this.height-t)/2),this.alignY==="Max"&&(s=this.height-t);return{width:e,height:t,marginX:i,marginY:s}},_resetWidthHeight:function(){var e=this.getElement();this.set("width",e.width),this.set("height",e.height)},_initElement:function(e){this.setElement(fabric.util.getById(e)),fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(e){e||(e={}),this.setOptions(e),this._setWidthHeight(e),this._element&&this.crossOrigin&&(this._element.crossOrigin=this.crossOrigin)},_initFilters:function(e,t){e.filters&&e.filters.length?fabric.util.enlivenObjects(e.filters,function(e){t&&t(e)},"fabric.Image.filters" +):t&&t()},_setWidthHeight:function(e){this.width="width"in e?e.width:this.getElement()?this.getElement().width||0:0,this.height="height"in e?e.height:this.getElement()?this.getElement().height||0:0},complexity:function(){return 1}}),fabric.Image.CSS_CANVAS="canvas-img",fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc,fabric.Image.fromObject=function(e,t){fabric.util.loadImage(e.src,function(n){fabric.Image.prototype._initFilters.call(e,e,function(r){e.filters=r||[];var i=new fabric.Image(n,e);t&&t(i)})},null,e.crossOrigin)},fabric.Image.fromURL=function(e,t,n){fabric.util.loadImage(e,function(e){t(new fabric.Image(e,n))},null,n&&n.crossOrigin)},fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href".split(" ")),fabric.Image.fromElement=function(e,n,r){var i=fabric.parseAttributes(e,fabric.Image.ATTRIBUTE_NAMES),s="xMidYMid",o="meet",u,a,f;i.preserveAspectRatio&&(f=i.preserveAspectRatio.split(" ")),f&&f.length&&(o=f.pop(),o!=="meet"&&o!=="slice"?(s=o,o="meet"):f.length&&(s=f.pop())),u=s!=="none"?s.slice(1,4):"none",a=s!=="none"?s.slice(5,8):"none",i.alignX=u,i.alignY=a,i.meetOrSlice=o,fabric.Image.fromURL(i["xlink:href"],n,t(r?fabric.util.object.clone(r):{},i))},fabric.Image.async=!0,fabric.Image.pngCompression=1}(typeof exports!="undefined"?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var e=this.getAngle()%360;return e>0?Math.round((e-1)/90)*90:Math.round(e/90)*90},straighten:function(){return this.setAngle(this._getAngleValueForStraighten()),this},fxStraighten:function(e){e=e||{};var t=function(){},n=e.onComplete||t,r=e.onChange||t,i=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(e){i.setAngle(e),r()},onComplete:function(){i.setCoords(),n()},onStart:function(){i.set("active",!1)}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(e){return e.straighten(),this.renderAll(),this},fxStraightenObject:function(e){return e.fxStraighten({onChange:this.renderAll.bind(this)}),this}}),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",initialize:function(e){e&&this.setOptions(e)},setOptions:function(e){for(var t in e)this[t]=e[t]},toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}}),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.Brightness=t.util.createClass(t.Image.filters.BaseFilter,{type:"Brightness",initialize:function(e){e=e||{},this.brightness=e.brightness||0},applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=this.brightness;for(var s=0,o=r.length;s<o;s+=4)r[s]+=i,r[s+1]+=i,r[s+2]+=i;t.putImageData(n,0,0)},toObject:function(){return n(this.callSuper("toObject"),{brightness:this.brightness})}}),t.Image.filters.Brightness.fromObject=function(e){return new t.Image.filters.Brightness(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.Convolute=t.util.createClass(t.Image.filters.BaseFilter,{type:"Convolute",initialize:function(e){e=e||{},this.opaque=e.opaque,this.matrix=e.matrix||[0,0,0,0,1,0,0,0,0];var n=t.util.createCanvasElement();this.tmpCtx=n.getContext("2d")},_createImageData:function(e,t){return this.tmpCtx.createImageData(e,t)},applyTo:function(e){var t=this.matrix,n=e.getContext("2d"),r=n.getImageData(0,0,e.width,e.height),i=Math.round(Math.sqrt(t.length)),s=Math.floor(i/2),o=r.data,u=r.width,a=r.height,f=u,l=a,c=this._createImageData(f,l),h=c.data,p=this.opaque?1:0;for(var d=0;d<l;d++)for(var v=0;v<f;v++){var m=d,g=v,y=(d*f+v)*4,b=0,w=0,E=0,S=0;for(var x=0;x<i;x++)for(var T=0;T<i;T++){var N=m+x-s,C=g+T-s;if(N<0||N>a||C<0||C>u)continue;var k=(N*u+C)*4,L=t[x*i+T];b+=o[k]*L,w+=o[k+1]*L,E+=o[k+2]*L,S+=o[k+3]*L}h[y]=b,h[y+1]=w,h[y+2]=E,h[y+3]=S+p*(255-S)}n.putImageData(c,0,0)},toObject:function(){return n(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}}),t.Image.filters.Convolute.fromObject=function(e){return new t.Image.filters.Convolute(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.GradientTransparency=t.util.createClass(t.Image.filters.BaseFilter,{type:"GradientTransparency",initialize:function(e){e=e||{},this.threshold=e.threshold||100},applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=this.threshold,s=r.length;for(var o=0,u=r.length;o<u;o+=4)r[o+3]=i+255*(s-o)/s;t.putImageData(n,0,0)},toObject:function(){return n(this.callSuper("toObject"),{threshold:this.threshold})}}),t.Image.filters.GradientTransparency.fromObject=function(e){return new t.Image.filters.GradientTransparency(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={});t.Image.filters.Grayscale=t.util.createClass(t.Image.filters.BaseFilter,{type:"Grayscale",applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=n.width*n.height*4,s=0,o;while(s<i)o=(r[s]+r[s+1]+r[s+2])/3,r[s]=o,r[s+1]=o,r[s+2]=o,s+=4;t.putImageData(n,0,0)}}),t.Image.filters.Grayscale.fromObject=function(){return new t.Image.filters.Grayscale}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={});t.Image.filters.Invert=t.util.createClass(t.Image.filters.BaseFilter,{type:"Invert",applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=r.length,s;for(s=0;s<i;s+=4)r[s]=255-r[s],r[s+1]=255-r[s+1],r[s+2]=255-r[s+2];t.putImageData(n,0,0)}}),t.Image.filters.Invert.fromObject=function(){return new t.Image.filters.Invert}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.Mask=t.util.createClass(t.Image.filters.BaseFilter,{type:"Mask",initialize:function(e){e=e||{},this.mask=e.mask,this.channel=[0,1,2,3].indexOf(e.channel)>-1?e.channel:0},applyTo:function(e){if(!this.mask)return;var n=e.getContext("2d"),r=n.getImageData(0,0,e.width,e.height),i=r.data,s=this.mask.getElement(),o=t.util.createCanvasElement(),u=this.channel,a,f=r.width*r.height*4;o.width=s.width,o.height=s.height,o.getContext("2d").drawImage(s,0,0,s.width,s.height);var l=o.getContext("2d").getImageData(0,0,s.width,s.height),c=l.data;for(a=0;a<f;a+=4)i[a+3]=c[a+u];n.putImageData(r,0,0)},toObject:function(){return n(this.callSuper("toObject"),{mask:this.mask.toObject(),channel:this.channel})}}),t.Image.filters.Mask.fromObject=function(e,n){t.util.loadImage(e.mask.src,function(r){e.mask=new t.Image(r,e.mask),n&&n(new t.Image.filters.Mask(e))})},t.Image.filters.Mask.async=!0}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.Noise=t.util.createClass(t.Image.filters.BaseFilter,{type:"Noise",initialize:function(e){e=e||{},this.noise=e.noise||0},applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=this.noise,s;for(var o=0,u=r.length;o<u;o+=4)s=(.5-Math.random())*i,r[o]+=s,r[o+1]+=s,r[o+2]+=s;t.putImageData(n,0,0)},toObject:function(){return n(this.callSuper("toObject"),{noise:this.noise})}}),t.Image.filters.Noise.fromObject=function(e){return new t.Image.filters.Noise(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.Pixelate=t.util.createClass(t.Image.filters.BaseFilter,{type:"Pixelate",initialize:function(e){e=e||{},this.blocksize=e.blocksize||4},applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=n.height,s=n.width,o,u,a,f,l,c,h;for(u=0;u<i;u+=this.blocksize)for(a=0;a<s;a+=this.blocksize){o=u*4*s+a*4,f=r[o],l=r[o+1],c=r[o+2],h=r[o+3];for(var p=u,d=u+this.blocksize;p<d;p++)for(var v=a,m=a+this.blocksize;v<m;v++)o=p*4*s+v*4,r[o]=f,r[o+1]=l,r[o+2]=c,r[o+3]=h}t.putImageData(n,0,0)},toObject:function(){return n(this.callSuper("toObject"),{blocksize:this.blocksize})}}),t.Image.filters.Pixelate.fromObject=function(e){return new t.Image.filters.Pixelate(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.RemoveWhite=t.util.createClass(t.Image.filters.BaseFilter,{type:"RemoveWhite",initialize:function(e){e=e||{},this.threshold=e.threshold||30,this.distance=e.distance||20},applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=this.threshold,s=this.distance,o=255-i,u=Math.abs,a,f,l;for(var c=0,h=r.length;c<h;c+=4)a=r[c],f=r[c+1],l=r[c+2],a>o&&f>o&&l>o&&u(a-f)<s&&u(a-l)<s&&u(f-l)<s&&(r[c+3]=1);t.putImageData(n,0,0)},toObject:function(){return n(this.callSuper("toObject"),{threshold:this.threshold,distance:this.distance})}}),t.Image.filters.RemoveWhite.fromObject=function(e){return new t.Image.filters.RemoveWhite(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={});t.Image.filters.Sepia=t.util.createClass(t.Image.filters.BaseFilter,{type:"Sepia",applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=r.length,s,o;for(s=0;s<i;s+=4)o=.3*r[s]+.59*r[s+1]+.11*r[s+2],r[s]=o+100,r[s+1]=o+50,r[s+2]=o+255;t.putImageData(n,0,0)}}),t.Image.filters.Sepia.fromObject=function(){return new t.Image.filters.Sepia}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={});t.Image.filters.Sepia2=t.util.createClass(t.Image.filters.BaseFilter,{type:"Sepia2",applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=r.length,s,o,u,a;for(s=0;s<i;s+=4)o=r[s],u=r[s+1],a=r[s+2],r[s]=(o*.393+u*.769+a*.189)/1.351,r[s+1]=(o*.349+u*.686+a*.168)/1.203,r[s+2]=(o*.272+u*.534+a*.131)/2.14;t.putImageData(n,0,0)}}),t.Image.filters.Sepia2.fromObject=function(){return new t.Image.filters.Sepia2}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.Tint=t.util.createClass(t.Image.filters.BaseFilter,{type:"Tint",initialize:function(e){e=e||{},this.color=e.color||"#000000",this.opacity=typeof e.opacity!="undefined"?e.opacity:(new t.Color(this.color)).getAlpha()},applyTo:function(e){var n=e.getContext("2d"),r=n.getImageData(0,0,e.width,e.height),i=r.data,s=i.length,o,u,a,f,l,c,h,p,d;d=(new t.Color(this.color)).getSource(),u=d[0]*this.opacity,a=d[1]*this.opacity,f=d[2]*this.opacity,p=1-this.opacity;for(o=0;o<s;o+=4)l=i[o],c=i[o+1],h=i[o+2],i[o]=u+l*p,i[o+1]=a+c*p,i[o+2]=f+h*p;n.putImageData(r,0,0)},toObject:function(){return n(this.callSuper("toObject"),{color:this.color,opacity:this.opacity})}}),t.Image.filters.Tint.fromObject=function(e){return new t.Image.filters.Tint(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend;t.Image.filters.Multiply=t.util.createClass(t.Image.filters.BaseFilter,{type:"Multiply",initialize:function(e){e=e||{},this.color=e.color||"#000000"},applyTo:function(e){var n=e.getContext("2d"),r=n.getImageData(0,0,e.width,e.height),i=r.data,s=i.length,o,u;u=(new t.Color(this.color)).getSource();for(o=0;o<s;o+=4)i[o]*=u[0]/255,i[o+1]*=u[1]/255,i[o+2]*=u[2]/255;n.putImageData(r,0,0)},toObject:function(){return n(this.callSuper("toObject"),{color:this.color})}}),t.Image.filters.Multiply.fromObject=function(e){return new t.Image.filters.Multiply(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric;t.Image.filters.Blend=t.util.createClass({type:"Blend",initialize:function(e){e=e||{},this.color=e.color||"#000",this.image=e.image||!1,this.mode=e.mode||"multiply",this.alpha=e.alpha||1},applyTo:function(e){var n=e.getContext("2d"),r=n.getImageData(0,0,e.width,e.height),i=r.data,s,o,u,a,f,l,c,h=!1;if(this.image){h=!0;var p=t.util.createCanvasElement();p.width=this.image.width,p.height=this.image.height;var d=new t.StaticCanvas(p);d.add(this.image);var v=d.getContext("2d");c=v.getImageData(0,0,d.width,d.height).data}else c=(new t.Color(this.color)).getSource(),s=c[0]*this.alpha,o=c[1]*this.alpha,u=c[2]*this.alpha;for(var m=0,g=i.length;m<g;m+=4){a=i[m],f=i[m+1],l=i[m+2],h&&(s=c[m]*this.alpha,o=c[m+1]*this.alpha,u=c[m+2]*this.alpha);switch(this.mode){case"multiply":i[m]=a*s/255,i[m+1]=f*o/255,i[m+2]=l*u/255;break;case"screen":i[m]=1-(1-a)*(1-s),i[m+1]=1-(1-f)*(1-o),i[m+2]=1-(1-l)*(1-u);break;case"add":i[m]=Math.min(255,a+s),i[m+1]=Math.min(255,f+o),i[m+2]=Math.min(255,l+u);break;case"diff":case"difference":i[m]=Math.abs(a-s),i[m+1]=Math.abs(f-o),i[m+2]=Math.abs(l-u);break;case"subtract":var y=a-s,b=f-o,w=l-u;i[m]=y<0?0:y,i[m+1]=b<0?0:b,i[m+2]=w<0?0:w;break;case"darken":i[m]=Math.min(a,s),i[m+1]=Math.min(f,o),i[m+2]=Math.min(l,u);break;case"lighten":i[m]=Math.max(a,s),i[m+1]=Math.max(f,o),i[m+2]=Math.max(l,u)}}n.putImageData(r,0,0)},toObject:function(){return{color:this.color,image:this.image,mode:this.mode,alpha:this.alpha}}}),t.Image.filters.Blend.fromObject=function(e){return new t.Image.filters.Blend(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=Math.pow,r=Math.floor,i=Math.sqrt,s=Math.abs,o=Math.max,u=Math.round,a=Math.sin,f=Math.ceil;t.Image.filters.Resize=t.util.createClass(t.Image.filters.BaseFilter,{type:"Resize",resizeType:"hermite",scaleX:0,scaleY:0,lanczosLobes:3,applyTo:function(e,t,n){this.rcpScaleX=1/t,this.rcpScaleY=1/n;var r=e.width,i=e.height,s=u(r*t),o=u(i*n),a;this.resizeType==="sliceHack"&&(a=this.sliceByTwo(e,r,i,s,o)),this.resizeType==="hermite"&&(a=this.hermiteFastResize(e,r,i,s,o)),this.resizeType==="bilinear"&&(a=this.bilinearFiltering(e,r,i,s,o)),this.resizeType==="lanczos"&&(a=this.lanczosResize(e,r,i,s,o)),e.width=s,e.height=o,e.getContext("2d").putImageData(a,0,0)},sliceByTwo:function(e,n,i,s,u){var a=e.getContext("2d"),f,l=.5,c=.5,h=1,p=1,d=!1,v=!1,m=n,g=i,y=t.util.createCanvasElement(),b=y.getContext("2d");s=r(s),u=r(u),y.width=o(s,n),y.height=o(u,i),s>n&&(l=2,h=-1),u>i&&(c=2,p=-1),f=a.getImageData(0,0,n,i),e.width=o(s,n),e.height=o(u,i),a.putImageData(f,0,0);while(!d||!v)n=m,i=g,s*h<r(m*l*h)?m=r(m*l):(m=s,d=!0),u*p<r(g*c*p)?g=r(g*c):(g=u,v=!0),f=a.getImageData(0,0,n,i),b.putImageData(f,0,0),a.clearRect(0,0,m,g),a.drawImage(y,0,0,n,i,0,0,m,g);return a.getImageData(0,0,s,u)},lanczosResize:function(e,t,o,u,l){function c(e){return function(t){if(t>e)return 0;t*=Math.PI;if(s(t)<1e-16)return 1;var n=t/e;return a(t)*a(n)/t/n}}function h(e){var a,f,c,p,d,L,A,O,M,_,D;C.x=(e+.5)*b,k.x=r(C.x);for(a=0;a<l;a++){C.y=(a+.5)*w,k.y=r(C.y),d=0,L=0,A=0,O=0,M=0;for(f=k.x-x;f<=k.x+x;f++){if(f<0||f>=t)continue;_=r(1e3*s(f-C.x)),N[_]||(N[_]={});for(var P=k.y-T;P<=k.y+T;P++){if(P<0||P>=o)continue;D=r(1e3*s(P-C.y)),N[_][D]||(N[_][D]=y(i(n(_*E,2)+n(D*S,2))/1e3)),c=N[_][D],c>0&&(p=(P*t+f)*4,d+=c,L+=c*m[p],A+=c*m[p+1],O+=c*m[p+2],M+=c*m[p+3])}}p=(a*u+e)*4,g[p]=L/d,g[p+1]=A/d,g[p+2]=O/d,g[p+3]=M/d}return++e<u?h(e):v}var p=e.getContext("2d"),d=p.getImageData(0,0,t,o),v=p.getImageData(0,0,u,l),m=d.data,g=v.data,y=c(this.lanczosLobes),b=this.rcpScaleX,w=this.rcpScaleY,E=2/this.rcpScaleX,S=2/this.rcpScaleY,x=f(b*this.lanczosLobes/2),T=f(w*this.lanczosLobes/2),N={},C={},k={};return h(0)},bilinearFiltering:function(e,t,n,i,s){var o,u,a,f,l,c,h,p,d,v,m,g,y=0,b,w=this.rcpScaleX,E=this.rcpScaleY,S=e.getContext("2d"),x=4*(t-1),T=S.getImageData(0,0,t,n),N=T.data,C=S.getImageData(0,0,i,s),k=C.data;for(h=0;h<s;h++)for(p=0;p<i;p++){l=r(w*p),c=r(E*h),d=w*p-l,v=E*h-c,b=4*(c*t+l);for(m=0;m<4;m++)o=N[b+m],u=N[b+4+m],a=N[b+x+m],f=N[b+x+4+m],g=o*(1-d)*(1-v)+u*d*(1-v)+a*v*(1-d)+f*d*v,k[y++]=g}return C},hermiteFastResize:function(e,t,n,o,u){var a=this.rcpScaleX,l=this.rcpScaleY,c=f(a/2),h=f(l/2),p=e.getContext("2d"),d=p.getImageData(0,0,t,n),v=d.data,m=p.getImageData(0,0,o,u),g=m.data;for(var y=0;y<u;y++)for(var b=0;b<o;b++){var w=(b+y*o)*4,E=0,S=0,x=0,T=0,N=0,C=0,k=0,L=(y+.5)*l;for(var A=r(y*l);A<(y+1)*l;A++){var O=s(L-(A+.5))/h,M=(b+.5)*a,_=O*O;for(var D=r(b*a);D<(b+1)*a;D++){var P=s(M-(D+.5))/c,H=i(_+P*P);if(H>1&&H<-1)continue;E=2*H*H*H-3*H*H+1,E>0&&(P=4*(D+A*t),k+=E*v[P+3],x+=E,v[P+3]<255&&(E=E*v[P+3]/250),T+=E*v[P],N+=E*v[P+1],C+=E*v[P+2],S+=E)}}g[w]=T/S,g[w+1]=N/S,g[w+2]=C/S,g[w+3]=k/x}return m}}),t.Image.filters.Resize.fromObject=function(){return new t.Image.filters.Resize}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.object.clone,i=t.util.toFixed,s=t.StaticCanvas.supports("setLineDash");if(t.Text){t.warn("fabric.Text is already defined");return}var o=t.Object.prototype.stateProperties.concat();o.push("fontFamily","fontWeight","fontSize","text","textDecoration","textAlign","fontStyle","lineHeight","textBackgroundColor","useNative","path"),t.Text=t.util.createClass(t.Object,{_dimensionAffectingProps:{fontSize:!0,fontWeight:!0,fontFamily:!0,textDecoration:!0,fontStyle:!0,lineHeight:!0,stroke:!0,strokeWidth:!0,text:!0},_reNewline:/\r?\n/,type:"text",fontSize:40,fontWeight:"normal",fontFamily:"Times New Roman",textDecoration:"",textAlign:"left",fontStyle:"",lineHeight:1.3,textBackgroundColor:"",path:null,useNative:!0,stateProperties:o,stroke:null,shadow:null,initialize:function(e,t){t=t||{},this.text=e,this.__skipDimension=!0,this.setOptions(t),this.__skipDimension=!1,this._initDimensions()},_initDimensions:function(){if(this.__skipDimension)return;var e=t.util.createCanvasElement();this._render(e.getContext("2d"))},toString:function(){return"#<fabric.Text ("+this.complexity()+'): { "text": "'+this.text+'", "fontFamily": "'+this.fontFamily+'" }>'},_render:function(e){typeof Cufon=="undefined"||this.useNative===!0?this._renderViaNative(e):this._renderViaCufon(e)},_renderViaNative:function(e){var n=this.text.split(this._reNewline);this._setTextStyles(e),this.width=this._getTextWidth(e,n),this.height=this._getTextHeight(e,n),this.clipTo&&t.util.clipContext(this,e),this._renderTextBackground(e,n),this._translateForTextAlign(e),this._renderText(e,n),this.textAlign!=="left"&&this.textAlign!=="justify"&&e.restore(),this._renderTextDecoration(e,n),this.clipTo&&e.restore(),this._setBoundaries(e,n),this._totalLineHeight=0},_renderText:function(e,t){e.save(),this._setOpacity(e),this._setShadow(e),this._setupCompositeOperation(e),this._renderTextFill(e,t),this._renderTextStroke(e,t),this._restoreCompositeOperation(e),this._removeShadow(e),e.restore()},_translateForTextAlign:function(e){this.textAlign!=="left"&&this.textAlign!=="justify"&&(e.save(),e.translate(this.textAlign==="center"?this.width/2:this.width,0))},_setBoundaries:function(e,t){this._boundaries=[];for(var n=0,r=t.length;n<r;n++){var i=this._getLineWidth(e,t[n]),s=this._getLineLeftOffset(i);this._boundaries.push({height:this.fontSize*this.lineHeight,width:i,left:s})}},_setTextStyles:function(e){this._setFillStyles(e),this._setStrokeStyles(e),e.textBaseline="alphabetic",this.skipTextAlign||(e.textAlign=this.textAlign),e.font=this._getFontDeclaration()},_getTextHeight:function(e,t){return this.fontSize*t.length*this.lineHeight},_getTextWidth:function(e,t){var n=e.measureText(t[0]||"|").width;for(var r=1,i=t.length;r<i;r++){var s=e.measureText(t[r]).width;s>n&&(n=s)}return n},_renderChars:function(e,t,n,r,i){t[e](n,r,i)},_renderTextLine:function(e,t,n,r,i,s){i-=this.fontSize/4;if(this.textAlign!=="justify"){this._renderChars(e,t,n,r,i,s);return}var o=t.measureText(n).width,u=this.width;if(u>o){var a=n.split(/\s+/),f=t.measureText(n.replace(/\s+/g,"")).width,l=u-f,c=a.length-1,h=l/c,p=0;for(var d=0,v=a.length;d<v;d++)this._renderChars(e,t,a[d],r+p,i,s),p+=t.measureText(a[d]).width+h}else this._renderChars(e,t,n,r,i,s)},_getLeftOffset:function(){return-this.width/2},_getTopOffset:function(){return-this.height/2},_renderTextFill:function(e,t){if(!this.fill&&!this._skipFillStrokeCheck)return;this._boundaries=[];var n=0;for(var r=0,i=t.length;r<i;r++){var s=this._getHeightOfLine(e,r,t);n+=s,this._renderTextLine("fillText",e,t[r],this._getLeftOffset(),this._getTopOffset()+n,r)}this.shadow&&!this.shadow.affectStroke&&this._removeShadow(e)},_renderTextStroke:function(e,t){if((!this.stroke||this.strokeWidth===0)&&!this._skipFillStrokeCheck)return;var n=0;e.save(),this.strokeDashArray&&(1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray),s&&e.setLineDash(this.strokeDashArray)),e.beginPath();for(var r=0,i=t.length;r<i;r++){var o=this._getHeightOfLine(e,r,t);n+=o,this._renderTextLine("strokeText",e,t[r],this._getLeftOffset(),this._getTopOffset()+n,r)}e.closePath(),e.restore()},_getHeightOfLine:function(){return this.fontSize*this.lineHeight},_renderTextBackground:function(e,t){this._renderTextBoxBackground(e),this._renderTextLinesBackground(e,t)},_renderTextBoxBackground:function(e){if(!this.backgroundColor)return;e.save(),e.fillStyle=this.backgroundColor,e.fillRect(this._getLeftOffset(),this._getTopOffset(),this.width,this.height),e.restore()},_renderTextLinesBackground:function(e,t){if(!this.textBackgroundColor)return;e.save(),e.fillStyle=this.textBackgroundColor;for(var n=0,r=t.length;n<r;n++)if(t[n]!==""){var i=this._getLineWidth(e,t[n]),s=this._getLineLeftOffset(i);e.fillRect(this._getLeftOffset()+s,this._getTopOffset()+n*this.fontSize*this.lineHeight,i,this.fontSize*this.lineHeight)}e.restore()},_getLineLeftOffset:function(e){return this.textAlign==="center"?(this.width-e)/2:this.textAlign==="right"?this.width-e:0},_getLineWidth:function(e,t){return this.textAlign==="justify"?this.width:e.measureText(t).width},_renderTextDecoration:function(e,t){function i(i){for(var s=0,o=t.length;s<o;s++){var u=r._getLineWidth(e,t[s]),a=r._getLineLeftOffset(u);e.fillRect(r._getLeftOffset()+a,~~(i+s*r._getHeightOfLine(e,s,t)-n),u,1)}}if(!this.textDecoration)return;var n=this._getTextHeight(e,t)/2,r=this;this.textDecoration.indexOf("underline")>-1&&i(this.fontSize*this.lineHeight),this.textDecoration.indexOf("line-through")>-1&&i(this.fontSize*this.lineHeight-this.fontSize/2),this.textDecoration.indexOf("overline")>-1&&i(this.fontSize*this.lineHeight-this.fontSize)},_getFontDeclaration:function(){return[t.isLikelyNode?this.fontWeight:this.fontStyle,t.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",t.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},render:function(e,t){if(!this.visible)return;e.save(),t||this.transform(e);var n=this.group&&this.group.type==="path-group";n&&e.translate(-this.group.width/2,-this.group.height/2),this.transformMatrix&&e.transform.apply(e,this.transformMatrix),n&&e.translate(this.left,this.top),this._render(e),e.restore()},toObject:function(e){var t=n(this.callSuper("toObject",e),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,path:this.path,textBackgroundColor:this.textBackgroundColor,useNative:this.useNative});return this.includeDefaultValues||this._removeDefaultValues(t),t},toSVG:function(e){var t=[],n=this.text.split(this._reNewline),r=this._getSVGLeftTopOffsets(n),i=this._getSVGTextAndBg(r.lineTop,r.textLeft,n),s=this._getSVGShadows(r.lineTop,n);return r.textTop+=this._fontAscent?this._fontAscent/5*this.lineHeight:0,this._wrapSVGTextAndBg(t,i,s,r),e?e(t.join("")):t.join("")},_getSVGLeftTopOffsets:function(e){var t=this.useNative?this.fontSize*this.lineHeight:-this._fontAscent-this._fontAscent/5*this.lineHeight,n=-(this.width/2),r=this.useNative?this.fontSize*this.lineHeight-.25*this.fontSize:this.height/2-e.length*this.fontSize-this._totalLineHeight;return{textLeft:n+(this.group&&this.group.type==="path-group"?this.left:0),textTop:r+(this.group&&this.group.type==="path-group"?this.top:0),lineTop:t}},_wrapSVGTextAndBg:function(e,t,n,r){e.push('<g transform="',this.getSvgTransform(),this.getSvgTransformMatrix(),'">\n',t.textBgRects.join(""),"<text ",this.fontFamily?'font-family="'+this.fontFamily.replace(/"/g,"'")+'" ':"",this.fontSize?'font-size="'+this.fontSize+'" ':"",this.fontStyle?'font-style="'+this.fontStyle+'" ':"",this.fontWeight?'font-weight="'+this.fontWeight+'" ':"",this.textDecoration?'text-decoration="'+this.textDecoration+'" ':"",'style="',this.getSvgStyles(),'" ','transform="translate(',i(r.textLeft,2)," ",i(r.textTop,2),')">',n.join(""),t.textSpans.join(""),"</text>\n","</g>\n")},_getSVGShadows:function(e,n){var r=[],s,o,u=1;if(!this.shadow||!this._boundaries)return r;for(s=0,o=n.length;s<o;s++)if(n[s]!==""){var a=this._boundaries&&this._boundaries[s]?this._boundaries[s].left:0;r.push('<tspan x="',i(a+u+this.shadow.offsetX,2),s===0||this.useNative?'" y':'" dy','="',i(this.useNative?e*s-this.height/2+this.shadow.offsetY:e+(s===0?this.shadow.offsetY:0),2),'" ',this._getFillAttributes(this.shadow.color),">",t.util.string.escapeXml(n[s]),"</tspan>"),u=1}else u++;return r},_getSVGTextAndBg:function(e,t,n){var r=[],i=[],s=1;this._setSVGBg(i);for(var o=0,u=n.length;o<u;o++){n[o]!==""?(this._setSVGTextLineText(n[o],o,r,e,s,i),s=1):s++;if(!this.textBackgroundColor||!this._boundaries)continue;this._setSVGTextLineBg(i,o,t,e)}return{textSpans:r,textBgRects:i}},_setSVGTextLineText:function(e,n,r,s,o){var u=this._boundaries&&this._boundaries[n]?i(this._boundaries[n].left,2):0;r.push('<tspan x="',u,'" ',n===0||this.useNative?"y":"dy",'="',i(this.useNative?s*n-this.height/2:s*o,2),'" ',this._getFillAttributes(this.fill),">",t.util.string.escapeXml(e),"</tspan>")},_setSVGTextLineBg:function(e,t,n,r){e.push("<rect ",this._getFillAttributes(this.textBackgroundColor),' x="',i(n+this._boundaries[t].left,2),'" y="',i(r*t-this.height/2,2),'" width="',i(this._boundaries[t].width,2),'" height="',i(this._boundaries[t].height,2),'"></rect>\n')},_setSVGBg:function(e){this.backgroundColor&&this._boundaries&&e.push("<rect ",this._getFillAttributes(this.backgroundColor),' x="',i(-this.width/2,2),'" y="',i(-this.height/2,2),'" width="',i(this.width,2),'" height="',i(this.height,2),'"></rect>')},_getFillAttributes:function(e){var n=e&&typeof e=="string"?new t.Color(e):"";return!n||!n.getSource()||n.getAlpha()===1?'fill="'+e+'"':'opacity="'+n.getAlpha()+'" fill="'+n.setAlpha(1).toRgb()+'"'},_set:function(e,t){e==="fontFamily"&&this.path&&(this.path=this.path.replace(/(.*?)([^\/]*)(\.font\.js)/,"$1"+t+"$3")),this.callSuper("_set",e,t),e in this._dimensionAffectingProps&&(this._initDimensions(),this.setCoords())},complexity:function(){return 1}}),t.Text.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" ")),t.Text.DEFAULT_SVG_FONT_SIZE=16,t.Text.fromElement=function(e,n){if(!e)return null;var r=t.parseAttributes(e,t.Text.ATTRIBUTE_NAMES);n=t.util.object.extend(n?t.util.object.clone(n):{},r),n.top=n.top||0,n.left=n.left||0,"dx"in r&&(n.left+=r.dx),"dy"in r&&(n.top+=r.dy),"fontSize"in n||(n.fontSize=t.Text.DEFAULT_SVG_FONT_SIZE),n.originX||(n.originX="left"),n.top+=n.fontSize/4;var i=new t.Text(e.textContent,n),s=0;return i.originX==="left"&&(s=i.getWidth()/2),i.originX==="right"&&(s=-i.getWidth()/2),i.set({left:i.getLeft()+s,top:i.getTop()-i.getHeight()/2}),i},t.Text.fromObject=function(e){return new t.Text(e.text,r(e))},t.util.createAccessors(t.Text)}(typeof exports!="undefined"?exports:this),function(){var e=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:!1,editable:!0,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,styles:null,caching:!0,_skipFillStrokeCheck:!0,_reSpace:/\s|\n/,_fontSizeFraction:4,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:!1,_charWidthsCache:{},initialize:function(e,t){this.styles=t?t.styles||{}:{},this.callSuper("initialize",e,t),this.initBehavior(),fabric.IText.instances.push(this),this.__lineWidths={},this.__lineHeights={},this.__lineOffsets={}},isEmptyStyles:function(){if(!this.styles)return!0;var e=this.styles;for(var t in e)for(var n in e[t])for(var r in e[t][n])return!1;return!0},setSelectionStart:function(e){this.selectionStart!==e&&(this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})),this.selectionStart=e,this.hiddenTextarea&&(this.hiddenTextarea.selectionStart=e)},setSelectionEnd:function(e){this.selectionEnd!==e&&(this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})),this.selectionEnd=e,this.hiddenTextarea&&(this.hiddenTextarea.selectionEnd=e)},getSelectionStyles:function(e,t){if(arguments.length===2){var n=[];for(var r=e;r<t;r++)n.push(this.getSelectionStyles(r));return n}var i=this.get2DCursorLocation(e);return this.styles[i.lineIndex]?this.styles[i.lineIndex][i.charIndex]||{}:{}},setSelectionStyles:function(e){if(this.selectionStart===this.selectionEnd)this._extendStyles(this.selectionStart,e);else for(var t=this.selectionStart;t<this.selectionEnd;t++)this._extendStyles(t,e);return this},_extendStyles:function(e,t){var n=this.get2DCursorLocation(e);this.styles[n.lineIndex]||(this.styles[n.lineIndex]={}),this.styles[n.lineIndex][n.charIndex]||(this.styles[n.lineIndex][n.charIndex]={}),fabric.util.object.extend(this.styles[n.lineIndex][n.charIndex],t)},_render:function(e){this.callSuper("_render",e),this.ctx=e,this.isEditing&&this.renderCursorOrSelection()},renderCursorOrSelection:function(){if(!this.active)return;var e=this.text.split(""),t;this.selectionStart===this.selectionEnd?(t=this._getCursorBoundaries(e,"cursor"),this.renderCursor(t)):(t=this._getCursorBoundaries(e,"selection"),this.renderSelection(e,t))},get2DCursorLocation:function(e){typeof e=="undefined"&&(e=this.selectionStart);var t=this.text.slice(0,e),n=t.split(this._reNewline);return{lineIndex:n.length-1,charIndex:n[n.length-1].length}},getCurrentCharStyle:function(e,t){var n=this.styles[e]&&this.styles[e][t===0?0:t-1];return{fontSize:n&&n.fontSize||this.fontSize,fill:n&&n.fill||this.fill,textBackgroundColor:n&&n.textBackgroundColor||this.textBackgroundColor,textDecoration:n&&n.textDecoration||this.textDecoration,fontFamily:n&&n.fontFamily||this.fontFamily,fontWeight:n&&n.fontWeight||this.fontWeight,fontStyle:n&&n.fontStyle||this.fontStyle,stroke:n&&n.stroke||this.stroke,strokeWidth:n&&n.strokeWidth||this.strokeWidth}},getCurrentCharFontSize:function(e,t){return this.styles[e]&&this.styles[e][t===0?0:t-1]&&this.styles[e][t===0?0:t-1].fontSize||this.fontSize},getCurrentCharColor:function(e,t){return this.styles[e]&&this.styles[e][t===0?0:t-1]&&this.styles[e][t===0?0:t-1].fill||this.cursorColor},_getCursorBoundaries:function(e,t){var n=this.get2DCursorLocation(),r=this.text.split(this._reNewline),i=Math.round(this._getLeftOffset()),s=this._getTopOffset(),o=this._getCursorBoundariesOffsets(e,t,n,r);return{left:i,top:s,leftOffset:o.left+o.lineLeft,topOffset:o.top}},_getCursorBoundariesOffsets:function(e,t,n,r){var i=0,s=0,o=0,u=0,a=t==="cursor"?this._getHeightOfLine(this.ctx,0)-this.getCurrentCharFontSize(n.lineIndex,n.charIndex):0;for(var f=0;f<this.selectionStart;f++){if(e[f]==="\n"){u=0;var l=s+(t==="cursor"?1:0);a+=this._getCachedLineHeight(l),s++,o=0}else u+=this._getWidthOfChar(this.ctx,e[f],s,o),o++;i=this._getCachedLineOffset(s,r)}return this._clearCache(),{top:a,left:u,lineLeft:i}},_clearCache:function(){this.__lineWidths={},this.__lineHeights={},this.__lineOffsets={}},_getCachedLineHeight:function(e){return this.__lineHeights[e]||(this.__lineHeights[e]=this._getHeightOfLine(this.ctx,e))},_getCachedLineWidth:function(e,t){return this.__lineWidths[e]||(this.__lineWidths[e]=this._getWidthOfLine(this.ctx,e,t))},_getCachedLineOffset:function(e,t){var n=this._getCachedLineWidth(e,t);return this.__lineOffsets[e]||(this.__lineOffsets[e]=this._getLineLeftOffset(n))},renderCursor:function(e){var t=this.ctx;t.save();var n=this.get2DCursorLocation(),r=n.lineIndex,i=n.charIndex,s=this.getCurrentCharFontSize(r,i),o=r===0&&i===0?this._getCachedLineOffset(r,this.text.split(this._reNewline)):e.leftOffset;t.fillStyle=this.getCurrentCharColor(r,i),t.globalAlpha=this.__isMousedown?1:this._currentCursorOpacity,t.fillRect(e.left+o,e.top+e.topOffset,this.cursorWidth/this.scaleX,s),t.restore()},renderSelection:function(e,t){var n=this.ctx;n.save(),n.fillStyle=this.selectionColor;var r=this.get2DCursorLocation(this.selectionStart +),i=this.get2DCursorLocation(this.selectionEnd),s=r.lineIndex,o=i.lineIndex,u=this.text.split(this._reNewline);for(var a=s;a<=o;a++){var f=this._getCachedLineOffset(a,u)||0,l=this._getCachedLineHeight(a),c=0;if(a===s)for(var h=0,p=u[a].length;h<p;h++)h>=r.charIndex&&(a!==o||h<i.charIndex)&&(c+=this._getWidthOfChar(n,u[a][h],a,h)),h<r.charIndex&&(f+=this._getWidthOfChar(n,u[a][h],a,h));else if(a>s&&a<o)c+=this._getCachedLineWidth(a,u)||5;else if(a===o)for(var d=0,v=i.charIndex;d<v;d++)c+=this._getWidthOfChar(n,u[a][d],a,d);n.fillRect(t.left+f,t.top+t.topOffset,c,l),t.topOffset+=l}n.restore()},_renderChars:function(e,t,n,r,i,s){if(this.isEmptyStyles())return this._renderCharsFast(e,t,n,r,i);this.skipTextAlign=!0,r-=this.textAlign==="center"?this.width/2:this.textAlign==="right"?this.width:0;var o=this.text.split(this._reNewline),u=this._getWidthOfLine(t,s,o),a=this._getHeightOfLine(t,s,o),f=this._getLineLeftOffset(u),l=n.split(""),c,h="";r+=f||0,t.save();for(var p=0,d=l.length;p<=d;p++){c=c||this.getCurrentCharStyle(s,p);var v=this.getCurrentCharStyle(s,p+1);if(this._hasStyleChanged(c,v)||p===d)this._renderChar(e,t,s,p-1,h,r,i,a),h="",c=v;h+=l[p]}t.restore()},_renderCharsFast:function(e,t,n,r,i){this.skipTextAlign=!1,e==="fillText"&&this.fill&&this.callSuper("_renderChars",e,t,n,r,i),e==="strokeText"&&this.stroke&&this.callSuper("_renderChars",e,t,n,r,i)},_renderChar:function(e,t,n,r,i,s,o,u){var a,f,l;if(this.styles&&this.styles[n]&&(a=this.styles[n][r])){var c=a.stroke||this.stroke,h=a.fill||this.fill;t.save(),f=this._applyCharStylesGetWidth(t,i,n,r,a),l=this._getHeightOfChar(t,i,n,r),h&&t.fillText(i,s,o),c&&t.strokeText(i,s,o),this._renderCharDecoration(t,a,s,o,f,u,l),t.restore(),t.translate(f,0)}else e==="strokeText"&&this.stroke&&t[e](i,s,o),e==="fillText"&&this.fill&&t[e](i,s,o),f=this._applyCharStylesGetWidth(t,i,n,r),this._renderCharDecoration(t,null,s,o,f,u),t.translate(t.measureText(i).width,0)},_hasStyleChanged:function(e,t){return e.fill!==t.fill||e.fontSize!==t.fontSize||e.textBackgroundColor!==t.textBackgroundColor||e.textDecoration!==t.textDecoration||e.fontFamily!==t.fontFamily||e.fontWeight!==t.fontWeight||e.fontStyle!==t.fontStyle||e.stroke!==t.stroke||e.strokeWidth!==t.strokeWidth},_renderCharDecoration:function(e,t,n,r,i,s,o){var u=t?t.textDecoration||this.textDecoration:this.textDecoration,a=(t?t.fontSize:null)||this.fontSize;if(!u)return;u.indexOf("underline")>-1&&this._renderCharDecorationAtOffset(e,n,r+this.fontSize/this._fontSizeFraction,i,0,this.fontSize/20),u.indexOf("line-through")>-1&&this._renderCharDecorationAtOffset(e,n,r+this.fontSize/this._fontSizeFraction,i,o/2,a/20),u.indexOf("overline")>-1&&this._renderCharDecorationAtOffset(e,n,r,i,s-this.fontSize/this._fontSizeFraction,this.fontSize/20)},_renderCharDecorationAtOffset:function(e,t,n,r,i,s){e.fillRect(t,n-i,r,s)},_renderTextLine:function(e,t,n,r,i,s){i+=this.fontSize/4,this.callSuper("_renderTextLine",e,t,n,r,i,s)},_renderTextDecoration:function(e,t){if(this.isEmptyStyles())return this.callSuper("_renderTextDecoration",e,t)},_renderTextLinesBackground:function(e,t){if(!this.textBackgroundColor&&!this.styles)return;e.save(),this.textBackgroundColor&&(e.fillStyle=this.textBackgroundColor);var n=0,r=this.fontSize/this._fontSizeFraction;for(var i=0,s=t.length;i<s;i++){var o=this._getHeightOfLine(e,i,t);if(t[i]===""){n+=o;continue}var u=this._getWidthOfLine(e,i,t),a=this._getLineLeftOffset(u);this.textBackgroundColor&&(e.fillStyle=this.textBackgroundColor,e.fillRect(this._getLeftOffset()+a,this._getTopOffset()+n+r,u,o));if(this.styles[i])for(var f=0,l=t[i].length;f<l;f++)if(this.styles[i]&&this.styles[i][f]&&this.styles[i][f].textBackgroundColor){var c=t[i][f];e.fillStyle=this.styles[i][f].textBackgroundColor,e.fillRect(this._getLeftOffset()+a+this._getWidthOfCharsAt(e,i,f,t),this._getTopOffset()+n+r,this._getWidthOfChar(e,c,i,f,t)+1,o)}n+=o}e.restore()},_getCacheProp:function(e,t){return e+t.fontFamily+t.fontSize+t.fontWeight+t.fontStyle+t.shadow},_applyCharStylesGetWidth:function(t,n,r,i,s){var o=s||this.styles[r]&&this.styles[r][i];o?o=e(o):o={},this._applyFontStyles(o);var u=this._getCacheProp(n,o);if(this.isEmptyStyles()&&this._charWidthsCache[u]&&this.caching)return this._charWidthsCache[u];typeof o.shadow=="string"&&(o.shadow=new fabric.Shadow(o.shadow));var a=o.fill||this.fill;return t.fillStyle=a.toLive?a.toLive(t):a,o.stroke&&(t.strokeStyle=o.stroke&&o.stroke.toLive?o.stroke.toLive(t):o.stroke),t.lineWidth=o.strokeWidth||this.strokeWidth,t.font=this._getFontDeclaration.call(o),this._setShadow.call(o,t),this.caching?(this._charWidthsCache[u]||(this._charWidthsCache[u]=t.measureText(n).width),this._charWidthsCache[u]):t.measureText(n).width},_applyFontStyles:function(e){e.fontFamily||(e.fontFamily=this.fontFamily),e.fontSize||(e.fontSize=this.fontSize),e.fontWeight||(e.fontWeight=this.fontWeight),e.fontStyle||(e.fontStyle=this.fontStyle)},_getStyleDeclaration:function(t,n){return this.styles[t]&&this.styles[t][n]?e(this.styles[t][n]):{}},_getWidthOfChar:function(e,t,n,r){if(this.textAlign==="justify"&&/\s/.test(t))return this._getWidthOfSpace(e,n);var i=this._getStyleDeclaration(n,r);this._applyFontStyles(i);var s=this._getCacheProp(t,i);if(this._charWidthsCache[s]&&this.caching)return this._charWidthsCache[s];if(e){e.save();var o=this._applyCharStylesGetWidth(e,t,n,r);return e.restore(),o}},_getHeightOfChar:function(e,t,n,r){return this.styles[n]&&this.styles[n][r]?this.styles[n][r].fontSize||this.fontSize:this.fontSize},_getWidthOfCharAt:function(e,t,n,r){r=r||this.text.split(this._reNewline);var i=r[t].split("")[n];return this._getWidthOfChar(e,i,t,n)},_getHeightOfCharAt:function(e,t,n,r){r=r||this.text.split(this._reNewline);var i=r[t].split("")[n];return this._getHeightOfChar(e,i,t,n)},_getWidthOfCharsAt:function(e,t,n,r){var i=0;for(var s=0;s<n;s++)i+=this._getWidthOfCharAt(e,t,s,r);return i},_getWidthOfLine:function(e,t,n){return this._getWidthOfCharsAt(e,t,n[t].length,n)},_getWidthOfSpace:function(e,t){var n=this.text.split(this._reNewline),r=n[t],i=r.split(/\s+/),s=this._getWidthOfWords(e,r,t),o=this.width-s,u=i.length-1,a=o/u;return a},_getWidthOfWords:function(e,t,n){var r=0;for(var i=0;i<t.length;i++){var s=t[i];s.match(/\s/)||(r+=this._getWidthOfChar(e,s,n,i))}return r},_getTextWidth:function(e,t){if(this.isEmptyStyles())return this.callSuper("_getTextWidth",e,t);var n=this._getWidthOfLine(e,0,t);for(var r=1,i=t.length;r<i;r++){var s=this._getWidthOfLine(e,r,t);s>n&&(n=s)}return n},_getHeightOfLine:function(e,t,n){n=n||this.text.split(this._reNewline);var r=this._getHeightOfChar(e,n[t][0],t,0),i=n[t],s=i.split("");for(var o=1,u=s.length;o<u;o++){var a=this._getHeightOfChar(e,s[o],t,o);a>r&&(r=a)}return r*this.lineHeight},_getTextHeight:function(e,t){var n=0;for(var r=0,i=t.length;r<i;r++)n+=this._getHeightOfLine(e,r,t);return n},_getTopOffset:function(){var e=fabric.Text.prototype._getTopOffset.call(this);return e-this.fontSize/this._fontSizeFraction},_renderTextBoxBackground:function(e){if(!this.backgroundColor)return;e.save(),e.fillStyle=this.backgroundColor,e.fillRect(this._getLeftOffset(),this._getTopOffset()+this.fontSize/this._fontSizeFraction,this.width,this.height),e.restore()},toObject:function(t){return fabric.util.object.extend(this.callSuper("toObject",t),{styles:e(this.styles)})}}),fabric.IText.fromObject=function(t){return new fabric.IText(t.text,e(t))},fabric.IText.instances=[]}(),function(){var e=fabric.util.object.clone;fabric.util.object.extend(fabric.IText.prototype,{initBehavior:function(){this.initAddedHandler(),this.initCursorSelectionHandlers(),this.initDoubleClickSimulation()},initSelectedHandler:function(){this.on("selected",function(){var e=this;setTimeout(function(){e.selected=!0},100)})},initAddedHandler:function(){this.on("added",function(){this.canvas&&!this.canvas._hasITextHandlers&&(this.canvas._hasITextHandlers=!0,this._initCanvasHandlers())})},_initCanvasHandlers:function(){this.canvas.on("selection:cleared",function(){fabric.IText.prototype.exitEditingOnOthers.call()}),this.canvas.on("mouse:up",function(){fabric.IText.instances.forEach(function(e){e.__isMousedown=!1})}),this.canvas.on("object:selected",function(e){fabric.IText.prototype.exitEditingOnOthers.call(e.target)})},_tick:function(){if(this._abortCursorAnimation)return;var e=this;this.animate("_currentCursorOpacity",1,{duration:this.cursorDuration,onComplete:function(){e._onTickComplete()},onChange:function(){e.canvas&&e.canvas.renderAll()},abort:function(){return e._abortCursorAnimation}})},_onTickComplete:function(){if(this._abortCursorAnimation)return;var e=this;this._cursorTimeout1&&clearTimeout(this._cursorTimeout1),this._cursorTimeout1=setTimeout(function(){e.animate("_currentCursorOpacity",0,{duration:this.cursorDuration/2,onComplete:function(){e._tick()},onChange:function(){e.canvas&&e.canvas.renderAll()},abort:function(){return e._abortCursorAnimation}})},100)},initDelayedCursor:function(e){var t=this,n=e?0:this.cursorDelay;e&&(this._abortCursorAnimation=!0,clearTimeout(this._cursorTimeout1),this._currentCursorOpacity=1,this.canvas&&this.canvas.renderAll()),this._cursorTimeout2&&clearTimeout(this._cursorTimeout2),this._cursorTimeout2=setTimeout(function(){t._abortCursorAnimation=!1,t._tick()},n)},abortCursorAnimation:function(){this._abortCursorAnimation=!0,clearTimeout(this._cursorTimeout1),clearTimeout(this._cursorTimeout2),this._currentCursorOpacity=0,this.canvas&&this.canvas.renderAll();var e=this;setTimeout(function(){e._abortCursorAnimation=!1},10)},selectAll:function(){this.selectionStart=0,this.selectionEnd=this.text.length,this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},getSelectedText:function(){return this.text.slice(this.selectionStart,this.selectionEnd)},findWordBoundaryLeft:function(e){var t=0,n=e-1;if(this._reSpace.test(this.text.charAt(n)))while(this._reSpace.test(this.text.charAt(n)))t++,n--;while(/\S/.test(this.text.charAt(n))&&n>-1)t++,n--;return e-t},findWordBoundaryRight:function(e){var t=0,n=e;if(this._reSpace.test(this.text.charAt(n)))while(this._reSpace.test(this.text.charAt(n)))t++,n++;while(/\S/.test(this.text.charAt(n))&&n<this.text.length)t++,n++;return e+t},findLineBoundaryLeft:function(e){var t=0,n=e-1;while(!/\n/.test(this.text.charAt(n))&&n>-1)t++,n--;return e-t},findLineBoundaryRight:function(e){var t=0,n=e;while(!/\n/.test(this.text.charAt(n))&&n<this.text.length)t++,n++;return e+t},getNumNewLinesInSelectedText:function(){var e=this.getSelectedText(),t=0;for(var n=0,r=e.split(""),i=r.length;n<i;n++)r[n]==="\n"&&t++;return t},searchWordBoundary:function(e,t){var n=this._reSpace.test(this.text.charAt(e))?e-1:e,r=this.text.charAt(n),i=/[ \n\.,;!\?\-]/;while(!i.test(r)&&n>0&&n<this.text.length)n+=t,r=this.text.charAt(n);return i.test(r)&&r!=="\n"&&(n+=t===1?0:1),n},selectWord:function(e){var t=this.searchWordBoundary(e,-1),n=this.searchWordBoundary(e,1);this.setSelectionStart(t),this.setSelectionEnd(n),this.initDelayedCursor(!0)},selectLine:function(e){var t=this.findLineBoundaryLeft(e),n=this.findLineBoundaryRight(e);this.setSelectionStart(t),this.setSelectionEnd(n),this.initDelayedCursor(!0)},enterEditing:function(){if(this.isEditing||!this.editable)return;return this.exitEditingOnOthers(),this.isEditing=!0,this.initHiddenTextarea(),this._updateTextarea(),this._saveEditingProps(),this._setEditingProps(),this._tick(),this.canvas&&this.canvas.renderAll(),this.fire("editing:entered"),this.canvas&&this.canvas.fire("text:editing:entered",{target:this}),this},exitEditingOnOthers:function(){fabric.IText.instances.forEach(function(e){e.selected=!1,e.isEditing&&e.exitEditing()},this)},_setEditingProps:function(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0},_updateTextarea:function(){if(!this.hiddenTextarea)return;this.hiddenTextarea.value=this.text,this.hiddenTextarea.selectionStart=this.selectionStart},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){if(!this._savedProps)return;this.hoverCursor=this._savedProps.overCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor)},exitEditing:function(){return this.selected=!1,this.isEditing=!1,this.selectable=!0,this.selectionEnd=this.selectionStart,this.hiddenTextarea&&this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea),this.hiddenTextarea=null,this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this.fire("editing:exited"),this.canvas&&this.canvas.fire("text:editing:exited",{target:this}),this},_removeExtraneousStyles:function(){var e=this.text.split(this._reNewline);for(var t in this.styles)e[t]||delete this.styles[t]},_removeCharsFromTo:function(e,t){var n=t;while(n!==e){var r=this.get2DCursorLocation(n).charIndex;n--;var i=this.get2DCursorLocation(n).charIndex,s=i>r;s?this.removeStyleObject(s,n+1):this.removeStyleObject(this.get2DCursorLocation(n).charIndex===0,n)}this.text=this.text.slice(0,e)+this.text.slice(t)},insertChars:function(e){var t=this.text.slice(this.selectionStart,this.selectionStart+1)==="\n";this.text=this.text.slice(0,this.selectionStart)+e+this.text.slice(this.selectionEnd),this.selectionStart===this.selectionEnd&&this.insertStyleObjects(e,t,this.copiedStyles),this.selectionStart+=e.length,this.selectionEnd=this.selectionStart,this.canvas&&this.canvas.renderAll().renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},insertNewlineStyleObject:function(t,n,r){this.shiftLineStyles(t,1),this.styles[t+1]||(this.styles[t+1]={});var i=this.styles[t][n-1],s={};if(r)s[0]=e(i),this.styles[t+1]=s;else{for(var o in this.styles[t])parseInt(o,10)>=n&&(s[parseInt(o,10)-n]=this.styles[t][o],delete this.styles[t][o]);this.styles[t+1]=s}},insertCharStyleObject:function(t,n,r){var i=this.styles[t],s=e(i);n===0&&!r&&(n=1);for(var o in s){var u=parseInt(o,10);u>=n&&(i[u+1]=s[u])}this.styles[t][n]=r||e(i[n-1])},insertStyleObjects:function(e,t,n){var r=this.get2DCursorLocation(),i=r.lineIndex,s=r.charIndex;this.styles[i]||(this.styles[i]={}),e==="\n"?this.insertNewlineStyleObject(i,s,t):n?this._insertStyles(n):this.insertCharStyleObject(i,s)},_insertStyles:function(e){for(var t=0,n=e.length;t<n;t++){var r=this.get2DCursorLocation(this.selectionStart+t),i=r.lineIndex,s=r.charIndex;this.insertCharStyleObject(i,s,e[t])}},shiftLineStyles:function(t,n){var r=e(this.styles);for(var i in this.styles){var s=parseInt(i,10);s>t&&(this.styles[s+n]=r[s])}},removeStyleObject:function(t,n){var r=this.get2DCursorLocation(n),i=r.lineIndex,s=r.charIndex;if(t){var o=this.text.split(this._reNewline),u=o[i-1],a=u?u.length:0;this.styles[i-1]||(this.styles[i-1]={});for(s in this.styles[i])this.styles[i-1][parseInt(s,10)+a]=this.styles[i][s];this.shiftLineStyles(i,-1)}else{var f=this.styles[i];if(f){var l=this.selectionStart===this.selectionEnd?-1:0;delete f[s+l]}var c=e(f);for(var h in c){var p=parseInt(h,10);p>=s&&p!==0&&(f[p-1]=c[p],delete f[p])}}},insertNewline:function(){this.insertChars("\n")}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+(new Date),this.__lastLastClickTime=+(new Date),this.__lastPointer={},this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(e){this.__newClickTime=+(new Date);var t=this.canvas.getPointer(e.e);this.isTripleClick(t)?(this.fire("tripleclick",e),this._stopEvent(e.e)):this.isDoubleClick(t)&&(this.fire("dblclick",e),this._stopEvent(e.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=t,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected},isDoubleClick:function(e){return this.__newClickTime-this.__lastClickTime<500&&this.__lastPointer.x===e.x&&this.__lastPointer.y===e.y&&this.__lastIsEditing},isTripleClick:function(e){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===e.x&&this.__lastPointer.y===e.y},_stopEvent:function(e){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler(),this.initMousedownHandler(),this.initMousemoveHandler(),this.initMouseupHandler(),this.initClicks()},initClicks:function(){this.on("dblclick",function(e){this.selectWord(this.getSelectionStartFromPointer(e.e))}),this.on("tripleclick",function(e){this.selectLine(this.getSelectionStartFromPointer(e.e))})},initMousedownHandler:function(){this.on("mousedown",function(e){var t=this.canvas.getPointer(e.e);this.__mousedownX=t.x,this.__mousedownY=t.y,this.__isMousedown=!0,this.hiddenTextarea&&this.canvas&&this.canvas.wrapperEl.appendChild(this.hiddenTextarea),this.selected&&this.setCursorByClick(e.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.initDelayedCursor(!0))})},initMousemoveHandler:function(){this.on("mousemove",function(e){if(!this.__isMousedown||!this.isEditing)return;var t=this.getSelectionStartFromPointer(e.e);t>=this.__selectionStartOnMouseDown?(this.setSelectionStart(this.__selectionStartOnMouseDown),this.setSelectionEnd(t)):(this.setSelectionStart(t),this.setSelectionEnd(this.__selectionStartOnMouseDown))})},_isObjectMoved:function(e){var t=this.canvas.getPointer(e);return this.__mousedownX!==t.x||this.__mousedownY!==t.y},initMouseupHandler:function(){this.on("mouseup",function(e){this.__isMousedown=!1;if(this._isObjectMoved(e.e))return;this.__lastSelected&&(this.enterEditing(),this.initDelayedCursor(!0)),this.selected=!0})},setCursorByClick:function(e){var t=this.getSelectionStartFromPointer(e);e.shiftKey?t<this.selectionStart?(this.setSelectionEnd(this.selectionStart),this.setSelectionStart(t)):this.setSelectionEnd(t):(this.setSelectionStart(t),this.setSelectionEnd(t))},_getLocalRotatedPointer:function(e){var t=this.canvas.getPointer(e),n=new fabric.Point(t.x,t.y),r=new fabric.Point(this.left,this.top),i=fabric.util.rotatePoint(n,r,fabric.util.degreesToRadians(-this.angle));return this.getLocalPointer(e,i)},getSelectionStartFromPointer:function(e){var t=this._getLocalRotatedPointer(e),n=this.text.split(this._reNewline),r=0,i=0,s=0,o=0,u;for(var a=0,f=n.length;a<f;a++){s+=this._getHeightOfLine(this.ctx,a)*this.scaleY;var l=this._getWidthOfLine(this.ctx,a,n),c=this._getLineLeftOffset(l);i=c*this.scaleX,this.flipX&&(n[a]=n[a].split("").reverse().join(""));for(var h=0,p=n[a].length;h<p;h++){var d=n[a][h];r=i,i+=this._getWidthOfChar(this.ctx,d,a,this.flipX?p-h:h)*this.scaleX;if(s<=t.y||i<=t.x){o++;continue}return this._getNewSelectionStartFromOffset(t,r,i,o+a,p)}if(t.y<s)return this._getNewSelectionStartFromOffset(t,r,i,o+a,p)}if(typeof u=="undefined")return this.text.length},_getNewSelectionStartFromOffset:function(e,t,n,r,i){var s=e.x-t,o=n-e.x,u=o>s?0:1,a=r+u;return this.flipX&&(a=i-a),a>this.text.length&&(a=this.text.length),a}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.style.cssText="position: fixed; bottom: 20px; left: 0px; opacity: 0; width: 0px; height: 0px; z-index: -999;",fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keypress",this.onKeyPress.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this)),this._clickHandlerInitialized=!0)},_keysMap:{8:"removeChars",9:"exitEditing",27:"exitEditing",13:"insertNewline",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMap:{65:"selectAll",88:"cut"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(e){if(!this.isEditing)return;if(e.keyCode in this._keysMap)this[this._keysMap[e.keyCode]](e);else{if(!(e.keyCode in this._ctrlKeysMap&&(e.ctrlKey||e.metaKey)))return;this[this._ctrlKeysMap[e.keyCode]](e)}e.stopImmediatePropagation(),e.preventDefault(),this.canvas&&this.canvas.renderAll()},forwardDelete:function(e){this.selectionStart===this.selectionEnd&&this.moveCursorRight(e),this.removeChars(e)},copy:function(e){var t=this.getSelectedText(),n=this._getClipboardData(e);n&&n.setData("text",t),this.copiedText=t,this.copiedStyles=this.getSelectionStyles(this.selectionStart,this.selectionEnd)},paste:function(e){var t=null,n=this._getClipboardData(e);n?t=n.getData("text"):t=this.copiedText,t&&this.insertChars(t)},cut:function(e){if(this.selectionStart===this.selectionEnd)return;this.copy(),this.removeChars(e)},_getClipboardData:function(e){return e&&(e.clipboardData||fabric.window.clipboardData)},onKeyPress:function(e){if(!this.isEditing||e.metaKey||e.ctrlKey)return;e.which!==0&&this.insertChars(String.fromCharCode(e.which)),e.stopPropagation()},getDownCursorOffset:function(e,t){var n=t?this.selectionEnd:this.selectionStart,r=this.text.split(this._reNewline),i,s,o=this.text.slice(0,n),u=this.text.slice(n),a=o.slice(o.lastIndexOf("\n")+1),f=u.match(/(.*)\n?/)[1],l=(u.match(/.*\n(.*)\n?/)||{})[1]||"",c=this.get2DCursorLocation(n);if(c.lineIndex===r.length-1||e.metaKey||e.keyCode===34)return this.text.length-n;var h=this._getWidthOfLine(this.ctx,c.lineIndex,r);s=this._getLineLeftOffset(h);var p=s,d=c.lineIndex;for(var v=0,m=a.length;v<m;v++)i=a[v],p+=this._getWidthOfChar(this.ctx,i,d,v);var g=this._getIndexOnNextLine(c,l,p,r);return f.length+1+g},_getIndexOnNextLine:function(e,t,n,r){var i=e.lineIndex+1,s=this._getWidthOfLine(this.ctx,i,r),o=this._getLineLeftOffset(s),u=o,a=0,f;for(var l=0,c=t.length;l<c;l++){var h=t[l],p=this._getWidthOfChar(this.ctx,h,i,l);u+=p;if(u>n){f=!0;var d=u-p,v=u,m=Math.abs(d-n),g=Math.abs(v-n);a=g<m?l+1:l;break}}return f||(a=t.length),a},moveCursorDown:function(e){this.abortCursorAnimation(),this._currentCursorOpacity=1;var t=this.getDownCursorOffset(e,this._selectionDirection==="right");e.shiftKey?this.moveCursorDownWithShift(t):this.moveCursorDownWithoutShift(t),this.initDelayedCursor()},moveCursorDownWithoutShift:function(e){this._selectionDirection="right",this.selectionStart+=e,this.selectionStart>this.text.length&&(this.selectionStart=this.text.length),this.selectionEnd=this.selectionStart,this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},swapSelectionPoints:function(){var e=this.selectionEnd;this.selectionEnd=this.selectionStart,this.selectionStart=e},moveCursorDownWithShift:function(e){this.selectionEnd===this.selectionStart&&(this._selectionDirection="right");var t=this._selectionDirection==="right"?"selectionEnd":"selectionStart";this[t]+=e,this.selectionEnd<this.selectionStart&&this._selectionDirection==="left"&&(this.swapSelectionPoints(),this._selectionDirection="right"),this.selectionEnd>this.text.length&&(this.selectionEnd=this.text.length),this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},getUpCursorOffset:function(e,t){var n=t?this.selectionEnd:this.selectionStart,r=this.get2DCursorLocation(n);if(r.lineIndex===0||e.metaKey||e.keyCode===33)return n;var i=this.text.slice(0,n),s=i.slice(i.lastIndexOf("\n")+1),o=(i.match(/\n?(.*)\n.*$/)||{})[1]||"",u=this.text.split(this._reNewline),a,f=this._getWidthOfLine(this.ctx,r.lineIndex,u),l=this._getLineLeftOffset(f),c=l,h=r.lineIndex;for(var p=0,d=s.length;p<d;p++)a=s[p],c+=this._getWidthOfChar(this.ctx,a,h,p);var v=this._getIndexOnPrevLine(r,o,c,u);return o.length-v+s.length},_getIndexOnPrevLine:function(e,t,n,r){var i=e.lineIndex-1,s=this._getWidthOfLine(this.ctx,i,r),o=this._getLineLeftOffset(s),u=o,a=0,f;for(var l=0,c=t.length;l<c;l++){var h=t[l],p=this._getWidthOfChar(this.ctx,h,i,l);u+=p;if(u>n){f=!0;var d=u-p,v=u,m=Math.abs(d-n),g=Math.abs(v-n);a=g<m?l:l-1;break}}return f||(a=t.length-1),a},moveCursorUp:function(e){this.abortCursorAnimation(),this._currentCursorOpacity=1;var t=this.getUpCursorOffset(e,this._selectionDirection==="right");e.shiftKey?this.moveCursorUpWithShift(t):this.moveCursorUpWithoutShift(t),this.initDelayedCursor()},moveCursorUpWithShift:function(e){this.selectionEnd===this.selectionStart&&(this._selectionDirection="left");var t=this._selectionDirection==="right"?"selectionEnd":"selectionStart";this[t]-=e,this.selectionEnd<this.selectionStart&&this._selectionDirection==="right"&&(this.swapSelectionPoints(),this._selectionDirection="left"),this.selectionStart<0&&(this.selectionStart=0),this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},moveCursorUpWithoutShift:function(e){this.selectionStart===this.selectionEnd&&(this.selectionStart-=e),this.selectionStart<0&&(this.selectionStart=0),this.selectionEnd=this.selectionStart,this._selectionDirection="left",this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},moveCursorLeft:function(e){if(this.selectionStart===0&&this.selectionEnd===0)return;this.abortCursorAnimation(),this._currentCursorOpacity=1,e.shiftKey?this.moveCursorLeftWithShift(e):this.moveCursorLeftWithoutShift(e),this.initDelayedCursor()},_move:function(e,t,n){e.altKey?this[t]=this["findWordBoundary"+n](this[t]):e.metaKey||e.keyCode===35||e.keyCode===36?this[t]=this["findLineBoundary"+n](this[t]):this[t]+=n==="Left"?-1:1},_moveLeft:function(e,t){this._move(e,t,"Left")},_moveRight:function(e,t){this._move(e,t,"Right")},moveCursorLeftWithoutShift:function(e){this._selectionDirection="left",this.selectionEnd===this.selectionStart&&this._moveLeft(e,"selectionStart"),this.selectionEnd=this.selectionStart,this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},moveCursorLeftWithShift:function(e){this._selectionDirection==="right"&&this.selectionStart!==this.selectionEnd?this._moveLeft(e,"selectionEnd"):(this._selectionDirection="left",this._moveLeft(e,"selectionStart"),this.text.charAt(this.selectionStart)==="\n"&&this.selectionStart--,this.selectionStart<0&&(this.selectionStart=0)),this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},moveCursorRight:function(e){if(this.selectionStart>=this.text.length&&this.selectionEnd>=this.text.length)return;this.abortCursorAnimation(),this._currentCursorOpacity=1,e.shiftKey?this.moveCursorRightWithShift(e):this.moveCursorRightWithoutShift(e),this.initDelayedCursor()},moveCursorRightWithShift:function(e){this._selectionDirection==="left"&&this.selectionStart!==this.selectionEnd?this._moveRight(e,"selectionStart"):(this._selectionDirection="right",this._moveRight(e,"selectionEnd"),this.text.charAt(this.selectionEnd-1)==="\n"&&this.selectionEnd++,this.selectionEnd>this.text.length&&(this.selectionEnd=this.text.length)),this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},moveCursorRightWithoutShift:function(e){this._selectionDirection="right",this.selectionStart===this.selectionEnd?(this._moveRight(e,"selectionStart"),this.selectionEnd=this.selectionStart):(this.selectionEnd+=this.getNumNewLinesInSelectedText(),this.selectionEnd>this.text.length&&(this.selectionEnd=this.text.length),this.selectionStart=this.selectionEnd),this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this})},removeChars:function(e){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(e):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.selectionEnd=this.selectionStart,this._removeExtraneousStyles(),this.canvas&&this.canvas.renderAll().renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(e){if(this.selectionStart!==0)if(e.metaKey){var t=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(t,this.selectionStart),this.selectionStart=t}else if(e.altKey){var n=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(n,this.selectionStart),this.selectionStart=n}else{var r=this.text.slice(this.selectionStart-1,this.selectionStart)==="\n";this.removeStyleObject(r),this.selectionStart--,this.text=this.text.slice(0,this.selectionStart)+this.text.slice(this.selectionStart+1)}}}),fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(e,t,n,r,i,s){this.styles[t]?this._setSVGTextLineChars(e,t,n,r,i,s):this.callSuper("_setSVGTextLineText",e,t,n,r,i)},_setSVGTextLineChars:function(e,t,n,r,i,s){var o=t===0||this.useNative?"y":"dy",u=e.split(""),a=0,f=this._getSVGLineLeftOffset(t),l=this._getSVGLineTopOffset(t),c=this._getHeightOfLine(this.ctx,t);for(var h=0,p=u.length;h<p;h++){var d=this.styles[t][h]||{};n.push(this._createTextCharSpan(u[h],d,f,l,o,a));var v=this._getWidthOfChar(this.ctx,u[h],t,h);d.textBackgroundColor&&s.push(this._createTextCharBg(d,f,l,c,v,a)),a+=v}},_getSVGLineLeftOffset:function(e){return this._boundaries&&this._boundaries[e]?fabric.util.toFixed(this._boundaries[e].left,2):0},_getSVGLineTopOffset:function(e){var t=0;for(var n=0;n<=e;n++)t+=this._getHeightOfLine(this.ctx,n);return t-this.height/2},_createTextCharBg:function(e,t,n,r,i,s){return['<rect fill="',e.textBackgroundColor,'" transform="translate(',-this.width/2," ",-this.height+r,")",'" x="',t+s,'" y="',n+r,'" width="',i,'" height="',r,'"></rect>'].join("")},_createTextCharSpan:function(e,t,n,r,i,s){var o=this.getSvgStyles.call(fabric.util.object.extend({visible:!0,fill:this.fill,stroke:this.stroke,type:"text"},t));return['<tspan x="',n+s,'" ',i,'="',r,'" ',t.fontFamily?'font-family="'+t.fontFamily.replace(/"/g,"'")+'" ':"",t.fontSize?'font-size="'+t.fontSize+'" ':"",t.fontStyle?'font-style="'+t.fontStyle+'" ':"",t.fontWeight?'font-weight="'+t.fontWeight+'" ':"",t.textDecoration?'text-decoration="'+t.textDecoration+'" ':"",'style="',o,'">',fabric.util.string.escapeXml(e),"</tspan>"].join("")}}),function(){function request(e,t,n){var r=URL.parse(e);r.port||(r.port=r.protocol.indexOf("https:")===0?443:80);var i=r.port===443?HTTPS:HTTP,s=i.request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(e){var r="";t&&e.setEncoding(t),e.on("end",function(){n(r)}),e.on("data",function(t){e.statusCode===200&&(r+=t)})});s.on("error",function(e){e.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+r.hostname+":"+r.port):fabric.log(e.message)}),s.end()}function requestFs(e,t){var n=require("fs");n.readFile(e,function(e,n){if(e)throw fabric.log(e),e;t(n)})}if(typeof document!="undefined"&&typeof window!="undefined")return;var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;fabric.util.loadImage=function(e,t,n){function r(r){i.src=new Buffer(r,"binary"),i._src=e,t&&t.call(n,i)}var i=new Image;e&&(e instanceof Buffer||e.indexOf("data")===0)?(i.src=i._src=e,t&&t.call(n,i)):e&&e.indexOf("http")!==0?requestFs(e,r):e?request(e,"binary",r):t&&t.call(n,e)},fabric.loadSVGFromURL=function(e,t,n){e=e.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),e.indexOf("http")!==0?requestFs(e,function(e){fabric.loadSVGFromString(e.toString(),t,n)}):request(e,"",function(e){fabric.loadSVGFromString(e,t,n)})},fabric.loadSVGFromString=function(e,t,n){var r=(new DOMParser).parseFromString(e);fabric.parseSVGDocument(r.documentElement,function(e,n){t&&t(e,n)},n)},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.Image.fromObject=function(e,t){fabric.util.loadImage(e.src,function(n){var r=new fabric.Image(n);r._initConfig(e),r._initFilters(e,function(e){r.filters=e||[],t&&t(r)})})},fabric.createCanvasForNode=function( +e,t,n,r){r=r||n;var i=fabric.document.createElement("canvas"),s=new Canvas(e||600,t||600,r);i.style={},i.width=s.width,i.height=s.height;var o=fabric.Canvas||fabric.StaticCanvas,u=new o(i,n);return u.contextContainer=s.getContext("2d"),u.nodeCanvas=s,u.Font=Canvas.Font,u},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(e){return this.nodeCanvas.createJPEGStream(e)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(e,t){return origSetWidth.call(this,e,t),this.nodeCanvas.width=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth);var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(e,t){return origSetHeight.call(this,e,t),this.nodeCanvas.height=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight)}(); \ No newline at end of file diff --git a/js/redactor-fonts.js b/js/redactor-fonts.js deleted file mode 100644 index 021ca561d63b28bd5e38b8c4f1c4ef8bdc6bfe57..0000000000000000000000000000000000000000 --- a/js/redactor-fonts.js +++ /dev/null @@ -1,187 +0,0 @@ -if (!RedactorPlugins) var RedactorPlugins = {}; - -RedactorPlugins.fontfamily = { - init: function () - { - var fonts = [ 'Arial', 'Helvetica', 'Georgia', 'Times New Roman', __('Monospace') ]; - var that = this; - var dropdown = {}; - - $.each(fonts, function(i, s) - { - dropdown['s' + i] = { title: '<span style="font-family:'+s+';">'+s+'</style>', callback: function() { that.setFontfamily(s); }}; - }); - - dropdown['remove'] = { title: 'Remove font', callback: function() { that.resetFontfamily(); }}; - - this.buttonAddBefore('bold', 'fontfamily', __('Change font family'), false, dropdown); - }, - setFontfamily: function (value) - { - this.inlineSetStyle('font-family', value); - }, - resetFontfamily: function() - { - this.inlineRemoveStyle('font-family'); - } -}; - -RedactorPlugins.fontcolor = { - init: function() - { - var colors = [ - '#ffffff', '#000000', '#eeece1', '#1f497d', '#4f81bd', '#c0504d', '#9bbb59', '#8064a2', '#4bacc6', '#f79646', '#ffff00', - '#f2f2f2', '#7f7f7f', '#ddd9c3', '#c6d9f0', '#dbe5f1', '#f2dcdb', '#ebf1dd', '#e5e0ec', '#dbeef3', '#fdeada', '#fff2ca', - '#d8d8d8', '#595959', '#c4bd97', '#8db3e2', '#b8cce4', '#e5b9b7', '#d7e3bc', '#ccc1d9', '#b7dde8', '#fbd5b5', '#ffe694', - '#bfbfbf', '#3f3f3f', '#938953', '#548dd4', '#95b3d7', '#d99694', '#c3d69b', '#b2a2c7', '#b7dde8', '#fac08f', '#f2c314', - '#a5a5a5', '#262626', '#494429', '#17365d', '#366092', '#953734', '#76923c', '#5f497a', '#92cddc', '#e36c09', '#c09100', - '#7f7f7f', '#0c0c0c', '#1d1b10', '#0f243e', '#244061', '#632423', '#4f6128', '#3f3151', '#31859b', '#974806', '#7f6000' - ]; - - var buttons = ['fontcolor', 'backcolor']; - - for (var i = 0; i < 2; i++) - { - var name = buttons[i]; - - var $dropdown = $('<div class="redactor_dropdown redactor_dropdown_box_' + name + '" style="display: none; width: 265px;">'); - - this.pickerBuild($dropdown, name, colors); - $(this.$toolbar).append($dropdown); - - var btn = this.buttonAddBefore('deleted', name, this.opts.curLang[name], $.proxy(function(btnName, $button, btnObject, e) - { - this.dropdownShow(e, btnName); - - }, this)); - - btn.data('dropdown', $dropdown); - } - }, - pickerBuild: function($dropdown, name, colors) - { - var rule = 'color'; - if (name === 'backcolor') rule = 'background-color'; - - var _self = this; - var onSwatch = function(e) - { - e.preventDefault(); - - var $this = $(this); - _self.pickerSet($this.data('rule'), $this.attr('rel')); - - }; - - var len = colors.length; - for (var z = 0; z < len; z++) - { - var color = colors[z]; - - var $swatch = $('<a rel="' + color + '" data-rule="' + rule +'" href="#" style="float: left; font-size: 0; border: 2px solid #fff; padding: 0; margin: 0; width: 20px; height: 20px;"></a>'); - $swatch.css('background-color', color); - $dropdown.append($swatch); - $swatch.on('click', onSwatch); - } - - var $elNone = $('<a href="#" style="display: block; clear: both; padding: 4px 0; font-size: 11px; line-height: 1;"></a>') - .html(this.opts.curLang.none) - .on('click', function(e) - { - e.preventDefault(); - _self.pickerSet(rule, false); - }); - - $dropdown.append($elNone); - }, - pickerSet: function(rule, type) - { - this.bufferSet(); - - this.$editor.focus(); - this.inlineRemoveStyle(rule); - if (type !== false) this.inlineSetStyle(rule, type); - if (this.opts.air) this.$air.fadeOut(100); - this.sync(); - } -}; - -RedactorPlugins.fontsize = { - init: function() - { - var fonts = [10, 14, 22, 32]; - var that = this; - var dropdown = {}; - - $.each(fonts, function(i, s) - { - dropdown['s' + i] = { - title: '<span style="font-size:'+s+'px">'+s+'px</span>', - callback: function() { that.setFontsize(s); } }; - }); - - dropdown['remove'] = { title: __('Remove font size'), callback: function() { that.resetFontsize(); } }; - - this.buttonAddAfter('formatting', 'fontsize', __('Change font size'), false, dropdown); - }, - setFontsize: function(size) - { - this.inlineSetStyle('font-size', size + 'px'); - }, - resetFontsize: function() - { - this.inlineRemoveStyle('font-size'); - } -}; - -RedactorPlugins.textdirection = { - init: function() - { - var that = this; - var dropdown = {}; - - dropdown.ltr = { title: __('Left to Right'), callback: this.setLtr }; - dropdown.rtl = { title: __('Right to Left'), callback: this.setRtl }; - - var button = this.buttonAdd('textdirection', __('Change Text Direction'), - false, dropdown); - - if (this.opts.direction == 'rtl') - this.setRtl(); - }, - setRtl: function() - { - var c = this.getCurrent(), s = this.getSelection(); - this.bufferSet(); - if (s.type == 'Range' && s.focusNode.nodeName != 'div') { - this.linebreakHack(s); - } - else if (!c) { - var repl = '<div dir="rtl">' + this.get() + '</div>'; - this.set(repl, false); - } - $(this.getCurrent()).attr('dir', 'rtl'); - this.sync(); - }, - setLtr: function() - { - var c = this.getCurrent(), s = this.getSelection(); - this.bufferSet(); - if (s.type == 'Range' && s.focusNode.nodeName != 'div') { - this.linebreakHack(s); - } - else if (!c) { - var repl = '<div dir="ltr">' + this.get() + '</div>'; - this.set(repl, false); - } - $(this.getCurrent()).attr('dir', 'ltr'); - this.sync(); - }, - linebreakHack: function(sel) { - var range = sel.getRangeAt(0); - var wrapper = document.createElement('div'); - wrapper.appendChild(range.extractContents()); - range.insertNode(wrapper); - this.selectionElement(wrapper); - } -}; diff --git a/js/redactor-osticket.js b/js/redactor-osticket.js index cf575f287870c377ac9fb0b1f3bd1cde3a5b85d7..39ffaad3051debd0098e3c67400ebe5a8e405222 100644 --- a/js/redactor-osticket.js +++ b/js/redactor-osticket.js @@ -12,25 +12,27 @@ if (typeof RedactorPlugins === 'undefined') var RedactorPlugins = {}; * uploads. Furthermore, the id of the staff is considered for the drafts, * so one user will not retrieve drafts for another user. */ -RedactorPlugins.draft = { +RedactorPlugins.draft = function() { + return { init: function() { if (!this.opts.draftNamespace) return; - this.opts.changeCallback = this.hideDraftSaved; + this.opts.changeCallback = this.draft.hideDraftSaved; var autosave_url = 'ajax.php/draft/' + this.opts.draftNamespace; if (this.opts.draftObjectId) autosave_url += '.' + this.opts.draftObjectId; this.opts.autosave = this.opts.autoCreateUrl = autosave_url; this.opts.autosaveInterval = 30; - this.opts.autosaveCallback = this.afterUpdateDraft; - this.opts.autosaveErrorCallback = this.autosaveFailed; - this.opts.imageUploadErrorCallback = this.displayError; + this.opts.autosaveCallback = this.draft.afterUpdateDraft; + this.opts.autosaveErrorCallback = this.draft.autosaveFailed; + this.opts.imageUploadErrorCallback = this.draft.displayError; if (this.opts.draftId) { this.opts.autosave = 'ajax.php/draft/'+this.opts.draftId; this.opts.clipboardUploadUrl = this.opts.imageUpload = 'ajax.php/draft/'+this.opts.draftId+'/attach'; + this.autosave.enable(); } else { // Just upload the file. A draft will be created automatically @@ -49,22 +51,26 @@ RedactorPlugins.draft = { this.$toolbar.append(this.$draft_saved); // Add [Delete Draft] button to the toolbar if (this.opts.draftDelete) { - var trash = this.draftDeleteButton = - this.buttonAdd('deleteDraft', __('Delete Draft'), - this.deleteDraft); - this.buttonAwesome('deleteDraft', 'icon-trash'); + var trash = this.draft.deleteButton = + this.button.add('deleteDraft', __('Delete Draft'), + this.draft.deleteDraft); + this.button.setAwesome('deleteDraft', 'icon-trash'); trash.parent().addClass('pull-right'); trash.addClass('delete-draft'); if (!this.opts.draftId) trash.hide(); } + if (this.code.get()) + this.$box.trigger('draft:recovered'); }, - afterUpdateDraft: function(data) { + afterUpdateDraft: function(name, data) { // Slight workaround. Signal the 'keyup' event normally signaled // from typing in the <textarea> - if ($.autoLock && this.opts.draftNamespace == 'ticket.response') { - if (this.get()) - $.autoLock.handleEvent(); + if ($.autoLock + && this.$box.closest('form').find('input[name=lockCode]').val() + && this.code.get() + ) { + $.autoLock.handleEvent(); } // If the draft was created, a draft_id will be sent back — update @@ -75,22 +81,23 @@ RedactorPlugins.draft = { this.opts.clipboardUploadUrl = this.opts.imageUpload = 'ajax.php/draft/'+this.opts.draftId+'/attach'; - if (!this.get()) - this.set(' ', false); + if (!this.code.get()) + this.code.set(' ', false); } // Only show the [Draft Saved] notice if there is content in the // field that has been touched - if (!this.firstSave) { - this.firstSave = true; + if (!this.draft.firstSave) { + this.draft.firstSave = true; // No change yet — dont't show the button return; } - if (data && this.get()) { + if (data && this.code.get()) { this.$draft_saved.show().delay(5000).fadeOut(); } // Show the button if there is a draft to delete if (this.opts.draftId && this.opts.draftDelete) - this.draftDeleteButton.show(); + this.draft.deleteButton.show(); + this.$box.trigger('draft:saved'); }, autosaveFailed: function(error) { if (error.code == 422) @@ -101,6 +108,7 @@ RedactorPlugins.draft = { // Cancel autosave clearInterval(this.autosaveInterval); this.hideDraftSaved(); + this.$box.trigger('draft:failed'); }, displayError: function(json) { @@ -121,17 +129,20 @@ RedactorPlugins.draft = { async: false, success: function() { self.draft_id = self.opts.draftId = undefined; - self.hideDraftSaved(); - self.set(self.opts.draftOriginal || '', false, false); + self.draft.hideDraftSaved(); + self.code.set(self.opts.draftOriginal || '', false, false); self.opts.autosave = self.opts.autoCreateUrl; - self.draftDeleteButton.hide(); - self.firstSave = false; + self.draft.deleteButton.hide(); + self.draft.firstSave = false; + this.$box.trigger('draft:deleted'); } }); } + }; }; -RedactorPlugins.signature = { +RedactorPlugins.signature = function() { + return { init: function() { var $el = $(this.$element.get(0)), inner = $('<div class="inner"></div>'); @@ -195,6 +206,7 @@ RedactorPlugins.signature = { inner.load(url).parent().show(); } + } }; /* Redactor richtext init */ @@ -220,24 +232,29 @@ $(function() { }); var options = $.extend({ 'air': el.hasClass('no-bar'), - 'airButtons': ['formatting', '|', 'bold', 'italic', 'underline', 'deleted', '|', 'unorderedlist', 'orderedlist', 'outdent', 'indent', '|', 'image'], - 'buttons': ['html', '|', 'formatting', '|', 'bold', + 'buttons': el.hasClass('no-bar') + ? ['formatting', '|', 'bold', 'italic', 'underline', 'deleted', '|', 'unorderedlist', 'orderedlist', 'outdent', 'indent', '|', 'image'] + : ['html', '|', 'formatting', '|', 'bold', 'italic', 'underline', 'deleted', '|', 'unorderedlist', 'orderedlist', 'outdent', 'indent', '|', 'image', 'video', 'file', 'table', 'link', '|', 'alignment', '|', 'horizontalrule'], + 'buttonSource': !el.hasClass('no-bar'), 'autoresize': !el.hasClass('no-bar'), 'minHeight': selectedSize, 'focus': false, - 'plugins': [], - 'imageGetJson': 'ajax.php/draft/images/browse', + 'plugins': el.hasClass('no-bar') + ? ['imagepaste','imagemanager','definedlinks'] + : ['imagepaste','imagemanager','imageannotate','table','video','definedlinks'], + 'imageUpload': 'tbd', + 'imageManagerJson': 'ajax.php/draft/images/browse', 'syncBeforeCallback': captureImageSizes, 'linebreaks': true, 'tabFocus': false, 'toolbarFixedBox': true, 'focusCallback': function() { this.$box.addClass('no-pjax'); }, 'linkSize': 100000, - 'predefinedLinks': 'ajax.php/config/links' + 'definedLinks': 'ajax.php/config/links' }, options||{}); if (el.data('redactor')) return; var reset = $('input[type=reset]', el.closest('form')); @@ -254,7 +271,7 @@ $(function() { // where Redactor does not sync properly after adding an image. // Therefore, the ::get() call will not include text added after // the image was inserted. - el.redactor('sync'); + el.redactor('code.sync'); }); if (!$.clientPortal) { options['plugins'] = options['plugins'].concat( @@ -265,6 +282,10 @@ $(function() { options['plugins'].push('draft'); options.draftDelete = el.hasClass('draft-delete'); } + if (el.hasClass('fullscreen')) + options['plugins'].push('fullscreen'); + if ($('#ticket_thread[data-thread-id]').length) + options['imageManagerJson'] += '?threadId=' + $('#ticket_thread').data('threadId'); getConfig().then(function(c) { if (c.lang && c.lang.toLowerCase() != 'en_us' && $.Redactor.opts.langs[c.short_lang]) @@ -301,6 +322,18 @@ $(function() { $(document).ajaxStop(findRichtextBoxes); $(document).on('pjax:success', findRichtextBoxes); $(document).on('pjax:start', cleanupRedactorElements); + + // Monkey patch paste to show the loading bar + var oldImagePaste = $.Redactor.fn.paste.insertFromClipboard, + oldImageInsert = $.Redactor.fn.image.insert; + $.Redactor.fn.paste.insertFromClipboard = function() { + this.progress.show(); + return oldImagePaste.apply(this, arguments); + }; + $.Redactor.fn.image.insert = function() { + this.progress.hide(); + return oldImageInsert.apply(this, arguments); + }; }); $(document).ajaxError(function(event, request, settings) { diff --git a/js/redactor-plugins.js b/js/redactor-plugins.js new file mode 100644 index 0000000000000000000000000000000000000000..b63d3820e69a5fcf8093189015057dac7f0ce1f6 --- /dev/null +++ b/js/redactor-plugins.js @@ -0,0 +1,1601 @@ +if (!RedactorPlugins) var RedactorPlugins = {}; + +RedactorPlugins.definedlinks = function() +{ + return { + init: function() + { + if (!this.opts.definedLinks) return; + + this.modal.addCallback('link', $.proxy(this.definedlinks.load, this)); + + }, + load: function() + { + var $select = $('<select id="redactor-defined-links" />'); + $('#redactor-modal-link-insert').prepend($select); + + this.definedlinks.storage = {}; + + $.getJSON(this.opts.definedLinks, $.proxy(function(data) + { + $.each(data, $.proxy(function(key, val) + { + this.definedlinks.storage[key] = val; + $select.append($('<option>').val(key).html(val.name)); + + }, this)); + + $select.on('change', $.proxy(this.definedlinks.select, this)); + + }, this)); + + }, + select: function(e) + { + var key = $(e.target).val(); + var name = '', url = ''; + if (key !== 0) + { + name = this.definedlinks.storage[key].name; + url = this.definedlinks.storage[key].url; + } + + $('#redactor-link-url').val(url); + + var $el = $('#redactor-link-url-text'); + if ($el.val() === '') $el.val(name); + } + }; +}; + +RedactorPlugins.fontcolor = function() +{ + return { + init: function() + { + var colors = [ + '#ffffff', '#000000', '#eeece1', '#1f497d', '#4f81bd', '#c0504d', '#9bbb59', '#8064a2', '#4bacc6', '#f79646', '#ffff00', + '#f2f2f2', '#7f7f7f', '#ddd9c3', '#c6d9f0', '#dbe5f1', '#f2dcdb', '#ebf1dd', '#e5e0ec', '#dbeef3', '#fdeada', '#fff2ca', + '#d8d8d8', '#595959', '#c4bd97', '#8db3e2', '#b8cce4', '#e5b9b7', '#d7e3bc', '#ccc1d9', '#b7dde8', '#fbd5b5', '#ffe694', + '#bfbfbf', '#3f3f3f', '#938953', '#548dd4', '#95b3d7', '#d99694', '#c3d69b', '#b2a2c7', '#b7dde8', '#fac08f', '#f2c314', + '#a5a5a5', '#262626', '#494429', '#17365d', '#366092', '#953734', '#76923c', '#5f497a', '#92cddc', '#e36c09', '#c09100', + '#7f7f7f', '#0c0c0c', '#1d1b10', '#0f243e', '#244061', '#632423', '#4f6128', '#3f3151', '#31859b', '#974806', '#7f6000' + ]; + + var buttons = ['fontcolor', 'backcolor']; + + for (var i = 0; i < 2; i++) + { + var name = buttons[i]; + + var button = this.button.addBefore('deleted', name, this.lang.get(name)); + var $dropdown = this.button.addDropdown(button); + + $dropdown.width(242); + this.fontcolor.buildPicker($dropdown, name, colors); + + } + }, + buildPicker: function($dropdown, name, colors) + { + var rule = (name == 'backcolor') ? 'background-color' : 'color'; + + var len = colors.length; + var self = this; + var func = function(e) + { + e.preventDefault(); + self.fontcolor.set($(this).data('rule'), $(this).attr('rel')); + }; + + for (var z = 0; z < len; z++) + { + var color = colors[z]; + + var $swatch = $('<a rel="' + color + '" data-rule="' + rule +'" href="#" style="float: left; font-size: 0; border: 2px solid #fff; padding: 0; margin: 0; width: 22px; height: 22px;"></a>'); + $swatch.css('background-color', color); + $swatch.on('click', func); + + $dropdown.append($swatch); + } + + var $elNone = $('<a href="#" style="display: block; clear: both; padding: 5px; font-size: 12px; line-height: 1;"></a>').html(this.lang.get('none')); + $elNone.on('click', $.proxy(function(e) + { + e.preventDefault(); + this.fontcolor.remove(rule); + + }, this)); + + $dropdown.append($elNone); + }, + set: function(rule, type) + { + this.inline.format('span', 'style', rule + ': ' + type + ';'); + }, + remove: function(rule) + { + this.inline.removeStyleRule(rule); + } + }; +}; + +RedactorPlugins.fontfamily = function() +{ + return { + init: function () + { + var fonts = [ 'Arial', 'Helvetica', 'Georgia', 'Times New Roman', 'Monospace' ]; + var that = this; + var dropdown = {}; + + $.each(fonts, function(i, s) + { + dropdown['s' + i] = { title: '<span style="font-family:' + s.toLowerCase() + ';">' + + s + '</span>', func: function() { that.fontfamily.set(s); }}; + }); + + dropdown.remove = { title: __('Remove Font Family'), func: that.fontfamily.reset }; + + var button = this.button.addBefore('bold', 'fontfamily', __('Change Font Family')); + this.button.addDropdown(button, dropdown); + + }, + set: function (value) + { + this.inline.format('span', 'style', 'font-family:' + value + ';'); + }, + reset: function() + { + this.inline.removeStyleRule('font-family'); + } + }; +}; + +RedactorPlugins.fullscreen = function() +{ + return { + init: function() + { + this.fullscreen.isOpen = false; + + var button = this.button.add('fullscreen', 'Fullscreen'); + this.button.addCallback(button, this.fullscreen.toggle); + + if (this.opts.fullscreen) this.fullscreen.toggle(); + }, + enable: function() + { + this.button.changeIcon('fullscreen', 'normalscreen'); + this.button.setActive('fullscreen'); + this.fullscreen.isOpen = true; + + if (this.opts.toolbarExternal) + { + this.fullscreen.toolcss = {}; + this.fullscreen.boxcss = {}; + this.fullscreen.toolcss.width = this.$toolbar.css('width'); + this.fullscreen.toolcss.top = this.$toolbar.css('top'); + this.fullscreen.toolcss.position = this.$toolbar.css('position'); + this.fullscreen.boxcss.top = this.$box.css('top'); + } + + this.fullscreen.height = this.$editor.height(); + + if (this.opts.maxHeight) this.$editor.css('max-height', ''); + if (this.opts.minHeight) this.$editor.css('min-height', ''); + + if (!this.$fullscreenPlaceholder) this.$fullscreenPlaceholder = $('<div/>'); + this.$fullscreenPlaceholder.insertAfter(this.$box); + + this.$box.appendTo(document.body); + + this.$box.addClass('redactor-box-fullscreen'); + $('body, html').css('overflow', 'hidden'); + + this.fullscreen.resize(); + $(window).on('resize.redactor.fullscreen', $.proxy(this.fullscreen.resize, this)); + $(document).scrollTop(0, 0); + + this.$editor.focus(); + this.observe.load(); + }, + disable: function() + { + this.button.removeIcon('fullscreen', 'normalscreen'); + this.button.setInactive('fullscreen'); + this.fullscreen.isOpen = false; + + $(window).off('resize.redactor.fullscreen'); + $('body, html').css('overflow', ''); + + this.$box.insertBefore(this.$fullscreenPlaceholder); + this.$fullscreenPlaceholder.remove(); + + this.$box.removeClass('redactor-box-fullscreen').css({ width: 'auto', height: 'auto' }); + + this.code.sync(); + + if (this.opts.toolbarExternal) + { + this.$box.css('top', this.fullscreen.boxcss.top); + this.$toolbar.css({ + 'width': this.fullscreen.toolcss.width, + 'top': this.fullscreen.toolcss.top, + 'position': this.fullscreen.toolcss.position + }); + } + + if (this.opts.minHeight) this.$editor.css('minHeight', this.opts.minHeight); + if (this.opts.maxHeight) this.$editor.css('maxHeight', this.opts.maxHeight); + + this.$editor.css('height', 'auto'); + this.$editor.focus(); + this.observe.load(); + }, + toggle: function() + { + if (this.fullscreen.isOpen) + { + this.fullscreen.disable(); + } + else + { + this.fullscreen.enable(); + } + }, + resize: function() + { + if (!this.fullscreen.isOpen) return; + + var toolbarHeight = this.$toolbar.height(); + + var height = $(window).height() - toolbarHeight; + this.$box.width($(window).width() - 2).height(height + toolbarHeight); + + if (this.opts.toolbarExternal) + { + this.$toolbar.css({ + 'top': '0px', + 'position': 'absolute', + 'width': '100%' + }); + + this.$box.css('top', toolbarHeight + 'px'); + } + + this.$editor.height(height - 14); + } + }; +}; + +RedactorPlugins.imagemanager = function() +{ + return { + init: function() + { + if (!this.opts.imageManagerJson) return; + + this.modal.addCallback('image', this.imagemanager.load); + }, + load: function() + { + var $modal = this.modal.getModal(); + + this.modal.createTabber($modal); + this.modal.addTab(1, 'Upload', 'active'); + this.modal.addTab(2, 'Choose'); + + $('#redactor-modal-image-droparea').addClass('redactor-tab redactor-tab1'); + + var $box = $('<div id="redactor-image-manager-box" style="overflow: auto; height: 300px;" class="redactor-tab redactor-tab2">').hide(); + $modal.append($box); + + $.ajax({ + dataType: "json", + cache: false, + url: this.opts.imageManagerJson, + success: $.proxy(function(data) + { + $.each(data, $.proxy(function(key, val) + { + // title + var thumbtitle = ''; + if (typeof val.title !== 'undefined') thumbtitle = val.title; + + var img = $('<img src="' + val.thumb + '" rel="' + val.image + '" title="' + thumbtitle + '" style="width: 100px; height: 75px; cursor: pointer;" />'); + $('#redactor-image-manager-box').append(img); + $(img).click($.proxy(this.imagemanager.insert, this)); + + }, this)); + + + }, this) + }); + + + }, + insert: function(e) + { + this.image.insert('<img src="' + $(e.target).attr('rel') + '" alt="' + $(e.target).attr('title') + '">'); + } + }; +}; + +RedactorPlugins.table = function() +{ + return { + getTemplate: function() + { + return String() + + '<section id="redactor-modal-table-insert">' + + '<label>' + this.lang.get('rows') + '</label>' + + '<input type="text" size="5" value="2" id="redactor-table-rows" />' + + '<label>' + this.lang.get('columns') + '</label>' + + '<input type="text" size="5" value="3" id="redactor-table-columns" />' + + '</section>'; + }, + init: function() + { + + var dropdown = {}; + + dropdown.insert_table = { title: this.lang.get('insert_table'), func: this.table.show }; + dropdown.insert_row_above = { title: this.lang.get('insert_row_above'), func: this.table.addRowAbove }; + dropdown.insert_row_below = { title: this.lang.get('insert_row_below'), func: this.table.addRowBelow }; + dropdown.insert_column_left = { title: this.lang.get('insert_column_left'), func: this.table.addColumnLeft }; + dropdown.insert_column_right = { title: this.lang.get('insert_column_right'), func: this.table.addColumnRight }; + dropdown.add_head = { title: this.lang.get('add_head'), func: this.table.addHead }; + dropdown.delete_head = { title: this.lang.get('delete_head'), func: this.table.deleteHead }; + dropdown.delete_column = { title: this.lang.get('delete_column'), func: this.table.deleteColumn }; + dropdown.delete_row = { title: this.lang.get('delete_row'), func: this.table.deleteRow }; + dropdown.delete_table = { title: this.lang.get('delete_table'), func: this.table.deleteTable }; + + this.observe.addButton('td', 'table'); + this.observe.addButton('th', 'table'); + + var button = this.button.addBefore('link', 'table', this.lang.get('table')); + this.button.addDropdown(button, dropdown); + }, + show: function() + { + this.modal.addTemplate('table', this.table.getTemplate()); + + this.modal.load('table', this.lang.get('insert_table'), 300); + this.modal.createCancelButton(); + + var button = this.modal.createActionButton(this.lang.get('insert')); + button.on('click', this.table.insert); + + this.selection.save(); + this.modal.show(); + + $('#redactor-table-rows').focus(); + + }, + insert: function() + { + + var rows = $('#redactor-table-rows').val(), + columns = $('#redactor-table-columns').val(), + $tableBox = $('<div>'), + tableId = Math.floor(Math.random() * 99999), + $table = $('<table id="table' + tableId + '"><tbody></tbody></table>'), + i, $row, z, $column; + + for (i = 0; i < rows; i++) + { + $row = $('<tr>'); + + for (z = 0; z < columns; z++) + { + $column = $('<td>' + this.opts.invisibleSpace + '</td>'); + + // set the focus to the first td + if (i === 0 && z === 0) + { + $column.append(this.selection.getMarker()); + } + + $($row).append($column); + } + + $table.append($row); + } + + $tableBox.append($table); + var html = $tableBox.html(); + + + this.modal.close(); + this.selection.restore(); + + if (this.table.getTable()) return; + + this.buffer.set(); + + var current = this.selection.getBlock() || this.selection.getCurrent(); + if (current && current.tagName != 'BODY') + { + if (current.tagName == 'LI') current = $(current).closest('ul, ol'); + $(current).after(html); + } + else + { + this.insert.html(html); + } + + this.selection.restore(); + + var table = this.$editor.find('#table' + tableId); + + if (!this.opts.linebreaks && (this.utils.browser('mozilla') || this.utils.browser('msie'))) + { + var $next = table.next(); + if ($next.length === 0) + { + table.after(this.opts.emptyHtml); + } + } + + this.observe.buttons(); + + table.find('span.redactor-selection-marker').remove(); + table.removeAttr('id'); + + this.code.sync(); + this.core.setCallback('insertedTable', table); + }, + getTable: function() + { + var $table = $(this.selection.getParent()).closest('table'); + + if (!this.utils.isRedactorParent($table)) return false; + if ($table.size() === 0) return false; + + return $table; + }, + restoreAfterDelete: function($table) + { + this.selection.restore(); + $table.find('span.redactor-selection-marker').remove(); + this.code.sync(); + }, + deleteTable: function() + { + var $table = this.table.getTable(); + if (!$table) return; + + this.buffer.set(); + + + var $next = $table.next(); + if (!this.opts.linebreaks && $next.length !== 0) + { + this.caret.setStart($next); + } + else + { + this.caret.setAfter($table); + } + + + $table.remove(); + + this.code.sync(); + }, + deleteRow: function() + { + var $table = this.table.getTable(); + if (!$table) return; + + var $current = $(this.selection.getCurrent()); + + this.buffer.set(); + + var $current_tr = $current.closest('tr'); + var $focus_tr = $current_tr.prev().length ? $current_tr.prev() : $current_tr.next(); + if ($focus_tr.length) + { + var $focus_td = $focus_tr.children('td, th').first(); + if ($focus_td.length) $focus_td.prepend(this.selection.getMarker()); + } + + $current_tr.remove(); + this.table.restoreAfterDelete($table); + }, + deleteColumn: function() + { + var $table = this.table.getTable(); + if (!$table) return; + + this.buffer.set(); + + var $current = $(this.selection.getCurrent()); + var $current_td = $current.closest('td, th'); + var index = $current_td[0].cellIndex; + + $table.find('tr').each($.proxy(function(i, elem) + { + var $elem = $(elem); + var focusIndex = index - 1 < 0 ? index + 1 : index - 1; + if (i === 0) $elem.find('td, th').eq(focusIndex).prepend(this.selection.getMarker()); + + $elem.find('td, th').eq(index).remove(); + + }, this)); + + this.table.restoreAfterDelete($table); + }, + addHead: function() + { + var $table = this.table.getTable(); + if (!$table) return; + + this.buffer.set(); + + if ($table.find('thead').size() !== 0) + { + this.table.deleteHead(); + return; + } + + var tr = $table.find('tr').first().clone(); + tr.find('td').html(this.opts.invisibleSpace); + $thead = $('<thead></thead>').append(tr); + $table.prepend($thead); + + this.code.sync(); + + }, + deleteHead: function() + { + var $table = this.table.getTable(); + if (!$table) return; + + var $thead = $table.find('thead'); + if ($thead.size() === 0) return; + + this.buffer.set(); + + $thead.remove(); + this.code.sync(); + }, + addRowAbove: function() + { + this.table.addRow('before'); + }, + addRowBelow: function() + { + this.table.addRow('after'); + }, + addColumnLeft: function() + { + this.table.addColumn('before'); + }, + addColumnRight: function() + { + this.table.addColumn('after'); + }, + addRow: function(type) + { + var $table = this.table.getTable(); + if (!$table) return; + + this.buffer.set(); + + var $current = $(this.selection.getCurrent()); + var $current_tr = $current.closest('tr'); + var new_tr = $current_tr.clone(); + + new_tr.find('th').replaceWith(function() + { + var $td = $('<td>'); + $td[0].attributes = this.attributes; + + return $td.append($(this).contents()); + }); + + new_tr.find('td').html(this.opts.invisibleSpace); + + if (type == 'after') + { + $current_tr.after(new_tr); + } + else + { + $current_tr.before(new_tr); + } + + this.code.sync(); + }, + addColumn: function (type) + { + var $table = this.table.getTable(); + if (!$table) return; + + var index = 0; + var current = $(this.selection.getCurrent()); + + this.buffer.set(); + + var $current_tr = current.closest('tr'); + var $current_td = current.closest('td, th'); + + $current_tr.find('td, th').each($.proxy(function(i, elem) + { + if ($(elem)[0] === $current_td[0]) index = i; + + }, this)); + + $table.find('tr').each($.proxy(function(i, elem) + { + var $current = $(elem).find('td, th').eq(index); + + var td = $current.clone(); + td.html(this.opts.invisibleSpace); + + if (type == 'after') + { + $current.after(td); + } + else + { + $current.before(td); + } + + }, this)); + + this.code.sync(); + } + }; +}; + +RedactorPlugins.textdirection = function() { + return { + init: function() + { + var that = this; + var dropdown = {}; + + dropdown.ltr = { title: __('Left to Right'), callback: this.setLtr }; + dropdown.rtl = { title: __('Right to Left'), callback: this.setRtl }; + + var button = this.button.add('textdirection', __('Change Text Direction'), + false, dropdown); + + if (this.opts.direction == 'rtl') + this.setRtl(); + }, + setRtl: function() + { + var c = this.getCurrent(), s = this.getSelection(); + this.bufferSet(); + if (s.type == 'Range' && s.focusNode.nodeName != 'div') { + this.linebreakHack(s); + } + else if (!c) { + var repl = '<div dir="rtl">' + this.get() + '</div>'; + this.set(repl, false); + } + $(this.getCurrent()).attr('dir', 'rtl'); + this.sync(); + }, + setLtr: function() + { + var c = this.getCurrent(), s = this.getSelection(); + this.bufferSet(); + if (s.type == 'Range' && s.focusNode.nodeName != 'div') { + this.linebreakHack(s); + } + else if (!c) { + var repl = '<div dir="ltr">' + this.get() + '</div>'; + this.set(repl, false); + } + $(this.getCurrent()).attr('dir', 'ltr'); + this.sync(); + }, + linebreakHack: function(sel) { + var range = sel.getRangeAt(0); + var wrapper = document.createElement('div'); + wrapper.appendChild(range.extractContents()); + range.insertNode(wrapper); + this.selectionElement(wrapper); + } + }; +}; + +RedactorPlugins.video = function() +{ + return { + reUrlYoutube: /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig, + reUrlVimeo: /https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/, + getTemplate: function() + { + return String() + + '<section id="redactor-modal-video-insert">' + + '<label>' + this.lang.get('video_html_code') + '</label>' + + '<textarea id="redactor-insert-video-area" style="height: 160px;"></textarea>' + + '</section>'; + }, + init: function() + { + var button = this.button.addAfter('image', 'video', this.lang.get('video')); + this.button.addCallback(button, this.video.show); + }, + show: function() + { + this.modal.addTemplate('video', this.video.getTemplate()); + + this.modal.load('video', this.lang.get('video'), 700); + this.modal.createCancelButton(); + + var button = this.modal.createActionButton(this.lang.get('insert')); + button.on('click', this.video.insert); + + this.selection.save(); + this.modal.show(); + + $('#redactor-insert-video-area').focus(); + + }, + insert: function() + { + var data = $('#redactor-insert-video-area').val(); + data = this.clean.stripTags(data); + + // parse if it is link on youtube & vimeo + var iframeStart = '<iframe style="width: 500px; height: 281px;" src="', + iframeEnd = '" frameborder="0" allowfullscreen></iframe>'; + + if (data.match(this.video.reUrlYoutube)) + { + data = data.replace(this.video.reUrlYoutube, iframeStart + '//www.youtube.com/embed/$1' + iframeEnd); + } + else if (data.match(this.video.reUrlVimeo)) + { + data = data.replace(this.video.reUrlVimeo, iframeStart + '//player.vimeo.com/video/$2' + iframeEnd); + } + + this.selection.restore(); + this.modal.close(); + + var current = this.selection.getBlock() || this.selection.getCurrent(); + + if (current) $(current).after(data); + else + { + this.insert.html(data); + } + + this.code.sync(); + } + + }; +}; + +RedactorPlugins.imagepaste = function() { + return { + init: function() { + if (this.utils.browser('webkit') && navigator.userAgent.indexOf('Chrome') === -1) + { + var arr = this.utils.browser('version').split('.'); + if (arr[0] < 536) + return true; + } + + // paste except opera (not webkit) + if (this.utils.browser('opera')) + return true; + + this.$editor.on('paste.imagepaste', $.proxy(this.imagepaste.buildEventPaste, this)); + }, + buildEventPaste: function(e) + { + var event = e.originalEvent || e, + fileUpload = false, + files = [], + i, file, + cd = event.clipboardData; + + if (typeof(cd) === 'undefined') return; + + if (cd.items && cd.items.length) + { + for (i = 0, k = cd.items.length; i < k; i++) { + if (cd.kind == 'file' && cd.type.indexOf('image/') !== -1) { + file = cd.items[i].getAsFile(); + if (file !== null) + files.push(file); + } + } + } + else if (cd.files && cd.files.length) + { + files = cd.files + } + else if (cd.types.length) { + for (i = 0, k = cd.types.length; i < k; i++) { + if (cd.types[i].indexOf('image/') != -1) { + var data = cd.getData(cd.types[i]); + if (data.length) + files.push(new Blob([data], {type: cd.types[i]})); + } + } + } + if (files.length) { + // clipboard upload + this.selection.save(); + this.buffer.set(); + this.clean.singleLine = false; + for (i = 0, k = files.length; i < k; i++) + this.upload.directUpload(files[i], event); + return false; + } + } + }; +}; + +var loadedFabric = false; +RedactorPlugins.imageannotate = function() { + return { + annotateButton: false, + init: function() { + var redactor = this, + self = this.imageannotate; + if (typeof window.fabric === 'undefined' && !loadedFabric) { + $.ajax({ + dataType: 'script', + cache: true, + url: '../js/fabric.min.js' + }); + loadedFabric = true; + } + $(document).on('click', '.redactor-box img', function() { + var $image = $(this), + image_box = $('#redactor-image-box'); + if (!image_box.length || !redactor.image.editter) + return; + + var edit_size = redactor.image.editter.outerWidth(); + + self.annotateButton = redactor.image.editter + .on('remove.annotate', + function() { self.teardownAnnotate.call(redactor, image_box); }) + .clone() + .text(' '+__('Annotate')) + .prepend('<i class="icon-pencil"></i>') + .addClass('annotate-button') + .insertAfter(redactor.image.editter) + .data('image', this) + .on('click', + function() { self.startAnnotate.call(redactor, $image) }); + var diff = (edit_size - self.annotateButton.outerWidth()) / 2; + self.annotateButton.css('margin-left', + (diff + 5) + 'px'); + redactor.image.editter.css('margin-left', + (-edit_size + diff - 5) + 'px'); + }); + }, + startAnnotate: function(img) { + canvas = this.imageannotate.initCanvas(img); + this.imageannotate.buildToolbar(img); + this.image.editter.hide(); + this.imageannotate.annotateButton.hide(); + }, + teardownAnnotate: function(box) { + this.image.editter.off('.annotate'); + this.opts.keydownCallback = false; + this.opts.keyupCallback = false; + box.find('.annotate-toolbar').remove(); + box.find('.annotate-button').remove(); + var img = box.find('img')[0], + $img = $(img), + fcanvas = $img.data('canvas'), + state = fcanvas.toObject(); + // Capture current annotations + delete state.backgroundImage; + $img.attr('data-annotations', btoa(JSON.stringify(state))); + // Drop the canvas + fcanvas.dispose(); + box.find('canvas').parent().remove(); + $img.data('canvas', false); + // Deselect the image + this.image.hideResize(); + // Show the original image + $img.removeClass('hidden'); + }, + buildToolbar: function(img) { + var box = img.parent(), + redactor = this, + plugin = this.imageannotate, + shapes = $('<span>') + .attr('data-redactor', 'verified') + .attr('contenteditable', 'false') + .css({'display': 'inline-block', 'vertical-align': 'top'}), + swatches = shapes.clone(), + actions = shapes.clone(), + container = $('<div></div>') + .addClass('annotate-toolbar') + .attr('data-redactor', 'verified') + .attr('contenteditable', 'false') + .css({position: 'absolute', bottom: 0, 'min-height': '28px', + width: '100%', 'background-color': 'rgba(0,0,0,0.5)', + margin: 0, 'padding-top': '4px' }) + .appendTo(box) + .append(shapes) + .append(swatches) + .append(actions); + + var button = $('<a></a>') + .attr('href', '#') + .attr('data-redactor', 'verified') + .attr('contenteditable', 'false') + .css({color: 'white', padding: '0 7px 1px', margin: '1px 3px', + 'text-decoration': 'none', 'vertical-align': 'top'}); + + shapes + .append(button.clone() + .append($('<i class="icon-arrow-right icon-large"></i>') + .on('click', plugin.drawArrow.bind(redactor)) + .attr('title', __('Add Arrow'))) + ) + .append(button.clone() + .append($('<i class="icon-check-empty icon-large"></i>') + .on('click', plugin.drawBox.bind(redactor)) + .attr('title', __('Add Rectangle'))) + ) + .append(button.clone() + .append($('<i class="icon-circle-blank icon-large"></i>') + .on('click', plugin.drawEllipse.bind(redactor)) + .attr('title', __('Add Ellipse'))) + ) + .append(button.clone() + .append($('<i class="icon-text-height icon-large"></i>') + .on('click', plugin.drawText.bind(redactor)) + .attr('title', __('Add Text'))) + ); + + var colors = [ + '#ffffff', '#888888', '#000000', 'fuchsia', 'blue', 'red', + 'lime', 'blueviolet', 'cyan', '#f4a63b', 'yellow'] + len = colors.length; + + swatches.append( + $('<span><i class="icon-ellipsis-vertical icon-large"></i></span>') + .css({color: 'white', padding: '0 3px 1px', margin: '1px 3px', + height: '21px', position: 'relative', bottom: '8px'} + ) + ); + for (var z = 0; z < len; z++) { + var color = colors[z]; + + var $swatch = $('<a rel="' + color + '" href="#" style="font-size: 0; padding: 0; margin: 2px; width: 22px; height: 22px;"></a>'); + $swatch.css({'background-color': color, 'border': '1px dotted rgba(255,255,255,0.4)'}); + $swatch.attr('data-redactor', 'verified'); + $swatch.attr('contenteditable', 'false'); + $swatch.on('click', plugin.setColor.bind(redactor)); + + swatches.append($swatch); + } + + actions + .append( + $('<span><i class="icon-ellipsis-vertical icon-large"></i></span>') + .css({color: 'white', padding: '0 3px 1px', margin: '1px 3px', + height: '21px'} + ) + ) + .append(button.clone() + .css('padding-left', '1px') + .append($('<span></span>').css('position','relative') + .append($('<i class="icon-font"></i>')) + .append($('<i class="icon-minus"></i>') + .css({position: 'absolute', right: '-4px', top: '5px', + 'text-shadow': '0 0 2px black', 'font-size':'80%'}) + ) + ) + .on('click', plugin.smallerFont.bind(redactor)) + .attr('title', __('Decrease Font Size')) + ) + .append(button.clone() + .css('padding-left', '1px') + .append($('<span></span>').css('position','relative') + .append($('<i class="icon-font icon-large"></i>')) + .append($('<i class="icon-plus"></i>') + .css({position: 'absolute', right: '-8px', top: '4px', + 'text-shadow': '0 0 2px black'}) + ) + ) + .on('click', plugin.biggerFont.bind(redactor)) + .attr('title', __('Increase Font Size')) + ) + .append(button.clone() + .attr('id', 'annotate-set-stroke') + .append($('<span></span>').css({'position': 'relative', 'top': '2px'}) + .append($('<i class="icon-check-empty icon-large"></i>') + .css('font-size', '120%') + ).append($('<i class="icon-tint"></i>') + .css({position: 'absolute', left: '4.5px', top: 0}) + ) + ) + .on('click', plugin.paintStroke.bind(redactor)) + .attr('title', __('Set Stroke')) + ) + .append(button.clone() + .attr('id', 'annotate-set-fill') + .append($('<span></span>').css('position','relative') + .append($('<i class="icon-sign-blank icon-large"></i>')) + .append($('<i class="icon-tint icon-dark"></i>') + .css({position: 'absolute', left: '4px', top: '2px'}) + ) + ) + .on('click', plugin.paintFill.bind(redactor)) + .attr('title', __('Set Fill')) + ) + .append(button.clone() + .append($('<i class="icon-eye-close icon-large"></i>')) + .on('click', plugin.setOpacity.bind(redactor)) + .attr('title', __('Toggle Opacity')) + ) + .append(button.clone() + .append($('<i class="icon-double-angle-up icon-large"></i>')) + .on('click', plugin.bringForward.bind(redactor)) + .attr('title', __('Bring Forward')) + ) + .append(button.clone() + .append($('<i class="icon-trash icon-large"></i>')) + .on('click', plugin.discard.bind(redactor)) + .attr('title', __('Delete Object')) + ); + + container.append(button.clone() + .append($('<i class="icon-save icon-large"></i>')) + .on('click', plugin.commit.bind(redactor)) + .addClass('pull-right') + .attr('title', __('Commit Annotations')) + ); + plugin.paintStroke(); + }, + + setColor: function(e) { + e.preventDefault(); + var plugin = this.imageannotate, + redactor = this, + swatch = e.target, + image_box = $('#redactor-image-box'), + img = image_box.find('img')[0], + fcanvas = $(img).data('canvas'); + $.each(fcanvas.getObjects(), function() { + if (this.get('active')) { + if (plugin.paintMode == 'fill') + this.setFill($(e.target).attr('rel')); + else + this.setStroke($(e.target).attr('rel')); + } + }); + fcanvas.renderAll(); + }, + + // Shapes + drawShape: function(ondown, onmove, onup, cursor) { + // @see http://jsfiddle.net/URWru/ + var plugin = this.imageannotate, + redactor = this, + image_box = $('#redactor-image-box'), + img = image_box.find('img')[0], + fcanvas = $(img).data('canvas'), + isDown, shape, + mousedown = function(o) { + isDown = true; + plugin.setBuffer(); + var pointer = fcanvas.getPointer(o.e); + shape = ondown(pointer, o.e); + fcanvas.add(shape); + }, + mousemove = function(o) { + if (!isDown) return; + var pointer = fcanvas.getPointer(o.e); + onmove(shape, pointer, o.e); + fcanvas.renderAll(); + }, + mouseup = function(o) { + isDown = false; + if (onup) { + if (shape2 = onup(shape, fcanvas.getPointer(o.e))) { + shape.remove(); + fcanvas.add(shape2); + shape = shape2; + } + } + shape.setCoords() + .set({ + transparentCorners: false, + borderColor: 'rgba(102,153,255,0.9)', + cornerColor: 'rgba(102,153,255,0.5)', + cornerSize: 10 + }); + fcanvas.calcOffset() + .off('mouse:down', mousedown) + .off('mouse:up', mouseup) + .off('mouse:move', mousemove) + .deactivateAll() + .setActiveObject(shape) + .renderAll(); + fcanvas.selection = true; + fcanvas.defaultCursor = 'default'; + }; + + fcanvas.selection = false; + fcanvas.defaultCursor = cursor || 'crosshair'; + // Ensure double presses of same button are squelched + fcanvas.off('mouse:down'); + fcanvas.off('mouse:up'); + fcanvas.off('mouse:move'); + fcanvas.on('mouse:down', mousedown); + fcanvas.on('mouse:up', mouseup); + fcanvas.on('mouse:move', mousemove); + return false; + }, + + drawArrow: function(e) { + e.preventDefault(); + var top, left; + return this.imageannotate.drawShape( + function(pointer) { + top = pointer.y; + left = pointer.x; + return new fabric.Group([ + new fabric.Line([0, 5, 0, 5], { + strokeWidth: 5, + fill: 'red', + stroke: 'red', + originX: 'center', + originY: 'center', + selectable: false, + hasBorders: false + }), + new fabric.Polygon([ + {x: 20, y: 0}, + {x: 0, y: -5}, + {x: 0, y: 5} + ], { + strokeWidth: 0, + fill: 'red', + originX: 'center', + originY: 'center', + selectable: false, + hasBorders: false + }) + ], { + left: pointer.x, + top: pointer.y, + originX: 'center', + originY: 'center' + }); + }, + function(group, pointer) { + var dx = pointer.x - left, + dy = pointer.y - top, + angle = Math.atan(dy / dx), + d = Math.sqrt(dx * dx + dy * dy) - 10, + sign = dx < 0 ? -1 : 1, + dy2 = Math.sin(angle) * d * sign; + dx2 = Math.cos(angle) * d * sign, + group.item(0) + .set({ x2: dx2, y2: dy2 }); + group.item(1) + .set({ + angle: angle * 180 / Math.PI, + flipX: dx < 0, + flipY: dy < 0 + }) + .setPositionByOrigin(new fabric.Point(dx, dy), + 'center', 'center'); + }, + function(shape, pointer) { + var dx = pointer.x - left, + dy = pointer.y - top, + angle = Math.atan(dy / dx), + d = Math.sqrt(dx * dx + dy * dy); + // Mess with the next two lines and you *will* be sorry! + shape.forEachObject(function(e) { shape.removeWithUpdate(e); }); + return new fabric.Path( + 'M '+left+' '+top+' l '+(d-20)+' 0 0 -3 15 3 -15 3 0 -3 z', { + angle: angle * 180 / Math.PI + (dx < 0 ? 180 : 0), + strokeWidth: 5, + fill: 'red', + stroke: 'red' + }); + } + ); + }, + + drawEllipse: function(e) { + e.preventDefault(); + return this.imageannotate.drawShape( + function(pointer) { + return new fabric.Ellipse({ + top: pointer.y, + left: pointer.x, + strokeWidth: 5, + fill: 'transparent', + stroke: 'red', + originX: 'left', + originY: 'top' + }); + }, + function(circle, pointer, event) { + var x = circle.get('left'), y = circle.get('top'), + dx = pointer.x - x, dy = pointer.y - y, + sw = circle.getStrokeWidth()/2; + // Use SHIFT to draw circles + if (event.shiftKey) { + dy = dx = Math.max(dx, dy); + } + circle.set({ + rx: Math.max(0, Math.abs(dx/2) - sw), + ry: Math.max(0, Math.abs(dy/2) - sw), + originX: dx < 0 ? 'right' : 'left', + originY: dy < 0 ? 'bottom' : 'top'}); + } + ); + }, + + drawBox: function(e) { + e.preventDefault(); + return this.imageannotate.drawShape( + function(pointer) { + return new fabric.Rect({ + top: pointer.y, + left: pointer.x, + strokeWidth: 5, + fill: 'transparent', + stroke: 'red', + originX: 'left', + originY: 'top' + }); + }, + function(rect, pointer, event) { + var x = rect.get('left'), y = rect.get('top'), + dx = pointer.x - x, dy = pointer.y - y; + // Use SHIFT to draw squares + if (event.shiftKey) { + dy = dx = Math.max(dx, dy); + } + rect.set({ width: Math.abs(dx), height: Math.abs(dy), + originX: dx < 0 ? 'right' : 'left', + originY: dy < 0 ? 'bottom' : 'top'}); + } + ); + }, + + drawText: function(e) { + e.preventDefault(); + return this.imageannotate.drawShape( + function(pointer) { + return new fabric.IText(__('Text'), { + top: pointer.y, + left: pointer.x, + fill: 'red', + originX: 'left', + originY: 'top', + fontFamily: 'sans-serif', + fontSize: 30 + }); + }, + function(rect, pointer, event) { + var x = rect.get('left'), y = rect.get('top'), + dx = pointer.x - x, dy = pointer.y - y; + // Use SHIFT to draw squares + if (event.shiftKey) { + dy = dx = Math.max(dx, dy); + } + rect.set({ width: Math.abs(dx), height: Math.abs(dy), + originX: dx < 0 ? 'right' : 'left', + originY: dy < 0 ? 'bottom' : 'top'}); + }, + function(shape) { + shape.on('editing:exited', function() { + if (!shape.getText()) + shape.remove(); + }); + }, + 'text' + ); + }, + + // Action buttons + biggerFont: function(e) { + e.preventDefault(); + var image_box = $('#redactor-image-box'), + img = image_box.find('img')[0], + fcanvas = $(img).data('canvas'); + $.each(fcanvas.getObjects(), function() { + if (this.get('active') && this instanceof fabric.IText) { + if (this.getSelectedText()) { + this.setSelectionStyles({ + fontSize: (this.getSelectionStyles().fontSize || this.getFontSize()) + 5 + }); + } + else { + this.setFontSize(this.getFontSize() + 5); + } + } + }); + fcanvas.renderAll(); + return false; + }, + smallerFont: function(e) { + e.preventDefault(); + var image_box = $('#redactor-image-box'), + img = image_box.find('img')[0], + fcanvas = $(img).data('canvas'); + $.each(fcanvas.getObjects(), function() { + if (this.get('active') && this instanceof fabric.IText) { + if (this.getSelectedText()) { + this.setSelectionStyles({ + fontSize: (this.getSelectionStyles().fontSize || this.getFontSize()) - 5 + }); + } + else { + this.setFontSize(this.getFontSize() - 5); + } + } + }); + fcanvas.renderAll(); + return false; + }, + + paintStroke: function(e) { + $('#annotate-set-stroke').css({'background-color': 'rgba(255,255,255,0.3)'}); + $('#annotate-set-fill').css({'background-color': 'transparent'}); + this.imageannotate.paintMode = 'stroke'; + return false; + }, + paintFill: function(e) { + $('#annotate-set-fill').css({'background-color': 'rgba(255,255,255,0.3)'}); + $('#annotate-set-stroke').css({'background-color': 'transparent'}); + this.imageannotate.paintMode = 'fill'; + return false; + }, + + setOpacity: function(e) { + e.preventDefault(); + var image_box = $('#redactor-image-box'), + img = image_box.find('img')[0], + fcanvas = $(img).data('canvas'); + $.each(fcanvas.getObjects(), function() { + if (this.get('active')) { + if (this.getOpacity() != 1) + this.setOpacity(1); + else + this.setOpacity(0.6); + } + }); + fcanvas.renderAll(); + return false; + }, + + bringForward: function(e) { + e.preventDefault(); + var image_box = $('#redactor-image-box'), + img = image_box.find('img')[0], + fcanvas = $(img).data('canvas'); + $.each(fcanvas.getObjects(), function() { + if (this.get('active')) { + this.bringForward(); + } + }); + }, + + keydown: function(e) { + var image_box = $('#redactor-image-box'), + img = image_box.find('img')[0], + fcanvas = $(img).data('canvas'); + + if (!fcanvas) + return; + + var active = fcanvas.getActiveObject(); + + // Check if editing a text element + if (active instanceof fabric.IText && active.get('isEditing')) { + // This keystroke is not for redactor + var ss = active.get('selectionStart'), + se = active.get('selectionEnd'); + active.exitEditing(); + active.enterEditing(); + active.set({ + 'selectionStart': ss, + 'selectionEnd': se + }); + if (e.type == 'keydown') + active.onKeyDown(e); + else + active.onKeyPress(e); + return false; + } + + // Check if [delete] was pressed with selected objects + if (e.keyCode == 8 || e.keyCode == 46) + return this.imageannotate.discard(e); + else if (e.keyCode == 90 && (e.metaKey || e.ctrlKey)) { + fcanvas.loadFromJSON(atob($(img).attr('data-annotations'))); + return false; + } + }, + + discard: function(e) { + var image_box = $('#redactor-image-box', this.$editor), + img = image_box && image_box.find('img')[0], + fcanvas = img && $(img).data('canvas'); + + if (!fcanvas) + // Not annotating + return; + + e.preventDefault(); + this.imageannotate.setBuffer(); + $.each(fcanvas.getObjects(), function() { + if (this.get('active')) + this.remove(); + }); + fcanvas.renderAll(); + return false; + }, + + commit: function(e) { + e.preventDefault(); + var redactor = this, + image_box = $('#redactor-image-box'), + img = image_box.find('img')[0], + $img = $(img), + fcanvas = $(img).data('canvas'); + fcanvas.deactivateAll(); + + // Upload to server + redactor.buffer.set(); + var annotated = fcanvas.toDataURL({ + format: 'jpg', quality: 4, + multiplier: 1/fcanvas.getZoom() + }), + file = new Blob([annotated], {type: 'image/jpeg'}); + + // Fallback to the data URL — show while the image is being uploaded + var origSrc = $img.attr('src'); + $img.attr('src', annotated); + + var origCallback = redactor.opts.imageUploadCallback, + origErrorCbk = redactor.opts.imageUploadErrorCallback; + + // After successful upload, replace the old image with the new one. + // Transfer the annotation state to the new image for replay. + redactor.opts.imageUploadCallback = function(image, json) { + redactor.opts.imageUploadCallback = origCallback; + redactor.opts.imageUploadErrorCallback = origErrorCbk; + // Transfer the annotation JSON data and drop the original image. + image.attr('data-annotations', $img.attr('data-annotations')); + // Record the image that was originally annotated. If the committed + // image is annotated again, it should be the original image with + // the annotations placed live on the original image. The image + // being committed here will be discarded. + image.attr('data-orig-annotated-image-src', + $img.attr('data-orig-annotated-image-src') || origSrc + ); + $img.remove(); + // Redactor will add <br> before and after the image in linebreaks + // mode + var N = image.next(); + if (N.is('br')) N.remove(); + var P = image.prev(); + if (N.is('br')) P.remove(); + }; + + // Handle upload issues + redactor.opts.imageUploadErrorCallback = function(json) { + redactor.opts.imageUploadCallback = origCallback; + redactor.opts.imageUploadErrorCallback = origErrorCbk; + $img.show(); + }; + redactor.imageannotate.teardownAnnotate(image_box); + $img.css({opacity: 0.5}); + redactor.upload.directUpload(file, e); + return false; + }, + + // Utils + resizeShape: function(o) { + var shape = o.target; + if (shape instanceof fabric.Ellipse) { + shape.set({ + rx: shape.get('rx') * shape.get('scaleX'), + ry: shape.get('ry') * shape.get('scaleY'), + scaleX: 1, + scaleY: 1 + }); + } + else if (shape instanceof fabric.Rect) { + shape.set({ + width: shape.get('width') * shape.get('scaleX'), + height: shape.get('height') * shape.get('scaleY'), + scaleX: 1, + scaleY: 1 + }); + } + }, + setBuffer: function() { + var image_box = $('#redactor-image-box'), + img = image_box.find('img')[0], + $img = $(img), + fcanvas = $img.data('canvas'), + state = fcanvas.toObject(); + // Capture current annotations + delete state.backgroundImage; + $img.attr('data-annotations', btoa(JSON.stringify(state))); + }, + + // Startup + + initCanvas: function(img) { + var self = this, + plugin = this.imageannotate, + $img = $(img); + if ($img.data('canvas')) + return; + var box = $img.parent(), + canvas = $('<canvas>').css({ + position: 'absolute', + top: 0, bottom: 0, left: 0, right: 0, + width: '100%', height: '100%' + }).appendTo(box), + fcanvas = new fabric.Canvas(canvas[0], { + backgroundColor: 'rgba(0,0,0,0,0)', + containerClass: 'no-margin', + includeDefaultValues: false, + }), + previous = $(img).attr('data-annotations'); + + // Catch [delete] key and map to delete object + self.opts.keydownCallback = plugin.keydown.bind(self); + self.opts.keyupCallback = plugin.keydown.bind(self); + + var I = new Image(), scale; + I.src = $img.attr('src'); + // Use a maximum zoom-out of 0.7, so that very large pictures do not + // result in unusually small annotations (esp. stroke widths which are + // not adjustable). + scale = Math.max(0.7, $img.width() / I.width); + var scaleWidth = $img.width() / scale, + scaleHeight = $img.height() / scale; + console.log(I.width, scaleWidth, $img.width(), scale); + fcanvas + .setDimensions({width: $img.width(), height: $img.height()}) + .setZoom(scale) + .setBackgroundImage( + $img.attr('data-orig-annotated-image-src') || $img.attr('src'), + fcanvas.renderAll.bind(fcanvas), { + width: scaleWidth, + height: scaleHeight, + // Needed to position overlayImage at 0/0 + originX: 'left', + originY: 'top' + }) + .on('object:scaling', plugin.resizeShape.bind(self)); + if (previous) { + fcanvas.loadFromJSON(atob(previous)); + fcanvas.forEachObject(function(o) { + o.set({ + transparentCorners: false, + borderColor: 'rgba(102,153,255,0.9)', + cornerColor: 'rgba(102,153,255,0.5)', + cornerSize: 10 + }); + }); + } + $img.data('canvas', fcanvas).addClass('hidden'); + return fcanvas; + } + }; +}; diff --git a/js/redactor.min.js b/js/redactor.min.js index 32e661ee98ae716d7c3629e8cbfbf27d365edabc..2e800e0daec7c51352bb9a8c8ac809771302923f 100644 --- a/js/redactor.min.js +++ b/js/redactor.min.js @@ -1,6 +1,6 @@ /* - Redactor v9.2.4 - Updated: May 15, 2014 + Redactor v10.0.5 + Updated: November 18, 2014 http://imperavi.com/redactor/ @@ -9,4 +9,4 @@ Usage: $('#content').redactor(); */ -eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(B($){q 7z=0;"lI lJ";q cp=B(O){c[0]=O.lO;c[1]=O.jP;c.O=O;F c};cp.5g.iv=B(){F c[0]===c[1]};q 8s=/5C?:\\/\\/(?:[0-9A-Z-]+\\.)?(?:lN\\.be\\/|bU\\.6V\\S*[^\\w\\-\\s])([\\w\\-]{11})(?=[^\\w\\-]|$)(?![?=&+%\\w.-]*(?:[\'"][^<>]*>|<\\/a>))[?=&+%\\w.-]*/ig;q 8x=/5C?:\\/\\/(bg\\.)?bN.6V\\/(\\d+)($|\\/)/;$.fn.U=B(3Q){q 1p=[];q jW=fk.5g.k0.5B(hj,1);if(1E 3Q==="8O"){c.1u(B(){q 6H=$.1a(c,"U");if(1E 6H!=="1I"&&$.72(6H[3Q])){q aA=6H[3Q].cx(6H,jW);if(aA!==1I&&aA!==6H){1p.3a(aA)}}I{F $.3V(\'m5 lL 5w "\'+3Q+\'" 3w 3G\')}})}I{c.1u(B(){if(!$.1a(c,"U")){$.1a(c,"U",3G(c,3Q))}})}if(1p.1m===0){F c}I{if(1p.1m===1){F 1p[0]}I{F 1p}}};B 3G(el,3Q){F 2a 3G.5g.7B(el,3Q)}$.3G=3G;$.3G.lK="9.2.4";$.3G.C={4a:E,1Q:E,4j:E,1f:E,1y:"en",63:"lE",4R:E,8u:E,fI:E,kq:N,gl:N,h0:N,kj:E,do:N,kl:N,bV:N,d5:E,jU:E,5L:N,2j:E,7y:E,4K:N,7R:E,ch:E,6p:{"3k+m, 4E+m":"c.22(\'kz\', E)","3k+b, 4E+b":"c.22(\'3q\', E)","3k+i, 4E+i":"c.22(\'3r\', E)","3k+h, 4E+h":"c.22(\'fh\', E)","3k+l, 4E+l":"c.22(\'fo\', E)","3k+k, 4E+k":"c.an()","3k+8E+7":"c.22(\'8f\', E)","3k+8E+8":"c.22(\'82\', E)"},ji:{"3k+3":"c.22(\'kz\', E)"},7p:E,9N:60,e6:E,7I:"9W://",jE:E,6N:50,eQ:E,8c:"9a",7k:E,fr:N,kF:N,3Z:E,ba:"26",hX:N,7N:E,dF:"26",9l:N,cJ:E,cB:["T/le","T/kP","T/kN"],5p:E,3E:E,4F:N,5F:N,eX:N,ag:E,fv:N,3d:E,g8:["6c","3q","3r","5j","5V","6u","6W","5S"],1A:N,64:E,8w:X,a3:0,b4:E,8P:E,gq:E,gA:N,42:["o","6c","3q","3r","5j","5V","6u","6W","5S","T","3C","26","1n","1s","9Y","|","8b"],bz:[],aB:["5j","3r","3q","4W","5V","6u","dv","dx","dk","dK","1n"],eF:{b:"3q",43:"3q",i:"3r",em:"3r",56:"5j",5J:"5j",2q:"5V",ol:"6u",u:"4W",3h:"1n",1g:"1n",1n:"1n"},gB:["p","2h","2r","h1","h2","h3","h4","h5","h6"],1N:E,6a:N,aP:N,6P:N,68:E,6O:E,fD:E,8e:E,5G:E,7M:["o","aK","1s","2v","4E","3s","1o","lH"],5X:"43",5Y:"em",aJ:20,3J:[],7Y:[],6z:E,5a:"<p>&#aY;</p>",2i:"&#aY;",dJ:/^(P|H[1-6]|3f|b2|bi|b6|b8|am|ao)$/i,5r:["P","kG","l9","l0","hZ","hu","hF","hN","hK","jm","8J","6i","3L","jw","dP","b2","bi","b6","b8","am","ao"],dU:["gj","2v","aK","hr","i?2Z","1s","4E","m8","1o","3s","1n","7L","3X","cg"],dM:["li","dt","dt","h[1-6]","47","3s"],jb:["2h","12","dl","ga","2s","lj","gk","ol","p","2r","3n","1g","eN","3h","2q"],ac:["P","kG","l9","l0","hZ","hu","hF","hN","hK","jm","8J","3f","3L","jw","dP","6w","b2","bi","b6","b8","am","ao","6i"],jj:{en:{o:"kc",3C:"6C iY",T:"6C iX",1n:"bA",1s:"j3",eJ:"6C 1s",fU:"jx 1s",67:"lD",6c:"lC",jf:"lB Y",jg:"lF",2o:"iZ",hT:"8q 1",hS:"8q 2",hP:"8q 3",hG:"8q 4",hw:"8q 5",3q:"lR",3r:"lS",m3:"m2 jn",m4:"lA jn",5V:"m6 jq",6u:"m1 jq",6W:"lg",5S:"lf",6I:"ll",4u:"6C",83:"ln",ih:"8o",dS:"6C bA",dX:"8L bJ lw",ea:"8L bJ lu",ec:"8L bG iR",e3:"8L bG iW",cY:"8o bG",cX:"8o bJ",cW:"8o bA",ae:"lp",ap:"lr",dD:"8L j1",d9:"8o j1",1c:"ls",io:"nB",3o:"n6",1t:"iR",4I:"iW",6D:"iB",hW:"iX n5 j3",Y:"n4",er:"n3",n7:"hC",ht:"iY n8 iZ",26:"6C nb",8r:"iz",na:"n9",dR:"n2",iF:"n1 dR",iD:"mV 26 mU",du:"iM Y iL iK 1t",ds:"iB Y",dj:"iM Y iL iK 4I",ei:"mT Y",8b:"6C mS mW",5j:"mX",n0:"mZ",dA:"mY 1s in 2a 53",4W:"nc",9Y:"nd",dI:"nu (nt)",84:"jx"}}};3G.fn=$.3G.5g={2O:{9D:8,d3:46,ev:40,b3:13,eA:27,fF:9,nr:17,nq:91,nv:37,gd:91},7B:B(el,3Q){c.85=E;c.$2g=c.$1v=$(el);c.7z=7z++;q C=$.4H(N,{},$.3G.C);c.C=$.4H({},C,c.$2g.1a(),3Q);c.2u=N;c.nx=[];c.aF=c.$1v.1f("21");c.nA=c.$1v.1f("2l");if(c.C.4j){c.C.1Q=N}if(c.C.1N){c.C.6a=E}if(c.C.6a){c.C.1N=E}if(c.C.b4){c.C.64=N}c.X=X;c.48=48;c.5M=E;c.gL=2a 2L("^<(/?"+c.C.dU.5U("|/?")+"|"+c.C.dM.5U("|")+")[ >]");c.gI=2a 2L("^<(br|/?"+c.C.dU.5U("|/?")+"|/"+c.C.dM.5U("|/")+")[ >]");c.cF=2a 2L("^</?("+c.C.jb.5U("|")+")[ >]");c.a7=2a 2L("^("+c.C.ac.5U("|")+")$","i");if(c.C.1N===E){if(c.C.5G!==E){q dh=["43","em","56"];q j8=["b","i","5J"];if($.4L("p",c.C.5G)==="-1"){c.C.5G.3a("p")}3w(i in dh){if($.4L(dh[i],c.C.5G)!="-1"){c.C.5G.3a(j8[i])}}}if(c.C.7M!==E){q 3Y=$.4L("p",c.C.7M);if(3Y!=="-1"){c.C.7M.9r(3Y,3Y)}}}if(c.1C("3t")||c.1C("8S")){c.C.42=c.lb(c.C.42,"8b")}c.C.1F=c.C.jj[c.C.1y];$.4H(c.C.6p,c.C.ji);c.gV();c.ks()},fQ:B(1y){F{o:{1c:1y.o,1H:"cA"},6c:{1c:1y.6c,1H:"2N",1P:{p:{1c:1y.jf,1H:"5i"},2h:{1c:1y.jg,1H:"bR",2U:"ny"},2r:{1c:1y.2o,1H:"5i",2U:"np"},h1:{1c:1y.hT,1H:"5i",2U:"no"},h2:{1c:1y.hS,1H:"5i",2U:"m9"},h3:{1c:1y.hP,1H:"5i",2U:"ng"},h4:{1c:1y.hG,1H:"5i",2U:"nf"},h5:{1c:1y.hw,1H:"5i",2U:"ne"}}},3q:{1c:1y.3q,2p:"3q"},3r:{1c:1y.3r,2p:"3r"},5j:{1c:1y.5j,2p:"fC"},4W:{1c:1y.4W,2p:"4W"},5V:{1c:"∋ "+1y.5V,2p:"82"},6u:{1c:"1. "+1y.6u,2p:"8f"},6W:{1c:"< "+1y.6W,1H:"dz"},5S:{1c:"> "+1y.5S,1H:"dr"},T:{1c:1y.T,1H:"kJ"},3C:{1c:1y.3C,1H:"kC"},26:{1c:1y.26,1H:"kL"},1n:{1c:1y.1n,1H:"2N",1P:{dS:{1c:1y.dS,1H:"l4"},nj:{2n:"aj"},dX:{1c:1y.dX,1H:"lc"},ea:{1c:1y.ea,1H:"la"},ec:{1c:1y.ec,1H:"kT"},e3:{1c:1y.e3,1H:"kR"},nn:{2n:"aj"},dD:{1c:1y.dD,1H:"l8"},d9:{1c:1y.d9,1H:"d8"},nm:{2n:"aj"},cY:{1c:1y.cY,1H:"kW"},cX:{1c:1y.cX,1H:"kV"},cW:{1c:1y.cW,1H:"l6"}}},1s:{1c:1y.1s,1H:"2N",1P:{1s:{1c:1y.eJ,1H:"an"},67:{1c:1y.67,2p:"67"}}},9Y:{1c:1y.9Y,1H:"2N",1P:{dv:{1c:1y.du,1H:"dQ"},dx:{1c:1y.ds,1H:"dG"},dk:{1c:1y.dj,1H:"dT"},dK:{1c:1y.ei,1H:"dL"}}},dv:{1c:1y.du,1H:"dQ"},dx:{1c:1y.ds,1H:"dG"},dk:{1c:1y.dj,1H:"dT"},nk:{1c:1y.ei,1H:"dL"},8b:{2p:"fX",1c:1y.8b}}},1e:B(1G,6t,1a){q 1e=c.C[1G+"mQ"];if($.72(1e)){if(6t===E){F 1e.5B(c,1a)}I{F 1e.5B(c,6t,1a)}}I{F 1a}},mo:B(){gf(c.9N);$(48).3z(".U");c.$1v.3z("U-5R");c.$2g.3z(".U").mn("U");q o=c.2R();if(c.C.6z){c.$2A.2E(c.$1v);c.$2A.1w();c.$1v.1p(o).2N()}I{q $1B=c.$K;if(c.C.1Q){$1B=c.$2g}c.$2A.2E($1B);c.$2A.1w();$1B.3e("4e").3e("fP").2C("3F").o(o).2N()}if(c.C.8P){$(c.C.8P).o("")}if(c.C.3d){$("#gr"+c.7z).1w()}},mm:B(){F $.4H({},c)},ml:B(){F c.$K},mq:B(){F c.$2A},mj:B(){F(c.C.1Q)?c.$2Z:E},mc:B(){F(c.$1A)?c.$1A:E},2R:B(){F c.$1v.1p()},l1:B(){c.$K.2C("3F").2C("6m");q o=c.49(c.$2Z.1W().4k());c.$K.1i({3F:N,6m:c.C.63});F o},7x:B(o,a9,eC){o=o.3T();o=o.G(/\\$/g,"$");if(c.C.4j){c.kX(o)}I{c.kS(o,a9)}if(o==""){eC=E}if(eC!==E){c.fB()}},kS:B(o,a9){if(a9!==E){o=c.bt(o);o=c.7S(o);o=c.de(o);o=c.ax(o,N);if(c.C.1N===E){o=c.db(o)}I{o=o.G(/<p(.*?)>([\\w\\W]*?)<\\/p>/gi,"$2<br>")}}o=o.G(/&ab;#36;/g,"$");o=c.e5(o);c.$K.o(o);c.7J();c.aN();c.1j()},kX:B(o){q 3y=c.bm();c.$2Z[0].3l="me:mf";o=c.de(o);o=c.ax(o);o=c.79(o);3y.b1();3y.gw(o);3y.g5();if(c.C.4j){c.$K=c.$2Z.1W().1b("2v").1i({3F:N,6m:c.C.63})}c.7J();c.aN();c.1j()},cz:B(o){c.7A=o.1S(/^<\\!l3[^>]*>/i);if(c.7A&&c.7A.1m==1){o=o.G(/^<\\!l3[^>]*>/i,"")}o=c.bt(o,N);o=c.db(o);o=c.e5(o);c.$K.o(o);c.7J();c.aN();c.1j()},k1:B(){if(c.7A&&c.7A.1m==1){q 1v=c.7A[0]+"\\n"+c.$1v.1p();c.$1v.1p(1v)}},aN:B(){q 93=c.$K.1b("V");q 6G="4o";$.1u(93,B(){q au=c.ka;q 5Q=2a 2L("<"+c.Q,"gi");q 5A=au.G(5Q,"<"+6G);5Q=2a 2L("</"+c.Q,"gi");5A=5A.G(5Q,"</"+6G);$(c).2f(5A)})},aV:B(o){o=o.G(/<V(.*?)>/,"<4o$1>");F o.G(/<\\/V>/,"</4o>")},7J:B(){c.$K.1b(".mi").1i("3F",E)},1j:B(e){q o="";c.gy();if(c.C.4j){o=c.l1()}I{o=c.$K.o()}o=c.bF(o);o=c.cb(o);q 1v=c.79(c.$1v.1p(),E);q K=c.79(o,E);if(1v==K){F E}o=o.G(/<\\/li><(2q|ol)>([\\w\\W]*?)<\\/(2q|ol)>/gi,"<$1>$2</$1></li>");if($.28(o)==="<br>"){o=""}if(c.C.jU){q jT=["br","hr","1z","1s","2S","4E"];$.1u(jT,B(i,s){o=o.G(2a 2L("<"+s+"(.*?[^/$]?)>","gi"),"<"+s+"$1 />")})}o=c.1e("mu",E,o);c.$1v.1p(o);c.k1();c.1e("mv",E,o);if(c.2u===E){if(1E e!="1I"){mK(e.6h){9O 37:8h;9O 38:8h;9O 39:8h;9O 40:8h;mJ:c.1e("5W",E,o)}}I{c.1e("5W",E,o)}}},bF:B(o){if(!c.C.4j){o=c.7S(o)}o=$.28(o);o=c.fS(o);o=o.G(/&#aY;/gi,"");o=o.G(/&#mI;/gi,"");o=o.G(/<\\/a>&3u;/gi,"</a> ");o=o.G(/\\7m/g,"");if(o=="<p></p>"||o=="<p> </p>"||o=="<p>&3u;</p>"){o=""}if(c.C.jE){o=o.G(/<a(.*?)4h="jI"(.*?)>/gi,"<a$1$2>");o=o.G(/<a(.*?)>/gi,\'<a$1 4h="jI">\')}o=o.G("<!--?4P","<?4P");o=o.G("?-->","?>");o=o.G(/<(.*?)1x="k4"(.*?) 3F="E"(.*?)>/gi,\'<$mL="k4"$2$3>\');o=o.G(/ 1a-7Z=""/gi,"");o=o.G(/<br\\s?\\/?>\\n?<\\/(P|H[1-6]|3f|b2|bi|b6|b8|am|ao)>/gi,"</$1>");o=o.G(/<V(.*?)id="U-T-2A"(.*?)>([\\w\\W]*?)<1z(.*?)><\\/V>/gi,"$3<1z$4>");o=o.G(/<V(.*?)id="U-T-da"(.*?)>(.*?)<\\/V>/gi,"");o=o.G(/<V(.*?)id="U-T-d6"(.*?)>(.*?)<\\/V>/gi,"");o=o.G(/<(2q|ol)>\\s*\\t*\\n*<\\/(2q|ol)>/gi,"");if(c.C.bV){o=o.G(/<2F(.*?)>([\\w\\W]*?)<\\/2F>/gi,"$2")}o=o.G(/<V(.*?)>([\\w\\W]*?)<\\/V>/gi,"$2");o=o.G(/<4o>/gi,"<V>");o=o.G(/<4o /gi,"<V ");o=o.G(/<\\/4o>/gi,"</V>");o=o.G(/<V(.*?)1x="57"(.*?)>([\\w\\W]*?)<\\/V>/gi,"");o=o.G(/<1z(.*?)3F="E"(.*?)>/gi,"<1z$1$2>");o=o.G(/&/gi,"&");o=o.G(/\\mM/gi,"&mP;");o=o.G(/\\mO/gi,"&mN;");o=o.G(/\\mG/gi,"&mF;");o=o.G(/\\mz/gi,"&my;");o=o.G(/\\mx/gi,"&mw;");o=c.gM(o);F o},ks:B(){c.3I="";c.$2A=$(\'<12 1x="mE" />\');if(c.$1v[0].Q==="mD"){c.C.6z=N}if(c.C.kq===E&&c.5c()){c.k9()}I{c.k6();if(c.C.1Q){c.C.4K=E;c.5n()}I{if(c.C.6z){c.kb()}I{c.kg()}}if(!c.C.1Q){c.cK();c.cm()}}},k9:B(){if(!c.C.6z){c.$K=c.$1v;c.$K.2T();c.$1v=c.b0(c.$K);c.$1v.1p(c.3I)}c.$2A.aG(c.$1v).1h(c.$1v)},k6:B(){if(c.C.6z){c.3I=$.28(c.$1v.1p())}I{c.3I=$.28(c.$1v.o())}},kb:B(){c.$K=$("<12 />");c.$2A.aG(c.$1v).1h(c.$K).1h(c.$1v);c.kd(c.$K);c.ci()},kg:B(){c.$K=c.$1v;c.$1v=c.b0(c.$K);c.$2A.aG(c.$K).1h(c.$K).1h(c.$1v);c.ci()},b0:B($1v){F $("<5R />").1i("2n",$1v.1i("id")).1f("21",c.aF)},kd:B(el){$.1u(c.$1v.2R(0).2U.4i(/\\s+/),B(i,s){el.2y("nh"+s)})},ci:B(){c.$K.2y("4e").1i({3F:N,6m:c.C.63});c.$1v.1i("6m",c.C.63).2T();c.7x(c.3I,N,E)},cK:B(){q $1v=c.$K;if(c.C.1Q){$1v=c.$2Z}if(c.C.7y){$1v.1i("7y",c.C.7y)}if(c.C.7R){$1v.1f("fO-21",c.C.7R+"px")}I{if(c.1C("3c")&&c.C.1N){c.$K.1f("fO-21","mC")}}if(c.1C("3c")&&c.C.1N){c.$K.1f("95-i0","9a")}if(c.C.ch){c.C.4K=E;c.aF=c.C.ch}if(c.C.fI){c.$K.2y("fP")}if(c.C.8u){c.$K.2y("U-K-8u")}if(!c.C.4K){$1v.1f("21",c.aF)}},cm:B(){c.2u=E;if(c.C.1A){c.C.1A=c.fQ(c.C.1F);c.g6()}c.iu();c.gW();c.cU();if(c.C.7p){c.7p()}2W($.M(c.7D,c),4);if(c.1C("3c")){bK{c.X.22("mB",E,E);c.X.22("mA",E,E)}bI(e){}}if(c.C.2j){2W($.M(c.2j,c),3P)}if(!c.C.5L){2W($.M(B(){c.C.5L=N;c.cA(E)},c),5l)}c.1e("7B")},cU:B(){c.89=0;if(c.C.fr&&(c.C.3Z!==E||c.C.5p!==E)){c.$K.on("6y.U",$.M(c.g2,c))}c.$K.on("25.U",$.M(B(){c.5O=E},c));c.$K.on("2S.U",$.M(c.1j,c));c.$K.on("aW.U",$.M(c.gc,c));c.$K.on("5y.U",$.M(c.g9,c));c.$K.on("58.U",$.M(c.fs,c));if($.72(c.C.fi)){c.$1v.on("5y.U-5R",$.M(c.C.fi,c))}if($.72(c.C.fy)){c.$K.on("2j.U",$.M(c.C.fy,c))}q aq;$(X).8U(B(e){aq=$(e.1O)});c.$K.on("bO.U",$.M(B(e){if(!$(aq).3v("bs")&&$(aq).8y(".bs").1U()==0){c.5O=E;if($.72(c.C.mH)){c.1e("bO",e)}}},c))},g2:B(e){e=e.go||e;if(48.eP===1I||!e.8T){F N}q 1m=e.8T.7d.1m;if(1m==0){F N}e.2x();q 26=e.8T.7d[0];if(c.C.cB!==E&&c.C.cB.3W(26.1G)==-1){F N}c.1Z();c.8I();if(c.C.5p===E){c.ey(c.C.3Z,26,N,e,c.C.ba)}I{c.e2(26)}},gc:B(e){q bn=E;if(c.1C("4C")&&6k.7i.3W("mg")===-1){q 2M=c.1C("9y").4i(".");if(2M[0]<mh){bn=N}}if(bn){F N}if(c.1C("8S")){F N}if(c.C.9l&&c.gv(e)){F N}if(c.C.gl){c.85=N;c.2e();if(!c.5O){if(c.C.4K===N&&c.cl!==N){c.$K.21(c.$K.21());c.aX=c.X.2v.3g}I{c.aX=c.$K.3g()}}q 4f=c.cE();2W($.M(B(){q gE=c.cE();c.$K.1h(4f);c.1Y();q o=c.hR(gE);c.kk(o);if(c.C.4K===N&&c.cl!==N){c.$K.1f("21","4d")}},c),1)}},gv:B(e){q 6t=e.go||e;c.gm=E;if(1E(6t.eL)==="1I"){F E}if(6t.eL.gz){q 26=6t.eL.gz[0].ma();if(26!==2J){c.1Z();c.gm=N;q es=2a mb();es.jt=$.M(c.jK,c);es.md(26);F N}}F E},g9:B(e){if(c.85){F E}q 1k=e.6h;q 3k=e.aw||e.8K;q L=c.2B();q 1r=c.3S();q 1l=c.2P();q 2r=E;c.1e("5y",e);if(c.1C("3c")&&"ej"in 48.29()){if((3k)&&(e.2O===37||e.2O===39)){q 1J=c.29();q ex=(e.8K?"9v":"mk");if(e.2O===37){1J.ej("4H","1t",ex);if(!e.5d){1J.he()}}if(e.2O===39){1J.ej("4H","4I",ex);if(!e.5d){1J.mr()}}e.2x()}}c.62(E);if((L&&$(L).2R(0).Q==="6w")||(1r&&$(1r).2R(0).Q==="6w")){2r=N;if(1k===c.2O.ev){c.6Q(1l)}}if(1k===c.2O.ev){if(L&&$(L)[0].Q==="3L"){c.6Q(L)}if(1r&&$(1r)[0].Q==="3L"){c.6Q(1r)}if(L&&$(L)[0].Q==="P"&&$(L).L()[0].Q=="3L"){c.6Q(L,$(L).L()[0])}if(1r&&$(1r)[0].Q==="P"&&L&&$(L)[0].Q=="3L"){c.6Q(1r,L)}}c.6p(e,1k);if(3k&&1k===90&&!e.5d&&!e.gh){e.2x();if(c.C.3J.1m){c.jN()}I{c.X.22("mt",E,E)}F}I{if(3k&&1k===90&&e.5d&&!e.gh){e.2x();if(c.C.7Y.1m!=0){c.jO()}I{c.X.22("mp",E,E)}F}}if(1k==32){c.1Z()}if(3k&&1k===65){c.1Z();c.5O=N}I{if(1k!=c.2O.gd&&!3k){c.5O=E}}if(1k==c.2O.b3&&!e.5d&&!e.aw&&!e.8K){q O=c.3m();if(O&&O.4M===E){1q=c.29();if(1q.51){O.ay()}}if(c.1C("3t")&&(L.4v==1&&(L.Q=="6i"||L.Q=="mR"))){e.2x();c.1Z();c.3A(X.4y("br"));c.1e("6E",e);F E}if(1l&&(1l.Q=="3L"||$(1l).L()[0].Q=="3L")){if(c.cR()){if(c.89==1){q 2g;q 2X;if(1l.Q=="3L"){2X="br";2g=1l}I{2X="p";2g=$(1l).L()[0]}e.2x();c.cf(2g);c.89=0;if(2X=="p"){$(1l).L().1b("p").2X().1w()}I{q 2H=$.28($(1l).o());$(1l).o(2H.G(/<br\\s?\\/?>$/i,""))}F}I{c.89++}}I{c.89++}}if(2r===N){F c.fT(e,1r)}I{if(!c.C.1N){if(1l&&1l.Q=="3f"){q 5E=c.2P();if(5E!==E||5E.Q==="3f"){q aC=$.28($(1l).Y());q gN=$.28($(5E).Y());if(aC==""&&gN==""&&$(5E).4l("li").1U()==0&&$(5E).8y("li").1U()==0){c.1Z();q $30=$(5E).2c("ol, 2q");$(5E).1w();q J=$("<p>"+c.C.2i+"</p>");$30.2E(J);c.4b(J);c.1j();c.1e("6E",e);F E}}}if(1l&&c.C.dJ.4c(1l.Q)){c.1Z();2W($.M(B(){q 55=c.2P();if(55.Q==="8J"&&!$(55).3v("4e")){q J=$("<p>"+c.C.2i+"</p>");$(55).2f(J);c.4b(J)}},c),1)}I{if(1l===E){c.1Z();q J=$("<p>"+c.C.2i+"</p>");c.3A(J[0]);c.4b(J);c.1e("6E",e);F E}}}if(c.C.1N){if(1l&&c.C.dJ.4c(1l.Q)){c.1Z();2W($.M(B(){q 55=c.2P();if((55.Q==="8J"||55.Q==="P")&&!$(55).3v("4e")){c.ko(55)}},c),1)}I{F c.ef(e)}}if(1l.Q=="3L"||1l.Q=="dP"){F c.ef(e)}}c.1e("6E",e)}I{if(1k===c.2O.b3&&(e.aw||e.5d)){c.1Z();e.2x();c.aD()}}if((1k===c.2O.fF||e.8K&&1k===gH)&&c.C.6p){F c.fx(e,2r,1k)}if(1k===c.2O.9D){c.fW(e,1r,L)}},fT:B(e,1r){e.2x();c.1Z();q o=$(1r).L().Y();c.3A(X.8d("\\n"));if(o.4G(/\\s$/)==-1){c.3A(X.8d("\\n"))}c.1j();c.1e("6E",e);F E},fx:B(e,2r,1k){if(!c.C.fv){F N}if(c.a4(c.2R())&&c.C.ag===E){F N}e.2x();if(2r===N&&!e.5d){c.1Z();c.3A(X.8d("\\t"));c.1j();F E}I{if(c.C.ag!==E){c.1Z();c.3A(X.8d(fk(c.C.ag+1).5U("\\nz")));c.1j();F E}I{if(!e.5d){c.dr()}I{c.dz()}}}F E},fW:B(e,1r,L){if(L&&1r&&L.4Q.Q=="6i"&&L.Q=="fJ"&&1r.Q=="3f"&&$(L).4k("li").1U()==1){q Y=$(1r).Y().G(/[\\7m-\\hk\\hm]/g,"");if(Y==""){q J=L.4Q;$(L).1w();c.4b(J);c.1j();F E}}if(1E 1r.Q!=="1I"&&/^(H[1-6])$/i.4c(1r.Q)){q J;if(c.C.1N===E){J=$("<p>"+c.C.2i+"</p>")}I{J=$("<br>"+c.C.2i)}$(1r).2f(J);c.4b(J);c.1j()}if(1E 1r.aZ!=="1I"&&1r.aZ!==2J){if(1r.1w&&1r.4v===3&&1r.aZ.1S(/[^\\7m]/g)==2J){$(1r).4Z().1w();c.1j()}}},ef:B(e){c.1Z();e.2x();c.aD();c.1e("6E",e);F},fs:B(e){if(c.85){F E}q 1k=e.6h;q L=c.2B();q 1r=c.3S();if(!c.C.1N&&1r.4v==3&&(L==E||L.Q=="bp")){q J=$("<p>").1h($(1r).6f());$(1r).2f(J);q 4l=$(J).4l();if(1E(4l[0])!=="1I"&&4l[0].Q=="cP"){4l.1w()}c.7e(J)}if((c.C.6P||c.C.68||c.C.6O)&&1k===c.2O.b3){c.gS()}if(1k===c.2O.d3||1k===c.2O.9D){F c.gX(e)}c.1e("58",e);c.1j(e)},gS:B(){c.c6(c.C.7I,c.C.6P,c.C.68,c.C.6O,c.C.6N);2W($.M(B(){if(c.C.68){c.4F()}if(c.C.5F){c.5F()}},c),5)},gW:B(){if(!c.C.e6){F}$.1u(c.C.e6,$.M(B(i,s){if(df[s]){$.4H(c,df[s]);if($.72(df[s].7B)){c.7B()}}},c))},5n:B(){c.gu();if(c.C.6z){c.fg(c.$1v)}I{c.$eZ=c.$1v.2T();c.$1v=c.b0(c.$eZ);c.fg(c.$eZ)}},fg:B(el){c.$1v.1i("6m",c.C.63).2T();c.$2A.aG(el).1h(c.$2Z).1h(c.$1v)},gu:B(){c.$2Z=$(\'<1Q 1o="2l: 3P%;" c2="0" />\').8Z("iJ",$.M(B(){if(c.C.4j){c.bm();if(c.3I===""){c.3I=c.C.2i}c.$2Z.1W()[0].gw(c.3I);c.$2Z.1W()[0].g5();q gG=hc($.M(B(){if(c.$2Z.1W().1b("2v").o()){gf(gG);c.cG()}},c),0)}I{c.cG()}},c))},bM:B(){F c.$2Z[0].dp.X},bm:B(){q 3y=c.bM();if(3y.9L){3y.lM(3y.9L)}F 3y},cI:B(1f){1f=1f||c.C.1f;if(c.iE(1f)){c.$2Z.1W().1b("aK").1h(\'<1s 4h="ly" 1R="\'+1f+\'" />\')}if($.lP(1f)){$.1u(1f,$.M(B(i,1L){c.cI(1L)},c))}},cG:B(){c.$K=c.$2Z.1W().1b("2v").1i({3F:N,6m:c.C.63});if(c.$K[0]){c.X=c.$K[0].lh;c.48=c.X.lq||48}c.cI();if(c.C.4j){c.cz(c.$1v.1p())}I{c.7x(c.3I,N,E)}c.cK();c.cm()},gV:B(){if(c.C.4R!==E){c.bQ=c.C.4R;c.C.4R=N}I{if(1E c.$2g.1i("4R")=="1I"||c.$2g.1i("4R")==""){c.C.4R=E}I{c.bQ=c.$2g.1i("4R");c.C.4R=N}}},gO:B(o){if(c.C.4R===E){F E}if(c.a4(o)){c.C.2j=E;c.c3();c.c1();F c.c4()}I{c.c1()}F E},c3:B(){c.$K.on("2j.57",$.M(c.fp,c))},c1:B(){c.$K.on("bO.57",$.M(c.fM,c))},c4:B(){q ph=$(\'<V 1x="57">\').1a("U","8R").1i("3F",E).Y(c.bQ);if(c.C.1N===E){F $("<p>").1h(ph)}I{F ph}},fM:B(){q o=c.2R();if(c.a4(o)){c.c3();c.$K.o(c.c4())}},fp:B(){c.$K.1b("V.57").1w();q o="";if(c.C.1N===E){o=c.C.5a}c.$K.3z("2j.57");c.$K.o(o);if(c.C.1N===E){c.4b(c.$K.4k()[0])}I{c.2j()}c.1j()},fB:B(){c.$K.1b("V.57").1w();c.$K.3z("2j.57")},fS:B(o){F o.G(/<V 1x="57"(.*?)>(.*?)<\\/V>/i,"")},6p:B(e,1k){if(!c.C.6p){if((e.aw||e.8K)&&(1k===66||1k===73)){e.2x()}F E}$.1u(c.C.6p,$.M(B(4D,g1){q 52=4D.4i(",");3w(q i in 52){if(1E 52[i]==="8O"){c.fj(e,$.28(52[i]),$.M(B(){lQ(g1)},c))}}},c))},fj:B(e,52,hg){q gK={8:"lG",9:"53",10:"F",13:"F",16:"8E",17:"3k",18:"87",19:"m7",20:"m0",27:"lV",32:"6s",33:"lU",34:"lT",35:"3p",36:"lW",37:"1t",38:"lX",39:"4I",40:"lZ",45:"4u",46:"56",59:";",61:"=",96:"0",97:"1",98:"2",99:"3",3P:"4",lY:"5",lx:"6",lk:"7",lm:"8",lz:"9",lv:"*",lo:"+",ms:"-",oz:".",qG:"/",qF:"f1",qH:"f2",qI:"f3",qJ:"f4",qE:"f5",qD:"f6",qy:"f7",qx:"f8",qz:"f9",qA:"qC",qB:"qK",qL:"qV",qU:"qW",qX:"gn",qY:"-",qT:";",qS:"=",qN:",",qM:"-",qO:".",qP:"/",qR:"`",gH:"[",qQ:"\\\\",qw:"]",qv:"\'"};q cr={"`":"~","1":"!","2":"@","3":"#","4":"$","5":"%","6":"^","7":"&","8":"*","9":"(","0":")","-":"r0","=":"+",";":": ","\'":\'"\',",":"<",".":">","/":"?","\\\\":"|"};52=52.3N().4i(" ");q 8X=gK[e.2O],8C=4S.qb(e.6h).3N(),7w="",74={};$.1u(["87","3k","4E","8E"],B(2I,8V){if(e[8V+"qd"]&&8X!==8V){7w+=8V+"+"}});if(8X){74[7w+8X]=N}if(8C){74[7w+8C]=N;74[7w+cr[8C]]=N;if(7w==="8E+"){74[cr[8C]]=N}}3w(q i=0,l=52.1m;i<l;i++){if(74[52[i]]){e.2x();F hg.cx(c,hj)}}},2j:B(){if(!c.1C("8S")){c.48.2W($.M(c.9E,c,N),1)}I{c.$K.2j()}},4m:B(){if(c.1C("3t")){q 1T=c.X.9L.3g}c.$K.2j();if(c.1C("3t")){c.X.9L.3g=1T}},bX:B(){if(!c.1C("3c")){c.9E()}I{if(c.C.1N===E){q 2X=c.$K.4k().2X();c.$K.2j();c.7e(2X)}I{c.9E()}}},9E:B(5I,2g){c.$K.2j();if(1E 2g=="1I"){2g=c.$K[0]}q O=c.3m();O.9K(2g);O.5I(5I||E);q 1q=c.29();1q.4O();1q.5e(O)},cA:B(9Q){if(c.C.5L){c.h8(9Q)}I{c.hl()}},hl:B(){q o=c.$1v.2T().1p();if(1E c.6n!=="1I"){q 6n=c.6n.G(/\\n/g,"");q 7f=o.G(/\\n/g,"");7f=c.79(7f,E);c.6n=c.79(6n,E)!==7f}if(c.6n){if(c.C.4j&&o===""){c.cz(o)}I{c.7x(o);if(c.C.4j){c.cU()}}c.1e("5W",E,o)}if(c.C.1Q){c.$2Z.2N()}I{c.$K.2N()}if(c.C.4j){c.$K.1i("3F",N)}c.$1v.3z("5y.U-5R-h9");c.$K.2j();c.1Y();c.7D();c.gT();c.dW("o");c.C.5L=N},h8:B(9Q){if(9Q!==E){c.2e()}q 21=2J;if(c.C.1Q){21=c.$2Z.21();if(c.C.4j){c.$K.2C("3F")}c.$2Z.2T()}I{21=c.$K.gZ();c.$K.2T()}q o=c.$1v.1p();if(o!==""&&c.C.h0){c.$1v.1p(c.gF(o))}c.6n=o;c.$1v.21(21).2N().2j();c.$1v.on("5y.U-5R-h9",c.ha);c.hn();c.6M("o");c.C.5L=E},ha:B(e){if(e.2O===9){q $el=$(c);q 2u=$el.2R(0).4b;$el.1p($el.1p().a8(0,2u)+"\\t"+$el.1p().a8($el.2R(0).7e));$el.2R(0).4b=$el.2R(0).7e=2u+1;F E}},7p:B(){q bE=E;c.9N=hc($.M(B(){q o=c.2R();if(bE!==o){q 2n=c.$1v.1i("2n");$.j2({1L:c.C.7p,1G:"7X",1a:"2n="+2n+"&"+2n+"="+qe(qf(o)),4n:$.M(B(1a){q 1K=$.8G(1a);if(1E 1K.3V=="1I"){c.1e("7p",E,1K)}I{c.1e("qa",E,1K)}bE=o},c)})}},c),c.C.9N*q9)},g6:B(){if(c.5c()&&c.C.bz.1m>0){$.1u(c.C.bz,$.M(B(i,s){q 2I=c.C.42.3W(s);c.C.42.9r(2I,1)},c))}if(c.C.3d){c.C.42=c.C.g8}I{if(!c.C.gA){q 2I=c.C.42.3W("o");c.C.42.9r(2I,1)}}if(c.C.1A){$.1u(c.C.1A.6c.1P,$.M(B(i,s){if($.4L(i,c.C.gB)=="-1"){d2 c.C.1A.6c.1P[i]}},c))}if(c.C.42.1m===0){F E}c.gb();c.$1A=$("<2q>").2y("bs").1i("id","q4"+c.7z);if(c.C.8u){c.$1A.2y("U-1A-8u")}if(c.C.gq&&c.5c()){c.$1A.2y("U-1A-af")}if(c.C.3d){c.$3d=$(\'<12 1x="gg">\').1i("id","gr"+c.7z).2T();c.$3d.1h(c.$1A);$("2v").1h(c.$3d)}I{if(c.C.8P){c.$1A.2y("U-1A-q3");$(c.C.8P).o(c.$1A)}I{c.$2A.6v(c.$1A)}}$.1u(c.C.42,$.M(B(i,2z){if(c.C.1A[2z]){q 2d=c.C.1A[2z];if(c.C.7N===E&&2z==="26"){F N}c.$1A.1h($("<li>").1h(c.6X(2z,2d)))}},c));c.$1A.1b("a").1i("7y","-1");if(c.C.64){c.cV();$(c.C.8w).on("gn.U",$.M(c.cV,c))}if(c.C.aB){c.$K.on("9x.U 58.U",$.M(c.7K,c))}},cV:B(){q 3g=$(c.C.8w).3g();q 8v=0;q 1t=0;q 3p=0;if(c.C.8w===X){8v=c.$2A.2V().1T}I{8v=1}3p=8v+c.$2A.21()+40;if(3g>8v){q 2l="3P%";if(c.C.b4){1t=c.$2A.2V().1t;2l=c.$2A.hd();c.$1A.2y("g7")}c.64=N;if(c.C.8w===X){c.$1A.1f({3j:"9w",2l:2l,8Q:gp,1T:c.C.a3+"px",1t:1t})}I{c.$1A.1f({3j:"8B",2l:2l,8Q:gp,1T:(c.C.a3+3g)+"px",1t:0})}if(3g<3p){c.$1A.1f("gx","j7")}I{c.$1A.1f("gx","8F")}}I{c.64=E;c.$1A.1f({3j:"ia",2l:"4d",1T:0,1t:1t});if(c.C.b4){c.$1A.3e("g7")}}},gb:B(){if(!c.C.3d){F}c.$K.on("9x.U 58.U",c,$.M(B(e){q Y=c.9V();if(e.1G==="9x"&&Y!=""){c.eV(e)}if(e.1G==="58"&&e.5d&&Y!=""){q $fc=$(c.7U(c.29().q5)),2V=$fc.2V();2V.21=$fc.21();c.eV(2V,N)}},c))},eV:B(e,hb){if(!c.C.3d){F}q 1t,1T;$(".gg").2T();if(hb){1t=e.1t;1T=e.1T+e.21+14;if(c.C.1Q){1T+=c.$2A.3j().1T-$(c.X).3g();1t+=c.$2A.3j().1t}}I{q 2l=c.$3d.hd();1t=e.k5;if($(c.X).2l()<(1t+2l)){1t-=2l}1T=e.k7+14;if(c.C.1Q){1T+=c.$2A.3j().1T;1t+=c.$2A.3j().1t}I{1T+=$(c.X).3g()}}c.$3d.1f({1t:1t+"px",1T:1T+"px"}).2N();c.h7()},h7:B(){if(!c.C.3d){F}q 7r=$.M(B(3y){$(3y).on("8U.U",$.M(B(e){if($(e.1O).2c(c.$1A).1m===0){c.$3d.6J(3P);c.cn();$(3y).3z(e)}},c)).on("5y.U",$.M(B(e){if(e.6h===c.2O.eA){c.29().he()}c.$3d.6J(3P);$(3y).3z(e)},c))},c);7r(X);if(c.C.1Q){7r(c.X)}},9h:B(){if(!c.C.3d){F}q 7r=$.M(B(3y){$(3y).on("jB.U",$.M(B(e){if($(e.1O).2c(c.$1A).1m===0){c.$3d.6J(3P);$(3y).3z(e)}},c))},c);7r(X);if(c.C.1Q){7r(c.X)}},gU:B($1P,hf){$.1u(hf,$.M(B(2z,2d){if(!2d.2U){2d.2U=""}q $76;if(2d.2n==="aj"){$76=$(\'<a 1x="q6">\')}I{$76=$(\'<a 1R="#" 1x="\'+2d.2U+" q8"+2z+\'">\'+2d.1c+"</a>");$76.on("25",$.M(B(e){if(e.2x){e.2x()}if(c.1C("3t")){e.gP=E}if(2d.1e){2d.1e.5B(c,2z,$76,2d,e)}if(2d.2p){c.22(2d.2p,2z)}if(2d.1H){c[2d.1H](2z)}c.7K();if(c.C.3d){c.$3d.6J(3P)}},c))}$1P.1h($76)},c))},e8:B(e,1k){if(!c.C.5L){e.2x();F E}q $1D=c.4s(1k);q $1P=$1D.1a("1P").8D(X.2v);if($1D.3v("7u")){c.9t()}I{c.9t();c.1e("e8",{1P:$1P,1k:1k,1D:$1D});c.6M(1k);$1D.2y("7u");q 8H=$1D.2V();q dq=$1P.2l();if((8H.1t+dq)>$(X).2l()){8H.1t-=dq}q 1t=8H.1t+"px";q dc=$1D.gZ();q 3j="8B";q 1T=(dc+c.C.a3)+"px";if(c.C.64&&c.64){3j="9w"}I{1T=8H.1T+dc+"px"}$1P.1f({3j:3j,1t:1t,1T:1T}).2N();c.1e("q7",{1P:$1P,1k:1k,1D:$1D})}q 8W=$.M(B(e){c.e1(e,$1P)},c);$(X).8Z("25",8W);c.$K.8Z("25",8W);c.$K.8Z("qg",8W);e.qh();c.4m()},9t:B(){c.$1A.1b("a.7u").3e("8t").3e("7u");$(".gQ").2T();c.1e("e1")},e1:B(e,$1P){if(!$(e.1O).3v("7u")){$1P.3e("7u");c.9t()}},6X:B(2z,2d,gJ){q $1D=$(\'<a 1R="9I:;" 1c="\'+2d.1c+\'" 7y="-1" 1x="re-b5 re-\'+2z+\'"></a>\');if(1E gJ!="1I"){$1D.2y("U-2b-T")}$1D.on("25",$.M(B(e){if(e.2x){e.2x()}if(c.1C("3t")){e.gP=E}if($1D.3v("dm")){F E}if(c.7H()===E&&!2d.2p){c.4m()}if(2d.2p){c.4m();c.22(2d.2p,2z);c.9h()}I{if(2d.1H&&2d.1H!=="2N"){c[2d.1H](2z);c.9h()}I{if(2d.1e){2d.1e.5B(c,2z,$1D,2d,e);c.9h()}I{if(2d.1P){c.e8(e,2z)}}}}c.7K(E,2z)},c));if(2d.1P){q $1P=$(\'<12 1x="gQ qr\'+2z+\'" 1o="3i: 3o;">\');$1D.1a("1P",$1P);c.gU($1P,2d.1P)}F $1D},4s:B(1k){if(!c.C.1A){F E}F $(c.$1A.1b("a.re-"+1k))},qq:B(dV,Q){c.C.aB.3a(dV);c.C.eF[Q]=dV},fV:B(1k){q 2b=c.4s(1k);if(2b.3v("8t")){c.dW(1k)}I{c.6M(1k)}},6M:B(1k){q 2b=c.4s(1k);2b.2y("8t")},dW:B(1k){q 2b=c.4s(1k);2b.3e("8t")},fK:B(2z){c.$1A.1b("a.re-b5").ar(".re-"+2z).3e("8t")},gT:B(){c.$1A.1b("a.re-b5").ar("a.re-o").3e("dm")},hn:B(){c.$1A.1b("a.re-b5").ar("a.re-o").2y("dm")},qs:B(1k,b7){c.4s(1k).2y("re-"+b7)},qt:B(1k,b7){c.4s(1k).3e("re-"+b7)},qu:B(1k,2n){q 1D=c.4s(1k);1D.3e("U-2b-T");1D.2y("fa-U-2b");1D.o(\'<i 1x="fa \'+2n+\'"></i>\')},qp:B(1k,1c,1e,1P){if(!c.C.1A){F}q 2b=c.6X(1k,{1c:1c,1e:1e,1P:1P},N);c.$1A.1h($("<li>").1h(2b));F 2b},qo:B(1k,1c,1e,1P){if(!c.C.1A){F}q 2b=c.6X(1k,{1c:1c,1e:1e,1P:1P},N);c.$1A.6v($("<li>").1h(2b))},qj:B(g0,1k,1c,1e,1P){if(!c.C.1A){F}q 2b=c.6X(1k,{1c:1c,1e:1e,1P:1P},N);q $2b=c.4s(g0);if($2b.1U()!==0){$2b.L().2E($("<li>").1h(2b))}I{c.$1A.1h($("<li>").1h(2b))}F 2b},qi:B(fl,1k,1c,1e,1P){if(!c.C.1A){F}q 2b=c.6X(1k,{1c:1c,1e:1e,1P:1P},N);q $2b=c.4s(fl);if($2b.1U()!==0){$2b.L().3M($("<li>").1h(2b))}I{c.$1A.1h($("<li>").1h(2b))}F 2b},qk:B(1k){q $2b=c.4s(1k);$2b.1w()},7K:B(e,2z){q L=c.2B();c.fK(2z);if(e===E&&2z!=="o"){if($.4L(2z,c.C.aB)!=-1){c.fV(2z)}F}if(L&&L.Q==="A"){c.$1A.1b("a.fq").Y(c.C.1F.fU)}I{c.$1A.1b("a.fq").Y(c.C.1F.eJ)}$.1u(c.C.eF,$.M(B(1k,2t){if($(L).2c(1k,c.$K.2R()[0]).1m!=0){c.6M(2t)}},c));q $L=$(L).2c(c.C.5r.3T().3N(),c.$K[0]);if($L.1m){q 54=$L.1f("Y-54");if(54==""){54="1t"}c.6M("54"+54)}},bb:B(o){q 1q=c.29();if(1q.41&&1q.51){q O=c.3m();O.ay();q el=c.X.4y("12");el.3O=o;q 4f=c.X.cO(),J,5N;3x((J=el.8z)){5N=4f.7c(J)}q ql=4f.8z;O.3A(4f);if(5N){O=O.9p();O.9d(5N);O.5I(N)}1q.4O();1q.5e(O)}},2p:B(23,2K,1j){if(23==="c0"&&c.1C("3t")){2K="<"+2K+">"}if(23==="5b"&&c.1C("3t")){if(!c.8N()){c.4m();c.X.1J.5z().cd(2K)}I{c.bb(2K)}}I{c.X.22(23,E,2K)}if(1j!==E){c.1j()}c.1e("22",23,2K)},22:B(23,2K,1j){if(!c.C.5L){c.$1v.2j();F E}if(23==="3q"||23==="3r"||23==="4W"||23==="fC"){c.1Z()}if(23==="fh"||23==="fo"){q L=c.2B();if(L.Q==="qn"||L.Q==="qm"){c.9P(L)}}if(23==="5b"){c.9m(2K,1j);c.1e("22",23,2K);F}if(c.7s("6w")&&!c.C.fD){F E}if(23==="82"||23==="8f"){F c.fE(23,2K)}if(23==="67"){F c.fG(23,2K)}c.2p(23,2K,1j);if(23==="fX"){c.$K.1b("hr").2C("id")}},fG:B(23,2K){c.1Z();q 1s=c.7s("A");if(1s){$(1s).2f($(1s).Y());c.1j();c.1e("22",23,2K);F}},fE:B(23,2K){c.1Z();q L=c.2B();q $30=$(L).2c("ol, 2q");if(!c.4g($30)&&$30.1U()!=0){$30=E}q 1w=E;if($30&&$30.1m){1w=N;q 5q=$30[0].Q;if((23==="82"&&5q==="qZ")||(23==="8f"&&5q==="fJ")){1w=E}}c.2e();if(1w){q 1V=c.7b();q 4p=c.3H(1V);if(1E 1V[0]!="1I"&&1V.1m>1&&1V[0].4v==3){4p.k2(c.2P())}q 1a="",5v="";$.1u(4p,$.M(B(i,s){if(s.Q=="3f"){q $s=$(s);q 7a=$s.6f();7a.1b("2q","ol").1w();if(c.C.1N===E){1a+=c.49($("<p>").1h(7a.1W()))}I{q fR=7a.o().G(/<br\\s?\\/?>$/i,"");1a+=fR+"<br>"}if(i==0){$s.2y("U-5v").6d();5v=c.49($s)}I{$s.1w()}}},c));o=c.$K.o().G(5v,"</"+5q+">"+1a+"<"+5q+">");c.$K.o(o);c.$K.1b(5q+":6d").1w()}I{q fz=$(c.2B()).2c("1g");if(c.1C("3t")&&!c.8N()&&c.C.1N){q 3K=c.cs("12");q az=$(3K).o();q 6R=$("<2q>");if(23=="8f"){6R=$("<ol>")}q 8n=$("<li>");if($.28(az)==""){8n.1h(az+\'<V id="1J-1M-1">\'+c.C.2i+"</V>");6R.1h(8n);c.$K.1b("#1J-1M-1").2f(6R)}I{8n.1h(az);6R.1h(8n);$(3K).2f(6R)}}I{c.X.22(23)}q L=c.2B();q $30=$(L).2c("ol, 2q");if(c.C.1N===E){q aC=$.28($30.Y());if(aC==""){$30.4k("li").1b("br").1w();$30.4k("li").1h(\'<V id="1J-1M-1">\'+c.C.2i+"</V>")}}if(fz.1U()!=0){$30.gR("<1g>")}if($30.1m){q $6F=$30.L();if(c.4g($6F)&&$6F[0].Q!="3f"&&c.7n($6F[0])){$6F.2f($6F.1W())}}if(c.1C("3c")){c.$K.2j()}}c.1Y();c.$K.1b("#1J-1M-1").2C("id");c.1j();c.1e("22",23,2K);F},dr:B(){c.e4("5S")},dz:B(){c.e4("6W")},e4:B(23){c.1Z();if(23==="5S"){q 1l=c.2P();c.2e();if(1l&&1l.Q=="3f"){q L=c.2B();q $30=$(L).2c("ol, 2q");q 5q=$30[0].Q;q 4p=c.3H();$.1u(4p,B(i,s){if(s.Q=="3f"){q $4Z=$(s).4Z();if($4Z.1U()!=0&&$4Z[0].Q=="3f"){q $eb=$4Z.4k("2q, ol");if($eb.1U()==0){$4Z.1h($("<"+5q+">").1h(s))}I{$eb.1h(s)}}}})}I{if(1l===E&&c.C.1N===N){c.2p("6B","2h");q 7v=c.2P();q 1l=$(\'<12 1a-7Z="">\').o($(7v).o());$(7v).2f(1l);q 1t=c.9g($(1l).1f("2G-1t"))+c.C.aJ;$(1l).1f("2G-1t",1t+"px")}I{q 7G=c.3H();$.1u(7G,$.M(B(i,1B){q $el=E;if(1B.Q==="6i"){F}if($.4L(1B.Q,c.C.5r)!==-1){$el=$(1B)}I{$el=$(1B).2c(c.C.5r.3T().3N(),c.$K[0])}q 1t=c.9g($el.1f("2G-1t"))+c.C.aJ;$el.1f("2G-1t",1t+"px")},c))}}c.1Y()}I{c.2e();q 1l=c.2P();if(1l&&1l.Q=="3f"){q 4p=c.3H();q 2I=0;c.dH(1l,2I,4p)}I{q 7G=c.3H();$.1u(7G,$.M(B(i,1B){q $el=E;if($.4L(1B.Q,c.C.5r)!==-1){$el=$(1B)}I{$el=$(1B).2c(c.C.5r.3T().3N(),c.$K[0])}q 1t=c.9g($el.1f("2G-1t"))-c.C.aJ;if(1t<=0){if(c.C.1N===N&&1E($el.1a("7Z"))!=="1I"){$el.2f($el.o()+"<br>")}I{$el.1f("2G-1t","");c.4V($el,"1o")}}I{$el.1f("2G-1t",1t+"px")}},c))}c.1Y()}c.1j()},dH:B(li,2I,4p){if(li&&li.Q=="3f"){q $L=$(li).L().L();if($L.1U()!=0&&$L[0].Q=="3f"){$L.2E(li)}I{if(1E 4p[2I]!="1I"){li=4p[2I];2I++;c.dH(li,2I,4p)}I{c.22("82")}}}},dQ:B(){c.88("","rA")},dT:B(){c.88("4I","ry")},dG:B(){c.88("6D","rs")},dL:B(){c.88("dK","rt")},88:B(1G,23){c.1Z();if(c.cv()){c.X.22(23,E,E);F N}c.2e();q 1l=c.2P();if(!1l&&c.C.1N){c.2p("c0","12");q 7v=c.2P();q 1l=$(\'<12 1a-7Z="">\').o($(7v).o());$(7v).2f(1l);$(1l).1f("Y-54",1G);c.4V(1l,"1o");if(1G==""&&1E($(1l).1a("7Z"))!=="1I"){$(1l).2f($(1l).o())}}I{q 7G=c.3H();$.1u(7G,$.M(B(i,1B){q $el=E;if($.4L(1B.Q,c.C.5r)!==-1){$el=$(1B)}I{$el=$(1B).2c(c.C.5r.3T().3N(),c.$K[0])}if($el){$el.1f("Y-54",1G);c.4V($el,"1o")}},c))}c.1Y();c.1j()},e5:B(o){q ph=c.gO(o);if(ph!==E){F ph}if(c.C.1N===E){if(o===""){o=c.C.5a}I{if(o.4G(/^<hr\\s?\\/?>$/gi)!==-1){o="<hr>"+c.C.5a}}}F o},db:B(o){if(c.C.aP&&!c.C.ru){o=o.G(/<12(.*?)>([\\w\\W]*?)<\\/12>/gi,"<p$1>$2</p>")}if(c.C.6a){o=c.bj(o)}F o},de:B(o){if(c.C.d5){o=o.G(/\\{\\{(.*?)\\}\\}/gi,"<!-- a2 gY $1 -->");o=o.G(/\\{(.*?)\\}/gi,"<!-- a2 $1 -->")}o=o.G(/<3s(.*?)>([\\w\\W]*?)<\\/3s>/gi,\'<1c 1G="Y/9I" 1o="3i: 3o;" 1x="U-3s-1d"$1>$2</1c>\');o=o.G(/<1o(.*?)>([\\w\\W]*?)<\\/1o>/gi,\'<2m$1 1o="3i: 3o;" 4h="U-1o-1d">$2</2m>\');o=o.G(/<2s(.*?)>([\\w\\W]*?)<\\/2s>/gi,\'<2m$1 4h="U-2s-1d">$2</2m>\');if(c.C.8e){o=o.G(/<\\?4P([\\w\\W]*?)\\?>/gi,\'<2m 1o="3i: 3o;" 4h="U-4P-1d">$1</2m>\')}I{o=o.G(/<\\?4P([\\w\\W]*?)\\?>/gi,"")}F o},gM:B(o){if(c.C.d5){o=o.G(/<!-- a2 gY (.*?) -->/gi,"{{$1}}");o=o.G(/<!-- a2 (.*?) -->/gi,"{$1}")}o=o.G(/<1c 1G="Y\\/9I" 1o="3i: 3o;" 1x="U-3s-1d"(.*?)>([\\w\\W]*?)<\\/1c>/gi,\'<3s$1 1G="Y/9I">$2<\\/3s>\');o=o.G(/<2m(.*?) 1o="3i: 3o;" 4h="U-1o-1d">([\\w\\W]*?)<\\/2m>/gi,"<1o$1>$2</1o>");o=o.G(/<2m(.*?)4h="U-2s-1d"(.*?)>([\\w\\W]*?)<\\/2m>/gi,"<2s$1$2>$3</2s>");if(c.C.8e){o=o.G(/<2m 1o="3i: 3o;" 4h="U-4P-1d">([\\w\\W]*?)<\\/2m>/gi,"<?4P\\r\\n$1\\r\\n?>")}F o},79:B(o,3J){if(3J!==E){q 3J=[];q 2w=o.1S(/<(2r|1o|3s|1c)(.*?)>([\\w\\W]*?)<\\/(2r|1o|3s|1c)>/gi);if(2w===2J){2w=[]}if(c.C.8e){q 7l=o.1S(/<\\?4P([\\w\\W]*?)\\?>/gi);if(7l){2w=$.eW(2w,7l)}}if(2w){$.1u(2w,B(i,s){o=o.G(s,"hh"+i);3J.3a(s)})}}o=o.G(/\\n/g," ");o=o.G(/[\\t]*/g,"");o=o.G(/\\n\\s*\\n/g,"\\n");o=o.G(/^[\\s\\n]*/g," ");o=o.G(/[\\s\\n]*$/g," ");o=o.G(/>\\s{2,}</g,"> <");o=c.hi(o,3J);o=o.G(/\\n\\n/g,"\\n");F o},hi:B(o,3J){if(3J===E){F o}$.1u(3J,B(i,s){o=o.G("hh"+i,s)});F o},cb:B(o){o=o.G(/[\\7m-\\hk\\hm]/g,"");q di=["<b>\\\\s*</b>","<b>&3u;</b>","<em>\\\\s*</em>"];q 75=["<2r></2r>","<2h>\\\\s*</2h>","<dd></dd>","<dt></dt>","<2q></2q>","<ol></ol>","<li></li>","<1n></1n>","<3h></3h>","<V>\\\\s*<V>","<V>&3u;<V>","<p>\\\\s*</p>","<p></p>","<p>&3u;</p>","<p>\\\\s*<br>\\\\s*</p>","<12>\\\\s*</12>","<12>\\\\s*<br>\\\\s*</12>"];if(c.C.do){75=75.rq(di)}I{75=di}q 4T=75.1m;3w(q i=0;i<4T;++i){o=o.G(2a 2L(75[i],"gi"),"")}F o},bj:B(o){o=$.28(o);if(c.C.1N===N){F o}if(o===""||o==="<p></p>"){F c.C.5a}o=o+"\\n";if(c.C.do===E){F o}q eG=[];q 2w=o.1S(/<(1n|12|2r|3R)(.*?)>([\\w\\W]*?)<\\/(1n|12|2r|3R)>/gi);if(!2w){2w=[]}q ff=o.1S(/<!--([\\w\\W]*?)-->/gi);if(ff){2w=$.eW(2w,ff)}if(c.C.8e){q 7l=o.1S(/<2m(.*?)4h="U-4P-1d">([\\w\\W]*?)<\\/2m>/gi);if(7l){2w=$.eW(2w,7l)}}if(2w){$.1u(2w,B(i,s){eG[i]=s;o=o.G(s,"{G"+i+"}\\n")})}o=o.G(/<br \\/>\\s*<br \\/>/gi,"\\n\\n");o=o.G(/<br><br>/gi,"\\n\\n");B R(4D,ge,r){F o.G(2a 2L(4D,ge),r)}q 3D="(rw|o|2v|aK|1c|4E|1o|3s|1s|1Q|1n|3X|cg|rp|rr|rx|7L|3h|1g|eN|12|dl|dd|dt|2q|ol|li|2r|3n|47|2s|gk|gj|2h|c5|rz|1o|p|h[1-6]|hr|ga|rn|2m|kf|ke|r7|aI|44|r8|r9|r5|r1|r2|ro)";o=R("(<"+3D+"[^>]*>)","gi","\\n$1");o=R("(</"+3D+">)","gi","$1\\n\\n");o=R("\\r\\n","g","\\n");o=R("\\r","g","\\n");o=R("/\\n\\n+/","g","\\n\\n");q 4B=o.4i(2a 2L("\\ns*\\n","g"),-1);o="";3w(q i in 4B){if(4B.r3(i)){if(4B[i].4G("{G")==-1){4B[i]=4B[i].G(/<p>\\n\\t?<\\/p>/gi,"");4B[i]=4B[i].G(/<p><\\/p>/gi,"");if(4B[i]!=""){o+="<p>"+4B[i].G(/^\\n+|\\n+$/g,"")+"</p>"}}I{o+=4B[i]}}}o=R("<p><p>","gi","<p>");o=R("</p></p>","gi","</p>");o=R("<p>s?</p>","gi","");o=R("<p>([^<]+)</(12|c5|2s)>","gi","<p>$1</p></$2>");o=R("<p>(</?"+3D+"[^>]*>)</p>","gi","$1");o=R("<p>(<li.+?)</p>","gi","$1");o=R("<p>s?(</?"+3D+"[^>]*>)","gi","$1");o=R("(</?"+3D+"[^>]*>)s?</p>","gi","$1");o=R("(</?"+3D+"[^>]*>)s?<br />","gi","$1");o=R("<br />(s*</?(?:p|li|12|dl|dd|dt|eN|2r|1g|2q|ol)[^>]*>)","gi","$1");o=R("\\n</p>","gi","</p>");o=R("<li><p>","gi","<li>");o=R("</p></li>","gi","</li>");o=R("</li><p>","gi","</li>");o=R("<p>\\t?\\n?<p>","gi","<p>");o=R("</dt><p>","gi","</dt>");o=R("</dd><p>","gi","</dd>");o=R("<br></p></2h>","gi","</2h>");o=R("<p>\\t*</p>","gi","");$.1u(eG,B(i,s){o=o.G("{G"+i+"}",s)});F $.28(o)},ax:B(o,7x){q 5X="43";if(c.C.5X==="b"){5X="b"}q 5Y="em";if(c.C.5Y==="i"){5Y="i"}o=o.G(/<V 1o="2F-1o: 3r;">([\\w\\W]*?)<\\/V>/gi,"<"+5Y+">$1</"+5Y+">");o=o.G(/<V 1o="2F-71: 3q;">([\\w\\W]*?)<\\/V>/gi,"<"+5X+">$1</"+5X+">");if(c.C.5X==="43"){o=o.G(/<b>([\\w\\W]*?)<\\/b>/gi,"<43>$1</43>")}I{o=o.G(/<43>([\\w\\W]*?)<\\/43>/gi,"<b>$1</b>")}if(c.C.5Y==="em"){o=o.G(/<i>([\\w\\W]*?)<\\/i>/gi,"<em>$1</em>")}I{o=o.G(/<em>([\\w\\W]*?)<\\/em>/gi,"<i>$1</i>")}o=o.G(/<V 1o="Y-bP: 4W;">([\\w\\W]*?)<\\/V>/gi,"<u>$1</u>");if(7x!==N){o=o.G(/<5J>([\\w\\W]*?)<\\/5J>/gi,"<56>$1</56>")}I{o=o.G(/<56>([\\w\\W]*?)<\\/56>/gi,"<5J>$1</5J>")}F o},7S:B(o){if(o==""||1E o=="1I"){F o}q 94=E;if(c.C.5G!==E){94=N}q 2M=94===N?c.C.5G:c.C.7M;q gs=/<\\/?([a-z][a-ep-9]*)\\b[^>]*>/gi;o=o.G(gs,B($0,$1){if(94===N){F $.4L($1.3N(),2M)>"-1"?$0:""}I{F $.4L($1.3N(),2M)>"-1"?"":$0}});o=c.ax(o);F o},bt:B(o,gD){q 2r=o.1S(/<(2r|2o)(.*?)>([\\w\\W]*?)<\\/(2r|2o)>/gi);if(2r!==2J){$.1u(2r,$.M(B(i,s){q 2M=s.1S(/<(2r|2o)(.*?)>([\\w\\W]*?)<\\/(2r|2o)>/i);2M[3]=2M[3].G(/&3u;/g," ");if(gD!==E){2M[3]=c.bZ(2M[3])}2M[3]=2M[3].G(/\\$/g,"$");o=o.G(s,"<"+2M[1]+2M[2]+">"+2M[3]+"</"+2M[1]+">")},c))}F o},bZ:B(4D){4D=4S(4D).G(/&ab;/g,"&").G(/</g,"<").G(/>/g,">").G(/&gC;/g,\'"\');F 4D.G(/&/g,"&ab;").G(/</g,"<").G(/>/g,">").G(/"/g,"&gC;")},gy:B(){q $1B=c.$K.1b("li, 1z, a, b, 43, rc, rk, i, em, u, rl, 5J, 56, V, rm");$1B.g3(\'[1o*="9b-8i: g4;"][1o*="9v-21"]\').1f("9b-8i","").1f("9v-21","");$1B.g3(\'[1o*="9b-8i: g4;"]\').1f("9b-8i","");$1B.1f("9v-21","");$.1u($1B,$.M(B(i,s){c.4V(s,"1o")},c));q $bD=c.$K.1b("b, 43, i, em, u, 5J, 56");$bD.1f("2F-1U","");$.1u($bD,$.M(B(i,s){c.4V(s,"1o")},c));c.$K.1b(\'12[1o="Y-54: -4C-4d;"]\').1W().fA();c.$K.1b("2q, ol, li").2C("1o")},gF:B(2o){q i=0,9f=2o.1m,31=0,2u=2J,3p=2J,1d="",1X="",4Y="";c.86=0;3w(;i<9f;i++){31=i;if(-1==2o.4N(i).3W("<")){1X+=2o.4N(i);F c.cu(1X)}3x(31<9f&&2o.5u(31)!="<"){31++}if(i!=31){4Y=2o.4N(i,31-i);if(!4Y.1S(/^\\s{2,}$/g)){if("\\n"==1X.5u(1X.1m-1)){1X+=c.7C()}I{if("\\n"==4Y.5u(0)){1X+="\\n"+c.7C();4Y=4Y.G(/^\\s+/,"")}}1X+=4Y}if(4Y.1S(/\\n/)){1X+="\\n"+c.7C()}}2u=31;3x(31<9f&&">"!=2o.5u(31)){31++}1d=2o.4N(2u,31-2u);i=31;q t;if("!--"==1d.4N(1,3)){if(!1d.1S(/--$/)){3x("-->"!=2o.4N(31,3)){31++}31+=2;1d=2o.4N(2u,31-2u);i=31}if("\\n"!=1X.5u(1X.1m-1)){1X+="\\n"}1X+=c.7C();1X+=1d+">\\n"}I{if("!"==1d[1]){1X=c.9o(1d+">",1X)}I{if("?"==1d[1]){1X+=1d+">\\n"}I{if(t=1d.1S(/^<(3s|1o|2r)/i)){t[1]=t[1].3N();1d=c.ct(1d);1X=c.9o(1d,1X);3p=4S(2o.4N(i+1)).3N().3W("</"+t[1]);if(3p){4Y=2o.4N(i+1,3p);i+=3p;1X+=4Y}}I{1d=c.ct(1d);1X=c.9o(1d,1X)}}}}}F c.cu(1X)},7C:B(){q s="";3w(q j=0;j<c.86;j++){s+="\\t"}F s},cu:B(2o){2o=2o.G(/\\n\\s*\\n/g,"\\n");2o=2o.G(/^[\\s\\n]*/,"");2o=2o.G(/[\\s\\n]*$/,"");2o=2o.G(/<3s(.*?)>\\n<\\/3s>/gi,"<3s$1><\\/3s>");c.86=0;F 2o},ct:B(1d){q 81="";1d=1d.G(/\\n/g," ");1d=1d.G(/\\s{2,}/g," ");1d=1d.G(/^\\s+|\\s+$/g," ");q cS="";if(1d.1S(/\\/$/)){cS="/";1d=1d.G(/\\/+$/,"")}q m;3x(m=/\\s*([^= ]+)(?:=(([\'"\']).*?\\3|[^ ]+))?/.2p(1d)){if(m[2]){81+=m[1].3N()+"="+m[2]}I{if(m[1]){81+=m[1].3N()}}81+=" ";1d=1d.4N(m[0].1m)}F 81.G(/\\s*$/,"")+cS+">"},9o:B(1d,1X){q nl=1d.1S(c.cF);if(1d.1S(c.gL)||nl){1X=1X.G(/\\s*$/,"");1X+="\\n"}if(nl&&"/"==1d.5u(1)){c.86--}if("\\n"==1X.5u(1X.1m-1)){1X+=c.7C()}if(nl&&"/"!=1d.5u(1)){c.86++}1X+=1d;if(1d.1S(c.gI)||1d.1S(c.cF)){1X=1X.G(/ *$/,"");1X+="\\n"}F 1X},gX:B(e){q o=$.28(c.$K.o());if(c.C.1N){if(o==""){e.2x();c.$K.o("");c.2j()}}I{o=o.G(/<br\\s?\\/?>/i,"");q 7f=o.G(/<p>\\s?<\\/p>/gi,"");if(o===""||7f===""){e.2x();q J=$(c.C.5a).2R(0);c.$K.o(J);c.2j()}}c.1j()},5i:B(1d){if(c.1C("3c")&&c.7H()){c.$K.2j()}c.1Z();q 1V=c.3H();c.2e();$.1u(1V,$.M(B(i,J){if(J.Q!=="3f"){q L=$(J).L();if(1d==="p"){if((J.Q==="P"&&L.1U()!=0&&L[0].Q==="3L")||J.Q==="3L"){c.bR();F}I{if(c.C.1N){if(J&&J.Q.4G(/H[1-6]/)==0){$(J).2f(J.3O+"<br>")}I{F}}I{c.6B(1d,J)}}}I{c.6B(1d,J)}}},c));c.1Y();c.1j()},6B:B(1d,1l){if(1l===E){1l=c.2P()}if(1l===E&&c.C.1N===N){c.22("c0",1d);F N}q 1W="";if(1d!=="2r"){1W=$(1l).1W()}I{1W=$(1l).o();if($.28(1W)===""){1W=\'<V id="1J-1M-1"></V>\'}}if(1l.Q==="6w"){1d="p"}if(c.C.1N===N&&1d==="p"){$(1l).2f($("<12>").1h(1W).o()+"<br>")}I{q L=c.2B();q J=$("<"+1d+">").1h(1W);$(1l).2f(J);if(L&&L.Q=="6i"){$(J).gR("<1g>")}}},jH:B(fY,fZ,83){if(83!==E){c.2e()}q 8A=$("<"+fZ+"/>");$(fY).2f(B(){F 8A.1h($(c).1W())});if(83!==E){c.1Y()}F 8A},bR:B(){if(c.1C("3c")&&c.7H()){c.$K.2j()}c.1Z();if(c.C.1N===E){c.2e();q 3D=c.3H();q 2h=E;q fH=3D.1m;if(3D){q 1a="";q 5v="";q G=E;q bT=N;$.1u(3D,B(i,s){if(s.Q!=="P"){bT=E}});$.1u(3D,$.M(B(i,s){if(s.Q==="3L"){c.6B("p",s,E)}I{if(s.Q==="P"){2h=$(s).L();if(2h[0].Q=="3L"){q 7o=$(2h).4k("p").1U();if(7o==1){$(2h).2f(s)}I{if(7o==fH){G="2h";1a+=c.49(s)}I{G="o";1a+=c.49(s);if(i==0){$(s).2y("U-5v").6d();5v=c.49(s)}I{$(s).1w()}}}}I{if(bT===E||3D.1m==1){c.6B("2h",s,E)}I{G="fN";1a+=c.49(s)}}}I{if(s.Q!=="3f"){c.6B("2h",s,E)}}}},c));if(G){if(G=="fN"){$(3D[0]).2f("<2h>"+1a+"</2h>");$(3D).1w()}I{if(G=="2h"){$(2h).2f(1a)}I{if(G=="o"){q o=c.$K.o().G(5v,"</2h>"+1a+"<2h>");c.$K.o(o);c.$K.1b("2h").1u(B(){if($.28($(c).o())==""){$(c).1w()}})}}}}}c.1Y()}I{q 1l=c.2P();if(1l.Q==="3L"){c.2e();q o=$.28($(1l).o());q 1J=$.28(c.jR());o=o.G(/<V(.*?)id="1J-1M(.*?)<\\/V>/gi,"");if(o==1J){$(1l).2f($(1l).o()+"<br>")}I{c.ft("2H");q 2H=c.$K.1b("2H");2H.6d();q fu=c.$K.o().G("<2H></2H>",\'</2h><V id="1J-1M-1">\'+c.C.2i+"</V>"+1J+"<2h>");c.$K.o(fu);2H.1w();c.$K.1b("2h").1u(B(){if($.28($(c).o())==""){$(c).1w()}})}c.1Y();c.$K.1b("V#1J-1M-1").1i("id",E)}I{q 3K=c.cs("2h");q o=$(3K).o();q fw=["2q","ol","1n","3h","7L","3X","cg","dl"];$.1u(fw,B(i,s){o=o.G(2a 2L("<"+s+"(.*?)>","gi"),"");o=o.G(2a 2L("</"+s+">","gi"),"")});q 6Y=c.C.ac;$.1u(6Y,B(i,s){o=o.G(2a 2L("<"+s+"(.*?)>","gi"),"");o=o.G(2a 2L("</"+s+">","gi"),"<br>")});$(3K).o(o);c.cq(3K);q 4l=$(3K).4l();if(4l.1U()!=0&&4l[0].Q==="cP"){4l.1w()}}}c.1j()},rj:B(1i,2t){q 1V=c.3H();$(1V).2C(1i);c.1j()},ri:B(1i,2t){q 1V=c.3H();$(1V).1i(1i,2t);c.1j()},rf:B(5h){q 1V=c.3H();$(1V).1f(5h,"");c.4V(1V,"1o");c.1j()},rh:B(5h,2t){q 1V=c.3H();$(1V).1f(5h,2t);c.1j()},rg:B(2U){q 1V=c.3H();$(1V).3e(2U);c.4V(1V,"1x");c.1j()},rd:B(2U){q 1V=c.3H();$(1V).2y(2U);c.1j()},rb:B(2U){c.2e();c.ck(B(J){$(J).3e(2U);c.4V(J,"1x")});c.1Y();c.1j()},r4:B(2U){q 1r=c.3S();if(!$(1r).3v(2U)){c.as("2y",2U)}},r6:B(5h){c.2e();c.ck(B(J){$(J).1f(5h,"");c.4V(J,"1o")});c.1Y();c.1j()},ra:B(5h,2t){c.as("1f",5h,2t)},qc:B(1i){c.2e();q O=c.3m(),J=c.7U(),1V=c.7b();if(O.4M||O.5T===O.7Q&&J){1V=$(J)}$(1V).2C(1i);c.fm();c.1Y();c.1j()},q1:B(1i,2t){c.as("1i",1i,2t)},as:B(1G,1i,2t){c.1Z();c.2e();q O=c.3m();q el=c.7U();if((O.4M||O.5T===O.7Q)&&el&&!c.7n(el)){$(el)[1G](1i,2t)}I{c.X.22("8a",E,4);q aH=c.$K.1b("2F");$.1u(aH,$.M(B(i,s){c.fL(1G,s,1i,2t)},c))}c.1Y();c.1j()},fL:B(1G,s,1i,2t){q L=$(s).L(),el;q av=c.9V();q aE=$(L).Y();q aR=av==aE;if(aR&&L&&L[0].Q==="c7"&&L[0].or.1m!=0){el=L;$(s).2f($(s).o())}I{el=$("<4o>").1h($(s).1W());$(s).2f(el)}$(el)[1G](1i,2t);F el},ck:B(1e){q O=c.3m(),J=c.7U(),1V=c.7b(),4M;if(O.4M||O.5T===O.7Q&&J){1V=$(J);4M=N}$.1u(1V,$.M(B(i,J){if(!4M&&J.Q!=="c7"){q av=c.9V();q aE=$(J).L().Y();q aR=av==aE;if(aR&&J.4Q.Q==="c7"&&!$(J.4Q).3v("4e")){J=J.4Q}I{F}}1e.5B(c,J)},c))},fm:B(){q $93=c.$K.1b("4o");$.1u($93,$.M(B(i,V){q $V=$(V);if($V.1i("1x")===1I&&$V.1i("1o")===1I){$V.1W().fA()}},c))},ft:B(1d){c.2e();c.X.22("8a",E,4);q aH=c.$K.1b("2F");q 2X;$.1u(aH,B(i,s){q el=$("<"+1d+"/>").1h($(s).1W());$(s).2f(el);2X=el});c.1Y();c.1j()},oq:B(1d){c.2e();q ca=1d.op();q 1V=c.7b();q L=$(c.2B()).L();$.1u(1V,B(i,s){if(s.Q===ca){c.9P(s)}});if(L&&L[0].Q===ca){c.9P(L)}c.1Y();c.1j()},9P:B(el){$(el).2f($(el).1W())},9m:B(o,1j){q 1r=c.3S();q L=1r.4Q;c.4m();c.1Z();q $o=$("<12>").1h($.cc(o));o=$o.o();o=c.cb(o);$o=$("<12>").1h($.cc(o));q c9=c.2P();if($o.1W().1m==1){q 9R=$o.1W()[0].Q;if(9R!="P"&&9R==c9.Q||9R=="6w"){$o=$("<12>").1h(o)}}if(c.C.1N){o=o.G(/<p(.*?)>([\\w\\W]*?)<\\/p>/gi,"$2<br>")}if(!c.C.1N&&$o.1W().1m==1&&$o.1W()[0].4v==3&&(c.bk().1m>2||(!1r||1r.Q=="bp"&&!L||L.Q=="kc"))){o="<p>"+o+"</p>"}o=c.aV(o);if($o.1W().1m>1&&c9||$o.1W().is("p, :aI, 2q, ol, li, 12, 1n, 1g, 2h, 2r, c5, 2m, aI, 44, ke, kf")){if(c.1C("3t")){if(!c.8N()){c.X.1J.5z().cd(o)}I{c.bb(o)}}I{c.X.22("5b",E,o)}}I{c.ah(o,E)}if(c.5O){c.48.2W($.M(B(){if(!c.C.1N){c.7e(c.$K.1W().2X())}I{c.bX()}},c),1)}c.7D();c.7J();if(1j!==E){c.1j()}},ah:B(o,1j){o=c.aV(o);q 1q=c.29();if(1q.41&&1q.51){q O=1q.41(0);O.ay();q el=c.X.4y("12");el.3O=o;q 4f=c.X.cO(),J,5N;3x((J=el.8z)){5N=4f.7c(J)}O.3A(4f);if(5N){O=O.9p();O.9d(5N);O.5I(N);1q.4O();1q.5e(O)}}if(1j!==E){c.1j()}},os:B(o){o=c.aV(o);q J=$(o);q 6s=X.4y("V");6s.3O="\\7m";q O=c.3m();O.3A(6s);O.3A(J[0]);O.5I(E);q 1q=c.29();1q.4O();1q.5e(O);c.1j()},ot:B(o){q $o=$($.cc(o));if($o.1m){o=$o.Y()}c.4m();if(c.1C("3t")){if(!c.8N()){c.X.1J.5z().cd(o)}I{c.bb(o)}}I{c.X.22("5b",E,o)}c.1j()},3A:B(J){J=J[0]||J;if(J.Q=="kt"){q 6G="4o";q au=J.ka;q 5Q=2a 2L("<"+J.Q,"i");q 5A=au.G(5Q,"<"+6G);5Q=2a 2L("</"+J.Q,"i");5A=5A.G(5Q,"</"+6G);J=$(5A)[0]}q 1q=c.29();if(1q.41&&1q.51){O=1q.41(0);O.ay();O.3A(J);O.ov(J);O.9d(J);1q.4O();1q.5e(O)}F J},iS:B(e,J){q O;q x=e.k5,y=e.k7;if(c.X.k8){q 3Y=c.X.k8(x,y);O=c.3m();O.7W(3Y.ou,3Y.2V);O.5I(N);O.3A(J)}I{if(c.X.kh){O=c.X.kh(x,y);O.3A(J)}I{if(1E X.2v.ki!="1I"){O=c.X.2v.ki();O.kr(x,y);q ce=O.oo();ce.kr(x,y);O.om("og",ce);O.3n()}}}},6Q:B(2g,L){if(1E(L)!="1I"){2g=L}if(c.cR()){if(c.C.1N){q 1W=$("<12>").1h($.28(c.$K.o())).1W();q 2X=1W.2X()[0];if(2X.Q=="kt"&&2X.3O==""){2X=1W.4Z()[0]}if(c.49(2X)!=c.49(2g)){F E}}I{if(c.$K.1W().2X()[0]!==2g){F E}}c.cf(2g)}},cf:B(2g){c.1Z();if(c.C.1N===E){q J=$(c.C.5a);$(2g).2E(J);c.4b(J)}I{q J=$(\'<V id="1J-1M-1">\'+c.C.2i+"</V>",c.X)[0];$(2g).2E(J);$(J).2E(c.C.2i);c.1Y();c.$K.1b("V#1J-1M-1").2C("id")}},aD:B(kp){c.2e();q br="<br>";if(kp==N){br="<br><br>"}if(c.1C("3c")){q V=$("<V>").o(c.C.2i);c.$K.1b("#1J-1M-1").3M(br).3M(V).3M(c.C.2i);c.jZ(V[0]);V.1w();c.7V()}I{q L=c.2B();if(L&&L.Q==="A"){q 2V=c.cT(L);q Y=$.28($(L).Y()).G(/\\n\\r\\n/g,"");q 4T=Y.1m;if(2V==4T){c.7V();q J=$(\'<V id="1J-1M-1">\'+c.C.2i+"</V>",c.X)[0];$(L).2E(J);$(J).3M(br+(c.1C("4C")?c.C.2i:""));c.1Y();F N}}c.$K.1b("#1J-1M-1").3M(br+(c.1C("4C")?c.C.2i:""));c.1Y()}},of:B(){c.aD(N)},ko:B(2g){q J=$("<br>"+c.C.2i);$(2g).2f(J);c.4b(J)},kk:B(o){o=c.1e("oe",E,o);if(c.1C("3t")){q 2H=$.28(o);if(2H.4G(/^<a(.*?)>(.*?)<\\/a>$/i)==0){o=o.G(/^<a(.*?)>(.*?)<\\/a>$/i,"$2")}}if(c.C.kj){q 2H=c.X.4y("12");o=o.G(/<br>|<\\/H[1-6]>|<\\/p>|<\\/12>/gi,"\\n");2H.3O=o;o=2H.9X||2H.bC;o=$.28(o);o=o.G("\\n","<br>");o=c.bj(o);c.aL(o);F E}q aO=E;if(c.7s("6i")){aO=N;q 6Y=c.C.ac;6Y.3a("3h");6Y.3a("1n");$.1u(6Y,B(i,s){o=o.G(2a 2L("<"+s+"(.*?)>","gi"),"");o=o.G(2a 2L("</"+s+">","gi"),"<br>")})}if(c.7s("6w")){o=c.kn(o);c.aL(o);F N}o=o.G(/<1z(.*?)v:oh=(.*?)>/gi,"");o=o.G(/<p(.*?)1x="oi"([\\w\\W]*?)<\\/p>/gi,"<2q><li$2</li>");o=o.G(/<p(.*?)1x="ok"([\\w\\W]*?)<\\/p>/gi,"<li$2</li>");o=o.G(/<p(.*?)1x="oj"([\\w\\W]*?)<\\/p>/gi,"<li$2</li></2q>");o=o.G(/<p(.*?)1x="ow"([\\w\\W]*?)<\\/p>/gi,"<2q><li$2</li></2q>");o=o.G(/·/g,"");o=o.G(/<!--[\\s\\S]*?-->|<\\?(?:4P)?[\\s\\S]*?\\?>/gi,"");if(c.C.kl===N){o=o.G(/(&3u;){2,}/gi,"&3u;");o=o.G(/&3u;/gi," ")}o=o.G(/<b\\ox="km-1v-1M(.*?)">([\\w\\W]*?)<\\/b>/gi,"$2");o=o.G(/<b(.*?)id="oJ-km-oI(.*?)">([\\w\\W]*?)<\\/b>/gi,"$3");o=o.G(/<V[^>]*(2F-1o: 3r; 2F-71: 3q|2F-71: 3q; 2F-1o: 3r)[^>]*>/gi,\'<V 1o="2F-71: 3q;"><V 1o="2F-1o: 3r;">\');o=o.G(/<V[^>]*2F-1o: 3r[^>]*>/gi,\'<V 1o="2F-1o: 3r;">\');o=o.G(/<V[^>]*2F-71: 3q[^>]*>/gi,\'<V 1o="2F-71: 3q;">\');o=o.G(/<V[^>]*Y-bP: 4W[^>]*>/gi,\'<V 1o="Y-bP: 4W;">\');o=o.G(/<1g>\\oH*<\\/1g>/gi,"[1g]");o=o.G(/<1g>&3u;<\\/1g>/gi,"[1g]");o=o.G(/<1g><br><\\/1g>/gi,"[1g]");o=o.G(/<1g(.*?)bc="(.*?)"(.*?)>([\\w\\W]*?)<\\/1g>/gi,\'[1g bc="$2"]$4[/1g]\');o=o.G(/<1g(.*?)bh="(.*?)"(.*?)>([\\w\\W]*?)<\\/1g>/gi,\'[1g bh="$2"]$4[/1g]\');o=o.G(/<a(.*?)1R="(.*?)"(.*?)>([\\w\\W]*?)<\\/a>/gi,\'[a 1R="$2"]$4[/a]\');o=o.G(/<1Q(.*?)>([\\w\\W]*?)<\\/1Q>/gi,"[1Q$1]$2[/1Q]");o=o.G(/<3C(.*?)>([\\w\\W]*?)<\\/3C>/gi,"[3C$1]$2[/3C]");o=o.G(/<5t(.*?)>([\\w\\W]*?)<\\/5t>/gi,"[5t$1]$2[/5t]");o=o.G(/<4X(.*?)>([\\w\\W]*?)<\\/4X>/gi,"[4X$1]$2[/4X]");o=o.G(/<3R(.*?)>([\\w\\W]*?)<\\/3R>/gi,"[3R$1]$2[/3R]");o=o.G(/<2K(.*?)>/gi,"[2K$1]");o=o.G(/<1z(.*?)>/gi,"[1z$1]");o=o.G(/ 1x="(.*?)"/gi,"");o=o.G(/<(\\w+)([\\w\\W]*?)>/gi,"<$1>");if(c.C.1N){o=o.G(/<43><\\/43>/gi,"");o=o.G(/<u><\\/u>/gi,"");if(c.C.bV){o=o.G(/<2F(.*?)>([\\w\\W]*?)<\\/2F>/gi,"$2")}o=o.G(/<[^\\/>][^>]*>(\\s*|\\t*|\\n*|&3u;|<br>)<\\/[^>]+>/gi,"<br>")}I{o=o.G(/<[^\\/>][^>]*>(\\s*|\\t*|\\n*|&3u;|<br>)<\\/[^>]+>/gi,"")}o=o.G(/<12>\\s*?\\t*?\\n*?(<2q>|<ol>|<p>)/gi,"$1");o=o.G(/\\[1g bc="(.*?)"\\]([\\w\\W]*?)\\[\\/1g\\]/gi,\'<1g bc="$1">$2</1g>\');o=o.G(/\\[1g bh="(.*?)"\\]([\\w\\W]*?)\\[\\/1g\\]/gi,\'<1g bh="$1">$2</1g>\');o=o.G(/\\[1g\\]/gi,"<1g>&3u;</1g>");o=o.G(/\\[a 1R="(.*?)"\\]([\\w\\W]*?)\\[\\/a\\]/gi,\'<a 1R="$1">$2</a>\');o=o.G(/\\[1Q(.*?)\\]([\\w\\W]*?)\\[\\/1Q\\]/gi,"<1Q$1>$2</1Q>");o=o.G(/\\[3C(.*?)\\]([\\w\\W]*?)\\[\\/3C\\]/gi,"<3C$1>$2</3C>");o=o.G(/\\[5t(.*?)\\]([\\w\\W]*?)\\[\\/5t\\]/gi,"<5t$1>$2</5t>");o=o.G(/\\[4X(.*?)\\]([\\w\\W]*?)\\[\\/4X\\]/gi,"<4X$1>$2</4X>");o=o.G(/\\[3R(.*?)\\]([\\w\\W]*?)\\[\\/3R\\]/gi,"<3R$1>$2</3R>");o=o.G(/\\[2K(.*?)\\]/gi,"<2K$1>");o=o.G(/\\[1z(.*?)\\]/gi,"<1z$1>");if(c.C.aP){o=o.G(/<12(.*?)>([\\w\\W]*?)<\\/12>/gi,"<p>$2</p>");o=o.G(/<\\/12><p>/gi,"<p>");o=o.G(/<\\/p><\\/12>/gi,"</p>");o=o.G(/<p><\\/p>/gi,"<br />")}I{o=o.G(/<12><\\/12>/gi,"<br />")}o=c.7S(o);if(c.7s("3f")){o=o.G(/<p>([\\w\\W]*?)<\\/p>/gi,"$1<br>")}I{if(aO===E){o=c.bj(o)}}o=o.G(/<V(.*?)>([\\w\\W]*?)<\\/V>/gi,"$2");o=o.G(/<1z>/gi,"");o=o.G(/<[^\\/>][^>][^1z|2K|1v|1g][^<]*>(\\s*|\\t*|\\n*| |<br>)<\\/[^>]+>/gi,"");o=o.G(/\\n{3,}/gi,"\\n");o=o.G(/<p><p>/gi,"<p>");o=o.G(/<\\/p><\\/p>/gi,"</p>");o=o.G(/<li>(\\s*|\\t*|\\n*)<p>/gi,"<li>");o=o.G(/<\\/p>(\\s*|\\t*|\\n*)<\\/li>/gi,"</li>");if(c.C.1N===N){o=o.G(/<p(.*?)>([\\w\\W]*?)<\\/p>/gi,"$2<br>")}o=o.G(/<[^\\/>][^>][^1z|2K|1v|1g][^<]*>(\\s*|\\t*|\\n*| |<br>)<\\/[^>]+>/gi,"");o=o.G(/<1z 3l="4C-oK-1L\\:\\/\\/(.*?)"(.*?)>/gi,"");o=o.G(/<1g(.*?)>(\\s*|\\t*|\\n*)<p>([\\w\\W]*?)<\\/p>(\\s*|\\t*|\\n*)<\\/1g>/gi,"<1g$1>$3</1g>");if(c.C.aP){o=o.G(/<12(.*?)>([\\w\\W]*?)<\\/12>/gi,"$2");o=o.G(/<12(.*?)>([\\w\\W]*?)<\\/12>/gi,"$2")}c.bY=E;if(c.1C("3c")){if(c.C.9l){q 2w=o.1S(/<1z 3l="1a:T(.*?)"(.*?)>/gi);if(2w!==2J){c.bY=2w;3w(k in 2w){q 1z=2w[k].G("<1z",\'<1z 1a-3c-aW-T="\'+k+\'" \');o=o.G(2w[k],1z)}}}3x(/<br>$/gi.4c(o)){o=o.G(/<br>$/gi,"")}}o=o.G(/<p>•([\\w\\W]*?)<\\/p>/gi,"<li>$1</li>");if(c.1C("3t")){3x(/<2F>([\\w\\W]*?)<\\/2F>/gi.4c(o)){o=o.G(/<2F>([\\w\\W]*?)<\\/2F>/gi,"$1")}}if(aO===E){o=o.G(/<1g(.*?)>([\\w\\W]*?)<p(.*?)>([\\w\\W]*?)<\\/1g>/gi,"<1g$1>$2$4</1g>");o=o.G(/<1g(.*?)>([\\w\\W]*?)<\\/p>([\\w\\W]*?)<\\/1g>/gi,"<1g$1>$2$3</1g>");o=o.G(/<1g(.*?)>([\\w\\W]*?)<p(.*?)>([\\w\\W]*?)<\\/1g>/gi,"<1g$1>$2$4</1g>");o=o.G(/<1g(.*?)>([\\w\\W]*?)<\\/p>([\\w\\W]*?)<\\/1g>/gi,"<1g$1>$2$3</1g>")}o=o.G(/\\n/g," ");o=o.G(/<p>\\n?<li>/gi,"<li>");c.aL(o)},kn:B(s){s=s.G(/<br>|<\\/H[1-6]>|<\\/p>|<\\/12>/gi,"\\n");q 2H=c.X.4y("12");2H.3O=s;F c.bZ(2H.9X||2H.bC)},aL:B(o){o=c.1e("oL",E,o);if(c.5O){c.$K.o(o);c.cn();c.bX();c.1j()}I{c.9m(o)}c.5O=E;2W($.M(B(){c.85=E;if(c.1C("3c")){c.$K.1b("p:6d").1w()}if(c.bY!==E){c.k3()}},c),3P);if(c.C.4K&&c.cl!==N){$(c.X.2v).3g(c.aX)}I{c.$K.3g(c.aX)}},cL:B(4q){if(c.C.3E!==E&&1E c.C.3E==="3R"){$.1u(c.C.3E,$.M(B(k,v){if(v!=2J&&v.3T().3W("#")===0){v=$(v).1p()}4q[k]=v},c))}F 4q},k3:B(){q jL=c.$K.1b("1z[1a-3c-aW-T]");$.1u(jL,$.M(B(i,s){q $s=$(s);q 2M=s.3l.4i(",");q 4q={eI:2M[0].4i(";")[0].4i(":")[1],1a:2M[1]};4q=c.cL(4q);$.7X(c.C.cJ,4q,$.M(B(1a){q 1K=(1E 1a==="8O"?$.8G(1a):1a);$s.1i("3l",1K.5Z);$s.2C("1a-3c-aW-T");c.1j();c.1e("3Z",$s,1K)},c))},c))},jK:B(e){q 9n=e.1O.9n;q 2M=9n.4i(",");q 4q={eI:2M[0].4i(";")[0].4i(":")[1],1a:2M[1]};if(c.C.9l){4q=c.cL(4q);$.7X(c.C.cJ,4q,$.M(B(1a){q 1K=(1E 1a==="8O"?$.8G(1a):1a);q o=\'<1z 3l="\'+1K.5Z+\'" id="jM-T-1M" />\';c.22("5b",o,E);q T=$(c.$K.1b("1z#jM-T-1M"));if(T.1m){T.2C("id")}I{T=E}c.1j();if(T){c.1e("3Z",T,1K)}},c))}I{c.9m(\'<1z 3l="\'+9n+\'" />\')}},1Z:B(2e){if(2e!==E){c.2e()}c.C.3J.3a(c.$K.o());if(2e!==E){c.7V("3J")}},jN:B(){if(c.C.3J.1m===0){c.4m();F}c.2e();c.C.7Y.3a(c.$K.o());c.1Y(E,N);c.$K.o(c.C.3J.jJ());c.1Y();2W($.M(c.7D,c),3P)},jO:B(){if(c.C.7Y.1m===0){c.4m();F E}c.2e();c.C.3J.3a(c.$K.o());c.1Y(E,N);c.$K.o(c.C.7Y.jJ());c.1Y(N);2W($.M(c.7D,c),4)},7D:B(){c.4F();if(c.C.5F){c.5F()}},5F:B(){c.$K.1b("a").on("25",$.M(c.jD,c));c.$K.on("25.U",$.M(B(e){c.7t(e)},c));$(X).on("25.U",$.M(B(e){c.7t(e)},c))},4F:B(){if(c.C.4F===E){F E}c.$K.1b("1z").1u($.M(B(i,1B){if(c.1C("3t")){$(1B).1i("nC","on")}q L=$(1B).L();if(!L.3v("cH")&&!L.3v("cM")){c.kZ(1B)}},c));c.$K.1b(".cM, .cH").on("25",$.M(c.oM,c))},jD:B(e){q $1s=$(e.1O);q L=$(e.1O).L();if(L.3v("cH")||L.3v("cM")){F}if($1s.1U()==0||$1s[0].Q!=="A"){F}q 3Y=$1s.2V();if(c.C.1Q){q cN=c.$2Z.2V();3Y.1T=cN.1T+(3Y.1T-$(c.X).3g());3Y.1t+=cN.1t}q 4w=$(\'<V 1x="U-1s-4w"></V>\');q 1R=$1s.1i("1R");if(1R===1I){1R=""}if(1R.1m>24){1R=1R.a8(0,24)+"..."}q jF=$(\'<a 1R="\'+$1s.1i("1R")+\'" 1O="6j">\'+1R+"</a>").on("25",$.M(B(e){c.7t(E)},c));q jG=$(\'<a 1R="#">\'+c.C.1F.84+"</a>").on("25",$.M(B(e){e.2x();c.an();c.7t(E)},c));q kv=$(\'<a 1R="#">\'+c.C.1F.67+"</a>").on("25",$.M(B(e){e.2x();c.22("67");c.7t(E)},c));4w.1h(jF);4w.1h(" | ");4w.1h(jG);4w.1h(" | ");4w.1h(kv);4w.1f({1T:(3Y.1T+20)+"px",1t:3Y.1t+"px"});$(".U-1s-4w").1w();$("2v").1h(4w)},7t:B(e){if(e!==E&&e.1O.Q=="A"){F E}$(".U-1s-4w").1w()},29:B(){if(!c.C.4a){F c.X.29()}I{if(!c.C.1Q){F 4a.29()}I{F 4a.29(c.$2Z[0])}}},3m:B(){if(!c.C.4a){if(c.X.29){q 1q=c.29();if(1q.41&&1q.51){F 1q.41(0)}}F c.X.5z()}I{if(!c.C.1Q){F 4a.5z()}I{F 4a.5z(c.bM())}}},cq:B(J){c.jQ(J)},4b:B(J){c.7O(J[0]||J,0,2J,0)},7e:B(J){c.7O(J[0]||J,1,2J,1)},7O:B(4U,cD,8k,9S){if(8k==2J){8k=4U}if(9S==2J){9S=cD}q 1q=c.29();if(!1q){F}if(4U.Q=="P"&&4U.3O==""){4U.3O=c.C.2i}if(4U.Q=="cP"&&c.C.1N===E){q 6r=$(c.C.5a)[0];$(4U).2f(6r);4U=6r;8k=4U}q O=c.3m();O.7W(4U,cD);O.8g(8k,9S);bK{1q.4O()}bI(e){}1q.5e(O)},cs:B(1d){1d=1d.3N();q 1l=c.2P();if(1l){q 3K=c.jH(1l,1d);c.1j();F 3K}q 1q=c.29();q O=1q.41(0);q 3K=X.4y(1d);3K.7c(O.oG());O.3A(3K);c.cq(3K);F 3K},oF:B(){q O=c.3m();O.9K(c.$K[0]);q 1q=c.29();1q.4O();1q.5e(O)},cn:B(){c.29().4O()},cT:B(2g){q co=0;q O=c.3m();q 9z=O.9p();9z.9K(2g);9z.8g(O.7Q,O.jP);co=$.28(9z.3T()).1m;F co},hx:B(){F 2a cp(c.29().41(0))},jQ:B(el,2u,3p){if(1E 3p==="1I"){3p=2u}el=el[0]||el;q O=c.3m();O.9K(el);q 4A=c.cy(el);q 9J=E;q 77=0,78;if(4A.1m==1&&2u){O.7W(4A[0],2u);O.8g(4A[0],3p)}I{3w(q i=0,8l;8l=4A[i++];){78=77+8l.1m;if(!9J&&2u>=77&&(2u<78||(2u==78&&i<4A.1m))){O.7W(8l,2u-77);9J=N}if(9J&&3p<=78){O.8g(8l,3p-77);8h}77=78}}q 1q=c.29();1q.4O();1q.5e(O)},jZ:B(J){c.$K.2j();J=J[0]||J;q O=c.X.5z();q 2u=1;q 3p=-1;O.7W(J,2u);O.8g(J,3p+2);q 1J=c.48.29();q cw=c.X.5z();q al=c.X.8d("\\7m");$(J).2E(al);cw.9d(al);1J.4O();1J.5e(cw);$(al).1w()},cy:B(J){q 4A=[];if(J.4v==3){4A.3a(J)}I{q 4k=J.8p;3w(q i=0,4T=4k.1m;i<4T;++i){4A.3a.cx(4A,c.cy(4k[i]))}}F 4A},3S:B(){q el=E;q 1q=c.29();if(1q&&1q.51>0){el=1q.41(0).5T}F c.4g(el)},2B:B(1B){1B=1B||c.3S();if(1B){F c.4g($(1B).L()[0])}I{F E}},2P:B(J){if(1E J==="1I"){J=c.3S()}3x(J){if(c.7n(J)){if($(J).3v("4e")){F E}F J}J=J.4Q}F E},3H:B(1V){q 8m=[];if(1E 1V=="1I"){q O=c.3m();if(O&&O.4M===N){F[c.2P()]}q 1V=c.7b(O)}$.1u(1V,$.M(B(i,J){if(c.C.1Q===E&&$(J).8y("12.4e").1U()==0){F E}if(c.7n(J)){8m.3a(J)}},c));if(8m.1m===0){8m=[c.2P()]}F 8m},oA:B(J){if(J.4v!=1){F E}F!c.a7.4c(J.jY)},7n:B(J){F J.4v==1&&c.a7.4c(J.jY)},bl:B(1d){F c.a7.4c(1d)},7b:B(O,1d){if(1E O=="1I"||O==E){q O=c.3m()}if(O&&O.4M===N){if(1E 1d==="1I"&&c.bl(1d)){q 1l=c.2P();if(1l.Q==1d){F[1l]}I{F[]}}I{F[c.3S()]}}q 1V=[],4z=[];q 1q=c.X.29();if(!1q.q2){1V=c.bk(1q.41(0))}$.1u(1V,$.M(B(i,J){if(c.C.1Q===E&&$(J).8y("12.4e").1U()==0){F E}if(1E 1d==="1I"){if($.28(J.9X)!=""){4z.3a(J)}}I{if(J.Q==1d){4z.3a(J)}}},c));if(4z.1m==0){if(1E 1d==="1I"&&c.bl(1d)){q 1l=c.2P();if(1l.Q==1d){F 4z.3a(1l)}I{F[]}}I{4z.3a(c.3S())}}q 2X=4z[4z.1m-1];if(c.7n(2X)){4z=4z.k0(0,-1)}F 4z},7U:B(J){if(!J){J=c.3S()}3x(J){if(J.4v==1){if($(J).3v("4e")){F E}F J}J=J.4Q}F E},bk:B(O){O=O||c.3m();q J=O.5T;q bL=O.7Q;if(J==bL){F[J]}q a5=[];3x(J&&J!=bL){a5.3a(J=c.jX(J))}J=O.5T;3x(J&&J!=O.oy){a5.k2(J);J=J.4Q}F a5},jX:B(J){if(J.oB()){F J.8z}I{3x(J&&!J.jS){J=J.4Q}if(!J){F 2J}F J.jS}},9V:B(){F c.29().3T()},jR:B(){q o="";q 1q=c.29();if(1q.51){q bB=c.X.4y("12");q 4T=1q.51;3w(q i=0;i<4T;++i){bB.7c(1q.41(i).oC())}o=bB.3O}F c.bF(o)},2e:B(){if(!c.7H()){c.4m()}if(!c.C.4a){c.jV(c.3m())}I{c.5M=4a.oE()}},jV:B(O,1w){if(!O){F}q 5K=$(\'<V id="1J-1M-1" 1x="U-1J-1M">\'+c.C.2i+"</V>",c.X)[0];q 7P=$(\'<V id="1J-1M-2" 1x="U-1J-1M">\'+c.C.2i+"</V>",c.X)[0];if(O.4M===N){c.9e(O,5K,N)}I{c.9e(O,5K,N);c.9e(O,7P,E)}c.5M=c.$K.o();c.1Y(E,E)},9e:B(O,J,1G){q 9j=O.9p();bK{9j.5I(1G);9j.3A(J);9j.oD()}bI(e){q o=c.C.5a;if(c.C.1N){o="<br>"}c.$K.6v(o);c.2j()}},1Y:B(G,1w){if(!c.C.4a){if(G===N&&c.5M){c.$K.o(c.5M)}q 5K=c.$K.1b("V#1J-1M-1");q 7P=c.$K.1b("V#1J-1M-2");if(c.1C("3c")){c.$K.2j()}I{if(!c.7H()){c.4m()}}if(5K.1m!=0&&7P.1m!=0){c.7O(5K[0],0,7P[0],0)}I{if(5K.1m!=0){c.7O(5K[0],0,2J,0)}}if(1w!==E){c.7V();c.5M=E}}I{4a.od(c.5M)}},7V:B(1G){if(!c.C.4a){$.1u(c.$K.1b("V.U-1J-1M"),B(){q o=$.28($(c).o().G(/[^\\oc-\\nP]/g,""));if(o==""){$(c).1w()}I{$(c).2C("1x").2C("id")}})}I{4a.nO(c.5M)}},l4:B(){c.2e();c.6l(c.C.1F.1n,c.C.hy,nN,$.M(B(){$("#hq").25($.M(c.kY,c));2W(B(){$("#eh").2j()},5l)},c))},kY:B(){c.1Z(E);q ae=$("#eh").1p(),ap=$("#hs").1p(),$bq=$("<12></12>"),bu=4x.jr(4x.j5()*j4),$1n=$(\'<1n id="1n\'+bu+\'"><7L></7L></1n>\'),i,$ak,z,$b9;3w(i=0;i<ae;i++){$ak=$("<3h></3h>");3w(z=0;z<ap;z++){$b9=$("<1g>"+c.C.2i+"</1g>");if(i===0&&z===0){$b9.1h(\'<V id="1J-1M-1">\'+c.C.2i+"</V>")}$($ak).1h($b9)}$1n.1h($ak)}$bq.1h($1n);q o=$bq.o();if(c.C.1N===E&&c.1C("3c")){o+="<p>"+c.C.2i+"</p>"}c.3b();c.1Y();q 1r=c.2P()||c.3S();if(1r&&1r.Q!="bp"){if(1r.Q=="3f"){q 1r=$(1r).2c("2q, ol")}$(1r).2E(o)}I{c.ah(o,E)}c.1Y();q 1n=c.$K.1b("#1n"+bu);c.7K();1n.1b("V#1J-1M-1, 4o#1J-1M-1").1w();1n.2C("id");c.1j()},l6:B(){q $1n=$(c.2B()).2c("1n");if(!c.4g($1n)){F E}if($1n.1U()==0){F E}c.1Z();$1n.1w();c.1j()},kV:B(){q L=c.2B();q $1n=$(L).2c("1n");if(!c.4g($1n)){F E}if($1n.1U()==0){F E}c.1Z();q $4r=$(L).2c("3h");q $bx=$4r.4Z().1m?$4r.4Z():$4r.4l();if($bx.1m){q $bw=$bx.4k("1g").l7();if($bw.1m){$bw.6v(\'<V id="1J-1M-1">\'+c.C.2i+"</V>")}}$4r.1w();c.1Y();$1n.1b("V#1J-1M-1").1w();c.1j()},kW:B(){q L=c.2B();q $1n=$(L).2c("1n");if(!c.4g($1n)){F E}if($1n.1U()==0){F E}c.1Z();q $6e=$(L).2c("1g");if(!($6e.is("1g"))){$6e=$6e.2c("1g")}q 2I=$6e.2R(0).nQ;$1n.1b("3h").1u($.M(B(i,1B){q ld=2I-1<0?2I+1:2I-1;if(i===0){$(1B).1b("1g").eq(ld).6v(\'<V id="1J-1M-1">\'+c.C.2i+"</V>")}$(1B).1b("1g").eq(2I).1w()},c));c.1Y();$1n.1b("V#1J-1M-1").1w();c.1j()},l8:B(){q $1n=$(c.2B()).2c("1n");if(!c.4g($1n)){F E}if($1n.1U()==0){F E}c.1Z();if($1n.1b("3X").1U()!==0){c.d8()}I{q 3h=$1n.1b("3h").l7().6f();3h.1b("1g").o(c.C.2i);$3X=$("<3X></3X>");$3X.1h(3h);$1n.6v($3X);c.1j()}},d8:B(){q $1n=$(c.2B()).2c("1n");if(!c.4g($1n)){F E}q $3X=$1n.1b("3X");if($3X.1U()==0){F E}c.1Z();$3X.1w();c.1j()},lc:B(){c.eE("3M")},la:B(){c.eE("2E")},kT:B(){c.eK("3M")},kR:B(){c.eK("2E")},eE:B(1G){q $1n=$(c.2B()).2c("1n");if(!c.4g($1n)){F E}if($1n.1U()==0){F E}c.1Z();q $4r=$(c.2B()).2c("3h");q bf=$4r.6f();bf.1b("1g").o(c.C.2i);if(1G==="2E"){$4r.2E(bf)}I{$4r.3M(bf)}c.1j()},eK:B(1G){q L=c.2B();q $1n=$(L).2c("1n");if(!c.4g($1n)){F E}if($1n.1U()==0){F E}c.1Z();q 2I=0;q 1r=c.3S();q $4r=$(1r).2c("3h");q $6e=$(1r).2c("1g");$4r.1b("1g").1u($.M(B(i,1B){if($(1B)[0]===$6e[0]){2I=i}},c));$1n.1b("3h").1u($.M(B(i,1B){q $1r=$(1B).1b("1g").eq(2I);q 1g=$1r.6f();1g.o(c.C.2i);1G==="2E"?$1r.2E(1g):$1r.3M(1g)},c));c.1j()},kC:B(){c.2e();c.6l(c.C.1F.3C,c.C.hp,nR,$.M(B(){$("#hv").25($.M(c.kD,c));2W(B(){$("#eT").2j()},5l)},c))},kD:B(){q 1a=$("#eT").1p();1a=c.7S(1a);q 5n=\'<1Q 2l="bW" 21="kQ" 3l="\',6U=\'" c2="0" kO></1Q>\';if(1a.1S(8s)){1a=1a.G(8s,5n+"//bg.bU.6V/4X/$1"+6U)}I{if(1a.1S(8x)){1a=1a.G(8x,5n+"//kH.bN.6V/3C/$2"+6U)}}c.1Y();q 1r=c.2P()||c.3S();if(1r){$(1r).2E(1a)}I{c.ah(1a,E)}c.1j();c.3b()},an:B(){c.2e();q 1e=$.M(B(){if(c.C.eQ!==E){c.ai={};q 4J=c;$.kI(c.C.eQ,B(1a){q $3n=$("#U-hz-hB");$3n.o("");$.1u(1a,B(1k,1p){4J.ai[1k]=1p;$3n.1h($("<47>").1p(1k).o(1p.2n))});$3n.on("5W",B(){q 1k=$(c).1p();q 2n="",1L="";if(1k!=0){2n=4J.ai[1k].2n;1L=4J.ai[1k].1L}$("#8j").1p(1L);$("#aa").1p(2n)});$3n.2N()})}c.7E=E;q 1q=c.29();q 1L="",Y="",1O="";q 1B=c.2B();q 6r=$(1B).L().2R(0);if(6r&&6r.Q==="A"){1B=6r}if(1B&&1B.Q==="A"){1L=1B.1R;Y=$(1B).Y();1O=1B.1O;c.7E=1B}I{Y=1q.3T()}$("#aa").1p(Y);q kE=kB.kA.1R.G(/\\/$/i,"");1L=1L.G(kE,"");1L=1L.G(/^\\/#/,"#");1L=1L.G("er:","");if(c.C.7I===E){q re=2a 2L("^(9W|9u|5C)://"+kB.kA.nT,"i");1L=1L.G(re,"")}$("#8j").1p(1L);if(1O==="6j"){$("#70").aS("aT",N)}c.eB=E;$("#hD").on("25",$.M(c.ky,c));2W(B(){$("#8j").2j()},5l)},c);c.6l(c.C.1F.1s,c.C.hA,nS,1e)},ky:B(){if(c.eB){F}c.eB=N;q 1O="",eS="";q 1s=$("#8j").1p();q Y=$("#aa").1p();if(1s.4G("@")!=-1&&/(9W|9u|5C):\\/\\//i.4c(1s)===E){1s="er:"+1s}I{if(1s.4G("#")!=0){if($("#70").aS("aT")){1O=\' 1O="6j"\';eS="6j"}q eo="((nM--)?[a-ep-9]+(-[a-ep-9]+)*.)+[a-z]{2,}";q re=2a 2L("^(9W|9u|5C)://"+eo,"i");q kM=2a 2L("^"+eo,"i");if(1s.4G(re)==-1&&1s.4G(kM)==0&&c.C.7I){1s=c.C.7I+1s}}}Y=Y.G(/<|>/g,"");q ek="&3u;";if(c.1C("3c")){ek="&3u;"}c.kK(\'<a 1R="\'+1s+\'"\'+1O+">"+Y+"</a>"+ek,$.28(Y),1s,eS)},kK:B(a,Y,1s,1O){c.1Y();if(Y!==""){if(c.7E){c.1Z();$(c.7E).Y(Y).1i("1R",1s);if(1O!==""){$(c.7E).1i("1O",1O)}I{$(c.7E).2C("1O")}}I{q $a=$(a).2y("U-eu-1s");c.2p("5b",c.49($a),E);q 1s=c.$K.1b("a.U-eu-1s");1s.2C("1o").3e("U-eu-1s").1u(B(){if(c.2U==""){$(c).2C("1x")}})}c.1j()}2W($.M(B(){if(c.C.5F){c.5F()}},c),5);c.3b()},kL:B(){c.2e();q 1e=$.M(B(){q 1q=c.29();q Y="";if(c.cv()){Y=1q.Y}I{Y=1q.3T()}$("#dE").1p(Y);if(!c.5c()&&!c.bH()){c.et("#5s",{1L:c.C.7N,3E:c.C.3E,4n:$.M(c.ew,c),3V:$.M(B(7F,1K){c.1e("ho",1K)},c),6x:c.C.dF})}c.e7("5s",{4d:N,1L:c.C.7N,4n:$.M(c.ew,c),3V:$.M(B(7F,1K){c.1e("ho",1K)},c)})},c);c.6l(c.C.1F.26,c.C.iw,bW,1e)},ew:B(1K){c.1Y();if(1K!==E){q Y=$("#dE").1p();if(Y===""){Y=1K.dI}q 1s=\'<a 1R="\'+1K.5Z+\'" id="5Z-1M">\'+Y+"</a>";if(c.1C("4C")&&!!c.48.cC){1s=1s+"&3u;"}c.22("5b",1s,E);q 7T=$(c.$K.1b("a#5Z-1M"));if(7T.1U()!=0){7T.2C("id")}I{7T=E}c.1j();c.1e("7N",7T,1K)}c.3b()},kJ:B(){c.2e();q 1e=$.M(B(){if(c.C.7k){$.kI(c.C.7k,$.M(B(1a){q 7j={},7o=0;$.1u(1a,$.M(B(1k,1p){if(1E 1p.a0!=="1I"){7o++;7j[1p.a0]=7o}},c));q 9c=E;$.1u(1a,$.M(B(1k,1p){q f0="";if(1E 1p.1c!=="1I"){f0=1p.1c}q 9G=0;if(!$.kx(7j)&&1E 1p.a0!=="1I"){9G=7j[1p.a0];if(9c===E){9c=".7h"+9G}}q 1z=$(\'<1z 3l="\'+1p.nL+\'" 1x="7h 7h\'+9G+\'" 4h="\'+1p.T+\'" 1c="\'+f0+\'" />\');$("#dN").1h(1z);$(1z).25($.M(c.iq,c))},c));if(!$.kx(7j)){$(".7h").2T();$(9c).2N();q kw=B(e){$(".7h").2T();$(".7h"+$(e.1O).1p()).2N()};q 3n=$(\'<3n id="nF">\');$.1u(7j,B(k,v){3n.1h($(\'<47 2t="\'+v+\'">\'+k+"</47>"))});$("#dN").3M(3n);3n.5W(kw)}},c))}I{$("#U-53-6A-2").1w()}if(c.C.3Z||c.C.5p){if(!c.5c()&&!c.bH()&&c.C.5p===E){if($("#5s").1m){c.et("#5s",{1L:c.C.3Z,3E:c.C.3E,4n:$.M(c.ed,c),3V:$.M(B(7F,1K){c.1e("by",1K)},c),6x:c.C.ba})}}if(c.C.5p===E){c.e7("5s",{4d:N,1L:c.C.3Z,4n:$.M(c.ed,c),3V:$.M(B(7F,1K){c.1e("by",1K)},c)})}I{$("#5s").on("5W.U",$.M(c.j6,c))}}I{$(".5x").2T();if(!c.C.7k){$("#5m").1w();$("#il").2N()}I{$("#U-53-6A-1").1w();$("#U-53-6A-2").2y("6S");$("#im").2N()}}if(!c.C.kF&&(c.C.3Z||c.C.7k)){$("#U-53-6A-3").2T()}$("#hV").25($.M(c.it,c));if(!c.C.3Z&&!c.C.7k){2W(B(){$("#6b").2j()},5l)}},c);c.6l(c.C.1F.T,c.C.ik,nE,1e)},jC:B(T){q $el=T;q L=$el.L().L();q 1e=$.M(B(){$("#dO").1p($el.1i("87"));$("#nD").1i("1R",$el.1i("3l"));if($el.1f("3i")=="1l"&&$el.1f("5o")=="3o"){$("#aQ").1p("6D")}I{$("#aQ").1p($el.1f("5o"))}if($(L).2R(0).Q==="A"){$("#6b").1p($(L).1i("1R"));if($(L).1i("1O")=="6j"){$("#70").aS("aT",N)}}$("#ii").25($.M(B(){c.d1($el)},c));$("#ij").25($.M(B(){c.l5($el)},c))},c);c.6l(c.C.1F.84,c.C.ip,nG,1e)},d1:B(el){q 8Y=$(el).L().L();q L=$(el).L();q ad=E;if(8Y.1m&&8Y[0].Q==="A"){ad=N;$(8Y).1w()}I{if(L.1m&&L[0].Q==="A"){ad=N;$(L).1w()}I{$(el).1w()}}if(L.1m&&L[0].Q==="P"){c.4m();if(ad===E){c.4b(L)}}c.1e("nH",el);c.3b();c.1j()},l5:B(el){c.62(E);q $el=$(el);q L=$el.L();$el.1i("87",$("#dO").1p());q bd=$("#aQ").1p();q 2G="";if(bd==="1t"){2G="0 "+c.C.8c+" "+c.C.8c+" 0";$el.1f({"5o":"1t",2G:2G})}I{if(bd==="4I"){2G="0 0 "+c.C.8c+" "+c.C.8c+"";$el.1f({"5o":"4I",2G:2G})}I{if(bd==="6D"){$el.1f({"5o":"",3i:"1l",2G:"4d"})}I{$el.1f({"5o":"",3i:"",2G:""})}}}q 1s=$.28($("#6b").1p());if(1s!==""){q 1O=E;if($("#70").aS("aT")){1O=N}if(L.2R(0).Q!=="A"){q a=$(\'<a 1R="\'+1s+\'">\'+c.49(el)+"</a>");if(1O){a.1i("1O","6j")}$el.2f(a)}I{L.1i("1R",1s);if(1O){L.1i("1O","6j")}I{L.2C("1O")}}}I{if(L.2R(0).Q==="A"){L.2f(c.49(el))}}c.3b();c.4F();c.1j()},62:B(e){if(e!==E&&$(e.1O).L().1U()!=0&&$(e.1O).L()[0].id==="U-T-2A"){F E}q 2Y=c.$K.1b("#U-T-2A");if(2Y.1U()==0){F E}c.$K.1b("#U-T-d6, #U-T-da").1w();2Y.1b("1z").1f({5H:2Y[0].1o.5H,9T:2Y[0].1o.9T,5D:2Y[0].1o.5D,9U:2Y[0].1o.9U});2Y.1f("2G","");2Y.1b("1z").1f("i5","");2Y.2f(B(){F $(c).1W()});$(X).3z("25.U-T-80-2T");c.$K.3z("25.U-T-80-2T");c.$K.3z("5y.U-T-d2");c.1j()},kZ:B(T){q $T=$(T);$T.on("8U",$.M(B(){c.62(E)},c));$T.on("nK",$.M(B(){c.$K.on("6y.U-T-l2-6y",$.M(B(){2W($.M(B(){c.4F();c.$K.3z("6y.U-T-l2-6y");c.1j()},c),1)},c))},c));$T.on("25",$.M(B(e){if(c.$K.1b("#U-T-2A").1U()!=0){F E}q nJ=E,9M,9F,dy=$T.2l()/$T.21(),i9=20,nI=10;q 5k=c.ib($T);q 9B=E;if(5k!==E){5k.on("8U",B(e){9B=N;e.2x();dy=$T.2l()/$T.21();9M=4x.6q(e.dw-$T.eq(0).2V().1t);9F=4x.6q(e.dg-$T.eq(0).2V().1T)});$(c.X.2v).on("jB",$.M(B(e){if(9B){q nU=4x.6q(e.dw-$T.eq(0).2V().1t)-9M;q i6=4x.6q(e.dg-$T.eq(0).2V().1T)-9F;q i7=$T.21();q i8=9C(i7,10)+i6;q 9H=4x.6q(i8*dy);if(9H>i9){$T.2l(9H);if(9H<3P){c.69.1f({5H:"-aM",5D:"-nV",8a:"o7",95:"o6 i1"})}I{c.69.1f({5H:"-92",5D:"-i4",8a:"92",95:"aM 9a"})}}9M=4x.6q(e.dw-$T.eq(0).2V().1t);9F=4x.6q(e.dg-$T.eq(0).2V().1T);c.1j()}},c)).on("9x",B(){9B=E})}c.$K.on("5y.U-T-d2",$.M(B(e){q 1k=e.6h;if(c.2O.9D==1k||c.2O.d3==1k){c.1Z(E);c.62(E);c.d1($T)}},c));$(X).on("25.U-T-80-2T",$.M(c.62,c));c.$K.on("25.U-T-80-2T",$.M(c.62,c))},c))},ib:B($T){q 2Y=$(\'<V id="U-T-2A" 1a-U="8R">\');2Y.1f({3j:"ia",3i:"4o-1l",d7:0,o5:"i3 o8 o9(0, 0, 0, .6)","5o":$T.1f("5o")});2Y.1i("3F",E);if($T[0].1o.2G!="4d"){2Y.1f({5H:$T[0].1o.5H,9T:$T[0].1o.9T,5D:$T[0].1o.5D,9U:$T[0].1o.9U});$T.1f("2G","")}I{2Y.1f({3i:"1l",2G:"4d"})}$T.1f("i5",0.5).2E(2Y);c.69=$(\'<V id="U-T-d6" 1a-U="8R">\'+c.C.1F.84+"</V>");c.69.1f({3j:"8B",8Q:5,1T:"50%",1t:"50%",5H:"-92",5D:"-i4",d7:1,ic:"#ie",8i:"#i2",8a:"92",95:"aM 9a",eM:"ob"});c.69.1i("3F",E);c.69.on("25",$.M(B(){c.jC($T)},c));2Y.1h(c.69);if(c.C.hX){q 5k=$(\'<V id="U-T-da" 1a-U="8R"></V>\');5k.1f({3j:"8B",8Q:2,d7:1,eM:"nw-80",i0:"-oa",4I:"-i1",o4:"i3 o3 #i2",ic:"#ie",2l:"ir",21:"ir"});5k.1i("3F",E);2Y.1h(5k);2Y.1h($T);F 5k}I{2Y.1h($T);F E}},iq:B(e){q 1z=\'<1z id="T-1M" 3l="\'+$(e.1O).1i("4h")+\'" 87="\'+$(e.1O).1i("1c")+\'" />\';q L=c.2B();if(c.C.6a&&$(L).2c("li").1U()==0){1z="<p>"+1z+"</p>"}c.9k(1z,N)},it:B(){q 1p=$("#6b").1p();if(1p!==""){q 1a=\'<1z id="T-1M" 3l="\'+1p+\'" />\';if(c.C.1N===E){1a="<p>"+1a+"</p>"}c.9k(1a,N)}I{c.3b()}},ed:B(1a){c.9k(1a)},9k:B(1K,1s){c.1Y();if(1K!==E){q o="";if(1s!==N){o=\'<1z id="T-1M" 3l="\'+1K.5Z+\'" />\';q L=c.2B();if(c.C.6a&&$(L).2c("li").1U()==0){o="<p>"+o+"</p>"}}I{o=1K}c.22("5b",o,E);q T=$(c.$K.1b("1z#T-1M"));if(T.1m){T.2C("id")}I{T=E}c.1j();1s!==N&&c.1e("3Z",T,1K)}c.3b();c.4F()},dY:B(){if($("#U-eO").1U()!=0){F}c.$aU=$(\'<12 id="U-eO"><V></V></12>\');$(X.2v).1h(c.$aU)},8I:B(){c.dY();c.$aU.nY()},9Z:B(){c.dY();c.$aU.6J(nX)},iu:B(){$.4H(c.C,{iw:4S()+\'<2m id="U-6g-26-4u"><2s id="nW" 5w="7X" 7q="" a6="9q/2s-1a"><2D>\'+c.C.1F.dI+\'</2D><2S 1G="Y" id="dE" 1x="6T" /><12 1o="2G-1T: aM;"><2S 1G="26" id="5s" 2n="\'+c.C.dF+\'" /></12></2s></2m>\',ip:4S()+\'<2m id="U-6g-T-84"><2D>\'+c.C.1F.1c+\'</2D><2S 1G="Y" id="dO" 1x="6T" /><2D>\'+c.C.1F.1s+\'</2D><2S 1G="Y" id="6b" 1x="6T" /><2D><2S 1G="hE" id="70"> \'+c.C.1F.dA+"</2D><2D>"+c.C.1F.io+\'</2D><3n id="aQ"><47 2t="3o">\'+c.C.1F.3o+\'</47><47 2t="1t">\'+c.C.1F.1t+\'</47><47 2t="6D">\'+c.C.1F.6D+\'</47><47 2t="4I">\'+c.C.1F.4I+\'</47></3n></2m><44><1D id="ii" 1x="4t nZ">\'+c.C.1F.ih+\'</1D><1D 1x="4t 6L">\'+c.C.1F.6I+\'</1D><1D id="ij" 1x="4t 6K">\'+c.C.1F.83+"</1D></44>",ik:4S()+\'<2m id="U-6g-T-4u"><12 id="5m"><a 1R="#" id="U-53-6A-1" 1x="6S">\'+c.C.1F.8r+\'</a><a 1R="#" id="U-53-6A-2">\'+c.C.1F.dR+\'</a><a 1R="#" id="U-53-6A-3">\'+c.C.1F.1s+\'</a></12><2s id="o0" 5w="7X" 7q="" a6="9q/2s-1a"><12 id="o2" 1x="5x"><2S 1G="26" id="5s" 2n="\'+c.C.ba+\'" /></12><12 id="im" 1x="5x" 1o="3i: 3o;"><12 id="dN"></12></12></2s><12 id="il" 1x="5x" 1o="3i: 3o;"><2D>\'+c.C.1F.hW+\'</2D><2S 1G="Y" 2n="6b" id="6b" 1x="6T" /><br><br></12></2m><44><1D 1x="4t 6L">\'+c.C.1F.6I+\'</1D><1D 1x="4t 6K" id="hV">\'+c.C.1F.4u+"</1D></44>",hA:4S()+\'<2m id="U-6g-1s-4u"><3n id="U-hz-hB" 1o="2l: 99.5%; 3i: 3o;"></3n><2D>hC</2D><2S 1G="Y" 1x="6T" id="8j" /><2D>\'+c.C.1F.Y+\'</2D><2S 1G="Y" 1x="6T" id="aa" /><2D><2S 1G="hE" id="70"> \'+c.C.1F.dA+\'</2D></2m><44><1D 1x="4t 6L">\'+c.C.1F.6I+\'</1D><1D id="hD" 1x="4t 6K">\'+c.C.1F.4u+"</1D></44>",hy:4S()+\'<2m id="U-6g-1n-4u"><2D>\'+c.C.1F.ae+\'</2D><2S 1G="Y" 1U="5" 2t="2" id="eh" /><2D>\'+c.C.1F.ap+\'</2D><2S 1G="Y" 1U="5" 2t="3" id="hs" /></2m><44><1D 1x="4t 6L">\'+c.C.1F.6I+\'</1D><1D id="hq" 1x="4t 6K">\'+c.C.1F.4u+"</1D></44>",hp:4S()+\'<2m id="U-6g-3C-4u"><2s id="o1"><2D>\'+c.C.1F.ht+\'</2D><5R id="eT" 1o="2l: 99%; 21: oO;"></5R></2s></2m><44><1D 1x="4t 6L">\'+c.C.1F.6I+\'</1D><1D id="hv" 1x="4t 6K">\'+c.C.1F.4u+"</1D></44>"})},6l:B(1c,3I,2l,1e){c.hL();c.$a1=2l;c.$2Q=$("#fe");if(!c.$2Q.1m){c.$2Q=$(\'<12 id="fe" 1o="3i: 3o;" />\');c.$2Q.1h($(\'<12 id="eR">&oP;</12>\'));c.$2Q.1h($(\'<aI id="9i" />\'));c.$2Q.1h($(\'<12 id="at" />\'));c.$2Q.8D(X.2v)}$("#eR").on("25",$.M(c.3b,c));$(X).58($.M(c.ez,c));c.$K.58($.M(c.ez,c));c.hI(3I);c.hH(1c);c.ix();c.jh();c.hM();c.hJ();c.6Z=c.X.2v.3g;if(c.C.4K===E){c.6Z=c.$K.3g()}if(c.5c()===E){c.hU()}I{c.hO()}if(1E 1e==="B"){1e()}2W($.M(B(){c.1e("pE",c.$2Q)},c),11);$(X).3z("pD.6g");c.$2Q.1b("2S[1G=Y]").on("pC",$.M(B(e){if(e.6h===13){c.$2Q.1b(".6K").25();e.2x()}},c));F c.$2Q},hU:B(){c.$2Q.1f({3j:"9w",1T:"-d4",1t:"50%",2l:c.$a1+"px",5D:"-"+(c.$a1/2)+"px"}).2N();c.dB=$(X.2v).1f("af");$(X.2v).1f("af","8F");2W($.M(B(){q 21=c.$2Q.jk();c.$2Q.1f({1T:"50%",21:"4d",7R:"4d",5H:"-"+(21+10)/2+"px"})},c),15)},hO:B(){c.$2Q.1f({3j:"9w",2l:"3P%",21:"3P%",1T:"0",1t:"0",2G:"0",7R:"pF"}).2N()},hI:B(3I){c.6o=E;if(3I.3W("#")==0){c.6o=$(3I);$("#at").6d().1h(c.6o.o());c.6o.o("")}I{$("#at").6d().1h(3I)}},hH:B(1c){c.$2Q.1b("#9i").o(1c)},hJ:B(){q 42=c.$2Q.1b("44 1D").ar(".pG");q eD=42.1U();if(eD>0){$(42).1f("2l",(c.$a1/eD)+"px")}},hM:B(){c.$2Q.1b(".6L").on("25",$.M(c.3b,c))},hL:B(){if(c.C.eX){c.$8M=$("#eY");if(!c.$8M.1m){c.$8M=$(\'<12 id="eY" 1o="3i: 3o;"></12>\');$("2v").6v(c.$8M)}c.$8M.2N().on("25",$.M(c.3b,c))}},ix:B(){if(1E $.fn.iy!=="1I"){c.$2Q.iy({pI:"#9i"});c.$2Q.1b("#9i").1f("eM","pH")}},jh:B(){q $5m=$("#5m");if(!$5m.1m){F E}q 4J=c;$5m.1b("a").1u(B(i,s){i++;$(s).on("25",B(e){e.2x();$5m.1b("a").3e("6S");$(c).2y("6S");$(".5x").2T();$("#5x"+i).2N();$("#pB").1p(i);if(4J.5c()===E){q 21=4J.$2Q.jk();4J.$2Q.1f("2G-1T","-"+(21+10)/2+"px")}})})},ez:B(e){if(e.2O===c.2O.eA){c.3b();F E}},3b:B(){$("#eR").3z("25",c.3b);$("#fe").6J("pA",$.M(B(){q fb=$("#at");if(c.6o!==E){c.6o.o(fb.o());c.6o=E}fb.o("");if(c.C.eX){$("#eY").2T().3z("25",c.3b)}$(X).je("58",c.jd);c.$K.je("58",c.jd);c.1Y();if(c.C.4K&&c.6Z){$(c.X.2v).3g(c.6Z)}I{if(c.C.4K===E&&c.6Z){c.$K.3g(c.6Z)}}c.1e("pu")},c));if(c.5c()===E){$(X.2v).1f("af",c.dB?c.dB:"j7")}F E},pt:B(dC){$(".5x").2T();$("#5m").1b("a").3e("6S").eq(dC-1).2y("6S");$("#5x"+dC).2N()},j6:B(e){q 7d=e.1O.7d;3w(q i=0,f;f=7d[i];i++){c.e2(f)}},e2:B(26){c.ja(26,$.M(B(j9){c.jz(26,j9)},c))},ja:B(26,1e){q 2k=2a jy();q ee="?";if(c.C.5p.4G(/\\?/)!="-1"){ee="&"}2k.b1("ps",c.C.5p+ee+"2n="+26.2n+"&1G="+26.1G,N);if(2k.jl){2k.jl("Y/pv; pw=x-pz-py")}q 4J=c;2k.pJ=B(e){if(c.jv==4&&c.e9==5l){4J.8I();1e(pK(c.pW))}I{if(c.jv==4&&c.e9!=5l){}}};2k.jp()},ju:B(5w,1L){q 2k=2a jy();if("pV"in 2k){2k.b1(5w,1L,N)}I{if(1E jA!="1I"){2k=2a jA();2k.b1(5w,1L)}I{2k=2J}}F 2k},jz:B(26,1L){q 2k=c.ju("pU",1L);if(!2k){}I{2k.jt=$.M(B(){if(2k.e9==5l){c.9Z();q eg=1L.4i("?");if(!eg[0]){F E}c.1Y();q o="";o=\'<1z id="T-1M" 3l="\'+eg[0]+\'" />\';if(c.C.6a){o="<p>"+o+"</p>"}c.22("5b",o,E);q T=$(c.$K.1b("1z#T-1M"));if(T.1m){T.2C("id")}I{T=E}c.1j();c.1e("3Z",T,E);c.3b();c.4F()}I{}},c);2k.pX=B(){};2k.8r.pY=B(e){};2k.jo("q0-pZ",26.1G);2k.jo("x-pT-pS","pN-pM");2k.jp(26)}},e7:B(el,3Q){c.3B={1L:E,4n:E,3V:E,2u:E,e0:E,4d:E,2S:E};$.4H(c.3B,3Q);q $el=$("#"+el);if($el.1m&&$el[0].Q==="pL"){c.3B.2S=$el;c.el=$($el[0].2s)}I{c.el=$el}c.iC=c.el.1i("7q");if(c.3B.4d){$(c.3B.2S).5W($.M(B(e){c.el.dn(B(e){F E});c.dZ(e)},c))}I{if(c.3B.e0){$("#"+c.3B.e0).25($.M(c.dZ,c))}}},dZ:B(e){c.8I();c.iI(c.2g,c.js())},js:B(){c.id="f"+4x.jr(4x.j5()*j4);q d=c.X.4y("12");q 1Q=\'<1Q 1o="3i:3o" id="\'+c.id+\'" 2n="\'+c.id+\'"></1Q>\';d.3O=1Q;$(d).8D("2v");if(c.3B.2u){c.3B.2u()}$("#"+c.id).iJ($.M(c.iH,c));F c.id},iI:B(f,2n){if(c.3B.2S){q cZ="pO"+c.id,iN="pP"+c.id;c.2s=$(\'<2s 7q="\'+c.3B.1L+\'" 5w="eH" 1O="\'+2n+\'" 2n="\'+cZ+\'" id="\'+cZ+\'" a6="9q/2s-1a" />\');if(c.C.3E!==E&&1E c.C.3E==="3R"){$.1u(c.C.3E,$.M(B(k,v){if(v!=2J&&v.3T().3W("#")===0){v=$(v).1p()}q 8F=$("<2S/>",{1G:"8F",2n:k,2t:v});$(c.2s).1h(8F)},c))}q d0=c.3B.2S;q 8A=$(d0).6f();$(d0).1i("id",iN).3M(8A).8D(c.2s);$(c.2s).1f("3j","8B").1f("1T","-d4").1f("1t","-d4").8D("2v");c.2s.dn()}I{f.1i("1O",2n).1i("5w","eH").1i("a6","9q/2s-1a").1i("7q",c.3B.1L);c.2g.dn()}},iH:B(){q i=$("#"+c.id)[0],d;if(i.iG){d=i.iG}I{if(i.dp){d=i.dp.X}I{d=48.pR[c.id].X}}if(c.3B.4n){c.9Z();if(1E d!=="1I"){q iA=d.2v.3O;q 7g=iA.1S(/\\{(.|\\n)*\\}/)[0];7g=7g.G(/^\\[/,"");7g=7g.G(/\\]$/,"");q 1K=$.8G(7g);if(1E 1K.3V=="1I"){c.3B.4n(1K)}I{c.3B.3V(c,1K);c.3b()}}I{c.3b();pQ("iz pr!")}}c.el.1i("7q",c.iC);c.el.1i("1O","")},et:B(el,3Q){c.5P=$.4H({1L:E,4n:E,3V:E,pq:E,3E:E,Y:c.C.1F.iD,iO:c.C.1F.iF,6x:E},3Q);if(48.eP===1I){F E}c.eU=$(\'<12 1x="p2"></12>\');c.5f=$(\'<12 1x="p1">\'+c.5P.Y+"</12>");c.iP=$(\'<12 1x="p0">\'+c.5P.iO+"</12>");c.eU.1h(c.5f);$(el).3M(c.eU);$(el).3M(c.iP);c.5f.on("p3",$.M(B(){F c.iU()},c));c.5f.on("p4",$.M(B(){F c.hY()},c));c.5f.2R(0).p6=$.M(B(e){e.2x();c.5f.3e("bo").2y("6y");c.8I();c.ey(c.5P.1L,e.8T.7d[0],E,e,c.5P.6x)},c)},ey:B(1L,26,bv,e,6x){if(!bv){q 2k=$.p5.2k();if(2k.8r){2k.8r.oZ("eO",$.M(c.iV,c),E)}$.oY({2k:B(){F 2k}})}c.1e("6y",e);q fd=2a eP();if(6x!==E){fd.1h(6x,26)}I{fd.1h("26",26)}if(c.C.3E!==E&&1E c.C.3E==="3R"){$.1u(c.C.3E,$.M(B(k,v){if(v!=2J&&v.3T().3W("#")===0){v=$(v).1p()}fd.1h(k,v)},c))}$.j2({1L:1L,oS:"o",1a:fd,oR:E,eI:E,oQ:E,1G:"eH",4n:$.M(B(1a){1a=1a.G(/^\\[/,"");1a=1a.G(/\\]$/,"");q 1K=(1E 1a==="8O"?$.8G(1a):1a);c.9Z();if(bv){q $1z=$("<1z>");$1z.1i("3l",1K.5Z).1i("id","iT-T-1M");c.iS(e,$1z[0]);q T=$(c.$K.1b("1z#iT-T-1M"));if(T.1m){T.2C("id")}I{T=E}c.1j();c.4F();if(T){c.1e("3Z",T,1K)}if(1E 1K.3V!=="1I"){c.1e("by",1K)}}I{if(1E 1K.3V=="1I"){c.5P.4n(1K)}I{c.5P.3V(c,1K);c.5P.4n(E)}}},c)})},iU:B(){c.5f.2y("bo");F E},hY:B(){c.5f.3e("bo");F E},iV:B(e,Y){q j0=e.iQ?9C(e.iQ/e.oT*3P,10):e;c.5f.Y("oU "+j0+"% "+(Y||""))},5c:B(){F/(oX|oW|oV|p7)/.4c(6k.7i)},bH:B(){F/p8/.4c(6k.7i)},9g:B(4D){if(1E(4D)==="1I"){F 0}F 9C(4D.G("px",""),10)},49:B(el){F $("<12>").1h($(el).eq(0).6f()).o()},pl:B(o){q 2H=X.4y("8J");2H.3O=o;F 2H.9X||2H.bC||""},iE:B(7F){F pk.5g.3T.5B(7F)=="[3R 4S]"},a4:B(o){o=o.G(/&#aY;|<br>|<br\\/>|&3u;/gi,"");o=o.G(/\\s/g,"");o=o.G(/^<p>[^\\W\\w\\D\\d]*?<\\/p>$/i,"");F o==""},pj:B(){q rv=E;if(6k.pm=="pn pp po"){q 3U=6k.7i;q re=2a 2L("pi ([0-9]{1,}[.0-9]{0,})");if(re.2p(3U)!=2J){rv=pg(2L.$1)}}F rv},8N:B(){F!!6k.7i.1S(/pb\\/7\\./)},1C:B(1C){q 3U=6k.7i.3N();q 1S=/(jc)[\\/]([\\w.]+)/.2p(3U)||/(cC)[ \\/]([\\w.]+)/.2p(3U)||/(4C)[ \\/]([\\w.]+).*(pa)[ \\/]([\\w.]+)/.2p(3U)||/(4C)[ \\/]([\\w.]+)/.2p(3U)||/(8S)(?:.*9y|)[ \\/]([\\w.]+)/.2p(3U)||/(3t) ([\\w.]+)/.2p(3U)||3U.3W("p9")>=0&&/(rv)(?::| )([\\w.]+)/.2p(3U)||3U.3W("pc")<0&&/(3c)(?:.*? rv:([\\w.]+)|)/.2p(3U)||[];if(1C=="9y"){F 1S[2]}if(1C=="4C"){F(1S[1]=="cC"||1S[1]=="4C")}if(1S[1]=="rv"){F 1C=="3t"}if(1S[1]=="jc"){F 1C=="4C"}F 1C==1S[1]},cv:B(){if(c.1C("3t")&&9C(c.1C("9y"),10)<9){F N}F E},hR:B(hQ){q 7a=hQ.pd(N);q 12=c.X.4y("12");12.7c(7a);F 12.3O},cE:B(){q J=c.$K[0];q 4f=c.X.cO();q cQ;3x((cQ=J.8z)){4f.7c(cQ)}F 4f},4g:B(el){if(!el){F E}if(c.C.1Q){F el}if($(el).8y("12.4e").1m==0||$(el).3v("4e")){F E}I{F el}},7s:B(Q){q L=c.2B(),1r=c.3S();F L&&L.Q===Q?L:1r&&1r.Q===Q?1r:E},cR:B(){q 1r=c.2P();q 2V=c.cT(1r);q Y=$.28($(1r).Y()).G(/\\n\\r\\n/g,"");q 4T=Y.1m;if(2V==4T){F N}I{F E}},7H:B(){q el,1q=c.29();if(1q&&1q.51&&1q.51>0){el=1q.41(0).5T}if(!el){F E}if(c.C.1Q){if(c.hx().iv()){F!c.$K.is(el)}I{F N}}F $(el).2c("12.4e").1m!=0},4V:B(el,1i){if($(el).1i(1i)==""){$(el).2C(1i)}},lb:B(9s,2t){q 2I=2J;3x((2I=9s.3W(2t))!==-1){9s.9r(2I,1)}F 9s}};3G.5g.7B.5g=3G.5g;$.3G.fn.c6=B(c8,6P,68,6O,6N){q 1L=/(((5C?|pf?):\\/\\/)|bg[.][^\\s])(.+?\\..+?)([.),]?)(\\s|\\.\\s+|\\)|$)/gi,kU=/(5C?|9u):\\/\\//i,bS=/(5C?:\\/\\/.*\\.(?:le|pe|kP|kN))/gi;q 8p=(c.$K?c.$K.2R(0):c).8p,i=8p.1m;3x(i--){q n=8p[i];if(n.4v===3){q o=n.aZ;if(6O&&o){q 5n=\'<1Q 2l="bW" 21="kQ" 3l="\',6U=\'" c2="0" kO></1Q>\';if(o.1S(8s)){o=o.G(8s,5n+"//bg.bU.6V/4X/$1"+6U);$(n).2E(o).1w()}I{if(o.1S(8x)){o=o.G(8x,5n+"//kH.bN.6V/3C/$2"+6U);$(n).2E(o).1w()}}}if(68&&o&&o.1S(bS)){o=o.G(bS,\'<1z 3l="$1">\');$(n).2E(o).1w()}if(6P&&o&&o.1S(1L)){q 2w=o.1S(1L);3w(q i in 2w){q 1R=2w[i];q Y=1R;q 6s="";if(1R.1S(/\\s$/)!==2J){6s=" "}q cj=c8;if(1R.1S(kU)!==2J){cj=""}if(Y.1m>6N){Y=Y.a8(0,6N)+"..."}Y=Y.G(/&/g,"&ab;").G(/</g,"<").G(/>/g,">");q ku=Y.G("$","$$$");o=o.G(1R,\'<a 1R="\'+cj+$.28(1R)+\'">\'+$.28(ku)+"</a>"+6s)}$(n).2E(o).1w()}}I{if(n.4v===1&&!/^(a|1D|5R)$/i.4c(n.Q)){$.3G.fn.c6.5B(n,c8,6P,68,6O,6N)}}}}})(oN);',62,1711,'||||||||||||this||||||||||||html||var|||||||||||function|opts||false|return|replace||else|node|editor|parent|proxy|true|range||tagName|||image|redactor|span||document|text||||div||||||||data|find|title|tag|callback|css|td|append|attr|sync|key|block|length|table|style|val|sel|current|link|left|each|source|remove|class|lang|img|toolbar|elem|browser|button|typeof|curLang|type|func|undefined|selection|json|url|marker|linebreaks|target|dropdown|iframe|href|match|top|size|nodes|contents|out|selectionRestore|bufferSet||height|execCommand|cmd||click|file||trim|getSelection|new|btn|closest|btnObject|selectionSave|replaceWith|element|blockquote|invisibleSpace|focus|xhr|width|section|name|code|exec|ul|pre|form|value|start|body|matches|preventDefault|addClass|btnName|box|getParent|removeAttr|label|after|font|margin|tmp|index|null|param|RegExp|arr|show|keyCode|getBlock|redactorModal|get|input|hide|className|offset|setTimeout|last|imageBox|frame|list|point|||||||||push|modalClose|mozilla|air|removeClass|LI|scrollTop|tr|display|position|ctrl|src|getRange|select|none|end|bold|italic|script|msie|nbsp|hasClass|for|while|doc|off|insertNode|uploadOptions|video|blocks|uploadFields|contenteditable|Redactor|getBlocks|content|buffer|wrapper|BLOCKQUOTE|before|toLowerCase|innerHTML|100|options|object|getCurrent|toString|ua|error|indexOf|thead|pos|imageUpload||getRangeAt|buttons|strong|footer|||option|window|outerHtml|rangy|selectionStart|test|auto|redactor_editor|frag|isParentRedactor|rel|split|fullpage|children|next|focusWithSaveScroll|success|inline|elems|postData|current_tr|buttonGet|redactor_modal_btn|insert|nodeType|tooltip|Math|createElement|finalnodes|textNodes|htmls|webkit|str|meta|observeImages|search|extend|right|that|autoresize|inArray|collapsed|substr|removeAllRanges|php|parentNode|placeholder|String|len|orgn|removeEmptyAttr|underline|embed|cont|prev||rangeCount|keys|tab|align|blockElem|del|redactor_placeholder|keyup||emptyHtml|inserthtml|isMobile|shiftKey|addRange|dropareabox|prototype|rule|formatBlocks|deleted|imageResizer|200|redactor_tabs|iframeStart|float|s3|listTag|alignmentTags|redactor_file|audio|charAt|replaced|method|redactor_tab|keydown|createRange|newTag|call|https|marginLeft|listCurrent|observeLinks|allowedTags|marginTop|collapse|strike|node1|visual|savedSel|lastNode|selectall|draguploadOptions|regex|textarea|indent|startContainer|join|unorderedlist|change|boldTag|italicTag|filelink|||imageResizeHide|direction|toolbarFixed|||unlink|convertImageLinks|imageEditter|paragraphy|redactor_file_link|formatting|empty|current_td|clone|modal|which|TD|_blank|navigator|modalInit|dir|modified|modalcontent|shortcuts|round|par|space|event|orderedlist|prepend|PRE|uploadParam|drop|textareamode|control|formatBlock|Insert|center|enter|listParent|replacementTag|instance|cancel|fadeOut|redactor_modal_action_btn|redactor_btn_modal_close|buttonActive|linkSize|convertVideoLinks|convertLinks|insertAfterLastElement|tmpList|redactor_tabs_act|redactor_input|iframeEnd|com|outdent|buttonBuild|blocksElems|saveModalScroll|redactor_link_blank|weight|isFunction||possible|etags|item|charCount|endCharCount|cleanRemoveSpaces|cloned|getNodes|appendChild|files|selectionEnd|thtml|jsonString|redactorfolder|userAgent|folders|imageGetJson|phpMatches|u200B|nodeTestBlocks|count|autosave|action|hideHandler|currentOrParentIs|linkObserverTooltipClose|dropact|newblock|modif|set|tabindex|uuid|fullpageDoctype|init|cleanGetTabs|observeStart|insert_link_node|obj|elements|isFocused|linkProtocol|setNonEditable|buttonActiveObserver|tbody|deniedTags|fileUpload|selectionSet|node2|endContainer|minHeight|cleanStripTags|linkmarker|getElement|selectionRemoveMarkers|setStart|post|rebuffer|tagblock|resize|tagout|insertunorderedlist|save|edit|rtePaste|cleanlevel|alt|alignmentSet|dblEnter|fontSize|horizontalrule|imageFloatMargin|createTextNode|phpTags|insertorderedlist|setEnd|break|color|redactor_link_url|focn|textNode|newnodes|tmpLi|Delete|childNodes|Header|upload|reUrlYoutube|redactor_act|typewriter|boxTop|toolbarFixedTarget|reUrlVimeo|parents|firstChild|newElement|absolute|character|appendTo|shift|hidden|parseJSON|keyPosition|showProgressBar|DIV|metaKey|Add|redactorModalOverlay|isIe11|string|toolbarExternal|zIndex|verified|opera|dataTransfer|mousedown|specialKey|hdlHideDropDown|special|parentLink|one|||11px|spans|allowed|padding|||||10px|background|folderclass|setStartAfter|selectionSetMarker|codeLength|normalize|airBindMousemoveHide|redactor_modal_header|boundaryRange|imageInsert|clipboardUpload|insertHtml|result|placeTag|cloneRange|multipart|splice|array|dropdownHideAll|ftp|line|fixed|mouseup|version|preCaretRange||isResizing|parseInt|BACKSPACE|focusSet|start_y|folderkey|new_w|javascript|foundStart|selectNodeContents|documentElement|start_x|autosaveInterval|case|inlineRemoveFormatReplace|direct|htmlTagName|foco|marginBottom|marginRight|getSelectionText|http|textContent|alignment|hideProgressBar|folder|redactorModalWidth|template|toolbarFixedTopOffset|isEmpty|rangeNodes|enctype|rTestBlock|substring|strip|redactor_link_url_text|amp|blockLevelElements|parentEl|rows|overflow|tabSpaces|insertHtmlAdvanced|predefinedLinksStorage|separator|row|emptyElement|ASIDE|linkShow|ARTICLE|columns|clickedElement|not|inlineMethods|redactor_modal_inner|outer|selectionHtml|ctrlKey|cleanConvertInlineTags|deleteContents|wrapperHtml|methodVal|activeButtons|listText|insertLineBreak|parentHtml|sourceHeight|insertAfter|fonts|header|indentValue|head|pasteInsert|7px|setSpansVerified|tablePaste|convertDivs|redactor_form_image_align|selected|prop|checked|progressBar|setSpansVerifiedHtml|paste|saveScroll|x200b|nodeValue|buildCodearea|open|ADDRESS|ENTER|toolbarFixedBox|icon|HEADER|classname|FOOTER|column|imageUploadParam|execPasteFrag|colspan|floating||new_tr|www|rowspan|SECTION|cleanParagraphy|getRangeSelectedNodes|tagTestBlock|iframePage|oldsafari|hover|BODY|table_box||redactor_toolbar|cleanSavePreCode|tableId|directupload|focus_td|focus_tr|imageUploadError|buttonsHideOnMobile|Table|container|innerText|elem2|savedHtml|syncClean|Column|isIPad|catch|Row|try|endNode|iframeDoc|vimeo|blur|decoration|placeholderText|formatQuote|urlImage|paragraphsOnly|youtube|cleanFontTag|500|focusEnd|pasteClipboardMozilla|cleanEncodeEntities|formatblock|placeholderOnBlur|frameborder|placeholderOnFocus|placeholderGet|address|formatLinkify|INLINE|protocol|currBlock|utag|cleanRemoveEmptyTags|parseHTML|pasteHTML|endRange|insertingAfterLastElement|tfoot|maxHeight|buildEnable|addProtocol|inlineEachNodes|fullscreen|buildAfter|selectionRemove|caretOffset|Range|selectionElement|hotkeysShiftNums|selectionWrap|cleanTag|cleanFinish|oldIE|cursorRange|apply|getTextNodesIn|setFullpageOnInit|toggle|dnbImageTypes|chrome|orgo|extractContent|cleannewLevel|iframeLoad|royalSlider|iframeAddCss|clipboardUploadUrl|buildOptions|pasteClipboardAppendFields|fotorama|posFrame|createDocumentFragment|BR|child|isEndOfElement|suffix|getCaretOffset|buildBindKeyboard|toolbarObserveScroll|delete_table|delete_row|delete_column|formId|oldElement|imageRemove|delete|DELETE|2000px|templateVars|editter|lineHeight|tableDeleteHead|delete_head|resizer|cleanConverters|btnHeight||cleanConvertProtected|RedactorPlugins|pageY|arrSearch|etagsInline|align_right|alignright||redactor_button_disabled|submit|removeEmptyTags|contentWindow|dropdownWidth|indentingIndent|align_center||align_left|alignleft|pageX|aligncenter|ratio|indentingOutdent|link_new_tab|modalSaveBodyOveflow|num|add_head|redactor_filename|fileUploadParam|alignmentCenter|insideOutdent|filename|rBlockTest|justify|alignmentJustify|contOwnLine|redactor_image_box|redactor_file_alt|FIGCAPTION|alignmentLeft|choose|insert_table|alignmentRight|ownLine|buttonName|buttonInactive|insert_row_above|buildProgressBar|uploadSubmit|trigger|dropdownHide|s3uploadFile|insert_column_right|indentingStart|cleanEmpty|plugins|uploadInit|dropdownShow|status|insert_row_below|childList|insert_column_left|imageCallback|mark|buildEventKeydownInsertLineBreak|s3image|redactor_table_rows|align_justify|modify|extra||||pattern|z0||mailto|reader|draguploadInit|added|DOWN|fileCallback|lineOrWord|dragUploadAjax|modalCloseHandler|ESC|linkInsertPressed|placeholderRemove|buttonsSize|tableAddRow|activeButtonsStates|safes|POST|contentType|link_insert|tableAddColumn|clipboardData|cursor|th|progress|FormData|predefinedLinks|redactor_modal_close|targetBlank|redactor_insert_video_area|droparea|airShow|merge|modalOverlay|redactor_modal_overlay|sourceOld|thumbtitle|||||||||||redactorModalInner|focusElem||redactor_modal|commentsMatches|iframeAppend|superscript|textareaKeydownCallback|shortcutsHandler|Array|beforekey|inlineUnwrapSpan||subscript|placeholderFocus|redactor_dropdown_link|dragUpload|buildEventKeyup|inlineFormat|newhtml|tabFocus|blocksElemsRemove|buildEventKeydownTab|focusCallback|firstParent|unwrap|placeholderRemoveFromEditor|strikethrough|formattingPre|execLists|TAB|execUnlink|blocksLen|wym|UL|buttonInactiveAll|inlineSetMethods|placeholderBlur|paragraphs|min|redactor_editor_wym|toolbarInit|clonedHtml|placeholderRemoveFromCode|buildEventKeydownPre|link_edit|buttonActiveToggle|buildEventKeydownBackspace|inserthorizontalrule|fromElement|toTagName|afterkey|command|buildEventDrop|filter|transparent|close|toolbarBuild|toolbar_fixed_box|airButtons|buildEventKeydown|fieldset|airEnable|buildEventPaste|LEFT_WIN|mod|clearInterval|redactor_air|altKey||area|map|cleanup|clipboardFilePaste|scroll|originalEvent|10005|toolbarOverflow|redactor_air_|tags||iframeCreate|buildEventClipboardUpload|write|visibility|cleanUnverified|items|buttonSource|formattingTags|quot|encode|pastedFrag|cleanHtml|timer|219|cleanlineAfter|buttonImage|hotkeysSpecialKeys|cleanlineBefore|cleanReConvertProtected|listCurrentText|placeholderStart|returnValue|redactor_dropdown|wrapAll|buildEventKeyupConverters|buttonActiveVisual|dropdownBuild|placeholderInit|buildPlugins|formatEmpty|double|innerHeight|tidyHtml|||||||airBindHide|toggleCode|indenting|textareaIndenting|keyboard|setInterval|innerWidth|collapseToStart|dropdownObject|origHandler|buffer_|cleanReplacer|arguments|u200D|toggleVisual|uFEFF|buttonInactiveVisual|fileUploadError|modal_video|redactor_insert_table_btn||redactor_table_columns|video_html_code|H5|redactor_insert_video_btn|header5|getCaretOffsetRange|modal_table|predefined|modal_link|links|URL|redactor_insert_link_btn|checkbox|H6|header4|modalSetTitle|modalSetContent|modalSetButtonsWidth|DL|modalSetOverlay|modalOnCloseButton|DD|modalShowOnMobile|header3|fragment|getFragmentHtml|header2|header1|modalShowOnDesktop|redactor_upload_btn|image_web_link|imageResizable|draguploadOndragleave|H4|bottom|5px|fff|1px|18px|opacity|mouse_y|div_h|new_h|min_w|relative|imageResizeControls|backgroundColor||000|||_delete|redactor_image_delete_btn|redactorSaveBtn|modal_image|redactor_tab3|redactor_tab2||image_position|modal_image_edit|imageThumbClick|8px||imageCallbackLink|modalTemplatesInit|equals|modal_file|modalSetDraggable|draggable|Upload|rawString|Center|element_action|drop_file_here|isString|or_choose|contentDocument|uploadLoaded|uploadForm|load|the|to|Align|fileId|atext|dropalternative|loaded|Left|insertNodeToCaretPositionFromPoint|drag|draguploadOndrag|uploadProgress|Right|Image|Video|Code|percent|Head|ajax|Link|99999|random|s3handleFileSelect|visible|arrAdd|signedURL|s3executeOnSignedUrl|newLevel|opr|hdlModalClose|unbind|paragraph|quote|modalLoadTabs|shortcutsAdd|langs|outerHeight|overrideMimeType|DT|Color|setRequestHeader|send|List|floor|uploadFrame|onload|s3createCORSRequest|readyState|OUTPUT|Edit|XMLHttpRequest|s3uploadToS3|XDomainRequest|mousemove|imageEdit|linkObserver|linkNofollow|aLink|aEdit|formatChangeTag|nofollow|pop|pasteClipboardUpload|imgs|clipboard|bufferUndo|bufferRedo|endOffset|setCaret|getSelectionHtml|nextSibling|xhtmlTags|xhtml|selectionCreateMarker|args|nextNode|nodeName|setCaretAfter|slice|setFullpageDoctype|unshift|pasteClipboardUploadMozilla|noeditable|clientX|buildContent|clientY|caretPositionFromPoint|buildMobile|outerHTML|buildFromTextarea|HTML|buildAddClasses|aside|article|buildFromElement|caretRangeFromPoint|createTextRange|pastePlainText|pasteClean|cleanSpaces|internal|pastePre|replaceLineBreak|twice|mobile|moveToPoint|buildStart|SPAN|escapedBackReferences|aUnlink|onchangeFunc|isEmptyObject|linkProcess|removeFormat|location|self|videoShow|videoInsert|thref|imageTabLink|H1|player|getJSON|imageShow|linkInsert|fileShow|re2|gif|allowfullscreen|jpeg|281|tableAddColumnRight|setEditor|tableAddColumnLeft|rProtocol|tableDeleteRow|tableDeleteColumn|setCodeIframe|tableInsert|imageResize|H3|getCodeIframe|inside|doctype|tableShow|imageSave|tableDeleteTable|first|tableAddHead|H2|tableAddRowBelow|removeFromArrayByValue|tableAddRowAbove|focusIndex|png|Indent|Outdent|ownerDocument||frameset|103|Cancel|104|Save|107|Rows|defaultView|Columns|Title||Below|106|Above|102|stylesheet|105|Back|Normal|Formatting|Unlink|ltr|Quote|backspace|applet|use|strict|VERSION|such|removeChild|youtu|startOffset|isArray|eval|Bold|Italic|pagedown|pageup|esc|home|up|101|down|capslock|Ordered|Font|fontcolor|backcolor|No|Unordered|pause|noscript|redactor_format_h2|getAsFile|FileReader|getToolbar|readAsDataURL|about|blank|Chrome|536|noneditable|getIframe|word|getEditor|getObject|removeData|destroy|redo|getBox|collapseToEnd|109|undo|syncBefore|syncAfter|dash|u2010|mdash|u2014|enableInlineTableEditing|enableObjectResizing|45px|TEXTAREA|redactor_box|hellip|u2026|blurCallback|8203|default|switch|1class|u2122|copy|u00a9|trade|Callback|TH|Horizontal|Justify|here|Drop|Rule|Deleted|Open|Anchor|anchor|Or|Choose|Email|Text|Web|None|web|Embed|Download|download|File|Underline|Alignment|redactor_format_h5|redactor_format_h4|redactor_format_h3|redactor_|bull|separator_drop1|alignjustify||separator_drop3|separator_drop2|redactor_format_h1|redactor_format_pre|META|CTRL||optional|Name|LEFT||dropdowns|redactor_format_blockquote|u00a0|sourceWidth|Position|unselectable|redactor_image_edit_src|610|redactor_image_box_select|380|imageDelete|min_h|clicked|dragstart|thumb|xn|300|removeMarkers|u1C7F|cellIndex|600|460|host|mouse_x|13px|redactorUploadFileForm|1500|fadeIn|redactor_modal_delete_btn|redactorInsertImageForm|redactorInsertVideoForm|redactor_tab1|solid|border|outline|3px|9px|dashed|rgba|4px|pointer|u0000|restoreSelection|pasteBefore|insertDoubleLineBreak|EndToEnd|shapes|MsoListParagraphCxSpFirst|MsoListParagraphCxSpLast|MsoListParagraphCxSpMiddle||setEndPoint||duplicate|toUpperCase|inlineRemoveFormat|attributes|insertBeforeCursor|insertText|offsetNode|setEndAfter|MsoListParagraph|sid|commonAncestorContainer|110|isInlineNode|hasChildNodes|cloneContents|detach|saveSelection|selectionAll|extractContents|u200b|guid|docs|fake|pasteAfter|editGallery|jQuery|160px|times|processData|cache|dataType|total|Loading|BlackBerry|iPod|iPhone|ajaxSetup|addEventListener|redactor_dropalternative|redactor_dropareabox|redactor_droparea|dragover|dragleave|ajaxSettings|ondrop|Android|iPad|trident|safari|Trident|compatible|cloneNode|jpg|ftps|parseFloat||MSIE|getInternetExplorerVersion|Object|stripHtml|appName|Microsoft|Explorer|Internet|preview|failed|GET|modalSetTab|modalClosed|plain|charset||defined|user|fast|redactor_tab_selected|keypress|focusin|modalOpened|300px|redactor_modal_btn_hidden|move|handle|onreadystatechange|decodeURIComponent|INPUT|read|public|redactorUploadForm|redactorUploadFile|alert|frames|acl|amz|PUT|withCredentials|responseText|onerror|onprogress|Type|Content|inlineSetAttr|isCollapsed|external|redactor_toolbar_|focusNode|redactor_separator_drop|dropdownShown|redactor_dropdown_|1000|autosaveError|fromCharCode|inlineRemoveAttr|Key|escape|encodeURIComponent|touchstart|stopPropagation|buttonAddBefore|buttonAddAfter|buttonRemove|firstNode|SUB|SUP|buttonAddFirst|buttonAdd|buttonTagToActiveState|redactor_dropdown_box_|buttonChangeIcon|buttonRemoveIcon|buttonAwesome|222|221|119|118|120|121|122|f10|117|116|112|111|113|114|115|f11|123|189|188|190|191|220|192|187|186|144|f12|numlock|145|173|OL|_|details|menu|hasOwnProperty|inlineSetClass|figcaption|inlineRemoveStyle|hgroup|nav|figure|inlineSetStyle|inlineRemoveClass|sub|blockSetClass||blockRemoveStyle|blockRemoveClass|blockSetStyle|blockSetAttr|blockRemoveAttr|sup|small|cite|legend|summary|caption|concat|col|JustifyCenter|JustifyFull|gallery||comment|colgroup|JustifyRight|math|JustifyLeft'.split('|'),0,{})) \ No newline at end of file +eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(B($){\'kg kf\';if(!dA.5k.9B){dA.5k.9B=B(dj){C fn=c;E B(){E fn.87(dj)}}}C 8J=0;C bh=/6n?:\\/\\/(?:[0-9A-Z-]+\\.)?(?:k5\\.be\\/|hH\\.9R\\S*[^\\w\\-\\s])([\\w\\-]{11})(?=[^\\w\\-]|$)(?![?=&+%\\w.\\-]*(?:[\'"][^<>]*>|<\\/a>))[?=&+%\\w.-]*/ig;C aU=/6n?:\\/\\/(9a\\.)?hI.9R\\/(\\d+)($|\\/)/;$.fn.G=B(3L){C 2w=[];C dq=7M.5k.jX.5X(h7,1);if(1C 3L===\'62\'){c.1z(B(){C 5V=$.1h(c,\'G\');C 1v;if(3L.3F(/\\./)!=\'-1\'){1v=3L.4E(\'.\');if(1C 5V[1v[0]]!=\'1H\'){1v=5V[1v[0]][1v[1]]}}L{1v=5V[3L]}if(1C 5V!==\'1H\'&&$.5n(1v)){C aG=1v.87(5V,dq);if(aG!==1H&&aG!==5V){2w.2W(aG)}}L{$.5r(\'jW jV ae "\'+3L+\'" 2v 3l\')}})}L{c.1z(B(){$.1h(c,\'G\',{});$.1h(c,\'G\',3l(c,3L))})}if(2w.1o===0)E c;L if(2w.1o===1)E 2w[0];L E 2w};B 3l(el,3L){E 1J 3l.5k.3r(el,3L)}$.3l=3l;$.3l.k0=\'10.0.5\';$.3l.9r=[\'3t\',\'3x\',\'N\',\'1Z\',\'2f\',\'1s\',\'1U\',\'1p\',\'1a\',\'1S\',\'1y\',\'1P\',\'2t\',\'J\',\'3e\',\'1V\',\'1O\',\'1u\',\'2m\',\'1E\',\'4r\',\'T\',\'2T\',\'V\',\'2n\',\'2p\',\'4V\',\'2Y\',\'5p\',\'K\',\'5A\',\'2s\',\'1x\',\'1r\',\'1j\',\'O\'];$.3l.F={1E:\'en\',cd:\'kA\',7t:M,2t:M,eB:M,2Y:M,63:1q,8y:M,av:M,9J:M,1L:M,6S:1q,2p:1q,dv:M,bi:1q,j8:1q,eJ:1q,eu:M,3x:M,b4:M,7K:60,aT:M,iW:1q,8k:\'7Y\',es:M,6H:50,gw:1q,gq:1q,gp:1q,8b:\'kE\',aN:1q,8s:M,hW:\'1P\',kD:M,f0:1q,8t:M,hS:\'1P\',eT:1q,8u:M,8A:1q,75:1q,6C:1q,6T:1q,5Z:4,9j:M,dC:1q,7p:M,1r:1q,gT:1q,6v:1d,6y:0,aj:M,gV:M,gS:M,3D:[\'q\',\'2K\',\'3W\',\'3X\',\'5I\',\'5z\',\'54\',\'6O\',\'3e\',\'J\',\'1P\',\'T\',\'3t\',\'9q\'],bQ:[],bR:[],2K:[\'p\',\'1N\',\'2D\',\'h1\',\'h2\',\'h3\',\'h4\',\'h5\',\'h6\'],cq:M,2s:1q,4G:[\'q\',\'hf\',\'T\',\'2x\',\'5m\',\'3Z\',\'1n\',\'kt\'],4R:M,6k:M,56:[[\'81\',\'43\']],55:[[\'3p-6E:\\\\s?3W\',"5i"],[\'3p-1n:\\\\s?3X\',"em"],[\'1b-76:\\\\s?5c\',"u"],[\'1b-76:\\\\s?4r-fh\',\'43\']],5b:M,1W:M,58:M,6j:[\'1e\'],3N:[\'p\'],9N:[\'5I\',\'3X\',\'3W\',\'5c\',\'5z\',\'54\',\'kk\',\'kr\',\'jm\',\'8g\'],bl:{b:\'3W\',5i:\'3W\',i:\'3X\',em:\'3X\',43:\'5I\',81:\'5I\',2O:\'5z\',ol:\'54\',u:\'5c\'},5A:{\'3S+67+m, 5m+67+m\':{1v:\'1V.b7\'},\'3S+b, 5m+b\':{1v:\'1V.2Z\',5w:[\'3W\']},\'3S+i, 5m+i\':{1v:\'1V.2Z\',5w:[\'3X\']},\'3S+h, 5m+h\':{1v:\'1V.2Z\',5w:[\'fx\']},\'3S+l, 5m+l\':{1v:\'1V.2Z\',5w:[\'fw\']},\'3S+k, 5m+k\':{1v:\'T.2B\'},\'3S+67+7\':{1v:\'2T.2M\',5w:[\'54\']},\'3S+67+8\':{1v:\'2T.2M\',5w:[\'5z\']}},fz:M,1Z:[],7m:[],7G:\'<p>&#bU;</p>\',5M:\'&#bU;\',hU:[\'J/hL\',\'J/hK\',\'J/hG\'],9I:20,bL:[\'a\',\'1B\',\'b\',\'5i\',\'7a\',\'74\',\'i\',\'em\',\'u\',\'8l\',\'81\',\'43\',\'8r\',\'2O\',\'ol\',\'li\'],4C:[\'5i\',\'b\',\'u\',\'em\',\'i\',\'1a\',\'43\',\'jp\',\'9V\',\'a5\',\'74\',\'7a\',\'6s\',\'C\',\'8r\',\'8l\'],7J:[\'P\',\'eV\',\'eU\',\'eW\',\'eX\',\'eZ\',\'eY\',\'js\',\'jk\',\'ju\',\'8F\',\'7k\',\'8L\',\'jc\',\'eH\',\'je\',\'jf\',\'jM\',\'jK\',\'jS\',\'jw\'],8G:[\'ad\',\'8j\',\'8i\',\'4P\'],da:{en:{q:\'jB\',6t:\'6c fC\',J:\'6c fB\',4q:\'cC\',T:\'bb\',bq:\'6c T\',jC:\'fM T\',6h:\'jF\',2K:\'jE\',gY:\'jD 1b\',bO:\'lJ\',1a:\'fP\',gX:\'89 1\',gH:\'89 2\',gI:\'89 3\',gJ:\'89 4\',gK:\'89 5\',3W:\'lS\',3X:\'lI\',lA:\'lB du\',lG:\'m9 du\',5z:\'mg cY\',54:\'m6 cY\',6O:\'lY\',3e:\'kU\',iO:\'kQ\',1O:\'6c\',2R:\'lr\',gc:\'7o\',mh:\'6c cC\',lc:\'7U cA ld\',le:\'7U cA lf\',lb:\'7U cH d6\',la:\'7U cH fD\',l6:\'7o cH\',l7:\'7o cA\',l8:\'7o cC\',l9:\'lg\',lh:\'lp\',lq:\'7U d2\',ls:\'7o d2\',1F:\'lo\',ik:\'ln\',5f:\'lj\',21:\'d6\',4c:\'fD\',57:\'fN\',lk:\'fB lm bb\',1b:\'l5\',bW:\'l4\',kO:\'ip\',kP:\'fC kR fP or kM/kI bb\',1P:\'6c kJ\',1j:\'kK\',kL:\'kS\',fR:\'kT\',l0:\'l1 fR\',l3:\'hZ 1P i0\',gG:\'fK 1b fL ag 21\',gF:\'fN 1b\',gB:\'fK 1b fL ag 4c\',gA:\'kY 1b\',9q:\'6c kV kW\',5I:\'kX\',lu:\'lv\',bu:\'m1 T in 1J 5j\',5c:\'m2\',3t:\'m3\',6p:\'m4 (m0)\',7T:\'fM\'}}};3l.fn=$.3l.5k={3j:{7d:8,8C:46,db:40,5T:13,cz:32,cG:27,b8:9,d5:17,d1:91,dr:16,dp:18,lV:37,dc:91},3r:B(el,3L){c.$2F=$(el);c.8J=8J++;c.7h=M;c.$5C=M;c.fy(3L);c.fk();c.2K={};$.lW(c.F.8G,c.F.7J);c.hx=1J 1T(\'^(\'+c.F.8G.2H(\'|\')+\')$\',\'i\');c.1x.hq();c.1E.2G();$.70(c.F.5A,c.F.fz);c.1S.2o(\'2X\');c.2X=1q;c.2f.dO()},fy:B(3L){c.F=$.70({},$.70(1q,{},$.3l.F),c.$2F.1h(),3L)},bt:B(4F){E hD.m5(4F).g7(B(9f){E 1C 4F[9f]==\'B\'})},fk:B(){C 22=$.3l.9r.1o;2v(C i=0;i<22;i++){c.fl($.3l.9r[i])}},fl:B(5y){if(1C c[5y]==\'1H\')E;c[5y]=c[5y]();C 5s=c.bt(c[5y]);C 22=5s.1o;2v(C z=0;z<22;z++){c[5y][5s[z]]=c[5y][5s[z]].9B(c)}},3t:B(){E{21:B(){c.3t.1K(\'\')},4c:B(){c.3t.1K(\'4c\')},57:B(){c.3t.1K(\'57\')},8g:B(){c.3t.1K(\'8g\')},1K:B(1c){if(!c.O.26(\'2J\'))c.$U.2t();c.1Z.1K();c.K.2R();c.3t.1Q=c.K.3V();if(c.F.1L&&c.3t.1Q[0]===M){c.3t.fj(1c)}L{c.3t.fi(1c)}c.K.2S();c.1a.1R()},fj:B(1c){C 4j=c.K.5E(\'1i\');$(4j).Y(\'1h-7N\',\'G\');$(4j).1I(\'1b-4S\',1c)},fi:B(1c){$.1z(c.3t.1Q,$.X(B(i,el){C $el=c.O.9e(el);if(!$el)E;if(1c===\'\'&&1C($el.1h(\'7N\'))!==\'1H\'){$el.2y($el.q())}L{$el.1I(\'1b-4S\',1c);c.O.5J($el,\'1n\')}},c))}}},3x:B(){E{9b:B(){if(!c.F.3x)E;c.3x.q=M;c.3x.1f=(c.F.b4)?c.F.b4:c.$2E.Y(\'1f\');if(!c.F.aT){c.7K=me($.X(c.3x.2G,c),c.F.7K*mf)}},e1:B(){if(!c.F.aT)E;c.3x.2G()},2G:B(){C q=c.1a.14();if(c.3x.q===q)E;if(c.O.4t(q))E;$.mc({2c:c.F.3x,1c:\'mb\',1h:\'1f=\'+c.3x.1f+\'&\'+c.3x.1f+\'=\'+m7(m8(q)),bd:$.X(B(1h){c.3x.bd(1h,q)},c)})},bd:B(1h,q){C 2z;4s{2z=$.i2(1h)}4x(e){2z=1h}C fS=(1C 2z.5r==\'1H\')?\'3x\':\'ma\';c.1S.2o(fS,c.3x.1f,2z);c.3x.q=q},lU:B(){fW(c.7K)}}},N:B(){E{2K:B(1f){C 1c,1D;if(1C c.2K[1f].1h!=\'1H\')1c=\'1h\';L if(1C c.2K[1f].Y!=\'1H\')1c=\'Y\';L if(1C c.2K[1f].1G!=\'1H\')1c=\'1G\';if(1c)1D=c.2K[1f][1c];c.N.2Z(c.2K[1f].R,1c,1D)},2Z:B(R,1c,1D){if(R==\'bO\')R=\'1N\';C gh=[\'p\',\'2D\',\'1N\',\'h1\',\'h2\',\'h3\',\'h4\',\'h5\',\'h6\'];if($.3B(R,gh)==-1)E;c.N.8f=(R==\'2D\'||R.3F(/h[1-6]/i)!=-1);if(!c.O.26(\'2J\'))c.$U.2t();c.N.1Q=c.K.3V();c.N.7j=c.N.1Q.1o;c.N.1c=1c;c.N.1D=1D;c.1Z.1K();c.K.2R();c.N.1K(R);c.K.2S();c.1a.1R()},1K:B(R){c.K.14();c.N.5P=c.12.g9.1l;if(c.12.4Z){c.N.fU(R)}L{c.N.fV(R)}},fU:B(R){C N=c.N.1Q[0];if(N===M)E;if(N.1l==\'4P\'){if(R!=\'1N\')E;c.N.ab();E}C 8M=(c.N.5P==\'7k\'||c.N.5P==\'aL\');if(8M&&!c.F.1L){1d.3O(\'a2\',M,\'<\'+R+\'>\');N=c.K.47();c.N.2M($(N))}L if(N.1l.2P()!=R){if(c.F.1L&&R==\'p\'){$(N).4N(\'<br>\').1w(\'<br>\');c.O.5N(N)}L{C $1Y=c.O.4v(N,R);c.N.2M($1Y);if(R!=\'p\'&&R!=\'1N\')$1Y.1k(\'1B\').1t();if(c.N.8f)c.O.4J($1Y);if(R==\'p\'||c.N.cv)$1Y.1k(\'p\').23().3Y();c.N.bB($1Y)}}L if(R==\'1N\'&&N.1l.2P()==R){if(c.F.1L){$(N).4N(\'<br>\').1w(\'<br>\');c.O.5N(N)}L{C $el=c.O.4v(N,\'p\');c.N.2M($el)}}L if(N.1l.2P()==R){c.N.2M($(N))}},fV:B(R){C N=c.N.1Q[0];C 8M=(c.N.5P==\'7k\'||c.N.5P==\'aL\');if(N!==M&&c.N.7j===1){if(N.1l.2P()==R&&R==\'1N\'){if(c.F.1L){$(N).4N(\'<br>\').1w(\'<br>\');c.O.5N(N)}L{C $el=c.O.4v(N,\'p\');c.N.2M($el)}}L if(N.1l==\'4P\'){if(R!=\'1N\')E;c.N.ab()}L if(c.N.5P==\'8L\'){c.N.e4(R)}L if(c.F.1L&&((8M)||(c.12.g9!=N))){c.N.a7(R)}L{if(c.F.1L&&R==\'p\'){$(N).4N(\'<br>\').1w(\'<br>\');c.O.5N(N)}L if(N.1l===\'7k\'){c.N.a7(R)}L{C $1Y=c.O.4v(N,R);c.N.2M($1Y);if(c.N.8f)c.O.4J($1Y);if(R==\'p\'||c.N.cv)$1Y.1k(\'p\').23().3Y()}}}L{if(c.F.1L||R!=\'p\'){if(R==\'1N\'){C ct=0;2v(C i=0;i<c.N.7j;i++){if(c.N.1Q[i].1l==\'8L\')ct++}if(ct==c.N.7j){$.1z(c.N.1Q,$.X(B(i,s){if(c.F.1L){$(s).4N(\'<br>\').1w(\'<br>\');c.O.5N(s)}L{c.O.4v(s,\'p\')}},c));E}}c.N.a7(R)}L{C 7W=0;C 5o=M;if(c.N.1c==\'1G\'){5o=\'2M\';7W=$(c.N.1Q).g7(\'.\'+c.N.1D).28();if(c.N.7j==7W)5o=\'2M\';L if(c.N.7j>7W)5o=\'1K\';L if(7W===0)5o=\'1K\'}C 7A=[\'2O\',\'ol\',\'li\',\'3K\',\'5U\',\'dl\',\'dt\',\'dd\'];$.1z(c.N.1Q,$.X(B(i,s){if($.3B(s.1l.2P(),7A)!=-1)E;C $1Y=c.O.4v(s,R);if(5o){if(5o==\'2M\')c.N.2M($1Y);L if(5o==\'1t\')c.N.1t($1Y);L if(5o==\'1K\')c.N.e5($1Y)}L c.N.2M($1Y);if(R!=\'p\'&&R!=\'1N\')$1Y.1k(\'1B\').1t();if(c.N.8f)c.O.4J($1Y);if(R==\'p\'||c.N.cv)$1Y.1k(\'p\').23().3Y()},c))}}},e5:B($el){if(c.N.1c==\'1G\'){$el.2q(c.N.1D);E}L if(c.N.1c==\'Y\'||c.N.1c==\'1h\'){$el.Y(c.N.1D.1f,c.N.1D.1D);E}},2M:B($el){if(c.N.1c==\'1G\'){$el.94(c.N.1D);E}L if(c.N.1c==\'Y\'||c.N.1c==\'1h\'){if($el.Y(c.N.1D.1f)==c.N.1D.1D){$el.1W(c.N.1D.1f)}L{$el.Y(c.N.1D.1f,c.N.1D.1D)}E}L{$el.1W(\'1n 1G\');E}},1t:B($el){$el.2I(c.N.1D)},ab:B(){C N=$(c.N.1Q[0]).2u(\'2O, ol\');$(N).1k(\'2O, ol\').23().3Y();$(N).1k(\'li\').1w($(\'<br>\')).23().3Y();C $el=c.O.4v(N,\'1N\');c.N.2M($el)},e4:B(R){1d.3O(\'6O\');1d.3O(\'a2\',M,R);c.1p.4d();c.$U.1k(\'p:ea\').1t();C 1Y=c.K.47();if(R!=\'p\'){$(1Y).1k(\'1B\').1t()}if(!c.F.1L){c.N.2M($(1Y))}c.$U.1k(\'2O, ol, 6q, 1N, p\').1z($.X(c.O.3N,c));if(c.F.1L&&R==\'p\'){c.O.5N(1Y)}},a7:B(R){if(c.N.5P==\'8j\'||c.N.5P==\'8i\'){if(R==\'1N\'){c.N.ab()}L{E}}C 1Y=c.K.5E(R);if(1Y===M)E;C $1Y=$(1Y);c.N.bB($1Y);C $bK=$1Y.1k(c.F.8G.2H(\',\')+\', 3K, 4q, cJ, cs, cT, 5U, 6q\');if((c.F.1L&&R==\'p\')||R==\'2D\'||R==\'1N\'){$bK.1w(\'<br />\')}$bK.23().3Y();if(R!=\'p\'&&R!=\'1N\')$1Y.1k(\'1B\').1t();$.1z(c.N.1Q,$.X(c.O.3N,c));$1Y.1w(c.K.6d(2));if(!c.F.1L){c.N.2M($1Y)}c.$U.1k(\'2O, ol, 6q, 1N, p\').1z($.X(c.O.3N,c));$1Y.1k(\'1N:ea\').1t();if(c.N.8f){c.O.4J($1Y)}if(c.F.1L&&R==\'p\'){c.O.5N($1Y)}},bB:B($1Y){if($1Y.2u(\'4q\').28()===0)E;if($1Y.2u(\'6q\').28()===0)$1Y.5E(\'<6q>\');if($1Y.2u(\'3K\').28()===0&&$1Y.2u(\'5U\').28()===0){$1Y.5E(\'<3K>\')}},g2:B(1f,1D){C 1Q=c.K.3V();$(1Q).1W(\'1h-\'+1f);c.1a.1R()},lO:B(1f,1D){C 1Q=c.K.3V();$(1Q).Y(\'1h-\'+1f,1D);c.1a.1R()},lN:B(1f,1D){C 1Q=c.K.3V();$.1z(1Q,B(){if($(c).Y(\'1h-\'+1f)){$(c).1W(\'1h-\'+1f)}L{$(c).Y(\'1h-\'+1f,1D)}})},1W:B(Y,1D){C 1Q=c.K.3V();$(1Q).1W(Y);c.1a.1R()},lK:B(Y,1D){C 1Q=c.K.3V();$(1Q).Y(Y,1D);c.1a.1R()},lL:B(Y,1D){C 1Q=c.K.3V();$.1z(1Q,B(){if($(c).Y(1f)){$(c).1W(1f)}L{$(c).Y(1f,1D)}})},2I:B(4u){C 1Q=c.K.3V();$(1Q).2I(4u);c.O.5J(1Q,\'1G\');c.1a.1R()},lM:B(4u){C 1Q=c.K.3V();$(1Q).2q(4u);c.1a.1R()},94:B(4u){C 1Q=c.K.3V();$(1Q).94(4u);c.1a.1R()}}},1Z:B(){E{1K:B(1c){if(1C 1c==\'1H\'||1c==\'9C\'){c.1Z.ee()}L{c.1Z.eb()}},ee:B(){c.K.2R();c.F.1Z.2W(c.$U.q());c.K.2S()},eb:B(){c.K.2R();c.F.7m.2W(c.$U.q());c.K.2S()},dM:B(){c.$U.q(c.F.1Z.ed())},dN:B(){c.$U.q(c.F.7m.ed())},ck:B(){c.F.1Z.2W(c.$U.q())},9C:B(){if(c.F.1Z.1o===0)E;c.1Z.1K(\'cB\');c.1Z.dM();c.K.2S();3q($.X(c.2n.2G,c),50)},cB:B(){if(c.F.7m.1o===0)E;c.1Z.1K(\'9C\');c.1Z.dN();c.K.2S();3q($.X(c.2n.2G,c),50)}}},2f:B(){E{dO:B(){c.2f.dL();c.2f.dG();c.2f.dJ();c.2f.dI();c.2f.ej()},8O:B(){E(c.$2F[0].1l===\'kF\')},dL:B(){c.$2r=$(\'<1i 1G="G-2r" />\')},dS:B(){c.$2E=$(\'<2E />\').Y(\'1f\',c.2f.dK())},dK:B(){C 1f=c.$2F.Y(\'id\');if(1C(1f)==\'1H\'){1f=\'c7-\'+c.8J}E 1f},dG:B(){C 1v=(c.2f.8O())?\'2w\':\'q\';c.c7=$.3d(c.$2F[1v]())},dI:B(){c.$U.Y({\'77\':1q,\'eQ\':c.F.cd})},dJ:B(){C 1v=(c.2f.8O())?\'dQ\':\'dW\';c.2f[1v]()},dQ:B(){c.$U=$(\'<1i />\');c.$2E=c.$2F;c.$2r.dT(c.$2F).1w(c.$U).1w(c.$2F);c.$U.2q(\'G-U\');c.$2F.3b()},dW:B(){c.$U=c.$2F;c.2f.dS();c.$2r.dT(c.$U).1w(c.$U).1w(c.$2E);c.$U.2q(\'G-U\');c.$2E.3b()},ej:B(){c.1a.1K(c.c7);c.2f.eP();c.2f.eO();if(!c.F.63){3q($.X(c.1a.bH,c),9D)}},eO:B(){c.2f.eA();c.2f.eS();c.2f.er();if(c.F.1r){c.F.1r=c.1r.3r();c.1r.2f()}c.V.ix();c.2f.7t();3q($.X(c.2n.2G,c),4);c.1S.2o(\'3r\')},eP:B(){$(c.$2E).Y(\'eQ\',c.F.cd);if(c.F.1L)c.$U.2q(\'G-1L\');if(c.F.8y)c.$U.Y(\'8y\',c.F.8y);if(c.F.av)c.$U.1I(\'av\',c.F.av);if(c.F.9J)c.$U.1I(\'9J\',c.F.9J)},eS:B(){c.$U.on(\'4A.G\',$.X(B(e){e=e.7l||e;if(3M.9i===1H||!e.9d)E 1q;C 1o=e.9d.5D.1o;if(1o===0){c.1a.1R();3q($.X(c.1p.4d,c),1);c.1S.2o(\'4A\',e);E 1q}L{e.2k();if(c.F.f0||c.F.eT){C 5D=e.9d.5D;c.1j.hX(5D[0],e)}}3q($.X(c.1p.4d,c),1);c.1S.2o(\'4A\',e)},c));c.$U.on(\'2e.G\',$.X(B(e){C 1c=\'2e\';if((c.1S.69()==\'2e\'||c.1S.69()==\'4D\')){1c=M}c.1S.7H(1c);c.O.8a();c.1S.2o(\'2e\',e)},c));c.$U.on(\'4V.G\',$.X(c.4V.3r,c));c.$U.on(\'1u.G\',$.X(c.1u.3r,c));c.$U.on(\'2m.G\',$.X(c.2m.3r,c));if($.5n(c.F.eI)){c.$2E.on(\'1u.G-2E\',$.X(c.F.eI,c))}if($.5n(c.F.ew)){c.$2E.on(\'2m.G-2E\',$.X(c.F.ew,c))}if($.5n(c.F.ep)){c.$U.on(\'2t.G\',$.X(c.F.ep,c))}C bS;$(1d).on(\'cD\',B(e){bS=$(e.1M)});c.$U.on(\'aD.G\',$.X(B(e){if(c.7h)E;C $el=$(bS);if(!$el.3i(\'G-1r, G-1y\')&&!$el.is(\'#G-V\')&&$el.hF(\'.G-1r, .G-1y, #G-V\').28()===0){c.O.8a();if($.5n(c.F.jL))c.1S.2o(\'aD\',e)}},c))},er:B(){c.3x.9b();c.2Y.9b();if(c.F.2t)3q($.X(c.2t.3h,c),7I);if(c.F.eB)3q($.X(c.2t.41,c),7I)},7t:B(){if(!c.F.7t)E;if(!ar)E;$.1z(c.F.7t,$.X(B(i,s){if(1C ar[s]===\'1H\')E;if($.3B(s,$.3l.9r)!==-1){$.5r(\'ji 1f "\'+s+\'" 4l ag 1f of ag 3l\\\'s 5y.\');E}if(!$.5n(ar[s]))E;c[s]=ar[s]();C 5s=c.bt(c[s]);C 22=5s.1o;2v(C z=0;z<22;z++){c[s][5s[z]]=c[s][5s[z]].9B(c)}if($.5n(c[s].3r))c[s].3r()},c))},eA:B(){if(!c.O.26(\'6P\'))E;4s{1d.3O(\'jt\',M,M);1d.3O(\'jq\',M,M)}4x(e){}}}},1s:B(){E{2f:B(2i,3k){C $1s=$(\'<a 29="#" 1G="3U-8x 3U-\'+2i+\'" 3G="\'+2i+\'" />\').Y(\'8y\',\'-1\');if(3k.1v||3k.4a||3k.1y){$1s.on(\'68 2e\',$.X(B(e){if($1s.3i(\'G-1s-8w\'))E M;C 1c=\'1v\';C 2l=3k.1v;if(3k.4a){1c=\'4a\';2l=3k.4a}L if(3k.1y){1c=\'1y\';2l=M}c.1s.9l(e,2i,1c,2l)},c))}if(3k.1y){C $1y=$(\'<1i 1G="G-1y G-1y-2r-\'+2i+\'" 1n="6f: 5f;">\');$1s.1h(\'1y\',$1y);c.1y.2f(2i,$1y,3k.1y)}if(c.O.c8()){c.1s.ez($1s,2i,3k.1F)}E $1s},ez:B($1s,1f,1F){C $31=$(\'<1e>\').2q(\'G-1r-31 G-1r-31-\'+1f).3b().q(1F);$31.cw(\'2x\');$1s.on(\'fY\',B(){if($(c).3i(\'G-1s-8w\'))E;C 2V=$1s.2Q();C 3f=$1s.5G();C 2h=$1s.a0();$31.2B();$31.1I({2C:(2V.2C+3f)+\'3m\',21:(2V.21+2h/2-$31.a0()/2)+\'3m\'})});$1s.on(\'g1\',B(){$31.3b()})},9l:B(e,2i,1c,2l){c.1s.jn=c.1U.a4();e.2k();if(c.O.26(\'2J\'))e.jo=M;if(1c==\'4a\'){c.1V.2Z(2l)}L if(1c==\'1y\'){c.1y.2B(e,2i)}L{C 1v;if($.5n(2l)){2l.5X(c,2i);c.2n.3D(e,2i)}L if(2l.3F(/\\./)!=\'-1\'){1v=2l.4E(\'.\');if(1C c[1v[0]]!=\'1H\'){c[1v[0]][1v[1]](2i);c.2n.3D(e,2i)}}L{c[2l](2i);c.2n.3D(e,2i)}}},14:B(1m){E c.$1r.1k(\'a.3U-\'+1m)},8d:B(1m){c.1s.14(1m).2q(\'G-7D\')},g5:B(1m){c.1s.14(1m).2I(\'G-7D\')},j4:B(1m){if(1C 1m==\'1H\'){c.$1r.1k(\'a.3U-8x\').2I(\'G-7D\')}L{c.$1r.1k(\'a.3U-8x\').6o(\'.3U-\'+1m).2I(\'G-7D\')}},g6:B(){c.$1r.1k(\'a.3U-8x\').6o(\'a.3U-q\').2I(\'G-1s-8w\')},e7:B(){c.$1r.1k(\'a.3U-8x\').6o(\'a.3U-q\').2q(\'G-1s-8w\')},jU:B(1m,9n){c.1s.14(1m).2q(\'3U-\'+9n)},kp:B(1m,9n){c.1s.14(1m).2I(\'3U-\'+9n)},ks:B(1m,1f){C $1s=c.1s.14(1m);$1s.2I(\'G-25-J\').2q(\'fa-G-25\');$1s.q(\'<i 1G="fa \'+1f+\'"></i>\')},bo:B($25,2l){C 1c=(2l==\'1y\')?\'1y\':\'1v\';C 1m=$25.Y(\'3G\');$25.on(\'68 2e\',$.X(B(e){if($25.3i(\'G-1s-8w\'))E M;c.1s.9l(e,1m,1c,2l)},c))},kn:B($25,1y){C 1m=$25.Y(\'3G\');c.1s.bo($25,\'1y\');C $1y=$(\'<1i 1G="G-1y G-1y-2r-\'+1m+\'" 1n="6f: 5f;">\');$25.1h(\'1y\',$1y);if(1y){c.1y.2f(1m,$1y,1y)}E $1y},ck:B(1m,1F){if(!c.F.1r)E;C 25=c.1s.2f(1m,{1F:1F});25.2q(\'G-25-J\');c.$1r.1w($(\'<li>\').1w(25));E 25},kj:B(1m,1F){if(!c.F.1r)E;C 25=c.1s.2f(1m,{1F:1F});c.$1r.4N($(\'<li>\').1w(25));E 25},kl:B(eC,1m,1F){if(!c.F.1r)E;C 25=c.1s.2f(1m,{1F:1F});C $25=c.1s.14(eC);if($25.28()!==0)$25.1g().3u($(\'<li>\').1w(25));L c.$1r.1w($(\'<li>\').1w(25));E 25},ku:B(eD,1m,1F){if(!c.F.1r)E;C 25=c.1s.2f(1m,{1F:1F});C $25=c.1s.14(eD);if($25.28()!==0)$25.1g().aI($(\'<li>\').1w(25));L c.$1r.1w($(\'<li>\').1w(25));E 25},1t:B(1m){c.1s.14(1m).1t()}}},1U:B(){E{3h:B(Q){if(!c.O.6m(Q)){C 2U=c.O.9X();$(Q).4N(2U);c.1U.41(2U)}L{c.1U.1K(Q,0,Q,0)}},41:B(Q){c.1U.1K(Q,1,Q,1)},1K:B(4n,eG,6F,eF){if(!c.O.26(\'2J\'))c.$U.2t();4n=4n[0]||4n;6F=6F[0]||6F;if(c.O.6V(4n.1l)&&4n.3w===\'\'){4n.3w=c.F.5M}if(4n.1l==\'6i\'&&c.F.1L===M){C c3=$(c.F.7G)[0];$(4n).2y(c3);4n=c3;6F=4n}c.K.14();4s{c.12.3h(4n,eG);c.12.41(6F,eF)}4x(e){}c.K.4M()},5q:B(Q){4s{C R=$(Q)[0].1l;if(R!=\'6i\'&&!c.O.6m(Q)){C 2U=c.O.9X();$(Q).3u(2U);c.1U.41(2U)}L{if(R!=\'6i\'&&c.O.26(\'2J\')){c.1U.3h($(Q).2b())}L{c.1U.bZ(Q,\'3u\')}}}4x(e){C 2U=c.O.9X();$(Q).3u(2U);c.1U.41(2U)}},bJ:B(Q){if(c.O.6m(Q)){c.1U.41($(Q).6e())}L{c.1U.bZ(Q,\'aI\')}},bZ:B(Q,1c){if(!c.O.26(\'2J\'))c.$U.2t();Q=Q[0]||Q;c.K.14();if(1c==\'3u\'){4s{c.12.fO(Q);c.12.kw(Q)}4x(e){}}L{4s{c.12.kx(Q);c.12.ky(Q)}4x(e){}}c.12.51(M);c.K.4M()},bF:B(Q){Q=Q[0]||Q;c.K.14();C 9Q=c.12.7B();9Q.ap(Q);9Q.41(c.12.eE,c.12.ey);E $.3d(9Q.4I()).1o},a4:B(){C 2Q=0;C 2N=3M.6a();if(2N.7R>0){C 12=3M.6a().6G(0);C 9L=12.7B();9L.ap(c.$U[0]);9L.41(12.eE,12.ey);2Q=9L.4I().1o}E 2Q},9o:B(2X,3I){if(1C 3I==\'1H\')3I=2X;if(!c.2t.g0())c.2t.3h();C 12=1d.aZ();C 2N=1d.6a();C Q,2Q=0;C ex=1d.k3(c.$U[0],k4.jZ,4f,4f);4O(Q=ex.jY()){2Q+=Q.9g.1o;if(2Q>2X){12.3h(Q,Q.9g.1o+2X-2Q);2X=k6}if(2Q>=3I){12.41(Q,Q.9g.1o+3I-2Q);6x}}2N.aB();2N.4M(12)},mi:B(2X,3I){c.1U.9o(2X,3I)},kd:B(){E c.1U.a4()}}},1p:B(){E{e3:B(q){q=c.1p.dZ(q);q=q.I(/<3Z(.*?[^>]?)>([\\w\\W]*?)<\\/3Z>/gi,\'<2D 1G="G-3Z-R" 1n="6f: 5f;" $1>$2</2D>\');q=q.I(/\\$/g,\'$\');q=q.I(/â€/g,\'"\');q=q.I(/‘/g,\'\\\'\');q=q.I(/’/g,\'\\\'\');if(c.F.6S)q=c.1p.6S(q);if(c.F.1L)q=c.1p.am(q);q=c.1p.bP(q);C $1i=$(\'<1i>\');$1i.q(q);C bT=$1i.1k(\'3p[1n]\');if(bT.1o!==0){bT.2y(B(){C $el=$(c);C $1e=$(\'<1e>\').Y(\'1n\',$el.Y(\'1n\'));E $1e.1w($el.23())});q=$1i.q()}$1i.1t();q=q.I(/<3p(.*?[^<])>/gi,\'\');q=q.I(/<\\/3p>/gi,\'\');q=c.1x.2G(q);if(c.F.2p)q=c.2p.2G(q);q=c.1p.6B(q);q=c.1p.bN(q);E q},b5:B(q){q=q.I(/[\\8o-\\aE\\aq]/g,\'\');q=q.I(/&#bU;/gi,\'\');q=q.I(/&53;/gi,\' \');if(q.3F(/^<p>(||\\s||&53;)<\\/p>$/i)!=-1){E\'\'}q=q.I(/<2D 1G="G-3Z-R" 1n="6f: 5f;"(.*?[^>]?)>([\\w\\W]*?)<\\/2D>/gi,\'<3Z$1>$2</3Z>\');q=c.1p.e9(q);C eo={\'\\kc\':\'&kb;\',\'\\k7\':\'&k8;\',\'\\k9\':\'&ka;\',\'\\lT\':\'&mw;\',\'\\o1\':\'&o2;\'};$.1z(eo,B(i,s){q=q.I(1J 1T(i,\'g\'),s)});q=q.I(1J 1T(\'<br\\\\s?/?></li>\',\'gi\'),\'</li>\');q=q.I(1J 1T(\'</li><br\\\\s?/?>\',\'gi\'),\'</li>\');q=q.I(1J 1T(\'<1i(.*?) 1h-7N="G"(.*?[^>])>\',\'gi\'),\'<1i$1$2>\');q=q.I(1J 1T(\'<(.*?) 1h-3v="G"(.*?[^>])>\',\'gi\'),\'<$1$2>\');q=q.I(1J 1T(\'<1e(.*?) 3G="(.*?)"(.*?[^>])>\',\'gi\'),\'<1e$1$3>\');q=q.I(1J 1T(\'<1B(.*?) 3G="(.*?)"(.*?[^>])>\',\'gi\'),\'<1B$1$3>\');q=q.I(1J 1T(\'<1B(.*?) 1n="" (.*?[^>])>\',\'gi\'),\'<1B$1 $2>\');q=q.I(1J 1T(\'<1B(.*?) 1n (.*?[^>])>\',\'gi\'),\'<1B$1 $2>\');q=q.I(1J 1T(\'<1e 1G="G-7u-2U">(.*?)</1e>\',\'gi\'),\'$1\');q=q.I(/ 1h-2R-2c="(.*?[^>])"/gi,\'\');q=q.I(/<1e(.*?)id="G-J-2r"(.*?[^>])>([\\w\\W]*?)<1B(.*?)><\\/1e>/gi,\'$3<1B$4>\');q=q.I(/<1e(.*?)id="G-J-7n"(.*?[^>])>(.*?)<\\/1e>/gi,\'\');q=q.I(/<1e(.*?)id="G-J-5h"(.*?[^>])>(.*?)<\\/1e>/gi,\'\');q=q.I(/<3p(.*?[^<])>/gi,\'\');q=q.I(/<\\/3p>/gi,\'\');q=c.1x.2G(q);if(c.F.es){q=q.I(/<a(.*?)3G="et"(.*?[^>])>/gi,\'<a$1$2>\');q=q.I(/<a(.*?[^>])>/gi,\'<a$1 3G="et">\')}q=q.I(/<(.*?) 1h-G-R="(.*?)"(.*?[^>])>/gi,\'<$1$3>\');q=q.I(/<(.*?) 1h-G-1G="(.*?)"(.*?[^>])>/gi,\'<$1$3>\');q=q.I(/<(.*?) 1h-G-1n="(.*?)"(.*?[^>])>/gi,\'<$1$3>\');q=q.I(1J 1T(\'<(.*?) 1h-3v="G"(.*?[^>])>\',\'gi\'),\'<$1$2>\');q=q.I(1J 1T(\'<(.*?) 1h-3v="G">\',\'gi\'),\'<$1>\');E q},8B:B(q,8n){q=$.3d(q);q=q.I(/\\$/g,\'$\');q=q.I(/â€/g,\'"\');q=q.I(/“/g,\'"\');q=q.I(/‘/g,\'\\\'\');q=q.I(/’/g,\'\\\'\');q=q.I(/<1e 1G="ev-nV-2U">&53;<\\/1e>/gi,\' \');q=q.I(/<1e 1G="ev-5j-1e"[^>]*>\\t<\\/1e>/gi,\'\\t\');q=q.I(/<1e[^>]*>(\\s|&53;)<\\/1e>/gi,\' \');if(c.F.eu){E c.1p.8T(q)}if(!c.O.6J()&&1C 8n==\'1H\'){if(c.O.5g([\'eH\',\'A\'])){E c.1p.8T(q,M)}if(c.O.5g(\'ad\')){E c.1p.e0(q)}if(c.O.5g([\'8L\',\'eV\',\'eU\',\'eW\',\'eX\',\'eZ\',\'eY\'])){q=c.1p.ec(q);if(!c.O.26(\'2J\')){C N=c.K.47();if(N&&N.1l==\'P\'){q=q.I(/<1B(.*?)>/gi,\'<p><1B$1></p>\')}}E q}if(c.O.5g([\'7k\'])){q=c.1p.ax(q,\'3K\');if(c.F.1L)q=c.1p.am(q);q=c.1p.eg(q);E q}if(c.O.5g([\'4P\'])){E c.1p.ax(q,\'li\')}}q=c.1p.dY(q,8n);if(!c.1p.8I){if(c.F.1L)q=c.1p.am(q);if(c.F.6S)q=c.1p.6S(q);q=c.1p.bP(q)}q=c.1p.eR(q);q=c.1p.eM(q);q=c.1p.ax(q,\'ek\');if(!c.1p.8I&&c.F.2p){q=c.2p.2G(q)}q=c.1p.ei(q);q=c.1p.dU(q);q=c.1p.dR(q);q=c.1p.bN(q);E q},eR:B(q){q=q.I(/<!--[\\s\\S]*?-->/gi,\'\');q=q.I(/<1n[^>]*>[\\s\\S]*?<\\/1n>/gi,\'\');if(/(1G=\\"?eL|1n=\\"[^\\"]*\\ob\\-|w:oc)/.6L(q)){q=c.1p.dV(q);q=q.I(/<1B(.*?)v:od=(.*?)>/gi,\'\');q=q.I(/4e="1P\\:\\/\\/(.*?)"/,\'4e=""\');q=q.I(/<p(.*?)1G="oa"([\\w\\W]*?)<\\/p>/gi,\'<2O><li$2</li>\');q=q.I(/<p(.*?)1G="o9"([\\w\\W]*?)<\\/p>/gi,\'<li$2</li>\');q=q.I(/<p(.*?)1G="o6"([\\w\\W]*?)<\\/p>/gi,\'<li$2</li></2O>\');q=q.I(/<p(.*?)1G="o7"([\\w\\W]*?)<\\/p>/gi,\'<2O><li$2</li></2O>\');q=q.I(/·/g,\'\');q=q.I(/<p 1G="eL(.*?)"/gi,\'<p\');q=q.I(/ 1G=\\"(eK[^\\"]*)\\"/gi,"");q=q.I(/ 1G=(eK\\w+)/gi,"");q=q.I(/<o:p(.*?)>([\\w\\W]*?)<\\/o:p>/gi,\'$2\');q=q.I(/\\n/g,\' \');q=q.I(/<p>\\n?<li>/gi,\'<li>\')}if(c.F.eJ){q=q.I(/(\\s|&53;)+/g,\' \')}E q},eM:B(q){q=q.I(/<b\\nT="eN-az-2L(.*?)">([\\w\\W]*?)<\\/b>/gi,"$2");q=q.I(/<b(.*?)id="nF-eN-nH(.*?)">([\\w\\W]*?)<\\/b>/gi,"$3");q=q.I(/<1e[^>]*(3p-1n: 3X; 3p-6E: 3W|3p-6E: 3W; 3p-1n: 3X)[^>]*>/gi,\'<1e 1n="3p-6E: 3W;"><1e 1n="3p-1n: 3X;">\');q=q.I(/<1e[^>]*3p-1n: 3X[^>]*>/gi,\'<1e 1n="3p-1n: 3X;">\');q=q.I(/<1e[^>]*3p-6E: 3W[^>]*>/gi,\'<1e 1n="3p-6E: 3W;">\');q=q.I(/<1e[^>]*1b-76: 5c[^>]*>/gi,\'<1e 1n="1b-76: 5c;">\');q=q.I(/<1B>/gi,\'\');q=q.I(/\\n{3,}/gi,\'\\n\');q=q.I(/<3p(.*?)>([\\w\\W]*?)<\\/3p>/gi,\'$2\');q=q.I(/<p><p>/gi,\'<p>\');q=q.I(/<\\/p><\\/p>/gi,\'</p>\');q=q.I(/<li>(\\s*|\\t*|\\n*)<p>/gi,\'<li>\');q=q.I(/<\\/p>(\\s*|\\t*|\\n*)<\\/li>/gi,\'</li>\');q=q.I(/<\\/p>\\s<p/gi,\'<\\/p><p\');q=q.I(/<1B 4e="7g-nD-2c\\:\\/\\/(.*?)"(.*?)>/gi,\'\');q=q.I(/<p>•([\\w\\W]*?)<\\/p>/gi,\'<li>$1</li>\');if(c.O.26(\'6P\')){q=q.I(/<br\\s?\\/?>$/gi,\'\')}E q},ax:B(q,1c){C 2j=[\'1e\',\'a\',\'2D\',\'1N\',\'8l\',\'em\',\'5i\',\'1a\',\'a5\',\'6s\',\'aH\',\'8r\',\'C\',\'9V\',\'c9\',\'74\',\'7a\',\'b\',\'i\',\'u\',\'43\',\'ol\',\'2O\',\'li\',\'dl\',\'dt\',\'dd\',\'p\',\'br\',\'6t\',\'8q\',\'4W\',\'7f\',\'8p\',\'4F\',\'1B\',\'4q\',\'3K\',\'5U\',\'6q\',\'cs\',\'cT\',\'cJ\',\'h1\',\'h2\',\'h3\',\'h4\',\'h5\',\'h6\'];C bw=M;C bx=[[\'a\',\'*\'],[\'1B\',[\'4e\',\'72\']],[\'1e\',[\'1G\',\'3G\',\'1h-3v\']],[\'4W\',\'*\'],[\'6t\',\'*\'],[\'8q\',\'*\'],[\'7f\',\'*\'],[\'4F\',\'*\'],[\'8p\',\'*\'],[\'az\',\'*\']];if(1c==\'ek\'){bw=[\'p\',\'1e\',\'h1\',\'h2\',\'h3\',\'h4\',\'h5\',\'h6\'];bx=[[\'4q\',\'1G\'],[\'3K\',[\'nA\',\'nB\']],[\'a\',\'*\'],[\'1B\',[\'4e\',\'72\',\'1h-G-7V-J\']],[\'1e\',[\'1G\',\'3G\',\'1h-3v\']],[\'4W\',\'*\'],[\'6t\',\'*\'],[\'8q\',\'*\'],[\'7f\',\'*\'],[\'4F\',\'*\'],[\'8p\',\'*\'],[\'az\',\'*\']]}L if(1c==\'3K\'){2j=[\'2O\',\'ol\',\'li\',\'1e\',\'a\',\'8l\',\'em\',\'5i\',\'1a\',\'a5\',\'6s\',\'8r\',\'C\',\'9V\',\'c9\',\'74\',\'7a\',\'b\',\'i\',\'u\',\'43\',\'ol\',\'2O\',\'li\',\'dl\',\'dt\',\'dd\',\'br\',\'4W\',\'6t\',\'8q\',\'7f\',\'8p\',\'4F\',\'1B\',\'h1\',\'h2\',\'h3\',\'h4\',\'h5\',\'h6\']}L if(1c==\'li\'){2j=[\'2O\',\'ol\',\'li\',\'1e\',\'a\',\'8l\',\'em\',\'5i\',\'1a\',\'a5\',\'6s\',\'8r\',\'C\',\'9V\',\'c9\',\'74\',\'7a\',\'b\',\'i\',\'u\',\'43\',\'br\',\'4W\',\'6t\',\'8q\',\'7f\',\'8p\',\'4F\',\'1B\']}C 3L={4G:M,4R:2j,6k:1q,nQ:1q,1W:M,58:bx,3N:bw};E c.1x.2G(q,3L)},dR:B(q){q=q.I(/<(p|h[1-6])>(|\\s|\\n|\\t|<br\\s?\\/?>)<\\/(p|h[1-6])>/gi,\'\');if(!c.F.1L)q=q.I(/<br>$/i,\'\');E q},dU:B(q){q=q.I(/<1e>(.*?)<\\/1e>/gi,\'$1\');q=q.I(/<1e[^>]*>\\s|&53;<\\/1e>/gi,\' \');E q},dV:B(q){if(!c.O.26(\'2J\'))E q;C 52=$.3d(q);if(52.3F(/^<a(.*?)>(.*?)<\\/a>$/i)===0){q=q.I(/^<a(.*?)>(.*?)<\\/a>$/i,"$2")}E q},dY:B(q,8n){c.1p.8I=M;if(!c.O.6J()&&1C 8n==\'1H\'){C 1Q=c.F.8G.2H(\'|\').I(\'P|\',\'\').I(\'8F|\',\'\');C dX=q.2d(1J 1T(\'</(\'+1Q+\')>\',\'gi\'));C at=q.2d(/<\\/(p|1i)>/gi);if(!dX&&(at===4f||(at&&at.1o<=1))){C dP=q.2d(/<br\\s?\\/?>/gi);C dH=q.2d(/<1B(.*?[^>])>/gi);if(!dP&&!dH){c.1p.8I=1q;q=q.I(/<\\/?(p|1i)(.*?)>/gi,\'\')}}}E q},nM:B(3n,5a){5a=(((5a||\'\')+\'\').2P().2d(/<[a-z][a-8X-9]*>/g)||[]).2H(\'\');C 2j=/<\\/?([a-z][a-8X-9]*)\\b[^>]*>/gi;E 3n.I(2j,B($0,$1){E 5a.4T(\'<\'+$1.2P()+\'>\')>-1?$0:\'\'})},dZ:B(q){C 2D=q.2d(/<(2D|1a)(.*?)>([\\w\\W]*?)<\\/(2D|1a)>/gi);if(2D!==4f){$.1z(2D,$.X(B(i,s){C 3a=s.2d(/<(2D|1a)(.*?)>([\\w\\W]*?)<\\/(2D|1a)>/i);3a[3]=3a[3].I(/<br\\s?\\/?>/g,\'\\n\');3a[3]=3a[3].I(/&53;/g,\' \');if(c.F.5Z){3a[3]=3a[3].I(/\\t/g,7M(c.F.5Z+1).2H(\' \'))}3a[3]=c.1p.bs(3a[3]);3a[3]=3a[3].I(/\\$/g,\'$\');q=q.I(s,\'<\'+3a[1]+3a[2]+\'>\'+3a[3]+\'</\'+3a[1]+\'>\')},c))}E q},bp:B(q){q=q.I(/<br\\s?\\/?>|<\\/H[1-6]>|<\\/p>|<\\/1i>|<\\/li>|<\\/3K>/gi,\'\\n\');C 52=1d.3A(\'1i\');52.3w=q;q=52.ox||52.ow;E $.3d(q)},8T:B(q,2p){q=c.1p.bp(q);q=q.I(/\\n/g,\'<br />\');if(c.F.2p&&1C 2p==\'1H\'){q=c.2p.2G(q)}E q},e0:B(q){q=q.I(/<1B(.*?) 1n="(.*?)"(.*?[^>])>/gi,\'<1B$1$3>\');q=q.I(/<1B(.*?)>/gi,\'<1B$1>\');q=c.1p.bp(q);if(c.F.5Z){q=q.I(/\\t/g,7M(c.F.5Z+1).2H(\' \'))}q=c.1p.bs(q);E q},ec:B(q){q=q.I(/<1B(.*?)>/gi,\'[1B$1]\');q=q.I(/<(.*?)>/gi,\'\');q=q.I(/\\[1B(.*?)\\]/gi,\'<1B$1>\');E q},oE:B(q){q=q.I(/<a(.*?)29="(.*?)"(.*?)>([\\w\\W]*?)<\\/a>/gi,\'[a 29="$2"]$4[/a]\');q=q.I(/<1B(.*?)>/gi,\'[1B$1]\');q=q.I(/<(.*?)>/gi,\'\');q=q.I(/\\[a 29="(.*?)"\\]([\\w\\W]*?)\\[\\/a\\]/gi,\'<a 29="$1">$2</a>\');q=q.I(/\\[1B(.*?)\\]/gi,\'<1B$1>\');E q},bs:B(5l){5l=5L(5l).I(/&cE;/g,\'&\').I(/</g,\'<\').I(/>/g,\'>\').I(/&ef;/g,\'"\');E 5l.I(/&/g,\'&cE;\').I(/</g,\'<\').I(/>/g,\'>\').I(/"/g,\'&ef;\')},ei:B(q){if(c.O.26(\'2J\'))E q;C 1i=1d.3A(\'1i\');1i.3w=q;c.1p.bM($(1i));q=1i.3w;$(1i).1t();E q},4d:B(){if(c.O.26(\'2J\'))E;c.1p.bM(c.$U);C bC=c.$U.1k(\'h1, h2, h3, h4, h5, h6\');bC.1k(\'1e\').1W(\'1n\');bC.1k(c.F.bL.2H(\', \')).1W(\'1n\');c.1a.1R()},bM:B($U){$U.1k(c.F.bL.2H(\', \')).1W(\'1n\');$U.1k(\'1e\').6o(\'[1h-3v="G"]\').1W(\'1n\');$U.1k(\'1e[1h-3v="G"], 1B[1h-3v="G"]\').1z(B(i,s){C $s=$(s);$s.Y(\'1n\',$s.Y(\'3G\'))})},6B:B(q){if(c.O.26(\'2J\'))E q;q=q.I(1J 1T(\'<1B(.*?[^>])>\',\'gi\'),\'<1B$1 1h-3v="G">\');q=q.I(1J 1T(\'<1e(.*?)>\',\'gi\'),\'<1e$1 1h-3v="G">\');C 4l=q.2d(1J 1T(\'<(1e|1B)(.*?)1n="(.*?)"(.*?[^>])>\',\'gi\'));if(4l){C 22=4l.1o;2v(C i=0;i<22;i++){4s{C eh=4l[i].I(/1n="(.*?)"/i,\'1n="$1" 3G="$1"\');q=q.I(1J 1T(4l[i],\'gi\'),eh)}4x(e){}}}E q},bN:B(q){C $1i=$(\'<1i />\').q(q);C 2j=c.F.4C;2j.2W(\'1e\');$1i.1k(2j.2H(\',\')).1z(B(){C $el=$(c);C R=c.1l.2P();$el.Y(\'1h-G-R\',R);if(R==\'1e\'){if($el.Y(\'1n\'))$el.Y(\'1h-G-1n\',$el.Y(\'1n\'));L if($el.Y(\'1G\'))$el.Y(\'1h-G-1G\',$el.Y(\'1G\'))}});q=$1i.q();$1i.1t();E q},a6:B(){c.$U.1k(\'li\').1z(B(i,s){C $2b=$(s).2b();if($2b.1o!==0&&($2b[0].1l==\'8j\'||$2b[0].1l==\'8i\')){$(s).1w($2b)}})},cN:B(q){q=q.I(/\\n/g,\'\');q=q.I(/[\\t]*/g,\'\');q=q.I(/\\n\\s*\\n/g,"\\n");q=q.I(/^[\\s\\n]*/g,\' \');q=q.I(/[\\s\\n]*$/g,\' \');q=q.I(/>\\s{2,}</g,\'> <\');q=q.I(/\\n\\n/g,"\\n");q=q.I(/[\\8o-\\aE\\aq]/g,\'\');E q},6S:B(q){if(c.F.1L){q=q.I(/<1i><br\\s?\\/?><\\/1i>/gi,\'<br />\');q=q.I(/<1i(.*?)>([\\w\\W]*?)<\\/1i>/gi,\'$2<br />\')}L{q=q.I(/<1i(.*?)>([\\w\\W]*?)<\\/1i>/gi,\'<p$1>$2</p>\')}E q},eg:B(q){q=q.I(/<1i\\s(.*?)>/gi,\'<p>\');q=q.I(/<1i><br\\s?\\/?><\\/1i>/gi,\'<br /><br />\');q=q.I(/<1i>([\\w\\W]*?)<\\/1i>/gi,\'$1<br /><br />\');E q},am:B(q){q=q.I(/<p\\s(.*?)>/gi,\'<p>\');q=q.I(/<p><br\\s?\\/?><\\/p>/gi,\'<br />\');q=q.I(/<p>([\\w\\W]*?)<\\/p>/gi,\'$1<br /><br />\');q=q.I(/(<br\\s?\\/?>){1,}\\n?<\\/1N>/gi,\'</1N>\');E q},bP:B(q){E q.I(/<5v(.*?)>([\\w\\W]*?)<\\/5v>/gi,\'<3T$1 3G="G-5v-R">$2</3T>\')},e9:B(q){E q.I(/<3T(.*?) 3G="G-5v-R"(.*?)>([\\w\\W]*?)<\\/3T>/gi,\'<5v$1$2>$3</5v>\')}}},1a:B(){E{1K:B(q){q=$.3d(q.4I());q=c.1p.e3(q);c.$U.q(q);c.1a.1R();3q($.X(c.1Z.ck,c),15);if(c.2X===M)c.2n.2G()},14:B(){C 1a=c.$2E.2w();1a=c.2s.14(1a);E 1a},1R:B(){3q($.X(c.1a.e2,c),10)},e2:B(){C q=c.$U.q();if(c.1a.bG&&c.1a.bG==q){E}c.1a.bG=q;q=c.1S.2o(\'nx\',q);q=c.1p.b5(q);c.$2E.2w(q);c.1S.2o(\'1R\',q);if(c.2X===M){c.1S.2o(\'i1\',q)}c.2X=M;c.3x.e1()},2M:B(){if(c.F.63){c.1a.bH()}L{c.1a.e6()}},bH:B(){c.1a.2Q=c.1U.a4();C 6W=$(3M).3C();C 3f=c.$U.5G();c.$U.3b();C q=c.$2E.2w();c.fb=c.1p.cN(q);q=c.2s.14(q);c.$2E.2w(q).3f(3f).2B().2t();c.$2E.on(\'1u.G-2E-fc\',c.1a.g4);$(3M).3C(6W);if(c.$2E[0].e8){c.$2E[0].e8(0,0)}c.$2E[0].3C=0;c.F.63=M;c.1s.e7();c.1s.8d(\'q\');c.1S.2o(\'az\',q)},e6:B(){if(c.F.63)E;C q=c.$2E.3b().2w();if(c.fb!==c.1p.cN(q)){c.1a.1K(q)}c.$U.2B();if(!c.O.4t(q)){c.2Y.1t()}c.1U.9o(c.1a.2Q);c.$2E.3H(\'1u.G-2E-fc\');c.1s.g6();c.1s.g5(\'q\');c.2n.2G();c.F.63=1q},g4:B(e){if(e.3j!==9)E 1q;C $el=c.$2E;C 2X=$el.14(0).g8;$el.2w($el.2w().9z(0,2X)+"\\t"+$el.2w().9z($el.14(0).gb));$el.14(0).g8=$el.14(0).gb=2X+1;E M}}},1S:B(){E{mM:B(){E $.70({},c)},mS:B(){E c.$U},mT:B(){E c.$2r},mR:B(){E c.$2F},mQ:B(){E c.$2E},mN:B(){E(c.$1r)?c.$1r:M},7H:B(1f){c.1S.ga=1f},69:B(){E c.1S.ga},2o:B(1c,e,1h){C 2l=c.F[1c+\'mP\'];if($.5n(2l)){E(1C 1h==\'1H\')?2l.5X(c,e):2l.5X(c,e,1h)}L{E(1C 1h==\'1H\')?e:1h}},g3:B(){c.1S.2o(\'g3\');c.$2F.3H(\'.G\').g2(\'G\');c.$U.3H(\'.G\');c.$U.2I(\'G-U G-1L G-2Y\');c.$U.1W(\'77\');C q=c.1a.14();if(c.2f.8O()){c.$2r.3u(c.$2F);c.$2r.1t();c.$2F.2w(q).2B()}L{c.$2r.3u(c.$U);c.$2r.1t();c.$2F.q(q).2B()}if(c.$5C)c.$5C.1t();if(c.$4o)c.$4o.1t();if(c.$6Y)c.$6Y.1t();$(\'.G-1r-31\').1t();fW(c.7K)}}},1y:B(){E{2f:B(1f,$1y,cm){if(1f==\'2K\'&&c.F.cq){$.1z(c.F.cq,$.X(B(i,s){C 1f=s.R;if(1C s.1G!=\'1H\'){1f=1f+\'-\'+s.1G}s.1c=(c.O.6V(s.R))?\'N\':\'1V\';C 1v=(s.1c==\'1V\')?\'1V.2K\':\'N.2K\';if(c.F.1L&&s.1c==\'N\'&&s.R==\'p\')E;c.2K[1f]={R:s.R,1n:s.1n,\'1G\':s.1G,Y:s.Y,1h:s.1h};cm[1f]={1v:1v,1F:s.1F}},c))}$.1z(cm,$.X(B(2i,3k){C $3g=$(\'<a 29="#" 1G="G-1y-\'+2i+\'">\'+3k.1F+\'</a>\');if(1f==\'2K\')$3g.2q(\'G-2K-\'+2i);$3g.on(\'2e\',$.X(B(e){C 1c=\'1v\';C 2l=3k.1v;if(3k.4a){1c=\'4a\';2l=3k.4a}L if(3k.1y){1c=\'1y\';2l=3k.1y}c.1s.9l(e,2i,1c,2l)},c));$1y.1w($3g)},c))},2B:B(e,1m){if(!c.F.63){e.2k();E M}C $1s=c.1s.14(1m);C $1y=$1s.1h(\'1y\').cw(1d.2x);1d.iJ.aD();if($1s.3i(\'78\')){c.1y.9M()}L{c.1y.9M();c.1S.2o(\'mj\',{1y:$1y,1m:1m,1s:$1s});c.1s.8d(1m);$1s.2q(\'78\');C 7v=$1s.2Q();C cn=$1y.2h();if((7v.21+cn)>$(1d).2h()){7v.21-=cn}C 21=7v.21+\'3m\';if(c.$1r.3i(\'1r-71-2r\')){C 2C=c.$1r.5G()+c.F.6y;C 3R=\'71\';if(c.F.6v!==1d){2C=(c.$1r.5G()+c.$1r.2Q().2C)+c.F.6y;3R=\'8H\'}$1y.1I({3R:3R,21:21,2C:2C+\'3m\'}).2B()}L{C 2C=($1s.5G()+7v.2C)+\'3m\';$1y.1I({3R:\'8H\',21:21,2C:2C}).2B()}c.1S.2o(\'ml\',{1y:$1y,1m:1m,1s:$1s})}$(1d).fX(\'2e\',$.X(c.1y.3b,c));c.$U.fX(\'2e\',$.X(c.1y.3b,c));C $2x=$(1d.2x);C 2h=$2x.2h();$1y.on(\'fY\',B(){$2x.2q(\'2x-6z\');$2x.1I(\'48-4c\',($2x.2h()-2h)+\'3m\')});$1y.on(\'g1\',B(){$2x.2I(\'2x-6z\').1I(\'48-4c\',0)});e.do()},9M:B(){c.$1r.1k(\'a.78\').2I(\'G-7D\').2I(\'78\');$(1d.2x).2I(\'2x-6z\').1I(\'48-4c\',0);$(\'.G-1y\').3b();c.1S.2o(\'mA\')},3b:B(e){C $1y=$(e.1M);if(!$1y.3i(\'78\')){$1y.2I(\'78\');c.1y.9M()}}}},1P:B(){E{2B:B(){c.V.2G(\'1P\',c.1E.14(\'1P\'),fZ);c.1j.3r(\'#G-V-1P-1j\',c.F.8t,c.1P.1O);c.K.2R();c.K.14();C 1b=c.2N.4I();$(\'#G-6p\').2w(1b);c.V.2B()},1O:B(2z,4H,e){if(1C 2z.5r!=\'1H\'){c.V.44();c.K.2S();c.1S.2o(\'mv\',2z);E}C T;if(1C 2z==\'62\'){T=2z}L{C 1b=$(\'#G-6p\').2w();if(1C 1b==\'1H\'||1b===\'\')1b=2z.6p;T=\'<a 29="\'+2z.8z+\'" id="8z-2L">\'+1b+\'</a>\'}if(4H){c.K.aC();C 2L=c.K.6d();c.1O.b2(e,2L)}L{c.V.44()}c.K.2S();c.1Z.1K();c.1O.q(T);if(1C 2z==\'62\')E;C 8c=$(c.$U.1k(\'a#8z-2L\'));if(8c.28()!==0)8c.1W(\'id\');L 8c=M;c.1S.2o(\'8t\',8c,2z)}}},2t:B(){E{3h:B(){c.$U.2t();C 3z=c.$U.4g().3z();if(3z.28()===0)E;if(3z[0].1o===0||3z[0].1l==\'6i\'||3z[0].9Z==3){E}if(3z[0].1l==\'8j\'||3z[0].1l==\'8i\'){3z=3z.1k(\'li\').3z();C 5Y=3z.4g().3z();if(!c.O.6m(5Y)&&5Y.1b()===\'\'){c.1U.3h(5Y);E}}if(c.F.1L&&!c.O.6V(3z[0].1l)){c.K.14();c.12.3h(c.$U[0],0);c.12.41(c.$U[0],0);c.K.4M();E}c.1U.3h(3z)},41:B(){if(c.O.26(\'6P\')||c.O.26(\'2J\')){C 3o=c.$U.4g().3o();c.1U.41(3o)}L{c.K.14();4s{c.12.ap(c.$U[0]);c.12.51(M);c.K.4M()}4x(e){}}},g0:B(){C 7L=1d.6a().7L;if(7L===4f)E M;if(c.F.1L&&$(7L.bk).3i(\'G-1L\'))E 1q;L if(!c.O.4i(7L.bk))E M;E c.$U.is(\':2t\')}}},J:B(){E{2B:B(){c.V.2G(\'J\',c.1E.14(\'J\'),fZ);c.1j.3r(\'#G-V-J-3P\',c.F.8s,c.J.1O);c.K.2R();c.V.2B()},gl:B($J){C $T=$J.2u(\'a\');c.V.2G(\'im\',c.1E.14(\'7T\'),nn);c.V.cU();c.J.gd=c.V.iK(c.1E.14(\'gc\'));c.J.gr=c.V.cu(c.1E.14(\'2R\'));c.J.gd.on(\'2e\',$.X(B(){c.J.1t($J)},c));c.J.gr.on(\'2e\',$.X(B(){c.J.dF($J)},c));$(\'#G-J-1F\').2w($J.Y(\'72\'));if(!c.F.gq)$(\'.G-J-T-3E\').3b();L{C $cx=$(\'#G-J-T\');$cx.Y(\'29\',$J.Y(\'4e\'));if($T.28()!==0){$cx.2w($T.Y(\'29\'));if($T.Y(\'1M\')==\'7e\')$(\'#G-J-T-6R\').8P(\'8N\',1q)}}if(!c.F.gp)$(\'.G-J-3R-3E\').3b();L{C gs=($J.1I(\'6f\')==\'N\'&&$J.1I(\'7i\')==\'5f\')?\'57\':$J.1I(\'7i\');$(\'#G-J-4S\').2w(gs)}c.V.2B()},gx:B($J){C gu=$(\'#G-J-4S\').2w();C 9s=\'\';C cI=\'\';C 88=\'\';fm(gu){7Q\'21\':9s=\'21\';88=\'0 \'+c.F.8b+\' \'+c.F.8b+\' 0\';6x;7Q\'4c\':9s=\'4c\';88=\'0 0 \'+c.F.8b+\' \'+c.F.8b;6x;7Q\'57\':cI=\'N\';88=\'a3\';6x}$J.1I({\'7i\':9s,6f:cI,48:88});$J.Y(\'3G\',$J.Y(\'1n\'))},dF:B($J){c.J.64();c.1Z.1K();C $T=$J.2u(\'a\');$J.Y(\'72\',$(\'#G-J-1F\').2w());c.J.gx($J);C T=$.3d($(\'#G-J-T\').2w());if(T!==\'\'){C 1M=($(\'#G-J-T-6R\').8P(\'8N\'))?1q:M;if($T.28()===0){C a=$(\'<a 29="\'+T+\'">\'+c.O.5K($J)+\'</a>\');if(1M)a.Y(\'1M\',\'7e\');$J.2y(a)}L{$T.Y(\'29\',T);if(1M){$T.Y(\'1M\',\'7e\')}L{$T.1W(\'1M\')}}}L if($T.28()!==0){$T.2y(c.O.5K($J))}c.V.44();c.2n.9P();c.1a.1R()},j0:B($J){if(!c.F.gw)E;$J.on(\'nr\',$.X(c.J.9H,c));$J.on(\'cD\',$.X(c.J.64,c));$J.on(\'2e 68\',$.X(B(e){c.2n.J=$J;if(c.$U.1k(\'#G-J-2r\').28()!==0)E M;c.J.7n=c.J.gj($J);$(1d).on(\'2e.G-J-4m-3b\',$.X(c.J.64,c));c.$U.on(\'2e.G-J-4m-3b\',$.X(c.J.64,c));if(!c.F.aN)E;c.J.7n.on(\'cD.G 68.G\',$.X(B(e){e.2k();c.J.4b={x:e.gv,y:e.9u,el:$J,cy:$J.2h()/$J.3f(),h:$J.3f()};e=e.7l||e;if(e.7C){c.J.4b.x=e.7C[0].gv;c.J.4b.y=e.7C[0].9u}c.J.go()},c))},c))},go:B(){$(1d).on(\'nd.G-J-4m n1.G-J-4m\',$.X(c.J.gn,c));$(1d).on(\'gC.G-J-4m n2.G-J-4m\',$.X(c.J.gg,c))},gn:B(e){e.2k();e=e.7l||e;C 3f=c.J.4b.h;if(e.7C)3f+=(e.7C[0].9u-c.J.4b.y);L 3f+=(e.9u-c.J.4b.y);C 2h=n0.mZ(3f*c.J.4b.cy);if(3f<50||2h<7I)E;c.J.4b.el.2h(2h);c.J.4b.el.3f(c.J.4b.el.2h()/c.J.4b.cy);c.1a.1R()},gg:B(){c.iS=M;$(1d).3H(\'.G-J-4m\');c.J.64()},9H:B(e){if(c.$U.1k(\'#G-J-2r\').28()!==0){e.2k();E M}c.$U.on(\'4A.G-J-gf-4A\',$.X(B(){3q($.X(c.J.9U,c),1)},c))},9U:B(){c.J.ge();c.2n.9P();c.$U.3H(\'4A.G-J-gf-4A\');c.1p.4d();c.1a.1R()},ge:B(){c.$U.1k(\'1B[1h-2R-2c]\').1z(B(){C $el=$(c);$el.Y(\'4e\',$el.Y(\'1h-2R-2c\'));$el.1W(\'1h-2R-2c\')})},64:B(e){if(e&&$(e.1M).2u(\'#G-J-2r\').1o!==0)E;if(e&&e.1M.1l==\'bj\'){C $J=$(e.1M);$J.Y(\'1h-2R-2c\',$J.Y(\'4e\'))}C 3s=c.$U.1k(\'#G-J-2r\');if(3s.28()===0)E;c.J.5h.1t();$(c.J.7n).1t();3s.1k(\'1B\').1I({5t:3s[0].1n.5t,9y:3s[0].1n.9y,9w:3s[0].1n.9w,9x:3s[0].1n.9x});3s.1I(\'48\',\'\');3s.1k(\'1B\').1I(\'gm\',\'\');3s.2y(B(){E $(c).23()});$(1d).3H(\'2e.G-J-4m-3b\');c.$U.3H(\'2e.G-J-4m-3b\');if(1C c.J.4b!==\'1H\'){c.J.4b.el.Y(\'3G\',c.J.4b.el.Y(\'1n\'))}c.1a.1R()},gj:B($J){C 3s=$(\'<1e id="G-J-2r" 1h-G="3v">\');3s.1I(\'7i\',$J.1I(\'7i\')).Y(\'77\',M);if($J[0].1n.48!=\'a3\'){3s.1I({5t:$J[0].1n.5t,9y:$J[0].1n.9y,9w:$J[0].1n.9w,9x:$J[0].1n.9x});$J.1I(\'48\',\'\')}L{3s.1I({\'6f\':\'N\',\'48\':\'a3\'})}$J.1I(\'gm\',\'.5\').3u(3s);c.J.5h=$(\'<1e id="G-J-5h" 1h-G="3v">\'+c.1E.14(\'7T\')+\'</1e>\');c.J.5h.Y(\'77\',M);c.J.5h.on(\'2e\',$.X(B(){c.J.gl($J)},c));3s.1w(c.J.5h);C gk=c.J.5h.a0();c.J.5h.1I(\'48-21\',\'-\'+gk/2+\'3m\');if(c.F.aN&&!c.O.5Q()){C 8e=$(\'<1e id="G-J-7n" 1h-G="3v"></1e>\');if(!c.O.c8()){8e.1I({2h:\'fT\',3f:\'fT\'})}8e.Y(\'77\',M);3s.1w(8e);3s.1w($J);E 8e}L{3s.1w($J);E M}},1t:B(J){C $J=$(J);C $T=$J.2u(\'a\');C $6r=$J.2u(\'6r\');C $1g=$J.1g();if($(\'#G-J-2r\').28()!==0){$1g=$(\'#G-J-2r\').1g()}C $2b;if($6r.28()!==0){$2b=$6r.2b();$6r.1t()}L if($T.28()!==0){$1g=$T.1g();$T.1t()}L{$J.1t()}$(\'#G-J-2r\').1t();if($6r.28()!==0){c.1U.3h($2b)}L{c.1U.3h($1g)}c.1S.2o(\'bf\',$J[0].4e,$J);c.V.44();c.1a.1R()},1O:B(2z,4H,e){if(1C 2z.5r!=\'1H\'){c.V.44();c.K.2S();c.1S.2o(\'nt\',2z);E}C $1B;if(1C 2z==\'62\'){$1B=$(2z).Y(\'1h-G-7V-J\',\'1q\')}L{$1B=$(\'<1B>\');$1B.Y(\'4e\',2z.8z).Y(\'1h-G-7V-J\',\'1q\')}C Q=$1B;C aP=c.O.5g(\'P\');if(aP){Q=$(\'<1N />\').1w($1B)}if(4H){c.K.aC();C 2L=c.K.6d();c.1O.b2(e,2L)}L{c.V.44()}c.K.2S();c.1Z.1K();c.1O.q(c.O.5K(Q),M);C $J=c.$U.1k(\'1B[1h-G-7V-J=1q]\').1W(\'1h-G-7V-J\');if(aP){$J.1g().23().3Y().5E(\'<p />\')}L if(c.F.1L){$J.aI(\'<br>\').3u(\'<br>\')}if(1C 2z==\'62\')E;c.1S.2o(\'8s\',$J,2z)}}},3e:B(){E{8S:B(){if(!c.O.26(\'2J\'))c.$U.2t();c.1Z.1K();c.K.2R();C N=c.K.47();if(N&&N.1l==\'4P\'){c.3e.fs()}L if(N===M&&c.F.1L){c.3e.fq()}L{c.3e.fr()}c.K.2S();c.1a.1R()},fs:B(){1d.3O(\'3e\');c.3e.af();c.1p.a6();c.1p.4d()},fr:B(){$.1z(c.K.3V(),$.X(B(i,4z){if(4z.1l===\'7k\'||4z.1l===\'aL\')E;C $el=c.O.9e(4z);C 21=c.O.bv($el.1I(\'48-21\'))+c.F.9I;$el.1I(\'48-21\',21+\'3m\')},c))},fq:B(){C 4j=c.K.5E(\'1i\');$(4j).Y(\'1h-7N\',\'G\');$(4j).1I(\'48-21\',c.F.9I+\'3m\')},8Z:B(){c.1Z.1K();c.K.2R();C N=c.K.47();if(N&&N.1l==\'4P\'){c.3e.ft()}L{c.3e.fu()}c.K.2S();c.1a.1R()},ft:B(){1d.3O(\'6O\');C 1A=c.K.3J();C $3g=$(1A).2u(\'li\');C $1g=$3g.1g();if($3g.28()!==0&&$1g.28()!==0&&$1g[0].1l==\'4P\'){$1g.3u($3g)}c.3e.af();if(!c.F.1L&&$3g.28()===0){1d.3O(\'a2\',M,\'p\');c.$U.1k(\'2O, ol, 1N, p\').1z($.X(c.O.3N,c))}c.1p.4d()},fu:B(){$.1z(c.K.3V(),$.X(B(i,4z){C $el=c.O.9e(4z);C 21=c.O.bv($el.1I(\'48-21\'))-c.F.9I;if(21<=0){if(c.F.1L&&1C($el.1h(\'7N\'))!==\'1H\'){$el.2y($el.q()+\'<br />\')}L{$el.1I(\'48-21\',\'\');c.O.5J($el,\'1n\')}}L{$el.1I(\'48-21\',21+\'3m\')}},c))},af:B(){C N=c.K.47();if(c.12.4Z&&N&&N.1l==\'4P\'&&c.O.4t($(N).1b())){C $N=$(N);$N.1k(\'1e\').6o(\'.G-K-2L\').23().3Y();$N.1w(\'<br>\')}}}},1V:B(){E{2K:B(1f){C 1c,1D;if(1C c.2K[1f].1n!=\'1H\')1c=\'1n\';L if(1C c.2K[1f].1G!=\'1H\')1c=\'1G\';if(1c)1D=c.2K[1f][1c];c.1V.2Z(c.2K[1f].R,1c,1D)},2Z:B(R,1c,1D){if(c.O.5g(\'ad\'))E;C 2j=[\'b\',\'3W\',\'i\',\'3X\',\'5c\',\'fo\',\'5I\',\'fx\',\'fw\'];C 82=[\'5i\',\'5i\',\'em\',\'em\',\'u\',\'43\',\'43\',\'74\',\'7a\'];2v(C i=0;i<2j.1o;i++){if(R==2j[i])R=82[i]}c.1V.1c=1c||M;c.1V.1D=1D||M;c.1Z.1K();c.$U.2t();c.K.14();if(c.12.4Z){c.1V.fv(R)}L{c.1V.fp(R)}},fv:B(R){C 1A=c.K.3J();C $1g=$(1A).2u(R+\'[1h-G-R=\'+R+\']\');if($1g.28()!==0){c.1U.5q($1g[0]);if(c.O.4t($1g.1b()))$1g.1t();c.1a.1R();E}C Q=$(\'<\'+R+\'>\').Y(\'1h-3v\',\'G\').Y(\'1h-G-R\',R);Q.q(c.F.5M);Q=c.1V.b1(Q);c.1O.Q(Q);c.1a.1R();E},fp:B(R){c.1V.fe(R);c.K.2R();1d.3O(\'fo\');c.$U.1k(\'81\').1z($.X(B(i,s){C $el=$(s);c.1V.ff($el,R);C $1e;if(c.1V.1c){$1e=$(\'<1e>\').Y(\'1h-G-R\',R).Y(\'1h-3v\',\'G\');$1e=c.1V.b1($1e)}L{$1e=$(\'<\'+R+\'>\').Y(\'1h-G-R\',R).Y(\'1h-3v\',\'G\')}$el.2y($1e.q($el.23()));if(R==\'1e\'){C $1g=$1e.1g();if($1g&&$1g[0].1l==\'6M\'&&c.1V.1c==\'1n\'){C 3a=c.1V.1D.4E(\';\');2v(C z=0;z<3a.1o;z++){if(3a[z]===\'\')E;C 1n=3a[z].4E(\':\');$1g.1I(1n[0],\'\');if(c.O.5J($1g,\'1n\')){$1g.2y($1g.23())}}}}},c));if(R!=\'1e\'){c.$U.1k(c.F.4C.2H(\', \')).1z($.X(B(i,s){C $el=$(s);C 9f=$el.1I(\'1b-76\');if(9f==\'4r-fh\'){$el.1I(\'1b-76\',\'\');c.O.5J($el,\'1n\')}},c))}if(R!=\'43\'){C fg=c;c.$U.1k(\'1V\').1z(B(i,s){fg.O.4v(s,\'43\')})}c.K.2S();c.1a.1R()},ff:B($el,R){$el.4g(R).1z(B(){C $5Y=$(c);if(!$5Y.3i(\'G-K-2L\')){$5Y.23().3Y()}})},fe:B(R){c.K.2R();C 1k=\'\';if(c.1V.1c==\'1G\')1k=\'[1h-G-1G=\'+c.1V.1D+\']\';L if(c.1V.1c==\'1n\'){1k=\'[1h-G-1n="\'+c.1V.1D+\'"]\'}if(R!=\'43\'){C 3Q=c;c.$U.1k(\'43\').1z(B(i,s){3Q.O.4v(s,\'1V\')})}c.$U.1k(\'[1h-G-R="\'+R+\'"]\'+1k).1z(B(){if(1k===\'\'&&R==\'1e\'&&c.1l.2P()==R)E;C $el=$(c);$el.2y($(\'<81 />\').q($el.23()))});c.K.2S()},b1:B(Q){fm(c.1V.1c){7Q\'1G\':if(Q.3i(c.1V.1D)){Q.2I(c.1V.1D);Q.1W(\'1h-G-1G\')}L{Q.2q(c.1V.1D);Q.Y(\'1h-G-1G\',c.1V.1D)}6x;7Q\'1n\':Q[0].1n.oy=c.1V.1D;Q.Y(\'1h-G-1n\',c.1V.1D);6x}E Q},op:B(){c.1Z.1K();C 1A=c.K.3J();C 1X=c.K.aS();c.K.2R();if(1A&&1A.1l===\'6M\'){C $s=$(1A);$s.1W(\'1n\');if($s[0].42.1o===0){$s.2y($s.23())}}$.1z(1X,$.X(B(i,s){C $s=$(s);if($.3B(s.1l.2P(),c.F.4C)!=-1&&!$s.3i(\'G-K-2L\')){$s.1W(\'1n\');if($s[0].42.1o===0){$s.2y($s.23())}}},c));c.K.2S();c.1a.1R()},om:B(1f){c.1Z.1K();C 1g=c.K.5R();C 1X=c.K.aS();c.K.2R();if(1g&&1g.1l===\'6M\'){C $s=$(1g);$s.1I(1f,\'\');c.O.5J($s,\'1n\');if($s[0].42.1o===0){$s.2y($s.23())}}$.1z(1X,$.X(B(i,s){C $s=$(s);if($.3B(s.1l.2P(),c.F.4C)!=-1&&!$s.3i(\'G-K-2L\')){$s.1I(1f,\'\');c.O.5J($s,\'1n\');if($s[0].42.1o===0){$s.2y($s.23())}}},c));c.K.2S();c.1a.1R()},b7:B(){c.1Z.1K();C 1A=c.K.3J();c.K.2R();1d.3O(\'b7\');if(1A&&1A.1l===\'6M\'){$(1A).2y($(1A).23())}$.1z(c.K.6Z(),$.X(B(i,s){C $s=$(s);if($.3B(s.1l.2P(),c.F.4C)!=-1&&!$s.3i(\'G-K-2L\')){$s.2y($s.23())}},c));c.K.2S();c.1a.1R()},94:B(4u){c.1V.2Z(\'1e\',\'1G\',4u)},oi:B(1D){c.1V.2Z(\'1e\',\'1n\',1D)}}},1O:B(){E{1K:B(q,1p){c.2Y.1t();q=c.1p.6B(q);if(1C 1p==\'1H\'){q=c.1p.8B(q,M)}c.$U.q(q);c.K.1t();c.2t.41();c.1p.a6();c.1a.1R();c.2n.2G();if(1C 1p==\'1H\'){3q($.X(c.1p.4d,c),10)}},1b:B(1b){c.2Y.1t();1b=1b.4I();1b=$.3d(1b);1b=c.1p.8T(1b,M);c.$U.2t();if(c.O.26(\'2J\')){c.1O.aV(1b)}L{c.K.14();c.12.4L();C el=1d.3A("1i");el.3w=1b;C 4X=1d.cV(),Q,4Y;4O((Q=el.aR)){4Y=4X.7S(Q)}c.12.49(4X);if(4Y){C 12=c.12.7B();12.fO(4Y);12.51(1q);c.2N.aB();c.2N.4M(12)}}c.1a.1R();c.1p.4d()},oB:B(q){c.1O.q(q,M)},q:B(q,1p){c.2Y.1t();if(1C 1p==\'1H\')1p=1q;c.$U.2t();q=c.1p.6B(q);if(1p){q=c.1p.8B(q)}if(c.O.26(\'2J\')){c.1O.aV(q)}L{if(c.1p.8I)c.1O.fI(q);L 1d.3O(\'iB\',4f,q);c.1O.fQ()}c.1p.a6();if(!c.F.1L){c.$U.1k(\'p\').1z($.X(c.O.3N,c))}c.1a.1R();c.2n.2G();if(1p){c.1p.4d()}},fQ:B(){if(!c.O.26(\'6P\'))E;C $2b=$(c.K.47()).2b();if($2b.1o>0&&$2b[0].1l==\'P\'&&$2b.q()===\'\'){$2b.1t()}},aV:B(q){if(c.O.hM()){C 1g=c.O.5g(\'P\');C $q=$(\'<1i>\').1w(q);C fJ=$q.23().is(\'p, :a9, dl, 2O, ol, 1i, 4q, 3K, 1N, 2D, aH, 3T, a9, b3, it, iu\');if(1g&&fJ)c.1O.fF(1g,q);L c.1O.gy(q);E}1d.K.aZ().nE(q)},fI:B(q){q=c.1p.6B(q);c.K.14();c.12.4L();C el=1d.3A(\'1i\');el.3w=q;C 4X=1d.cV(),Q,4Y;4O((Q=el.aR)){4Y=4X.7S(Q)}c.12.49(4X);c.12.51(1q);c.1U.5q(4Y)},Q:B(Q,4L){Q=Q[0]||Q;C q=c.O.5K(Q);q=c.1p.6B(q);Q=$(q)[0];c.K.14();if(4L!==M){c.12.4L()}c.12.49(Q);c.12.51(M);c.K.4M();E Q},nW:B(Q,x,y){Q=Q[0]||Q;c.K.14();C 12;if(1d.8Y){C 2V=1d.8Y(x,y);c.12.3h(2V.fA,2V.2Q);c.12.51(1q);c.12.49(Q)}L if(1d.8U){12=1d.8U(x,y);12.49(Q)}L if(1C 1d.2x.9m!="1H"){12=1d.2x.9m();12.9G(x,y);C 6I=12.fE();6I.9G(x,y);12.fH("fG",6I);12.6U()}},b2:B(e,Q){Q=Q[0]||Q;C 12;C x=e.o5,y=e.nL;if(1d.8Y){C 2V=1d.8Y(x,y);C 2N=1d.6a();12=2N.6G(0);12.3h(2V.fA,2V.2Q);12.51(1q);12.49(Q)}L if(1d.8U){12=1d.8U(x,y);12.49(Q)}L if(1C 1d.2x.9m!="1H"){12=1d.2x.9m();12.9G(x,y);C 6I=12.fE();6I.9G(x,y);12.fH("fG",6I);12.6U()}},fF:B(1g,q){C Q=1d.3A(\'1e\');Q.4u=\'G-ie-4V\';c.1O.Q(Q);C 9p=$(1g).q();9p=\'<p>\'+9p.I(/<1e 1G="G-ie-4V"><\\/1e>/gi,\'</p>\'+q+\'<p>\')+\'</p>\';$(1g).2y(9p)},gy:B(q){c.K.14();c.12.4L();C el=1d.3A("1i");el.3w=q;C 4X=1d.cV(),Q,4Y;4O((Q=el.aR)){4Y=4X.7S(Q)}c.12.49(4X)}}},1u:B(){E{3r:B(e){if(c.7h)E;C 1m=e.7E;C 4D=(1m>=37&&1m<=40);c.1u.3S=e.7X||e.5W;c.1u.1A=c.K.3J();c.1u.1g=c.K.5R();c.1u.N=c.K.47();c.1u.2D=c.O.9Y(c.1u.1A,\'2D\');c.1u.1N=c.O.9Y(c.1u.1A,\'1N\');c.1u.6Q=c.O.9Y(c.1u.1A,\'6Q\');c.5A.3r(e,1m);c.1u.dw(4D,1m);c.1u.cX(e,1m);c.1u.dm(4D);c.1u.d9(e,1m);C d4=c.1S.2o(\'1u\',e);if(d4===M){e.2k();E M}if(c.F.bi&&1m===c.3j.db){c.1u.dx()}if(!c.F.bi&&1m===c.3j.5T){e.2k();if(!c.12.4Z)c.12.4L();E}if(1m==c.3j.5T&&!e.5S&&!e.7X&&!e.5W){C d0=c.1S.2o(\'oh\',e);if(d0===M){e.2k();E M}if(c.1u.1N&&c.1u.df(e)===1q){E M}C 1A,$2b;if(c.1u.2D){E c.1u.dB(e)}L if(c.1u.1N||c.1u.6Q){1A=c.K.3J();$2b=$(1A).2b();if($2b.28()!==0&&$2b[0].1l==\'6i\'){E c.1u.7r(e)}L if(c.O.84()&&(1A&&1A!=\'6M\')){E c.1u.7F(e)}L{E c.1u.7r(e)}}L if(c.F.1L&&!c.1u.N){1A=c.K.3J();$2b=$(c.1u.1A).2b();if(1A!==M&&$(1A).3i(\'G-7u-2U\')){$(1A).1t();E c.1u.7F(e)}L{if($2b.1o===0&&1A===M&&1C $2b.oD!=\'1H\'){E c.1u.7F(e)}E c.1u.7r(e)}}L if(c.F.1L&&c.1u.N){3q($.X(c.1u.dk,c),1)}L if(!c.F.1L&&c.1u.N&&c.1u.N.1l!==\'4P\'){3q($.X(c.1u.ds,c),1)}L if(!c.F.1L&&!c.1u.N){E c.1u.d8(e)}}if(1m===c.3j.5T&&(e.7X||e.5S)){E c.1u.dg(e)}if(1m===c.3j.b8||e.5W&&1m===co||e.5W&&1m===cp){E c.1u.dD(e,1m)}if(1m===c.3j.7d||1m===c.3j.8C){C 1X=c.K.6Z();if(1X){C 22=1X.1o;C 3o;2v(C i=0;i<22;i++){C 4g=$(1X[i]).4g(\'1B\');if(4g.28()!==0){C 3Q=c;$.1z(4g,B(z,s){C $s=$(s);if($s.1I(\'7i\')!=\'5f\')E;3Q.1S.2o(\'bf\',s.4e,$s);3o=s})}L if(1X[i].1l==\'bj\'){if(3o!=1X[i]){c.1S.2o(\'bf\',1X[i].4e,$(1X[i]));3o=1X[i]}}}}}if(1m===c.3j.7d){c.1u.dh();c.1u.dy(e)}c.1a.1R()},dw:B(4D,1m){if(!4D&&(c.1S.69()==\'2e\'||c.1S.69()==\'4D\')){c.1S.7H(M);if(c.1u.d3(1m)){c.1Z.1K()}}},d3:B(1m){C k=c.3j;C 4B=[k.7d,k.8C,k.5T,k.cz,k.cG,k.b8,k.d5,k.d1,k.dp,k.dr];E($.3B(1m,4B)==-1)?1q:M},dm:B(4D){if(!4D)E;if((c.1S.69()==\'2e\'||c.1S.69()==\'4D\')){c.1S.7H(M);E}c.1S.7H(\'4D\')},cX:B(e,1m){if(c.1u.3S&&1m===90&&!e.5S&&!e.cZ&&c.F.1Z.1o){e.2k();c.1Z.9C();E}L if(c.1u.3S&&1m===90&&e.5S&&!e.cZ&&c.F.7m.1o!==0){e.2k();c.1Z.cB();E}L if(!c.1u.3S){if(1m==c.3j.7d||1m==c.3j.8C||(1m==c.3j.5T&&!e.7X&&!e.5S)||1m==c.3j.cz){c.1Z.1K()}}},d9:B(e,1m){if(c.1u.3S&&1m===65){c.O.hE()}L if(1m!=c.3j.dc&&!c.1u.3S){c.O.8a()}},dx:B(){C 2j=[c.1u.1N,c.1u.2D,c.1u.6Q];2v(C i=0;i<2j.1o;i++){if(2j[i]){c.1u.dz(2j[i]);E M}}},dg:B(e){c.1Z.1K();if(c.1u.1N&&c.O.84()){E c.1u.7F(e)}E c.1u.7r(e)},dD:B(e,1m){if(!c.F.dC)E 1q;if(c.O.4t(c.1a.14())&&c.F.9j===M)E 1q;e.2k();C Q;if(c.1u.2D&&!e.5S){Q=(c.F.5Z)?1d.8R(7M(c.F.5Z+1).2H(\'\\di\')):1d.8R(\'\\t\');c.1O.Q(Q);c.1a.1R()}L if(c.F.9j!==M){Q=1d.8R(7M(c.F.9j+1).2H(\'\\di\'));c.1O.Q(Q);c.1a.1R()}L{if(e.5W&&1m===cp)c.3e.8Z();L if(e.5W&&1m===co)c.3e.8S();L if(!e.5S)c.3e.8S();L c.3e.8Z()}E M},dk:B(){C 4k=c.K.47();C 95=4k.3w.I(/<br\\s?\\/?>/gi,\'\');if((4k.1l===\'8F\'||4k.1l===\'P\')&&95===\'\'&&!$(4k).3i(\'G-U\')){C br=1d.3A(\'br\');$(4k).2y(br);c.1U.bJ(br);c.1a.1R();E M}},ds:B(){C 4k=c.K.47();C 95=4k.3w.I(/<br\\s?\\/?>/gi,\'\');if(4k.1l===\'8F\'&&95===\'\'&&!$(4k).3i(\'G-U\')){C p=1d.3A(\'p\');p.3w=c.F.5M;$(4k).2y(p);c.1U.3h(p);c.1a.1R();E M}L if(c.F.dv&&4k.1l==\'P\'){$(4k).1W(\'1G\').1W(\'1n\')}},d8:B(e){e.2k();c.K.14();C p=1d.3A(\'p\');p.3w=c.F.5M;c.12.4L();c.12.49(p);c.1U.3h(p);c.1a.1R();E M},df:B(e){if(!c.O.84())E;C 52=$.3d($(c.1u.N).q());if(52.3F(/(<br\\s?\\/?>){2}$/i)!=-1){e.2k();if(c.F.1L){C br=1d.3A(\'br\');$(c.1u.1N).3u(br);c.1U.bJ(br);$(c.1u.N).q(52.I(/<br\\s?\\/?>$/i,\'\'))}L{C Q=$(c.F.7G);$(c.1u.1N).3u(Q);c.1U.3h(Q)}E 1q}E},dz:B(2F){if(!c.O.84())E;c.1Z.1K();if(c.F.1L){C 23=$(\'<1i>\').1w($.3d(c.$U.q())).23();C 3o=23.3o()[0];if(3o.1l==\'6M\'&&3o.3w===\'\'){3o=23.6e()[0]}if(c.O.5K(3o)!=c.O.5K(2F))E;C br=1d.3A(\'br\');$(2F).3u(br);c.1U.5q(br)}L{if(c.$U.23().3o()[0]!==2F)E;C Q=$(c.F.7G);$(2F).3u(Q);c.1U.3h(Q)}},dB:B(e){e.2k();C Q=1d.8R(\'\\n\');c.K.14();c.12.4L();c.12.49(Q);c.1U.5q(Q);c.1a.1R();E M},7r:B(e){E c.1u.bn(e)},7F:B(e){E c.1u.bn(e,1q)},bn:B(e,dn){e.do();c.K.14();C bz=1d.3A(\'br\');c.12.4L();c.12.49(bz);if(dn===1q){C bA=1d.3A(\'br\');c.12.49(bA);c.1U.5q(bA)}L{c.1U.5q(bz)}c.1a.1R();E M},dh:B(){C $1A=$(c.1u.1A);if($1A.1b().3F(/^\\8o$/g)===0){$1A.1t()}},dy:B(e){C $1A=$(c.1u.1A);C $1g=$(c.1u.1g);C 3K=$1A.2u(\'3K\');if(3K.28()!==0&&$1A.2u(\'li\')&&$1g.4g(\'li\').28()===1){if(!c.O.4t($1A.1b()))E;e.2k();$1A.1t();$1g.1t();c.1U.3h(3K)}}}},2m:B(){E{3r:B(e){if(c.7h)E;C 1m=e.7E;c.2m.1A=c.K.3J();c.2m.1g=c.K.5R();C $1g=c.O.4i($(c.2m.1g).1g());C dE=c.1S.2o(\'2m\',e);if(dE===M){e.2k();E M}if(!c.F.1L&&c.2m.1A.9Z==3&&c.2m.1A.1o<=1&&(c.2m.1g===M||c.2m.1g.1l==\'aY\')){c.2m.bV()}if(!c.F.1L&&$(c.2m.1g).3i(\'G-7u-2U\')&&($1g===M||$1g[0].1l==\'aY\')){$(c.2m.1g).23().3Y();c.2m.bV()}if(c.F.8A&&(c.F.75||c.F.6C||c.F.6T)&&1m===c.3j.5T){c.cb(c.F.8k,c.F.8A,c.F.75,c.F.6C,c.F.6T,c.F.6H);c.2n.2G();c.1a.1R()}if(1m===c.3j.8C||1m===c.3j.7d){c.1p.4d();if(c.2n.J){e.2k();c.J.64();c.1Z.1K();c.J.1t(c.2n.J);c.2n.J=M;E M}c.$U.1k(\'p\').1z($.X(c.O.3N,c));if(c.2m.1A&&c.2m.1A.1l==\'8F\'&&c.O.4t(c.2m.1A.3w)){if(c.F.1L){$(c.2m.1A).3u(c.K.7x());c.K.2S();$(c.2m.1A).1t()}}E c.2m.de(e)}},bV:B(){C $1A=$(c.2m.1A);C Q=$(\'<p>\').1w($1A.hu());$1A.2y(Q);C 2b=$(Q).2b();if(1C(2b[0])!==\'1H\'&&2b[0].1l==\'6i\'){2b.1t()}c.1U.41(Q)},de:B(e){C q=$.3d(c.$U.q());if(!c.O.4t(q))E;e.2k();if(c.F.1L){c.$U.q(c.K.7x());c.K.2S()}L{q=\'<p><br /></p>\';c.$U.q(q);c.2t.3h()}c.1a.1R();E M}}},1E:B(){E{2G:B(){c.F.c4=c.F.da[c.F.1E]},14:B(1f){E(1C c.F.c4[1f]!=\'1H\')?c.F.c4[1f]:\'\'}}},4r:B(){E{1O:B(){c.1Z.1K();C 1Q=c.K.3V();if(1Q[0]!==M&&c.4r.d7(1Q)){if(!c.O.26(\'2J\'))c.$U.2t();E}if(c.O.26(\'2J\')){c.4r.ay()}L{c.4r.j5()}},d7:B(1Q){C 7A=[\'li\',\'3K\',\'5U\',\'1N\',\'6Q\',\'2D\',\'dl\',\'dt\',\'dd\'];C 3z=1Q[0].1l.2P();C 3o=c.K.hb();3o=(1C 3o==\'1H\')?3z:3o.1l.2P();C c1=$.3B(3z,7A)!=-1;C ht=$.3B(3o,7A)!=-1;if((c1&&ht)||c1){E 1q}},ay:B(){c.O.7z();c.1Z.1K();c.1O.Q(1d.3A(\'hr\'));c.O.a1();c.1a.1R()},j5:B(){c.1Z.1K();C c2=\'<p id="G-1O-4r"><br /></p>\';if(c.F.1L)c2=\'<br id="G-1O-4r">\';1d.3O(\'iB\',M,\'<hr>\'+c2);c.4r.iA();c.1a.1R()},iA:B(){C Q=c.$U.1k(\'#G-1O-4r\');C 2b=$(Q).2b()[0];if(2b){c.1U.5q(Q);Q.1t()}L{Q.1W(\'id\')}}}},T:B(){E{2B:B(e){if(1C e!=\'1H\'&&e.2k)e.2k();c.V.2G(\'T\',c.1E.14(\'bq\'),lZ);c.V.cU();c.T.iz=c.V.cu(c.1E.14(\'1O\'));c.K.14();c.T.iF();c.T.iy();if(c.T.1M==\'7e\')$(\'#G-T-6R\').8P(\'8N\',1q);c.T.$8D=$(\'#G-T-2c\');c.T.$bX=$(\'#G-T-2c-1b\');c.T.$bX.2w(c.T.1b);c.T.$8D.2w(c.T.2c);c.T.iz.on(\'2e\',$.X(c.T.1O,c));$(\'.G-T-31\').1t();c.K.2R();c.V.2B();c.T.$8D.2t()},iy:B(){C iC=3Q.iD.29.I(/\\/$/i,\'\');c.T.2c=c.T.2c.I(iC,\'\');c.T.2c=c.T.2c.I(/^\\/#/,\'#\');c.T.2c=c.T.2c.I(\'bW:\',\'\');if(!c.F.8k){C 3U=1J 1T(\'^(7Y|a8|6n)://\'+3Q.iD.lw,\'i\');c.T.2c=c.T.2c.I(3U,\'\')}},iF:B(){c.T.$Q=M;C $el=$(c.K.3J()).2u(\'a\');if($el.28()!==0&&$el[0].1l===\'A\'){c.T.$Q=$el;c.T.2c=$el.Y(\'29\');c.T.1b=$el.1b();c.T.1M=$el.Y(\'1M\')}L{c.T.1b=c.2N.4I();c.T.2c=\'\';c.T.1M=\'\'}},1O:B(){C 1M=\'\';C T=c.T.$8D.2w();C 1b=c.T.$bX.2w();if($.3d(T)===\'\'){c.T.$8D.2q(\'G-3n-5r\').on(\'2m\',B(){$(c).2I(\'G-3n-5r\');$(c).3H(\'2m\')});E}if(T.3F(\'@\')!=-1&&/(7Y|a8|6n):\\/\\//i.6L(T)===M){T=\'bW:\'+T}L if(T.3F(\'#\')!==0){if($(\'#G-T-6R\').8P(\'8N\')){1M=\'7e\'}C c5=\'((lH--)?[a-8X-9]+(-[a-8X-9]+)*\\\\.)+[a-z]{2,}\';C 3U=1J 1T(\'^(7Y|a8|6n)://\'+c5,\'i\');C iE=1J 1T(\'^\'+c5,\'i\');if(T.3F(3U)==-1&&T.3F(iE)===0&&c.F.8k){T=c.F.8k+\'://\'+T}}c.T.1K(1b,T,1M);c.V.44()},1K:B(1b,T,1M){1b=$.3d(1b.I(/<|>/g,\'\'));c.K.2S();if(1b===\'\'&&T===\'\')E;if(1b===\'\'&&T!==\'\')1b=T;if(c.T.$Q){c.1Z.1K();c.T.$Q.1b(1b).Y(\'29\',T);if(1M!==\'\'){c.T.$Q.Y(\'1M\',1M)}L{c.T.$Q.1W(\'1M\')}c.1a.1R()}L{if(c.O.26(\'6P\')&&c.T.1b===\'\'){C $a=$(\'<a />\').Y(\'29\',T).1b(1b);if(1M!==\'\')$a.Y(\'1M\',1M);c.1O.Q($a);c.K.9c($a)}L{C $a;if(c.O.26(\'2J\')){$a=$(\'<a 29="\'+T+\'">\').1b(1b);if(1M!==\'\')$a.Y(\'1M\',1M);$a=$(c.1O.Q($a));c.K.9c($a)}L{1d.3O(\'lQ\',M,T);$a=$(c.K.3J()).2u(\'a\');if(1M!==\'\')$a.Y(\'1M\',1M);$a.1W(\'1n\');if(c.T.1b===\'\'){$a.1b(1b);c.K.9c($a)}}}c.1a.1R();c.1S.2o(\'lR\',$a)}3q($.X(B(){c.2n.aX()},c),5)},6h:B(e){if(1C e!=\'1H\'&&e.2k)e.2k();C 1X=c.K.6Z();if(!1X)E;c.1Z.1K();C 22=1X.1o;2v(C i=0;i<22;i++){if(1X[i].1l==\'A\'){C $Q=$(1X[i]);$Q.2y($Q.23())}}$(\'.G-T-31\').1t();c.1a.1R()}}},2T:B(){E{2M:B(4w){if(!c.O.26(\'2J\'))c.$U.2t();c.1Z.1K();c.K.2R();C 1g=c.K.5R();C $2T=$(1g).2u(\'ol, 2O\');if(!c.O.4i($2T)&&$2T.28()!==0){$2T=M}C cg,ci;C 1t=M;if($2T&&$2T.1o){1t=1q;C ce=$2T[0].1l;cg=(4w===\'54\'&&ce===\'8j\');ci=(4w===\'5z\'&&ce===\'8i\')}if(cg){c.O.4v($2T,\'ol\')}L if(ci){c.O.4v($2T,\'2O\')}L{if(1t){c.2T.1t(4w)}L{c.2T.1O(4w)}}c.K.2S();c.1a.1R()},1O:B(4w){if(c.O.26(\'2J\')&&c.F.1L){c.2T.ay(4w)}L{1d.3O(\'1O\'+4w)}C 1g=c.K.5R();C $2T=$(1g).2u(\'ol, 2O\');if(c.O.4t($2T.1k(\'li\').1b())){C $4g=$2T.4g(\'li\');$4g.1k(\'br\').1t();$4g.1w(c.K.7x())}if($2T.1o){C $6A=$2T.1g();if(c.O.4i($6A)&&$6A[0].1l!=\'4P\'&&c.O.6m($6A[0])){$6A.2y($6A.23())}}if(!c.O.26(\'2J\')){c.$U.2t()}c.1p.4d()},ay:B(4w){C 4j=c.K.5E(\'1i\');C aF=$(4j).q();C 6w=(4w==\'54\')?$(\'<ol>\'):$(\'<2O>\');C 8m=$(\'<li>\');if($.3d(aF)===\'\'){8m.1w(c.K.7x());6w.1w(8m);c.$U.1k(\'#K-2L-1\').2y(6w)}L{C 8h=aF.4E(/<br\\s?\\/?>/gi);if(8h){2v(C i=0;i<8h.1o;i++){if($.3d(8h[i])!==\'\'){6w.1w($(\'<li>\').q(8h[i]))}}}L{8m.1w(aF);6w.1w(8m)}$(4j).2y(6w)}},1t:B(4w){1d.3O(\'1O\'+4w);C $1A=$(c.K.3J());c.3e.af();if(!c.F.1L&&$1A.2u(\'li, 5U, 3K\').28()===0){1d.3O(\'a2\',M,\'p\');c.$U.1k(\'2O, ol, 1N\').1z($.X(c.O.3N,c))}C $4q=$(c.K.3J()).2u(\'4q\');C $6e=$4q.6e();if(!c.F.1L&&$4q.28()!==0&&$6e.28()!==0&&$6e[0].1l==\'6i\'){$6e.1t()}c.1p.4d()}}},V:B(){E{9h:{},ix:B(){c.F.V={im:5L()+\'<3T id="G-V-J-7T">\'+\'<3c>\'+c.1E.14(\'1F\')+\'</3c>\'+\'<3n 1c="1b" id="G-J-1F" />\'+\'<3c 1G="G-J-T-3E">\'+c.1E.14(\'T\')+\'</3c>\'+\'<3n 1c="1b" id="G-J-T" 1G="G-J-T-3E" />\'+\'<3c 1G="G-J-T-3E"><3n 1c="iq" id="G-J-T-6R"> \'+c.1E.14(\'bu\')+\'</3c>\'+\'<3c 1G="G-J-3R-3E">\'+c.1E.14(\'ik\')+\'</3c>\'+\'<6U 1G="G-J-3R-3E" id="G-J-4S">\'+\'<3E 1D="5f">\'+c.1E.14(\'5f\')+\'</3E>\'+\'<3E 1D="21">\'+c.1E.14(\'21\')+\'</3E>\'+\'<3E 1D="57">\'+c.1E.14(\'57\')+\'</3E>\'+\'<3E 1D="4c">\'+c.1E.14(\'4c\')+\'</3E>\'+\'</6U>\'+\'</3T>\',J:5L()+\'<3T id="G-V-J-1O">\'+\'<1i id="G-V-J-3P"></1i>\'+\'</3T>\',1P:5L()+\'<3T id="G-V-1P-1O">\'+\'<1i id="G-V-1P-1j-2r">\'+\'<3c>\'+c.1E.14(\'6p\')+\'</3c>\'+\'<3n 1c="1b" id="G-6p" /><br><br>\'+\'<1i id="G-V-1P-1j"></1i>\'+\'</1i>\'+\'</3T>\',T:5L()+\'<3T id="G-V-T-1O">\'+\'<3c>ip</3c>\'+\'<3n 1c="2c" id="G-T-2c" />\'+\'<3c>\'+c.1E.14(\'1b\')+\'</3c>\'+\'<3n 1c="1b" id="G-T-2c-1b" />\'+\'<3c><3n 1c="iq" id="G-T-6R"> \'+c.1E.14(\'bu\')+\'</3c>\'+\'</3T>\'};$.70(c.F,c.F.V)},bo:B(1f,2l){c.V.9h[1f]=2l},jy:B($V){c.V.$7q=$(\'<1i>\').Y(\'id\',\'G-V-7q\');$V.4N(c.V.$7q)},jA:B(id,1f,7w){C $5j=$(\'<a 29="#" 3G="5j\'+id+\'">\').1b(1f);if(7w){$5j.2q(\'7w\')}C 3Q=c;$5j.on(\'2e\',B(e){e.2k();$(\'.G-5j\').3b();$(\'.G-\'+$(c).Y(\'3G\')).2B();3Q.V.$7q.1k(\'a\').2I(\'7w\');$(c).2q(\'7w\')});c.V.$7q.1w($5j)},jH:B(1f,iv){c.F.V[1f]=iv},iT:B(1f){E c.F.V[1f]},jh:B(){E c.$9F.1k(\'3T\')},2G:B(5H,1F,2h){c.V.5H=5H;c.V.2h=2h;c.V.2f();c.V.iV();c.V.iN(1F);c.V.iQ();c.V.iM();if(1C c.V.9h[5H]!=\'1H\'){c.V.9h[5H].5X(c)}},2B:B(){1d.iJ.aD();$(1d.2x).2I(\'2x-6z\');c.V.j3=$(1d.2x).1I(\'aa\');$(1d.2x).1I(\'aa\',\'6z\');if(c.O.5Q()){c.V.cj()}L{c.V.ao()}c.$6Y.2B();c.$4o.2B();c.V.iL();c.O.7z();if(!c.O.5Q()){3q($.X(c.V.ao,c),0);$(3M).on(\'4m.G-V\',$.X(c.V.4m,c))}c.1S.2o(\'ja\',c.V.5H,c.$V);$(1d).3H(\'jd.V\');c.$V.1k(\'3n[1c=1b]\').on(\'1u.G-V\',$.X(c.V.iP,c))},ao:B(){C 3f=c.$V.jl();C 9W=$(3M).3f();C j1=$(3M).2h();if(c.V.2h>j1){c.$V.1I({2h:\'96%\',5t:(9W/2-3f/2)+\'3m\'});E}if(3f>9W){c.$V.1I({2h:c.V.2h+\'3m\',5t:\'kB\'})}L{c.$V.1I({2h:c.V.2h+\'3m\',5t:(9W/2-3f/2)+\'3m\'})}},cj:B(){c.$V.1I({2h:\'96%\',5t:\'2%\'})},4m:B(){if(c.O.5Q()){c.V.cj()}L{c.V.ao()}},iN:B(1F){c.$7y.q(1F)},iM:B(){c.$9F.q(c.V.iT(c.V.5H))},iQ:B(){if(1C $.fn.iR===\'1H\')E;c.$V.iR({iS:c.$7y});c.$7y.1I(\'nY\',\'o4\')},iP:B(e){if(e.7E!=13)E;e.2k();c.$V.1k(\'1s.G-V-6N-25\').2e()},cU:B(){C 1s=$(\'<1s>\').2q(\'G-V-25 G-V-44-25\').q(c.1E.14(\'iO\'));1s.on(\'2e\',$.X(c.V.44,c));c.$7P.1w(1s)},iK:B(3c){E c.V.cK(3c,\'8v\')},cu:B(3c){E c.V.cK(3c,\'6N\')},cK:B(3c,4u){C 1s=$(\'<1s>\').2q(\'G-V-25\').2q(\'G-V-\'+4u+\'-25\').q(3c);c.$7P.1w(1s);E 1s},iL:B(){C 3D=c.$7P.1k(\'1s\');C cl=3D.28();if(cl===0)E;3D.1I(\'2h\',(7I/cl)+\'%\')},2f:B(){c.V.iU();c.$4o=$(\'<1i id="G-V-2r" />\').3b();c.$V=$(\'<1i id="G-V" />\');c.$7y=$(\'<a9 />\');c.$7s=$(\'<1e id="G-V-44" />\').q(\'&nG;\');c.$9F=$(\'<1i id="G-V-2x" />\');c.$7P=$(\'<b3 />\');c.$V.1w(c.$7y);c.$V.1w(c.$7s);c.$V.1w(c.$9F);c.$V.1w(c.$7P);c.$4o.1w(c.$V);c.$4o.cw(1d.2x)},iU:B(){c.$6Y=$(\'<1i id="G-V-nz">\').3b();$(\'2x\').4N(c.$6Y)},iV:B(){c.$7s.on(\'2e.G-V\',$.X(c.V.44,c));$(1d).on(\'2m.G-V\',$.X(c.V.cF,c));c.$U.on(\'2m.G-V\',$.X(c.V.cF,c));c.$4o.on(\'2e.G-V\',$.X(c.V.44,c))},j2:B(){c.$7s.3H(\'2e.G-V\');$(1d).3H(\'2m.G-V\');c.$U.3H(\'2m.G-V\');c.$4o.3H(\'2e.G-V\');$(3M).3H(\'4m.G-V\')},cF:B(e){if(e.7E!=c.3j.cG)E;c.V.44(M)},44:B(e){if(e){if(!$(e.1M).3i(\'G-V-44-25\')&&e.1M!=c.$7s[0]&&e.1M!=c.$4o[0]){E}e.2k()}if(!c.$4o)E;c.V.j2();c.$6Y.1t();c.$4o.ii(\'nI\',$.X(B(){c.$4o.1t();3q($.X(c.O.a1,c),0);if(e!==1H)c.K.2S();$(1d.2x).1I(\'aa\',c.V.j3);c.1S.2o(\'nJ\',c.V.5H)},c))}}},2n:B(){E{2G:B(){c.2n.9P();c.2n.aX()},3D:B(e,2i){C 1A=c.K.3J();C 1g=c.K.5R();c.1s.j4(2i);if(e===M&&2i!==\'q\'){if($.3B(2i,c.F.9N)!=-1)c.1s.og(2i);E}$.1z(c.F.bl,$.X(B(1m,1D){C 9v=$(1g).2u(1m);C aJ=$(1A).2u(1m);if(9v.1o!==0&&!c.O.4i(9v))E;if(!c.O.4i(aJ))E;if(9v.1o!==0||aJ.2u(1m).1o!==0){c.1s.8d(1D)}},c));C $1g=$(1g).2u(c.F.7J.4I().2P());if(c.O.4i(1g)&&$1g.1o){C 4S=($1g.1I(\'1b-4S\')===\'\')?\'21\':$1g.1I(\'1b-4S\');c.1s.8d(\'4S\'+4S)}},nS:B(R,2i){c.F.9N.2W(2i);c.F.bl[R]=2i},9P:B(){c.$U.1k(\'1B\').1z($.X(B(i,1B){C $1B=$(1B);$1B.2u(\'a\').on(\'2e\',B(e){e.2k()});if(c.O.26(\'2J\'))$1B.Y(\'nP\',\'on\');c.J.j0($1B)},c));$(1d).on(\'2e.G-J-8v\',$.X(B(e){c.2n.J=M;if(e.1M.1l==\'bj\'&&c.O.4i(e.1M)){c.2n.J=(c.2n.J&&c.2n.J==e.1M)?M:e.1M}},c))},aX:B(){if(!c.F.iW)E;c.$U.1k(\'a\').on(\'68 2e\',$.X(c.2n.iX,c));c.$U.on(\'68 2e.G\',$.X(c.2n.bc,c));$(1d).on(\'68 2e.G\',$.X(c.2n.bc,c))},iY:B($T){E $T.2Q()},iX:B(e){C $T=$(e.1M);C $1g=$T.2u(\'a\');if($1g.28()!==0&&$1g[0].1l===\'A\'&&$T[0].1l!==\'A\'){$T=$1g}L if($T.28()===0||$T[0].1l!==\'A\'){E}C 2V=c.2n.iY($T);C 31=$(\'<1e 1G="G-T-31"></1e>\');C 29=$T.Y(\'29\');if(29===1H){29=\'\'}if(29.1o>24)29=29.9z(0,24)+\'...\';C iZ=$(\'<a 29="\'+$T.Y(\'29\')+\'" 1M="7e" />\').q(29).2q(\'G-T-31-6N\');C iI=$(\'<a 29="#" />\').q(c.1E.14(\'7T\')).on(\'2e\',$.X(c.T.2B,c)).2q(\'G-T-31-6N\');C ir=$(\'<a 29="#" />\').q(c.1E.14(\'6h\')).on(\'2e\',$.X(c.T.6h,c)).2q(\'G-T-31-6N\');31.1w(iZ).1w(\' | \').1w(iI).1w(\' | \').1w(ir);31.1I({2C:(2V.2C+20)+\'3m\',21:2V.21+\'3m\'});$(\'.G-T-31\').1t();$(\'2x\').1w(31)},bc:B(e){e=e.7l||e;C 1M=e.1M;C $1g=$(1M).2u(\'a\');if($1g.28()!==0&&$1g[0].1l===\'A\'&&1M.1l!==\'A\'){E}L if((1M.1l===\'A\'&&c.O.4i(1M))||$(1M).3i(\'G-T-31-6N\')){E}$(\'.G-T-31\').1t()}}},2p:B(){E{2G:B(q){if(c.F.1L)E q;if(q===\'\'||q===\'<p></p>\')E c.F.7G;c.2p.1Q=[\'4q\',\'1i\',\'2D\',\'5v\',\'2O\',\'ol\',\'h1\',\'h2\',\'h3\',\'h4\',\'h5\',\'h6\',\'dl\',\'1N\',\'6Q\',\'aH\',\'3T\',\'a9\',\'b3\',\'it\',\'iu\',\'4F\',\'1n\',\'3Z\',\'4W\',\'6U\',\'3n\',\'2E\',\'1s\',\'3E\',\'hn\',\'h8\',\'oo\',\'hr\',\'hg\',\'oq\',\'oj\',\'oA\',\'6r\',\'oz\',\'mI\',\'mK\',\'p\'];q=q+"\\n";c.2p.9t=[];c.2p.z=0;q=q.I(/(<br\\s?\\/?>){1,}\\n?<\\/1N>/gi,\'</1N>\');q=c.2p.gz(q);q=c.2p.io(q);q=c.2p.iH(q);q=c.2p.iG(q);q=c.2p.j6(q);q=c.2p.iw(q);q=q.I(1J 1T(\'<br\\\\s?/?>\\n?<(\'+c.2p.1Q.2H(\'|\')+\')(.*?[^>])>\',\'gi\'),\'<p><br /></p>\\n<$1$2>\');E $.3d(q)},gz:B(q){C $1i=$(\'<1i />\').1w(q);$1i.1k(\'1N p\').2y(B(){E $(c).1w(\'<br />\').23()});q=$1i.q();$1i.1k(c.2p.1Q.2H(\', \')).1z($.X(B(i,s){c.2p.z++;c.2p.9t[c.2p.z]=s.il;q=q.I(s.il,\'\\n{I\'+c.2p.z+\'}\')},c));E q},io:B(q){C aM=q.2d(/<!--([\\w\\W]*?)-->/gi);if(!aM)E q;$.1z(aM,$.X(B(i,s){c.2p.z++;c.2p.9t[c.2p.z]=s;q=q.I(s,\'\\n{I\'+c.2p.z+\'}\')},c));E q},iw:B(q){$.1z(c.2p.9t,B(i,s){q=q.I(\'{I\'+i+\'}\',s)});E q},iG:B(q){C 4p=q.4E(1J 1T(\'\\n\',\'g\'),-1);q=\'\';if(4p){C 22=4p.1o;2v(C i=0;i<22;i++){if(!4p.mp(i))E;if(4p[i].3F(\'{I\')==-1){4p[i]=4p[i].I(/<p>\\n\\t?<\\/p>/gi,\'\');4p[i]=4p[i].I(/<p><\\/p>/gi,\'\');if(4p[i]!==\'\'){q+=\'<p>\'+4p[i].I(/^\\n+|\\n+$/g,"")+"</p>"}}L q+=4p[i]}}E q},iH:B(q){q=q.I(/<br \\/>\\s*<br \\/>/gi,"\\n\\n");q=q.I(/<br\\s?\\/?>\\n?<br\\s?\\/?>/gi,"\\n<br /><br />");q=q.I(1J 1T("\\r\\n",\'g\'),"\\n");q=q.I(1J 1T("\\r",\'g\'),"\\n");q=q.I(1J 1T("/\\n\\n+/"),\'g\',"\\n\\n");E q},j6:B(q){q=q.I(1J 1T(\'</1N></p>\',\'gi\'),\'</1N>\');q=q.I(1J 1T(\'<p></1N>\',\'gi\'),\'</1N>\');q=q.I(1J 1T(\'<p><1N>\',\'gi\'),\'<1N>\');q=q.I(1J 1T(\'<1N></p>\',\'gi\'),\'<1N>\');q=q.I(1J 1T(\'<p><p \',\'gi\'),\'<p \');q=q.I(1J 1T(\'<p><p>\',\'gi\'),\'<p>\');q=q.I(1J 1T(\'</p></p>\',\'gi\'),\'</p>\');q=q.I(1J 1T(\'<p>\\\\s?</p>\',\'gi\'),\'\');q=q.I(1J 1T("\\n</p>",\'gi\'),\'</p>\');q=q.I(1J 1T(\'<p>\\t?\\t?\\n?<p>\',\'gi\'),\'<p>\');q=q.I(1J 1T(\'<p>\\t*</p>\',\'gi\'),\'\');E q}}},4V:B(){E{3r:B(e){if(!c.F.j8)E;c.7h=1q;c.1Z.1K();c.K.2R();c.O.7z();c.4V.j7();$(3M).on(\'6W.G-j9\',$.X(B(){$(3M).3C(c.al)},c));3q($.X(B(){C q=c.$5C.q();c.$5C.1t();c.K.2S();c.O.a1();c.4V.1O(q);$(3M).3H(\'6W.G-j9\')},c),1)},j7:B(){c.$5C=$(\'<1i>\').q(\' \').Y(\'77\',\'1q\').1I({3R:\'71\',2h:0,2C:0,21:\'-oe\'});c.$2r.1g().1w(c.$5C);c.$5C.2t()},1O:B(q){q=c.1S.2o(\'nN\',q);q=(c.O.6J())?c.1p.8B(q,M):c.1p.8B(q);q=c.1S.2o(\'4V\',q);if(c.O.6J()){c.1O.1K(q,M)}L{c.1O.q(q,M)}c.O.8a();c.7h=M;3q($.X(c.1p.4d,c),10)}}},2Y:B(){E{9b:B(){if(!c.2Y.is())E;c.$U.Y(\'2Y\',c.$2F.Y(\'2Y\'));c.2Y.2M();c.$U.on(\'2m.G-2Y\',$.X(c.2Y.2M,c))},2M:B(){C 1v=\'2I\';if(c.O.4t(c.$U.q(),M))1v=\'2q\';c.$U[1v](\'G-2Y\')},1t:B(){c.$U.2I(\'G-2Y\')},is:B(){if(c.F.2Y){E c.$2F.Y(\'2Y\',c.F.2Y)}L{E!(1C c.$2F.Y(\'2Y\')==\'1H\'||c.$2F.Y(\'2Y\')===\'\')}}}},5p:B(){E{2B:B(){$(1d.2x).1w($(\'<1i id="G-5p"><1e></1e></1i>\'));$(\'#G-5p\').nX()},3b:B(){$(\'#G-5p\').ii(nR,B(){$(c).1t()})}}},K:B(){E{14:B(){c.2N=1d.6a();if(1d.6a&&c.2N.6G&&c.2N.7R){c.12=c.2N.6G(0)}L{c.12=1d.aZ()}},4M:B(){4s{c.2N.aB()}4x(e){}c.2N.4M(c.12)},3J:B(){C el=M;c.K.14();if(c.2N&&c.2N.7R>0){el=c.2N.6G(0).nK}E c.O.4i(el)},5R:B(4z){4z=4z||c.K.3J();if(4z){E c.O.4i($(4z).1g()[0])}E M},47:B(Q){Q=Q||c.K.3J();4O(Q){if(c.O.6V(Q.1l)){E($(Q).3i(\'G-U\'))?M:Q}Q=Q.bk}E M},aS:B(1X){c.K.14();if(c.12&&c.12.4Z){E M}C ai=[];1X=(1C 1X==\'1H\')?c.K.6Z():1X;C 4C=c.F.4C;4C.2W(\'1e\');$.1z(1X,$.X(B(i,Q){if($.3B(Q.1l.2P(),4C)!=-1){ai.2W(Q)}},c));E(ai.1o===0)?M:ai},3V:B(1X){c.K.14();if(c.12&&c.12.4Z){E[c.K.47()]}C 1Q=[];1X=(1C 1X==\'1H\')?c.K.6Z():1X;$.1z(1X,$.X(B(i,Q){if(c.O.6m(Q)){c.K.hc=Q;1Q.2W(Q)}},c));E(1Q.1o===0)?[c.K.47()]:1Q},hb:B(){E c.K.hc},6Z:B(){c.K.14();C as=c.K.b9(1);C 93=c.K.b9(2);c.K.aO(c.12,as,1q);if(c.12.4Z===M){c.K.aO(c.12,93,M)}L{93=as}C 1X=[];C 8K=0;C 3Q=c;c.$U.1k(\'*\').1z(B(){if(c==as){C 1g=$(c).1g();if(1g.1o!==0&&1g[0].1l!=\'aY\'&&3Q.O.4i(1g[0])){1X.2W(1g[0])}1X.2W(c);8K=1}L{if(8K>0){1X.2W(c);8K=8K+1}}if(c==93){E M}});C b6=[];C 22=1X.1o;2v(C i=0;i<22;i++){if(1X[i].id!=\'1X-2L-1\'&&1X[i].id!=\'1X-2L-2\'){b6.2W(1X[i])}}c.K.hd();E b6},b9:B(5F){E $(\'<1e id="1X-2L-\'+5F+\'" 1G="G-1X-2L" 1h-3v="G">\'+c.F.5M+\'</1e>\')[0]},aO:B(12,Q,1c){12=12.7B();4s{12.51(1c);12.49(Q)}4x(e){}},hd:B(){$(1d).1k(\'1e.G-1X-2L\').1t();c.$U.1k(\'1e.G-1X-2L\').1t()},oF:B(2X,3I){c.1U.9o(2X,3I)},5E:B(R){c.K.14();if(c.12.4Z)E M;C 4j=1d.3A(R);4j.7S(c.12.ok());c.12.49(4j);E 4j},9c:B(Q){c.1U.1K(Q,0,Q,1)},ak:B(){c.K.14();c.12.ap(c.$U[0]);c.K.4M()},1t:B(){c.K.14();c.2N.aB()},2R:B(){c.K.he()},he:B(){c.K.14();C 5B=c.K.6d(1);c.K.aQ(c.12,5B,1q);if(c.12.4Z===M){C 83=c.K.6d(2);c.K.aQ(c.12,83,M)}c.ha=c.$U.q()},6d:B(5F){if(1C 5F==\'1H\')5F=1;E $(\'<1e id="K-2L-\'+5F+\'" 1G="G-K-2L" 1h-3v="G">\'+c.F.5M+\'</1e>\')[0]},7x:B(5F){E c.O.5K(c.K.6d(5F))},aQ:B(12,Q,1c){12=12.7B();4s{12.51(1c);12.49(Q)}4x(e){c.2t.3h()}},2S:B(){C 5B=c.$U.1k(\'1e#K-2L-1\');C 83=c.$U.1k(\'1e#K-2L-2\');if(5B.1o!==0&&83.1o!==0){c.1U.1K(5B,0,83,0)}L if(5B.1o!==0){c.1U.1K(5B,0,5B,0)}L{c.$U.2t()}c.K.aC();c.ha=M},aC:B(){c.$U.1k(\'1e.G-K-2L\').1t()},os:B(){c.K.14();E c.2N.4I()},ot:B(){C q=\'\';c.K.14();if(c.2N.7R){C b0=1d.3A(\'1i\');C 22=c.2N.7R;2v(C i=0;i<22;++i){b0.7S(c.2N.6G(i).ov())}q=b0.3w}E c.1p.b5(q)}}},5A:B(){E{3r:B(e,1m){if(!c.F.5A){if((e.7X||e.5W)&&(1m===66||1m===73))e.2k();E M}$.1z(c.F.5A,$.X(B(5l,4a){C 4B=5l.4E(\',\');C 22=4B.1o;2v(C i=0;i<22;i++){if(1C 4B[i]===\'62\'){c.5A.h9(e,$.3d(4B[i]),$.X(B(){C 1v;if(4a.1v.3F(/\\./)!=\'-1\'){1v=4a.1v.4E(\'.\');if(1C c[1v[0]]!=\'1H\'){c[1v[0]][1v[1]].87(c,4a.5w)}}L{c[4a.1v].87(c,4a.5w)}},c))}}},c))},h9:B(e,4B,h0){C gZ={8:"mJ",9:"5j",10:"E",13:"E",16:"67",17:"3S",18:"72",19:"mG",20:"mD",27:"ny",32:"2U",33:"mL",34:"mO",35:"3I",36:"mo",37:"21",38:"mm",39:"4c",40:"mt",45:"1O",46:"43",59:";",61:"=",96:"0",97:"1",98:"2",99:"3",7I:"4",mY:"5",nc:"6",na:"7",n8:"8",mE:"9",n7:"*",n6:"+",n9:"-",nb:".",n5:"/",n4:"f1",mX:"f2",mW:"f3",n3:"f4",ne:"f5",ns:"f6",nq:"f7",nu:"f8",nw:"f9",nv:"np",no:"nh",ng:"nf",ni:"nj",nm:"6W",nk:"-",mV:";",mU:"=",mu:",",mx:"-",mz:".",my:"/",ms:"`",cp:"[",mr:"\\\\",co:"]",mk:"\'"};C cr={"`":"~","1":"!","2":"@","3":"#","4":"$","5":"%","6":"^","7":"&","8":"*","9":"(","0":")","-":"5O","=":"+",";":": ","\'":"\\"",",":"<",".":">","/":"?","\\\\":"|"};4B=4B.2P().4E(" ");C 8W=gZ[e.3j],86=5L.mn(e.7E).2P(),7b="",7c={};$.1z(["72","3S","5m","67"],B(5u,8V){if(e[8V+\'mq\']&&8W!==8V){7b+=8V+\'+\'}});if(8W)7c[7b+8W]=1q;if(86){7c[7b+86]=1q;7c[7b+cr[86]]=1q;if(7b==="67+"){7c[cr[86]]=1q}}2v(C i=0,22=4B.1o;i<22;i++){if(7c[4B[i]]){e.2k();E h0.87(c,h7)}}}}},2s:B(){E{14:B(1a){if(!c.F.2s)E 1a;C cP=[\'h8\',\'2x\',\'hf\',\'hr\',\'i?mB\',\'T\',\'5m\',\'mC\',\'1n\',\'3Z\',\'4q\',\'cs\',\'cJ\',\'cT\'];C cM=[\'li\',\'dt\',\'dt\',\'h[1-6]\',\'3E\',\'3Z\'];C 80=[\'1N\',\'1i\',\'dl\',\'hg\',\'5v\',\'mF\',\'hn\',\'ol\',\'p\',\'2D\',\'6U\',\'3K\',\'5U\',\'6q\',\'2O\'];c.2s.ho=1J 1T(\'^<(/?\'+cP.2H(\'|/?\')+\'|\'+cM.2H(\'|\')+\')[ >]\');c.2s.hp=1J 1T(\'^<(br|/?\'+cP.2H(\'|/?\')+\'|/\'+cM.2H(\'|/\')+\')[ >]\');c.2s.80=1J 1T(\'^</?(\'+80.2H(\'|\')+\')[ >]\');C i=0,au=1a.1o,3y=0,2X=4f,3I=4f,R=\'\',2a=\'\',4U=\'\';c.2s.7Z=0;2v(;i<au;i++){3y=i;if(-1==1a.4Q(i).4T(\'<\')){2a+=1a.4Q(i);E c.2s.cL(2a)}4O(3y<au&&1a.5x(3y)!=\'<\'){3y++}if(i!=3y){4U=1a.4Q(i,3y-i);if(!4U.2d(/^\\s{2,}$/g)){if(\'\\n\'==2a.5x(2a.1o-1))2a+=c.2s.6u();L if(\'\\n\'==4U.5x(0)){2a+=\'\\n\'+c.2s.6u();4U=4U.I(/^\\s+/,\'\')}2a+=4U}if(4U.2d(/\\n/))2a+=\'\\n\'+c.2s.6u()}2X=3y;4O(3y<au&&\'>\'!=1a.5x(3y)){3y++}R=1a.4Q(2X,3y-2X);i=3y;C t;if(\'!--\'==R.4Q(1,3)){if(!R.2d(/--$/)){4O(\'-->\'!=1a.4Q(3y,3)){3y++}3y+=2;R=1a.4Q(2X,3y-2X);i=3y}if(\'\\n\'!=2a.5x(2a.1o-1))2a+=\'\\n\';2a+=c.2s.6u();2a+=R+\'>\\n\'}L if(\'!\'==R[1]){2a=c.2s.aA(R+\'>\',2a)}L if(\'?\'==R[1]){2a+=R+\'>\\n\'}L if(t=R.2d(/^<(3Z|1n|2D)/i)){t[1]=t[1].2P();R=c.2s.cR(R);2a=c.2s.aA(R,2a);3I=5L(1a.4Q(i+1)).2P().4T(\'</\'+t[1]);if(3I){4U=1a.4Q(i+1,3I);i+=3I;2a+=4U}}L{R=c.2s.cR(R);2a=c.2s.aA(R,2a)}}E c.2s.cL(2a)},6u:B(){C s=\'\';2v(C j=0;j<c.2s.7Z;j++){s+=\'\\t\'}E s},cL:B(1a){1a=1a.I(/\\n\\s*\\n/g,\'\\n\');1a=1a.I(/^[\\s\\n]*/,\'\');1a=1a.I(/[\\s\\n]*$/,\'\');1a=1a.I(/<3Z(.*?)>\\n<\\/3Z>/gi,\'<3Z$1></3Z>\');c.2s.7Z=0;E 1a},cR:B(R){C 7O=\'\';R=R.I(/\\n/g,\' \');R=R.I(/\\s{2,}/g,\' \');R=R.I(/^\\s+|\\s+$/g,\' \');C cW=\'\';if(R.2d(/\\/$/)){cW=\'/\';R=R.I(/\\/+$/,\'\')}C m;4O(m=/\\s*([^= ]+)(?:=(([\'"\']).*?\\3|[^ ]+))?/.4K(R)){if(m[2])7O+=m[1].2P()+\'=\'+m[2];L if(m[1])7O+=m[1].2P();7O+=\' \';R=R.4Q(m[0].1o)}E 7O.I(/\\s*$/,\'\')+cW+\'>\'},aA:B(R,2a){C nl=R.2d(c.2s.80);if(R.2d(c.2s.ho)||nl){2a=2a.I(/\\s*$/,\'\');2a+=\'\\n\'}if(nl&&\'/\'==R.5x(1))c.2s.7Z--;if(\'\\n\'==2a.5x(2a.1o-1))2a+=c.2s.6u();if(nl&&\'/\'!=R.5x(1))c.2s.7Z++;2a+=R;if(R.2d(c.2s.hp)||R.2d(c.2s.80)){2a=2a.I(/ *$/,\'\');2a+=\'\\n\'}E 2a}}},1x:B(){E{hq:B(){if(c.F.4R)c.F.4G=M;if(c.F.58)c.F.1W=M;if(c.F.1L)E;C 2j=[\'p\',\'3T\'];if(c.F.4R)c.1x.hm(2j);if(c.F.4G)c.1x.hl(2j)},hm:B(2j){C 22=2j.1o;2v(C i=0;i<22;i++){if($.3B(2j[i],c.F.4R)==-1){c.F.4R.2W(2j[i])}}},hl:B(2j){C 22=2j.1o;2v(C i=0;i<22;i++){C 2V=$.3B(2j[i],c.F.4G);if(2V!=-1){c.F.4G.ah(2V,1)}}},2G:B(q,3L){c.1x.2g={4G:c.F.4G,4R:c.F.4R,6k:c.F.6k,56:c.F.56,55:c.F.55,5b:c.F.5b,1W:c.F.1W,58:c.F.58,6j:c.F.6j,3N:c.F.3N};$.70(c.1x.2g,3L);q=c.1x.6k(q);c.1x.$1i=$(\'<1i />\').1w(q);c.1x.56();c.1x.55();c.1x.hh();c.1x.1W();c.1x.3N();c.1x.hj();c.1x.5b();c.1x.6j();q=c.1x.$1i.q();c.1x.$1i.1t();E q},6k:B(q){if(!c.1x.2g.6k)E q;E q.I(/<!--[\\s\\S]*?-->/gi,\'\')},56:B(q){if(!c.1x.2g.56)E q;C 22=c.1x.2g.56.1o;C 5e=[],bI=[];2v(C i=0;i<22;i++){bI.2W(c.1x.2g.56[i][1]);5e.2W(c.1x.2g.56[i][0])}c.1x.$1i.1k(5e.2H(\',\')).1z($.X(B(n,s){C R=bI[n];$(s).2y(B(){C 82=$(\'<\'+R+\' />\').1w($(c).23());2v(C i=0;i<c.42.1o;i++){82.Y(c.42[i].1f,c.42[i].1D)}E 82})},c));E q},55:B(){if(!c.1x.2g.55)E;C 22=c.1x.2g.55.1o;c.1x.$1i.1k(\'1e\').1z($.X(B(n,s){C $el=$(s);C 1n=$el.Y(\'1n\');2v(C i=0;i<22;i++){if(1n&&1n.2d(1J 1T(\'^\'+c.1x.2g.55[i][0],\'i\'))){C 1l=c.1x.2g.55[i][1];$el.2y(B(){C R=1d.3A(1l);E $(R).1w($(c).23())})}}},c))},hh:B(){if(!c.1x.2g.4G&&c.1x.2g.4R){c.1x.$1i.1k(\'*\').6o(c.1x.2g.4R.2H(\',\')).1z(B(i,s){if(s.3w===\'\')$(s).1t();L $(s).23().3Y()})}if(c.1x.2g.4G){c.1x.$1i.1k(c.1x.2g.4G.2H(\',\')).1z(B(i,s){if(s.3w===\'\')$(s).1t();L $(s).23().3Y()})}},1W:B(){C 22;if(!c.1x.2g.1W&&c.1x.2g.58){C bD=[],bE=[];22=c.1x.2g.58.1o;2v(C i=0;i<22;i++){bD.2W(c.1x.2g.58[i][0]);bE.2W(c.1x.2g.58[i][1])}c.1x.$1i.1k(\'*\').1z($.X(B(n,s){C $el=$(s);C 2V=$.3B($el[0].1l.2P(),bD);C 5d=c.1x.hi(2V,bE,$el);if(5d){$.1z(5d,B(z,f){$el.1W(f)})}},c))}if(c.1x.2g.1W){22=c.1x.2g.1W.1o;2v(C i=0;i<22;i++){C 85=c.1x.2g.1W[i][1];if($.an(85))85=85.2H(\' \');c.1x.$1i.1k(c.1x.2g.1W[i][0]).1W(85)}}},hi:B(2V,5a,$el){C 5d=[];if(2V==-1){$.1z($el[0].42,B(i,3g){5d.2W(3g.1f)})}L if(5a[2V]==\'*\'){5d=[]}L{$.1z($el[0].42,B(i,3g){if($.an(5a[2V])){if($.3B(3g.1f,5a[2V])==-1){5d.2W(3g.1f)}}L if(5a[2V]!=3g.1f){5d.2W(3g.1f)}})}E 5d},hk:B(el,6X){6X=1J 1T(6X,"g");E el.1z(B(){C 3Q=$(c);C 22=c.42.1o-1;2v(C i=22;i>=0;i--){C 3g=c.42[i];if(3g&&3g.ou&&3g.1f.3F(6X)>=0){3Q.1W(3g.1f)}}})},3N:B(){if(!c.1x.2g.3N)E;c.1x.$1i.1k(c.1x.2g.3N.2H(\',\')).1z(B(){C $el=$(c);C 1b=$el.1b();1b=1b.I(/[\\8o-\\aE\\aq]/g,\'\');1b=1b.I(/&53;/gi,\'\');1b=1b.I(/\\s/g,\'\');if(1b===\'\'&&$el.4g().1o===0){$el.1t()}})},hj:B(){c.1x.$1i.1k(\'li p\').23().3Y()},5b:B(){if(!c.1x.2g.5b)E;C 2j=c.1x.2g.5b;if($.an(c.1x.2g.5b))2j=c.1x.2g.5b.2H(\',\');c.1x.hk(c.1x.$1i.1k(2j),\'^(1h-)\')},6j:B(){if(!c.1x.2g.6j)E;c.1x.$1i.1k(c.1x.2g.6j.2H(\',\')).1z(B(){if(c.42.1o===0){$(c).23().3Y()}})}}},1r:B(){E{3r:B(){E{q:{1F:c.1E.14(\'q\'),1v:\'1a.2M\'},2K:{1F:c.1E.14(\'2K\'),1y:{p:{1F:c.1E.14(\'gY\'),1v:\'N.2Z\'},1N:{1F:c.1E.14(\'bO\'),1v:\'N.2Z\'},2D:{1F:c.1E.14(\'1a\'),1v:\'N.2Z\'},h1:{1F:c.1E.14(\'gX\'),1v:\'N.2Z\'},h2:{1F:c.1E.14(\'gH\'),1v:\'N.2Z\'},h3:{1F:c.1E.14(\'gI\'),1v:\'N.2Z\'},h4:{1F:c.1E.14(\'gJ\'),1v:\'N.2Z\'},h5:{1F:c.1E.14(\'gK\'),1v:\'N.2Z\'}}},3W:{1F:c.1E.14(\'3W\'),1v:\'1V.2Z\'},3X:{1F:c.1E.14(\'3X\'),1v:\'1V.2Z\'},5I:{1F:c.1E.14(\'5I\'),1v:\'1V.2Z\'},5c:{1F:c.1E.14(\'5c\'),1v:\'1V.2Z\'},5z:{1F:\'&oC; \'+c.1E.14(\'5z\'),1v:\'2T.2M\'},54:{1F:\'1. \'+c.1E.14(\'54\'),1v:\'2T.2M\'},6O:{1F:\'< \'+c.1E.14(\'6O\'),1v:\'3e.8Z\'},3e:{1F:\'> \'+c.1E.14(\'3e\'),1v:\'3e.8S\'},J:{1F:c.1E.14(\'J\'),1v:\'J.2B\'},1P:{1F:c.1E.14(\'1P\'),1v:\'1P.2B\'},T:{1F:c.1E.14(\'T\'),1y:{T:{1F:c.1E.14(\'bq\'),1v:\'T.2B\'},6h:{1F:c.1E.14(\'6h\'),1v:\'T.6h\'}}},3t:{1F:c.1E.14(\'3t\'),1y:{21:{1F:c.1E.14(\'gG\'),1v:\'3t.21\'},57:{1F:c.1E.14(\'gF\'),1v:\'3t.57\'},4c:{1F:c.1E.14(\'gB\'),1v:\'3t.4c\'},8g:{1F:c.1E.14(\'gA\'),1v:\'3t.8g\'}}},9q:{1F:c.1E.14(\'9q\'),1v:\'4r.1O\'}}},2f:B(){c.1r.gR();c.1r.gN();c.1r.gW();if(c.F.3D.1o===0)E;c.$1r=c.1r.gD();c.1r.gU();c.1r.1w();c.1r.gE();c.1r.gL();c.1r.gM();if(c.F.9N){c.$U.on(\'gC.G 2m.G 2t.G\',$.X(c.2n.3D,c))}},gD:B(){E $(\'<2O>\').2q(\'G-1r\').Y(\'id\',\'G-1r-\'+c.8J)},gE:B(){$.1z(c.F.1r.2K.1y,$.X(B(i,s){if($.3B(i,c.F.2K)==-1)8v c.F.1r.2K.1y[i]},c))},gL:B(){$.1z(c.F.3D,$.X(B(i,2i){if(!c.F.1r[2i])E;if(c.F.8t===M&&2i===\'1P\')E 1q;if((c.F.8s===M&&c.F.8u===M)&&2i===\'J\')E 1q;C 3k=c.F.1r[2i];c.$1r.1w($(\'<li>\').1w(c.1s.2f(2i,3k)))},c))},1w:B(){if(c.F.aj){c.$1r.2q(\'G-1r-nO\');$(c.F.aj).q(c.$1r)}L{c.$2r.4N(c.$1r)}},gM:B(){if(c.O.5Q())E;if(c.F.aj)E;if(!c.F.gT)E;c.1r.ca();$(c.F.6v).on(\'6W.G\',$.X(c.1r.ca,c))},gU:B(){if(c.O.5Q()&&c.F.gV){c.$1r.2q(\'G-1r-aa\')}},gW:B(){if(c.F.gS)E;C 5u=c.F.3D.4T(\'q\');if(5u!==-1){c.F.3D.ah(5u,1)}},gR:B(){if(c.F.bQ.1o===0)E;$.1z(c.F.bQ,$.X(B(i,s){C 5u=c.F.3D.4T(s);c.F.3D.ah(5u,1)},c))},gN:B(){if(!c.O.5Q()||c.F.bR.1o===0)E;$.1z(c.F.bR,$.X(B(i,s){C 5u=c.F.3D.4T(s);c.F.3D.ah(5u,1)},c))},ca:B(){C 3C=$(c.F.6v).3C();C 6l=1;if(c.F.6v===1d){6l=c.$2r.2Q().2C}if(3C>6l){c.1r.gO(3C,6l)}L{c.1r.gP()}},gO:B(3C,6l){C 2C=c.F.6y+3C-6l;C 21=0;C 3I=6l+c.$2r.3f()+30;C 2h=c.$2r.a0();c.$1r.2q(\'1r-71-2r\');c.$1r.1I({3R:\'8H\',2h:2h,2C:2C+\'3m\',21:21});c.1r.ij();c.$1r.1I(\'gQ\',(3C<3I)?\'hs\':\'6z\')},gP:B(){c.$1r.1I({3R:\'nC\',2h:\'a3\',2C:0,21:0,gQ:\'hs\'});c.1r.hY();c.$1r.2I(\'1r-71-2r\')},ij:B(){C 2C=c.$1r.5G()+c.F.6y;C 3R=\'71\';if(c.F.6v!==1d){2C=(c.$1r.5G()+c.$1r.2Q().2C)+c.F.6y;3R=\'8H\'}$(\'.G-1y\').1z(B(){$(c).1I({3R:3R,2C:2C+\'3m\'})})},hY:B(){C 2C=(c.$1r.5G()+c.$1r.2Q().2C);$(\'.G-1y\').1z(B(){$(c).1I({3R:\'8H\',2C:2C+\'3m\'})})}}},1j:B(){E{3r:B(id,2c,2l){c.1j.4H=M;c.1j.2l=2l;c.1j.2c=2c;c.1j.$el=$(id);c.1j.$3P=$(\'<1i id="G-3P" />\');c.1j.$ch=$(\'<1i id="G-3P-2Y" />\').1b(\'hZ 1P i0 or \');c.1j.$3n=$(\'<3n 1c="1P" 1f="1P" />\');c.1j.$ch.1w(c.1j.$3n);c.1j.$3P.1w(c.1j.$ch);c.1j.$el.1w(c.1j.$3P);c.1j.$3P.3H(\'G.1j\');c.1j.$3n.3H(\'G.1j\');c.1j.$3P.on(\'nU.G.1j\',$.X(c.1j.9H,c));c.1j.$3P.on(\'o8.G.1j\',$.X(c.1j.i3,c));c.1j.$3n.on(\'i1.G.1j\',$.X(B(e){e=e.7l||e;c.1j.9k(c.1j.$3n[0].5D[0],e)},c));c.1j.$3P.on(\'4A.G.1j\',$.X(B(e){e.2k();c.1j.$3P.2I(\'79-bY\').2q(\'79-4A\');c.1j.9U(e)},c))},hX:B(1P,e){c.1j.4H=1q;c.1j.9k(1P,e)},9U:B(e){e=e.7l||e;C 5D=e.9d.5D;c.1j.9k(5D[0],e)},9k:B(1P,e){if(c.F.8u){c.1j.c6(1P);c.1j.ia(1P);E}C 4h=!!3M.9i?1J 9i():4f;if(3M.9i){c.1j.c6(1P);C 1f=(c.1j.1c==\'J\')?c.F.hW:c.F.hS;4h.1w(1f,1P)}c.5p.2B();c.1j.hV(4h,e)},c6:B(1P){c.1j.hT(1P);if(c.1j.4H){c.1j.2c=(c.1j.1c==\'J\')?c.F.8s:c.F.8t;c.1j.2l=(c.1j.1c==\'J\')?c.J.1O:c.1P.1O}},hT:B(1P){c.1j.1c=\'J\';if(c.F.hU.4T(1P.1c)==-1){c.1j.1c=\'1P\'}},8E:B(6K,fd){if(6K===M||1C 6K!==\'4F\')E fd;$.1z(6K,$.X(B(k,v){if(v!==4f&&v.4I().4T(\'#\')===0)v=$(v).2w();fd.1w(k,v)},c));E fd},hV:B(4h,e){if(c.1j.1c==\'J\'){4h=c.1j.8E(c.F.nZ,4h);4h=c.1j.8E(c.1j.9S,4h)}L{4h=c.1j.8E(c.F.o0,4h);4h=c.1j.8E(c.1j.9E,4h)}C 2A=1J by();2A.ac(\'o3\',c.1j.2c);2A.i9=$.X(B(){if(2A.cS==4){C 1h=2A.i4;1h=1h.I(/^\\[/,\'\');1h=1h.I(/\\]$/,\'\');C 2z;4s{2z=(1C 1h===\'62\'?$.i2(1h):1h)}4x(ke){2z={5r:1q}}c.5p.3b();if(!c.1j.4H){c.1j.$3P.2I(\'79-4A\')}c.1j.2l(2z,c.1j.4H,e)}},c);2A.cc(4h)},9H:B(e){e.2k();c.1j.$3P.2q(\'79-bY\')},i3:B(e){e.2k();c.1j.$3P.2I(\'79-bY\')},k2:B(){c.1j.9S={}},k1:B(1f,1D){c.1j.9S[1f]=1D},kh:B(1f){8v c.1j.9S[1f]},ki:B(){c.1j.9E={}},kv:B(1f,1D){c.1j.9E[1f]=1D},kz:B(1f){8v c.1j.9E[1f]},ia:B(1P){c.1j.ic(1P,$.X(B(ib){c.1j.i6(1P,ib)},c))},ic:B(1P,2l){C 2A=1J by();C 6s=\'?\';if(c.F.8u.3F(/\\?/)!=\'-1\')6s=\'&\';2A.ac(\'kC\',c.F.8u+6s+\'1f=\'+1P.1f+\'&1c=\'+1P.1c,1q);if(2A.ih)2A.ih(\'1b/km; ko=x-kq-jT\');C i8=c;2A.i9=B(e){if(c.cS==4&&c.c0==9D){i8.5p.2B();2l(jj(c.i4))}L if(c.cS==4&&c.c0!=9D){}};2A.cc()},i7:B(ae,2c){C 2A=1J by();if("jb"in 2A){2A.ac(ae,2c,1q)}L if(1C i5!="1H"){2A=1J i5();2A.ac(ae,2c)}L{2A=4f}E 2A},i6:B(1P,2c){C 2A=c.1j.i7(\'jg\',2c);if(!2A){}L{2A.jr=$.X(B(){if(2A.c0==9D){c.5p.3b();C 9K=2c.4E(\'?\');if(!9K[0]){E M}if(!c.1j.4H){c.1j.$3P.2I(\'79-4A\')}C 2z={8z:9K[0]};if(c.1j.1c==\'1P\'){C 3a=9K[0].4E(\'/\');2z.6p=3a[3a.1o-1]}c.1j.2l(2z,c.1j.4H,M)}L{}},c);2A.jv=B(){};2A.1j.jJ=B(e){};2A.hR(\'jN-jO\',1P.1c);2A.hR(\'x-jR-jQ\',\'jP-jI\');2A.cc(1P)}}}},O:B(){E{5Q:B(){E/(hQ|hA|hB|hC)/.6L(92.8Q)},c8:B(){E!/(hQ|hA|jz|hB|hC)/.6L(92.8Q)},jx:B(6K){E hD.5k.4I.5X(6K)==\'[4F 5L]\'},4t:B(q,hz){q=q.I(/[\\8o-\\aE\\aq]/g,\'\');q=q.I(/&53;/gi,\'\');q=q.I(/<\\/?br\\s?\\/?>/g,\'\');q=q.I(/\\s/g,\'\');q=q.I(/^<p>[^\\W\\w\\D\\d]*?<\\/p>$/i,\'\');if(hz!==M){q=q.I(/<[^\\/>][^>]*><\\/[^>]+>/gi,\'\');q=q.I(/<[^\\/>][^>]*><\\/[^>]+>/gi,\'\')}q=$.3d(q);E q===\'\'},bv:B(5l){if(1C(5l)===\'1H\')E 0;E 6D(5l.I(\'3m\',\'\'),10)},jG:B(6g){if(1C 6g==\'1H\')E;if(6g.3F(/^#/)==-1)E 6g;C hy=/^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i;6g=6g.I(hy,B(m,r,g,b){E r+r+g+g+b+b});C 9T=/^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.4K(6g);E\'kG(\'+6D(9T[1],16)+\', \'+6D(9T[2],16)+\', \'+6D(9T[3],16)+\')\'},5K:B(el){E $(\'<1i>\').1w($(el).eq(0).hu()).q()},9e:B(el){if($.3B(el.1l,c.F.7J)!==-1){E $(el)}L{E $(el).2u(c.F.7J.4I().2P(),c.$U[0])}},5J:B(el,Y){C $el=$(el);if(1C $el.Y(Y)==\'1H\'){E 1q}if($el.Y(Y)===\'\'){$el.1W(Y);E 1q}E M},3N:B(i,s){C $s=$(s);$s.1k(\'.G-7u-2U\').1W(\'1n\').1W(\'1G\');if($s.1k(\'hr, br, 1B, 4W\').1o!==0)E;C 1b=$.3d($s.1b());if(c.O.4t(1b,M)){$s.1t()}},7z:B(){if(c.O.6J())E;c.hv=c.$U.3C();c.al=$(3M).3C();if(c.F.7p)c.hw=$(c.F.7p).3C()},a1:B(){if(1C c.7z===\'1H\'&&1C c.al===\'1H\')E;$(3M).3C(c.al);c.$U.3C(c.hv);if(c.F.7p)$(c.F.7p).3C(c.hw)},9X:B(){C 2U=1d.3A(\'1e\');2U.4u=\'G-7u-2U\';2U.3w=c.F.5M;E 2U},4J:B(Q){C 2j=c.F.4C;2j.2W(\'1e\');if(Q.1l==\'ad\')2j.2W(\'a\');$(Q).1k(2j.2H(\',\')).6o(\'1e.G-K-2L\').23().3Y()},5N:B(Q,4J){C 3Q=c;$(Q).2y(B(){if(4J===1q)3Q.O.4J(c);E $(c).23()})},4v:B(Q,R,4J){C 5e;C 3Q=c;$(Q).2y(B(){5e=$(\'<\'+R+\' />\').1w($(c).23());2v(C i=0;i<c.42.1o;i++){5e.Y(c.42[i].1f,c.42[i].1D)}if(4J===1q)3Q.O.4J(5e);E 5e});E 5e},lP:B(){C N=c.K.47();if(!N)E M;C 2Q=c.1U.bF(N);E(2Q===0)?1q:M},84:B(){C N=c.K.47();if(!N)E M;C 2Q=c.1U.bF(N);C 1b=$.3d($(N).1b()).I(/\\n\\r\\n/g,\'\');E(2Q==1b.1o)?1q:M},6m:B(N){N=N[0]||N;E N&&c.O.6V(N.1l)},6V:B(R){if(1C R==\'1H\')E M;E c.hx.6L(R)},9Y:B(1A,R){C 2F=$(1A).2u(R);if(2F.28()==1){E 2F[0]}E M},6J:B(){E c.ak},hE:B(){c.ak=1q},8a:B(){c.ak=M},4i:B(el){if(!el){E M}if($(el).hF(\'.G-U\').1o===0||$(el).3i(\'G-U\')){E M}E el},5g:B(1l){C 1g=c.K.5R();C 1A=c.K.3J();if($.an(1l)){C cO=0;$.1z(1l,$.X(B(i,s){if(c.O.cQ(1A,1g,s)){cO++}},c));E(cO===0)?M:1q}L{E c.O.cQ(1A,1g,1l)}},cQ:B(1A,1g,1l){E 1g&&1g.1l===1l?1g:1A&&1A.1l===1l?1A:M},lz:B(){E(c.O.26(\'2J\')&&6D(c.O.26(\'9O\'),10)<9)?1q:M},ly:B(){E(c.O.26(\'2J\')&&6D(c.O.26(\'9O\'),10)<10)?1q:M},hM:B(){E!!92.8Q.2d(/lx\\/7\\./)},26:B(26){C 4y=92.8Q.2P();C 2d=/(hO)[\\/]([\\w.]+)/.4K(4y)||/(hN)[ \\/]([\\w.]+)/.4K(4y)||/(7g)[ \\/]([\\w.]+).*(lC)[ \\/]([\\w.]+)/.4K(4y)||/(7g)[ \\/]([\\w.]+)/.4K(4y)||/(lF)(?:.*9O|)[ \\/]([\\w.]+)/.4K(4y)||/(2J) ([\\w.]+)/.4K(4y)||4y.4T("lE")>=0&&/(bg)(?::| )([\\w.]+)/.4K(4y)||4y.4T("lD")<0&&/(6P)(?:.*? bg:([\\w.]+)|)/.4K(4y)||[];if(26==\'9O\')E 2d[2];if(26==\'7g\')E(2d[1]==\'hN\'||2d[1]==\'7g\');if(2d[1]==\'bg\')E 26==\'2J\';if(2d[1]==\'hO\')E 26==\'7g\';E 26==2d[1]}}}};3l.5k.3r.5k=3l.5k;$.3l.fn.cb=B(cf,8A,75,6C,6T,6H){C hP=\'((?:7Y[s]?:\\\\/\\\\/(?:9a\\\\.)?|9a\\\\.){1}(?:[0-9A-6b-z\\\\-%5O]+\\\\.)+[a-md-Z]{2,}(?::[0-9]+)?(?:(?:/[0-9A-6b-z\\\\-\\\\.%\\+5O]*)+)?(?:\\\\?(?:[0-9A-6b-z\\\\-\\\\.%5O]+(?:=[0-9A-6b-z\\\\-\\\\.%5O\\\\+]*)?)?(?:&(?:[0-9A-6b-z\\\\-\\\\.%5O]+(?:=[0-9A-6b-z\\\\-\\\\.%5O\\\\+]*)?)?)*)?(?:#[0-9A-6b-z\\\\-\\\\.%5O\\\\+=\\\\?&;]*)?)\';C 6X=1J 1T(hP,\'gi\');C hJ=/(6n?|a8):\\/\\//i;C ba=/(6n?:\\/\\/.*\\.(?:hL|lX|hK|hG))/gi;C aw=(c.$U?c.$U[0]:c).aw,i=aw.1o;4O(i--){C n=aw[i];if(n.9Z===3){C q=n.9g;if(6T&&q){C aW=\'<4W 2h="kZ" 3f="l2" 4e="\',aK=\'" kH="0" kN></4W>\';if(q.2d(bh)){q=q.I(bh,aW+\'//9a.hH.9R/7f/$1\'+aK);$(n).3u(q).1t()}L if(q.2d(aU)){q=q.I(aU,aW+\'//ll.hI.9R/6t/$2\'+aK);$(n).3u(q).1t()}}if(6C&&q&&q.2d(ba)){q=q.I(ba,\'<1B 4e="$1" />\');$(n).3u(q).1t();E}if(q.3F(/\\$/g)!=-1)q=q.I(/\\$/g,\'$\');C 4l=q.2d(6X);if(75&&q&&4l){C 22=4l.1o;2v(C z=0;z<22;z++){if(4l[z].2d(/\\.$/)!==4f)4l[z]=4l[z].I(/\\.$/,\'\');C 29=4l[z];C 1b=29;C 2U=\'\';if(29.2d(/\\s$/)!==4f)2U=\' \';C bm=cf+\'://\';if(29.2d(hJ)!==4f)bm=\'\';if(1b.1o>6H)1b=1b.9z(0,6H)+\'...\';1b=1b.I(/$/g,\'$\').I(/&/g,\'&cE;\').I(/</g,\'<\').I(/>/g,\'>\');q=q.I(29,\'<a 29=\\"\'+bm+$.3d(29)+\'\\">\'+$.3d(1b)+\'</a>\'+2U)}$(n).3u(q).1t()}}L if(n.9Z===1&&!/^(a|1s|2E)$/i.6L(n.1l)){$.3l.fn.cb.5X(n,cf,8A,75,6C,6T,6H)}}}})(mH);',62,1530,'||||||||||||this||||||||||||||html|||||||||||function|var||return|opts|redactor||replace|image|selection|else|false|block|utils||node|tag||link|editor|modal||proxy|attr||||range||get||||||code|text|type|document|span|name|parent|data|div|upload|find|tagName|key|style|length|clean|true|toolbar|button|remove|keydown|func|append|tidy|dropdown|each|current|img|typeof|value|lang|title|class|undefined|css|new|set|linebreaks|target|blockquote|insert|file|blocks|sync|core|RegExp|caret|inline|removeAttr|nodes|formatted|buffer||left|len|contents||btn|browser||size|href|out|next|url|match|click|build|settings|width|btnName|tags|preventDefault|callback|keyup|observe|setCallback|paragraphize|addClass|box|tabifier|focus|closest|for|val|body|replaceWith|json|xhr|show|top|pre|textarea|element|load|join|removeClass|msie|formatting|marker|toggle|sel|ul|toLowerCase|offset|save|restore|list|space|pos|push|start|placeholder|format||tooltip|||||||||arr|hide|label|trim|indent|height|item|setStart|hasClass|keyCode|btnObject|Redactor|px|input|last|font|setTimeout|init|imageBox|alignment|after|verified|innerHTML|autosave|point|first|createElement|inArray|scrollTop|buttons|option|search|rel|off|end|getCurrent|td|options|window|removeEmpty|execCommand|droparea|self|position|ctrl|section|re|getBlocks|bold|italic|unwrap|script||setEnd|attributes|del|close|||getBlock|margin|insertNode|command|resizeHandle|right|clearUnverified|src|null|children|formData|isRedactorParent|wrapper|blockElem|matches|resize|orgn|modalBox|htmls|table|line|try|isEmpty|className|replaceToTag|cmd|catch|ua|elem|drop|keys|inlineTags|arrow|split|object|deniedTags|direct|toString|removeInlineTags|exec|deleteContents|addRange|prepend|while|LI|substr|allowedTags|align|indexOf|cont|paste|iframe|frag|lastNode|collapsed||collapse|tmp|nbsp|orderedlist|replaceStyles|replaceTags|center|allowedAttr||allowed|removeDataAttr|underline|attributesRemove|replacement|none|isCurrentOrParent|editter|strong|tab|prototype|str|meta|isFunction|toggleType|progress|setAfter|error|methods|marginTop|index|form|params|charAt|module|unorderedlist|shortcuts|node1|pasteBox|files|wrap|num|innerHeight|templateName|deleted|removeEmptyAttr|getOuterHtml|String|invisibleSpace|replaceWithContents|_|containerTag|isMobile|getParent|shiftKey|ENTER|th|instance|metaKey|call|child|preSpaces|||string|visual|hideResize|||shift|touchstart|getEvent|getSelection|Za|Insert|getMarker|prev|display|hex|unlink|BR|removeWithoutAttr|removeComments|boxTop|isBlock|https|not|filename|tr|figure|mark|video|getTabs|toolbarFixedTarget|tmpList|break|toolbarFixedTopOffset|hidden|listParent|setVerified|convertImageLinks|parseInt|weight|focn|getRangeAt|linkSize|endRange|isSelectAll|obj|test|SPAN|action|outdent|mozilla|figcaption|blank|replaceDivs|convertVideoLinks|select|isBlockTag|scroll|regex|modalOverlay|getNodes|extend|fixed|alt||sup|convertUrlLinks|decoration|contenteditable|dropact|drag|sub|modif|possible|BACKSPACE|_blank|embed|webkit|rtePaste|float|blocksSize|TD|originalEvent|rebuffer|resizer|Delete|scrollTarget|tabber|insertBreakLine|modalClose|plugins|invisible|keyPosition|active|getMarkerAsHtml|modalHeader|saveScroll|exceptTags|cloneRange|targetTouches|act|which|insertDblBreakLine|emptyHtml|addEvent|100|alignmentTags|autosaveInterval|focusNode|Array|tagblock|tagout|modalFooter|case|rangeCount|appendChild|edit|Add|inserted|classSize|ctrlKey|http|cleanlevel|newLevel|strike|replaced|node2|isEndOfElement|attrs|character|apply|imageMargin|Header|disableSelectAll|imageFloatMargin|linkmarker|setActive|imageResizer|isRemoveInline|justify|items|OL|UL|linkProtocol|small|tmpLi|setMode|u200B|param|audio|cite|imageUpload|fileUpload|s3|delete|disabled|icon|tabindex|filelink|convertLinks|onPaste|DELETE|inputUrl|getHiddenFields|DIV|blockLevelElements|absolute|singleLine|uuid|counter|BLOCKQUOTE|isContainerTable|checked|isTextarea|prop|userAgent|createTextNode|increase|getPlainText|caretRangeFromPoint|specialKey|special|z0|caretPositionFromPoint|decrease|||navigator|endNode|toggleClass|blockHtml|||||www|enable|selectElement|dataTransfer|getAlignmentElement|property|nodeValue|callbacks|FormData|tabAsSpaces|traverseFile|onClick|createTextRange|classname|setOffset|parHtml|horizontalrule|modules|imageFloat|safes|pageY|parentEl|marginLeft|marginRight|marginBottom|substring||bind|undo|200|fileFields|modalBody|moveToPoint|onDrag|indentValue|maxHeight|s3file|preCaretRange|hideAll|activeButtons|version|images|cloned|com|imageFields|result|onDrop|samp|windowHeight|createSpaceElement|isTag|nodeType|innerWidth|restoreScroll|formatblock|auto|getOffset|kbd|normalizeLists|formatWrap|ftp|header|overflow|formatListToBlockquote|open|PRE|method|fixEmptyIndent|the|splice|inlines|toolbarExternal|selectAll|saveBodyScroll|replaceParagraphsToBr|isArray|showOnDesktop|selectNodeContents|uFEFF|RedactorPlugins|startNode|matchContainers|codeLength|minHeight|childNodes|onPasteTidy|insertInIe|source|placeTag|removeAllRanges|removeMarkers|blur|u200D|wrapperHtml|methodVal|address|before|currentEl|iframeEnd|TH|commentsMatches|imageResizable|setNodesMarker|isP|setMarker|firstChild|getInlines|autosaveOnChange|reUrlVimeo|htmlIe|iframeStart|links|BODY|createRange|container|setFormat|nodeToCaretPositionFromPoint|footer|autosaveName|onSync|finalNodes|removeFormat|TAB|getNodesMarker|urlImage|Link|closeTooltip|success||imageDelete|rv|reUrlYoutube|enterKey|IMG|parentNode|activeButtonsStates|addProtocol|insertBreakLineProcessing|addCallback|getTextFromHtml|link_insert||encodeEntities|getModuleMethods|link_new_tab|normalize|tagsEmpty|attrAllowed|XMLHttpRequest|br1|br2|formatTableWrapping|headers|allowedAttrTags|allowedAttrData|getOffsetOfElement|syncCode|showCode|rTags|setBefore|elements|verifiedTags|clearUnverifiedRemove|convertInline|quote|saveFormTags|buttonsHide|buttonsHideOnMobile|clickedElement|fonts|x200b|replaceToParagraph|mailto|inputText|hover|setAfterOrBefore|status|firstFound|extra|par|curLang|pattern|setConfig|content|isDesktop|dfn|observeScroll|formatLinkify|send|direction|listTag|protocol|isUnorderedCmdOrdered|placeholdler|isOrderedCmdUnordered|showOnMobile|add|buttonsSize|dropdownObject|dropdownWidth|221|219|formattingAdd|hotkeysShiftNums|tbody|count|createActionButton|headTag|appendTo|redactorImageLink|ratio|SPACE|Row|redo|Table|mousedown|amp|closeHandler|ESC|Column|imageDisplay|thead|createButton|finish|contOwnLine|removeSpaces|matched|ownLine|isCurrentOrParentOne|cleanTag|readyState|tfoot|createCancelButton|createDocumentFragment|suffix|setupBuffer|List|altKey|stop|META|Head|checkKeyEvents|keydownStop|CTRL|Left|isExceptLastOrFirst|insertParagraph|setupSelectAll|langs|DOWN|LEFT_WIN||formatEmpty|exitFromBlockquote|onShiftEnter|removeInvisibleSpace|u00a0|scope|replaceDivToBreakLine||addArrowsEvent|dbl|stopPropagation|ALT|args|SHIFT|replaceDivToParagraph||Color|cleanStyleOnEnter|checkEvents|onArrowDown|removeEmptyListInTable|insertAfterLastElement|Function|insertNewLine|tabFocus|onTab|keyupStop|update|loadContent|matchIMG|enableEditor|loadEditor|getTextareaName|createContainerBox|getUndo|getRedo|run|matchBR|fromTextarea|onPasteRemoveEmpty|createTextarea|insertAfter|onPasteRemoveSpans|onPasteIeFixLinks|fromElement|matchBlocks|isSingleLine|savePreCode|getPreCode|onChange|startSync|onSet|formatBlockquote|setForce|showVisual|setInactiveInCode|setSelectionRange|restoreFormTags|empty|setRedo|getOnlyImages|pop|setUndo|quot|replaceDivsToBr|newTag|removeDirtyStyles|setCodeAndCall|all||||chars|focusCallback||setHelpers|linkNofollow|nofollow|pastePlainText|Apple|codeKeyupCallback|walker|endOffset|createTooltip|disableMozillaEditing|focusEnd|afterkey|beforekey|endContainer|foco|orgo|FIGCAPTION|codeKeydownCallback|cleanSpaces|mso|Mso|onPasteExtra|internal|callEditor|setOptions|dir|onPasteWord|setEvents|dragFileUpload|H2|H1|H3|H4|H6|H5|dragImageUpload|||||||||||modified|indenting||formatConvert|formatRemoveSameChildren|_this|through|setBlocks|setText|loadModules|bindModuleMethods|switch||strikethrough|formatMultiple|increaseText|increaseBlocks|increaseLists|decreaseLists|decreaseBlocks|formatCollapsed|subscript|superscript|loadOptions|shortcutsAdd|offsetNode|Image|Video|Right|duplicate|ie11FixInserting|EndToEnd|setEndPoint|execHtml|blocksMatch|Align|to|Edit|Center|setStartAfter|Code|htmlFixMozilla|choose|callbackName|15px|setCollapsed|setMultiple|clearInterval|one|mouseover|700|isFocused|mouseout|removeData|destroy|textareaIndenting|setInactive|setActiveInVisual|filter|selectionStart|commonAncestorContainer|event|selectionEnd|_delete|buttonDelete|fixImageSourceAfterDrop|inside|stopResize|formatTags||loadEditableControls|editerWidth|showEdit|opacity|moveResize|startResize|imagePosition|imageLink|buttonSave|floatValue||floating|pageX|imageEditable|setFloating|ie11PasteFrag|getSafes|align_justify|align_right|mouseup|createContainer|setFormattingTags|align_center|align_left|header2|header3|header4|header5|loadButtons|setFixed|hideButtonsOnMobile|observeScrollEnable|observeScrollDisable|visibility|hideButtons|buttonSource|toolbarFixed|setOverflow|toolbarOverflow|isButtonSourceNeeded|header1|paragraph|hotkeysSpecialKeys|origHandler|||||||arguments|area|handler|savedSel|getLastBlock|lastBlock|removeNodesMarkers|createMarkers|head|fieldset|removeTags|removeAttrGetRemoves|removeParagraphsInLists|removeAttrs|removeFromDenied|addToAllowed|map|lineBefore|lineAfter|setupAllowed||visible|lastFound|clone|saveEditorScroll|saveTargetScroll|reIsBlock|shorthandRegex|removeEmptyTags|iPod|BlackBerry|Android|Object|enableSelectAll|parents|gif|youtube|vimeo|rProtocol|jpeg|png|isIe11|chrome|opr|urlCheck|iPhone|setRequestHeader|fileUploadParam|getType|imageTypes|sendData|imageUploadParam|directUpload|unsetDropdownsFixed|Drop|here|change|parseJSON|onDragLeave|responseText|XDomainRequest|s3uploadToS3|s3createCORSRequest|that|onreadystatechange|s3uploadFile|signedURL|s3executeOnSignedUrl|||||overrideMimeType|fadeOut|setDropdownsFixed|image_position|outerHTML|imageEdit||getSafesComments|URL|checkbox|aUnlink||aside|article|template|restoreSafes|loadTemplates|cleanUrl|buttonInsert|setFocus|insertHTML|thref|location|re2|getData|replaceBreaksToParagraphs|replaceBreaksToNewLines|aEdit|activeElement|createDeleteButton|setButtonsWidth|setContent|setTitle|cancel|setEnter|setDraggable|draggable|handle|getTemplate|buildOverlay|enableEvents|linkTooltip|showTooltip|getTooltipPosition|aLink|setEditable|windowWidth|disableEvents|bodyOveflow|setInactiveAll|insertInOthersBrowsers|clear|createPasteBox|cleanOnPaste|freeze|modalOpened|withCredentials|OUTPUT|focusin|ADDRESS|SECTION|PUT|getModal|Plugin|decodeURIComponent|DT|outerHeight|alignright|caretOffset|returnValue|ins|enableInlineTableEditing|onload|DL|enableObjectResizing|DD|onerror|ARTICLE|isString|createTabber|iPad|addTab|HTML|link_edit|Normal|Formatting|Unlink|hexToRgb|addTemplate|read|onprogress|FOOTER|blurCallback|HEADER|Content|Type|public|acl|amz|ASIDE|defined|changeIcon|such|No|slice|nextNode|SHOW_TEXT|VERSION|addImageFields|clearImageFields|createTreeWalker|NodeFilter|youtu|Infinity|u00a9|copy|u2026|hellip|trade|u2122|getCoords|err|strict|use|removeImageFields|clearFileFields|addFirst|alignleft|addAfter|plain|addDropdown|charset|removeIcon|user|aligncenter|setAwesome|applet|addBefore|addFileFields|setEndAfter|setStartBefore|setEndBefore|removeFileFields|ltr|20px|GET|uploadImageField|10px|TEXTAREA|rgb|frameborder|Vimeo|File|Upload|download|Youtube|allowfullscreen|web|video_html_code|Cancel|Embed|Download|Choose|Indent|Horizontal|Rule|Deleted|Justify|500|or_choose|Or|281|drop_file_here|Email|Text|delete_column|delete_row|delete_table|rows|insert_column_right|insert_column_left|insert_row_above|Above|insert_row_below|Below|Rows|columns||None|image_web_link|player|Web|Position|Title|Columns|add_head|Save|delete_head||anchor|Anchor|host|Trident|isLessIe10|isOldIe|fontcolor|Font|safari|compatible|trident|opera|backcolor|xn|Italic|Quote|setAttr|toggleAttr|setClass|toggleData|setData|isStartOfElement|createLink|insertedLink|Bold|u2014|disable|LEFT|merge|jpg|Outdent|600|optional|Open|Underline|Alignment|Name|getOwnPropertyNames|Ordered|escape|encodeURIComponent|Back|autosaveError|post|ajax|zA|setInterval|1000|Unordered|insert_table|setToPoint|dropdownShow|222|dropdownShown|up|fromCharCode|home|hasOwnProperty|Key|220|192|down|188|fileUploadError|mdash|189|191|190|dropdownHide|frame|noscript|capslock|105|frameset|pause|jQuery|menu|backspace|summary|pageup|getObject|getToolbar|pagedown|Callback|getTextarea|getElement|getEditor|getBox|187|186|114|113|101|round|Math|touchmove|touchend|115|112|111|107|106|104|109|103|110|102|mousemove|116|f12|123|f11|144|numlock|173||145|705|122|f10|118|dragstart|117|imageUploadError|119|121|120|syncBefore|esc|overlay|colspan|rowspan|relative|fake|pasteHTML|docs|times|guid|fast|modalClosed|startContainer|clientY|stripTags|pasteBefore|external|unselectable|removePhp|1500|addButton|sid|dragover|converted|nodeToPoint|fadeIn|cursor|uploadImageFields|uploadFileFields|u2010|dash|POST|move|clientX|MsoListParagraphCxSpLast|MsoListParagraph|dragleave|MsoListParagraphCxSpMiddle|MsoListParagraphCxSpFirst|bmso|WordDocument|shapes|9999px||toggleActive|enter|toggleStyle|hgroup|extractContents||removeStyleRule||math|removeStyle|legend||getText|getHtml|specified|cloneContents|innerText|textContent|cssText|details|nav|htmlWithoutClean|bull|context|getOnlyLinksAndImages|fromPoint'.split('|'),0,{})) \ No newline at end of file diff --git a/login.php b/login.php index f79bf8563320f672fdb90c67fff9e178eafd4fd7..0d6f9e3d4c30a8df3f6e8aa83334b0582563022e 100644 --- a/login.php +++ b/login.php @@ -31,6 +31,20 @@ else $inc = 'login.inc.php'; $suggest_pwreset = false; + +// Check the CSRF token, and ensure that future requests will have to use a +// different CSRF token. This will help ward off both parallel and serial +// brute force attacks, because new tokens will have to be requested for +// each attempt. +if ($_POST) { + // Check CSRF token + if (!$ost->checkCSRFToken()) + Http::response(400, __('Valid CSRF Token Required')); + + // Rotate the CSRF token (original cannot be reused) + $ost->getCSRF()->rotate(); +} + if ($_POST && isset($_POST['luser'])) { if (!$_POST['luser']) $errors['err'] = __('Valid username or email address is required'); @@ -71,9 +85,12 @@ elseif ($_POST && isset($_POST['lticket'])) { if (!$cfg->isClientEmailVerificationRequired()) Http::redirect('tickets.php'); + // This will succeed as it is checked in the authentication backend + $ticket = Ticket::lookupByNumber($_POST['lticket']); + // We're using authentication backend so we can guard aganist brute // force attempts (which doesn't buy much since the link is emailed) - $user->sendAccessLink(); + $ticket->sendAccessLink($user); $msg = sprintf(__("%s - access link sent to your email!"), Format::htmlchars($user->getName()->getFirst())); $_POST = null; diff --git a/logout.php b/logout.php index 74d73cc377b58049f286551771ff880dfc800fab..9fb8037acd458c9998c126d6d17ec533fbac7b57 100644 --- a/logout.php +++ b/logout.php @@ -19,6 +19,7 @@ require('client.inc.php'); if ($thisclient && $_GET['auth'] && $ost->validateLinkToken($_GET['auth'])) $thisclient->logOut(); +osTicketSession::destroyCookie(); Http::redirect('index.php'); ?> diff --git a/scp/css/login.css b/scp/css/login.css index 99f8f1220c1f388f52a37d8759c5ba5049566b9c..aef7b3a789b44c4d55bc0e7df0965cc7f1bc2247 100644 --- a/scp/css/login.css +++ b/scp/css/login.css @@ -69,12 +69,21 @@ h1 { #logo a { display:block; - width:180px; - height:72px; text-decoration:none; - text-indent:-9999px; - background:url(../images/login-logo.png); - margin:0 auto 1em auto; + height: 100px; +} + +#logo a img { + max-height:66px; + max-width: 300px; + height: auto; + width: auto; + vertical-align: middle; +} +.valign-helper { + height: 100%; + display: inline-block; + vertical-align: middle; } h3 { diff --git a/scp/css/scp.css b/scp/css/scp.css index ebb60c9ba34d2b21761a3fdb59f148524e7ef8cc..e687b82be86bc6700eb385246ce3f4118a182caa 100644 --- a/scp/css/scp.css +++ b/scp/css/scp.css @@ -102,19 +102,31 @@ div#header a { #header { height:76px; - background:url(../images/header-bg.png) top left repeat-x; border-left:1px solid #aaa; border-right:1px solid #aaa; + background-color: rgb(248,248,248); + box-shadow: inset 0 -10px 8px -5px rgba(0,0,0,0.1); } #logo { display:block; - width:190px; - height:76px; text-decoration:none; outline:none; - text-indent:-9999px; - background:url(../images/ost-logo.png) top left no-repeat; + height: 64px; + max-width: 400px; + padding: 5px 0 7px 5px; +} +#logo img { + max-height: 66px; + max-width: 300px; + height: auto; + width: auto; + vertical-align: middle; +} +.valign-helper { + height: 100%; + display: inline-block; + vertical-align: middle; } #header p { @@ -1428,10 +1440,10 @@ time { bottom:0; left:0; right:0; - z-index:1; + z-index:11; } -.redactor_editor { +.redactor-editor { font-size: 11pt; } @@ -2141,3 +2153,6 @@ td.indented { #dynamic-actions > tr > td { padding: 5px; } +.no-margin { + margin: 0 !important; +} diff --git a/scp/images/header-bg.png b/scp/images/header-bg.png deleted file mode 100644 index dc3e1d5c51f1a9c7b58c5a5b8c423a0152c72767..0000000000000000000000000000000000000000 Binary files a/scp/images/header-bg.png and /dev/null differ diff --git a/scp/images/login-logo.png b/scp/images/login-logo.png deleted file mode 100644 index 6526ebe0a15f393382e0339b38cef8422d7ff471..0000000000000000000000000000000000000000 Binary files a/scp/images/login-logo.png and /dev/null differ diff --git a/scp/images/ost-logo.png b/scp/images/ost-logo.png index 0cf40c72dc58b139663d8ba7bd0210ae5d2743f1..33b09d35aa8dfbc935e85e70ee17bc5c69d0567e 100644 Binary files a/scp/images/ost-logo.png and b/scp/images/ost-logo.png differ diff --git a/scp/js/scp.js b/scp/js/scp.js index a3a531d298e37aeb6a52395199291b865b81283f..9ac9e8f73eae53db1768095de2b04896b6ad934e 100644 --- a/scp/js/scp.js +++ b/scp/js/scp.js @@ -221,12 +221,12 @@ var scp_prep = function() { redactor = box.data('redactor'); if(canned.response) { if (redactor) - redactor.insertHtml(canned.response); + redactor.insert.html(canned.response); else box.val(box.val() + canned.response); if (redactor) - redactor.observeStart(); + redactor.observe.load(); } //Canned attachments. var ca = $('.attachments', fObj); diff --git a/scp/js/tips.js b/scp/js/tips.js index 127d81db312a7d37a0b56567a48ca69b89c1b00b..57ca1ee78ce5e9966216ac135841120eddbf2fd0 100644 --- a/scp/js/tips.js +++ b/scp/js/tips.js @@ -235,9 +235,11 @@ jQuery(function() { // Tooltip preview $('.preview').live('mouseover', function(e) { - e.preventDefault(); var elem = $(this); var vars = elem.attr('href').split('='); + if (!elem.data('preview')) + return; + e.preventDefault(); var url = 'ajax.php/'+elem.data('preview').substr(1); // TODO - hash url to integer and use it as id. var id= url.match(/\d/g).join(""); diff --git a/scp/login.php b/scp/login.php index 609a0c5eca29df70b768233f29c9eb38e4e5fe1c..6655239c2be175d57a10a49744bb45019b928032 100644 --- a/scp/login.php +++ b/scp/login.php @@ -31,6 +31,16 @@ $msg = $msg ?: ($content ? $content->getLocalName() : __('Authentication Require $dest=($dest && (!strstr($dest,'login.php') && !strstr($dest,'ajax.php')))?$dest:'index.php'; $show_reset = false; if($_POST) { + // Check the CSRF token, and ensure that future requests will have to + // use a different CSRF token. This will help ward off both parallel and + // serial brute force attacks, because new tokens will have to be + // requested for each attempt. + if (!$ost->checkCSRFToken()) + Http::response(400, __('Valid CSRF Token Required')); + + // Rotate the CSRF token (original cannot be reused) + $ost->getCSRF()->rotate(); + // Lookup support backends for this staff $username = trim($_POST['userid']); if ($user = StaffAuthenticationBackend::process($username, diff --git a/scp/logo.php b/scp/logo.php new file mode 100644 index 0000000000000000000000000000000000000000..0acbf430882b3690134e4048bb7c22ffc1cd697f --- /dev/null +++ b/scp/logo.php @@ -0,0 +1,32 @@ +<?php +/********************************************************************* + logo.php + + Simple logo to facilitate serving a customized client-side logo from + osTicet. The logo is configurable in Admin Panel -> Settings -> Pages + + Peter Rotich <peter@osticket.com> + Jared Hancock <jared@osticket.com> + Copyright (c) 2006-2013 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ + +// Don't update the session for inline image fetches +if (!function_exists('noop')) { function noop() {} } +session_set_save_handler('noop','noop','noop','noop','noop','noop'); +define('DISABLE_SESSION', true); + +require_once('../main.inc.php'); + +if (($logo = $ost->getConfig()->getStaffLogo())) { + $logo->display(); +} else { + header('Location: images/ost-logo.png'); +} + +?> diff --git a/scp/logout.php b/scp/logout.php index bdc697c78beceb7b4cf3185603f45afbcf8d2838..0a7f6ee8e9f5c3c259e45e0b8bf515e69e08c515 100644 --- a/scp/logout.php +++ b/scp/logout.php @@ -23,7 +23,7 @@ if(!$_GET['auth'] || !$ost->validateLinkToken($_GET['auth'])) $thisstaff->logOut(); //Clear any ticket locks the staff has. -TicketLock::removeStaffLocks($thisstaff->getId()); +Lock::removeStaffLocks($thisstaff->getId()); //Destroy session on logout. // TODO: Stop doing this starting with 1.9 - separate session data per @@ -31,6 +31,8 @@ TicketLock::removeStaffLocks($thisstaff->getId()); session_unset(); session_destroy(); +osTicketSession::destroyCookie(); + @header('Location: login.php'); require('login.php'); ?> diff --git a/scp/tickets.php b/scp/tickets.php index 78da72d76421cfaad6828e0bdebf6b5d7b4a504f..0a57e94c53c053b377504484ca5f80c98fa8a355 100644 --- a/scp/tickets.php +++ b/scp/tickets.php @@ -57,22 +57,31 @@ if($_POST && !$errors): if($ticket && $ticket->getId()) { //More coffee please. $errors=array(); - $lock=$ticket->getLock(); //Ticket lock if any + $lock = $ticket->getLock(); //Ticket lock if any $role = $thisstaff->getRole($ticket->getDeptId()); switch(strtolower($_POST['a'])): case 'reply': - if(!$role || !$role->hasPerm(TicketModel::PERM_REPLY)) + if (!$role || !$role->hasPerm(TicketModel::PERM_REPLY)) { $errors['err'] = __('Action denied. Contact admin for access'); + } else { if(!$_POST['response']) $errors['response']=__('Response required'); - //Use locks to avoid double replies - if($lock && $lock->getStaffId()!=$thisstaff->getId()) - $errors['err']=__('Action Denied. Ticket is locked by someone else!'); + + if (!$lock) { + $errors['err'] = __('This action requires a lock. Please try again'); + } + // Use locks to avoid double replies + elseif ($lock->getStaffId()!=$thisstaff->getId()) { + $errors['err'] = __('Action Denied. Ticket is locked by someone else!'); + } + elseif ($lock->getCode() != $_POST['lockCode']) { + $errors['err'] = __('Your lock has expired. Please try again'); + } //Make sure the email is not banned - if(!$errors['err'] && TicketFilter::isBanned($ticket->getEmail())) + if(!$errors['err'] && Banlist::isBanned($ticket->getEmail())) $errors['err']=__('Email is in banlist. Must be removed to reply.'); } @@ -92,8 +101,7 @@ if($_POST && !$errors): $response_form->getField('attachments')->reset(); // Remove staff's locks - TicketLock::removeStaffLocks($thisstaff->getId(), - $ticket->getId()); + $ticket->releaseLock($thisstaff->getId()); // Cleanup response draft for this user Draft::deleteForNamespace( @@ -174,7 +182,7 @@ if($_POST && !$errors): $msg = __('Ticket is NOW assigned to you!'); } else { $msg=sprintf(__('Ticket assigned successfully to %s'), $ticket->getAssigned()); - TicketLock::removeStaffLocks($thisstaff->getId(), $ticket->getId()); + $ticket->releaseLock($thisstaff->getId()); $ticket=null; } } elseif(!$errors['assign']) { @@ -189,6 +197,17 @@ if($_POST && !$errors): $vars['cannedattachments'] = array_merge( $vars['cannedattachments'] ?: array(), $attachments); + if (!$lock) { + $errors['err'] = __('This action requires a lock. Please try again'); + } + // Use locks to avoid double replies + elseif ($lock->getStaffId()!=$thisstaff->getId()) { + $errors['err'] = __('Action Denied. Ticket is locked by someone else!'); + } + elseif ($lock->getCode() != $_POST['lockCode']) { + $errors['err'] = __('Your lock has expired. Please try again'); + } + $wasOpen = ($ticket->isOpen()); if(($note=$ticket->postNote($vars, $errors, $thisstaff))) { diff --git a/setup/inc/streams/core/install-mysql.sql b/setup/inc/streams/core/install-mysql.sql index d988d02b0c802d1f5ba76f71d4921283fb026c84..26f129681118b2c67eea32dc5f4b74f78d30a656 100644 --- a/setup/inc/streams/core/install-mysql.sql +++ b/setup/inc/streams/core/install-mysql.sql @@ -303,6 +303,7 @@ CREATE TABLE `%TABLE_PREFIX%filter` ( `match_all_rules` tinyint(1) unsigned NOT NULL default '0', `stop_onmatch` tinyint(1) unsigned NOT NULL default '0', `target` ENUM( 'Any', 'Web', 'Email', 'API' ) NOT NULL DEFAULT 'Any', + `email_id` int(10) unsigned NOT NULL default '0', `name` varchar(32) NOT NULL default '', `notes` text, `created` datetime NOT NULL, @@ -468,7 +469,8 @@ CREATE TABLE `%TABLE_PREFIX%help_topic_form` ( `form_id` int(10) unsigned NOT NULL default 0, `sort` int(10) unsigned NOT NULL default 1, `extra` text, - PRIMARY KEY (`topic_id`, `form_id`) + PRIMARY KEY (`id`), + KEY `topic-form` (`topic_id`, `form_id`) ) DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `%TABLE_PREFIX%organization`; @@ -631,6 +633,7 @@ CREATE TABLE `%TABLE_PREFIX%thread_entry` ( `staff_id` int(11) unsigned NOT NULL default '0', `user_id` int(11) unsigned not null default 0, `type` char(1) NOT NULL default '', + `flags` int(11) unsigned NOT NULL default '0', `poster` varchar(128) NOT NULL default '', `source` varchar(32) NOT NULL default '', `title` varchar(255), @@ -670,6 +673,7 @@ CREATE TABLE `%TABLE_PREFIX%ticket` ( `staff_id` int(10) unsigned NOT NULL default '0', `team_id` int(10) unsigned NOT NULL default '0', `email_id` int(11) unsigned NOT NULL default '0', + `lock_id` int(11) unsigned NOT NULL default '0', `flags` int(10) unsigned NOT NULL default '0', `ip_address` varchar(64) NOT NULL default '', `source` enum('Web','Email','Phone','API','Other') NOT NULL default 'Other', @@ -697,15 +701,14 @@ CREATE TABLE `%TABLE_PREFIX%ticket` ( KEY `sla_id` (`sla_id`) ) DEFAULT CHARSET=utf8; -DROP TABLE IF EXISTS `%TABLE_PREFIX%ticket_lock`; -CREATE TABLE `%TABLE_PREFIX%ticket_lock` ( +DROP TABLE IF EXISTS `%TABLE_PREFIX%lock`; +CREATE TABLE `%TABLE_PREFIX%lock` ( `lock_id` int(11) unsigned NOT NULL auto_increment, - `ticket_id` int(11) unsigned NOT NULL default '0', `staff_id` int(10) unsigned NOT NULL default '0', `expire` datetime default NULL, + `code` varchar(20), `created` datetime NOT NULL, PRIMARY KEY (`lock_id`), - UNIQUE KEY `ticket_id` (`ticket_id`), KEY `staff_id` (`staff_id`) ) DEFAULT CHARSET=utf8; @@ -755,17 +758,17 @@ CREATE TABLE `%TABLE_PREFIX%ticket_priority` ( KEY `ispublic` (`ispublic`) ) DEFAULT CHARSET=utf8; -CREATE TABLE `%TABLE_PREFIX%ticket_collaborator` ( +CREATE TABLE `%TABLE_PREFIX%thread_collaborator` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `isactive` tinyint(1) NOT NULL DEFAULT '1', - `ticket_id` int(11) unsigned NOT NULL DEFAULT '0', + `thread_id` int(11) unsigned NOT NULL DEFAULT '0', `user_id` int(11) unsigned NOT NULL DEFAULT '0', -- M => (message) clients, N => (note) 3rd-Party, R => (reply) external authority `role` char(1) NOT NULL DEFAULT 'M', `created` datetime NOT NULL, `updated` datetime NOT NULL, PRIMARY KEY (`id`), - UNIQUE KEY `collab` (`ticket_id`,`user_id`) + UNIQUE KEY `collab` (`thread_id`,`user_id`) ) DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `%TABLE_PREFIX%task`; @@ -778,6 +781,7 @@ CREATE TABLE `%TABLE_PREFIX%task` ( `sla_id` int(10) unsigned NOT NULL DEFAULT '0', `staff_id` int(10) unsigned NOT NULL DEFAULT '0', `team_id` int(10) unsigned NOT NULL DEFAULT '0', + `lock_id` int(11) unsigned NOT NULL DEFAULT '0', `flags` int(10) unsigned NOT NULL DEFAULT '0', `duedate` datetime DEFAULT NULL, `created` datetime NOT NULL,