1. Lynn Rees
  2. ScoredIBIS

Commits

Lynn Rees  committed 19e7546

- functional prototype

  • Participants
  • Branches master

Comments (0)

Files changed (15)

File images/scoredIBIS-icon.png

Added
New image

File images/scoredIBIS-screenshot-1.png

Added
New image

File images/scoredIBIS.png

Added
New image

File images/scoredibis.svg

View file
Added
New image

File scoredibis.mm

View file
+<map version="freeplane 1.2.0">
+<!--To view this file, download free mind mapping software Freeplane from http://freeplane.sourceforge.net -->
+<node TEXT="ScoredIBIS" FOLDED="false" ID="ID_1723255651" CREATED="1283093380553" MODIFIED="1370380762272" BACKGROUND_COLOR="#97c7dc" LINK="https://bitbucket.org/lcrees/freeibis/">
+<font SIZE="16" BOLD="true" ITALIC="true"/>
+<hook NAME="MapStyle">
+    <properties show_icon_for_attributes="true" show_note_icons="true"/>
+
+<map_styles>
+<stylenode LOCALIZED_TEXT="styles.root_node">
+<stylenode LOCALIZED_TEXT="styles.predefined" POSITION="right">
+<stylenode LOCALIZED_TEXT="default" COLOR="#000000" STYLE="fork" MAX_WIDTH="600">
+<font NAME="SansSerif" SIZE="12" BOLD="false" ITALIC="false"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="defaultstyle.details"/>
+<stylenode LOCALIZED_TEXT="defaultstyle.note"/>
+<stylenode LOCALIZED_TEXT="defaultstyle.floating">
+<edge STYLE="hide_edge"/>
+<cloud COLOR="#f0f0f0" SHAPE="ROUND_RECT"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.ok">
+<icon BUILTIN="button_ok"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.needs_action">
+<icon BUILTIN="messagebox_warning"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.floating_node">
+<cloud COLOR="#ffffff" SHAPE="ARC"/>
+<edge STYLE="hide_edge"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.topic" COLOR="#18898b" STYLE="fork">
+<font NAME="Liberation Sans" SIZE="12" BOLD="true"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.subtopic" COLOR="#cc3300" STYLE="fork">
+<font NAME="Liberation Sans" SIZE="12" BOLD="true"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.subsubtopic" COLOR="#669900">
+<font NAME="Liberation Sans" SIZE="12" BOLD="true"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.connection" COLOR="#606060" STYLE="fork">
+<font NAME="Arial" SIZE="10" BOLD="false"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.important" COLOR="#ff0000">
+<icon BUILTIN="yes"/>
+<font NAME="Liberation Sans" SIZE="12"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.question">
+<icon BUILTIN="help"/>
+<font NAME="Aharoni" SIZE="12"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.key" COLOR="#996600">
+<icon BUILTIN="password"/>
+<font NAME="Liberation Sans" SIZE="12" BOLD="false"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.idea">
+<icon BUILTIN="idea"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.note" COLOR="#990000">
+<font NAME="Liberation Sans" SIZE="12"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.date" COLOR="#0033ff">
+<icon BUILTIN="calendar"/>
+<font NAME="Liberation Sans" SIZE="12"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.website" COLOR="#006633">
+<font NAME="Liberation Sans" SIZE="12"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.list" COLOR="#cc6600">
+<icon BUILTIN="list"/>
+<font NAME="Liberation Sans" SIZE="12" BOLD="true"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.quotation" COLOR="#338800" STYLE="fork">
+<font NAME="Liberation Sans" SIZE="12" BOLD="false" ITALIC="false"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.definition" COLOR="#666600">
+<font NAME="Liberation Sans" SIZE="12" BOLD="false"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.description" COLOR="#996600">
+<font NAME="Liberation Sans" SIZE="12" BOLD="false"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.pending" COLOR="#b3b95c">
+<font NAME="Liberation Sans" SIZE="12"/>
+</stylenode>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.AutomaticLayout" POSITION="right">
+<stylenode LOCALIZED_TEXT="AutomaticLayout.level.root" COLOR="#000000">
+<font SIZE="20"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="AutomaticLayout.level,1" COLOR="#0033ff">
+<font SIZE="18"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="AutomaticLayout.level,2" COLOR="#00b439">
+<font SIZE="16"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="AutomaticLayout.level,3" COLOR="#990000">
+<font SIZE="14"/>
+</stylenode>
+<stylenode LOCALIZED_TEXT="AutomaticLayout.level,4" COLOR="#111111">
+<font SIZE="12"/>
+</stylenode>
+</stylenode>
+<stylenode LOCALIZED_TEXT="styles.user-defined" POSITION="right"/>
+</stylenode>
+</map_styles>
+</hook>
+<hook NAME="AutomaticEdgeColor" COUNTER="9"/>
+<attribute_layout NAME_WIDTH="103" VALUE_WIDTH="103"/>
+<attribute NAME="name" VALUE="scoredIBIS"/>
+<attribute NAME="version" VALUE="v0.1.1" OBJECT="org.freeplane.features.format.FormattedObject|v0.1.1|number:decimal:#0.####"/>
+<attribute NAME="author" VALUE="L. C. Rees"/>
+<attribute NAME="freeplaneVersionFrom" VALUE="1.2.15"/>
+<attribute NAME="freeplaneVersionTo" VALUE=""/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    <p>
+      The homepage of this add-on should be set as the link of the root node.
+    </p>
+    <p>
+      The basic properties of this add-on. They can be used in script names and other attributes, e.g. &quot;${name}.groovy&quot;.
+    </p>
+    <ul>
+      <li>
+        name: The name of the add-on, normally a technically one (no spaces, no special characters except _.-).
+      </li>
+      <li>
+        author: Author's name(s) and (optionally) email address.
+      </li>
+      <li>
+        version: Since it's difficult to protect numbers like 1.0 from Freeplane's number parser it's advised to prepend a 'v' to the number, e.g. 'v1.0'.
+      </li>
+      <li>
+        freeplane-version-from: The oldest compatible Freeplane version. The add-on will not be installed if the Freeplane version is too old.
+      </li>
+      <li>
+        freeplane-version-to: Normally empty: The newest compatible Freeplane version. The add-on will not be installed if the Freeplane version is too new.
+      </li>
+    </ul>
+  </body>
+</html>
+</richcontent>
+<hook NAME="FlexibleLayout" VALUE="CHILDREN"/>
+<node TEXT="description" POSITION="left" ID="ID_143630176" CREATED="1357715826843" MODIFIED="1370328381460">
+<edge COLOR="#ff0000"/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    <p>
+      Description would be awkward to edit as an attribute.
+    </p>
+    <p>
+      So you have to put the add-on description as a child of the <i>'description'</i> node.
+    </p>
+    <p>
+      To translate the description you have to define a translation for the key 'addons.${name}.description'.
+    </p>
+  </body>
+</html>
+</richcontent>
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+<node TEXT="Scored Issue-Based Information System for Freeplane" ID="ID_419235551" CREATED="1357715987721" MODIFIED="1370325732593">
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+</node>
+</node>
+<node TEXT="changes" POSITION="left" ID="ID_1790870178" CREATED="1357715826877" MODIFIED="1370328381461">
+<edge COLOR="#0000ff"/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    <p>
+      Change log of this add-on: append one node for each noteworthy version and put the details for each version into a child node.
+    </p>
+  </body>
+</html>
+</richcontent>
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+<node TEXT="0.1.0" ID="ID_1041388750" CREATED="1358051551048" MODIFIED="1369080817668">
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+<node TEXT="initial release" ID="ID_885933822" CREATED="1358051564024" MODIFIED="1358051567394">
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+</node>
+</node>
+</node>
+<node TEXT="license" FOLDED="true" POSITION="left" ID="ID_1348143779" CREATED="1357715826886" MODIFIED="1370328381463">
+<edge COLOR="#00ff00"/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    <p>
+      The add-ons's license that the user has to accept before she can install it.
+    </p>
+    <p>
+      
+    </p>
+    <p>
+      The License text has to be entered as a child of the <i>license</i> node, either as plain text or as HTML.
+    </p>
+  </body>
+</html>
+</richcontent>
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+<node TEXT="This add-on is free software: you can redistribute it and/or modify&#xa;it under the terms of the GNU General Public License as published by&#xa;the Free Software Foundation, either version 2 of the License, or&#xa;(at your option) any later version.&#xa;&#xa;This program is distributed in the hope that it will be useful,&#xa;but WITHOUT ANY WARRANTY; without even the implied warranty of&#xa;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&#xa;GNU General Public License for more details." ID="ID_241792435" CREATED="1357715826895" MODIFIED="1357719017976">
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+</node>
+</node>
+<node TEXT="preferences.xml" POSITION="left" ID="ID_1772733941" CREATED="1357715826946" MODIFIED="1370328381465">
+<edge COLOR="#ff00ff"/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    <p>
+      <font face="SansSerif, sans-serif" color="#000000">The child node contains the add-on configuration as an extension to <i><b>mindmapmodemenu.xml</b></i> (in Tools &#8594; Preferences &#8594; Add-ons).</font>
+    </p>
+    <p>
+      <font face="SansSerif, sans-serif" color="#000000">Every property in the configuration should receive a default value in <i>default.properties</i> node.</font>
+    </p>
+  </body>
+</html>
+</richcontent>
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+</node>
+<node TEXT="default.properties" POSITION="left" ID="ID_1954124232" CREATED="1357715826968" MODIFIED="1370328381466">
+<edge COLOR="#00ffff"/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    <p>
+      These properties play together with the preferences: Each property defined in the preferences should have a default value in the attributes of this node.
+    </p>
+  </body>
+</html>
+</richcontent>
+<attribute_layout NAME_WIDTH="72" VALUE_WIDTH="72"/>
+</node>
+<node TEXT="translations" POSITION="left" ID="ID_1430168348" CREATED="1357715826977" MODIFIED="1370328381468">
+<edge COLOR="#ffff00"/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    <p>
+      The translation keys that this script uses. Define one child node per supported locale. The attributes contain the translations. Define at least
+    </p>
+    <ul>
+      <li>
+        'addons.${name}' for the add-on's name
+      </li>
+      <li>
+        'addons.${name}.description' for the description, e.g. in the add-on overview dialog (not necessary for English)
+      </li>
+    </ul>
+  </body>
+</html>
+</richcontent>
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+<node TEXT="en" ID="ID_1245393964" CREATED="1357715826986" MODIFIED="1370325755279">
+<attribute_layout NAME_WIDTH="76" VALUE_WIDTH="76"/>
+<attribute NAME="addons.${name}" VALUE="scoredIBIS"/>
+</node>
+</node>
+<node TEXT="uninstall" POSITION="left" ID="ID_1844997656" CREATED="1357715826998" MODIFIED="1370328383066">
+<edge COLOR="#7c0000"/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    <p>
+      List of files and/or directories to remove on uninstall
+    </p>
+  </body>
+</html>
+</richcontent>
+<attribute_layout NAME_WIDTH="30" VALUE_WIDTH="269"/>
+<attribute NAME="delete" VALUE="${installationbase}/addons/${name}.script.xml"/>
+<attribute NAME="delete" VALUE="${installationbase}/scripts/siCon.groovy"/>
+<attribute NAME="delete" VALUE="${installationbase}/scripts/siIdea.groovy"/>
+<attribute NAME="delete" VALUE="${installationbase}/scripts/siPro.groovy"/>
+<attribute NAME="delete" VALUE="${installationbase}/scripts/siQuestion.groovy"/>
+<attribute NAME="delete" VALUE="${installationbase}/resources/images/scoredIBIS.png"/>
+<attribute NAME="delete" VALUE="${installationbase}/resources/images/scoredIBIS-icon.png"/>
+<attribute NAME="delete" VALUE="${installationbase}/resources/images/scoredIBIS-screenshot-1.png"/>
+<attribute NAME="delete" VALUE="${installationbase}/scripts/siScore.groovy"/>
+<attribute NAME="delete" VALUE="${installationbase}/scripts/siScore0.groovy"/>
+<attribute NAME="delete" VALUE="${installationbase}/scripts/siScore1.groovy"/>
+<attribute NAME="delete" VALUE="${installationbase}/scripts/siScore2.groovy"/>
+<attribute NAME="delete" VALUE="${installationbase}/scripts/siScore3.groovy"/>
+<attribute NAME="delete" VALUE="${installationbase}/scripts/siScore4.groovy"/>
+<attribute NAME="delete" VALUE="${installationbase}/scripts/siScore5.groovy"/>
+</node>
+<node TEXT="scripts" POSITION="right" ID="ID_1324856264" CREATED="1357715827025" MODIFIED="1370328381480">
+<edge COLOR="#00007c"/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    An add-on may contain multiple scripts. Each node's text defines the script name (e.g. <i><b>insertInlineImage.groovy</b></i>). This name has to end with <i><b>.groovy</b></i> and may only contain letters and digits. The script's properties have to be configured by setting the following attributes:
+
+    <p>
+      
+    </p>
+    <p>
+      <b>menuLocation</b> &lt;<i>locationkey</i>&gt;
+    </p>
+    <ul>
+      <li>
+        Defines where the menu location.
+      </li>
+      <li>
+        See <i><b>mindmapmodemenu.xml</b></i> for how the menu locations look like.
+      </li>
+      <li>
+        This attribute is <font color="#ff0033"><b>mandatory</b></font>.
+      </li>
+    </ul>
+    <p>
+      <b>menuTitleKey </b>&lt;<i>key</i>&gt;
+    </p>
+    <ul>
+      <li>
+        The menu item title will be looked up under the translation key &lt;<i>key</i>&gt; (don't forget to define its translation).
+      </li>
+      <li>
+        This attribute is <font color="#ff0033"><b>mandatory</b></font>.
+      </li>
+    </ul>
+    <p>
+      
+    </p>
+    <p>
+      <b>executionMode</b> &lt;<i>mode</i>&gt;
+    </p>
+    <ul>
+      <li>
+        Execution mode as described in the <a href="http://freeplane.sourceforge.net/wiki/index.php/Scripting">Freeplane wiki</a>.
+      </li>
+      <li>
+        <b>ON_SINGLE_NODE</b>: Execute the script once. The <i><b>node</b></i> variable is set to the selected node.
+      </li>
+      <li>
+        <b>ON_SELECTED_NODE</b>: Execute the script <i><b>n</b></i> times for <i><b>n</b></i> selected nodes, once for each node.
+      </li>
+      <li>
+        <b>ON_SELECTED_NODE_RECURSIVELY</b>: Execute the script on every selected node and recursively on all of its children.
+      </li>
+      <li>
+        When in doubt, use <b>ON_SINGLE_NODE</b>.
+      </li>
+      <li>
+        This attribute is <font color="#ff0033"><b>mandatory</b></font>.
+      </li>
+    </ul>
+    <p>
+      
+    </p>
+    <p>
+      <b>keyboardShortcut</b> &lt;<i>shortcut</i>&gt;
+    </p>
+    <ul>
+      <li>
+        Keyboard combination (accelerator) for this script (e.g. <i><b>control alt I</b></i>).
+      </li>
+      <li>
+        Use lowercase letters for modifiers and uppercase for letters.
+      </li>
+      <li>
+        Don't use <i><b>+</b></i> signs.
+      </li>
+      <li>
+        Available key names are listed at <a href="http://download.oracle.com/javase/1.4.2/docs/api/java/awt/event/KeyEvent.html#VK_0">http://download.oracle.com/javase/1.4.2/docs/api/java/awt/event/KeyEvent.html#VK_0</a> (In that list, only entries with a <i><b>VK_</b></i> prefix count. Leave out the <i><b>VK_ </b></i>prefix in the shortcut definition.)
+      </li>
+      <li>
+        This attribute is <b>optional</b>.
+      </li>
+    </ul>
+    <p>
+      
+    </p>
+    <p>
+      These are the permission attributes for each script.
+    </p>
+    <ul>
+      <li>
+        <b>execute_scripts_without_asking:</b> permission to run without asking for permission
+      </li>
+      <li>
+        <b>execute_scripts_without_file_restriction: </b>permission to read files
+      </li>
+      <li>
+        <b>execute_scripts_without_write_restriction: </b>permission to create/change/delete files
+      </li>
+      <li>
+        <b>execute_scripts_without_exec_restriction: </b>permission to execute other programs
+      </li>
+      <li>
+        <b>execute_scripts_without_network_restriction: </b>permission to access the network
+      </li>
+      <li>
+        This set of permissions is fixed.
+      </li>
+      <li>
+        Don't change any permission attribute's name.
+      </li>
+      <li>
+        Don't leave out any permission attribute's name.
+      </li>
+      <li>
+        Set each value to either <i><b>true</b></i> or <i><b>false</b></i>:
+      </li>
+      <li>
+        <b>set execute_scripts_without_asking</b> to <i><b>true</b></i> unless you want to annoy users.
+      </li>
+      <li>
+        This attribute is <font color="#ff0033"><b>mandatory</b></font>.
+      </li>
+    </ul>
+  </body>
+</html>
+</richcontent>
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+<node TEXT="siCon.groovy" ID="ID_1501046977" CREATED="1357794199593" MODIFIED="1370325791158">
+<attribute_layout NAME_WIDTH="206" VALUE_WIDTH="206"/>
+<attribute NAME="menuTitleKey" VALUE="Con"/>
+<attribute NAME="menuLocation" VALUE="main_menu_scripting/scoredIBIS"/>
+<attribute NAME="executionMode" VALUE="on_single_node"/>
+<attribute NAME="keyboardShortcut" VALUE="meta MINUS"/>
+<attribute NAME="execute_scripts_without_asking" VALUE="true"/>
+<attribute NAME="execute_scripts_without_file_restriction" VALUE="true"/>
+<attribute NAME="execute_scripts_without_write_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_exec_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_network_restriction" VALUE="false"/>
+</node>
+<node TEXT="siIdea.groovy" ID="ID_1766457930" CREATED="1357794199593" MODIFIED="1370325793547">
+<attribute_layout NAME_WIDTH="206" VALUE_WIDTH="206"/>
+<attribute NAME="menuTitleKey" VALUE="Idea"/>
+<attribute NAME="menuLocation" VALUE="main_menu_scripting/scoredIBIS"/>
+<attribute NAME="executionMode" VALUE="on_single_node"/>
+<attribute NAME="keyboardShortcut" VALUE="meta PERIOD"/>
+<attribute NAME="execute_scripts_without_asking" VALUE="true"/>
+<attribute NAME="execute_scripts_without_file_restriction" VALUE="true"/>
+<attribute NAME="execute_scripts_without_write_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_exec_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_network_restriction" VALUE="false"/>
+</node>
+<node TEXT="siPro.groovy" ID="ID_575754475" CREATED="1357794217131" MODIFIED="1370325795487">
+<attribute_layout NAME_WIDTH="206" VALUE_WIDTH="206"/>
+<attribute NAME="menuTitleKey" VALUE="Pro"/>
+<attribute NAME="menuLocation" VALUE="main_menu_scripting/scoredIBIS"/>
+<attribute NAME="executionMode" VALUE="on_single_node"/>
+<attribute NAME="keyboardShortcut" VALUE="meta EQUALS"/>
+<attribute NAME="execute_scripts_without_asking" VALUE="true"/>
+<attribute NAME="execute_scripts_without_file_restriction" VALUE="true"/>
+<attribute NAME="execute_scripts_without_write_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_exec_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_network_restriction" VALUE="false"/>
+</node>
+<node TEXT="siQuestion.groovy" ID="ID_1207751289" CREATED="1357794244507" MODIFIED="1370325797333">
+<attribute_layout NAME_WIDTH="206" VALUE_WIDTH="206"/>
+<attribute NAME="menuTitleKey" VALUE="Question"/>
+<attribute NAME="menuLocation" VALUE="main_menu_scripting/scoredIBIS"/>
+<attribute NAME="executionMode" VALUE="on_single_node"/>
+<attribute NAME="keyboardShortcut" VALUE="meta SLASH"/>
+<attribute NAME="execute_scripts_without_asking" VALUE="true"/>
+<attribute NAME="execute_scripts_without_file_restriction" VALUE="true"/>
+<attribute NAME="execute_scripts_without_write_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_exec_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_network_restriction" VALUE="false"/>
+</node>
+<node TEXT="siScore0.groovy" ID="ID_182523331" CREATED="1370328347212" MODIFIED="1370328492852">
+<attribute_layout NAME_WIDTH="206" VALUE_WIDTH="206"/>
+<attribute NAME="menuTitleKey" VALUE="Score 0"/>
+<attribute NAME="menuLocation" VALUE="main_menu_scripting/scoredIBIS"/>
+<attribute NAME="executionMode" VALUE="on_single_node"/>
+<attribute NAME="keyboardShortcut" VALUE="control 0"/>
+<attribute NAME="execute_scripts_without_asking" VALUE="true"/>
+<attribute NAME="execute_scripts_without_file_restriction" VALUE="true"/>
+<attribute NAME="execute_scripts_without_write_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_exec_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_network_restriction" VALUE="false"/>
+</node>
+<node TEXT="siScore1.groovy" ID="ID_1565343304" CREATED="1370328347213" MODIFIED="1370328485886">
+<attribute_layout NAME_WIDTH="206" VALUE_WIDTH="206"/>
+<attribute NAME="menuTitleKey" VALUE="Score 1"/>
+<attribute NAME="menuLocation" VALUE="main_menu_scripting/scoredIBIS"/>
+<attribute NAME="executionMode" VALUE="on_single_node"/>
+<attribute NAME="keyboardShortcut" VALUE="control 1"/>
+<attribute NAME="execute_scripts_without_asking" VALUE="true"/>
+<attribute NAME="execute_scripts_without_file_restriction" VALUE="true"/>
+<attribute NAME="execute_scripts_without_write_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_exec_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_network_restriction" VALUE="false"/>
+</node>
+<node TEXT="siScore2.groovy" ID="ID_522074364" CREATED="1370328347211" MODIFIED="1370328500621">
+<attribute_layout NAME_WIDTH="206" VALUE_WIDTH="206"/>
+<attribute NAME="menuTitleKey" VALUE="Score 2"/>
+<attribute NAME="menuLocation" VALUE="main_menu_scripting/scoredIBIS"/>
+<attribute NAME="executionMode" VALUE="on_single_node"/>
+<attribute NAME="keyboardShortcut" VALUE="control 2"/>
+<attribute NAME="execute_scripts_without_asking" VALUE="true"/>
+<attribute NAME="execute_scripts_without_file_restriction" VALUE="true"/>
+<attribute NAME="execute_scripts_without_write_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_exec_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_network_restriction" VALUE="false"/>
+</node>
+<node TEXT="siScore3.groovy" ID="ID_296929847" CREATED="1370328347212" MODIFIED="1370328505851">
+<attribute_layout NAME_WIDTH="206" VALUE_WIDTH="206"/>
+<attribute NAME="menuTitleKey" VALUE="Score 3"/>
+<attribute NAME="menuLocation" VALUE="main_menu_scripting/scoredIBIS"/>
+<attribute NAME="executionMode" VALUE="on_single_node"/>
+<attribute NAME="keyboardShortcut" VALUE="control 3"/>
+<attribute NAME="execute_scripts_without_asking" VALUE="true"/>
+<attribute NAME="execute_scripts_without_file_restriction" VALUE="true"/>
+<attribute NAME="execute_scripts_without_write_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_exec_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_network_restriction" VALUE="false"/>
+</node>
+<node TEXT="siScore4.groovy" ID="ID_1968323935" CREATED="1370328347211" MODIFIED="1370328509895">
+<attribute_layout NAME_WIDTH="206" VALUE_WIDTH="206"/>
+<attribute NAME="menuTitleKey" VALUE="Score 4"/>
+<attribute NAME="menuLocation" VALUE="main_menu_scripting/scoredIBIS"/>
+<attribute NAME="executionMode" VALUE="on_single_node"/>
+<attribute NAME="keyboardShortcut" VALUE="control 4"/>
+<attribute NAME="execute_scripts_without_asking" VALUE="true"/>
+<attribute NAME="execute_scripts_without_file_restriction" VALUE="true"/>
+<attribute NAME="execute_scripts_without_write_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_exec_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_network_restriction" VALUE="false"/>
+</node>
+<node TEXT="siScore5.groovy" ID="ID_1444727303" CREATED="1370328347210" MODIFIED="1370328516662">
+<attribute_layout NAME_WIDTH="206" VALUE_WIDTH="206"/>
+<attribute NAME="menuTitleKey" VALUE="Score 5"/>
+<attribute NAME="menuLocation" VALUE="main_menu_scripting/scoredIBIS"/>
+<attribute NAME="executionMode" VALUE="on_single_node"/>
+<attribute NAME="keyboardShortcut" VALUE="control 5"/>
+<attribute NAME="execute_scripts_without_asking" VALUE="true"/>
+<attribute NAME="execute_scripts_without_file_restriction" VALUE="true"/>
+<attribute NAME="execute_scripts_without_write_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_exec_restriction" VALUE="false"/>
+<attribute NAME="execute_scripts_without_network_restriction" VALUE="false"/>
+</node>
+</node>
+<node TEXT="zips" POSITION="right" ID="ID_269135974" CREATED="1357715827053" MODIFIED="1370328381661">
+<edge COLOR="#007c00"/>
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    <p>
+      An add-on may contain any number of nodes containing ZIP files.
+    </p>
+    <p>
+      
+    </p>
+    <p>
+      - The immediate child nodes contain a description of the ZIP. The devtools script <i>releaseAddOn.groovy</i> allows automatic ZIP creation if the name of this node matches a directory in the current directory.
+    </p>
+    <p>
+      
+    </p>
+    <p>
+      - The child nodes of these nodes contain the actual ZIP files.
+    </p>
+    <p>
+      
+    </p>
+    <p>
+      - Any ZIP file will be extracted in &lt;installationbase&gt;. Currently, &lt;installationbase&gt; is always Freeplane's &lt;userhome&gt;, e.g. ~/.freeplane/1.2.
+    </p>
+    <p>
+      
+    </p>
+    <p>
+      - The files will be processed in the sequence as seen in the map.
+    </p>
+    <p>
+      
+    </p>
+    <p>
+      - ZIP files must be loaded into the map via the script <i>Tools-&gt;Scripts-&gt;Insert Binary</i> since they have to be (base64) encoded as simple strings.
+    </p>
+  </body>
+</html>
+</richcontent>
+</node>
+<node TEXT="images" POSITION="right" ID="ID_112966804" CREATED="1357715827065" MODIFIED="1370328381665">
+<edge COLOR="#7c007c"/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    <p>
+      An add-on may define any number of images as child nodes of the <i><b>images</b></i> node.
+    </p>
+    <p>
+      
+    </p>
+    <p>
+      Images are saved to the <i><b>${installationbase}/resources/images</b></i> directory.
+    </p>
+    <p>
+      The following images should be present:
+    </p>
+    <ul>
+      <li>
+        <i>${name}-icon.png</i>, like <i>oldicons-theme-icon.png</i>. This will be used in the add-on overview.
+      </li>
+      <li>
+        <i>${name}-screenshot-1.png</i>, like <i>oldicons-theme-screenshot-1.png</i>. This will be used in the add-on details dialog. Further images can be included but they are not used yet.
+      </li>
+    </ul>
+    <p>
+      Images can be added automatically with <i><b>releaseAddOn.groovy</b></i> or loaded into the map with <i><b>Tools &#8594; Scripts &#8594; Insert Binary</b></i>. The actual image data has to be placed as BASE64 encoded binary data into the text of a subnode.
+    </p>
+  </body>
+</html>
+</richcontent>
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+<node TEXT="${name}.png" ID="ID_473909841" CREATED="1357854883609" MODIFIED="1357866785018">
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+</node>
+<node TEXT="${name}-icon.png" ID="ID_1117040601" CREATED="1357853471253" MODIFIED="1357866788268">
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+</node>
+<node TEXT="${name}-screenshot-1.png" ID="ID_1706510600" CREATED="1357855573438" MODIFIED="1357866791195">
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+</node>
+</node>
+<node TEXT="jars" POSITION="right" ID="ID_1123935066" CREATED="1369093250633" MODIFIED="1370328381668">
+<edge COLOR="#007c00"/>
+<richcontent TYPE="NOTE">
+
+<html>
+  <head>
+    
+  </head>
+  <body>
+    <p>
+      An add-on may define any number of jars as child nodes of the <i><b>jars</b></i> node.
+    </p>
+    <p>
+      
+    </p>
+    <p>
+      Jars are saved to the <i><b>${installationbase}/jars</b></i> directory.
+    </p>
+    <p>
+      
+    </p>
+    <p>
+      Jars can be added automatically with <i><b>releaseAddOn.groovy</b></i> or loaded into the map with <i><b>Tools &#8594; Scripts &#8594; Insert Binary</b></i>. The jar's data has to be placed as BASE64 encoded binary data into the text of a subnode.
+    </p>
+  </body>
+</html>
+</richcontent>
+<attribute_layout NAME_WIDTH="100" VALUE_WIDTH="100"/>
+</node>
+</node>
+</map>

File scripts/siCon.groovy

View file
+// @CacheScriptContent(true)
+// @ExecutionModes({ON_SINGLE_NODE})
+
+def con
+
+if (c.selected.icons.icons.contains('idea')) {
+	con = c.selected.createChild()
+} else if (c.selected.icons.icons.contains('very_positive') ||
+	c.selected.icons.icons.contains('very_negative')) {
+	con = c.selected.parent.createChild()
+}
+
+if (con != null) {
+	con.icons.add('very_negative')
+	con.icons.add('full-0')
+	con.style.textColorCode = '#CC0000'
+	c.editInPopup(con)
+}

File scripts/siIdea.groovy

View file
+// @CacheScriptContent(true)
+// @ExecutionModes({ON_SINGLE_NODE})
+
+def idea
+
+if (c.selected.icons.icons.contains('help')) {
+	idea = c.selected.createChild()
+} else if (c.selected.icons.icons.contains('idea')) {
+	idea = c.selected.parent.createChild()
+}
+
+if (idea != null) {
+	idea.icons.add('idea')
+	idea.icons.add('full-0')
+	idea.style.font.italic = true
+	idea.style.textColorCode = '#333300'
+	c.editInPopup(idea)
+}

File scripts/siPro.groovy

View file
+// @CacheScriptContent(true)
+// @ExecutionModes({ON_SINGLE_NODE})
+
+def pro
+
+if (c.selected.icons.icons.contains('idea')) {
+	pro = c.selected.createChild()
+} else if (c.selected.icons.icons.contains('very_negative') ||
+	c.selected.icons.icons.contains('very_positive')) {
+	pro = c.selected.parent.createChild()
+}
+
+if (pro != null) {
+	pro.icons.add('very_positive')
+	pro.icons.add('full-0')
+	pro.style.textColorCode = '#003300'
+	c.editInPopup(pro)
+}

File scripts/siQuestion.groovy

View file
+// @CacheScriptContent(true)
+// @ExecutionModes({ON_SINGLE_NODE})
+
+if (c.selected == c.selected.map.root && !c.selected.icons.icons.contains('help')) {
+	c.selected.icons.add('help')
+} else {
+	def question = c.selected.createChild()
+	question.icons.add('help')
+	question.style.font.bold = true
+	question.style.textColorCode = '#990099'
+	question.style.font.size = 13
+	c.editInPopup(question)
+}

File scripts/siScore0.groovy

View file
+// @CacheScriptContent(true)
+// @ExecutionModes({ON_SINGLE_NODE})
+
+if (c.selected.icons.contains('very_negative') || c.selected.icons.contains('very_positive')) {
+	def full = 0
+
+	def baseTextSize = 12
+
+	def target = c.selected
+	def parent = target.parent
+	def grandParent = parent.parent
+
+	target.icons.icons.findAll { it.startsWith('full') }.each {
+		target.icons.remove(it)
+	}
+	target.icons.add("full-${full}")
+	target.style.font.size = baseTextSize + full
+
+	def pros = parent.children*.icons.findAll {
+		it.first == 'very_positive' }.collect { it[1][-1].toInteger() }
+	pros = pros.size() > 0 ? pros : [0]
+	def prosAvg = (pros.sum() / pros.size()).toDouble().round().toInteger()
+
+	def cons = parent.children*.icons.findAll {
+		it.first == 'very_negative' }.collect { it[1][-1].toInteger() }
+	cons = cons.size() > 0 ? cons : [0]
+	def consAvg = (cons.sum() / cons.size()).toDouble().round().toInteger()
+
+	full = (prosAvg - consAvg)
+	full = full > 0 ? full : 0
+
+	parent.icons.icons.findAll { it.startsWith('full') }.each {
+		parent.icons.remove(it)
+	}
+	parent.icons.add("full-${full}")
+	parent.style.font.size = baseTextSize + full
+	def hold = parent.children.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	parent.children.toList().each { it.delete() }
+	hold.each { parent.appendBranch(it) }
+	def firstChild = parent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+
+	hold = grandParent.children.findAll {
+		it.icons.contains('idea')
+	}.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	grandParent.style.font.size = baseTextSize + full
+	grandParent.children.toList().each { it.delete() }
+	hold.each { grandParent.appendBranch(it) }
+	firstChild = grandParent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+}

File scripts/siScore1.groovy

View file
+// @CacheScriptContent(true)
+// @ExecutionModes({ON_SINGLE_NODE})
+
+if (c.selected.icons.contains('very_negative') || c.selected.icons.contains('very_positive')) {
+	def full = 1
+
+	def baseTextSize = 12
+
+	def target = c.selected
+	def parent = target.parent
+	def grandParent = parent.parent
+
+	target.icons.icons.findAll { it.startsWith('full') }.each {
+		target.icons.remove(it)
+	}
+	target.icons.add("full-${full}")
+	target.style.font.size = baseTextSize + full
+
+	def pros = parent.children*.icons.findAll {
+		it.first == 'very_positive' }.collect { it[1][-1].toInteger() }
+	pros = pros.size() > 0 ? pros : [0]
+	def prosAvg = (pros.sum() / pros.size()).toDouble().round().toInteger()
+
+	def cons = parent.children*.icons.findAll {
+		it.first == 'very_negative' }.collect { it[1][-1].toInteger() }
+	cons = cons.size() > 0 ? cons : [0]
+	def consAvg = (cons.sum() / cons.size()).toDouble().round().toInteger()
+
+	full = (prosAvg - consAvg)
+	full = full > 0 ? full : 0
+
+	parent.icons.icons.findAll { it.startsWith('full') }.each {
+		parent.icons.remove(it)
+	}
+	parent.icons.add("full-${full}")
+	parent.style.font.size = baseTextSize + full
+	def hold = parent.children.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	parent.children.toList().each { it.delete() }
+	hold.each { parent.appendBranch(it) }
+	def firstChild = parent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+
+	hold = grandParent.children.findAll {
+		it.icons.contains('idea')
+	}.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	grandParent.style.font.size = baseTextSize + full
+	grandParent.children.toList().each { it.delete() }
+	hold.each { grandParent.appendBranch(it) }
+	firstChild = grandParent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+}

File scripts/siScore2.groovy

View file
+// @CacheScriptContent(true)
+// @ExecutionModes({ON_SINGLE_NODE})
+
+if (c.selected.icons.contains('very_negative') || c.selected.icons.contains('very_positive')) {
+	def full = 2
+
+	def baseTextSize = 12
+
+	def target = c.selected
+	def parent = target.parent
+	def grandParent = parent.parent
+
+	target.icons.icons.findAll { it.startsWith('full') }.each {
+		target.icons.remove(it)
+	}
+	target.icons.add("full-${full}")
+	target.style.font.size = baseTextSize + full
+
+	def pros = parent.children*.icons.findAll {
+		it.first == 'very_positive' }.collect { it[1][-1].toInteger() }
+	pros = pros.size() > 0 ? pros : [0]
+	def prosAvg = (pros.sum() / pros.size()).toDouble().round().toInteger()
+
+	def cons = parent.children*.icons.findAll {
+		it.first == 'very_negative' }.collect { it[1][-1].toInteger() }
+	cons = cons.size() > 0 ? cons : [0]
+	def consAvg = (cons.sum() / cons.size()).toDouble().round().toInteger()
+
+	full = (prosAvg - consAvg)
+	full = full > 0 ? full : 0
+
+	parent.icons.icons.findAll { it.startsWith('full') }.each {
+		parent.icons.remove(it)
+	}
+	parent.icons.add("full-${full}")
+	parent.style.font.size = baseTextSize + full
+	def hold = parent.children.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	parent.children.toList().each { it.delete() }
+	hold.each { parent.appendBranch(it) }
+	def firstChild = parent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+
+	hold = grandParent.children.findAll {
+		it.icons.contains('idea')
+	}.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	grandParent.style.font.size = baseTextSize + full
+	grandParent.children.toList().each { it.delete() }
+	hold.each { grandParent.appendBranch(it) }
+	firstChild = grandParent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+}

File scripts/siScore3.groovy

View file
+// @CacheScriptContent(true)
+// @ExecutionModes({ON_SINGLE_NODE})
+
+if (c.selected.icons.contains('very_negative') || c.selected.icons.contains('very_positive')) {
+	def full = 3
+
+	def baseTextSize = 12
+
+	def target = c.selected
+	def parent = target.parent
+	def grandParent = parent.parent
+
+	target.icons.icons.findAll { it.startsWith('full') }.each {
+		target.icons.remove(it)
+	}
+	target.icons.add("full-${full}")
+	target.style.font.size = baseTextSize + full
+
+	def pros = parent.children*.icons.findAll {
+		it.first == 'very_positive' }.collect { it[1][-1].toInteger() }
+	pros = pros.size() > 0 ? pros : [0]
+	def prosAvg = (pros.sum() / pros.size()).toDouble().round().toInteger()
+
+	def cons = parent.children*.icons.findAll {
+		it.first == 'very_negative' }.collect { it[1][-1].toInteger() }
+	cons = cons.size() > 0 ? cons : [0]
+	def consAvg = (cons.sum() / cons.size()).toDouble().round().toInteger()
+
+	full = (prosAvg - consAvg)
+	full = full > 0 ? full : 0
+
+	parent.icons.icons.findAll { it.startsWith('full') }.each {
+		parent.icons.remove(it)
+	}
+	parent.icons.add("full-${full}")
+	parent.style.font.size = baseTextSize + full
+	def hold = parent.children.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	parent.children.toList().each { it.delete() }
+	hold.each { parent.appendBranch(it) }
+	def firstChild = parent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+
+	hold = grandParent.children.findAll {
+		it.icons.contains('idea')
+	}.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	grandParent.style.font.size = baseTextSize + full
+	grandParent.children.toList().each { it.delete() }
+	hold.each { grandParent.appendBranch(it) }
+	firstChild = grandParent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+}

File scripts/siScore4.groovy

View file
+// @CacheScriptContent(true)
+// @ExecutionModes({ON_SINGLE_NODE})
+
+if (c.selected.icons.contains('very_negative') || c.selected.icons.contains('very_positive')) {
+	def full = 4
+
+	def baseTextSize = 12
+
+	def target = c.selected
+	def parent = target.parent
+	def grandParent = parent.parent
+
+	target.icons.icons.findAll { it.startsWith('full') }.each {
+		target.icons.remove(it)
+	}
+	target.icons.add("full-${full}")
+	target.style.font.size = baseTextSize + full
+
+	def pros = parent.children*.icons.findAll {
+		it.first == 'very_positive' }.collect { it[1][-1].toInteger() }
+	pros = pros.size() > 0 ? pros : [0]
+	def prosAvg = (pros.sum() / pros.size()).toDouble().round().toInteger()
+
+	def cons = parent.children*.icons.findAll {
+		it.first == 'very_negative' }.collect { it[1][-1].toInteger() }
+	cons = cons.size() > 0 ? cons : [0]
+	def consAvg = (cons.sum() / cons.size()).toDouble().round().toInteger()
+
+	full = (prosAvg - consAvg)
+	full = full > 0 ? full : 0
+
+	parent.icons.icons.findAll { it.startsWith('full') }.each {
+		parent.icons.remove(it)
+	}
+	parent.icons.add("full-${full}")
+	parent.style.font.size = baseTextSize + full
+	def hold = parent.children.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	parent.children.toList().each { it.delete() }
+	hold.each { parent.appendBranch(it) }
+	def firstChild = parent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+
+	hold = grandParent.children.findAll {
+		it.icons.contains('idea')
+	}.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	grandParent.style.font.size = baseTextSize + full
+	grandParent.children.toList().each { it.delete() }
+	hold.each { grandParent.appendBranch(it) }
+	firstChild = grandParent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+}

File scripts/siScore5.groovy

View file
+// @CacheScriptContent(true)
+// @ExecutionModes({ON_SINGLE_NODE})
+
+if (c.selected.icons.contains('very_negative') || c.selected.icons.contains('very_positive')) {
+	def full = 5
+
+	def baseTextSize = 12
+
+	def target = c.selected
+	def parent = target.parent
+	def grandParent = parent.parent
+
+	target.icons.icons.findAll { it.startsWith('full') }.each {
+		target.icons.remove(it)
+	}
+	target.icons.add("full-${full}")
+	target.style.font.size = baseTextSize + full
+
+	def pros = parent.children*.icons.findAll {
+		it.first == 'very_positive' }.collect { it[1][-1].toInteger() }
+	pros = pros.size() > 0 ? pros : [0]
+	def prosAvg = (pros.sum() / pros.size()).toDouble().round().toInteger()
+
+	def cons = parent.children*.icons.findAll {
+		it.first == 'very_negative' }.collect { it[1][-1].toInteger() }
+	cons = cons.size() > 0 ? cons : [0]
+	def consAvg = (cons.sum() / cons.size()).toDouble().round().toInteger()
+
+	full = (prosAvg - consAvg)
+	full = full > 0 ? full : 0
+
+	parent.icons.icons.findAll { it.startsWith('full') }.each {
+		parent.icons.remove(it)
+	}
+	parent.icons.add("full-${full}")
+	parent.style.font.size = baseTextSize + full
+	def hold = parent.children.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	parent.children.toList().each { it.delete() }
+	hold.each { parent.appendBranch(it) }
+	def firstChild = parent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+
+	hold = grandParent.children.findAll {
+		it.icons.contains('idea')
+	}.each { it.style.font.bold = false }.sort {
+		it.icons[1][-1].toInteger()
+	}.reverse()
+	grandParent.style.font.size = baseTextSize + full
+	grandParent.children.toList().each { it.delete() }
+	hold.each { grandParent.appendBranch(it) }
+	firstChild = grandParent.children.first()
+	c.select(firstChild)
+	firstChild.style.font.bold = true
+}