Full Code of HemulGM/ChatGPT for AI

main 97ad2e8d3d6e cached
80 files
1.2 MB
378.0k tokens
1 requests
Download .txt
Showing preview only (1,297K chars total). Download the full file or copy to clipboard to get everything.
Repository: HemulGM/ChatGPT
Branch: main
Commit: 97ad2e8d3d6e
Files: 80
Total size: 1.2 MB

Directory structure:
gitextract_yo52volr/

├── .gitattributes
├── .github/
│   └── FUNDING.yml
├── .gitignore
├── .gitmodules
├── AndroidManifest.template.xml
├── ChatGPT.About.fmx
├── ChatGPT.About.pas
├── ChatGPT.Android.pas
├── ChatGPT.ChatSettings.fmx
├── ChatGPT.ChatSettings.pas
├── ChatGPT.Classes.pas
├── ChatGPT.Code.pas
├── ChatGPT.FrameChat.fmx
├── ChatGPT.FrameChat.pas
├── ChatGPT.FrameCode.fmx
├── ChatGPT.FrameCode.pas
├── ChatGPT.FrameImage.fmx
├── ChatGPT.FrameImage.pas
├── ChatGPT.FrameImagePreview.fmx
├── ChatGPT.FrameImagePreview.pas
├── ChatGPT.FrameMessage.fmx
├── ChatGPT.FrameMessage.pas
├── ChatGPT.FramePlainText.fmx
├── ChatGPT.FramePlainText.pas
├── ChatGPT.FrameSVG.fmx
├── ChatGPT.FrameSVG.pas
├── ChatGPT.FrameUIMessage.fmx
├── ChatGPT.FrameUIMessage.pas
├── ChatGPT.Functions.External.Intf.pas
├── ChatGPT.Functions.External.pas
├── ChatGPT.Functions.pas
├── ChatGPT.ImportExport.fmx
├── ChatGPT.ImportExport.pas
├── ChatGPT.LoadedFunctions.fmx
├── ChatGPT.LoadedFunctions.pas
├── ChatGPT.Main.fmx
├── ChatGPT.Main.pas
├── ChatGPT.Manager.dfm
├── ChatGPT.Manager.pas
├── ChatGPT.Overlay.fmx
├── ChatGPT.Overlay.pas
├── ChatGPT.Settings.fmx
├── ChatGPT.Settings.pas
├── ChatGPT.SoundRecorder.pas
├── ChatGPT.TextEditor.fmx
├── ChatGPT.TextEditor.pas
├── ChatGPT.deployproj
├── ChatGPT.dpr
├── ChatGPT.dproj
├── ChatGPT.res
├── ChatGPTGroup.groupproj
├── ChatGPT_Console.dpr
├── ChatGPT_Console.dproj
├── ChatGPT_Console.res
├── Code/
│   ├── ChatGPT.Code.JSON.pas
│   ├── ChatGPT.Code.MarkDown.pas
│   ├── ChatGPT.Code.Pascal.pas
│   ├── ChatGPT.Code.Python.pas
│   └── ChatGPT.Code.SQL.pas
├── FMX.Media.Win.pas
├── FunctionsLib/
│   ├── func_cmd.pas
│   ├── func_weather.pas
│   ├── gpt_function_cmd.dpr
│   ├── gpt_function_cmd.dproj
│   ├── gpt_function_cmd.res
│   ├── gpt_function_owm.deployproj
│   ├── gpt_function_owm.dpr
│   ├── gpt_function_owm.dproj
│   └── gpt_function_owm.res
├── HGM.FMX.Ani.pas
├── HGM.FMX.Image.pas
├── LICENSE
├── LaunchScreen.TemplateiOS/
│   ├── Assets/
│   │   ├── AppIcon.appiconset/
│   │   │   └── Contents.json
│   │   ├── Contents.json
│   │   ├── LaunchScreenBackgroundColor.colorset/
│   │   │   └── Contents.json
│   │   └── LaunchScreenImage.imageset/
│   │       └── Contents.json
│   └── LaunchScreen.storyboard
├── README.md
└── Res/
    ├── chatgptfmx/
    │   └── res/
    │       └── mipmap-anydpi-v26/
    │           └── chatgptfmx.xml
    └── preview.psd

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: hemulgm
open_collective: hemulgm


================================================
FILE: .gitignore
================================================
# Uncomment these types if you want even more clean repository. But be careful.
# It can make harm to an existing project source. Read explanations below.
#
# Resource files are binaries containing manifest, project icon and version info.
# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
#*.res
#
# Type library file (binary). In old Delphi versions it should be stored.
# Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
#*.tlb
#
# Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
# Uncomment this if you are not using diagrams or use newer Delphi version.
#*.ddp
#
# Visual LiveBindings file. Added in Delphi XE2.
# Uncomment this if you are not using LiveBindings Designer.
#*.vlb
#
# Deployment Manager configuration file for your project. Added in Delphi XE2.
# Uncomment this if it is not mobile development and you do not use remote debug feature.
#*.deployproj
#
# C++ object files produced when C/C++ Output file generation is configured.
# Uncomment this if you are not using external objects (zlib library for example).
#*.obj
#

# Delphi compiler-generated binaries (safe to delete)
*.exe
*.dll
*.bpl
*.bpi
*.dcp
*.so
*.apk
*.drc
*.map
*.dres
*.rsm
*.tds
*.dcu
*.lib
*.a
*.o
*.ocx

# Delphi autogenerated files (duplicated info)
*.cfg
*.hpp
*Resource.rc

# Delphi local files (user-specific info)
*.local
*.identcache
*.projdata
*.tvsconfig
*.dsk

# Delphi history and backups
__history/
__recovery/
Win32/
Win64/
Android/
Android64/
*.~*

# Castalia statistics file (since XE7 Castalia is distributed with Delphi)
*.stat

