// ==================== |-----| ====================
// ==================== | api | ====================
// ==================== |-----| ====================
// API
// ==================== |-------------| ====================
// ==================== | api_version | ====================
// ==================== |-------------| ====================
/**
* <h3>Sanity tests for After Effects</h3>
* <p>DuSan requires <i>DuAEF</i>, the <i>Duduf After Effects Framework</i>. Two builds of the <i>DuSan API</i> are available:<br />
* <ul><li><code>DuSan_api.jsxinc</code> does not include <i>DuAEF</i>, and can be used to compine multiple <i>Duduf APIs</i> with a single copy of <i>DuAEF</i>.<br />
* Be careful to grab the right version of <i>DuAEF</i> in this case.</li>
* <li><code>DuAEF_DuSan_api.jsxinc</code> includes all dependencies, with <i>DuAEF</i>, and is easier to include in your scripts.</li></ul></p>
* @namespace
* @author Nicolas Dufresne and contributors
* @copyright 2022 Nicolas Dufresne, RxLaboratory
* @version 2.0.6-dev
* @requires DuAEF>=1.0.0
* @license GPL-3.0 <br />
* DuSan is free software: you can redistribute it and/or modify<br />
* it under the terms of the GNU General Public License as published by<br />
* the Free Software Foundation, either version 3 of the License, or<br />
* (at your option) any later version.<br />
*<br />
* DuSan is distributed in the hope that it will be useful,<br />
* but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
* GNU General Public License for more details.<br />
*<br />
* You should have received a copy of the GNU General Public License<br />
* along with DuSan. If not, see {@link http://www.gnu.org/licenses/}.
* @category DuSanity
*/
var DuSanity = {}
// ==================== |-------| ====================
// ==================== | icons | ====================
// ==================== |-------| ====================
// ==================== |-----------| ====================
// ==================== | w12_check | ====================
// ==================== |-----------| ====================
var w12_check = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01;IDAT(\u0091}\u00CF;KCA\x10\u0086\u00E1wv\u00D7\u00A4\u00B0\x10T\x14+\u008Bt^j\u00AD\u00C5\u00C6\u00C2\u0080\u009D\u00A0\u0085U\b\u00EAo\u0090t\u00FE\u0089\x18Q\x14\u0084\u00ED\x04\x0BAP\x10/\u00C5Q\x0BE{\t\x16V\u00D9\u0080 \u00E6\u009CY\u009B\x13\u0090\u00A0~\u00DD\u00CC<30B\u009EJ\u00A5\u00D2\x17c\\\u008B1\u00AE\x02\x13\u0080\x01^\u0080\u00C3\x10\u00C2\u008E\u00F7\u00FE\x0B@\x00\u00AA\u00D5\u00EAH\u00A7\u00D39\x16\u0091\x19~\u00CF\u00BD\u00AA.6\x1A\u008D7\u00A9\u00D5j\u00AE\u00D9l^\x02\u00B3\x7F\u00E0n\x1EB\b\u00B3\u00B6T*\u00AD\u0089\u00C8\u00C6?0\x01\u00DA\u00C0t\u00B1X|7\"\u00B2\u00F2\x0F\u00BER\u00D59U]\x07\x10\u0091\x15\u0093?\b\u00F0\b\u009C\u00F6\u00E0\u0085B\u00A10d\u008C\u00D9\u00CD{\u0093\x0E\u0088\x001\u00C6-k\u00ED\u0089\u00AA\x1E\x01\u00A3]\u009C\u00A6\u00E9\x050\u00DE\u00BD\u00E2\u0080g`LDv\u00B2,\u009B\u00B7\u00D6.;\u00E7\u008A\u00AA:\u00DC\u008B\u0081'\x03\x1C\u00E6\u00C5\u00A0\u0088\u009CeY6\u00F5\x07FD\x0EL\ba\x1F\u00B8\u00FE\u00B1t\u009E\u00A6\u00E9m/\x06\u00EEZ\u00ADV\u00DDx\u00EF3\u00E7\u00DC\x12p\u0093\x0F\x06\u0080\u00D1\x1E\u009C\u00A8j\u00D9{\u00FFe\x01\u0092$\u00F9(\u0097\u00CB{\u00EDv\u00FB5_\u00E8\x07>\u0081\u00BB\x18\u00E3\u00B6\u00B5v\u00B3^\u00AF\x07\u0080o\u008E\u00F9\u008B\t\x16\x10\u00F0~\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_check.png", "icons" );
w12_check;
// ==================== |-------------| ====================
// ==================== | w12_check_g | ====================
// ==================== |-------------| ====================
var w12_check_g = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01FIDAT(\u0091}\u00D2\u00BF+\u00C4q\x1C\u00C7\u00F1\u00E7\u00EB\u00E3\u00B8\u00FC\u00BA\u00F3+b\u00B1\u00CAY\u0094\u00A2\x1BM\f\u0094E\u00CA\u00CF\u0089Rf\u009B\u00BE\u00BB?@\x06,n\u00B9\u00C1`S\u00EAD\u00B2\x1C\x06\"e\u00B1\u00B0\x11\u00CEq\u00A7\u00EF\u00F7m\u00F0\u00BD\x12\u0097\u00D7\u00F6y\u00BD\x1F\u00BD\u0087w\x1F\x11f=\u00BB^\u00F9R\u00FF>\x17\x04\u009A\u0092\u00E8\x06\x1C\u00D85\u00B8T\u00DE\x7F\u00DC\u00F0\x12^\x11@\x00\u00AB\u00B7k\u00AD\u00F6Y\u00DCE\u00F4S6:34\u00B2\u00DC\u00B5t//\u00E3Ej:\x1A\u008F0\x06\u00CA\u00E3\u00EF\u0098q\u00FE\x1E<\rDj\u00DA\u009Bf0\u00FB\x07[\x16T'\u00D1[\u00ED\x1A\u00E6\x1D\x04\u0093\u00FF\u00E0c\u00A30h\u00B0\b \u00A7I\x07\u00EA\x0E\u00A7\x17B{\u00BF\u00F0p`U\u00CD\u0082\u00AD\u00EF\u008A\u008430\x00S\u00B0\x12\u00CBEG$\u00DB\u00F9\u0089+\u00E4\x0E\u0080\u00CE\u00D2\x1A'\u00B8\x02\u0090\u00B9\u008D\\\u00BC\u00D0\x13{\u00AD\u009E\u00C8\u00FB\u0095C\u00E50\u00E8\u00D2\x19\u00A4\u00C2W\u0093\u00EF\u00DB~.^\u00E8\u0089\u00BAb\u00CB_\f\u00A6`[iKW\u00DC\u00DD<\x1C\x1A$\u00C3\u00FE\x19\u00F1\u0081\u00D1\u00F6\u00EB\x02\u00A7y\u00FF)\u00E9\u00C65\u00EE\x13\u00A9\x1A\x03\u009D\u0084\u0083\u00F8_lY\u00C3\u008Dz\t\u00AF\u00A8R\u00E5e\u00BCHm{\u00C3\u00AC\u00A1i(}\r\u00AEdJ\u00C5\u00DE\u00A2\u009B\x0B}\x0B\u009F\x00_\x01#\u0080\u00CF\u00FC\u0086\u00D2\u00B1\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_check_g.png", "icons" );
w12_check_g;
// ==================== |--------------| ====================
// ==================== | w12_critical | ====================
// ==================== |--------------| ====================
var w12_critical = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x03IDAT(\u0091m\u008F\u00B1J\x03Q\x10E\u00CFl^\x04\x15D0\u00F86/F[k\u00C1B\u008C\u009D\u00DF\u00A0\x06\u00EC\u00F4\x0F\u0084\u00F8\x0B\x16~\u0082\u009D\u0085~B\u00FEA\u00B0\u00B6U!,\u00B8\u00BB\u008A\u0085\u0085d\u00DFX$\u00CA\u00EE\u00F3M3\u00CC\u00BDs\u00EF\u00DC\u0081H\u00BDu:.\u00B3v=\u00C6\u0099\x10P\u0090\u00D2\u0098{\x01\u00A3\u00B0/\u00A0u>\t\x05\u00B9\u00B5C\u0085\x03`/\u00B7\u00F6$\u00E4\u00A5>L\u009C[Z\u00F0\u00FE\t\u00B8\u009BC\u00C3\u00EF$\u00D9v\u0093\u00C9W\u00F4B\u00DB\u00FBK\u00A0\u00AF0V\x18\x03\u00FD\u00B6\u00F7\u00A3h\u00A4\u00A2\u00D7\u00DB\x10\u00B8\u0088D\x18\u00BDw\u00BB[\u00FF\x04\u00BE\u00AA\u00AE\u0081\u00E5P\x00,z\u00D5\u00AB\u0086\u00A0tn p\u00F4\u00E7\u00AA\u00DA\x12\u00D5\u00D6\u00EF\u00ACp\\:7\u0098q\u0090\x14i\u00FA\x00\u00EC\u00D4\\_\u00E6}\u00B3\u0086=\u00AEe\u00D9\u00AE\x14\u00D6\u009E\u00A9\u00C8M=\u0083\u008A\u009C\n\b\u00AA\u00B7\u008D\x7FT\u00CF%O\u00D3\u00E7\u00C0\tT?f\x1B\u00B2\x1A\u00FC\u00F3j|U\x1D\u008A1+\rX\u0084X\u00E9t\u00FA\u00F9\x03\u0081\u008EM\u00EC\x18N\u00BBB\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_critical.png", "icons" );
w12_critical;
// ==================== |-----------| ====================
// ==================== | w12_fatal | ====================
// ==================== |-----------| ====================
var w12_fatal = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00F7IDAT(\u0091\u008D\u008F\u00B1N\x02\x01\x10D\u00DFl\x0ECaa\u00E1'\u0098\u00F3\x1B\u008C\u00A7\t\u0089\u0095\r\u0095\u00C6 ~\x04\u009DFCB\u00FC\x06\x1Bb\t\u009D\u0091\u0086\u00C4\u0082\u00C2\u00C2\u008B\u00BD\u0085\t\x02\x7F \u0085\u008D\x16\u00A2\u00B7\x16x\x06\u00BD\u00C30\u00D5\u00EE\u00EC\u00EC\u00CC\u00AE\u00DA\u00EBq\t|\u0095\u0085\u00A0q\u0080\u00D3\x04\u00AD\u00CD\u00D2\u008E\u00DFK\x12\u00CE\u00C6/\u00BDkh.\u009Dd|\u00A43\u00E04\u009B\u00E0\u00C7V}\u00DA\u00BC\x02z\x0B\u00DCs{8\u008C\u00AE\r@\t5\u00E0\u00E3\x1F\u00F1g\u0082\u00D7\x00\f\u00A02\u008A\x1Eq.\u00E7\u00CA\u009D\u00E6\u00D1`\u00EB\x01 H\u00B9\u0082'\u00F5\u0089\u00EC\x00X\u00C19\u009F\u0091\u00BFH\u0093z\u00DAXZ\u00EC\u008F\u00B6\u009F]4\u00A6\u0086\u00DEq\u00BC\x03\u00E0\u00A2Q\x19\u0094\u00C6\u0099\x05\u0080\u00D7\u00E5\u00E2\x05\u00D07T6T\x06\u00FA\u00DF\u00DC\x0F\u00F4\u00F7\u00DCvx\u00B7\x03\u00EAM\u0093\u00D8\u00AD\x0E\u00A2\u009B\u00B9\u00BF\u00A5h\u0085q\u00B7\x15\u00C6\u00DD\u00BCY\u0090G.\u00BD\u00D9\u00DE{\u00D1\ny\u00B3/\u00ECZJ\x18\u00D9\u009A'\x17\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_fatal.png", "icons" );
w12_fatal;
// ==================== |-----------------| ====================
// ==================== | w12_information | ====================
// ==================== |-----------------| ====================
var w12_information = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\"IDAT(\u0091\u008D\u0092;NBa\x10\u0085\u00BF\u00F3\u00FF\x17\x03X\u00AB[\u00E0\u00D5\u0098X`\u00E9\x024\u00C6\u0082\x061\u00B1\u00D1m\u00DC-hE\u00D4X\u0081\x056\u00BA\x02\x0B\u00EC4\x1A\x13Q\u00D8\u0080\x1D\u0095\t\x10\u00E1\u00DE\u00B1\u00F0\x06\u0085h\u00E2iNr\x1E\u0093\u00C9dD\u0082\u00F0\u00C6\x02\u00BF4\u00D8\u00C7\u00B4\x0B\x14\x00\x07\u00BC\u009A\u00EC\"V\u00F6,,\u00EA\x03@\x00\u00E1\u00D3\u00FB\u00B2w\u00FE\x1A('\u00FD\u00AB\u0084\u00B7\x13~\u0088R\u00B6\x19\u00E6\x16\u00DF\u00D4j\u0099\u00EF\u00E5\u0087m`=1\u00C7Q)\u0093.\\\u00A2^~8\x02\x02\x00\u008C\u00C7\u00C8g\u00CAA77\u00AA\u00E9;\f\u0090\u00F2\u00CF\u0083\u0093^\x1E@\u00C1T\x15\u00AB.\x1A\x1E\x04R\\M6\u009B\u00C2L}\x00\u00CD\u00CAHT\x1D\u00A8\u00C8\x1C\\\u00CCq\u00BC`G\u00F3:Pr\x18\u00F6\u008B\u00F1\x07,v\u0092u\u00FE_P\u00C7\u00C5r\u008D\x7F\u00CF\u00975\\\u00EE%\u00DDD\u00B4g\x1C\u008F\x0B\u00C6\u00F2s\u00F9\u00FB\u0095Q\u00F6\u00D4U*\u008A\u00A2\u00D4d\x07\u00B8\u009DNBuC\u00F5\x1F\u00E1;\u00E7m\u00EBpM\u00E3\u00E9\u00E1Z-\u00F3\u00DD\u00DC\u00A8\u00E6d{\u00F6\u00F5\x1A\x02\u00BAf\u00D6\u008C\u00FB\u00D9\u00F3pC\x13\u0080O\u00DA\u00B9a\u00B0+\x13\u00D1O\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_information.png", "icons" );
w12_information;
// ==================== |-------------| ====================
// ==================== | w12_warning | ====================
// ==================== |-------------| ====================
var w12_warning = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x05IDAT(\u0091\u008D\u008F\u00BF/\x03q\x18\u00C6?\u00CF7W\u008B\u00CD\u00A1\u00ADYB\u00B4\x06\x12!$&\u00B1\x19\u00ACr1\u00E1_\u00F1?\u0088A\u009A\u00F6\x0F\u0090\u00D8\f$\x12]\u00DAI\u00DA\x1A\u00BA;\u00EAl\x16\u00CE\u00BD\x06\x17\u00B9\u00D3J\u00FA\u008C\u00CF\u00FB>\u00BFD\n\u00BB\u00C1{+\x17\x0F\u00CD\x14\x00\u008B)\u00DD\u0093\u00A8O-\u00845\u0089/\x00\x01\u0084\u00FD\u00E2\u00AC\u00F7\u00A9K`\u0083\u0091\u00D0}\\H\u00F6K\u00F3\u00CF/\u00B2\x16\u0085h\u00B2t\x07\u00ACg\x1E\u00AE!1\u00D0nF\u00D5\u00F4\u00C3p[\u0083^\u00F9X\u00D8Y\u00CE0\u00B1\x1Ds\u008A\x05\u00B7\u00B9\x1C\u00B3#\u00E7\u00B0`t\u008Da\u0098\x148\u0083\u00EA\u00D8\x02\u00A8:\u00D2\u00E1\u00E3@ \u00CF\u00B0\u00AE\u00D0V\u00EE\u00E2t*H\u0086\x04\u00A2\u00EB$5F\u0098\u00D5L\u00BA\u00F8K&\u00A6\u0086\u00ACS\u0099\u0088\\\u00D4\x04V3\u00B76?\tk\x19\u00AE\u00E5\u00BF\u0087\u009B\x02\x18<N\u00CF\u00C9\u00BC+`\u00E5\u009F\u00FAm\u00B3xof\u00E9\u00F5\u00E9wp\u009At\x02\x1C\x00\u00CB)\u00FD\u0080Q\u00F7\u00CD?W\u00A5\u00F3\x01\u00F0\r\u00D4FV\u00F60\u00B8l\u00C2\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_warning.png", "icons" );
w12_warning;
// ==================== |------------| ====================
// ==================== | w12_danger | ====================
// ==================== |------------| ====================
var w12_danger = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\f\x00\x00\x00\f\b\x06\x00\x00\x00Vu\\\u00E7\x00\x00\x00\tpHYs\x00\x00\x05\u0089\x00\x00\x05\u0089\x01mh\u009D\u00FA\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x1CIDAT(\u0091\u008D\u0091=K\u00C3P\x14\u0086\u009Fs\u009B,\u0081B\x03\u00C9hGu\x11\n\"\u00FE\x01\u00F1'8\u008B 86\u00BB\x1F\u00E0 \bb\x1D\n\"8\u0088\u00A3\x7F\u00C1\u00C5]\u0087\u00A2S\x1D\u00AB[\x02\x06\n\x19L\u009A\u00E3\u00D04\u00DCJ\x05\u00DF\u00E9\u00DE\u00F7>\u00EF\u00F9\u00E0\n\u0095\u00F4\u0081F2\u00F2:,P\u00D0\u00CE\x06\u00B2\u00C3\x04\u00C0\u0099\u0099\u00C9\u00A7\u00B7/F\u00AE\x17\x05\u0092\x0F\u00EF\x00\u00B2\x1B\x00\x01\u00F8\u00EA\u00B5Z\x13\u00CD\u00DF\u0081\u0090\u00A9\u00FB\u0088\u00A2\u00C0v\u0095\u0089\x1B\u00E2.\u00FBQ\u009A\x1A\u0080\u0082\u00FC\u00A4\u0086\x01J\u00CE\x159\u00B3\u009A\u0084\u0085\u00E6\u00C7\x00\u0092\\4W1\u00E5+\u00E0\u00D6\u00CF\u00CA\u0096\u008A\x14\u0082>Y\u00A1B\u0090\u008EQS^\u00CE\u00C1\x7F\u00CBQ\u00D1\u009E1\u00A0\u00FF\u0080\u00A7\u00AB)\u00DF\x12_5W\u00A4,\u00DF~\u008D\u00F4\u008CP\x02\u009B\x16\u009F\u00AB1k&\u00EC\u008E\u0087\n\u00FD\u00F9Rr\u00AF\u00E8\u009Dm)\u00F4\u00C3\u00EExh\x00\x1CqO\u0081\u00D8\u00EA\u00BD+*{\x16\x1FW\f\x06\u00C0\u008F\u00D2TU\u008F\u00ACr\u00EB\b\x1B\u00F5U\u00F4\u00D0\u008F\u00D2\x14\u00AC\u009F\x0E\u0096\u00B2\u00DBd\u00E4\u00BD,Z6hg\u0083\u00D9\u00F9\x07\u00C1Ia\u009F\u00C3$\u00BB\u00CC\x00\x00\x00\x00IEND\u00AEB`\u0082", "w12_danger.png", "icons" );
w12_danger;
// ==================== |----------| ====================
// ==================== | w16_file | ====================
// ==================== |----------| ====================
var w16_file = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07k\x00\x00\x07k\x01\u00CE\u00B7sZ\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u0090IDAT8\u008Dc\u00DC\u00B8q\u00E3Q\x06\x06\x06+\x06\u00FC \fJg\u00FF\u00FC\u00F9\u00D3?,,\u00EC#L\u0082\u0089\b\u00CD\u00C8\u00C0\u009E\u0083\u0083c\u00EF\u0096-[\x04\u0091\r \t\u00FC\u00FF\u00FF\u00DF\u00F8\u00DF\u00BF\x7F\u00BBW\u00ADZ%D\u0096\x010C\u00D8\u00D9\u00D9w\u00AFZ\u00B5J\u0088,\x03\u00A0\u00C0\u0088\u009D\u009D}\x1D\x0B\u0091\u008A\u0099\u00FF\u00FC\u00F9s\u0084\u0085\u0085%\f]\u0082(\x03\u00FE\u00FF\u00FF\u009F\u00C7\u00CA\u00CA\u00CA\u00F8\u00FF\u00FF\u00FF?d\x19\u00C0\u00C8\u00C8h\u00F9\u00FF\u00FF\x7FKlr\u0094\u0084\u00C1\u00A8\x01\u0083\u00CA\u0080\u00A3\x14\u00E8?\x02\x00\u008B\u00BC-'\u00FCN\u00B0\u00CA\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_file.png", "icons" );
w16_file;
// ==================== |------------| ====================
// ==================== | w16_file_d | ====================
// ==================== |------------| ====================
var w16_file_d = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07k\x00\x00\x07k\x01\u00CE\u00B7sZ\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u0092IDAT8\u008D\u00ED\u00D0\u00B1\r\u00C20\x10F\u00E1\u00F7\x1F,@F!Uh\x18\u0081\u008E\x05\u009C&Bb\u00A0\f\u00C1\x02\x11]2\x10\u00B5\u0091\u008F*R\x14\x04\x04W\x14\u00BC\u00F6|\u009FNV]\u00D7\x03\u00B0\u00E3M\u00EE~\x04\u0090t2\u00B3C\u00DB\u00B6\u00B7qf\u009F\u0096g\u00EDSJ\u00D7\u00A6i6S\u00E0\u00DB\u00CA\x18c\x17B(r\x01\u0080RR\x17B(r\x01\u0080\u00AD\u00A4\u00CBz\u00C9K3[\u00B9{?~\u00E6\u00B4E\u0080\u00BB\u009F\x01\x01\u00F7,\x00\u00A8\u0080J\u00D2\u00F3u\x0B\u0081\u0097\u00FD\u0081_\x01\u0086\u00DCew\u00EF\x1F\u00FB\u00F1'KC\u00B6\u0093\u0086\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_file_d.png", "icons" );
w16_file_d;
// ==================== |---------| ====================
// ==================== | w16_fix | ====================
// ==================== |---------| ====================
var w16_fix = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\x1EIDAT8\u008D\u0095\u0091\u00B1J\x041\x10\u0086\u00FF\t\x07a\u00F1\x01|\x05\x11\x05[+\u00AFK\u00E3&\x0B\u00C2\u00956\u00B6W\u00A8\u008D\u00F7\bg\u00E5\u00E1\x1B\u00D8\u00AE\u0088\u0091h\u00B1\u009D\x07\u0096\u0082\u00D5\u00F9\x1A\u0082\u00B0\u00904\x13\u009B\x13\u00D6\u00F5n7\u00F7\u00973\u00F9\u00BE\x19&\u0084\rS\u0096e&\u00A5\u009C\u00C5\x18\u00BF\u008A\u00A2\u0098\u00D0&\u00B0sn\u0087\u0099K\x00\u00FB\x00\x10c\u00BC\x16\u00A9\u00B0\u00B5\u00F6\u0094\u0099\u00DF\x7F\u00E1e\u00B6\x07\u00A9\x02\"\u00BAk\u0095>\u00B3,\x1B'o\u00D0JMD#\u00A5T\u009D$\u00B0\u00D6N[\u00DB\u008C\u00B5\u00D6\x0B\x00\u00E8=\u00A2\u00B5vJDW\x00f\u00C6\u0098\u008Bv\u00BFS\u00E0\u009C+\u0098\u00F9\u0091\u0088n\u00B4\u00D6\u0097\u00AB\u00DE\u00FC\x11TU\u00B5\u00E5\u00BD\u00BF\x05`\x00,\x00\u009C\t!\u00F6\u00F2<\u00B7\u00EB\u0086P\x13\x0E!<\u00C7\x18\u0087\u008D\u00FE\u00DC\x183\u00FCG52hL~\x01p\u00D4\u00EA\u00EFv\u00C1\x00 :`\x10\u00D1S\u00AF\u00C0{\x7F\u00BF\x06~\u0095R\u009E\u00F7\n\x00\x1C\u00AC\u00A8\u00CF\u00A5\u0094\u00C7J\u00A9\u00BAW \u00848\x01\u00F0\u00DD\u00A8\u00BD\u0085\x10\u0092``\u00F9\x0B\u00CE\u00B9Cf~ \u00A2\x0F)\u00E5(\x15\x06\u0080\x1F\u00A1\u00D8hU\u00F50k\u0098\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_fix.png", "icons" );
w16_fix;
// ==================== |--------------| ====================
// ==================== | w16_live_fix | ====================
// ==================== |--------------| ====================
var w16_live_fix = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\u009DIDAT8\u008D\u008D\u0093=k\x14Q\x14\u0086\u009F\u00F7\x06\u00C6\u00D4\u0082\u00B5\u009D\u009D\u00C5\x0E\u00F8\x07\u00ACd\u00C3\u009D\x19\u008B@\x1AE$\u00A0\"h0\u00A2\u008D\u00E0h\n\u0083\x1FlH\u0097F\u0089V\x11\\\u00E7\u00CE\u00C8v\u00B2\x7F\u00C2? \u0096b\u00B3\u00D5\u00EA\u00C2\x1C\u009B\u0099e\u00D8(\u00BB\u00A7\u00B9\u0097\u00F7\u00DC\u00E7=\u00E7^\u00CE\u0085\u0085\u00C8\u00F3\u00DC\u0085\x10n/\u00EAf\u00A6\x10\u00C2\u00EB\u00B2,\x7F\u0085\x106Z\u00DD-\x1E\u008C\u00E3\u00F8:0\x18\x0E\u0087\x17\u00BApUU\x07\u00C0\u00AE\u0099\u009D\x05>\x15E\u00D1\x07P\u00B7r\x1C\u00C7Gf\u00B6\u00DDH\x7F$\u00DD\u00F2\u00DE\x1FWUu`f\u00F7\u00CC\u00EC\u009Bsn\u00CF\u00CC\u00DE\x01k\u0092\u00AE\u00BA\u008EA=\u009DN\u00EF\x02/\u0081\x1A\u00D8\u00F4\u00DE\x1F\u0097e9h\u00E1(\u008A.'I\u00F2\x11\u00B8\x01\u009C1\u00B3\x0F\u00F3\x0E\u00DA\x18\u008F\u00C7\u00EB\u0093\u00C9\u00E4E\u0092$\x0F\u00CA\u00B2\x1C\x00\u00F7\u00CD\u00EC{\x14E\u0097\u00FA\u00FD\u00FE\u00CF\u00D1htn6\u009B}\x05.\x02oN\x19\u00B4wn\u00E1F\u00AA\u00CDl;\u008A\u00A2/-,\u00E9\u00D0{\u00BFs\u00CA\u00E0\x1F0\x1D\u0093\x1F\u0092\u00CE\u00CFa\u00C9\u00B4\"<\x0FIG\u00DE\u00FB;\u0092\f`\u00AD\u009B\u00EC\u00F5z\u00FB\u0092vW\u0085\u00A13\x07EQ\u00ECKz\u00BC\n\x1CB\u00D8\u009B\x1B4\x136X\x02\x1Fv\u00E0M\u00E0I\u00B3\u00A2\u00A2(^Iz\u00B8\x04\u00DEi\u00E0\x1Cx\u00DAI?s\u00CE\u00B9\u009B\u00AB\u00C0\x00i\u009A\u00E6f\u00B6\x05`f[i\u009A\u00E6\u00AE\u00AE\u00EBk\u00C0\u00EFep\x1BY\u0096\u009DHz\u009Ee\u00D9\t4\x7F!\u0084p\x05\u00F8\f\u00AC/>\u00D8\u00FF\u00BA\u009B\x17j7!\u0084\rI\u00EF\u00EB\u00BA~\u009B\u00A6\u00E9\u00A3U`\u0080\u00BFqE\u00D9\u00BCQ\x18\u00D39\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_live_fix.png", "icons" );
w16_live_fix;
// ==================== |----------------| ====================
// ==================== | w16_live_fix_d | ====================
// ==================== |----------------| ====================
var w16_live_fix_d = new DuBinary( "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\x07a\x00\x00\x07a\x01\u0095\u00C3\u00B8\u00B6\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x01\u00A8IDAT8\u008D\u0095\u0093\u00BF\u008B\x13A\x18\u0086\u009Fw\u00B7\u00D0\x14\u00D7\bbi\u0091X\x1A\u0098t\u0082\u0095U\u00B0\x13\x11\u00CE\u00E2\u008A8\x1B\u0083\u0085z\u00A0`\u00E9\u00EA\x15\n\nwx\u0088\u00CAL\bVr\u0082\\cc!\u00A4\u00B0\x13\x19\u008B3\u00CD\u00D9\u00C8\u0096\u00FE\x05\n{cq\x1B\u008Dk\u00C2\u009DO\u00F9}\u00F3\u00BC\x1F\u00F3+\u00A5F\u009E\u00E7I\u00B3\u00D9\u00BC\x1AB\u00F8Tk)\u00CB\u00B2\u00C7\u009DN\u00E7\u00951\u00E6K\ba\x17 \u00A9\x07\x14E\u00B1\"ic0\x18\u009C\u00AA\u00C9\x1B\u00C0-\u00E0\u0098\u00A47Y\u0096\u009D\x07\u00D0\u00EC\u00E4\u00A2(\u009EK\u00EAW\u00A5\u009F\u0092\x06\u00CE\u00B9\u0097\u0095|\x03\u00D8\u0091\u00B4\x16c\x1C\x01\u00A9\u00A4\x0B\u00E94`<\x1E\u00C7V\u00AB\u00F5\u00AE\u00D1h\x1C\x01\u00CEH\u00BA\u00E8\u009C{m\u00AD]\u0097t\x13\u00D8)\u00CB\u00F2\u00DCp8\u00FCh\u008C\u00D9\u0095t\x19\u00E8\u00FE\x0E\x00\u0098L&e\u00BB\u00DD\u00FE\u0090$\u00C9\u0092\u00F7~sF\u00FEV\u0096\u00E5\u00D9\u00D1h\u00F4\u00BD\u00D7\u00EB\x1DO\u0092d\b\u009C\x00\u009E\u0089\u00F9hF\x06\u00D8\x03\u00B2\u00B2,\u00DF\u00A6i\u00FA\x1E8\r<\u00F1\u00DE\u00AF\u00CE\x0B\u00A8\u00CBS\u00F6\u0080\x0289\u0095\u0081X\x0FX$\u00FFY \u00BDp\u00CE]\x03\"\u00D4\u00AE\u00D1Z\u00FB\u00E0\x7F\u00E4\u00BF\x02\u00AC\u00B5\x0F%\u00DD9\u008Cl\u00AD]\u009B\u00D6S\u00F6\x1F\u00C9\u00BA\u00A4\u00DB\u008Bd\u00F6\u00F7|\u00BD\u0092/I\u00DA4\u00C6LB\b\x13\u00F5\u00FB\u00FDG1\u00C6\u0083\u00E4U fY\u0096\x03wgz\u00F7\u0092\x18\u00E3\u0095\u00C3\u00C8\x00\u00DE\u00FB\x1CX\u00AEz\u00CB\u00DE\u00FB<\x01V\u0080\x1F\x07\u00C9S\u00BC\u00F7[\u0092\u00EE{\u00EF\u00B7\u00A0\u00FA\x0B\u00D6\u00DA\u00AE\u00A4m\u00E0(\u00CC?\u00EDE\u00A4\x00!\u0084\u00AF\u00C6\u0098\u00CF\u0092\u00BA\u0092\u009E:\u00E7\u00FE\u0099\u00BC\u0088_X;\u00B1\u008F\teN\u00CC\x00\x00\x00\x00IEND\u00AEB`\u0082", "w16_live_fix_d.png", "icons" );
w16_live_fix_d;
// ==================== |------| ====================
// ==================== | core | ====================
// ==================== |------| ====================
/**
* The sanity levels.
* @enum {number}
* @readonly
*/
DuSanity.Level = {
UNKNOWN: -1,
OK: 0,
INFO: 1,
WARNING: 2,
DANGER: 3,
CRITICAL: 4,
FATAL: 5
}
/**
* The current sanity level
* @type {DuSanity.Level}
* @readonly
*/
DuSanity.currentLevel = DuSanity.Level.UNKNOWN;
/**
* Fixes the issues for the given test, if possible
* @param {DuSanity.Test} test The test to fix
* @return {DuSanity.Level} The level after the fix
*/
DuSanity.fix = function(test) {
if (!DuSanity.needsFix(test)) return test.currentLevel;
test.fix();
return test(true);
}
/**
* Checks if the the live fix is enabled for the given test
* @param {DuSanity.Test} test The test
* @return {boolean} True if the test live fix is enabled
*/
DuSanity.isLiveFixEnabled = function (test)
{
var fix = DuESF.settings.get("sanity/fix/" + test.stringId, false);
return fix && test.hasAutoFix;
}
/**
* Enables or disables the live fix for the given test
* @param {DuSanity.Test} test The test
* @param {boolean} [enabled=true]
*/
DuSanity.setLiveFixEnabled = function (test, enabled)
{
DuESF.settings.set("sanity/fix/" + test.stringId, enabled);
DuESF.settings.save();
}
/**
* Checks if the fiven test needs a fix
* @param {DuSanity.Test} test The test to fix
* @return {boolean} True if the test needs a fix
*/
DuSanity.needsFix = function ( test ) {
var liveFix = DuESF.settings.get("sanity/fix/" + test.stringId, false);
return liveFix && test.currentLevel >= DuSanity.Level.DANGER && test.hasFix;
}
/**
* Checks if the fiven test is enabled for the current project
* @param {DuSanity.Test} test The test
* @return {boolean} True if the test is enabled for the current project
*/
DuSanity.isProjectEnabled = function( test ) {
//Init project settings
DuAEProject.settings.update();
DuAEProject.settings.data.sanity = def(DuAEProject.settings.data.sanity, {});
DuAEProject.settings.data.sanity[test.stringId] = def(DuAEProject.settings.data.sanity[test.stringId], true);
return DuAEProject.settings.data.sanity[test.stringId];
}
/**
* Checks if the fiven test is globally enabled
* @param {DuSanity.Test} test The test
* @return {boolean} True if the test is enabled
*/
DuSanity.isGloballyEnabled = function (test)
{
return DuESF.settings.get("sanity/" + test.stringId, true);
}
/**
* Globally enables or disables the test
* @param {DuSanity.Test} test The test
* @param {boolean} [enabled=true]
*/
DuSanity.setGloballyEnabled = function (test, enabled)
{
DuESF.settings.set("sanity/" + test.stringId, enabled);
DuESF.settings.save();
}
/**
* Checks if a Sanity Test is enabled
* @param {DuSanity.Test} test The test
* @return {boolean}
*/
DuSanity.isEnabled = function(test)
{
var project = DuSanity.isProjectEnabled(test)
if (project)
{
//check DuAEF settings
test.enabled = DuSanity.isGloballyEnabled(test);
}
else
{
test.enabled = false;
}
return test.enabled;
}
/**
* Enables or disables the test
* @param {DuSanity.Test} test The test
* @param {boolean} [enabled=true]
*/
DuSanity.setEnabled = function (test, enabled)
{
if (enabled)
{
//First run
test();
test.enabled = true;
}
else
{
test.enabled = false;
}
}
/**
* Enables or disables the test for the current project only
* @param {DuSanity.Test} test The test
* @param {boolean} [enabled=true]
*/
DuSanity.setProjectEnabled = function (test, enabled)
{
//Init project settings
DuAEProject.settings.update();
DuAEProject.settings.data.sanity = def(DuAEProject.settings.data.sanity, {});
DuAEProject.settings.data.sanity[test.stringId] = enabled;
DuAEProject.settings.save();
}
/**
* Sets the timeout for the test
* @param {DuSanity.Test} test The test
* @param {int} timeOut The time out in milliseconds.
*/
DuSanity.setTimeOut = function (test, timeOut)
{
var enabled = test.enabled;
DuSanity.setEnabled(test, false);
DuESF.settings.set("sanity/timeOut/" + test.stringId, timeOut);
DuESF.settings.save();
DuSanity.setEnabled(test, enabled);
}
/**
* Runs a test
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
* @param {boolean} [force=false] To improve performance, the test may be automatically paused. Set this to true to force it to run if calling this method.
* @return {DuSanity.Level} The level of the result of the test.
*/
DuSanity.runTest = function(test, dontFix, force) {
dontFix = def(dontFix, false);
force = def(force, false);
var elapsed = Date.now() - test.lastRun;
var timedOut = elapsed > test.timeOut;
var result = test.currentLevel;
if (force || timedOut) {
result = test(dontFix, force);
test.lastRun = Date.now();
}
if(DuSanity.currentLevel < result) DuSanity.currentLevel = result;
return result;
}
//low-level undocumented function: checks a value against a limit and sets the results in the UI
//returns the level
DuSanity.checkLevel = function(value, limit)
{
if (value < limit*0.66)
{
return DuSanity.Level.OK;
}
if (value < limit*0.75)
{
return DuSanity.Level.INFO;
}
if (value < limit)
{
return DuSanity.Level.WARNING;
}
if (value < limit * 1.5)
{
return DuSanity.Level.DANGER;
}
return DuSanity.Level.CRITICAL;
}
/**
* All the available tests.
* @namespace
* @category DuSanity
*/
DuSanity.Test = {};
/**
* Checks if some compositions share the same name.
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
* @param {boolean} [force=false] To improve performance, this test may be automatically paused. Set this to true to force it to run if calling this method.
*/
DuSanity.Test.compNames = function ( dontFix, force ) {
dontFix = def(dontFix, false);
force = def(force, false);
if ( DuSanity.Test.projectSize.currentLevel > DuSanity.Level.WARNING ) {
DuSanity.Test.compNames.info = "Project too big";
DuSanity.Test.compNames.tip = "The project is too big to run this test automatically. Use the 'Refresh' button to run it now.";
DuSanity.Test.compNames.paused = true;
}
else if ( DuSanity.Test.projectItems.currentLevel > DuSanity.Level.WARNING ) {
DuSanity.Test.compNames.info = "Too many items";
DuSanity.Test.compNames.tip = "The project contains too many items to run this test automatically.\nUse the 'Refresh' button to run it now.";
DuSanity.Test.compNames.paused = true;
}
else {
DuSanity.Test.compNames.paused = false;
}
if (!force && DuSanity.Test.compNames.paused) {
DuSanity.Test.compNames.currentLevel = DuSanity.Level.UNKNOWN;
return DuSanity.Test.compNames.currentLevel;
}
var duplicatedNames = DuAEProject.checkCompNames();
if (duplicatedNames.length == 0)
{
DuSanity.Test.compNames.info = "";
DuSanity.Test.compNames.tip = "";
DuSanity.Test.compNames.currentLevel = DuSanity.Level.OK;
}
else
{
DuSanity.Test.compNames.info = duplicatedNames.length;
DuSanity.Test.compNames.tip = "Some compositions have the same name:";
for (name in duplicatedNames)
{
if (name == 'length') continue;
if (duplicatedNames.hasOwnProperty(name))
{
DuSanity.Test.compNames.tip += "\n- " + name;
}
}
DuSanity.Test.compNames.currentLevel = DuSanity.Level.DANGER;
}
if (dontFix) return DuSanity.Test.compNames.currentLevel;
return DuSanity.fix( DuSanity.Test.compNames );
}
DuSanity.Test.compNames.lastRun = 0;
DuSanity.Test.compNames.stringId = 'compNames';
DuSanity.Test.compNames.info = '';
DuSanity.Test.compNames.tip = '';
DuSanity.Test.compNames.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.compNames.enabled = true;
DuSanity.Test.compNames.id = 0;
DuSanity.Test.compNames.hasFix = true;
DuSanity.Test.compNames.hasAutoFix = true;
DuSanity.Test.compNames.timeOut = 600000;
DuSanity.Test.compNames.paused = false;
DuSanity.Test.compNames.testName = ""; // Added during init
DuSanity.Test.compNames.options = {}; // Added during init
DuSanity.Test.compNames.fix = function() {
DuAE.beginUndoGroup( i18n._("Fix") + ': ' + DuSanity.Test.compNames.testName);
var duplicatedNames = DuAEProject.checkCompNames();
for (name in duplicatedNames)
{
if (name == 'length') continue;
if (duplicatedNames.hasOwnProperty(name))
{
DuAEProject.setUniqueCompNames( duplicatedNames[name] );
}
}
DuAE.endUndoGroup();
}
/**
* Checks if some layers share the same name in the current comp.
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
*/
DuSanity.Test.layerNames = function ( dontFix ) {
dontFix = def(dontFix, false);
var duplicatedNames = DuAEComp.checkLayerNames();
if (duplicatedNames.length == 0)
{
DuSanity.Test.layerNames.info = ""
DuSanity.Test.layerNames.tip = ""
DuSanity.Test.layerNames.currentLevel = DuSanity.Level.OK;
}
else
{
DuSanity.Test.layerNames.info = duplicatedNames.length;
DuSanity.Test.layerNames.tip = "Some layers have the same name:";
for (name in duplicatedNames)
{
if (name == 'length') continue;
if (duplicatedNames.hasOwnProperty(name))
{
DuSanity.Test.layerNames.tip += "\n- " + name;
for (var i = 0, n = duplicatedNames[name].length; i < n; i++)
{
DuSanity.Test.layerNames.tip += " | " + duplicatedNames[name][i].index;
}
}
}
DuSanity.Test.layerNames.currentLevel = DuSanity.Level.DANGER;
}
if (dontFix) return DuSanity.Test.layerNames.currentLevel;
return DuSanity.fix( DuSanity.Test.layerNames );
}
DuSanity.Test.layerNames.lastRun = 0;
DuSanity.Test.layerNames.stringId = 'layerNames';
DuSanity.Test.layerNames.info = '';
DuSanity.Test.layerNames.tip = '';
DuSanity.Test.layerNames.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.layerNames.enabled = true;
DuSanity.Test.layerNames.id = 0;
DuSanity.Test.layerNames.hasFix = true;
DuSanity.Test.layerNames.hasAutoFix = true;
DuSanity.Test.layerNames.timeOut = 60000;
DuSanity.Test.layerNames.testName = ""; // Added during init
DuSanity.Test.layerNames.options = {}; // Added during init
DuSanity.Test.layerNames.fix = function() {
DuAE.beginUndoGroup( i18n._("Fix") + ': ' + DuSanity.Test.layerNames.testName);
var duplicatedNames = DuAEComp.checkLayerNames();
for (name in duplicatedNames)
{
if (name == 'length') continue;
if (duplicatedNames.hasOwnProperty(name))
{
DuAEComp.setUniqueLayerNames( duplicatedNames[name] );
}
}
DuAE.endUndoGroup();
}
/**
* Checks the expression engine.
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
*/
DuSanity.Test.expressionEngine = function ( dontFix ) {
dontFix = def(dontFix, false);
var e = DuAEProject.expressionEngine();
if (e.indexOf("javascript") == 0)
{
DuSanity.Test.expressionEngine.info = "";
DuSanity.Test.expressionEngine.tip = "";
DuSanity.Test.expressionEngine.currentLevel = DuSanity.Level.OK;
}
else
{
DuSanity.Test.expressionEngine.info = "ES";
DuSanity.Test.expressionEngine.tip = "The expression engine is set to 'ExtendScript Legacy'\n'JavaScript' improves performance, you can change it in the project settings.";
DuSanity.Test.expressionEngine.currentLevel = DuSanity.Level.DANGER;
}
if (dontFix) return DuSanity.Test.expressionEngine.currentLevel;
return DuSanity.fix( DuSanity.Test.expressionEngine );
}
DuSanity.Test.expressionEngine.lastRun = 0;
DuSanity.Test.expressionEngine.stringId = 'expressionEngine';
DuSanity.Test.expressionEngine.info = '';
DuSanity.Test.expressionEngine.tip = '';
DuSanity.Test.expressionEngine.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.expressionEngine.enabled = true;
DuSanity.Test.expressionEngine.id = 0;
DuSanity.Test.expressionEngine.hasFix = true;
DuSanity.Test.expressionEngine.hasAutoFix = true;
DuSanity.Test.expressionEngine.timeOut = 1800000;
DuSanity.Test.expressionEngine.testName = ""; // Added during init
DuSanity.Test.expressionEngine.options = {}; // Added during init
DuSanity.Test.expressionEngine.fix = function() {
DuAE.beginUndoGroup( i18n._("Fix") + ': ' + DuSanity.Test.expressionEngine.testName);
app.project.expressionEngine = 'javascript-1.0';
DuAE.endUndoGroup();
}
/**
* Checks the project size
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
*/
DuSanity.Test.projectSize = function ( dontFix ) {
dontFix = def(dontFix, false);
var size = DuAEProject.getSize();
var sizeLimit = DuESF.settings.get("sanity/options/" + DuSanity.Test.projectSize.stringId + "/sizeLimit", 100) * 1000000;
if (size < 0 && app.project.numItems > 0)
{
DuSanity.Test.projectSize.info = "Not saved";
DuSanity.Test.projectSize.tip = "You should save this project right now!";
DuSanity.Test.projectSize.currentLevel = DuSanity.Level.FATAL;
return DuSanity.Test.projectSize.currentLevel;
}
else if (size < 0)
{
DuSanity.Test.projectSize.info = "";
DuSanity.Test.projectSize.tip = "";
DuSanity.Test.projectSize.currentLevel = DuSanity.Level.OK;
}
else
{
DuSanity.Test.projectSize.info = DuString.fromSize(size);
DuSanity.Test.projectSize.tip = "Try to keep the project small (e.g. do not animate several shots in the same project).";
DuSanity.Test.projectSize.currentLevel = DuSanity.checkLevel(size, sizeLimit);
}
if (dontFix) return DuSanity.Test.projectSize.currentLevel;
return DuSanity.fix( DuSanity.Test.projectSize );
}
DuSanity.Test.projectSize.lastRun = 0;
DuSanity.Test.projectSize.stringId = 'projectSize';
DuSanity.Test.projectSize.info = '';
DuSanity.Test.projectSize.tip = '';
DuSanity.Test.projectSize.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.projectSize.enabled = true;
DuSanity.Test.projectSize.id = 0;
DuSanity.Test.projectSize.hasFix = false;
DuSanity.Test.projectSize.hasAutoFix = false;
DuSanity.Test.projectSize.testName = ""; // Added during init
DuSanity.Test.projectSize.options = {}; // Added during init
DuSanity.Test.projectSize.timeOut = 60000;
/**
* Checks the project size
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
*/
DuSanity.Test.projectItems = function ( dontFix ) {
dontFix = def(dontFix, false);
var n = app.project.numItems;
var limit = DuESF.settings.get("sanity/options/" + DuSanity.Test.projectItems.stringId + "/itemsLimit", 1000);
DuSanity.Test.projectItems.info = n + " items";
DuSanity.Test.projectItems.tip = "Try to keep the project small (e.g. do not animate several shots in the same project).";
DuSanity.Test.projectItems.currentLevel = DuSanity.checkLevel(n, limit);
if (dontFix) return DuSanity.Test.projectItems.currentLevel;
return DuSanity.fix( DuSanity.Test.projectItems );
}
DuSanity.Test.projectItems.lastRun = 0;
DuSanity.Test.projectItems.stringId = 'projectItems';
DuSanity.Test.projectItems.info = '';
DuSanity.Test.projectItems.tip = '';
DuSanity.Test.projectItems.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.projectItems.enabled = true;
DuSanity.Test.projectItems.id = 0;
DuSanity.Test.projectItems.hasFix = false;
DuSanity.Test.projectItems.hasAutoFix = false;
DuSanity.Test.projectItems.testName = ""; // Added during init
DuSanity.Test.projectItems.options = {}; // Added during init
DuSanity.Test.projectItems.timeOut = 600000;
/**
* Checks if some items have the same source file
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
* @param {boolean} [force=false] To improve performance, this test may be automatically paused. Set this to true to force it to run if calling this method.
*/
DuSanity.Test.itemSources = function ( dontFix, force ) {
dontFix = def(dontFix, false);
force = def(force, false);
if ( DuSanity.Test.projectSize.currentLevel > DuSanity.Level.WARNING ) {
DuSanity.Test.itemSources.info = "Project too big";
DuSanity.Test.itemSources.tip = "The project is too big to run this test automatically. Use the 'Refresh' button to run it now.";
DuSanity.Test.itemSources.paused = true;
}
else if ( DuSanity.Test.projectItems.currentLevel > DuSanity.Level.WARNING ) {
DuSanity.Test.itemSources.info = "Too many items";
DuSanity.Test.itemSources.tip = "The project contains too many items to run this test automatically.\nUse the 'Refresh' button to run it now.";
DuSanity.Test.itemSources.paused = true;
}
else {
DuSanity.Test.itemSources.paused = false;
}
if (!force && DuSanity.Test.itemSources.paused) {
DuSanity.Test.itemSources.currentLevel = DuSanity.Level.UNKNOWN;
return DuSanity.Test.itemSources.currentLevel;
}
var duplicatedSources = {};
duplicatedSources.length = 0;
var sources = {};
for (var i = 1, n = app.project.numItems; i <= n; i++)
{
var item = app.project.item(i);
if (!(item instanceof FootageItem)) continue;
var source = item.mainSource;
if (!(source instanceof FileSource)) continue;
var file = source.file.fsName;
if (DuAE.isLayeredFile(file)) continue;
if (duplicatedSources[file])
{
duplicatedSources[file].push(item);
continue;
}
if ( sources[file])
{
duplicatedSources[file] = [sources[file], item];
duplicatedSources.length++;
continue;
}
sources[file] = item;
}
if (duplicatedSources.length == 0)
{
DuSanity.Test.itemSources.info = "";
DuSanity.Test.itemSources.tip = "";
DuSanity.Test.itemSources.currentLevel = DuSanity.Level.OK;
}
else
{
DuSanity.Test.itemSources.info = duplicatedSources.length + " items";
DuSanity.Test.itemSources.tip = "Some footages share the same sources:";
for (var file in duplicatedSources)
{
if (file == 'length') continue;
if (duplicatedSources.hasOwnProperty(file))
{
DuSanity.Test.itemSources.tip += "\n- " + file;
}
}
DuSanity.Test.itemSources.currentLevel = DuSanity.Level.DANGER;
}
if (dontFix) return DuSanity.Test.itemSources.currentLevel;
return DuSanity.fix( DuSanity.Test.itemSources );
}
DuSanity.Test.itemSources.lastRun = 0;
DuSanity.Test.itemSources.stringId = 'itemSources';
DuSanity.Test.itemSources.info = '';
DuSanity.Test.itemSources.tip = '';
DuSanity.Test.itemSources.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.itemSources.enabled = true;
DuSanity.Test.itemSources.id = 0;
DuSanity.Test.itemSources.hasFix = false;
DuSanity.Test.itemSources.hasAutoFix = false;
DuSanity.Test.itemSources.timeOut = 1800000;
DuSanity.Test.itemSources.testName = ""; // Added during init
DuSanity.Test.itemSources.options = {}; // Added during init
DuSanity.Test.itemSources.paused = false;
/**
* Checks if some items (footages) are not used
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
*/
DuSanity.Test.unusedItems = function ( dontFix ) {
dontFix = def(dontFix, false);
var limit = 10;
var unused = DuAEProject.getUnusedFootages();
DuSanity.Test.unusedItems.currentLevel = DuSanity.checkLevel(unused.length, limit);
if (DuSanity.Test.unusedItems.currentLevel > DuSanity.Level.OK)
{
DuSanity.Test.unusedItems.info = unused.length + " footages";
DuSanity.Test.unusedItems.tip = "Found some footages which are unused. You should remove them.";
for (var i = 0, n = unused.length; i < n; i++)
{
DuSanity.Test.unusedItems.tip += "\n- " + unused[i].name;
}
}
else
{
DuSanity.Test.unusedItems.info = "";
DuSanity.Test.unusedItems.tip = "";
}
if (dontFix) return DuSanity.Test.unusedItems.currentLevel;
return DuSanity.fix( DuSanity.Test.unusedItems );
}
DuSanity.Test.unusedItems.lastRun = 0;
DuSanity.Test.unusedItems.stringId = 'unusedItems';
DuSanity.Test.unusedItems.info = '';
DuSanity.Test.unusedItems.tip = '';
DuSanity.Test.unusedItems.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.unusedItems.enabled = true;
DuSanity.Test.unusedItems.id = 0;
DuSanity.Test.unusedItems.hasFix = true;
DuSanity.Test.unusedItems.hasAutoFix = true;
DuSanity.Test.unusedItems.timeOut = 1800000;
DuSanity.Test.unusedItems.testName = ""; // Added during init
DuSanity.Test.unusedItems.options = {}; // Added during init
DuSanity.Test.unusedItems.fix = function () {
DuAE.beginUndoGroup( i18n._("Fix") + ': ' + DuSanity.Test.unusedItems.testName);
var unused = DuAEProject.getUnusedFootages();
for (var i = unused.length-1; i >= 0; i--)
{
unused[i].remove();
}
DuAE.endUndoGroup();
};
/**
* Checks if some precomps are in the root of the project
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
*/
DuSanity.Test.precomps = function ( dontFix ) {
dontFix = def(dontFix, false);
var precomps = DuAEProject.getPrecompsAtRoot();
var limit = DuESF.settings.get("sanity/options/" + DuSanity.Test.precomps.stringId + "/maxPrecompsAtRoot", 1);
DuSanity.Test.precomps.currentLevel = DuSanity.checkLevel(precomps.length, limit);
DuSanity.Test.precomps.tip = "";
DuSanity.Test.precomps.info = "";
if (DuSanity.Test.precomps.currentLevel > DuSanity.Level.OK)
{
DuSanity.Test.precomps.info = precomps.length + " comps";
DuSanity.Test.precomps.tip = "Some precompositions are at the root of the project.\n" +
"They should be moved in a subfolder.";
for (var i = 0, n = precomps.length; i<n; i++)
{
DuSanity.Test.precomps.tip += "\n- " + precomps[i].name;
}
}
if (dontFix) return DuSanity.Test.precomps.currentLevel;
return DuSanity.fix( DuSanity.Test.precomps );
}
DuSanity.Test.precomps.lastRun = 0;
DuSanity.Test.precomps.stringId = 'precomps';
DuSanity.Test.precomps.info = '';
DuSanity.Test.precomps.tip = '';
DuSanity.Test.precomps.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.precomps.enabled = true;
DuSanity.Test.precomps.id = 0;
DuSanity.Test.precomps.hasFix = true;
DuSanity.Test.precomps.hasAutoFix = true;
DuSanity.Test.precomps.timeOut = 600000;
DuSanity.Test.precomps.testName = ""; // Added during init
DuSanity.Test.precomps.options = {}; // Added during init
DuSanity.Test.precomps.fix = function () {
DuAE.beginUndoGroup( i18n._("Fix") + ': ' + DuSanity.Test.precomps.testName);
var precomps = DuAEProject.getPrecompsAtRoot();
var precompFolderName = DuESF.settings.get("sanity/options/" + DuSanity.Test.precomps.stringId + "/precompsFolder", "Precomps");
var precompFolder = DuAEProject.getFolderItem( precompFolderName );
if (!precompFolder) precompFolder = app.project.items.addFolder(precompFolderName);
for (var i = 0, n = precomps.length; i < n; i++)
{
precomps[i].parentFolder = precompFolder;
}
DuAE.endUndoGroup();
};
/**
* Checks if there are multiple comps in the root of the project
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
*/
DuSanity.Test.unusedComps = function ( dontFix ) {
dontFix = def(dontFix, false);
var folderName = DuESF.settings.get("sanity/options/" + DuSanity.Test.unusedComps.stringId + "/mainCompsFolder", "" );
if (folderName == 'Project root') folderName = '';
var unusedFolder = DuAEProject.getFolderItem( folderName );
var comps = DuAEProject.getUnusedComps(unusedFolder);
var limit = DuESF.settings.get("sanity/options/" + DuSanity.Test.unusedComps.stringId + "/maxUnusedComps", 1);
DuSanity.Test.unusedComps.currentLevel = DuSanity.checkLevel(comps.length, limit);
DuSanity.Test.unusedComps.tip = "";
DuSanity.Test.unusedComps.info = "";
if (DuSanity.Test.unusedComps.currentLevel > DuSanity.Level.OK)
{
DuSanity.Test.unusedComps.info = comps.length + " comps";
DuSanity.Test.unusedComps.tip = "Some main compositions are stored in subfolders.\n" +
"It is easier to keep them at the root of the project, or they should be removed if they're not needed anymore.";
for (var i = 0, n = comps.length; i<n; i++)
{
DuSanity.Test.unusedComps.tip += "\n- " + comps[i].name;
}
}
if (dontFix) return DuSanity.Test.unusedComps.currentLevel;
return DuSanity.fix( DuSanity.Test.unusedComps );
}
DuSanity.Test.unusedComps.lastRun = 0;
DuSanity.Test.unusedComps.stringId = 'unusedComps';
DuSanity.Test.unusedComps.info = '';
DuSanity.Test.unusedComps.tip = '';
DuSanity.Test.unusedComps.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.unusedComps.enabled = true;
DuSanity.Test.unusedComps.id = 0;
DuSanity.Test.unusedComps.hasFix = true;
DuSanity.Test.unusedComps.hasAutoFix = false;
DuSanity.Test.unusedComps.timeOut = 1800000;
DuSanity.Test.unusedComps.testName = ""; // Added during init
DuSanity.Test.unusedComps.options = {}; // Added during init
DuSanity.Test.unusedComps.fix = function () {
var unusedFolderName = DuESF.settings.get("sanity/options/" + DuSanity.Test.unusedComps.stringId + "/mainCompsFolder", "Project root");
var unusedFolder = DuAEProject.getFolderItem( unusedFolderName );
var comps = DuAEProject.getUnusedComps(unusedFolder);
if (comps.length > 0)
{
var dlg = DuScriptUI.popUp("Fix Unused Compositions", 'column', true);
DuScriptUI.staticText(dlg.content, comps.length + " seemingly unused comps. have been found in this project.\nWhat do you want to do with them?");
var slctr = DuScriptUI.selector(dlg.content);
slctr.addButton("Remove unused compositions");
slctr.addButton("Collect unused comps. into folder:");
slctr.setCurrentIndex(1);
var folderEdit = DuScriptUI.editText(dlg.content,unusedFolderName, undefined, undefined, "Project Root");
folderEdit.alignment = ['fill','top'];
var validGrp = DuScriptUI.group(dlg.content, 'row');
validGrp.alignment = ['fill','bottom'];
var cnclBtn = DuScriptUI.button(validGrp, "Cancel");
var okBtn = DuScriptUI.button(validGrp, "Fix");
slctr.onChange = function() {
folderEdit.enabled = slctr.index == 1;
}
cnclBtn.onClick = dlg.cancel;
okBtn.onClick = function() {
DuAE.beginUndoGroup( i18n._("Fix") + ': ' + DuSanity.Test.unusedComps.testName);
if (slctr.index == 1)
{
var unusedFolderName = folderEdit.text;
var unusedFolder = DuAEProject.getFolderItem( unusedFolderName );
if (!unusedFolder)
{
unusedFolder = app.project.items.addFolder(unusedFolderName);
}
for (var i = 0, n = comps.length; i < n ; i++)
{
comps[i].parentFolder = unusedFolder;
}
}
else
{
for (var i = 0, n = comps.length; i < n ; i++)
{
comps[i].remove();
}
}
DuAE.endUndoGroup();
dlg.cancel();
};
dlg.show();
}
};
/**
* Checks the memory in use
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
*/
DuSanity.Test.memory = function ( dontFix ) {
dontFix = def(dontFix, false);
var mem = app.memoryInUse ;
var limit = DuESF.settings.get("sanity/options/" + DuSanity.Test.memory.stringId + "/memoryLimit", 8) * 1073741824;
DuSanity.Test.memory.info = DuString.fromSize(mem);
DuSanity.Test.memory.tip = "If the memory used gets too high, it may be good to purge the cache and free some space.";
DuSanity.Test.memory.currentLevel = DuSanity.checkLevel(mem, limit);
if (dontFix) return DuSanity.Test.memory.currentLevel;
return DuSanity.fix( DuSanity.Test.memory );
}
DuSanity.Test.memory.lastRun = 0;
DuSanity.Test.memory.stringId = 'memory';
DuSanity.Test.memory.info = '';
DuSanity.Test.memory.tip = '';
DuSanity.Test.memory.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.memory.enabled = true;
DuSanity.Test.memory.id = 0;
DuSanity.Test.memory.hasFix = true;
DuSanity.Test.memory.hasAutoFix = false;
DuSanity.Test.memory.timeOut = 300000;
DuSanity.Test.memory.testName = ""; // Added during init
DuSanity.Test.memory.options = {}; // Added during init
DuSanity.Test.memory.fix = function() {
app.purge(PurgeTarget.SNAPSHOT_CACHES);
app.purge(PurgeTarget.IMAGE_CACHES);
var ok = confirm("We've purged what can be purged without impacting your workflow. We can now purge more memory, but you will lose your undo history.\n\nDo you want to continue?");
if (ok) {
app.purge(PurgeTarget.UNDO_CACHES);
app.purge(PurgeTarget.ALL_CACHES);
}
DuSanity.Test.memory();
}
/**
* Checks the number of essential properties in the current comp
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
*/
DuSanity.Test.essentialProperties = function ( dontFix ) {
dontFix = def(dontFix, false);
var n = DuAEComp.numMasterProperties();
var limit = DuESF.settings.get("sanity/options/" + DuSanity.Test.essentialProperties.stringId + "/maxEssentialProps", 40);
DuSanity.Test.essentialProperties.info = n;
DuSanity.Test.essentialProperties.tip = "Having a lot of Master Properties in the current composition has a very bad impact on performance.";
DuSanity.Test.essentialProperties.currentLevel = DuSanity.checkLevel(n, limit);
if (dontFix) return DuSanity.Test.essentialProperties.currentLevel;
return DuSanity.fix( DuSanity.Test.essentialProperties );
}
DuSanity.Test.essentialProperties.lastRun = 0;
DuSanity.Test.essentialProperties.stringId = 'essentialProperties';
DuSanity.Test.essentialProperties.info = '';
DuSanity.Test.essentialProperties.tip = '';
DuSanity.Test.essentialProperties.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.essentialProperties.enabled = true;
DuSanity.Test.essentialProperties.id = 0;
DuSanity.Test.essentialProperties.hasFix = false;
DuSanity.Test.essentialProperties.hasAutoFix = false;
DuSanity.Test.essentialProperties.timeOut = 300000;
DuSanity.Test.essentialProperties.testName = ""; // Added during init
DuSanity.Test.essentialProperties.options = {}; // Added during init
/**
* Checks the elapsed time since last save
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
*/
DuSanity.Test.save = function ( dontFix ) {
dontFix = def(dontFix, false);
var proj = app.project;
var f = app.project.file;
var limit = DuESF.settings.get("sanity/options/" + DuSanity.Test.save.stringId + "/timeout", 30) * 60000;
if (!app.project.dirty) {
DuSanity.Test.save.info = "";
DuSanity.Test.save.tip = "";
DuSanity.Test.save.currentLevel = DuSanity.Level.OK;
return DuSanity.Test.save.currentLevel;
}
if (!(f instanceof File) && app.project.numItems > 0)
{
DuSanity.Test.save.info = "Not saved";
DuSanity.Test.save.tip = "This project has not been saved yet. You should save it right now!";
DuSanity.Test.save.currentLevel = DuSanity.Level.FATAL;
return DuSanity.Test.save.currentLevel;
}
else if (!(f instanceof File))
{
DuSanity.Test.save.info = "";
DuSanity.Test.save.tip = "";
DuSanity.Test.save.currentLevel = DuSanity.Level.OK;
return DuSanity.Test.save.currentLevel;
}
if (!f.exists)
{
DuSanity.Test.save.info = "Missing file";
DuSanity.Test.save.tip = "It looks like the file for this project has disappeared. You should save it right now!";
DuSanity.Test.save.currentLevel = DuSanity.Level.FATAL;
return DuSanity.Test.save.currentLevel;
}
var date = f.modified.getTime();
var now = new Date().getTime();
var elapsed = now - date;
var elapsedStr = Math.round(elapsed/60000) + "mn";
DuSanity.Test.save.info = elapsedStr;
DuSanity.Test.save.tip = "You should save the project regularly.";
DuSanity.Test.save.currentLevel = DuSanity.checkLevel(elapsed, limit);
if (dontFix) return DuSanity.Test.save.currentLevel;
return DuSanity.fix( DuSanity.Test.save );
}
DuSanity.Test.save.lastRun = 0;
DuSanity.Test.save.stringId = 'save';
DuSanity.Test.save.info = '';
DuSanity.Test.save.tip = '';
DuSanity.Test.save.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.save.enabled = true;
DuSanity.Test.save.id = 0;
DuSanity.Test.save.hasFix = true;
DuSanity.Test.save.hasAutoFix = true;
DuSanity.Test.save.timeOut = 900000;
DuSanity.Test.save.testName = ""; // Added during init
DuSanity.Test.save.options = {}; // Added during init
DuSanity.Test.save.fix = function() {
app.project.save();
}
/**
* Checks the up time of After Effects
* @param {boolean} [dontFix=false] If false, will automatically fix the issue.
*/
DuSanity.Test.upTime = function ( dontFix ) {
dontFix = def(dontFix, false);
var limit = DuESF.settings.get("sanity/options/" + DuSanity.Test.upTime.stringId +"/timeout", 180);
$.global.DuSan = def($.global.DuSan, {});
$.global.DuSan.AEStartTime = def($.global.DuSan.AEStartTime, Date.now());
// Check time elapsed and convert to minutes
var elapsed = Date.now() - $.global.DuSan.AEStartTime;
elapsed /= 60000;
elapsed = Math.round(elapsed);
DuSanity.Test.upTime.currentLevel = DuSanity.checkLevel(elapsed, limit);
DuSanity.Test.upTime.info = elapsed + ' mn';
DuSanity.Test.upTime.tip = "When After Effects stays up for too long, it gets tired.\n\nRestarting After Effects regularly helps keep the memory usage low and improves performance.";
if (dontFix) return DuSanity.Test.upTime.currentLevel;
return DuSanity.fix( DuSanity.Test.upTime );
}
DuSanity.Test.upTime.lastRun = 0;
DuSanity.Test.upTime.stringId = 'upTime';
DuSanity.Test.upTime.info = '';
DuSanity.Test.upTime.tip = '';
DuSanity.Test.upTime.currentLevel = DuSanity.Level.UNKNOWN;
DuSanity.Test.upTime.enabled = true;
DuSanity.Test.upTime.id = 0;
DuSanity.Test.upTime.hasFix = true;
DuSanity.Test.upTime.hasAutoFix = false;
DuSanity.Test.upTime.timeOut = 900000;
DuSanity.Test.upTime.testName = ""; // Added during init
DuSanity.Test.upTime.options = {}; // Added during init
DuSanity.Test.upTime.fix = function() {
app.quit();
}
// ==================== |----------| ====================
// ==================== | scriptui | ====================
// ==================== |----------| ====================
/**
* UI tools to show sanity levels and settings
* @namespace
* @memberof DuSanity
* @category DuSanity
*/
DuSanity.UI = {}
// The list of icons and labels in the ui, kept to update them
DuSanity.UI.items = [];
/**
* Creates an icon to show the current sanity level
* @param {Group} container A ScriptUI group where to add the icon
* @param {boolean} [addLabel=true] Adds a label next to the icon
* @param {boolean} [autoUpdate=true] If true, the icon will be automatically updated according to the current sanity level. Otherwise, call setLevel to change the level.
* @return {Group} The ScriptUI Group containing the icon and its label
*/
DuSanity.UI.icon = function( container, addLabel, autoUpdate ) {
addLabel = def(addLabel, true);
autoUpdate = def(autoUpdate, true);
// Add status
var statusGroup = DuScriptUI.group(container, 'row');
statusGroup.spacing = 3;
var statusIconGroup = DuScriptUI.group(statusGroup, 'stacked');
statusIconGroup.alignment = ['left', 'center'];
var statusUnknownIcon = statusIconGroup.add('image', undefined, w12_check.binAsString );
statusUnknownIcon.helpTip = i18n._("Sanity status: Unknown");
var statusOKIcon = statusIconGroup.add('image', undefined, w12_check_g.binAsString );
statusOKIcon.helpTip = i18n._("Sanity status: OK");
var statusInfoIcon = statusIconGroup.add('image', undefined, w12_information.binAsString );
statusInfoIcon.helpTip = i18n._("Sanity status: Information");
var statusWarningIcon = statusIconGroup.add('image', undefined, w12_warning.binAsString );
statusWarningIcon.helpTip = i18n._("Sanity status: Warning");
var statusDangerIcon = statusIconGroup.add('image', undefined, w12_danger.binAsString );
statusDangerIcon.helpTip = i18n._("Sanity status: Danger");
var statusCriticalIcon = statusIconGroup.add('image', undefined, w12_critical.binAsString );
statusCriticalIcon.helpTip = i18n._("Sanity status: Critical");
var statusFatalIcon = statusIconGroup.add('image', undefined, w12_fatal.binAsString );
statusFatalIcon.helpTip = i18n._("Sanity status: Fatal");
statusIconGroup.setLevel = function( level ) {
statusUnknownIcon.visible = level == DuSanity.Level.UNKNOWN;
statusOKIcon.visible = level == DuSanity.Level.OK;
statusInfoIcon.visible = level == DuSanity.Level.INFO;
statusWarningIcon.visible = level == DuSanity.Level.WARNING;
statusDangerIcon.visible = level == DuSanity.Level.DANGER;
statusCriticalIcon.visible = level == DuSanity.Level.CRITICAL;
statusFatalIcon.visible = level == DuSanity.Level.FATAL;
};
if (addLabel) {
var statusLabel = DuScriptUI.staticText( statusGroup, {
text: i18n._("OK"),
color: DuColor.Color.LIGHT_GREEN
});
statusLabel.alignment = ['fill', 'center'];
statusLabel.setLevel = function( level ) {
if (level == DuSanity.Level.UNKNOWN) {
statusLabel.text = i18n._("Unknown");
DuScriptUI.setTextColor( statusLabel, DuColor.Color.APP_TEXT_COLOR.darker());
}
else if (level == DuSanity.Level.OK) {
statusLabel.text = i18n._("OK");
DuScriptUI.setTextColor( statusLabel, DuColor.Color.LIGHT_GREEN);
}
else if (level == DuSanity.Level.INFO) {
statusLabel.text = i18n._("Information");
DuScriptUI.setTextColor( statusLabel, DuColor.Color.LIGHT_BLUE);
}
else if (level == DuSanity.Level.WARNING) {
statusLabel.text = i18n._("Warning");
DuScriptUI.setTextColor( statusLabel, DuColor.Color.YELLOW);
}
else if (level == DuSanity.Level.DANGER) {
statusLabel.text = i18n._("Danger");
DuScriptUI.setTextColor( statusLabel, DuColor.Color.ORANGE);
}
else if (level == DuSanity.Level.CRITICAL) {
statusLabel.text = i18n._("Critical");
DuScriptUI.setTextColor( statusLabel, DuColor.Color.RAINBOX_RED);
}
else if (level == DuSanity.Level.FATAL) {
statusLabel.text = i18n._("Fatal");
DuScriptUI.setTextColor( statusLabel, DuColor.Color.RX_PURPLE);
}
};
}
statusGroup.setLevel = function( level ) {
if (addLabel) statusLabel.setLevel( level );
statusIconGroup.setLevel( level );
}
statusGroup.setInfo = function( info ) {
if (!addLabel) return;
if (info != "") statusLabel.text = statusLabel.text + ' - ' + info;
}
statusGroup.setHelpTip = function( tip ) {
if (addLabel) statusLabel.helpTip = tip;
}
statusGroup.setLevel(DuSanity.Level.UNKNOWN);
if (autoUpdate) DuSanity.UI.items.push(statusGroup);
return statusGroup;
}
/**
* Creates a button to show the current sanity level
* @param {Group} container A ScriptUI group where to add the button
* @param {boolean} [addLabel=true] Adds a label next to the icon
* @param {boolean} [autoUpdate=true] If true, the button will be automatically updated according to the current sanity level. Otherwise, call setLevel to change the level.
* @return {DuButton} The DuButton
*/
DuSanity.UI.button = function( container, addLabel, autoUpdate ) {
addLabel = def(addLabel, true);
autoUpdate = def(autoUpdate, true);
var options = {};
if (addLabel) options.text = i18n._("Unknown");
else options.text = '';
options.image = w12_check;
options.helpTip = i18n._("Sanity status: Unknown");
var button = DuScriptUI.button( container, options);
button.setLevel = function( level ) {
if (level == DuSanity.Level.UNKNOWN) {
button.setText( i18n._("Unknown") );
button.setTextColor( DuColor.Color.APP_TEXT_COLOR.darker());
button.setHelpTip( i18n._("Sanity status: Unknown") );
button.setImage( w12_check );
}
else if (level == DuSanity.Level.OK) {
button.setText( i18n._("OK") );
button.setTextColor( DuColor.Color.APP_TEXT_COLOR.LIGHT_GREEN);
button.setHelpTip( i18n._("Sanity status: OK") );
button.setImage( w12_check_g );
}
else if (level == DuSanity.Level.INFO) {
button.setText( i18n._("Information") );
button.setTextColor( DuColor.Color.APP_TEXT_COLOR.LIGHT_BLUE);
button.setHelpTip( i18n._("Sanity status: Information") );
button.setImage( w12_information );
}
else if (level == DuSanity.Level.WARNING) {
button.setText( i18n._("Warning") );
button.setTextColor( DuColor.Color.APP_TEXT_COLOR.YELLOW);
button.setHelpTip( i18n._("Sanity status: Warning") );
button.setImage( w12_warning );
}
else if (level == DuSanity.Level.DANGER) {
button.setText( i18n._("Danger") );
button.setTextColor( DuColor.Color.APP_TEXT_COLOR.ORANGE);
button.setHelpTip( i18n._("Sanity status: Danger") );
button.setImage( w12_danger );
}
else if (level == DuSanity.Level.CRITICAL) {
button.setText( i18n._("Critical") );
button.setTextColor( DuColor.Color.APP_TEXT_COLOR.RAINBOX_RED);
button.setHelpTip( i18n._("Sanity status: Critical"));
button.setImage( w12_critical );
}
else if (level == DuSanity.Level.FATAL) {
button.setText( i18n._("Fatal") );
button.setTextColor( DuColor.Color.APP_TEXT_COLOR.RX_PURPLE);
button.setHelpTip( i18n._("Sanity status: Fatal") );
button.setImage( w12_fatal);
}
};
if (autoUpdate) DuSanity.UI.items.push(button);
return button;
}
/**
* Creates a panel showing all tests and current status
* @param {Group} container The ScriptUI Group containing the DuSanity panel
* @return {Group} The panel
*/
DuSanity.UI.panel = function(container) {
// Add tests
for (var k in DuSanity.Test) {
if (DuSanity.Test.hasOwnProperty(k)) DuSanity.UI.test( container, DuSanity.Test[k] );
}
DuScriptUI.separator(container);
// Run all button
var runAllButton = DuScriptUI.button( container, {
text: i18n._("Run all tests"), /// TRANSLATORS: sanity test
helpTip: i18n._("Run all the tests and displays the results."), /// TRANSLATORS: sanity test
image: DuScriptUI.Icon.UPDATE,
alignment: 'center',
orientation: 'row'
});
runAllButton.alignment = ['fill', 'top'];
runAllButton.onClick = function() { DuSanity.run(true); };
}
/**
* Adds the UI to display a test in the UI
* @param {Group} container A ScriptUI group where to add the test report
* @param {DuSanity.Test} test The test to show
* @return {Group} The ScriptUI Group containing the test report
*/
DuSanity.UI.test = function (container, test) {
// Util: updates the UI for the current test
function updateUI() {
group.setChecked( DuSanity.isGloballyEnabled(test) );
projectEnableButton.setChecked( DuSanity.isProjectEnabled(test) );
liveFixButton.setChecked( DuSanity.isLiveFixEnabled(test) );
if (!DuSanity.isEnabled(test))
{
statusIcon.setLevel(DuSanity.Level.UNKNOWN);
return;
}
statusIcon.setLevel( test.currentLevel );
statusIcon.setInfo( test.info );
statusIcon.setHelpTip( test.tip );
}
var group = DuScriptUI.settingField( container, test.testName, 250 );
group.onClick = function() {
var c = group.checked;
if (!c) projectEnableButton.setChecked(false);
else projectEnableButton.setChecked( DuSanity.isProjectEnabled( test ) );
projectEnableButton.enabled = c;
DuSanity.setGloballyEnabled(test, c);
DuSanity.setEnabled(test, c && projectEnableButton.checked);
updateUI();
};
var projectEnableButton = DuScriptUI.checkBox(group, {
text: '',
image: w16_file_d,
imageChecked: w16_file,
helpTip: i18n._("Toggle this test for the current project only.") /// TRANSLATORS: sanity test
});
projectEnableButton.alignment = ['left', 'center'];
projectEnableButton.onClick = function () {
var c = projectEnableButton.checked;
DuSanity.setProjectEnabled(test, c)
DuSanity.setEnabled(test, c);
updateUI();
};
var liveFixButton = DuScriptUI.checkBox(group, {
text: '',
image: w16_live_fix_d,
imageChecked: w16_live_fix,
helpTip: i18n._("Enable or disable automatic live-fix.") /// TRANSLATORS: (automatic)live fix for a sanity test
});
liveFixButton.alignment = ['left', 'center'];
liveFixButton.visible = test.hasAutoFix;
liveFixButton.onClick = function() {
DuSanity.setLiveFixEnabled(test, liveFixButton.checked);
};
var fixButton = DuScriptUI.button(group, {
text: '',
image: w16_fix,
helpTip: i18n._("Fix now.") /// TRANSLATORS: fix an issue detected by sanity tests
});
fixButton.alignment = ['left', 'center'];
fixButton.visible = test.hasFix;
fixButton.onClick = function() {
test.fix();
test();
updateUI();
};
var statusIcon = DuSanity.UI.icon(group, true, false);
statusIcon.alignment = ['fill', 'center'];
var refreshButton = DuScriptUI.button( group, {
text: '',
image: DuScriptUI.Icon.UPDATE,
helpTip: i18n._("Run the current test.") /// TRANSLATORS: sanity test
});
refreshButton.alignment = ['right', 'center'];
refreshButton.onClick = function() { DuSanity.runTest( test, false, true ); updateUI(); };
var optionsButton = DuScriptUI.button(group, {
text: '',
image: DuScriptUI.Icon.OPTIONS,
helpTip: i18n._("Change the test settings.") /// TRANSLATORS: sanity test
});
optionsButton.alignment = ['right', 'center'];
var optionsPopup = DuScriptUI.popUp( i18n._("Options") + ' (' + test.testName + ')');
var timeG = DuScriptUI.group(optionsPopup.content, 'row');
DuScriptUI.staticText(timeG, i18n._("Test every:")); /// TRANSLATORS: sanity test, label for duration between two tests
var timeOut = DuESF.settings.get("sanity/timeOut" + test.stringId, test.timeOut);
var timeOutStr = timeOut.toString();
var unit = "ms";
if (timeOut > 1000)
{
timeOutStr = (timeOut / 1000).toString();
unit = "s";
}
if (timeOut > 60000)
{
timeOutStr = (timeOut / 60000).toString();
unit = "mn";
}
var timeOutEdit = DuScriptUI.editText( timeG, {
text: timeOutStr,
suffix: ' ' + unit,
localize: false
});
timeOutEdit.onChange = function()
{
var t = parseInt(timeOutEdit.text);
if (unit == " s") t = t*1000;
if (unit == " mn") t = t*60000;
DuSanity.setTimeOut(test, t);
};
// Add custom options
if (isdef(test.options)) {
for (var o in test.options) {
if (!test.options.hasOwnProperty(o)) continue;
var option = test.options[o];
var optG = DuScriptUI.group( optionsPopup.content, 'row');
DuScriptUI.staticText(optG, option.description + ':');
if (jstype(option.value) == 'number' || jstype(option.value) == 'string' ) {
var optB = DuScriptUI.editText( optG, {
text: DuESF.settings.get("sanity/options/" + test.stringId + "/" + o, option.value).toString(),
placeHolder: i18n._("Default")
});
optB.onChange = function () {
DuESF.settings.set("sanity/options/" + test.stringId + "/" + o, optB.text);
DuESF.settings.save();
test();
}
}
else if ( jstype(option.value) == 'boolean' )
{
var optB = DuScriptUI.simpleCheckBox( optG );
optB.onClick = function () {
DuESF.settings.set("sanity/options/" + test.stringId + "/" + o, optB.checked);
DuESF.settings.save();
test();
}
}
}
}
optionsPopup.tieTo(optionsButton);
//First run
updateUI();
//add to events
DuScriptUI.addEvent(updateUI, 1000);
}
// ==================== |------| ====================
// ==================== | init | ====================
// ==================== |------| ====================
DuSanity.initialized = false;
/**
* Runs all sanity tests
* @param {boolean} [force=false] Force running all tests even if they've not timed out yet.
*/
DuSanity.run = function( force ) {
if (!DuSanity.initialized) return;
force = def(force, false);
// Runs all tests and get the result
DuSanity.currentLevel = DuSanity.Level.OK;
var level = DuSanity.Level.UNKNOWN;
for (var k in DuSanity.Test) {
if (!DuSanity.Test.hasOwnProperty(k)) continue;
var test = DuSanity.Test[k];
if (DuSanity.isEnabled(test)) {
var testLevel = test.currentLevel;
testLevel = DuSanity.runTest(test, false, force);
if (testLevel > level) level = testLevel;
}
}
DuSanity.currentLevel = level;
// Update UI
for(var i = 0; i < DuSanity.UI.items.length; i++) {
DuSanity.UI.items[i].setLevel( DuSanity.currentLevel );
}
}
/**
* This function must be called once when everything in the script is ready and after {@link DuAEF.init}
*/
DuSanity.init = function() {
// A single global variable to keep track of Ae Uptime
$.global.DuSan = def($.global.DuSan, {});
$.global.DuSan.AEStartTime = def($.global.DuSan.AEStartTime, Date.now());
// Add options (just now to translate the description)
DuSanity.Test.projectSize.options = {
sizeLimit: {
value: 100,
description: i18n._("Size limit (MB)")
}
};
DuSanity.Test.projectItems.options = {
itemsLimit: {
value: 1000,
description: i18n._("Maximum number of items")
}
};
DuSanity.Test.precomps.options = {
maxPrecompsAtRoot: {
value: 0,
description: i18n._("Maximum number of precompositions in the root folder")
},
precompsFolder: {
value: "Precomps",
description: i18n._("Default folder for precompositions")
}
};
DuSanity.Test.unusedComps.options = {
maxUnusedComps: {
value: 0,
description: i18n._("Maximum unused comps in the project")
},
mainCompsFolder: {
value: "Project root",
description: i18n._("Folder for main comps (leave empty for project root)")
}
};
DuSanity.Test.memory.options = {
memoryLimit: {
value: 8,
description: i18n._("Maximum memory (GB)")
}
};
DuSanity.Test.essentialProperties.options = {
maxEssentialProps: {
value: 40,
description: i18n._("Maximum number of essential properties in a comp")
}
};
DuSanity.Test.save.options = {
timeout: {
value: 30,
description: i18n._("Time limit before saving the project (mn)")
}
};
DuSanity.Test.upTime.options = {
timeout: {
value: 180,
description: i18n._("Uptime limit (mn)")
}
};
// Add names
DuSanity.Test.compNames.testName = i18n._('Composition Names');
DuSanity.Test.layerNames.testName = i18n._('Layer Names');
DuSanity.Test.expressionEngine.testName = i18n._('Expression engine');
DuSanity.Test.projectSize.testName = i18n._('Project size');
DuSanity.Test.projectItems.testName = i18n._('Project items');
DuSanity.Test.itemSources.testName = i18n._('Duplicated footages');
DuSanity.Test.unusedItems.testName = i18n._('Unused footages');
DuSanity.Test.precomps.testName = i18n._('Precompositions');
DuSanity.Test.unusedComps.testName = i18n._('Main compositions');
DuSanity.Test.memory.testName = i18n._('Memory in use');
DuSanity.Test.essentialProperties.testName = i18n._('Essential properties');
DuSanity.Test.save.testName = i18n._('Time since last save');
DuSanity.Test.upTime.testName = i18n._('Up time');
};
DuESF.initMethods.push( DuSanity.init );
DuSanity.enterRunTime = function() {
DuDebug.log( "DuSanity: entering runtime..." );
if (DuSanity.initialized) return;
// Enable tests
for (var k in DuSanity.Test) {
if (!DuSanity.Test.hasOwnProperty(k)) continue;
var test = DuSanity.Test[k];
DuSanity.setEnabled(test, DuSanity.isProjectEnabled(test) && DuSanity.isGloballyEnabled(test));
}
// first run
DuDebug.log( "DuSanity: First run" );
DuSanity.run(true);
// Add event
DuDebug.log( "DuSanity: Adding event..." );
DuScriptUI.addEvent(DuSanity.run);
DuSanity.initialized = true;
DuDebug.log( "DuSanity: Runtime!" );
};
DuESF.enterRunTimeMethods.push( DuSanity.enterRunTime );
//*/
Source