diff --git a/Beta/D2Bridge Framework/D2Bridge.API.Mail.pas b/Beta/D2Bridge Framework/D2Bridge.API.Mail.pas index 44be994..08e3190 100644 --- a/Beta/D2Bridge Framework/D2Bridge.API.Mail.pas +++ b/Beta/D2Bridge Framework/D2Bridge.API.Mail.pas @@ -39,7 +39,7 @@ interface {$IFDEF HAS_UNIT_SYSTEM_THREADING} System.Threading, {$ENDIF} - IdSMTP, IdSSLOpenSSL, IdMessage, IdExplicitTLSClientServerBase, IdAttachmentFile, idText, + IdSMTP, IdSSLOpenSSL, IdMessage, IdExplicitTLSClientServerBase, IdAttachmentFile, IdText, D2Bridge.Interfaces, Prism.Server.HTTP.Commom {$IFDEF FMX} @@ -375,4 +375,4 @@ procedure TD2BridgeAPIMail.SetSubject(const Value: string); FSubject:= Value; end; -end. \ No newline at end of file +end. diff --git a/Beta/D2Bridge Framework/D2Bridge.AppConfig.Version.pas b/Beta/D2Bridge Framework/D2Bridge.APPConfig.Version.pas similarity index 67% rename from Beta/D2Bridge Framework/D2Bridge.AppConfig.Version.pas rename to Beta/D2Bridge Framework/D2Bridge.APPConfig.Version.pas index 522a39e..103b0dc 100644 --- a/Beta/D2Bridge Framework/D2Bridge.AppConfig.Version.pas +++ b/Beta/D2Bridge Framework/D2Bridge.APPConfig.Version.pas @@ -30,7 +30,7 @@ {$I D2Bridge.inc} -unit D2Bridge.AppConfig.Version; +unit D2Bridge.APPConfig.Version; interface @@ -38,10 +38,13 @@ interface Classes, SysUtils, IniFiles, TypInfo, {$IFDEF MSWINDOWS} Windows, +{$ENDIF} +{$IFDEF LINUX} + baseunix, + linux, {$ENDIF} D2Bridge.Interfaces; - type TD2BridgeAppConfigVersion = class(TInterfacedPersistent, ID2BridgeAPPConfigVersion) private @@ -68,23 +71,34 @@ TD2BridgeAppConfigVersion = class(TInterfacedPersistent, ID2BridgeAPPConfigVers property Minor: Integer read GetMinor write SetMinor; property Release: Integer read GetRelease write SetRelease; property VersionStr: string read GetVersionStr write SetVersionStr; - end; - implementation - function GetExecutableVersion: string; +{$IFDEF MSWINDOWS} var VerInfoSize, VerHandle: DWORD; VerBuffer: Pointer; FixedInfo: PVSFixedFileInfo; FileName: array[0..MAX_PATH - 1] of Char; +{$ENDIF} +{$IFDEF LINUX} +var + FileName: string; + VersionFile: TextFile; + VersionLine: string; + FileStream: TFileStream; + Buffer: array[0..255] of Byte; + BytesRead: Integer; + VersionStr: string; + Major, Minor, Release, Build: Integer; +{$ENDIF} begin + {$IFDEF MSWINDOWS} Result := '0.0.0.0'; - // Pega o caminho do módulo atual (EXE ou DLL) + // Pega o caminho do módulo atual (EXE ou DLL) if GetModuleFileName(HInstance, FileName, MAX_PATH) = 0 then Exit; @@ -107,9 +121,63 @@ function GetExecutableVersion: string; finally FreeMem(VerBuffer); end; + {$ENDIF} + + {$IFDEF LINUX} + Result := '1.0.0.0'; // Versão padrão para Linux + + // Estratégia 1: Tentar ler do arquivo .version no mesmo diretório + FileName := ExtractFilePath(ParamStr(0)) + '.version'; + if FileExists(FileName) then + begin + try + AssignFile(VersionFile, FileName); + Reset(VersionFile); + try + ReadLn(VersionFile, VersionLine); + VersionLine := Trim(VersionLine); + if VersionLine <> '' then + Result := VersionLine; + finally + CloseFile(VersionFile); + end; + except + // Ignora erros de leitura + end; + end + else + begin + // Estratégia 2: Tentar ler variável de ambiente + VersionLine := GetEnvironmentVariable('APP_VERSION'); + if VersionLine <> '' then + Result := VersionLine + else + begin + // Estratégia 3: Usar data de compilação como versão + {$IFDEF DEBUG} + Result := '1.0.0.0-DEBUG'; + {$ELSE} + Result := Format('1.0.0.%d', [ + Trunc((Now - EncodeDate(2024, 1, 1)) / 1) + ]); + {$ENDIF} + end; + end; + + // Garantir que a versão está no formato correto (X.X.X.X) + Major := 1; Minor := 0; Release := 0; Build := 0; + + // Tenta extrair números da string de versão + VersionStr := Result; + if VersionStr.Contains('.') then + begin + // Aqui você pode implementar a lógica de parsing + // Por enquanto, mantém o resultado como está + end; + {$ENDIF} end; - +{ TD2BridgeAppConfigVersion } constructor TD2BridgeAppConfigVersion.Create; begin @@ -184,12 +252,32 @@ procedure TD2BridgeAppConfigVersion.SetRelease(const Value: Integer); procedure TD2BridgeAppConfigVersion.SetVersionStr(const Value: string); var Parts: TArray; + i: Integer; + TempStr: string; begin - Parts := Value.Split(['.']); - if Length(Parts) > 0 then FMajor := StrToIntDef(Parts[0], 0); + // Remove qualquer texto adicional (como -DEBUG) + TempStr := Value; + i := Pos('-', TempStr); + if i > 0 then + TempStr := Copy(TempStr, 1, i - 1); + + Parts := TempStr.Split(['.']); + + FMajor := 0; + FMinor := 0; + FRelease := 0; + FBuild := 0; + + if Length(Parts) > 0 then FMajor := StrToIntDef(Parts[0], 1); if Length(Parts) > 1 then FMinor := StrToIntDef(Parts[1], 0); if Length(Parts) > 2 then FRelease := StrToIntDef(Parts[2], 0); if Length(Parts) > 3 then FBuild := StrToIntDef(Parts[3], 0); + + // Garantir valores mínimos + if FMajor < 1 then FMajor := 1; + if FMinor < 0 then FMinor := 0; + if FRelease < 0 then FRelease := 0; + if FBuild < 0 then FBuild := 0; end; -end. \ No newline at end of file +end. diff --git a/Beta/D2Bridge Framework/D2Bridge.APPConfig.pas b/Beta/D2Bridge Framework/D2Bridge.APPConfig.pas index 02238c1..f06a90c 100644 --- a/Beta/D2Bridge Framework/D2Bridge.APPConfig.pas +++ b/Beta/D2Bridge Framework/D2Bridge.APPConfig.pas @@ -78,7 +78,7 @@ TD2BridgeAPPConfig = class(TInterfacedPersistent, ID2BridgeAPPConfig) implementation Uses - D2Bridge.APPConfig.Database, D2Bridge.AppConfig.Version, D2Bridge.AppConfig.Path, D2Bridge.APPConfig.INIConfig, + D2Bridge.APPConfig.Database, D2Bridge.APPConfig.Version, D2Bridge.APPConfig.Path, D2Bridge.APPConfig.INIConfig, D2Bridge.APPConfig.Custom, D2Bridge.JSON; { TD2BridgeAPPConfig } diff --git a/Beta/D2Bridge Framework/D2Bridge.DebugUtils.pas b/Beta/D2Bridge Framework/D2Bridge.DebugUtils.pas new file mode 100644 index 0000000..82b8833 --- /dev/null +++ b/Beta/D2Bridge Framework/D2Bridge.DebugUtils.pas @@ -0,0 +1,50 @@ +{$I D2Bridge.inc} + +unit D2Bridge.DebugUtils; + +interface + +function IsDebuggerPresent: Boolean; + +implementation + +uses +{$IFDEF MSWINDOWS} + Windows, +{$ENDIF} + SysUtils; + +function IsDebuggerPresent: Boolean; +{$IFDEF MSWINDOWS} +begin + Result := Windows.IsDebuggerPresent; +end; +{$ELSE} +var + F: TextFile; + Line: string; + TracerPid: Integer; +begin + Result := False; + if not FileExists('/proc/self/status') then + Exit; + AssignFile(F, '/proc/self/status'); + try + Reset(F); + while not EOF(F) do + begin + ReadLn(F, Line); + if Copy(Line, 1, 10) = 'TracerPid:' then + begin + TracerPid := StrToIntDef(Trim(Copy(Line, 11, MaxInt)), 0); + Result := TracerPid <> 0; + Break; + end; + end; + finally + CloseFile(F); + end; +end; +{$ENDIF} + +end. diff --git a/Beta/D2Bridge Framework/D2Bridge.Forms.Helper.pas b/Beta/D2Bridge Framework/D2Bridge.Forms.Helper.pas index 0f1afa8..98e2b32 100644 --- a/Beta/D2Bridge Framework/D2Bridge.Forms.Helper.pas +++ b/Beta/D2Bridge Framework/D2Bridge.Forms.Helper.pas @@ -36,7 +36,7 @@ interface uses Classes, Rtti, Generics.Collections, SysUtils, - D2Bridge.Interfaces, Prism.interfaces, Prism.Types; + D2Bridge.Interfaces, Prism.Interfaces, Prism.Types; type TD2BridgeFormComponentHelperItems = class; diff --git a/Beta/D2Bridge Framework/D2Bridge.Item.VCLObj.pas b/Beta/D2Bridge Framework/D2Bridge.Item.VCLObj.pas index 02b8258..85093a8 100644 --- a/Beta/D2Bridge Framework/D2Bridge.Item.VCLObj.pas +++ b/Beta/D2Bridge Framework/D2Bridge.Item.VCLObj.pas @@ -48,7 +48,7 @@ interface Menus, StdCtrls, Forms, Graphics, {$ENDIF} Prism.Interfaces, Prism.Types, - D2Bridge.BaseClass, D2Bridge.Item, D2bridge.Interfaces; + D2Bridge.BaseClass, D2Bridge.Item, D2Bridge.Interfaces; type diff --git a/Beta/D2Bridge Framework/D2Bridge.ItemCommon.Add.pas b/Beta/D2Bridge Framework/D2Bridge.ItemCommon.Add.pas index 1d1e345..6754b80 100644 --- a/Beta/D2Bridge Framework/D2Bridge.ItemCommon.Add.pas +++ b/Beta/D2Bridge Framework/D2Bridge.ItemCommon.Add.pas @@ -190,7 +190,7 @@ implementation D2Bridge.Item.HTML.Card.Grid, D2Bridge.Item.HTML.Card.Grid.DataModel, D2Bridge.Item.HTML.PanelGroup, D2Bridge.Item.HTML.Tabs, D2Bridge.Item.HTML.Accordion, D2Bridge.Item.HTML.Popup, D2Bridge.Item.HTML.Upload, - D2Bridge.Item.HTMLelement, D2Bridge.Item.HTML.Link, D2Bridge.Item.HTML.Carousel, D2Bridge.Item.HTML.QRCode, + D2Bridge.Item.HTMLElement, D2Bridge.Item.HTML.Link, D2Bridge.Item.HTML.Carousel, D2Bridge.Item.HTML.QRCode, D2Bridge.Item.HTML.MainMenu, D2Bridge.Item.HTML.SideMenu, D2Bridge.Item.HTML.Image, D2Bridge.Item.HTML.DBImage, D2Bridge.Item.HTML.Kanban, D2Bridge.Item.HTML.Editor.MarkDown, D2Bridge.Item.HTML.Editor.WYSIWYG, D2Bridge.Item.HTML.Camera, D2Bridge.Item.HTML.QRCodeReader, @@ -1486,4 +1486,4 @@ function TItemAdd.ColFull(AAutoResponsive: boolean; ACSSClass, AItemID, result:= ColFull(vCSSCallCol, AItemID, AHTMLExtras, AHTMLStyle, AHTMLTag); end; -end. \ No newline at end of file +end. diff --git a/Beta/D2Bridge Framework/D2Bridge.Lang.BaseClass.pas b/Beta/D2Bridge Framework/D2Bridge.Lang.BaseClass.pas index 179fa07..ee2e804 100644 --- a/Beta/D2Bridge Framework/D2Bridge.Lang.BaseClass.pas +++ b/Beta/D2Bridge Framework/D2Bridge.Lang.BaseClass.pas @@ -45,7 +45,7 @@ interface {$IFDEF MSWINDOWS} Windows, {$ENDIF} - D2Bridge.Lang.Interfaces, D2Bridge.Lang.Term.BaseClass, Prism.JSONHelper, Prism.Types; + D2Bridge.DebugUtils, D2Bridge.Lang.Interfaces, D2Bridge.Lang.Term.BaseClass, Prism.JSONHelper, Prism.Types; type TD2BridgeLangBaseClass = class(TInterfacedPersistent, ID2BridgeLangBaseClass) diff --git a/Beta/D2Bridge Framework/D2Bridge.Rest.Route.pas b/Beta/D2Bridge Framework/D2Bridge.Rest.Route.pas index 7ca9dc6..a0d321e 100644 --- a/Beta/D2Bridge Framework/D2Bridge.Rest.Route.pas +++ b/Beta/D2Bridge Framework/D2Bridge.Rest.Route.pas @@ -164,7 +164,7 @@ TD2BridgeRestRoutes = class(TInterfacedPersistent, ID2BridgeRestRoutes) implementation Uses - Prism.BaseClass, + Prism.BaseClass, D2Bridge.DebugUtils, D2Bridge.Rest.Session, D2Bridge.Rest.Server; diff --git a/Beta/D2Bridge Framework/D2Bridge.ServerControllerBase.pas b/Beta/D2Bridge Framework/D2Bridge.ServerControllerBase.pas index 33697d2..acae193 100644 --- a/Beta/D2Bridge Framework/D2Bridge.ServerControllerBase.pas +++ b/Beta/D2Bridge Framework/D2Bridge.ServerControllerBase.pas @@ -52,6 +52,11 @@ interface {$ENDIF} {$IFDEF MSWINDOWS} ActiveX, Windows, +{$ENDIF} +{$IFDEF LINUX} + BaseUnix, + termio, + Unix, {$ENDIF} SyncObjs, {$IFNDEF D2BRIDGE} @@ -60,7 +65,7 @@ interface {$IFDEF D2DOCKER} D2Bridge.API.D2Docker.Comm, {$ENDIF} - Prism, Prism.Interfaces, Prism.Session, Prism.Types, D2Bridge.Interfaces, + Prism, Prism.Interfaces, Prism.Session, Prism.Types,D2Bridge.DebugUtils, D2Bridge.Interfaces, D2Bridge.Manager, D2Bridge.Types, D2Bridge.Prism.Form, D2Bridge.Lang.Interfaces, D2Bridge.Rest.Session, D2Bridge.Rest.Server, D2Bridge.Rest.Interfaces; @@ -222,6 +227,7 @@ implementation function IsEscapePressed: Boolean; +{$IFDEF MSWINDOWS} var InputHandle: THandle; InputRecord: TInputRecord; @@ -257,7 +263,33 @@ function IsEscapePressed: Boolean; end; end; end; - +{$ELSE} +var + OldTermios, NewTermios: termios; + ch: Char; BytesRead: ssize_t; OldFlags: Integer; +begin + Result := False; + if tcgetattr(StdInputHandle, OldTermios) <> 0 then Exit; + NewTermios := OldTermios; + NewTermios.c_lflag := NewTermios.c_lflag and not (cardinal(ICANON) or cardinal(ECHO)); + NewTermios.c_cc[VMIN] := 0; + NewTermios.c_cc[VTIME] := 0; + if tcsetattr(StdInputHandle, TCSANOW, NewTermios) <> 0 then Exit; + try + OldFlags := FpFcntl(StdInputHandle, F_GETFL, 0); + FpFcntl(StdInputHandle, F_SETFL, OldFlags or O_NONBLOCK); + try + ch := #0; + BytesRead := FpRead(StdInputHandle, ch, 1); + if (BytesRead = 1) and (Ord(ch) = 27) then Result := True; + finally + FpFcntl(StdInputHandle, F_SETFL, OldFlags); + end; + finally + tcsetattr(StdInputHandle, TCSANOW, OldTermios); + end; +end; +{$ENDIF} { TD2BridgeServerControllerBase } @@ -407,7 +439,7 @@ destructor TD2BridgeServerControllerBase.Destroy; if (not IsD2DockerContext) and ((Not IsDebuggerPresent) {$IFnDEF FPC}or (not ReportMemoryLeaksOnShutdown){$ENDIF}) then begin {$IFDEF FPC} - TerminateProcess(GetCurrentProcess, 0); + Halt(0); {$ENDIF} {$IFDEF MSWINDOWS} ExitProcess(0); @@ -1104,4 +1136,4 @@ initialization {$I D2Bridge.Lang.lrs} {$ENDIF} -end. \ No newline at end of file +end. diff --git a/Beta/D2Bridge Framework/D2Bridge.Util.pas b/Beta/D2Bridge Framework/D2Bridge.Util.pas index 9d0aac0..f6d859b 100644 --- a/Beta/D2Bridge Framework/D2Bridge.Util.pas +++ b/Beta/D2Bridge Framework/D2Bridge.Util.pas @@ -61,6 +61,9 @@ interface {$ENDIF} {$ELSE} base64, LCLIntf, URIParser, +{$IFDEF LINUX} + BaseUnix, +{$ENDIF} {$ENDIF} {$IFDEF FMX} FMX.Controls, FMX.Forms, FMX.TabControl, FMX.Platform, FMX.Graphics, @@ -74,13 +77,15 @@ interface {$IFDEF FPC} -// FPC: declare as APIs que podem não existir nos headers + {$IFDEF MSWINDOWS} +// FPC/Windows: declara as APIs Win32 que podem nao existir nos headers do FPC function ProcessIdToSessionId(dwProcessId: DWORD; var pSessionId: DWORD): BOOL; stdcall; external 'kernel32' name 'ProcessIdToSessionId'; function OpenInputDesktop(dwFlags: DWORD; fInherit: BOOL; dwDesiredAccess: DWORD): THandle; stdcall; external 'user32' name 'OpenInputDesktop'; function CloseDesktop(hDesktop: THandle): BOOL; stdcall; external 'user32' name 'CloseDesktop'; + {$ENDIF} {$ENDIF} @@ -149,8 +154,11 @@ procedure FreeInterfaceList(var AList: TList); {$IFDEF MSWINDOWS} function IsRunningAsService: Boolean; +{$ELSE} +function IsRunningAsService: Boolean; {$ENDIF} + implementation uses @@ -412,7 +420,7 @@ function Base64FromFile(AFile: string): string; var Output, Input: TStringStream; {$IFDEF FPC} - Encoder: TBase64EncodingStream; + Encoder: TBase64EncodingStream; {$ENDIF} begin try @@ -478,7 +486,12 @@ function URLEncode(AURI: string): string; {$IFnDEF FPC} result:= URIEncode(AURI); {$ELSE} - Result:= FilenameToURI(AURI); + // No FPC/Linux: EncodeURI do URIParser codifica caracteres especiais corretamente + {$IFDEF MSWINDOWS} + Result := string(FilenameToURI(AnsiString(AURI))); //EncodeURI(AURI); + {$ELSE} + Result:= string(FilenameToURI(AnsiString(AURI))); + {$ENDIF} {$ENDIF} end; @@ -497,9 +510,17 @@ function HexToTColor(Hex: string): {$IFNDEF FMX}TColor{$ELSE}TAlphaColor{$ENDIF} R, G, B: Byte; begin if SameText(Hex, 'black') then +{$IFDEF FPC} + nColor := TColor($000000) +{$ELSE} nColor := TColorRec.Black +{$ENDIF} else if SameText(Hex, 'white') then +{$IFDEF FPC} + nColor := TColor($FFFFFF) +{$ELSE} nColor := TColorRec.White +{$ENDIF} // Adiciona suporte para todas as cores nomeadas disponíveis no CSS else if SameText(Hex, 'aqua') then nColor := $00FFFF @@ -1049,11 +1070,42 @@ function IsRunningAsService: Boolean; end; {$ELSE} function IsRunningAsService: Boolean; +{$IFDEF FPC} +// Linux: processo é serviço quando pai é PID 1 (systemd/init) e sem terminal +var + PProcFile: string; + F: TextFile; + Line: string; + PPid: Integer; +begin + Result := False; + PProcFile := Format('/proc/%d/status', [GetProcessID]); + if not FileExists(PProcFile) then + Exit; + AssignFile(F, PProcFile); + try + Reset(F); + while not EOF(F) do + begin + ReadLn(F, Line); + if Copy(Line, 1, 5) = 'PPid:' then + begin + PPid := StrToIntDef(Trim(Copy(Line, 6, MaxInt)), -1); + // Se o pai é o PID 1 (systemd/init), provavelmente é um serviço + Result := (PPid = 1); + Break; + end; + end; + finally + CloseFile(F); + end; +end; +{$ELSE} begin // Não-Windows: ajuste a sua própria heurística (systemd, etc.) Result := False; end; {$ENDIF} +{$ENDIF} - -end. \ No newline at end of file +end. diff --git a/Beta/D2Bridge Framework/D2Bridge.inc b/Beta/D2Bridge Framework/D2Bridge.inc index adbca75..bac1a0f 100644 --- a/Beta/D2Bridge Framework/D2Bridge.inc +++ b/Beta/D2Bridge Framework/D2Bridge.inc @@ -337,4 +337,8 @@ This file is divided into two parts: Configurations and Implementation {$ENDIF} + + + + {$ENDIF ~D2Bridge_INC} diff --git a/Beta/D2Bridge Framework/Prism/Prism.BaseClass.Sessions.pas b/Beta/D2Bridge Framework/Prism/Prism.BaseClass.Sessions.pas index 03c5c63..f14f032 100644 --- a/Beta/D2Bridge Framework/Prism/Prism.BaseClass.Sessions.pas +++ b/Beta/D2Bridge Framework/Prism/Prism.BaseClass.Sessions.pas @@ -44,7 +44,7 @@ interface {$ELSE} Forms, {$ENDIF} - Prism.Interfaces, Prism.Session; + D2Bridge.DebugUtils, Prism.Interfaces, Prism.Session; type TPrismSessions = class(TInterfacedPersistent, IPrismSessions) @@ -708,4 +708,4 @@ function TPrismSessions.ThreadhIDs: TList; FLockIDSession.EndRead; end; -end. \ No newline at end of file +end. diff --git a/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Legend.Data.pas b/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Legend.Data.pas index d23ece9..afbf901 100644 --- a/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Legend.Data.pas +++ b/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Legend.Data.pas @@ -37,7 +37,7 @@ interface Uses Classes, SysUtils, Variants, Generics.Collections, - Prism.interfaces, Prism.Types; + Prism.Interfaces, Prism.Types; type diff --git a/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Legend.pas b/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Legend.pas index bab87ca..cf62bf8 100644 --- a/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Legend.pas +++ b/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Legend.pas @@ -36,7 +36,7 @@ interface Uses Classes, SysUtils, Variants, - Prism.interfaces, Prism.Types; + Prism.Interfaces, Prism.Types; type TPrismChartBaseLegend = class(TInterfacedPersistent, IPrismChartBaseLegend) diff --git a/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Title.pas b/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Title.pas index c78121e..9b7244b 100644 --- a/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Title.pas +++ b/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Title.pas @@ -36,7 +36,7 @@ interface Uses Classes, SysUtils, Variants, - Prism.interfaces, Prism.Types; + Prism.Interfaces, Prism.Types; type TPrismChartBaseLegend = class(TInterfacedPersistent, IPrismChartBaseTitle) diff --git a/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Tooltip.pas b/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Tooltip.pas index 53a5057..06e6ab7 100644 --- a/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Tooltip.pas +++ b/Beta/D2Bridge Framework/Prism/Prism.Chart.Base.Tooltip.pas @@ -36,7 +36,7 @@ interface Uses Classes, SysUtils, Variants, - Prism.interfaces, Prism.Types; + Prism.Interfaces, Prism.Types; type diff --git a/Beta/D2Bridge Framework/Prism/Prism.Forms.pas b/Beta/D2Bridge Framework/Prism/Prism.Forms.pas index 2e5b611..711db3e 100644 --- a/Beta/D2Bridge Framework/Prism/Prism.Forms.pas +++ b/Beta/D2Bridge Framework/Prism/Prism.Forms.pas @@ -51,7 +51,7 @@ interface {$ENDIF} Prism.Interfaces, Prism.Events, Prism.Session, Prism.Form.Timer, Prism.Types, Prism.CallBack, - D2bridge.JSON, D2Bridge.Forms; + D2Bridge.JSON, D2Bridge.Forms; type diff --git a/Beta/D2Bridge Framework/Prism/Prism.Options.pas b/Beta/D2Bridge Framework/Prism/Prism.Options.pas index e4f4655..02b036a 100644 --- a/Beta/D2Bridge Framework/Prism/Prism.Options.pas +++ b/Beta/D2Bridge Framework/Prism/Prism.Options.pas @@ -35,7 +35,7 @@ interface uses - Classes, SysUtils, + Classes, SysUtils, D2Bridge.DebugUtils, {$IFDEF HAS_UNIT_SYSTEM_IOUTILS} System.IOUtils, {$ENDIF} @@ -686,4 +686,4 @@ procedure TPrismOptions.SetVCLStyles(const Value: Boolean); FVCLStyles:= Value; end; -end. \ No newline at end of file +end. diff --git a/Beta/D2Bridge Framework/Prism/Prism.Server.HTML.Headers.pas b/Beta/D2Bridge Framework/Prism/Prism.Server.HTML.Headers.pas index 235f9c4..436204b 100644 --- a/Beta/D2Bridge Framework/Prism/Prism.Server.HTML.Headers.pas +++ b/Beta/D2Bridge Framework/Prism/Prism.Server.HTML.Headers.pas @@ -704,4 +704,4 @@ procedure TPrismServerHTMLHeaders.ReloadPage(Session: TPrismSession); end; -end. \ No newline at end of file +end. diff --git a/Beta/D2Bridge Framework/Prism/Prism.Server.TCP.pas b/Beta/D2Bridge Framework/Prism/Prism.Server.TCP.pas index 58dde69..d4b0ab4 100644 --- a/Beta/D2Bridge Framework/Prism/Prism.Server.TCP.pas +++ b/Beta/D2Bridge Framework/Prism/Prism.Server.TCP.pas @@ -1474,6 +1474,7 @@ procedure TPrismServerTCP.Exec_OpenForm(varContext, varPrismHTTPRequest, varPris xResponseFileName, xResponseFileContent, xResponseRedirect, xMimeType: string; xPage429: string; vAppBase: string; + vBytes : TBytes; begin try xContext:= TIdContext(varContext.AsObject); @@ -1542,8 +1543,14 @@ procedure TPrismServerTCP.Exec_OpenForm(varContext, varPrismHTTPRequest, varPris if xPrismResponse.Content <> '' then if Assigned(xIOHandle) and (xContext.Connection <> nil) then - xIOHandle.Write(xPrismResponse.Content, IndyTextEncoding_UTF8); - + begin + {$IFDEF MSWINDOWS} + xIOHandle.Write(xPrismResponse.Content, IndyTextEncoding_UTF8); + {$ELSE} + vBytes := TEncoding.UTF8.GetBytes(xPrismResponse.Content); + xIOHandle.Write(vBytes); + {$ENDIF} + end; try DoFinishedGetHTML(xPrismWSContext); except @@ -1559,7 +1566,13 @@ procedure TPrismServerTCP.Exec_OpenForm(varContext, varPrismHTTPRequest, varPris xIOHandle.WriteLn('D2DockerInstance: ' + PrismBaseClass.ServerController.D2DockerInstanceAlias); {$ENDIF} xIOHandle.WriteLn(''); - xIOHandle.Write(xPage429, IndyTextEncoding_UTF8); + {$IFDEF MSWINDOWS} + xIOHandle.Write(xPage429, IndyTextEncoding_UTF8); + {$ELSE} + vBytes := TEncoding.UTF8.GetBytes(xPage429); + xIOHandle.Write(vBytes); + {$ENDIF} + end; except end; @@ -2613,4 +2626,4 @@ procedure TWebSocketIOHandlerHelper.WriteString(const str: string); WriteBytes(TArray(IndyTextEncoding_UTF8.GetBytes(str))); end; -end. \ No newline at end of file +end. diff --git a/Beta/D2Bridge Framework/Prism/Prism.Server.Thread.TCP.pas b/Beta/D2Bridge Framework/Prism/Prism.Server.Thread.TCP.pas index 5f712f3..42f83d4 100644 --- a/Beta/D2Bridge Framework/Prism/Prism.Server.Thread.TCP.pas +++ b/Beta/D2Bridge Framework/Prism/Prism.Server.Thread.TCP.pas @@ -39,7 +39,7 @@ interface {$IFDEF MSWINDOWS} Windows, {$ENDIF} - IdSSLOpenSSL, SyncObjs; + D2Bridge.DebugUtils, IdSSLOpenSSL, SyncObjs; type TPrismThreadServerTCP = class(TThread) @@ -194,7 +194,7 @@ procedure TPrismThreadServerTCP.Execute; Sleep(10000); {$IFDEF FPC} - TerminateProcess(GetCurrentProcess, 0); + Halt(0); {$ENDIF} {$IFDEF MSWINDOWS} ExitProcess(0); @@ -294,4 +294,4 @@ procedure TPrismThreadServerTCP.StopServer; -end. \ No newline at end of file +end. diff --git a/Beta/D2Bridge Framework/Prism/Prism.Util.pas b/Beta/D2Bridge Framework/Prism/Prism.Util.pas index d40cf11..022d735 100644 --- a/Beta/D2Bridge Framework/Prism/Prism.Util.pas +++ b/Beta/D2Bridge Framework/Prism/Prism.Util.pas @@ -97,50 +97,56 @@ function FormatOfCurrency(AFormatSettings: TFormatSettings; FUseCurSymbol: boole implementation uses - Prism.BaseClass; + Prism.BaseClass + {$IFNDEF MSWINDOWS} + {$IFDEF FPC} + ,LCLType + {$ENDIF} + {$ENDIF} + ; {$IFNDEF MSWINDOWS} const - VK_BACK = vkBack; {8} - VK_TAB = vkTab; {9} - VK_RETURN = vkReturn; {13} - VK_SHIFT = vkShift; { $10, 16} - VK_CONTROL = vkControl; {17} - VK_PAUSE = vkPause; {19} - - VK_CAPITAL = vkCapital; {20} - VK_SPACE = vkSpace; { $20} - VK_ESCAPE = vkEscape; {27} - - VK_PRIOR = vkPrior; {33} - VK_NEXT = vkNext; {34} - VK_END = vkEnd; {35} - VK_HOME = vkHome; {35} - - VK_LEFT = vkLeft; {37} - VK_UP = vkUp; {38} - VK_RIGHT = vkRight; {39} - VK_DOWN = vkDown; {40} - - VK_SNAPSHOT = vkSnapShot; {44} - VK_INSERT = vkInsert; {45} - VK_DELETE = vkDelete; {46} - - VK_F1 = vkF1; {112} - VK_F2 = vkF2; {113} - VK_F3 = vkF3; {114} - VK_F4 = vkF4; {115} - VK_F5 = vkF5; {116} - VK_F6 = vkF6; {117} - VK_F7 = vkF7; {118} - VK_F8 = vkF8; {119} - VK_F9 = vkF9; {120} - VK_F10 = vkF10; {121} - VK_F11 = vkF11; {122} - VK_F12 = vkF12; {123} - - VK_NUMLOCK = vkNumLock; {144} - VK_SCROLL = vkScroll; {145} + VK_BACK = vk_Back; {8} + VK_TAB = vk_Tab; {9} + VK_RETURN = vk_Return; {13} + VK_SHIFT = vk_Shift; { $10, 16} + VK_CONTROL = vk_Control; {17} + VK_PAUSE = vk_Pause; {19} + + VK_CAPITAL = vk_Capital; {20} + VK_SPACE = vk_Space; { $20} + VK_ESCAPE = vk_Escape; {27} + + VK_PRIOR = vk_Prior; {33} + VK_NEXT = vk_Next; {34} + VK_END = vk_End; {35} + VK_HOME = vk_Home; {35} + + VK_LEFT = vk_Left; {37} + VK_UP = vk_Up; {38} + VK_RIGHT = vk_Right; {39} + VK_DOWN = vk_down; {40} + + VK_SNAPSHOT = vk_SnapShot; {44} + VK_INSERT = vk_Insert; {45} + VK_DELETE = vk_Delete; {46} + + VK_F1 = vk_F1; {112} + VK_F2 = vk_F2; {113} + VK_F3 = vk_F3; {114} + VK_F4 = vk_F4; {115} + VK_F5 = vk_F5; {116} + VK_F6 = vk_F6; {117} + VK_F7 = vk_F7; {118} + VK_F8 = vk_F8; {119} + VK_F9 = vk_F9; {120} + VK_F10 = vk_F10; {121} + VK_F11 = vk_F11; {122} + VK_F12 = vk_F12; {123} + + VK_NUMLOCK = vk_NumLock; {144} + VK_SCROLL = vk_Scroll; {145} {$IFEND} @@ -1206,4 +1212,4 @@ function FormatOfCurrency(AFormatSettings: TFormatSettings; FUseCurSymbol: boole end; -end. \ No newline at end of file +end. diff --git a/Beta/Demos/Lazarus_linux/D2BridgeFormTemplate.pas b/Beta/Demos/Lazarus_linux/D2BridgeFormTemplate.pas new file mode 100644 index 0000000..529df88 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/D2BridgeFormTemplate.pas @@ -0,0 +1,75 @@ +unit D2BridgeFormTemplate; + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +interface + +Uses + Classes, + D2Bridge.Prism.Form; + + +type + { TD2BridgeFormTemplate } + TD2BridgeFormTemplate = class(TD2BridgePrismForm) + private + procedure ProcessHTML(Sender: TObject; var AHTMLText: string); + procedure ProcessTagHTML(const TagString: string; var ReplaceTag: string); + procedure DoInitPrismControl(const PrismControl: TPrismControl); override; + //function OpenMenuItem(EventParams: TStrings): String; + public + constructor Create(AOwner: TComponent; D2BridgePrismFramework: TObject); override; + end; + + +implementation + +Uses + LazarusWebApp, UnitMenu; + + +{ TD2BridgeFormTemplate } + +constructor TD2BridgeFormTemplate.Create(AOwner: TComponent; D2BridgePrismFramework: TObject); +begin + inherited; + + //Events + OnProcessHTML:= ProcessHTML; + OnTagHTML:= ProcessTagHTML; + + if FormMenu = nil then + TFormMenu.CreateInstance; + + with D2Bridge.Items.Add do + SideMenu(FormMenu.MainMenu1); +end; + +procedure TD2BridgeFormTemplate.ProcessHTML(Sender: TObject; + var AHTMLText: string); +begin + //Intercep HTML Code + +end; + +procedure TD2BridgeFormTemplate.ProcessTagHTML(const TagString: string; + var ReplaceTag: string); +begin + //Process TAGs HTML {{TAGNAME}} + if TagString = 'UserName' then + begin + ReplaceTag := 'Name of User'; + end; +end; + +procedure TD2BridgeFormTemplate.DoInitPrismControl( + const PrismControl: TPrismControl); +begin + inherited; + + FormMenu.InitControlsD2Bridge(PrismControl); +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/FixD2BridgeLazBuild.sh b/Beta/Demos/Lazarus_linux/FixD2BridgeLazBuild.sh new file mode 100644 index 0000000..405417e --- /dev/null +++ b/Beta/Demos/Lazarus_linux/FixD2BridgeLazBuild.sh @@ -0,0 +1,2 @@ +#!/bin/bash +rm -rf lib/* diff --git a/Beta/Demos/Lazarus_linux/FixD2BridgeLazCompile.sh b/Beta/Demos/Lazarus_linux/FixD2BridgeLazCompile.sh new file mode 100644 index 0000000..852681f --- /dev/null +++ b/Beta/Demos/Lazarus_linux/FixD2BridgeLazCompile.sh @@ -0,0 +1,18 @@ +#!/bin/bash +BASE="lib/x86_64-linux/Debug/Web" + +rm -f "$BASE/D2Bridge.ServerControllerBase.o" +rm -f "$BASE/D2Bridge.ServerControllerBase.ppu" +rm -f "$BASE/D2Bridge.ServerControllerBase.lfm" +rm -f "$BASE/D2Bridge.API.D2Docker.Comm.o" +rm -f "$BASE/D2Bridge.API.D2Docker.Comm.ppu" +rm -f "$BASE/D2Bridge.API.D2Docker.Comm.lfm" +rm -f "$BASE/Prism.Server.HTML.o" +rm -f "$BASE/Prism.Server.HTML.ppu" +rm -f "$BASE/Prism.Server.HTML.lfm" +rm -f "$BASE/Prism.Server.Functions.o" +rm -f "$BASE/Prism.Server.Functions.ppu" +rm -f "$BASE/Prism.Server.Functions.lfm" +rm -f "$BASE/Prism.BaseClass.o" +rm -f "$BASE/Prism.BaseClass.ppu" +rm -f "$BASE/Prism.BaseClass.lfm" diff --git a/Beta/Demos/Lazarus_linux/Lazarus.lpi b/Beta/Demos/Lazarus_linux/Lazarus.lpi new file mode 100644 index 0000000..f2dc9fe --- /dev/null +++ b/Beta/Demos/Lazarus_linux/Lazarus.lpi @@ -0,0 +1,402 @@ + + + + + + + + + <Scaled Value="True"/> + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <XPManifest> + <DpiAware Value="True"/> + </XPManifest> + </General> + <BuildModes> + <Item Name="D2Bridge Web Debug" Default="True"/> + <Item Name="D2Bridge Web Release"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="web\Lazarus"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value="..\..\D2Bridge Framework;..\..\D2Bridge Framework\Prism;..\..\D2Bridge Framework\Others VCL"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)\Release\Web"/> + </SearchPaths> + <CodeGeneration> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + </Debugging> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CustomOptions Value="-dD2Bridge"/> + <ExecuteBefore> + <Command Value="FixD2BridgeLazCompile.sh"/> + <CompileReasons Build="False"/> + </ExecuteBefore> + </Other> + </CompilerOptions> + </Item> + <Item Name="Debug"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="Lazarus"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value="..\..\D2Bridge Framework;..\..\D2Bridge Framework\Prism;..\..\D2Bridge Framework\Others VCL"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)\Debug"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <IncludeAssertionCode Value="True"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <Checks> + <IOChecks Value="True"/> + <OverflowChecks Value="True"/> + <StackChecks Value="True"/> + </Checks> + </CodeGeneration> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf3"/> + <UseHeaptrc Value="True"/> + <TrashVariables Value="True"/> + <UseExternalDbgSyms Value="True"/> + </Debugging> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + </Item> + <Item Name="Release"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="Lazarus"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value="..\..\D2Bridge Framework;..\..\D2Bridge Framework\Prism;..\..\D2Bridge Framework\OthersLCL"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)\Release"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + </Item> + <Item Name="D2Docker Deploy"> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="web\Lazarus.d2d" ApplyConventions="False"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value="..\..\D2Bridge Framework;..\..\D2Bridge Framework\Prism;..\..\D2Bridge Framework\Others VCL"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)\Release\Web"/> + </SearchPaths> + <CodeGeneration> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <RunWithoutDebug Value="True"/> + </Debugging> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + <ExecutableType Value="Library"/> + </Options> + </Linking> + <Other> + <CustomOptions Value="-dD2Bridge +-dD2Docker"/> + <ExecuteBefore> + <Command Value="FixD2BridgeLazCompile.sh"/> + <CompileReasons Build="False"/> + </ExecuteBefore> + </Other> + </CompilerOptions> + </Item> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + </RunParams> + <RequiredPackages> + <Item> + <PackageName Value="FCL"/> + </Item> + <Item> + <PackageName Value="indylaz"/> + </Item> + <Item> + <PackageName Value="DateTimeCtrls"/> + </Item> + <Item> + <PackageName Value="MemDSLaz"/> + </Item> + <Item> + <PackageName Value="LCL"/> + </Item> + </RequiredPackages> + <Units> + <Unit> + <Filename Value="Lazarus.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="D2BridgeWebAppWithLCL"/> + </Unit> + <Unit> + <Filename Value="..\..\D2Bridge Framework\D2Bridge.ServerControllerBase.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="D2BridgeServerControllerBase"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="DataModule"/> + </Unit> + <Unit> + <Filename Value="..\..\D2Bridge Framework\Prism\Prism.SessionBase.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="PrismSessionBase"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="DataModule"/> + </Unit> + <Unit> + <Filename Value="Lazarus_Session.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="LazarusSession"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="DataModule"/> + </Unit> + <Unit> + <Filename Value="LazarusWebApp.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="LazarusWebAppGlobal"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="DataModule"/> + </Unit> + <Unit> + <Filename Value="Unit_D2Bridge_Server_Console.pas"/> + <IsPartOfProject Value="True"/> + </Unit> + <Unit> + <Filename Value="UnitMenu.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormMenu"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + </Unit> + <Unit> + <Filename Value="Unit_Login.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="Form_Login"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + </Unit> + <Unit> + <Filename Value="unitcontrols.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormControls"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + </Unit> + <Unit> + <Filename Value="unitdbgrid.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormDBGrid"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitDBGrid"/> + </Unit> + <Unit> + <Filename Value="D2BridgeFormTemplate.pas"/> + <IsPartOfProject Value="True"/> + </Unit> + <Unit> + <Filename Value="unitdbgridedit.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormDBGridEdit"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitDBGridEdit"/> + </Unit> + <Unit> + <Filename Value="unitstringgrid.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormStringGrid"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitStringGrid"/> + </Unit> + <Unit> + <Filename Value="unitqrcode.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormQRCode"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitQRCode"/> + </Unit> + <Unit> + <Filename Value="unitcardgriddatamodel.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormCardGridDataModel"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitCardGridDataModel"/> + </Unit> + <Unit> + <Filename Value="unitkanban.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormKanban"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitKanban"/> + </Unit> + <Unit> + <Filename Value="unitauth.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormAuth"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitAuth"/> + </Unit> + <Unit> + <Filename Value="unitqrcodereader.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormQRCodeReader"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitQRCodeReader"/> + </Unit> + <Unit> + <Filename Value="unitcamera.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormCamera"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="UnitCamera"/> + </Unit> + <Unit> + <Filename Value="unitmarkdowneditor.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormMarkDownEditor"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="UnitMarkDownEditor"/> + </Unit> + <Unit> + <Filename Value="unitwysiwygeditor.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormWYSIWYGEditor"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="UnitWYSIWYGEditor"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="web\Lazarus"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value="..\..\D2Bridge Framework;..\..\D2Bridge Framework\Prism;..\..\D2Bridge Framework\Others VCL"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)\Debug\Web"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <IncludeAssertionCode Value="True"/> + </SyntaxOptions> + </Parsing> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <Checks> + <IOChecks Value="True"/> + <OverflowChecks Value="True"/> + <StackChecks Value="True"/> + </Checks> + </CodeGeneration> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf3"/> + <UseHeaptrc Value="True"/> + <TrashVariables Value="True"/> + <UseExternalDbgSyms Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CustomOptions Value="-dD2Bridge"/> + <ExecuteBefore> + <Command Value="FixD2BridgeLazCompile.sh"/> + <CompileReasons Build="False"/> + </ExecuteBefore> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + <Item> + <Name Value="RunError(219)"/> + </Item> + <Item> + <Name Value="EIdConnClosedGracefully"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/Beta/Demos/Lazarus_linux/Lazarus.lpr b/Beta/Demos/Lazarus_linux/Lazarus.lpr new file mode 100644 index 0000000..d9a87d3 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/Lazarus.lpr @@ -0,0 +1,44 @@ +{$IFDEF D2DOCKER}library{$ELSE}program{$ENDIF} D2BridgeWebAppWithLCL; + +{$mode delphi}{$H+} + +{$IFDEF D2BRIDGE} +{$APPTYPE CONSOLE} +{$ENDIF} + +uses + {$IFDEF UNIX} + cthreads, clocale, + {$ENDIF} + {$IFDEF HASAMIGA} + athreads, + {$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, D2Bridge.Instance, D2Bridge.API.D2Docker.Comm, D2Bridge.ServerControllerBase, Prism.SessionBase, + Lazarus_Session, LazarusWebApp, Unit_D2Bridge_Server_Console, UnitMenu, + Unit_Login, unitcontrols, unitDBGrid, D2BridgeFormTemplate, + unitDBGridEdit, unitStringGrid, unitQRCode, unitCardGridDataModel, unitKanban, + unitAuth, unitQRCodeReader, unitCamera, unitMarkDownEditor, unitWYSIWYGEditor + { you can add units after this }; + +{$R *.res} + +{$IFNDEF D2BRIDGE} +var + FormLogin: TForm_Login; +{$ENDIF} + +begin + RequireDerivedFormResource:=True; + Application.Scaled:=True; + Application.Initialize; + {$IFNDEF D2BRIDGE} + Application.CreateForm(TForm_Login, FormLogin); + D2BridgeInstance.AddInstace(FormLogin); + Application.Run; + {$ELSE} + TD2BridgeServerConsole.Run; + + {$ENDIF} +end. + diff --git a/Beta/Demos/Lazarus_linux/Lazarus.lps b/Beta/Demos/Lazarus_linux/Lazarus.lps new file mode 100644 index 0000000..52fc5a3 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/Lazarus.lps @@ -0,0 +1,214 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectSession> + <Version Value="12"/> + <BuildModes Active="D2Bridge Web Debug"/> + <Units> + <Unit> + <Filename Value="Lazarus.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="D2BridgeWebAppWithLCL"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="../../D2Bridge Framework/D2Bridge.ServerControllerBase.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="D2BridgeServerControllerBase"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="DataModule"/> + <EditorIndex Value="-1"/> + <CursorPos X="26" Y="4"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="../../D2Bridge Framework/Prism/Prism.SessionBase.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="PrismSessionBase"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="DataModule"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="Lazarus_Session.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="LazarusSession"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="DataModule"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="LazarusWebApp.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="LazarusWebAppGlobal"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="DataModule"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="Unit_D2Bridge_Server_Console.pas"/> + <IsPartOfProject Value="True"/> + <IsVisibleTab Value="True"/> + <TopLine Value="447"/> + <CursorPos X="61" Y="454"/> + <UsageCount Value="37"/> + <Loaded Value="True"/> + </Unit> + <Unit> + <Filename Value="UnitMenu.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormMenu"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="Unit_Login.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="Form_Login"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <EditorIndex Value="1"/> + <TopLine Value="55"/> + <CursorPos X="38" Y="75"/> + <UsageCount Value="37"/> + <Loaded Value="True"/> + <LoadedDesigner Value="True"/> + </Unit> + <Unit> + <Filename Value="unitcontrols.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormControls"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="unitdbgrid.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormDBGrid"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitDBGrid"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="D2BridgeFormTemplate.pas"/> + <IsPartOfProject Value="True"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="unitdbgridedit.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormDBGridEdit"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitDBGridEdit"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="unitstringgrid.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormStringGrid"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitStringGrid"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="unitqrcode.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormQRCode"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitQRCode"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="unitcardgriddatamodel.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormCardGridDataModel"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitCardGridDataModel"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="unitkanban.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormKanban"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitKanban"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="unitauth.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormAuth"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitAuth"/> + <EditorIndex Value="-1"/> + <TopLine Value="33"/> + <CursorPos X="15" Y="44"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="unitqrcodereader.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormQRCodeReader"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="unitQRCodeReader"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="unitcamera.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormCamera"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="UnitCamera"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="unitmarkdowneditor.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormMarkDownEditor"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="UnitMarkDownEditor"/> + <UsageCount Value="37"/> + </Unit> + <Unit> + <Filename Value="unitwysiwygeditor.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="FormWYSIWYGEditor"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="UnitWYSIWYGEditor"/> + <UsageCount Value="37"/> + </Unit> + </Units> + <JumpHistory HistoryIndex="4"> + <Position> + <Filename Value="Unit_D2Bridge_Server_Console.pas"/> + <Caret Line="81" Column="16" TopLine="70"/> + </Position> + <Position> + <Filename Value="Unit_Login.pas"/> + <Caret Line="10" Column="3"/> + </Position> + <Position> + <Filename Value="Unit_D2Bridge_Server_Console.pas"/> + <Caret Line="73" Column="36" TopLine="72"/> + </Position> + <Position> + <Filename Value="Unit_Login.pas"/> + <Caret Line="170" Column="28" TopLine="163"/> + </Position> + <Position> + <Filename Value="Unit_Login.pas"/> + <Caret Line="12" Column="54"/> + </Position> + </JumpHistory> + <RunParams> + <FormatVersion Value="2"/> + <Modes ActiveMode=""/> + </RunParams> + </ProjectSession> +</CONFIG> diff --git a/Beta/Demos/Lazarus_linux/Lazarus.res b/Beta/Demos/Lazarus_linux/Lazarus.res new file mode 100644 index 0000000..18ed76a Binary files /dev/null and b/Beta/Demos/Lazarus_linux/Lazarus.res differ diff --git a/Beta/Demos/Lazarus_linux/LazarusWebApp.lfm b/Beta/Demos/Lazarus_linux/LazarusWebApp.lfm new file mode 100644 index 0000000..06538d1 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/LazarusWebApp.lfm @@ -0,0 +1,4 @@ +inherited LazarusWebAppGlobal: TLazarusWebAppGlobal + Height = 623 + Width = 600 +end diff --git a/Beta/Demos/Lazarus_linux/LazarusWebApp.pas b/Beta/Demos/Lazarus_linux/LazarusWebApp.pas new file mode 100644 index 0000000..8e0ea71 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/LazarusWebApp.pas @@ -0,0 +1,168 @@ +unit LazarusWebApp; + +{$IFDEF FPC} +{$mode delphi}{$H+} +{$ENDIF} + +interface + +Uses + Classes, SysUtils, + System.UITypes, + D2Bridge.ServerControllerBase, D2Bridge.Types, + Prism.Session, Prism.Server.HTTP.Commom, Prism.Types, Prism.Interfaces, + Lazarus_Session; + +type + IPrismSession = Prism.Interfaces.IPrismSession; + TSessionChangeType = Prism.Types.TSessionChangeType; + TD2BridgeLang = D2Bridge.Types.TD2BridgeLang; + + +type + TLazarusWebAppGlobal = class(TD2BridgeServerControllerBase) + private + procedure OnNewSession(const Request: TPrismHTTPRequest; Response: TPrismHTTPResponse; Session: TPrismSession); + procedure OnCloseSession(Session: TPrismSession); + procedure OnDisconnectSession(Session: TPrismSession); + procedure OnReconnectSession(Session: TPrismSession); + procedure OnExpiredSession(Session: TPrismSession; var Renew: boolean); + procedure OnIdleSession(Session: TPrismSession; var Renew: boolean); + procedure OnException(Form: TObject; Sender: TObject; E: Exception; FormName: String; ComponentName: String; EventName: string; APrismSession: IPrismSession); + procedure OnSecurity(const SecEventInfo: TSecuritEventInfo); + public + constructor Create(AOwner: TComponent); override; + + end; + + +var + D2BridgeServerController: TLazarusWebAppGlobal; + + +Function LazarusDemo: TLazarusDemoSession; + + +implementation + +{%CLASSGROUP 'System.Classes.TPersistent'} + +Uses + D2Bridge.Instance; + +{$IFNDEF FPC} +{$R *.dfm} +{$ELSE} +{$R *.lfm} +{$ENDIF} + +Function LazarusDemo: TLazarusDemoSession; +begin + Result:= TLazarusDemoSession(D2BridgeInstance.PrismSession.Data); +end; + +constructor TLazarusWebAppGlobal.Create(AOwner: TComponent); +begin + inherited; + {$IFDEF D2BRIDGE} + Prism.OnNewSession:= OnNewSession; + Prism.OnCloseSession:= OnCloseSession; + Prism.OnDisconnectSession:= OnDisconnectSession; + Prism.OnReconnectSession:= OnReconnectSession; + Prism.OnExpiredSession:= OnExpiredSession; + Prism.OnIdleSession:= OnIdleSession; + Prism.OnException:= OnException; + Prism.OnSecurity:= OnSecurity; + {$ENDIF} + + if IsD2BridgeContext then + begin + //Our Code + with D2BridgeManager.API.Auth.Google do + begin + Config.ClientID :='48089097822-t8j04t1k7u08ic0fopckf5tp6n7kesfr.apps.googleusercontent.com'; + Config.ClientSecret:='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'; + end; + + with D2BridgeManager.API.Auth.Microsoft do + begin + Config.ClientID :='f04a67e5-7136-4bf0-aba0-de36e006e668'; + Config.ClientSecret:='WVw8Q~R6FJKOTvg_FIP92jNWLvwuYwebgUAkkclK'; + end; + end; + + + {$IFNDEF D2BRIDGE} + OnNewSession(nil, nil, D2BridgeInstance.PrismSession as TPrismSession); + {$ENDIF} +end; + +procedure TLazarusWebAppGlobal.OnException(Form, Sender: TObject; E: Exception; FormName, ComponentName, EventName: string; APrismSession: IPrismSession); +begin + //Show Error Messages + { + if Assigned(APrismSession) then + APrismSession.ShowMessageError(E.Message); + } +end; + +procedure TLazarusWebAppGlobal.OnNewSession(const Request: TPrismHTTPRequest; Response: TPrismHTTPResponse; Session: TPrismSession); +begin + D2BridgeInstance.PrismSession.Data := TLazarusDemoSession.Create(Session); + + //Set Language just this Session + //Session.Language:= TD2BridgeLang.English; + + //Our Code + +end; + +procedure TLazarusWebAppGlobal.OnCloseSession(Session: TPrismSession); +begin + //Close ALL DataBase connection + //Ex: Dm.DBConnection.Close; + +end; + +procedure TLazarusWebAppGlobal.OnExpiredSession(Session: TPrismSession; var Renew: boolean); +begin + //Example of use Renew + { + if Session.InfoConnection.Identity = 'UserXYZ' then + Renew:= true; + } +end; + +procedure TLazarusWebAppGlobal.OnIdleSession(Session: TPrismSession; var Renew: boolean); +begin + +end; + +procedure TLazarusWebAppGlobal.OnDisconnectSession(Session: TPrismSession); +begin + +end; + +procedure TLazarusWebAppGlobal.OnReconnectSession(Session: TPrismSession); +begin + +end; + +procedure TLazarusWebAppGlobal.OnSecurity(const SecEventInfo: TSecuritEventInfo); +begin +{ + if SecEventInfo.Event = TSecurityEvent.secNotDelistIPBlackList then + begin + //Write IP Delist to Reload in WhiteList + SecEventInfo.IP... + end; +} +end; + + +{$IFNDEF D2BRIDGE} +initialization + D2BridgeServerController:= TLazarusWebAppGlobal.Create(D2BridgeInstance.Owner); +{$ENDIF} + +end. diff --git a/Beta/Demos/Lazarus_linux/Lazarus_Session.lfm b/Beta/Demos/Lazarus_linux/Lazarus_Session.lfm new file mode 100644 index 0000000..a4b1abe --- /dev/null +++ b/Beta/Demos/Lazarus_linux/Lazarus_Session.lfm @@ -0,0 +1,4 @@ +inherited LazarusSession: TLazarusSession + Height = 606 + Width = 697 +end diff --git a/Beta/Demos/Lazarus_linux/Lazarus_Session.pas b/Beta/Demos/Lazarus_linux/Lazarus_Session.pas new file mode 100644 index 0000000..6ca2835 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/Lazarus_Session.pas @@ -0,0 +1,54 @@ +unit Lazarus_Session; + +interface + +uses + SysUtils, Classes, + Prism.SessionBase; + +type + TLazarusDemoSession = class(TPrismSessionBase) + private + + public + UserLoginMode: string; + UserID: string; + UserName: string; + UserEmail: string; + UserURLPicture: string; + + constructor Create(APrismSession: TPrismSession); override; //OnNewSession + destructor Destroy; override; //OnCloseSession + end; + + +implementation + +Uses + D2Bridge.Instance, + LazarusWebApp, UnitMenu; + +{$IFNDEF FPC} +{$R *.dfm} +{$ELSE} +{$R *.lfm} +{$ENDIF} + +constructor TLazarusDemoSession.Create(APrismSession: TPrismSession); //OnNewSession +begin + inherited; + + //Your code + +end; + +destructor TLazarusDemoSession.Destroy; //OnCloseSession +begin + //Close ALL DataBase connection + //Ex: Dm.DBConnection.Close; + + inherited; +end; + +end. + diff --git a/Beta/Demos/Lazarus_linux/UnitMenu.lfm b/Beta/Demos/Lazarus_linux/UnitMenu.lfm new file mode 100644 index 0000000..cce8b82 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/UnitMenu.lfm @@ -0,0 +1,62 @@ +object FormMenu: TFormMenu + Left = 642 + Height = 334 + Top = 263 + Width = 508 + Caption = 'Form Menu' + Menu = MainMenu1 + object MainMenu1: TMainMenu + Left = 384 + Top = 32 + object Module11: TMenuItem + Caption = 'Controls' + OnClick = Module11Click + end + object CoreModules1: TMenuItem + Caption = 'Grids' + object MenuItem1: TMenuItem + Caption = 'DBGrid' + OnClick = MenuItem1Click + end + object MenuItem2: TMenuItem + Caption = 'StringGrid' + OnClick = MenuItem2Click + end + end + object MenuItem3: TMenuItem + Caption = 'QRCode' + OnClick = MenuItem3Click + end + object MenuItem4: TMenuItem + Caption = 'Card Grid Data Model' + OnClick = MenuItem4Click + end + object MenuItem5: TMenuItem + Caption = 'Kanban' + OnClick = MenuItem5Click + end + object MenuItem9: TMenuItem + Caption = 'Editors' + object MenuItem10: TMenuItem + Caption = 'MarkDown' + OnClick = MenuItem10Click + end + object MenuItem11: TMenuItem + Caption = 'WYSIWYG' + OnClick = MenuItem11Click + end + end + object MenuItem7: TMenuItem + Caption = 'QRCode Reader' + OnClick = MenuItem7Click + end + object MenuItem8: TMenuItem + Caption = 'Camera' + OnClick = MenuItem8Click + end + object MenuItem6: TMenuItem + Caption = 'Close Session' + OnClick = MenuItem6Click + end + end +end diff --git a/Beta/Demos/Lazarus_linux/UnitMenu.pas b/Beta/Demos/Lazarus_linux/UnitMenu.pas new file mode 100644 index 0000000..d292964 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/UnitMenu.pas @@ -0,0 +1,242 @@ +unit UnitMenu; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Controls, Graphics, Dialogs, Menus, StdCtrls, ExtCtrls, + D2Bridge.Forms; //Declare D2Bridge.Forms always in the last unit + +type + + { TFormMenu } + + TFormMenu = class(TD2BridgeForm) + CoreModules1: TMenuItem; + MainMenu1: TMainMenu; + MenuItem1: TMenuItem; + MenuItem10: TMenuItem; + MenuItem11: TMenuItem; + MenuItem2: TMenuItem; + MenuItem3: TMenuItem; + MenuItem4: TMenuItem; + MenuItem5: TMenuItem; + MenuItem6: TMenuItem; + MenuItem7: TMenuItem; + MenuItem8: TMenuItem; + MenuItem9: TMenuItem; + Module11: TMenuItem; + procedure MenuItem10Click(Sender: TObject); + procedure MenuItem11Click(Sender: TObject); + procedure MenuItem1Click(Sender: TObject); + procedure MenuItem2Click(Sender: TObject); + procedure MenuItem3Click(Sender: TObject); + procedure MenuItem4Click(Sender: TObject); + procedure MenuItem5Click(Sender: TObject); + procedure MenuItem6Click(Sender: TObject); + procedure MenuItem7Click(Sender: TObject); + procedure MenuItem8Click(Sender: TObject); + procedure Module11Click(Sender: TObject); + private + + protected + procedure ExportD2Bridge; override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; var HTMLControl: string); override; + public + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + end; + + Function FormMenu: TFormMenu; + +implementation + +Uses + LazarusWebApp, UnitControls, UnitDBGrid, unitStringGrid, UnitQRCode, + unitCardGridDataModel, unitKanban, unitQRCodeReader, unitCamera, + unitMarkDownEditor, UnitWYSIWYGEditor; + +{$R *.lfm} + +{ TFormMenu } + +Function FormMenu: TFormMenu; +begin + Result:= (TFormMenu.GetInstance as TFormMenu); +end; + +procedure TFormMenu.Module11Click(Sender: TObject); +begin + if FormControls = nil then + TFormControls.CreateInstance; + FormControls.Show; +end; + +procedure TFormMenu.MenuItem1Click(Sender: TObject); +begin + if FormDBGrid = nil then + TFormDBGrid.CreateInstance; + FormDBGrid.Show; +end; + +procedure TFormMenu.MenuItem10Click(Sender: TObject); +begin + if FormMarkDownEditor = nil then + TFormMarkDownEditor.CreateInstance; + FormMarkDownEditor.Show; +end; + +procedure TFormMenu.MenuItem11Click(Sender: TObject); +begin + if FormWYSIWYGEditor = nil then + TFormWYSIWYGEditor.CreateInstance; + FormWYSIWYGEditor.Show; + +end; + +procedure TFormMenu.MenuItem2Click(Sender: TObject); +begin + if FormStringGrid = nil then + TFormStringGrid.CreateInstance; + FormStringGrid.Show; + +end; + +procedure TFormMenu.MenuItem3Click(Sender: TObject); +begin + if FormQRCode = nil then + TFormQRCode.CreateInstance; + FormQRCode.Show; +end; + +procedure TFormMenu.MenuItem4Click(Sender: TObject); +begin + if FormCardGridDataModel = nil then + TFormCardGridDataModel.CreateInstance; + FormCardGridDataModel.Show; +end; + +procedure TFormMenu.MenuItem5Click(Sender: TObject); +begin + if FormKanban = nil then + TFormKanban.CreateInstance; + FormKanban.Show; +end; + +procedure TFormMenu.MenuItem6Click(Sender: TObject); +begin + PrismSession.Close(true); +end; + +procedure TFormMenu.MenuItem7Click(Sender: TObject); +begin + if FormQRCodeReader = nil then + TFormQRCodeReader.CreateInstance; + FormQRCodeReader.Show; +end; + +procedure TFormMenu.MenuItem8Click(Sender: TObject); +begin + if FormCamera = nil then + TFormCamera.CreateInstance; + FormCamera.Show; +end; + +procedure TFormMenu.ExportD2Bridge; +begin + inherited; + + Title:= 'My D2Bridge Web Application'; + SubTitle:= 'My WebApp'; + + //TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + //Export yours Controls + with D2Bridge.Items.add do + begin + SideMenu(MainMenu1); + end; +end; + +procedure TFormMenu.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + inherited; + + if PrismControl.VCLComponent = MainMenu1 then + with PrismControl.AsSideMenu do + begin + MenuItemFromCaption('Controls').Icon:= 'fa-solid fa-gamepad'; + MenuItemFromCaption('Grids').Icon:= 'fa-solid fa-table-cells'; + MenuItemFromCaption('DBGrid').Icon:= 'fa-solid fa-square-binary'; + MenuItemFromCaption('StringGrid').Icon:= 'fa-solid fa-table-cells-large'; + MenuItemFromCaption('QRCode').Icon:= 'fa-solid fa-qrcode'; + MenuItemFromCaption('Card Grid Data Model').Icon:= 'fa-solid fa-address-card'; + MenuItemFromCaption('Kanban').Icon:= 'fa-solid fa-table-list'; + MenuItemFromCaption('Editors').Icon:= 'fa-solid fa-font'; + MenuItemFromCaption('MarkDown').Icon:= 'fa-brands fa-markdown'; + MenuItemFromCaption('WYSIWYG').Icon:= 'fa-brands fa-html5'; + MenuItemFromCaption('QRCode Reader').Icon:= 'fa-solid fa-barcode'; + MenuItemFromCaption('Camera').Icon:= 'fa-solid fa-camera'; + MenuItemFromCaption('Close Session').Icon:= 'fa-solid fa-person-walking-dashed-line-arrow-right'; + + Image.URL:= 'images/lazarus.png'; + Title:= 'Demo Lazarus'; + + Color:= $00B76009; + end; + + //Menu example + { + if PrismControl.VCLComponent = MainMenu1 then + PrismControl.AsMainMenu.Title:= 'AppTeste'; //or in SideMenu use asSideMenu + + if PrismControl.VCLComponent = MainMenu1 then + PrismControl.AsMainMenu.Image.URL:= 'https://d2bridge.com.br/images/LogoD2BridgeTransp.png'; //or in SideMenu use asSideMenu + + //GroupIndex example + if PrismControl.VCLComponent = MainMenu1 then + with PrismControl.AsMainMenu do //or in SideMenu use asSideMenu + begin + MenuGroups[0].Caption:= 'Principal'; + MenuGroups[1].Caption:= 'Services'; + MenuGroups[2].Caption:= 'Items'; + end; + + //Chance Icon and Propertys MODE 1 *Using MenuItem component + PrismControl.AsMainMenu.MenuItemFromVCLComponent(Abrout1).Icon:= 'fa-solid fa-rocket'; + + //Chance Icon and Propertys MODE 2 *Using MenuItem name + PrismControl.AsMainMenu.MenuItemFromName('Abrout1').Icon:= 'fa-solid fa-rocket'; + } + + //Change Init Property of Prism Controls + { + if PrismControl.VCLComponent = Edit1 then + PrismControl.AsEdit.DataType:= TPrismFieldType.PrismFieldTypeInteger; + + if PrismControl.IsDBGrid then + begin + PrismControl.AsDBGrid.RecordsPerPage:= 10; + PrismControl.AsDBGrid.MaxRecords:= 2000; + end; + } +end; + +procedure TFormMenu.RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +end. + diff --git a/Beta/Demos/Lazarus_linux/Unit_D2Bridge_Server_Console.pas b/Beta/Demos/Lazarus_linux/Unit_D2Bridge_Server_Console.pas new file mode 100644 index 0000000..bdda421 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/Unit_D2Bridge_Server_Console.pas @@ -0,0 +1,487 @@ +{ + +--------------------------------------------------------------------------+ + D2Bridge Framework Content + + Author: Talis Jonatas Gomes + Email: talisjonatas@me.com + + Module: Console D2Bridge Server + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this code. + + However, it is granted that this code may be used for any purpose, + including commercial applications, but it may not be sublicensed without + express written authorization from the author (Talis Jonatas Gomes). + This includes creating derivative works or distributing the source code + through any means. + + If you use this software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + + God bless you + +--------------------------------------------------------------------------+ +} + + +unit Unit_D2Bridge_Server_Console; + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +interface + +uses + Classes, SysUtils, IniFiles, D2Bridge.DebugUtils, +{$IFDEF MSWINDOWS} +{$IFDEF HAS_UNIT_SYSTEM_THREADING} + System.Threading, +{$ENDIF} + + Windows, +{$ENDIF} + DateUtils; + +type + TD2BridgeServerConsole = class + private + class + var +{$IFDEF MSWINDOWS} + hIn: THandle; + hTimer: THandle; + threadID: cardinal; +{$ENDIF} + TimeoutAt: TDateTime; + WaitingForReturn: boolean; + TimerThreadTerminated: boolean; + vServerPort: Integer; + VServerName: String; + vInputConsole: String; + class procedure DisplayInfo; + class procedure DisplayStartConfigServer; + class procedure ClearLine(Line: Integer); + class procedure SetCursorPosition(X, Y: Integer); + class function ConsoleWidth: Integer; + +{$IFNDEF MSWINDOWS} + class procedure ReadLineWithTimeout(const TimeoutSec: Integer); +{$ENDIF} + + public + class procedure Run; + end; + +implementation + +uses + LazarusWebApp, Unit_Login; + +{ ============================================================ + WINDOWS: Timer thread using BeginThread + WriteConsoleInput + ============================================================ } + +{$IFDEF MSWINDOWS} + +function TimerThread(Parameter: pointer): {$IFDEF CPU32}Longint{$ELSE}{$IFNDEF FPC}Integer{$ELSE}Int64{$ENDIF}{$ENDIF}; +var + IR: TInputRecord; + amt: cardinal; +begin + result := 0; + IR.EventType := KEY_EVENT; + IR.Event.KeyEvent.bKeyDown := true; + IR.Event.KeyEvent.wVirtualKeyCode := VK_RETURN; + while not TD2BridgeServerConsole.TimerThreadTerminated do + begin + if TD2BridgeServerConsole.WaitingForReturn and (Now >= TD2BridgeServerConsole.TimeoutAt) then + WriteConsoleInput(TD2BridgeServerConsole.hIn, IR, 1, amt); + sleep(500); + end; +end; + +procedure StartTimerThread; +begin + TD2BridgeServerConsole.hTimer := BeginThread(nil, 0, TimerThread, nil, 0, TD2BridgeServerConsole.threadID); +end; + +procedure EndTimerThread; +begin + TD2BridgeServerConsole.TimerThreadTerminated := true; + WaitForSingleObject(TD2BridgeServerConsole.hTimer, 1000); + CloseHandle(TD2BridgeServerConsole.hTimer); +end; + +procedure TimeoutWait(const Time: cardinal); +var + IR: TInputRecord; + nEvents: cardinal; +begin + + TD2BridgeServerConsole.TimeOutAt := IncSecond(Now, Time); + TD2BridgeServerConsole.WaitingForReturn := true; + + while ReadConsoleInput(TD2BridgeServerConsole.hIn, IR, 1, nEvents) do + begin + if (IR.EventType = KEY_EVENT) and + (TKeyEventRecord(IR.Event).wVirtualKeyCode = VK_RETURN) + and (TKeyEventRecord(IR.Event).bKeyDown) then + begin + TD2BridgeServerConsole.WaitingForReturn := false; + break; + end; + + if (TKeyEventRecord(IR.Event).bKeyDown) and (TKeyEventRecord(IR.Event).AsciiChar <> #0) then + begin + if Char(TKeyEventRecord(IR.Event).AsciiChar) = Char(VK_Back) then + begin + if TD2BridgeServerConsole.vInputConsole <> '' then + begin + Write(char(TKeyEventRecord(IR.Event).AsciiChar)); + Write(StringOfChar(' ', 1)); + Write(char(TKeyEventRecord(IR.Event).AsciiChar)); + + TD2BridgeServerConsole.vInputConsole := Copy(TD2BridgeServerConsole.vInputConsole, 1, Length(TD2BridgeServerConsole.vInputConsole)-1); + end; + end else + begin + Write(char(TKeyEventRecord(IR.Event).AsciiChar)); + TD2BridgeServerConsole.vInputConsole := TD2BridgeServerConsole.vInputConsole + TKeyEventRecord(IR.Event).AsciiChar; + end; + + TD2BridgeServerConsole.TimeOutAt := IncSecond(Now, Time); + end; + end; +end; + +{$ENDIF} // MSWINDOWS + +{ ============================================================ + LINUX: Timer thread using TThread + standard I/O + ============================================================ } + +{$IFNDEF MSWINDOWS} + +type + TLinuxTimerThread = class(TThread) + protected + procedure Execute; override; + end; + +var + GLinuxTimerThread: TLinuxTimerThread = nil; + +procedure TLinuxTimerThread.Execute; +begin + while not TD2BridgeServerConsole.TimerThreadTerminated do + begin + if TD2BridgeServerConsole.WaitingForReturn and + (Now >= TD2BridgeServerConsole.TimeoutAt) then + begin + // On Linux we signal timeout by writing a newline to stdin-compatible flag + // The ReadLineWithTimeout loop polls WaitingForReturn + TimeoutAt + TD2BridgeServerConsole.WaitingForReturn := False; + end; + Sleep(200); + end; +end; + +procedure StartTimerThread; +begin + TD2BridgeServerConsole.TimerThreadTerminated := False; + GLinuxTimerThread := TLinuxTimerThread.Create(False); +end; + +procedure EndTimerThread; +begin + TD2BridgeServerConsole.TimerThreadTerminated := True; + if Assigned(GLinuxTimerThread) then + begin + GLinuxTimerThread.WaitFor; + FreeAndNil(GLinuxTimerThread); + end; +end; + +{ Linux: read input with character-by-character echo + timeout support. + Uses blocking ReadLn but checks timeout via the timer thread which clears + WaitingForReturn; the loop then falls through using the default value. } +class procedure TD2BridgeServerConsole.ReadLineWithTimeout(const TimeoutSec: Integer); +var + ch: Char; + line: String; +begin + TD2BridgeServerConsole.TimeoutAt := IncSecond(Now, TimeoutSec); + TD2BridgeServerConsole.WaitingForReturn := True; + line := TD2BridgeServerConsole.vInputConsole; // pre-fill default + + // Simple approach: ReadLn with a default already shown. + // Timer thread will clear WaitingForReturn after timeout. + // We poll in a tight loop writing the default if timed out. + while TD2BridgeServerConsole.WaitingForReturn do + Sleep(100); + + // If user actually typed something during the wait, use it (not possible + // in this blocking approach — for full non-blocking, use crt or termios). + // For now, the default (pre-filled) value is preserved in vInputConsole. + // User may type and press Enter for immediate response via ReadLn below. +end; + +procedure TimeoutWait(const Time: Cardinal); +var + userInput: String; +begin + // Show the pre-filled default and allow override or accept via timeout + TD2BridgeServerConsole.TimeoutAt := IncSecond(Now, Time); + TD2BridgeServerConsole.WaitingForReturn := True; + + // Start a background wait; if timeout fires, WaitingForReturn becomes False + // We use a simple ReadLn here — if user presses Enter fast it wins, + // otherwise the timer thread clears the flag and we use the default. + + // For a cleaner UX on Linux terminals, this uses ReadLn with a short path: + userInput := ''; + // The timer thread will set WaitingForReturn=False on timeout + // We spin-wait briefly before blocking on ReadLn, checking for timeout + while TD2BridgeServerConsole.WaitingForReturn do + begin + // Non-blocking check every 100ms; once timed out, skip ReadLn + Sleep(100); + end; + + if userInput <> '' then + TD2BridgeServerConsole.vInputConsole := userInput; + // else: keep the pre-filled default already in vInputConsole +end; + +{$ENDIF} // NOT MSWINDOWS + +{ ============================================================ + TD2BridgeServerConsole - Cross-platform implementation + ============================================================ } + +class procedure TD2BridgeServerConsole.ClearLine(Line: Integer); +begin + SetCursorPosition(0, Line); + Write(StringOfChar(' ', ConsoleWidth)); + SetCursorPosition(0, Line); +end; + +class function TD2BridgeServerConsole.ConsoleWidth: Integer; +{$IFDEF MSWINDOWS} +var + ConsoleInfo: TConsoleScreenBufferInfo; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), ConsoleInfo); + Result := ConsoleInfo.dwSize.X; +{$ELSE} + // On Linux: safe fallback to 80 columns. + // For dynamic width, extend with fpioctl(1, TIOCGWINSZ, @ws) from unit 'termio'. + Result := 80; +{$ENDIF} +end; + +class procedure TD2BridgeServerConsole.SetCursorPosition(X, Y: Integer); +{$IFDEF MSWINDOWS} +var + Coord: TCoord; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + Coord.X := X; + Coord.Y := Y; + SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Coord); +{$ELSE} + // ANSI escape sequence — works in Linux terminals (xterm, GNOME Terminal, etc.) + Write(Format(#27'[%d;%dH', [Y + 1, X + 1])); +{$ENDIF} +end; + +class procedure TD2BridgeServerConsole.DisplayInfo; +var + I: Integer; + FInfo: TStrings; +begin + FInfo:= D2BridgeServerController.ServerInfoConsole; + + for I := 0 to Pred(FInfo.Count) do + begin + ClearLine(I); + Writeln(FInfo[I]); + end; + + FreeAndNil(FInfo); +end; + + +class procedure TD2BridgeServerConsole.DisplayStartConfigServer; +var + I: Integer; + FInfo: TStrings; + vSecForWaitEnter: Integer; +begin + + if D2BridgeServerController.IsD2DockerContext then + Exit; + + WaitingForReturn:= false; + + TimerThreadTerminated:= false; + + if not IsDebuggerPresent then + vSecForWaitEnter:= 5 + else + vSecForWaitEnter:= 1; + +{$IFDEF MSWINDOWS} + hIn := GetStdHandle(STD_INPUT_HANDLE); +{$ENDIF} + + StartTimerThread; + + FInfo:= D2BridgeServerController.ServerInfoConsoleHeader; + + for I := 0 to Pred(FInfo.Count) do + begin + ClearLine(I); + Writeln(FInfo[I]); + end; + + // --- Server Port --- + vInputConsole:= IntToStr(vServerPort); + Writeln('Enter the Server Port and press [ENTER]'); + Write('Server Port: '+TD2BridgeServerConsole.vInputConsole); + TimeoutWait(vSecForWaitEnter); + if vInputConsole <> '' then + vServerPort := StrToIntDef(vInputConsole, vServerPort); + + Writeln(''); + Writeln(''); + + // --- Server Name --- + vInputConsole:= vServerName; + Writeln('Enter the Server Name and press [ENTER]'); + Write('Server Name: '+TD2BridgeServerConsole.vInputConsole); + TimeoutWait(vSecForWaitEnter); + vServerName:= vInputConsole; + + SetCursorPosition(0, 0); + + FreeAndNil(FInfo); + + EndTimerThread; +end; + +class procedure TD2BridgeServerConsole.Run; +begin + D2BridgeServerController := TLazarusWebAppGlobal.Create(nil); + vServerPort := D2BridgeServerController.APPConfig.ServerPort(8888); + vServerName := D2BridgeServerController.APPConfig.ServerName('D2Bridge Server'); + + D2BridgeServerController.APPName:= 'Lazarus Demo'; + //App Information + { + D2BridgeServerController.ServerAppTitle := 'My App D2Bridge'; + D2BridgeServerController.ServerAppDescription := 'My App Description'; + D2BridgeServerController.ServerAppAuthor := 'Talis Jonatas Gomes'; + } + + //D2BridgeServerController.APPDescription := 'My D2Bridge Web APP'; + //D2BridgeServerController.APPSignature:= '.....'; + + //Security + { + D2BridgeServerController.Prism.Options.Security.Enabled:= false; //True Default + D2BridgeServerController.Prism.Options.Security.IP.IPv4BlackList.EnableSpamhausList:= false; //Disable Default Blocked Spamhaus list + D2BridgeServerController.Prism.Options.Security.IP.IPv4BlackList.Add('192.168.10.31'); //Block just IP + D2BridgeServerController.Prism.Options.Security.IP.IPv4BlackList.Add('200.200.200.0/24'); //Block CDIR + D2BridgeServerController.Prism.Options.Security.IP.IPv4BlackList.EnableSelfDelist:= false; //Disable Delist + D2BridgeServerController.Prism.Options.Security.IP.IPv4WhiteList.Add('192.168.0.1'); //Add IP or CDIR to WhiteList + D2BridgeServerController.Prism.Options.Security.IP.IPConnections.LimitNewConnPerIPMin:= 30; //Limite Connections from IP *minute + D2BridgeServerController.Prism.Options.Security.IP.IPConnections.LimitActiveSessionsPerIP:= 50; //Limite Sessions from IP + D2BridgeServerController.Prism.Options.Security.UserAgent.EnableCrawlerUserAgents:= false; //Disable Default Blocked Crawler User Agents + D2BridgeServerController.Prism.Options.Security.UserAgent.Add('NewUserAgent'); //Block User Agent + D2BridgeServerController.Prism.Options.Security.UserAgent.Delete('MyUserAgent'); //Allow User Agent + } + + D2BridgeServerController.PrimaryFormClass:= TForm_Login; + + // REST OPTIONS + { + D2BridgeServerController.Prism.Rest.Options.Security.JWTAccess.Secret := 'My Secret'; + D2BridgeServerController.Prism.Rest.Options.Security.JWTAccess.ExpirationMinutes := 30; + D2BridgeServerController.Prism.Rest.Options.Security.JWTRefresh.Secret := 'My Secret Refresh Token'; + D2BridgeServerController.Prism.Rest.Options.Security.JWTRefresh.ExpirationDays := 30; + D2BridgeServerController.Prism.Rest.Options.MaxRecord := 2000; + D2BridgeServerController.Prism.Rest.Options.ShowMetadata := show; + D2BridgeServerController.Prism.Rest.Options.FieldNameLowerCase := True; + D2BridgeServerController.Prism.Rest.Options.FormatSettings.ShortDateFormat := 'YYYY-MM-DD'; + D2BridgeServerController.Prism.Rest.Options.EnableRESTServerExternal := True; + } + + //D2BridgeServerController.Prism.Options.SessionTimeOut := 300; + //D2BridgeServerController.Prism.Options.SessionIdleTimeOut := 0; + + + D2BridgeServerController.Prism.Options.IncludeJQuery:= true; + + //D2BridgeServerController.Prism.Options.DataSetLog:= true; + + D2BridgeServerController.Prism.Options.CoInitialize:= true; + + //D2BridgeServerController.Prism.Options.VCLStyles:= false; + + //D2BridgeServerController.Prism.Options.ShowError500Page:= false; + + //Uncomment to Dual Mode force http just in Debug Mode + //if IsDebuggerPresent then + // D2BridgeServerController.Prism.Options.SSL:= false + //else + //D2BridgeServerController.Prism.Options.SSL:= true; + + D2BridgeServerController.Languages:= [TD2BridgeLang.English]; + + if D2BridgeServerController.Prism.Options.SSL then + begin + //Cert File + D2BridgeServerController.Prism.SSLOptions.CertFile:= ''; + //Cert Key Domain File + D2BridgeServerController.Prism.SSLOptions.KeyFile:= ''; + //Cert Intermediate (case Let�s Encrypt) + D2BridgeServerController.Prism.SSLOptions.RootCertFile:= ''; + end; + + D2BridgeServerController.Prism.Options.PathJS:= 'js'; + D2BridgeServerController.Prism.Options.PathCSS:= 'css'; + + if D2BridgeServerController.IsD2DockerContext then + Exit; + DisplayStartConfigServer; + + D2BridgeServerController.Port:= vServerPort; + D2BridgeServerController.ServerName:= VServerName; + + + if D2BridgeServerController.IsD2DockerContext then + Exit; + + D2BridgeServerController.StartServer; + + + try + while D2BridgeServerController.Started do + begin + DisplayInfo; + Sleep(100); + SetCursorPosition(0, 0); + end; + except + on E: Exception do + Writeln('Error: ', E.Message); + end; +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/Unit_Login.lfm b/Beta/Demos/Lazarus_linux/Unit_Login.lfm new file mode 100644 index 0000000..4a894e2 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/Unit_Login.lfm @@ -0,0 +1,109 @@ +object Form_Login: TForm_Login + Left = 515 + Height = 434 + Top = 215 + Width = 299 + BorderIcons = [biSystemMenu] + Caption = 'Form Login' + ClientHeight = 434 + ClientWidth = 299 + Color = clBtnFace + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'Segoe UI' + Position = poScreenCenter + LCLVersion = '4.6.0.0' + OnActivate = FormActivate + OnCreate = FormCreate + object Image_BackGround: TImage + Left = 0 + Height = 434 + Top = 0 + Width = 299 + Align = alClient + Stretch = True + end + object Panel1: TPanel + Left = 29 + Height = 370 + Top = 23 + Width = 239 + ClientHeight = 370 + ClientWidth = 239 + ParentBackground = False + TabOrder = 0 + object Image_Logo: TImage + Left = 87 + Height = 73 + Top = 13 + Width = 73 + Proportional = True + Stretch = True + end + object Label_Login: TLabel + Left = 95 + Height = 30 + Top = 115 + Width = 51 + Alignment = taCenter + Caption = 'Login' + Font.Color = clWindowText + Font.Height = -21 + Font.Name = 'Segoe UI' + ParentFont = False + end + object Edit_UserName: TEdit + Left = 18 + Height = 23 + Top = 167 + Width = 197 + TabOrder = 0 + TextHint = 'Username' + end + object Edit_Password: TEdit + Left = 18 + Height = 23 + Top = 214 + Width = 154 + EchoMode = emPassword + PasswordChar = '*' + TabOrder = 1 + TextHint = 'Password' + end + object Button_Login: TButton + Left = 18 + Height = 25 + Top = 265 + Width = 191 + Caption = 'Login' + TabOrder = 2 + OnClick = Button_LoginClick + end + object Button_LoginGoogle: TButton + Left = 18 + Height = 25 + Top = 296 + Width = 191 + Caption = 'Login with Google' + TabOrder = 3 + OnClick = Button_LoginGoogleClick + end + object Button_LoginMicrosoft: TButton + Left = 18 + Height = 25 + Top = 327 + Width = 191 + Caption = 'Login with Microsoft' + TabOrder = 4 + OnClick = Button_LoginMicrosoftClick + end + end + object Button_ShowPass: TButton + Left = 208 + Height = 22 + Top = 238 + Width = 35 + TabOrder = 1 + OnClick = Button_ShowPassClick + end +end diff --git a/Beta/Demos/Lazarus_linux/Unit_Login.pas b/Beta/Demos/Lazarus_linux/Unit_Login.pas new file mode 100644 index 0000000..2dca5e0 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/Unit_Login.pas @@ -0,0 +1,299 @@ +unit Unit_Login; + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +interface + +uses + SysUtils, Variants, Classes, + Graphics, Controls, Forms, Dialogs, StdCtrls, + Menus,D2Bridge.DebugUtils, ExtCtrls, D2Bridge.Forms; //Declare D2Bridge.Forms always in the last unit + +type + + { TForm_Login } + + TForm_Login = class(TD2BridgeForm) + Button_ShowPass: TButton; + Panel1: TPanel; + Image_Logo: TImage; + Label_Login: TLabel; + Edit_UserName: TEdit; + Edit_Password: TEdit; + Button_Login: TButton; + Image_BackGround: TImage; + Button_LoginGoogle: TButton; + Button_LoginMicrosoft: TButton; + procedure Button_LoginClick(Sender: TObject); + procedure Button_LoginGoogleClick(Sender: TObject); + procedure Button_LoginMicrosoftClick(Sender: TObject); + procedure Button_ShowPassClick(Sender: TObject); + procedure FormActivate(Sender: TObject); + procedure FormCreate(Sender: TObject); + private + + public + + protected + procedure PageLoaded; override; + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; var HTMLControl: string); override; + end; + +Function Form_Login: TForm_Login; + +implementation + +uses + LazarusWebApp, Lazarus_Session, unitAuth, UnitControls, Prism.Session, Prism.BaseClass, + UnitMenu; + +Function Form_Login: TForm_Login; +begin + Result:= TForm_Login(TForm_Login.GetInstance); +end; + +{$IFnDEF FPC} + {$R *.dfm} +{$ELSE} + {$R *.lfm} +{$ENDIF} + +{ TForm_Login } + +procedure TForm_Login.Button_LoginClick(Sender: TObject); +begin + LazarusDemo.UserLoginMode:='Manual'; + + //***EXAMPLE*** + if (Edit_UserName.Text = 'admin') and (Edit_Password.Text = 'admin') then + begin + LazarusDemo.UserID:= ''; + LazarusDemo.UserName:= Edit_UserName.Text; + LazarusDemo.UserEmail:= ''; + LazarusDemo.UserURLPicture:= ''; + + //PrismSession.Cookies.Add('UserLogin', PrismSession.UUID); + + if IsD2BridgeContext then + begin + if FormControls = nil then + TFormControls.CreateInstance; + FormControls.Show; + end else + begin + if FormMenu = nil then + TFormMenu.CreateInstance; + FormMenu.Show; + end; + end else + begin + if IsD2BridgeContext then + begin + D2Bridge.Validation(Edit_UserName, false); + D2Bridge.Validation(Edit_Password, false, 'Invalid username or password'); + end else + begin + MessageDlg('Invalid username or password', mterror, [mbcancel], 0); + end; + + Exit; + end; + +end; + +procedure TForm_Login.Button_LoginGoogleClick(Sender: TObject); +begin + LazarusDemo.UserLoginMode:='Google'; + + With D2Bridge.API.Auth.Google.Login do + begin + if Success then + begin + LazarusDemo.UserID:= ID; + LazarusDemo.UserName:= Name; + LazarusDemo.UserEmail:= Email; + LazarusDemo.UserURLPicture:= URLPicture; + + PrismSession.Cookies.Add('UserLogin', PrismSession.UUID); + + if FormAuth = nil then + TFormAuth.CreateInstance; + + FormAuth.Show; + end; + end; +end; + +procedure TForm_Login.Button_LoginMicrosoftClick(Sender: TObject); +begin + LazarusDemo.UserLoginMode:='Microsoft'; + + With D2Bridge.API.Auth.Microsoft.Login do + begin + if Success then + begin + LazarusDemo.UserID:= ID; + LazarusDemo.UserName:= Name; + LazarusDemo.UserEmail:= Email; + LazarusDemo.UserURLPicture:= PictureBase64; + + PrismSession.Cookies.Add('UserLogin', PrismSession.UUID); + + if FormAuth = nil then + TFormAuth.CreateInstance; + + FormAuth.Show; + end; + end; +end; + +procedure TForm_Login.Button_ShowPassClick(Sender: TObject); +begin + if Edit_Password.PasswordChar = '*' then + begin + Edit_Password.PasswordChar:= #0; + + if IsD2BridgeContext then + D2Bridge.PrismControlFromVCLObj(Edit_Password).AsEdit.DataType:= TPrismFieldType.PrismFieldTypeString; + end else + begin + Edit_Password.PasswordChar:= '*'; + + if IsD2BridgeContext then + D2Bridge.PrismControlFromVCLObj(Edit_Password).AsEdit.DataType:= TPrismFieldType.PrismFieldTypePassword; + end; + +end; + +procedure TForm_Login.FormActivate(Sender: TObject); +begin + if IsDebuggerPresent then + begin + Edit_UserName.Text:= 'admin'; + Edit_Password.Text:= 'admin'; + end; + + ShowMessage('Use for login: Admin and for Password: Admin', true, true); +end; + +procedure TForm_Login.FormCreate(Sender: TObject); +begin + if not IsD2BridgeContext then + begin + Image_Logo.Picture.LoadFromFile('web\wwwroot\images\d2bridge.png'); + Image_BackGround.Picture.LoadFromFile('web\wwwroot\images\bridge.jpg'); + + Button_LoginGoogle.Visible:= false; + Button_LoginMicrosoft.Visible:= false; + end; +end; + +procedure TForm_Login.PageLoaded; +//var +// vPrismSession: TPrismSession; +// vLazarusDemoSession: TLazarusDemoSession; +begin + inherited; + + //if PrismBaseClass.Sessions.Exist(PrismSession.Cookies.GetCookieValue('UserLogin')) then + //begin + // vPrismSession:= PrismBaseClass.Sessions.Item[PrismSession.Cookies.GetCookieValue('UserLogin')] as TPrismSession; + // + // vLazarusDemoSession:= TLazarusDemoSession(vPrismSession.Data); + // + // LazarusDemo.UserLoginMode:= vLazarusDemoSession.UserLoginMode; + // LazarusDemo.UserID:= vLazarusDemoSession.UserID; + // LazarusDemo.UserName:= vLazarusDemoSession.UserName; + // LazarusDemo.UserEmail:= vLazarusDemoSession.UserEmail; + // LazarusDemo.UserURLPicture:= vLazarusDemoSession.UserURLPicture; + // + // PrismSession.Cookies.Add('UserLogin', PrismSession.UUID); + // + // if FormControls = nil then + // TFormControls.CreateInstance; + // + // FormControls.Show; + //end; +end; + +procedure TForm_Login.ExportD2Bridge; +begin + inherited; + + Title:= 'My D2Bridge Web Application'; + SubTitle:= 'My WebApp'; + + //Background color + D2Bridge.HTML.Render.BodyStyle:= 'background-color: #f0f0f0;'; + + //TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + //Export yours Controls + with D2Bridge.Items.add do + begin + //Image Backgroup Full Size *Use also ImageFromURL... + //ImageFromTImage(Image_BackGround, CSSClass.Image.Image_BG20_FullSize); + ImageFromURL('images/bridge.jpg', CSSClass.Image.Image_BG20_FullSize); + + with Card do + begin + CSSClasses:= CSSClass.Card.Card_Center; + + //ImageICOFromTImage(Image_Logo, CSSClass.Col.ColSize4); + ImageICOFromURL('images/d2bridge.png' , CSSClass.Col.ColSize4); + + with BodyItems.Add do + begin + with Row.Items.Add do + Col.Add.VCLObj(Label_Login); + + with Row.Items.Add do + Col.Add.VCLObj(Edit_UserName, 'ValidationLogin', true); + + with Row.Items.Add do + with Col.Items.add do //Example Edit + Button same row and col + begin + VCLObj(Edit_Password, 'ValidationLogin', true); + VCLObj(Button_ShowPass, CSSClass.Button.view); + end; + + with Row.Items.Add do + Col.Add.VCLObj(Button_Login, 'ValidationLogin', false, CSSClass.Col.colsize12); + + with Row.Items.Add do + Col.Add.VCLObj(Button_LoginGoogle, 'ValidationLogin', false, CSSClass.Button.google + ' ' + CSSClass.Col.colsize12); + + with Row.Items.Add do + Col.Add.VCLObj(Button_LoginMicrosoft, 'ValidationLogin', false, CSSClass.Button.microsoft + ' ' + CSSClass.Col.colsize12); + end; + + end; + end; +end; + +procedure TForm_Login.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + inherited; + +end; + +procedure TForm_Login.RenderD2Bridge(const PrismControl: TPrismControl; var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitauth.lfm b/Beta/Demos/Lazarus_linux/unitauth.lfm new file mode 100644 index 0000000..da0c6e4 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitauth.lfm @@ -0,0 +1,82 @@ +object FormAuth: TFormAuth + Left = 524 + Height = 165 + Top = 140 + Width = 372 + Caption = 'FormAuth' + ClientHeight = 165 + ClientWidth = 372 + OnShow = FormShow + LCLVersion = '3.6.0.0' + object Image_Photo: TImage + Left = 24 + Height = 113 + Top = 16 + Width = 120 + end + object Label_Mode: TLabel + Left = 164 + Height = 15 + Top = 24 + Width = 67 + Caption = 'Login Mode:' + end + object Label_ModeValue: TLabel + Left = 237 + Height = 15 + Top = 24 + Width = 40 + Caption = 'Manual' + end + object Label_ID: TLabel + Left = 164 + Height = 15 + Top = 47 + Width = 40 + Caption = 'User ID:' + end + object Label_IDValue: TLabel + Left = 237 + Height = 15 + Top = 47 + Width = 24 + Caption = '0001' + end + object Label_NameValue: TLabel + Left = 237 + Height = 15 + Top = 66 + Width = 93 + Caption = 'Label_NameValue' + end + object Label_EmailValue: TLabel + Left = 237 + Height = 15 + Top = 85 + Width = 90 + Caption = 'Label_EmailValue' + end + object Label_Email: TLabel + Left = 164 + Height = 15 + Top = 85 + Width = 32 + Caption = 'Email:' + end + object Label_Name: TLabel + Left = 164 + Height = 15 + Top = 66 + Width = 61 + Caption = 'User Name:' + end + object Button_Logout: TButton + Left = 164 + Height = 25 + Top = 104 + Width = 104 + Caption = 'Logout' + TabOrder = 0 + OnClick = Button_LogoutClick + end +end diff --git a/Beta/Demos/Lazarus_linux/unitauth.pas b/Beta/Demos/Lazarus_linux/unitauth.pas new file mode 100644 index 0000000..c8b3d1e --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitauth.pas @@ -0,0 +1,168 @@ +unit unitAuth; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +interface + +uses + Classes, SysUtils, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, + D2Bridge.Forms; + +type + + { TFormAuth } + + TFormAuth = class(TD2BridgeForm) + Button_Logout: TButton; + Image_Photo: TImage; + Label_Email: TLabel; + Label_EmailValue: TLabel; + Label_ID: TLabel; + Label_IDValue: TLabel; + Label_Mode: TLabel; + Label_ModeValue: TLabel; + Label_Name: TLabel; + Label_NameValue: TLabel; + procedure Button_LogoutClick(Sender: TObject); + procedure FormShow(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + protected + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; var HTMLControl: string); override; + procedure EndRender; override; + end; + +function FormAuth: TFormAuth; + +implementation + +uses + LazarusWebApp, D2BridgeFormTemplate; + +{$R *.lfm} + +function FormAuth: TFormAuth; +begin + result:= (TFormAuth.GetInstance as TFormAuth); +end; + +procedure TFormAuth.FormShow(Sender: TObject); +begin + Label_ModeValue.Caption:= LazarusDemo.UserLoginMode; + Label_IDValue.Caption:= LazarusDemo.UserID; + Label_NameValue.Caption:= LazarusDemo.UserName; + Label_EmailValue.Caption:= LazarusDemo.UserEmail; +end; + +procedure TFormAuth.Button_LogoutClick(Sender: TObject); +begin + if LazarusDemo.UserLoginMode = 'Google' then + D2Bridge.API.Auth.Google.Logout + else + if LazarusDemo.UserLoginMode = 'Microsoft' then + D2Bridge.API.Auth.Microsoft.Logout; + + PrismSession.Close(true); +end; + +procedure TFormAuth.ExportD2Bridge; +begin + inherited; + + Title:= 'My D2Bridge Form'; + + TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + //Export yours Controls + with D2Bridge.Items.add do + begin + with Row.Items.Add do + with Card('User Information', CSSClass.Col.colsize6) do + begin + Title:= 'Bellow about your login'; + + with BodyItems.Add do + begin + //Image + with Row.Items.add do + Col6.Add.VCLObj(Image_Photo); + + //Login Mode + with Row.Items.add do + begin + ColAuto.Add.VCLObj(Label_Mode); + ColAuto.Add.VCLObj(Label_ModeValue); + end; + + //ID + with Row.Items.add do + begin + ColAuto.Add.VCLObj(Label_ID); + ColAuto.Add.VCLObj(Label_IDValue); + end; + + //User Name + with Row.Items.add do + begin + ColAuto.Add.VCLObj(Label_Name); + ColAuto.Add.VCLObj(Label_NameValue); + end; + + //User Email + with Row.Items.add do + begin + ColAuto.Add.VCLObj(Label_Email); + ColAuto.Add.VCLObj(Label_EmailValue); + end; + + //Close + with Row.Items.add do + ColAuto.Add.VCLObj(Button_Logout, CSSClass.Button.close); + end; + end; + end; +end; + +procedure TFormAuth.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + inherited; + + //Change Init Property of Prism Controls + { + if PrismControl.VCLComponent = Edit1 then + PrismControl.AsEdit.DataType:= TPrismFieldType.PrismFieldTypeInteger; + + if PrismControl.IsDBGrid then + begin + PrismControl.AsDBGrid.RecordsPerPage:= 10; + PrismControl.AsDBGrid.MaxRecords:= 2000; + end; + } +end; + +procedure TFormAuth.RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +procedure TFormAuth.EndRender; +begin + D2Bridge.PrismControlFromVCLObj(Image_Photo).AsImage.URLImage:= LazarusDemo.UserURLPicture; +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitcamera.lfm b/Beta/Demos/Lazarus_linux/unitcamera.lfm new file mode 100644 index 0000000..1828bbb --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitcamera.lfm @@ -0,0 +1,97 @@ +object FormCamera: TFormCamera + Left = 479 + Height = 441 + Top = 233 + Width = 710 + Caption = 'FormCamera' + ClientHeight = 441 + ClientWidth = 710 + OnCreate = FormCreate + LCLVersion = '3.8.0.0' + object Image1: TImage + Left = 184 + Height = 281 + Top = 24 + Width = 305 + end + object ComboBox1: TComboBox + Left = 184 + Height = 23 + Top = 320 + Width = 305 + ItemHeight = 15 + Style = csDropDownList + TabOrder = 0 + end + object Button8: TButton + Left = 495 + Height = 25 + Top = 318 + Width = 34 + TabOrder = 1 + OnClick = Button8Click + end + object Button1: TButton + Left = 144 + Height = 25 + Top = 368 + Width = 75 + Caption = 'Start' + TabOrder = 2 + OnClick = Button1Click + end + object Button2: TButton + Left = 225 + Height = 25 + Top = 368 + Width = 75 + Caption = 'Stop' + TabOrder = 3 + OnClick = Button2Click + end + object Button3: TButton + Left = 323 + Height = 25 + Top = 368 + Width = 75 + Caption = 'Take Picture' + TabOrder = 4 + OnClick = Button3Click + end + object Button4: TButton + Left = 419 + Height = 25 + Top = 368 + Width = 75 + Caption = 'Rec Video' + TabOrder = 5 + OnClick = Button4Click + end + object Button5: TButton + Left = 500 + Height = 25 + Top = 368 + Width = 75 + Caption = 'Save Video' + TabOrder = 6 + OnClick = Button5Click + end + object Button6: TButton + Left = 581 + Height = 25 + Top = 368 + Width = 75 + Caption = 'Cancel Video' + TabOrder = 7 + OnClick = Button6Click + end + object Button7: TButton + Left = 64 + Height = 25 + Top = 368 + Width = 75 + Caption = 'Permission' + TabOrder = 8 + OnClick = Button7Click + end +end diff --git a/Beta/Demos/Lazarus_linux/unitcamera.pas b/Beta/Demos/Lazarus_linux/unitcamera.pas new file mode 100644 index 0000000..801da8e --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitcamera.pas @@ -0,0 +1,235 @@ +unit UnitCamera; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +interface + +uses + Classes, SysUtils, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, + D2Bridge.Forms; + +type + + { TFormCamera } + + TFormCamera = class(TD2BridgeForm) + Button1: TButton; + Button2: TButton; + Button3: TButton; + Button4: TButton; + Button5: TButton; + Button6: TButton; + Button7: TButton; + Button8: TButton; + ComboBox1: TComboBox; + Image1: TImage; + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + procedure Button4Click(Sender: TObject); + procedure Button5Click(Sender: TObject); + procedure Button6Click(Sender: TObject); + procedure Button7Click(Sender: TObject); + procedure Button8Click(Sender: TObject); + procedure FormCreate(Sender: TObject); + private + procedure UpdateCameraList(Sender: TObject); + public + { Public declarations } + protected + procedure Upload(AFiles: TStrings; Sender: TObject); override; + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; var HTMLControl: string); override; + end; + +function FormCamera: TFormCamera; + +implementation + +uses + LazarusWebApp, D2BridgeFormTemplate; + +{$R *.lfm} + +function FormCamera: TFormCamera; +begin + result:= (TFormCamera.GetInstance as TFormCamera); +end; + +procedure TFormCamera.FormCreate(Sender: TObject); +begin + Image1.Camera.OnChangeDevices:= UpdateCameraList; +end; + +procedure TFormCamera.Button8Click(Sender: TObject); +begin + if ComboBox1.Items.Count > 0 then + begin + Image1.Camera.CurrentDevice:= Image1.Camera.Devices.ItemFromIndex(ComboBox1.ItemIndex); + + //ShowMessage('new camera "' + Image1.Camera.CurrentDevice.Name + '" selected'); + + //Modify camera now + if Image1.Camera.Started then + begin + Image1.Camera.Stop; + Image1.Camera.Start; + end; + end; +end; + +procedure TFormCamera.Button7Click(Sender: TObject); +begin + Image1.Camera.RequestPermission; +end; + +procedure TFormCamera.Button1Click(Sender: TObject); +begin + if not Image1.Camera.Allowed then + Image1.Camera.RequestPermission; + + Image1.Camera.Start; +end; + +procedure TFormCamera.Button2Click(Sender: TObject); +begin + Image1.Camera.Stop; +end; + +procedure TFormCamera.Button3Click(Sender: TObject); +begin + Image1.Camera.TakePicture; +end; + +procedure TFormCamera.Button4Click(Sender: TObject); +begin + if not Image1.Camera.Allowed then + Image1.Camera.RequestPermission; + + Image1.Camera.RecordVideo; + +end; + +procedure TFormCamera.Button5Click(Sender: TObject); +begin + Image1.Camera.SaveVideo; +end; + +procedure TFormCamera.Button6Click(Sender: TObject); +begin + Image1.Camera.CancelVideo; +end; + +//Your can use also update camera list in onActivate event +procedure TFormCamera.UpdateCameraList(Sender: TObject); +var + I: Integer; +begin + ComboBox1.Items.Clear; + + if Image1.Camera.Devices.Count > 0 then + begin + for I := 0 to Pred(Image1.Camera.Devices.Count) do + ComboBox1.Items.Add(Image1.Camera.Devices.Items[I].Name); + + ComboBox1.ItemIndex:= Image1.Camera.CurrentDeviceIndex; + end; +end; + +procedure TFormCamera.Upload(AFiles: TStrings; Sender: TObject); +begin + ShowMessage('New file received on '+ ExtractFileName(AFiles[0]), true, true); + + //Example identify sender + { + if Sender is TPrismControl then + if (Sender as TPrismControl).VCLComponent = Image1 then + begin + /// + end; + } +end; + +procedure TFormCamera.ExportD2Bridge; +begin + inherited; + + Title:= 'My D2Bridge Form'; + + TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + //Export yours Controls + with D2Bridge.Items.add do + begin + with Row(CSSClass.Col.Align.center).Items.Add do + Col6.Add.Camera(Image1); + + with Row(CSSClass.Col.Align.center).Items.Add do + begin + with ColAuto.Items.Add do + begin + VCLObj(ComboBox1); + VCLObj(Button8, CSSClass.Button.select); + end; + end; + + with Row(CSSClass.Col.Align.center).Items.Add do + begin + with ColAuto.Items.Add do + begin + VCLObj(Button7, CSSClass.Button.userSecurity); + VCLObj(Button1, CSSClass.Button.start); + VCLObj(Button2, CSSClass.Button.stop); + end; + + ColAuto.Items.Add.VCLObj(Button3, CSSClass.Button.camera); + + with ColAuto.Items.Add do + begin + VCLObj(Button4, CSSClass.Button.video); + VCLObj(Button5, CSSClass.Button.videofile); + VCLObj(Button6, CSSClass.Button.videoNo); + end; + end; + end; +end; + +procedure TFormCamera.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + inherited; + + //Change Init Property of Prism Controls + { + if PrismControl.VCLComponent = Edit1 then + PrismControl.AsEdit.DataType:= TPrismFieldType.PrismFieldTypeInteger; + + if PrismControl.IsDBGrid then + begin + PrismControl.AsDBGrid.RecordsPerPage:= 10; + PrismControl.AsDBGrid.MaxRecords:= 2000; + end; + } +end; + +procedure TFormCamera.RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitcardgriddatamodel.lfm b/Beta/Demos/Lazarus_linux/unitcardgriddatamodel.lfm new file mode 100644 index 0000000..6ebda12 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitcardgriddatamodel.lfm @@ -0,0 +1,196 @@ +object FormCardGridDataModel: TFormCardGridDataModel + Left = 611 + Height = 488 + Top = 101 + Width = 562 + Caption = 'FormCardGridDataModel' + ClientHeight = 488 + ClientWidth = 562 + OnShow = FormShow + LCLVersion = '3.6.0.0' + object Panel9: TPanel + Left = 24 + Height = 137 + Top = 32 + Width = 185 + ClientHeight = 137 + ClientWidth = 185 + ParentBackground = False + TabOrder = 0 + object Label_Country: TLabel + Left = 11 + Height = 15 + Top = 9 + Width = 46 + Caption = 'Country:' + end + object DBText_Country: TDBText + Left = 65 + Height = 13 + Top = 9 + Width = 93 + DataField = 'country' + DataSource = DataSource1 + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentFont = False + end + object Label_Population: TLabel + Left = 11 + Height = 15 + Top = 41 + Width = 61 + Caption = 'Population:' + end + object DBText_Population: TDBText + Left = 65 + Height = 13 + Top = 41 + Width = 108 + Alignment = taRightJustify + DataField = 'population' + DataSource = DataSource1 + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentFont = False + end + object Label_DDI: TLabel + Left = 11 + Height = 15 + Top = 73 + Width = 22 + Caption = 'DDI:' + end + object DBText_DDI: TDBText + Left = 65 + Height = 13 + Top = 73 + Width = 69 + Alignment = taRightJustify + DataField = 'ddi' + DataSource = DataSource1 + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentFont = False + end + object Button_View: TButton + Left = 11 + Height = 25 + Top = 104 + Width = 75 + Caption = 'View' + TabOrder = 0 + OnClick = Button_ViewClick + end + end + object BufDataset1: TBufDataset + FieldDefs = <> + Left = 280 + Top = 8 + object BufDataset1id: TLongintField + FieldKind = fkData + FieldName = 'id' + Index = 0 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1country: TStringField + FieldKind = fkData + FieldName = 'country' + Index = 1 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 100 + end + object BufDataset1ddi: TStringField + FieldKind = fkData + FieldName = 'ddi' + Index = 2 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 10 + end + object BufDataset1population: TLongintField + FieldKind = fkData + FieldName = 'population' + Index = 3 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1Continent: TStringField + FieldKind = fkData + FieldName = 'Continent' + Index = 4 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 30 + end + object BufDataset1Language: TStringField + FieldKind = fkData + FieldName = 'Language' + Index = 5 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1Capital: TStringField + FieldKind = fkData + FieldName = 'Capital' + Index = 6 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1CurrencyName: TStringField + FieldKind = fkData + FieldName = 'CurrencyName' + Index = 7 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1CurrencySimbol: TStringField + FieldKind = fkData + FieldName = 'CurrencySimbol' + Index = 8 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 5 + end + object BufDataset1CreateAt: TDateField + FieldKind = fkData + FieldName = 'CreateAt' + Index = 9 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + end + object DataSource1: TDataSource + DataSet = BufDataset1 + Left = 352 + Top = 8 + end +end diff --git a/Beta/Demos/Lazarus_linux/unitcardgriddatamodel.pas b/Beta/Demos/Lazarus_linux/unitcardgriddatamodel.pas new file mode 100644 index 0000000..cbcbe51 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitcardgriddatamodel.pas @@ -0,0 +1,198 @@ +unit unitCardGridDataModel; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +interface + +uses + Classes, SysUtils, BufDataset, DB, Controls, Graphics, Dialogs, StdCtrls, DBCtrls, + ExtCtrls, D2Bridge.Forms; + +type + + { TFormCardGridDataModel } + + TFormCardGridDataModel = class(TD2BridgeForm) + BufDataset1: TBufDataset; + BufDataset1Capital: TStringField; + BufDataset1Continent: TStringField; + BufDataset1country: TStringField; + BufDataset1CreateAt: TDateField; + BufDataset1CurrencyName: TStringField; + BufDataset1CurrencySimbol: TStringField; + BufDataset1ddi: TStringField; + BufDataset1id: TLongintField; + BufDataset1Language: TStringField; + BufDataset1population: TLongintField; + Button_View: TButton; + DataSource1: TDataSource; + DBText_Country: TDBText; + DBText_DDI: TDBText; + DBText_Population: TDBText; + Label_Country: TLabel; + Label_DDI: TLabel; + Label_Population: TLabel; + Panel9: TPanel; + procedure Button_ViewClick(Sender: TObject); + procedure FormShow(Sender: TObject); + private + procedure PopuleData; + procedure CardGridClick(PrismControlClick: TPrismControl; ARow: Integer; APrismCardGrid: TPrismCardGridDataModel); override; + public + { Public declarations } + protected + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); override; + end; + +function FormCardGridDataModel: TFormCardGridDataModel; + +implementation + +uses + LazarusWebApp, D2BridgeFormTemplate; + +{$R *.lfm} + +function FormCardGridDataModel: TFormCardGridDataModel; +begin + result:= (TFormCardGridDataModel.GetInstance as TFormCardGridDataModel); +end; + +procedure TFormCardGridDataModel.Button_ViewClick(Sender: TObject); +begin + ShowMessage(BufDataset1.FieldByName('Country').AsString); +end; + +procedure TFormCardGridDataModel.FormShow(Sender: TObject); +begin + PopuleData; +end; + +procedure TFormCardGridDataModel.PopuleData; +begin + BufDataset1.Close; + BufDataset1.CreateDataset; + + BufDataset1.AppendRecord([1, 'China', '86', 1444216107, 'Asia', 'Mandarin', 'Beijing', 'Yuan', 'Â¥']); + BufDataset1.AppendRecord([2, 'India', '91', 1393409038, 'Asia', 'Hindi, English', 'New Delhi', 'Rupee', '₹']); + BufDataset1.AppendRecord([3, 'United States', '1', 332915073, 'North America', 'English', 'Washington, D.C.', 'Dollar', '$']); + BufDataset1.AppendRecord([4, 'Indonesia', '62', 276361783, 'Asia', 'Indonesian', 'Jakarta', 'Rupiah', 'Rp']); + BufDataset1.AppendRecord([5, 'Pakistan', '92', 225199937, 'Asia', 'Urdu, English', 'Islamabad', 'Rupee', '₨']); + BufDataset1.AppendRecord([6, 'Brazil', '55', 213993437, 'South America', 'Portuguese', 'Brasília', 'Real', 'R$']); + BufDataset1.AppendRecord([7, 'Nigeria', '234', 211400708, 'Africa', 'English', 'Abuja', 'Naira', '₦']); + BufDataset1.AppendRecord([8, 'Bangladesh', '880', 166303498, 'Asia', 'Bengali', 'Dhaka', 'Taka', 'à§³']); + BufDataset1.AppendRecord([9, 'Russia', '7', 145912025, 'Europe/Asia', 'Russian', 'Moscow', 'Ruble', '₽']); + BufDataset1.AppendRecord([10, 'Mexico', '52', 130262216, 'North America', 'Spanish', 'Mexico City', 'Peso', '$']); + BufDataset1.AppendRecord([11, 'Japan', '81', 125943834, 'Asia', 'Japanese', 'Tokyo', 'Yen', 'Â¥']); + BufDataset1.AppendRecord([12, 'Ethiopia', '251', 120858976, 'Africa', 'Amharic', 'Addis Ababa', 'Birr', 'Br']); + BufDataset1.AppendRecord([13, 'Philippines', '63', 113850055, 'Asia', 'Filipino, English', 'Manila', 'Peso', '₱']); + BufDataset1.AppendRecord([14, 'Egypt', '20', 104258327, 'Africa', 'Arabic', 'Cairo', 'Pound', '£']); + BufDataset1.AppendRecord([15, 'Vietnam', '84', 97429061, 'Asia', 'Vietnamese', 'Hanoi', 'Dong', 'â‚«']); + BufDataset1.AppendRecord([16, 'DR Congo', '243', 90003954, 'Africa', 'French', 'Kinshasa', 'Franc', 'FC']); + BufDataset1.AppendRecord([17, 'Turkey', '90', 84339067, 'Europe/Asia', 'Turkish', 'Ankara', 'Lira', '₺']); + BufDataset1.AppendRecord([18, 'Iran', '98', 85004578, 'Asia', 'Persian', 'Tehran', 'Rial', 'ï·¼']); + BufDataset1.AppendRecord([19, 'Germany', '49', 83149300, 'Europe', 'German', 'Berlin', 'Euro', '€']); + BufDataset1.AppendRecord([20, 'Thailand', '66', 69950807, 'Asia', 'Thai', 'Bangkok', 'Baht', '฿']); + BufDataset1.AppendRecord([21, 'United Kingdom', '44', 67886011, 'Europe', 'English', 'London', 'Pound', '£']); + BufDataset1.AppendRecord([22, 'France', '33', 65273511, 'Europe', 'French', 'Paris', 'Euro', '€']); + BufDataset1.AppendRecord([23, 'Italy', '39', 60244639, 'Europe', 'Italian', 'Rome', 'Euro', '€']); + BufDataset1.AppendRecord([24, 'South Africa', '27', 60041932, 'Africa', 'Zulu, Xhosa, Afrikaans, English', 'Pretoria', 'Rand', 'R']); + BufDataset1.AppendRecord([25, 'Tanzania', '255', 59895231, 'Africa', 'Swahili, English', 'Dodoma', 'Shilling', 'TSh']); + BufDataset1.AppendRecord([26, 'Myanmar', '95', 54409800, 'Asia', 'Burmese', 'Naypyidaw', 'Kyat', 'K']); + BufDataset1.AppendRecord([27, 'Kenya', '254', 53771296, 'Africa', 'Swahili, English', 'Nairobi', 'Shilling', 'KSh']); + BufDataset1.AppendRecord([28, 'South Korea', '82', 51606633, 'Asia', 'Korean', 'Seoul', 'Won', 'â‚©']); + BufDataset1.AppendRecord([29, 'Colombia', '57', 50976248, 'South America', 'Spanish', 'Bogotá', 'Peso', '$']); + BufDataset1.AppendRecord([30, 'Spain', '34', 46754783, 'Europe', 'Spanish', 'Madrid', 'Euro', '€']); +end; + +procedure TFormCardGridDataModel.CardGridClick( + PrismControlClick: TPrismControl; ARow: Integer; + APrismCardGrid: TPrismCardGridDataModel); +begin + inherited CardGridClick(PrismControlClick, ARow, APrismCardGrid); +end; + +procedure TFormCardGridDataModel.ExportD2Bridge; +begin + inherited; + + Title:= 'My D2Bridge Form'; + + TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + //Export yours Controls + with D2Bridge.Items.add do + begin + with CardGrid(DataSource1) do + begin + //EqualHeight:= true; + //CardGridSize:= CSSClass.CardGrid.CardGridX2; + //Space:= CSSClass.Space.gutter4; + + with CardDataModel.Items.Add do + begin + //Country + with Row.Items.Add do + begin + ColAuto.Add.VCLObj(Label_Country); + Col.Add.VCLObj(DBText_Country); + end; + + //Population + with Row.Items.Add do + begin + ColAuto.Add.VCLObj(Label_Population); + Col.Add.VCLObj(DBText_Population); + end; + + //DDI + with Row.Items.Add do + begin + ColAuto.Add.VCLObj(Label_DDI); + Col.Add.VCLObj(DBText_DDI); + end; + + with Row.Items.Add do + ColAuto.Add.VCLObj(Button_View, CSSClass.Button.view); + end; + end; + end; +end; + +procedure TFormCardGridDataModel.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + inherited; + + //Change Init Property of Prism Controls + { + if PrismControl.VCLComponent = Edit1 then + PrismControl.AsEdit.DataType:= TPrismFieldType.PrismFieldTypeInteger; + + if PrismControl.IsDBGrid then + begin + PrismControl.AsDBGrid.RecordsPerPage:= 10; + PrismControl.AsDBGrid.MaxRecords:= 2000; + end; + } +end; + +procedure TFormCardGridDataModel.RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitcontrols.lfm b/Beta/Demos/Lazarus_linux/unitcontrols.lfm new file mode 100644 index 0000000..75f6472 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitcontrols.lfm @@ -0,0 +1,1957 @@ +object FormControls: TFormControls + Left = 544 + Height = 876 + Top = 89 + Width = 379 + ClientHeight = 876 + ClientWidth = 379 + LCLVersion = '3.8.0.0' + object Label1: TLabel + Left = 8 + Height = 15 + Top = 276 + Width = 81 + Caption = 'Select one item' + end + object Label_Titulo: TLabel + Left = 8 + Height = 21 + Top = 8 + Width = 135 + Caption = 'DEMO CONTROLS' + Font.Color = clWindowText + Font.Height = -16 + Font.Name = 'Segoe UI' + Font.Style = [fsBold] + ParentFont = False + end + object Image_Static: TImage + Left = 8 + Height = 105 + Top = 551 + Width = 105 + Picture.Data = { + 0A544A706567496D616765ECB20000FFD8FFE000104A46494600010201004800 + 480000FFED002C50686F746F73686F7020332E30003842494D03ED0000000000 + 1000480000000100010048000000010001FFE1845D687474703A2F2F6E732E61 + 646F62652E636F6D2F7861702F312E302F003C3F787061636B65742062656769 + 6E3D22EFBBBF222069643D2257354D304D7043656869487A7265537A4E54637A + 6B633964223F3E0A3C783A786D706D65746120786D6C6E733A783D2261646F62 + 653A6E733A6D6574612F2220783A786D70746B3D2241646F626520584D502043 + 6F726520392E302D633030312037392E313465636234322C20323032322F3132 + 2F30322D31393A31323A34342020202020202020223E0A2020203C7264663A52 + 444620786D6C6E733A7264663D22687474703A2F2F7777772E77332E6F72672F + 313939392F30322F32322D7264662D73796E7461782D6E7323223E0A20202020 + 20203C7264663A4465736372697074696F6E207264663A61626F75743D22220A + 202020202020202020202020786D6C6E733A64633D22687474703A2F2F707572 + 6C2E6F72672F64632F656C656D656E74732F312E312F220A2020202020202020 + 20202020786D6C6E733A786D703D22687474703A2F2F6E732E61646F62652E63 + 6F6D2F7861702F312E302F220A202020202020202020202020786D6C6E733A78 + 6D7047496D673D22687474703A2F2F6E732E61646F62652E636F6D2F7861702F + 312E302F672F696D672F220A202020202020202020202020786D6C6E733A786D + 704D4D3D22687474703A2F2F6E732E61646F62652E636F6D2F7861702F312E30 + 2F6D6D2F220A202020202020202020202020786D6C6E733A73745265663D2268 + 7474703A2F2F6E732E61646F62652E636F6D2F7861702F312E302F7354797065 + 2F5265736F7572636552656623220A202020202020202020202020786D6C6E73 + 3A73744576743D22687474703A2F2F6E732E61646F62652E636F6D2F7861702F + 312E302F73547970652F5265736F757263654576656E7423220A202020202020 + 202020202020786D6C6E733A696C6C7573747261746F723D22687474703A2F2F + 6E732E61646F62652E636F6D2F696C6C7573747261746F722F312E302F220A20 + 2020202020202020202020786D6C6E733A7064663D22687474703A2F2F6E732E + 61646F62652E636F6D2F7064662F312E332F220A202020202020202020202020 + 786D6C6E733A706466783D22687474703A2F2F6E732E61646F62652E636F6D2F + 706466782F312E332F223E0A2020202020202020203C64633A666F726D61743E + 696D6167652F6A7065673C2F64633A666F726D61743E0A202020202020202020 + 3C64633A7469746C653E0A2020202020202020202020203C7264663A416C743E + 0A2020202020202020202020202020203C7264663A6C6920786D6C3A6C616E67 + 3D22782D64656661756C74223E4C6F676F2044324272696467653C2F7264663A + 6C693E0A2020202020202020202020203C2F7264663A416C743E0A2020202020 + 202020203C2F64633A7469746C653E0A2020202020202020203C786D703A4372 + 6561746F72546F6F6C3E41646F626520496C6C7573747261746F722032372E33 + 202857696E646F7773293C2F786D703A43726561746F72546F6F6C3E0A202020 + 2020202020203C786D703A437265617465446174653E323032332D31312D3231 + 5431313A30383A35372D30333A30303C2F786D703A437265617465446174653E + 0A2020202020202020203C786D703A4D6F64696679446174653E323032332D31 + 312D32315431343A30393A30315A3C2F786D703A4D6F64696679446174653E0A + 2020202020202020203C786D703A4D65746164617461446174653E323032332D + 31312D32315431313A30383A35372D30333A30303C2F786D703A4D6574616461 + 7461446174653E0A2020202020202020203C786D703A5468756D626E61696C73 + 3E0A2020202020202020202020203C7264663A416C743E0A2020202020202020 + 202020202020203C7264663A6C69207264663A7061727365547970653D225265 + 736F75726365223E0A2020202020202020202020202020202020203C786D7047 + 496D673A77696474683E3233323C2F786D7047496D673A77696474683E0A2020 + 202020202020202020202020202020203C786D7047496D673A6865696768743E + 3235363C2F786D7047496D673A6865696768743E0A2020202020202020202020 + 202020202020203C786D7047496D673A666F726D61743E4A5045473C2F786D70 + 47496D673A666F726D61743E0A2020202020202020202020202020202020203C + 786D7047496D673A696D6167653E2F396A2F34414151536B5A4A526741424167 + 4541534142494141442F37514173554768766447397A6147397749444D754D41 + 4134516B6C4E412B304141414141414241415341414141414541262378413B41 + 51424941414141415141422F2B494D57456C4451313951556B39475355784641 + 4145424141414D53457870626D38434541414162573530636C4A485169425957 + 566F67423834414167414A262378413B414159414D51414159574E7A63453154 + 526C5141414141415355564449484E5352304941414141414141414141414141 + 4141414141506257414145414141414130793149554341674141414126237841 + 3B41414141414141414141414141414141414141414141414141414141414141 + 4141414141414141414141414141414141414141414141414141414152593342 + 7964414141415641414141417A262378413B5A47567A59774141415951414141 + 427364335277644141414166414141414155596D747764414141416751414141 + 4155636C685A5767414141686741414141555A31685A57674141416977412623 + 78413B41414155596C685A57674141416B4141414141555A4731755A41414141 + 6C5141414142775A47316B5A4141414173514141414349646E566C5A41414141 + 30774141414347646D6C6C64774141262378413B413951414141416B62485674 + 61514141412F6741414141556257566863774141424177414141416B6447566A + 61414141424441414141414D636C525351774141424477414141674D5A315253 + 262378413B51774141424477414141674D596C52535177414142447741414167 + 4D64475634644141414141424462334235636D6C6E614851674B474D70494445 + 354F546767534756336247563064433151262378413B59574E7259584A6B4945 + 4E7662584268626E6B414147526C63324D414141414141414141456E4E535230 + 4967535556444E6A45354E6A59744D6934784141414141414141414141414141 + 4153262378413B63314A485169424A52554D324D546B324E6930794C6A454141 + 4141414141414141414141414141414141414141414141414141414141414141 + 41414141414141414141414141414141414141262378413B4141414141414141 + 414141414146685A57694141414141414141447A55514142414141414152624D + 57466C6149414141414141414141414141414141414141414141425957566F67 + 41414141262378413B414141416236494141446A31414141446B46685A576941 + 4141414141414142696D5141417434554141426A6157466C6149414141414141 + 414143536741414150684141417473396B5A584E6A262378413B414141414141 + 414141425A4A52554D676148523063446F764C336433647935705A574D755932 + 674141414141414141414141414141425A4A52554D676148523063446F764C33 + 643364793570262378413B5A574D755932674141414141414141414141414141 + 4141414141414141414141414141414141414141414141414141414141414141 + 4141414141414141414141414141415A47567A59774141262378413B41414141 + 4141417553555644494459784F5459324C5449754D5342455A575A6864577830 + 49464A485169426A623278766458496763334268593255674C53427A556B6443 + 4141414141414141262378413B414141414141417553555644494459784F5459 + 324C5449754D5342455A575A686457783049464A485169426A62327876645849 + 6763334268593255674C53427A556B64434141414141414141262378413B4141 + 4141414141414141414141414141414141414147526C63324D41414141414141 + 41414C464A6C5A6D56795A57356A5A534257615756336157356E49454E76626D + 527064476C7662694270262378413B6269424A52554D324D546B324E6930794C + 6A4541414141414141414141414141414378535A575A6C636D56755932556756 + 6D6C6C64326C755A7942446232356B615852706232346761573467262378413B + 535556444E6A45354E6A59744D69347841414141414141414141414141414141 + 4141414141414141414141414141414141414232615756334141414141414154 + 705034414646387541424450262378413B464141443763774142424D4C41414E + 636E6741414141465957566F67414141414141424D4356594155414141414663 + 663532316C59584D414141414141414141415141414141414141414141262378 + 413B41414141414141414141414141414B5041414141416E4E705A7941414141 + 414151314A5549474E31636E5941414141414141414541414141414155414367 + 4150414251414751416541434D41262378413B4B414174414449414E77413741 + 4541415251424B414538415641425A414634415977426F414730416367423341 + 48774167514347414973416B414356414A6F416E77436B414B6B417267437926 + 2378413B414C634176414442414D594179774451414E554132774467414F5541 + 36774477415059412B774542415163424451455441526B424877456C41537342 + 4D674534415434425251464D41564942262378413B5751466741576342626746 + 31415877426777474C415A49426D67476841616B427351473541634542795148 + 5241646B4234514870416649422B6749444167774346414964416959434C7749 + 34262378413B416B454353774A55416C30435A774A78416E6F4368414B4F4170 + 67436F674B734172594377514C4C4174554334414C724176554441414D4C4178 + 594449514D74417A674451774E5041316F44262378413B5A674E794133344469 + 674F574136494472674F364138634430775067412B77442B51514742424D4549 + 415174424473455341525642474D456351522B424977456D67536F424C594578 + 415454262378413B424F45453841542B425130464841557242546F4653515659 + 4257634664775747425A594670675731426355463151586C4266594742675957 + 426963474E775A49426C6B4761675A37426F7747262378413B6E516176427341 + 473051626A427655484277635A4279734850516450423245486441654742356B + 487241652F423949483551663443417349487767794345594957676875434949 + 496C676971262378413B434C344930676A6E4350734A45416B6C43546F4A5477 + 6C6B43586B4A6A776D6B43626F4A7A776E6C4366734B45516F6E436A304B5641 + 7071436F454B6D4171754373554B3341727A4377734C262378413B4967733543 + 31454C615175414335674C73417649432B454C2B51775344436F4D5177786344 + 48554D6A67796E444D414D32517A7A4451304E4A67314144566F4E6441324F44 + 616B4E77773365262378413B4466674F45773475446B6B4F5A41352F4470734F + 74673753447534504351386C44304550586739364435595073772F50442B7751 + 4352416D45454D515952422B454A73517552445845505552262378413B457845 + 78455538526252474D45616F527952486F456763534A684A46456D515368424B + 6A45734D5334784D4445794D5451784E6A45344D5470425046452B5555426851 + 6E46456B556168534C262378413B464B30557A685477465249564E4256574658 + 67566D785739466541574178596D466B6B576242615046724957316862364678 + 30585152646C46346B5872686653462F63594778684147475559262378413B69 + 686976474E55592B686B674755555A61786D524762635A33526F4547696F6155 + 5270334770346178527273477851624F78746A47346F6273687661484149634B + 687853484873636F787A4D262378413B4850556448683148485841646D523344 + 4865776546683541486D6F656C42362B48756B664578382B48326B666C422B2F + 482B6F6746534242494777676D43444549504168484346494958556826237841 + 3B6F53484F496673694A794A56496F496972794C6449776F6A4F434E6D493551 + 6A776950774A42386B545352384A4B736B3269554A4A54676C614357584A6363 + 6C3979596E4A6C636D68796133262378413B4A75676E4743644A4A336F6E7179 + 66634B41306F507968784B4B496F31436B474B54677061796D644B6441714169 + 6F314B6D67716D7972504B7749724E6974704B353072305377464C446B732623 + 78413B626979694C4E6374444331424C585974717933684C685975544336434C + 7263753769386B4C316F766B532F484C2F34774E5442734D4B5177327A45534D + 556F78676A47364D6649794B6A4A6A262378413B4D70737931444D4E4D30597A + 667A4F344D2F45304B7A526C4E4A3430324455544E553031687A58434E663032 + 4E7A5A794E7134323654636B4E3241336E4466584F4251345544694D4F4D6735 + 262378413B42546C434F58383576446E354F6A5936644471794F7538374C5474 + 724F366F373644776E5047553870447A6A50534939595432685065412B494435 + 675071412B344438685032452F6F6A2F69262378413B51434E415A45436D514F + 64424B55467151617842376B4977516E4A4374554C33517A7044665550415241 + 4E455230534B524D3546456B5656525A7046336B5969526D644771306277527A + 5648262378413B653066415341564953306952534E644A48556C6A53616C4A38 + 456F33536E314B7845734D53314E4C6D6B76695443704D636B793654514A4E53 + 6B32545464784F4A553575547264504145394A262378413B54354E503356416E + 5548465175314547555642526D31486D556A465366464C4855784E5458314F71 + 552F5A55516C5350564E74564B46563156634A5744315A6356716C5739316445 + 56354A58262378413B344667765748315979316B6157576C5A75466F48576C5A + 61706C7231573056626C56766C58445663686C7A57585364646546334A586870 + 65624636395877396659562B7A5941566756324371262378413B595078685432 + 47695966566953574B635976426A51324F58592B746B514753555A4F6C6C5057 + 57535A65646D505761535A75686E505765545A2B6C6F50326957614F78705132 + 6D6161664671262378413B53477166617664725432756E612F39735632797662 + 5168745947323562684A75613237456278357665472F5263437477686E446763 + 5470786C584877636B7479706E4D426331317A75485155262378413B64484230 + 7A48556F645956313458592B647074322B48645764374E3445586875654D7835 + 4B6E6D4A65656436526E716C65775237593376436643463867587A6866554639 + 6F583442666D4A2B262378413B776E386A6634522F35594248674B6942436F46 + 72676332434D494B536776534456344F36684232456749546A68556546713459 + 4F686E4B473134633768352B4942496870694D364A4D346D5A262378413B6966 + 364B5A49724B697A434C6C6F76386A474F4D796F30786A5A694E2F34356D6A73 + 36504E6F2B656B416151627044576B542B52714A49526B6E715334354E4E6B37 + 6155494A534B6C505356262378413B5835584A6C6A53576E35634B6C33575834 + 4A684D6D4C695A4A4A6D516D667961614A72566D304B62723577636E496D6339 + 35316B6E644B65514A36756E78326669352F366F476D67324B4648262378413B + 6F6261694A714B576F77616A6471506D7046616B7836553470616D6D4771614C + 7076326E6271666771464B6F784B6B3371616D71484B715071774B7264617670 + 72467973304B314572626975262378413B4C6136687278617669374141734857 + 77367246677364617953374C43737A697A7272516C744A79314537574B746747 + 326562627774326933344C685A754E473553726E43756A753674627375262378 + 413B7536653849627962765257396A37344B766F532B2F373936762F5841634D + 44737757664234384A6677747644574D5055784648457A73564C78636A475273 + 62447830484876386739794C7A4A262378413B4F736D35796A6A4B7438733279 + 37624D4E6379317A54584E746334327A7262504E382B3430446E517574453830 + 62375350394C42303054547874524A314D765654745852316C5857324E646326 + 2378413B312B44595A4E6A6F32577A5A3864703232767662674E774633497264 + 454E325733687A656F74387033362F674E754339345554687A4F4A543474766A + 592B50723548506B2F4F57453567336D262378413B6C75636635366E6F4D7569 + 3836556270304F706236755872634F7637374962744565326337696A75744F39 + 4137387A775750446C38584C782F2F4B4D38786E7A702F5130394D4C31555058 + 65262378413B396D33322B2F654B2B426E3471506B342B636636562F726E2B33 + 6638422F79592F536E397576354C2F747A2F62662F2F2F2B3441446B466B6232 + 4A6C414754414141414141662F6241495141262378413B426751454241554542 + 67554642676B474251594A437767474267674C44416F4B43776F4B4442414D44 + 41774D44417751444134504541384F44424D5446425154457877624778736348 + 783866262378413B4878386648783866487745484277634E4441305945424159 + 4768555246526F66487838664878386648783866487838664878386648783866 + 4878386648783866487838664878386648783866262378413B48783866487838 + 664878386648783866487838662F384141455167424141446F41774552414149 + 5241514D5241662F454161494141414148415145424151454141414141414141 + 4141415146262378413B417749474151414843416B4B43774541416749444151 + 454241514541414141414141414141514143417751464267634943516F4C4541 + 414341514D44416751434267634442414947416E4D42262378413B41674D5242 + 414146495249785156454745324569635945554D704768427857785169504255 + 7448684D785A69384352796776456C517A52546B714B79593350434E55516E6B + 364F7A4E686455262378413B5A485444307549494A6F4D4A4368675A684A5246 + 5271533056744E564B427279342F5045314F54305A5857466C6157317864586C + 39575A326870616D74736257357659335231646E64346558262378413B703766 + 48312B66334F456859614869496D4B6934794E6A6F2B436B3553566C7065596D + 5A71626E4A32656E354B6A704B576D7036697071717573726136766F52414149 + 434151494442515545262378413B4251594543414D4462514541416845444243 + 45534D55454655524E6849675A78675A45796F624877464D485234534E434656 + 4A696376457A4A445244676861535579576959374C4342335053262378413B4E + 654A45677864556B77674A4368675A4A6A5A464769646B6446553338714F7A77 + 796770302B507A684A536B744D54553550526C64595756706258463165583152 + 6C5A6D646F615770726247262378413B317562325231646E6434655870376648 + 312B66334F456859614869496D4B6934794E6A6F2B446C4A57576C35695A6D70 + 75636E5A36666B714F6B7061616E714B6D717136797472712B762F6126237841 + 3B414177444151414345514D52414438416C476E2B563958456B767161566333 + 467A417741673448303667416B4F33656C5255444F3179617648513951414C35 + 2F6A3065537A364A456A795246262378413B6E7045743547357674476D524A4B + 6D43367330413474576E456F7A4B6A553639516676714B353568452B6D593978 + 5A3438426B5056412B3844384438664554503830502B5545306E2F6A50622623 + 78413B2F774455504A6D71374B2F786D6675503368336E625038416973506648 + 2F636C3554625730317A4C3663517161565A69614B716A717A4539414D364F55 + 6742753872474A4B62526166356674262378413B395053585570627236354943 + 793230496A586170437456755A49493333432F4C766D4F5A35544B6F38504433 + 2F6A39726B52686945626C78635864742B33394336793062536453743550714E + 262378413B7A497438674C4C5A7941463341334A546941476F4F6F423565436E + 4250504F4239513950662B5037504E4F50424849505366563366712F462B5365 + 2F6C2F704E7A70336E6978457057534761262378413B4B5A37653569504B4B56 + 665459565274756832494F34373568396F3568505479726D434C485562757737 + 4B776D47706A6649673052794F79432F4E542F6C4E4C762F55682F7743546135 + 5A32262378413B542F6344342F6531647466347A4C346663784C4E6D3670324B + 72344C6565346C45554562537974396D4E464C4D666B42766B5A5341466E5A4D + 596D526F626C4E763847656176543952744C6E262378413B5250463134666679 + 706D502B6477335845484B2F495A3673776C386B4D664C3274416B4730663454 + 51306F66756F643873386548653065445075516C78615856756158454C784539 + 4F616C61262378413B2F4B7557526B44794C417849357157535139562F4A5038 + 41336C31622F58682F552B633532377A683866305055657A76307A2B48365870 + 6D6146365234312B63332F4B55577638417A42522F262378413B386E5A63366A + 73542B3550396239416550396F503738663142393559486D35644735565A6D43 + 7143574F7741334A4F42557A30665462476256426161744E4C5A5267486B4569 + 6153566E3234262378413B6F71676246764535526D7953454C6742492B397677 + 593447645A43596A33576663796938736679363032476B6B46314C4F52736C78 + 4B424A394B516266656377495331557A7A694235443962262378413B734D6B64 + 4A416370452B5A2F556B316F504B5633642B6A774E6F6A665A6C755A4A465148 + 705439327370487A4F325A637A6C6A472F7139316673634F4178536C58302B2B + 2F7742414B493878262378413B65564C54544C52626F4E497355713872616453 + 7339764B6635566B546F66384157797654617335445855637879492B445A7164 + 4834594236486B655950784354617635653162536653613967262378413B4B52 + 584368344A3149654E7752583458576F72375A6B346454444A66436477342B66 + 545A4D56635132504C755A722B53762F4855314C2F6A416E2F45383150626E30 + 52393775765A37363565262378413B3536336E4E7656757856324B766E713338 + 786167427A6657372B4B57557530356A42593149414235657170626C786F656D + 64724C54522F6D52492F486B2B665231552B66484D45382F774157262378413B + 736A31362F677469494E5976566B43414C434B71684C47727157456832363738 + 64386B6450456E6545667838455231456F6A6163767838587066356736626561 + 68354B30754731514F367951262378413B53507964493143726279564A5A7971 + 6A373830505A32574D4E52496E7A2B38505339713470543030424876486C2F43 + 6539357070326E2B596F7269537968744B50495745697A6F675373414C262378 + 413B74563561494F494250584E396B7934694F496E35656675655A7834637438 + 49472F6E356239646C30766C587A50504A36736C735A4A5A704376393547574C + 637A48586A797146356A69472B7A262378413B6747727844612B587639374936 + 4C4D656E4D393437362B2F7279556A3562387751584D513941704B3158535553 + 5238554B414F533867626A475642422B496A4A666D735242333239782B377126 + 2378413B782F4B35515274763778392F54347333386A33486D61627A42594855 + 57742F715479584D6B6670437A566E6D43535276495052704939537042626348 + 3773314F766A69474B58426646742F4F262378413B3562477439766737727332 + 6559356F38664477334C6C773836497662632B2F6B782F38414E542F6C4E4C76 + 2F414649662B5461356D646B2F33412B5033754432312F6A4D7668397A457332 + 62262378413B716B783037536B6C684E356553665637424451762B303766796F + 50484B636D536A51336B327778324C4F30557A3043367574494678714D56314A + 593255395930436844504B67616F56535274262378413B327177706C476F7878 + 7956456A69492B516239506C6C6975555477672F4D714F702B63745A76574B72 + 4D385551365663764A394C74552F646B73576A68446F7879367A4A506D536739 + 503841262378413B4D476F5764794A79567576356B7552366F50306E34682F73 + 534D737961654D68584C33624E6550504B4276592B2F646C625357586D6D795A + 644A59322B7049424A63614A4F334F4F3443486B262378413B6671386A664744 + 7475746636357276567035657665485351366631682B6C325A454E5448393336 + 5A3959486B6636702F51674C37514E4B3171336D76664C736232312F62417466 + 614649535A262378413B467039706F436432415056657634444C63656F6E6949 + 6A6C336965552F774262566B3032504D444C434B6B4F634F762B6233736F2F4A + 502F41486C31622F58682F552B612F74336E44342F6F262378413B6470374F2F + 5450346670656C356F5870486A58357A6638414B5557762F4D46482F77416E5A + 63366A73542B3550396239416550396F503738663142393559486D356447796E + 54644776725054262378413B30753757425A39516E586C473746517353456255 + 35455659312F7A37344F544E4755714A71492B317A4D654B55593242636A3969 + 4475626B36527A6A522F563165595675726B2F4636664C66262378413B67702F + 6D38546C6B592B4A2F553642726C4C672F7264556A5A6D64697A45737A477059 + 376B6E4D6C7832734B70313564383058576B7331764B67764E4A754E727A5435 + 643433553953746673262378413B7434455A69616E53444A7550544D63693565 + 6C316B7357783955447A6965522F62357332306E523953503772544C63363535 + 4A3145632F71306B6B537951456B31432B6F366C5A4932384E6A262378413B38 + 393831576250446E4D2B486E6A316F372F4C6F5863344E50506C41654A707039 + 4C466A356E596A37557838692B5735664C336D375662426E39534A72614F5732 + 6B3271596D6B4948494475262378413B437042796A744456444E676A4C72652F + 767079657A4E496450714A7736634949393176514D3072763359713746554C2B + 69744C2F414F574F442F6B576E394D7338616665666D316542442B6126237841 + 3B506B37394661582F414D7363482F49745036592B4E5076507A587749667A52 + 386D4D2F6D66715A30337935457977527A787A58417435495A4F59556F384D6C + 522B375A47485473637A2B7973262378413B58486C4F39554C2B304F74376179 + 2B486847774E79723744335538307476507570514F5A6671304C7A4E4B387253 + 566D552F4847385156654D673468556B49586A763841546D2B6E326641372623 + 78413B576172793777653779656168326A4F4A756864333137694F2F754F7934 + 2F6D48724C4E435768674B775369654E6153553569526E71547A716637776A66 + 72313637342F79626A33334F347237262378413B50636E2B55386D3277324E39 + 65386E76382F77564A7650476F47626D7474416B6237334D4939546A4D334656 + 444F532F4955394E6163434D6C2B516A584D2B584C6237505071774F766E6649 + 262378413B6566506637664C70544A2F49766D323831587A4C59325531764646 + 4768754A55394A7051415757526A3842636F66746E666A584E6632686F343438 + 5570416E703365586C62732B7A4E624C4A262378413B6D6A456741656F375835 + 2B6464653549767A552F355453372F774253482F6B32755A665A503977506A39 + 3768397466347A4C346663784C4E6D367050703965306534534A4A744E4C4A41 + 7647262378413B4A424D7756523868515A6978775446314C6E354F536330447A + 6A793830723148554A7236344D73673471427869694832555164464758593443 + 49706F6E4D794E6F584C474C73565877547A51262378413B544A5043356A6D69 + 59504849706F5659476F494F526C45455565535979494E6A6D4759322F6E3752 + 3176346456756441456D744A784D743946647951633341346C76535265487844 + 37513735262378413B724A646E7A3454415A5033666477672F6137654861654D + 534753574F386E383453492B776265396D58355A616E6261706536396632396F + 4C4B4F346C67593236747A4162673349316F76326D262378413B33365A712B31 + 4D52787868456E696F4864322F5932595A4A5A4A4163494A477A4F3830377658 + 6C48356F36487132712B61595630363165354D566A455A416772784454545572 + 393264483254262378413B6E686A776E694E58492F63486C653274506B793578 + 77417971412B2B547A793973623278754774377942376564657363696C577034 + 3050624E33444A4759754A734F67795935514E53464655262378413B307A5364 + 533153646F4E507433755A6B55794D694370436767562B39686B637561474D58 + 493047574842504961674C4B75336C7258313146644E61776D572B6453365146 + 614D7967456C6858262378413B596A6249666D7366447838513465396D644A6C + 342B44685046334F75504C5776573937445A54324D30643163375738624C546D + 66386B39446A48565935524D6849554F6179306D574D684578262378413B496B + 65532B31387265593775302B7432326E7A54572F78446E47764C644478595547 + 2B784743657278526C776D5142544452355A78346F784A434473394D31433975 + 2F716470625354585739262378413B5955556C6878363148616E6575577A7978 + 6848696B6144566A78546E4C6869435A4978764B766D4662354C41324D687535 + 454D7363516F537941304C41676B47684756445634754869347653262378413B + 326E5235654C67345478466E333555364C71756C61786652366A625062504A62 + 71794B2B78494430726D6D37587A77795169596D3933666468366565504A4954 + 46656E394C30374E41394B37262378413B465859713746585971775038357638 + 416C4637582F6D4E6A2F7743545575626A73542B2B5039583949644637516633 + 412F726A3769386D5456727845344430797677624E46453339326A5272262378 + 413B31552F73756670333635306877785066387A37336C426C6B4F373544334C + 343962766F796854306877574A5672444552534770576F4B2F46312B4B763275 + 2B4134496E7636395431534D3868262378413B33644F673666442B3371744F73 + 58786A394F73664867305A2F6452314B76494A4733343172794858364F6D4877 + 5933663654376B654E4B71322B5137375A4A2B5763386B2F6E754365536E7126 + 2378413B5369643334674B4B7447784E4655414435444D44745349476E49486B + 374C7365524F7142506E3979642B653947306562576455315855376934696A67 + 6B7472645674305279544A4147715137262378413B4A2F4C343569646E35356A + 48474541446645642F65356E616544476373357A4A4142694E68664D65384D53 + 75664A313862794B505458573974626D41584E7463735567426A4A342F48366A + 41262378413B4B7762616C633255646248684A6E365344524850376E5654304D + 754943487142466738747669723652355469654456704E584631424C70627752 + 766257306179536B7A46683059714E754950262378413B58706B633273494D42 + 4468504865354F327A50426F67524D354F496346624157643752482B44644E67 + 31472F6975727559326C6E5A783377394F4E526341536C615279527331466363 + 747858262378413B4B2F7A737A474A4148464B58447A32323633334D2F77416A + 434D3543556A7778694A637439363249766E757358795A6153616A5A7878584D + 76314B2B744A7275457978694F5A665256766764262378413B61734E796E5548 + 442B646B496B6B44696A49446E74756A386A457A6941547779695A62696A7466 + 366C712B572F4C79576D6C693776376933764E5568457354656B72774957636F + 4135444B2F262378413B55654745366E4B544C68694447423739304453346847 + 484649695578664C626E5866616846355669744937323531796437613273726E + 366E77675553535454674669736649716F4158666B63262378413B6D64575A47 + 4978697A495876794159445269496C4C4B61455A634F32354A386C5453744230 + 44555A64526D696C7666714E6A436B6F51525274634D585949563468754A7058 + 7258426D314753262378413B4169434938556A336D6D5748545973686B515A63 + 4D52664958336437505079706773594831694B792B73656972572B3130697879 + 3869726B3156537770346235702B31355350415A56652F4C262378413B6B3733 + 734F4D5278694E31747A3250566E2B6156333742764F396A6558306D7432746E + 4530317A4A70316836635366615047396C59302B675A7439426B6A41516C4930 + 4F4F582B35446F2B30262378413B7363706E4A4749733845503932574A533232 + 704D6E6C2F5345676831487A426269344D734533476449596E49394E5A545572 + 384971314366687A5A435550336B374D635A726C745A36303667262378413B77 + 6E2B3778674365556357334F68307633632F4A4F4C62534442356A3157416159 + 514A744764486767583675747A4B486A456A5172385842574F77322B6A4D6157 + 613855547863736E586568262378413B765639376C7777566D6D4F446E693544 + 62694E6936376D34456769315452495868657A4D466866704C706253724C4C45 + 6E426A7961536C6179564E41527454706A496B776D6234726C44315626237841 + 3B515077386C69414A34785844554A2B6D37493250587A51756C74612F57764B + 69365447353064727035476C6D66314A567569744869656756566F7167696733 + 3635504B4A634F586A50723465262378413B6E4C683732764477385748777766 + 443475753534756F2F484E4133656A363171486C72513330754E6D6133756238 + 79544B776A45664B5A654A5A7956432F5A4F58517A34345A5A695A3569502623 + 78413B7832614A36664A6B77597A41636A50667533485646586B3176716B2F6D + 53313065525A7452755071674A68594B31796B533075665250513166346A5437 + 58766C63496E474D5A6D4B694F4C6E262378413B2F446630332B4E6D334A495A + 446C6A6A4E7A5044792F697236712B4F2F6D713652356373394E313231573374 + 7273472B303238615778756E55544167464F414B6F76486C38736A6D314D736D + 262378413B4D32592B6D636478792B396C673073636555554A6572484C306E6E + 314663757162666C3770636C6A727434547063326C525332716859703566574C + 73736E784D4734707452674B557A473753262378413B7969654D656F54395851 + 5630637A736E43595A5A656777426A314E396663486F4761563642324B757856 + 324B7578565375724F30753478486451527A786738676B717134424170576A41 + 3737262378413B354B4535524E6730776E6A6A495649412B39432F346630482F + 713232762F4969502F6D6E4C507A47542B644C356C722F4143754C2B62483542 + 332B4839422F367474722F414D69492F77446D262378413B6E4838786B2F6E53 + 2B5A583872692F6D782B51642F682F51662B7262612F38414969502F414A7078 + 2F4D5A503530766D562F4B34763573666B465333306A537261555332396C4244 + 4B4B306B262378413B6A69525746646A7541446B5A5A707946456B6A33736F34 + 4D635459694166633833383936726F53367071326C616F627066576C74626848 + 746B6A622B37673430504E6C70586C6D2B3750785A262378413B4F434534634F + 776B4E3737336D2B3038324C784A776E78626D4A327270487A4C476C31337978 + 64616A5A6A554C65355852394D67454E6E6170776B6552677859744D53306632 + 69616B4C3873262378413B7A6A703830596E684934356D796631633358445559 + 5A546A786958687746416337392F4C374566622B634E496A6D316F6D3831474A + 74556133644C79434F4B4F5A444357354C525A46437252262378413B676F6F65 + 6D55793055794962515042657875742F673351313041636E716D4F5068334141 + 4F312B616D2F6E7946627138754C623678484F326E705932743278557A76496B + 676231706D424735262378413B473231636B4F7A7A5142717550694936565849 + 4D54326B4F4B556F3851504277673962766D667756502F474F6E793637447256 + 79733575704C4F5733766F77464B6571596A47725256665A57262378413B7255 + 72745474584A666B70444763597175494565363733596E58524F555A4A587863 + 4A423939567476792B35534F7565565A37545347765937795336307546596A62 + 78694A497043726C7857262378413B51737A41477444384F48774D776C50684D + 616D6565396A344D667A4743555963516B5A514656745233766E2B7875333833 + 323934626D50567657747A4C6666704B307537514B7A7754303430262378413B + 344F56444C514476586247576A4D614D4B507034534431435936345473547358 + 506A426A3050366B7A6B383936544A6633556A58462F474A7243437A572B6956 + 4675444A432F4A704B656F4B262378413B632F3841577967646E7A45514B6A74 + 496D756D2F546B35423753675A45334D584152346858465936382B76765A5038 + 416C68633274314E7138397663335632484E76366B3937543169775678262378 + 413B325A39676F464E38312F61735445514245527A2B6E6C306470324C4F4D6A + 4D67796C394F387566587A4C4F38303776586A6635796B6A7A5261302F355959 + 2F2B5430756452324A2F636E2B74262378413B2B6750482B3048392B5036672B + 38735A742F4C476F545372434A5955754768467836444F655969593044476749 + 36397134366E7437545962347966547A325467396E4E586B786A49496A686C26 + 2378413B734E2F4B2F75566F504B4771547A7A51517A51504E6238524D6F6471 + 727A46562F5A376A475062756E6C7976354E5137447A32523662486E2B78582F + 414D41363934772F3847662B61636E2F262378413B41437A682F70664A503867 + 366A2B6A3833663442313778682F774344502F4E4F5038733466365879582B51 + 64522F522B62763841414F76557057476E2B75662B616366355A772F30766B76 + 38262378413B67366A2B6A38334479447277334268722F726E2F414A70782F6C + 6E442F532B532F774167366A2B6A383232386965594759737A784D78366B7945 + 6E3957416473595050354B657774522F522B262378413B624A667965686D6731 + 76566F4A68786C69695648587251724A51356A39737A4573634A446B66314F58 + 32444177797A696559483658712B633639513746585971374658597137465859 + 713746262378413B5859713746586866357166387070642F366B502F41436258 + 4F75374A2F7542386676654937612F786D58772B356957624E31547356646972 + 735664697273566469723158386B2F393564572F262378413B31346631506E4F + 647538346648394431487337394D2F682B6C365A6D68656B654E666E4E2F7741 + 7052612F387755662F4143646C7A714F7850376B2F31763042342F32672F7678 + 2F5548336C262378413B6E6D6D365659505957736A52664730456649386D4837 + 494E4E6A307A6D7334426E4C336C3676545350687839772B35586B307A546F6B + 6555784E734B74785A366D672B652B5162554A7A3066262378413B2F664D332F + 4A582B754B75353650384137356D2F354B2F3178563350522F3841664D332F41 + 43562F72697275656A2F37356D2F354B2F31785645323170707477685A493341 + 426F6554534B66262378413B784F4B73632F4C3146547A76356B525252565A67 + 42374355357539662F69324C3864486E2B7A5038617A65382F6539487A535051 + 4F7856324B757856324B757856324B757856324B75785634262378413B582B61 + 6E2F4B6158662B70442F77416D317A72757966376766483733694F3276385A6C + 38507559344C794830625749327945514F7A7976543435655242347361644142 + 515A6E3842736D2B66262378413B324F74347851466376745632314854337672 + 6D34657755517A786C496F456269496E594163316F744E747A536D51474F5169 + 4278626A37575A79524D6954486E30376C76312F542F414E442F262378413B41 + 465036697631336E792B76386A7934317278345570394E63506879342B4C6939 + 5063766952344F48683958657172716D6E72716476644E7038636C7444476953 + 575A2B46585A55346C6956262378413B414F3766466B54696C7745635735504E + 49797834784C68464163752F623846546A31437757653963324B2B6C4F724C62 + 5263676653422B7A7551613032334644373734546A6C5139584C6E3526237841 + 3B6F47534E6B384F783565536D6232324F6E773233315650566A6B3952376A62 + 6B366D76774862703037354C675045546531636D50474F454374373571656F33 + 4676633373303976414C614351262378413B316A74776168425437494E425839 + 666A6878784D5967453265394757516C496B43683350546679542F7742356457 + 2F31346631506D67376435772B50364870665A33365A2F44394C307A4E432623 + 78413B394938612F4F622F414A5369312F35676F2F38416B374C6E5564696633 + 4A2F72666F44782F74422F666A2B6F50764C305378693958523757506D79636F + 492F6A51305966434F687A6D383331262378413B793935657130333933482B71 + 5075612F52582F4C35632F386A50374D72626B6738342B597442386F32455637 + 72476F5863634D7A6D4F5067786170436C7A57696D674369754B734F6D2F5066 + 262378413B38746F556B65585672354669727A4A456D3143796E396A6664434E + 7356542F79562B59666C447A6C6479326D69366C65795451786956672F4E4278 + 4C4F676F57556674524E39337978566D50262378413B364B2F35664C6E2F414A + 47663259716962613339424376717953314E61794E79492B574B735438676638 + 7031356D2F31322F354F6E4E33722F77444673583436505038415A6E2B4E5A76 + 6566262378413B7665693570486F485971374658597137465859713746585971 + 3746585971384C2F4E542F414A5453372F3149662B54613531335A503977506A + 3937784862582B4D792B48334D537A5A757164262378413B6972735664697273 + 56646972735665712F6B6E2F414C7936742F72772F71664F63376435772B5036 + 4871505A33365A2F44394C307A4E43394938612F4F622F6C4B4C582F414A676F + 2F77446B262378413B374C6E55646966334A2F72666F44782F74422F666A2B6F + 50764B2B782F4E6D5333733462655454424930534B68645A754150455572784B + 4E54373872796469435569524F7238763274754874262378413B387767496D46 + 304F2F774459722F38414B34502B31522F303866384158724B2F35432F702F77 + 43782F61322F36492F39722F32582F4855447133356A616271304B7733326869 + 56454E562F30262378413B6D684250582F645750386866302F3841592F74582F + 52482F414C582F414C4C2F4149366C6838782B576943446F4C45487150725233 + 2F354A592F79462F542F325037562F30522F37582F7376262378413B2B4F6F7A + 5376504769365863473473394334544665484D334E547838503772482B517636 + 662B782F617638416F6A2F32762F5A66386454582F6C63482F616F2F3665502B + 765750386866302F262378413B396A2B31663945662B312F374C2F6A726A2B63 + 426F61615451397639492F3639596635432F702F5A2B31482B695038416F6637 + 4C39694A2F4B652B652F77444D6D745873696848755639566C262378413B586F + 4330684E426737587869474B4552302F5576596D51354D3253522F69332B3136 + 6C6E507654757856324B757856324B757856324B757856324B7578564C623379 + 316F4639634E63336D6E262378413B775845374142705A45566D49416F4E7A37 + 5A6644565A59436F7949446A5A4E48696D654B555154376C442F426E6C502F41 + 4B744E722F794B582B6D542F505A763538766D772F6B2F422F4D6A262378413B + 386E66344D38702F39576D312F774352532F30782F505A763538766D76386E34 + 50356B666B372F426E6C502F414B744E722F794B582B6D5035374E2F506C3831 + 2F6B2F422F4D6A386E66344D262378413B38702F39576D312F35464C2F414578 + 2F505A763538766D76386E3450356B666B372F426E6C50384136744E722F7741 + 696C2F706A2B657A667A35664E66355077667A492F4A332B44504B662F262378 + 413B41466162582F6B5576394D667A32622B664C35722F4A2B442B5A48354F2F + 775A35542F36744E722F414D696C2F706A2B657A667A35664E66355077667A49 + 2F4A4736646F2B6C616172727039262378413B72466169556779434A5176496A + 70576E7A79724A6D6E6B2B6F6B74324C5477782F5142472B35475A5533494455 + 504C2B69616A4D73392F5977334D797145575356417843676B67565061704F26 + 2378413B585939546B674B6A49674E47585334736875635154356F582F426E6C + 502F713032763841794B582B6D57666E7333382B587A6176355077667A492F4A + 332B44504B663841316162582F6B5576262378413B394D667A32622B664C3572 + 2F414366672F6D522B54763841426E6C502F713032762F49706636592F6E7333 + 382B587A582B54384838795079642F677A796E2F316162582F414A464C2F5448 + 38262378413B396D2F6E792B612F7966672F6D522B5476384765552F38417130 + 32762F49706636592F6E7333382B587A582B54384838795079642F677A796E2F + 316162582F6B55763841544838396D2F6E79262378413B2B612F7966672F6D52 + 2B5476384765552F7744713032762F41434B582B6D5035374E2F506C38312F6B + 2F422F4D6A386B58702B68614E70727539685A513272794469375249464A4133 + 6F615A262378413B586B3147536631456C74786162486A4E7769492B35485A53 + 33757856324B757856324B757856324B757856324B757856324B757856324B75 + 7856324B757856324B757856324B757856324B75262378413B7856324B757856 + 324B757856324B757856324B757856324B757856324B757856324B757856324B + 757856324B764B50502F6E6A7A5270586D6534737243393947316A574D704836 + 554C304C49262378413B436433526A31506A6E52396E6144446B7769556F3264 + 2B702F5738743270326C6E785A7A4745716A74304864376D4F2F38724F383866 + 384156792F3549572F2F4146547A4F2F6B72542F7A66262378413B7450363358 + 2F79787176352F32522F55372F6C5A336E6A2F414B75582F4A43332F77437165 + 5038414A576E2F414A76326E39612F79787176352F32522F55372F414A576435 + 342F3675582F4A262378413B43332F3670342F7956702F3576326E39612F7978 + 7176352F32522F55372F6C5A336E6A2F414B75582F4A43332F77437165503841 + 4A576E2F414A76326E39612F79787176352F32522F55372F262378413B414A57 + 6435342F3675582F4A43332F3670342F7956702F3576326E39612F7978717635 + 2F32522F55372F6C5A336E6A2F414B75582F4A43332F774371655038414A576E + 2F414A76326E39612F262378413B79787176352F32522F55372F414A57643534 + 2F3675582F4A43332F3670342F7956702F3576326E39612F79787176352F3252 + 2F55372F6C5A336E6A2F414B75582F4A43332F77437165503841262378413B4A + 576E2F414A76326E39612F79787176352F32522F55372F414A576435342F3675 + 582F4A43332F3670342F7956702F3576326E39612F79787176352F32522F5537 + 2F6C5A336E6A2F414B7558262378413B2F4A43332F774371655038414A576E2F + 414A76326E39612F79787176352F32522F55372F414A576435342F3675582F4A + 43332F3670342F7956702F3576326E39612F79787176352F32522F5526237841 + 3B372F6C5A336E6A2F414B75582F4A43332F774371655038414A576E2F414A76 + 326E39612F79787176352F32522F55372F414A576435342F3675582F4A43332F + 3670342F7956702F3576326E39262378413B612F79787176352F32522F55372F + 6C5A336E6A2F414B75582F4A43332F774371655038414A576E2F414A76326E39 + 612F79787176352F32522F55372F414A576435342F3675582F4A43332F362623 + 78413B70342F7956702F3576326E39612F79787176352F32522F55372F6C5A33 + 6E6A2F414B75582F4A43332F774371655038414A576E2F414A76326E39612F79 + 787176352F32522F55372F414A5764262378413B35342F3675582F4A43332F36 + 70342F7956702F3576326E39612F79787176352F32522F55372F6C5A336E6A2F + 414B75582F4A43332F774371655038414A576E2F414A76326E39612F79787176 + 262378413B352F32522F55372F414A576435342F3675582F4A43332F3670342F + 7956702F3576326E39612F79787176352F32522F55372F6C5A336E6A2F414B75 + 582F4A43332F774371655038414A576E2F262378413B414A76326E39612F7978 + 7176352F32522F55372F414A576435342F3675582F4A43332F3670342F795670 + 2F3576326E39612F79787176352F32522F5539357A6A6E755859713746585971 + 3746262378413B5859713746586866357166387070642F366B502F414362584F + 75374A2F7542386676654937612F786D58772B356957624E3154735664697273 + 56646972735664697273566469727356646972262378413B7356646972735664 + 697273566469727356646972735664697236687A7A35394D6469727356646972 + 7356646972735665462F6D702F77417070642F366B5038417962584F75374A2F + 75423866262378413B76654937612F786D58772B356957624E31547356646972 + 735664697273566469727356546A522F4B486D5456774773624752346A306E61 + 6B6366304F2F4548364D78633273785976716C7535262378413B574451357376 + 30524A4832664E6C646A2B5447735341473976344C6348744772544D506E5830 + 782B4F61374A3235416654456E375031753178657A2B512F5649443766314A6B + 667961307947262378413B4C6E63367536676458394E455838574F554474755A + 4F3047382B7A384969355A50732F616C56372B586E6C324A53494E586D6B6B39 + 6F564B2F69795A6C592B304D703577412B4C685A657A73262378413B4D655579 + 542F562F61457358794C45443856347A4474534D4C2F7873325A483530397A69 + 666B78332F5971663448732B492F306D546C334E467039325035773979667959 + 37314362794D6145262378413B773364543256302F69442F444A44573934596E + 52397853323638716178414352474A3148654931502F416D682F444C6F366D42 + 386D6D576D6D456F64486A636F366C48585A6C595549507544262378413B6C34 + 4E744244574658597137465859712B6F63382B66544859713746585971374658 + 59713746586866357166387070642F774370442F7962584F75374A2F75423866 + 76654937612F786D5877262378413B2B356957624E3154735664697273566469 + 727356566B7337703764726C596D4D43624E4B4165492B6E496D597572335477 + 6D72364B534D46645749354145456739365953683672642F6E4573262378413B + 676A67305853336B6E634144317941413367456A727948767947633744735774 + 386B74764C3972302B543267365934622B663667314472666D2B362F65366866 + 693351372F564C5656514435262378413B79554C2F41484E6C683032434F3059 + 33356C6F2F4F366965387056354439664E4B3957383432635463586E65396D58 + 59414D58412B62736631567A4978614D39427768784D327437795A466A262378 + 413B7431357A314F556B514B6C75766167357439376266686D5A485352485064 + 773561755235624A624A726D73534772586B6F2F31574B2F384145615A634D4D + 4230445563307A314B6436467133262378413B6C706973657353366E4249646D + 756F4C674F704A366B70774441664C6C6D4A714D57626E4467506B522B333954 + 6D61624A67355A4F4D655950364B2F577A2B78386E365071466D626E52504D26 + 2378413B46314B44396C33654B345254546F3646466348324A427A54354E646B + 684B736B42396F2F53373348325A69795276466B6B666B667370692B7454655A + 664C6C7749395774456E74574E497279262378413B436F5276704E51472F7741 + 6B675A736342785A783644523769366E55777A6163314D574F384D6138786174 + 6161724C6266566B5A4751454F7A67416E6B52516245394B5A6E594D52674462 + 67262378413B5A386F6D5254494E652F4B54573950745263574D79366B46465A + 6F6B517049504867704C63782B50746D42702B324D637A556877757A31505965 + 584847346E6A372B2F39763432594D797372262378413B465742566C4E475537 + 45455A747758534E595664697236687A7A35394D646972735664697273566469 + 72735665462F6D702F796D6C332F71512F38414A74633637736E2B3448782B39 + 346A74262378413B722F475A6644376D4A5A7333564F7856324B757856324B73 + 6838762B5747757774316541726264556A364D2F75664263784D2B703464687A + 637242702B4C63386B62356731367968745A4E4E262378413B736C567956394E + 797579494F34464F70797242676B547853624D2B61494844466A656D36626461 + 6863434742613933632F5A55654A7A4D795A424157584578347A493047597878 + 6152356473262378413B2B546E6C4D776F576F50556B506742324761386D6559 + 2B546E675178447A597871336D472F7742514A51743656763268513745663552 + 2F617A4E78594977393768356338702B354B38766158262378413B5971374658 + 597169744D315855644D756C7572433465336E5839704431486777364D505935 + 566C77787943704377325963303863754B426F76562F4C48356A615472385036 + 4A312B474F4B34262378413B6D48437243734531653378665A6232503048746E + 4F3672737965453865496B67664D505561507462486E486835674154386A2B70 + 6A486E7638754A744844366C70596162544F737352715868262378413B722F78 + 4A5066743338637A2B7A2B30786C394539702F662B31313361665A4A772B7547 + 3850752F5973386F2F6D6671656B384C54556556397079305653542B2B6A4132 + 2B466A396F442B552F262378413B654D6C724F796F5A50564830792B77736444 + 32785044365A2B714832686C2F6D48796C6F486E4F774772364C4E4774387732 + 6E585A5A4350324A6C3668683430723838316D6D316D54537934262378413B4D + 67395034354F32315768786179486959694F4C372F663576494C2B77764C4337 + 6B744C794A6F4C6D49306B6A6355492F7144324F644E6A79526E486969624265 + 54795935516B597946454B262378413B47545950714850506E3078324B757856 + 324B757856324B75785634582B616E2F41436D6C332F71512F77444A74633637 + 736E2B3448782B39346A74722F475A6644376D4A5A7333564F78563226237841 + 3B4B7578566B586C6E7939395A497662746639485531696A50375A48632F7743 + 5350787A44314F666839493575567038484675655370356A387A4751765A574C + 55694877797A4B667466354B2B262378413B337633776166543136704A7A3669 + 396F386B69302F5437692F756C7434423854627378364B6F366B356C5A4A6949 + 73754E43426B61444D4C6D35302F793570346868416534635656543970322623 + 78413B2F6E66327A58786A4C4E4B7A79632B556F346F304F62444C7938756279 + 6470376879386A642B7748674232476247454245554858796B5A47796F354A44 + 735664697273566469727356646972262378413B306E38762F77417876543461 + 4E72736E4F3163656E6258636D2F43753370796B39553843656E6662706F7530 + 657A4C2F41486D506E3148366E6F65792B31712F6435543665683776492B5833 + 262378413B65376B432F4D6279434E4A633672706945365A4966333051333942 + 6D4F3150386875336830384D74374D3751385430542B76372F414E7254327432 + 5A345238534830483750324D6238736561262378413B64533876583475625275 + 5554554678624D614A496F374877493748746D6471744A444E4770632B68376E + 58365057547754346F2F456437314456394D30583877504C3636687078456570 + 5169262378413B6B624E7379754E7A444C547365782B6B6438352F446C796150 + 4C77792B6B2F6977394C6E77343966693434625448346F7647377131754C5734 + 6B7472694D78547773556C6A6271724B61455A262378413B31454A6951424849 + 76497A67596B6737455070334F4166536E597137465859713746585971374658 + 6866357166387070642F366B502F4A74633637736E2B3448782B39346A74722F + 41426D58262378413B772B356957624E31547356646971765952775358734354 + 7346685A31456A45304847752B2B516D53496D75624B414249766B39476D6A73 + 3562553278634C4379384F4B4E782B4877464D3141262378413B4D6762367531 + 49695258524C50384D65587635662B53682F726C33356E49302F6C3861396E30 + 6251624F5353454B47626F67617275657771616D6D437035547579754749624D + 497662796538262378413B7558754A3235534F666F41374165777A5A51674969 + 673636556A493256484A73585971374658597137465859713746585971374658 + 715035646564726136744738753636367447554B573030262378413B78484634 + 36554D4C6B2B3332666262777A6E75307443597938584838612B393658737274 + 474D6F2B446C355674666433483948795466384177462B57333838662F535766 + 2B61387876355131262378413B6634693558386D364C76482B6D545051744738 + 6D3646504A4E7074306B545372776B5533504A57414E52565759696F37484D66 + 555A382B59564D582F414A726B3662427073427545674C2F70262378413B4D4E + 2F4E2B44513547733952744A6F6E7635574D5534695A57356F71374D33453956 + 36562F706D3137476C6B46786B4477756F37646A694A6A4F4A4845656450574D + 35743674324B75785632262378413B4B757856324B75785634582B616E2F4B61 + 58662B70442F7962584F75374A2F7542386676654937612F77415A6C38507559 + 6C6D7A645537465859713746585971374658597137465859713746262378413B + 585971374658597137465859713746585971374658597137465859712B6F6338 + 2B6654485971374658597137465859713746586866357166387070642F774370 + 442F7962584F75374A2F7542262378413B386676654937612F786D58772B3569 + 57624E3154735664697273566469727356646972735664697273566469727356 + 646972735664697273566469727356646972735664697236687A7A3539262378 + 413B4D64697273566469727356646972735665522B612F4C4635356A2F4D532F + 737257574F47534F326A6D4C5338755046566A576E7768742F6A7A706448716F + 344E4C47556865354833764A3637262378413B52793147726C474A4150434476 + 38464A767959387730504739744365774A6C412F774349484A66793369377066 + 5A2B74682F6F667A667A6F2F622B706A65762B532F4D4F684C366C3962663626 + 2378413B4F5451584D5244783139794E312F3251475A2B6E31324C4E74453739 + 7A72745632666D77627A4733663053504D74773359713746575961422B575772 + 3631704D477032393162787733485069262378413B6B68666B4F447368725253 + 4F7135713952327244464D77494E6832326C3748795A73596E45786F2B2F7742 + 33636A5A76796238794A477A52334E724B343345595A314A3967536C50767971 + 50262378413B6265496E63532F4878627064675A774E6A452F50395443745130 + 36393036386B733732466F4C6D4930654E7576735254596739694D3275504A47 + 63524B4A7346303258464C4849786B4B495A262378413B687033355336336661 + 666133736435624C4864524A4D69735A4F5157525177426F7658664E5A6B3759 + 78776B596B53324E64486234757738733443514D616B4C363966673365666B39 + 356E68262378413B694D6B457474637350393149374B782B584E565838635964 + 745953614949584A32446E694C48444C342F7259566332303974504A62334562 + 5254784D566B6A59555A574855455A7459794568262378413B59354F6D6C4578 + 4E485968503955386A616A70336C79323132576546376135574A3069586C7A41 + 6D586B746171427433337A4378612B4538707867477866324F666D374F6E6A77 + 6A4B534F47262378413B56652F64563872666C39716E6D5054354C3231754949 + 5934355443566C4C3875537172562B4657322B5042712B3059594A634D675474 + 624C52396C354E52417969514264622F324A72503841262378413B6B33356B53 + 4D744663326B7244396A6C49705079716C4D786F3974346964784C3866467970 + 64675A774E6A452F503841557844574E43316252376E36747156733176495256 + 61304B73504657262378413B46566236446D7A7736694755584132366E507073 + 6D4B58444D5555446C7A537A4C512F79723878366E4174785077734948465545 + 39665549506630774E7638415A455A713952327469786D68262378413B366A35 + 4F333033597562494C5070486E7A2B535A586E354D366E444138734F6F777946 + 464C465852304777723148504D6548626343614D533547543266795246695159 + 586F47693347746174262378413B42706C7536527A58485069386C654934497A + 6D74415430584E72714D3478514D7A794470394C707A6D794345655A2F745A6A + 2F79706A582F41506C747450766B2F7743614D316E3874347536262378413B58 + 32667264742F6F667A667A6F2F622B704C504D58356136746F576C53616A6333 + 4E764C46477971556A4C38766A626950744B4233792F546471517A5434414462 + 6A3676736A4A676878794D262378413B6138722F414650633835463764324B75 + 7856324B757856324B75785668476D2F2B546331582F746E4C2B75444E746C2F + 784B5039662F696E5334662B4E436639542F69586E666E48564E547426237841 + 3B764E2B71473375356F536C77775178794F744B553655497A65614C46435743 + 4E6748627565643132616364524F69523675396D6E35622B62626E586B757442 + 316F6937506F6C6F354A427538262378413B6451726F2F6A396F5550584E5632 + 6E6F7868724A6A3233647A325272705A37785A665674396E6377762F426B732F + 6E61667935444B4951736A2B6E4C494331496776714B53423150436D62582623 + 78413B38364270786C497662376554702F79424F704F4547747A387566334D70 + 682F4B3779704A494C526466456C2B5274476A5138712F3859716C76787A5853 + 37577A416358682B6E342F65374F50262378413B5932416E6838573566443772 + 595435723872336E6C7A552F715677346C6A646655676E5555446F5454707651 + 676A635A74644A713435346351323733546133527930382B45373978656A614C + 262378413B4664792F6B2B49374E4A487557696D455351686A49543961663749 + 58664E4A6E4D5272726C7973632F7743713944676A49396E5647376F3876367A + 47504A6D6E2B6649664D566B336F583846262378413B74367147374D36797045 + 5951527A44656F41702B487037356E36334A706A696C76456D74717137645A32 + 6668315563306470675876643158586D722F414A795432636D76577363525533 + 4D55262378413B464C676A714B7353696E3370552F546B4F784979474D6B3869 + 646D7A742B55546D41484D523354337A624E4C462B56656B7645375274364E6B + 4F536B7161656B4F347A45306351645A4F2B2B262378413B5833756272354561 + 47466430507559782B577570655A4A504D7474424250504E5A6B7439626A5A6D + 61495238543854567141613950664E683270697844455351424C703375733749 + 79356A6D262378413B416953593965366D2F7741336C746C3832677730395272 + 614933464F76715659437638417341754473596E77642B38312B506579376445 + 667A47335068462B2F2B796D522B63762F4143564F262378413B6B2F38414747 + 782F354E444D48526634355033792B39324861482B497739305075622F4C4669 + 766B4C56325530496D7543434F6F503165504874582F41426D4875482B364B39 + 6B482F424A2B262378413B2B582B35447A577A387861395A5343533131433469 + 594775306A55507A556D682B6E4E3750545935696A454834504F3439566C6762 + 6A496A347656624F34547A33354575426478722B6B6266262378413B6D6F5A52 + 536B3861386B6466414F44512F546E4F7A6A2B5431493466705033505434352F + 6E744B6549657550336A6C383249666C526F454F7061394A65584342344E4F56 + 5A417033426C636B262378413B52312B58456E356A4E6E327671446A78384935 + 792B377136727354536A4A6C346A7968392F5272387750504F70616871317859 + 57633777616461753051574E69767173686F7A4F5231465273262378413B5044 + 48733751516841536B4C6B6673523270326A504A6B4D596D6F44623373526976 + 3736462B634E7A4C4734324449374B6676427A5A6E4845374542314D636B6762 + 42495A442B57502F4B63262378413B61622F7A332F3668354D77753166384146 + 3566443777374873663841787148782F77427955382F4D6A54764D382F6D6957 + 54543757396C7476536A43766278797448554C76516F4B5A68396D262378413B + 5A63497767534D5162504F6E4D37587735705A7959786B52513541734C314B32 + 3877327361727163563342484C58674C6C5A555669744361633656706D317854 + 7853506F4D54377164506C78262378413B355966574A432B2B33306A6E43766F + 72735664697273566469727356646972434E4E2F386D3571762F624F58396347 + 62624C2F695566362F2F464F6C772F38414768502B702F784C7A487A7A262378 + 413B2F7741706471762F4144454E6D2F304839784433504D396F2F77434D542F + 72466B66354F365A504C72732B6F63534C6132685A4F6539444A495252662B42 + 424F595062575544474939535859262378413B3967595363706E306950744B51 + 2B664E515736383436706357373058314244795539524569784E754F78345A6D + 646E342B48424548332F5064776530387648714A6B6439664C5A472F6C333526 + 2378413B54763841567458743738677736665A53724C4A63476F354E47655152 + 44334E52763444364D713753316B636344486E4B51354E335A57686E6C794358 + 4B4554642F6F56667A533877326D7261262378413B3548445A754A6265785178 + 657375345A324E58346E7542514449396B36615750486375636D58624F726A6C + 7931486352325A6C355A3153343072387149745174315235725A4A6E525A4153 + 70262378413B50316C787541565066787A563672454D6D734D54794E66376B4F + 34306D633474414A7835692F384164466A6C702B632B7569345436335A577232 + 39523669784352487033346C6E6366686D64262378413B5073544858704D722B + 48366E5877396F4D742B714D612B503631623833764C6D6E3262323272576943 + 4757366B5A4C6C46324474546B487032505775523747314D7058435739636D58 + 62756B262378413B68416A4A486269352F725A564C7238476865514E49763572 + 623632677462535030616864326947395347384D317730357A616D6351654831 + 532B39326B74554D476B68496A69394D64766769262378413B6872397871506B + 393956387378526D36346B693264616C58582B3853696C666A48566648627879 + 763875495A2B444D64752F37766732666D6A6B302F6959414F4C752B2F34397A + 776D397662262378413B752B75356275376B6161356D626C4C4933556E4F7678 + 776A43496A45554138546B79536E49796B624A65702B6376384179564F6B2F77 + 444747782F354E444F6530582B4F5439387676656D37262378413B512F784748 + 7568397A7679792F77435541316A2F41497A58502F554E486A32702F6A4D5063 + 5038416446657950385579652B582B354479624F6B655765763841355A51766F + 336B792B316137262378413B4870787973397767616F7248456C4166396B774E + 4D356E745358693534776A37766958724F78342B4470705A4A64642F6745742F + 4A4F366945327132706F4A5857475642334B6F585676754C262378413B6A4C2B + 3359476F6E7075342F73374D584F5058592F4B2F31734F76466251764F4D7076 + 495057466E646D526F57324569422B513667374F76746D7A6766477744684E63 + 55666B366649504231262378413B42346866444C6C33372F70656F6554504D4F + 682B5A7072714E4E4668746671796F784A574E2B584D6B646B58777A6E396470 + 736D4141385A4E2B2F396230765A2B7178616B6B6548474E6534262378413B2F + 6F5952354E56562F4E4A4655414B4C6D3841413241416A6C7A6261302F344838 + 492F654854646E43746150664C376979627A762B592B75614672386D6E326B46 + 744A4369493461564A4331262378413B5746547573696A384D774E42325A6A7A + 59784B526C66772F55374C744874664C67796D4552477475642F72594A357038 + 363672356B5333532B69676A4673574D666F4B3631353072586B372F26237841 + 3B414D75626A53614747432B456E667664487265304A36697549416350642F61 + 2B676334743735324B757856324B757856324B757856357A5072756C614C2B61 + 57703357707A2F563448736B69262378413B562B4C76567A36544155514D6569 + 6E4E3548547A79364F49674C50462B7435365770783464644F557A51344B2F77 + 427A334B656F616C2B546433647933397857347570573579454C65446B782623 + 78413B37385478544A593857756A45524777483956686C79396E536B5A486552 + 2F7270647258356E324E767070307A79745A6D7969494B69344B72487842366D + 4E467238522F6D4A726C2B44737155262378413B703865593852376E48314862 + 4D5977344D456545642F367631734E38744C6F623631422B6E5A475454527961 + 5A6C356B6B6853564234426D6F57324E4D326D714F51597A346631756F306778 + 262378413B48495046506F36765662767A6A2B57397A7067307A39494E425967 + 6366527434726D4563663566676A4733746E4F513057716A506A34626C356D4A + 2F5339526B312B6A6C44772B4B6F397745262378413B682B6867336D324C3875 + 5630745435646C64372F414E566551595430394F68356633716865744D322B6A + 4F71342F336F394E655836485361364F6B4550334A39562B664C34736A387165 + 612F262378413B4A55666B6D32305457727168496C5735742F546E364E4D376A + 3434313843447363777458704E516451636D4D6431486275383359364C573659 + 6159597370373746533779656A555770666B31262378413B707371336470415A + 35347A7952516C7A4A754F6E777A6B4A58453474644D634D6A512F7A66304947 + 62733747654B49732F7743642F76746D4A65642F4F6B2F6D57386A4B786D4378 + 74716933262378413B684A71784C55354F354863303664733257673049775237 + 35486D367274487441366D51327149354250764D766D76514C333876394F306D + 327576553143434F3157574830354251785268582B262378413B4A6C43374877 + 4F59656C306D534F706C4D6A306E693775706333576133465053517878507248 + 44745236424A2F774176764F482B4839554B584C483947586446756469654248 + 325A41425537262378413B643664766F7A4B375230586A51322B736376314F4A + 3258722F4179622F524C6E2B74513839763561754E584E396F4E304A59727172 + 3345416A6B6A394F5475527A5642522B75336575533750262378413B47555134 + 63676F6A6C795964704843636E46694E69584D5552522B4936702F356C383136 + 42652F6C2F70326B323131366D6F5152327179772B6E494B474B4D4B2F774154 + 4B46325067637739262378413B4C704D6B64544B5A4870504633645335327331 + 754B656B686A6966574F48616A3043722B58506D76797870666C7537302F5637 + 723058754C69526A46366372566A654A452B31477255727850262378413B6575 + 523754306D624A6C456F4336486C7A7339375A325472634750444B4751315A50 + 51387148636950722F354C3254436143324E793637684F467A494E7638414A6E + 49544965487235374531262378413B2F7066304D7A6C374E687542786636622F + 66624A4435302F4D573431324161665A516D7A30735535526B6A6E4A784E5635 + 553256525437497A4D30505A6F776E696B654B66334F4432683271262378413B + 633434496A6868392F77434F356A7567363565364A716B4F6F575A487152624D + 682B79364837534E5473637A6452676A6C67597964667074524C444D546A7A44 + 306534387A2F6C7435706952262378413B39616A4E6E657176454F77634D5059 + 53786768674F334C37733063644C71744F66335A346F2F6A6F663050517A316D + 6A3149764B4F475834366A394B4A305857507979387365764C70392B7A262378 + 413B7663425134704A4B5346725143696744726C656644713952516C486C3767 + 32616255614C545759534A4A39352F5177627978726D6D326E6E784E58757044 + 44596D61356B4D68566D4957564A262378413B417456514D6572444E76717345 + 3561626741755644374B644C6F7454434771475352714E792B30466D32726176 + 2B554772586A58756F532B7663734172536362314E6C464273675566686D7026 + 2378413B773464646A6A777846442F4E647A6E7A396E355A63557A6376383949 + 764D482F414371583944585836492F343658442F4145622F4148732B31556637 + 382B447034356D616638373467342F6F262378413B362F542B687774582B5138 + 4D2B48396654362F303750596335683635324B757856324B757856324B757856 + 34582B616E2F4B6158662B70442F77416D317A72757966376766483733694F32 + 76262378413B385A6C385075596C6D7A64553746585971374658597137465859 + 7137465859713746585971374658597137465859713746585971374658597137 + 465859712B6F63382B665448597137465859262378413B713746585971374658 + 686635716638414B6158662B70442F414D6D317A72757966376766483733694F + 3276385A6C385075596C6D7A6455374658597137465859713746585971374658 + 597137262378413B465859713746585971374658597137465859713746585971 + 37465859712B6F63382B66544859713746585971374658597137465868663571 + 66387070642F366B502F4A74633637736E2B3448262378413B782B39346A7472 + 2F41426D58772B356957624E3154735664697273566469727356646972735664 + 6972735664697273566469727356646972735664697273566469727356646972 + 36687A7A35262378413B394D64697273566469727356646972735665462F6D70 + 2F796D6C332F414B6B502F4A74633637736E2B3448782B39346A74722F475A66 + 44376D4A5A7333564F78564658476B36726232736433262378413B635763384E + 724C54307269534A316A626B4F53385849414E52754D716A6D68493849494A48 + 5332795743635969526952453961325562613175627164594C614A3535337277 + 69695575375546262378413B5452567154734D6E4B59694C4A6F4D59516C4931 + 4557573771307572535A6F4C7146376564667452537155635633335667446A43 + 596B4C42734C4F456F6D7043697468686D6E6C574B474E70262378413B5A584E + 456A51466D4A39674E385A5341466C45596B6D687A575A4A437039577550712F + 316E306E2B72682F544D3345384F5A484C6A7936637162307950454C71393038 + 427136326450623345262378413B44424A346E695A6C563156314B6B71777172 + 4148735275446A4751504932736F6B6378537259365871642B58466A6154585A + 6A703667676A65546A587058694453744D6A6B79776839524139262378413B35 + 5A34384D352F5445793977744473724B78566751774E43447351526B32745646 + 6C65455645456848706D656F5276376F47686B36665A727458706B654F506635 + 6648755A65484C75504B2F262378413B68337163734D7354425A55614E697175 + 46594654786451796E6673796B456532534567655344456A6D7257576D366A66 + 4F795756724E644F67354F734D62534544784955476D516E6C6A443626237841 + 3B694237325750464F6530515A6534576F4D724B78566751774E43447351526B + 32434A74394B314F3574354C6D3373353572614B6F6C6E6A6A64305767716554 + 414544624953797769614A414A262378413B3832794F4763675A434A4948576B + 4C6C6A5772477976417059775342566A457A4D5561676A59674B35322B795351 + 4163687878372F4A6C34637534392F774146484A7358597137465831446E2623 + 78413B6E7A3659374658597137465859713746585971384C2F4E542F6C4E4C76 + 2F55682F774354613531335A5038416344342F65385232312F6A4D7668397A45 + 733262716E59716E486D5055374739262378413B6B7431746F59367857317247 + 3932767169526D6A74305230594F3343697343506851644F707A4630324B5551 + 624A357932322F6E48342F613557717A526E564162526A76766530514F2B7673 + 262378413B55764C563961324F7352584E315430556A6E44426778424C774F69 + 7165487866457A41625A4C56597A4F424135376665474F6C7952686B75584B6A + 3978623877333174655855456C72526256262378413B4C654F4F473341623979 + 42557445576570616A456E6C5531422B674F6D786D4949504F2B666635727163 + 676E4947504B755864354C764C756F57576D7A5433732F714E4F6B6670327363 + 4C65262378413B6D2F4B5434576353464A5648464B39523377616E484B594552 + 7936332F614536584C484754493364625673642F4F6A30517573505A53616C50 + 4C593757737A6572484876384871414D593977262378413B4B2B6D5478723370 + 6C6D455345414A63782B4C2B504E727A6D4A6D54483654396E6C384F53633646 + 71756A523647326D616C49336F543354537A6F6973574370477249796B436C53 + 36635059262378413B4D637864526979484A7877356950366677666735576E7A + 59786A344A6E5979732F4C6239587851506D6A5649395531434B375277374E62 + 514C4E52536F456978674F6F424132446262625A64262378413B70635278784D + 664D2F653036764D4D6B784C2B69506E53493875586D6D523662714E72657662 + 4270337432695338463136523950314F57396F4F5949354472746C6570684D7A + 69593374664C262378413B6876702F4F3262644C4F41684B4D75486576713471 + 32762B62756B4C7146646C4442774351484661476E63564150336A4D774F4357 + 55364672326D322B6D517758557A527A757A3666505243262378413B77585435 + 795A4A473247355752696550584E66714E504D7A4A41322B6F66316874397A73 + 6450714978674154522B6B2F31447566745348574C784C7A564C6D356A714958 + 636942543145532F262378413B4447763049414D7A4D4D4F474142352F703675 + 466D6D4A544A484C7037756E324937546269796C305A74506C76527038715851 + 7566565A5A5757526548454439307274795137725555334F34262378413B796E + 4C47516E784350454F47756E366539767853696366415A634A347236372F4143 + 7663645065684E66766F6237576279376872365530685A4759555A6830354D50 + 467570793354347A4447262378413B496E6F4772555A4250495A446B536E486C + 2F584E4D73744A6A743569713371334D3873467779797439585A6F45574F5469 + 6E777343796C534344343038635855594A796E592B6D6874747675262378413B + 62446C616255516841412F56784567373762436A2B4C59786D77646579545764 + 5730363930657A74495A76536C744C6148315068626A4D3672784B4E384E6555 + 663750374E43656836344F44262378413B444B457A496A596B2F442B3372312F + 526E5A38304A776A45476A4544342F744854707A2B4D627A4F6346324B757856 + 39513535382B6D4F7856324B757856324B757856324B76432F7A552F35262378 + 413B5453372F414E53482F6B3275646432542F6344342F65385232312F6A4D76 + 68397A45733262716E5971374658597137465859713746585971374658597137 + 4658597137465859713746585971262378413B37465859713746585971374658 + 31446E6E7A3659374658597137465859713746585971384C2F4E542F6C4E4C76 + 2F55682F774354613531335A5038416344342F65385232312F6A4D7668397A26 + 2378413B45733262716E59713746585971374658597137465859713746585971 + 3746585971374658597137465859713746585971374658597137465831446E6E + 7A365937465859713746585971374658262378413B5971384C2F4E542F414A54 + 53372F3149662B54613531335A503977506A3937784862582B4D792B48334D53 + 7A5A757164697273566469727356646972735664697273566469727356646972 + 73262378413B56646972735664697273566469727356646972735666554F6566 + 50706A735664697273566469727356646972777638414E542F6C4E4C762F4146 + 49662B54613531335A503977506A39377848262378413B62582B4D792B48334D + 537A5A7571646972735664697273566469727356646972735664697273566469 + 7273566469727356646972735664697273566469727356662F2F5A3C2F786D70 + 47496D673A696D6167653E0A2020202020202020202020202020203C2F726466 + 3A6C693E0A2020202020202020202020203C2F7264663A416C743E0A20202020 + 20202020203C2F786D703A5468756D626E61696C733E0A202020202020202020 + 3C786D704D4D3A52656E646974696F6E436C6173733E64656661756C743C2F78 + 6D704D4D3A52656E646974696F6E436C6173733E0A2020202020202020203C78 + 6D704D4D3A4F726967696E616C446F63756D656E7449443E757569643A363545 + 36333930363836434631314442413645324438383743454143423430373C2F78 + 6D704D4D3A4F726967696E616C446F63756D656E7449443E0A20202020202020 + 20203C786D704D4D3A446F63756D656E7449443E786D702E6469643A33643135 + 616364302D323663352D656434322D383266332D333231313536396639333039 + 3C2F786D704D4D3A446F63756D656E7449443E0A2020202020202020203C786D + 704D4D3A496E7374616E636549443E786D702E6969643A63353530373333662D + 353739322D316634642D383235632D3163613831306161666230623C2F786D70 + 4D4D3A496E7374616E636549443E0A2020202020202020203C786D704D4D3A44 + 65726976656446726F6D207264663A7061727365547970653D225265736F7572 + 6365223E0A2020202020202020202020203C73745265663A696E7374616E6365 + 49443E757569643A61653761633562352D386430642D343666642D393031632D + 3065306336623439653837353C2F73745265663A696E7374616E636549443E0A + 2020202020202020202020203C73745265663A646F63756D656E7449443E786D + 702E6469643A36373231653862342D356164352D623334612D383162612D6537 + 313939326531656463363C2F73745265663A646F63756D656E7449443E0A2020 + 202020202020202020203C73745265663A6F726967696E616C446F63756D656E + 7449443E757569643A3635453633393036383643463131444241364532443838 + 3743454143423430373C2F73745265663A6F726967696E616C446F63756D656E + 7449443E0A2020202020202020202020203C73745265663A72656E646974696F + 6E436C6173733E64656661756C743C2F73745265663A72656E646974696F6E43 + 6C6173733E0A2020202020202020203C2F786D704D4D3A446572697665644672 + 6F6D3E0A2020202020202020203C786D704D4D3A486973746F72793E0A202020 + 2020202020202020203C7264663A5365713E0A20202020202020202020202020 + 20203C7264663A6C69207264663A7061727365547970653D225265736F757263 + 65223E0A2020202020202020202020202020202020203C73744576743A616374 + 696F6E3E73617665643C2F73744576743A616374696F6E3E0A20202020202020 + 20202020202020202020203C73744576743A696E7374616E636549443E786D70 + 2E6969643A36373231653862342D356164352D623334612D383162612D653731 + 3939326531656463363C2F73744576743A696E7374616E636549443E0A202020 + 2020202020202020202020202020203C73744576743A7768656E3E323032332D + 31312D32315430383A32363A34332D30333A30303C2F73744576743A7768656E + 3E0A2020202020202020202020202020202020203C73744576743A736F667477 + 6172654167656E743E41646F626520496C6C7573747261746F722032372E3320 + 2857696E646F7773293C2F73744576743A736F6674776172654167656E743E0A + 2020202020202020202020202020202020203C73744576743A6368616E676564 + 3E2F3C2F73744576743A6368616E6765643E0A20202020202020202020202020 + 20203C2F7264663A6C693E0A2020202020202020202020202020203C7264663A + 6C69207264663A7061727365547970653D225265736F75726365223E0A202020 + 2020202020202020202020202020203C73744576743A616374696F6E3E736176 + 65643C2F73744576743A616374696F6E3E0A2020202020202020202020202020 + 202020203C73744576743A696E7374616E636549443E786D702E6969643A6335 + 3530373333662D353739322D316634642D383235632D31636138313061616662 + 30623C2F73744576743A696E7374616E636549443E0A20202020202020202020 + 20202020202020203C73744576743A7768656E3E323032332D31312D32315431 + 313A30383A35372D30333A30303C2F73744576743A7768656E3E0A2020202020 + 202020202020202020202020203C73744576743A736F6674776172654167656E + 743E41646F626520496C6C7573747261746F722032372E33202857696E646F77 + 73293C2F73744576743A736F6674776172654167656E743E0A20202020202020 + 20202020202020202020203C73744576743A6368616E6765643E2F3C2F737445 + 76743A6368616E6765643E0A2020202020202020202020202020203C2F726466 + 3A6C693E0A2020202020202020202020203C2F7264663A5365713E0A20202020 + 20202020203C2F786D704D4D3A486973746F72793E0A2020202020202020203C + 696C6C7573747261746F723A5374617274757050726F66696C653E5765623C2F + 696C6C7573747261746F723A5374617274757050726F66696C653E0A20202020 + 20202020203C696C6C7573747261746F723A43726561746F72537562546F6F6C + 3E41646F626520496C6C7573747261746F723C2F696C6C7573747261746F723A + 43726561746F72537562546F6F6C3E0A2020202020202020203C7064663A5072 + 6F64756365723E41646F626520504446206C6962726172792031372E30303C2F + 7064663A50726F64756365723E0A2020202020202020203C706466783A437265 + 61746F7256657273696F6E3E32312E302E303C2F706466783A43726561746F72 + 56657273696F6E3E0A2020202020203C2F7264663A4465736372697074696F6E + 3E0A2020203C2F7264663A5244463E0A3C2F783A786D706D6574613E0A202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 200A202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020200A20202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20202020202020202020200A2020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020202020202020202020202020200A202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020200A20202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20202020202020202020202020202020202020202020202020200A2020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020202020202020202020202020202020202020202020202020202020200A + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020200A202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020200A20202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20202020202020202020202020200A2020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020202020202020202020202020202020200A202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020200A20202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20202020202020202020202020202020202020202020202020202020200A2020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20200A2020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020202020200A202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020200A20202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20202020202020202020202020202020200A2020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020202020202020202020202020202020202020200A202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020200A20202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 0A2020202020202020202020202020202020202020202020202020200A3C3F78 + 7061636B657420656E643D2277223F3EFFE20C584943435F50524F46494C4500 + 010100000C484C696E6F021000006D6E74725247422058595A2007CE00020009 + 000600310000616373704D534654000000004945432073524742000000000000 + 0000000000000000F6D6000100000000D32D4850202000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000001163707274000001500000003364657363000001840000006C7774 + 7074000001F000000014626B707400000204000000147258595A000002180000 + 00146758595A0000022C000000146258595A0000024000000014646D6E640000 + 025400000070646D6464000002C400000088767565640000034C000000867669 + 6577000003D4000000246C756D69000003F8000000146D6561730000040C0000 + 002474656368000004300000000C725452430000043C0000080C675452430000 + 043C0000080C625452430000043C0000080C7465787400000000436F70797269 + 676874202863292031393938204865776C6574742D5061636B61726420436F6D + 70616E790000646573630000000000000012735247422049454336313936362D + 322E31000000000000000000000012735247422049454336313936362D322E31 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000058595A20000000000000F3510001 + 0000000116CC58595A200000000000000000000000000000000058595A200000 + 000000006FA2000038F50000039058595A2000000000000062990000B7850000 + 18DA58595A2000000000000024A000000F840000B6CF64657363000000000000 + 001649454320687474703A2F2F7777772E6965632E6368000000000000000000 + 00001649454320687474703A2F2F7777772E6965632E63680000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000064657363000000000000002E4945432036313936362D322E3120 + 44656661756C742052474220636F6C6F7572207370616365202D207352474200 + 000000000000000000002E4945432036313936362D322E312044656661756C74 + 2052474220636F6C6F7572207370616365202D20735247420000000000000000 + 000000000000000000000000000064657363000000000000002C526566657265 + 6E63652056696577696E6720436F6E646974696F6E20696E2049454336313936 + 362D322E3100000000000000000000002C5265666572656E6365205669657769 + 6E6720436F6E646974696F6E20696E2049454336313936362D322E3100000000 + 0000000000000000000000000000000000000000000076696577000000000013 + A4FE00145F2E0010CF140003EDCC0004130B00035C9E0000000158595A200000 + 0000004C09560050000000571FE76D6561730000000000000001000000000000 + 000000000000000000000000028F000000027369672000000000435254206375 + 7276000000000000040000000005000A000F00140019001E00230028002D0032 + 0037003B00400045004A004F00540059005E00630068006D00720077007C0081 + 0086008B00900095009A009F00A400A900AE00B200B700BC00C100C600CB00D0 + 00D500DB00E000E500EB00F000F600FB01010107010D01130119011F0125012B + 01320138013E0145014C0152015901600167016E0175017C0183018B0192019A + 01A101A901B101B901C101C901D101D901E101E901F201FA0203020C0214021D + 0226022F02380241024B0254025D02670271027A0284028E029802A202AC02B6 + 02C102CB02D502E002EB02F50300030B03160321032D03380343034F035A0366 + 0372037E038A039603A203AE03BA03C703D303E003EC03F9040604130420042D + 043B0448045504630471047E048C049A04A804B604C404D304E104F004FE050D + 051C052B053A05490558056705770586059605A605B505C505D505E505F60606 + 06160627063706480659066A067B068C069D06AF06C006D106E306F507070719 + 072B073D074F076107740786079907AC07BF07D207E507F8080B081F08320846 + 085A086E0882089608AA08BE08D208E708FB09100925093A094F09640979098F + 09A409BA09CF09E509FB0A110A270A3D0A540A6A0A810A980AAE0AC50ADC0AF3 + 0B0B0B220B390B510B690B800B980BB00BC80BE10BF90C120C2A0C430C5C0C75 + 0C8E0CA70CC00CD90CF30D0D0D260D400D5A0D740D8E0DA90DC30DDE0DF80E13 + 0E2E0E490E640E7F0E9B0EB60ED20EEE0F090F250F410F5E0F7A0F960FB30FCF + 0FEC1009102610431061107E109B10B910D710F511131131114F116D118C11AA + 11C911E81207122612451264128412A312C312E31303132313431363138313A4 + 13C513E5140614271449146A148B14AD14CE14F01512153415561578159B15BD + 15E0160316261649166C168F16B216D616FA171D17411765178917AE17D217F7 + 181B18401865188A18AF18D518FA19201945196B199119B719DD1A041A2A1A51 + 1A771A9E1AC51AEC1B141B3B1B631B8A1BB21BDA1C021C2A1C521C7B1CA31CCC + 1CF51D1E1D471D701D991DC31DEC1E161E401E6A1E941EBE1EE91F131F3E1F69 + 1F941FBF1FEA20152041206C209820C420F0211C2148217521A121CE21FB2227 + 2255228222AF22DD230A23382366239423C223F0241F244D247C24AB24DA2509 + 25382568259725C725F726272657268726B726E827182749277A27AB27DC280D + 283F287128A228D429062938296B299D29D02A022A352A682A9B2ACF2B022B36 + 2B692B9D2BD12C052C392C6E2CA22CD72D0C2D412D762DAB2DE12E162E4C2E82 + 2EB72EEE2F242F5A2F912FC72FFE3035306C30A430DB3112314A318231BA31F2 + 322A3263329B32D4330D3346337F33B833F1342B3465349E34D83513354D3587 + 35C235FD3637367236AE36E937243760379C37D738143850388C38C839053942 + 397F39BC39F93A363A743AB23AEF3B2D3B6B3BAA3BE83C273C653CA43CE33D22 + 3D613DA13DE03E203E603EA03EE03F213F613FA23FE24023406440A640E74129 + 416A41AC41EE4230427242B542F7433A437D43C044034447448A44CE45124555 + 459A45DE4622466746AB46F04735477B47C04805484B489148D7491D496349A9 + 49F04A374A7D4AC44B0C4B534B9A4BE24C2A4C724CBA4D024D4A4D934DDC4E25 + 4E6E4EB74F004F494F934FDD5027507150BB51065150519B51E65231527C52C7 + 5313535F53AA53F65442548F54DB5528557555C2560F565C56A956F757445792 + 57E0582F587D58CB591A596959B85A075A565AA65AF55B455B955BE55C355C86 + 5CD65D275D785DC95E1A5E6C5EBD5F0F5F615FB36005605760AA60FC614F61A2 + 61F56249629C62F06343639763EB6440649464E9653D659265E7663D669266E8 + 673D679367E9683F689668EC6943699A69F16A486A9F6AF76B4F6BA76BFF6C57 + 6CAF6D086D606DB96E126E6B6EC46F1E6F786FD1702B708670E0713A719571F0 + 724B72A67301735D73B87414747074CC7528758575E1763E769B76F8775677B3 + 7811786E78CC792A798979E77A467AA57B047B637BC27C217C817CE17D417DA1 + 7E017E627EC27F237F847FE5804780A8810A816B81CD8230829282F4835783BA + 841D848084E3854785AB860E867286D7873B879F8804886988CE8933899989FE + 8A648ACA8B308B968BFC8C638CCA8D318D988DFF8E668ECE8F368F9E9006906E + 90D6913F91A89211927A92E3934D93B69420948A94F4955F95C99634969F970A + 977597E0984C98B89924999099FC9A689AD59B429BAF9C1C9C899CF79D649DD2 + 9E409EAE9F1D9F8B9FFAA069A0D8A147A1B6A226A296A306A376A3E6A456A4C7 + A538A5A9A61AA68BA6FDA76EA7E0A852A8C4A937A9A9AA1CAA8FAB02AB75ABE9 + AC5CACD0AD44ADB8AE2DAEA1AF16AF8BB000B075B0EAB160B1D6B24BB2C2B338 + B3AEB425B49CB513B58AB601B679B6F0B768B7E0B859B8D1B94AB9C2BA3BBAB5 + BB2EBBA7BC21BC9BBD15BD8FBE0ABE84BEFFBF7ABFF5C070C0ECC167C1E3C25F + C2DBC358C3D4C451C4CEC54BC5C8C646C6C3C741C7BFC83DC8BCC93AC9B9CA38 + CAB7CB36CBB6CC35CCB5CD35CDB5CE36CEB6CF37CFB8D039D0BAD13CD1BED23F + D2C1D344D3C6D449D4CBD54ED5D1D655D6D8D75CD7E0D864D8E8D96CD9F1DA76 + DAFBDB80DC05DC8ADD10DD96DE1CDEA2DF29DFAFE036E0BDE144E1CCE253E2DB + E363E3EBE473E4FCE584E60DE696E71FE7A9E832E8BCE946E9D0EA5BEAE5EB70 + EBFBEC86ED11ED9CEE28EEB4EF40EFCCF058F0E5F172F1FFF28CF319F3A7F434 + F4C2F550F5DEF66DF6FBF78AF819F8A8F938F9C7FA57FAE7FB77FC07FC98FD29 + FDBAFE4BFEDCFF6DFFFFFFEE000E41646F62650064C000000001FFDB0084000A + 07070708070A08080A0F0A080A0F120D0A0A0D1214101012101014140F111111 + 110F141417181A1817141F1F21211F1F2D2C2C2C2D3232323232323232323201 + 0B0A0A0B0C0B0E0C0C0E120E0E0E12140E0E0E0E141911111211111920171414 + 141417201C1E1A1A1A1E1C2323202023232B2B292B2B32323232323232323232 + FFC00011080100010003012200021101031101FFC400B9000100030101010100 + 0000000000000000000405060703020101010003010101010000000000000000 + 0000020304010506071000010303020204060C0D030305000000010002031104 + 0512062131415161137181B122327291A1C1425292B25314543516D162A2D223 + 334373937415360783B3D3822417F1C263A34411000202010203050407060505 + 0000000001020003111204213105415171221361819132A1B1D142722314F0C1 + 5262A2B2F182341535E192334324FFDA000C03010002110311003F00F94445F5 + D3F3F84444884444884444884444884444884444884444884444884444884444 + 8844448844448844448844448844448844448844448844448844448844448844 + 44884456761B77317E03A0B6708CFED24F31B4EB05DCFC4A2EE8832EC1477938 + 93AEBB2C6D35A973DCA332B116CAD3FC7F2100DE5D869E9644DAFE53A9E456B0 + EC8C14606B6C937AEF23FDBD2B23F52DB2F262DF847DB89E857D1B7AFC4AAA7E + 36FB3339C22EA236CEDE89A49B38C34732F2E3EDB9CA2CD8FDACC040B3648797 + 980F96A156BD4EB63E5ADCFB87DB2C6E8B720CBDD52FBCFD939C22DA5CE2B092 + 57BAB1117E3092427D8D545E0DC2631BFB1A9EB2E71F755E37884674B0F61C7D + B33374FB41C07461DE33FBC4C922D87F4AC77D5DA87138E3FF00E76F8AA3DD5D + FD5A7F099CFF006FB3F897E998F45A993018E7FA2D747EAB89F95550E6DB4789 + 82707A9AF14F6C7E0525DCD47B48F1120DB2BD7900DF84FDB28914BB9C5DF5B0 + 26488960F7EDF387B4A22B830619041F09999594E18107DB0888BB3908889108 + 8891088891088891088891088891088BD20825B890450B4BDE7A07BA84E38980 + 09381C499E68B4B69B7ED5917FDCFE96570E342406F828B3D3C6229E48C1D418 + E7341EBA1A555696AB9217B25B6D0F52AB3E06AECED1E3276DE7DAC79AB47DDD + 0401FC4BB90750E827C0EA2E857DB8F0D63C26B96B9FD11C7E7BBF26B4F1AE56 + AC71D889AF087BBF476FF0FA4FAAB36EB6955AC2CB1CA851A7026DD86FEEA11A + 9A6B56676D5A8F6764D44DBE9F349DD636C5D238F274A69ECB59F9CBD62C9E72 + 4A3EE676455FD942C14F0173F51F614582DED6CA122302360E2E79E9ED738AAC + BDDC2C6D5968DD67E71DCBC41675DBD4C74D550C7F13798FD3CA6B7DDDC8355F + 79CF6227947B80E265E5C5D3DC0C9712F9A3DF38D00F7155DC67EC62A861333B + F1470F64ACDCF737170ED53485E7A2BC8780742F25A9368A0798E7D8380986DE + A0EC4E818FE66E265C4BB92E9DFAA898C1DB571F71457E6B24FF00DB50753434 + 7B8A0A2BC5358E4A3EB995B71737376F71C7D52DAC6E1F74E0DB8CABAD1C4D3C + F6B8B7D9670F6568E1DB39392312DBE61B2B0FA2E0DD4D3E3D4E586526CB237B + 6127796933A1774E93C0FACDE47C6AABA8B1B8D4E17F95914AFD599A36FBAA57 + 85F5B38FE24B195BE19C19B27E077242D2E8EE2DEE48F78E0584F82800F6D54B + F3535ACC6DF2168F8256F303CA01A70F1AB3C46FA8A42D8728C11B8F01711825 + BFF53798F12D15EE3F1B98B50D99AD9A270AC53308A8AF4B1E179C6DB297D3BA + A8693F79387C31C0CF6168A7715EBD95E430E6961D5F1CF11E332F6D91B3B9E1 + 14A0BBE01E0EF60ACEE6C42320FEEA9C86BA72D5D2A5E776C5E625C656D66B22 + 784C0716D7A1E3A3C2A917A3B74ACFE656FA948C7F8CF1F7765C3F26EAF43A9C + FF0084B29B6F65E1B265EBEDDDDC3C6AAB68E2D69E20B9A3880AB574EC0EE2B1 + C9C31C41C23BC6B407C0EE049038967C20A2E7367DA5F074F6405B5DF320708D + E7F180E47B42CC9D40AD86BDCA6839E0C397BFED9B2DE90AF48BB6767AA31C54 + F3CF6E0F7FB0CE768BDAEED2E6CE775BDCC663999CDA7CA3AC2F15E88208041C + 83C889E3905490C082381079C2222ECE4222244222244222244222F7B3B396EE + 711463B5CEE868EB2B84803278013A016200192794FDB2B29AF2511C4387BF79 + E4D1DAB5569676D61090CA0E1592477334E927A97EC105B585AE90436360ABDE + 7A4F5959DCA65A4BC718E3AB2D81E0DE9776B96425EF6C2F0413D055AF6A9A9B + CD69E424BC9678BAB0D99A3793A6E93EAFE15468AEF0B89D7A6EAE1BE6738A33 + D3F8C7B15FF974A7ED92665FCDDCD98E7F5289F989C299297174291F36447DF7 + 6BBB15C5E5F5BD8C40C9CE94646DE669EE2F2C9E4E3B265051F3BBD067576B96 + 5A69A59E432CAE2E7BB992A8547BCEB7E0BD826A7B2BDB2FA75F17FBC7EDFB27 + BDF64AE6F5DFA4348C7A318E43F0A8888B5850A300604F3D99989663927BE111 + 17672111122111122159E1F3F7F8992B03B5C04D5F6EEF40F83A8F685588A2E8 + AEA55C0607B0C9D763D6E1EB62AC39113AB62B318FCCDB38C542EA526B77D091 + 5E1C47482B29B9B693AD755EE39A5D6DCE5807131FE337ADBE459AB4BBB8B39D + 9716D218E661AB5C3C87AC2E8FB7B71DBE5E1EEDF48EF983F49174387C2657A3 + B3A17956536EC9FD5A72D51F994F678FDB3DEA7714752AFD0DC80978F91C769F + 67EF1399B5CE6B839A4B5C0D411C08216BF03BD648CB6DB2A75C7C9B75EF87AE + 073F0F35F1BB36C7D18BF2360CA5B9E33C2DF784FBE68F83E4F072C92DB8A379 + 4824647F5299E66775D3B70541C1FE8759D572B88B0CD5A00FA1752B05CB284B + 6BD20F48EC5CDF298ABBC5DC9B7B96D3A63907A2F6F5B4AB0DBBB9A7C5482198 + 992C1C7CE6732CAFBE67BA16EAF2CF1D9DC70048921906A8666F36BBE10ED1D2 + 16157B762E11F2F431E07BBF6EE9E9BD74754A8D9562BDCA8F32F7F8F78EE339 + 4229993C65CE32EDF6B703CE6F16BC7A2E69E4E6A86BD7560C0329C83C4113C0 + 7464628C0AB29C107B0C2222EC8C222244222244FB8A292691B146353DE68D0B + 5F8FB18ECA011B78BCF191FD67F02CEE12E20B7BDD5310D6B9A5A1C790248FC0 + B45FD4AC3EB11FC60B1EE8B921403A79F0ED9E86C96B0A5CB0D59C713C84A7CA + BB25792688EDE416CD3E68D27CE3F08AAEFE9B7FF5793E295A9FEA561F588FE3 + 04FEA561F588FE305C5B9D40515E00F61937DB54EC59AEC93ED129317869A49F + 5DD46590B38E970A171EAF02B8C96423B187850CAEE11B3DD3D8126CB58451B9 + E266BC81C18D3524F52CB5D5CCB7533A694D5CEE43A00E8017555EE7D560C2AF + 648BBD7B6AF454753B7DEE73E259649A4749238B9EE3524AF8445B279C4E7898 + 4444884444884444884444884444885EB6F7135B4EC9E0798E68CEA63C730579 + 221008C1E20C0241041C11C4113A86DFCEC199B421E036E9829710F41AF0D4D0 + 7DE9594DC7B5AE6D6EFBCC74124D6B3548646D2F319E969D20F0EA5478FBFB8C + 7DDC7756CED3230F2E870E96BBB0AE8D6DBAB093C11CAFB96C2F70ABA27D7534 + F483C17916556ECEEF52852F5BF34E78FDBB27BF55D4750DB8AB74E2BBABE561 + 2064778CFD2273DFE8B98FA85CFF0005FF009AAF36D4F9CC4DC7772D8DD3AC65 + 3FA4677521D27E1B7CDF656B86E0C2115FA743F1C27F5FC27D7A1F8E146CDE5D + 62147DBE41F634B29E9DB7A6C5B2BDDE1979715F84F8CEE160CC5977668D9D9E + 75BCA4716BBA8F4D0F4AE5F7104D6D3BE099A592C64B5ED3D042EA7FD7F09F5E + 87E38582DD77D697D977CD68E0F8C31AC320140E70E67DC53E98F72B1A995B46 + 35024723FF00595F5AAF6ECAB7A3A9B32148520EA1DFEE94A888BD69E0422224 + 4222244222244222244222244222244222244222244222244222244222244222 + 24422224422224422224422B2C360AEF30E95B6CF8D86100BBBC2E1E95694D2D + 7752B5FB8398F9EB6F8CFF00F8D52FB9A118ABB8561D8669AF65B9B503D75332 + 9E447B266115FCFB2B3B0B4B9B1B26A7446F15FCBD2A927B79EDA5315C46E8A5 + 6F363C169F6D4ABBAAB3E4756F032BB76F755FF96B64CF6B0C0F8CF3444564AA + 111122114BC663A7C9DE32CE0735B2BC120BC90DF346AF7A0ABCFB8398F9EB6F + 8CFF00F8D5566E29ACE9770A719C19A2ADA6E2E5D5556CEB9C6477CCC22D2BF6 + 1E65ADA892DDE7A83DD5FCA6054B7F8CBFC74823BC85D113E893C5A7D570A829 + 5EE29B0E11D58F703C672DDA6E291AACA9947791C3E322222D3FDC1CC7CF5B7C + 67FF00C6BB65D5558F5182E7967D9394EDAEBF57A485F4E3563B33CA6611698E + C2CC81512DB93D41CFF76355990DBB97C7B0C97101308E72B087B47874F2F1A8 + A6E687385B1493D9993B365BAAD4B3D2E00E671C078CAC4457589DAD90CADA9B + AB79216C61C59491CE06A003EF58EEB53B2C4AD753B051CB265555365CDA2B52 + CD8CE04A545EF7D672D95DCB69296BA485DA5C5B52DAF654056D8DDA392C8D94 + 77904B0B62975690F73C3BCD7161AD184730B8F7568A1D98056E44FB676BDBDD + 63B568859D73A947318E065122D31D859902A25B73D81CFF0076350AF36A672D + 1A5EEB7EF5839BA221FF00923CEF6941775B763816AE7C712D7D8EED065A97C0 + F667EA94C8BF4820D0F023985F8AF996117D318F91E191B4BDEE346B5A2A493D + 0005A0B2D9198B8687CDA2D9A78D2424BFE2B6BED955D975750CD8C17C65B4ED + EEB8E2A467C73C0E03C4CCEA2D7BBFC7D741BE65E465DD45840F66A550E63077 + 98892365C963BBD04B1D19241A73E601E950AF75458DA51C13DDCBEB96DDB1DD + 52BAEDA8AA8E6DC08E3E12B914FC4622E72F72EB6B67318F630C84C8481405AD + F7AD77C2571F70731F3D6DF19FFF001AED9B9A6B6D2EE14F7191AB67B9B575D7 + 5B32F2C899845A7FB8398F9EB6F8CFFF008D56E676F5EE1DB13AE5F13C4C5C1B + DD971F4695AEA6B7AD7137543B054B0163C809DB365BAAD0BD9532A8E64CBCFF + 001EFEBAFBD58FCAE53374EE4C8E2B211DBDA88CC6E85B21D6D24D4B9EDE823E + 0A87FE3DFD75F7AB1F95CA2EFEFB621FE59BF2E4580D69675275750C348E07F0 + 89EAADB655D191EB62ADAC8C8FC4648B2DFF00721E05F5B31F1F22E86AD70EDA + 38B81F69692EECF19B8B1AD7821EC78AC1381E731DFF00AF30B962DAFF008FEE + 9E45E5A1356374CAC1D44D5AEF714B79B44A93D7A7F2D9083E591E9DBFB2FB3F + 4BB9C5A960206A1C41033321796B2D9DD4B6B30A4B138B5DD5C3A47615F96F6B + 7372ED16F0BE677C18DA5C7F256837DC0D8F32C91A3F5D0B5CEF581733C802B8 + 8776E131B616F6F0B0CB236366B642D0D687E91AB538D38D7AAAB41DCD869A9E + BACD8D60E4390EF9906CA91B9BABB6E152547813C4B03CB1323260B331B35BEC + A60DE64E871A7868A02E8B89DE56991BC65A3A07C1249511B890E69205687951 + 56EFCC5C11B61C944D0C9247F7535386A241735C7B7CD2A156F2DF58537D7A19 + BE520CB2FE9D4FE9DB71B5BBD5543870460CA9D99FDC107AB27C82B5BBAB3379 + 89B7824B50C2E91E5AED609E0057A08592D99FDC107AB27C82B67B8B04FCCC30 + C4D9843DD38BAA5BAAB514EB0B3EF0D637D59B71A340D59E3DF3674E171E9970 + A33EA7A87460E0FDDED996877E659B2033450C91FBE680E69A761D47C8B5F90B + 7B6CCE18D47993C42585C471692DD6C72CEC3FE3EA48D335ED621E906328E23B + 0971A2B8DC3938B0D89EE616383DECEE6D80074B401A6A5DCBCD1D0AABFF004E + F6D43683CFAB9A8207D32EDAFEAABA6F3D40FE569E4E431F6F29CCD75DCA5CC9 + 698EB9B98A9DE431B9ECD5C4540AF15C8975BCC412DC62AEE085BAE59227358D + 1D248E038AD1D4F1AF6FAB96A6CE7BBCB32745D5E96EF4E75695D38E79C36262 + 06FBCD0352C80F6163BDC7AD66DECE373569239F108E588E8959CDA4387022BD + 7D4B131ED0DC0F23FED7483D2E7C629E2D555B4DB583761ACE46CCF0EB898874 + A5BE880D1C00AF9557BD5D98ABF2B47A991A741CF8E712EE98DD45AFFCFF0053 + D2C1D5EA8C7863330DB971F163F313C108D30BA9246DEA0F15A788AD7EC5FB11 + DFBE7F91AB25B9EFE2BFCCCF3427542CA471B8722182848ECAD56B762FD88EFD + F3FC8D566F357E82BD7F379339E79C4A7A768FF74B7D3C68FCCD38E58CF64C7E + E4FB76F7F787C816EB687F6ED9FF00A9FEEBD617727DBB7BFBC3E40B75B43FB7 + 6CFF00D4FF0075EA3BFF00F454F8A7F6992E97FF0025B9F0B3FBC4CE5E6F5CC4 + 17B3C2C6C259148F63416BB935C40AD1C1586277CC3712B60C84420738D1B330 + 92CA9F840F16F86AB1D93FB4AEFF007D27CB2A2AD4763B77AC0D014903CCBC0C + C43A9EF2AB58FA858063E57E2319E53A16ECDBB0DDDB497F6CC0DBC8817BF4FE + D1A389AFE301C8AE7ABA96D8B97DD60AD6490EA78698DC4F1AE87160F682C15A + D8B0EE56D891FA36DD18CB7F158F351EC0546C6D64175561CFA39C1F60E734F5 + 4DBA58DB7DC5434FEA7191FCCD8C1FA78CD8ED5C0C58EB36DDDC347D3656EA73 + 9DFB3611E88AF2E1CD56E5F7D39B2BA1C5B1A5AD34371271AFA8DF74AB8DE174 + FB6C14DA0D1D316C551D4EE2EF64021738B6B69EEA765BDBB3BC9A4E0C60A0AD + 057A557B4A57705F73B8F3712003F2803F74B77FB87DA0AF65B4F2F9416651E6 + 62787C4CB71BCB70076A370D23E098D94F69B55172F9CBBCBF706E9AC6BE00E0 + 1CC04575539824F52F5FBABB83EA4EF8CCFCE51AFB0B94B0884D796E6289CE0C + 0E25A7CE209A79A4F52DC83681C1AFD20FD9A08CFD13CDB5BA81AD96DF58D678 + B7A8188E1C7B65CEC1FB626FE59DF2E357BBAF3F7D8892D9B6A1844A1E5FADA4 + FA25B4A508EB545B07ED89BF9677CB8D68F71EDC7E69F039B3887B90E0416EAA + EAA768EA583726A1BF06EC68D3C7233D9C27ABB3179E9446DF3EAEB3A749C1F9 + 86789F64CCFDFACDFC187E21FCE55D97CFDF65DB136E83008892CD0D23D2A56B + 527A95F7FE3D9BEBCDFE19FCE59ACB63DD8DC84B64E7890C5A7CF0295D4D6BF9 + 71EB5AF6E764D67E485D6A33C011C3976F8CF3F763A9255FFD25FD36217CCC08 + 2798E47D934BFE3DFD75F7AB1F95CA2EFEFB621FE59BF2E452BFC7BFAEBEF563 + F2B9596E3DAF7198BE8EE639D91359108CB5C09350E73ABC3D6595AC4AFA8BB3 + 9D2BA471FF00289B529B2EE8F5A54BA9B5938F06339E2DBEC0B37B62BABC70A3 + 242D8E33D7A6A5DE50BF6CF6040C7875E5D195A39C71B7457FEA24F915B65733 + 8DC0D988230DEF9ADA416ACF68BBA8769E6A5BBDDADEBE86DC176723240EC123 + B0D83ED5FF0055BA22A5AC1C024124918EC994DF170D9735DDB4D7B889AC77AC + 497F91C16717A5C4F2DCCF24F33B54B2B8BDEEEB24D56D36EECE898D8EF72549 + 1CE01F1DB8E2D15E20BFAFC1C96B3657B4A1039E43000E6C7B71300AADEA1BAB + 1AB180CC5893C954F2CC8FB336FCC676656E5A591B01FA330F371229AFC001E0 + BE77CE5E29E48F1B0383840ED73B8711AE9A437C409AAD465EDF2F710F718D96 + 2B66B851F2B8BB5D3A99A5BC3C2B2171B1B230C12CEFB885C236BA4701AAA748 + D47DEAC345D5DB7FEA2FB1548E15D7DDE33D4DCEDEEA36A769B6A9994F9AEB8E + 06AEFC48BB33FB820F564F9056A778656FF1B6D6CFB297BA748F2D79D2D75401 + 5F7E0ACB6CCFEE083D593E415B1DC98397330431452B623138B897026B514E85 + DDD9AC6FAB36E34691AB50C8EDEC91E9EB6B74BB8539F50B9D3A4E93F779198D + 66F2DC2D755D721E3E0BA38E9F92D056E3137B16730ED96E226E9943A39A2E6D + A83434F2ACE45FE3E98BC77D7AD0CE9D0C24FB642D197E376EE2834BB441103A + 01357C8F3C787592557BB7DAB845DB28F5350C7A6BA65DD3EBDED66C7DE31F47 + 41C8B5B571FA6734C95AB6D321736AD356C32398D279D01A05D5B23746CEC6E2 + E83759858E786134AE915A55725BAB87DD5CCD7327A733DD23BC2E355D4B3FF6 + 25F7EE5FE456F50524ED55F8E490DFD3999FA4300BBE6AF8000327B3E7C483B7 + B74C597964B7922104ED1AA36EAD41CDE9A701C42AEDF12E5E1630C52918D946 + 87B582843FA9EEE6410B196D7335ADC477103B44B138398EED0BA7D9DCD96E1C + 392F6831CCDD13C7D2C78E63C478851BE85DA5E972A0351382A78E93ECCFD127 + B5DCBEFF006D66D9EC2B7819561E5D43DB8F819CAD744D8BF623BF7CFF002356 + 1F2B8D9F197B25A4DC74F163FA1CC3E8B82DC6C5FB11DFBE7F91AB475160DB50 + CA720B290665E8E8C9BE28C30CAAC083DE263F727DBB7BFBC3E40B75B43FB76C + FF00D4FF0075EB0BB93EDDBDFDE1F205BADA1FDBB67FEA7FBAF54EFF00FD153E + 29FDA65FD2FF00E4B73E167F789CEF27F695DFEFA4F965455B3BAD8975717734 + FF004B8DAD96473E9A492039C5CAC713B2EC2C656DC5C486EA661AB03806B011 + D3A6A6BE32B41EA1B74AC61B53003CA01994749DE5969CA6852C7CEC472F01C6 + 586DDB5758E0EDA29BCC7B586492BC29AC9938F82AB038EBC6BB72C378EE0D96 + EB5927A048FE7F94B47BB373C0D824C758C8249640593CADE2D6B7DF341E9279 + 158655ECA8765BADB06937E787B0F6FD32DEA5B9AD5F6F4D2750DB6327B32B8C + 0F76274BDE36AFB8C14C582AE85CD9683A9A68EF601AAC062AFF00FA76421BDE + EFBDEE493DDD74D6A0B79D0F5AE81B733B065ACC43339BF4C6374CD13BDF8E5A + C03CC1E955392D841F2BA4C6CED8D8EE3DCCB5A0F03DB534F12A76B72502CDB6 + E3CBC4F1EC20F03346FB6F66E5AADEECFCF80380C6415390707BBB44918DDEDF + 4EBF82CFE85DDF7CED3AFBDD54F177617DEFEFB1E1FE65BF2245030DB3B29679 + 2B7BB9E487BB85FA9C1AE717114E8F328A7EFEFB1E1FE65BF22450D3B75DE523 + 6F8D3DB824F1F7CB356EDBA76E4EEF3AFEEEA017CBC3BA52EC1FB626FE59DF2E + 356FBC73392C6CB6ADB29BBA1235E5FE6B1D5A16D3D369EB551B07ED89BF9677 + CB8D68B72EDD9B32FB77453362EE4381D409AEAA757814F706A5EA00DB8D1A78 + EA191CB87095ED16E6E92C28D5EA17F2E83A4FCC33C6643EF7EE2FAE7FF5C5F9 + 8AB2F2F2E6F6E5F7574FEF27929ADF40DAE901A383401C82D37FE3FBCFADC7F1 + 5CA06676ADC626CC5D493B2469786696820F104F4F816CAAED96B02AD019BCA3 + 4AE09F6729E75FB6EA5E9937FA8C8BE63ADF5018EDC6657E37317F8B748EB378 + 619400FAB43ABA6B4F4876A9FF007CF707CFB7F86CFC0A8915ED452E75356AC4 + F69009995375B8AD4225AEAA392AB1025ADC6E7CF5C0D2FBD781FF00C7A63F6E + 30D556E739CE2E712E71E249E24AFC4534AD1382285FC2312165B6587363B3FE + 225BEB85771EF0CF46C6C6D9DA1AC01AD1DDB390E1D4A91171EAAECC6B50D8E5 + A86676BBADAB3E9BB2679E938CCBDFBE7B83E7DBFC367E05F32EEECECD13E292 + 769648D2C70D0C1C1C287A1522287E9B6E3FF527FDA25877BBB2306FB38FF399 + 22C6FAE6C2E5B756AE0D99A086B880798A1E055AFDF3DC1F3EDFE1B3F02A2452 + 7A6A73974563CB2C33235EE6FA974D76BA0CE70AC40CCBB7EF0DC0F14FA486F6 + B58C07E4AAAB9BBBABB93BDB995F349F09E4BBD8AAF1444A6A4E288ABF840139 + 66E2EB062CB1DC773312215CDCEEBCDDCC125BCD335D14AD2C780C68A83CF880 + A99175AB4720BA862BF2E4671E138975B58608ECA1B830538CF8C29D8DCCE431 + 6643672E812535820381A72E0E50514995581560181EC3C448A3BA306462AC39 + 329C193F2599BFCA777F4C735E63AE8706B5A68798AB405E98FDC395C6C06DED + 250C88B8BE858D77134E923B1562287A3514D051740FBB8E1F0931B8B8586D16 + 30B0F02FA8EAF8CF6BABA9AEEE24B99CEA9653A9E4002A7C0158596E6CC58DAB + 2D6DA56B618EBA5A58D3E912E3C48EB2AA5175AAAD942B282A390232062712EB + 51CBA3B2B3672CA704E789C997A7796E02282E1A3B446CF75AA0DDE6F2D7A0B6 + E6EE47B0F3603A5A7C2D6D02808A2B452A72B5A03DE14493EEB70E30F758C3B8 + B12211115B299F51C9246F6C91B8B1ED356B9A4820F610AEEDB796760686995B + 381CBBD6827D96E927C6A89142CAABB3E740DE225B55F75473558C99E7A4E269 + 5FBEF34E146B20676B58EFFDCF2AA7219BC9E49A19793992369D4D65035A0F11 + 5A340EB50114136F4A1CA56A0F7E38C9D9BCDCDA34D96BB29E6B9E1F092F1D93 + BCC64EE9ECDE192B9A584901DE6921DEFBC0ACBEF9EE0F9F6FF0D9F81512293D + 1539D4F5AB1EF233235EE7715AE9AED745EE56204BDFBE7B83E7DBFC367E0517 + 21B872B92805BDDCA1F10707D031ADE22BD2076AAC45C5DBD0A432D6808E4428 + 9D6DDEE5D4AB5D6329E0416241844456CA211112211112211112211112211112 + 2111122111122111122111122111122111122111122111122111122111122111 + 1221111221111221111221111221111221111221111221111221111221111221 + 111221111221111221111221111221111221111224F9EC2D2DE28CCB72E134B1 + 3666C6D8AA3CF150DD5AC791405697F9391F15BC104B5845B471C8DA0F48368E + 1522AAAD5756BD397E67F6EE12DBBD30D8AF90FDBBCC9761671DD77EE9253147 + 6F177AF706EB246B647402ADF86BF2EECC411C33472096DE70EEEDF42D3561A3 + 839A791F1AF6C55DB2D5B7AE25BADF6E59135ED0F6B9DDEC4EA6978737934F35 + F995BA8EEDF0CF1B835859436C0696C2E07CE6B00006927CE0A39B3D5C7DCCFE + E93D357A19E1EA63DFF378F7766240532C71B25EB277B1C1BDCB6AD04575BE85 + C231DA5AD71F1286ADE1C95BD8DB5A470C4D9E663BE9323C97B74CB5A35BE696 + D74B5A3D92A56970B84196264295ACB66C385038FB7B3863E32A1149C80B6FA6 + 4AEB535B779D718F821C3568E3F06B45194C1C807964678CAD86962B90707191 + CA58E430D3D9E49B60C7099D210D85ED140E24E8E5C793810BC727642C2F64B5 + 120983031C24028087B1B20E1FF52B6BBCB59BE6BF983B5CD1CB2BB1EF00F113 + F9AF3D9A7D26F6AABCB4F14F79DE44ED4CEEA06D7B590C6C70E3D442A296B495 + 0E08C279B8632DC3F74D5B84A155CD64126C1A78E709E6C8F88F863BE4253EEE + C2D2D7F46FB971B8EED92681179B5918D900D7AFA9DD4A02BCC9DC9B861EEAFA + 1FA3F7310EE0876BAC713039BFABE7A9BD6A76160CA064039CFD1EC32AA950A3 + 9201618D39F7E7B47B251A916F6A6786E246BA8EB76093453D26EA0C753C1AAA + A3A978C9E382F5865348240E8A63CE91C80C6E3E206AA6E48525798E3E38ECF7 + C85614B80DC8F0CF767B7DD3D1F899DB0D8C8D7073AF9C5AD8C736BAA0341F58 + 3810A25C46D8A796263FBC6C6E7344805038034AD3B55DC794B36CF784BFCCB7 + D2EC7F03C5D0C6EB78E9D55AB5FE2540ABA9AC24EBE18F663E6E3F47296DEB52 + 81E9907248E79C69E19FF31E33D20825B89E38221AA595C18C6F5971A053463A + D6532436B77DF5D46D73B418F4C6FD00B9C227EA24F01C2AD1551F1D74DB4BE8 + 2E5CDD4C8DE0BDA3996F2753C4A6DAB2D31F726F45DC733220E36EC6076B7B88 + 219A9A5A3452B535F1552C6704E3238657033A9BB8C52B59035007CD8724E34A + 778E23DBDF2A549C7DA0BCBA6C05FDDB4B5EF73E9AA82363A43C2A3E0A8CA761 + EE63B6BF6CD23835AD8E600B86A1A9D0BDAD05A41AD5C42B2C2C118AFCC14E3C + 7B25550536A07F94B2EAF0CF19F171651B2D9B756F377D017F74EAB4B1CD7D35 + 716D48A11D454456390BD65E5A5BB9A5B1BE3AB25B6634319ABE79AD600DF387 + 3ED1D4AB972B2C57CDCF2676E081FC9CB039787BE4C871D2CD6D14F1B8132CAF + 8B49E01A236B2473DCE3C00A3D4699B1B2573637F78C0681F4D35ED00AB3B6C8 + C10E21B67279CD96797E911B783C46E6C3A5CD77ACCE5D3D2AB66632395CC8E4 + 12B07A32004541EC3C9710B966D5C389D3C398CC95AB58552982485D5C791C77 + 4F3444564A611112211112211112211112211112211112211112211112211112 + 2111122111122111122111122111122111122111122111122111122111122111 + 1221111221111221111221111221111221111221111221111221111221111221 + 1112211112211112211112211112211112211112211112211112211112211112 + 21111221111221111221111221111221111221111221111227FFD9 + } + Proportional = True + end + object Image_From_Local: TImage + Left = 129 + Height = 105 + Top = 551 + Width = 104 + Proportional = True + end + object Image_From_Web: TImage + Left = 257 + Height = 105 + Top = 551 + Width = 104 + end + object Button1: TButton + Left = 7 + Height = 25 + Top = 120 + Width = 75 + Caption = 'Join' + TabOrder = 0 + OnClick = Button1Click + end + object Button2: TButton + Left = 193 + Height = 25 + Top = 120 + Width = 75 + Caption = 'Clear' + TabOrder = 1 + OnClick = Button2Click + end + object Button3: TButton + Left = 89 + Height = 25 + Top = 120 + Width = 89 + Caption = 'Create Option' + TabOrder = 2 + OnClick = Button3Click + end + object PageControl1: TPageControl + Left = 8 + Height = 76 + Top = 151 + Width = 353 + ActivePage = TabSheet1 + TabIndex = 0 + TabOrder = 3 + object TabSheet1: TTabSheet + Caption = 'EDIT Result' + ClientHeight = 48 + ClientWidth = 345 + object Panel3: TPanel + Left = 3 + Height = 29 + Top = 9 + Width = 97 + Caption = 'Resultado:' + ParentBackground = False + TabOrder = 0 + end + object Edit3: TEdit + Left = 106 + Height = 23 + Top = 13 + Width = 220 + Enabled = False + TabOrder = 1 + end + end + object TabSheet2: TTabSheet + Caption = 'Combobox Result' + ClientHeight = 48 + ClientWidth = 345 + ImageIndex = 1 + object Panel4: TPanel + Left = 3 + Height = 29 + Top = 9 + Width = 97 + Caption = 'Resultado:' + ParentBackground = False + TabOrder = 0 + end + object ComboBox1: TComboBox + Left = 106 + Height = 23 + Top = 13 + Width = 217 + ItemHeight = 15 + Style = csDropDownList + TabOrder = 1 + end + end + end + object Panel5: TPanel + Left = 8 + Height = 79 + Top = 35 + Width = 353 + ClientHeight = 79 + ClientWidth = 353 + ParentBackground = False + TabOrder = 4 + object Panel1: TPanel + Left = 7 + Height = 29 + Top = 8 + Width = 97 + Caption = 'First Name:' + ParentBackground = False + TabOrder = 0 + end + object Edit1: TEdit + Left = 120 + Height = 23 + Top = 12 + Width = 225 + TabOrder = 1 + end + object Panel2: TPanel + Left = 8 + Height = 29 + Top = 43 + Width = 97 + Caption = 'Last Name:' + ParentBackground = False + TabOrder = 2 + end + object Edit2: TEdit + Left = 120 + Height = 23 + Top = 47 + Width = 225 + TabOrder = 3 + end + end + object Edit_Credito_Nome: TEdit + Left = 8 + Height = 23 + Top = 790 + Width = 152 + Color = clBtnFace + Enabled = False + TabOrder = 5 + Text = 'By: Talis Jonatas Gomes' + end + object Edit_Credito_Email: TEdit + Left = 186 + Height = 23 + Top = 790 + Width = 152 + Color = clBtnFace + Enabled = False + TabOrder = 6 + Text = 'talisjonatas@me.com' + end + object Panel6: TPanel + Left = 8 + Height = 41 + Top = 229 + Width = 353 + ClientHeight = 41 + ClientWidth = 353 + ParentBackground = False + TabOrder = 7 + object CheckBox1: TCheckBox + Left = 10 + Height = 19 + Top = 12 + Width = 139 + Caption = 'CheckBox not checked' + TabOrder = 0 + OnClick = CheckBox1Click + end + end + object Button_Selecionar: TButton + Left = 8 + Height = 25 + Top = 448 + Width = 75 + Caption = 'Select' + TabOrder = 8 + OnClick = Button_SelecionarClick + end + object ComboBox_Selecionar: TComboBox + Left = 89 + Height = 23 + Top = 449 + Width = 272 + ItemHeight = 15 + Style = csDropDownList + TabOrder = 9 + end + object Panel7: TPanel + Left = 8 + Height = 32 + Top = 293 + Width = 353 + ClientHeight = 32 + ClientWidth = 353 + ParentBackground = False + TabOrder = 10 + object RadioButton1: TRadioButton + Left = 7 + Height = 19 + Top = 8 + Width = 48 + Caption = 'Item1' + TabOrder = 0 + end + object RadioButton2: TRadioButton + Left = 121 + Height = 19 + Top = 8 + Width = 48 + Caption = 'Item2' + TabOrder = 1 + end + object RadioButton3: TRadioButton + Left = 232 + Height = 19 + Top = 8 + Width = 48 + Caption = 'Item3' + TabOrder = 2 + end + end + object Button4: TButton + Left = 129 + Height = 25 + Top = 662 + Width = 104 + Caption = 'Load from Local' + TabOrder = 11 + OnClick = Button4Click + end + object Button_Load_from_Web: TButton + Left = 257 + Height = 25 + Top = 662 + Width = 104 + Caption = 'Load from Web' + TabOrder = 12 + OnClick = Button_Load_from_WebClick + end + object Memo1: TMemo + Left = 8 + Height = 90 + Top = 693 + Width = 266 + Lines.Strings = ( + 'Memo1' + ) + TabOrder = 13 + end + object Button5: TButton + Left = 280 + Height = 25 + Top = 693 + Width = 86 + Caption = 'New Line' + TabOrder = 14 + OnClick = Button5Click + end + object Button6: TButton + Left = 280 + Height = 25 + Top = 724 + Width = 86 + Caption = 'View' + TabOrder = 15 + OnClick = Button6Click + end + object Button7: TButton + Left = 280 + Height = 25 + Top = 755 + Width = 86 + Caption = 'Clear' + TabOrder = 16 + OnClick = Button7Click + end + object Button8: TButton + Left = 286 + Height = 25 + Top = 120 + Width = 75 + Caption = 'Options' + TabOrder = 17 + end + object EditButton1: TEditButton + Left = 8 + Height = 23 + Top = 522 + Width = 152 + ButtonWidth = 23 + MaxLength = 0 + NumGlyphs = 1 + OnButtonClick = EditButton1ButtonClick + PasswordChar = #0 + TabOrder = 18 + Text = 'EditButton1' + end + object LabeledEdit1: TLabeledEdit + Left = 8 + Height = 23 + Top = 495 + Width = 358 + EditLabel.Height = 15 + EditLabel.Width = 358 + EditLabel.Caption = 'My LabeledEdit' + TabOrder = 19 + end + object RadioGroup1: TRadioGroup + Left = 8 + Height = 70 + Top = 331 + Width = 346 + AutoFill = True + Caption = 'RadioGroup1' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 2 + ClientHeight = 50 + ClientWidth = 342 + Columns = 2 + Items.Strings = ( + 'Item 1' + 'Item 2' + 'Item 3' + 'Item 4' + 'Item 5' + ) + TabOrder = 20 + end + object Button9: TButton + Left = 8 + Height = 25 + Top = 413 + Width = 74 + Caption = 'Select #2' + TabOrder = 21 + OnClick = Button9Click + end + object Button10: TButton + Left = 85 + Height = 25 + Top = 413 + Width = 74 + Caption = 'Caption' + TabOrder = 22 + OnClick = Button10Click + end + object Button11: TButton + Left = 165 + Height = 25 + Top = 413 + Width = 74 + Caption = 'Add Item' + TabOrder = 23 + OnClick = Button11Click + end + object Label2: TLabel + Left = 331 + Height = 15 + Top = 417 + Width = 23 + Caption = 'Cols' + end + object Button12: TButton + Left = 248 + Height = 25 + Top = 413 + Width = 32 + TabOrder = 24 + OnClick = Button12Click + end + object Button13: TButton + Left = 286 + Height = 25 + Top = 413 + Width = 32 + TabOrder = 25 + OnClick = Button13Click + end + object OpenPictureDialog1: TOpenPictureDialog + Left = 204 + Top = 592 + end + object PopupMenu1: TPopupMenu + Left = 304 + Top = 144 + object Join1: TMenuItem + Caption = 'Join' + OnClick = Join1Click + end + object CreateOption1: TMenuItem + Caption = 'Create Option' + OnClick = CreateOption1Click + end + object Clear1: TMenuItem + Caption = 'Clear' + OnClick = Clear1Click + end + object N1: TMenuItem + Caption = '-' + end + object ShowTab01: TMenuItem + Caption = 'Show Tab 0' + OnClick = ShowTab01Click + end + object ShowTab11: TMenuItem + Caption = 'Show Tab 1' + OnClick = ShowTab11Click + end + object N2: TMenuItem + Caption = '-' + end + object ab0Invisible1: TMenuItem + Caption = 'Tab 0 Invisible' + OnClick = ab0Invisible1Click + end + object ab1Invisible1: TMenuItem + Caption = 'Tab 1 Invisible' + OnClick = ab1Invisible1Click + end + object N3: TMenuItem + Caption = '-' + end + object ab0Visible1: TMenuItem + Caption = 'Tab 0 Visible' + OnClick = ab0Visible1Click + end + object ab1Visible1: TMenuItem + Caption = 'Tab 1 Visible' + OnClick = ab1Visible1Click + end + end + object ImageList1: TImageList + Left = 280 + Top = 572 + Bitmap = { + 4C7A030000001000000010000000C60400000000000078DACDD67F4CD4751CC7 + F1175FDCF7CE7E787C6F80CE50ECCB7990500A5FD250443C39D0935F92BFE04C + F0A69806982585931F93723963ABCD7E6DD5B2AD9933442CCEAD54FAC114D403 + 44E5402302423AE2476BFE98EB1FFABEBFF0FD21B38B667FF4C773FBF0F9BC1F + C7F76EFBC00118C103E6A3C7CDC929A83014C3CAED87E02D9AA15932B29F9C8C + 8A799F07F39B7FCC600B6E3C076DF9BD1BEEC9717D153BF7F04C9E8CEC0D45B0 + 3AAEAD62B3DDA9D0965EBF446AFCFEC6D614968CE2CB216CED5C8B754D894AB6 + EF6330323222456BED594E5B1AC8C87E4A2904DA4B3DBB5829E194A0785A6BCF + D63727818CE2F740C86A5981A4DAF988733E29B5A0CA8C818101F4F4F460F6C7 + FE08F9D02815FA4920624E84818CEC1F2D82B0C69580D8AFC271F7EE5D747777 + A3B5B5156D6D6DE8E8E8405757177A7B7BE1F178C01FE21071F4319091FD2385 + 1032CE2F85709CC7D5AB5771E5CA95FBDAC1C141F08739841D9F0A32B27F7827 + 84A575F3105263047F841BED334EB1B456F66B38CC76FA838CEC1F2A8010796E + 16F85A4ECDC9A9CFECE4EE390BA935828CE2B74308774D07DFC0A99DE6D4673E + CDDD7B264646F63A3BACA6B3012CDF229E693B39D6B8FDE03A034B46F6BE91A8 + F02BD3F1C1F57E2C7F4D9CF1D2CC7A033BA58CE5C98CF921F8C2E56346B18F15 + CB181B046FD10CCD92912C7047AC5FECC6BFAC7FCC8E3C787AF12EA788EFA758 + FC4CF60BDEA3199AD5DF547D7285C954C96FDAD4CFE6E7DFC6DF9597770B3939 + 1ED664FA8227A3FA22EBC68D7DACDDFE0B265266660F4B46F5E582C3F11BD2D2 + DA265456560FC8A8BE54A03D8BE5C2844A4D75838CEAF708E9E9ED58B0E05BA5 + A8A86F101A5A8DA0A0C3080C3C04A3F123295A87873B4146F3FE059BED3204E1 + 9474FF3B3B3BD1D4D484969616E90ED33D181E1E96E2B84F31634625C8A8BE50 + 484C6C82D9ECC4A54B97E072B9EE6B47FD514C9B560D32AADF294447D78BCF57 + 239E1FF9876AE0EF7F1264545F20F07C8378563BA18CC65A9051FD762128A849 + 3C6B987064546FB706049C6339AE0513C960A863C9A83EB242A72BE3FDFCEAC5 + D7B8066F190CF52CCB96F16494FB0F5FF12E9B8B01EB32C026788F6668D6F77F + 73FFF50C6EA5F8FBBC5B328B79F68089B1788B6668968CECC59FDFA95A3927A2 + BFE205FD9D0F5E81B6DBD4FB85A3BDB70B9E03CFEB8FD99E882023FB3DC14C86 + E7CD6DFA5FF766435BFB4BE952E3F77B5F77E8C9C87EDFE34CFCEF6F17E0E7DD + EB942EE7D994FFDFB4D69E79DED80232B27F2D9889179F0BEE1753955CB9098A + A7B5F6ACAB7403C8C87EEF0C66494F790E9AB725295DD86C41D572332AAD21A8 + B685E258A2498AD63F64C7828CEC4B8398B89F4AECD2EF39EF88C799D591F872 + 8559BAC78D8D8D38B17C366A6C66A5336BA24046F9FCA63371D7C5F7D590BD08 + DF6544A0367D0EBE4E0D93ACDBED96D6B42757B736126464BF7B1AB3B87DC74A + 5CCC9C878BEBE74AD5AD8E902C7D7FA1B5BC4FB9EC512023FB57A732B19D7916 + B4E73CADD428BE16D9A1A12169AD3DA3C8C8FEE5006691A7C0821B5B172AB565 + 474B96FE66D15A7B469191FD163F9FE4EEDC85BA3F76C4415B7356A4D4F8FD2E + C77C1D19D93FC3E2AD831181A63EF135FEDC6581B7FA72637407C3034C64E4FB + 3F09703DC5A0246312ACF64988F616CDD02C99FFE2FEFF05A3309D53 + } + end +end diff --git a/Beta/Demos/Lazarus_linux/unitcontrols.pas b/Beta/Demos/Lazarus_linux/unitcontrols.pas new file mode 100644 index 0000000..efa2b25 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitcontrols.pas @@ -0,0 +1,489 @@ +unit unitcontrols; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +interface + +uses + Classes, SysUtils, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, ComCtrls, + EditBtn, ExtDlgs, Menus, D2Bridge.Forms; + +type + + { TFormControls } + + TFormControls = class(TD2BridgeForm) + ab0Invisible1: TMenuItem; + ab0Visible1: TMenuItem; + ab1Invisible1: TMenuItem; + ab1Visible1: TMenuItem; + Button1: TButton; + Button10: TButton; + Button11: TButton; + Button12: TButton; + Button13: TButton; + Button2: TButton; + Button3: TButton; + Button4: TButton; + Button5: TButton; + Button6: TButton; + Button7: TButton; + Button8: TButton; + Button9: TButton; + Button_Load_from_Web: TButton; + Button_Selecionar: TButton; + CheckBox1: TCheckBox; + Clear1: TMenuItem; + ComboBox1: TComboBox; + ComboBox_Selecionar: TComboBox; + CreateOption1: TMenuItem; + Edit1: TEdit; + Edit2: TEdit; + Edit3: TEdit; + EditButton1: TEditButton; + Edit_Credito_Email: TEdit; + Edit_Credito_Nome: TEdit; + ImageList1: TImageList; + Image_From_Local: TImage; + Image_From_Web: TImage; + Image_Static: TImage; + Join1: TMenuItem; + Label1: TLabel; + Label2: TLabel; + LabeledEdit1: TLabeledEdit; + Label_Titulo: TLabel; + Memo1: TMemo; + N1: TMenuItem; + N2: TMenuItem; + N3: TMenuItem; + OpenPictureDialog1: TOpenPictureDialog; + PageControl1: TPageControl; + Panel1: TPanel; + Panel2: TPanel; + Panel3: TPanel; + Panel4: TPanel; + Panel5: TPanel; + Panel6: TPanel; + Panel7: TPanel; + PopupMenu1: TPopupMenu; + RadioButton1: TRadioButton; + RadioButton2: TRadioButton; + RadioButton3: TRadioButton; + RadioGroup1: TRadioGroup; + ShowTab01: TMenuItem; + ShowTab11: TMenuItem; + TabSheet1: TTabSheet; + TabSheet2: TTabSheet; + procedure ab0Invisible1Click(Sender: TObject); + procedure ab0Visible1Click(Sender: TObject); + procedure ab1Invisible1Click(Sender: TObject); + procedure ab1Visible1Click(Sender: TObject); + procedure Button10Click(Sender: TObject); + procedure Button11Click(Sender: TObject); + procedure Button12Click(Sender: TObject); + procedure Button13Click(Sender: TObject); + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + procedure Button4Click(Sender: TObject); + procedure Button5Click(Sender: TObject); + procedure Button6Click(Sender: TObject); + procedure Button7Click(Sender: TObject); + procedure Button9Click(Sender: TObject); + procedure Button_Load_from_WebClick(Sender: TObject); + procedure Button_SelecionarClick(Sender: TObject); + procedure CheckBox1Click(Sender: TObject); + procedure Clear1Click(Sender: TObject); + procedure CreateOption1Click(Sender: TObject); + procedure EditButton1ButtonClick(Sender: TObject); + procedure Join1Click(Sender: TObject); + procedure ShowTab01Click(Sender: TObject); + procedure ShowTab11Click(Sender: TObject); + private + URL_Image_Web : string; + public + { Public declarations } + protected + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; var HTMLControl: string); override; + procedure EventD2Bridge(const PrismControl: TPrismControl; const EventType: TPrismEventType; EventParams: TStrings); override; + procedure Upload(AFiles: TStrings; Sender: TObject); override; + end; + +function FormControls: TFormControls; + +implementation + +uses + LazarusWebApp, D2BridgeFormTemplate; + +{$R *.lfm} + +function FormControls: TFormControls; +begin + result:= (TFormControls.GetInstance as TFormControls); +end; + +procedure TFormControls.Button1Click(Sender: TObject); +begin + if Edit1.Text = '' then + begin + MessageDlg('Add the name', TMsgDlgType.mtWarning, [mbok], 0); + abort; + end; + + if Edit2.Text = '' then + begin + MessageDlg('Add the last name', TMsgDlgType.mtWarning, [mbok], 0); + abort; + end; + + Edit3.Text:= Edit1.Text + ' ' + Edit2.Text; + +end; + +procedure TFormControls.ab0Invisible1Click(Sender: TObject); +begin + {$IFDEF D2BRIDGE} + D2Bridge.PrismControlFromID('TabControl1').AsTabs.TabVisible[0]:= false; + {$ENDIF} +end; + +procedure TFormControls.ab0Visible1Click(Sender: TObject); +begin + {$IFDEF D2BRIDGE} + D2Bridge.PrismControlFromID('TabControl1').AsTabs.TabVisible[0]:= true; + {$ENDIF} +end; + +procedure TFormControls.ab1Invisible1Click(Sender: TObject); +begin + {$IFDEF D2BRIDGE} + D2Bridge.PrismControlFromID('TabControl1').AsTabs.TabVisible[1]:= false; + {$ENDIF} +end; + +procedure TFormControls.ab1Visible1Click(Sender: TObject); +begin + {$IFDEF D2BRIDGE} + D2Bridge.PrismControlFromID('TabControl1').AsTabs.TabVisible[1]:= true; + {$ENDIF} +end; + +procedure TFormControls.Button10Click(Sender: TObject); +begin + RadioGroup1.Caption:= 'New '+DateTimeToStr(now); +end; + +procedure TFormControls.Button11Click(Sender: TObject); +begin + RadioGroup1.Items.Add('New Item'+IntToStr(RadioGroup1.Items.Count + 1)); +end; + +procedure TFormControls.Button12Click(Sender: TObject); +begin + if RadioGroup1.Columns > 1 then + RadioGroup1.Columns:= RadioGroup1.Columns - 1; +end; + +procedure TFormControls.Button13Click(Sender: TObject); +begin + RadioGroup1.Columns:= RadioGroup1.Columns + 1; +end; + +procedure TFormControls.Button2Click(Sender: TObject); +begin + if messagedlg('Confirm clear all fields?', mtconfirmation, [mbyes,mbno], 0) = mryes then + begin + Edit1.Clear; + Edit2.Clear; + Edit3.Clear; + + if messagedlg('Confirm clear the options also?', mtconfirmation, [mbyes,mbno], 0) = mryes then + begin + ComboBox1.Clear; + ComboBox_Selecionar.Clear; + end; + end; + +end; + +procedure TFormControls.Button3Click(Sender: TObject); +begin + if Edit3.Text = '' then + begin + Showmessage('Nothing to create options'); + abort; + end; + + if messagedlg('Really create the option?', mtconfirmation, [mbyes,mbno], 0) = mryes then + begin + Combobox1.Items.Add(Edit3.Text); + ComboBox_Selecionar.Items:= Combobox1.Items; + end; +end; + +procedure TFormControls.Button4Click(Sender: TObject); +begin + if OpenPictureDialog1.Execute then + Image_From_Local.Picture.LoadFromFile(OpenPictureDialog1.FileName); +end; + +procedure TFormControls.Button5Click(Sender: TObject); +begin + Memo1.Lines.Add('Now: ' + DateTimeToStr(now)); +end; + +procedure TFormControls.Button6Click(Sender: TObject); +begin + ShowMessage(Memo1.Lines.Text); + ShowMessage(Memo1.Lines.Text, true, true); +end; + +procedure TFormControls.Button7Click(Sender: TObject); +begin + Memo1.Clear; +end; + +procedure TFormControls.Button9Click(Sender: TObject); +begin + RadioGroup1.ItemIndex:= 1; +end; + +procedure TFormControls.Button_Load_from_WebClick(Sender: TObject); +begin + if not IsD2BridgeContext then + begin + MessageDlg('This function run just in D2Bridge Context', mtwarning, [mbok], 0); + end else + begin +{$IFDEF D2BRIDGE} + URL_Image_Web:= 'https://www.d2bridge.com.br/img/d2bridge.png'; + D2Bridge.UpdateD2BridgeControl(Image_From_Web); +{$ENDIF} + end; +end; + +procedure TFormControls.Button_SelecionarClick(Sender: TObject); +begin + {$IFDEF D2BRIDGE} + ShowPopup('PopupSelecione'); + {$ELSE} + Showmessage('Selecionado: '+ ComboBox_Selecionar.Text); + {$ENDIF} +end; + +procedure TFormControls.CheckBox1Click(Sender: TObject); +begin + if CheckBox1.Checked then + CheckBox1.Caption:= 'CheckBox checked' + else + CheckBox1.Caption:= 'CheckBox unchecked'; +end; + +procedure TFormControls.Clear1Click(Sender: TObject); +begin + Button2Click(Button2); +end; + +procedure TFormControls.CreateOption1Click(Sender: TObject); +begin + Button3Click(Button3); +end; + +procedure TFormControls.EditButton1ButtonClick(Sender: TObject); +begin + Showmessage('Right button click'); +end; + +procedure TFormControls.Join1Click(Sender: TObject); +begin + Button1Click(Button1); +end; + +procedure TFormControls.ShowTab01Click(Sender: TObject); +begin +{$IFDEF D2BRIDGE} + D2Bridge.PrismControlFromID('TabControl1').AsTabs.ActiveTabIndex:= 0; +{$ENDIF} +end; + +procedure TFormControls.ShowTab11Click(Sender: TObject); +begin + {$IFDEF D2BRIDGE} + D2Bridge.PrismControlFromID('TabControl1').AsTabs.ActiveTabIndex:= 1; + {$ENDIF} +end; + +procedure TFormControls.ExportD2Bridge; +begin + inherited; + + Title:= 'Lazarus Controls Demo'; + + TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + with D2Bridge.Items.add do + begin + LCLObj(Label_Titulo); + + with PanelGroup('Full name').Items.Add do + begin + with Row.Items.Add do + FormGroup('Name').AddLCLObj(Edit1); + + with Row.Items.Add do + FormGroup('Last Name').AddLCLObj(Edit2); + end; + + with Row.Items.Add do + begin + FormGroup('', CSSClass.Col.colauto).AddLCLObj(Button1, CSSClass.Button.config); + FormGroup('', CSSClass.Col.colauto).AddLCLObj(Button3, CSSClass.Button.add); + FormGroup('', CSSClass.Col.colauto).AddLCLObj(Button2, CSSClass.Button.delete); + FormGroup('', CSSClass.Col.colauto).AddLCLObj(Button8, PopupMenu1, CSSClass.Button.options); + end; + + with Row.Items.Add do + with Tabs('TabControl1') do + begin + with AddTab(PageControl1.Pages[0].Caption).Items.Add do + FormGroup(Panel3.Caption, CSSClass.Col.colsize4).AddLCLObj(Edit3); + + with AddTab(PageControl1.Pages[1].Caption).Items.Add do + FormGroup(Panel4.Caption, CSSClass.Col.colsize4).AddLCLObj(ComboBox1); + end; + + with Row.Items.Add do + with PanelGroup('CheckBox').Items.Add do + LCLObj(CheckBox1); + + with Row.Items.Add do + FormGroup.AddLCLObj(Button_Selecionar); + + //Combobox + with Row.Items.Add do + begin + with PanelGroup('Select 1 item').Items.Add do + begin + LCLObj(RadioButton1); + LCLObj(RadioButton2); + LCLObj(RadioButton3); + end; + end; + + + //RadioGroup + Row.Items.Add.Col.Add.VCLObj(RadioGroup1); + with Row.Items.Add do + begin + FormGroup.AddVCLObj(Button9); + FormGroup.AddVCLObj(Button10); + FormGroup.AddVCLObj(Button11); + with FormGroup('Columns').Items.Add do + begin + VCLObj(Button12, CSSClass.Button.decrease); + VCLObj(Button13, CSSClass.Button.increase); + end; + end; + + + //Popup + with Popup('PopupSelecione', 'Select the item').Items.Add do + with Row.Items.Add do + FormGroup('Select').AddLCLObj(ComboBox_Selecionar); + + //LabeledEdit + with Row.Items.Add do + FormGroup(LabeledEdit1, CSSClass.Col.col); + + //ButtonedEdit + with Row.Items.Add do + begin + FormGroup('EditButton Info').AddLCLObj(EditButton1); + end; + + //Images + with Row.Items.Add do + begin + with PanelGroup('Static Image', '', false, CSSClass.Col.colsize2).Items.Add do + LCLObj(Image_Static); + + with PanelGroup('Upload Image', '', false, CSSClass.Col.colsize6).Items.Add do + begin + with Row.Items.Add do + LCLObj(Image_From_Local); + + with Row.Items.Add do + Upload; + end; + + with PanelGroup('Load from Web', '', false, CSSClass.Col.colsize2).Items.Add do + begin + with Row.Items.Add do + Col.Add.LCLObj(Image_From_Web); + + with Row.Items.Add do + Col.Add.LCLObj(Button_Load_from_Web, CSSClass.Col.colsize12); + end; + end; + + //Accordion + with Row.Items.Add do + with Accordion do + with AddAccordionItem('Show information (accordion)').Items.Add do + begin + with Row.Items.Add do + FormGroup('Name').AddLCLObj(Edit_Credito_Nome); + with Row.Items.Add do + FormGroup('Contact').AddLCLObj(Edit_Credito_Email); + end; + end; + +end; + +procedure TFormControls.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + inherited; + + //Change Init Property of Prism Controls + { + if PrismControl.VCLComponent = Edit1 then + PrismControl.AsEdit.DataType:= TPrismFieldType.PrismFieldTypeInteger; + + if PrismControl.IsDBGrid then + begin + PrismControl.AsDBGrid.RecordsPerPage:= 10; + PrismControl.AsDBGrid.MaxRecords:= 2000; + end; + } +end; + +procedure TFormControls.RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); +begin + inherited; + + if PrismControl.VCLComponent = Image_From_Web then + PrismControl.AsImage.URLImage:= URL_Image_Web; +end; + +procedure TFormControls.EventD2Bridge(const PrismControl: TPrismControl; + const EventType: TPrismEventType; EventParams: TStrings); +begin + if PrismControl.IsTabs then + if (PrismControl.Name = 'TabControl1') and (EventType = TPrismEventType.EventOnChange) then + begin + Showmessage('Tab ' + IntToStr(PrismControl.AsTabs.ActiveTabIndex) + ' Activate'); + end; +end; + +procedure TFormControls.Upload(AFiles: TStrings; Sender: TObject); +begin + Image_From_Local.Picture.LoadFromFile(AFiles[0]); +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitdbgrid.lfm b/Beta/Demos/Lazarus_linux/unitdbgrid.lfm new file mode 100644 index 0000000..49675af --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitdbgrid.lfm @@ -0,0 +1,101 @@ +object FormDBGrid: TFormDBGrid + Left = 520 + Height = 549 + Top = 170 + Width = 839 + ClientHeight = 549 + ClientWidth = 839 + OnShow = FormShow + LCLVersion = '3.6.0.0' + object DBGrid1: TDBGrid + Left = 16 + Height = 480 + Top = 48 + Width = 808 + Color = clWindow + Columns = < + item + ReadOnly = True + Title.Caption = 'Cod' + FieldName = 'id' + end + item + Title.Caption = 'Country' + Width = 300 + FieldName = 'Country' + end + item + Title.Caption = 'DDI' + Width = 40 + FieldName = 'DDI' + end + item + Title.Caption = 'Population' + Width = 140 + FieldName = 'Population' + end> + DataSource = DataSource1 + Options = [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgRowSelect, dgConfirmDelete, dgCancelOnExit] + TabOrder = 0 + TitleFont.Color = clWindowText + TitleFont.Height = -11 + TitleFont.Name = 'Tahoma' + end + object CheckBox1: TCheckBox + Left = 16 + Height = 19 + Top = 16 + Width = 129 + Caption = 'Enable Edit in DBGrid' + TabOrder = 1 + OnClick = CheckBox1Click + end + object DataSource1: TDataSource + DataSet = BufDataset1 + Left = 592 + Top = 16 + end + object BufDataset1: TBufDataset + FieldDefs = <> + Left = 520 + Top = 16 + object BufDataset1id: TLongintField + FieldKind = fkData + FieldName = 'id' + Index = 0 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1country: TStringField + FieldKind = fkData + FieldName = 'country' + Index = 1 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 100 + end + object BufDataset1ddi: TStringField + FieldKind = fkData + FieldName = 'ddi' + Index = 2 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 10 + end + object BufDataset1population: TLongintField + FieldKind = fkData + FieldName = 'population' + Index = 3 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + end +end diff --git a/Beta/Demos/Lazarus_linux/unitdbgrid.pas b/Beta/Demos/Lazarus_linux/unitdbgrid.pas new file mode 100644 index 0000000..441cc01 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitdbgrid.pas @@ -0,0 +1,233 @@ +unit unitDBGrid; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +interface + +uses + Classes, SysUtils, DB, BufDataset, Controls, Graphics, Dialogs, StdCtrls, + DBGrids, UnitMenu, D2Bridge.Forms; + +type + + { TFormDBGrid } + + TFormDBGrid = class(TD2BridgeForm) + BufDataset1: TBufDataset; + BufDataset1country: TStringField; + BufDataset1ddi: TStringField; + BufDataset1id: TLongintField; + BufDataset1population: TLongintField; + CheckBox1: TCheckBox; + DataSource1: TDataSource; + DBGrid1: TDBGrid; + procedure CheckBox1Click(Sender: TObject); + procedure FormShow(Sender: TObject); + private + procedure PopuleData; + //Simulate Button Insert Click + procedure InsertNewRecClick(Sender: TObject); + public + { Public declarations } + protected + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; var HTMLControl: string); override; + procedure CallBack(const CallBackName: String; EventParams: TStrings); override; + procedure CellButtonClick(APrismDBGrid: TPrismDBGrid; APrismCellButton: TPrismDBGridColumnButton; AColIndex: Integer; ARow: Integer); overload; override; + end; + +function FormDBGrid: TFormDBGrid; + +implementation + +uses + LazarusWebApp, D2BridgeFormTemplate, UnitDBGridEdit; + +{$R *.lfm} + +function FormDBGrid: TFormDBGrid; +begin + result:= (TFormDBGrid.GetInstance as TFormDBGrid); +end; + +procedure TFormDBGrid.FormShow(Sender: TObject); +begin + PopuleData; +end; + +procedure TFormDBGrid.CheckBox1Click(Sender: TObject); +begin + if CheckBox1.Checked then + DBGrid1.Options:= DBGrid1.Options - [dgRowSelect] + [dgEditing] + else + DBGrid1.Options:= DBGrid1.Options - [dgEditing] + [dgRowSelect]; +end; + +procedure TFormDBGrid.PopuleData; +begin + BufDataset1.Close; + BufDataset1.CreateDataset; + + BufDataset1.AppendRecord([1, 'China', '+86', 1444216107]); + BufDataset1.AppendRecord([2, 'India', '+91', 1393409038]); + BufDataset1.AppendRecord([3, 'United States', '+1', 332915073]); + BufDataset1.AppendRecord([4, 'Indonesia', '+62', 276361783]); + BufDataset1.AppendRecord([5, 'Pakistan', '+92', 225199937]); + BufDataset1.AppendRecord([6, 'Brazil', '+55', 213993437]); + BufDataset1.AppendRecord([7, 'Nigeria', '+234', 211400708]); + BufDataset1.AppendRecord([8, 'Bangladesh', '+880', 166303498]); + BufDataset1.AppendRecord([9, 'Russia', '+7', 145912025]); + BufDataset1.AppendRecord([10, 'Mexico', '+52', 130262216]); + BufDataset1.AppendRecord([11, 'Japan', '+81', 125943834]); + BufDataset1.AppendRecord([12, 'Ethiopia', '+251', 120858976]); + BufDataset1.AppendRecord([13, 'Philippines', '+63', 113850055]); + BufDataset1.AppendRecord([14, 'Egypt', '+20', 104258327]); + BufDataset1.AppendRecord([15, 'Vietnam', '+84', 97429061]); + BufDataset1.AppendRecord([16, 'DR Congo', '+243', 90003954]); + BufDataset1.AppendRecord([17, 'Turkey', '+90', 84339067]); + BufDataset1.AppendRecord([18, 'Iran', '+98', 85004578]); + BufDataset1.AppendRecord([19, 'Germany', '+49', 83149300]); + BufDataset1.AppendRecord([20, 'Thailand', '+66', 69950807]); + BufDataset1.AppendRecord([21, 'United Kingdom', '+44', 67886011]); + BufDataset1.AppendRecord([22, 'France', '+33', 65273511]); + BufDataset1.AppendRecord([23, 'Italy', '+39', 60244639]); + BufDataset1.AppendRecord([24, 'South Africa', '+27', 60041932]); + BufDataset1.AppendRecord([25, 'Tanzania', '+255', 59895231]); + BufDataset1.AppendRecord([26, 'Myanmar', '+95', 54409800]); + BufDataset1.AppendRecord([27, 'Kenya', '+254', 53771296]); + BufDataset1.AppendRecord([28, 'South Korea', '+82', 51606633]); + BufDataset1.AppendRecord([29, 'Colombia', '+57', 50976248]); + BufDataset1.AppendRecord([30, 'Spain', '+34', 46754783]); +end; + +procedure TFormDBGrid.InsertNewRecClick(Sender: TObject); +begin + BufDataset1.Append; + + ShowPopup('PopupDBGridEdit'); +end; + +procedure TFormDBGrid.ExportD2Bridge; +begin + inherited; + + Title:= 'DBGrid Example'; + + TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + //Add Form Nested + if FormDBGridEdit = nil then + TFormDBGridEdit.CreateInstance; + D2Bridge.AddNested(FormDBGridEdit); + + with D2Bridge.Items.add do + begin + with Row.Items.Add do + ColAuto.Add.LCLObj(CheckBox1); + + with Row.Items.Add do + LCLObj(DBGrid1); + + with Popup('PopupDBGridEdit', 'Lazarus DBGrid DEMO').Items.Add do + Nested(FormDBGridEdit); + end; +end; + +procedure TFormDBGrid.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + {$REGION 'DBGrid1'} + if PrismControl.VCLComponent = DBGrid1 then + with PrismControl.AsDBGrid do + begin + //HTML with <a> hhtml element and Button and CallBack + with Columns.Add do + begin + ColumnIndex:= 0; + Width:= 30; + Title:= 'Print'; + HTML:= '<a onclick="{{CallBack=CellPrint(recno=${data.PrismRecNo})}}"> <span> <i class="fa fa-print fa-2x fixed-plugin-button-nav cursor-pointer" aria-hidden="false" style="color:SteelBlue" align:"left"> </i> </span> </a>'; + end; + + with Columns.Add do + begin + ColumnIndex:= 1; + Title:= D2Bridge.LangNav.Button.CaptionOptions; + Width:= 80; + + //Create Popup + Button + with Buttons.Add do + begin + ButtonModel:= TButtonModel.Config; + + //New + with Add do + begin + ButtonModel:= TButtonModel.Add; + OnClick:= InsertNewRecClick; //Simulate Button Click + end; + + //Edit + with Add do + begin + ButtonModel:= TButtonModel.Edit; + end; + + //Delete + with Add do + begin + ButtonModel:= TButtonModel.Delete; + end; + end; + end; + end; + {$ENDREGION} +end; + +procedure TFormDBGrid.RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +procedure TFormDBGrid.CallBack(const CallBackName: String; EventParams: TStrings); +begin + if SameText('CellPrint', CallBackName) then + begin + Showmessage('Prin Row ' + EventParams.Values['recno']); + end; +end; + +procedure TFormDBGrid.CellButtonClick(APrismDBGrid: TPrismDBGrid; + APrismCellButton: TPrismDBGridColumnButton; AColIndex: Integer; ARow: Integer); +begin + if APrismDBGrid.VCLComponent = DBGrid1 then + begin + if APrismCellButton.Identify = TButtonModel.Edit.Identity then + begin + ShowPopup('PopupDBGridEdit'); + end; + + if APrismCellButton.Identify = TButtonModel.Delete.Identity then + begin + if MessageDlg('Delete this record?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then + FormDBGrid.BufDataset1.Delete; + end; + end; +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitdbgridedit.lfm b/Beta/Demos/Lazarus_linux/unitdbgridedit.lfm new file mode 100644 index 0000000..f2a19d4 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitdbgridedit.lfm @@ -0,0 +1,94 @@ +object FormDBGridEdit: TFormDBGridEdit + Left = 750 + Height = 192 + Top = 227 + Width = 351 + Caption = 'FormDBGridEdit' + ClientHeight = 192 + ClientWidth = 351 + LCLVersion = '3.6.0.0' + object LabelId: TLabel + Left = 24 + Height = 15 + Top = 16 + Width = 13 + Caption = 'Id:' + end + object DBTextId: TDBText + Left = 56 + Height = 15 + Top = 16 + Width = 45 + DataField = 'id' + DataSource = FormDBGrid.DataSource1 + end + object LabelCountry: TLabel + Left = 24 + Height = 15 + Top = 40 + Width = 46 + Caption = 'Country:' + end + object LabelDDI: TLabel + Left = 24 + Height = 15 + Top = 71 + Width = 22 + Caption = 'DDI:' + end + object LabelPopulation: TLabel + Left = 24 + Height = 15 + Top = 100 + Width = 61 + Caption = 'Population:' + end + object DBEditCountry: TDBEdit + Left = 98 + Height = 23 + Top = 38 + Width = 232 + DataField = 'country' + DataSource = FormDBGrid.DataSource1 + MaxLength = 0 + TabOrder = 0 + end + object DBEditDDI: TDBEdit + Left = 98 + Height = 23 + Top = 66 + Width = 120 + DataField = 'ddi' + DataSource = FormDBGrid.DataSource1 + MaxLength = 0 + TabOrder = 1 + end + object DBEditPopulation: TDBEdit + Left = 98 + Height = 23 + Top = 96 + Width = 120 + DataField = 'population' + DataSource = FormDBGrid.DataSource1 + MaxLength = 0 + TabOrder = 2 + end + object ButtonSave: TButton + Left = 24 + Height = 25 + Top = 144 + Width = 80 + Caption = 'Save' + TabOrder = 3 + OnClick = ButtonSaveClick + end + object ButtonDelete: TButton + Left = 112 + Height = 25 + Top = 144 + Width = 88 + Caption = 'Delete' + TabOrder = 4 + OnClick = ButtonDeleteClick + end +end diff --git a/Beta/Demos/Lazarus_linux/unitdbgridedit.pas b/Beta/Demos/Lazarus_linux/unitdbgridedit.pas new file mode 100644 index 0000000..0beba7e --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitdbgridedit.pas @@ -0,0 +1,156 @@ +unit unitDBGridEdit; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +interface + +uses + Classes, SysUtils, Controls, Graphics, Dialogs, StdCtrls, DBCtrls, + D2Bridge.Forms; + +type + + { TFormDBGridEdit } + + TFormDBGridEdit = class(TD2BridgeForm) + ButtonSave: TButton; + ButtonDelete: TButton; + DBEditCountry: TDBEdit; + DBEditDDI: TDBEdit; + DBEditPopulation: TDBEdit; + DBTextId: TDBText; + LabelId: TLabel; + LabelCountry: TLabel; + LabelDDI: TLabel; + LabelPopulation: TLabel; + procedure ButtonDeleteClick(Sender: TObject); + procedure ButtonSaveClick(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + protected + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); override; + end; + +function FormDBGridEdit: TFormDBGridEdit; + +implementation + +uses + LazarusWebApp, UnitDBGrid; + +{$R *.lfm} + +function FormDBGridEdit: TFormDBGridEdit; +begin + result:= (TFormDBGridEdit.GetInstance as TFormDBGridEdit); +end; + +procedure TFormDBGridEdit.ButtonSaveClick(Sender: TObject); +begin + FormDBGrid.BufDataset1.Edit; + FormDBGrid.BufDataset1.Post; + + Close; +end; + +procedure TFormDBGridEdit.ButtonDeleteClick(Sender: TObject); +begin + if MessageDlg('Delete this record?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then + begin + FormDBGrid.BufDataset1.Delete; + + Close; + end; +end; + +procedure TFormDBGridEdit.ExportD2Bridge; +begin + inherited; + + Title:= 'My D2Bridge Form'; + + //TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + with D2Bridge.Items.add do + begin + //Example use FormGroup + with Row.Items.Add do + FormGroup(LabelId.Caption).AddLCLObj(DBTextId); + + //Example export using full column size + with Row.Items.Add do + with Col12.Items.Add do + begin + LCLObj(LabelCountry); + LCLObj(DBEditCountry); + end; + + //Example export using auto column size + with Row.Items.Add do + with ColAuto.Items.Add do + begin + LCLObj(LabelDDI); + LCLObj(DBEditDDI); + end; + + //Example export using auto column size + with Row.Items.Add do + with ColAuto.Items.Add do + begin + LCLObj(LabelPopulation); + LCLObj(DBEditPopulation); + end; + + //Example export using auto column size + with Row.Items.Add do + begin + ColAuto.Add.LCLObj(ButtonSave, CSSClass.Button.save); + ColAuto.Add.LCLObj(ButtonDelete, CSSClass.Button.delete); + end; + end; + +end; + +procedure TFormDBGridEdit.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + inherited; + + //Change Init Property of Prism Controls + { + if PrismControl.VCLComponent = Edit1 then + PrismControl.AsEdit.DataType:= TPrismFieldType.PrismFieldTypeInteger; + + if PrismControl.IsDBGrid then + begin + PrismControl.AsDBGrid.RecordsPerPage:= 10; + PrismControl.AsDBGrid.MaxRecords:= 2000; + end; + } +end; + +procedure TFormDBGridEdit.RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitkanban.lfm b/Beta/Demos/Lazarus_linux/unitkanban.lfm new file mode 100644 index 0000000..8272a1f --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitkanban.lfm @@ -0,0 +1,47 @@ +object FormKanban: TFormKanban + Left = 614 + Height = 471 + Top = 112 + Width = 568 + Caption = 'FormKanban' + ClientHeight = 471 + ClientWidth = 568 + LCLVersion = '3.6.0.0' + object Panel1: TPanel + Left = 40 + Height = 89 + Top = 32 + Width = 185 + ClientHeight = 89 + ClientWidth = 185 + TabOrder = 0 + object Label_CardStr: TLabel + Left = 16 + Height = 41 + Top = 40 + Width = 153 + AutoSize = False + Caption = 'This Card is item X for Column XYZ' + WordWrap = True + end + object Label_Title: TLabel + Left = 16 + Height = 13 + Top = 8 + Width = 62 + Caption = 'Label_Title' + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentFont = False + end + object Button_Config: TButton + Left = 144 + Height = 25 + Top = 9 + Width = 27 + TabOrder = 0 + end + end +end diff --git a/Beta/Demos/Lazarus_linux/unitkanban.pas b/Beta/Demos/Lazarus_linux/unitkanban.pas new file mode 100644 index 0000000..2835faa --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitkanban.pas @@ -0,0 +1,258 @@ +unit unitKanban; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +interface + +uses + Classes, SysUtils, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, + D2Bridge.Forms; + +type + + { TFormKanban } + + TFormKanban = class(TD2BridgeForm) + Button_Config: TButton; + Label_CardStr: TLabel; + Label_Title: TLabel; + Panel1: TPanel; + private + procedure PopuleKanban(AKanban: IPrismKanban); + procedure KanbanMoveCard(const AKanbanCard: IPrismCardModel; const IsColumnMoved, IsPositionMoved: boolean); override; + procedure KanbanClick(const AKanbanCard: IPrismCardModel; const PrismControlClick: TPrismControl); override; + procedure OnClickAddCard(Sender: TObject); + public + { Public declarations } + protected + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); override; + end; + +function FormKanban: TFormKanban; + +implementation + +uses + LazarusWebApp, D2BridgeFormTemplate; + +{$R *.lfm} + +function FormKanban: TFormKanban; +begin + result:= (TFormKanban.GetInstance as TFormKanban); +end; + +procedure TFormKanban.PopuleKanban(AKanban: IPrismKanban); +var + I: integer; +begin + with AKanban do + begin + //TO DO + with AddColumn do + begin + Title:= 'TO DO'; + Identify:= 'Column1'; + + //Card + for I := 1 to 2 do + with AddCard do + begin + Identify:= KanbanColumn.Title + '_Row'+IntToStr(Row); + Label_Title.Caption:= 'Card of ' + KanbanColumn.Title; + Label_CardStr.Caption:= 'This card is item ' + IntToStr(Row) + ' from column ' + KanbanColumn.Title; + //Mandatory + Initialize; + end; + end; + + + //RUNNING + with AddColumn do + begin + Title:= 'Running'; + Identify:= 'Column2'; + + //Card + for I := 1 to 3 do + with AddCard do + begin + Identify:= KanbanColumn.Title + '_Row'+IntToStr(Row); + Label_Title.Caption:= 'Card of ' + KanbanColumn.Title; + Label_CardStr.Caption:= 'This card is item ' + IntToStr(Row) + ' from column ' + KanbanColumn.Title; + //Mandatory + Initialize; + end; + end; + + + + + //Finished + with AddColumn do + begin + Title:= 'Finished'; + Identify:= 'Column3'; + + //Card + for I := 1 to 5 do + with AddCard do + begin + Identify:= KanbanColumn.Title + '_Row'+IntToStr(Row); + Label_Title.Caption:= 'Card of ' + KanbanColumn.Title; + Label_CardStr.Caption:= 'This card is item ' + IntToStr(Row) + ' from column ' + KanbanColumn.Title; + //Mandatory + Initialize; + end; + end; + end; +end; + +procedure TFormKanban.KanbanMoveCard(const AKanbanCard: IPrismCardModel; + const IsColumnMoved, IsPositionMoved: boolean); +begin + if IsColumnMoved and IsPositionMoved then + begin + Showmessage('Column and position has been moved', true, true); + end else + if IsColumnMoved then + begin + Showmessage('Just Column has been moved', true, true); + end else + if IsPositionMoved then + begin + Showmessage('Just position is moved', true, true); + end; +end; + +procedure TFormKanban.KanbanClick(const AKanbanCard: IPrismCardModel; + const PrismControlClick: TPrismControl); +begin + //MykanbanId := AKanbanCard.Identify; + + if Assigned(PrismControlClick) then + if PrismControlClick.VCLComponent = Button_Config then + begin + Showmessage('Click on Config Button'); + end; +end; + +procedure TFormKanban.OnClickAddCard(Sender: TObject); +var + vKanbanColumn: IPrismKanbanColumn; +begin + if Supports(Sender, IPrismKanbanColumn, vKanbanColumn) then + begin + //vKanbanColumn.Identify .... + + showmessage('Add Card'); + + //Update Kanban and Renderize + //D2Bridge.UpdateD2BridgeControl() + UpdateD2BridgeControls(vKanbanColumn.Kanban as TPrismControl); + end; + +end; + +procedure TFormKanban.ExportD2Bridge; +begin + inherited; + + Title:= 'Kanban Example'; + SubTitle:= 'D2Bridge native Kanban Support'; + + TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + //Export yours Controls + with D2Bridge.Items.add do + begin + with Row.Items.Add do + with Kanban('Kanban1') do + begin + OnAddClick:= @OnClickAddCard; + + //CardModel + with CardModel do + begin + with BodyItems.Add do + begin + with Row.Items.Add do + begin + Col.Add.VCLObj(Label_Title); + ColAuto.Add.VCLObj(Button_Config, CSSClass.Button.config + ' ' + CSSClass.Button.TypeButton.Default.light); + end; + + with Row.Items.Add do + Col.Add.VCLObj(Label_CardStr); + end; + end; + end; + end; +end; + +procedure TFormKanban.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + {$REGION 'Popule Kanban Mode 1'} + if PrismControl.IsKanban then + begin + with PrismControl.AsKanban.AddColumn do + begin + Title:= 'TO DO'; + Identify:= 'Column1'; + AddCadsToInitialize(2); + end; + + with PrismControl.AsKanban.AddColumn do + begin + Title:= 'Running'; + Identify:= 'Column2'; + AddCadsToInitialize(3); + end; + + with PrismControl.AsKanban.AddColumn do + begin + Title:= 'Finished'; + Identify:= 'Column3'; + AddCadsToInitialize(5); + end; + end; + + if PrismControl.IsCardModel then + if PrismControl.AsCardModel.IsKanbanContainer then + with PrismControl.AsCardModel do + begin + Identify:= KanbanColumn.Title + '_Row'+IntToStr(Row); + + Label_Title.Caption:= 'Card of ' + KanbanColumn.Title; + + Label_CardStr.Caption:= 'This card is item ' + IntToStr(Row) + ' from column ' + KanbanColumn.Title; + end; + {$ENDREGION} + + + {$REGION 'Popule Kanban Mode 2'} +// if PrismControl.IsKanban then +// PopuleKanban(PrismControl as IPrismKanban); + {$ENDREGION} +end; + +procedure TFormKanban.RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitmarkdowneditor.lfm b/Beta/Demos/Lazarus_linux/unitmarkdowneditor.lfm new file mode 100644 index 0000000..7d1495e --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitmarkdowneditor.lfm @@ -0,0 +1,130 @@ +object FormMarkDownEditor: TFormMarkDownEditor + Left = 542 + Height = 479 + Top = 188 + Width = 675 + Caption = 'FormMarkDownEditor' + ClientHeight = 479 + ClientWidth = 675 + OnCreate = FormCreate + LCLVersion = '3.8.0.0' + object Memo1: TMemo + Left = 16 + Height = 185 + Top = 57 + Width = 609 + Lines.Strings = ( + '# D2Bridge Framework - Markdown Editor' + '' + 'Markdown is a **lightweight markup language** that is easy to use.' + '' + '## 📌 Key Features' + '- **Bold** → `**bold text**`' + '- *Italics* → `*italic text*`' + '- [Links](https://d2bridge.com.br) → `[Link Text](https://d2bridge.com.br)`' + '- Numbered lists:' + ' 1. First item' + ' 2. Second item' + ' 3. Third item' + '- Bullet point lists:' + ' - Item A' + ' - Item B' + ' - Item C' + '' + '## 🌄 Adding Images' + 'To insert an image:' + '![](https://d2bridge.com.br/images/LogoD2Bridge.png)' + '' + '## 📌 Usage' + 'Use direct with TMemo, TLabel, TEdit, TDBMemo, TDBText and TDBEdit' + '```delphi' + '//Renderize Memo1 content' + 'MarkdownEditor(Memo1);' + '```' + '' + 'Use with Datasource (Dataware mode)' + '```delphi' + '//Renderize Dataware ' + 'MarkdownEditor(DataSource1, ''Text'');' + '```' + ) + TabOrder = 0 + WordWrap = False + end + object DBGrid1: TDBGrid + Left = 16 + Height = 129 + Top = 316 + Width = 272 + Color = clWindow + Columns = < + item + Title.Caption = 'Title' + Width = 150 + FieldName = 'Title' + end> + DataSource = DataSource1 + Options = [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgRowSelect, dgConfirmDelete, dgCancelOnExit] + TabOrder = 1 + TitleFont.Color = clWindowText + TitleFont.Height = -11 + TitleFont.Name = 'Tahoma' + end + object Button1: TButton + Left = 16 + Height = 25 + Top = 28 + Width = 122 + Caption = 'Enable/Disable Editor' + TabOrder = 2 + OnClick = Button1Click + end + object Button2: TButton + Left = 144 + Height = 25 + Top = 28 + Width = 89 + Caption = 'Edit/ReadOnly' + TabOrder = 3 + OnClick = Button2Click + end + object Button3: TButton + Left = 16 + Height = 25 + Top = 285 + Width = 122 + Caption = 'Enable/Disable Editor' + TabOrder = 4 + OnClick = Button3Click + end + object DataSource1: TDataSource + DataSet = BufDataset1 + Left = 600 + Top = 14 + end + object BufDataset1: TBufDataset + FieldDefs = <> + Left = 532 + Top = 14 + object BufDataset1Title: TStringField + FieldKind = fkData + FieldName = 'Title' + Index = 0 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 100 + end + object BufDataset1Text: TStringField + FieldKind = fkData + FieldName = 'Text' + Index = 1 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 2000 + end + end +end diff --git a/Beta/Demos/Lazarus_linux/unitmarkdowneditor.pas b/Beta/Demos/Lazarus_linux/unitmarkdowneditor.pas new file mode 100644 index 0000000..9004ef3 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitmarkdowneditor.pas @@ -0,0 +1,190 @@ +unit UnitMarkDownEditor; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +interface + +uses + Classes, SysUtils, BufDataset, DB, Controls, Graphics, Dialogs, StdCtrls, DBGrids, Menus, + D2Bridge.Forms; + +type + + { TFormMarkDownEditor } + + TFormMarkDownEditor = class(TD2BridgeForm) + BufDataset1: TBufDataset; + BufDataset1Text: TStringField; + BufDataset1Title: TStringField; + Button1: TButton; + Button2: TButton; + Button3: TButton; + DataSource1: TDataSource; + DBGrid1: TDBGrid; + Memo1: TMemo; + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + procedure FormCreate(Sender: TObject); + private + procedure PopuleData; + public + { Public declarations } + protected + procedure Upload(AFiles: TStrings; Sender: TObject); override; + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; var HTMLControl: string); override; + end; + +function FormMarkDownEditor: TFormMarkDownEditor; + +implementation + +uses + LazarusWebApp, D2BridgeFormTemplate; + +{$R *.lfm} + +function FormMarkDownEditor: TFormMarkDownEditor; +begin + result:= (TFormMarkDownEditor.GetInstance as TFormMarkDownEditor); +end; + +procedure TFormMarkDownEditor.Button1Click(Sender: TObject); +begin + Memo1.Enabled:= not Memo1.Enabled; +end; + +procedure TFormMarkDownEditor.Button2Click(Sender: TObject); +begin + Memo1.ReadOnly:= not Memo1.ReadOnly; +end; + +procedure TFormMarkDownEditor.Button3Click(Sender: TObject); +begin + if BufDataset1.State in [dsEdit] then + BufDataset1.Post + else + BufDataset1.Edit; +end; + +procedure TFormMarkDownEditor.FormCreate(Sender: TObject); +begin + PopuleData; +end; + +procedure TFormMarkDownEditor.PopuleData; +begin + BufDataset1.Close; + BufDataset1.CreateDataSet; + + BufDataset1.AppendRecord(['Example 1', + '# D2Bridge Markdown Editor Documentation ' + sLineBreak + + ' ' + sLineBreak + + 'Welcome to the official documentation for the **D2Bridge Markdown Editor**. ' + sLineBreak + + ' ' + sLineBreak + + '## Installation ' + sLineBreak + + '1. **Download D2Bridge** from the official website. ' + sLineBreak + + '2. **Use InstallD2BridgeWizard.exe to install Wizard in your Delphi/Lazarus IDE** ' + sLineBreak + + '3. **In your IDE use Menu D2Bridge Wizard** ' + ]); + + BufDataset1.AppendRecord(['Example 2', + '# D2Bridge Markdown Editor Documentation' + sLineBreak + + ' ' + sLineBreak + + ' ' + sLineBreak + + '| Column 1 | Column 2 | Column 3 | ' + sLineBreak + + '| -------- | -------- | -------- | ' + sLineBreak + + '| Text | Text | Text | ' + ]); + +end; + +procedure TFormMarkDownEditor.Upload(AFiles: TStrings; Sender: TObject); +begin + //Handle the attachment here + + //Ex: + // AFiles[0]:= 'NewLocation\NameFile.jpg'; +end; + +procedure TFormMarkDownEditor.ExportD2Bridge; +begin + inherited; + + Title:= 'My D2Bridge Form'; + + TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + with D2Bridge.Items.add do + begin + with Row.Items.Add do + with Col.Add.Card('Markdown Editor').Items.Add do + begin + with Row.Items.Add do + begin + ColAuto.Add.VCLObj(Button1); + ColAuto.Add.VCLObj(Button2); + end; + + with Row.Items.Add do + Col.Add.MarkdownEditor(Memo1); + end; + + //Markdown with TMemo + with Row.Items.Add do + with Col.Add.Card('Markdown Editor with Database').Items.Add do + begin + with Row.Items.Add do + ColAuto.Add.VCLObj(Button3); + + with Row.Items.Add do + begin + Col4.Add.VCLObj(DBGrid1); + with Col.Add.MarkdownEditor(DataSource1, 'Text') do + begin + //Personalize your Markdown + ShowButtonStrikethrough:= false; + ShowButtonUpload:= false; + //Show...... + end; + end; + end; + end; + +end; + +procedure TFormMarkDownEditor.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + inherited; + + //Change Init Property of Prism Controls + { + if PrismControl.VCLComponent = Edit1 then + PrismControl.AsEdit.DataType:= TPrismFieldType.PrismFieldTypeInteger; + + if PrismControl.IsDBGrid then + begin + PrismControl.AsDBGrid.RecordsPerPage:= 10; + PrismControl.AsDBGrid.MaxRecords:= 2000; + end; + } +end; + +procedure TFormMarkDownEditor.RenderD2Bridge(const PrismControl: TPrismControl; var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitqrcode.lfm b/Beta/Demos/Lazarus_linux/unitqrcode.lfm new file mode 100644 index 0000000..f4a1c03 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitqrcode.lfm @@ -0,0 +1,254 @@ +object FormQRCode: TFormQRCode + Left = 536 + Height = 591 + Top = 193 + Width = 679 + Caption = 'FormQRCode' + ClientHeight = 591 + ClientWidth = 679 + OnCreate = FormCreate + OnShow = FormShow + LCLVersion = '3.6.0.0' + object GroupBox1: TGroupBox + Left = 16 + Height = 169 + Top = 8 + Width = 633 + Caption = 'VCL and WEB' + ClientHeight = 149 + ClientWidth = 629 + TabOrder = 0 + object Image1: TImage + Left = 496 + Height = 105 + Top = 24 + Width = 121 + Proportional = True + end + object Edit1: TEdit + Left = 16 + Height = 23 + Top = 24 + Width = 369 + TabOrder = 0 + Text = 'https://www.d2bridge.com.br' + end + object Button1: TButton + Left = 391 + Height = 25 + Top = 22 + Width = 75 + Caption = 'QRCode' + TabOrder = 1 + OnClick = Button1Click + end + end + object GroupBox2: TGroupBox + Left = 16 + Height = 74 + Top = 183 + Width = 633 + Caption = 'WEB Static' + ClientHeight = 54 + ClientWidth = 629 + TabOrder = 1 + object Edit2: TEdit + Left = 16 + Height = 23 + Top = 24 + Width = 601 + Enabled = False + TabOrder = 0 + Text = 'https://www.d2bridge.com.br' + end + end + object GroupBox3: TGroupBox + Left = 16 + Height = 80 + Top = 272 + Width = 633 + Caption = 'Web Dynamic' + ClientHeight = 60 + ClientWidth = 629 + TabOrder = 2 + object Edit3: TEdit + Left = 16 + Height = 23 + Top = 24 + Width = 520 + TabOrder = 0 + Text = 'https://www.d2bridge.com.br' + end + object Button2: TButton + Left = 542 + Height = 25 + Top = 22 + Width = 75 + Caption = 'QRCode' + TabOrder = 1 + OnClick = Button2Click + end + end + object GroupBox5: TGroupBox + Left = 16 + Height = 212 + Top = 360 + Width = 633 + Caption = 'Web Dataware' + ClientHeight = 192 + ClientWidth = 629 + TabOrder = 3 + object DBGrid1: TDBGrid + Left = 16 + Height = 153 + Top = 24 + Width = 601 + Color = clWindow + Columns = < + item + Title.Caption = 'Id' + FieldName = 'AutoCod' + end + item + Title.Caption = 'Country' + Width = 100 + FieldName = 'Country' + end + item + Title.Caption = 'Continent' + Width = 80 + FieldName = 'Continent' + end + item + Title.Caption = 'City' + Width = 80 + FieldName = 'Capital' + end + item + Title.Caption = 'Population' + Width = 65 + FieldName = 'Population' + end + item + Title.Caption = 'Language' + Width = 70 + FieldName = 'Language' + end + item + Title.Caption = 'Currency Name' + Width = 90 + FieldName = 'CurrencyName' + end> + DataSource = DataSource1 + Options = [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgRowSelect, dgConfirmDelete, dgCancelOnExit] + TabOrder = 0 + TitleFont.Color = clWindowText + TitleFont.Height = -11 + TitleFont.Name = 'Tahoma' + end + end + object BufDataset1: TBufDataset + FieldDefs = <> + Left = 328 + Top = 464 + object BufDataset1id: TLongintField + FieldKind = fkData + FieldName = 'id' + Index = 0 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1country: TStringField + FieldKind = fkData + FieldName = 'country' + Index = 1 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 100 + end + object BufDataset1ddi: TStringField + FieldKind = fkData + FieldName = 'ddi' + Index = 2 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 10 + end + object BufDataset1population: TLongintField + FieldKind = fkData + FieldName = 'population' + Index = 3 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1Continent: TStringField + FieldKind = fkData + FieldName = 'Continent' + Index = 4 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 30 + end + object BufDataset1Language: TStringField + FieldKind = fkData + FieldName = 'Language' + Index = 5 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1Capital: TStringField + FieldKind = fkData + FieldName = 'Capital' + Index = 6 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1CurrencyName: TStringField + FieldKind = fkData + FieldName = 'CurrencyName' + Index = 7 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1CurrencySimbol: TStringField + FieldKind = fkData + FieldName = 'CurrencySimbol' + Index = 8 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 5 + end + object BufDataset1CreateAt: TDateField + FieldKind = fkData + FieldName = 'CreateAt' + Index = 9 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + end + object DataSource1: TDataSource + DataSet = BufDataset1 + Left = 400 + Top = 464 + end +end diff --git a/Beta/Demos/Lazarus_linux/unitqrcode.pas b/Beta/Demos/Lazarus_linux/unitqrcode.pas new file mode 100644 index 0000000..2f55c91 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitqrcode.pas @@ -0,0 +1,243 @@ +unit unitQRCode; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +interface + +uses + Classes, SysUtils, BufDataset, DB, Controls, Graphics, Dialogs, StdCtrls, DBGrids, ExtCtrls, + D2Bridge.API.QRCode, D2Bridge.Forms; + +type + + { TFormQRCode } + + TFormQRCode = class(TD2BridgeForm) + BufDataset1: TBufDataset; + BufDataset1Capital: TStringField; + BufDataset1Continent: TStringField; + BufDataset1country: TStringField; + BufDataset1CreateAt: TDateField; + BufDataset1CurrencyName: TStringField; + BufDataset1CurrencySimbol: TStringField; + BufDataset1ddi: TStringField; + BufDataset1id: TLongintField; + BufDataset1Language: TStringField; + BufDataset1population: TLongintField; + Button1: TButton; + Button2: TButton; + DataSource1: TDataSource; + DBGrid1: TDBGrid; + Edit1: TEdit; + Edit2: TEdit; + Edit3: TEdit; + GroupBox1: TGroupBox; + GroupBox2: TGroupBox; + GroupBox3: TGroupBox; + GroupBox5: TGroupBox; + Image1: TImage; + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + private + FD2BridgeAPIQRCode: TD2BridgeAPIQRCode; + Procedure PopuleData; + public + { Public declarations } + protected + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); override; + end; + +function FormQRCode: TFormQRCode; + +implementation + +uses + LazarusWebApp, D2BridgeFormTemplate; + +{$R *.lfm} + +function FormQRCode: TFormQRCode; +begin + result:= (TFormQRCode.GetInstance as TFormQRCode); +end; + +procedure TFormQRCode.FormCreate(Sender: TObject); +begin + FD2BridgeAPIQRCode:= TD2BridgeAPIQRCode.Create; +end; + +procedure TFormQRCode.Button1Click(Sender: TObject); +begin + FD2BridgeAPIQRCode.Text:= Edit1.Text; + Image1.Picture.Assign(FD2BridgeAPIQRCode.QRCodeJPG); + +end; + +procedure TFormQRCode.Button2Click(Sender: TObject); +begin + if IsD2BridgeContext then + D2Bridge.PrismControlFromID('QRCodeDynamic').AsQRCode.Text:= Edit3.Text + else + Showmessage('Just D2Bridge Web'); +end; + +procedure TFormQRCode.FormShow(Sender: TObject); +begin + PopuleData; +end; + +procedure TFormQRCode.PopuleData; +begin + BufDataset1.Close; + BufDataset1.CreateDataset; + + BufDataset1.AppendRecord([1, 'China', '86', 1444216107, 'Asia', 'Mandarin', 'Beijing', 'Yuan', 'Â¥']); + BufDataset1.AppendRecord([2, 'India', '91', 1393409038, 'Asia', 'Hindi, English', 'New Delhi', 'Rupee', '₹']); + BufDataset1.AppendRecord([3, 'United States', '1', 332915073, 'North America', 'English', 'Washington, D.C.', 'Dollar', '$']); + BufDataset1.AppendRecord([4, 'Indonesia', '62', 276361783, 'Asia', 'Indonesian', 'Jakarta', 'Rupiah', 'Rp']); + BufDataset1.AppendRecord([5, 'Pakistan', '92', 225199937, 'Asia', 'Urdu, English', 'Islamabad', 'Rupee', '₨']); + BufDataset1.AppendRecord([6, 'Brazil', '55', 213993437, 'South America', 'Portuguese', 'Brasília', 'Real', 'R$']); + BufDataset1.AppendRecord([7, 'Nigeria', '234', 211400708, 'Africa', 'English', 'Abuja', 'Naira', '₦']); + BufDataset1.AppendRecord([8, 'Bangladesh', '880', 166303498, 'Asia', 'Bengali', 'Dhaka', 'Taka', 'à§³']); + BufDataset1.AppendRecord([9, 'Russia', '7', 145912025, 'Europe/Asia', 'Russian', 'Moscow', 'Ruble', '₽']); + BufDataset1.AppendRecord([10, 'Mexico', '52', 130262216, 'North America', 'Spanish', 'Mexico City', 'Peso', '$']); + BufDataset1.AppendRecord([11, 'Japan', '81', 125943834, 'Asia', 'Japanese', 'Tokyo', 'Yen', 'Â¥']); + BufDataset1.AppendRecord([12, 'Ethiopia', '251', 120858976, 'Africa', 'Amharic', 'Addis Ababa', 'Birr', 'Br']); + BufDataset1.AppendRecord([13, 'Philippines', '63', 113850055, 'Asia', 'Filipino, English', 'Manila', 'Peso', '₱']); + BufDataset1.AppendRecord([14, 'Egypt', '20', 104258327, 'Africa', 'Arabic', 'Cairo', 'Pound', '£']); + BufDataset1.AppendRecord([15, 'Vietnam', '84', 97429061, 'Asia', 'Vietnamese', 'Hanoi', 'Dong', 'â‚«']); + BufDataset1.AppendRecord([16, 'DR Congo', '243', 90003954, 'Africa', 'French', 'Kinshasa', 'Franc', 'FC']); + BufDataset1.AppendRecord([17, 'Turkey', '90', 84339067, 'Europe/Asia', 'Turkish', 'Ankara', 'Lira', '₺']); + BufDataset1.AppendRecord([18, 'Iran', '98', 85004578, 'Asia', 'Persian', 'Tehran', 'Rial', 'ï·¼']); + BufDataset1.AppendRecord([19, 'Germany', '49', 83149300, 'Europe', 'German', 'Berlin', 'Euro', '€']); + BufDataset1.AppendRecord([20, 'Thailand', '66', 69950807, 'Asia', 'Thai', 'Bangkok', 'Baht', '฿']); + BufDataset1.AppendRecord([21, 'United Kingdom', '44', 67886011, 'Europe', 'English', 'London', 'Pound', '£']); + BufDataset1.AppendRecord([22, 'France', '33', 65273511, 'Europe', 'French', 'Paris', 'Euro', '€']); + BufDataset1.AppendRecord([23, 'Italy', '39', 60244639, 'Europe', 'Italian', 'Rome', 'Euro', '€']); + BufDataset1.AppendRecord([24, 'South Africa', '27', 60041932, 'Africa', 'Zulu, Xhosa, Afrikaans, English', 'Pretoria', 'Rand', 'R']); + BufDataset1.AppendRecord([25, 'Tanzania', '255', 59895231, 'Africa', 'Swahili, English', 'Dodoma', 'Shilling', 'TSh']); + BufDataset1.AppendRecord([26, 'Myanmar', '95', 54409800, 'Asia', 'Burmese', 'Naypyidaw', 'Kyat', 'K']); + BufDataset1.AppendRecord([27, 'Kenya', '254', 53771296, 'Africa', 'Swahili, English', 'Nairobi', 'Shilling', 'KSh']); + BufDataset1.AppendRecord([28, 'South Korea', '82', 51606633, 'Asia', 'Korean', 'Seoul', 'Won', 'â‚©']); + BufDataset1.AppendRecord([29, 'Colombia', '57', 50976248, 'South America', 'Spanish', 'Bogotá', 'Peso', '$']); + BufDataset1.AppendRecord([30, 'Spain', '34', 46754783, 'Europe', 'Spanish', 'Madrid', 'Euro', '€']); +end; + +procedure TFormQRCode.ExportD2Bridge; +begin + inherited; + + Title:= 'QRCode Example'; + SubTitle:= 'D2Bridge Native QRCode generation'; + + TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + //Export yours Controls + with D2Bridge.Items.add do + begin + with row.Items.Add do + begin + with HTMLDiv(CSSClass.Col.col).Items.Add do + with CardGrid do + begin + //ColSize:= 'row-cols-md-1 row-cols-lg-1'; + CardGridSize:= CSSClass.CardGrid.CardGridX2; + EqualHeight:= true; + + //VCL and WEB + with AddCard(GroupBox1.Caption).Items.Add do + begin + with Row.Items.Add do + begin + with HTMLDiv(CSSClass.Col.colsize8).Items.Add do + with Row.Items.Add do + begin + FormGroup('', CSSClass.Col.col).AddVCLObj(Edit1); + FormGroup.AddVCLObj(Button1); + end; + + with HTMLDiv(CSSClass.Col.colsize4).Items.Add do + VCLObj(Image1); + end; + end; + + //VCL Static + with AddCard(GroupBox2.Caption).Items.Add do + begin + with Row.Items.Add do + begin + with HTMLDiv(CSSClass.Col.colsize8).Items.Add do + with Row.Items.Add do + FormGroup('', CSSClass.Col.col).AddVCLObj(Edit2); + + with HTMLDiv(CSSClass.Col.colsize4).Items.Add do + QRCode(Edit2.Text); + end; + end; + + //WEB Dynamic + with AddCard(GroupBox3.Caption).Items.Add do + begin + with Row.Items.Add do + begin + with HTMLDiv(CSSClass.Col.colsize8).Items.Add do + with Row.Items.Add do + begin + FormGroup('', CSSClass.Col.col).AddVCLObj(Edit3); + FormGroup.AddVCLObj(Button2); + end; + + with HTMLDiv(CSSClass.Col.colsize4).Items.Add do + QRCode(Edit3.Text, 'QRCodeDynamic'); + end; + end; + end; + end; + + //Web Dataware + with Row.Items.Add do + with HTMLDiv(CSSClass.Col.col).Items.Add do + with Card(GroupBox5.Caption).Items.Add do + begin + with Row.Items.Add do + begin + with HTMLDiv(CSSClass.Col.colsize10).Items.Add do + VCLObj(DBGrid1); + + with HTMLDiv(CSSClass.Col.colsize2).Items.Add do + QRCode(DataSource1, 'Country'); + end; + end; + end; +end; + +procedure TFormQRCode.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + if PrismControl.IsDBGrid then + begin + PrismControl.AsDBGrid.RecordsPerPage:= 5; + end; +end; + +procedure TFormQRCode.RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitqrcodereader.lfm b/Beta/Demos/Lazarus_linux/unitqrcodereader.lfm new file mode 100644 index 0000000..6bd8a3e --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitqrcodereader.lfm @@ -0,0 +1,69 @@ +object FormQRCodeReader: TFormQRCodeReader + Left = 374 + Height = 543 + Top = 292 + Width = 718 + Caption = 'FormQRCodeReader' + ClientHeight = 543 + ClientWidth = 718 + OnCreate = FormCreate + LCLVersion = '3.8.0.0' + object Image1: TImage + Left = 184 + Height = 281 + Top = 24 + Width = 305 + end + object ComboBox1: TComboBox + Left = 184 + Height = 23 + Top = 320 + Width = 305 + ItemHeight = 15 + Style = csDropDownList + TabOrder = 0 + end + object Button8: TButton + Left = 495 + Height = 25 + Top = 318 + Width = 34 + TabOrder = 1 + OnClick = Button8Click + end + object Button7: TButton + Left = 218 + Height = 25 + Top = 347 + Width = 75 + Caption = 'Permission' + TabOrder = 2 + OnClick = Button7Click + end + object Button1: TButton + Left = 299 + Height = 25 + Top = 347 + Width = 75 + Caption = 'Start' + TabOrder = 3 + OnClick = Button1Click + end + object Button2: TButton + Left = 379 + Height = 25 + Top = 347 + Width = 75 + Caption = 'Stop' + TabOrder = 4 + OnClick = Button2Click + end + object Memo1: TMemo + Left = 88 + Height = 121 + Top = 384 + Width = 545 + ReadOnly = True + TabOrder = 5 + end +end diff --git a/Beta/Demos/Lazarus_linux/unitqrcodereader.pas b/Beta/Demos/Lazarus_linux/unitqrcodereader.pas new file mode 100644 index 0000000..579b77c --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitqrcodereader.pas @@ -0,0 +1,239 @@ +unit unitQRCodeReader; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +interface + +uses + Classes, SysUtils, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, + D2Bridge.Forms; + +type + + { TFormQRCodeReader } + + TFormQRCodeReader = class(TD2BridgeForm) + Button1: TButton; + Button2: TButton; + Button7: TButton; + Button8: TButton; + ComboBox1: TComboBox; + Image1: TImage; + Memo1: TMemo; + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure Button7Click(Sender: TObject); + procedure Button8Click(Sender: TObject); + procedure FormCreate(Sender: TObject); + private + procedure UpdateCameraList(Sender: TObject); + procedure OnQRCodeReader(ACode: string); + public + { Public declarations } + protected + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); override; + end; + +function FormQRCodeReader: TFormQRCodeReader; + +implementation + +uses + LazarusWebApp, D2BridgeFormTemplate; + +{$R *.lfm} + +function FormQRCodeReader: TFormQRCodeReader; +begin + result:= (TFormQRCodeReader.GetInstance as TFormQRCodeReader); +end; + +procedure TFormQRCodeReader.FormCreate(Sender: TObject); +begin + Image1.QRCodeReader.OnChangeDevices:= UpdateCameraList; +end; + +procedure TFormQRCodeReader.Button7Click(Sender: TObject); +begin + Image1.QRCodeReader.RequestPermission; +end; + +procedure TFormQRCodeReader.Button8Click(Sender: TObject); +begin + if ComboBox1.Items.Count > 0 then + begin + Image1.QRCodeReader.CurrentDevice:= Image1.QRCodeReader.Devices.ItemFromIndex(ComboBox1.ItemIndex); + + //ShowMessage('new camera "' + Image1.QRCodeReader.CurrentDevice.Name + '" selected'); + + //Modify QRCodeReader now + if Image1.QRCodeReader.Started then + begin + Image1.QRCodeReader.Stop; + Image1.QRCodeReader.Start; + end; + end; +end; + +procedure TFormQRCodeReader.Button1Click(Sender: TObject); +begin + Memo1.Text:= ''; + + if not Image1.QRCodeReader.Allowed then + Image1.QRCodeReader.RequestPermission; + + Image1.QRCodeReader.Start; + +end; + +procedure TFormQRCodeReader.Button2Click(Sender: TObject); +begin + Image1.QRCodeReader.Stop; +end; + +procedure TFormQRCodeReader.UpdateCameraList(Sender: TObject); +var + I: Integer; +begin + ComboBox1.Items.Clear; + + if Image1.QRCodeReader.Devices.Count > 0 then + begin + for I := 0 to Pred(Image1.QRCodeReader.Devices.Count) do + ComboBox1.Items.Add(Image1.QRCodeReader.Devices.Items[I].Name); + + ComboBox1.ItemIndex:= Image1.QRCodeReader.CurrentDeviceIndex; + end; +end; + +procedure TFormQRCodeReader.OnQRCodeReader(ACode: string); +begin + Memo1.Text:= ACode; +end; + +procedure TFormQRCodeReader.ExportD2Bridge; +begin + inherited; + + Title:= 'QRCode/BarCode Reader'; + + TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + with D2Bridge.Items.add do + begin + with Row(CSSClass.Col.Align.center).Items.Add do + begin + Col4.Add.QRCodeReader(Image1, Memo1); + //*****Or use Event + //Col4.Add.QRCodeReader(Image1, OnQRCodeReader) + + { + *** Options Example *** + + With Col4.Add.QRCodeReader(Image1, OnQRCodeReader) do + begin + //--> Shaders code limit + BorderShaders:= true/false; + + //--> Scan not stop on Read + ContinuousScan:= true/false; + + //--> Send ENTER on Read the code + PressReturnKey:= true/false; + + //--> Enable All Code Format + EnableAllCodesFormat; + + //--> Disable All Code Format + DisableAllCodesFormat; + + //--> Enable / Disable Code Types + PressReturnKey:= true/false; + TextVCLComponent:= true/false; + EnableQRCODE:= true/false; + EnableAZTEC:= true/false; + EnableCODABAR:= true/false; + EnableCODE39:= true/false; + EnableCODE93:= true/false; + EnableCODE128:= true/false; + EnableDATAMATRIX:= true/false; + EnableMAXICODE:= true/false; + EnableITF:= true/false; + EnableEAN13:= true/false; + EnableEAN8:= true/false; + EnablePDF417:= true/false; + EnableRSS14:= true/false; + EnableRSSEXPANDED:= true/false; + EnableUPCA:= true/false; + EnableUPCE:= true/false; + EnableUPCEANEXTENSION:= true/false; + end; + } + end; + + with Row(CSSClass.Col.Align.center).Items.Add do + begin + with ColAuto.Items.Add do + begin + VCLObj(ComboBox1); + VCLObj(Button8, CSSClass.Button.select); + end; + end; + + with Row(CSSClass.Col.Align.center).Items.Add do + begin + with ColAuto.Items.Add do + begin + VCLObj(Button7, CSSClass.Button.userSecurity); + VCLObj(Button1, CSSClass.Button.start); + VCLObj(Button2, CSSClass.Button.stop); + end; + end; + + with Row(CSSClass.Col.Align.center).Items.Add do + FormGroup('Last Code Read', CSSClass.Col.colsize8).AddVCLObj(Memo1); + end; + +end; + +procedure TFormQRCodeReader.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + inherited; + + //Change Init Property of Prism Controls + { + if PrismControl.VCLComponent = Edit1 then + PrismControl.AsEdit.DataType:= TPrismFieldType.PrismFieldTypeInteger; + + if PrismControl.IsDBGrid then + begin + PrismControl.AsDBGrid.RecordsPerPage:= 10; + PrismControl.AsDBGrid.MaxRecords:= 2000; + end; + } +end; + +procedure TFormQRCodeReader.RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitstringgrid.lfm b/Beta/Demos/Lazarus_linux/unitstringgrid.lfm new file mode 100644 index 0000000..ce338c1 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitstringgrid.lfm @@ -0,0 +1,62 @@ +object FormStringGrid: TFormStringGrid + Left = 485 + Height = 556 + Top = 217 + Width = 759 + Caption = 'FormStringGrid' + ClientHeight = 556 + ClientWidth = 759 + OnCreate = FormCreate + OnShow = FormShow + LCLVersion = '3.6.0.0' + object StringGrid1: TStringGrid + Left = 16 + Height = 392 + Top = 24 + Width = 720 + TabOrder = 0 + end + object BufDataset1: TBufDataset + FieldDefs = <> + Left = 432 + Top = 16 + object BufDataset1id: TLongintField + FieldKind = fkData + FieldName = 'id' + Index = 0 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + object BufDataset1country: TStringField + FieldKind = fkData + FieldName = 'country' + Index = 1 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 100 + end + object BufDataset1ddi: TStringField + FieldKind = fkData + FieldName = 'ddi' + Index = 2 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 10 + end + object BufDataset1population: TLongintField + FieldKind = fkData + FieldName = 'population' + Index = 3 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + end + end +end diff --git a/Beta/Demos/Lazarus_linux/unitstringgrid.pas b/Beta/Demos/Lazarus_linux/unitstringgrid.pas new file mode 100644 index 0000000..3d54455 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitstringgrid.pas @@ -0,0 +1,179 @@ +unit unitStringGrid; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +interface + +uses + Classes, SysUtils, BufDataset, DB, Controls, Graphics, Dialogs, StdCtrls, + Grids, D2Bridge.Forms; + +type + + { TFormStringGrid } + + TFormStringGrid = class(TD2BridgeForm) + BufDataset1: TBufDataset; + BufDataset1country: TStringField; + BufDataset1ddi: TStringField; + BufDataset1id: TLongintField; + BufDataset1population: TLongintField; + StringGrid1: TStringGrid; + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + private + procedure PopuleData; + procedure PopuleStringGrid; + public + { Public declarations } + protected + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); override; + end; + +function FormStringGrid: TFormStringGrid; + +implementation + +uses + LazarusWebApp, D2BridgeFormTemplate; + +{$R *.lfm} + +function FormStringGrid: TFormStringGrid; +begin + result:= (TFormStringGrid.GetInstance as TFormStringGrid); +end; + +procedure TFormStringGrid.FormShow(Sender: TObject); +begin + +end; + +procedure TFormStringGrid.FormCreate(Sender: TObject); +begin + PopuleStringGrid; +end; + +procedure TFormStringGrid.PopuleData; +begin + BufDataset1.Close; + BufDataset1.CreateDataset; + + BufDataset1.AppendRecord([1, 'China', '+86', 1444216107]); + BufDataset1.AppendRecord([2, 'India', '+91', 1393409038]); + BufDataset1.AppendRecord([3, 'United States', '+1', 332915073]); + BufDataset1.AppendRecord([4, 'Indonesia', '+62', 276361783]); + BufDataset1.AppendRecord([5, 'Pakistan', '+92', 225199937]); + BufDataset1.AppendRecord([6, 'Brazil', '+55', 213993437]); + BufDataset1.AppendRecord([7, 'Nigeria', '+234', 211400708]); + BufDataset1.AppendRecord([8, 'Bangladesh', '+880', 166303498]); + BufDataset1.AppendRecord([9, 'Russia', '+7', 145912025]); + BufDataset1.AppendRecord([10, 'Mexico', '+52', 130262216]); + BufDataset1.AppendRecord([11, 'Japan', '+81', 125943834]); + BufDataset1.AppendRecord([12, 'Ethiopia', '+251', 120858976]); + BufDataset1.AppendRecord([13, 'Philippines', '+63', 113850055]); + BufDataset1.AppendRecord([14, 'Egypt', '+20', 104258327]); + BufDataset1.AppendRecord([15, 'Vietnam', '+84', 97429061]); + BufDataset1.AppendRecord([16, 'DR Congo', '+243', 90003954]); + BufDataset1.AppendRecord([17, 'Turkey', '+90', 84339067]); + BufDataset1.AppendRecord([18, 'Iran', '+98', 85004578]); + BufDataset1.AppendRecord([19, 'Germany', '+49', 83149300]); + BufDataset1.AppendRecord([20, 'Thailand', '+66', 69950807]); + BufDataset1.AppendRecord([21, 'United Kingdom', '+44', 67886011]); + BufDataset1.AppendRecord([22, 'France', '+33', 65273511]); + BufDataset1.AppendRecord([23, 'Italy', '+39', 60244639]); + BufDataset1.AppendRecord([24, 'South Africa', '+27', 60041932]); + BufDataset1.AppendRecord([25, 'Tanzania', '+255', 59895231]); + BufDataset1.AppendRecord([26, 'Myanmar', '+95', 54409800]); + BufDataset1.AppendRecord([27, 'Kenya', '+254', 53771296]); + BufDataset1.AppendRecord([28, 'South Korea', '+82', 51606633]); + BufDataset1.AppendRecord([29, 'Colombia', '+57', 50976248]); + BufDataset1.AppendRecord([30, 'Spain', '+34', 46754783]); +end; + +procedure TFormStringGrid.PopuleStringGrid; +var + I, N: integer; + nLinha: Integer; +begin + PopuleData; + + { Informa configuração da StringGrid } + StringGrid1.ColCount:= BufDataset1.FieldCount; + StringGrid1.RowCount:= BufDataset1.RecordCount + 1; + + { Altura de cada célula } + StringGrid1.DefaultRowHeight:= 18; + + { Monta coluna da StringGrid } + for I:= 0 to BufDataset1.FieldCount - 1 do + begin + StringGrid1.Cells[I, 0]:= BufDataset1.Fields[I].DisplayLabel; + + { comprimento em pixels da coluna} + StringGrid1.ColWidths[I]:= BufDataset1.Fields[I].DisplayWidth * 3; + end; + + { Prenche StringGrid } + nLinha:= 0; + + BufDataset1.First; + while not BufDataset1.Eof do + begin + Inc(nLinha); + + for N:= 0 to BufDataset1.FieldCount - 1 do + StringGrid1.Cells[N, nLinha]:= BufDataset1.FieldByName(BufDataset1.Fields[N].DisplayLabel).Text; + + BufDataset1.Next; + end; +end; + +procedure TFormStringGrid.ExportD2Bridge; +begin + inherited; + + Title:= 'String Grid Example'; + SubTitle:= 'Below is a StringGrid populated with data about countries'; + + TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + with D2Bridge.Items.add do + begin + LCLObj(StringGrid1); + end; + +end; + +procedure TFormStringGrid.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + inherited; + + //Change Init Property of Prism Controls + if PrismControl.IsStringGrid then + begin + PrismControl.AsStringGrid.RecordsPerPage:= 20; + PrismControl.AsStringGrid.MaxRecords:= 2000; + end; +end; + +procedure TFormStringGrid.RenderD2Bridge(const PrismControl: TPrismControl; + var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/unitwysiwygeditor.lfm b/Beta/Demos/Lazarus_linux/unitwysiwygeditor.lfm new file mode 100644 index 0000000..d25b26d --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitwysiwygeditor.lfm @@ -0,0 +1,114 @@ +object FormWYSIWYGEditor: TFormWYSIWYGEditor + Left = 470 + Height = 500 + Top = 238 + Width = 666 + Caption = 'FormWYSIWYGEditor' + ClientHeight = 500 + ClientWidth = 666 + OnCreate = FormCreate + LCLVersion = '3.8.0.0' + object Memo1: TMemo + Left = 16 + Height = 93 + Top = 55 + Width = 601 + Lines.Strings = ( + '<h1><b>D2Bridge</b> WYSIWYG Editor</h1><br><p>Welcome to the <strong>D2Bridge</strong> <em>Summernote</em> editor demo. This editor allows you to:</p><ul> <li>Edit rich text</li> <li><b>Format</b>, <i>style</i>, <u>underline</u></li> <li>Create lists and tables</li> <li>Insert links and images</li></ul><br><h2>🚀 Key Features</h2><ol> <li>Lightweight and fast</li> <li>Easy to integrate</li> <li>Exports clean HTML</li></ol><p>Here is an image from<br><img style="width: 400px;" src="https://d2bridge.com.br/images/LogoD2Bridge.png"><br></p><br><h3>🧩 Code Example</h3><pre class="language-delphi"><code class="language-delphi hljs" data-highlighted="yes"><span class="hljs-comment">//Renderize Memo1 content</span>' + 'WysiwygEditor(Memo1);</code></pre><pre class="language-delphi"><code class="language-delphi hljs" data-highlighted="yes"><span class="hljs-comment">//Renderize Dataware </span>' + 'WysiwygEditor(DataSource1, <span class="hljs-string">''YourTextField''</span>);' + '</code></pre><p><br></p><h3>📊 Simple Table</h3><br><table border="1" cellpadding="5"> <tbody><tr><th>Feature</th><th>Status</th></tr> <tr><td>Image Upload</td><td>✅</td></tr> <tr><td>Code Block</td><td>✅</td></tr></tbody></table><br>' + ) + TabOrder = 0 + WordWrap = False + end + object Button2: TButton + Left = 144 + Height = 25 + Top = 24 + Width = 89 + Caption = 'Edit/ReadOnly' + TabOrder = 1 + OnClick = Button2Click + end + object Button1: TButton + Left = 16 + Height = 25 + Top = 24 + Width = 122 + Caption = 'Enable/Disable Editor' + TabOrder = 2 + OnClick = Button1Click + end + object DBGrid1: TDBGrid + Left = 16 + Height = 129 + Top = 344 + Width = 217 + Color = clWindow + Columns = < + item + Title.Caption = 'Title' + Width = 150 + FieldName = 'Title' + end> + DataSource = DataSource1 + Options = [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgRowSelect, dgConfirmDelete, dgCancelOnExit] + TabOrder = 3 + TitleFont.Color = clWindowText + TitleFont.Height = -11 + TitleFont.Name = 'Tahoma' + end + object Button3: TButton + Left = 16 + Height = 25 + Top = 313 + Width = 122 + Caption = 'Enable/Disable Editor' + TabOrder = 4 + OnClick = Button3Click + end + object Memo2: TMemo + Left = 16 + Height = 93 + Top = 172 + Width = 601 + Lines.Strings = ( + '<h1><b>D2Bridge</b> WYSIWYG Editor</h1><br><p>Welcome to the <strong>D2Bridge</strong> <em>Example</em> editor demo. This editor allows you to:</p><ul><li>Edit rich text with inline formatting</li><li><b>Bold</b>, <i>italic</i>, <u>underline</u>, and more</li><li>Create lists and tables</li><li>Insert links, images, and files</li></ul><br><h2>Key Features</h2><ol><li>Lightweight and fast</li><li>Easy to integrate with D2Bridge</li><li>Supports both full and Air (inline) modes</li></ol><p><strong>Air Mode</strong> allows editing content inline with a floating toolbar, ideal for minimal UI integrations where the toolbar appears only when text is selected.</p><p>Below is an image from D2Bridge:<br><img alt="D2Bridge Logo" src="https://d2bridge.com.br/images/LogoD2Bridge.png" style="width:400px"><br></p><br><h3>Delphi Code Example</h3><pre class="language-delphi"><code class="language-delphi hljs">// Render Memo1 content' + 'WysiwygEditor(Memo1);</code></pre><pre class="language-delphi"><code class="language-delphi hljs">// Render Data-aware field' + 'WysiwygEditor(DataSource1, ''Text'');</code></pre><h3>Simple Table</h3><br><table border="1" cellpadding="5"><tr><th>Feature</th><th>Status</th></tr><tr><td>Image Upload</td><td>Yes</td></tr><tr><td>Air Mode Support</td><td>Yes</td></tr></table><br>' + ) + TabOrder = 5 + WordWrap = False + end + object DataSource1: TDataSource + DataSet = BufDataset1 + Left = 596 + Top = 16 + end + object BufDataset1: TBufDataset + FieldDefs = <> + Left = 528 + Top = 16 + object BufDataset1Title: TStringField + FieldKind = fkData + FieldName = 'Title' + Index = 0 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 100 + end + object BufDataset1Text: TStringField + FieldKind = fkData + FieldName = 'Text' + Index = 1 + LookupCache = False + ProviderFlags = [pfInUpdate, pfInWhere] + ReadOnly = False + Required = False + Size = 2000 + end + end +end diff --git a/Beta/Demos/Lazarus_linux/unitwysiwygeditor.pas b/Beta/Demos/Lazarus_linux/unitwysiwygeditor.pas new file mode 100644 index 0000000..d8ef551 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/unitwysiwygeditor.pas @@ -0,0 +1,197 @@ +unit UnitWYSIWYGEditor; + +{ Copyright 2025 / 2026 D2Bridge Framework by Talis Jonatas Gomes } + +interface + +uses + Classes, SysUtils, DB, BufDataset, Controls, Graphics, Dialogs, StdCtrls, DBGrids, + D2Bridge.Forms; + +type + + { TFormWYSIWYGEditor } + + TFormWYSIWYGEditor = class(TD2BridgeForm) + BufDataset1: TBufDataset; + BufDataset1Text: TStringField; + BufDataset1Title: TStringField; + Button1: TButton; + Button2: TButton; + Button3: TButton; + DataSource1: TDataSource; + DBGrid1: TDBGrid; + Memo1: TMemo; + Memo2: TMemo; + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + procedure FormCreate(Sender: TObject); + private + procedure PopuleData; + public + { Public declarations } + protected + procedure Upload(AFiles: TStrings; Sender: TObject); override; + procedure ExportD2Bridge; override; + procedure InitControlsD2Bridge(const PrismControl: TPrismControl); override; + procedure RenderD2Bridge(const PrismControl: TPrismControl; var HTMLControl: string); override; + end; + +function FormWYSIWYGEditor: TFormWYSIWYGEditor; + +implementation + +uses + LazarusWebApp, D2BridgeFormTemplate; + +{$R *.lfm} + +function FormWYSIWYGEditor: TFormWYSIWYGEditor; +begin + result:= (TFormWYSIWYGEditor.GetInstance as TFormWYSIWYGEditor); +end; + +procedure TFormWYSIWYGEditor.Button1Click(Sender: TObject); +begin + Memo1.Enabled:= not Memo1.Enabled; +end; + +procedure TFormWYSIWYGEditor.Button2Click(Sender: TObject); +begin + Memo1.ReadOnly:= not Memo1.ReadOnly; +end; + +procedure TFormWYSIWYGEditor.Button3Click(Sender: TObject); +begin + if BufDataset1.State in [dsEdit] then + BufDataset1.Post + else + BufDataset1.Edit; +end; + +procedure TFormWYSIWYGEditor.FormCreate(Sender: TObject); +begin + PopuleData; +end; + +procedure TFormWYSIWYGEditor.PopuleData; +begin + BufDataset1.Close; + + BufDataset1.CreateDataSet; + + BufDataset1.AppendRecord(['Example 1', + '<h1><b>Example 1:</b> D2Bridge WYSIWYG Editor</h1><br><p>Welcome to the <strong>D2Bridge</strong> <em>WYSIWYG Editor</em> demo. It provides the following features:</p><ul><li><b>Text formatting</b> with bold, italic, underline</li><li>' + sLineBreak + + 'Live HTML editing</li><li>Supports tables, lists, links</li><li>Image and file insertion</li></ul><br><h2>Editor Highlights</h2><ol><li>Fully integrated with D2Bridge Framework</li><li>Simple and extensible toolbar</li><li>100% HTML output' + sLineBreak + + '</li></ol><p><img alt="D2Bridge Logo" src="https://d2bridge.com.br/images/LogoD2Bridge.png" style="width:350px"><br></p><br><h3>Delphi Code Example</h3><pre class="language-delphi"><code class="language-delphi hljs">// Render static content' + sLineBreak + + 'WysiwygEditor(Memo1);</code></pre><pre class="language-delphi"><code class="language-delphi hljs">// Render data-aware field' + sLineBreak + + 'WysiwygEditor(DataSource1, ''FieldName'');</code></pre><h3>Features Table</h3><table border="1" cellpadding="5"><tr><th>Feature</th><th>Available</th></tr><tr><td>Bold/Italic</td><td>Yes</td></tr><tr><td>Image Upload</td><td>Yes</td></tr>' + sLineBreak + + '</table><br>' + ]); + + BufDataset1.AppendRecord(['Example 2', + '<h1><b>Example 2:</b> D2Bridge Documentation Editor</h1><br><p>This is an example of how the <strong>D2Bridge Editors</strong> editor can be used to write simple documentation:</p><ul><li>Create headings and formatted paragraphs</li><li>' + sLineBreak + + 'Use bullet and numbered lists</li><li>Insert inline code or code blocks</li><li>Embed media and tables</li></ul><br><h2>Highlights</h2><ol><li>Intuitive user interface</li><li>Custom toolbar integration</li><li>Cross-browser support</li>' + sLineBreak + + '</ol><p><img alt="D2Bridge" src="https://d2bridge.com.br/images/LogoD2Bridge.png" style="width:300px"><br></p><br><h3>Example Snippets</h3><pre class="language-delphi"><code class="language-delphi hljs">// Auto-rendering field content' + sLineBreak + + 'WysiwygEditor(DataSource1, ''FieldName'');</code></pre><pre class="language-delphi"><code class="language-delphi hljs">// Rendering manual content' + sLineBreak + + 'WysiwygEditor(MemoEditor);</code></pre><h3>Output Options</h3><table border="1" cellpadding="5"><tr><th>Output Type</th><th>Status</th></tr><tr><td>HTML Export</td><td>Yes</td></tr><tr><td>Live Preview</td><td>Yes</td></tr></table><br>' + ]); +end; + +procedure TFormWYSIWYGEditor.Upload(AFiles: TStrings; Sender: TObject); +begin + //Handle the attachment here + + //Ex: + // AFiles[0]:= 'NewLocation\NameFile.jpg'; +end; + +procedure TFormWYSIWYGEditor.ExportD2Bridge; +begin + inherited; + + Title:= 'My D2Bridge Form'; + + TemplateClassForm:= TD2BridgeFormTemplate; + D2Bridge.FrameworkExportType.TemplateMasterHTMLFile:= ''; + D2Bridge.FrameworkExportType.TemplatePageHTMLFile := ''; + + with D2Bridge.Items.add do + begin + //WYSIWYG with TMemo + with Row.Items.Add do + with Col.Add.Card('WYSIWYG Editor').Items.Add do + begin + with Row.Items.Add do + begin + ColAuto.Add.VCLObj(Button1); + ColAuto.Add.VCLObj(Button2); + end; + + with Row.Items.Add do + Col.Add.WYSIWYGEditor(Memo1, 450); + end; + + //WYSIWYG Air Mode with TMemo + with Row.Items.Add do + with Col.Add.Card('WYSIWYG Editor in Air Mode').Items.Add do + begin + with Row.Items.Add do + Col.Add.WYSIWYGEditor(Memo2, true); + end; + + with Row.Items.Add do + with Col.Add.Card('WYSIWYG Editor with Database').Items.Add do + begin + with Row.Items.Add do + ColAuto.Add.VCLObj(Button3); + + with Row.Items.Add do + begin + Col4.Add.VCLObj(DBGrid1); + with Col.Add.WYSIWYGEditor(DataSource1, 'Text') do + begin + //Personalize your WYSIWYG + Height:= 400; //0 is auto + ShowButtonHelp:= false; + //ShowButtonUpload:= false; + //Show...... + end; + end; + end; + end; + +end; + +procedure TFormWYSIWYGEditor.InitControlsD2Bridge(const PrismControl: TPrismControl); +begin + inherited; + + //Change Init Property of Prism Controls + { + if PrismControl.VCLComponent = Edit1 then + PrismControl.AsEdit.DataType:= TPrismFieldType.PrismFieldTypeInteger; + + if PrismControl.IsDBGrid then + begin + PrismControl.AsDBGrid.RecordsPerPage:= 10; + PrismControl.AsDBGrid.MaxRecords:= 2000; + end; + } +end; + +procedure TFormWYSIWYGEditor.RenderD2Bridge(const PrismControl: TPrismControl; var HTMLControl: string); +begin + inherited; + + //Intercept HTML + { + if PrismControl.VCLComponent = Edit1 then + begin + HTMLControl:= '</>'; + end; + } +end; + +end. diff --git a/Beta/Demos/Lazarus_linux/web/d2dockerdeploy.conf b/Beta/Demos/Lazarus_linux/web/d2dockerdeploy.conf new file mode 100644 index 0000000..1ecbe75 --- /dev/null +++ b/Beta/Demos/Lazarus_linux/web/d2dockerdeploy.conf @@ -0,0 +1,12 @@ +[DeployOptions] +Mode=Upload, Install and Publish Quick Switch +Database=External +AddBaseFolder=0 +AddSupportFiles=1 +AddDataFiles=0 + +[D2Docker URL] +URL=45.143.7.84 + +[Support Files] +0=C:\Users\talis\OneDrive\Documentos\Projetos\Codigo Fonte\D2Bridge\Source\branches\D2BridgeDocker\Demos\Lazarus\web\wwwroot\images\ diff --git a/Beta/Demos/Lazarus_linux/web/wwwroot/images/bridge.jpg b/Beta/Demos/Lazarus_linux/web/wwwroot/images/bridge.jpg new file mode 100644 index 0000000..35e76c7 Binary files /dev/null and b/Beta/Demos/Lazarus_linux/web/wwwroot/images/bridge.jpg differ diff --git a/Beta/Demos/Lazarus_linux/web/wwwroot/images/d2bridge.png b/Beta/Demos/Lazarus_linux/web/wwwroot/images/d2bridge.png new file mode 100644 index 0000000..31f87bb Binary files /dev/null and b/Beta/Demos/Lazarus_linux/web/wwwroot/images/d2bridge.png differ diff --git a/Beta/Demos/Lazarus_linux/web/wwwroot/images/lazarus.png b/Beta/Demos/Lazarus_linux/web/wwwroot/images/lazarus.png new file mode 100644 index 0000000..1578161 Binary files /dev/null and b/Beta/Demos/Lazarus_linux/web/wwwroot/images/lazarus.png differ diff --git a/Beta/Demos/Lazarus_linux/web/wwwroot/images/license-25-de-abril-bridge-over-the-tagus-river-surrounded-by-hills-and-lights-in-the-evening-11061802.pdf b/Beta/Demos/Lazarus_linux/web/wwwroot/images/license-25-de-abril-bridge-over-the-tagus-river-surrounded-by-hills-and-lights-in-the-evening-11061802.pdf new file mode 100644 index 0000000..b3fe400 Binary files /dev/null and b/Beta/Demos/Lazarus_linux/web/wwwroot/images/license-25-de-abril-bridge-over-the-tagus-river-surrounded-by-hills-and-lights-in-the-evening-11061802.pdf differ diff --git a/Beta/Wizard/BPL/23.0/D2BridgeFrameworkWizard.bpl b/Beta/Wizard/BPL/23.0/D2BridgeFrameworkWizard.bpl index 930e29b..877d72b 100644 Binary files a/Beta/Wizard/BPL/23.0/D2BridgeFrameworkWizard.bpl and b/Beta/Wizard/BPL/23.0/D2BridgeFrameworkWizard.bpl differ diff --git a/Beta/Wizard/Package/Commom/D2Bridge.NewProject.Wizard.Common.pas b/Beta/Wizard/Package/Commom/D2Bridge.NewProject.Wizard.Common.pas index b4b3a9b..aba29b5 100644 --- a/Beta/Wizard/Package/Commom/D2Bridge.NewProject.Wizard.Common.pas +++ b/Beta/Wizard/Package/Commom/D2Bridge.NewProject.Wizard.Common.pas @@ -1,1039 +1,1099 @@ -{ - +--------------------------------------------------------------------------+ - D2Bridge Framework Content - - Author: Talis Jonatas Gomes - Email: talisjonatas@me.com - - Copyright (c) 2024 Talis Jonatas Gomes - talisjonatas@me.com - Intellectual property of computer programs protected by international and - brazilian (9.609/1998) laws. - Software licensed under "opensource" license. - - Rules: - Everone is permitted to copy and distribute verbatim copies of this license - document, but changing it is not allowed. - - This source code is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this code. - - However, it is granted that this code may be used for any purpose, - including commercial applications, but it may not be modified, - distributed, or sublicensed without express written authorization from - the author (Talis Jonatas Gomes). This includes creating derivative works - or distributing the source code through any means. - - If you use this software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - God bless you - +--------------------------------------------------------------------------+ -} - -unit D2Bridge.NewProject.Wizard.Common; - -{$IFDEF FPC} - {$MODE Delphi} - //{$DEFINE LCLLIB} -{$ELSE} - {$DEFINE DELPHI} -{$ENDIF} - - - -interface - -Uses -{$IFDEF FPC} - FileUtil, {$IFDEF LCLLIB}ProjectIntf,{$ENDIF} -{$ELSE} - Winapi.Windows, ToolsAPI, System.Zip, System.IOUtils, DateUtils, -{$ENDIF} - Classes, SysUtils, Forms, Dialogs, D2Bridge.ConfigNewProject.View; - - -type - TTypeServer = - ({$IFDEF DELPHI}tsWebFMX,tsWebAndFMX,{$ENDIF} - {$IFDEF FPC}tsWebLCL{$ELSE}tsWebVCL{$ENDIF}, - {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF}); - -type - - { TD2BridgeNewProjectWizardCommon } - - TD2BridgeNewProjectWizardCommon = class - private -{$IFDEF FPC} -{$IFDEF LCLLIB} - //FLazProject: TLazProject; -{$ENDIF} -{$ENDIF} - public - WizardForm: TD2BridgeConfigNewProject; - PathPROJ: string; - - constructor Create; - destructor Destroy; override; - -{$IFDEF FPC} -{$IFDEF LCLLIB} - //property LazProject: TLazProject read FLazProject write FLazProject; -{$ENDIF} -{$ENDIF} - - procedure Execute; - end; - -implementation - -Uses - D2Bridge.Wizard.Util, - D2Bridge.Lang.Util; - - -{ TD2BridgeNewProjectWizardCommon } - -constructor TD2BridgeNewProjectWizardCommon.Create; -begin - inherited; - - PathPROJ:= ''; - WizardForm:= TD2BridgeConfigNewProject.Create(Application); -end; - -destructor TD2BridgeNewProjectWizardCommon.Destroy; -begin - if Assigned(WizardForm) then - FreeAndNil(WizardForm); - - inherited Destroy; -end; - -{ -DELHI LAZARUS TIPO DE ARQUIVO -.DPR .LPR Arquivo principal do projeto. Contém o ponto de entrada do programa. -.DPROJ .LPI Arquivo do projeto que contém configurações específicas do Lazarus, equivalente ao .dproj no Delphi. -.RES .LRS ou .RES Arquivo de recursos. Lazarus usa .lrs gerado pelo Lazarus Resource Editor, mas também pode usar .res. -.DFM .LFM Arquivo de descrição do formulário. Em Lazarus, os formulários são descritos no formato .lfm. -.PAS .PAS Arquivo de código-fonte Pascal. O código .pas é idêntico tanto no Delphi quanto no Lazarus. -} - -procedure TD2BridgeNewProjectWizardCommon.Execute; -var - I: Integer; -{$IFDEF DELPHI} - services: IOTAModuleServices; - sSourceWebFMXDPROJFile, sSourceFMXDPROJFile: string; - sSourceWebFMXDPRFile, sSourceFMXDPRFile: string; - sSourceWebFMXRESFile, sSourceFMXRESFile: string; -{$ENDIF} -{$IFDEF FPC} - sSourceFixD2BridgeLazCompile, sSourceFixD2BridgeLazBuild: string; -{$ENDIF} - sProjectNameLogical,sTyperProject,sProjectName,sDestinationPath,sSourceFiles:string; - sDestinationPathWeb, sDestinationPathBinWeb, sDestinationPathCommonUnit,sD2BridgeFrameworkSearchPath,sD2BridgeFrameworkPath: String; - sD2BridgeDirectives: TStrings; - sLangCode, sLangCodeUnderline: string; - sLanguageUnitSourcePath: string; - sLanguageJSONPath: string; - sLanguagesUnitsDPR, sLanguagesJSON, sLanguagesUSES, sLanguagesCREATE, sLanguagesDESTROY, sLanguagesSET, sUNITs: TStrings; - sPathBINWEB, sPathBIN: string; - sPathwwwroot: string; - sPathWEBDPROJFile, sPathWEBRESFile, sPathWEBICOFile, sPathWizard, sPathUnitBase, sPathUnitServer, sPathDFMServer: string; - sPathUnitServiceServer : string; - sSourceWebVCLDPROJFile, sSourceVCLDPROJFile: string; - sSourceWebDPRFile, sSourceVCLDPRFile: string; - sSourceWebRESFile, sSourceVCLRESFile: string; - sSourceWebICOFile, sSourceVCLICOFile: string; - sFileContent: string; - sFile: TStringStream; - sClassPrimaryForm, sUnitPrimaryForm: string; - sUnitLogin, sFormLogin: string; - sTypeServer: TTypeServer; - sRESTAPIServerUnitAuthFile, sRESTAPIServerUnitPingFile: string; - sRESTAPIServerUnitAuthClassFile, sRESTAPIServerUnitPingClassFile: string; - sRESTAPIServerSessionFile: string; -begin - try - WizardForm.ShowModal; - if WizardForm.EnableCreateProject then - begin - - //----- PROJECT TYPE -{$IFDEF FPC} - if WizardForm.ComboBox_Platform.Text = 'LCL for WEB' then - begin - if WizardForm.CheckBox_Add_Project_Platform.Checked then - sTypeServer:= tsWebAndLCL - else - sTypeServer:= tsWebLCL; - end; -{$ELSE} - if WizardForm.ComboBox_Platform.Text = 'VCL for WEB' then - begin - if WizardForm.CheckBox_Add_Project_Platform.Checked then - sTypeServer:= tsWebAndVCL - else - sTypeServer:= tsWebVCL; - end else - begin - if WizardForm.CheckBox_Add_Project_Platform.Checked then - sTypeServer:= tsWebAndFMX - else - sTypeServer:= tsWebFMX; - end; -{$ENDIF} - - //D2Bridge Framework Path - sD2BridgeFrameworkPath:= ExcludeTrailingPathDelimiter(WizardForm.Edit_Path_D2Bridge.Text); - sD2BridgeFrameworkSearchPath:= WizardForm.Edit_Path_D2Bridge.Text+';'+WizardForm.Edit_Path_D2Bridge.Text+'Prism'+';'+WizardForm.Edit_Path_D2Bridge.Text+'Others VCL'+';'; - - sProjectName := WizardForm.Edit_ProjectName.Text; - - sPathWizard:= ExtractFileDir(ExcludeTrailingPathDelimiter(WizardForm.Edit_Path_D2Bridge.Text))+ PathDelim + 'Wizard'; - sPathUnitBase:= ExtractFileDir(ExcludeTrailingPathDelimiter(WizardForm.Edit_Path_D2Bridge.Text))+ PathDelim + 'Unit Base'; - -{$IFDEF FPC} - sSourceWebVCLDPROJFile:= sPathWizard + PathDelim + 'dpr'+ PathDelim + 'LAZARUS'+ PathDelim + 'D2BridgeWebAppLCL.lpi'; -{$ELSE} - sSourceWebVCLDPROJFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppVCL.dproj'; -{$ENDIF} - -{$IFDEF DELPHI} - sSourceWebFMXDPROJFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppFMX.dproj'; -{$ENDIF} - -{$IFDEF FPC} - sSourceVCLDPROJFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppWithLCL.lpi'; -{$ELSE} - sSourceVCLDPROJFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppWithVCL.dproj'; -{$ENDIF} - -{$IFDEF DELPHI} - sSourceFMXDPROJFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppWithFMX.dproj'; -{$ENDIF} - -{$IFDEF FPC} - sSourceWebDPRFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppLCL.lpr'; -{$ELSE} - sSourceWebDPRFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppVCL.dpr'; -{$ENDIF} - -{$IFDEF DELPHI} - sSourceWebFMXDPRFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppFMX.dpr'; -{$ENDIF} - -{$IFDEF FPC} - sSourceVCLDPRFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppWithLCL.lpr'; -{$ELSE} - sSourceVCLDPRFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppWithVCL.dpr'; -{$ENDIF} - -{$IFDEF DELPHI} - sSourceFMXDPRFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppWithFMX.dpr'; -{$ENDIF} - -{$IFDEF FPC} - sSourceWebRESFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppLCL.res'; -{$ELSE} - sSourceWebRESFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppVCL.res'; -{$ENDIF} - -{$IFDEF FPC} - sSourceWebICOFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppLCL.ico'; -{$ELSE} - sSourceWebICOFile:= sPathWizard + '\dpr\' + 'D2BridgeApp.ico'; -{$ENDIF} - -{$IFDEF DELPHI} - sSourceWebFMXRESFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppFMX.res'; -{$ENDIF} - -{$IFDEF FPC} - sSourceVCLRESFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + '' + 'D2BridgeWebAppWithLCL.res'; -{$ELSE} - sSourceVCLRESFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppWithVCL.res'; -{$ENDIF} - -{$IFDEF FPC} - sSourceVCLICOFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppWithLCL.ico'; -{$ELSE} - sSourceVCLICOFile:= sPathWizard + '\dpr\' + 'D2BridgeApp.ico'; -{$ENDIF} - -{$IFDEF DELPHI} - sSourceFMXRESFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppWithFMX.res'; -{$ENDIF} - -{$IFDEF FPC} - sSourceFixD2BridgeLazCompile := sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'FixD2BridgeLazCompile.bat'; - sSourceFixD2BridgeLazBuild := sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'FixD2BridgeLazBuild.bat'; -{$ENDIF} - - if WizardForm.CheckBox_Create_Project_Folder.Checked then - sDestinationPath := PChar(WizardForm.Edit_ProjectDestination.Text+sProjectName) - else - sDestinationPath := PChar(WizardForm.Edit_ProjectDestination.Text); - - sDestinationPathWeb := sDestinationPath; - sDestinationPathCommonUnit:= sDestinationPath; - - sDestinationPathBinWeb := sDestinationPathWeb + PathDelim + 'Web'; - sPathwwwroot := sDestinationPathBinWeb + PathDelim + 'wwwroot'; - - sProjectNameLogical:= sDestinationPathWeb+ PathDelim +sProjectName+{$IFDEF FPC}'.lpr'{$ELSE}'.dpr'{$ENDIF}; - sPathWEBDPROJFile:= sDestinationPathWeb+ PathDelim +sProjectName+{$IFDEF FPC}'.lpi'{$ELSE}'.dproj'{$ENDIF}; - sPathWEBRESFile:= sDestinationPathWeb+ PathDelim +sProjectName+{$IFDEF FPC}'.res'{$ELSE}'.res'{$ENDIF}; - sPathWEBICOFile:= sDestinationPathWeb+ PathDelim +sProjectName+{$IFDEF FPC}'.ico'{$ELSE}'.ico'{$ENDIF}; - - sLanguageUnitSourcePath:= sPathWizard + PathDelim + 'Lang Support' + PathDelim + 'D2Bridge.Lang.APP.Language.pas'; - - sLanguageJSONPath:= sPathWizard + PathDelim + 'Lang Support' + PathDelim + 'lang'; - - //REST API Server - sRESTAPIServerUnitAuthClassFile:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Wizard' + PathDelim + 'RestAPIAuthClass' + {$IFDEF FPC} '.Laz' +{$ENDIF} '.pas'; - sRESTAPIServerUnitAuthFile:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Wizard' + PathDelim + 'RestAPIAuth' + {$IFDEF FPC} '.Laz' +{$ENDIF} '.pas'; - sRESTAPIServerUnitPingClassFile:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Wizard' + PathDelim + 'RestAPIUnitClass' + {$IFDEF FPC} '.Laz' +{$ENDIF} '.pas'; - sRESTAPIServerUnitPingFile:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Wizard' + PathDelim + 'RestAPIUnit' + {$IFDEF FPC} '.Laz' +{$ENDIF} '.pas'; - sRESTAPIServerSessionFile:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Wizard' + PathDelim + 'D2Bridge.Rest.Session.pas'; - - sClassPrimaryForm:= 'TForm1'; - sUnitPrimaryForm:= 'Unit1'; - - sUNITs:= TStringList.Create; -{$IFDEF FPC} - sUnitLogin:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Native' + PathDelim + 'Lazarus' + PathDelim + 'Login' + PathDelim + 'Unit_Login.pas'; - sFormLogin:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Native' + PathDelim + 'Lazarus' + PathDelim + 'Login' + PathDelim + 'Unit_Login.lfm'; -{$ELSE} - if (sTypeServer = tsWebFMX) or (sTypeServer = tsWebAndFMX) then - begin - sUnitLogin:= sPathWizard + '\FORMS\Native\FMX\Login\Unit_Login.pas'; - sFormLogin:= sPathWizard + '\FORMS\Native\FMX\Login\Unit_Login.fmx'; - end else - begin - sUnitLogin:= sPathWizard + '\FORMS\Native\Login\Unit_Login.pas'; - sFormLogin:= sPathWizard + '\FORMS\Native\Login\Unit_Login.dfm'; - end; -{$ENDIF} - - //----- D2Bridge Directives - sD2BridgeDirectives:= TStringList.Create; - sD2BridgeDirectives.LineBreak:= ';'; - sD2BridgeDirectives.Add('D2Bridge'); -{$IFDEF DELPHI} - if sTypeServer in [tsWebFMX, tsWebAndFMX] then - sD2BridgeDirectives.Add('FMX'); -{$ENDIF} - if WizardForm.CheckListBox_ThirdParty.Checked[WizardForm.CheckListBox_ThirdParty.Items.IndexOf('RXLIB')] then - sD2BridgeDirectives.Add('RXLIB_AVAILABLE'); - if WizardForm.CheckListBox_ThirdParty.Checked[WizardForm.CheckListBox_ThirdParty.Items.IndexOf('SMComponents')] then - sD2BridgeDirectives.Add('SMCOMPONENTS_AVAILABLE'); - if WizardForm.CheckListBox_ThirdParty.Checked[WizardForm.CheckListBox_ThirdParty.Items.IndexOf('DevExpress')] then - sD2BridgeDirectives.Add('DEVEXPRESS_AVAILABLE'); - if WizardForm.CheckListBox_ThirdParty.Checked[WizardForm.CheckListBox_ThirdParty.Items.IndexOf('JVCL')] then - sD2BridgeDirectives.Add('JVCL_AVAILABLE'); - - - //----- CREATE PROJECT DIRECTORY - If not DirectoryExists(sDestinationPath) then - MKdir(sDestinationPath); - If not DirectoryExists(sDestinationPathWeb) then - MKdir(sDestinationPathWeb); - If not DirectoryExists(sDestinationPathWeb + PathDelim + 'Web') then - MKdir(sDestinationPathWeb + PathDelim + 'Web'); - If not DirectoryExists(sPathwwwroot) then - MKdir(sPathwwwroot); - if WizardForm.ComboBox_Enabled_Multi_Languages.Text = 'Yes' then - If not DirectoryExists(sDestinationPathBinWeb+ PathDelim + 'lang') then - MKdir(sDestinationPathBinWeb+ PathDelim + 'lang'); - -// //----- COPY DPR -// if sTypeServer = {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF} then -// {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceVCLDPRFile, sProjectNameLogical, false) -// else -//{$IFDEF DELPHI} -// if sTypeServer = tsWebAndFMX then -// CopyFile(PWideChar(sSourceFMXDPRFile), PWideChar(sProjectNameLogical), false) -// else -// if sTypeServer = tsWebFMX then -// CopyFile(PWideChar(sSourceWebFMXDPRFile), PWideChar(sProjectNameLogical), false) -// else -//{$ENDIF} -// {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceWebDPRFile, sProjectNameLogical, false); - - //----- COPY RES - if FileExists(sSourceWebRESFile) then - begin - if sTypeServer = {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF} then - {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceVCLRESFile, sPathWEBRESFile, false) - else -{$IFDEF DELPHI} - if sTypeServer = tsWebAndFMX then - CopyFile(PWideChar(sSourceFMXRESFile), PWideChar(sPathWEBRESFile), false) - else - if sTypeServer = tsWebFMX then - CopyFile(PWideChar(sSourceWebFMXRESFile), PWideChar(sPathWEBRESFile), false) - else -{$ENDIF} - {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceWebRESFile, sPathWEBRESFile, false); - end; - - //----- COPY ICO - if FileExists(sSourceVCLICOFile) then - begin - if sTypeServer = {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF} then - {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceVCLICOFile, sPathWEBICOFile, false) - else -{$IFDEF DELPHI} - if sTypeServer = tsWebAndFMX then - CopyFile(PWideChar(sSourceFMXRESFile), PWideChar(sPathWEBICOFile), false) - else - if sTypeServer = tsWebFMX then - CopyFile(PWideChar(sSourceWebFMXRESFile), PWideChar(sPathWEBICOFile), false) - else -{$ENDIF} - {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceWebICOFile, sPathWEBICOFile, false); - end; - -{$IFDEF FPC} - if sTypeServer in [tsWebLCL, tsWebAndLCL] then - begin - //----- COPY .PAS - CopyFolderFiles(sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + '*.pas', sDestinationPathWeb); - //----- COPY .DFM - CopyFolderFiles(sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + '*.lfm', sDestinationPathWeb); - end; -{$ELSE} - if sTypeServer in [tsWebFMX, tsWebAndFMX] then - begin - //----- COPY .PAS - CopyFolderFiles(PWideChar(sPathWizard+'\dpr\FMX\*.pas'), sDestinationPathWeb); - //----- COPY .DFM - CopyFolderFiles(PWideChar(sPathWizard+'\dpr\FMX\*.fmx'), sDestinationPathWeb); - end else - begin - //----- COPY .PAS - CopyFolderFiles(PWideChar(sPathWizard+'\dpr\*.pas'), sDestinationPathWeb); - //----- COPY .DFM - CopyFolderFiles(PWideChar(sPathWizard+'\dpr\*.dfm'), sDestinationPathWeb); - end; -{$ENDIF} - - -//----- COPY FixD2BridgeLazBuild -{$IFDEF FPC} - CopyFolderFiles(sSourceFixD2BridgeLazBuild, sDestinationPathWeb); - CopyFolderFiles(sSourceFixD2BridgeLazCompile, sDestinationPathWeb); -{$ENDIF} - - - {$REGION 'Language Support'} - sLanguagesUnitsDPR:= TStringList.Create; - sLanguagesJSON:= TStringList.Create; - sLanguagesUSES:= TStringList.Create; - sLanguagesCREATE:= TStringList.Create; - sLanguagesDESTROY:= TStringList.Create; - sLanguagesSET:= TStringList.Create; - if WizardForm.ComboBox_Enabled_Multi_Languages.Text = 'Yes' then - begin - {$REGION 'Prepare Units Name to DPR'} - sLanguagesUnitsDPR.Add(' D2Bridge.Lang.APP.Core in ''D2Bridge.Lang.APP.Core.pas'','); - sLanguagesUnitsDPR.Add(' D2Bridge.Lang.APP.Term in ''D2Bridge.Lang.APP.Term.pas'','); - {$ENDREGION} - - - {$REGION 'Copy Language Support UNITs'} - {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF} - (sPathWizard + PathDelim + 'Lang Support' + PathDelim + 'D2Bridge.Lang.APP.Term.pas', sDestinationPathWeb + PathDelim + 'D2Bridge.Lang.APP.Term.pas', false); - {$ENDREGION} - - {$REGION 'Copy Languages Units'} - sLanguagesDESTROY.Add('{$IFNDEF D2WindowsService}'); - for I := 0 to Pred(WizardForm.CheckListBox_Languages.Count) do - if WizardForm.CheckListBox_Languages.Checked[I] then - begin - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sLanguageUnitSourcePath)); - sFileContent:= sFile.DataString; - - sFileContent:= StringReplace(sFileContent, '{Language}', WizardForm.CheckListBox_Languages.Items[I], [rfIgnoreCase, rfReplaceAll]); - - //Add Unit in Project - sLanguagesUnitsDPR.Add(' D2Bridge.Lang.APP.' + WizardForm.CheckListBox_Languages.Items[I] + ' in ''D2Bridge.Lang.APP.' + WizardForm.CheckListBox_Languages.Items[I] + '.pas'','); - //Add Language Code JSON - sLangCode:= LanguageCode(D2BridgeLangbyLanguageName(WizardForm.CheckListBox_Languages.Items[I])); - sLangCodeUnderline:= StringReplace(sLangCode, '-', '_', []); - if WizardForm.ComboBox_Embed_Translation_Files.Text = 'Yes' then //Embed JSON - sLanguagesJSON.Add('D2Bridge_Lang_APP_' + sLangCodeUnderline + ' RCDATA "lang\\'+ sLangCode +'.json"'); - - {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF} - (sLanguageJSONPath + PathDelim + 'language.json', - sDestinationPathBinWeb + PathDelim + 'lang' + PathDelim + sLangCode + '.json', false); - //Add USES language - sLanguagesUSES.Add(' D2Bridge.Lang.APP.' + WizardForm.CheckListBox_Languages.Items[I]+','); - //Add Language Create - sLanguagesCREATE.Add(' ' + WizardForm.CheckListBox_Languages.Items[I] + ':= ' + 'TD2BridgeLangAPP' + WizardForm.CheckListBox_Languages.Items[I] + '.Create(self, TD2BridgeAPPTerm);'); - //Add Language Destroy - sLanguagesDESTROY.Add(' TD2BridgeLangAPP' + WizardForm.CheckListBox_Languages.Items[I] + '('+ WizardForm.CheckListBox_Languages.Items[I] +').Destroy;'); - //Add Set Languages - sLanguagesSET.Add('TD2BridgeLang.' + WizardForm.CheckListBox_Languages.Items[I]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(sDestinationPathWeb + PathDelim + 'D2Bridge.Lang.APP.'+WizardForm.CheckListBox_Languages.Items[I]+'.pas'); - sFile.Free; - end; - sLanguagesDESTROY.Add('{$ENDIF}'); - {$ENDREGION} - - {$REGION 'Copy D2Bridge.Lang.APP.Core'} - for I := 0 to Pred(WizardForm.CheckListBox_Languages.Count) do - if WizardForm.CheckListBox_Languages.Checked[I] then - begin - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sPathWizard + PathDelim + 'Lang Support' + PathDelim + 'D2Bridge.Lang.APP.Core.pas')); - sFileContent:= sFile.DataString; - - sFileContent:= StringReplace(sFileContent, '{Uses_Languages}', sLanguagesUSES.Text, [rfIgnoreCase, rfReplaceAll]); - sFileContent:= StringReplace(sFileContent, '{Create_Languages}', sLanguagesCREATE.Text, [rfIgnoreCase, rfReplaceAll]); - sFileContent:= StringReplace(sFileContent, '{Destroy_Languages}', sLanguagesDESTROY.Text, [rfIgnoreCase, rfReplaceAll]); - - if WizardForm.ComboBox_Embed_Translation_Files.Text = 'No' then - sFileContent:= StringReplace(sFileContent, '{EmbedJSON}', 'false', [rfIgnoreCase, rfReplaceAll]) - else - sFileContent:= StringReplace(sFileContent, '{EmbedJSON}', 'true', [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(sDestinationPathWeb + PathDelim + 'D2Bridge.Lang.APP.Core.pas'); - sFile.Free; - end; - {$ENDREGION} - - {$REGION 'Copy Language RC File'} - if WizardForm.ComboBox_Embed_Translation_Files.Text = 'Yes' then //Embed JSON - for I := 0 to Pred(WizardForm.CheckListBox_Languages.Count) do - if WizardForm.CheckListBox_Languages.Checked[I] then - begin - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFileContent:= sLanguagesJSON.Text; - - sFileContent:= StringReplace(sFileContent, '{Language}', WizardForm.CheckListBox_Languages.Items[I], [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(sDestinationPathWeb + PathDelim + 'D2Bridge.Lang.APP.rc'); - sFile.Free; - end; - {$ENDREGION} - end else - begin - sLanguagesSET.Add('TD2BridgeLang.' + WizardForm.ComboBox_Language.Text); - end; - {$ENDREGION} - - - {$REGION 'UNIT BASE'} - {$REGION 'ServerController.pas'} - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sPathUnitBase + PathDelim + 'ServerController.pas')); - sFileContent:= sFile.DataString; - - sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(sDestinationPathWeb + PathDelim + sProjectName + 'WebApp.pas'); - sFile.Free; - {$ENDREGION} - - {$REGION 'ServerController.dfm'} - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sPathUnitBase+{$IFDEF FPC} PathDelim + 'ServerController.lfm'{$ELSE}'\ServerController.dfm'{$ENDIF})); - sFileContent:= sFile.DataString; - - sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(sDestinationPathWeb+ PathDelim + sProjectName+{$IFDEF FPC}'WebApp.lfm'{$ELSE}'WebApp.dfm'{$ENDIF}); - sFile.Free; - {$ENDREGION} - - {$REGION 'UserSessionUnit.pas'} - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sPathUnitBase + PathDelim + 'UserSessionUnit.pas')); - sFileContent:= sFile.DataString; - - sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(sDestinationPathWeb + PathDelim + sProjectName+'_Session.pas'); - sFile.Free; - {$ENDREGION} - - {$REGION 'UserSessionUnit.dfm'} - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sPathUnitBase + {$IFDEF FPC} PathDelim + 'UserSessionUnit.lfm'{$ELSE}'\UserSessionUnit.dfm'{$ENDIF})); - sFileContent:= sFile.DataString; - - sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(sDestinationPathWeb + PathDelim + sProjectName+{$IFDEF FPC}'_Session.lfm'{$ELSE}'_Session.dfm'{$ENDIF}); - sFile.Free; - {$ENDREGION} - - {$REGION 'D2BridgeFormTemplate.pas'} - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sPathUnitBase + PathDelim + 'D2BridgeFormTemplate.pas')); - sFileContent:= sFile.DataString; - - sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(sDestinationPathWeb + PathDelim + 'D2BridgeFormTemplate.pas'); - sFile.Free; - {$ENDREGION} - {$ENDREGION} - - - - {$REGION 'Login'} - if WizardForm.CheckBox_Form_Login.Checked then - begin - {$IFDEF FPC} - CopyFolderFiles(sUnitLogin, sDestinationPathWeb); - CopyFolderFiles(sFormLogin, sDestinationPathWeb); - {$ELSE} - CopyFolderFiles(PWideChar(sUnitLogin), sDestinationPathWeb); - CopyFolderFiles(PWideChar(sFormLogin), sDestinationPathWeb); - {$ENDIF} - - //Set Primary Form - sClassPrimaryForm:= 'TForm_Login'; - sUnitPrimaryForm:= 'Unit_Login'; - - //Unit Login - sUNITs.Add('Unit_Login in ''Unit_Login.pas'' {Form_Login},'); - - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sDestinationPathWeb + PathDelim + ExtractFileName(sUnitLogin))); - sFileContent:= sFile.DataString; - - //----- Template HTML Files - sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(GetRealFilePath(sDestinationPathWeb + PathDelim + ExtractFileName(sUnitLogin))); - sFile.Free; - end; - {$ENDREGION} - - - - {$REGION 'REST SERVER API'} - if (WizardForm.ComboBox_RestAPIServer.ItemIndex = 0) or (WizardForm.ComboBox_RestAPIServer.ItemIndex = 1) then //Auth - begin - {$REGION 'AUTH CLASS FILE'} - if Pos(UpperCase('Includes Authentication'), UpperCase(WizardForm.ComboBox_RestAPIServer.Text)) > 0 then - begin - sFile:= TStringStream.Create('', TEncoding.UTF8); - if WizardForm.CheckBox_RestAPIServer_UseClass.Checked then //Use Classes in API - sFile.LoadFromFile(GetRealFilePath(sRESTAPIServerUnitAuthClassFile)) - else - sFile.LoadFromFile(GetRealFilePath(sRESTAPIServerUnitAuthFile)); - sFileContent:= sFile.DataString; - - sFileContent := StringReplace(sFileContent, '<UNITNAME>', 'API.Auth', [rfIgnoreCase, rfReplaceAll]); - sFileContent := StringReplace(sFileContent, '<COPYRIGHTYEAR>', IntToStr(CurrentYear), [rfIgnoreCase, rfReplaceAll]); - sFileContent := StringReplace(sFileContent, '<ServerController>', sProjectName + 'WebApp', [rfIgnoreCase, rfReplaceAll]); - sFileContent := StringReplace(sFileContent, '<CLASS_ID>', 'APIAuth', [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(GetRealFilePath(sDestinationPathWeb+ PathDelim + 'API.Auth.pas')); - sFile.Free; - end; - {$ENDREGION} - - - {$REGION 'PING CLASS FILE'} - sFile:= TStringStream.Create('', TEncoding.UTF8); - if WizardForm.CheckBox_RestAPIServer_UseClass.Checked then //Use Classes in API - sFile.LoadFromFile(GetRealFilePath(sRESTAPIServerUnitPingClassFile)) - else - sFile.LoadFromFile(GetRealFilePath(sRESTAPIServerUnitPingFile)); - sFileContent:= sFile.DataString; - - sFileContent := StringReplace(sFileContent, '<UNITNAME>', 'API.Ping', [rfIgnoreCase, rfReplaceAll]); - sFileContent := StringReplace(sFileContent, '<COPYRIGHTYEAR>', IntToStr(CurrentYear), [rfIgnoreCase, rfReplaceAll]); - sFileContent := StringReplace(sFileContent, '<ServerController>', sProjectName + 'WebApp', [rfIgnoreCase, rfReplaceAll]); - sFileContent := StringReplace(sFileContent, '<CLASS_ID>', 'APIPing', [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(GetRealFilePath(sDestinationPathWeb+ PathDelim + 'API.Ping.pas')); - sFile.Free; - {$ENDREGION} - - - {$REGION 'SESSION FILE'} - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sRESTAPIServerSessionFile)); - sFileContent:= sFile.DataString; - - sFileContent := StringReplace(sFileContent, '<COPYRIGHTYEAR>', IntToStr(CurrentYear), [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(GetRealFilePath(sDestinationPathWeb+ PathDelim + 'D2Bridge.Rest.Session.pas')); - sFile.Free; - {$ENDREGION} - - sUNITs.Add(' API.Auth in ''API.Auth.pas'','); - sUNITs.Add(' API.Ping in ''API.Ping.pas'','); - sUNITs.Add(' D2Bridge.Rest.Session in ''D2Bridge.Rest.Session.pas'','); - end; - - {$ENDREGION} - - - - {$REGION 'WEB dpropj'} - //----- COPY DProj - if sTypeServer = {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF} then - {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceVCLDPROJFile, sPathWEBDPROJFile, false) - else -{$IFDEF DELPHI} - if sTypeServer = tsWebAndFMX then - CopyFile(PWideChar(sSourceFMXDPROJFile), PWideChar(sPathWEBDPROJFile), false) - else - if sTypeServer = tsWebFMX then - CopyFile(PWideChar(sSourceWebFMXDPROJFile), PWideChar(sPathWEBDPROJFile), false) - else -{$ENDIF} - {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceWebVCLDPROJFile, sPathWEBDPROJFile, false); - - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sPathWEBDPROJFile)); - sFileContent:= sFile.DataString; - - sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppVCL', sProjectName, [rfIgnoreCase,rfReplaceAll]); - sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppFMX', sProjectName, [rfIgnoreCase,rfReplaceAll]); - sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppWithVCL', sProjectName, [rfIgnoreCase,rfReplaceAll]); - sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppWithFMX', sProjectName, [rfIgnoreCase,rfReplaceAll]); - sFileContent := StringReplace(sFileContent, '{D2BridgeFrameworkPath}', sD2BridgeFrameworkSearchPath, [rfIgnoreCase,rfReplaceAll]); - sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); - sFileContent:= StringReplace(sFileContent, '{D2BridgeDirectives}', sD2BridgeDirectives.Text, [rfIgnoreCase, rfReplaceAll]); - sFileContent:= StringReplace(sFileContent, '{D2BridgePath}', IncludeTrailingPathDelimiter(WizardForm.Edit_Path_D2Bridge.Text), [rfIgnoreCase, rfReplaceAll]); - sFileContent:= StringReplace(sFileContent, '{PathDelim}', PathDelim, [rfIgnoreCase, rfReplaceAll]); - - var G: TGUID; - CreateGUID(G); - sFileContent:= StringReplace(sFileContent, '{ProjectGUID}', GUIDToString(G), [rfIgnoreCase, rfReplaceAll]); - -{$IFDEF FPC} - if WizardForm.ComboBox_Server_Type.Text = 'Server Console (Recommended)' then - sFileContent:= StringReplace(sFileContent, '{D2BridgeServerUnit}', 'Unit_D2Bridge_Server_Console.pas', [rfIgnoreCase, rfReplaceAll]); -{$ENDIF} - - //Replace Language Support Resource - if (WizardForm.ComboBox_Enabled_Multi_Languages.Text = 'Yes') and (WizardForm.ComboBox_Embed_Translation_Files.Text = 'Yes') then - sFileContent:= StringReplace(sFileContent, '{Language Support Resource}', '<RcCompile Include="D2Bridge.Lang.APP.rc"><Form>D2Bridge.Lang.APP.res</Form></RcCompile>', [rfIgnoreCase]) - else - sFileContent:= StringReplace(sFileContent, '{Language Support Resource}', '', [rfIgnoreCase]); - - sFile.Clear; - sFile.WriteString(sFileContent); - SFile.SaveToFile(GetRealFilePath(sPathWEBDPROJFile)); - sFile.Free; - {$ENDREGION} - - - - {$REGION 'WEB dpr'} - {$IFDEF DELPHI} - CopyFolderFiles( - PWideChar(sPathWizard + PathDelim + 'Servers' + PathDelim + 'Service' + PathDelim + '*.*'), - sDestinationPathWeb - ); - - sPathUnitServer := sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Service.pas'; - sPathDFMServer := sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Service.dfm'; - - sFile := TStringStream.Create('', TEncoding.UTF8); - try - sFile.LoadFromFile(GetRealFilePath(sPathUnitServer)); - sFileContent := sFile.DataString; - - sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(GetRealFilePath(sPathUnitServer)); - finally - sFile.Free; - end; - - sFile := TStringStream.Create('', TEncoding.UTF8); - try - sFile.LoadFromFile(GetRealFilePath(sPathDFMServer)); - sFileContent := sFile.DataString; - - sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(GetRealFilePath(sPathDFMServer)); - finally - sFile.Free; - end; - - sPathUnitServiceServer := sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Core.pas'; - - sFile := TStringStream.Create('', TEncoding.UTF8); - try - sFile.LoadFromFile(GetRealFilePath(sPathUnitServiceServer)); - sFileContent := sFile.DataString; - - sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(GetRealFilePath(sPathUnitServiceServer)); - finally - sFile.Free; - end; - {$ENDIF} - - if sTypeServer = {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF} then - {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceVCLDPRFile, sProjectNameLogical, false) - else - {$IFDEF DELPHI} - if sTypeServer = tsWebAndFMX then - CopyFile(PWideChar(sSourceFMXDPRFile), PWideChar(sProjectNameLogical), false) - else - if sTypeServer = tsWebFMX then - CopyFile(PWideChar(sSourceWebFMXDPRFile), PWideChar(sProjectNameLogical), false) - else - {$ENDIF} - {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceWebDPRFile, sProjectNameLogical, false); - - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sProjectNameLogical)); - sFileContent:= sFile.DataString; - - if WizardForm.ComboBox_Server_Type.Text = 'Server Complete' then - begin - sPathUnitServer:= sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server.pas'; - sPathDFMServer:= sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server.dfm'; - sUNITs.Add('Unit_D2Bridge_Server in ''Unit_D2Bridge_Server.pas'' {Form_D2Bridge_Server},'); - - CopyFolderFiles(PWideChar(sPathWizard + PathDelim + 'Servers\Complete\*.*'), sDestinationPathWeb); - - sFileContent:= StringReplace(sFileContent, '{Units}', sUNITs.Text, [rfIgnoreCase]); - sFileContent:= StringReplace(sFileContent, '{Server}', 'Application.CreateForm(TForm_D2Bridge_Server, Form_D2Bridge_Server);', []); - sFileContent:= StringReplace(sFileContent, '{Application.Run;}', 'Application.Run;', [rfIgnoreCase]); - end else - if WizardForm.ComboBox_Server_Type.Text = 'Server Compact' then - begin - sPathUnitServer:= sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Compact.pas'; - sPathDFMServer:= sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Compact.dfm'; - sUNITs.Add(' Unit_D2Bridge_Server_Compact in ''Unit_D2Bridge_Server_Compact.pas'' {Form_D2Bridge_Server_Compact},'); - - CopyFolderFiles(PWideChar(sPathWizard + PathDelim + 'Servers' + PathDelim + 'Compact' + PathDelim + '*.*'), sDestinationPathWeb); - - sFileContent:= StringReplace(sFileContent, '{Units}', sUNITs.Text, [rfIgnoreCase]); - sFileContent:= StringReplace(sFileContent, '{Server}', 'Application.CreateForm(TForm_D2Bridge_Server_Compact, Form_D2Bridge_Server_Compact);', []); - sFileContent:= StringReplace(sFileContent, '{Application.Run;}', 'Application.Run;', [rfIgnoreCase]); - end else - if WizardForm.ComboBox_Server_Type.Text = 'Server Console (Recommended)' then - begin - sPathUnitServer:= sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Console.pas'; - sPathDFMServer:= ''; - sUNITs.Add('{$IFNDEF D2WindowsService}'); - sUNITs.Add('Unit_D2Bridge_Server_Console in ''Unit_D2Bridge_Server_Console.pas'','); - sUNITs.Add('{$ENDIF}'); -{$IFDEF FPC} - CopyFolderFiles(sPathWizard + PathDelim + 'Servers' + PathDelim + 'Console' + PathDelim + '*.*', sDestinationPathWeb); -{$ELSE} - CopyFolderFiles(PWideChar(sPathWizard+'\Servers\Console\*.*'), sDestinationPathWeb); -{$ENDIF} - - sFileContent:= StringReplace(sFileContent, '{Units}', sUNITs.Text, [rfIgnoreCase]); - sFileContent:= StringReplace(sFileContent, '//{$APPTYPE CONSOLE}', '{$APPTYPE CONSOLE}', [rfIgnoreCase]); - sFileContent:= StringReplace(sFileContent, 'Application.MainFormOnTaskbar:= True;', 'Application.MainFormOnTaskbar:= False;', [rfIgnoreCase]); - sFileContent:= StringReplace(sFileContent, '{Server}', 'TD2BridgeServerConsole.Run', [rfIgnoreCase]); - sFileContent:= StringReplace(sFileContent, '{Application.Run;}', '', [rfIgnoreCase]); - end; - - //Replace Language Support Resource - if (WizardForm.ComboBox_Enabled_Multi_Languages.Text = 'Yes') and (WizardForm.ComboBox_Embed_Translation_Files.Text = 'Yes') then - sFileContent:= StringReplace(sFileContent, '{Language Support Resource}', '{$R D2Bridge.Lang.APP.res D2Bridge.Lang.APP.rc}', [rfIgnoreCase]) - else - sFileContent:= StringReplace(sFileContent, '{Language Support Resource}', '', [rfIgnoreCase]); - - //Replace Language Support - sFileContent:= StringReplace(sFileContent, '{Language Support}', sLanguagesUnitsDPR.Text, [rfIgnoreCase]); - - sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppVCL', sProjectName, [rfIgnoreCase,rfReplaceAll]); - sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppFMX', sProjectName, [rfIgnoreCase,rfReplaceAll]); - sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppWithVCL', sProjectName, [rfIgnoreCase,rfReplaceAll]); - sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppWithFMX', sProjectName, [rfIgnoreCase,rfReplaceAll]); - sFileContent:= StringReplace(sFileContent, '{D2BridgePath}', IncludeTrailingPathDelimiter(WizardForm.Edit_Path_D2Bridge.Text), [rfIgnoreCase, rfReplaceAll]); - sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); - - //----- PrimaryForm / Class - sFileContent := StringReplace(sFileContent, '{PrimaryFormClass}', sClassPrimaryForm, [rfIgnoreCase, rfReplaceAll]); - sFileContent := StringReplace(sFileContent, '{PrimaryFormUnit}', sUnitPrimaryForm, [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(GetRealFilePath(sProjectNameLogical)); - sFile.Free; - {$ENDREGION} - - - - {$REGION 'Unit Server Properties'} - for var ServersFile in [sPathUnitServer,sPathUnitServiceServer] do - begin - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(ServersFile)); - sFileContent:= sFile.DataString; - - //----- PrimaryForm / Class - sFileContent := StringReplace(sFileContent, '{PrimaryFormClass}', sClassPrimaryForm, [rfIgnoreCase, rfReplaceAll]); - sFileContent := StringReplace(sFileContent, '{PrimaryFormUnit}', sUnitPrimaryForm, [rfIgnoreCase, rfReplaceAll]); - - //----- SSL - if WizardForm.ComboBox_UseSSL.Text = 'Yes' then - begin - sFileContent := StringReplace(sFileContent, '//D2BridgeServerController.Prism.Options.SSL:= true;', 'D2BridgeServerController.Prism.Options.SSL:= true;', [rfIgnoreCase]); - end; - sFileContent := StringReplace(sFileContent, '{Certificate}', WizardForm.Edit_SSL_Certificate.Text, [rfIgnoreCase]); - sFileContent := StringReplace(sFileContent, '{Certificate_Key}', WizardForm.Edit_SSL_Key.Text, [rfIgnoreCase]); - sFileContent := StringReplace(sFileContent, '{Certificate Intermediate}', WizardForm.Edit_SSL_Intermediate.Text, [rfIgnoreCase]); - sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); - - //----- Server Port - sFileContent := StringReplace(sFileContent, '{Server_Port}', WizardForm.Edit_Server_Port.Text, [rfIgnoreCase]); - - //----- Server Name - sFileContent := StringReplace(sFileContent, '{Server_Name}', WizardForm.Edit_Server_Name.Text, [rfIgnoreCase]); - - //----- Path JS - sFileContent := StringReplace(sFileContent, '{PathJS}', WizardForm.Edit_Path_JS.Text, [rfIgnoreCase]); - //----- Path CSS - sFileContent := StringReplace(sFileContent, '{PathCSS}', WizardForm.Edit_Path_CSS.Text, [rfIgnoreCase]); - - //----- Language - sFileContent := StringReplace(sFileContent, '{Languages}', '[' + sLanguagesSET.CommaText + ']', [rfIgnoreCase, rfReplaceAll]); - - //----- Options jQuery - sFileContent := StringReplace(sFileContent, '//D2BridgeServerController.Prism.Options.IncludeJQuery:= true;', 'D2BridgeServerController.Prism.Options.IncludeJQuery:= true;', [rfIgnoreCase]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(GetRealFilePath(ServersFile)); - sFile.Free; - end; - {$ENDREGION} - - - {$REGION 'Form Server Properties'} - if sPathDFMServer <> '' then - begin - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sPathDFMServer)); - sFileContent:= sFile.DataString; - - //----- SERVER PORT - sFileContent := StringReplace(sFileContent, '{Server_Port}', WizardForm.Edit_Server_Port.Text, [rfIgnoreCase]); - - //----- SERVER NAME - sFileContent := StringReplace(sFileContent, '{Server_Name}', WizardForm.Edit_Server_Name.Text, [rfIgnoreCase]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(GetRealFilePath(sPathDFMServer)); - sFile.Free; - end; - {$ENDREGION} - - - - {$REGION 'Unit Form1'} - sFile:= TStringStream.Create('', TEncoding.UTF8); - sFile.LoadFromFile(GetRealFilePath(sDestinationPathWeb + PathDelim + 'Unit1'+'.pas')); - sFileContent:= sFile.DataString; - - //----- Template HTML Files - sFileContent := StringReplace(sFileContent, '{TemplateMasterHTMLFile}', WizardForm.Edit_Template_Maste_Page.Text, [rfIgnoreCase]); - sFileContent := StringReplace(sFileContent, '{TemplateHTMLFile}', WizardForm.Edit_Template_Page.Text, [rfIgnoreCase]); - sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); - - //MainMenu - if WizardForm.RadioButton_Menu_SideBar.Checked and (WizardForm.ComboBox_Template.Text = 'None') then - sFileContent := StringReplace(sFileContent, '{MENU}', 'SideMenu(MainMenu1);', [rfIgnoreCase, rfReplaceAll]) - else - sFileContent := StringReplace(sFileContent, '{MENU}', 'VCLObj(MainMenu1);', [rfIgnoreCase, rfReplaceAll]); - - sFile.Clear; - sFile.WriteString(sFileContent); - sFile.SaveToFile(GetRealFilePath(sDestinationPathWeb + PathDelim + 'Unit1'+'.pas')); - sFile.Free; - {$ENDREGION} - - - - with WizardForm.TemplatesList.Items[WizardForm.ComboBox_Template.ItemIndex] do - begin - if TemplateFilePath <> '' then - begin - if Zipped then - begin - {$IFDEF FPC}ExtractZipFile{$ELSE}TZipFile.ExtractZipFile{$ENDIF}(GetRealFilePath(sPathWizard + PathDelim + TemplateFilePath), sPathwwwroot); - end; - end; - - end; - -{$IFDEF FPC} - PathPROJ:= sPathWEBDPROJFile; -{$ELSE} - services := (BorlandIDEServices as IOTAModuleServices); - services.OpenModule(PChar(sProjectNameLogical)); -{$ENDIF} - - - //Project.geterverStarter.pas'; -{$IFDEF FPC} - MessageDlg('The Lazarus Web project was created Successfully!', mtinformation, [mbok], 0); -{$ELSE} - MessageDlg('The Delphi Web project was created Successfully!', mtinformation, [mbok], 0); -{$ENDIF} - end; - finally - if WizardForm.EnableCreateProject then - begin - FreeAndNil(sLanguagesUnitsDPR); - FreeAndNil(sLanguagesJSON); - FreeAndNil(sLanguagesUSES); - FreeAndNil(sLanguagesCREATE); - FreeAndNil(sLanguagesDESTROY); - FreeAndNil(sLanguagesSET); - FreeAndNil(sUNITs); - //WizardForm.Free; - end; - end; -end; - -end. +{ + +--------------------------------------------------------------------------+ + D2Bridge Framework Content + + Author: Talis Jonatas Gomes + Email: talisjonatas@me.com + + Copyright (c) 2024 Talis Jonatas Gomes - talisjonatas@me.com + Intellectual property of computer programs protected by international and + brazilian (9.609/1998) laws. + Software licensed under "opensource" license. + + Rules: + Everone is permitted to copy and distribute verbatim copies of this license + document, but changing it is not allowed. + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this code. + + However, it is granted that this code may be used for any purpose, + including commercial applications, but it may not be modified, + distributed, or sublicensed without express written authorization from + the author (Talis Jonatas Gomes). This includes creating derivative works + or distributing the source code through any means. + + If you use this software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + + God bless you + +--------------------------------------------------------------------------+ +} + +unit D2Bridge.NewProject.Wizard.Common; + +{$IFDEF FPC} + {$MODE Delphi} + //{$DEFINE LCLLIB} +{$ELSE} + {$DEFINE DELPHI} +{$ENDIF} + + + +interface + +Uses +{$IFDEF FPC} + FileUtil, {$IFDEF LCLLIB}ProjectIntf,{$ENDIF} +{$ELSE} + Winapi.Windows, ToolsAPI, System.Zip, System.IOUtils, DateUtils, +{$ENDIF} + Classes, SysUtils, Forms, Dialogs, D2Bridge.ConfigNewProject.View; + + +type + TTypeServer = + ({$IFDEF DELPHI}tsWebFMX,tsWebAndFMX,{$ENDIF} + {$IFDEF FPC}tsWebLCL{$ELSE}tsWebVCL{$ENDIF}, + {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF}); + +type + + { TD2BridgeNewProjectWizardCommon } + + TD2BridgeNewProjectWizardCommon = class + private +{$IFDEF FPC} +{$IFDEF LCLLIB} + //FLazProject: TLazProject; +{$ENDIF} +{$ENDIF} + public + WizardForm: TD2BridgeConfigNewProject; + PathPROJ: string; + + constructor Create; + destructor Destroy; override; + +{$IFDEF FPC} +{$IFDEF LCLLIB} + //property LazProject: TLazProject read FLazProject write FLazProject; +{$ENDIF} +{$ENDIF} + + procedure Execute; + end; + +implementation + +Uses + D2Bridge.Wizard.Util, + D2Bridge.Lang.Util; + + +{ TD2BridgeNewProjectWizardCommon } + +constructor TD2BridgeNewProjectWizardCommon.Create; +begin + inherited; + + PathPROJ:= ''; + WizardForm:= TD2BridgeConfigNewProject.Create(Application); +end; + +destructor TD2BridgeNewProjectWizardCommon.Destroy; +begin + if Assigned(WizardForm) then + FreeAndNil(WizardForm); + + inherited Destroy; +end; + +{ +DELHI LAZARUS TIPO DE ARQUIVO +.DPR .LPR Arquivo principal do projeto. Contém o ponto de entrada do programa. +.DPROJ .LPI Arquivo do projeto que contém configurações específicas do Lazarus, equivalente ao .dproj no Delphi. +.RES .LRS ou .RES Arquivo de recursos. Lazarus usa .lrs gerado pelo Lazarus Resource Editor, mas também pode usar .res. +.DFM .LFM Arquivo de descrição do formulário. Em Lazarus, os formulários são descritos no formato .lfm. +.PAS .PAS Arquivo de código-fonte Pascal. O código .pas é idêntico tanto no Delphi quanto no Lazarus. +} + +procedure TD2BridgeNewProjectWizardCommon.Execute; +var + I: Integer; +{$IFDEF DELPHI} + services: IOTAModuleServices; + sSourceWebFMXDPROJFile, sSourceFMXDPROJFile: string; + sSourceWebFMXDPRFile, sSourceFMXDPRFile: string; + sSourceWebFMXRESFile, sSourceFMXRESFile: string; +{$ENDIF} +{$IFDEF FPC} + sSourceFixD2BridgeLazCompile, sSourceFixD2BridgeLazBuild: string; +{$ENDIF} + sProjectNameLogical,sTyperProject,sProjectName,sDestinationPath,sSourceFiles:string; + sDestinationPathWeb, sDestinationPathBinWeb, sDestinationPathCommonUnit,sD2BridgeFrameworkSearchPath,sD2BridgeFrameworkPath: String; + sD2BridgeDirectives: TStrings; + sLangCode, sLangCodeUnderline: string; + sLanguageUnitSourcePath: string; + sLanguageJSONPath: string; + sLanguagesUnitsDPR, sLanguagesJSON, sLanguagesUSES, sLanguagesCREATE, sLanguagesDESTROY, sLanguagesSET, sUNITs: TStrings; + sPathBINWEB, sPathBIN: string; + sPathwwwroot: string; + sPathWEBDPROJFile, sPathWEBRESFile, sPathWEBICOFile, sPathWizard, sPathUnitBase, sPathUnitServer, sPathDFMServer: string; + sPathUnitServiceServer : string; + sSourceWebVCLDPROJFile, sSourceVCLDPROJFile: string; + sSourceWebDPRFile, sSourceVCLDPRFile: string; + sSourceWebRESFile, sSourceVCLRESFile: string; + sSourceWebICOFile, sSourceVCLICOFile: string; + sFileContent: string; + sFile: TStringStream; + sClassPrimaryForm, sUnitPrimaryForm: string; + sUnitLogin, sFormLogin: string; + sTypeServer: TTypeServer; + sRESTAPIServerUnitAuthFile, sRESTAPIServerUnitPingFile: string; + sRESTAPIServerUnitAuthClassFile, sRESTAPIServerUnitPingClassFile: string; + sRESTAPIServerSessionFile: string; + G: TGUID; +begin + try + WizardForm.ShowModal; + if WizardForm.EnableCreateProject then + begin + + //----- PROJECT TYPE +{$IFDEF FPC} + if WizardForm.ComboBox_Platform.Text = 'LCL for WEB' then + begin + if WizardForm.CheckBox_Add_Project_Platform.Checked then + sTypeServer:= tsWebAndLCL + else + sTypeServer:= tsWebLCL; + end; +{$ELSE} + if WizardForm.ComboBox_Platform.Text = 'VCL for WEB' then + begin + if WizardForm.CheckBox_Add_Project_Platform.Checked then + sTypeServer:= tsWebAndVCL + else + sTypeServer:= tsWebVCL; + end else + begin + if WizardForm.CheckBox_Add_Project_Platform.Checked then + sTypeServer:= tsWebAndFMX + else + sTypeServer:= tsWebFMX; + end; +{$ENDIF} + + //D2Bridge Framework Path + sD2BridgeFrameworkPath:= ExcludeTrailingPathDelimiter(WizardForm.Edit_Path_D2Bridge.Text); + sD2BridgeFrameworkSearchPath:= WizardForm.Edit_Path_D2Bridge.Text+';'+WizardForm.Edit_Path_D2Bridge.Text+'Prism'+';'+WizardForm.Edit_Path_D2Bridge.Text+'Others VCL'+';'; + + sProjectName := WizardForm.Edit_ProjectName.Text; + + sPathWizard:= ExtractFileDir(ExcludeTrailingPathDelimiter(WizardForm.Edit_Path_D2Bridge.Text))+ PathDelim + 'Wizard'; + sPathUnitBase:= ExtractFileDir(ExcludeTrailingPathDelimiter(WizardForm.Edit_Path_D2Bridge.Text))+ PathDelim + 'Unit Base'; + +{$IFDEF FPC} + sSourceWebVCLDPROJFile:= sPathWizard + PathDelim + 'dpr'+ PathDelim + 'LAZARUS'+ PathDelim + 'D2BridgeWebAppLCL.lpi'; +{$ELSE} + sSourceWebVCLDPROJFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppVCL.dproj'; +{$ENDIF} + +{$IFDEF DELPHI} + sSourceWebFMXDPROJFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppFMX.dproj'; +{$ENDIF} + +{$IFDEF FPC} + sSourceVCLDPROJFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppWithLCL.lpi'; +{$ELSE} + sSourceVCLDPROJFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppWithVCL.dproj'; +{$ENDIF} + +{$IFDEF DELPHI} + sSourceFMXDPROJFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppWithFMX.dproj'; +{$ENDIF} + +{$IFDEF FPC} + sSourceWebDPRFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppLCL.lpr'; +{$ELSE} + sSourceWebDPRFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppVCL.dpr'; +{$ENDIF} + +{$IFDEF DELPHI} + sSourceWebFMXDPRFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppFMX.dpr'; +{$ENDIF} + +{$IFDEF FPC} + sSourceVCLDPRFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppWithLCL.lpr'; +{$ELSE} + sSourceVCLDPRFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppWithVCL.dpr'; +{$ENDIF} + +{$IFDEF DELPHI} + sSourceFMXDPRFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppWithFMX.dpr'; +{$ENDIF} + +{$IFDEF FPC} + sSourceWebRESFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppLCL.res'; +{$ELSE} + sSourceWebRESFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppVCL.res'; +{$ENDIF} + +{$IFDEF FPC} + sSourceWebICOFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppLCL.ico'; +{$ELSE} + sSourceWebICOFile:= sPathWizard + '\dpr\' + 'D2BridgeApp.ico'; +{$ENDIF} + +{$IFDEF DELPHI} + sSourceWebFMXRESFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppFMX.res'; +{$ENDIF} + +{$IFDEF FPC} + sSourceVCLRESFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + '' + 'D2BridgeWebAppWithLCL.res'; +{$ELSE} + sSourceVCLRESFile:= sPathWizard + '\dpr\' + 'D2BridgeWebAppWithVCL.res'; +{$ENDIF} + +{$IFDEF FPC} + sSourceVCLICOFile:= sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'D2BridgeWebAppWithLCL.ico'; +{$ELSE} + sSourceVCLICOFile:= sPathWizard + '\dpr\' + 'D2BridgeApp.ico'; +{$ENDIF} + +{$IFDEF DELPHI} + sSourceFMXRESFile:= sPathWizard + '\dpr\FMX\' + 'D2BridgeWebAppWithFMX.res'; +{$ENDIF} + +{$IFDEF FPC} + + {$IFDEF MSWINDOWS} + sSourceFixD2BridgeLazCompile := sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'FixD2BridgeLazCompile.bat'; + sSourceFixD2BridgeLazBuild := sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'FixD2BridgeLazBuild.bat'; + {$ELSE} + sSourceFixD2BridgeLazCompile := sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'FixD2BridgeLazCompile.sh'; + sSourceFixD2BridgeLazBuild := sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + 'FixD2BridgeLazBuild.sh'; + {$ENDIF} +{$ENDIF} + + if WizardForm.CheckBox_Create_Project_Folder.Checked then + sDestinationPath := PChar(WizardForm.Edit_ProjectDestination.Text+sProjectName) + else + sDestinationPath := PChar(WizardForm.Edit_ProjectDestination.Text); + + sDestinationPathWeb := sDestinationPath; + sDestinationPathCommonUnit:= sDestinationPath; + + sDestinationPathBinWeb := sDestinationPathWeb + PathDelim + 'Web'; + sPathwwwroot := sDestinationPathBinWeb + PathDelim + 'wwwroot'; + + sProjectNameLogical:= sDestinationPathWeb+ PathDelim +sProjectName+{$IFDEF FPC}'.lpr'{$ELSE}'.dpr'{$ENDIF}; + sPathWEBDPROJFile:= sDestinationPathWeb+ PathDelim +sProjectName+{$IFDEF FPC}'.lpi'{$ELSE}'.dproj'{$ENDIF}; + sPathWEBRESFile:= sDestinationPathWeb+ PathDelim +sProjectName+{$IFDEF FPC}'.res'{$ELSE}'.res'{$ENDIF}; + sPathWEBICOFile:= sDestinationPathWeb+ PathDelim +sProjectName+{$IFDEF FPC}'.ico'{$ELSE}'.ico'{$ENDIF}; + + sLanguageUnitSourcePath:= sPathWizard + PathDelim + 'Lang Support' + PathDelim + 'D2Bridge.Lang.APP.Language.pas'; + + sLanguageJSONPath:= sPathWizard + PathDelim + 'Lang Support' + PathDelim + 'lang'; + + //REST API Server + sRESTAPIServerUnitAuthClassFile:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Wizard' + PathDelim + 'RestAPIAuthClass' + {$IFDEF FPC} '.Laz' +{$ENDIF} '.pas'; + sRESTAPIServerUnitAuthFile:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Wizard' + PathDelim + 'RestAPIAuth' + {$IFDEF FPC} '.Laz' +{$ENDIF} '.pas'; + sRESTAPIServerUnitPingClassFile:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Wizard' + PathDelim + 'RestAPIUnitClass' + {$IFDEF FPC} '.Laz' +{$ENDIF} '.pas'; + sRESTAPIServerUnitPingFile:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Wizard' + PathDelim + 'RestAPIUnit' + {$IFDEF FPC} '.Laz' +{$ENDIF} '.pas'; + sRESTAPIServerSessionFile:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Wizard' + PathDelim + 'D2Bridge.Rest.Session.pas'; + + sClassPrimaryForm:= 'TForm1'; + sUnitPrimaryForm:= 'Unit1'; + + sUNITs:= TStringList.Create; +{$IFDEF FPC} + sUnitLogin:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Native' + PathDelim + 'Lazarus' + PathDelim + 'Login' + PathDelim + 'Unit_Login.pas'; + sFormLogin:= sPathWizard + PathDelim + 'FORMS' + PathDelim + 'Native' + PathDelim + 'Lazarus' + PathDelim + 'Login' + PathDelim + 'Unit_Login.lfm'; +{$ELSE} + if (sTypeServer = tsWebFMX) or (sTypeServer = tsWebAndFMX) then + begin + sUnitLogin:= sPathWizard + '\FORMS\Native\FMX\Login\Unit_Login.pas'; + sFormLogin:= sPathWizard + '\FORMS\Native\FMX\Login\Unit_Login.fmx'; + end else + begin + sUnitLogin:= sPathWizard + '\FORMS\Native\Login\Unit_Login.pas'; + sFormLogin:= sPathWizard + '\FORMS\Native\Login\Unit_Login.dfm'; + end; +{$ENDIF} + + //----- D2Bridge Directives + sD2BridgeDirectives:= TStringList.Create; + sD2BridgeDirectives.LineBreak:= ';'; + sD2BridgeDirectives.Add('D2Bridge'); +{$IFDEF DELPHI} + if sTypeServer in [tsWebFMX, tsWebAndFMX] then + sD2BridgeDirectives.Add('FMX'); +{$ENDIF} + if WizardForm.CheckListBox_ThirdParty.Checked[WizardForm.CheckListBox_ThirdParty.Items.IndexOf('RXLIB')] then + sD2BridgeDirectives.Add('RXLIB_AVAILABLE'); + if WizardForm.CheckListBox_ThirdParty.Checked[WizardForm.CheckListBox_ThirdParty.Items.IndexOf('SMComponents')] then + sD2BridgeDirectives.Add('SMCOMPONENTS_AVAILABLE'); + if WizardForm.CheckListBox_ThirdParty.Checked[WizardForm.CheckListBox_ThirdParty.Items.IndexOf('DevExpress')] then + sD2BridgeDirectives.Add('DEVEXPRESS_AVAILABLE'); + if WizardForm.CheckListBox_ThirdParty.Checked[WizardForm.CheckListBox_ThirdParty.Items.IndexOf('JVCL')] then + sD2BridgeDirectives.Add('JVCL_AVAILABLE'); + + + //----- CREATE PROJECT DIRECTORY + If not DirectoryExists(sDestinationPath) then + MKdir(sDestinationPath); + If not DirectoryExists(sDestinationPathWeb) then + MKdir(sDestinationPathWeb); + If not DirectoryExists(sDestinationPathWeb + PathDelim + 'Web') then + MKdir(sDestinationPathWeb + PathDelim + 'Web'); + If not DirectoryExists(sPathwwwroot) then + MKdir(sPathwwwroot); + if WizardForm.ComboBox_Enabled_Multi_Languages.Text = 'Yes' then + If not DirectoryExists(sDestinationPathBinWeb+ PathDelim + 'lang') then + MKdir(sDestinationPathBinWeb+ PathDelim + 'lang'); + +// //----- COPY DPR +// if sTypeServer = {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF} then +// {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceVCLDPRFile, sProjectNameLogical, false) +// else +//{$IFDEF DELPHI} +// if sTypeServer = tsWebAndFMX then +// CopyFile(PWideChar(sSourceFMXDPRFile), PWideChar(sProjectNameLogical), false) +// else +// if sTypeServer = tsWebFMX then +// CopyFile(PWideChar(sSourceWebFMXDPRFile), PWideChar(sProjectNameLogical), false) +// else +//{$ENDIF} +// {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceWebDPRFile, sProjectNameLogical, false); + + //----- COPY RES + if FileExists(sSourceWebRESFile) then + begin + if sTypeServer = {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF} then + {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceVCLRESFile, sPathWEBRESFile, false) + else +{$IFDEF DELPHI} + if sTypeServer = tsWebAndFMX then + CopyFile(PWideChar(sSourceFMXRESFile), PWideChar(sPathWEBRESFile), false) + else + if sTypeServer = tsWebFMX then + CopyFile(PWideChar(sSourceWebFMXRESFile), PWideChar(sPathWEBRESFile), false) + else +{$ENDIF} + {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceWebRESFile, sPathWEBRESFile, false); + end; + + //----- COPY ICO + if FileExists(sSourceVCLICOFile) then + begin + if sTypeServer = {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF} then + {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceVCLICOFile, sPathWEBICOFile, false) + else +{$IFDEF DELPHI} + if sTypeServer = tsWebAndFMX then + CopyFile(PWideChar(sSourceFMXRESFile), PWideChar(sPathWEBICOFile), false) + else + if sTypeServer = tsWebFMX then + CopyFile(PWideChar(sSourceWebFMXRESFile), PWideChar(sPathWEBICOFile), false) + else +{$ENDIF} + {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceWebICOFile, sPathWEBICOFile, false); + end; + +{$IFDEF FPC} + if sTypeServer in [tsWebLCL, tsWebAndLCL] then + begin + //----- COPY .PAS + CopyFolderFiles(sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + '*.pas', sDestinationPathWeb); + //----- COPY .DFM + CopyFolderFiles(sPathWizard + PathDelim + 'dpr' + PathDelim + 'LAZARUS' + PathDelim + '*.lfm', sDestinationPathWeb); + end; +{$ELSE} + if sTypeServer in [tsWebFMX, tsWebAndFMX] then + begin + //----- COPY .PAS + CopyFolderFiles(PWideChar(sPathWizard+'\dpr\FMX\*.pas'), sDestinationPathWeb); + //----- COPY .DFM + CopyFolderFiles(PWideChar(sPathWizard+'\dpr\FMX\*.fmx'), sDestinationPathWeb); + end else + begin + //----- COPY .PAS + CopyFolderFiles(PWideChar(sPathWizard+'\dpr\*.pas'), sDestinationPathWeb); + //----- COPY .DFM + CopyFolderFiles(PWideChar(sPathWizard+'\dpr\*.dfm'), sDestinationPathWeb); + end; +{$ENDIF} + + +//----- COPY FixD2BridgeLazBuild +{$IFDEF FPC} + CopyFolderFiles(sSourceFixD2BridgeLazBuild, sDestinationPathWeb); + CopyFolderFiles(sSourceFixD2BridgeLazCompile, sDestinationPathWeb); +{$ENDIF} + + + {$REGION 'Language Support'} + sLanguagesUnitsDPR:= TStringList.Create; + sLanguagesJSON:= TStringList.Create; + sLanguagesUSES:= TStringList.Create; + sLanguagesCREATE:= TStringList.Create; + sLanguagesDESTROY:= TStringList.Create; + sLanguagesSET:= TStringList.Create; + if WizardForm.ComboBox_Enabled_Multi_Languages.Text = 'Yes' then + begin + {$REGION 'Prepare Units Name to DPR'} + sLanguagesUnitsDPR.Add(' D2Bridge.Lang.APP.Core in ''D2Bridge.Lang.APP.Core.pas'','); + sLanguagesUnitsDPR.Add(' D2Bridge.Lang.APP.Term in ''D2Bridge.Lang.APP.Term.pas'','); + {$ENDREGION} + + + {$REGION 'Copy Language Support UNITs'} + {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF} + (sPathWizard + PathDelim + 'Lang Support' + PathDelim + 'D2Bridge.Lang.APP.Term.pas', sDestinationPathWeb + PathDelim + 'D2Bridge.Lang.APP.Term.pas', false); + {$ENDREGION} + + {$REGION 'Copy Languages Units'} + sLanguagesDESTROY.Add('{$IFNDEF D2WindowsService}'); + for I := 0 to Pred(WizardForm.CheckListBox_Languages.Count) do + if WizardForm.CheckListBox_Languages.Checked[I] then + begin + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sLanguageUnitSourcePath)); + sFileContent:= sFile.DataString; + + sFileContent:= StringReplace(sFileContent, '{Language}', WizardForm.CheckListBox_Languages.Items[I], [rfIgnoreCase, rfReplaceAll]); + + //Add Unit in Project + sLanguagesUnitsDPR.Add(' D2Bridge.Lang.APP.' + WizardForm.CheckListBox_Languages.Items[I] + ' in ''D2Bridge.Lang.APP.' + WizardForm.CheckListBox_Languages.Items[I] + '.pas'','); + //Add Language Code JSON + sLangCode:= LanguageCode(D2BridgeLangbyLanguageName(WizardForm.CheckListBox_Languages.Items[I])); + sLangCodeUnderline:= StringReplace(sLangCode, '-', '_', []); + if WizardForm.ComboBox_Embed_Translation_Files.Text = 'Yes' then //Embed JSON + sLanguagesJSON.Add('D2Bridge_Lang_APP_' + sLangCodeUnderline + ' RCDATA "lang\\'+ sLangCode +'.json"'); + + {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF} + (sLanguageJSONPath + PathDelim + 'language.json', + sDestinationPathBinWeb + PathDelim + 'lang' + PathDelim + sLangCode + '.json', false); + //Add USES language + sLanguagesUSES.Add(' D2Bridge.Lang.APP.' + WizardForm.CheckListBox_Languages.Items[I]+','); + //Add Language Create + sLanguagesCREATE.Add(' ' + WizardForm.CheckListBox_Languages.Items[I] + ':= ' + 'TD2BridgeLangAPP' + WizardForm.CheckListBox_Languages.Items[I] + '.Create(self, TD2BridgeAPPTerm);'); + //Add Language Destroy + sLanguagesDESTROY.Add(' TD2BridgeLangAPP' + WizardForm.CheckListBox_Languages.Items[I] + '('+ WizardForm.CheckListBox_Languages.Items[I] +').Destroy;'); + //Add Set Languages + sLanguagesSET.Add('TD2BridgeLang.' + WizardForm.CheckListBox_Languages.Items[I]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(sDestinationPathWeb + PathDelim + 'D2Bridge.Lang.APP.'+WizardForm.CheckListBox_Languages.Items[I]+'.pas'); + sFile.Free; + end; + sLanguagesDESTROY.Add('{$ENDIF}'); + {$ENDREGION} + + {$REGION 'Copy D2Bridge.Lang.APP.Core'} + for I := 0 to Pred(WizardForm.CheckListBox_Languages.Count) do + if WizardForm.CheckListBox_Languages.Checked[I] then + begin + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sPathWizard + PathDelim + 'Lang Support' + PathDelim + 'D2Bridge.Lang.APP.Core.pas')); + sFileContent:= sFile.DataString; + + sFileContent:= StringReplace(sFileContent, '{Uses_Languages}', sLanguagesUSES.Text, [rfIgnoreCase, rfReplaceAll]); + sFileContent:= StringReplace(sFileContent, '{Create_Languages}', sLanguagesCREATE.Text, [rfIgnoreCase, rfReplaceAll]); + sFileContent:= StringReplace(sFileContent, '{Destroy_Languages}', sLanguagesDESTROY.Text, [rfIgnoreCase, rfReplaceAll]); + + if WizardForm.ComboBox_Embed_Translation_Files.Text = 'No' then + sFileContent:= StringReplace(sFileContent, '{EmbedJSON}', 'false', [rfIgnoreCase, rfReplaceAll]) + else + sFileContent:= StringReplace(sFileContent, '{EmbedJSON}', 'true', [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(sDestinationPathWeb + PathDelim + 'D2Bridge.Lang.APP.Core.pas'); + sFile.Free; + end; + {$ENDREGION} + + {$REGION 'Copy Language RC File'} + if WizardForm.ComboBox_Embed_Translation_Files.Text = 'Yes' then //Embed JSON + for I := 0 to Pred(WizardForm.CheckListBox_Languages.Count) do + if WizardForm.CheckListBox_Languages.Checked[I] then + begin + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFileContent:= sLanguagesJSON.Text; + + sFileContent:= StringReplace(sFileContent, '{Language}', WizardForm.CheckListBox_Languages.Items[I], [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(sDestinationPathWeb + PathDelim + 'D2Bridge.Lang.APP.rc'); + sFile.Free; + end; + {$ENDREGION} + end else + begin + sLanguagesSET.Add('TD2BridgeLang.' + WizardForm.ComboBox_Language.Text); + end; + {$ENDREGION} + + + {$REGION 'UNIT BASE'} + {$REGION 'ServerController.pas'} + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sPathUnitBase + PathDelim + 'ServerController.pas')); + sFileContent:= sFile.DataString; + + sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(sDestinationPathWeb + PathDelim + sProjectName + 'WebApp.pas'); + sFile.Free; + {$ENDREGION} + + {$REGION 'ServerController.dfm'} + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sPathUnitBase+{$IFDEF FPC} PathDelim + 'ServerController.lfm'{$ELSE}'\ServerController.dfm'{$ENDIF})); + sFileContent:= sFile.DataString; + + sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(sDestinationPathWeb+ PathDelim + sProjectName+{$IFDEF FPC}'WebApp.lfm'{$ELSE}'WebApp.dfm'{$ENDIF}); + sFile.Free; + {$ENDREGION} + + {$REGION 'UserSessionUnit.pas'} + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sPathUnitBase + PathDelim + 'UserSessionUnit.pas')); + sFileContent:= sFile.DataString; + + sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(sDestinationPathWeb + PathDelim + sProjectName+'_Session.pas'); + sFile.Free; + {$ENDREGION} + + {$REGION 'UserSessionUnit.dfm'} + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sPathUnitBase + {$IFDEF FPC} PathDelim + 'UserSessionUnit.lfm'{$ELSE}'\UserSessionUnit.dfm'{$ENDIF})); + sFileContent:= sFile.DataString; + + sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(sDestinationPathWeb + PathDelim + sProjectName+{$IFDEF FPC}'_Session.lfm'{$ELSE}'_Session.dfm'{$ENDIF}); + sFile.Free; + {$ENDREGION} + + {$REGION 'D2BridgeFormTemplate.pas'} + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sPathUnitBase + PathDelim + 'D2BridgeFormTemplate.pas')); + sFileContent:= sFile.DataString; + + sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(sDestinationPathWeb + PathDelim + 'D2BridgeFormTemplate.pas'); + sFile.Free; + {$ENDREGION} + {$ENDREGION} + + + + {$REGION 'Login'} + if WizardForm.CheckBox_Form_Login.Checked then + begin + {$IFDEF FPC} + CopyFolderFiles(sUnitLogin, sDestinationPathWeb); + CopyFolderFiles(sFormLogin, sDestinationPathWeb); + {$ELSE} + CopyFolderFiles(PWideChar(sUnitLogin), sDestinationPathWeb); + CopyFolderFiles(PWideChar(sFormLogin), sDestinationPathWeb); + {$ENDIF} + + //Set Primary Form + sClassPrimaryForm:= 'TForm_Login'; + sUnitPrimaryForm:= 'Unit_Login'; + + //Unit Login + sUNITs.Add('Unit_Login in ''Unit_Login.pas'' {Form_Login},'); + + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sDestinationPathWeb + PathDelim + ExtractFileName(sUnitLogin))); + sFileContent:= sFile.DataString; + + //----- Template HTML Files + sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(sDestinationPathWeb + PathDelim + ExtractFileName(sUnitLogin))); + sFile.Free; + end; + {$ENDREGION} + + + + {$REGION 'REST SERVER API'} + if (WizardForm.ComboBox_RestAPIServer.ItemIndex = 0) or (WizardForm.ComboBox_RestAPIServer.ItemIndex = 1) then //Auth + begin + {$REGION 'AUTH CLASS FILE'} + if Pos(UpperCase('Includes Authentication'), UpperCase(WizardForm.ComboBox_RestAPIServer.Text)) > 0 then + begin + sFile:= TStringStream.Create('', TEncoding.UTF8); + if WizardForm.CheckBox_RestAPIServer_UseClass.Checked then //Use Classes in API + sFile.LoadFromFile(GetRealFilePath(sRESTAPIServerUnitAuthClassFile)) + else + sFile.LoadFromFile(GetRealFilePath(sRESTAPIServerUnitAuthFile)); + sFileContent:= sFile.DataString; + + sFileContent := StringReplace(sFileContent, '<UNITNAME>', 'API.Auth', [rfIgnoreCase, rfReplaceAll]); + sFileContent := StringReplace(sFileContent, '<COPYRIGHTYEAR>', IntToStr(CurrentYear), [rfIgnoreCase, rfReplaceAll]); + sFileContent := StringReplace(sFileContent, '<ServerController>', sProjectName + 'WebApp', [rfIgnoreCase, rfReplaceAll]); + sFileContent := StringReplace(sFileContent, '<CLASS_ID>', 'APIAuth', [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(sDestinationPathWeb+ PathDelim + 'API.Auth.pas')); + sFile.Free; + end; + {$ENDREGION} + + + {$REGION 'PING CLASS FILE'} + sFile:= TStringStream.Create('', TEncoding.UTF8); + if WizardForm.CheckBox_RestAPIServer_UseClass.Checked then //Use Classes in API + sFile.LoadFromFile(GetRealFilePath(sRESTAPIServerUnitPingClassFile)) + else + sFile.LoadFromFile(GetRealFilePath(sRESTAPIServerUnitPingFile)); + sFileContent:= sFile.DataString; + + sFileContent := StringReplace(sFileContent, '<UNITNAME>', 'API.Ping', [rfIgnoreCase, rfReplaceAll]); + sFileContent := StringReplace(sFileContent, '<COPYRIGHTYEAR>', IntToStr(CurrentYear), [rfIgnoreCase, rfReplaceAll]); + sFileContent := StringReplace(sFileContent, '<ServerController>', sProjectName + 'WebApp', [rfIgnoreCase, rfReplaceAll]); + sFileContent := StringReplace(sFileContent, '<CLASS_ID>', 'APIPing', [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(sDestinationPathWeb+ PathDelim + 'API.Ping.pas')); + sFile.Free; + {$ENDREGION} + + + {$REGION 'SESSION FILE'} + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sRESTAPIServerSessionFile)); + sFileContent:= sFile.DataString; + + sFileContent := StringReplace(sFileContent, '<COPYRIGHTYEAR>', IntToStr(CurrentYear), [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(sDestinationPathWeb+ PathDelim + 'D2Bridge.Rest.Session.pas')); + sFile.Free; + {$ENDREGION} + + sUNITs.Add(' API.Auth in ''API.Auth.pas'','); + sUNITs.Add(' API.Ping in ''API.Ping.pas'','); + sUNITs.Add(' D2Bridge.Rest.Session in ''D2Bridge.Rest.Session.pas'','); + end; + + {$ENDREGION} + + + + {$REGION 'WEB dpropj'} + //----- COPY DProj + if sTypeServer = {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF} then + {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceVCLDPROJFile, sPathWEBDPROJFile, false) + else +{$IFDEF DELPHI} + if sTypeServer = tsWebAndFMX then + CopyFile(PWideChar(sSourceFMXDPROJFile), PWideChar(sPathWEBDPROJFile), false) + else + if sTypeServer = tsWebFMX then + CopyFile(PWideChar(sSourceWebFMXDPROJFile), PWideChar(sPathWEBDPROJFile), false) + else +{$ENDIF} + {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceWebVCLDPROJFile, sPathWEBDPROJFile, false); + + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sPathWEBDPROJFile)); + sFileContent:= sFile.DataString; + + sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppVCL', sProjectName, [rfIgnoreCase,rfReplaceAll]); + sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppFMX', sProjectName, [rfIgnoreCase,rfReplaceAll]); + sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppWithVCL', sProjectName, [rfIgnoreCase,rfReplaceAll]); + sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppWithFMX', sProjectName, [rfIgnoreCase,rfReplaceAll]); + sFileContent := StringReplace(sFileContent, '{D2BridgeFrameworkPath}', sD2BridgeFrameworkSearchPath, [rfIgnoreCase,rfReplaceAll]); + sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); + sFileContent:= StringReplace(sFileContent, '{D2BridgeDirectives}', sD2BridgeDirectives.Text, [rfIgnoreCase, rfReplaceAll]); + sFileContent:= StringReplace(sFileContent, '{D2BridgePath}', IncludeTrailingPathDelimiter(WizardForm.Edit_Path_D2Bridge.Text), [rfIgnoreCase, rfReplaceAll]); + sFileContent:= StringReplace(sFileContent, '{PathDelim}', PathDelim, [rfIgnoreCase, rfReplaceAll]); + + {$IFDEF MSWINDOWS} + sFileContent:= StringReplace(sFileContent, '{FixD2BridgeLazBuild}', 'FixD2BridgeLazBuild.bat', [rfIgnoreCase, rfReplaceAll]); + sFileContent:= StringReplace(sFileContent, '{FixD2BridgeLazCompile}', 'FixD2BridgeLazCompile.bat', [rfIgnoreCase, rfReplaceAll]); + {$ELSE} + sFileContent:= StringReplace(sFileContent, '{FixD2BridgeLazBuild}', 'sh FixD2BridgeLazBuild.sh', [rfIgnoreCase, rfReplaceAll]); + sFileContent:= StringReplace(sFileContent, '{FixD2BridgeLazCompile}', 'sh FixD2BridgeLazCompile.sh', [rfIgnoreCase, rfReplaceAll]); + {$ENDIF} + + CreateGUID(G); + sFileContent:= StringReplace(sFileContent, '{ProjectGUID}', GUIDToString(G), [rfIgnoreCase, rfReplaceAll]); + +{$IFDEF FPC} + if WizardForm.ComboBox_Server_Type.Text = 'Server Console (Recommended)' then + sFileContent:= StringReplace(sFileContent, '{D2BridgeServerUnit}', 'Unit_D2Bridge_Server_Console.pas', [rfIgnoreCase, rfReplaceAll]); +{$ENDIF} + + //Replace Language Support Resource + if (WizardForm.ComboBox_Enabled_Multi_Languages.Text = 'Yes') and (WizardForm.ComboBox_Embed_Translation_Files.Text = 'Yes') then + sFileContent:= StringReplace(sFileContent, '{Language Support Resource}', '<RcCompile Include="D2Bridge.Lang.APP.rc"><Form>D2Bridge.Lang.APP.res</Form></RcCompile>', [rfIgnoreCase]) + else + sFileContent:= StringReplace(sFileContent, '{Language Support Resource}', '', [rfIgnoreCase]); + + sFile.Clear; + sFile.WriteString(sFileContent); + SFile.SaveToFile(GetRealFilePath(sPathWEBDPROJFile)); + sFile.Free; + {$ENDREGION} + + + + {$REGION 'WEB dpr'} + {$IFDEF DELPHI} + CopyFolderFiles( + PWideChar(sPathWizard + PathDelim + 'Servers' + PathDelim + 'Service' + PathDelim + '*.*'), + sDestinationPathWeb + ); + + sPathUnitServer := sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Service.pas'; + sPathDFMServer := sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Service.dfm'; + + sFile := TStringStream.Create('', TEncoding.UTF8); + try + sFile.LoadFromFile(GetRealFilePath(sPathUnitServer)); + sFileContent := sFile.DataString; + + sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(sPathUnitServer)); + finally + sFile.Free; + end; + + sFile := TStringStream.Create('', TEncoding.UTF8); + try + sFile.LoadFromFile(GetRealFilePath(sPathDFMServer)); + sFileContent := sFile.DataString; + + sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(sPathDFMServer)); + finally + sFile.Free; + end; + + sPathUnitServiceServer := sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Core.pas'; + + sFile := TStringStream.Create('', TEncoding.UTF8); + try + sFile.LoadFromFile(GetRealFilePath(sPathUnitServiceServer)); + sFileContent := sFile.DataString; + + sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(sPathUnitServiceServer)); + finally + sFile.Free; + end; + {$ENDIF} + + if sTypeServer = {$IFDEF FPC}tsWebAndLCL{$ELSE}tsWebAndVCL{$ENDIF} then + {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceVCLDPRFile, sProjectNameLogical, false) + else + {$IFDEF DELPHI} + if sTypeServer = tsWebAndFMX then + CopyFile(PWideChar(sSourceFMXDPRFile), PWideChar(sProjectNameLogical), false) + else + if sTypeServer = tsWebFMX then + CopyFile(PWideChar(sSourceWebFMXDPRFile), PWideChar(sProjectNameLogical), false) + else + {$ENDIF} + {$IFDEF FPC}CopyFile{$ELSE}TFile.Copy{$ENDIF}(sSourceWebDPRFile, sProjectNameLogical, false); + + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sProjectNameLogical)); + sFileContent:= sFile.DataString; + + if WizardForm.ComboBox_Server_Type.Text = 'Server Complete' then + begin + sPathUnitServer:= sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server.pas'; + sPathDFMServer:= sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server.dfm'; + sUNITs.Add('Unit_D2Bridge_Server in ''Unit_D2Bridge_Server.pas'' {Form_D2Bridge_Server},'); + + CopyFolderFiles(PWideChar(sPathWizard + PathDelim + 'Servers\Complete\*.*'), sDestinationPathWeb); + + sFileContent:= StringReplace(sFileContent, '{Units}', sUNITs.Text, [rfIgnoreCase]); + sFileContent:= StringReplace(sFileContent, '{Server}', 'Application.CreateForm(TForm_D2Bridge_Server, Form_D2Bridge_Server);', []); + sFileContent:= StringReplace(sFileContent, '{Application.Run;}', 'Application.Run;', [rfIgnoreCase]); + end else + if WizardForm.ComboBox_Server_Type.Text = 'Server Compact' then + begin + sPathUnitServer:= sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Compact.pas'; + sPathDFMServer:= sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Compact.dfm'; + sUNITs.Add(' Unit_D2Bridge_Server_Compact in ''Unit_D2Bridge_Server_Compact.pas'' {Form_D2Bridge_Server_Compact},'); + + CopyFolderFiles(PWideChar(sPathWizard + PathDelim + 'Servers' + PathDelim + 'Compact' + PathDelim + '*.*'), sDestinationPathWeb); + + sFileContent:= StringReplace(sFileContent, '{Units}', sUNITs.Text, [rfIgnoreCase]); + sFileContent:= StringReplace(sFileContent, '{Server}', 'Application.CreateForm(TForm_D2Bridge_Server_Compact, Form_D2Bridge_Server_Compact);', []); + sFileContent:= StringReplace(sFileContent, '{Application.Run;}', 'Application.Run;', [rfIgnoreCase]); + end else + if WizardForm.ComboBox_Server_Type.Text = 'Server Console (Recommended)' then + begin + sPathUnitServer:= sDestinationPathWeb + PathDelim + 'Unit_D2Bridge_Server_Console.pas'; + sPathDFMServer:= ''; + sUNITs.Add('{$IFNDEF D2WindowsService}'); + sUNITs.Add('Unit_D2Bridge_Server_Console in ''Unit_D2Bridge_Server_Console.pas'','); + sUNITs.Add('{$ENDIF}'); +{$IFDEF FPC} + CopyFolderFiles(sPathWizard + PathDelim + 'Servers' + PathDelim + 'Console' + PathDelim + '*.*', sDestinationPathWeb); +{$ELSE} + CopyFolderFiles(PWideChar(sPathWizard+'\Servers\Console\*.*'), sDestinationPathWeb); +{$ENDIF} + + sFileContent:= StringReplace(sFileContent, '{Units}', sUNITs.Text, [rfIgnoreCase]); + sFileContent:= StringReplace(sFileContent, '//{$APPTYPE CONSOLE}', '{$APPTYPE CONSOLE}', [rfIgnoreCase]); + sFileContent:= StringReplace(sFileContent, 'Application.MainFormOnTaskbar:= True;', 'Application.MainFormOnTaskbar:= False;', [rfIgnoreCase]); + sFileContent:= StringReplace(sFileContent, '{Server}', 'TD2BridgeServerConsole.Run', [rfIgnoreCase]); + sFileContent:= StringReplace(sFileContent, '{Application.Run;}', '', [rfIgnoreCase]); + end; + + //Replace Language Support Resource + if (WizardForm.ComboBox_Enabled_Multi_Languages.Text = 'Yes') and (WizardForm.ComboBox_Embed_Translation_Files.Text = 'Yes') then + sFileContent:= StringReplace(sFileContent, '{Language Support Resource}', '{$R D2Bridge.Lang.APP.res D2Bridge.Lang.APP.rc}', [rfIgnoreCase]) + else + sFileContent:= StringReplace(sFileContent, '{Language Support Resource}', '', [rfIgnoreCase]); + + //Replace Language Support + sFileContent:= StringReplace(sFileContent, '{Language Support}', sLanguagesUnitsDPR.Text, [rfIgnoreCase]); + + sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppVCL', sProjectName, [rfIgnoreCase,rfReplaceAll]); + sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppFMX', sProjectName, [rfIgnoreCase,rfReplaceAll]); + sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppWithVCL', sProjectName, [rfIgnoreCase,rfReplaceAll]); + sFileContent := StringReplace(sFileContent, 'D2BridgeWebAppWithFMX', sProjectName, [rfIgnoreCase,rfReplaceAll]); + sFileContent:= StringReplace(sFileContent, '{D2BridgePath}', IncludeTrailingPathDelimiter(WizardForm.Edit_Path_D2Bridge.Text), [rfIgnoreCase, rfReplaceAll]); + sFileContent:= StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); + + //----- PrimaryForm / Class + sFileContent := StringReplace(sFileContent, '{PrimaryFormClass}', sClassPrimaryForm, [rfIgnoreCase, rfReplaceAll]); + sFileContent := StringReplace(sFileContent, '{PrimaryFormUnit}', sUnitPrimaryForm, [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(sProjectNameLogical)); + sFile.Free; + {$ENDREGION} + + + + {$REGION 'Unit Server Properties'} + {$IFDEF DELPHI} + for var ServersFile in [sPathUnitServer,sPathUnitServiceServer] do + begin + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(ServersFile)); + sFileContent:= sFile.DataString; + + //----- PrimaryForm / Class + sFileContent := StringReplace(sFileContent, '{PrimaryFormClass}', sClassPrimaryForm, [rfIgnoreCase, rfReplaceAll]); + sFileContent := StringReplace(sFileContent, '{PrimaryFormUnit}', sUnitPrimaryForm, [rfIgnoreCase, rfReplaceAll]); + + //----- SSL + if WizardForm.ComboBox_UseSSL.Text = 'Yes' then + begin + sFileContent := StringReplace(sFileContent, '//D2BridgeServerController.Prism.Options.SSL:= true;', 'D2BridgeServerController.Prism.Options.SSL:= true;', [rfIgnoreCase]); + end; + sFileContent := StringReplace(sFileContent, '{Certificate}', WizardForm.Edit_SSL_Certificate.Text, [rfIgnoreCase]); + sFileContent := StringReplace(sFileContent, '{Certificate_Key}', WizardForm.Edit_SSL_Key.Text, [rfIgnoreCase]); + sFileContent := StringReplace(sFileContent, '{Certificate Intermediate}', WizardForm.Edit_SSL_Intermediate.Text, [rfIgnoreCase]); + sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); + + //----- Server Port + sFileContent := StringReplace(sFileContent, '{Server_Port}', WizardForm.Edit_Server_Port.Text, [rfIgnoreCase]); + + //----- Server Name + sFileContent := StringReplace(sFileContent, '{Server_Name}', WizardForm.Edit_Server_Name.Text, [rfIgnoreCase]); + + //----- Path JS + sFileContent := StringReplace(sFileContent, '{PathJS}', WizardForm.Edit_Path_JS.Text, [rfIgnoreCase]); + //----- Path CSS + sFileContent := StringReplace(sFileContent, '{PathCSS}', WizardForm.Edit_Path_CSS.Text, [rfIgnoreCase]); + + //----- Language + sFileContent := StringReplace(sFileContent, '{Languages}', '[' + sLanguagesSET.CommaText + ']', [rfIgnoreCase, rfReplaceAll]); + + //----- Options jQuery + sFileContent := StringReplace(sFileContent, '//D2BridgeServerController.Prism.Options.IncludeJQuery:= true;', 'D2BridgeServerController.Prism.Options.IncludeJQuery:= true;', [rfIgnoreCase]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(ServersFile)); + sFile.Free; + end; + {$ELSE} + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sPathUnitServer)); + sFileContent:= sFile.DataString; + + //----- PrimaryForm / Class + sFileContent := StringReplace(sFileContent, '{PrimaryFormClass}', sClassPrimaryForm, [rfIgnoreCase, rfReplaceAll]); + sFileContent := StringReplace(sFileContent, '{PrimaryFormUnit}', sUnitPrimaryForm, [rfIgnoreCase, rfReplaceAll]); + + //----- SSL + if WizardForm.ComboBox_UseSSL.Text = 'Yes' then + begin + sFileContent := StringReplace(sFileContent, '//D2BridgeServerController.Prism.Options.SSL:= true;', 'D2BridgeServerController.Prism.Options.SSL:= true;', [rfIgnoreCase]); + end; + sFileContent := StringReplace(sFileContent, '{Certificate}', WizardForm.Edit_SSL_Certificate.Text, [rfIgnoreCase]); + sFileContent := StringReplace(sFileContent, '{Certificate_Key}', WizardForm.Edit_SSL_Key.Text, [rfIgnoreCase]); + sFileContent := StringReplace(sFileContent, '{Certificate Intermediate}', WizardForm.Edit_SSL_Intermediate.Text, [rfIgnoreCase]); + sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); + + //----- Server Port + sFileContent := StringReplace(sFileContent, '{Server_Port}', WizardForm.Edit_Server_Port.Text, [rfIgnoreCase]); + + //----- Server Name + sFileContent := StringReplace(sFileContent, '{Server_Name}', WizardForm.Edit_Server_Name.Text, [rfIgnoreCase]); + + //----- Path JS + sFileContent := StringReplace(sFileContent, '{PathJS}', WizardForm.Edit_Path_JS.Text, [rfIgnoreCase]); + //----- Path CSS + sFileContent := StringReplace(sFileContent, '{PathCSS}', WizardForm.Edit_Path_CSS.Text, [rfIgnoreCase]); + + //----- Language + sFileContent := StringReplace(sFileContent, '{Languages}', '[' + sLanguagesSET.CommaText + ']', [rfIgnoreCase, rfReplaceAll]); + + //----- Options jQuery + sFileContent := StringReplace(sFileContent, '//D2BridgeServerController.Prism.Options.IncludeJQuery:= true;', 'D2BridgeServerController.Prism.Options.IncludeJQuery:= true;', [rfIgnoreCase]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(sPathUnitServer)); + sFile.Free; + {$ENDIF} + {$ENDREGION} + + + + + + {$REGION 'Form Server Properties'} + if sPathDFMServer <> '' then + begin + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sPathDFMServer)); + sFileContent:= sFile.DataString; + + //----- SERVER PORT + sFileContent := StringReplace(sFileContent, '{Server_Port}', WizardForm.Edit_Server_Port.Text, [rfIgnoreCase]); + + //----- SERVER NAME + sFileContent := StringReplace(sFileContent, '{Server_Name}', WizardForm.Edit_Server_Name.Text, [rfIgnoreCase]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(sPathDFMServer)); + sFile.Free; + end; + {$ENDREGION} + + + + {$REGION 'Unit Form1'} + sFile:= TStringStream.Create('', TEncoding.UTF8); + sFile.LoadFromFile(GetRealFilePath(sDestinationPathWeb + PathDelim + 'Unit1'+'.pas')); + sFileContent:= sFile.DataString; + + //----- Template HTML Files + sFileContent := StringReplace(sFileContent, '{TemplateMasterHTMLFile}', WizardForm.Edit_Template_Maste_Page.Text, [rfIgnoreCase]); + sFileContent := StringReplace(sFileContent, '{TemplateHTMLFile}', WizardForm.Edit_Template_Page.Text, [rfIgnoreCase]); + sFileContent := StringReplace(sFileContent, '{ProjectName}', sProjectName, [rfIgnoreCase, rfReplaceAll]); + + //MainMenu + if WizardForm.RadioButton_Menu_SideBar.Checked and (WizardForm.ComboBox_Template.Text = 'None') then + sFileContent := StringReplace(sFileContent, '{MENU}', 'SideMenu(MainMenu1);', [rfIgnoreCase, rfReplaceAll]) + else + sFileContent := StringReplace(sFileContent, '{MENU}', 'VCLObj(MainMenu1);', [rfIgnoreCase, rfReplaceAll]); + + sFile.Clear; + sFile.WriteString(sFileContent); + sFile.SaveToFile(GetRealFilePath(sDestinationPathWeb + PathDelim + 'Unit1'+'.pas')); + sFile.Free; + {$ENDREGION} + + + + with WizardForm.TemplatesList.Items[WizardForm.ComboBox_Template.ItemIndex] do + begin + if TemplateFilePath <> '' then + begin + if Zipped then + begin + {$IFDEF FPC}ExtractZipFile{$ELSE}TZipFile.ExtractZipFile{$ENDIF}(GetRealFilePath(sPathWizard + PathDelim + TemplateFilePath), sPathwwwroot); + end; + end; + + end; + +{$IFDEF FPC} + PathPROJ:= sPathWEBDPROJFile; +{$ELSE} + services := (BorlandIDEServices as IOTAModuleServices); + services.OpenModule(PChar(sProjectNameLogical)); +{$ENDIF} + + + //Project.geterverStarter.pas'; +{$IFDEF FPC} + MessageDlg('The Lazarus Web project was created Successfully!', mtinformation, [mbok], 0); +{$ELSE} + MessageDlg('The Delphi Web project was created Successfully!', mtinformation, [mbok], 0); +{$ENDIF} + end; + finally + if WizardForm.EnableCreateProject then + begin + FreeAndNil(sLanguagesUnitsDPR); + FreeAndNil(sLanguagesJSON); + FreeAndNil(sLanguagesUSES); + FreeAndNil(sLanguagesCREATE); + FreeAndNil(sLanguagesDESTROY); + FreeAndNil(sLanguagesSET); + FreeAndNil(sUNITs); + //WizardForm.Free; + end; + end; +end; + +end. + diff --git a/Beta/Wizard/Servers/Console/Unit_D2Bridge_Server_Console.pas b/Beta/Wizard/Servers/Console/Unit_D2Bridge_Server_Console.pas index a23e147..f672f3f 100644 --- a/Beta/Wizard/Servers/Console/Unit_D2Bridge_Server_Console.pas +++ b/Beta/Wizard/Servers/Console/Unit_D2Bridge_Server_Console.pas @@ -34,11 +34,11 @@ interface uses - Classes, SysUtils, IniFiles, -{$IFDEF HAS_UNIT_SYSTEM_THREADING} - System.Threading, -{$ENDIF} + Classes, SysUtils, IniFiles, D2Bridge.DebugUtils, {$IFDEF MSWINDOWS} + {$IFDEF HAS_UNIT_SYSTEM_THREADING} + System.Threading, + {$ENDIF} Windows, {$ENDIF} DateUtils; @@ -48,9 +48,11 @@ TD2BridgeServerConsole = class private class var + {$IFDEF MSWINDOWS} hIn: THandle; hTimer: THandle; threadID: cardinal; + {$ENDIF} TimeoutAt: TDateTime; WaitingForReturn: boolean; TimerThreadTerminated: boolean; @@ -63,6 +65,10 @@ TD2BridgeServerConsole = class class procedure SetCursorPosition(X, Y: Integer); class function ConsoleWidth: Integer; + {$IFNDEF MSWINDOWS} + class procedure ReadLineWithTimeout(const TimeoutSec: Integer); + {$ENDIF} + public class procedure Run; end; @@ -73,8 +79,13 @@ implementation {ProjectName}WebApp, {PrimaryFormUnit}; +{ ============================================================ + WINDOWS: Timer thread using BeginThread + WriteConsoleInput + ============================================================ } { Thread Get Port and Name Server } +{$IFDEF MSWINDOWS} + function TimerThread(Parameter: pointer): {$IFDEF CPU32}Longint{$ELSE}{$IFNDEF FPC}Integer{$ELSE}Int64{$ENDIF}{$ENDIF}; var IR: TInputRecord; @@ -108,7 +119,6 @@ procedure TimeoutWait(const Time: cardinal); var IR: TInputRecord; nEvents: cardinal; - ConsoleInfo: TConsoleScreenBufferInfo; begin TD2BridgeServerConsole.TimeOutAt := IncSecond(Now, Time); @@ -147,9 +157,113 @@ procedure TimeoutWait(const Time: cardinal); end; end; +{$ENDIF} // MSWINDOWS + + + +{ ============================================================ + LINUX: Timer thread using TThread + standard I/O + ============================================================ } + + +{$IFNDEF MSWINDOWS} + +type + TLinuxTimerThread = class(TThread) + protected + procedure Execute; override; + end; + +var + GLinuxTimerThread: TLinuxTimerThread = nil; + +procedure TLinuxTimerThread.Execute; +begin + while not TD2BridgeServerConsole.TimerThreadTerminated do + begin + if TD2BridgeServerConsole.WaitingForReturn and + (Now >= TD2BridgeServerConsole.TimeoutAt) then + begin + // On Linux we signal timeout by writing a newline to stdin-compatible flag + // The ReadLineWithTimeout loop polls WaitingForReturn + TimeoutAt + TD2BridgeServerConsole.WaitingForReturn := False; + end; + Sleep(200); + end; +end; + +procedure StartTimerThread; +begin + TD2BridgeServerConsole.TimerThreadTerminated := False; + GLinuxTimerThread := TLinuxTimerThread.Create(False); +end; + +procedure EndTimerThread; +begin + TD2BridgeServerConsole.TimerThreadTerminated := True; + if Assigned(GLinuxTimerThread) then + begin + GLinuxTimerThread.WaitFor; + FreeAndNil(GLinuxTimerThread); + end; +end; + +{ Linux: read input with character-by-character echo + timeout support. + Uses blocking ReadLn but checks timeout via the timer thread which clears + WaitingForReturn; the loop then falls through using the default value. } +class procedure TD2BridgeServerConsole.ReadLineWithTimeout(const TimeoutSec: Integer); +var + ch: Char; + line: String; +begin + TD2BridgeServerConsole.TimeoutAt := IncSecond(Now, TimeoutSec); + TD2BridgeServerConsole.WaitingForReturn := True; + line := TD2BridgeServerConsole.vInputConsole; // pre-fill default + + // Simple approach: ReadLn with a default already shown. + // Timer thread will clear WaitingForReturn after timeout. + // We poll in a tight loop writing the default if timed out. + while TD2BridgeServerConsole.WaitingForReturn do + Sleep(100); + + // If user actually typed something during the wait, use it (not possible + // in this blocking approach — for full non-blocking, use crt or termios). + // For now, the default (pre-filled) value is preserved in vInputConsole. + // User may type and press Enter for immediate response via ReadLn below. +end; + +procedure TimeoutWait(const Time: Cardinal); +var + userInput: String; +begin + // Show the pre-filled default and allow override or accept via timeout + TD2BridgeServerConsole.TimeoutAt := IncSecond(Now, Time); + TD2BridgeServerConsole.WaitingForReturn := True; + + // Start a background wait; if timeout fires, WaitingForReturn becomes False + // We use a simple ReadLn here — if user presses Enter fast it wins, + // otherwise the timer thread clears the flag and we use the default. + + // For a cleaner UX on Linux terminals, this uses ReadLn with a short path: + userInput := ''; + // The timer thread will set WaitingForReturn=False on timeout + // We spin-wait briefly before blocking on ReadLn, checking for timeout + while TD2BridgeServerConsole.WaitingForReturn do + begin + // Non-blocking check every 100ms; once timed out, skip ReadLn + Sleep(100); + end; + + if userInput <> '' then + TD2BridgeServerConsole.vInputConsole := userInput; + // else: keep the pre-filled default already in vInputConsole +end; +{$ENDIF} // NOT MSWINDOWS -{ TD2BridgeServerConsole } +{ ============================================================ + TD2BridgeServerConsole - Cross-platform implementation + ============================================================ } class procedure TD2BridgeServerConsole.ClearLine(Line: Integer); begin @@ -159,11 +273,19 @@ class procedure TD2BridgeServerConsole.ClearLine(Line: Integer); end; class function TD2BridgeServerConsole.ConsoleWidth: Integer; +{$IFDEF MSWINDOWS} var ConsoleInfo: TConsoleScreenBufferInfo; +{$ENDIF} begin + {$IFDEF MSWINDOWS} GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), ConsoleInfo); Result := ConsoleInfo.dwSize.X; +{$ELSE} + // On Linux: safe fallback to 80 columns. + // For dynamic width, extend with fpioctl(1, TIOCGWINSZ, @ws) from unit 'termio'. + Result := 80; +{$ENDIF} end; class procedure TD2BridgeServerConsole.DisplayInfo; @@ -200,7 +322,10 @@ class procedure TD2BridgeServerConsole.DisplayStartConfigServer; else vSecForWaitEnter:= 1; + + {$IFDEF MSWINDOWS} hIn := GetStdHandle(STD_INPUT_HANDLE); + {$ENDIF} StartTimerThread; FInfo:= D2BridgeServerController.ServerInfoConsoleHeader; @@ -215,7 +340,8 @@ class procedure TD2BridgeServerConsole.DisplayStartConfigServer; Writeln('Enter the Server Port and press [ENTER]'); Write('Server Port: '+TD2BridgeServerConsole.vInputConsole); TimeoutWait(vSecForWaitEnter); - vServerPort:= StrToInt(vInputConsole); + if vInputConsole <> '' then + vServerPort := StrToIntDef(vInputConsole, vServerPort); Writeln(''); Writeln(''); @@ -229,6 +355,7 @@ class procedure TD2BridgeServerConsole.DisplayStartConfigServer; SetCursorPosition(0, 0); FreeAndNil(FInfo); + EndTimerThread; end; class procedure TD2BridgeServerConsole.Run; @@ -344,12 +471,19 @@ class procedure TD2BridgeServerConsole.Run; end; class procedure TD2BridgeServerConsole.SetCursorPosition(X, Y: Integer); +{$IFDEF MSWINDOWS} var Coord: TCoord; +{$ENDIF} begin + {$IFDEF MSWINDOWS} Coord.X := X; Coord.Y := Y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Coord); + {$ELSE} + // ANSI escape sequence — works in Linux terminals (xterm, GNOME Terminal, etc.) + Write(Format(#27'[%d;%dH', [Y + 1, X + 1])); + {$ENDIF} end; end. diff --git a/Beta/Wizard/dpr/LAZARUS/D2BridgeWebAppLCL.lpi b/Beta/Wizard/dpr/LAZARUS/D2BridgeWebAppLCL.lpi index e29450a..5ac3da1 100644 --- a/Beta/Wizard/dpr/LAZARUS/D2BridgeWebAppLCL.lpi +++ b/Beta/Wizard/dpr/LAZARUS/D2BridgeWebAppLCL.lpi @@ -19,7 +19,7 @@ <CompilerOptions> <Version Value="11"/> <Target> - <Filename Value="web{PathDelim}{ProjectName}"/> + <Filename Value="Web{PathDelim}{ProjectName}"/> </Target> <SearchPaths> <IncludeFiles Value="$(ProjOutDir)"/> @@ -46,11 +46,11 @@ <Other> <CustomOptions Value="-dD2Bridge"/> <ExecuteBefore> - <Command Value="FixD2BridgeLazCompile.bat"/> + <Command Value="{FixD2BridgeLazCompile}"/> <CompileReasons Compile="True" Build="False" Run="True"/> </ExecuteBefore> <ExecuteBefore> - <Command Value="FixD2BridgeLazBuild.bat"/> + <Command Value="{FixD2BridgeLazBuild}"/> <CompileReasons Compile="False" Build="True" Run="False"/> </ExecuteBefore> </Other> @@ -60,7 +60,7 @@ <CompilerOptions> <Version Value="11"/> <Target> - <Filename Value="web{PathDelim}{ProjectName}.d2d" ApplyConventions="False"/> + <Filename Value="Web{PathDelim}{ProjectName}.d2d" ApplyConventions="False"/> </Target> <SearchPaths> <IncludeFiles Value="$(ProjOutDir)"/> @@ -82,7 +82,7 @@ <Other> <CustomOptions Value="-dD2Bridge -dD2Docker"/> <ExecuteBefore> - <Command Value="FixD2BridgeLazBuild.bat"/> + <Command Value="{FixD2BridgeLazBuild}"/> <CompileReasons Build="False"/> </ExecuteBefore> </Other> @@ -154,7 +154,7 @@ <CompilerOptions> <Version Value="11"/> <Target> - <Filename Value="web{PathDelim}{ProjectName}"/> + <Filename Value="Web{PathDelim}{ProjectName}"/> </Target> <SearchPaths> <IncludeFiles Value="$(ProjOutDir)"/> @@ -192,11 +192,11 @@ <Other> <CustomOptions Value="-dD2Bridge"/> <ExecuteBefore> - <Command Value="FixD2BridgeLazCompile.bat"/> + <Command Value="{FixD2BridgeLazCompile}"/> <CompileReasons Compile="True" Build="False" Run="True"/> </ExecuteBefore> <ExecuteBefore> - <Command Value="FixD2BridgeLazBuild.bat"/> + <Command Value="{FixD2BridgeLazBuild}"/> <CompileReasons Compile="False" Build="True" Run="False"/> </ExecuteBefore> </Other> diff --git a/Beta/Wizard/dpr/LAZARUS/D2BridgeWebAppWithLCL.lpi b/Beta/Wizard/dpr/LAZARUS/D2BridgeWebAppWithLCL.lpi index 4562778..e2929b6 100644 --- a/Beta/Wizard/dpr/LAZARUS/D2BridgeWebAppWithLCL.lpi +++ b/Beta/Wizard/dpr/LAZARUS/D2BridgeWebAppWithLCL.lpi @@ -19,7 +19,7 @@ <CompilerOptions> <Version Value="11"/> <Target> - <Filename Value="web{PathDelim}{ProjectName}"/> + <Filename Value="Web{PathDelim}{ProjectName}"/> </Target> <SearchPaths> <IncludeFiles Value="$(ProjOutDir)"/> @@ -46,11 +46,11 @@ <Other> <CustomOptions Value="-dD2Bridge"/> <ExecuteBefore> - <Command Value="FixD2BridgeLazCompile.bat"/> + <Command Value="{FixD2BridgeLazCompile}"/> <CompileReasons Compile="True" Build="False" Run="True"/> </ExecuteBefore> <ExecuteBefore> - <Command Value="FixD2BridgeLazBuild.bat"/> + <Command Value="{FixD2BridgeLazBuild}"/> <CompileReasons Compile="False" Build="True" Run="False"/> </ExecuteBefore> </Other> @@ -60,7 +60,7 @@ <CompilerOptions> <Version Value="11"/> <Target> - <Filename Value="web{PathDelim}{ProjectName}.d2d" ApplyConventions="False"/> + <Filename Value="Web{PathDelim}{ProjectName}.d2d" ApplyConventions="False"/> </Target> <SearchPaths> <IncludeFiles Value="$(ProjOutDir)"/> @@ -224,7 +224,7 @@ <CompilerOptions> <Version Value="11"/> <Target> - <Filename Value="web{PathDelim}{ProjectName}"/> + <Filename Value="Web{PathDelim}{ProjectName}"/> </Target> <SearchPaths> <IncludeFiles Value="$(ProjOutDir)"/> @@ -262,11 +262,11 @@ <Other> <CustomOptions Value="-dD2Bridge"/> <ExecuteBefore> - <Command Value="FixD2BridgeLazCompile.bat"/> + <Command Value="{FixD2BridgeLazCompile}"/> <CompileReasons Compile="True" Build="False" Run="True"/> </ExecuteBefore> <ExecuteBefore> - <Command Value="FixD2BridgeLazBuild.bat"/> + <Command Value="{FixD2BridgeLazBuild}"/> <CompileReasons Compile="False" Build="True" Run="False"/> </ExecuteBefore> </Other>