# Boss dependency manager vendor folder https://github.com/HashLoad/boss
modules/
MY_TOKEN.txt
/Linux64/Release/ChatGPT
/FMX.Memo.Style.1.pas
/Linux64/Release/ChatGPT_Linux64.zip
/Linux64/Debug/ChatGPT
/MacOS/ChatGPT_MacOSarm64.zip
/MacOS/ChatGPT_MacOSi64.zip
/iOSDevice64/*
/Keys/*


================================================
FILE: .gitmodules
================================================
[submodule "DelphiOpenAI"]
	path = DelphiOpenAI
	url = https://github.com/HemulGM/DelphiOpenAI
[submodule "WindowDarkMode"]
	path = WindowDarkMode
	url = https://github.com/HemulGM/WindowDarkMode
[submodule "OWM_API"]
	path = OWM_API
	url = https://github.com/HemulGM/OWM_API
[submodule "TProcessDelphi"]
	path = TProcessDelphi
	url = https://github.com/HemulGM/TProcessDelphi
[submodule "FMXRichMemo"]
	path = FMXRichMemo
	url = https://github.com/HemulGM/FMXRichMemo


================================================
FILE: AndroidManifest.template.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="%package%"
    android:versionCode="%versionCode%"
    android:versionName="%versionName%"
    android:installLocation="%installLocation%">
    <uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="33" />
<%uses-permission%>
    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>
    <queries>
<%queries-child-elements%>
    </queries>
    <application
        android:persistent="%persistent%"
        android:restoreAnyVersion="%restoreAnyVersion%"
        android:label="%label%"
        android:debuggable="%debuggable%"
        android:largeHeap="%largeHeap%"
        android:icon="%icon%"
        android:theme="%theme%"
        android:hardwareAccelerated="%hardwareAccelerated%"
        android:resizeableActivity="false"
        android:requestLegacyExternalStorage="true">
<%provider%>
<%application-meta-data%>
<%uses-libraries%>
<%services%>
        <!-- Our activity is a subclass of the built-in NativeActivity framework class.
             This will take care of integrating with our NDK code. -->
        <activity
            android:name="com.embarcadero.firemonkey.FMXNativeActivity"
            android:exported="true"
            android:label="%activityLabel%"
            android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|uiMode"
            android:launchMode="singleTask">
            <!-- Tell NativeActivity the name of our .so -->
            <meta-data android:name="android.app.lib_name" android:value="%libNameValue%" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
<%activity%>
<%receivers%>
    </application>
</manifest>
<!-- END_INCLUDE(manifest) -->


================================================
FILE: ChatGPT.About.fmx
================================================
inherited FrameAbout: TFrameAbout
  Size.Width = 944.000000000000000000
  Size.Height = 703.000000000000000000
  OnResize = FrameResize
  OnResized = FrameResize
  inherited RectangleBG: TRectangle
    Size.Width = 944.000000000000000000
    Size.Height = 703.000000000000000000
    OnClick = ButtonOkClick
  end
  object LayoutClient: TLayout
    Align = Center
    Padding.Left = 20.000000000000000000
    Padding.Top = 20.000000000000000000
    Padding.Right = 20.000000000000000000
    Padding.Bottom = 20.000000000000000000
    Size.Width = 635.000000000000000000
    Size.Height = 641.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 0
    object RectangleFrame: TRectangle
      Align = Contents
      Fill.Color = xFF202123
      Locked = True
      Size.Width = 635.000000000000000000
      Size.Height = 641.000000000000000000
      Size.PlatformDefault = False
      Stroke.Kind = None
      XRadius = 6.000000000000000000
      YRadius = 6.000000000000000000
    end
    object VertScrollBoxContent: TVertScrollBox
      Align = Client
      Padding.Right = 10.000000000000000000
      Padding.Bottom = 10.000000000000000000
      Size.Width = 595.000000000000000000
      Size.Height = 555.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 1
      Viewport.Width = 579.000000000000000000
      Viewport.Height = 555.000000000000000000
      object Label1: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = []
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 10.000000000000000000
        Position.Y = 10.000000000000000000
        Size.Width = 569.000000000000000000
        Size.Height = 27.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Size = 20.000000000000000000
        TextSettings.Font.StyleExt = {00070000000000000004000000}
        TextSettings.FontColor = xFFE9E9E9
        TextSettings.WordWrap = False
        Text = 'About'
        TabOrder = 10
      end
      object Label5: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 57.000000000000000000
        Size.Width = 569.000000000000000000
        Size.Height = 38.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Segoe UI Emoji'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        Text = 
          'The ChatGPT client is an amazing open source cross-platform appl' +
          'ication that allows you to play with the OpenAI ChatGPT API for ' +
          'free!'
        TabOrder = 8
        TabStop = False
      end
      object LabelAppearance: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = []
        Margins.Top = 30.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 220.000000000000000000
        Size.Width = 569.000000000000000000
        Size.Height = 24.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Segoe UI Emoji'
        TextSettings.Font.Size = 18.000000000000000000
        TextSettings.Font.StyleExt = {00070000000000000004000000}
        TextSettings.FontColor = xFFE9E9E9
        TextSettings.WordWrap = False
        Text = 'Support'
        TabOrder = 2
        TabStop = False
      end
      object LabelVersion: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 780.000000000000000000
        Size.Width = 569.000000000000000000
        Size.Height = 19.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        TextSettings.WordWrap = False
        Text = 'HemulGM'
        TabOrder = 9
        TabStop = False
      end
      object Label34: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 110.000000000000000000
        Size.Width = 569.000000000000000000
        Size.Height = 19.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Segoe UI Emoji'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        Text = 'Check out the source code on GitHub and give it a '#11088'!'
        TabOrder = 4
        TabStop = False
      end
      object Label2: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 259.000000000000000000
        Size.Width = 569.000000000000000000
        Size.Height = 149.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Segoe UI Emoji'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        Text = 
          'At ChatGPT, we strive to bring you useful and amazing features e' +
          'very time. And just like any other project, your support and mot' +
          'ivation will help us move forward!'#13#10#13#10'If you liked our applicati' +
          'on, we ask you to give this project a '#11088#65039'. Your approval means a ' +
          'lot to us and encourages us to work harder to deliver the best p' +
          'ossible experience.'#13#10#13#10'Thank you for being a part of our communi' +
          'ty and we look forward to serving you better in the future.'
        TabOrder = 7
        TabStop = False
      end
      object Label3: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = []
        Margins.Top = 30.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 499.000000000000000000
        Size.Width = 569.000000000000000000
        Size.Height = 24.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Segoe UI Emoji'
        TextSettings.Font.Size = 18.000000000000000000
        TextSettings.Font.StyleExt = {00070000000000000004000000}
        TextSettings.FontColor = xFFE9E9E9
        TextSettings.WordWrap = False
        Text = 'Privacy Statement'
        TabOrder = 1
        TabStop = False
      end
      object Label4: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 538.000000000000000000
        Size.Width = 569.000000000000000000
        Size.Height = 168.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Segoe UI Emoji'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        Text = 
          'We value your privacy and are committed to protecting the privac' +
          'y of our users. We do not collect or store the text you enter or' +
          ' receive from the OpenAI server in any form on third party serve' +
          'rs. All history is stored only on your computer and nowhere else' +
          '. Our source code is available for review to verify this claim.'#13 +
          #10#13#10'We prioritize the security of your API key and handle it with' +
          ' the utmost care. If you use your own API key, your key is store' +
          'd solely on your computer and is never shared with any third par' +
          'ty. It is used solely for its intended purpose to access the Ope' +
          'nAI API and not for any other unauthorized use.'
        TabOrder = 3
        TabStop = False
      end
      object Label6: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = []
        Margins.Top = 30.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 741.000000000000000000
        Size.Width = 569.000000000000000000
        Size.Height = 24.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Segoe UI Emoji'
        TextSettings.Font.Size = 18.000000000000000000
        TextSettings.Font.StyleExt = {00070000000000000004000000}
        TextSettings.FontColor = xFFE9E9E9
        TextSettings.WordWrap = False
        Text = 'Autor'
        TabOrder = 0
        TabStop = False
      end
      object Layout4: TLayout
        Align = Top
        Margins.Top = 10.000000000000000000
        Position.Y = 144.000000000000000000
        Size.Width = 569.000000000000000000
        Size.Height = 46.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 6
        TabStop = False
        object ButtonGitHub: TButton
          OnTap = ButtonGitHubTap
          Align = Left
          ImageIndex = 9
          Size.Width = 289.000000000000000000
          Size.Height = 46.000000000000000000
          Size.PlatformDefault = False
          StyleLookup = 'buttonstyle_menu'
          TabOrder = 0
          Text = 'Open GitHub page'
          TextSettings.HorzAlign = Leading
          ParentShowHint = False
          ShowHint = True
          OnClick = ButtonGitHubClick
        end
      end
      object Layout1: TLayout
        Align = Top
        Margins.Top = 10.000000000000000000
        Position.Y = 423.000000000000000000
        Size.Width = 569.000000000000000000
        Size.Height = 46.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 5
        TabStop = False
        object ButtonReport: TButton
          OnTap = ButtonReportTap
          Align = Left
          ImageIndex = 9
          Size.Width = 289.000000000000000000
          Size.Height = 46.000000000000000000
          Size.PlatformDefault = False
          StyleLookup = 'buttonstyle_menu'
          TabOrder = 0
          Text = 'Report a problem'
          TextSettings.HorzAlign = Leading
          ParentShowHint = False
          ShowHint = True
          OnClick = ButtonReportClick
        end
      end
    end
    object Layout2: TLayout
      Align = Bottom
      Position.X = 20.000000000000000000
      Position.Y = 575.000000000000000000
      Size.Width = 595.000000000000000000
      Size.Height = 46.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 3
      object ButtonOk: TButton
        Align = Right
        Cancel = True
        Position.X = 515.000000000000000000
        Size.Width = 80.000000000000000000
        Size.Height = 46.000000000000000000
        Size.PlatformDefault = False
        StyleLookup = 'buttonstyle_menu'
        TabOrder = 2
        Text = 'OK'
        OnClick = ButtonOkClick
      end
    end
  end
end


================================================
FILE: ChatGPT.About.pas
================================================
unit ChatGPT.About;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
  ChatGPT.Overlay, FMX.Objects, FMX.Memo.Types, FMX.ScrollBox, FMX.Memo,
  FMX.ComboEdit, FMX.Edit, FMX.Controls.Presentation, FMX.Layouts,
  ChatGPT.Classes;

{$IF DEFINED(ANDROID) OR DEFINED(IOS) OR DEFINED(IOS64)}
  {$DEFINE MOBILE}
{$ENDIF}

type
  TFrameAbout = class(TFrameOveraly)
    LayoutClient: TLayout;
    RectangleFrame: TRectangle;
    VertScrollBoxContent: TVertScrollBox;
    Label1: TLabel;
    Label5: TLabel;
    LabelAppearance: TLabel;
    LabelVersion: TLabel;
    Layout2: TLayout;
    ButtonOk: TButton;
    Label34: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label6: TLabel;
    Layout4: TLayout;
    ButtonGitHub: TButton;
    Layout1: TLayout;
    ButtonReport: TButton;
    procedure ButtonOkClick(Sender: TObject);
    procedure FrameResize(Sender: TObject);
    procedure ButtonGitHubClick(Sender: TObject);
    procedure ButtonReportClick(Sender: TObject);
    procedure ButtonGitHubTap(Sender: TObject; const Point: TPointF);
    procedure ButtonReportTap(Sender: TObject; const Point: TPointF);
  private
    FProcCallback: TProc<TFrameAbout, Boolean>;
    FLayoutClientWidth, FLayoutClientHeight: Single;
  protected
    procedure SetMode(const Value: TWindowMode); override;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Cancel; override;
    class procedure Execute(AParent: TControl; ProcSet: TProc<TFrameAbout>; ProcExecuted: TProc<TFrameAbout, Boolean>);
  end;

var
  FrameAbout: TFrameAbout;

implementation

uses
  System.Math;

{$R *.fmx}

procedure TFrameAbout.ButtonGitHubClick(Sender: TObject);
begin
  OpenUrl('https://github.com/HemulGM/ChatGPT');
end;

procedure TFrameAbout.ButtonGitHubTap(Sender: TObject; const Point: TPointF);
begin
  ButtonGitHubClick(nil);
end;

procedure TFrameAbout.ButtonOkClick(Sender: TObject);
begin
  Cancel;
end;

procedure TFrameAbout.ButtonReportClick(Sender: TObject);
begin
  OpenUrl('https://github.com/HemulGM/ChatGPT/issues');
end;

procedure TFrameAbout.ButtonReportTap(Sender: TObject; const Point: TPointF);
begin
  ButtonReportClick(nil);
end;

procedure TFrameAbout.Cancel;
begin
  if Assigned(FProcCallback) then
    FProcCallback(Self, True);
  Release;
end;

constructor TFrameAbout.Create(AOwner: TComponent);
begin
  inherited;
  Name := '';
  FLayoutClientWidth := LayoutClient.Width;
  FLayoutClientHeight := LayoutClient.Height;
  VertScrollBoxContent.AniCalculations.Animation := True;
  //VertScrollBoxContent.AniCalculations.Interval := 1;
  VertScrollBoxContent.AniCalculations.Averaging := True;
  VertScrollBoxContent.ViewportPosition := TPoint.Zero;
  {$IFDEF MOBILE}
  ButtonReport.OnClick := nil;
  ButtonGitHub.OnClick := nil;
  {$ENDIF}
end;

class procedure TFrameAbout.Execute(AParent: TControl; ProcSet: TProc<TFrameAbout>; ProcExecuted: TProc<TFrameAbout, Boolean>);
begin
  var Frame := TFrameAbout.Create(AParent);
  Frame.Parent := AParent;
  Frame.FProcCallback := ProcExecuted;
  Frame.Align := TAlignLayout.Contents;
  Frame.BringToFront;
  if Assigned(ProcSet) then
    ProcSet(Frame);
  Frame.ButtonOk.SetFocus;
end;

procedure TFrameAbout.FrameResize(Sender: TObject);
begin
  LayoutClient.Width := Min(FLayoutClientWidth, Width);
  LayoutClient.Height := Min(FLayoutClientHeight, Height);
end;

procedure TFrameAbout.SetMode(const Value: TWindowMode);
begin
  inherited;
  if Mode = TWindowMode.Compact then
  begin
    LayoutClient.Align := TAlignLayout.Client;
    RectangleFrame.Corners := [];
  end
  else
  begin
    LayoutClient.Align := TAlignLayout.Center;
    RectangleFrame.Corners := AllCorners;
  end;
  FrameResize(nil);
end;

end.



================================================
FILE: ChatGPT.Android.pas
================================================
unit ChatGPT.Android;

{$IFDEF ANDROID}

interface

uses
  System.SysUtils, System.Types, System.IOUtils,
  System.Messaging, FMX.Dialogs;

type
  TDialog = class
  private
    FProc: TProc<string>;
    FRequestCode: Integer;
    procedure ResultCallback(const Sender: TObject; const M: TMessage);
  public
    constructor Create;
    destructor Destroy; override;
    procedure Show(const MimeType: string; Proc: TProc<string>);
  end;

procedure OpenFileDialog(const MimeType: string; Proc: TProc<string>);

implementation

uses
  System.Permissions,Androidapi.Helpers, Androidapi.JNI.Os,
  Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.JavaTypes,
  Androidapi.JNI.Webkit, Androidapi.JNI.Net, Androidapi.JNI.App,
  Androidapi.JNI.Support, FMX.Platform.Android;

constructor TDialog.Create;
begin
  FRequestCode := Random(9999999);
  TMessageManager.DefaultManager.SubscribeToMessage(TMessageResultNotification, ResultCallback);
end;

destructor TDialog.Destroy;
begin
  TMessageManager.DefaultManager.Unsubscribe(TMessageResultNotification, ResultCallback);
end;

function GetRealPathFromURI(Uri: Jnet_Uri): string;
var
  Cursor: JCursor;
  ColumnIndex: Integer;
begin
  Cursor := TAndroidHelper.Context.getContentResolver.query(Uri, nil, nil, nil, nil);
  ColumnIndex := Cursor.getColumnIndexOrThrow(StringToJString('_data'));
  Cursor.moveToFirst;
  Result := JStringToString(Cursor.getString(ColumnIndex));
  Cursor.close;
end;

procedure TDialog.ResultCallback(const Sender: TObject; const M: TMessage);
begin
  try
    if TMessageResultNotification(M).RequestCode = FRequestCode then
      if TMessageResultNotification(M).ResultCode = TJActivity.JavaClass.RESULT_OK then
      try
        FProc(GetRealPathFromURI(TMessageResultNotification(M).Value.getData));
      except
        on E: Exception do
          ShowMessage(E.Message);
      end;
  finally
    Free;
  end;
end;

procedure TDialog.Show(const MimeType: string; Proc: TProc<string>);
begin
  FProc := Proc;
  var Intent: JIntent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_PICK);
  Intent.setType(StringToJString(MimeType));
  //Intent.putExtra(TJIntent.JavaClass.EXTRA_ALLOW_MULTIPLE, False);
  MainActivity.startActivityForResult(Intent, FRequestCode);
end;

procedure OpenFileDialog(const MimeType: string; Proc: TProc<string>);
begin
  PermissionsService.RequestPermissions([JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE)],
    procedure(const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray)
    begin
      if (Length(AGrantResults) > 0) and (AGrantResults[0] = TPermissionStatus.Granted) then
        TDialog.Create.Show(MimeType, Proc);
    end);
end;

{$ELSE}

interface

implementation

{$ENDIF}

end.



================================================
FILE: ChatGPT.ChatSettings.fmx
================================================
inherited FrameChatSettings: TFrameChatSettings
  Size.Width = 729.000000000000000000
  Size.Height = 719.000000000000000000
  OnResize = FrameResize
  OnResized = FrameResize
  inherited RectangleBG: TRectangle
    Size.Width = 729.000000000000000000
    Size.Height = 719.000000000000000000
    OnClick = RectangleBGClick
  end
  object LayoutClient: TLayout
    Align = Center
    Padding.Left = 10.000000000000000000
    Padding.Top = 10.000000000000000000
    Padding.Right = 10.000000000000000000
    Padding.Bottom = 10.000000000000000000
    Size.Width = 440.000000000000000000
    Size.Height = 644.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 0
    object RectangleFrame: TRectangle
      Align = Contents
      Fill.Color = xFF202123
      Locked = True
      Size.Width = 440.000000000000000000
      Size.Height = 644.000000000000000000
      Size.PlatformDefault = False
      Stroke.Kind = None
      XRadius = 6.000000000000000000
      YRadius = 6.000000000000000000
    end
    object LayoutActs: TLayout
      Align = Bottom
      Position.X = 10.000000000000000000
      Position.Y = 588.000000000000000000
      Size.Width = 420.000000000000000000
      Size.Height = 46.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 1
      TabStop = False
      object ButtonCancel: TButton
        Align = Right
        Cancel = True
        Position.X = 340.000000000000000000
        Size.Width = 80.000000000000000000
        Size.Height = 46.000000000000000000
        Size.PlatformDefault = False
        StyleLookup = 'buttonstyle_menu'
        TabOrder = 0
        Text = 'CANCEL'
        ParentShowHint = False
        ShowHint = True
        OnClick = ButtonCancelClick
      end
      object ButtonOk: TButton
        Align = Right
        Position.X = 260.000000000000000000
        Size.Width = 80.000000000000000000
        Size.Height = 46.000000000000000000
        Size.PlatformDefault = False
        StyleLookup = 'buttonstyle_menu'
        TabOrder = 1
        Text = 'OK'
        OnClick = ButtonOkClick
      end
    end
    object VertScrollBox: TVertScrollBox
      Align = Client
      Padding.Right = 10.000000000000000000
      Padding.Bottom = 10.000000000000000000
      Margins.Right = -10.000000000000000000
      Size.Width = 430.000000000000000000
      Size.Height = 578.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 21
      Viewport.Width = 414.000000000000000000
      Viewport.Height = 578.000000000000000000
      object ComboEditModel: TComboEdit
        Touch.InteractiveGestures = [LongTap, DoubleTap]
        Align = Top
        StyleLookup = 'combo_style'
        TabOrder = 3
        ItemHeight = 36.000000000000000000
        Items.Strings = (
          'gpt-3.5-turbo'
          'gpt-3.5-turbo-0613'
          'gpt-3.5-turbo-16k'
          'gpt-4'
          'gpt-4-turbo'
          'gpt-4-0613'
          'gpt-4-32k')
        ItemIndex = 0
        Text = 'gpt-3.5-turbo'
        Position.Y = 134.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 33.000000000000000000
        Size.PlatformDefault = False
        OnMouseWheel = ComboEditModelMouseWheel
      end
      object EditMaxTokens: TEdit
        Touch.InteractiveGestures = [LongTap, DoubleTap]
        Align = Top
        StyleLookup = 'editstyle_clear'
        TabOrder = 4
        KeyboardType = DecimalNumberPad
        FilterChar = '0123456789'
        Position.Y = 382.000000000000000000
        Margins.Top = 5.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 33.000000000000000000
        Size.PlatformDefault = False
        TextPrompt = 'Example: 4096'
        object ClearEditButton3: TClearEditButton
          Touch.InteractiveGestures = [LongTap]
          CanFocus = False
          Cursor = crArrow
          Hint = 'Clear'
          Size.Width = 28.000000000000000000
          Size.Height = 29.000000000000000000
          Size.PlatformDefault = False
          StyleLookup = 'buttonstyle_clearmini'
          TabOrder = 0
          Text = 'buttonstyle_clearmini'
          object Path2: TPath
            Align = Center
            Data.Path = {
              0E00000000000000000060413333B33F010000009A9949410000000001000000
              0000E0403333B340010000003333B33F0000000001000000000000003333B33F
              010000003333B3400000E04001000000000000009A994941010000003333B33F
              00006041010000000000E04066660641010000009A9949410000604101000000
              000060419A99494101000000666606410000E04001000000000060413333B33F
              03000000000060413333B33F}
            Fill.Color = xFFACACBE
            Locked = True
            HitTest = False
            Margins.Left = 2.000000000000000000
            Size.Width = 13.000000000000000000
            Size.Height = 13.000000000000000000
            Size.PlatformDefault = False
            Stroke.Kind = None
            WrapMode = Fit
          end
        end
      end
      object EditQueryMaxToken: TEdit
        Touch.InteractiveGestures = [LongTap, DoubleTap]
        Align = Top
        StyleLookup = 'editstyle_clear'
        TabOrder = 5
        KeyboardType = DecimalNumberPad
        FilterChar = '0123456789'
        Position.Y = 492.000000000000000000
        Margins.Top = 5.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 33.000000000000000000
        Size.PlatformDefault = False
        TextPrompt = 'Example: 1024'
        object ClearEditButton4: TClearEditButton
          Touch.InteractiveGestures = [LongTap]
          CanFocus = False
          Cursor = crArrow
          Hint = 'Clear'
          Size.Width = 28.000000000000000000
          Size.Height = 29.000000000000000000
          Size.PlatformDefault = False
          StyleLookup = 'buttonstyle_clearmini'
          TabOrder = 0
          Text = 'buttonstyle_clearmini'
          object Path3: TPath
            Align = Center
            Data.Path = {
              0E00000000000000000060413333B33F010000009A9949410000000001000000
              0000E0403333B340010000003333B33F0000000001000000000000003333B33F
              010000003333B3400000E04001000000000000009A994941010000003333B33F
              00006041010000000000E04066660641010000009A9949410000604101000000
              000060419A99494101000000666606410000E04001000000000060413333B33F
              03000000000060413333B33F}
            Fill.Color = xFFACACBE
            Locked = True
            HitTest = False
            Margins.Left = 2.000000000000000000
            Size.Width = 13.000000000000000000
            Size.Height = 13.000000000000000000
            Size.PlatformDefault = False
            Stroke.Kind = None
            WrapMode = Fit
          end
        end
      end
      object Label1: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 10.000000000000000000
        Position.Y = 10.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 25.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.Font.Size = 20.000000000000000000
        TextSettings.FontColor = xFFE9E9E9
        TextSettings.HorzAlign = Center
        TextSettings.WordWrap = False
        Text = 'Chat Settings'
        TabOrder = 21
        TabStop = False
      end
      object Label16: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 20.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 465.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 17.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        Text = 'Query max tokens (default: 1024)'
        TabOrder = 24
        TabStop = False
      end
      object Label17: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Left = 5.000000000000000000
        Margins.Top = 10.000000000000000000
        Margins.Right = 5.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.X = 5.000000000000000000
        Position.Y = 425.000000000000000000
        Size.Width = 394.000000000000000000
        Size.Height = 15.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.FontColor = x78FFFFFF
        Text = 'Limit of the selected model'
        TabOrder = 13
        TabStop = False
      end
      object Label18: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Left = 5.000000000000000000
        Margins.Top = 10.000000000000000000
        Margins.Right = 5.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.X = 5.000000000000000000
        Position.Y = 535.000000000000000000
        Size.Width = 394.000000000000000000
        Size.Height = 15.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.FontColor = x78FFFFFF
        Text = 'Max number of tokens per request'
        TabOrder = 10
        TabStop = False
      end
      object Label19: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Left = 5.000000000000000000
        Margins.Top = 10.000000000000000000
        Margins.Right = 5.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.X = 5.000000000000000000
        Position.Y = 177.000000000000000000
        Size.Width = 394.000000000000000000
        Size.Height = 29.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.FontColor = x78FFFFFF
        Text = 
          'GPT-4 is currently in a limited beta and only accessible to thos' +
          'e who have been granted access'
        TabOrder = 12
        TabStop = False
      end
      object Label3: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 20.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 575.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 17.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        TextSettings.WordWrap = False
        Text = 'Temperature (default: 1.0)'
        TabOrder = 14
        TabStop = False
      end
      object Label4: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 627.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 15.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.FontColor = x78FFFFFF
        Text = 
          'The higher, the more creativity will be in the answers (less acc' +
          'urate)'
        TabOrder = 11
        TabStop = False
      end
      object Label8: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 10.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 112.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 17.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        Text = 'Model (default: gpt-3.5-turbo)'
        TabOrder = 26
        TabStop = False
      end
      object Label9: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 20.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 355.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 17.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        Text = 'Model max tokens (default: 4096)'
        TabOrder = 28
        TabStop = False
      end
      object Layout3: TLayout
        Align = Top
        Position.Y = 597.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 20.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 6
        TabStop = False
        object TrackBarTemp: TTrackBar
          Align = Client
          CanParentFocus = True
          Frequency = 1.000000000000000000
          Max = 20.000000000000000000
          Orientation = Horizontal
          Size.Width = 370.000000000000000000
          Size.Height = 20.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 0
          Value = 10.000000000000000000
          OnTracking = TrackBarTempTracking
        end
        object LabelTemp: TLabel
          Align = Right
          StyledSettings = [Style]
          Margins.Left = 6.000000000000000000
          Position.X = 376.000000000000000000
          Size.Width = 28.000000000000000000
          Size.Height = 20.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Family = 'Roboto'
          TextSettings.Font.Size = 14.000000000000000000
          TextSettings.FontColor = xBEFFFFFF
          TextSettings.HorzAlign = Trailing
          TextSettings.WordWrap = False
          Text = '2.0'
          TabOrder = 71
          TabStop = False
        end
      end
      object Layout1: TLayout
        Align = Top
        Position.Y = 689.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 20.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 7
        TabStop = False
        object TrackBarPP: TTrackBar
          Align = Client
          CanParentFocus = True
          Frequency = 1.000000000000000000
          Max = 20.000000000000000000
          Min = -20.000000000000000000
          Orientation = Horizontal
          Size.Width = 370.000000000000000000
          Size.Height = 20.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 0
          OnTracking = TrackBarPPTracking
        end
        object LabelPP: TLabel
          Align = Right
          StyledSettings = [Style]
          Margins.Left = 6.000000000000000000
          Position.X = 376.000000000000000000
          Size.Width = 28.000000000000000000
          Size.Height = 20.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Family = 'Roboto'
          TextSettings.Font.Size = 14.000000000000000000
          TextSettings.FontColor = xBEFFFFFF
          TextSettings.HorzAlign = Trailing
          TextSettings.WordWrap = False
          Text = '0.0'
          TabOrder = 71
          TabStop = False
        end
      end
      object Label12: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 20.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 667.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 17.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        TextSettings.WordWrap = False
        Text = 'Presence penalty (default: 0.0)'
        TabOrder = 23
        TabStop = False
      end
      object Label11: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Left = 5.000000000000000000
        Margins.Top = 10.000000000000000000
        Margins.Right = 5.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.X = 5.000000000000000000
        Position.Y = 719.000000000000000000
        Size.Width = 394.000000000000000000
        Size.Height = 44.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.FontColor = x78FFFFFF
        Text = 
          'Number between -2.0 and 2.0. Positive values penalize new tokens' +
          ' based on whether they appear in the text so far, increasing the' +
          ' model'#39's likelihood to talk about new topics.'
        TabOrder = 19
        TabStop = False
      end
      object Label15: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 20.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 788.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 17.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        TextSettings.WordWrap = False
        Text = 'Frequency penalty (default: 0.0)'
        TabOrder = 20
        TabStop = False
      end
      object Layout5: TLayout
        Align = Top
        Position.Y = 810.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 20.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 8
        TabStop = False
        object TrackBarFP: TTrackBar
          Align = Client
          CanParentFocus = True
          Frequency = 1.000000000000000000
          Max = 20.000000000000000000
          Min = -20.000000000000000000
          Orientation = Horizontal
          Size.Width = 370.000000000000000000
          Size.Height = 20.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 0
          OnTracking = TrackBarFPTracking
        end
        object LabelFP: TLabel
          Align = Right
          StyledSettings = [Style]
          Margins.Left = 6.000000000000000000
          Position.X = 376.000000000000000000
          Size.Width = 28.000000000000000000
          Size.Height = 20.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Family = 'Roboto'
          TextSettings.Font.Size = 14.000000000000000000
          TextSettings.FontColor = xBEFFFFFF
          TextSettings.HorzAlign = Trailing
          TextSettings.WordWrap = False
          Text = '0.0'
          TabOrder = 71
          TabStop = False
        end
      end
      object Label13: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Left = 5.000000000000000000
        Margins.Top = 10.000000000000000000
        Margins.Right = 5.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.X = 5.000000000000000000
        Position.Y = 840.000000000000000000
        Size.Width = 394.000000000000000000
        Size.Height = 44.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.FontColor = x78FFFFFF
        Text = 
          'Number between -2.0 and 2.0. Positive values penalize new tokens' +
          ' based on their existing frequency in the text so far, decreasin' +
          'g the model'#39's likelihood to repeat the same line verbatim.'
        TabOrder = 16
        TabStop = False
      end
      object Label28: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Left = 5.000000000000000000
        Margins.Top = 10.000000000000000000
        Margins.Right = 5.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.X = 5.000000000000000000
        Position.Y = 961.000000000000000000
        Size.Width = 394.000000000000000000
        Size.Height = 73.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.FontColor = x78FFFFFF
        Text = 
          'An alternative to sampling with temperature, called nucleus samp' +
          'ling, where the model considers the results of the tokens with t' +
          'op_p probability mass. So 0.1 means only the tokens comprising t' +
          'he top 10% probability mass are considered.'#13#10'We generally recomm' +
          'end altering this or temperature but not both.'
        TabOrder = 15
        TabStop = False
      end
      object Layout6: TLayout
        Align = Top
        Position.Y = 931.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 20.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 9
        TabStop = False
        object TrackBarTopP: TTrackBar
          Align = Client
          CanParentFocus = True
          Frequency = 1.000000000000000000
          Max = 10.000000000000000000
          Orientation = Horizontal
          Size.Width = 370.000000000000000000
          Size.Height = 20.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 0
          Value = 10.000000000000000000
          OnTracking = TrackBarTopPTracking
        end
        object LabelTopP: TLabel
          Align = Right
          StyledSettings = [Style]
          Margins.Left = 6.000000000000000000
          Position.X = 376.000000000000000000
          Size.Width = 28.000000000000000000
          Size.Height = 20.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Family = 'Roboto'
          TextSettings.Font.Size = 14.000000000000000000
          TextSettings.FontColor = xBEFFFFFF
          TextSettings.HorzAlign = Trailing
          TextSettings.WordWrap = False
          Text = '0.0'
          TabOrder = 71
          TabStop = False
        end
      end
      object Label30: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 20.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 909.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 17.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.Font.Size = 14.000000000000000000
        TextSettings.FontColor = xB4FFFFFF
        TextSettings.WordWrap = False
        Text = 'Top P (default: 1.0)'
        TabOrder = 18
        TabStop = False
      end
      object LabelAppearance: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Top = 30.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.Y = 75.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 22.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.Font.Size = 18.000000000000000000
        TextSettings.FontColor = xFFE9E9E9
        TextSettings.WordWrap = False
        Text = 'General settings'
        TabOrder = 0
        TabStop = False
      end
      object Layout7: TLayout
        Align = Top
        Padding.Top = 4.000000000000000000
        Padding.Bottom = 4.000000000000000000
        Margins.Top = 20.000000000000000000
        Position.Y = 231.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 30.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 2
        TabStop = False
        object SwitchUseFunctions: TSwitch
          Align = Right
          IsChecked = False
          Margins.Top = 2.000000000000000000
          Margins.Bottom = 2.000000000000000000
          Position.X = 359.000000000000000000
          Position.Y = 6.000000000000000000
          Size.Width = 45.000000000000000000
          Size.Height = 18.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 1
        end
        object Label34: TLabel
          Align = Client
          AutoSize = True
          StyledSettings = [Style]
          Size.Width = 359.000000000000000000
          Size.Height = 22.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Family = 'Roboto'
          TextSettings.Font.Size = 14.000000000000000000
          TextSettings.FontColor = xB4FFFFFF
          TextSettings.WordWrap = False
          Text = 'Use functions'
          TabOrder = 0
          TabStop = False
        end
      end
      object Label35: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Style]
        Margins.Left = 5.000000000000000000
        Margins.Top = 10.000000000000000000
        Margins.Right = 5.000000000000000000
        Margins.Bottom = 5.000000000000000000
        Position.X = 5.000000000000000000
        Position.Y = 301.000000000000000000
        Size.Width = 394.000000000000000000
        Size.Height = 29.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.FontColor = x78FFFFFF
        Text = 
          'In an API call, you can describe functions to gpt-3.5-turbo-0613' +
          ', gpt-3.5-turbo-16k and gpt-4-0613'
        TabOrder = 17
        TabStop = False
      end
      object Layout9: TLayout
        Align = Top
        Padding.Top = 4.000000000000000000
        Padding.Bottom = 4.000000000000000000
        Position.Y = 261.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 30.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 1
        TabStop = False
        object SwitchAutoExecFuncs: TSwitch
          Align = Right
          IsChecked = False
          Margins.Top = 2.000000000000000000
          Margins.Bottom = 2.000000000000000000
          Position.X = 359.000000000000000000
          Position.Y = 6.000000000000000000
          Size.Width = 45.000000000000000000
          Size.Height = 18.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 1
        end
        object Label37: TLabel
          Align = Client
          AutoSize = True
          StyledSettings = [Style]
          Size.Width = 359.000000000000000000
          Size.Height = 22.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Family = 'Roboto'
          TextSettings.Font.Size = 14.000000000000000000
          TextSettings.FontColor = xB4FFFFFF
          TextSettings.WordWrap = False
          Text = 'Auto execution of functions'
          TabOrder = 0
          TabStop = False
        end
      end
      object Layout2: TLayout
        Align = Top
        Position.Y = 1039.000000000000000000
        Size.Width = 404.000000000000000000
        Size.Height = 20.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 30
      end
    end
  end
end


================================================
FILE: ChatGPT.ChatSettings.pas
================================================
unit ChatGPT.ChatSettings;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
  ChatGPT.Overlay, FMX.Objects, FMX.Edit, FMX.Controls.Presentation, FMX.Layouts,
  ChatGPT.Classes, FMX.ComboEdit;

type
  TFrameChatSettings = class(TFrameOveraly)
    LayoutClient: TLayout;
    RectangleFrame: TRectangle;
    LayoutActs: TLayout;
    ButtonCancel: TButton;
    ButtonOk: TButton;
    VertScrollBox: TVertScrollBox;
    ComboEditModel: TComboEdit;
    EditMaxTokens: TEdit;
    ClearEditButton3: TClearEditButton;
    Path2: TPath;
    EditQueryMaxToken: TEdit;
    ClearEditButton4: TClearEditButton;
    Path3: TPath;
    Label1: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    Layout3: TLayout;
    TrackBarTemp: TTrackBar;
    LabelTemp: TLabel;
    Layout1: TLayout;
    TrackBarPP: TTrackBar;
    LabelPP: TLabel;
    Label12: TLabel;
    Label11: TLabel;
    Label15: TLabel;
    Layout5: TLayout;
    TrackBarFP: TTrackBar;
    LabelFP: TLabel;
    Label13: TLabel;
    Label28: TLabel;
    Layout6: TLayout;
    TrackBarTopP: TTrackBar;
    LabelTopP: TLabel;
    Label30: TLabel;
    LabelAppearance: TLabel;
    Layout7: TLayout;
    SwitchUseFunctions: TSwitch;
    Label34: TLabel;
    Label35: TLabel;
    Layout9: TLayout;
    SwitchAutoExecFuncs: TSwitch;
    Label37: TLabel;
    Layout2: TLayout;
    procedure TrackBarTempTracking(Sender: TObject);
    procedure ButtonCancelClick(Sender: TObject);
    procedure ButtonOkClick(Sender: TObject);
    procedure FrameResize(Sender: TObject);
    procedure RectangleBGClick(Sender: TObject);
    procedure TrackBarPPTracking(Sender: TObject);
    procedure TrackBarFPTracking(Sender: TObject);
    procedure TrackBarTopPTracking(Sender: TObject);
    procedure ComboEditModelMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; var Handled: Boolean);
  private
    FProcCallback: TProc<TFrameChatSettings, Boolean>;
    FLayoutClientWidth: Single;
    FLayoutClientHeight: Single;
  protected
    procedure SetMode(const Value: TWindowMode); override;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Cancel; override;
    class procedure Execute(AParent: TControl; ProcSet: TProc<TFrameChatSettings>; ProcExecuted: TProc<TFrameChatSettings, Boolean>);
  end;

var
  FrameChatSettings: TFrameChatSettings;

implementation

uses
  System.Math, FMX.Ani, HGM.FMX.Ani, ChatGPT.Manager;

{$R *.fmx}

{ TFrameChatSettings }

procedure TFrameChatSettings.Cancel;
begin
  if Assigned(FProcCallback) then
    FProcCallback(Self, False);
  Release;
end;

procedure TFrameChatSettings.ComboEditModelMouseWheel(Sender: TObject;
  Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean);
begin
  Handled := True;
  VertScrollBox.AniCalculations.MouseWheel(0, -WheelDelta);
end;

procedure TFrameChatSettings.ButtonCancelClick(Sender: TObject);
begin
  Cancel;
end;

procedure TFrameChatSettings.ButtonOkClick(Sender: TObject);
begin
  if Assigned(FProcCallback) then
    FProcCallback(Self, True);
  Release;
end;

constructor TFrameChatSettings.Create(AOwner: TComponent);
begin
  inherited;
  FLayoutClientWidth := LayoutClient.Width;
  FLayoutClientHeight := LayoutClient.Height;
  VertScrollBox.AniCalculations.Animation := True;
  //VertScrollBox.AniCalculations.Interval := 1;
  VertScrollBox.AniCalculations.Averaging := True;
  VertScrollBox.ViewportPosition := TPoint.Zero;
  ComboEditModel.Items.Clear;
  ComboEditModel.Items.AddStrings(ActualModels);
  Name := '';
end;

class procedure TFrameChatSettings.Execute(AParent: TControl; ProcSet: TProc<TFrameChatSettings>; ProcExecuted: TProc<TFrameChatSettings, Boolean>);
begin
  var Frame := TFrameChatSettings.Create(AParent);
  Frame.Parent := AParent;
  Frame.FProcCallback := ProcExecuted;
  Frame.Align := TAlignLayout.Contents;
  Frame.BringToFront;
  if Assigned(ProcSet) then
    ProcSet(Frame);
  Frame.TrackBarTempTracking(nil);
  Frame.TrackBarPPTracking(nil);
  Frame.TrackBarFPTracking(nil);
  Frame.TrackBarTopPTracking(nil);
  Frame.ButtonCancel.SetFocus;
end;

procedure TFrameChatSettings.FrameResize(Sender: TObject);
begin
  LayoutClient.Width := Min(FLayoutClientWidth, Width);
  LayoutClient.Height := Min(FLayoutClientHeight, Height);
end;

procedure TFrameChatSettings.RectangleBGClick(Sender: TObject);
begin
  Cancel;
end;

procedure TFrameChatSettings.SetMode(const Value: TWindowMode);
begin
  inherited;
  if Mode = TWindowMode.Compact then
  begin
    LayoutClient.Align := TAlignLayout.Client;
    RectangleFrame.Corners := [];
  end
  else
  begin
    LayoutClient.Align := TAlignLayout.Center;
    RectangleFrame.Corners := AllCorners;
  end;
  FrameResize(nil);
end;

procedure TFrameChatSettings.TrackBarFPTracking(Sender: TObject);
begin
  LabelFP.Text := FormatFloat('0.0', TrackBarFP.Value / 10);
end;

procedure TFrameChatSettings.TrackBarPPTracking(Sender: TObject);
begin
  LabelPP.Text := FormatFloat('0.0', TrackBarPP.Value / 10);
end;

procedure TFrameChatSettings.TrackBarTempTracking(Sender: TObject);
begin
  LabelTemp.Text := FormatFloat('0.0', TrackBarTemp.Value / 10);
end;

procedure TFrameChatSettings.TrackBarTopPTracking(Sender: TObject);
begin
  LabelTopP.Text := FormatFloat('0.0', TrackBarTopP.Value / 10);
end;

end.



================================================
FILE: ChatGPT.Classes.pas
================================================
unit ChatGPT.Classes;

interface

uses
  System.SysUtils, OpenAI.Chat.Functions;

{$SCOPEDENUMS ON}

type
  TWindowMode = (Compact, Full);

  TPartType = (Text, Code);

  TMessageKind = (User, Assistant, System, Error, Func);

  TMessageKindHelper = record helper for TMessageKind
    function ToString: string;
    class function FromString(const Value: string): TMessageKind; static;
  end;

  TMessageFuncState = (Wait, Success, Error, Executing);

  TPart = record
    PartType: TPartType;
    Content: string;
    Language: string;
  end;

  TUnderMouse = record
    WordStart: Int64;
    WordLength: Int64;
    WordLine: Int64;
    Text: string;
  end;

  TOnFuncExecute = procedure(Sender: TObject; const FuncName, FuncArgs: string; Callback: TProc<Boolean, string>) of object;

  TOnNeedFuncList = procedure(Sender: TObject; out Items: TArray<IChatFunction>) of object;

  TOnTextUpdated = procedure(Sender: TObject; const MessageId, Text: string) of object;

const
  MaxMessageWidth = 850;

procedure OpenUrl(const URL: string);

implementation

uses
  {$IFDEF ANDROID}
  Androidapi.Helpers, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.NET,
  {$ENDIF}
  {$IF DEFINED(IOS) OR DEFINED(IOS64)}
  MacApi.Helpers, iOSApi.Foundation, FMX.Helpers.iOS,
  {$ENDIF}
  {$IFDEF POSIX}
  Posix.Stdlib,
  {$ENDIF POSIX}
  {$IFDEF MSWINDOWS}
  ShellAPI, DarkModeApi.FMX, FMX.Platform.Win,
  {$ENDIF}
  FMX.Platform;

procedure OpenUrl(const URL: string);
begin
  {$IFDEF ANDROID}
  TAndroidHelper.Context.startActivity(TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW, StrToJURI(URL)));
  {$ENDIF}
  {$IF DEFINED(IOS) OR DEFINED(IOS64)}
  SharedApplication.OpenURL(StrToNSUrl(URL));
  {$ENDIF}
  {$IFDEF POSIX}
  _system(PAnsiChar('open ' + AnsiString(URL)));
  {$ENDIF POSIX}
  {$IFDEF MSWINDOWS}
  ShellExecute(0, 'open', PChar(URL), nil, nil, 1);
  {$ENDIF}
end;

{ TMessageKindHelper }

class function TMessageKindHelper.FromString(const Value: string): TMessageKind;
begin
  if Value = 'system' then
    Exit(TMessageKind.System)
  else if Value = 'user' then
    Exit(TMessageKind.User)
  else if Value = 'assistant' then
    Exit(TMessageKind.Assistant)
  else if Value = 'error' then
    Exit(TMessageKind.Error)
  else if Value = 'function' then
    Exit(TMessageKind.Func)
  else
    Result := TMessageKind.User;
end;

function TMessageKindHelper.ToString: string;
begin
  case Self of
    TMessageKind.System:
      Result := 'system';
    TMessageKind.User:
      Result := 'user';
    TMessageKind.Assistant:
      Result := 'assistant';
    TMessageKind.Error:
      Result := 'error';
    TMessageKind.Func:
      Result := 'function';
  end;
end;

end.



================================================
FILE: ChatGPT.Code.pas
================================================
unit ChatGPT.Code;

interface

uses
  System.SysUtils, FMX.Graphics, System.UITypes, System.Generics.Collections,
  FMX.TextLayout;

type
  TKeyWord = class
    Word: TArray<string>;
    Font: TFont;
    Color: TAlphaColor;
    constructor Create;
    destructor Destroy; override;
  end;

  TKeyWords = class(TObjectList<TKeyWord>)
    function FindWord(const Value: string; out Key: TKeyWord): Boolean;
  end;

  TTextAttributedRangeData = record
  public
    Range: TTextRange;
    Attribute: TTextAttribute;
    constructor Create(const ARange: TTextRange; const AAttribute: TTextAttribute);
  end;

  TLineTextAttributedRange = class(TList<TTextAttributedRangeData>)
  private
    FText: string;
  public
    property Text: string read FText write FText;
  end;

  TCodeSyntaxClass = class of TCodeSyntax;

  TRegisteredSyntax = record
    SyntaxClass: TCodeSyntaxClass;
    Languages: TArray<string>;
  end;

  TCachedAttributes = TDictionary<Integer, TArray<TTextAttributedRangeData>>;

  TCodeSyntax = class abstract
  private
    class var
      FRegitered: TList<TRegisteredSyntax>;
  protected
    FCached: TCachedAttributes;
    FDefaultFont: TFont;
    FDefaultColor: TAlphaColor;
  public
    constructor Create(DefaultFont: TFont; DefaultColor: TAlphaColor); virtual;
    destructor Destroy; override;
    function GetAttributesForLine(const Line: string; const Index: Integer): TArray<TTextAttributedRangeData>; virtual; abstract;
    procedure DropCache; virtual;
    class function FindSyntax(const Language: string; DefaultFont: TFont; DefaultColor: TAlphaColor): TCodeSyntax;
    class procedure RegisterSyntax(Languages: TArray<string>; CodeSyntaxClass: TCodeSyntaxClass);
  end;

implementation

{ TKeyWord }

constructor TKeyWord.Create;
begin
  inherited;
  Font := TFont.Create;
end;

destructor TKeyWord.Destroy;
begin
  Font.Free;
  inherited;
end;

{ TKeyWords }

function TKeyWords.FindWord(const Value: string; out Key: TKeyWord): Boolean;
begin
  var LowValue := Value.ToLower;
  for var KeyWord in Self do
    for var Word in KeyWord.Word do
    begin
      if Word = LowValue then
      begin
        Key := KeyWord;
        Exit(True);
      end;
    end;
  Result := False;
end;

{ TTextAttributedRangeData }

constructor TTextAttributedRangeData.Create(const ARange: TTextRange; const AAttribute: TTextAttribute);
begin
  Self.Range := ARange;
  Self.Attribute := AAttribute;
end;

{ TCodeSyntax }

constructor TCodeSyntax.Create(DefaultFont: TFont; DefaultColor: TAlphaColor);
begin
  inherited Create;
  FCached := TCachedAttributes.Create;
  FDefaultFont := DefaultFont;
  FDefaultColor := DefaultColor;
end;

destructor TCodeSyntax.Destroy;
begin
  FCached.Free;
  inherited;
end;

procedure TCodeSyntax.DropCache;
begin
  FCached.Clear;
end;

class function TCodeSyntax.FindSyntax(const Language: string; DefaultFont: TFont; DefaultColor: TAlphaColor): TCodeSyntax;
begin
  if not Assigned(FRegitered) then
    Exit(nil);
  for var Item in FRegitered do
    for var Lang in Item.Languages do
      if Lang = Language.ToLower then
        Exit(Item.SyntaxClass.Create(DefaultFont, DefaultColor));
  Result := nil;
end;

class procedure TCodeSyntax.RegisterSyntax(Languages: TArray<string>; CodeSyntaxClass: TCodeSyntaxClass);
begin
  if not Assigned(FRegitered) then
    FRegitered := TList<TRegisteredSyntax>.Create;
  var Reg: TRegisteredSyntax;
  Reg.SyntaxClass := CodeSyntaxClass;
  Reg.Languages := Languages;
  FRegitered.Add(Reg);
end;

initialization

finalization
  TCodeSyntax.FRegitered.Free;

end.



================================================
FILE: ChatGPT.FrameChat.fmx
================================================
object FrameChat: TFrameChat
  Align = Contents
  Size.Width = 1006.000000000000000000
  Size.Height = 786.000000000000000000
  Size.PlatformDefault = False
  object RectangleBG: TRectangle
    Align = Contents
    Fill.Color = xFF343541
    Locked = True
    HitTest = False
    Size.Width = 1006.000000000000000000
    Size.Height = 786.000000000000000000
    Size.PlatformDefault = False
    Stroke.Kind = None
  end
  object VertScrollBoxChat: TVertScrollBox
    Align = Contents
    Padding.Bottom = 160.000000000000000000
    Size.Width = 1006.000000000000000000
    Size.Height = 786.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 0
    OnViewportPositionChange = VertScrollBoxChatViewportPositionChange
    Viewport.Width = 990.000000000000000000
    Viewport.Height = 786.000000000000000000
    object LayoutTyping: TLayout
      Align = Top
      Padding.Left = 16.000000000000000000
      Padding.Top = 16.000000000000000000
      Padding.Right = 16.000000000000000000
      Padding.Bottom = 16.000000000000000000
      Size.Width = 990.000000000000000000
      Size.Height = 62.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 0
      OnResize = LayoutTypingResize
      OnResized = LayoutTypingResize
      object RectangleTypeBG: TRectangle
        Align = Contents
        Fill.Color = x14FFFFFF
        Locked = True
        Size.Width = 990.000000000000000000
        Size.Height = 62.000000000000000000
        Size.PlatformDefault = False
        Stroke.Kind = None
      end
      object LayoutTypingContent: TLayout
        Align = HorzCenter
        Locked = True
        Position.X = 117.000000000000000000
        Position.Y = 16.000000000000000000
        Size.Width = 755.000000000000000000
        Size.Height = 30.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 2
        object Layout3: TLayout
          Align = Left
          Margins.Right = 14.000000000000000000
          Size.Width = 30.000000000000000000
          Size.Height = 30.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 2
          object RectangleBot: TRectangle
            Align = Top
            Fill.Color = xFF10A37F
            Size.Width = 30.000000000000000000
            Size.Height = 30.000000000000000000
            Size.PlatformDefault = False
            Stroke.Kind = None
            XRadius = 2.000000000000000000
            YRadius = 2.000000000000000000
            object Path3: TPath
              Align = Center
              Data.Path = {
                0F010000000000002D21164232F786410200000057EC1742B762784102000000
                928B1842F38E61410200000054F4174272F94A4102000000155D1742F1633441
                02000000D792154279921E410200000039B41242C2FA0A41020000004D730E42
                75B0DA4002000000EBF3074261C3AB400200000032260042B6F38F4002000000
                F2B0F04141486840020000004547DF4109C45940020000006F92CE412E737640
                020000006C09C741E48332400200000074C6BD41E17AF83F02000000D567B341
                3884AE3F020000003709A941711B493F0200000098CC9D419C87FB3E02000000
                47729241E90C003F02000000CC5D81416876FD3E02000000C66D61410282953F
                020000004BC8454157041B4002000000D1222A4184476B400200000094931541
                0A4BAE400200000034110B41014DEF400200000090A0E9405969F84002000000
                5B94BF40607605410200000070CE9A4001CD1241020000000A116C40A3232041
                0200000048C42E404F4031410200000024D10140F4FD444102000000D3DA743F
                AC8B6241020000007A70FF3EF16382410200000033C1383FE561934102000000
                3ACA713FA45FA44102000000FB05EB3FF55BB44102000000E9265140CE08C141
                020000004F753440A5CECB41020000001B812A408638D74102000000DCF43340
                4783E241020000009D683D4007CEED4102000000740C5A40AEB6F84102000000
                D7FA834055410142020000005C03A640E2A90842020000005DFED9405F870E42
                020000001C360C415501124202000000F46C2B414A7B1542020000004F404E41
                A36316420200000093A96F41C89814420200000099BB7E41C2D7184202000000
                F9A088411C3C1C420200000063FF9241E18B1E4202000000015E9D418CDB2042
                02000000A09AA841E908224202000000F1F4B341CCFF214202000000AC0BC541
                8805224202000000D7B4D54112541F4202000000CE88E3410E4F1A4202000000
                FB5CF141094A15420200000012A5FB41D0330E42020000009672004254120642
                02000000C4020642CCEE0442020000004D440B426A9E02420200000015DD0F42
                6891FE4102000000C375144232E6F741020000008C4A1842A857EF4102000000
                CE191B42D578E5410200000019621F4261B2D641020000008E3521424D95C541
                02000000CB5020423199B44102000000226C1F42159DA3410200000009DB1B42
                9CA29341020000002D21164232F78641030000002D21164232F7864100000000
                7FFBB341238A17420200000054F4A541B38C174202000000015E9841DC171542
                020000005F988D41B499104202000000AF148E41CF77104202000000CCEE8E41
                023C104202000000EE7C8F417D101042010000000534CF412653FB4102000000
                6ACDD0414B6AFA41020000006221D2419318F94102000000E70CD3419D80F741
                02000000A1F8D341A7E8F541020000004D73D4416519F441020000006F70D441
                8F42F241010000006F70D441006F984101000000D35EEF41E7FBA74102000000
                DE82EF41ED0DA84102000000FFA1EF418D28A841020000008CB9EF418649A841
                02000000E5D0EF417F6AA84102000000A4DFEF41CB90A84102000000C3E4EF41
                BBB8A84101000000C3E4EF41781CF34102000000A4DFEF410080014202000000
                8A8EE941CC1D094202000000C353DE4185BC0E4202000000FC18D341575B1442
                02000000D3DEC341BC851742020000007FFBB341238A1742030000007FFBB341
                238A1742000000007A8DCC401B0DF841020000007172B04010E9EB4102000000
                4451A64083AFDD4102000000F2EFAF4098DDCF41020000006BD4B1404C26D041
                02000000A722B54087A7D04102000000ED81B740C5FED041010000001B2F5B41
                64CCF54102000000295C5E41F5B9F6410200000009F961414C37F74102000000
                B5A665414C37F74102000000F85369414C37F74102000000D8F06C41F5B9F641
                02000000E71D704164CCF5410100000017D9C541E5E1C8410100000017D9C541
                B3FBE7410200000057DBC5414024E841020000008FD3C541014DE84102000000
                5BC2C541DE71E8410200000027B1C541BC96E841020000002497C541E3B6E841
                020000009476C54142CFE84101000000B90D8541B1FF064202000000B98D6E41
                66F70A42020000002CD44D41EF090C42020000007E1D2F414AFB094202000000
                A5661041A5EC0742020000004469EC40BBE70242020000007A8DCC401B0DF841
                030000007A8DCC401B0DF841000000009981894010E95941020000006B7DA540
                C89841410200000075B0D1407FFB2E41020000007D2E0341BD52254102000000
                7D2E0341BA6B2641020000005A1E0341645D2841020000005A1E0341AEB62941
                010000005A1E0341C9769E41020000009E1803416A4DA04102000000AE0D0441
                431CA2410200000045E4054105B4A34102000000DCBA0741924BA54102000000
                04620A41159DA64102000000FD930D41F085A7410100000012949441006FD441
                01000000C74B7341B3FBE34102000000C80773413A12E441020000008CB97241
                BE1FE44102000000736872416E23E44102000000591772411E27E44102000000
                6DC57141C520E44102000000787A7141CB10E44101000000734BE14079D8BE41
                020000008048AA407CE1B641020000002D268240BAC9A941020000008D626340
                D26F9A4102000000C07842401E168B410200000070995340F775754102000000
                9981894010E95941030000009981894010E9594100000000D7A3FF41DE71A041
                010000007FD9B141BF0E674101000000E3C7CC4138F8474102000000E2E9CC41
                92CB4741020000000011CD4121B04741020000008C39CD41C1A8474102000000
                1962CD4162A1474102000000DB8ACD417DAE47410200000055B0CD4170CE4741
                010000006A0D074259178941020000009FFC0B42C1CA8E4102000000BE011042
                832F97410200000074A41242584AA14102000000114715422C65AB4102000000
                366B1642C1CAB64102000000CCEE1542AF25C24102000000617215429D80CD41
                02000000515A13427958D84102000000AFE50F423E68E14102000000F2700C42
                0378EA410200000019C40742A45FF14102000000366B02421450F54102000000
                366B0242F2C1F44102000000366B024252C9F34102000000366B0242781CF341
                01000000366B02420681A94102000000296D024236ABA741020000008A300242
                C6DCA5410200000099BB01423945A44102000000A8460142ACADA24102000000
                B29D0042C05BA14102000000D7A3FF41DE71A04103000000D7A3FF41DE71A041
                00000000D5380D426E3470410200000050FC0C42BE9F6F410200000089920C42
                90A06E4102000000A8460C427CF26D410100000004D6D841D656244102000000
                7D3FD741857C2241020000004171D54141822141020000006B9AD34141822141
                02000000CAC3D14141822141020000005AF5CF41857C224102000000D35ECE41
                D656244101000000AF9480413D2C7E4101000000AF948041A1F83F4102000000
                6F9280411EA73F4102000000379A804104563F41020000006BAB80414A0C3F41
                020000009FBC80418FC23E4102000000A1D6804141823E410200000032F78041
                83513E41010000000D60C1410C02E840020000000E3ECB41BC3FD14002000000
                C286D6414833C640020000000AE8E1417C27C840020000005249ED41C51BCA40
                020000008C4AF84111FCD840020000004ED10042E50AF340020000003C7D0542
                DD8C0641020000000523094296A118410200000067550B424CA62D4102000000
                C8870D42CEAA424102000000832F0E4283C0594102000000D5380D426E347041
                03000000D5380D426E34704100000000DFE063410389AF4101000000D2002E41
                1CFC9F4102000000BBB82D4116EA9F4102000000107A2D4176CF9F4102000000
                5E4B2D417DAE9F4102000000AC1C2D41848D9F4102000000C5FE2C4138679F41
                02000000F1F42C41143F9F4101000000F1F42C41AEB6294102000000A1F82C41
                5DED124102000000107A33413A3BF94002000000DDB53F4160C8D24002000000
                13F24B418655AC400200000038675D41A0A68D40020000003D0A724122A67440
                02000000A156834104FF4D4002000000B7D18E412FA83F4002000000841E9A41
                0E4F4B4002000000856BA541EDF55640020000003A12B0414B1F7C4002000000
                C3D3B841B0389B40020000007357B84102489C4002000000FA7EB74118269E40
                0200000035EFB641E8829F40010000003B706E41DB5C194102000000713D6B41
                342E1B4102000000EA95684124D11D410200000077BE66416900214102000000
                6DE76441832F24410200000013F263419FCD27410200000066F76341E17A2B41
                01000000DFE063410389AF4103000000DFE063410389AF410000000068918041
                28FE8F4101000000E336A341FDF677410100000029DCC541E1FA8F4101000000
                29DCC541EEFCB74101000000E336A34185FCCB410100000068918041EEFCB741
                010000006891804128FE8F41030000006891804128FE8F41}
              Fill.Color = claWhite
              Size.Width = 20.000000000000000000
              Size.Height = 20.000000000000000000
              Size.PlatformDefault = False
              Stroke.Kind = None
              WrapMode = Fit
            end
          end
        end
        object Layout4: TLayout
          Align = Client
          Locked = True
          Size.Width = 711.000000000000000000
          Size.Height = 30.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 3
          object RectangleIndicate: TRectangle
            Align = Left
            Fill.Color = xFFE6E6E6
            Margins.Top = 7.000000000000000000
            Margins.Bottom = 7.000000000000000000
            Position.Y = 7.000000000000000000
            Size.Width = 10.000000000000000000
            Size.Height = 16.000000000000000000
            Size.PlatformDefault = False
            Stroke.Color = xFFC4C4C4
          end
        end
      end
    end
    object LayoutWelcome: TLayout
      Align = Top
      Locked = True
      Position.Y = 62.000000000000000000
      Size.Width = 990.000000000000000000
      Size.Height = 619.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 3
      OnResize = LayoutWelcomeResize
      OnResized = LayoutWelcomeResize
      object LabelWelcomeTitle: TLabel
        Align = Top
        AutoSize = True
        StyledSettings = [Family]
        Margins.Top = 188.000000000000000000
        Margins.Bottom = 64.000000000000000000
        Position.Y = 188.000000000000000000
        Size.Width = 990.000000000000000000
        Size.Height = 48.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Size = 36.000000000000000000
        TextSettings.Font.StyleExt = {00060000000000000004000000}
        TextSettings.FontColor = xFFECECF1
        TextSettings.HorzAlign = Center
        TextSettings.WordWrap = False
        TextSettings.Trimming = None
        Text = 'ChatGPT'
        TabOrder = 2
      end
      object FlowLayoutWelcome: TFlowLayout
        Align = HorzCenter
        Locked = True
        Position.X = 183.000000000000000000
        Position.Y = 300.000000000000000000
        Size.Width = 624.000000000000000000
        Size.Height = 319.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 1
        Justify = Left
        JustifyLastLine = Left
        FlowDirection = LeftToRight
        OnResize = FlowLayoutWelcomeResize
        OnResized = FlowLayoutWelcomeResize
        object LayoutExampleTitle: TLayout
          Align = Client
          Locked = True
          Size.Width = 208.000000000000000000
          Size.Height = 319.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 2
          object PathExaFull: TPath
            Align = MostTop
            Data.Path = {
              9C00000000000000000080430000104302000000004042430000104302000000
              0000104300404243020000000000104300008043020000000000104300E09E43
              02000000004042430000B84302000000000080430000B8430200000000E09E43
              0000B843020000000000B84300E09E43020000000000B8430000804302000000
              0000B843004042430200000000E09E4300001043020000000000804300001043
              03000000000080430000104300000000000080430000A84302000000DFCF5343
              0000A84302000000000030431018964302000000000030430000804302000000
              00003043DFCF534302000000DFCF534300003043020000000000804300003043
              020000001018964300003043020000000000A843DFCF5343020000000000A843
              00008043020000000000A8431018964302000000101896430000A84302000000
              000080430000A84303000000000080430000A84300000000000080430000E042
              02000000A06A84430000E04202000000000088437FAAD1420200000000008843
              0000C042010000000000884300008042020000000000884302AB5C4202000000
              A06A84430000404202000000000080430000404202000000C02A774300004042
              020000000000704302AB5C420200000000007043000080420100000000007043
              0000C04202000000000070437FAAD14202000000C12A77430000E04202000000
              000080430000E04203000000000080430000E04200000000000080430000C843
              02000000C02A77430000C84302000000000070436095CB430200000000007043
              0000D04301000000000070430000E0430200000000007043A06AE44302000000
              C02A77430000E84302000000000080430000E84302000000A06A84430000E843
              0200000000008843A06AE44302000000000088430000E0430100000000008843
              0000D04302000000000088436095CB4302000000A06A84430000C84302000000
              000080430000C84303000000000080430000C843000000001038BE43C12A1A43
              010000001088C943C18A03430200000010A8CC438295FA420200000010A8CC43
              8255E642020000001088C94382D5D942020000001068C6438255CD4202000000
              1058C1438255CD42020000001038BE4382D5D9420100000010E8B243C18A0343
              0200000010C8AF43C1CA09430200000010C8AF43C1EA13430200000010E8B243
              C12A1A43020000001008B643C16A2043020000001018BB43C16A204302000000
              1038BE43C12A1A43030000001038BE43C12A1A4300000000DF8F0343C1EAB243
              01000000BEDFD942C13ABE4302000000BE5FCD42A05AC14302000000BE5FCD42
              A06AC64302000000BEDFD942A08AC94302000000BE5FE642A0AACC4302000000
              BE9FFA42A0AACC4302000000DF8F0343A08AC94301000000DF2F1A43C13ABE43
              02000000DF6F20431118BB4302000000DF6F2043A00AB64302000000DF2F1A43
              C1EAB2430200000021F01343A0CAAF4302000000DFCF0943F0C7AF4302000000
              DF8F0343C1EAB24303000000DF8F0343C1EAB243000000000000E04200008043
              020000000000E042C02A7743020000007FAAD14200007043020000000000C042
              000070430100000000008042000070430200000002AB5C420000704302000000
              00004042C02A77430200000000004042000080430200000000004042A06A8443
              0200000002AB5C4200008843020000000000804200008843010000000000C042
              00008843020000007FAAD14200008843020000000000E042A06A844302000000
              0000E04200008043030000000000E04200008043000000000000E04300007043
              010000000000D04300007043020000006095CB4300007043020000000000C843
              C02A7743020000000000C84300008043020000000000C843A06A844302000000
              6095CB4300008843020000000000D04300008843010000000000E04300008843
              02000000A06AE44300008843020000000000E843A06A8443020000000000E843
              00008043020000000000E843C02A774302000000A06AE4430000704302000000
              0000E04300007043030000000000E04300007043000000007F8A0343C12A1A43
              02000000C1CA0943C16A204302000000C0EA1343C16A2043020000007F2A1A43
              C12A1A4302000000C16A2043C1EA134302000000C16A2043C1CA094302000000
              7F2A1A43C18A0343010000007F8A034382D5D94202000000FE94FA428255CD42
              020000008155E6428255CD4202000000FED4D94282D5D94202000000FE54CD42
              8255E64202000000FE54CD428295FA4202000000FED4D942C18A034301000000
              7F8A0343C12A1A43030000007F8A0343C12A1A4300000000C13ABE43F0E7B243
              020000001118BB43F0C7AF4302000000A00AB643F0C7AF4302000000C1EAB243
              F0E7B24302000000A0CAAF43F007B6430200000011C8AF43F017BB4302000000
              C1EAB243F037BE4301000000C13ABE43F087C94302000000A05AC143F0A7CC43
              02000000A06AC643F0A7CC4302000000A08AC943F087C94302000000A0AACC43
              F067C64302000000A0AACC43F057C14302000000A08AC943F037BE4301000000
              C13ABE43F0E7B24303000000C13ABE43F0E7B243}
            Fill.Color = xFFECECF1
            Locked = True
            Margins.Top = 2.000000000000000000
            Margins.Bottom = 4.000000000000000000
            Position.Y = 2.000000000000000000
            Size.Width = 208.000000000000000000
            Size.Height = 24.000000000000000000
            Size.PlatformDefault = False
            Stroke.Kind = None
            WrapMode = Fit
          end
          object ButtonExample3: TButton
            Tag = 1
            OnTap = ButtonExample3Tap
            Align = Top
            StyledSettings = [Family, Style]
            Margins.Left = 7.000000000000000000
            Margins.Top = 7.000000000000000000
            Margins.Right = 7.000000000000000000
            Margins.Bottom = 7.000000000000000000
            Position.X = 7.000000000000000000
            Position.Y = 226.000000000000000000
            Size.Width = 194.000000000000000000
            Size.Height = 65.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_welcome'
            TabOrder = 0
            Text = '"How do I make an HTTP request in Javascript?" '#8594
            TextSettings.Font.Size = 14.000000000000000000
            TextSettings.FontColor = xFFECECF1
            TextSettings.WordWrap = True
            OnClick = ButtonExample3Click
          end
          object ButtonExample2: TButton
            Tag = 1
            OnTap = ButtonExample2Tap
            Align = Top
            StyledSettings = [Family, Style]
            Margins.Left = 7.000000000000000000
            Margins.Top = 7.000000000000000000
            Margins.Right = 7.000000000000000000
            Margins.Bottom = 7.000000000000000000
            Position.X = 7.000000000000000000
            Position.Y = 147.000000000000000000
            Size.Width = 194.000000000000000000
            Size.Height = 65.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_welcome'
            TabOrder = 1
            Text = '"Got any creative ideas for a 10 year old'#8217's birthday?" '#8594
            TextSettings.Font.Size = 14.000000000000000000
            TextSettings.FontColor = xFFECECF1
            TextSettings.WordWrap = True
            OnClick = ButtonExample2Click
          end
          object ButtonExample1: TButton
            Tag = 1
            OnTap = ButtonExample1Tap
            Align = Top
            StyledSettings = [Family, Style]
            Margins.Left = 7.000000000000000000
            Margins.Top = 7.000000000000000000
            Margins.Right = 7.000000000000000000
            Margins.Bottom = 7.000000000000000000
            Position.X = 7.000000000000000000
            Position.Y = 68.000000000000000000
            Size.Width = 194.000000000000000000
            Size.Height = 65.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_welcome'
            TabOrder = 2
            Text = '"Explain quantum computing in simple terms" '#8594
            TextSettings.Font.Size = 14.000000000000000000
            TextSettings.FontColor = xFFECECF1
            TextSettings.WordWrap = True
            OnClick = ButtonExample1Click
          end
          object Layout5: TLayout
            Align = Top
            Locked = True
            Position.Y = 30.000000000000000000
            Size.Width = 208.000000000000000000
            Size.Height = 31.000000000000000000
            Size.PlatformDefault = False
            TabOrder = 3
            object Label2: TLabel
              Align = Center
              AutoSize = True
              StyledSettings = [Family, Style]
              Locked = True
              Size.Width = 75.000000000000000000
              Size.Height = 24.000000000000000000
              Size.PlatformDefault = False
              TextSettings.Font.Size = 18.000000000000000000
              TextSettings.FontColor = xFFECECF1
              TextSettings.HorzAlign = Center
              TextSettings.WordWrap = False
              Text = 'Examples'
              TabOrder = 3
              object PathExaCompact: TPath
                Align = Left
                Data.Path = {
                  9C00000000000000000080430000104302000000004042430000104302000000
                  0000104300404243020000000000104300008043020000000000104300E09E43
                  02000000004042430000B84302000000000080430000B8430200000000E09E43
                  0000B843020000000000B84300E09E43020000000000B8430000804302000000
                  0000B843004042430200000000E09E4300001043020000000000804300001043
                  03000000000080430000104300000000000080430000A84302000000DFCF5343
                  0000A84302000000000030431018964302000000000030430000804302000000
                  00003043DFCF534302000000DFCF534300003043020000000000804300003043
                  020000001018964300003043020000000000A843DFCF5343020000000000A843
                  00008043020000000000A8431018964302000000101896430000A84302000000
                  000080430000A84303000000000080430000A84300000000000080430000E042
                  02000000A06A84430000E04202000000000088437FAAD1420200000000008843
                  0000C042010000000000884300008042020000000000884302AB5C4202000000
                  A06A84430000404202000000000080430000404202000000C02A774300004042
                  020000000000704302AB5C420200000000007043000080420100000000007043
                  0000C04202000000000070437FAAD14202000000C12A77430000E04202000000
                  000080430000E04203000000000080430000E04200000000000080430000C843
                  02000000C02A77430000C84302000000000070436095CB430200000000007043
                  0000D04301000000000070430000E0430200000000007043A06AE44302000000
                  C02A77430000E84302000000000080430000E84302000000A06A84430000E843
                  0200000000008843A06AE44302000000000088430000E0430100000000008843
                  0000D04302000000000088436095CB4302000000A06A84430000C84302000000
                  000080430000C84303000000000080430000C843000000001038BE43C12A1A43
                  010000001088C943C18A03430200000010A8CC438295FA420200000010A8CC43
                  8255E642020000001088C94382D5D942020000001068C6438255CD4202000000
                  1058C1438255CD42020000001038BE4382D5D9420100000010E8B243C18A0343
                  0200000010C8AF43C1CA09430200000010C8AF43C1EA13430200000010E8B243
                  C12A1A43020000001008B643C16A2043020000001018BB43C16A204302000000
                  1038BE43C12A1A43030000001038BE43C12A1A4300000000DF8F0343C1EAB243
                  01000000BEDFD942C13ABE4302000000BE5FCD42A05AC14302000000BE5FCD42
                  A06AC64302000000BEDFD942A08AC94302000000BE5FE642A0AACC4302000000
                  BE9FFA42A0AACC4302000000DF8F0343A08AC94301000000DF2F1A43C13ABE43
                  02000000DF6F20431118BB4302000000DF6F2043A00AB64302000000DF2F1A43
                  C1EAB2430200000021F01343A0CAAF4302000000DFCF0943F0C7AF4302000000
                  DF8F0343C1EAB24303000000DF8F0343C1EAB243000000000000E04200008043
                  020000000000E042C02A7743020000007FAAD14200007043020000000000C042
                  000070430100000000008042000070430200000002AB5C420000704302000000
                  00004042C02A77430200000000004042000080430200000000004042A06A8443
                  0200000002AB5C4200008843020000000000804200008843010000000000C042
                  00008843020000007FAAD14200008843020000000000E042A06A844302000000
                  0000E04200008043030000000000E04200008043000000000000E04300007043
                  010000000000D04300007043020000006095CB4300007043020000000000C843
                  C02A7743020000000000C84300008043020000000000C843A06A844302000000
                  6095CB4300008843020000000000D04300008843010000000000E04300008843
                  02000000A06AE44300008843020000000000E843A06A8443020000000000E843
                  00008043020000000000E843C02A774302000000A06AE4430000704302000000
                  0000E04300007043030000000000E04300007043000000007F8A0343C12A1A43
                  02000000C1CA0943C16A204302000000C0EA1343C16A2043020000007F2A1A43
                  C12A1A4302000000C16A2043C1EA134302000000C16A2043C1CA094302000000
                  7F2A1A43C18A0343010000007F8A034382D5D94202000000FE94FA428255CD42
                  020000008155E6428255CD4202000000FED4D94282D5D94202000000FE54CD42
                  8255E64202000000FE54CD428295FA4202000000FED4D942C18A034301000000
                  7F8A0343C12A1A43030000007F8A0343C12A1A4300000000C13ABE43F0E7B243
                  020000001118BB43F0C7AF4302000000A00AB643F0C7AF4302000000C1EAB243
                  F0E7B24302000000A0CAAF43F007B6430200000011C8AF43F017BB4302000000
                  C1EAB243F037BE4301000000C13ABE43F087C94302000000A05AC143F0A7CC43
                  02000000A06AC643F0A7CC4302000000A08AC943F087C94302000000A0AACC43
                  F067C64302000000A0AACC43F057C14302000000A08AC943F037BE4301000000
                  C13ABE43F0E7B24303000000C13ABE43F0E7B243}
                Fill.Color = xFFECECF1
                Locked = True
                Margins.Left = -35.000000000000000000
                Position.X = -35.000000000000000000
                Size.Width = 24.000000000000000000
                Size.Height = 24.000000000000000000
                Size.PlatformDefault = False
                Stroke.Kind = None
                WrapMode = Fit
              end
            end
          end
        end
        object LayoutCapabilitiesTitle: TLayout
          Align = Client
          Locked = True
          Size.Width = 208.000000000000000000
          Size.Height = 319.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 1
          object PathCapFull: TPath
            Align = MostTop
            Data.Path = {
              340000000000000085250B413C4A253D0200000096890E41D32E063E02000000
              2E7F1041B0AFB53E02000000F1E30F415A0D153F010000006B7101411500C040
              0100000097FF47411500C040020000005F074B411500C04002000000CDCC4D41
              A06CC34002000000BB274F4145D8C8400200000041825041E943CE4002000000
              B537504183C0D44002000000FE654E419A99D940010000008ECCDC40CDCC6C41
              02000000855FD8401AC06F4102000000857CD04007CE70410200000063B4C940
              865A6F410200000042ECC2406DE76D41020000001101BF4054526A4102000000
              8B37C0404FAF664101000000971CDD40F6FF0F4101000000D6FF1F40F6FF0F41
              0200000009E11340F6FF0F41020000004FCC0840B0490E4102000000BF600340
              DE930B41020000000CEAFB3F0BDE0841020000000B41FE3FBE9F054102000000
              3C66064033330341010000007099014180D64C3E02000000F4CF03410C01803C
              0200000074C10741EF264EBD0200000085250B413C4A253D0300000085250B41
              3C4A253D00000000D6FF5F400000004101000000ACFFEF400000004102000000
              BCB3F4400000004102000000C32AF940D9080141020000000135FC4037D40241
              020000003E3FFF408A9F044102000000F1460041DAFE064102000000F7C7FF40
              A6500941010000007D91EA401FF448410100000097FF37410000E04001000000
              ACFFEF400000E04002000000B24BEB400000E04002000000AAD4E6404EEEDD40
              020000006DCAE3409357DA40020000002FC0E040ECC0D640020000008B71DF40
              4B02D240020000007637E040B35ECD4001000000F06DF540D72F1C4001000000
              D6FF5F400000004103000000D6FF5F4000000041}
            Fill.Color = xFFECECF1
            Locked = True
            Margins.Top = 2.000000000000000000
            Margins.Bottom = 4.000000000000000000
            Position.Y = 2.000000000000000000
            Size.Width = 208.000000000000000000
            Size.Height = 24.000000000000000000
            Size.PlatformDefault = False
            Stroke.Kind = None
            WrapMode = Fit
          end
          object Label5: TLabel
            Tag = 1
            Align = Top
            StyledSettings = [Family, Style]
            Margins.Left = 7.000000000000000000
            Margins.Top = 7.000000000000000000
            Margins.Right = 7.000000000000000000
            Margins.Bottom = 7.000000000000000000
            Position.X = 7.000000000000000000
            Position.Y = 68.000000000000000000
            Size.Width = 194.000000000000000000
            Size.Height = 65.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_welcome'
            TextSettings.Font.Size = 14.000000000000000000
            TextSettings.FontColor = xFFECECF1
            TextSettings.HorzAlign = Center
            Text = 'Remembers what user said earlier in the conversation'
            TabOrder = 3
          end
          object Label6: TLabel
            Tag = 1
            Align = Top
            StyledSettings = [Family, Style]
            Margins.Left = 7.000000000000000000
            Margins.Top = 7.000000000000000000
            Margins.Right = 7.000000000000000000
            Margins.Bottom = 7.000000000000000000
            Position.X = 7.000000000000000000
            Position.Y = 147.000000000000000000
            Size.Width = 194.000000000000000000
            Size.Height = 66.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_welcome'
            TextSettings.Font.Size = 14.000000000000000000
            TextSettings.FontColor = xFFECECF1
            TextSettings.HorzAlign = Center
            Text = 'Allows user to provide follow-up corrections'
            TabOrder = 1
          end
          object Label9: TLabel
            Tag = 1
            Align = Top
            StyledSettings = [Family, Style]
            Margins.Left = 7.000000000000000000
            Margins.Top = 7.000000000000000000
            Margins.Right = 7.000000000000000000
            Margins.Bottom = 7.000000000000000000
            Position.X = 7.000000000000000000
            Position.Y = 227.000000000000000000
            Size.Width = 194.000000000000000000
            Size.Height = 64.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_welcome'
            TextSettings.Font.Size = 14.000000000000000000
            TextSettings.FontColor = xFFECECF1
            TextSettings.HorzAlign = Center
            Text = 'Trained to decline inappropriate requests'
            TabOrder = 0
          end
          object Layout6: TLayout
            Align = Top
            Locked = True
            Position.Y = 30.000000000000000000
            Size.Width = 208.000000000000000000
            Size.Height = 31.000000000000000000
            Size.PlatformDefault = False
            TabOrder = 2
            object Label1: TLabel
              Align = Center
              AutoSize = True
              StyledSettings = [Family, Style]
              Locked = True
              Size.Width = 92.000000000000000000
              Size.Height = 24.000000000000000000
              Size.PlatformDefault = False
              TextSettings.Font.Size = 18.000000000000000000
              TextSettings.FontColor = xFFECECF1
              TextSettings.HorzAlign = Center
              TextSettings.WordWrap = False
              Text = 'Capabilities'
              TabOrder = 3
              object PathCapCompact: TPath
                Align = Left
                Data.Path = {
                  340000000000000085250B413C4A253D0200000096890E41D32E063E02000000
                  2E7F1041B0AFB53E02000000F1E30F415A0D153F010000006B7101411500C040
                  0100000097FF47411500C040020000005F074B411500C04002000000CDCC4D41
                  A06CC34002000000BB274F4145D8C8400200000041825041E943CE4002000000
                  B537504183C0D44002000000FE654E419A99D940010000008ECCDC40CDCC6C41
                  02000000855FD8401AC06F4102000000857CD04007CE70410200000063B4C940
                  865A6F410200000042ECC2406DE76D41020000001101BF4054526A4102000000
                  8B37C0404FAF664101000000971CDD40F6FF0F4101000000D6FF1F40F6FF0F41
                  0200000009E11340F6FF0F41020000004FCC0840B0490E4102000000BF600340
                  DE930B41020000000CEAFB3F0BDE0841020000000B41FE3FBE9F054102000000
                  3C66064033330341010000007099014180D64C3E02000000F4CF03410C01803C
                  0200000074C10741EF264EBD0200000085250B413C4A253D0300000085250B41
                  3C4A253D00000000D6FF5F400000004101000000ACFFEF400000004102000000
                  BCB3F4400000004102000000C32AF940D9080141020000000135FC4037D40241
                  020000003E3FFF408A9F044102000000F1460041DAFE064102000000F7C7FF40
                  A6500941010000007D91EA401FF448410100000097FF37410000E04001000000
                  ACFFEF400000E04002000000B24BEB400000E04002000000AAD4E6404EEEDD40
                  020000006DCAE3409357DA40020000002FC0E040ECC0D640020000008B71DF40
                  4B02D240020000007637E040B35ECD4001000000F06DF540D72F1C4001000000
                  D6FF5F400000004103000000D6FF5F4000000041}
                Fill.Color = xFFECECF1
                Locked = True
                Margins.Left = -35.000000000000000000
                Position.X = -35.000000000000000000
                Size.Width = 24.000000000000000000
                Size.Height = 24.000000000000000000
                Size.PlatformDefault = False
                Stroke.Kind = None
                WrapMode = Fit
              end
            end
          end
        end
        object LayoutLimitationsTitle: TLayout
          Align = Client
          Locked = True
          Size.Width = 208.000000000000000000
          Size.Height = 319.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 0
          object PathLimFull: TPath
            Align = MostTop
            Data.Path = {
              4E00000000000000000080410000D04102000000AF536E410000D04102000000
              0000604129D6C84102000000000060410000C0410200000000006041D729B741
              02000000AF536E410000B04102000000000080410000B0410200000028D68841
              0000B0410200000000009041D729B74102000000000090410000C04102000000
              0000904129D6C8410200000029D688410000D04102000000000080410000D041
              03000000000080410000D04100000000000080410000C0410300000000008041
              0000C04100000000000080410000A04102000000D72977410000A04102000000
              00007041146B9C41020000000000704100009841010000000000704100003041
              0200000000007041D729274102000000D8297741000020410200000000008041
              0000204102000000146B8441000020410200000000008841D729274102000000
              00008841000030410100000000008841000098410200000000008841146B9C41
              02000000146B84410000A04102000000000080410000A0410300000000008041
              0000A04100000000713DDE410000F041010000003D0A87400000F04102000000
              0D4D45400110F0410200000054C20140FC46EB41020000009E99B93FA570E341
              0200000060485F3F54C7DB41020000005C6D593FA13BD241020000008AEBB13F
              6766CA410100000052B8524148E16A4002000000527A6041A4D9064002000000
              3DE77F4148BEC43F0200000093748C41256719400200000035BF9041724A2C40
              020000006D479441348C484002000000D7A3964148E16A400100000048E1F441
              6666CA41020000009734F941A03BD24102000000BF05F94153C7DB4102000000
              6866F441A470E34102000000B7C7EF41FC46EB41020000005F56E7410210F041
              02000000703DDE410000F04103000000713DDE410000F0410000000000008041
              00008040020000000DD87841545F7F4002000000EB367241287E874002000000
              48E16E41F7289440010000009A9949400000D241020000005AC93B4035DAD441
              020000005AC93B40796DD841020000009A994940AE47DB4102000000D2ED5640
              C222DE410200000038286F402FECDF4102000000CECC84400000E04101000000
              713DDE410000E041020000009E8BE1412FECDF4102000000EB92E441C222DE41
              02000000713DE641AE47DB410200000079F7E741796DD8410200000079F7E741
              35DAD44102000000703DE6410000D241010000005C8F8841F628944002000000
              8AE48641287E874002000000F9938341545F7F40020000000000804100008040
              030000000000804100008040}
            Fill.Color = xFFECECF1
            Locked = True
            Margins.Top = 2.000000000000000000
            Margins.Bottom = 4.000000000000000000
            Position.Y = 2.000000000000000000
            Size.Width = 208.000000000000000000
            Size.Height = 24.000000000000000000
            Size.PlatformDefault = False
            Stroke.Kind = None
            WrapMode = Fit
          end
          object Label8: TLabel
            Tag = 1
            Align = Top
            StyledSettings = [Family, Style]
            Margins.Left = 7.000000000000000000
            Margins.Top = 7.000000000000000000
            Margins.Right = 7.000000000000000000
            Margins.Bottom = 7.000000000000000000
            Position.X = 7.000000000000000000
            Position.Y = 68.000000000000000000
            Size.Width = 194.000000000000000000
            Size.Height = 65.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_welcome'
            TextSettings.Font.Size = 14.000000000000000000
            TextSettings.FontColor = xFFECECF1
            TextSettings.HorzAlign = Center
            Text = 'May occasionally generate incorrect information'
            TabOrder = 3
          end
          object Label7: TLabel
            Tag = 1
            Align = Top
            StyledSettings = [Family, Style]
            Margins.Left = 7.000000000000000000
            Margins.Top = 7.000000000000000000
            Margins.Right = 7.000000000000000000
            Margins.Bottom = 7.000000000000000000
            Position.X = 7.000000000000000000
            Position.Y = 147.000000000000000000
            Size.Width = 194.000000000000000000
            Size.Height = 65.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_welcome'
            TextSettings.Font.Size = 14.000000000000000000
            TextSettings.FontColor = xFFECECF1
            TextSettings.HorzAlign = Center
            Text = 'May occasionally produce harmful instructions or biased content'
            TabOrder = 1
          end
          object Label10: TLabel
            Tag = 1
            Align = Top
            StyledSettings = [Family, Style]
            Margins.Left = 7.000000000000000000
            Margins.Top = 7.000000000000000000
            Margins.Right = 7.000000000000000000
            Margins.Bottom = 7.000000000000000000
            Position.X = 7.000000000000000000
            Position.Y = 226.000000000000000000
            Size.Width = 194.000000000000000000
            Size.Height = 65.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_welcome'
            TextSettings.Font.Size = 14.000000000000000000
            TextSettings.FontColor = xFFECECF1
            TextSettings.HorzAlign = Center
            Text = 'Limited knowledge of world and events after 2021'
            TabOrder = 0
          end
          object Layout7: TLayout
            Align = Top
            Locked = True
            Position.Y = 30.000000000000000000
            Size.Width = 208.000000000000000000
            Size.Height = 31.000000000000000000
            Size.PlatformDefault = False
            TabOrder = 2
            object Label11: TLabel
              Align = Center
              AutoSize = True
              StyledSettings = [Family, Style]
              Locked = True
              Size.Width = 87.000000000000000000
              Size.Height = 24.000000000000000000
              Size.PlatformDefault = False
              TextSettings.Font.Size = 18.000000000000000000
              TextSettings.FontColor = xFFECECF1
              TextSettings.HorzAlign = Center
              TextSettings.WordWrap = False
              Text = 'Limitations'
              TabOrder = 3
              object PathLimCompact: TPath
                Align = Left
                Data.Path = {
                  4E00000000000000000080410000D04102000000AF536E410000D04102000000
                  0000604129D6C84102000000000060410000C0410200000000006041D729B741
                  02000000AF536E410000B04102000000000080410000B0410200000028D68841
                  0000B0410200000000009041D729B74102000000000090410000C04102000000
                  0000904129D6C8410200000029D688410000D04102000000000080410000D041
                  03000000000080410000D04100000000000080410000C0410300000000008041
                  0000C04100000000000080410000A04102000000D72977410000A04102000000
                  00007041146B9C41020000000000704100009841010000000000704100003041
                  0200000000007041D729274102000000D8297741000020410200000000008041
                  0000204102000000146B8441000020410200000000008841D729274102000000
                  00008841000030410100000000008841000098410200000000008841146B9C41
                  02000000146B84410000A04102000000000080410000A0410300000000008041
                  0000A04100000000713DDE410000F041010000003D0A87400000F04102000000
                  0D4D45400110F0410200000054C20140FC46EB41020000009E99B93FA570E341
                  0200000060485F3F54C7DB41020000005C6D593FA13BD241020000008AEBB13F
                  6766CA410100000052B8524148E16A4002000000527A6041A4D9064002000000
                  3DE77F4148BEC43F0200000093748C41256719400200000035BF9041724A2C40
                  020000006D479441348C484002000000D7A3964148E16A400100000048E1F441
                  6666CA41020000009734F941A03BD24102000000BF05F94153C7DB4102000000
                  6866F441A470E34102000000B7C7EF41FC46EB41020000005F56E7410210F041
                  02000000703DDE410000F04103000000713DDE410000F0410000000000008041
                  00008040020000000DD87841545F7F4002000000EB367241287E874002000000
                  48E16E41F7289440010000009A9949400000D241020000005AC93B4035DAD441
                  020000005AC93B40796DD841020000009A994940AE47DB4102000000D2ED5640
                  C222DE410200000038286F402FECDF4102000000CECC84400000E04101000000
                  713DDE410000E041020000009E8BE1412FECDF4102000000EB92E441C222DE41
                  02000000713DE641AE47DB410200000079F7E741796DD8410200000079F7E741
                  35DAD44102000000703DE6410000D241010000005C8F8841F628944002000000
                  8AE48641287E874002000000F9938341545F7F40020000000000804100008040
                  030000000000804100008040}
                Fill.Color = xFFECECF1
                Locked = True
                Margins.Left = -35.000000000000000000
                Position.X = -35.000000000000000000
                Size.Width = 24.000000000000000000
                Size.Height = 24.000000000000000000
                Size.PlatformDefault = False
                Stroke.Kind = None
                WrapMode = Fit
              end
            end
          end
        end
      end
    end
  end
  object LayoutSend: TLayout
    Align = MostBottom
    Padding.Top = 10.000000000000000000
    Padding.Bottom = 40.000000000000000000
    Margins.Right = 11.000000000000000000
    Position.Y = 686.000000000000000000
    Size.Width = 995.000000000000000000
    Size.Height = 100.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 1
    OnResize = LayoutSendResize
    OnResized = LayoutSendResize
    object LineBorder: TLine
      Align = Contents
      Locked = True
      HitTest = False
      LineType = Top
      Size.Width = 995.000000000000000000
      Size.Height = 100.000000000000000000
      Size.PlatformDefault = False
      Stroke.Color = x33FFFFFF
    end
    object RectangleSendBG: TRectangle
      Align = Contents
      Fill.Kind = Gradient
      Fill.Gradient.Points = <
        item
          Color = xFF343541
          Offset = 0.217391297221183800
        end
        item
          Color = x00353740
          Offset = 1.000000000000000000
        end>
      Fill.Gradient.StartPosition.X = 0.500000000000000000
      Fill.Gradient.StartPosition.Y = 1.000000000000000000
      Fill.Gradient.StopPosition.X = 0.499999970197677600
      Fill.Gradient.StopPosition.Y = 0.000000000000000000
      Locked = True
      HitTest = False
      Size.Width = 995.000000000000000000
      Size.Height = 100.000000000000000000
      Size.PlatformDefault = False
      Stroke.Kind = None
      object Label12: TLabel
        Align = Bottom
        AutoSize = True
        StyledSettings = [Style]
        Opacity = 0.699999988079071000
        Margins.Bottom = 4.000000000000000000
        Position.Y = 82.000000000000000000
        Size.Width = 995.000000000000000000
        Size.Height = 14.000000000000000000
        Size.PlatformDefault = False
        TextSettings.Font.Family = 'Roboto'
        TextSettings.Font.Size = 11.000000000000000000
        TextSettings.FontColor = xAFFFFFFF
        TextSettings.HorzAlign = Center
        TextSettings.WordWrap = False
        TextSettings.Trimming = None
        Text = 'by HemulGM'
        TabOrder = 0
      end
    end
    object LayoutQuery: TLayout
      Align = HorzCenter
      Locked = True
      HitTest = True
      Padding.Top = 12.000000000000000000
      Padding.Right = 16.000000000000000000
      Padding.Bottom = 12.000000000000000000
      Position.X = 113.000000000000000000
      Position.Y = 10.000000000000000000
      Size.Width = 768.000000000000000000
      Size.Height = 50.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 1
      object RectangleMemoBG: TRectangle
        Align = Contents
        Fill.Color = xFF40414F
        Locked = True
        HitTest = False
        Margins.Left = 15.000000000000000000
        Size.Width = 753.000000000000000000
        Size.Height = 50.000000000000000000
        Size.PlatformDefault = False
        Stroke.Color = x3C000000
        XRadius = 6.000000000000000000
        YRadius = 6.000000000000000000
      end
      object MemoQuery: TMemo
        Touch.InteractiveGestures = [Pan, LongTap, DoubleTap]
        DataDetectorTypes = []
        StyledSettings = [Style]
        TextSettings.Font.Size = 16.000000000000000000
        TextSettings.FontColor = claWhite
        TextSettings.WordWrap = True
        OnChange = MemoQueryChange
        OnChangeTracking = MemoQueryChange
        Align = Top
        Margins.Top = 2.000000000000000000
        Position.X = 26.000000000000000000
        Position.Y = 14.000000000000000000
        Size.Width = 618.000000000000000000
        Size.Height = 26.000000000000000000
        Size.PlatformDefault = False
        StyleLookup = 'memostyle_clear'
        TabOrder = 0
        OnEnter = MemoQueryEnter
        OnKeyUp = MemoQueryKeyUp
        OnKeyDown = MemoQueryKeyDown
        OnViewportPositionChange = MemoQueryViewportPositionChange
        Viewport.Width = 608.000000000000000000
        Viewport.Height = 26.000000000000000000
        object LabelSendTip: TLabel
          Align = Contents
          StyledSettings = [Family, Style]
          Opacity = 0.800000011920929000
          Margins.Right = -200.000000000000000000
          Size.Width = 201.000000000000000000
          Size.Height = 21.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Size = 16.000000000000000000
          TextSettings.FontColor = xFFACACBE
          TextSettings.WordWrap = False
          TextSettings.Trimming = None
          Text = 'Send a message.'
          TabOrder = 0
        end
      end
      object LayoutSendControls: TLayout
        Align = MostRight
        Margins.Left = 4.000000000000000000
        Position.X = 648.000000000000000000
        Position.Y = 12.000000000000000000
        Size.Width = 104.000000000000000000
        Size.Height = 26.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 1
        object LayoutSendCommons: TLayout
          Align = Bottom
          Size.Width = 104.000000000000000000
          Size.Height = 26.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 2
          object ButtonAudio: TButton
            Align = Right
            CanFocus = False
            Hint = 
              'Submit an audio recording for recognition. Will be taken into ac' +
              'count in the context of communication with GPT (Whisper)'
            Position.X = 26.000000000000000000
            Size.Width = 26.000000000000000000
            Size.Height = 26.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_clearmini'
            TabOrder = 3
            ParentShowHint = False
            ShowHint = True
            OnClick = ButtonAudioClick
            object Path8: TPath
              Align = Center
              Data.Path = {
                19000000000000000000A0400000A84101000000000040400000A84101000000
                0000404000003041010000000000A04000003041030000000000A0400000A841
                00000000000030410000E04001000000000010410000E0400100000000001041
                0000C84101000000000030410000C84103000000000030410000E04000000000
                000088410000004001000000000070410000004001000000000070410000F041
                01000000000088410000F041030000000000884100000040000000000000B841
                00003041010000000000A84100003041010000000000A8410000A84101000000
                0000B8410000A841030000000000B84100003041000000000000E8410000E040
                010000000000D8410000E040010000000000D8410000C841010000000000E841
                0000C841030000000000E8410000E040}
              Fill.Color = xFFACACBE
              Locked = True
              HitTest = False
              Size.Width = 14.000000000000000000
              Size.Height = 14.000000000000000000
              Size.PlatformDefault = False
              Stroke.Kind = None
              WrapMode = Fit
            end
          end
          object ButtonSend: TButton
            Align = Right
            CanFocus = False
            Hint = 'Send prompt'
            Position.X = 78.000000000000000000
            Size.Width = 26.000000000000000000
            Size.Height = 26.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_clearmini'
            TabOrder = 5
            Text = 'ButtonSend'
            OnClick = ButtonSendClick
            object PathSend: TPath
              Align = Center
              Data.Path = {
                2700000000000000D34D2E415A642340020000003A582A41DFCA034002000000
                16BB20419307EE3F02000000B8D418412EDA064002000000CDBE1541CA090D40
                02000000143E1341AC0C1740020000002DB211415964234001000000B4C80640
                8B6C84410200000068EFED3F116088410200000059C503405D2E8D4102000000
                876123407D288F4102000000BBB43140DA0D904102000000B3324240FC3E9041
                02000000989951402DB28F41010000006666044195438441020000000F450B41
                124883410200000004011041002480410200000000001041D122794101000000
                00001041000030410200000000001041D729274102000000D829174100002041
                0200000000002041000020410200000028D62841000020410200000000003041
                D72927410200000000003041000030410100000000003041D122794102000000
                1CFF2F4124248041020000002CBB34412C48834102000000DF993B41A0438441
                01000000F0CC85412BB08F4102000000500C8A4189E7904102000000397A8E41
                75728E410200000097B18F4114338A4102000000A23E90418646884102000000
                EE0D9041FE3686410200000019298F41966C84410100000032522E41B0642340
                03000000D34D2E415A64234003000000D34D2E415A642340}
              Fill.Color = xFFACACBE
              Locked = True
              HitTest = False
              Margins.Left = 2.000000000000000000
              RotationAngle = 90.000000000000000000
              Size.Width = 12.800000190734860000
              Size.Height = 12.800000190734860000
              Size.PlatformDefault = False
              Stroke.Kind = None
              Visible = False
              WrapMode = Fit
            end
            object PathAudio: TPath
              Align = Center
              Data.Path = {
                4F0000000000000000004041000080410200000039B41C410000804102000000
                00000041AE47634102000000000000410000404101000000000000410000C040
                020000000000004148E172400200000039B41C41000000400200000000004041
                0000004002000000C74B634100000040020000000000804148E1724002000000
                000080410000C0400100000000008041000040410200000000008041AE476341
                02000000C74B6341000080410200000000004041000080410300000000004041
                00008041000000000000404100008040020000001D5A2E410000804002000000
                0000204108AC9C4002000000000020410000C040010000000000204100004041
                0200000000002041FCA95141020000001D5A2E41000060410200000000004041
                0000604102000000E3A55141000060410200000000006041FCA9514102000000
                000060410000404101000000000060410000C040020000000000604108AC9C40
                02000000E3A55141000080400200000000004041000080400300000000004041
                0000804000000000000098410000404101000000000098410000204102000000
                00009841EA261741020000008B6C944100001041020000000000904100001041
                0200000075938B41000010410200000000008841E92617410200000000008841
                000020410100000000008841000040410200000000008841AC1C6C4102000000
                AC1C6C41000088410200000000004041000088410200000054E3134100008841
                020000000000E040AC1C6C41020000000000E04000004041010000000000E040
                00002041020000000000E040EA261741020000002DB2D1400000104102000000
                0000C0400000104102000000D34DAE4000001041020000000000A040E9261741
                020000000000A04000002041010000000000A04000004041020000000000A040
                EC51784102000000B29DF340BC7493410200000000003041295C974101000000
                000030410000A04101000000000000410000A04102000000D34DEE400000A041
                020000000000E0407593A341020000000000E0400000A841020000000000E040
                8B6CAC4102000000D34DEE400000B04102000000000000410000B04101000000
                000080410000B041020000008B6C84410000B04102000000000088418B6CAC41
                02000000000088410000A84102000000000088417593A341020000008B6C8441
                0000A04102000000000080410000A04101000000000050410000A04101000000
                00005041295C97410200000093188341BC7493410200000000009841EC517841
                020000000000984100004041030000000000984100004041}
              Fill.Color = xFFACACBE
              Locked = True
              HitTest = False
              Margins.Left = 2.000000000000000000
              Size.Width = 15.000000000000000000
              Size.Height = 15.000000000000000000
              Size.PlatformDefault = False
              Stroke.Kind = None
              WrapMode = Fit
            end
            object PathStopRecord: TPath
              Align = Center
              Data.Path = {
                1200000000000000000080410000C04001000000000000410000C04002000000
                CDCCDC400000C040020000000000C040CDCCDC40020000000000C04000000041
                010000000000C04000008041020000000000C040CDCC884102000000CDCCDC40
                0000904102000000000000410000904101000000000080410000904102000000
                CDCC8841000090410200000000009041CDCC8841020000000000904100008041
                0100000000009041000000410200000000009041CDCCDC4002000000CDCC8841
                0000C04002000000000080410000C04003000000000080410000C040}
              Fill.Color = xFFACACBE
              Locked = True
              HitTest = False
              Margins.Left = 2.000000000000000000
              RotationAngle = 90.000000000000000000
              Size.Width = 13.000000000000000000
              Size.Height = 13.000000000000000000
              Size.PlatformDefault = False
              Stroke.Kind = None
              WrapMode = Fit
            end
          end
          object ButtonImage: TButton
            Align = Right
            CanFocus = False
            Hint = 'Image generation mode on demand (DALL-E)'
            Position.X = 52.000000000000000000
            Size.Width = 26.000000000000000000
            Size.Height = 26.000000000000000000
            Size.PlatformDefault = False
            StyleLookup = 'buttonstyle_clearmini'
            TabOrder = 4
            Text = 'ButtonSend'
            OnClick = ButtonImageClick
            object RectangleImageMode: TRectangle
              Align = Client
              Fill.Kind = None
              Locked = True
              HitTest = False
              Size.Width = 26.000000000000000000
              Size.Height = 26.000000000000000000
              Size.PlatformDefault = False
              Stroke.Color = xFFACACBE
              Stroke.Thickness = 2.000000000000000000
              XRadius = 4.000000000000000000
              YRadius = 4.000000000000000000
              ParentShowHint = False
              ShowHint = True
            end
            object PathImage: TPath
              Align = Center
              Data.Path = {
                44000000000000000000B84300006043020000000040C5430000604302000000
                0000D04300804A43020000000000D04300003043020000000000D04300801543
                020000000040C54300000043020000000000B843000000430200000000C0AA43
                00000043020000000000A04300801543020000000000A0430000304302000000
                0000A04300804A430200000000C0AA4300006043020000000000B84300006043
                030000000000B84300006043000000000000E243000080420100000000007042
                00008042020000009A9931420000804202000000000000426666994202000000
                000000429A99B84201000000000000429AD9D143020000000000004267A6D943
                020000009A9931420000E04302000000000070420000E043010000000000E243
                0000E04302000000CDCCE9430000E043020000000000F04366A6D94302000000
                0000F0439AD9D143010000000000F0439A99B842020000000000F04366669942
                02000000CDCCE94300008042020000000000E24300008042030000000000E243
                00008042000000003373AE439AD982430200000033F3AC439A19814302000000
                66A6AA4301807F4302000000CD0CA84301807F43020000000080A54301807F43
                0200000033B3A34334F380430200000067A6A1439A99824301000000CD4C9843
                00808A43020000009A59964366E68B4302000000CDCC94439AD98C4302000000
                CD8C92439AD98C4302000000676690439AD98C430200000033738E43CD0C8C43
                02000000CD0C8D43CDCC8A4302000000CD8C8C439A598A430200000067A68B43
                008089430200000067E68A4300C088430100000000006043CD4C574302000000
                00005C4333B352430200000000005643CDCC4F4302000000CD4C4F43CDCC4F43
                020000009A994843CDCC4F4302000000676642439A1953430200000000803E43
                9A99574301000000000080429A19B84301000000000080426666D74202000000
                00008242CCCCC942020000009A998C420000C0420200000033339A420000C042
                010000006766D9430000C042020000009AD9DC430000C0420200000067A6DF43
                3333CA42020000009AD9DF430000D842010000000000E0433333B84301000000
                3373AE439AD98243030000003373AE439AD98243}
              Fill.Color = xFFDDDDE4
              Locked = True
              HitTest = False
              Margins.Left = 2.000000000000000000
              Size.Width = 12.800000190734860000
              Size.Height = 12.800000190734860000
              Size.PlatformDefault = False
              Stroke.Kind = None
              WrapMode = Fit
            end
          end
          object LabelTyping: TLabel
            Align = MostLeft
            StyledSettings = [Style]
            Margins.Left = 4.000000000000000000
            Position.X = 4.000000000000000000
            Size.Width = 20.000000000000000000
            Size.Height = 26.000000000000000000
            Size.PlatformDefault = False
            TextSettings.Font.Size = 20.000000000000000000
            TextSettings.FontColor = xFFACACBE
            TextSettings.HorzAlign = Center
            TextSettings.WordWrap = False
            TextSettings.Trimming = None
            Text = '...'
            TabOrder = 2
          end
        end
      end
      object LayoutChatSettings: TLayout
        Align = MostLeft
        Locked = True
        Margins.Left = -15.000000000000000000
        Margins.Right = 15.000000000000000000
        Position.X = -15.000000000000000000
        Position.Y = 12.000000000000000000
        Size.Width = 26.000000000000000000
        Size.Height = 26.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 2
        object ButtonSettings: TButton
          Align = Bottom
          CanFocus = False
          Hint = 'Current chat settings'
          Size.Width = 26.000000000000000000
          Size.Height = 26.000000000000000000
          Size.PlatformDefault = False
          StyleLookup = 'buttonstyle_clearmini'
          TabOrder = 0
          Text = 'ButtonTranslate'
          OnClick = ButtonSettingsClick
          object Path9: TPath
            Align = Center
            Data.Path = {
              FF0000000000000098CCA24152C40E41010000009EDE9F41D8810B4102000000
              4B6A9F413F000B4102000000F2309F413EBF0A4102000000A1F89E41DD7B0A41
              0200000052C99C41CCDD07410200000013F29A411040044102000000029A9941
              EDD8FF40020000006677994105FAFE4002000000D65699414D10FE4002000000
              121499415B42FC400200000083D19841E674FA4002000000B8AF98411A8BF940
              0200000097909841ADA3F84002000000295C97411AA3EF40020000003FB59641
              D49AE5400200000036AB9641D864DB400200000030AA96410B5EDA4002000000
              65AA96419851D94002000000A5AC9641B83BD7400100000064BB9641FD9FC940
              02000000BDD2964117D9B340020000009EDE964114EDA84002000000A01A9641
              B41F9F4002000000C06C9541BE6A964002000000BA499441D4658E4002000000
              05C592418D97874002000000B90D914164CC7F400200000077AD8E415FD27440
              02000000EEEB89418AE55E4001000000A1F885414FAF4C4002000000933A8141
              35D2364002000000AEB67D41ACE22B400200000043AD78416BB7274002000000
              EF3874413507244002000000BE9F6F41F432244002000000832F6B415A2F2840
              02000000A52C664125AF2C4002000000567D614196E73740020000005C205841
              5C554E40010000006F125841696F4E40010000004469524187FE5B4002000000
              4D84514164235E400200000062105141F4375F4002000000499D504161376040
              020000005F294C414F1E6A400200000027314741F6976F400200000065194241
              683F704002000000539641414850704002000000621041414850704002000000
              530540414850704002000000E7FB3E4148507040020000003B703E4148507040
              0200000029ED3D41683F704002000000F2D238414E976F4002000000DCD73341
              F4156A40020000004E622F41B32460400200000035EF2E4120245F4002000000
              567D2E41450D5E4002000000F6972D41C9E55B400100000060E5274161374E40
              02000000AF771E41369337400200000014BF1941C93C2C400200000054B51441
              6BB72740020000004F4010416BB72340020000004FA30B41139B234002000000
              A42A07416957274002000000261E0241478F2B4002000000A1BEFA409F933640
              0200000037C3E740249C4C400100000097ADE7404FAF4C4001000000AE12D840
              A3CC5E400100000071E6D740B4025F4002000000DB16C54099D8744002000000
              3FA9BB4043CA7F4002000000BADAB440758E87400200000068D0AE40EE5A8E40
              02000000984CAA40A75C964002000000C898A740B70B9F4002000000C68AA440
              72DCA8400200000078B4A44085CEB34002000000AE12A540B8AFC94001000000
              404DA5408846D740020000001956A5404755D940020000008065A540185BDA40
              02000000A661A540355EDB4002000000D23AA5408599E540020000006896A240
              09A7EF40020000006EC09D40B4ABF840020000000B469D400490F94002000000
              27C29C405474FA4002000000B2BA9B40603CFC400200000014B39A40D504FE40
              020000005D339A40C0E7FE4002000000B9AA994009C4FF40020000007C449440
              793B04410200000055DE8C40A9DE07410200000016138440D47D0A4102000000
              6E3483403AC00A4102000000BA49824015000B41020000009A7C8040D67F0B41
              0100000067D569408DB40E410200000047554340090A14410200000072163040
              5FB516410200000077152240CD811A4102000000D9B1154016DE1D4102000000
              04560C4051DA214102000000959F0640F9312641020000006F2A0040371A2B41
              02000000BF2B0040D49A30410200000078450040A69B3B4101000000475A0040
              6B9A444102000000AC73004066884F410200000092960040C5FE544102000000
              7C0F07406ADE5941020000005CC90C40492E5E4102000000A9131640DD246241
              020000006B652240B37B6541020000003F5230405B4269410200000018604340
              79E96B410200000057956940C139714101000000314280407F6A744102000000
              D23582405AF57441020000003C318340C13975410200000029228440AA827541
              02000000EDD88C40FF21784102000000403094408FC27B4102000000B18A9940
              DB0A804102000000B81E9A40A846804102000000DAAC9A40B684804102000000
              1DC99B400601814102000000C6E19C407F7B81410200000061719D40BBB88141
              0200000038F39D402BF6814102000000BEA4A240E62E8441020000000F28A540
              E9A6864102000000E353A540FC29894102000000A358A540696F894102000000
              A054A540A8B58941020000000A4BA540F8428A4101000000AE12A54088858D41
              02000000D0B3A440AA02934102000000728AA440F2C19541020000000A9DA740
              E937984102000000F354AA402C659A4102000000F8DFAE4066669C4102000000
              BBF2B440021A9E410200000014D0BB405906A041020000006154C5406065A141
              02000000AF5AD8400523A441010000002827E8407969A64102000000C91FFB40
              4625A941020000009F4D0241AA82AA4102000000CB5607413108AB4102000000
              53CB0B41287EAB4102000000ED641041A779AB41020000005CD5144110FAAA41
              02000000C9D91941E269AA41020000003B8D1E41A301A9410200000041F12741
              C431A641010000006B9A2D410080A44102000000CC7F2E41303BA44102000000
              1FF42E41C818A44102000000CF662F41D5F8A34102000000BADA334102BCA241
              02000000B7D13841E10BA2410200000079E93D41FDF6A141020000008B6C3E41
              F1F4A141020000007CF23E41F1F4A141020000008BFD3F41F1F4A14102000000
              6C094141F1F4A14102000000F38E4141F1F4A141020000006F124241FDF6A141
              02000000A52C4741150CA24102000000D42B4C41D3BCA2410200000062A15041
              E1FAA34102000000BC055141F016A441020000007F6A51413F35A44102000000
              091B52414B6AA44101000000F31F5841BB38A64102000000B98D6141500DA941
              02000000FE436641FD76AA4102000000D34D6B41C807AB41020000008FC26F41
              C887AB4102000000AA607441E78CAB41020000007FD978418115AB4102000000
              60E57D418A8EAA41020000005B538141432DA941020000009D1186418B6CA641
              010000005F078A412720A4410200000002BC8E41F764A14102000000F6179141
              5906A04102000000C7CB9241DA1B9E4102000000704E9441DC689C4102000000
              D26F9541A7689A4102000000AC1C9641D33C984102000000D3DE964136CD9541
              0200000026D396411E16934102000000CDBB9641F9B18D4101000000A5AC9641
              E02D8A410200000065AA964130AA89410200000030AA9641A768894102000000
              36AB9641F027894102000000D7B49641FC98864102000000235B97414D158441
              02000000979098412CD48141020000004FAF9841099B8141020000007DD09841
              7C6181410200000006129941D2EF804102000000F8539941F47D804102000000
              2B76994105458041020000005F989941ED0D804102000000DEF19A4127C27B41
              02000000C7CB9C414F1E784102000000C5FE9E41FA7E754102000000A8359F41
              713D754102000000636E9F41C5FE744102000000D3DE9F414182744101000000
              B7E29F41917E74410100000011C7A241BA497141020000002497A74188F46B41
              020000003400AA4117486941020000004FC0AB41B37B654102000000CD4CAD41
              8A1F624102000000CF77AE4174245E4102000000B22EAF4136CD594102000000
              1CFCAF4157EC54410200000078FAAF41EB734F410200000066F7AF41DE934441
              01000000BCF4AF41F1633B410200000076F1AF418E75304102000000D2EFAF41
              97FF2A4102000000C520AF41F31F2641020000007969AE4114D0214102000000
              773EAD418AD91D410200000039B4AB4175821A410200000032F7A941DEBC1641
              020000007B94A7418C1514410200000048D0A241CEC70E410100000098CCA241
              52C40E410300000098CCA24152C40E41000000005A0100410000404102000000
              5A0100417958634102000000B7A81C4100008041020000003B01404100008041
              020000001D5A634100008041020000009D00804179586341020000009D008041
              00004041020000009D00804133A71C41020000001D5A6341ACFFFF4002000000
              3B014041ACFFFF4002000000B7A81C41ACFFFF40020000005A01004133A71C41
              020000005A01004100004041030000005A01004100004041}
            Fill.Color = xFFACACBE
            Locked = True
            HitTest = False
            Margins.Left = 2.000000000000000000
            Size.Width = 13.000000000000000000
            Size.Height = 13.000000000000000000
            Size.PlatformDefault = False
            Stroke.Kind = None
            WrapMode = Fit
          end
        end
      end
      object LayoutAudioRecording: TLayout
        Align = Contents
        Margins.Left = 26.000000000000000000
        Margins.Top = 12.000000000000000000
        Margins.Right = 16.000000000000000000
        Margins.Bottom = 12.000000000000000000
        Size.Width = 726.000000000000000000
        Size.Height = 26.000000000000000000
        Size.PlatformDefault = False
        Visible = False
        TabOrder = 3
        object AnimatedImageRecording: TSkAnimatedImage
          Align = Left
          Size.Width = 60.000000000000000000
          Size.Height = 26.000000000000000000
          Size.PlatformDefault = False
          Data = {
            7B2276223A22352E372E38222C226672223A32392E3937303030313232303730
            33312C226970223A302C226F70223A34312E303030303031363639393634322C
            2277223A3136302C2268223A36342C226E6D223A22436F6D702031222C226464
            64223A302C22617373657473223A5B5D2C226C6179657273223A5B7B22646464
            223A302C22696E64223A312C227479223A342C226E6D223A22524543204F7574
            6C696E6573222C227372223A312C226B73223A7B226F223A7B2261223A302C22
            6B223A3130302C226978223A31317D2C2272223A7B2261223A302C226B223A30
            2C226978223A31307D2C2270223A7B2261223A302C226B223A5B3130352E3538
            2C33322E3734362C305D2C226978223A322C226C223A327D2C2261223A7B2261
            223A302C226B223A5B2D31392E31372C2D362E332C305D2C226978223A312C22
            6C223A327D2C2273223A7B2261223A302C226B223A5B3235312C3235312C3130
            305D2C226978223A362C226C223A327D7D2C22616F223A302C22736861706573
            223A5B7B227479223A226772222C226974223A5B7B22696E64223A302C227479
            223A227368222C226978223A312C226B73223A7B2261223A302C226B223A7B22
            69223A5B5B302C305D2C5B302C305D2C5B302C305D2C5B302C305D2C5B2D302E
            3337382C302E3538335D2C5B302C302E3837335D2C5B302E38322C302E363734
            5D2C5B312E3531322C305D2C5B302C305D2C5B302C305D2C5B302C305D2C5B30
            2C305D2C5B302C305D5D2C226F223A5B5B302C305D2C5B302C305D2C5B302C30
            5D2C5B302E3736382C2D302E3334365D2C5B302E3337382C2D302E3538335D2C
            5B302C2D312E32335D2C5B2D302E38322C2D302E3637345D2C5B302C305D2C5B
            302C305D2C5B302C305D2C5B302C305D2C5B302C305D2C5B302C305D5D2C2276
            223A5B5B2D32362E30312C305D2C5B2D32332E31382C305D2C5B2D32332E3138
            2C2D302E3132335D2C5B2D32352E3934392C2D352E3335335D2C5B2D32342E32
            33312C2D362E3734365D2C5B2D32332E3636342C2D382E39335D2C5B2D32342E
            3839342C2D31312E3738365D2C5B2D32382E3339322C2D31322E3739375D2C5B
            2D33332E3134372C2D31322E3739375D2C5B2D33332E3134372C305D2C5B2D33
            302E35312C305D2C5B2D33302E35312C2D342E3638355D2C5B2D32382E34312C
            2D342E3638355D5D2C2263223A747275657D2C226978223A327D2C226E6D223A
            2252222C226D6E223A224144424520566563746F72205368617065202D204772
            6F7570222C226864223A66616C73657D2C7B22696E64223A312C227479223A22
            7368222C226978223A322C226B73223A7B2261223A302C226B223A7B2269223A
            5B5B302C305D2C5B302C305D2C5B2D302E3334332C2D302E3334365D2C5B302C
            2D302E3630335D2C5B302E3336332C2D302E3333375D2C5B302E3636322C305D
            2C5B302C305D5D2C226F223A5B5B302C305D2C5B302E3730392C305D2C5B302E
            3334332C302E3334365D2C5B302C302E3539325D2C5B2D302E3336332C302E33
            33375D2C5B302C305D2C5B302C305D5D2C2276223A5B5B2D33302E35312C2D31
            302E3636315D2C5B2D32382E3339322C2D31302E3636315D2C5B2D32362E3831
            352C2D31302E3134335D2C5B2D32362E332C2D382E3731395D2C5B2D32362E38
            34352C2D372E3332365D2C5B2D32382E3338332C2D362E38325D2C5B2D33302E
            35312C2D362E38325D5D2C2263223A747275657D2C226978223A327D2C226E6D
            223A2252222C226D6E223A224144424520566563746F72205368617065202D20
            47726F7570222C226864223A66616C73657D2C7B227479223A226D6D222C226D
            6D223A312C226E6D223A224D657267652050617468732031222C226D6E223A22
            4144424520566563746F722046696C746572202D204D65726765222C22686422
            3A66616C73657D2C7B227479223A22666C222C2263223A7B2261223A302C226B
            223A5B312C302E3239343131373634373035392C302E33363037383433313337
            32352C315D2C226978223A347D2C226F223A7B2261223A302C226B223A313030
            2C226978223A357D2C2272223A312C22626D223A302C226E6D223A2246696C6C
            2031222C226D6E223A224144424520566563746F722047726170686963202D20
            46696C6C222C226864223A66616C73657D2C7B227479223A227472222C227022
            3A7B2261223A302C226B223A5B302C305D2C226978223A327D2C2261223A7B22
            61223A302C226B223A5B302C305D2C226978223A317D2C2273223A7B2261223A
            302C226B223A5B3130302C3130305D2C226978223A337D2C2272223A7B226122
            3A302C226B223A302C226978223A367D2C226F223A7B2261223A302C226B223A
            3130302C226978223A377D2C22736B223A7B2261223A302C226B223A302C2269
            78223A347D2C227361223A7B2261223A302C226B223A302C226978223A357D2C
            226E6D223A225472616E73666F726D227D5D2C226E6D223A2252222C226E7022
            3A352C22636978223A322C22626D223A302C226978223A312C226D6E223A2241
            44424520566563746F722047726F7570222C226864223A66616C73657D2C7B22
            7479223A226772222C226974223A5B7B22696E64223A302C227479223A227368
            222C226978223A312C226B73223A7B2261223A302C226B223A7B2269223A5B5B
            302C305D2C5B302C305D2C5B302C305D2C5B302C305D2C5B302C305D2C5B302C
            305D2C5B302C305D2C5B302C305D2C5B302C305D2C5B302C305D2C5B302C305D
            2C5B302C305D5D2C226F223A5B5B302C305D2C5B302C305D2C5B302C305D2C5B
            302C305D2C5B302C305D2C5B302C305D2C5B302C305D2C5B302C305D2C5B302C
            305D2C5B302C305D2C5B302C305D2C5B302C305D5D2C2276223A5B5B2D31332E
            3531312C2D372E3631315D2C5B2D31382E3537332C2D372E3631315D2C5B2D31
            382E3537332C2D31302E3636315D2C5B2D31322E3634392C2D31302E3636315D
            2C5B2D31322E3634392C2D31322E3739375D2C5B2D32312E32312C2D31322E37
            39375D2C5B2D32312E32312C305D2C5B2D31322E3633322C305D2C5B2D31322E
            3633322C2D322E3131385D2C5B2D31382E3537332C2D322E3131385D2C5B2D31
            382E3537332C2D352E3534365D2C5B2D31332E3531312C2D352E3534365D5D2C
            2263223A747275657D2C226978223A327D2C226E6D223A2245222C226D6E223A
            224144424520566563746F72205368617065202D2047726F7570222C22686422
            3A66616C73657D2C7B227479223A22666C222C2263223A7B2261223A302C226B
            223A5B312C302E3239343131373634373035392C302E33363037383433313337
            32352C315D2C226978223A347D2C226F223A7B2261223A302C226B223A313030
            2C226978223A357D2C2272223A312C22626D223A302C226E6D223A2246696C6C
            2031222C226D6E223A224144424520566563746F722047726170686963202D20
            46696C6C222C226864223A66616C73657D2C7B227479223A227472222C227022
            3A7B2261223A302C226B223A5B302C305D2C226978223A327D2C2261223A7B22
            61223A302C226B223A5B302C305D2C226978223A317D2C2273223A7B2261223A
            302C226B223A5B3130302C3130305D2C226978223A337D2C2272223A7B226122
            3A302C226B223A302C226978223A367D2C226F223A7B2261223A302C226B223A
            3130302C226978223A377D2C22736B223A7B2261223A302C226B223A302C2269
            78223A347D2C227361223A7B2261223A302C226B223A302C226978223A357D2C
            226E6D223A225472616E73666F726D227D5D2C226E6D223A2245222C226E7022
            3A332C22636978223A322C22626D223A302C226978223A322C226D6E223A2241
            44424520566563746F722047726F7570222C226864223A66616C73657D2C7B22
            7479223A226772222C226974223A5B7B22696E64223A302C227479223A227368
            222C226978223A312C226B73223A7B2261223A302C226B223A7B2269223A5B5B
            302C305D2C5B302E3430312C2D302E3337325D2C5B302E3831342C305D2C5B30
            2E3431392C302E3633395D2C5B302C312E3338335D2C5B302C305D2C5B2D302E
            3433372C302E36335D2C5B2D302E3837392C305D2C5B2D302E3339362C2D302E
            3337325D2C5B2D302E3036352C2D302E3832365D2C5B302C305D2C5B302E3930
            322C302E3739315D2C5B312E3437372C305D2C5B302E3830362C2D302E353031
            5D2C5B302E3433342C2D302E3933375D2C5B302C2D312E32335D2C5B302C305D
            2C5B2D302E39342C2D312E3130345D2C5B2D312E3634312C305D2C5B2D302E39
            31372C302E3739315D2C5B2D302E312C312E3337375D5D2C226F223A5B5B2D30
            2E3035392C302E3737395D2C5B2D302E3430312C302E3337325D2C5B2D302E39
            30322C305D2C5B2D302E3431392C2D302E3633395D2C5B302C305D2C5B302E30
            31322C2D312E3332345D2C5B302E3433362C2D302E36335D2C5B302E3830392C
            305D2C5B302E3339362C302E3337325D2C5B302C305D2C5B2D302E3134312C2D
            312E34335D2C5B2D302E3930322C2D302E3739315D2C5B2D312E3036362C305D
            2C5B2D302E3830362C302E3530315D2C5B2D302E3433342C302E3933385D2C5B
            302C305D2C5B302C312E3932385D2C5B302E39342C312E3130355D2C5B312E35
            2C305D2C5B302E3931372C2D302E3739315D2C5B302C305D5D2C2276223A5B5B
            2D332E3232362C2D342E3236335D2C5B2D332E3931362C2D322E3533365D2C5B
            2D352E3733392C2D312E3937385D2C5B2D372E3732312C2D322E3933365D2C5B
            2D382E33352C2D352E3936385D2C5B2D382E33352C2D362E3933355D2C5B2D37
            2E3637372C2D392E3836365D2C5B2D352E3730342C2D31302E3831315D2C5B2D
            332E3839382C2D31302E3235325D2C5B2D332E3230382C2D382E3435355D2C5B
            2D302E3537312C2D382E3435355D2C5B2D322E3133362C2D31312E3738365D2C
            5B2D352E3730342C2D31322E3937335D2C5B2D382E3531322C2D31322E323231
            5D2C5B2D31302E3337312C2D31302E3036335D2C5B2D31312E3032312C2D362E
            3831325D2C5B2D31312E3032312C2D362E3032395D2C5B2D392E3631312C2D31
            2E3438315D2C5B2D352E3733392C302E3137365D2C5B2D322E3131342C2D312E
            3031315D2C5B2D302E3538392C2D342E3236335D5D2C2263223A747275657D2C
            226978223A327D2C226E6D223A2243222C226D6E223A22414442452056656374
            6F72205368617065202D2047726F7570222C226864223A66616C73657D2C7B22
            7479223A22666C222C2263223A7B2261223A302C226B223A5B312C302E323934
            3131373634373035392C302E3336303738343331333732352C315D2C22697822
            3A347D2C226F223A7B2261223A302C226B223A3130302C226978223A357D2C22
            72223A312C22626D223A302C226E6D223A2246696C6C2031222C226D6E223A22
            4144424520566563746F722047726170686963202D2046696C6C222C22686422
            3A66616C73657D2C7B227479223A227472222C2270223A7B2261223A302C226B
            223A5B302C305D2C226978223A327D2C2261223A7B2261223A302C226B223A5B
            302C305D2C226978223A317D2C2273223A7B2261223A302C226B223A5B313030
            2C3130305D2C226978223A337D2C2272223A7B2261223A302C226B223A302C22
            6978223A367D2C226F223A7B2261223A302C226B223A3130302C226978223A37
            7D2C22736B223A7B2261223A302C226B223A302C226978223A347D2C22736122
            3A7B2261223A302C226B223A302C226978223A357D2C226E6D223A225472616E
            73666F726D227D5D2C226E6D223A2243222C226E70223A332C22636978223A32
            2C22626D223A302C226978223A332C226D6E223A224144424520566563746F72
            2047726F7570222C226864223A66616C73657D5D2C226970223A302C226F7022
            3A34312E303030303031363639393634322C227374223A302C22626D223A307D
            2C7B22646464223A302C22696E64223A332C227479223A342C226E6D223A2253
            68617065204C617965722032222C227372223A312C226B73223A7B226F223A7B
            2261223A302C226B223A3130302C226978223A31317D2C2272223A7B2261223A
            302C226B223A302C226978223A31307D2C2270223A7B2261223A302C226B223A
            5B33312C33322C305D2C226978223A322C226C223A327D2C2261223A7B226122
            3A302C226B223A5B302C302C305D2C226978223A312C226C223A327D2C227322
            3A7B2261223A312C226B223A5B7B2269223A7B2278223A5B302E3636372C302E
            3636372C302E3636375D2C2279223A5B312C312C315D7D2C226F223A7B227822
            3A5B302E3333332C302E3333332C302E3333335D2C2279223A5B302C302C305D
            7D2C2274223A302C2273223A5B3132372C3132372C3130305D7D2C7B2269223A
            7B2278223A5B302E3636372C302E3636372C302E3636375D2C2279223A5B312C
            312C315D7D2C226F223A7B2278223A5B302E3333332C302E3333332C302E3333
            335D2C2279223A5B302C302C305D7D2C2274223A31302C2273223A5B3134372C
            3134372C3130305D7D2C7B2274223A32302E303030303030383134363136372C
            2273223A5B3132372C3132372C3130305D7D5D2C226978223A362C226C223A32
            7D7D2C22616F223A302C22736861706573223A5B7B227479223A226772222C22
            6974223A5B7B2264223A312C227479223A22656C222C2273223A7B2261223A30
            2C226B223A5B32362E32352C32362E32355D2C226978223A327D2C2270223A7B
            2261223A302C226B223A5B302C305D2C226978223A337D2C226E6D223A22456C
            6C6970736520506174682031222C226D6E223A224144424520566563746F7220
            5368617065202D20456C6C69707365222C226864223A66616C73657D2C7B2274
            79223A22666C222C2263223A7B2261223A302C226B223A5B312C302E32393431
            31373634373035392C302E3336303738343331333732352C315D2C226978223A
            347D2C226F223A7B2261223A302C226B223A3130302C226978223A357D2C2272
            223A312C22626D223A302C226E6D223A2246696C6C2031222C226D6E223A2241
            44424520566563746F722047726170686963202D2046696C6C222C226864223A
            66616C73657D2C7B227479223A227472222C2270223A7B2261223A302C226B22
            3A5B302E3337352C302E3337355D2C226978223A327D2C2261223A7B2261223A
            302C226B223A5B302C305D2C226978223A317D2C2273223A7B2261223A302C22
            6B223A5B3130302C3130305D2C226978223A337D2C2272223A7B2261223A302C
            226B223A302C226978223A367D2C226F223A7B2261223A302C226B223A313030
            2C226978223A377D2C22736B223A7B2261223A302C226B223A302C226978223A
            347D2C227361223A7B2261223A302C226B223A302C226978223A357D2C226E6D
            223A225472616E73666F726D227D5D2C226E6D223A22456C6C69707365203122
            2C226E70223A332C22636978223A322C22626D223A302C226978223A312C226D
            6E223A224144424520566563746F722047726F7570222C226864223A66616C73
            657D5D2C226970223A302C226F70223A34312E30303030303136363939363432
            2C227374223A302C22626D223A307D2C7B22646464223A302C22696E64223A34
            2C227479223A342C226E6D223A225368617065204C617965722031222C227372
            223A312C226B73223A7B226F223A7B2261223A312C226B223A5B7B2269223A7B
            2278223A5B302E3636375D2C2279223A5B315D7D2C226F223A7B2278223A5B30
            2E3333335D2C2279223A5B305D7D2C2274223A302C2273223A5B3130305D7D2C
            7B2274223A34302E303030303031363239323333342C2273223A5B305D7D5D2C
            226978223A31317D2C2272223A7B2261223A302C226B223A302C226978223A31
            307D2C2270223A7B2261223A302C226B223A5B33312C33322C305D2C22697822
            3A322C226C223A327D2C2261223A7B2261223A302C226B223A5B302C302C305D
            2C226978223A312C226C223A327D2C2273223A7B2261223A312C226B223A5B7B
            2269223A7B2278223A5B302E3636372C302E3636372C302E3636375D2C227922
            3A5B312C312C315D7D2C226F223A7B2278223A5B302E3333332C302E3333332C
            302E3333335D2C2279223A5B302C302C305D7D2C2274223A302C2273223A5B31
            32372C3132372C3130305D7D2C7B2274223A34302E3030303030313632393233
            33342C2273223A5B3235302C3235302C3130305D7D5D2C226978223A362C226C
            223A327D7D2C22616F223A302C22736861706573223A5B7B227479223A226772
            222C226974223A5B7B2264223A312C227479223A22656C222C2273223A7B2261
            223A302C226B223A5B32362E32352C32362E32355D2C226978223A327D2C2270
            223A7B2261223A302C226B223A5B302C305D2C226978223A337D2C226E6D223A
            22456C6C6970736520506174682031222C226D6E223A22414442452056656374
            6F72205368617065202D20456C6C69707365222C226864223A66616C73657D2C
            7B227479223A22666C222C2263223A7B2261223A302C226B223A5B312C302E32
            39343131373634373035392C302E3336303738343331333732352C315D2C2269
            78223A347D2C226F223A7B2261223A302C226B223A3130302C226978223A357D
            2C2272223A312C22626D223A302C226E6D223A2246696C6C2031222C226D6E22
            3A224144424520566563746F722047726170686963202D2046696C6C222C2268
            64223A66616C73657D2C7B227479223A227472222C2270223A7B2261223A302C
            226B223A5B302E3337352C302E3337355D2C226978223A327D2C2261223A7B22
            61223A302C226B223A5B302C305D2C226978223A317D2C2273223A7B2261223A
            302C226B223A5B3130302C3130305D2C226978223A337D2C2272223A7B226122
            3A302C226B223A302C226978223A367D2C226F223A7B2261223A302C226B223A
            3130302C226978223A377D2C22736B223A7B2261223A302C226B223A302C2269
            78223A347D2C227361223A7B2261223A302C226B223A302C226978223A357D2C
            226E6D223A225472616E73666F726D227D5D2C226E6D223A22456C6C69707365
            2031222C226E70223A332C22636978223A322C22626D223A302C226978223A31
            2C226D6E223A224144424520566563746F722047726F7570222C226864223A66
            616C73657D5D2C226970223A302C226F70223A34312E30303030303136363939
            3634322C227374223A302C22626D223A307D5D2C226D61726B657273223A5B5D
            7D}
        end
        object LabelRecordingTime: TLabel
          Align = Left
          AutoSize = True
          StyledSettings = [Family, Style]
          Margins.Left = 10.000000000000000000
          Margins.Right = 10.000000000000000000
          Position.X = 70.000000000000000000
          Size.Width = 26.000000000000000000
          Size.Height = 26.000000000000000000
          Size.PlatformDefault = False
          TextSettings.Font.Size = 14.000000000000000000
          TextSettings.FontColor = xFFECECF1
          TextSettings.WordWrap = False
          TextSettings.Trimming = None
          Text = '0:00'
          TabOrder = 1
        end
      end
      object LayoutAttachments: TLayout
        Align = MostTop
        Position.X = 26.000000000000000000
        Position.Y = 12.000000000000000000
        Size.Width = 618.000000000000000000
        Size.Height = 50.000000000000000000
        Size.PlatformDefault = False
        Visible = False
        TabOrder = 4
      end
    end
  end
  object TimerTyping: TTimer
    Enabled = False
    Interval = 800
    OnTimer = TimerTypingTimer
    Left = 64
    Top = 80
  end
  object OpenDialogAudio: TOpenDialog
    Filter = 
      'Supported formats|*.m4a; *.mp3; *.webm; *.mp4; *.mpga; *.wav; *.' +
      'mpeg'
    Left = 64
    Top = 202
  end
  object LayoutButtom: TLayout
    Align = Bottom
    Locked = True
    Position.Y = 636.000000000000000000
    Size.Width = 1006.000000000000000000
    Size.Height = 50.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 5
    object FlowLayoutActions: TFlowLayout
      Align = Client
      ClipChildren = True
      HitTest = False
      Padding.Left = 40.000000000000000000
      Padding.Top = 6.000000000000000000
      Padding.Right = 40.000000000000000000
      Margins.Left = 20.000000000000000000
      Margins.Right = 20.000000000000000000
      Size.Width = 966.000000000000000000
      Size.Height = 50.000000000000000000
      Size.PlatformDefault = False
      Justify = Center
      JustifyLastLine = Center
      FlowDirection = LeftToRight
      HorizontalGap = 10.000000000000000000
      VerticalGap = 10.000000000000000000
      object ButtonContinue: TButton
        Align = Center
        Hint = 'Continue chat. Request an addition or continuation'
        Size.Width = 112.000000000000000000
        Size.Height = 38.000000000000000000
        Size.PlatformDefault = False
        StyleLookup = 'buttonstyle_continue'
        TabOrder = 2
        Text = 'Continue'
        TextSettings.HorzAlign = Leading
        OnClick = ButtonContinueClick
        object ShadowEffect2: TShadowEffect
          Distance = 0.001000000047497451
          Direction = 45.000000000000000000
          Softness = 0.600000023841857900
          Opacity = 0.600000023841857900
          ShadowColor = xFF343541
        end
      end
      object ButtonExportImport: TButton
        Align = Center
        Hint = 'Import or export chat'
        Size.Width = 156.000000000000000000
        Size.Height = 38.000000000000000000
        Size.PlatformDefault = False
        StyleLookup = 'buttonstyle_import_export'
        TabOrder = 1
        Text = 'Import && Export'
        OnClick = ButtonExportImportClick
        object ShadowEffect3: TShadowEffect
          Distance = 0.001000000047497451
          Direction = 45.000000000000000000
          Softness = 0.600000023841857900
          Opacity = 0.600000023841857900
          ShadowColor = xFF343541
        end
        object Rectangle2: TRectangle
          Anchors = [akTop, akRight]
          Fill.Color = xFFC40000
          HitTest = False
          Position.X = 127.000000000000000000
          Position.Y = -3.000000000000000000
          Size.Width = 37.000000000000000000
          Size.Height = 13.000000000000000000
          Size.PlatformDefault = False
          Stroke.Kind = None
          XRadius = 4.000000000000000000
          YRadius = 4.000000000000000000
          object Label3: TLabel
            Align = Client
            StyledSettings = [Style]
            Size.Width = 37.000000000000000000
            Size.Height = 13.000000000000000000
            Size.PlatformDefault = False
            TextSettings.Font.Family = 'Roboto'
            TextSettings.Font.Size = 9.000000000000000000
            TextSettings.FontColor = claWhite
            TextSettings.HorzAlign = Center
            TextSettings.WordWrap = False
            TextSettings.Trimming = None
            Text = 'beta'
            TabOrder = 0
          end
        end
      end
      object ButtonRetry: TButton
        Align = Center
        Hint = 'Resend request'
        Size.Width = 103.000000000000000000
        Size.Height = 38.000000000000000000
        Size.PlatformDefault = False
        StyleLookup = 'buttonstyle_retry'
        TabOrder = 0
        Text = '  Retry'
        TextSettings.HorzAlign = Leading
        OnClick = ButtonRetryClick
        object ShadowEffect1: TShadowEffect
          Distance = 0.001000000047497451
          Direction = 45.000000000000000000
          Softness = 0.600000023841857900
          Opacity = 0.600000023841857900
          ShadowColor = xFF343541
        end
      end
    end
    object LayoutScrollDown: TLayout
      Align = Client
      Locked = True
      Padding.Top = 10.000000000000000000
      Padding.Right = 30.000000000000000000
      Padding.Bottom = 10.000000000000000000
      Size.Width = 1006.000000000000000000
      Size.Height = 50.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 0
      object ButtonScrollDown: TButton
        Align = Right
        Hint = 'Scroll down'
        Position.X = 946.000000000000000000
        Position.Y = 10.000000000000000000
        Size.Width = 30.000000000000000000
        Size.Height = 30.000000000000000000
        Size.PlatformDefault = False
        StyleLookup = 'button_scrolldown'
        TabOrder = 0
        Text = 'button_scrolldown'
        OnClick = ButtonScrollDownClick
      end
    end
  end
  object TimerCheckRecording: TTimer
    Enabled = False
    OnTimer = TimerCheckRecordingTimer
    Left = 64
    Top = 144
  end
  object Rectangle1: TRectangle
    Position.X = 20.000000000000000000
    Position.Y = 70.000000000000000000
    Size.Width = 190.000000000000000000
    Size.Height = 97.000000000000000000
    Size.PlatformDefault = False
    Visible = False
    object LabelTest: TLabel
      Align = Client
      Margins.Left = 4.000000000000000000
      Margins.Top = 4.000000000000000000
      Margins.Right = 4.000000000000000000
      Margins.Bottom = 4.000000000000000000
      Size.Width = 182.000000000000000000
      Size.Height = 89.000000000000000000
      Size.PlatformDefault = False
      TextSettings.VertAlign = Leading
      TextSettings.Trimming = None
      Text = 'LabelTest'
      TabOrder = 0
    end
  end
end


================================================
FILE: ChatGPT.FrameChat.pas
================================================
unit ChatGPT.FrameChat;

interface

{$IF DEFINED(ANDROID) OR DEFINED(IOS) OR DEFINED(IOS64)}
  {$DEFINE MOBILE}
{$ENDIF}

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
  FMX.Objects, FMX.Layouts, FMX.Memo.Types, FMX.Controls.Presentation,
  FMX.Memo.Style, FMX.ScrollBox, FMX.Memo, OpenAI, OpenAI.Completions,
  FMX.Edit.Style, ChatGPT.FrameMessage, ChatGPT.Classes, System.Threading,
  FMX.Edit, FMX.ImgList, OpenAI.Chat, System.Generics.Collections, OpenAI.Audio,
  OpenAI.Utils.ChatHistory, OpenAI.Images, ChatGPT.ChatSettings, System.JSON,
  FMX.Effects, FMX.ListBox, System.Skia, FMX.Skia, ChatGPT.SoundRecorder,
  FMX.InertialMovement, System.RTLConsts, OpenAI.Chat.Functions;

type
  TButton = class(FMX.StdCtrls.TButton)
  public
    procedure SetBounds(X, Y, AWidth, AHeight: Single); override;
  end;

  TLabel = class(FMX.StdCtrls.TLabel)
  public
    procedure SetBounds(X, Y, AWidth, AHeight: Single); override;
  end;

  TFixedScrollCalculations = class(TScrollCalculations)
  protected
    procedure DoChanged; override;
  end;

  TVertScrollBox = class(FMX.Layouts.TVertScrollBox)
  private
    FViewPositionY: Single;
    procedure SetViewPositionY(const Value: Single);
  protected
    function CreateAniCalculations: TScrollCalculations; override;
  published
    property ViewPositionY: Single read FViewPositionY write SetViewPositionY;
  end;

  TMemo = class(FMX.Memo.TMemo)
  private
    FViewPos: Single;
    procedure SetViewPos(const Value: Single);
  public
    property ViewPos: Single read FViewPos write SetViewPos;
  end;

  TFrameChat = class(TFrame)
    VertScrollBoxChat: TVertScrollBox;
    LayoutSend: TLayout;
    RectangleSendBG: TRectangle;
    MemoQuery: TMemo;
    LayoutQuery: TLayout;
    RectangleMemoBG: TRectangle;
    LayoutSendControls: TLayout;
    LayoutTyping: TLayout;
    TimerTyping: TTimer;
    LayoutTypingContent: TLayout;
    Layout3: TLayout;
    RectangleBot: TRectangle;
    Path3: TPath;
    Layout4: TLayout;
    RectangleIndicate: TRectangle;
    LabelTyping: TLabel;
    LineBorder: TLine;
    LayoutWelcome: TLayout;
    RectangleBG: TRectangle;
    LabelWelcomeTitle: TLabel;
    FlowLayoutWelcome: TFlowLayout;
    LayoutExampleTitle: TLayout;
    PathExaFull: TPath;
    ButtonExample3: TButton;
    ButtonExample2: TButton;
    ButtonExample1: TButton;
    LayoutCapabilitiesTitle: TLayout;
    PathCapFull: TPath;
    Label5: TLabel;
    Label6: TLabel;
    Label9: TLabel;
    LayoutLimitationsTitle: TLayout;
    PathLimFull: TPath;
    Label8: TLabel;
    Label7: TLabel;
    Label10: TLabel;
    Label12: TLabel;
    LayoutSendCommons: TLayout;
    ButtonAudio: TButton;
    Path8: TPath;
    ButtonSend: TButton;
    PathSend: TPath;
    OpenDialogAudio: TOpenDialog;
    ButtonImage: TButton;
    PathImage: TPath;
    RectangleImageMode: TRectangle;
    RectangleTypeBG: TRectangle;
    LabelSendTip: TLabel;
    Layout5: TLayout;
    Label2: TLabel;
    PathExaCompact: TPath;
    Layout6: TLayout;
    Label1: TLabel;
    PathCapCompact: TPath;
    Layout7: TLayout;
    Label11: TLabel;
    PathLimCompact: TPath;
    LayoutChatSettings: TLayout;
    ButtonSettings: TButton;
    Path9: TPath;
    LayoutButtom: TLayout;
    ButtonRetry: TButton;
    ShadowEffect1: TShadowEffect;
    LayoutScrollDown: TLayout;
    ButtonScrollDown: TButton;
    PathAudio: TPath;
    LayoutAudioRecording: TLayout;
    AnimatedImageRecording: TSkAnimatedImage;
    PathStopRecord: TPath;
    TimerCheckRecording: TTimer;
    LabelRecordingTime: TLabel;
    ButtonContinue: TButton;
    ShadowEffect2: TShadowEffect;
    FlowLayoutActions: TFlowLayout;
    ButtonExportImport: TButton;
    ShadowEffect3: TShadowEffect;
    Rectangle1: TRectangle;
    LabelTest: TLabel;
    Rectangle2: TRectangle;
    Label3: TLabel;
    LayoutAttachments: TLayout;
    procedure LayoutSendResize(Sender: TObject);
    procedure MemoQueryChange(Sender: TObject);
    procedure ButtonSendClick(Sender: TObject);
    procedure TimerTypingTimer(Sender: TObject);
    procedure LayoutTypingResize(Sender: TObject);
    procedure MemoQueryKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
    procedure LayoutWelcomeResize(Sender: TObject);
    procedure FlowLayoutWelcomeResize(Sender: TObject);
    procedure ButtonExample1Click(Sender: TObject);
    procedure ButtonExample2Click(Sender: TObject);
    procedure ButtonExample3Click(Sender: TObject);
    procedure ButtonAudioClick(Sender: TObject);
    procedure ButtonImageClick(Sender: TObject);
    procedure ButtonSettingsClick(Sender: TObject);
    procedure ButtonRetryClick(Sender: TObject);
    procedure ButtonScrollDownClick(Sender: TObject);
    procedure VertScrollBoxChatViewportPositionChange(Sender: TObject; const OldViewportPosition, NewViewportPosition: TPointF; const ContentSizeChanged: Boolean);
    procedure TimerCheckRecordingTimer(Sender: TObject);
    procedure ButtonExample1Tap(Sender: TObject; const Point: TPointF);
    procedure ButtonExample2Tap(Sender: TObject; const Point: TPointF);
    procedure ButtonExample3Tap(Sender: TObject; const Point: TPointF);
    procedure MemoQueryKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
    procedure MemoQueryEnter(Sender: TObject);
    procedure MemoQueryViewportPositionChange(Sender: TObject; const OldViewportPosition, NewViewportPosition: TPointF; const ContentSizeChanged: Boolean);
    procedure ButtonContinueClick(Sender: TObject);
    procedure ButtonExportImportClick(Sender: TObject);
  private
    FAPI: IOpenAI;
    FChatId: string;
    FPool: TThreadPool;
    FTitle: string;
    FMode: TWindowMode;
    FIsTyping: Boolean;
    FBuffer: TChatHistory;
    FIsImageMode: Boolean;
    FTemperature: Single;
    FLastRequest: TProc;
    FMenuItem: TListBoxItem;
    FIsFirstMessage: Boolean;
    FPresencePenalty: Single;
    FModel: string;
    FMaxTokens: Integer;
    FMaxTokensQuery: Integer;
    FFrequencyPenalty: Single;
    FTopP: Single;
    FAudioRecord: TAudioRecord;
    FRecordingStartTime: TDateTime;
    FOnNeedFuncList: TOnNeedFuncList;
    FUseFunctions: Boolean;
    FAutoExecFuncs: Boolean;
    FOnTitleChanged: TNotifyEvent;
    procedure DoOnUpdateChatItems;
    function NewMessage(const Text: string; Role: TMessageKind; UseBuffer: Boolean = True; IsAudio: Boolean = False): TFrameMessage;
    function NewMessageImage(Role: TMessageKind; Images: TArray<string>): TFrameMessage;
    procedure ClearChat;
    procedure SetTyping(const Value: Boolean);
    procedure SetAPI(const Value: IOpenAI);
    procedure SetChatId(const Value: string);
    procedure ShowError(const Text: string);
    procedure AppendMessages(Response: TChat); overload;
    procedure AppendMessages(Response: TImageGenerations); overload;
    procedure ScrollDown(Animate: Boolean = False);
    procedure SetTitle(const Value: string);
    procedure SetMode(const Value: TWindowMode);
    procedure AppendAudio(Response: TAudioTranscriptionObject);
    procedure SetIsImageMode(const Value: Boolean);
    procedure SendRequestImage;
    procedure SendRequestPrompt;
    procedure SetTemperature(const Value: Single);
    procedure RequestPrompt;
    procedure RequestImage(const Prompt: string);
    procedure RequestAudio(const AudioFile: string);
    procedure SetLastRequest(const Value: TProc);
    procedure SetMenuItem(const Value: TListBoxItem);
    procedure SetFrequencyPenalty(const Value: Single);
    procedure SetMaxTokens(const Value: Integer);
    procedure SetMaxTokensQuery(const Value: Integer);
    procedure SetModel(const Value: string);
    procedure SetPresencePenalty(const Value: Single);
    procedure ChatToUp;
    procedure SetTopP(const Value: Single);
    procedure FOnMessageDelete(Sender: TObject);
    procedure StopRecording;
    procedure StartRecording;
    function GenerateAudioFileName: string;
    procedure FOnStartRecord(Sender: TObject);
    procedure UpdateSendControls;
    procedure SetOnNeedFuncList(const Value: TOnNeedFuncList);
    function GetFuncs: TArray<IChatFunction>;
    procedure ProcFunction(Func: TChatFunctionCall);
    procedure RequestFunc(FuncResult: string);
    function NewMessageFunc(const FuncName, FuncArgs: string): TFrameMessage;
    procedure FOnMessageTextUpdated(Sender: TObject; const MessageId, Text: string);
    procedure FOnExecuteFunc(Sender: TObject; const FuncName, FuncArgs: string; Callback: TProc<Boolean, string>);
    procedure ExecuteFunc(const FuncName, FuncArgs: string; Callback: TProc<Boolean, string>);
    procedure SetUseFunctions(const Value: Boolean);
    procedure SetAutoExecFuncs(const Value: Boolean);
    procedure SetOnTitleChanged(const Value: TNotifyEvent);
    procedure SendText;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function MakeContentScreenshot: TBitmap;
    function SaveAsJson: TJSONObject;
    procedure LoadFromJson(JSON: TJSONObject);
    property API: IOpenAI read FAPI write SetAPI;
    property ChatId: string read FChatId write SetChatId;
    property Title: string read FTitle write SetTitle;
    property Mode: TWindowMode read FMode write SetMode;
    property Temperature: Single read FTemperature write SetTemperature;
    property MaxTokens: Integer read FMaxTokens write SetMaxTokens;
    property MaxTokensQuery: Integer read FMaxTokensQuery write SetMaxTokensQuery;
    property PresencePenalty: Single read FPresencePenalty write SetPresencePenalty;
    property FrequencyPenalty: Single read FFrequencyPenalty write SetFrequencyPenalty;
    property Model: string read FModel write SetModel;
    property TopP: Single read FTopP write SetTopP;
    property IsImageMode: Boolean read FIsImageMode write SetIsImageMode;
    property LastRequest: TProc read FLastRequest write SetLastRequest;
    property MenuItem: TListBoxItem read FMenuItem write SetMenuItem;
    property IsFirstMessage: Boolean read FIsFirstMessage write FIsFirstMessage;
    property OnNeedFuncList: TOnNeedFuncList read FOnNeedFuncList write SetOnNeedFuncList;
    property UseFunctions: Boolean read FUseFunctions write SetUseFunctions;
    property AutoExecFuncs: Boolean read FAutoExecFuncs write SetAutoExecFuncs;
    property OnTitleChanged: TNotifyEvent read FOnTitleChanged write SetOnTitleChanged;
    procedure Init;
  end;

const
  MAX_TOKENS = 1024;
  MODEL_TOKENS_LIMIT = 4096;
  ErrorHintTimeout = 'If the error is due to a timeout, you can increase the response timeout in the general program settings.';

implementation

uses
  FMX.Ani, System.Math, OpenAI.API, System.IOUtils, ChatGPT.Manager,
  ChatGPT.Overlay, FMX.BehaviorManager, HGM.FMX.Ani, System.Net.HttpClient,
  {$IFDEF ANDROID}
  ChatGPT.Android, FMX.Platform.UI.Android,
  {$ENDIF}
  System.DateUtils, ChatGPT.ImportExport, FMX.Text;

{$R *.fmx}

function HumanTime(Value: TTime): string;
var
  H, M, S, Ms: Word;
begin
  DecodeTime(Value, H, M, S, Ms);
  Result := '';
  if H > 0 then
    Result := Result + H.ToString + ' ч. ';
  if M > 0 then
    Result := Result + M.ToString + ' мин. ';
  if S > 0 then
    Result := Result + S.ToString + ' сек. ';
  if Result.IsEmpty then
    Result := Result + '< 1 сек. ';
end;

function SecondsToTime(Value: Double): TTime;
begin
  Result := Value / SecsPerDay;
end;

procedure TFrameChat.ShowError(const Text: string);
begin
  TThread.Queue(nil,
    procedure
    begin
      var Frame := NewMessage(Text, TMessageKind.Error, False);
      Frame.IsError := True;
    end);
end;

procedure TFrameChat.AppendMessages(Response: TImageGenerations);
begin
  try
    var Images: TArray<string>;
    SetLength(Images, Length(Response.Data));
    for var i := 0 to High(Response.Data) do
      Images[i] := Response.Data[i].Url;
    NewMessageImage(TMessageKind.Assistant, Images);
  finally
    Response.Free;
  end;
end;

function TFrameChat.NewMessageFunc(const FuncName, FuncArgs: string): TFrameMessage;
begin
  ChatToUp;
  LayoutWelcome.Visible := False;
  Result := TFrameMessage.Create(VertScrollBoxChat);
  Result.SetMode(FMode);
  Result.Position.Y := VertScrollBoxChat.ContentBounds.Height;
  Result.Parent := VertScrollBoxChat;
  Result.Align := TAlignLayout.MostTop;
  Result.Id := '';
  Result.OnDelete := FOnMessageDelete;
  Result.OnTextUpdated := FOnMessageTextUpdated;
  TFrameMessage(Result).MessageRole := TMessageKind.Func;
  TFrameMessage(Result).FuncName := FuncName;
  TFrameMessage(Result).FuncArgs := FuncArgs;
  TFrameMessage(Result).FuncState := TMessageFuncState.Wait;
  TFrameMessage(Result).OnFuncExecute := FOnExecuteFunc;
  Result.StartAnimate;
  DoOnUpdateChatItems;
  if AutoExecFuncs then
    TFrameMessage(Result).ExecuteFunc;
end;

function TFrameChat.NewMessageImage(Role: TMessageKind; Images: TArray<string>): TFrameMessage;
begin
  ChatToUp;
  LayoutWelcome.Visible := False;
  Result := TFrameMessage.Create(VertScrollBoxChat);
  Result.SetMode(FMode);
  Result.Position.Y := VertScrollBoxChat.ContentBounds.Height;
  Result.Parent := VertScrollBoxChat;
  Result.Align := TAlignLayout.MostTop;
  Result.Id := '';
  Result.OnDelete := FOnMessageDelete;
  Result.OnTextUpdated := FOnMessageTextUpdated;
  TFrameMessage(Result).MessageRole := Role;
  TFrameMessage(Result).Images := Images;
  Result.StartAnimate;
  DoOnUpdateChatItems;
end;

procedure TFrameChat.ExecuteFunc(const FuncName, FuncArgs: string; Callback: TProc<Boolean, string>);
begin
  var Funcs := GetFuncs;
  for var Item in Funcs do
    if Item.Name = FuncName then
    begin
      TTask.Run(
        procedure
        begin
          var FuncResult := '';
          var ErrorText: string;
          try
            try
              FuncResult := Item.Execute(FuncArgs);
            except
              on E: Exception do
              begin
                ErrorText := E.Message;
                FuncResult := '';
              end;
            end;
            TThread.Queue(nil,
              procedure
              begin
                Callback(not FuncResult.IsEmpty, ErrorText);
                if not FuncResult.IsEmpty then
                begin
                  FBuffer.NewFunc(FuncName, FuncResult, TGUID.NewGuid.ToString);
                  RequestFunc(FuncResult);
                end;
              end);
          finally
            //
          end;
        end);
      Exit;
    end;
  Callback(False, 'Function not found');
end;

procedure TFrameChat.ProcFunction(Func: TChatFunctionCall);
begin
  FBuffer.NewAsistantFunc(Func.Name, Func.Arguments, TGUID.NewGuid.ToString);
  var Funcs := GetFuncs;
  for var Item in Funcs do
    if Item.Name = Func.Name then
    begin
      NewMessageFunc(Func.Name, Func.Arguments);
      Exit;
    end;
  ShowError('Function with name "' + Func.Name + '" not found');
end;

procedure TFrameChat.AppendMessages(Response: TChat);
begin
  try
    for var Item in Response.Choices do
      if Item.FinishReason = TFinishReason.FunctionCall then
        ProcFunction(Item.Message.FunctionCall)
      else
        NewMessage(Item.Message.Content, TMessageKind.Assistant);
  finally
    Response.Free;
  end;
end;

procedure TFrameChat.AppendAudio(Response: TAudioTranscriptionObject);
begin
  try
    NewMessage(Response.Text, TMessageKind.Assistant, True, True);
  finally
    Response.Free;
  end;
end;

function TFrameChat.SaveAsJson: TJSONObject;
begin
  Result := TJSONObject.Create;
  try
    var JArray := TJSONArray.Create;
    Result.AddPair('chat_id', FChatId);
    Result.AddPair('temperature', TJSONNumber.Create(FTemperature));
    Result.AddPair('title', FTitle);
    Result.AddPair('items', JArray);

    Result.AddPair('frequency_penalty', TJSONNumber.Create(FrequencyPenalty));
    Result.AddPair('presence_penalty', TJSONNumber.Create(PresencePenalty));
    Result.AddPair('max_tokens', TJSONNumber.Create(MaxTokens));
    Result.AddPair('max_tokens_query', TJSONNumber.Create(MaxTokensQuery));
    Result.AddPair('top_p', TJSONNumber.Create(TopP));
    Result.AddPair('model', Model);
    Result.AddPair('is_image_mode', IsImageMode);
    Result.AddPair('draft', MemoQuery.Text);
    Result.AddPair('use_functions', UseFunctions);
    Result.AddPair('auto_exec_funcs', AutoExecFuncs);

    for var Control in VertScrollBoxChat.Content.Controls do
      if Control is TFrameMessage then
        if not TFrameMessage(Control).IsError then
          if not (TFrameMessage(Control).MessageRole in [TMessageKind.Error, TMessageKind.Func]) then
            JArray.Add(TFrameMessage(Control).ToJsonObject);
  except
    //
  end;
end;

procedure TFrameChat.FOnExecuteFunc(Sender: TObject; const FuncName, FuncArgs: string; Callback: TProc<Boolean, string>);
begin
  ExecuteFunc(FuncName, FuncArgs, Callback);
end;

procedure TFrameChat.FOnMessageDelete(Sender: TObject);
var
  Frame: TFrameMessage absolute Sender;
begin
  if not (Sender is TFrameMessage) then
    Exit;
  FBuffer.DeleteByTag(Frame.Id);
  if VertScrollBoxChat.Content.ControlsCount <= 3 then
    LayoutWelcome.Visible := True;
end;

procedure TFrameChat.FOnMessageTextUpdated(Sender: TObject; const MessageId, Text: string);
var
  Frame: TFrameMessage absolute Sender;
begin
  if not (Sender is TFrameMessage) then
    Exit;
  FBuffer.SetContentByTag(MessageId, Text);
end;

function TFrameChat.GenerateAudioFileName: string;
begin
  Result := TPath.Combine(Manager.AudioCacheFolder, 'audio_record' + FormatDateTime('DDMMYYYY_HHNNSS', Now) + '.wav');
end;

procedure TFrameChat.Init;
begin
  //Opacity := 0;
  //TAnimator.AnimateFloat(Self, 'Opacity', 1);
  {$IFNDEF MOBILE}
  MemoQuery.SetFocus;
  {$ENDIF}
  TThread.ForceQueue(nil,
    procedure
    begin
      MemoQuery.PrepareForPaint;
      MemoQueryChange(nil);
    end);
end;

procedure TFrameChat.LoadFromJson(JSON: TJSONObject);
begin
  var ItemCount: Integer := 0;
  var LastRoleIsUser: Boolean := False;
  if FChatId.IsEmpty then
    FChatId := JSON.GetValue('chat_id', TGUID.NewGuid.ToString);
  Title := JSON.GetValue('title', FTitle);
  FTemperature := JSON.GetValue('temperature', FTemperature);
  FrequencyPenalty := JSON.GetValue<Single>('frequency_penalty', FrequencyPenalty);
  PresencePenalty := JSON.GetValue<Single>('presence_penalty', PresencePenalty);
  TopP := JSON.GetValue<Single>('top_p', TopP);
  Model := JSON.GetValue('model', Model);
  MaxTokens := JSON.GetValue<Integer>('max_tokens', MaxTokens);
  MaxTokensQuery := JSON.GetValue<Integer>('max_tokens_query', MaxTokensQuery);
  IsImageMode := JSON.GetValue('is_image_mode', IsImageMode);
  UseFunctions := JSON.GetValue('use_functions', UseFunctions);
  AutoExecFuncs := JSON.GetValue('auto_exec_funcs', AutoExecFuncs);
  MemoQuery.Text := JSON.GetValue('draft', MemoQuery.Text);
  MemoQuery.SelStart := MemoQuery.Text.Length;
  MemoQuery.SelLength := 0;

  var JArray: TJSONArray;
  if JSON.TryGetValue<TJSONArray>('items', JArray) then
    for var JItem in JArray do
    begin
      var Item: TChatMessageBuild;
      var IsAudio := JItem.GetValue('is_audio', False);

      Item.Role := TMessageRole.FromString(JItem.GetValue('role', 'user'));
      Item.Content := JItem.GetValue('content', '');
      Item.Tag := JItem.GetValue('id', TGUID.NewGuid.ToString);
      Item.Name := JItem.GetValue('name', '');
      var Func: TFunctionCallBuild;
      Func.Name := JItem.GetValue('func_name', '');
      Func.Arguments := JItem.GetValue('func_args', '');
      Item.FunctionCall := Func;

      if not (IsAudio and (Item.Role = TMessageRole.User)) then
        FBuffer.Add(Item);

      var Frame := TFrameMessage.Create(VertScrollBoxChat);
      Frame.Position.Y := VertScrollBoxChat.ContentBounds.Height;
      VertScrollBoxChat.AddObject(Frame);
      Frame.Align := TAlignLayout.MostTop;
      case Item.Role of
        TMessageRole.System:
          Frame.MessageRole := TMessageKind.System;
        TMessageRole.User:
          Frame.MessageRole := TMessageKind.User;
        TMessageRole.Assistant:
          Frame.MessageRole := TMessageKind.Assistant;
        TMessageRole.Func:
          Frame.MessageRole := TMessageKind.Func;
      end;
      Frame.OnDelete := FOnMessageDelete;
      Frame.OnTextUpdated := FOnMessageTextUpdated;
      Frame.Id := Item.Tag;
      Frame.Text := Item.Content;
      Frame.IsAudio := IsAudio;
      Frame.Images := JItem.GetValue<TArray<string>>('images', []);
      Frame.FuncName := Item.FunctionCall.Name;
      Frame.FuncArgs := Item.FunctionCall.Arguments;
      Frame.FuncState := TMessageFuncState(JItem.GetValue('func_state', 0));
      if not Frame.FuncName.IsEmpty then
        Frame.OnFuncExecute := FOnExecuteFunc;
      Frame.SetMode(FMode);
      Frame.UpdateContentSize;
      Inc(ItemCount);
    end;
  DoOnUpdateChatItems;
  if ItemCount > 0 then
  begin
    LayoutWelcome.Visible := False;
    IsFirstMessage := False;
    ScrollDown;
    if LastRoleIsUser then
      LastRequest := RequestPrompt;
  end;
end;

procedure TFrameChat.ScrollDown(Animate: Boolean = False);
begin
  VertScrollBoxChat.RecalcSize;
  if Animate then
    TAnimator.AnimateFloat(VertScrollBoxChat, 'ViewPositionY', VertScrollBoxChat.ContentBounds.Height - VertScrollBoxChat.Height, 1, TAnimationType.out, TInterpolationType.Circular)
  else
    VertScrollBoxChat.ViewportPosition := TPointF.Create(0, VertScrollBoxChat.ContentBounds.Height - VertScrollBoxChat.Height);
end;

function TFrameChat.MakeContentScreenshot: TBitmap;

  function GetMaxBitmapRect: TRectF;
  var
    MaxDimensionSize: Integer;
  begin
    MaxDimensionSize := TCanvasManager.DefaultCanvas.GetAttribute(TCanvasAttribute.MaxBitmapSize);
    Result := TRectF.Create(0, 0, MaxDimensionSize, MaxDimensionSize);
  end;

var
  SceneScale: Single;
  BitmapRect: TRectF;
begin
  if Scene <> nil then
    SceneScale := Scene.GetSceneScale
  else
    SceneScale := 1;

  // TBitmap has limitation of size. It's a max texture size. If we takes screenshot of control, which exceeds this
  // limitation, we get "Bitmap size to big" exception. So we normalize size for avoiding it.
  BitmapRect := TRectF.Create(0, 0, VertScrollBoxChat.Content.ScrollBox.ContentBounds.Width * SceneScale, VertScrollBoxChat.Content.ScrollBox.ContentBounds.Height * SceneScale);
  BitmapRect := BitmapRect.PlaceInto(GetMaxBitmapRect);

  Result := TBitmap.Create(Round(BitmapRect.Width), Round(BitmapRect.Height));
  Result.BitmapScale := SceneScale;
  Result.Clear(0);
  if Result.Canvas.BeginScene then
  try
    VertScrollBoxChat.Content.PaintTo(Result.Canvas, TRectF.Create(0, 0, Result.Width / SceneScale, Result.Height / SceneScale));
  finally
    Result.Canvas.EndScene;
  end;
end;

procedure TFrameChat.ButtonSettingsClick(Sender: TObject);
begin
  TFrameChatSettings.Execute(Self,
    procedure(Frame: TFrameChatSettings)
    begin
      Frame.Mode := FMode;
      Frame.TrackBarTemp.Value := Temperature * 10;
      Frame.TrackBarPP.Value := PresencePenalty * 10;
      Frame.TrackBarFP.Value := FrequencyPenalty * 10;
      if MaxTokens <> 0 then
        Frame.EditMaxTokens.Text := MaxTokens.ToString
      else
        Frame.EditMaxTokens.Text := '';
      if MaxTokensQuery <> 0 then
        Frame.EditQueryMaxToken.Text := MaxTokensQuery.ToString
      else
        Frame.EditQueryMaxToken.Text := '';
      Frame.ComboEditModel.Text := Model;
      Frame.TrackBarTopP.Value := TopP * 10;
      Frame.SwitchUseFunctions.IsChecked := UseFunctions;
      Frame.SwitchAutoExecFuncs.IsChecked := AutoExecFuncs;
    end,
    procedure(Frame: TFrameChatSettings; Success: Boolean)
    begin
      MemoQuery.SetFocus;
      if not Success then
        Exit;
      Temperature := Frame.TrackBarTemp.Value / 10;
      PresencePenalty := Frame.TrackBarPP.Value / 10;
      FrequencyPenalty := Frame.TrackBarFP.Value / 10;
      MaxTokens := StrToIntDef(Frame.EditMaxTokens.Text, 0);
      MaxTokensQuery := StrToIntDef(Frame.EditQueryMaxToken.Text, 0);
      TopP := Frame.TrackBarTopP.Value / 10;
      Model := Frame.ComboEditModel.Text;
      UseFunctions := Frame.SwitchUseFunctions.IsChecked;
      AutoExecFuncs := Frame.SwitchAutoExecFuncs.IsChecked;
    end);
end;

procedure TFrameChat.ButtonAudioClick(Sender: TObject);
begin
  if FIsTyping then
    Exit;
  {$IFNDEF ANDROID}
  if not OpenDialogAudio.Execute then
    Exit;
  var AudioFile := OpenDialogAudio.FileName;
  //MemoQuery.Text := '';
  NewMessage(TPath.GetFileName(AudioFile), TMessageKind.User, False, True);
  RequestAudio(AudioFile);
  {$ELSE}
  try
    OpenFileDialog('*/*',
      procedure(FilePath: string)
      begin
        //MemoQuery.Text := '';
        NewMessage(TPath.GetFileName(FilePath), TMessageKind.User, False, True);
        RequestAudio(FilePath);
      end);
  except
    on E: Exception do
      ShowError(E.Message);
  end;
  {$ENDIF}
