Merge branch 'a12_2_a13'

This commit is contained in:
Basile Burg 2015-02-25 07:57:30 +01:00
commit 1735e9444b
9 changed files with 1153 additions and 45 deletions

24
cesyms/cesyms.coedit Normal file
View File

@ -0,0 +1,24 @@
object CurrentProject: TCEProject
OptionsCollection = <
item
name = 'release'
outputOptions.inlining = True
outputOptions.boundsCheck = offAlways
outputOptions.optimizations = True
outputOptions.release = True
pathsOptions.outputFilename = '..\lazproj\cesyms'
preBuildProcess.options = []
preBuildProcess.showWindow = swoNone
postBuildProcess.options = []
postBuildProcess.showWindow = swoNone
runOptions.options = []
runOptions.showWindow = swoNone
end>
Sources.Strings = (
'cesyms.d'
)
ConfigurationIndex = 0
LibraryAliases.Strings = (
'libdparse'
)
end

View File

@ -1,14 +1,23 @@
module runnable;
import std.path, std.file;
import std.stdio;
import std.d.lexer;
import std.d.ast;
import std.d.parser;
module cesyms;
import std.stdio, std.path, std.file, std.array, std.string;
import std.d.lexer, std.d.ast, std.d.parser;
static import std.conv;
interface I{}
alias Int32 = int;
//alias long Int64;
enum E
{
e1,
e2,
e3,
}
enum {opt1,opt2}
class A
{
class AA
@ -26,26 +35,42 @@ class A
enum SymbolType
{
_alias,
_alias, // X
_class, // X
_enum, // X
_function, // X
_interface, // X
_import,
_import, // X
_mixin,
_struct, // X
_template, // X
_union, // X
_variable
_variable // X
}
struct Symbol
{
uint line;
uint col;
int line;
int col;
string name;
SymbolType type;
Symbol * [] subs;
void serialize(ref Appender!string lfmApp)
{
lfmApp.put(" \r item\r");
lfmApp.put(format(" line = %d\r", line));
lfmApp.put(format(" col = %d\r", col));
lfmApp.put(format(" name = '%s'\r", name));
lfmApp.put(format(" symType = %s\r", type));
lfmApp.put(" subs = <");
if (subs.length) foreach(Symbol * sub; subs)
sub.serialize(lfmApp);
lfmApp.put(">\r");
lfmApp.put(" end\r");
}
}
void main(string[] args)
@ -68,11 +93,13 @@ void main(string[] args)
slb.visit(decl);
}
// TODO-cfeature: Outputs the symbol tree in a format handlable by a Coedit widget
int level = -1;
void print(Symbol * s)
{
foreach(i; 0..level) write(".");
foreach(i; 0 .. level) write(".");
level++;
write(s.name, '\r');
foreach(ss; s.subs)
@ -80,16 +107,21 @@ void main(string[] args)
level--;
}
//print(&slb.root);
print(&slb.root);
writeln();
auto str = slb.serialize;
//std.file.write(r"C:\too.txt",cast(ubyte[])str);
write(str);
stdout.flush;
}
class SymbolListBuilder : ASTVisitor
{
Symbol root;
Symbol * parent;
size_t count;
alias visit = ASTVisitor.visit;
@ -97,11 +129,25 @@ class SymbolListBuilder : ASTVisitor
void resetRoot(){parent = &root;}
string serialize()
{
Appender!string lfmApp;
lfmApp.reserve(count * 64);
lfmApp.put("object TSymbolList\r symbols = <");
foreach(Symbol * sym; root.subs) sym.serialize(lfmApp);
lfmApp.put(">\rend\r\n");
return lfmApp.data;
}
/// returns a new symbol if the declarator is based on a Token named "name".
Symbol * addDeclaration(DT)(DT adt)
{
static if
(
is(DT == const(AliasInitializer)) ||
is(DT == const(ClassDeclaration)) ||
is(DT == const(Declarator)) ||
is(DT == const(EnumDeclaration)) ||
@ -113,8 +159,9 @@ class SymbolListBuilder : ASTVisitor
)
{
count++;
auto result = new Symbol;
result.name = adt.name.text;
result.name = adt.name.text.idup;
result.line = adt.name.line;
result.col = adt.name.column;
parent.subs ~= result;
@ -130,17 +177,21 @@ class SymbolListBuilder : ASTVisitor
auto newSymbol = addDeclaration(dt);
newSymbol.type = st;
//
static if (dig)
{
auto previousParent = parent;
scope(exit) parent = previousParent;
parent = newSymbol;
static if (dig) dt.accept(this);
parent = previousParent;
dt.accept(this);
}
}
final override void visit(const AliasDeclaration aliasDeclaration)
final override void visit(const AliasDeclaration decl)
{
// IdentifierList
// old alias syntax not supported by this.
// why is initializers an array ?
if (decl.initializers.length == 1)
namedVisitorImpl!(AliasInitializer, SymbolType._alias)(decl.initializers[0]);
}
final override void visit(const ClassDeclaration decl)
@ -150,6 +201,7 @@ class SymbolListBuilder : ASTVisitor
final override void visit(const EnumDeclaration decl)
{
// TODO-ctest: try to see if what dmd outputs as , "enum member" is handled.
namedVisitorImpl!(EnumDeclaration, SymbolType._class)(decl);
}
@ -165,19 +217,32 @@ class SymbolListBuilder : ASTVisitor
final override void visit(const ImportDeclaration decl)
{
// singlesImp[]
// singleImport.identifierchain.join
import std.array;
foreach(const(SingleImport) si; decl.singleImports)
writeln( si.identifierChain.identifiers[0].text );
{
if (!si.identifierChain.identifiers.length)
continue;
//
string[] modules;
foreach(ident; si.identifierChain.identifiers)
{
modules ~= ident.text;
modules ~= ".";
}
//
count++;
auto result = new Symbol;
result.name = modules[0..$-1].join;
result.line = si.identifierChain.identifiers[0].line;
result.col = si.identifierChain.identifiers[0].column;
result.type = SymbolType._import;
parent.subs ~= result;
}
}
final override void visit(const MixinDeclaration decl)
{
// identifier
// TODO-cfeature: MixinDeclaration, just display the name of the mixed template.
// the template might be implemented in another module so their ùeùbrs cant be displayed.
}
final override void visit(const StructDeclaration decl)

13
cesyms/readme.md Normal file
View File

@ -0,0 +1,13 @@
ceSyms
======
Tool designed to build a symbol tree for a particular D module.
It's written in D using Coedit. To build it, [libdparse](https://github.com/Hackerpilot/libdparse)
must be setup in the [libman](https://github.com/BBasile/Coedit/wiki#library-manager-widget)
as described in this [tutorial](https://github.com/BBasile/Coedit/wiki#lets-build-a-static-library).
This tool is mandatory to enable the new _Symbol list widget_.
If missing, the old _static explorer widget_ still does the same but it's from far less
efficient since it actually compiles while only the AST is needed.
The new tool does not take the module correctness in account.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 KiB

View File

@ -5,11 +5,3 @@ Tool designed to analyze the _TODO comments_ in D source files.
It's written in D using Coedit. To build it, [libdparse](https://github.com/Hackerpilot/libdparse)
must be setup in the [libman](https://github.com/BBasile/Coedit/wiki#library-manager-widget)
as described in this [tutorial](https://github.com/BBasile/Coedit/wiki#lets-build-a-static-library).
alpha 11 preview
================
![](https://github.com/BBasile/Coedit/blob/master/cetodo/a11.tdl.png)
In the widget, empty categories are auto hidden, items are double click-able.
Items can only be edited in the source-code.

View File

@ -132,7 +132,7 @@
<PackageName Value="LCL"/>
</Item6>
</RequiredPackages>
<Units Count="37">
<Units Count="38">
<Unit0>
<Filename Value="coedit.lpr"/>
<IsPartOfProject Value="True"/>
@ -167,6 +167,7 @@
<Unit6>
<Filename Value="..\src\ce_dlangutils.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ce_dlangutils"/>
</Unit6>
<Unit7>
<Filename Value="..\src\ce_dmdwrap.pas"/>
@ -303,6 +304,7 @@
<ComponentName Value="CEToolsEditorWidget"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="ce_toolseditor"/>
</Unit27>
<Unit28>
<Filename Value="..\src\ce_txtsyn.pas"/>
@ -358,6 +360,14 @@
<ResourceBaseClass Value="Frame"/>
<UnitName Value="ce_shortcutseditor"/>
</Unit36>
<Unit37>
<Filename Value="..\src\ce_symlist.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="CESymbolListWidget"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="ce_symlist"/>
</Unit37>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -12,7 +12,7 @@ uses
ce_messages, ce_interfaces, ce_editor, ce_projinspect, ce_projconf, ce_search,
ce_staticexplorer, ce_miniexplorer, ce_libman, ce_libmaneditor, ce_todolist,
ce_observer, ce_writableComponent, ce_toolseditor, ce_procinput, ce_optionseditor,
ce_cdbcmd;
ce_cdbcmd, ce_symlist;
type
@ -198,6 +198,7 @@ type
fPrInpWidg: TCEProcInputWidget;
fTodolWidg: TCETodoListWidget;
fOptEdWidg: TCEOptionEditorWidget;
fSymlWidg: TCESymbolListWidget;
//fResWidg: TCEResmanWidget;
{$IFDEF WIN32}
fCdbWidg: TCECdbWidget;
@ -421,6 +422,7 @@ begin
fPrInpWidg:= TCEProcInputWidget.create(self);
fTodolWidg:= TCETodoListWidget.create(self);
fOptEdWidg:= TCEOptionEditorWidget.create(self);
fSymlWidg := TCESymbolListWidget.create(self);
//fResWidg := TCEResmanWidget.create(self);
getMessageDisplay(fMsgs);
@ -441,6 +443,7 @@ begin
fWidgList.addWidget(@fPrInpWidg);
fWidgList.addWidget(@fTodolWidg);
fWidgList.addWidget(@fOptEdWidg);
fWidgList.addWidget(@fSymlWidg);
//fWidgList.addWidget(@fResWidg);
{$IFDEF WIN32}

400
src/ce_symlist.lfm Normal file
View File

@ -0,0 +1,400 @@
inherited CESymbolListWidget: TCESymbolListWidget
Left = 1548
Height = 430
Top = 457
Width = 310
Caption = 'Symbol list'
ClientHeight = 430
ClientWidth = 310
inherited Back: TPanel
Height = 430
Width = 310
ClientHeight = 430
ClientWidth = 310
inherited Content: TPanel
Height = 430
Width = 310
ClientHeight = 430
ClientWidth = 310
PopupMenu = nil
object Tree: TTreeView[0]
Left = 4
Height = 394
Top = 32
Width = 302
Align = alClient
BorderSpacing.Around = 4
DefaultItemHeight = 18
ExpandSignType = tvestPlusMinus
HideSelection = False
Images = imgList
ReadOnly = True
RightClickSelect = True
RowSelect = True
ScrollBars = ssAutoBoth
SelectionColor = clActiveBorder
TabOrder = 0
OnDeletion = TreeDeletion
OnKeyPress = TreeKeyPress
Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoRightClickSelect, tvoRowSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw]
Items.Data = {
F9FFFFFF02000B000000000000000000000000000000FFFFFFFF000000000000
00000005000000416C696173010000000100000001000000FFFFFFFF00000000
000000000007000000436C6173736573020000000200000002000000FFFFFFFF
00000000000000000005000000456E756D73030000000300000003000000FFFF
FFFF0000000000000000000800000046756E6374696F6E040000000400000004
000000FFFFFFFF00000000000000000007000000496D706F7274730500000005
00000005000000FFFFFFFF00000000000000000009000000496E746572666163
65060000000600000006000000FFFFFFFF000000000000000000050000004D69
78696E070000000700000007000000FFFFFFFF00000000000000000007000000
53747275637473080000000800000008000000FFFFFFFF000000000000000000
0900000054656D706C61746573000000000000000000000000FFFFFFFF000000
00000000000005000000556E696F6E010000000100000001000000FFFFFFFF00
0000000000000000080000005661726961626C65
}
TreeLineColor = 14671839
TreeLinePenStyle = psSolid
end
object Panel1: TPanel[1]
Left = 2
Height = 26
Top = 2
Width = 306
Align = alTop
BorderSpacing.Around = 2
BevelOuter = bvNone
ClientHeight = 26
ClientWidth = 306
PopupMenu = contextMenu
TabOrder = 1
object TreeFilterEdit1: TTreeFilterEdit
Left = 32
Height = 22
Top = 2
Width = 272
OnAfterFilter = TreeFilterEdit1AfterFilter
ButtonWidth = 28
NumGlyphs = 1
Align = alClient
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 0
FilteredTreeview = Tree
end
object btnRefresh: TBitBtn
Left = 2
Height = 22
Hint = 'refresh the list'
Top = 2
Width = 28
Align = alLeft
BorderSpacing.Around = 2
Layout = blGlyphBottom
OnClick = btnRefreshClick
Spacing = 0
TabOrder = 1
end
end
end
end
inherited contextMenu: TPopupMenu
left = 112
top = 48
end
object imgList: TImageList[2]
left = 80
top = 48
Bitmap = {
4C69090000001000000010000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF000000000064646497626262FF616161FF626262FF6464649700000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00646464976F6E6EFFA6A5A4FFA9A8A9FFA6A5A4FF6D6E6EFF64646497FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00626363FFA7A5A5FF7D7B7AFF787675FF7D7B7AFFA7A5A5FF626363FFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00626363FF8E8C8BFF767371FF767371FF767371FF8E8C8BFF626363FFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00636464FF858381FF878481FF868381FF878481FF858381FF636464FFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00585858AC6F6E6EFF95918FFF989492FF95918FFF6F6E6EFF585858ACFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF000000001E585858AC636363FF626263FF636363FF585858AC0000001EFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000000000001E0000003300000033000000330000001E00000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF0000000000B9851C97B78319FFB68217FFB78319FFB9851C9700000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00B9851C97C6922EFFECC482FFEFC886FFECC482FFC6912CFFB9851C97FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00B78319FFEEC684FFE5AA49FFE2A641FFE5AA49FFEEC684FFB78319FFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00B78219FFEBB964FFE3A641FFE3A641FFE3A641FFEBB964FFB78219FFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00B7841AFFEAB45CFFE9B45CFFE8B35BFFE9B45CFFEAB45CFFB7841AFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00A37519ACC5922FFFEDC074FFF1C47AFFEDC074FFC5922FFFA37519ACFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF000000001EA37519ACB78319FFB68218FFB78319FFA37519AC0000001EFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000000000001E0000003300000033000000330000001E00000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF0000000000008C4B97008A48FF008946FF008A48FF008C4B9700000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00008C4B97109F63FF74DAB7FF7ADEBDFF74DAB7FF109F63FF008C4B97FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00008A49FF66DAB4FF1EC68EFF16C388FF1EC68EFF66DAB4FF008A49FFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00008948FF25CF99FF00C07FFF00BE7EFF00C07FFF25CF99FF008948FFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00008A4AFF00C789FF00C88AFF00C689FF00C88AFF00C789FF008A4AFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00007B43AC009B5CFF00CE90FF00D194FF00CE90FF009B5CFF007B43ACFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF000000001E007B43AC008A4AFF008949FF008A4AFF007B43AC0000001EFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000000000001E0000003300000033000000330000001E00000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000002C70DC97296DDBFF286CDBFF296DDBFF2C70DC9700000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF002D70DC974083E7FF95C2FFFF9BC7FFFF95C2FFFF4081E7FF2D70DC97FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF002B6EDBFF8FC3FFFF5AA4FFFF53A1FFFF5AA4FFFF8FC3FFFF2B6EDBFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF002B6DDBFF65B2FFFF449EFFFF449DFFFF449EFFFF65B2FFFF2B6DDBFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF002D6FDBFF4FA9FFFF4FA9FFFF4EA7FFFF4FA9FFFF4FA9FFFF2D6FDBFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF002863C1AC387FE4FF56B2FFFF58B6FFFF56B2FFFF387FE4FF2863C1ACFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF000000001E2862C1AC2D6EDBFF2D6DDBFF2D6EDBFF2862C1AC0000001EFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000000000001E0000003300000033000000330000001E00000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000009A6BDC979968DBFF9968DBFF9968DBFF9A6BDC9700000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF009A6BDC97A17DE7FFC6BCFFFFC9C1FFFFC6BCFFFFA17DE7FF9A6BDC97FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF009A69DBFFC5BDFFFFAA9DFFFFA798FFFFAA9DFFFFC5BDFFFF9A69DBFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF009A68DBFFB3ACFFFFA396FFFFA396FFFFA396FFFFB3ACFFFF9A68DBFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF009A69DBFFACA5FFFFACA5FFFFABA3FFFFACA5FFFFACA5FFFF9A69DBFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00885EC1ACA17BE4FFB3B1FFFFB4B6FFFFB3B1FFFFA17BE4FF885EC1ACFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF000000001E885EC1AC9A69DBFF9A68DBFF9A69DBFF885EC1AC0000001EFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000000000001E0000003300000033000000330000001E00000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF0000000000AB499C97AA459AFFA94499FFAA459AFFAB499C9700000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00AB499C97B462AAFFD8B8D9FFDBBEDDFFD8B8D9FFB462AAFFAB499C97FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00AA469AFFDCB6DAFFCA91C9FFC78CC5FFCA91C9FFDCB6DAFFAA469AFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00A94699FFD69ED4FFCA83C7FFCA83C6FFCA83C7FFD69ED4FFA94699FFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00AA489AFFD68ED1FFD68ED2FFD58DD1FFD68ED2FFD68ED1FFAA489AFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00964189ACB85CAAFFE195DAFFE499DEFFE195DAFFB85CAAFF964189ACFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF000000001E964189ACA94899FFA84799FFA94899FF964189AC0000001EFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000000000001E0000003300000033000000330000001E00000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF0000000000354CCD973249CCFF3148CBFF3249CCFF354CCD9700000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00354CCD97455DDBFF90A6FCFF95ACFFFF90A6FCFF445DDBFF354CCD97FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00334ACCFF90A5FDFF5A79FAFF5573F9FF5A79FAFF90A5FDFF334ACCFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00334ACBFF6D88FFFF4D6DFBFF4D6DFAFF4D6DFBFF6D88FFFF334ACBFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00354BCBFF5F7CFFFF607CFFFF5F7BFDFF607CFFFF5F7CFFFF354BCBFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF002F44B4AC425AD9FF6F88FFFF738CFFFF6F88FFFF425AD9FF2F44B4ACFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF000000001E2F44B4AC344BCBFF334ACAFF344BCBFF2F44B4AC0000001EFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000000000001E0000003300000033000000330000001E00000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000002CC1FF9729C0FFFF28C0FFFF29C0FFFF2CC1FF9700000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF002DC1FF9741C6FFFF96DCFFFF9CDDFFFF96DCFFFF41C5FFFF2DC1FF97FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF002AC0FFFF95DDFFFF62CDFFFF5CCBFFFF62CDFFFF95DDFFFF2AC0FFFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF002AC0FFFF75D7FFFF56CEFFFF56CEFFFF56CEFFFF75D7FFFF2AC0FFFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF002BC0FFFF68D8FFFF69D8FFFF68D8FFFF69D8FFFF68D8FFFF2BC0FFFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF0028AAE0AC3EC9FFFF76E0FFFF7BE2FFFF76E0FFFF3EC9FFFF28AAE0ACFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF000000001E28AAE0AC2BC0FFFF2ABFFFFF2BC0FFFF28AAE0AC0000001EFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000000000001E0000003300000033000000330000001E00000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF0000000000DADADA97D9D9DAFFD9D9D9FFD9D9DAFFDADADA9700000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00DADADA97DADADBFFE5E5E4FFE6E6E4FFE5E5E4FFDADAD9FFDADADA97FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00D9DADAFFE6E6E5FFDBDBD9FFDADAD8FFDBDBD9FFE6E6E5FFD9DADAFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00D9DADAFFE2E1E0FFDBDAD9FFDBDAD9FFDBDAD9FFE2E1E0FFD9DADAFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00D9DADAFFE2E1E0FFE3E2E0FFE2E1E0FFE3E2E0FFE2E1E0FFD9DADAFFFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00BFBFBFACDDDDDDFFE8E7E6FFE9E8E7FFE8E7E6FFDDDDDDFFBFBFBFACFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF000000001EBFBFBFACD9D9D9FFD9D9D9FFD9D9D9FFBFBFBFAC0000001EFFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00000000000000001E0000003300000033000000330000001E00000000FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00
}
end
end

601
src/ce_symlist.pas Normal file
View File

@ -0,0 +1,601 @@
unit ce_symlist;
{$I ce_defines.inc}
interface
uses
Classes, SysUtils, TreeFilterEdit, Forms, Controls, Graphics, ExtCtrls, Menus,
ComCtrls, ce_widget, jsonparser, process, actnlist, Buttons, Clipbrd,
ce_common, ce_observer, ce_synmemo, ce_interfaces, LCLProc;
type
// Enumerates the possible symbol kind. To be kept in sync with the tool declaration.
TSymbolType = (
_alias,
_class,
_enum,
_function,
_interface,
_import,
_mixin,
_struct,
_template,
_union,
_variable
);
TSymbolCollection = class;
// Encapsulates a symbol to enable structured serialization
TSymbol = class(TCollectionItem)
private
fline, fCol: integer;
fName: string;
fType: TSymbolType;
fSubs: TSymbolCollection;
procedure setSubs(aValue: TSymbolCollection);
published
property line: Integer read fline write fLine;
property col: Integer read fCol write fCol;
property name: string read fName write fName;
property symType: TSymbolType read fType write fType;
property subs: TSymbolCollection read fSubs write setSubs;
public
constructor Create(ACollection: TCollection); override;
destructor destroy; override;
end;
// Encapsulates a ssymbol ub symbols.
TSymbolCollection = class(TCollection)
private
function getSub(index: Integer): TSymbol;
public
constructor create;
property sub[index: Integer]: TSymbol read getSub; default;
end;
// Serializable Symbol list
TSymbolList = class(TComponent)
private
fSymbols: TSymbolCollection;
procedure setSymbols(aValue: TSymbolCollection);
published
property symbols: TSymbolCollection read fSymbols write setSymbols;
public
constructor create(aOwner: TCOmponent); override;
destructor destroy; override;
//
procedure LoadFromTool(str: TStream);
end;
TCESymbolListWidget = class(TCEWidget, ICEMultiDocObserver)
btnRefresh: TBitBtn;
imgList: TImageList;
Panel1: TPanel;
Tree: TTreeView;
TreeFilterEdit1: TTreeFilterEdit;
procedure btnRefreshClick(Sender: TObject);
procedure TreeDeletion(Sender: TObject; Node: TTreeNode);
procedure TreeFilterEdit1AfterFilter(Sender: TObject);
procedure TreeKeyPress(Sender: TObject; var Key: char);
private
fSyms: TSymbolList;
fMsgs: ICEMessagesDisplay;
fToolProc: TCheckedAsyncProcess;
fActCopyIdent: TAction;
fActRefresh: TAction;
fActRefreshOnChange: TAction;
fActRefreshOnFocus: TAction;
fActAutoRefresh: TAction;
fActSelectInSource: TAction;
fDoc: TCESynMemo;
fAutoRefresh: boolean;
fRefreshOnChange: boolean;
fRefreshOnFocus: boolean;
ndAlias, ndClass, ndEnum, ndFunc, ndUni: TTreeNode;
ndImp, ndIntf, ndMix, ndStruct, ndTmp, ndVar: TTreeNode;
procedure TreeDblClick(Sender: TObject);
procedure actRefreshExecute(Sender: TObject);
procedure actAutoRefreshExecute(Sender: TObject);
procedure actRefreshOnChangeExecute(Sender: TObject);
procedure actRefreshOnFocusExecute(Sender: TObject);
procedure actCopyIdentExecute(Sender: TObject);
procedure updateVisibleCat;
procedure clearTree;
//
procedure callToolProc;
procedure symbolListProduced(sender: TObject);
//
procedure optget_AutoRefresh(aWriter: TWriter);
procedure optset_AutoRefresh(aReader: TReader);
procedure optget_RefreshOnChange(aWriter: TWriter);
procedure optset_RefreshOnChange(aReader: TReader);
procedure optget_RefreshOnFocus(aWriter: TWriter);
procedure optset_RefreshOnFocus(aReader: TReader);
//
procedure docNew(aDoc: TCESynMemo);
procedure docClosing(aDoc: TCESynMemo);
procedure docFocused(aDoc: TCESynMemo);
procedure docChanged(aDoc: TCESynMemo);
protected
procedure UpdateByDelay; override;
//
procedure sesoptDeclareProperties(aFiler: TFiler); override;
//
function contextName: string; override;
function contextActionCount: integer; override;
function contextAction(index: integer): TAction; override;
//
procedure SetVisible(Value: boolean); override;
published
property autoRefresh: boolean read fAutoRefresh write fAutoRefresh;
property refreshOnChange: boolean read fRefreshOnChange write fRefreshOnChange;
property refreshOnFocus: boolean read fRefreshOnFocus write fRefreshOnFocus;
public
constructor create(aOwner: TComponent); override;
destructor destroy; override;
end;
implementation
{$R *.lfm}
{$REGION Serializable symbols---------------------------------------------------}
constructor TSymbol.create(ACollection: TCollection);
begin
inherited create(ACollection);
fSubs := TSymbolCollection.create;
end;
destructor TSymbol.destroy;
begin
fSubs.Free;
inherited;
end;
procedure TSymbol.setSubs(aValue: TSymbolCollection);
begin
fSubs.Assign(aValue);
end;
constructor TSymbolCollection.create;
begin
inherited create(TSymbol);
end;
function TSymbolCollection.getSub(index: Integer): TSymbol;
begin
exit(TSymbol(self.Items[index]));
end;
constructor TSymbolList.create(aOwner: TCOmponent);
begin
inherited;
fSymbols := TSymbolCollection.create;
end;
destructor TSymbolList.destroy;
begin
fSymbols.free;
inherited;
end;
procedure TSymbolList.setSymbols(aValue: TSymbolCollection);
begin
fSymbols.Assign(aValue);
end;
procedure TSymbolList.LoadFromTool(str: TStream);
var
bin: TMemoryStream;
begin
bin := TMemoryStream.Create;
try
str.Position:=0;
ObjectTextToBinary(str, bin);
bin.Position:=0;
bin.ReadComponent(self);
finally
bin.Free;
end;
end;
{$ENDREGION}
{$REGION Standard Comp/Obj------------------------------------------------------}
constructor TCESymbolListWidget.create(aOwner: TComponent);
var
png: TPortableNetworkGraphic;
begin
fAutoRefresh := false;
fRefreshOnFocus := true;
fRefreshOnChange := false;
//
fActCopyIdent := TAction.Create(self);
fActCopyIdent.OnExecute:=@actCopyIdentExecute;
fActCopyIdent.Caption := 'Copy identifier';
fActRefresh := TAction.Create(self);
fActRefresh.OnExecute := @actRefreshExecute;
fActRefresh.Caption := 'Refresh';
fActAutoRefresh := TAction.Create(self);
fActAutoRefresh.OnExecute := @actAutoRefreshExecute;
fActAutoRefresh.Caption := 'Auto-refresh';
fActAutoRefresh.AutoCheck := true;
fActAutoRefresh.Checked := fAutoRefresh;
fActRefreshOnChange := TAction.Create(self);
fActRefreshOnChange.OnExecute := @actRefreshOnChangeExecute;
fActRefreshOnChange.Caption := 'Refresh on change';
fActRefreshOnChange.AutoCheck := true;
fActRefreshOnChange.Checked := fRefreshOnChange;
fActRefreshOnFocus := TAction.Create(self);
fActRefreshOnFocus.OnExecute := @actRefreshOnFocusExecute;
fActRefreshOnFocus.Caption := 'Refresh on focused';
fActRefreshOnFocus.AutoCheck := true;
fActRefreshOnFocus.Checked := fRefreshOnFocus;
fActSelectInSource := TAction.Create(self);
fActSelectInSource.OnExecute := @TreeDblClick;
fActSelectInSource.Caption := 'Select in source';
//
inherited;
// allow empty name if owner is nil
fSyms := TSymbolList.create(nil);
//
ndAlias := Tree.Items[0];
ndClass := Tree.Items[1];
ndEnum := Tree.Items[2];
ndFunc := Tree.Items[3];
ndImp := Tree.Items[4];
ndIntf := Tree.Items[5];
ndMix := Tree.Items[6];
ndStruct := Tree.Items[7];
ndTmp := Tree.Items[8];
ndUni := Tree.Items[9];
ndVar := Tree.Items[10];
//
png := TPortableNetworkGraphic.Create;
try
png.LoadFromLazarusResource('arrow_update');
btnRefresh.Glyph.Assign(png);
finally
png.Free;
end;
//
Tree.OnDblClick := @TreeDblClick;
Tree.PopupMenu := contextMenu;
//
EntitiesConnector.addObserver(self);
end;
destructor TCESymbolListWidget.destroy;
begin
EntitiesConnector.removeObserver(self);
//
killProcess(fToolProc);
fSyms.Free;
inherited;
end;
procedure TCESymbolListWidget.SetVisible(Value: boolean);
begin
inherited;
getMessageDisplay(fMsgs);
if Value then
callToolProc;
end;
{$ENDREGION}
{$REGION ICESessionOptionsObserver ---------------------------------------------}
procedure TCESymbolListWidget.optget_AutoRefresh(aWriter: TWriter);
begin
aWriter.WriteBoolean(fAutoRefresh);
end;
procedure TCESymbolListWidget.optset_AutoRefresh(aReader: TReader);
begin
fAutoRefresh := aReader.ReadBoolean;
fActAutoRefresh.Checked := fAutoRefresh;
end;
procedure TCESymbolListWidget.optget_RefreshOnChange(aWriter: TWriter);
begin
aWriter.WriteBoolean(fRefreshOnChange);
end;
procedure TCESymbolListWidget.optset_RefreshOnChange(aReader: TReader);
begin
fRefreshOnChange := aReader.ReadBoolean;
fActRefreshOnChange.Checked := fRefreshOnChange;
end;
procedure TCESymbolListWidget.optget_RefreshOnFocus(aWriter: TWriter);
begin
aWriter.WriteBoolean(fRefreshOnFocus);
end;
procedure TCESymbolListWidget.optset_RefreshOnFocus(aReader: TReader);
begin
fRefreshOnFocus := aReader.ReadBoolean;
fActRefreshOnFocus.Checked := fRefreshOnFocus;
end;
procedure TCESymbolListWidget.sesoptDeclareProperties(aFiler: TFiler);
begin
inherited;
aFiler.DefineProperty(Name + '_AutoRefresh', @optset_AutoRefresh, @optget_AutoRefresh, true);
aFiler.DefineProperty(Name + '_RefreshOnChange', @optset_RefreshOnChange, @optget_RefreshOnChange, true);
aFiler.DefineProperty(Name + '_RefreshOnFocus', @optset_RefreshOnFocus, @optget_RefreshOnFocus, true);
end;
{$ENDREGION}
{$REGION ICEContextualActions---------------------------------------------------}
function TCESymbolListWidget.contextName: string;
begin
result := 'Static explorer';
end;
function TCESymbolListWidget.contextActionCount: integer;
begin
result := 6;
end;
function TCESymbolListWidget.contextAction(index: integer): TAction;
begin
case index of
0: exit(fActSelectInSource);
1: exit(fActCopyIdent);
2: exit(fActRefresh);
3: exit(fActAutoRefresh);
4: exit(fActRefreshOnChange);
5: exit(fActRefreshOnFocus);
else result := nil;
end;
end;
procedure TCESymbolListWidget.actRefreshExecute(Sender: TObject);
begin
if Updating then exit;
callToolProc;
end;
procedure TCESymbolListWidget.actAutoRefreshExecute(Sender: TObject);
begin
autoRefresh := not autoRefresh;
end;
procedure TCESymbolListWidget.actRefreshOnChangeExecute(Sender: TObject);
begin
refreshOnChange := not refreshOnChange;
end;
procedure TCESymbolListWidget.actRefreshOnFocusExecute(Sender: TObject);
begin
refreshOnFocus := not refreshOnFocus;
end;
procedure TCESymbolListWidget.actCopyIdentExecute(Sender: TObject);
begin
if Tree.Selected = nil then exit;
Clipboard.AsText:= Tree.Selected.Text;
end;
{$ENDREGION}
{$REGION ICEMultiDocObserver ---------------------------------------------------}
procedure TCESymbolListWidget.docNew(aDoc: TCESynMemo);
begin
fDoc := aDoc;
beginUpdateByDelay;
end;
procedure TCESymbolListWidget.docClosing(aDoc: TCESynMemo);
begin
if fDoc <> aDoc then exit;
fDoc := nil;
clearTree;
updateVisibleCat;
beginUpdateByDelay;
end;
procedure TCESymbolListWidget.docFocused(aDoc: TCESynMemo);
begin
if fDoc = aDoc then exit;
fDoc := aDoc;
if not Visible then exit;
//
if fAutoRefresh then beginUpdateByDelay
else if fRefreshOnFocus then callToolProc;
end;
procedure TCESymbolListWidget.docChanged(aDoc: TCESynMemo);
begin
if fDoc <> aDoc then exit;
if not Visible then exit;
//
if fAutoRefresh then beginUpdateByDelay
else if fRefreshOnChange then callToolProc;
end;
{$ENDREGION}
{$REGION Symbol-tree things ----------------------------------------------------}
procedure TCESymbolListWidget.UpdateByDelay;
begin
if not fAutoRefresh then exit;
callToolProc;
end;
procedure TCESymbolListWidget.TreeDeletion(Sender: TObject; Node: TTreeNode);
begin
if (node.Data <> nil) then
Dispose(PInt64(node.Data));
end;
procedure TCESymbolListWidget.btnRefreshClick(Sender: TObject);
begin
fActRefresh.Execute;
end;
procedure TCESymbolListWidget.updateVisibleCat;
begin
if (fDoc <> nil) then
begin
ndAlias.Visible := ndAlias.Count > 0;
ndClass.Visible := ndClass.Count > 0;
ndEnum.Visible := ndEnum.Count > 0;
ndFunc.Visible := ndFunc.Count > 0;
ndImp.Visible := ndImp.Count > 0;
ndIntf.Visible := ndIntf.Count > 0;
ndMix.Visible := ndMix.Count > 0;
ndStruct.Visible:= ndStruct.Count > 0;
ndTmp.Visible := ndTmp.Count > 0;
ndUni.Visible := ndUni.Count > 0;
ndVar.Visible := ndVar.Count > 0;
end else
begin
ndAlias.Visible := true;
ndClass.Visible := true;
ndEnum.Visible := true;
ndFunc.Visible := true;
ndImp.Visible := true;
ndIntf.Visible := true;
ndMix.Visible := true;
ndStruct.Visible:= true;
ndTmp.Visible := true;
ndUni.Visible := true;
ndVar.Visible := true;
end;
end;
procedure TCESymbolListWidget.clearTree;
begin
ndAlias.DeleteChildren;
ndClass.DeleteChildren;
ndEnum.DeleteChildren;
ndFunc.DeleteChildren;
ndImp.DeleteChildren;
ndIntf.DeleteChildren;
ndMix.DeleteChildren;
ndStruct.DeleteChildren;
ndTmp.DeleteChildren;
ndUni.DeleteChildren;
ndVar.DeleteChildren;
end;
procedure TCESymbolListWidget.TreeFilterEdit1AfterFilter(Sender: TObject);
begin
if TreeFilterEdit1.Filter ='' then
updateVisibleCat;
end;
procedure TCESymbolListWidget.TreeKeyPress(Sender: TObject; var Key: char);
begin
if Key = #13 then TreeDblClick(nil);
end;
procedure TCESymbolListWidget.TreeDblClick(Sender: TObject);
var
line: Int64;
begin
if fDoc = nil then exit;
if Tree.Selected = nil then exit;
if Tree.Selected.Data = nil then exit;
//
line := PInt64(Tree.Selected.Data)^;
fDoc.CaretY := line;
fDoc.SelectLine;
end;
procedure TCESymbolListWidget.callToolProc;
var
srcFname: string;
begin
if fDoc = nil then exit;
if fDoc.Lines.Count = 0 then exit;
// standard process options
killProcess(fToolProc);
fToolProc := TCheckedAsyncProcess.Create(nil);
fToolProc.ShowWindow := swoHIDE;
fToolProc.Options := [poUsePipes];
fToolProc.Executable := 'cesyms';
fToolProc.OnTerminate := @symbolListProduced;
fToolProc.OnReadData := @symbolListProduced;
fToolProc.CurrentDirectory := ExtractFileDir(Application.ExeName);
// focused source
srcFname := fDoc.fileName;
if not fileExists(srcFname) or (srcFname = fDoc.tempFilename) then
fDoc.saveTempFile;
srcFname := fDoc.fileName;
fToolProc.Parameters.Add(srcFname);
fToolProc.Execute;
end;
procedure TCESymbolListWidget.symbolListProduced(sender: TObject);
var
cnt, sum: Integer;
str: TmemoryStream;
i: Integer;
const
buffSz = 1024;
//
procedure symbolToTreeNode(sym: TSymbol);
var
data: PInt64;
cat: TTreeNode;
i: Integer;
begin
case sym.symType of
_alias : cat := ndAlias;
_class : cat := ndClass;
_enum : cat := ndEnum;
_function : cat := ndFunc;
_import : cat := ndImp;
_interface: cat := ndIntf;
_mixin : cat := ndMix;
_struct : cat := ndStruct;
_template : cat := ndTmp;
_union : cat := ndUni;
_variable : cat := ndVar;
end;
data := new(PInt64);
data^ := sym.fline;
tree.Items.AddChildObject(cat, sym.name, data);
cat.Visible:=true;
//
for i := 0 to sym.subs.Count-1 do
symbolToTreeNode(sym.subs[i]);
end;
//
begin
if ndAlias = nil then exit;
clearTree;
updateVisibleCat;
if fDoc = nil then exit;
//
sum := 0;
str := TMemoryStream.Create;
try
while fToolProc.Output.NumBytesAvailable <> 0 do begin
str.SetSize(sum + buffSz);
cnt := fToolProc.Output.Read((str.Memory + sum)^, buffSz);
sum += cnt;
end;
str.SetSize(sum);
str.Position := 0;
//str.SaveToFile('C:\symlist.txt');
fSyms.LoadFromTool(str);
finally
str.Free;
end;
fToolProc.OnTerminate := nil;
fToolProc.OnReadData := nil;
//
tree.BeginUpdate;
for i := 0 to fSyms.symbols.Count-1 do
symbolToTreeNode(fSyms.symbols[i]);
tree.EndUpdate;
end;
{$ENDREGION --------------------------------------------------------------------}
end.