RbBFBlokProj^M/[jPSIVStrn5.5OPSpStrnXMLDictionary.rbACnmStrnAChpStrnACsvStrnlocalhost:7325Ver1Strn1Ver2Strn0Ver3Strn0RelsStrn0NnRlStrn0RegnStrn0SVerStrnLVerStrnIVerStrnDVewInt 6prTpInt DLanInt CLanInt DEncInt BflgInt BCXFInt IconGrupEndGInt CPalGrupflagInt elemInt elemInt elemInt elemInt elemInt elemInt elemInt elemInt elemInt elemInt elemInt elemInt elemInt elemInt elemInt elemInt EndGInt MacCStrn????BMacStrnMy ApplicationBCarStrnMy Application (Mac OS X)BSizInt @BMSzInt BSzSStrn4096BMSSStrn2048MDIcStrnMy ApplicationBWinStrnMy Application.exeBMDIInt BL86Strn MyApplicationrEdtRect.fTypGrupLnameStrntextMacCStrnR*chtypeStrnTEXTdefnStrnflagInt EndGInt PadnPadn,********************************************BlokpVew6P>_W-NameStrnWindow1ContInt rEdtRect,eSptInt bPGpGrupPbPElGrup4scKyInt rEdtRect,eSptInt EndGInt EndGInt lstHInt llstVInt uPDefGrup4nameStrnNamePValStrnWindow1EncoInt EndGInt PDefGrup(nameStrnFramePValStrn0EndGInt PDefGrup0nameStrn CompositePValStrnFalseEndGInt PDefGrup0nameStrn HasBackColorPValStrnFalseEndGInt PDefGrup0nameStrn BackColorPValStrn16777215EndGInt PDefGrup(nameStrnBackdropPValStrn0EndGInt PDefGrup@nameStrnTitlePValStrnXML DictionaryEncoInt EndGInt PDefGrup(nameStrnVisiblePValStrnTrueEndGInt PDefGrup0nameStrn FullScreenPValStrnFalseEndGInt PDefGrup0nameStrnMenuBarVisiblePValStrnTrueEndGInt PDefGrup(nameStrnCloseBoxPValStrnTrueEndGInt PDefGrup,nameStrnGrowIconPValStrnFalseEndGInt PDefGrup0nameStrn LiveResizePValStrnFalseEndGInt PDefGrup,nameStrnZoomIconPValStrnFalseEndGInt PDefGrup(nameStrn BalloonHelpPValStrnEndGInt PDefGrup,nameStrn MacProcIDPValStrn0EndGInt PDefGrup0nameStrnMenuBarPValStrn -1137275409EndGInt PDefGrup,nameStrn PlacementPValStrn0EndGInt PDefGrup(nameStrnWidthPValStrn933EndGInt PDefGrup(nameStrnHeightPValStrn428EndGInt PDefGrup(nameStrnMinWidthPValStrn64EndGInt PDefGrup,nameStrn MinHeightPValStrn64EndGInt PDefGrup,nameStrnMaxWidthPValStrn32000EndGInt PDefGrup0nameStrn MaxHeightPValStrn32000EndGInt FDefGrup NameStrnWindow1SizeInt SuprStrnWindowbNtrInt HInsGrupEncoInt nameStrnOpensorcGrupxstsrInt stscInt ndsrInt ndscInt EncoInt srclStrn Sub Open()srclStrnsrclStrnEnd SubEndGInt EndGInt EndGInt CBhvGrupNameStrnSizeInt SuprStrnDictionaryViewerbNtrInt HInsGrup EncoInt nameStrn CellClicksorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt srclStrn\Function CellClick(row as Integer, column as Integer, x as Integer, y as Integer) As BooleansrclStrnsrclStrn End FunctionEndGInt EndGInt HInsGrupEncoInt nameStrn DoubleClicksorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt srclStrnSub DoubleClick()srclStrnsrclStrnEnd SubEndGInt EndGInt HInsGrupEncoInt nameStrnDragReorderRowssorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt srclStrn;Function DragReorderRows(newPosition as Integer) As BooleansrclStrnsrclStrn End FunctionEndGInt EndGInt HInsGrupEncoInt nameStrnOpensorcGrupxstsrInt stscInt ndsrInt ndscInt EncoInt srclStrn Sub Open()srclStrnsrclStrnEnd SubEndGInt EndGInt EndGInt CBhvGrup<NameStrnSizeInt SuprStrn PushButtonbNtrInt HInsGrupEncoInt nameStrnActionsorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt srclStrn Sub Action()srclStrnDim d As DictionarysrclStrnsrclStrnd = New DictionarysrclStrnsrclStrn"If d.LoadXML(EditField1.Text) ThensrclStrnDictionaryViewer1.Populate dsrclStrnElsesrclStrnBeepsrclStrnEnd IfsrclStrnsrclStrnException err As XmlExceptionsrclStrnMsgBox err.MessagesrclStrnEnd SubEndGInt EndGInt EndGInt CBhvGrup\NameStrnSizeInt SuprStrn PushButtonbNtrInt HInsGrupEncoInt nameStrnActionsorcGrupstsrInt #stscInt >ndsrInt #ndscInt >EncoInt srclStrn Sub Action()srclStrnDim d As DictionarysrclStrnDim mb As MemoryBlocksrclStrnDim bs As BinaryStreamsrclStrnDim d2 As DictionarysrclStrnDim col As CollectionsrclStrnsrclStrnd = New DictionarysrclStrnsrclStrnd.Value("3.4") = 2.8srclStrn#d.Value("pi") = 3.14159265358979323srclStrnsrclStrncol = New CollectionsrclStrncol.Add "Crépe paper"srclStrn col.Add 7srclStrncol.Add "Shamrock!"srclStrnd.Value("Junk") = colsrclStrnsrclStrnd.Value("Hooray") = "Yippie!"srclStrnsrclStrn(d.Value("Directory") = GetFolderItem("")srclStrnsrclStrnd2 = New DictionarysrclStrnd2.Value("Foo") = "bar"srclStrnd2.Value("Today") = New DatesrclStrn!d2.Value("Light Blue") = &c5555FFsrclStrnmb = "Hello world!"srclStrnd2.Value("MemoryBlock") = mbsrclStrnsrclStrnd.Value("Subdict") = d2srclStrnsrclStrnd.Value("Right") = TruesrclStrnd.Value("Wrong") = FalsesrclStrnsrclStrn// Make tabs show rightsrclStrnQEditField1.Text = ReplaceAll(d.ExportXMLString(CheckBox1.Value), ChrB(9), " ")srclStrnEnd SubEndGInt EndGInt EndGInt CBhvGrupNameStrnSizeInt SuprStrnSelectAllFieldbNtrInt HInsGrupLEncoInt nameStrnKeyDownsorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt srclStrn*Function KeyDown(Key As String) As BooleansrclStrnIf Asc(Key) = 9 Then // TabsrclStrnme.SelText = " " // 4 spacessrclStrn Return TruesrclStrnEnd IfsrclStrn End FunctionEndGInt EndGInt EndGInt CBhvGruptNameStrnSizeInt SuprStrn PushButtonbNtrInt HInsGrupEncoInt nameStrnActionsorcGrupstsrInt stscInt %ndsrInt ndscInt %EncoInt srclStrn Sub Action()srclStrnDim f As FolderItemsrclStrnDim sd As SaveAsDialogsrclStrnDim d As DictionarysrclStrnsrclStrnsd = New SaveAsDialogsrclStrn%sd.SuggestedFileName = "Untitled.xml"srclStrnf = sd.ShowModalWithin(self)srclStrnIf f <> nil ThensrclStrnd = New DictionarysrclStrn"If d.LoadXML(EditField1.Text) ThensrclStrnIf d.SaveXML(f, False) ThensrclStrn// SavedsrclStrnElsesrclStrnBeepsrclStrnMsgBox "Error saving XML"srclStrnEnd IfsrclStrnElsesrclStrnBeepsrclStrn*MsgBox "Error loading XML from text field"srclStrnEnd IfsrclStrnEnd IfsrclStrnEnd SubEndGInt EndGInt EndGInt CBhvGrup<NameStrnSizeInt SuprStrnCheckBoxbNtrInt EndGInt CtrlGrup $cclsStrnSelectAllFieldnameStrn EditFieldPDefGrup8nameStrnNamePValStrn EditField1EncoInt EndGInt PDefGrup0nameStrnIndexPValStrn -2147483648EndGInt PDefGrup0nameStrn TabPanelIndexPValStrn0EndGInt PDefGrup(nameStrnVisiblePValStrnTrueEndGInt PDefGrup$nameStrnLeftPValStrn20EndGInt PDefGrup$nameStrnTopPValStrn14EndGInt PDefGrup(nameStrnWidthPValStrn400EndGInt PDefGrup(nameStrnHeightPValStrn400EndGInt PDefGrup,nameStrn InitialParentPValStrnEndGInt PDefGrup$nameStrnHelpTagPValStrnEndGInt PDefGrup( nameStrn BalloonHelpPValStrnEndGInt  PDefGrup0 nameStrnDisabledBalloonHelpPValStrnEndGInt  PDefGrup0 nameStrnAutoDeactivatePValStrnTrueEndGInt  PDefGrup, nameStrnLockLeftPValStrnFalseEndGInt  PDefGrup, nameStrnLockTopPValStrnFalseEndGInt  PDefGrup0nameStrn LockRightPValStrnFalseEndGInt PDefGrup0nameStrn LockBottomPValStrnFalseEndGInt PDefGrup8nameStrnTextFontPValStrnMonacoEncoInt EndGInt PDefGrup(nameStrnTextSizePValStrn10EndGInt PDefGrup(nameStrnBoldPValStrnFalseEndGInt PDefGrup,nameStrnItalicPValStrnFalseEndGInt PDefGrup0nameStrn UnderlinePValStrnFalseEndGInt PDefGrup(nameStrnBorderPValStrnTrueEndGInt PDefGrup,nameStrn MultiLinePValStrnTrueEndGInt PDefGrup4nameStrnScrollBarHorizontalPValStrnTrueEndGInt PDefGrup,nameStrn ScrollBarPValStrnTrueEndGInt PDefGrup4nameStrnScrollBarVerticalPValStrnTrueEndGInt PDefGrup,nameStrnStyledPValStrnFalseEndGInt PDefGrup,nameStrnPasswordPValStrnFalseEndGInt PDefGrup,nameStrn UseFocusRingPValStrnTrueEndGInt PDefGrup,nameStrnReadOnlyPValStrnFalseEndGInt PDefGrup,nameStrn LimitTextPValStrn0EndGInt PDefGrup,nameStrn AcceptTabsPValStrnTrueEndGInt PDefGrup, nameStrn AlignmentPValStrn0EndGInt  PDefGrup,!nameStrn TextColorPValStrn0EndGInt !PDefGrup0"nameStrn BackColorPValStrn16777215EndGInt "PDefGrup(#nameStrnEnabledPValStrnTrueEndGInt #PDefGrup$nameStrnTextPValStrn EncoInt EndGInt $PDefGrup(%nameStrn DataSourcePValStrnEndGInt %PDefGrup(&nameStrn DataFieldPValStrnEndGInt &PDefGrup$'nameStrnFormatPValStrnEndGInt 'PDefGrup (nameStrnMaskPValStrnEndGInt (CBixInt EndGInt CtrlGrup )cclsStrnDictionaryViewernameStrnListBoxPDefGrup@*nameStrnNamePValStrnDictionaryViewer1EncoInt EndGInt *PDefGrup0+nameStrnIndexPValStrn -2147483648EndGInt +PDefGrup0,nameStrn TabPanelIndexPValStrn0EndGInt ,PDefGrup(-nameStrnVisiblePValStrnTrueEndGInt -PDefGrup$.nameStrnLeftPValStrn513EndGInt .PDefGrup$/nameStrnTopPValStrn14EndGInt /PDefGrup(0nameStrnWidthPValStrn400EndGInt 0PDefGrup(1nameStrnHeightPValStrn400EndGInt 1PDefGrup,2nameStrn InitialParentPValStrnEndGInt 2PDefGrup$3nameStrnHelpTagPValStrnEndGInt 3PDefGrup(4nameStrn BalloonHelpPValStrnEndGInt 4PDefGrup05nameStrnDisabledBalloonHelpPValStrnEndGInt 5PDefGrup06nameStrnAutoDeactivatePValStrnTrueEndGInt 6PDefGrup,7nameStrnLockLeftPValStrnFalseEndGInt 7PDefGrup,8nameStrnLockTopPValStrnFalseEndGInt 8PDefGrup09nameStrn LockRightPValStrnFalseEndGInt 9PDefGrup0:nameStrn LockBottomPValStrnFalseEndGInt :PDefGrup8;nameStrnTextFontPValStrnSystemEncoInt EndGInt ;PDefGrup(nameStrnItalicPValStrnFalseEndGInt >PDefGrup0?nameStrn UnderlinePValStrnFalseEndGInt ?PDefGrup(@nameStrnEnabledPValStrnTrueEndGInt @PDefGrup,AnameStrn ColumnCountPValStrn2EndGInt APDefGrup(BnameStrn ColumnWidthsPValStrnEndGInt BPDefGrup,CnameStrn HasHeadingPValStrnTrueEndGInt CPDefGrup,DnameStrn UseFocusRingPValStrnTrueEndGInt DPDefGrup(EnameStrn InitialValuePValStrnEndGInt EPDefGrup0FnameStrn HierarchicalPValStrnFalseEndGInt FPDefGrup0GnameStrn EnableDragPValStrnFalseEndGInt GPDefGrup8HnameStrnEnableDragReorderPValStrnFalseEndGInt HPDefGrup0InameStrn SelectionTypePValStrn0EndGInt IPDefGrup,JnameStrn HeadingIndexPValStrn-1EndGInt JPDefGrup8KnameStrnScrollBarHorizontalPValStrnFalseEndGInt KPDefGrup0LnameStrnScrollPositionXPValStrn0EndGInt LPDefGrup4MnameStrnScrollBarVerticalPValStrnTrueEndGInt MPDefGrup0NnameStrnScrollPositionPValStrn0EndGInt NPDefGrup(OnameStrn DataSourcePValStrnEndGInt OPDefGrup(PnameStrn DataFieldPValStrnEndGInt PPDefGrup4QnameStrnGridLinesHorizontalPValStrn0EndGInt QPDefGrup4RnameStrnGridLinesVerticalPValStrn0EndGInt RPDefGrup0SnameStrnDefaultRowHeightPValStrn-1EndGInt SPDefGrup4TnameStrnColumnsResizablePValStrnFalseEndGInt TCBixInt EndGInt )CtrlGrup0UcclsStrn PushButtonnameStrn PushButtonPDefGrup8VnameStrnNamePValStrn PushButton1EncoInt EndGInt VPDefGrup0WnameStrnIndexPValStrn -2147483648EndGInt WPDefGrup0XnameStrn TabPanelIndexPValStrn0EndGInt XPDefGrup(YnameStrnVisiblePValStrnTrueEndGInt YPDefGrup$ZnameStrnLeftPValStrn432EndGInt ZPDefGrup$[nameStrnTopPValStrn181EndGInt [PDefGrup(\nameStrnWidthPValStrn69EndGInt \PDefGrup(]nameStrnHeightPValStrn20EndGInt ]PDefGrup,^nameStrn InitialParentPValStrnEndGInt ^PDefGrup$_nameStrnHelpTagPValStrnEndGInt _PDefGrup(`nameStrn BalloonHelpPValStrnEndGInt `PDefGrup0anameStrnDisabledBalloonHelpPValStrnEndGInt aPDefGrup0bnameStrnAutoDeactivatePValStrnTrueEndGInt bPDefGrup,cnameStrnLockLeftPValStrnFalseEndGInt cPDefGrup,dnameStrnLockTopPValStrnFalseEndGInt dPDefGrup0enameStrn LockRightPValStrnFalseEndGInt ePDefGrup0fnameStrn LockBottomPValStrnFalseEndGInt fPDefGrup8gnameStrnTextFontPValStrnSystemEncoInt EndGInt gPDefGrup(hnameStrnTextSizePValStrn12EndGInt hPDefGrup(inameStrnBoldPValStrnFalseEndGInt iPDefGrup,jnameStrnItalicPValStrnFalseEndGInt jPDefGrup0knameStrn UnderlinePValStrnFalseEndGInt kPDefGrup4lnameStrnCaptionPValStrn->EncoInt EndGInt lPDefGrup,mnameStrnDefaultPValStrnFalseEndGInt mPDefGrup,nnameStrnCancelPValStrnFalseEndGInt nPDefGrup(onameStrnEnabledPValStrnTrueEndGInt oCBixInt EndGInt UCtrlGrup0pcclsStrn PushButtonnameStrn PushButtonPDefGrup8qnameStrnNamePValStrn PushButton2EncoInt EndGInt qPDefGrup0rnameStrnIndexPValStrn -2147483648EndGInt rPDefGrup0snameStrn TabPanelIndexPValStrn0EndGInt sPDefGrup(tnameStrnVisiblePValStrnTrueEndGInt tPDefGrup$unameStrnLeftPValStrn432EndGInt uPDefGrup$vnameStrnTopPValStrn213EndGInt vPDefGrup(wnameStrnWidthPValStrn69EndGInt wPDefGrup(xnameStrnHeightPValStrn20EndGInt xPDefGrup,ynameStrn InitialParentPValStrnEndGInt yPDefGrup$znameStrnHelpTagPValStrnEndGInt zPDefGrup({nameStrn BalloonHelpPValStrnEndGInt {PDefGrup0|nameStrnDisabledBalloonHelpPValStrnEndGInt |PDefGrup0}nameStrnAutoDeactivatePValStrnTrueEndGInt }PDefGrup,~nameStrnLockLeftPValStrnFalseEndGInt ~PDefGrup,nameStrnLockTopPValStrnFalseEndGInt PDefGrup0nameStrn LockRightPValStrnFalseEndGInt PDefGrup0nameStrn LockBottomPValStrnFalseEndGInt PDefGrup8nameStrnTextFontPValStrnSystemEncoInt EndGInt PDefGrup(nameStrnTextSizePValStrn12EndGInt PDefGrup(nameStrnBoldPValStrnFalseEndGInt PDefGrup,nameStrnItalicPValStrnFalseEndGInt PDefGrup0nameStrn UnderlinePValStrnFalseEndGInt PDefGrup4nameStrnCaptionPValStrn<-EncoInt EndGInt PDefGrup,nameStrnDefaultPValStrnFalseEndGInt PDefGrup,nameStrnCancelPValStrnFalseEndGInt PDefGrup(nameStrnEnabledPValStrnTrueEndGInt CBixInt EndGInt pCtrlGrup0cclsStrn PushButtonnameStrn PushButtonPDefGrup8nameStrnNamePValStrn PushButton3EncoInt EndGInt PDefGrup0nameStrnIndexPValStrn -2147483648EndGInt PDefGrup0nameStrn TabPanelIndexPValStrn0EndGInt PDefGrup(nameStrnVisiblePValStrnTrueEndGInt PDefGrup$nameStrnLeftPValStrn432EndGInt PDefGrup$nameStrnTopPValStrn245EndGInt PDefGrup(nameStrnWidthPValStrn69EndGInt PDefGrup(nameStrnHeightPValStrn20EndGInt PDefGrup,nameStrn InitialParentPValStrnEndGInt PDefGrup$nameStrnHelpTagPValStrnEndGInt PDefGrup(nameStrn BalloonHelpPValStrnEndGInt PDefGrup0nameStrnDisabledBalloonHelpPValStrnEndGInt PDefGrup0nameStrnAutoDeactivatePValStrnTrueEndGInt PDefGrup,nameStrnLockLeftPValStrnFalseEndGInt PDefGrup,nameStrnLockTopPValStrnFalseEndGInt PDefGrup0nameStrn LockRightPValStrnFalseEndGInt PDefGrup0nameStrn LockBottomPValStrnFalseEndGInt PDefGrup8nameStrnTextFontPValStrnSystemEncoInt EndGInt PDefGrup(nameStrnTextSizePValStrn12EndGInt PDefGrup(nameStrnBoldPValStrnFalseEndGInt PDefGrup,nameStrnItalicPValStrnFalseEndGInt PDefGrup0nameStrn UnderlinePValStrnFalseEndGInt PDefGrup4nameStrnCaptionPValStrnSaveEncoInt EndGInt PDefGrup,nameStrnDefaultPValStrnFalseEndGInt PDefGrup,nameStrnCancelPValStrnFalseEndGInt PDefGrup(nameStrnEnabledPValStrnTrueEndGInt CBixInt EndGInt CtrlGruphcclsStrnCheckBoxnameStrnCheckBoxPDefGrup8nameStrnNamePValStrn CheckBox1EncoInt EndGInt PDefGrup0nameStrnIndexPValStrn -2147483648EndGInt PDefGrup0nameStrn TabPanelIndexPValStrn0EndGInt PDefGrup(nameStrnVisiblePValStrnTrueEndGInt PDefGrup$nameStrnLeftPValStrn441EndGInt PDefGrup$nameStrnTopPValStrn277EndGInt PDefGrup(nameStrnWidthPValStrn50EndGInt PDefGrup(nameStrnHeightPValStrn20EndGInt PDefGrup,nameStrn InitialParentPValStrnEndGInt PDefGrup$nameStrnHelpTagPValStrnEndGInt PDefGrup(nameStrn BalloonHelpPValStrnEndGInt PDefGrup0nameStrnDisabledBalloonHelpPValStrnEndGInt PDefGrup0nameStrnAutoDeactivatePValStrnTrueEndGInt PDefGrup,nameStrnLockLeftPValStrnFalseEndGInt PDefGrup,nameStrnLockTopPValStrnFalseEndGInt PDefGrup0nameStrn LockRightPValStrnFalseEndGInt PDefGrup0nameStrn LockBottomPValStrnFalseEndGInt PDefGrup8nameStrnTextFontPValStrnSystemEncoInt EndGInt PDefGrup(nameStrnTextSizePValStrn12EndGInt PDefGrup(nameStrnBoldPValStrnFalseEndGInt PDefGrup,nameStrnItalicPValStrnFalseEndGInt PDefGrup0nameStrn UnderlinePValStrnFalseEndGInt PDefGrup8nameStrnCaptionPValStrnplistEncoInt EndGInt PDefGrup,nameStrnValuePValStrnFalseEndGInt PDefGrup(nameStrnEnabledPValStrnTrueEndGInt PDefGrup(nameStrn DataSourcePValStrnEndGInt PDefGrup(nameStrn DataFieldPValStrnEndGInt CBixInt EndGInt PadnPadn@****************************************************************BlokpMnu6 -NameStrnMenuBar1ContInt rEdtRectdd,MItmGrupspmuInt nameStrntextStrnindxInt scutStrnbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt MItmGrupspmuInt nameStrntextStrnindxInt scutStrnbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt EndGInt EndGInt MItmGrupspmuInt nameStrnFileMenutextStrn&FileindxInt scutStrnbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt MItmGrupspmuInt nameStrnFileQuittextStrnQuitindxInt scutStrnQbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrn QuitMenuItembNtrInt EndGInt MItmGrupspmuInt nameStrntextStrnindxInt scutStrnbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt EndGInt EndGInt MItmGrupspmuInt nameStrnEditMenutextStrn&EditindxInt scutStrnbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt MItmGrupspmuInt nameStrnEditUndotextStrnUndoindxInt scutStrnZbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt EndGInt MItmGrupspmuInt nameStrntextStrn-indxInt scutStrnbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt EndGInt MItmGrupspmuInt nameStrnEditCuttextStrnCutindxInt scutStrnXbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt EndGInt MItmGrupspmuInt nameStrnEditCopytextStrnCopyindxInt scutStrnCbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt EndGInt MItmGrupspmuInt nameStrn EditPastetextStrnPasteindxInt scutStrnVbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt EndGInt MItmGrupspmuInt nameStrn EditCleartextStrnClearindxInt scutStrnbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt EndGInt MItmGrupspmuInt nameStrn EditSelectAlltextStrn Select AllindxInt scutStrnAbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt EndGInt MItmGrupspmuInt nameStrntextStrnindxInt scutStrnbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt EndGInt EndGInt MItmGrupspmuInt nameStrntextStrnindxInt scutStrnbhlpStrndhlpStrnstylInt EncoInt flagInt maEnInt NameStrnSizeInt LSuprStrnMenuItembNtrInt EndGInt PadnPadn@************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************BlokpObj6@#Y(NameStrnAppContInt rEdtRect_K!eSptInt bPGpGrupPbPElGrup4scKyInt rEdtRect_K!eSptInt EndGInt EndGInt bClsInt NameStrnAppSizeInt 4SuprStrn ApplicationbNtrInt IntrStrnbApOInt PDefGrup0nameStrnMenuBarPValStrn -1137275409EndGInt PadnPadn****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************BlokpObj8~l*jNameStrnDictionaryViewerContInt rEdtRectU3eSptInt bPGpGrupbPElGrup4scKyInt rEdtRectU3eSptInt EndGInt bPElGrup4scKyInt rEdtRectAN,eSptInt EndGInt EndGInt bClsInt NameStrnDictionaryViewerSizeInt SuprStrnListboxbNtrInt PropGrupEncoInt declStrnrowFolders(-1) As VariantflagInt sorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt ntlnStrnrowFolders(-1) As VariantntlnStrnntlnStrnEndGInt EndGInt NoteGrupEncoInt nameStrnUseflagInt sorcGrupstsrInt stscInt [ndsrInt ndscInt [EncoInt ntlnStrnUsentlnStrn[Just pass a dictionary to Populate, and it will display the whole thing, all nicely coloredntlnStrnEndGInt EndGInt NoteGrup\EncoInt nameStrnCreditsflagInt sorcGrupstsrInt stscInt ^ndsrInt ndscInt ^EncoInt ntlnStrnCreditsntlnStrnntlnStrn^If you use this in your application, please give me credit somewhere (like, a Thanks section).ntlnStrnEndGInt EndGInt MethGrupEncoInt nameStrnPopulateparmStrnd As DictionaryrsltStrnflagInt sorcGrup$stsrInt stscInt ndsrInt ndscInt EncoInt srclStrnSub Populate(d As Dictionary)srclStrnA// Clears the listbox, and parses the top level of the dictionarysrclStrnsrclStrnself.DeleteAllRowssrclStrnsrclStrnParseStorage dsrclStrnEnd SubEndGInt EndGInt MethGrupEncoInt nameStrn ParseStorageparmStrnstorage As VariantrsltStrnflagInt sorcGrupstsrInt stscInt >ndsrInt ndscInt >EncoInt srclStrn$Sub ParseStorage(storage As Variant)srclStrn8// Parses a dictionary and creates a row for each value.srclStrn7// If it finds a nested dictionary, it creates a foldersrclStrnC// It also records the type of each key and value in hidden columnssrclStrnV// And, if a nested dictionary, it saves the dictionary and records the saved locationsrclStrnsrclStrnDim i, n As IntegersrclStrnDim v As VariantsrclStrnsrclStrnn = StorageCount(storage) - 1srclStrnsrclStrnFor i = 0 To nsrclStrn.v = StorageValue(storage, i) // Grab the valuesrclStrn2If ValueIsExpandable(v) Then // If it's expandablesrclStrnGself.AddFolder getVariantValue(StorageKey(storage, i)) // Make a foldersrclStrnCrowFolders.Append v.ObjectValue // Save the value for parsing latersrclStrnMself.Cell(self.LastIndex, 3) = "0" // This means it's a folder for colorationsrclStrn[self.Cell(self.LastIndex, 4) = Str(UBound(rowFolders)) // Remember where it saved the valuesrclStrnElsesrclStrnCself.AddRow getVariantValue(StorageKey(storage, i)) // Create a rowsrclStrn4If v.Type = 9 AND v.ObjectValue IsA MemoryBlock ThensrclStrnAself.Cell(self.LastIndex, 3) = "0" // Color it like a memoryblocksrclStrnElsesrclStrnGself.Cell(self.LastIndex, 3) = getVariantType(v) // Color it like it issrclStrnEnd IfsrclStrnXself.Cell(self.LastIndex, 4) = "-1" // It's not a folder, so has no dictionary referencesrclStrnEnd IfsrclStrnCself.Cell(self.LastIndex, 1) = getVariantValue(v) // Show the valuesrclStrnnself.Cell(self.LastIndex, 2) = getVariantType(StorageKey(storage, i)) // Record the type of key for colorationsrclStrnNextsrclStrnEnd SubEndGInt EndGInt MethGrup$EncoInt nameStrngetVariantTypeparmStrn v As VariantrsltStrnStringflagInt sorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt srclStrn/Function getVariantType(v As Variant) As StringsrclStrn)// Returns the variant's type as a stringsrclStrnsrclStrnIf v <> nil ThensrclStrnIf v.IsNull ThensrclStrn Return "0"srclStrnElsesrclStrnReturn Str(v.Type)srclStrnEnd IfsrclStrnElsesrclStrn Return "-1"srclStrnEnd IfsrclStrn End FunctionEndGInt EndGInt MethGrupEncoInt nameStrngetVariantValueparmStrn v As VariantrsltStrnStringflagInt sorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt srclStrn0Function getVariantValue(v As Variant) As StringsrclStrn)// Return the variant's value as a stringsrclStrnsrclStrnIf v <> nil ThensrclStrnSelect Case v.TypesrclStrn Case 0 // NilsrclStrn Return "Null"srclStrnCase 2 // IntegersrclStrn"Return Format(v.IntegerValue,"-#")srclStrnCase 5 // DoublesrclStrn'Return Format(v.DoubleValue,"-#.0####")srclStrnCase 7 // DatesrclStrn'Return v.StringValue // Valid for datessrclStrnCase 8 // StringsrclStrnReturn v.StringValuesrclStrnCase 9 // ObjectsrclStrn= Val(self.Cell(row, 4)) ThensrclStrn/ParseStorage rowFolders(Val(self.Cell(row, 4)))srclStrnElsesrclStrnBeepsrclStrnself.AddRow "Error"srclStrn@self.Cell(self.LastIndex, 1) = "Couldn't find nested dictionary"srclStrn"self.Cell(self.LastIndex, 2) = "8"srclStrn"self.Cell(self.LastIndex, 3) = "0"srclStrnEnd IfsrclStrnEnd SubEndGInt EndGInt HInsGrupEncoInt nameStrnOpensorcGrupstsrInt stscInt 'ndsrInt ndscInt 'EncoInt srclStrn Sub Open()srclStrn&// Make sure the display looks correctsrclStrnsrclStrn%// Give the user a chance to do stuffsrclStrnOpensrclStrnsrclStrn!// Now make sure it looks correctsrclStrnme.ColumnCount = 5srclStrnme.ColumnWidths = "33%,*,0,0,0"srclStrnme.Hierarchical = TruesrclStrnme.Heading(0) = "Key"srclStrnme.Heading(1) = "Value"srclStrn)me.Heading(2) = "Internal Use - Key Type"srclStrn+me.Heading(3) = "Internal Use - Value Type"srclStrn'me.Heading(4) = "Internal Use - RowTag"srclStrnEnd SubEndGInt EndGInt IntrStrnPadnPadn****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************BlokpObj6,-NameStrnSelectAllFieldContInt rEdtRect_K!eSptInt bPGpGrupPbPElGrup4scKyInt rEdtRect_K!eSptInt EndGInt EndGInt bClsInt NameStrnSelectAllFieldSizeInt SuprStrn EditFieldbNtrInt MnuHGrupEncoInt nameStrn EditSelectAllsorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt srclStrnFunction Action() As BooleansrclStrnself.SelStart = 0srclStrnself.SelLength = Len(self.Text)srclStrn End FunctionEndGInt EndGInt IntrStrnPadnPadn********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************BlokpObj6Ĩd \INameStrn XMLDictionaryContInt rEdtRectUreSptInt bPGpGrupPbPElGrup4 scKyInt rEdtRectUreSptInt EndGInt  EndGInt bClsInt NameStrn XMLDictionarySizeInt bNtrInt NoteGrup t EncoInt nameStrnVersion HistoryflagInt sorcGrup $ stsrInt stscInt sndsrInt ndscInt sEncoInt ntlnStrnVersion HistoryntlnStrn Kevin BallardntlnStrn kevin@sb.orgntlnStrnhttp://www.tildesoft.comntlnStrnntlnStrnv1.2.6:ntlnStrno- Approximately tripled the speed of loading an XML file. Unfortunately, I can't do the same for saving becausentlnStrns the Dictionary class lacks an appropriate iterator-style access so my Ishmale the Painter's algorithm is requiredntlnStrnntlnStrnv1.2.5:ntlnStrnM- As per Jarvis Badgley's request, made it now respect existing dictionaries.ntlnStrne This means that if you create a set of nested dictionaries that corresponds to the plist structure,ntlnStrno when parsing the plist it will use the existing dictionaries rather than overwriting with its own. Of course,ntlnStrn7 this is not valid when parsing an array in the plist.ntlnStrnP The main purpose of this is to set up default values before parsing the plist.ntlnStrn ntlnStrnj Note: This means I no longer clear the dictionary when I parse the XML file. If you want to keep the oldntlnStrnG behaviour, do a Dictionary.clear before parsing the XML filentlnStrnntlnStrnv1.2.4:ntlnStrn5- Made line endings use EndOfLine instead of linefeedntlnStrnB- Removed some commented-out code left over from the 5.5.1fc1 hackntlnStrnntlnStrnv1.2.3:ntlnStrnR- Removed said hack, due to fix in 5.5.1fc4. If you're using 5.5.1fc1-fc3, upgradentlnStrnntlnStrnv1.2.2:ntlnStrn^- Added a hack to work around the XmlDocument.AppendChild() As XmlNode bug present in 5.5.1fc1ntlnStrng- If you pass a variant of an unknown type (something that should never happen), it now outputs "false"ntlnStrn, instead of "null" in plist-compatible modentlnStrnntlnStrnv1.2.1:ntlnStrn[- Fixed bug where plist-compatible mode wasn't preserved in nested dictionaries/collectionsntlnStrny- Fixed plist-compatible mode so that colors are now output as False instead (since plist doesn't support the color type)ntlnStrnntlnStrnv1.2:ntlnStrn6- Fixed double output to use Format() instead of Str()ntlnStrnM- SaveXML now sets file type/creator to "" instead of using the text filetypentlnStrn- Can now parse plist filesntlnStrnS- Can now save as plist files with an option boolean to all the export/save methodsntlnStrnntlnStrnv1.1:ntlnStrnJ- Added support for Collections as a replacement for lack of array supportntlnStrn4 Note that keys in Collections are not preservedntlnStrnx- Ugraded version attribute of resulting document to "1.1" - previous versions of XMLDictionary won't read new documentsntlnStrn- When adding a string value to a document, it now converts it to UTF-8. If conversion failed (because no encoding was present originally),ntlnStrn, it simply defines the encoding as UTF-8ntlnStrnntlnStrnv1.0.1:ntlnStrn!- Added support for 5.5b6 changesntlnStrnntlnStrnv1.0:ntlnStrn- Initial releasentlnStrnEndGInt  EndGInt  MethGrup EncoInt nameStrn ExportXMLparmStrn7Extends xmldict As Dictionary, plist As Boolean = FalsersltStrn XmlDocumentflagInt sorcGrup$ stsrInt stscInt .ndsrInt ndscInt .EncoInt srclStrnZFunction ExportXML(Extends xmldict As Dictionary, plist As Boolean = False) As XmlDocumentsrclStrnDim xdoc As XmlDocumentsrclStrnDim root, dict As XmlElementsrclStrnsrclStrnxdoc = New XmlDocumentsrclStrn If plist ThensrclStrn// Plist-compatible outputsrclStrn@root = XmlElement(xdoc.AppendChild(xdoc.CreateElement("plist")))srclStrn*root.SetAttribute("version", PlistVersion)srclStrn?dict = XmlElement(root.AppendChild(xdoc.CreateElement("dict")))srclStrn ParseStorage xmldict, dict, TruesrclStrnIndentNode root, 0, TruesrclStrnIndentNode dict, 0, TruesrclStrnElsesrclStrnBroot = XmlElement(xdoc.AppendChild(xdoc.CreateElement("xmldict")))srclStrn,root.SetAttribute("version", CurrentVersion)srclStrn!ParseStorage xmldict, root, FalsesrclStrnIndentNode root, 0, TruesrclStrnEnd IfsrclStrn0xdoc.AppendChild(xdoc.CreateTextNode(EndOfLine))srclStrnsrclStrn Return xdocsrclStrn End FunctionEndGInt  EndGInt  MethGrupEncoInt nameStrnExportXMLStringparmStrn7Extends xmldict As Dictionary, plist As Boolean = FalsersltStrnStringflagInt sorcGrupstsrInt stscInt PndsrInt ndscInt PEncoInt srclStrn[Function ExportXMLString(Extends xmldict As Dictionary, plist As Boolean = False) As StringsrclStrn3// Since we can't add a DOCTYPE to the XmlDocument,srclStrn"// lets hack this output to add itsrclStrnsrclStrnDim s, DTD As StringsrclStrnDim i As IntegersrclStrn%s = xmldict.ExportXML(plist).ToStringsrclStrnsrclStrn// Let's add the DTDsrclStrni = s.InStr(EndOfLine)srclStrnsrclStrn If plist ThensrclStrnDTD = PlistDTDsrclStrnElsesrclStrnDTD = XMLDictDTDsrclStrnEnd IfsrclStrnRs = s.Mid(1, i + Len(EndOfLine) - 1) + DTD + EndOfLine + s.Mid(i + Len(EndOfLine))srclStrnReturn ssrclStrn End FunctionEndGInt EndGInt MethGrupEncoInt nameStrn IndentNodeparmStrnDnode As XmlNode, level As Integer, indentCloseTag As Boolean = FalsersltStrnflagInt !sorcGrup$stsrInt stscInt ndsrInt ndscInt EncoInt srclStrnTSub IndentNode(node As XmlNode, level As Integer, indentCloseTag As Boolean = False)srclStrnDim i As IntegersrclStrnDim s As StringsrclStrn s = EndOfLinesrclStrnFor i = 1 To levelsrclStrns = s + Chr(9) // TabsrclStrnNextsrclStrn>node.Parent.Insert(node.OwnerDocument.CreateTextNode(s), node)srclStrnIf indentCloseTag ThensrclStrn6node.AppendChild(node.OwnerDocument.CreateTextNode(s))srclStrnEnd IfsrclStrnEnd SubEndGInt EndGInt MethGrupEncoInt nameStrnLoadXMLparmStrn0Extends xmldict As Dictionary, XMLData As StringrsltStrnBooleanflagInt sorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt srclStrnMFunction LoadXML(Extends xmldict As Dictionary, XMLData As String) As BooleansrclStrnDim xdoc As XmlDocumentsrclStrnsrclStrnxdoc = New XmlDocument()srclStrnxdoc.PreserveWhitespace = TruesrclStrnxdoc.LoadXml(XMLData)srclStrnReturn xmldict.LoadXML(xdoc)srclStrnsrclStrnException err As XmlExceptionsrclStrn// Ugh, invalid XMLsrclStrn Return FalsesrclStrn End FunctionEndGInt EndGInt MethGrupEncoInt nameStrnLoadXMLparmStrn4Extends xmldict As Dictionary, XMLFile As FolderItemrsltStrnBooleanflagInt sorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt srclStrnQFunction LoadXML(Extends xmldict As Dictionary, XMLFile As FolderItem) As BooleansrclStrnDim tos As TextInputStreamsrclStrnDim s As StringsrclStrnsrclStrntos = XMLFile.OpenAsTextFile()srclStrnIf tos <> nil ThensrclStrns = tos.ReadAllsrclStrn tos.ClosesrclStrnReturn xmldict.LoadXML(s)srclStrnElsesrclStrn Return FalsesrclStrnEnd IfsrclStrn End FunctionEndGInt EndGInt MethGrupEncoInt nameStrnLoadXMLparmStrn4Extends xmldict As Dictionary, XMLDoc As XmlDocumentrsltStrnBooleanflagInt sorcGrupstsrInt stscInt ndsrInt ndscInt EncoInt srclStrnQFunction LoadXML(Extends xmldict As Dictionary, XMLDoc As XmlDocument) As BooleansrclStrnDim node As XmlNodesrclStrnsrclStrn XMLDoc.PreserveWhitespace = TruesrclStrnsrclStrn6// Check to see if it's our xmldict or if it's a plistsrclStrn-If XMLDoc.DocumentElement.Name = "plist" ThensrclStrn+// Make sure it's a "dict" as the base typesrclStrn(node = XMLDoc.DocumentElement.FirstChildsrclStrn;While node.Type <> XmlNodeType.ELEMENT_NODE And node <> nilsrclStrnnode = node.NextSiblingsrclStrnWendsrclStrn)If node = nil Or node.Name <> "dict" ThensrclStrn// It's not validsrclStrn Return FalsesrclStrnEnd IfsrclStrn// Now check the versionsrclStrnPIf Val(XMLDoc.DocumentElement.GetAttribute("version")) <= Val(PlistVersion) ThensrclStrnParseXML node, xmldictsrclStrn Return TruesrclStrnElsesrclStrn Return FalsesrclStrnEnd IfsrclStrnElsesrclStrn9// First, make sure the version is at most what we expectsrclStrnRIf Val(XMLDoc.DocumentElement.GetAttribute("version")) <= Val(CurrentVersion) ThensrclStrn(ParseXML XMLDoc.DocumentElement, xmldictsrclStrn Return TruesrclStrnElsesrclStrnH// We can't reliably parse a higher version, so lets not parse it at allsrclStrn Return FalsesrclStrnEnd IfsrclStrnEnd IfsrclStrnsrclStrnException err As XmlExceptionsrclStrn// Ugh, invalid XMLsrclStrn Return FalsesrclStrn End FunctionEndGInt EndGInt MethGrupEncoInt nameStrn NodeContentsparmStrnparent As XmlNodersltStrnStringflagInt !sorcGrup<stsrInt stscInt ndsrInt ndscInt EncoInt srclStrn2Function NodeContents(parent As XmlNode) As StringsrclStrnC// Concatenates all the node children values and returns the resultsrclStrnH// It's designed for the children to be all text nodes, but for anythingsrclStrn // else it'll just use .ToStringsrclStrnsrclStrnDim i, n As IntegersrclStrnDim node As XmlNodesrclStrnDim s As StringsrclStrnn = parent.ChildCount - 1srclStrnFor i = 0 To nsrclStrnnode = parent.Child(i)srclStrn"If node.Type = 3 Then // Text nodesrclStrns = s + node.ValuesrclStrnKElse // Other node - shouldn't happen, but we gotta deal with it if it doessrclStrns = s + node.ToStringsrclStrnEnd IfsrclStrnNextsrclStrnReturn ssrclStrn End FunctionEndGInt EndGInt MethGrupEncoInt nameStrn ParseStorageparmStrnqstorage As Variant, parent As XmlNode, alreadySeen() As Variant, indentLevel As Integer, plist As Boolean = FalsersltStrnflagInt !sorcGrupstsrInt gstscInt ndsrInt gndscInt EncoInt srclStrnSub ParseStorage(storage As Variant, parent As XmlNode, alreadySeen() As Variant, indentLevel As Integer, plist As Boolean = False)srclStrnDim i, n, x As IntegersrclStrnDim key, value As VariantsrclStrnDim node, tempNode As XmlNodesrclStrnDim xdoc As XmlDocumentsrclStrnDim s, data(-1) As StringsrclStrnDim multilineTag As BooleansrclStrnDim mb As MemoryBlocksrclStrnsrclStrn;// First, make sure we haven't already seen this dictionarysrclStrn7// This protects against circular dictionary referencessrclStrnn = UBound(alreadySeen)srclStrnFor i = 0 To nsrclStrn If alreadySeen(i) = storage ThensrclStrn!// Ack! We've seen this! Bail outsrclStrnReturnsrclStrnEnd IfsrclStrnNextsrclStrn'// Ok, lets add out storage to the listsrclStrnalreadySeen.Append storagesrclStrnsrclStrnxdoc = parent.OwnerDocumentsrclStrnn = StorageCount(storage) - 1srclStrnFor i = 0 To nsrclStrn// KeysrclStrnkey = StorageKey(storage, i)srclStrn*If key <> nil Then // It's a keyed storagesrclStrn4node = parent.AppendChild(xdoc.CreateElement("key"))srclStrn6node.AppendChild(xdoc.CreateTextNode(key.StringValue))srclStrnIndentNode node, indentLevelsrclStrnEnd IfsrclStrnsrclStrn// ValuesrclStrnmultilineTag = FalsesrclStrn value = StorageValue(storage, i)srclStrnSelect Case value.TypesrclStrnCase 0 // NullsrclStrn8// If it's a plist, we can't use null, so lets use falsesrclStrn If plist ThensrclStrn"node = xdoc.CreateElement("false")srclStrnElsesrclStrn!node = xdoc.CreateElement("null")srclStrnEnd IfsrclStrnCase 2 // IntegersrclStrn$node = xdoc.CreateElement("integer")srclStrn>node.AppendChild(xdoc.CreateTextNode(Str(value.IntegerValue)))srclStrnCase 5 // Double/SinglesrclStrn!node = xdoc.CreateElement("real")srclStrnVnode.AppendChild(xdoc.CreateTextNode(Format(value.DoubleValue, "-#.0##############")))srclStrnCase 7 // DatesrclStrn!node = xdoc.CreateElement("date")srclStrn8node.AppendChild(xdoc.CreateTextNode(value.StringValue))srclStrnCase 8 // StringsrclStrn#node = xdoc.CreateElement("string")srclStrnIs = ConvertEncoding(value.StringValue, Encodings.UTF8) // Convert to UTF8srclStrnIf s.Encoding = nil Then s = DefineEncoding(s, Encodings.UTF8) // If encoding was undefined, convert fails. Simply define insteadsrclStrn(node.AppendChild(xdoc.CreateTextNode(s))srclStrnCase 9 // ObjectsrclStrn@// Is this a dictionary, memoryblock, collection, or folderitem?srclStrn(If value.ObjectValue IsA Dictionary ThensrclStrn// We can parse this dictionarysrclStrn!node = xdoc.CreateElement("dict")srclStrnSParseStorage Dictionary(value.ObjectValue), node, alreadySeen, indentLevel+1, plistsrclStrnmultilineTag = TruesrclStrn-ElseIf value.ObjectValue IsA MemoryBlock ThensrclStrn // We can parse this memoryblocksrclStrn!node = xdoc.CreateElement("data")srclStrnjdata = Split(EncodeBase64(MemoryBlock(value.ObjectValue), 45), ChrB(13)+ChrB(10)) // 45 is what plists usesrclStrnFor Each s In datasrclStrnTtempNode = node.AppendChild(xdoc.CreateTextNode(DefineEncoding(s, Encodings.ASCII)))srclStrn IndentNode tempNode, indentLevelsrclStrnNextsrclStrnmultilineTag = TruesrclStrn,ElseIf value.ObjectValue IsA Collection ThensrclStrn// We can parse this collectionsrclStrn"node = xdoc.CreateElement("array")srclStrnSParseStorage Collection(value.ObjectValue), node, alreadySeen, indentLevel+1, plistsrclStrnmultilineTag = TruesrclStrnlElseIf value.ObjectValue IsA FolderItem And Not plist Then // We can't output this if it's plist-compatible srclStrn?// Do the same thing as a memoryblock, but with a different tagsrclStrn!node = xdoc.CreateElement("file")srclStrnadata = Split(EncodeBase64(FolderItem(value.ObjectValue).GetSaveInfo(Nil), 45), ChrB(13)+ChrB(10))srclStrnFor Each s In DatasrclStrn3tempNode = node.AppendChild(xdoc.CreateTextNode(s))srclStrn IndentNode tempNode, indentLevelsrclStrnNextsrclStrnmultilineTag = TruesrclStrnElsesrclStrnD// Arbitrary object? We can't do this. Let's just add a null elementsrclStrn8// If it's a plist, we can't use null, so lets use falsesrclStrn If plist ThensrclStrn"node = xdoc.CreateElement("false")srclStrnElsesrclStrn!node = xdoc.CreateElement("null")srclStrnEnd IfsrclStrnEnd IfsrclStrnCase 11 // BooleansrclStrn!If value.BooleanValue = True ThensrclStrn!node = xdoc.CreateElement("true")srclStrnElsesrclStrn"node = xdoc.CreateElement("false")srclStrnEnd IfsrclStrnCase 16 // ColorsrclStrn If plist ThensrclStrn#// We can't output colors in plistssrclStrn// Lets just add a False nodesrclStrn"node = xdoc.CreateElement("false")srclStrnElsesrclStrn"node = xdoc.CreateElement("color")srclStrnDnode.AppendChild(xdoc.CreateTextNode("#" + Hex(value.IntegerValue)))srclStrnEnd IfsrclStrnElsesrclStrnQ// Buh? We should never reach this point, but just in case, lets add a null valuesrclStrnf// However, if it's plist-compatible mode, we have to add a false value, since it doesn't support nullsrclStrn if plist ThensrclStrn"node = xdoc.CreateElement("false")srclStrnElsesrclStrn!node = xdoc.CreateElement("null")srclStrnEnd IfsrclStrn End SelectsrclStrnFparent.AppendChild node // workaround for AppendChild() as XmlNode bugsrclStrn*IndentNode node, indentLevel, multilineTagsrclStrnNextsrclStrnEnd SubEndGInt EndGInt MethGrup EncoInt nameStrnParseXMLparmStrn%parent As XmlNode, storage As VariantrsltStrnflagInt !sorcGrup <stsrInt stscInt ndsrInt ndscInt EncoInt srclStrn3Sub ParseXML(parent As XmlNode, storage As Variant)srclStrnDim i As IntegersrclStrnDim node, tempNode As XmlNodesrclStrnDim key As VariantsrclStrnDim v As VariantsrclStrnDim d As DictionarysrclStrnDim col As CollectionsrclStrnDim mb As MemoryBlocksrclStrnsrclStrn//ClearStorage storagesrclStrnsrclStrnnode = parent.FirstChildsrclStrnWhile node <> nilsrclStrn*// We only want to deal with element nodessrclStrn7// The only other type of node that *should* show up issrclStrn5// a text node with only whitespace. However, even ifsrclStrn4// other nodes show up, we should ignore them, sincesrclStrn// we're not a validatorsrclStrn nil ThensrclStrn'bs.Write xmldict.ExportXMLString(plist)srclStrnbs.ClosesrclStrnXMLFile.MacType = ""srclStrnXMLFile.MacCreator = ""srclStrn Return TruesrclStrnElsesrclStrn Return FalsesrclStrnEnd IfsrclStrn End FunctionEndGInt EndGInt MethGrup EncoInt nameStrn ParseStorageparmStrn?storage As Variant, parent As XmlNode, plist As Boolean = FalsersltStrnflagInt !sorcGrup !stsrInt stscInt )ndsrInt ndscInt )EncoInt srclStrnQSub ParseStorage(storage As Variant, parent As XmlNode, plist As Boolean = False)srclStrnDim v(-1) As VariantsrclStrn*ParseStorage(storage, parent, v, 1, plist)srclStrnEnd SubEndGInt !EndGInt  MethGrup"EncoInt nameStrn StoreValueparmStrn4key As Variant, value As Variant, storage As VariantrsltStrnflagInt !sorcGrup#stsrInt stscInt ndsrInt ndscInt EncoInt srclStrnDSub StoreValue(key As Variant, value As Variant, storage As Variant)srclStrnIf storage.Type = 9 ThensrclStrn9If storage.ObjectValue IsA Dictionary And key <> nil ThensrclStrn2Dictionary(storage.ObjectValue).Value(key) = valuesrclStrn.ElseIf storage.ObjectValue IsA Collection ThensrclStrn)Collection(storage.ObjectValue).Add valuesrclStrnEnd IfsrclStrnEnd IfsrclStrnEnd SubEndGInt #EndGInt "MethGrup$EncoInt nameStrn ClearStorageparmStrnstorage As VariantrsltStrnflagInt !sorcGrup4%stsrInt stscInt ndsrInt ndscInt EncoInt srclStrn$Sub ClearStorage(storage As Variant)srclStrnDim i, n As IntegersrclStrnsrclStrnIf storage.Type = 9 ThensrclStrn*If storage.ObjectValue IsA Dictionary ThensrclStrnDictionary(storage).ClearsrclStrn.ElseIf storage.ObjectValue IsA Collection ThensrclStrn)n = Collection(storage.ObjectValue).CountsrclStrnFor i = n DownTo 1srclStrn(Collection(storage.ObjectValue).Remove isrclStrnNextsrclStrnEnd IfsrclStrnEnd IfsrclStrnEnd SubEndGInt %EndGInt $MethGrup\&EncoInt nameStrn StorageCountparmStrnstorage As VariantrsltStrnIntegerflagInt !sorcGrup'stsrInt stscInt ndsrInt ndscInt EncoInt srclStrn4Function StorageCount(storage As Variant) As IntegersrclStrnIf storage.Type = 9 ThensrclStrn*If storage.ObjectValue IsA Dictionary ThensrclStrn,Return Dictionary(storage.ObjectValue).CountsrclStrn.ElseIf storage.ObjectValue IsA Collection ThensrclStrn,Return Collection(storage.ObjectValue).CountsrclStrnEnd IfsrclStrnEnd IfsrclStrnReturn 0srclStrn End FunctionEndGInt 'EndGInt &MethGrup(EncoInt nameStrn StorageKeyparmStrn$storage As Variant, index As IntegerrsltStrnVariantflagInt !sorcGrup`)stsrInt stscInt ndsrInt ndscInt EncoInt srclStrnDFunction StorageKey(storage As Variant, index As Integer) As VariantsrclStrn?If storage.Type = 9 And storage.ObjectValue IsA Dictionary ThensrclStrn1Return Dictionary(storage.ObjectValue).Key(index)srclStrnEnd IfsrclStrn Return nilsrclStrn End FunctionEndGInt )EndGInt (MethGrup*EncoInt nameStrn StorageValueparmStrn$storage As Variant, index As IntegerrsltStrnVariantflagInt !sorcGrup+stsrInt stscInt ndsrInt ndscInt EncoInt srclStrnFFunction StorageValue(storage As Variant, index As Integer) As VariantsrclStrnIf storage.Type = 9 ThensrclStrn*If storage.ObjectValue IsA Dictionary ThensrclStrnXReturn Dictionary(storage.ObjectValue).Value(Dictionary(storage.ObjectValue).Key(index))srclStrn.ElseIf storage.ObjectValue IsA Collection ThensrclStrn4Return Collection(storage.ObjectValue).Item(index+1)srclStrnEnd IfsrclStrnEnd IfsrclStrn End FunctionEndGInt +EndGInt *MethGrup,EncoInt nameStrn StorageByKeyparmStrn"storage As Variant, key As VariantrsltStrnVariantflagInt !sorcGrupp-stsrInt stscInt ndsrInt ndscInt EncoInt srclStrnDFunction StorageByKey(storage As Variant, key As Variant) As VariantsrclStrn&// This is only valid for dictionariessrclStrna// The only purpose is to make Jarvis Badgley's request work, i.e. preserve existing dictionariessrclStrnsrclStrnIf storage.Type = 9 ThensrclStrnZIf storage.ObjectValue IsA Dictionary And Dictionary(storage.ObjectValue).HasKey(key) ThensrclStrn1Return Dictionary(storage.ObjectValue).Value(key)srclStrnEnd IfsrclStrnEnd IfsrclStrnsrclStrn Return nilsrclStrn End FunctionEndGInt -EndGInt ,CnstGrup.EncoInt nameStrn XMLDictDTDtypeInt defnStrnsflagInt !EndGInt .CnstGrupT/EncoInt nameStrnCurrentVersiontypeInt defnStrn1.1flagInt !EndGInt /CnstGrupP0EncoInt nameStrn PlistVersiontypeInt defnStrn1.0flagInt !EndGInt 0CnstGrup1EncoInt nameStrnPlistDTDtypeInt defnStrnoflagInt !EndGInt 1IntrStrnPadnPadn****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************EOF!