end;

procedure TFrameChat.ButtonContinueClick(Sender: TObject);
begin
  RequestPrompt;
end;

procedure TFrameChat.RequestAudio(const AudioFile: string);
begin
  SetTyping(True);
  ScrollDown;
  LastRequest := nil;
  TTask.Run(
    procedure
    begin
      try
        var Audio := API.Audio.CreateTranscription(
          procedure(Params: TAudioTranscription)
          begin
            Params.&File(AudioFile);
            Params.Temperature(Temperature / 2);
            Params.Language('ru');
          end);
        TThread.Queue(nil,
          procedure
          begin
            AppendAudio(Audio);
          end);
      except
        on E: OpenAIException do
        begin
          ShowError(E.Message);
          LastRequest :=
            procedure
            begin
              RequestAudio(AudioFile);
            end;
        end;
        on E: Exception do
        begin
          ShowError(E.Message);
          LastRequest :=
            procedure
            begin
              RequestAudio(AudioFile);
            end;
        end;
      end;
      TThread.Queue(nil,
        procedure
        begin
          SetTyping(False);
        end);
    end, FPool);
end;

procedure TFrameChat.ButtonExample1Click(Sender: TObject);
begin
  if MemoQuery.Text.IsEmpty then
    MemoQuery.Text := 'Explain quantum computing in simple terms';
