Notepad++¶
Notepad++ is a free text editor on MS Windows only.
Syntax highlighting¶
For the packages files (pkg).
Edit the AppData\Notepad++\userDefineLang.xml file (create it if it does'nt exist). By default, this file is in C:\Users\your_login\AppData\Roaming\Notepad++\
Add it this at the end :
<NotepadPlus> <UserLang name="Scol" ext="pkg" udlVersion="2.1"> <Settings> <Global caseIgnored="no" allowFoldOfComments="no" foldCompact="no" forcePureLC="0" decimalSeparator="0" /> <Prefix Keywords1="no" Keywords2="no" Keywords3="no" Keywords4="no" Keywords5="no" Keywords6="no" Keywords7="no" Keywords8="no" /> </Settings> <KeywordLists> <Keywords name="Comments">03/* 04*/ 00// 01 02</Keywords> <Keywords name="Numbers, prefix1"></Keywords> <Keywords name="Numbers, prefix2"></Keywords> <Keywords name="Numbers, extras1"></Keywords> <Keywords name="Numbers, extras2"></Keywords> <Keywords name="Numbers, suffix1"></Keywords> <Keywords name="Numbers, suffix2"></Keywords> <Keywords name="Numbers, range"></Keywords> <Keywords name="Operators1"></Keywords> <Keywords name="Operators2"></Keywords> <Keywords name="Folders in code1, open"></Keywords> <Keywords name="Folders in code1, middle"></Keywords> <Keywords name="Folders in code1, close"></Keywords> <Keywords name="Folders in code2, open"></Keywords> <Keywords name="Folders in code2, middle"></Keywords> <Keywords name="Folders in code2, close"></Keywords> <Keywords name="Folders in comment, open"></Keywords> <Keywords name="Folders in comment, middle"></Keywords> <Keywords name="Folders in comment, close"></Keywords> <Keywords name="Keywords1">fun typeof typedef var struct proto defcom defcomvar ;;</Keywords> <Keywords name="Keywords2">set let -> <- mutate in</Keywords> <Keywords name="Keywords3">if else then while do</Keywords> <Keywords name="Keywords4"></Keywords> <Keywords name="Keywords5"></Keywords> <Keywords name="Keywords6"></Keywords> <Keywords name="Keywords7"></Keywords> <Keywords name="Keywords8"></Keywords> <Keywords name="Delimiters">00' 01 02' 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23</Keywords> </KeywordLists> <Styles> <WordsStyle name="DEFAULT" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="COMMENTS" fgColor="008000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="LINE COMMENTS" fgColor="008000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="NUMBERS" fgColor="FF8040" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" /> <WordsStyle name="KEYWORDS1" fgColor="FF0000" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" /> <WordsStyle name="KEYWORDS2" fgColor="800000" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" /> <WordsStyle name="KEYWORDS3" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="KEYWORDS4" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="KEYWORDS5" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="KEYWORDS6" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="KEYWORDS7" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="KEYWORDS8" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="OPERATORS" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="FOLDER IN CODE1" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="FOLDER IN CODE2" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="FOLDER IN COMMENT" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="DELIMITERS1" fgColor="808080" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="DELIMITERS2" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="DELIMITERS3" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="DELIMITERS4" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="DELIMITERS5" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="DELIMITERS6" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="DELIMITERS7" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> <WordsStyle name="DELIMITERS8" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" /> </Styles> </UserLang> </NotepadPlus>
or, for an old NPP version :
<NotepadPlus> <UserLang name='Scol' ext='pkg'> <Settings> <Global caseIgnored='no' /> <TreatAsSymbol comment='no' commentLine='no' /> <Prefix words1='no' words2='no' words3='no' words4='no' /> </Settings> <KeywordLists> <Keywords name='Delimiters'>'00'00</Keywords> <Keywords name='Folder+'></Keywords> <Keywords name='Folder-'></Keywords> <Keywords name='Operators'></Keywords> <Keywords name='Comment'>1/* 2*/ 0//</Keywords> <Keywords name='Words1'>fun typeof typedef var struct proto defcom exec match with ;;</Keywords> <Keywords name='Words2'>set let -> <- mutate in</Keywords> <Keywords name='Words3'>if else then while do</Keywords> <Keywords name='Words4'></Keywords> </KeywordLists> <Styles> <WordsStyle name='DEFAULT' styleID='11' fgColor='000000' bgColor='FFFFFF' fontName='' fontStyle='0' /> <WordsStyle name='FOLDEROPEN' styleID='12' fgColor='000000' bgColor='FFFFFF' fontName='' fontStyle='0' /> <WordsStyle name='FOLDERCLOSE' styleID='13' fgColor='000000' bgColor='FFFFFF' fontName='' fontStyle='0' /> <WordsStyle name='KEYWORD1' styleID='5' fgColor='FF0000' bgColor='FFFFFF' fontName='' fontStyle='1' /> <WordsStyle name='KEYWORD2' styleID='6' fgColor='800000' bgColor='FFFFFF' fontName='' fontStyle='1' /> <WordsStyle name='KEYWORD3' styleID='7' fgColor='0000FF' bgColor='FFFFFF' fontName='' fontStyle='0' /> <WordsStyle name='KEYWORD4' styleID='8' fgColor='000000' bgColor='FFFFFF' fontName='' fontStyle='0' /> <WordsStyle name='COMMENT' styleID='1' fgColor='008000' bgColor='FFFFFF' fontName='' fontStyle='0' /> <WordsStyle name='COMMENT LINE' styleID='2' fgColor='008000' bgColor='FFFFFF' fontName='' fontStyle='0' /> <WordsStyle name='NUMBER' styleID='4' fgColor='FF8040' bgColor='FFFFFF' fontName='' fontStyle='1' /> <WordsStyle name='OPERATOR' styleID='10' fgColor='000000' bgColor='FFFFFF' fontName='' fontStyle='0' /> <WordsStyle name='DELIMINER1' styleID='14' fgColor='808080' bgColor='FFFFFF' fontName='' fontStyle='0' /> <WordsStyle name='DELIMINER2' styleID='15' fgColor='000000' bgColor='FFFFFF' fontName='' fontStyle='0' /> <WordsStyle name='DELIMINER3' styleID='16' fgColor='000000' bgColor='FFFFFF' fontName='' fontStyle='0' /> </Styles> </UserLang> </NotepadPlus>
Relaunch Notepad++ if any.
The code completion¶
Download the scol_api_notepadpp.7z file and extract the content in the plugins/api subdirectory of the installation folder (by default C:\Program Files\Notepad++ or C:\Programs\Notepad++)
Go to Settings menu, next Preferences and choose Save / Completion tab. Configure it at your convenience. Validate and relaunch Notepad++.
The FunctionList plugin¶
This plugin displays and sorts functions, types, constructors and variables in the side panel.
Download the lastest plugin named "FunctionList" from SourceForge
In the most case, you should get the UNICODE version.
Copy the dll in the Plugins subfolder of the installation directory. Perform a backup if any.
Copy all other files in AppData\Notepad++\Plugins\Config or in AppInstall\Notepad++\plugins\config\, especially FunctionListRules.xml
Edit the FunctionListRules.xml file and add it these line before just the last \"\"
<Language name='Scol' imagelistpath=''> <CommList param1='//' param2='' /> <CommList param1='/\*' param2='\*/' /> <Group name='FUNCTION' subgroup='' icon='0' child='0' autoexp='0' matchcase='1' fendtobbeg='' bbegtobend=''> <Rules regexbeg='^[ \t]*fun[ \t]+' regexfunc='[a-zA-Z0-9_]+' regexend='' bodybegin='\=' bodyend=';;' sep='' /> </Group> <Group name='TYPEOF' subgroup='' icon='0' child='0' autoexp='0' matchcase='1' fendtobbeg='' bbegtobend=''> <Rules regexbeg='^[ \t]*typeof[ \t]+' regexfunc='[a-zA-Z0-9_]+' regexend='' bodybegin='\=' bodyend=';;' sep='' /> </Group> <Group name='VAR' subgroup='' icon='0' child='0' autoexp='0' matchcase='1' fendtobbeg='' bbegtobend=''> <Rules regexbeg='^[ \t]*var[ \t]+' regexfunc='[a-zA-Z0-9_]+' regexend='' bodybegin='\=' bodyend=';;' sep='' /> </Group> <Group name='PROTO' subgroup='' icon='0' child='0' autoexp='0' matchcase='1' fendtobbeg='' bbegtobend=''> <Rules regexbeg='^[ \t]*proto[ \t]+' regexfunc='[a-zA-Z0-9_]+' regexend='' bodybegin='\=' bodyend=';;' sep='' /> </Group> <Group name='STRUCT' subgroup='' icon='0' child='0' autoexp='0' matchcase='1' fendtobbeg='' bbegtobend=''> <Rules regexbeg='^[ \t]*struct[ \t]+' regexfunc='[a-zA-Z0-9_]+' regexend='' bodybegin='\=' bodyend=';;' sep='' /> </Group> <Group name='TYPEDEF' subgroup='' icon='0' child='0' autoexp='0' matchcase='1' fendtobbeg='' bbegtobend=''> <Rules regexbeg='^[ \t]*typedef[ \t]+' regexfunc='[a-zA-Z0-9_]+' regexend='' bodybegin='\=' bodyend=';;' sep='' /> </Group> <Group name='DEFCOM' subgroup='' icon='0' child='0' autoexp='0' matchcase='1' fendtobbeg='' bbegtobend=''> <Rules regexbeg='^[ \t]*defcom[ \t]+' regexfunc='[a-zA-Z0-9_]+' regexend='' bodybegin='\=' bodyend=';;' sep='' /> </Group> <Group name='DEFCOMVAR' subgroup='' icon='0' child='0' autoexp='0' matchcase='1' fendtobbeg='' bbegtobend=''> <Rules regexbeg='^[ \t]*defcomvar[ \t]+' regexfunc='[a-zA-Z0-9_]+' regexend='' bodybegin='\=' bodyend=';;' sep='' /> </Group> </Language>
If the plugin doesn't work, try to uncheck "Make language Menu compact" in the menu Settings > Preferences > Language Menu.
You can edit too the file _AppData\Notepad++\functionList.xml (the same directory then the syntax highlighting above) to configure a parser for Scol :
- In the associationMap section, add the item :
<association userDefinedLangName="Scol" id="scol_function"/>
- In the parsers section, add this block :
<parser id="scol_function" displayName="Scol_source" commentExpr="((/\*.*?\*)/|(//.*?$))"> <function mainExpr="^[\t ]*fun[\s]+\w+\(" displayMode="$functionName"> <functionName> <nameExpr expr="(?!(if|whille))[\w_]+[\s]*\("/> <nameExpr expr="(?!(if|while))[\w_]+"/> </functionName> </function> </parser>
So, you should obtain something like this :
<?xml version="1.0" encoding="UTF-8" ?> <!-- For learning making your language parser, please check the following link: http://notepad-plus-plus.org/features/function-list.html --> <NotepadPlus> <functionList> <associationMap> <!-- langID: L_TEXT: 0 L_PHP: 1 L_C: 2 L_CPP: 3 L_CS: 4 L_OBJC: 5 L_JAVA: 6 L_RC: 7 L_HTML: 8 L_XML: 9 L_MAKEFILE: 10 L_PASCAL: 11 L_BATCH:12 L_INI: 13 L_ASCII: 14 L_USER: 15 L_ASP: 16 L_SQL: 17 L_VB: 18 L_JS: 19 L_CSS: 20 L_PERL: 21 L_PYTHON: 22 L_LUA: 23 L_TEX: 24 L_FORTRAN: 25 L_BASH: 26 L_FLASH: 27 L_NSIS: 28 L_TCL: 29 L_LISP: 30 L_SCHEME: 31 L_ASM: 32 L_DIFF: 33 L_PROPS: 34 L_PS: 35 L_RUBY: 36 L_SMALLTALK:37 L_VHDL: 38 L_KIX: 39 L_AU3: 40 L_CAML: 41 L_ADA: 42 L_VERILOG: 43 L_MATLAB: 44 L_HASKELL: 45 L_INNO: 46 L_SEARCHRESULT: 47 L_CMAKE: 48 L_YAML: 49 L_COBOL 50 L_GUI4CLI: 51 L_D: 52 L_POWERSHELL: 53 L_R: 54 L_JSP: 55 --> <association langID="1" id="php_function"/> <association langID="2" id="c_function"/> <association langID="3" id="c_cpp_function"/> <association langID="6" id="java"/> <association langID="9" id="xml_node"/> <association langID="12" id="batch_label"/> <association langID="13" id="ini_section"/> <association langID="19" id="js_function"/> <association langID="21" id="perl_function"/> <association langID="28" id="nsis_syntax"/> <association userDefinedLangName="Scol" id="scol_function"/> <!-- if langID cannot be found above, you can still set the file extensions <association ext=".my_passer_ext1" id="my_passer_id"/> <association ext=".my_passer_ext2" id="my_passer_id"/> for User Defined Languages: <association userDefinedLangName="my user defined language" id="my_udl_passer_id"/> <association userDefinedLangName="Autocad" id="my_autocad_passer_id"/> --> </associationMap> <parsers> <parser id="xml_node" displayName="XML Node" commentExpr="<!--([^-]|-(?!->))*-->"> <!-- Only match nodes with at least one attribute --> <function mainExpr="<[\w\?]+[\t ]+\w+[\t ]*=[\t ]*"[^"]+"" displayMode="$functionName"> <functionName> <nameExpr expr="[^<]*"/> </functionName> </function> </parser> <parser id="batch_label" displayName="BAT Label" commentExpr="((::.*?$)|(REM.*?$))"> <function mainExpr="^[\t ]*:\w+" displayMode="$functionName"> <functionName> <nameExpr expr="[^\t :]*"/> </functionName> </function> </parser> <parser id="ini_section" displayName="INI Section" commentExpr="((#.*?$)|(;.*?$))"> <function mainExpr="^[\t ]*[\["][\w_.; \(\)-]+[\]"]" displayMode="$functionName"> <functionName> <nameExpr expr="[^\[\]"]*"/> </functionName> </function> </parser> <parser id="java" displayName="Java" commentExpr="((/\*.*?\*)/|(//.**$))"> <classRange mainExpr="^[\t ]*((public|protected|private|static|final|abstract|synchronized|@(\w)+)\s+)*(class|enum|interface|@interface)\s+\w+(<\s*\w+(,\s*\w+)*\s*>)?(\s+extends\s+\w+)?(\s+implements\s+\w+(,\s*\w+)*)?\s*\{" openSymbole="\{" closeSymbole="\}"> <className> <nameExpr expr="(class|enum|interface|@interface)\s+\w+(<\s*\w+(,\s*\w+)*\s*>)?"></nameExpr> <nameExpr expr="\s+\w+(<\s*\w+(,\s*\w+)*\s*>)?"></nameExpr> <nameExpr expr="\w+(<\s*\w+(,\s*\w+)*\s*>)?"></nameExpr> </className> <function mainExpr="^[\t ]*((public|protected|private|static|final|abstract|synchronized|@(\w)+)\s+)*(\w*(\[\s*])*\s+)?(?!(if|while|for|switch|catch|synchronized)\b)\w+(\[\s*])*(<\s*\w+(,\s*\w+)*\s*>)?\s*\([^\)\(]*\)(\s+throws\s+\w+)?\s*\{"> <functionName> <funcNameExpr expr="(?!(if|while|for|switch|catch|synchronized)\b)\w+(\[\s*])*(<\s*\w+(,\s*\w+)*\s*>)?\s*\("></funcNameExpr> <funcNameExpr expr="(?!(if|while|for|switch|catch|synchronized)\b)\w+(\[\s*])*(<\s*\w+(,\s*\w+)*\s*>)?"></funcNameExpr> </functionName> </function> </classRange> </parser> <parser id="c_function" displayName="C source" commentExpr="((/\*.*?\*)/|(//.*?$))"> <function mainExpr="^[\t ]*((static|const|virtual)[\s]+)?[\w:]+([\s]+[\w]+)?([\s]+|\*[\s]+|[\s]+\*|[\s]+\*[\s]+)([\w_]+[\s]*::)?(?!(if|while|for))[\w_]+[\s]*\([^\)\(]*\)([\s]*const[\s]*)?[\n\s]*\{" displayMode="$functionName"> <functionName> <nameExpr expr="(?!(if|while|for))[\w_~]+[\s]*\("/> <nameExpr expr="(?!(if|while|for))[\w_~]+"/> </functionName> </function> </parser> <parser id="js_function" displayName="Javascript" commentExpr="((/\*.*?\*)/|(//.*?$))"> <function mainExpr="((^|[\s]+|[;\}\.])([_A-Za-z][\w_]*\.)*[_A-Za-z][\w_]*[\s]*=|^|[\s;\}]+)[\s]*function([\s]+[_A-Za-z]?[\w_]*\([^\)\(]*\)|\([^\)\(]*\))[\n\s]*\{" displayMode="$className->$functionName"> <functionName> <nameExpr expr="[_A-Za-z][\w_]*[\s]*=|[_A-Za-z]?[\w_]*[\s]*\("/> <nameExpr expr="[_A-Za-z]?[\w_]*"/> </functionName> <className> <nameExpr expr="([_A-Za-z][\w_]*\.)*[_A-Za-z][\w_]*\."/> <nameExpr expr="([_A-Za-z][\w_]*\.)*[_A-Za-z][\w_]*"/> </className> </function> </parser> <parser id="c_cpp_function" displayName="C++ Class" commentExpr="((/\*.*?\*)/|(//.*?$))"> <classRange mainExpr="^[\t ]*(class|struct)[\t ]+[\w]+[\s]*(:[\s]*(public|protected|private)[\s]+[\w]+[\s]*)?\{" openSymbole = "\{" closeSymbole = "\}" displayMode="node"> <className> <nameExpr expr="(class|struct)[\t ]+[\w]+"/> <nameExpr expr="[\t ]+[\w]+"/> <nameExpr expr="[\w]+"/> </className> <function mainExpr="^[\t ]*((static|const|virtual)[\s]+)?([\w]+([\s]+[\w]+)?([\s]+|\*[\s]+|[\s]+\*|[\s]+\*[\s]+))?([\w_]+[\s]*::)?(?!(if|while|for|switch))[\w_~]+[\s]*\([^\)\(]*\)([\s]*const[\s]*)?[\n\s]*\{"> <functionName> <funcNameExpr expr="(?!(if|while|for|switch))[\w_~]+[\s]*\("/> <funcNameExpr expr="(?!(if|while|for|switch))[\w_~]+"/> </functionName> </function> </classRange> <function mainExpr="^[\t ]*((static|const|virtual)[\s]+)?[\w]+([\s]+[\w]+)?([\s]+|\*[\s]+|[\s]+\*|[\s]+\*[\s]+)([\w_]+[\s]*::)?(?!(if|while|for))[\w_]+[\s]*\([^\)\(]*\)([\s]*const[\s]*)?[\n\s]*\{" displayMode="$className->$functionName"> <functionName> <nameExpr expr="(?!(if|while|for))[\w_]+[\s]*\("/> <nameExpr expr="(?!(if|while|for))[\w_]+"/> </functionName> <className> <nameExpr expr="[\w_]+(?=[\s]*::)"/> </className> </function> </parser> <parser id="nsis_syntax" displayName="NSIS Syntax" commentExpr="((/\*.*?\*)/|(#.*?$)|(;.*?$))"> <function mainExpr="^[\t ]*(!macro|Function|Section|SectionGroup)[\t ]+[^\r\n]*$" displayMode="$functionName"> <functionName> <nameExpr expr="(?(?=[\t ]*!macro)[\t ]*!macro[\t ]+[^\s]+|[^\r\n]*)"/> </functionName> </function> </parser> <parser id="perl_function" displayName="Perl"> <function mainExpr="sub[\s]+[\w]+[\s]*\([^\)\(]*\)[\n\s]*\{" displayMode="$className->$functionName"> <functionName> <nameExpr expr="(sub[\s]+)?\K[\w]+"/> </functionName> <className> <nameExpr expr="[\w]+(?=[\s]*::)"/> </className> </function> </parser> <parser id="php_function" displayName="PHP" commentExpr="((/\*.*?\*)/|(//.*?$))"> <classRange mainExpr="^[\t ]*(class|struct|abstract[\t ]+class)[\t ]+[\w]+([\s]*|[\s\t]*(extends|implement)[\t ]+[\w]+[\s]*)?\{" openSymbole = "\{" closeSymbole = "\}" displayMode="node"> <className> <nameExpr expr="(class|struct|abstract[\t ]+class)[\t ]+[\w]+"/> <nameExpr expr="[\t ]+[\w]+\Z"/> <nameExpr expr="[\w]+\Z"/> </className> <function mainExpr="^[\t ]*((static|public|protected|abstract|private|private[\s]+static|public[\s]+static|protected[\s]+static)[\s]+)?(function[\s]+)+([\w]+([\s]+[\w]+)?([\s]+|\*[\s]+|[\s]+\*|[\s]+\*[\s]+))?([\w_]+[\s]*::)?(?!(if|while|for|switch))[\w_~]+[\s]*\([^\{]*\{"> <functionName> <funcNameExpr expr="(?!(if|while|for|switch))[\w_~]+[\s]*\([^\{]*"/> <!-- comment below node if want display method with parmas --> <funcNameExpr expr="(?!(if|while|for|switch))[\w_~]+"/> </functionName> </function> </classRange> <function mainExpr="^[\t ]*function[\s]+\w+\(" displayMode="$className->$functionName"> <functionName> <nameExpr expr="(?!(if|while|for))[\w_]+[\s]*\("/> <nameExpr expr="(?!(if|while|for))[\w_]+"/> </functionName> <className> <nameExpr expr="[\w_]+(?=[\s]*::)"/> </className> </function> </parser> <parser id="scol_function" displayName="Scol_source" commentExpr="((/\*.*?\*)/|(//.*?$))"> <function mainExpr="^[\t ]*fun[\s]+\w+\(" displayMode="$functionName"> <functionName> <nameExpr expr="(?!(if|whille))[\w_]+[\s]*\("/> <nameExpr expr="(?!(if|while))[\w_]+"/> </functionName> </function> </parser> </parsers> </functionList> </NotepadPlus>
Save an relaunch NPP.
Note : NPP can be slower with the FunctionList plugin.
Updated by iri about 11 years ago · 4 revisions