├── shrink_all.bat ├── gui ├── gditools.ico ├── rsrc │ ├── icons │ │ ├── gditools.icns │ │ ├── gditools.ico │ │ ├── gditools.png │ │ ├── imglist │ │ │ ├── disc16.ico │ │ │ ├── file16.ico │ │ │ └── folder16.ico │ │ └── highres │ │ │ ├── Iconleak-Stainless-Document.ico │ │ │ ├── Oxygen-Icons.org-Oxygen-Mimetypes-inode-directory.ico │ │ │ └── Oxygen-Icons.org-Oxygen-Actions-tools-media-optical-format.ico │ └── setupgui.txt ├── gditools.lpr ├── settings.pas ├── about.pas ├── sortfile.lfm ├── sortfile.pas ├── utils.pas ├── settings.lfm ├── extract.lfm ├── extract.pas ├── version.pas ├── gditools.lpi ├── main.pas ├── main.lfm ├── engine.pas └── about.lfm ├── gdishrink.py ├── addons ├── guihelp.py ├── gdifix.py └── bin2iso.py ├── .gitignore ├── licences ├── iso9660_license.txt └── GNU_GPL_v3.txt ├── shrink_all.sh ├── readme.txt └── iso9660.py /shrink_all.bat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/shrink_all.bat -------------------------------------------------------------------------------- /gui/gditools.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/gditools.ico -------------------------------------------------------------------------------- /gui/rsrc/icons/gditools.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/gditools.icns -------------------------------------------------------------------------------- /gui/rsrc/icons/gditools.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/gditools.ico -------------------------------------------------------------------------------- /gui/rsrc/icons/gditools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/gditools.png -------------------------------------------------------------------------------- /gui/rsrc/icons/imglist/disc16.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/imglist/disc16.ico -------------------------------------------------------------------------------- /gui/rsrc/icons/imglist/file16.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/imglist/file16.ico -------------------------------------------------------------------------------- /gui/rsrc/icons/imglist/folder16.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/imglist/folder16.ico -------------------------------------------------------------------------------- /gui/rsrc/icons/highres/Iconleak-Stainless-Document.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/highres/Iconleak-Stainless-Document.ico -------------------------------------------------------------------------------- /gui/rsrc/icons/highres/Oxygen-Icons.org-Oxygen-Mimetypes-inode-directory.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/highres/Oxygen-Icons.org-Oxygen-Mimetypes-inode-directory.ico -------------------------------------------------------------------------------- /gui/rsrc/icons/highres/Oxygen-Icons.org-Oxygen-Actions-tools-media-optical-format.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/einsteinx2/gditools/HEAD/gui/rsrc/icons/highres/Oxygen-Icons.org-Oxygen-Actions-tools-media-optical-format.ico -------------------------------------------------------------------------------- /gdishrink.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from gditools import gdishrink 3 | 4 | def main(argv): 5 | inputfile = argv[1] 6 | outputpath = argv[2] if len(argv) > 2 else None 7 | gdishrink(inputfile, outputpath, True, True) 8 | 9 | def _printUsage(pname='gditools.py'): 10 | print('Usage: {} input_gdi output_path\n'.format(pname)) 11 | print('If no output_path is supplied, the image is shrunk in place') 12 | 13 | if __name__ == '__main__': 14 | if len(sys.argv) > 1: 15 | main(sys.argv) 16 | else: 17 | _printUsage(sys.argv[0]) -------------------------------------------------------------------------------- /gui/gditools.lpr: -------------------------------------------------------------------------------- 1 | program gditools; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | uses 6 | {$IFDEF UNIX}{$IFDEF UseCThreads} 7 | cthreads, 8 | {$ENDIF}{$ENDIF} 9 | Interfaces, // this includes the LCL widgetset 10 | Forms, Main, utils, extract, sortfile, Settings, Engine, Version, about; 11 | 12 | {$R *.res} 13 | 14 | begin 15 | Application.Title:='gditools.py GUI'; 16 | RequireDerivedFormResource := True; 17 | Application.Initialize; 18 | Application.CreateForm(TfrmMain, frmMain); 19 | Application.CreateForm(TfrmExtractAll, frmExtractAll); 20 | Application.CreateForm(TfrmSortFile, frmSortFile); 21 | Application.CreateForm(TfrmSettings, frmSettings); 22 | Application.CreateForm(TfrmAbout, frmAbout); 23 | Application.Run; 24 | end. 25 | 26 | -------------------------------------------------------------------------------- /addons/guihelp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Program that outputs the volume label of the iso9660 filesystem of 6 | a GDI dump. Designed to be used in a GUI SiZiOUS is writing. 7 | 8 | FamilyGuy 2014 9 | 10 | 11 | GuiHelper is released under the GNU General Public License 12 | (version 3), a copy of which (GNU_GPL_v3.txt) is provided in the 13 | license folder. 14 | """ 15 | 16 | import os, sys 17 | sys.path.append('..') 18 | sys.path.append('.') 19 | from gditools import GDIfile 20 | 21 | 22 | if __name__ == '__main__': 23 | with GDIfile(sys.argv[1]) as gdifile: 24 | tmp = gdifile._sorted_records()[0]['name'] 25 | if tmp[0] == '/': 26 | tmp = tmp[1:] 27 | print(tmp) 28 | print(gdifile.get_pvd()['volume_identifier']) 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | *.pyc 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | env/ 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *,cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | 56 | # Sphinx documentation 57 | docs/_build/ 58 | 59 | # PyBuilder 60 | target/ 61 | 62 | #Ipython Notebook 63 | .ipynb_checkpoints 64 | -------------------------------------------------------------------------------- /licences/iso9660_license.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013-2014 Barnaby Gale 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to 5 | deal in the Software without restriction, including without limitation the 6 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | sell copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies of the Software and its documentation and acknowledgment shall be 12 | given in the documentation and software packages that this Software was 13 | used. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /gui/rsrc/setupgui.txt: -------------------------------------------------------------------------------- 1 | ___ __ __ 2 | ____ _____/ (_) /_____ ____ / /____ 3 | / __ `/ __ / / __/ __ \/ __ \/ / ___/ 4 | / /_/ / /_/ / / /_/ /_/ / /_/ / (__ ) 5 | \__, /\__,_/_/\__/\____/\____/_/____/ 6 | /____/ 7 | 8 | For your convenience you can use the GUI provided for your platform. 9 | This package is an addon for the original gditools.py package. It can't 10 | be used alone. 11 | 12 | To use it it's really simple: 13 | 0. Download the gditools.py original package and extract it. 14 | 1. Download the GUI package for your platform (currently Windows or 15 | Linux 64-bit). 16 | 2. Extract the GUI binary at the same location of your gditools.py script. 17 | 3. Just double-click on the 'gditools.exe' or 'gditools' binary to run it. 18 | 19 | The usage is pretty much the same as the excellent GD-ROM Explorer made by 20 | Japanese Cake which is only available on Windows. 21 | 22 | If you want to modify/compile the GUI for your platform, please use the 23 | Lazarus IDE: http://www.lazarus.freepascal.org/ 24 | 25 | ______________________________________________________________________/ eof /___ 26 | -------------------------------------------------------------------------------- /addons/gdifix.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | gdifix, like isofix.exe but much more simple. 6 | 7 | This is an example of a simple program that uses gditools.py as a 8 | base library to handle gdi files in a meaningful manner. 9 | 10 | FamilyGuy 2014 11 | 12 | 13 | gdifix.py is released under the GNU General Public License 14 | (version 3), a copy of which (GNU_GPL_v3.txt) is provided in the 15 | license folder. 16 | """ 17 | 18 | import os, sys 19 | sys.path.append('..') 20 | sys.path.append('.') 21 | from gditools import GDIfile, _copy_buffered 22 | 23 | 24 | def gdifix(ifile, ofile='{dirname}/fixed.iso'): 25 | gdifile = GDIfile(ifile, verbose = True)._gdifile 26 | gdifile.seek(0,0) 27 | ofile = ofile.format(dirname = os.path.dirname(ifile)) 28 | print('Reading: {} \nWriting: {}'.format(ifile,ofile)) 29 | with open(ofile,'wb') as of: 30 | _copy_buffered(gdifile,of) 31 | 32 | def main(argv): 33 | if len(argv) > 1 and os.path.isfile(argv[1]): 34 | gdifix(*argv[1:]) 35 | else: 36 | print('gdifix, converts a gdi dump into a valid iso file\n') 37 | print('Usage: gdifix.py disc.gdi [fixed.iso]') 38 | print('\nFamilyGuy 2014') 39 | 40 | if __name__ == '__main__': 41 | main(sys.argv) 42 | -------------------------------------------------------------------------------- /addons/bin2iso.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | bin2iso, blindly read a file as a 2352 bytes/sector cd-rom image 6 | and outputs the corresponding 2048 bytes/sector image file. 7 | 8 | This is an example of a simple program that uses gditools.py as a 9 | base library to handle gdi files in a meaningful manner. 10 | 11 | FamilyGuy 2014 12 | 13 | 14 | bin2iso.py is released under the GNU General Public License 15 | (version 3), a copy of which (GNU_GPL_v3.txt) is provided in the 16 | license folder. 17 | """ 18 | 19 | import os, sys 20 | sys.path.append('..') 21 | sys.path.append('.') 22 | from gditools import CdImage, _copy_buffered 23 | 24 | 25 | def bin2iso(ifile, ofile='{dirname}/{basename}.iso', length = None): 26 | binfile = CdImage(ifile, mode = 2352) 27 | ofile = ofile.format(dirname = os.path.dirname(ifile), 28 | basename = os.path.splitext(os.path.basename(ifile))[0]) 29 | print('Reading: {} \nWriting: {}'.format(ifile, ofile)) 30 | with open(ofile, 'wb') as of: 31 | _copy_buffered(binfile, of, length=length) 32 | 33 | def main(argv): 34 | if len(argv) > 1 and os.path.isfile(argv[1]): 35 | bin2iso(*argv[1:]) 36 | else: 37 | print('bin2iso, converts a bin file into an iso, BLINDLY.\n') 38 | print('Usage: bin2iso.py file.bin [file.iso]') 39 | print('\nFamilyGuy 2014') 40 | 41 | if __name__ == '__main__': 42 | main(sys.argv) 43 | -------------------------------------------------------------------------------- /gui/settings.pas: -------------------------------------------------------------------------------- 1 | { 2 | gditools.py GUI are licensed under the GNU General Public License (version 3), 3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt. 4 | 5 | SiZiOUS 2015 / www.sizious.com 6 | } 7 | unit Settings; 8 | 9 | {$mode objfpc}{$H+} 10 | 11 | interface 12 | 13 | uses 14 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, 15 | ExtCtrls; 16 | 17 | type 18 | { TfrmSettings } 19 | 20 | TfrmSettings = class(TForm) 21 | btnCancel: TButton; 22 | btnOK: TButton; 23 | btnPythonFileName: TButton; 24 | edtPythonFileName: TEdit; 25 | gbxPython: TGroupBox; 26 | lblPythonHint: TLabel; 27 | opdPythonFileName: TOpenDialog; 28 | pnlPython: TPanel; 29 | pnlButtons: TPanel; 30 | procedure btnPythonFileNameClick(Sender: TObject); 31 | private 32 | function GetPythonExecutable: TFileName; 33 | procedure SetPythonExecutable(AValue: TFileName); 34 | { private declarations } 35 | public 36 | { public declarations } 37 | property PythonExecutable: TFileName 38 | read GetPythonExecutable write SetPythonExecutable; 39 | end; 40 | 41 | var 42 | frmSettings: TfrmSettings; 43 | 44 | implementation 45 | 46 | {$R *.lfm} 47 | 48 | { TfrmSettings } 49 | 50 | procedure TfrmSettings.btnPythonFileNameClick(Sender: TObject); 51 | begin 52 | with opdPythonFileName do 53 | begin 54 | FileName := PythonExecutable; 55 | if Execute then 56 | PythonExecutable := FileName; 57 | end; 58 | end; 59 | 60 | function TfrmSettings.GetPythonExecutable: TFileName; 61 | begin 62 | Result := edtPythonFileName.Text; 63 | end; 64 | 65 | procedure TfrmSettings.SetPythonExecutable(AValue: TFileName); 66 | begin 67 | edtPythonFileName.Text := AValue; 68 | end; 69 | 70 | end. 71 | 72 | -------------------------------------------------------------------------------- /gui/about.pas: -------------------------------------------------------------------------------- 1 | { 2 | gditools.py GUI are licensed under the GNU General Public License (version 3), 3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt. 4 | 5 | SiZiOUS 2015 / www.sizious.com 6 | } 7 | unit About; 8 | 9 | {$mode objfpc}{$H+} 10 | 11 | interface 12 | 13 | uses 14 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, 15 | StdCtrls; 16 | 17 | type 18 | { TfrmAbout } 19 | 20 | TfrmAbout = class(TForm) 21 | btnClose: TButton; 22 | imgLogo: TImage; 23 | lblAppInfo: TLabel; 24 | lblAppName: TLabel; 25 | lblAuthors: TLabel; 26 | lblCredits: TLabel; 27 | lblIcons: TLabel; 28 | lblPoweredBy: TLabel; 29 | procedure btnCloseClick(Sender: TObject); 30 | procedure FormCreate(Sender: TObject); 31 | procedure lblAuthorsClick(Sender: TObject); 32 | procedure lblAuthorsMouseEnter(Sender: TObject); 33 | procedure lblAuthorsMouseLeave(Sender: TObject); 34 | private 35 | { private declarations } 36 | public 37 | { public declarations } 38 | end; 39 | 40 | var 41 | frmAbout: TfrmAbout; 42 | 43 | implementation 44 | 45 | uses 46 | LCLIntf, Version; 47 | 48 | {$R *.lfm} 49 | 50 | { TfrmAbout } 51 | 52 | procedure TfrmAbout.btnCloseClick(Sender: TObject); 53 | begin 54 | Close; 55 | end; 56 | 57 | procedure TfrmAbout.FormCreate(Sender: TObject); 58 | begin 59 | lblAppName.Caption := Application.Title; 60 | Caption := 'About ' + Application.Title + '...'; 61 | lblAppInfo.Caption := 'Version ' + GetFileVersion + ' on ' + GetTargetInfo; 62 | end; 63 | 64 | procedure TfrmAbout.lblAuthorsClick(Sender: TObject); 65 | begin 66 | OpenURL((Sender as TLabel).Hint); 67 | end; 68 | 69 | procedure TfrmAbout.lblAuthorsMouseEnter(Sender: TObject); 70 | begin 71 | with (Sender as TLabel) do 72 | begin 73 | Font.Underline := True; 74 | Cursor := crHandPoint; 75 | end; 76 | end; 77 | 78 | procedure TfrmAbout.lblAuthorsMouseLeave(Sender: TObject); 79 | begin 80 | with (Sender as TLabel) do 81 | begin 82 | Font.Underline := False; 83 | Cursor := crDefault; 84 | end; 85 | end; 86 | 87 | end. 88 | 89 | -------------------------------------------------------------------------------- /gui/sortfile.lfm: -------------------------------------------------------------------------------- 1 | object frmSortFile: TfrmSortFile 2 | Left = 496 3 | Height = 190 4 | Top = 308 5 | Width = 320 6 | BorderIcons = [biSystemMenu] 7 | BorderStyle = bsDialog 8 | Caption = 'Generate Sort File' 9 | ClientHeight = 190 10 | ClientWidth = 320 11 | OnCreate = FormCreate 12 | Position = poScreenCenter 13 | LCLVersion = '1.2.6.0' 14 | object gbxDataDir: TGroupBox 15 | Left = 8 16 | Height = 80 17 | Top = 8 18 | Width = 304 19 | Caption = ' Data Directory: ' 20 | ClientHeight = 58 21 | ClientWidth = 296 22 | TabOrder = 0 23 | object edtDataDir: TEdit 24 | Left = 8 25 | Height = 22 26 | Top = 8 27 | Width = 280 28 | TabOrder = 0 29 | Text = 'data' 30 | end 31 | object cbxVolumeLabel: TCheckBox 32 | Left = 8 33 | Height = 18 34 | Top = 38 35 | Width = 133 36 | Caption = 'Use Volume Label' 37 | OnChange = cbxVolumeLabelChange 38 | TabOrder = 1 39 | end 40 | end 41 | object gbxOutputDir: TGroupBox 42 | Left = 8 43 | Height = 56 44 | Top = 96 45 | Width = 304 46 | Caption = ' Output FileName: ' 47 | ClientHeight = 34 48 | ClientWidth = 296 49 | TabOrder = 1 50 | object edtOutputFileName: TEdit 51 | Left = 8 52 | Height = 22 53 | Top = 8 54 | Width = 240 55 | TabOrder = 0 56 | end 57 | object btnOutputFileName: TButton 58 | Left = 256 59 | Height = 25 60 | Top = 6 61 | Width = 35 62 | Caption = '...' 63 | OnClick = btnOutputFileNameClick 64 | TabOrder = 1 65 | end 66 | end 67 | object btnOK: TButton 68 | Left = 112 69 | Height = 25 70 | Top = 160 71 | Width = 99 72 | Caption = 'OK' 73 | ModalResult = 1 74 | TabOrder = 2 75 | end 76 | object btnCancel: TButton 77 | Left = 213 78 | Height = 25 79 | Top = 160 80 | Width = 99 81 | Caption = 'Cancel' 82 | ModalResult = 2 83 | TabOrder = 3 84 | end 85 | object svdSortFile: TSaveDialog 86 | Title = 'Save the Sort file to...' 87 | DefaultExt = '.txt' 88 | FileName = 'sorttxt.txt' 89 | Filter = 'Sort Files (sorttxt.txt)|sorttxt.txt|Text Files (*.txt)|*.txt|All Files (*.*)|*.*' 90 | Options = [ofOverwritePrompt, ofPathMustExist, ofEnableSizing, ofViewDetail] 91 | left = 208 92 | top = 104 93 | end 94 | end -------------------------------------------------------------------------------- /shrink_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Text formatting 4 | readonly BOLD=$(tput bold) 5 | readonly RED=$(tput setaf 1) 6 | readonly NORMAL=$(tput sgr0) 7 | 8 | promptContinue() { 9 | read -n 1 -s -r -p "${BOLD}Press ctrl+c to cancel or any key to continue...${NORMAL}" 10 | printf "\n\n" 11 | } 12 | 13 | echo "NOTE: Python 2.7.x is required to use gditools, Python 3.x.x will not work." 14 | echo "Your installed Python version is: ${BOLD}${RED}$(python --version 2>&1)${NORMAL}" 15 | promptContinue 16 | 17 | echo "NOTE: If you have the REDUMP game set, they add some non-standard track data to" 18 | echo "their gdi files that may or may not work correctly. TOSEC or TruRip are preferred." 19 | promptContinue 20 | 21 | echo "Instructions:" 22 | echo "Make sure to copy this script as well as the gdishrink.py, gditools.py, and iso9660.py" 23 | echo "files into your directory of Dreamcast game folders or it won't work. The folder must" 24 | echo "contain sub-folders that each have one game's .gdi file and associated image files." 25 | echo " " 26 | echo "For example:" 27 | echo " " 28 | echo "├── Crazy\ Taxi\ v1.004\ (1999)(Sega)(NTSC)(US)[!][10S\ 51035]" 29 | echo "│   ├── Crazy\ Taxi\ v1.004\ (1999)(Sega)(NTSC)(US)[!][10S\ 51035].gdi" 30 | echo "│   ├── track01.bin" 31 | echo "│   ├── track02.raw" 32 | echo "│   └── track03.bin" 33 | echo "├── Dead\ or\ Alive\ 2\ v1.100\ (2000)(Tecmo)(NTSC)(US)[!]" 34 | echo "│   ├── Dead\ or\ Alive\ 2\ v1.100\ (2000)(Tecmo)(NTSC)(US)[!].gdi" 35 | echo "│   ├── track01.bin" 36 | echo "│   ├── track02.raw" 37 | echo "│   └── track03.bin" 38 | echo "├── Rez\ v1.003\ (2001)(Sega)(PAL)(M6)[!]" 39 | echo "| ├── Rez\ v1.003\ (2001)(Sega)(PAL)(M6)[!].gdi" 40 | echo "| ├── track01.bin" 41 | echo "| ├── track02.raw" 42 | echo "| └── track03.bin" 43 | echo "├── gdishrink.py" 44 | echo "├── gditools.py" 45 | echo "├── iso9660.py" 46 | echo "└── shrink_all.sh" 47 | echo " " 48 | echo " " 49 | echo "Are you sure you want to shrink all .gdi images ${BOLD}${RED}IN PLACE${NORMAL} in directory: $(pwd)" 50 | echo "${BOLD}${RED}IMPORTANT:${NORMAL} Make sure you have backups of the original files, as this process is not reversible." 51 | promptContinue 52 | 53 | numthreads=2 54 | read -p "How many threads would you like to use (recommended 2 for HDDs and 10 for SSDs): " numthreads 55 | if [ -n "$numthreads" ] && [ "$numthreads" -eq "$numthreads" ] 2>/dev/null; then 56 | echo "${BOLD}Using $numthreads threads${NORMAL}" 57 | find . -depth -mindepth 2 -maxdepth 2 -name "*.gdi" -exec echo -ne '"{}"\n' \; | sort | xargs -P$numthreads -n1 bash -c 'echo "Shinking $0" && python ./gdishrink.py "$0" > /dev/null 2>&1 && printf "Finished $0\n"' 58 | echo "${BOLD}Done!${NORMAL}" 59 | else 60 | echo "${BOLD}${RED}You must enter a valid number of threads${NORMAL}" 61 | fi 62 | 63 | -------------------------------------------------------------------------------- /gui/sortfile.pas: -------------------------------------------------------------------------------- 1 | { 2 | gditools.py GUI are licensed under the GNU General Public License (version 3), 3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt. 4 | 5 | SiZiOUS 2015 / www.sizious.com 6 | } 7 | unit SortFile; 8 | 9 | {$mode objfpc}{$H+} 10 | 11 | interface 12 | 13 | uses 14 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls; 15 | 16 | type 17 | { TfrmSortFile } 18 | 19 | TfrmSortFile = class(TForm) 20 | btnCancel: TButton; 21 | btnOK: TButton; 22 | btnOutputFileName: TButton; 23 | cbxVolumeLabel: TCheckBox; 24 | edtDataDir: TEdit; 25 | edtOutputFileName: TEdit; 26 | gbxDataDir: TGroupBox; 27 | gbxOutputDir: TGroupBox; 28 | svdSortFile: TSaveDialog; 29 | procedure btnOutputFileNameClick(Sender: TObject); 30 | procedure cbxVolumeLabelChange(Sender: TObject); 31 | procedure FormCreate(Sender: TObject); 32 | private 33 | function GetDataDirectory: string; 34 | function GetOutputFileName: TFileName; 35 | procedure SetDataDirectory(AValue: string); 36 | procedure SetOutputFileName(AValue: TFileName); 37 | { private declarations } 38 | public 39 | { public declarations } 40 | property DataDirectory: string 41 | read GetDataDirectory write SetDataDirectory; 42 | property OutputFileName: TFileName 43 | read GetOutputFileName write SetOutputFileName; 44 | end; 45 | 46 | var 47 | frmSortFile: TfrmSortFile; 48 | 49 | implementation 50 | 51 | uses 52 | Engine; 53 | 54 | {$R *.lfm} 55 | 56 | { TfrmSortFile } 57 | 58 | procedure TfrmSortFile.btnOutputFileNameClick(Sender: TObject); 59 | begin 60 | with svdSortFile do 61 | begin 62 | FileName := OutputFileName; 63 | if Execute then 64 | OutputFileName := FileName; 65 | end; 66 | end; 67 | 68 | procedure TfrmSortFile.cbxVolumeLabelChange(Sender: TObject); 69 | begin 70 | edtDataDir.Enabled := not cbxVolumeLabel.Checked; 71 | end; 72 | 73 | procedure TfrmSortFile.FormCreate(Sender: TObject); 74 | begin 75 | OutputFileName := IncludeTrailingPathDelimiter(GetCurrentDir) + SFILE_SORT; 76 | end; 77 | 78 | function TfrmSortFile.GetDataDirectory: string; 79 | begin 80 | Result := edtDataDir.Text; 81 | if cbxVolumeLabel.Checked then 82 | Result := SDIR_DATA_VOLUME_LABEL; 83 | end; 84 | 85 | function TfrmSortFile.GetOutputFileName: TFileName; 86 | begin 87 | Result := edtOutputFileName.Text; 88 | end; 89 | 90 | procedure TfrmSortFile.SetDataDirectory(AValue: string); 91 | begin 92 | edtDataDir.Text := AValue; 93 | end; 94 | 95 | procedure TfrmSortFile.SetOutputFileName(AValue: TFileName); 96 | begin 97 | edtOutputFileName.Text := AValue; 98 | end; 99 | 100 | end. 101 | 102 | -------------------------------------------------------------------------------- /gui/utils.pas: -------------------------------------------------------------------------------- 1 | { 2 | gditools.py GUI are licensed under the GNU General Public License (version 3), 3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt. 4 | 5 | SiZiOUS 2015 / www.sizious.com 6 | } 7 | unit Utils; 8 | 9 | {$mode objfpc}{$H+} 10 | 11 | interface 12 | 13 | uses 14 | Classes, SysUtils, ComCtrls; 15 | 16 | function GetNodePath(TreeNode: TTreeNode): string; 17 | procedure LoadConfig; 18 | procedure SaveConfig; 19 | function GetApplicationPath: TFileName; 20 | 21 | implementation 22 | 23 | uses 24 | Forms, IniFiles, Main; 25 | 26 | var 27 | sAppPath: TFileName; 28 | 29 | { Thanks to L.Saenz 30 | http://www.swissdelphicenter.ch/torry/showcode.php?id=859 } 31 | function GetNodePath(TreeNode: TTreeNode; var Path: string): string; overload; 32 | begin 33 | Result := ''; 34 | if Assigned(TreeNode) then 35 | begin 36 | Path := TreeNode.Text + '/' + Path; 37 | if TreeNode.Level = 0 then 38 | Result := Path 39 | else 40 | Result := GetNodePath(TreeNode.Parent, Path); 41 | end; 42 | end; 43 | 44 | function GetNodePath(TreeNode: TTreeNode): string; 45 | var 46 | Path: string; 47 | 48 | begin 49 | Path := ''; 50 | Result := StringReplace(GetNodePath(TreeNode, Path), '//', '/', []); 51 | end; 52 | 53 | // Get the application configuration file name. 54 | function GetConfigFile: TFileName; 55 | begin 56 | Result := GetApplicationPath + 57 | ChangeFileExt(ExtractFileName(Application.ExeName), '.conf'); 58 | end; 59 | 60 | // Load the previous saved configuration. 61 | procedure LoadConfig; 62 | var 63 | IniFile: TIniFile; 64 | 65 | begin 66 | IniFile := TIniFile.Create(GetConfigFile); 67 | try 68 | GDReader.PythonExecutable := IniFile.ReadString('General', 'PythonExecutable', 'python'); 69 | finally 70 | IniFile.Free; 71 | end; 72 | end; 73 | 74 | // Save the current configuration. 75 | procedure SaveConfig; 76 | var 77 | IniFile: TIniFile; 78 | 79 | begin 80 | IniFile := TIniFile.Create(GetConfigFile); 81 | try 82 | IniFile.WriteString('General', 'PythonExecutable', GDReader.PythonExecutable); 83 | finally 84 | IniFile.Free; 85 | end; 86 | end; 87 | 88 | // Get the application location 89 | function GetApplicationPath: TFileName; 90 | var 91 | Path: TFileName; 92 | {$IFDEF Darwin} 93 | i: Integer; 94 | {$ENDIF} 95 | 96 | begin 97 | if (sAppPath = '') then 98 | begin 99 | Path := Application.Location; 100 | {$IFDEF Darwin} 101 | i := Pos('.app', Path); 102 | if i > 0 then 103 | begin 104 | i := LastDelimiter('/', Copy(Path, 1, i)); 105 | Path := Copy(Path, 1, i); 106 | end; 107 | {$ENDIF} 108 | sAppPath := IncludeTrailingPathDelimiter(Path); 109 | end; 110 | Result := sAppPath; 111 | end; 112 | 113 | initialization 114 | sAppPath := ''; 115 | 116 | end. 117 | 118 | -------------------------------------------------------------------------------- /gui/settings.lfm: -------------------------------------------------------------------------------- 1 | object frmSettings: TfrmSettings 2 | Left = 594 3 | Height = 182 4 | Top = 399 5 | Width = 320 6 | AutoSize = True 7 | BorderIcons = [biSystemMenu] 8 | BorderStyle = bsDialog 9 | Caption = 'Settings' 10 | ClientHeight = 182 11 | ClientWidth = 320 12 | Position = poScreenCenter 13 | LCLVersion = '1.2.6.0' 14 | object gbxPython: TGroupBox 15 | Left = 4 16 | Height = 136 17 | Top = 4 18 | Width = 312 19 | Align = alClient 20 | BorderSpacing.Around = 4 21 | Caption = ' Python Executable: ' 22 | ClientHeight = 114 23 | ClientWidth = 304 24 | TabOrder = 0 25 | object lblPythonHint: TLabel 26 | Left = 12 27 | Height = 76 28 | Top = 4 29 | Width = 280 30 | Align = alClient 31 | AutoSize = False 32 | BorderSpacing.Left = 8 33 | BorderSpacing.Right = 8 34 | BorderSpacing.Around = 4 35 | Caption = 'Please select the location of your Python 2 executable.'#13#10#13#10'If your Python 2 executable is already in your PATH,'#13#10'inputting ''python'' in the box below should be fine.' 36 | ParentColor = False 37 | end 38 | object pnlPython: TPanel 39 | Left = 0 40 | Height = 30 41 | Top = 84 42 | Width = 304 43 | Align = alBottom 44 | BevelOuter = bvNone 45 | ClientHeight = 30 46 | ClientWidth = 304 47 | TabOrder = 0 48 | object btnPythonFileName: TButton 49 | Left = 260 50 | Height = 25 51 | Top = 0 52 | Width = 35 53 | Anchors = [akTop, akRight] 54 | Caption = '...' 55 | OnClick = btnPythonFileNameClick 56 | TabOrder = 0 57 | end 58 | object edtPythonFileName: TEdit 59 | Left = 10 60 | Height = 22 61 | Top = 2 62 | Width = 242 63 | Anchors = [akTop, akLeft, akRight] 64 | BorderSpacing.Bottom = 10 65 | TabOrder = 1 66 | Text = 'python' 67 | end 68 | end 69 | end 70 | object pnlButtons: TPanel 71 | Left = 0 72 | Height = 38 73 | Top = 144 74 | Width = 320 75 | Align = alBottom 76 | BevelOuter = bvNone 77 | ClientHeight = 38 78 | ClientWidth = 320 79 | TabOrder = 1 80 | object btnOK: TButton 81 | Left = 112 82 | Height = 25 83 | Top = 8 84 | Width = 99 85 | Caption = 'OK' 86 | ModalResult = 1 87 | TabOrder = 0 88 | end 89 | object btnCancel: TButton 90 | Left = 213 91 | Height = 25 92 | Top = 8 93 | Width = 99 94 | Caption = 'Cancel' 95 | ModalResult = 2 96 | TabOrder = 1 97 | end 98 | end 99 | object opdPythonFileName: TOpenDialog 100 | Title = 'Please select the Python 2 executable...' 101 | Filter = 'Python 2|python;python.exe|All Files|*.*' 102 | Options = [ofPathMustExist, ofFileMustExist, ofEnableSizing, ofViewDetail] 103 | left = 136 104 | top = 80 105 | end 106 | end 107 | -------------------------------------------------------------------------------- /gui/extract.lfm: -------------------------------------------------------------------------------- 1 | object frmExtractAll: TfrmExtractAll 2 | Left = 462 3 | Height = 285 4 | Top = 270 5 | Width = 320 6 | BorderIcons = [biSystemMenu] 7 | BorderStyle = bsDialog 8 | Caption = 'Extract All' 9 | ClientHeight = 285 10 | ClientWidth = 320 11 | OnCreate = FormCreate 12 | Position = poScreenCenter 13 | LCLVersion = '1.2.6.0' 14 | object gbxDataDir: TGroupBox 15 | Left = 8 16 | Height = 80 17 | Top = 8 18 | Width = 304 19 | Caption = ' Data Directory: ' 20 | ClientHeight = 58 21 | ClientWidth = 296 22 | TabOrder = 0 23 | object edtDataDir: TEdit 24 | Left = 8 25 | Height = 22 26 | Top = 8 27 | Width = 280 28 | TabOrder = 0 29 | Text = 'data' 30 | end 31 | object cbxVolumeLabel: TCheckBox 32 | Left = 8 33 | Height = 18 34 | Top = 38 35 | Width = 133 36 | Caption = 'Use Volume Label' 37 | OnChange = cbxVolumeLabelChange 38 | TabOrder = 1 39 | end 40 | end 41 | object gbxOutputDir: TGroupBox 42 | Left = 8 43 | Height = 56 44 | Top = 96 45 | Width = 304 46 | Caption = ' Output Directory: ' 47 | ClientHeight = 34 48 | ClientWidth = 296 49 | TabOrder = 1 50 | object edtOutputDir: TEdit 51 | Left = 8 52 | Height = 22 53 | Top = 8 54 | Width = 240 55 | TabOrder = 0 56 | end 57 | object btnOutputDir: TButton 58 | Left = 256 59 | Height = 25 60 | Top = 6 61 | Width = 35 62 | Caption = '...' 63 | OnClick = btnOutputDirClick 64 | TabOrder = 1 65 | end 66 | end 67 | object ckgOptions: TCheckGroup 68 | Left = 7 69 | Height = 80 70 | Top = 160 71 | Width = 305 72 | AutoFill = True 73 | Caption = ' Options: ' 74 | ChildSizing.LeftRightSpacing = 6 75 | ChildSizing.TopBottomSpacing = 6 76 | ChildSizing.EnlargeHorizontal = crsHomogenousChildResize 77 | ChildSizing.EnlargeVertical = crsHomogenousChildResize 78 | ChildSizing.ShrinkHorizontal = crsScaleChilds 79 | ChildSizing.ShrinkVertical = crsScaleChilds 80 | ChildSizing.Layout = cclLeftToRightThenTopToBottom 81 | ChildSizing.ControlsPerLine = 1 82 | ClientHeight = 58 83 | ClientWidth = 297 84 | Items.Strings = ( 85 | 'Extract Bootsector (IP.BIN)' 86 | 'Generate Sort File (sorttxt.txt)' 87 | ) 88 | TabOrder = 2 89 | Data = { 90 | 020000000202 91 | } 92 | end 93 | object btnOK: TButton 94 | Left = 112 95 | Height = 25 96 | Top = 248 97 | Width = 99 98 | Caption = 'OK' 99 | ModalResult = 1 100 | TabOrder = 3 101 | end 102 | object btnCancel: TButton 103 | Left = 213 104 | Height = 25 105 | Top = 248 106 | Width = 99 107 | Caption = 'Cancel' 108 | ModalResult = 2 109 | TabOrder = 4 110 | end 111 | object bfdExtractAll: TSelectDirectoryDialog 112 | Title = 'Select the output directory:' 113 | left = 208 114 | top = 112 115 | end 116 | end 117 | -------------------------------------------------------------------------------- /gui/extract.pas: -------------------------------------------------------------------------------- 1 | { 2 | gditools.py GUI are licensed under the GNU General Public License (version 3), 3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt. 4 | 5 | SiZiOUS 2015 / www.sizious.com 6 | } 7 | unit Extract; 8 | 9 | {$mode objfpc}{$H+} 10 | 11 | interface 12 | 13 | uses 14 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, 15 | ExtCtrls; 16 | 17 | type 18 | { TfrmExtractAll } 19 | 20 | TfrmExtractAll = class(TForm) 21 | btnOutputDir: TButton; 22 | btnOK: TButton; 23 | btnCancel: TButton; 24 | cbxVolumeLabel: TCheckBox; 25 | ckgOptions: TCheckGroup; 26 | edtOutputDir: TEdit; 27 | edtDataDir: TEdit; 28 | gbxDataDir: TGroupBox; 29 | gbxOutputDir: TGroupBox; 30 | bfdExtractAll: TSelectDirectoryDialog; 31 | procedure btnOutputDirClick(Sender: TObject); 32 | procedure cbxVolumeLabelChange(Sender: TObject); 33 | procedure FormCreate(Sender: TObject); 34 | private 35 | { private declarations } 36 | function GetDataDirectory: string; 37 | function GetExtractBootstrap: Boolean; 38 | function GetGenerateSortFile: Boolean; 39 | function GetOutputDirectory: TFileName; 40 | procedure SetDataDirectory(AValue: string); 41 | procedure SetExtractBootstrap(AValue: Boolean); 42 | procedure SetGenerateSortFile(AValue: Boolean); 43 | procedure SetOutputDirectory(AValue: TFileName); 44 | public 45 | { public declarations } 46 | property DataDirectory: string read GetDataDirectory write SetDataDirectory; 47 | property OutputDirectory: TFileName 48 | read GetOutputDirectory write SetOutputDirectory; 49 | property ExtractBootstrap: Boolean read GetExtractBootstrap 50 | write SetExtractBootstrap; 51 | property GenerateSortFile: Boolean read GetGenerateSortFile 52 | write SetGenerateSortFile; 53 | end; 54 | 55 | var 56 | frmExtractAll: TfrmExtractAll; 57 | 58 | implementation 59 | 60 | uses 61 | Engine; 62 | 63 | {$R *.lfm} 64 | 65 | { TfrmExtractAll } 66 | 67 | procedure TfrmExtractAll.btnOutputDirClick(Sender: TObject); 68 | begin 69 | with bfdExtractAll do 70 | begin 71 | FileName := OutputDirectory; 72 | if Execute then 73 | OutputDirectory := FileName; 74 | end; 75 | end; 76 | 77 | procedure TfrmExtractAll.cbxVolumeLabelChange(Sender: TObject); 78 | begin 79 | edtDataDir.Enabled := not cbxVolumeLabel.Checked; 80 | end; 81 | 82 | procedure TfrmExtractAll.FormCreate(Sender: TObject); 83 | begin 84 | ExtractBootstrap := True; 85 | GenerateSortFile := True; 86 | OutputDirectory := GetCurrentDir; 87 | end; 88 | 89 | function TfrmExtractAll.GetDataDirectory: string; 90 | begin 91 | Result := edtDataDir.Text; 92 | if cbxVolumeLabel.Checked then 93 | Result := SDIR_DATA_VOLUME_LABEL; 94 | end; 95 | 96 | function TfrmExtractAll.GetExtractBootstrap: Boolean; 97 | begin 98 | Result := ckgOptions.Checked[0]; 99 | end; 100 | 101 | function TfrmExtractAll.GetGenerateSortFile: Boolean; 102 | begin 103 | Result := ckgOptions.Checked[1]; 104 | end; 105 | 106 | function TfrmExtractAll.GetOutputDirectory: TFileName; 107 | begin 108 | Result := IncludeTrailingPathDelimiter(edtOutputDir.Text); 109 | end; 110 | 111 | procedure TfrmExtractAll.SetDataDirectory(AValue: string); 112 | begin 113 | edtDataDir.Text := AValue; 114 | end; 115 | 116 | procedure TfrmExtractAll.SetExtractBootstrap(AValue: Boolean); 117 | begin 118 | ckgOptions.Checked[0] := AValue; 119 | end; 120 | 121 | procedure TfrmExtractAll.SetGenerateSortFile(AValue: Boolean); 122 | begin 123 | ckgOptions.Checked[1] := AValue; 124 | end; 125 | 126 | procedure TfrmExtractAll.SetOutputDirectory(AValue: TFileName); 127 | begin 128 | edtOutputDir.Text := IncludeTrailingPathDelimiter(AValue); 129 | end; 130 | 131 | end. 132 | 133 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | ___ __ __ 2 | ____ _____/ (_) /_____ ____ / /____ 3 | / __ `/ __ / / __/ __ \/ __ \/ / ___/ 4 | / /_/ / /_/ / / /_/ /_/ / /_/ / (__ ) 5 | \__, /\__,_/_/\__/\____/\____/_/____/ 6 | /____/ 7 | 8 | gditools, a Python library to extract files, sorttxt.txt and 9 | bootsector (IP.BIN) from SEGA Gigabyte Disc (GD-ROM) dumps in 10 | gdi format. 11 | 12 | The goals is to make it efficient, readable and multi-platform. 13 | 14 | As of December 2014 it's tested working on Linux and Win7 under 15 | python 2.7 but it was only tested on x86_64 processors. The 16 | performances are typically limited by the usage of a platter HDD. 17 | When using a SSD, the CPU can be the bottleneck if it's an old one 18 | or if it's used in power-saving mode. 3-tracks gdi can be extracted 19 | in less than 2 seconds with the right configuration (~1GiB of data). 20 | 21 | To get the most recent version, browse code on: 22 | https://sourceforge.net/projects/dcisotools/ 23 | 24 | or using git: 25 | git clone git://git.code.sf.net/p/dcisotools/code dcisotools-code 26 | 27 | Releases of stable code might be sporadically packaged into a .zip 28 | archive for convenience, and made available on the SourceForge page 29 | download section. 30 | 31 | bin2iso.py and gdifix.py (creating a single .iso from a gdi dump) 32 | are provided in the 'addons' folder. They can be used as is or be 33 | used to see how to incorporate gditools.py in another project. 34 | 35 | See the Legal Stuff section at the end of this readme for the infos 36 | on licensing and using this project in another one. 37 | 38 | Enjoy! 39 | 40 | FamilyGuy 2015 41 | 42 | Thanks to SiZiOUS for testing the code, providing support and for the GUI. 43 | 44 | ___ _ __ 45 | / _ \___ ___ ___ __(_)______ __ _ ___ ___ / /____ 46 | ___/ , _/ -_) _ `/ // / / __/ -_) ' \/ -_) _ \/ __(_-<________________________ 47 | /_/|_|\__/\_, /\_,_/_/_/ \__/_/_/_/\__/_//_/\__/___/ 48 | /_/ 49 | 50 | - Python 2.7.x, Python 3 won't work. 51 | - On Windows you have to add the python folder to your path manually (or 52 | choose the option when installing). 53 | 54 | __ __ 55 | / / / /__ ___ ____ ____ 56 | ___/ /_/ (_- Use ISO9660 volume label) 71 | --sort-spacer [num] Sorttxt entries are sperated by num 72 | --silent Minimal verbosity mode 73 | [no option] Display gdi infos if not silent 74 | 75 | __ __ ____ __ 76 | / / / /__ ___ ____ ____ / __/_ _____ ___ _ ___ / /__ ___ 77 | ___/ /_/ (_-'' Then 160 | oStringList.Values[oTable.Keys[j]] := oTable.ValuesByIndex[j]; 161 | end; 162 | end; 163 | end; 164 | 165 | Function ProductVersionToString(PV: TFileProductVersion): String; 166 | Begin 167 | Result := Format('%d.%d.%d.%d', [PV[0], PV[1], PV[2], PV[3]]); 168 | End; 169 | 170 | Function GetProductVersion: String; 171 | Begin 172 | CreateInfo; 173 | 174 | If FInfo.BuildInfoAvailable Then 175 | Result := ProductVersionToString(FInfo.FixedInfo.ProductVersion) 176 | Else 177 | Result := 'No build information available'; 178 | End; 179 | 180 | Function GetFileVersion: String; 181 | Begin 182 | CreateInfo; 183 | 184 | If FInfo.BuildInfoAvailable Then 185 | Result := ProductVersionToString(FInfo.FixedInfo.FileVersion) 186 | Else 187 | Result := 'No build information available'; 188 | End; 189 | 190 | { TVersionInfo } 191 | 192 | Function TVersionInfo.GetFixedInfo: TVersionFixedInfo; 193 | Begin 194 | Result := FVersResource.FixedInfo; 195 | End; 196 | 197 | Function TVersionInfo.GetStringFileInfo: TVersionStringFileInfo; 198 | Begin 199 | Result := FVersResource.StringFileInfo; 200 | End; 201 | 202 | Function TVersionInfo.GetVarFileInfo: TVersionVarFileInfo; 203 | Begin 204 | Result := FVersResource.VarFileInfo; 205 | End; 206 | 207 | Constructor TVersionInfo.Create; 208 | Begin 209 | Inherited Create; 210 | 211 | FVersResource := TVersionResource.Create; 212 | FBuildInfoAvailable := False; 213 | End; 214 | 215 | Destructor TVersionInfo.Destroy; 216 | Begin 217 | FVersResource.Free; 218 | 219 | Inherited Destroy; 220 | End; 221 | 222 | Procedure TVersionInfo.Load(Instance: THandle); 223 | Var 224 | Stream: TResourceStream; 225 | ResID: Integer; 226 | Res: TFPResourceHandle; 227 | 228 | Begin 229 | FBuildInfoAvailable := False; 230 | ResID := 1; 231 | 232 | // Defensive code to prevent failure if no resource available... 233 | Res := FindResource(Instance, PChar(PtrInt(ResID)), PChar(RT_VERSION)); 234 | If Res = 0 Then 235 | Exit; 236 | 237 | Stream := TResourceStream.CreateFromID(Instance, ResID, PChar(RT_VERSION)); 238 | Try 239 | FVersResource.SetCustomRawDataStream(Stream); 240 | 241 | // access some property to load from the stream 242 | FVersResource.FixedInfo; 243 | 244 | // clear the stream 245 | FVersResource.SetCustomRawDataStream(nil); 246 | 247 | FBuildInfoAvailable := True; 248 | Finally 249 | Stream.Free; 250 | End; 251 | End; 252 | 253 | Initialization 254 | FInfo := nil; 255 | 256 | Finalization 257 | If Assigned(FInfo) Then 258 | FInfo.Free; 259 | 260 | End. 261 | -------------------------------------------------------------------------------- /gui/gditools.lpi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | <ResourceType Value="res"/> 11 | <UseXPManifest Value="True"/> 12 | <Icon Value="0"/> 13 | </General> 14 | <i18n> 15 | <EnableI18N LFM="False"/> 16 | </i18n> 17 | <VersionInfo> 18 | <UseVersionInfo Value="True"/> 19 | <AutoIncrementBuild Value="True"/> 20 | <MajorVersionNr Value="1"/> 21 | <RevisionNr Value="1"/> 22 | <BuildNr Value="100"/> 23 | <Language Value="040C"/> 24 | <StringTable Comments="www.sizious.com" CompanyName="SiZiOUS" FileDescription="gditools.py GUI" InternalName="gditools.exe" LegalCopyright="© Copyleft 2015" LegalTrademarks="gditools.py was made FamilyGuy" OriginalFilename="gditools" ProductName="gditools.py GUI" ProductVersion="1.0"/> 25 | </VersionInfo> 26 | <BuildModes Count="3"> 27 | <Item1 Name="Default" Default="True"/> 28 | <Item2 Name="Debug"> 29 | <CompilerOptions> 30 | <Version Value="11"/> 31 | <PathDelim Value="\"/> 32 | <Target> 33 | <Filename Value="gditools"/> 34 | </Target> 35 | <SearchPaths> 36 | <IncludeFiles Value="$(ProjOutDir)"/> 37 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 38 | </SearchPaths> 39 | <Parsing> 40 | <SyntaxOptions> 41 | <IncludeAssertionCode Value="True"/> 42 | </SyntaxOptions> 43 | </Parsing> 44 | <CodeGeneration> 45 | <Checks> 46 | <IOChecks Value="True"/> 47 | <RangeChecks Value="True"/> 48 | <OverflowChecks Value="True"/> 49 | <StackChecks Value="True"/> 50 | </Checks> 51 | </CodeGeneration> 52 | <Linking> 53 | <Debugging> 54 | <DebugInfoType Value="dsDwarf2Set"/> 55 | <UseHeaptrc Value="True"/> 56 | <UseExternalDbgSyms Value="True"/> 57 | </Debugging> 58 | <Options> 59 | <Win32> 60 | <GraphicApplication Value="True"/> 61 | </Win32> 62 | </Options> 63 | </Linking> 64 | <Other> 65 | <CompilerMessages> 66 | <MsgFileName Value=""/> 67 | </CompilerMessages> 68 | <CustomOptions Value="-dDEBUG"/> 69 | <CompilerPath Value="$(CompPath)"/> 70 | </Other> 71 | </CompilerOptions> 72 | </Item2> 73 | <Item3 Name="Release"> 74 | <CompilerOptions> 75 | <Version Value="11"/> 76 | <PathDelim Value="\"/> 77 | <Target> 78 | <Filename Value="gditools"/> 79 | </Target> 80 | <SearchPaths> 81 | <IncludeFiles Value="$(ProjOutDir)"/> 82 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 83 | </SearchPaths> 84 | <CodeGeneration> 85 | <SmartLinkUnit Value="True"/> 86 | <Optimizations> 87 | <OptimizationLevel Value="3"/> 88 | </Optimizations> 89 | </CodeGeneration> 90 | <Linking> 91 | <Debugging> 92 | <GenerateDebugInfo Value="False"/> 93 | <StripSymbols Value="True"/> 94 | </Debugging> 95 | <LinkSmart Value="True"/> 96 | <Options> 97 | <Win32> 98 | <GraphicApplication Value="True"/> 99 | </Win32> 100 | </Options> 101 | </Linking> 102 | <Other> 103 | <WriteFPCLogo Value="False"/> 104 | <CompilerMessages> 105 | <MsgFileName Value=""/> 106 | </CompilerMessages> 107 | <CustomOptions Value="-dRELEASE"/> 108 | <CompilerPath Value="$(CompPath)"/> 109 | </Other> 110 | </CompilerOptions> 111 | </Item3> 112 | </BuildModes> 113 | <PublishOptions> 114 | <Version Value="2"/> 115 | <DestinationDirectory Value="C:\Users\Utilisateur\Desktop\published"/> 116 | </PublishOptions> 117 | <RunParams> 118 | <local> 119 | <FormatVersion Value="1"/> 120 | </local> 121 | </RunParams> 122 | <RequiredPackages Count="1"> 123 | <Item1> 124 | <PackageName Value="LCL"/> 125 | </Item1> 126 | </RequiredPackages> 127 | <Units Count="9"> 128 | <Unit0> 129 | <Filename Value="gditools.lpr"/> 130 | <IsPartOfProject Value="True"/> 131 | <UnitName Value="gditools"/> 132 | </Unit0> 133 | <Unit1> 134 | <Filename Value="main.pas"/> 135 | <IsPartOfProject Value="True"/> 136 | <ComponentName Value="frmMain"/> 137 | <HasResources Value="True"/> 138 | <ResourceBaseClass Value="Form"/> 139 | <UnitName Value="Main"/> 140 | </Unit1> 141 | <Unit2> 142 | <Filename Value="utils.pas"/> 143 | <IsPartOfProject Value="True"/> 144 | <UnitName Value="Utils"/> 145 | </Unit2> 146 | <Unit3> 147 | <Filename Value="extract.pas"/> 148 | <IsPartOfProject Value="True"/> 149 | <ComponentName Value="frmExtractAll"/> 150 | <HasResources Value="True"/> 151 | <ResourceBaseClass Value="Form"/> 152 | <UnitName Value="Extract"/> 153 | </Unit3> 154 | <Unit4> 155 | <Filename Value="sortfile.pas"/> 156 | <IsPartOfProject Value="True"/> 157 | <ComponentName Value="frmSortFile"/> 158 | <HasResources Value="True"/> 159 | <ResourceBaseClass Value="Form"/> 160 | <UnitName Value="SortFile"/> 161 | </Unit4> 162 | <Unit5> 163 | <Filename Value="settings.pas"/> 164 | <IsPartOfProject Value="True"/> 165 | <ComponentName Value="frmSettings"/> 166 | <HasResources Value="True"/> 167 | <ResourceBaseClass Value="Form"/> 168 | <UnitName Value="Settings"/> 169 | </Unit5> 170 | <Unit6> 171 | <Filename Value="engine.pas"/> 172 | <IsPartOfProject Value="True"/> 173 | <UnitName Value="Engine"/> 174 | </Unit6> 175 | <Unit7> 176 | <Filename Value="version.pas"/> 177 | <IsPartOfProject Value="True"/> 178 | <UnitName Value="Version"/> 179 | </Unit7> 180 | <Unit8> 181 | <Filename Value="about.pas"/> 182 | <IsPartOfProject Value="True"/> 183 | <ComponentName Value="frmAbout"/> 184 | <HasResources Value="True"/> 185 | <ResourceBaseClass Value="Form"/> 186 | <UnitName Value="About"/> 187 | </Unit8> 188 | </Units> 189 | </ProjectOptions> 190 | <CompilerOptions> 191 | <Version Value="11"/> 192 | <PathDelim Value="\"/> 193 | <Target> 194 | <Filename Value="gditools"/> 195 | </Target> 196 | <SearchPaths> 197 | <IncludeFiles Value="$(ProjOutDir)"/> 198 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 199 | </SearchPaths> 200 | <Linking> 201 | <Options> 202 | <Win32> 203 | <GraphicApplication Value="True"/> 204 | </Win32> 205 | </Options> 206 | </Linking> 207 | <Other> 208 | <CompilerMessages> 209 | <MsgFileName Value=""/> 210 | </CompilerMessages> 211 | <CustomOptions Value="-dDEBUG"/> 212 | <CompilerPath Value="$(CompPath)"/> 213 | </Other> 214 | </CompilerOptions> 215 | <Debugging> 216 | <Exceptions Count="3"> 217 | <Item1> 218 | <Name Value="EAbort"/> 219 | </Item1> 220 | <Item2> 221 | <Name Value="ECodetoolError"/> 222 | </Item2> 223 | <Item3> 224 | <Name Value="EFOpenError"/> 225 | </Item3> 226 | </Exceptions> 227 | </Debugging> 228 | </CONFIG> 229 | -------------------------------------------------------------------------------- /iso9660.py: -------------------------------------------------------------------------------- 1 | import urllib 2 | import struct 3 | 4 | try: 5 | from cStringIO import StringIO 6 | except ImportError: 7 | from StringIO import StringIO 8 | 9 | class ISO9660IOError(IOError): 10 | def __init__(self, path): 11 | self.path = path 12 | 13 | def __str__(self): 14 | return "Path not found: %s" % self.path 15 | 16 | class ISO9660(object): 17 | def __init__(self, url): 18 | self._buff = None #input buffer 19 | self._root = None #root node 20 | self._pvd = {} #primary volume descriptor 21 | self._paths = [] #path table 22 | 23 | self._url = url 24 | self._get_sector = self._get_sector_url if url.startswith('http') else self._get_sector_file 25 | 26 | ### Volume Descriptors 27 | sector = 0x10 28 | while True: 29 | self._get_sector(sector, 2048) 30 | sector += 1 31 | ty = self._unpack('B') 32 | 33 | if ty == 1: 34 | self._unpack_pvd() 35 | elif ty == 255: 36 | break 37 | else: 38 | continue 39 | 40 | ### Path table 41 | l0 = self._pvd['path_table_size'] 42 | self._get_sector(self._pvd['path_table_l_loc'], l0) 43 | 44 | while l0 > 0: 45 | p = {} 46 | l1 = self._unpack('B') 47 | l2 = self._unpack('B') 48 | p['ex_loc'] = self._unpack('<I') 49 | p['parent'] = self._unpack('<H') 50 | p['name'] = self._unpack_string(l1) 51 | if p['name'] == '\x00': 52 | p['name'] = '' 53 | 54 | if l1%2 == 1: 55 | self._unpack('B') 56 | 57 | self._paths.append(p) 58 | 59 | l0 -= 8 + l1 + (l1 % 2) 60 | 61 | assert l0 == 0 62 | 63 | ## 64 | ## Generator listing available files/folders 65 | ## 66 | 67 | def tree(self, get_files = True): 68 | if get_files: 69 | gen = self._tree_node(self._root) 70 | else: 71 | gen = self._tree_path('', 1) 72 | 73 | yield '/' 74 | for i in gen: 75 | yield i 76 | 77 | def _tree_path(self, name, index): 78 | spacer = lambda s: "%s/%s" % (name, s) 79 | for i, c in enumerate(self._paths): 80 | if c['parent'] == index and i != 0: 81 | yield spacer(c['name']) 82 | for d in self._tree_path(spacer(c['name']), i+1): 83 | yield d 84 | 85 | def _tree_node(self, node): 86 | spacer = lambda s: "%s/%s" % (node['name'], s) 87 | for c in list(self._unpack_dir_children(node)): 88 | yield spacer(c['name']) 89 | if c['flags'] & 2: 90 | for d in self._tree_node(c): 91 | yield spacer(d) 92 | 93 | ## 94 | ## Retrieve file contents as a string 95 | ## 96 | 97 | def get_file(self, path): 98 | path = path.upper().strip('/').split('/') 99 | path, filename = path[:-1], path[-1] 100 | 101 | if len(path)==0: 102 | parent_dir = self._root 103 | else: 104 | try: 105 | parent_dir = self._dir_record_by_table(path) 106 | except ISO9660IOError: 107 | parent_dir = self._dir_record_by_root(path) 108 | 109 | f = self._search_dir_children(parent_dir, filename) 110 | 111 | self._get_sector(f['ex_loc'], f['ex_len']) 112 | return self._unpack_raw(f['ex_len']) 113 | 114 | ## 115 | ## Methods for retrieving partial contents 116 | ## 117 | 118 | def _get_sector_url(self, sector, length): 119 | start = sector * 2048 120 | if self._buff: 121 | self._buff.close() 122 | opener = urllib.FancyURLopener() 123 | opener.http_error_206 = lambda *a, **k: None 124 | opener.addheader("Range", "bytes=%d-%d" % (start, start+length-1)) 125 | self._buff = opener.open(self._url) 126 | 127 | def _get_sector_file(self, sector, length): 128 | with open(self._url, 'rb') as f: 129 | f.seek(sector*2048) 130 | self._buff = StringIO(f.read(length)) 131 | 132 | ## 133 | ## Return the record for final directory in a path 134 | ## 135 | 136 | def _dir_record_by_table(self, path): 137 | for e in self._paths[::-1]: 138 | search = list(path) 139 | f = e 140 | while f['name'] == search[-1]: 141 | search.pop() 142 | f = self._paths[f['parent']-1] 143 | if f['parent'] == 1: 144 | e['ex_len'] = 2048 #TODO 145 | return e 146 | 147 | raise ISO9660IOError(path) 148 | 149 | def _dir_record_by_root(self, path): 150 | current = self._root 151 | remaining = list(path) 152 | 153 | while remaining: 154 | current = self._search_dir_children(current, remaining[0]) 155 | 156 | remaining.pop(0) 157 | 158 | return current 159 | 160 | ## 161 | ## Unpack the Primary Volume Descriptor 162 | ## 163 | 164 | def _unpack_pvd(self): 165 | self._pvd['type_code'] = self._unpack_string(5) 166 | self._pvd['standard_identifier'] = self._unpack('B') 167 | self._unpack_raw(1) #discard 1 byte 168 | self._pvd['system_identifier'] = self._unpack_string(32) 169 | self._pvd['volume_identifier'] = self._unpack_string(32) 170 | self._unpack_raw(8) #discard 8 bytes 171 | self._pvd['volume_space_size'] = self._unpack_both('i') 172 | self._unpack_raw(32) #discard 32 bytes 173 | self._pvd['volume_set_size'] = self._unpack_both('h') 174 | self._pvd['volume_seq_num'] = self._unpack_both('h') 175 | self._pvd['logical_block_size'] = self._unpack_both('h') 176 | self._pvd['path_table_size'] = self._unpack_both('i') 177 | self._pvd['path_table_l_loc'] = self._unpack('<i') 178 | self._pvd['path_table_opt_l_loc'] = self._unpack('<i') 179 | self._pvd['path_table_m_loc'] = self._unpack('>i') 180 | self._pvd['path_table_opt_m_loc'] = self._unpack('>i') 181 | _, self._root = self._unpack_record() #root directory record 182 | self._pvd['volume_set_identifer'] = self._unpack_string(128) 183 | self._pvd['publisher_identifier'] = self._unpack_string(128) 184 | self._pvd['data_preparer_identifier'] = self._unpack_string(128) 185 | self._pvd['application_identifier'] = self._unpack_string(128) 186 | self._pvd['copyright_file_identifier'] = self._unpack_string(38) 187 | self._pvd['abstract_file_identifier'] = self._unpack_string(36) 188 | self._pvd['bibliographic_file_identifier'] = self._unpack_string(37) 189 | self._pvd['volume_datetime_created'] = self._unpack_vd_datetime() 190 | self._pvd['volume_datetime_modified'] = self._unpack_vd_datetime() 191 | self._pvd['volume_datetime_expires'] = self._unpack_vd_datetime() 192 | self._pvd['volume_datetime_effective'] = self._unpack_vd_datetime() 193 | self._pvd['file_structure_version'] = self._unpack('B') 194 | 195 | ## 196 | ## Unpack a directory record (a listing of a file or folder) 197 | ## 198 | 199 | def _unpack_record(self, read=0): 200 | l0 = self._unpack('B') 201 | 202 | if l0 == 0: 203 | return read+1, None 204 | 205 | l1 = self._unpack('B') 206 | 207 | d = dict() 208 | d['ex_loc'] = self._unpack_both('I') 209 | d['ex_len'] = self._unpack_both('I') 210 | d['datetime'] = self._unpack_dir_datetime() 211 | d['flags'] = self._unpack('B') 212 | d['interleave_unit_size'] = self._unpack('B') 213 | d['interleave_gap_size'] = self._unpack('B') 214 | d['volume_sequence'] = self._unpack_both('h') 215 | 216 | l2 = self._unpack('B') 217 | d['name'] = self._unpack_string(l2).split(';')[0] 218 | if d['name'] == '\x00': 219 | d['name'] = '' 220 | 221 | if l2 % 2 == 0: 222 | self._unpack('B') 223 | 224 | t = 34 + l2 - (l2 % 2) 225 | 226 | e = l0-t 227 | if e>0: 228 | extra = self._unpack_raw(e) 229 | 230 | return read+l0, d 231 | 232 | #Assuming d is a directory record, this generator yields its children 233 | def _unpack_dir_children(self, d): 234 | sector = d['ex_loc'] 235 | read = 0 236 | self._get_sector(sector, 2048) 237 | 238 | read, r_self = self._unpack_record(read) 239 | read, r_parent = self._unpack_record(read) 240 | 241 | while read < r_self['ex_len']: #Iterate over files in the directory 242 | if read % 2048 == 0: 243 | sector += 1 244 | self._get_sector(sector, 2048) 245 | read, data = self._unpack_record(read) 246 | 247 | if data == None: #end of directory listing 248 | to_read = 2048 - (read % 2048) 249 | self._unpack_raw(to_read) 250 | read += to_read 251 | else: 252 | yield data 253 | 254 | #Search for one child amongst the children 255 | def _search_dir_children(self, d, term): 256 | for e in self._unpack_dir_children(d): 257 | if e['name'] == term: 258 | return e 259 | 260 | raise ISO9660IOError(term) 261 | ## 262 | ## Datatypes 263 | ## 264 | 265 | def _unpack_raw(self, l): 266 | return self._buff.read(l) 267 | 268 | #both-endian 269 | def _unpack_both(self, st): 270 | a = self._unpack('<'+st) 271 | b = self._unpack('>'+st) 272 | assert a == b 273 | return a 274 | 275 | def _unpack_string(self, l): 276 | return self._buff.read(l).rstrip(' ') 277 | 278 | def _unpack(self, st): 279 | if st[0] not in ('<','>'): 280 | st = '<' + st 281 | d = struct.unpack(st, self._buff.read(struct.calcsize(st))) 282 | if len(st) == 2: 283 | return d[0] 284 | else: 285 | return d 286 | 287 | def _unpack_vd_datetime(self): 288 | return self._unpack_raw(17) #TODO 289 | 290 | def _unpack_dir_datetime(self): 291 | return self._unpack_raw(7) #TODO 292 | 293 | 294 | if __name__ == '__main__': 295 | import sys 296 | if len(sys.argv) < 2: 297 | print "usage: python iso9660.py isourl [path]" 298 | else: 299 | iso_path = sys.argv[1] 300 | ret_path = sys.argv[2] if len(sys.argv) > 2 else None 301 | cd = ISO9660(iso_path) 302 | if ret_path: 303 | sys.stdout.write(cd.get_file(ret_path)) 304 | else: 305 | for path in cd.tree(): 306 | print path -------------------------------------------------------------------------------- /gui/main.pas: -------------------------------------------------------------------------------- 1 | { 2 | gditools.py GUI are licensed under the GNU General Public License (version 3), 3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt. 4 | 5 | SiZiOUS 2015 / www.sizious.com 6 | } 7 | unit Main; 8 | 9 | {$mode objfpc}{$H+} 10 | 11 | interface 12 | 13 | uses 14 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, 15 | ComCtrls, Menus, ExtCtrls, Engine, Types, LCLIntf; 16 | 17 | type 18 | { TfrmMain } 19 | 20 | TfrmMain = class(TForm) 21 | btnOpen: TButton; 22 | edtFileName: TEdit; 23 | gbxDiscImage: TGroupBox; 24 | gbxContents: TGroupBox; 25 | ilDirectories: TImageList; 26 | ilFiles: TImageList; 27 | lvwFiles: TListView; 28 | miSep5: TMenuItem; 29 | miOpenItem: TMenuItem; 30 | miGenerateSortFile: TMenuItem; 31 | miExtractBootstrap: TMenuItem; 32 | miSep4: TMenuItem; 33 | miExtract2: TMenuItem; 34 | miSettings: TMenuItem; 35 | miSep3: TMenuItem; 36 | miExtractAll: TMenuItem; 37 | miTools: TMenuItem; 38 | miExtract: TMenuItem; 39 | miFile: TMenuItem; 40 | miSep2: TMenuItem; 41 | miHelp: TMenuItem; 42 | miOpenFile: TMenuItem; 43 | miCloseFile: TMenuItem; 44 | miSep1: TMenuItem; 45 | miQuit: TMenuItem; 46 | miProjectPage: TMenuItem; 47 | miAbout: TMenuItem; 48 | miGetAssistance: TMenuItem; 49 | mmMain: TMainMenu; 50 | opdGDI: TOpenDialog; 51 | pmFiles: TPopupMenu; 52 | sbrMain: TStatusBar; 53 | svdExtract: TSaveDialog; 54 | Splitter1: TSplitter; 55 | svdExtractBootstrap: TSaveDialog; 56 | tmrResetStatusBar: TTimer; 57 | tvwDirectories: TTreeView; 58 | procedure btnOpenClick(Sender: TObject); 59 | procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); 60 | procedure FormCreate(Sender: TObject); 61 | procedure FormShow(Sender: TObject); 62 | procedure lvwFilesContextPopup(Sender: TObject; MousePos: TPoint; 63 | var Handled: Boolean); 64 | procedure lvwFilesDblClick(Sender: TObject); 65 | procedure lvwFilesSelectItem(Sender: TObject; Item: TListItem; 66 | Selected: Boolean); 67 | procedure miAboutClick(Sender: TObject); 68 | procedure miCloseFileClick(Sender: TObject); 69 | procedure miGetAssistanceClick(Sender: TObject); 70 | procedure miProjectPageClick(Sender: TObject); 71 | procedure miQuitClick(Sender: TObject); 72 | procedure miExtractAllClick(Sender: TObject); 73 | procedure miExtractBootstrapClick(Sender: TObject); 74 | procedure miExtractClick(Sender: TObject); 75 | procedure miGenerateSortFileClick(Sender: TObject); 76 | procedure miOpenItemClick(Sender: TObject); 77 | procedure miSettingsClick(Sender: TObject); 78 | procedure tmrResetStatusBarTimer(Sender: TObject); 79 | procedure tvwDirectoriesClick(Sender: TObject); 80 | private 81 | { private declarations } 82 | fSelectedFile: string; 83 | procedure ChangeButtonsState(State: Boolean); 84 | function GetSelectedNodePath: string; 85 | function GetStatusText: string; 86 | procedure SetStatusText(AValue: string); 87 | procedure ResetStatusBar(Success: Boolean); 88 | public 89 | { public declarations } 90 | property SelectedFile: string read fSelectedFile; 91 | property StatusText: string read GetStatusText write SetStatusText; 92 | end; 93 | 94 | var 95 | frmMain: TfrmMain; 96 | GDReader: TGDReader; 97 | 98 | implementation 99 | 100 | {$R *.lfm} 101 | 102 | uses 103 | {$IFDEF Darwin} 104 | LCLType, 105 | {$ENDIF} 106 | Utils, 107 | Extract, 108 | SortFile, 109 | Settings, 110 | About; 111 | 112 | { TfrmMain } 113 | 114 | procedure TfrmMain.btnOpenClick(Sender: TObject); 115 | var 116 | Success: Boolean; 117 | 118 | begin 119 | with opdGDI do 120 | if Execute then 121 | begin 122 | if FileExists(FileName) then 123 | begin 124 | StatusText := 'Opening the specified file... Please wait.'; 125 | 126 | // Load the file then populate the TreeView 127 | GDReader.LoadFromFile(FileName); 128 | GDReader.FillTreeView(tvwDirectories); 129 | 130 | // Check if the file was successfully opened or not 131 | Success := tvwDirectories.Items.Count > 0; 132 | 133 | // Reset the status bar 134 | ResetStatusBar(Success); 135 | 136 | // If we can open the root folder, do it 137 | // This means that the opened file is valid. 138 | if Success then 139 | begin 140 | edtFileName.Text := FileName; 141 | ChangeButtonsState(True); 142 | tvwDirectories.Items[0].Selected := True; 143 | tvwDirectoriesClick(Self); 144 | end 145 | else 146 | begin 147 | MessageDlg('The specified file seems to be invalid.', mtWarning, [mbOK], 0); 148 | miCloseFileClick(Self); 149 | end; 150 | end 151 | else 152 | MessageDlg('The specified GDI image doesn''t exist.', mtWarning, [mbOK], 0); 153 | end; 154 | end; 155 | 156 | procedure TfrmMain.FormClose(Sender: TObject; var CloseAction: TCloseAction); 157 | begin 158 | SaveConfig; 159 | end; 160 | 161 | procedure TfrmMain.FormCreate(Sender: TObject); 162 | begin 163 | Caption := Application.Title; 164 | ChangeButtonsState(False); 165 | end; 166 | 167 | procedure TfrmMain.FormShow(Sender: TObject); 168 | begin 169 | LoadConfig; 170 | end; 171 | 172 | procedure TfrmMain.lvwFilesContextPopup(Sender: TObject; MousePos: TPoint; 173 | var Handled: Boolean); 174 | begin 175 | // Show the context menu only on items 176 | if not Assigned(lvwFiles.Selected) then 177 | Handled := True; 178 | miExtract.Enabled := not Handled; 179 | miExtract2.Enabled := not Handled; 180 | end; 181 | 182 | procedure TfrmMain.lvwFilesDblClick(Sender: TObject); 183 | var 184 | Node: TTreeNode; 185 | 186 | begin 187 | if Assigned(lvwFiles.Selected) then 188 | if lvwFiles.Selected.ImageIndex = 1 then // it's a directory 189 | begin 190 | // get the directory on the left tree view 191 | Node := tvwDirectories.Items.FindNodeWithText(lvwFiles.Selected.Caption); 192 | if Assigned(Node) then 193 | begin 194 | // the current directory was found in the left tree view, open the contents 195 | Node.Selected := True; 196 | tvwDirectoriesClick(Self); 197 | end; 198 | end 199 | else 200 | MessageDlg('This action is only available on folders.', mtWarning, [mbOK], 0); 201 | end; 202 | 203 | procedure TfrmMain.lvwFilesSelectItem(Sender: TObject; Item: TListItem; 204 | Selected: Boolean); 205 | begin 206 | if Selected then 207 | fSelectedFile := GetSelectedNodePath + Item.Caption; 208 | miExtract.Enabled := Selected; 209 | miExtract2.Enabled := Selected; 210 | end; 211 | 212 | procedure TfrmMain.miAboutClick(Sender: TObject); 213 | begin 214 | frmAbout.ShowModal; 215 | end; 216 | 217 | procedure TfrmMain.miCloseFileClick(Sender: TObject); 218 | begin 219 | edtFileName.Clear; 220 | lvwFiles.Clear; 221 | tvwDirectories.Items.Clear; 222 | fSelectedFile := ''; 223 | ChangeButtonsState(False); 224 | end; 225 | 226 | procedure TfrmMain.miGetAssistanceClick(Sender: TObject); 227 | begin 228 | OpenURL('http://www.assemblergames.com/forums/showthread.php?55022-gditools-py-a-Python-program-library-to-handle-GDI-files!'); 229 | end; 230 | 231 | procedure TfrmMain.miProjectPageClick(Sender: TObject); 232 | begin 233 | OpenURL('https://sourceforge.net/projects/dcisotools/'); 234 | end; 235 | 236 | procedure TfrmMain.miQuitClick(Sender: TObject); 237 | begin 238 | Close; 239 | end; 240 | 241 | procedure TfrmMain.miExtractAllClick(Sender: TObject); 242 | var 243 | Success: Boolean; 244 | 245 | begin 246 | Success := True; 247 | with frmExtractAll do 248 | if ShowModal = mrOK then 249 | begin 250 | StatusText := 'Please wait while extracting the whole dump...'; 251 | GDReader.ExtractAll(OutputDirectory, DataDirectory); 252 | Success := Success and DirectoryExists(OutputDirectory); 253 | if ExtractBootstrap then 254 | Success := Success and GDReader.ExtractBootstrap(OutputDirectory + SFILE_BOOTSTRAP); 255 | if GenerateSortFile then 256 | Success := Success and GDReader.GenerateSortFile(OutputDirectory + SFILE_SORT, DataDirectory); 257 | ResetStatusBar(Success); 258 | end; 259 | end; 260 | 261 | procedure TfrmMain.miExtractBootstrapClick(Sender: TObject); 262 | var 263 | Success: Boolean; 264 | 265 | begin 266 | with svdExtractBootstrap do 267 | if Execute then 268 | begin 269 | StatusText := 'Extracting Boostrap...'; 270 | Success := GDReader.ExtractBootstrap(FileName); 271 | ResetStatusBar(Success); 272 | end; 273 | end; 274 | 275 | procedure TfrmMain.miExtractClick(Sender: TObject); 276 | var 277 | Success: Boolean; 278 | 279 | begin 280 | if Assigned(lvwFiles.Selected) then 281 | begin 282 | // An item is selected 283 | 284 | // If the item is a directory, the feature can't be used (for now) 285 | if lvwFiles.Selected.ImageIndex = 1 then 286 | MessageDlg('This feature was only designed to handle files.', mtWarning, [mbOK], 0) 287 | else 288 | begin 289 | // Extract the file 290 | with svdExtract do 291 | begin 292 | FileName := lvwFiles.Selected.Caption; 293 | if Execute then 294 | begin 295 | StatusText := Format('Extracting ''%s''...', [SelectedFile]); 296 | Success := GDReader.Extract(SelectedFile, FileName); 297 | ResetStatusBar(Success); 298 | end; 299 | end; 300 | end; 301 | end 302 | else 303 | begin 304 | MessageDlg('Please select a file in order to use this feature.', mtWarning, [mbOK], 0); 305 | end; 306 | end; 307 | 308 | procedure TfrmMain.miGenerateSortFileClick(Sender: TObject); 309 | var 310 | Success: Boolean; 311 | 312 | begin 313 | with frmSortFile do 314 | if ShowModal = mrOK then 315 | begin 316 | StatusText := 'Generating Sort File...'; 317 | Success := GDReader.GenerateSortFile(OutputFileName, DataDirectory); 318 | ResetStatusBar(Success); 319 | end; 320 | end; 321 | 322 | procedure TfrmMain.miOpenItemClick(Sender: TObject); 323 | begin 324 | if Assigned(lvwFiles.Selected) then 325 | lvwFilesDblClick(Self) 326 | end; 327 | 328 | procedure TfrmMain.miSettingsClick(Sender: TObject); 329 | begin 330 | with frmSettings do 331 | begin 332 | PythonExecutable := GDReader.PythonExecutable; 333 | if ShowModal = mrOK then 334 | GDReader.PythonExecutable := PythonExecutable; 335 | end; 336 | end; 337 | 338 | procedure TfrmMain.tmrResetStatusBarTimer(Sender: TObject); 339 | begin 340 | StatusText := ''; 341 | tmrResetStatusBar.Enabled := False; 342 | end; 343 | 344 | procedure TfrmMain.tvwDirectoriesClick(Sender: TObject); 345 | begin 346 | GDReader.FillListView(lvwFiles, GetSelectedNodePath); 347 | end; 348 | 349 | procedure TfrmMain.ChangeButtonsState(State: Boolean); 350 | begin 351 | miCloseFile.Enabled := State; 352 | miExtractAll.Enabled := State; 353 | miExtractBootstrap.Enabled := State; 354 | miGenerateSortFile.Enabled := State; 355 | if not State then 356 | begin 357 | miExtract.Enabled := False; 358 | miExtract2.Enabled := False; 359 | end; 360 | end; 361 | 362 | function TfrmMain.GetSelectedNodePath: string; 363 | begin 364 | Result := GetNodePath(tvwDirectories.Selected); 365 | end; 366 | 367 | function TfrmMain.GetStatusText: string; 368 | begin 369 | Result := sbrMain.SimpleText; 370 | end; 371 | 372 | procedure TfrmMain.SetStatusText(AValue: string); 373 | begin 374 | sbrMain.SimpleText := AValue; 375 | end; 376 | 377 | procedure TfrmMain.ResetStatusBar(Success: Boolean); 378 | begin 379 | if Success then 380 | StatusText := 'Done!' 381 | else 382 | StatusText := 'Failed!'; 383 | tmrResetStatusBar.Enabled := True; 384 | end; 385 | 386 | initialization 387 | GDReader := TGDReader.Create; 388 | 389 | finalization 390 | GDReader.Free; 391 | 392 | end. 393 | 394 | -------------------------------------------------------------------------------- /gui/main.lfm: -------------------------------------------------------------------------------- 1 | object frmMain: TfrmMain 2 | Left = 259 3 | Height = 522 4 | Top = 137 5 | Width = 784 6 | Caption = '<Dynamic Title> (Main Form)' 7 | ClientHeight = 522 8 | ClientWidth = 784 9 | Menu = mmMain 10 | OnClose = FormClose 11 | OnCreate = FormCreate 12 | OnShow = FormShow 13 | Position = poScreenCenter 14 | LCLVersion = '1.2.6.0' 15 | object gbxDiscImage: TGroupBox 16 | Left = 4 17 | Height = 49 18 | Top = 4 19 | Width = 776 20 | Align = alTop 21 | BorderSpacing.Around = 4 22 | Caption = ' Disc Image: ' 23 | ClientHeight = 27 24 | ClientWidth = 768 25 | TabOrder = 0 26 | object btnOpen: TButton 27 | Left = 680 28 | Height = 25 29 | Top = 0 30 | Width = 83 31 | Anchors = [akTop, akRight] 32 | Caption = 'Open...' 33 | OnClick = btnOpenClick 34 | TabOrder = 0 35 | end 36 | object edtFileName: TEdit 37 | Left = 8 38 | Height = 22 39 | Top = 0 40 | Width = 668 41 | Anchors = [akTop, akLeft, akRight] 42 | Color = clBtnFace 43 | ReadOnly = True 44 | TabOrder = 1 45 | end 46 | end 47 | object gbxContents: TGroupBox 48 | Left = 4 49 | Height = 446 50 | Top = 57 51 | Width = 776 52 | Align = alClient 53 | BorderSpacing.Around = 4 54 | Caption = ' Contents: ' 55 | ClientHeight = 424 56 | ClientWidth = 768 57 | TabOrder = 1 58 | object tvwDirectories: TTreeView 59 | Left = 4 60 | Height = 416 61 | Top = 4 62 | Width = 264 63 | Align = alLeft 64 | BorderSpacing.Around = 4 65 | DefaultItemHeight = 18 66 | Images = ilDirectories 67 | ReadOnly = True 68 | TabOrder = 0 69 | OnClick = tvwDirectoriesClick 70 | Options = [tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw] 71 | end 72 | object lvwFiles: TListView 73 | Left = 281 74 | Height = 416 75 | Top = 4 76 | Width = 483 77 | Align = alClient 78 | BorderSpacing.Around = 4 79 | Columns = < 80 | item 81 | AutoSize = True 82 | Caption = 'Filename' 83 | Width = 481 84 | end> 85 | ColumnClick = False 86 | PopupMenu = pmFiles 87 | ReadOnly = True 88 | RowSelect = True 89 | SmallImages = ilFiles 90 | TabOrder = 1 91 | ViewStyle = vsReport 92 | OnContextPopup = lvwFilesContextPopup 93 | OnDblClick = lvwFilesDblClick 94 | OnSelectItem = lvwFilesSelectItem 95 | end 96 | object Splitter1: TSplitter 97 | Left = 272 98 | Height = 424 99 | Top = 0 100 | Width = 5 101 | end 102 | end 103 | object sbrMain: TStatusBar 104 | Left = 0 105 | Height = 15 106 | Top = 507 107 | Width = 784 108 | AutoHint = True 109 | Panels = <> 110 | end 111 | object ilDirectories: TImageList 112 | left = 176 113 | top = 96 114 | Bitmap = { 115 | 4C69020000001000000010000000000000000000000000000000000000000000 116 | 000000000000625D5C02746F6D1B75716F1D6A68670400000000000000000000 117 | 000000000000000000000000000000000000000000000000000000000000988C 118 | 882DC5BAB9A4D5CBCBF0E1D8D8FFE5DEDEFFDEDEDEF6D5DADBB3B9BDBC3E0000 119 | 0000000000000000000000000000000000000000000000000000A19B9571D6C2 120 | BCFADCD1D0FFE1D8D8FFE5DEDEFFE9E4E4FFE7EAEBFFEAF1F2FFEAF4F7FEBECE 121 | D09051575702000000000000000000000000000000007D8D8D6CBFD1CFFED6CD 122 | C5FFE1D4D0FFE5DEDEFFEAE4E4FFEDEAEAFFEBF0F1FFEDF6F8FFE9FAFDFFE3F9 123 | FCFFA8BABC9100000000000000000000000048444A22B9BACEF7BBD3D9FFC9DB 124 | DAFFE0D7D0FFEAE2E1FFEFEAEAFFF0F0F0FFEEF7F8FFEBFBFCFFE2FAFCFFDAF6 125 | F9FFD0F2F6FE6C7A7B4000000000000000008B838A90D1C8D7FFCECADEFFC5D6 126 | E3FFD1E4E4FFE3DED8FBECEAEAD2ECEEEECEE5F3F3F7E1FAFCFFD5F7FAFFCFF6 127 | F9FFD3F6F9FF95B8BAB50000000013121201B5ACADD8DED5D9FFDFD8E0FFDCD9 128 | E7FFCFD8E8FDEFF5F59FFBFBFB90FBFBFB91F3F9F992C8F1F3F8BFF8FAFFAAF7 129 | F9FF8FF4F8FF83E5E8F6162020070F0E0E04D7CECEF8C3BEBEFFB3B0B0FFC9C5 130 | C5FFCDCCCFE8FBFBFB8E5A5A5A5537363649FBFBFB91ACF1F2D282F9FBFF7FF9 131 | FCFF7DFAFCFF7BFAFCFF1927262209080806D8D1D1F6CAC5C5FFB5B2B2FFB7B5 132 | B5FFC4C4C4EEFBFBFB8CADABAC4FA2A1A141FBFBFB907ECDE4D849C7E5FF48C8 133 | E5FF47C8E6FF47C7E6FF121B1C2206060602B7B2B1D5D8D3D3FFE7E5E5FFCBCB 134 | CEFF8B99DCFEAFCCEAB3FBFBFB8CFBFBFB8EBBDBECA41391CAFD1589CBFF1684 135 | C8FF1386C7FF147EB5F306090B09000000007675748CF5F2F2FFE2E1F4FF6F8D 136 | E9FF3895D8FF3699D0FF49A1D1E94CA2D1E61B88CAFE1990D0FF179BD3FF1B96 137 | D1FF228BCDFF1C567BB0000000000000000014141421B1B2E1F3598CE6FF4AAB 138 | DEFF50AFDEFF48ACDDFF30A1D9FF30A1D9FF31A0D9FF349DD9FF32A1DAFF2DAB 139 | DCFF2EA6D4FB0F1D243C000000000000000000000000253B5B6E5FBBE2FD66C0 140 | E7FF6CC3E8FF56BAE5FF4BB5E3FF4BB5E3FF4BB5E3FF4CB3E3FF4DB0E3FF4BB3 141 | E2FE204C5B870103030100000000000000000000000001020202243E476E77C3 142 | DDF582D5F1FF66CCEDFF65CBEDFF65CBEDFF65CBEDFF65CAEDFF62BCE1F92949 143 | 5785010202050000000000000000000000000000000000000000000000000C11 144 | 122D446A749D62ABBEE177D0E6F978D2E8FA66B1C4E640707CA90F16183A0001 145 | 0102000000000000000000000000000000000000000000000000000000000000 146 | 0000000000010000000A000000190000001B0000000D00000001000000000000 147 | 0000000000000000000000000000000000000000000000000000000000000000 148 | 0000000000000000000000000000000000000000000000000000000000000000 149 | 000000000000000000000000000000000000EDBF9AB2EDC5A4FFEDC5A4FFEDC4 150 | A1EBDEAB82330000000000000000000000000000000000000000000000000000 151 | 000000000000000000000000000000000000EABA93BFEAC09DFFEAC09DFFEAC0 152 | 9DFFEABE9AFFEABC97FFEABC97FFEABC97FFEABC97FFEABC97FFEABC97FFEABC 153 | 97FFEABC97FFEAB890B800000000E3B18874E3AF84DDE3B186FFE3B186FFE3B1 154 | 86FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B1 155 | 86FFE3B186FFE3AF84DDE4B28A74E29459E2E3985EF8E3985FFFE3985FFFE398 156 | 5FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE398 157 | 5FFFE3985FFFE3985EF8E29459E2EC9E65D6ECA068F8ECA068FFECA068FFECA0 158 | 68FFECA068FFECA068FFECA068FFECA068FFECA068FFECA068FFECA068FFECA0 159 | 68FFECA068FFECA068F8EC9E65D6F4A871CAF3A872F8F3A872FFF3A872FFF3A8 160 | 72FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A8 161 | 72FFF3A872FFF3A872F8F4A871CAF6B17DBEF5B07CF8F4AF7BFFF4AF7BFFF4AF 162 | 7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF 163 | 7BFFF4AF7BFFF5B07CF8F6B17DBEF8BA89B2F6B786F9F5B685FFF5B685FFF5B6 164 | 85FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B6 165 | 85FFF5B685FFF6B786F9F8BA89B2FAC396A6F7BE90F9F6BD8EFFF6BD8EFFF6BD 166 | 8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD 167 | 8EFFF6BD8EFFF7BE90F9FAC396A6FCCCA29AF8C69AFAF7C598FFF7C598FFF7C5 168 | 98FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C5 169 | 98FFF7C598FFF8C69AFAFCCCA29AFDD5AE8EFACDA2FBF9CCA1FFF9CCA1FFF9CC 170 | A1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CC 171 | A1FFF9CCA1FFFACDA2FBFDD5AE8EC8A68381F4C393FEF3C392FFF3C392FFF3C3 172 | 92FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C3 173 | 92FFF3C392FFF4C393FECBA8858102020118000000490000004C0000004C0000 174 | 004C0000004C0000004C0000004C0000004C0000004C0000004C0000004C0000 175 | 004C0000004C0000004903020218000000000000000000000000000000000000 176 | 0000000000000000000000000000000000000000000000000000000000000000 177 | 0000000000000000000000000000000000000000000000000000000000000000 178 | 0000000000000000000000000000000000000000000000000000000000000000 179 | 0000000000000000000000000000 180 | } 181 | end 182 | object ilFiles: TImageList 183 | left = 408 184 | top = 328 185 | Bitmap = { 186 | 4C690200000010000000100000000000000000000000A4A4A459ABABAB69A9A9 187 | A969A6A6A669A3A3A369A1A1A1699D9D9D687D7D7D2200000000000000000000 188 | 00000000000000000000000000000000000000000000D8D8D8D9E8E8E8FFE6E6 189 | E6FFE2E2E2FFDDDDDDFFD9D9D9FFD4D4D4FFCACACAF48F8F8F57000000000000 190 | 00000000000000000000000000000000000000000000C8C8C8DAEAEAEAFFE9E9 191 | E9FFE7E7E7FFE3E3E3FFDFDFDFFFDADADAFFD6D6D6FFD1D1D1FD808080700000 192 | 00000000000000000000000000000000000000000000C7C7C7DCEBEBEBFFEAEA 193 | EAFFE9E9E9FFE8E8E8FFE4E4E4FFE0E0E0FFDCDCDCFFE6E6E6FFD1D1D1FE7676 194 | 76720000000000000000000000000000000000000000C8C8C8DDEDEDEDFFECEC 195 | ECFFEBEBEBFFE9E9E9FFE8E8E8FFE6E6E6FFE1E1E1FFADADADFFA5A5A5FFA3A3 196 | A3FD6262625300000000000000000000000000000000C8C8C8DFEEEEEEFFEDED 197 | EDFFECECECFFEBEBEBFFEAEAEAFFE9E9E9FFE7E7E7FFCBCBCBFFC5C5C5FFC1C1 198 | C1FFA0A0A0D400000000000000000000000000000000C9C9C9E0F0F0F0FFEFEF 199 | EFFFEEEEEEFFECECECFFEBEBEBFFEAEAEAFFE9E9E9FFE7E7E7FFE4E4E4FFE0E0 200 | E0FFB6B6B6DF00000000000000000000000000000000C9C9C9E2F2F2F2FFF0F0 201 | F0FFEFEFEFFFEEEEEEFFEDEDEDFFECECECFFEAEAEAFFE9E9E9FFE8E8E8FFE5E5 202 | E5FFBABABAE000000000000000000000000000000000CACACAE2F3F3F3FFF2F2 203 | F2FFF1F1F1FFF0F0F0FFEEEEEEFFEDEDEDFFECECECFFEBEBEBFFEAEAEAFFE8E8 204 | E8FFBDBDBDE100000000000000000000000000000000CBCBCBE3F5F5F5FFF3F3 205 | F3FFF2F2F2FFF1F1F1FFF0F0F0FFEFEFEFFFEEEEEEFFECECECFFEBEBEBFFEAEA 206 | EAFFBFBFBFE200000000000000000000000000000000CCCCCCE4F6F6F6FFF5F5 207 | F5FFF4F4F4FFF3F3F3FFF1F1F1FFF0F0F0FFEFEFEFFFEEEEEEFFEDEDEDFFECEC 208 | ECFFBFBFBFE300000000000000000000000000000000CCCCCCE5F8F8F8FFF7F7 209 | F7FFF5F5F5FFF4F4F4FFF3F3F3FFF2F2F2FFF1F1F1FFEFEFEFFFEEEEEEFFEDED 210 | EDFFC0C0C0E400000000000000000000000000000000CDCDCDE6F9F9F9FFF8F8 211 | F8FFF7F7F7FFF6F6F6FFF5F5F5FFF3F3F3FFF2F2F2FFF1F1F1FFF0F0F0FFEFEF 212 | EFFFC1C1C1E400000000000000000000000000000000CECECEE7FBFBFBFFFAFA 213 | FAFFF8F8F8FFF7F7F7FFF6F6F6FFF5F5F5FFF4F4F4FFF3F3F3FFF1F1F1FFF0F0 214 | F0FFC2C2C2E500000000000000000000000000000000CFCFCFE7FCFCFCFFFBFB 215 | FBFFFAFAFAFFF9F9F9FFF8F8F8FFF6F6F6FFF5F5F5FFF4F4F4FFF3F3F3FFF2F2 216 | F2FFC3C3C3E6000000000000000000000000000000003C3C3C50484848574848 217 | 4857484848574848485747474757474747574747475747474757464646574646 218 | 4657393939500000000000000000000000000000000000000000000000000000 219 | 0000000000000000000000000000000000000000000000000000000000000000 220 | 000000000000000000000000000000000000EDBF9AB2EDC5A4FFEDC5A4FFEDC4 221 | A1EBDEAB82330000000000000000000000000000000000000000000000000000 222 | 000000000000000000000000000000000000EABA93BFEAC09DFFEAC09DFFEAC0 223 | 9DFFEABE9AFFEABC97FFEABC97FFEABC97FFEABC97FFEABC97FFEABC97FFEABC 224 | 97FFEABC97FFEAB890B800000000E3B18874E3AF84DDE3B186FFE3B186FFE3B1 225 | 86FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B186FFE3B1 226 | 86FFE3B186FFE3AF84DDE4B28A74E29459E2E3985EF8E3985FFFE3985FFFE398 227 | 5FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE3985FFFE398 228 | 5FFFE3985FFFE3985EF8E29459E2EC9E65D6ECA068F8ECA068FFECA068FFECA0 229 | 68FFECA068FFECA068FFECA068FFECA068FFECA068FFECA068FFECA068FFECA0 230 | 68FFECA068FFECA068F8EC9E65D6F4A871CAF3A872F8F3A872FFF3A872FFF3A8 231 | 72FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A872FFF3A8 232 | 72FFF3A872FFF3A872F8F4A871CAF6B17DBEF5B07CF8F4AF7BFFF4AF7BFFF4AF 233 | 7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF7BFFF4AF 234 | 7BFFF4AF7BFFF5B07CF8F6B17DBEF8BA89B2F6B786F9F5B685FFF5B685FFF5B6 235 | 85FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B685FFF5B6 236 | 85FFF5B685FFF6B786F9F8BA89B2FAC396A6F7BE90F9F6BD8EFFF6BD8EFFF6BD 237 | 8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD8EFFF6BD 238 | 8EFFF6BD8EFFF7BE90F9FAC396A6FCCCA29AF8C69AFAF7C598FFF7C598FFF7C5 239 | 98FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C598FFF7C5 240 | 98FFF7C598FFF8C69AFAFCCCA29AFDD5AE8EFACDA2FBF9CCA1FFF9CCA1FFF9CC 241 | A1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CCA1FFF9CC 242 | A1FFF9CCA1FFFACDA2FBFDD5AE8EC8A68381F4C393FEF3C392FFF3C392FFF3C3 243 | 92FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C392FFF3C3 244 | 92FFF3C392FFF4C393FECBA8858102020118000000490000004C0000004C0000 245 | 004C0000004C0000004C0000004C0000004C0000004C0000004C0000004C0000 246 | 004C0000004C0000004903020218000000000000000000000000000000000000 247 | 0000000000000000000000000000000000000000000000000000000000000000 248 | 0000000000000000000000000000000000000000000000000000000000000000 249 | 0000000000000000000000000000000000000000000000000000000000000000 250 | 0000000000000000000000000000 251 | } 252 | end 253 | object mmMain: TMainMenu 254 | left = 72 255 | top = 96 256 | object miFile: TMenuItem 257 | Caption = 'File' 258 | object miOpenFile: TMenuItem 259 | Caption = 'Open...' 260 | Hint = 'Load a GD-ROM Image file in the application.' 261 | ShortCut = 16463 262 | ShortCutKey2 = 4175 263 | OnClick = btnOpenClick 264 | end 265 | object miCloseFile: TMenuItem 266 | Caption = 'Close' 267 | Hint = 'Close the current GD-ROM Image file.' 268 | OnClick = miCloseFileClick 269 | end 270 | object miSep1: TMenuItem 271 | Caption = '-' 272 | end 273 | object miQuit: TMenuItem 274 | Caption = 'Quit' 275 | Hint = 'Return to your life.' 276 | ShortCut = 16465 277 | ShortCutKey2 = 4177 278 | OnClick = miQuitClick 279 | end 280 | end 281 | object miTools: TMenuItem 282 | Caption = 'Tools' 283 | object miExtractAll: TMenuItem 284 | Caption = 'Extract All...' 285 | Hint = 'Extract the whole data of the current GD-ROM image.' 286 | ShortCut = 16501 287 | ShortCutKey2 = 4213 288 | OnClick = miExtractAllClick 289 | end 290 | object miExtract2: TMenuItem 291 | Caption = 'Extract Selected...' 292 | Hint = 'Extract the selected file.' 293 | ShortCut = 117 294 | OnClick = miExtractClick 295 | end 296 | object miSep3: TMenuItem 297 | Caption = '-' 298 | end 299 | object miExtractBootstrap: TMenuItem 300 | Caption = 'Extract Bootstrap (IP.BIN)...' 301 | Hint = 'Extract the Bootstrap of the current loaded GD-ROM Image file.' 302 | ShortCut = 118 303 | OnClick = miExtractBootstrapClick 304 | end 305 | object miGenerateSortFile: TMenuItem 306 | Caption = 'Generate Sort File (sorttxt.txt)' 307 | Hint = 'Generate the Sort file needed for mkisofs.' 308 | ShortCut = 119 309 | OnClick = miGenerateSortFileClick 310 | end 311 | object miSep4: TMenuItem 312 | Caption = '-' 313 | end 314 | object miSettings: TMenuItem 315 | Caption = 'Settings...' 316 | Hint = 'Configure the application.' 317 | ShortCut = 113 318 | OnClick = miSettingsClick 319 | end 320 | end 321 | object miHelp: TMenuItem 322 | Caption = 'Help' 323 | object miGetAssistance: TMenuItem 324 | Caption = 'Get Assistance...' 325 | Hint = 'Open the official thread help.' 326 | ShortCut = 112 327 | OnClick = miGetAssistanceClick 328 | end 329 | object miProjectPage: TMenuItem 330 | Caption = 'Project Page...' 331 | Hint = 'Go to the project home page.' 332 | OnClick = miProjectPageClick 333 | end 334 | object miSep2: TMenuItem 335 | Caption = '-' 336 | end 337 | object miAbout: TMenuItem 338 | Caption = 'About...' 339 | Hint = 'This item is really useless.' 340 | ShortCut = 123 341 | OnClick = miAboutClick 342 | end 343 | end 344 | end 345 | object pmFiles: TPopupMenu 346 | left = 408 347 | top = 120 348 | object miOpenItem: TMenuItem 349 | Caption = 'Open' 350 | Default = True 351 | OnClick = miOpenItemClick 352 | end 353 | object miSep5: TMenuItem 354 | Caption = '-' 355 | end 356 | object miExtract: TMenuItem 357 | Caption = 'Extract...' 358 | OnClick = miExtractClick 359 | end 360 | end 361 | object svdExtract: TSaveDialog 362 | Title = 'Extract the selected file to...' 363 | Filter = 'All Files (*.*)|*.*' 364 | Options = [ofOverwritePrompt, ofPathMustExist, ofEnableSizing, ofViewDetail] 365 | left = 408 366 | top = 192 367 | end 368 | object tmrResetStatusBar: TTimer 369 | Enabled = False 370 | Interval = 3000 371 | OnTimer = tmrResetStatusBarTimer 372 | left = 96 373 | top = 392 374 | end 375 | object opdGDI: TOpenDialog 376 | Title = 'Please select the GD-ROM Image to open...' 377 | DefaultExt = '.gdi' 378 | Filter = 'GD-ROM Images Files (*.gdi)|*.gdi;*.GDI|All Files (*.*)|*.*' 379 | Options = [ofFileMustExist, ofEnableSizing, ofViewDetail] 380 | left = 672 381 | top = 120 382 | end 383 | object svdExtractBootstrap: TSaveDialog 384 | Title = 'Extract the Bootstrap file to...' 385 | DefaultExt = '.BIN' 386 | FileName = 'IP.BIN' 387 | Filter = 'Bootstrap Files (IP.BIN)|IP.BIN|Binary Files (*.BIN)|*.BIN|All Files (*.*)|*.*' 388 | Options = [ofOverwritePrompt, ofPathMustExist, ofEnableSizing, ofViewDetail] 389 | left = 408 390 | top = 256 391 | end 392 | end 393 | -------------------------------------------------------------------------------- /gui/engine.pas: -------------------------------------------------------------------------------- 1 | { 2 | gditools.py GUI are licensed under the GNU General Public License (version 3), 3 | a copy of which is provided in the licences folder: GNU_GPL_v3.txt. 4 | 5 | SiZiOUS 2015 / www.sizious.com 6 | } 7 | unit Engine; 8 | 9 | {$mode objfpc}{$H+} 10 | 11 | interface 12 | 13 | uses 14 | SysUtils, Classes, Contnrs, ComCtrls; 15 | 16 | const 17 | SFILE_BOOTSTRAP = 'IP.BIN'; 18 | SFILE_SORT = 'sorttxt.txt'; 19 | SDIR_DATA_VOLUME_LABEL = '__volume_label__'; 20 | 21 | type 22 | EGDReader = class(Exception); 23 | 24 | { TFileEntry } 25 | 26 | TFileEntry = class(TObject) 27 | private 28 | fDirectory: Boolean; 29 | fFileName: string; 30 | fFullPath: string; 31 | fSortHashStr: string; 32 | procedure Update; 33 | public 34 | constructor Create(AFileName, AFullPath: string); 35 | property FileName: string read fFileName; 36 | property Directory: Boolean read fDirectory; 37 | end; 38 | 39 | { TFilesList } 40 | 41 | TFilesList = class(TObject) 42 | private 43 | fList: TList; 44 | function GetCount: Integer; 45 | function GetItem(Index: Integer): TFileEntry; 46 | procedure Add(AFileName, AFullPath: string); 47 | procedure Clear; 48 | public 49 | constructor Create; 50 | destructor Destroy; override; 51 | property Count: Integer read GetCount; 52 | property Items[Index: Integer]: TFileEntry read GetItem; default; 53 | end; 54 | 55 | { TGDReader } 56 | 57 | TGDReader = class(TObject) 58 | private 59 | fLoadedFileName: TFileName; 60 | fDirectoriesList: TStringList; 61 | fFilesListHashTable: TFPDataHashTable; 62 | fPythonExecutable: TFileName; 63 | fPythonScriptFileName: TFileName; 64 | procedure Clear; 65 | procedure HashTableCleanUp(Item: Pointer; const Key: string; var Continue: Boolean); 66 | procedure HashTableUpdateDirectoryRecord(Item: Pointer; const Key: string; var Continue: Boolean); 67 | procedure HashTableSortRecords(Item: Pointer; const Key: string; var Continue: Boolean); 68 | function RunCommandFileOutput(const CmdSwitch: string; const OutputFileName: TFileName): Boolean; 69 | function RunCommand(OutputDirectory: TFileName; CommandLine: string): string; 70 | public 71 | constructor Create; 72 | destructor Destroy; override; 73 | function GetFilesList(const Path: string): TFilesList; 74 | function Extract(const AFullPath: string; const OutputFileName: TFileName): Boolean; 75 | procedure ExtractAll(const OutputDirectory: TFileName; const DataFolder: string); 76 | function ExtractBootstrap(const OutputFileName: TFileName): Boolean; 77 | function GenerateSortFile(const OutputFileName: TFileName; const DataFolder: string): Boolean; 78 | procedure LoadFromFile(const AFileName: TFileName); 79 | procedure FillListView(ListView: TListView; Path: string); 80 | procedure FillTreeView(TreeView: TTreeView); 81 | property LoadedFileName: TFileName read fLoadedFileName; 82 | property PythonExecutable: TFileName read fPythonExecutable write fPythonExecutable; 83 | end; 84 | 85 | implementation 86 | 87 | uses 88 | {$IFDEF DEBUG} 89 | Dialogs, 90 | {$ENDIF} 91 | Utils, 92 | Forms, 93 | Process 94 | {$IF Defined(Unix) OR Defined(Darwin)} 95 | , UTF8Process 96 | {$ENDIF}; 97 | 98 | const 99 | SFILE_GDITOOLS_PY = 'gditools.py'; 100 | 101 | { TFileEntry } 102 | 103 | procedure TFileEntry.Update; 104 | var 105 | S: string; 106 | 107 | begin 108 | S := '1'; 109 | if fDirectory then 110 | S := '0'; 111 | fSortHashStr := S + UpperCase(fFileName); 112 | end; 113 | 114 | constructor TFileEntry.Create(AFileName, AFullPath: string); 115 | begin 116 | fFileName := AFileName; 117 | fFullPath := AFullPath; 118 | fDirectory := False; 119 | Update; 120 | end; 121 | 122 | { TFilesList } 123 | 124 | function TFilesList.GetCount: Integer; 125 | begin 126 | Result := fList.Count; 127 | end; 128 | 129 | function TFilesList.GetItem(Index: Integer): TFileEntry; 130 | begin 131 | Result := TFileEntry(fList[Index]); 132 | end; 133 | 134 | procedure TFilesList.Add(AFileName, AFullPath: string); 135 | begin 136 | fList.Add(TFileEntry.Create(AfileName, AFullPath)); 137 | end; 138 | 139 | procedure TFilesList.Clear; 140 | var 141 | i: Integer; 142 | 143 | begin 144 | for i := 0 to fList.Count - 1 do 145 | TFileEntry(fList[i]).Free; 146 | fList.Clear; 147 | end; 148 | 149 | constructor TFilesList.Create; 150 | begin 151 | fList := TList.Create; 152 | end; 153 | 154 | destructor TFilesList.Destroy; 155 | begin 156 | Clear; 157 | fList.Free; 158 | inherited Destroy; 159 | end; 160 | 161 | { TGDReader } 162 | 163 | procedure TGDReader.Clear; 164 | begin 165 | fDirectoriesList.Clear; 166 | fFilesListHashTable.Iterate(@HashTableCleanUp); 167 | fFilesListHashTable.Clear; 168 | end; 169 | 170 | procedure TGDReader.HashTableCleanUp(Item: Pointer; const Key: string; 171 | var Continue: Boolean); 172 | begin 173 | FreeAndNil(Item); 174 | Continue := True; 175 | end; 176 | 177 | // This code was made to determine if a FileEntry is in reality a directory. 178 | // This can be optimized if the gditools.py script prints if the entry is a 179 | // directory or a file. 180 | procedure TGDReader.HashTableUpdateDirectoryRecord(Item: Pointer; 181 | const Key: string; var Continue: Boolean); 182 | var 183 | i, Index: Integer; 184 | FilesList: TFilesList; 185 | FileEntry: TFileEntry; 186 | 187 | begin 188 | FilesList := TFilesList(Item); 189 | 190 | // for each entry in the current directory... 191 | for i := 0 to FilesList.Count - 1 do 192 | begin 193 | FileEntry := FilesList[i]; 194 | 195 | // if the current entry is in fDirectoriesList, then it's a directory. 196 | if fDirectoriesList.Find(FileEntry.fFullPath + '/', Index) then 197 | begin 198 | FileEntry.fDirectory := True; 199 | FileEntry.Update; 200 | end; 201 | end; 202 | Continue := True; 203 | end; 204 | 205 | function __Compare__FileEntry(Item1, Item2: Pointer): Integer; 206 | var 207 | FileEntry1, FileEntry2: TFileEntry; 208 | 209 | begin 210 | FileEntry1 := TFileEntry(Item1); 211 | FileEntry2 := TFileEntry(Item2); 212 | 213 | Result := -1; 214 | if FileEntry1.fSortHashStr > FileEntry2.fSortHashStr then 215 | Result := 1 216 | else if FileEntry1.fSortHashStr = FileEntry2.fSortHashStr then 217 | Result := 0; 218 | end; 219 | 220 | procedure TGDReader.HashTableSortRecords(Item: Pointer; const Key: string; 221 | var Continue: Boolean); 222 | var 223 | FilesList: TFilesList; 224 | 225 | begin 226 | FilesList := TFilesList(Item); 227 | FilesList.fList.Sort(@__Compare__FileEntry); 228 | Continue := True; 229 | end; 230 | 231 | { This is a shortcut for commands generating output files (like IP.BIN and 232 | sorttxt.txt). } 233 | function TGDReader.RunCommandFileOutput(const CmdSwitch: string; 234 | const OutputFileName: TFileName): Boolean; 235 | var 236 | OutputDirectory, TargetFileName: TFileName; 237 | 238 | begin 239 | OutputDirectory := IncludeTrailingPathDelimiter(ExtractFilePath(OutputFileName)); 240 | TargetFileName := ExtractFileName(OutputFileName); 241 | RunCommand(OutputDirectory, Format('%s %s -o .', [CmdSwitch, TargetFileName])); 242 | Result := FileExists(OutputDirectory + TargetFileName); 243 | end; 244 | 245 | { Thanks to Marc Weustink and contributors 246 | http://wiki.freepascal.org/Executing_External_Programs } 247 | function TGDReader.RunCommand(OutputDirectory: TFileName; 248 | CommandLine: string): string; 249 | const 250 | READ_BYTES = 2048; 251 | 252 | var 253 | OutputLines: TStringList; 254 | MemStream: TMemoryStream; 255 | {$IFDEF Windows} 256 | OurProcess: TProcess; 257 | {$ELSE} 258 | OurProcess: TProcessUTF8; 259 | {$ENDIF} 260 | NumBytes: LongInt; 261 | BytesRead: LongInt; 262 | SavedDirectory: TFileName; 263 | 264 | begin 265 | // Checking the presence of the gditools.py script 266 | if not FileExists(fPythonScriptFileName) then 267 | raise EGDReader.Create('The gditools.py script wasn''t found'); 268 | 269 | // Saving the current directory 270 | SavedDirectory := GetCurrentDir; 271 | 272 | // Handling the output directory 273 | OutputDirectory := IncludeTrailingPathDelimiter(OutputDirectory); 274 | ForceDirectories(OutputDirectory); 275 | SetCurrentDir(OutputDirectory); 276 | 277 | // A temp Memorystream is used to buffer the output 278 | MemStream := TMemoryStream.Create; 279 | try 280 | BytesRead := 0; 281 | {$IFDEF Windows} 282 | OurProcess := TProcess.Create(nil); 283 | {$ELSE} 284 | OurProcess := TProcessUTF8.Create(nil); 285 | {$ENDIF} 286 | try 287 | 288 | {$IFDEF Windows} 289 | OurProcess.Executable := PythonExecutable; 290 | OurProcess.Parameters.Add(Format('"%s" -i "%s" %s', [fPythonScriptFileName, LoadedFileName, CommandLine])); 291 | {$ELSE} 292 | { On Linux (at least), we can't use the Parameters method above for an unknow reason. 293 | I think I should add several parameters for every part of the command line but it's too complicated for no gain. 294 | So I use the old deprecated CommandLine property instead and it works like a charm! } 295 | OurProcess.CommandLine := Format('"%s" "%s" -i "%s" %s', [PythonExecutable, fPythonScriptFileName, LoadedFileName, CommandLine]); 296 | {$ENDIF} 297 | 298 | {$IFDEF DEBUG} 299 | ShowMessage(OurProcess.Parameters.Text); 300 | {$ENDIF} 301 | 302 | { We cannot use poWaitOnExit here since we don't know the size of the output. 303 | On Linux the size of the output pipe is 2 kB; if the output data is more, we 304 | need to read the data. This isn't possible since we are waiting. 305 | So we get a deadlock here if we use poWaitOnExit. } 306 | OurProcess.Options := [poUsePipes, poStderrToOutput]; 307 | OurProcess.ShowWindow := swoHide; 308 | OurProcess.Execute; 309 | 310 | while True do 311 | begin 312 | // Refresh the GUI 313 | Application.ProcessMessages; 314 | 315 | // make sure we have room 316 | MemStream.SetSize(BytesRead + READ_BYTES); 317 | 318 | // try reading it 319 | NumBytes := OurProcess.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES); 320 | if NumBytes > 0 then 321 | begin 322 | Inc(BytesRead, NumBytes); 323 | end 324 | else 325 | Break; 326 | end; 327 | 328 | MemStream.SetSize(BytesRead); 329 | 330 | OutputLines := TStringList.Create; 331 | try 332 | OutputLines.LoadFromStream(MemStream); 333 | Result := OutputLines.Text; 334 | finally 335 | OutputLines.Free; 336 | end; 337 | 338 | finally 339 | OurProcess.Free; 340 | end; 341 | 342 | finally 343 | MemStream.Free; 344 | end; 345 | 346 | // Restoring the right directory 347 | SetCurrentDir(SavedDirectory); 348 | end; 349 | 350 | constructor TGDReader.Create; 351 | begin 352 | fFilesListHashTable := TFPDataHashTable.Create; 353 | fDirectoriesList := TStringList.Create; 354 | with fDirectoriesList do 355 | begin 356 | Sorted := True; 357 | Duplicates := dupIgnore; 358 | end; 359 | fPythonScriptFileName:= GetApplicationPath + SFILE_GDITOOLS_PY; 360 | end; 361 | 362 | destructor TGDReader.Destroy; 363 | begin 364 | Clear; 365 | fFilesListHashTable.Free; 366 | fDirectoriesList.Free; 367 | inherited Destroy; 368 | end; 369 | 370 | procedure TGDReader.LoadFromFile(const AFileName: TFileName); 371 | const 372 | FILELIST_SIGN = 'Listing all files in the filesystem:'; 373 | 374 | var 375 | Index, i, StartIndex: Integer; 376 | OutputBuffer, RecordFullPath, RecordDirectoryPath, RecordFileName: string; 377 | FilesList: TStringList; 378 | Buffer: TFilesList; 379 | 380 | begin 381 | Clear; 382 | fLoadedFileName := AFileName; 383 | 384 | // Executing gditools.py 385 | OutputBuffer := RunCommand(GetCurrentDir, '--list'); 386 | 387 | // Extracting the files listing 388 | StartIndex := Pos(FILELIST_SIGN, OutputBuffer); 389 | if StartIndex = 0 then 390 | raise EGDReader.CreateFmt('Error when parsing the GD-ROM Image%s%s', 391 | [sLineBreak, Trim(OutputBuffer)]); 392 | Index := StartIndex + Length(FILELIST_SIGN) + 1; 393 | 394 | // Parsing the files list... 395 | FilesList := TStringList.Create; 396 | try 397 | // Load the files list buffer 398 | FilesList.Text := Trim(Copy(OutputBuffer, Index, Length(OutputBuffer) - Index)); 399 | 400 | // Extracting the directory listing and building the files list 401 | for i := 0 to FilesList.Count - 1 do 402 | begin 403 | RecordFullPath := Trim(FilesList[i]); 404 | RecordDirectoryPath := ExtractFilePath(RecordFullPath); 405 | RecordFileName := ExtractFileName(RecordFullPath); 406 | 407 | // Building the directory listing... 408 | fDirectoriesList.Add(RecordDirectoryPath); 409 | 410 | // Handling the files list... 411 | if not Assigned(fFilesListHashTable.Find(RecordDirectoryPath)) then 412 | fFilesListHashTable.Add(RecordDirectoryPath, TFilesList.Create); 413 | Buffer := TFilesList(fFilesListHashTable[RecordDirectoryPath]); 414 | 415 | // Adding the record... 416 | if RecordFileName <> '' then 417 | Buffer.Add(RecordFileName, RecordFullPath); 418 | end; 419 | 420 | // Setting the Directory flag: 421 | // This can be optimized if the output of gditools.py indicates if the entry is a file/dir 422 | fFilesListHashTable.Iterate(@HashTableUpdateDirectoryRecord); 423 | 424 | // Sorting the directories and the files order 425 | fFilesListHashTable.Iterate(@HashTableSortRecords); 426 | finally 427 | FilesList.Free; 428 | end; 429 | end; 430 | 431 | procedure TGDReader.FillTreeView(TreeView: TTreeView); 432 | var 433 | i, ImageIndex: Integer; 434 | Directory, DirectoryName, DirectoryPath: string; 435 | HashTable: TFPDataHashTable; 436 | Node: TTreeNode; 437 | 438 | begin 439 | HashTable := TFPDataHashTable.Create; 440 | try 441 | TreeView.Items.Clear; 442 | ImageIndex := 0; 443 | for i := 0 to fDirectoriesList.Count - 1 do 444 | begin 445 | // Work with the current directory entry 446 | Directory := fDirectoriesList[i]; 447 | 448 | // Get only the directory name 449 | DirectoryName := ExtractFileName(Copy(Directory, 1, Length(Directory) - 1)); 450 | 451 | // Get the directory path (to handle parent nodes) 452 | DirectoryPath := Copy(Directory, 1, Pos(DirectoryName, Directory) - 1); 453 | 454 | // If the directory name is empty, then use the full path (the 'directory' it-self) 455 | if DirectoryName = '' then 456 | DirectoryName := Directory; 457 | 458 | // Get the parent node (returns 'nil' if the parent node doesn't exists 459 | Node := TTreeNode(HashTable.Items[DirectoryPath]); 460 | 461 | // Add the current directory under the found parent (or under 'nil') 462 | Node := TreeView.Items.AddChild(Node, DirectoryName); 463 | Node.ImageIndex := ImageIndex; 464 | Node.SelectedIndex := ImageIndex; 465 | 466 | // For the first node (the root) the image will be a 'CD', after 'folders' 467 | ImageIndex := 1; 468 | 469 | // Adding the current directory (may be a parent for further nodes) 470 | HashTable.Add(Directory, Node); 471 | end; 472 | finally 473 | HashTable.Free; 474 | end; 475 | 476 | // Open the first node 477 | if TreeView.Items.Count > 0 then 478 | TreeView.Items[0].Expand(False); 479 | end; 480 | 481 | procedure TGDReader.FillListView(ListView: TListView; Path: string); 482 | var 483 | FilesList: TFilesList; 484 | i: Integer; 485 | FileEntry: TFileEntry; 486 | 487 | begin 488 | // Get the selected files list from the GDI path 489 | FilesList := GetFilesList(Path); 490 | 491 | // Fill the ListView with the contents of the files list 492 | ListView.Clear; 493 | if Assigned(FilesList) then 494 | begin 495 | ListView.BeginUpdate; 496 | for i := 0 to FilesList.Count - 1 do 497 | with ListView.Items.Add do 498 | begin 499 | FileEntry := FilesList[i]; 500 | Caption := FileEntry.FileName; 501 | 502 | // By default, every entries are files... 503 | ImageIndex := 0; 504 | 505 | // ... but mark directories with the right icon 506 | if FileEntry.Directory then 507 | ImageIndex := 1; 508 | end; 509 | ListView.EndUpdate; 510 | end; 511 | end; 512 | 513 | function TGDReader.GetFilesList(const Path: string): TFilesList; 514 | begin 515 | Result := TFilesList(fFilesListHashTable.Items[Path]); 516 | end; 517 | 518 | function TGDReader.Extract(const AFullPath: string; 519 | const OutputFileName: TFileName): Boolean; 520 | var 521 | SourceFileName, TargetFileName, OutputDir: TFileName; 522 | 523 | begin 524 | Result := False; 525 | 526 | SourceFileName := ExtractFileName(AFullPath); 527 | TargetFileName := ExtractFileName(OutputFileName); 528 | 529 | // Handling the output directory 530 | OutputDir := IncludeTrailingPathDelimiter(ExtractFilePath(OutputFileName)); 531 | 532 | // Calling the gditools.py script 533 | RunCommand(OutputDir, Format('-e %s -o .', [AFullPath])); 534 | 535 | // if the file need to be renamed, do it 536 | if (SourceFileName <> TargetFileName) then 537 | RenameFile(OutputDir + SourceFileName, OutputDir + TargetFileName); 538 | 539 | Result := FileExists(OutputFileName); 540 | end; 541 | 542 | procedure TGDReader.ExtractAll(const OutputDirectory: TFileName; 543 | const DataFolder: string); 544 | begin 545 | RunCommand(OutputDirectory, Format('--extract-all -o . --data-folder %s', [DataFolder])); 546 | end; 547 | 548 | function TGDReader.ExtractBootstrap(const OutputFileName: TFileName): Boolean; 549 | begin 550 | Result := RunCommandFileOutput('-b', OutputFileName); 551 | end; 552 | 553 | function TGDReader.GenerateSortFile(const OutputFileName: TFileName; 554 | const DataFolder: string): Boolean; 555 | begin 556 | Result := RunCommandFileOutput(Format('--data-folder %s -s', [DataFolder]), OutputFileName); 557 | end; 558 | 559 | end. -------------------------------------------------------------------------------- /licences/GNU_GPL_v3.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | <one line to give the program's name and a brief idea of what it does.> 635 | Copyright (C) <year> <name of author> 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see <http://www.gnu.org/licenses/>. 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | <program> Copyright (C) <year> <name of author> 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | <http://www.gnu.org/licenses/>. 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | <http://www.gnu.org/philosophy/why-not-lgpl.html>. 675 | -------------------------------------------------------------------------------- /gui/about.lfm: -------------------------------------------------------------------------------- 1 | object frmAbout: TfrmAbout 2 | Left = 639 3 | Height = 166 4 | Top = 402 5 | Width = 406 6 | AutoSize = True 7 | BorderIcons = [biSystemMenu] 8 | BorderStyle = bsDialog 9 | Caption = '<Dynamic Title> (About Form)' 10 | ClientHeight = 166 11 | ClientWidth = 406 12 | OnCreate = FormCreate 13 | Position = poScreenCenter 14 | LCLVersion = '1.2.6.0' 15 | object imgLogo: TImage 16 | Left = 8 17 | Height = 128 18 | Top = 8 19 | Width = 128 20 | BorderSpacing.Bottom = 30 21 | Picture.Data = { 22 | 1754506F727461626C654E6574776F726B477261706869635344000089504E47 23 | 0D0A1A0A0000000D4948445200000080000000800806000000C33E61CB000000 24 | 097048597300000EC400000EC401952B0E1B000020004944415478DAED7D7778 25 | 5CD599FEFB9D73EF548DBA6459B6DC7B37CD404C6FA6991242494280141248AF 26 | 6C7637BFEC6EB225D9EC26D96481248484107A02A1188301D331D518DCBB245B 27 | D59634D2F47BEF39E7F7C72D7367349225B0C1C9FA3ECF3CA3A99A7BDFF77CDF 28 | FB95730E70E438721C398E1C478E23C791E3C871E438721C39FE6F1DF4B77A62 29 | 4F3FF32A314620C6C088883106222A38DFB7DF591BADAAAA2E4FA75329611A89 30 | C58B8F5600400410632028054029A5A094C092E38E52470870981E4F3EF53271 31 | C68931463DBDFB75D334672B60B61062C29EF6BDB32A2B2AE60503C15ACE7944 32 | D37898732DA46B9AA6691AA494B02C4B082973528A8C1022655A567C2031B039 33 | 9B4E6D9C3573D61EC6686B2C1A595F535D99B13921D5E2C58BD511027C48C78A 34 | 95CF93C63530C6D940221E4967B367F4F4F69CA069DA39E5B1F239B168991E2B 35 | 8BA1A23C8650280422726E806B08DCE7F27F63D063D33430904860203180642A 36 | 210712895DDBB66D7BE2B8638F7AB5AABC7C556545AC5729A9A4946AE1A2A3D5 37 | 11021CC2E3E1479F218D6BE01A67DB776C9B6898D6559AA62DAFACA85C545B53 38 | 13A8AFAD83AEEB43023D3AF009440A008191725E572052905260DFFE1E74EDEB 39 | 16BDF1F83629D463D55515F74D99347E9D924A0A29B160C15F87BBA0BF0EE057 40 | 93A66994480C54A4D2E9CB7AE37D578F1D33F6C409E39B785934324230470BBE 41 | 738108603EF0EDE794F71C00188681E6D63DAAADB37B733299FABDB48C7B4E39 42 | F9C40E29A49C3377913A4280F7783CF8F033A46B1A6BD9D33C6F6F7BDB37A74D 43 | 9EFAD1A671E323B5353500F2C01D4AF0FD04C883AF8ADEA3C01803000C2492D8 44 | DDBAD76AD9D3FE746343FD4FA64E6A7A5E082166CD5EA08E106084C7FD0F3E45 45 | 015D67ED1D7B8FE9EAEAFCBBE9D3665C3875D2646E9B777C00E09307BE3BDA5D 46 | F0C97507F0BB051AF4FF9452D8D5B2476DDEBAEB9531F5353F9A32B169A52584 47 | 344D53CD9F7FF8B887C38A00773FF02405749D7574B61DDF1BEFFBDED44953CF 48 | 9A3C71220B68BC04381F04F8CEAD24F8CAF79EC104B0DF47904AA1756F3B366D 49 | DDF1767555E50F264F1CFFA8691A62CE9CC32382382C08F0BB3F3E467A4067A6 50 | 91AB7BFD8D57FEFD84254BAF9E3471320F68CC36BF8C9C51F841814F3EB0E900 51 | E06348F0E1FB4E80D0DCBA57AD79E3ED27485ADF58FA91E3B6E772865CB46889 52 | FA3F4D80DBEE5CC1F6B4EEE48CE1335595D5FF3A7BD6DCEA70380402C089C098 53 | EB873F48F0E1F978E6031B0EF8C51AC04932D9EF67F9EFB7BF93E0CF3F599689 54 | 751B3665BBF6F5FEA4BEBAE23F6AAA2B323923A78E3DF614F57F8A00BFF8ED5F 55 | 28A8EB6CDBD60D7363E5E5BF99376BF671F5F5F5F605830BB83DF26D2B907FEE 56 | 83019F7C6A3F0F7EB12660CCFD1FCCA7070683EFFF4E22A0B72F8E356FACDBF5 57 | F6DBEB3E77D5C796BF60185971D4D11F3C093E1402FCF2B70FB25DDBB7F07059 58 | C5272B6B1A7E397FD6AC484863E01A1CC0A9C09496B602870A7C2A8A00D43002 59 | 10608C7C603B401339AEA3187CF82C870494C43B1B378B07FEBCF2DF16CD9FFE 60 | C3D9B3A65A471F73BAFC9B25C0FFDC7A076981106532B9D8C6CDDB7EB1E4C4D3 61 | 3FD938661C694C21C0015D57D0D96070189163010A497068C0A7421F5F00BE2A 62 | 720BC5E2CF459B9CCF5109F07D9A020A80404757179E7EEEF5D503F1BEEB4EFE 63 | C8D16DD95C4E7E64E9F9EA6F8A00B7DCF65BE25A90FDE98107E61D7FEA0577CF 64 | 99B5784E241205C0C009D03810D414748DC0992BBE0A01E33E4B7068C1A712A1 65 | 5E7112A89000280098BC0B5BCAADB8C402A46D092090CD64F0DC2B6BBB376CD8 66 | FAC9B34F5FF2AC6198E2848F1C7A127C2004F8D56DB7901E08F335AFBEB174CE 67 | 82631F9A317D51A5221D0ACC192D04CE08010D08E880CEDCE44B1E4C4604C694 68 | A70B0E0DF82832D3F0093E55E0065831F8CED52462CEF85743B815E7FB94EFFB 69 | 20A0940094C0AB6F6D301F78F0E9CFCE9EDE78CFFC79B3C4474E5A2EFFAA09F0 70 | EBDB7E413B76ECD676B7B45DB0ECDC73EE9A3E7D5ED81401989606A1589E04C4 71 | A03120A8DB96C08E000AC16464AB6C76C8C0CFE7FF87039FE08A52E65DC1FCE7 72 | 99776187041FAAC0B5404900EECDC2FA4D3BE45DF7ADBA694A53CDFFCC9B3FDB 73 | 3AE9E48BE45F25016EF9F57FB3DD3B5B78774FFCD3E79C73DA2FA74E9AAA29E8 74 | 30A406D3D461080D121C4A91377274CD264180B926DF070EF204F0875B070F7C 75 | 1C40002A5FE847252C87DFFF0F1694F6E78BC047FE463E126CDDDEA27E7FD7E3 76 | FF3DB1B1FAEFE7CC9D619D7ADA47E55F1501FEF7961FB3E6E63D5A5F7FF26BE7 77 | 9D7BFABF378D1FCF080C0087543A4CA923277498960629199463051811023A10 78 | D26C41580C74A1153814E017FAE9C1E03B6E880D01BEF7B952E0C3137FF6CBD2 79 | 013FFF3A200129A0948596BD1DF8FD5D2B7F5B5719FEE29CB933CC33CEBC5CFE 80 | 5510E09737FF8835EF6EE5FB7AFB3F75D1F2B37E3D61FC38669B469B00008354 81 | 011852474E68B02C0EA938146C2BC03520C809214D81B3C13EBFD8151C1CF069 82 | 98F4AF1FFCD299BFE1C177DD084090DE636FE47B28E4DD8152124A59686E6DC7 83 | AF6E7FF427E3C694FDE3ECD933CC73965D250F6B02FCEC7F7E48AD2D7BB5963D 84 | 5DE77FECF273EF9F3679B24EC4BC8B6E274C1894D221950653EAC80A0DA6A541 85 | 399A807182C680B0060438C059615E804A5A81F70B7E3E0270416183C02F1DFE 86 | 159007C381EF33FBA41C21580C3EA0948282DD860629B07567B3FAED1D2BBEDD 87 | 34B6E21733674EB5CEBFE06A795812E0BF7EFA7DDAD3DAAEBDFCCADB277CF96B 88 | D7AD9C337346C41FCEC1137CB61550D020A50643E8C80A1D96E48E2864608CA0 89 | 3B24D0B9E3F75D80593E4368FBE28301BE5FFDAB4125E0A18A3F0560A3389454 90 | C380EF37FB7EF0E1809FB706520AACDFBC5DDE76FBA3D74E995873EF8C1953AC 91 | 8B2FF9B43AAC08F0A31FFD1D45A251FED88A67675D7EE5852F2C9C37B78A18F9 92 | 4CA21B32B9611207A04181433AAE20273458D2B604203B340C7220A4D9790286 93 | C291C7589E04070FFCA13380403EF53BD8CCBB02B004F85ED2070049E7C2FBC1 94 | B749A19433FA55FE35B72155490BAFADDD6CFED3BFFCCFF9679FB1E4B9695327 95 | 591FBBFCF3EAB020C0BFFDF09B148D46D9BD0F3C5E76E52796AF3EE1B8638ED2 96 | 342D0FBA4B8282308901C441D0201587907654605B02472B104167E473056E34 97 | 408E15B00129D608A3077F70A84625C02F54FF28721B7EF05104BE1C1E7C2828 98 | 1483EF7F2C0125208489A79E7FBBF31B5FFFFE09FFFD93EFEE4D2452E293577F 99 | E57D91403B1804086A41FAC52FEFD0CF39FF94FF5C3C7FE651BA468EA9734715 100 | F3122680724CB9722E8802270922E159889C2008A9A0C8BE74862270E53A105F 101 | B5CD777F70C0F73F56BEC7B2C4EB25BE1FA5C07747BE2AF8C92EF0A547BEFB18 102 | 5E94001018E33869C9EC866F7DE7CBBFFDC7EFFDE785DFFFDE577300C4876A01 103 | 7EF44F37515B67A7DE15EFBBEC9AABCFFBE3B8C64652CEE8B6CD3D2B1CF9AE25 104 | F0FC257778C8209506216D3D60080EA16CADC08810E284A0A6A0712A48047979 105 | 8122D047073EF9467A7106500E53FB2F56FF859D43766CAF7CE0AB82516F9BF8 106 | 5266DF268842FEFDCAD509CA427B5737FEF7D70FFFA0AD65C7BF5E78E199E627 107 | 3EF955F9A110E09FBFF54DEAEAE9D69E7CFE8599FFFA2F5F7979CEECA9E5F926 108 | 3A1B3C906BCE6D4BE081EFDD33904300226E470642434ED8BA40289B449C11C2 109 | 1A21C06D12D855427F583898042307BF183C38255F59E8166808CB510A7C5220 110 | A53CAB5710E7AB22F03DA0E181EF48411F592414EC0AA25216D66FDA2DBEF3DD 111 | 9F9D77FAC98B9E6D9AD0685DF7E96FAB0FDC05840261F6E4B32FE85FFADC353F 112 | 9DD534AD9C0982E2EE890B8000450440D823DDB958AA28D60684F31A819370A7 113 | E600201892209482520C96B44342AEEC04D1600EBF1FF0A9A89E2F0B7C3CD110 114 | 4DA3182C2041B0AF015022CE1F0E7C3504F8CA015F79BF7BEEAC26FEB5AF7DFA 115 | E6CF5CF7F5636EFEDFEF27DEAB2B78CF16E09FBFF95DF6F21B6BF44824F2B1AF 116 | 5CF3A93F8C195345D005109080266D91EFDA68CF0A386120633E81C81CCBC07D 117 | D10187501A4CA1236BE930248752765F608803418DA0732A481533F23F1E0DF8 118 | 833376A5AA807646920D023B5FF5437EE40F4AF2285FA8A70A433DD7C42BF8DC 119 | 42FEBD79F01D11E93EAF24F6F5F6E3E7FFFBD0BFB5366FFBC1F9E79D665C73ED 120 | B7E5074280EFDCF875AAA9ACE43FFFEDAF6A7EFC9DFFB776F19C598DE012C405 121 | 3C12E812E00AC408CA7109E4BA04F7E601E32780FDB752F91C414E681E097446 122 | 0870425007349FD9670C5E016974E017D6FF6D918A2172FFA54ABA85E07B7EDF 123 | EFF38BCDFEB0E0CB22B39F0F13FDA47049F0F6BBADB94F5D77D3711FBFE2ECCD 124 | 631BEBAD2FDCF03D75C85D40381CA65FFDF177FA25CB96FFC3F449D31AA13440 125 | 487B3483034A80944304A7F80126F232DEE59E57E45145A25E4191B0E37BB7F8 126 | 2E184CA92040B014C0A51D16C2972154647F131B35F87EF5EE1784C5E4284EF2 127 | 503EAFEF2BF4808A433D0C4EF2F8C59D7FE4437A5942F8C347555838724C0266 128 | CF1C1BFCF64D5FFACF9FFDD7CF2FFDBBEF7C5E8ED6158C9A00DFBAF1EBD4D6D9 129 | C1CB62E5734E5B7AF21722656550D2CEEB9114F6892B0652CCFE2DBAE312987B 130 | 51241491D308C1F266920400CD1B3576224642E302E4B809B208962248102C49 131 | D0A46DF67DDD18BE386B24E00F5D082A047F084DE13500A9BC3925E533ABFE91 132 | EFA67765DEE7230FB452AAC855488737FE918F3C291CAB110C6A38E52333CF7E 133 | F82F33CF7FF891A71FBEE5E61FC81B6E1CB9151835012291087B70C55F02179F 134 | 7FF1D7274D98A02B8DD94C960EE84A8124032C06521C101628E8F82E4DD96E81 135 | 44DE0139C575EFE215A866090E02D32C80982D282D825404A108A652E092C0B4 136 | 628F361AF0D53023BD502816440B2861F63DB75064F6510C7EA1C853C5A69D6C 137 | 4290EBFFDD3C82471278D1051430AEA10AD75D77E54D975D7AF5CAE5CBCFB446 138 | 6305464580AF7DE12BD4D6D9CE99C6A72C39E6D88F6981A027EB6DECC9B17394 139 | 071FCC7107A2D08731E95DEC7C5208792BE066D09C705127CB71170C8660904A 140 | 4148068B3949225F3E5EC1977DC448AB80A5C9502828D510E0FBCDBE3FD6974E 141 | 86CF21C320852FF366DF1BDDF67B093EF740CA1BF14EA6C0C31F50E09C61FE9C 142 | 31472D3BEFDCB31E7EF8E9C77FF98B1FC82F7D796456401BA5EF670F3FFE88BE 143 | ECCC655F9D3C7E6280DC588C94CF2A9193E05320C54052822C0B501C50961D5E 144 | 2969FF675F08985753168834CF1FDBF776A690F986A129EC2CA1296D3DC098E7 145 | 507CCD99236FFE18CAE7032819FA817CD7D7EBECC12013EE82AF20EDB0B840E1 146 | FB47BE2C4A0DCBA25A010A48605FEAFCFF6C6CA8C4A7AEB9EC9B1FBFE2334F5F 147 | 78E1391600EBA012E0864F7F81DA3B3BB8841A7FF289277F22180C3917C26717 148 | DD1FC614481194B4AD011403090932180876EF9B77C21C80B2AD81B2D33B0E29 149 | 1C7148B61560B08561C0CB2A3298922015832519B822701740B011E605E0231A 150 | 8AC0F745B13E8D005F66CF9FF2CDFB7CE9A97737AE579025C3BBBCD02B7419F9 151 | 1BF2114051E8A6FCAE40D9C9B145F3C79D70C659672E7DF89155CFFCEC673F10 152 | 5FFBDA81ADC08809108E4468E5D32BF5D34E3AFDFA29132684DCA94FE4CBCF7B 153 | 155F90739ECAB10612500C900C64D8E94C48DB25F8AD81A70DBC8B2B9DF0D026 154 | 02038139D640814082604A272A1000670ACC569BB691F4B5690B61C1B24C0821 155 | 20A5F4AA6C2E11382770CEC03983AE7104831A34674E625E5BFADBB830087C05 156 | 6947302A0FB6F2C0C5A091AF0AFA01E1D546FC69E1BCAF27DFE857250C02C384 157 | 718D74F5A72EFFD2B5575FFFE2B2654B47A4054644806B3E712D757677F296D6 158 | 96E049272EBD2A148AC0D3C179064031DF28D11C6D0005080E72C5A1928069BB 159 | 0628D3B9F75D04E666054DE7E7E55BAEDDC916A42C40772C8145B02473424306 160 | CE00E66802CB12304D039669402939C8E7E77D8F8294B618B32C05C350486760 161 | 13211440381404D77861CEB1A0A7CF156D7208F0FD424FFA74801C1CDAF9C1F7 162 | AC80AB0FC8971C72CD12076361305E81008FE1C4E3ADB3264C9C34E6B1C79E6A 163 | FDD71F7E59FEC33FFE42BD6F02442251DAB8699776CAC9A79F31764CC3587F35 164 | 8E0010F79950AFE0837CAF3473A48B0420C88E16A40209660B3D65D80C0F38CC 165 | 26E9EB99CBC7EB70442123828E7CF5109684541C9654E0D2FE5C3A9D816559BE 166 | C69162F08BBB79D5204D20A440269341369B413814402412761242FE0C9FDDBE 167 | 95075FFA7CB8CC2B7E2F969705227010011C31992F0C2A5FEE447AA39D480763 168 | 6560BC028C4501D20148348CA9D7961CBFF88A77D7ADFDD9E9A72D1607B20223 169 | 2240281C622FBCFC82FE8DAF7EFBB286FAB100736BF2289A00413E45EC8BAB5D 170 | A3C56087814A39E74E8094208B39C9230BD0453E9462565ED02978F5029B78C2 171 | 9E45A45976CD40D8B90123958312067446E03EEB94F7F930A5541D44D4AB696C 172 | 80739E16C20A48A9CA0155CD393512A9905F6C0140269B452E97452412422412 173 | 2AC8DC1582EF53F64556A050E8C9C251EEFBDB5F16F69783010E626130560EE2 174 | E5602C643FAF0C48AB0B527443539D38FB9CE3AF78E0BE876EDEDDDC6A7CFB5B 175 | 97CBFFFCC9FDEA3D13E0E3575D4D6B5E5BC36A6BEB2A16CE5F7C1ED7B58204B2 176 | 720778F1A8F24613F39A203CF70000AE4074DC826D0D9857F2842E419A9B05B3 177 | 603FF0996E2230122027FE1352A23F958390409813B8D32CE2FCAE4420A0AF8B 178 | 4623DBA3D1E8AE6030A0954A832BA554369B4D653299F1994C628652D6B18C44 179 | AD2DC4EC45E3D2E9344C338BF2F232AFD943A9FC88579E3B5379F0917771CACD 180 | F415157B0AB386AA50F2910EC6A260AC02C4CB40A403CA84147D90629F0DBEEC 181 | 839229401998DC64CE5BB8F8A8D93B77B4AE3DE698E9D6FBB200E17084DADAF6 182 | EAF3E72FBAB0716C6399937A2B2C2650618637DF09E2BB635E90E6F4863A27AB 183 | 1420292F122D5B30DAAEC1CA9B3E261D30A53397C806979384696661660DE8A4 184 | 41920643011C040ED55F511E7BA6B6A66A9DA669DCF9327DC8C2081185C3E1B2 185 | 70381C07AA5F370CE3B9FEFE9EC9A6D17F11E762ACCD2506D314E8EBED437945 186 | 041AE7BE919F07DB1EC5A228B47308E38AC282D19F37F7A414143888059DD15E 187 | E18C760525D310D61E67C4F740A924A00C28985E7435656280E6CD9BF4D1BBEE 188 | 7CF0DDA54B679AC3B981031220140AB33D7B5BF54B2FBBEA94DABABAC2125851 189 | 028E50A00907979C88F97C9A633A94A3D894B2AD011C6D604AE7B19B45B4AD01 190 | 29B2EF1D4B90CDA591CD18D0B9732A26C154DC8A95953DDBD450B32618D09553 191 | 621CF511080422757563BBB2D9AA9F0F0CEC9BA764DF254432AA148754403CDE 192 | 8FF25804BACE4B809FD70070F40BF9EB005404BE6BF64907B10838AB00F11808 193 | 1A14B2905607A4E8B247BC1C00540E80832D39D1941345D4D7693876C9ACB3EE 194 | BA13FFD6D2D299FBE28DCBE4FFDEFC841A35012EBEE4727AFD8D571980E0ACD9 195 | 739612E7A56B88058F558149202F6C295E39C3F5F3BEA8562990E71AF29680A4 196 | F0A963A7D40C82659AC865D220D2A0395942223630B5A1F1DEEA8AF28E83D5F0 197 | 1A0A85C2A150D3CE8181C87FA512CD9F662C375E3965EBFE817E5456948173F2 198 | 5901E5CB096050926790CA07012C04C66260AC02A010000125E390561784EC86 199 | 92FD80CA402937C7E3772DF932B472EA2893C663766D5D7DE5AEDD9DA9850B27 200 | 5BEFC90284C3616A6FDFABCD5F70D494EAAA9AB1C48A0B2E8309B065FB167476 201 | 76A02C1A85699AD8B865232A2B2A70E9791723140CE4B36DC82B6FB78042809D 202 | D6737581522021F22EC1971D93C244269D849DFE110018B480BE77E298C9F786 203 | 4291D4A198F0525E5EA3380FDC1CEFDD7C39D7928BA0420018060606505119B1 204 | AB90AE89477EE4E743377FAF00D9669E2260BC02C4CAEC248A4C418A7648D105 205 | 25FBA054DA1EE9CA721A6B4A640F7D8472AB90E31A499B377FEEA94F3DF5EC7D 206 | 4B8E9B36A41B189600C16090DADAF66AD366CE39B9AEAE9E1411188A423CE7AE 207 | 754F0B1E79EC4130CE71F289A760FAD46908878268EB6CC786CD1B70D985973A 208 | 6935E7032A5FCAF53A653D41A1EC8BA194A30D246049BBA6A02414974867134E 209 | C7997D5E9AC63BC78E9B7D87A6052D1CC2231A8D05399F7FEFFEEE5719E7030B 210 | 40610841480C98282F2F2B91E2CD0B3EF2AC6310C4CAC0A902604140E5A08463 211 | E2652FA05279BFEEEA08123E77529437F042C7BC956F1C13C2C44955C701F873 212 | 20C8E83D5980EEEE2E06403B76C98927565755FA1A3AE1D5F201E0C5979EC573 213 | CF3F83891326E1539FF8B49D4173E8F1B14B2EC7D18B8E861E0A7BF972F20B06 214 | 77764CBE5DD679CD3599E4D514E0E40D72E984ED3D34406900E32A55DF30EBDE 215 | D182AF94821042D734CD1C9D4B0887ABAA17DEDFD7F74A3D67B9064565304C20 216 | 9B630887023EF5EF4BEC10035104C4CA4154E6B88B7E286B1FA4DC07259300B2 217 | DE480709AF7C0E7F51A8386AA0E2D633FB7175B586A38E9E7EEA1DB7435FFDCC 218 | 26F6D9CF9D4EB7FD66B51A3101969D7B217576B43300812993A72C72DBA10AFB 219 | FC8127563E8237DF7A0D0D63C6E2DA6B3F5F140D009C31CC9831AB60A42B6F02 220 | 95FF44FC753CE523029C516F93400A0B664682B806280906C89AB1B3EF0F0663 221 | FD07024E08A1C5E3F199E9747A92522AC039274DD32CCBB2342184628C65A2D1 222 | E8AE8A8A8AED8CB1613368D1B26ADDB216DD9E4ABEF24D820C82A2C8A4930805 223 | CB9D11299DC294065019188BD901884A43CADD50C2F1EBC802B040B0F2C9A352 224 | 1604AE8F1F227A4061F848A430AE81A60483A108E3940C059985E2E4C6700408 225 | 0643C43867814020148D441B4A4DBF6A6EDE8937DF7A0D00F0D18F7EBCE49A38 226 | 2E194CD34440D73D6E64D26964322954565440D7F4C230C83310D20B210912C4 227 | 19D2D90C140B82A405B2042295756B23B131AD0718E9D4D3D3B3309D4E4FADAE 228 | AE6EA9AEAE5E474483FAE7A4943C994C8EDFB367CF47CBCBCBD75755556D1DEE 229 | 7B2B2AC79BE974F52AA53A2E24C5212447269342241201608B3AA230000B4AED 230 | 83945D80EC8752190086D30463796E830ACAE2AA64A2A860E0A8D2E0BB7FD7D6 231 | 0A6DFEC2C5D357AF5ED3B378F1441A950B080683F4E61BAFF2638E3B615AAC2C 232 | 1628065F4A81071EB8CB161CE39A50575F6F4761A6012515C2E11014805C2E0B 233 | 25151203FD58F5CC1318E8EF473295C48C69D3317BE66CBCFAD6EB48241238F9 234 | 841331B169A2AF0266C7DC9E7022826559B09402716E979D49372A1A263E371C 235 | 48966505DADBDBCFADAAAA6AABADAD7D65B8F732C6447979794B2C166BE9EFEF 236 | 9FB677EFDE498D8D8D4F31C6E4D02438FAB5BE9E074F25D61FE3AC1E524641AC 237 | CE99009B8014AD50AACFF6EB30ECD14EA220610497E83EA1A8E0EF2FC803AB8A 238 | 46B9BF4B206F611DD11A03A2D1D01C00AF07026C741A40D77502C0CBCA623363 239 | B1F2C2742F011B36BC835C2E0B0058B2E444EFF578BC0F8F3DF62006060690C9 240 | 6410080470D5959FC4C48993515656862D5B360100CE39EB5C54565662E28449 241 | F8E18F7E80B5EFBC8D6B3E7E3516CD5F54C074F24DAE34AC1C14713B29044259 242 | 4DED2B5A309C1A0EFCB6B6B6E563C78E5D17080452A5DF2348D3B82A4A08A1B2 243 | B272472814AADAB367CF454D4D4D0F0F458248A44ACFA4173ECDD9C0255CAF87 244 | 52064CB3051A8F032A05859C3DCAC949CB2BE5E431FC22CE67E655D13C025538 245 | C2A9C468A7A291EFBEA7B25287AE9B1300685CA3D15900CD218002265496C706 246 | B55B6FDBB6D9B514983D7BBEF75A43C3584C9830092FBEF81C8808575D753526 247 | 4E9A0202D0DADA0200B8FE7337A0B2BA1A0050555D8D2F7EFE8BB8F39E3BF1F2 248 | 6B6BB078D1515ECDCB9B58E15C24D312CE4E1E0C444AC5EA1BDE1CCEECB7B7B7 249 | 9F5B0C7E369B632F3CFFE2B83BEEB823BB65CB162B93CE28C618CD9A355BBFE2 250 | CA2BB44B2E5DDE6ECF6B0442A1505F7D7DFDB6F6F6F633C78F1FBF6AA8FF5516 251 | 9BB53E957AE64233DDA609918515B0501EE38E6F1F1CAF17177F0A4C3D15E509 252 | 06E5584A9BFB528FAB2A38161D356BF2D3AB5EE2CFAEDECA2EBFE278BAFFBE57 253 | D5010970FC8927D1DA375F27007CDE824593C3E1F0A01EBB542A0900A8AB1B83 254 | 402050F05A67A79D83F9D8C7AEC2F4E9B6007CFBED37D1DDDD85DADA3A4C9B3E 255 | 13524AA4D329C4E3719852E0D8639720DED78B55CF3C85F2F27234D43760EAE4 256 | C9DE48B04CD32E893BFD018170A899EB812147FFBE7DFB8EAAAEAEDEE3077FEF 257 | DEBD55DFF9CE4DFC2F7F79E8994C26D30520ED38616DE3E6F5B1152B1F6D3CF1 258 | 96934EB8F9965F0ECC9C353DE5E4427AA3D1684D3C1E9F565959B9A3B4BB2C53 259 | FBBA3B37697C6081ED061514051DF055A18A57A5157C813F279F8F1F94312CEC 260 | 46A2C2E270C17BCBCA18EAEA63D30168448A69DA082D80C6B9BBBF8E565F3FA6 261 | A654836563E378ECD9D382643251F09A6118D8BEDDD64E93274FF75E7BE6197B 262 | 009D77DE721011F6EDDF879EDE1E241203686D69413295407B7B1BDE5AFB96F7 263 | 3BE6CE9E831BAEBF0104C094398071CFBC452AAB760C63FAF55C2E37A9BEBEDE 264 | F3F99D9D9DD5577FF2EA7DCF3DFFDC3300F603709DB2DB9E1CCC6633ADAB9F5B 265 | B5FBE28B2E39EF9147FF12993E635A1A002A2B2BB7B7B6B69E585151B1834A5B 266 | 5294954D6FCE66D62C701B3A2C4B21A0B3C1628E4A6502556176D4D76A366864 267 | 97785F416B25E5230502100A51A5DD680962DC5F8D1B86008C71B7378B8743E1 268 | B25211C019679C83AEAE0E3437EFC2EDB7DF8A0B2EB814BAAEE1DE7BFF000038 269 | F7DC0B5159590122C2FAF5EBD0D3B31FA15008F3E72F0011A1AEBE1E0D631B41 270 | 4478FDF55791CB66F1AD6F7D17BB77EDC46F6FFF3594524824935EF248486F22 271 | 00008570343AA4428FC7E373ABABAB3D82643359FE0FFFF00FE9E79E7FEE5100 272 | 9D00FA0138521C4ED60901001100892DDB363EF0A51BBFF2A9C79F7C34CDEDC1 273 | 808A8A8AAEFEFEFE49959595CD25AF199FB29ED88B173AAD3B10C20402DA1040 274 | 2B5F165815085F1A81691FF2792AD2040484822A02406B6DE96353A6D48FCC02 275 | 30E64D74E6A150305A6A35AE6030844F7FFA0BD8B0E11DBCFBEE3AAC5BF72622 276 | 9108E6CD5B80CF7EF646442211F4F7C7515555850D1BDE0500CC9E3D37BFE823 277 | D74044D8B56B275A5A9A9DD473080B162C84520A9C6BB8F1C62FDB3E9F9C2430 278 | E3CEEF60D00281C4500448A7D34D3535359E3E78E5953563EEBEFBEEDB00EC05 279 | D00320198D460D21849052C2344DD2759D1B86917203F397D6BCF0E88A47577E 280 | 74F9C5177402402C166BEDEAEA9A311401C2E10691495B760F1B5758F9210000 281 | 20004944415414A44461F9BBD86FD350237BA4E0E71B5814869AE2A510082204 282 | 80B5B6F6B9EB758C400412A1B3B39D00B04020102E06DFEF12E6CF5F84050B16 283 | 17345B6EDFBE05814008B5B535C86633D8BC79A3ADFCCF397FD08C9D071FBCDF 284 | 6E3BBBE633D0340D4F3DF52482C1206EBAE9EF112B8F792923E964D31400A669 285 | 6922328609E7027E53FDC73BEF6ACD66B3AD007A2A2B2BFBABAAAA73FBF6750B 286 | C33020A5B467DD496545A365562A95943689525B1E79E4B1F8F28B2FB0135A9C 287 | 9B9665458614CD5A901494C548720505FB5BD91020AA52977C58A0871BFDC3CD 288 | EF0B0555C0A98692926284518052D4D5D5691727753D3CD2A5D85E79E525C4E3 289 | 7D98366D3AA64C990C22C2934F3E0EC330B060C122D4D5D516807FDB6DB7A2BD 290 | BD0D975EFA311C7DF4D1D8B1633B5E7FFD35DC74D3DF63CC9806DF0C1CE5650B 291 | 0180693C3E5CB64FD334CBA707D8AE5DBB5CB39F3CFEF81372EFBEFBAE482693 292 | 05885896A902015D4D9A3829DBDCD2CC01F4AD5DFB661B801A1FB1D830BD04D2 293 | 3259BFA6E5EA01405A124AD201C054C3FE7540933F5441D6F744302035628C2B 294 | 29498E94004E51C15E979169FA81C0DFBD7B07D6AD5B0BC618CE39E73C949595 295 | 8188904CA63CF177EEB9E77BE0EFD8B11D4F3CF11876EDDA89E5CB2FC1A9A79E 296 | 86542A858E8E0E7CF5ABDF40454545413651F9461311C0352D3BD4E5314D33AC 297 | F95E8FF7F5F36C36D701207DDC71C719E15058B4B7B7A9215C871A33668C4867 298 | D2B9EEEEEE3411A5FC04E07CF8B60269202D44DAFE1D16C10A9A837D3A61B0CD 299 | 56853E7CD047463485B73431B832A8BCBC22D01FEF831472640490527AE51A21 300 | ACDC70E0FFF18FB7231EEFC3F2E59762F2E4A9DE7B76EEDC81FBEFBFDBFBCE75 301 | EBDE465D5D3DD6AF5F877DFBF661F2E4A9B8FEFA1B118984BDE68E534E397544 302 | 5BC328A5CA864960652CCB0AB98F2BAB2A2C4DD32300CC050B168ADB6EFBCDB0 303 | 43ACB6AE4E2928D1DDDD6D84236151645D86FB2889ECFE1AC5724E5F07839531 304 | 871EA1231EF1EFEF73E99492FDF13E0B008D9600EE88CA96025F08815FFCE227 305 | 088542B8E186AF16E50208914804575EF9495455550220F4F70F8073E0F4D3CF 306 | C28409139D5D36F2EF8FC5CA86059FB92D65449052560E75C29C73CBB22C2DEF 307 | 9B35357DEAF4F297D73C2F971CB744DD76DB6F86BD6013264C402693010075D1 308 | F28BC6145D972153C24A4A5DE6FAA3D251F55C3258999137221DAA255BD329CD 309 | 74D932620288BCAF508691CB1483DFDCBC0B7FF8C36D983C792AAEBDF67325A7 310 | 5F8D1B37BE40F0D5D5D5BD87B97AF9F773CE61FB30829432A0940A1351660802 311 | 1B4AE567FC5C7AE9A5B3FEF2E89F836D6D6DC9035DB0E9D3A6A3A3A31D139A26 312 | D49E79D6998D00E2CEE8D7354D4B0FF539C3489295CE32B7AF412A82C5180695 313 | 47078DDCC13AE1609221938E7A62599823D400C2125EA6229BCBA6FD40A45249 314 | DC76DBCDA8AF6F1812FCD12DCE8011997DCE19A4945E66500851AD695A5BE9FC 315 | 7C646F3A9DAE8F46A3DD0070E639A7A6969D79E115BB9B77FFEAF1154F58E79D 316 | BF6C48FB3975EA14FADDEF6EE737DEF8C54F2C5ABCC0139BC964B2291289EC1C 317 | EA73A9DECD0D229D8372AAC801229844071CE7F9C2CFA1B10ED94C24EBE6A14D 318 | C31A19012CCBF408904A26D32E10E9740AB7DCF27300C0A9A79EF181814F44D0 319 | 751D96657ACFE572C682A108505959B9A1B3B373B94B8070248C7FFEE1FF3BE6 320 | 9B5FFBCEEE3163C63CFED28B6BC4D2934E184482975E7C89DE79F75D7ED96597 321 | 7DFCFACF5F3F8E884C5714C7E3F1B113264C18B29A98EA583B57242C675A9284 322 | 22C0B2DE1B7A348CBFA7511340A6DD28DA3447E8020CD350353535AAA7A747EE 323 | DAB563BF0BC6EDB7DF8A78BC0F00F0F8E38FA0AAAA0A53A74E2B0926006CDFBE 324 | 059CEB98366D9AF7DA962D76CFE0E9A7DB04EAEBEB851002EE8651FBF7EF07E7 325 | 0C3535B50564090603308C1C34CE11086820527301AC06901B1C936B66201068 326 | 49269363CBCACA3A0060C6ACA9E9FFFEF98F2F7BF2F1679A66CC9E7AC7E64D5B 327 | 52D16814132636A9B6BDED944AA7A8AFB7AF064A7DEEEBDFF8FAB4582C66FA32 328 | 8BD32B2A2AD611911A226AE23DDB56CD843D70404CD91396B8DBCE6ECF037CAF 329 | 2399DE231984045219D9EB59809112C0340C5455D5A0A7A747B4B7EDDD934AA7 330 | 511E2BC3C28547239D7E01030303482613F8D5AF7E8979F31660FEFC85983B77 331 | 1EC2E1B037F2B76DDB82952B57402989050B16E2ECB397E195575EC2A38F3E82 332 | DADA1A6CD9B2195FFAD297B171E346DC73CF1F71EBADBF0111E17BDFFB7B9C7E 333 | FA19B8F2CAAB0AD6E4D5B4A0D752669A39A492FDD150305CC91875958A93EAEA 334 | EADEDAB367CFF2402030E01684A6CF9C9A993069FC82979E7BF5E6FBEF79E8AD 335 | 638F3BBA7BD5CA6732DBB7EE8CB4B7B78F3BFAD8C50BBE70C317D28C310FFC4C 336 | 26539D4AA542E3C78F1FB2F630D0B5A15E643BCBED665620A011445239ABA4A9 337 | BC5570C8301472F90851E5434537FDA1868F044A7D653C4DD8B5BBABC5692C94 338 | B9DC085D402E6728E66C666359D6DE814402E5B1184E3DF5749C7CF2A9E8EAEA 339 | 403A9D462E97432231005DD7BD9FE18E74CBB210898421A5740A4684152B1EC3 340 | F7BFFF2F8846A3F8C10FBE8F175E781ED3A64D73D2B52F21140A432985B2B218 341 | 1863608C8173F2B662555220954C405A59282B8B14D396C6CACAFF02CE25344D 342 | 15CE4E22D5D8D8B8B2ADADEDA2B163C7BEED9220180CE28C734EC99C71CE2973 343 | 00CCB12C0B5ABE4C5620F2B2D96C557777F78CA6A6A687871BA0EDEFDC7C8690 344 | 6928C1EC390D44B0B285B0D8449000535094BFA7918C7EA50ADBEC474886DE3E 345 | 8EBDED037B0088D9532A94614835420264A16B9A02203BDAF6EE1A480C80A8D1 346 | 19891CE3C7371DD0E70783416CDBB61542085C73CD7500089AA6A1B5B515D3A6 347 | 4D412693412412C1DEBD7B5157578F471F7D149665A2B6B60E1D1D6D080434C7 348 | BC4A08CBDE5387948430D2809505A5E3C8F474CF8DC6C66D669595ADA8AE4E43 349 | D7A59F049AA619E3C68D7BD8ED088AC5626D25DC45C944587F7FFFB464321919 350 | AE190400FADA5F99DAD7F6E45425094A3030C90049B02CE66402A9A09FC72B00 351 | 91B22D826715FC5D40541A5435187D1A2647D0D71F8429CB5B6DCD2C65362746 352 | EA0272EEB758DBB76D694FA69269228A8C46F05996892F7CE14B686BDB83E6E6 353 | 662C58B010575C71151E7AE80154565661C1828538EEB82578EAA92771EEB9E7 354 | 219349C3B22CD4D45463D7AEDD104242497726ADBDA884C624746942F6EE87D6 355 | D901BDAF8FB291FDE745EAC63C8C3973DA505D9D814DDC02123435353DD2D3D3 356 | B3301E8F9F585555B53B1A8D7696F2E7524A964C26C7F7F5F54D88C562EBC78F 357 | 1FBF65F85C8CD25A5EF9C169CACC42297BEE608013A460807B93642F9D3328D0 358 | CB93C1B60EC2F95B7AF324D420904BE4FED5D06E2091A9467757D74E00966929 359 | 95C9899159809E9E1E75CCB14B646747BB009089F7C73B893065346A7FEEDC79 360 | 2022CC9A35DB7B6DC1820558B870A1B3AE1F83A6712C5FBEDCDB7A5D4A092925 361 | 4E3CF123905ED64D00D202CC2C904EA0ACBF17C68E5D080EA4117F67135AEEBA 362 | 2BBAE8E73F5D1C9A30A1071515D96202B8EEA0B6B6769D1062433C1E9FD9D7D7 363 | B7482915D4348D344D334DD3D4A594923196894422BB9B9A9ADE186ED4BBC7EE 364 | 353F3A6DA0ED8D46DBC43B696A2661097B593B2508B01C2228723AC0FC6EA190 365 | 168A9CA65026BD29F26AC8FC802A594424DF27F6A763B9E6DD6FEFB55DB9522A 366 | 374211688B9FB473F561BEF2F24B9BCE39FD8C297609F7BD867AE4ACC2C1A169 367 | 1CDCA9EDDBCD13C2977DF475BE2A09481330B240A20FD4B617FACEDDD0321676 368 | DFFD67A4B66CC2A48F2E4567E733B3C66B676FD588E2C301C639B76A6A6A36D6 369 | D4D46C744DBD6559014DD30CA2D169F47DDB562C6E7EF13F4E20B2433E02100E 370 | 0848D399CF22094ADA135E21EDD5CD942312DDD9F145B2AFA0546C773F49C722 371 | 382D655444063574FF8090404722B6CDE97B10131BC2F2A577F68FBC2D3C9DCE 372 | B8B31272AD2DBBD7EEEBE9B960EC9831A306DF5E768543D73938E7608C9C0919 373 | 0A4258BED92CF9B504E09A7D6102B934A86F3FA8B919B4A70D465F0A5B7EFA33 374 | C4AA639874E5198847FBD1DDFB1AC5577FEF9CF99FB8AD8303DD230EAFECFC82 375 | 31DAB0ACBF7DDDD477EFB9FA3C0583DC454F39976096407E869E6BFADDD90E0C 376 | 52DAD64049F22C77814528E1DC957F7E04492812A0529D424564D8970E61DDE6 377 | AE754E982C323935BAC9A1B95C56358E1B2FDADBF61A1BDE5DB7B6B3BB4B3436 378 | 34F091806FAB77065DD77CA31D1042C1302C6F8D1EF77325C1370D209300EDEB 379 | 06EDDA09D69740CFBB5BD17CDB6D9870CA3108CD1B83FD813EC4037DC8980A7D 380 | 9B1E0CE77ED773DDA2ABEF7928182EDF768852EBE8DEF2E4D1EFDC7DF5B94A9A 381 | 9C3933CE39938806E0AC909EAFDE29008A932D063580DC557B2C404906E9B885 382 | C1DADC2F0279412791DB64AA48E497A9A3422D00007DA202BD49F51600A3B24C 383 | 13E99C1C2501B219C5389700CC7DDDDD1D1D1D1DADB470E1E4A1C0678C9C91AE 384 | 79A3DDA9DCC1B28463E65541034449F0A505980628110775EC056DDF0512C0CE 385 | 3FDC83F4867731F3F2B3603532F447BA9164FD48892C5430005DAB42DFEE1742 386 | AFDD7CEA958B3E79DFD3E563A6BF7290B1D776AEFEE9193B57FDF312902262CC 387 | 5EB680294435D89354BD915A347F87034AB349A05C02088059B62570D58654C5 388 | 533FBC2DA87CBC60BE98C25D454D7A5FE2868DDD6A7266E3FAD7DE0160948575 389 | 91354649809E9E1E3567EE3CB1AFBBDB04905ABDFAE977979D79D6645DD78BFC 390 | 3A7340B747BBBB7F8F1012420808218B80A7D2E02B65CF8BCB6540F15E504B33 391 | 78CB1E6406D2D8FA9F3F41454D19A67DF24CA42BD24886F723AB27C09801DD04 392 | 0CC1C1B518480F23D3D74CAFDF72D25913977E6DD6A493BEFCB41E8CB6BE4FE0 393 | A97FEF3BB3B6AFFCFE69BDBB5EA82B58174701114DD8EB237BE79737D96E2F03 394 | F9AC0149001A41590E21ACBC5EE0DE40A68279BF439583F31633BFF8A6828205 395 | A03D59B945082B0EC08C04B918C896D6B4C34E0E4DA7D3CAE62B327B5A9AD7B4 396 | 75745C3465D244706E2B785DD79DD1EE0A3A09D37447BBC8CF8B1C6EA166177C 397 | 61823269D0FE2ED0CE1D603D71EC7F7B3D9A7F7B3B269E7A2CC2F3C76020D68F 398 | 74288E9C968274560E8D71424E10520681730DBCA21156268EDDCFFDB8A9EDCD 399 | DF5D37F9B4EF6C695C74E59AF740049EECDE3165D7EA1F2DED5AFFD0047B9598 400 | 7C431067405950821383B7ECB13BB5CD6709FC8B91B924000794A60041CE5C50 401 | 3B6250D2567FD25D3E51D190E04B9F2D40D13E841DA900DEDEB2EF3547009AC1 402 | 80A63AF7C6D5A80B4D631A1A1814825D5D9DD54434EBDE3F3D7CCF79679F5917 403 | 08E8E09C39820E9052F8809745A3FD00E04B090803944C80B5EF016DDF01A473 404 | D8F1873B91D9B209932F3C19721C47B22C8E4C600026CF4292F4CD4ECEAF1C9A 405 | CCE51F4B918395E985B472605C47CDB4B3527533CED8523363D9CE40A47A3FE3 406 | 5A1F1159BEE44F505AD9AA44D7E6FA7D9B1F9FD1BDF9F169E9FDDB83F9245C3E 407 | 26D339501690DEBA884400711B3567A71C570EF8A6D217A482ECBC81B4BB5D95 408 | 132A2AC16C5228F22C8152430580439590155EDD3FD5FA973B377EBCB7B7E7B5 409 | F288D653571DCDECDCDB2F476D0172D99C629C090039A554CFC37F79F0E58B2F 410 | 5876B1AE7348690B3ACBB26059A248CD8F047C5BFD909101E27D602D2D60BB77 411 | 23D3BD0F5B7EFE3FA81C538DE9579F8D746506A9E87EE402290866382BCB70DF 412 | CA5F4E973267D0752063107202602C8400AB83C82520AC347AB63F11EDD9FEC4 413 | D158F1EDA319D7A1872B11AC9868F0602C971B680B1B890E6E194972D73AB68B 414 | 3ACC5E9206EE1EE70A214D21E4F8FCE2D53ADD30BE608328E65F4A810A7B84B9 415 | E3F9B8230E056C4BE0B306CACD1FF8C66B5E610C2E12642CC2C67DE5EB7A7B7B 416 | F600C88543BA9535D47B5B252C1EEF5353A64C95BD3D3D0680D4DB6BDF7C72D3 417 | D66D17CD983A8D4C33AFE6475AD2F5C0570A1002944D83F67783EDDC09D6D58D 418 | AE575F43EB3DF760D2E94B105ED080447902E9F0000C2D0DC59C553D9DDD46FC 419 | 7B0FB98F3908318D10960AA99C842101E21C4C69CED635CA33A046A61746A637 420 | 007B3E800778FE7A9297ADB18107423CBF8975C1BB8AB68921778E5FD1D2B3DE 421 | 96393E2AB8CBE7D92E01805090826C4B2098E3DE0B2D010D63093A06A2787B6B 422 | F76A0003008CA0AEC9546EE856B6032E12954AA765341AB552A9547AF3C60D9B 423 | DF7873EDCEA6C6A6697E253F2AF0A5B4C14F0E80757480B66F85EAE9C3D63FDC 424 | 895CCB2ECCFAF832C8713A06CAE3C886123079CEC990B102930F0C2680FB1B74 425 | 0E54700B39066495425612A4BBE2C8486AAF8EF9D51810E00A41EE9E231B345D 426 | CF03D423017C2B83233FF99315AE36AE06057C8E3690042608EE92CACA4B273B 427 | 6EC397421C3CFE159A339392EFBCBBEA0500A958583734CE654F3CF1DED709CC 428 | 6633AAAABADA4AA55259007D7FFED303AB4F59BA745A6D4DCDE8C08703BE6980 429 | F5F5825A5BC076ED427A7733B6DEFA2B548DAF43D3D567235B63201DED432E98 430 | 82C54D6773095E00F2F0042028290112D035051E5408EB7671C6148025ED704B 431 | 2A2A00C1DD2E9611A033059DE577248542A19273378BF0FEF6B182E581A7823C 432 | BD7F07B17CB3BBDFB8BBD680389CBD2229EF16A47373C057BEDFE1FE979E34C7 433 | 1B3BB22F99A6D105201B0C6A563A27864D691F9000FDF1B8AAA8A810B0A75125 434 | 5F78F6E995EBD6AFBFECACD34EAB1E39F8D25EEC299705DBBFCF36F97BF7A2F3 435 | F9E7B1E7914730E98CE311593016A9CA3432D101987A0E82097B979092E6DEFD 436 | BFBE3D687C729BEC9568BDC5291931047485805EA266A60A97861FFC069FFD56 437 | 45CF2B3F90285CAE058E4B50EE025885AB9E945A6DCF9B44A608E0F60E6C4A92 438 | 33B33CAF0DF2BAA0A05880ED0363AD97DFDAF4A063FEB3D5B190D8B6A7EFFDAF 439 | 159C4AA6644D4D8DD9D3D393CE6432EDF7DE73D713C71E75D4C7AB2A2B0F003E 440 | 404A808400A592601DEDA06DDBA0DADAB0E5CE3B61747560F627CE856C0A2051 441 | 9140369C84D00C4852CE3673FE3589293FD3A64000FA2D00BC8C0A0967E93446 442 | 45337446D16B5762E40F2640E137917F8D231F09BC420D292F7EA341CBC0FB44 443 | A2B237C9860414578050B645F05B029927416F86E3A5EDFC95AEAEF62D00D2D1 444 | 9066660C71C082D6880890CD6650573F46F4F4F46401C49F59F5C4A3EF5C73ED 445 | 05A79D7452F9F0E04B906180FAE3602DCD603B7722B57113B6FEFEF7A89E3416 446 | 13AF59866C8D814C6C00B9600652B36C935F64DAA930B82EF19CDF02486F172E 447 | 2282F294FC7BECBF578582B0B89447CA9FB12B8ACBDD5C805F0FF8B69729EE0E 448 | F2AD9BE5ACA969AFC06EAFC74BF6AC430990F411C1997DB4BDBF56BEF8C6E63F 449 | 01E80590A92A0F5B69431C9CFD0252A9948A2493221C0EE732994C726060A0E5 450 | BE7BEF5975CCE2C59755949797065F58A06C16BC673F68E70E50730B3A56AD42 451 | DBD34F61F2592722B2701CD2D51964A22998C11C24930031675FE16273CFF29B 452 | 539422872F01AF24151805C6F87B07BF406AD301ACC050FADC9FABB7C9E05A02 453 | 3FA7E10BEDA844B95F31F2A201BBC1CBCD23300C64185ED91178BDADAD753D80 454 | 4434A4651963A2A72F71F0368CC864D22A162BB732F6AC89BE554F3CFEC8E557 455 | 5C79D699A79E5A41BEADDB2015485A60C91458673BD8B66D103BB663DB1FEF82 456 | D5DF8B39575F00393184646512B968069666DA0D93DECEA28347BB3FDECF9BF3 457 | C23D88FD4BAA2BE1CC9367E4DB3D04EF93045488AD2AA10D4A9180F21D40DE2A 458 | 688348A00ABEDEBFBF747E753572D2CAB635703767850436B6558967D66C7C00 459 | F6BA07E9AAF2B07920F1376A02249349158E445C2B90E8EDE9D9F9EB5FDDFAA7 460 | D933677EA6695C63FEC44C03ACBF0FBCA505B4633B126FBC896DF7DE8BDA694D 461 | 68B8E43C64EB2C642B9230C319086E394BCFF322300BCDFA50A4F00883BCF977 462 | 17492052765C4F07699AC57024F087658A8A3B34F2337FA970A52F8F044C0DCA 463 | 13946EF6C81797C8118AED718627DFC1D37BF6B4AE03900090658CC4FE118CFE 464 | 5111C0E99055B158CCCCD8DD223D4FAC7874C599679D7DD2F5D75D3B838340B9 465 | 0C784F0FD8CE1DA0EDDBD0FED80AB4AD790553CF598AC8A2714857E7902DCF40 466 | 040D08A600D2F20A7CD0681E2ADC439116C857C8F2519774F2067CD07E3B0785 467 | 0005E0175A01523478DE27A9C1A1A06F1731288704BE53540A43B3C1493C0810 468 | DEEA1CDBBB62D5737703E802901A575F66A40D31E22D644745806422A122A190 469 | 8884C3B974269300B0F7F65FDF7AE709471FF3FDA3A64ED678473BD8B6ADB0D6 470 | AFC7B6BBEF86CCA531EF53CB21278591AAC9C188A661E9F60EA28C7869535FCA 471 | D717287E0C127F9E7A9676778EBD84AC9B3F3888C7B056A0582C16B56C150B43 472 | 5F0187C8D72E4EF095C78BFF7F61F3C8E6EE00EE59D17A5F2A95DA01602012D2 473 | 328C91D8DF9B3C741B4766D21955192B37D3994C8A80BE8E5D3BDF7EFA4FF7BF 474 | 3CF7E28B4E29DBB51389E79FC7D607FF8CBA595331F6ECD390AB97C855656084 475 | 73909AB31FD0A0C44E7E14178676189E00FED8DF6FFE017B69197508A65C8EC0 476 | 150C4A27176FF64885E290942C8C0E30C4DC01DFD7273284A7D6576E7CF38D57 477 | 9F84BDEA49AA3C163452596B541B488F9A00895452559745C5B8DADAECBE783C 478 | 313E16DBD7F7C66BCFB7D7542F8E3CBBBABCF3B5573175D949882C1E8F4C9D85 479 | 5C450E56D080E476C70C2B19BB0F11DAF9DE437EF1576AAB58E91B3D8CF29D34 480 | 879200C52E40158BC212A91EF2258D088EE9F7ED1AE6DF88BAC4C79553407DB9 481 | B93A71DF836FFD16F6B23703E110CF10207AE39943BF79744B57973C7EFA0CAB 482 | AFAF2F5D110CF6D770DED2B272C5B6FABDBB8F99F3D98B404D51A46B0D986539 483 | 88802DF41815FBED626187C1C99D12A37DF067DDC127BDEA1C11CB0BAB43710C 484 | 110E8EC80A386FC96F3E69B77D91DB04EB2E9EED6D25E72F4FD8AB2CBFD51A50 485 | BFB9B7F9CEEEAEEE754EDC9FAAAF8998F18439EA93D6DEEB3590B9AC9CDFD898 486 | 4D19465F672AB5ADB9BAFA71B9ECA486FAE9A1F1C1DA1CAC8809C9A5BDB4DB20 487 | E156ECCB7D041832C133CC7B9C8D19ECD1EF166D0887F42826C1504418CA920F 488 | D2042A1F2EBA7FB3C2FD1400A0A507F8F38BDAD3EBD66D5E057BC5B344657930 489 | 97CA0AD93F90FDE008F07A6BAB3A77F264B1A5AF2FF14E47476B6F32F96C664F 490 | 6BFA9CAAE9379D373156C57514AAFC92611D068776C01082AF8800DE679C75F2 491 | 653EFB57D0B67548095094241A05090A6A077E1214AD0E0E9F3B48641456AC8D 492 | EDBAFF81957F04D00AA03F14E4E95050B33AF7A5E47B390DEDFD5C03CB34D48C 493 | CA0A6353BCAF77C7C0004920B7F19E9EF2F28653BE71F2DC608815C4E1C3B900 494 | 14297E94D609C516C4358E52DAC9240628C50EBEFA7F3F51C181C6649125B04F 495 | 313F5D0CCC2646D65478664B59EFED77ADB95508B1C331FD89DAEA88319034E4 496 | 7B3D85F73D4E4E686CA08434B50D9D3D1100D500C64F9F5C7BD58F6F3AE3734B 497 | A607B5E1553D861484BEA26BE16BAC48242A09257290560ACA4A4349CBB757CF 498 | 0741022A51CE1B0D0954C1E9E4C34147103209532A3CB92198FA979FBFF1F3B6 499 | BDEDAB01B400E8A9AF89A42CA1CCD10ABF834A0000985E5FC52C487D77777F14 500 | 402D80A679331BAEFDAFEF9EF9F1859302AC387D3B28DE776FACB0FC4AAC3479 501 | 0AB6AB5102CAC8405A49289145A9B5F03E7057E09181868E1E0685877E6BA0BC 502 | 684040E1E90DCCF8E1CDEB6ED9B9B3791580DD00F6579607139ACE8DFD3DE9F7 503 | C5F683E6291B6AA2AC2F910DE40C1173483071C9E2A6CFFFF83BA75F346B7C90 504 | BCE6381F19A800F42290FD65E0E21A804B1EA5A0A40965A66D0B208C0F76F497 505 | 22811ACE250C5133A0D2BA4041E1B94D4AFCF8F75B6F7FE79D8D8F39E0EF0B06 506 | F840452C94EBEE49BD6FB61F340284021A9595055822990B3A24A80330F9B48F 507 | 4CBFE19FBE7CF2B2399342841271FE605780D26160B13680DDDBA7440ECA4841 508 | 5A19B7C91E1FCAA186B002831E0F9724CABF2494C2731B95F8E57DBBEE5EF3EA 509 | 9B0F03D809A03B18E0FD15E5A15C326D8A74DA78DFB1AE76B0CE3F6B580A29C8 510 | 5859D0403297CC19820160CFBEBCFD57896436F3EF372DBB78D1B408F354BAEF 511 | ACA964F267B026C84700282C9D119C1675061C8CEADF41B702A311848029249E 512 | 5C87DC4FEF58F7870D1B373D056017807D76C8173E68E01F540BE01EE1A04665 513 | 65413E90C88672862877DDC1DC99632FFFD1DF5F78C59239653AF356FD2E55D5 514 | C3B004281839D284128EF9B7CC0F6FF48F86041826414940C69058F116923FFE 515 | F58BBF6B6E6E7EC1077EBCB23C9CB584B492A9DC41CB721D9268391CD2A92C1A 516 | E0FB7A5221002E09C64F9F5C7FE1BF7E77F935272DAA0A07037C087750D4438D 517 | 21C8E0A87F65A5A084BBA3A6FAF0092087204129175174C4531656BC49BD3FBE 518 | F5E9DBDADBDBD6386A7F3F80FECAF270C612CA4AA6B207F5240F59BA2414D4A8 519 | 2C1AE403C96CD0B02D4135807163EA2A4EF9C60D677DE6D233A78CA9AB0A0CB2 520 | 04C3EA035FEE5F490B4A661D02649DD1FF2113E040510160AF1530C832003BDA 521 | 0DDCF36C6AC79D0F3C77474FCFFE7500F638E00F54C4C259CB92562A933BE827 522 | 7848F365C1804665D1004F247301C3143187040D04CCFBECA74EBFE6FA2B8F39 523 | 6AFAC4081D68E45371D3A75250CA72C04F4349B368E81D2E24A061B6F67396D2 524 | 31155EDA98937F78B4E3A98757AC5AA194DA0AA0DD49F40C94978573A69056E6 525 | 10807FC80900008180466591004BA47241D3145100558E4B987CD4824917FDF3 526 | DF5DB27CC9DCAA6028C887D600285C7F50290148034A38E65F8AC363F41F480F 527 | 1411A1B7DFC4CA37ACFE5FFCEEC5FBB76EDBBEC655FA00FA023A4FC6CAC2B974 528 | C614996CEE909D1C7D10D742D73885C33ACB640CDDB464044085EB12EA6B2B8E 529 | FFFC75675DF9D173E74C9E323E5254F62D45067B1AB912599B00D27026DDE330 530 | 2640A100344D89B55BB3EABE55DDEF3CF4D8CB0FF5F5F56C845DD6DD0FA05FD7 531 | 783A1A0D1A998C2972867948994D1FE4358946028C73A60F24B22100650E09EA 532 | 004C3DF6A869677EE3C60B967DE4E831E535E581215C826BFE6DF5AF441A50E6 533 | C8A67C1D16240076EDCD62E5ABD9CE3BEE5FF3D8962D5BD73A2ABFCB35F99150 534 | 20C339B33239535A9638E427461FF435090634A6699C1BA615705C826B0DC632 535 | 4633AFBEF28C8BAEFFD4C94B664E2A6391102FCE93DA3B6ECAAC63FA33CEE83F 536 | FC09B0BFD7C4CB1BB2B9BB1FDEB17AD5AA179EB384B5DBF1F53DB057244F9545 537 | 43592195C8645B9398D6000003ED49444154721F98A0A10FE3BA681AA7505067 538 | D9ACA15B42861D6B50E910617CC398EA451FBB64E9599FF8E8F1F3A74E88B2B2 539 | B096BF9ECA0244164AA61DF32F0F5F0200E8DC9FC39B9B73C69F57EE7A7DF573 540 | 6B9FEFE9D9BF137629773FEC6D6C129AC6D29170D0CCE64C6118D6077A32F461 541 | 5E9C6040639C336E98226859220220E610A106C0B89A9AF299975D7CF299D75E 542 | B174D1D40965BC3CCAA19409C8B413FA998725F84A016D5D19BCBE2997F9F3E3 543 | 5B5F7BF6B9B52FC5E37D7B1C3FBFCF19F10300D2D1483027A4B20CC35252CA0F 544 | FC64E8C3BE589C330A043426A5D473392B087BEFBE72E7560D606C792C32EDC2 545 | F34E38E5F24B3FB270EAF8606C7C3D10D4CCC36EF40F244D6C6F4DE1CD4D46F7 546 | 93AB37AE7BF1E577D624138936006D8E8FEF87DDBB9FE29C6543C18099334CF1 547 | 41F8FAC396003EB7C082018D6573A62E840C39442873885009600C808685F3A7 548 | CC3BE6A8C98B2E3D6FCE9C498D41BD696CC4D9A1F3C339D2190BCD6D696CDC69 549 | A6563CB365FDDAB75BD66DDBB66DB713CE7502E873467BD2055ED3B829A51296 550 | 2594521FAE823D6C08E0447CC43927C6880B4BEA42CA20803080A8E31E624E1E 551 | A18E080D272F9DB770DCD88AC9179CBD70EAC471C18A86BA101A6AC3D0F8A13B 552 | AD9C21D1D69D46E73E436DDA95DBFFC2CB9B77EE6AEEDFF9D65BEB364B297B1C 553 | 13EF073D0920CD39CB39C05B8703F0872501FCBF8B73468C312E84D0A4540187 554 | 08619F652873C8500DA0BCB23236F6F8E366CC1CDB503EFE8C93E736358E0956 555 | 4643C42A62015496075011D3A1F1915B0AC31488274CF4F51B48A44CF42560ED 556 | 69CFF6BCFCDAB696E6D678DBBBEF6EDF1A8FF7B940F739263E017B4FE2B473CB 557 | 32C6729AC62C29218410F27001FE702780F7FB1823D23863422A4D08A9010802 558 | 0839B7887373AD4485E332CA00446A6BABABE7CC9E38B6B25CAFD5033CD638B6 559 | 3E525B531EAAAA8C846265C16059440B0674A6A573D24CA5ACDC4032978DF7A7 560 | B33D3D03D9EE7D3DA964D24AF4F51BDD3B76B476ECDFBF7F00F6B2AB29C797F7 561 | FBC0CEF8EEB300729AC64D2808A99470C4DD6119AA1CEE0428F89D8C11233B55 562 | A8092175D80B3C051C52F88911F23DEF5A8E10001DF68C110EBB71C0BDF7265D 563 | C35E175102301DC0333E600DE73EEBBCE6DE1B000C22328960113129A5104A0D 564 | 4A071D21C041FACDE4108101E04A290EBBB9C52585EEDCB4A2BF5DF0C977EF2D 565 | E4E9002F7D44706FA6EFDE74003701588C9125A5128C9194D20B4BD45FD3C5FC 566 | 6B3EC8470852764B907F74BB7F6B4523DEFD5CF1EECEB28808A2E8E63E271923 567 | 21A52A6CE4FF2BBD807F4B47F19A1B7EA06988D78B13B7AAC44D0EF1FADFC405 568 | FB5B3F68047F179360B8BF8F1C478E23C791E3C871E4F85B38FE3FF52F073A2C 569 | 1146B50000000049454E44AE426082 570 | } 571 | end 572 | object btnClose: TButton 573 | Left = 288 574 | Height = 25 575 | Top = 136 576 | Width = 112 577 | Anchors = [akRight, akBottom] 578 | Caption = 'Okay, he!' 579 | OnClick = btnCloseClick 580 | TabOrder = 0 581 | end 582 | object lblAppName: TLabel 583 | Left = 144 584 | Height = 16 585 | Top = 8 586 | Width = 202 587 | BorderSpacing.Top = 8 588 | Caption = '<Application Title goes here>' 589 | Font.Style = [fsBold] 590 | ParentColor = False 591 | ParentFont = False 592 | end 593 | object lblAppInfo: TLabel 594 | Left = 144 595 | Height = 16 596 | Top = 24 597 | Width = 195 598 | Caption = '<Version and Date goes here>' 599 | ParentColor = False 600 | ParentFont = False 601 | end 602 | object lblAuthors: TLabel 603 | Left = 144 604 | Height = 16 605 | Hint = 'http://www.sizious.com/' 606 | Top = 48 607 | Width = 174 608 | Caption = 'Created in 2015 by SiZiOUS' 609 | Font.Color = clHighlight 610 | ParentColor = False 611 | ParentFont = False 612 | OnClick = lblAuthorsClick 613 | OnMouseEnter = lblAuthorsMouseEnter 614 | OnMouseLeave = lblAuthorsMouseLeave 615 | end 616 | object lblPoweredBy: TLabel 617 | Left = 144 618 | Height = 16 619 | Top = 72 620 | Width = 235 621 | Caption = 'Powered by gditools.py by FamilyGuy' 622 | ParentColor = False 623 | end 624 | object lblCredits: TLabel 625 | Left = 144 626 | Height = 16 627 | Top = 88 628 | Width = 302 629 | Caption = 'Inspired by GD-ROM Explorer by Japanese Cake' 630 | ParentColor = False 631 | end 632 | object lblIcons: TLabel 633 | Left = 144 634 | Height = 16 635 | Top = 112 636 | Width = 305 637 | BorderSpacing.Right = 10 638 | Caption = 'Icons created by Oxygen-Icons.org and Iconleak' 639 | ParentColor = False 640 | end 641 | end --------------------------------------------------------------------------------