end;

procedure TFrameChat.ButtonExample1Tap(Sender: TObject; const Point: TPointF);
begin
  ButtonExample1Click(Sender);
end;

procedure TFrameChat.ButtonExample2Click(Sender: TObject);
begin
  if MemoQuery.Text.IsEmpty then
    MemoQuery.Text := 'Got any creative ideas for a 10 year old’s birthday?';
end;

procedure TFrameChat.ButtonExample2Tap(Sender: TObject; const Point: TPointF);
begin
  ButtonExample2Click(Sender);
end;

procedure TFrameChat.ButtonExample3Click(Sender: TObject);
begin
  if MemoQuery.Text.IsEmpty then
    MemoQuery.Text := 'How do I make an HTTP request in Javascript?';
end;

procedure TFrameChat.ButtonExample3Tap(Sender: TObject; const Point: TPointF);
begin
  ButtonExample3Click(Sender);
end;

procedure TFrameChat.ButtonExportImportClick(Sender: TObject);
begin
  TFrameImportExport.Execute(Self,
    procedure(Frame: TFrameImportExport)
    begin
      Frame.Mode := FMode;
    end,
    procedure(Frame: TFrameImportExport; Success: Boolean)
    begin
      MemoQuery.SetFocus;
      if not Success then
        Exit;
      if Frame.RadioButtonExport.IsChecked then
      begin
        if Frame.EditExport.Text.EndsWith('.json') then
        begin
          var JSON := SaveAsJson;
          if Assigned(JSON) then
          try
            TFile.WriteAllText(Frame.EditExport.Text, JSON.ToJSON, TEncoding.UTF8);
          finally
            JSON.Free;
          end;
        end
        else
        begin
          var Stream := TFile.Create(Frame.EditExport.Text);
          try
            for var Control in VertScrollBoxChat.Content.Controls do
              if Control is TFrameMessage then
                if not TFrameMessage(Control).IsError then
                begin
                  var Buff := TEncoding.UTF8.GetBytes(TFrameMessage(Control).MessageRole.ToString + #13#10 + TFrameMessage(Control).Text + #13#10 + #13#10 + #13#10);
                  Stream.WriteBuffer(Buff, Length(Buff));
                end;
          finally
            Stream.Free;
          end;
        end;
      end
      else
      begin
        var JSON := TJSONObject.ParseJSONValue(TFile.ReadAllText(Frame.EditImport.Text, TEncoding.UTF8));
        if Assigned(JSON) then
        try
          LoadFromJson(JSON as TJSONObject);
        finally
          JSON.Free;
        end;
      end;
    end);
end;

procedure TFrameChat.ButtonImageClick(Sender: TObject);
begin
  IsImageMode := not IsImageMode;
end;

procedure TFrameChat.ButtonRetryClick(Sender: TObject);
begin
  if Assigned(FLastRequest) then
    FLastRequest;
end;

procedure TFrameChat.SendRequestImage;
begin
  if FIsTyping then
    Exit;
  var Prompt := MemoQuery.Text;
  if Prompt.IsEmpty then
    Exit;
  MemoQuery.Text := '';
  NewMessage(Prompt, TMessageKind.User, False);
  RequestImage(Prompt);
end;

procedure TFrameChat.RequestImage(const Prompt: string);
begin
  SetTyping(True);
  ScrollDown;
  LastRequest := nil;
  TTask.Run(
    procedure
    begin
      try
        var Images := API.Image.Create(
          procedure(Params: TImageCreateParams)
          begin
            Params.Prompt(Prompt);
            Params.ResponseFormat(TImageResponseFormat.Url);
            Params.Quality(TImageQuality.Standard);
            //Params.N(4);
            Params.Model('dall-e-3');
            Params.Size(TImageSize.s1024x1024);
            Params.User(FChatId);
          end);
        TThread.Queue(nil,
          procedure
          begin
            AppendMessages(Images);
          end);
      except
        on E: Exception do
        begin
          ShowError(E.Message);
          LastRequest :=
            procedure
            begin
              RequestImage(Prompt);
            end;
        end;
      end;
      TThread.Queue(nil,
        procedure
        begin
          SetTyping(False);
        end);
    end, FPool);
end;

procedure TFrameChat.SendRequestPrompt;
begin
  if FIsTyping then
    Exit;
  var Prompt := MemoQuery.Text.Trim([' ', #13, #10]);
  if Prompt.IsEmpty then
    Exit;
  MemoQuery.Text := '';
  NewMessage(Prompt, TMessageKind.User);
  if (not Prompt.StartsWith('/system ')) and (not Prompt.StartsWith('/assistant ')) and (not Prompt.StartsWith('/user ')) then
    RequestPrompt;
end;

function TFrameChat.GetFuncs: TArray<IChatFunction>;
begin
  if Assigned(FOnNeedFuncList) and FUseFunctions then
    FOnNeedFuncList(Self, Result)
  else
    Result := [];
end;

function CreateTools(Funcs: TArray<IChatFunction>): TArray<TChatToolParam>;
begin
  for var Item in Funcs do
    Result := Result + [TChatToolFunctionParam.Create(Item)];
end;

procedure TFrameChat.RequestFunc(FuncResult: string);
begin
  SetTyping(True);
  ScrollDown;
  LastRequest := nil;
  TTask.Run(
    procedure
    begin
      try
        var Funcs := GetFuncs;
        var Completions := API.Chat.Create(
          procedure(Params: TChatParams)
          begin
            if not Model.IsEmpty then
              Params.Model(Model);
            if PresencePenalty <> 0 then
              Params.PresencePenalty(PresencePenalty);
            if FrequencyPenalty <> 0 then
              Params.FrequencyPenalty(FrequencyPenalty);
            Params.Messages(FBuffer.ToArray);
            if FBuffer.MaxTokensForQuery <> 0 then
              Params.MaxTokens(FBuffer.MaxTokensForQuery);
            Params.Temperature(Temperature);
            if Length(Funcs) > 0 then
            begin
              Params.Tools(CreateTools(Funcs));
              Params.ToolChoice(TChatToolChoiceParam.Auto);
            end;
            Params.User(FChatId);
          end);
        TThread.Queue(nil,
          procedure
          begin
            AppendMessages(Completions);
          end);
      except
        on E: OpenAIException do
        begin
          ShowError(E.Message);
          LastRequest :=
            procedure
            begin
              RequestFunc(FuncResult);
            end;
        end;
        on E: Exception do
        begin
          ShowError(E.Message);
          LastRequest :=
            procedure
            begin
              RequestFunc(FuncResult);
            end;
        end;
      end;
      TThread.Queue(nil,
        procedure
        begin
          SetTyping(False);
        end);
    end, FPool);
end;

procedure TFrameChat.RequestPrompt;
begin
  SetTyping(True);
  ScrollDown;
  LastRequest := nil;
  TTask.Run(
    procedure
    begin
      try
        var Funcs := GetFuncs;
        var Completions := API.Chat.Create(
          procedure(Params: TChatParams)
          begin
            if not Model.IsEmpty then
              Params.Model(Model);
            if PresencePenalty <> 0 then
              Params.PresencePenalty(PresencePenalty);
            if FrequencyPenalty <> 0 then
              Params.FrequencyPenalty(FrequencyPenalty);
            Params.Messages(FBuffer.ToArray);
            if FBuffer.MaxTokensForQuery <> 0 then
              Params.MaxTokens(FBuffer.MaxTokensForQuery);
            if Temperature <> 1 then
              Params.Temperature(Temperature);
            if Length(Funcs) > 0 then
            begin
              Params.Tools(CreateTools(Funcs));
              Params.ToolChoice(TChatToolChoiceParam.Auto);
            end;
            Params.User(FChatId);
          end);
        TThread.Queue(nil,
          procedure
          begin
            AppendMessages(Completions);
          end);
      except
        on E: OpenAIException do
        begin
          ShowError(E.Message);
          LastRequest := RequestPrompt;
        end;
        on E: Exception do
        begin
          if E is ENetHTTPClientException then
            E.Message := E.Message + #13#10 + ErrorHintTimeout;
          ShowError(E.Message);

          LastRequest := RequestPrompt;
        end;
      end;
      TThread.Queue(nil,
        procedure
        begin
          SetTyping(False);
        end);
    end, FPool);
end;

procedure TFrameChat.ButtonScrollDownClick(Sender: TObject);
begin
  ScrollDown(True);
end;

procedure TFrameChat.StopRecording;
begin
  LayoutAudioRecording.Visible := False;
  MemoQuery.Visible := True;
  PathStopRecord.Visible := False;
  PathAudio.Visible := True;
  TimerCheckRecording.Enabled := False;
end;

procedure TFrameChat.StartRecording;
begin
  FAudioRecord.StartRecord(GenerateAudioFileName);
end;

procedure TFrameChat.ButtonSendClick(Sender: TObject);
begin
  if FAudioRecord.IsAvailableDevice then
  begin
    if FAudioRecord.IsMicrophoneRecording then
    begin
      FAudioRecord.StopRecord;
      Exit;
    end;
  end;
  if MemoQuery.Text.IsEmpty and FAudioRecord.IsAvailableDevice then
    StartRecording
  else
    SendText;
end;

procedure TFrameChat.SendText;
begin
  if IsImageMode then
    SendRequestImage
  else
    SendRequestPrompt;
end;

procedure TFrameChat.ClearChat;
begin
  LayoutTyping.Parent := nil;
  LayoutWelcome.Parent := nil;
  while VertScrollBoxChat.Content.ControlsCount > 0 do
    VertScrollBoxChat.Content.Controls[0].Free;
  LayoutTyping.Parent := VertScrollBoxChat;
  LayoutWelcome.Parent := VertScrollBoxChat;
  DoOnUpdateChatItems;
end;

procedure TFrameChat.FOnStartRecord(Sender: TObject);
begin
  FRecordingStartTime := Now;
  TimerCheckRecording.Enabled := True;
  LabelRecordingTime.Text := '';
  LayoutAudioRecording.Visible := True;
  MemoQuery.Visible := False;
  PathStopRecord.Visible := True;
  PathAudio.Visible := False;
end;

constructor TFrameChat.Create(AOwner: TComponent);
begin
  inherited;
  FIsFirstMessage := True;
  LastRequest := nil;
  FAudioRecord := TAudioRecord.Create(Self);
  FAudioRecord.OnStartRecord := FOnStartRecord;
  FBuffer := TChatHistory.Create;
  FBuffer.MaxTokensForQuery := MAX_TOKENS;
  FBuffer.MaxTokensOfModel := MODEL_TOKENS_LIMIT;
  FBuffer.AutoTrim := True;
  FPool := TThreadPool.Create;
  Temperature := 0.2;
  Name := '';
  VertScrollBoxChat.AniCalculations.Animation := True;
  //VertScrollBoxChat.AniCalculations.Interval := 1;
  VertScrollBoxChat.AniCalculations.Averaging := True;
  {$IFDEF MOBILE}
  VertScrollBoxChat.AniCalculations.BoundsAnimation := True;
  {$ENDIF}

  MemoQuery.ScrollAnimation := TBehaviorBoolean.True;
  PathStopRecord.Visible := False;
  PathAudio.Visible := False;
  PathSend.Visible := True;
  LayoutAudioRecording.Visible := False;

  {$IFDEF MOBILE}
  ButtonExample1.OnClick := nil;
  ButtonExample2.OnClick := nil;
  ButtonExample3.OnClick := nil;
  //(MemoQuery.Presentation as TStyledMemo).NeedSelectorPoints := True;
  ButtonExportImport.Visible := False;
  {$ENDIF}

  SetTyping(False);
  ClearChat;
  IsImageMode := False;
  MemoQueryChange(nil);
  MemoQuery.ApplyStyleLookup;
end;

destructor TFrameChat.Destroy;
begin
  FMenuItem := nil;
  FPool.Free;
  FBuffer.Free;
  inherited;
end;

procedure TFrameChat.DoOnUpdateChatItems;
begin
  ButtonContinue.Visible := FBuffer.Count > 0;
end;

procedure TFrameChat.FlowLayoutWelcomeResize(Sender: TObject);
begin
  var W: Single := 0;
  case Mode of
    TWindowMode.Compact:
      W := FlowLayoutWelcome.Width;
    TWindowMode.Full:
      W := Trunc(FlowLayoutWelcome.Width / FlowLayoutWelcome.ControlsCount);
  end;
  for var Control in FlowLayoutWelcome.Controls do
    Control.Width := W;

  var B: Single := 0;
  for var Control in LayoutExampleTitle.Controls do
    B := Max(B, Control.Position.Y + Control.Height + Control.Margins.Bottom);
  if LayoutExampleTitle.Height <> B then
    LayoutExampleTitle.Height := B;

  B := 0;
  for var Control in LayoutCapabilitiesTitle.Controls do
    B := Max(B, Control.Position.Y + Control.Height + Control.Margins.Bottom);
  if LayoutCapabilitiesTitle.Height <> B then
    LayoutCapabilitiesTitle.Height := B;

  B := 0;
  for var Control in LayoutLimitationsTitle.Controls do
    B := Max(B, Control.Position.Y + Control.Height + Control.Margins.Bottom);
  if LayoutLimitationsTitle.Height <> B then
    LayoutLimitationsTitle.Height := B;

  B := 0;
  for var Control in FlowLayoutWelcome.Controls do
    B := Max(B, Control.Position.Y + Control.Height);

  B := B + FlowLayoutWelcome.Position.Y;
  if LayoutWelcome.Height <> B then
    LayoutWelcome.Height := B;
end;

procedure TFrameChat.LayoutSendResize(Sender: TObject);
begin
  LayoutQuery.Width := Min(768, LayoutSend.Width - 48);
  VertScrollBoxChat.Padding.Bottom := LayoutSend.Height + LayoutButtom.Height + 20;
end;

procedure TFrameChat.LayoutTypingResize(Sender: TObject);
begin
  LayoutTypingContent.Width := Min(LayoutTyping.Width - (LayoutTyping.Padding.Left + LayoutTyping.Padding.Right), MaxMessageWidth);
end;

procedure TFrameChat.LayoutWelcomeResize(Sender: TObject);
begin
  FlowLayoutWelcome.Width := Min(720, LayoutWelcome.Width);
end;

procedure TFrameChat.MemoQueryChange(Sender: TObject);
begin
  LabelSendTip.Visible := MemoQuery.Text.IsEmpty;
  var H: Single := 0;
  if not LabelSendTip.Visible then
    H := H + Round(MemoQuery.ContentBounds.Height)
  else
    H := H + 21;
  //LayoutAudioRecording
  //LayoutSend.Height := Max(LayoutSend.TagFloat, Min(H, 400));

  var MaxMemoH := Min(H, 400 - (LayoutSend.Padding.Top + LayoutSend.Padding.Bottom + LayoutQuery.Padding.Top + LayoutQuery.Padding.Bottom));
  MemoQuery.Height := Max(26, MaxMemoH);
  H := H + LayoutSend.Padding.Top + LayoutSend.Padding.Bottom + LayoutQuery.Padding.Top + LayoutQuery.Padding.Bottom;
  TAnimator.DetachPropertyAnimation(LayoutSend, 'Height');
  if LayoutAttachments.Visible then
    H := H + LayoutAttachments.Height;
  TAnimator.AnimateFloat(LayoutSend, 'Height', Max(LayoutSend.TagFloat, Min(H, 400)), 0.1);
  MemoQuery.ShowScrollBars := H > 400;

  {$IFDEF MOBILE}
  if LabelSendTip.Visible then
  begin
    LayoutChatSettings.Visible := True;
    RectangleMemoBG.Margins.Left := 15;
  end
  else
  begin
    LayoutChatSettings.Visible := False;
    RectangleMemoBG.Margins.Left := -11;
  end;
  {$ENDIF}
  UpdateSendControls;
end;

procedure TFrameChat.MemoQueryEnter(Sender: TObject);
begin
  MemoQuery.PrepareForPaint;
end;

procedure TFrameChat.UpdateSendControls;
begin
  PathAudio.Visible := FAudioRecord.IsAvailableDevice and LabelSendTip.Visible;
  PathSend.Visible := not PathAudio.Visible;
  ButtonAudio.Visible := MemoQuery.Text.IsEmpty;
  ButtonAudio.Position.X := 0;
  var i := 0;
  for var Control in LayoutSendCommons.Controls do
    if Control.IsVisible then
      Inc(i);
  LayoutSendControls.Width := LayoutSendCommons.Height * i;
  LayoutSendCommons.RecalcSize;
end;

procedure TFrameChat.MemoQueryKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
begin
  if Manager.SendByEnter then
  begin
    if (Key = vkReturn) and not ((ssCtrl in Shift) or (ssShift in Shift)) then
    begin
      Key := 0;
      KeyChar := #0;
      SendText;
    end;
  end
  else
  begin
    if (Key = vkReturn) and (ssCtrl in Shift) then
    begin
      Key := 0;
      KeyChar := #0;
      SendText;
    end;
  end;
  MemoQueryChange(Sender);
end;

procedure TFrameChat.MemoQueryKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
begin
  MemoQueryChange(Sender);
end;

procedure TFrameChat.MemoQueryViewportPositionChange(Sender: TObject; const OldViewportPosition, NewViewportPosition: TPointF; const ContentSizeChanged: Boolean);
begin
  MemoQueryChange(Sender);
end;

procedure TFrameChat.VertScrollBoxChatViewportPositionChange(Sender: TObject; const OldViewportPosition, NewViewportPosition: TPointF; const ContentSizeChanged: Boolean);
begin
  VertScrollBoxChat.FViewPositionY := NewViewportPosition.Y;
  LayoutScrollDown.Visible := NewViewportPosition.Y < VertScrollBoxChat.ContentBounds.Height - Ver
Download .txt
gitextract_yo52volr/

├── .gitattributes
├── .github/
│   └── FUNDING.yml
├── .gitignore
├── .gitmodules
├── AndroidManifest.template.xml
├── ChatGPT.About.fmx
├── ChatGPT.About.pas
├── ChatGPT.Android.pas
├── ChatGPT.ChatSettings.fmx
├── ChatGPT.ChatSettings.pas
├── ChatGPT.Classes.pas
├── ChatGPT.Code.pas
├── ChatGPT.FrameChat.fmx
├── ChatGPT.FrameChat.pas
├── ChatGPT.FrameCode.fmx
├── ChatGPT.FrameCode.pas
├── ChatGPT.FrameImage.fmx
├── ChatGPT.FrameImage.pas
├── ChatGPT.FrameImagePreview.fmx
├── ChatGPT.FrameImagePreview.pas
├── ChatGPT.FrameMessage.fmx
├── ChatGPT.FrameMessage.pas
├── ChatGPT.FramePlainText.fmx
├── ChatGPT.FramePlainText.pas
├── ChatGPT.FrameSVG.fmx
├── ChatGPT.FrameSVG.pas
├── ChatGPT.FrameUIMessage.fmx
├── ChatGPT.FrameUIMessage.pas
├── ChatGPT.Functions.External.Intf.pas
├── ChatGPT.Functions.External.pas
├── ChatGPT.Functions.pas
├── ChatGPT.ImportExport.fmx
├── ChatGPT.ImportExport.pas
├── ChatGPT.LoadedFunctions.fmx
├── ChatGPT.LoadedFunctions.pas
├── ChatGPT.Main.fmx
├── ChatGPT.Main.pas
├── ChatGPT.Manager.dfm
├── ChatGPT.Manager.pas
├── ChatGPT.Overlay.fmx
├── ChatGPT.Overlay.pas
├── ChatGPT.Settings.fmx
├── ChatGPT.Settings.pas
├── ChatGPT.SoundRecorder.pas
├── ChatGPT.TextEditor.fmx
├── ChatGPT.TextEditor.pas
├── ChatGPT.deployproj
├── ChatGPT.dpr
├── ChatGPT.dproj
├── ChatGPT.res
├── ChatGPTGroup.groupproj
├── ChatGPT_Console.dpr
├── ChatGPT_Console.dproj
├── ChatGPT_Console.res
├── Code/
│   ├── ChatGPT.Code.JSON.pas
│   ├── ChatGPT.Code.MarkDown.pas
│   ├── ChatGPT.Code.Pascal.pas
│   ├── ChatGPT.Code.Python.pas
│   └── ChatGPT.Code.SQL.pas
├── FMX.Media.Win.pas
├── FunctionsLib/
│   ├── func_cmd.pas
│   ├── func_weather.pas
│   ├── gpt_function_cmd.dpr
│   ├── gpt_function_cmd.dproj
│   ├── gpt_function_cmd.res
│   ├── gpt_function_owm.deployproj
│   ├── gpt_function_owm.dpr
│   ├── gpt_function_owm.dproj
│   └── gpt_function_owm.res
├── HGM.FMX.Ani.pas
├── HGM.FMX.Image.pas
├── LICENSE
├── LaunchScreen.TemplateiOS/
│   ├── Assets/
│   │   ├── AppIcon.appiconset/
│   │   │   └── Contents.json
│   │   ├── Contents.json
│   │   ├── LaunchScreenBackgroundColor.colorset/
│   │   │   └── Contents.json
│   │   └── LaunchScreenImage.imageset/
│   │       └── Contents.json
│   └── LaunchScreen.storyboard
├── README.md
└── Res/
    ├── chatgptfmx/
    │   └── res/
    │       └── mipmap-anydpi-v26/
    │           └── chatgptfmx.xml
    └── preview.psd
Condensed preview — 80 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,325K chars).
[
  {
    "path": ".gitattributes",
    "chars": 66,
    "preview": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 88,
    "preview": "# These are supported funding model platforms\n\ngithub: hemulgm\nopen_collective: hemulgm\n"
  },
  {
    "path": ".gitignore",
    "chars": 1914,
    "preview": "# Uncomment these types if you want even more clean repository. But be careful.\n# It can make harm to an existing projec"
  },
  {
    "path": ".gitmodules",
    "chars": 469,
    "preview": "[submodule \"DelphiOpenAI\"]\n\tpath = DelphiOpenAI\n\turl = https://github.com/HemulGM/DelphiOpenAI\n[submodule \"WindowDarkMod"
  },
  {
    "path": "AndroidManifest.template.xml",
    "chars": 1997,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- BEGIN_INCLUDE(manifest) -->\n<manifest xmlns:android=\"http://schemas.android."
  },
  {
    "path": "ChatGPT.About.fmx",
    "chars": 10928,
    "preview": "inherited FrameAbout: TFrameAbout\n  Size.Width = 944.000000000000000000\n  Size.Height = 703.000000000000000000\n  OnResiz"
  },
  {
    "path": "ChatGPT.About.pas",
    "chars": 3831,
    "preview": "unit ChatGPT.About;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,\n"
  },
  {
    "path": "ChatGPT.Android.pas",
    "chars": 2784,
    "preview": "unit ChatGPT.Android;\n\n{$IFDEF ANDROID}\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.IOUtils,\n  System.Mess"
  },
  {
    "path": "ChatGPT.ChatSettings.fmx",
    "chars": 27362,
    "preview": "inherited FrameChatSettings: TFrameChatSettings\n  Size.Width = 729.000000000000000000\n  Size.Height = 719.00000000000000"
  },
  {
    "path": "ChatGPT.ChatSettings.pas",
    "chars": 5497,
    "preview": "unit ChatGPT.ChatSettings;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Var"
  },
  {
    "path": "ChatGPT.Classes.pas",
    "chars": 2682,
    "preview": "unit ChatGPT.Classes;\n\ninterface\n\nuses\n  System.SysUtils, OpenAI.Chat.Functions;\n\n{$SCOPEDENUMS ON}\n\ntype\n  TWindowMode"
  },
  {
    "path": "ChatGPT.Code.pas",
    "chars": 3553,
    "preview": "unit ChatGPT.Code;\n\ninterface\n\nuses\n  System.SysUtils, FMX.Graphics, System.UITypes, System.Generics.Collections,\n  FMX"
  },
  {
    "path": "ChatGPT.FrameChat.fmx",
    "chars": 95301,
    "preview": "object FrameChat: TFrameChat\n  Align = Contents\n  Size.Width = 1006.000000000000000000\n  Size.Height = 786.0000000000000"
  },
  {
    "path": "ChatGPT.FrameChat.pas",
    "chars": 50668,
    "preview": "unit ChatGPT.FrameChat;\n\ninterface\n\n{$IF DEFINED(ANDROID) OR DEFINED(IOS) OR DEFINED(IOS64)}\n  {$DEFINE MOBILE}\n{$ENDIF"
  },
  {
    "path": "ChatGPT.FrameCode.fmx",
    "chars": 6350,
    "preview": "object FrameCode: TFrameCode\n  ClipChildren = True\n  HitTest = False\n  Margins.Bottom = 5.000000000000000000\n  Size.Widt"
  },
  {
    "path": "ChatGPT.FrameCode.pas",
    "chars": 6149,
    "preview": "unit ChatGPT.FrameCode;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Varian"
  },
  {
    "path": "ChatGPT.FrameImage.fmx",
    "chars": 1780,
    "preview": "object FrameImage: TFrameImage\n  Size.Width = 256.000000000000000000\n  Size.Height = 256.000000000000000000\n  Size.Platf"
  },
  {
    "path": "ChatGPT.FrameImage.pas",
    "chars": 2730,
    "preview": "unit ChatGPT.FrameImage;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Varia"
  },
  {
    "path": "ChatGPT.FrameImagePreview.fmx",
    "chars": 3454,
    "preview": "object FramePreview: TFramePreview\n  Padding.Left = 20.000000000000000000\n  Padding.Top = 20.000000000000000000\n  Paddin"
  },
  {
    "path": "ChatGPT.FrameImagePreview.pas",
    "chars": 3825,
    "preview": "unit ChatGPT.FrameImagePreview;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, Syste"
  },
  {
    "path": "ChatGPT.FrameMessage.fmx",
    "chars": 52800,
    "preview": "object FrameMessage: TFrameMessage\n  Size.Width = 735.000000000000000000\n  Size.Height = 521.000000000000000000\n  Size.P"
  },
  {
    "path": "ChatGPT.FrameMessage.pas",
    "chars": 18258,
    "preview": "unit ChatGPT.FrameMessage;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Var"
  },
  {
    "path": "ChatGPT.FramePlainText.fmx",
    "chars": 1213,
    "preview": "object FrameText: TFrameText\n  Size.Width = 575.000000000000000000\n  Size.Height = 387.000000000000000000\n  Size.Platfor"
  },
  {
    "path": "ChatGPT.FramePlainText.pas",
    "chars": 3235,
    "preview": "unit ChatGPT.FramePlainText;\n\ninterface\n\n{$IF DEFINED(ANDROID) OR DEFINED(IOS) OR DEFINED(IOS64)}\n  {$DEFINE MOBILE}\n{$"
  },
  {
    "path": "ChatGPT.FrameSVG.fmx",
    "chars": 302,
    "preview": "object FrameSVG: TFrameSVG\n  Size.Width = 654.000000000000000000\n  Size.Height = 150.000000000000000000\n  Size.PlatformD"
  },
  {
    "path": "ChatGPT.FrameSVG.pas",
    "chars": 617,
    "preview": "unit ChatGPT.FrameSVG;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variant"
  },
  {
    "path": "ChatGPT.FrameUIMessage.fmx",
    "chars": 1384,
    "preview": "object FrameUIMessage: TFrameUIMessage\n  Align = Contents\n  HitTest = False\n  Size.Width = 754.000000000000000000\n  Size"
  },
  {
    "path": "ChatGPT.FrameUIMessage.pas",
    "chars": 1222,
    "preview": "unit ChatGPT.FrameUIMessage;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System.V"
  },
  {
    "path": "ChatGPT.Functions.External.Intf.pas",
    "chars": 556,
    "preview": "unit ChatGPT.Functions.external.Intf;\n\ninterface\n\ntype\n  IChatFunctionExternal = interface\n    ['{B2DACD74-B773-44C2-83"
  },
  {
    "path": "ChatGPT.Functions.External.pas",
    "chars": 1244,
    "preview": "unit ChatGPT.Functions.external;\n\ninterface\n\nuses\n  System.Classes, OpenAI.Chat.Functions, ChatGPT.Functions.external.I"
  },
  {
    "path": "ChatGPT.Functions.pas",
    "chars": 1592,
    "preview": "unit ChatGPT.Functions;\n\ninterface\n\nuses\n  {$IFDEF MSWINDOWS}\n  Winapi.Windows,\n  {$ENDIF}\n  System.SysUtils, System.Ge"
  },
  {
    "path": "ChatGPT.ImportExport.fmx",
    "chars": 18319,
    "preview": "inherited FrameImportExport: TFrameImportExport\n  Size.Width = 772.000000000000000000\n  Size.Height = 703.00000000000000"
  },
  {
    "path": "ChatGPT.ImportExport.pas",
    "chars": 4385,
    "preview": "unit ChatGPT.ImportExport;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Var"
  },
  {
    "path": "ChatGPT.LoadedFunctions.fmx",
    "chars": 4716,
    "preview": "inherited FrameLoadedFunctions: TFrameLoadedFunctions\n  Size.Width = 1035.000000000000000000\n  Size.Height = 811.0000000"
  },
  {
    "path": "ChatGPT.LoadedFunctions.pas",
    "chars": 2176,
    "preview": "unit ChatGPT.LoadedFunctions;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System."
  },
  {
    "path": "ChatGPT.Main.fmx",
    "chars": 233251,
    "preview": "object FormMain: TFormMain\n  Left = 0\n  Top = 0\n  Caption = 'ChatGPT'\n  ClientHeight = 686\n  ClientWidth = 1053\n  Fill.C"
  },
  {
    "path": "ChatGPT.Main.pas",
    "chars": 35082,
    "preview": "unit ChatGPT.Main;\n\ninterface\n\n{$IF DEFINED(ANDROID) OR DEFINED(IOS) OR DEFINED(IOS64)}\n  {$DEFINE MOBILE}\n{$ENDIF}\n\nus"
  },
  {
    "path": "ChatGPT.Manager.dfm",
    "chars": 20496,
    "preview": "object Manager: TManager\n  Height = 480\n  Width = 640\n  object SVGIconImageList: TSVGIconImageList\n    Source = <\n      "
  },
  {
    "path": "ChatGPT.Manager.pas",
    "chars": 5459,
    "preview": "unit ChatGPT.Manager;\n\ninterface\n\nuses\n  System.SysUtils, System.Classes, System.Actions, FMX.Controls, FMX.ActnList,\n "
  },
  {
    "path": "ChatGPT.Overlay.fmx",
    "chars": 389,
    "preview": "object FrameOveraly: TFrameOveraly\n  Size.Width = 689.000000000000000000\n  Size.Height = 469.000000000000000000\n  Size.P"
  },
  {
    "path": "ChatGPT.Overlay.pas",
    "chars": 1118,
    "preview": "unit ChatGPT.Overlay;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants"
  },
  {
    "path": "ChatGPT.Settings.fmx",
    "chars": 60940,
    "preview": "inherited FrameSettings: TFrameSettings\n  Size.Width = 906.000000000000000000\n  Size.Height = 804.000000000000000000\n  O"
  },
  {
    "path": "ChatGPT.Settings.pas",
    "chars": 9842,
    "preview": "unit ChatGPT.Settings;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variant"
  },
  {
    "path": "ChatGPT.SoundRecorder.pas",
    "chars": 2450,
    "preview": "unit ChatGPT.SoundRecorder;\n\ninterface\n\nuses\n  System.Classes, System.SysUtils, FMX.Media;\n\ntype\n  TAudioRecord = class"
  },
  {
    "path": "ChatGPT.TextEditor.fmx",
    "chars": 3732,
    "preview": "inherited FrameTextEditor: TFrameTextEditor\n  Size.Width = 1035.000000000000000000\n  Size.Height = 811.00000000000000000"
  },
  {
    "path": "ChatGPT.TextEditor.pas",
    "chars": 2578,
    "preview": "unit ChatGPT.TextEditor;\n\ninterface\n\nuses\n  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Varia"
  },
  {
    "path": "ChatGPT.deployproj",
    "chars": 93409,
    "preview": "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n    <Import Condition=\"Exists('$(BDS)\\bin\\CodeGea"
  },
  {
    "path": "ChatGPT.dpr",
    "chars": 4418,
    "preview": "program ChatGPT;\n\n{$IF DEFINED(ANDROID) OR DEFINED(IOS) OR DEFINED(IOS64)}\n  {$DEFINE MOBILE}\n{$ENDIF}\n\nuses\n  System.S"
  },
  {
    "path": "ChatGPT.dproj",
    "chars": 130857,
    "preview": "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n    <PropertyGroup>\n        <ProjectGuid>{C8E3829"
  },
  {
    "path": "ChatGPTGroup.groupproj",
    "chars": 2361,
    "preview": "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n    <PropertyGroup>\n        <ProjectGuid>{8E18A81"
  },
  {
    "path": "ChatGPT_Console.dpr",
    "chars": 1762,
    "preview": "program ChatGPT_Console;\n\n{$APPTYPE CONSOLE}\n\n{$R *.res}\n\nuses\n  System.SysUtils,\n  System.Classes,\n  OpenAI.Chat,\n  Op"
  },
  {
    "path": "ChatGPT_Console.dproj",
    "chars": 79408,
    "preview": "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n    <PropertyGroup>\n        <ProjectGuid>{48B49E9"
  },
  {
    "path": "Code/ChatGPT.Code.JSON.pas",
    "chars": 3053,
    "preview": "unit ChatGPT.Code.JSON;\n\ninterface\n\nuses\n  System.SysUtils, ChatGPT.Code, System.Generics.Collections, FMX.TextLayout,\n"
  },
  {
    "path": "Code/ChatGPT.Code.MarkDown.pas",
    "chars": 4287,
    "preview": "unit ChatGPT.Code.MarkDown;\n\ninterface\n\nuses\n  System.SysUtils, ChatGPT.Code, System.Generics.Collections, FMX.TextLayo"
  },
  {
    "path": "Code/ChatGPT.Code.Pascal.pas",
    "chars": 6667,
    "preview": "unit ChatGPT.Code.pascal;\n\ninterface\n\nuses\n  System.SysUtils, ChatGPT.Code, System.Generics.Collections, FMX.TextLayout"
  },
  {
    "path": "Code/ChatGPT.Code.Python.pas",
    "chars": 5783,
    "preview": "unit ChatGPT.Code.Python;\n\ninterface\n\nuses\n  System.SysUtils, ChatGPT.Code, System.Generics.Collections, FMX.TextLayout"
  },
  {
    "path": "Code/ChatGPT.Code.SQL.pas",
    "chars": 7766,
    "preview": "unit ChatGPT.Code.SQL;\n\ninterface\n\nuses\n  System.SysUtils, ChatGPT.Code, System.Generics.Collections, FMX.TextLayout,\n "
  },
  {
    "path": "FMX.Media.Win.pas",
    "chars": 41003,
    "preview": "{*******************************************************}\n{                                                       }\n{   "
  },
  {
    "path": "FunctionsLib/func_cmd.pas",
    "chars": 1882,
    "preview": "unit func_cmd;\n\ninterface\n\nuses\n  System.SysUtils, System.JSON, ChatGPT.Functions.External.Intf, Process;\n\ntype\n  TChat"
  },
  {
    "path": "FunctionsLib/func_weather.pas",
    "chars": 2607,
    "preview": "unit func_weather;\n\ninterface\n\nuses\n  System.SysUtils, System.JSON, ChatGPT.Functions.External.Intf, OWM.API,\n  OWM.Cla"
  },
  {
    "path": "FunctionsLib/gpt_function_cmd.dpr",
    "chars": 392,
    "preview": "library gpt_function_cmd;\n\nuses\n  System.SysUtils,\n  ChatGPT.Functions.External.Intf in '..\\ChatGPT.Functions.External."
  },
  {
    "path": "FunctionsLib/gpt_function_cmd.dproj",
    "chars": 75689,
    "preview": "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n    <PropertyGroup>\n        <ProjectGuid>{5D99C67"
  },
  {
    "path": "FunctionsLib/gpt_function_owm.deployproj",
    "chars": 1918,
    "preview": "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n    <Import Condition=\"Exists('$(BDS)\\bin\\CodeGea"
  },
  {
    "path": "FunctionsLib/gpt_function_owm.dpr",
    "chars": 402,
    "preview": "library gpt_function_owm;\n\nuses\n  System.SysUtils,\n  ChatGPT.Functions.External.Intf in '..\\ChatGPT.Functions.External."
  },
  {
    "path": "FunctionsLib/gpt_function_owm.dproj",
    "chars": 75381,
    "preview": "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n    <PropertyGroup>\n        <ProjectGuid>{457F133"
  },
  {
    "path": "HGM.FMX.Ani.pas",
    "chars": 9280,
    "preview": "unit HGM.FMX.Ani;\n\ninterface\n\nuses\n  FMX.Ani, FMX.Types, System.Classes, System.SysUtils, System.Types;\n\ntype\n  TAniFre"
  },
  {
    "path": "HGM.FMX.Image.pas",
    "chars": 8730,
    "preview": "unit HGM.FMX.Image;\n\ninterface\n\nuses\n  System.Classes, System.Types, System.SysUtils, FMX.Forms, FMX.Graphics,\n  FMX.Ob"
  },
  {
    "path": "LICENSE",
    "chars": 1064,
    "preview": "MIT License\n\nCopyright (c) 2023 HemulGM\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
  },
  {
    "path": "LaunchScreen.TemplateiOS/Assets/AppIcon.appiconset/Contents.json",
    "chars": 110,
    "preview": "{\n  \"images\" : [\n    <%AppIconImages%>\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"RAD Studio\"\n  }\n}\n"
  },
  {
    "path": "LaunchScreen.TemplateiOS/Assets/Contents.json",
    "chars": 68,
    "preview": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"RAD Studio\"\n  }\n}\n"
  },
  {
    "path": "LaunchScreen.TemplateiOS/Assets/LaunchScreenBackgroundColor.colorset/Contents.json",
    "chars": 125,
    "preview": "{\n  \"colors\" : [\n    <%LaunchScreenBackgroundColors%>\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"RAD Studio\"\n "
  },
  {
    "path": "LaunchScreen.TemplateiOS/Assets/LaunchScreenImage.imageset/Contents.json",
    "chars": 115,
    "preview": "{\n  \"images\" : [\n    <%LaunchScreenImages%>\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"RAD Studio\"\n  }\n}\n"
  },
  {
    "path": "LaunchScreen.TemplateiOS/LaunchScreen.storyboard",
    "chars": 2902,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
  },
  {
    "path": "README.md",
    "chars": 2966,
    "preview": "<p align=\"center\">\n  <img width=\"180\" src=\"Res/chatgptfmx/154.png\" alt=\"ChatGPT\">\n  <h1 align=\"center\">ChatGPT</h1>\n  <p"
  },
  {
    "path": "Res/chatgptfmx/res/mipmap-anydpi-v26/chatgptfmx.xml",
    "chars": 266,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <bac"
  }
]

// ... and 5 more files (download for full content)

About this extraction

This page contains the full source code of the HemulGM/ChatGPT GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 80 files (1.2 MB), approximately 378.0k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!