diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..565c1d5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+/backup/
+*.log
+*.o
+*.or
+*.ppu
+*.compiled
+
+Copier
+Copini
\ No newline at end of file
diff --git a/Copier.lpi b/Copier.lpi
new file mode 100644
index 0000000..36d3455
--- /dev/null
+++ b/Copier.lpi
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Copier.lpr b/Copier.lpr
new file mode 100644
index 0000000..f2f8f02
--- /dev/null
+++ b/Copier.lpr
@@ -0,0 +1,14 @@
+program Copier;
+
+uses
+ Forms, Interfaces,
+ Main in 'Main.pas' {frmMain};
+
+{.$R *.RES}
+
+begin
+ Application.Initialize;
+ Application.Title := 'Copier';
+ Application.CreateForm(TfrmMain, frmMain);
+ Application.Run;
+end.
diff --git a/Copier.lps b/Copier.lps
new file mode 100644
index 0000000..921cc26
--- /dev/null
+++ b/Copier.lps
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Main.lfm b/Main.lfm
new file mode 100644
index 0000000..e2fdeb8
--- /dev/null
+++ b/Main.lfm
@@ -0,0 +1,138 @@
+object frmMain: TfrmMain
+ Left = 140
+ Height = 294
+ Top = 201
+ Width = 397
+ Caption = 'Midnight Copier'
+ ClientHeight = 294
+ ClientWidth = 397
+ Color = clBtnFace
+ Constraints.MinHeight = 190
+ Constraints.MinWidth = 250
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ KeyPreview = True
+ OnClose = FormClose
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ OnKeyDown = FormKeyDown
+ OnResize = FormResize
+ Position = poScreenCenter
+ LCLVersion = '1.8.4.0'
+ object Label5: TLabel
+ Left = 135
+ Height = 13
+ Top = 277
+ Width = 249
+ Anchors = [akRight, akBottom]
+ Caption = '©2004 Copyright by Midnight Entertainment'
+ ParentColor = False
+ end
+ object iProgress: TImage
+ Left = 8
+ Height = 25
+ Top = 80
+ Width = 380
+ Anchors = [akTop, akLeft, akRight]
+ OnPaint = iProgressPaint
+ end
+ object Label1: TLabel
+ Left = 8
+ Height = 13
+ Top = 16
+ Width = 32
+ Caption = 'From:'
+ ParentColor = False
+ end
+ object Label2: TLabel
+ Left = 8
+ Height = 13
+ Top = 48
+ Width = 16
+ Caption = 'To:'
+ ParentColor = False
+ end
+ object eSrcFile: TEdit
+ Left = 40
+ Height = 30
+ Top = 8
+ Width = 237
+ Anchors = [akTop, akLeft, akRight]
+ TabOrder = 0
+ end
+ object eDestFile: TEdit
+ Left = 40
+ Height = 30
+ Top = 40
+ Width = 237
+ Anchors = [akTop, akLeft, akRight]
+ TabOrder = 1
+ end
+ object bCopy: TButton
+ Left = 315
+ Height = 30
+ Top = 8
+ Width = 75
+ Anchors = [akTop, akRight]
+ Caption = 'Copy'
+ Default = True
+ OnClick = bCopyClick
+ TabOrder = 2
+ end
+ object bSrc: TButton
+ Left = 283
+ Height = 30
+ Top = 8
+ Width = 29
+ Anchors = [akTop, akRight]
+ Caption = '...'
+ OnClick = bSrcClick
+ TabOrder = 3
+ end
+ object bDest: TButton
+ Left = 283
+ Height = 30
+ Top = 40
+ Width = 29
+ Anchors = [akTop, akRight]
+ Caption = '...'
+ OnClick = bDestClick
+ TabOrder = 4
+ end
+ object bCancel: TButton
+ Left = 315
+ Height = 30
+ Top = 40
+ Width = 75
+ Anchors = [akTop, akRight]
+ Caption = 'Cancel'
+ OnClick = bCancelClick
+ TabOrder = 5
+ end
+ object mReport: TMemo
+ Left = 8
+ Height = 164
+ Top = 112
+ Width = 380
+ Anchors = [akTop, akLeft, akRight, akBottom]
+ Color = clBtnFace
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Courier New'
+ ParentFont = False
+ ReadOnly = True
+ ScrollBars = ssBoth
+ TabOrder = 6
+ end
+ object odSrc: TOpenDialog
+ Options = [ofNoChangeDir, ofExtensionDifferent, ofEnableSizing, ofForceShowHidden]
+ left = 232
+ top = 72
+ end
+ object sdDest: TSaveDialog
+ Options = [ofNoChangeDir, ofExtensionDifferent, ofNoReadOnlyReturn, ofEnableSizing, ofForceShowHidden]
+ left = 264
+ top = 72
+ end
+end
diff --git a/Main.pas b/Main.pas
new file mode 100644
index 0000000..e596e28
--- /dev/null
+++ b/Main.pas
@@ -0,0 +1,582 @@
+unit Main;
+
+interface
+
+uses
+ SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
+ StdCtrls, ExtCtrls, LCLType;
+
+type
+
+ { TfrmMain }
+
+ TfrmMain = class(TForm)
+ eSrcFile: TEdit;
+ eDestFile: TEdit;
+ bCopy: TButton;
+ iProgress: TImage;
+ Label1: TLabel;
+ Label2: TLabel;
+ bSrc: TButton;
+ bDest: TButton;
+ Label5: TLabel;
+ odSrc: TOpenDialog;
+ sdDest: TSaveDialog;
+ bCancel: TButton;
+ mReport: TMemo;
+ procedure bCopyClick(Sender: TObject);
+ procedure bSrcClick(Sender: TObject);
+ procedure bDestClick(Sender: TObject);
+ procedure FormCreate(Sender: TObject);
+ procedure FormDestroy(Sender: TObject);
+ procedure bCancelClick(Sender: TObject);
+ procedure FormKeyDown(Sender: TObject; var Key: Word;
+ Shift: TShiftState);
+ procedure FormResize(Sender: TObject);
+ procedure FormClose(Sender: TObject; var Action: TCloseAction);
+ procedure iProgressPaint(Sender: TObject);
+ private
+ { Private declarations }
+ public
+ { Public declarations }
+ end;
+
+ PZone = ^TZone;
+ TZone = record
+ sStart : integer;
+ sEnd : integer;
+ BlkSize : integer;
+ Error : boolean;
+ Prev : PZone;
+ Next : PZone;
+ Current : boolean;
+ ErrZone : boolean;
+ end;
+
+const
+ MaxBlkSize = 4096;
+ MinBlkSize = 4096;
+
+var
+ frmMain: TfrmMain;
+
+ Cancel: boolean;
+ CurZone: PZone;
+ ErrZones: PZone;
+ fSize: integer;
+ InfoFile: string;
+ IniFile: string;
+ OldTime: double;
+ LockCopy: boolean;
+ CancelErrors: boolean;
+
+implementation
+
+{$R *.lfm}
+
+function IntToStrEx(Value: integer): string;
+var
+ str : string;
+ n : integer;
+begin
+ str:=IntToStr(Value);
+ Result:=''; n:=0;
+ while length(str)>0 do begin
+ Result := str[length(str)]+Result;
+ str := copy(str, 1, length(str)-1);
+ Inc(n);
+ if (length(str)>0) and (n=3) then begin
+ n:=0;
+ Result := Chr(39)+Result;
+ end;
+ end;
+end;
+
+function UpInt(Value: Extended): integer;
+begin
+ Result := trunc(Value);
+ if Resultnil then begin
+ Zone.Prev := Zone.Next.Prev;
+ Zone.Next.Prev := Zone;
+ if Zone.Prev<>nil then Zone.Prev.Next:=Zone;
+ end else Zone.Prev := nil;
+end;
+
+procedure AddZoneAfter(Zone, ZoneListItem: PZone);
+begin
+ Zone.Prev := ZoneListItem;
+ if Zone.Prev<>nil then begin
+ Zone.Next := Zone.Prev.Next;
+ Zone.Prev.Next := Zone;
+ if Zone.Next<>nil then Zone.Next.Prev:=Zone;
+ end else Zone.Next := nil;
+end;
+
+procedure RemoveZone(Zone: PZone);
+begin
+ if Zone.Prev<>nil then Zone.Prev.Next:=Zone.Next;
+ if Zone.Next<>nil then Zone.Next.Prev:=Zone.Prev;
+end;
+
+function FindFirstZone(Zone: PZone): PZone;
+begin
+ Result := Zone;
+ if Result<>nil then while Result.Prev<>nil do Result:=Result.Prev;
+end;
+
+procedure DisposeZoneList(var Zone: PZone);
+var
+ z: PZone;
+begin
+ Zone := FindFirstZone(Zone);
+ while Zone<>nil do begin
+ z := Zone.Next;
+ Dispose(Zone);
+ Zone := z;
+ end;
+end;
+
+function FindMaxZone(Zone: PZone): PZone;
+begin
+ Result := FindFirstZone(Zone);
+ Zone := Result;
+ while Zone<>nil do begin
+ if ((not Zone.Error) and Result.Error)
+ or ((Zone.Error=Result.Error) and ((Zone.sEnd-Zone.sStart)>(Result.sEnd-Result.sStart))) then
+ Result := Zone;
+ Zone := Zone.Next;
+ end;
+end;
+
+
+procedure MoveToError(Zone: PZone);
+var
+ z : PZone;
+begin
+ RemoveZone(Zone);
+
+ z:=ErrZones;
+ while (z<>nil) and (z.next<>nil) and (z.sEndnil) and (z.sEnd<=Zone.sStart) then AddZoneAfter(Zone, z) else AddZoneBefore(Zone, z);
+
+ if (Zone.Prev<>nil) and (Zone.Prev.sEnd=Zone.sStart) then begin
+ Zone.sStart:=Zone.Prev.sStart;
+ z := Zone.Prev;
+ RemoveZone(z);
+ Dispose(z);
+ end;
+ if (Zone.Next<>nil) and (Zone.Next.sStart=Zone.sEnd) then begin
+ Zone.sEnd:=Zone.Next.sEnd;
+ z := Zone.Next;
+ RemoveZone(z);
+ Dispose(z);
+ end;
+
+ ErrZones := FindFirstZone(Zone);
+end;
+
+procedure GenerateReport;
+var
+ z : PZone;
+ str : string;
+ Text, ns : string;
+ ncp, dmg : integer;
+begin
+ if fSize=0 then exit;
+ z := FindFirstZone(CurZone);
+ ncp := 0;
+ ns := Chr(13);
+ Text := 'Remained Blocks:'+ns;
+ while z<>nil do begin
+ str := IntToHex(z.sStart, 8)+':'+IntToHex(z.sEnd, 8)+' - ';
+ if z.Error then str:=str+'Read Error' else str:=str+'Copying';
+ Text := Text+str+ns;
+ ncp := ncp+z.sEnd-z.sStart;
+ z:=z.Next;
+ end;
+
+ z := ErrZones;
+ dmg := 0;
+ Text := Text+'Damaged Blocks:'+ns;
+ while z<>nil do begin
+ str := IntToHex(z.sStart, 8)+':'+IntToHex(z.sEnd, 8);
+ Text := Text+str+ns;
+ dmg := dmg+z.sEnd-z.sStart;
+ z:=z.Next;
+ end;
+
+ str := 'Damaged: '+IntToStrEx(dmg)+' ('+FloatToStr(round((dmg)/fSize*10000)*0.01)+'%)';
+ Text := str+ns+Text;
+ str := 'Remained: '+IntToStrEx(ncp)+' ('+FloatToStr(round((ncp)/fSize*10000)*0.01)+'%)';
+ Text := str+ns+Text;
+ str := 'Copied: '+IntToStrEx(fSize-ncp-dmg)+' ('+FloatToStr(round((fSize-ncp-dmg)/fSize*10000)*0.01)+'%)';
+ Text := str+ns+Text;
+ str := 'File Size: '+IntToStrEx(fSize);
+ Text := str+ns+Text;
+
+ frmMain.mReport.Lines.Text := Text;
+end;
+
+procedure SaveCopyInfo;
+var
+ f : file of TZone;
+ z : PZone;
+begin
+ if InfoFile='' then exit;
+ if (CurZone<>nil) or (ErrZones<>nil) then begin
+ AssignFile(f, InfoFile);
+ ReWrite(f);
+ z := FindFirstZone(CurZone);
+ while z<>nil do begin
+ z.Current := (z=CurZone);
+ z.ErrZone := (z=ErrZones);
+ write(f, z^);
+ z:=z.Next;
+ end;
+ z := ErrZones;
+ while z<>nil do begin
+ z.Current := (z=CurZone);
+ z.ErrZone := (z=ErrZones);
+ write(f, z^);
+ z:=z.Next;
+ end;
+ CloseFile(f);
+ end else DeleteFile(InfoFile);
+end;
+
+procedure LoadCopyInfo;
+var
+ f : file of TZone;
+ z, z2 : PZone;
+ asked : boolean;
+begin
+ DisposeZoneList(CurZone);
+ DisposeZoneList(ErrZones);
+ asked:=false;
+ if FileExists(InfoFile) then begin
+ AssignFile(f, InfoFile);
+ Reset(f);
+ z2 := nil;
+ while not eof(f) do begin
+ New(z);
+ read(f, z^);
+ if (not asked) and (z.Error or z.ErrZone or (z.BlkSize<>MaxBlkSize)) then begin
+ CancelErrors := mrYes=MessageDlg('Reread error blocks?', mtConfirmation, [mbYes, mbNo], 0);
+ asked := true;
+ end;
+ if CancelErrors then begin
+ z.Error := False;
+ z.BlkSize := MaxBlkSize;
+ z.ErrZone := False;
+ end;
+ if z.Current then CurZone:=z;
+ if z.ErrZone then begin
+ ErrZones:=z;
+ z2:=nil;
+ end;
+ AddZoneAfter(z, z2);
+ z2:=z;
+ end;
+ if CancelErrors then CurZone:=FindMaxZone(z2);
+ CloseFile(f);
+ end else begin
+ New(CurZone);
+ CurZone.sStart := 0;
+ CurZone.sEnd := fSize;
+ CurZone.BlkSize := MaxBlkSize;
+ CurZone.Error := False;
+ CurZone.Prev := nil;
+ CurZone.Next := nil;
+ end;
+end;
+
+procedure DrawZones;
+var
+ z : PZone;
+ s : integer;
+ r, r2 : TRect;
+ str : string;
+ bmp : TBitmap;
+begin
+ with frmMain.iProgress do begin
+ r.Top:=1; r.Left:=1; r.Right:=Width-1; r.Bottom:=Height-1;
+ Canvas.Brush.Color := clBlue;
+ if fSize=0 then Canvas.Brush.Color := clWhite;
+ Canvas.FillRect(r);
+ Canvas.Brush.Color := clWhite;
+ z := FindFirstZone(CurZone);
+ s := 0;
+ while z<>nil do begin
+ r.Left := 1+trunc(z.sStart/fSize*(Width-2));
+ r.Right := 1+trunc(z.sEnd/fSize*(Width-2));
+ s := s+z.sEnd-z.sStart;
+ Canvas.FillRect(r);
+ z:=z.Next;
+ end;
+ Canvas.Brush.Color := clRed;
+ z := ErrZones;
+ while z<>nil do begin
+ r.Left := 1+trunc(z.sStart/fSize*(Width-2));
+ r.Right := r.Left+UpInt((z.sEnd-z.sStart)/fSize*(Width-2));
+ Canvas.FillRect(r);
+ z:=z.Next;
+ end;
+ Canvas.Brush.Color := clRed;
+ z := FindFirstZone(CurZone);
+ while z<>nil do begin
+ if z.Error then begin
+ r.Left := 1+trunc(z.sStart/fSize*(Width-2));
+ r.Right := r.Left+1;
+ Canvas.FillRect(r);
+ end;
+ z:=z.Next;
+ end;
+ if fSize<>0 then begin
+ bmp := TBitmap.Create;
+ str:=FloatToStr(round((1-s/fSize)*1000)*0.1)+'%';
+ bmp.Width := bmp.Canvas.TextWidth(str);
+ bmp.Height := bmp.Canvas.TextHeight(str);
+ bmp.Canvas.Brush.Color := clBlack;
+ bmp.Canvas.Font.Color := clWhite;
+ bmp.Canvas.TextOut(0, 0, str);
+ r.Left:=trunc((Width-bmp.Width)/2);
+ r.Top:=trunc((Height-bmp.Height)/2);
+ r.Right:=r.Left+bmp.Width;
+ r.Bottom:=r.Top+bmp.Height;
+ r2.Left:=0; r2.Top:=0; r2.Right:=bmp.Width; r2.Bottom:=bmp.Height;
+ Canvas.CopyMode := cmSrcInvert;
+ Canvas.CopyRect(r, bmp.Canvas, r2);
+ bmp.Free;
+ end;
+ Canvas.Brush.Style := bsClear;
+ Canvas.Pen.Color := clBlack;
+ r.Top:=0; r.Left:=0; r.Right:=Width; r.Bottom:=Height;
+ Canvas.Rectangle(r);
+ Canvas.Brush.Style := bsSolid;
+ end;
+ SaveCopyInfo;
+ GenerateReport;
+ LockCopy:=True;
+ Application.ProcessMessages;
+ LockCopy:=False;
+ OldTime:=Time*24*3600;
+end;
+
+procedure CopyFile(Src, Dest: string);
+var
+ SrcFile : file;
+ DestFile : file;
+ e : integer;
+ Res, IORes : integer;
+ z : PZone;
+ Buffer : array[0..MaxBlkSize] of byte;
+ DlgRes : Word;
+ rewr : boolean;
+begin
+ InfoFile := Dest+'.copyinfo';
+ if not FileExists(Src) then begin
+ ShowMessage('Source file not found');
+ exit;
+ end;
+ rewr:=true;
+ if FileExists(Dest) then begin
+ if FileExists(InfoFile) then begin
+ DlgRes := MessageDlg('Do you want to continue last copying of this file?', mtConfirmation, mbYesNoCancel, 0);
+ if DlgRes=mrNo then DeleteFile(InfoFile) else
+ if DlgRes=mrYes then rewr:=false else exit;
+ end else begin
+ DlgRes := MessageDlg('Destination file already exists. Do you want to overwrite it?', mtConfirmation, mbOkCancel, 0);
+ if DlgRes<>mrOk then exit;
+ end;
+ end;
+ AssignFile(SrcFile, Src);
+ AssignFile(DestFile, Dest);
+ FileMode := fmOpenRead;
+ Reset(SrcFile, 1);
+ fSize:=FileSize(SrcFile);
+ FileMode := fmOpenReadWrite;
+ if rewr then ReWrite(DestFile, 1) else Reset(DestFile, 1);
+ LoadCopyInfo;
+
+ {$IOCHECKS OFF}
+ while CurZone<>nil do begin
+ if Cancel then break;
+ if CurZone.Error then CurZone:=FindMaxZone(CurZone);
+ if CurZone.Error then begin
+ e := (trunc((CurZone.sStart+CurZone.sEnd)/2) div MinBlkSize)*MinBlkSize;
+ if e<=CurZone.sStart then e:=e+MinBlkSize;
+ if e>=CurZone.sEnd then begin
+ if CurZone.Prev<>nil then z:=CurZone.Prev else z:=CurZone.Next;
+ MoveToError(CurZone);
+ CurZone:=FindMaxZone(z);
+ end else begin
+ New(z);
+ z.BlkSize := MaxBlkSize;
+ z.sStart := e;
+ z.sEnd := CurZone.sEnd;
+ z.Error := False;
+ CurZone.sEnd := e;
+ AddZoneAfter(z, CurZone);
+ if CurZone.sEnd-CurZone.sStart<=MinBlkSize then MoveToError(CurZone);
+ CurZone := FindMaxZone(z);
+ end;
+ DrawZones;
+ end else begin
+ if CurZone.sEnd-CurZone.sStart>0 then begin
+ Seek(SrcFile, CurZone.sStart);
+ if CurZone.sEnd-CurZone.sStart0 then Res:=0;
+ if Res=0 then begin
+ if CurZone.BlkSize<=MinBlkSize then CurZone.Error:=True else CurZone.BlkSize:=MinBlkSize;
+ end else begin
+ Seek(DestFile, CurZone.sStart);
+ BlockWrite(DestFile, Buffer, Res);
+ end;
+ CurZone.sStart:=CurZone.sStart+Res;
+ if Time*24*3600-OldTime>=0.05 then DrawZones;
+ end;
+ if CurZone.sEnd-CurZone.sStart<=0 then begin
+ if CurZone.Prev<>nil then z:=CurZone.Prev else z:=CurZone.Next;
+ RemoveZone(CurZone);
+ Dispose(CurZone);
+ CurZone := FindMaxZone(z);
+ DrawZones;
+ end;
+ end;
+ end;
+ {$IOCHECKS ON}
+ CloseFile(SrcFile);
+ CloseFile(DestFile);
+ DrawZones;
+ DisposeZoneList(CurZone);
+ DisposeZoneList(ErrZones);
+ if not Cancel then beep;
+end;
+
+procedure ClearVars;
+begin
+ Cancel:=False;
+ CurZone:=nil;
+ ErrZones:=nil;
+ LockCopy:=False;
+ CancelErrors:=False;
+ InfoFile:='';
+ fSize:=0;
+end;
+
+procedure TfrmMain.bCopyClick(Sender: TObject);
+begin
+ if not LockCopy then begin
+ ClearVars;
+ SaveIni;
+ CopyFile(eSrcFile.Text, eDestFile.Text);
+ ClearVars;
+ DrawZones;
+ SaveIni;
+ end;
+end;
+
+procedure TfrmMain.bSrcClick(Sender: TObject);
+begin
+ odSrc.FileName:=eSrcFile.Text;
+ if odSrc.Execute then eSrcFile.Text:=odSrc.FileName;
+end;
+
+procedure TfrmMain.bDestClick(Sender: TObject);
+var
+ n: integer;
+ path, fname: string;
+begin
+ n:=Length(eSrcFile.Text);
+ while n>0 do
+ if eSrcFile.Text[n]='\' then break else Dec(n);
+ fname:=copy(eSrcFile.Text, n+1, Length(eSrcFile.Text)-n);
+ n:=Length(eDestFile.Text);
+ while n>0 do
+ if eDestFile.Text[n]='\' then break else Dec(n);
+ path:=copy(eDestFile.Text, 1, n);
+ sdDest.FileName:=path+fname;
+ if sdDest.Execute then eDestFile.Text:=sdDest.FileName;
+end;
+
+procedure TfrmMain.FormCreate(Sender: TObject);
+begin
+ ClearVars;
+ DrawZones;
+ IniFile := copy(Application.ExeName, 1, length(Application.ExeName)-3)+'ini';
+ LoadIni;
+end;
+
+procedure TfrmMain.FormDestroy(Sender: TObject);
+begin
+ SaveIni;
+end;
+
+procedure TfrmMain.bCancelClick(Sender: TObject);
+begin
+ Cancel:=true;
+end;
+
+procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word;
+ Shift: TShiftState);
+begin
+// if (Key=VK_F2) and (CurZone<>nil) then CurZone.Error:=true;
+ if Key=VK_ESCAPE then Cancel:=true;
+end;
+
+procedure TfrmMain.FormResize(Sender: TObject);
+begin
+ DrawZones;
+end;
+
+procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
+begin
+ Cancel := true;
+end;
+
+procedure TfrmMain.iProgressPaint(Sender: TObject);
+begin
+ DrawZones;
+end;
+
+end.
+
+
diff --git a/copier.res b/copier.res
new file mode 100644
index 0000000..067a453
Binary files /dev/null and b/copier.res differ