diff --git a/v1.4.3/Exemplo/uPrincipal.dfm b/v1.4.3/Exemplo/uPrincipal.dfm index b5aff10..c358dd6 100644 --- a/v1.4.3/Exemplo/uPrincipal.dfm +++ b/v1.4.3/Exemplo/uPrincipal.dfm @@ -3848,9 +3848,9 @@ object Form1: TForm1 object btnEnviarTxtComBTInline: TButton Left = 146 Top = 159 - Width = 137 + Width = 151 Height = 25 - Caption = 'Send Text w/ Buttons Inline' + Caption = 'Send Text w/ Inline Buttons ' Default = True TabOrder = 19 OnClick = btnEnviarTxtComBTInlineClick @@ -3952,9 +3952,9 @@ object Form1: TForm1 OnClick = EnviarFotoSpoilerClick end object SendTextTopic: TButton - Left = 289 - Top = 159 - Width = 137 + Left = 146 + Top = 190 + Width = 151 Height = 25 Caption = 'Send Text for Topic' Default = True @@ -4135,8 +4135,8 @@ object Form1: TForm1 end object InjectTelegramExceptionManagerUI1: TInjectTelegramExceptionManagerUI OnLog = InjectTelegramExceptionManagerUI1Log - Left = 208 - Top = 326 + Left = 488 + Top = 438 end object cuHttpClientSysNet1: TcuHttpClientSysNet Left = 488 @@ -4155,8 +4155,8 @@ object Form1: TForm1 OnReceiveRawData = InjectTelegramBot1ReceiveRawData OnSendData = InjectTelegramBot1SendData OnDisconect = InjectTelegramBot1Disconect - Left = 48 - Top = 326 + Left = 488 + Top = 382 end object BotManager1: TInjectTelegramBotManager Bot = InjectTelegramBot1 @@ -4181,6 +4181,6 @@ object Form1: TForm1 OnGeneralForumTopicUnhidden = BotManager1GeneralForumTopicUnhidden OnMessageEntityReceiver = BotManager1MessageEntityReceiver Left = 360 - Top = 328 + Top = 400 end end diff --git a/v1.4.4/CrossUrl/Core/CrossUrl.HttpClient.pas b/v1.4.4/CrossUrl/Core/CrossUrl.HttpClient.pas new file mode 100644 index 0000000..1681f24 --- /dev/null +++ b/v1.4.4/CrossUrl/Core/CrossUrl.HttpClient.pas @@ -0,0 +1,94 @@ +unit CrossUrl.HttpClient; + +interface + +uses + System.Classes, + System.SysUtils; + +type + TcuProxy = record + private + FHost: string; + FPort: Integer; + FUserName: string; + FPassword: string; + public + constructor Create(const AHost: string; APort: Integer; const AUserName: + string = ''; const APassword: string = ''); + property Host: string read FHost write FHost; + property Port: Integer read FPort write FPort; + property UserName: string read FUserName write FUserName; + property Password: string read FPassword write FPassword; + end; + + IcuUri = interface + ['{46DF4232-C572-45F8-8CAB-86096F32FA66}'] + function GetScheme: string; + procedure SetScheme(const Value: string); + property Scheme: string read GetScheme write SetScheme; + end; + + IcuMultipartFormData = interface + ['{C1FEF918-67B9-4503-B67F-AD942F16FEB3}'] + function GetStream: TStream; + // + procedure AddField(const AField, AValue: string); + procedure AddFile(const AFieldName, AFilePath: string); + /// + /// Add a form data Stream + /// + /// + /// Field Name + /// + /// + /// Stream + /// + /// + /// file name: "File.ext" + /// + procedure AddStream(const AFieldName: string; Data: TStream; const AFileName: + string = ''); + property Stream: TStream read GetStream; + end; + + IcuHttpResponse = interface + ['{44F74F9B-CCD2-475E-95E0-02DA30AC749D}'] + //private + function GetStatusCode: Integer; + function GetStatusText: string; + function GetContentStream: TStream; + //public + property StatusText: string read GetStatusText; + property StatusCode: Integer read GetStatusCode; + property ContentStream: TStream read GetContentStream; + function ContentAsString(const AnEncoding: TEncoding = nil): string; + end; + + IcuHttpClient = interface + ['{EB3348C4-5651-4BAB-988D-A28794FEB149}'] + function GetProxy: TcuProxy; + procedure SetProxy(const AProxy: TcuProxy); + // + function CreateMultipartFormData: IcuMultipartFormData; + function Get(const AUrl: string): IcuHttpResponse; + function Post(const AURL: string; const ASource: IcuMultipartFormData): + IcuHttpResponse; + property Proxy: TcuProxy read GetProxy write SetProxy; + end; + +implementation + +{ TcuProxy } + +constructor TcuProxy.Create(const AHost: string; APort: Integer; const AUserName, + APassword: string); +begin + FHost := AHost; + FPort := APort; + FUserName := AUserName; + FPassword := APassword; +end; + +end. + diff --git a/v1.4.4/CrossUrl/Core/CrossUrl.dpk b/v1.4.4/CrossUrl/Core/CrossUrl.dpk new file mode 100644 index 0000000..3446363 --- /dev/null +++ b/v1.4.4/CrossUrl/Core/CrossUrl.dpk @@ -0,0 +1,37 @@ +package CrossUrl; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Cross URL'} +{$IMPLICITBUILD ON} + +requires + rtl; + +contains + CrossUrl.HttpClient in 'CrossUrl.HttpClient.pas'; + +end. diff --git a/v1.4.4/CrossUrl/Core/CrossUrl.dproj b/v1.4.4/CrossUrl/Core/CrossUrl.dproj new file mode 100644 index 0000000..e13092d --- /dev/null +++ b/v1.4.4/CrossUrl/Core/CrossUrl.dproj @@ -0,0 +1,1027 @@ + + + {984584BD-F5BF-4226-86FA-F276A3B81854} + CrossUrl.dpk + 19.4 + None + True + Release + Win32 + 1 + Package + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + true + true + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + All + CrossUrl + + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar + + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar + + + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers + iPhoneAndiPad + true + Debug + $(MSBuildProjectName) + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers + Debug + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers + Debug + true + Base + true + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + rtl;$(DCC_UsePackage) + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + Package + + + + CrossUrl.dpk + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + CrossUrl.bpl + true + + + + + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + classes + 1 + + + classes + 1 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + + 1 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + + False + False + False + False + False + False + True + False + + + 12 + + + + + diff --git a/v1.4.4/CrossUrl/Core/CrossUrl.res b/v1.4.4/CrossUrl/Core/CrossUrl.res new file mode 100644 index 0000000..705d434 Binary files /dev/null and b/v1.4.4/CrossUrl/Core/CrossUrl.res differ diff --git a/v1.4.4/CrossUrl/CrossUrl.pas b/v1.4.4/CrossUrl/CrossUrl.pas new file mode 100644 index 0000000..a47a5ea --- /dev/null +++ b/v1.4.4/CrossUrl/CrossUrl.pas @@ -0,0 +1,7 @@ +unit CrossUrl; + +interface + +implementation + +end. diff --git a/v1.4.4/CrossUrl/CrossUrlProject.groupproj b/v1.4.4/CrossUrl/CrossUrlProject.groupproj new file mode 100644 index 0000000..58c5a49 --- /dev/null +++ b/v1.4.4/CrossUrl/CrossUrlProject.groupproj @@ -0,0 +1,84 @@ + + + {B1B0AA9C-8DE4-40E6-99FA-1601E40DC0D5} + + + + + + + Core\CrossUrl.dproj + + + + + + + + + + + + + Default.Personality.12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v1.4.4/CrossUrl/Demo/Demo.dpr b/v1.4.4/CrossUrl/Demo/Demo.dpr new file mode 100644 index 0000000..27c0b1d --- /dev/null +++ b/v1.4.4/CrossUrl/Demo/Demo.dpr @@ -0,0 +1,49 @@ +program Demo; + +{$APPTYPE CONSOLE} + +{$R *.res} + +uses + CrossUrl.HttpClient, + CrossUrl.SystemNet.HttpClient, + CrossUrl.Indy.HttpClient, + System.SysUtils; + +const + SERVER = 'http://example.com/'; + +procedure TestCore(Client: IcuHttpClient); +var + r: IcuHttpResponse; +begin + r := Client.Get(SERVER); + Writeln(r.StatusText); + Writeln(r.StatusCode); + Writeln(r.ContentAsString); +end; + +procedure TestSysNet; +begin + Writeln('Test System.Net: '); + TestCore(TcuHttpClientSysNet.Create(nil)); +end; + +procedure TestIndy; +begin + Writeln('Test Indy: '); + TestCore(TcuHttpClientIndy.Create(nil)); +end; + +begin + try + { TODO -oUser -cConsole Main : Insert code here } + TestSysNet; + TestIndy; + except + on E: Exception do + Writeln(E.ClassName, ': ', E.Message); + end; + Readln; +end. + diff --git a/v1.4.4/CrossUrl/Demo/Demo.dproj b/v1.4.4/CrossUrl/Demo/Demo.dproj new file mode 100644 index 0000000..42eb4da --- /dev/null +++ b/v1.4.4/CrossUrl/Demo/Demo.dproj @@ -0,0 +1,644 @@ + + + {86147BCA-AD6D-4187-BEC5-50AE4F61A79E} + 18.6 + None + Demo.dpr + True + Debug + Win32 + 1 + Console + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + RESTComponents;emsclientfiredac;DataSnapFireDAC;FireDACIBDriver;emsclient;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;FireDAC;FireDACSqliteDriver;soaprtl;soapmidas;$(DCC_UsePackage) + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + Demo + ..\Core;..\Indy;..\System.Net;$(DCC_UnitSearchPath) + 1049 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + + + DBXSqliteDriver;DBXInterBaseDriver;tethering;bindcompfmx;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage) + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services-ads-7.0.0.dex.jar;google-play-services-analytics-7.0.0.dex.jar;google-play-services-base-7.0.0.dex.jar;google-play-services-identity-7.0.0.dex.jar;google-play-services-maps-7.0.0.dex.jar;google-play-services-panorama-7.0.0.dex.jar;google-play-services-plus-7.0.0.dex.jar;google-play-services-wallet-7.0.0.dex.jar + + + DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;svnui;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;DBXOracleDriver;inetdb;emsedge;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;ObjectDebugger10Seattle;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + true + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + 1033 + C:\Users\Максим\Documents\Embarcadero\Studio\Projects\(None) + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Application + + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + Demo.dpr + + + + + + true + + + + + Demo.exe + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + classes + 1 + + + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + + + res\values + 1 + + + + + res\values-v21 + 1 + + + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + 1 + + + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + False + True + + + 12 + + + + + diff --git a/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.HttpClient.pas b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.HttpClient.pas new file mode 100644 index 0000000..a0d7803 --- /dev/null +++ b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.HttpClient.pas @@ -0,0 +1,111 @@ +unit CrossUrl.Indy.HttpClient; + +interface + +uses + CrossUrl.HttpClient, + System.Classes, + IdHTTP, + IdSSLOpenSSL; + +type + TcuHttpClientIndy = class(TComponent, IcuHttpClient) + private + FHttpClient: TIdHTTP; + FIdSSLIOHandlerSocketOpenSSL: TIdSSLIOHandlerSocketOpenSSL; + function GetProxy: TcuProxy; + procedure SetProxy(const AProxy: TcuProxy); + public + + destructor Destroy; override; + function Get(const AURL: string): IcuHttpResponse; + function Post(const AURL: string; const ASource: IcuMultipartFormData): + IcuHttpResponse; + function CreateMultipartFormData: IcuMultipartFormData; + constructor Create(AOwner: TComponent); override; + property Proxy: TcuProxy read GetProxy write SetProxy; + end; + +implementation + +uses + CrossUrl.Indy.HttpResponse, + CrossUrl.Indy.MultipartFormData; +{ TcuHttpClient } + + + +constructor TcuHttpClientIndy.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FIdSSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create(Nil); + FIdSSLIOHandlerSocketOpenSSL.SSLOptions.Method := sslvSSLv23; + + FHttpClient := TIdHTTP.Create(nil); + FHttpClient.Request.Connection := 'Keep-Alive'; + FHttpClient.Request.Accept := 'application/json'; + FHttpClient.IOHandler := FIdSSLIOHandlerSocketOpenSSL; + FHttpClient.Request.CustomHeaders.Clear; + FHttpClient.Request.ContentType := 'application/json'; + FHttpClient.HandleRedirects := True; + FHttpClient.Request.UserAgent := ''; +end; + +function TcuHttpClientIndy.CreateMultipartFormData: IcuMultipartFormData; +begin + Result := TcuMultipartFormDataIndy.Create; +end; + +destructor TcuHttpClientIndy.Destroy; +begin + FHttpClient.Free; + FIdSSLIOHandlerSocketOpenSSL.Free; + inherited; +end; + +function TcuHttpClientIndy.Get(const AUrl: string): IcuHttpResponse; +var + LStream: TMemoryStream; +begin + LStream := TMemoryStream.Create; + try + FHttpClient.Get(AUrl, LStream); + Result := TcuHttpResponce.Create(FHttpClient.Response, LStream); + finally + // LStream.Free; + end; +end; + +function TcuHttpClientIndy.GetProxy: TcuProxy; +begin + Result.Host := FHttpClient.ProxyParams.ProxyServer; + Result.Port := FHttpClient.ProxyParams.ProxyPort; + Result.UserName := FHttpClient.ProxyParams.ProxyUsername; + Result.Password := FHttpClient.ProxyParams.ProxyPassword; +end; + +function TcuHttpClientIndy.Post(const AURL: string; const ASource: + IcuMultipartFormData): IcuHttpResponse; +var + LStream: TMemoryStream; +begin + LStream := TMemoryStream.Create; + try + FHttpClient.Post(AURL, (ASource as TcuMultipartFormDataIndy).GetCore); + Result := TcuHttpResponce.Create(FHttpClient.Response, LStream); + finally + // LStream.Free; + end; +end; + +procedure TcuHttpClientIndy.SetProxy(const AProxy: TcuProxy); +begin + FHttpClient.ProxyParams.Clear; + FHttpClient.ProxyParams.ProxyServer := AProxy.Host; + FHttpClient.ProxyParams.ProxyPort := AProxy.Port; + FHttpClient.ProxyParams.ProxyUsername := AProxy.UserName; + FHttpClient.ProxyParams.ProxyPassword := AProxy.Password; +end; + +end. + diff --git a/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.HttpResponse.pas b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.HttpResponse.pas new file mode 100644 index 0000000..caa3d14 --- /dev/null +++ b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.HttpResponse.pas @@ -0,0 +1,100 @@ +unit CrossUrl.Indy.HttpResponse; + +interface + +uses + CrossUrl.HttpClient, + IdHTTP, + System.SysUtils, + System.Classes; + +type + TcuHttpResponce = class(TInterfacedObject, IcuHttpResponse) + private + FResponse: TIdHTTPResponse; + FStream: TMemoryStream; + function GetStatusCode: Integer; + function GetStatusText: string; + function GetContentStream: TStream; + public + constructor Create(AResponse: TIdHTTPResponse; AData: TMemoryStream); + function ContentAsString(const AnEncoding: TEncoding = nil): string; + property StatusText: string read GetStatusText; + property StatusCode: Integer read GetStatusCode; + property ContentStream: TStream read GetContentStream; + end; + +implementation + +{ TcuHttpResponce } + +function TcuHttpResponce.ContentAsString(const AnEncoding: TEncoding): string; +var + LReader: TStringStream; + LCharset: string; + LStream: TStream; + LFreeLStream: Boolean; +begin + Result := ''; + LStream := nil; + if AnEncoding = nil then + begin + LCharset := FResponse.CharSet; + if (LCharset <> '') and (string.CompareText(LCharset, 'utf-8') <> 0) then // do not translate + LReader := TStringStream.Create('', TEncoding.GetEncoding(LCharset), True) + else + LReader := TStringStream.Create('', TEncoding.UTF8, False); + end + else + LReader := TStringStream.Create('', AnEncoding, False); + try + {$IFNDEF MACOS} // NSURLConnection automatically decompresses response body. + if FResponse.ContentEncoding = 'gzip' then + begin + // 15 is the default mode. + // 16 is to enable gzip mode. http://www.zlib.net/manual.html#Advanced + // LStream := TDecompressionStream.Create(FStream, 15 + 16); + LFreeLStream := True; + end + else + {$ENDIF} + begin + LStream := GetContentStream; + LFreeLStream := False; + end; + + try + LReader.CopyFrom(LStream, 0); + Result := LReader.DataString; + finally + if LFreeLStream then + LStream.Free; + end; + finally + LReader.Free; + end; +end; + +constructor TcuHttpResponce.Create(AResponse: TIdHTTPResponse; AData: TMemoryStream); +begin + FResponse := AResponse; + FStream := AData; +end; + +function TcuHttpResponce.GetContentStream: TStream; +begin + Result := FStream //FResponse.ContentStream; +end; + +function TcuHttpResponce.GetStatusCode: Integer; +begin + Result := FResponse.ResponseCode; +end; + +function TcuHttpResponce.GetStatusText: string; +begin + Result := FResponse.ResponseText; +end; + +end. + diff --git a/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.MultipartFormData.pas b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.MultipartFormData.pas new file mode 100644 index 0000000..06d390a --- /dev/null +++ b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.MultipartFormData.pas @@ -0,0 +1,94 @@ +unit CrossUrl.Indy.MultipartFormData; + +interface + +uses + IdMultipartFormData, + CrossUrl.HttpClient, + System.Classes; + +type + TcuMultipartFormDataIndy = class(TInterfacedObject, IcuMultipartFormData) + private + FFormData: TIdMultiPartFormDataStream; + public + function GetCore: TIdMultiPartFormDataStream; + constructor Create; + procedure AddField(const AField: string; const AValue: string); + procedure AddFile(const AFieldName: string; const AFilePath: string); + destructor Destroy; override; + function GetStream: TStream; + procedure AddStream(const AFieldName: string; Data: TStream; const AFileName: + string = ''); + end; + +implementation + +uses + System.IOUtils, + System.SysUtils; + +{ TcuMultipartFormDataSysNet } + +procedure TcuMultipartFormDataIndy.AddField(const AField, AValue: string); +begin + FFormData.AddFormField(AField, AValue); +end; + +procedure TcuMultipartFormDataIndy.AddFile(const AFieldName, AFilePath: string); +begin + FFormData.AddFile(AFieldName, AFilePath); +end; + +procedure TcuMultipartFormDataIndy.AddStream(const AFieldName: string; Data: + TStream; const AFileName: string); +var + LFileStream: TFileStream; + LTmpDir: string; + LTmpFilename: string; +begin + //get filename for tmp folder e.g. ..\AppData\local\temp\4F353A8AC6AB446D9F592A30B157291B + LTmpDir := IncludeTrailingPathDelimiter(TPath.GetTempPath) + TPath.GetGUIDFileName + (false); + LTmpFilename := IncludeTrailingPathDelimiter(LTmpDir) + ExtractFileName(AFileName); + try + TDirectory.CreateDirectory(LTmpDir); + try + LFileStream := TFileStream.Create(LTmpFilename, fmCreate); + try + LFileStream.CopyFrom(Data, 0); + finally + LFileStream.Free; + end; + AddFile(AFieldName, LTmpFilename); + finally + TFile.Delete(LTmpFilename); + end; + finally + TDirectory.Delete(LTmpDir); + end; +end; + +constructor TcuMultipartFormDataIndy.Create; +begin + FFormData := TIdMultiPartFormDataStream.Create; +end; + +destructor TcuMultipartFormDataIndy.Destroy; +begin + FFormData.Free; + inherited; +end; + +function TcuMultipartFormDataIndy.GetCore: TIdMultiPartFormDataStream; +begin + Result := FFormData; +end; + +function TcuMultipartFormDataIndy.GetStream: TStream; +begin + result := FFormData; +end; + +end. + diff --git a/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.Register.pas b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.Register.pas new file mode 100644 index 0000000..ab4d6e7 --- /dev/null +++ b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.Register.pas @@ -0,0 +1,18 @@ +unit CrossUrl.Indy.Register; + +interface + +procedure register; + +implementation + +uses + System.Classes, + CrossUrl.Indy.HttpClient; + +procedure register; +begin + RegisterComponents('CrossUrl', [TcuHttpClientIndy]); +end; + +end. diff --git a/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.Uri.pas b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.Uri.pas new file mode 100644 index 0000000..8081000 --- /dev/null +++ b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.Uri.pas @@ -0,0 +1,41 @@ +unit CrossUrl.Indy.Uri; + +interface + +uses + IdURI, + CrossUrl.HttpClient, + System.Classes; + +type + TcuUriSysNet = class(TInterfacedObject, IcuUri) + private + FUri: TIdURI; + function GetScheme: string; + procedure SetScheme(const Value: string); + public + constructor Create(const AURIStr: string); + property Scheme: string read GetScheme write SetScheme; + end; + +implementation + +{ TcuUriSysNet } + +constructor TcuUriSysNet.Create(const AURIStr: string); +begin + FUri := TIdURI.Create(AURIStr); +end; + +function TcuUriSysNet.GetScheme: string; +begin + Result := FUri.Protocol; +end; + +procedure TcuUriSysNet.SetScheme(const Value: string); +begin + FUri.Protocol := Value; +end; + +end. + diff --git a/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.dpk b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.dpk new file mode 100644 index 0000000..9c3c7c4 --- /dev/null +++ b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.dpk @@ -0,0 +1,43 @@ +package CrossUrl.Indy; +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS OFF} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO OFF} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE RELEASE} +{$ENDIF IMPLICITBUILDING} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystem, + IndyProtocols, + IndyCore, + CrossUrl; + +contains + CrossUrl.Indy.HttpClient in 'CrossUrl.Indy.HttpClient.pas', + CrossUrl.Indy.HttpResponse in 'CrossUrl.Indy.HttpResponse.pas', + CrossUrl.Indy.MultipartFormData in 'CrossUrl.Indy.MultipartFormData.pas', + CrossUrl.Indy.Register in 'CrossUrl.Indy.Register.pas', + CrossUrl.Indy.Uri in 'CrossUrl.Indy.Uri.pas'; + +end. diff --git a/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.dproj b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.dproj new file mode 100644 index 0000000..1c0c917 --- /dev/null +++ b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.dproj @@ -0,0 +1,1044 @@ + + + {736CEA6E-0CB3-4907-A696-8704727F2301} + CrossUrl.Indy.dpk + 19.4 + None + True + Release + Win32 + 1 + Package + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + true + true + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + All + CrossUrl_Indy + ..\Core;$(DCC_UnitSearchPath) + 1049 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + true + + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar + + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar + + + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers + iPhoneAndiPad + true + Debug + $(MSBuildProjectName) + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers + Debug + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers + Debug + true + Base + true + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + rtl;IndySystem;IndyProtocols;IndyCore;CrossUrl.SystemNet;CrossUrl;$(DCC_UsePackage) + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + true + 1033 + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + true + 1033 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + + + + + + + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + Package + + + + CrossUrl.Indy.dpk + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + CrossUrl_Indy.bpl + true + + + + + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + classes + 1 + + + classes + 1 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + + 1 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + + False + False + False + False + False + False + True + False + + + 12 + + + + + diff --git a/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.res b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.res new file mode 100644 index 0000000..cd89ce6 Binary files /dev/null and b/v1.4.4/CrossUrl/Indy/CrossUrl.Indy.res differ diff --git a/v1.4.4/CrossUrl/LICENSE b/v1.4.4/CrossUrl/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/v1.4.4/CrossUrl/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/v1.4.4/CrossUrl/README.md b/v1.4.4/CrossUrl/README.md new file mode 100644 index 0000000..3206dfc --- /dev/null +++ b/v1.4.4/CrossUrl/README.md @@ -0,0 +1,4 @@ +# CrossUrl +Biblioteca para usar bibliotecas de rede do usuário final. + +**Installing and other info: see [wiki-page](https://github.com/ms301/CrossUrl/wiki)** diff --git a/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.HttpClient.pas b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.HttpClient.pas new file mode 100644 index 0000000..6841ffc --- /dev/null +++ b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.HttpClient.pas @@ -0,0 +1,79 @@ +unit CrossUrl.SystemNet.HttpClient; + +interface + +uses + CrossUrl.HttpClient, + System.Classes, + System.Net.HttpClient; + +type + TcuHttpClientSysNet = class(TComponent, IcuHttpClient) + private + FHttpClient: THTTPClient; + function GetProxy: TcuProxy; + procedure SetProxy(const AProxy: TcuProxy); + public + destructor Destroy; override; + function Get(const AURL: string): IcuHttpResponse; + function Post(const AURL: string; const ASource: IcuMultipartFormData): + IcuHttpResponse; + function CreateMultipartFormData: IcuMultipartFormData; + constructor Create(AOwner: TComponent); override; + property Proxy: TcuProxy read GetProxy write SetProxy; + end; + +implementation + +uses + CrossUrl.SystemNet.HttpResponse, + CrossUrl.SystemNet.MultipartFormData, + System.Net.URLClient; + +{ TcuHttpClient } + +constructor TcuHttpClientSysNet.Create(AOwner: TComponent); +begin + inherited; + FHttpClient := THTTPClient.Create; +end; + +function TcuHttpClientSysNet.CreateMultipartFormData: IcuMultipartFormData; +begin + Result := TcuMultipartFormDataSysNet.Create; +end; + +destructor TcuHttpClientSysNet.Destroy; +begin + FHttpClient.Free; + inherited Destroy; +end; + +function TcuHttpClientSysNet.Get(const AUrl: string): IcuHttpResponse; +begin + Result := TcuHttpResponce.Create(FHttpClient.Get(AUrl)); +end; + +function TcuHttpClientSysNet.GetProxy: TcuProxy; +begin + Result.Host := FHttpClient.ProxySettings.Host; + Result.Port := FHttpClient.ProxySettings.Port; + Result.UserName := FHttpClient.ProxySettings.UserName; + Result.Password := FHttpClient.ProxySettings.Password; +end; + +function TcuHttpClientSysNet.Post(const AURL: string; const ASource: + IcuMultipartFormData): IcuHttpResponse; +begin + Result := TcuHttpResponce.Create(FHttpClient.Post(AURL, (ASource as + TcuMultipartFormDataSysNet).GetCore)); +end; + +procedure TcuHttpClientSysNet.SetProxy(const AProxy: TcuProxy); +begin + FHttpClient.ProxySettings := TProxySettings.Create(AProxy.Host, AProxy.Port, + AProxy.UserName, AProxy.Password); +end; + +end. + diff --git a/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.HttpResponse.pas b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.HttpResponse.pas new file mode 100644 index 0000000..9f91cb1 --- /dev/null +++ b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.HttpResponse.pas @@ -0,0 +1,56 @@ +unit CrossUrl.SystemNet.HttpResponse; + +interface + +uses + System.Net.HttpClient, + CrossUrl.HttpClient, + System.SysUtils, + System.Classes; + +type + TcuHttpResponce = class(TInterfacedObject, IcuHttpResponse) + private + FHttpResponse: IHTTPResponse; + function GetStatusCode: Integer; + function GetStatusText: string; + function GetContentStream: TStream; + public + constructor Create(AHttpResponse: IHTTPResponse); + function ContentAsString(const AnEncoding: TEncoding = nil): string; + property StatusText: string read GetStatusText; + property StatusCode: Integer read GetStatusCode; + property ContentStream: TStream read GetContentStream; + end; + +implementation + +{ TcuHttpResponce } + +function TcuHttpResponce.ContentAsString(const AnEncoding: TEncoding): string; +begin + Result := FHttpResponse.ContentAsString(AnEncoding); +end; + +constructor TcuHttpResponce.Create(AHttpResponse: IHTTPResponse); +begin + FHttpResponse := AHttpResponse; +end; + +function TcuHttpResponce.GetContentStream: TStream; +begin + Result := FHttpResponse.ContentStream; +end; + +function TcuHttpResponce.GetStatusCode: Integer; +begin + Result := FHttpResponse.StatusCode; +end; + +function TcuHttpResponce.GetStatusText: string; +begin + Result := FHttpResponse.StatusText; +end; + +end. + diff --git a/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.MultipartFormData.pas b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.MultipartFormData.pas new file mode 100644 index 0000000..13db496 --- /dev/null +++ b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.MultipartFormData.pas @@ -0,0 +1,94 @@ +unit CrossUrl.SystemNet.MultipartFormData; + +interface + +uses + System.Net.Mime, + CrossUrl.HttpClient, + System.Classes; + +type + TcuMultipartFormDataSysNet = class(TInterfacedObject, IcuMultipartFormData) + private + FFormData: TMultipartFormData; + public + function GetCore: TMultipartFormData; + constructor Create; + procedure AddField(const AField: string; const AValue: string); + procedure AddFile(const AFieldName: string; const AFilePath: string); + destructor Destroy; override; + procedure AddStream(const AFieldName: string; Data: TStream; const AFileName: + string = ''); + function GetStream: TStream; + end; + +implementation + +uses + System.IOUtils, + System.SysUtils; + +{ TcuMultipartFormData } + +procedure TcuMultipartFormDataSysNet.AddField(const AField, AValue: string); +begin + FFormData.AddField(AField, AValue); +end; + +procedure TcuMultipartFormDataSysNet.AddFile(const AFieldName, AFilePath: string); +begin + FFormData.AddFile(AFieldName, AFilePath); +end; + +procedure TcuMultipartFormDataSysNet.AddStream(const AFieldName: string; Data: + TStream; const AFileName: string); +var + LFileStream: TFileStream; + LTmpDir: string; + LTmpFilename: string; +begin + // get filename for tmp folder e.g. ..\AppData\local\temp\4F353A8AC6AB446D9F592A30B157291B + LTmpDir := IncludeTrailingPathDelimiter(TPath.GetTempPath) + TPath.GetGUIDFileName + (false); + LTmpFilename := IncludeTrailingPathDelimiter(LTmpDir) + ExtractFileName(AFileName); + try + TDirectory.CreateDirectory(LTmpDir); + try + LFileStream := TFileStream.Create(LTmpFilename, fmCreate); + try + LFileStream.CopyFrom(Data, 0); + finally + LFileStream.Free; + end; + AddFile(AFieldName, LTmpFilename); + finally + TFile.Delete(LTmpFilename); + end; + finally + TDirectory.Delete(LTmpDir); + end; +end; + +constructor TcuMultipartFormDataSysNet.Create; +begin + FFormData := TMultipartFormData.Create; +end; + +destructor TcuMultipartFormDataSysNet.Destroy; +begin + FFormData.Free; + inherited; +end; + +function TcuMultipartFormDataSysNet.GetCore: TMultipartFormData; +begin + Result := FFormData; +end; + +function TcuMultipartFormDataSysNet.GetStream: TStream; +begin + Result := FFormData.Stream; +end; + +end. + diff --git a/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.Register.pas b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.Register.pas new file mode 100644 index 0000000..6b777fb --- /dev/null +++ b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.Register.pas @@ -0,0 +1,19 @@ +unit CrossUrl.SystemNet.Register; + +interface + +procedure register; + +implementation + +uses + System.Classes, + CrossUrl.SystemNet.HttpClient; + +procedure register; +begin + RegisterComponents('CrossUrl', [TcuHttpClientSysNet]); +end; + +end. + diff --git a/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.Uri.pas b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.Uri.pas new file mode 100644 index 0000000..bb6c5ac --- /dev/null +++ b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.Uri.pas @@ -0,0 +1,41 @@ +unit CrossUrl.SystemNet.Uri; + +interface + +uses + System.Net.URLClient, + CrossUrl.HttpClient, + System.Classes; + +type + TcuUriSysNet = class(TInterfacedObject, IcuUri) + private + FUri: TURI; + function GetScheme: string; + procedure SetScheme(const Value: string); + public + constructor Create(const AURIStr: string); + property Scheme: string read GetScheme write SetScheme; + end; + +implementation + +{ TcuUriSysNet } + +constructor TcuUriSysNet.Create(const AURIStr: string); +begin + FUri := turi.Create(AURIStr); +end; + +function TcuUriSysNet.GetScheme: string; +begin + Result := FUri.Scheme; +end; + +procedure TcuUriSysNet.SetScheme(const Value: string); +begin + FUri.Scheme := Value; +end; + +end. + diff --git a/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.dpk b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.dpk new file mode 100644 index 0000000..880ae78 --- /dev/null +++ b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.dpk @@ -0,0 +1,41 @@ +package CrossUrl.SystemNet; +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS OFF} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO OFF} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE RELEASE} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Cross URL - SystemNet'} +{$IMPLICITBUILD ON} + +requires + rtl, + CrossUrl; + +contains + CrossUrl.SystemNet.Uri in 'CrossUrl.SystemNet.Uri.pas', + CrossUrl.SystemNet.Register in 'CrossUrl.SystemNet.Register.pas', + CrossUrl.SystemNet.MultipartFormData in 'CrossUrl.SystemNet.MultipartFormData.pas', + CrossUrl.SystemNet.HttpResponse in 'CrossUrl.SystemNet.HttpResponse.pas', + CrossUrl.SystemNet.HttpClient in 'CrossUrl.SystemNet.HttpClient.pas'; + +end. diff --git a/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.dproj b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.dproj new file mode 100644 index 0000000..d2da4a1 --- /dev/null +++ b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.dproj @@ -0,0 +1,1039 @@ + + + {F04A0510-3390-4D30-AAD7-DF356290AA6F} + CrossUrl.SystemNet.dpk + 19.4 + None + True + Release + Win32 + 1 + Package + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + true + true + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + All + CrossUrl_SystemNet + ..\Core;$(DCC_UnitSearchPath) + 1033 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar + + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar + + + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers + iPhoneAndiPad + true + Debug + $(MSBuildProjectName) + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers + Debug + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers + Debug + true + Base + true + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + rtl;CrossUrl.Indy;CrossUrl;$(DCC_UsePackage) + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + true + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + true + 1033 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + + + + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + Package + + + + CrossUrl.SystemNet.dpk + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + CrossUrl_SystemNet.bpl + true + + + + + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + classes + 1 + + + classes + 1 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + + 1 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + + False + False + False + False + False + False + True + False + + + 12 + + + + + diff --git a/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.res b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.res new file mode 100644 index 0000000..822f0fa Binary files /dev/null and b/v1.4.4/CrossUrl/System.Net/CrossUrl.SystemNet.res differ diff --git a/v1.4.4/CrossUrl/System.Net/Demo.dpr b/v1.4.4/CrossUrl/System.Net/Demo.dpr new file mode 100644 index 0000000..ec3c9c1 --- /dev/null +++ b/v1.4.4/CrossUrl/System.Net/Demo.dpr @@ -0,0 +1,19 @@ +program Demo; + +{$APPTYPE CONSOLE} + +{$R *.res} + +uses + CrossUrl.HttpClient, + System.SysUtils; + +begin + try + { TODO -oUser -cConsole Main : Insert code here } + except + on E: Exception do + Writeln(E.ClassName, ': ', E.Message); + end; +end. + diff --git a/v1.4.4/CrossUrl/System.Net/Demo.dproj b/v1.4.4/CrossUrl/System.Net/Demo.dproj new file mode 100644 index 0000000..93a71c4 --- /dev/null +++ b/v1.4.4/CrossUrl/System.Net/Demo.dproj @@ -0,0 +1,581 @@ + + + {86147BCA-AD6D-4187-BEC5-50AE4F61A79E} + 18.4 + None + Demo.dpr + True + Debug + Win32 + 1 + Console + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + RESTComponents;emsclientfiredac;DataSnapFireDAC;FireDACIBDriver;emsclient;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;FireDAC;FireDACSqliteDriver;soaprtl;soapmidas;$(DCC_UsePackage) + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + Demo + ..\Core;..\Indy;..\System.Net;$(DCC_UnitSearchPath) + 1049 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + + + DBXSqliteDriver;DBXInterBaseDriver;tethering;bindcompfmx;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage) + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services-ads-7.0.0.dex.jar;google-play-services-analytics-7.0.0.dex.jar;google-play-services-base-7.0.0.dex.jar;google-play-services-identity-7.0.0.dex.jar;google-play-services-maps-7.0.0.dex.jar;google-play-services-panorama-7.0.0.dex.jar;google-play-services-plus-7.0.0.dex.jar;google-play-services-wallet-7.0.0.dex.jar + + + DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;svnui;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;DBXOracleDriver;inetdb;emsedge;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;ObjectDebugger10Seattle;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + true + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + 1033 + C:\Users\Максим\Documents\Embarcadero\Studio\Projects\(None) + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Application + + + + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + Demo.dpr + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + Demo.exe + true + + + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 0 + + + + + classes + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + + + res\values + 1 + + + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + 1 + + + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\ + 1 + + + + + Contents + 1 + + + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + False + True + + + 12 + + + + + diff --git a/v1.4.4/Exemplo/ExemplosTInjectTelegram.dpr b/v1.4.4/Exemplo/ExemplosTInjectTelegram.dpr new file mode 100644 index 0000000..75ceee5 --- /dev/null +++ b/v1.4.4/Exemplo/ExemplosTInjectTelegram.dpr @@ -0,0 +1,15 @@ +program ExemplosTInjectTelegram; +uses + Vcl.Forms, + uPrincipal in 'uPrincipal.pas' {Form1}, + uResourceString in 'uResourceString.pas', + XSuperJSON in 'XSuperJSON.pas', + XSuperObject in 'XSuperObject.pas'; + +{$R *.res} +begin + Application.Initialize; + Application.MainFormOnTaskbar := True; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. diff --git a/v1.4.4/Exemplo/ExemplosTInjectTelegram.dproj b/v1.4.4/Exemplo/ExemplosTInjectTelegram.dproj new file mode 100644 index 0000000..dd7876f --- /dev/null +++ b/v1.4.4/Exemplo/ExemplosTInjectTelegram.dproj @@ -0,0 +1,1109 @@ + + + {3F3B4088-78E3-456E-8B27-FEF37FD14424} + 19.4 + VCL + ExemplosTInjectTelegram.dpr + True + Debug + Win64 + 3 + Application + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + ExemplosTInjectTelegram + true + + + DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;DataSnapFireDAC;svnui;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;Intraweb;DBXOracleDriver;inetdb;CEF4Delphi;FmxTeeUI;emsedge;FireDACIBDriver;fmx;fmxdae;CrossUrl.Indy;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;TInjectCollection;DataSnapClient;inet;bindcompdbx;IndyIPCommon;vcl;IndyIPServer;DBXSybaseASEDriver;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;CrossUrl;emshosting;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;FireDACTDataDriver;DBXOdbcDriver;FMXTee;soaprtl;DbxCommonDriver;CrossUrl.SystemNet;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;emsserverresource;DbxClientDriver;FireDACDSDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;TInjectTelegramGestorCollection;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;TInjectTelegramCollection;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + $(BDS)\bin\default_app.manifest + + + DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;DataSnapFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;inetdb;CEF4Delphi;FmxTeeUI;emsedge;FireDACIBDriver;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;vcl;IndyIPServer;DBXSybaseASEDriver;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;FireDACTDataDriver;DBXOdbcDriver;FMXTee;soaprtl;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;emsserverresource;DbxClientDriver;FireDACDSDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + $(BDS)\bin\default_app.manifest + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + true + PerMonitorV2 + + + true + PerMonitorV2 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + true + PerMonitorV2 + + + true + PerMonitorV2 + + + + MainSource + + +
Form1
+ dfm +
+ + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + +
+ + Delphi.Personality.12 + Application + + + + ExemplosTInjectTelegram.dpr + + + $00000416 + ITA + + + Espanhol (Bolívia)*$0000400A*ESB*ESB + Francês (França)*$0000040C*FRA*FRA + Hebraico (Israel)*$0000040D*HEB*HEB + Inglês (Estados Unidos)*$00000409*ENU*ENU + Italiano (Itália)*$00000410*ITA*ITA + Persa (Irã)*$00000429*FAR*FAR + Russo (Rússia)*$00000419*RUS*RUS + Russo (Moldova)*$00000819*RUM*RUM + + + uPrincipal.dfm + Win32\Debug\ExemplosTInjectTelegram.drc + + + + + + ExemplosTInjectTelegram.exe + true + + + + + ExemplosTInjectTelegram.exe + true + + + + + ExemplosTInjectTelegram.rsm + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + classes + 1 + + + classes + 1 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + 1 + + + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen + 64 + + + ..\$(PROJECTNAME).launchscreen + 64 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + + True + True + + + 12 + + + + +
diff --git a/v1.4.4/Exemplo/ExemplosTInjectTelegram.res b/v1.4.4/Exemplo/ExemplosTInjectTelegram.res new file mode 100644 index 0000000..df29309 Binary files /dev/null and b/v1.4.4/Exemplo/ExemplosTInjectTelegram.res differ diff --git a/v1.4.4/Exemplo/Win64/Debug/Chats/1042366601/file_74.jpg b/v1.4.4/Exemplo/Win64/Debug/Chats/1042366601/file_74.jpg new file mode 100644 index 0000000..1fab9c4 Binary files /dev/null and b/v1.4.4/Exemplo/Win64/Debug/Chats/1042366601/file_74.jpg differ diff --git a/v1.4.4/Exemplo/XSuperJSON.pas b/v1.4.4/Exemplo/XSuperJSON.pas new file mode 100644 index 0000000..bd50f5f --- /dev/null +++ b/v1.4.4/Exemplo/XSuperJSON.pas @@ -0,0 +1,2368 @@ + (* + * XSuperObject - Simple JSON Framework + * + * The MIT License (MIT) + * Copyright (c) 2015 Onur YILDIZ + * + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH + * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *) + +unit XSuperJSON; + +interface + +uses + SysUtils, Classes, Generics.Collections, Generics.Defaults, Math, DateUtils, + {$IFDEF FPC}RegEx{$ELSE}RegularExpressions{$ENDIF}, RTTI; + + +const + CNull = 'null'; + MaxCHR = #127; + + Err_UnexpectedEndOfInput = 'Unexpected end of input'; + Err_Expected = 'Expected %s'; + Err_ExpectedButFound = '"%s" expected but "%s" found'; + Err_UnexpectedTokenILLEGAL = 'Unexpected token ILLEGAL'; + +type + + // ## Forward Declarations + // ----------------------- + + TJSONNull = class; + TLexGenerator = class; + TRoute = class; + PPosition = ^TPosition; + TPosition = record + Col: Integer; + Line: Integer; + end; + + TDataType = (dtNil, dtNull, dtObject, dtArray, dtString, dtInteger, dtFloat, dtBoolean, dtDateTime, dtDate, dtTime); + TJSONComparison = {$IFDEF FPC} function(Left, Right: T): Integer{$ELSE}reference to function(Left, Right: T): Integer{$ENDIF}; + // ## Exception + + TJSONSyntaxError = class(Exception) + public + constructor Create(const Msg: String; Pos: PPosition); + constructor CreateFmt(const Msg: String; const Args: array of TVarRec; Pos: PPosition); + end; + + // ## JSONWriter + TJSONWriter = class + public const + IDENT_SIZE = 2; + private + FData: TStringBuilder; + FIdent: Boolean; + FIdentOffset: Integer; + FUniversalTime: Boolean; + public + constructor Create(const useIdent, useUniversalTime: Boolean); + destructor Destroy; override; + procedure Inc; + procedure Dec; + + function Append(const Value: string; const CRLF: Boolean = False): TJSONWriter; overload; + function Append(const Value: int64; const CRLF: Boolean = False): TJSONWriter; overload; + function AppendVal(const Value: string; const CRLF: Boolean = False): TJSONWriter; overload; + function AppendVal(const Value: int64; const CRLF: Boolean = False): TJSONWriter; overload; + function ToString: string; {$IFNDEF FPC}override;{$ENDIF} + + property Ident: Boolean read FIdent; + property UniversalTime: Boolean read FUniversalTime; + end; + + + // ## JSON Symbols + // --------------- + + IJSONAncestor = interface + ['{FFB71762-50A1-4D27-9F59-56F6208421C7}'] + function GetAsVariant: Variant; + procedure SetAsVariant(const Value: Variant); + function GetDataType: TDataType; + function GetIsNull: Boolean; + procedure AsJSONString(Str: TJSONWriter); + property IsNull: Boolean read GetIsNull; + property DataType: TDataType read GetDataType; + property AsVariant: Variant read GetAsVariant write SetAsVariant; + end; + + TJSONAncestor = class abstract(TInterfacedObject, IJSONAncestor) + private + function GetAsVariant: Variant; + procedure SetAsVariant(const Value: Variant); + protected + function GetDataType: TDataType; virtual; + function GetIsNull: Boolean; virtual; + public + procedure AsJSONString(Str: TJSONWriter); virtual; + property IsNull: Boolean read GetIsNull; + property DataType: TDataType read GetDataType; + property AsVariant: Variant read GetAsVariant write SetAsVariant; + end; + + IJSONValue = interface(IJSONAncestor) + ['{0B1ED53C-EF62-4BFA-9E78-9DD9088D96C5}'] + function GetData: T; + procedure SetData(const Value: T); + procedure SetNull; + property Value: T read GetData write SetData; + end; + + TJSONValue = class abstract(TJSONAncestor, IJSONValue) + public + FNull: Boolean; + FData: T; + protected + function GetData: T; virtual; + procedure SetData(const Value: T); virtual; + function GetIsNull: Boolean; override; + property Value: T read GetData write SetData; + public + constructor Create(const Value: T); + constructor CreateNull; + procedure SetNull; + end; + + IJSONNull = interface(IJSONValue)['{C19F5715-B832-46D8-8668-1A9DC31393D7}']end; + TJSONNull = class(TJSONValue, IJSONNull) + public + procedure AsJSONString(Str: TJSONWriter); override; + protected + function GetIsNull: Boolean; override; + end; + + IJSONBoolean = interface(IJSONValue)['{CCC8D8C5-081D-4DCF-93DB-CC0696458A12}']end; + TJSONBoolean = class(TJSONValue, IJSONBoolean) + public + procedure AsJSONString(Str: TJSONWriter); override; + property Value; + end; + + IJSONString = interface(IJSONValue)['{C507BB41-3674-4F47-8D6B-5605258F6A2F}']end; + TJSONString = class(TJSONValue, IJSONString) + public + procedure AsJSONString(Str: TJSONWriter); override; + property Value; + end; + + IJSONRaw = interface(IJSONString)['{EF5EF422-1A81-49EA-A3E0-9E7D5B5CC1E2}']end; + TJSONRaw = class(TJSONString, IJSONRaw) + public + procedure AsJSONString(Str: TJSONWriter); override; + property Value; + end; + + IJSONInteger = interface(IJSONValue)['{E9D84348-9634-40F5-8A1F-FF006F45FC6D}']end; + TJSONInteger = class(TJSONValue, IJSONInteger) + public + procedure AsJSONString(Str: TJSONWriter); override; + property Value; + end; + + IJSONFloat = interface(IJSONValue)['{29D840FB-191B-4304-9518-C2937B3AE6B0}']end; + TJSONFloat = class(TJSONValue, IJSONFloat) + public + procedure AsJSONString(Str: TJSONWriter); override; + property Value; + end; + + IJSONBaseDate = interface(IJSONValue) + ['{7ACB3D47-A9A6-49C1-AFF3-F451368EAE48}'] + function GetAsString: String; + property AsString: String read GetAsString; + end; + + TJSONBaseDate = class(TJSONValue, IJSONBaseDate) + protected + FFormat: String; + public + function GetAsString: String; + procedure AsJSONString(Str: TJSONWriter); override; + end; + + IJSONDateTime = interface(IJSONBaseDate)['{9441CA2E-B822-4C13-ABF0-15F8026CCE50}']end; + TJSONDateTime = class(TJSONBaseDate, IJSONDateTime) + public + constructor Create(const Value: TDateTime; const Format: String = 'yyyy-mm-dd"T"hh":"mm":"ss.zzz'); + property Value; + end; + + IJSONDate = interface(IJSONBaseDate)['{A862D6A5-2C4A-41CD-B2C0-F7B58FA14066}']end; + TJSONDate = class(TJSONBaseDate, IJSONDate) + public + constructor Create(const Value: TDate; const Format: String = 'yyyy-mm-dd'); + property Value; + end; + + IJSONTime = interface(IJSONBaseDate)['{EEBCD145-B837-4129-A21D-378DF7DA53B2}']end; + TJSONTime = class(TJSONBaseDate, IJSONTime) + public + constructor Create(const Value: TTime; const Format: String = 'hh":"mm":"ss.zzz'); + property Value; + end; + + + TJSONDateTimeCheckCallBack = {$IFDEF FPC} function(Str: String; var Value: TDateTime; var Typ: TDataType): Boolean{$ELSE}reference to function(Str: String; var Value: TDateTime; var Typ: TDataType): Boolean{$ENDIF}; + TJSONDateManager = class + private + class var FFormats: TList; + class function GetFormats: TList; static; inline; + public + class constructor Create; + class destructor Destroy; + class function Check(const Data: String; var AValue: TDateTime; var Typ: TDataType): Boolean; + class property Formats: TList read GetFormats; + end; + + IJSONPair = interface + ['{D328943F-5ED1-4B35-8332-573156565C96}'] + function GetName: String; + function GetValue: IJSONAncestor; + procedure SetName(const Value: String); + procedure SetValue(const Value: IJSONAncestor); + property Name: String read GetName write SetName; + property JSONValue: IJSONAncestor read GetValue write SetValue; + end; + + TJSONPair = class(TInterfacedObject, IJSONPair) + private + FName: String; + FValue: IJSONAncestor; + function GetName: String; + function GetValue: IJSONAncestor; + procedure SetName(const Value: String); + procedure SetValue(const Value: IJSONAncestor); + public + constructor Create(const aName: String; aValue: IJSONAncestor); + destructor Destroy; override; + property Name: String read GetName write SetName; + property JSONValue: IJSONAncestor read GetValue write SetValue; + end; + + TJSONEnumerator = record + Index : Integer; + List : TList; + function MoveNext : Boolean; + function GetCurrent : T; + property Current : T read GetCurrent; + end; + + IJSONObject = Interface(IJSONValue) + ['{2A9244EC-F202-4CC1-9F89-7DA12437F7ED}'] + function Count: Integer; + function Get(const Name: String): IJSONPair; overload; + function Get(const Index: Integer): IJSONPair; overload; + procedure AddPair(P: IJSONPair); overload; + procedure AddPair(Name: String; Value: IJSONAncestor); overload; + procedure Remove(P: IJSONPair); overload; + procedure Remove(const Name: String); overload; + procedure Remove(const Index: Integer); overload; + function GetEnumerator: TJSONEnumerator; + procedure Sort(Comparison: TJSONComparison); + end; + + + TJSONObject = class(TJSONValue, IJSONObject) + private + FPairList: TList; + FNull: Boolean; + protected + function GetIsNull: Boolean; override; + public + constructor Create; + destructor Destroy; override; + function Count: Integer; + function Get(const Name: String): IJSONPair; overload; + function Get(const Index: Integer): IJSONPair; overload; + procedure AsJSONString(Str: TJSONWriter); override; + procedure AddPair(P: IJSONPair); overload; + procedure AddPair(Name: String; Value: IJSONAncestor); overload; inline; + procedure Remove(P: IJSONPair); overload; inline; + procedure Remove(const Name: String); overload; + procedure Remove(const Index: Integer); overload; + function GetEnumerator: TJSONEnumerator; + procedure Sort(Comparison: TJSONComparison); + class function ParseJSONValue(const Str: String; const CheckDate: Boolean): IJSONAncestor; + end; + + IJSONArray = interface(IJSONValue) + ['{C63B4323-6D7E-4151-BA1B-4C55CDE28FDB}'] + procedure Add(Val: IJSONAncestor); + procedure Remove(Val: IJSONAncestor); overload; + procedure Remove(Index: Integer); overload; + procedure Clear; + function Count: Integer; + function Get(const I: Integer): IJSONAncestor; + procedure SetIndex(const Int: Integer; const Value: IJSONAncestor); + function GetEnumerator: TJSONEnumerator; + procedure Sort(Comparison: TJSONComparison); + property Index[const Int: Integer]: IJSONAncestor read Get write SetIndex; default; + end; + + TJSONArray = class(TJSONValue, IJSONArray) + private + FList: TList; + FNull: Boolean; + procedure SetIndex(const Int: Integer; const Value: IJSONAncestor); + protected + function GetIsNull: Boolean; override; + public + constructor Create; + destructor Destroy; override; + procedure AsJSONString(Str: TJSONWriter); override; + procedure Add(Val: IJSONAncestor); + procedure Remove(Val: IJSONAncestor); overload; + procedure Remove(Index: Integer); overload; + procedure Clear; + function Count: Integer; + function Get(const I: Integer): IJSONAncestor; + function GetEnumerator: TJSONEnumerator; + procedure Sort(Comparison: TJSONComparison); + property Index[const Int: Integer]: IJSONAncestor read Get write SetIndex; default; + end; + + + TJSONBuilder = class + private + LGen: TLexGenerator; + FCheckDates: Boolean; + public + constructor Create(const JSON: String; const CheckDates: Boolean); + destructor Destroy; override; + function ReadValue: IJSONAncestor; + procedure ReadString(var Val: IJSONAncestor); + procedure ReadInteger(var Val: IJSONAncestor); + procedure ReadFloat(var Val: IJSONAncestor); + procedure ReadObject(var Val: IJSONAncestor); + procedure ReadTrue(var Val: IJSONAncestor); + procedure ReadFalse(var Val: IJSONAncestor); + procedure ReadNull(var Val: IJSONAncestor); + procedure ReadArray(var Val: IJSONAncestor); + end; + + TJSONInterpreter = class + private + LGen: TLexGenerator; + FJSON: IJSONAncestor; + FExceptionBlock: Boolean; + function ReadName(Base: IJSONAncestor): IJSONAncestor; + function ReadArrayIndex(Base: IJSONArray): IJSONAncestor; + function ReadObject(Base: IJSONAncestor): IJSONObject; + function ReadArray(Base: IJSONAncestor): IJSONArray; + function ReadValue(Base: IJSONAncestor): IJSONAncestor; + procedure CreateExcept(const S: String; Args: array of TVarRec); overload; + procedure CreateExcept(const S: String); overload; inline; + public + constructor Create(const Expression: String; JSON: IJSONAncestor; BlockException: Boolean = False); + destructor Destroy; override; + function ReadExpression: IJSONAncestor; + end; + + + // ## Parse + // -------- + + TLexemType = ( ltNil, + ltSValue, ltIValue, ltDValue, ltNull, ltCLeft, ltCRight, + ltBLeft, ltBRight, ltBSlash, ltColon, ltDot, ltVirgule, + ltName, + ltTrue, + ltFalse ); + + TLexemTypes = set of TLexemType; + + TLexBuff = class + public + Capacity: Integer; + Length : Integer; + Buff: PWideChar; + constructor Create; + destructor Destroy; override; + function AsString: String; inline; + function AsInt64: Int64; + function AsDouble: Double; + function AsType: TLexemType; + function AsHInt: Int64; + procedure Add(Ch: WideChar); inline; + procedure Grow; + procedure Clear; inline; + end; + + ILexeme = ^TLexeme; + TLexeme = record + Pos: TPosition; + Int: Int64; + Str: String; + Dbl: Double; + LType: TLexemType; + end; + + TParseProc = (ppNil, ppInteger, ppDouble, ppString, ppName, ppEscape, ppEscapeUChar); + + TTriggerProcs = set of (ttBuffer, ttEnd, ttBack); + + TTrigger = class + public + TriggerProcs: TTriggerProcs; + ParseProcs: TParseProc; + NextRoute: TRoute; + BF: Boolean; + ED: Boolean; + BK: Boolean; + constructor Create(NextRoute: TRoute; TriggerProcs: TTriggerProcs; ParseProcs: TParseProc); + end; + + TErrorTrigger = class(TTrigger) + private + FMessage: String; + function GetMeessage: String; + procedure SetMessage(const Value: String); + public + constructor Create(const Message: String); + property Message: String read GetMeessage write SetMessage; + end; + + + TNoRouteTrigger = class(TTrigger) + end; + + TUseRouteTrigger = class(TTrigger) + end; + + TJumpTrigger = class(TTrigger) + end; + + {$WARNINGS OFF} + TRouteChars = set of Char; + {$WARNINGS ON} + + TRoute = class + private + FName: String; + FTriggers: array[#0..MaxCHR] of TTrigger; + FTriggerList: TObjectList; + function GetIndex(Ch: WideChar): TTrigger; inline; + function GetName: String; + public + constructor Create(const Name: String); + destructor Destroy; override; + property Name: String read GetName; + procedure Add(const Chars: TRouteChars; Trigger: TTrigger); + procedure NoRoute(Trigger: TTrigger); + function TryGetRoute(Ch: WideChar; var Trg: TTrigger): Boolean; inline; + property Index[Ch: WideChar]: TTrigger read GetIndex; default; + end; + + TLexGrammar = class + private + FRoutes: TList; + protected + function FirstRoute: TRoute; virtual; abstract; + function CreateRoute(const Name: String): TRoute; + function EscapeSupport: Boolean; virtual; + function EscapeRoute: TRoute; virtual; + public + constructor Create; virtual; + destructor Destroy; override; + end; + + TJSONGrammar = class(TLexGrammar) + private + rFirst, + rName, + rString, + rString2, + rInt, + rDouble, + rExp, rExpE, + rExpPM, + + rEscape, + rEscapeRoute, + rEscapeUChar: TRoute; + + protected + function FirstRoute: TRoute; override; + function EscapeSupport: Boolean; override; + function EscapeRoute: TRoute; override; + public + constructor Create; override; + destructor Destroy; override; + end; + + TLexGenerator = class + private + FFirstRoute: TRoute; + FBuffer: TLexBuff; + FEscapeBuff: TLexBuff; + FCurr: PWideChar; + FCurrPos: PPosition; + FLexem: ILexeme; + FLexG: TLexGrammar; + FEscapeSupport: Boolean; + FEscapeRoute: TRoute; + FExceptBlock: Boolean; + procedure CreateLexeme; + procedure NextLex; + procedure KillLex; inline; + public + constructor Create(LexG: TLexGrammar = nil; ExceptBlock: Boolean = False); + destructor Destroy; override; + procedure Load(const Source: String); + function Check(LTyp: TLexemType): Boolean; overload; + function Check(LTyp: TLexemTypes): TLexemType; overload; + function CheckName(var S: String): Boolean; + function CheckKill(LTyp: TLexemType): Boolean; overload; + function CheckKill(LTyp: TLexemTypes): TLexemType; overload; + function Current: ILexeme; inline; + property CurrPos: PPosition read FCurrPos; + end; + + TSuperParser = class + public + class function ParseJSON(const S: String; const CheckDateTime: Boolean): IJSONAncestor; + end; + + TISO8601 = record + private + FData: TMatch; + FSuccess: Boolean; + FOffset: Integer; + FUseTime: Boolean; + FUseDate: Boolean; + FValue: TDateTime; + FValueType: TDataType; + function NextOffset: Integer; + function GetIntData(const Index: Integer): Integer; overload; inline; + function GetIntData(const Index: Integer; const P: Boolean): Integer; overload; + function GetStrData(const Index: Integer): String; inline; + procedure ReadStructure; + procedure ReadZulu; + function ReadDate: Boolean; + function ReadTime: Boolean; + procedure ReadMS; + procedure ReadTZ(const P: Boolean); + public + constructor Create(const Value: String); + property Value: TDateTime read FValue; + property ValueType: TDataType read FValueType; + property Success: Boolean read FSuccess; + end; + + function LimitedStrToUTF16(const Str: String): String; + +implementation + +uses + XSuperObject; + +const + FloatFormat : TFormatSettings = ( DecimalSeparator : '.' ); + STokenTypes : array [TLexemType] of string = ('Nil', + 'String', 'Integer', 'Float', 'Null', '[', ']', + '(', ')', '\', ':', '.', ',', + '', + 'TRUE', + 'FALSE' ); + + + optAll = [#0..#255]; + optWhiteSpace = [' ', #0, #9, #10, #13]; + + optAlpha = ['a'..'z', 'A'..'Z', '$', '_', #127]; + optSym = ['[', ']', '{', '}', ':', ',', '"', '''', '.']; + optNumeric = ['0'..'9']; + optEscape = ['b', 'f', 'n', 'r', 't', 'v', '''', '"', '\']; + optEscapeUnicode = ['u']; + optHex = ['A'..'F', 'a'..'f'] + optNumeric; + optStop = optWhiteSpace + optSym; + + HexMap : array [0..15] of WideChar = ('0', '1', '2', '3', '4', '5', '6', + '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); + +var + JSONLexGrammar: TJSONGrammar; + function iff(const Bool: Boolean; _true, _false: Variant): Variant; inline; + begin + if Bool then + Result := _true + else + Result := _false; + end; + + function ChrToUTF16(const ChrCode: Integer): String; inline; + begin + Result := '\u' + + HexMap[ChrCode shr 12] + + HexMap[(ChrCode shr 8) and 15] + + HexMap[(ChrCode shr 4) and 15] + + HexMap[ChrCode and 15]; + end; + + function StrToUTF16(const Str: String): String; + var + Tmp: PWideChar; + begin + if Str = #0 then Exit(ChrToUtf16(0)); + Result := ''; + if Str = '' then + Exit + else + Tmp := PWideChar(Pointer(Str)); + while Tmp^ <> #0 do + begin + case Tmp^ of + #1..#31: case Tmp^ of + #8 : Result := Result + '\b'; + #9 : Result := Result + '\t'; + #10: Result := Result + '\n'; + //#11: Result := Result + '\v'; + #12: Result := Result + '\f'; + #13: Result := Result + '\r'; + else + Result := Result + ChrtoUTF16(Ord(Tmp^)) + end; + #34{"}: Result := Result + '\"'; + #92{\}: Result := Result + '\\'; + #127..#65535: Result := Result + ChrtoUTF16(Ord(Tmp^)); + else + Result := Result + Tmp^; + end; + Inc(Tmp); + end; + end; + + function LimitedStrToUTF16(const Str: String): String; + var + Tmp: PWideChar; + begin + if Str = #0 then Exit(ChrToUtf16(0)); + Result := ''; + if Str = '' then + Exit + else + Tmp := PWideChar(Pointer(Str)); + while Tmp^ <> #0 do + begin + case Tmp^ of + #1..#31: case Tmp^ of + #8 : Result := Result + '\b'; + #9 : Result := Result + '\t'; + #10: Result := Result + '\n'; + //#11: Result := Result + '\v'; + #12: Result := Result + '\f'; + #13: Result := Result + '\r'; + else + Result := Result + ChrtoUTF16(Ord(Tmp^)) + end; + else + Result := Result + Tmp^; + end; + Inc(Tmp); + end; + end; + +{ TJSONAncestor } + +procedure TJSONAncestor.AsJSONString(Str: TJSONWriter); +begin + Str.Append(''); +end; + +function TJSONAncestor.GetDataType: TDataType; +begin + with TCast.Create(Self) do + begin + Result := DataType; + Free; + end; +end; + +function TJSONAncestor.GetIsNull: Boolean; +begin + Result := Self is TJSONNull; +end; + +function TJSONAncestor.GetAsVariant: Variant; +begin + with TCast.Create(Self) do + begin + Result := AsVariant; + Free; + end; +end; + +procedure TJSONAncestor.SetAsVariant(const Value: Variant); +begin + with TCast.Create(Self) do + begin + AsVariant := Value; + Free; + end; +end; + +{ TLexBuff } + +procedure TLexBuff.Add(Ch: WideChar); +begin + if Capacity = 0 then Exit; + if (Length >= Capacity - Length) then Grow; + Buff[Length] := Ch; + Inc(Length); + Buff[Length] := #0; +end; + +function TLexBuff.AsDouble: Double; +var + Res: Extended; +begin + Add(#0); + {$WARNINGS OFF} + if not TextToFloat(PWideChar(@Buff[0]), Res, fvExtended, FloatFormat) then + {$WARNINGS ON} + raise EConvertError.Create('') + else + Result := Res; +end; + +function TLexBuff.AsHInt: Int64; +var + I, J: Integer; +begin + I := 0; + Result := 0; + while I < Length do + begin + J := Ord(Buff[I]); + Inc(I); + case J of + Ord('a')..Ord('f') : + J := J - (Ord('a') - 10); + Ord('A')..Ord('F') : + J := J - (Ord('A') - 10); + Ord('0')..Ord('9') : + J := J - Ord('0'); + else + Continue; + end; + Result := (Result shl 4) or J; + end; +end; + +function TLexBuff.AsInt64: Int64; +begin + Result := StrToInt64(AsString); +end; + +function TLexBuff.AsString: String; +begin + SetString(Result, Buff, Length); +end; + +function TLexBuff.AsType: TLexemType; +begin + Result := ltName; + if Length = 0 then + Exit; + + case Buff[0] of + '[': Result := ltCLeft; + ']': Result := ltCRight; + ':': Result := ltColon; + ',': Result := ltVirgule; + '{': Result := ltBLeft; + '}': Result := ltBRight; + '.': Result := ltDot; + else + if CompareText(STokenTypes[ltTrue], AsString) = 0 then + Result := ltTrue + else + if CompareText(STokenTypes[ltFalse], AsString) = 0 then + Result := ltFalse + else + if CompareText(STokenTypes[ltNull], AsString) = 0 then + Result := ltNull + end; +end; + +procedure TLexBuff.Clear; +begin + Length := 0; + Buff[0] := #0; +end; + +constructor TLexBuff.Create; +begin + inherited; + Length := 0; + Capacity := 32; + GetMem(Buff, Capacity * SizeOf(PWideChar)); +end; + +destructor TLexBuff.Destroy; +begin + if Assigned(Buff) then + FreeMem(Buff); + inherited; +end; + +procedure TLexBuff.Grow; +begin + Capacity := Math.Max(Capacity * 2, Length + 8); + ReallocMem(Buff, Capacity * SizeOf(WideChar)); +end; + +{ TSuperParser } + +class function TSuperParser.ParseJSON(const S: String; const CheckDateTime: Boolean): IJSONAncestor; +var + JSON: TJSONBuilder; +begin + JSON := TJSONBuilder.Create(S, CheckDateTime); + try + Result := JSON.ReadValue; + finally + if Assigned(JSON) then + JSON.Free; + end; +end; + +{ TTrigger } + +{ TTrigger } + +constructor TTrigger.Create(NextRoute: TRoute; TriggerProcs: TTriggerProcs; + ParseProcs: TParseProc); +begin + Self.NextRoute := NextRoute; + Self.ParseProcs := ParseProcs; + Self.TriggerProcs := TriggerProcs; + BF := ttBuffer in TriggerProcs; + ED := ttEnd in TriggerProcs; + BK := ttBack in TriggerProcs; +end; + +{ TRoute } + +procedure TRoute.Add(const Chars: TRouteChars; Trigger: TTrigger); +var + Ch: WideChar; +begin + Ch := #0; + + if not FTriggerList.Contains(Trigger) then + FTriggerList.Add(Trigger); + + while Ch <= MaxCHR do + begin + {$WARNINGS OFF} + if Ch in Chars then {$WARNINGS ON} + if not Assigned(FTriggers[Ch]) then + FTriggers[Ch] := Trigger; + Inc(Ch); + end; +end; + +constructor TRoute.Create(const Name: String); +begin + FName := Name; + FTriggerList := TObjectList.Create; +end; + + +destructor TRoute.Destroy; +begin + FTriggerList.Free; + inherited; +end; + +function TRoute.GetIndex(Ch: WideChar): TTrigger; +begin + if Ch > MaxCHR then Ch := MaxCHR; + Result := FTriggers[Ch]; +end; + +function TRoute.GetName: String; +begin + Result := FName; +end; + +procedure TRoute.NoRoute(Trigger: TTrigger); +var + Ch: WideChar; +begin + Ch := #0; + + if not FTriggerList.Contains(Trigger) then + FTriggerList.Add(Trigger); + + while Ch <= MaxCHR do + begin + if not Assigned(FTriggers[Ch]) then + FTriggers[Ch] := Trigger; + Inc(Ch); + end; +end; + +function TRoute.TryGetRoute(Ch: WideChar; var Trg: TTrigger): Boolean; +begin + if Ch > MaxCHR then Ch := MaxCHR; + if FTriggers[Ch] <> nil then + begin + Result := True; + Trg := FTriggers[Ch]; + end + else + Result := False; +end; + +{ TLexGrammar } + +constructor TLexGrammar.Create; +begin + FRoutes := TList.Create; +end; + +destructor TLexGrammar.Destroy; +begin + FRoutes.Free; + inherited; +end; + +function TLexGrammar.EscapeRoute: TRoute; +begin + Result := Nil; +end; + +function TLexGrammar.EscapeSupport: Boolean; +begin + Result := False; +end; + +function TLexGrammar.CreateRoute(const Name: String): TRoute; +begin + Result := TRoute.Create(Name); + FRoutes.Add(Result); +end; + +{ TJSONGrammar } + +constructor TJSONGrammar.Create; +begin + inherited; + + rFirst := CreateRoute('First'); + rName := CreateRoute('Name'); + rString := CreateRoute('String'); + rString2 := CreateRoute('String2'); + rInt := CreateRoute('Int'); + rDouble := CreateRoute('Double'); + + rExp := CreateRoute('Exp'); + rExpE := CreateRoute('ExpE'); + rExpPM := CreateRoute('ExpPM'); + + rEscape := CreateRoute('Escape'); + rEscapeRoute := CreateRoute('EscapeRoute'); + rEscapeUChar := CreateRoute('EscapeUChar'); + + + rEscape.Add( ['\'], TJumpTrigger.Create(rEscapeRoute, [], ppNil )); + + rEscapeRoute.Add(['u'], TJumpTrigger.Create(rEscapeUChar, [ttBuffer], ppNil)); + rEscapeRoute.NoRoute(TUseRouteTrigger.Create(rEscape, [ttBuffer, ttEnd], ppEscape)); + + rEscapeUChar.Add(optHex, TUseRouteTrigger.Create(rEscapeUChar, [], ppEscapeUChar)); + rEscapeUChar.NoRoute(TErrorTrigger.Create(ERR_UnexpectedTokenILLEGAL)); + + rFirst.Add(optSym - ['"', ''''], TUseRouteTrigger.Create(rFirst, [ttBuffer, ttEnd], ppName)); + rFirst.Add(optAlpha, TUseRouteTrigger.Create(rName, [ttBuffer], ppNil)); + rFirst.Add(['"'], TJumpTrigger.Create(rString, [ttBuffer], ppNil)); + rFirst.Add([''''], TJumpTrigger.Create(rString2, [ttBuffer], ppNil)); + rFirst.Add(optNumeric, TUseRouteTrigger.Create(rInt, [ttBuffer], ppNil)); + rFirst.Add(optWhiteSpace - [#0], TJumpTrigger.Create(rFirst, [], ppNil)); + rFirst.Add(['-'], TUseRouteTrigger.Create(rInt, [ttBuffer], ppNil)); + rFirst.NoRoute(TErrorTrigger.Create(ERR_UnexpectedTokenILLEGAL)); + + rName.Add(optAll - optWhiteSpace - optSym, TUseRouteTrigger.Create(rName, [], ppNil)); + rName.Add(optWhiteSpace, TJumpTrigger.Create(rFirst, [ttEnd, ttBack], ppName)); + rName.NoRoute(TJumpTrigger.Create(rFirst, [ttEnd, ttBack], ppName)); + + rString.Add(optAll - ['"', #0, #10, #13], TUseRouteTrigger.Create(rString, [], ppNil)); + rString.Add(['"'], TJumpTrigger.Create(rFirst, [ttEnd], ppString)); + rString.Add([#0, #10, #13], TErrorTrigger.Create(ERR_UnexpectedTokenILLEGAL)); + + rString2.Add(optAll - ['''', #0, #10, #13], TUseRouteTrigger.Create(rString2, [], ppNil)); + rString2.Add([''''], TJumpTrigger.Create(rFirst, [ttEnd], ppString)); + rString2.Add([#0, #10, #13], TErrorTrigger.Create(ERR_UnexpectedTokenILLEGAL)); + + rInt.Add(optNumeric, TUseRouteTrigger.Create(rInt, [], ppNil)); + rInt.Add(['.'], TUseRouteTrigger.Create(rDouble, [], ppNil)); + rInt.Add(['e', 'E'], TUseRouteTrigger.Create(rExp, [], ppNil)); + rInt.Add(optStop, TJumpTrigger.Create(rFirst, [ttEnd, ttBack], ppInteger)); + rInt.NoRoute(TErrorTrigger.Create(ERR_UnexpectedTokenILLEGAL)); + + rDouble.Add(optNumeric, TUseRouteTrigger.Create(rDouble, [], ppNil)); + rDouble.Add(['e', 'E'], TUseRouteTrigger.Create(rExp, [], ppNil)); + rDouble.Add(optStop, TJumpTrigger.Create(rFirst, [ttEnd, ttBack], ppDouble)); + rDouble.NoRoute(TErrorTrigger.Create(ERR_UnexpectedTokenILLEGAL)); + + rExp.Add(['+', '-'], TUseRouteTrigger.Create(rExpPM, [], ppNil)); + rExp.Add(optNumeric, TUseRouteTrigger.Create(rExpE, [], ppNil)); + rExp.NoRoute(TErrorTrigger.Create(Err_UnexpectedTokenILLEGAL)); + + rExpPM.Add(optNumeric, TUseRouteTrigger.Create(rExpE, [], ppNil)); + rExpPM.NoRoute(TErrorTrigger.Create(Err_UnexpectedTokenILLEGAL)); + + rExpE.Add(optNumeric, TUseRouteTrigger.Create(rExpE, [], ppNil)); + rExpE.Add(optStop, TJumpTrigger.Create(rFirst, [ttEnd, ttBack], ppDouble)); + rExpE.NoRoute(TErrorTrigger.Create(Err_UnexpectedTokenILLEGAL)); + +end; + +destructor TJSONGrammar.Destroy; +begin + rFirst.Free; + rName.Free; + rString.Free; + rString2.Free; + rInt.Free; + rDouble.Free; + rExp.Free; + rExpE.Free; + rExpPM.Free; + rEscape.Free; + rEscapeRoute.Free; + rEscapeUChar.Free; + inherited; +end; + +function TJSONGrammar.EscapeRoute: TRoute; +begin + Result := rEscape; +end; + +function TJSONGrammar.EscapeSupport: Boolean; +begin + Result := True; +end; + +function TJSONGrammar.FirstRoute: TRoute; +begin + Result := rFirst; +end; + +{ TErrorTrigger } + +constructor TErrorTrigger.Create(const Message: String); +begin + inherited Create(Nil, [], ppNil); + FMessage := Message; +end; + +function TErrorTrigger.GetMeessage: String; +begin + Result := FMessage; +end; + +procedure TErrorTrigger.SetMessage(const Value: String); +begin + FMessage := Value; +end; + +{ TLexGenerator } + +function TLexGenerator.Check(LTyp: TLexemTypes): TLexemType; +begin + if not Assigned(FLexem) then + begin + NextLex; + if not Assigned(FLexem) then + Exit(ltNil); + end; + Result := iff(FLexem.LType in LTyp, FLexem.LType, ltNil); +end; + +function TLexGenerator.Check(LTyp: TLexemType): Boolean; +begin + if not Assigned(FLexem) then + begin + NextLex; + if not Assigned(FLexem) then + Exit(False); + end; + Result := FLexem.LType = LTyp; +end; + +function TLexGenerator.CheckKill(LTyp: TLexemType): Boolean; +begin + if not Assigned(FLexem) then + begin + NextLex; + if not Assigned(FLexem) then + Exit(False); + end; + if FLexem.LType = LTyp then + begin + KillLex; + Result := True; + end + else + Result := False; +end; + +function TLexGenerator.CheckKill(LTyp: TLexemTypes): TLexemType; +begin + if not Assigned(FLexem) then + begin + NextLex; + if not Assigned(FLexem) then + Exit(ltNil); + end; + if FLexem.LType in LTyp then + begin + Result := FLexem.LType; + KillLex; + end + else + Result := ltNil; +end; + +function TLexGenerator.CheckName(var S: String): Boolean; +var + lt: TLexemType; +begin + lt := Check([ltSValue, ltName, ltDValue, ltIValue, ltTrue, ltFalse]); + if lt in [ltSValue, ltName, ltTrue, ltFalse] then + begin + if (Pos(#$D, FLexem.Str) > 0) or (Pos(#$A, FLexem.Str)>0) then + Exit(False); + Result := True; + S := FLexem.Str; + end + else + Result := False; +end; + +constructor TLexGenerator.Create(LexG: TLexGrammar; ExceptBlock: Boolean); +begin + FExceptBlock := ExceptBlock; + if not Assigned(LexG) then + FLexG := JSONLexGrammar + else + FLexG := LexG; + FFirstRoute := LexG.FirstRoute; + FBuffer := TLexBuff.Create; + FEscapeSupport := LexG.EscapeSupport; + if FEscapeSupport then + begin + FEscapeRoute := LexG.EscapeRoute; + FEscapeBuff := TLexBuff.Create; + end; + New(FCurrPos); + FCurrPos.Line := 1; + FCurrPos.Col := 0; +end; + +procedure TLexGenerator.CreateLexeme; +begin + KillLex; + New(FLexem); + FillChar(FLexem.Pos, SizeOf(TPosition), 0); + FLexem.LType := ltNull; +end; + +function TLexGenerator.Current: ILexeme; +begin + Result := FLexem; +end; + +destructor TLexGenerator.Destroy; +begin + KillLex; + FBuffer.Free; + if FEscapeSupport then + FEscapeBuff.Free; + Dispose(FCurrPos); + inherited; +end; + +procedure TLexGenerator.KillLex; +begin + if Assigned(FLexem) then + begin + Dispose(FLexem); + FLexem := Nil; + end; +end; + +procedure TLexGenerator.Load(const Source: String); +begin + FCurr := PWideChar(Source); +end; + +{$HINTS OFF} +procedure TLexGenerator.NextLex; +var + Route: TRoute; + Trigger: TTrigger; + CTyp: TClass; + UseEscape, UseEscapeEnd: Boolean; +begin + CreateLexeme; + UseEscape := False; + UseEscapeEnd := False; + FBuffer.Clear; + if FEscapeSupport then + begin + FEscapeRoute := FLexG.EscapeRoute; + FEscapeBuff.Clear; + end; + + Route := FFirstRoute; + while Assigned(Route) do + begin + + if FEscapeSupport then + begin + Trigger := FEscapeRoute[FCurr^]; + if Trigger = Nil then + begin + Trigger := Route[FCurr^]; + UseEscape := False; + end + else + UseEscape := True; + end + else + begin + Trigger := Route[FCurr^]; + UseEscape := False; + end; + + if Trigger = Nil then Exit; + + CTyp := Trigger.ClassType; + + if CTyp = TErrorTrigger then + if FCurr^ = #0 then + Break + else + if FExceptBlock then + Abort + else + raise TJSONSyntaxError.Create( TErrorTrigger(Trigger).Message, FCurrPos); + + if CTyp = TUseRouteTrigger then + if UseEscape then + FEscapeBuff.Add(FCurr^) + else + FBuffer.Add(FCurr^); + + if Trigger.BF and (FLexem.Pos.Col = 0) then + FLexem.Pos := FCurrPos^; + + if not Trigger.BK then + begin + Inc(FCurr); + if FCurr^ = #10 then + begin + Inc(FCurrPos.Line); + FCurrPos.Col := 1; + end + else + Inc(FCurrPos.Col); + end; + + if Trigger.ParseProcs <> ppNil then + begin + case Trigger.ParseProcs of + ppInteger: begin + FLexem.Int := FBuffer.AsInt64; + FLexem.LType := ltIValue; + end; + ppDouble:begin + FLexem.Dbl := FBuffer.AsDouble; + FLexem.LType := ltDValue; + end; + ppString:begin + FLexem.LType := ltSValue; + end; + + ppName: begin + FLexem.Str := FBuffer.AsString; + FLexem.LType := FBuffer.AsType; + end; + + ppEscapeUChar: begin + if FEscapeBuff.Length = 4 then + begin + FBuffer.Add(Chr(FEscapeBuff.AsHInt)); + FEscapeBuff.Clear; + UseEscapeEnd := True; + end; + end; + + ppEscape: begin + case FEscapeBuff.Buff[0] of + 'b' : FBuffer.Add(#8); + 't' : FBuffer.Add(#9); + 'n' : FBuffer.Add(#10); + 'v' : FBuffer.Add(#11); + 'f' : FBuffer.Add(#12); + 'r' : FBuffer.Add(#13); + '\' : FBuffer.Add('\'); + '"' : FBuffer.Add('"'); + '''': FBuffer.Add(''''); + else + FBuffer.Add(FEscapeBuff.Buff[0]); + end; + FEscapeBuff.Clear; + end; + end; + end; + + if Trigger.ED or UseEscapeEnd then + begin + if not UseEscape then + begin + FFirstRoute := Trigger.NextRoute; + FLexem.Str := FBuffer.AsString; + Exit; + end; + UseEscape := False; + UseEscapeEnd := False; + FEscapeRoute := FLexG.EscapeRoute; + end + else + if UseEscape then + FEscapeRoute := Trigger.NextRoute + else + Route := Trigger.NextRoute; + end; + KillLex; +end; +{$HINTS ON} + +{ TJSONBuilder } + +constructor TJSONBuilder.Create(const JSON: String; const CheckDates: Boolean); +begin + LGen := TLexGenerator.Create(JSONLexGrammar); + LGen.Load(JSON); + FCheckDates := CheckDates; +end; + +destructor TJSONBuilder.Destroy; +begin + LGen.Free; + inherited; +end; + +procedure TJSONBuilder.ReadArray(var Val: IJSONAncestor); +var + Item: IJSONAncestor; +begin + LGen.KillLex; + Val := TJSONArray.Create; + + repeat + Item := ReadValue; + if Assigned(Item) then + TJSONArray(Val).Add(Item); + until not LGen.CheckKill(ltVirgule); + + if not LGen.CheckKill(ltCRight) then + raise TJSONSyntaxError.Create(Err_UnexpectedEndOfInput, LGen.CurrPos); +end; + +procedure TJSONBuilder.ReadFalse(var Val: IJSONAncestor); +begin + Val := TJSONBoolean.Create(False); + LGen.KillLex; +end; + +procedure TJSONBuilder.ReadFloat(var Val: IJSONAncestor); +begin + Val := TJSONFloat.Create(LGen.Current.Dbl); + LGen.KillLex; +end; + +procedure TJSONBuilder.ReadInteger(var Val: IJSONAncestor); +begin + Val := TJSONInteger.Create(LGen.Current.Int); + LGen.KillLex; +end; + +procedure TJSONBuilder.ReadNull(var Val: IJSONAncestor); +begin + Val := TJSONNull.Create(True); + LGen.KillLex; +end; + +procedure TJSONBuilder.ReadObject(var Val: IJSONAncestor); +var + Name: String; +begin + LGen.KillLex; + Val := TJSONObject.Create; + repeat + if LGen.CheckName(Name) then + begin + LGen.KillLex; + if not LGen.CheckKill(ltColon) then + raise TJSONSyntaxError.CreateFmt(Err_Expected, [':'], LGen.CurrPos); + TJSONObject(Val).AddPair(TJSONPair.Create(Name, ReadValue)); + end + until not LGen.CheckKill(ltVirgule); + + if not LGen.CheckKill(ltBRight) then + raise TJSONSyntaxError.Create(Err_UnexpectedEndOfInput, LGen.CurrPos); +end; + +procedure TJSONBuilder.ReadString(var Val: IJSONAncestor); +var + dT: TDateTime; + DVal: TDataType; +label + JMP; +begin + if (not FCheckDates) or (Length(LGen.Current.Str) > 25 {2015-10-20T12:22:24+00:00}) or (Length(LGen.Current.Str) < 5 {22:22}) then + JMP:Val := TJSONString.Create( LGen.Current.Str ) + else + if TJSONDateManager.Check(LGen.Current.Str, dT, DVal ) then + case DVal of + dtDateTime: Val := TJSONDateTime.Create(dT); + dtDate : Val := TJSONDate.Create(TDate(dT)); + dtTime : Val := TJSONTime.Create(TTime(dT)); + else + goto JMP; + end + else + goto JMP; + LGen.KillLex; +end; + +procedure TJSONBuilder.ReadTrue(var Val: IJSONAncestor); +begin + Val := TJSONBoolean.Create(True); + LGen.KillLex; +end; + +function TJSONBuilder.ReadValue: IJSONAncestor; +begin + case LGen.Check([ ltSValue, ltIValue, ltDValue, ltBLeft, ltCLeft, + ltTrue, ltFalse, ltNull ]) of + ltSValue: ReadString(Result); + ltIValue: ReadInteger(Result); + ltDValue: ReadFloat(Result); + ltBLeft : ReadObject(Result); + ltTrue : ReadTrue(Result); + ltFalse : ReadFalse(Result); + ltCLeft : ReadArray(Result); + ltNull : ReadNull(Result); + else + Result := Nil; + end; +end; + +{ TJSONString } + +procedure TJSONString.AsJSONString(Str: TJSONWriter); +begin + if IsNull then + Str.AppendVal( cNull ) + else + Str.AppendVal( '"' + StrToUTF16(Value) + '"' ); +end; + +{ TJSONInteger } + +procedure TJSONInteger.AsJSONString(Str: TJSONWriter); +begin + if FNull then + Str.AppendVal( cNull ) + else + Str.AppendVal( Value ); +end; + + +{ TJSONFloat } + +procedure TJSONFloat.AsJSONString(Str: TJSONWriter); +begin + if FNull then + Str.AppendVal( cNull ) + else + Str.AppendVal( FloatToStr(Value, FloatFormat) ); +end; + +{ TJSONBoolean } + +procedure TJSONBoolean.AsJSONString(Str: TJSONWriter); +begin + Str.AppendVal( String(iff( IsNull, cNull, iff( Value, 'true', 'false') )) ); +end; + +{ TJSONNull } + +procedure TJSONNull.AsJSONString(Str: TJSONWriter); +begin + Str.AppendVal( cNull ); +end; + +function TJSONNull.GetIsNull: Boolean; +begin + Result := True; +end; + +{ TJSONObject } + +procedure TJSONObject.AddPair(P: IJSONPair); +var + N: IJSONPair; +begin + N := Get(P.Name); + if Assigned(N) then + begin + FPairList.Remove(N); + N := Nil; + end; + FPairList.Add(P); +end; + +procedure TJSONObject.AddPair(Name: String; Value: IJSONAncestor); +begin + AddPair( TJSONPair.Create(Name, Value) ); +end; + +procedure TJSONObject.AsJSONString(Str: TJSONWriter); +var + P: IJSONPair; + I,L: Integer; +begin + if FNull then + Str.AppendVal( cNull ) + else + begin + Str.Append('{', True); + Str.Inc; + L := Count-1; + for I := 0 to L do + begin + P := FPairList[I]; + Str.Append('"' + StrToUTF16(P.Name) + '":'); + if Str.Ident and (P.JSONValue.DataType in [dtObject, dtArray]) then + Str.Append('', True); + P.JSONValue.AsJSONString(Str); + if I < L then + Str.AppendVal(',', Str.Ident); + end; + Str.Dec; + if Str.Ident then + Str.Append(#$D#$A); + Str.Append('}'); + end; +end; + +function TJSONObject.Count: Integer; +begin + Result := FPairList.Count; +end; + +constructor TJSONObject.Create; +begin + FPairList := TList.Create; +end; + +destructor TJSONObject.Destroy; +begin + FPairList.Free; + inherited; +end; + +function TJSONObject.Get(const Name: String): IJSONPair; +var + P: IJSONPair; +begin + for P in FPairList do + if CompareText(Name, P.Name) = 0 then + Exit(P); + Result := Nil; +end; + +function TJSONObject.GetIsNull: Boolean; +begin + Result := FNull; +end; + +function TJSONObject.Get(const Index: Integer): IJSONPair; +begin + if (FPairList.Count = 0) or (FPairList.Count <= Index) then + Result := Nil + else + Result := FPairList[Index]; +end; + +function TJSONObject.GetEnumerator: TJSONEnumerator; +begin + Result.Index := -1; + Result.List := FPairList; +end; + +class function TJSONObject.ParseJSONValue(const Str: String; const CheckDate: Boolean): IJSONAncestor; +begin + Result := TSuperParser.ParseJSON(Str, CheckDate); +end; + +procedure TJSONObject.Remove(P: IJSONPair); +begin + Remove(P.Name); +end; + +procedure TJSONObject.Remove(const Index: Integer); +begin + if Count > Index then + FPairList.Delete(Index); +end; + +procedure TJSONObject.Sort(Comparison: TJSONComparison); +begin + FPairList.Sort( TComparer.Construct( + TComparison(Comparison) + )); +end; + +procedure TJSONObject.Remove(const Name: String); +var + R: IJSONPair; +begin + R := Get(Name); + if Assigned(R) then + begin + FPairList.Remove(R); + R := Nil; + end; +end; + + +{ TJSONPair } + +constructor TJSONPair.Create(const aName: String; aValue: IJSONAncestor); +begin + FName := aName; + FValue := aValue; +end; + +destructor TJSONPair.Destroy; +begin + FValue := Nil; + inherited; +end; + + +function TJSONPair.GetName: String; +begin + Result := FName; +end; + +function TJSONPair.GetValue: IJSONAncestor; +begin + Result := FValue; +end; + +procedure TJSONPair.SetName(const Value: String); +begin + FName := Value; +end; + +procedure TJSONPair.SetValue(const Value: IJSONAncestor); +begin + FValue := Value; +end; + +{ TJSONSyntaxError } + +constructor TJSONSyntaxError.Create(const Msg: String; Pos: PPosition); +begin + inherited CreateFmt(Msg + '. (Line: %d Col: %d)', [Pos.Line, Pos.Col]); +end; + +constructor TJSONSyntaxError.CreateFmt(const Msg: String; const Args: array of TVarRec; + Pos: PPosition); +begin + Create( Format(Msg, Args), Pos ); +end; + + +{ TJSONArray } + +procedure TJSONArray.Add(Val: IJSONAncestor); +begin + FList.Add(Val); +end; + +procedure TJSONArray.AsJSONString(Str: TJSONWriter); +var + I,L: Integer; +begin + if FNull then + Str.AppendVal( cNull ) + else + begin + Str.Append('[', True); + Str.Inc; + L := Count - 1; + for I := 0 to L do + begin + if FList = Nil then Continue; + FList[I].AsJSONString(Str); + if I < L then + Str.AppendVal(',', Str.Ident); + end; + Str.Dec; + if Str.Ident then + Str.Append(#$D#$A); + Str.Append(']'); + end; +end; + +procedure TJSONArray.Clear; +begin + FList.Clear; +end; + +function TJSONArray.Count: Integer; +begin + Result := FList.Count; +end; + +constructor TJSONArray.Create; +begin + FList := TList.Create; +end; + +destructor TJSONArray.Destroy; +begin + FList.Free; + inherited; +end; + +function TJSONArray.Get(const I: Integer): IJSONAncestor; +begin + if (FList.Count = 0) or (Flist.Count <= I) then + Result := Nil + else + Result := FList.Items[I] +end; + +function TJSONArray.GetEnumerator: TJSONEnumerator; +begin + Result.Index := -1; + Result.List := FList; +end; + +function TJSONArray.GetIsNull: Boolean; +begin + Result := FNull; +end; + +procedure TJSONArray.Remove(Val: IJSONAncestor); +begin + FList.Remove(Val); +end; + +procedure TJSONArray.Remove(Index: Integer); +begin + FList.Delete(Index); +end; + +procedure TJSONArray.SetIndex(const Int: Integer; const Value: IJSONAncestor); +begin + if (FList.Count = 0) or (Flist.Count <= Int) then + Exit; + FList[Int] := Value; +end; + +procedure TJSONArray.Sort(Comparison: TJSONComparison); +begin + FList.Sort( TComparer.Construct( + TComparison(Comparison) + )); +end; + +{ TJSONValue } + +constructor TJSONValue.Create(const Value: T); +begin + FData := Value; + FNull := False; +end; + +constructor TJSONValue.CreateNull; +begin + FNull := True; +end; + +function TJSONValue.GetData: T; +begin + Result := FData; +end; + +function TJSONValue.GetIsNull: Boolean; +begin + Result := FNull; +end; + +procedure TJSONValue.SetData(const Value: T); +begin + FData := Value; +end; + +procedure TJSONValue.SetNull; +begin + FNull := True; +end; + +{ TJSONInterpreter } + +constructor TJSONInterpreter.Create(const Expression: String; + JSON: IJSONAncestor; BlockException: Boolean = False); +begin + LGen := TLexGenerator.Create(JSONLexGrammar, BlockException); + LGen.Load(Expression); + FJSON := JSON; + FExceptionBlock := BlockException; +end; + +procedure TJSONInterpreter.CreateExcept(const S: String; + Args: array of TVarRec); +begin + if FExceptionBlock then + Abort + else + raise TJSONSyntaxError.CreateFmt(S, Args, LGen.CurrPos); +end; + +procedure TJSONInterpreter.CreateExcept(const S: String); +begin + if FExceptionBlock then + Abort + else + raise TJSONSyntaxError.Create(S, LGen.CurrPos); +end; + +destructor TJSONInterpreter.Destroy; +begin + LGen.Free; + inherited; +end; + +function TJSONInterpreter.ReadArray(Base: IJSONAncestor): IJSONArray; +var + Item: IJSONAncestor; +begin + LGen.KillLex; + Result := TJSONArray.Create; + repeat + Item := ReadValue(Base); + if Assigned(Item) then + TJSONArray(Result).Add(Item); + until not LGen.CheckKill(ltVirgule); + + if not LGen.CheckKill(ltCRight) then + CreateExcept(Err_UnexpectedEndOfInput); +end; + +function TJSONInterpreter.ReadArrayIndex(Base: IJSONArray): IJSONAncestor; +var + RName: IJSONAncestor; + Index: Integer; +begin + Index := 0; + case LGen.Check([ltIValue, ltName]) of + ltIValue: + begin + Index := StrToInt(LGen.Current.Str); + LGen.KillLex; + end; + ltName: + begin + RName := ReadName(FJSON); + if not (RName is TJSONInteger) then + CreateExcept(Err_ExpectedButFound, [STokenTypes[ltIValue], STokenTypes[LGen.Current.LType]]) + else + Index := TJSONInteger(RName).Value; + end + else + CreateExcept(Err_ExpectedButFound, [STokenTypes[ltIValue], STokenTypes[LGen.Current.LType]]) + end; + Result := Base.Index[Index]; + if not LGen.CheckKill(ltCRight) then + CreateExcept(Err_Expected, [STokenTypes[ltCRight]]); + if LGen.CheckKill(ltDot) then + begin + RName := ReadName(Result); + if Assigned(RName) then + Result := RName; + end; +end; + +function TJSONInterpreter.ReadExpression: IJSONAncestor; +begin + try + case LGen.Check([ltBLeft, ltCLeft]) of + ltBLeft : Result := ReadObject(FJSON); + ltCLeft : Result := ReadArray(FJSON); + else + Result := ReadName(FJSON); + end; + except + on E: Exception do + begin + if FExceptionBlock then + Result := Nil + else + raise; + end; + end; +end; + +function TJSONInterpreter.ReadName(Base: IJSONAncestor): IJSONAncestor; +var + Name: String; + Pair: IJSONPair; +begin + if not LGen.CheckName(Name) then + Exit(Nil); + + if Base is TJSONArray then + begin + if LGen.Current.LType <> ltIValue then + CreateExcept(Err_ExpectedButFound, [STokenTypes[ltIValue], STokenTypes[LGen.Current.LType]]) + else + Result := TJSONArray(Base).Index[StrToInt(Name)]; + end + else + if Base is TJSONObject then + begin + Pair := TJSONObject(Base).Get(Name); + if Pair = Nil then + Exit(Nil) + else + Result := Pair.JSONValue; + LGen.KillLex; + if Assigned(Result) then + case LGen.CheckKill([ltDot, ltCLeft]) of + ltDot: + Result := ReadName(Result); + ltCLeft: + begin + if Result is TJSONArray then + Result := ReadArrayIndex(TJSONArray(Result)) + else + CreateExcept(Err_Expected, ['Array']); + end; + end; + end + else + Result := Nil; +end; + +function TJSONInterpreter.ReadObject(Base: IJSONAncestor): IJSONObject; +var + Name: String; +begin + LGen.KillLex; + Result := TJSONObject.Create; + repeat + if LGen.CheckName(Name) then + begin + LGen.KillLex; + if not LGen.CheckKill(ltColon) then + CreateExcept(Err_Expected, [':']); + TJSONObject(Result).AddPair(TJSONPair.Create(Name, ReadValue(Base))); + end + until not LGen.CheckKill(ltVirgule); + + if not LGen.CheckKill(ltBRight) then + CreateExcept(Err_UnexpectedEndOfInput); +end; + +function TJSONInterpreter.ReadValue(Base: IJSONAncestor): IJSONAncestor; +begin + case LGen.Check([ ltSValue, ltIValue, ltDValue, ltBLeft, ltCLeft, + ltTrue, ltFalse, ltName, ltNull ]) of + ltSValue: Result := TJSONString.Create(LGen.Current.Str); + ltIValue: Result := TJSONInteger.Create(LGen.Current.Int); + ltDValue: Result := TJSONFloat.Create(LGen.Current.Dbl); + ltBLeft : Result := ReadObject(Base); + ltTrue : Result := TJSONBoolean.Create(True); + ltFalse : Result := TJSONBoolean.Create(False); + ltCLeft : Result := ReadArray(Base); + ltNull : Result := TJSONNull.Create(True); + ltName : begin + Result := ReadName(Base); + Exit; + end + else + Result := Nil; + Exit; + end; + LGen.KillLex; +end; + +{ TSuperEnumerator } + +function TJSONEnumerator.GetCurrent: T; +begin + Result := List[Index] +end; + +function TJSONEnumerator.MoveNext: Boolean; +begin + Result := Index < List.Count - 1; + if Result then + Inc(Index); +end; + +{ TJSONWriter } + +function TJSONWriter.Append(const Value: string; const CRLF: Boolean = False): TJSONWriter; +begin + if FIdent then + begin + FData.Append(' ', FIdentOffset); + if CRLF then + FData.AppendLine(Value) + else + FData.Append(Value) + end + else + FData.Append(Value); + Result := Self; +end; + +function TJSONWriter.Append(const Value: int64; const CRLF: Boolean): TJSONWriter; +begin + Result := Append(IntToStr(Value), CRLF); +end; + +function TJSONWriter.AppendVal(const Value: string; const CRLF: Boolean): TJSONWriter; +begin + if CRLF then + FData.AppendLine(Value) + else + FData.Append(Value); + Result := Self; +end; + +function TJSONWriter.AppendVal(const Value: int64; const CRLF: Boolean): TJSONWriter; +begin + Result := Append(IntToStr(Value), CRLF); +end; + +constructor TJSONWriter.Create(const useIdent, useUniversalTime: Boolean); +begin + inherited Create; + FData := TStringBuilder.Create; + FIdent := useIdent; + FUniversalTime := useUniversalTime; + FIdentOffset := 0; +end; + +procedure TJSONWriter.Dec; +begin + System.Dec(FIdentOffset, IDENT_SIZE); +end; + +destructor TJSONWriter.Destroy; +begin + FData.Free; + inherited; +end; + +procedure TJSONWriter.Inc; +begin + System.Inc(FIdentOffset, IDENT_SIZE); +end; + +function TJSONWriter.ToString: string; +begin + Result := FData.ToString; +end; + +{ TJSONDateTime } + +constructor TJSONDateTime.Create(const Value: TDateTime; const Format: String); +begin + inherited Create(Value); + FFormat := Format; +end; + +{ TJSONDateManager } + +class function TJSONDateManager.Check(const Data: String; var AValue: TDateTime; + var Typ: TDataType): Boolean; +var + CallBck: TJSONDateTimeCheckCallBack; +begin + for CallBck in FFormats do + if CallBck(Data, AValue, Typ) then + Exit(True); + Result := False; +end; + +class constructor TJSONDateManager.Create; +begin + FFormats := TList.Create; +end; + +class destructor TJSONDateManager.Destroy; +{$IF CompilerVersion < 29} +var + I: Integer; +{$ENDIF} +begin + if Assigned(FFormats) then begin + {$IF CompilerVersion < 29} + for I := 0 to FFormats.Count - 1 do + FFormats.List[I]._Release; + {$ENDIF} + FFormats.Free; + end; +end; + +class function TJSONDateManager.GetFormats: TList; +begin + Result := FFormats; +end; + +{ TISO8601 } + +constructor TISO8601.Create(const Value: String); +var + Matches: TMatchCollection; +begin + FillChar(Self, SizeOf(TISO8601), #0); + Matches := TRegEx.Matches(Value, '(?=\d{4})((\d{4})-(\d{2})-(\d{2}))?(T(\d{2})\:(\d{2})\:('+ + '\d{2})(Z)?(\.(\d{1,3})(Z)?)?([+-](\d{2})\:(\d{2}))?)?|(\d{2})\:('+ + '\d{2})\:(\d{2})(Z)?(\.(\d{1,3}))?([+-](\d{2})\:(\d{2}))?'); + if Matches.Count <> 1 then Exit; + FData := Matches.Item[0]; + FSuccess := Trim(FData.Value) = Trim(Value); + if not FSuccess then Exit; + ReadStructure; +end; + +function TISO8601.GetIntData(const Index: Integer): Integer; +begin + Result := StrToInt(GetStrData(Index)); +end; + +function TISO8601.GetIntData(const Index: Integer; const P: Boolean): Integer; +begin + Result := GetIntData(Index); + if not P then + Result := -1 * Result; +end; + +function TISO8601.GetStrData(const Index: Integer): String; +begin + Result := FData.Groups.Item[Index].Value; +end; + +function TISO8601.NextOffset: Integer; +begin + Inc(FOffset); + Result := FOffset; +end; + +procedure TISO8601.ReadStructure; +var + Len, VLen: Integer; + Grp: TGroup; +begin + FOffset := 1; + Len := FData.Groups.Count - 1; + while FOffset <= Len do + begin + Grp := FData.Groups.Item[FOffset]; + with Grp do + if Value > '' then begin + VLen := System.Length(Value); + if (Value[CharIndex] <> '.') and (VLen = 4) then begin + Dec(FOffset); + ReadDate + end else + case Value[CharIndex] of + '0'..'9': if VLen = 2 then begin + FUseTime := True; + Dec(FOffset); + if not ReadTime then + begin + FSuccess := False; + Exit; + end; + end; + + 'T', 't': begin + FUseTime := True; + if not ReadTime then + begin + FSuccess := False; + Exit; + end; + end; + 'Z': if FUseTime then ReadZulu; + '.': if FUseTime then ReadMS; + '+': if FUseTime then ReadTZ(True); + '-': if FUseTime then ReadTZ(False); + end; + end; + Inc(FOffset); + end; + if FUseDate and FUseTime then + FValueType := dtDateTime + else if FUseDate then + FValueType := dtDate + else if FUseTime then + FValueType := dtTime; +end; + +function TISO8601.ReadDate: Boolean; +begin + Result := True; + if not TryEncodeDate( GetIntData(NextOffset), GetIntData(NextOffset), GetIntData(NextOffset), FValue ) then + begin + FValue := 0; + Result := False; + end + else + FUseDate := True +end; + +procedure TISO8601.ReadMS; +var + Temp: TDateTime; +begin + if TryEncodeTime(0, 0, 0, GetIntData(NextOffset), Temp) then + FValue := FValue + TTime(Temp); +end; + +function TISO8601.ReadTime: Boolean; +var + Temp: TDateTime; +begin + if TryEncodeTime(GetIntData(NextOffset), GetIntData(NextOffset), GetIntData(NextOffset), 0, Temp ) then + begin + FValue := FValue + TTime(Temp); + FUseTime := True; + Result := True; + end + else + Result := False; +end; + +procedure TISO8601.ReadTZ(const P: Boolean); +begin + FValue := IncHour(FValue, -1 * GetIntData(NextOffset, P)); + FValue := IncMinute(FValue, -1 * GetIntData(NextOffset, P)); + FValue := TTimeZone.Local.ToLocalTime(FValue) +end; + + +procedure TISO8601.ReadZulu; +begin + FValue := TTimeZone.Local.ToLocalTime(FValue); +end; + +{ TJSONDate } + +constructor TJSONDate.Create(const Value: TDate; const Format: String); +begin + inherited Create(Value); + FFormat := Format; +end; + +{ TJSONTime } + +constructor TJSONTime.Create(const Value: TTime; const Format: String); +begin + inherited Create(Value); + FFormat := Format; +end; + +{ TJSONBaseDate } + +procedure TJSONBaseDate.AsJSONString(Str: TJSONWriter); +begin + if FNull then + Str.AppendVal( cNull ) + else + begin + if Str.UniversalTime then + Str.AppendVal( '"' + FormatDateTime(FFormat, TTimeZone.Local.ToUniversalTime(PDateTime(@FData)^)) + 'Z"' ) + else + Str.AppendVal( '"' + FormatDateTime(FFormat, PDateTime(@FData)^) + '"' ); + end; +end; + +function TJSONBaseDate.GetAsString: String; +begin + Result := FormatDateTime(FFormat, PDateTime(@FData)^); +end; + +{ TJSONRaw } + +procedure TJSONRaw.AsJSONString(Str: TJSONWriter); +begin + Str.AppendVal( Value ); +end; + +initialization + + JSONLexGrammar := TJSONGrammar.Create; + + TJSONDateManager.Formats.Add( (* ISO-8601 | [Date] + [ Time + [MS] + [UTC] + [Z] ] *) + function(Str: String; var AValue: TDateTime; var Typ: TDataType): Boolean + begin + with TISO8601.Create(Str) do + begin + Result := Success; + if Result then + begin + AValue := Value; + Typ := ValueType; + end; + end; + end); + +finalization + + JSONLexGrammar.Free; + +end. diff --git a/v1.4.4/Exemplo/XSuperObject.inc b/v1.4.4/Exemplo/XSuperObject.inc new file mode 100644 index 0000000..9f43fbb --- /dev/null +++ b/v1.4.4/Exemplo/XSuperObject.inc @@ -0,0 +1,41 @@ + (* + * XSuperObject - Simple JSON Framework + * + * The MIT License (MIT) + * Copyright (c) 2015 Onur YILDIZ + * + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH + * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *) + + (* + * Marshalling Options + *) + {$DEFINE SP_DATASET} + {$DEFINE SP_STREAM} + + // ** Zero Based Strings Definations... + {$UNDEF XE2UP} + {$IFDEF DCC} + {$IF CompilerVersion >= 24} + {$DEFINE XE2UP} + {$ENDIF} + {$ENDIF} \ No newline at end of file diff --git a/v1.4.4/Exemplo/XSuperObject.pas b/v1.4.4/Exemplo/XSuperObject.pas new file mode 100644 index 0000000..2aeb3b8 --- /dev/null +++ b/v1.4.4/Exemplo/XSuperObject.pas @@ -0,0 +1,3456 @@ + (* + * XSuperObject - Simple JSON Framework + * + * The MIT License (MIT) + * Copyright (c) 2015 Onur YILDIZ + * + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH + * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *) + +unit XSuperObject; + +interface + +{$I XSuperObject.inc} + +uses + Classes, + Variants, + SysUtils, + Character, + XSuperJSON, + RTTI, + TypInfo, + Generics.Collections + {$IFDEF SP_DATASET} + ,DB + {$ENDIF} + {$IFDEF SP_STREAM} + ,IdGlobal + ,IdCoderMIME + {$ENDIF} + ; + +{$IFDEF XE2UP} + const CharIndex = Low(String); +{$ELSE} + const CharIndex = 1; +{$ENDIF} + +type + + SOException = class(Exception) end; + SOInvalidDate = class(SOException) end; + ESerializeError = class(Exception) end; + + ISuperObject = interface; + ISuperArray = interface; + ICast = Interface; + IMember = ICast; + TSuperObject = class; + TSuperArray = class; + + TMemberStatus = (jUnAssigned, jNull, jAssigned); + TJSONType = (jtObject, jtArray); + + Alias = class(TCustomAttribute) + private + FName: String; + public + constructor Create(const AName: String); + property Name: String read FName write FName; + end; + + TRevalOption = (roNone, roEmptyArrayToNull); + + REVAL = class(TCustomAttribute) + private + FOption: TRevalOption; + FEqual: Variant; + FValue: Variant; + public + constructor Create(EQVal: String; NewVal: String); overload; + constructor Create(EQVal: Integer; NewVal: Integer); overload; + constructor Create(EQVal: Boolean; NewVal: Boolean); overload; + constructor Create(EQVal: Double; NewVal: Double); overload; + constructor Create(EQVal: String); overload; + constructor Create(EQVal: Integer); overload; + constructor Create(EQVal: Double); overload; + constructor Create(EQVal: Boolean); overload; + constructor Create(Option: TRevalOption); overload; + function CheckEQ(Val: TValue): Boolean; + property Equal: Variant read FEqual; + property Value: Variant read FValue; + property Option: TRevalOption read FOption; + end; + + DISABLE = class(TCustomAttribute) + end; + + DISABLEREAD = class(TCustomAttribute) + end; + + DISABLEWRITE = class(TCustomAttribute) + end; + + IBase = interface + ['{872FA14E-9276-4F86-A8D8-832CF39DACE6}'] + function AsObject: ISuperObject; + function AsArray: ISuperArray; + end; + + TBase = class(TInterfacedObject, IBase) + function AsObject: ISuperObject; virtual; + function AsArray: ISuperArray; virtual; + end; + + IBaseJSON = interface(IBase) + ['{EBD49266-BEF2-4B79-9BAF-329F725E0568}'] + function GetBoolean(V: Typ): Boolean; + function GetInteger(V: Typ): Int64; + function GetString(V: Typ): String; + procedure SetBoolean(V: Typ; const Value: Boolean); + procedure SetInteger(V: Typ; const Value: Int64); + procedure SetString(V: Typ; const Value: String); + function GetObject(V: Typ): ISuperObject; + procedure SetObject(V: Typ; const Value: ISuperObject); + function GetArray(V: Typ): ISuperArray; + procedure SetArray(V: Typ; const Value: ISuperArray); + function GetDouble(V: Typ): Double; + procedure SetDouble(V: Typ; const Value: Double); + function GetVariant(V: Typ): Variant; + procedure SetVariant(V: Typ; const Value: Variant); + function GetDateTime(V: Typ): TDateTime; + procedure SetDateTime(V: Typ; const Value: TDateTime); + function GetDate(V: Typ): TDate; + procedure SetDate(V: Typ; const Value: TDate); + function GetTime(V: Typ): TTime; + procedure SetTime(V: Typ; const Value: TTime); + function GetSelf: T; + function GetAncestor(V: Typ): IJSONAncestor; + function GetNull(V: Typ): TMemberStatus; + procedure SetNull(V: Typ; const Value: TMemberStatus); + function GetDataType: TDataType; + + property Null[V: Typ]: TMemberStatus read GetNull write SetNull; + property S[V: Typ]: String read GetString write SetString; + property I[V: Typ]: Int64 read GetInteger write SetInteger; + property B[V: Typ]: Boolean read GetBoolean write SetBoolean; + property F[V: Typ]: Double read GetDouble write SetDouble; + property O[V: Typ]: ISuperObject read GetObject write SetObject; + property A[V: Typ]: ISuperArray read GetArray write SetArray; + property V[V: Typ]: Variant read GetVariant write SetVariant; + property D[V: Typ]: TDateTime read GetDateTime write SetDateTime; + property Date[V: Typ]: TDate read GetDate write SetDate; + property Time[V: Typ]: TTime read GetTime write SetTime; + property Ancestor[V: Typ]: IJSONAncestor read GetAncestor; + function Contains(Key: Typ): Boolean; + function GetType(Key: Typ): TVarType; + procedure Sort(Comparison: TJSONComparison); + procedure SaveTo(Stream: TStream; const Ident: Boolean = false; const UniversalTime : Boolean = false); overload; + procedure SaveTo(AFile: String; const Ident: Boolean = false; const UniversalTime : Boolean = false); overload; + function AsJSON(const Ident: Boolean = False; const UniversalTime: Boolean = False): String; + property Self: T read GetSelf; + property DataType: TDataType read GetDataType; + end; + + TJSONValueHelper = class helper for TJSONAncestor + public + function ValueEx: Variant; + end; + + TCondCallBack = reference to function(Arg: T): Boolean; + + TBaseJSON = class(TBase, IBaseJSON) + protected + FJSONObj: T; + FCasted: IJSONAncestor; + FInterface: IInterface; + FCheckDate: Boolean; + function ContainsEx(Key: Typ; out Value: IJSONAncestor): Boolean; + function DefaultValueClass(const Value): TT; + procedure Member(const Name: Typ; const Value: TValue); overload; + function Member(const Name: Typ): Boolean; overload; + function GetValue(const Name: Typ): C; + function GetSelf: T; + function GetData(Key: Typ): IJSONAncestor; + function GetVariant(V: Typ): Variant; + procedure SetVariant(V: Typ; const Value: Variant); + function GetDataType: TDataType; + protected + function GetObject(V: Typ): ISuperObject; virtual; + function GetArray(V: Typ): ISuperArray; virtual; + function GetBoolean(V: Typ): Boolean; virtual; + function GetInteger(V: Typ): Int64; virtual; + function GetString(V: Typ): String; virtual; + function GetDouble(V: Typ): Double; virtual; + function GetAncestor(V: Typ): IJSONAncestor; inline; + function GetNull(V: Typ): TMemberStatus; virtual; + function GetDateTime(V: Typ): TDateTime; virtual; + function GetDate(V: Typ): TDate; virtual; + function GetTime(V: Typ): TTime; virtual; + procedure SetDate(V: Typ; const Value: TDate); virtual; + procedure SetTime(V: Typ; const Value: TTime); virtual; + procedure SetDateTime(V: Typ; const Value: TDateTime); virtual; + procedure SetObject(V: Typ; const Value: ISuperObject); virtual; + procedure SetArray(V: Typ; const Value: ISuperArray); virtual; + procedure SetBoolean(V: Typ; const Value: Boolean); virtual; + procedure SetInteger(V: Typ; const Value: Int64); virtual; + procedure SetString(V: Typ; const Value: String); virtual; + procedure SetDouble(V: Typ; const Value: Double); virtual; + procedure SetNull(V: Typ; const Value: TMemberStatus); virtual; + public + constructor Create(JSON: String = '{}'; const CheckDate: Boolean = True); overload; + constructor Create(JSON: T; const CheckDate: Boolean = True); overload; + constructor CreateCasted(Value: IJSONAncestor; const CheckDate: Boolean = True); + constructor CreateWithEscape(JSON: String = '{}'; const CheckDate: Boolean = True); + destructor Destroy; override; + property Null[V: Typ]: TMemberStatus read GetNull write SetNull; + property S[V: Typ]: String read GetString write SetString; + property I[V: Typ]: Int64 read GetInteger write SetInteger; + property B[V: Typ]: Boolean read GetBoolean write SetBoolean; + property F[V: Typ]: Double read GetDouble write SetDouble; + property O[V: Typ]: ISuperObject read GetObject write SetObject; + property A[V: Typ]: ISuperArray read GetArray write SetArray; + property V[V: Typ]: Variant read GetVariant write SetVariant; + property D[V: Typ]: TDateTime read GetDateTime write SetDateTime; + property Date[V: Typ]: TDate read GetDate write SetDate; + property Time[V: Typ]: TTime read GetTime write SetTime; + property Ancestor[V: Typ]: IJSONAncestor read GetAncestor; + function Contains(Key: Typ): Boolean; + function GetType(Key: Typ): TVarType; + procedure Sort(Comparison: TJSONComparison); virtual; abstract; + procedure SaveTo(Stream: TStream; const Ident: Boolean = false; const UniversalTime : Boolean = false); overload; virtual; abstract; + procedure SaveTo(AFile: String; const Ident: Boolean = false; const UniversalTime : Boolean = false); overload; virtual; abstract; + function AsJSON(const Ident: Boolean = False; const UniversalTime: Boolean = False): String; inline; + property Self: T read GetSelf; + property DataType: TDataType read GetDataType; + end; + + + ICast = interface + ['{0F5387AB-C1C9-4229-921D-226960332271}'] + function GetArray: ISuperArray; + function GetBoolean: Boolean; + function GetDataType: TDataType; + function GetFloat: Double; + function GetInteger: Int64; + function GetObject: ISuperObject; + function GetString: String; + function GetName: String; + function GetVariant: Variant; + function GetDate: TDate; + function GetDateTime: TDateTime; + function GetTime: TTime; + procedure SetDate(const Value: TDate); + procedure SetDateTime(const Value: TDateTime); + procedure SetTime(const Value: TTime); + procedure SetBoolean(const Value: Boolean); + procedure SetFloat(const Value: Double); + procedure SetInteger(const Value: Int64); + procedure SetString(const Value: String); + procedure SetVariant(const Value: Variant); + + property AsObject: ISuperObject read GetObject; + property AsArray: ISuperArray read GetArray; + property AsString: String read GetString write SetString; + property AsInteger: Int64 read GetInteger write SetInteger; + property AsFloat: Double read GetFloat write SetFloat; + property AsBoolean: Boolean read GetBoolean write SetBoolean; + property AsVariant: Variant read GetVariant write SetVariant; + property AsDateTime: TDateTime read GetDateTime write SetDateTime; + property AsDate: TDate read GetDate write SetDate; + property AsTime: TTime read GetTime write SetTime; + property DataType: TDataType read GetDataType; + property Name: String read GetName; + function ToString(const Ident: Boolean = False; const UniversalTime: Boolean = False): String; + function ToAnsiString(const Ident: Boolean = False; const UniversalTime: Boolean = False): Ansistring; + end; + + TCast = class(TInterfacedObject, ICast) + private + FJSON: IJSONAncestor; + FName: String; + function GetArray: ISuperArray; + function GetBoolean: Boolean; + function GetDataType: TDataType; + function GetFloat: Double; + function GetInteger: Int64; + function GetObject: ISuperObject; + function GetString: String; + procedure SetBoolean(const Value: Boolean); + procedure SetFloat(const Value: Double); + procedure SetInteger(const Value: Int64); + procedure SetString(const Value: String); + function GetName: String; + function GetVariant: Variant; + procedure SetVariant(const Value: Variant); + function GetDate: TDate; + function GetDateTime: TDateTime; + function GetTime: TTime; + procedure SetDate(const Value: TDate); + procedure SetDateTime(const Value: TDateTime); + procedure SetTime(const Value: TTime); + public + constructor Create(Base: IJSONAncestor); overload; + constructor Create(Base: IJSONPair); overload; + class function CreateFrom(Base: T): ICast; + destructor Destroy; override; + property AsObject: ISuperObject read GetObject; + property AsArray: ISuperArray read GetArray; + property AsString: String read GetString write SetString; + property AsInteger: Int64 read GetInteger write SetInteger; + property AsFloat: Double read GetFloat write SetFloat; + property AsBoolean: Boolean read GetBoolean write SetBoolean; + property AsVariant: Variant read GetVariant write SetVariant; + property AsDateTime: TDateTime read GetDateTime write SetDateTime; + property AsDate: TDate read GetDate write SetDate; + property AsTime: TTime read GetTime write SetTime; + property DataType: TDataType read GetDataType; + property Name: String read GetName; + function ToString(const Ident: Boolean = False; const UniversalTime: Boolean = False): String; reintroduce; + function ToAnsiString(const Ident: Boolean = False; const UniversalTime: Boolean = False): Ansistring; + end; + + + + ISuperExpression = interface(ICast) + ['{58366F15-0D83-4BC5-85D5-238E78E73247}'] + end; + + TSuperExpression = class(TCast, ISuperExpression) + private + FInterpreter: TJSONInterpreter; + public + constructor Create(Base: IJSONAncestor; const Expr: String; const BlockException: Boolean = False); + destructor Destroy; override; + end; + + TSuperEnumerator = record + Index : Integer; + List : TJSONEnumerator; + function MoveNext : Boolean; + function GetCurrent : ICast; + property Current : ICast read GetCurrent; + end; + + ISuperObject = interface(IBaseJSON) + ['{B7E271F3-205B-4172-8532-BE03F2A6EDE7}'] + procedure First; + procedure Next; + function GetEoF: Boolean; + function GetCount: Integer; + function GetCurrentKey: String; + function GetCurrentValue: IJSONAncestor; + function GetOffset: Integer; + function GetExpr(const Code: String): ISuperExpression; + function GetRaw(V: String): String; + procedure SetRaw(V: String; Value: String); + + + procedure Add(const Key: String; const Data: IJSONAncestor); + procedure SetData(V: String; Data: Variant); overload; + procedure SetData(V: String; Data: Variant; AFormatSettings: TFormatSettings); overload; + procedure Remove(Key: String); + function Check(const Expr: String): Boolean; + + property Expression[const Code: String]: ISuperExpression read GetExpr; default; + property Count: Integer read GetCount; + property EoF: Boolean read GetEoF; + property CurrentKey: String read GetCurrentKey; + property CurrentValue: IJSONAncestor read GetCurrentValue; + property Offset: Integer read GetOffset; + function Clone: ISuperObject; + function GetEnumerator: TSuperEnumerator; + function T: TSuperObject; + function Where(const Cond: TCondCallBack): ISuperObject; + function Delete(const Cond: TCondCallBack): ISuperObject; + function Cast: ICast; + property Raw[V: String]: String read GetRaw write SetRaw; + end; + + TSuperObject = class(TBaseJSON, ISuperObject) + private + FOffset: Integer; + function GetEoF: Boolean; + function GetCount: Integer; + function GetCurrentKey: String; + function GetCurrentValue: IJSONAncestor; + function GetOffset: Integer; + function GetExpr(const Code: String): ISuperExpression; + function GetRaw(V: String): String; + procedure SetRaw(V: String; Value: String); + protected + function GetString(V: String): String; override; + procedure SetNull(V: String; const Value: TMemberStatus); override; + public + procedure First; + procedure Next; + + procedure Add(const Key: String; const Data: IJSONAncestor); + procedure SetData(V: String; Data: Variant); overload; inline; + procedure SetData(V: String; Data: Variant; AFormatSettings: TFormatSettings); overload; + + class function ParseStream(Stream: TStream; CheckDate: Boolean = True): TSuperObject; + class function ParseFile(FileName: String; CheckDate: Boolean = True): TSuperObject; + + procedure SaveTo(Stream: TStream; const Ident: Boolean = false; const UniversalTime : Boolean = false); overload; override; + procedure SaveTo(AFile: String; const Ident: Boolean = false; const UniversalTime : Boolean = false); overload; override; + procedure Remove(Key: String); + function Check(const Expr: String): Boolean; + + property Expression[const Code: String]: ISuperExpression read GetExpr; default; + property Count: Integer read GetCount; + property Offset: Integer read GetOffset; + property EoF: Boolean read GetEoF; + property CurrentKey: String read GetCurrentKey; + property CurrentValue: IJSONAncestor read GetCurrentValue; + function GetEnumerator: TSuperEnumerator; + function AsType: T; + function T: TSuperObject; inline; + function Clone: ISuperObject; + function AsObject: ISuperObject; override; + function AsArray: ISuperArray; override; + procedure Sort(Comparison: TJSONComparison); override; + function Where(const Cond: TCondCallBack): ISuperObject; + function Delete(const Cond: TCondCallBack): ISuperObject; + function Cast: ICast; + end; + + ISuperArray = interface(IBaseJSON) + ['{41A2D578-CFAB-4924-8F15-0D0227F35412}'] + function GetLength: Integer; + property Length: Integer read GetLength; + procedure Add(Value: IJSONAncestor); overload; + procedure Add(Value: ISuperArray); overload; + procedure Add(Value: ISuperObject); overload; + procedure Add(Value: Variant; DateFormat: TFormatSettings); overload; + procedure Add(Value: Variant); overload; + procedure Delete(Index: Integer); overload; + procedure Clear; + function Clone: ISuperArray; + function GetEnumerator: TSuperEnumerator; + function T: TSuperArray; + function Where(const Cond: TCondCallBack): ISuperArray; + function Delete(const Cond: TCondCallBack): ISuperArray; overload; + end; + + TSuperArray = class(TBaseJSON, ISuperArray) + private + function GetLength: Integer; + protected + procedure SetNull(V: Integer; const aValue: TMemberStatus); override; + public + procedure Add(Value: IJSONAncestor); overload; + procedure Add(Value: ISuperObject); overload; + procedure Add(Value: ISuperArray); overload; + procedure Add(Value: Variant; DateFormat: TFormatSettings); overload; + procedure Add(Value: Variant); overload; + procedure Delete(Index: Integer); overload; + function Delete(const Cond: TCondCallBack): ISuperArray; overload; + procedure Clear; + property Length: Integer read GetLength; + function GetEnumerator: TSuperEnumerator; + procedure SaveTo(Stream: TStream; const Ident: Boolean = false; const UniversalTime : Boolean = false); overload; override; + procedure SaveTo(AFile: String; const Ident: Boolean = false; const UniversalTime : Boolean = false); overload; override; + procedure Sort(Comparison: TJSONComparison); override; + function Clone: ISuperArray; + function AsArray: ISuperArray; override; + function AsObject: ISuperObject; override; + function Where(const Cond: TCondCallBack): ISuperArray; + function T: TSuperArray; inline; + function AsType: T; + end; + + TSuperProperty = class(TRttiProperty) + public + ArrayRawData: Pointer; + end; + + TSuperField = class(TRttiField) + public + ArrayRawData: Pointer; + end; + + TSuperDynArr = class(TRttiDynamicArrayType) + public + ArrayRawData: Pointer; + end; + + TSuperArr = class(TRttiArrayType) + public + ArrayRawData: Pointer; + end; + + TGenericsType = (gtNil, gtList, gtObjectList); + + TGenericsInfo = class + private + FContext: TRttiContext; + FType: TRttiType; + FAddMethod: TRttiMethod; + FCountProperty: TRttiProperty; + FGetItemMethod: TRttiIndexedProperty; + public + IsGeneric: Boolean; + Typ: TRttiType; + CreateArgs: TArray; + procedure AddVal(Instance: TObject; Val: TValue); + function Count(Instance: TObject): Integer; + function Item(Instance: TObject; const Index: Integer): TObject; + constructor Create(GenericClass: TClass; const AIsGeneric: Boolean; AType: TRttiType); + destructor Destroy; override; + end; + + TAttributeClass = class of TCustomAttribute; + TPropertyGetterType = (pgtField, pgtMethod); + + TSerializeParse = class + private + class var FGenericsCache: TObjectDictionary; + class function GetAttribute(AttributeType: TAttributeClass; Attributes: TArray): TCustomAttribute; + class procedure GetAliasName(const Attributes: TArray; var Result: String); + class function GetREVAL(const Attributues: TArray): REVAL; + class function IsDisabled(const Attributes: TArray): Boolean; inline; + class function IsDisabledRead(const Attributes: TArray): Boolean; inline; + class function IsDisabledWrite(const Attributes: TArray): Boolean; inline; + class function PropGetterType(Prop: TRttiProperty): TPropertyGetterType; + public + class constructor Create; + class destructor Destroy; + class function IsGenerics(Cls: TRttiType): Boolean; overload; + class function IsGenerics(Cls: TClass): Boolean; overload; + class function IsCollection(Cls: TRttiType): Boolean; overload; + class function IsCollection(Cls: TClass): Boolean; overload; inline; + class function GetGenericType(Cls: TClass): TGenericsType; + class function GetGenericsCreateArgs(Cls: TRttiType): TArray; + + // ** Read + {$IFDEF SP_STREAM} + class procedure ReadStream(AStream: TStream; IResult: IJSONAncestor); + {$ENDIF} + class procedure ReadGeneric(AObject: TObject; IResult: ISuperArray); + class procedure ReadCollection(ACollection: TCollection; IResult: ISuperArray); + class procedure ReadObject(AObject: TObject; IResult: ISuperObject); + class procedure ReadRecord(Info: PTypeInfo; ARecord: Pointer; IResult: ISuperObject); + class function ReadRecordEx(Rec: T): ISuperObject; + class procedure ReadMembers(Data: Pointer; aType: TRttiType; IJsonData: ISuperObject); + class procedure ReadMember(Member: Typ; RType: PTypeInfo; MemberValue: TValue; IJsonData: IBaseJSON); + + class procedure ReadSet(Val: TValue; IJsonData: ISuperArray); + class procedure ReadVariantOfArray(Val: Variant; IJsonData: ISuperArray); + class procedure ReadTValueOfArray(Val: TValue; IJsonData: ISuperArray); + class procedure ReadVariantOfObject(Val: Variant; const Name: String; IJsonData: ISuperObject); + + // ** Write + {$IFDEF SP_STREAM} + class procedure WriteStream(AStream: TStream; IData: IJSONAncestor); + {$ENDIF} + class procedure WriteGeneric(AObject: TObject; IData: ISuperArray); + class procedure WriteCollection(ACollection: TCollection; IData: ISuperArray); + class procedure WriteObject(AObject: TObject; IData: ISuperObject); + class procedure WriteRecord(Info: PTypeInfo; ARecord: Pointer; IData: ISuperObject); + class procedure WriteRecordEx(Rec: T; IData: ISuperObject); + class procedure WriteMembers(Data: Pointer; aType: TRttiType; IJsonData: ISuperObject); + class procedure WriteMember(Data: Pointer; Member: Typ; RType: PTypeInfo; MemberValue: TRttiObject; IJsonData: IBaseJSON); + class procedure WriteSet(Data: Pointer; Member: TRttiObject; IJSONData: ISuperArray); + class procedure SetValue(var Data: Pointer; Member: TRttiObject; MIdx: Typ; Val: TValue); + class function GetValue(Data: Pointer; Member: TRttiObject; MIdx: Typ): TValue; + class function GetMemberTypeInfo(Member: TRttiObject; const GetArray: Boolean = true): PTypeInfo; inline; + class function GetMemberType(Member: TRttiObject; const GetArray: Boolean = true): TRttiType; //inline; + class function GetArrayRawData(Member: TRttiObject): Pointer; + class procedure SetArrayRawData(Member: TRttiObject; RawData: Pointer); + class procedure ClearArrayRawData(Member: TRttiObject); + + class function ObjectConstructorParamCount(Instance: TClass): Integer; + class function ObjectConstructor(Instance: TClass): TObject; + class function CheckObject(Data: Pointer; Member: TRttiObject; MIdx: Typ; var Obj: TObject): Boolean; + + class property GenericsCache: TObjectDictionary read FGenericsCache; + end; + + TMemberVisibilities = set of TMemberVisibility; + TSerializeParseOptions = class + private + class var FVisibilities: TMemberVisibilities; + public + class constructor Create; + class property Visibilities: TMemberVisibilities read FVisibilities write FVisibilities; + end; + + TSuperObjectHelper = class helper for TObject + public + function AsJSON(const Ident: Boolean = False; const UniversalTime: Boolean = False): String; + function AsJSONObject: ISuperObject; + procedure AssignFromJSON(const JSON: String); overload; + procedure AssignFromJSON(JSON: ISuperObject); overload; + constructor FromJSON(const JSON: String); overload; + constructor FromJSON(JSON: ISuperObject); overload; + constructor FromJSON(const JSON: String; CreateArgs: Array of TValue; const ConstructMethod: String = 'Create'); overload; + constructor FromJSON(const JSON: ISuperObject; CreateArgs: Array of TValue; const ConstructMethod: String = 'Create'); overload; + end; + + TBaseSuperRecord = class + public + class function AsJSON(Rec: T): String; + class function AsJSONObject(Rec: T): ISuperObject; + class function FromJSON(JSON: String): T; overload; + class function FromJSON(JSON: ISuperObject): T; overload; + end; + TSuperRecord = class(TBaseSuperRecord); + + TJSON = class + public + class function Parse(const Value: String): T; overload; + class function Parse(JSON: ISuperObject): T; overload; + class function Parse(JSON: ISuperArray): T; overload; + class function SuperObject(Value: T): ISuperObject; overload; + {$IFDEF SP_DATASET} + class function SuperObject(Value: TDataSet): ISuperObject; overload; + class function Stringify(Value: TDataSet): String; overload; + {$ENDIF} + class function SuperObject(Value: TValue): ISuperObject; overload; + class function Stringify(Value: T; Indent: Boolean = False; UniversalTime: Boolean = True): String; overload; + class function Stringify(Value: TValue; Indent: Boolean = False; UniversalTime: Boolean = True): String; overload; + end; + + function SO(JSON: String = '{}'): ISuperObject; overload; + function SO(const Args: array of const): ISuperObject; overload; + function SA(JSON: String = '[]'): ISuperArray; overload; + function SA(const Args: array of const): ISuperArray; overload; + +implementation + +var GenericsUnit : String; + +function SO(JSON: String): ISuperObject; +begin + if JSON = '' then JSON := '{}'; + Result := TSuperObject.Create(JSON); +end; + +function SO(const Args: array of const): ISuperObject; +var + I: Integer; + Members: ISuperArray; +begin + Result := TSuperObject.Create; + Members := SA(Args); + if Odd(Members.Length) then + Assert(False); + for I := 0 to (Members.Length div 2) - 1 do + Result.Add(Members.S[I*2], Members.Ancestor[(I*2)+1]); +end; + +function SA(JSON: String): ISuperArray; +begin + Result := TSuperArray.Create(JSON); +end; + +function SA(const Args: array of const): ISuperArray; +var + I: Integer; + SArray: ISuperArray; + SObject: ISuperObject; +begin + Result := TSuperArray.Create; + for I := 0 to High(Args) do + case PVarRec(@Args[I]).VType of + vtInteger : Result.Add(TJSONInteger.Create(PVarRec(@Args[I]).VInteger)); + vtInt64 : Result.Add(TJSONInteger.Create(PVarRec(@Args[I]).VInt64^)); + vtBoolean : Result.Add(TJSONBoolean.Create(PVarRec(@Args[I]).VBoolean)); + {$IFNDEF NEXTGEN} + vtChar : Result.Add(TJSONString.Create(PVarRec(@Args[I]).VWideChar)); + vtString : Result.Add(TJSONString.Create(String(PVarRec(@Args[I]).VString^))); + vtPChar : Result.Add(TJSONString.Create(Char(PVarRec(@Args[I]).VPChar^))); + vtAnsiString: Result.Add(TJSONString.Create(String(PVarRec(@Args[I]).VAnsiString))); + {$ENDIF} + vtWideChar: Result.Add(TJSONString.Create(PVarRec(@Args[I]).VWideChar)); + vtExtended: Result.Add(TJSONFloat.Create(PVarRec(@Args[I]).VExtended^)); + vtCurrency: Result.Add(TJSONFloat.Create(PVarRec(@Args[I]).VCurrency^)); + vtWideString: Result.Add(TJSONString.Create(PWideChar(PVarRec(@Args[I]).VWideString))); + vtUnicodeString: Result.Add(TJSONString.Create(String(PVarRec(@Args[I]).VUnicodeString))); + vtInterface: + if PVarRec(@Args[I]).VInterface = nil then + Result.Add(TJSONNull.Create(False)) + else if IInterface(PVarRec(@Args[I]).VInterface).QueryInterface(ISuperObject, SObject) = 0 then + Result.Add(SObject) + else if IInterface(PVarRec(@Args[I]).VInterface).QueryInterface(ISuperArray, SArray) = 0 then + Result.Add(SArray) + else + Assert(False); + vtPointer : + if PVarRec(@Args[I]).VPointer = nil then + Result.Add(TJSONNull.Create(False)) + else + Result.Add(TJSONInteger.Create(NativeInt(PVarRec(@Args[I]).VPointer))); + vtVariant: + Result.Add(PVarRec(@Args[I]).VVariant^); + vtObject: + if PVarRec(@Args[I]).VPointer = nil then + Result.Add(TJSONNull.Create(False)) + else + Result.Add(TJSONInteger.Create(NativeInt(PVarRec(@Args[I]).VPointer))); + vtClass: + if PVarRec(@Args[I]).VPointer = nil then + Result.Add(TJSONNull.Create(False)) + else + Result.Add(TJSONInteger.Create(NativeInt(PVarRec(@Args[I]).VPointer))); + else + Assert(false); + end; +end; + +{ TSuperObject } + + + +constructor TBaseJSON.Create(JSON: String; const CheckDate: Boolean); +type PInterface = ^IInterface; +var + JVal: IJSONAncestor; + PIntf: PInterface; +begin + FCheckDate := CheckDate; + if (Self.InheritsFrom(TSuperArray)) and (Trim(JSON) = '{}') then JSON := '[]'; + JVal := TJSONObject.ParseJSONValue(JSON, FCheckDate); + if JVal.QueryInterface(GetTypeData(TypeInfo(T)).Guid, FJSONObj) = S_OK then + FInterface := TValue.From(FJSONObj).AsInterface + else + FCasted := JVal +end; + +function TBaseJSON.GetValue(const Name: Typ): C; +begin + if Self.InheritsFrom(TSuperObject) then + with TJSONObject(FInterface).Get(PString(@Name)^) do + if JsonValue is TJSONNull then + Result := Nil + else + Result := JSonValue as C + else + if Self.InheritsFrom(TSuperArray) then + Result := TJSONArray(FInterface).Get(PInteger(@Name)^) as C + else + Result := Nil; +end; + +function TBaseJSON.GetVariant(V: Typ): Variant; +begin + case GetType(V) of + varString: Result := S[V]; + varInt64: Result := I[V]; + varDouble: Result := F[V]; + varBoolean: Result := B[V]; + varDate: Result := D[V]; + else + Result := Variants.Null; + end; +end; + +function TBaseJSON.Member(const Name: Typ): Boolean; +begin + if Self.InheritsFrom(TSuperObject) then + Result := Assigned(TJSONObject(FInterface).Get(PString(@Name)^)) + else + Result := Assigned(TJSONArray(FInterface).Get(PInteger(@Name)^)) +end; + +procedure TBaseJSON.Member(const Name: Typ; const Value: TValue); +var + Pair: IJSONPair; +begin + if Self.InheritsFrom(TSuperObject) then + begin + Pair := TJSONObject(FInterface).Get(PString(@Name)^); + if not Assigned(Pair) then + begin + TJSONObject(FInterface).AddPair(PString(@Name)^, DefaultValueClass(Value) as TJSONAncestor ); + Exit; + end; + if Assigned(Pair.JsonValue) then + Pair.JsonValue := Nil; + Pair.JsonValue := DefaultValueClass(Value) as TJSONAncestor; + end + else + begin + if TJSONArray(FInterface).Count - 1 < PInteger(@Name)^ then + while TJSONArray(FInterface).Count - 1 < PInteger(@Name)^ do + TJSONArray(FInterface).Add(DefaultValueClass(Value) as TJSONAncestor) + else + TJSONArray(FInterface).Index[PInteger(@Name)^] := DefaultValueClass(Value) as TJSONAncestor + end; +end; + +function TBaseJSON.AsJSON(const Ident, UniversalTime: Boolean): String; +var + SBuild: TJSONWriter; +begin + try + SBuild := TJSONWriter.Create(Ident, UniversalTime); + if Assigned(FCasted) then + FCasted.AsJSONString(SBuild) + else + TJSONAncestor(FInterface).AsJSONString(SBuild); + Result := SBuild.ToString; + finally + SBuild.Free; + end; + +end; + +function TBaseJSON.Contains(Key: Typ): Boolean; +begin + Result := GetData(Key) <> Nil; +end; + +function TBaseJSON.ContainsEx(Key: Typ; out Value: IJSONAncestor): Boolean; +begin + Value := GetData(Key); + Result := Value <> Nil; +end; + +constructor TBaseJSON.Create(JSON: T; const CheckDate: Boolean = True); +begin + FJSONObj := JSON; + FCasted := nil; + FCheckDate := CheckDate; + FInterface := TValue.From(JSON).AsInterface; +end; + +constructor TBaseJSON.CreateCasted(Value: IJSONAncestor; const CheckDate: Boolean); +begin +// FJSONObj := Nil; + FInterface := Nil; + FCasted := Value; + FCheckDate := CheckDate; +end; + +constructor TBaseJSON.CreateWithEscape(JSON: String; const CheckDate: Boolean); +begin + Create(LimitedStrToUTF16(JSON), CheckDate); +end; + +function TBaseJSON.DefaultValueClass(const Value): TT; +var + r: TRttiContext; + ty: TRttiType; +begin + if TJSONString.InheritsFrom(TT) then + Result := TJSONString.Create(String(Value)) as TT + else if TJSONInteger.InheritsFrom(TT) then + Result := TJSONInteger.Create(Int64(Value)) as TT + else if TJSONFloat.InheritsFrom(TT) then + Result := TJSONFloat.Create(Double(Value)) as TT + else if TJSONBoolean.InheritsFrom(TT) then + Result := TJSONBoolean.Create(Boolean(Value)) as TT + else if TJSONNull.InheritsFrom(TT) then + Result := TJSONNull.Create(Boolean(Value)) as TT + else if TJSONDateTime.InheritsFrom(TT) then + Result := TJSONDateTime.Create(TDateTime(Value)) as TT + else if TJSONDate.InheritsFrom(TT) then + Result := TJSONDate.Create(TDate(Value)) as TT + else if TJSONTime.InheritsFrom(TT) then + Result := TJSONTime.Create(TTime(Value)) as TT + else if TJSONRaw.InheritsFrom(TT) then + Result := TJSONRaw.Create(String(Value)) as TT + else if TJSONArray.InheritsFrom(TT) then + begin + if Pointer(Value) <> Nil then + Exit(TJSONArray(ISuperArray(Value)) as TT); + Result := TJSONArray.Create as TT; + end + else if TJSONObject.InheritsFrom(TT) then + begin + if Pointer(Value) <> Nil then + Exit(TJSONObject(ISuperObject(Value)) as TT); + Result := TJSONObject.Create as TT; + end + else + begin + r := TRttiContext.Create; + ty := r.GetType(TClass(TT)); + if ty = nil then + exit(Nil); + try + Result := TT(ty.GetMethod('Create').Invoke(ty.AsInstance.MetaclassType, []).AsObject); + except + if Assigned(ty) then + ty.Free; + raise; + end; + r.Free; + end; +end; + +destructor TBaseJSON.Destroy; +begin + inherited; +end; + +function TBaseJSON.GetBoolean(V: Typ): Boolean; +begin + Result := False; + if Member(V) then + Result := GetValue(V).ValueEx; +end; + +function TBaseJSON.GetData(Key: Typ): IJSONAncestor; +var + P: IJsonPair; +begin + if Self.InheritsFrom(TSuperObject) then + begin + P := TJSONObject(FInterface).Get(PString(@Key)^); + if Assigned(P) then + Result := P.JsonValue + else + Result := Nil + end + else + if Self.InheritsFrom(TSuperArray) then + Result := TJSONArray(FInterface).Get(PInteger(@Key)^); +end; + +function TBaseJSON.GetDataType: TDataType; +var + Cast: ICast; +begin + if TValue.From(FJSONObj).AsInterface <> nil then + Cast := TCast.CreateFrom(FJSONObj) + else + if Assigned(FCasted) then + Cast := TCast.Create(FCasted) + else + Exit(dtNil); + Result := Cast.DataType +end; + +function TBaseJSON.GetDate(V: Typ): TDate; +begin + Result := 0; + if Member(V) then + Result := GetValue(V).Value; +end; + +function TBaseJSON.GetDateTime(V: Typ): TDateTime; +begin + Result := 0; + if Member(V) then + Result := GetValue(V).Value; +end; + +function TBaseJSON.GetDouble(V: Typ): Double; +begin + Result := 0; + if Member(V) then + if GetType(V) = varInt64 then + Result := GetValue(V).ValueEx + else + Result := GetValue(V).ValueEx; +end; + +function TBaseJSON.GetInteger(V: Typ): Int64; +begin + Result := 0; + if Member(V) then + Result := GetValue(V).ValueEx; +end; + +function TBaseJSON.GetNull(V: Typ): TMemberStatus; +var + Val: IJSONAncestor; +begin + if ContainsEx(V, Val) then begin + if Val is TJSONNull then + Result := jNull + else + Result := jAssigned + end else + Result := jUnAssigned; +end; + +function TBaseJSON.GetArray(V: Typ): ISuperArray; +var + J: IJSONArray; +begin + Result := Nil; + if not Member(V) then + Member(V, nil); + J := GetValue(V); + Result := TSuperArray.Create(J); +end; + +function TBaseJSON.GetObject(V: Typ): ISuperObject; +begin + Result := Nil; + if not Member(V) then + Member(V, Nil); + + Result := TSuperObject.Create(GetValue(V)); +end; + +function TBaseJSON.GetAncestor(V: Typ): IJSONAncestor; +begin + Result := GetData(V); +end; + +function TBaseJSON.GetString(V: Typ): String; +label + JMP; +begin + Result := ''; + if Member(V) then + if FCheckDate then + case Ancestor[V].DataType of + dtDateTime : Result := GetValue(V).GetAsString; + dtDate : Result := GetValue(V).GetAsString; + dtTime : Result := GetValue(V).GetAsString; + else + goto JMP; + end + else + JMP: Result := GetValue(V).ValueEx; +end; + +function TBaseJSON.GetTime(V: Typ): TTime; +begin + Result := 0; + if Member(V) then + Result := GetValue(V).Value; +end; + +function TBaseJSON.GetType(Key: Typ): TVarType; +var + Temp: IJSONAncestor; +begin + Temp := GetData(Key); + if Temp = Nil then + Result := varUnknown + else if Temp is TJSONString then + Result := varString + else if Temp is TJSONFloat then + Result := varDouble + else if Temp is TJSONInteger then + Result := varInt64 + else if Temp is TJSONNull then + Result := varNull + else if Temp is TJSONObject then + Result := varObject + else if Temp is TJSONArray then + Result := varArray + else if Temp is TJSONBoolean then + Result := varBoolean + else if (Temp is TJSONDateTime) or (Temp is TJSONDate) or (Temp is TJSONTime) then + Result := varDate +end; + +procedure TBaseJSON.SetArray(V: Typ; const Value: ISuperArray); +begin + Member(V, Value.Self ) +end; + +procedure TBaseJSON.SetBoolean(V: Typ; const Value: Boolean); +begin + Member(V, Value) +end; + +procedure TBaseJSON.SetDate(V: Typ; const Value: TDate); +begin + Member(V, Value); +end; + +procedure TBaseJSON.SetDateTime(V: Typ; const Value: TDateTime); +begin + Member(V, Value); +end; + +procedure TBaseJSON.SetDouble(V: Typ; const Value: Double); +begin + Member(V, Value); +end; + +procedure TBaseJSON.SetInteger(V: Typ; const Value: Int64); +begin + Member(V, Value); +end; + +procedure TBaseJSON.SetNull(V: Typ; const Value: TMemberStatus); +begin +end; + +procedure TBaseJSON.SetObject(V: Typ; const Value: ISuperObject); +begin + Member(V, Value.Self ) +end; + +procedure TBaseJSON.SetString(V: Typ; const Value: String); +var + Anc: IJSONAncestor; + dT: TDateTime; + ValType: TDataType; +label + JMP, JERR; +begin + if FCheckDate then + begin + Anc := Ancestor[V]; + if Assigned(Anc) and (Anc.DataType in [dtDateTime..dtTime]) then + begin + if not TJSONDateManager.Check(Value, dT, ValType ) then + JERR: raise SOInvalidDate.Create('Invalid date format.') + else + case ValType of + dtDateTime: Member(V, dT); + dtDate: Member(V, TDate(dT)); + dtTime: Member(V, TTime(dT)); + else + goto JERR; + end; + end + else + goto JMP; + end + else + JMP: Member(V, Value); +end; + +procedure TBaseJSON.SetTime(V: Typ; const Value: TTime); +begin + Member(V, Value); +end; + +procedure TBaseJSON.SetVariant(V: Typ; const Value: Variant); +var + VTyp: TVarType; +begin + if VarIsNull(Value) then + Null[V] := jNull + else + begin + VTyp := GetType(V); + if VTyp = varUnknown then + VTyp := VarType(Value); + case VTyp of + varString, varUString: + S[V] := Value; + varInt64, varInteger, varByte: + I[V] := Value; + varDouble, varCurrency: + F[V] := Value; + varBoolean: + B[V] := Value; + varDate: + D[V] := Value; + varNull: + Null[V] := jNull; + end; + end; +end; + +function TBaseJSON.GetSelf: T; +begin + Result := FJSONObj; +end; + + +{ TSuperObject } + +function TSuperObject.AsArray: ISuperArray; +begin + if not Assigned(FCasted) or not (FCasted is TJSONArray) then + Exit(Nil); + Result := TSuperArray.Create(IJSONArray(FCasted)); +end; + +function TSuperObject.AsObject: ISuperObject; +begin + Result := Self; +end; + +function TSuperObject.Check(const Expr: String): Boolean; +var + IExpr: ISuperExpression; +begin + IExpr := TSuperExpression.Create(FJSONObj, Expr, True); + Result := IExpr.DataType <> dtNil; +end; + +function TSuperObject.AsType: T; +begin + Result := TJSON.Parse(Self); +end; + +function TSuperObject.Cast: ICast; +begin + if Assigned(FCasted) then + Result := TCast.Create(FCasted) + else + Result := TCast.Create(FJSONObj); +end; + +function TSuperObject.Clone: ISuperObject; +begin + Result := SO(AsJSON); +end; + +function TSuperObject.Delete(const Cond: TCondCallBack): ISuperObject; +var + Member: IJSONPair; +begin + Result := Self; + if not Assigned(Cond) then + Exit; + for Member in FJSONObj do + if Cond(TCast.Create(Member)) then + Result.Self.Remove(Member); +end; + +procedure TSuperObject.First; +begin + FOffset := 0; +end; + +function TSuperObject.GetCount: Integer; +begin + Result := FJSONObj.Count; +end; + +function TSuperObject.GetCurrentKey: String; +begin + Result := FJSONObj.Get(FOffset).Name; +end; + +function TSuperObject.GetCurrentValue: IJSONAncestor; +begin + Result := FJSONObj.Get(FOffset).JsonValue; +end; + +function TSuperObject.GetEnumerator: TSuperEnumerator; +begin + Result.Index := -1; + Result.List := TJSONObject(FJSONObj).GetEnumerator +end; + +function TSuperObject.GetEoF: Boolean; +begin + Result := FOffset > Count - 1; +end; + +function TSuperObject.GetExpr(const Code: String): ISuperExpression; +begin + Result := TSuperExpression.Create(FJSONObj, Code); +end; + + +function TSuperObject.GetOffset: Integer; +begin + Result := FOffset; +end; + +function TSuperObject.GetRaw(V: String): String; +begin + Result := GetValue(V).ValueEx; +end; + +function TSuperObject.GetString(V: String): String; +begin + Result := inherited GetString(V); +end; + +procedure TSuperObject.Next; +begin + Inc(FOffset); +end; + +class function TSuperObject.ParseFile(FileName: String; CheckDate: Boolean): TSuperObject; +var + Strm: TFileStream; +begin + Strm := TFileStream.Create(FileName, fmOpenRead, fmShareDenyWrite); + try + Result := ParseStream(Strm, CheckDate); + finally + Strm.Free; + end; +end; + +class function TSuperObject.ParseStream(Stream: TStream; CheckDate: Boolean): TSuperObject; +var + Strm: TStringStream; +begin + Strm := TStringStream.Create; + try + Strm.LoadFromStream(Stream); + Result := TSuperObject.Create(Strm.DataString, CheckDate); + finally + Strm.Free; + end; +end; + +procedure TSuperObject.Remove(Key: String); +begin + FJSONObj.Remove(Key); +end; + +procedure TSuperObject.SaveTo(Stream: TStream; const Ident, UniversalTime: Boolean); +var + S: TStringStream; +begin + S := TStringStream.Create( AsJSON(Ident, UniversalTime) ); + try + S.SaveToStream(Stream); + finally + S.Free; + end; +end; + +procedure TSuperObject.SaveTo(AFile: String; const Ident, UniversalTime: Boolean); +var + S: TStringStream; +begin + S := TStringStream.Create( AsJSON(Ident, UniversalTime) ); + try + S.SaveToFile(AFile); + finally + S.Free; + end; +end; + +procedure TSuperObject.Add(const Key: String; const Data: IJSONAncestor); +begin + FJSONObj.AddPair(Key, Data); +end; + +procedure TSuperObject.SetData(V: String; Data: Variant; AFormatSettings: TFormatSettings); +begin + case VarType(Data) of + varNull: + FJSONObj.AddPair(V, TJSONNull.Create(True)); + + varDate: + FJSONObj.AddPair(V, TJSONString.Create(DateTimeToStr(TDateTime(Data), AFormatSettings))); + + varInteger: + FJSONObj.AddPair(V, TJSONInteger.Create(Integer(Data))); + + varBoolean: + FJSONObj.AddPair(V, TJSONBoolean.Create(Data)); + + varString, varUString: + FJSONObj.AddPair(V, TJSONString.Create(String(Data))); + + varDouble: + FJSONObj.AddPair(V, TJSONFloat.Create(Double(Data))); + + vtCurrency: + FJSONObj.AddPair(V, TJSONFloat.Create(Currency(Data))); + + varInt64: FJSONObj.AddPair(V, TJSONInteger.Create(Int64(Data))); + end; +end; + +procedure TSuperObject.SetNull(V: String; const Value: TMemberStatus); +var + Val: IJSONAncestor; +begin + if Value = jAssigned then + Exit; + with TJSONObject(FJSONObj) do begin + if ContainsEx(V, Val) then + begin + case Value of + jUnAssigned: + Remove(V); + jNull: begin + Remove(V); + AddPair(V, TJSONNull.Create(True)); + end; + end; + end + else + AddPair(V, TJSONNull.Create(True)); + end; +end; + +procedure TSuperObject.SetRaw(V, Value: String); +begin + Member(V, Value); +end; + +procedure TSuperObject.Sort(Comparison: TJSONComparison); +begin + if not Assigned(Comparison) then Exit; + FJSONObj.Sort(function(Left, Right: IJSONPair): Integer + begin + Result := Comparison(TCast.Create(Left), TCast.Create(Right)); + end); +end; + +function TSuperObject.T: TSuperObject; +begin + Result := Self; +end; + +function TSuperObject.Where(const Cond: TCondCallBack): ISuperObject; +var + Member: IJSONPair; +begin + Result := TSuperObject.Create('{}', FCheckDate); + if not Assigned(Cond) then + Exit; + for Member in FJSONObj do + if Cond(TCast.Create(Member)) then + Result.Self.AddPair(Member); +end; + +procedure TSuperObject.SetData(V: String; Data: Variant); +begin + SetData(V, Data, FormatSettings); +end; + +{ TSuperArray } + +procedure TSuperArray.Add(Value: Variant; DateFormat: TFormatSettings); +begin + if VarIsNull(Value) then + begin + TJSONArray(FJSONObj).Add(TJSONNull.Create(True)); + Exit; + end; + + case VarType(Value) of + varDate : + TJSONArray(FJSONObj).Add(TJSONString.Create(DateTimeToStr(TDateTime(Value), DateFormat))); + + varBoolean: + TJSONArray(FJSONObj).Add(TJSONBoolean.Create(Value)); + + else + with TValue.FromVariant(Value) do + case Kind of + tkInteger, tkInt64: + TJSONArray(FJSONObj).Add(TJSONInteger.Create(Int64(Value))); + + tkFloat: + TJSONArray(FJSONObj).Add(TJSONFloat.Create(Double(Value))); + + tkString, tkWChar, tkLString, tkWString, tkUString, tkChar: + TJSONArray(FJSONObj).Add(TJSONString.Create(Value)); + end; + end; + +end; + +procedure TSuperArray.Add(Value: Variant); +begin + Add(Value, FormatSettings); +end; + +function TSuperArray.AsArray: ISuperArray; +begin + Result := Self; +end; + +function TSuperArray.AsObject: ISuperObject; +begin + Result := TSuperObject.CreateCasted(FJSONObj); +end; + +function TSuperArray.AsType: T; +var + Ctx: TRttiContext; + Typ: TRttiType; +begin + Ctx := TRttiContext.Create; + try + Typ := Ctx.GetType(TypeInfo(T)); + if not Assigned(Typ) then + Exit; + if Typ.IsInstance then begin + if TSerializeParse.IsGenerics(Typ) then begin + Result := TValue.From(TSerializeParse.ObjectConstructor(Typ.AsInstance.MetaclassType)).AsType; + TSerializeParse.WriteGeneric(TValue.From(Result).AsObject, Self); + Exit; + end else if TSerializeParse.IsCollection(Typ) then begin + Result := TValue.From(TSerializeParse.ObjectConstructor(Typ.AsInstance.MetaclassType)).AsType; + TSerializeParse.WriteCollection(TValue.From(Result).AsObject as TCollection, Self); + Exit; + end; + end; + raise SOException.Create('Unsupported type.'); + except + Ctx.Free; + raise; + end; +end; + +procedure TSuperArray.Add(Value: IJSONAncestor); +begin + TJSONArray(FJSONObj).Add(Value); +end; + +procedure TSuperArray.Clear; +begin + FJSONObj.Clear; +end; + +function TSuperArray.Clone: ISuperArray; +begin + Result := SA(AsJSON); +end; + +function TSuperArray.Delete(const Cond: TCondCallBack): ISuperArray; +var + Member: IJSONAncestor; +begin + Result := Self; + if not Assigned(Cond) then + Exit; + for Member in FJSONObj do + if Cond(TCast.Create(Member)) then + Result.Self.Remove(Member); +end; + +procedure TSuperArray.Delete(Index: Integer); +begin + TJsonArray(FJSONObj).Remove(Index); +end; + +function TSuperArray.GetEnumerator: TSuperEnumerator; +begin + Result.Index := -1; + Result.List := TJSONArray(FJSONObj).GetEnumerator +end; + +function TSuperArray.GetLength: Integer; +begin + Result := TJSONArray(FJSONObj).Count; +end; + +procedure TSuperArray.SaveTo(Stream: TStream; const Ident, UniversalTime: Boolean); +var + S: TStringStream; +begin + S := TStringStream.Create( AsJSON(Ident, UniversalTime) ); + try + S.SaveToStream(S); + finally + S.Free; + end; +end; + +procedure TSuperArray.SaveTo(AFile: String; const Ident, UniversalTime: Boolean); +var + S: TStringStream; +begin + S := TStringStream.Create( AsJSON(Ident, UniversalTime) ); + try + S.SaveToFile(AFile); + finally + S.Free; + end; +end; + +procedure TSuperArray.SetNull(V: Integer; const aValue: TMemberStatus); +var + Val: IJSONAncestor; +begin + if aValue = jAssigned then + Exit; + with FJSONObj do begin + if ContainsEx(V, Val) then + begin + case aValue of + jUnAssigned: + Remove(V); + jNull: begin + Index[V] := TJSONNull.Create(True); + end; + end; + end + else + Member(V, True); + end; +end; + +procedure TSuperArray.Sort(Comparison: TJSONComparison); +begin + if not Assigned(Comparison) then Exit; + FJSONObj.Sort(function(Left, Right: IJSONAncestor): Integer + begin + Result := Comparison(TCast.Create(Left), TCast.Create(Right)); + end); +end; + +function TSuperArray.T: TSuperArray; +begin + Result := Self; +end; + +function TSuperArray.Where(const Cond: TCondCallBack): ISuperArray; +var + Member: IJSONAncestor; +begin + Result := TSuperArray.Create('[]', FCheckDate); + if not Assigned(Cond) then + Exit; + for Member in FJSONObj do + if Cond(TCast.Create(Member)) then + Result.Self.Add(Member); +end; + +procedure TSuperArray.Add(Value: ISuperObject); +begin + Add(Value.Self); +end; + +procedure TSuperArray.Add(Value: ISuperArray); +begin + Add(Value.Self); +end; + +{ TSuperObjectHelper } + +function TSuperObjectHelper.AsJSON(const Ident: Boolean = False; const UniversalTime: Boolean = False): String; +begin + Result := AsJSONObject.AsJSON(Ident, UniversalTime); +end; + +constructor TSuperObjectHelper.FromJSON(const JSON: String); +begin + FromJSON(JSON, []); +end; + +function TSuperObjectHelper.AsJSONObject: ISuperObject; +var + IResult: ISuperObject; +begin + try + IResult := TSuperObject.Create; + TSerializeParse.ReadObject(Self, IResult); + finally + Result := IResult; + end; +end; + +procedure TSuperObjectHelper.AssignFromJSON(const JSON: String); +begin + TSerializeParse.WriteObject(Self, SO(JSON)); +end; + +procedure TSuperObjectHelper.AssignFromJSON(JSON: ISuperObject); +begin + TSerializeParse.WriteObject(Self, JSON); +end; + +constructor TSuperObjectHelper.FromJSON(const JSON: String; CreateArgs: array of TValue; const ConstructMethod: String); +var + IData: ISuperObject; +begin + IData := TSuperObject.Create(JSON); + FromJSON(IData, CreateArgs, ConstructMethod); +end; + +constructor TSuperObjectHelper.FromJSON(const JSON: ISuperObject; CreateArgs: array of TValue; const ConstructMethod: String); +var + Ctx: TRttiContext; + Typ: TRttiType; + Method: TRttiMethod; +begin + Ctx := TRttiContext.Create; + try + Typ := Ctx.GetType(ClassType); + if not Assigned(Typ) then Exit; + Method := Typ.GetMethod(ConstructMethod); + if (not Assigned(Method)) or not Method.IsConstructor then Exit; + Method.Invoke(Self, CreateArgs); + finally + Ctx.Free; + TSerializeParse.WriteObject(Self, JSON); + end; +end; + +constructor TSuperObjectHelper.FromJSON(JSON: ISuperObject); +begin + FromJSON(JSON, []); +end; + +{ TSerializeParse } + +class procedure TSerializeParse.ReadMembers(Data: Pointer; aType: TRttiType; IJsonData: ISuperObject); +var + Prop: TRttiProperty; + Field: TRttiField; + MemberName: String; + RevalAttribute: REVAL; + Value: TValue; + Attributes: TArray; +begin + for Prop in aType.GetProperties do + begin + if (not (Prop.Visibility in TSerializeParseOptions.Visibilities)) + {$IFDEF AUTOREFCOUNT} or (Prop.Parent.AsInstance.MetaclassType = TObject){$ENDIF} + or (Prop.Parent.AsInstance.MetaclassType = TCollectionItem) then Continue; + + MemberName := Prop.Name; + Attributes := Prop.GetAttributes; + // * Read Disable + if IsDisabled(Attributes) or IsDisabledWrite(Attributes) then + Continue; + + // * Read Alias Name + GetAliasName(Attributes, MemberName); + + Value := Prop.GetValue(Data); + + // * Read Reval Attribute + RevalAttribute := GetREVAL(Attributes); + if (RevalAttribute <> Nil) and (RevalAttribute.CheckEQ(Value)) then + Value := TValue.FromVariant(RevalAttribute.Value); + + ReadMember(MemberName, Prop.PropertyType.Handle, Value, IJSonData); + end; + + for Field in aType.GetFields do + begin + if not (Field.Visibility in TSerializeParseOptions.Visibilities) then Continue; + + MemberName := Field.Name; + Attributes := Field.GetAttributes; + // * Read Disable + if IsDisabled(Attributes) or IsDisabledWrite(Attributes) then + Continue; + + // * Read Alias Name + GetAliasName(Field.GetAttributes, MemberName); + + Value := Field.GetValue(Data); + + // * Read Reval Attribute + RevalAttribute := GetREVAL(Field.GetAttributes); + if (RevalAttribute <> Nil) and (RevalAttribute.CheckEQ(Value)) then + Value := TValue.FromVariant(RevalAttribute.Value); + + ReadMember(MemberName, Field.FieldType.Handle, Value, IJSonData); + end; +end; + +class procedure TSerializeParse.ReadObject(AObject: TObject; IResult: ISuperObject); +var + Ctx: TRttiContext; + Typ: TRttiType; +begin + Ctx := TRttiContext.Create; + try + Typ := Ctx.GetType(AObject.ClassType); + if not Assigned(Typ) then Exit; + ReadMembers(AObject, Typ, IResult) ; + finally + Ctx.Free; + end; +end; + +class procedure TSerializeParse.ReadRecord(Info: PTypeInfo; ARecord: Pointer; IResult: ISuperObject); +var + Ctx: TRttiContext; + Typ: TRttiRecordType; +begin + Ctx := TRttiContext.Create; + try + Typ := Ctx.GetType(Info).AsRecord; + if not Assigned(Typ) then Exit; + ReadMembers(ARecord, Typ, IResult) ; + finally + Ctx.Free; + end; +end; + +class function TSerializeParse.ReadRecordEx(Rec: T): ISuperObject; +var + IResult: ISuperObject; +begin + try + IResult := TSuperObject.Create; + with TValue.From(Rec) do + ReadRecord(TypeInfo, GetReferenceToRawData, IResult); + finally + Result := IResult; + end; +end; + +class function TSerializeParse.CheckObject(Data: Pointer; + Member: TRttiObject; MIdx: Typ; var Obj: TObject): Boolean; +var + rtype: TRttiType; + rawData: Pointer; + Val, ArrVal: TValue; +begin + Obj := Nil; + rawData := GetArrayRawData(Member); + rtype := GetMemberType(Member); + if rawData <> nil then + begin + Obj := GetValue(rawData, Member, MIdx).AsObject; + if (Obj = Nil) and (ObjectConstructorParamCount(rtype.AsInstance.MetaclassType) = 0 ) then + begin + Obj := ObjectConstructor(rtype.AsInstance.MetaclassType); + TValue.Make(@Obj, rtype.Handle , Val); + if Member.ClassType = TRttiDynamicArrayType then begin + TValue.Make(rawData, TRttiDynamicArrayType(Member).Handle, ArrVal); + rawData := ArrVal.GetReferenceToRawArrayElement(PInteger(@MIdx)^) + + end else if Member.ClassType = TRttiArrayType then begin + TValue.Make(rawData, TRttiArrayType(Member).Handle, ArrVal); + rawData := ArrVal.GetReferenceToRawArrayElement(PInteger(@MIdx)^) + + end; + + SetValue(rawData, Member, MIdx, Val); + end; + end + else + begin + Obj := GetValue(Data, Member, '').AsObject; + if (Obj = Nil) and (ObjectConstructorParamCount(rtype.AsInstance.MetaclassType) = 0 ) then + begin + Obj := ObjectConstructor(rtype.AsInstance.MetaclassType); + TValue.Make(@Obj, rtype.Handle , Val); + SetValue(Data, Member, '', Val); + end; + end; + Result := Obj <> nil; +end; + +class procedure TSerializeParse.ClearArrayRawData(Member: TRttiObject); +begin + SetArrayRawData(Member, Nil); +end; + +class constructor TSerializeParse.Create; +begin + FGenericsCache := TObjectDictionary.Create([doOwnsValues]); +end; + +class destructor TSerializeParse.Destroy; +begin + FGenericsCache.Free; +end; + +{$WARNINGS OFF} +class function TSerializeParse.GetArrayRawData(Member: TRttiObject): Pointer; +begin + if Member is TRttiProperty then + Result := TSuperProperty(Member).ArrayRawData + + else if Member is TRttiField then + Result := TSuperField(Member).ArrayRawData + + else if Member is TRttiDynamicArrayType then + Result := TSuperDynArr(Member).ArrayRawData + + else if Member is TRttiArrayType then + Result := TSuperArr(Member).ArrayRawData; + +end; +{$WARNINGS ON} + +class function TSerializeParse.GetAttribute(AttributeType: TAttributeClass; Attributes: TArray): TCustomAttribute; +var + Attr: TCustomAttribute; +begin + for Attr in Attributes do + if Attr is AttributeType then + Exit(Attr); + Result := Nil; +end; + +class function TSerializeParse.GetGenericsCreateArgs(Cls: TRttiType): TArray; +var + Info: TGenericsInfo; +begin + SetLength(Result, 0); + if FGenericsCache.TryGetValue(Cls.AsInstance.MetaclassType, Info) then + Result := Info.CreateArgs + else + if Cls.AsInstance.MetaclassType.InheritsFrom(TStringStream) then + begin + SetLength(Result, 3); + Result[0] := TValue.From(''); + Result[1] := TValue.From(TEncoding.UTF8); + Result[2] := TValue.From(True) + end; + +end; + +class function TSerializeParse.GetGenericType(Cls: TClass): TGenericsType; +var + Temp: String; +begin + Temp := Cls.ClassName; + if Copy(Temp, 1, 6) = 'TList<' then + Result := gtList + else if Copy(Temp, 1, 12) = 'TObjectList<' then + Result := gtObjectList + else + Result := gtNil +end; + +{$WARNINGS OFF} +class function TSerializeParse.GetMemberType(Member: TRttiObject; const GetArray: Boolean): TRttiType; +begin + if Member is TRttiProperty then begin + Result := TRttiProperty(Member).PropertyType; + if GetArray and (TSuperProperty(Member).ArrayRawData <> Nil) then + if Result is TRttiArrayType then + Result := TRttiArrayType(Result).ElementType + else + Result := TRttiDynamicArrayType(Result).ElementType; + + end else if Member is TRttiField then begin + Result := TRttiField(Member).FieldType; + if GetArray and (TSuperField(Member).ArrayRawData <> Nil) then + if Result is TRttiArrayType then + Result := TRttiArrayType(Result).ElementType + else + Result := TRttiDynamicArrayType(Result).ElementType; + + end else if Member is TRttiDynamicArrayType then begin + Result := TRttiDynamicArrayType(Member).ElementType + + end else if Member is TRttiArrayType then begin + Result := TRttiArrayType(Member).ElementType + + end; +end; +{$WARNINGS ON} + +class function TSerializeParse.GetMemberTypeInfo( + Member: TRttiObject; const GetArray: Boolean): PTypeInfo; +begin + Result := GetMemberType(Member, GetArray).Handle +end; + +class function TSerializeParse.GetREVAL(const Attributues: TArray): REVAL; +begin + Result := REVAL(GetAttribute(REVAL, Attributues)); +end; + +class function TSerializeParse.PropGetterType(Prop: TRttiProperty): TPropertyGetterType; +var + Getter: Pointer; +begin + if Prop is TRttiInstanceProperty then begin + Getter := TRttiInstanceProperty(Prop).PropInfo^.GetProc; + if (IntPtr(Getter) and PROPSLOT_MASK) <> PROPSLOT_FIELD then + Exit(pgtMethod); + end; + Result := pgtField; +end; + +class function TSerializeParse.GetValue(Data: Pointer; + Member: TRttiObject; MIdx: Typ): TValue; +begin + if (TypeInfo(Typ) = TypeInfo(Integer) ) and ( GetMemberTypeInfo(Member, False).Kind in [tkDynArray, tkArray] ) then + Result := GetValue(GetArrayRawData(Member), Member, '').GetArrayElement(PInteger(@MIdx)^) + + else if Member is TRttiProperty then begin + if (TRttiProperty(Member).PropertyType.Handle.Kind = tkDynArray) and (PropGetterType(TRttiProperty(Member)) = pgtMethod) then begin + TValue.Make(Nil, TRttiProperty(Member).PropertyType.Handle, Result); + Exit; + end; + Result := TRttiProperty(Member).GetValue(Data) + + end else if Member is TRttiField then + Result := TRttiField(Member).GetValue(Data) + + else if Member is TRttiDynamicArrayType then begin + TValue.Make(GetArrayRawData(Member), TRttiDynamicArrayType(Member).Handle, Result); + Result := Result.GetArrayElement(PInteger(@MIdx)^); + end; +end; + +class function TSerializeParse.IsCollection(Cls: TRttiType): Boolean; +begin + if Cls = Nil then Exit(False); + Result := Cls.AsInstance.MetaclassType.InheritsFrom(TCollection); +end; + +class function TSerializeParse.IsCollection(Cls: TClass): Boolean; +begin + with TRttiContext.Create do + try + Result := IsCollection(GetType(Cls)); + finally + Free; + end; +end; + +class function TSerializeParse.IsDisabled(const Attributes: TArray): Boolean; +begin + Result := GetAttribute(DISABLE, Attributes) <> Nil; +end; + +class function TSerializeParse.IsDisabledRead(const Attributes: TArray): Boolean; +begin + Result := GetAttribute(DISABLEREAD, Attributes) <> Nil; +end; + +class function TSerializeParse.IsDisabledWrite(const Attributes: TArray): Boolean; +begin + Result := GetAttribute(DISABLEWRITE, Attributes) <> Nil; +end; + +class function TSerializeParse.IsGenerics(Cls: TClass): Boolean; +var + Info: TGenericsInfo; + ctx: TRttiContext; + typ: TRttiType; +begin + if FGenericsCache.TryGetValue(Cls, Info) then + Result := Info.IsGeneric + else + begin + Result := False; + ctx := TRttiContext.Create; + try + typ := ctx.GetType(Cls); + if typ <> Nil then + Result := IsGenerics(typ) + finally + ctx.Free; + end; + end; +end; + +class function TSerializeParse.IsGenerics(Cls: TRttiType): Boolean; +var + C: TClass; + Mtd: TRttiMethod; + Info: TGenericsInfo; + Gt: TGenericsType; +begin + Result := False; + C := Cls.AsInstance.MetaclassType; + if FGenericsCache.TryGetValue(C, Info) then + Exit(Info.IsGeneric); + + if C.UnitName = GenericsUnit then begin + Gt := GetGenericType(C); + if Gt in [gtList, gtObjectList] then begin + Mtd := Cls.GetMethod('First'); + if (Mtd <> Nil) and (Mtd.MethodKind = mkFunction) then begin // TList<> or TObjectList<> + Info := TGenericsInfo.Create(C, True, Mtd.ReturnType); + if Gt = gtObjectList then begin + SetLength(Info.CreateArgs, 1); + Info.CreateArgs[0] := True; + end; + FGenericsCache.Add(C, Info); + Exit(True); + end + end; + end; +end; + +class function TSerializeParse.ObjectConstructor( + Instance: TClass): TObject; +var + Ctx: TRttiContext; + Typ: TRttiType; + Mtd: TRttiMethod; + function InEncoding(List: TArray): Boolean; + var + I: Integer; + begin + if Length(List) <> 3 then Exit(False); + for I := 0 to High(List) do + if (List[I].ParamType.TypeKind = tkClass) and (List[I].ParamType.AsInstance.MetaclassType.InheritsFrom(TEncoding)) then + Exit(True); + Result := False; + end; +begin + Ctx := TRttiContext.Create; + try + Typ := Ctx.GetType(Instance); + Mtd := nil; + {$IFNDEF Android or IOS} + if Instance.InheritsFrom(TStringStream) then begin + for Mtd in Typ.GetMethods do + if (CompareText(Mtd.Name, 'Create') = 0) and InEncoding(Mtd.GetParameters) then + Break; + Assert(Assigned(Mtd)); + end + else + {$ENDIF} + Mtd := Typ.GetMethod('Create'); + + Result := Mtd.Invoke(Instance, GetGenericsCreateArgs(Typ)).AsObject; + finally + Ctx.Free; + end; +end; + +class function TSerializeParse.ObjectConstructorParamCount( + Instance: TClass): Integer; +var + Ctx: TRttiContext; + Typ: TRttiType; + Mtd: TRttiMethod; +begin + Result := -1; + Ctx := TRttiContext.Create; + try + Typ := Ctx.GetType(Instance); + if IsGenerics(Typ) then + Exit(0); + if not Assigned(Typ) then Exit; + Mtd := Typ.GetMethod('Create'); + if not Assigned(Mtd) then Exit; + Result := Length( Mtd.GetParameters ); + finally + Ctx.Free; + end; +end; + +class procedure TSerializeParse.ReadCollection(ACollection: TCollection; IResult: ISuperArray); +var + I: Integer; + Item: TCollectionItem; +begin + for I := 0 to ACollection.Count - 1 do + begin + Item := ACollection.Items[I]; + if Item <> Nil then + ReadObject(Item, IResult.O[I]) + end; +end; + +class procedure TSerializeParse.ReadGeneric(AObject: TObject; IResult: ISuperArray); +var + I, Len: Integer; + Info: TGenericsInfo; + Item: TObject; +begin + Info := FGenericsCache[AObject.ClassType]; + Len := Info.Count(AObject); + for I := 0 to Len - 1 do + begin + Item := Info.Item(AObject, I); + if Item <> Nil then + ReadObject(Item, IResult.O[I]) + end; +end; + +class procedure TSerializeParse.ReadMember(Member: Typ; RType: PTypeInfo; MemberValue: TValue; IJsonData: IBaseJSON); +var + I: Integer; + SubVal: TValue; + Obj: TObject; +begin + if MemberValue.IsEmpty and not (RType.Kind in [tkArray, tkDynArray]) then + IJSONDATA.Null[Member] := jNull + else + if RType = TypeInfo(TDateTime) then + IJSonData.D[Member] := MemberValue.AsType + else + if RType = TypeInfo(TDate) then + IJSONData.Date[Member] := MemberValue.AsType + else + if RType = TypeInfo(TTime) then + IJsonData.Time[Member] := MemberValue.AsType + else + case RType.Kind of + tkInteger: + IJSonData.I[Member] := MemberValue.AsInteger; + + tkInt64: + IJSonData.I[Member] := MemberValue.AsInt64; + + tkChar, tkString, tkWChar, tkLString, tkWString, tkUString: + IJSonData.S[Member] := MemberValue.AsString ; + + tkEnumeration: + if MemberValue.TypeInfo = TypeInfo(Boolean) then + IJsonData.B[Member] := Boolean( MemberValue.AsOrdinal ) + else + IJsonData.I[Member] := MemberValue.AsOrdinal; + + tkFloat: + IJsonData.F[Member] := MemberValue.AsExtended; + + tkSet: + ReadSet(MemberValue, IJsonData.A[Member]); + + tkClass, tkPointer: + if MemberValue.IsObject and (MemberValue.AsObject <> Nil) then + begin + Obj := MemberValue.AsObject; + if Obj is TStream then begin + IJSONData.S[Member] := ''; + {$IFDEF SP_STREAM} + ReadStream(TStream(Obj), IJSONData.Ancestor[Member]) + {$ENDIF} + end else if IsGenerics(Obj.ClassType) then + ReadGeneric(Obj, IJSonData.A[Member]) + else if IsCollection(Obj.ClassType) then + ReadCollection(Obj as TCollection, IJSONData.A[Member]) + else + ReadObject(Obj, IJSonData.O[Member]); + end; + + tkVariant: + if TypeInfo(Typ) = TypeInfo(String) then + ReadVariantOfObject(MemberValue.AsVariant, PString(@Member)^, ISuperObject(IJsonData)) + else + if TypeInfo(Typ) = TypeInfo(Integer) then + ReadVariantOfArray(MemberValue.AsVariant, ISuperArray(IJsonData) ); + + tkArray, tkDynArray: + if not MemberValue.IsArray then + IJSONDATA.Null[Member] := jNull + else begin + IJsonData.A[Member]; + with MemberValue do + for I := 0 to GetArrayLength - 1 do begin + SubVal := GetArrayElement(I); + ReadMember( I, SubVal.TypeInfo, SubVal, IJsonData.A[Member]); + end; + end; + + tkRecord: + ReadRecord(MemberValue.TypeInfo, MemberValue.GetReferenceToRawData, IJSonData.O[Member]); + + tkInterface: + if (TypeInfo(ISuperObject) = MemberValue.TypeInfo) then + IJsonData.O[Member] := MemberValue.AsType.Clone + else + if (TypeInfo(ISuperArray) = MemberValue.TypeInfo) then + IJsonData.A[Member] := MemberValue.AsType.Clone; + + end; +end; + +class procedure TSerializeParse.ReadSet(Val: TValue; IJsonData: ISuperArray); +var + S: TIntegerSet; + I: Integer; +begin + Integer(S) := TValueData(Val).FAsULong; + for I := 0 to SizeOf(Integer) * 8 - 1 do + if I in S then + IJsonData.Add(I); +end; + +{$IFDEF SP_STREAM} + +function Base64Encode(const Bytes: TIdBytes): String; +var + Encoder: TIdEncoderMIME; +begin + Encoder := TIdEncoderMIME.Create(nil); + try + Result := Encoder.EncodeBytes(Bytes) + finally + Encoder.Free; + end; +end; + +class procedure TSerializeParse.ReadStream(AStream: TStream; IResult: IJSONAncestor); +var + ByteArray: TIdBytes; +begin + SetLength(ByteArray, AStream.Size); + AStream.Position := 0; + AStream.Read(ByteArray[0], AStream.Size); + (IResult as TJSONString).Value := Base64Encode(ByteArray); +end; +{$ENDIF} + +class procedure TSerializeParse.ReadTValueOfArray(Val: TValue; + IJsonData: ISuperArray); +begin + +end; + +class procedure TSerializeParse.ReadVariantOfArray(Val: Variant; IJsonData: ISuperArray); +begin + IJSonData.Add(Val); +end; + +class procedure TSerializeParse.ReadVariantOfObject(Val: Variant; const Name: String; IJsonData: ISuperObject); +begin + IJsonData.SetData(Name, Val); +end; + + + +class procedure TSerializeParse.SetArrayRawData(Member: TRttiObject; + RawData: Pointer); +begin + if Member is TRttiProperty then + TSuperProperty(Member).ArrayRawData := RawData + + else if Member is TRttiField then + TSuperField(Member).ArrayRawData:= RawData + + else if Member is TRttiDynamicArrayType then + TSuperDynArr(Member).ArrayRawData := RawData + + else if Member is TRttiArrayType then + TSuperArr(Member).ArrayRawData := RawData; +end; + +class procedure TSerializeParse.SetValue(var Data: Pointer; Member: TRttiObject; MIdx: Typ; Val: TValue); +var + RVal: REVAL; +begin + if (TypeInfo(Typ) = TypeInfo(Integer) ) then + case GetMemberTypeInfo(Member, False).Kind of + tkArray: begin + Val.ExtractRawData(Data); + Exit; + end; + + tkDynArray: begin + GetValue(GetArrayRawData(Member), Member, '').SetArrayElement(PInteger(@MIdx)^, Val); + Exit; + end; + end; + + if Member is TRttiProperty then begin + RVal := GetREVAL(TRttiProperty(Member).GetAttributes); + if (RVal <> Nil) and (RVal.CheckEQ(Val)) then + Val := TValue.FromVariant(RVal.Value); + TRttiProperty(Member).SetValue(Data, Val) + + end else if Member is TRttiField then begin + RVal := GetREVAL(TRttiProperty(Member).GetAttributes); + if (RVal <> Nil) and (RVal.CheckEQ(Val)) then + Val := TValue.FromVariant(RVal.Value); + TRttiField(Member).SetValue(Data, Val); + + end else begin + if Val.IsObject then + PPointer(Data)^ := Val.AsObject + else + PPointer(Data)^ := Val.GetReferenceToRawData + end; + +end; + +class procedure TSerializeParse.WriteCollection(ACollection: TCollection; IData: ISuperArray); +var + ItemType: TRttiType; + Item: TCollectionItem; + JMembers: IMember; +begin + with TRttiContext.Create do + try + ItemType := GetType(ACollection.ItemClass) + finally + Free; + end; + + if ItemType = Nil then + raise ESerializeError.CreateFmt('Unknown collection item type (%s).', [ACollection.ItemClass.ClassName]); + + for JMembers in IData do + if JMembers.DataType <> dtObject then + Continue + else begin + Item := ACollection.Add; + WriteMembers(Item, ItemType, JMembers.AsObject); + end; +end; + +class procedure TSerializeParse.WriteGeneric(AObject: TObject; IData: ISuperArray); +var + Info: TGenericsInfo; + Item: TObject; + JMembers: IMember; +begin + if IData.DatatYpe = dtNil then + Exit; + + Info := FGenericsCache[AObject.ClassType]; + for JMembers in IData do + if JMembers.DataType <> dtObject then + Continue + else + begin + Item := ObjectConstructor(Info.Typ.AsInstance.MetaclassType); + WriteMembers(Item, Info.Typ, JMembers.AsObject); + Info.AddVal(AObject, Item); + end; +end; + +class procedure TSerializeParse.WriteMember(Data: Pointer; Member: Typ; + RType: PTypeInfo; MemberValue: TRttiObject; IJsonData: IBaseJSON); +var + I: Integer; + J: NativeInt; + P: Pointer; + V: Variant; + SubVal: TValue; + SubArr: ISuperArray; + DataType: TDataType; + Obj: TObject; + Ancestor: IJSONAncestor; +begin + if not IJsonData.Contains(Member) then + Exit; + + if (RType = TypeInfo(TDateTime)) or (RType = TypeInfo(TDate)) or (RType = TypeInfo(TTime)) then + begin + Ancestor := IJSONData.Ancestor[Member]; + if not (Ancestor.DataType in [dtNull, dtString]) then + SetValue(Data, MemberValue, Member, TValue.From(Ancestor.AsVariant)) + end + else + case RType.Kind of + tkInteger: + SetValue(Data, MemberValue, Member, Integer(IJSonData.I[Member])); + + tkInt64: + SetValue(Data, MemberValue, Member, IJSonData.I[Member]); + + tkChar, tkWChar: + if IJsonData.S[Member] > '' then + SetValue(Data, MemberValue, Member, TValue.From(IJSonData.S[Member]{$IFDEF XE2UP}.Chars[CharIndex]{$ELSE}[CharIndex]{$ENDIF})); + + tkString,tkLString, tkWString, tkUString: + SetValue(Data, MemberValue, Member, IJSonData.S[Member]); + + tkEnumeration: + if GetMemberTypeInfo(MemberValue) = TypeInfo(Boolean) then + begin + SetValue(Data, MemberValue, Member, IJSONData.B[Member]); + end + else + begin + TValue.Make(IJSONData.I[Member], GetMemberTypeInfo(MemberValue), SubVal ); + SetValue(Data, MemberValue, Member, SubVal); + end; + + + tkFloat: + SetValue(Data, MemberValue, Member, IJsonData.F[Member]); + + tkSet: + WriteSet(Data, MemberValue, IJsonData.A[Member]); + + tkClass: + begin + if CheckObject(Data, MemberValue, Member, Obj) then + if (Obj is TStream) then begin + {$IFDEF SP_STREAM} + if IJSONData.Null[Member] = jAssigned then + WriteStream(TStream(Obj), IJSonData.Ancestor[Member]) + {$ENDIF} + end else if IsGenerics(Obj.ClassType) then + WriteGeneric(Obj, IJSONData.A[Member]) + else if IsCollection(Obj.ClassType) then + WriteCollection(Obj as TCollection, IJSONData.A[Member]) + else + WriteObject(Obj, IJSonData.O[Member]); + end; + + tkVariant: + begin + V := IJSONData.V[Member]; + if not VarIsNull(V) then + begin + TValue.Make(@V, GetMemberTypeInfo(MemberValue), SubVal); + SetValue(Data, MemberValue, Member, SubVal); + end; + end; + + tkDynArray, tkArray: + begin + if IJSonData.Null[Member] = jAssigned then + begin + SetArrayRawData(MemberValue, Data); + try + DataType := IJSONData.DataType; + if DataType = dtArray then begin + SubArr := IJSONData.AsArray; + J := IJsonData.AsArray.Length; + if RType.Kind = tkDynArray then + DynArraySetLength(PPointer(Data)^, RType, 1, @J); + TValue.Make(Data, Rtype, SubVal); + + end else begin + J := IJSonData.A[Member].Length; + SubVal := GetValue(Data, MemberValue, Member); + if RType.Kind = tkDynArray then begin + DynArraySetLength(PPointer(SubVal.GetReferenceToRawData)^, SubVal.TypeInfo, 1, @J); + if (MemberValue is TRttiProperty) and (PropGetterType(TRttiProperty(MemberValue)) = pgtMethod) then begin + WriteMember(SubVal.GetReferenceToRawData, + 0, + RType, + TRttiProperty(MemberValue).PropertyType, + IJSONData.A[Member]); + SetValue(Data, MemberValue,'', SubVal ); + Exit; + + end else + SetValue(Data, MemberValue,'', SubVal ); + + end; + end; + + for I := 0 to J-1 do begin + if DataType <> dtArray then + SubArr := IJSONData.A[Member]; + WriteMember + (SubVal.GetReferenceToRawArrayElement(I), + I, + GetMemberTypeInfo(MemberValue), + MemberValue, + SubArr); + end; + + if DataType = dtArray then + SubVal.ExtractRawData(Data) + else SetValue(Data, MemberValue,'', SubVal ); + + finally + ClearArrayRawData(MemberValue); + end; + end; + end; + + tkRecord: + begin + if (MemberValue.ClassType = TRttiDynamicArrayType) or (MemberValue.ClassType = TRttiArrayType) then + WriteRecord(GetMemberTypeInfo(MemberValue), Data, IJSonData.O[Member]) + else begin + P := IValueData(TValueData( GetValue(Data, MemberValue, Member) ).FValueData).GetReferenceToRawData; + WriteRecord(GetMemberTypeInfo(MemberValue), P, IJSonData.O[Member]); + TValue.Make(P, GetMemberTypeInfo(MemberValue), SubVal); + SetValue(Data, MemberValue, Member, SubVal ); + end; + end; + + tkInterface: + if (TypeInfo(ISuperObject) = GetMemberTypeInfo(MemberValue)) And (IJsonData.Ancestor[Member].DataType = dtObject) then + SetValue(Data, MemberValue, Member, TValue.From(IJsonData.O[Member].Clone)) + else + if (TypeInfo(ISuperArray) = GetMemberTypeInfo(MemberValue)) And (IJsonData.Ancestor[Member].DataType = dtArray) then + SetValue(Data, MemberValue, Member, TValue.From(IJsonData.A[Member].Clone)); + end; +end; + +class procedure TSerializeParse.GetAliasName(const Attributes: TArray; var Result: String); +var + Attr: Alias; +begin + Attr := Alias(GetAttribute(Alias, Attributes)); + if Assigned(Attr) then + Result := Attr.Name; +end; + +class procedure TSerializeParse.WriteMembers(Data: Pointer; aType: TRttiType; + IJsonData: ISuperObject); +var + Prop: TRttiProperty; + Field: TRttiField; + MemberName: String; +begin + for Prop in aType.GetProperties do + if Prop.PropertyType <> Nil then + begin + if not (Prop.Visibility in TSerializeParseOptions.Visibilities) then Continue; + MemberName := Prop.Name; + if IsDisabled(Prop.GetAttributes) or IsDisabledRead(Prop.GetAttributes) then + Continue; + GetAliasName(Prop.GetAttributes, MemberName); + WriteMember(Data, MemberName, Prop.PropertyType.Handle, TSuperProperty(Prop), IJSonData); + end; + for Field in aType.GetFields do + if Field.FieldType <> Nil then + begin + if not (Field.Visibility in TSerializeParseOptions.Visibilities) then Continue; + MemberName := Field.Name; + if IsDisabled(Field.GetAttributes) or IsDisabledRead(Field.GetAttributes) then + Continue; + GetAliasName(Field.GetAttributes, MemberName); + WriteMember(Data, MemberName, Field.FieldType.Handle, TSuperField(Field), IJSonData); + end; +end; + +class procedure TSerializeParse.WriteObject(AObject: TObject; + IData: ISuperObject); +var + Ctx: TRttiContext; + Typ: TRttiType; +begin + Ctx := TRttiContext.Create; + try + Typ := Ctx.GetType(AObject.ClassType); + if (not Assigned(Typ)) or (IData.DataType = dtNil) then Exit; + WriteMembers(AObject, Typ, IData); + finally + Ctx.Free; + end; +end; + +class procedure TSerializeParse.WriteRecord(Info: PTypeInfo; ARecord: Pointer; + IData: ISuperObject); +var + Ctx: TRttiContext; + Typ: TRttiType; +begin + Ctx := TRttiContext.Create; + try + Typ := Ctx.GetType(Info); + if (not Assigned(Typ)) or (IData.DataType = dtNil) then + Exit; + WriteMembers(ARecord, Typ, IData); + finally + Ctx.Free; + end; +end; + +class procedure TSerializeParse.WriteRecordEx(Rec: T; + IData: ISuperObject); +begin + with TValue.From(Rec) do + WriteRecord(TypeInfo, GetReferenceToRawData, IData); +end; + +class procedure TSerializeParse.WriteSet(Data: Pointer; Member: TRttiObject; + IJSONData: ISuperArray); +var + Sets: TIntegerSet; + I: Integer; + Val: TValue; +begin + Sets := []; + for I := 0 to IJSONData.Length -1 do + Include(Sets, IJSONData.I[I]); + TValue.Make(Integer(Sets), GetMemberTypeInfo(Member), Val); + SetValue(Data, Member, '', Val); +end; + +{$IFDEF SP_STREAM} +function Base64Decode(const EncodedText: string): TBytesStream; +var + Decoder: TIdDecoderMIME; +begin + Decoder := TIdDecoderMIME.Create(nil); + try + Result := TBytesStream.Create; + try + Decoder.DecodeBegin(Result); + Decoder.Decode(EncodedText); + Decoder.DecodeEnd; + except + Result.Free; + raise; + end; + finally + Decoder.Free; + end; +end; + +class procedure TSerializeParse.WriteStream(AStream: TStream; IData: IJSONAncestor); +var + Setter: TBytesStream; +begin + Setter := Base64Decode((IData as TJSONString).Value); + try + Setter.Position := 0; + AStream.CopyFrom(Setter, Setter.Size); + finally + Setter.Free; + end; +end; +{$ENDIF} + +{ TSuperRecord } + +class function TBaseSuperRecord.AsJSON(Rec: T): String; +begin + Result := AsJSONObject(Rec).AsJSON; +end; + +class function TBaseSuperRecord.FromJSON(JSON: String): T; +begin + Result := FromJSON(SO(JSON)); +end; + +class function TBaseSuperRecord.AsJSONObject(Rec: T): ISuperObject; +begin + Result := XSuperObject.TSerializeParse.ReadRecordEx(Rec); +end; + +class function TBaseSuperRecord.FromJSON(JSON: ISuperObject): T; +var + Val: TValue; + P: Pointer; +begin + FillChar(Result, SizeOf(T), 0); + Val := TValue.From(Result); + P := IValueData(TValueData(Val).FValueData).GetReferenceToRawData; + TSerializeParse.WriteRecord(Val.TypeInfo, P, JSON); + Result := T(P^); +end; + +{ TJSONValueHelper } + +function TJSONValueHelper.ValueEx: Variant; +var + Valuable: Boolean; + pV: PTypeInfo; +const + Int = 0; + Str = ''; +begin + Valuable := (Self <> Nil) and not isNull; + pV := TypeInfo(T); + if pV = TypeInfo(Int64) then begin + if Valuable then + Result := (Self as TJSONInteger).Value + else + Result := Int; + end + else + if pV = TypeInfo(Double) then begin + if Valuable then + Result := (Self as TJSONFloat).Value + else + Result := Int + end + else + if pV = TypeInfo(Boolean) then begin + if Valuable then + Result := (Self as TJSONBoolean).Value + else + Result := False + end + else + if pV = TypeInfo(String) then + if Valuable then + Result := (Self as TJSONString).Value + else + Result := Str +end; + +{ TSuperExpression } + +constructor TSuperExpression.Create(Base: IJSONAncestor; const Expr: String; const BlockException: Boolean); +begin + FInterpreter := TJSONInterpreter.Create(Expr, Base, BlockException); + inherited Create(FInterpreter.ReadExpression); +end; + +destructor TSuperExpression.Destroy; +begin + FInterpreter.Free; + inherited; +end; + +{ TCast } + +constructor TCast.Create(Base: IJSONAncestor); +begin + FJSON := Base; + FName := ''; +end; + +constructor TCast.Create(Base: IJSONPair); +begin + FJSON := Base.JSONValue; + FName := Base.Name; +end; + +class function TCast.CreateFrom(Base: T): ICast; +var + IFace: IInterface; +begin + IFace := TValue.From(Base).AsInterface; + if IFace is TJSONAncestor then + Result := TCast.Create(IFace as TJSONAncestor) + else + if IFace is TJSONPair then + Result := TCast.Create(IFace as TJSONPair) + else + Result := TCast.Create(TJSONAncestor(Nil)); +end; + +destructor TCast.Destroy; +begin + FJSON := Nil; + inherited; +end; + +function TCast.GetArray: ISuperArray; +begin + if not Assigned(FJSON) then + Result := Nil + else + Result := TSuperArray.Create(FJSON as TJSONArray); +end; + +function TCast.GetBoolean: Boolean; +begin + if not Assigned(FJSON) then + Result := False + else + Result := TJSONBoolean(FJSON).Value; +end; + +function TCast.GetDataType: TDataType; +begin + if FJSON = Nil then + Result := dtNil + else if FJSON is TJSONNull then + Result := dtNull + else if FJSON is TJSONString then + Result := dtString + else if FJSON is TJSONInteger then + Result := dtInteger + else if FJSON is TJSONFloat then + Result := dtFloat + else if FJSON is TJSONBoolean then + Result := dtBoolean + else if FJSON is TJSONObject then + Result := dtObject + else if FJSON is TJSONArray then + Result := dtArray + else if FJSON is TJSONDateTime then + Result := dtDateTime + else if FJSON is TJSONDate then + Result := dtDate + else if FJSON is TJSONTime then + Result := dtTime + else + raise SOException.Create('Unknown JSON Type'); +end; + +function TCast.GetDate: TDate; +begin + if not Assigned(FJSON) then + Result := 0 + else + Result := TJSONDate(FJSON).Value; +end; + +function TCast.GetDateTime: TDateTime; +begin + if not Assigned(FJSON) then + Result := 0 + else + Result := TJSONDateTime(FJSON).Value; +end; + +function TCast.GetFloat: Double; +begin + if not Assigned(FJSON) then + Result := 0 + else + if FJSON is TJSONInteger then + Result := TJSONInteger(FJSON).Value + else + Result := TJSONFloat(FJSON).Value; +end; + +function TCast.GetInteger: Int64; +begin + if not Assigned(FJSON) then + Result := 0 + else + if DataType <> dtInteger then + Result := StrToIntDef(VarToStr(GetVariant), 0) + else + Result := TJSONInteger(FJSON).Value; +end; + +function TCast.GetName: String; +begin + Result := FName; +end; + +function TCast.GetObject: ISuperObject; +begin + if not Assigned(FJSON) then + Result := Nil + else + Result := TSuperObject.Create(FJSON as TJSONObject); +end; + +function TCast.GetString: String; +begin + if not Assigned(FJSON) then + Result := '' + else + if FJSON is TJSONString then + Result := TJSONString(FJSON).Value + else + Result := VarToStr(FJSON.AsVariant); +end; + +function TCast.GetTime: TTime; +begin + if not Assigned(FJSON) then + Result := 0 + else + Result := TJSONTime(FJSON).Value; +end; + +function TCast.GetVariant: Variant; +begin + case DataType of + dtNil, dtNull, dtObject, dtArray: + Result := Null; + dtString: + Result := AsString; + dtInteger: + Result := AsInteger; + dtFloat: + Result := AsFloat; + dtBoolean: + Result := AsBoolean; + dtDateTime: + Result := AsDateTime; + dtDate: + Result := AsDate; + dtTime: + Result := AsTime; + end; +end; + +procedure TCast.SetBoolean(const Value: Boolean); +begin + if not Assigned(FJSON) then Exit; + TJSONBoolean(FJSON).Value := Value; +end; + +procedure TCast.SetDate(const Value: TDate); +begin + if not Assigned(FJSON) then Exit; + TJSONDate(FJSON).Value := Value; + +end; + +procedure TCast.SetDateTime(const Value: TDateTime); +begin + if not Assigned(FJSON) then Exit; + TJSONDateTime(FJSON).Value := Value; +end; + +procedure TCast.SetFloat(const Value: Double); +begin + if not Assigned(FJSON) then Exit; + TJSONFloat(FJSON).Value := Value; +end; + +procedure TCast.SetInteger(const Value: Int64); +begin + if not Assigned(FJSON) then Exit; + TJSONInteger(FJSON).Value := Value; +end; + +procedure TCast.SetString(const Value: String); +begin + if not Assigned(FJSON) then Exit; + TJSONString(FJSON).Value := Value; +end; + + +procedure TCast.SetTime(const Value: TTime); +begin + if not Assigned(FJSON) then Exit; + TJSONTime(FJSON).Value := Value; +end; + +procedure TCast.SetVariant(const Value: Variant); +begin + case DataType of + dtString: + AsString := VarToStr(Value); + dtInteger: + AsInteger := Value; + dtFloat: + AsFloat := Value; + dtBoolean: + AsBoolean := Value; + dtDateTime: + AsDateTime := Value; + dtDate: + AsDate := Value; + dtTime: + AsTime := Value; + end; +end; + +function TCast.ToAnsiString(const Ident, UniversalTime: Boolean): Ansistring; +begin + Result := Self.ToString(ident,UniversalTime); +end; + +function TCast.ToString(const Ident, UniversalTime: Boolean): String; +var + SBuilder: TJSONWriter; +begin + SBuilder := TJSONWriter.Create(Ident, UniversalTime); + try + FJSON.AsJSONString(SBuilder); + Result := SBuilder.ToString; + finally + SBuilder.Free; + end; +end; + +{ TJSONEnumerator } + +function TSuperEnumerator.GetCurrent: ICast; +begin + Result := TCast.CreateFrom(List.List[Index]); +end; + +function TSuperEnumerator.MoveNext: Boolean; +begin + Result := Index < List.List.Count - 1; + if Result then + Inc(Index); +end; + +{ TBase } + +function TBase.AsArray: ISuperArray; +begin + Result := Nil; +end; + +function TBase.AsObject: ISuperObject; +begin + Result := Nil; +end; + +{ TGenericsInfo } + +procedure TGenericsInfo.AddVal(Instance: TObject; Val: TValue); +begin + FAddMethod.Invoke(Instance, [Val]); +end; + +function TGenericsInfo.Count(Instance: TObject): Integer; +begin + Result := FCountProperty.GetValue(Instance).AsInteger; +end; + +constructor TGenericsInfo.Create(GenericClass: TClass;const AIsGeneric: Boolean; AType: TRttiType); +begin + IsGeneric := AIsGeneric; + Typ := AType; + if GenericClass <> Nil then + begin + FContext := TRttiContext.Create; + FType := FContext.GetType(GenericClass); + FAddMethod := FType.GetMethod('Add'); + FCountProperty := FType.GetProperty('Count'); + FGetItemMethod := FType.GetIndexedProperty('Items'); + end +end; + +destructor TGenericsInfo.Destroy; +begin + if IsGeneric then + FContext.Free; + inherited; +end; + +function TGenericsInfo.Item(Instance: TObject; const Index: Integer): TObject; +begin + Result := FGetItemMethod.GetValue(Instance, [Index]).AsObject; +end; + +{ ReNameField } + +constructor Alias.Create(const AName: String); +begin + FName := AName; +end; + +{ REVAL } + +function REVAL.CheckEQ(Val: TValue): Boolean; +begin + case FOption of + roNone: + Result := Val.AsVariant = FEqual; + roEmptyArrayToNull: + Result := Val.GetArrayLength = 0; + else raise Exception.CreateFmt('Unknown option: %d', [Ord(FOption)]); + end; +end; + +constructor REVAL.Create(EQVal, NewVal: Integer); +begin + FOption := roNone; + FEqual := EQVal; + FValue := NewVal; +end; + +constructor REVAL.Create(EQVal, NewVal: String); +begin + FOption := roNone; + FEqual := EQVal; + FValue := NewVal; +end; + +constructor REVAL.Create(EQVal, NewVal: Double); +begin + FOption := roNone; + FEqual := EQVal; + FValue := NewVal; +end; + +constructor REVAL.Create(EQVal: String); +begin + FOption := roNone; + FEqual := EQVal; + FValue := Variants.Null; +end; + +constructor REVAL.Create(EQVal, NewVal: Boolean); +begin + FOption := roNone; + FEqual := EQVal; + FValue := NewVal; +end; + +constructor REVAL.Create(EQVal: Integer); +begin + FOption := roNone; + FEqual := EQVal; + FValue := Variants.Null; +end; + +constructor REVAL.Create(EQVal: Double); +begin + FOption := roNone; + FEqual := EQVal; + FValue := Variants.Null; +end; + +constructor REVAL.Create(EQVal: Boolean); +begin + FOption := roNone; + FEqual := EQVal; + FValue := Variants.Null; +end; + +constructor REVAL.Create(Option: TRevalOption); +const + EMPTY_DATE: TDateTime = 0; +begin + FOption := Option; + case FOption of + roEmptyArrayToNull: + FValue := Variants.Null; + end; +end; + +{ TSerializeParseOptions } + +class constructor TSerializeParseOptions.Create; +begin + FVisibilities := [mvPublic, mvPublished]; +end; + +{ TSerialize } + +class function TJSON.SuperObject(Value: TValue): ISuperObject; +var + Ctx: TRttiContext; + Typ: TRttiType; + I: Integer; + SubVal: TValue; + _Array: ISuperArray; +begin + Ctx := TRttiContext.Create; + try + Typ := Ctx.GetType(Value.TypeInfo); + if not Assigned(Typ) then Exit(SO); + + if Typ.IsRecord then begin + Result := TSuperObject.Create; + TSerializeParse.ReadRecord(Value.TypeInfo, Value.GetReferenceToRawData, Result) + + end else if Typ.IsInstance then begin + Result := TSuperObject.Create; + TSerializeParse.ReadObject(Value.AsObject, Result); + + end else if Typ.TypeKind = tkInterface then begin + if Typ.Handle = TypeInfo(ISuperObject) then + Result := Value.AsType + else if Typ.Handle = TypeInfo(ISuperArray) then + Result := TSuperObject.CreateCasted(Value.AsType.Self) + + end else if Typ.Handle = TypeInfo(TDateTime) then begin + Result := TSuperObject.CreateCasted(TJSONDateTime.Create(Value.AsExtended)); + + end else if Typ.Handle = TypeInfo(TDate) then begin + Result := TSuperObject.CreateCasted(TJSONDate.Create(Value.AsExtended)); + + end else if Typ.Handle = TypeInfo(TTime) then begin + Result := TSuperObject.CreateCasted(TJSONTime.Create(Value.AsExtended)); + + end else if Typ.Handle = TypeInfo(Boolean) then begin + Result := TSuperObject.CreateCasted(TJSONBoolean.Create(Value.AsBoolean)); + + end else begin + case Typ.TypeKind of + tkInteger: + Result := TSuperObject.CreateCasted(TJSONInteger.Create(Int64(Value.AsInteger))); + + tkFloat: + Result := TSuperObject.CreateCasted(TJSONFloat.Create(Value.AsExtended)); + + tkInt64: + Result := TSuperObject.CreateCasted(TJSONInteger.Create(Value.AsInt64)); + + tkString: + Result := TSuperObject.CreateCasted(TJSONString.Create(Value.AsString)); + + tkDynArray, tkArray: begin + Result := TSuperObject.CreateCasted(TJSONArray.Create); + _Array := Result.AsArray; + for I := 0 to Value.GetArrayLength - 1 do begin + SubVal := Value.GetArrayElement(I); + TSerializeParse.ReadMember( + I, + SubVal.TypeInfo, + SubVal, + _Array); + end; + end; + + tkUString: + Result := TSuperObject.CreateCasted(TJSONString.Create(Value.AsString)); + end; + + end; + except + Ctx.Free; + raise; + end; +end; + + +class function TJSON.Parse(JSON: ISuperObject): T; +var + Ctx: TRttiContext; + Typ: TRttiType; + DType: TDataType; + _Array: ISuperArray; + _PResult: Pointer; + I: Integer; +type PTime = ^TTime; +begin + Ctx := TRttiContext.Create; + try + Typ := Ctx.GetType(TypeInfo(T)); + if not Assigned(Typ) then + Exit(Default(T)); + + if Typ.IsRecord then + Result := TBaseSuperRecord.FromJSON(JSON) + + else if Typ.IsInstance then begin + Result := Typ.GetMethod('Create').Invoke(Typ.AsInstance.MetaclassType, []).AsType; + TSerializeParse.WriteObject(TValue.From(Result).AsObject, JSON); + + end else if Typ.Handle = TypeInfo(TDateTime) then begin + PDateTime(@Result)^ := JSON.Cast.AsDateTime + + end else if Typ.Handle = TypeInfo(TDate) then begin + PDate(@Result)^ := JSON.Cast.AsDate + + end else if Typ.Handle = TypeInfo(TTime) then begin + PTime(@Result)^ := JSON.Cast.AsTime + + end else if Typ.Handle = TypeInfo(Boolean) then begin + PBoolean(@Result)^ := JSON.Cast.AsBoolean + + end else begin + case Typ.TypeKind of + tkInteger: + PInteger(@Result)^ := Integer(JSON.Cast.AsInteger); + + tkFloat: + PDouble(@Result)^ := JSON.Cast.AsFloat; + + tkInt64: + PInt64(@Result)^ := JSON.Cast.AsInteger; + + tkString: + {$IFDEF NEXTGEN} + PString(@Result)^ := JSON.Cast.AsString; + {$ELSE} + PAnsiString(@Result)^ := AnsiString(JSON.Cast.AsString); + {$ENDIF} + + tkDynArray, tkArray: begin + _Array := JSON.AsArray; + _PResult := @Result; + TSerializeParse.WriteMember( + _PResult, + 0, + Typ.Handle, + Typ, + _Array); + end; + + tkUString: + PString(@Result)^ := JSON.Cast.AsString; + end; + + end; + except + Ctx.Free; + raise; + end; +end; + + +class function TJSON.Parse(JSON: ISuperArray): T; +var + Ctx: TRttiContext; + _PResult: Pointer; + Typ: TRttiType; +begin + Ctx := TRttiContext.Create; + try + Typ := Ctx.GetType(TypeInfo(T)); + if not Assigned(Typ) then Exit(Default(T)); + _PResult := @Result; + TSerializeParse.WriteMember( + _PResult, + 0, + Typ.Handle, + Typ, + JSON); + finally + Ctx.Free; + end; +end; + +class function TJSON.Stringify(Value: TValue; Indent, UniversalTime: Boolean): String; +begin + Result := SuperObject(Value).AsJSON(Indent, UniversalTime); +end; + +{$IFDEF SP_DATASET} + +class function TJSON.Stringify(Value: TDataSet): String; +begin + Result := SuperObject(Value).AsJSON(False, True); +end; + +class function TJSON.SuperObject(Value: TDataSet): ISuperObject; +var + I, J, Z: Integer; + Rec: ISuperObject; + Return: ISuperArray; + Bookmark: TBookmark; + ABytes: TArray; +begin + Return := SA; + Bookmark := Value.Bookmark; + Value.DisableControls; + try + if not Value.Active then + Value.Active := True; + Value.First; + for I := 0 to Value.RecordCount - 1 do begin + Rec := SO; + for J := 0 to Value.FieldCount - 1 do with Value.Fields.Fields[J] do begin + case DataType of + ftString: + Rec.S[FieldName] := AsString; + ftSmallint, ftInteger: + Rec.I[FieldName] := AsInteger; + ftBoolean: + Rec.B[FieldName] := AsBoolean; + ftFloat: + Rec.F[FieldName] := AsFloat; + ftCurrency: + Rec.F[FieldName] := AsCurrency; + ftDate: + Rec.Date[FieldName] := TDate(AsDateTime); + ftTime: + Rec.Time[FieldName] := TTime(AsDateTime); + ftDateTime: + Rec.D[FieldName] := AsDateTime; + ftWideString: + Rec.S[FieldName] := AsWideString; + ftLargeint, ftAutoInc: + Rec.I[FieldName] := AsLargeInt; + ftVariant: + Rec.V[FieldName] := AsVariant; + ftShortint: + Rec.I[FieldName] := AsInteger; + ftByte: begin + ABytes := AsBytes; + with Rec.A[FieldName] do + for Z := 0 to High(ABytes) do + Add(ABytes[Z]); + end; + ftExtended: + Rec.D[FieldName] := AsExtended; + end; + end; + Return.Add(Rec); + Value.Next; + end; + finally + Value.Bookmark := Bookmark; + Value.EnableControls; + end; + Result := TSuperObject.CreateCasted(Return.Self); +end; +{$ENDIF} + +class function TJSON.Stringify(Value: T; Indent: Boolean; UniversalTime: Boolean): String; +begin + Result := SuperObject(Value).AsJSON(Indent, UniversalTime); +end; + +class function TJSON.Parse(const Value: String): T; +begin + Result := Parse(SO(Value)); +end; + +class function TJSON.SuperObject(Value: T): ISuperObject; +begin + Result := SuperObject(TValue.From(Value)); +end; + +initialization + + GenericsUnit := TEnumerable.UnitName; + +end. diff --git a/v1.4.4/Exemplo/midias/DocTeste.txt b/v1.4.4/Exemplo/midias/DocTeste.txt new file mode 100644 index 0000000..868f99c --- /dev/null +++ b/v1.4.4/Exemplo/midias/DocTeste.txt @@ -0,0 +1 @@ +Documento de Teste diff --git a/v1.4.4/Exemplo/midias/Fundo3.png b/v1.4.4/Exemplo/midias/Fundo3.png new file mode 100644 index 0000000..23eb59b Binary files /dev/null and b/v1.4.4/Exemplo/midias/Fundo3.png differ diff --git a/v1.4.4/Exemplo/midias/IMG_Logo_TInjectTelegram_c_Fundo.png b/v1.4.4/Exemplo/midias/IMG_Logo_TInjectTelegram_c_Fundo.png new file mode 100644 index 0000000..c51f9ee Binary files /dev/null and b/v1.4.4/Exemplo/midias/IMG_Logo_TInjectTelegram_c_Fundo.png differ diff --git a/v1.4.4/Exemplo/midias/TesteAnimation.mp4 b/v1.4.4/Exemplo/midias/TesteAnimation.mp4 new file mode 100644 index 0000000..2559711 Binary files /dev/null and b/v1.4.4/Exemplo/midias/TesteAnimation.mp4 differ diff --git a/v1.4.4/Exemplo/uPrincipal.dfm b/v1.4.4/Exemplo/uPrincipal.dfm new file mode 100644 index 0000000..a075e50 --- /dev/null +++ b/v1.4.4/Exemplo/uPrincipal.dfm @@ -0,0 +1,4238 @@ +object Form1: TForm1 + Left = 0 + Top = 0 + Caption = + 'Example of use of TinjectTelegambot for v1.4.4 (by Ruan Diego La' + + 'cerda Menezes)' + ClientHeight = 518 + ClientWidth = 740 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + Position = poDesktopCenter + PrintScale = poNone + Visible = True + OnClose = FormClose + OnCreate = FormCreate + OnShow = FormShow + TextHeight = 13 + object Image1: TImage + Left = 0 + Top = 0 + Width = 740 + Height = 169 + Align = alTop + Picture.Data = { + 0954506E67496D61676589504E470D0A1A0A0000000D494844520000024E0000 + 00CA080600000053E7CF120000001974455874536F6674776172650041646F62 + 6520496D616765526561647971C9653C0000032269545874584D4C3A636F6D2E + 61646F62652E786D7000000000003C3F787061636B657420626567696E3D22EF + BBBF222069643D2257354D304D7043656869487A7265537A4E54637A6B633964 + 223F3E203C783A786D706D65746120786D6C6E733A783D2261646F62653A6E73 + 3A6D6574612F2220783A786D70746B3D2241646F626520584D5020436F726520 + 352E332D633031312036362E3134353636312C20323031322F30322F30362D31 + 343A35363A32372020202020202020223E203C7264663A52444620786D6C6E73 + 3A7264663D22687474703A2F2F7777772E77332E6F72672F313939392F30322F + 32322D7264662D73796E7461782D6E7323223E203C7264663A44657363726970 + 74696F6E207264663A61626F75743D222220786D6C6E733A786D703D22687474 + 703A2F2F6E732E61646F62652E636F6D2F7861702F312E302F2220786D6C6E73 + 3A786D704D4D3D22687474703A2F2F6E732E61646F62652E636F6D2F7861702F + 312E302F6D6D2F2220786D6C6E733A73745265663D22687474703A2F2F6E732E + 61646F62652E636F6D2F7861702F312E302F73547970652F5265736F75726365 + 526566232220786D703A43726561746F72546F6F6C3D2241646F62652050686F + 746F73686F7020435336202857696E646F7773292220786D704D4D3A496E7374 + 616E636549443D22786D702E6969643A46364539353436343746354431314541 + 394530334131384236363745353745392220786D704D4D3A446F63756D656E74 + 49443D22786D702E6469643A4636453935343635374635443131454139453033 + 413138423636374535374539223E203C786D704D4D3A4465726976656446726F + 6D2073745265663A696E7374616E636549443D22786D702E6969643A46364539 + 3534363237463544313145413945303341313842363637453537453922207374 + 5265663A646F63756D656E7449443D22786D702E6469643A4636453935343633 + 374635443131454139453033413138423636374535374539222F3E203C2F7264 + 663A4465736372697074696F6E3E203C2F7264663A5244463E203C2F783A786D + 706D6574613E203C3F787061636B657420656E643D2272223F3ED5A500940000 + FFFF4944415478DADCBD0994645979DFF94544EEB564552F557417DD5DDDD5D5 + 2BBD4023C008091881603C922D8F3548038CD062698E169F197B6421E9206924 + 3C68D0D88D8633968530B264D9203C8C6D099DE3A3B1074908903046029A6E7A + ADDEBBBAAA6BC9ACCCCA25D6B9FF17F1CBFAF7E5BDC888CCAC6EE497274F66BC + 78EF2EDFFDDFEF7EF7DB6EEDAEBBEE7AA6DBEDCE4F4E4E46A3D188F3E7CFC7DA + DA5AA47BD16C368B7BFAAED56A45BBDD8E5EAF57DCABD56AE1179FF53D9FF5FC + C4C444F1BCAE4EA753FCEA9A9A9ADA284F755D7DF5D5457DCF3CF34C515F7EE9 + 3995A9EF66676763656525F6EDDB17274F9EDC285FE550B7FED73B7A46EFE8F7 + F4E9D3B17FFFFEA22F333333C5B3CBCBCB453B54376D999E9E2EEED13E5DD4E1 + 57BD5EDF7846FDE459DDD7F394A1EF68932EDDBBFEFAEBE3B9E79E2BEACF6949 + 7FF5BB67CF9EE2AFDAA7FFF58EFA42FFF4AEEA135D55A79ED1F7BABFB8B818BB + 77EF2ECA537FF5BCEA5359A201F5A8BFEBEBEBC5FF2A47E5E957655C72C925C5 + 7D95A97B7A5FCF6E051FD067147CA84CFDCF985C73CD35052E8F1F3FFE75F880 + 0EE04A7D153EE6E7E70B7CA88E61F8D03B6AC39933672AF1A13E53979ED733B4 + 6F27F1C118081F6ABBE6E366F8D07B2A47633D2A3E749D3B772E76EDDA557C2F + 0C8C8A0FC657BF975E7A695157193E5486EE6D171FD02EC787BE675C0F1F3E5C + 8CF9B3CF3E5B890FFAA2DFD5D5D5E7E1037A3A3E74E99971F1A1F24543F0C118 + E4FDD52FCFA87CC7076356858FA3478F167D559FCBF0015DF6EEDD5B94A1FFE7 + E6E6E2D4A95323E3636969A97867183E548E6851860FBD27FEA17BA2A1E3436D + 82D76C071FAC5B8E0F7D279AE97B687CEDB5D716753B3F28C387FAA232D546D1 + 6E547CA81F0B0B0B053F717C8886AC2FDBC187DA409DD067337C88570AE72F26 + 3EBCBF2A73337C882781859DC487EAA6FE2A7CA83FE29F9BE123B575B1F6BAD7 + BDEE5C22EE1E75588DA3C30CA437C00BCA1BEC44F6CF0CB6FEF23D9DE65D7DF7 + 9297BCA4F8AB863350745675F39C065A6D14202EBFFCF2E279162D673C0E743D + AFF7B4486810110ED52FEF2F0B1D75E67DF385D7174CFDAFF7A897C160C2392D + 79EF8A2BAE28064A74A76FBCC7C2ACB23531F58CEEAB0F12FEF4BDB7CB2FE8A6 + 09ACBEEA59F5578C80C5DEDB41BF1C2C4E478D8B40AFB6BED8F850DB35B15D20 + 29C387DAABF1BDECB2CB9E371146C58733F79DC0071376547CE8AFF021C15763 + B7193E3436F47D547C4800D0735BC507CC5CE3225A7F23F00FD5A3FE97E183BE + 8B5E6AAF3022A16F547CE83D2D123B890FFA330C1F3C5F850FB585BEC13735A6 + EA9FDE171FD06284903D0A3E7C43013EE09765F860311B071F080617131F5CFA + 4EF452DD170B1FA29736F43E9F10986897E343CF39AD760A1F7A56CFA9BF12E4 + D496CDF0211CE95DF13F6D0EB68A0FD18171F031D4E51B47CA16DD0F1E3C58BC + 8B80F962E2433451FF87E143FD4EB2C752EDC891230BE9A1F99C993B48F2C6FA + 6051380D42D86170D02C69D20226978EBDE38004426B21D084145155967ED570 + 3A25A00A1C791BFD33845439028698884F7ED76C006EDA960F1403C9FF94E37D + 60272CC954DFABCF79FB7C6230A07A5E1A03DDA7BF0840021652B61810FF3B10 + 69879727DAABBF3E2159C873E0955D00CD2573C787D3631C7C40A7EDE2434C4E + F71C1F1208D8DD8906620AE3E2833A2E063ED46EDD1776D15494E1039A71CFF1 + C1AE0C7C6813C1AE73547CA87EF5ED62E263ABFC63147CA079AAC287DE17FFF0 + 5DACE343EF4908DA0A3E2E26FF40B3A0F1767CE48B45153E749F4D8EBE130DC4 + 3FD85C68911B860F16D8BF4AF850B9EAFB4EE0431A10D10B2DCAA8F850BF2458 + EB79171ECAF041DBC6C1076542FFADE043734865820FF887B496084B5BC507FD + FB46C1071A25E6D356F0A1F545DFE7F8487F176BD75C73CD824C752E8DF982C5 + 8095A9C6BC01BAE8B8DE610722A62E8022A18AB14BC52C268490E5E5BB0A940E + 6B3019607548E63C5484BAE7ED7562D30E3741399172A6E50029637CBE63A00E + CAE7AF269D762AEC3E3491A425D1E75C1AF7F6483BA2814183C042A1679E7EFA + E9A2FF6805A82FDFA130F00E2407BE4F48EAA74D559763602BF800A8C3F0A13E + EB578C4A20957A5CE3BB193E54BF7054860FDDA7FC17031F392E1C1F1A6B045B + 09FEDAE5E8F356F0A1E7D55F046C57678F820F67DADFA8F850DFC4434423D14B + 5A008D2FDAB35C806747CC82EAF850F9A21726F071F0014D2F363EA449475BBC + 13F810FF10C3575F37C3872FF27F55F0216158FD158DCE9E3D5BF0DBEDE043F4 + 12DEF4AEC663A7F15146A351F0A1FB1A53E103970461437DD6FAE2027D5E7719 + 3E704FD17C103ED47F371DFF55C207FDA4DD0860EA93D663E1413412BDA4752C + C3878F110A1AE103B70FFD55F9497E59AC5D7DF5D50BE9C17907842F50559D76 + 46ACC54A83081372E2AA03080D7A46A08648F94073A9C1EAAC3AA80115B00564 + FD657268B2A052A59DB439B717BBF6C2EB71D5271373587F69AB1675F50B35B9 + 972F40034A3DC38EC51956995F83FA2B81527FD52FD5217AEAAF160AA934C544 + F53C66410774AECDCA0580FC7B9F9CC32EFFDECBDA0A3E043CE84CFDECD4D0C2 + E0B3E6E3390A3E30696AC1113E58285CF5FB42E3430CCA7741D8EB850F4C6DE3 + E0433E0B6280629EA2957022BA0A1F3289383EDC7CBD1D7CE418D8697CA8AFF8 + 1DE5F8C0FFCDF94799693E67DEE043BC467F737C884EE0063FA9EDE083F75F0C + 7C70891F8A7F800FFC8EA0994C115A34A0CF5F257CB8DF62153EF4BCC636C747 + AE89E17DCC70A29770C1FA02FFE03EF8F0BE5C6C7C6851C7D252860F2DE68CA1 + B08CBFA4E3C3EB5719393ED44F614C7F354FC43FFEAAE2A38C7FA075D233AC2F + F435F789767C50B7F8839E15BD840BCD493473694E2ED6AEBDF6DA4270426206 + 9410DC6D93550DD7400A88925C510BEB3B815DBF988EB49069707C778FAD979D + B03302351446879A1161441D42859613C2819DEF0473491630B3C8970DB66B3B + F4BC88AA3EABBFAA1F07341822BF2238AA5B1641764C2E1DAB7C9527614B65B1 + F3D1A5CF2A43BB0C4DE87C2CBC1CC6C4FBEDBB23D503BD5065E60C38BF5CB3B8 + 557C68EC4433EDE4346947C5078EFAF4C5F181890A75BAE8471B858B6F047CA8 + BF60167CA8EF7C1663C43FC9F191D7C9E4575FF43DA60454E32A43FD153EF2B6 + 9531D3CDF041FB5834F28522C7473EDEB9EA7E147C68BE6B3E393EB4206A7C75 + 1110A23E3A16C1879BC7D426094AC207E66AC787E8257EB513F8609161811B05 + 1FAA5BE3297CB800C08209FF503BD5466F13FD2EC3076D41D3E4E67DF10F16C6 + 171B1F6E5E19051F582C442FF82DE6668D3FFC43FC566B4519FF18860F9C9C19 + 67D14B6324BE926BA25F087C682EAB6F55F860BD19051FF01F5C03740F6503E6 + 7DD14DFD153ECAB4A55BC1879B24B7CB3F727AE5CF63B1707CE812BD7CAD1917 + 1FC832E0832B7DEE9BEA5221F36E13D543AA1467CBBCF33E69F58C402DE6F7F8 + E38F17EFA1E6D4FF38B8D278110206EF0E730C3A1D1023D5BBD8A15527DEFAA8 + DF607C0205365B6FAB4BAD6E27F6DDA52ED5A13EAB5C11A94CA5CA67D52360A3 + D2553B895CD32454DF58D8A021BB021772E89306517451792A5B65A83F44E9B0 + EB501B5536BE191ED595DBD17D279E9B9FF4ABB2F48EDA455BCB2E6714393E10 + F460C6C3F0018D1E7BECB1E22F66587C02CAF0C138E9BEFAEAF67D54EDA28DCA + 4378C319D3F1A1CF081DDBC587DAA93A1D0F65F8D022A5B66222C16CA8B115BD + 30C156E1C319319A38E689CA505B346EBAD4477DA7F9A772761A1F5A5CAA04EB + 32353D3B66FD8E8A0FD1487D12FF503FE01F65F8207AC9F191F30F5D9824840F + FA8FCFA168A73A47E11FB99938C7077353658C830FD58189A40A1FCC31D1A00A + 1FEA3B6E0BEA9FFA8AB65ADFF3EEA8F8F076BBD6D8F9B568AB39F742E1437359 + 63FFC4134F54E2436D6013360E3E0808C1F11D2B8678D64EE3430219568A327C + C0C30E1C38B0618247C8AEC287FE573B87E1037CF13DE64934561A4BD66AF081 + 8F2DF870CDAC8F6F6EC2041F94ED3E9C9BE1834BED539FC14799268FF7737C88 + D6441AAB0C1CE4D547221DF18B767C38E6E0F97A8F80105C6484F7F4DB179C52 + 270B531DBB655D5ABC5077E79D736956BF1A687D16E14534095BEEC08D939516 + 34223B70782E8B24104034586AF855575D55B4058620620A28D87755EF1D77DC + 11C78E1D2B2682CA240C9A363B415CBDA8364A452930AB6D9A2C6A5BBE0B023C + 4C9E2BAFBC72C39F446DD23BD489139ECAD033989F108A10025C221750D8F922 + 30EA598159ED12F8102854FE2DB7DC12F7DF7FFFF3425CE9A74F1E5F20F95F26 + 3F221872E7FA2A707BBA00C2CFF5DEA8F8509DBAB0AD6BDCB6830F0159DF09C4 + 870E1D2AE802BD6024E043CF091F0F3FFCF086E3F4A8F850DB850F95A7F64858 + 537F732D5B8E0FB5097F01ECEAD4A9CF087B6A3FF8D0583241CBF08136922829 + 0428F08140A1F26EBEF9E62DE143F56A2EE300BD157C6853A1BF7A8FA8C6327C + B0B84063FDAFF1011F9858D5473131C787C68039310C1F1A33CDD51C1FC2218B + 90C641F878F0C1073718EC28F860A154DB355F55EE307CA0E1051F444B621A22 + B507F8A0FDC231FCA30A1FF833A94FA295FA27ACE0FFA7B2C187E879D34D37C5 + 7DF7DDB7B1188E830F5C06309DBAF3F428F890D0A83E603550DFF28531C70711 + 719A2F447ED176F547FC4357193E72077CB4536CC455B6E3830840D18F7547F8 + 78E081073684517795D80C1F44B7A93DAC8D9BE1E3A52F7DE9C6865963CEFA92 + E303939BAF2F2E04383EC092FE07FFEA2F8EE2E043F76EBCF1C6B8F7DE7B37DE + 1F860F68CAC65AFC03C548EE5C3F2A3E88E2D6FAA2BEE5EFE7F8D01CD73B55F8 + 807FE87B52B68876AEDD770110ED23F281FAA3BEB0614D74EAFB38A567E76988 + 060635B126893ACE22E61784220782DED773AA84281F7C7DD411F2C51029A767 + 3450BE0050AEDEC3794BFF6B1180606A9FEF2C1C183ED1195CD79478CA0054CD + 02334ED79AC802A93B7FD326D77628C78EEA531B4E9C38B1014A0D0ABB0A7D16 + B1750F50628670E95E6D1058C89D21BA3DF9E4931B80F41D916B170833F5680B + 800CE0611CA83C099B253790FA2BBF99613BC6DC46EFFE5D9A24F46B183EAEBB + EEBAA21C3D57860FD11C3A810FE10101126D0F1845038456534C2DC787CA6202 + AB1ED5994FD6CDF001BDC6C58772A8A8FD7A26C787E695FA829941FD6077A6E7 + 6068301CD14774262A4AF79E7AEAA94A7CF88ED2C7817EB9497C183E740FF37B + 9ED7A40C1FECDC98E72A63547C1C397264C3F155BC021539F35AF7582CD8946C + 860FD1172658860F5D7A5FEDC7F1D335058E0FF79DCAF1A18D8EB0C5A6A20A1F + 30695DC20742BCFC4EF0452AC307F414965928D1B4800F3177376968CC727CA8 + AD6C2CE153BEE0E5F8F0C5D7F1A1FEEADDEDE00321984516A171183ED016A271 + 717CA80CCC5855F880DE9876DC4540F8A0BFE043F593C6A10C1FB85CB8C3BE9B + F59C5E7A57CFB1D174E16A183E744FFC199F46FA51850FA20CF51D6B05C2A10B + 07E00313AFFA8BB0020DDD7F37C707C206F4D45FC6174B80EEA9BFD2BA97E565 + 2CC307696170CA173E7CD399BF073EB41E13F596E30339C3D717F0271A898668 + 03E90F816C7A5EDF6B53E5F828F23825697A2115324FF41BBE009AD022A80AC1 + 5CE7129FAB2595BC928542C05059EA34A605181451757A0ECD07BB6EFD759F29 + 061335B4DE1738F4BEDA047175C15072BBABABAF05609E25A788EA519FF1AD01 + 9C6A6F7E013A1157FD65C7A88551F5E044A632442F76BDEAA3FE275F86FA8463 + 2FFD521B7C370430F5BCE82A5A912B83C9A032735F29C604531A8B91DE450815 + 13109054B668A267105ACBFA8CCA5275830F8DABFA8DB6A80A1F8C01F4523B91 + F6850FFA01BD354E0058DF8B76081D8E0FF5037572193ED42F4F4A380A3E48F4 + 99E303A6297CC064107ACBFAACB2A425DD0C1F0877EAA3FE573D2A97E4799840 + C0070CCCF181B0255A6D071FEA2F1B16B5437414532139DD28F850397A1F7C10 + 398B0669183E94DC94712FC307A6971C1F6A234207112F55F8507DEA97DA4A12 + 4BA28AD8AD57E143DF31575860489140FF55F6B8F8D06776D4DA3CA96FC3F021 + 3A90EA84CD87CAD0772CDA84A9BBB0255A917B6A147C68DC5807727C888F693C + C187EAF24D49193E488A48AE34D15BF362147CC06F1977B4B3E289CC6BC787E8 + 25BAA8CFF0DB1C1F98A2D50E0439D141EDC0F2407A93CDF0A1FEAB0DC3F0A1B6 + A3CD81DF55E143F548E304CF26AF6119FFC01F4BF7544F153E8810CBF907F810 + 2D716BD82A3EF41CFC5274446384A6B04C684290717C607ED438EB7FD5C506B8 + 0C1FEAA3E613E33E0A3EF4974D1D9ADCCDF0A1FAD42FF525E17EB176DB6DB72D + A4CECE939C0CD51DD2A626340CDD6DD5A8C2D4394D20F9AF48050DF8F41E3B0C + 49CDFA0CC1208A3A8A731B8E6AD82CF51C6A533D2B10A2AD2082C87331E872B5 + 9BEF0ED9CDE144ACC16562A87E0F79555F5045FB850F80DEC5F15700D702E12A + 46D5A57B1A38958903B0060AFA62DA6122C2F8F0CFC1EF411304CD0E111EEE93 + 9287C3A21552FBF4ABF7B191138A0C48EB838847185759F4028BB6DA073EB0FB + 0326F59B093B0A3E30C3891160EA14BDC087CA14B360E7083ED8B50CC387DA21 + FA6D071F303BD108B34E8E8F32277D4F0CA7B1031FC2BEEEC344B68B0F314FD1 + 8E2CBFCCB561F86097E88227F8C21155E5E87D37ED6C171FFA9EA0862A7CB018 + CBBF49F8C0CCB21D7CE85D365698FF34BEF81F8AF6FA3F8FDC19051FF85094E1 + 83E8A561F8D0F7A2B770217CB0FB275C5C4C5C428530ACFB24C9652160911AC6 + 3F1853D1894D2CE6D7CDF0A1BEA0D1D5B80FC307115E55F8D0A5B2984FE0C343 + C8C187A7B5717CF0BEFC57442FF54965A95D2A2FC7074972D12CE073E6497271 + 37001F0874682B446BFDEFDA76D73EE6F8107DD012D35E95B3157C88BF0803EA + 93E683F0A1F7D466F0A1F55363AA4BF4447BA7FEB0611BC63F442B22DCCBF0C1 + BCA8C287CAC30541EF92895FE3C1A6137C20F854E1436511459AAFC7E043F5F8 + 7A3C0C1F982DC187DAA9F9A476B24E6E051FC21982661A97C5DA9D77DE5924C0 + F41C0EEE8C0DC32F4BEDCF42A1C669A0F1D151C354316A6C12478928BAA78EE8 + F249E3764BEA1441C5BCC9048DB0A3C98A99CE4D2DAE8EE41E03A2BAD81DAA3E + FD85C16326D32F61A824C9F3C1C2874365BB448CBA9A480C5D38FEE24B21DAA0 + 75CAFD07441B3401646245BDAB8182E9E7B477E769224DD46E6CB3983000B4AB + DDE92F365C5FD8BCCF38DAC13875E5F8C0BE5C860F8D378B01F8C0EF85C838C7 + 87EEE95995E593A60C1F98F560525BC5070EBB9840737CE09380A048C2CD327C + C0C059DC35373846487DF42CBD8E0F127A128509FD10D6C0075197C3F0E10C1F + 7C10BD0A3EA4BEC7A159F7D02A383E540E3BB351F1E1D1452C709ABB98B6737C + A86FEA13475B68FC737C60F2D80A3ED8413B3E5C187407D761F8101DF039DC0C + 1F2E3CE6F88081ABBF988C840FB45A98E008A156D91A5B1202E7095A598C87E1 + 43ED663E8C830F2291E01F2CA42CAEE0C38550AF03B30F5AA92A7CE83B2201CB + F0A1BE93C19B63B6F42CB9973011A98DA2A96B79C187FB1D810F7C2B737C309F + AAF0E1A635B25D3B3E744F7F1120DCECBB193E24B4A169E2F4076DC2B0FE800F + 5274800F4C5355F8E09D2A7CE4C24DEE600E3EF43C7E6768F29C7FE4F840081D + 171FBAE0CBF87196E1436389A50B7C30FEEA3729477041D01C622DC2B49ECF7D + 612EC70799D107B9B0166BD75D77DD426AF4BC0893DBB5F5D76DD21E3DE0E17C + 385E61E7D73D5504517569D044240D3C66411C9E31D5417424509545C839923D + 3B0101C47D0F70AEE3B3DACD2E0DDBAF163C3EB343A59FF41DD39D3B9F025076 + C048EF0C1C8EEC0CBEBE4760C0510D1F0D1CBC295FCF107EAC81C2A4A5CF6A33 + AA5A6CD6AEA664C1C0D7077A014A54D57C7640B37B70413177B6E5C2F7A60C1F + 64B376C169337CA82CF51F7C106983C0835930C70761AE38D3E7F8C0215C17F4 + 62B794E34365B04B63E1C8F19147CB800FDABD5D7C2034A105C2FC360E3EC87B + B5193ED0FC55E1038DAF8710830FB4D05BC10769445C701A860FD5C759612C3E + E09B050D475BE895E303FF48FA8BCF0AF84093E3E1CF3885B350800FC68CB406 + 2CAE8E0FF7D3D80C1F08CC9891C187E6A01F6B8240093E54AE2E8D1967071249 + A67A710CC7E4A05FE71F44D781877CF356860F4C1955F8603E6F051FF8988E82 + 0FCA40E85159AC2FB48F483D77C4D67DF51BD708E8827F24B900110A70C4563B + 984F55F850BBB5A88F8A0F1666F28939BD727CB040EB790447E71FD041F71D1F + AC8B65F8C0DF167CE4EBCBC5C287E6B3A775A8C207E39CF30F8E5873C1C9FDDF + C8E155850FE40F22F5E01F12A4A09768E4F8A0CC21F8B81055E70E6E100CBB36 + B67676579EC8CB1762DEC78111072B1C57F183229D39CCD1A31F5820DCDC477B + 346802904BC8D4CDE18CE4B9C1B95D0453DD447FB1F3C0FE0B8071586732E0A0 + 9A0FB4FB66B08B50DD38D5B38353FDE46342D302F89D867A8FFAF165A15F6A37 + 9102848DBA2F037D40852E55258BA8E8C344F0F04D7DA6CFA834D1A0D05F97BE + 99247CF6847038E2EAC2D9742BF8707A31A9D136205053A63B8562CEA16FE3E0 + 4334D2AE896334D879207C50A7E7AD011FEC80C6C507E38CC9022C800F16CF32 + 7C6036F3B9898F608E0F17B8CAF02146460A84327C90BC157CB0431E171FFAAC + 368F8B0FD10BED89E383A837F0A17180E1E5F8D0F888893A3ED86913A6ECF860 + FE3A3E14AD83A3ADA76529C387EEBBBFD956F04139F8C9800FFA8B60EF34545F + F45773894D0CF5B090E377E5F82072D9F1215F1102597C211DC63FDC95632BF8 + 80E7E1DCBF557C309FC873C41A82DF1FED22F8022DB7AF777A1E9FDB51F02153 + 1AB4F5B40A9BE103C1C90FEE1D877F6C051FF05CE7DDEE5399E3A38C7FC8D78C + CDCA28F860E385C67A1C7C3026E3E00321B40C1F286CF43ED1C9EEF797E3032D + B7E3033FD234167DC129BD304F323024535D9246F11F9129CE4330B95C7DE913 + C2D5FE34064D143B70764F749801207D3E83A87758E070F8429043DA451DA905 + 13ED0E3B368EE2D04599004C65B1209199991D290076C2D26797C6193C0432A2 + 1DB0FDE2204F98ABD30795228C08C01136C902062366272B131BBB7416565D48 + D494EDBB3B5D02140B8BB4155A4C451FA2B0FC3DEF6F193E3037A84CD4A33E29 + 46C507931A7CA0FD61F794E343F573C480E3030D4A193E48B34184053413BD5E + 687C30B1D91971B40682768E0FB51D06E0F810FD7162747CA80C6D1A1C1F302D + A26FCAF0C1CE52BF6A97F08723F328F8E09810E87531F1216C1078E1F8505904 + 97383ED066B2C0D31F5D7A86E000FC2011687108051FD493E343F7F1B551BDF8 + 22B9A677337CB0E08E830F846E36A8EEE7289AA37D6063043EC43F7050071F38 + 486F860FB2286B332A7C90CE25C7878F2FF8807FE0ABA6058C940BA3E2C3174B + F0A1F9EFF4DA0A3E705928C3077E2FE3E203FF3802AE089AC217C98586ADE283 + 9416C3F081A6CCF9C728F880CEF00F8F72DB0C1FDA6CE0B8BD557CA0994733B6 + 557CE4FC83FC5F9C75E84EFF2E7F3096F8F20DE6CB62EDF0E1C30B8928F3303C + FC99C839A407C95504610113039B0FBA33403AC240522ED12A2C56FE2EAA4F22 + 9B30C52039E3C487544FC41E111FAECAF3C800226D3C141CAD06391A50396203 + F6B63998DD568FD48D70427F61489843DC61CFCD65008A89866604802BFCDC1D + 5875315E9A302C06799243E8C691272C1E44F7109144E4833B9953862E3DEB47 + C92044B9197627F0C1F8823B17667C92D05F54E6E0881D8333FF2A7C20A8FAAE + 87BA4925419A0C8EC0F1C352114A7CC758860F26A3ABB177021F605F63AAF415 + D4E3F87061811C2FF4159A502FF961F057A15DD0643BF8C044360E3EDC7936E7 + 1F4E2FEFB3A795707C38FFD0FBC22A1B9061FC037A217CFB01DE65F8A0DF3B81 + 0F5FB036C3076555F18F327C206C8C830F34B9DC1B071F2C888E0F3678F0F41C + 1F39BDC6C107116AA3E2C3F98F04423629E043F7892076DA23A4A8BC51F0415D + E3E023E7FD393E30FB96E1C3739291411C4D4C15FFC0EDC1F1E14930191BFA42 + 024D4C61393EF011DA0C1F5812106E1C1FA23B639BBFBF5DFE9127C074A778E4 + 0F7F3F09718BB5D7BCE635451E270D30D11E10858343F1F9D1BD1C842EDDE63B + 65BFE89C6B0E2022C4F7F2185C841900C9F3001B86435828619BDA05A16570C7 + 478880AA54BB005D6831101C91CEE9AF1F95E2D269595A79170EF2FE7A282B93 + 15891D353D83889D9CC144D8C4278088242222A4D6C414064D7058641279EE2B + F257006A3779001CB2D8E22B023E0891C6DC7AB1F0C104F7A471A410A8C2077D + 470BC7677D8F69521829C307E1DCBCBF5D7CF8A42CC3073BB6CDF0C1B86C051F + 389C135DC333E0031398C610E775765D9897ABF021CD163E061A7FF041AA0AF7 + 35D82E3EF83B8C7FE4F8401B40840D7372337C10968E90A1B2D974B1F1234884 + 9DB6BE23B28D71DD297C386D46C1074239FDCDB384830FF591330EE11F393ED0 + 943B3EF4ACE8B2193EA4B9C0E74FE50A1FBA08A127128CB0F0170A1FCC791669 + F0411DC3F0815930C787E8439266DA093E984F65F8707AF9460E21EFC5C20747 + DD783E3C0452921B935B4AEF61C2747C6CB6BE90DC14E14CFC56CF92B8F285C2 + 071A35CA18868FF4BB58BBE9A69B0AC1090F79CC161E1EEA03E903E752B22F7E + FCE6593991AE219A87D27BC3314FB9100578044E9E71673334089AE8BA87C3A8 + DE157397544DAE1954B3F822B827BF6BAB986C793F7D20A00303909705ED5C8A + 65E0F36842FAE5BB1004AA9CEEFA1528E58741B4A21820A6114D589CF0E9B767 + F9F60CC9800846E1AA4FB2A8FA227AB1F1E1B6F671F1416EAF2A7C906788DDA0 + FA25F34A193EF2E84AEF8F33E351F1E142D238F8A03CC707F7FDACB5327CC80F + 438B1D6914308D10AAEEF8D03DE8E8A663C620C787EEFB7CC307C093F95D6C7C + 2034EE043EC825031F216F8E164B853BF3BDE84606E66F347C4067CAF4E49255 + F8E014000E4FC734225AB139C275605C7C60A662811DC63F72FE390A3E7C81A4 + CC9C5E55F8E0F338FCC3E70B3994443BF18FEDE023C7C438F8C8E703F8F0B5A3 + 0A1FBE06E4F810FEB5BE800F69050966B818F8206F9F2B51BE41F1B158BBF5D6 + 5B1712539DC761944E5309CC87F047723CE50E61B9E49B4BC939D370C149BF37 + DC7043A18E234A88EF734F7CB75597F945686120E70AA7A0638BC617CA7D0690 + 4EBDDD4C1C247EF76371551E9A221F543795F13FD23CCFE9DECB5EF6B2E21810 + CF484B9D9E6F85817615ACF7997C401C804A3E20C256F9DE7D9F72264EDFD04A + 011454D984498F8B0F5F2847C5876B507CB1153E343125FCD1DE327C0C634465 + F81023803EF842719074153EDC6CB2193EDC09745C7C3CF4D0431BD18A3EB9B7 + 820F0EB824B12451431C87E3E74AE56578BB1C1F84ECA2D5DA497CD0AFCDF001 + 5D850FF10EF19071F0E1828D9E13D64982CBB120BAAAF0E13E2AA3E28371071F + 0812C3F0E1F354EF25BE5D643466A1776D81EFC0E165AECDF0B195464817F810 + 1E08AE717CB86FDC56F0E10EC5DE27C7079A9DEDE2A36C3E091FD266704CD74E + E04373889C720467E833011824EDCDF1E163C25CF66772FEC1B83A9FD6E59B7C + 68C62653C77229233A663CC7472ECC97E18367187F0989EA13BE9324B296C648 + 65AAFFC3F0C1F8F921BCA409F0A4CC1ED9E76380CF51D9B983DBC587FE0A1F4A + 0B229C57E1C3CA58AC1D3972642181769E469755C4B95A101835382A49CE9123 + C53D03EABE2B654E5C5C84DF62DF04006EDFF5C5B6AC0C88CC89C8EECBE3091B + F1B6D7F73037577DA24604F4982DD9BDE9D267B290425C071C6596B515E62249 + DECFD401484C18B7CBE68CD02FA21E51A7BA3A54BF9E81D8A37CFC729F16C69B + F1C5BF612BF8403BB813F81043F27C1E2E408F8B0F16BE1C1FA888617CC3F0C1 + A2B9557C9409FFE0833C3A12027C675E858F325C7091E88D2843847DC707DA87 + 71F0E1BE662AC30F1A2DA3173BC961F8D09CC4EC01AD46C187EE897F78F8F156 + F141E000F870EDD94EE183C3ACC9865D860FE6DA66F8F0C3573D02742BF8D095 + 9FD5877973ABF820A084A8AD61F8A0CFF09F327C604219171FE21F44B3ED143E + 5C2818071F682E181B8E00827E9C3A310C1FC3F887DA2381B80C1FCC3DE7BDC3 + 2EA2A671F128C387DA23C17B183E7064C757731C7CB0BE54E14365101958850F + 1736F331D52F6935DC4F79083E166BD75E7BED421AB0791C4E913CCB26862E49 + 8724ABA3621262E138E73B059790AB263040F2450186956B98F29D484E00FC5D + F41D8B623EE0489365C063E03C6497D07E1F4CED3C48A2E7CECB2E09975DB4D9 + 739B50AF4727D0DE3230F9B8787D84CA024E5D5E9EF72FBFF0915259E40AE259 + 04A861F800CC2A23C707BE0E980AB78B0F67583B850FF70918051F382DEE243E + 7C17C4A1AD3B858F7C81A2BD940793AF6A97CA001F68E2781E865C860FA7BBDE + C164ECCEE1DBC5879E235864547CE4F4AAC207BB6837C56F860F9E474022F543 + 8E0FB4633B810F30BC157CB0496531DA2A3EF0A1DB2A3EF4BD36362433CCF181 + 29E8C5C68767C61E868FB236393E2474E8FF1C1FBAC7516717031FBA5C1BFE42 + E2836497A3E283769076811313727C48FE2031EAC5C6C786E0A4CCE1CE30AA4C + 6C02B50E5CFCCA57BEB21199A08B6CAB84F9C1E021A6DB16CB88E284CF9D65D9 + 6D6033260CBC6A8020041D755FA55C2D9BDB8C9D9024EF92FF8B4E1277C99F1C + 0F84957A7F5DD59ADB586923110AEEA78023AB1663CEECD184C2F1B2AABF3E51 + CBFCA4BC4F682CCA2E2DA8320FA93D3211B130300EC3F0413BD4661DF82C7C30 + 768E0F7D4633F15F023E840DED54840F0403F041F6D98B810F3120229CFC70EB + 51F191FB988C8A8FDB6EBBAD18CB471E79646C7CE852BB950BE69E7BEEF93A7C + 704AC076F0016DDDE4CDA1A76455E6F0D217021F326BA8CF3AA4BC0A1F08198E + 0F37D16D860FF7692180832344C6C50774CE4D87DEA7AAB541F5DC71C71D457F + 1E7DF4D12DE143C282C2D7C53F7CB38EEF109A73DAEAE3BC193E7068BE98F870 + 1A329FCA0E40E63B2DF6EA578E0F32AA6B31C7549FFB7996E183F655F10F0238 + F083DD0EFFF0236746C5C79D77DE59F0C371F1415BB4E6CA274FF8A01D8E0F5C + 12721FE59DC207290C423E4E24C0CC6DB0391370F38F67096510D94D72D4041D + 1131B07F62A6F10B2D496EB3A43344E688480211A912CA04031F4418919EC58F + A8CC27297730E3B3474D79F826CF90204CBB02FACB8EDED3D7E7F47435298C97 + 76911D59ED457DE97E13797FFD2F52BBFAEB872A02FE2A873A9E71F5B1472F38 + E0AAF0E161DBAE8A1D051F44FAA1B61D071F089968EF086E282BA7ACCD6814C7 + C587FB26B8E929C707BE755BC5078C77A7F0A1FEA2F6764DD628F86057862665 + 5C7CC0A4D880B86F179FD537ED2677021FBA087146E0C479BDCAA450850F98B1 + 0BBBDBC5072674E183F3B6107E48BEB8157C706C10879BE6FE2C65F880DF6D17 + 1F8CC356F8C766F8706D148751836BF22F6D051F645BDF0C1F65EB8BE3C37DB7 + 725FA49DC00767336E071FE468737C549973CBF0014F2B3B5EABAC2D65FC63AB + EBCB56F121B983049CDBC187C68304A369BCFA799CD283F365D15B349643EE48 + F72E6121B7C1EB5DA95389CEE3B04EEDCA09492ED38420E0E04B83E4073109FD + D40ECD33A33AF3CA9DF8B838CC501131B994ECBB86BCBF380C938811473807BD + FED7A9EEE420E1CC3DA2531CC47E218891ECCB55837A96C3693965DAEDF7DE47 + 7720457DAC1DAEEEEB6C2372B0205123E1FB38036A8D9BC6072D97FAEBE1BBF9 + 7B39BD38730BDA94E1439F550F0C8A5C3A64E2761FA971F021E141F8E2AC3B12 + B8E5A637675AB45F8ED22A4F11319E957D337C9004537D519D2CAC3C4F7DE043 + 7D25BF09D16DC3F0A13661B7A73DE0833C4B8E0FCADA0C1F38027336DAA8F8D0 + CE98C32E5527E90B46C5C73E3908A7DFCBF6E8B057851E37E396B4737CAD4C59 + 724A3F7D365ACB2BD1595B894633D14FE1FEEBADE87553BB26D3C6622261A991 + 98E574C2C1EED998D8B33B26F7EF8DC7A6E7E253C74FC472733D9A6B892FCCCE + C4F956F379D13C8E0FFD8F603C0A3E349FD44FCD27179AE8B797E1FD25092619 + A8D12AE58BA6F0A17110AF44C8D90E3E70D2DD2A3E34CE7A5729035864DCE7AA + 0A1FF2D7149F24CFD1307CE40BA3DA2C4D82FBBDE1889F3BFAAA7D6A97B0A87A + FC2CB361FC0301871C461E814652650260CAF0E1EB8B8FB7E6939E1D171F04F0 + 70B0B03B91FB865ADA59F0C1668B438237C307EB4B19FFD067CD65F8B4E36118 + 3E34CEA28F9CEC5D0871D3758E0F5D1A37F0C1C1E48E0FDA5D850F0232D8DCE3 + 889FE343EDE3F822FCBB484FE43E9655F8908C934728925499793968675FE394 + 1E9877FBA9FB71E050ADFF39B74E194769B4DE41358C84CC193A22942A94E042 + 79B97D5BEF628BF523589098DD6CA6FF71F0CB0528014A6DE0F46C546E3E61F3 + 64962CC2CE3C759FD3DE39A418D0AA2C9267BA53B6DE55BB38F05813897C517E + A16E447D8B060D930421D4AA8B4CB5029CDA883D1A90609E925D374F5CE734F6 + C94F92BBBC4D384E8A1168DC307731BED0B00A1FA2BB2E7C60C85D92E343EFC0 + 1447C5879E71956C8E0FEF832E727E1086CD44241A66147C700DC30793890CF8 + E0830CB51C358220ACE74805E082CBA8F8A0BF3035D53D0C1F68A734573D8A64 + 337CE4878FEA525DE0430C097346153E0A7AA731BF6C7E5FEC4E6DBAFAB20371 + B8558B979C4AEF1D3F15BBD7DB71BEB91427BAE762BA9E76C4A9BAB485889924 + 204DA4D72752F3EA125C85A15E5F7DAE916976DBE96FBA977EDB9D34177BD371 + D9DCA5B1305B8FD5BD7B62EDC0FE787CD7443CDB6EC699D4C6E796CFC78985B3 + D11C1C1D837F56193E3436A219A7AB6F071FE4BFE34057FDB2080CC30711BF08 + 2E9BE1038121E71F6AAFE683CADD8C7F6C171FBA4FEE2B2D5CA21F59B747E11F + AA9BFC40EA9BF83ABEB28C81BE77FEA17248ADA15FF10F8F7EF5B6E97BFA8DE9 + 2BE71F08BB8E0FD61736502A870CF8281072CD746EDEACC207EB0A076893655E + CFB0BEC04B11E6D42E0408049732131BA750C00B5D8386294ADFAB2C95CBE1EF + EEEF44424BF10FD5E59BABADF20FE1436636D18F2CE28C2F1B1DD693327CA094 + 507F727CA0D8613EE137265AE83B127CE6FE61E083BAC9598910EC4EFF6C8606 + 01288BB5BBEEBAABF071824943745F185D25E69DD58E0C2758118453A7498A27 + 86C1AECFEDADDE7011538B19DFA1A5D2C5F93FBA50F17166102640952100925E + 9FC83C06D7B507FAC5B780736A1C80FCF589EEA7C2AB5F22B4C0C4C0B05363B7 + A76719BCDC6784DDBBDE6732B36B42924692270B301117249F53799C382D70AB + DF8C11E3465DA45F405DE92A772E7D26DAC7052BBD2BBA92BC8E0CEBEE4C5886 + 0FB7BF432FD24C94E103E6E0D180393E10C4B0FF3B3E98B438F313D5828947DF + B380093B44E60DC307021A26C0327C9439074BB0905025C188DC5A8E0F425DAB + F0A1F2441B2D9C1EB2CBF989C3F0A1B612C9A3E7451BCE69743BBFE383339B1C + 1FFE8CE30313BD3B4EC34C8AD3E553FDFB537D87939074FD9E7D71F454C2E5E9 + 343E6BABB176E654D45ACD989D998E895474BDAB719E8E5A3DB5BD9676775ACC + 0B4129EDE63A3D352E7ADAC8F5068B4DFAA9A5DB12987AE95E23FDD40AAC2501 + A8733E7D97309060DB4E02597A2876EDD91FB5DDB3D1D9BD27BE7AC5A5F1F0AE + C9787669319E595C90D450890F6187DC6E65F8D098319F786EABF860074E0414 + F8D03BF0CB61F80007F8DA09AF1EB53A0C1F9AD7DAF96B51C1DC9B9B29DC5542 + FD04B3393EE06160C2FF071F7ADF1725F839F4F1284FE71FF800A9ADE2012A0F + FE01DF808F94AD2FBAC43F442FCAD6D8A9FF685FBC4EB27DAB8D7A8E7120E925 + B9A8C83C5D858F51D617F8BFFB2C0907EAAF36DE7ABF0A1F38938F820F34E455 + F8202A4E63C31168A233F8608D1D860FB0551655AB0B077ACF3EAE77D5AE71F0 + E1B280DE93A08E795FBF2AAF0C1F8C6399A0297C683EB296C16F9D5F97AC2F8B + B557BFFAD50B69909E9700D36DB3EA94721C88116B0144FD874F820AC7AEAE0A + 051C09510C822AF245DF2F3AA2F70811D7AF08A2675DA0429547193841EABE40 + 8D3A9E2348386DD9778908121CF4E9B9499840221E391D3C9C5CE511768D80A6 + 892DE01C3B766CA30C3FA1BB2AD11BA61E72C1C82112C189E7C85E0DBD39DD19 + 731E0E8444229549D31CB382D328BB5B07A1DE93C9405239D9E3F50C1A443206 + 7B9660C787DA217AA91DC2088C1AAD0767C37168B3E8AF892DC6C019862A93BC + 315BC587ABD8F111001F7A477DD8097CE8F7E8D1A31BF860578A6ADC0578B553 + 6DC0995A17738648C51C1FE482D1FF040748650FE3E339B25797E1833E0A1F44 + 2295E1836334AAF08170A5FA737CA83E3D77C5E507E2EAFD97C615B57A1C3CBD + 14338F3C13B5330B315DEFAB8E6A8D44BBE924042689A99B86B79304A5769272 + E6DAD3B1A73915CD9076479A3471E56EA4A707A292AC7312A6060B4B22938427 + 7D5F17734EC2523BBDDDA927665B9B4C82547AB6538BE2450959692FD015CF68 + ADC77ABD17E7AF79693C77E4EA7874662A9E3CBF12C7C51407F4777C902284B4 + 084E33044DF0E1E776393E341F744C12266F5D988908DBD6F82318289F1BCF71 + 2696E7EFC9F1C182831992F304D16CB1000CC387BE17CE86E143CFABDD08009C + 729F2F9EAA5F5A1FE842FE375D9CD7297C91453AE71F37DE7863B19984B73217 + 396099D30F70B6976081A68DEF70A7C8F987EE897FB06151793A9F53DF91EEC3 + 1DB92923E71F6A274A02CC61EE97E31B11FACB3C747CE812FFD07CC2A4A90B81 + 0D33161B2ED151F8A03EA252716118860FD609CE13ACC287EA25F3BDBEE3D821 + CD07CE10CCF181A561547C3CFEF8E31C905BD42DDAE2EE300C1FA283F001BF2D + C307C7D9800FCD3DA2E448548A3B458E0FB5558234D623D5013E4467C6177C0C + 84E4BEC62911675E95B01361D78016806CCB980A70F41661F51C52AB2A560389 + A0A2D12E38E5D228E056DD489D48A99C1B86E4EC67192175E2EC86EAD1A32E7C + B021123B18BDA7FFC53874B9E044F657F75951DD1C9688CF8D060826413E1BB5 + 8F0CB965A1A3FA2CDA6917E149D2D477805CA6FE254A806352F4BE40E3A6AB3C + DF07B66E3108CC88FA3F1F03F5D7A3D1D4078191C841D20B08989806737C60DE + 40EDEBF8806173E03211988C9DEF58AAF041E235F0214C710CC2C5C087C694DD + 4C193ED860A06D737C8856F84EE979E603E70222E857E14363A6F14570DA2A3E + C057153E3894177C70A65CAE7122E2885DD9D4C464DC79E34D7178DFA571D9D3 + A763F7C34FC58C9CF27B6AFB4474A62662550AB39E841CC94FA9EE6E14A6B786 + E8DCED0B46BDDA40484ADF772515D5F450516BBFEE5EA778471F278AF7A5858A + 81E054102BBDDE41568A8EC6B5D737E575EB7D41756FFB6CEC6EADC57AB311AB + CD4EAC4DCDC6F98369C371F4483CB97B2E8E2D2EC43D69E383A69153D83DD2CC + B5122C5C989F737CE07EE0D13D8CA968CC2224BA4BD8D0C501B5687C47C187E6 + 838F2F676BE2B89FE38385D6F1217C793DC3F021FA700EE466F8C07F078D0987 + C94A80C134E81A6B0E1D47338ADF09871733C7D50E8E35E1A05B36FBCCEB32FE + 81961ED3E666FCC3177E32C84BC8D43B8CAB85A67F1D3EB4A610B946C25ECA03 + 1FE468021F1C61C5E64FFD97B001FFD4F7F8DF20E8E7F860BCF52C56097C7BD4 + 77C6B40C1FEE7BAB6771DB60E358850FBDA3E7840F52B394E103FE0E3E587F55 + AF846632B06B7DC9F1410050193E0846D077B86120F08B0E58D2D8E4FAE5FD96 + FCE1DA66D5C75C737C0C1CDC176BAF78C52B1652A7E6B1E9A2C5000844B67854 + 0905A8812218804655A64648A85063D5013F3C33BF58B0B065BA133A2ACFDCFF + 8A4834A2C83458020A2AB7B2A808EA113835C9193C0E30CE1DF8DCD98D73BC34 + 801A2CD5A37B78EEAB1CDDD300112A8E735A2EE5A282577FF1ABC037018D4EEE + 30CE4442DA56D9928AA5B9F1ACAF39D340EBC3E9F69A0C4ED35C3871477F7614 + 24166357A1F1CEF181BF884789383E10C635315085820F3D8323EB307C20800C + C387879D6E051FFA4E63ECF8107EF3C522C707A61FB2ACE39CAFCF7AC6F181AF + C4C5C2071B1854D01EC23C0C1FECE85D7878DEE2A3DC32A93F771CB921AE59EF + C5FCA3C7A377F24C5CDE4DBBBA89A9A84DA5F64D26C174AA501DC5FEE5FA407B + 1485F0147DF927DDEB6B8BD6279210534FFDEF8B4E512F642899E9300944F1BF + 84ACDA4094AAF72EFCD56F3BBDBC927E27DA1193E9F364376D6A5A49B04B9FA7 + BA7D1FA9E7E6CF266169352E3B3F197BD72762BA3D19ED6E3D9E6B25863AD388 + E6F547E22B87D35C9A6AC4A7BFF8C5F45D77647C70FE58153E7479C664CEFEC2 + 0752B8C077147C083F6C7036C3077E7BE0831DFBB8F8C8CDB8F4178D8ECA6531 + 25D06714FEC101A968E0452BB599CD2A7D73D3265A138E3DD2F35A4CF181C234 + A94D89DA4524A1C6A0CC14E30BBDF30F367868AACAF8075186E27FAA53E3C601 + CA65F840C3A1E7C99A0EFF19071FE28DA2157EB46A335A36D140DFA12D1B071F + CE3F7C9CC00742375AFD51F0E147E96C071F1C848C03B9E303FF2BC787F0A4B1 + D7FA82CF35F8E088249438687137C307E7B7A204707CB8B3FC86A92E11681E9B + 29BB043FB811A2C1807D80D471A47111529DC60F0935A09831E0C901E7219CD8 + 3FD99DAB1C18819F730301798F705076113CE703C640AB7F22346572A69D6BD9 + DC53DF6DBB6A0B4EE84C78C2CD5187E3785CA6D9713AFA795AECECD467726D78 + 1FD889A2EA24D70DC72D20DC7954842E95C78E914981DF4B99AF1352BE1F1321 + 606A470063F12466393EDCB44139AA576554E143CF818FB22811CAC1BF8689A3 + 32727CE421B4C3F0E1E50FC30763C2E6C1DBE8C23C5A21C707A1D2393ED4AE7C + B12DC387FB9E71E27A193E38A17E2BF860C7C8CE5B6D777C14DABEC4885E79E5 + D571ED5233261E782CE6B4084EA6F12BDEE944473E4B8DB4F9294C717DE632D9 + EEF68D6EB5BEB377AD2BED933446FDBFEBF56E127CBA85F648A253A1498ACE86 + 19AE90B40AC12906C6BBBE30D517CB063A29699B8AB1A80DEE75075A283DDBD7 + 4A7584EB54F244176D57B7A85F0A29FDDF5C5D8FE5762B160F5E1ACFBEFCD6F8 + 52A2D597645630CD25638C302C7C90908F5D6D7EB44A193E843F8461C707A917 + 382711EDECA8F8C04CCC89F2C3F807EE06082755F8C05447024F76DE393E3CDA + 37E71F7A17D70DEEABFFEA379A9F3C922AE71FC2337E656AA3842EB54165E316 + A0F244AF320D9DF30F4F868C1607939F6BABE813021DFC03AD6F15FFC8F18106 + A70A1FF9998E049CA8CFF8FB8AF6E0034B08EB4B59BEA32A7C30D737C307A744 + 8C820FDC393CA3BBE83A2E3E585F46C1876BA308C6E11DDDD3FAB21D7C20036C + 828FC5DACB5FFEF28554D93C529C769DD89AF1A3604174023851A46162878414 + A8F70039FE1CEE6038EC723BA9245F0F9155D938CAB268709E146A3E8F768069 + 61522322034746549A9C6CEE21B8BE4B4770501B24286A72A046D4E0E3630091 + F1BD2A4B80965F2CF2986808D7E784796CB4F81EE99EDE21532A0030897863C7 + A3773CBD8040C6F8BAF9D5A571CA24BA824849E103153FB66DE8350C1FA231FE + 48E043F50272A22A70E2DBEC7261D64364D5272256CAF0C1988D8A0FDD13B637 + C3874780800FB547175A288D1FE604CADE0A3E08EDA54D1A637DD62E8F5C2DA3 + E0033F03C7872E34B2AA6B57621CAF3E7A631C38B514BB1E7A32F6AFB5E29274 + AF373B1967D7570A61A9A6BE74DA857034DD91C0D437C9351BED42BA910CA4D1 + 92002351AA574F7F1545D7EAC56CA76FB2935649A3DE179ABA03C1A92F04A1B5 + 2A6E0D84A10DA416DAA9F58180D617AFBAEAE3E0A71046569340D19E8CD5D4B0 + 566A64ABA16FDAA9CE4E4C24E969B2D98DF9F576ACA7BA4E259A2C5EB63F4EDE + 7E73FC45B71D5F38F6C8C68E1C7AE1BCCD1C87F709C73E1FAAF021BAB219D105 + FF20ED09F8D09C28332F0CC387183D267C619813E61D1FE4C81A051F6C92727C + A8FFAA4BDF218C94F10F34122C5AF05BDA86F96518FFD0251A8B7F20B8B11153 + 39F8DCE959CC859BD1CA37FFE21F9AD79813F171C49F10C500F4AAE21FF05B5D + 6C5CB6820FB472393E70CB403BA4B27C5C46C587F887FAE6F820E50F18F7E8E8 + 327CD056A2CF112CDDA2434461153E10D8347E444A9232457819151F04771040 + 54850F5D657EB465B4626CF5AC34B36A87F081F52CD17DB176F3CD372FA406CF + 932B4920415D8FB3727EF9AE15E91D95B33A2F90E358C6A2418E8F511A0E4138 + 7D5997CA5087D4111646A444D5CF5946B92D96C50CE73E7D8F10A2CF228400C3 + A18D79E4088474073992196A916211D3E22CE26AA2A81CD483559998BDBF3CA3 + 7ED11E7C5BE45827BAE1CBC4E228A6C4E47610E1CBA0FE621A23C456A0C4595F + ED6682E73B3E07270C12E77BB48B1CFA380A3E0825767CA0B2DF0A3E78A60C1F + 32619222007CE0C4382E3ED45F9883CAF389370A3E50DB6B025F4C7C48004505 + 5F850F378B20B8E1C3C6A22A7C146793A53AAF93D3F7B9B5D8F3E013B1B7251C + 4C476732BDAF28B84E23094A8D42E3D3F7414ACC2D0922F58148E37A925A0F0D + 51AFC8CBD4D714F5B5478586C89EE93B2BB964D4DEB85FAF0D9EE9F62E3C5F53 + FDED8DFAEAE0973A156D979EE9D6FA5AAC7ABFA94542834238D3D8491324DE25 + A1226DD07BAD669CED34E3998307E2F1DB6F88CF2F2FC5B1B488A10D200504CE + B3E083B0F251F1216CE6874D3B3EC8FC3D2E3E88EA020F9A0F5BC58767BF27BA + 0B2D2F59FA87F10F822608EF571F59D4E03F65BC837E39FFD085464E7C02131E + A95446E51FCE9FD000928640F7442FEF1B267B4F385BC53F5018905E409F35D6 + 44E88D820F4C46F00F0EBFDD2E3EF0DBC1978F0869A296F19942B8C64479B1F1 + 815F70193E48F3B2193E343ED08DF4411AD71C1F7ED4D338F8700B9CF091DAD5 + 770E57E67015A80AF48B9F8A8701E61232BE4FBA87239CA4644E3A16605431DF + A96235BC4CFD5C36D83866A90D387C21BD32009EDFC61993AB07759F5C20841B + 13EAADC141F5E9E19D2E597B9BF0F227DC11A738B2BBAA2C49BFD072540D9BB7 + 15FF1DF5DD23AF98A09EEBC96DEDBE33C07F42A0244B2C517C7E9A3A34CCF35B + F13DE1B524A763578C59CB138A8E820F4D7C425C0963C569FDC5C687DAA57680 + 0F76B0393E5CBD5E850F7CC9446F2271B68B0F54D655F8A0BFA3E083684B2225 + C1C7D2B9A5B82AB5FDD5975F11BDFB8FC59EA5565C3E311DD39D6E7414F91609 + 8775A50AA86F98D30AC169433B64BB4A13A20A3FA6DE00E76142527483DE1726 + B9DEE08BE7094617CA2984AFDE05414B0250A731187399028B7A3AFDF707CFC8 + 3C57A70CDEA31D32E5A5FFD61B69CE282F54BB57F84A89620BA93F279230D83E + 7C659CBEE3F6F8EC732762A5DDDA887AD2053E5C4B93E7F629C38776FD2CA639 + 3E88F061E1186523C1B88E838F3C52AA0C1F64E3C74C07FF70970B9F0F39FF50 + F99ADF65FC234F385BC53F1050D5169CAE452F7265E1F3A37656B947F8E52E27 + F05336DFCE3FBC8D5831726770F8078150F00FCC5638EF3B3E28B30C1F04D788 + 7F68ED14BED44F0902EA377E887A6F27F081EF10F840007C21F1415E32954B32 + 61DE2B5B5F5CF0041F128EF4BCD60FF081E541D8C1E1DD1DF5B7898FC5DA9123 + 4716D220CDE310E7B96B20AE1748A77DA1473AD6C228095683CA796B98CF9CE1 + 8C72E5E0F48475103FCFF25A96008D76BBEF963B017AE22F80934705E8F2F2F1 + 29D044C674A505912CAF6804DCEF6618B09D9644EDE587DABA0A318FF601D030 + 22A23BC847E4EA550733CCD5E9E640A52E6FCB4EE103610AF5F74EE0C30F7E1C + 071F44BA80D3DC8E9EE3A38C5E5E3EFE04C2821649313E2D884C6E70F862E103 + 6DA9E3636F1A9F6FB9E5E571C9330BB1EBF889D83D3D1B33092E738A8A934937 + 8918DD895EDFF4D6ED0B30F581E024014666B3FA20DF527F802EFC8F90D27321 + 08CD0F9FA36F79AB0F849AFE739D70DB9C4C7A455F366EA53635CC67418251A7 + BBE10755603D09528DEE05C1A9FFF7423BF46FB3A6CC50DD9848C2E1647A5FF9 + A3261ADA1874A2B59E76D4E9C5B3DFF48AF8F44BF6C51FFFE59737C5878F6915 + 3E48022BFE41F082C66527F1E1EFE7F8F0B95A850F12466E877FE0DBE5999F9D + 7FE4516CDE27D7A0939C74B0E3DF70A2C744E3A1FDE3F20F16617F1F216618FF + F03140F3C8FAE2820AF8507F39B6A80A1FFA8B6F598E0F7C78F4CC56F0E18713 + 3B3EE0DDC3F0C133A3E2C305B151F1815F1782D8A8F8C0E427DA687D113E1098 + 840F5D3B8C8FFE912BA9F1F3DC41D2F3E3523863067F2788E84C9A245B448A10 + 89E136E5B2412E8BF6F1EF7C52E78073699841F58EBBADD2B36BF33DEDC7D747 + FDCD73E5F80E887A891C240A06EF7B7C12724DCE66FD7529D7BFA36D3E2E00CF + 1745DAC584274A91BED37F346DD485B68CB6D2DFB2480DD762383E30036E860F + 3D4B9403BB4F26DD76F0C1D894E1C377763B850FB444445D94E103DF28B24163 + FAFE46C487CA3872CDE178D51547A2FBA5C7E292244ECC4FD50AB35A478B5C3D + 8D793DF5B548195004FA177E4C8D8176A856FC760B535D6D907FA956FCF40598 + FA86B07241E0E96B9C069AAAB81029D727C005CD539A81F6B95F6E3DFA824F41 + 076997BA179CFDEB264335060EE3DD24F2F56A174C8285D9AF7B41702A9EEDD6 + 8B9674530132ED3552998DD49F224A2F7D33DDAEC74AA2C5632FB924EEFBD6D7 + C6FFF7D023717A61715BF820A9290948F16364D1DA297CD006C747991050860F + 78872F50EEA353C63F7267DE9C7FC00FC43F3447D46F3F907618FF60C3853618 + 477AA7C30BC93FF285155EE2634DD9AC9198D746E11FAC2FEA2791D1DBC147DE + 87DC517B27F1A10B6DEA66F8F0E84FDA81BFB5C67C147C60C2D47C2AB4E7E9BD + ADE2C31DE0737C0CEE2DD6AEBDF6DA8574739E7400843AAAB3D8E0397F0D093C + 3FD38B5C1C1C30AB06FB6E3F97D25D9A5547452424711AEC67C6508F138E0E7A + 54436E4BCDF393700FA14875EBC2D999B056F597B4EEBAF27371088DC5E4827A + 12102081F33CBB0E7D26811EA9F073707A5489A77CF709465BDC7457969BC8A5 + 7BEA66978039CFCD8D552A5A263EC7E3301988D0E37DCF7D53850F32778F820F + 5D642EDE0A3E98A4B963A16361337C60E2D42E90849E3004DA8DB045BB391E40 + 7591C70C5A82832A7CE0F355860FDF79ED043E848157DC7A475CD19A88C61367 + E2CAE9BD4586EF88D542EC1988137D6D526F20C424A163B6DD2DA2D47A03C1A9 + 5EF82FB50BBF25B443BD415A01520814EDF7CFDDBEA64A1AAC5A8FE496C6BCD4 + 87A2CE0B66B5FA4037B5919E209531D1ED0E5CA3FA36B646ADFF442138D5A44D + 5A4FE25762D8FA81949DBE33BAEA96C24A029222025B75F970A57629DA2F095C + F55EBB30F5CD367B31D792137CC45349B03AF1AADBE393CD561C5F39BF61A2C0 + CF92DDAEF38F1C1F981730B98C8B0FB257E7E77D8D8A8FDC14E1FC6618FFC0FC + 815600BF52CC4955FC037339C75BE09F3A0EFFC02F8CFA77927F40A37C1D19C6 + 3F9CC797F10FF721C427898835C7876F54737CE8827FD0A661F8603D15A6DC92 + 920B0D393E1C3F2E64B94521C7474E0BF031389264236BBDFA5B850FB7E66C17 + 1F1A67349A443F8E8A0F3D8F66CBF1E18266868FFE5975D238913600BF110D34 + 8798924539579DF995DB218735985041F23C6163F541F3F3751CDC0EE6BC7EB4 + 5E3852FB2E82BF240A7435AAFE27B32F892FD536B511A7B9BC2FA8C5694F99E4 + EA522BA1E438673328B9BDDB7737B4351F6C0696448C447BD11E073860F3A82F + 9EF3C849C22E519BE6BE4E65F8E0C04D721DE1E8F78D8C0FCF6552868F3C4713 + 5A3A0E80DC2A3ECAAE51F0911F8E3A2E3E38BB2FC7C7BEF97DF1C657BE266A8F + 9D8E38BB1297CCCCC5542FEDF69A2B31D1680DA2E1BA45F459A3D729CC75539D + E86B623ADD81B9EB828F53110DB72135C5857C4C30E578BE4668C3376A70E5DF + 150AA5DE20B5C8460EA8D8F84CC97D41A9570843858835700E57F45EF17C2FED + 3A8B726A171CD37BBD0DAD5671B787DFCA44BF8CE2CB762AA35568CE1AA9EC6E + 92AC261B137168AD11EBABE7E2BEEBAE8E4FDD7224FEF4FE0736F0E12920F01D + DB097C104955850FDF3C94E1C3B5BA948B5F8EE3C33524CC0F846E8F0A2CC6CB + F8071A02345CDE5F7F5FCF9027C7F90759EB2FC6FAE279DFAAF887D36818FF40 + EB8520E38B7F2E3C39FFD07D42E449B0382A3E8639337B7D44DA79B4F3307CF0 + 77A7F191AF2FF8A0E26A53850FBD83C095AF2FE0A3EA2C3CA70563310C1FA4C2 + D15812B0E4CA1CD7E8E5341AD0A0EFE3A4A83A8F2020C331BB56228DC488FDFC + 96FC72D0E5E7E8F8A56738E5D9F39CF8A29F67ECA5E32E64F8C2436791F6F377 + 9850D85191282571F28CA7B1D720A261A0CD791F72734895FD9B9C437EBC81EF + 18DCB1944493BA5CA3E2E5F12EEA77DA03FD984C8C89AB84C929E42A553F3F88 + F3BB184BE8E2491E61982E994B80DB297CE83976298E0FDEDD0E3EF2BA737CE8 + 62720FC3879E610759860F67A69BE1839C2155F8F08330C7C107CEC08E8FC24C + 74D9E5F1AD77BC32DAF73D1D97C474CC4D2506DE6E4533756132090C739D3589 + 0D72BD2E04A2298532B73AB1ABD52B124CB66AED68D72EF83815A7C8F53A03ED + 536D9062C054E4D1177A6ADD8D1351FACF72169DDA96FE9FE925E1A437D8F515 + 76BD565FB62A8E5D19085B03CD52E19B9404A2D55ABBD082299F544FFE4985F3 + EA5CD4262722ED3B63AE2541AF551C129C2815D3C2CC7AA265F483025693C4B6 + 34D18C896E62A6CDA9986A4FC45437F54266BB584F95AAAF4920124F99A8C554 + 92D41AF27D5A69C7897D7BE3A9BFFE6DF17B0FDC17CB2BAB1B19F34940C88EFB + C5C4479EAC31C707828A9B5CDC64EDFC43FF6B7D701331F385200B22A172FE41 + 5E21B4D6D4CB5C965028DEB293FC83B34E59F4F3F565039F994091F30F170AC8 + 5C3D2AFF202A0B3ECBE2AFEF86E1236FC7307C2064081F6C725F2C7CB0BE20F8 + E95984A66F147CE83E4EE46502B3E323DFB00EDA7C41E3E42A49D46E1019A745 + 063D5711E7835A2654F87324CE44E596AB860536D29F93840AA1C7B51F39D1FC + F80B774274E7619F24B4479F0138EF13BAE8EAD71CD8AEC22D63828081A8AF7C + 62F2995C1AEE8F441980DC233EBC7C97C0735B3CEDF1C315E91FC9C1008C54C7 + 08626E22CA4105D0B0BD830F4D5A8FE4B998F820EF0D1A301CA59968F81C54E1 + 8371A19DE3E203276F98CE76F1811056A602071FE40E727C30B6D06C337CE8FD + 5B6FBC256E3A787D9C7EE0F1B86C6677CCD613C63BCD819377A25327D1BEDD2C + B44D32D5D5258CE85EFA3BD1EE9BC66ABD661161D71BF80BC9B15A2CAAAEEFE5 + 0B259163A251084712BE3A8D5E9112404EDA736958763513BDEB9D58A9A79D65 + 37ED96937CD24C6DFDCA4C33BEB0763676F7A6E3D2954E71C65C33092B45C4DD + 40EA2ACEAA131E45CFC95AACCEA6B1AE4FC6647D26E6849999C4AB4E3C1387CE + 2CC7774E5D9A84B285D48656CCB4E7637D6A2EBEDC391F5F6D2A1AA9115726E9 + EFD6A9F9B85218E835521969FC9BADA27FFD54089D4280EA3424584E141AB076 + AD1593A92FB3EB89E12701ECF8EC642CBCF9B5F1C9F34B71FCE47363E1035EBB + 5D7C10C98CF6D1858271F051C63FDC3F0A9E45F0836BCBC8F5B61DFE8106B78A + 7F9499A4F30B2D12DA8E32D32379911064C6E11FCCA32AFE919BDDF89EE0A49D + C4071682EDE003C5C856F091FB25F13DC10FEE2F3A0A3E5C6B44D424F8909337 + A90EFCE0E48B850FCEDD2BC3475D47AEC8C729BD58388713A2ACE827F2C590D0 + 512A33CEACCB8FECA052074CD98520A08580C303CBA20AA887DD165A1F7635A8 + C47D91437A66D707B3D0F7749E307300AC76E8C2DCC4A4C07919FB789E42DEFB + 3C4CC26580C831C2C0BADDD99DD23DC53F65E97D3D47DE1E5737BBBA559747D5 + B80F04F5B98F13D956012E8ECCFA8B50EA025E8E0F9C9E0136F820AFC756F1A1 + F2B5B318860F22065587EFDA46C507511B65F8704771B44DEA0FF88051800F7C + FAB68A0F8E5640BB96073DE83D9918D547320A937F0B7CE8E270CC2A7CE8FF1B + 8FDE182FBBFCE638F3E8C984FDDD7DC1A09D162AED20BBFDD07F99A564962BBE + 9399AE8832EB14DF17663045FD24C14AF70BF65BEB67FF6ED4FAE6B2C2F15A73 + AF51EB0B5B5DF90DB5634D4ED79313B12B266272A9192B4998594F24DDDB4D42 + FC722F4E2701E9E3BBCEC735EFFCAEB861FFD5B17FB115F5BD73D1D89304A299 + B9982E4CE9697E4C4DC69432E2EBBCC899349FE7529F27E762AA3117BB7574C9 + 73C7E3E77FE487E286AF3E1A6F9B3A180BDDC7A33BD588E9EE81F8FCF2B9B8FF + F0C1F81FEEFEE558583C135FFEFD7F1F2BFFF92B517BF4C9E8B5DA7170D79EB8 + 626E2676775A21CE30D74E7D4B82542BF5792DD5DD99EA3B9BD7C563C4CB92B8 + 981013675617E2916F7F53FCFED2729C4CF37C547CB8D6A20C1F6446E66068C7 + 07D8265085647F5BC507F5F942E8119BBE98913F8D79A2727064161F702D2738 + 47DBAD3926FE413E38F80791D855FC761CFE217AA17D29E31F9C7D86898B7C52 + 449CE96FCE6FABF88747A9E5EB0B9B2DF10F8DA3BB3D6C868FDCF769337CB88F + 6A193EF43DF9B02E263ED41F34478E0FD69C61F8C08F6D183E38CF76ABF810BF + 151D840F8FD2CFF181EB8ADA432674C6BAA12357AEBBEE3A4925F3EE588B2330 + 020C1A18247457DF5129DA819CC81048CF91395A49FB1E7BECB10DFF1A246F06 + 83707FBD47545FAE0980F1D05E0FA5A52E9E210919133C1F7054AA48C26A8F32 + 95E3DFE27E26AEAE2CF351F032F1ABD1EF830F3EF83CA1C97724A2B32E9234E6 + AA597732F5FEBABAD40F8B24EBAAFA415E0CDF451285E04EC3125490C2F3E811 + C05D850F76504C3257DD56E123F72FA25D2A5321C78F3EFAE886C923C70747C9 + 8C830F8FC2D80A3EC837C23B64B2F7BE6D051F129AE5FCF8D0430F7D1D3EE8CF + 56F141DDBA7FFD91A371E34B6F8EA52716E3923DF3D15C4F8CB2D32CA2E61A7A + 56F5455F509A6817B9BE0B61A910A8DAE9EFE0381469A0E624947795A2208A88 + B5DE207CAE93FEEFF6FAE6BBB9762B76AFD76257AB9F787225916065B6510854 + 5D095DB5F5A83792E0D84B9B9CF55EDCB7B61CED6FFFA6F8DF7FE7770BED55DF + 9E470C9EFF8DC1FFDD4122CB84B14E6A791A9A95C45C7FF57DEF8D87DEFFA178 + E781C3D1595F8AFA6412E292C0F695D67A7C6EB21B3FF3CF7F33BEF9DBDF126B + E9ED8924202D3E7B22EEBBEFCBF1C52F7C3EBEF6993F8B93F7DC1FBBCF2CC555 + BD89B86A72365E32371FFBD65762B6B51CCBA98EBE99B29B04A7B441913B5473 + BDD0A4B55BB349787A63FC7E7735094F678A73BE5860B78A0FFD2AB248BCE9E1 + 871F1E8A0F361155F8707F197C7EA8DBF90787A33287351FE01FBEA88A7FA02D + 5179689CABF8872FC6649D262586E611690546E51F55EB8BE6B2B2811F3B766C + 631EE4F99838F2090189B9BFD9FAE2CEC6E3F00FB418D05F7FB78B0FDAA07405 + AAFF91471EA9C48704565C4646C5475EBF2B3270D5A0BFAEE5D92E3EF83FC787 + 8429DAB81D7CA85CA58811BD5C20F631C65F51BF5A3FDD1D6640D7C55A126236 + D211D07911588DA660A2E524F5B9331DB65A2A22599447160094DC210C829181 + 54420AD166AA9B4CA978C8BBFDD13537FCC5C90B8776CEC98380028FDA9FE773 + D0337A57BF104F6DE1081554A2AA1B2D8E7ED152B8F318392B3C82893EFB206B + 12413F24710DA8261334F5E801071913024D20D238E6377CD1D42642FEFD8044 + 7270E0840718D5D7FC406557618E820F95E1F440A3A5E737C387DBDA737C080B + 7A86DD99EA26333D290D98707962BD71F0414243DFD9412F61DC9D05452B76AA + EEF7B45D7CC064F51EF8D067B54FF860D1DB0C1FAA1F4672E88A97C6E10337C4 + E2C9A5D837B7A7104CBA4968A8B5DA319B041999E7FA916DDD42885238BE42FD + 0BED93E69EC2F37B8373E4249CB7D33C680F7C007A9D8163783F014167909A60 + 57673D3D977668DD24E04E4EC7D95E2B4E77D32E7F326D8C622266EA49E0E8A4 + 9D63CCC64AB7117FBE722ADEFA4BEF8EFFFE877F343DB712BB5612B62612CD6A + FDE49A8540A69FFAC0C9BB2EF7A37AD4D713B66727E59C15FFE6DF7D227EE35D + 3F1C7F6FEEBA38B4D68C73F5B4BB9DDD1B0FA53EFC419C891FFDC03F8EEF7EC7 + F7C589D4B65EE19793FAAB63416AB3218378ABB91A4F3CF8503CF4D57BE2A1CF + 7D2EEEFDEC9FC7E3C71E8F2B93D07567AB130727E7E2CAFA6CE1EF559C9337D1 + 8975452026FA5DB6BE3B4EA636DCFF8657C7BF4F5478ECE9A747C20773721CFE + 410673F0A1CFC2870E821D860F9F5BE06318FF20E43FE71FF839BA833BC90B47 + E11F4420B298116D4B467678810B7398C7DCBCE22957AAF88768A4CD899E21A2 + 976390585FDCF1BC8A7FB088E7FC833125021D4D5619FF70FF20D2D7383E30FF + 810F3FAF4D97E3C3A3F9CAF001DED41EF14FF13FE1C3036A46C507FD25616E8E + 0F140CD00FCB84270A1E071F6A2BAE2D9BE143BFC81FE0C305A151F181564CF8 + E0B06525F4C6993FC3475FE3946ECCB3EBF0481D37D98818E4DF605740F8202A + 51111166A14A34606AAC1638162E1F281A828A8F0CDF94A5FA50A9D170CC67B9 + 8F93DEA3ADE4CA50B9F57A7D2334520B8F9F9FC362EB4E7D0C2467EC6173D73D + 163488CEA9D07CD600907D1D4742DF2D10E2894ADBCB54DDAA0F131563803D1E + 073B6F9FCA26078C9E176D98A8A295CA22EA25B74BFB4454FF706A65E744B831 + 99E447C50713C9C34B61208E0F95297A71661D9959CBF041982B9162689AC6C1 + 07E77395E1438C59FD173E188BEDE08367105CC7C187704A96607DC789DF442E + 6182D80C1F60E0F0E1EBE2CA4B92D0F4DC6AEC9A9AE99BE0A44DD298685C359E + 4A25A094030AE72F04A77E1A80FEFFFDA83A2585AC757A85A09496F8E23B45D9 + 4D7594E7A85B387577A47DD10E5D9AA7A9BEA6E74412601E5E3917A77B2B3155 + ABC74BBB33F1F2BD0762B2792E9521E7EB5D712C95F5B54B26E3173EF65B71FD + CDB7C6F26AC273474EE8177219144AADDA406BDA3FF52E096F4928EBCDC4DADE + 7A3C72FF3DF10FBFF7ED71CBD79E8D375E7A65B49B6913901E7FB4361DFFB1BD + 146F7EF74FC40FFED4BBE364E77CEC49C2D6AE4E2DD2CC88759D5DD7AB1742D9 + 446AEFE4D4442144B5537FCF9E3915F7DEF3D5F8CB7BBF180FFED96763F9CFBF + 16FB9F3A150792C076B091E6F1542D0EE890BEF595C2176B5FAB118B49C8FA8B + BFF68AF8835E339E7EF6C4507CB0F0B0604833CDE66E147C502679A45416D991 + 117684712DE8CE031C1FE4A0531BFD2818E65619FFC805BD32FEC121EDEA8F3B + 5857F10FF16F8FCE2B223F07F393C5567D565BE10D9A4F7A9EB3CD46595F70CF + 20A5816793C6BCC6A1EF39FF80F74B6B03BDD080EB33FCC3FD8586F10FF8D4A8 + F8C0A54374A8C287684E34ADCAE0581402783896C6F1A1FEB810053E18234E53 + E02816FDE5E82CB097E3039E75B1F1016DB1AE383EA4F512FD86E18383DDC107 + E77CE23BE6C7F8808F44C7C5DA1D77DCB1900668DE6D7C4C0C376F2049BBFF0C + 36475582FD94705CDD93494E6548722BF384C7264D6391FA50916AF0C893C4D1 + 17EE5C4D9938C7916491107D6CD8CA26AAEF9F78E289E279D4CFEC789C304C54 + 040022935496E7936081F61DCBF5D75F5F10DA9368BA2601CD07A06497E1FDD5 + BBBA87B602210426407F05246F0F366AB54BEA7D3DFBE4934F6EA41AA03DF94E + 05E9DFA30B88A6C44E8DA45F850FC2F4C7C5C7D5575F5D94CFE9E965F8D00473 + A1C7338C8B06A3E24313470B13C22E4C5FE50B1FFA2B7CA80CE8C5AE68147C20 + E0E1CBE6FE203043E1438CDA37179BE1C3B32EEB3BF081A6CD23E7727CDC76DB + 1D71E5C15BE289638BB16FD71E71EEA84D484BD0178AEA9D5661A22B04A86E5F + A32441A95EF838F52E084D85C9AEAF8D52849B7C967446DC4C7B70586FBBD78F + 6C6BA51D79123CCED75A71FFF2C9787CF95C74AF3818D7BEFE35F1E6B7BE351E + FAB3CFC77FFAB58FC4DF387024265AE7A3A1BC49B13B3E73FE6CC41BEF8ABB3F + F6AFA2B7B29ECA49BF891FCA013C9EE7B2C022D1CFA4D94802CCC4F45C9C6E9D + 895FF807FF539CF9F0BF8A1FB9F2B658EAAEC7F25CDA54A4767D6A6129AE7DD7 + DBE2173FF88148624074D79B71E95A7A4F499B121D9A69B3BC3C551F58017B7D + 47F424484E145AD07A4C696328FE2741E289C7E36B5FFA4A7CF6739F8BFBEFFD + CB681C7F2A0E3C792AEE9C988E7DA927D32BCDD8B7DC89A554DE7D6FFAD6F8C8 + 638FC49A2D8E393ED0A0826DE1439B1D341165F81036984B65F8D0228826CAF1 + E1666A7DE6F058DA037F17FF90F947171ACE9C7FB843AD4720F90288EF1E8219 + 73D3356C39FF401B07BD387B0C2D115A7F16B66BAEB9E6799B899C7F600DC154 + E5FC037EABB9081F1FC63FD072C33FA03BFC43ED7DEAA9A736368FC3F807FC0F + FE91E34397FB3FD1F6A3478F166BA90B07C3F081A052850F7846193E543F9167 + EA03020BA62EDD031FF9315EC3F081967F3BF8208F98FAEA5A22D65336BFC207 + 47790DC307FC5675F991399C359AE3A3700E3F7CF8F042EAC83C6072F59ADB4C + 59345D22E6CC255DD84FC99C9BBFEBE19C7E114AC924A7E36E8346AAD720E6E7 + EBB0F8A97E114ADA042DC410135090D703BF2AB7D933C01E8DE0EA608416D9CE + D51E8F04614700B8018567717641002111F314020F9233A0C0492E4FD006ADF1 + 15D344125DD0F070769068A9FBB4C923B25C00A0ED9EB34863808D59E57BEEAB + EDE04363C3F94AA3E2835D0EC21CAA53C7077939A0039335C747C27AC1984457 + 160F7640A416C0AF8A367A86ED61F810EDD45FC70787673A3E3CA263547CB86F + 05E646DD1B868FABAF391CB7DEF62D71ECE185B874CF25D1594BC28FCE7EAB6B + E1E91F4352EFF635478DC2A9BBDB37CF258148DA9E28BE1FE47052D45CFB821F + 542D095C8AB493B24567BB290540DAAAC4F1A58578F2F4F1E8EE9E89CB6EBB25 + 5EFBE66F8F37FDCDBF19879280FCDC7327E33D3FF1E3B1FC877F14FFED4B8F44 + 6B6DA938F36EE97C233EDD5B8DB7FEF2CFC63BBFFFFBA379763D49046BD19C49 + 0CAAD6B0037F9F2F3EE9F644E18C1BF1C98F7D343EFC633F1EDFBDF7501C4912 + D7CA642D8E4D77E34FCF1C8FFD6F7A6B7CE05FFE4E4C4E4FC5C2DAB9D48FB42B + 4F3D6AF4FA39CFDBF52460D53DA9663F95C254ADEF9BD5D2C6666A3A09990A3A + 4882E9EE2852313CB3702ADEFFBE9F8D2FDEFDE1787BDAB01D55A4A00E0595C6 + 26D1FA58A313F7BEE5DBE2B7FFE22F363640E21F680BC007F363147CE8621301 + 3EC0BF6B91F5BE3EABFC2A7CE04BA8C58FE4C6048768BEE83DDD1F857F300F9C + 7F70248AF807FD47D8ABE21FCC251674690CD814902B8EE8E332DE53964D1BFE + C11C855FD31F8D87EE8B66E20D6EA6E37FD2C9687D11CF4793CFE619BF5CB58D + F5C5FDA3B0C8E4FC031E45DB727CC0A758E4A1D156F0C15811A99EE3C3C78664 + D0120865DE2330014B89840DBDAFF100133B8D0FC76D8E0FE8250581AF2F1A3F + 0E621F171F5883B01094E14302D8A06FCF3F72C5557F6859BC6297C651E9A2CE + D56E1E551A9DF47044D497B9AA4C0474AD16AA4E95836D98448868723C878F7E + 0534754C846407212212BEA8090880FC847BDA467FDDD64A5B6138A863991C68 + 2F7C12F8E0E683078064BEA45C428DF517C768B5994CB344137A6658FA2BBA48 + 50C22F8793A831B1918D18952D63E70BB04F9A1CE4AA5FCF41B761F870C180FF + C92CAEC94964187D2DC387D3CDF1A15D1E7843ABC42E87837949468926A70C1F + FA5EF8104D51EF830FDDC7A9D34F30F7BEE5CE863E2FD08C71E23C9192AE8676 + C657850FFACB18614E001F64F627B15FBEB05DA0D9A5F1CD6F784B3CF24433F6 + EDBE3409398989B706916FB5F345966F094E1292FA8EE198E2BA030D546B1061 + A788B981D6A9F8AE5744DACD25C149C92C740CCBD9A5C5787CF1D938D95D89BD + 47AE8ABBDEFC8678F3777C67DCF8B2BB62567E0EDDBE94F3F4138FC6BBDFF18E + D877ECF1F8D64B2F8FB5F544E7A9C43F163BF1C50333F1D3FFFA5FC62D476F8C + E642DA89779AB1B24BF99A1AC5D12E17DCC395D6A0D64F62293F8C44837BBFFC + 97F18B7FEBBBE3558BCD7845EA7767E15C4C4CEF8A3F5C3C1E275F7543FCCAC7 + 3E11870E5C19E797D34E72A211CD242C2A3B784B4EEA49706B746A31BF3E380E + A68E9F56C2CD641AAB5E1F476BF5B4CBED4EC425E9D999A9461C7FE6C9B8FBE7 + DE13F77FF2F7E27BEABBE36549503AAB77EB699E2A4FF9442D16D3D82D4CEF8F + 47BEED5BE3A35FF8DC8643B2E383681DE6DDB8F8C05C0D3EC881C3E256850FF1 + 08B507FEE1C77960B6C6570A9320ED64C350C63F281FFE81267C18FFF0F75C33 + 038FC31C84D9C58F771A857F88DFC2A3F3F545F4122D48B2C8A6CEF33039FF50 + 1BF063F2849D1C8FB219FF70FF5CFF0E3FD01C1FF92633EF67193EC8483F0E3E + D45F02A3C087BE9760083EC001F8C0AC360C1F6599CBC147EEFAC3FD9DC047AE + B9AA923F74693EB111677D619D021FC81F1AF3815F5BDFC749E908DC77471DD0 + 62A28173BB2C83EF3E1BF862A0D6F27C440C749E2CCCA57A7558C453E30867E7 + 19B279A36940E2F3090B28F5AC061A0D828848883C60F185CECD907A5FFD456D + ED4E6400015B391A22FDAF414342F5C5D105905CD8A48DEEFB80AA537D405BE4 + 2A46176CE82F2A467610A890F11103041EA9E00E8F1264B4A3C9B3840350958F + 20E063B71D7C087808AE8CE1B8F86002E4F8C0BF43D7307CB043147D727C2000 + 3B3E60D25BC1878446C6D61D3AC7C507A1D11A67F0E1FE0A8E8F9999D978F537 + BF319E59DD9316F23D3137951872AB1DD34918D2B12912842420F5B54B7D939D + 7C9C267AFD3402C5D12ACAEBD4ED1F47523C533CDB2AFCA12458299DE433E7CF + C643A78F476DFFEE78C31B5E1FDFFED7FFEBB8F39577C51ED120091EE73B69E3 + B394F0504F34DD3B1D5FFDC2E7E397BFF7FBE2556B937144E715363B9138457C + AA7B36265FFFAAF8F57FF1D1682943F7F9667A27ED8C1B3209A6FEA47BF2A152 + F203E5755A9F48D84982CC6C6332D6CE2DC47BFFEE8FC733BFFBC9F8FE6B6E8E + A9C5E538B77B2A3EDD3C17F75CB93F7EF9773F1A771DBD398D6DDA3CD4FA47B0 + 14181F086085DF94E8AE449C4948ABF51A85C649CEEDF5A988D5DA5AACD6D723 + EDBF63A6B63B3DD88CFFF087BF17BFF953EF89CBEF7B38BEE3D22BE340DAF036 + D757636DBA1EEBD36A675A08D2FB7BD7128ED7EAF1E0A197C4675E716B7CE6DE + 7B9FA7E1C4F9941DF328F8C01F8305C2B5AEEECBA9FB55F8603EB029857FE08F + 87C693C536E71F9862B4E0887FE43979E01F64CA769F46E71F1C5EEB0B1A1B44 + DACB4910FA5FB4537FF83C0AFFD08550A35FB5098D886F7670C4C64C96F34432 + 9D9306057F2B1CA589BEAAE21F449995F10F721B9186057C48A140B0D0B8F850 + 5FE0C5F8FE60B5011FBA87C62817E4C08778A6DA83D28234146CEACAD61778A1 + DA2FFE57B5BE800F126296E143ED730DA52B10F4594222D817EDC4FF9DDF6E86 + 0FFCC6C0873BA4E3E72B6CB01E6BFC06D85BAC1D3A7468213566DE256C157AE3 + 8D3716034764996B9DDC090DC2B9C44D83DD0CE603E42A41A295900EF18DD2C0 + 720614911F656A5A06448403B82A430327C106351BD2BB0F1060D17BEAAF5224 + B87F8BB7577D65E20118FDFAAEC0A31EBC9D48E72A83083D9F081C088B990DC7 + 629296B99D9CFE6286140D610AE4DFCAFD74DC714F97682AB3954232F3C46744 + CA103E8B7095E3E3A69B6E2A6CFAB956057CE05BC03B985CC107001D860F95C1 + 912BBE93918981A8B6327CE457153E34B1D1560EC387FA7FC30D370CC587188A + 1F0F43FFD42E98DB56F0A1BF3895AB6E1297AA5CB5D9F151ABD5E39697DD1197 + 1F79553C7DBA1333737B8BDC4A5349689AEC24812E0948F54E0C8E25B9E0F43D + 39D034C96F29068295048842FBA4679238A0E8BA462160B4E3C1E38F46E7F25D + F1BD3FF6C3F1AAD7BF2EAEBAF250217435D7949FA91DED4945EA258CAE26217D + A211EB7393F1A94FFE5EFCD31FF8D1F88EFD57C781C9B45959E9C4D9D494FF58 + 3B137FE3177F3ABEEFFB7F249656568BACDD4A05D56A2865413DA6253815E90B + 940C332D62695D9DA8292F533D3EFEDBBF1D1FF97B7F3FDE79E54D71F56212E7 + 52E7FEACB7149FDB538FF77CE49FC51B5EFF6DB1744E3B623B302FBBD4CFE956 + 1277A6EA716E5A3CA856F86ECD6A0198A9C5721203F74CA4C5E8DC527CE403FF + 28FEE0EEBBE3CEDA547CCBFC81985D3A5FD0A39384B9892408AE37D2EF643366 + 92E074C99A04FF897834D1ECA997DF1A9F4A383D9DC6CB9D87F1EF00472CCA55 + F810C6186F165CFDADC207F97ACAF8079B08F10D160DF2B3B9DF4A19FFD0A22A + FF44A548C84D1FF00F0956FAAB39C606005EA036897F3CFEF8E305DFCBF9071A + 89DC970B1F9432FE919B9CF0F7113D9C7FA87DE21FA20D476EA85CFD5F66E6A1 + 2E0E17C6DF87A83C842FE67919FFD0F7F24F528A042C01BE91C54C2A3E84A086 + 59CD73E28D8B0FCCFA123038F4167CD0FFCDF0215C0857E26D1ACB51F1A1355C + EB4B153ED0046A8D667DE1597D663D1636CBF0217EAEB6393E9043B68A0F78B7 + 4CA6E0A1021F8BB5EBAFBF7EE3905F2AF11073C212DD5401B03DF4554C5CBB72 + 328CE3A7A35F54822E20E97F4D2ECED6218A80C176C75B3D83C7BC87C6BA24EB + AA46018C646BA8025536CFB81F8EABC971A4430B057362C7432A03B28193588C + 9D1FD22992BC3BC3A166F7835751D56BF0B0B122748866B9FF8303DB338A33F1 + 54273B014FE0065D7C070488A12793DCA3D360BC4CCC2A7CE4BB3C95CBEE1AD0 + 0B74A2D7B8F8F0F3E0C007BB267CE288FE637C46C10711880833846497E18376 + 6D860FA29330B1711A3A89F1C6C5078950C1C566F8B8FA9AEBE2C697BF351E3D + B91E33BBF645AF70AEEEF405A7DEDA4063148570546404EFF6B54E13037FA642 + 70EAF69358F67336F57D9E741C8A9CC3279250D16EADC7574FDC1F6F79D7DF8E + BFFBD3EF8E4E7A7655CC4A1A90C644A115EA4E4F14DAAA99B5F4AE766BB56EFC + D63FFDBFE20F7FFEFDF13DD7DC1293EDF5586BF7E278AAF3BEFDB578EF273E16 + 575C7743AC2F2506DDAB2701A81BCD011F971F95CA92E0B43E9116DE46A27563 + 3ABEF4852FC64FBDED7BE275E7DBF19ABD57C6E4F25A3CD0588F4F3416E207EE + 7E7FBCEB6DDF1FBD45C5FFAD2541AE5BEA2B55603EDD9750B836951665CDE324 + 26CE756A7D3FAF545F637A261EB8F72BF1AB7FFF7F8E53FFE1B3F1B68387E3C0 + 6A1A9F44874882D68AB2A227FAEC5F4BE398DABD3CD34AED4DF86AA7929ADD58 + A937E2C944EF85B7BE293EF4952F4763E0B7264C71783A82050970F14D048330 + 7A3D0F4FACC207E1D92A176D4515FF40BBA07784553763312FA83FE797C3F887 + BEC70C58C63FD0B0B0512CE31F684EE0079ADB6AA376FD68029C7FB8C61BFEA1 + E7C93BA8EFC9068D8F0FA70EE0244E7D2EE439BDD044E81DF5CF7D3E99FBC3D6 + 17123A720F5AE833FC163F1BDC58D437D6607C9FE09765F88027A97CE80F2E10 + 12240CE02F3C0A3E301D22587028EE56F1417004F8A5BD65F840D0F3B5C1FD79 + 11FCF43FF84098655EE1775D860F0F9E10BDAAF0E1A9260A1FA7247D3F4FE394 + FB32010E9790C9AD03C34788C2CB1DE071DE1B517510C707470B0E2A63C085EF + 908023AD86064D65614FADBA3C828AFC3748DE488B38A9D12F3EE300EDAA5CF2 + 74607A51991CF6AA8B45DD4329754FC91129CB85179CBAC9E94104067E48E4EA + C157CB17FFAF63F899633BF93A50D333F9A033FD05946EC7CFCD78F86221A820 + B18F8B0F008956B10A1FA2974762D006B55B0C85849EE043F48239CB7951F820 + 826D1C7C4850618C7DC7B8557CA0F9C35C093E9C46A2BDE643193EC86F033ED8 + D9817BD14FB4921A1BFF37F0B17BF79EF8A66FF98E78E4DC65E9FFB44B6AD48B + 7376EB851F53DAA9F656FB0250BB9FAF49BF7D2D52DFFC561F68A114C5566FD7 + A2515796F05661766A74FA3E4F93D23DB53A71EFA907E2F6B7BE3ADEF7FE5F89 + 536BCB3193848349F950851CAD138D9518B2D074253C4D4FC5F2EA4AFCEA7BFF + D778E8373E1E7FEBAA1B63BDB914E7939075EFF9E598FFAF5E11FFDB6FFF4E2C + B5531DAB9D98EED60A01A429A1A538D2A57FD29DFC92D6A215BBE66662F5B985 + F8E91FFC3BB1FA479F8D1F39785D9C4D347EBAD189FFF7DC8978F37BFE97F889 + 9FFC9974AF1DBB5613936CB452791230BF5EE5A43B4A79B03CD38ED9563DE6D6 + A78ABBD2984DCEA63993F0F9C97FF76FE29FBCE767E3EAA79E88B75C7A38AE3D + 97F0D06AC6B9248C2DD4DAE9B9B9A8AF769390D828328B2FEBFC985A3376B7D3 + 5827C1A9514BF3B1D98A67F7ED8DCFBFE175F19907EFDFC00787BCBAE9057CB8 + DFA4E343F8121F19051FCE23AAF8873B4D932F4DFC97200C5DCC077816FCC37D + 40CBF807FE3A6C2CAB72F794F10FCD69FC2BD55FFA8F6B04DA67DDF3F505DE04 + 2FC60F123A93BE4597788BD6177C1CE1E5C3F887DE179DF53CF462CD629CFC10 + 793EE7FC031A40471CAF49B7C2C2EDF88037111452868F32FEC186125E8B9934 + 5F9387E1437497A08112824D71193E38ECBD0A1F6C1247C1872EEE7BD41F2636 + 36E1BA727CE0A251850F9CE01D1FAC2F8E0FD18B133506EF2FD66EBEF9E685D4 + 80793AE0129947062085B108AB420FC7472BA4CEB8260AC9D2FD45683C61D334 + 9C9D04A01011A41E54B492E722C9D5A148A4EEB5AFFFA5E100B4EEEC481B91E4 + 7D60289BC82576350C4A7E202E65A319C3A91B3A3A78D00CE95D4F24065D0466 + 4D1E3477C3263182051304E7783467EC0250D13A7D98B0EE300EDDD901AABF08 + 60D06B183E38EE6127F041BF87E1833069D149C01E051FECA2C8462B7C78CE11 + BDA73632CEDBC587C693FA98C47A8E9D56193E4806EBFE13B451BB44D10FCD1D + 74D2F777BCE255B17EE96BE35C37D531A536F78A08B8C23C17ADC2E1BB5E2851 + 3A8580D4D738F5B54E8526AAD73F72253A496890537692B03AADE5989BAC17C9 + 22BBAB89FE13334970AAC50367EE8D6BBEE9687CF0D77F2356E44ABD9676D2AD + FE01BF129C94597B2295332DFFA699469C78EE54FC5C1274767FEEBEF8B643D7 + C64AEF7C3C59AFC517CE9D8D77FEC24FC7DFFEA11F8C53E75762772FD132095C + CD24044970D2FF0D69A092C8D64C8DAF4F24E126D1F1631FFC60FCD6CFFF52FC + E0F5B7C77567CEC73DBB22FEEDE2B371C7DBFFBBF8950FFE5AB4535BCEAF27C6 + 2EDA157E5D158B43442190359310B47BAD1E93CB69A1994BFC627E773C7DF2A9 + F8E87BDF1B0F7EE8E3F1EAB95D71CDFC44EC3D9F04A475397F27612B4DA58E84 + 95765A90562722B1D4584BE5B453DB7B497092503A9BDA3125013591F55C6ACF + FDB7DD1A7F74F5C178E489274BF181691A7CE4A93FD052E1A3474410BB69E143 + F34D8B0A676D566DBC72FE41F004FC933AE11F3C0F669D7F90F685C5DEF9073C + 84A85D374FB9EF49CE3F847DBDEB4996C96BC45CC527D023B9DD7444E42C4EDC + 6822984F9A63D250687D21B27033FE81C0A632350FA13DC29FF30F68E1FC837E + E392417BA0970B2B64F9061F5A5B70622FC3877E091EE0505C5F5FD4D71C1FBE + F9DA0C1FE2B3B4A70A1FB4E962E1032169183ED0C8926BAB0C1FAEB9C27291E3 + 436BB17081A069F858ACDD7EFBEDC5912B6419F51D360457A338F88E0A599C91 + E23560248D628126CB2C607215655958A69B3334217C12E3E8E86AD4DC960C78 + 380E04F52BC4C2139F48033775B8C944C4740686973D03CA8E4A84F5307E9CBB + 91C81106FC546C1CDD011A6020511909E7D03895658975BAA1DD61570070DC19 + 90A49F9E6F039AA1D9831943730400D11146E9F8F0B07F4D680420C707BB872A + 7CA85C4CA06E331F860F4C7C3829324946C107E387BF1A13AD0A1F9E4A007CB0 + 13D92A3E5407071497E103F5708E0FCE6E8291393EAE387455DCFCDAEF8A7B4E + 4DC48C92064A7BD3EBE75EAAF7FA9AA4C2F4A61D6BB72F2415799B0642130254 + 0C926026392BD599E6527B394E3C752C2E9BDF17FB77ED8BD64A7ABF36158F9C + FE5A1CBCF5507CF0373E1C496E88766AEF747BE087D1E89BD564726B14A6BB88 + 638F1E8B9F79C7BBE29B9E598BDBE7F7C7426D39BED45A8D2777ED89BB3FF65B + 71F8A69BE2646282FBDA8DE26CBBF58924C04CA8AD32194AEC4B0C59895D67EA + F1E53FF974FCDCF7BE23FEDAC47CBC6C6657AC24E1EEF7168EC7E5FFCD5BE257 + 3EF2CF63F7E46CB4CEC93C27E126D1B06F71ABBC24EC4D363B7D67F8D984EB99 + C9F8E3CFFF69BCEFE7DE1DFB3EFDE5F8B1F9A331D76AC6427D2524C2B51B12EC + 126D527727BB49904B1D96B66A792A8A683C993EA3D6A765E1589F0457F5A391 + 5E78ACD78E07DFF2C6F8F017FE73B17BC734804042400669539823CC39983BF3 + 9485067C303FF5EEA8FCC38531F2A1C1FB9D7F301F78DFA39D58ACF12F8187E9 + 12FF67934CFBC03A6D108F4100E2D97C7DC1511CCD8D47EEA2212BE31F581C68 + 2B667E7C4171754003E3A6A75C78A27CAC244470432FA21587AD2FBA54377E95 + F00FF8989BDDAAF0C101C565F8807F0CC3879EC337D537835CA3E283F56E337C + E87D5DBEBE40E3327CE4EB8B9E4100025F084C7C561D2F043E06E3B858BBEDB6 + DB16D2C239AF4631D97222EA97F0485F4C108EDC591C0732723D88005295E50E + 775EBE97037850B3B28833297315A5EF303CFF904C5E5C22BC0685CCAC2A57BB + 33D70CB974EB51231E8DC242A77A0083CA106DD084E83BCEB9733568EE77E3FD + 55FF5CB382B39B0BB1DE062E8EAB51DD3259E982D909A4E4B920E2009BB787B3 + A2FEC5EEEDE1CB980FD5577D2700BA46087A110153850F842BD257E0DB96E3A3 + 6CA797D38B7E3B3E48E8966BAD727CE0D4296C6A8C1817B54BF8E0280BF57954 + 7CE45A41F0814F8068023E48DE8629C6E7C3307C903306D39F6F5CE69350F3CA + D7BF35BEBA726D92729360369B16A4C26C36D0D87407491D95B728153DA5DC4D + 6901575A81FE21BEED245874FB799DD2629F3EC6CC4462D4DD7371DF57FF532C + 2D9E88C357BC246E3E724B349712A3A94FC633CF3D107BAEDA17777FE4C331B5 + 7B57AC2E9F8F99E8D3614DA997EA89C9771BC521C09D99A9F8934FFF71BCEF5D + 3F1C6FAB1F8C6B531F4EF416E233CD7371F91BDE14FFC76F7E284EA77674565B + 718904A78E0ED44DF37DBADD37F525E1A4554B0BC6F4442C1C7F267EF287FE4E + C49F7E317EE0AA1BE3DCCAD9F844EF444C5F7B43FC9FFFF7FF13FB12DE97CEA5 + BEE928959A8E7349C26C6A59A2C4E040980BA7DE6DD03DD1A5DBEEA57ECC44B3 + B51E1FFFD0AFC7EFFFD2FBE39673EBF1CD870E462F098FB595C4846B49D09E4A + 8BE1E47AA4E6C5DE96E85B2F3286AF1518480B5C5B8EECCAFFA4ACE472704FE3 + 5993262E099289B0F5E5D578ECC025F1A9BB5E195F7DEA898DE4B2C207476D08 + 8704648CCA3F86E123E71F0850F059CCFBE21F7A86C510FE41F247CD5B4FE5E2 + FE7F7A5EF39BA823F8071B67CD157DA70D5219FF20424AF38D0D452E7068AE93 + CB4FE5B181D2F3CC430F67CFF9870B8E98F888E21E957FB00154DDF00F4CA4F0 + 16F807899073FEC198E859F84019FF208755193EF45ED5FAE2D1E28E0F843504 + 3A0482CDF021BEAE7B5A4FC1079B7FB591F5057CE4EB0BF810BDF3F5C5F1A1F5 + 09C127C707FC16BFBD7C7DC1270E2DAEB004BF1D051FB9EF2F51949C7652828F + C5DA2DB7DC523887E7E7E2F8852A8CBC09A81989705263F91EE94E8B34047649 + BE4C8AF7CBB5523820FB0432A9EFEB4C3B0281002250B370E959C08124AE7709 + D1CC7D4D0037FD51591A14F7B8D784D03D7D46ABA0BF301C5DA82DAB54E5DE5F + 761584B57A882F63E27E008C0989EC3491340E6A973EB3FB60B0F9DF1D9B731F + 038EF690E0CB5106448490AF03E094E103DF0BC787EA511235E183EF77021F4C + 781889E3C313B195E143E3267A8D828F9C5E8E0FD4E62A4B9863D722B5BF1600 + D153F7304DE6F87067F551F1C1AEDEF171C32D2F8BDDB7BE251E3EBB2BF65EA2 + 70DA738569A89F9B29FD4D8B7BAD7008EFA71B98E9AC0CF231358ABC48B5B4A0 + 4F160EE049C84842D59EE9A938F9EC33F1E0835F8EB7BFFDBBE29577DE16EFFB + C55F8A1B0FDF1C73F5BDE9F9C978F6D42331B5BF1E77FFE66FC4FE0397C5F2D2 + B9988E7E78BFF223E9AC93E9440E25E78E24F0FCEB8F7D347EEB1FFC7C7CEF65 + 47636FBB15E7EAABF1A9CE627CD72FFC7CBCE31DEF8C675B2B3197849BA9B56E + 21C4C954B73659246B4AC2481A9FFA54B4BBEBF16B1FF8407CE21FFEA3F8BE23 + B7C6D1F3DDF8A3338FC59FDC7E45FCF687FE451C4D74387F6625BA7333D14AFD + 99EDAEC54CAA6BA591E6C2442AA3D7CF6E5E8FFAE05CBD34CE5A64262762368D + E3C38F1E8BBB7FE1E7E2E98FFDDBF8BE5D87E296DE649C8CC578625F33097033 + 31BF3A5BF842F56AAD986D7562F7BA3478F5582AFC9A6A49606AF633A9EBFCBC + 6EADF0F392E024CD542FD161BAD38A3DEBCD3897BE3FF986D7C7C76BCD581C68 + C489AEDB0E3E3081E4F818C63FE0715A58140525DC62DE719F52F8071A8CB2F9 + 80C65C0BA0165BE635AE12C3F807DA14CD27F10FF109EE6B3E69C1E57C3CAC17 + 1C5BE40962B7C23FA0B7F30F9EC905277C7235E7116C28C7F94715BF757A9106 + 854846E88559080D33168417031FF0388D89F8B8D617F0A1B6E1AFBA193E3021 + 925F712BF8505BD407B585730E1D1F442463FA9310C7FAB2D3F8289CC375C8AF + F23811A555A515E2E03B0D2A61E6EEB98FC4E6797A304D6152F21C3FC32E8F14 + F09D3942409E9893BF121E108800B02E0D38440474EECD5F365868723410D857 + 551E0B3E8ECA000069DFA3A2F2DDC466FD456064F00028CEE8BE23D0334A2920 + 41877C1B303C0459FACB04A65D797FD11861EED36461A722A0B2700FC30729FA + 1D1F84E33B70C9A7E5F8C047E062E243CF081F6A4F7E16D256F101BD5E087CF8 + 01A130F47DA90D2FFB96EF8C2F9FBF3CD1FE9242609270507878D77A032D536A + BFB220C9272409537B3AE7D2D7A2DF5C5AE01BFD7C4E351D1FA3D0FAC578E6D8 + D7E2DCE927E3A77EEA27E3ED49A8B9FF81AFC5FFF8433F1697CC1E882B2EB92E + 7A6BB5786EF9A948A26FFCDA3FFB2771D5B58762616921261AFDECDB32ADD5FF + 7FEEBE03CECEAA4CFFB9754A2699F400291008A1869A80F4220144455CFDAF2E + 16EC8A0DB1A02808B22A1654105840C5B52DA2A2AEBB3650592B828202468A49 + 28E9A44EBFFD7EFFF39CEF3E33EF1CBE3B732704DDDF7EFC86CCDCF27DA73CE7 + 3DCF796B2DCE8954EF7482AC38802F5EF569FCE2FAAFE0AC7D0FF1D177DBFA7A + F0E09408577CFF9B3874FE22F4167A3DED62CBE384976CB71B3F74A093FE2099 + 0AEEBCF347F8D7735F837F6E9B8B791D53707FA107774E01DEFF8DAFE2ACA547 + BB360D3A6297F156327E9F33462FAF4AD69D18BDCA2DE54D67F9AA7BAF420F78 + 27D81DC9A246E8E7B7DF8E9B2EB904B356ADC1E933666376B9E4FA597104CE11 + F36CDEEBAA72DE07CCA3CCDFB9E69DE9535E9B148FB99BD354FC9A10AC2C085E + CB452D5FBA827495F5F03AF1DD338EC74FFF78EFD3F021AD40ABF890463C091F + 725C4E921FFC9799B0B9717353520921FEAB3430CAB26DFDA892E407FF96E3F0 + 58F2A3D9262FF921738CE4870E1CB66A81E4873571DB75DAAAFCB005C65B951F + 249792156A1F5F679B15BDA7F11A4FDE527EE8E027FF61FEAE0D5F7F874ED6BB + 021F1AF389E2438A8C5D850FF683F8B011C3CDF041EEA15C80CDF0A103EFB385 + 0F5E0D13739C39DCDDCC3B14D96AD761C3F9A31A683283C93EA8067163525237 + B14945B71128CCCB305EC32D88ADE94636CB30E997754693B3319FAFBC3C6188 + A405A11532F6D206A72282EC9326415A243907AAB0A3C68DEDE038111CECAF40 + D9CAA5FB087C56BD6C4F3F5AE06C83C2E0E537651DBEEDA21FABBFFA0EB530FC + 2CD5F66118E978F8E025676BA9B16DB82DBF437CF03DBDA608409EAE38D6CCEB + F2F7C007C74A6AF49DC587D4EDEAAF5ED38182648AC242EF5901C65325B1C4FE + 8E870F1B89129E12F73FF81064F73B056B7ADB307D6A37AA156AD77C96C7589B + C4718A620315CD702CB5D2562B797213D572B129CF6DF86D29B75EEB3DF8CB83 + 7761FAE4367CFA139763D9514B7D31DD8D1B36E13D17BED711AAAD387CFF6330 + D85B427F6913FA8A5B70F5BF7D0E8B0F5A8CDE811E9FB452C489DA2CA473C0A4 + 1C7AB76EC127DF7B119EBCFD7738799F8330501EC0235BD762E68947E3AAAF7C + D51194322AC5524CF438F67E7219D9E7F053CC229AD18EC7B73D890BCF7B25F6 + BC6B25FEDFEC03F170DF367C7F521FCE75ED3CEFE5E7A1DE5742CDF5AF42F29D + 779883F771F737EA2CC3F77DB09DBE53F1D8E5DD9B53BC8F5A1F6EFACC55F8D5 + 559FC721ED5371C8AC196873A4AEB35EF664C913A774DE13AE0E4FD4CDBC78E2 + 24B31FB579D438D6FD33F9BA5D21FC3BF2F5EF981A2287CD850AD69E7C1C7EE8 + C6E2098781670B1F49F2C3BA1B4863FD4CE587D6BAB4B8948949F2437B85951F + F67EEC37FF965928CCED43ED02D793D6B8123952EE7033E5788D155093243FF4 + BBA28F259B42F9A18023E5370A133DEFCCFEA2AA19B6EC884C64242B32E785F8 + E038B0EFACADF9F7C287AD9917E2C3E6E71A0F1F6C3FE7577E9F76ACC36CE161 + BB14BC400C34C387DD8F850F7E8FFD98083EECEFEAA3F1CDEB4D3956E99DC3AD + 577C7832B0510A1A041B6DA4282A6E80DC74E55466599F8D361BAFE172DAB2D1 + 024A17AF707FDB2181D7269693C6C5326CE56CB0E016082CB0EC662C35A7C645 + A02011649B488EECE2938319DBAA0485ADF4D7325BB6511A0DDE87FDB59A264B + 64927C80AC7F4468B7B63E5BFAB1F32BB5B99D3FBBD89F293E18DE296D94088D + 6CE013C5879D13D9B843FF8366F8A050B06576744F5B036AA2F8E0A585CCBE6A + B186F850C6735559DF197CCC9B371F4B4F390B77F774219B9F8EF67CCE6FD0B5 + 5ABD419A1A8B5E6D46C361BE9E6A382DD327C709E85C0DE5FE4D78E8FEBBB0F4 + C8FDF0C92B2FC7EEBBCDC610D5F06E2A4A85323EFDA9CFE2BF6EFB294E39EA0C + 948722EC18DA80AD7D6BF0C9CF5C89239FB3140343CC0E1D356ABD65FC6FA54C + 1AED1DEDD8F2D813B8E4D56FC2A44DBD3860EE7C6C28F6E0CF3D6BF1A64B3E84 + 97BCEA3C94FA8ADE91DA0B48786558A3E38EE038E232581BC2A73F7A29EEBFE6 + 2B78F5C223B1AD3884EF0FACC7991FBE10EF7EC77B80ED45D42AEEA4DFEE36BD + 8C9B63BA68BB86303378DD0D487B856643371A69479EF2750C75A4D1916AC7EA + 07EFC7F5177D083BEEB81BE74EDB0393DAD328D406917124D23D1625D798AA23 + 7FB554CE979B69AB57219A1413A1C6A61B4F1267C5A778107152ED3B9F9D9CD5 + 63181B18D1FF2C8DB539373653E6E0F7A72EC5F7EEBCF3696BF299E28318E6A6 + AB5C364AF761D7BA1C72435F446D383B233F6CDD47C90FF9A4487E8409119BC9 + 0F1BCC215F18A5A7915FA80EEEF2EBD4616822F2433244F243F2362407566BA3 + 08C8707F09E547D278A9BFD68FC8CA0F7D9F872E8EA30E93F61E4AFACBFEB682 + 8FA4670A1F6CB3F5B9FCBF880FF9EDED2C3E78293AB3315E71C9153488938D28 + B060E0A58EDAC80CCBDEB4E0F5BEF28048EBA00EDA7B84CFB1CF667BB42038C1 + FC976620F9D158473E1B3922E62E95ABD5D4345305DA01B321DED64F26BC97FC + A0F43DE510B280537E0B2D4E0BB030EC555A2C094D65C3269868C30D33BC5A47 + 710150A0B0A50BECE209FFB6EDB0EA6999C1B408C27EDB538C352DFEA3F1C171 + 921FDE58F8D0824A9AD350E3D54C088C850F0919F96AF0B5F1F0619FA5DFED89 + 5F845C2919F65AB418D19ECBB0B2BF03933AA720578B9357467E1EEBB1A689A6 + A454AC19610536EFDB13E57D91DEF67A095332356C7DE2513CF1C83D78C36B5E + 8EF77FE05DA0C26AA8DF09B86CCD679E4CA532F8F6ADDFC727FFF5B338F1E8D3 + 51AFD0FCF614363CB512977FFC329C70EA091828F4C7E487E3E28813494BC135 + A3DDB575D51FFF8C8B5FF13A1CDC3E13B39D605B3DB80D4FB497F1B97FBF19FB + 2F3E10FD459A0A323E7D42E4D9464CA0A8B261BB7FF5E31FE0A697BF092F9BB2 + 17A2AE0E7CA3BA11CBDEF93A7CF4C20F212AD651280DA2E608135315440DECB3 + CC0B3397D374594DC59A0FFA4EE5DB5DDBA32ABEF11F5FC1573FF2311CB1238D + 5326CFC5B45A0F8A8E3095533554D215D488EF74D691C0AC77F4F63E62A9FA30 + 19F226BB7A34AA865EE44851CA689C622DDF88D9AE1E51DB14BFBF239FC194BE + 34D69C78246EDAB2D611CF911C42BB0A1F921FBC07E56652749DD50885C9015B + 911FB61DC2BF3DA024C90FFB5E187491243FACAC51490C5EB6B48622AC9AC90F + 7D2EDCDB38563AE4F2778E937C7AACDFE544E447F8FC507E58392BF961236FD5 + 5F69AD792958C85A1B78D97C7396B08C850FC94BBE2E3FCEFF6DF8088303FE91 + F8B065BD7890E1F86DDDBA35D638D154A7875B7BB21E9014EDA49B5BB3854257 + 39116A7818A117263AD4FD0526754C27099D06E433A2DC0D62A71668E165EF1F + 6EE41A486B1FB52CBA59748635E3B17D6C0BFB2B67EAF07B96A9AB4DE1DF02B6 + FC88E4582C1BAE84A8C8E0580430BCA7C6557DB2A1985A0463A92FC35384AD62 + 6DEFF38FC487B2F88E858F66A4683C7C487D6EB57BCF063EEC1C85D132FA5B7E + 22BBEFB1070E587A1CEE1B9AE9C8C43CE4DD67DA2B05BFABD7529986B6297606 + E77FB1E9A81EFB0EA5DDA9DA6DF2EDD53EAC59F147D47B37E0D28BDF8997BEF4 + 6CD41DD928164A7EC3AFA69C00CB46BEF6DDDDBFBB17EF7AC7C55834FF204C9D + 341343854DD8B06935DE73F18538F3ECE7B98DBF1F9EAC618438D5B229B465DA + F0B3EFFF009F7AC77B71DADE87BA76A6F1C0D6359877FA51F8D4B5D7A352AFA1 + 4C61C576F274571BE937D7E5238FFC1597BCF90DD8FB91CD386BCE3E5839B805 + B7D4B6E2C4379C87379DFB7A2CDA675FAAA51C19AAA1508D9DACDB32391FF5C6 + 122879479AEA6E3C8A79A61A7002EFA90DF8F2151FC1FD377D1D274CDE03FB4C + 9F8D328B0DA77D362A6FDEA39F1249114957AE96F62907389AB5D448DB320DB9 + 9BB2A6BBA8E44D9BE961E2D4F071D267185D576B90435E437594664EC77F1D7F + 287EF3A73F374DBED82A3EF8AF34C2722C964F90D68E36BFB1E487DDB4429C87 + F283970D34194B7EE86A557E24AD2769897940127948921FA1B9DE1E7A348ECA + B3C4DF299B7829F9A1AC2413911FFA5B72F299C80FB6CB46C1A94AC0AEC0073F + 436B86529EFC5FC007C7492962EC783D537CA8A207F1C1D778CF063E7A530B17 + 2EEC712F76CB8EAB680BFA26294743A8ADB1932346A71218CA2322769CC4BEF5 + BBC88A32D1CA3C67D924CD1D7C860AFEF1756964E46866196CB349567B74A253 + 9FA41950FAFF24ED54D85F8141FD1D0B1C3AA168616A3159E74DAB455248BC92 + E3C9913AD4EA84631B2E127B4FDD472759E5FAD0D835F32BB2CF180B1F49F3BC + ABF0A1F6CAF93DC487F280D8046572AE6C051F965CDA1391FA20CD562BF8D0F7 + 2D4E77253E787111774F9B8E3D8F5A8E7B7A27A373EA3C646B154CAA0D363678 + DEABE1E314450D33526CAAE3EF79370499F2209E58713776EBA8E253FF7A3196 + 2D3D0C0566C6AD30BA2E8B7C96262AB7363335B4B5B761E3BA2D78EBDB2E42EF + D60A0EDEF7500CF6AEC5C6A71EC7ABDFF82ABCEA75AFC46081E4BEEA5DB2D351 + C6670DCF38E254762CE12647906EBBE60B38E7D063110D14F0A7F5ABB16D7A0E + 071C7210CA837D5E53C5BC05AC8F57F7CF6F68751CD1286CDC8CF496ED3868B7 + DD30A9ECC6A65AC7F65A197FD9B11DDBBA3AB1E8A8A538F1CCE7E1C4E5A761D6 + DC3D1CDF89D0EFFA96729F6BAFA7FCBDB2D9369F84F33777FD069FF8E0FB30FD + DEBFE115DD7B635AB5866D6D65F4B5BB2654EB9E2CFAECE9C4AC2F3B039FD281 + A6CEC813D294E7A2C38EDF1821455EA3D7204ED231C5664B8335CE8A276475EF + 685EE00BB53CEE3EE3047CED0F778F8B0F096E8B0F39175B99A0E858AE07AD3F + 1B29359EFC107693E48736A39D951FD232AB3E5EABF2431B7A283F9A3DCF9A71 + ACFCD0B8D98D58F283FB8BCDE726E76C1D7E5A951FBC6C445E283F2C791A4B7E + D888EFB10EB7ADE24397A21F95136967F1111EC0850F7EC6E6941A0B1FF6123E + 782939E678F808C74BF99F9AC9DB500BD70A3E68A2E3DF5C4FFAAEFB5C5C72C5 + BDDFADDC4974B4E38D38B00C1D54BE8524F59665DCD6266C4FEFF67B5603A1CE + 2985819D387D57F65F5EAAF323B263557CCDDA67DF13906C9402FBABBC1CECAB + EA0235038DBDAF164BE814D86CA2A421510244ABF1D2D8842A5BDD5776607BDF + A4360A403A35D8B9B0892AF95DF65721B34963A7D7A4BE945D9F0E7E526BF31E + 36DBEBAEC607FB41526BCBA184F8D07CED4A7C58539B928BB2AF5C13C263B3FE + 869ABE5D8D0FBEBFE4F02311ED733C1E1D9A8CB6AE59C8558B985CEBF7C6389A + A6D286388D3C93B98DDCA657EEC38687EFC7FEF3A7E1C6AB2FC37477522BF633 + BF0A7C86EEA89645969A9A74C56B9D32F91C4A03255CFE914FE3673FF93D4E3D + F10C0C6C7B12EB37AEC4F35FF202BCEBBD1760B038E85319906A30FD016BDFE5 + 693A2D0CE263575C81DF7CF787F87F879D086C1DC4B65A118FD397A8DC8FA915 + E61A422343B81360FC3E098BCF1F594397632C7B764F4321EAC74066101DAE2B + F38A79473CDAF050A682FB86FAF0545F1953F69C8325A79D80E79EF3421C79CC + D1E86CEB60A961702476148AF8F77FFF027EF6E14FE1E8523B96CC9EE9FAE84E + 8D2838225670ED7507A9CC54AF59CA36344D2CDC5B4F39C29BADF93180278459 + 3F9E5A85A3CC767E9CCB18760E8788534CBA527142766FF29B5CA9B9B1ADFADC + 4F43A514361F7010BE5CEDC5F6BEDE310F423A013F9BF2C3666FB6277EFDCD43 + 2CE507AF9D911F943FF4DDE11A2251E14F33F911CADB24F9916422B24EBC6C1B + 9F65CBA1D843A5DD5FECC63951F9617D4B75F8912B877C5599A6813E36ADCA0F + FBFCF1E487F021B3924D7E2A7C280A2D8C6EDC597C84FB8B72110A1FEC2F49DB + 44F1A19C77DA8FC7C3871DAF89E043F3CDF950268066F8908543F8F01A2716F9 + ED76175FD09BB283AE5DBBF669661335C0B23D9D04AC0F4ED2C0DBC6CB4B9E0D + 63D56895E848BA47682E92C9884011D96996DCCA66D856DF545B4F64519343C7 + 32DBBFB0BF02A03676EB3898A44E0C3528EC2FFB481BBA423CEDE2B4A9EAAD0D + 5CDA0B9D2A421BB45D04BC7442527F756AD2694F8E6F74E4B776E4A4B62B8BAA + B2C372BE548479A2F8B063D40A3E1865C3EF3EFEF8E37F177CA8740AC7482717 + 09237E57494677061F49577862E5A18598A0D069868F7C5B3B8E3EE39FF0C7A2 + 234C93673B9293415B35F219C1DD928EEBC40141545DAC78CA785F9F2A363C7A + 2F8E593C0D5FBAFA5F512D6E63AB51A9396182B8A0669664A11EB799516AF56A + 0D37DCF465DC78E3B771CA49E760A87713D6AE5B81E5671D874B3EF42114CABD + A81423AFDD69A37F4D3683BE9E7EFCE4BFEFC08D9FBF16D353ED3870F63C64FA + 0B3EFD4135E50E4C194754CB45472C529E3865A9F5A9553D814AF94CDBEEFD4A + 09B972D5F5A4824A3A4EB13089A9042A118A1DEE54EB7E9823697B4F2F9EDCBC + 190353DC4168D9A13874F97371EA4BCE41D1CDEB4D1FBE042B6EF92E4EDF7D31 + F6CD76A15C1840A5ADEE095147AD8EF6C8ADB97ABE4174520D67FABA3771D653 + 75FFE34D7046BB344C98A0E8B95423AA2EF6788A1DC6E39A80309FF74EE2A9B8 + 140EA22A06DC5894F25370F7314BF1C3FBEF1D57A3A19A6ADC549E6DF921D701 + 39D6EA35CA4E694218C13496FCD026A53C78921F9447FC0EE547525B92D69375 + 1D69B6B15B2D0F7F679415FB44076B2541B687B6D0AC65FD81E428AEC352ABFB + 8BCA6E29C1A41246F2E2FE92B457D88DDEF6D726E21C6B7F513B880F9A92948E + C6D605153E6C71DE101FE20013C1079F23A2CA4BFB0BFFB6413AE3E14365CB84 + 0FEDC7ADE2C3A642B0A4AA193EF839E28317F141CD52ABF870576FEAB0C30EEB + 7183DDCD05C11F65AD953F0A176952649898B9F5EA4F2A62D8ACF1029812ADA9 + 909ECD5E6E1741C808F5BB3404CD8025AD04178E4E4E7C86F234A952BDB27673 + A134EBAF558B5AF0D9E72501849F579D32F6512A75E5C4D0FDF5AFFA671DC86D + EE214B3EECA585219F00316585ECF25EECBB0A67B2AF4A5C166A7EA4F1613B39 + 3FC406E78B79A3F47DF91BB48A0F099956F1A18CDE6CE344F061C7A7157C70B1 + 121F6AB7C5872A912B6FC944F0A1FB6B4CC7322FA84E99F290A8A874888FE933 + 67E380335F83DFF7746266F764E478D8E12322470E1DF5A9A51D3E9812C04476 + 41FFBAD7EB34C30D6CC4B6153FC787DFF60A9CFBB27F46717003CAD50ED4DC26 + EED80BB2D180FBA7C367ED4EB9BF736D19DCF1F35FE35DEFF9180E3F7C39DAB2 + 29AC5CF57B9C7CF261B8F2A38E7C45838E6C4DF26D5CFBE45AFCF8C777E047B7 + FD0C1B1F5F87C57B2EC0FC1933511D1844BE4ADFAA98149140454C1CE0CBBC44 + BED830C91F899D77BCA6D6AA56F2D17F1966E3F6BCA9E67D8D6AE9D8872B433F + AC34CBBD64918F72E88952585D1AC2AAC220CAB32623D396C7EC27D6E3B8397B + 38E29545AD5840B72377A9624C2EFCBD884B3A71A7304278EA31014AFB7F3967 + D5C64F438006242AAD8DCDFB9535CC72C475C3F4C78F738EE867D6EB8868BBEB + 4B2E2AA0541FC290E392EB4E3B13D73D78CFB8F8E08FF2A271B3213E88D5507E + 08E7D6AD6067E48736523E47091F95278F58E5DAA7CC6C263F74E8E27794D99C + 8746C90FF9A384DF0FE5473379DB4C7E48BBCE1FB65D99FC253FECE792F69489 + CA0F1DC679697FE1F3784FD5E194F989EF35EBAF48803D70B5223FF879158FD7 + FD4904243F2C01180F1FD635A0193EE4532422AEFD5B3E40C207B9830D5A1A0B + 1FFC97B8E3A1510758B6E5D9C087DC4D427CB01F92B763E123CD0498D438B94E + 764B8B20FB27079E8D503E246B9BE5DFB20D2B219892016A40AC8F8A6C9E36EA + 4D1B11EFC3C1E146C5EFF0354DBE6592A1C35AC844656691CF948D78E2E6AF54 + F39C448573AACDCA59C1DF2D4BB7FDD53DA8F655349DCA1BA8BF52FF256957D8 + 4FDE5B27019DDC2808F54C114F01C39ADC048C701C440C354ED2D4A87C812505 + 8D88007F1FD5D4930DDACE2FDBC1EF68CC74EAD43CF27B7C5F35B19AE18317DF + 5718E744F1A142A6EC8B4ADC24E1234C9110DAC3057C4557D813A4F0A13A7A21 + 3EE46C2E3F38F90C84F850665C0A017E96EFCB417722F8E077F98C247CF0BBFB + 1E7808EAFB9D89278A9D98D2E5C84DB51C9726891C31886862A2C9283DACE1B0 + A28FC3524DE731C991ABDEC7EFC1EC4C0F6EF9C235983289EAEA215453EDC8E4 + DC77334CD498F3F9989C68746DCA62D563EBF1C6B77E08F9DC6CCCDD6D2E56AD + BC17871C3E1FFF76EDE7FC1C3C70FF5FF15FDFFF117E76C71D280F0E61D19CFD + 306BDA0C476E6AA8BB31C97B676B8769E20DF5462998BA4F0CC9DA79D97A5C78 + 38EBEBE8F1144D015FF299CDBD468AEBA15A6B24CA8CE2A494AE4F1D940D14C4 + 4C1F90726DCF757A8A333050605020A64CA3BF8A234A65F7BCB27B0E698CAFCB + 173B827B531A092246722F79E264C72EE2E665D21160843CF9BFA3D8274BDABD + 11F35DE4F54FDE6F2A8AEBD70D651D71A279124CB0E948495F05DB8E391EFFDE + BB099BB66C7E1A3EEC7A4AC287EA2D5AF961B510BA5792FCD01A0C9FA9ECD532 + 1FF3D9726D507158CA9C66F283F79386989897564299BE8969C9176B26B1EB49 + BE25567ED85A646ABB64BF0D6BB7FB0BC7897DE1C6C8F79475DC66FC7E26F283 + 7F2B379CD6B7CA8DA958B7C8157F0F4B52699E7490D61C87F283972C42499189 + EC67337C880C89283D137C48F349D22C8D3C9F95840F728330BDC058F8500256 + 8E93DE4FC207EF4F7CB0AD7C06DBC0D75AC58734A91A27EE2F34214F001FBDA9 + A54B97F6B8C1F52557E4CF2195958A0C86B92234F0646C5477A946191B2F469F + E4042755322F9E6078FA500247018E97B45C04A4DA90C4F6B509CB6150C57D55 + BA8483AEB21FB690AA2654090CB5692AED7BB367717CF843AD9CECA47C8EDD04 + 0530F9DB88E12B1922173055DCECBF882A41A85A7F049EB5B3DA360814323312 + 5CEC2FDFE318B2FD7C36059FC8195FE37B62D56AA33439BCC267A93FAA1CCDF1 + E2E755EC514E9E9C1BEBDC1CE283CFB7248ECFE19C84B8B00EA40238DB2A7CF0 + 3B0A0D153E948C4E7399345EADE28389394532437C4860EA6435163E38C7FC0E + B572C287FCF7F41D2DE6101F1C5B9582A14990C2498452AAF7E9EE330B0F5A8A + 27A71C8E429B5BAB29128DAA7736662ACB1AE22497D0C66EC893CFA44D5F30B4 + A12D5D455B71239EB8F71738FFDC17E0C2B7BF1985C15E6439B78EBCD0113A1B + E57C166CE6276A6FCF60EB8E21BCEF831FC783F7AFC5D2238EC3DA271F46F7B4 + 0ADEF8C657E1B66F7E1FBFBAF36E74B54DC27EFB2DC47487CB7CC1095B9A2B2A + 655FFE252644719A0412263AB47B2D922356696A37A3BAAF53976E14244EF93E + 0DF9EF324ACE1727667DB8C8275142DD75ACAB54C7CC4206031D4E6876A67D89 + 972AC999BBAFCF104EDF226676A2FF91635639A62948C5A42C6AFCE7936DD687 + 0D6EC31A223F76753422141BC4291A9977EBE3948A86D952EC34DE287153373E + 51699FE3A9E6C89213DA65B2B5324AED4E160E46D8326D1E7EB4DF6C3CB8F26F + C344C4BA3FA856974A7DD084C175652B05A816A40E46A1CF8A3503C98CA462D7 + 7C5F049D17B1C7F5CEF7B84E54568ACF967CD3263F96FCE05A601BB9FE293324 + 7F642E1C4F7E50BEB19FDAA479693D85F2C3921BC90FAE43151FA7EC1021A1FC + 50F2E056E487CCF6BC970E55921FFC2EF717C90F255FE673A40C68557EB0CD7C + 06F717DE4B07B166F263A2F8503DC156F141F9CAFEF2FDBE467920EB52D00C1F + 4ABFD2AC8C8A5546482BC7BE527EEA8029CDBF0EF249F8E0FC11ABEC93C88DFC + 612D3EAC064F8105CF101F713A023700DDD2D2281A830F9173997598D325D5B1 + CD022DB6A6466B51C8ECC3C164AD37A9F86412E102E1F7545092F7A100501453 + 52886498D78193C689E6C0A992B12A264BB324351C9F41762C906B32E4B897C4 + 9245226CA8BB806DFBAB53954E062AA2C976F04789CDB4696B72947345A78A70 + BCED0994E3C185C17EA818AD92484AABC67B8BC4AA2E12DBCB710EC3DBEDD80A + A8B2552B379248854C57213EC2F9516D3A6B47E7B88C870F0A21111DE143E489 + AF112B1C47922A9993C382A8161FD69F8EF7E13D395ED212C95419E243425063 + A8F16A860F6D12213EACA017A10EF1C1DFF939B6810B9AFDD281C1E263D6EC39 + 38E8A417E1CFC53D909FBABBDBAB4B8E34951A9B72230941F4F47C43C3A53F28 + A0B3EDC83B46902BF6A2B06915D23D6BF0D51B3F8D850BF64069A0C7FBF45498 + F491F99EBCE2854EF76EEE4A297CEEDA2FE1966FDD81138E7FA113EE6BF0D08A + 5FA3AB338FE9536662EEAC858E3851F0F4A35E2EA1BDEC4E9069CE43C5479379 + FF25473EBC3609F469AA7A024512446D5396C2A91EFFB0272459F96AC113435F + 7B8F893D2B55AF0D4AD1CB3DE34EB89113A845605D7A088F157760A85CC482CE + 29D867B2DBB058E3D27DB683093FEBB1862A45930BB54CF59AC2DC6259D7306D + 02A34D9B2245512A264EC31909A2E6C489D7B036AA3E7253FA355123E81080CE + 6AC63BDF0F640A682BB98340AA138F3CFF14DCFA9BFF193EB84A06487E081F0A + DE49C287757A6D263FB4E62887656EE37AD0C661E587CC3C5C73561B60E54792 + B686F7E71AE21AD3A6AD43AB951FFC5CE8DEA14B32DACA0FF63F94B73A18295D + 8D0EC95ABB5C4F7CBEF617ED35ECB7DD5FC2F10A5FA7BCE577794F998FB82750 + 16A91489E48A6ABC493BAEFB8E273F34EE921F1AEFB1E407F7137E4FD9BD850F + CE9DC827DBCBFB34C387B5DE883C5121D22A3E6C9D38FEB4820F1B0D2D7CF0DE + 7CD644F0212B81F021799B840FDE9FF81091153EE442C3E728537A888F607FE9 + 4DEDB3CF3E3D6E1175AB309E1CBFACB77CC892D57999D614D9143A887B21D208 + EF54F49C54B46C30BFAB8521A2A44DD376B6998D53C4891D1343E7DF0493B424 + 2453DAFC3941FC0C3751BE2F35A66A0BC9F61AF6579328B35098D5DC86B2B3BD + B2D7CA6CA3C5A4D31AFF657FF9396983F49C66444063699DDC55E892F7217B96 + 398DE01318A5ED228B96A949FD55A4459273A72D9048B0ED0C3E7829DA6D2C7C + 489B64F1A142906A9F6AF2C989B0157CA88F6C8BFAC3BF850F7E978B5ECEB6C2 + 07858F36A35D850FF595CF54D65ECE871C6575DA190B1F73E7EF897D4E7939FE + B87D32264D9D85A8E6DA562F7A9316354EDE2F4742309E88D85F4804C0938734 + B234EB541CE1AA0CE1F1077F8FB38E3B18577FEC22D42B83283AD2534DB1CC48 + AE4108CA4867B946DBF0A3DB7F874B3F7235F6DBFF24EF345E1CDC88CE7C16ED + 6EE347C5CD778D492007DD771D79ACE41B24CE7DD79106A612F0C4288A9DAD33 + 2452F5384542A6E1DB946E90273A55A71895C40D826D774429F2F3E9047B3A85 + 52DD09BDA141ACEDEFC15F5141F7C2DDF19C938EC5FA150FA3F8ABFBF0FC798B + 901918F46449CC854EE4A42DDE34978A9DBD957EA06E32828B188D5A115E8B57 + 332556309C00731803F271421071E7FF4DC58EFBE9A27B663BBA8B4E98671C71 + EAA8215FA8A250CEE089E79E80AFAD5A819EC66141070955796F860FAD49ABF1 + 1E4F7E28E123B145FC710D707D098B2A162EDCB33D921FDA385B951FBC07E507 + 9F457918CA0F9B9A642CF9A1B687F283DF932B01DBA7C00EE5B2D2C6CAFEE9A0 + 2F8D869E9F14F965899312206A7FE1DEC5F190D69FBF73BCE4F749F94119CCFD + 456954345E610E215DD6EDC0965E49921FEC9B0EA2161F9239BC0FDB14E243EF + 27E1436D527E2B456FCA12422D98F63215FB953B03E599C5876AD7B5820F7E9F + 24DE5A005AC187C668BCFD45FE653A1C27E183ED65FF427C58AD63808FDED451 + 471DD5E36ED02D07449A916C322C5BDAC2363C0CD5B4BE2BD6F9978D5018AB8A + 167290A4E653B483ECF82AFA27BF1DEB94154EB4D5CEC8A158A55914F1A13C1A + B243F3F3FC57C9AD48AA4255A5266E94EC8C9E9EBD5AEDB08C9D6D52B247DE4F + D5BCC5D639C63257CA814EDA1B5B9430293C34541DB3AFF2ADE1B8A90F1C4795 + 4D51A1628142AADAF1FAABF067F976091F3423D9DC2ABB021F6C2F09AEF0A1F6 + 26E18302500B4F42D13A3C26E1438B91F7E498B11D349B4A38E97591303E4FE3 + A51372ABF8489ABB247CE83423322B0DA8CA1128A0C0E263D1014B903DF82CAC + ADCD46AE6DB2DB840B6E832F3A5250F24170D49CE4EB29CF976293136D55712E + 277F0FF7AAE33BAE8D0E7FB5343A1C891ADCB61EDB57DF8F2F5E7D098E39E240 + F40D6C7713D3E1C84FB65142A4E0FE76EDEB9882BFFC750D5EF786F7A273E6A1 + 98B7CF42A0BC0D15CE4DC56D2CF536F71DD7F7A81FA9B4235BB558D8F0B50CD3 + 643852E523E62810BDC3773526790DDFA5581B55F3E54D3C817254A3BD52F7A9 + 15904DF968C1FEF210D6F66EC153853E74CD9A8A85871E86435E7A0E8E39E138 + 4C7177B8E2827760F07B3FC70BE6EC8DD4D000EAED699452B4D245BE944B5C8A + 25F2F999B2AE6BD97A9C55BD6628D0B006C910A0A861AA5301DF386F53342A01 + A6928E8E8AB8331175710A8222DACA1DE82EE450CE95D13FA5868E21FA804558 + 75C412DC56EEC31A874B0526F019AA23278DAFC587AA29682DD908A3B1E48735 + C5108BC41FE5870803D7829EA303206538DB61AB18D80D2C497EF01EBA3F9FCF + F6522E8F273FEC9AB239776CA90DF5996DA26C57FBF8235F521129F91589208E + 273FAC594C5600C96B2563565916C90F1DF8243F14F8240DCA58F243BF8F253F + 2C9190965AF89043BF488FC633C487F5876D051F1C57EDDB161F72F4B7F8909C + 96B5C7E22389C42BBD8DEE2F058BEA1CEE4A7C10839A0FB9A834C30709147FB7 + F84878766F6AFEFCF93DAEF13E73B81C61AD93720826DB600D8006DE7EC60E9E + 9CB7942D5AA62B5E3C8D0818B295CA094FDA01EB54672F79F94B95CA8E4BE5A6 + 0D98032A7F2A2D00E532923A339C84105462B13A2D24A9766D6E0B39D68BA069 + C21402C94953F42227D186B37292299C9216967C5EF83D152E542233F9D32882 + 90FDE5F315BDC8EFC87FCAFA0484E904AC43AA088F32EBFE3DF0A1F10DF12112 + 6A354E3AFD697369860F3E4BAA76DD4359C679DF247CF0928D3D1462CDF06193 + F64D041F12F8FC9E54E449F838E6B4E761EBF4A3B02D350BF54C9B2FD09B4F0D + 39E2C468BAD857C71327A091C3A9E14C49ED0AEFD5D78B0D0F3F807D971C82F6 + 49D3502DB9EF4735ACFDEBEFB164C124DCF2C5AB50281750AAB0AE5ADE13A77A + CA91B38CEB4BBA0B5FBFE5567CF6EAAF62DFA5E720C5136E699BD71AE5AAEDC8 + 56335ED3948E061C4129FA8CDDF4354AB3B82D9DBE1B1A26FA32D1EC96F64EE2 + B5D8519CC429AAC71174D5BA2758D95CDA67FEEE1FEC7764621D36157AD1317B + 0AE61D7A208E3B6B398E3FE554EC3E771E27C0674FFAC3030FE2E3AF7A1D0EDF + 51C381B90E94A221542765A88241BAE44EBE696A9D628D53AE1E3F83691C384E + E5747AA430AF9FEE110D54438FC315E689E9F0BCD743E2E4B79506511A71228F + EF11F968C79223B86DA54E4C2B645174CC6D6BC710BA1DB1CDF5D4B0E58843F0 + 5FD33BF187BFAE18850F39B14AD3431CF335FAB368D352F49B324E27C90F6945 + 253F781FCA051D0CE4A8AD0831120C1135F9F5C8F137CCAB94B4D1DB04C3921F + 5A7BE3C90F7B1F1B926F2FBB9EE4A7C571D2E6C975C37F253FD8178DA37C4425 + 3FD86F1B6D68E587B4661A2F397B6B03E63D283F381F3A54B3BFF2D149EA53F8 + 1C8D57ABFB0B890BFB237CB01DDAE4B92F70BE48EC8807E1438772E28387B1F0 + F9161FDC67781FE1430444F85074B5C8B1C587940BADE243CEF5161F61F99367 + 8A0F453C86F8E067ACEB90F669A582E045FEC1790C725D8D14F9B51DB2BF87E1 + 9076426DEE90F0B23E39D64CC506CB26C989E546218761397629645F9122D228 + 8557C82E65E6533160A9E8B8296A030DC16B27588CDE16A9D57DC5E6B59985EA + 3B990C6547971AD1AA2E390E3C2D0820BC2FEF2515B07CAC42A19274A9AD6A97 + 08122F025880D5C66E17A465F422423A3DD9E45FCD227CEC1886D165BB121F9C + 430A2CF96529919DECFE36BB6ED28924C48734758AAA508E2691268D57880F7B + 421E0B1F32758C850FE281824F5133161F5CE0D436587C48FDCDEFBFE6CA2FE1 + F6DFAF46AD733AEA7987B154DAFB0EB545EE1E8EB494520CE2A8A3A33EE8751F + 83E9C9188A184557C1F4CA660C3CF25B44EBFE8CD28C7DD1B5F45F50C8B89363 + 791BBA7B5762E38A5FE3928BDE8973CE391B3BCA7DC857263B724336E136ECF6 + 3A7E79D73D78FD059763AFC5A762B7797B6368A0CF3FD3ADCED8FFA85AF10EE0 + 299FCF282648F461A206898925BD2689C488E3E0C842BA5A8F0B0F23D62E651C + C3C8A623FF6F6FCF766CEBDB8E554527B4277560DFC5FBE1C4D34EC629CB9F8B + 057BEEE9C6CA093E6A8A8AEEDE5577E0EBA8E07FBEFB5D7CE3CD17E2EC597BC2 + 9DA951A66F543CF3C680D6F8CDF87DA51AD175FE93369500ACE629F26D1D4594 + EAF633C48DC9E324AD95B0472C91FCD3113E8AF345D57DC2D1BA379BD6861C39 + 769BC73DC71C866FFEEEB7C3A1DE14E2D2924BE3CA4D59262F692C65CA950FCD + 44E487D271487EF09E941FF6F063EB484A8B1CCA0F5ED64C22F991547BCCCAA4 + B1E487D64512A9B1F24379F942F9C13E91002861A882677428937CB22952C61A + 2FC90FE51A126190FCB0057F5BDD5FD40791544B00C3FE4A7E2855840893F2CC + 9170133B3AE0EAB029F9AB648EE3E1C3BA9D288A50F8508A22E1C0E2C3FAE00A + 173B830F3B86BB121F725AD7F873FE487A2D3E34AEF6FE09F8E84DEDB5D75E9E + 3869C06C88B8DD7C933407D2DCF0C672140B1BCE8153766EE510D27755DD5989 + C2C4E4156EAE246F49406A36E17AB6D8A6549352F98521971200213BB69A18B5 + 99C0E425A75F6B4B95D64CD1689A6045B77192544452A1A17C86A2596447D789 + 2804423370DBFC1C029E351BD9D7ECC9C30A2FDB7E699A94988C8BC49A9A744F + 9B5432C4873EDB2A3EA47AE658587C509B260743A986E56B257C8878FEA3F0A1 + B994136DABF890199A8B95DF535EAD247CC82FEDF997DE8CBBEE7D04A9498E38 + E53A4937BCA9ABADE60E0B7027261ABC52518338A55170C4A99C7102DEFD9D5A + FF674CED7D0CD77DE222DCF0F51FE08B3F5B8923CE7A05EA857E4CAE6CC5F6D5 + F76146BE8C5BBFFE054C6ACFBAF962D45B1B2675A5B17ECB3ABCF9C2F762E553 + 291C7ECC8B3140F34314A715889356D6BC46298E9A8BC941D687FCD7BCD9CD6B + 93BCB92E2649F45FE2F7B27ECEDC69AFE24EEE699609D9824D9B377ACDCFA283 + 16E3F0334EC2F1A79E8CC58E38E53269EF6B3D50A97AD39B27272CAD926D437F + AD1F5FFCF895F8D35537E125FB1E8452A5DF53987CADEEC7815182A3FC919EA6 + 2DF26170F17C1AC233F2996838A1A85E1F4D9CF84BA561AE4B8D68AAEA23944D + 1AA951579CF50075377F5526303DEB34BCFFB7BF1EAE55A9E82D55665768BEC5 + A3FC34959E6367E487B069FDF3AC56C89AF6A5D94A8A5CB29F551A1469B9F54C + 6DE26152DAD0F787F791594C8122CDE487722671CD696CE4341FCA0F4519CBEF + D6FA6DB52A3FACAF994CA836FF92951F220E963CD9809C24F921A7F0507EE8B2 + F8605F14B8A4E8E3670B1F49FB8B9D73AB6008F111EE2F3B838FD077499A4C05 + 428D850F59D434DE72F417DE437C882C36C1C768E2C42F2ADAE26F7FFBDB287B + A91E283516DF2321E0C3A5FE0B27438C53AC4F39723858AAA9245BAD1CC595BB + 42E44D0333DE44EBB293689362D95C0E3A05F0737BBA132C1718D5DBFABE2E31 + 67B55F8B93EA3B9A52AC53B28D2CB4D9D795CF82E4511118CAAFA14522339DCD + 459594ECCC5E16C89640D93ED8A28D9AC3C58B17FB70559DBE42CD8AB45FAA69 + 6417B0426FD98755AB560D3BF35B01A0C5A313CA78F8D06959CEA8FC1E4F7024 + 53D21EEA24A948B530E54352BA8A89E04327A6247CB8F5E109AFF51548C28784 + 1EC79563475576123E8401E143251294C7652C7C3CE7821BF0B7C7D739E2E44E + 9C69B73699181271E24892178AB1883E3C5EEB93F2255468CACA9776E0A97B7F + 8ED7BCE0387CF0A2B763CDBA0D78F3BB2EC543DB5238F8C4B3D15F2CA13EB419 + 4F3DF86BBCFBBCB370FEEBCEC3E0802371B96EF497FAF1D14F5F8D5B7E78278E + 3FFD95E81DC8F94CDE69EFC704AF418A4D6FB1D9CD67FDF6C429F2A6BE347D9B + EA551F0198AE573C896A73EC24ED3E542917B1D5E162E3968D28BAF7E72DD81D + A72F3F0DA79EF65CEC73E0BEC8E647D6FFCA958F61B3931B872F5BE6FAD430A9 + B33C4B9445FFD053B8E8F56F42E6977FC2F2057B63B03CE0894A7B258A353B99 + 20A755407A9812C1FA25F97B1BCCC4F999A2510945879DEEE3D5E89DE09F9E39 + 7CF473D278BAD6DCAF1F6A01DC38E58E598AB73FF8E7617C582C587C1077D2D2 + EF0AF9A1BFC7931FFC9DF28399966D167FC9115B6F4C85646512D1FD162C58E0 + FF66B508C90FDDDBCA0F2584A5BC550047D827F597CF963B02C78D9F95FCD21E + 26F9A1E2B67F0FF9C16BE1C2855E1670BEAC164FF7D241947D947CA3BCA40C1C + 4B7E485BAE5C6F4A986BF121AB87C587E4FBB3898F279E7862140E9BE183EDB5 + B5F4783FCA5B7E9ED5222C3E6415D1E15F918BE3E14339ACB47FCB6F94FB8B7C + C3A4859446AA057C8C264ECA3DC10ECA866EBF68A31DB4B84938A8EE12F1B097 + D47976C294E154277C451ED86758C2A3DFC753A52669026C6482ADB1A3CFCB3E + 2D8F7E4B10742F45444823C601A61053E87A523B2400145E6E0BDCCA662C95B2 + 6D6B331B78B3056C35407AB6B5F95A67432D04121FCE5508580B6EFEAE8CAEB6 + 2AB7F0C1BF95CB4AE31BE243A55976353EF49DBF173EA4EAB71AA4101F32C3B2 + 3D9C579E9443FF8689E28338D358AAAD079F7FBD2319DB90EBEC462D72F72049 + E1FD1891467F24341CC21B69226906EA4C57B063F5FDC86F7B0CDFFECA3598BF + FB1C442C94FBE05FF1AA37BE0FE5BD8EC31E4B4FC3C0F6A750DEF020A6EF7800 + DFFAE29598B9C7816E23A8E2B61FFC14EFBBEC2A2C396E39D293E7A150A1B6B2 + E0352CACF346131C7F52B5B850AE2F8CEBDA952BC7E6AD5ABD887CAA8A7CC609 + 59F79D4A61103DDBB660F3F64D28568630D71DD44E39ED649CF8DC13B1FFFEFB + 3A013789EEE831F1713F5BB66EC38D37DE849B6FBE196F3EFF6DB8F8A277A3AF + 5845A5169BCE3A73793CF2E803B8F85F5E8DA38B392C6AEF426F750099B4DB4C + 4B71EA836A261A2ECA2B53DC88A6080D339CD9181A09301B6F0FA72E185D6605 + 71AA0720D650A50C71D277EB866C45C9C429C620D78FBBDDE28578DFC635A3F0 + C1B5630BDCCA2749E6E067437EE83026939C951FCC79664DDB5A43567EF0520E + 3E5B70553EABFC97F7B0F24397C8820E16D4C22A8A2DEC5792FC50749BE418E5 + B45C1AACA97157CA0FC9BD24F9A13C76F2B91A4B7E50CEB11F13911F944F4AB6 + B9ABF1A1B6B68A0F5EDC5FE4FFB433F820DEF95A880FDD4BF8D01CF31E8A1A6F + 051F3CE0CAA5827F736E6C61E016F1319A38E961625B728C636778C909973F72 + 605462C1B0348B3A6155950A2DE4E6CB7B49B52A7262999DD5A2846ABFF12E3B + 490AE3D589C356751610C43AA59952B8B8B2E77213A32F96EA9EA9C86D7822D0 + B3AD7D56595295044EA7C8A448147B526C6521DB7BC81F4C272CF903E9B36A8F + B201F3925A553E37CA81A164A8D6793E091FCA27427CF03539F10B1FF2A150C8 + EE44F041B2A2F4FD49F8B063B4B3F8B0E325A7C0101F3612462A79E56C220644 + 96880FE5FEE07B3243EF2C3E429F3EAF1D7DC3B5E8E9A31A7992270EE974C66F + D271345BEC33548F1881D6EE75209D8E82E407D661D35F7F8B77BCF24538FFB5 + AFC48EC122BA4862DC737FF293FFC1F997DE80C9879F893DDCC9B8D0B3165BEE + FB29CE3D6E7F5CF6B18FE1DE0757E0D56F7E1FA6CE5D82DDF6390C3B86DC269B + A516A8EC6BADD134E76BCAB957982BC9358A0170B1168AE645D7B8B676379EB5 + 02766CD9802D9BD6B8B5D4E784EB1C9C70E27370CA734FC001071E88EE2993BC + BEA69FDA6CF76F879B839EDE1EFCE2473FC1673EF549AC5BBF119FBEEAD378DD + 79AFC640B18632371EFA77B9CF76E6813B7EF8435C7BFE8578E18C3DD1E5DAD3 + 9B2979CDD1D4421C1157C9D41BB5E80CE9110E2345CD8D6890E4A3349239DC1B + D4467D6774CA81C86BE1E294042993D66074945D264AAE7E1063C29DA4E7CCC4 + 45833B12F141AC29C962525E3B6B0A99A8FC907C50DA0EC902DD4BEF5B5F3E6B + AA6A263F14B8D24C7EC8844462A4E020F9FDF19ED24EF02015967652FBA54D91 + 594659B8B9A1EAF0617D5592E4C744AF24F92147716DB2E11CF2928643399BD8 + 271DC6493854C394F760FBAD79C8CA387B6FDE4FD9D19F6D7C48433E117C28DD + 057F570E2E25536E051FFC57645BFB8BFCBC146CA69AA449F8B099C4850FEE2F + 22B3CDF0115A71822B760E775FEAB683A42F2AA24AE482971265F26F7AEEDB93 + 012F1BBE27F59D3624CB3CE57466BDE76D756FBD9E0482100CA1EF950649F5D5 + 38B0340F2A93A9FDBE05BA4C549C104E3627494925F93986E273127532B00ED4 + 76C2ECBDAD3D5C765431687DDFAA3A9BA98DC580F57BB808941F4826328675DA + 34F33A1585C92A29B41406AF280DF5970BD93A4C4F141F6C833D19B4820F3B37 + 3A7124E143279AF1F0615322D8852E277E9904D8577B2A4CC2072F855787F8E0 + F7D85FE59F9296AC157C687EB41E9AE163B737DC80A1A25BECDC282A75633A8A + 37EC6C9D4EE4740AEF76BC2285EEFA0E14FFF63BEC9EDE81FFF8F2F5E868EB44 + DF5011ED19375F2CEC9BEDC097BEFC2D5CF2992FE3E8179F8B7A4717FA9F5889 + F68D0FE3FD975E88AF7FEF07B8FB812771D8735E889E813A6A5986D5971D494A + F9083E3A82A7BC6F93DB10BCE3B3233E5537AE792760AB43E8D9BECDAD194796 + 067A3077B79938FED82371EA29C7E3B0C30E761BE3646F311B2AD3F45F452D93 + 42575B1E85A1026EBFE367F8CF9FFC087FBCE76ED4DD58DE78C38D587EF2C918 + 749FADF8683CAF3F7278766DA816F0856BAEC71D575E8D7F5A70806B5B113BDA + DCBBB5083386224FF02A99AA0C68C3044AAEE2B1064AA55C46A710D0E77D8462 + E81C6E32B27BC76F8CF838296B3BCCE69489C6214E6E3086BADA7169BA320A1F + 9299213E7869530EE547920645781A4B7E50F6294A8AB24E9FB7D15E567EF035 + C9439B4E43EB816B4A2776B5D1AE2FDE5726356DB64A6AC87E713DD9CCE6BCC2 + 9430CDF697507E4806DB1C49CD22D8EC3DC6921F4ADBC01F6A5914156CE7B699 + FC50FA15D56493FCE021544EDF49F2C3DEEFD9C6873D442A7F949CE2E9EEA1E7 + 34C307EF239398F0A1F9E5A52CF7ADE243FB8BC58722E6268A0F5E766C8589D0 + CAD6644F1E89AAB38DB70E6C6C384FCF72B6E3C4CBA64AE2A4D04B45C269C2AC + 4DD202296963B2511BB6AE4E9227BDEE2122A012280284D46BDA10756F32520B + 060B144D325F23A0553B4FB67225CEE273F4B72DFE68A3D6C6EAAF2E0B68B5BB + 590E165D7C5D29F069460D4B3208D05ABC72B4B642CEE62D91BA95F34AD2ABAC + EBCA67243BB9359F5A7CE877B177397387F8E0FB3A6D3C537C286581B46B619A + 88101F1C239522D0C9C3D6A35342CD9DC107FBA97FD926094FF9B2D91C209AE3 + 678A8FA9AFBDD1EFD83E3752BD91A3C97F3D16E86DF582232369F46467219D71 + A7E11D8FA0F6D0CFF089F7BC16679E7926FA7AB723937702ACE27373635A671B + FA0676E053577E0A5FFBE9DD38F0256F457D2042E5C13FE1E195BF47E78239D8 + FFA8E56E8C66A05875A7DFDC0052597712AE4E76C4CD09B2A8E023EB728E98E4 + D334DD151C59DA8E2DEB1F47AAEF29CC9C3D13471E71284E3CF6281C75F432CC + 9E31D573894A996550EADEC93B9D4923CF9362BD8A5FFEF2D7F8F6ADDF415B87 + 23780E435BFBB6E08ACB2EC3D2C30EC716FADAA5B2C8A41A59BE538CCA7518DD + BE151F7AFB0528FFF28F78DE1E8B3038D487EDACDCE4EEBDFB00CB9E9451C8D4 + 7C0EABE1F227F5D119C2E33235C6913B0A6BD125689C4699ED46344E49CEE15E + A0472ABB32720D1327FEB879EE6FCBE1B27C6BF890D63A497E246D8C2A19C28D + 478576253FE41BA4D407BCA85108E587BDB7363C1E3E941051F9D7B46EEC9AD7 + 5AB789257985F2837FF390C575C6752B5F477BE84DF2EDDC19F961D779525416 + C784EDA0DC97AC91558263A583305F9789CC9AC5D4477BB0D73EAAFE2ABFA0E6 + 85FDE5D85B821346358ED55FABE56AB6BF34C3872C2D36AD80C58752A7C8BA30 + 1E3ED866EE9BDC0F14C8437C0807764EC7C287E4ACF617F935717F1171B787DE + 9DC587E51F63ED2F20715AB870618FEB70B7352B6883E117D550323B0D808AE2 + 718039D1B6D8A33A6E9DC6C61204B6F136FAC186AB2625A11291607B0838015A + 9595D57979C6CBACA267897858073F5E4AA4265394D2E9ABF2B4B2C28A35EB5E + E1C9A2597F05609D325456C0AA1593725F28611D1718099DB42FAAF127A2C0FB + 719E94195B0B48F93E2C619153A5FA2B476D316F39768AE15B7C28445E6635E1 + 836DE1B3890B39E1ED2A7C246965C6C3878211345E5ACC52B5735C280464EB9E + 083E64CA563E26AE136AF076353E74AFF6575FEF084ACA1327EF2F53AD1BE294 + F2D9B799A868303BC5910C27B87A1E47DF9F7F82572D3F02975E7AB1FF8EF75B + 8B72C8665268633995541D9B76F4E2C20F5C893B9F2863D9A92F4561F3363CBE + FA0F98BFCFEE98D4451F404792725350CB3999C0248E25879B54DEDDC3FD5D19 + C060CF53D8B6E949F46D5D8FDD664EC511472CC10B4E5E86238F3CD2CDFF34AF + 79192C55BD4F167F6782800C33987BD294C15F563C842F7EE18B6EDCFAF0A2B3 + 5F84BF3CF0201E79F4217CE4639761FFC5FB3BD21447C378E35C9482FE630DBD + 87573C808BCE7B3D0E1E4AE3908EE96E0E1D796B8BF3334DA7C6A95E4135556B + 68E7E4AC5D1F65664B45C6197C38958031D5C5B16FA31DCC4725CA0C9CC3F57D + 61328A9322841A27440D8FB47AFC6F9FBBF9659D23B8DFD5F243D157AAFD26B3 + B03633F92572BDCA37C8CA0F95AFD2BA93B3AD0E0936FF0DEF2B92A2200F9BE7 + 4C98D6FEA20D56E5A894CF8EFB0CD793D5A2D844BACF96FCB0D1E04AEF229781 + 507EB0FD1C2FC90FB940E85066C9997C99B4C7DAF1E1DAA4FCD05EF54CE58752 + FE28145F7D68860FB92024E1431ABC89E043077AEBEF642D0513C58732DD2B92 + 50F8D0A17757E34357A28FD382050B7A5C4387354ED6CF4321A11C248586AAF3 + AA55C389961946AA5179D45B1B6DB3868BE5C9C42487336EBABA5F086C4DB454 + CB542B5B5BAAC24C653EB4E6221BF560431C45BC780F45C6F13E8A5450157231 + 60090D99ECC2016EE5C4C831551D2A9B9B28C9FECC67CC9F3FDF3F8F27200247 + EA6DB683ED53FE1F2D6CEBE764B52D120C3A35B15FAA7527F2C33E2A82C3AA53 + ED7C28AC539A2AFB19DE9FAFABBC09DBA1D07F91F29DC187481B17CD58F8501D + 27F68BF8505679E18363A504972A25200D9B757CB4F82026489CE4DBC5F6688C + 445425F0E55FB7B3F8906F8BC28CF99C8ED75DEFFD8A3A69AEA479AB5A897304 + 212E2FEB8E1DFEDF7CDD118DA89168706807D6DE733B4E5F320B577DE4036E4C + F67044A7171D997EAF2729663B91E99881C7563F81B79EFF7E6CC8CFC6A413CE + 4667B11FD9811EE4AB65772F3716F54E54338E04B54F4657B41ED52DABF1D4BA + 8D28EDD8881993D238F4E07DB1FCF41370CC714761CEF419BE4DA55A84529973 + 1D9F84ABDEA4451CB8B1735D58FBC45A7CED1BB7E0EE7BFF84D34F5F8ED3DCCF + B59FBF0EDBB76CC6F5D75C8539EE90B275B012D342F6D33874732CF3D91A7EFC + BDEFE1CAF32FC4F3171F86E97587834AC9471632871409497BA5EA136B7A6A12 + 71338A0B0943B999382FF5117D94CD0A3EA2958A8953E8F714660E1F494710C5 + 046FB8161EBF556B946E69E0DAFF34FC56A2D8197DC0DDF0D2CEF1354E3AD884 + F8D03A4F325DF33B8C68A33CA366943895795DB51195DC51D5EEADC6C8264794 + BF9FF2E469E353592DD53893ECB4260F6BF292C68AEDA72C945CE76794D243C4 + 492480CF9A88FCE0DFAAD8A0A013DE5BFEAA63C90F1E92F979990C392E567E28 + 4048C5E99BC95B6B06D24155F540791FF64B073769B4A5E5D919F9A167A9861C + DB291FAC6699BCF91D4698B30F8A7A173E389FBC0731A67A6E36DF51880F45BE + 091F929DDA5F546CD8E2C3A6CFB1F850ED38F10F7D46291BC6C287CDA5B72BF1 + 01EBE3A4D38AD8B03646692AE4FC2A9F263E908B4DFE21FCFB80030EF09B3A3F + 17DA669B355CEC52391954788F6ADA66E53478B19D24126C9BC8020582D495F2 + 6DD204F0F7B56BD73E4D75297BBC2257C454A53256F4A04D36A64DFBA0830EF2 + 61B5FC5C180A39161150B654914C4E98A202AC4F91BDD84786B6F273D29C581F + 2465FCD5B379CF356BD68CBA97C0A905A882CAFCAE0498042041A9E469229921 + 3EE41C49A0A98A79337CB0BDFBEFBFBF57AFCAB17E22F8E07CF0332263BC4FD2 + E9C9E2831B8532E7AA1DCDF0C1760B1F365789C5878208F8B71C509BE183E342 + 7CAC5EBD7A181FA183E758F850AE16A576E0BC4F7BE38DA8503865DD46CF3C49 + C614143B25671ABF571B26A8143AB2405BB5078FDD7307E67744B8E623EFC761 + 871F8AA1C11ED4D26E7D65DC89D07D6F6A2EC22F7EF253BCE943D761D649AF47 + D724272C490ADB1DA16E73B2A0BC0D554792B66D780C3BB66EC6EEDD53B164D1 + 5E58FEDCE371F271CB3067D6749FCE72B0EEC87BC58D6185B95CD23E53375B59 + AB93306531399FC2E6EDBDB8F5D66FE18E5FFC0F0E3CF020BCE10DAFF7E3FCEE + 77BF1B7BEF391FD77CF6538832EEB03254F6F99BC28BF7CBD114E008E2B59FBF + 06DFF9CC8DF87F871C8B6CDF1052AC97976EF87470036156F20671F29A2592A7 + 28F647525D3FEFAF654C79223269A35192A96E54C9158D7DA4568D44EFF9D747 + A53D88937D5A139FC7433D265CE4587DB9342ECF8FF8388D870FF9D129BAD9FA + 7986173FB7D75E7BF935406CF23ECAA1C31F9B4097173FC3F560CDCB561E2B42 + 89EB4B7540951F49BFAB124433F9218DB9EABB29CF9D2D37238D0F9FCDFD856D + 921BC244E40735DF6C8BD285507ED85C8549F283E325A5804C699A0399FAADFC + A0BCB5AE0C36058E3676699054B85CA905445AE534CEFBB3BF4C0B2493D644E5 + 874DACDC0A3EB8BFA8261D2FED49EA9F08135F6B860F6B62143E14E9A8F914C1 + 9649D246EB494B67F1C1D7A4894BC287523770BC38077F077CF4A60E3DF45047 + D87ABA2D591043E60220D393A7BCF2FFA898AC3620E5B8119B16D34E8A60081D + C0F41A0799DFE3607013B60565935822DF5BB468D130C815222B26AF02AD8ACA + 52124ADE5F9A27F96F89C5CAF427B03197844E53FAE1F7A44191F6C1AAA74747 + CA24DB55ED58736214C166854C48C4F8B9430E39C42F00FE4E6122A739FE489D + 2D02C8BEB20F8A4E93364DA7248E197376C93CCA3631FF86FAA1E814B6459A3B + 9105691DD97F8B0F8256DAAB101FFC5D8E903B830FF95E091F32FF8D858F7DF7 + DD7738925021B2F6E423CD11DB227CF075A5A650DA093D4735081561C2F1D23D + 437CE8B42462AF53D544F0A1A846E163E61BAF776D1B448AA6CE7466389750BC + 6137124DD287289DE35FFEFD4CDD6124E336ED7A191B1FFD0BA66FBC0F1F7EFF + 0578D1D9676188DA3F3A9B671CA9C9E6F19FDFFD0E3EF299AF63AF635E8F5A3E + 87A27B4EEF503F7A363E0AF43C8A19B9ED58B2D72C9C74CA0B71D249A761CF39 + 333DC728D4E9B35446D53DABC6122B2937A65566C167ABC840DC9A6C77BFBBB9 + FFE1EDBFC0376FFB3EBA3A27E1B5E7BD02CB962DC36F7EF33B5C71D9A58E849D + 8A2B2EBF0445F795C1211276A3650AAE1C73A6F56FC387DEFD5EACBFFB019CB4 + E701881C214BFB42C691D7C8314379DE672DAF3231828FF683279C95466A80A8 + 513F2F3DCA0C178938A1417A52B1764AE6BB9038F9398C825C4F364966BC8247 + 699CE2CFC519C5BDA9CEFD0C4C6EC36551A1257C282AC9E263BC7C774B962C19 + DEFCE5DED04C7E70DD721D4BD3206DAB88842ACD8BD8534E30BF93702EF9C1B5 + 277969D3B858570B4587517E28F2CCA68151BD37F9C9D8942BADC80F5EB22470 + CDAB8877E82C1CCA0F1EF49430527EB4921FB640BCC64BAF2BE24C499EA585E7 + 3C29CF127F283FA41DE23D94D95B1175D2685B1FC956E5079F25B92B3FB2F1F2 + 55717F512D3FE1430594AD0FE858F8D05C73DC98BA429A49FEAB83BC2D1ECDCF + 597C68AE2D3E44A2882FEDC7161FB200091FD6443A117CB01F9C53A678507FC7 + 244E2CF2AB9383550DF266D62B9D0B8C0DE6E0DA0D57270D8597DA86DA6CAA0A + 5D977F0C9FA9828862A7628B041D9F1316EED3BD794F6A1474EAA73A951799A9 + 7C5038F9366A8ADFE1A66BEDB3B2CBCB115EB665694EF87CB24F4515A848B165 + D7362BAC6CC9D272296C52219C6CBB1619DB213F2AA9B7938A30F2BBFC3C9FAF + CF1384728E977321BFAFB4FD52354A956953DC5BC73B1BA9A6F9943335BFABA4 + 9F72FCB4F890FA54F890C94B859A2550395ED6672C09C849F8507832C78B58E4 + DFCA1AAE829D61E160DD93ED113E1481A128208B0F090069C5947745E3D22A3E + 746A611F3956161FD6C1DE9A2B26820FEFA8FACA2BD1D3C72CDB2468D978F7AD + C7463AE64FCAD78BFEFB8574172901728ECC7464AA68CBE4D0577634C091A3D4 + 9A7BB1E1CF77E16DE7FD132EBEE0B540D1ADE572015BCB6DB8F88A6BF187955B + 71E0112761D39AD5D8F1D41AE4AA83587AE8BE38F1C46538FEA84330DF8D4FCA + 11A342C98D4914633D954DC56570693E74D340129669D4CC6B6FCFFA3C53BFFD + E37DB8F9E6AFA16FB08897FDCBCB71F209C7B9CFA5F1DF3FFC116EB8F65ABCF1 + F5AF753FE7A1C7DDD76BAC1212F4D98D82F75DB36A15DEFE9A376256298503A7 + CC4666A0E0DB12A562D2C4BA774C0ECA7A79D438A5FDEF159F3833ED354FF5D8 + 6426D39C35CF8D32C391648D44D53D2D5D41DC38482B958E46DF431A27188D93 + 88534AA6BA5A1DC539337071FF68ADB9A2AF2C3E7482570A0B9B334D3E2DA1FC + E0BD1431CC35C34330FFE57AD061479A0E7E5E59ECB5016B4DC90C23F9A12493 + 3279F33DED0FBC372FB65B0114EA0B2FD528B3EB41D178F67E32878F253F941A + 41F25FCFE5EFDC5B64F29196877FCB493EBC248BB8F16B3F527162C9DB507E28 + E1AD34EFD69F483E46DA3F642150892DCA0FB916A8E8B73D40877399840F7E56 + E92092F0C1F6AA1243880FA58C51A00BFB497CB03F213E447489093E8318508E + BED0CF4DFD153E44A04842F937EF2DCB84ADCB28F2277C88D0F3FBFC3CBFCF4B + F7936BCD78F8E0984BFEF3927286E3A54381B45863E103720E67915FF965A8D1 + 52F7F192DD9003AE1C4C4A3CC506D9E491D6294B9B9A9C67E5A028E24190B3D3 + 2A9B21E7657E4EAC2FE914A5CD85F7E204F3B30289A2FC3880FC3E8125E76EA9 + 21F95DE5051183953A5061A08A4E23A0D85FDEC3464C3553C7DA362A0A8BFD55 + 656DDE478BC3665EE558AA3867122B663B38A1EC03CDA6122EECAFEE23FF0209 + 22AA5A55F74A3E54360499FD553B144A2C9F2BFEAD0287CA23D30A3E544B4B26 + 57BE36163EF47DA9B139A77CBE16ADF0A1D23B161FCA83D20C1FEC3BF14161A6 + 3C27E3E143445B7E06161F2275C287B44AD25ED93A73ADE0837FAB30359FAB53 + 71880F9D20679C7B059EDAEA4EFCED53508E523ECA8C26BB2C354DA822EB8813 + 455629DBEDCB9994D63F8AF5F7FE0A7B1FB01FA62F5A8ACDA5361F89166D5F8F + B5BFFC4FBCEC98B9F8C4C7DE85CEE97BE0BE3F3D8A7FBEE06AD416EC8FC263F7 + A1B2F661BCE31DAFC7DB5EFD32CCDE7D5E43C03A613358F7E907682E64ADBC88 + E6BE147D0E2AC864339EF0D4189194A79930C25F1E7E145F7084E9B127D6E0EC + 17BD18CF3DFD34E4F26D28BB3EFEE0B66FE13BDFBE15575C7E29CE3C7D397A4B + 116AD59AD73425F9F9491344B633A92D8DDBFFFBC7F8E05BDF8D330E390AB3A2 + 1CEA83EE741E55BC8F137DC1F2244EB56AC3D72836DDD16CC76CE6CA109E8D46 + DEF7EBA36E4BA4E8C1759F8E4045806D741EE2E634DA2B9FA691D72D7192A9CE + E68AF21BA4C354A55246E680C578FFA62746E183F89473AC4EC5FC09F3D22918 + C3CA1E7BC9DF851BBCE4072F69859474559B39BFCFF52597029BA74817D7B734 + 22723950342EEFC9F5ABC011C90FEBE4CD67CB5F4A073AAD7F7E4FEB2DCC1964 + 5D0FF47DE553E2F7458E3826A1FCD078F1DEB69C548833B6996316CA0F4509CB + 77889FE17DB9BF716C95D1DACA0F997C94FAC5CA0F993595DB886DB7EE24ADC8 + 0F7E9F325ACA07F5D9122F458937C3077126F70FE2837D911648F8E0BDA571E7 + 457CE87D119EF1F0A18338E75BFD55C0591875CCB9B4F8D0FC8AE0700EB9E7DB + EA16E3E143EB897F2B425EF25616AAF1F0E189D3DCB9737BDC407573D3B0A194 + 1A4C6DDA1A14A92E091A82CB1611D4A6664F27BC081C2D3C769C832D01A04EDB + CF8BA085253F7489687071D0CE2AC73D110F452E285240BF2B64513E32FCBE36 + 462D0AF55B8057AD1AE5DC90EAD54E948DD010C0A535E1B3A44214B356C45FBC + 19D5863FA7F793EA269128705C940242D10F324DCA0E2E3088B070EE74DA081D + E3658A932645A0D6C2E698121734E9510BD50A3EA491E2F3B4902D3E745AB551 + 758AE0133E543E80DF557D216BB3163E38C67A3F147CAA7F47C1A77C5E121C32 + 2987BE22D2142985C158F850308188B4C8D744F141E1A22004399887F8E0C5FE + EC7BFEE7B0E291C7909DE204302814728E3039211E551A49304BA838325375C4 + A9CDBD567BFC1EE4D63D885993BBF0B0EBFAFC635F80EA64878F4177322B0F60 + EBDD3FC0B299557CE2AA8FE3A127B7E05597DE88BD4F3E0BD9E2160CAD5B856C + EF061CB8DB749C74E2F138E1B863B1F7C2858EF4B8FB9769AA71EB89F3E78813 + 5FA3E6A45E897CD45F67670AEB376DC6CD377F057FF8D3FD38FEA45370E65967 + A1CBB5A352A1BA278D9B6FB80EF7DEF56B7CEE339FC2E1871D8A6D439511F3D5 + 18573CB6299F8DFCC69BBE84AF7FEA063CEF8863D13E5862A350F7592EDD86C3 + CDAD16D7C8F38EE2CCA4DEF077A2F9D29BE6EAB1A378AA5E1AF5E4903C455143 + E30424E77A1AD628599FA630D753BD9168D36430AF35C29DCBF1C633ED94E3F1 + CEBFDC3B0A1F14E0F23355B466337C083F6181695EDCFCF91E71ADEA10F24595 + 4F235F5378BC088B7530169EAD9FA6D6900EB8921FFCBE52B870230EF71785E6 + 4B7EE8DE2A11225242192699612B21D8307145F0C9C4AD03C858F243DA615B12 + C6CA0FD537A3A649F9DE947748695F78710C7470D4C19FAFA9B2824C8F3A54AA + DF921F928FDA5F647E6D557E081FECA735D70A03DA5365DA953B4B123ED80612 + 267ED65A2DE48325770F3E5BF810E1920937091FDACB79C9974BF8E0F3F8EC67 + 1B1F7264B7F89042C496FB113EECA13DD1397C9F7DF6E9711B4B373715A9D4C4 + 54D93115C993BA5444488C5A9A2A09B57063E467690BB79999459A42E66BA3F6 + B8D9F13D11A7D014A3682FDD9793241F1579FC2B728C8320F3918AA82A6BB91C + D2A4CEB484C226765441401110B55D6A4C7D9EED2610C4F865AAB255996D7E09 + 4DB02D711246C6F0596C375F5318323FAF682EB5431A379104453648A029B49D + F72118353F8A0A913D9ACF935F13E74999E193F06185904C7E13C107FB406236 + 163EACA9AB157C28B4DAE243C941437CC884311E3E64A6962F9CC6417DDE597C + F0DECA883B1E3E8EFEE0BFE157BF7B089D33E6A0880E5423E635727D65591326 + BF741BF35026875ACE09FACA20B0E24778C1E2C978FF7B2FC2A557DE80AFFEF8 + 6ECC7BCE49E858B40C3DE52E7439C25079F02798F4D47D98367B2A364FDA1DD3 + 161D8B814AC66B944A83FDD8BEE171F4AF7B1453EB3B70D4E23938F394E7E0A4 + 53CFC0EE73F7F454A1BFCEF227555FFA656AB60DC5817E7CFB5BB7E17BB7FF1C + FBEEBB3F5EFEF29739E1BE3BFA0B8ED867E81C5CC1673FFB1977DF2771C3359F + C18205F3B1DD91A6A85EF3E6471F3CD7C40F812916483FDA721914FA76E0031F + F80856FFEA5E1CBBDF41C8F4BB0D92BE684C0945535DC5AD5D9AEB1AC58669BA + 8B0B11B3B65FDD6BEAD20DE214D1C4494C9AC83AF938A1417A449C86DB128D36 + E745DEECF774E204C8119C664D9368D3A78F701BA06B53E47E98CBAA7AC6C9F8 + F0DDBFF58724E243EB4526A7F1F0C1CF69634C921FDAB0A4C952449EA29414A4 + A3600499F86436B7F2439BBF4C4EF20B9263B17CA6A469A03CD0A95FA6175575 + 9009D1CA0F913A5B7140E3613767DE93F243E325CD880E62CDE407DBAF5C42CD + E487366A1D2EF91AC741DF9399876366CD8BDE5CDE2064723E96B645FE941A07 + 4529CA2428F9A1CBCA0F7E9EDF153E42F9210B4F123EE49F2A191BE243692544 + CC8927D5C1B3F8E038A81EA0F0A13C8E4A72299F541B79A9B403C2877CCCF49A + 2DE82EB9AA3D4F875BE120091FB26284F8E03D48DCB59FB4820FB64985D8358F + 4F234E4B972EED7137ED563A742D4C858A6A93B50DE78D6506920A561B0307CC + 963051124992279E76ECC9C516109459422C511162362456979CC7AC0398ECCE + 9C48F99E8830485D281F1A316FF9B16803D5A669339ADB8D9CF727902C11603B + 6DA140BECF683FBE4E36ADF1B1B94FACFD5A40160BB635A06C7F6DC24DA96FD9 + 4E6DE8123A7C9E65F4524DCAF4A879D2E94725422C79550486EA26491D1AE243 + 61CB161F6A6B2BF8601FF82C122F0A3F6AD3ECC9C58EB3CDFE2A136A18126BC7 + 4B1B88FE96AD5F0B59EF091F528BCB71549A55E1837D5539039B91987F6B218E + 870F7E8ECFA3EF15DB417C108B76E18F858F177FFC8BB8E5F607519FB61B909F + E408931322B59277C1AE37FE5F537E99C236D41EFA055EB2743E2EFEE065DE94 + F69F3FF811AEBEE66A6CE95C80B927BC0A8339B77996FBD0BBFA5E6C58B90207 + 1F731CF293DD498B876947C0A254C617E36D8313A87D1BD1BB7E3506B66EC26E + 9D392CD9730E4E597E2A4E3C7E29E6CE9E8562A9889FDF7E07FEE3D66F61EA8C + D938FB9C57E090A5876373EF0E0C1406D13DB51BBD5BB7E3F3577E1293DB32F8 + FCE7AF72F8ECC4F67EE2FA69C6B1063949FB97632318C7A6CE4145071D45D73C + 8E77BEFE1D98559AE49F5FEF1F403E95F62489C928B3DE293C760CA78F132917 + 354EF4678A0B1357BD5376D63B91171B3B08FF571B4E2DA03C4CDE072A36C88D + 2256D65F491AA7517E52A3A2BE6BDEF72A5DCFA1A3EAD648C609E56C09B9520D + 6D05D7E2F97BE2AE257BE1DBBFBCD387852BA16AABF8904B40583B2C497E28CF + 8F1C7F253FF89EE487302F57051DD8B481CB4CAFBA5F567E70EDF335AE095917 + 446C6C9D3345F1F139567E281C5CA588ACFC500A172B67B866791861DA11F9F9 + 8C273F44FCA4394A921FDAC8ADBB8942D6253F940A4272D9BA10C86AA12A058A + 12B3C456E444F3630F823219AA1D8A74B6F85084B2F6D130D58EC5878D624BC2 + 87DA35163EECDE697DC72C3EE4082FDF5C1BCDA7684E6981E4DE60F12172A4EF + DADC573A8CCAA231163ED826CE05E7843FC2872C62769C2D3E78C9EA247FA8E0 + EA4D1D70C0013DAEE1DD3A59CB3C21E2A449B39BB53AAA8829D97065D796B7BD + 7249B0A3EC80EE6B735BE8E220F179EC303B28B38836D2509D6A7D652C102CE8 + A566D446270D8536B7B0B2B348972E2D72694F44C4A4F162BFC8662DE396CF8B + 5488362796D5D62884976DE56945F66FCB8C75A97D36AF9017C566B215952107 + 6D8150BE5F3613AAC6475A1B8D834823D5A632C30A80D6C17F2C7C2801A7161E + 9FBF33F8D0BC685E850F5E549F6B612A42B2193EEC185A7C28F24FC2C19A1AAC + B6C99E0C850FDD4B8B4F39C77889602A1F0809A1B48E4AFBC0BECBCEDF0C1F72 + 105744203787135E742E7E5B9883A726CD44BEAD0B53A8512CBB93274F511937 + FE6E736786EACE8C6BEFC046141FFA355EB3FC48BCEBED6F45A93C80B67C17D6 + 3EFA203EFEE91B70DBBD1BB1DBD16762DA824528579D20AC5451ADC7BE526DBE + 169DD5BEB8B175F74F3B32E53531BD8EE03EF9087A98F0B22B85A30F5EE8BEEB + 0E493DBD58FE821762F91967A0DC1F61E3F6AD8EE0A5316DD634ACFCDBC3B8FA + A31FC749CB8EC0473E7CB1CFA4B07DB0E28BF1265D5E0354CF70C262CFA14CCD + 931392A02E37D6BFF9ED6FF1DE375C80A3E72F457B973BE8541CC64924AB355F + 0A864489C42526468C8A8CA3EA98713D1BC5B99DE8C94EFFB0F64A197139E09A + D744A57CF45BADA1418A3C814BFB540F23C4C9CF99D52CA5928893F53077823D + ED8878B51D534A590CE586B0ADCB118B825BBB3D296C5D72307EBBC08DD3DA35 + 1E1F224149F890A3ACF021F9213FD1B1E447E867D44C7EE81EF2ED09E5871C68 + B5F9DB30751E90654691594907479B38566442F243DA2905B348A36EE587722B + 71DDF359F2FB52D246996642F9A10024BE4EF921FF4B11AD56E587E46EB8BFE8 + D9B6C6A695638AECB619CB4582397FD2BE5912A6C86765C6E667780F8E8FCD2E + AEF65B7C28DD0ABF4BA2A2522E49BE48F679D62C95840F9119F541F55C93F0A1 + BA7B36508663457CA852C5CEE083CFD4679BE183AFAB8E22E7C3FA4BB7820FF9 + D785BEC1C3C469FEFCF93DEE46DE594527ECB052302F01451A07AB89B1999565 + 77D5E9DA6EB46A80D8BA98AC40A3D4FDF28EE773A48A0B239464BFB5517FCD80 + 1E4625A81D7A5DF7B38052BE087D4E93213BB64D352F27371B0DA17B8970F112 + F8A4B296B6454EDD1C779D306D65669B613B894085C4C0F6DB6A46D4261B9961 + 33BCDAFEF2759D84345F5603634BB7587CE86F39AB8763C27B53683D537CC86C + 283FAF67131F7ABD157CC8243B117CE87349F890EF1B17F66E0BF641FF41CFC3 + 63D999C8B54D4687DBF0BB1CE9614F86B24E00A1DD6DDA6E2EDD269E19D884C2 + 8A3B71E14B4FC29B5E732E8A43FD5E2BD5E9EECDFA705FF9CE8FF1891B6E45BA + 7B3A0E59B60CFDB51C7A239A6C338E38157C4913EFF7538F46C2EB1945C74D38 + E5DA99611E2577CFFE2D58FDC03DC8560671F3D7BE80850BE763D5EA756873ED + C9D32434A50BF7DF7B1FAEBBFA3378D93F9D8DF3DFF206F4151D51AB71A37DBA + 2FDFF0FC60843891C3D551F50EDA1D3947E06A25FCFB57BE8AEB3EF6799CB5F4 + 4C874B46CA394CD6F8139BDFD2DE4447BFA6C847F5910865AA3179CAD2CF29AA + 35CC7511DA2ABC77B5417CF87AD593A858D3448294F2E4C9D6B7532A88912499 + A37D9C461CC6A59972C429E3D66DAD0D938B8EE4E64AE8EB2A6392238FD58108 + EB961D8EEF6C5F87CD0D026031617F17EE88216E06161F5CAB0A65B7F2C31E50 + 77467ED883896483951FCAE726F3965E675BAC4F8D8DECB5FB8BFA26F9A1E785 + F24317E5879206CB8FC8CA23DDC3CA0F7E9FED11D192194887622B3F9288E5B3 + 213FEC78C94CA743AAEECFDF95BA46E65AF90B25C98FB1F0C1EF8BAC245545D0 + 3D93D2E1EC6A7C28A8AC557C286583C5870EE876CE427CD8FD450708BBBF2862 + 99CF56A26F9F6CB8819926F888A3EADC2FDD7A535A27F9870898EAB07EC4B2E5 + E4262D8654B99C3036545EFAD63159A1EDBC3FEF4D164D275E5E7C5D6C54EA3B + 9B78309C9850E334DE65275336784DA83D59C98B5F832BF5A52597769295419D + 9F2171D47795295BFE57F213A0564760927647DA0AAB22B61B6D781A182B2787 + C06EC786DF57A14545B158B6AEB1560E26CDBB4E24161FD244ED0C3EE40CCFDF + 498C890FCD8DC587F543223EF8BEA2CFE4D8F76CE243EA76451AD99355337C84 + 5A40914C8B0FFE6E37B1101FCA4BA612075287CFDC6D2E663FF715B86BB00B5D + 33E7A19D21DEF429C84428A65DBB23928A0C7254100D6E4271D5DDF8D0ABCFC2 + BF9C73066A7DDB40BF6C371B48B7315C39837B1F7C181FFDE895F8CBE3EBB1E8 + C417BB8D7C2F0C55227444CC429D1E89FE4A358840438352AC533E641D412B62 + 52C6ADF7A1EDD8F0F07D78C54B5E887F7EE98BB071D35A44F9085DD9363CFC87 + FBF0BD6FDE82D7BCFA5CBCE09CB31C69ABA0BF5AF2B993F2A9B686C74FC23C20 + CEE8ED1368A662531D1B33A9CD1DD87AB6E3924B2EC77DBFBC0FA71C7A0A061D + 29F4A906487A3847514C88D030C5651B242AAEF157F7DA264F9ABC06AA8E9C23 + A069D41AD9C06BBE6E9E7FBFE1D794A9478DD401A3733D0DFF1DC53E4CA95144 + 09C3457EE3BF1D194B53F3E54EE2A59C235125F4E607D1554A61D0F1D46D2F5C + 8EAFDF7F0FFA1BD142CDE48742B695C8D2E2431A629BB8EF1F253FB45E92E487 + D693324DABD493362669AE14E12CB22099A2CD91AF7163A3994E6B973FB28628 + F92DDB4B2B865C40345E369BF678F2A395F16A263F94E6C5CA0FE528B4845101 + 2BA1FCE0776C2916FE9E840FCA17C94D6A99E4CAA1C83D9901AD86F07FE3FE92 + 848F707FE1676C8592101F8AB823196D860F691B555DC2E243FC8357023E7A53 + 7BEDB597274E02AD1AAA81D400E9DF303F8200AFC1D6662095AF26899DA06F07 + 1BA862C14A46465384F549B121E656AD167ACBCBD729294A602C60EB19BC54FB + 460E6CEA9BFDDDDA85D586F064223BBD3675DE8F7655E65B52E9004E848AEA86 + F71523567F2DB02D886D1DB556802D22A6538A22D804DE7001D8480CFBBEC587 + ECBE49A7B056F12187745B868579534890548BE8FF123EA82993CF98CC0CEC5B + 880FF98559B39DEE3B63E62C1C74D62BF0B3C20CB44D9B87CE9A2339B5581353 + 61124BE6732A55BD590D835B505BFB003EFDAE57E0D4638E40D4FF148AE53A0A + A92EA47279F75926B865E8F810AEBBE9665CFBBDDF60F7535F855ABA03F92AB5 + C89961ED4A6CAE1B2101EC558AA7551291C809CA7A095B57AFC0D4D4106EBAE6 + 1328D70AE8CFA6B075ED465C72FE3BF0C23397E35FAFBCCCF19108FDA5220A19 + 46013A011AE59A12278F9BA831C6AE11359FB3CA8D637B169BD6ADC59BDE7001 + 508870C0BC03512A0CF802BA243834E5C5DAA438258137D579E204AF4922A962 + C41D89965F6F353AD797E2FEB98E6598559C3E5174F6AE374AB3D4EBC3C93047 + 45D38D5A6C2AE3629CC2471513A666D01DBC529D682F3B3CA62A28E5DCD815AA + D85CCFE1B1E71D87FFFEFDEFFCFC533E286F1BA386850F1E2854A34B18B5F808 + E58770683508BB4A7EC8343D51F92117072B179AC90FDDC3F623497E6803A51F + 2DC78B0481FB0BDB49194CDF49ABBDB01A96B1E487C66B67E5873678E5390CC7 + C3CA0F2BE7C7931FDC3F850FCA0F951E09F1614DBD9A1F5B983E091F96F48D87 + 0FB5579C81F75004FDCEE2C3EE2F63E1C3DEB7D9FEA2A0086550273E984493E3 + 64F141D39CC6A6457CC41A27F742B7068F69D77943121CEB4C97746A57C7F59E + DDE0556999DF67C3E48D2F4D8B1CCB38C9CA1524875CCB2CED045922A1D77525 + 78BE3715061A5C0ECAE2C58B7D9B94D6DFAAE4423F2ADBD7503DA8F40864AA3C + 0D72426CA23012264523C85EAD09B524D5F62BEC6FB368A3B116B165E41CF7FD + F6DBCF67ACD5694C82C1F6CD8EA95ED7B8ECBDF7DEFEBB4A08278DDB44F1A1A8 + 40A55850D48A342D1C2FE5DBFA47E383ED5374E0AEC487D23628C797CA4B2859 + A0F0A1F677386170F08967E2BEA987A132792E3A1C47EAE2492EED4E6A99B427 + 00E95201998E2E44437D5873CFED78E9B1FBE182D7BDCCCDDB9E7E5B2F95533E + CF12CA8E0CD69D809B32157FBCEFAF78F9851F45E7D273D0DE3DC7BFE7FB37AC + 39C1707912BE964971E3A330C97A4D4B3B4948EF53D8B6EA4FF8E05BCFC349A7 + 1C8727878A58F9E00A5CF3F12B317FF7B9D867EF0578E73BDE84B9F3E6623B4F + D6E477C88E0E4D0BAE74C3CFAAEECD7529CF4226E552F8E35D7FC0F9E75F8825 + 8B0E4677DB4C544B433E01A8FFF1892F6BB106C93B8457BDF98E7D6011E4B44F + 47D0A85FE789530DF97A65588344FF274FACBC53B99BDB54E37743F092723D45 + 0DE294C688162A3DFC95942764110A28663AD05EC97AD35EDD11C8EC50155BA6 + CEC0EF0FD90BABD7AFF3582706784A96E9DEE283D891FF60888F507E841BF0CE + CA0FDE47876166E367992945AB5A73FD58F2439B38AB3D70E35749AD56E58735 + 75F15FCA0B69B2792FAE2FFECDB1E33AB305BE95E7486947EC7D9F2DF92179CB + F1E26150BE98D644A6CFB7223FA865926F97B4F4CABAAD44BADC6FD9DFB1F061 + C9C7AEC487B45E9497AB56AD1AD6BE8B882569FE437CF073C40765AD925F37C3 + 4768326C860F8E11F777E283F7933FAA6ABDF26F958591C66F3C7C0C1327F7A0 + 6E35420901A595084FF0561B621B6E371C85C7CA114CA1A7647A62B3DC14952F + 4804CB8667CA14A601D17BE126AC322AAD025B00D1E795504B66275B8C320453 + E813653FAB905AE57DE0A54D5E619B5257F2929F4EE8F3A2FB0B705AC8724894 + F375AB6A63BB305594D7967791B9D1F657CF4C02AC6CC072E0DB597C8858B78A + 0FB55198B027C15D890FAB92DDD5F8D0BAB23E631A33692CC7C207BFB7E4E8E3 + B0FEA0E7637D752ABAD36DE8A895BDC6A99A76A735466D315F59AA0DF94C16D9 + 9E27B1EDAF77A17D68330EDD6F319EF7BCE538F5A8259837770F443437B2DC4A + 3E833B7E7517DE7AF9F5987ECC8B7D2A036FF292B6D087B48D941749FB9CE434 + E545A8A43A3D552019C9977660F0F1BFE0E0395DB8F21357607BA18CDFFCFA97 + B8F3CE3BF0D677BC1DFFFD9FDFC703F7DC8D37BEEE5578D94B5E8CB2BB6FDF20 + 379128317353AAF1ECD84C978A9FC31C51A912BEFE8DEFE1AA4F7C1E271E7382 + EB83C300B1E09DBF2B5EEBE44D6B34B739F214E76E8ABC4628EBF33AD5BDA6CC + 6B93B8C610E775A26FB7771CAFC7CEE4CCFF44AD13FDBAFCBDA20A6CAEA75484 + A04C4B4C9CD4F6D8D438D29B6C5476FF2F6220DB8EB60AF36FF1B365A0BF84ED + 471E8EDB2A3D58BF71C3A83C6E213E741227169AC90FBB0693E487CA3085A7F9 + F1E4072F95D590F3F6CEC80FA54D9019C6FAC98C273F4494941E80F7D7061BCA + 0FB6939F95FB85CDF56343DE9BED2FB61A42ABF2C39AF4D47E698894CF6967E4 + 072F459F49B363F1C1CFCA8789972C3C4A56A9BE5B0D93C6D3E24329796CB1E2 + 56FAAB6BA2F8482AAE2C371D4524EE2C3E948B4AD5253816213ECA3EF16C65C2 + F8F0A6BA050B16F822BF76429354BE56A568DFE3A585AE0E4ADDA67C187A5DF7 + E2A506EBB9F69E76F352015F2E385BD85529D4551FC766684D9A9410983A15C8 + 0745836241664F53F6A412AA06E597631D39ADE0904F8C65DE3662CB2E34D5E8 + E18215A9B0C4838050CE2181527DB26DD36BFA9CC65C3668BB58ADA949243604 + FAAEC687A23BE408ADF10CF1A179180B1FCAF2CBF1B26552848FB0848AC62909 + 1FD65EBF33F8083561213EEC7BCDF0618302427CCC99BF00335FF016FC61A01B + 33DA26B94D981164555469CECA5033D38662AADD9BD3A6A60BE82E6F41AA7723 + B66C7C0A3B36AEC3C2FA261C77C4129C75F6395876F4324CEA6CC30F7F7A27DE + 72F9E7B1E0D47F4635D78D1A7D7E0C718A9E469C4A7EDB2FA43B7D0C1E476052 + 5404B6ACC6C0EA0770F59597E180FDF7C637BE7D1B7E75D7AFF1AE4B2F46B55C + C0AA157FC50FFFE35B3860C13CBCFF43EFC3EC39B3D0EF185499241E566D9FF2 + 517799614F6C7A086590CF39AC0EF6E223977F0EBF7364EFE8A5C7A0AFA7D2A8 + D357F364271729A9659C4E20578DFD95E20498556FBEF34931A3460996460251 + 92286AAA72F48F6AE47FF249456B71245FE489CF68E2346CBA4313E2D448744E + F6C7F2376EC4D097EB747396F5A92422262C1DAA62FD738FC5B5BFBB7397E043 + B998B8018A5458AC527EA8187A283FEC7DACFCB0E943A4490971AECF4B8B1CCA + 0F6D6A7AAD99FC08A359ADFCB0873D99FBE40FFA4CE487B4DBD44C58F9A12836 + F91659F991442CACFC9096AE15F9610F7A49F2437E39BB0A1F2461CA226FF1C1 + EFF3BD678A0FBBBFEC0C3E34E7FF1BF0A19C4EAA2CD1205EBDA9C58B17FB5A75 + 76C308ED903AAD0860242A8AFEB20DD677AD03B11AA301B5A7231BAE195ED6DB + 9FCFA56A9295A2EDA54D5389DC34B0AA561F82DBDA9F2DE3B680D604C9A98E03 + 46759E4DC71E9233A9B1356672FCB3219A21E0C236E975DE8B21A87CFEEAD5AB + 871DEDE43CA82CACCADE2A673BF9A5258DA316969CEED4079120D982653EA56A + 59CF94BA7322F8203688114514866928D416AB2D4AC287559B37EB97B442F417 + 5AB972E5A8CF287F8ACAC8EC2C3EF45A123E546330091FD6915CF89053A4150E + 13C1475B47274E7AD1B9F8AFFA0214775B8419C52CA694DC092DC7829E15A42A + 1D28A5A6BBBD9AF5E27AD1991A402E4377A06E54D39351EDDF8CDEC7FE8CECBA + 1558B24716671E77A89BAB217CF5970F61EE29AFF6D17599EAA08FAA1B89A6C3 + B0E373ECC753F265565CAF5C9B325E2333D9B19C8E720F9E5CF147BCE88C13F1 + B6B7FC0BAEBBFE4B78F4D19578E7BB2E40AFF7DB7144CFE1E48BD75D873FFCF2 + A7B8E8E2F7E0BC579E8B9C234A030CC37624A59A726398A33E260796934B374C + 742CA39273C469CB9AB578F35BDE8F8A938BFB2F3A0085019EBAE900DED02679 + 335CB5418C22AF7592AF9237DB0D13A7D8813CCEEF548AC99637DDC989BC9120 + B32607F3387A91042B4AC59AA8F470EEA6BA8F664CDB140EFEB322508E1C6623 + 0CE6AA985D7087C96A1D7DF93A86AA1186DAA7E0CF8BE7E3AE471F6A091FCD0E + 83567ED09783D8A3493E941FAA1FC61F6925C2356EEF6D37E656E507FD8CB4D6 + 746F7D6F2CF9A1A2AE32CF27ED2F6A0B9FA7CD50444787F489C80FFE704C2857 + 296F43F9A17AAD921F0A06515EBC67223F38563217D954003612DA9238F545CE + D213C1879D47E619E47792F0A1DA74DA6394C7A9193EB44FB78A0FCE2FF1A1FD + B3557C28F584923B2B61E8DF031F3493129BC2876BD388C6492A2CFD5852A154 + FC36B99F3CD279D90D529DB11EF352115B95A74D3E9504409BDFC1E65F082F55 + 4AE642D3494BDEFD4AB6993428164896C9CAA18F93A45044A9C62D7950BB421F + 24B5896446510C963587C24EDF939D5893CD4BDA183B665683213BAE2638ECAF + C06BD3EF6B51DAF9E5A224A8094845ED48E5A9F16A051F56D88589E8B42148FB + A5C5A2F1E28F4DFE66C7B5157C686C92F0A1FA59320F6AB186597A5BC5878480 + B2D7B2BDD2B0B68A0F956B99083E44EE0F597A0CD61D710EFE96DD0D7BA4BA31 + B9D0875A6E9B6BB82300954E5430CD7D29877CCACD476D9BCF025E8E98B3CB6D + 023947141CC9A1E6A66FDD438E44AD40CDE166D6C1CFC1E4FD8E41DF60C991AD + F2709EECD8D9391AA9D1C6B6205E0B957487CFF1441292AD0C6172B6829EB54F + A0D311A86BAFBAD4A70CD8D6DB8FF3DFFA366CEBE947FBA429F8FD6F7F875B6F + B90535B79FD4DC9C1CB2DF9EF8C07BDF86A5872DF159B40B25776AE51C306754 + D5E196A6BC14D7BF1BB75C16F7DEF327BCE58D17E1E0038F40D724470659238F + 9FA7798D24C99BE3AA31318A1A46BE7A9C38335B8F4D7A299F0833F661E267B2 + D5A2EFA3F7DFAAC76559FCE748641A9179ED7425E01A421CBD475617A72A50AE + A711E2144F1A865339F0BEE52C6B08D630BD50419BFBFE902352DB4B55140F3D + 0CDFDCF004B6F6EC189E7F255A15B9B7F848C2ABC5873D312B8AD5A622B1F283 + 84419B8DC2B1434D813D00DA4D3D941F2401941F8AEAB2C5C4ADFC501BADF684 + BFCBA465933DDA365BF9C1D7B5F6355E763DB5223FB45F59796B3536762E14FA + 2E4D8D4ABC84E3A5CB26DED4215AE3CE1FED2FF2C7E2E7AC997E3CF9B1ABF0A1 + FC75161F92DFAABD391E3ED45EDDD7EED5C287721626E1437361F121CC25E143 + E467A2F8D078B58A0F5E92B7213E3C71523A029959FE3F776F1E6BDB75DFF7AD + 73EEBD6FE074290E2245E971A6286AA04446831D27B2ECD84EECA0B5323B0DD0 + 06999C09089AA28D6320059C2668DA2028DA3F8AB601521445870408D2C4B512 + 231E62C5B12C57836589A26489224589A2440D7CEFF191EFBD7BEF39A7FBB3F7 + FE9CFB7D4BFB4CF7DD47C9D9C4E3BDF79CBDD75EEBB7BEEBB77EEB377A424F07 + 589DAA2026A719AB5FDB895481A56928B38023C9E2343654CD7EA8D36C4438D0 + 9AA59541608A9190297513AD673D36C0481FCC589B047492D50E68FB7431A496 + 8B76B8E803EFAD9D816508825055237F23A1D21F34371999983E4CB9491BB60A + 6DE93B8C0890A8B511904EDE030F3CD03EC3C66D849EB5AA6A095A2152B32800 + 760E72FEAC048DE6861341E6A072C12DC307F43261DB327CB828121F3011E60B + 7CA49FC1328751E610075A55B3A678702ECC8742DFC8B46B19184B0558AC5ABA + 2EC287858FA5850C8276F81B7A6142AE7348253EEC878C5A474F0330D6C50727 + C5F6E77D0F96D1633F5C7EE5F2EDE5B5D7BDAEECEC354C647CA14C4760F74499 + 4DAE6B36FEAD726AFC52B9F0DC27CAD73EF6A172CB6B5E574E5C7743B9E9D6DD + B273FBDDE5E2F56F28E57423603542C3E4E5B3AD09EEE2C1ACEC8C4913100930 + ED9B9162CCDF74AF15A0F6C7273B2DCCB873AADE995D2CFB2FBD58BEF5B98F97 + BFFE277EA03CF7D5AF97B397A6E54FFD99BF509EFBC6D94660FA27E5177EF9DF + 95871E7F673973F7BD65BF617E4F3DF1B172F0CDE7CA1F7FFF0F97BFF2937FBA + DC7ECB6BCA853E4DC978E774972260D46D2027C6DBE59FFED30F949FF999FFBE + BCE75DEF2BA3F14E994E2EB725513A87EE5E6B349DCC7D98B62C85D20A4E3A87 + 1F965C41C0DA39D8EB4BA8748EE36DD6F1A9C9307B07F283491701D80A630D66 + 267D083DD9B1DA6747871AA776124BD7F7125178234CAA07E5047D391895AF35 + 82E0D3EF797BF9671FFED015F80053FC9DF848EC2FC30774F310E4A9BCE61F38 + 2C731FFCC3C316EB6119FF703DC0CB33978EC294E9118C0494DFB8CED5309804 + B2E61F3C4F1FB12CC8E76BB3D422FEC1A18D769F7EFAE96FE31F35BDFCCCBD4C + 6D089B2A7DA8F907BFC33F4C260C9FD367512B475E3CA3FFA7FC23F30FA9F130 + 3F21F4827FA44B46ED6759F30FF0C16706E8AC830F354DF40D7E0B8FB6FE9CF8 + 50C98183B659D9756A873FAFB3BF0CE183B64D8F00DDD81797E1C3394C7CD05F + EEABF121BD96E1C332649BE0033A810FDAB0962363E8F1D1699C9A8EED5AACCF + 8794CE32757C3AF59A465F1BAE44D7639D4569D6CDDABFC9CBD350AD6ED6BE2A + 7021A6C4B70DB3DCAA6A067C66350718DA24EBB6259A79A6B8B2A48AE357F853 + 556B3DA0CCBECBBBD53EF02E1DF7B437D74E6CCBC66B9230DF6906EB3C1D9849 + 950B21C0BE7A32D0272A2FC1C702757158685106A11A5321469A98E7C494FDCE + B3996C87F0A1166C193E680B7C70CF51F0E18275F11931C342AFF1615A0C8B6E + 32767DC88E1B1F461A797A021B9EC6991B4D9647C587F9605E7BC79DE5EEDFF5 + 7DE557B71E2E5B379D293B239CA12F9583F1AC35719D38D82A3BCDE6BFB3FD4A + B9F4C26F9783CFFE46F92BFFD1FBCBB986F9FCE2877EA37CF9DCAC9C3D714799 + DD764FB9FDB65BCB4D37EFB2A3960B97BBA8B013B3CBAD41AECE47D43262E6B1 + D5D83432D778AB4D13C05B29CDB2333E287B975E2E2F7DE9C9F2E8F4CBE575F7 + DC57EE7EF3E3E5D177FEEEF233FFD57F5B3EF9B967CBA3DFFF238DBC765BB9F8 + 7283ADA69DD3DB933239FF8DF2F98FFF7AB96B77BBFCE77FEDCF97F7FFC1DFDF + CA1DE72FF7656F1A817087C082CBD3F2F7FFC1FF54FEC5FFFBEFCAA36F7F6FD9 + 6BF3045DEE05972EF5C0389CBADBF404B3CEC7A9CDE934EBCD709CE4679D266A + D6084A3B24CF9C555AA93E3966DBEE014EE6D336FBF7B8FFAEF479A33AADD695 + A9070E338A1FD26D67D209602F9FEA84D09D0BD3F2953B6F2E1FBEF7B5E52B0D + 5F4B7C88833AC2A72E33C5E53D9AA0C187292F3C95A716DD8DD24D509F17EE61 + 3D24FF4887F375F987751C5D33AE55F60437529E31516CE67AD3A997FBAC5A9F + FCD6BC55D6CECC724BE96FB86C3D25BDDC44E9B3D50BE41FF276D31EB071CB3F + 180BFDE0B321FEC105FF50C89037A436C4773316DEE93DE94B95FC83FD2D8305 + 8E820FCD7DF49FFD23EBB5B98FF96E8542F0C19C709F3E51353EF867A1783E73 + DF5233A71F54E2C3EA23898F145A86F0E18177113E4CFEC93B1082B39C4E46F7 + ADC2876392DF1B1085E0DCE3A3CBE3D4BC7C17E98A019B64CD5C078648AB9172 + 13B4B69B958AE92412ADE6BC2C90A729C99C1B7CC6A9DB70EC3A44345593F5E6 + C2E0213204348D0012B803E4B230A159A58722187886C5A76040BF00484B953E + 0A42A9D98CAC266553CB83F40B00954833E19B9A37FD90B41DD3761D49E182C8 + 8913506AB058609CE4A0A9110396205160C8BA5635B0D58C64D673AB9A5BFC51 + 21CB05CBEFA6D4071FD0D52CE79A0A2DB4B80C1F66C4051F9AF3AE061F8E6F28 + C222F1C166642DABC4077DA08D34C5D6B447D3C8E2731E92810CE1C3D20B26E5 + E33B3462FC6EB2353746FB2D3E3CA96F828F071F796B39F59E3F5C3E39B9AD9C + BCFE356D41DBC9D6AC3573DDB04F21DB496B96DBBFF8D5F2CA677FBDFCAD3FF9 + 07CA9FFAC3EF2F175EBE503EF7A5AF968F7EE289F26B1FFE8DF2B9CF7EB67CFD + 6C73C079C35BCBCD6FFBFE72891403FBAF10C37645B1DA39859BDF791742412B + 34311FED4D93B6ECC85643BEF185AF956FFECAFF59766FB9ADFCC88FFF89F2F3 + 1FF885F2ECF9FDF2D80FFD5879B911CEC85C3EDE3ED5DCDE30F4E9E546789A96 + EB1AA1EB1B4F7FAA3CF7DB9F283FFABEEF2DFFC55FFB8BE5BE7BCF9473179B11 + CDF6CA8D2777CA0BDF385BFED25FFDA9F2E5AF5D2E6F7DC70FB439A846D30BAD + D033D2ECD69BDADA54046D3F0FBA8496AD20356D1DCE5B2771733DA1719AEC75 + 424E2F34751175CDF793AECD9D83CE6FAAD51FB51AA98356086B05AB695F9E65 + 765804B84E57C04F04D9D1A5E6C0714323ECCFC6E5F2A56939FBBE77967FF4D1 + 0FCD2365D33433840FD68B45AA6B813B4FCFAE63B10CFED97CC9F903C6144E2C + 99A2F6D4F248438121AC47341C595E04FE01A6594FE9842CFFE0B2F61DFC83F6 + 4DAAAC2988F5A716D8F5CB7BAD0D49FBAE37F887C560F9BBCEC4EFE76A72DC9B + 32F82553ECD4FC436D13FC83B1C12FE9BFFCC34365F28F3A8D8C82A6F9E752AB + C27879CE7A6F0A341E8ACC3964BBD6BD3321A3F84873698D0FFB36848F740548 + 7CF01EF630F0417B0A27EC2FA95D4F0BC8103ED0906AFEE3738BF3AE830F72F8 + F1BB02A60A81C487F4AAF161F08F6D981C73193ED88F7DD6B66B7C64B50B2FFA + D68CAB33D53537ECF201C0805808237400C18097B8814874370DB39EAA9EB346 + 1BA061C26B1558DA5AE938C206C4E15EC3F8BD87779013827733610E08825B23 + CFA4604C1013CF46693D1BFAC584B939A74F951A2D9E6312794ED38F9BB5C474 + 31E8C0680D1D268785E52949355EDAC825BE8B91893477552E5E3747722CC19C + AC956618B252B815AC791FFD5710E25DAAE75D9002DB9FD6ED314B2AEFC7AC46 + 9F5C6C6966727EF56962ECBC23F10133E43E55DC890FB585B4A179CF1A6D2C54 + 85D675F0A1737E9ABE7807F44278B6CC846A556BE4A989322AC2539BF5E914E8 + 52AD5CE3C3DA7DB443BF65C68BF06148AEF8F094B40E3EC0AAF398EDCB94590F + CC5D7BEA7DCD2DE5B1DFF7FEF26F761E2A939BEF6A84A506070D8FDE1F5F2EBB + 7B6CF44DDB8DB0717972A15C78E283E5F7DF7E50FE97FFE1EF96D9C10E9260D3 + 36EAF197CBB917CF958F7DF489F277FFE13F2E9F19BDBE9C79ECBDCDA67EA9D5 + 3C95BE74485DD0767C585DA4FD62D6277E24B28CC4980841673FFA81F25B1FFC + B7E5B58FBCBDBCEEA13797373CFCD6F2E2F94B65B67DB24DD079B087766BAB33 + 7D8DF61BC1E2A05CDF087AA38397CAD39FF8483938FFCDF267FFE33F567EF2CF + FC44B9E9BA53656F322DBFF589DF2C7FFEAFFCCD72E73D6F2FD7DF727FD96B04 + C4139397DB54035D46F0599F08F3602E1469B243BCDB3AE8344B9DD0A38338A6 + BAFDB61FE3DEB4379A74B99C5A616BD6170A9E4CE6FE5208663BB32E42AF8BDE + A39DFD62419643B3E621CD102867ADDF20A6ADADF2ADDB76CB27DF7867F9D58F + 7DB49D7B37A7DAC7C69372F28FC4473AE2820FCC207920014FB986E5579A8A8D + 88725DA7905EF30F53CC58E5C1AAF31E54D38CA31092A910D85F2C7ECE9AD554 + A625C1B5A4A95C2D1AFC9EDF5977BC8FFD45578A21FEC1FBE01FF01AD61EFC29 + F9E2227E6B98BA7B872964E003F00CE8252DE8D722FEA1764C9F5BB589EC2FFA + DEBAFE1DB3CED5C93F781FDFC1B7A5D1103EF401121F9A136B7C305E8567E964 + 315BDBE13EAD4A0A42E2083AD6427A8D0F9EB3CAC326F8D0A202CDC107CFACC2 + 87561AC6ACE200EC2FC38734AFF1912E1B890FF9ADCAA0BE3E6B273871185763 + 20D194D4F364AD6A8B4BA9B27512EDC1C5336C2E4C8C8EE079A55396E63CB521 + 56A95792368BB2EAB68C34501BC12094B23DC198355433513AB4E7894C95A82A + 42DEAF935E4AE52929A72A9DC932B3B59A98DA79DD85A4A98BC964C13959E964 + 4D5B1624CC5305CF425B81427B9AE4F417B09FA689CFFC13C94C7837E365EC16 + 93F47DAA2C87726448FF4DF091F5EC78DF51F061957569AC6A775D7C38479E58 + 6953952E8B8F7F32CD75F1A100276DD6C1876693217CB41B6CF38CCEA2306868 + A59677193E1E79C7BBCAD9DFFD13E50BB35BCBADFBA7CBC1A4114C4EED95DD4B + F8E36C9797B64E97C989663CCF7FB2BCF6F3BF54FEF7BFF737CB036F79BC9C3B + 7BA19CD8C16C75A98D54BB586E28FFE33FFE67E56FFFA39F2D8FFEC81F2F2F37 + 42589BA13232651F26739CB5A926DB5A72B3AECC48E724DDFB438D1A9C8E0ECA + E4EB4F97A79FFC7439F3E647CB1D6FB8BB79E7B9B2DF0819274E37B4DF43506A + EE9B6D37825E434322F8B61A1A4E2E97E60C594E9F28E55B5F7DAE7CE5631F29 + 0FDD7553F9E99FFECBE5077ECF7BCACFFEDC07CA7FFA537FA73CFEFD3F5ECE4F + 6E6805AF53F87795CE270961A74D4B302FB932ED6BCF4DE7E908BA88B959EBF7 + 34EAB38A6FB7799C3AEDD19699C57B935F9BFF0941ECA07304C7978BEF4ECCBA + 649B5DAA03CC7C97BBF78D46839AA783ED69D96FE8D29C55CB4BCDFCBCF0038F + 95FFED531F293785592DB53D890FCDD16002DE063EF42374FD9B55BAE61F0A5D + 19E185409F056AE513590FAD3E4425FF00E79A79E47B1950B18C7FE856C0BB0C + D7CFFC4219899A0129069F58ACB65EB7C93F3457CA3FE039F000134226FF50C8 + 74E3640E2C200EADD5002964A4E68235A9437A3D67E60162AEB8E41F9AA086F8 + 476A947837EF80972930AE830F53F7AC8B0F152659190161413798C4877C7408 + 1F292CEACA71147C684DD10AB2293E986BC658CFCB2A7C2074193998F8A01D85 + 26E9D5085D9D8F13457ED381503BB2277B41E224D5D993F533A2234CB4A7A7FA + 4A09DB8DD1F731519A4EB4E16696680704000007044680D0614CC18913847E4E + 800926E1E6941B950E695C5646761232C1A3F724A0D5A60024245719D190C3BB + 8213E3354F88F4CA2805DB77BC323DC6C558A02BCED39EDAB89FBE60BE53FD4E + 1FF45310686ADB74F076BCB4A3D06B6246DFE9B3A9BECC883CFACFF36A971442 + 121F0A534691D0AE456BD7C5875A1ACDA49A22D7C507F3C2E79CF4A0118B1A7C + 30BF47C5872646F19163151F46D0B090192FEFB4A8E8103E6887452A3E580B9E + B097E1E3B63B5E57EEF9D13F597E71725FB9F5BA33CDEE7CBE9CD8BA506E6864 + FFC9F84439B77543D947E377E1D932FBD0FF55FEB31FFFBEF267FFEA5F6BEBBE + 4DFA92B55B5D6AC9F2C18F7EBCFCB9BFF15F969B1EFD9132BDF591326D0492AD + B6DC4869858ECE59BCCF05331AB7C2CA4E2F808CFB88B45E1FD59BAF3A019E8F + F7D92CC660AA63E46D64DE416736DB1B537E64BB2FA932695327E0787D7AABD9 + 640F2E97E73EFBC9F2F56F3E55DEFF07DFD73C362D3FF74B1F2A6F7AC7EF2D2F + 5EDC6EC6DAD0EA807A85B3D6BCD63A82CFBAD404ADB0343B989BF03AADD0B475 + FC6E05A1FE3B3455DB7D14DE289CCCBB9406932E9B78FF772B44E1EFD49BE9B6 + 7A3FA7D6B437ED9CD4E758EEB54FA399E9089ABFB667E5E6E7F7CBD91B6E2CBF + F5BE47CACF7EF0DFAC8D0F1D7AF95D1EA4E36EE223370BF987A66BF807BFABC1 + E19D6AA87438E64097FC2323BCEC1FFC47330EFC83F5E4FEB009FF68B1D43CAF + 4F8BA6985C5346ED19A0443FEDE350E088BCC183086D28206AB958C53F181FFC + C3E01EDEE9FEA2BB845A2803873CF0252FF06FE84D9B9BF00F0F6BF463153ED4 + EA8B0FDEA7F0B1293EB4DE9876011A587F95CB0A1B43F8702CA6A5487FD865F8 + 480168193EDC4F56E1433AAC830FE7C7C8FCC4470A6D898F667C9D8F53F3C56E + 4A7E291566D15D1AE3EFACDECDA5E3ACC4E37925B5A18E6BEED2018DCF95EE53 + F5E9C4A4C32D7F4344374709CEA683E4A8FDD3F4012C166BE7A4C097B6CBCCCB + 6468BEF585325C54FBAD39874C77CF386CA796A6F5DD31BF918C240BD5EA27E3 + F84CEB607FCD472498A091422AFD01F816F8D427497F9B5AEACE4818DEC598CC + 3A6BE6589958A638487C242017E123231DC04216EDE45F6658AFE9A5BADA5307 + EDD047FAB50A1FAA72C5870EB02C26CBE0404BFAA45F877E17A9315B071FAAD6 + 87F0E141C0E2AC192DB32E3E78CE136A8E2F0B4CBFE9ED8F97971EFB63E5A3A3 + FBCA1D37EE949B2F3EDF0A3314FC7D79D49C90B74F97DDE9F9B2FFC42F94337B + CF96BFF7B7FE6AD939392E2F5F6AA4AB1127D846A83D79BA3CFBEC73E56FFF9D + BF5D266F7867D97AFC8F96E9F9AF9713A5CB7B346BCBAB6C7562D6A8956CCA3C + D9E3EC30EA2EDC64DBFC490C75369D1EFAFBCCCABC582E292DA76D76EFD13CD7 + 512770F4026C2398345B48397D6A5CBE79FE2BE599A79E28679FFF7279CB63EF + 2A77BDEEBE72E1DC5EDBCEC9B694C9B44D4340841B8EDFAD20648D39FEB5FE47 + 93B9996D6BB23F4F45A089CEEFDB3C4E934EB01ACF35556424EFDE379AF6BE52 + 38944F3B3F29F2475D4F641E8C1E9172D6F95875745023372DD7ED1F94575E9A + 95AFFFDE77967FFED5CF97AFF71AA455F8F060A98958416A193E6AFEE1818B36 + 597B604D3F0F234CF94E3782AC2A3FC43F7C870ED48BF887293FEAFDC5F17988 + 63AD7B68907F281CC1DB4C93E2612D3537492FCD82B4EBFE22FFD00A91BE2C8B + F8076B1CBEEAE60FFFC0B5C184996ABCCCE1B6887FD8A7E41F1675F700BD8A7F + 409B9A27ADC287350F332272193ECCA195F8B09032C294D9E68F131F99E2601D + 7C5839C3E8C21A1FEEA5ABF0413F5C77CE197FEB6CBE0A1FCDFBCF8DEEBFFFFE + 361D41DA446BC7320682BD910B09944E5A4222278B8DCA534C0A2879A9023529 + A19B3892A27E4B0C40E2E4C418BD953E2848E36EFEAA5E91244DB9AF5A38EBB1 + E5C4D47DF41442082AC4A77DFA6BF8A9CE675CD61FA370E0D08940F34D4612B8 + 000025FD343F566694F559FD9AD28ECD89C7130C80A24D8B822A84BAA8D367A7 + F6F34A803306E6D7F406B46DDE8CACA7B7081FFCC371937EA2E6D59C50E3037A + 413BC690E1B7353E189F91260A2D890F3EAFE9253E147487F001ADC11642A7FE + 0BE668D9041F3C033E680B8D156DC95CC407CF593F0B7C6402BBC48799E2D574 + 4A034FD6B4AB00997D7203B9ADB9EFCD3FF2C7CACF4FDF54AEBFF5AE4690B854 + 4E4E2FB626B44B8DE8D1B0D5E6FF17CBEEC5AF94E73FFEC132BE88291BEDD941 + AB359AB51A9F9DF2CA7E232434FF6E7BE4D17270F78365FACA85B23DEAFC84C8 + 1C8E74D316F8C5AC369B85E9EEB008F061E83DC2D6C11599B5E7F7150B971CB4 + 116D5D76CB2E4B78EF3951D4D4D09F2D2205C72F1796DCE58BAF94F188849B27 + 1A21E5745B6AE524E9084A679A43E3B475D0975041709B96B9E05466D37936F0 + 56DB35ED344CE3B929AFCC6BD8B509327B535D9B6EA011B47626FBBDAF579740 + 13E16ABBD74871EF6984B136DD55D71EC29CED8E5BED5CD387BDCBE56BB7DF56 + 3E7AE6B6F2A14FFCE615F870FD1E173E5C0FF2257D14E1CD6A5015BE78DE88BC + 3CF4AECB3FC03BFC83FED09EBC581F20795E8E2BF907DFE1D84B5BACD75CABFA + 036942631CA63B58C63FF88EE7E51F3A5A3BE6CC3135C43FB4BAD01FD6AE3C8D + 67AD1F681BFAC0E4E69CEB74887FDC7BEFBD6D5B1CF8E51FCC83B9AC788E3D82 + 7B196FBEAFC687E6530F83EE2F087BEC5BEBE0431E09FF86FFBBBFF02CFD1CC2 + 87F4AEF1E17BD448F22CF3CB58D99B6C7B137C986A037EEBFE04DDF5CFED4D68 + ED4FE865D4736DDAF4E0CC253EDA48E5DE2F7B4D7C1CFA38E5E6980B24A5782B + 1F7369CA6313529BA03F8EFE2F43A62B3AAA4DD59A34E6F1813012832BD5B6A9 + F2B56F46C1296DAA856182CC904BDFDCBCEB710D2D3CFBE846A78A5175AD9277 + 3A120EE58B4A60ABF9308C17300352230E5C78B9E832C2CBCFE9830EF2BC9389 + E6338B1842034D5AAA16978D3719A382A62A64FAACCF83CF653B3EEF183D3D89 + 0F23D8E8638D0F9DEF57E1433F08DA82396C8A0F530A24BDC007EA757E7A0A5A + 868F7AF1253E78B7F4611E7887BE5B898F8CB85C071FFC6D200063D54F60113E + EE7DE8E1F29AEFFF89F2CB2FDD5E6EBCF5CE360125A544A668894627DACDFB86 + D1C5B61CC9F94BA7DB6CDC3BB3CB6DA996369900023EBE4914079EED97834B2F + B599C3F937EB4D68AD3F13C2C00841627C45B24704946916B845DB32EB05DB20 + 5D16BD4DC169D43FB2D57FD3BB583742C956F7EEED4628191170D01F6C1AC169 + 7B7CBAE9E72BE5D4AC73CA9E17EF2501669F3260EE20DE0B31E3361A6EDA0A4E + E3BE9EDD78643EA7D2B5D1FA3DEDCFFF1EF5ED6E4F3A2D5B97E769DA0A4BFCAE + 5076F2A0AB93D7652CEF328ED37E670A6D7EDF9F94B3CD3D5FFA7DBFABFC937F + FB6FE7811F26CA5D860F706CD2BF75F1511F70DC1C0C8EE0195D0DD860E51FF2 + E50CDFCEF5905AF5F473919F196A4F1FDD18EB7555FF2DFFD09AC0059F602C1E + 44D4C2C30756F10F53A77820E5193EA36F468E6FC23F189B420D9F25FFB070B7 + DA8855FCC3F17A70CBDC4CFAE648E74DF0A1DFAA99D0D5CCD067FD2B97E1834B + 0B865A2EC665892FA37E6967537CB8BF402F951F9BE2C3B432CBF0A17261153E + D26F55FF5BF61CF0A1BFF20A7C1CFA38A9595253545F29490EFDED4FC134743F + 0333843D53B8F38CF6E7CCCB50DB8EF37243E55D084CFA4C29804108C0036105 + 54AD7EBB9AF1DAAF3CA5D48C8ACFCDCE9B0288A63637DF2C685C3BDEE578559D + 321EC00D40689F89E63B4D933A7EDB56DDAF45E3CDCF336A4735E571E123EBD3 + 2DC2879A2EBE37F26F537CE8148BC0243E685F4749FA613EA921F56CCD008F1B + 1FE053C7FFC487396516E1A3D65C318EB77ECF7BCB27DEF0A3E5DCF567CACDA3 + 573ACDCAACD5FB94C9B437B16D6D97E978BB6C8DF6CB75E386115F7CB111142E + 95CBFB175BD3DD74B45D4E3602D16B6FBCB95C1E9F28170F10A8B65B93DB4EE9 + 0ADD6EB5E54DC0D56149967996ECF9F810B2F67B6B9E35EF3A3FA879F9393459 + ADA7551F85D6FF1BF79AABEEBE53E5A0F52DDA6BB39D8FC70D2D1A01646B7CB2 + 4D65309BEC9553A3834EE89AF419BF275DEA815680296A8E265DBB08327D5EA6 + 56E06905C24EB8EAF232CDE61AA74E289AF57E500864BDA9AE74CEE3ED7B10A6 + 667DD996E6FB6D7DA878E77E1FE5D7926056F62E5E2E2F9EB9B37CE0E42BE599 + 67BF744562C27423A8F1616878E2030107BEB62E3ED44EE2EBA77F8DAE06F20F + 0F65BA360CAD5DF9426D9E59C63FB88E93DF7A181E5A4F19D9A52683CB340E43 + 39B216F10F4D98466BE94C6C31778364DC5FECE326FCA3EE7F3DDE75F1E1FCA6 + EBCC51F081AFB08584691B9EAB1957A1DB48F5DFA9F860DEF4555A858F450EED + 853C4EF7DC73CFDCC729350B47B992380EA4BE746C34D74D16FD7383CE448343 + 6534BC8C2CE3C484AA9849574A3734B10E814C07E0F461D9F44AA93D7FD6F770 + B2E073FA6388ADA727A56968E2E9632831A2BFEB644D5BA89ECDB5C5738C5D53 + 607D29C1E7896AD3394D0670147A6D820F7DB54C42263EF4EB59171F3AD26212 + C53F417CE898FFDD840F03238E8A8F1B776F2E6FFB437FA1FCE2E57BCA2D68FB + 46D8FA1B010ACD4E23FC5CDC3A5D668D3074EBE517CBDEF34F95979EFD4C39DD + 08583BFB389437A7DB065BB75F7F53F9FAB98BE5F9D16E79F07BBEBFBCB8B755 + CE1D346B92CCFA080C44E1B50571B7BA522BEDA4F6E6B84800D9893DDD497A6E + A69B1E2684ECBD194A29B32B22D0660AD3335B39D1FF7DD06ABA66BDF9CDFCDC + 68C0E6DA211CCF6176A5129ED01AB53E4FD379CA8236BDC0B4177A10908A59C6 + 27DDF7B3D93CCB78CB979AFB0F4D750773531DF7955ED82AB3CB8D40366B735C + ED4CBA84995BA47D6AFE5DBAF84A79F9F4C9F285B7DC537EFEA3BF7EECF850DB + B30C1F6A5E752A5743EA41426DC7108E8734329BACF9E3584F3EE7A6BC0EFF30 + C965F28F344F99D367D178CCFC8DC004FF40804080A27D7317AEE21F47DD4F37 + C187BE6446C6253EF85D6D4F6AC516E183DF4D2974147CD4E6C4EF367C402FAE + C4875ABF0DF071980073A8F4C3A6579AF6F83914F9A06469E7247896BAD0BFC6 + 49A9CB62A41F0A13AB86496766269E7BB2DE4DF6A396DE8724DC75C69A12FC10 + CDECBBA70341A5064235A5E6239DE886B442FE8DA0A4C6C4507BFDB2163DA79D + 5F406D3A5EB53CAF163E3C1DD86F370CF343A98E752CB51ABBC687F4A26D55D0 + 9982E1BB111FA67A101FFA522DC207F7BDE9B177954B8FFE87E50B7B3796AD9B + 6E2F076D78FFE5CEDF69AB697FB653CE5C3A5F465FF97C79EA57FF55F9C93FF1 + 43E52FFDB93F5A2EA3C13C79BAA1D1CDE5F3CF3D5FFEF24FFFBDF2CCC5EDF2D6 + 1FFA23E54B8D2C7E0901668B107CCC7D7B8D80D3D06D16F4B110F0FC13A42005 + A7D1A18065EDB68ECA65EE60EE6F93E915A6BD4E381BCDEBC1CD5A9BE0AC2FAE + 7BF8EE36A3F741A73D6A23FD5A6DD141E773D4A72840E2DADEB778EFA19669AB + 4CE7A63A84A2ED3EABF8D6ECB0240B75F04EA85DEA9364B6B5F1FAE8BDD6C70A + 8D53D37F3284233C6D3582D368BB11C9C69372EEC2F972F0BBDE52FED78FFCBB + B6DEDD77021FC93FD49898632713F72EE31FF5016ADDEB38D69334937F2CE263 + C93FFCDD2CDD3A4A6FC23F3451F10C73A14F58D6AE1CE261AF26FFE072BC353E + 78DEC8EF55F8E09FF9C2C007C292E6CE6B810FDB3C6E7C0C6550F7AAE975147C + 1404A73367CEB4A63A886AB4D3512F3B9E85678788C595B6437346609EE033FD + A4D8F48C121BCA61A11D58B5A2915A99DBA806866D6963B650E251AF54F70E9D + 086A70F013218F9F4617684632BBB7E1EC356DF95797F8F0DE3CD928DCA4FF80 + 5129AAFCD7BD5CBC96BD392E7C2CF281ABF1A1B3A76635531558D479153E4C56 + 9AF8F0DEDAF7407CC078D4F21C173E169DC432CA3193D2496B17B2FE59CBF0B1 + D3F4FBFB7EECFDE5C3377C4FF9E6A9D797EB4E6F95137BDF68041ECAB19C2897 + 46A7CB41D929BB8D0034FED2C7CBCE531F29FFDDCFFCF5F2FDEFF99E326B36FA + C9E566F3BFFE54F9F8273E55FEE2DFF86FCAD99B1F2CB7BDFD7DE5EC01F3B0D7 + 0861971AC1E4522380751176F331962C33D2A2A6750EEF3434B3D6A7AAED636F + BA52D8C9C8BCEEFBE915F9A2B6A66AA47A5F3F9CD44B1701376A05AF719B76A1 + F4399A4C45D0FA20CD7AA7F03E196627001DE67A323DC1A817C446BD9044E6F1 + 1D9FEF0523B44B3B7D7DBEADBEC65D2B38F58937BBA8BEBD563375A2E9D68983 + 6EDCFBCDBB5FDEBB504E3C727FF917DFFC4A79F62BCF5D353EF401D41FD11C60 + AC0337C8CCD92436FC09960C8870A358C63F8C42D28F74C89773D96504D671F0 + 5BFB95A6B0217AFADEDA57C84A1296A4817FF099A6AC1C7F8BE201FE9135D686 + E895FCC3E8AE57937FD4F830C753E2230B2CD7E380B772A15D1BC247AD2132BF + 97F5FE8E828FE3E2B7AF163E0A82D39BDFFCE6B3CD22DA4D35DF32C7E9459752 + B19992014C4D845ADB60985FD6EE315336CF9A0555E7AF1A3029ACA899480266 + 74839BB6F5EC8C5CA8336D2F9AB49A1EE94CCC78AD65377472A9FB60248AAA56 + AE74BC339540FDFE3ABF44E601A94B07A8C9337A11609A386C9DF1DA0E0B82E7 + 8F0B1FD2CBDC5157830F6807B087E8B50C1FF5BB16E1836B5D7A2DC20797A7B7 + 217CD451286212BA273EDC244D9391E34D15F7EE6B6E290FFF819F28BF307AA8 + DC70CB99720327ACFD0B65B275A95CDA1937A2CFCDE5BA86EFDFB8FF6239FFD9 + 8F97EBBFFAF9F20FFFEB9F2ABFFBED6F2A972F5E28274FE3545ACAFFFD4F7FAE + FCE44FFF83F2963FF4A7CBD61DF79473175F29A3ADAED6DBF6C176EBBC3DBF7A + 01E98A7404B33E8A67367CCF681EB27F653997C37B4C2E398FB3EB925ACECD7B + 93FE8BDE645219A7910000AFBB49444154D80A40079D1378EBD88DA666DA959E + 994C5BA1C7E4956DD45C6FA6537032BA6EBB4F80390A077334499D49F05013B5 + 3535D7D3B495014FEF77799ED030E14375727F5A2E5EBA58BE79CB89F2ECEDD7 + 970F3FF1A9A5F870A3BAD6F8C8FC45CBF8476A7AC12EEFC95C3DEBF00F4DED43 + FCF66AF987B9A3EAF73B0EF987FE4EAE67F907CF1AF2BF887FA4B022ED9246C9 + 3FFC3EC77B9CFCE3A8F8C87C4A5C26D25C860F0379C447D235F1214FA6CDEF16 + 7C48AF217EBB081F60C148F935F1716EF4EE77BFFBEC37BFF9CD5D37637D8D74 + E2B5F3AAB8529A53B394252732B7C350A6F154E56588A4290A92E0B4A50DDF2C + 9FAA2E9D64DB4947AEB4C7E7249A99542932C7EB49C18977B3767CB9792B795B + 73AD76064CFB6AED70E6784D4297766755EF3ABC7B72CCACD849D734652548B3 + 7F80286B41497F4F0A9973C55C528ED1E7D5EA24BD78CE10D54DF0E12966537C + 48AF217C801DE674081F6A9E36C5474D874DF021AD131FA9CE5E171FBED77178 + 82CCD3D1103E5EFBBABBCAFD7FF03F29BF74FECE72D32DAF2F138488D185A6E1 + CBE5D4F48632C594D4080BD78F0FCAB73EF91BE5D6F3CF94FFF9EFFF5479F33D + B7950FFCCB9F2DFFFC5F7FB83CF1E56F94B3276F2D37BFF1B132BBE1F6F2F26C + D446DFF11FBE3C5BD345024FCF8C6787DAA459FFF7956638F03229B5016234B3 + 640918DE9B977649ADD6613EA84E33E44D6D5ACEF6EF4E5042903975D069913A + 6DD1B4CFD5B4DF17FFEDF22B8DFB5A776D045DD3A72EA5C1649E1473AB4F8A39 + EA4D863B075DC995790EA8E6F3EB2F96D694B8B7B5D7968FD9D9DB2F171A41F3 + CB0FDC5A7EF1FFFBF595F8380AFF487CC8ECF9CC808855FC23D7A9F84FCD8299 + F32D8F94EBC8E8DE2CF69D75ECF2F945FC23537464EDB655FC232D1A59B643DA + D5FCC364C1E91AC03D3A08B3CFE94366DF6BFE515B161C4B7E660A94BA24CEBA + FC43612B37F7A3E2C33268BEC7A002DEA18FF1227C24CDFD7C081F96D1B1BCDA + A6F8C882EF35BF3D2A3EB262C53AF8B01D9368AE838F361D01CEE1CDCDBB9901 + D4CE69EF440BA24DDC8E9A119ACF14B4D2E66B27AD243F2429A7D0A066C13078 + EB9B5981BADE60653A6A256CDF045F0A6FA9E5C98937CF838E745C2E7223B2CC + FFE4A4D007B5249995BB66845E09A2DC9C5D10FCAE094C405B63479AC9703C09 + 28E0A41094C26AAA5D731E52E0F31FAA5B737C001CD3F1D7E918A47F8D0F3161 + C570ABB11F073E04BEE3CA42CCE051276F5231489F4DF091D18B43F848E74AF1 + 914C5175EE51F1E1F893C12BD025866B7C5817D0C855EF933E62FBDE87DE54AE + 7FCF1F29BF3ABDB16CBDE6F672C3F474393DE17D2FB78634E48B93CD067FD378 + BFBCF4F94F94D9339F2A77DF7E5DF9AD17BE512E9F7953B9E78D8F969DEB5F5B + CEBD3C2993D989B2DD17F7452373404995D16162CB512BBBA4FF52CB7E0FB54D + ED9F87DF5BD7AE94837942CCCCF5A4C669368D5371E96BE4C5DF9D5F925A813E + 83799F7092FE60423B71D015FE9D62A4EC8BF66EF5A5575AFFA43692EFE0D02C + D726D1D451FCA0ED676B9E9BCCFAEFFB9407BDA0D50A606D1DBC5EA06AFA3C3D + D82BE7B7F6CBE5875F5FFE9F5FFBE055E1A35EB3890F7ED7C5428DB0F8904778 + 9F9B73F2BE75F8471E66D254439F311DC32FB9384425FF302F95FCC33594FCC3 + 882D7844CD3F3C20681EABF987FDDA847F182927FFE0330BF17ADF26FC230595 + E41FCE65BDBF584A89CB04D0F20F7825CF8B8FA1A83FF78DE4B1CBF0A140E09E + 213E1CDFA6F8A85D21AE161FBC5BE124831D121F2679356F9397755097E1832B + 0F2CEBE043ED9EF8607F49D377DFBF4E706A7ED9AD896F7E25FEE677CD226E38 + 74867FE6ADA94F52B57D54E94FB59813EBA4B27048CE66365B89C0E6647D354D + 464A8AB5609276FDFA84A7F624D3B1E7A9C0FC284C0EFDE3FD462A98869FCB9C + 4B59BF26D59B095E1DF4008DFD310BB8C56379A7B9931C2F9FC14C3C2164A654 + C79BDA928CA4710E2C7EC842499F9E8C5E549B047D8D9CB0DF3264AB550FE143 + 876BB5829BE24340E6E960081F9E6C48CE063E125BF8C265646146E1A59F570A + 2A625A7CB8F158E6A53E69AE8B0FEE33395C9A443471D6F8C82CF4890FF35831 + 77063F38F78C1786443F96E183F7BCF9B17796BD77FD58F9D864B79C3A71A634 + A253695A6DA3D3668D303425126DB65F6E181F9497BEF2C572EAE062B9F1BEFB + CB0BA76F2DB3BD46289B8C5A1FEF93A3711B2986A075A21114A8B97630AA849D + 6946CC952EE75327CFCC05A7D20BA987E9080E05A7D43C8DE61AA7FDD2FF3AF7 + 8DFAB60CE5F3F7F6B998FA97A22942706AA3DB5A3FA4D246CA6DE9D4DD3B7A97 + 2B6ADB4DDAE8C14EB0EA04A3F6B336326FDAA75498F4457E2773E18971ED8F27 + E5BAFDE6DF2B97CB4B07AF949DEF7D53F93F7EE15F96491F04F26AE2C302D90A + 156AB2935FD6FCA3D64299F49183425DFB32F9076B3EF995FDD674939149B9D9 + 66E246DFA796CC354F7F4CE69BC284878475F987BC10FE811F69161186FFC983 + AD8091C997937FA480A006C9838FDA13E664D1FEC2BC200840572EE66A5DFE91 + 82598D8FCC63C44FE8EA213CF121BFB41F624A7CE4E1332D1843F8B098FA51F1 + 61DEC0C4476AD1C4872646530B6D828FDA0271147C5826ACC2C761C9953C852B + 89719365254C2A6547D23C966A38079F4CC041B8F198C82A4FFB5E74DC0D8DCF + 95D0FDDB369D602756623B715E121361853C26D4E34949DBF1F2D392040082F7 + 7AEAA86DC00A066A8072BCD04B3F034F54B463491419878C924D300B31224C69 + 024B55A2CC2E178E1A074F082E621D8AA1F7E73EF7B96F33C5995F084070D157 + EB3AA5392B998727A7C40763CD140957830FDAD0572CF121ADBC48C3908C6308 + 1FF63305DB3CADD5F8E06233A26DF0615B6912E03933CE1E073ECC3963723AF1 + 51FB19D4F820FA92F7E7F886F0D1329386468F3CF6AEF2F2833F543EBDFD8632 + DBBDBDDC3439DBE632DA9B92DFA99B1F4C5CA7B6B75A6DCB749F4CF0E34ECED9 + 1A97AE9EDD41FB6F7BDA30941198DC4624999BE30EF3381D0A34D66D9B3B8D4F + BBCFC7BD4E68D426DF3C988B5AAD00540950A575029FCD531ECC85AFBC6F369A + FB3C8DBDA7942EC540297373DEA8AF2DB7A520A4E0D43A7BF759C27BA7F0EDA9 + E63D7D9CB8A74BB4D9A63468531FECCF935D72ED6F37CF5C6C0E19AF5C2C3B6F + BAB3FCDC131F2BDF3AFBE24A7CD411A6AC13F0C11C5B6414AC6762C44C49003E + DC385833F00FFD19E51FB979887F058E747C75ADCAABC1FB534F3DB5907F983B + 4EFE91A6400F28A9A94E9F19D791072C35131EDC6A578CDACFC431198DCDF7FA + B6B8566AFEC1E7EC2FF20F3E97EFD5FCB65E5FB9BF2828E46190B50C3F4DFEE1 + 7DD25D4504FC5D578C4DF0C1E56174153E148A1C2FD73AF8700EFC6C081F4672 + 221C7FE10B5FB8C2C496F8E0DDE2467EE97CA642C3FD78193E0C1CDB141F6906 + 3D0A3EB22E62E0A3D33835CFECBAD9BA002DF70118E8B495DBD58ED4C902D3D9 + 8A977A823022CB227DD6E9C9A46112D1A4840C54A994F7B9290B6841A13AD768 + 40C3FC5363E5A2C844842E064BA158230F40593CD80D5C60E944A684AE20A093 + B7D237F7B240F437D0B95A156C6A3EAC85940E7DF44F6120EB18F15EA56C2575 + C79E6A7FA5FE04A5FE4C19CD67CD25688CA6CF8594A7977446141F2E40BE835E + E083FE9AD073193E6A7A79C2A40F9AF4F89DD390D17BE9D7447FC5875A315332 + A43DDBFE1F373EE81B8B8FC814E773537C58674C15738D8FB4C1D7F8B08E973E + 2759276F113E90661E7EF45DE595C7FF70F9D8E474B9F3E48DADC96B7FDC8917 + 2DC3465F33EBC49AEB9AF66EBE7C500E9A9B268D84321D37F82A8D0048A2491E + 2401E6C1A946D0E8FDEAE6024C965CD1D7E8CA68BBB13255084E8A3DAD4FD2B4 + 44F6F1109C8AC25757C32E4D80E33E2D42A7E1323D409917D9ED5ED999D7BAF2 + 2BB3D60749C7701A1B1F1CCC35495DF1DED225109D74EFDFEEF33EB57E5C6D36 + 70125C9AF6A069930497B3FD72E9E573E58E87CF949FFFAD5F2F5FFDFA0B83F8 + 487F17235EB98C2AB68EA7F72A686BF25A850F7EEA73B20A1F595F54FE21BFC8 + 03C632FEC11A847FB8F925FFD061BD5E4FF20FEB496205B08C89D9CBE517A9ED + C8F5647E3623B25C4FD6A8CBA2F41E0279BFEBD368DD45FC435F31F34059CF32 + 036C92E73AA7A975A9C72BFFA08C4B3AB6D386F4727E16E1C33A9EF23305EDE3 + C2476AB21CFB3AF8B08667E283F15B885E61B2C687F3B3885E1CA611F6AC0B7B + 547C582FD5DAB249AF65F8E07D5881F2E030D738E1E32443171486B05B4F0E60 + A7AD939798C53A254D88A7C486B446C7951CAD81834ACC6CCD4E6C3A9FA962F6 + 34E3C40B6E07A8740A11B2D4059A25DA5070AB1D8055F559B15A422B9DF23DC2 + 93B660DEADBAD17EA44DD4B64DFFAE96CECCD58C373395D692766A77529B22D3 + B58480E03305BFCF21FD33FEAC51E738ED277360A23C853B810B38605E9AA054 + 939A5A5F608B0F4F03DAAD1D7BDAFE55B3263E4CC590F810CC0A4D578B0FDA36 + 7BF071E2C3FA573AA4EB7B97F8B0865E9E6416E143D53EEF87918A0F4F758BF0 + 91BE57B921A559A1C607C9FBEE7BEB63E5B937BCAB7CE6D25DCD1ABDA9F3F119 + 530CB89997564BD3160669CBB29C9C748ECFB3AE105B77DA1AB5CA9D321BF78E + E1BDA66714A6B8B90F53AB18B2C8AD024EDCDBD6A7EB9CC3E702502F54957422 + 1F4D0EB55ABD70654A83AE4D22EDC6F19E69FBDE719F865CC7F42927F662AEA7 + 499BAE60AB8FA26BDF373D983B821311475996B6C44C2F5C6DF5655A3A536123 + 74F3CFB22D981CF7F75A21F0D6B79E291FFCD487CBB79A79D6F74E7C70C0B0C4 + 43E2838DC1830E3C36F1A1C92537DA65F8A87D9BDC1C57E1034DABA5396A4760 + FB097F34C45EE14EFEC17308F30A6696B1B0CE9CFDE019F9076D19C1CAD8591B + E9E49C91B7C93F3CDCCB3FDCA76C9FDFE11F3C37C43F525058B4BFC8B7E51FB4 + 95FE396660D77454BF43415377079DD39D178B8EAF8B0F79F0103E782F07B945 + F8482D4CEDDBB4081FF6438D0D5A18DE9D350C57E143E5C1B5C4879195890FD3 + 29880FF729FBC4EFACA7C447D22705E71A1FEEC7CD3BBA5A75CD0B7765E46997 + 35D4904E5A0B878EA6336186DBEBC4CA466E3A024F1D16F6A3AD679E79A67DCE + DA4BAA22EBC82FFFB62FFEB3DE99B656F392A85EBDFBEEBBE766AF34CBD4C066 + A2D299CD9F0A180A4A19099684D63ECA78D592A8CDA06D365327D0F6BCD4C42C + 0A977422F9A72332977D73E2F99EF1024C4327D3C15360D386269EDA8CE5290D + 9AA5892CFD112C7A99F890A930A7E6E0E05F3AE7273ED4AAC1246A7C58D8937F + 143DE539857669911B44E223A339D6C107057A151617E1C32AE6BE3355C83208 + 6B14A67F4A5EE2ACC6874222F8A0BF9C8CA0436AB16A35FE227C28042FC207DF + 5320137ADCFF96C7CA17DFF667CB172F8ECB1D277BE7EB5E80EAB444CD1CA1E6 + DF1A7761F9D3D20A196D491392514E773AFDCFB8697B74E89FA4C0D38B44BD39 + 2D72A8956F77EEEE9CC327738DD37836EDA3EFCAA1C9AECFF534CFF3349BCEB5 + 528782535F5CB54CE7ED1E9AE99ADBC75D34E0D8C49838891F74D9C1F571EA92 + 619A00B3ABCBD7095A5D6E27CBB9B4EF9C761176A427E0BE83CB7B6D3A8337BC + E50DE55F7DFC57CA8BE7CECE3519F28F217CC82FD5EA5B173205136B71B2B633 + BDCBD5E223D739ED5080151E95C5D05D0F9A7D58976A3F6AAD0B58B6FF8BF887 + FC36D3D6780832492DE3E3F9BAEE9BF4F200085DBCD78DD3C2AF8CF5D9679FFD + 36FE91FC360F4A35FFE0A7F5F0F8DE740FB4A5390BFEC1DF5A186AC1C9485FC7 + 9BFC439790ABC1874A083EA77D0E80D263193E14AA121FA9E55F840FF8077B69 + 1643AFF101CFCD42C0CA08890FE72BF9B9FB931AABABC5077457E84E7C584899 + BEA001A37DC79C66C675F0D1B4D3094E640EA74137569DAE24A40EC0FC637080 + AACE29A1D448C7EFBFFFFEB9F946672CEF558B95A609DEA799C301A8FD516049 + 2740CAAB68CA31D782159C735127117263346ACC8803CD284AA65CF6C7A29799 + 13C24D5B6DC9030F3CD04AFDF483E73C5DB871F379869FF29CC90DD3B93DFF16 + 18FCCD0947C0D11E12B34E81464248A79A91BA90AD69A436C55A689EBC1C9F4E + 78B988E98F0EEDF6D3ECDB46CFACC207972550C0078C1A9A5B37CBEB5AE083B1 + D2A6D9977381D4F890C1263E54930FE1C33C5975CE10FD991C2F73065D78CE32 + 099AF036C547FA5F316E3406890F4EDC0ABB890F12643EFCBD3F500EDEF4CEF2 + CCB9D3657CDD9932DDD92D076850B679DFC5E65DD8F24FB4FE4EDB7D8EA3CE24 + B7D5AA9CD0DEB482C6ACCFAE342B57689E46BDB6A775FCAEA2E534E775CF99C7 + 49CDD5B44F6B708897560BD4B655BD636664DE74EE4B352AB32B92671EDEDBBD + 679EBE4073DEAC2BC88BE07472BAD7978499B6D1716DE4DDA44BC059DACFF6DA + 8CE965B6D399F1A65D66F457F65F2C276F1897330FBEAE7CE05FFF5CB978F9D2 + 15FE24CBF021AEC4077366198FC487A936121FAC5F4FF3B635840F4FE8353E30 + AD6996171F754A93E41FE90F299F5FC43F2C329E029C9A669DA9E51FFCCC7A6A + FC641F327D41BD816976815E5804B84FFE216FAF4D9B6AB735B5A500A5C9A80E + BF47439BFC83BD0C21675DFEA19B898758C3D96BFE617F74D4AEF1A1833EE365 + CE121FA9C9828FD6C134353EEAC874F1C14F344AF25BDE09AF4AFEE19C2DC287 + 85CA9D27DA64BCA68070BCFC4EDFD6C18742BCF85023C8D8B57E0DE183EF1B99 + E60A7CC8C7E92B7390A63AF1C1F88D6CB46F43F8E0F3061F87E9085419DB716B + DBF0122470B38F9AB721B54EB9A0742CF4D42B01DCBC01B56DE5258135ED6444 + 5C6A17208ECE843C8314E922CC1C1BB593B34285EDE8292F210D9D376AC54CA8 + 0A55B576C80D4EA76626020D1A93AA00673420971A80A497204EE7BBD4DE29C8 + F0D331D26F55D499DB63487B95E0361BB539B104A04ECF8C93F1F393D3456AD8 + F8273E1466A09D6A7F4F7AE0C29FF56947B527ED7A82B0786F46611C073E7456 + F75D9648B85A7CA821A57F890F186B3282217CA8EEA72FE6475383C7EFC78D0F + FDA1BC0E99FDB83CF0C8C3E5CEEFFBF1F2CBE777CBECA6BBCA78E76439D1481D + E3BD97DBE8B1519B8DBBD3BC749A9CE817789A8E5A535D4BB34A70EA475FAC55 + 37CEFBE6E31BB5DA9D6C77AC1378A5951A87B9EFDB0427A203FB2499DDBBD23F + CA7B7B8D5231D7545722A595E3A65D21E09316F06D6EDB9E94489039EBC77AB9 + 1122F75AEDD6167D9F1C94BDCB0D266E6E307DE3A4FCD22FFFC27CC3CE4DC05C + 67FAA45D41A15E704A7CF0FC103E4C0B929A64AFF4ADC98D5CAD2F38E01AC247 + 6E3ECBF8871A74C3C8C1BB028E1A05857DC664887FF20FF6845AFBACD6163E49 + 1BF00D78C9B2F594FCC3E2ACF20FDA311923EBBF1E83EB8CFBEB9C49198D6CF4 + 9991D8F28F8CDE5EC63FF869A49EFCC39F7C5FE3439FD645F8A00F35FFE032D2 + 5BBF2231E05816F18F1A1F7C671013B4D59F795D7CA821E59E55F8E0676AFA97 + E1C3395E071FF5FEA2B6097A29FCF0AC3C9BF9CD795351B1263ECE8DEEBEFBEE + 361D0193A37A13E0E9B96F2A02FD38E888CE6529F1296C41B8748E668200316D + 78FAB7FC470250C9950ACDBCC368A33C712B11F3CF139827767D62540FA6D626 + 89AB1F8091052E76FD66D47068C2A22FF4BF9E24FAE6A2E779CD50B4E778AD40 + AEC77F02DA139ECEF76E72F542345F913402A068B75268CA055B2F3E4F81D6B6 + 5338CABA46F6877B109A98FB3AD20330F28CF8302CDFC5A260CC78D558253E68 + DF6CDFFA47243E2C9DB30C1FBC0B7CE88F21434813AF366D3714DB4CD3E626F8 + 50639A4EEFA9E2A62F9BE083CF1CAFA51C16E1832B13B6263E7C9F3E85D28876 + 396DADC2C72DAFBDB33CFC1FFC44F9D549B3096DDD526E38754B23389D680591 + E9D65EA77D19A9192231E4AC8F9C9BB6956B159CDABE94BAC8EFA1E034D7287D + 5BAEA72BFD97F8BD15CA42EB34EBEBD9CD1DCCE7F74AE8CED4969FD5C2D39549 + 323BFFA8712B38CDFA28BDE684DE3A79770584DBACE0E4AB825EAD4339EDED77 + 4EE1DCCE3C4C2E959B5E53CA975FF87CF9F4939F9AA70B601EE45962087C5877 + 332FEEB548B7E1D1FA0C8A0F70919504D6C547BE6B081FF00F37FD75F807FD32 + 8F8E4EE5AE3B0F897CC6BBC09E115EB6E1E6EF414B676EFDB1AC4BA989BD167A + 927FE80729BDA10BF4E5DDF441CD4E3AA6A7A501FE213F18E21FF4CD44957CAF + E09B26C8D43ED4FDD4D15B1E6BC45F66E3E6397D7F17E1C34839E6577F4D0349 + B89F3DB6AE3491E35070E5790FFE43F8A09DF487853FA3714AFFB0E4C1B5AB8A + 3C9776C44746C5ABED31E4FF38F0C11C0FF15B9E0107E9CBCB4FE8057E3D501F + 151F5C7D79964E706A08BFABBF0F2F72A3A011FE5693C0F74ABD438B4C55A903 + B658A08E617CCEB37634EDB00A5F6F7CE31B5B1B35F765D48203340CD3480673 + 2BA8814A53D722B5B3C25D26FC8250A86801A25A14EEE5EFDAB6DBB2FDFE1DFA + C1A8EE4378001CB4CF95B4CAFE99CF0933DF673EF3992B12DFE544D28E55CDF5 + D3B1DDCC6995596FE79B462FB93307D24366C3850A5FEDA1F40064E6DBB0AF3A + 3AD6F8C084689486F860615B64B9C687AA5AC37B798FF8F034E9A94C21457C18 + D5F0D0430FB53E509A0A131F9E88E98B21A72E003550A99D4B8DA9F8309A83B9 + 49353558061F0AF5E6A0390A3ED8B8785E3B7B8D0F1D48C1206AFA279F7CF28A + C3C3327C48074F90CBF071B2A1D563BFEFC7CA176F7F5B79FAE0D6524EDD554E + 6E354C7DF2526B929B585B6ED4A524D8E99346A2879ACDC683E6339DB43BE7EF + 2BB38B8FA7A975E9B549DAE1E2BBC3670EA3EAE6C25739D470CDDAFFF6DA4F5A + C16DD4F9515D99A1DC9A78A3AE761D742E9DE669D6E77EEA8AF5762556B66687 + 8213FE4CB336E2AE2BE732D9BB5C6E3C3D2E77BDEE54F9CD4FFE7AF9F297BF34 + C70D58031FAE1F73A3B91E16E123FD3AE497EBE2837BEFBDF7DE6FC3873F3352 + 59F3879FAF830FF90798759D65B41C261EF98707336BBAA5B3B1812919F1CAE7 + 19A4A17FAD856517ED2FB5B9CBA492BC8367D40A0FF10FE800BF7DFAE9A7E761 + FC3966EE5130937F6862827FE4417ED1FE22FF304F517EEEA12FF1C1589D8B1A + 1F46A4CB3BE597E0839F5A8416E18379C3FF157CA45095F8A01F6A6AC407EDAA + B858860F2ECD745E192DA752402DBDC9B497E123CD889A98A1BD390357E1435E + 98FC160DABEE33CBF001B6E0B7A458C83EA655A7DF1B3AC1A9E9F4AE5156AA29 + 3D014930265E4DC150C7534D98B673BDE5D550A832D65137015327B674634BAF + 76274021800560865205365598E67EC83ED23F263A735728A4A58A0EC2A9614B + 09B99E2C4F0FFA10580AC1F169BB4ED3668E5F0D579E58B97C4EC77085153E03 + EC264FE3194FBCAA94EB3E429F8CB0D389DCF7C9B479570DEC00CB1C1F005981 + 4A0D0CDFA90A4D8D55D2DE939A21A9E6DF30BCD61C25990BAAC6877858850FFB + 4FBB353EDCAC864E2E7CCE824F9F29E96A6E33DBE53EFD9686AE217C98917615 + 3E3217D6327C88852C9F53E3C3341143F840DA78E7EF795F296FFDA1F2AF5EBA + A19C3A71AA9C39B95D2E4D1A468D3032DE6E858C3697535FD4B6B4CCE44A539D + CEE1E3BEC82F690BBAEF4787825044DECD7A539D492DE7DDB9023457A62340A0 + 693F9EDFC76F93F973E3D665A94A83506687E55F4AEF443E9B1EFA55F1739ED7 + 69DA66026F73354DFBC2BD0400363FA7975F2AB7DCD4E0F6F20BE50B4F3D39AF + A270DCF8009BE2C0C083ABC54786FA1BA55BE3C34D6D887F308E747C86AF6A86 + 4E1F227197EB2FD39EACE21FE63533D7CE10FF50BB25FFC802E6E643ABF987FB + 521D7C94FCC34312F4D75CA3A0C73E90FCC3E8E2214DB3662737DCC48707472E + F1A11FCE227CB82FB99FD23FFBBF293E9CAF217C18B2AFD94D617F193E1CAFFB + CB227C28842EC20778D4299DCF799E4B815F7CE9EAB3093EB4406404E851F091 + FB4BD356978EA0B9A1D5382970A8598090AA0B9172F9B9AA8271DA03954EB5E9 + BAB93B38AEDA57AA8E02D0E938D3D6AB2EB6A2B24CA10D9BEE9DF716D98E0556 + 469929801925A53D559F9B34177A25D1D39F87CF0512BF6B4BCD1C20F54987CB + FC1182BD65FEE3F15C78D3B4A3E6C545E33BA10566B67A5E74D856952D2D7578 + D779D10CDCFC4C4749FBB10A1FA87719B7398F165D9BE02385CB4DF1C198F403 + D3842A3E14EE87F0E1E9AAC68799BACD3F033E2C0950D3EBA8F8C89C5CF5B50A + 1FCEAFC2A83E68EBE003FA9FB9EF81F2C00FFC68F9F08553E5C22B3BE5D4F5BB + E5E0E4F5656FD6B439EBCC5B5BFA0B8DCA15A63A1360B673D2FE9FDC46BD7F95 + 82533887D3FB696F02D4C17C1CA6366F6F43FD53E334EBFCA0B6E6F7748E4957 + 6898A6573A999B71BCF465583AE169D227D5346D41E773D5094E93B618F076AF + 6DDADFBB5C4E8F2F963B6E3C284F7EEA63E5E92F7C6E8E0F831A86F0C186A8E9 + 3AFD63121F993A60081F7C2E3E348B6F8A0F85374D15A93532249D7F8CC5140A + 43F8D07498FC43415D4B02E355F39FE3557352F30F68E68688733C1A2853252C + E21DDD145FE95BE4D8E41FF2B4217EBB8C7FF037FCC33A69D25C13BBF7CB9FE0 + 1FB5E0C4654A830CA63177A11177EBE22379A082D826F848F7831A1FFA23830F + 535F70AF254C56E1C3FE888F74385F171F0A28EE2FCEADFBCBA6F870AF1EC287 + 4A9F217CD4184B7CA8FDE3EFDEBFAE139C9A06762D6BC100559D39288407D45D + A8664DE53FB478B3D32E3299BB8292929F7921BCCF894CA9CF01AA7E7312DCFC + F499A11D09A2398F7FB549D136E983A702BDEE694770B229D21E4C07602E6256 + 29FCA4942A53554AF5D4A1DA37A360D2218E8BE74C44A67F929BBE4222B493D9 + 0230CD82AA9FEBFE796A327AC5680DDF89B39E270205978CEA4B1B357431545F + E67C147CA875D27FAAC6877E4CCBF021C38066D2CBD306EF801E265C3534D948 + 47B59F890F4F2CE2830BFA2EC28742CB907FC8227C181E2E3E6492E223C36233 + C223F16194EA327CC898C4878E8F43F850DD3E6D7EBFFF2D8F961B1EFF91F291 + AF354CF3BA5BCAEC74839B5143F749B3B98C266D0EA38E6B8EE75A1F4BAE5CE1 + E3D4A62B38740EEFBDB1BBE8B6A25074283865599543CEAC99ED4AC1E98A08BE + D141FF77DF9B6908527DC160476C91DEC33A7ABDE669B4D547D91DF4057DF7CA + C1DEC5E65477A9DC71F3C9323BFF54F9C8AFFD9BF9A669CD4419BCEB417A627A + 067306260CE1A38E0812DFF20FB5F6326FC3D1D7C587781EC2079B97EB887768 + 26CBA48C35FFB014564603BA1E704D5073A07F52F20F4FFEA63DC9D0734D44D0 + 0CFEC13AB504C82AFE51EF2FCE8D5A2D93446ECA3FDC2CF5A952CB21FF601C6A + C787F8C72A7C207069763397D12A7C24FF382E7CA801334D8E56267326B9BF18 + E4544786263E10E6CC81283E7CAF3EB9CCB9825E9DAEC23C5043F8D06FD6B42E + B5B265D5FE027675104FF963537CE8BF364F80D9FCD26A9C12086EDE26E9B3B3 + 489D9E6CF35240505DCC22A44D98369DD4DF441F287D3F20B6044F2734EE67C0 + 9EEE7D5F0A23FCD4174927DEDCE4EBB056FBA9BAD1B614C894C0B9DCFC59D043 + B65DFBEA49C58590E907740CB43F9E6EF83CC7AB633DC0305C53E0AABD5178B3 + B0AE35F0CC73413F005886B5667E0ADBA833BCC3ACDC10F85CF3550A4D6AAD12 + 1F6EDEE243F021842DC387EA5BF1E1623A0A3EA097E1DAB9D0D52C71D5F8F004 + B90E3EA44BE243B38574DE141F0A36F45F07761D6B4DAEB90A1F6E7CE243E629 + 3E3C9569BEA3CF32A055F8D8DEDE29B7BFFEF5E5C1EFFDE172E1350F96CF5C3C + 5D5E999D2E274EDFD425C44423532E96EDD6017CDC27BB24747FDC47BA19F67F + 7085666A365343A489AF2B90ABC0330EE7F22B9CC3C3A17CD417273E8CA2EB43 + E14ABC673AA9EADE8D7AADD7B47BBED52C7535EDDA6499A36673196DB79AA6F1 + 043FA657CA6CEF42B9FDFA9D72D3E85C79F2A3BF529E7FEED995FC437E696E1D + 4FEBBA0B2CC2875A27FD3198B3C407DFD7FCA38EA0D21463799E0CF74E7C981C + 76113E86C2BC131FE97FE278E11FAE391DB5D30FCF43AE42931B9EFCC304B19A + 4A4C9ABC8C7FB8FED574482FA3D432CACBE8BD21FE810F4DCD6F35D97930857F + A845977F78F0ACE9B50E3E982305B37417A885EB217CB03799DA408B43EE2FF2 + 8FC487F3B02E3E8C52F780ADAB03F730B743F8905643F8D04F49DAAEC2876E0C + 57830FF7174D80578B8F3C68F487DDC304983EA0E35E2E4A169BA716F35BD412 + 9F93ECE236DD3A037582F576377B34C481B1681EAA9394394006EE60940A8D30 + 90D9F01E254BCB1B98CD3A1DE2B8EA02804ABF5980D7740C466F2D72769641C2 + 40F8493FEC9F1127D0C1F21A089EAA7D7D5EB01889A323A2A036FD3FE3C50195 + 8B0D1B67439FD3493923001CB3EFC8CF1CAF59D80DFF34FF4CDE9BB58172A1A8 + 963D0A3E78868589A065CE10134B263E18A73E68E2C3B615B054FF660A7FC3C3 + 6536CC8B75BD4C3D919ABB75F1A159515536ED2CC2875981799645E8C237478B + 8C58BF384375D51C7A1AB31F6A5F131FD2457C90C38A36B907D5B6F8808626F1 + AB2F05EA1A1FA7AFBFA1BCE7BD3F5CCEDFF9B6F2E4DECDE5DC89DBCBFE4E731A + 1C9F2D2727CD26B875AA915B9A7BA7A3B6F449A75D1AB7BE48E3E95E2BE1B44E + E618FAC6A54D44396DFF95B68C094583E7090AA69D516E4B3AB6FDBC32FB7869 + FD905228EACC6EF85B8DE79E4F578EAF65A8BDA96E3C9AF60EE9B3B6FDF6744A + DF986B125C5E3A5BDE70DDB4DC75E2A5F2F4A73F563EFDC4278F8C0F37B675F0 + C105FFA03F6823C4845A14F98785C1D51C8A8FCCDF63246FE2C3CD04FE40B2CB + 4DF1E11887F807EB583E66A9AE9A7F6415849A7F68E9604C6ABD96F10F7D57D8 + 50359725FF700ED4B6F1BD025BF20F798466D545FC833D853EB34FC93FD4D2A4 + 66665D7C683672C3D6B773113E3CE8880F7336A9F55283BE2E3E927F6801497C + 90EC92BE81077896D6239E318BF7BAFC230393D4E0A94C484DDAB5C007728135 + F2D4A4198D6FA674F1A14220F7632EDD81C487F3DABCEBD0C74900D499456DC0 + 459876C47A839688961B611360E372F2CCA8ABD944EFFF9A08E910667D321280 + B1D0AD6387D0C0446B42D15B1E6031D8AC455333D2D428E4A9CA45E3C2502B53 + DBD41DAF52B06A68C68B60435F54899A024020E5C4A48A5689D7B4102C00C65B + 17844D0D8AB9A3EA1C23F59C184D28305CC8FA3CE854A963AB7DCBBC4DC7850F + 991CE318C287F94A8E8A0FB535FCAEEF0FEF4E7C68DE75B11C051F063B0C8D75 + 113E109AC0ED227CE8839059846B95BDD134D08E319A23467C58EA26F1218687 + F0E17817E183EBB63B5E575EF7967797C9DD8F952F5DDE292F6CDF5CCAA9DD72 + 72DC08CE14BC6D1DA8BB70FD512BC44CDA2CDDE1C5DD966B29F33195B9E9AE14 + 1DBB3B6D52D6AA9B55CEE1ADA3B79175ADAF13A6C34B6DE3B3D13C3F7939B4D4 + 35639BECB7DAA469EFE28E596E86E99138399C3E2F5D2837ED9F2D77DCB8535E + 333E5F9EFEAD5F2B5FFCFC67AF0A1FF00D6B63AD8B0F0F9908BECC297FEB8BB4 + 0C1FCED5103E4CED62243258D087C743D251F1E13A1CE21F8E6D19FF483ACA3F + 92D64307C0E41FE01C1E8960933EAF8BF8476AFDF457312A8FBFF1D1845E6A6B + 101AA05D9AB9798F891DB316DE327C78CF227C0C8DB5C607EF335F9C91DF890F + C6CB25EF5B860F040AC6415B46F9C19B4C2790F860CC1EE2D6C18702E126F8C8 + 20A4217CA8EDDF141FA6D641E054D3A486D5E4DEEEC743FB8BF830A2147C40FB + 7E2D1ED6AA4BA939374D3FD3B33C1BF7BBAC21C3C50B1414ECA0B67FA5EBF4F8 + F77D0E40C0F01D0051A3A134AA5F4D4E4086742A1064D868127A0808992B2893 + 25A6D92A3DF7956EB997F1AAEED3414FC73DCD878E27DF99428840D1BCE97814 + A88C729081EAA0EF242793CACD2F176EE6AD4855693A21E6BCE7FDC7850FFE86 + 5E9A33D2AC71B5F8704E121FAA708F828FF40DA8F161BB9BE0431AAB22365A72 + 081FD97EF60B6C68361DC2870C34F191CCE56AF071FA861BCB9B1F7F57B9F4C8 + EF2F4F5EBEB95CBED430D5ED9DB2B37DA26C353FA7AD31AEAB7167DE234BAD20 + 4C91CAA0138CBAF22E2157753E5275BEA62AD7532B6DCD4BAE8C5A07EEF1E452 + 2B894D657E33B45BDED1DC73D0D061BAD70A4B5B2D461BFACFFA6CE4CDDFF7ED + 9672E38B9F294FFCE66F94E79E7DE68A0345E223379F1A1F35BD927FD49B4C8D + 0FDEC506A6493EFDA8D6C547AEFD1A1F8E21F1A1503D848F5C7BEBE243D34946 + 725D4BFE817099E62E696611DCD4B2D7FCC3DFD5E8C03FD864F5B755AB90FE8F + 199E2FFF704E6AA12CE738FD8C36C1877B81074AF1913C5A47E74DF0E1FEA2DF + 967E3F5CFEAD90A8B563081FD9EE772B3EF4C74B8C181979547C68896AF33821 + 3835EFDF2D4BAE7AD3525D9915EC339AC722846E5849A45A25999B4EDAD3052C + 0355F59A3656079E15B6750C14486CA856EFCE6456438EBC79E5A66DFD3DAE94 + AAD3966A3D23DAF6A45A0B1F8B689934519D6A4E2D1D2D9D7C2EC6C444E29099 + B4332F8AE6C25C40ABAE3A02CCA4654365538E031F48FE2E5A059C5ADDBD0C1F + FE6D9B6A95D8683CE5C974003EF8E0F4A150253EF449131F292CAFA2975AAF8C + 8ECA53F9103E5457E75817E12337EA217CF0BBE1D059068231F13DE3ADF10103 + D61C74547CB4513D77DE55DEF0F05BCB893BEF2F67B71B2CCE4E970BB39365EF + C40D657CEABA5EB3336AFD88BA2492B33677D256E99CB547AD36EACA9A72659E + 817C364F28DEFA49954851303D4C79A0D26A8ADD6FD4E999269D5C55B6C6877D + 2DD3FDB2433B9346786A04BDEBB6F6CB6DA74AB96EFF5B65EFECD7CAB39F7FA2 + D548E9E09CF8D00D80881E99FFB5C087FE7CDC9B011E47C187FE2E8BF0C198F8 + BEC6077D73C3E10073147CD8075D148ECA3FAC0CE05AB18F6A1EE41F0A349BF0 + 8F3C3424FFE0D2F138376368C59A121FC97BD076F13CDA8821BF9B75F1A1E96A + D1FE52E3C3CDFEA8FCC3740ABAC82884721FBC129EC87E5AF30F0F80A60BD804 + 1FB9FF6E828F3CACAC8B0F8BC66F820FAE5AE3BE041FEB094E4A7B4614988D96 + 0596CE89E9B9AE64574F70AD624BA95D9392926E862C66249ADFA9C604D84686 + 091CEEB10F7561C155976332D4DE081204928C04F0E4914E71DA9673D2878090 + 60765C2948B9892BB4096E05272315927E966AC83A67EB8E573AE910679E9255 + 97E3101F861D7FB7E0C3E2C16C1459B74D7F3E2E4FFBEB30F91A1F304FA33E15 + 58D351F2A8F8C853E3103EEACCEFD2DFF24866874EFAC9B0AE061F08E7FAAAC1 + 786FB9FDB5E5FEB73D5EA6773C505EBEEE8EF295C975E5A5464E3918EF9413DB + 273AD3D801F462631D5375B78C1A896A7B76B96C4DD1168DE7C58267B3E91525 + 5C66252ABBCFBA1229AD9F935ADA46403A18350CF960D2A61220380E61ADB482 + C27E991CECB7D6C153CDE7B76C5D2AB74CBF51462F7DB5BCF0F467CA335FF85C + F3FDC15C6379DCF8E07973F5880F78944CFC3B850F0B9D5E0B7CE850AB362DCB + 5A2CBA6AFE61E667037386D6D3901FD5D5F08FA4ABFCC30398662C0F5E890F05 + 9EABE11FF84D19B5253E4A391446AF253E348325FD11AC5913088A43F8E0397D + A336C10717EBEB28F8484D1B73E17E6C3A88EF003E560B4E4AEA86505BE0D190 + 4F25E4A162784E604EC050FB765C5B69122C4D59F5EF3A9D9BE04F0FFA9418B9 + 0C51B73FCB2E8515EB91D12755C02CE40CA354924E0740AEAC1CBE0808E9BC97 + 5AB0341DD5FE46F64DC1869F3A820A2E17B58B669DF102C4CC0ECE788DD25BF5 + BC603244D6028F8BF091D95A1D6F263E5D860FE97535F8D0D1EF6AF0E1A9DE6C + C56625CF6AE9C7810F19DC3AF890211895789CF8D051594D9726D5C4C768BC55 + 5E77E6EE72F7236F2F07D7DF5626A776CBA59D1BCAF909C934C7E5E529BE4527 + CA78A7D99C1B61691B47ED51979EA02DB5D27A921F964529293899647372988B + 09E109C3DF848497230AF1360C6F72A98C0FF6CAF5DB9372E3C951B9BE3407A9 + 8BE7CBE8D2D9F2952F3C599EFFE253E520229DA491A1DD06661C073EA09921D9 + 9BE0C3F75E0B7CB851CA3F9CC334D55F2D3E8CCC35CDC03ACF6B555080A8F987 + 9B629AB08ECA3FD2076719FF68E1D66B1C8E1B1FF25ADAE36F73397D37E0C30A + 1F0A6E43F8A8DD17568DB72F53D2CE317492869BE0C3FDE5BB041FEB094E1253 + 130C8D6362C90ACA32EBB4F12EEA687DA55D5730E66690135EB7A10686539255 + C4F35EDA34CC7D5D539D3976389D692BD5E4685E1401AD66C8FEA7BDB4F69D11 + D80A10A919A96DE40AACD93EEFD6464D1F90B8CD089B7E5BBE6711BDEBFEB080 + 4D6BA0A9D190D4BA14C0EF147C08F44DF1B1CE094A7CE868493FF48978B5F061 + DFF33B37AF1A1F5910F938F0C1E5FC2EC2C7891327CBED77DC596EBEF30DE5BA + DBEE2A276F7D7DB978EA9672763A2AE70F76CAF9E9897219416A4AC2C9CE8CB7 + BDD5ABD447A33E17139B51E709356B8426B2824FD1BCB6F25383B5F1A4DCB67D + B99C1CEF9553B3FD726A72A1CCCE7DB5EC5F78B17CF3AB5F2E5FFDCA73E59597 + 0F5D0586F0C11AD771DA30EF217CA88DD9041F68AB753636B2CB885F85973C14 + BD9AF8601ED9A86B7C48974DF061B4D226F8F0D27423EF70E3835E0A2E59A665 + 887F0C093D79ADE21F8EB7C607CFC93FC04716B7AFF1616DBA75E865A587C487 + D9C58F0B1FEE09E223FD9296E1C3140F8C77081F35C6568D97FB723FD574B62E + 3EDCF78C8273EEA1D771E0234D7D898FA4CB003E0E9DC3EB46F2A7E17C8048DF + 1A25CF94D2D2BB3E6DC1430B71C8B152934EDAF8EB934FED3826E1D5DC282D0B + 0CFB934E69CB366DC76BB48505125579679FEBF045899D004F3ADA6793A2B9E8 + D43EA58ADD77E5585C108E37B5742938655445BDD01238A9994165EC6951C0D7 + 8B63193E2CF4083EECC3D5E023DF9D1B458D8F74BCF44AE178081F994DB85683 + 6F820FEE31879482D771E2C3C8C14DF1E1E930699E9AE01CDB2A7CF039FD31DF + 578D8FBC7F193E766F7E4D79ED9DAF2B971AE1E78EBB1F2837BCF64C995C7F4B + 3979D743E51BE72F97B32F5F2A0753CC3DFB65028EDB79EF8A0A6F6F37A7CEAD + ED727ABC55761B21EEC6D33BE5F4EC42D9FBD2A7CACB2F7CA97CAD11902E9C7B + B1ECEF5D2AE7CFBEB8363E3CCDBA06D6C147D26B193E1022B80C59D7893769A6 + 06F5BB091F2914ACCB3F680BFEA13661081F751BD996E917F8A7EF951BBF7393 + 7DD50C735CFCC3DF87F091150C8E131F26C81CC2473A96A73665137C589B2DA3 + 9D53FBE2FD353E3CF01D373EE01FF42513600EE123B19B1A7A047ED3D7E4BAFD + 0EE1E3DCE89E7BEE698BFC5ACD3D4F34194164A7B21335B34C21A70662BD7834 + B938607D33CCDB538764D736DB0481FD5B740910D57AE63BE13D7E9FEA578998 + 793D3272C0EF52B818CA2E5E3B864A27406DFD3718852905EA4D28693734E98B + 16A6E3954626FD3217462D10390E234AB20F3A148A0FDB3C2A3EEA45BE0C1FDE + A3AA167A9997E538F051D32B93B7C1C86A7C64F44AD2EB6AF0918EA1890F7D3D + 322F4B8D8F5A4396F399878B7ABCD23CF1A123EA227CC8A064E2B9AE34D1AE83 + 8FFA50541F8886369D6B810FB19D878D75F0A1169579B3A8F2103E86F84746F2 + 1C173E38A8283C5D2B7CA49076147C688213C7AF363ED4A44033FC10AD87B90A + 1F29842E13846A7CE8D232848F54120CE1236BC3AEC2471EA4131FE082FDE5D5 + C08759BFF9DC740857838F65F247EE4FB5493235FB47C187FC63683F161FA185 + EA344EB7DD76DB2E9DCFE8223B69275483A91ACB482916D6902F45ADA9C87674 + F25295481B7CC7843FF3CC335748F74AE069FFB52D351BE957554F742DD5125D + C4180095C56BB5F93B59DAAC3321A82723DA50C8B4FF02B8B6A9BA18AC25A6AF + 8DDFF3D917BFF8C53958864E0129D4251D6AB5633D5EFB45856C4E82E630B2B8 + 6C96C5A9E9996DE3E00A3EBEF4A52FCD93360EE1437A65F490F933B4957B9A59 + 850F13A8FA376D78F2A07A35978C2AA354322C377D3672A1ACA297F95C38DD24 + 3E349DBA88F509C8481C4B15C904D6C18785B055D31B45A3EA7E137C48976418 + CBC64BFBE003CD99396A96E1C3B6131F6634877FAC830FD5FF66AF5E171F325F + 2EF987ED6632D1A79F7E7A253EA497E359877FD4F86013B6786DCD3FC447A6C8 + A8F1913E8EF6A3D6922DC28758E239F091568075F0B12EFF605E498AB80C1FCE + CD103EF81C7CD0F71A1F0A095CAE2179A474635FE0330E3147C187ED263EE01F + 7C76ADF061BE1F8478E64A8133F37D2DC28773BB0A1FFE5EE323F71785F4679F + 7DF69AE383BDC562C18C47FFD2BA0EE3227CF039F890CFA76562137C18413A64 + D65420E5E7103E4C2C0A3E3248A0C647D3AF73A3071F7CF06C3359ADA98E8143 + 0424726B0629193320852237EFDCC86560123E53B3E769DC34E82C42243B5496 + 7C86B0A4F9CABE28F9A6BDD709483B660A378B26DA456296668543BCFC391918 + CA6EB6567D1A522D5B6748ADC79F02809B924E6D56C16651F11C92AD959B3311 + 9D1AB194A0B30FB5666AD9783D2D5AF99A36B4335B0AA236E1A423BFE1CD2E44 + 36B745F8308541E223D5BD47C507421B4C81CDC13053FA52E3235336D4F8C834 + 06ABF001E3B2DDABC587FDC9F12EC287FE578684B3292B546422BA45F870FE16 + 9D1673BC4973F1619E1A13698A0F19F5227C5897AAC687A1BB43F8B09F9BE023 + 4B8698CD977EC274C10B9B83F8E03D3AAE27FF9006578B0F371CFA880982B15A + D332F121134F7CE489DB772EC2879A12CB3ED02E99BFA1279BB2D9902D307CAD + F1215E995F4B85AC8B0FFD00E9FF26F870B34F9F9375F0017EE933EB97B6DD94 + 8F828F4DF61778953C957FD6575B860F79C6227C0CED2F6A7AADFCA0FF15EB0F + 2C20C8AC8B0F0537D7E2AAFD25F161724E1335337EF947ED883E840FEBCAEA47 + 6C02E9AC49A769FAB8F1014F051FF49B9423E28371E9B8BE001FE746EF78C73B + CE369D6C6BD571334CC8444F6C4E59C244E9AD56B7D6795E9482058912339B20 + 44B15272D696A30D08672915135EDAB6B64B733A79FAE1B29ED910331064120F + 20332E04087E9ABA9E7B8C265372AF6DB7E9AF93E69FCCBBC164585E05503356 + EB94A99DD039D34CE0E9949A6A6B19279F4113FDAC529B519BC5D2DC086DA1B9 + D9837562A41DE65387553358A7194A80334FDC77DCF8D011547CD00642B48B06 + 7A253E78C68CDB56DE1EC207F454F056E05B848F9A5ECBF0A17FCF26F890090E + E1C36CCEBCC30CC62E50DE29B363FE97E1C302ADE283EF4D6E781CF8D069374B + E9D84E8D0F3607B02D9ED422BD5AF88006F47F113E5C4FC7850FE6C588A16B81 + 0FFA0A0DCD60EC29DB0486D67BB4E6E2227C98CFE66AF1610666F1A0C96B193E + 2C84ED58E8BBF85A071FE95BA44039840FFE168B66C0161F3A63435B5D343CF4 + E57B6A7C980FEB5AF08F3AF378FA036DC23FE40DBCAFC60718041FE9D49EF880 + 3E8CF76AF0C1FC2A3429009B195D93579DD3CFF1263E6AFEC1F3CCE5B5C28785 + E515DE68DF2090217C24BD46E4717AFCF1C7CFBEF0C20BBB96F2E0A5091E3A8B + 94466376BC76B892104AC5866ABB907896B69026AD57C7BD9EE27594F3FD66BD + CD77491406411B9CF400848E62687086FC1404809B12E3441AE79D2E0E01AA94 + CE673AB1A5C45C3BE2D19E6D9A54CC93B775C332178C95B02D33421B6A6E929E + C978E81BFD61BCE45E51F56B48F8D0E9C0F1F2BC0B07A0704A8511DA77FAA3C4 + 4F3F322F9217CF61B20203DAB015E6789EBFAF161FB4C33FF1611D274F1D3023 + 4FF8FC533B721CF8F039B5568C4D7CC094AC9B473BD00F61DDB417F5897B081F + B699F8E0591803F8F0C474547C58AF0F1A91888FF7D0B6293486F0E1737CC7B3 + DCCB3BADF738848FAC8398FD3087DA103E927FA45368E2234FED6E1A19AA9DF8 + 805E9AF47917B4497C68425A171F1668E633C6B00C1F9A8986F0A139B2C64706 + 1B0CE1438774FD6F5C7FCC074C3CF1A1A0C1659911DACFA48DEBE203BA79E8D9 + 141FB4C365E6FB75F1C14F374F13FCAAB5827F6E820FF987F8602CBC1F7A69EA + 31B3B65A1FD7A2029407C47C5726BDE419F1C17D8C615104D8227C4037B06FFF + 2D07B6293EA00F7D4A7C8007F8A5E350D0E0F975F0E13EA1998F67D0BAD05F9E + 59171F5A0786F0413B5A5596E103DEECA1C8F5CF7535F8E09DDE4F3B601E6DA7 + 7C5E7CE8B82EAD2D7194152C6A3FB6660ECF8D1E7DF4D1B3CDCDBB34E864D380 + F5BC5431EA8F930E5EF584731F9D70911891C6DF829C0985C0E686428AF314A9 + 649E512619A9C07BCC39A48D9D7B3D61E6954EC1325737046B7A59C8D1CD4DC0 + F8DCA26889F41D41352A789C68054F6DAA2C3A355016D4843E4AC6F5069CAA4D + C6AB464E21C0E2B443E3F5775490262BE35D963961BCB42B9833174FA66CB01D + AB83F31D429449E9D48A6C8A0FFA95E64223D40439EFB202B6B9B43C25E40960 + 193ECCDB243EA0B749EA925E0AA6F401C6A146407C58934E7C7800E05A171FF8 + 0F695A1AC287E355C3606E1DE66D081FF65D7C9843477C68D659860F2E8B865A + 7E037CB836C407E35565AD7FC1103ED444880F375CB066D8F0BAF820C1A6250E + 8C584CFEC1BB1050D42ED226EFC99A6B43F8B0BFD02BF9879BCB103ED26957FE + E1C6EB093FF1A180C7A586204FE743F8B8E79E7BDAFE30676EA6662A566062BC + 47C107EF057B353EA46B3DDEFC6914A575CB121FB4AB5FDA3AF880FF9868D4AC + D3CCC371E3C32865E895664EE6B7763C1EC20757BDBF6C820F0506F1618D3685 + 1FE6D8809375F0417FC187AE1EE6C7625CF6DD7D36F1018EF4BBABEB8FAEC33F + 56E143BFA4C407426B0AA5F4197C68D5101F75EA0C30C133F443A506F7F2B785 + EB37C107FE87D6DDF3E0CC3B8E0B1F3DFF3837FAC11FFCC186CE677755954374 + 73D1A443B23F57856A6B6AE3770B12F2372FD481CB89D7B1D293A360A9A5DC24 + 0C0051F3409FD34C936DC8CC341B2899ABAE13B4164CB4F07046A325E116D9B7 + 15BE783FE0414852AD0720F411A02D8B439AC3A266A2395E3F879ED02823F434 + 85663248BE47F0E55232D694423F34BD31BF29C1A73DBF5E247CCEC215FC9EEE + C4472E8275F1A1A0AC933EFD70E1808F4CB478B5F830B7D4227CB8F15A97099A + C1F056E1C371AE830F053FDEC37AE074656416747023E7FEE3C24746F8E47811 + 0E6538CE9175FE649CE2430131FD116A7C40230443E9C57B60EEFA652DC2C790 + 1F45064BD4F870E3E57735C29BE2C3F9DA041FD046B39BF8E0334D54353E7CC7 + BAF8D04C0EEE1917E3256045FF95C407972685A3E22343EB87F807F870CEDC90 + 121FFA06D5F8A8699EF8807F1838C47D6C66FA5C665463D26D113E92DFD21E42 + 94A66EF16141EDE3C2473AE80FE14377141DBDF50153A0E2F7E3C007FD62BC66 + F4F6C0A0698BE7AF353E4C59E3A54F6A8D0F0F11ABF061E09209404DFFA34F5D + 0AE1EBE043FE213E584FFA161BC076147CA43CD0E3E3DCE881071E38DBFCB22B + 0194D000642657CB82A28B2E5FA8832FCF43082BC9CB783225BAC0E1D49DCE8B + 79D59B716EEC1252474341C8BBD980155A58A8FA3D709998D1531152A89B0F9F + 67E2C6A171E789C3F12AE57A4164262723484C0BC084EA9B51B73DF4BE5A5D38 + 345E19BD366BDFEBE9C68D9F3E315E692DDDEB36F39DD0523B33EFA1FF2EFE4D + F1610D41C62E3E4CA26975EE57031F2C709D0EE903B85C840FDEAF8A5AFF9175 + F1C19834879A0789CBB414395E6B301D051F7E77147C64982E7D522B2C6D97E1 + 4326B40C1FBEF76AF0A1CF8EFC43FAF20EFAEBE168537CA4A3698D0F855A4DA6 + E2C3D3EFD5E0C33E583331359AE2033A648922D33E788059071FAEF1A3E0C3C8 + CEC4077D827F6C820F5D3434ED6BD9709DAC8B0F4D37E2837E58A0977FB46D02 + C98C64BB16F830B023F1E13B32225C7CC8278F820FCDA1890F4DDA6AD7B9AE16 + 1FFE3E345EB568FA233BDFBEDBE736C147621D7AD0B66E25F6557C6484EF327C + E800CEFB6847FEAA8F92F4DA041F29ACCD4880D99C82CF368DEEA2ADA05198B6 + 93A383A3CC900E30B8A1CB4585540A509864198D12A99A0E9D8C25B86AC59A98 + D97612472954A629606A09D908075307708FA77F4E57105755A02A4709A7BA2F + 4FCD759F3489A92DF1527302D3550365348EE60625F7A1891A52ADBA496424CE + 90C6C9538EA754E692DFF5B7527D69AE2C05314D2B99208DCBC56D749BE65B9D + 6A53585E071F9800348B0EE1437F851A1F43FE57C7890F35263A3A5AA3103AD1 + 067D4C07D1A3E283CFAC6ACE3FF091D19EF5788F0B1F6A1F3545EA2302BDF91D + 6D986585C4F0227CE4A54943FE61F0874EB5290C41E7AC703E840FE8C5BC681E + D1D1D40D88FEAAC1569850BB75DCF8E81D41E7F8E0F21028FF702DF079FA9218 + 5DB40C1F5C8C579CD93F3550BC070DA561F4E2C3408E6B850FB524E283DFD176 + 30CF43F8601E34ADD41A8E1A1F5A2096E1634803E39C402FB0C8FBB53A880F05 + F69A7F24BD16E1237D65D6C187FEA3FCAE4F1D177D49FEE15EBA293E7C0F74D7 + 6C6EFFD440313EF1E1FEB2293ED2845FE7A2ABC7CB989833D71FF7827F7EB7C6 + A9F5E3D432AEC2879A3DA3EB794EF3B758101F7CAE9FE8D03CD2B6FCD6FD4573 + 3A9781366AEA3CAC1E011FE7460F3DF4D0D9E6835D734FB828209E2A2F4D0B99 + D3609153B2A631016238AA593FDD2CFDE9097B283CD32BF35938A9DCEF4934C3 + 7E53428611E8FBA44A5DDB2EBE4929203249DA39F3043464E7CC85CCFB0D1557 + 55C87BE9AFA72ACD41B9188D2C197238CC5C3F5C9980D27EE5440A6C98B92A52 + DA662E049D1A3117AFCEDCB6E1E920E7573F09FEA1F64C7CC8305C6C9BE0C322 + A25CD66DE2A785348D8630A262537C30162339F2E4B7081F9E18754AA47D04CD + 1410F927AE37C58774F274E606A53F90587043F3B9A3E263A89E9FF8D0A95DBF + 24BEF744AB70A843B6D72A7C6836B19C8289FF6A7CE8807935F8F0D4E986ACE0 + ADD3F871E183BFD57ED6F83057CFD5E2430D550AEEFA125A85FEA8F8481FB775 + F98711617CA65F2357E2C3A48DEBE0439E98F8E0D2EC9D09318F820FE965A49E + 4284DA0D4DB1D049135C6A5716E123F9CEBAF8606C4679F38C666683163C98AF + 8B0FE9EAC6AFC58275C07B694BEBC6D5F00F4D8CE22353FFD40203C24D625E6D + 9B11F28EF1B8F1E17EB9093E6C5BFE91F8C8FDE528F8D8A2C8EF7BDFFBDEB3CD + 04ECA6EAD013909B2B848110E9B83D34C9A98E135C0A5EC968155E327BB8CFAD + BA9C401DE3F49BCA93426A140C93F462F3402DE7466FA565DAD1366D886FB6BB + C8065D278DACEFD791CD3EA5BA3637A0BA6D4F88D2DF5054189BB668C153ABDA + 8D5A3439A93E582E122E7D4774D2D7213BFBA0C064D8B09B9527EDC487A6DDA3 + E023EDCB7EE79836C50717F85013B10A1FE2DE7918C207EF657C0A02C78D0F17 + 6426A65B365EDB71811F051F269FD497A6C687BE23466549939A19C2F086F0A1 + E6D0F5EA21E26AF1918900333FD1B2F534840F2EF06150CA327CD0B6D8D601DE + 039B59B53D29D7F8489FA1A3E0C30D76537C380EC7CBF306732CC28765A6F4F1 + 111F86C07B68D51776193E140A17E1C393BFF8BDD6F8C830FF45F8F0BBC487D6 + 83217CE88C2D3EF491141FA642D037543A42AF4DF09149238F0B1F3ECF4FE82F + 3E925FD6F8E03EE96A5917054CDD4134E99A26C1F10EE1031AA1211AC28779B8 + C48787CCA3E223F9EDD5E2A3D923CE8DDEF39EF7B43E4E7CA187B9A624D5BA16 + E94BD56FDABCDDF032F22B4F3C4A7FE90C98FE09FCBBEFBEFBDA674874A84D3D + D58D5C4A94302B086BC8F9A28D8BCFD43221751A1EEAB8182F805692B59DECBF + 004AF566DA8305AA84D7313CEDF76E8CE994F7D0430FB5EFD6F69D15ED3353B9 + E624C0E506944C31C7CB3FEE4F93A08EB4321505E03CED08DA748C7363E49DDE + CBB834A1D8C6B5C047D2D5CF1E78E081F6BD243A345264153E58942CB855F8E0 + 799E61B10FE123E975ADF091911CB4053EE8CF3AF85083C85C1995B20C1F9E5E + 6B7C785274EDDBAF74805D840F3523E640714DBD5AF878F0C1075B064E767BF1 + 510B98E2C328B64DF0C13360A1C687B5C6A4977C344B600CE1234FCC8BF0211E + 86F0F1C637BEB1ED3BA691217CB819880FD6AD1BD03AF8E07273B4CF1E20D6C5 + 077DE29DD7021FB919AE8B0F04171261D607C4C487C2A2F890BEC7850FF9C7B5 + C6C7C30F3FDC5A78F4355C848FCC13B80A1F5CA6EFE1A22FFA10D7F85059B20C + 1FF4054133F101FF51705F850FE72C733B2DC287F819C2077F830FD608293B86 + 1408193CD0B47F6EF4EE77BFFB6CC37076F533D16E9C9BF3903399DFA7A39783 + 48869760B613B550644407EFD6366A3FB21A35CFEB1C0AD35F2648E425409874 + D3B9EB08AF3A339D2757B59763AECD269ED06A0D5B3EA72DD630485587A95EB5 + 5DD4E7AA7C616A862C2708EB4BED8255CBB539737FCE6F3D9EFA33EE6331416F + EDF1DF297C4007FA01E3FD9D868F3C30AC8B0F4FEAD699D2A1745D7C2CBB6A7C + 70A93DDC041F3AF35F4B7CB8B6D2EF64113E4CDAB90C1F4689599D5E9F9D65A7 + 4CFDEFCC3106465E0D7CB821D42937B8D78821D7B7A693EC8FE6370312D4742C + D3DC4A6B1348AACDB91A7CD027FD906A7CD482C371E143E1C5DF396467D24EF9 + ADA6A5C487BE566AC2BE53F8C8C3B66B48D79065F8E027FC63537C985F6A113E + EC8B74BA16F8D0EAF59DC04726ED5C868FE69E73A3FBEEBBEF6CD3E8AE9BD632 + 1F957AE0D9F98C40C810C49C20432525420E5435A3A62DA309F411312A8ECFF4 + 2952E5BBA8BFB54AD2DC211239D3DB0F8DADFE2C4F41B6996A517D2F001404E6 + F72C149BF4D2DE2B880D65D5BFC0F1EA77A0E6CC3C4CCBFA9835E2CC93624E12 + 81B0CE951BDF71E3A37E0782B3F8707C353E5C6CF625732D253EF409F014B809 + 3E4CBDF0DD840F19E6327C9805DB50FE571B1F19A1729CF8E0E233849C4DF161 + AE252B1198815BD335F3203E96699D96E1635944D451F1C1BC20C89B0436DB97 + 5E9E9E35B166950173B73197AC2B339C6F828FAC01A6B699F77CB7E0230F8EB4 + 073E148C5218151F6AAE5CD346780FE1C3002235209BE2430DD1AB810FFD9193 + DE353EB88C28131FF00F9E877F201C9A80D5BDF5DF477C303605E74DF0A1154E + 7CB482D33DF7DC8387F4AE52DBAA0E676753C2352DBA9D72F0FC63D3D7419C85 + 6BA8B3EF5492F51955CC5C262363D20510194E61049A28B4152F22B0A6A85439 + CB7487C6BC0C345C3EA78DDFC8013735A57193C465DE9754A94A2BC6A5E060F8 + B199DC790FEA6500CEC41BF937B4205D286EBABEC3F1A74A7BDD2B017A5CF848 + 75748D0F686528EB327CC8046A7CD02EF8B014893E2CEBE2234F2457830F2EA3 + C286F0A1FF59FA4E39A7395EF1C1FCC3DC0DEBCE4CE4E083139321E4BF93F0E1 + DFCCF7227CE81C6E74225AA23CC5D7F4D2FF64113EA097261585A855F8C8E00E + DF772DF0415FCD2FA6F958E7F1217C6816A9F101FF7403663DF0FD77021FD9E7 + 4DF121DD86F091661673193176F8ADA5B3121F29E82EC307F7422F846E239497 + E1838B76131FD78A7FC80BDCD0C5473A51AFC28761FA0A4ADC87790A0B88918A + EBE0234D71BF53F0A1C6D5D23749EF2CD2ADF65E7C482FF1F1FCF3CF9F1BDD7B + EFBD73C1293DFC5305B6ECB42E31ADCB966A453BA53A9FDFD914CD2C2AD8BCD7 + 89E6B2248AE607138B590EC5F077558F439365FFD2665B6FE88ED7FB1649DB49 + 601628A0D51E9C270F233CB2FC8AC077A2D2814D95619680319CD6C827DA4893 + CCA2488C3C69251805453A220EA94F5781F5A8F8F034ACB930FB477BE6F6121F + 463D2DC2077FEB909EF83061E077121F2E320BF7267DF8DE088F45F85030ACF1 + 6180866901327F0B7831A2F26AF091291FD6C1477DE2BE56F8509DCFDF0A4D9B + E0C3A47C353ED4CAAC838F1CD7B5C447D6BEA34D35829BE2C32821C6C6DF898F + ECFFBAF8C842A7AF163E32E2CE795C840F8587A3E2C3542BE24393DD2A7CE4DC + 2DC347FAE2ACC28719AD2D949B66E9A3E0431A993AC09A9F6AC5C4871195FF3E + E3C3AA03890FDF990A156B0D263E8CDE6DF86D67AA6B5EB0EBE472F16218B3FE + 1EB5EACDCE29D531990011C995CEE83066C15593EA2195D209C332F997271C07 + 6ABE1F34530A120A4E46AC3030938EA5BDB7EE67FA3918E1A75A5090F19D135F + DB49EB4562F409FDE0E46AE404979BB591042C3C812D6DD3EFC805010D68437F + 1627D334108CDFDA586947AE8199911543004C935B463B2EBB12BC47C507B482 + 669CE474385D860FE9B0081FFAB4800F198135B868C7229B898FF4251AC287E9 + 02F22475547CB016E817E3ADF16188B3F870B1CB743C0127C34C7C2443906132 + CEE3C047CEDB770A1F3A9CEA87256DCCF22BFF700E2C4794F8A04DA3232D1DC5 + F3E0E438F021FF10979BE2C31C3FF00F4FB5C7810FF3EE496FFB6F5153FD757E + A7E0C33EB0B6C102F4D2819BEFF9CC8D5C4D7DE2431366E2C3BE3007D61684E6 + D25B3F9FE3C4875A9975F10176D9270874E073D38628CC595F8EFE991B69113E + 78CE9C71E2234D88DC479BE0E33BC53FBC6A7CE82FB68A7F2CC2875A43B5D6F0 + 4FCB6F3976D76D0A5BE2C3523666A6F767B38E3A535DD3C0AE9D71D33704530D + 514ADC795AE477F37C1011C7A4FB2C9F3129D665EB0BE4B5F914BC675108A049 + F098D024968EA89E18F85CBBB480C9055B27CCCAF70922CBA2981B6348359BA0 + 315CD5E284DA9169C7A8112B97AB5548C12E998213ED0207E02E66E8AE7D55C6 + A76F8FD1123208C72C83C893906A6A4F06F4CB9A79E62159E6FC98A76A939919 + D99119A697E183311211273E5CE4890F3700A24196E123FDD50C91F55DB45533 + 022BBCAF8B8F1C07F4D69408AD328C78113E2C5D016DE8874CC8B4FF3A9F67B1 + E465F8B0E2B8BE49353EC02D344E7C980368537CA8D2B6269ACC76537C188E9D + 198417E1C33C30E00381D8F554E38336B90FBA6ADA5A860FF8047471DC5CB4C5 + 3F3ED729D60AEDE223E9B50C1F8E57FEB1093EF81DDA0CE1837E40772BD7EBC7 + 92FE5C590980E7A431345248E433C76598BCBE1BDF697C98EEC33E2DC3873C16 + 4162081FFCD34F6F113E72A38776EE4DD0423F22DE99BE92D696549B978106AB + F0E1BBC48702BCC57397E183319AE78DB16BFED3FAE0FE82A0CDFBB324D6103E + 4CA992F8D00469943574B0703CED7E37E1A3F679AAF1C17AE21EF081C225F1C1 + 3A30F04DBF35B54EABF0C173D0427C700FEDCD7D9C109C54135A799ACDCB0AE2 + 8BEC969E8488F07023665346F3948BDA1046D590B4E9C45947C674F55C4AE8DC + 9F55CC6524A6D477637CDBDBDE569E79E699B9239F932C73738205794675A8C6 + E31FEF321CB15EC81294FEDE7FFFFDF3ECB7DCCB425533E1C6E646073D9E7FFE + F9B9CAD70934C7456D3F6591D29EEA7C437779BF3945DEFCE63797279F7CF2DB + 0401174D2E207DBA049BCEF59ED2A87D6422B365C0AECD0CF411BBB8A9EA97E1 + C32ADE2C70B0003D96E103609B5B4867C8C4876542B4DD2BDCEBF723ADDD181F + 7DF4D1F2D4534FCD1D378F8A0FDE45DF57E183D40959CC93FE792AD55727C7BB + 0E3E1C3FFD111FDEE789DA8CE48F3CF248F9F4A73F3D5FEC8E254FF28BF0A1F3 + 3417385E868F649E696660DE18F33AF8E019AA96F36E4D69AC41FB67D911E79B + 71D3A627EF45F850ED5EE383F7495B3746F8C7E73FFFF9B9E3F426F8E89D45E7 + 8ED8EBE2238565F89BF85008CBF1D6F890371AE66D24297F5B3E2A73D8253EA0 + D59BDEF4A6F2C4134FCC37C1217C28140CE1438775F7090F39EBE083FEB926D6 + C507C98A3D14F14EE8B1081FCC31075A730B998F4A7CD08E81106A2687F06168 + 3DF7818FDFFEEDDF9E3B4E2FC387FB57E2C3F224FCCE7A5A850F42E3F5C3D13C + BD081FF253313D840F23493589335ECD81353E689F54069FFAD4A7AE70B9D914 + 1F7CEE3EB1293E688F31B31F0F296E6A7C500F51BECF5CC33F14F22C6BA5F043 + FBEBE0C371E781547C34F2C7B9513349679B8776ED985A12D5FF46F00CA9171D + 383998B868944E290C7932367C920EE5A62181EB6815FA6014086DA0C2371BB1 + 79362CE6A7CACE89AC255B1DF734FB187D2308329C9A85CC62C99A545E196545 + 0E154F39A807554D6A073524DA64788E4BD59F852A0D7B84CE264AD379D53E5B + ADDBECB32ECC45401A1AAFEA6C53DB0346051AF3940C5DAA33CDA9C17D008F36 + A197914EDA8F87FA431BE04375328C83318B0F4F8C5CEBE203001B45C64FE8B5 + 0C1F594DBBBED6C187512819E29BF8486DADF8B06C00D8F520A039C08CFC6A77 + D7C187B51EB96833F1619DA7A3E22323D2D848D80C0D795F860FDF752DF021EE + E51F9BE0833E98C5197A820F8541A309B372FD51F0C1253ED452C03F60B2B579 + A1C607828BA59E86F061B000F733364D4016504E7CD0378443B38373315E0F55 + 8CDF83699A9D56E143D786CC7D23FF487CB0312EBBC487DA14B5248CD348B874 + 5118C20707559D9C111234E7263E3449ADC287DA9555F830A1EC2A7CB84697E1 + 43C17A1D7C7021B8E82F4CDFCC64AE2651015FED8CE3051F46BB253E1040F4FB + E25DABF0A150B6C83459E3C3B9151FC8005CF0CB4DF161B4B1E9645C5B8BF0C1 + E7E043B31EFC83DFD55A253E3CB43A67D2C8D26BE2430B896652E86532CE7EFD + 9D1B3DF6D863671B42EC1AD1A58A5BA6C26403D6DA84A1C4CE8B294F61724905 + 275E2E985968744E09D4F04005164F46AACB1C9CD2A0A1E5BC0370C0DCB95F29 + 3AEBDC09DAB4BFD29E93C0A543AE458021A04511691B8935812D803495C0300C + 0187A8E9E00C08D96CF89BCF19BBEDD27FCD711981483F32CF8442238B87BE5A + 1A244B00D4D95DF3776DBE6EDE024795B1596CD50EE884585F8CDB71992CD1CA + D556AF66512EC287A71F0434E60DA6E9C6C8980C63151FAA514DACC87875641C + C287F3A12667113EEA5C3EEBE2C322C02C2A3EE31DF49BF12EC207F79B0D9731 + 8125F1616A7FC6C8FAE032A3AEF850C035AC775D7CB801AD830FE681FEE81FB1 + 081FDC47DF877243B901EBD7477FC507EBC936D9D499F32113A8E6377312253E + ACBBA8E9D6DA74890F85EE1A1F0AA38BF06184919AEB55F8D087D331B9A9312F + 890F7E87AEE02305EB217C588F4E5E93F84080E66FF1C17DFA5C28C0243ED4C4 + 273E741C3631AA11756A2396E183775B6F547CB869D4F8E07DD074153E78B745 + 69C50717B85F850F3660DEC938DD18C5877B8AFC4333DD103ED4427A98151FCC + 15ED405FDE93F850EBBF0C1FFAE8B9B9EA97263E5CA78C1F7A2CC307E380A70E + E1438D4AF20F796766D7161F0A36E2C383B01175C7850F4B2D791886869AB9A4 + C73AF8D0DA45BBD69755105B840FE687F594FCC328759385EAEBC898121FF4DB + 394E7C402F2EF727E50F9E652CCDFBCE8DDEF296B79C6D5EB2AB39C2481319B0 + A60A4F5DF5E668ED2DC040672DE2A81D5F5BA7C06200DC0B812CF521286D9FCF + DD989804FD90F4E73079A4CC52212BF3EED47655A3AE981C7FE7790B972A08AA + 6A941149C0547B0A5EFA0170338127EDA8F2D43991C9D424A59092B655DA4C1B + BBB67AEDD92C24FDB9325745DA657301CA3C19A3DA3B0092028FB4329A69E872 + F1A7E036840F7382D4F85062E71EE6DCC840FAC0EF6EF0E283765878DCCB4FCD + 32353EDCD0C587BE51890F436B0D55554B3444AF4DF0A13FCC327CC884C58726 + 016964D493A7541883268755F8F0A0610E22CD959A2537C587DA3B85548503B5 + B846952CBAC447F28FDC7092290FF10F735A31E73240FA203EF4D3D1DCA0A986 + 3E3306D661E24393BE63B7044DFA1F2AD8BA21AEC2876DBA9EFCBDC687FE5A46 + AF0DE1C3DC74E283B9D74F431A39C76A9DC48779EBB827D336ACC2871516725D + AEC2873E3947C5472D54A8B5957F983C314D59EBE083716836AFF1611432F782 + 0DFA5DE323F987F830754CE2C38A12CBF091EBCCE014DAB6802FE354B858860F + F7490F94BCC7CA07EC1D0A9826ABB590B021F51E2C4C4F90F85038497CE853BB + 081F994E61193EF4D3D4B2243EC4FB2AFEA186DAB59DFB8BF8807F40C345F860 + 2C0AA308D8AC2B7000BDC487C165890F95262A72121FF44721597CF0CF3DA539 + E89D1BBDE31DEF6833879B1832BDE9B509D241A5C63A6CDB85C504F39D09D774 + B0D3B1D3E47D9A0115863213769A0B15CAB84795A39BBF0CA4666EE960A6B4A9 + 8F1013A0C39F0CCFF17229A5433433BF0E49B88C8FBEC1CC9C34D5AF86B4BA31 + D13EEF577AB6AA776AEC0C31556598E6134F4C99E833FB543B875BA891BF5974 + 3A13AAFE87963EE3894B606604444AF78CCFE717E183BF7560ADF1A1D944ADD4 + 103E32AF8A2798E3C047ED306C9F546D6F8A0F9DF4D32C968B5801890B66E6E1 + 20F1E1D8D48AA429CB3C4543F830B022D5E3E243816B081FE96FA1F981DF6132 + 0AE7890F1D4BC5878EF543F89031CA3487F061649CAAF0217C280CA949622C0A + A132E275F1E13A131F96C4A8F1516B5957E1033AD0576BB4E57837C1071B3E7F + C33F9837E8A7265A6156130CCFA429CB50F98C925D071F43FC23236C17E1C304 + 90CEEF327C64C99914FA99B745FC2335CF8BF0E141157C58C2459F1FF1E1018F + 4B33A05A82DCB7121F9A47937F68D659858FD476587E4A7C24FF50F0D54D85F6 + 355F67FDD41A1FFC5418F2B06DF43AED6AB24E7CE8FF640176C7EB5EE4FE92F8 + 50E362892AB54CFA07D5F8F07DFC141F6A1FF9273E546648974C93B2081F262E + 1DC287F9D686F06186FB55F8703F161F26C05D850FF987A96DFAC3F5B9D19933 + 67DA74042E061DAE044D16C1CDE80789CBCB25281784D099D43C189AEC94DAB8 + B4470BD004A549DCD8FC058A6A6EA3306498694F566012A877DF7DF7BCD232ED + EADB930B388BFBF1ACA72355774EB01B017DE032AAC94D9CB604B1F654530938 + 89DC6349193701231EB8D4BA283C593389EF6598F569C77ED3BE6549FCCC8CB8 + 568196D9F113FA6A8AF5F4BD28EC33E955E3C38AF19991557CA80A5F850F43F6 + 97E1C3395E171F7546F9DC10DDE8121F3AE90EE1C3765CC859257E081F7C2633 + 4B7CE47AF0D4E7695BD53BE3B75DF1A1A09BE1C8890FD7E750B4CBFFDFDC7980 + D95595EB7F9D73A6F7244402240142081D4228094DA52B55B1805D6FF17A51F4 + 5AB04BB15C7BBDA057EFF5AF5E41AA0A11905EA4F75E42492040682933C9D433 + 67E6FCF7BBCEFC76BEB373EA3E73063E9E7932CCCCD97BADB5DFFDAD777D15F2 + AEEB53BD3F8A0F82215176E00357ACCD288A830FFDCC16F9647CB8E22D3E28FE + A8BF639D2D3E681CACFFE7846DF101A122303C2E3ED01FDC4FF790FE604D4BE1 + 030BAC0D9AD597EDED550E1F645272A8B11B48141F8C87438ECDC08C830F0A2D + 929154081F6CFC58C3F979B5F8C0AD580C1F5866350E2C7F6CF0E0033CB05EC4 + C6DAF917C30744157C9071550C1F587D746D05AD733F82B8CBE1030B2C6B5008 + 1FBA06FA45F3E5F77C4EF3A8141FE8674A1810144D3637074C02FEA3F8808C0A + 1F1469662E95E0032B61A1320C95E2834340317C4828D512C5070798283EC8FC + B561087008CA1968BE45F0912B80A9AC3ACC5AB6D78C6E4AAC8E2D658F22B18B + 4BC015416BA4FED96B6931C90ED083201D9EBF616384A5629EB44D49F115531D + 16E0114305006902ACF18BBD0BD4FC1E401304C7432015D3C613493865D9B973 + 1FD8351B217F674914D7B5EE4540830B8FEFF57332AB3017EBF3B81C182F417D + 3073FD5EA7001E2E19783673C632759E9F352BB3CED64C6B33280AE18374EF4A + F1C1294CCF42F3E219EAFEFAE27947F161AD01523EE0233A9E283E10F001C1C1 + 14AEE72273ADF0413D1D9E79B5F8B08A80CF587C6C9348B9ED4673EBB3A87FC4 + 4D1F2F5DE3E4B6D4B8EB6B6A74774FDF5845DFE28306A210EB72F850AC193E7F + DA4AD8675D0C1FD4B329860FBB5E363E027C480868AD151F567F90EE6CF507A7 + 4EAB3F784E246E40B8CAE143EF9314B1F487FE9F80519E810DA2C5ED0CB925DE + AC1C3E38D0B0115AFD0199241BCABA9F2D7122D0D9E2039D81552A8A0F884514 + 1FC41992A119D631DB7E7F97686AF35F2DBB1E5E12B799352BDDE8730F084D2E + B3F20137DEBF265C037A2EFA6480A62E376D9703C33178D7F5DC852E3563AEAB + 489EBBC725877B739F7FF55937FCC2A3A13ED073881E082D3E88EDB1F8C0F261 + F161E3202108FA8CC587AC87FA7F489EF506F0AE306FC86DADF8E01AE5F0810B + 4F3FA3840CEB40563A1E8342F88024692D15CB4C9C90D6C9E2C3269058AF0665 + 856C6DA862FA238A0F083DF32DA63F582F7401FA83FD185D8475107CB0BF5A7C + E833C47F46F141A84BB02E39E214DC3C6CB9428017BE53FD3FB1260CD0066323 + 2C883505F2F7C4EC30294EA0F674644D709448672298CD09DAD53531D7736F5C + 46023041785A2CFD3FCA3C0A6608179984AA03A1C5B2A9CAC76692EED0D1CADE + E3C994E7DA9ADDCF1323EE2703B55D674DB0ACA737E494C7CF872BEB21843C1F + 60FA978D636EC3F8C6F58AE2E317230D65AFF31FADE39BE0635A66DC9D9169AC + 696EF7B635B92B37CBB596387D555F4DD7AA446E761977D5CCAE3C7CD88D145F + B9B5826E936C70F303B2745C2619EB9E6B1259F7B3991DEEE091AC3BA46FB0EE + 738CCAF2E606F7DBCEE01DDDFE10D7BADB11537EFFD19796B9F44DBF76ED27FD + A4FE375B798FEBBDE90F39D7D73BBF5BF3E57AFF784A497C7857C387CFAAFBB4 + 32CFDCE1D6DFF2C7F0DDD3BB6B5D46B66E8EF43C41B1C96D17BBA66D16B9C62D + 76887DEF819B7EEB8657DCEBA2FBCBF8D167D665AE8935CB9D7BED1937F0E095 + E1A1CB1E1E092F613FB0D639E27C24639BEFE43ADEF2CFB1C630F4F0D56EF8FE + A52101A1FD8DF6171DD6243EAE33E6B31FB9E667AE71F0B5B0AC0275E1B08E60 + 9509DD59FB1CEF123B57F7EE26975DEB461EBD360CEA27E648A41A7C40D26C66 + 3B7BAF8898C2776495A3F9367CC012A66825727B101021C5434159245BF621EA + 4A651CB6A0252E37CB3FF43B113F8B0FEBF5B2562BBC58E063E23E7D89EDB6DB + AE37B868378B43912E4CE330321B74C600392D5A73238B61FDAC36C08C0AC851 + FFA9FDD706F592050163A606082F030B4FA69E160D9FBB0D10C77F1AF55D720A + C5AF8992C38523D2746CCC4DAF1679A629E5CE9DD9E94E7BB1B7A6EBAC4D26DC + 8FA7E7B2614E5EB5CEF58C8E55F5F91782A9FFAEA7D9A526EA06E9E524C34CFF + FFE95737B8E963A52D279F69192B888F9F0DD5B6AE973566DDD5C95C7CD4E7D6 + 0E951D47AD726D578BBBA53D772A23C8DE2A0109047146301491A5856395B7B5 + 292422BE673665DCA199843B7EAC3AE23B19F2684BA33BA72D38E9CD3BD0B52E + 3A6ECAEF2FE2B4E1EA5FB8EE13CE0C30B8595DEFA5CD22F3C40D5E7F74BDE374 + 97ACE17ED9F4A0EBBBE04B45F11126C2BC33B84F477DE7A54D3CFDD8757E2C6C + 3A949EE07DC67AE653DFE7EF173CEBE3BD75A95619B9FB429758796F5814916A + E89DC1FA26DAA7D775DE238F5E1390986BFCB3B0FA072B147B18F1B7B88DBD3B + 66A74363E33DFBE2C3AEF9914BFCB5345FED2FD6E546DC6BE73B4E8BF5EC479E + BCC50DDE717E58A788F8311B6EE3C731B1FF759FF8FDAA9FE5F05D17BAAE75CB + FC3E48988EF5BCB03F63D5D1FE82E50A222A213E08973B6B60B3F2299A498910 + 5DC3C663496CDD335CAEB6744C29FE618924852D253699CCBA4D4BE163C225DB + 9758B264496F4054BAC91889D68DE0214374583C6E8A099FC132509B1984D818 + 1BCBF06C7C93CDFAB0A7351E94CD50815D43CE2454F5D642CB5527B10D5609D2 + 23C25EAC16570AC199B624FB5B87C7DC71AFC3862537CD45CD09F7F5A184DF84 + E3CACBCD8DEEACAE9C89F7DF560FB82D33953760445E6A4CB9FFE968085EF25C + 7142AD3FF8F8F8EA7EB755A6F8006531F94E5B22CFDAC7F7A78DA46A9ADBDF02 + E2746D2AD7D640D6ABCDB2B591947222E274752293870FDC7136A8FF886C833B + 263D79F7FD747366D2AF59A9DCD99474E7A532AE75D7235CF39EC74EF9FDD34F + DDEA3789A9201883F75EEADA5FBA37A7900FFA844B4D9F13FB5A724FF55FFACD + 82F8408FF9E0F8779E511341AB4486EE5BEA4904BA157DAB31C83D477985EEB9 + 3BB9CC2E47BB6CD7169376EF86A7AEF76494DA6DD21FDEA5F9AE6F06CF73465D + E78D0CDE715E40366ECDF390D8E28ED1FDC56FE6FBBCC7352F3830DE0D47875C + 7AE919A15B0BCB1375EB08D7E838EAD4D818EB3DFF8BFE3E514B26C482F9690E + 6D4B4EAAFAFA03B79FE78697DDEC4B85505E81385DEA0ADA1657640562592276 + 4FFBAC8DE7B2D62909717514B225C89B0E1AD49144DFDA1636B8F3786ED1FDC5 + 720CEB2D8B264920D19016047C18434FAE00A62C4EBAB98DD0E78236188B8BDB + F4C42831B2F56660844CC036D18B3245DBB8D04A94115A7F70D45548E612158C + F5C0755D112899493537983FE9A73610CDDE1B93DF11E3A9D7C5E2747B837317 + 348EBB6F0C8B38C527044F3726DDFF76E402224F7AB9D7ED301EEF5AAB02F2F4 + ABE6ACEB1BDD18F4AAAF93D3C992D794C5E49BCD1BFB1B597C7C7628EBE6C41C + 8F04E224F9E468CA2DA8CE9856B59CDF30EE092DE3E71060B3D74E1E49B80535 + CCA9909CD234EA0E720DEEBDE9FA12C342A2F96ADE72D3C90A31D5A2D3F5D09D + 17B88EC33EE51A6A7019552203B7FDC935BDFC9057D69D479CE2B233E6C5BE96 + 88D3BA8BBFB1093EA2D2717830AF59F59D9788A708A81562426475F2BDFCB65F + ECB27B9D38E9F716691A7FF4CA301182D37CDBA19FACC90558AD8C3DFFA0EBBF + E9B79BEC5DD1FD854DB7F3A82FBAD48CF8C43971D5775DDFEA97F382E66DE28C + 2753879CEC1AB7DC31D6F587EEBB34B42246E3AAB08E68AD3B8F3F2D16311FBC + EE976EE0B987427C685F95258E629A2ADC4A3623F7B399EE365E8B9F450D22C4 + 60090F517C443D55D1C072EB7A8D5E5F827EB69FE55DB47FC7E76C2FBF72F8F0 + C469B7DD76EBED0E449386685832C4038F169AC4EA63192F41ABB651AA354B5B + F79E155D67E1C285DEFA635B3CD885B712254D4C9406AB62AA9A8B7C92D46B20 + 50523E668D91429D85149A3527EE359876EF1B2B1FC733D9725B43D65D181083 + CF8F24037211FF3ACFB636B9F367E5FA101DDF9F76078EC7B79EAD4C64DDAF5B + 820DC66DC44739A2B02C9975FF3D11730D3EC85CFAA74CCAED91893F3711CBDB + 1B2A1BC764C8EF9BB2EE8154360F1FD41C694F24DDBFF4676A7A56C5E46BAD59 + B77B26EB4E1C7D7D08BC2C4EED3BBF253885BF77CAEF3F95C4491B6BE786E7FC + 21A37F87A35D72F6EEB1AF35B6F6793778E58FC3A28524935837832F3170D827 + EB4E9C146734BAF281BC9FA1E3B51166B73BD0C7B0D5459EBBDB752CBFDEEB62 + 1D54D95FA6E2796E22AB1E71AF5D7956183F6B0FEE76CFF3D695937E5093AB72 + F8D63FB881A7EE2CB9BFB42E3ED135CEDF3FD6F5E57EDC70D157363134A06377 + DD7557F7546FB06FBFF9E3B1AEDF7FCD7F7937B9F64BE154CF8FDE8F12AC4CB2 + 48D1538EFA7E762D6DF6BDB53C61ADA7E1B5AE2F6B5521FE61638D88B5B5FC23 + 9A1C42A88F0D44B716ABE8B5F5B3458B16F9B66D1A07C1E925F0D197D876DB6D + 7B8387DB0D3BB3BDACECE4B908752E888097D01A801A347CC646C1F3B34220A2 + 5C0129F2F67E51E657ACFC3D6638AA7E460BD359F226D1BD08888C8ECB9A3C97 + A4B3EE7DE3534F9CFE169CF2AF0DC8D3A7461BDCF635C4EEC8D5F2A764EE3929 + E646B132B5C8F3017992E56970E232EF1D4DB8FD33A589D36FDA9205F1A1F11C + 5243E0BD88E5ED8DB9E7256BCCFE35C61395935F06F37E32B931AE893610DA68 + 3F31E46A7A4EA544163B59F55E0FE224ABDE35C931D7B6E39B5DCBE2C9B74894 + 13B999861FB9DAB52D799F6B5E70405DEFB5FEEA5FB88EA1577296F2DD8E754D + DBC7BF5F26D874743DD2BEFDCF26740D29CF7A1F5A979CE45AE2BA842A14590F + D2AB1ECFFB19A7EEE9FB1CEFB23B1D1EF3CA15ACC3CBCBDCF00DFF9D1748ECAD + 2DC1BC6B59DFB8224B8D829E8BED2F3E83AA6D9AEB38FEB4DAEEF3F0D52EF3F0 + 1545CB78F8E28DFBBE37BE3B50F7B8F37CEF82B40221F135010FFAD7D8E4B4FF + 8A1FBAD1D5CFE5F562B4FB240613910C4A0114DADF25B61B02B1C6D1ACC1283E + 90A825495E316A58D9D232D4B0B29FAB847FA0C7F579DBF0BE143E7C70F8DCB9 + 737B836FBAC97E83405981B9C97A23D39D98991D08961E8A4491E66CFD89D101 + D845258D395AE1D512A462638B82111FA74DC5273D57C2356CE059A1052528EC + CD892677C4ABB50568C791CB9B137EC3922BAC1617D46DA9AC3B3791F31FBF45 + F15A93E07654B6DDAF9AC63D792A479C64393B2F99C9AB7FC4B379EB48FC6C33 + 8988CC132EB738EF1F6F744B46EB1B1CFEE3E6713F7789C62F9FBF88FA1ECB5F + F02EDD7AC9B75AC6BD4BF3A3AF83AB4EC4E986A6E0BE5BEFE3BA0EFCE094DF5F + 81CDDAE844309A629ECE2B156D1623AFAEF0DF77EC7B826BDEF9B0D8D71A5DF5 + 844BDDFD47AF33A52FA57FAC5ED3495BF12F1D077CA0EEF3DA70C50FDCD89AE7 + F37EE6CB9F6CB78F6B3DF0A375BDB74A13F42EFD6EB8C9B2D9BD5EC4C9AFC725 + 677A57AAF56AD8ECEE86B90B5DFB9BFFA9A67B8C3E77BFB7604A8AED2FD3F77D + 47D5D96E563487F57F3D23FC7FF657BFD76DB18BEB3CF85F635FBBF72FA7BBD4 + 705F68CCB05E205B8892B83D5C8351922821094BCD78C974B7E13AB8B22D3E10 + 7B1F5ABDE87D8A8EC17628E03AD102C051FE614BDCE0222CC43FA2F8F0162795 + 23C0E2641B1AE63DA009D6A6403099E69E7AEAA9BCE02B0D52BFD3E2C9644720 + 154164B6586014440490712AE35E0C98A68B629944F8473355B84EA1870833B6 + 8065E38650156ADEC8C3D8ADA1D9BDEBF9D28D0AEB2137CDE8F481C8EF593758 + 5366D6ADC97177714B8EB11F96494C5ABC16E4E9984C79E274AE4B87F5442C3E + 444A4F188CEFABFB65707FB922F5BC95FDF896B5FD9332B7622202B36662AAB4 + D9D925D5E4DE5D677C9CDD181C0602CC9F92791D2C9F0171BAB13938B94DDFD6 + 75BFED33537EFF9107FEE6FA1FF8BB6BDBFD6D75CFEAD36631B63ED73B30B9E0 + ADAE6DAFF8315DE967EF73AD8F2DF5B85FB1624578B2A699B10E123EA662BB83 + 6ABA4FA5F372036BF37E966AE970ED6FFB7CDD03D3C7FB57BB81A5DF0E0B13B3 + BFE85936EF523F4B572991FBB7FFB63FF9E7A1674D8F468577F8FA44C1B86A7D + 2672A5ADFDD3174AEE2F33F73BC18DEF109F9C4B0AC5AFF9E06C6585D6107C2F + 37E0E8E0FA3CB718E40382616B426184882684F133615DCDBC45A00898870FE0 + BDB2F8B0621B882B98FCC9279F0CAD56BC4F3AC05226066EA27D41D78D161B8D + AE15EE744BE4E01885F0E189932C4EAA1C6E4D5B8504D318D1EFDCD4065B51B4 + 90A28E909352BDAE6C112BD82C248B6AE394FBA7F060B4B5848D9A0794123A47 + 63C2834D126F60630DAC6029D35C77CC26DD67B2CD35813B8E5CD3D1E4AE0A88 + D309836335B9A008A0D61ABD25202AEF1A9EBC201C912765CD952276BAB7C650 + 081F730786DD87D6C42F54755657935BDDDEE2F1218BCFE1FDF54D3BFB6A4BCE + CA66F1F195F16637D7D5D785F6EBD69CC2FAC470EDD7AA561447764B22386C6C + B9930F989E7279FC6AD77BCFDF7CD1C5963DEB4B9CD65FF865BFE1798BF5F607 + B8F6FDDE17FB5A72A1F4FEE30F61E0AC2D6C889E937E1ADD7ABFBA13425F1621 + 3D9897BDDCB4C7315356976BDDFF7DCA45F7179193D7A3BC85446BD17FE9B75C + 73723C0C4AA6B9BD36D1AE83FFD5356EBD67CDF7C1DD15CDD6E2309FDA76B1EB + 3AE84335DD43C474FD5F37D6C4F24467DE12D7BEFFFB6BBAEE9ADF9F9C97FD46 + E215C5596DD037FBB76D3E6DE70BF6897DB685A8ADD7A71CFF90BEA5D441B424 + 1255C329704B9298FE2EDA65C48A75034296E01F9464123E684E3D6199EA4B6C + BDF5D6DE5517657AD60CA60D8F1A1792E79E7B2E6468F829B568AA2CAAEB8828 + 89558AE8A8BA2A7D80EC751140A48D944AE3B05B5AAB28AE4A962E1A62EA5E2C + A435A1F1BD2D6425F39EC66B03C860B63670DD963E50401C16B637ADE9751F78 + 6D434D208C23974F6B73576C58E73E906DAA89382D4D8DB99B5A73E99ABB8F66 + DDC7A6384EE6D2E0FE72F5E8D928F59967EA9B240FA7DD575D6BEC6B9FBD458F + 5BD1BFDE63EB5DEDD3EA5E2052853C850F615AEBB9289B7247BFB8BAEE6B7861 + 4FABEB6D4CB98FBF565F8B5A2139BF61CCBDB0ED1CB7A179A64BEC5F9BFB228E + 241E5AEA069FF88773F30FAA7B565FFF799FDDD872A546E29458798FEB59F90F + AF0B6565B559C612E94FE9CBF4DCC56E606E7D5D56222EB60ECF5873972F0730 + 5522CB4B4376344FDF4E05112E2589FB2E74A9571E0F7BCBE99DA6A1EEB4E3BF + 5A53290AC406E5DBFD457AD01796DC7EB14F42A855283721194F35BB69C77DC5 + 256A2CF5B0FEDCCFE4C5316B5F155EF5FF2A7C6CAB806371B2161D3BDF79F3E6 + 79F7DCECD9B3FD5E2C82CADF407CB846A1CF535608722B1E20AE4039243A9568 + 5D3566DD8B60758D99CAE5852C4ED42EA332BCE605F913C7103E68EF053EC296 + 2BC105BB6D4074D47F48EB032EAC4D4FDF8BD08898E87B628874232905FD4E84 + 4B3FD7DF170A92A3A92181DD62741A34BD846C654FB9CD60B4DA786D4C133532 + 68564829FAF074331178CEB56C55515B2C8BF9420AB5985DE98CFBDC9AA9AFD8 + 2CE2F44067ABDB67CD7A77C440FC086A0599AB48A4E6B74BB2D1FDDB507DE380 + A272655B83BBA3BB2D24AE161F5B74F7B82FBE14BFE2F7190DA39E50F8DA49AD + 9DEED8BEFA9964646992C589D638BAA7E2CFE68DD4901658A1FCB5BDC12D4B64 + DD97FBEB5C6FA180A814C1C33DED6EB4A9D3B51DF3B529BF7FC36357B8750F5C + EDAB58D74264CACAE8906BBDE9A75E577965BCC50EAEE3F0F816B6F48397B9E6 + E7EFF27A8FFE5812CCFEE89E81CD76F641C2F59CD7EA733E97A7EFBA16BFDB35 + EC7870FDEE1911B90AC737ACCE2B47A340FFD6C5D5D7179A2C512AFFFA3B2F0E + 6B00D131623838A4A68EFEC6A4DC43B17983F75E9217648CFEF0EEA5797BBAEC + 928FD47C1F59D06475D2BF3316BFC38D2D38B4B6EB0DAC718DFF382BAFBF2B96 + 4A9BC6EFFF361207646395F99D0C18DAB7C515A4FFB95EB4CB88C587DD8FB150 + D1E751D7807FC031C8C6A378B70ED37287D38394FD3F6A7512FF90D0BB93FE77 + FA97162EF4ADD3F826DA7AF525F6D9679FB000268DF90A7521B611EA2C9EAC40 + B2CA68602A5CA5F2EA743C26084C93B5712D361D50D7129BA4670E6D55C4FE25 + 7A68902DD8228A47FF4FC34EF93EE951667B3CD92ED6047FD1BF2A5AE8D2CE37 + 2F883358E76F0C4F7D369352DF1F6A4CB823B30DEEC81AE280FE3EA3C3DDD198 + 6B2E3C3B58FA2FA4A7762ED76D31C3DD38361C96DF8FE2E37BEBE2BBD7BED21C + 90EB54EED929FB5181EAF512C5367DBB75A35BB8CD25DC77A6884FEB193EEEC6 + 5F1702AF0C4A6546AA6AB7E226A65A641958FBC83F5CCB0E07D675A355A06DC3 + 4DBF08FB49366DB9634DC469E4FEBFB9C187AF0AC302A4D8756A958E521148E9 + 3CBD0FD9B97BB9B15D8EA9DBBCB203810EBEFDBF434B816F7972C2B75DB6A1A5 + F68B572A77FCDE6D58FE4068BD782310A7C44B8FBAB5D7FC6A93FDA57D9BDD5D + C381FF3229F75060FCFACBBE9F4724FCBD39A8F76CE5BA8EFEE2A4DC4B714E22 + 6A9D477FC9B9C6DA9E6D62A8D7D720A3A71FF1C2B6E71E59E924FDE8BDB14608 + 9B991635CA10C02DD242616A488BA410FF602FC7E5A7FF17FFD0FB240B943C5C + 7A9F70D9694C7AC7C43FC423B02045CB11E89DC482A6BFD13828B150A8C1FC04 + FFE84BECBDF7DEBDC11FFB962BDACCE8CE6E19DFFCF9F343F31726325D508445 + 4A40E6301111FD3FCD03752D0D5AD7150BA42C7C21539906AA01897C89458ADC + E0F263B16C414EAC4194F1E794A807A10D5A8CD306AB51844CD7D1B5F169EB5F + 6A47D8A87BCD5705BEF4BB590D8DAF0B7162C33A7864DC1D5F4339842BA6B5BB + 5B9239D6DED23FE0BEB4BEFE16122BE72646DD8AD99BFBE7AF13879EABB0A497 + 45F850AB946ADBC0205FE8DCD83771FB4CAE1867BDE4C9542E185DB2DD76DBB9 + F9CFAC746F1F9A1A0BD00DC133BC3FC0C2EB419C54832BBBE3F6EE9997D6D69C + A21D479AEF3FCFF53E75AF1B9BB6754D44A69C8CBEF4846BBEEF3CAF84BDC5B9 + 759AAF561EFB7A0F5DEEFAEEBD2C3CB1EA644C4F31E92D7498D2C507767B4FDD + E6A53204FDD79CE5EFE98B15766FE9D28BA7D6E53A7AFB1F5DCBBA67C20DD687 + 7604C4B4FDD04F4EE938F264F5337E5DECFEA27F9B763ED4B5EDF58E49B94536 + 2D6BDF67F3F617FD2BFD219755BAA1DD4D7BF7B7266D4AAABB3419454545F886 + AFFEA9C70B643BDA974EFFD26D43CF55DF6B3FD5FE8D1B8FC071CD77D9B26521 + 01D2B5B40FE326F3055827BA76E81AB612BABE162C58E079068D88B98E3EA3F1 + 893FE81AE21FBAB74894FE86E6C7FA7F8A5B46BD5EE209342FD69E0F8F9008AB + E0034BD804AFE84BECB1C71EBD01D1F1C1E1B0477D59A66553F76D114C5986C8 + 60A3719E48927C999CB25808FDBC583130B24CBCA97422005CD7B45D9031EDC1 + 5A71C769F3A574802DCF6E4D8AD6CCA8CD1B57A394991607466D6B3500145DBB + 9246B6932DCAA452BF3AA5D8D75231FA77DDCDEEAE0DBD7E9D667575BB53574D + 6D69858BE7CC744FA5722707ADB5B77C197C7CE4C5B56EAB186D60249F6C1809 + F1A1920DAA1E5E2FB1C449E37EE760A66436E164CA15CD4977F9D8903B3B33F5 + 490A22F06AF4ABF7A0EB033F9FF2FB676EFE5FBFC90DB66FE1BA8EF874FD6E14 + DC63E4C65F87FAC3B54F773D27C46F44AB6CA7D1A76FCBCBF49542A6DFA30E32 + DA0C1474DF76E8C9F55BBF60331DBCFE976143F5CE3D8FF281E15329FDB79DEB + 1B0D5313C897ACD96AA7D79538A95C44EF953FCBDB5F7C45F3833E362981E1C8 + E0553F7123AF2C2FB8BFBC5E56DC7232F6F293AEE9BE3FF93DDBA4E0FBDFD918 + 24FACCE9202C122392A2EF6D0573EB2286081168EE93238275C073247C10AE63 + CB15D8BE74D6AD27FE411D298A740AE78A75C22A85C1867E7B8502C439D8D8EE + 2985F887A90C9073D50503EF6681E4EB15B1901097625BA7D8AC340D5A8405F2 + 21E6A77FB588588FB4985A10B53CE1C6566C6D055F8179A259A0843E79D12AA0 + F889F5F7122D984C6E3A2D464B105896E91B1E06E395450CDFA9C6AAF992DE88 + 2BD2C67AD5DA8C368EE8A4FF5836E35B6DBC6724FE75FE6F7A9BBB7F38A7AC04 + D61FF44DADC5E99C991DEE81E1410F64011D7C68D3D098FEC3B5B8F9A3D513A7 + E164C27D735A7398E131279B709F1DAC5FFC96CA2A5CD494FB5ED8F8822ABAD7 + B9371E725F7B935BDAD5E2CE78697DED17AB527E1490C59589DCF399FE91B3A7 + FCFE224E5DE9D7DCCBC13BD875CC97EA769FE4F3F7B9D5D7FF364F7FF47CE8BF + 625F4FED5BD20171B23DB238ACC92AAE838CB742B5CF7463FBC7ABEE5C89680C + C3775EE0EFE7CBB02C7CB74B6CB55BDDEE5748548B6BE0C12BFD9A6ACEBE89EE + 665BD7F43C07967ECB0DAD59E57AB6DED9D7A31ADD7A497517088872FAA6DFF8 + FD053DEFE38E82314D466038927DEC2AB7E6CE4B8AEE2FD33E7C56BD963DB6A8 + 6869E33DE786FBA2DD776D7905ED9FC294488974B98C127AC6F4ABA371B4255D + 9028FD5C7B31256AF4FF84DD10DA43DC5231FEA1C308FB39613FFAB938847AEE + EA7BFD9E1EBC858893ED954B9C34FC03438CC5C744B8515F62DF7DF7ED0D5EE4 + 6E164844479B1B1B52B16AA05C488B27D222A64814BAAE41D7647C9830B94205 + B2A293A08930266D7E065327485CD7A3943B13A5C065B4543AF59B3436B25CA8 + 0D8149CE767DB60B2CE2A4D613AF8E675C4BB0B0F7CDEC09CBBD2B783B4E6D24 + 55A03EAB712C54AC7209EEED02A004FFED359076E76CD6E106DA5ADC6EBDFDEE + E875F15D34B2388938699D34DEEF0C265C6B76EA02C47FD69674A35BE6E30397 + AED6F9C8D7D6BB3DFBAB0FEA5E132CF959B3BAC367362378974F79253EB138AB + 21E36B42E925133E54DE40ABA4977351FF885B961C777F4A66C274D5EF0C255C + DB242EA34A36288E4A2D5D10E6A6ECBDC7DB9A7C3CD8BDC1BF6B530166124977 + F78CCEB0ACC6DE010E0FDF503DC39655F3E78991B0CDC0564D2D6EC186413FF7 + C3025CFFD8D4AE1291502CC5D88635C1FF65DDE8E3D7FB83960E2CEDBBBF2D56 + 13E0B1579E749D8FFCD99F0CB5B67DA329D7B9C37EC11A079BCCDCBD7D11C94C + DFAB6E30D15253707AE2CE3FB8A6BEE737EA8F39FB86CA5AF7C9BEFA946F6C6A + F5472DC4C9D6D7417F495FD16282D4EAFE6C936FF41B57D41A63FCD5A7FDF3F3 + C1B3F30E08C7AFA2A5EEB5675CD3137F0F3D091DC77DC365DBA6C5BE5F215156 + 97D2E255F41161CE3D7B1CEEFA56AD70D9D79E0E3D031A87920D6AB1E8A56EFC + B96B1CEDF76BA8AFA18E2D5DEBC1FF5EF1E7D5BBAEE1C13FE79589686CEB7423 + 077F6152D7462D677AFFF17F2101C08281D482B17A4926589BECDDE7F97732DA + 09842C7A888DBEB47FA23F443CF4FF48B1FD1E4B928834314614B91459B1169F + 42A2FB7308A7F8A57E262B19048E4298249E152BD089D83E7764DAE5E163827F + 04D7ED4BECB9E79EBD81E2EBC6BA24DFA30641590032DBA24CCD16AD922581A2 + 56C41D69D0B23AC9DAA4C9B0A0A5066E1795B82499DDB4A0BA3E163132EB00A1 + 889B84720536400DB0C23EF5336DDEA43FCA4A268B9536484C7451CB98ED95A3 + DF690C3CECB7259A626D58DA2015006EE7ABEB29C04DEBA4318AEC2C6AED70EF + 7B257EE6D9F73A53EEF9A1C1F0C4737ABAC1F564A62E3BEBCCC6605E5B6C9E87 + 0F48B59ED78793013119A83E407C7522EBAF4D8A6CF6B5D5EEB491F8AE3A65E8 + 8DF6E4DAF5C89DC88B0C3E845FBDD0BA576732479C2643E849584A4AE183F7EB + 800DC3EEB8B1EAE7AF04845F6787C3E0489DDAF45CF4AEE8BA8584C314AD4374 + 32ED587854ACA2812A14D9FEC465FE7DB26549C007B5BF5AA66FE11ADF16DF42 + D1F7D7335CB67F8DD76FDAB8754D4EC0D21F52901A83D51F5DEFFD5EEC7E65FD + D79EE5DD643C3FBAC7EB5F3D3352AADB67CE7189C33E177B5ECAA61ADBF05A18 + 2F227C08BF7A76161F6077D6BFFE4FEC7B454529F0224D51011F9A9FBEF4FEB0 + D96AFD799EA9234E8D7D6F657DBDF6DCB230DCC2C7BEEC766CC52D4C061FBACA + 5BC2A43FA4F775586A9EBDF3A4BB0F13EB5FF201E2C4D462B5607F511C5DB2A3 + BE4548AB95D40BF7BBC4C34BFDFB106DD2CBFBA179681FD49CF43E497FE84BCF + 57BA5E0750E1AE589B3549297C08BB7A2E64B615E21F1021B9C03556C80E9E28 + E9259128F0C1E1BD9CA06F750F8595E8DD618C134D8FFB123BEFBC736F30B06E + 4D524A9313B5C8938D4B2A54CD1365A0C191C2AFC98B3031192960AA88DB0751 + 4C6C6AA3160ECB04273411292DAC1681F82AFD8D4E5B30641B916FDD7652CAFC + 1CD322E640AA9217F383DAEBE865C52AB6EBBA7E774C6FF51621364C58354172 + 6C1AC48DED3F6DB39A88D34FA6B7BA57B363FE7A02FA3FBFB2DECD1AA9A1415C + 9522723336BD272CD90F3ED8A08F6BEE7047C628B7F042F028BE974C87F86818 + 49BBEFD6409C546A20D999C387D69DF4594CD3E0C36F7CE3D949491850AAFF1D + 8DA5FF067CE07F8FE243EF8314C43EC3197752A6FAF9DFDDD2E0FEDC9A3B58D8 + 38435D9F034FA95647F4AD1CDE7CB758E502869FBCC5353DFEF7101F12B9B2C0 + 879E81CFA6ED9AE6460F8D9F81D47BFE177D25646D941009B26DD11F7AC612F4 + 47E73B4E8BBDA94589936DFF409AB4AF19339E74D923BF52D3BC9263B9BA33C2 + 87AF7A3E51A959F7153EB491F98DA0A5C3759FF8FDD8F70A65709DCBDC718E5B + F7ECA325F1410AB9B72406648E86B1FAEA1F19AB29ED3F71FD4FDD2B2B9EF06B + 498789BE9EED7D4FC34A444D78372CBBDDAF17EF9302C3DBF77E67EDEB1391A6 + EB7FE8FAD7AD0EF7172B6F44E294597E871BBBEF2F1E4FD6E2847B1177B6F641 + 3D7BE90EDAAE692DF106E99997D31F84E688DCC03FF4FF7A1739C01673AFE179 + 22998C318A67E867D21F1A9344E32094A7943047F4ADC50781E401C9EE4BECB5 + D75EBE00267E439D641904A7DC42D5B5ED04E4FE22BB8DCC366DD20481B130F6 + 4114131BDF64FDC2362511A28175C8361B66A3B1816464F78938E196D3E7351E + 2951C0CCBD51728C15A0A000F550F4C044D40E6B6E77C7ADAFDEE2745D409CE4 + 9E0128B6B3B4CD5E9895CEB82F8EC60F4EFFFEAC2E3792CAAD9780F8D1DE615F + 0D7DAAE4CBCDC15A4F90679DEAA2F83822DBE00E5E577DF5F02712E33E70D992 + E49F0FC7274EDF9E333DC4071DB78BE163DA58D69D9EAE2D10FDA69694BB787C + B860C2849572F8C055B72878A61F8A51A3EBD68E66775D77ABBFB6E61A9EDE4D + 457E3B772BDE1513101B6FE2DE7A1F7FE2AF56D4C0B7F1E91B43372EAE3FBD63 + 588921AE4DEF8ABFE9530412ABB1ED4F452208EF3CFAA3F3F8D362B724B1C429 + AA3FF40EE03AD3FC92C77F27F6BC54A8B0127CF8D892969E9A320525631B56BB + 816BCFF656AE4AF1811ED57A5383C707E4D610DF337EED8F5D7ADDCB21FE7C3A + FC9C4515953850BDA335177DDD358C6F3CB0F9E7FDD67FF17DEA265B06FEF1FF + DCC88A7BF382A4D94FDF88C4498D90D5A4385AB7094E20CC6ACF279E89F749CF + 567B22874D8B8972FA030C6349270E8C3194E21F2270FA1B1153ACB9941D82DC + 61192B27967F509B927B199D916BB9125CB85BE4828A99B8B868AD42F7632ECC + 842020BAA816008647BD25FD4EEC4F7F0F118A2E68A9CEC596B858EB9175C1F1 + 7B4852B4A3312F3729A13A694AA832CEBF126D9C1A67D4176AE74E50BC8898CC + 774BBAA7BB0FAEAEBEA2B34893C853A10767C73E3391ACC9BAF1A9C674E8A3D5 + 1A7D66BCD96D3F3675314E9F6B7779F8D0C648209ED67EDE0BAFC46A03A318B1 + B327B2DCC047DC207E15B73CBD33476078B98AE1C3B76408C86C2DC449F7FB76 + 734006B29B2A8468755B1BA767FFDFD65793A81C439CAC425576575B1CF0417F + 27D2E5F5EE478BDE59D1EFF4F75DDBED59558C09A27A47C38F5EB3093E689764 + F5C78C8FFE32D67A6BA354DB119BF0812EB18574A3FAA3EDD04FC64EEFC63568 + D70DFD41FF2B6D12B2C28C1D7546EC79F9363115E0C37B08BADF547316175962 + D5E043EF4F747FF1AE9E98CF53D274F3D9AE21BD3E4C3DD7B5DBF7785B45D5C8 + 157BA618B4E8FE226B5C5CD76CC935BBF7527F40901141EB0551D757C7619FF2 + 2529DE4822F7EBE8E3D76DB287DAB5C2B842F0B4841205D5EA0FF0818749A29F + E9F37A2FA9B7680D1B90180E79D21F58AAF519E96AFD3DF8A8957F5822E7B3EA + D47225F85D3726380D84606EC52EE9148A7507AB8F2D8DCE44C4F050BCF4A7D3 + E4AD4262416C83BE68AF39FBFF56C1D99E78851AF6F1324637A2621B0F816C30 + 5D7D568B4EBC133DF1186374BE22881ADBAEA92677E24BEBAA06A7DC74B7376E + BC1E60B4E99F3E0B656CBCA6D81DB50961BE02A77ADF2D4E4F5EBFBA4AEE1FC5 + 87E6A8D381FE5D9CCEBA936206D7FFAAC5E5E1A3168B533911C17870D60C6F35 + 9BDED2EA4EEF8D5FB8F3DA80305FD6B8B1A1A46D5F2089E2BB143E504A73B309 + F7F991EAD75138BC35957B46282A14BB4E6B3EF66322DEC036C7B6EF99379BAB + 6064B009542BDAC08697DD1CE2839A31D21FB6AA70ADC1DAE584CC2F3B2FD58D + 8A4B9C7CFFB0C1B5057B6F51A9DA13CEE0E43E78687C575D3991F560F8916B72 + FAB563B39A2C4E63CBEF70C3775D185687A6B40BF1A1C2075954D6122C21E986 + 0D4FFA75F37FF94DECB10C5EF61D37DAFB4A1E3E2AB1DE78B279F90F3CA925F6 + D56FD693588C322A0A9A5F7FC3FF784BA3DE27FAAEEAFE6D879CFC86244EE9C7 + AE2DF89E5B621EAD886EF547217C90C855293EE466B6FAC71A00A2FBB1D656D7 + 26F142FB4B547F48D82F0A15C38CF6B3B3F8E06F270E237D896DB7DDD613274A + 8D13ECA945104326D55F273F5C18D19B6241A0A6026D350A951FC0FF6EB3DA74 + 6FEA323149CB2A618AD66C175548F83CA3E98F51B12E3FCD1713A3E64B112F52 + 1C4B5D436BE3DBD0F46D705F8D9106AFE6A9AAE86D83056D2A7458297D3CEBFE + 33A6C58936216CCA1AF3F11BD26EDF91A90B0E87B845F1A1B5D77CF7C838F7D1 + 1875AA541CF4376DC93C7C8860CEA89331EDE7ED49B7BABDD59BA2B5D9D5521A + 40490164CFD93457CD21CC3A9A503EE5F001D6E356B887C0830FFD2BA5A3EF69 + 6BA031119F68630918BF64BCA53B56313F112775AB071FB847C187D51FF5746B + 68334DAE7F294F7F7406C429EEA6A63623DA9C8BE90F5C1D5AEBB663BFEE1ABA + 66D6655E1BAEF8811B5BF3BCFF5ED6945A629CC66EFDADAF7F64F1A1E7A5EF49 + DE29860FD2C4A5A3B519FAD00915548D99E1278B9E1B581B3EABF637FF5345F5 + 972005BC4FBC5F8A6F2AD50BD13749EE5FEB92D367573DD6ECC8A01BBAE41B61 + C37AAD17FB8B6A93BDD18813EF2459697E0E05FABC49A2AD55381413BE43C157 + 710AF0C1F5F8BC44F7D1DFD16B4EDFEBCB961A821394E21FD257C456156AEC6B + F98744BA8D2438C663AB9D5BDD6C0EB41B89933EC4C0F4459021E630819DEA9E + 0C200F1C26A688A06DBB3012FADE49742D3650524AADD589B16069B2C1D98C35 + 6A72232D51D7227E212A36F85C0B48F3E2E8699B8AE2D1E685F67EDE4A9548B9 + D363C42029FDFDE9C664381E1B5B610B8EEA773F1D8C97C1A534F2339B366EBC + 1AEF7B52ADEE2DC353439C74FF6FB56CEC3C6DF181F975876CD29D3C52FDFC6E + 4B8DBB8B5B927996C87A112725D0FD70CB9E3C7C7C62CD60EC3A4EDF9A48F107 + E3BCF87E139D3059DB8382C58724DA155CBF13C18E131CAF42ABC221CF07E5C5 + BB481B26DE271A7023A109BF63462C3710B140365D5BBA276A9E97E8FAA99831 + 47A504571E05F80878ED3CE003BED96F1CB18D754BE90F5FCB27209CC91A9BB2 + 169B17AE3CC610D71DA56BA9596F141F2429342EF96045F141EAE137B6EC46AF + 0312877D3E36715AFB874FE674C9AE47B8E605FB5744A8E5A21BBAF3823C0B2E + EF57CBBE27FA3630C5441984ADD9E0BDDCB5FA383E49F2965FFB8ADCE081CCF5 + 96033E32A90537274328DEAAF7412404777C743FB5B1C7B8B2C007BA8AC0719B + DD5E2C368EDA8AFA3B8F8F09D73605B4A51B09B529C73F0AE90FF80771CF184C + 2859801BBF103E6C9C55F0BB9CAB2E18583793239D8FC5225B0EE6A89B150AD6 + B2C5B14A0593333899F1B4187603C09244B68BB52EF1AFB548158A1DB095CDB9 + 67740C7C9E4AE2366A1E570135AAB499D98C182BB830E3B8887EA9962A898932 + FF13EED1A8507BEA27D5C74E7BD1E6FC9D369707FA235DE394B50AB1C4A9183E + E604BF8EE362525DADF31BC6F2AC305F0F184E3D88D3A32D0DEE9CB6541E3E4E + 5A3FE2761F8D7733ADC9DAE446D732F5C5742AB3640AACD21B2A8A65F0C1F771 + 70A842AB8F8E6FC487DE77140FAE175BAD9786B5F63407918B13EC0B71D2BC8B + B90291AE8038C50DD62E2572A5F45DFF9BF0C0878E52A071D3F6FBC7BAE6E005 + 9FAF587F74BDF38CBA10C29167EF73E9DBFE2F6F53E93CEA8B2E35A3FA028FAA + D324F723F8C0F5023E1A773FDAA576786BF9B5BEF7CF2EF5C27DB93539E20B2E + D13EF984B1E07D83673C74CBEFC3FDC5B6E0F0F5A58EFD72C9C297BD4BBFEB1A + 065EF5B5C4E26030F3F015BEEE99EDB4E10FE6BB1C5392B0BD1E3274E7F96EE0 + B19BBCAEA38AB7A450D88B253712CD4F9F23230DA308645B079362FA03AB37FB + 047B3A318EBAAE3843A1FA4E85F447F4C0622B994BDFEA5A58462D692A840F7B + 88F516A76DB6D9A637F845B7CDA4D187A8F24C7902AA735A8263C5668E942B72 + 4983C0A8F010C474496924D389D31BD630986725125D40CB3C794044E1631193 + 8910D75F21972320D2787EB4A1FA98A19FB43AF77C221B16FDA26818EE42C024 + 22AB789AD6187BF4F3C9ACFB61E34610E99A878C3A774C99F01CC5DFEC3196F0 + A4A616B1C409B327DF23715D4C773625DD9F92A379F850E5F07A54F35E9A1A73 + F7BD695A5EF1B7BD56F7B9E362C46649B038B126583EC1593433945A46BAAFB0 + 1FC587448A2A0E71FA61D3987B31B531664AC2890C1227A14D5134C69031EA77 + 9DEFFF59D5F7C795540C1F563A8FFEE2A4567546E4BE9145212A6D4B4E8A6771 + 1A1D726BCEFD7CC5FAA3F5C8CFD5655E0A4A4EADB8D53F336244E2CE697CC36A + D7BF34E78AD5F3D12666F1D13F63276FA12B3BA69B7FE7FA9FBC23D74875EF0F + BAC49BE64FFABCA362DD737A1ED42AC47DB86138E3A6BFFF47453F2F7C0AA792 + E65D0E77AD8BCA07A06F22AB1E71A3779C13BE63D4126CDEE73D15D79E9A2A51 + 16A0EAAB21B67E93241AEB041F000B588C24CCB798FEC08001FF8024091F9036 + 5D17571FC4A7507C52D4681215C222B06C158A7D8EE2437A10EF13C694603C39 + E2A4720428616D44F22752F38881EBC3626912BA0643AA88C7B001DD764056E8 + 8AAC5A3E2C1A4A1BD7808813AE3E3D004EB99CDC70B3313E1EA0ADF219756F70 + BAE71AFEA4371167A0F9E89E2C2ACC96C69C5A44EB3AB4D939FAFA76C0E1AAAD + 22FDCDE631D7DB900AEB2BF9A270139BA7482173D23DBF3230EE2B63572BEAAF + A6947DE62F82B66860C4BD73A074DB1559C3147CADD8A38563F18988C8C17FB6 + 274AE243C4294EF0BB88D35FDA5279F8F8C4B0733B8C4F3E71FA6D6AD43D3BA3 + 27C4872F6FB1669D3B356666DD4F5AB201A97561B90EE14C2D89789F2010E054 + 2F32A66AAD1F653D88EB2333258EABF2DBADB98AE5FA3C7897795EEFA8ADDE2B + B2A6C314ED152456F9695D36FBE04F5DA2A9B5AAFBAB75C6C8BA973789E3B282 + 0E693FEC5393D2C4342ADACCB55144F547F3C263838DF2B018175CE7D65EF475 + FF5ED37B33B4300473B316286FD93AE4E4BACC4B1B60F6C587F3DC822DC1C61F + ABC27B409C543B49F81006840FE960E632D239DB751E51BE0973E2E6FF76AF3C + 797FAEBBC49B3FEE929B6F3FE9F346BC95E9E1ABBD8B8C038F9E074550A92E3D + 327DBE6B3DE86345AFA3C40105D87BBDDFDCEE7A4EFA418CC10CB9914B4F0F33 + C8449C7CC98D9D8E72A9798BEBB6067164E0BAB37D2C9BCD62B7D626488A3DE0 + D06F5698903E8EE203FD21DDC2DECDF5387C0913D2E714E0B535958439ED5FBA + 0FF525A3FC83B115D31F3EA421D8DB354EB5FC92D86AE1E04363A7593195D125 + 185C7C398279F3E6F50617EC4611C3C668C287C94DA97ED60245A12BDBC95893 + 22ABCE9216989E44039F3B77AE7BFAE9A7C389317816527F2340EBBEB82F5066 + 9CFA2D09B28AC1068843A6145C8655827473C664BB3C6BBEB056113BC644501B + B10F64860128594CAADDB0449C56BB6C18102CD19C1564C9660840CF186D8CE5 + 8252EC8A62A9D88C359703C693EEC4D1D2961211A7A71B720447ED3E3E12B357 + 1EB5967856602B8A8F38315CF7B436B82B37EBCAC3C7C9E95CB3DF6A65457363 + 30E7F1309851CF5441EBD332636E61B05E7F694DB9BE9E4EAFF0C0993A699F3A + 9A72736210B5BF358CBB6B5239CCEBD94BA1A87BB8ED6966EBFE587C5021371A + BCA8EFBF36E8AAC689AC5F22F0361B4AD7B7C53FF53B827F79E7A281EA3EE039 + 862B8D205F0885C5870D82F724F30865B9ED58F57AAB6BFCC0B567E5E98FE66D + F77289F6E9AE699B456EF08EF35CFAD56737D11F224D6D7BBDA3EAFB25867ADD + 9A0BBF96171BC129B990FE889B923EFAD213AEF7EF3F0BEBD8E8BABD6DB35D63 + F7E6AE69EB853E9E67E4D51561C0B65FCBA6365F113D8EAC3BEF544F000AE163 + CD70B6A2162AEB2EFE866F95A24D32B1DFC7DCD8F46D628DA59C28266BE0EF3F + F2840F7C4AC8FEF2D69E006BC2B582C25B763DBCE8B514FF9619DA58AFA879FF + 0FC78A4B6ABDFBF76E7CDD0BFE59487FF878BE0A30A6B9486A2E95D0179085EE + 2DCBFE9988D3C80B8F85D61DB0AAFD1FE38AF4A4C60F01B5FA831EB6D6E546E7 + 0893D29FB77F5BFE211C43A270098BE8A07B790EFA9DBD160749AE43C803FA83 + A40CE95BF10FEE6D33E789D3C2B345524CC42DD9979833674E6F3018AF996166 + DA20A8C7C04909FF24E4099F3913212E09DF204483C5E184C5E7D8208833A272 + 360BA785D762E396B091ED5CC3122E1A0EDA380CB284F4BD16436C978D9105B6 + 192E3061E246E869C7A64F44BF3ECBA6A539C739E99FB145579E29526B20AB03 + F7E19E2291FFBC3EED16C4D8A06571FA45321DDE43220BD287874B0F96F82BD8 + BC6A497D2C205BD5920465BE2986C6671F4EC4E9587C10287876A6B9AAEB4A1E + EA69777F4AE4AC81E0E3DF86B2B188D35D2D2977CD9B7A0AE243221C597CE077 + 5FF45A6F2C771DCFC5A66FF312B329E1C2036F7A1F8AE1030B501C1C9ED2349A + 97EDE2E360268AD61260495C97DE07F482247ADAEB3EE18CAAB3DEFACEF97488 + 0FDD0F2B972D81C27BA77618710846FAA9DBDCC8DD17E61D466CB801A549264E + 93FE742BE95A748C4BEE7264F580D206F58F5FF9F5C2CAC473C3DD2AE12016B7 + ECC1D8F23BDDF8037FF5F7900E5323D352F840E2660BAAE656FAF1EB0AE2C3EF + 0B1514F2ECFDE329E1FE92D9E56897DC66DFEAD7B7D2F559FBBC6F7742A707ED + 2F9465D11C64D9F045484BC4378974AFBFEAE7213EBC5764D6EEDEE559AD64EE + 3CD7BBEC3818F9ECB13DDE5ED6022837E9E07D97BA8EB7FC734DEBD17FC50F5D + C751E5DBDC28EEB0B17765E855925E1466D943C92817BE8927B216548B0FDCBA + 36DBDEEA0F48199F95800FDE7FF663EDEB24E758EB30FC831A59567F701FF42B + D628C20B7C21D622F890B188763296F405F7C8B55C09369F6E5B2381D3113597 + B024D98C1AFD4BB14B06A30BDB3E70AA8BA4C18AB559B31E3E4D4E7FDA142038 + 589B60931A3C850825DA54307FDBC5D04365F1D84C2153522AFA5AB93297D500 + 5B8645F3D06DB55D1EB065C632BD03089A76EA5AB27454EB223A73CBEE50B1B1 + 869AA7D62FAC2D3231DFF7BFBA3E1621503B8D8B5B1261CD10DD67DB918C3B25 + 533A0B509BFACAF696B0609B00A5CF8A241C52457794E5CD0DBE5971317CF8E2 + 7FC1BF5F78B1D7557B96BAAFBDD9FD7D46CEAD0C3E4E0CC6B77FA67A82F95077 + 9BBB7DBB3955E3A331F8F7B47443AC66BFBF6C1AF7C4123CD9981161155CEBE7 + DC1B7CF05E4A840F6DF41AD329638D55E3E44B3D8DE1BBC47C6D56A70422C9CF + ECC9D3E2A3E3F04FB98659D56DC889CB4E0B098CAE4FDD387DAF932184CD2BE0 + C527C50AA41D7AE266377CD70561528AC68B52679D49AFB7FA43051515F45CAD + A4573DEE466EFC75A83F2033B45A01531A87EEA7362171E6957DF66ED7FAD4D5 + E1A959F7D3FA45F1414D3D4EE08D7317BAF6189BB0CFACBBE81B2E359E2E888F + 72316EFABC5AC4B0BFB42E3ED1B5EC7050D5E3A8EA593C769D6B7CFA86D0AA40 + E15D74E22B6BD7978C6F527CD4E04357E6A5D70FC91AFDEE6F566D0192DB506E + 3FF6535F0268B7234A96419088386DB8F49B6EE69B3FE0D273E3B9F5524F5EE7 + B319DDB1E54B86A87174EBC04BA16E92F1427B29FBA9F641AD1D5620F66A0995 + EA2D3E38B817D21F5A4FBD07B6B0B5B5CE6201B699FA7E3E13FBB1F536E146E6 + 5EAA03A5EB4B675A771D648CEB5B038BC6C521599FB16510D01F817EE84BECBA + EBAEBD01930B89938DAFE0FFAD5B00D64D5033AE2F3A09CB754254BA88934437 + C76AC5E24048B4201A38F7B0F56B04562C4E9ABC75F1D8EC3AE2B3E49BD443A4 + BD8B16470FC7FBD383EFF5A0C9108CC629D9A25AFC3FBF87A0F96275135631B1 + 54CAB82B9DBE1A8BD0BA86A4FBC59B3AF3D238796804BD6BBEAC83884E1C8BD3 + 5DCD291F078415C5A7FF07D7F9C470E9CFC9E2B422203DD18D51E3D92E3DE63E + 369AAA88E88838FDBA35376E5DCB9BF4270A9A091F3457FDE44BBD6EB32A83BA + E5AABB61AB99FE1970FA796F3AE1F68F119325EBD54DB3DFE4DDB3517C40F88B + E1E3B080A81D335AFD3DD70497FD4522ED36B4E44E53E058EF1427A162F8D0F7 + 34B9B6AE3A3DD76A889332FB7ED0DD98870F1BF0CDA1897158B33AD5F36B224E + 83EBDCD065DF298A0F1127FD4C3A456311C18893E5965879AF5B77D3EF438251 + 4A7F682EC2944F4C59F876D7B4C73155DF4F5982EBAFFE45B899703FE939F487 + 4814F1627103B693CFDF1B807769517C40F2C107AE06FD7EFAF15F7389695B55 + 3FB79797E55AAE14C047F70967962CAB30DEBFC6F5FEF934FFBD3EA37937CEAF + FE798EBDFCA4CB36B6B88619732BFAFBD4FD17B9ECAA470AEF2F5DDBB8C4DEC5 + AD477225ABD0A6F039D1E035A773167FC0BB79AB1AF74490B9250872D595AB76 + CEE714303DB8D78783E756652DA9090BA84FE7AFA0D8AADCA91DC9D1BC3D4E5F + 3AC40963C432112641E24135FAC366EF7250B1213D964849AC978AF77682C484 + EF966DD9A2EF459C343659F6203E51FEA135D1B3452FD8C38EF041888FAE61E6 + B5B11C41B4878E4D87B66405F22251C33B0255B5A0B22C59A26503B6459C1894 + F537B35190D1A6EB1180EB41137CAFC9EB21EAE404FB65BC120A77AA33B81406 + 26362D26648FD32425E2A39599119B0A6EC99CAE21E052C78AF9EA776A7551CD + 86B52E1510A7CD3BFDB5691C6BDBDB683C1449D3BABC6FACC1ED97A9FCFA880A + 6C9E9B488704C0D7BAAA208B4D9956ABDB727E66AD25BE6AD6431616C53D9523 + 730F74B5BA4BDA1B437C88405BF20B10E3C470DDDBD6E4FED6DD92878F435F5A + 1BAB2AFA3F0212767D4F5BA820A2596312FEB5F890E86F3E3B94ABDC5DAD2828 + FB82A69C5B14A129A5A4103E38A8501C8E8D51E3F9683AE91656814391B7331A + 46F3F021B164CCCEDD0684EA9D8BE2A3DAE06DC50265AFFD71880F5DCBE2CC26 + 62E81E8D7BBD3B96654669E0ED2B6F0D9BFB424C9917AE01E90F6D060A11D03A + F7EC71B86B587442F5F77BEE7E1F98EDE798D8D8A64944D0EA0FACA5EDFBBD3F + 1E217CE616B7E1AE3F87D68072F8E059FA78CEAD16B8F4E27FAAFA9E1E076B56 + BAC1DBCF73D9DE17C36BFA7B1E756A493223B7D7E07567879F899BA1A6EB8CDC + BFB422B753EE03C19E72E3D9AE69B43F4CF4D1FAFBFD6987C35C72C15B0A7E6C + 2C98A70AA3FA123DD366B9EE9D0EF09F1FEEDCCAA5365F106BED365CF415373E + 3210AE99F05CAEBF9E88F8866BFE2BE7D2EF9AE92B9C576AED92956FEC86B35C + 532687BBF1A3CBC7A18D5DFD434F9C84D7679F7D36ECEFAAF75DFA48BA567A57 + 6B61E39ED9476D2C921F43447F8041BD77C46CDAAE097CA614FFD0F7E21F1C14 + F48C38F85AFD61E336A3FC43FFE2A6E31DD59CB04C62CDA2E79DDEA709834CAE + 006670B1903859F71727CB68F014D607FCC4FA0CC5E3FCC33191EA519FBB4D8D + A761203E5FDC1154F2D4F5F5B0708DE9346A23FBEDF7FAFD44E7E2D0C5872990 + E07029173A2EDB71E2A2B0E992D6B40791A311A944244A20D2E7DE3FDE5815B1 + 59D59874BFD9AC23ECCDA331E10B86E593EDA771BC773411CB05755773D2FD31 + 3B9207E04AB2D8CE0C8853BA2B6701C0C75B081FC76692EEF0B1E224EC9EB646 + F73F83B926B9FF9E6A77CFAAA966309F5B1363BEAA39F8382D9DAA3A6BF0D6E4 + B8BB7C5A5BE84ED43A2E79698DB700552BD70504EF4A97CEC3874A31A8FF1BF8 + 58329ACB860B5EAB4DEA844DCB8CBB2F661A62958C903C9052DC53D6DD96CA86 + AD388487C5BD033EAE6CF958DA5DDF98DBE0295DC129C85AC16471AB06872A43 + F0BD547A1305673B83E3E2B13185107B2AFE838FAA5D69BDABDC4B179EE63F4F + 66A9CD8A89EA8FE685C7F88287D54AF6B1AB5DC3B3B77952C45A69834F4D58C7 + 920A680D88CBB4472E706B5E7EC18F410ABD678FC35CF33EEFADFA7E145A644D + 7D9DA0BD72962BAC7B1DBB1CEC066EFAAD1B7E65B9EBD8E78458D97BAA0D945C + 7E6BD8985DFAA373CE0E6EA87DAB600EEA2336E45A7638C06DB8FC879E3C58B2 + AFE7D7BADB916E64DE9BABBEEFC679DEE6465F7BD66596DF912B7550A67D8808 + CFD0F5BF0C3724B9A9E204DF13ECDFBAD7F1AE79E70AD7AD6F9527105848A4B7 + B506CD87FF87CB766D117B0DAA153DF3D1950F84EFAD2C6EE5E2A5449C866EF8 + D5C6B8B5797B97CC02B4927DEC2AB7F6AE4B73165BB9294F289F18B0E192333D + 71D2DE2C1D43935C5C6E789778FFA3072CC2584AE90FF6757D59379E4DF69244 + 0F3936590BE2851B5CBADBB684B37149C5F807C409EE81C7817648785D740F02 + DCC30298224E1A942D1D20379B0682FFD1D67062122224C447E84BDF33F848A5 + CD3C42622B8E4A61D21B0F02C5BF048D1217A0878858B39F266C2B96628A9542 + D146A3EBD0E5DE5608B556271121DACA58D6CAE2FB3A35C18BC602EB7B29622D + EA892236639507093FD394F2ED42087AE3844FD576FD5C9B236B7974DAC52204 + 970597BF2699DFD747D6A2722D5C449C323D5D61FD0C1BF8C7BF726B684D771C + 18F6AEBB4282C5499F3F7020ED0E5E17B392670151FCD6653DAD79F858F4EA3A + 4FE6EA212F3737BA1F358DE5595C6D5CE03EC926F781811866C10AE4ACAEA6E0 + FE0D617AACBE443284117B82AA36C64B41EAAA1C1E2D1922852785A24391245A + 248ED2161C6678CFAB75A525D7AE70E3B7FEBF507F48D7685ED116078C411B7D + AC1A3A154876DD0B2E136CACB62C4A7A8B3D2AAA4D1447129961D77FF1577335 + ED6266EF552272F3ACBF3CD766C5127EDA4D65773B6ECAD2E145B4545C11FDD1 + 3F6BCF5831645860522D1DAEE3A82F549C9030BEE24E97B9EF2FE1DEA1CF27DE + FEB529993B32F2E8B5BE7FA0C4270A2C38D0B5EC5B9A9CAB348002B66DAF4AB9 + F74A65024A7C298A7BCE0F8BD97AF7D7A19F73D932D5DA459C9AC706C3041E11 + 28ED0394F091BE831744FBC64964BDA5E9AE254C567F48BFE87B4A1BB11EFC2B + 7CE877D1B86A5B338AB21258A445EEA4138BE98F28FF8070E91AC41D129AC33D + 58375C7E6101CCB973E7FAAC3A0607F39B3F7FBE5F2C62962CE323885B8B48E6 + 1DAE31910F58226E3202C66CF56F1E022987BA9EAEAB0722CB11C4478448D7D0 + A0A3554759047C95A4326B2C5A101A0C922953AC9AB9AEB3D34E3BB9E5CB9787 + 80E0772CBAE64619786A3C60AED4495F69FE95CA438D49B774568F5F037D6172 + D418355F6A595096FFE0743656F6D6E54D09774D2ADF77A339952B9428E2343E + BDC77FAF750750E043DF0B1F7AD6DA38E73736BB8F8C6C5AB5FBFE8E16776967 + 8E04EFD03FEC3E38387915CB15977451930BF1A1712CE91B74C7C68837AA44EE + DC6AA6FB73FFBAF0A0C05A4A3841EDA778A7DECA0BB356226AF7F2DB5DE7854A + C19F92039C5B7CF04C441AAB21D80F3638F7BBC67C531F2501B6DB6E3B5F22A1 + 50E57D1F2313BC5FFAD7E2A3DA4ADBC9971F73E3779F176697E91DD6A9CEEA0F + 360B6F51517B8D1835882A11AC37E8321DE8D6B56EE57BA0D54314733372EB1F + 72D6D29D0E71ED7BBFB32EF75130F2E04357E56D3EE8333298D3BB9FE09AA6A0 + ED878853FF6DE77A3DBCFDF6DB078781D92EB567F5AED0F4D3B77957A12F6F32 + 7BE7AA9A4B679EB8C16DBEF6414F26D677CC75C97DDE57F0EFBC8B2B209D93DD + 474E6E4E65B7F97BC85DB9E0007FE02825224EB8EA788EDEF2F3F62F142F9C3A + 3AEC32D7FFC2C79529D647BA433AA4E9ED5F76D9D69E92F7539FC58E443A0CCA + D63E2CB79DB236A9B188CB3B5A33890CD56DB7DDD63DF1C4139BAEEB843EA16E + 22B178CC8B775DFB8B4A36C878608B73730FCA07E9FE74FDA0CF2EFA83383242 + 6DA2FC43E48D7EB8B47ED3F75A2FE1C36610EABAB8057D935F2C4ED1F625FC6B + B37AECE64930A76E40412F2D2E6E26B2C2E87367639EB0088995424678185890 + 88E0D7CF0922B33DBCA2314A9C5AE98DA3C98A296B73C10553A8ED0163C11285 + DBCF5E9F4031CCECFABDAE2BE5AA312BD3AC9A3626F7B537B94B3A9AC2A05A5E + 042AA20B1004A8EAE78704C4298E2545F582AE6BCCFF99EE57AE6E928A220EB5 + B78581ACD675590C1F2D63E3EEA3A3F97594EE0888DBF9A95C6658E7BA3EF7D5 + 6C4BD57328262A80298B13A0D75A1DD03F5237E2F4BD64DABD90DA9834510C1F + 0ABEFFF8608D25D78D3CD89070E7B42537C1871421666EDEA9435515BE8AF9CB + 357861D3A615ADB1AA61FDB5274A365E02912D3E2A0974B59279E67637106C80 + BC9FB2605BFD416C02FAA35C23D65A44357F14B313B61051B6CDBC85BED6503D + 4455BD5B5FBCDBAFA1D6AD61B7A3EA721F6DD2A3AB9F0B0F8D36860C8B8277DD + ED79944BEDFAF6BA8C0191B565E481BF85F76C9CBF9FEB3CE083555F47AE41F7 + E0A5213E06B73EB0ACF5C58AC8A47BFAE6004F87152D37A13835113495C02838 + 86950FB886D64EE7666E57F5F8D53F50714EDEE51410B362F740C65F79CA3758 + 269690828C6A57D379F4A905E39DB20F5EE2FA1FBD719394FDECC1FFE11265FA + 22AA5E972CA2161F36805ABA965243516384D51FB6296FDED826629288372BB6 + BF7877EE44B671317D8BE5487A435EB2A8FE20A4C1C64C322F91376203E11FFC + 8D7E4EA16DC64AAB1C5FC749314E2A80696397EC82E006894E5C6C0D17132E2C + 6223A8D3E0031F2782A8AD6B0DD1C0F440F4794C65C4D5E8E1E8B39A3411F3F8 + 3D19838DE2B7C16461FFA1803861769362B61B40B4843C8B85E28CCE972AC014 + CB84CD6AB1B5611FB6BE4CAA9A91877B3ADC15D3DBC34AA59A2F6B254B824C90 + 58D724DA10E312A76B1BF2DBCD689EA7A71B4A0663AB38E7F8F469A10FDA06E4 + D9921585F071DC582A8C7BBAB2ADC1DDDA91ABFFA1CF7F79C5AB55CFA190AC6A + 48BA8B02BCAFEBCA05C0EA25D23AEE3B3CE6E3C1265BC433BFD4385A141F12BD + 84584EE73534B9235EED75B3466A77DD5DDBD5E2AE6BC8861587F52E091F284F + 09CFE6D04CA22AE228E27441E3F826F8C004CFC1C5C602E262D7FB1FC54725A9 + D556548728F1F0D2306622AA3F28C7401C4325F120718434F928C6A76DBF974B + EC5F1F8B53F37DE7B986DEE77259415BEFE3B2BB4FBE0B92E6C556D745AB4073 + 1AD7BF3376DCD725773ED2652B28921847E4A2527900F61759B92A8DD5B132FE + EC5D2EFBC02579F8E839EE2B95B7AD191DF23143B260BA2D772D3A56113DF511 + B499825AD3E13B2F7043CBEF71D3763ED025F6795F65F734B2E1C6FF0D5B9A34 + 6EB9A3EB3AE2D3A53FB0F21E97518FBF099D4B9658B178A7C6D796B98607FFEC + BFB795EB3D0939F8332ED539B3E4EDD69FFB99C2F808F640480AC6064931FD41 + 79201BDA60F507B166767F89068333062BD1FD98C33BE142B8F7B042C98ACD01 + D30AE13734FAE533942BD1CF7568138F80544D485F62975D76F1759C70A759BF + A52553646E6049A272A70742A0C4095AA541AEAD49236B140F1D72146D7BA209 + 6B63D017C164BA9E4C648A3FB215A2AD582520210B8E380D0AEBF177BAA6B55C + D9BF27A08DA0782D3A63618CFA5ECA4E0B8ECFB35A57DA152DC930D857D741C8 + B2C1CD08E93B2020227108C1DF6774BA1B3243E17362EDCA553A3F7BCB1ED7DF + D21C6E62BC2895E263A7C1B47BD79A7E776D67B3BBA523D7E85473FAF717D7C6 + 6A1D63E58669EDEE9E195D213E046C593AB55E0AE03EA90E314EF727C77D935F + 620528B86AF1C1494CA2974CCF754FC55CD548E496CE9AE69675B484F5D02859 + 608BB3A260AA25D85ACBBF8F8FE4A5134B6C27002C4E3C5B4CDEBC0F161F4ADF + AFCA22F4F8D5FEE4AFE748D62C0A99C2BB6497FA13F38203EB429C6C161C0701 + 29E3EEF98B7C3FB57A48F2EAEFF940746F299FB7C4B5EF57FD065CC9BCFA6FFA + ED263AD26E74D4AC21CD5CBF1B7A534026E61FE8B2ADD3E2DCB6A8888C28C331 + 6C1ABDF9828ADAB44465F8C95BDC865BCEC9C347F3E6DBFA06C625A577956B58 + F5806B79E561FFBFFD070684A5B1708B207A28DAAC37FDFFD02DBFF32D82840F + BD87A3879EEAB20DD559D247D437EFD1AB726124C11A8CEDFBA1D27F1FCCB7EF + E63F8671BCB8AF78471427165ADC025238B0F4DBFE5F52ED257AFEDA5FDA8FFB + 46C992117E99FEB8F199587C5037C9D6B6D3DAB3BF46DDC18C8F46E651FD213D + 494BB34AF617C26ED88F29A62CFD23FD41D35E5B3853E3A676A01D1BEFB99E21 + 73D2DFFAFA7C137FABEBE98BF867537520479C821B745B5355D432239068D1A4 + AC516A98F2F97BE29D740D164842BD92524D79A32FB506A7FB514D9C20325B6B + 2ADADBCAD6DBD16260FE273D97A2851AA71E1001E951164ABD26BD9064F151FB + 043048343E88E241AEC1C739552A588298AFE649CC088530B190E94B29F6E5DA + A4141215BF7C645AAEEC012C5AF728479C6471528D1F89C084E5A1183EF4826A + FC161FB3C7B26ECB4CD6DD92C89D4AF44C3EB26E28CC54AB4694B67F5B6AA3F5 + 0C7C58F22E7CC42598659F5763D65B7D986F217C48781F24648935073F3B703C + E5AD4171B2EE7EDC3CEE03D32D3E28F416AD4BA2C0F06AE67F7973C2DD3D3D87 + 0F4CD1D1982689EE2D8C8A9CA270C080C54766AB856553ABADC85DA5E28212E1 + 837752F7C2C40FA1F2C923DB1F5017E2842584779C122903ADB35CF35BFF6DD2 + EF27AB45E2AAEFFA7979ABC18E0755B56E958A5C529A57A1005E1B3C4B41438D + 47EF1338EED9F940D7326B9E73DB4D4E914A05860F2FBB656378C2163B54159F + 84C885367ACFC57E0FA0C0A7CF022D52DE406505D46B2E1D104936DD19F37673 + E925858B802A0EC9BB6E27F697CEF77CD7932691EBB1E1DC264D3674C3920FBA + E62AEB39B9DE175DEB3D7FC81D7E02E2540E6354BEC7DB41991A2B228DA91973 + 0A36E8D558F58CFDDEF2E653CA06878B38A1E7F545E167D6190B11D69A72FA43 + 9FB789248C1D17202E314275A2FB8BEEA13597FE019BF68BC2949493D1DE4FE8 + 8E7E2EF213AD9E6F25CA3FF43959F529004A2CA7493CEB4B2C5CB8B037D808BA + F50B52B1ED859888360B0DC0D6648045EAE25A4432CDC8B881CCA8BE42D4445C + 4A2CC9E1452E14946BD3E35940DF8075A2A603A65C8D47AC54FF52EC4EE314F1 + 81B9DBF9622963A3B05976F84715F50FA1D3C6C283D2BA88D947155529212B50 + 7386CC5970155B338D479FD31C54F59A2AE9582270296A4DA86D556CBE1081E8 + FD3437AD9BD682AAAC517C509A82520D3C0FDD0B92AA7169DD67BFB2C6CD6E0E + 4E79C1F2A8E170CF68E1D8309115C903A95C13DA62F8E045B6D56B4BE14363D0 + 7AA8182AE66B0AA9D1EA04F7B27E5668BD38E996C3877EA6778A8AD1F3D2636E + E6E0B06BD93050B2506774EE647112E3442A70397CF0DE6ABCA5F0A135A0FD44 + 317C501768B2F141156799C3F55C8441326E704708BB3623A694102FE9E3EA82 + 7BE206A7A489C507EF90047211C587BED7D838D5B25E32FF97C287D60BABB1C5 + 07AD20148F410801961E7469B4D342B9F90A0B24AF1037520E1FBC1BB41352E0 + 2F3DC6C034C1B7DE1DD63FEADD5AA964A0E7662DA828685ABDF49A7A9F774D01 + 6E075E7BDEF53D7E6B497C587C45F1413CACFEA6143E3ADE7EAA2710FE990664 + 67F8D16BBCE52D8A0FF609ADB7D6CAE2C362C43FB3ADF774C3CBEFC9D5B09BF0 + 8A2870994363217CE819DA9A61A5F061B3CEC000C55FB1D6830FAD85B017B536 + 2BB3B079C1FEBED279217C5004BA52FD013EF4398D2B8A0FF407212ED21F1A37 + 7158D1F9127663C363F4BD080A6B4199954AF0C175A9FDA8B5D738A463A88567 + F151E8DD2FF63E6161A3C06F547F38599CD4E4379868B71D5074D36763D79714 + 0A0F5217D503D684051682A679E0A4F5522E9DFA49E5060EA325E30E50D97A0F + D15E53A40E6A8C224D32AFA10C998F9494DD44F96C54F4392C1A028CAEC538A4 + F0F07B9281A3B969DED6CC8F39B39207851FD9B602B0BF8FC686215A1F1A216F + BDF5D6612F35366FAB440164F4F4C9B53991E8A5D41CF1F942E4CAE183D387F0 + A16B49A80E1EC587AEAD9F810FCD813156820F02F9211258A12AC587C6A8CC09 + 8B0FCD4B988DAE75297C683EBA96DE01DCB8E00312A6E7C9690AB730C90E5125 + 516CBED418AB161FB42F2A840F6B4164EDED09CEE243427D295D2B0E3EA48035 + 1EBD9B52961C0E840FAD3B75D230DF17C287ED1F18171FA47317C2071B9AC648 + 666F5CFDC189155D447564116AF0A1F96B5EB6F0EA64E1C3C66BD93A38F6B9EA + 7D257856F840C7597CD8D65BA5F0A1F9EA33C2879E2956C938F8D01AE1B2D5B5 + B4EE1A2B19CDBAB6880A73677FF101C1ED337C2664943015C287D68CF7B6127C + 084FC269217C58FD51293E24DAD4C107F5CC2087645D13F3CB5E11071F1A3B16 + 7A8B8F52FA83B019F0C15A598F4D35F8A05F9DF447141FD18295517C68BFD51C + B45EE043F7D6F764A3EBB3E85B8B8FB8FAC3E2C31A467C39028853A101475F32 + 3D4C6298000003A40E91365E32E56C5A310FBB52B1E98936CBCD16B7B28164FA + 3B6D60C42EB129003E029A71ED4503D0A222C546014D168C4260366B504AD0F6 + 19637C36B6AADC3C0132EB6A41542813909F6BF3E7E4806B8FA26436C5D3662A + 147AD9F47301130B1F85C08809B3E32A063CF06183FD8AE183603ED25909E2AB + 061FAC11CFB5127C484151220352C989338A0FD6A5D8F3D35CA558E87956081F + 9878C187AD904B25FB7296053B866AF0A1B566BE58BE20F671F0A1F7010B8EAD + 7526A56533B58AE143EF1264A190FE20BE412775BA06D8C2B8B803A70A1F2467 + 44F161EBD214C307EBC58995FB820FEAB5597CF0CCD88CB13CD4131FD21F6C60 + C4914D063EAC1B45FAA35A7C802FCD87961AB86ED11F5867C0076D36EA890FF4 + ADC64285698B8F4285958BE143FA836C60744E141FBA8EBC3CD28D161F90BC7A + E2834E19BC73940D2021A4103E6C467AA1F9B29FDAAC3BE1A3902BB9183E4846 + 613E182CD0DD22EEF47F8D8B0F6B15B389509289B1F625E6CC99D31B3C846E80 + 5E6C21F1FD6B00044AD98AD2BEDAF29C399E11421878C8DA9065A57AE699672A + B22A704F365C2660BB8A03685B1994C5822C011ADB119D6B5ACB44A1D39884AC + BCA8C91D22A9D3904CB6F64597E8D4A0CFAA2E54B9F95AE6CF43E3C52350DD66 + 1544B308B5A1D80C07BB3923D172F5D1970D60510D5A2F49D4245A093E08C6A7 + 70A2C587AE317BF66C8F0F7CE1C4A669ADF4D9D7131FB4A6A8161FFA3D81DAF6 + B9E845D7C94AF860ED78463A7D69AD850F08F81B051F5CA3183EB46E90747B0F + 1454297C4807E8F94A7FB0CEAC8D36076D4C3ACD1353083EA4772A7D9FEC3D6D + 2B19C8B95DAF52F8B0AE8C283ED8C0CAE143E3D6DF47F141DD2F9D96A3F8D0EF + 851BE997152B56D4840FCD970DB91A7CD88EF5B5E2C3622E0E3E7876DA0CB591 + 830FDE73FD9D3EA77B6BBDA60A1F85F407F7AE061F12B2E4A295F9A527700972 + C0D4F7DA7774B8A8051F247C58B75D317C400C6BC1073D69A98F14C507D8AF04 + 1F742BB10607AD870C27F200586226D17EACF749ED6326091FB93A4EC1DF75B3 + 593078DBF0CE9A2DF10F33606EE0B350264AB4032A5BDA20CA90A3E50FAC6999 + 9702B6A7DFD39A4583D7E2F062619182B55AA0D8DF59E51ECD1E8AF672E27B94 + 99E68B72E3FAC41490ED677DEE58576C365FA1562E1664D68D664DB9BA073162 + B605859D4BF41949A8690569B1CA939794978875647EBC50F639597C9049C629 + C3CEA7183EF4336D16C2873DB154830FBB7EC5F0A1B1DBF5AA151F51E567D7B8 + 143E3457DCA8517C605D992A7C70DD4AF061094DA5F840C194C3079B12E507A2 + F8200EAA103E582F4B40E2E243FAC336318FE2C3EAA0C9C487DD58883911A92A + 840F1B845F2D3EF4B7E043F7A082F31B091FACAFBD77297CE867044647F161AB + BDC7C1877E277C689ED5E003628F3599F14E063E18CF64E383EF850F9E95F407 + EF986DCE6BD7F08D880F4B70A7021F7A97F415E063A3AB8E05610161D076B12D + D9B000B17DE77898B82C2C838B02CA6E905600110181285681882AE2D1829AA5 + 5C8D88DD3099ABDDC4A240E3FFA3F700287A503439C464688997F521DBB9150A + 62B6D980947927989646AFCC97135C25FEDA42AE057CDDD10043FB7C2D1EEC0B + C39A11B316071F12623E6AC10701811077E1C2E223EA2228870FE617C5473413 + A45A7C109B512B3EB0E831E7C9C2878DF542F1592513FD4CADF8B0789C2C7CD8 + DF17C207159089D9606CAF173E4852990C7C40DA8BE1C306DDDA90827252081F + 6C72C5DC4476BC51FDC3B3B6169A284E2BC187FE9E98B0C9C007C521DF88F880 + 1CD862C9E5F0116D448E1E245B5473D5E764F9C15D66F5C764E223BA6E85F061 + 5D75B5E2C3763289E2C3DEB3127CC8C2C55E1CC1475F629B6DB6591FFC61274C + 90A252D6426182A28A82459B8406AECF8B34E19B8E7EC6BA58B807BE75DB9645 + 425C032E3382E4A828CA670046B98D8245011C2CA4BDBF6D041805098B8CE54B + 4014A0E5DA82409502980D26A41BB37DA8CC97E2A2C42BF16C6C406035F3E554 + C067204EB8E04AC51E58171F715B94A7E733D6B5556CEE346C2E870F7B422885 + 0F6B36D773D0CFDF48F8C002AB790A1FD6FA12071F76BE517C809DC9C447B42A + 79297CD8869C95E023BAC9D5131F1A0F5958BAF61B151FA5F46BA5F8B0FA8358 + 32825B2D3ED0AF53890FFB3CC047D49A5D093E341FAD59B5F820E3AB103EC8C2 + 2A858F4241DE95E2234A04AAC187DE05EA9B95C3872520161F3C2330A0F9122B + 043ED02DD6951F071F76BD27031F85AC5D85F0418918CD476B06D12CC43F4C59 + 81AAF041924FB03E1B54397C55F0C7DDB02CB20788F247E14707004B6353A5C4 + B92D7E59886DB200360817D33EA638CC6C02B1E200746D999BB9A6EDA06C8315 + 2B3911D81795974CD62C9A0316F3D3F2FF36B8970527A0B4D8E99C75E07BD653 + 5FB69898BE971F5FE392758DD60F6CB8BC0C9504D359B1F3A5AB34A527A29987 + 85D6CB0652820FDFF76842515B5F70BDF161B333B5F6C2077EEF7AE083AEF3E0 + 239A6955293E0AF9D62BC1070AC8E243F7D0A9181712D79A4C7C683347894E06 + 3EAAD11FF61996C2878DAF2C860FC583E86FDF88F8C012110D402D870FF46374 + BEF4BDD4BF90B142F8C0053255F8E0F353890F4B44A2EB85AEA62C847E4775FA + 42F86003AF442AC147314B5D217C08C3C562C3A2F32D860F0EC804B8EB9A7A7E + C5F4471C7CF05C742FCDD7E2A3D4B5AC11C5662F568B0FE6510E1F763C95E243 + 42F5F1896BF7FD7F43AD0EBDFA2406840000000049454E44AE426082} + Stretch = True + ExplicitLeft = -8 + ExplicitTop = 8 + end + object ImgLoad: TImage + Left = 627 + Top = 8 + Width = 105 + Height = 105 + Transparent = True + Visible = False + end + object PageControl1: TPageControl + Left = 0 + Top = 169 + Width = 740 + Height = 344 + ActivePage = TabSheet2 + Align = alTop + TabOrder = 0 + object TabSheet2: TTabSheet + Caption = 'Config' + ImageIndex = 1 + object Label1: TLabel + Left = 3 + Top = 3 + Width = 29 + Height = 13 + Caption = 'Token' + end + object Label2: TLabel + Left = 410 + Top = 3 + Width = 89 + Height = 13 + Caption = 'Destination user id' + end + object Label4: TLabel + Left = 410 + Top = 49 + Width = 57 + Height = 13 + Caption = 'Game Name' + end + object Label5: TLabel + Left = 3 + Top = 49 + Width = 55 + Height = 13 + Caption = 'Bank Token' + end + object Label3: TLabel + Left = 3 + Top = 95 + Width = 52 + Height = 13 + Caption = 'Bot Logger' + end + object txtToken: TEdit + Left = 3 + Top = 22 + Width = 401 + Height = 21 + PasswordChar = '*' + TabOrder = 0 + TextHint = 'Fill in this field with your bot token' + end + object Button2: TButton + Left = 575 + Top = 18 + Width = 75 + Height = 25 + Caption = 'Start' + TabOrder = 1 + OnClick = Button2Click + end + object Button3: TButton + Left = 652 + Top = 18 + Width = 75 + Height = 25 + Caption = 'Stop' + TabOrder = 2 + OnClick = Button3Click + end + object txtID: TEdit + Left = 410 + Top = 22 + Width = 159 + Height = 21 + TabOrder = 3 + TextHint = 'User ID' + end + object txtNomeJogo: TEdit + Left = 410 + Top = 68 + Width = 159 + Height = 21 + TabOrder = 4 + TextHint = 'Game Name' + end + object btnComoSaberID: TButton + Left = 575 + Top = 66 + Width = 137 + Height = 25 + Caption = 'How to know my id?' + Default = True + TabOrder = 5 + OnClick = btnComoSaberIDClick + end + object txtTokenBanco: TEdit + Left = 3 + Top = 68 + Width = 401 + Height = 21 + PasswordChar = '*' + TabOrder = 6 + TextHint = 'Fill in this field with the bank'#39's token' + end + object cbDisableNotification: TCheckBox + Left = 289 + Top = 45 + Width = 115 + Height = 17 + Caption = 'Disable Notification' + TabOrder = 7 + end + object cbProtectedContent: TCheckBox + Left = 168 + Top = 45 + Width = 115 + Height = 17 + Caption = 'Protected Content' + TabOrder = 8 + end + object memConsole: TMemo + Left = 3 + Top = 114 + Width = 732 + Height = 202 + ScrollBars = ssBoth + TabOrder = 9 + end + end + object TabSheet1: TTabSheet + Caption = 'SendMethods' + object btnEnviarVenue: TButton + Left = 289 + Top = 34 + Width = 137 + Height = 25 + Caption = 'Send Venue' + Default = True + TabOrder = 0 + OnClick = btnEnviarVenueClick + end + object btnEnviarLocalizacao: TButton + Left = 146 + Top = 34 + Width = 137 + Height = 25 + Caption = 'Send Location' + Default = True + TabOrder = 1 + OnClick = btnEnviarLocalizacaoClick + end + object btnEnviaTexto: TButton + Left = 3 + Top = 3 + Width = 137 + Height = 25 + Caption = 'Send Text' + Default = True + TabOrder = 2 + OnClick = btnEnviaTextoClick + end + object btnEnviaFoto: TButton + Left = 146 + Top = 3 + Width = 137 + Height = 25 + Caption = 'Send Photo' + Default = True + TabOrder = 3 + OnClick = btnEnviaFotoClick + end + object btnEnviaAudio: TButton + Left = 289 + Top = 3 + Width = 137 + Height = 25 + Caption = 'Send Audio' + Default = True + TabOrder = 4 + OnClick = btnEnviaAudioClick + end + object btnEnviarDocumento: TButton + Left = 3 + Top = 34 + Width = 137 + Height = 25 + Caption = 'Send File' + Default = True + TabOrder = 5 + OnClick = btnEnviarDocumentoClick + end + object Button5: TButton + Left = 575 + Top = 159 + Width = 137 + Height = 25 + Caption = 'Send SlotMachine' + Default = True + TabOrder = 6 + OnClick = Button5Click + end + object btnEnviarVideo: TButton + Left = 432 + Top = 3 + Width = 137 + Height = 25 + Caption = 'Send V'#237'deo' + Default = True + TabOrder = 7 + OnClick = btnEnviarVideoClick + end + object btnEnviarNotaDeVideo: TButton + Left = 575 + Top = 3 + Width = 137 + Height = 25 + Caption = 'Send Voice Note' + Default = True + TabOrder = 8 + OnClick = btnEnviarNotaDeVideoClick + end + object btnEnviarVoz: TButton + Left = 432 + Top = 34 + Width = 137 + Height = 25 + Caption = 'Send Voice' + Default = True + TabOrder = 9 + OnClick = btnEnviarVozClick + end + object btnEnviarJogo: TButton + Left = 3 + Top = 65 + Width = 137 + Height = 25 + Caption = 'Send Game' + Default = True + TabOrder = 10 + OnClick = btnEnviarJogoClick + end + object btnEnviarDado: TButton + Left = 575 + Top = 252 + Width = 137 + Height = 25 + Caption = 'Send Dice' + Default = True + TabOrder = 11 + OnClick = btnEnviarDadoClick + end + object btnEnviarStiker: TButton + Left = 575 + Top = 34 + Width = 137 + Height = 25 + Caption = 'Send Stiker' + Default = True + TabOrder = 12 + OnClick = btnEnviarStikerClick + end + object btnEnviarContato: TButton + Left = 146 + Top = 65 + Width = 137 + Height = 25 + Caption = 'Send Contact' + Default = True + TabOrder = 13 + OnClick = btnEnviarContatoClick + end + object btnEnviarPoll: TButton + Left = 575 + Top = 65 + Width = 137 + Height = 25 + Caption = 'Send Poll' + Default = True + TabOrder = 14 + OnClick = btnEnviarPollClick + end + object btnEnviarAcao: TButton + Left = 3 + Top = 96 + Width = 137 + Height = 25 + Caption = 'Send Action' + Default = True + TabOrder = 15 + OnClick = btnEnviarAcaoClick + end + object btnEnviarDardo: TButton + Left = 575 + Top = 221 + Width = 137 + Height = 25 + Caption = 'Send Dart' + Default = True + TabOrder = 16 + OnClick = btnEnviarDardoClick + end + object btnEnviarAnimacao: TButton + Left = 289 + Top = 65 + Width = 137 + Height = 25 + Caption = 'Send Animation' + Default = True + TabOrder = 17 + OnClick = btnEnviarAnimacaoClick + end + object btnEnviarTxtComBt: TButton + Left = 3 + Top = 159 + Width = 137 + Height = 25 + Caption = 'Send Text w/ Buttons' + Default = True + TabOrder = 18 + OnClick = btnEnviarTxtComBtClick + end + object btnEnviarTxtComBTInline: TButton + Left = 146 + Top = 159 + Width = 151 + Height = 25 + Caption = 'Send Text w/ Inline Buttons ' + Default = True + TabOrder = 19 + OnClick = btnEnviarTxtComBTInlineClick + end + object btnApagarBotoes: TButton + Left = 3 + Top = 190 + Width = 137 + Height = 25 + Caption = 'Send Text & Erase Buttons' + Default = True + TabOrder = 20 + OnClick = btnApagarBotoesClick + end + object Button1: TButton + Left = 575 + Top = 283 + Width = 137 + Height = 25 + Caption = 'Send BasketBall' + Default = True + TabOrder = 21 + OnClick = Button1Click + end + object btnEnviarGrpMidias: TButton + Left = 146 + Top = 96 + Width = 113 + Height = 25 + Caption = 'Send Media Group' + Default = True + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -9 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + TabOrder = 22 + OnClick = btnEnviarGrpMidiasClick + end + object btnADD: TButton + Left = 258 + Top = 96 + Width = 25 + Height = 25 + Caption = '+' + Default = True + TabOrder = 23 + OnClick = btnADDClick + end + object btnEnviarInvoice: TButton + Left = 432 + Top = 65 + Width = 137 + Height = 25 + Caption = 'Send Invoice' + Default = True + TabOrder = 24 + OnClick = btnEnviarInvoiceClick + end + object Button4: TButton + Left = 575 + Top = 190 + Width = 137 + Height = 25 + Caption = 'Send FootBal' + Default = True + TabOrder = 25 + OnClick = Button4Click + end + object Button8: TButton + Left = 3 + Top = 267 + Width = 137 + Height = 25 + Caption = 'Send OrderFood' + Default = True + TabOrder = 26 + OnClick = Button8Click + end + object Button9: TButton + Left = 3 + Top = 236 + Width = 137 + Height = 25 + Caption = 'Send OrderFood Inline' + Default = True + TabOrder = 27 + OnClick = Button9Click + end + object Button10: TButton + Left = 289 + Top = 96 + Width = 137 + Height = 25 + Caption = 'Send Spoiler Photo' + Default = True + TabOrder = 28 + OnClick = EnviarFotoSpoilerClick + end + object SendTextTopic: TButton + Left = 146 + Top = 190 + Width = 151 + Height = 25 + Caption = 'Send Text for Topic' + Default = True + TabOrder = 29 + OnClick = SendTextTopicClick + end + end + object TabSheet3: TTabSheet + Caption = 'OtherMethods' + ImageIndex = 2 + object btnGetCMD: TButton + Left = 3 + Top = 3 + Width = 137 + Height = 25 + Caption = 'GetMyCommands' + Default = True + TabOrder = 0 + OnClick = btnGetCMDClick + end + object btnCommands: TButton + Left = 146 + Top = 3 + Width = 137 + Height = 25 + Caption = 'SetMyCommands' + Default = True + TabOrder = 1 + OnClick = btnCommandsClick + end + object btnDeleteCommands: TButton + Left = 289 + Top = 3 + Width = 137 + Height = 25 + Caption = 'DeleteMyCommands' + Default = True + TabOrder = 2 + OnClick = btnDeleteCommandsClick + end + object btnSolicitarCtt: TButton + Left = 3 + Top = 65 + Width = 137 + Height = 25 + Caption = 'Get Contact' + Default = True + TabOrder = 3 + OnClick = btnSolicitarCttClick + end + object btnSolicitarLocalizacao: TButton + Left = 146 + Top = 65 + Width = 137 + Height = 25 + Caption = 'Get Location' + Default = True + TabOrder = 4 + OnClick = btnSolicitarLocalizacaoClick + end + object Button6: TButton + Left = 3 + Top = 189 + Width = 137 + Height = 25 + Caption = 'Send Thread' + Default = True + TabOrder = 5 + OnClick = Button6Click + end + object Button7: TButton + Left = 146 + Top = 189 + Width = 137 + Height = 25 + Caption = 'Send Thread Loop' + Default = True + TabOrder = 6 + OnClick = Button7Click + end + object GetForumStikersTopic: TButton + Left = 289 + Top = 65 + Width = 137 + Height = 25 + Caption = 'Get Topic Stiker' + Default = True + TabOrder = 7 + OnClick = GetForumStikersTopicClick + end + object btnSetMyDefaultAdministratorRights: TButton + Left = 472 + Top = 46 + Width = 137 + Height = 25 + Caption = 'setAdministratorRights' + Default = True + TabOrder = 8 + OnClick = btnSetMyDefaultAdministratorRightsClick + end + object btnGetAdministratorRights: TButton + Left = 472 + Top = 77 + Width = 137 + Height = 25 + Caption = 'getAdministratorRights' + Default = True + TabOrder = 9 + OnClick = btnGetAdministratorRightsClick + end + object CriarTopico: TButton + Left = 3 + Top = 96 + Width = 137 + Height = 25 + Caption = 'Create Topic' + Default = True + TabOrder = 10 + OnClick = CriarTopicoClick + end + object EditarTopico: TButton + Left = 146 + Top = 96 + Width = 137 + Height = 25 + Caption = 'Edit Topic' + Default = True + TabOrder = 11 + OnClick = EditarTopicoClick + end + object btnSetChatMenuButton: TButton + Left = 3 + Top = 158 + Width = 137 + Height = 25 + Caption = 'setChatMenuButton' + Default = True + TabOrder = 12 + OnClick = btnSetChatMenuButtonClick + end + object btnGetChatMenuButton: TButton + Left = 146 + Top = 158 + Width = 137 + Height = 25 + Caption = 'getChatMenuButton' + Default = True + TabOrder = 13 + OnClick = btnGetChatMenuButtonClick + end + object btnAnswerWebAppQuery: TButton + Left = 3 + Top = 127 + Width = 137 + Height = 25 + Caption = 'answerWebAppQuery' + Default = True + TabOrder = 14 + OnClick = btnAnswerWebAppQueryClick + end + object cbRightsAdmin: TCheckBox + Left = 472 + Top = 0 + Width = 115 + Height = 17 + Caption = 'Administrator Rights' + TabOrder = 15 + end + object cbChanel: TCheckBox + Left = 472 + Top = 23 + Width = 58 + Height = 17 + Caption = 'Chanel' + TabOrder = 16 + end + object btnGetCMD2: TButton + Left = 3 + Top = 34 + Width = 137 + Height = 25 + Caption = 'GetMyCommands2' + Default = True + TabOrder = 17 + OnClick = btnGetCMD2Click + end + object Button11: TButton + Left = 146 + Top = 34 + Width = 137 + Height = 25 + Caption = 'SetMyCommands2' + Default = True + TabOrder = 18 + OnClick = Button11Click + end + object Button12: TButton + Left = 289 + Top = 34 + Width = 137 + Height = 25 + Caption = 'DeleteMyCommands2' + Default = True + TabOrder = 19 + OnClick = Button12Click + end + object btnSetMyName: TButton + Left = 3 + Top = 241 + Width = 137 + Height = 25 + Caption = 'setMyName for Bot' + Default = True + TabOrder = 20 + OnClick = btnSetMyNameClick + end + object btnGetMyName: TButton + Left = 3 + Top = 272 + Width = 137 + Height = 25 + Caption = 'getMyName for Bot' + Default = True + TabOrder = 21 + OnClick = btnGetMyNameClick + end + end + end + object InjectTelegramExceptionManagerUI1: TInjectTelegramExceptionManagerUI + OnLog = InjectTelegramExceptionManagerUI1Log + Left = 488 + Top = 438 + end + object cuHttpClientSysNet1: TcuHttpClientSysNet + Left = 488 + Top = 322 + end + object AbrirArquivo: TOpenDialog + Filter = 'Imagens|*.jpeg;*.jpg;*.gif;*.png;*.bmp' + FilterIndex = 0 + Left = 608 + Top = 322 + end + object InjectTelegramBot1: TInjectTelegramBot + Logger = InjectTelegramExceptionManagerUI1 + HttpCore = cuHttpClientSysNet1 + IsBusy = False + OnReceiveRawData = InjectTelegramBot1ReceiveRawData + OnSendData = InjectTelegramBot1SendData + OnDisconect = InjectTelegramBot1Disconect + Left = 488 + Top = 382 + end + object BotManager1: TInjectTelegramBotManager + Bot = InjectTelegramBot1 + TimeOutMessage = + 'Ol'#225', notei que nossa conversa atingiu o tempo limite de inativid' + + 'ade, caso n'#227'o se comunique comigo mais, nossa conversa se encerr' + + 'ar'#225' automaticamente!' + TimeOutAutoIncSeconds = 30 + Simultaneous = 0 + InactivityTimeMinute = 0 + InactivityNotice = False + OnStart = ServiceStart + OnStop = ServiceStop + OnMessage = ReceiverMessage + OnChosenInlineResult = ChosenInlineResult + OnCallbackQuery = ReceiverCallbackQuery + OnForumTopicCreated = BotManager1ForumTopicCreated + OnForumTopicClosed = BotManager1ForumTopicClosed + OnForumTopicEdited = BotManager1ForumTopicEdited + OnForumTopicReopened = BotManager1ForumTopicReopened + OnGeneralForumTopicHidden = BotManager1GeneralForumTopicHidden + OnGeneralForumTopicUnhidden = BotManager1GeneralForumTopicUnhidden + OnMessageEntityReceiver = BotManager1MessageEntityReceiver + OnWebAppData = BotManager1WebAppData + Left = 360 + Top = 400 + end +end diff --git a/v1.4.4/Exemplo/uPrincipal.pas b/v1.4.4/Exemplo/uPrincipal.pas new file mode 100644 index 0000000..6cb6653 --- /dev/null +++ b/v1.4.4/Exemplo/uPrincipal.pas @@ -0,0 +1,2502 @@ +unit uPrincipal; +interface +uses + Winapi.Windows, Winapi.Messages, System.SysUtils, + System.Variants, System.Classes, + Vcl.Graphics, + Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, + CrossUrl.Indy.HttpClient, + CrossUrl.SystemNet.HttpClient, + TInjectTelegram.UpdateParser, + TInjectTelegram.Receiver.Base, + TInjectTelegram.Receiver.Service, + TInjectTelegram.Receiver.UI, + TInjectTelegram.Logger, + TInjectTelegram.Logger.Old, + TInjectTelegram.Base, + TInjectTelegram.Types, {Uso Especifico} + TInjectTelegram.Types.Impl, {Uso Especifico} + TInjectTelegram.Types.Enums, {Uso Especifico} + TInjectTelegram.Types.ReplyMarkups,{Uso Especifico} + TInjectTelegram.Bot, {Uso Especifico} + TinjectTelegram.Emoji, {para usar os Emojis} + TInjectTelegram.Bot.Impl, + TinjectTelegram.Types.InlineQueryResults, + TinjectTelegram.Types.InputMessageContents, + TinjectTelegram.Utils.JSON, + Vcl.Imaging.pngimage, uResourceString, TInjectTelegram.Bot.Manager, + //Use JSON with X-SuperObject + XSuperJSON, + XSuperObject, + + System.Json, REST.Json, REST.JsonReflect, REST.Json.Types, Vcl.ComCtrls; +type + + TMessageToSend = record + chatId: Int64; + Text: String; + ParseMode: TtdParseMode; + end; + + TForm1 = class(TForm) + Image1: TImage; + InjectTelegramExceptionManagerUI1: TInjectTelegramExceptionManagerUI; + cuHttpClientSysNet1: TcuHttpClientSysNet; + AbrirArquivo: TOpenDialog; + ImgLoad: TImage; + InjectTelegramBot1: TInjectTelegramBot; + BotManager1: TInjectTelegramBotManager; + PageControl1: TPageControl; + TabSheet2: TTabSheet; + TabSheet1: TTabSheet; + btnEnviarVenue: TButton; + btnEnviarLocalizacao: TButton; + btnEnviaTexto: TButton; + btnEnviaFoto: TButton; + btnEnviaAudio: TButton; + btnEnviarDocumento: TButton; + Button5: TButton; + btnEnviarVideo: TButton; + btnEnviarNotaDeVideo: TButton; + btnEnviarVoz: TButton; + btnEnviarJogo: TButton; + btnEnviarDado: TButton; + btnEnviarStiker: TButton; + btnEnviarContato: TButton; + btnEnviarPoll: TButton; + btnEnviarAcao: TButton; + btnEnviarDardo: TButton; + btnEnviarAnimacao: TButton; + btnEnviarTxtComBt: TButton; + btnEnviarTxtComBTInline: TButton; + btnApagarBotoes: TButton; + Button1: TButton; + btnEnviarGrpMidias: TButton; + btnADD: TButton; + btnEnviarInvoice: TButton; + Button4: TButton; + Button8: TButton; + Button9: TButton; + Button10: TButton; + SendTextTopic: TButton; + Label1: TLabel; + Label2: TLabel; + Label4: TLabel; + Label5: TLabel; + txtToken: TEdit; + Button2: TButton; + Button3: TButton; + txtID: TEdit; + txtNomeJogo: TEdit; + btnComoSaberID: TButton; + txtTokenBanco: TEdit; + cbDisableNotification: TCheckBox; + cbProtectedContent: TCheckBox; + memConsole: TMemo; + Label3: TLabel; + TabSheet3: TTabSheet; + btnGetCMD: TButton; + btnCommands: TButton; + btnDeleteCommands: TButton; + btnSolicitarCtt: TButton; + btnSolicitarLocalizacao: TButton; + Button6: TButton; + Button7: TButton; + GetForumStikersTopic: TButton; + btnSetMyDefaultAdministratorRights: TButton; + btnGetAdministratorRights: TButton; + CriarTopico: TButton; + EditarTopico: TButton; + btnSetChatMenuButton: TButton; + btnGetChatMenuButton: TButton; + btnAnswerWebAppQuery: TButton; + cbRightsAdmin: TCheckBox; + cbChanel: TCheckBox; + btnGetCMD2: TButton; + Button11: TButton; + Button12: TButton; + btnSetMyName: TButton; + btnGetMyName: TButton; + procedure btnEnviaTextoClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + procedure ServiceStart(Sender: TObject); + procedure ServiceStop(Sender: TObject); + procedure InjectTelegramExceptionManagerUI1Log(ASender: TObject; + const Level: TLogLevel; const Msg: string; E: Exception); + procedure btnEnviaFotoClick(Sender: TObject); + procedure btnEnviaAudioClick(Sender: TObject); + procedure btnEnviarDocumentoClick(Sender: TObject); + procedure btnEnviarVideoClick(Sender: TObject); + procedure btnEnviarVozClick(Sender: TObject); + procedure btnEnviarNotaDeVideoClick(Sender: TObject); + procedure btnEnviarLocalizacaoClick(Sender: TObject); + procedure btnEnviarVenueClick(Sender: TObject); + procedure btnEnviarContatoClick(Sender: TObject); + procedure btnEnviarPollClick(Sender: TObject); + procedure btnEnviarDadoClick(Sender: TObject); + procedure btnEnviarStikerClick(Sender: TObject); + procedure btnEnviarJogoClick(Sender: TObject); + procedure btnEnviarAcaoClick(Sender: TObject); + procedure btnEnviarInvoiceClick(Sender: TObject); + procedure btnEnviarGrpMidiasClick(Sender: TObject); + procedure btnEnviarTxtComBtClick(Sender: TObject); + procedure btnEnviarTxtComBTInlineClick(Sender: TObject); + procedure btnApagarBotoesClick(Sender: TObject); + procedure ReceiverCallbackQuery(ASender: TObject; + ACallbackQuery: ItdCallbackQuery); + procedure ReceiverMessage(ASender: TObject; + AMessage: ItdMessage); + procedure ChosenInlineResult(ASender: TObject; + AChosenInlineResult: ItdChosenInlineResult); + procedure btnEnviarAnimacaoClick(Sender: TObject); + procedure btnEnviarDardoClick(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure btnSolicitarCttClick(Sender: TObject); + procedure btnSolicitarLocalizacaoClick(Sender: TObject); + procedure btnComoSaberIDClick(Sender: TObject); + procedure btnADDClick(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure Button1Click(Sender: TObject); + procedure Button4Click(Sender: TObject); + procedure Button5Click(Sender: TObject); + procedure InjectTelegramBot1ReceiveRawData(ASender: TObject; + const AData: string); + procedure btnCommandsClick(Sender: TObject); + procedure InjectTelegramBot1SendData(ASender: TObject; const AUrl, + AData: string); + procedure btnGetCMDClick(Sender: TObject); + procedure btnDeleteCommandsClick(Sender: TObject); + procedure InjectTelegramBot1Disconect(ASender: TObject; + const AErrorCode: string); + procedure btnSetChatMenuButtonClick(Sender: TObject); + procedure btnGetChatMenuButtonClick(Sender: TObject); + procedure btnSetMyDefaultAdministratorRightsClick(Sender: TObject); + procedure btnGetAdministratorRightsClick(Sender: TObject); + procedure btnAnswerWebAppQueryClick(Sender: TObject); + procedure Button6Click(Sender: TObject); + procedure Button7Click(Sender: TObject); + procedure Button8Click(Sender: TObject); + procedure Button9Click(Sender: TObject); + procedure EnviarFotoSpoilerClick(Sender: TObject); + procedure BotManager1ForumTopicCreated(ASender: TObject; + AForumTopicCreated: ItdForumTopicCreated); + procedure BotManager1ForumTopicEdited(ASender: TObject; + AForumTopicEdited: ItdForumTopicEdited); + procedure BotManager1ForumTopicReopened(ASender: TObject; + AForumTopicReopened: ItdForumTopicReopened); + procedure BotManager1ForumTopicClosed(ASender: TObject; + AForumTopicClosed: ItdForumTopicClosed); + procedure BotManager1GeneralForumTopicHidden(ASender: TObject; + AGeneralForumTopicHidden: ItdGeneralForumTopicHidden); + procedure BotManager1GeneralForumTopicUnhidden(ASender: TObject; + AGeneralForumTopicUnhidden: ItdGeneralForumTopicUnhidden); + procedure CriarTopicoClick(Sender: TObject); + procedure EditarTopicoClick(Sender: TObject); + procedure GetForumStikersTopicClick(Sender: TObject); + procedure SendTextTopicClick(Sender: TObject); + procedure BotManager1MessageEntityReceiver(ASender: TObject; + AMessageEntityType: TtdMessageEntityType); + procedure btnGetCMD2Click(Sender: TObject); + procedure Button11Click(Sender: TObject); + procedure Button12Click(Sender: TObject); + procedure btnSetMyNameClick(Sender: TObject); + procedure btnGetMyNameClick(Sender: TObject); + procedure BotManager1WebAppData(ASender: TObject; + AWebAppData: ItdWebAppData); + private + procedure CarregarBTStr(AStrArrayBtName: TArray>; + AInlineMode: Boolean; url: string); + { Private declarations } + public + procedure AplicarResource; + var + //Variaveis Globais + MyCallback : ItdCallbackQuery; + MyMessage : ItdMessage; + MyInlineQuery : ItdInlineQuery; + MyFile : TtdFileToSend; + MyFiles : TArray; + MyLocation : TtdLocation; + MyVenue : TtdVenue; + MyMedia : TArray; + MyChatId : TtdUserLink; + MyContact : Ttdcontact; + MyAction : TtdSendChatAction; + MyPrices : TArray; + MyPollKey : TtdKeyboardButtonPollType; //Novo Recurso + //SemUso... + MyFotoFile : TtdInputMediaPhoto; //Add para teste + LParseMode : TtdParseMode; //Necessario declarar TelegAPI.Types.Enums + LMarkup : IReplyMarkup; //Necessario declarar TelegAPI.Types.ReplyMarkups + LChatID : Int64; + FileCount : Integer; //Variavel para contar os Arquivos no SendMediaGroup + + {$REGION 'MYRESOURCES'} + VRes_Filtro_Foto_Video, + VRes_Filtro_Video, + VRes_Filtro_Fotos, + VRes_Filtro_Voz, + VRes_Filtro_Stiker, + VRes_Filtro_Todos, + VRes_Filtro_Audio, + // + VRes_Animacao, + VRes_Dado, + VRes_Dardo, + VRes_Basquete, + VRes_Grav_Voz, + VRes_Video, + VRes_Audio, + VRes_Imagem, + VRes_Acao, + VRes_Localizacao, + VRes_Stiker, + VRes_Enquete_Quiz, + VRes_Nota_Video, + VRes_Jogo, + VRes_Contato, + VRes_Pagamento, + VRes_Documento, + VRes_GrupoMidia, + // + VRes_Texto_Video, + VRes_Texto_Voz, + VRes_Texto_Audio, + VRes_Texto_Animacao, + VRes_Texto_Foto, + VRes_Texto_Documento, + // + VRes_Falha, + VRes_Falha_Envio_Destinatario, + VRes_Ative_Servico, + VRes_Preencha_Token, + VRes_MSG_Exemplo_Envio_BT, + VRes_Servico_Ativo, + VRes_Servico_Desativado, + VRes_O_Usuario, + VRes_Compartilhou_CTT, + VRes_Compartilhou_Localizacao, + VRes_Solicitou, + VRes_Telefone, + VRes_Qual_Meu_ID, + VRes_Ola_Me_Passe_Localizacao, + VRes_Solicitacao_Env_Mas_Incomp_Teleg_Descktop, + VRes_Ola_Me_Passe_Contato, + VRes_Enviar_Localizacao, + VRes_Enviar_Contato, + VRes_Use_Seu_Cel_Envio_MeuID, + VRes_Este_Seu_ID, + VRes_Ex_Endereco_Digitado, + VRes_Ex_Titulo, + VRes_Ex_Tipo, + VRes_Ex_Remover_BT, + VRes_Ta_Doidao, + VRes_Quem_Desc_Brasil, + VRes_Informe_Jogo_Valido, + VRes_Ajuda_Token_Banco, + VRes_ProdutoA, + VRes_ProdutoB, + VRes_Limite_Arquivos_MediaGroup, + VRes_Teste_MidiaGroup, + VRes_Titulo_PG, + VRes_Descricao_PG, + VRes_PlayLoad_PG: String; + {$ENDREGION 'MYRESOURCES'} + { Public declarations } + end; +var + Form1: TForm1; + Clique : Integer; +implementation +{$R *.dfm} +procedure TForm1.AplicarResource; +Begin +{$REGION 'Atribuio das Variaveis'} + VRes_Filtro_Foto_Video := ARes_Filtro_Foto_Video; + VRes_Filtro_Video := ARes_Filtro_Video; + VRes_Filtro_Fotos := ARes_Filtro_Fotos; + VRes_Filtro_Voz := ARes_Filtro_Voz; + VRes_Filtro_Stiker := ARes_Filtro_Stiker; + VRes_Filtro_Todos := ARes_Filtro_Todos; + VRes_Filtro_Audio := ARes_Filtro_Audio; + // + VRes_Animacao := ARes_Animacao; + VRes_Dado := ARes_Dado; + VRes_Dardo := ARes_Dardo; + VRes_Basquete := ARes_Basquete; + VRes_Grav_Voz := ARes_Grav_Voz; + VRes_Video := ARes_Video; + VRes_Audio := ARes_Audio; + VRes_Imagem := ARes_Imagem; + VRes_Acao := ARes_Acao; + VRes_Localizacao := ARes_Localizacao; + VRes_Stiker := ARes_Stiker; + VRes_Enquete_Quiz := ARes_Enquete_Quiz; + VRes_Nota_Video := ARes_Nota_Video; + VRes_Jogo := ARes_Jogo; + VRes_Contato := ARes_Contato; + VRes_Pagamento := ARes_Pagamento; + VRes_Documento := ARes_Documento; + VRes_GrupoMidia := ARes_GrupoMidia; + // + VRes_Texto_Video := ARes_Texto_Video; + VRes_Texto_Voz := ARes_Texto_Voz; + VRes_Texto_Audio := ARes_Texto_Audio; + VRes_Texto_Animacao := ARes_Texto_Animacao; + VRes_Texto_Foto := ARes_Texto_Foto; + VRes_Texto_Documento := ARes_Texto_Documento; + // + VRes_Falha := ARes_Falha; + VRes_Falha_Envio_Destinatario := ARes_Falha_Envio_Destinatario; + VRes_Ative_Servico := ARes_Ative_Servico; + VRes_Preencha_Token := ARes_Preencha_Token; + VRes_MSG_Exemplo_Envio_BT := ARes_MSG_Exemplo_Envio_BT; + VRes_Servico_Ativo := ARes_Servico_Ativo; + VRes_Servico_Desativado := ARes_Servico_Desativado; + VRes_O_Usuario := ARes_O_Usuario; + VRes_Compartilhou_CTT := ARes_Compartilhou_CTT; + VRes_Compartilhou_Localizacao := ARes_Compartilhou_Localizacao; + VRes_Solicitou := ARes_Solicitou; + VRes_Telefone := ARes_Telefone; + VRes_Qual_Meu_ID := ARes_Qual_Meu_ID; + VRes_Ola_Me_Passe_Localizacao := ARes_Ola_Me_Passe_Localizacao; + VRes_Solicitacao_Env_Mas_Incomp_Teleg_Descktop := ARes_Solicitacao_Env_Mas_Incomp_Teleg_Descktop; + VRes_Ola_Me_Passe_Contato := ARes_Ola_Me_Passe_Contato; + VRes_Enviar_Localizacao := ARes_Enviar_Localizacao; + VRes_Enviar_Contato := ARes_Enviar_Contato; + VRes_Use_Seu_Cel_Envio_MeuID := ARes_Use_Seu_Cel_Envio_MeuID; + VRes_Este_Seu_ID := ARes_Este_Seu_ID; + VRes_Ex_Endereco_Digitado := ARes_Ex_Endereco_Digitado; + VRes_Ex_Titulo := ARes_Ex_Titulo; + VRes_Ex_Tipo := ARes_Ex_Tipo; + VRes_Ex_Remover_BT := ARes_Ex_Remover_BT; + VRes_Ta_Doidao := ARes_Ta_Doidao; + VRes_Quem_Desc_Brasil := ARes_Quem_Desc_Brasil; + VRes_Informe_Jogo_Valido := ARes_Informe_Jogo_Valido; + VRes_Ajuda_Token_Banco := ARes_Ajuda_Token_Banco; + VRes_ProdutoA := ARes_ProdutoA; + VRes_ProdutoB := ARes_ProdutoB; + VRes_Limite_Arquivos_MediaGroup := ARes_Limite_Arquivos_MediaGroup; + VRes_Teste_MidiaGroup := ARes_Teste_MidiaGroup; + VRes_Titulo_PG := ARes_Titulo_PG; + VRes_Descricao_PG := ARes_Descricao_PG; + VRes_PlayLoad_PG := ARes_PlayLoad_PG; +{$ENDREGION 'Atribuio das Variaveis'} +End; +procedure TForm1.BotManager1ForumTopicClosed(ASender: TObject; + AForumTopicClosed: ItdForumTopicClosed); +begin + memConsole.Lines.Add('Um Topico foi Fechado!'); +end; + +procedure TForm1.BotManager1ForumTopicCreated(ASender: TObject; + AForumTopicCreated: ItdForumTopicCreated); +begin + memConsole.Lines.Add('Topico Criado'+sLinebreak+ + 'Name : '+AForumTopicCreated.name+sLinebreak+ + 'icon_color : '+AForumTopicCreated.icon_color.ToString+sLinebreak+ + 'icon_custom_emoji_id : '+AForumTopicCreated.icon_custom_emoji_id); +end; + +procedure TForm1.BotManager1ForumTopicEdited(ASender: TObject; + AForumTopicEdited: ItdForumTopicEdited); +begin + memConsole.Lines.Add('Topico Editado'+sLinebreak+ + 'Name : '+AForumTopicEdited.name+sLinebreak+ + 'icon_custom_emoji_id : '+AForumTopicEdited.icon_custom_emoji_id); +end; + +procedure TForm1.BotManager1ForumTopicReopened(ASender: TObject; + AForumTopicReopened: ItdForumTopicReopened); +begin + memConsole.Lines.Add('Um Topico foi Reaberto'); +end; + +procedure TForm1.BotManager1GeneralForumTopicHidden(ASender: TObject; + AGeneralForumTopicHidden: ItdGeneralForumTopicHidden); +begin + memConsole.Lines.Add('Um Topico foi Ocultado'); +end; + +procedure TForm1.BotManager1GeneralForumTopicUnhidden(ASender: TObject; + AGeneralForumTopicUnhidden: ItdGeneralForumTopicUnhidden); +begin + memConsole.Lines.Add('Um Topico foi Reexibido'); +end; + +procedure TForm1.BotManager1MessageEntityReceiver(ASender: TObject; + AMessageEntityType: TtdMessageEntityType); +begin + case AMessageEntityType of + TtdMessageEntityType.mention: ; + TtdMessageEntityType.hashtag: ; + TtdMessageEntityType.cashtag: ; + TtdMessageEntityType.bot_command: ; + TtdMessageEntityType.url: ; + TtdMessageEntityType.email: ; + TtdMessageEntityType.phone_number: ; + TtdMessageEntityType.bold: ; + TtdMessageEntityType.italic: ; + TtdMessageEntityType.underline: ; + TtdMessageEntityType.strikethrough: ; + TtdMessageEntityType.code: ; + TtdMessageEntityType.pre: ; + TtdMessageEntityType.text_link: ; + TtdMessageEntityType.text_mention: ; + TtdMessageEntityType.spoiler: ; + TtdMessageEntityType.custom_emoji: ; + TtdMessageEntityType.N_A: ; + end; +end; + +procedure TForm1.BotManager1WebAppData(ASender: TObject; + AWebAppData: ItdWebAppData); +begin + if AWebAppData <> Nil then + Begin + memConsole.Lines.Add('OnWebAppData Event : '); + memConsole.Lines.Add('button_text : '+AWebAppData.button_text); + memConsole.Lines.Add('data : '+AWebAppData.data); + End; +end; + +procedure TForm1.btnADDClick(Sender: TObject); +var + I : Integer; + F: Integer; +begin + if FileCount > 10 then + FileCount := 0; + FileCount := FileCount + 1; + AbrirArquivo.Filter := VRes_Filtro_Foto_Video; + if FileCount <= 10 then // Limite de arquivos da API + Begin + SetLength(MyFiles, FileCount); + if AbrirArquivo.Execute then + MyFiles[FileCount - 1] := TtdFileToSend.Create(TtdFileToSendTag.FromFile,AbrirArquivo.FileName); + SetLength(MyMedia, Length(MyFiles)); + if ExtractFileExt(AbrirArquivo.FileName) = '.png' then + MyMedia[FileCount - 1] := TtdInputMediaPhoto.Create(MyFiles[FileCount - 1], VRes_Teste_MidiaGroup); + if ExtractFileExt(AbrirArquivo.FileName) = '.mp4' then + MyMedia[FileCount - 1] := TtdInputMediaVideo.Create(MyFiles[FileCount - 1], VRes_Teste_MidiaGroup); + End + Else + Showmessage(VRes_Limite_Arquivos_MediaGroup); +end; +procedure TForm1.btnAnswerWebAppQueryClick(Sender: TObject); +var + FResult: TtdInlineQueryResult; + FWebSent: TtdSentWebAppMessage; + imp: TtdInputTextMessageContent; + InlineMarkup: TtdInlineKeyboardMarkup; + InlineKeyboard: TtdInlineKeyboardButton; +begin + + if BotManager1.IsActive then + Begin + try + FResult:= TtdInlineQueryResult.Create; + FResult.&Type := 'article'; + FResult.Title := 'Teste'; + + imp:= TtdInputTextMessageContent.Create('OLA MUNDO','Markdown',False); + + FResult.ParseMode := TtdParseMode.Markdown; + FResult.InputMessageContent := imp; + + InlineKeyboard := TtdInlineKeyboardButton.Create('Teste','teste'); + InlineMarkup:= TtdInlineKeyboardMarkup.Create([[InlineKeyboard]]); + + FResult.ReplyMarkup := InlineMarkup; + + FWebSent := BotManager1.Bot.AnswerWebAppQuery('123456',FResult) as TtdSentWebAppMessage; + memConsole.Lines.Add('inline_message_id: '+FWebSent.inline_message_id); + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; + +procedure TForm1.btnApagarBotoesClick(Sender: TObject); +begin +{ +Aqui voc Remove botoes do destinatario,apenas seguindo a mensagem +} +//Necessario declarar TinjectTelegram.Types.ReplyMarkups //TtdReplyKeyboardRemove +LMarkup := TtdReplyKeyboardRemove.Create; + if BotManager1.IsActive then + Begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendMessage(StrToInt64(txtID.Text),VRes_Ex_Remover_BT, LParseMode, False, False, 0, False, LMarkup) + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; + +procedure TForm1.btnGetCMDClick(Sender: TObject); +var + MyCommands: TArray; + I: Integer; + BotCommandScope: ItdBotCommandScope; +begin + if BotManager1.IsActive then + begin + + try + MyCommands := InjectTelegramBot1.GetMyCommands(TtdBotCommandScopeType.BotCommandScopeDefault); + + if MyCommands <> Nil then + Begin + for I := 0 to Length(MyCommands) -1 do + Begin + if Length(MyCommands) > 0 then + Begin + if I = 0 then + memConsole.Lines.Add('Command List...'); + if (I >= 0) then + Begin + memConsole.Lines.Add('Command'+IntToStr(I+1)+' : '+MyCommands[I].Command); + memConsole.Lines.Add('Description'+IntToStr(I+1)+' : '+MyCommands[I].Description); + memConsole.Lines.Add('-----------------'); + End; + End; + End; + End + Else + Begin + memConsole.Lines.Add('No Command Found!'); + End; + + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+' ao obter a lista de comandos!'); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; + +procedure TForm1.btnGetMyNameClick(Sender: TObject); +var + MyBotName: TtdBotName; +begin + if BotManager1.IsActive then + begin + try + MyBotName := TtdBotName(InjectTelegramBot1.GetMyName()); + + if MyBotName <> Nil then + Begin + memConsole.Lines.Add('MyBotName is: '+ MyBotName.name); + memConsole.Lines.Add('The bot name was successfully fetched!!'); + End; + + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+' when getting the name of the bot!'); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; + +procedure TForm1.btnCommandsClick(Sender: TObject); +var + botcmdArr: TArray; +begin + + botcmdArr := [TtdBotCommand.Create('commandname1','CommandDescription1'), + TtdBotCommand.Create('commandname2','CommandDescription2'), + TtdBotCommand.Create('commandname3','CommandDescription3'), + TtdBotCommand.Create('commandname4','CommandDescription4')]; + + if BotManager1.IsActive then + begin + try + try + InjectTelegramBot1.SetMyCommands(botcmdArr, TtdBotCommandScopeType.BotCommandScopeDefault); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+' ao setar os comandos!'); + end; + end; + finally + memConsole.Lines.Add('Command Created!'); + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; + +procedure TForm1.btnDeleteCommandsClick(Sender: TObject); +var + BotCommandScope: TtdBotCommandScopeDefault; +begin +// BotCommandScope := TtdBotCommandScopeDefault.Create('{}'); +// // BotCommandScope.type_ := 'default'; + if BotManager1.IsActive then + begin + try + try + InjectTelegramBot1.DeleteMyCommands(TtdBotCommandScopeType.BotCommandScopeDefault); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+' ao deletar a lista de comandos!'); + end; + end; + + finally + memConsole.Lines.Add('Command Deleted!'); + end; + + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; + +procedure TForm1.btnComoSaberIDClick(Sender: TObject); +begin + Showmessage(VRes_Use_Seu_Cel_Envio_MeuID); +end; + +procedure TForm1.btnEnviaAudioClick(Sender: TObject); +begin + AbrirArquivo.Filter := VRes_Filtro_Audio; + if AbrirArquivo.Execute then + MyFile := TtdFileToSend.Create(TtdFileToSendTag.FromFile,AbrirArquivo.FileName); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendAudio(StrToInt64(txtID.Text), MyFile,VRes_Texto_Audio, + LParseMode, 0,'Titulo Sobreescrito',cbDisableNotification.Checked, 0, False, LMarkup, cbProtectedContent.Checked); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Audio); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviaFotoClick(Sender: TObject); +//From Stream Use +var + MyStream: TMemoryStream; + BoolStream: Boolean; +begin + AbrirArquivo.Filter := VRes_Filtro_Fotos; + if AbrirArquivo.Execute then + ImgLoad.Picture.WICImage.LoadFromFile(AbrirArquivo.FileName); + MyFile := Nil; + if MessageDlg('Send from Stream?',mtInformation,[mbYes,mbNo],0) = mrYes then + Begin + BoolStream := True; + //From Stream Use + MyStream := TMemoryStream.Create; + MyStream.Position := 0; + ImgLoad.Picture.Graphic.SaveToStream(MyStream); + MyFile := TtdFileToSend.Create(TtdFileToSendTag.FromStream,AbrirArquivo.FileName, MyStream); + End Else + Begin + BoolStream := False; + //From File + MyFile := TtdFileToSend.Create(TtdFileToSendTag.FromFile,AbrirArquivo.FileName, Nil); + End; + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + try + if Assigned(MyFile) then + Begin + if BoolStream then + InjectTelegramBot1.SendPhoto(StrToInt64(txtID.Text), MyFile,VRes_Texto_Foto+ + ' - From Stream', LParseMode, cbDisableNotification.Checked, 0, False, LMarkup,cbProtectedContent.Checked) + else + InjectTelegramBot1.SendPhoto(StrToInt64(txtID.Text), MyFile,VRes_Texto_Foto+ + ' - From File', LParseMode, cbDisableNotification.Checked, 0, False, LMarkup, cbProtectedContent.Checked); + End Else + memConsole.Lines.Add(VRes_Falha+VRes_Imagem+ ' ERROR: Nenhum Arquivo Assossiado para envio, foi encontrado!'); + except on e:exception do + memConsole.Lines.Add(VRes_Falha+VRes_Imagem+ ' ERROR: '+e.Message); + end; + finally + if BoolStream then + MyStream.Free; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarAcaoClick(Sender: TObject); +begin + { + Basta Mudar a ao aqui para que ele envie a ao selecionada + como por exemplo: + MyAction := TtdSendChatAction.Record_audio; + MyAction := TtdSendChatAction.Upload_document; + entre outros + } + //Neste caso irei enviar a ao Escrevendo... (Typing) + MyAction := TtdSendChatAction.Typing; + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + InjectTelegramBot1.SendChatAction(MyChatId, MyAction); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Acao); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarAnimacaoClick(Sender: TObject); +var + MyThumb : TtdFileToSend; +begin + AbrirArquivo.Filter := VRes_Filtro_Video; + if AbrirArquivo.Execute then + MyFile := TtdFileToSend.Create(TtdFileToSendTag.FromFile, AbrirArquivo.FileName); + AbrirArquivo.Filter := VRes_Filtro_Fotos; + if AbrirArquivo.Execute then + MyThumb := TtdFileToSend.Create(TtdFileToSendTag.FromFile, AbrirArquivo.FileName); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendAnimation(StrToInt64(txtID.Text), MyFile,30,0,0,MyThumb, + VRes_Texto_Animacao, LParseMode, cbDisableNotification.Checked, 0, False, LMarkup, cbProtectedContent.Checked); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Animacao); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarContatoClick(Sender: TObject); +begin + MyContact := TtdContact.Create('5521997196000','Ruan Diego','Lacerda Menezes','CB Lacerda'); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendContact(StrToInt64(txtID.Text), MyContact, False, 0, False, LMarkup); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Contato); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarDocumentoClick(Sender: TObject); +begin + MyFile := Nil; + AbrirArquivo.Filter := VRes_Filtro_Todos; + if AbrirArquivo.Execute then + MyFile := TtdFileToSend.FromFile(AbrirArquivo.FileName); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try //Thumb 320x320 px at 200k + InjectTelegramBot1.SendDocument(StrToInt64(txtID.Text), MyFile, nil , + VRes_Texto_Documento, LParseMode, False, cbDisableNotification.Checked, 0, + False, LMarkup,cbProtectedContent.Checked, 0, []); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Documento); + memConsole.Lines.Add(e.Message); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarGrpMidiasClick(Sender: TObject); +var + I: integer; +Begin + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + if Assigned(MyMedia) then + try + InjectTelegramBot1.sendMediaGroup(MyChatId.ID, MyMedia, + cbDisableNotification.Checked, 0, False, cbProtectedContent.Checked); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_GrupoMidia); + end; + end; + finally + MyFile.Free; + for I := 0 to Length(MyMedia) -1 do + MyMedia[I].Free; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarInvoiceClick(Sender: TObject); +var + AText, sJson, FotoUrl : String; + Ctt : Int64; + pvToken, BrandName, pgMetod: String; +begin + FotoUrl := 'https://user-images.githubusercontent.com/11804577/79389701-fd284580-7f44-11ea-8238-bab525a19caa.png'; + pvToken := txtTokenBanco.Text;//'SEU TOKEN_PROVIDER GERADO NO BOTFATHER PARA PAGAMENTOS'; + BrandName := 'Visa'; + pgMetod := 'pm_card_visa'; + //R$10,00 + // MyInvoice := TtdInvoice.Create('Teste Titulo','Descrio', 'www.lmcodenew.com.br','USD',1000); + if txtTokenBanco.Text = '' then + Begin + Showmessage(VRes_Ajuda_Token_Banco); + Exit; + End; + SetLength(MyPrices, 2); + MyPrices[0] := TtdLabeledPrice.Create(VRes_ProdutoA, 1000); + MyPrices[1] := TtdLabeledPrice.Create(VRes_ProdutoB, 300); + + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + //ID //TITULO //DESC //PLayload //Token //Param //Curr //Prices //ProvData //Foto + InjectTelegramBot1.SendInvoice(MyChatId.ID, + VRes_Titulo_PG, + VRes_Descricao_PG, + VRes_PlayLoad_PG, + pvToken, pgMetod ,'USD', MyPrices, + 5478750, //MaxTipAmount + [], //SuggestedTipAmounts = Array of Integer + '', //ProviderData + FotoUrl, 300, 100, 100, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,0, nil); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Pagamento); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarJogoClick(Sender: TObject); +var + MyChatId: TtdUserLink; //Uses TelegAPI.Bot +begin + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + { Necessrio criar um game no BotFather para obter o + nome do game que ser enviado } + if txtNomeJogo.Text <> '' then + Begin + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + InjectTelegramBot1.SendGame(MyChatId.ID, txtNomeJogo.Text); + End Else + memConsole.Lines.Add(VRes_Informe_Jogo_Valido); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Jogo); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarLocalizacaoClick(Sender: TObject); +var + lt, lg: Single; +begin + lt := -22.8272758; + lg := -43.0292233; + MyLocation := TtdLocation.Create(lt,lg); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendLocation(StrToInt64(txtID.Text), MyLocation, False, 0, False, LMarkup); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Localizacao); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarNotaDeVideoClick(Sender: TObject); +begin + AbrirArquivo.Filter := VRes_Filtro_Video; + if AbrirArquivo.Execute then + MyFile := TtdFileToSend.Create(TtdFileToSendTag.FromFile,AbrirArquivo.FileName); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendVideoNote(StrToInt64(txtID.Text), MyFile, 0, 0, False, 0, False, LMarkup); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Nota_Video); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarPollClick(Sender: TObject); +var + MyStrArray: Array of String; +begin + MyStrArray := [ + 'Peido Alvares Cabral', + 'Sergio Cabral', + 'Cristovo Colombo', + 'Pedro Alvares Cabral']; + //Outra forma de Pegar o link com os dados do usuario e remeter na mensagem + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendPoll(MyChatId, + VRes_Quem_Desc_Brasil, MyStrArray, False, + TtdQuizType.qtQuiz, False, 3, VRes_Ta_Doidao, + [], 0, 0, False, False,0,False, LMarkup,False,0); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Enquete_Quiz); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarStikerClick(Sender: TObject); +begin + AbrirArquivo.Filter := VRes_Filtro_Stiker; + if AbrirArquivo.Execute then + MyFile := TtdFileToSend.Create(TtdFileToSendTag.FromFile,AbrirArquivo.FileName); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendSticker(StrToInt64(txtID.Text), MyFile, + cbDisableNotification.Checked, 0, LMarkup); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Stiker); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarVenueClick(Sender: TObject); +var + lt, lg: Single; +begin + lt := -22.8272758; + lg := -43.0292233; +///Desta Forma necessrio instanciar o MyLocation e passa-lo como paramentro ao instanciar o MyVenue + // MyLocation := TtdLocation.Create(lt,lg); + // MyVenue := TtdVenue.Create(MyLocation, VRes_Ex_Endereco_Digitado, VRes_Ex_Titulo,'',VRes_Ex_Tipo); + //Desta Forma o MyLocation no precisa ser instanciado pois os parametros de coordenado sopassados diretamente aqui + MyVenue := TtdVenue.Create(lt,lg, VRes_Ex_Endereco_Digitado, VRes_Ex_Titulo,'',VRes_Ex_Tipo); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + //A Funo SendVenue depende do Mylocation + //InjectTelegramBot1.SendVenue(StrToInt64(txtID.Text), MyVenue, MyLocation, False, 0, LMarkup); + //A Funo SendVenue2 NO depende do Mylocation + InjectTelegramBot1.SendVenue2(StrToInt64(txtID.Text), MyVenue, False, 0, False, LMarkup); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Localizacao); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarVideoClick(Sender: TObject); +begin + AbrirArquivo.Filter := VRes_Filtro_Video; + if AbrirArquivo.Execute then + MyFile := TtdFileToSend.Create(TtdFileToSendTag.FromFile,AbrirArquivo.FileName); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendVideo(StrToInt64(txtID.Text), MyFile,VRes_TExto_Video, + LParseMode, True, 0, 0, 0, cbDisableNotification.Checked, 0, False, LMarkup, cbProtectedContent.Checked); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Video); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarVozClick(Sender: TObject); +begin + AbrirArquivo.Filter := VRes_Filtro_Voz; + if AbrirArquivo.Execute then + MyFile := TtdFileToSend.Create(TtdFileToSendTag.FromFile,AbrirArquivo.FileName); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendVoice(StrToInt64(txtID.Text), MyFile,VRes_Texto_Voz, LParseMode, 0, False, 0, False, LMarkup); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Grav_Voz); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviaTextoClick(Sender: TObject); +begin + if {InjectTelegramReceiverService1}BotManager1.IsActive then + Begin + if txtID.Text <> '' then + try + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + {InjectTelegramBot1}BotManager1.Bot.SendMessage(MyChatId.ID, VRes_Este_Seu_ID + MyChatId.ID.ToString, LParseMode, False, cbDisableNotification.Checked, 0, False, LMarkup, cbProtectedContent.Checked) + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; +procedure TForm1.btnGetAdministratorRightsClick(Sender: TObject); +var + rights: TtdChatAdministratorRights; +begin + if BotManager1.IsActive then + Begin + try + rights := BotManager1.Bot.getMyDefaultAdministratorRights(cbChanel.Checked) as TtdChatAdministratorRights; + + if Assigned(rights) then + Begin + memConsole.Lines.Add('is_anonymous: '+rights.is_anonymous.ToString); + memConsole.Lines.Add('can_manage_chat: '+rights.can_manage_chat.ToString); + memConsole.Lines.Add('can_delete_messages: '+rights.can_delete_messages.ToString); + memConsole.Lines.Add('can_manage_video_chats: '+rights.can_manage_video_chats.ToString); + memConsole.Lines.Add('can_restrict_members: '+rights.can_restrict_members.ToString); + memConsole.Lines.Add('can_promote_members: '+rights.can_promote_members.ToString); + memConsole.Lines.Add('can_change_info: '+rights.can_change_info.ToString); + memConsole.Lines.Add('can_invite_users: '+rights.can_invite_users.ToString); + memConsole.Lines.Add('can_post_messages: '+rights.can_post_messages.ToString); + memConsole.Lines.Add('can_edit_messages: '+rights.can_edit_messages.ToString); + memConsole.Lines.Add('can_pin_messages: '+rights.can_pin_messages.ToString); + End; + + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; + +procedure TForm1.btnGetChatMenuButtonClick(Sender: TObject); +var MyMenuButton: TtdMenuButtonWebApp; +begin + if BotManager1.IsActive then + Begin + if txtID.Text <> '' then + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)) + else + MyChatId := 0; + try + + MyMenuButton := BotManager1.Bot.GetChatMenuButton(MyChatId) as TtdMenuButtonWebApp; + memConsole.Lines.Add('type : '+MyMenuButton.&type); + if MyMenuButton.&type = 'web_app' then + Begin + memConsole.Lines.Add('text : '+MyMenuButton.text); + memConsole.Lines.Add('web_app.url : '+MyMenuButton.web_app.url); + End; + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; + +procedure TForm1.btnSetChatMenuButtonClick(Sender: TObject); +var MyMenuButton: TtdMenuButton; + MyWebAppInfo: TtdWebAppInfo; + MyButtonType: TtdMenuButtonType; + url, FUrl, FButtonName, ButtonName: string; +begin + if BotManager1.IsActive then + Begin + if txtID.Text <> '' then + try + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + +// MyMenuButton := BotManager1.Bot.GetChatMenuButton(MyChatId) as TtdMenuButton; +// +// if MyMenuButton.ClassName = TtdMenuButtonWebApp.ClassName then +// Begin +// if TtdMenuButtonWebApp(MyMenuButton).text <> 'Menu' then +// FUrl := TtdMenuButtonWebApp(MyMenuButton).web_app.url; +// FButtonName := TtdMenuButtonWebApp(MyMenuButton).text; +// End; + + url := InputBox('Preencha o Campo com sua URL do Web Bot','URL',FUrl); + ButtonName := InputBox('Preencha o Campo com um nome para o Boto do Web Bot','Nome do Boto',FButtonName); + + MyWebAppInfo:= TtdWebAppInfo.Create(url); + + if url <> '' then + MyButtonType := TtdMenuButtonType.MenuButtonWebApp + else begin + MyButtonType := TtdMenuButtonType.MenuButtonCommands; + ButtonName := ''; + end; + + if BotManager1.Bot.SetChatMenuButton(MyChatId, url, ButtonName,MyButtonType) = true then + memConsole.Lines.Add('O Web Bot foi definido com sucesso!'); + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; + +procedure TForm1.btnSetMyDefaultAdministratorRightsClick(Sender: TObject); +var + rights: TtdChatAdministratorRights; + Estado: Boolean; +begin + Estado := cbRightsAdmin.Checked; + rights:= TtdChatAdministratorRights.Create; + + with rights do + Begin + IsAnonymous := Estado; + CanManageChat := Estado; + CanDeleteMessages := Estado; + CanManageVideoChats := Estado; + CanRestrictMembers := Estado; + CanPromoteMembers := Estado; + CanChangeInfo := Estado; + CanInviteUsers := Estado; + CanPostMessages := Estado; + CanEditMessages := Estado; + CanPinMessages := Estado; + End; + + if BotManager1.IsActive then + Begin + try + BotManager1.Bot.setMyDefaultAdministratorRights(rights, cbChanel.Checked); + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); + +end; + +procedure TForm1.btnSetMyNameClick(Sender: TObject); +begin + if BotManager1.IsActive then + begin + try + + if InjectTelegramBot1.SetMyName('LMCDelivery2_Testebot') = true then + memConsole.Lines.Add('Bot name has been changed!'); + + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+' when changing the commands!'); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; + +procedure TForm1.btnSolicitarCttClick(Sender: TObject); +begin +LMarkup := TtdReplyKeyboardMarkup.Create([ + { Primeira Linha } + [TtdKeyboardButton.Create(VRes_Enviar_Contato, True, FALSE)]], TRUE); + if BotManager1.IsActive then + Begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendMessage(StrToInt64(txtID.Text), + VRes_Ola_Me_Passe_Contato, + LParseMode, False, False, 0, False, LMarkup) + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; +procedure TForm1.btnSolicitarLocalizacaoClick(Sender: TObject); +begin +LMarkup := TtdReplyKeyboardMarkup.Create([ + { Primeira Linha } + [TtdKeyboardButton.Create(VRes_Enviar_Localizacao, False, TRUE)]], TRUE); + if BotManager1.IsActive then + Begin + if txtID.Text <> '' then + try + memConsole.Lines.Add(VRes_Solicitacao_Env_Mas_Incomp_Teleg_Descktop); + InjectTelegramBot1.SendMessage(StrToInt64(txtID.Text), + VRes_Ola_Me_Passe_Localizacao, + LParseMode, False, False, 0, False, LMarkup) + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarDadoClick(Sender: TObject); +begin + //Outra forma de Pegar o link com os dados do usuario e remeter na mensagem + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendDice(MyChatId, TtdEmojiType.etDado ,False, 0, False, LMarkup); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Dado); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarDardoClick(Sender: TObject); +begin + //Outra forma de Pegar o link com os dados do usuario e remeter na mensagem + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendDice(MyChatId, TtdEmojiType.etDardo ,False, 0, False, LMarkup); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Dardo); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.btnEnviarTxtComBtClick(Sender: TObject); +var +bt1, bt2, bt3: TtdKeyboardButton; +begin + + bt1 := TtdKeyboardButton.Create('texto1', FALSE, FALSE); + + bt2 := TtdKeyboardButton.Create('texto2', FALSE, FALSE); + + bt3 := TtdKeyboardButton.Create(VRes_Qual_Meu_ID, FALSE, FALSE); + +{ +Aqui voc cria os botoes do tipo ReplyKeyboard para enviar na mensagem +eles sero criados como um teclado personalizado para seu destinatario +} + LMarkup := TtdReplyKeyboardMarkup.Create([ + { Primeira Linha } + [bt1, bt2], + { Segunda Linha } + [bt3]], TRUE); + + + if BotManager1.IsActive then + Begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendMessage(StrToInt64(txtID.Text), + VRes_MSG_Exemplo_Envio_BT, + LParseMode, False, False, 0, False, LMarkup) + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; +procedure TForm1.EditarTopicoClick(Sender: TObject); +var + ForumTopicId: Int64; + TopicName: string; +begin + if BotManager1.IsActive then + Begin + TopicName := InputBox('Informe um Nome para o Tpico', 'Nome','TInjectTelegram - Topic01'); + ForumTopicId := InputBox('Informe o Id do Topico', 'ID','0').ToInt64; + try + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + BotManager1.Bot.editForumTopic(MyChatId, ForumTopicId, TopicName, '5312536423851630001'); + except on E: Exception do + memConsole.Lines.Add('Falha ao criar um tpico - ' + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); + +end; + +procedure TForm1.EnviarFotoSpoilerClick(Sender: TObject); +var + MyStream: TMemoryStream; + BoolStream: Boolean; +begin + AbrirArquivo.Filter := VRes_Filtro_Fotos; + if AbrirArquivo.Execute then + ImgLoad.Picture.WICImage.LoadFromFile(AbrirArquivo.FileName); + MyFile := Nil; + if MessageDlg('Send from Stream?',mtInformation,[mbYes,mbNo],0) = mrYes then + Begin + BoolStream := True; + //From Stream Use + MyStream := TMemoryStream.Create; + MyStream.Position := 0; + ImgLoad.Picture.Graphic.SaveToStream(MyStream); + MyFile := TtdFileToSend.Create(TtdFileToSendTag.FromStream,AbrirArquivo.FileName, MyStream); + End Else + Begin + BoolStream := False; + //From File + MyFile := TtdFileToSend.Create(TtdFileToSendTag.FromFile,AbrirArquivo.FileName, Nil); + End; + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + try + if Assigned(MyFile) then + Begin + if BoolStream then + InjectTelegramBot1.SendPhoto(StrToInt64(txtID.Text), MyFile,VRes_Texto_Foto+ + ' Spoiler - From Stream', LParseMode, cbDisableNotification.Checked, 0, False, + LMarkup,cbProtectedContent.Checked,0,[],True) + else + InjectTelegramBot1.SendPhoto(StrToInt64(txtID.Text), MyFile,VRes_Texto_Foto+ + ' Spoiler - From File', LParseMode, cbDisableNotification.Checked, 0, False, + LMarkup, cbProtectedContent.Checked,0,[],True); + End Else + memConsole.Lines.Add(VRes_Falha+VRes_Imagem+ ' ERROR: Nenhum Arquivo Assossiado para envio, foi encontrado!'); + except on e:exception do + memConsole.Lines.Add(VRes_Falha+VRes_Imagem+ ' ERROR: '+e.Message); + end; + finally + if BoolStream then + MyStream.Free; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); + +end; + +procedure TForm1.btnGetCMD2Click(Sender: TObject); +var + MyCommands: TArray; + I: Integer; + BotCommandScope: TtdBotCommandScopeDefault; + BotCommandScopeType: TtdBotCommandScopeType; +begin + BotCommandScopeType := TtdBotCommandScopeType.BotCommandScopeDefault; + BotCommandScope := TtdBotCommandScopeDefault.Create(BotCommandScopeType); + + memConsole.Lines.Add('BotCommandScope : ' +BotCommandScope.AsJSON()); + if BotManager1.IsActive then + begin + + try + MyCommands := InjectTelegramBot1.GetMyCommands2(BotCommandScope); + + if MyCommands <> Nil then + Begin + for I := 0 to High(MyCommands) do + Begin + if (High(MyCommands) > 0) then + Begin + if I = 0 then + memConsole.Lines.Add('Command List...'); + if (I >= 0) then + Begin + memConsole.Lines.Add('Command'+IntToStr(I+1)+' : '+MyCommands[I].Command); + memConsole.Lines.Add('Description'+IntToStr(I+1)+' : '+MyCommands[I].Description); + memConsole.Lines.Add('-----------------'); + End; + End; + End; + End + Else + Begin + memConsole.Lines.Add('No Command Found!'); + End; + + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+' ao obter a lista de comandos!'); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; + +procedure TForm1.Button11Click(Sender: TObject); +var + botcmdArr: TArray; + BotCommandScope: TtdBotCommandScopeDefault; + BotCommandScopeType: TtdBotCommandScopeType; +begin + BotCommandScopeType := TtdBotCommandScopeType.BotCommandScopeDefault; + BotCommandScope := TtdBotCommandScopeDefault.Create(BotCommandScopeType); + + botcmdArr := [TtdBotCommand.Create('commandname11','CommandDescription11'), + TtdBotCommand.Create('commandname22','CommandDescription22'), + TtdBotCommand.Create('commandname33','CommandDescription33'), + TtdBotCommand.Create('commandname44','CommandDescription44')]; + + if BotManager1.IsActive then + begin + try + try + InjectTelegramBot1.SetMyCommands2(botcmdArr, BotCommandScope); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+' ao setar os comandos!'); + end; + end; + finally + memConsole.Lines.Add('Command Created!'); + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; + +procedure TForm1.Button12Click(Sender: TObject); +var + BotCommandScope: TtdBotCommandScopeDefault; + BotCommandScopeType: TtdBotCommandScopeType; +begin + BotCommandScopeType := TtdBotCommandScopeType.BotCommandScopeDefault; + BotCommandScope := TtdBotCommandScopeDefault.Create(BotCommandScopeType); + + if BotManager1.IsActive then + begin + try + try + InjectTelegramBot1.DeleteMyCommands2(BotCommandScope); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+' ao deletar a lista de comandos!'); + end; + end; + + finally + memConsole.Lines.Add('Command Deleted!'); + end; + + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; + +procedure TForm1.Button1Click(Sender: TObject); +begin + //Outra forma de Pegar o link com os dados do usuario e remeter na mensagem + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendDice(MyChatId, TtdEmojiType.etBasquete ,False, 0, False, LMarkup); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Basquete); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.Button2Click(Sender: TObject); +begin + if (txtToken.Text = '') or (length(txtToken.Text) < 20) {or ( + BotManager1.Bot.IsValidToken = false)} then + Begin + Showmessage(VRes_Preencha_Token); + End + Else + Begin + //InjectTelegramBot1.Token := txtToken.Text; + //InjectTelegramReceiverService1.Start; + BotManager1.Bot.Token := txtToken.Text; + BotManager1.Start; + End; +end; +procedure TForm1.Button3Click(Sender: TObject); +begin + //InjectTelegramReceiverService1.Stop; + BotManager1.Stop; +end; +procedure TForm1.Button4Click(Sender: TObject); +begin + //Outra forma de Pegar o link com os dados do usuario e remeter na mensagem + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + if {InjectTelegramReceiverService1}BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + {InjectTelegramBot1}BotManager1.Bot.SendDice(MyChatId, TtdEmojiType.etFootball ,False, 0, False, LMarkup); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Basquete); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.Button5Click(Sender: TObject); +begin + //Outra forma de Pegar o link com os dados do usuario e remeter na mensagem + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + if BotManager1.IsActive then + begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendDice(MyChatId, TtdEmojiType.etSlotMachine ,False, 0, False, LMarkup); + except on e:exception do + begin + memConsole.Lines.Add(VRes_Falha+VRes_Basquete); + end; + end; + end + else + memConsole.Lines.Add(VRes_Ative_Servico); +end; +procedure TForm1.Button6Click(Sender: TObject); +var + MT: TThread; + MyMsg : TArray; + Sending: Boolean; +begin + Clique := Clique + 1; + SetLength(MyMsg,Clique); + + MT := TThread.CreateAnonymousThread(procedure + var + I: Integer; + A: Integer; + procedure DeleteArrayItem(X: TArray; Index: Integer); + Begin + if Index > High(X) then Exit; + if Index < Low(X) then Exit; + if Index = High(X) then + SetLength(X, Length(X) - 1); + Exit; + End; + + begin + Sending := True; + + for I := 0 to Length(MyMsg) - 1 do + begin + MyMsg[I].chatId := StrToInt64(txtID.Text); + MyMsg[I].Text := 'ALEATORIO ...'+(I+1).ToString; + MyMsg[I].ParseMode := LParseMode; + end; + + while Sending do + begin + + if InjectTelegramBot1.IsBusy = false then + Begin + for A := 0 to Length(MyMsg) -1 do + Begin + if InjectTelegramBot1.SendMessage( MyMsg[A].chatId, MyMsg[A].Text, MyMsg[A].ParseMode) <> nil then + DeleteArrayItem(MyMsg,A) + else + continue; + + Clique := Clique - 1; + if A = Length(MyMsg) -1 then + Begin + Sending := False; + Clique := 0; + Break; + End; + + End; + End + Else Begin + Sleep(500); + Continue; + End; + end; + + end + ); + MT.FreeOnTerminate := True; + MT.Start; + +end; + +procedure TForm1.Button7Click(Sender: TObject); +var + MT: TThread; +begin + MT := TThread.CreateAnonymousThread(procedure + var + I: Integer; + begin + for I := 1 to 5 do + Begin + InjectTelegramBot1.SendMessage(StrToInt64(txtID.Text),'TEXTO '+I.ToString, + LParseMode, False, False, 0, False, LMarkup); + if I < 5 then + InjectTelegramBot1.IsBusy := True; + if I = 5 then + InjectTelegramBot1.IsBusy := False; + End; + end + ); + MT.FreeOnTerminate := True; + MT.Start; +end; + +procedure TForm1.Button8Click(Sender: TObject); +var + MyBT: TtdKeyboardWebAppButton; //TtdKeyboardWebAppButton + web: TtdWebAppInfo; + url, ButtonName: string; +begin + + try + url := InputBox('Preencha o Campo com sua URL do Web Bot','URL','https://www.clinicarocha.com.br/webbot/'); + ButtonName := InputBox('Preencha o Campo com um nome para o Boto do Web Bot','Nome do Boto','WEBAPP EXEMPLO'); + + web := TtdWebAppInfo.Create(url); + + MyBT := TtdKeyboardWebAppButton.Create(ButtonName, web); + + LMarkup := TtdReplyKeyboardMarkup.Create([ + { Primeira Linha } + [MyBT], + { Segunda Linha } + []], TRUE); + if BotManager1.IsActive then + Begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendMessage(StrToInt64(txtID.Text), + 'Acesse aqui o web bot e divirte-se testando!', + LParseMode, False, False, 0, False, LMarkup) + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); + finally + web.Free; + end; +end; + +procedure TForm1.Button9Click(Sender: TObject); +var + MyBT: TtdInlineKeyboardButton{TtdInlineKeyboardWebAppButton}; + web: TtdWebAppInfo; + url, ButtonName: string; +begin + + url := InputBox('Preencha o Campo com sua URL do Web Bot','URL','https://www.clinicarocha.com.br/webbot/'); + ButtonName := InputBox('Preencha o Campo com um nome para o Boto do Web Bot','Nome do Boto','TESTE'); + + web := TtdWebAppInfo.Create(url); + + MyBT := TtdInlineKeyboardButton.Create(ButtonName, web); + // MyBT.SwitchInlineQuery := '123456'; + // MyBT.WebApp := web; + LMarkup := TtdInlineKeyboardMarkup.Create([ + { Primeira Linha } + [MyBT]]); + if BotManager1.IsActive then + Begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendMessage(StrToInt64(txtID.Text), + 'Acesse aqui o web bot e divirte-se testando!', + LParseMode, False, False, 0, False, LMarkup) + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); + +end; + +procedure TForm1.btnEnviarTxtComBTInlineClick(Sender: TObject); +begin +{ +Aqui voc cria os botoes do tipo ReplyKeyboard para enviar na mensagem +eles sero criados como um teclado personalizado para seu destinatario +} +//Necessario declarar TelegAPI.Types.ReplyMarkups +LMarkup := TtdInlineKeyboardMarkup.Create([ + { Primeira Linha } + [TtdInlineKeyboardButton.Create('TEXTO 1','texto1'), + TtdInlineKeyboardButton.Create('TEXTO 2','texto2')], + { Segunda Linha } + [TtdInlineKeyboardButton.Create('TEXTO 3','texto3'), + TtdInlineKeyboardButton.Create('ARTIGO','123456789456'), + TtdInlineKeyboardButton.Create('MEU ID','meuid')], + { TErceira Linha } + [TtdInlineKeyboardButton.Create('INICIO','inicio'), + TtdInlineKeyboardButton.Create('FECHAR','fechar')]]); + + + + if BotManager1.IsActive then + Begin + if txtID.Text <> '' then + try + InjectTelegramBot1.SendMessage(StrToInt64(txtID.Text),VRes_MSG_Exemplo_Envio_BT, LParseMode, False, False, 0, False, LMarkup) + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; +function SingleToStr(Value: String): String; +var + FloatValue: Extended; +Begin + floatValue := strtofloat(Value); + result := FloatToStr(floatValue); +End; +procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); +begin +// if InjectTelegramReceiverService1.IsActive then +// InjectTelegramReceiverService1.Stop; + if BotManager1.IsActive then + BotManager1.Stop; +end; +procedure TForm1.FormCreate(Sender: TObject); +begin + {Envie Markdown ou HTML, se voc deseja que os aplicativos Telegram + mostrem texto em negrito, itlico, largura fixa ou URLs embutidos na + mensagem do seu bot.} + LParseMode := TtdParseMode.Markdown; //Necessario declarar TelegAPI.Types.Enums + FileCount := 0; + AbrirArquivo.InitialDir := '../../'+ExtractFilePath(Application.ExeName)+'\midias'; +end; +procedure TForm1.FormShow(Sender: TObject); +begin + AplicarResource; +end; +procedure TForm1.GetForumStikersTopicClick(Sender: TObject); +var + MyStickerArray : TArray; + I: Integer; +begin + + if BotManager1.IsActive then + Begin + try + SetLength(MyStickerArray, Length(BotManager1.Bot.getForumTopicIconStickers) + 1); + MyStickerArray := BotManager1.Bot.getForumTopicIconStickers; + + for I := 0 to Length(MyStickerArray) - 1 do + Begin + memConsole.Lines.Add( + '---------------------------------------------------------------------'+sLineBreak+ + 'CustomEmojiId : '+MyStickerArray[I].CustomEmojiId.ToString+sLineBreak+ + 'Emoji : '+MyStickerArray[I].Emoji+sLineBreak); + End; + + // memConsole.Lines.Add(TJsonUtils.ArrayToJString(BotManager1.Bot.getForumTopicIconStickers)); + except on E: Exception do + memConsole.Lines.Add('Falha ao criar um tpico - ' + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; + +procedure TForm1.InjectTelegramBot1Disconect(ASender: TObject; + const AErrorCode: string); +begin +// while Not BotManager1.IsActive do +// Begin +// BotManager1.Stop; +// Sleep(1000); +// BotManager1.Start; +// End; + //Showmessage('Sua Aplicao perdeu a conexo com o servidor!'); +end; +procedure TForm1.InjectTelegramBot1ReceiveRawData(ASender: TObject; + const AData: string); +var + TLOEvent, TLOReplyMarkup: ISuperObject; + TLAInlineKeyBoard: ISuperArray; + I: Integer; + + LValue: string; + LObj: TJSONValue; + FJSON: TJSONObject; + MyKey: TtdInlineKeyboardMarkup; +begin +// Result := nil; +// LObj := FJSON.GetValue('reply_markup'); +// if Assigned(LObj) and (not LObj.Null) then +// begin +// +// LValue := LObj.ToJSON; +// +// // MyKey := FJSON.Create(LValue) as T; +// end; + +{$REGION 'DOCUMENTATION'} +(* + +{ + "ok":true, + "result":[ + { + "update_id":118364456, + "message":{ + "message_id":7250, + "from":{ + "id":1042366601, + "is_bot":false, + "first_name":"Ruan Diego", + "last_name":"Lacerda Menezes", + "username":"diegolacerdamenezes", + "language_code":"pt-br" + }, + "chat":{ + "id":1042366601, + "first_name":"Ruan Diego", + "last_name":"Lacerda Menezes", + "username":"diegolacerdamenezes", + "type":"private" + }, + "date":1650550138, + "forward_from_chat":{ + "id":-1001560050482, + "title":"HOLDING IR TR UR", + "type":"channel" + }, + "forward_from_message_id":151, + "forward_date":1648714863, + "photo":[ + { + "file_id":"AgACAgQAAxkBAAIcUmJhZXrj4LtPciacYnwfMiFpZiICAAKUuTEbo7opUg0LK__MttVVAQADAgADcwADJAQ", + "file_unique_id":"AQADlLkxG6O6KVJ4", + "file_size":2701, + "width":87, + "height":90 + }, + { + "file_id":"AgACAgQAAxkBAAIcUmJhZXrj4LtPciacYnwfMiFpZiICAAKUuTEbo7opUg0LK__MttVVAQADAgADbQADJAQ", + "file_unique_id":"AQADlLkxG6O6KVJy", + "file_size":40897, + "width":310, + "height":320 + }, + { + "file_id":"AgACAgQAAxkBAAIcUmJhZXrj4LtPciacYnwfMiFpZiICAAKUuTEbo7opUg0LK__MttVVAQADAgADeAADJAQ", + "file_unique_id":"AQADlLkxG6O6KVJ9", + "file_size":147542, + "width":774, + "height":800 + }, + { + "file_id":"AgACAgQAAxkBAAIcUmJhZXrj4LtPciacYnwfMiFpZiICAAKUuTEbo7opUg0LK__MttVVAQADAgADeQADJAQ", + "file_unique_id":"AQADlLkxG6O6KVJ-", + "file_size":171172, + "width":968, + "height":1000 + }], + "caption":"\u062e\u062f\u0627 \u0642\u0648\u062a \u062f\u0648\u0633\u062a + \u0639\u0632\u06cc\u0632.\ud83c\udf08\ud83c\udf08\ud83d\udc99\n\n\ud83c + \udf3a\ud83c\udf3a\ud83c\udf3a\u0627\u0645\u06cc\u062f\u0648\u0627\u0631 + \u06cc\u0645 \u0632\u0646\u062f\u06af\u06cc\u062a\u0648\u0646 \u067e\u0631 + \u0627\u0632 \u0634\u0627\u062f\u06cc \u0648 \u0635\u0641\u0627 \u0628\u0627 + \u0634\u0647\ud83c\udf3a\ud83c\udf3a\ud83c\udf3a\n\n\ud83c\udf0e\ud83c\udf0e + \u06af\u0631\u0648\u0647 \u0642\u062f\u0631\u062a\u0645\u0646\u062f \u062a + \u0628\u0644\u06cc\u063a \u0631\u0627\u06cc\u06af\u0627\u0646 : \u062a\u0631 + \u06a9\u06cc\u0647|| \u0627\u06cc\u0631\u0627\u0646 || \u062c\u0647\u0627 + \u0646||\ud83c\udf0e\ud83c\udf0e\n\n \ud83d\udc99\ud83d\udc99\u067e\u0631 + \u0628\u0627\u0632\u062f\u06cc\u062f \u0628\u0631\u0627\u06cc \u0645\u0639 + \u0631\u0641\u06cc \u0648 \u0631\u0648\u0646\u0642 \u062a\u062c\u0627\u0631 + \u062a \u0648 \u06a9\u0633\u0628 \u0648 \u06a9\u0627\u0631 \u0634\u0645\u0627 + \u062f\u0631 \u0627\u06cc\u0631\u0627\u0646\u060c\u062a\u0631\u06a9\u06cc\u0647 + \u0648 \u0627\u0631\u0648\u067e\u0627\ud83d\udc99\ud83d\udc99\n\n\u0628\u062f\u0648 + \u0646 \u0645\u062d\u062f\u0648\u062f\u06cc\u062a \u0645\u06cc\u062a\u0648\u0646 + \u06cc\u062f \u062a\u0628\u0644\u06cc\u063a \u06a9\u0646\u06cc\u0646.\ud83d\udc99 + \ud83c\udf3a\ud83d\udc99\n\ud83d\udc4c\ud83d\udc4c\ud83d\udc4c\u0634\u0627\u0645 + \u0644 \u0645\u0639\u0631\u0648\u0641\u062a\u0631\u06cc\u0646 \u0641\u0639\u0627 + \u0644\u0627\u0646 \u0635\u0646\u0641\u06cc \u0648 \u0628\u0631\u0646\u062f\u0647 + \u0627\u06cc \u0645\u0639\u062a\u0628\u0631 \u06a9\u0633\u0628 \u0648 \u06a9\u0627 + \u0631 \u062f\u0631 \u062a\u0631\u06a9\u06cc\u0647-\u0627\u06cc\u0631\u0627\u0646- + \u06af\u0631\u062c\u0633\u062a\u0627\u0646 \ud83d\udc4c\ud83d\udc4c\ud83d\udc4c + \n\n\n\ud83d\udfe2\u062a\u0628\u0644\u06cc\u063a\u0627\u062a \u0622\u0632\u0627 + \u062f\n\ud83d\udfe2\u0631\u06af\u0628\u0627\u0631\u06cc\n\ud83d\udfe2\u0641\u0627 + \u0635\u0644\u0647 \u06cc \u0628\u06cc\u0646 \u0647\u0631 \u067e\u0633\u062a : 10 + \u062b\u0627\u0646\u06cc\u0647\n\ud83d\udfe2\u0634\u0628\u0627\u0646\u0647 + \u0631\u0648\u0632\u06cc\n\n\u0628\u0647\u062a\u0631\u06cc\u0646 \u06af\u0631\u0648 + \u0647 \u0628\u0627\u0632\u0627\u0631\u06cc\u0627\u0628\u06cc \u0648 \u062a\u062c + \u0627\u0631\u062a \u0648 \u06a9\u0633\u0628 \u0648 \u06a9\u0627\u0631\ud83c\udf3a + \ud83c\udf3a\ud83c\udf3a\n\n\ud83d\udc47\ud83d\udc47\ud83d\udc47\u06a9\u0644\u06cc + \u06a9 \u06a9\u0646\u06cc\u062f\ud83d\udc47\ud83d\udc47\ud83d\udc47", + "reply_markup":{ + "inline_keyboard":[ + [ + { + "text":"\u0648\u0631\u0648\u062f \u0628\u0647 \u06af\u0631\u0648\u0647 \u0627\u06cc\u0631\u0627\u0646 \u062a\u0631\u06a9\u06cc\u0647 \u062c\u0647\u0627\u0646", + "url":"https://t.me/+FxR3O_lP8oZmM2Q0" + } + ] + ] + } + } + } + ] +} + +// memConsole.Lines.Add('ID : '+TLOEvent.A['result'].O[0].I['update_id'].ToString); +// memConsole.Lines.Add('CAPTION : '+TLOEvent.A['result'].O[0].O['message'].S['caption']); +// +// memConsole.Lines.Add('CHAT ID : '+TLOEvent.A['result'].O[0].O['message'].O['chat'].I['id'].ToString ); +// memConsole.Lines.Add('FORWARD ID : '+TLOEvent.A['result'].O[0].O['message'].I['forward_from_message_id'].ToString); +// memConsole.Lines.Add('MESSAGE ID : '+TLOEvent.A['result'].O[0].O['message'].I['message_id'].ToString); +// memConsole.Lines.Add('REPLYMARKUP : '+TLOEvent.A['result'].O[0].O['message'].O['reply_markup'].A['inline_keyboard'].A[0].O[0].S['text']); +// memConsole.Lines.Add('URL : '+TLOEvent.A['result'].O[0].O['message'].O['reply_markup'].A['inline_keyboard'].A[0].O[0].S['url']); + +*) +{$ENDREGION 'DOCUMENTATION'} + +// if (AData <> '{"ok":true,"result":[]}') and (AData <> '{"ok":true,"result":true}') then +// memConsole.Lines.Add('RECEIVING : '+AData); +// +// ///For example: +// TLOEvent := SO(AData); +// +// if TLOEvent <> nil then +// Begin +// if Assigned(TLOEvent.A['result'].O[0].O['message'].O['reply_markup']) then +// Begin +// TLOReplyMarkup := TLOEvent.A['result'].O[0].O['message'].O['reply_markup']; +// TLAInlineKeyBoard := TLOReplyMarkup.A['inline_keyboard']; +// for I := 0 to TLOReplyMarkup.A['inline_keyboard'].A[0].Length -1 do +// Begin +// +// /// +// /// Here you do what you need with the button +// /// +// +// ///For example: +// memConsole.Lines.Add('TEXTO : '+TLAInlineKeyBoard.A[0].O[I].S['text']); +// memConsole.Lines.Add('URL : '+TLAInlineKeyBoard.A[0].O[I].S['url']); +// End; +// End; +// End; + + (* +{ + "ok":true, + "result":{ + "file_id":"AgACAgQAAxkBAAIcY2Jhdu-dCZnuiVt7kgY4PaBYUTiHAAKXuDEb8fSQUq_9U-I_3GU7AQADAgADcwADJAQ", + "file_unique_id":"AQADl7gxG_H0kFJ4", + "file_size":2246, + "file_path":"photos/file_15.jpg" + } +} + *) + +end; +procedure TForm1.InjectTelegramBot1SendData(ASender: TObject; const AUrl, + AData: string); +begin +// memConsole.Lines.Add('SENDING URL: '+AUrl); +// memConsole.Lines.Add('SENDING DATA: '+AData); +end; +procedure TForm1.InjectTelegramExceptionManagerUI1Log(ASender: TObject; + const Level: TLogLevel; const Msg: string; E: Exception); + var Texto: String; +begin + if level >= TLogLevel.Error then + begin + if Assigned(e) then + Begin + memConsole.Lines.Add(msg + ' [ '+Texto + ' '+ e.ToString + '] ' ); + End + else + memConsole.Lines.Add(msg); + end; +end; +procedure TForm1.ReceiverCallbackQuery(ASender: TObject; + ACallbackQuery: ItdCallbackQuery); + var + Res: TtdInlineQueryResult; + + MyBT: TtdKeyboardWebAppButton; //TtdKeyboardWebAppButton + web: TtdWebAppInfo; + url, ButtonName: string; +begin + + if ACallbackQuery.Data.ToLower.Equals('texto1') then + Begin + memConsole.Lines.Add(VRes_O_Usuario+ + ACallbackQuery.From.FirstName+VRes_Solicitou+ + ACallbackQuery.Data + ' - CallbackQueryEvent!'); + + BotManager1.Bot.SendMessage(ACallbackQuery.From.ID,'texto1 - CallbackQueryEvent!'); + End; + + if ACallbackQuery.Data.ToLower.Equals('texto2') then + Begin + memConsole.Lines.Add(VRes_O_Usuario+ + ACallbackQuery.From.FirstName+VRes_Solicitou+ + ACallbackQuery.Data + ' - CallbackQueryEvent!'); + + BotManager1.Bot.SendMessage(ACallbackQuery.From.ID,'texto2 - CallbackQueryEvent!'); + End; + + if ACallbackQuery.Data.ToLower.Equals('texto3') then + Begin + memConsole.Lines.Add(VRes_O_Usuario+ + ACallbackQuery.From.FirstName+VRes_Solicitou+ + ACallbackQuery.Data + ' - CallbackQueryEvent!'); + + BotManager1.Bot.SendMessage(ACallbackQuery.From.ID,'texto3 - CallbackQueryEvent!'); + End; + + if ACallbackQuery.Data.ToLower.Equals('inicio') then + Begin + + try + url := 'https://www.clinicarocha.com.br/webbot/'; + ButtonName := 'WEBAPP EXEMPLO'; + + web := TtdWebAppInfo.Create(url); + + MyBT := TtdKeyboardWebAppButton.Create(ButtonName, web); + + LMarkup := TtdReplyKeyboardMarkup.Create([ + { Primeira Linha } + [MyBT], + { Segunda Linha } + []], TRUE); + + + finally + BotManager1.Bot.SendMessage(ACallbackQuery.From.ID,'Boto Criado - CallbackQueryEvent!' + , LParseMode, False, False, 0, False, LMarkup); + + web.Free; + end; + End; + + if ACallbackQuery.Data.ToLower.Equals('fechar') then + Begin + + LMarkup := TtdReplyKeyboardRemove.Create(); + + BotManager1.Bot.SendMessage(ACallbackQuery.From.ID,'Boto Destruido - CallbackQueryEvent!' + , LParseMode, False, False, 0, False, LMarkup); + End; + + + if ACallbackQuery.Data.ToLower.Equals('meuid') then + Begin + memConsole.Lines.Add(VRes_O_Usuario+ + ACallbackQuery.From.FirstName+' ID : '+ACallbackQuery.From.ID.ToString+VRes_Solicitou+ + '' + ACallbackQuery.message.Text + ' - CallbackQueryEvent!'); + + MyChatId := TtdUserLink.FromID(ACallbackQuery.From.ID); + + BotManager1.Bot.SendMessage(MyChatId, + ACallbackQuery.From.FirstName+' '+ACallbackQuery.Message.Text+sLineBreak+ + ' Seu ID : '+ACallbackQuery.From.ID.ToString + ' - CallbackQueryEvent!', + LParseMode, False, False,0,False{,LMarkup, False}); + End; + + if ACallbackQuery.Data.ToLower.Equals('123456789456') then + Begin + try + Res := TtdInlineQueryResult.Create; + Res.ID := '123456789456'; + Res.&Type := 'article'; + Res.Title := 'TESTE DE TITULO - CallbackQueryEvent'; + Res.InputMessageContent := TtdInputTextMessageContent.Create('OLA MUNDO','Markdown' ,False); + memConsole.Lines.Add('inline_message_id : '+BotManager1.Bot.answerWebAppQuery('123456789456',Res).inline_message_id); + finally + Res.Free; + end; + End; + +end; +procedure TForm1.ChosenInlineResult( + ASender: TObject; AChosenInlineResult: ItdChosenInlineResult); +begin + if AChosenInlineResult.Query.ToLower.Equals('texto3retornoembutido') then + memConsole.Lines.Add(VRes_O_Usuario+ + AChosenInlineResult.From.FirstName+VRes_Solicitou+ + AChosenInlineResult.Query); +end; + +procedure TForm1.CriarTopicoClick(Sender: TObject); +var + MyTopic: ItdForumTopic; + TopicName: string; +begin + if BotManager1.IsActive then + Begin + TopicName := InputBox('Informe um Nome para o Tpico', 'Nome','TInjectTelegram - Topic01'); + if txtID.Text <> '' then + try + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + MyTopic := BotManager1.Bot.createForumTopic(MyChatId.ID, TopicName); + BotManager1.Bot.SendMessage(MyTopic.message_thread_id, 'Texto de Abertura para o Topico Do TInjectTelegramBot', + LParseMode,False,False,0,False,LMarkup,False); + except on E: Exception do + memConsole.Lines.Add('Falha ao criar um tpico - ' + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; + +procedure TForm1.CarregarBTStr(AStrArrayBtName: TArray>; + AInlineMode: Boolean; url: string); +var + I, O: Integer; + str: String; + //InLine Mode + LButtonIL: TArray; + DButtonIL: TArray; + RButtonIL: TArray>; + + //Reply Mode + LButton : TArray; + DButton : TArray; + RButton : TArray>; + + webinfo: TtdWebAppInfo; +Begin +{ +Exemplo de uso +Assim ela criara os botoes de acordo com a quantidade de itens do array bidimencional + CarregarBTStr([['REMOVER','FINALIZAR'],['INICIO','SAIR']]); +} + try + SetLength(AStrArrayBtName, Length(AStrArrayBtName[0]) + Length(AStrArrayBtName[1])); + + if AInlineMode = False then //Reply Mode + Begin + + SetLength(LButton, Length(AStrArrayBtName[0])); + SetLength(DButton, Length(AStrArrayBtName[1])); + SetLength(RButton, Length(LButton) + Length(DButton)); + + for I := 0 to Length(AStrArrayBtName[0]) - 1 do + LButton[I] := TtdKeyboardButton.Create(String(AStrArrayBtName[0,I])); + + if Length(AStrArrayBtName[1]) > 0 then + Begin + for O := 0 to Length(AStrArrayBtName[1]) - 1 do + DButton[O] := TtdKeyboardButton.Create(String(AStrArrayBtName[1,O])); + + RButton[LOW(RButton)] := LButton; + RButton[HIGH(RButton)] := DButton; + + LMarkup := TtdReplyKeyboardMarkup.Create(RButton,TRUE); + End Else + LMarkup := TtdReplyKeyboardMarkup.Create([LButton],TRUE); + End + Else //Inline Mode + Begin + + SetLength(LButtonIL, Length(AStrArrayBtName[0])); + SetLength(DButtonIL, Length(AStrArrayBtName[1])); + SetLength(RButtonIL, Length(LButtonIL) + Length(DButtonIL)); + + for I := 0 to Length(AStrArrayBtName[0]) - 1 do + begin + LButtonIL[I] := TtdInlineKeyboardButton.Create(String(AStrArrayBtName[0,I]),String(AStrArrayBtName[0,I])); + end; + + if Length(AStrArrayBtName[1]) > 0 then + Begin + for O := 0 to Length(AStrArrayBtName[1]) - 1 do + begin + DButtonIL[O] := TtdInlineKeyboardButton.Create(String(AStrArrayBtName[1,O]),String(AStrArrayBtName[1,O])); + end; + + RButtonIL[LOW(RButtonIL)] := LButtonIL; + RButtonIL[HIGH(RButtonIL)] := DButtonIL; + + LMarkup := TtdInlineKeyboardMarkup.Create(RButtonIL); + End + Else + LMarkup := TtdInlineKeyboardMarkup.Create([LButtonIL]); + End; + + finally + LButtonIL := Nil; + DButtonIL := Nil; + RButtonIL := Nil; + + LButton := Nil; + DButton := Nil; + RButton := Nil; + end; + +end; + +procedure TForm1.ReceiverMessage(ASender: TObject; + AMessage: ItdMessage); +var + mRPL : IReplyMarkup; + I: Integer; + A: Integer; + AOutDir: String; +begin +(* +data_check_string = ... +secret_key = HMAC_SHA256(, "WebAppData") +if (hex(HMAC_SHA256(data_check_string, secret_key)) == hash) { + // data is from Telegram +} + + +uses system.hash; + +var s, sst:string; +bt:TBytes; + +HMAC 256: + +s:=THashSHA2.GetHMAC(DATA, KEY, SHA256); + +base64 HMAC 256: + +bt:= THashSHA2.GetHMACAsBytes(DATA, KEY, SHA256); +sst:= TNetEncoding.Base64.EncodeBytesToString(bt); + + +*) +// if AMessage.ReplyMarkup <> nil then +// Begin +// mRPL := TtdInlineKeyboardMarkup(AMessage.ReplyMarkup); +// +// for I := 0 to TtdInlineKeyboardMarkup(mRPL).RefCount -1 do +// bEGIN +// for A := 0 to TtdInlineKeyboardMarkup(mRPL).RefCount -1 do +// BEGIN +// memConsole.Lines.Add('Keyboard ('+IntToStr(I) +', '+IntToStr(A)+') '+TtdInlineKeyboardMarkup(mRPL).Keyboard[I][A].Text); +// end; +// end; +// End; + (* + +'{"inline_keyboard":[[{"text":"asdfasdf","url":"aswdfasdf"}]]}' + *) +// if AMessage.ReplyMarkup <> NIl then +// Begin +// memConsole.Lines.Add('Text = '+((AMessage as TtdMessage).ReplyMarkup as TtdInlineKeyboardMarkup).Keyboard[0][0].Text); +// memConsole.Lines.Add('Url = '+((AMessage as TtdMessage).ReplyMarkup as TtdInlineKeyboardMarkup).Keyboard[0][1].Url); +// memConsole.Lines.Add('CallbackData = '+((AMessage as TtdMessage).ReplyMarkup as TtdInlineKeyboardMarkup).Keyboard[0][1].CallbackData); +// End; + +// if AMessage.WebAppData <> nil then +// Begin +// memConsole.Lines.Add('WEB DATA : '); +// memConsole.Lines.Add('button_text : '+AMessage.WebAppData.button_text); +// memConsole.Lines.Add('data : '+AMessage.WebAppData.data); +// End; + + if AMessage.Text <> '' then + memConsole.Lines.Add( + 'Mensagem do Usurio '+ AMessage.From.FirstName+' : '+AMessage.Text); + with BotManager1 do + Begin + with Conversa do + Begin + memConsole.Lines.Add( + 'Coversa ID : '+ ID+sLineBreak+ + 'MSG : '+ MSGText+sLineBreak+ + 'IdChat : ' + ChatId.ToString+sLineBreak+ + 'Nome : ' + Name+sLineBreak+ + 'UltimaIteracao : ' +TimeToStr(LastIteration)+sLineBreak+ + 'MessageThreadId : '+AMessage.MessageThreadId.ToString+sLineBreak+ + '***********************************************************'); + End; + End; + + if AMessage.&Type = TtdMessageType.ContactMessage then + memConsole.Lines.Add(VRes_O_Usuario+ + AMessage.From.FirstName+VRes_Compartilhou_CTT+ + VRes_Telefone +AMessage.Contact.PhoneNumber+ + ' ID : '+AMessage.Contact.UserId.ToString); + + if AMessage.&Type = TtdMessageType.LocationMessage then + memConsole.Lines.Add(VRes_O_Usuario+ + AMessage.From.FirstName+VRes_Compartilhou_Localizacao+ + 'Latitude : '+AMessage.Location.Latitude.ToString+ + ' Longitude : '+AMessage.Location.Longitude.ToString); + + if AMessage.Text.ToLower.Equals('meuid') then + Begin + memConsole.Lines.Add(VRes_O_Usuario+ + AMessage.From.FirstName+' ID : '+AMessage.From.ID.ToString+VRes_Solicitou+ + '' + AMessage.Text); + MyChatId := TtdUserLink.FromID(AMessage.From.ID); + BotManager1.Bot.SendMessage(MyChatId, + AMessage.From.FirstName+' '+VRes_Solicitou+' '+AMessage.Text+sLineBreak+ + ' Seu ID : '+AMessage.From.ID.ToString, + LParseMode, False, False,0,False{,LMarkup, False}); + End; + + if AMessage.Text.ToLower.Equals('inicio') then + Begin + memConsole.Lines.Add('Boto Criado - OnMessageEvent'); + MyChatId := TtdUserLink.FromID(AMessage.From.ID); + BotManager1.Bot.SetChatMenuButton(MyChatId, + 'https://www.clinicarocha.com.br/webbot/', + 'TinjectTelegram',TtdMenuButtonType.MenuButtonWebApp); + End; + + if AMessage.Text.ToLower.Equals('fechar') then + Begin + memConsole.Lines.Add('Boto Destruido - OnMessageEvent'); + MyChatId := TtdUserLink.FromID(AMessage.From.ID); + BotManager1.Bot.SetChatMenuButton(MyChatId, + 'https://www.clinicarocha.com.br/webbot/', + 'TinjectTelegram',TtdMenuButtonType.MenuButtonCommands); + End; + + if (Pos(LowerCase(AMessage.Text),'oi.ola.bom.dia.boa.tarde.noite') > 0) then + Begin + + // CarregarBTStr([['Web Bot']], true,'https://produlog.com.br/tinjecttelegram/'); + MyChatId := TtdUserLink.FromID(AMessage.From.ID); + BotManager1.Bot.SendMessage(MyChatId, + 'Ol, Digite inicio para criar o boto do webbot e fechar para destruir o boto.', + LParseMode, False, False,0,False{,LMarkup, False}); + + End; + + if AMessage.ReplyToMessage <> NIl then + memConsole.Lines.Add( + 'Resposta do Usario : '+ AMessage.From.FirstName+sLineBreak+ + ' Para o Usario : '+ AMessage.ReplyToMessage.From.FirstName+sLineBreak+ + ' ID MSG Resposta : '+AMessage.From.ID.ToString+sLineBreak+ + ' ID MSG Pergunta : '+AMessage.ReplyToMessage.From.ID.ToString+sLineBreak+ + ' Resposta : ' + AMessage.Text+sLineBreak+ + ' Pergunta : ' + AMessage.ReplyToMessage.Text); + + //it is necessary to give permission to the project folder so that the bot can create the folders + //Com CMD usar os Comandos para dar Permisso: ICACLS NomeOuDiretrioDoArquivo /GRANT NomeDoUsurioOuGrupoDeUsurios:F + With BotManager1 do + Begin + if Conversa.ReceivedFile <> '' then + Begin //memConsole is TMemo + memConsole.Lines.Add('Arquivo Recebido : '+ ExtractFileNameFromURL(Conversa.ReceivedFile)); //ExtractFileNameFromURL is New Metod from Compoent TinjectTelegramBotManager + if CreateSubDir(Conversa.ClientId.ToString, AOutDir) then //CreateSubDir is New Metod from Compoent TinjectTelegramBotManager + Begin + memConsole.Lines.Add('OutDir : '+ AOutDir); //Var AOutDir: string; + if DownloadFile(Conversa.ReceivedFile, AOutDir) then //DownloadFile is New Metod from Compoent TinjectTelegramBotManager + memConsole.Lines.Add('Arquivo Baxado em : '+ AOutDir+' ...') + else + memConsole.Lines.Add('Erro ao baixar o arquivo : '+ ExtractFileName(Conversa.ReceivedFile)); + End + Else + memConsole.Lines.Add('Erro ao criar a pasta : '+ AOutDir+'\'+Conversa.ClientId.ToString); + End; + End; +end; +procedure TForm1.SendTextTopicClick(Sender: TObject); +var + MyTopicId: Int64; +begin + if BotManager1.IsActive then + Begin + if txtID.Text <> '' then + try + MyTopicId := InputBox('Informe o Id do Topico', 'ID','0').ToInt64; + MyChatId := TtdUserLink.FromID(StrToInt64(txtID.Text)); + BotManager1.Bot.SendMessage( + MyChatId.ID, + VRes_Este_Seu_ID + MyChatId.ID.ToString, + LParseMode, False, cbDisableNotification.Checked, 0, + False, LMarkup, cbProtectedContent.Checked, MyTopicId); + except on E: Exception do + memConsole.Lines.Add(VRes_Falha_Envio_Destinatario + E.Message); + end; + End + else + Showmessage(VRes_Ative_Servico); +end; + +procedure TForm1.ServiceStart(Sender: TObject); +begin + memConsole.Lines.Add(VRes_Servico_Ativo); +end; +procedure TForm1.ServiceStop(Sender: TObject); +begin + memConsole.Lines.Add(VRes_Servico_Desativado); +end; +end. diff --git a/v1.4.4/Exemplo/uResourceString.pas b/v1.4.4/Exemplo/uResourceString.pas new file mode 100644 index 0000000..7a262a9 --- /dev/null +++ b/v1.4.4/Exemplo/uResourceString.pas @@ -0,0 +1,96 @@ + +unit uResourceString; + +interface + +ResourceString + ARes_Filtro_Foto_Video = 'Fotos e Videos|*.jpeg;*.jpg;*.gif;*.png;*.bmp;*.mp4;*.wmv;*.vid;*.flv;*.m4v;*.f4v;*.lrv'; + ARes_Filtro_Video = 'Videos|*.mp4;*.wmv;*.vid;*.flv;*.m4v;*.f4v;*.lrv;*.tgs|Todos|*.*'; + ARes_Filtro_Fotos = 'Fotos|*.jpeg;*.jpg;*.gif;*.png;*.bmp|Todos|*.*'; + ARes_Filtro_Voz = 'Arquivo de Voz|*.mp3;*.wav;*.ogg'; + ARes_Filtro_Stiker = 'Stiker|*.jpeg;*.jpg;*.gif;*.png;*.bmp;*.tgs'; + ARes_Filtro_Todos = 'Todos os Arquivos|*.*'; + ARes_Filtro_Audio = 'Audio|*.mp3;*.wav;*.ogg'; + + // + ARes_Animacao = 'Animao.'; + ARes_Dado = ' Dado.'; + ARes_Dardo = ' Dardo.'; + ARes_Basquete = 'Basquete.'; + ARes_Grav_Voz = ' Gravao de Voz.'; + ARes_Video = ' Vdeo.'; + ARes_Audio = ' Audio.'; + ARes_Imagem = ' Imagem.'; + ARes_Acao = ' Ao.'; + ARes_Localizacao = ' Localizao.'; + ARes_Stiker = ' Stiker.'; + ARes_Enquete_Quiz = ' Enquete ou Quiz.'; + ARes_Nota_Video = 'Nota de Vdeo.'; + ARes_Jogo = ' Jogo.'; + ARes_Contato = ' Contato.'; + ARes_Pagamento = ' Pagamento.'; + ARes_Documento = ' Documento.'; + ARes_GrupoMidia = ' Midias.'; + + // + ARes_Texto_Video = 'Texo do Vdeo'; + ARes_Texto_Voz = 'Texo da Voz'; + ARes_Texto_Audio = 'Texto do Audio'; + ARes_Texto_Animacao = 'Texo da Animo'; + ARes_Texto_Foto = 'Texto da Foto'; + ARes_Texto_Documento = 'Texo do Documento'; + + // + ARes_Falha = '**** Falha ***** Tente outro(a) '; + ARes_Falha_Envio_Destinatario = 'Falha no Envio para este destinatio - '; + + ARes_Ative_Servico = 'Ative o Servio primeiro!'; + ARes_Preencha_Token = 'Preencha o campo do Token com um valor vlido, antes'; + + ARes_MSG_Exemplo_Envio_BT = 'Esta uma mensagem de exemplo para teste de envio dos botes'; + + ARes_Servico_Ativo = 'Servio Ativado!'; + ARes_Servico_Desativado = 'Servio Desativado!'; + + ARes_O_Usuario = 'O Usuario : '; + ARes_Compartilhou_CTT = ' Compartilhou seu Contato '; + ARes_Compartilhou_Localizacao = ' Compartilhou sua Localizao '; + ARes_Solicitou = ' Solicitou '; + ARes_Telefone = 'Telefone : '; + ARes_Qual_Meu_ID = 'Qual Meu ID?'; + + ARes_Ola_Me_Passe_Localizacao = 'Ol Caro Usuario, voc pode me fornecer sua Localizao para prosseguir com o atendimento?'; + ARes_Solicitacao_Env_Mas_Incomp_Teleg_Descktop = 'Solicitao enviada, mas no compativel com a verso desktop do Telegram!'; + ARes_Ola_Me_Passe_Contato = 'Ol Caro Usuario, voc pode me fornecer seu contato para continuar com o atendimento?'; + ARes_Enviar_Localizacao = 'Enviar Minha Localizao'; + ARes_Enviar_Contato = 'Enviar Meu Contato'; + ARes_Use_Seu_Cel_Envio_MeuID = 'Use seu celular para enviar o comando meuid para o seu bot e ele retornara seu ID no LOG do Exemplo...'; + + ARes_Este_Seu_ID = 'Este o Seu ID : '; + + ARes_Ex_Endereco_Digitado = 'Exemplo de Endereo digitado...'; + ARes_Ex_Titulo = 'Exemplo de Titulo'; + ARes_Ex_Tipo = 'Teste de tipo'; + ARes_Ex_Remover_BT = 'Esta uma mensagem de exemplo, onde os botes foram removidos...'; + + ARes_Ta_Doidao = 'Ta doido, essa tava fcil, man'; + ARes_Quem_Desc_Brasil = 'Quem Descobriu o Brasil?'; + + ARes_Informe_Jogo_Valido = 'Informe o nome de um jogo Valido primeiro!'; + + ARes_Ajuda_Token_Banco = 'Gere seu Provider_Token no BotFather, use o comando /mybots, clique no seu bot e depois clique em Payments'+#10#13+ + 'Eu recomendo obanco TRANZZO para testes, depois disso clique em Connect Tranzzo Test. Depois retorne ao BotFather e copie'+#10#13+ + ' o Token que aparece na parte superior da lista de bancos'; + + ARes_ProdutoA = 'Goiaba'; + ARes_ProdutoB = 'Abacaxi'; + + ARes_Limite_Arquivos_MediaGroup = 'Voc j atingiu o limite de 10 arquivos para envio agrupado!'; + ARes_Teste_MidiaGroup = 'Meu teste de Midia Group'; + ARes_Titulo_PG = 'Titulo'; + ARes_Descricao_PG = 'Teste de Descrio'; + ARes_PlayLoad_PG = 'LMCODE-Delivery'; +implementation + + +end. diff --git a/v1.4.4/Exemplo/webapp/.htaccess b/v1.4.4/Exemplo/webapp/.htaccess new file mode 100644 index 0000000..b296c69 --- /dev/null +++ b/v1.4.4/Exemplo/webapp/.htaccess @@ -0,0 +1,4 @@ + +# HTID:19712691: DO NOT REMOVE OR MODIFY THIS LINE AND THE LINES BELOW +php_value display_errors 1 +# DO NOT REMOVE OR MODIFY THIS LINE AND THE LINES ABOVE HTID:19712691: diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto.css b/v1.4.4/Exemplo/webapp/WebApp_Projeto.css new file mode 100644 index 0000000..b88941b --- /dev/null +++ b/v1.4.4/Exemplo/webapp/WebApp_Projeto.css @@ -0,0 +1,121 @@ +h1, .h1 +{ + font-family: Arial; + font-weight: bold; + font-size: 32px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +h2, .h2 +{ + font-family: Arial; + font-weight: bold; + font-size: 27px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +h3, .h3 +{ + font-family: Arial; + font-weight: bold; + font-size: 24px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +h4, .h4 +{ + font-family: Arial; + font-weight: bold; + font-size: 21px; + font-style: italic; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +h5, .h5 +{ + font-family: Arial; + font-weight: bold; + font-size: 19px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +h6, .h6 +{ + font-family: Arial; + font-weight: bold; + font-size: 16px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +.CustomStyle +{ + font-family: "Courier New"; + font-weight: bold; + font-size: 16px; + text-decoration: none; + color: #2E74B5; + background-color: transparent; +} +.bt-add +{ + font-weight: bold; + font-size: 13px; + text-decoration: none; + color: #FFFFFF; + background-color: #FBB727; + background-clip: text; + border-radius: 6px; +} +.bt-dec +{ + font-weight: bold; + font-size: 15px; + text-decoration: none; + color: #FFFFFF; + background-color: #FF4500; + background-clip: text; + border-radius: 6px; +} +.bt-ViewOrder +{ + font-weight: bold; + text-align: center; + text-decoration: none; + color: #FFFFFF; + background-color: #32CD32; + border-radius: 6px; +} +.ballon +{ + font-weight: bold; + text-decoration: none; + color: #FFFFFF; + background-color: #FBB727; + background-clip: text; + border: 0px none #FBB727; + border-radius: 20px; +} diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto.wbs b/v1.4.4/Exemplo/webapp/WebApp_Projeto.wbs new file mode 100644 index 0000000..d20d0b9 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto.wbs differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37440bd711acce4738b0_Burger.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37440bd711acce4738b0_Burger.png new file mode 100644 index 0000000..b7c9382 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37440bd711acce4738b0_Burger.png differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37441ab337d5e4457cc7_Coke.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37441ab337d5e4457cc7_Coke.png new file mode 100644 index 0000000..be4736c Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37441ab337d5e4457cc7_Coke.png differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e3744f5c1ad40f25a8e1e_Cake.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e3744f5c1ad40f25a8e1e_Cake.png new file mode 100644 index 0000000..8b82071 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e3744f5c1ad40f25a8e1e_Cake.png differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37450bd711c7c64738b1_Donut.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37450bd711c7c64738b1_Donut.png new file mode 100644 index 0000000..ffe08ad Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37450bd711c7c64738b1_Donut.png differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e374532d68422f6bc60f1_Cookie.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e374532d68422f6bc60f1_Cookie.png new file mode 100644 index 0000000..2ab7a17 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e374532d68422f6bc60f1_Cookie.png differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e374534b4422b6705300c_Fries.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e374534b4422b6705300c_Fries.png new file mode 100644 index 0000000..3719e00 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e374534b4422b6705300c_Fries.png differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37458510fa5eef7770a8_Flan.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37458510fa5eef7770a8_Flan.png new file mode 100644 index 0000000..9b48c79 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37458510fa5eef7770a8_Flan.png differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37461ab337876c457cca_Pizza.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37461ab337876c457cca_Pizza.png new file mode 100644 index 0000000..b1166c5 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37461ab337876c457cca_Pizza.png differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37465305fb44b137ca03_IceCream.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37465305fb44b137ca03_IceCream.png new file mode 100644 index 0000000..2bf5d1c Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37465305fb44b137ca03_IceCream.png differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37467f2c5d106b9abe04_HotDog.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37467f2c5d106b9abe04_HotDog.png new file mode 100644 index 0000000..5c9ed77 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e37467f2c5d106b9abe04_HotDog.png differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e3747af437c7751faae0c_PopCorn.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e3747af437c7751faae0c_PopCorn.png new file mode 100644 index 0000000..e9c0a3b Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e3747af437c7751faae0c_PopCorn.png differ diff --git a/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e3747f5c1ad60da5a8ea4_Tako.png b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e3747f5c1ad60da5a8ea4_Tako.png new file mode 100644 index 0000000..08d5f1d Binary files /dev/null and b/v1.4.4/Exemplo/webapp/WebApp_Projeto/625e3747f5c1ad60da5a8ea4_Tako.png differ diff --git a/v1.4.4/Exemplo/webapp/images/Burger.png b/v1.4.4/Exemplo/webapp/images/Burger.png new file mode 100644 index 0000000..b7c9382 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/Burger.png differ diff --git a/v1.4.4/Exemplo/webapp/images/Cake.png b/v1.4.4/Exemplo/webapp/images/Cake.png new file mode 100644 index 0000000..8b82071 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/Cake.png differ diff --git a/v1.4.4/Exemplo/webapp/images/Coke.png b/v1.4.4/Exemplo/webapp/images/Coke.png new file mode 100644 index 0000000..be4736c Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/Coke.png differ diff --git a/v1.4.4/Exemplo/webapp/images/Cookie.png b/v1.4.4/Exemplo/webapp/images/Cookie.png new file mode 100644 index 0000000..2ab7a17 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/Cookie.png differ diff --git a/v1.4.4/Exemplo/webapp/images/Donut.png b/v1.4.4/Exemplo/webapp/images/Donut.png new file mode 100644 index 0000000..ffe08ad Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/Donut.png differ diff --git a/v1.4.4/Exemplo/webapp/images/Flan.png b/v1.4.4/Exemplo/webapp/images/Flan.png new file mode 100644 index 0000000..9b48c79 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/Flan.png differ diff --git a/v1.4.4/Exemplo/webapp/images/Fries.png b/v1.4.4/Exemplo/webapp/images/Fries.png new file mode 100644 index 0000000..3719e00 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/Fries.png differ diff --git a/v1.4.4/Exemplo/webapp/images/HotDog.png b/v1.4.4/Exemplo/webapp/images/HotDog.png new file mode 100644 index 0000000..5c9ed77 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/HotDog.png differ diff --git a/v1.4.4/Exemplo/webapp/images/IceCream.png b/v1.4.4/Exemplo/webapp/images/IceCream.png new file mode 100644 index 0000000..2bf5d1c Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/IceCream.png differ diff --git a/v1.4.4/Exemplo/webapp/images/Pizza.png b/v1.4.4/Exemplo/webapp/images/Pizza.png new file mode 100644 index 0000000..b1166c5 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/Pizza.png differ diff --git a/v1.4.4/Exemplo/webapp/images/PopCorn.png b/v1.4.4/Exemplo/webapp/images/PopCorn.png new file mode 100644 index 0000000..e9c0a3b Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/PopCorn.png differ diff --git a/v1.4.4/Exemplo/webapp/images/Tako.png b/v1.4.4/Exemplo/webapp/images/Tako.png new file mode 100644 index 0000000..08d5f1d Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/Tako.png differ diff --git a/v1.4.4/Exemplo/webapp/images/telegram_icon 256x256.png b/v1.4.4/Exemplo/webapp/images/telegram_icon 256x256.png new file mode 100644 index 0000000..99f7f31 Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/telegram_icon 256x256.png differ diff --git a/v1.4.4/Exemplo/webapp/images/telegram_icon 32x32.png b/v1.4.4/Exemplo/webapp/images/telegram_icon 32x32.png new file mode 100644 index 0000000..96cceaa Binary files /dev/null and b/v1.4.4/Exemplo/webapp/images/telegram_icon 32x32.png differ diff --git a/v1.4.4/Exemplo/webapp/index.css b/v1.4.4/Exemplo/webapp/index.css new file mode 100644 index 0000000..604875a --- /dev/null +++ b/v1.4.4/Exemplo/webapp/index.css @@ -0,0 +1,816 @@ +h1, .h1 +{ + font-family: "Helvetica Neue", Helvetica, Ubuntu, "Segoe UI", Verdana, sans-serif; + font-weight: bold; + font-size: 32px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0; + padding: 0; + display: inline; +} +h2, .h2 +{ + font-family: "Helvetica Neue", Helvetica, Ubuntu, "Segoe UI", Verdana, sans-serif; + font-weight: bold; + font-size: 27px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0 0 0 0; + padding: 0 0 0 0; + display: inline; +} +h3, .h3 +{ + font-family: "Helvetica Neue", Helvetica, Ubuntu, "Segoe UI", Verdana, sans-serif; + font-weight: bold; + font-size: 24px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0 0 0 0; + padding: 0 0 0 0; + display: inline; +} +h4, .h4 +{ + font-family: "Helvetica Neue", Helvetica, Ubuntu, "Segoe UI", Verdana, sans-serif; + font-weight: bold; + font-size: 21px; + font-style: italic; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0 0 0 0; + padding: 0 0 0 0; + display: inline; +} +h5, .h5 +{ + font-family: "Helvetica Neue", Helvetica, Ubuntu, "Segoe UI", Verdana, sans-serif; + font-weight: bold; + font-size: 19px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0 0 0 0; + padding: 0 0 0 0; + display: inline; +} +h6, .h6 +{ + font-family: "Helvetica Neue", Helvetica, Ubuntu, "Segoe UI", Verdana, sans-serif; + font-weight: bold; + font-size: 16px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0 0 0 0; + padding: 0 0 0 0; + display: inline; +} +.CustomStyle +{ + font-family: "Helvetica Neue", Helvetica, Ubuntu, "Segoe UI", Verdana, sans-serif; + font-weight: bold; + font-size: 16px; + text-decoration: none; + color: #2E74B5; + background-color: transparent; +} + +.bt { + position:absolute; + top:50%; + left:50%; + transform:translate(-50%,-50%); + color: #ffffff;/*var(--tg-theme-button-text-color);*/ + border: none; +} + +.bt-add +{ + background-color: #FBB727; + /*background: var(--tg-theme-button-color, #FBB727);*/ + background-clip: inherit; + border-radius: 6px; + font-weight: bold; + font-size: 13px; + text-decoration: none; + color: #FFFFFF; + cursor: pointer; +} +.bt-dec +{ + font-weight: bold; + font-size: 15px; + text-decoration: none; + color: #FFFFFF; + /*color: var(--tg-theme-button-text-color);*/ + background-color: #FF4500; + background-clip: inherit; + border-radius: 6px; + cursor: pointer; +} +.ballon +{ + font-weight: bold; + text-decoration: none; + background: #FBB727; /*var(--tg-theme-button-color, #FBB727);*/ + color: #FFFFFF; /*var(--tg-theme-button-text-color, #FFFFFF);*/ + /*color: #FFFFFF; + background-color: #FBB727;*/ + background-clip: inherit; + border: 0 none #FBB727; + border-radius: 20px; +} +.hint{ + color: var(--tg-theme-hint-color, #a8a8a8);/*var(--tg-theme-hint-color);*/ +} +.link{ + color: var(--tg-theme-link-color); +} + +.produtonome .produtopreco{ + color:#000000; + font-family:Arial; + font-size:13px; +} + +/*FIM DAS CLASSES*/ + +div#container +{ + width: 400px; + position: relative; + margin: 0 auto 0 auto; + text-align: left; +} +body +{ + /* background-color: #FFFFFF;*/ + /*color: #000000;*/ + /*color: var(--tg-theme-text-color);*/ + /*background: var(--tg-theme-bg-color);*/ + /*color-scheme: var(--tg-color-scheme);*/ + /*display: flex; + flex-direction: column; + align-items: center; + font-size: 18px;*/ + font-family: "Helvetica Neue", Helvetica, Ubuntu, "Segoe UI", Verdana, sans-serif; + font-weight: normal; + font-size: 13px; + line-height: 1.1875; + margin: 0; + text-align: center; +} +a +{ + color: var(--tg-theme-link-color, #2678b6); + text-decoration: underline; +} +a:visited +{ + color: #800080; +} +a:active +{ + color: #FF0000; +} +a:hover +{ + color: #0000FF; + text-decoration: underline; +} +input:focus, textarea:focus, select:focus +{ + outline: none; +} +#Body +{ + /* color: #000000;/*var(--tg-theme-text-color);*/ + /* background: var(--tg-theme-bg-color);*/ + background-image: none; + border-radius: 0; +} +#img1 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#img2 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#img3 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#img4 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#img5 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#img6 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#img7 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#img8 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#img9 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#img10 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#img11 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#img12 +{ + border: 0 solid #000000; + border-radius: 0; + padding: 0; + left: 0; + top: 0; + width: 100%; + height: 100%; +} +#bt-dec1 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-dec2 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-dec3 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-dec4 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-dec5 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-dec6 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-dec7 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-dec8 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-dec9 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-dec10 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-dec11 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-dec12 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-inc1 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-inc2 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-inc3 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-inc4 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-inc5 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-inc6 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-inc7 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-inc8 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-inc9 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-inc10 +{ + -webkit-appearance: none; + margin: 0; +} + +#bt-inc11 +{ + -webkit-appearance: none; + margin: 0; +} + +#bt-inc12 +{ + -webkit-appearance: none; + margin: 0; +} +#CardItens1 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#CardItens2 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#CardItens3 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#CardItens4 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card1 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card2 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card3 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card4 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card5 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card6 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card7 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card8 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card9 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card10 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card11 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#Card12 +{ + background-color: transparent; + background-image: none; + border-radius: 0; +} +#bt-add1 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-add2 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-add3 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-add4 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-add5 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-add6 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-add7 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-add8 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-add9 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-add10 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-add11 +{ + -webkit-appearance: none; + margin: 0; +} +#bt-add12 +{ + -webkit-appearance: none; + margin: 0; +} +#wb_Text1 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text1 div +{ + text-align: left; +} +#wb_Text2 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text2 div +{ + text-align: left; +} +#wb_Text3 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text3 div +{ + text-align: left; +} +#wb_Text4 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text4 div +{ + text-align: left; +} +#wb_Text5 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text5 div +{ + text-align: left; +} +#wb_Text6 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text6 div +{ + text-align: left; +} +#wb_Text7 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text7 div +{ + text-align: left; +} +#wb_Text8 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text8 div +{ + text-align: left; +} +#wb_Text9 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text9 div +{ + text-align: left; +} +#wb_Text10 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text10 div +{ + text-align: left; +} +#wb_Text11 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text11 div +{ + text-align: left; +} +#wb_Text12 +{ + background-color: transparent; + background-image: none; + border: 0 solid #000000; + border-radius: 0; + padding: 0; + margin: 0; + text-align: left; +} +#wb_Text12 div +{ + text-align: left; +} +#Label1 +{ + vertical-align: top; +} +#Label2 +{ + vertical-align: top; +} +#Label3 +{ + vertical-align: top; +} +#Label4 +{ + vertical-align: top; +} +#Label5 +{ + vertical-align: top; +} +#Label6 +{ + vertical-align: top; +} +#Label7 +{ + vertical-align: top; +} +#Label8 +{ + vertical-align: top; +} +#Label9 +{ + vertical-align: top; +} +#Label10 +{ + vertical-align: top; +} +#Label11 +{ + vertical-align: top; +} +#Label12 +{ + vertical-align: top; +} +#bt-vieworder +{ + -webkit-appearance: none; + margin: 0; +} diff --git a/v1.4.4/Exemplo/webapp/index.html b/v1.4.4/Exemplo/webapp/index.html new file mode 100644 index 0000000..375db87 --- /dev/null +++ b/v1.4.4/Exemplo/webapp/index.html @@ -0,0 +1,474 @@ + + + + + +WebApp + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+ + + +
+ Burger + R$:10,00 +
+
+ - +
+
+ + +
+
+ ADD +
+ +
+ +
+ + + +
+ Frites + R$:10,00 +
+
+ - +
+
+ + +
+
+ ADD +
+ +
+ +
+ + + +
+ Hotdog + R$:10,00 +
+
+ - +
+
+ + +
+
+ ADD +
+ +
+
+ +
+
+ + + +
+ Tako + R$:10,00 +
+
+ - +
+
+ + +
+
+ ADD +
+ +
+ +
+ + + +
+ Pizza + R$:10,00 +
+
+ - +
+
+ + +
+
+ ADD +
+ +
+ +
+ + + +
+ Donaut + R$:10,00 +
+
+ - +
+
+ + +
+
+ ADD +
+ +
+ +
+ +
+
+ + + +
+ Popcorn + R$:10,00 +
+
+ - +
+
+ + +
+
+ ADD +
+ +
+ +
+ + + +
+ Coke + R$:10,00 +
+
+ - +
+
+ + +
+
+ ADD +
+ +
+ +
+ + + +
+ Cake + R$:10,00 +
+
+ - +
+
+ + +
+
+ ADD +
+ +
+
+ +
+
+ + + +
+ Icecream + R$:10,00 +
+
+ - +
+
+ + +
+
+ ADD +
+ +
+ +
+ + + +
+ Cokie + R$:10,00 +
+
+ - +
+
+ + +
+
+ ADD +
+ +
+ +
+ + + +
+ Flan + R$:10,00 +
+ - +
+
+ + +
+
+ ADD +
+ +
+
+ +
+ + +
+ + + \ No newline at end of file diff --git a/v1.4.4/Exemplo/webapp/telegram.webapp.js b/v1.4.4/Exemplo/webapp/telegram.webapp.js new file mode 100644 index 0000000..5de9e3a --- /dev/null +++ b/v1.4.4/Exemplo/webapp/telegram.webapp.js @@ -0,0 +1,786 @@ +// WebView +(function () { + var eventHandlers = {}; + + var locationHash = ''; + try { + locationHash = location.hash.toString(); + } catch (e) {} + + var initParams = urlParseHashParams(locationHash); + + var isIframe = false, iFrameStyle; + try { + isIframe = (window.parent != null && window != window.parent); + if (isIframe) { + window.addEventListener('message', function (event) { + if (event.source !== window.parent) return; + try { + var dataParsed = JSON.parse(event.data); + } catch (e) { + return; + } + if (!dataParsed || !dataParsed.eventType) { + return; + } + if (dataParsed.eventType == 'set_custom_style') { + iFrameStyle.innerHTML = dataParsed.eventData; + } else { + receiveEvent(dataParsed.eventType, dataParsed.eventData); + } + }); + iFrameStyle = document.createElement('style'); + document.head.appendChild(iFrameStyle); + try { + window.parent.postMessage(JSON.stringify({eventType: 'iframe_ready'}), '*'); + } catch (e) {} + } + } catch (e) {} + + function urlSafeDecode(urlencoded) { + try { + urlencoded = urlencoded.replace(/\+/g, '%20'); + return decodeURIComponent(urlencoded); + } catch (e) { + return urlencoded; + } + } + + function urlParseHashParams(locationHash) { + locationHash = locationHash.replace(/^#/, ''); + var params = {}; + if (!locationHash.length) { + return params; + } + if (locationHash.indexOf('=') < 0 && locationHash.indexOf('?') < 0) { + params._path = urlSafeDecode(locationHash); + return params; + } + var qIndex = locationHash.indexOf('?'); + if (qIndex >= 0) { + var pathParam = locationHash.substr(0, qIndex); + params._path = urlSafeDecode(pathParam); + locationHash = locationHash.substr(qIndex + 1); + } + var query_params = urlParseQueryString(locationHash); + for (var k in query_params) { + params[k] = query_params[k]; + } + return params; + } + + function urlParseQueryString(queryString) { + var params = {}; + if (!queryString.length) { + return params; + } + var queryStringParams = queryString.split('&'); + var i, param, paramName, paramValue; + for (i = 0; i < queryStringParams.length; i++) { + param = queryStringParams[i].split('='); + paramName = urlSafeDecode(param[0]); + paramValue = param[1] == null ? null : urlSafeDecode(param[1]); + params[paramName] = paramValue; + } + return params; + } + + // Telegram apps will implement this logic to add service params (e.g. tgShareScoreUrl) to game URL + function urlAppendHashParams(url, addHash) { + // url looks like 'https://game.com/path?query=1#hash' + // addHash looks like 'tgShareScoreUrl=' + encodeURIComponent('tgb://share_game_score?hash=very_long_hash123') + + var ind = url.indexOf('#'); + if (ind < 0) { + // https://game.com/path -> https://game.com/path#tgShareScoreUrl=etc + return url + '#' + addHash; + } + var curHash = url.substr(ind + 1); + if (curHash.indexOf('=') >= 0 || curHash.indexOf('?') >= 0) { + // https://game.com/#hash=1 -> https://game.com/#hash=1&tgShareScoreUrl=etc + // https://game.com/#path?query -> https://game.com/#path?query&tgShareScoreUrl=etc + return url + '&' + addHash; + } + // https://game.com/#hash -> https://game.com/#hash?tgShareScoreUrl=etc + if (curHash.length > 0) { + return url + '?' + addHash; + } + // https://game.com/# -> https://game.com/#tgShareScoreUrl=etc + return url + addHash; + } + + function postEvent(eventType, callback, eventData) { + if (!callback) { + callback = function () {}; + } + if (eventData === undefined) { + eventData = ''; + } + + if (window.TelegramWebviewProxy !== undefined) { + TelegramWebviewProxy.postEvent(eventType, JSON.stringify(eventData)); + callback(); + } + else if (window.external && 'notify' in window.external) { + window.external.notify(JSON.stringify({eventType: eventType, eventData: eventData})); + callback(); + } + else if (isIframe) { + try { + var trustedTarget = 'https://web.telegram.org'; + // For now we don't restrict target, for testing purposes + trustedTarget = '*'; + window.parent.postMessage(JSON.stringify({eventType: eventType, eventData: eventData}), trustedTarget); + if (initParams.tgWebAppDebug) { + console.log('[Telegram.WebView] postEvent via postMessage', eventType, eventData); + } + callback(); + } catch (e) { + callback(e); + } + } + else { + if (initParams.tgWebAppDebug) { + console.log('[Telegram.WebView] postEvent', eventType, eventData); + } + callback({notAvailable: true}); + } + }; + + function receiveEvent(eventType, eventData) { + callEventCallbacks(eventType, function(callback) { + callback(eventType, eventData); + }); + } + + function callEventCallbacks(eventType, func) { + var curEventHandlers = eventHandlers[eventType]; + if (curEventHandlers === undefined || + !curEventHandlers.length) { + return; + } + for (var i = 0; i < curEventHandlers.length; i++) { + try { + func(curEventHandlers[i]); + } catch (e) {} + } + } + + function onEvent(eventType, callback) { + if (eventHandlers[eventType] === undefined) { + eventHandlers[eventType] = []; + } + var index = eventHandlers[eventType].indexOf(callback); + if (index === -1) { + eventHandlers[eventType].push(callback); + } + }; + + function offEvent(eventType, callback) { + if (eventHandlers[eventType] === undefined) { + return; + } + var index = eventHandlers[eventType].indexOf(callback); + if (index === -1) { + return; + } + eventHandlers[eventType].splice(index, 1); + }; + + function openProtoUrl(url) { + if (!url.match(/^(web\+)?tgb?:\/\/./)) { + return false; + } + var useIframe = navigator.userAgent.match(/iOS|iPhone OS|iPhone|iPod|iPad/i) ? true : false; + if (useIframe) { + var iframeContEl = document.getElementById('tgme_frame_cont') || document.body; + var iframeEl = document.createElement('iframe'); + iframeContEl.appendChild(iframeEl); + var pageHidden = false; + var enableHidden = function () { + pageHidden = true; + }; + window.addEventListener('pagehide', enableHidden, false); + window.addEventListener('blur', enableHidden, false); + if (iframeEl !== null) { + iframeEl.src = url; + } + setTimeout(function() { + if (!pageHidden) { + window.location = url; + } + window.removeEventListener('pagehide', enableHidden, false); + window.removeEventListener('blur', enableHidden, false); + }, 2000); + } + else { + window.location = url; + } + return true; + } + + if (!window.Telegram) { + window.Telegram = {}; + } + window.Telegram.WebView = { + initParams: initParams, + isIframe: isIframe, + onEvent: onEvent, + offEvent: offEvent, + postEvent: postEvent, + receiveEvent: receiveEvent, + callEventCallbacks: callEventCallbacks + }; + + window.Telegram.Utils = { + urlSafeDecode: urlSafeDecode, + urlParseQueryString: urlParseQueryString, + urlParseHashParams: urlParseHashParams, + urlAppendHashParams: urlAppendHashParams + }; + + // For Windows Phone app + window.TelegramGameProxy_receiveEvent = receiveEvent; + + // App backward compatibility + window.TelegramGameProxy = { + receiveEvent: receiveEvent + }; +})(); + +// WebApp +(function () { + var Utils = window.Telegram.Utils; + var WebView = window.Telegram.WebView; + var initParams = WebView.initParams; + var isIframe = WebView.isIframe; + + var WebApp = {}; + var webAppInitData = '', webAppInitDataUnsafe = {}; + var themeParams = {}, colorScheme = 'light'; + var webAppVersion = '1.0'; + + if (initParams.tgWebAppData && initParams.tgWebAppData.length) { + webAppInitData = initParams.tgWebAppData; + webAppInitDataUnsafe = Utils.urlParseQueryString(webAppInitData); + for (var key in webAppInitDataUnsafe) { + var val = webAppInitDataUnsafe[key]; + try { + if (val.substr(0, 1) == '{' && val.substr(-1) == '}' || + val.substr(0, 1) == '[' && val.substr(-1) == ']') { + webAppInitDataUnsafe[key] = JSON.parse(val); + } + } catch (e) {} + } + } + if (initParams.tgWebAppThemeParams && initParams.tgWebAppThemeParams.length) { + var themeParamsRaw = initParams.tgWebAppThemeParams; + try { + var theme_params = JSON.parse(themeParamsRaw); + setThemeParams(theme_params); + } catch (e) {} + } + if (initParams.tgWebAppVersion) { + webAppVersion = initParams.tgWebAppVersion; + } + + function onThemeChanged(eventType, eventData) { + if (eventData.theme_params) { + setThemeParams(eventData.theme_params); + window.Telegram.WebApp.MainButton.setParams({ + force_update: true + }); + receiveWebViewEvent('themeChanged'); + } + } + + var lastWindowHeight = window.innerHeight; + function onViewportChanged(eventType, eventData) { + if (eventData.height) { + window.removeEventListener('resize', onWindowResize); + setViewportHeight(eventData); + } + } + + function onWindowResize(e) { + if (lastWindowHeight != window.innerHeight) { + lastWindowHeight = window.innerHeight; + receiveWebViewEvent('viewportChanged', { + isStateStable: true + }); + } + } + + function linkHandler(e) { + if (e.metaKey || e.ctrlKey) return; + var el = e.target; + while (el.tagName != 'A' && el.parentNode) { + el = el.parentNode; + } + if (el.tagName == 'A' && + el.target != '_blank' && + (el.protocol == 'http:' || el.protocol == 'https:') && + el.hostname == 't.me') { + WebApp.openTgLink(el.href); + e.preventDefault(); + } + } + + function receiveWebViewEvent(eventType) { + var args = Array.prototype.slice.call(arguments); + eventType = args.shift(); + WebView.callEventCallbacks('webview:' + eventType, function(callback) { + callback.apply(WebApp, args); + }); + } + + function onWebViewEvent(eventType, callback) { + WebView.onEvent('webview:' + eventType, callback); + }; + + function offWebViewEvent(eventType, callback) { + WebView.offEvent('webview:' + eventType, callback); + }; + + function setCssProperty(name, value) { + var root = document.documentElement; + if (root && root.style && root.style.setProperty) { + root.style.setProperty('--tg-' + name, value); + } + } + + function setThemeParams(theme_params) { + var color; + for (var key in theme_params) { + if (color = parseColorToHex(theme_params[key])) { + themeParams[key] = color; + if (key == 'bg_color') { + colorScheme = isColorDark(color) ? 'dark' : 'light' + setCssProperty('color-scheme', colorScheme); + } + key = 'theme-' + key.split('_').join('-'); + setCssProperty(key, color); + } + } + } + + var viewportHeight = false, viewportStableHeight = false, isExpanded = true; + function setViewportHeight(data) { + if (typeof data !== 'undefined') { + isExpanded = !!data.is_expanded; + viewportHeight = data.height; + if (data.is_state_stable) { + viewportStableHeight = data.height; + } + receiveWebViewEvent('viewportChanged', { + isStateStable: !!data.is_state_stable + }); + } + var height, stable_height; + if (viewportHeight !== false) { + height = (viewportHeight - mainButtonHeight) + 'px'; + } else { + height = mainButtonHeight ? 'calc(100vh - ' + mainButtonHeight + 'px)' : '100vh'; + } + if (viewportStableHeight !== false) { + stable_height = (viewportStableHeight - mainButtonHeight) + 'px'; + } else { + stable_height = mainButtonHeight ? 'calc(100vh - ' + mainButtonHeight + 'px)' : '100vh'; + } + setCssProperty('viewport-height', height); + setCssProperty('viewport-stable-height', stable_height); + } + + + function parseColorToHex(color) { + color += ''; + var match; + if (/^#([0-9a-f]){6}$/i.test(color)) { + return color.toLowerCase(); + } + else if (match = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color)) { + return ('#' + match[1] + match[1] + match[2] + match[2] + match[3] + match[3]).toLowerCase(); + } + return false; + } + + function isColorDark(rgb) { + rgb = rgb.replace(/[\s#]/g, ''); + if (rgb.length == 3) { + rgb = rgb[0] + rgb[0] + rgb[1] + rgb[1] + rgb[2] + rgb[2]; + } + var r = parseInt(rgb.substr(0, 2), 16); + var g = parseInt(rgb.substr(2, 2), 16); + var b = parseInt(rgb.substr(4, 2), 16); + var hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b)); + return hsp < 120; + } + + function versionCompare(v1, v2) { + if (typeof v1 !== 'string') v1 = ''; + if (typeof v2 !== 'string') v2 = ''; + v1 = v1.replace(/^\s+|\s+$/g, '').split('.'); + v2 = v2.replace(/^\s+|\s+$/g, '').split('.'); + var a = Math.max(v1.length, v2.length), i, p1, p2; + for (i = 0; i < a; i++) { + p1 = parseInt(v1[i]) || 0; + p2 = parseInt(v2[i]) || 0; + if (p1 == p2) continue; + if (p1 > p2) return 1; + return -1; + } + return 0; + } + + function versionAtLeast(ver) { + return versionCompare(webAppVersion, ver) >= 0; + } + + function byteLength(str) { + if (window.Blob) { + try { return new Blob([str]).size; } catch (e) {} + } + var s = str.length; + for (var i=str.length-1; i>=0; i--) { + var code = str.charCodeAt(i); + if (code > 0x7f && code <= 0x7ff) s++; + else if (code > 0x7ff && code <= 0xffff) s+=2; + if (code >= 0xdc00 && code <= 0xdfff) i--; + } + return s; + } + + var mainButtonHeight = 0; + var MainButton = (function() { + var isVisible = false; + var isActive = true; + var isProgressVisible = false; + var buttonText = 'CONTINUE'; + var buttonColor = false; + var buttonTextColor = false; + + var mainButton = {}; + Object.defineProperty(mainButton, 'text', { + set: function(val){ mainButton.setParams({text: val}); }, + get: function(){ return buttonText; }, + enumerable: true + }); + Object.defineProperty(mainButton, 'color', { + set: function(val){ mainButton.setParams({color: val}); }, + get: function(){ return buttonColor || themeParams.button_color || '#2481cc'; }, + enumerable: true + }); + Object.defineProperty(mainButton, 'textColor', { + set: function(val){ mainButton.setParams({text_color: val}); }, + get: function(){ return buttonTextColor || themeParams.button_text_color || '#ffffff'; }, + enumerable: true + }); + Object.defineProperty(mainButton, 'isVisible', { + set: function(val){ mainButton.setParams({is_visible: val}); }, + get: function(){ return isVisible; }, + enumerable: true + }); + Object.defineProperty(mainButton, 'isProgressVisible', { + get: function(){ return isProgressVisible; }, + enumerable: true + }); + Object.defineProperty(mainButton, 'isActive', { + set: function(val){ mainButton.setParams({is_active: val}); }, + get: function(){ return isActive; }, + enumerable: true + }); + + var curButtonState = null; + + WebView.onEvent('main_button_pressed', onMainButtonPressed); + + var debugBtn = null, debugBtnStyle = {}; + if (initParams.tgWebAppDebug) { + debugBtn = document.createElement('tg-main-button'); + debugBtnStyle = { + font: '600 14px/18px sans-serif', + display: 'none', + width: '100%', + height: '48px', + borderRadius: '0', + background: 'no-repeat right center', + position: 'fixed', + left: '0', + right: '0', + bottom: '0', + margin: '0', + padding: '15px 20px', + textAlign: 'center', + boxSizing: 'border-box', + zIndex: '10000' + }; + for (var k in debugBtnStyle) { + debugBtn.style[k] = debugBtnStyle[k]; + } + document.addEventListener('DOMContentLoaded', function onDomLoaded(event) { + document.removeEventListener('DOMContentLoaded', onDomLoaded); + document.body.appendChild(debugBtn); + debugBtn.addEventListener('click', onMainButtonPressed, false); + }); + } + + function onMainButtonPressed() { + if (isActive) { + receiveWebViewEvent('mainButtonClicked'); + } + } + + function buttonParams() { + var color = mainButton.color; + var text_color = mainButton.textColor; + return isVisible ? { + is_visible: true, + is_active: isActive, + is_progress_visible: isProgressVisible, + text: buttonText, + color: color, + text_color: text_color + } : {is_visible: false}; + } + + function buttonState(btn_params) { + if (typeof btn_params === 'undefined') { + btn_params = buttonParams(); + } + return JSON.stringify(btn_params); + } + + function updateButton() { + var btn_params = buttonParams(); + var btn_state = buttonState(btn_params); + if (curButtonState === btn_state) { + return; + } + curButtonState = btn_state; + WebView.postEvent('web_app_setup_main_button', false, btn_params); + if (initParams.tgWebAppDebug) { + updateDebugButton(btn_params); + } + } + + function updateDebugButton(btn_params) { + if (btn_params.is_visible) { + debugBtn.style.display = 'block'; + mainButtonHeight = 48; + + debugBtn.style.opacity = btn_params.is_active ? '1' : '0.8'; + debugBtn.style.cursor = btn_params.is_active ? 'pointer' : 'auto'; + debugBtn.disabled = !btn_params.is_active; + debugBtn.innerText = btn_params.text; + debugBtn.style.backgroundImage = btn_params.is_progress_visible ? "url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20viewport%3D%220%200%2048%2048%22%20width%3D%2248px%22%20height%3D%2248px%22%3E%3Ccircle%20cx%3D%2250%25%22%20cy%3D%2250%25%22%20stroke%3D%22%23fff%22%20stroke-width%3D%222.25%22%20stroke-linecap%3D%22round%22%20fill%3D%22none%22%20stroke-dashoffset%3D%22106%22%20r%3D%229%22%20stroke-dasharray%3D%2256.52%22%20rotate%3D%22-90%22%3E%3Canimate%20attributeName%3D%22stroke-dashoffset%22%20attributeType%3D%22XML%22%20dur%3D%22360s%22%20from%3D%220%22%20to%3D%2212500%22%20repeatCount%3D%22indefinite%22%3E%3C%2Fanimate%3E%3CanimateTransform%20attributeName%3D%22transform%22%20attributeType%3D%22XML%22%20type%3D%22rotate%22%20dur%3D%221s%22%20from%3D%22-90%2024%2024%22%20to%3D%22630%2024%2024%22%20repeatCount%3D%22indefinite%22%3E%3C%2FanimateTransform%3E%3C%2Fcircle%3E%3C%2Fsvg%3E')" : 'none'; + debugBtn.style.backgroundColor = btn_params.color; + debugBtn.style.color = btn_params.text_color; + } else { + debugBtn.style.display = 'none'; + mainButtonHeight = 0; + } + if (document.documentElement) { + document.documentElement.style.boxSizing = 'border-box'; + document.documentElement.style.paddingBottom = mainButtonHeight + 'px'; + } + setViewportHeight(); + } + + function setParams(params) { + if (typeof params.text !== 'undefined') { + var text = params.text.toString().replace(/^\s+|\s+$/g, ''); + if (!text.length) { + console.error('[Telegram.WebApp] Main button text is required', params.text); + throw Error('WebAppMainButtonParamInvalid'); + } + if (text.length > 64) { + console.error('[Telegram.WebApp] Main button text is too long', text); + throw Error('WebAppMainButtonParamInvalid'); + } + buttonText = text; + } + if (typeof params.color !== 'undefined') { + if (params.color === false || + params.color === null) { + buttonColor = false; + } else { + var color = parseColorToHex(params.color); + if (!color) { + console.error('[Telegram.WebApp] Main button color format is invalid', color); + throw Error('WebAppMainButtonParamInvalid'); + } + buttonColor = color; + } + } + if (typeof params.text_color !== 'undefined') { + if (params.text_color === false || + params.text_color === null) { + buttonTextColor = false; + } else { + var text_color = parseColorToHex(params.text_color); + if (!text_color) { + console.error('[Telegram.WebApp] Main button text color format is invalid', text_color); + throw Error('WebAppMainButtonParamInvalid'); + } + buttonTextColor = text_color; + } + } + if (typeof params.is_visible !== 'undefined') { + if (params.is_visible && + !mainButton.text.length) { + console.error('[Telegram.WebApp] Main button text is required'); + throw Error('WebAppMainButtonParamInvalid'); + } + isVisible = !!params.is_visible; + } + if (typeof params.is_active !== 'undefined') { + isActive = !!params.is_active; + } + updateButton(); + return mainButton; + } + + mainButton.setText = function(text) { + return mainButton.setParams({text: text}); + }; + mainButton.onClick = function(callback) { + onWebViewEvent('mainButtonClicked', callback); + return mainButton; + }; + mainButton.offClick = function(callback) { + offWebViewEvent('mainButtonClicked', callback); + return mainButton; + }; + mainButton.show = function() { + return mainButton.setParams({is_visible: true}); + }; + mainButton.hide = function() { + return mainButton.setParams({is_visible: false}); + }; + mainButton.enable = function() { + return mainButton.setParams({is_active: true}); + }; + mainButton.disable = function() { + return mainButton.setParams({is_active: false}); + }; + mainButton.showProgress = function(leaveActive) { + isActive = !!leaveActive; + isProgressVisible = true; + updateButton(); + return mainButton; + }; + mainButton.hideProgress = function() { + if (!mainButton.isActive) { + isActive = true; + } + isProgressVisible = false; + updateButton(); + return mainButton; + } + mainButton.setParams = setParams; + return mainButton; + })(); + + if (!window.Telegram) { + window.Telegram = {}; + } + + Object.defineProperty(WebApp, 'initData', { + get: function(){ return webAppInitData; }, + enumerable: true + }); + Object.defineProperty(WebApp, 'initDataUnsafe', { + get: function(){ return webAppInitDataUnsafe; }, + enumerable: true + }); + Object.defineProperty(WebApp, 'version', { + get: function(){ return webAppVersion; }, + enumerable: true + }); + Object.defineProperty(WebApp, 'colorScheme', { + get: function(){ return colorScheme; }, + enumerable: true + }); + Object.defineProperty(WebApp, 'themeParams', { + get: function(){ return themeParams; }, + enumerable: true + }); + Object.defineProperty(WebApp, 'isExpanded', { + get: function(){ return isExpanded; }, + enumerable: true + }); + Object.defineProperty(WebApp, 'viewportHeight', { + get: function(){ return (viewportHeight === false ? window.innerHeight : viewportHeight) - mainButtonHeight; }, + enumerable: true + }); + Object.defineProperty(WebApp, 'viewportStableHeight', { + get: function(){ return (viewportStableHeight === false ? window.innerHeight : viewportStableHeight) - mainButtonHeight; }, + enumerable: true + }); + Object.defineProperty(WebApp, 'MainButton', { + value: MainButton, + enumerable: true + }); + WebApp.isVersionAtLeast = function(ver) { + return versionAtLeast(ver); + }; + WebApp.onEvent = function(eventType, callback) { + onWebViewEvent(eventType, callback); + }; + WebApp.offEvent = function(eventType, callback) {offWebViewEvent(eventType, callback); + }; + WebApp.sendData = function (data) { + if (!data || !data.length) { + console.error('[Telegram.WebApp] Data is required', data); + throw Error('WebAppDataInvalid'); + } + if (byteLength(data) > 4096) { + console.error('[Telegram.WebApp] Data is too long', data); + throw Error('WebAppDataInvalid'); + } + WebView.postEvent('web_app_data_send', false, {data: data}); + }; + WebApp.openTgLink = function (url) { + var a = document.createElement('A'); + a.href = url; + if (a.protocol != 'http:' && + a.protocol != 'https:') { + console.error('[Telegram.WebApp] Url protocol is not supported', url); + throw Error('WebAppTgUrlInvalid'); + } + if (a.hostname != 't.me') { + console.error('[Telegram.WebApp] Url host is not supported', url); + throw Error('WebAppTgUrlInvalid'); + } + var path_full = a.pathname + a.search; + if (isIframe || versionAtLeast('1.1')) { + WebView.postEvent('web_app_open_tg_link', false, {path_full: path_full}); + } else { + location.href = 'https://t.me' + path_full; + } + }; + WebApp.ready = function () { + WebView.postEvent('web_app_ready'); + }; + WebApp.expand = function () { + WebView.postEvent('web_app_expand'); + }; + WebApp.close = function () { + WebView.postEvent('web_app_close'); + }; + + window.Telegram.WebApp = WebApp; + + setViewportHeight(); + + window.addEventListener('resize', onWindowResize); + if (isIframe) { + document.addEventListener('click', linkHandler); + } + + WebView.onEvent('theme_changed', onThemeChanged); + WebView.onEvent('viewport_changed', onViewportChanged); + WebView.postEvent('web_app_request_theme'); + WebView.postEvent('web_app_request_viewport'); + +})(); \ No newline at end of file diff --git a/v1.4.4/Exemplo/webapp/webapp.css b/v1.4.4/Exemplo/webapp/webapp.css new file mode 100644 index 0000000..b88941b --- /dev/null +++ b/v1.4.4/Exemplo/webapp/webapp.css @@ -0,0 +1,121 @@ +h1, .h1 +{ + font-family: Arial; + font-weight: bold; + font-size: 32px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +h2, .h2 +{ + font-family: Arial; + font-weight: bold; + font-size: 27px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +h3, .h3 +{ + font-family: Arial; + font-weight: bold; + font-size: 24px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +h4, .h4 +{ + font-family: Arial; + font-weight: bold; + font-size: 21px; + font-style: italic; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +h5, .h5 +{ + font-family: Arial; + font-weight: bold; + font-size: 19px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +h6, .h6 +{ + font-family: Arial; + font-weight: bold; + font-size: 16px; + text-decoration: none; + color: #000000; + background-color: transparent; + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + display: inline; +} +.CustomStyle +{ + font-family: "Courier New"; + font-weight: bold; + font-size: 16px; + text-decoration: none; + color: #2E74B5; + background-color: transparent; +} +.bt-add +{ + font-weight: bold; + font-size: 13px; + text-decoration: none; + color: #FFFFFF; + background-color: #FBB727; + background-clip: text; + border-radius: 6px; +} +.bt-dec +{ + font-weight: bold; + font-size: 15px; + text-decoration: none; + color: #FFFFFF; + background-color: #FF4500; + background-clip: text; + border-radius: 6px; +} +.bt-ViewOrder +{ + font-weight: bold; + text-align: center; + text-decoration: none; + color: #FFFFFF; + background-color: #32CD32; + border-radius: 6px; +} +.ballon +{ + font-weight: bold; + text-decoration: none; + color: #FFFFFF; + background-color: #FBB727; + background-clip: text; + border: 0px none #FBB727; + border-radius: 20px; +} diff --git a/v1.4.4/TInjectTelegram/Imagens/images.jfif b/v1.4.4/TInjectTelegram/Imagens/images.jfif new file mode 100644 index 0000000..79adf4d Binary files /dev/null and b/v1.4.4/TInjectTelegram/Imagens/images.jfif differ diff --git a/v1.4.4/TInjectTelegram/Imagens/images.jpeg b/v1.4.4/TInjectTelegram/Imagens/images.jpeg new file mode 100644 index 0000000..79adf4d Binary files /dev/null and b/v1.4.4/TInjectTelegram/Imagens/images.jpeg differ diff --git a/v1.4.4/TInjectTelegram/Imagens/img_TInjectTelegram.jpg b/v1.4.4/TInjectTelegram/Imagens/img_TInjectTelegram.jpg new file mode 100644 index 0000000..aceb7e7 Binary files /dev/null and b/v1.4.4/TInjectTelegram/Imagens/img_TInjectTelegram.jpg differ diff --git a/v1.4.4/TInjectTelegram/Imagens/img_TInjectTelegram.png b/v1.4.4/TInjectTelegram/Imagens/img_TInjectTelegram.png new file mode 100644 index 0000000..7961533 Binary files /dev/null and b/v1.4.4/TInjectTelegram/Imagens/img_TInjectTelegram.png differ diff --git a/v1.4.4/TInjectTelegram/Imagens/telegram.ico b/v1.4.4/TInjectTelegram/Imagens/telegram.ico new file mode 100644 index 0000000..f26cf5c Binary files /dev/null and b/v1.4.4/TInjectTelegram/Imagens/telegram.ico differ diff --git a/v1.4.4/TInjectTelegram/Packages/Botmanager.png b/v1.4.4/TInjectTelegram/Packages/Botmanager.png new file mode 100644 index 0000000..ba67cc0 Binary files /dev/null and b/v1.4.4/TInjectTelegram/Packages/Botmanager.png differ diff --git a/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.dcr b/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.dcr new file mode 100644 index 0000000..8fa4a90 Binary files /dev/null and b/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.dcr differ diff --git a/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.dpk b/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.dpk new file mode 100644 index 0000000..101652b --- /dev/null +++ b/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.dpk @@ -0,0 +1,72 @@ +package TInjectTelegramBotAPI; +{$R *.res} +{$R *.dcr} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$ENDIF IMPLICITBUILDING} +{$IMPLICITBUILD ON} + +requires + rtl, + RESTComponents, + vcl, + IndySystem, + IndyProtocols, + IndyCore, + FireDAC, + FireDACCommonDriver, + FireDACCommon, + CrossUrl; + +contains + TinjectTelegram.Core in '..\Source\TinjectTelegram.Core.pas', + TInjectTelegram.Base in '..\Source\TInjectTelegram.Base.pas', + TinjectTelegram.Ext.Sessions in '..\Source\TinjectTelegram.Ext.Sessions.pas', + TinjectTelegram.Helpers in '..\Source\TinjectTelegram.Helpers.pas', + TinjectTelegram.Logger.Old in '..\Source\TinjectTelegram.Logger.Old.pas', + TinjectTelegram.Logger in '..\Source\TinjectTelegram.Logger.pas', + TinjectTelegram.Receiver.Base in '..\Source\TinjectTelegram.Receiver.Base.pas', + TinjectTelegram.Receiver.Console in '..\Source\TinjectTelegram.Receiver.Console.pas', + TinjectTelegram.Receiver.Service in '..\Source\TinjectTelegram.Receiver.Service.pas', + TinjectTelegram.Receiver.UI in '..\Source\TinjectTelegram.Receiver.UI.pas', + TinjectTelegram.Types.Enums in '..\Source\TinjectTelegram.Types.Enums.pas', + TinjectTelegram.Types.Impl in '..\Source\TinjectTelegram.Types.Impl.pas', + TinjectTelegram.Types.InlineQueryResults in '..\Source\TinjectTelegram.Types.InlineQueryResults.pas', + TinjectTelegram.Types.InputMessageContents in '..\Source\TinjectTelegram.Types.InputMessageContents.pas', + TinjectTelegram.Types in '..\Source\TinjectTelegram.Types.pas', + TinjectTelegram.Types.Passport in '..\Source\TinjectTelegram.Types.Passport.pas', + TinjectTelegram.Types.ReplyMarkups in '..\Source\TinjectTelegram.Types.ReplyMarkups.pas', + TinjectTelegram.UpdateParser in '..\Source\TinjectTelegram.UpdateParser.pas', + TinjectTelegram.Utils.JSON in '..\Source\TinjectTelegram.Utils.JSON.pas', + TinjectTelegram.Ph in '..\Source\TinjectTelegram.Ph.pas', + TinjectTelegram.Ph.Types in '..\Source\TinjectTelegram.Ph.Types.pas', + TinjectTelegram.RegisterIDE in '..\Source\TinjectTelegram.RegisterIDE.pas', + TinjectTelegram.Emoji in '..\Source\TinjectTelegram.Emoji.pas', + TinjectTelegram.Bot.Impl in '..\Source\TinjectTelegram.Bot.Impl.pas', + TinjectTelegram.Bot in '..\Source\TinjectTelegram.Bot.pas', + TInjectTelegram.Bot.Chat in '..\Source\TInjectTelegram.Bot.Chat.pas', + TInjectTelegram.Bot.Manager in '..\Source\TInjectTelegram.Bot.Manager.pas', + TinjectTelegram.Receiver.Manager.Base in '..\Source\TinjectTelegram.Receiver.Manager.Base.pas'; + +end. diff --git a/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.dproj b/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.dproj new file mode 100644 index 0000000..2d9a745 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.dproj @@ -0,0 +1,999 @@ + + + {6E6E0078-F47D-4207-A288-76213B406395} + TInjectTelegramBotAPI.dpk + 19.4 + VCL + True + Debug + Win32 + 3 + Package + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + true + true + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + All + TInjectTelegramBotAPI + true + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + rtl;CrossUrl;RESTComponents;vcl;IndySystem;IndyProtocols;IndyCore;FireDAC;FireDACCommonDriver;FireDACCommon;$(DCC_UsePackage) + + + rtl;RESTComponents;vcl;IndySystem;IndyProtocols;IndyCore;FireDAC;FireDACCommonDriver;FireDACCommon;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + Package + + + + TInjectTelegramBotAPI.dpk + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + TInjectTelegramBotAPI.bpl + true + + + + + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + classes + 1 + + + classes + 1 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + + 1 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + + True + True + + + 12 + + + + + diff --git a/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.res b/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.res new file mode 100644 index 0000000..2debc5e Binary files /dev/null and b/v1.4.4/TInjectTelegram/Packages/TInjectTelegramBotAPI.res differ diff --git a/v1.4.4/TInjectTelegram/Source/TInjectTelegram.Base.pas b/v1.4.4/TInjectTelegram/Source/TInjectTelegram.Base.pas new file mode 100644 index 0000000..804d7fa --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TInjectTelegram.Base.pas @@ -0,0 +1,41 @@ +unit TInjectTelegram.Base; +{$I ..\Source\config.inc} +interface +uses + System.Classes; +type + TInjectTelegramAbstractComponent = class(TComponent) + private + FAPIVersion: string; + FComponentVersion: string; + FAutor: string; + FDeveloper: string; + FDateVersionAPI: string; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + published + property Author: string read FAutor; + property Developer: string read FDeveloper; + property APIVersion: string read FAPIVersion; + property DateVersionAPI: string read FDateVersionAPI; + property ComponentVersion: string read FComponentVersion; + end; +implementation +{ TInjectTelegramAbstractComponent } +constructor TInjectTelegramAbstractComponent.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FAutor := 'Maxin Sysoev - TelegApi'; + FDeveloper := 'Ruan Diego Lacerda Menezes'; + FComponentVersion := '1.4.4'; + FAPIVersion := '6.7'; + FDateVersionAPI := '21 de Abril de 2023'; +end; +destructor TInjectTelegramAbstractComponent.Destroy; +begin + // + inherited; +end; + +end. diff --git a/v1.4.4/TInjectTelegram/Source/TInjectTelegram.Bot.Chat.pas b/v1.4.4/TInjectTelegram/Source/TInjectTelegram.Bot.Chat.pas new file mode 100644 index 0000000..135e806 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TInjectTelegram.Bot.Chat.pas @@ -0,0 +1,375 @@ +unit TInjectTelegram.Bot.Chat; +{$I config.inc} +interface +uses + REST.Json, + REST.Types, + REST.Client, + System.Json, + System.SysUtils, + System.Generics.Collections, + System.NetEncoding, + System.TypInfo, + System.AnsiStrings, + System.Classes, + Vcl.ExtCtrls, + FireDAC.Comp.Client, + Dialogs, + TInjectTelegram.Bot, + TInjectTelegram.Bot.Impl, + TInjectTelegram.Logger, + TInjectTelegram.Logger.Old, + TInjectTelegram.Types, + TInjectTelegram.Types.Impl, + TInjectTelegram.Types.Enums, + TInjectTelegram.Types.ReplyMarkups, + TInjectTelegram.Types.InlineQueryResults, + TInjectTelegram.Types.InputMessageContents, + TInjectTelegram.Ph, + TInjectTelegram.UpdateParser, + TInjectTelegram.Receiver.Base, + TInjectTelegram.Receiver.Console, + TInjectTelegram.Receiver.Service, + TInjectTelegram.Receiver.UI; +type + TInjectTelegramChat = class; + TNotifyTelegramBotConversa = procedure(Conversa: TInjectTelegramChat; AMessage: ItdMessage) of object; + TNotifyOnMessage = procedure(AMessage: ItdMessage) of object; + TNotifyOnInlineQuery = procedure (AInlineQuery: ItdInlineQuery) of object; + TNotifyOnChosenInlineResult = procedure (AChosenInlineResult: ItdChosenInlineResult) of object; + TNotifyOnCallBackQuery = procedure (ACallback: ItdCallbackQuery) of object; + TNotifyOnStop = procedure of object; + TNotifyOnStart = procedure of object; + TNotifyOnLog = procedure (level: TLogLevel; msg: string; e: Exception) of object; + TInjectTelegramChatBot = TInjectTelegramChat deprecated 'Use TInjectTelegramChat instead'; + + PSuccessfulPayment = ^TSuccessfulPayment; + + TSuccessfulPayment = class + private + FTelegramPaymentChargeId: string; + FShippingOptionId: string; + FInvoicePayload: string; + FProviderPaymentChargeId: string; + FTotalAmount: string; + FCurrency: string; + public + property Currency : string read FCurrency write FCurrency; + property TotalAmount : string read FTotalAmount write FTotalAmount; + property InvoicePayload : string read FInvoicePayload write FInvoicePayload; + property ShippingOptionId: string read FShippingOptionId write FShippingOptionId; + property TelegramPaymentChargeId: string read FTelegramPaymentChargeId write FTelegramPaymentChargeId; + property ProviderPaymentChargeId: string read FProviderPaymentChargeId write FProviderPaymentChargeId; + end; + + //TAlvez TInjectTelegramChatBotControl??? + TInjectTelegramChat = class(TComponent) + private + //Enumerado + FEtapaAtendimento: TtdEtapasAtendimento; + FSituacao: TtdSituacaoAtendimento; + FTipoUsuario: TtdTipoUsuario; + //Propriedades Telegram + FEnderecoEntrega: String; + FLatitude: Single; + FLongetude: Single; + FTextoMSG: String; + FTempoInatividade: Integer; + FDescricao: String; + FMaiorValor: Currency; + FItemsPedido: TStringList; + FID: String; + FIdChat: Int64; + FIdPedido: Integer; + FIdCliente: Int64; + FFormaPGT: String; + FEtapa: Integer; + FPontoReferencia: String; + FNome: String; + FIDInc: integer; + FTipo: string; + FTotalPedido: Real; + FIdIdiomaStr: String; + FOnTimer: TNotifyEvent; + FUltimaIteracao: TTime; + FDistanciaKM: String; + FDuracaoMIN: String; + FTaxaEntrega: Real; + FCep: String; + FNumero: String; + FLogradouro: String; + FBairro: String; + FUF: String; + FLocalidade: String; + FArquivoRecebido: String; + //Notifys Eventos + FOnSituacaoAlterada: TNotifyTelegramBotConversa; + FOnMessage: TtdOnMessage; + FNomeArquivoRecebido: String; + FOnConversationReceived: TNotifyTelegramBotConversa; + FSuccessfulPayment: TSuccessfulPayment; + FInatividadeNotificada: Boolean; + FIdConversa: Int64; + public + FMessage : ItdMessage; + procedure SetSituacao(const Value: TtdSituacaoAtendimento); + procedure SetTempoInatividade(const Value: Integer); + //Construtores e destruidores + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure Clear; + procedure RestartTimer; + + property SuccessfulPayment : TSuccessfulPayment read FSuccessfulPayment write FSuccessfulPayment; + published + function LoadButtons(AQuery: TFDQuery; AFieldName: String; + AInitZero: Boolean = True) : IReplyMarkup; + function LoadButtonsStr(AStrArrayBtName: TArray>; + AInlineMode: Boolean = false) : IReplyMarkup; + //Proprieades + [Default(0)] + property UserType : TtdTipoUsuario read FTipoUsuario write FTipoUsuario {default tpCliente}; + [Default(0)] + property ServiceSituation : TtdSituacaoAtendimento read FSituacao write SetSituacao {default saIndefinido}; + [Default(0)] + property ServiceStage : TtdEtapasAtendimento read FEtapaAtendimento write FEtapaAtendimento {default pvListarMenu}; + [Default(0)] + property Stage : Integer read FEtapa write FEtapa {default 0}; + property ConversationID : Int64 read FIdConversa write FIdConversa; + property Tipo : string read FTipo write FTipo; + property ID : String read FID write FID; + property IdIdiomaStr : String read FIdIdiomaStr write FIdIdiomaStr; + property OrderID : Integer read FIdPedido write FIdPedido; + property ClientID : Int64 read FIdCliente write FIdCliente; + property ChatID : Int64 read FIdChat write FIdChat; + property IDInc : Integer read FIDInc write FIDInc; + property MSGText : String read FTextoMSG write FTextoMSG; + property Name : String read FNome write FNome; + property OrderItems : TStringList read FItemsPedido write FItemsPedido; + property HighestValue : Currency read FMaiorValor write FMaiorValor; + property DeliveryAddress : String read FEnderecoEntrega write FEnderecoEntrega; + property NumberAdress : String read FNumero write FNumero; + property PostalCodeAdress : String read FCep write FCep; + property PublicPlace : String read FLogradouro write FLogradouro; + property Neighborhood : String read FBairro write FBairro; + property Location : String read FLocalidade write FLocalidade; + property UF : String read FUF write FUF; + property ReferencePoint : String read FPontoReferencia write FPontoReferencia; + property DistanceKM : String read FDistanciaKM write FDistanciaKM; + property DurationMIN : String read FDuracaoMIN write FDuracaoMIN; + property DeliveryFee : Real read FTaxaEntrega write FTaxaEntrega; + property Latitude : Single read FLatitude write FLatitude; + property Longitude : Single read FLongetude write FLongetude; + property PaymentOrigin : String read FFormaPGT write FFormaPGT; + property TotalOrder : Real read FTotalPedido write FTotalPedido; + property Description : String read FDescricao write FDescricao; + + [Default('')] + property ReceivedFile : String read FArquivoRecebido write FArquivoRecebido; + property LastIteration : TTime read FUltimaIteracao write FUltimaIteracao; + property NotifiedInactivity : Boolean read FInatividadeNotificada write FInatividadeNotificada; + property InactivityTime : Integer read FTempoInatividade write SetTempoInatividade; + property Message_ : ItdMessage read FMessage; + //Eventos + property OnChangedSituation: TNotifyTelegramBotConversa read FOnSituacaoAlterada write FOnSituacaoAlterada; + property OnConversationReceived: TNotifyTelegramBotConversa read FOnConversationReceived write FOnConversationReceived; + end; +implementation +{ TInjectTelegramChatBot } +procedure TInjectTelegramChat.Clear; +begin + // Situacao := saIndefinido; + FLatitude := 0.0; + FLongetude := 0.0; + FMaiorValor := 0; + if Assigned(FItemsPedido) then + FItemsPedido.Clear; + // FIdPedido := 0; //No posso zerar essa propriedade + FFormaPGT := ''; + //FIdCliente := 0; //No posso zerar essa propriedade + FPontoReferencia := ''; + FEnderecoEntrega := ''; + FCep := ''; + FNumero := ''; + FLogradouro := ''; + FBairro := ''; + FUF := ''; + FLocalidade := ''; + FDescricao := ''; + //FTempoInatividade := 0; //No posso zerar essa propriedade + FNome := ''; + FIDInc := 0; + FID := ''; //ID da Mensagem + FTipo := ''; + FEtapa := 0; + FTipoUsuario := TtdTipoUsuario.tpCliente; + FEtapaAtendimento := TtdEtapasAtendimento.pvListarMenu; +end; +function TInjectTelegramChat.LoadButtonsStr(AStrArrayBtName: TArray>;AInlineMode: Boolean = false) : IReplyMarkup; +var + {$REGION 'VARIAVEIS'} + I, O: Integer; + str: String; + //InLine Mode + LButtonIL: TArray; + DButtonIL: TArray; + RButtonIL: TArray>; + //Reply Mode + LButton : TArray; + DButton : TArray; + RButton : TArray>; + {$ENDREGION 'VARIAVEIS'} +Begin + {$REGION 'CARREGARBTStr'} +{ +Exemplo de uso +Assim ela criara os botoes de acordo com a quantidade de itens do array bidimencional + CarregarBTStr([['REMOVER','FINALIZAR'],['INICIO','SAIR']]); +} + SetLength(AStrArrayBtName, Length(AStrArrayBtName[0]) + Length(AStrArrayBtName[1])); + + if Not AInlineMode then //Reply Mode + Begin + SetLength(LButton, Length(AStrArrayBtName[0])); + SetLength(DButton, Length(AStrArrayBtName[1])); + SetLength(RButton, Length(LButton) + Length(DButton)); + for I := 0 to Length(AStrArrayBtName[0]) - 1 do + LButton[I] := TtdKeyboardButton.Create(String(AStrArrayBtName[0,I])); + if Length(AStrArrayBtName[1]) > 0 then + Begin + for O := 0 to Length(AStrArrayBtName[1]) - 1 do + DButton[O] := TtdKeyboardButton.Create(String(AStrArrayBtName[1,O])); + RButton[LOW(RButton)] := LButton; + RButton[HIGH(RButton)] := DButton; + Result := TtdReplyKeyboardMarkup.Create(RButton,TRUE); + End Else + Result := TtdReplyKeyboardMarkup.Create([LButton],TRUE); + End + Else //Inline Mode + Begin + SetLength(LButtonIL, Length(AStrArrayBtName[0])); + SetLength(DButtonIL, Length(AStrArrayBtName[1])); + SetLength(RButtonIL, Length(LButton) + Length(DButton)); + for I := 0 to Length(AStrArrayBtName[0]) - 1 do + LButtonIL[I] := TtdInlineKeyboardButton.Create(String(AStrArrayBtName[0,I]),String(AStrArrayBtName[0,I])); + if Length(AStrArrayBtName[1]) > 0 then + Begin + for O := 0 to Length(AStrArrayBtName[1]) - 1 do + DButtonIL[O] := TtdInlineKeyboardButton.Create(String(AStrArrayBtName[1,O])); + RButtonIL[LOW(RButtonIL)] := LButtonIL; + RButtonIL[HIGH(RButtonIL)] := DButtonIL; + Result := TtdInlineKeyboardMarkup.Create(RButtonIL); + End + Else + Result := TtdInlineKeyboardMarkup.Create([LButtonIL]); + End; + {$ENDREGION 'CARREGARBTStr'} +End; +function TInjectTelegramChat.LoadButtons(AQuery: TFDQuery; AFieldName: String; AInitZero: Boolean = True) : IReplyMarkup; +var + {$REGION 'VARIAVEIS'} + I: Integer; + strTexto : String; + INLButton: TArray; //Botoes Inline na mensagem + LButton : TArray; + RButton : TArray>; + {$ENDREGION 'VARIAVEIS'} +Begin + {$REGION 'CARREGARBOTOES'} + if Assigned(AQuery) then + Begin + if AFieldName <> '' then + Begin + try + try + if AInitZero = True then + Begin + SetLength(LButton, AQuery.RecordCount + 1); + SetLength(RButton, Length(LButton) + 1); + // SetLength(INLbutton, AQuery.RecordCount + 1); + AQuery.First; + for I := 0 to AQuery.RecordCount do + Begin + strTexto := AQuery.FieldByName(AFieldName).AsString; + if I = 0 then + Begin + LButton[I] := TtdKeyboardButton.Create('0'); + LButton[I+1] := TtdKeyboardButton.Create(strTexto); + // INLbutton[I] := TtdInlineKeyboardButton.Create('0', '0'); + // INLbutton[I+1] := TtdInlineKeyboardButton.Create(strTexto, strTexto); + End + else + Begin + LButton[I+1] := TtdKeyboardButton.Create(strTexto); + // INLbutton[I+1] := TtdInlineKeyboardButton.Create(strTexto, strTexto); + End; + AQuery.Next; + End; + End + Else + Begin + SetLength(LButton, AQuery.RecordCount); + SetLength(RButton, Length(LButton) + 1); + // SetLength(INLbutton, AQuery.RecordCount); + AQuery.First; + for I := 0 to AQuery.RecordCount - 1 do + Begin + strTexto := AQuery.FieldByName(AFieldName).AsString; + LButton[I] := TtdKeyboardButton.Create(strTexto); + //INLbutton[I] := TtdInlineKeyboardButton.Create(strTexto, strTexto); + AQuery.Next; + End; + End; + except on E: Exception do + E.Message := 'Erro ao Ler a tabela'+ E.Message; + end; + finally + RButton[LOW(RButton)] := LButton; + RButton[HIGH(RButton)] := [TtdKeyboardButton.Create('Inicio')]; + Result := TtdReplyKeyboardMarkup.Create(RButton, TRUE); + end; + End; + End; + {$ENDREGION 'CARREGARBOTOES'} +End; +constructor TInjectTelegramChat.Create(AOwner: TComponent); +begin + FIdIdiomaStr := 'pt-br'; + NotifiedInactivity := False; + FSuccessfulPayment := TSuccessfulPayment.Create; + inherited Create(AOwner); +end; +destructor TInjectTelegramChat.Destroy; +begin + FSuccessfulPayment.Free; + inherited Destroy; +end; +procedure TInjectTelegramChat.RestartTimer; +begin + //Se estiver em atendimento reinicia o timer de inatividade + if FSituacao in [TtdSituacaoAtendimento.saEmAtendimento, TtdSituacaoAtendimento.saNova, TtdSituacaoAtendimento.saAguardandoEntrega] then + begin + FUltimaIteracao := StrToTime(FormatDateTime('hh:mm:ss',Now)); + end; +end; +procedure TInjectTelegramChat.SetSituacao(const Value: TtdSituacaoAtendimento); +begin + //DoChange + if FSituacao <> Value then + begin +// if FSituacao <> TtdSituacaoAtendimento.saAguardandoEntrega then +// FSituacao := Value; +// if Value <> TtdSituacaoAtendimento.saInativa then + + if FSituacao <> Value then + FSituacao := Value; + if Assigned( OnChangedSituation ) then + OnChangedSituation(Self, FMessage); + end; +end; +procedure TInjectTelegramChat.SetTempoInatividade(const Value: Integer); +begin + FTempoInatividade := Value{*60000}; //60000 +end; + +end. diff --git a/v1.4.4/TInjectTelegram/Source/TInjectTelegram.Bot.Manager.pas b/v1.4.4/TInjectTelegram/Source/TInjectTelegram.Bot.Manager.pas new file mode 100644 index 0000000..1efdf6e --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TInjectTelegram.Bot.Manager.pas @@ -0,0 +1,959 @@ +unit TInjectTelegram.Bot.Manager; +{$I config.inc} +interface +uses + REST.Json, + REST.Types, + REST.Client, + System.Json, + System.SysUtils, + System.Generics.Collections, + System.NetEncoding, + System.TypInfo, + System.AnsiStrings, + System.Classes, + Vcl.ExtCtrls, + Vcl.Dialogs, + System.DateUtils, + TInjectTelegram.Bot, + TInjectTelegram.Bot.Impl, + TInjectTelegram.Logger, + TInjectTelegram.Logger.Old, + TInjectTelegram.Types, + TInjectTelegram.Types.Impl, + TInjectTelegram.Types.Enums, + TInjectTelegram.Types.ReplyMarkups, + TInjectTelegram.Types.InlineQueryResults, + TInjectTelegram.Types.InputMessageContents, + TInjectTelegram.Ph, + TInjectTelegram.UpdateParser, + TInjectTelegram.Receiver.Base, + TInjectTelegram.Receiver.Console, + TInjectTelegram.Receiver.Service, + TInjectTelegram.Receiver.UI, + TInjectTelegram.Bot.Chat, + WinApi.Windows, + Vcl.Forms; +const + URL_File_Download : String = 'https://api.telegram.org/file/bot'; +type + TtdOnUpdate = procedure(ASender: TObject; AUpdate: ItdUpdate) of object; + TtdOnUpdates = procedure(ASender: TObject; AUpdates: TArray) of object; + TtdOnMessage = procedure(ASender: TObject; AMessage: ItdMessage) of object; + TtdOnInlineQuery = procedure(ASender: TObject; AInlineQuery: ItdInlineQuery) of object; + TtdOnInlineResultChosen = procedure(ASender: TObject; AChosenInlineResult: ItdChosenInlineResult) of object; + TtdOnCallbackQuery = procedure(ASender: TObject; ACallbackQuery: ItdCallbackQuery) of object; + TtdOnChannelPost = procedure(ASender: TObject; AChanelPost: ItdMessage) of object; + TtdOnShippingQuery = procedure(ASender: TObject; AShippingQuery: ItdShippingQuery) of object; + TtdOnPreCheckoutQuery = procedure(ASender: TObject; APreCheckoutQuery: ItdPreCheckoutQuery) of object; + TtdOnPollStatus = procedure(ASender: TObject; APoll: ItdPoll) of object; + TtdOnPollAnswer = procedure(ASender: TObject; APollAnswer: ItdPollAnswer) of object; + TtdOnSuccessfulPayment = procedure(ASender: TObject; ASuccessfulPayment: ItdSuccessfulPayment) of object; + + TtdOnForumTopicCreated = procedure(ASender: TObject; AForumTopicCreated: ItdForumTopicCreated) of object; + TtdOnForumTopicClosed = procedure(ASender: TObject; AForumTopicClosed: ItdForumTopicClosed) of object; + TtdOnForumTopicEdited = procedure(ASender: TObject; AForumTopicEdited: ItdForumTopicEdited) of object; + TtdOnForumTopicReopened = procedure(ASender: TObject; AForumTopicReopened: ItdForumTopicReopened) of object; + TtdOnGeneralForumTopicHidden = procedure(ASender: TObject; AGeneralForumTopicHidden: ItdGeneralForumTopicHidden) of object; + TtdOnGeneralForumTopicUnhidden = procedure(ASender: TObject; AGeneralForumTopicUnhidden: ItdGeneralForumTopicUnhidden) of object; + + TtdOnMyChatMember = procedure(ASender: TObject; AMyChatMember: ItdChatMemberUpdated) of object; + TtdOnChatMember = procedure(ASender: TObject; AChatMember: ItdChatMemberUpdated) of object; + + TtdOnMessageEntityReceiver = procedure(ASender: TObject; AMessageEntityType: TtdMessageEntityType) of object; + + TtdOnWebAppData = procedure(ASender: TObject; AWebAppData: ItdWebAppData) of object; + + TtdChatList = TObjectList; + + TInjectTelegramBotManager = class(TInjectTelegramBotReceiverBase) + private + FOnUpdate: TtdOnUpdate; + FOnMessage: TtdOnMessage; + FOnUpdates: TtdOnUpdates; + FOnStop: TNotifyEvent; + FOnStart: TNotifyEvent; + FOnEditedMessage: TtdOnMessage; + FOnChannelPost: TtdOnMessage; + FOnPreCheckoutQuery: TtdOnPreCheckoutQuery; + FOnInlineQuery: TtdOnInlineQuery; + FOnShippingQuery: TtdOnShippingQuery; + FOnChosenInlineResult: TtdOnInlineResultChosen; + FOnEditedChannelPost: TtdOnMessage; + FOnCallbackQuery: TtdOnCallbackQuery; + FOnPollStatus: TtdOnPollStatus; + FOnPollAnswer: TtdOnPollAnswer; + FSenhaADM: String; + FSimultaneos: Integer; + FInactivityTimeMinute: Integer; + FConversas: TtdChatList; + FConversa: TInjectTelegramChat; + LParseMode: TtdParseMode; + FOnTimer: TNotifyEvent; + FTimeNow, FLimit: TTime; + FOnMyChatMember: TtdOnMyChatMember; + FOnChatMember: TtdOnChatMember; + FOnChatJoinRequest: TtdOnChatJoinRequest; + FOnSuccessfulPayment: TtdOnSuccessfulPayment; + FMessage: ItdMessage; + FOnForumTopicCreated: TtdOnForumTopicCreated; + FOnForumTopicReopened: TtdOnForumTopicReopened; + FOnForumTopicEdited: TtdOnForumTopicEdited; + FOnForumTopicClosed: TtdOnForumTopicClosed; + FOnGeneralForumTopicHidden: TtdOnGeneralForumTopicHidden; + FOnGeneralForumTopicUnhidden: TtdOnGeneralForumTopicUnhidden; + FTotaldeConversas: Integer; + FConversasEmEspera: Integer; + FTimeOutMessage: String; + FTimeOutAutoIncSeconds: int64; + FOnMessageEntityReceiver: TtdOnMessageEntityReceiver; + FAvisoInatividade: Boolean; + FOnWebAppData: TtdOnWebAppData; + procedure SetMessage(const Value: ItdMessage); + protected + procedure DoOnStart; override; + procedure DoOnStop; override; + procedure DoOnUpdates(AUpdates: TArray); override; + procedure DoOnUpdate(AUpdate: ItdUpdate); override; + procedure DoOnMessage(AMessage: ItdMessage); override; + procedure DoOnInlineQuery(AInlineQuery: ItdInlineQuery); override; + procedure DoOnChosenInlineResult(AChosenInlineResult: ItdChosenInlineResult); override; + procedure DoOnEditedMessage(AEditedMessage: ItdMessage); override; + procedure DoOnChannelPost(AChannelPost: ItdMessage); override; + procedure DoOnEditedChannelPost(AEditedChannelPost: ItdMessage); override; + procedure DoOnShippingQuery(AShippingQuery: ItdShippingQuery); override; + procedure DoOnPreCheckoutQuery(APreCheckoutQuery: ItdPreCheckoutQuery); override; + procedure DoOnCallbackQuery(ACallbackQuery: ItdCallbackQuery); override; + procedure DoOnPollStatus(APoll: ItdPoll); override; + procedure DoOnPollAnswer(APollAnswer: ItdPollAnswer); override; + procedure DoOnChatJoinRequest(AChatJoinRequest: ItdChatJoinRequest); override; + procedure DoOnMyChatMember(AMyChatMember: ItdChatMemberUpdated); override; + procedure DoOnChatMember(AChatMember: ItdChatMemberUpdated); override; + procedure DoOnSuccessfulPayment(ASuccessfulPayment: ItdSuccessfulPayment); override; + procedure DoOnForumTopicCreated(AForumTopicCreated: ItdForumTopicCreated); override; + procedure DoOnForumTopicReopened(AForumTopicReopened: ItdForumTopicReopened); override; + procedure DoOnForumTopicEdited(AForumTopicEdited: ItdForumTopicEdited); override; + procedure DoOnForumTopicClosed(AForumTopicClosed: ItdForumTopicClosed); override; + procedure DoOnGeneralForumTopicHidden(AGeneralForumTopicHidden: ItdGeneralForumTopicHidden); override; + procedure DoOnGeneralForumTopicUnhidden(AGeneralForumTopicUnhidden: ItdGeneralForumTopicUnhidden); override; + procedure DoOnMessageEntityReceiver(AMessageEntityReceiver: TtdMessageEntityType); override; + procedure DoOnWebAppData(AWebAppData: ItdWebAppData); override; + procedure Init; + procedure ParseMessageObject(AMessage : ItdMessage); + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure TypeParser(AMessage : ItdMessage); + procedure ProcessarResposta(AMessage : ItdMessage); overload; + procedure ProcessarResposta(APreCheckoutQuery: ItdPreCheckoutQuery); overload; + procedure ConversaSituacaoAlterada(AConversa: TInjectTelegramChat; AMessage : ItdMessage); + + function BuscarConversa(AID: String): TInjectTelegramChat; + function NovaConversa(AMessage : ItdMessage): TInjectTelegramChat; + function BuscarConversaEmEspera: TInjectTelegramChat; + function AtenderProximoEmEspera: TInjectTelegramChat; + + procedure ReadChats(ABotManager: TInjectTelegramBotManager); + + + property TotaldeConversas: Integer read FTotaldeConversas; + property TotalConversasEmEspera: Integer read FConversasEmEspera; + + property Message : ItdMessage read FMessage write SetMessage; + property Conversas: TtdChatList read FConversas; + property Conversa: TInjectTelegramChat read FConversa write FConversa; + function GetUserName(AMessage: ItdMessage): string; overload; + function GetUserName(APreCheckoutQuery: ItdPreCheckoutQuery): string; overload; + + function CreateSubDir(const NomeSubDir: string; var OutDir: string): boolean; + function DownloadFile(const Origem, Destino: String): Boolean; + function ExtractFileNameFromURL(AURLFile: string): string; + published + property TimeOutMessage: String read FTimeOutMessage write FTimeOutMessage; + /// This property is used to define the time to cancel a conversation, after the timeout warning. + /// + /// Time in Seconds + /// + /// + /// If no value is defined, the time of 30 seconds will be assigned automatically. + /// + /// + property TimeOutAutoIncSeconds: int64 read FTimeOutAutoIncSeconds write FTimeOutAutoIncSeconds; + {Propriedades} + property AdminPassword: String read FSenhaADM write FSenhaADM; + [Default(1)] + property Simultaneous: Integer read FSimultaneos write FSimultaneos; + [Default(1)] + property InactivityTimeMinute: Integer read FInactivityTimeMinute write FInactivityTimeMinute; + property InactivityNotice : Boolean read FAvisoInatividade write FAvisoInatividade; + {Eventos} + property OnStart: TNotifyEvent read FOnStart write FOnStart; + property OnStop: TNotifyEvent read FOnStop write FOnStop; + property OnUpdates: TtdOnUpdates read FOnUpdates write FOnUpdates; + property OnUpdate: TtdOnUpdate read FOnUpdate write FOnUpdate; + property OnMessage: TtdOnMessage read FOnMessage write FOnMessage; + property OnInlineQuery: TtdOnInlineQuery read FOnInlineQuery write FOnInlineQuery; + property OnChosenInlineResult: TtdOnInlineResultChosen read FOnChosenInlineResult write FOnChosenInlineResult; + property OnEditedMessage: TtdOnMessage read FOnEditedMessage write FOnEditedMessage; + property OnChannelPost: TtdOnMessage read FOnChannelPost write FOnChannelPost; + property OnEditedChannelPost: TtdOnMessage read FOnEditedChannelPost write FOnEditedChannelPost; + property OnShippingQuery: TtdOnShippingQuery read FOnShippingQuery write FOnShippingQuery; + property OnPreCheckoutQuery: TtdOnPreCheckoutQuery read FOnPreCheckoutQuery write FOnPreCheckoutQuery; + property OnCallbackQuery: TtdOnCallbackQuery read FOnCallbackQuery write FOnCallbackQuery; + property OnSuccessfulPayment: TtdOnSuccessfulPayment read FOnSuccessfulPayment write FOnSuccessfulPayment; + property OnPollStatus: TtdOnPollStatus read FOnPollStatus write FOnPollStatus; + property OnPollAnswer: TtdOnPollAnswer read FOnPollAnswer write FOnPollAnswer; + property OnChatJoinRequest: TtdOnChatJoinRequest read FOnChatJoinRequest write FOnChatJoinRequest; + property OnMyChatMember: TtdOnMyChatMember read FOnMyChatMember write FOnMyChatMember; + property OnChatMember: TtdOnChatMember read FOnChatMember write FOnChatMember; + property OnForumTopicCreated: TtdOnForumTopicCreated read FOnForumTopicCreated write FOnForumTopicCreated; + property OnForumTopicClosed: TtdOnForumTopicClosed read FOnForumTopicClosed write FOnForumTopicClosed; + property OnForumTopicEdited: TtdOnForumTopicEdited read FOnForumTopicEdited write FOnForumTopicEdited; + property OnForumTopicReopened: TtdOnForumTopicReopened read FOnForumTopicReopened write FOnForumTopicReopened; + property OnGeneralForumTopicHidden: TtdOnGeneralForumTopicHidden read FOnGeneralForumTopicHidden write FOnGeneralForumTopicHidden; + property OnGeneralForumTopicUnhidden: TtdOnGeneralForumTopicUnhidden read FOnGeneralForumTopicUnhidden write FOnGeneralForumTopicUnhidden; + property OnMessageEntityReceiver : TtdOnMessageEntityReceiver read FOnMessageEntityReceiver write FOnMessageEntityReceiver; + property OnWebAppData: TtdOnWebAppData read FOnWebAppData write FOnWebAppData; + end; +implementation +uses + System.StrUtils, WinInet; +{ TInjectTelegramBotManager } + +function TInjectTelegramBotManager.ExtractFileNameFromURL(AURLFile: string): string; +var + AStrOut :String; + I: Integer; +begin + AStrOut := ExtractFileName(AURLFile); + + I := AStrOut.LastDelimiter('/'); + if I >= 0 then + Result := Copy(AStrOut, I + 2) + else + Result := AStrOut; +end; + +function TInjectTelegramBotManager.GetUserName( + APreCheckoutQuery: ItdPreCheckoutQuery): string; +begin + Result := IfThen( + (APreCheckoutQuery.From.FirstName <> EmptyStr) and + (APreCheckoutQuery.From.FirstName.Length > 1) + ,APreCheckoutQuery.From.FirstName+' '+APreCheckoutQuery.From.LastName + ,ifThen( + (APreCheckoutQuery.From.Username <> EmptyStr) and + (APreCheckoutQuery.From.Username.Length > 1) + ,APreCheckoutQuery.From.Username + ,'User '+APreCheckoutQuery.From.ID.ToString + ) + ); +end; + +function TInjectTelegramBotManager.DownloadFile(const Origem, Destino: String): Boolean; +const //1x 2x 3x 4x 8x + BufferSize = 1024; //1024 //2048 //3060 //4056 //8112 // +var + hSession, + hURL: HInternet; + Buffer: array[1..(BufferSize)] of Byte; + BufferLen: DWORD; + f: File; + sAppName: string; + StrFileName: String; +begin + StrFileName := ExtractFileNameFromURL(Origem); + Result := False; + sAppName := ExtractFileName(Application.ExeName); + hSession := InternetOpen(PChar(sAppName),INTERNET_OPEN_TYPE_PRECONFIG,nil, nil, 0); + + try + hURL := InternetOpenURL(hSession,PChar(Origem),nil,0,0,0); + try + AssignFile(f, Destino+'\'+StrFileName); + Rewrite(f,1); + + repeat + InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen); + BlockWrite(f, Buffer, BufferLen); + until BufferLen = 0; + + CloseFile(f); + Result := True; + finally + InternetCloseHandle(hURL); + end; + finally + InternetCloseHandle(hSession); + end; +end; + +function TInjectTelegramBotManager.CreateSubDir(const NomeSubDir: string; Var OutDir: string): boolean; +var + CaminhoSub, CaminhoDir : string; +begin + Result := False; + CaminhoDir := ExtractFilePath(Application.ExeName)+'Chats'; + if Not DirectoryExists(CaminhoDir) then + CreateDir(CaminhoDir) + else + Begin + CaminhoSub := CaminhoDir +'\'+ NomeSubDir; + if DirectoryExists(CaminhoSub) then + Result := True + else + Result := CreateDir(CaminhoSub); + End; + + if Result then + OutDir := CaminhoSub; +end; + +procedure TInjectTelegramBotManager.ReadChats(ABotManager: TInjectTelegramBotManager); +var + mt: TThread; +begin + + if Self.InactivityTimeMinute <> 0 then + Begin + + mt := TThread.CreateAnonymousThread( + procedure + var + AConversa: TInjectTelegramChat; + FTimeNow, FLimit: TTime; + ADisponivel: Boolean; + begin + + while Self.IsActive do + Begin + for AConversa in ABotManager.Conversas do + Begin + FTimeNow := StrToTime(FormatDateTime('hh:mm:ss',Now)); + FLimit := IncMinute(AConversa.LastIteration, ABotManager.InactivityTimeMinute); + + if (DateTimeToUnix(FTimeNow) > DateTimeToUnix(FLimit)) then + Begin + if (Self.InactivityNotice = True) and (AConversa.NotifiedInactivity = False) then + Begin + Self.Bot.SendMessage(AConversa.ClientID, FTimeOutMessage); + + AConversa.LastIteration := IncSecond(FTimeNow, FTimeOutAutoIncSeconds); + AConversa.NotifiedInactivity := True; + Continue; + End + Else + Begin + AConversa.ServiceSituation := TtdSituacaoAtendimento.saInativa; + + FConversas.Remove( AConversa ); //Deleta a Conversa + FConversa := AtenderProximoEmEspera; //Atende o Prximo Cliente da fila + End; + End Else + Continue; + + if AConversa.ServiceSituation = TtdSituacaoAtendimento.saFinalizada then + Begin + FConversas.Remove( AConversa ); //Deleta a Conversa + FConversa := AtenderProximoEmEspera; //Atende o Prximo Cliente da fila + End; + + if ABotManager.IsActive = False then + Break; + End; + + if ABotManager.IsActive = False then + Break; + + Sleep(ABotManager.PollingInterval); + End; + end); + mt.FreeOnTerminate := True; + mt.Start; + End; + +end; + +procedure TInjectTelegramBotManager.SetMessage(const Value: ItdMessage); +begin + FMessage := Value; +end; + +function TInjectTelegramBotManager.BuscarConversa(AID: String): TInjectTelegramChat; +var + AConversa: TInjectTelegramChat; +begin + Result := Nil; + for AConversa in FConversas do + begin + if (AConversa.ClientID.ToString = AID) or + (AConversa.ChatID.ToString = AID) then + begin + Result := AConversa; + Break; + end else + continue; + end; +end; + +function TInjectTelegramBotManager.AtenderProximoEmEspera: TInjectTelegramChat; +begin + Result := BuscarConversaEmEspera; + if Assigned( Result ) then + begin + Result.ServiceSituation := TtdSituacaoAtendimento.saEmFila; + if FConversasEmEspera > 0 then + FConversasEmEspera := FConversasEmEspera - 1; + Result.RestartTimer; + end; +end; + +function TInjectTelegramBotManager.BuscarConversaEmEspera: TInjectTelegramChat; +var + AConversa: TInjectTelegramChat; +begin + Result := nil; + if FConversas.Count > 0 then + for AConversa in FConversas do + begin + if AConversa.ServiceSituation = TtdSituacaoAtendimento.saEmEspera then + begin + Result := AConversa; + Break; + end; + end; +end; + +procedure TInjectTelegramBotManager.ConversaSituacaoAlterada( + AConversa: TInjectTelegramChat; AMessage : ItdMessage); +begin + //Se ficar Inativo ou Finalizar o Pedido + if ((AConversa.ServiceSituation = TtdSituacaoAtendimento.saInativa) or + (AConversa.ServiceSituation = TtdSituacaoAtendimento.saFinalizada)) then + begin + DoOnMessage(AMessage); //Encaminha a Mensagem + FConversas.Remove( AConversa ); //Deleta a Conversa + if FTotaldeConversas > 0 then + FTotaldeConversas := FTotaldeConversas - 1; + FConversa := AtenderProximoEmEspera; //Atende o Prximo Cliente da fila + end; + + //Quano o Pedido estava Em Espera ele ao ser selecionado, passa a ter o status de em Fila + if AConversa.ServiceSituation = TtdSituacaoAtendimento.saEmFila then + Begin + AConversa.ServiceSituation := TtdSituacaoAtendimento.saNova; //Atribui o Novo Status + DoOnMessage(AMessage); //Encaminha a Mensagem + End; + +end; +constructor TInjectTelegramBotManager.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FAvisoInatividade := False; + FTimeOutAutoIncSeconds := 30; + FInactivityTimeMinute := 0; + FTimeOutMessage := 'Hello, I noticed that our conversation has reached the inactivity timeout, if you do not communicate with me anymore, our conversation will automatically end!'; + Init; +end; +destructor TInjectTelegramBotManager.Destroy; +begin + if Assigned(FConversas) then + FreeAndNil(FConversas); + inherited Destroy; +end; +function TInjectTelegramBotManager.NovaConversa(AMessage: ItdMessage): TInjectTelegramChat; +var + ADisponivel: Boolean; +begin + ADisponivel := FConversas.Count < FSimultaneos; + Result := TInjectTelegramChat.Create(Self); + + with Result do + begin + if AdminPassword <> '' then + case TtdMessage(AMessage).Text = AdminPassword of + True : UserType := TtdTipoUsuario.tpAdm; + False : UserType := TtdTipoUsuario.tpCliente; + end; + ConversationID := Conversas.Count + 1; + FTotaldeConversas := ConversationID; + ID := AMessage.MessageId.ToString; + ChatID := AMessage.Chat.ID; + ClientID := AMessage.From.ID; + MSGText := AMessage.Text; + FMessage := AMessage; + Name := GetUserName(AMessage); + + LastIteration := StrToTime(FormatDateTime('hh:mm:ss',Now)); + + SetTempoInatividade(FInactivityTimeMinute); + + OnChangedSituation := ConversaSituacaoAlterada; + end; + + if ((ADisponivel = True) or (Result.UserType = TtdTipoUsuario.tpAdm)) then + Result.ServiceSituation := TtdSituacaoAtendimento.saNova + else begin + Result.ServiceSituation := TtdSituacaoAtendimento.saEmEspera; + FConversasEmEspera := FConversasEmEspera + 1; + end; + + FConversas.Add( Result ); +end; + +function TInjectTelegramBotManager.GetUserName(AMessage : ItdMessage): string; +Begin + Result := IfThen( + (AMessage.From.FirstName <> EmptyStr) and + (AMessage.From.FirstName.Length > 1) + ,AMessage.From.FirstName+' '+AMessage.From.LastName + ,ifThen( + (AMessage.From.Username <> EmptyStr) and + (AMessage.From.Username.Length > 1) + ,AMessage.From.Username + ,'User '+AMessage.From.ID.ToString + ) + ); +End; + +procedure TInjectTelegramBotManager.ProcessarResposta(AMessage : ItdMessage); +var + AConversa: TInjectTelegramChat; + AID: String; +begin + Self.Message := AMessage; + + if (AMessage.From.ID.ToString <> AMessage.Chat.ID.ToString) and (AMessage.Chat.ID.ToString <> '') then + AID := AMessage.Chat.ID.ToString //Para uso de Grupos + else + AID := AMessage.From.ID.ToString; //Para uso de Chat Privado + + AConversa := BuscarConversa( AID ); + + if AConversa <> Nil then + begin + AConversa.ID := AMessage.MessageId.ToString; + AConversa.ChatID := AMessage.Chat.ID; + AConversa.ClientID := AMessage.From.ID; + AConversa.MSGText := AMessage.Text; + AConversa.IdIdiomaStr := AMessage.From.LanguageCode; + AConversa.FMessage := AMessage; + AConversa.Name := GetUserName(AMessage); + AConversa.ReceivedFile := ''; + + AConversa.LastIteration := StrToTime(FormatDateTime('hh:mm:ss',Now)); + + if AMessage.SuccessfulPayment <> NIl then + Begin + + AConversa.SuccessfulPayment.TotalAmount := AMessage.SuccessfulPayment.TotalAmount.ToString; + AConversa.SuccessfulPayment.Currency := AMessage.SuccessfulPayment.Currency; + AConversa.SuccessfulPayment.InvoicePayload := AMessage.SuccessfulPayment.InvoicePayload; + AConversa.SuccessfulPayment.ShippingOptionId := AMessage.SuccessfulPayment.ShippingOptionId; + AConversa.SuccessfulPayment.TelegramPaymentChargeId := AMessage.SuccessfulPayment.TelegramPaymentChargeId; + AConversa.SuccessfulPayment.ProviderPaymentChargeId := AMessage.SuccessfulPayment.ProviderPaymentChargeId; + + End; + + if Self.InactivityTimeMinute <> 0 then + Begin + FTimeNow := AConversa.LastIteration; + FLimit := IncMinute(AConversa.LastIteration, Self.InactivityTimeMinute); + + if (DateTimeToUnix(FTimeNow) < DateTimeToUnix(FLimit)) then + AConversa.RestartTimer; + End; + + End Else + AConversa := NovaConversa( AMessage ); + + TypeParser(AMessage); + + FConversa := AConversa; +end; + +procedure TInjectTelegramBotManager.TypeParser(AMessage : ItdMessage); +var + FilePath, FileName : String; + I: Integer; + MyPhoto: ItdPhotoSize; + MyFile : ItdFile; + MyEntities: ItdMessageEntity; +Begin + //Tratando Entidades + if AMessage.&Type = TtdMessageType.TextMessage then + for MyEntities in AMessage.Entities do + Begin + if Assigned(OnMessageEntityReceiver) then + OnMessageEntityReceiver(Self, MyEntities.TypeMessage); + End; + //Tratando a situacao em que vem a localizacao. + if AMessage.&Type = TtdMessageType.LocationMessage then + if (AMessage.Location.Latitude <> 0) and (AMessage.Location.Longitude <> 0) then + begin + FConversa.Latitude := AMessage.Location.Latitude; + FConversa.Longitude := AMessage.Location.Longitude; + end; + //Tratamento para receber Fotos ou Imagens + if AMessage.&Type = TtdMessageType.PhotoMessage then + Begin + for I := 0 to Length(AMessage.Photo) -1 do + Begin + if I = 0 then + FileName := 'Thumbs'; + if I = 1 then + FileName := 'Photo_Low'; + if I = 2 then + FileName := 'Photo_Mid'; + if I = 3 then + FileName := 'Photo_High'; + if I = 4 then + FileName := 'Photo_Full_High'; + MyFile := Bot.GetFile(AMessage.Photo[I].FileId); + FilePath := MyFile.FilePath; + + if Assigned(FConversa) then + FConversa.ReceivedFile := URL_File_Download+Bot.Token+'/'+FilePath; + End; + End; + //Tratamento para receber Documentos + if AMessage.&Type = TtdMessageType.DocumentMessage then + Begin + MyFile := Bot.GetFile(AMessage.Document.FileId); + FilePath := MyFile.FilePath; + + FConversa.ReceivedFile := URL_File_Download+Bot.Token+'/'+FilePath; + End; + if AMessage.&Type = TtdMessageType.VideoMessage then + Begin + MyFile := Bot.GetFile(AMessage.Video.FileId); + FilePath := MyFile.FilePath; + + FConversa.ReceivedFile := URL_File_Download+Bot.Token+'/'+FilePath; + End; + if AMessage.&Type = TtdMessageType.AudioMessage then + Begin + MyFile := Bot.GetFile(AMessage.Audio.FileId); + FilePath := MyFile.FilePath; + + FConversa.ReceivedFile := URL_File_Download+Bot.Token+'/'+FilePath; + End; + if AMessage.&Type = TtdMessageType.VideoNoteMessage then + Begin + MyFile := Bot.GetFile(AMessage.VideoNote.FileId); + FilePath := MyFile.FilePath; + + FConversa.ReceivedFile := URL_File_Download+Bot.Token+'/'+FilePath; + End; + if AMessage.&Type = TtdMessageType.StickerMessage then + Begin + MyFile := Bot.GetFile(AMessage.Sticker.FileId); + FilePath := MyFile.FilePath; + + FConversa.ReceivedFile := URL_File_Download+Bot.Token+'/'+FilePath; + End; + if AMessage.&Type = TtdMessageType.AnimatoinMessage then + Begin + MyFile := Bot.GetFile(AMessage.Animation.FileId); + FilePath := MyFile.FilePath; + + FConversa.ReceivedFile := URL_File_Download+Bot.Token+'/'+FilePath; + End; + +End; + +procedure TInjectTelegramBotManager.ParseMessageObject(AMessage: ItdMessage); +begin + if AMessage.SuccessfulPayment <> Nil then + if Assigned(OnSuccessfulPayment) then + OnSuccessfulPayment(Self,AMessage.SuccessfulPayment); + + if AMessage.ForumTopicCreated <> Nil then + if Assigned(OnForumTopicCreated) then + OnForumTopicCreated(Self, AMessage.ForumTopicCreated); + + if AMessage.ForumTopicClosed <> Nil then + if Assigned(OnForumTopicClosed) then + OnForumTopicClosed(Self, AMessage.ForumTopicClosed); + + if AMessage.ForumTopicEdited <> Nil then + if Assigned(OnForumTopicEdited) then + OnForumTopicEdited(Self, AMessage.ForumTopicEdited); + + if AMessage.ForumTopicReopened <> Nil then + if Assigned(OnForumTopicReopened) then + OnForumTopicReopened(Self, AMessage.ForumTopicReopened); + + if AMessage.GeneralForumTopicHidden <> Nil then + if Assigned(OnGeneralForumTopicHidden) then + OnGeneralForumTopicHidden(Self, AMessage.GeneralForumTopicHidden); + + if AMessage.GeneralForumTopicUnhidden <> Nil then + if Assigned(OnGeneralForumTopicUnhidden) then + OnGeneralForumTopicUnhidden(Self, AMessage.GeneralForumTopicUnhidden); + + if AMessage.WebAppData <> Nil then + if Assigned(OnWebAppData) then + OnWebAppData(Self, AMessage.WebAppData); +end; + +procedure TInjectTelegramBotManager.ProcessarResposta(APreCheckoutQuery: ItdPreCheckoutQuery); +var + AConversa: TInjectTelegramChat; + AID: String; +begin + + AID := APreCheckoutQuery.From.ID.ToString; //Para uso de Chat Privado + + AConversa := BuscarConversa( AID ); + + if AConversa <> Nil then + begin + AConversa.ID := APreCheckoutQuery.ID; + AConversa.ChatID := APreCheckoutQuery.From.ID; + AConversa.ClientID := APreCheckoutQuery.From.ID; + AConversa.MSGText := APreCheckoutQuery.TotalAmount.ToString; + AConversa.IdIdiomaStr := APreCheckoutQuery.From.LanguageCode; + //AConversa.FMessage := AMessage; + AConversa.Name := GetUserName(APreCheckoutQuery); + AConversa.ReceivedFile := ''; + + if Self.InactivityTimeMinute <> 0 then + Begin + FTimeNow := StrToTime(FormatDateTime('hh:mm:ss',Now)); + FLimit := IncMinute(AConversa.LastIteration, Self.InactivityTimeMinute); + + if (DateTimeToUnix(FTimeNow) < DateTimeToUnix(FLimit)) then + AConversa.RestartTimer; + + AConversa.LastIteration := StrToTime(FormatDateTime('hh:mm:ss',Now)); + End; + + + End; + +// if AConversa = Nil then +// AConversa := NovaConversa( AMessage ); +// +// TypeParser(AMessage); +// + FConversa := AConversa; +end; + +procedure TInjectTelegramBotManager.DoOnCallbackQuery(ACallbackQuery: ItdCallbackQuery); +begin + inherited; + //Teste + if Assigned(OnCallbackQuery) then + Begin + // ProcessarResposta(ACallbackQuery.message); + OnCallbackQuery(Self, ACallbackQuery); + End; +end; +procedure TInjectTelegramBotManager.DoOnChannelPost(AChannelPost: ItdMessage); +begin + inherited; + if Assigned(OnChannelPost) then + OnChannelPost(Self, AChannelPost); +end; +procedure TInjectTelegramBotManager.DoOnChatJoinRequest( + AChatJoinRequest: ItdChatJoinRequest); +begin + inherited; + if Assigned(OnChatJoinRequest) then + OnChatJoinRequest(Self, AChatJoinRequest); +end; +procedure TInjectTelegramBotManager.DoOnChatMember( + AChatMember: ItdChatMemberUpdated); +begin + inherited; + if Assigned(OnChatMember) then + OnChatMember(Self, AChatMember); +end; +procedure TInjectTelegramBotManager.DoOnChosenInlineResult(AChosenInlineResult: ItdChosenInlineResult); +begin + inherited; + if Assigned(OnChosenInlineResult) then + OnChosenInlineResult(Self, AChosenInlineResult); +end; +procedure TInjectTelegramBotManager.DoOnEditedChannelPost(AEditedChannelPost: ItdMessage); +begin + inherited; + if Assigned(OnEditedChannelPost) then + OnEditedChannelPost(Self, AEditedChannelPost); +end; +procedure TInjectTelegramBotManager.DoOnEditedMessage(AEditedMessage: ItdMessage); +begin + inherited; + if Assigned(OnEditedMessage) then + OnEditedMessage(Self, AEditedMessage); +end; +procedure TInjectTelegramBotManager.DoOnForumTopicClosed( + AForumTopicClosed: ItdForumTopicClosed); +begin + inherited; + if Assigned(OnForumTopicClosed) then + OnForumTopicClosed(Self, AForumTopicClosed); +end; + +procedure TInjectTelegramBotManager.DoOnForumTopicCreated( + AForumTopicCreated: ItdForumTopicCreated); +begin + inherited; + if Assigned(OnForumTopicCreated) then + OnForumTopicCreated(Self, AForumTopicCreated); +end; + +procedure TInjectTelegramBotManager.DoOnForumTopicEdited( + AForumTopicEdited: ItdForumTopicEdited); +begin + inherited; + if Assigned(OnForumTopicEdited) then + OnForumTopicEdited(Self, AForumTopicEdited); +end; + +procedure TInjectTelegramBotManager.DoOnForumTopicReopened( + AForumTopicReopened: ItdForumTopicReopened); +begin + inherited; + if Assigned(OnForumTopicReopened) then + OnForumTopicReopened(Self, AForumTopicReopened); +end; + +procedure TInjectTelegramBotManager.DoOnGeneralForumTopicHidden( + AGeneralForumTopicHidden: ItdGeneralForumTopicHidden); +begin + inherited; + if Assigned(OnGeneralForumTopicHidden) then + OnGeneralForumTopicHidden(Self, AGeneralForumTopicHidden); +end; + +procedure TInjectTelegramBotManager.DoOnGeneralForumTopicUnhidden( + AGeneralForumTopicUnhidden: ItdGeneralForumTopicUnhidden); +begin + inherited; + if Assigned(OnGeneralForumTopicUnhidden) then + OnGeneralForumTopicUnhidden(Self, AGeneralForumTopicUnhidden); +end; + +procedure TInjectTelegramBotManager.DoOnInlineQuery(AInlineQuery: ItdInlineQuery); +begin + inherited; + if Assigned(OnInlineQuery) then + OnInlineQuery(Self, AInlineQuery); +end; +procedure TInjectTelegramBotManager.DoOnMessage(AMessage: ItdMessage); +begin + inherited; + if Assigned(OnMessage) then + Begin + ProcessarResposta(AMessage); + + OnMessage(Self, AMessage); + + ParseMessageObject(AMessage); + + End; +end; +procedure TInjectTelegramBotManager.DoOnMessageEntityReceiver( + AMessageEntityReceiver: TtdMessageEntityType); +begin + inherited; + if Assigned(OnMessageEntityReceiver) then + OnMessageEntityReceiver(Self, AMessageEntityReceiver); +end; + +procedure TInjectTelegramBotManager.DoOnMyChatMember( + AMyChatMember: ItdChatMemberUpdated); +begin + inherited; + if Assigned(OnMyChatMember) then + OnMyChatMember(Self, AMyChatMember); +end; +procedure TInjectTelegramBotManager.DoOnPollAnswer(APollAnswer: ItdPollAnswer); +begin + inherited; + if Assigned(OnPollAnswer) then + OnPollAnswer(Self, APollAnswer); +end; +procedure TInjectTelegramBotManager.DoOnPollStatus(APoll: ItdPoll); +begin + inherited; + if Assigned(OnPollStatus) then + OnPollStatus(Self, APoll); +end; +procedure TInjectTelegramBotManager.DoOnPreCheckoutQuery(APreCheckoutQuery: ItdPreCheckoutQuery); +begin + inherited; + if Assigned(OnPreCheckoutQuery) then + Begin +// ProcessarResposta(APreCheckoutQuery); + + OnPreCheckoutQuery(Self, APreCheckoutQuery); + End; +end; + +procedure TInjectTelegramBotManager.DoOnShippingQuery(AShippingQuery: ItdShippingQuery); +begin + inherited; + if Assigned(OnShippingQuery) then + OnShippingQuery(Self, AShippingQuery); +end; +procedure TInjectTelegramBotManager.DoOnStart; +begin + inherited; + Init; + if Assigned(OnStart) then + OnStart(Self); + + ReadChats(Self); +end; +procedure TInjectTelegramBotManager.DoOnStop; +begin + ReadChats(Self); + + inherited; + + if Assigned(OnStop) then + OnStop(Self); + + if Assigned(FConversas) then + FreeAndNil(FConversas); +end; +procedure TInjectTelegramBotManager.DoOnSuccessfulPayment( + ASuccessfulPayment: ItdSuccessfulPayment); +begin + inherited; + if Assigned(OnSuccessfulPayment) then + OnSuccessfulPayment(Self, ASuccessfulPayment); +end; + +procedure TInjectTelegramBotManager.DoOnUpdate(AUpdate: ItdUpdate); +begin + inherited; + if Assigned(OnUpdate) then + Begin + ProcessarResposta(AUpdate.&message); + OnUpdate(Self, AUpdate); + End; +end; +procedure TInjectTelegramBotManager.DoOnUpdates(AUpdates: TArray); +begin + inherited; + if Assigned(OnUpdates) then + OnUpdates(Self, AUpdates); +end; +procedure TInjectTelegramBotManager.DoOnWebAppData(AWebAppData: ItdWebAppData); +begin + inherited; + if Assigned(OnWebAppData) then + OnWebAppData(Self, AWebAppData); +end; + +procedure TInjectTelegramBotManager.Init; +begin + LParseMode := TtdParseMode.Markdown; + if Not Assigned(FConversas) then + FConversas := TObjectList.Create; +end; +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Bot.Impl.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Bot.Impl.pas new file mode 100644 index 0000000..912bcc5 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Bot.Impl.pas @@ -0,0 +1,5255 @@ +unit TInjectTelegram.Bot.Impl; +{$I ..\Source\config.inc} +interface +uses + Vcl.Dialogs, + System.Classes, + System.TypInfo, + System.SysUtils, + System.JSON, + System.Generics.Collections, + TinjectTelegram.Core, + TinjectTelegram.Base, + TinjectTelegram.Bot, + TinjectTelegram.Types, + TinjectTelegram.Types.Impl, + TinjectTelegram.Types.Enums, + TinjectTelegram.Types.ReplyMarkups, + TinjectTelegram.Types.InlineQueryResults, + TinjectTelegram.Logger, + TinjectTelegram.Types.Passport, + TinjectTelegram.Utils.JSON, + CrossUrl.HttpClient, + System.RegularExpressions; +type + TtdOnReceiveRawData = procedure(ASender: TObject; const AData: string) of object; + TtdOnSendData = procedure(ASender: TObject; const AUrl, AData: string) of object; + TtdOnDisconect = procedure(ASender: TObject; const AErrorCode: string) of object; + {TInjectTelegramBotBase} + TInjectTelegramBotBase = class(TInjectTelegramAbstractComponent) + strict private + FLog: ILogger; + FRequest: ItdRequestAPI; + FOnRawData: TtdOnReceiveRawData; + FOnSendData: TtdOnSendData; + FOnDisconect: TtdOnDisconect; + private + FIsBusy: Boolean; + function GetLogger: ILogger; + procedure SetLogger(const Value: ILogger); + function GetHttpCore: IcuHttpClient; + procedure SetHttpCore(const Value: IcuHttpClient); + function GetUrlAPI: string; + procedure SetUrlAPI(const Value: string); + protected + function GetRequest: ItdRequestAPI; + procedure DoInitApiCore; virtual; + /// Returns TJSONArray as method request result + function GetJSONArrayFromMethod(const AValue: string): TJSONArray; + /// Returns response JSON from server as result of request + function GetArrayFromMethod(const TdClass: TBaseJsonClass; + const AValue: string): TArray; + public + constructor Create(AOwner: TComponent); override; + {$REGION 'Propriedades|Property|Свойства'} + property Logger: ILogger read GetLogger write SetLogger; + property HttpCore: IcuHttpClient read GetHttpCore write SetHttpCore; + property UrlAPI: string read GetUrlAPI write SetUrlAPI; + property IsBusy: Boolean read FIsBusy write FIsBusy; + {$ENDREGION} + {$REGION 'Eventos|Events|События'} + property OnReceiveRawData: TtdOnReceiveRawData read FOnRawData write FOnRawData; + property OnSendData: TtdOnSendData read FOnSendData write FOnSendData; + property OnDisconect: TtdOnDisconect read FOnDisconect write FOnDisconect; + {$ENDREGION} + end; + {TInjectTelegramBot} + TInjectTelegramBot = class(TInjectTelegramBotBase, IInjectTelegramBot) + private + FToken: string; + function GetToken: string; + procedure SetToken(const Value: string); + protected + procedure DoInitApiCore; override; + public + procedure AssignTo(Dest: TPersistent); override; + constructor Create(AOwner: TComponent); overload; override; + constructor Create(const AToken: string); reintroduce; overload; + constructor Create(const AToken: string; ACore: IcuHttpClient); reintroduce; overload; +{$REGION 'Getting updates'} + /// + /// + /// Use this method to receive incoming updates using long polling.
+ /// + ///
+ /// + /// Identifier of the first update to be returned. Must be greater by one + /// than the highest among the identifiers of previously received + /// updates. By default, updates starting with the earliest unconfirmed + /// update are returned. An update is considered confirmed as soon as + /// + /// getUpdates is called with an offset higher than its update_id. + /// The negative offset can be specified to retrieve updates starting + /// from -offset update from the end of the updates queue. All previous + /// updates will forgotten.
+ /// + /// + /// The number of updates that can come in one request. + /// Valid value is from 1 to 100. The default is 100. Limits the number + /// of updates to be retrieved. Values between 1—100 are accepted. + /// Defaults to 100.
+ /// + /// + /// Timeout in seconds for long polling. Defaults to 0, i.e. usual short + /// polling
+ /// + /// + /// List the types of updates you want your bot to receive. For example, + /// specify [“message”, “edited_channel_post”, “callback_query”] to only + /// receive updates of these types. See Update for a complete list of + /// available update types. Specify an empty list to receive all updates + /// regardless of type (default). If not specified, the previous setting + /// will be used.

Please note that this parameter doesn't + /// affect updates created before the call to the getUpdates, so unwanted + /// updates may be received for a short period of time.
+ /// + /// + /// An Array of Update objects is returned.
+ ///
+ /// + /// 1. This method will not work if an outgoing webhook is set up. 2. In + /// order to avoid getting duplicate updates, recalculate offset after + /// each server response.
+ ///
+ function GetUpdates( // + const Offset: Int64 = 0; // + const Limit: Int64 = 100; // + const Timeout: Int64 = 0; // + const AllowedUpdates: TAllowedUpdates = UPDATES_ALLOWED_ALL): TArray< + ItdUpdate>; overload; + /// + /// + /// Use this method to receive incoming updates using long polling.
+ /// + ///
+ /// + /// A JSON-serialized list of getUpdates method parameters.
+ /// + /// + /// An Array of Update objects is returned.
+ ///
+ /// + /// 1. This method will not work if an outgoing webhook is set up. 2. In + /// order to avoid getting duplicate updates, recalculate offset after + /// each server response.
+ ///
+ function GetUpdates( // + const JSON: string): TArray; overload; + /// + /// Use this method to specify a url and receive incoming updates via an + /// outgoing webhook. Whenever there is an update for the bot, we will + /// send an HTTPS POST request to the specified url, containing a + /// JSON-serialized Update. In case of an unsuccessful request, we will + /// give up after a reasonable amount of attempts.
+ ///
+ /// + /// HTTPS url to send updates to. Use an empty string to remove webhook + /// integration
+ /// + /// + /// Upload your public key certificate so that the root certificate in + /// use can be checked. See our self-signed guide for details.
+ /// + /// + /// NEW!Optional The fixed IP address which will be used to send webhook + /// requests instead of the IP address resolved through DNS. + /// please check out this + /// amazing guide to SetWebhooks.
+ /// + /// + /// Maximum allowed number of simultaneous HTTPS connections to the + /// webhook for update delivery, 1-100. Defaults to 40. Use lower values + /// to limit the load on your bot‘s server, and higher values to increase + /// your bot’s throughput.
+ /// + /// + /// List the types of updates you want your bot to receive. For example, + /// specify [“message”, “edited_channel_post”, “callback_query”] to only + /// receive updates of these types. See Update for a complete list of + /// available update types. Specify an empty list to receive all updates + /// regardless of type (default). If not specified, the previous setting + /// will be used.

Please note that this parameter doesn't + /// affect updates created before the call to the setWebhook, so unwanted + /// updates may be received for a short period of time.
+ /// + /// + /// + /// NEW!Optional Pass True to drop all pending updates + /// please check out this + /// amazing guide to SetWebhooks.
+ /// + /// + /// + /// Notes + /// + /// + /// 1. You will not be able to receive updates using + /// getUpdates for as long as an outgoing webhook is set up.
+ /// + /// + /// 2. To use a self-signed certificate, you need to upload your + /// public key certificate using certificate parameter. + /// Please upload as InputFile, sending a String will not work.
+ /// + /// + /// 3. Ports currently supported for Webhooks: 443, 80, 88, 8443 + /// + /// + /// NEW! If you're having any trouble setting up webhooks, + /// please check out this + /// amazing guide to Webhooks. + ///
+ function SetWebhook( // + const Url: string; // + const Certificate: TtdFileToSend = nil; // + const IpAddress: String = ''; + const MaxConnections: Int64 = 40; // + const AllowedUpdates: TAllowedUpdates = UPDATES_ALLOWED_ALL; + const DropPendingUpdates: Boolean = False; + const SecretToken: string = ''): Boolean; + /// + /// Use this method to remove webhook integration if you decide to switch + /// back to getUpdates.
+ /// + /// getUpdates.
+ ///
+ /// + /// + /// + /// Returns True on success. + /// + function DeleteWebhook( + const DropPendingUpdates: Boolean = False): Boolean; + /// + /// Use this method to get current webhook status.
+ ///
+ /// + /// On success, returns a + /// WebhookInfo object
+ ///
+ /// + /// If the bot is using + /// getUpdates, will return an object with the url field empty + /// + function GetWebhookInfo: ItdWebhookInfo; +{$ENDREGION} + +{$REGION 'Basic methods'} + /// + /// + /// A simple method for testing your bot's authentication token.
+ ///
+ ///
+ /// + /// Requires no parameters.
+ ///
+ /// + /// + /// Returns basic information about the bot in form of a User object. + /// User object. + /// + /// + function GetMe: ItdUser; + /// + /// Use this method to send text messages.
+ ///
+ /// + /// Int64 or String. Unique identifier for the target chat or username of + /// the target channel (in the format @channelusername ).
+ /// + /// + /// Text of the message to be sent, 1-4096 characters after analyzing the + /// entities.
+ /// + /// + /// Mode for analyzing entities in message text. See the options for + /// formatting for more details.
+ /// + /// + /// Disables link views for links in this message.
+ /// + /// + /// Send the message silently. Users will receive a notification + /// no sound.
+ /// + /// + /// If the message is a reply, the original message ID.
+ /// + /// + /// InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or + /// ForceReply. Additional interface options. A serialized JSON object + /// for a built-in keyboard, custom response keyboard, instructions + /// to remove keyboard response or force a response from the user.
+ /// + /// + /// Protects the contents of the sent message from forwarding and saving.
+ /// + /// + /// In case of success, the sent message is returned. + /// SendMessage + /// + function SendMessage( // + const ChatId: TtdUserLink; // + const Text: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableWebPagePreview: Boolean = False; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + /// + /// Use this method to forward messages of any kind.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Unique identifier for the chat where the original message was sent + /// (or channel username in the format @channelusername)
+ /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// Unique message identifier
+ /// + /// + /// On success, the sent Message is returned. + /// + function ForwardMessage( // + const ChatId, FromChatId: TtdUserLink; // + const MessageId: Int64; // + const DisableNotification: Boolean = False; + const ProtectContent: Boolean = False): ItdMessage; + /// + /// Use this method to send photos.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Photo to send. You can either pass a file_id as String to resend a + /// photo that is already on the Telegram servers, or upload a new photo + /// using multipart/form-data.
+ /// + /// + /// Photo caption (may also be used when resending photos by file_id), + /// 0-200 characters
+ /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to remove reply + /// keyboard or to force a reply from the user.
+ /// + /// + /// Protects the contents of the sent message from forwarding and saving.
+ /// + /// + /// On success, the sent Message + /// is returned.
+ ///
+ /// + /// Example:
+ /// + /// var
+ /// LMessage: TtdMessage;
+ /// Begin
+ /// //If the file ID is not known
+ /// LMessage := sendPhoto(chatId, TtdFileToSend.Create('The path to the file'), nil);
+ /// //If the file ID is known
+ /// LMessage := sendPhoto(chatId, 'File ID');
+ /// ...
+ /// LMessage.Free;
+ /// End;
+ ///
+ ///
+ function SendPhoto( // + const ChatId: TtdUserLink; // + const Photo: TtdFileToSend; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []; + const HasSpoiler: boolean = False): ItdMessage; + /// + /// Use this method to send audio files, if you want Telegram clients to + /// display them in the music player. Your audio must be in the .mp3 + /// format.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Audio file to send. You can either pass a file_id as String to resend + /// an audio that is already on the Telegram servers, or upload a new + /// audio file using multipart/form-data.
+ /// + /// + /// Duration of the audio in seconds
+ /// + /// + /// Performer
+ /// + /// + /// Track name
+ /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide reply keyboard + /// or to force a reply from the user.
+ /// + /// + /// Protects the contents of the sent message from forwarding and saving.
+ /// + /// + /// On success, the sent Message + /// is returned.
+ ///
+ /// + /// Bots can currently send audio files of up to 50 MB in size, this + /// limit may be changed in the future. For sending voice messages, use + /// the + /// SendAudio method instead. + /// + function SendAudio( // + const ChatId: TtdUserLink; // + const Audio: TtdFileToSend; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const Duration: Int64 = 0; // + const Performer: string = ''; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []): ItdMessage; + /// + /// Use this method to send general files.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// File to send. You can either pass a file_id as String to resend a + /// file that is already on the Telegram servers, or upload a new file + /// using multipart/form-data.
+ /// + /// + /// Thumbnail of the file sent; can be ignored if thumbnail generation for + /// the file is supported server-side. The thumbnail should be in JPEG format + /// and less than 200 kB in size. A thumbnail's width and height should not + /// exceed 320. Ignored if the file is not uploaded using multipart/form-data. + /// Thumbnails can't be reused and can be only uploaded as a new file, so you + /// can pass “attach://” if the thumbnail was uploaded using + /// multipart/form-data under . More info on Sending Files ». + ///
+ /// + /// + /// Document caption (may also be used when resending documents by + /// file_id), 0-200 characters
+ /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide reply keyboard + /// or to force a reply from the user.
+ /// + /// + /// On success, the sent Message + /// is returned.
+ ///
+ /// + /// Bots can currently send files of any type of up to 50 MB in size, + /// this limit may be changed in the future. + /// + function SendDocument( // + const ChatId: TtdUserLink; // + const Document: TtdFileToSend; // + const Thumbnail: TtdFileToSend; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableContentTypeDetection: Boolean = False; + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []): ItdMessage; + /// + /// Use this method to send video files, Telegram clients support mp4 + /// videos (other formats may be sent as Document).
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Video to send. You can either pass a file_id as String to resend a + /// video that is already on the Telegram servers, or upload a new video + /// file using multipart/form-data.
+ /// + /// + /// Duration of sent video in seconds
+ /// + /// + /// Video width
+ /// + /// + /// Video height
+ /// + /// + /// Video caption (may also be used when resending videos by file_id), + /// 0-200 characters
+ /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide reply keyboard + /// or to force a reply from the user.
+ /// + /// + /// On success, the sent Message is returned.
+ ///
+ /// + /// Bots can currently send video files of up to 50 MB in size, this + /// limit may be changed in the future. + /// + function SendVideo( // + const ChatId: TtdUserLink; // + const Video: TtdFileToSend; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const SupportsStreaming: Boolean = True; // + const Duration: Int64 = 0; // + const Width: Int64 = 0; // + const Height: Int64 = 0; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []; + const HasSpoiler: boolean = False): ItdMessage; + /// + ///Use this method to send animation files (GIF or H.264/MPEG-4 AVC video + ///without sound). On success, the sent Message is returned. Bots can currently + ///send animation files of up to 50 MB in size, this limit may be changed in the future.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Animation to send. Pass a file_id as String to send an animation that + /// exists on the Telegram servers (recommended), pass an HTTP URL as a + /// String for Telegram to get an animation from the Internet, or upload a + /// new animation using multipart/form-data. More info on Sending Files »
+ /// + /// + /// Duration of sent video in seconds
+ /// + /// + /// Video width
+ /// + /// + /// Video height
+ /// + /// + /// Thumbnail of the file sent; can be ignored if thumbnail generation for + /// the file is supported server-side. The thumbnail should be in JPEG + /// format and less than 200 kB in size. A thumbnail‘s width and height + /// should not exceed 320. Ignored if the file is not uploaded using + /// multipart/form-data. Thumbnails can’t be reused and can be only uploaded + /// as a new file, so you can pass “attach://” if the + /// thumbnail was uploaded using multipart/form-data under . + /// More info on Sending Files »
+ /// + /// + /// Video caption (may also be used when resending videos by file_id), + /// 0-200 characters
+ /// + /// + /// Mode for parsing entities in the animation caption. See formatting + /// options for more details.
+ /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide reply keyboard + /// or to force a reply from the user.
+ /// + /// + /// On success, the sent Message is returned.
+ ///
+ /// + /// Bots can currently send video files of up to 50 MB in size, this + /// limit may be changed in the future. + /// + function SendAnimation( // + const ChatId: TtdUserLink; // + const Animation: TtdFileToSend; // + const Duration: Int64 = 0; // + const Width: Int64 = 0; // + const Height: Int64 = 0; // + const Thumbnail: TtdFileToSend = nil; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []; + const HasSpoiler: boolean = False): ItdMessage; + /// + /// Use this method to send audio files, if you want Telegram clients to + /// display the file as a playable voice message. For this to work, your + /// audio must be in an .ogg file encoded with OPUS (other formats may be + /// sent as Audio or Document).
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Audio file to send. You can either pass a file_id as String to resend + /// an audio that is already on the Telegram servers, or upload a new + /// audio file using multipart/form-data.
+ /// + /// + /// Duration of sent audio in seconds
+ /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide reply keyboard + /// or to force a reply from the user.
+ /// + /// + /// On success, the sent Message + /// is returned.
+ ///
+ /// + /// Bots can currently send voice messages of up to 50 MB in size, this + /// limit may be changed in the future. + /// + function SendVoice( // + const ChatId: TtdUserLink; // + const Voice: TtdFileToSend; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const Duration: Int64 = 0; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []): ItdMessage; + /// + /// As of + /// v.4.0, Telegram clients support rounded square mp4 videos of up + /// to 1 minute long.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Video note to send. Pass a file_id as String to send a video note + /// that exists on the Telegram servers (recommended) or upload a new + /// video using multipart/form-data. More info on Sending Files ». + /// Sending video notes by a URL is currently unsupported
+ /// + /// + /// Duration of sent video in seconds
+ /// + /// + /// Video width and height
+ /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to remove reply + /// keyboard or to force a reply from the user.
+ /// + /// + /// On success, the sent Message + /// is returned.
+ ///
+ /// + /// Use this method to send video messages. + /// + function SendVideoNote( // + const ChatId: TtdUserLink; // + const VideoNote: TtdFileToSend; // + const Duration: Int64 = 0; // + const Length: Int64 = 0; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + /// + /// Use this method to send point on the map.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Latitude and Longitude of location + /// This object represents a point on the map.
+ /// + /// + /// Sends the message + /// silently. iOS users will not receive a notification, Android + /// users will receive a notification with no sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide reply keyboard + /// or to force a reply from the user.
+ /// + /// + /// Pass True, if the message should be sent even if the specified + /// replied-to message is not found.
+ /// + /// + /// On success, the sent Message + /// is returned. + /// + function SendLocation( // + const ChatId: TtdUserLink; // + const Location: ItdLocation; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + /// + /// Use this method to send information about a venue.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Latitude and Longitude of the venue
+ /// + /// + /// + /// Name of the venue.
+ /// + /// + /// Address of the venue.
+ /// + /// + /// Foursquare identifier of the venue.
+ /// + /// + /// String Optional Foursquare type of the venue, if known. + /// (For example, “arts_entertainment/default”, + /// “arts_entertainment/aquarium” or “food/icecream”.).
+ /// + /// + /// Sends the message + /// silently. iOS users will not receive a notification, Android + /// users will receive a notification with no sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide reply keyboard + /// or to force a reply from the user.
+ /// + /// + /// On success, the sent Message is returned. + /// + function SendVenue( // + const ChatId: TtdUserLink; // + const Venue: ItdVenue; // + const Location: ItdLocation; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + /// + /// Use this method to send information about a venue.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// venue Data.
+ /// + /// + /// Sends the message + /// silently. iOS users will not receive a notification, Android + /// users will receive a notification with no sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide reply keyboard + /// or to force a reply from the user.
+ /// + /// + /// On success, the sent Message is returned. + /// + function SendVenue2( // + const ChatId: TtdUserLink; // + const Venue: ItdVenue; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + /// + /// Use this method to send phone contacts.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Contact's phone number, first name, last name + /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// If the message is a reply, ID of the original message.
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide keyboard or to + /// force a reply from the user.
+ /// + /// + /// On success, the sent Message + /// is returned.
+ ///
+ /// + function SendContact( // + const ChatId: TtdUserLink; // + const Contact: ItdContact; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + /// + /// sendPoll + /// Use this method to send a native poll.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// String Yes Poll question, 1-255 characters.
+ /// + /// + /// Array of String Yes A JSON-serialized list of answer options, + /// 2-10 strings 1-100 characters each.
+ /// + /// + /// Boolean Optional True, if the poll needs to be anonymous, defaults to True.
+ /// + /// + /// String Optional Poll type, “quiz” or “regular”, defaults to “regular”.
+ /// + /// + /// Boolean Optional True, if the poll allows multiple answers, + /// ignored for polls in quiz mode, defaults to False.
+ /// + /// + /// Integer Optional 0-based + /// identifier of the correct answer option, required for polls in quiz mode.
+ /// + /// + /// Text that is shown when a user chooses an incorrect answer or taps on + /// the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line + /// feeds after entities parsing.
+ /// + /// + /// Mode for parsing entities in the explanation. See formatting options + /// for more details.
+ /// + /// + /// Amount of time in seconds the poll will be active after creation, + /// 5-600. Can't be used together with close_date.
+ /// + /// + /// Point in time (Unix timestamp) when the poll will be automatically + /// closed. Must be at least 5 and no more than 600 seconds in the future. + /// Can't be used together with open_period.
+ /// + /// + /// Boolean Optional Pass True, + /// if the poll needs to be immediately closed. This can be useful for poll preview.
+ /// + /// + /// Sends the message + /// silently. iOS users will not receive a notification, Android + /// users will receive a notification with no sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide reply keyboard + /// or to force a reply from the user.
+ /// + /// + /// On success, the sent Message is returned. + /// + function SendPoll( + const ChatId: TtdUserLink; // + const Question: String; //Poll question, 1-255 characters + const Options: Array of String; // + const Is_Anonymous: Boolean = True; // + const &type: TtdQuizType = TtdQuizType.qtRegular;//String = '{"regular"}'; // + const Allows_Multiple_Answers: Boolean = False; // + const Correct_Option_Id: Integer = 0; + const Explanation: String = ''; // + const ExplanationEntities: TArray = []; // + const Open_period : Integer = 0; // + const Close_date: Integer= 0; // + const Is_Closed: Boolean = False; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + /// + /// sendDice + /// Use this method to send a dice, which will have a random value from 1 to 6.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// Sends the message + /// silently. iOS users will not receive a notification, Android + /// users will receive a notification with no sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide reply keyboard + /// or to force a reply from the user.
+ /// + /// + /// On success, the sent Message is returned. (Yes, we're aware of the + /// “proper” singular of die. But it's awkward, and we decided to help + /// it change. One dice at a time!) + /// + function SendDice( + const ChatId: TtdUserLink; // + const Emoji: TtdEmojiType = TtdEmojiType.etDado;// + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + /// + /// Use this method when you need to tell the user that something is + /// happening on the bot's side. The status is set for 5 seconds or less + /// (when a message arrives from your bot, Telegram clients clear its + /// typing status).
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Type of action to broadcast. Choose one, depending on what the user + /// is about to receive: typing for text messages, upload_photo for + /// photos, record_video or upload_video for videos, record_audio or + /// upload_audio for audio files, upload_document for general files, + /// find_location for location data
+ /// + /// + /// We only recommend using this method when a response from the bot will + /// take a noticeable amount of time to arrive.
+ ///
+ /// + function SendChatAction( // + const ChatId: TtdUserLink; // + const Action: TtdSendChatAction; + const MessageThreadId: int64 = 0): Boolean; + /// + /// Use this method to send a group of photos, videos, documents or audios as an album. + /// Documents and audio files can be only grouped in an album with messages of the same type.
+ ///
+ /// + /// Unique identifier of the target user
+ /// + /// + /// Array of InputMediaAudio, InputMediaDocument, + /// InputMediaPhoto and InputMediaVideo. + /// A JSON-serialized array describing messages to be sent, must include 2-10 items.
+ /// + /// + /// Sends messages silently. Users will receive a notification with no sound..
+ /// + /// + /// If the messages are a reply, ID of the original message.
+ /// + /// + /// Pass True, if the message should be sent even if the specified replied-to + /// message is not found.
+ /// + /// + /// Protects the contents of the sent messages from forwarding and saving.
+ /// + /// + /// Returns a + /// Message object.
+ ///
+ /// + function sendMediaGroup( // + const ChatId: TtdUserLink; // + const AMedia: TArray; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; + const AllowSendingWithoutReply: Boolean = False; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): TArray; + /// + /// Use this method to get a list of profile pictures for a user.
+ ///
+ /// + /// Unique identifier of the target user
+ /// + /// + /// Sequential number of the first photo to be returned. By default, all + /// photos are returned.
+ /// + /// + /// Limits the number of photos to be retrieved. Values between 1—100 are + /// accepted. Defaults to 100.
+ /// + /// + /// Returns a + /// UserProfilePhotos object.
+ ///
+ /// + function GetUserProfilePhotos( // + const ChatId: TtdUserLink; // + const Offset: Int64; // + const Limit: Int64 = 100): ItdUserProfilePhotos; + /// + /// Use this method to get basic info about a file and prepare it for + /// downloading. For the moment, bots can download files of up to 20MB in + /// size.
+ ///
+ /// + /// File identifier to get info about
+ /// + /// + /// On success, a File object is + /// returned.
+ ///
+ /// + function GetFile(const FileId: string): ItdFile; + /// + /// Use this method to kick a user from a group, a supergroup or a + /// channel. In the case of supergroups and channels, the user will not + /// be able to return to the group on their own using invite links, etc., + /// unless unbanned first. The bot must be an administrator in the chat + /// for this to work and must have the appropriate admin rights.
+ ///
+ /// + /// Unique identifier for the target group or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Unique identifier of the target user
+ /// + /// + /// Date when the user will be unbanned, unix time. If user is banned for + /// more than 366 days or less than 30 seconds from the current time they + /// are considered to be banned forever unbanChatMember
+ /// + /// + /// Pass True to delete all messages from the chat for the user that is + /// being removed. If False, the user will be able to see messages in the + /// group that were sent before the user was removed. Always True for + /// supergroups and channels.
+ /// + /// + /// Returns True on success.
+ ///
+ /// + /// Note: In regular groups (non-supergroups), this method will only work + /// if the ‘All Members Are Admins’ setting is off in the target group. + /// Otherwise members may only be removed by the group's creator or by + /// the member that added them.
+ ///
+ /// + function banChatMember( // + const ChatId: TtdUserLink; // + const UserId: Int64; // + const UntilDate: TDateTime = 0; + const RevokeMessages: Boolean = False): Boolean; + /// + /// Use this method to unban a previously kicked user in a supergroup. + /// The user will not return to the group automatically, but will be able + /// to join via link, etc.
+ ///
+ /// + /// Unique identifier for the target group or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Unique identifier of the target user
+ /// + /// + /// Returns True on success.
+ ///
+ /// + /// The bot must be an administrator in the group for this to work.
+ ///
+ /// + function UnbanChatMember( // + const ChatId: TtdUserLink; // + const UserId: Int64; + const OnlyIfBanned: Boolean): Boolean; + /// + /// Use this method for your bot to leave a group, supergroup or channel.
+ ///
+ /// + /// Unique identifier for the target group or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Returns True on success.
+ ///
+ /// + function LeaveChat(const ChatId: TtdUserLink): Boolean; + /// + /// Use this method to get up to date information about the chat (current + /// name of the user for one-on-one conversations, current username of a + /// user, group or channel, etc.)
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup or channel (in the format @channelusername)
+ /// + /// + /// Returns a Chat object on + /// success.
+ ///
+ /// + function GetChat(const ChatId: TtdUserLink): ItdChat; + /// + /// Use this method to get a list of administrators in a chat.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup or channel (in the format @channelusername).
+ /// + /// + /// On success, returns an Array of + /// ChatMember objects that contains information about all chat + /// administrators except other bots. If the chat is a group or a + /// supergroup and no administrators were appointed, only the creator + /// will be returned.
+ ///
+ /// + function GetChatAdministrators(const ChatId: TtdUserLink): TArray; + /// + /// Use this method to get the number of members in a chat.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup or channel (in the format @channelusername)
+ /// + /// + /// Returns Int64 on success.
+ ///
+ /// + function GetChatMemberCount(const ChatId: TtdUserLink): Int64; + /// + /// Use this method to get information about a member of a chat.
+ ///
+ /// + /// Unique identifier for the target group or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Unique identifier of the target user
+ /// + /// + /// Returns a ChatMember + /// object on success.
+ ///
+ /// + function GetChatMember( // + const ChatId: TtdUserLink; // + const UserId: Int64): ItdChatMember; + /// + /// Use this method to send answers to callback queries sent from inline + /// keyboards. The answer will be displayed to the user as a notification + /// at the top of the chat screen or as an alert.
+ ///
+ /// + /// Unique identifier for the query to be answered
+ /// + /// + /// Text of the notification. If not specified, nothing will be shown to + /// the user
+ /// + /// + /// If true, an alert will be shown by the client instead of a + /// notification at the top of the chat screen. Defaults to false.
+ /// + /// + /// On success, True is returned.
+ ///
+ /// + function AnswerCallbackQuery( // + const CallbackQueryId: string; // + const Text: string = ''; // + const ShowAlert: Boolean = False; // + const Url: string = ''; // + const CacheTime: Int64 = 0): Boolean; +{$ENDREGION} + +{$REGION 'ForumTopic'} + function getForumTopicIconStickers(): TArray; + + function createForumTopic( + const chat_id: TtdUserLink; + const name: string = ''; + const icon_color: integer = 0; + const icon_custom_emoji_id: string = ''): ItdForumTopic; + + function editForumTopic( + const chat_id: TtdUserLink; + const message_thread_id: int64 = 0; + const name: string = ''; + const icon_custom_emoji_id: string = ''): Boolean; + + function closeForumTopic( + const chat_id: TtdUserLink; + const message_thread_id: int64 = 0): Boolean; + + function reopenForumTopic( + const chat_id: TtdUserLink; + const message_thread_id: int64 = 0): Boolean; + + function deleteForumTopic( + const chat_id: TtdUserLink; + const message_thread_id: int64 = 0): Boolean; + + function unpinAllForumTopicMessages( + const chat_id: TtdUserLink; + const message_thread_id: int64 = 0): Boolean; + + function editGeneralForumTopic( + const chat_id: TtdUserLink; + const name: string = ''): Boolean; + + function closeGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; + + function reopenGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; + + function hideGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; + + function unhideGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; + +{$ENDREGION 'ForumTopic'} + +{$REGION 'BotCommands'} + /// + /// setMyCommands + /// Use this method to change the list of the bot's commands. + /// See https://core.telegram.org/bots#commands for more details + /// about bot commands.
+ ///
+ /// + /// A JSON-serialized list of bot commands to be set as the list of the + /// bot's commands. At most 100 commands can be specified.
+ /// + /// + /// A JSON-serialized object, describing scope of users for which the + /// commands are relevant. Defaults to BotCommandScopeDefault.
+ /// + /// + /// A two-letter ISO 639-1 language code. If empty, commands will be applied + /// to all users from the given scope, for whose language there are no + /// dedicated commands.
+ /// + /// + /// On success, True is returned.
+ ///
+ /// + function SetMyCommands( + const Command: TArray; + //const scope: ItdBotCommandScope = Nil; + const scope: TtdBotCommandScopeType = TtdBotCommandScopeType.BotCommandScopeDefault; + const language_code: string = ''): Boolean; + + function SetMyCommands2( + const Command: TArray; + const scope: ItdBotCommandScope = Nil; + const language_code: string = ''): Boolean; + /// + /// getMyCommands + /// Use this method to get the current list of the bot's commands. + /// Requires no parameters.
+ ///
+ /// + /// A JSON-serialized object, describing scope of users for which the + /// commands are relevant. Defaults to BotCommandScopeDefault.
+ /// + /// + /// A two-letter ISO 639-1 language code. If empty, commands will be applied + /// to all users from the given scope, for whose language there are no + /// dedicated commands.
+ /// + /// + /// On success, Returns Array of BotCommand.
+ ///
+ /// + function GetMyCommands( + //const scope: ItdBotCommandScope = Nil; + const scope: TtdBotCommandScopeType = TtdBotCommandScopeType.BotCommandScopeDefault; + const language_code: string = ''): TArray; + + function GetMyCommands2( + const scope: ItdBotCommandScope = Nil; + const language_code: string = ''): TArray; + /// + /// deleteMyCommands + /// Use this method to delete the list of the bot's commands for the given + /// scope and user language. After deletion, higher level commands will be + /// shown to affected users.
+ ///
+ /// + /// A JSON-serialized object, describing scope of users for which the + /// commands are relevant. Defaults to BotCommandScopeDefault.
+ /// + /// + /// A two-letter ISO 639-1 language code. If empty, commands will be applied + /// to all users from the given scope, for whose language there are no + /// dedicated commands.
+ /// + /// + /// Returns True on success.. + /// + function DeleteMyCommands( + const scope: TtdBotCommandScopeType = TtdBotCommandScopeType.BotCommandScopeDefault; + const language_code: string = ''): Boolean; + + function DeleteMyCommands2( + const scope: ItdBotCommandScope = Nil; + const language_code: string = ''): Boolean; + /// + /// LogOut + /// Use this method to log out from the cloud Bot API server before + /// launching the bot locally. You must log out the bot before running + /// it locally, otherwise there is no guarantee that the bot will receive + /// updates. After a successful call, you can immediately log in on a local + /// server, but will not be able to log in back to the cloud Bot API + /// server for 10 minutes.
+ ///
+ /// + /// Returns True on success. Requires no parameters.
+ ///
+ /// + function LogOut: Boolean; + /// + /// Close + /// Use this method to close the bot instance before moving it from one + /// local server to another. You need to delete the webhook before calling + /// this method to ensure that the bot isn't launched again after server + /// restart. The method will return error 429 in the first 10 minutes after + /// the bot is launched.
+ ///
+ /// + /// Returns True on success. Requires no parameters.
+ ///
+ /// + function Close: Boolean; +{$ENDREGION 'BotCommands'} + +{$REGION 'BotName'} + function SetMyName( + const name: string = ''; + const language_code: string = '' + ): Boolean; + + function GetMyName( + const language_code: string = '' + ): ItdBotName; +{$ENDREGION 'BotName'} + +{$REGION 'BotDescription'} + function setMyDescription( + const description: string = ''; //0-512 characters + const language_code: string = '' //two-letter ISO 639-1 language code + ): Boolean; + function getMyDescription( + const language_code: string = '' //two-letter ISO 639-1 language code + ): ItdBotDescription; + function setMyShortDescription( + const short_description: string = ''; //0-120 characters + const language_code: string = '' //two-letter ISO 639-1 language code + ): Boolean; + function getMyShortDescription( + const language_code: string = '' //two-letter ISO 639-1 language code + ): ItdBotShortDescription; +{$ENDREGION 'BotDescription'} + +{$REGION 'Updating messages'} + /// + /// Use this method to edit text messages sent by the bot or via the bot + /// (for inline bots).
+ ///
+ /// + /// Required if inline_message_id is not specified. Unique identifier for + /// the target chat or username of the target channel (in the format + /// @channelusername)
+ /// + /// + /// Required if inline_message_id is not specified. Unique identifier of + /// the sent message
+ /// + /// + /// New text of the message
+ /// + /// + /// Send Markdown or HTML, if you want Telegram apps to show bold, + /// italic, fixed-width text or inline URLs in your bot's message.
+ /// + /// + /// Disables link previews for links in this message
+ /// + /// + /// A JSON-serialized object for an inline keyboard.
+ /// + /// + /// On success, if edited message is sent by the bot, the edited Message + /// is returned, otherwise True is returned.
+ ///
+ /// + function EditMessageText( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + const Text: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableWebPagePreview: Boolean = False; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + /// + /// Use this method to edit text messages sent by the bot or via the bot + /// (for inline bots).
+ ///
+ /// + /// Required if chat_id and message_id are not specified. Identifier of + /// the inline message
+ /// + /// + /// New text of the message
+ /// + /// + /// Send Markdown or HTML, if you want Telegram apps to show bold, + /// italic, fixed-width text or inline URLs in your bot's message.
+ /// + /// + /// Disables link previews for links in this message
+ /// + /// + /// A JSON-serialized object for an inline keyboard.
+ /// + /// + /// On success, if edited message is sent by the bot, the edited Message + /// is returned, otherwise True is returned.
+ ///
+ /// + function EditMessageText( // + const InlineMessageId: string; // + const Text: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableWebPagePreview: Boolean = False; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + /// + /// Use this method to edit captions of messages sent by the bot or via + /// the bot (for inline bots).
+ ///
+ /// + /// Required if InlineMessageId is not specified. Unique identifier for + /// the target chat or username of the target channel (in the format + /// @channelusername)
+ /// + /// + /// Required if InlineMessageId is not specified. Unique identifier of
+ /// the sent message
+ /// + /// + /// New caption of the message
+ /// + /// + /// A JSON-serialized object for an inline keyboard.
+ /// + /// + /// On success, if edited message is sent by the bot, the edited Message + /// is returned, otherwise True is returned.
+ ///
+ /// + function EditMessageCaption( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + const Caption: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + /// + /// Use this method to edit captions of messages sent by the bot or via + /// the bot (for inline bots).
+ ///
+ /// + /// Required if ChatId and MessageId are not specified. Identifier of the + /// inline message
+ /// + /// + /// New caption of the message
+ /// + /// + /// A JSON-serialized object for an inline keyboard.
+ /// + /// + /// On success, if edited message is sent by the bot, the edited Message + /// is returned, otherwise True is returned.
+ ///
+ /// + function EditMessageCaption( // + const InlineMessageId: string; // + const Caption: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + + function EditMessageMedia( + const ChatId: TtdUserLink; // + const MessageId: Int64; // + const Media: TtdInputMedia; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + + function EditMessageMedia( + const InlineMessageId: string; // + const Media: TtdInputMedia; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + + /// + /// Use this method to edit live location messages sent by the bot or via + /// the bot (for inline bots). A location can be edited until its + /// live_period expires or editing is explicitly disabled by a call to + /// stopMessageLiveLocation.
+ ///
+ /// + /// Required if inline_message_id is not specified. Unique identifier for + /// the target chat or username of the target channel (in the format + /// @channelusername)
+ /// + /// + /// Required if inline_message_id is not specified. Identifier of the + /// sent message
+ /// + /// + /// new location + /// + /// + /// A JSON-serialized object for a new inline keyboard.
+ /// + /// + /// On success, if the edited message was sent by the bot, the edited + /// Message is returned, otherwise True is returned. + /// + function editMessageLiveLocation( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + const Location: ItdLocation; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + /// + /// Use this method to edit live location messages sent by the bot or via + /// the bot (for inline bots). A location can be edited until its + /// live_period expires or editing is explicitly disabled by a call to + /// stopMessageLiveLocation.
+ ///
+ /// + /// Required if chat_id and message_id are not specified. + /// Identifier of the inline message sent message
+ /// + /// + /// new location + /// + /// + /// A JSON-serialized object for a new inline keyboard.
+ /// + /// + /// On success, if the edited message was sent by the bot, the edited + /// Message is returned, otherwise True is returned. + /// + function editMessageLiveLocation( // + const InlineMessageId: string; // + const Location: ItdLocation; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + /// + /// Use this method to stop updating a live location message sent by the + /// bot or via the bot (for inline bots) before live_period expires.
+ ///
+ /// + /// equired if inline_message_id is not specified. Unique identifier for + /// the target chat or username of the target channel (in the format + /// @channelusername)
+ /// + /// + /// Required if inline_message_id is not specified. Identifier of the + /// sent message
+ /// + /// + /// A JSON-serialized object for a new inline keyboard.
+ /// + /// + /// On success, if the message was sent by the bot, the sent Message is + /// returned, otherwise True is returned. + /// + function stopMessageLiveLocation( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + /// + /// Use this method to stop updating a live location message sent by the + /// bot or via the bot (for inline bots) before live_period expires.
+ ///
+ /// + /// Required if chat_id and message_id are not specified. + /// Identifier of the inline message sent message
+ /// + /// + /// A JSON-serialized object for a new inline keyboard.
+ /// + /// + /// On success, if the message was sent by the bot, the sent Message is + /// returned, otherwise True is returned. + /// + function stopMessageLiveLocation( // + const InlineMessageId: string; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + /// + /// Use this method to edit only the reply markup of messages sent by the + /// bot or via the bot (for inline bots).
+ ///
+ /// + /// Required if InlineMessageId is not specified. Unique identifier for
+ /// the target chat or username of the target channel (in the format
+ /// @channelusername)
+ /// + /// + /// Required if InlineMessageId is not specified. Unique identifier of
+ /// the sent message
+ /// + /// + /// A JSON-serialized object for an inline keyboard.
+ /// + /// + /// On success, if edited message is sent by the bot, the edited Message + /// is returned, otherwise True is returned. + /// + function EditMessageReplyMarkup( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + /// + /// Use this method to edit only the reply markup of messages sent by the + /// bot or via the bot (for inline bots).
+ ///
+ /// + /// Required if ChatId and MessageId are not specified. Identifier of
+ /// the inline message
+ /// + /// + /// A JSON-serialized object for an inline keyboard.
+ /// + /// + /// On success, if edited message is sent by the bot, the edited Message + /// is returned, otherwise True is returned. + /// + function EditMessageReplyMarkup( // + const InlineMessageId: string; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + /// + /// Use this method to delete a message.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Identifier of the message to delete
+ /// + /// + /// Returns True on success.
+ ///
+ /// + /// A message can only be deleted if it was sent less than 48 hours ago. + /// Any such recently sent outgoing message may be deleted. Additionally, + /// if the bot is an administrator in a group chat, it can delete any + /// message. If the bot is an administrator in a supergroup, it can + /// delete messages from any other user and service messages about people + /// joining or leaving the group (other types of service messages may + /// only be removed by the group creator). In channels, bots can only + /// remove their own messages.
+ ///
+ /// + function DeleteMessage( // + const ChatId: TtdUserLink; // + const MessageId: Int64): Boolean; + /// + /// CopyMessage + /// Use this method to copy messages of any kind. The method is analogous + /// to the method forwardMessages, but the copied message doesn't have a + /// link to the original message.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Unique identifier for the chat where the original message was sent + /// (or channel username in the format @channelusername)
+ /// + /// + /// Message identifier in the chat specified in from_chat_id
+ /// + /// + /// New caption for media, 0-1024 characters after entities parsing. + /// If not specified, the original caption is kept
+ /// + /// + /// Modo para analisar entidades no texto da mensagem. Veja as opções de + /// formatação para mais detalhes.
+ /// + /// + /// Desativa visualizações de link para links nesta mensagem
+ /// + /// + /// Envia a mensagem silenciosamente . Os usuários receberão uma notificação + /// sem som.
+ /// + /// + /// Se a mensagem for uma resposta, o ID da mensagem original
+ /// + /// + /// Pass True, if the message should be sent even if the specified + /// replied-to message is not found
+ /// + /// + /// InlineKeyboardMarkup or ReplyKeyboardMarkup or ReplyKeyboardHide or + /// ForceReply. Opções de interface adicionais. Um objeto serializado JSON + /// para um teclado embutido , teclado de resposta personalizado , instruções + /// para remover o teclado de resposta ou forçar uma resposta do usuário.
+ /// + /// + /// Returns the MessageId of the sent message on success. + /// copyMessage + /// + function CopyMessage( // + const ChatId: TtdUserLink; // + const FromChatId: TtdUserLink; // + const MessageId: Int64;// + const Caption: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const CaptionEntities: TArray = []; + const DisableWebPagePreview: Boolean = False; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False): Int64; +{$ENDREGION} + +{$REGION 'ChatInviteLink'} + /// + /// Use this method to create an additional invite link for a chat. + /// The bot must be an administrator in the chat for this to work and must + /// have the appropriate administrator rights. The link can be revoked using + /// the method revokeChatInviteLink.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername)
+ /// + /// + /// Invite link name; 0-32 characters
+ /// + /// + /// Point in time (Unix timestamp) when the link will expire
+ /// + /// + /// Maximum number of users that can be members of the chat simultaneously + /// after joining the chat via this invite link; 1-99999.
+ /// + /// + /// True, if users joining the chat via the link need to be approved by chat + /// administrators. If True, member_limit can't be specified
+ /// + /// + /// Returns the new invite link as ChatInviteLink object..
+ ///
+ /// + function createChatInviteLink( // + const ChatId: TtdUserLink; // + const name: String; //Invite link name; 0-32 characters + const expire_date: TDateTime; + const member_limit: Integer = 0; + const creates_join_request: boolean = false): ItdChatInviteLink; + /// + /// Use this method to edit a non-primary invite link created by the bot. + /// The bot must be an administrator in the chat for this to work and must + /// have the appropriate administrator rights.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername)
+ /// + /// + /// Point in time (Unix timestamp) when the link will expire
+ /// + /// + /// The invite link to edit.
+ /// + /// + /// Invite link name; 0-32 characters
+ /// + /// + /// Maximum number of users that can be members of the chat simultaneously + /// after joining the chat via this invite link; 1-99999.
+ /// + /// + /// True, if users joining the chat via the link need to be approved by chat + /// administrators. If True, member_limit can't be specified
+ /// + /// + /// Returns the edited invite link as a ChatInviteLink object.
+ ///
+ /// + function editChatInviteLink( // + const ChatId: TtdUserLink; // + const expire_date: TDateTime; + const invite_link: String = ''; + const name: String = ''; //Invite link name; 0-32 characters + const member_limit: Integer = 0; + const creates_join_request: boolean = false): ItdChatInviteLink; + /// + /// Use this method to revoke an invite link created by the bot. + /// If the primary link is revoked, a new link is automatically generated. + /// The bot must be an administrator in the chat for this to work and must + /// have the appropriate administrator rights.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername)
+ /// + /// + /// The invite link to edit.
+ /// + /// + /// Returns the revoked invite link as ChatInviteLink object.
+ ///
+ /// + function revokeChatInviteLink( // + const ChatId: TtdUserLink; // + const invite_link: String = ''): ItdChatInviteLink; + /// + /// Use this method to approve a chat join request. + /// The bot must be an administrator in the chat for this to work and must + /// have the can_invite_users administrator right.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername)
+ /// + /// + /// Unique identifier of the target user.
+ /// + /// + /// Returns True on success.
+ ///
+ /// + function approveChatJoinRequest( + const ChatId: TtdUserLink; // + const UserId: TtdUserLink): Boolean; + /// + /// Use this method to decline a chat join request. + /// The bot must be an administrator in the chat for this to work and must + /// have the can_invite_users administrator right.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername)
+ /// + /// + /// Unique identifier of the target user.
+ /// + /// + /// Returns True on success.
+ ///
+ /// + function declineChatJoinRequest( + const ChatId: TtdUserLink; // + const UserId: TtdUserLink): Boolean; + /// + /// Use this method to generate a new primary invite link for a chat; + /// any previously generated primary link is revoked. The bot must be an + /// administrator in the chat for this to work and must have the appropriate + /// administrator rights.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername)
+ /// + /// + /// Returns the new invite link as String on success.
+ ///
+ /// + function ExportChatInviteLink(const ChatId: TtdUserLink): string; +{$ENDREGION 'ChatInviteLink'} + +{$REGION 'Inline mode'} + /// + /// Use this method to send answers to an inline query.
+ ///
+ /// + /// Unique identifier for the answered query
+ /// + /// + /// A JSON-serialized array of results for the inline query
+ /// + /// + /// The maximum amount of time in seconds that the result of the inline + /// query may be cached on the server. Defaults to 300.
+ /// + /// + /// Pass True, if results may be cached on the server side only for the user + /// that sent the query. By default, results may be returned to any user who + /// sends the same query
+ /// + /// + /// Pass the offset that a client should send in the next query with the same + /// text to receive more results. Pass an empty string if there are no more + /// results or if you don't support pagination. + /// Offset length can't exceed 64 bytes.
+ /// + /// + /// If passed, clients will display a button with specified text that switches + /// the user to a private chat with the bot and sends the bot a start message + /// with the parameter switch_pm_parameter
+ /// + /// + /// Deep-linking parameter for the /start message sent to the bot when user + /// presses the switch button. 1-64 characters, only A-Z, a-z, 0-9, _ and - are + /// allowed.
+ /// Example:
+ /// An inline bot that sends YouTube videos can ask the user to connect the + /// bot to their YouTube account to adapt search results accordingly. + /// To do this, it displays a 'Connect your YouTube account' button above the + /// results, or even before showing any. The user presses the button, switches + /// to a private chat with the bot and, in doing so, passes a start parameter + /// that instructs the bot to return an OAuth link. Once done, the bot can + /// offer a switch_inline button so that the user can easily return to the + /// chat where they wanted to use the bot's inline capabilities.
+ /// + /// + /// On success, True is returned. No more than 50 results per query are allowed.
+ ///
+ /// + function AnswerInlineQuery( // + const InlineQueryId: string; // + const Results: TArray; // + const CacheTime: Int64 = 300; // + const IsPersonal: Boolean = False; // + const NextOffset: string = ''; // + const Button: TtdInlineQueryResultsButton = nil): Boolean; +{$ENDREGION} + +{$REGION 'Payments'} + /// + /// Use this method to send invoices.
+ ///
+ /// + /// Unique identifier for the target private chat
+ /// + /// + /// Product name
+ /// + /// + /// Product description
+ /// + /// + /// Bot-defined invoice payload, 1-128 bytes. This will not be displayed + /// to the user, use for your internal processes.
+ /// + /// + /// Payments provider token, obtained via Botfather
+ /// + /// + /// Unique deep-linking parameter that can be used to generate this + /// invoice when used as a start parameter
+ /// + /// + /// Three-letter ISO 4217 currency code, see more on currencies
+ /// + /// + /// Price breakdown, a list of components (e.g. product price, tax, + /// discount, delivery cost, delivery tax, bonus, etc.)
+ /// + /// + /// Optional. The maximum accepted amount for tips in + /// the smallest units of the currency (integer, not + /// float/double). For example, for a maximum tip of + /// US$ 1.45 pass max_tip_amount = 145. See the exp + /// parameter in currencies.json, it shows the number + /// of digits past the decimal point for each currency + /// (2 for the majority of currencies). Defaults to 0
+ /// + /// + /// Optional. A JSON-serialized array of suggested + /// amounts of tip in the smallest units of the + /// currency (integer, not float/double). At most 4 + /// suggested tip amounts can be specified. The + /// suggested tip amounts must be positive, passed in + /// a strictly increased order and must not exceed + /// max_tip_amount.
+ /// + /// + /// URL of the product photo for the invoice. Can be a photo of the goods + /// or a marketing image for a service.
+ /// + /// + /// Photo size
+ /// + /// + /// Photo width
+ /// + /// + /// Photo height
+ /// + /// + /// Pass True, if you require the user's full name to complete the order
+ /// + /// + /// Pass True, if you require the user's phone number to complete the + /// order
+ /// + /// + /// Pass True, if you require the user's email to complete the order
+ /// + /// + /// Pass True, if you require the user's shipping address to complete the + /// order
+ /// + /// + /// Pass True, if the final price depends on the shipping method
+ /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for a custom + /// reply keyboard, instructions to hide keyboard or to force a reply + /// from the user.
+ /// + /// + /// On success, the sent is + /// returned.
+ ///
+ /// + function SendInvoice( // + const ChatId: Int64; // + const Title: string; // + const Description: string; // + const Payload: string; // + const ProviderToken: string; // + const StartParameter: string; // + const Currency: string; // + const Prices: TArray; // + const MaxTipAmount: Integer = 0; // + const SuggestedTipAmounts: TArray = []; // + const ProviderData: string = ''; // + const PhotoUrl: string = ''; // + const PhotoSize: Int64 = 0; // + const PhotoWidth: Int64 = 0; // + const PhotoHeight: Int64 = 0; // + const NeedName: Boolean = False; // + const NeedPhoneNumber: Boolean = False; // + const NeedEmail: Boolean = False; // + const NeedShippingAddress: Boolean = False; // + const SendPhoneNumberToProvider: Boolean = False; // + const SendRmailToProvider: Boolean = False; // + const IsFlexible: Boolean = False; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False): ItdMessage; + /// + /// If you sent an invoice requesting a shipping address and the + /// parameter is_flexible was specified, the Bot API will send an Update + /// with a shipping_query field to the bot. Use this method to reply to + /// shipping queries. On success, True is returned.
+ ///
+ /// + /// Unique identifier for the query to be answered
+ /// + /// + /// Required if ok is True. A JSON-serialized array of + /// available shipping options.
+ /// + /// + /// Required if ok is False. Error message in human + /// readable form that explains why it is impossible to complete the + /// order (e.g. "Sorry, delivery to your desired address is + /// unavailable'). Telegram will display this message to the user.
+ /// + /// + function AnswerShippingQueryGood( // + const ShippingQueryId: string; // + const ShippingOptions: TArray): Boolean; + /// + /// Once the user has confirmed their payment and shipping details, the + /// Bot API sends the final confirmation in the form of an + /// Update with the field PreCheckoutQueryId. Use this method to + /// respond to such pre-checkout queries.
+ ///
+ /// + /// Unique identifier for the query to be answered
+ /// + /// + /// Required if ok is False. Error message in human + /// readable form that explains the reason for failure to proceed with + /// the checkout (e.g. "Sorry, somebody just bought the last of our + /// amazing black T-shirts while you were busy filling out your payment + /// details. Please choose a different color or garment!"). Telegram will + /// display this message to the user.
+ /// + /// + /// On success, True is returned.
+ ///
+ /// + /// Note: The Bot API must receive an answer within 10 seconds + /// after the pre-checkout query was sent.
+ ///
+ /// + function AnswerShippingQueryBad( // + const ShippingQueryId: string; // + const ErrorMessage: string): Boolean; + /// + /// Once the user has confirmed their payment and shipping details, the + /// Bot API sends the final confirmation in the form of an + /// Update with the field PreCheckoutQueryId. Use this method to + /// respond to such pre-checkout queries.
+ ///
+ /// + /// Unique identifier for the query to be answered
+ /// + /// + /// Required if ok is False. Error message in human + /// readable form that explains the reason for failure to proceed with + /// the checkout (e.g. "Sorry, somebody just bought the last of our + /// amazing black T-shirts while you were busy filling out your payment + /// details. Please choose a different color or garment!"). Telegram will + /// display this message to the user.
+ /// + /// + /// On success, True is returned.
+ ///
+ /// + /// Note: The Bot API must receive an answer within 10 seconds + /// after the pre-checkout query was sent.
+ ///
+ /// + function AnswerPreCheckoutQueryGood( // + const PreCheckoutQueryId: string): Boolean; + /// + /// Once the user has confirmed their payment and shipping details, the + /// Bot API sends the final confirmation in the form of an + /// Update with the field PreCheckoutQueryId. Use this method to + /// respond to such pre-checkout queries.
+ ///
+ /// + /// Unique identifier for the query to be answered
+ /// + /// + /// Required if ok is False. Error message in human + /// readable form that explains the reason for failure to proceed with + /// the checkout (e.g. "Sorry, somebody just bought the last of our + /// amazing black T-shirts while you were busy filling out your payment + /// details. Please choose a different color or garment!"). Telegram will + /// display this message to the user.
+ /// + /// + /// On success, True is returned.
+ ///
+ /// + /// Note: The Bot API must receive an answer within 10 seconds + /// after the pre-checkout query was sent.
+ ///
+ /// + function AnswerPreCheckoutQueryBad( // + const PreCheckoutQueryId: string; // + const ErrorMessage: string): Boolean; + /// + /// Once the user has confirmed their payment and shipping details, the + /// Bot API sends the final confirmation in the form of an + /// Update with the field PreCheckoutQueryId. Use this method to + /// respond to such pre-checkout queries.
+ ///
+ /// + /// Unique identifier for the query to be answered
+ /// + /// + /// Specify True if everything is alright (goods are available, + /// etc.) and the bot is ready to proceed with the order. Use False if + /// there are any problems.
+ /// + /// + /// Required if ok is False. Error message in human + /// readable form that explains the reason for failure to proceed with + /// the checkout (e.g. "Sorry, somebody just bought the last of our + /// amazing black T-shirts while you were busy filling out your payment + /// details. Please choose a different color or garment!"). Telegram will + /// display this message to the user.
+ /// + /// + /// On success, True is returned.
+ ///
+ /// + /// Note: The Bot API must receive an answer within 10 seconds + /// after the pre-checkout query was sent.
+ ///
+ /// + function AnswerPreCheckoutQuery( // + const PreCheckoutQueryId: string; // + const OK: Boolean; + const ErrorMessage: string = ''): Boolean; + + function CreateInvoiceLink( + const Title: string; // + const Description: string; // + const Payload: string; // + const ProviderToken: string; // + const Currency: string; // + const Prices: TArray; // + const MaxTipAmount: Integer = 0; // + const SuggestedTipAmounts: TArray = []; // + const ProviderData: string = ''; // + const PhotoUrl: string = ''; // + const PhotoSize: Int64 = 0; // + const PhotoWidth: Int64 = 0; // + const PhotoHeight: Int64 = 0; // + const NeedName: Boolean = False; // + const NeedPhoneNumber: Boolean = False; // + const NeedEmail: Boolean = False; // + const NeedShippingAddress: Boolean = False; // + const SendPhoneNumberToProvider: Boolean = False; // + const SendRmailToProvider: Boolean = False; // + const IsFlexible: Boolean = False // + ): string; +{$ENDREGION} + +{$REGION 'Telegram Passport'} + /// + /// Informs a user that some of the Telegram Passport elements they provided + /// contains errors. The user will not be able to re-submit their Passport to + /// you until the errors are fixed (the contents of the field for which you + /// returned the error must change).
+ /// Use this if the data submitted by the user doesn't satisfy the standards + /// your service requires for any reason. For example, if a birthday date + /// seems invalid, a submitted document is blurry, a scan shows evidence of + /// tampering, etc. Supply some details in the error message to make sure the + /// user knows how to correct the issues.
+ ///
+ /// + /// User identifier
+ /// + /// + /// A JSON-serialized array describing the errors.
+ /// + /// + /// Returns True on success. + /// + /// + function SetPassportDataErrors( // + const UserId: Int64; // + const Errors: TArray): Boolean; +{$ENDREGION 'Telegram Passport'} + +{$REGION 'Games'} + /// + /// Use this method to send a game.
+ ///
+ /// + /// Unique identifier for the target chat
+ /// + /// + /// Short name of the game, serves as the unique identifier for the game. + /// Set up your games via Botfather.
+ /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// A JSON-serialized object for an inline keyboard. If empty, one ‘Play + /// game_title’ button will be shown. If not empty, the first button must + /// launch the game.
+ /// + /// + /// On success, the sent Message is returned. + /// + /// + function SendGame( // + const ChatId: Int64; // + const GameShortName: string; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False): ItdMessage; + /// + /// Use this method to set the score of the specified user in a game.
+ ///
+ /// + /// User identifier
+ /// + /// + /// New score, must be non-negative
+ /// + /// + /// Required if ChatId and MessageId are not specified. Identifier of the + /// inline message
+ /// + /// + /// Pass True, if the high score is allowed to decrease. This can be + /// useful when fixing mistakes or banning cheaters
+ /// + /// + /// On success, if the message was sent by the bot, returns the edited + /// Message, otherwise returns True. Returns an error, if the new score + /// is not greater than the user's current score in the chat and force is + /// False.
+ ///
+ /// + function SetGameScore( // + const UserId: Int64; // + const Score: Int64; // + const InlineMessageId: string; // + const Force: Boolean = False; // + const DisableEditMessage: Boolean = False): ItdMessage; overload; + /// + /// Use this method to set the score of the specified user in a game.
+ ///
+ /// + /// User identifier
+ /// + /// + /// New score, must be non-negative
+ /// + /// + /// Pass True, if the game message should not be automatically edited to + /// include the current scoreboard
+ /// + /// + /// Required if InlineMessageId is not specified. Unique identifier for
+ /// the target chat
+ /// + /// + /// Required if InlineMessageId is not specified. Identifier of the
+ /// sent message
+ /// + /// + /// Pass True, if the high score is allowed to decrease. This can be + /// useful when fixing mistakes or banning cheaters
+ /// + /// + /// On success, if the message was sent by the bot, returns the edited + /// Message, otherwise returns True. Returns an error, if the new score + /// is not greater than the user's current score in the chat and force is + /// False.
+ ///
+ /// + function SetGameScore( // + const UserId: Int64; // + const Score: Int64; // + const ChatId: Int64; // + const MessageId: Int64; // + const Force: Boolean = False; // + const DisableEditMessage: Boolean = False): ItdMessage; overload; + /// + /// Use this method to get data for high score tables. Will return the + /// score of the specified user and several of his neighbors in a game.
+ ///
+ /// + /// Target user id
+ /// + /// + /// Required if ChatId and MessageId are not specified. Identifier of
+ /// the inline message
+ /// + /// + /// On success, returns an Array of + /// GameHighScore objects.
+ ///
+ /// + /// This method will currently return scores for the target user, plus + /// two of his closest neighbors on each side. Will also return the top + /// three users if the user and his neighbors are not among them. Please + /// note that this behavior is subject to change.
+ ///
+ /// + /// Official API + /// + function GetGameHighScores( // + const UserId: Int64; // + const InlineMessageId: string = ''): TArray; overload; + /// + /// Use this method to get data for high score tables. Will return the + /// score of the specified user and several of his neighbors in a game.
+ ///
+ /// + /// Target user id
+ /// + /// + /// Required if InlineMessageId is not specified. Unique identifier for
+ /// the target chat
+ /// + /// + /// Required if InlineMessageId is not specified. Identifier of the
+ /// sent message
+ /// + /// + /// On success, returns an Array of + /// GameHighScore objects.
+ ///
+ /// + /// This method will currently return scores for the target user, plus + /// two of his closest neighbors on each side. Will also return the top + /// three users if the user and his neighbors are not among them. Please + /// note that this behavior is subject to change.
+ ///
+ /// + /// Official API + /// + function GetGameHighScores( // + const UserId: Int64; // + const ChatId: Int64 = 0; // + const MessageId: Int64 = 0): TArray; overload; +{$ENDREGION} + +{$REGION 'Manage groups and channels'} + /// + /// Use this method to delete a chat photo.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Returns True on success.
+ ///
+ /// + /// Photos can't be changed for private chats. The bot must be an + /// administrator in the chat for this to work and must have the + /// appropriate admin rights. + /// + function DeleteChatPhoto(const ChatId: TtdUserLink): Boolean; + /// + /// Use this method to pin a message in a supergroup. The bot must be an + /// administrator in the chat for this to work and must have the + /// appropriate admin rights.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Identifier of a message to pin
+ /// + /// + /// Pass True, if it is not necessary to send a notification to all group + /// members about the new pinned message
+ /// + /// + /// Returns True on success. + /// + function PinChatMessage( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + const DisableNotification: Boolean = False): Boolean; + /// + /// Use this method to change the description of a supergroup or a + /// channel. The bot must be an administrator in the chat for this to + /// work and must have the appropriate admin rights.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// New chat description, 0-255 characters
+ /// + /// + /// Returns True on success. + /// + function SetChatDescription(const ChatId: TtdUserLink; const Description: + string): Boolean; + /// + /// Use this method to set a new profile photo for the chat. Photos can't + /// be changed for private chats.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// New chat photo, uploaded using multipart/form-data
+ /// + /// + /// Returns True on success.
+ ///
+ /// + /// The bot must be an administrator in the chat for this to work and + /// must have the appropriate admin rights. + /// + function SetChatPhoto(const ChatId: TtdUserLink; const Photo: TtdFileToSend): Boolean; + /// + /// Use this method to change the title of a chat. Titles can't be + /// changed for private chats. The bot must be an administrator in the + /// chat for this to work and must have the appropriate admin rights.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// New chat title, 1-255 characters
+ /// + /// + /// Returns True on success.
+ ///
+ /// + /// Note: In regular groups (non-supergroups), this method will only work + /// if the ‘All Members Are Admins’ setting is off in the target group. + /// + function SetChatTitle(const ChatId: TtdUserLink; const Title: string): Boolean; + /// + /// Use this method to unpin a message in a supergroup chat. The bot must + /// be an administrator in the chat for this to work and must have the + /// appropriate admin rights.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Returns True on success. + /// + function UnPinChatMessage(const ChatId: TtdUserLink; // + const MessageId: Int64 = 0 ): Boolean; + /// + /// Use this method to clear the list of pinned messages in a chat. + /// If the chat is not a private chat, the bot must be an administrator in + /// the chat for this to work and must have the 'can_pin_messages' admin + /// right in a supergroup or 'can_edit_messages' admin right in a channel..
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Returns True on success. + /// + function UnPinAllChatMessages(const ChatId: TtdUserLink): Boolean; + /// + /// banChatSenderChat + /// Use this method to ban a channel chat in a supergroup or a channel. Until + /// the chat is unbanned, the owner of the banned chat won't be able to send + /// messages on behalf of any of their channels. The bot must be an administrator + /// in the supergroup or channel for this to work and must have the appropriate + /// administrator rights.
+ /// to the method forwardMessages, but the copied message doesn't have a + /// link to the original message.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Unique identifier of the target sender chat
+ /// + /// + /// Returns True on success. + /// banChatSenderChat + /// + function banChatSenderChat(const ChatId: TtdUserLink; // + const SenderChatId: Int64): boolean; + /// + /// banChatSenderChat + /// Use this method to ban a channel chat in a supergroup or a channel. Until + /// the chat is unbanned, the owner of the banned chat won't be able to send + /// messages on behalf of any of their channels. The bot must be an administrator + /// in the supergroup or channel for this to work and must have the appropriate + /// administrator rights.
+ /// to the method forwardMessages, but the copied message doesn't have a + /// link to the original message.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Unique identifier of the target sender chat
+ /// + /// + /// Returns True on success. + /// unbanChatSenderChat + /// + function unbanChatSenderChat(const ChatId: TtdUserLink; // + const SenderChatId: Int64): boolean; +{$ENDREGION} + +{$REGION 'Manage users and admins'} + /// + /// Use this method to restrict a user in a supergroup. The bot must be + /// an administrator in the supergroup for this to work and must have the + /// appropriate admin rights. Pass True for all boolean parameters to + /// lift restrictions from a user.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Unique identifier of the target user
+ /// + /// + /// Date when restrictions will be lifted for the user, unix time. If + /// user is restricted for more than 366 days or less than 30 seconds + /// from the current time, they are considered to be restricted forever
+ /// + /// + /// Pass True, if the user can send text messages, contacts, locations + /// and venues
+ /// + /// + /// Pass True, if the user can send audios, documents, photos, videos, + /// video notes and voice notes, implies CanSendMessages
+ /// + /// + /// Pass True, if the user can send animations, games, stickers and use + /// inline bots, implies CanSendMediaMessages
+ /// + /// + /// Pass True, if the user may add web page previews to their messages, + /// implies CanSendMediaMessages
+ /// + /// + /// Returns True on success. + /// + function RestrictChatMember( // + const ChatId: TtdUserLink; // + const UserId: Int64; // + const UntilDate: TDateTime = 0; // + const UseIndependentChatPermissions: Boolean = False; + const CanSendMessages: Boolean = False; // + const CanSendMediaMessages: Boolean = False; // + const CanSendOtherMessages: Boolean = False; // + const CanAddWebPagePreviews: Boolean = False): Boolean; + /// + /// Use this method to restrict a user in a supergroup. The bot must be + /// an administrator in the supergroup for this to work and must have the + /// appropriate admin rights. Pass True for all boolean parameters to + /// lift restrictions from a user.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// Unique identifier of the target user
+ /// + /// + /// Optional + /// Pass True, if the administrator's presence in the chat is hidden
+ /// + /// + /// Pass True, if the administrator can change chat title, photo and + /// other settings
+ /// + /// + /// Pass True, if the administrator can create channel posts, channels + /// only
+ /// + /// + /// Pass True, if the administrator can edit messages of other users, + /// channels only
+ /// + /// + /// Pass True, if the administrator can delete messages of other users
+ /// + /// + /// Pass True, if the administrator can invite new users to the chat
+ /// + /// + /// Pass True, if the administrator can restrict, ban or unban chat + /// members
+ /// + /// + /// Pass True, if the administrator can pin messages, supergroups only
+ /// + /// + /// Pass True, if the administrator can add new administrators with a + /// subset of his own privileges or demote administrators that he has + /// promoted, directly or indirectly (promoted by administrators that + /// were appointed by him)
+ /// + /// + /// Returns True on success. + /// + function PromoteChatMember( // + const ChatId: TtdUserLink; // + const UserId: Int64; // + const IsAnonymous: Boolean = False; + const CanManageChat: Boolean = False; + const CanPostMessages: Boolean = False; // + const CanEditMessages: Boolean = False; // + const CanDeleteMessages: Boolean = False; // + const CanManageVideoChats: Boolean = False; + const CanRestrictMembers: Boolean = False; // + const CanPromoteMembers: Boolean = False; + const CanChangeInfo: Boolean = False; // + const CanInviteUsers: Boolean = False; // + const CanPinMessages: Boolean = False): Boolean; + /// + /// Use this method to set default chat permissions for all members. + /// The bot must be an administrator in the group or a supergroup for this + /// to work and must have the can_restrict_members administrator rights.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// supergroup (in the format @supergroupusername)
+ /// + /// + /// A JSON-serialized object for new default chat permissions.
+ /// + /// + /// Pass True if chat permissions are set independently. + /// Otherwise, the can_send_other_messages and + /// can_add_web_page_previews permissions will imply the + /// can_send_messages, can_send_audios, can_send_documents, can_send_photos, + /// can_send_videos, can_send_video_notes, and can_send_voice_notes permissions; + /// the can_send_polls permission will imply the can_send_messages permission.
+ /// + function setChatPermissions( // + const ChatId: TtdUserLink; // + const Permissions: ItdChatPermissions;// + const UseIndependentChatPermissions: Boolean = False):Boolean; +{$ENDREGION} + +{$REGION 'Strickers'} + /// + /// Use this method to send .webp stickers.
+ ///
+ /// + /// Unique identifier for the target chat or username of the target + /// channel (in the format @channelusername)
+ /// + /// + /// Sticker to send. You can either pass a file_id as String to resend a + /// sticker that is already on the Telegram servers, or upload a new + /// sticker using multipart/form-data.
+ /// + /// + /// Sends the message silently. iOS users will not receive a + /// notification, Android users will receive a notification with no + /// sound.
+ /// + /// + /// If the message is a reply, ID of the original message
+ /// + /// + /// Additional interface options. A JSON-serialized object for an inline + /// keyboard, custom reply keyboard, instructions to hide reply keyboard + /// or to force a reply from the user.
+ /// + /// + /// On success, the sent Message is returned. + /// + function SendSticker( // + const ChatId: TtdUserLink; // + const Sticker: TtdFileToSend; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const AllowSendingWithoutReply: Boolean = False; + const emoji: string = ''): ItdMessage; + /// + /// Use this method to get a sticker set.
+ ///
+ /// + /// Name of the sticker set.
+ /// + /// + /// On success, a StickerSet + /// object is returned. + /// + function getStickerSet(const Name: string): ItdStickerSet; + /// + /// Use this method to upload a .png file with a sticker for later use in + /// + /// createNewStickerSet and + /// addStickerToSet methods (can be used multiple times).
+ ///
+ /// + /// User identifier of sticker file owner
+ /// + /// + /// Png image with the sticker, must be up to 512 kilobytes in size, + /// dimensions must not exceed 512px, and either width or height must be + /// exactly 512px.
+ /// + /// + /// Returns the uploaded File on + /// success. + /// + function uploadStickerFile( + const UserId: Int64; + const sticker: TtdFileToSend; + const sticker_format: TtdStickerFormat): ItdFile; + /// + /// Use this method to create new sticker set owned by a user. The bot + /// will be able to edit the created sticker set. + /// + /// + /// User identifier of created sticker set owner
+ /// + /// + /// Short name of sticker set, to be used in t.me/addstickers/ URLs + /// (e.g., animals). Can contain only english letters, digits and + /// underscores. Must begin with a letter, can't contain consecutive + /// underscores and must end in by “__<bot username>”. + /// <bot_username> is case insensitive. 1-64 characters.
+ /// + /// + /// Sticker set title, 1-64 characters
+ /// + /// + /// Png image with the sticker, must be up to 512 kilobytes in size, + /// dimensions must not exceed 512px, and either width or height must be + /// exactly 512px. Pass a file_id as a String to send a file that already + /// exists on the Telegram servers, pass an HTTP URL as a String for + /// Telegram to get a file from the Internet, or upload a new one using + /// multipart/form-data. More info on Sending Files »
+ /// + /// + /// TGS animation with the sticker, uploaded using multipart/form-data. + /// See https://core.telegram.org/animated_stickers#technical-requirements + /// for technical requirements »
+ /// + /// + /// One or more emoji corresponding to the sticker
+ /// + /// + /// Pass True, if a set of mask stickers should be created
+ /// + /// + /// A JSON-serialized object for position where the mask should be placed + /// on faces
+ /// + /// + /// Returns True on success. + /// + function createNewStickerSet( // + const UserId: Int64; // + const Name, Title: string; // + const stickers: TArray; + const sticker_format: TtdStickerFormat; + const Sticker_type: TtdStickerType; // + const needs_repainting: Boolean = false): Boolean; + /// + /// Use this method to add a new sticker to a set created by the bot.
+ ///
+ /// + /// Returns True on success. + /// + function addStickerToSet( // + const UserId: Int64; // + const Name: string; // + const sticker: TtdFileToSend): Boolean; + /// + /// Use this method to move a sticker in a set created by the bot to a + /// specific position.
+ ///
+ /// + /// File identifier of the sticker.
+ /// + /// + /// New sticker position in the set, zero-based.
+ /// + /// + /// Returns True on success. + /// + function setStickerPositionInSet(const Sticker: string; const Position: + Int64): Boolean; + /// + /// Use this method to delete a sticker from a set created by the bot.
+ ///
+ /// + /// File identifier of the sticker.
+ /// + /// + /// Returns True on success. + /// + function deleteStickerFromSet(const Sticker: string): Boolean; + /// + /// Use this method to set a new group sticker set for a supergroup.
+ ///
+ /// + /// Returns True on success.
+ ///
+ /// + /// The bot must be an administrator in the chat for this to work and + /// must have the appropriate admin rights. Use the field + /// CanSetStickerSet optionally returned in + /// getChat requests to check if the bot can use this method. + /// + function setChatStickerSet(const ChatId: TtdUserLink; const StickerSetName: + string): Boolean; + /// + /// Use this method to delete a group sticker set from a supergroup.
+ ///
+ /// + /// Returns True on success.
+ ///
+ + function deleteChatStickerSet(const ChatId: TtdUserLink): Boolean; + /// + /// Use this method to set the thumbnail of a sticker set. + /// Animated thumbnails can be set for animated sticker sets only.
+ ///
+ /// + /// Sticker set name
+ /// + /// + /// User identifier of the sticker set owner
+ /// + /// + /// A PNG image with the thumbnail, must be up to 128 kilobytes in size and + /// have width and height exactly 100px, or a TGS animation with the thumbnail + /// up to 32 kilobytes in size;
+ /// see https://core.telegram.org/animated_stickers#technical-requirements + /// for animated sticker technical requirements. Pass a file_id as a String + /// to send a file that already exists on the Telegram servers, pass an HTTP + /// URL as a String for Telegram to get a file from the Internet, or upload + /// a new one using multipart/form-data. More info on Sending Files ». + /// Animated sticker set thumbnail can't be uploaded via HTTP URL.
+ /// + /// + /// Returns True on success. + /// + function setStickerSetThumbnail( + const Name: string; + const UserId: Int64; + const Thumbnail: string): Boolean; + /// + /// Use this method to get information about custom emoji stickers by their + /// identifiers.
+ ///
+ /// + /// List of custom emoji identifiers. At most 200 custom emoji identifiers can be specified.
+ /// + /// + /// Returns an Array of Sticker objects. + /// + function getCustomEmojiStickers( + const custom_emoji_ids: TArray): TArray; + + function setStickerMaskPosition( + const sticker: string; + const mask_position: ItdMaskPosition): Boolean; + + function setStickerKeywords( + const sticker: string; + const keywords: TArray): Boolean; + + function setStickerEmojiList( + const sticker: string; + const emoji_list: TArray): Boolean; + + function setStickerSetTitle( + const name: string; //requerido + const title: string) : Boolean; //requerido + + function deleteStickerSet( + const name: string) : Boolean; //requerido + + function setCustomEmojiStickerSetThumbnail( + const name: string; + const custom_emoji_id: string): Boolean; +{$ENDREGION} + +{$REGION 'WebApp'} + function answerWebAppQuery( // + const web_app_query_id: string = ''; + const AResult: TtdInlineQueryResult = nil): ItdSentWebAppMessage; + function setChatMenuButton( // + const chat_id: TtdUserLink; + const url: String = ''; Text: String = ''; + const ButtonType: TtdMenuButtonType = TtdMenuButtonType.MenuButtonDefault): Boolean; + function getChatMenuButton( // + const chat_id: TtdUserLink): ItdMenuButton; + function setMyDefaultAdministratorRights( // + const rights: TtdChatAdministratorRights; + const for_channels: Boolean): Boolean; + function getMyDefaultAdministratorRights( // + const for_channels: Boolean): ItdChatAdministratorRights; +{$ENDREGION} + + published + {$REGION 'Propriedades|Property|Свойства'} + property Logger; + property HttpCore; + property Token: string read GetToken write SetToken; + property IsBusy; + {$ENDREGION} + {$REGION 'Eventos|Events|События'} + property OnReceiveRawData; + property OnSendData; + property OnDisconect; + {$ENDREGION} + end; + + TTelegramBotHelper = class helper for TInjectTelegramBot + function IsValidToken: Boolean; + end; + +implementation +uses + REST.JSON, + TInjectTelegram.Helpers; + + +{TInjectTelegramBotBase} +{$REGION 'TInjectTelegramBotBase'} + +constructor TInjectTelegramBotBase.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + DoInitApiCore; +end; +procedure TInjectTelegramBotBase.DoInitApiCore; +var + StrCodeError: String; +begin + FRequest := TtdCoreApi.Create; + GetRequest.OnError := + procedure(E: Exception) + begin + if Assigned(E) then + Begin + StrCodeError := Copy(E.ToString, POS('(', E.ToString)+1, 5); + if (StrCodeError = '12007') or (StrCodeError = '12002') or (StrCodeError = '12030') then + if Assigned(OnDisconect) then + OnDisconect(Self, StrCodeError); + End; + Logger.Error('TInjectTelegramRequestAPI', E); + end; + GetRequest.OnReceive := + procedure(AData: string) + begin + if Assigned(OnReceiveRawData) then + OnReceiveRawData(Self, AData); + end; + GetRequest.OnSend := + procedure(AUrl, AData: string) + begin + IsBusy := True; + if Assigned(OnSendData) then + OnSendData(Self, AUrl, AData); + end; + GetRequest.DataExtractor := + function(AInput: string): string + var + LJSON: TJSONObject; + LExcCode: Integer; + LExcDesc: string; + begin + Result := ''; + if AInput.IsEmpty or AInput.StartsWith('(const TdClass: TBaseJsonClass; + const AValue: string): TArray; +var + LJsonArr: TJSONArray; + I: Integer; + GUID: TGUID; + LException: Exception; +begin + GUID := GetTypeData(TypeInfo(TI))^.GUID; + // check for TI interface support + if TdClass.GetInterfaceEntry(GUID) = nil then + begin + Logger.Fatal('GetArrayFromMethod: unsupported interface for ' + TdClass.ClassName); + end; + // stage 2: proceed data + LJsonArr := GetJSONArrayFromMethod(AValue); + if (not Assigned(LJsonArr)) or LJsonArr.Null then + Exit(nil); + try + SetLength(Result, LJsonArr.Count); + for I := 0 to High(Result) do + TdClass.GetTdClass.Create(LJsonArr.Items[I].ToString).GetInterface(GUID, Result[I]); + finally + LJsonArr.Free; + end; +end; +function TInjectTelegramBotBase.GetHttpCore: IcuHttpClient; +begin + Result := GetRequest.HttpCore; +end; +function TInjectTelegramBotBase.GetJSONArrayFromMethod(const AValue: string): TJSONArray; +begin + Result := TJSONObject.ParseJSONValue(AValue) as TJSONArray; +end; +function TInjectTelegramBotBase.GetLogger: ILogger; +begin + if csDestroying in ComponentState then + Exit(nil); + if FLog = nil then + FLog := TLogEmpty.Create(nil); + Result := FLog; +end; +function TInjectTelegramBotBase.GetRequest: ItdRequestAPI; +begin + Result := FRequest; +end; +function TInjectTelegramBotBase.GetUrlAPI: string; +begin + Result := GetRequest.UrlAPI; +end; +procedure TInjectTelegramBotBase.SetHttpCore(const Value: IcuHttpClient); +begin + GetRequest.HttpCore := Value; +end; +procedure TInjectTelegramBotBase.SetLogger(const Value: ILogger); +begin + FLog := Value; +end; +procedure TInjectTelegramBotBase.SetUrlAPI(const Value: string); +begin + GetRequest.UrlAPI := Value; +end; +{$ENDREGION 'TInjectTelegramBotBase'} + +{ TInjectTelegramBot } +{$REGION 'Core'} +procedure TInjectTelegramBot.AssignTo(Dest: TPersistent); +begin + if not (Assigned(Dest) or (Dest is TInjectTelegramBot)) then + Exit; + (Dest as TInjectTelegramBot).Token := Self.Token; + (Dest as TInjectTelegramBot).HttpCore := Self.HttpCore; + (Dest as TInjectTelegramBot).Logger := Self.Logger; + (Dest as TInjectTelegramBot).OnReceiveRawData := Self.OnReceiveRawData; + (Dest as TInjectTelegramBot).OnSendData := Self.OnSendData; + (Dest as TInjectTelegramBot).OnDisconect := Self.OnDisconect; + // inherited AssignTo(Dest); +end; +constructor TInjectTelegramBot.Create(AOwner: TComponent); +begin + inherited Create(AOwner); +end; +constructor TInjectTelegramBot.Create(const AToken: string; ACore: IcuHttpClient); +begin + inherited Create(nil); + Token := AToken; + HttpCore := ACore; +end; +constructor TInjectTelegramBot.Create(const AToken: string); +begin + inherited Create(nil); + SetToken(AToken); +end; +function TInjectTelegramBot.GetToken: string; +begin + Result := FToken; +end; +procedure TInjectTelegramBot.SetToken(const Value: string); +begin + FToken := Value; + GetRequest.SetToken(Token); +end; +{$ENDREGION} + +{$REGION 'Getting updates'} +function TInjectTelegramBot.SetWebhook( + const Url: string; + const Certificate: TtdFileToSend; + const IpAddress: String; + const MaxConnections: Int64; + const AllowedUpdates: TAllowedUpdates; + const DropPendingUpdates: Boolean; + const SecretToken: string): Boolean; +begin + Logger.Enter(Self, 'SetWebhook'); + Result := GetRequest.SetMethod('setWebhook') // + .AddParameter('url', Url, '', True) // + .AddParameter('certificate', Certificate, nil, False) // + .AddParameter('ip_address', IpAddress, '', False) // + .AddParameter('max_connections', MaxConnections, 0, False) // + .AddParameter('allowed_updates', AllowedUpdates.ToString, '[]', False) // + .AddParameter('drop_pending_updates', DropPendingUpdates, False, False) // + .AddParameter('secret_token', SecretToken, '', False) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetWebhook'); +end; +function TInjectTelegramBot.GetWebhookInfo: ItdWebhookInfo; +begin + Logger.Enter(Self, 'GetWebhookInfo'); + Result := TtdWebhookInfo.Create(GetRequest.SetMethod('getWebhookInfo').Execute); + Logger.Leave(Self, 'GetWebhookInfo'); +end; + +function TInjectTelegramBot.GetUpdates(const Offset, Limit, Timeout: Int64; const + AllowedUpdates: TAllowedUpdates): TArray; +begin + Result := GetArrayFromMethod(TtdUpdate, GetRequest.SetMethod('getUpdates') // + .AddParameter('offset', Offset, 0, False) // + .AddParameter('limit', Limit, 100, False) // + .AddParameter('timeout', Timeout, 0, False) // + .AddParameter('allowed_updates', AllowedUpdates.ToString, '[]', False) // + .Execute); +end; +function TInjectTelegramBot.GetUpdates(const JSON: string): TArray; +begin + Logger.Enter(Self, 'GetUpdates'); + Result := GetArrayFromMethod(TtdUpdate, JSON); + Logger.Leave(Self, 'GetUpdates'); +end; +function TInjectTelegramBot.DeleteWebhook(const DropPendingUpdates: Boolean): Boolean; +begin + Logger.Enter(Self, 'DeleteWebhook'); + Result := GetRequest.SetMethod('deleteWebhook') + .AddParameter('drop_pending_updates', DropPendingUpdates, False, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'DeleteWebhook'); +end; +procedure TInjectTelegramBot.DoInitApiCore; +const + SERVER = 'https://api.telegram.org/bot'; +begin + inherited; + GetRequest.UrlAPI := SERVER; +end; +function TInjectTelegramBot.createChatInviteLink(const ChatId: TtdUserLink; + const name: String; const expire_date: TDateTime; const member_limit: Integer; + const creates_join_request: boolean): ItdChatInviteLink; +begin + Logger.Enter(Self, 'createChatInviteLink'); + + if creates_join_request = false then + Begin + Result := TtdChatInviteLink.Create(GetRequest.SetMethod('createChatInviteLink') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('name', name, '', False) // + .AddParameter('expire_date', expire_date, 0, False) // + .AddParameter('member_limit', member_limit, 0, False) // + .AddParameter('creates_join_request', creates_join_request, False, False) // + .Execute); + End + Else + Begin + Result := TtdChatInviteLink.Create(GetRequest.SetMethod('createChatInviteLink') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('name', name, '', False) // + .AddParameter('expire_date', expire_date, 0, False) // + .AddParameter('creates_join_request', creates_join_request, False, False) // + .Execute); + End; + + Logger.Leave(Self, 'createChatInviteLink'); +end; + +function TInjectTelegramBot.CreateInvoiceLink(const Title, Description, Payload, + ProviderToken, Currency: string; const Prices: TArray; + const MaxTipAmount: Integer; const SuggestedTipAmounts: TArray; + const ProviderData, PhotoUrl: string; const PhotoSize, PhotoWidth, + PhotoHeight: Int64; const NeedName, NeedPhoneNumber, NeedEmail, + NeedShippingAddress, SendPhoneNumberToProvider, SendRmailToProvider, + IsFlexible: Boolean): string; +Var + LabeledPriceJson, + SuggestedTipAmountsJson : string; +begin + LabeledPriceJson := TJsonUtils.ArrayToJString(Prices); + SuggestedTipAmountsJson := TJsonUtils.ArrayIntToJString(SuggestedTipAmounts); + Logger.Enter(Self, 'CreateInvoiceLink'); + Result := GetRequest.SetMethod('createInvoiceLink') // + .AddParameter('title', Title, '', True) // + .AddParameter('description', Description, '', True) // + .AddParameter('payload', Payload, '', True) // + .AddParameter('provider_token', ProviderToken, '', True) // + .AddParameter('currency', Currency, '', True) // + .AddParameter('prices', LabeledPriceJson, '[{"label":"null","amount":"0"}]', True) // + .AddParameter('max_tip_amount', MaxTipAmount, 0, False) // + .AddParameter('suggested_tip_amounts', SuggestedTipAmountsJson, '[]', False) // + .AddParameter('provider_data', ProviderData, '', False) // + .AddParameter('photo_url', PhotoUrl, '', False) // + .AddParameter('photo_size', PhotoSize, 0, False) // + .AddParameter('photo_width', PhotoWidth, 0, False) // + .AddParameter('photo_height', PhotoHeight, 0, False) // + .AddParameter('need_name', NeedName, False, False) // + .AddParameter('need_phone_number', NeedPhoneNumber, False, False) // + .AddParameter('need_email', NeedEmail, False, False) // + .AddParameter('need_shipping_address', NeedShippingAddress, False, False) // + .AddParameter('send_phone_number_to_provider', SendPhoneNumberToProvider, False, False) // + .AddParameter('send_email_to_provider', SendRmailToProvider, False, False) // + .AddParameter('is_flexible', IsFlexible, False, False) // + .ExecuteAndReadValue; + Logger.Leave(Self, 'CreateInvoiceLink'); +end; + +function TInjectTelegramBot.editChatInviteLink(const ChatId: TtdUserLink; + const expire_date: TDateTime; const invite_link: String; + const name: String; const member_limit: Integer; + const creates_join_request: boolean): ItdChatInviteLink; +begin + Logger.Enter(Self, 'editChatInviteLink'); + Result := TtdChatInviteLink.Create(GetRequest.SetMethod('editChatInviteLink') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('expire_date', expire_date, 0, False) // + .AddParameter('invite_link', invite_link, '', False) // + .AddParameter('name', name, '', False) // + .AddParameter('member_limit', member_limit, 0, False) // + .AddParameter('creates_join_request', creates_join_request, False, False) // + .Execute); + Logger.Leave(Self, 'editChatInviteLink'); +end; + +function TInjectTelegramBot.revokeChatInviteLink(const ChatId: TtdUserLink; + const invite_link: String): ItdChatInviteLink; +begin + Logger.Enter(Self, 'revokeChatInviteLink'); + Result := TtdChatInviteLink.Create(GetRequest.SetMethod('revokeChatInviteLink') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('invite_link', invite_link, '', False) // + .Execute); + Logger.Leave(Self, 'revokeChatInviteLink'); +end; + +function TInjectTelegramBot.answerWebAppQuery( + const web_app_query_id: string; + const AResult: TtdInlineQueryResult): ItdSentWebAppMessage; +begin + Logger.Enter(Self, 'AnswerWebAppQuery'); + Result := TtdSentWebAppMessage.Create(GetRequest.SetMethod('answerWebAppQuery') // + .AddParameter('web_app_query_id', web_app_query_id, '', True) // + .AddParameter('result', TInterfacedObject(AResult), nil, True) // + .Execute); + Logger.Leave(Self, 'AnswerWebAppQuery'); +end; + +function TInjectTelegramBot.setChatMenuButton(const chat_id: TtdUserLink; + const url: String; Text: String; + const ButtonType: TtdMenuButtonType): Boolean; +var + menubuttonJson: String; +begin + if ButtonType <> TtdMenuButtonType.MenuButtonWebApp then + menubuttonJson := '{"type":"'+ButtonType.ToString+'"}' + else + menubuttonJson := '{"type":"'+ButtonType.ToString+'","text":"'+Text+'","web_app":{"url":"'+url+'"}}'; + + Logger.Enter(Self, 'SetChatMenuButton'); + Result := GetRequest.SetMethod('setChatMenuButton') // + .AddParameter('chat_id', chat_id, 0, False) // + .AddParameter('menu_button', menubuttonJson, '{}', False) + .ExecuteAsBool; + Logger.Leave(Self, 'SetChatMenuButton'); + +end; + +function TInjectTelegramBot.setChatPermissions(const ChatId: TtdUserLink; + const Permissions: ItdChatPermissions; + const UseIndependentChatPermissions: Boolean): Boolean; +begin + Logger.Enter(Self, 'SetChatPermissions'); + Result := GetRequest.SetMethod('setChatPermissions') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('permissions', TInterfacedObject(Permissions), Nil, True) // + .AddParameter('use_independent_chat_permissions', UseIndependentChatPermissions, False, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetChatPermissions'); +end; + +function TInjectTelegramBot.getChatMenuButton( + const chat_id: TtdUserLink): ItdMenuButton; +begin + Logger.Enter(Self, 'GetChatMenuButton'); + Result := TtdMenuButtonWebApp.Create(GetRequest.SetMethod('getChatMenuButton') // + .AddParameter('chat_id', chat_id, 0, False) // + .Execute); + Logger.Leave(Self, 'GetChatMenuButton'); +end; + +function TInjectTelegramBot.getCustomEmojiStickers( + const custom_emoji_ids: TArray): TArray; +begin + Logger.Enter(Self, 'GetCustomEmojiStickers'); + Result := GetArrayFromMethod(TtdSticker, + GetRequest.SetMethod('getCustomEmojiStickers') // + .AddParameter('custom_emoji_ids', + TJsonUtils.ArrayStringToJString(custom_emoji_ids), '[]', True) // + .Execute); + Logger.Leave(Self, 'GetCustomEmojiStickers'); +end; + +function TInjectTelegramBot.setMyDefaultAdministratorRights( + const rights: TtdChatAdministratorRights; + const for_channels: Boolean): Boolean; +begin + Logger.Enter(Self, 'SetMyDefaultAdministratorRights'); + Result := GetRequest.SetMethod('setMyDefaultAdministratorRights') // + .AddParameter('rights', rights.ToJsonObject, '{}', False) // + .AddParameter('for_channels', for_channels, False, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetMyDefaultAdministratorRights'); +end; + +function TInjectTelegramBot.getMyDefaultAdministratorRights( + const for_channels: Boolean): ItdChatAdministratorRights; +begin + Logger.Enter(Self, 'GetMyDefaultAdministratorRights'); + Result := TtdChatAdministratorRights.Create(GetRequest.SetMethod('getMyDefaultAdministratorRights') // + .AddParameter('for_channels', for_channels, False, False) // + .Execute); + Logger.Leave(Self, 'GetMyDefaultAdministratorRights'); +end; + +function TInjectTelegramBot.getMyDescription( + const language_code: string): ItdBotDescription; +begin + Logger.Enter(Self, 'GetMyDescription'); + Result := TtdBotDescription.Create(GetRequest.SetMethod('getMyDescription') // + .AddParameter('language_code', language_code, '', False) // + .Execute); + Logger.Leave(Self, 'GetMyDescription'); +end; + + +function TInjectTelegramBot.SetMyName(const name, + language_code: string): Boolean; +begin + Logger.Enter(Self, 'SetMyName'); + Result := GetRequest.SetMethod('setMyName') // + .AddParameter('name', name, '', False) // + .AddParameter('language_code', language_code, '', False) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetMyName'); +end; + +function TInjectTelegramBot.GetMyName(const language_code: string): ItdBotName; +begin + Logger.Enter(Self, 'GetMyName'); + Result := TtdBotName.Create(GetRequest.SetMethod('getMyName') // + .AddParameter('language_code', language_code, '', False) // + .Execute); + Logger.Leave(Self, 'GetMyName'); +end; + +function TInjectTelegramBot.setMyDescription(const description, + language_code: string): Boolean; +begin + Logger.Enter(Self, 'SetMyDescription'); + Result := GetRequest.SetMethod('setMyDescription') // + .AddParameter('description', description, '', False) // + .AddParameter('language_code', language_code, '', False) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetMyDescription'); +end; + +function TInjectTelegramBot.setMyShortDescription(const short_description, + language_code: string): Boolean; +begin + Logger.Enter(Self, 'SetMyShortDescription'); + Result := GetRequest.SetMethod('setMyShortDescription') // + .AddParameter('short_description', short_description, '', False) // + .AddParameter('language_code', language_code, '', False) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetMyShortDescription'); +end; + +function TInjectTelegramBot.getMyShortDescription( + const language_code: string): ItdBotShortDescription; +begin + Logger.Enter(Self, 'GetMyShortDescription'); + Result := TtdBotShortDescription.Create(GetRequest.SetMethod('getMyShortDescription') // + .AddParameter('language_code', language_code, '', False) // + .Execute); + Logger.Leave(Self, 'GetMyShortDescription'); +end; + +function TInjectTelegramBot.approveChatJoinRequest(const ChatId, + UserId: TtdUserLink): Boolean; +begin + Logger.Enter(Self, 'ApproveChatJoinRequest'); + Result := GetRequest.SetMethod('approveChatJoinRequest') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('user_id', UserId, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'ApproveChatJoinRequest'); +end; +function TInjectTelegramBot.declineChatJoinRequest(const ChatId, + UserId: TtdUserLink): Boolean; +begin + Logger.Enter(Self, 'DeclineChatJoinRequest'); + Result := GetRequest.SetMethod('declineChatJoinRequest') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('user_id', UserId, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'DeclineChatJoinRequest'); +end; +function TInjectTelegramBot.ExportChatInviteLink(const ChatId: TtdUserLink): string; +begin + Logger.Enter(Self, 'ExportChatInviteLink'); + Result := GetRequest.SetMethod('exportChatInviteLink') // + .AddParameter('chat_id', ChatId, 0, True).ExecuteAndReadValue; + Logger.Leave(Self, 'ExportChatInviteLink'); +end; +{$ENDREGION} + +{$REGION 'Basic methods'} +function TInjectTelegramBot.stopMessageLiveLocation(const ChatId: TtdUserLink; const + MessageId: Int64; ReplyMarkup: IReplyMarkup): Boolean; +begin + Logger.Enter(Self, 'stopMessageLiveLocation'); + Result := GetRequest.SetMethod('stopMessageLiveLocation') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('message_id', MessageId, 0, True) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'stopMessageLiveLocation'); +end; +function TInjectTelegramBot.stopMessageLiveLocation(const InlineMessageId: string; + ReplyMarkup: IReplyMarkup): Boolean; +begin + Logger.Enter(Self, 'stopMessageLiveLocation'); + Result := GetRequest.SetMethod('stopMessageLiveLocation') // + .AddParameter('inline_message_id', InlineMessageId, 0, True) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'stopMessageLiveLocation'); +end; +function TInjectTelegramBot.UnbanChatMember(const ChatId: TtdUserLink; const UserId: + Int64; const OnlyIfBanned: Boolean): Boolean; +begin + Logger.Enter(Self, 'UnbanChatMember'); + Result := GetRequest.SetMethod('unbanChatMember') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('only_if_banned', OnlyIfBanned, False, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'UnbanChatMember'); +end; +function TInjectTelegramBot.unbanChatSenderChat(const ChatId: TtdUserLink; + const SenderChatId: Int64): boolean; +begin + Logger.Enter(Self, 'UnbanChatSenderChat'); + Result := GetRequest.SetMethod('unbanChatSenderChat') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('sender_chat_id', SenderChatId, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'UnbanChatSenderChat'); +end; + +function TInjectTelegramBot.SendLocation( + const ChatId: TtdUserLink; + const Location: ItdLocation; + const DisableNotification: Boolean; + const ReplyToMessageId: Int64; + const AllowSendingWithoutReply: Boolean; + ReplyMarkup: IReplyMarkup; + const ProtectContent: Boolean; + const MessageThreadId: int64): ItdMessage; +begin + Logger.Enter(Self, 'SendLocation'); + Result := TtdMessage.Create(GetRequest.SetMethod('sendLocation') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('latitude', TtdLocation(Location).Latitude, 0, True) // + .AddParameter('longitude', TtdLocation(Location).Longitude, 0, True) // + .AddParameter('live_period', TtdLocation(Location).LivePeriod, 0, False) // + .AddParameter('horizontal_accuracy', TtdLocation(Location).HorizontalAccuracy, 0.0, False) // + .AddParameter('heading', TtdLocation(Location).Heading, 0, False) // + .AddParameter('proximity_alert_radius', TtdLocation(Location).ProximityAlertRadius, 0, False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .Execute); + Logger.Leave(Self, 'SendLocation'); +end; +function TInjectTelegramBot.sendMediaGroup(const ChatId: TtdUserLink; + const AMedia: TArray; + const DisableNotification: Boolean; + const ReplyToMessageId: Int64; + const AllowSendingWithoutReply: Boolean; + const ProtectContent: Boolean; + const MessageThreadId: int64): TArray; +var + LRequest: ItdRequestAPI; + LMedia: TtdInputMedia; + LTmpJson: string; +begin + Logger.Enter(Self, 'SendMediaGroup'); + LTmpJson := TJsonUtils.ArrayToJString(AMedia); + LRequest := GetRequest.SetMethod('sendMediaGroup') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('media', LTmpJson, '[]', True) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False); // + for LMedia in AMedia do + begin + case LMedia.GetFileToSend.Tag of + TtdFileToSendTag.FromFile: + LRequest.AddRawFile(ExtractFileName(LMedia.GetFileToSend.Data), LMedia.GetFileToSend.Data); + TtdFileToSendTag.FromStream: + LRequest.AddRawStream(LMedia.GetFileToSend.Data, LMedia.GetFileToSend.Content, + LMedia.GetFileToSend.Data); + end; + end; + Result := GetArrayFromMethod(TtdMessage, LRequest.Execute); + Logger.Leave(Self, 'SendMediaGroup'); +end; +function TInjectTelegramBot.SendPhoto( + const ChatId: TtdUserLink; + const Photo: TtdFileToSend; + const Caption: string; + const ParseMode: TtdParseMode; + const DisableNotification: Boolean; + const ReplyToMessageId: Int64; + const AllowSendingWithoutReply: Boolean; + ReplyMarkup: IReplyMarkup; + const ProtectContent: Boolean; + const MessageThreadId: int64; + const CaptionEntities: TArray; + const HasSpoiler: Boolean): ItdMessage; +var + LTmpJson: string; +begin + Logger.Enter(Self, 'SendPhoto'); + LTmpJson := TJsonUtils.ArrayToJString(CaptionEntities); + Result := TtdMessage.Create(GetRequest.SetMethod('sendPhoto') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('photo', Photo, nil, True) // + .AddParameter('caption', Caption, '', False) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('caption_entities ', LTmpJson, '[]', False) // + .AddParameter('has_spoiler', HasSpoiler, False, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendPhoto'); +end; +//Add By Ruan Diego Lacerda Menezes 13/04/2020 +function TInjectTelegramBot.SendPoll( ////Add By Ruan Diego Lacerda Menezes 13/04/2020 + const ChatId: TtdUserLink; // + const Question: String; //Poll question, 1-255 characters + const Options: Array of String; // + const Is_Anonymous: Boolean; // + const &type: TtdQuizType;// {String = '{"regular"}'}; // + const Allows_Multiple_Answers: Boolean; // + const Correct_Option_Id: Integer; + const Explanation: String; // + const ExplanationEntities: TArray; // + const Open_period : Integer; // + const Close_date: Integer; // + const Is_Closed: Boolean; // + const DisableNotification: Boolean; // + const ReplyToMessageId: Int64; // + const AllowSendingWithoutReply: Boolean; + ReplyMarkup: IReplyMarkup; + const ProtectContent: Boolean; + const MessageThreadId: int64): ItdMessage; +var + LTmpJson, LTmpJson2: string; +begin + Logger.Enter(Self, 'SendPoll'); + LTmpJson := TJsonUtils.ArrayStringToJString(Options); + LTmpJson2 := TJsonUtils.ArrayToJString(ExplanationEntities); + Result := TtdMessage.Create(GetRequest.SetMethod('sendPoll') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('question', Question, '', True) // + .AddParameter('options', LTmpJson, '[]', True) // + .AddParameter('is_anonymous', Is_Anonymous, True, False) // + .AddParameter('type', &type.ToString, 'regular', True) // + .AddParameter('allows_multiple_answers', Allows_Multiple_Answers, False, False) // + .AddParameter('correct_option_id', Correct_Option_Id, 0, False) // + .AddParameter('explanation', Explanation, '', False) // + .AddParameter('explanation_entities', LTmpJson2, '[]', False) // + .AddParameter('open_period', Open_period, 0, False) // + .AddParameter('close_date', Close_date, 0, False) // + .AddParameter('is_closed', Is_Closed, False, False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendPoll'); +end; +function TInjectTelegramBot.SendMessage(const ChatId: TtdUserLink; const Text: string; + const ParseMode: TtdParseMode; const DisableWebPagePreview, + DisableNotification: Boolean; const ReplyToMessageId: Int64; + const AllowSendingWithoutReply: Boolean; ReplyMarkup: + IReplyMarkup; const ProtectContent: Boolean; + const MessageThreadId: int64): ItdMessage; +begin + Logger.Enter(Self, 'SendMessage'); + Result := TtdMessage.Create(GetRequest.SetMethod('sendMessage') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('text', Text, '', True) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('disable_web_page_preview', DisableWebPagePreview, Not DisableWebPagePreview, False) // + .AddParameter('disable_notification', DisableNotification, Not DisableNotification, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('reply_markup',TInterfacedObject(ReplyMarkup), nil, False) //nil + .Execute); + Logger.Leave(Self, 'SendMessage'); +end; + +function TInjectTelegramBot.SendVenue(const ChatId: TtdUserLink; const Venue: ItdVenue; + const Location: ItdLocation; const DisableNotification: Boolean; + const ReplyToMessageId: Int64;const AllowSendingWithoutReply: Boolean; + ReplyMarkup: IReplyMarkup; const ProtectContent: Boolean; + const MessageThreadId: int64): ItdMessage; +begin + Logger.Enter(Self, 'SendVenue'); + Result := TtdMessage.Create(GetRequest.SetMethod('sendVenue') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('latitude', TtdLocation(Location).Latitude, 0, True) // + .AddParameter('longitude', TtdLocation(Location).Longitude, 0, True) // + .AddParameter('title', TtdVenue(Venue).sTitle, '', True) // + .AddParameter('address', TtdVenue(Venue).sAddress, '', True) // + .AddParameter('foursquare_id', TtdVenue(Venue).sFoursquareId, '', False) // + .AddParameter('foursquare_type', TtdVenue(Venue).sFoursquareType, '', False) //Add By Ruan Diego + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendVenue'); +end; +//Add Nova Função com a localização como propriedade do TtdVenue - By Ruan Diego +function TInjectTelegramBot.SendVenue2(const ChatId: TtdUserLink; + const Venue: ItdVenue; const DisableNotification: Boolean; + const ReplyToMessageId: Int64;const AllowSendingWithoutReply: Boolean; + ReplyMarkup: IReplyMarkup; const ProtectContent: Boolean; + const MessageThreadId: int64): ItdMessage; +begin + Logger.Enter(Self, 'SendVenue'); + Result := TtdMessage.Create(GetRequest.SetMethod('sendVenue') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('latitude', TtdVenue(Venue).sLatitude, 0, True) // + .AddParameter('longitude', TtdVenue(Venue).sLongitude, 0, True) // + .AddParameter('title', TtdVenue(Venue).sTitle, '', True) // + .AddParameter('address', TtdVenue(Venue).sAddress, '', True) // + .AddParameter('foursquare_id', TtdVenue(Venue).sFoursquareId, '', False) // + .AddParameter('foursquare_type', TtdVenue(Venue).sFoursquareType, '', False) //Add By Ruan Diego + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendVenue'); +end; +function TInjectTelegramBot.SendVideo(const ChatId: TtdUserLink; const Video: + TtdFileToSend; const Caption: string; const ParseMode: TtdParseMode; const + SupportsStreaming: Boolean; const Duration, Width, Height: Int64; const + DisableNotification: Boolean; const ReplyToMessageId: Int64; + const AllowSendingWithoutReply: Boolean; ReplyMarkup: IReplyMarkup; + const ProtectContent: Boolean; + const MessageThreadId: int64; + const CaptionEntities: TArray; + const HasSpoiler: boolean): ItdMessage; +var + LTmpJson: string; +begin + Logger.Enter(Self, 'SendVideo'); + LTmpJson := TJsonUtils.ArrayToJString(CaptionEntities); + Result := TtdMessage.Create(GetRequest.SetMethod('sendVideo') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('video', Video, nil, True) // + .AddParameter('duration', Duration, 0, False) // + .AddParameter('width', Width, 0, False) // + .AddParameter('height', Height, 0, False) // + .AddParameter('caption', Caption, '', False) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('supports_streaming', SupportsStreaming, False, False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) //' + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('caption_entities ', LTmpJson, '[]', False) // + .AddParameter('has_spoiler', HasSpoiler, False, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendVideo'); +end; +function TInjectTelegramBot.SendVideoNote(const ChatId: TtdUserLink; const VideoNote: + TtdFileToSend; const Duration, Length: Int64; const DisableNotification: + Boolean; const ReplyToMessageId: Int64; + const AllowSendingWithoutReply: Boolean; ReplyMarkup: IReplyMarkup; + const ProtectContent: Boolean;const MessageThreadId: int64): ItdMessage; +begin + Logger.Enter(Self, 'SendVideoNote'); + Result := TtdMessage.Create(GetRequest.SetMethod('sendVideoNote') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('video_note', VideoNote, nil, True) // + .AddParameter('duration', Duration, 0, False) // + .AddParameter('length', Length, 0, False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendVideoNote'); +end; +function TInjectTelegramBot.SendVoice(const ChatId: TtdUserLink; const Voice: + TtdFileToSend; const Caption: string; const ParseMode: TtdParseMode; const + Duration: Int64; const DisableNotification: Boolean; const ReplyToMessageId: + Int64; const AllowSendingWithoutReply: Boolean; + ReplyMarkup: IReplyMarkup; const ProtectContent: Boolean; + const MessageThreadId: int64; + const CaptionEntities: TArray): ItdMessage; +var + LTmpJson: string; +begin + Logger.Enter(Self, 'SendVoice'); + LTmpJson := TJsonUtils.ArrayToJString(CaptionEntities); + Result := TtdMessage.Create(GetRequest.SetMethod('sendVoice') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('voice', Voice, nil, True) // + .AddParameter('duration', Duration, 0, False) // + .AddParameter('caption', Caption, '', False) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('caption_entities ', LTmpJson, '[]', False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendVoice'); +end; +//Novo Metodo Add - By Ruan Diego +function TInjectTelegramBot.SendAnimation( // + const ChatId: TtdUserLink; // + const Animation: TtdFileToSend; // + const Duration: Int64; // + const Width: Int64; // + const Height: Int64; // + const Thumbnail: TtdFileToSend; // + const Caption: string; // + const ParseMode: TtdParseMode; // + const DisableNotification: Boolean; // + const ReplyToMessageId: Int64; // + const AllowSendingWithoutReply: Boolean; + ReplyMarkup: IReplyMarkup; + const ProtectContent: Boolean; + const MessageThreadId: int64; + const CaptionEntities: TArray; + const HasSpoiler: boolean): ItdMessage; +var + LTmpJson : string; +begin + Logger.Enter(Self, 'SendAnimation'); + LTmpJson := TJsonUtils.ArrayToJString(CaptionEntities); + Result := TtdMessage.Create(GetRequest.SetMethod('sendAnimation') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('animation', Animation, nil, True) // + .AddParameter('duration', Duration, 0, False) // + .AddParameter('width', Width, 0, False) // + .AddParameter('height', Height, 0, False) // + .AddParameter('thumbnail', Thumbnail, nil, True) // + .AddParameter('caption', Caption, '', False) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('caption_entities ', LTmpJson, '[]', False) // + .AddParameter('has_spoiler', HasSpoiler, False, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendAnimation'); +end; +function TInjectTelegramBot.SendAudio(const ChatId: TtdUserLink; const Audio: + TtdFileToSend; const Caption: string; const ParseMode: TtdParseMode; const + Duration: Int64; const Performer: string; const DisableNotification: Boolean; + const ReplyToMessageId: Int64; const AllowSendingWithoutReply: Boolean; + ReplyMarkup: IReplyMarkup; const ProtectContent: Boolean; + const MessageThreadId: int64; + const CaptionEntities: TArray): ItdMessage; +var + LTmpJson : string; +begin + Logger.Enter(Self, 'SendAudio'); + LTmpJson := TJsonUtils.ArrayToJString(CaptionEntities); + Result := TtdMessage.Create(GetRequest.SetMethod('sendAudio') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('audio', Audio, nil, True) // + .AddParameter('duration', Duration, 0, False) // + .AddParameter('performer', Performer, '', False) // + .AddParameter('caption', Caption, '', False) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('caption_entities ', LTmpJson, '[]', False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendAudio'); +end; +function TInjectTelegramBot.SendChatAction(const ChatId: TtdUserLink; const Action: + TtdSendChatAction; const MessageThreadId: int64): Boolean; +begin + Logger.Enter(Self, 'SendChatAction'); + Result := GetRequest.SetMethod('sendChatAction') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('action', Action.ToJsonString, '', True) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'SendChatAction'); +end; +function TInjectTelegramBot.SendContact(const ChatId: TtdUserLink; const Contact: + ItdContact; const DisableNotification: Boolean; const ReplyToMessageId: Int64; + const AllowSendingWithoutReply: Boolean; + ReplyMarkup: IReplyMarkup; const ProtectContent: Boolean; + const MessageThreadId: int64): ItdMessage; +begin + Logger.Enter(Self, 'SendContact'); + Result := TtdMessage.Create(GetRequest.SetMethod('sendContact') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('phone_number', Contact.PhoneNumber, '', True) // + .AddParameter('first_name', Contact.FirstName, '', True) // + .AddParameter('last_name', Contact.LastName, '', False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendContact'); +end; + +function TInjectTelegramBot.SendDice( + const ChatId: TtdUserLink; // + const Emoji: TtdEmojiType;// + const DisableNotification: Boolean; // + const ReplyToMessageId: Int64; // + const AllowSendingWithoutReply: Boolean; + ReplyMarkup: IReplyMarkup; + const ProtectContent: Boolean; + const MessageThreadId: int64): ItdMessage; +begin + Logger.Enter(Self, 'SendDice'); + Result := TtdMessage.Create(GetRequest.SetMethod('sendDice') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('emoji', Emoji.ToString, 0, False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendDice'); +end; +function TInjectTelegramBot.SendDocument( + const ChatId: TtdUserLink; + const Document: TtdFileToSend; + const Thumbnail: TtdFileToSend; // + const Caption: string; + const ParseMode: TtdParseMode; + const DisableContentTypeDetection: Boolean; + const DisableNotification: Boolean; + const ReplyToMessageId: Int64; + const AllowSendingWithoutReply: Boolean; + ReplyMarkup: IReplyMarkup; const ProtectContent: Boolean; + const MessageThreadId: int64; + const CaptionEntities: TArray): ItdMessage; +var + LTmpJson: String; +begin + Logger.Enter(Self, 'SendDocument'); + LTmpJson := TJsonUtils.ArrayToJString(CaptionEntities); + Result := TtdMessage.Create(GetRequest.SetMethod('sendDocument') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('document', Document, nil, True) // +{ TODO 5 -oRuan Diego -csendDocument : Bug Fix 00123 } +// .AddParameter('thumbnail', Thumbnail, nil, False) // + .AddParameter('caption', Caption, '', False) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('caption_entities', LTmpJson, '[]', False) // + .AddParameter('disable_content_type_detection', DisableContentTypeDetection, False, False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendDocument'); +end; +function TInjectTelegramBot.banChatMember(const ChatId: TtdUserLink; const UserId: + Int64; const UntilDate: TDateTime; const RevokeMessages: Boolean): Boolean; +begin + Logger.Enter(Self, 'BanChatMember'); + Result := GetRequest.SetMethod('banChatMember') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('until_date', UntilDate, 0, False) // + .AddParameter('revoke_messages', RevokeMessages, False, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'BanChatMember'); +end; +function TInjectTelegramBot.banChatSenderChat(const ChatId: TtdUserLink; + const SenderChatId: Int64): boolean; +begin + Logger.Enter(Self, 'BanChatSenderChat'); + Result := GetRequest.SetMethod('banChatSenderChat') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('sender_chat_id', SenderChatId, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'BanChatSenderChat'); +end; + +function TInjectTelegramBot.LeaveChat(const ChatId: TtdUserLink): Boolean; +begin + Logger.Enter(Self, 'LeaveChat'); + Result := GetRequest.SetMethod('leaveChat') // + .AddParameter('chat_id', ChatId, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'LeaveChat'); +end; +function TInjectTelegramBot.GetUserProfilePhotos(const ChatId: TtdUserLink; const + Offset, Limit: Int64): ItdUserProfilePhotos; +begin + Logger.Enter(Self, 'GetUserProfilePhotos'); + Result := TtdUserProfilePhotos.Create(GetRequest.SetMethod('getUserProfilePhotos') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('offset', Offset, 0, True) // + .AddParameter('limit', Limit, 100, False) // + .Execute); + Logger.Leave(Self, 'GetUserProfilePhotos'); +end; +function TInjectTelegramBot.GetMe: ItdUser; +begin + Logger.Enter(Self, 'GetMe'); + Result := TtdUser.Create(GetRequest.SetMethod('getMe').Execute); + Logger.Leave(Self, 'GetMe'); +end; + + +function TInjectTelegramBot.SetMyCommands( + const Command: TArray; + const scope: TtdBotCommandScopeType; + const language_code: string): Boolean; +Var + LTmpJson: String; +begin + LTmpJson := TJsonUtils.ArrayCommandsToJString(Command); + Logger.Enter(Self, 'SetMyCommands'); + Result := GetRequest.SetMethod('setMyCommands') // + .AddParameter('commands', LTmpJson, '[]', True) + .AddParameter('scope', scope.ToJsonObject, TtdBotCommandScopeType.BotCommandScopeDefault.ToJsonObject, False) + .AddParameter('language_code', language_code, '', False) + .ExecuteAsBool; + Logger.Leave(Self, 'SetMyCommands'); +end; + + +function TInjectTelegramBot.SetMyCommands2(const Command: TArray; + const scope: ItdBotCommandScope; const language_code: string): Boolean; +Var + LTmpJson: String; +begin + LTmpJson := TJsonUtils.ArrayCommandsToJString(Command); + Logger.Enter(Self, 'SetMyCommands'); + Result := GetRequest.SetMethod('setMyCommands') // + .AddParameter('commands', LTmpJson, '[]', True) + .AddParameter('scope', TtdBotCommandScope(scope).AsJson, TtdBotCommandScopeType.BotCommandScopeDefault.ToJsonObject, False) + .AddParameter('language_code', language_code, '', False) + .ExecuteAsBool; + Logger.Leave(Self, 'SetMyCommands'); + +end; + +function TInjectTelegramBot.GetMyCommands( + const scope: TtdBotCommandScopeType; + const language_code: string + ): TArray; +begin + Logger.Enter(Self, 'GetMyCommands'); + Result := GetArrayFromMethod(TtdBotCommand, + GetRequest.SetMethod('getMyCommands') + .AddParameter('scope', scope.ToJsonObject, TtdBotCommandScopeType.BotCommandScopeDefault.ToJsonObject, False) + .AddParameter('language_code', language_code, '', False) + .Execute); + Logger.Leave(Self, 'GetMyCommands'); +end; + +function TInjectTelegramBot.GetMyCommands2( + const scope: ItdBotCommandScope; + const language_code: string): TArray; +begin + Logger.Enter(Self, 'GetMyCommands'); + Result := GetArrayFromMethod(TtdBotCommand, + GetRequest.SetMethod('getMyCommands') + .AddParameter('scope', TtdBotCommandScope(scope).AsJson, TtdBotCommandScopeType.BotCommandScopeDefault.ToJsonObject, False) + .AddParameter('language_code', language_code, '', False) + .Execute); + Logger.Leave(Self, 'GetMyCommands'); +end; + +function TInjectTelegramBot.DeleteMyCommands( + //const scope: ItdBotCommandScope; + const scope: TtdBotCommandScopeType; + const language_code: string + ): Boolean; +Begin + Logger.Enter(Self, 'DeleteMyCommands'); + Result := GetRequest.SetMethod('deleteMyCommands') // + .AddParameter('scope', scope.ToJsonObject, TtdBotCommandScopeType.BotCommandScopeDefault.ToJsonObject, False) + .AddParameter('language_code', language_code, '', False) + .ExecuteAsBool; + Logger.Leave(Self, 'DeleteMyCommands'); +End; + +function TInjectTelegramBot.DeleteMyCommands2(const scope: ItdBotCommandScope; + const language_code: string): Boolean; +begin + Logger.Enter(Self, 'DeleteMyCommands'); + Result := GetRequest.SetMethod('deleteMyCommands') // + .AddParameter('scope', TtdBotCommandScope(scope).AsJson, TtdBotCommandScopeType.BotCommandScopeDefault.ToJsonObject, False) + .AddParameter('language_code', language_code, '', False) + .ExecuteAsBool; + Logger.Leave(Self, 'DeleteMyCommands'); +end; + +function TInjectTelegramBot.Close: Boolean; +begin + Logger.Enter(Self, 'Close'); + Result := GetRequest.SetMethod('close').ExecuteAsBool; + Logger.Leave(Self, 'Close'); +end; + +function TInjectTelegramBot.CopyMessage(const ChatId, FromChatId: TtdUserLink; + const MessageId: Int64; const Caption: string; const ParseMode: TtdParseMode; + const CaptionEntities: TArray; const DisableWebPagePreview, + DisableNotification: Boolean; const ReplyToMessageId: Int64; + const AllowSendingWithoutReply: Boolean; ReplyMarkup: IReplyMarkup; + const ProtectContent: Boolean): Int64; +Var + LTmpJson: String; +begin + Logger.Enter(Self, 'CopyMessage'); + LTmpJson := TJsonUtils.ArrayToJString(CaptionEntities); + Result := GetRequest.SetMethod('copyMessage') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('from_chat_id', FromChatId, 0, True) // + .AddParameter('message_id', MessageId, 0, True) // + .AddParameter('caption', Caption, '', False) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('caption_entities', LTmpJson, '', False) // + .AddParameter('disable_web_page_preview', DisableWebPagePreview, False, False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute.ToInt64; + Logger.Leave(Self, 'CopyMessage'); +end; +function TInjectTelegramBot.LogOut: Boolean; +begin + Logger.Enter(Self, 'LogOut'); + Result := GetRequest.SetMethod('logOut').ExecuteAsBool; + Logger.Leave(Self, 'LogOut'); +end; +function TInjectTelegramBot.SetPassportDataErrors(const UserId: Int64; + const Errors: TArray): Boolean; +Var + LTmpJson: String; +begin + LTmpJson := TJsonUtils.ArrayToJString(Errors); + Logger.Enter(Self, 'SetPassportDataErrors'); + Result := GetRequest.SetMethod('setPassportDataErrors') // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('errors', LTmpJson, '', True) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetPassportDataErrors'); +end; +function TInjectTelegramBot.ForwardMessage(const ChatId, FromChatId: TtdUserLink; + const MessageId: Int64; const DisableNotification: Boolean; const ProtectContent: Boolean): ItdMessage; +begin + Logger.Enter(Self, 'ForwardMessage'); + Result := TtdMessage.Create(GetRequest.SetMethod('forwardMessage') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('from_chat_id', FromChatId, 0, True) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('message_id', MessageId, 0, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .Execute); + Logger.Leave(Self, 'ForwardMessage'); +end; +function TInjectTelegramBot.GetChat(const ChatId: TtdUserLink): ItdChat; +begin + Logger.Enter(Self, 'GetChat'); + Result := TtdChat.Create(GetRequest.SetMethod('getChat').// + AddParameter('chat_id', ChatId, 0, True).Execute); + Logger.Leave(Self, 'GetChat'); +end; +function TInjectTelegramBot.GetChatAdministrators(const ChatId: TtdUserLink): TArray< + ItdChatMember>; +begin + Logger.Enter(Self, 'GetChatAdministrators'); + Result := GetArrayFromMethod(TtdChatMember, GetRequest.SetMethod + ('getChatAdministrators').AddParameter('chat_id', ChatId, 0, True).Execute); + Logger.Leave(Self, 'GetChatAdministrators'); +end; +function TInjectTelegramBot.GetChatMember(const ChatId: TtdUserLink; const UserId: + Int64): ItdChatMember; +begin + Logger.Enter(Self, 'GetChatMember'); + Result := TtdChatMember.Create(GetRequest.SetMethod('getChatMember') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('user_id', UserId, 0, True) // + .Execute); + Logger.Leave(Self, 'GetChatMember'); +end; +function TInjectTelegramBot.GetChatMemberCount(const ChatId: TtdUserLink): Int64; +var + LJSON: TJSONValue; +begin + Logger.Enter(Self, 'GetChatMemberCount'); + LJSON := TJSONObject.ParseJSONValue(GetRequest.SetMethod('getChatMemberCount') // + .AddParameter('chat_id', ChatId, 0, True).Execute); + try + if not LJSON.TryGetValue(Result) then + Result := 0; + finally + LJSON.Free; + end; + Logger.Leave(Self, 'GetChatMemberCount'); +end; + +function TInjectTelegramBot.GetFile(const FileId: string): ItdFile; +begin + Logger.Enter(Self, 'GetFile'); + Result := TtdFile.Create(GetRequest.SetMethod('getFile') // + .AddParameter('file_id', FileId, '', True).Execute); + Logger.Leave(Self, 'GetFile'); +end; + +function TInjectTelegramBot.AnswerCallbackQuery(const CallbackQueryId, Text: string; + const ShowAlert: Boolean; const Url: string; const CacheTime: Int64): Boolean; +begin + Logger.Enter(Self, 'AnswerCallbackQuery'); + Result := GetRequest.SetMethod('answerCallbackQuery') // + .AddParameter('callback_query_id', CallbackQueryId, '', True) // + .AddParameter('text', Text, '', True) // + .AddParameter('show_alert', ShowAlert, False, False) // + .AddParameter('url', Url, '', False) // + .AddParameter('cache_time', CacheTime, 0, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'AnswerCallbackQuery'); +end; +{$ENDREGION} + +{$REGION 'ForumTopic'} +function TInjectTelegramBot.getForumTopicIconStickers: TArray; +var + LRequest: ItdRequestAPI; +begin + Logger.Enter(Self, 'GetForumTopicIconStickers'); + LRequest := GetRequest.SetMethod('getForumTopicIconStickers'); + Result := GetArrayFromMethod(TtdSticker, LRequest.Execute); + Logger.Leave(Self, 'GetForumTopicIconStickers'); +end; + +function TInjectTelegramBot.unhideGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; +begin + Logger.Enter(Self, 'UnhideGeneralForumTopic'); + Result := GetRequest.SetMethod('unhideGeneralForumTopic') // + .AddParameter('chat_id', chat_id, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'UnhideGeneralForumTopic'); +end; + +function TInjectTelegramBot.createForumTopic(const chat_id: TtdUserLink; + const name: string; const icon_color: integer; + const icon_custom_emoji_id: string): ItdForumTopic; +begin + Logger.Enter(Self, 'createForumTopic'); + Result := TtdForumTopic.Create(GetRequest.SetMethod('createForumTopic') // + .AddParameter('chat_id', chat_id, 0, True) // + .AddParameter('name', name, '', True) // + .AddParameter('icon_color', icon_color, 0, False) // + .AddParameter('icon_custom_emoji_id', icon_custom_emoji_id, '', False) // + .Execute); + Logger.Leave(Self, 'createForumTopic'); +end; + +function TInjectTelegramBot.closeForumTopic(const chat_id: TtdUserLink; + const message_thread_id: int64): Boolean; +begin + Logger.Enter(Self, 'CloseForumTopic'); + Result := GetRequest.SetMethod('closeForumTopic') // + .AddParameter('chat_id', chat_id, 0, True) // + .AddParameter('message_thread_id', message_thread_id, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'CloseForumTopic'); +end; + +function TInjectTelegramBot.closeGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; +begin + Logger.Enter(Self, 'CloseGeneralForumTopic'); + Result := GetRequest.SetMethod('closeGeneralForumTopic') // + .AddParameter('chat_id', chat_id, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'CloseGeneralForumTopic'); +end; + +function TInjectTelegramBot.deleteForumTopic(const chat_id: TtdUserLink; + const message_thread_id: int64): Boolean; +begin + Logger.Enter(Self, 'DeleteForumTopic'); + Result := GetRequest.SetMethod('deleteForumTopic') // + .AddParameter('chat_id', chat_id, 0, True) // + .AddParameter('message_thread_id', message_thread_id, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'DeleteForumTopic'); +end; +function TInjectTelegramBot.editForumTopic(const chat_id: TtdUserLink; + const message_thread_id: int64; const name: string; + const icon_custom_emoji_id: string): Boolean; +begin + Logger.Enter(Self, 'EditForumTopic'); + Result := GetRequest.SetMethod('editForumTopic') // + .AddParameter('chat_id', chat_id, 0, True) // + .AddParameter('message_thread_id', message_thread_id, 0, True) // + .AddParameter('name', name, '', False) // + .AddParameter('icon_custom_emoji_id', icon_custom_emoji_id, '', False) // + .ExecuteAsBool; + Logger.Leave(Self, 'EditForumTopic'); +end; + +function TInjectTelegramBot.editGeneralForumTopic(const chat_id: TtdUserLink; + const name: string): Boolean; +begin + Logger.Enter(Self, 'EditGeneralForumTopic'); + Result := GetRequest.SetMethod('editGeneralForumTopic') // + .AddParameter('chat_id', chat_id, 0, True) // + .AddParameter('name', name, '', True) // + .ExecuteAsBool; + Logger.Leave(Self, 'EditGeneralForumTopic'); +end; +function TInjectTelegramBot.unpinAllForumTopicMessages( + const chat_id: TtdUserLink; const message_thread_id: int64): Boolean; +begin + Logger.Enter(Self, 'CloseForumTopic'); + Result := GetRequest.SetMethod('closeForumTopic') // + .AddParameter('chat_id', chat_id, 0, True) // + .AddParameter('message_thread_id', message_thread_id, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'CloseForumTopic'); +end; +function TInjectTelegramBot.reopenForumTopic(const chat_id: TtdUserLink; + const message_thread_id: int64): Boolean; +begin + Logger.Enter(Self, 'CloseForumTopic'); + Result := GetRequest.SetMethod('closeForumTopic') // + .AddParameter('chat_id', chat_id, 0, True) // + .AddParameter('message_thread_id', message_thread_id, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'CloseForumTopic'); +end; + +function TInjectTelegramBot.hideGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; +begin + Logger.Enter(Self, 'CloseForumTopic'); + Result := GetRequest.SetMethod('closeForumTopic') // + .AddParameter('chat_id', chat_id, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'CloseForumTopic'); +end; + +function TInjectTelegramBot.reopenGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; +begin + Logger.Enter(Self, 'CloseForumTopic'); + Result := GetRequest.SetMethod('closeForumTopic') // + .AddParameter('chat_id', chat_id, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'CloseForumTopic'); +end; +{$ENDREGION 'ForumTopic'} + +{$REGION 'Updating messages'} +function TInjectTelegramBot.EditMessageText(const InlineMessageId, Text: string; const + ParseMode: TtdParseMode; const DisableWebPagePreview: Boolean; ReplyMarkup: + IReplyMarkup): ItdMessage; +begin + Logger.Enter(Self, 'EditMessageText'); + Result := TtdMessage.Create(GetRequest.SetMethod('editMessageText') // + .AddParameter('inline_message_id', InlineMessageId, 0, True) // + .AddParameter('text', Text, '', True) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('disable_web_page_preview', DisableWebPagePreview, False, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'EditMessageText'); +end; +function TInjectTelegramBot.EditMessageText(const ChatId: TtdUserLink; const MessageId: + Int64; const Text: string; const ParseMode: TtdParseMode; const + DisableWebPagePreview: Boolean; ReplyMarkup: IReplyMarkup): ItdMessage; +begin + Logger.Enter(Self, 'EditMessageText'); + Result := TtdMessage.Create(GetRequest.SetMethod('editMessageText') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('message_id', MessageId, 0, True) // + .AddParameter('text', Text, '', True) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('disable_web_page_preview', DisableWebPagePreview, False, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'EditMessageText'); +end; +function TInjectTelegramBot.DeleteMessage(const ChatId: TtdUserLink; const MessageId: + Int64): Boolean; +begin + Logger.Enter(Self, 'DeleteMessage'); + Result := GetRequest.SetMethod('deleteMessage') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('message_id', MessageId, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'DeleteMessage'); +end; +function TInjectTelegramBot.EditMessageCaption(const ChatId: TtdUserLink; const + MessageId: Int64; const Caption: string; const ParseMode: TtdParseMode; + ReplyMarkup: IReplyMarkup): Boolean; +begin + Logger.Enter(Self, 'EditMessageCaption'); + Result := GetRequest.SetMethod('editMessageText') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('message_id', MessageId, 0, True) // + .AddParameter('caption', Caption, '', True) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'EditMessageCaption'); +end; +function TInjectTelegramBot.EditMessageCaption(const InlineMessageId, Caption: string; + const ParseMode: TtdParseMode; ReplyMarkup: IReplyMarkup): Boolean; +begin + Logger.Enter(Self, 'EditMessageCaption'); + Result := GetRequest.SetMethod('editMessageCaption') // + .AddParameter('inline_message_id', InlineMessageId, 0, True) // + .AddParameter('caption', Caption, '', True) // + .AddParameter('parse_mode', ParseMode.ToString, '', False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'EditMessageCaption'); +end; +//Corrigido - By Ruan Diego +function TInjectTelegramBot.editMessageLiveLocation(const ChatId: TtdUserLink; const + MessageId: Int64; const Location: ItdLocation; ReplyMarkup: IReplyMarkup): Boolean; +begin + Logger.Enter(Self, 'editMessageLiveLocation'); + Result := GetRequest.SetMethod('editMessageLiveLocation') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('message_id', MessageId, 0, True) // + .AddParameter('latitude', TtdLocation(Location).Latitude, 0, True) // + .AddParameter('longitude', TtdLocation(Location).Longitude, 0, True) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'editMessageLiveLocation'); +end; +function TInjectTelegramBot.editMessageLiveLocation(const InlineMessageId: string; + const Location: ItdLocation; ReplyMarkup: IReplyMarkup): Boolean; +begin + Logger.Enter(Self, 'editMessageLiveLocation'); + Result := GetRequest.SetMethod('editMessageLiveLocation') // + .AddParameter('inline_message_id', InlineMessageId, 0, True) // + .AddParameter('latitude', TtdLocation(Location).Latitude, 0, False) // + .AddParameter('longitude', TtdLocation(Location).Longitude, 0, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'editMessageLiveLocation'); +end; +function TInjectTelegramBot.EditMessageReplyMarkup(const ChatId: TtdUserLink; const + MessageId: Int64; ReplyMarkup: IReplyMarkup): ItdMessage; +begin + Logger.Enter(Self, 'EditMessageReplyMarkup'); + Result := TtdMessage.Create(GetRequest.SetMethod('editMessageReplyMarkup') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('message_id', MessageId, 0, True) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'EditMessageReplyMarkup'); +end; +function TInjectTelegramBot.EditMessageMedia( + const InlineMessageId: string; + const Media: TtdInputMedia; ReplyMarkup: IReplyMarkup): ItdMessage; +begin + Logger.Enter(Self, 'EditMessageMedia'); + Result := TtdMessage.Create(GetRequest.SetMethod('editMessageMedia') // + .AddParameter('inline_message_id', InlineMessageId, 0, True) // + .AddParameter('media', Media.GetFileToSend, Nil, True) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'EditMessageMedia'); +end; + +function TInjectTelegramBot.EditMessageMedia(const ChatId: TtdUserLink; + const MessageId: Int64; const Media: TtdInputMedia; + ReplyMarkup: IReplyMarkup): ItdMessage; +begin + Logger.Enter(Self, 'EditMessageMedia'); + Result := TtdMessage.Create(GetRequest.SetMethod('editMessageMedia') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('message_id', MessageId, 0, True) // + .AddParameter('media', Media.GetFileToSend, Nil, True) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'EditMessageMedia'); +end; + +function TInjectTelegramBot.EditMessageReplyMarkup(const InlineMessageId: string; + ReplyMarkup: IReplyMarkup): ItdMessage; +begin + Logger.Enter(Self, 'EditMessageReplyMarkup'); + Result := TtdMessage.Create(GetRequest.SetMethod('editMessageReplyMarkup') // + .AddParameter('inline_message_id', InlineMessageId, 0, True) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'EditMessageReplyMarkup'); +end; +{$ENDREGION} + +{$REGION 'Manage groups and channels'} +function TInjectTelegramBot.DeleteChatPhoto(const ChatId: TtdUserLink): Boolean; +begin + Logger.Enter(Self, 'DeleteChatPhoto'); + Result := GetRequest.SetMethod('deleteChatPhoto') // + .AddParameter('chat_id', ChatId, 0, True).ExecuteAsBool; + Logger.Leave(Self, 'DeleteChatPhoto'); +end; +function TInjectTelegramBot.deleteChatStickerSet(const ChatId: TtdUserLink): Boolean; +begin + Logger.Enter(Self, 'deleteChatStickerSet'); + Result := GetRequest.SetMethod('deleteChatStickerSet') // + .AddParameter('chat_id', ChatId, 0, True) + .ExecuteAsBool; + Logger.Leave(Self, 'deleteChatStickerSet'); +end; + +function TInjectTelegramBot.PinChatMessage(const ChatId: TtdUserLink; const MessageId: + Int64; const DisableNotification: Boolean): Boolean; +begin + Logger.Enter(Self, 'PinChatMessage'); + Result := GetRequest.SetMethod('pinChatMessage') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('message_id', MessageId, 0, True) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'PinChatMessage'); +end; +function TInjectTelegramBot.SetChatDescription(const ChatId: TtdUserLink; const + Description: string): Boolean; +begin + Logger.Enter(Self, 'SetChatDescription'); + Result := GetRequest.SetMethod('setChatDescription') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('description', Description, '', True) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetChatDescription'); +end; + +function TInjectTelegramBot.SetChatPhoto(const ChatId: TtdUserLink; const Photo: + TtdFileToSend): Boolean; +begin + Logger.Enter(Self, 'SetChatPhoto'); + Result := GetRequest.SetMethod('setChatDescription') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('photo', Photo, nil, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetChatPhoto'); +end; +function TInjectTelegramBot.setChatStickerSet(const ChatId: TtdUserLink; const + StickerSetName: string): Boolean; +begin + Logger.Enter(Self, 'setChatStickerSet'); + Result := GetRequest.SetMethod('setChatStickerSet') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('sticker_set_name', StickerSetName, '', True) // + .ExecuteAsBool; + Logger.Leave(Self, 'setChatStickerSet'); +end; +function TInjectTelegramBot.SetChatTitle(const ChatId: TtdUserLink; const Title: + string): Boolean; +begin + Logger.Enter(Self, 'SetChatTitle'); + Result := GetRequest.SetMethod('setChatTitle') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('title', Title, '', True) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetChatTitle'); +end; +function TInjectTelegramBot.setCustomEmojiStickerSetThumbnail(const name, + custom_emoji_id: string): Boolean; +begin + Logger.Enter(Self, 'SetCustomEmojiStickerSetThumbnail'); + Result := GetRequest.SetMethod('setCustomEmojiStickerSetThumbnail') // + .AddParameter('name', name, '', True) // + .AddParameter('custom_emoji_id', custom_emoji_id, '', True) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetCustomEmojiStickerSetThumbnail'); +end; + +function TInjectTelegramBot.UnPinAllChatMessages( + const ChatId: TtdUserLink): Boolean; +begin + Logger.Enter(Self, 'UnPinAllChatMessages'); + Result := GetRequest.SetMethod('unpinAllChatMessages') + .AddParameter('chat_id', ChatId, 0, True) + .ExecuteAsBool; + Logger.Leave(Self, 'UnPinAllChatMessages'); +end; + +function TInjectTelegramBot.UnPinChatMessage(const ChatId: TtdUserLink; + const MessageId: Int64): Boolean; +begin + Logger.Enter(Self, 'UnpinChatMessage'); + Result := GetRequest.SetMethod('unpinChatMessage') // + .AddParameter('chat_id', ChatId, 0, True) + .AddParameter('message_id', MessageId, 0, False) + .ExecuteAsBool; + Logger.Leave(Self, 'UnpinChatMessage'); +end; +{$ENDREGION} + +{$REGION 'Manage users and admins'} +function TInjectTelegramBot.PromoteChatMember( // + const ChatId: TtdUserLink; // + const UserId: Int64; // + const IsAnonymous: Boolean = False; + const CanManageChat: Boolean = False; + const CanPostMessages: Boolean = False; // + const CanEditMessages: Boolean = False; // + const CanDeleteMessages: Boolean = False; // + const CanManageVideoChats: Boolean = False; + const CanRestrictMembers: Boolean = False; // + const CanPromoteMembers: Boolean = False; + const CanChangeInfo: Boolean = False; // + const CanInviteUsers: Boolean = False; // + const CanPinMessages: Boolean = False): Boolean; +begin + Logger.Enter(Self, 'PromoteChatMember'); + Result := GetRequest.SetMethod('promoteChatMember') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('is_anonymous', IsAnonymous, False, False) // + .AddParameter('can_manage_chat', CanManageChat, False, False) // + .AddParameter('can_post_messages', CanPostMessages, False, False) // + .AddParameter('can_edit_messages', CanEditMessages, False, False) // + .AddParameter('can_delete_messages', CanDeleteMessages, False, False) // + .AddParameter('can_manage_video_chats ', CanManageVideoChats, False, False) // + .AddParameter('can_restrict_members', CanRestrictMembers, False, False) // + .AddParameter('can_promote_members', CanPromoteMembers, False, False) // + .AddParameter('can_change_info', CanChangeInfo, False, False) // + .AddParameter('can_invite_users', CanInviteUsers, False, False) // + .AddParameter('can_pin_messages', CanPinMessages, False, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'PromoteChatMember'); +end; + +function TInjectTelegramBot.RestrictChatMember(const ChatId: TtdUserLink; const UserId: + Int64; const UntilDate: TDateTime; const UseIndependentChatPermissions: Boolean; const CanSendMessages, CanSendMediaMessages, + CanSendOtherMessages, CanAddWebPagePreviews: Boolean): Boolean; +begin + Logger.Enter(Self, 'RestrictChatMember'); + Result := GetRequest.SetMethod('restrictChatMember') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('until_date', UntilDate, 0, False) // + .AddParameter('use_independent_chat_permissions', UseIndependentChatPermissions, False, False) // + .AddParameter('can_send_messages', CanSendMessages, False, False) // + .AddParameter('can_send_media_messages', CanSendMediaMessages, False, False) // + .AddParameter('can_send_other_messages', CanSendOtherMessages, False, False) // + .AddParameter('can_add_web_page_previews', CanAddWebPagePreviews, False, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'RestrictChatMember'); +end; +{$ENDREGION} + +{$REGION 'Stickers'} +function TInjectTelegramBot.addStickerToSet(const UserId: Int64; const Name: string; + const sticker: TtdFileToSend): Boolean; +begin + Logger.Enter(Self, 'addStickerToSet'); + Result := GetRequest.SetMethod('addStickerToSet') // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('name', Name, '', False) // + .AddParameter('sticker', sticker, nil, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'addStickerToSet'); +end; +function TInjectTelegramBot.createNewStickerSet( + const UserId: Int64; + const Name, Title: string; + const stickers: TArray; + const sticker_format: TtdStickerFormat; + const Sticker_type: TtdStickerType; // + const needs_repainting: Boolean = false): Boolean; +Var + LTmpJson: String; +begin + LTmpJson := TJsonUtils.ArrayToJString(stickers); + + Logger.Enter(Self, 'createNewStickerSet'); + Result := GetRequest.SetMethod('createNewStickerSet') // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('name', Name, '', False) // + .AddParameter('title', Title, '', False) // + .AddParameter('stickers', LTmpJson, '[]', False) // + .AddParameter('sticker_format', sticker_format.ToString, '', False) // + .AddParameter('Sticker_type', Sticker_type.ToString, '', False) // + .AddParameter('needs_repainting', needs_repainting, False, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'createNewStickerSet'); +end; +function TInjectTelegramBot.deleteStickerFromSet(const Sticker: string): Boolean; +begin + Logger.Enter(Self, 'deleteStickerFromSet'); + Result := GetRequest.SetMethod('deleteStickerFromSet') // + .AddParameter('sticker', Sticker, '', False) // + .ExecuteAsBool; + Logger.Leave(Self, 'deleteStickerFromSet'); +end; + +function TInjectTelegramBot.deleteStickerSet(const name: string): Boolean; +begin + Logger.Enter(Self, 'DeleteStickerSet'); + Result := GetRequest.SetMethod('deleteStickerSet') // + .AddParameter('name', name, '', True) // + .ExecuteAsBool; + Logger.Leave(Self, 'DeleteStickerSet'); +end; + +function TInjectTelegramBot.getStickerSet(const Name: string): ItdStickerSet; +begin + Logger.Enter(Self, 'getStickerSet'); + Result := TtdStickerSet.Create(GetRequest.SetMethod('getStickerSet') // + .AddParameter('name', Name, '', True).Execute); + Logger.Leave(Self, 'getStickerSet'); +end; +function TInjectTelegramBot.SendSticker(const ChatId: TtdUserLink; const Sticker: + TtdFileToSend; const DisableNotification: Boolean; const ReplyToMessageId: + Int64; ReplyMarkup: IReplyMarkup; const ProtectContent: Boolean; + const MessageThreadId: int64; + const AllowSendingWithoutReply: Boolean; + const emoji: string): ItdMessage; +begin + Logger.Enter(Self, 'SendSticker'); + Result := TtdMessage.Create(GetRequest.SetMethod('sendSticker') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('sticker', Sticker, nil, True) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('message_thread_id ', MessageThreadId, 0, False) // + .AddParameter('allow_sending_without_reply', AllowSendingWithoutReply, False, False) // + .AddParameter('emoji ', emoji, '', False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendSticker'); +end; +function TInjectTelegramBot.setStickerEmojiList(const sticker: string; + const emoji_list: TArray): Boolean; +begin + Logger.Enter(Self, 'SetStickerEmojiList'); + Result := GetRequest.SetMethod('setStickerEmojiList') // + .AddParameter('sticker', sticker, '', True) // + .AddParameter('emoji_list', TJsonUtils.ArrayStringToJString(emoji_list), '[]', True) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetStickerEmojiList'); +end; + +function TInjectTelegramBot.setStickerKeywords(const sticker: string; + const keywords: TArray): Boolean; +begin + Logger.Enter(Self, 'SetStickerKeywords'); + Result := GetRequest.SetMethod('setStickerKeywords') // + .AddParameter('sticker', sticker, '', True) // + .AddParameter('keywords', TJsonUtils.ArrayStringToJString(keywords), '[]', True) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetStickerKeywords'); +end; + +function TInjectTelegramBot.setStickerMaskPosition(const sticker: string; + const mask_position: ItdMaskPosition): Boolean; +begin + Logger.Enter(Self, 'SetStickerMaskPosition'); + Result := GetRequest.SetMethod('setStickerMaskPosition') // + .AddParameter('sticker', name, '', True) // + .AddParameter('mask_position', TInterfacedObject(mask_position), nil, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetStickerMaskPosition'); +end; + +function TInjectTelegramBot.setStickerPositionInSet(const Sticker: string; const + Position: Int64): Boolean; +begin + Logger.Enter(Self, 'setStickerPositionInSet'); + Result := GetRequest.SetMethod('deleteStickerFromSet') // + .AddParameter('sticker', Sticker, '', True) // + .AddParameter('position', Position, 0, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'setStickerPositionInSet'); +end; +function TInjectTelegramBot.setStickerSetThumbnail(const Name: string; + const UserId: Int64; const Thumbnail: string): Boolean; +begin + Logger.Enter(Self, 'SetStickerSetThumbnail'); + Result := GetRequest.SetMethod('setStickerSetThumbnail') // + .AddParameter('name ', Name, '', True) + .AddParameter('user_id', UserId, 0, True) + .AddParameter('thumbnail', Thumbnail, '', False).ExecuteAsBool; + Logger.Leave(Self, 'SetStickerSetThumbnail'); +end; +function TInjectTelegramBot.setStickerSetTitle(const name, + title: string): Boolean; +begin + Logger.Enter(Self, 'SetStickerSetTitle'); + Result := GetRequest.SetMethod('setStickerSetTitle') // + .AddParameter('name', name, '', True) // + .AddParameter('title', title, '', True) // + .ExecuteAsBool; + Logger.Leave(Self, 'SetStickerSetTitle'); +end; + +function TInjectTelegramBot.uploadStickerFile( + const UserId: Int64; + const sticker: TtdFileToSend; + const sticker_format: TtdStickerFormat): ItdFile; +begin + Logger.Enter(Self, 'uploadStickerFile'); + Result := TtdFile.Create(GetRequest.SetMethod('uploadStickerFile') // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('sticker', sticker, nil, True) // + .AddParameter('sticker_format', sticker_format.ToString, '', True) // + .Execute); + Logger.Leave(Self, 'uploadStickerFile'); +end; +{$ENDREGION} + +{$REGION 'Inline mode'} +function TInjectTelegramBot.AnswerInlineQuery( + const InlineQueryId: string; + const Results: TArray; + const CacheTime: Int64; + const IsPersonal: Boolean; + const NextOffset: string; + const Button: TtdInlineQueryResultsButton): Boolean; +begin + Logger.Enter(Self, 'AnswerInlineQuery'); + Result := GetRequest.SetMethod('answerInlineQuery') // + .AddParameter('inline_query_id', InlineQueryId, '', True) // + .AddParameter('results', TJsonUtils.ArrayToJString(Results), + '[]', True) // + .AddParameter('cache_time', CacheTime, 0, False) // + .AddParameter('is_personal', IsPersonal, False, False) // + .AddParameter('next_offset', NextOffset, '', False) // + .AddParameter('button', Button, nil, False) // + .ExecuteAsBool; + Logger.Leave(Self, 'AnswerInlineQuery'); +end; +{$ENDREGION} + +{$REGION 'Payments'} +function TInjectTelegramBot.SendInvoice( + const ChatId: Int64; + const Title: string; + const Description: string; + const Payload: string; + const ProviderToken: string; + const StartParameter: string; + const Currency: string; + const Prices: TArray; + const MaxTipAmount: Integer; + const SuggestedTipAmounts: TArray; + const ProviderData: string; + const PhotoUrl: string; + const PhotoSize: Int64; + const PhotoWidth: Int64; + const PhotoHeight: Int64; + const NeedName: Boolean; + const NeedPhoneNumber: Boolean; + const NeedEmail: Boolean; + const NeedShippingAddress: Boolean; + const SendPhoneNumberToProvider: Boolean; + const SendRmailToProvider: Boolean; + const IsFlexible: Boolean; + const DisableNotification: Boolean; + const ReplyToMessageId: Int64; ReplyMarkup: + IReplyMarkup; const ProtectContent: Boolean): ItdMessage; +Var + LabeledPriceJson, + SuggestedTipAmountsJson : string; +begin + LabeledPriceJson := TJsonUtils.ArrayToJString(Prices); + SuggestedTipAmountsJson := TJsonUtils.ArrayIntToJString(SuggestedTipAmounts); + Logger.Enter(Self, 'SendInvoice'); + Result := TtdMessage.Create(GetRequest.SetMethod('sendInvoice') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('title', Title, '', True) // + .AddParameter('description', Description, '', True) // + .AddParameter('payload', Payload, '', True) // + .AddParameter('provider_token', ProviderToken, '', True) // + .AddParameter('start_parameter', StartParameter, '', False) //now is Optional in API 5.2 + .AddParameter('currency', Currency, '', True) // + .AddParameter('prices', LabeledPriceJson, '[{"label":"null","amount":"0"}]', True) // + .AddParameter('max_tip_amount', MaxTipAmount, 0, False) // + .AddParameter('suggested_tip_amounts', SuggestedTipAmountsJson, '[]', False) // + .AddParameter('provider_data', ProviderData, '', False) // + .AddParameter('photo_url', PhotoUrl, '', False) // + .AddParameter('photo_size', PhotoSize, 0, False) // + .AddParameter('photo_width', PhotoWidth, 0, False) // + .AddParameter('photo_height', PhotoHeight, 0, False) // + .AddParameter('need_name', NeedName, False, False) // + .AddParameter('need_phone_number', NeedPhoneNumber, False, False) // + .AddParameter('need_email', NeedEmail, False, False) // + .AddParameter('need_shipping_address', NeedShippingAddress, False, False) // + .AddParameter('send_phone_number_to_provider', SendPhoneNumberToProvider, False, False) // + .AddParameter('send_email_to_provider', SendRmailToProvider, False, False) // + .AddParameter('is_flexible', IsFlexible, False, False) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendInvoice'); +end; +function TInjectTelegramBot.AnswerPreCheckoutQuery( + const PreCheckoutQueryId: string; + const OK: Boolean; + const ErrorMessage: string): Boolean; +var + DefaultBool : Boolean; +begin + DefaultBool := Not OK; + Logger.Enter(Self, 'AnswerPreCheckoutQuery'); + Result := GetRequest.SetMethod('answerPreCheckoutQuery') // + .AddParameter('pre_checkout_query_id', PreCheckoutQueryId, '0', True) // + .AddParameter('ok', Ok , DefaultBool, True) // + .AddParameter('error_message', ErrorMessage, 'null', False) // + .ExecuteAsBool; + Logger.Leave(Self, 'AnswerPreCheckoutQuery'); +end; +function TInjectTelegramBot.AnswerPreCheckoutQueryBad(const PreCheckoutQueryId, + ErrorMessage: string): Boolean; +begin + Logger.Enter(Self, 'AnswerPreCheckoutQueryBad'); + Result := GetRequest.SetMethod('answerPreCheckoutQuery') // + .AddParameter('pre_checkout_query_id', PreCheckoutQueryId, 0, True) // + .AddParameter('ok', False, True, True) // + .AddParameter('error_message', ErrorMessage, '', False) // + .ExecuteAsBool; + Logger.Leave(Self, 'AnswerPreCheckoutQueryBad'); +end; +function TInjectTelegramBot.AnswerPreCheckoutQueryGood(const PreCheckoutQueryId: + string): Boolean; +begin + Logger.Enter(Self, 'AnswerPreCheckoutQueryGood'); + Result := GetRequest.SetMethod('answerPreCheckoutQuery') // + .AddParameter('pre_checkout_query_id', PreCheckoutQueryId, 0, True) // + .AddParameter('ok',True, False, True) // + .ExecuteAsBool; + Logger.Leave(Self, 'AnswerPreCheckoutQueryGood'); +end; +function TInjectTelegramBot.AnswerShippingQueryBad(const ShippingQueryId, ErrorMessage: + string): Boolean; +begin + Logger.Enter(Self, 'AnswerShippingQueryBad'); + Result := GetRequest.SetMethod('answerShippingQuery') // + .AddParameter('Shipping_query_id', ShippingQueryId, 0, True) // + .AddParameter('ok',False, True, False) // + .AddParameter('error_message', ErrorMessage, '', False) // + .ExecuteAsBool; + Logger.Leave(Self, 'AnswerShippingQueryBad'); +end; +function TInjectTelegramBot.AnswerShippingQueryGood(const ShippingQueryId: string; + const ShippingOptions: TArray): Boolean; +begin + Logger.Enter(Self, 'AnswerShippingQueryGood'); + Result := GetRequest.SetMethod('answerShippingQuery') // + .AddParameter('Shipping_query_id', ShippingQueryId, 0, True) // + .AddParameter('ok', True, False, False) // + .AddParameter('Shipping_options', TJsonUtils.ArrayToJString< + TtdShippingOption>(ShippingOptions), '[]', True) // + .ExecuteAsBool; + Logger.Leave(Self, 'AnswerShippingQueryGood'); +end; +{$ENDREGION} + +{$REGION 'Games'} +function TInjectTelegramBot.GetGameHighScores(const UserId: Int64; const + InlineMessageId: string): TArray; +begin + Logger.Enter(Self, 'GetGameHighScores'); + Result := GetArrayFromMethod(TtdGameHighScore, GetRequest.SetMethod + ('getGameHighScores') // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('inline_message_id', InlineMessageId, 0, True) // + .Execute); + Logger.Leave(Self, 'GetGameHighScores'); +end; +function TInjectTelegramBot.GetGameHighScores(const UserId, ChatId, MessageId: Int64): + TArray; +begin + Logger.Enter(Self, 'GetGameHighScores'); + Result := GetArrayFromMethod(TtdGameHighScore, GetRequest.SetMethod + ('getGameHighScores') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('message_id', MessageId, 0, True) // + .Execute); + Logger.Leave(Self, 'GetGameHighScores'); +end; +function TInjectTelegramBot.SendGame(const ChatId: Int64; const GameShortName: string; + const DisableNotification: Boolean; const ReplyToMessageId: Int64; ReplyMarkup: + IReplyMarkup; const ProtectContent: Boolean): ItdMessage; +begin + Logger.Enter(Self, 'SendGame'); + Result := TtdMessage.Create(GetRequest.SetMethod('sendGame') // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('game_short_name', GameShortName, '', True) // + .AddParameter('disable_notification', DisableNotification, False, False) // + .AddParameter('reply_to_message_id', ReplyToMessageId, 0, False) // + .AddParameter('protect_content ', ProtectContent, False, False) // + .AddParameter('reply_markup', TInterfacedObject(ReplyMarkup), nil, False) // + .Execute); + Logger.Leave(Self, 'SendGame'); +end; +function TInjectTelegramBot.SetGameScore(const UserId, Score: Int64; const + InlineMessageId: string; const Force, DisableEditMessage: Boolean): ItdMessage; +begin + Logger.Enter(Self, 'SetGameScore'); + Result := TtdMessage.Create(GetRequest.SetMethod('setGameScore') // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('score', Score, 0, True) // + .AddParameter('force', Force, False, False) // + .AddParameter('disable_edit_message', DisableEditMessage, False, False) // + .AddParameter('inline_message_id', InlineMessageId, 0, True) // + .Execute); + Logger.Leave(Self, 'SetGameScore'); +end; +function TInjectTelegramBot.SetGameScore(const UserId, Score, ChatId, MessageId: Int64; + const Force, DisableEditMessage: Boolean): ItdMessage; +begin + Logger.Enter(Self, 'SetGameScore'); + Result := TtdMessage.Create(GetRequest.SetMethod('setGameScore') // + .AddParameter('user_id', UserId, 0, True) // + .AddParameter('score', Score, 0, True) // + .AddParameter('force', Force, False, False) // + .AddParameter('disable_edit_message', DisableEditMessage, False, False) // + .AddParameter('chat_id', ChatId, 0, True) // + .AddParameter('message_id', MessageId, 0, True) // + .Execute); + Logger.Leave(Self, 'SetGameScore'); +end; +{$ENDREGION} + +{ TTelegramBotHelper } + +function TTelegramBotHelper.IsValidToken: Boolean; +const + TOKEN_CORRECT = '[-+]?[0-9]{10}\:?[\w\d-_]{35}'; //'/\d*:[\w\d-_]{35}/'; +begin + Result := TRegEx.IsMatch(Token, TOKEN_CORRECT, [roIgnoreCase]); +end; +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Bot.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Bot.pas new file mode 100644 index 0000000..ff72f8e --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Bot.pas @@ -0,0 +1,726 @@ +unit TinjectTelegram.Bot; +interface +uses + System.Classes, + Winapi.Windows, + TInjectTelegram.Types, + TInjectTelegram.Types.Enums, + TInjectTelegram.Types.Passport, + TInjectTelegram.Types.InlineQueryResults, + TInjectTelegram.Types.ReplyMarkups, + TInjectTelegram.Types.Impl, + TInjectTelegram.Logger, + CrossUrl.HttpClient; +type + {IInjectTelegramBot} + IInjectTelegramBot = interface + ['{12FA5CF8-3723-4ED1-BC1F-F1643B4FA361}'] + // private + function GetToken: string; + procedure SetToken(const Value: string); + function GetLogger: ILogger; + procedure SetLogger(const Value: ILogger); + function GetHttpCore: IcuHttpClient; + procedure SetHttpCore(const Value: IcuHttpClient); + // public +{$REGION 'Getting updates'} + function GetUpdates( // + const Offset: Int64 = 0; // + const Limit: Int64 = 100; // + const Timeout: Int64 = 0; // + const AllowedUpdates: TAllowedUpdates = UPDATES_ALLOWED_ALL) + : TArray; overload; + function GetUpdates(const JSON: string): TArray; overload; + function SetWebhook( // + const Url: string; // + const Certificate: TtdFileToSend = nil; // + const IpAddress: String = ''; + const MaxConnections: Int64 = 40; // + const AllowedUpdates: TAllowedUpdates = UPDATES_ALLOWED_ALL; + const DropPendingUpdates: Boolean = False; + const SecretToken: string = ''): Boolean; + function DeleteWebhook( + const DropPendingUpdates: Boolean = False): Boolean; + function GetWebhookInfo: ItdWebhookInfo; +{$ENDREGION} + +{$REGION 'Basic methods'} + function GetMe: ItdUser; + function SendMessage( // + const ChatId: TtdUserLink; // + const Text: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableWebPagePreview: Boolean = False; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + function ForwardMessage( // + const ChatId, FromChatId: TtdUserLink; // + const MessageId: Int64; // + const DisableNotification: Boolean = False; + const ProtectContent: Boolean = False): ItdMessage; + function SendPhoto( // + const ChatId: TtdUserLink; // + const Photo: TtdFileToSend; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []; + const HasSpoiler: boolean = False): ItdMessage; + function SendAudio( // + const ChatId: TtdUserLink; // + const Audio: TtdFileToSend; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const Duration: Int64 = 0; // + const Performer: string = ''; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []): ItdMessage; + function SendDocument( // + const ChatId: TtdUserLink; // + const Document: TtdFileToSend; // + const Thumb: TtdFileToSend; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableContentTypeDetection: Boolean = False; + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []): ItdMessage; + function SendVideo( // + const ChatId: TtdUserLink; // + const Video: TtdFileToSend; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const SupportsStreaming: Boolean = True; // + const Duration: Int64 = 0; // + const Width: Int64 = 0; // + const Height: Int64 = 0; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []; + const HasSpoiler: boolean = False): ItdMessage; + function SendAnimation( // + const ChatId: TtdUserLink; // + const Animation: TtdFileToSend; // + const Duration: Int64 = 0; // + const Width: Int64 = 0; // + const Height: Int64 = 0; // + const Thumb: TtdFileToSend = nil; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []; + const HasSpoiler: boolean = False): ItdMessage; + function SendVoice( // + const ChatId: TtdUserLink; // + const Voice: TtdFileToSend; // + const Caption: string = ''; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const Duration: Int64 = 0; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const CaptionEntities: TArray = []): ItdMessage; + function SendVideoNote( // + const ChatId: TtdUserLink; // + const VideoNote: TtdFileToSend; // + const Duration: Int64 = 0; // + const Length: Int64 = 0; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + function SendLocation( // + const ChatId: TtdUserLink; // + const Location: ItdLocation; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + function SendVenue( // + const ChatId: TtdUserLink; // + const Venue: ItdVenue; // + const Location: ItdLocation; //Add Para Testes + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + function SendVenue2( // + const ChatId: TtdUserLink; // + const Venue: ItdVenue; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + function SendContact( // + const ChatId: TtdUserLink; // + const Contact: ItdContact; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + function SendPoll( // + const ChatId: TtdUserLink; // + const Question: String; //Poll question, 1-255 characters + const Options: Array of String; // + const Is_Anonymous: Boolean = True; // + const &type: TtdQuizType = TtdQuizType.qtPadrao;//String = '"regular"'; //regular ou quiz + const Allows_Multiple_Answers: Boolean = False; // + const Correct_Option_Id: Integer = 0; + const Explanation: String = ''; // + const ExplanationEntities: TArray = []; // + const Open_period : Integer = 0; // + const Close_date: Integer= 0; // + const Is_Closed: Boolean = False; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + function SendDice( // + const ChatId: TtdUserLink; // + const Emoji: TtdEmojiType = TtdEmojiType.etDado;// + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): ItdMessage; + function SendChatAction( // + const ChatId: TtdUserLink; // + const Action: TtdSendChatAction; + const MessageThreadId: int64 = 0): Boolean; + function sendMediaGroup( // + const ChatId: TtdUserLink; // + const AMedia: TArray; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; + const AllowSendingWithoutReply: Boolean = False; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0): TArray; + function GetFile(const FileId: string): ItdFile; + function AnswerCallbackQuery( // + const CallbackQueryId: string; // + const Text: string = ''; // + const ShowAlert: Boolean = False; // + const Url: string = ''; // + const CacheTime: Int64 = 0): Boolean; + +{$ENDREGION} + +{$REGION 'ForumTopic'} + function getForumTopicIconStickers(): TArray; + + function createForumTopic( + const chat_id: TtdUserLink; + const name: string = ''; + const icon_color: integer = 0; + const icon_custom_emoji_id: string = ''): ItdForumTopic; + + function editForumTopic( + const chat_id: TtdUserLink; + const message_thread_id: int64 = 0; + const name: string = ''; + const icon_custom_emoji_id: string = ''): Boolean; + + function closeForumTopic( + const chat_id: TtdUserLink; + const message_thread_id: int64 = 0): Boolean; + + function reopenForumTopic( + const chat_id: TtdUserLink; + const message_thread_id: int64 = 0): Boolean; + + function deleteForumTopic( + const chat_id: TtdUserLink; + const message_thread_id: int64 = 0): Boolean; + + function unpinAllForumTopicMessages( + const chat_id: TtdUserLink; + const message_thread_id: int64 = 0): Boolean; + + function editGeneralForumTopic( + const chat_id: TtdUserLink; + const name: string = ''): Boolean; + + function closeGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; + + function reopenGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; + + function hideGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; + + function unhideGeneralForumTopic( + const chat_id: TtdUserLink): Boolean; + +{$ENDREGION 'ForumTopic'} + +{$REGION 'BotCommands'} + function SetMyCommands( + const Command: TArray; + //const scope: ItdBotCommandScope = Nil; + const scope: TtdBotCommandScopeType = TtdBotCommandScopeType.BotCommandScopeDefault; + const language_code: string = '' + ): Boolean; + function GetMyCommands( + //const scope: ItdBotCommandScope = Nil; + const scope: TtdBotCommandScopeType = TtdBotCommandScopeType.BotCommandScopeDefault; + const language_code: string = '' + ): TArray; + function DeleteMyCommands( + //const scope: ItdBotCommandScope = Nil; + const scope: TtdBotCommandScopeType = TtdBotCommandScopeType.BotCommandScopeDefault; + const language_code: string = '' + ): Boolean; + function LogOut: Boolean; + function Close: Boolean; +{$ENDREGION 'BotCommands'} + +{$REGION 'BotName'} + function SetMyName( + const name: string = ''; + const language_code: string = '' + ): Boolean; + + function GetMyName( + const language_code: string = '' + ): ItdBotName; +{$ENDREGION 'BotName'} + +{$REGION 'BotDescription'} + function setMyDescription( + const description: string = ''; //0-512 characters + const language_code: string = '' //two-letter ISO 639-1 language code + ): Boolean; + function getMyDescription( + const language_code: string = '' //two-letter ISO 639-1 language code + ): ItdBotDescription; + function setMyShortDescription( + const short_description: string = ''; //0-120 characters + const language_code: string = '' //two-letter ISO 639-1 language code + ): Boolean; + function getMyShortDescription( + const language_code: string = '' //two-letter ISO 639-1 language code + ): ItdBotShortDescription; +{$ENDREGION 'BotDescription'} + +{$REGION 'Updating messages'} + function EditMessageText( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + const Text: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableWebPagePreview: Boolean = False; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + function EditMessageText( // + const InlineMessageId: string; // + const Text: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const DisableWebPagePreview: Boolean = False; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + function EditMessageCaption( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + const Caption: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + function EditMessageCaption( // + const InlineMessageId: string; // + const Caption: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + + function editMessageMedia( + const ChatId: TtdUserLink; // + const MessageId: Int64; // + const Media: TtdInputMedia; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + + function editMessageMedia( + const InlineMessageId: string; // + const Media: TtdInputMedia; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + + function editMessageLiveLocation( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + const Location: ItdLocation; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + function editMessageLiveLocation( // + const InlineMessageId: string; // + const Location: ItdLocation; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + function stopMessageLiveLocation( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + function stopMessageLiveLocation( // + const InlineMessageId: string; // + ReplyMarkup: IReplyMarkup = nil): Boolean; overload; + function EditMessageReplyMarkup( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + function EditMessageReplyMarkup( // + const InlineMessageId: string; // + ReplyMarkup: IReplyMarkup = nil): ItdMessage; overload; + function DeleteMessage( // + const ChatId: TtdUserLink; // + const MessageId: Int64): Boolean; +{$ENDREGION} + +{$REGION 'ChatInviteLink'} + function createChatInviteLink( // + const ChatId: TtdUserLink; // + const name: String; //Invite link name; 0-32 characters + const expire_date: TDateTime; + const member_limit: Integer = 0; + const creates_join_request: boolean = false): ItdChatInviteLink; + function editChatInviteLink( // + const ChatId: TtdUserLink; // + const expire_date: TDateTime; + const invite_link: String = ''; + const name: String = ''; //Invite link name; 0-32 characters + const member_limit: Integer = 0; + const creates_join_request: boolean = false): ItdChatInviteLink; + function revokeChatInviteLink( // + const ChatId: TtdUserLink; // + const invite_link: String = ''): ItdChatInviteLink; + function approveChatJoinRequest( + const ChatId: TtdUserLink; // + const UserId: TtdUserLink): Boolean; + function declineChatJoinRequest( + const ChatId: TtdUserLink; // + const UserId: TtdUserLink): Boolean; +{$ENDREGION 'ChatInviteLink'} + +{$REGION 'Inline mode'} + function AnswerInlineQuery( // + const InlineQueryId: string; // + const Results: TArray; // + const CacheTime: Int64 = 300; // + const IsPersonal: Boolean = False; // + const NextOffset: string = ''; // + const Button: TtdInlineQueryResultsButton = nil): Boolean; +{$ENDREGION} + +{$REGION 'Payments'} + function SendInvoice( // + const ChatId: Int64; // + const title: string; // + const Description: string; // + const Payload: string; // + const ProviderToken: string; // + const StartParameter: string; // + const Currency: string; // + const Prices: TArray; // + const MaxTipAmount: Integer = 0; // + const SuggestedTipAmounts: TArray = []; // + const ProviderData: string = ''; // + const PhotoUrl: string = ''; // + const PhotoSize: Int64 = 0; // + const PhotoWidth: Int64 = 0; // + const PhotoHeight: Int64 = 0; // + const NeedName: Boolean = False; // + const NeedPhoneNumber: Boolean = False; // + const NeedEmail: Boolean = False; // + const NeedShippingAddress: Boolean = False; // + const SendPhoneNumberToProvider: Boolean = False; // + const SendRmailToProvider: Boolean = False; // + const IsFlexible: Boolean = False; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False): ItdMessage; + function AnswerShippingQueryGood( // + const ShippingQueryId: string; // + const ShippingOptions: TArray): Boolean; + function AnswerShippingQueryBad( // + const ShippingQueryId: string; // + const ErrorMessage: string): Boolean; + function AnswerPreCheckoutQueryGood( // + const PreCheckoutQueryId: string): Boolean; + function AnswerPreCheckoutQueryBad( // + const PreCheckoutQueryId: string; // + const ErrorMessage: string): Boolean; + function AnswerPreCheckoutQuery( // + const PreCheckoutQueryId: string; // + const OK: Boolean; + const ErrorMessage: string): Boolean; + function CreateInvoiceLink( + const Title: string; // + const Description: string; // + const Payload: string; // + const ProviderToken: string; // + const Currency: string; // + const Prices: TArray; // + const MaxTipAmount: Integer = 0; // + const SuggestedTipAmounts: TArray = []; // + const ProviderData: string = ''; // + const PhotoUrl: string = ''; // + const PhotoSize: Int64 = 0; // + const PhotoWidth: Int64 = 0; // + const PhotoHeight: Int64 = 0; // + const NeedName: Boolean = False; // + const NeedPhoneNumber: Boolean = False; // + const NeedEmail: Boolean = False; // + const NeedShippingAddress: Boolean = False; // + const SendPhoneNumberToProvider: Boolean = False; // + const SendRmailToProvider: Boolean = False; // + const IsFlexible: Boolean = False // + ): string; +{$ENDREGION} + +{$REGION 'Telegram Passport'} + function SetPassportDataErrors( // + const UserId: Int64; // + const Errors: TArray): Boolean; +{$ENDREGION 'Telegram Passport'} + +{$REGION 'Games'} + function SendGame( // + const ChatId: Int64; // + const GameShortName: string; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False): ItdMessage; + function SetGameScore( // + const UserId: Int64; // + const Score: Int64; // + const InlineMessageId: string; // + const Force: Boolean = False; // + const DisableEditMessage: Boolean = False): ItdMessage; overload; + function SetGameScore( // + const UserId: Int64; // + const Score: Int64; // + const ChatId: Int64; // + const MessageId: Int64; // + const Force: Boolean = False; // + const DisableEditMessage: Boolean = False): ItdMessage; overload; + function GetGameHighScores( // + const UserId: Int64; // + const InlineMessageId: string = ''): TArray; overload; + function GetGameHighScores( // + const UserId: Int64; // + const ChatId: Int64 = 0; // + const MessageId: Int64 = 0): TArray; overload; +{$ENDREGION} + +{$REGION 'Manage groups and channels'} + function DeleteChatPhoto(const ChatId: TtdUserLink): Boolean; + function ExportChatInviteLink(const ChatId: TtdUserLink): string; + function PinChatMessage( // + const ChatId: TtdUserLink; // + const MessageId: Int64; // + const DisableNotification: Boolean = False): Boolean; + function SetChatDescription(const ChatId: TtdUserLink; + const Description: string): Boolean; + function SetChatPhoto(const ChatId: TtdUserLink; + const Photo: TtdFileToSend): Boolean; + function SetChatTitle(const ChatId: TtdUserLink; + const title: string): Boolean; + function UnPinChatMessage( + const ChatId: TtdUserLink; // + const MessageId: Int64 ): Boolean; + function UnPinAllChatMessages(const ChatId: TtdUserLink): Boolean; + function CopyMessage( // + const ChatId: TtdUserLink; // + const FromChatId: TtdUserLink; // + const MessageId: Int64;// + const Caption: string; // + const ParseMode: TtdParseMode = TtdParseMode.Default; // + const CaptionEntities: TArray = []; + const DisableWebPagePreview: Boolean = False; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + const AllowSendingWithoutReply: Boolean = False; + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False): Int64; + function banChatSenderChat(const ChatId: TtdUserLink; // + const SenderChatId: Int64): boolean; + function unbanChatSenderChat(const ChatId: TtdUserLink; // + const SenderChatId: Int64): boolean; + function banChatMember( // + const ChatId: TtdUserLink; // + const UserId: Int64; // + const UntilDate: TDateTime = 0; + const RevokeMessages: Boolean = False): Boolean; + function UnbanChatMember( // + const ChatId: TtdUserLink; // + const UserId: Int64; + const OnlyIfBanned: Boolean): Boolean; + function LeaveChat(const ChatId: TtdUserLink): Boolean; + function GetChat(const ChatId: TtdUserLink): ItdChat; + function GetChatAdministrators(const ChatId: TtdUserLink) + : TArray; + function GetChatMemberCount(const ChatId: TtdUserLink): Int64; + function GetChatMember( // + const ChatId: TtdUserLink; // + const UserId: Int64): ItdChatMember; + function GetUserProfilePhotos( // + const ChatId: TtdUserLink; // + const Offset: Int64; // + const Limit: Int64 = 100): ItdUserProfilePhotos; +{$ENDREGION} + +{$REGION 'Manage users and admins'} + function RestrictChatMember( // + const ChatId: TtdUserLink; // + const UserId: Int64; // + const UntilDate: TDateTime = 0; // + const UseIndependentChatPermissions: Boolean = False; + const CanSendMessages: Boolean = False; // + const CanSendMediaMessages: Boolean = False; // + const CanSendOtherMessages: Boolean = False; // + const CanAddWebPagePreviews: Boolean = False): Boolean; + function PromoteChatMember( // + const ChatId: TtdUserLink; // + const UserId: Int64; // + const IsAnonymous: Boolean = False; + const CanManageChat: Boolean = False; + const CanPostMessages: Boolean = False; // + const CanEditMessages: Boolean = False; // + const CanDeleteMessages: Boolean = False; // + const CanManageVideoChats: Boolean = False; + const CanRestrictMembers: Boolean = False; // + const CanPromoteMembers: Boolean = False; + const CanChangeInfo: Boolean = False; // + const CanInviteUsers: Boolean = False; // + const CanPinMessages: Boolean = False): Boolean; + function setChatPermissions( // + const ChatId: TtdUserLink; // + const Permissions: ItdChatPermissions;// + const UseIndependentChatPermissions: Boolean = False):Boolean; +{$ENDREGION} + +{$REGION 'Strickers'} + function SendSticker( // + const ChatId: TtdUserLink; // + const Sticker: TtdFileToSend; // + const DisableNotification: Boolean = False; // + const ReplyToMessageId: Int64 = 0; // + ReplyMarkup: IReplyMarkup = nil; + const ProtectContent: Boolean = False; + const MessageThreadId: int64 = 0; + const AllowSendingWithoutReply: Boolean = False; + const emoji: string = ''): ItdMessage; + function getStickerSet(const Name: string): ItdStickerSet; + function uploadStickerFile( + const UserId: Int64; + const sticker: TtdFileToSend; + const sticker_format: TtdStickerFormat): ItdFile; + function createNewStickerSet( // + const UserId: Int64; // + const Name, title: string; // + const stickers: TArray; + const sticker_format: TtdStickerFormat; + const Sticker_type: TtdStickerType; // + const needs_repainting: Boolean = false): Boolean; + function addStickerToSet( // + const UserId: Int64; // + const Name: string; // + const sticker: TtdFileToSend): Boolean; + function setStickerPositionInSet(const Sticker: string; + const Position: Int64): Boolean; + function deleteStickerFromSet(const Sticker: string): Boolean; + function setChatStickerSet(const ChatId: TtdUserLink; + const StickerSetName: string): Boolean; + function deleteChatStickerSet(const ChatId: TtdUserLink): Boolean; + function setStickerSetThumbnail( + const Name: string; + const UserId: Int64; + const Thumbnail: string): Boolean; + function getCustomEmojiStickers( + const custom_emoji_ids: TArray): TArray; + + function setStickerMaskPosition( + const sticker: string; + const mask_position: ItdMaskPosition): Boolean; + + function setStickerKeywords( + const sticker: string; + const keywords: TArray): Boolean; + + function setStickerEmojiList( + const sticker: string; + const emoji_list: TArray): Boolean; + + function setStickerSetTitle( + const name: string; //requerido + const title: string) : Boolean; //requerido + + function deleteStickerSet( + const name: string) : Boolean; //requerido + + function setCustomEmojiStickerSetThumbnail( + const name: string; + const custom_emoji_id: string): Boolean; +{$ENDREGION} + +{$REGION 'WebApp'} + function answerWebAppQuery( // + const web_app_query_id: string; + const AResult: TtdInlineQueryResult): ItdSentWebAppMessage; + function setChatMenuButton( // + const chat_id: TtdUserLink; + const url: String = ''; Text: String = ''; + const ButtonType: TtdMenuButtonType = TtdMenuButtonType.MenuButtonDefault): Boolean; + function getChatMenuButton( // + const chat_id: TtdUserLink): ItdMenuButton; + function setMyDefaultAdministratorRights( // + const rights: TtdChatAdministratorRights; + const for_channels: Boolean): Boolean; + function getMyDefaultAdministratorRights( // + const for_channels: Boolean): ItdChatAdministratorRights; +{$ENDREGION} + + property Token: string read GetToken write SetToken; + property Logger: ILogger read GetLogger write SetLogger; + property HttpCore: IcuHttpClient read GetHttpCore write SetHttpCore; + end; +Implementation +End. + diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Core.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Core.pas new file mode 100644 index 0000000..6fe8a3e --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Core.pas @@ -0,0 +1,411 @@ +unit TinjectTelegram.Core; +interface +uses + System.Rtti, + System.TypInfo, + System.SysUtils, + System.Generics.Collections, + System.Classes, + TinjectTelegram.Base, + TinjectTelegram.Types, + TinjectTelegram.Helpers, + CrossUrl.HttpClient; +type + ItdRequestAPI = interface + ['{3DC5A653-F52D-4A31-87AD-0C008AFA7111}'] + // private + function GetOnError: TProc; + procedure SetOnError(const Value: TProc); + function GetOnSend: TProc; + procedure SetOnSend(const Value: TProc); + function GetOnReceive: TProc; + procedure SetOnReceive(const Value: TProc); + function GetDataExtractor: TFunc; + procedure SetDataExtractor(const Value: TFunc); + function GetFormData: IcuMultipartFormData; + function GetHttpCore: IcuHttpClient; + procedure SetHttpCore(const AHttpCore: IcuHttpClient); + function GetUrlAPI: string; + procedure SetUrlAPI(const AValue: string); + // public + function SetToken(const AToken: string): ItdRequestAPI; + function SetMethod(const AMethod: string): ItdRequestAPI; + // + function AddParameter(const AKey: string; const AValue, ADefaultValue: + string; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; const AValue, ADefaultValue: + Int64{Integer}; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; const AValue, ADefaultValue: + TDateTime; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; AValue, ADefaultValue: + TtdFileToSend; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; const AValue, ADefaultValue: + TtdUserLink; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; AValue, ADefaultValue: TObject; + const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; const AValue, ADefaultValue: + Boolean; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; const AValue, ADefaultValue: + Single; const ARequired: Boolean = False): ItdRequestAPI; overload; + // + function AddRawField(const AField, AValue: string): ItdRequestAPI; + function AddRawFile(const AFieldName, AFileName: string): ItdRequestAPI; + function AddRawStream(const AFieldName: string; Data: TStream; const + AFileName: string): ItdRequestAPI; + // + function ClearParameters: ItdRequestAPI; + function Execute: string; + function ExecuteAsBool: Boolean; + function ExecuteAndReadValue: string; + // props + property DataExtractor: TFunc read GetDataExtractor write + SetDataExtractor; + property MultipartFormData: IcuMultipartFormData read GetFormData; + property HttpCore: IcuHttpClient read GetHttpCore write SetHttpCore; + property UrlAPI: string read GetUrlAPI write SetUrlAPI; + // events + property OnError: TProc read GetOnError write SetOnError; + property OnSend: TProc read GetOnSend write SetOnSend; + property OnReceive: TProc read GetOnReceive write SetOnReceive; + end; + TtdCoreApiBase = class(TInterfacedObject, ItdRequestAPI) + private + FGetOnSend: TProc; + FDataExtractor: TFunc; + FOnReceive: TProc; + FToken: string; + FMethod: string; + FOnError: TProc; + FFormData: IcuMultipartFormData; + FHttpCore: IcuHttpClient; + FHaveFields: Boolean; + FUrlAPI: string; + private + function GetOnError: TProc; + procedure SetOnError(const Value: TProc); + function GetOnSend: TProc; + procedure SetOnSend(const Value: TProc); + function GetOnReceive: TProc; + procedure SetOnReceive(const Value: TProc); + function GetDataExtractor: TFunc; + procedure SetDataExtractor(const Value: TFunc); + function GetUrl: string; + function GetFormData: IcuMultipartFormData; + procedure SetHttpCore(const Value: IcuHttpClient); + function GetHttpCore: IcuHttpClient; + function GetUrlAPI: string; + procedure SetUrlAPI(const AValue: string); + protected + procedure DoHaveException(const AException: Exception); + function StreamToString(Stream: TStream): string; + public + function SetToken(const AToken: string): ItdRequestAPI; + function SetMethod(const AMethod: string): ItdRequestAPI; + function AddParameter(const AKey: string; const AValue, ADefaultValue: + string; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; const AValue, ADefaultValue: + Int64{Integer}; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; const AValue, ADefaultValue: + TDateTime; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; AValue, ADefaultValue: + TtdFileToSend; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; const AValue, ADefaultValue: + TtdUserLink; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; AValue, ADefaultValue: TObject; + const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; const AValue, ADefaultValue: + Boolean; const ARequired: Boolean = False): ItdRequestAPI; overload; + function AddParameter(const AKey: string; const AValue, ADefaultValue: + Single; const ARequired: Boolean = False): ItdRequestAPI; overload; + // + function AddRawField(const AField, AValue: string): ItdRequestAPI; + function AddRawFile(const AFieldName, AFileName: string): ItdRequestAPI; + function AddRawStream(const AFieldName: string; Data: TStream; const + AFileName: string): ItdRequestAPI; + function HaveFields: Boolean; + function ClearParameters: ItdRequestAPI; + function Execute: string; virtual; abstract; + function ExecuteAsBool: Boolean; + function ExecuteAndReadValue: string; + constructor Create; + // props + property DataExtractor: TFunc read GetDataExtractor write + SetDataExtractor; + property Url: string read GetUrl; + property HttpCore: IcuHttpClient read FHttpCore write SetHttpCore; + property UrlAPI: string read GetUrlAPI write SetUrlAPI; + // events + property OnError: TProc read GetOnError write SetOnError; + property OnSend: TProc read GetOnSend write SetOnSend; + property OnReceive: TProc read GetOnReceive write SetOnReceive; + end; + TtdCoreApi = class(TtdCoreApiBase, ItdRequestAPI) + private + protected + function DoPost: string; + function DoGet: string; + public + function Execute: string; override; + end; +implementation +uses + REST.Json, + System.DateUtils, + System.Json, + TInjectTelegram.Utils.Json, + TInjectTelegram.Types.ReplyMarkups; +{ TtdCoreApiBase } + +{$REGION 'TtdCoreApiBase.AddParameter'} +function TtdCoreApiBase.AddParameter(const AKey, AValue, ADefaultValue: string; + const ARequired: Boolean): ItdRequestAPI; +begin + if ARequired and (AValue.Equals(ADefaultValue) or AValue.IsEmpty) then + DoHaveException(Exception.Create('Mandatory data not assigned')); + if AValue <> ADefaultValue then + AddRawField(AKey, AValue); + Result := Self; +end; +function TtdCoreApiBase.AddParameter(const AKey: string; const AValue, + ADefaultValue: Int64{Integer}; const ARequired: Boolean): ItdRequestAPI; +begin + Result := AddParameter(AKey, AValue.ToString, ADefaultValue.ToString, ARequired); +end; +function TtdCoreApiBase.AddParameter(const AKey: string; const AValue, + ADefaultValue: TDateTime; const ARequired: Boolean): ItdRequestAPI; +begin + Result := AddParameter(AKey, DateTimeToUnix(AValue, False).ToString, + DateTimeToUnix(ADefaultValue, False).ToString, ARequired); +end; +function TtdCoreApiBase.AddParameter(const AKey: string; AValue, ADefaultValue: + TtdFileToSend; const ARequired: Boolean): ItdRequestAPI; +begin + if ARequired and (AValue.Equals(ADefaultValue) or AValue.IsEmpty) then + DoHaveException(Exception.Create('Mandatory data not assigned')); + Result := Self; + case AValue.Tag of + TtdFileToSendTag.FromStream: + AddRawStream(AKey, AValue.Content, AValue.Data); + TtdFileToSendTag.FromFile: + AddRawFile(AKey, AValue.Data); + TtdFileToSendTag.ID, TtdFileToSendTag.FromURL: + Result := AddParameter(AKey, AValue.Data, '', ARequired); + else + raise Exception.Create('Unable to convert TtdFileToSend: Unknown prototype tag'); + end; + if Assigned(AValue) then + FreeAndNil(AValue); + if Assigned(ADefaultValue) then + FreeAndNil(ADefaultValue); +end; +function TtdCoreApiBase.AddParameter(const AKey: string; const AValue, + ADefaultValue: TtdUserLink; const ARequired: Boolean): ItdRequestAPI; +begin + Result := AddParameter(AKey, AValue.ToString, ADefaultValue.ToString, ARequired); +end; +function TtdCoreApiBase.AddParameter(const AKey: string; AValue, ADefaultValue: + TObject; const ARequired: Boolean): ItdRequestAPI; +begin + Result := AddParameter(AKey, TJsonUtils.ObjectToJString(AValue), // + TJsonUtils.ObjectToJString(ADefaultValue), ARequired); +end; +function TtdCoreApiBase.AddParameter(const AKey: string; const AValue, + ADefaultValue, ARequired: Boolean): ItdRequestAPI; +begin + Result := AddParameter(AKey, AValue.ToJSONBool, ADefaultValue.ToJSONBool, ARequired); +end; + +function TtdCoreApiBase.AddParameter(const AKey: string; const AValue, + ADefaultValue: Single; const ARequired: Boolean): ItdRequestAPI; +Var StrSingle: String; + I: Integer; +begin + StrSingle := AValue.ToString; + for I:=1 to length(StrSingle) do + if StrSingle[I]= ',' then + StrSingle[I]:= '.'; + + Result := AddParameter(AKey, StrSingle, ADefaultValue.ToString, ARequired); +end; +{$ENDREGION} + +function TtdCoreApiBase.AddRawField(const AField, AValue: string): ItdRequestAPI; +begin + FFormData.AddField(AField, AValue); + FHaveFields := True; + Result := Self; +end; +function TtdCoreApiBase.AddRawFile(const AFieldName, AFileName: string): ItdRequestAPI; +begin + FFormData.AddFile(AFieldName, AFileName); + FHaveFields := True; + Result := Self; +end; +function TtdCoreApiBase.AddRawStream(const AFieldName: string; Data: TStream; + const AFileName: string): ItdRequestAPI; +begin + FFormData.AddStream(AFieldName, Data, AFileName); + FHaveFields := True; + Result := Self; +end; +function TtdCoreApiBase.ClearParameters: ItdRequestAPI; +begin + FFormData := nil; + FHaveFields := False; + FFormData := HttpCore.CreateMultipartFormData; + Result := Self; +end; +constructor TtdCoreApiBase.Create; +begin + FHaveFields := False; +end; +procedure TtdCoreApiBase.DoHaveException(const AException: Exception); +begin + if Assigned(OnError) then + OnError(AException) + else + raise AException; +end; +function TtdCoreApiBase.ExecuteAndReadValue: string; +var + LJson: TJSONValue; +begin + LJson := TJSONObject.ParseJSONValue(Execute); + try + Result := LJson.Value; + finally + LJson.Free; + end; +end; +function TtdCoreApiBase.ExecuteAsBool: Boolean; +var + LJson: TJSONValue; +begin + LJson := TJSONObject.ParseJSONValue(Execute); + try + Result := LJson is TJSONTrue; + finally + LJson.Free; + end; +end; +function TtdCoreApiBase.GetDataExtractor: TFunc; +begin + Result := FDataExtractor; +end; +function TtdCoreApiBase.GetFormData: IcuMultipartFormData; +begin + Result := FFormData; +end; +function TtdCoreApiBase.GetHttpCore: IcuHttpClient; +begin + Result := FHttpCore; +end; +function TtdCoreApiBase.GetOnError: TProc; +begin + Result := FOnError; +end; +function TtdCoreApiBase.GetOnReceive: TProc; +begin + Result := FOnReceive; +end; +function TtdCoreApiBase.GetOnSend: TProc; +begin + Result := FGetOnSend; +end; +function TtdCoreApiBase.GetUrl: string; +begin + Result := GetUrlAPI + FToken + '/' + FMethod; +end; +function TtdCoreApiBase.GetUrlAPI: string; +begin + Result := FUrlAPI; +end; +function TtdCoreApiBase.HaveFields: Boolean; +begin + Result := FHaveFields; +end; +procedure TtdCoreApiBase.SetDataExtractor(const Value: TFunc); +begin + FDataExtractor := Value; +end; +procedure TtdCoreApiBase.SetHttpCore(const Value: IcuHttpClient); +begin + FHttpCore := Value; + if FHttpCore <> nil then + FFormData := FHttpCore.CreateMultipartFormData; +end; +function TtdCoreApiBase.SetMethod(const AMethod: string): ItdRequestAPI; +begin + FMethod := AMethod; + Result := Self; +end; +procedure TtdCoreApiBase.SetOnError(const Value: TProc); +begin + FOnError := Value; +end; +procedure TtdCoreApiBase.SetOnReceive(const Value: TProc); +begin + FOnReceive := Value; +end; +procedure TtdCoreApiBase.SetOnSend(const Value: TProc); +begin + FGetOnSend := Value; +end; +function TtdCoreApiBase.SetToken(const AToken: string): ItdRequestAPI; +begin + FToken := AToken; + Result := Self; +end; +procedure TtdCoreApiBase.SetUrlAPI(const AValue: string); +begin + FUrlAPI := AValue; +end; +function TtdCoreApiBase.StreamToString(Stream: TStream): string; +var + LStrings: TStringList; +begin + LStrings := TStringList.Create; + try + Stream.Position := 0; + LStrings.LoadFromStream(Stream); + Result := LStrings.Text; + finally + LStrings.Free; + end; +end; +{ TtdCoreApiSysNet } +function TtdCoreApi.DoGet: string; +begin + Result := FHttpCore.Get(Url).ContentAsString; +end; +function TtdCoreApi.DoPost: string; +begin + Result := FHttpCore.Post(Url, FFormData).ContentAsString; +end; +function TtdCoreApi.Execute: string; +begin + if Assigned(OnSend) then + OnSend(Url, StreamToString(FFormData.Stream)); + try + if HaveFields then + begin + Result := DoPost; + ClearParameters; + end + else + Result := DoGet; + except + on E: Exception do + begin + Result := ''; + DoHaveException(E); + end; + end; + if Result = '' then + Exit; + if Assigned(OnReceive) then + OnReceive(Result); + if Assigned(DataExtractor) then + Result := DataExtractor(Result); +end; +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Emoji.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Emoji.pas new file mode 100644 index 0000000..c4ab26f --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Emoji.pas @@ -0,0 +1,1124 @@ +unit TinjectTelegram.Emoji; + +interface + +type + +TtdEmoji = record +const + +//Novos EMojis v11.0 +{$REGION 'EMOJI 11.0'} + SuperHeroiMulher = '🦸♀️' ; + SuperHeroiHomem = '🦸♂️' ; + SupervivenciaMulher = '🦹♀️' ; + HomemSuperando = '🦹♂️' ; + + HomemCabeloVermelho = '👨🦰' ; + HomemCabeloVermelhoPeleClara = '👨🏻🦰' ; + HomemCabeloVermelhoPeleLuzMedia = '👨🏼🦰' ; + HomemCabeloVermelhoPeleMedia = '👨🏽🦰' ; + HomemCabeloVermelhoPeleMedioEscuro = '👨🏾🦰' ; + HomemCabeloVermelhoPeleEscura = '👨🏿🦰' ; + + HomemCabelosEncaracolados = '👨🦱' ; + HomemCabelosEncaracoladosPeleClara = '👨🏻🦱' ; + HomemCabelosEncaracoladosPeleLuzMedia = '👨🏼🦱' ; + HomemCabeloEncaracoladoPeleMedia = '👨🏽🦱' ; + HomemCabeloEncaracoladoPeleMedioEscuro = '👨🏾🦱' ; + HomemCabeloEncaracoladosPeleEscura = '👨🏿🦱' ; + + HomemCalvo = '👨🦲' ; + HomemCalvoPeleClara = '👨🏻🦲' ; + HomemCalvoPeleLuzMedia = '👨🏼🦲' ; + HomemCalvoPeleMedia = '👨🏽🦲' ; + HomemCalvoPeleMedioEscuro = '👨🏾🦲' ; + HomemCalvoPeleEscura = '👨🏿🦲' ; + + HomemCabeloBranco = '👨🦳' ; + HomemCabeloBrancoPeleClara = '👨🏻🦳' ; + HomemCabeloBrancoPeleLuzMedia = '👨🏼🦳' ; + HomemCabeloBrancoPeleMedia = '👨🏽🦳' ; + HomemCabeloBrancoPeleMedioEscuro = '👨🏾🦳' ; + HomemCabeloBrancoPeleEscura = '👨🏿🦳' ; + + MulherCabeloVermelho = '👩🦰' ; + MulherCabeloVermelhoPeleClara = '👩🏻🦰' ; + MulherCabeloVermelhoPeleLuzMedia = '👩🏼🦰' ; + MulherCabeloVermelhoPeleMedia = '👩🏽🦰' ; + MulherCabeloVermelhoPeleMedioEscuro = '👩🏾🦰' ; + MulherCabeloVermelhoPeleEscura = '👩🏿🦰' ; + + MulherCabeloEncaracolado = '👩🦱' ; + MulherCabeloEncaracoladoPeleClara = '👩🏻🦱' ; + MulherCabeloEncaracoladoPeleLuzMedia = '👩🏼🦱' ; + MulherCabeloEncaracoladoPeleMedia = '👩🏽🦱' ; + MulherCabeloEncaracoladoPeleMedioEscuro = '👩🏾🦱' ; + MulherCabeloEncaracoladoPeleEscura = '👩🏿🦱' ; + + MulherCalva = '👩🦲' ; + MulherCalvaPeleClara = '👩🏻🦲' ; + MulherCalvaPeleLuzMedia = '👩🏼🦲' ; + MulherCalvaPeleMedia = '👩🏽🦲' ; + MulherCalvaPeleMedioEscuro = '👩🏾🦲' ; + MulherCalvaPeleEscura = '👩🏿🦲' ; + + MulherCabeloBranco = '👩🦳' ; + MulherCabeloBrancoPeleClara = '👩🏻🦳' ; + MulherCabeloBrancoPeleLuzMedia = '👩🏼🦳' ; + MulherCabeloBrancoPeleMedia = '👩🏽🦳' ; + MulherCabeloBrancoPeleMedioEscuro = '👩🏾🦳' ; + MulherCabeloBrancoPeleEscura = '👩🏿🦳' ; + + Infinito = '♾' ; + BandeiraDePirata = '🏴☠️ '; + Microbio = '🦠' ; + Bagagem = '🧳' ; + BolaFios = '🧶' ; + + CarinhaComOlhosSuplicantes = '🥺' ; + CarinhaComOlhosIrregularesEBocaOndulada = '🥴' ; + CarinhaSorridenteComOlhosSorridentesETresCoracoes = '🥰' ; + CarinhaComOlhosSorridentesEChifreDeFestaEChapeuDeFesta = '🥳' ; + + PinoDeSegurança = '🧷' ; + CaixaDeFerramentas = '🧰' ; + Vassoura = '🧹' ; + Cesta = '🧺' ; + Softball = '🥎' ; + Cupcake = '🧁' ; + BarraDeSabao = '🧼' ; + Perna = '🦵' ; + Manga = '🥭' ; + UrsinhoDePelucia = '🧸' ; + CarretelDeFio = '🧵' ; + Recibo = '🧾' ; + RoloDePapelHigienico = '🧻' ; + GarrafaDeLoção = '🧴' ; + CarinhaSuperaquecido = '🥵' ; + EnvelopeDePresenteVermelho = '🧧' ; + CarinhaGelado = '🥶' ; + Abaco = '🧮' ; + AmuletoNazare = '🧿' ; + + BoloDeLua = '🥮' ; + Bussola = '🧭' ; + Canguru = '🦘' ; + SuperHeroi = '🦸' ; + + Osso = '🦴' ; + DiscoVoador = '🥏' ; + Texugo = '🦡' ; + Cisne = '🦢' ; + Esponja = '🧽' ; + Hipopotamo = '🦛' ; + PetriDish = '🧫' ; + Dna = '🧬' ; + Salador = '🧂' ; + ExtintorDeIncendio = '🧯' ; + Dente = '🦷' ; + BotasDeCaminhada = '🥾' ; + Ima = '🧲' ; + BataDeLaboratório = '🥼' ; + SapatoPlano = '🥿' ; + Pavao = '🦚' ; + Lama = '🦙' ; + + TuboDeEnsaio = '🧪' ; + Raccoon = '🦝' ; + Lagosta = '🦞' ; + Mosquito = '🦟' ; + VerdeFrondoso = '🥬' ; + Papagaio = '🦜' ; + LacrosseStickEBola = '🥍' ; + Skateboard = '🛹' ; + Pe = '🦶' ; + Supervilancia = '🦹' ; + Foguete = '🧨' ; + PeçaDeQuebraCabeca = '🧩' ; + Bagel = '🥯' ; + Goggles = '🥽' ; + Tijolos = '🧱' ; + +{$ENDREGION 'EMOJI 11.0'} + +{$REGION 'SUPER-REGION:PESSOAS'} + + {$REGION 'SMILES'} + Sorridente = '😄'; + SorridenteLingua = '😝'; + Impressionado = '😱'; + Irritado = '😤'; + CabecaExplodindo = '🤯'; + Triste = '😢'; + Apaixonado = '😍'; + Sorrindo = '😄'; + Sorrindo1 = '😃'; + Sorrindo2 = '😀'; + Sorrindo3 = '😊'; + Sorrindo4 = '😁'; + Sono = '😴'; + Branco = '☺'; + Piscando = '😉'; + Smiling5 = '😍'; + ThrowingaKiss = '😘'; + KissingClosedEyes = '😚'; + Beijando = '😗'; + KissingSmilingEyes = '😙'; + Preso0 = '😜'; + Preso1 = '😝'; + Preso2 = '😛'; + Flushed = '😳'; + Pensativo = '😔'; + Aliviado = '😌'; + Naoutilizado = '😒'; + Decepcionado = '😞'; + Perseverante = '😣'; + Choro = '😢'; + ChorandoDeAlegria = '😂'; + ChorandoAlto = '😭'; + Sonolento = '😪'; + DecepcionadoMasAliviado = '😥'; + OpenMouthandColdSweat = '😰'; + SmilingOpenMouthandColdSweat = '😅'; + ColdSweat = '😓'; + Cansado = '😩'; + Cansado1 = '😫'; + Temível = '😨'; + ScreaminginFear = '😱'; + Pouting = '😡'; + Triunfo = '😤'; + Confundido = '😖'; + Sorrindo7 = '😆'; + Delicioso = '😋'; + MedicalMask = '😷'; + SmilingSunglasses = '😎'; + Dormindo = '😴'; + Dizzy = '😵'; + Surpreendido = '😲'; + Preocupado = '😟'; + FrowningOpenMouth = '😦'; + Angustiado = '😧'; + OpenMouth = '😮'; + Careta = '😬'; + Neutro = '😐'; + Confuso = '😕'; + Hushed = '😯'; + outMouth = '😶'; + SmilingHalo = '😇'; + Smirking = '😏'; + Expressionless = '😑'; + SmilingHorns = '😈'; + Imp = '👿'; + +{$ENDREGION "SMILES"} + {$REGION 'FACES'} + const PapaiNoel = '🎅'; + const Bot = '🤖'; + const ManGuaPiMao = '👲'; + const ManTurban = '👳'; + const Bebê = '👶'; + const Boy = '👦'; + const Garota = '👧'; + const Man = '👨'; + const Mulher = '👩'; + const OlderMan = '👴'; + const OlderWoman = '👵'; + const PersonBlondHair = '👱'; + const BabyAngel = '👼'; + const Princess = '👸'; + const Kiss = '💏'; + const CoupleHeart = '💑'; +{$ENDREGION 'FACES'} + {$REGION 'GESTOS'} + Like = '👍🏻'; + Deslike = '👎🏻'; + ApertoDeMao = '🤝🏻'; + PazEAmor = '✌🏻'; + ApontaCima = '👆🏻'; + ApontaBaixo = '👇🏻'; + Palmas = '👏🏻'; + ThumbsUpSign = '👍'; + ThumbsDownSign = '👎'; + OKHandSign = '👌'; + FistedHandSign = '👊'; + RaisedFist = '✊'; + VictoryHand = '✌'; + WavingHandSign = '👋'; + RaisedHand = '✋'; + OpenHandsSign = '👐'; + WhiteUpPointingBackhandIndex = '👆'; + WhiteDownPointingBackhandIndex = '👇'; + WhiteRightPointingBackhandIndex = '👉'; + WhiteLeftPointingBackhandIndex = '👈'; + PersonRaisingBothHandsinCelebration = '🙌'; + PersonFoldedHands = '🙏'; + WhiteUpPointingIndex = '☝'; + ClappingHandsSign = '👏'; + FlexedBiceps = '💪'; + NailPolish = '💅'; + DashSymbol = '💨'; + Orelha = '👂'; + Olhos = '👀'; + Nariz = '👃'; + Língua = '👅'; + Boca = '👄'; +{$ENDREGION 'GESTOS'} + {$REGION 'PERSONAGENS'} + const LoiraFazerOq = '🤷‍♀' ; + const LoiraMaoNoRosto = '🤦‍♀' ; + const LoiraNotebook = '👩🏼‍💻'; + const LoiraOla = '🙋🏼‍♀'; + const LoiraAteLogo = '💁🏼‍♀'; + const LoiraTriste = '🙍🏼‍♀'; + const AtendenteH = '👨🏼‍💼'; + const AtendenteM = '👩🏼‍💼'; + const PoliceOfficer = '👮'; + const ConstructionWorker = '👷'; + const Guardsman = '💂'; + const ManandWomanHoldingHands = '👫'; + const família = '👪'; + const TwoMenHoldingHands = '👬'; + const TwoWomenHoldingHands = '👭'; + const BustinSilhouette = '👤'; + const BustsinSilhouette = '👥'; + const Pedestre = '🚶'; + const Runner = '🏃'; + const Dançarino = '💃'; + const WomanBunnyEars = '👯'; + const OKGesture = '🙆'; + const NoGoodGesture = '🙅'; + const InformationDeskPerson = '💁'; + const HappyPersonRaisingOneHand = '🙋'; + const massagem = '💆'; + const Cortedecabelo = '💇'; + const BrideVeil = '👰'; + const PersonPouting = '🙎'; + const PersonFrowning = '🙍'; + const PersonBowingDeeply = '🙇'; + {$ENDREGION 'PERSONAGENS'} +{$ENDREGION 'SUPER-REGION:PESSOAS'} +{$REGION 'SUPER-REGION:NATUREZA'} + {$REGION 'FACES E ANIMAIS'} + const ExtraterrestrialAlien = '👽'; + const SmilingCatOpenMouth = '😺'; + const GrinningCatSmilingEyes = '😸'; + const SmilingCatHeartShapedEyes = '😻'; + const KissingCatClosedEyes = '😽'; + const CatWrySmile = '😼'; + const WearyCat = '🙀'; + const CryingCat = '😿'; + const CatTearsofJoy = '😹'; + const PoutingCat = '😾'; + const Macaco = '🐵'; + const SeeNoEvilMonkey = '🙈'; + const HearNoEvilMonkey = '🙉'; + const SpeakNoEvilMonkey = '🙊'; + const Dog = '🐶'; + const Wolf = '🐺'; + const Cat = '🐱'; + const Mouse = '🐭'; + const Hamster = '🐹'; + const Frog = '🐸'; + const Tiger = '🐯'; + const Koala = '🐨'; + const Bear = '🐻'; + const Pig = '🐷'; + const PigNose = '🐽'; + const Cow = '🐮'; + const Boar = '🐗'; + const Macaco1 = '🐒'; + const Cavalo = '🐴'; + const Ovelha = '🐑'; + const Elefante = '🐘'; + const Panda = '🐼'; + const Pinguim = '🐧'; + const Bird = '🐦'; + const BabyChick = '🐤'; + const FrontFacingBabyChick = '🐥'; + const HatchingChick = '🐣'; + const Frango = '🐔'; + const Cobra = '🐍'; + const Tartaruga = '🐢'; + const Bug = '🐛'; + const Honeybee = '🐝'; + const Ant = '🐜'; + const LadyBeetle = '🐞'; + const Caracol = '🐌'; + const Polvo = '🐙'; + const SpiralShell = '🐚'; + const TropicalFish = '🐠'; + const Peixe = '🐟'; + const Dolphin = '🐬'; + const SpoutingWhale = '🐳'; + const Baleia = '🐋'; + const Cow1 = '🐄'; + const Ram = '🐏'; + const Rato = '🐀'; + const WaterBuffalo = '🐃'; + const Tiger1 = '🐅'; + const Coelho = '🐇'; + const Dragão = '🐉'; + const Cavalo1 = '🐎'; + const Cabra = '🐐'; + const Galo = '🐓'; + const Dog1 = '🐕'; + const Pig1 = '🐖'; + const Mouse1 = '🐁'; + const Ox = '🐂'; + const Dragão1 = '🐲'; + const Blowfish = '🐡'; + const Crocodilo = '🐊'; + const BactrianCamel = '🐫'; + const DromedaryCamel = '🐪'; + const Leopardo = '🐆'; + const Cat1 = '🐈'; + const Poodle = '🐩'; + const PawPrints = '🐾'; +{$ENDREGION 'FACES E ANIMAIS'} + {$REGION 'NATUREZA'} + const Bouquet = '💐'; + const CherryBlossom = '🌸'; + const Tulip = '🌷'; + const FourLeafClover = '🍀'; + const Rose = '🌹'; + const Girassol = '🌻'; + const Hibisco = '🌺'; + const MapleLeaf = '🍁'; + const LeafFlutteringinWind = '🍃'; + const FallenLeaf = '🍂'; + const Herb = '🌿'; + const EarofRice = '🌾'; + const Cogumelo = '🍄'; + const Cactus = '🌵'; + const PalmTree = '🌴'; + const EvergreenTree = '🌲'; + const DeciduousTree = '🌳'; + const Chestnut = '🌰'; + const Mudas = '🌱'; + const Blossom = '🌼'; + const RedApple = '🍎'; + const GreenApple = '🍏'; + const Tangerina = '🍊'; + const Limão = '🍋'; + const Cerejas = '🍒'; + const Uvas = '🍇'; + const Melancia = '🍉'; + const Morango = '🍓'; + const Peach = '🍑'; + const Melão = '🍈'; + const Banana = '🍌'; + const Pear = '🍐'; + const Abacaxi = '🍍'; + const RoastedSweetPotato = '🍠'; + const Beringela = '🍆'; + const Tomate = '🍅'; + const EarofMaize = '🌽'; + const WhiteFlower = '💮'; + const GlobeMeridians = '🌐'; + const Sun = '🌞'; + const FullMoon = '🌝'; + const NewMoon = '🌚'; + const NewMoonSymbol = '🌑'; + const WaxingCrescentMoonSymbol = '🌒'; + const FirstQuarterMoonSymbol = '🌓'; + const WaxingGibbousMoonSymbol = '🌔'; + const FullMoonSymbol = '🌕'; + const WaningGibbousMoonSymbol = '🌖'; + const LastQuarterMoonSymbol = '🌗'; + const WaningCrescentMoonSymbol = '🌘'; + const LastQuarterMoon = '🌜'; + const FirstQuarterMoon = '🌛'; + const CrescentMoon = '🌙'; + const EarthGlobeEuropaafrica = '🌍'; + const EarthGlobeAmericas = '🌎'; + const EarthGlobeAsiaAustralia = '🌏'; + const Vulcão = '🌋'; + const MilkyWay = '🌌'; + const ShootingStar = '🌠'; + const WhiteMediumStar = '⭐'; + const BlackSunRays = '☀'; + const SunBehindCloud = '⛅'; + const Nuvem = '☁'; + const HighVoltageSign = '⚡'; + const UmbrellaRainDrops = '☔'; + const Flocodeneve = '❄'; + const SnowmanoutSnow = '⛄'; + const Ciclone = '🌀'; + const Foggy = '🌁'; + const Arcoiris = '🌈'; + const WaterWave = '🌊'; +{$ENDREGION 'NATUREZA'} +{$ENdREGION 'SUPER-REGION:NATUREZA'} +{$REGION 'SUPER-REGION:COMIDAS E BEBIDAS'} + {$REGION 'COMIDAS'} + const Macarrao = '🍜'; + const PizzaFatia = '🍕'; + const Sorvete = '🍧'; + const Açai = '🍨'; + const Restaurante = '🍽'; + const GarfoeFaca = '🍴'; + const Hambúrguer = '🍔'; + const BatatasFritas = '🍟'; + const PoultryLeg = '🍗'; + const MeatonBone = '🍖'; + const espaguete = '🍝'; + const CurryandRice = '🍛'; + const CamaraoFrito = '🍤'; + const BentoBox = '🍱'; + const Sushi = '🍣'; + const FishCakeSwirlDesign = '🍥'; + const PanelaComComida = '🥘'; + const RiceBall = '🍙'; + const RiceCracker = '🍘'; + const CookedRice = '🍚'; + const SteamingBowl = '🍜'; + const PotofFood = '🍲'; + const Oden = '🍢'; + const Dango = '🍡'; + const Culinária = '🍳'; + const Pão = '🍞'; + const Donut = '🍩'; + const Creme = '🍮'; + const SoftIceCream = '🍦'; + const IceCream = '🍨'; + const ShavedIce = '🍧'; + const BirthdayCake = '🎂'; + const Shortcake = '🍰'; + const Cookie = '🍪'; + const ChocolateBar = '🍫'; + const Candy = '🍬'; + const pirulito = '🍭'; + const HoneyPot = '🍯'; +{$ENDREGION 'COMIDAS'} + {$REGION 'BEBIDAS'} + const Bebida = '🥃'; + const HotBeverage = '☕'; + const TeacupoutHandle = '🍵'; + const SakeBottleandCup = '🍶'; + const BabyBottle = '🍼'; + const BeerMug = '🍺'; + const ClinkingBeerMugs = '🍻'; + const CocktailGlass = '🍸'; + const TropicalDrink = '🍹'; + const WineGlass = '🍷'; +{$ENDREGION 'BEBIDAS'} +{$ENDREGION 'SUPER-REGION:COMIDAS E BEBIDAS'} +{$REGION 'SUPER-REGION:SIMBOLOS E BANDEIRAS'} + {$REGION 'SIMBOLOS'} + const YellowHeart = '💛'; + const BlueHeart = '💙'; + const PurpleHeart = '💜'; + const GreenHeart = '💚'; + const HeavyBlackHeart = '❤'; + const BrokenHeart = '💔'; + const GrowingHeart = '💗'; + const BeatingHeart = '💓'; + const TwoHearts = '💕'; + const SparklingHeart = '💖'; + const RevolvingHearts = '💞'; + const HeartArrow = '💘'; + const LoveLetter = '💌'; + const KissMark = '💋'; + const Ring = '💍'; + const GemStone = '💎'; + const HeartDecoration = '💟'; + const SpeechBalloon = '💬'; + const Pegadas = '👣'; + const ThoughtBalloon = '💭'; + const HeartRibbon = '💝'; + const Corarao = '❤'; + const Check = '✅'; + const Check2 = '✔'; + const Atencao = '⚠'; + const SetaDireita = '➡'; + const SetaEsquerda = '⬅'; + const Relogio = '🕒'; + const Conversa = '💬'; + const Estrela = '⭐'; + const Erro = '❌'; + const Duvida = '⁉'; + const Dormiu = '💤'; + const DoubleExclamationMark = '‼'; + const ExclamationQuestionMark = '⁉'; + const HeavyExclamationMarkSymbol = '❗'; + const BlackQuestionMarkOrnament = '❓'; + const WhiteExclamationMarkOrnament = '❕'; + const WhiteQuestionMarkOrnament = '❔'; + const DownwardsBlackArrow = '⬇'; + const LeftwardsBlackArrow = '⬅'; + const BlackRightwardsArrow = '➡'; + const NorthEastArrow = '↗'; + const NorthWestArrow = '↖'; + const SouthEastArrow = '↘'; + const SouthWestArrow = '↙'; + const LeftRightArrow = '↔'; + const UpDownArrow = '↕'; + const AnticlockwiseDownwardsandUpwardsOpenCircleArrows = '🔄'; + const BlackLeftPointingTriangle = '◀'; + const BlackRightPointingTriangle = '▶'; + const UpPointingSmallRedTriangle = '🔼'; + const DownPointingSmallRedTriangle = '🔽'; + const LeftwardsArrowHook = '↩'; + const RightwardsArrowHook = '↪'; + const BlackLeftPointingDoubleTriangle = '⏪'; + const BlackRightPointingDoubleTriangle = '⏩'; + const BlackUpPointingDoubleTriangle = '⏫'; + const BlackDownPointingDoubleTriangle = '⏬'; + const ArrowPointingRightwardsthenCurvingDownwards = '⤵'; + const ArrowPointingRightwardsthenCurvingUpwards = '⤴'; + const TwistedRightwardsArrows = '🔀'; + const ClockwiseRightwardsandLeftwardsOpenCircleArrows = '🔁'; + const ClockwiseRightwardsandLeftwardsOpenCircleArrowsCircledOneOverlay = '🔂'; + const TopUpwardsArrowAbove = '🔝'; + const EndLeftwardsArrowAbove = '🔚'; + const BackLeftwardsArrowAbove = '🔙'; + const OnExclamationMarkLeftRightArrowAbove = '🔛'; + const SoonRightwardsArrowAbove = '🔜'; + const ClockwiseDownwardsandUpwardsOpenCircleArrows = '🔃'; + const UpPointingRedTriangle = '🔺'; + const DownPointingRedTriangle = '🔻'; + const UpwardsBlackArrow = '⬆'; + const Áries = '♈'; + const Touro = '♉'; + const Gêmeos = '♊'; + const Câncer = '♋'; + const Leo = '♌'; + const Virgo = '♍'; + const Libra = '♎'; + const Scorpius = '♏'; + const Sagitário = '♐'; + const Capricórnio = '♑'; + const Aquário = '♒'; + const Peixes = '♓'; + const Ophiuchus = '⛎'; + const FlagforJapan = '🇯🇵'; + const FlagforSouthKorea = '🇰🇷'; + const FlagforGermany = '🇩🇪'; + const FlagforChina = '🇨🇳'; + const FlagforUnitedStates = '🇺🇸'; + const FlagforFrance = '🇫🇷'; + const FlagforSpain = '🇪🇸'; + const FlagforItaly = '🇮🇹'; + const FlagforRussia = '🇷🇺'; + const FlagforUnitedKingdom = '🇬🇧'; + const Banheiro = '🚻'; + const MensSymbol = '🚹'; + const WomensSymbol = '🚺'; + const BabySymbol = '🚼'; + const WaterCloset = '🚾'; + const PotableWaterSymbol = '🚰'; + const PutLitterinitsPlaceSymbol = '🚮'; + const WheelchairSymbol = '♿'; + const NoSmokingSymbol = '🚭'; + const PassportControl = '🛂'; + const BaggageClaim = '🛄'; + const LeftLuggage = '🛅'; + const Alfândega = '🛃'; + const NoEntrySign = '🚫'; + const NoOneUnderEighteenSymbol = '🔞'; + const NoMobilePhones = '📵'; + const DoNotLitterSymbol = '🚯'; + const NonPotableWaterSymbol = '🚱'; + const NoBicycles = '🚳'; + const NoPedestrians = '🚷'; + const ChildrenCrossing = '🚸'; + const NoEntry = '⛔'; + const BlackUniversalRecyclingSymbol = '♻'; + const DiamondShapeaDotInside = '💠'; + const DoubleCurlyLoop = '➿'; + const LinkSymbol = '🔗'; + const CurlyLoop = '➰'; + const WavyDash = '〰'; + const PartAlternationMark = '〽'; + const TridentEmblem = '🔱'; + const BlackMediumSquare = '◼'; + const WhiteMediumSquare = '◻'; + const BlackMediumSmallSquare = '◾'; + const WhiteMediumSmallSquare = '◽'; + const BlackSmallSquare = '▪'; + const WhiteSmallSquare = '▫'; + const BlackSquareButton = '🔲'; + const WhiteSquareButton = '🔳'; + const MediumBlackCircle = '⚫'; + const MediumWhiteCircle = '⚪'; + const LargeRedCircle = '🔴'; + const LargeBlueCircle = '🔵'; + const WhiteLargeSquare = '⬜'; + const BlackLargeSquare = '⬛'; + const LargeOrangeDiamond = '🔶'; + const LargeBlueDiamond = '🔷'; + const SmallOrangeDiamond = '🔸'; + const SmallBlueDiamond = '🔹'; + const SquaredKatakanaKoko = '🈁'; + const SquaredCJKUnifiedIdeograph = '🈯'; + const SquaredCJKUnifiedIdeographaa = '🈳'; + const SquaredCJKUnifiedIdeographe = '🈵'; + const SquaredCJKUnifiedIdeograph1 = '🈴'; + const SquaredCJKUnifiedIdeograph2 = '🈲'; + const CircledIdeographAdvantage = '🉐'; + const SquaredCJKUnifiedIdeograph3 = '🈹'; + const SquaredCJKUnifiedIdeographb = '🈺'; + const SquaredCJKUnifiedIdeograph4 = '🈶'; + const SquaredCJKUnifiedIdeograph5 = '🈚'; + const SquaredCJKUnifiedIdeograph6 = '🈷'; + const SquaredCJKUnifiedIdeograph7 = '🈸'; + const SquaredKatakanaSa = '🈂'; + const CircledIdeographAccept = '🉑'; + const circledideographsecret = '㊙'; + const circledideographcongratulation = '㊗'; + const EightSpokedAsterisk = '✳'; + const Sparkle = '❇'; + const EightPointedBlackStar = '✴'; + const NegativeSquaredCrossMark = '❎'; + const WhiteHeavyCheckMark = '✅'; + const SixPointedStarMiddleDot = '🔯'; + const ChartUpwardsTrendandYenSign = '💹'; + const HeavyDollarSign = '💲'; + const CurrencyExchange = '💱'; + const CrossMark = '❌'; + const HeavyLargeCircle = '⭕'; + const HeavyMultiplicationX = '✖'; + const HeavyPlusSign = '➕'; + const HeavyMinusSign = '➕'; + const HeavyDivisionSign = '➗'; + const BlackSpadeSuit = '♠'; + const BlackHeartSuit = '♥'; + const BlackClubSuit = '♣'; + const BlackDiamondSuit = '♦'; + const HeavyCheckMark = '✔'; + const BallotBoxCheck = '☑'; + const RadioButton = '🔘'; +{$ENDREGION 'SIMBOLOS'} + {$REGION 'HORARIO'} + const ClockTwelveOclock = '🕛'; + const ClockTwelveThirty = '🕧'; + const ClockOneOclock = '🕐'; + const ClockOneThirty = '🕜'; + const ClockTwoOclock = '🕑'; + const ClockTwoThirty = '🕝'; + const ClockThreeOclock = '🕒'; + const ClockThreeThirty = '🕞'; + const ClockFourOclock = '🕓'; + const ClockFourThirty = '🕟'; + const ClockFiveOclock = '🕔'; + const ClockFiveThirty = '🕠'; + const ClockSixOclock = '🕕'; + const ClockSevenOclock = '🕖'; + const ClockEightOclock = '🕗'; + const ClockNineOclock = '🕘'; + const ClockTenOclock = '🕙'; + const ClockElevenOclock = '🕚'; + const ClockSixThirty = '🕡'; + const ClockSevenThirty = '🕢'; + const ClockEightThirty = '🕣'; + const ClockNineThirty = '🕤'; + const ClockTenThirty = '🕥'; + const ClockElevenThirty = '🕦'; +{$ENDREGION 'HORARIO'} + {$REGION 'NUMEROS'} + const Zero = '0⃣'; + const Um = '1⃣'; + const Dois = '2⃣'; + const Tres = '3⃣'; + const Quatro = '4⃣'; + const Cinco = '5⃣'; + const Seis = '6⃣'; + const Sete = '7⃣'; + const Oito = '8⃣'; + const Nove = '9⃣'; + const Dez = '🔟'; + const Aterisco = '*⃣'; + const KeycapDigitOne = '⃣'; + const KeycapDigitTwo = '⃣'; + const KeycapDigitThree = '⃣'; + const KeycapDigitFour = '⃣'; + const KeycapDigitFive = '⃣'; + const KeycapDigitSix = '⃣'; + const KeycapDigitSeven = '⃣'; + const KeycapDigitEight = '⃣'; + const KeycapDigitNine = '⃣'; + const KeycapDigitZero = '⃣'; + const KeycapTen = '🔟'; + const InputSymbolforNumbers = '🔢'; + const KeycapNumberSign = '# ⃣'; + const InputSymbolforLatinSmallLetters = '🔡'; + const InputSymbolforLatinLetters = '🔤'; + const InformationSource = 'ℹ'; + const SquaredOK = '🆗'; + const SquaredNEW = '🆕'; + const SquaredUPExclamationMark = '🆙'; + const SquaredCool = '🆒'; + const SquaredFree = '🆓'; + const SquaredNG = '🆖'; + const NegativeSquaredLatinCapitalLetterP = '🅿'; + const CircledLatinCapitalLetterM = 'Ⓜ'; + const SquaredCL = '🆑'; + const SquaredSOS = '🆘'; + const SquaredID = '🆔'; + const SquaredVS = '🆚'; + const NegativeSquaredLatinCapitalLetterA = '🅰'; + const NegativeSquaredLatinCapitalLetterB = '🅱'; + const NegativeSquaredAB = '🆎'; + const NegativeSquaredLatinCapitalLetterO = '🅾'; + const CopyrightSign = '©'; + const RegisteredSign = '®'; + const HundredPointsSymbol = '💯'; + const TradeMarkSign = '™'; + const InputSymbolforLatinCapitalLetters = '🔠'; +{$ENDREGION 'NUMEROS'} +{$ENDREGION 'SUPER-REGION:SIMBOLOS E BANDEIRAS'} +{$REGION 'ATIVIDADES'} + const PlayingCardBlackJoker = '🃏'; + const FlowerPlayingCards = '🎴'; + const MahjongTileRedDragon = '🀄'; + const GameDie = '🎲'; + const DirectHit = '🎯'; + const AmericanFootball = '🏈'; + const BasketballandHoop = '🏀'; + const SoccerBall = '⚽'; + const Baseball = '⚾'; + const TennisRacquetandBall = '🎾'; + const Bilhar = '🎱'; + const RugbyFootball = '🏉'; + const Boliche = '🎳'; + const FlaginHole = '⛳'; + const MountainBicyclist = '🚵'; + const Ciclista = '🚴'; + const ChequeredFlag = '🏁'; + const HorseRacing = '🏇'; + const troféu = '🏆'; + const SkiandSkiBoot = '🎿'; + const Snowboarder = '🏂'; + const Nadador = '🏊'; + const Surfista = '🏄'; +{$ENDREGION 'ATIVIDADES'} + +{$REGION 'LUGARES'} + const FishingPoleandFish = '🎣'; + const HouseBuilding = '🏠'; + const HouseGarden = '🏡'; + const Escola = '🏫'; + const OfficeBuilding = '🏢'; + const JapanesePostOffice = '🏣'; + const Hospital = '🏥'; + const Banco = '🏦'; + const ConvenienceStore = '🏪'; + const LoveHotel = '🏩'; + const Hotel = '🏨'; + const casamento = '💒'; + const Igreja = '⛪'; + const Moto = '🏍'; + const Carro = '🚘'; + const Barco = '🚢'; + const DepartmentStore = '🏬'; + const EuropeanPostOffice = '🏤'; + const SunsetoverBuildings = '🌇'; + const CityscapeatDusk = '🌆'; + const JapaneseCastle = '🏯'; + const EuropeanCastle = '🏰'; + const Tent = '⛺'; + const Fábrica = '🏭'; + const TokyoTower = '🗼'; + const SilhouetteofJapan = '🗾'; + const MountFuji = '🗻'; + const SunriseoverMountains = '🌄'; + const Nascerdosol = '🌅'; + const NightStars = '🌃'; + const StatueofLiberty = '🗽'; + const BridgeatNight = '🌉'; + const CarouselHorse = '🎠'; + const FerrisWheel = '🎡'; + const Fonte = '⛲'; + const RollerCoaster = '🎢'; + const Ship = '🚢'; + const Veleiro = '⛵'; + const Lancha = '🚤'; + const Rowboat = '🚣'; + const Ancora = '⚓'; + const FogueteNovo = '🚀'; + const Aviao = '✈'; + const Seat = '💺'; + const Helicóptero = '🚁'; + const SteamLocomotive = '🚂'; + const Bonde = '🚊'; + const estação = '🚉'; + const MountainRailway = '🚞'; + const Train = '🚆'; + const HighSpeedTrain = '🚄'; + const HighSpeedTrainBulletNose = '🚅'; + const LightRail = '🚈'; + const Metro = '🚇'; + const Monotrilho = '🚝'; + const TramCar = '🚋'; + const RailwayCar = '🚃'; + const Trólebus = '🚎'; + const Bus = '🚌'; + const OncomingBus = '🚍'; + const RecreationalVehicle = '🚙'; + const OncomingAutomobile = '🚘'; + const Automobile = '🚗'; + const Táxi = '🚕'; + const OncomingTaxi = '🚖'; + const ArticulatedLorry = '🚛'; + const DeliveryTruck = '🚚'; + const PoliceCarsRevolvingLight = '🚨'; + const PoliceCar = '🚓'; + const OncomingPoliceCar = '🚔'; + const FireEngine = '🚒'; + Const Ambulância = '🚑'; + const Minibus = '🚐'; + const Bicycle = '🚲'; + const AerialTramway = '🚡'; + const SuspensionRailway = '🚟'; + const MountainCableway = '🚠'; + const Trator = '🚜'; + const BarberPole = '💈'; + const BusStop = '🚏'; + const Ticket = '🎫'; +{$ENDREGION 'LUGARES'} + +{$REGION 'VARIADOS'} + const Violao = '🎸'; + const Chegada = '🏁'; + const Futebol = '⚽'; + const NaMosca = '🎯'; + const Dinheiro = '💵'; + const EnviarCel = '📲'; + const Enviar = '📩'; + const Fone = '📞'; + const Onibus = '🚍'; + const Aviao2 = '✈'; + const Joystick = '🎮'; + const Cartao = '💳'; + const TuboEnsaio = '🧪'; + const Pilula = '💊'; + const SacolaCompras = '🛍'; + const CarrinhoCompras = '🛒'; + const Ampulheta = '⏳'; + const Presente = '🎁'; + const Email = '📧'; + const AgendaAzul = '📘'; + const AgendaVerde = '📗'; + const AgendaVermelha = '📕'; + const ClipPapel = '📎'; + const CanetaAzul = '🖊'; + const Lapis = '✏'; + const LapisEPapel = '📝'; + const CadeadoEChave = '🔐'; + const Lupa = '🔎'; + + const JapaneseOgre = '👹'; + const JapaneseGoblin = '👺'; + const Crânio = '💀'; + const PileofPoo = '💩'; + + const TopHat = '🎩'; + const Coroa = '👑'; + const WomansHat = '👒'; + const AthleticShoe = '👟'; + const MansShoe = '👞'; + const WomansSandal = '👡'; + const HighHeeledShoe = '👠'; + const WomansBoots = '👢'; + const camiseta = '👕'; + const Gravata = '👔'; + const WomansClothes = '👚'; + const Dress = '👗'; + const RunningShirtSash = '🎽'; + const Jeans = '👖'; + const Quimono = '👘'; + const Biquíni = '👙'; + const Pasta = '💼'; + const Bolsa = '👜'; + const Pouch = '👝'; + const Bolsa1 = '👛'; + const Óculos = '👓'; + const Ribbon = '🎀'; + const ClosedUmbrella = '🌂'; + const Batom = '💄'; + const ArtistPalette = '🎨'; + const ClapperBoard = '🎬'; + const Microfone = '🎤'; + const Headphone = '🎧'; + const MusicalScore = '🎼'; + const NotaMusical = '🎵'; + const MultipleMusicalNotes = '🎶'; + const MusicalKeyboard = '🎹'; + const Violino = '🎻'; + const Trombeta = '🎺'; + const saxofone = '🎷'; + const Guitar = '🎸'; + const AlienMonster = '👾'; + const VideoGame = '🎮'; + + const VerticalTrafficLight = '🚦'; + const HorizontalTrafficLight = '🚥'; + const WarningSign = '⚠'; + const ConstructionSign = '🚧'; + const JapaneseSymbolforBeginner = '🔰'; + const FuelPump = '⛽'; + const IzakayaLantern = '🏮'; + const SlotMachine = '🎰'; + const HotSprings = '♨'; + const Moyai = '🗿'; + const CircusTent = '🎪'; + const PerformingArts = '🎭'; + const RoundPushpin = '📍'; + const TriangularFlagonPost = '🚩'; + const EMailSymbol = '📧'; + const InboxTray = '📥'; + const OutboxTray = '📤'; + const Envelope = '✉'; + const EnvelopeDownwardsArrowAbove = '📩'; + const IncomingEnvelope = '📨'; + const PostalHorn = '📯'; + const ClosedMailboxRaisedFlag = '📫'; + const ClosedMailboxLoweredFlag = '📪'; + const OpenMailboxRaisedFlag = '📬'; + const OpenMailboxLoweredFlag = '📭'; + const Caixapostal = '📮'; + const pacote = '📦'; + const Memo = '📝'; + const PageFacingUp = '📄'; + const PageCurl = '📃'; + const BookmarkTabs = '📑'; + const BarChart = '📊'; + const ChartUpwardsTrend = '📈'; + const ChartDownwardsTrend = '📉'; + const Scroll = '📜'; + const Area_de_transferencia = '📋'; + const Calendário = '📅'; + const TearOffCalendar = '📆'; + const CardIndex = '📇'; + const FileFolder = '📁'; + const OpenFileFolder = '📂'; + const BlackScissors = '✂'; + const Pino = '📌'; + const Clipede_papel = '📎'; + const BlackNib = '✒'; + const Lápis = '✏'; + const StraightRuler = '📏'; + const TriangularRuler = '📐'; + const ClosedBook = '📕'; + const GreenBook = '📗'; + const BlueBook = '📘'; + const OrangeBook = '📙'; + const Caderno = '📓'; + const NotebookDecorativeCover = '📔'; + const Ledger = '📒'; + const Livros = '📚'; + const OpenBook = '📖'; + const Marcador = '🔖'; + const NameBadge = '📛'; + const Microscópio = '📛'; + const Telescópio = '🔭'; + const Jornal = '📰'; + const MoneyBag = '💰'; + const BanknoteYenSign = '💴'; + const BanknoteDollarSign = '💵'; + const BanknotePoundSign = '💷'; + const BanknoteEuroSign = '💶'; + const CreditCard = '💳'; + const MoneyWings = '💸'; + const MovieCamera = '🎥'; + const Câmera = '📷'; + const VideoCamera = '📹'; + const fita_de_video = '📼'; + const OpticalDisc = '💿'; + const DVD = '📀'; + const Minidisc = '💽'; + const FloppyDisk = '💾'; + const PersonalComputer = '💻'; + const MobilePhone = '📱'; + const BlackTelephone = '☎'; + const TelephoneReceiver = '📞'; + const Pager = '📟'; + const FaxMachine = '📠'; + const SatelliteAntenna = '📡'; + const Televisão = '📺'; + const Rádio = '📻'; + const SpeakerThreeSoundWaves = '🔊'; + const SpeakerOneSoundWave = '🔉'; + const Altofalante = '🔈'; + const SpeakerCancellationStroke = '🔇'; + const Bell = '🔔'; + const BellcancellationStroke = '🔕'; + const PublicAddressLoudspeaker = '📢'; + const CheeringMegaphone = '📣'; + const HourglassFlowingSand = '⏳'; + const Hourglass = '⌛'; + const AlarmClock = '⏰'; + const Watch = '⌚'; + const OpenLock = '🔓'; + const Lock = '🔒'; + const LockInkPen = '🔏'; + const ClosedLockKey = '🔐'; + const Key = '🔑'; + const LeftPointingMagnifyingGlass = '🔎'; + const ElectricLightBulb = '💡'; + const ElectricTorch = '🔦'; + const ElectricPlug = '🔌'; + const Bateria = '🔋'; + const RightPointingMagnifyingGlass = '🔍'; + const Wrench = '🔧'; + const NutandBolt = '🔩'; + const Martelo = '🔨'; + const MobilePhoneRightwardsArrowatLeft = '📲'; + const AntennaBars = '📶'; + const Cinema = '🎦'; + const VibrationMode = '📳'; + const MobilePhoneOff = '📴'; + + const AutomatedTellerMachine = '🏧'; + + const PineDecoration = '🎍'; + const JapaneseDolls = '🎎'; + const SchoolSatchel = '🎒'; + const GraduationCap = '🎓'; + const CarpStreamer = '🎏'; + const Fireworks = '🎆'; + const FireworkSparkler = '🎇'; + const WindChime = '🎐'; + const MoonViewingCeremony = '🎑'; + const JackOLantern = '🎃'; + const Fantasma = '👻'; + const FatherChristmas = '🎅'; + const ChristmasTree = '🎄'; + const WrappedPresent = '🎁'; + const TanabataTree = '🎋'; + const PartyPopper = '🎉'; + const ConfettiBall = '🎊'; + const Balão = '🎈'; + const CrossedFlags = '🎌'; + const CrystalBall = '🔮'; + const HighBrightnessSymbol = '🔆'; + const LowBrightnessSymbol = '🔅'; + const Banheira = '🛁'; + const Bath = '🛀'; + const Shower = '🚿'; + const WC = '🚽'; + const Porta = '🚪'; + const SmokingSymbol = '🚬'; + const Bomb = '💣'; + const Pistola = '🔫'; + const Hocho = '🔪'; + const Pílula = '💊'; + const Seringa = '💉'; + const Fogo = '🔥'; + const Sparkles = '✨'; + const GlowingStar = '🌟'; + const DizzySymbol = '💫'; + const CollisionSymbol = '💥'; + const AngerSymbol = '💢'; + const SplashingSweatSymbol = '💦'; + const Gota = '💧'; + const SleepingSymbol = '💤'; +{$ENDREGION 'VARIADOS'} + +end; + +implementation + + +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Ext.Sessions.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Ext.Sessions.pas new file mode 100644 index 0000000..592ab60 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Ext.Sessions.pas @@ -0,0 +1,144 @@ +unit TinjectTelegram.Ext.Sessions; + +interface + +uses + System.Rtti, + System.Generics.Collections; + +type + ItdSession = interface + ['{D581A266-7AC0-496A-8784-9DCEDC6849C9}'] + function GetItem(const AKey: string): TValue; + procedure SetItem(const AKey: string; const Value: TValue); + function GetCreatedAt: TDateTime; + procedure SetCreatedAt(const Value: TDateTime); + // + procedure Clear; + property Items[const AKey: string]: TValue read GetItem write SetItem; Default; + property CreatedAt: TDateTime read GetCreatedAt write SetCreatedAt; + end; + + TtdSession = class(TInterfacedObject, ItdSession) + private + FItems: TDictionary; + FCreatedAt: TDateTime; + function GetItem(const AKey: string): TValue; + procedure SetItem(const AKey: string; const Value: TValue); + function GetCreatedAt: TDateTime; + procedure SetCreatedAt(const Value: TDateTime); + public + constructor Create; + destructor Destroy; override; + procedure Clear; + property CreatedAt: TDateTime read GetCreatedAt write SetCreatedAt; + property Items[const AKey: string]: TValue read GetItem write SetItem; Default; + end; + + ItdSessionManager = interface + ['{52E3CD5C-C096-4C3D-BC70-D284233C0250}'] + function GetItem(const AID: Int64): ItdSession; + procedure SetItem(const AID: Int64; const Value: ItdSession); + procedure Clear; + property Items[const AID: Int64]: ItdSession read GetItem write SetItem; Default; + end; + + TtdSessionManager = class(TInterfacedObject, ItdSessionManager) + private + class var + FInstance: TtdSessionManager; + private + FItems: TDictionary; + function GetItem(const AID: Int64): ItdSession; + procedure SetItem(const AID: Int64; const Value: ItdSession); + public + class function NewInstance: TObject; override; + constructor Create; + destructor Destroy; override; + procedure Clear; + property Items[const AID: Int64]: ItdSession read GetItem write SetItem; Default; + end; + +implementation + +uses + System.SysUtils; + +procedure TtdSession.Clear; +begin + FItems.Clear; +end; + +constructor TtdSession.Create; +begin + FItems := TDictionary.Create; +end; + +destructor TtdSession.Destroy; +begin + FItems.Free; + inherited; +end; + +function TtdSession.GetCreatedAt: TDateTime; +begin + Result := FCreatedAt; +end; + +function TtdSession.GetItem(const AKey: string): TValue; +begin + if not FItems.ContainsKey(AKey) then + FItems.Add(AKey, TValue.Empty); + Result := FItems.Items[AKey] +end; + +procedure TtdSession.SetCreatedAt(const Value: TDateTime); +begin + FCreatedAt := Value; +end; + +procedure TtdSession.SetItem(const AKey: string; const Value: TValue); +begin + FItems.AddOrSetValue(AKey, Value); +end; + +{ TtdSesionManager } + +procedure TtdSessionManager.Clear; +begin + FItems.Clear; +end; + +constructor TtdSessionManager.Create; +begin + FItems := TDictionary.Create; +end; + +destructor TtdSessionManager.Destroy; +begin + FItems.Free; + inherited; +end; + +function TtdSessionManager.GetItem(const AID: Int64): ItdSession; +begin + if not FItems.ContainsKey(AID) then + FItems.Add(AID, TtdSession.Create); + Result := FItems.Items[AID] +end; + +class function TtdSessionManager.NewInstance: TObject; +begin + if FInstance = nil then + FInstance := TtdSessionManager(inherited NewInstance); + Result := FInstance; +end; + +procedure TtdSessionManager.SetItem(const AID: Int64; const Value: ItdSession); +begin + FItems.AddOrSetValue(AID, Value); + FItems.Items[AID].CreatedAt := Now; +end; + +end. + diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Helpers.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Helpers.pas new file mode 100644 index 0000000..41e31e9 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Helpers.pas @@ -0,0 +1,385 @@ +unit TinjectTelegram.Helpers; +interface +uses + // TInjectTelegram.Bot.Impl, + TInjectTelegram.Types, + TInjectTelegram.Types.Enums, + System.DateUtils, + System.RegularExpressions; +type + TtdParseModeHelper = record helper for TtdParseMode + function ToString: string; + end; + TAllowedUpdatesHelper = record helper for TAllowedUpdates + function ToString: string; + end; + TSendChatActionHelper = record helper for TtdSendChatAction + function ToJsonString: string; + end; + TPassportDataHelper = record helper for TtdEncryptedPassportElementType + function ToString: string; + end; + TSendDiceHelper = record helper for TtdEmojiType + function ToString: string; + End; + TSendPollHelper = record helper for TtdQuizType + function ToString: string; + End; + TSendHelper = record helper for TtdMessageEntityType + function ToString: string; + end; + TBoolHelper = record helper for Boolean + strict protected const + FalseString: string = 'false'; + TrueString: string = 'true'; + FalseBytes: array[0..4] of Byte = (Ord('f'), Ord('a'), Ord('l'), Ord('s'), Ord('e')); + TrueBytes: array[0..3] of Byte = (Ord('t'), Ord('r'), Ord('u'), Ord('e')); + published + function ToJSONBool: string; + function ToBytes(const Data: TArray; Offset: Integer): Integer; + end; + TtdChatTypeHelper = record helper for TtdChatType + function ToString: string; + end; + TtdBotCommandScopeHelper = record helper for TtdBotCommandScopeType + function ToJsonObject: string; + end; + TTDateTimerHelper = record helper for TDateTime + function ToUnix: Integer; + End; + TtdSituacaoAtendimentoHelper = record helper for TtdSituacaoAtendimento + function ToString: String; + End; + TtdMenuButtonTypeHelper = record helper for TtdMenuButtonType + function ToString: String; + end; + TtdChatMemberStatusHelper = record helper for TtdChatMemberStatus + function ToString: String; + end; + TtdStickerTypeHelper = record helper for TtdStickerType + function ToString: String; + end; + TtdStickerFormatHelper = record helper for TtdStickerFormat + function ToString: String; + End; + +implementation +uses + System.SysUtils, + System.Generics.Collections; +{ TtdParseModeHelper } +function TtdParseModeHelper.ToString: string; +begin + case Self of + TtdParseMode.Default: + Result := ''; + TtdParseMode.Markdown: + Result := 'Markdown'; + TtdParseMode.MarkdownV2: + Result := 'MarkdownV2'; + TtdParseMode.Html: + Result := 'HTML'; + end; +end; +{ TAllowedUpdatesHelper } +function TAllowedUpdatesHelper.ToString: string; +var + LAllowed: TList; +begin + LAllowed := TList.Create; + try + if TAllowedUpdate.Message in Self then + LAllowed.Add('"message"'); + if TAllowedUpdate.Edited_message in Self then + LAllowed.Add('"edited_message"'); + if TAllowedUpdate.Channel_post in Self then + LAllowed.Add('"channel_post"'); + if TAllowedUpdate.Edited_channel_post in Self then + LAllowed.Add('"edited_channel_post"'); + if TAllowedUpdate.Inline_query in Self then + LAllowed.Add('"inline_query"'); + if TAllowedUpdate.Chosen_inline_result in Self then + LAllowed.Add('"chosen_inline_result"'); + if TAllowedUpdate.Callback_query in Self then + LAllowed.Add('"callback_query"'); + if TAllowedUpdate.ShippingQuery in Self then + LAllowed.Add('"shipping_query"'); + if TAllowedUpdate.PreCheckoutQuery in Self then + LAllowed.Add('"pre_checkout_query"'); + if TAllowedUpdate.PollState in Self then + LAllowed.Add('"poll"'); + if TAllowedUpdate.PollAnswer in Self then + LAllowed.Add('"poll_answer"'); + if TAllowedUpdate.MyChatMember in Self then + LAllowed.Add('"my_chat_member"'); + if TAllowedUpdate.ChatMember in Self then + LAllowed.Add('"chat_member"'); + Result := '[' + Result.Join(',', LAllowed.ToArray) + ']'; + finally + LAllowed.Free; + end; +end; +{ TSendChatActionHelper } +function TSendChatActionHelper.ToJsonString: string; +begin + case Self of + TtdSendChatAction.Typing: + Result := 'typing'; + TtdSendChatAction.UploadPhoto: + Result := 'upload_photo'; + TtdSendChatAction.Record_video: + Result := 'record_video'; + TtdSendChatAction.UploadVideo: + Result := 'upload_video'; + TtdSendChatAction.Record_audio: + Result := 'record_audio'; + TtdSendChatAction.Upload_audio: + Result := 'upload_audio'; + TtdSendChatAction.Upload_document: + Result := 'upload_document'; + TtdSendChatAction.Choose_sticker: + Result := 'choose_sticker '; + TtdSendChatAction.Find_location: + Result := 'find_location'; + TtdSendChatAction.Record_video_note: + Result := 'record_video_note'; + TtdSendChatAction.Upload_video_note: + Result := 'upload_video_note'; + end; +end; +{ TPassportDataHelper } +function TPassportDataHelper.ToString: string; +begin + case self of + TtdEncryptedPassportElementType.personal_details: + Result := 'personal_details'; + TtdEncryptedPassportElementType.passport: + Result := 'passport'; + TtdEncryptedPassportElementType.driver_license: + Result := 'driver_license'; + TtdEncryptedPassportElementType.identity_card: + Result := 'identity_card'; + TtdEncryptedPassportElementType.internal_passport: + Result := 'internal_passport'; + TtdEncryptedPassportElementType.address: + Result := 'address'; + TtdEncryptedPassportElementType.utility_bill: + Result := 'utility_bill'; + TtdEncryptedPassportElementType.bank_statement: + Result := 'bank_statement'; + TtdEncryptedPassportElementType.rental_agreement: + Result := 'rental_agreement'; + TtdEncryptedPassportElementType.passport_registration: + Result := 'passport_registration'; + TtdEncryptedPassportElementType.temporary_registration: + Result := 'temporary_registration'; + TtdEncryptedPassportElementType.phone_number: + Result := 'phone_number'; + TtdEncryptedPassportElementType.email: + Result := 'email'; + end; +end; +{ TSendDiceHelper } +function TSendDiceHelper.ToString: string; +begin + case Self of + TtdEmojiType.etDado: + Result := '🎲'; + TtdEmojiType.etDardo: + Result := '🎯'; + TtdEmojiType.etBasquete: + Result := '🏀'; + TtdEmojiType.etFootball: + Result := '⚽'; + TtdEmojiType.etSlotMachine: + Result := '🎰'; + TtdEmojiType.etBowling: + Result := '🎳'; + { TODO 3 -oRuan Diego -cEmojis : +adicionar os novos +⚰️ 🎃 🧛‍♀️ 🧟‍♂️ 🦇 🕷 🕸 🌜 🌛 or 🗿 } + end; +end; +{ TSendPollHelper } +function TSendPollHelper.ToString: string; +begin + case Self of + TtdQuizType.qtPadrao: + result := 'regular'; + TtdQuizType.qtRegular: + result := 'regular'; + TtdQuizType.qtQuiz: + result := 'quiz'; + end; +end; +{ TSendHelper } +function TSendHelper.ToString: string; +begin + case Self of + TtdMessageEntityType.mention: + result := 'mention'; + TtdMessageEntityType.hashtag: + result := 'hashtag'; + TtdMessageEntityType.cashtag: + result := 'cashtag'; + TtdMessageEntityType.bot_command: + result := 'bot_command'; + TtdMessageEntityType.url: + result := 'url'; + TtdMessageEntityType.email: + result := 'email'; + TtdMessageEntityType.phone_number: + result := 'phone_number'; + TtdMessageEntityType.bold: + result := 'bold'; + TtdMessageEntityType.italic: + result := 'italic'; + TtdMessageEntityType.underline: + result := 'underline'; + TtdMessageEntityType.strikethrough: + result := 'strikethrough'; + TtdMessageEntityType.code: + result := 'code'; + TtdMessageEntityType.pre: + result := 'pre'; + TtdMessageEntityType.text_link: + result := 'text_link'; + TtdMessageEntityType.text_mention: + result := 'text_mention'; + TtdMessageEntityType.spoiler: + result := 'spoiler'; + TtdMessageEntityType.N_A: + result := ''; + end; +end; +{ TBoolHelper } +function TBoolHelper.ToBytes(const Data: TArray; + Offset: Integer): Integer; +begin + case Self of + True: + Begin + Move(TrueBytes[0], Data[Offset], Length(TrueBytes)); + Result := Offset + Length(TrueBytes); + End; + + False: + Begin + Move(FalseBytes[0], Data[Offset], Length(FalseBytes)); + Result := Offset + Length(FalseBytes); + End; + end; +end; + +function TBoolHelper.ToJSONBool: string; +begin + case Self of + True: Result := TrueString; + False: Result := FalseString; + end; +end; +{ TtdChatTypeHelper } +function TtdChatTypeHelper.ToString: string; +begin + case Self of + TtdChatType.private: + Result := 'private'; + TtdChatType.Group: + Result := 'Group'; + TtdChatType.Channel: + Result := 'Channel'; + TtdChatType.Supergroup: + Result := 'Supergroup'; + end; +end; +{ TtdBotCommandScopeHelper } +function TtdBotCommandScopeHelper.ToJsonObject: string; +begin +{ TODO 5 -oDiego -cTipos de Dados : Promover a Integração do metodo de leitura de lista de classes para correção deste tipo de dado } + case Self of + TtdBotCommandScopeType.BotCommandScopeDefault: + Result := '{"type":"default"}'; + TtdBotCommandScopeType.BotCommandScopeAllPrivateChats: + Result := '{"type":"all_private_chats"}'; + TtdBotCommandScopeType.BotCommandScopeAllGroupChats: + Result := '{"type":"all_group_chats"}'; + TtdBotCommandScopeType.BotCommandScopeAllChatAdministrators: + Result := '{"type":"all_chat_administrators"}'; + TtdBotCommandScopeType.BotCommandScopeChat: + Result := '{"type":"chat"}'; + TtdBotCommandScopeType.BotCommandScopeChatAdministrators: + Result := '{"type":"chat_administrators"}'; + TtdBotCommandScopeType.BotCommandScopeChatMember: + Result := '{"type":"chat_member"}'; + end; +end; +{ TTDateTimerHelper } +function TTDateTimerHelper.ToUnix: Integer; +begin + Result := DateTimeToUnix(TDateTime(Self)); +end; +{ TtdSituacaoAtendimentoHelper } + +function TtdSituacaoAtendimentoHelper.ToString: String; +begin + case Self of + TtdSituacaoAtendimento.saIndefinido: Result := 'Indefinido'; + TtdSituacaoAtendimento.saNova: Result := 'Nova'; + TtdSituacaoAtendimento.saEmAtendimento: Result := 'EmAtendimento'; + TtdSituacaoAtendimento.saEmEspera: Result := 'EmEspera'; + TtdSituacaoAtendimento.saInativa: Result := 'Inativa'; + TtdSituacaoAtendimento.saFinalizada: Result := 'Finalizada'; + end; +end; + +{ TtdMenuButtonTypeHelper } + +function TtdMenuButtonTypeHelper.ToString: String; +begin + case Self of + TtdMenuButtonType.MenuButtonCommands: Result := 'commands'; + TtdMenuButtonType.MenuButtonWebApp: Result := 'web_app'; + TtdMenuButtonType.MenuButtonDefault: Result := 'default'; + end; +end; + +{ TtdChatMemberStatusHelper } + +function TtdChatMemberStatusHelper.ToString: String; +begin + case Self of + TtdChatMemberStatus.Creator: Result := 'Creator'; + TtdChatMemberStatus.Administrator: Result := 'Administrator'; + TtdChatMemberStatus.Member: Result := 'Member'; + TtdChatMemberStatus.Restricted: Result := 'Restricted'; + TtdChatMemberStatus.Left: Result := 'Left'; + TtdChatMemberStatus.Kicked: Result := 'Kicked'; + end; +end; + +{ TtdStickerTypeHelper } + +function TtdStickerTypeHelper.ToString: String; +begin + case Self of + TtdStickerType.regular: + Result := 'regular'; + TtdStickerType.mask: + Result := 'mask'; + TtdStickerType.custom_emoji: + Result := 'custom_emoji'; + end; +end; + +{ TtdStickerFormatHelper } + +function TtdStickerFormatHelper.ToString: String; +begin + case Self of + TtdStickerFormat.static: Result := 'static'; + TtdStickerFormat.animated: Result := 'animated'; + TtdStickerFormat.video: Result := 'video'; + end; +end; + +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Logger.Old.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Logger.Old.pas new file mode 100644 index 0000000..ba249fd --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Logger.Old.pas @@ -0,0 +1,59 @@ +unit TinjectTelegram.Logger.Old; + +interface + +uses + TinjectTelegram.Logger, + System.SysUtils; + +type + {TInjectTelegramExceptionManagerConsole} + TInjectTelegramExceptionManagerConsole = class(TLogEmpty) + private + FOnLog: TProc; + public + procedure Log(level: TLogLevel; const msg: string; const e: Exception); override; + property OnLog: TProc read FOnLog write FOnLog; + end; + + TtdOnLog = procedure(ASender: TObject; const Level: TLogLevel; const Msg: + string; E: Exception) of object; + + {TInjectTelegramExceptionManagerUI} + TInjectTelegramExceptionManagerUI = class(TLogEmpty) + private + FOnLog: TtdOnLog; + public + procedure Log(level: TLogLevel; const msg: string; const e: Exception); override; + published + property OnLog: TtdOnLog read FOnLog write FOnLog; + end; + +implementation + +{ TInjectTelegramExceptionManagerConsole } + +procedure TInjectTelegramExceptionManagerConsole.Log(level: TLogLevel; const msg: string; + const e: Exception); +begin + inherited; + if Assigned(OnLog) then + OnLog(level, msg, e) + else if level >= TLogLevel.Error then + raise e; +end; + +{ TInjectTelegramExceptionManagerUI } + +procedure TInjectTelegramExceptionManagerUI.Log(level: TLogLevel; const msg: string; const e: + Exception); +begin + inherited; + if Assigned(OnLog) then + OnLog(Self, level, msg, e) + else if level >= TLogLevel.Error then + raise e; +end; + +end. + diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Logger.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Logger.pas new file mode 100644 index 0000000..cf36826 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Logger.pas @@ -0,0 +1,203 @@ +unit TinjectTelegram.Logger; + +interface + +uses + TinjectTelegram.Base, + System.SysUtils; + +type + TLogLevel = (Unknown, Trace, Debug, Text, Info, Warn, Error, Fatal); + + TLogItem = record + Level: TLogLevel; + Message: string; + + end; +{$REGION 'ILogger'} + + ILogger = interface + ['{0FAACA17-5BE8-4676-BD21-C010208C48D5}'] +{$REGION 'Log'} + procedure Log(level: TLogLevel; const msg: string); overload; + procedure Log(level: TLogLevel; const msg: string; const e: Exception); overload; + procedure Log(level: TLogLevel; const fmt: string; const args: array of + const); overload; + procedure Log(level: TLogLevel; const fmt: string; const args: array of + const; const e: Exception); overload; +{$ENDREGION} +{$REGION 'Fatal'} + procedure Fatal(const msg: string); overload; + procedure Fatal(const msg: string; const e: Exception); overload; + procedure Fatal(const fmt: string; const args: array of const); overload; + procedure Fatal(const fmt: string; const args: array of const; const e: + Exception); overload; +{$ENDREGION} +{$REGION 'Error'} + procedure Error(const msg: string); overload; + procedure Error(const msg: string; const e: Exception); overload; + procedure Error(const fmt: string; const args: array of const); overload; + procedure Error(const fmt: string; const args: array of const; const e: + Exception); overload; +{$ENDREGION} +{$REGION 'Enter'} + procedure Enter(const methodName: string); overload; + procedure Enter(const instance: TObject; const methodName: string); overload; +{$ENDREGION} +{$REGION 'Leave'} + procedure Leave(const methodName: string); overload; + procedure Leave(const instance: TObject; const methodName: string); overload; +{$ENDREGION} + end; + + TLogAbstract = class(TInjectTelegramAbstractComponent, ILogger) + public +{$REGION 'Log'} + procedure Log(level: TLogLevel; const msg: string; const e: Exception); + overload; virtual; abstract; + procedure Log(level: TLogLevel; const msg: string); overload; + procedure Log(level: TLogLevel; const fmt: string; const args: array of + const); overload; + procedure Log(level: TLogLevel; const fmt: string; const args: array of + const; const e: Exception); overload; +{$ENDREGION} +{$REGION 'Fatal'} + procedure Fatal(const msg: string); overload; + procedure Fatal(const msg: string; const e: Exception); overload; + procedure Fatal(const fmt: string; const args: array of const); overload; + procedure Fatal(const fmt: string; const args: array of const; const e: + Exception); overload; +{$ENDREGION} +{$REGION 'Error'} + procedure Error(const msg: string); overload; + procedure Error(const msg: string; const e: Exception); overload; + procedure Error(const fmt: string; const args: array of const); overload; + procedure Error(const fmt: string; const args: array of const; const e: + Exception); overload; +{$ENDREGION} +{$REGION 'Enter'} + procedure Enter(const methodName: string); overload; + procedure Enter(const instance: TObject; const methodName: string); overload; + virtual; abstract; +{$ENDREGION} +{$REGION 'Leave'} + procedure Leave(const methodName: string); overload; + procedure Leave(const instance: TObject; const methodName: string); overload; + virtual; abstract; +{$ENDREGION} + end; + + TLogEmpty = class(TLogAbstract) + public + procedure Log(level: TLogLevel; const msg: string; const e: Exception); + overload; override; + procedure Enter(const instance: TObject; const methodName: string); overload; + override; + procedure Leave(const instance: TObject; const methodName: string); overload; + override; + end; + +implementation + + +{ TLogAbstract } +{$REGION 'Log'} + +procedure TLogAbstract.Log(level: TLogLevel; const fmt: string; const args: + array of const; const e: Exception); +begin + Log(level, string.Format(fmt, args), e); +end; + +procedure TLogAbstract.Log(level: TLogLevel; const fmt: string; const args: + array of const); +begin + Log(level, fmt, args, nil); +end; + +procedure TLogAbstract.Log(level: TLogLevel; const msg: string); +begin + Log(level, msg, nil); +end; +{$ENDREGION} +{$REGION 'Fatal'} + +procedure TLogAbstract.Fatal(const msg: string); +begin + Fatal(msg, nil); +end; + +procedure TLogAbstract.Fatal(const msg: string; const e: Exception); +begin + Log(TLogLevel.Fatal, msg, e); +end; + +procedure TLogAbstract.Fatal(const fmt: string; const args: array of const); +begin + Fatal(fmt, args, nil); +end; + +procedure TLogAbstract.Fatal(const fmt: string; const args: array of const; + const e: Exception); +begin + Fatal(string.Format(fmt, args), e); +end; +{$ENDREGION} +{$REGION 'Error'} + +procedure TLogAbstract.Error(const msg: string); +begin + Error(msg, nil); +end; + +procedure TLogAbstract.Error(const msg: string; const e: Exception); +begin + Log(TLogLevel.Error, msg, e); +end; + +procedure TLogAbstract.Error(const fmt: string; const args: array of const); +begin + Error(fmt, args, nil); +end; + +procedure TLogAbstract.Error(const fmt: string; const args: array of const; + const e: Exception); +begin + Error(string.Format(fmt, args), e); +end; +{$ENDREGION} +{$REGION 'Enter'} + +procedure TLogAbstract.Enter(const methodName: string); +begin + Enter(nil, methodName); +end; +{$ENDREGION} +{$REGION 'Leave'} + +procedure TLogAbstract.Leave(const methodName: string); +begin + Leave(nil, methodName); +end; +{$ENDREGION} + +{ TLogEmpty } + +procedure TLogEmpty.Enter(const instance: TObject; const methodName: string); +begin + inherited; +end; + +procedure TLogEmpty.Leave(const instance: TObject; const methodName: string); +begin + inherited; +end; + +procedure TLogEmpty.Log(level: TLogLevel; const msg: string; const e: Exception); +begin + inherited; +// nothing +end; + +end. + diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Ph.Types.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Ph.Types.pas new file mode 100644 index 0000000..f2906d2 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Ph.Types.pas @@ -0,0 +1,284 @@ +unit TinjectTelegram.Ph.Types; + +interface + +uses + TinjectTelegram.Utils.Json; + +type +{$REGION 'Account'} + IphAccount = interface + ['{AA9FE190-6D8B-44C4-9BC0-4A1BCECDFDD5}'] + function short_name: string; + function author_name: string; + function author_url: string; + function access_token: string; + function auth_url: string; + function page_count: Integer; + end; + + TphAccount = class(TBaseJson, IphAccount) + public + function short_name: string; + function author_name: string; + function author_url: string; + function access_token: string; + function auth_url: string; + function page_count: Integer; + end; +{$ENDREGION} + +{$REGION 'Node'} + + IphNode = interface; + + TphContent = TArray; + + IphContentHelper = record helper for TphContent + function ToJson: string; + end; + + IphNode = interface + ['{BC48D648-0A3D-427D-9D3E-E1765DF70932}'] + function Value: string; + function Tag: string; + function attrs: string; + function children: TphContent; + end; + + TphNode = class(TBaseJson, IphNode) + public + function Value: string; + function Tag: string; + function attrs: string; + function children: TphContent; + constructor Create(const ATag, AAttrs: string; AChildren: TphContent); overload; + constructor Create(const AValue: string); overload; + end; +{$ENDREGION} + +{$REGION 'Page'} + + IphPage = interface + ['{80BB10CE-9452-4F2E-914C-BEED76A98DAF}'] + function path: string; + function url: string; + function title: string; + function description: string; + function author_name: string; + function author_url: string; + function image_url: string; + function content: TphContent; + function views: Integer; + function can_edit: Boolean; + end; + + TphPage = class(TBaseJson, IphPage) + public + function path: string; + function url: string; + function title: string; + function description: string; + function author_name: string; + function author_url: string; + function image_url: string; + function content: TphContent; + function views: Integer; + function can_edit: Boolean; + end; +{$ENDREGION} + +{$REGION 'PageList'} + + IphPageList = interface + ['{551C6999-1C7D-4CE6-B44A-25F174A881DF}'] + function total_count: Integer; + function pages: TphContent; + end; + + TphPageList = class(TBaseJson, IphPageList) + public + function total_count: Integer; + function pages: TphContent; + end; +{$ENDREGION} +{$REGION 'PageViews'} + + IphPageViews = interface + ['{EACCDD18-450B-42F6-BF5B-7FACE18D912E}'] + function views: Integer; + end; + + TphPageViews = class(TBaseJson, IphPageViews) + public + function views: Integer; + end; +{$ENDREGION} + +implementation +{$REGION 'Account'} +{ TphAccount } + +function TphAccount.access_token: string; +begin + Result := ReadToSimpleType('access_token'); +end; + +function TphAccount.author_name: string; +begin + Result := ReadToSimpleType('author_name'); +end; + +function TphAccount.author_url: string; +begin + Result := ReadToSimpleType('author_url'); +end; + +function TphAccount.auth_url: string; +begin + Result := ReadToSimpleType('auth_url'); +end; + +function TphAccount.page_count: Integer; +begin + Result := ReadToSimpleType('page_count'); +end; + +function TphAccount.short_name: string; +begin + Result := ReadToSimpleType('short_name'); +end; +{$ENDREGION} +{$REGION 'Node'} +{ TphNode } + +function TphNode.attrs: string; +begin + Result := ReadToSimpleType('attrs'); +end; + +function TphNode.children: TphContent; +begin + Result := ReadToArray(TphNode, 'children'); +end; + +constructor TphNode.Create(const AValue: string); +begin + inherited; + SetJson(AValue); +end; + +constructor TphNode.Create(const ATag, AAttrs: string; AChildren: TphContent); +begin + inherited Create(''); + FJSON.S['tag'] := ATag; + FJSON.S['attrs'] := AAttrs; + FJSON.S['children'] := AChildren.ToJson; +end; + +function TphNode.Tag: string; +begin + Result := ReadToSimpleType('tag'); +end; + +function TphNode.Value: string; +begin + Result := FJSON.ToJSON; +end; +{ IphContentHelper } + +function IphContentHelper.ToJson: string; +var + I: Integer; +begin + Result := '['; + for I := Low(Self) to High(Self) do + if Assigned(Self[I]) then + begin + Result := Result + (Self[I] as TBaseJson).AsJson; + if I <> High(Self) then + Result := Result + ','; + end; + Result := Result + ']'; +end; +{$ENDREGION} +{$REGION 'Page'} + +{ TphPage } + +function TphPage.author_name: string; +begin + Result := ReadToSimpleType('author_name'); +end; + +function TphPage.author_url: string; +begin + Result := ReadToSimpleType('author_url'); +end; + +function TphPage.can_edit: Boolean; +begin + Result := ReadToSimpleType('can_edit'); +end; + +function TphPage.content: TArray; +begin + Result := ReadToArray(TphPage, 'content') +end; + +function TphPage.description: string; +begin + Result := ReadToSimpleType('description'); +end; + +function TphPage.image_url: string; +begin + Result := ReadToSimpleType('image_url'); +end; + +function TphPage.path: string; +begin + Result := ReadToSimpleType('path'); +end; + +function TphPage.title: string; +begin + Result := ReadToSimpleType('title'); +end; + +function TphPage.url: string; +begin + Result := ReadToSimpleType('url'); +end; + +function TphPage.views: Integer; +begin + Result := ReadToSimpleType('views'); +end; +{$ENDREGION} + +{$REGION 'PageList'} +{ TphPageList } + +function TphPageList.pages: TphContent; +begin + Result := ReadToArray(TphNode, 'pages'); +end; + +function TphPageList.total_count: Integer; +begin + Result := ReadToSimpleType('total_count'); +end; +{$ENDREGION} + +{$REGION 'PageViews'} +{ TphPageViews } + +function TphPageViews.views: Integer; +begin + Result := ReadToSimpleType('views'); +end; +{$ENDREGION} + +end. + diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Ph.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Ph.pas new file mode 100644 index 0000000..bd37468 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Ph.pas @@ -0,0 +1,181 @@ +unit TinjectTelegram.Ph; + +interface + +uses + TinjectTelegram.Ph.Types, + TinjectTelegram.Bot.Impl; + +type + TInjectTelegramPh = class(TInjectTelegramBotBase) + protected + procedure DoInitApiCore; override; + public + function createAccount(const ShortName: string; const AuthorName: string = + ''; const AuthorUrl: string = ''): IphAccount; + + function editAccountInfo(const AccessToken: string; const ShortName: string + = ''; const AuthorName: string = ''; const AuthorUrl: string = ''): IphAccount; + + function getAccountInfo(const AccessToken: string): IphAccount; + + function revokeAccessToken(const AccessToken: string): IphAccount; + + function createPage(const AccessToken: string; const title: string; const + author_name: string = ''; const author_url: string = ''; const content: + TphContent = nil; const return_content: Boolean = False): IphPage; + + function editPage(const AccessToken: string; const path: string; const title: + string; const content: TphContent; const author_name: string = ''; const + author_url: string = ''; const return_content: Boolean = False): IphPage; + + function getPage(const path: string; const return_content: Boolean = False): IphPage; + + function getPageList(const access_token: string; const offset: Integer = 0; + const limit: Integer = 50): IphPageList; + + function getViews(const path: string; const year: Integer = 0; const month: + Integer = 0; const day: Integer = 0; const hour: Integer = 0): IphPageViews; + published + property UrlAPI; + end; + +implementation + +uses + TinjectTelegram.Utils.Json, + System.SysUtils, + System.JSON; + +{ TInjectTelegramPh } + +function TInjectTelegramPh.createAccount(const ShortName, AuthorName, AuthorUrl: string): + IphAccount; +begin + Result := TphAccount.Create(// + GetRequest.SetMethod('createAccount')// + .AddParameter('short_name', ShortName, '', True)// + .AddParameter('author_name', AuthorName, '', False)// + .AddParameter('author_url', AuthorUrl, '', False)// + .Execute); +end; + +function TInjectTelegramPh.createPage(const AccessToken, title, author_name, author_url: + string; const content: TphContent; const return_content: Boolean): IphPage; +begin + Result := TphPage.Create(// + GetRequest.SetMethod('createPage')// + .AddParameter('access_token', AccessToken, '', True)// + .AddParameter('title', title, '', True)// + .AddParameter('author_name', author_name, '', False)// + .AddParameter('author_url', author_url, '', False)// + .AddParameter('content', content.ToJson, TphContent(nil).ToJson, False)// + .AddParameter('return_content', return_content, False, False)// + .Execute); +end; + +procedure TInjectTelegramPh.DoInitApiCore; +begin + inherited; + UrlAPI := 'https://api.telegra.ph/'; + GetRequest.DataExtractor := + function(AInput: string): string + var + LJSON: TJSONObject; + begin + Result := ''; + if AInput.IsEmpty or AInput.StartsWith('; virtual; + procedure Go; virtual; + procedure DoOnStart; virtual; abstract; + procedure DoOnStop; virtual; abstract; + public + constructor Create(AOwner: TComponent); overload; override; + constructor Create(ABot: IInjectTelegramBot); reintroduce; overload; + destructor Destroy; override; + procedure Start; + procedure Stop; + [Default(False)] + property IsActive: Boolean read FIsActive write SetIsActive; + published + property Bot: TInjectTelegramBot read FBotDonor write FBotDonor; + [Default(0)] + property MessageOffset: Int64 read FMessageOffset write FMessageOffset; + property AllowedUpdates: TAllowedUpdates read FAllowedUpdates write + FAllowedUpdates default UPDATES_ALLOWED_ALL; + [Default(1000)] + property PollingInterval: Integer read FPollingInterval write FPollingInterval; + end; +implementation +uses TinjectTelegram.Logger; +{ TInjectTelegramBotReceiverBase } +constructor TInjectTelegramBotReceiverBase.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + MessageOffset := 0; + AllowedUpdates := UPDATES_ALLOWED_ALL; + PollingInterval := 1000; +end; +constructor TInjectTelegramBotReceiverBase.Create(ABot: IInjectTelegramBot); +begin + Self.Create(nil); + FBotDonor := ABot as TInjectTelegramBot; +end; +destructor TInjectTelegramBotReceiverBase.Destroy; +begin + // FBotDonor.Free; + Stop; + inherited; +end; +procedure TInjectTelegramBotReceiverBase.Go; +var + LUpdates: TArray; +begin + DoOnStart; + while FIsActive do + begin + try + Self.Bot.Logger.Enter(Self, 'Go'); + LUpdates := ReadUpdates; + if Length(LUpdates) = 0 then + begin + Sleep(FPollingInterval); + Continue; + end; + MessageOffset := LUpdates[High(LUpdates)].ID + 1; + EventParser(LUpdates); + Sleep(FPollingInterval); + Self.Bot.Logger.Leave(Self, 'Go'); + except on E: Exception do + Begin + Bot.Logger.Fatal('Go', E); + //Independente do tipo de erro que o bot encontre, + //ele nunca para de responder a novas solicitações + continue; + End; + end; + end; + DoOnStop; +end; +function TInjectTelegramBotReceiverBase.ReadUpdates: TArray; +var + LBot: TInjectTelegramBot; +begin + LBot := TInjectTelegramBot.Create(Self); + try + Bot.Logger.Enter(Self, 'ReadUpdates'); + FBotDonor.AssignTo(LBot); + Result := LBot.GetUpdates(MessageOffset, 100, 0, AllowedUpdates); + Bot.Logger.Leave(Self, 'ReadUpdates'); + except + on E: Exception do + Bot.Logger.Fatal('TInjectTelegramBotReceiverBase.ReadUpdates', E) + end; +end; +procedure TInjectTelegramBotReceiverBase.SetIsActive(const AValue: Boolean); +begin + if FIsActive = AValue then + Exit; + FIsActive := AValue; + if AValue then + begin + FThread := TThread.CreateAnonymousThread(Go); + FThread.FreeOnTerminate := False; + FThread.Start; + end + else + FreeAndNil(FThread); +end; +procedure TInjectTelegramBotReceiverBase.Start; +begin + IsActive := True; +end; +procedure TInjectTelegramBotReceiverBase.Stop; +begin + IsActive := False; +end; +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.Console.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.Console.pas new file mode 100644 index 0000000..abf03c0 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.Console.pas @@ -0,0 +1,176 @@ +unit TinjectTelegram.Receiver.Console; +interface +uses + TInjectTelegram.Receiver.Base, + TInjectTelegram.Types, + System.SysUtils; +type + TInjectTelegramReceiverConsole = class(TInjectTelegramBotReceiverBase) + private + FOnStart: TProc; + FOnStop: TProc; + FOnUpdates: TProc>; + FOnUpdate: TProc; + FOnMessage: TProc; + FOnInlineQuery: TProc; + FOnChosenInlineResult: TProc; + FOnEditedMessage: TProc; + FOnChannelPost: TProc; + FOnEditedChannelPost: TProc; + FOnShippingQuery: TProc; + FOnPreCheckoutQuery: TProc; + FOnOnCallbackQuery: TProc; + FOnPollStatus: TProc; + FOnPollAnswer: TProc; + FOnMyChatMember: TProc; + FOnChatMember: TProc; + protected + procedure DoOnStart; override; + procedure DoOnStop; override; + procedure DoOnUpdates(AUpdates: TArray); override; + procedure DoOnUpdate(AUpdate: ItdUpdate); override; + procedure DoOnMessage(AMessage: ItdMessage); override; + procedure DoOnInlineQuery(AInlineQuery: ItdInlineQuery); override; + procedure DoOnChosenInlineResult(AChosenInlineResult: ItdChosenInlineResult); override; + procedure DoOnEditedMessage(AEditedMessage: ItdMessage); override; + procedure DoOnChannelPost(AChannelPost: ItdMessage); override; + procedure DoOnEditedChannelPost(AEditedChannelPost: ItdMessage); override; + procedure DoOnShippingQuery(AShippingQuery: ItdShippingQuery); override; + procedure DoOnPreCheckoutQuery(APreCheckoutQuery: ItdPreCheckoutQuery); override; + procedure DoOnCallbackQuery(ACallbackQuery: ItdCallbackQuery); override; + procedure DoOnPollStatus(APoll: ItdPoll); override; + procedure DoOnPollAnswer(APollAnswer: ItdPollAnswer); override; + procedure DoOnMyChatMember(AMyChatMember: ItdChatMemberUpdated); override; + procedure DoOnChatMember(AChatMember: ItdChatMemberUpdated); override; + public + property OnStart: TProc read FOnStart write FOnStart; + property OnStop: TProc read FOnStop write FOnStop; + property OnUpdates: TProc> read FOnUpdates write FOnUpdates; + property OnUpdate: TProc read FOnUpdate write FOnUpdate; + property OnMessage: TProc read FOnMessage write FOnMessage; + property OnInlineQuery: TProc read FOnInlineQuery write FOnInlineQuery; + property OnChosenInlineResult: TProc read FOnChosenInlineResult write FOnChosenInlineResult; + property OnEditedMessage: TProc read FOnEditedMessage write FOnEditedMessage; + property OnChannelPost: TProc read FOnChannelPost write FOnChannelPost; + property OnEditedChannelPost: TProc read FOnEditedChannelPost write FOnEditedChannelPost; + property OnShippingQuery: TProc read FOnShippingQuery write FOnShippingQuery; + property OnPreCheckoutQuery: TProc read FOnPreCheckoutQuery write FOnPreCheckoutQuery; + property OnCallbackQuery: TProc read FOnOnCallbackQuery write FOnOnCallbackQuery; + property OnPollStatus: TProc read FOnPollStatus write FOnPollStatus; + property OnPollAnswer: TProc read FOnPollAnswer write FOnPollAnswer; + property OnMyChatMember: TProc read FOnMyChatMember write FOnMyChatMember; + property OnChatMember: TProc read FOnChatMember write FOnChatMember; + end; +implementation +{ TInjectTelegramReceiverConsole } +procedure TInjectTelegramReceiverConsole.DoOnCallbackQuery(ACallbackQuery: ItdCallbackQuery); +begin + inherited; + if Assigned(OnCallbackQuery) then + OnCallbackQuery(ACallbackQuery); +end; +procedure TInjectTelegramReceiverConsole.DoOnChannelPost(AChannelPost: ItdMessage); +begin + inherited; + if Assigned(OnChannelPost) then + OnChannelPost(AChannelPost); +end; +procedure TInjectTelegramReceiverConsole.DoOnChatMember( + AChatMember: ItdChatMemberUpdated); +begin + inherited; + if Assigned(OnChatMember) then + OnChatMember(AChatMember); +end; + +procedure TInjectTelegramReceiverConsole.DoOnChosenInlineResult(AChosenInlineResult: ItdChosenInlineResult); +begin + inherited; + if Assigned(OnChosenInlineResult) then + OnChosenInlineResult(AChosenInlineResult); +end; +procedure TInjectTelegramReceiverConsole.DoOnEditedChannelPost(AEditedChannelPost: ItdMessage); +begin + inherited; + if Assigned(OnEditedChannelPost) then + OnEditedChannelPost(AEditedChannelPost); +end; +procedure TInjectTelegramReceiverConsole.DoOnEditedMessage(AEditedMessage: ItdMessage); +begin + inherited; + if Assigned(OnEditedMessage) then + OnEditedMessage(AEditedMessage); +end; +procedure TInjectTelegramReceiverConsole.DoOnInlineQuery(AInlineQuery: ItdInlineQuery); +begin + inherited; + if Assigned(OnInlineQuery) then + OnInlineQuery(AInlineQuery); +end; +procedure TInjectTelegramReceiverConsole.DoOnMessage(AMessage: ItdMessage); +begin + inherited; + if Assigned(OnMessage) then + OnMessage(AMessage); +end; +procedure TInjectTelegramReceiverConsole.DoOnMyChatMember( + AMyChatMember: ItdChatMemberUpdated); +begin + inherited; + if Assigned(OnMyChatMember) then + OnMyChatMember(AMyChatMember); +end; + +procedure TInjectTelegramReceiverConsole.DoOnPollAnswer( + APollAnswer: ItdPollAnswer); +begin + inherited; + if Assigned(OnPollAnswer) then + OnPollAnswer(APollAnswer); +end; + +procedure TInjectTelegramReceiverConsole.DoOnPollStatus( + APoll: ItdPoll); +begin + inherited; + if Assigned(OnPollStatus) then + OnPollStatus(APoll); +end; + +procedure TInjectTelegramReceiverConsole.DoOnPreCheckoutQuery(APreCheckoutQuery: ItdPreCheckoutQuery); +begin + inherited; + if Assigned(OnPreCheckoutQuery) then + OnPreCheckoutQuery(APreCheckoutQuery); +end; +procedure TInjectTelegramReceiverConsole.DoOnShippingQuery(AShippingQuery: ItdShippingQuery); +begin + inherited; + if Assigned(OnShippingQuery) then + OnShippingQuery(AShippingQuery); +end; +procedure TInjectTelegramReceiverConsole.DoOnStart; +begin + inherited; + if Assigned(OnStart) then + OnStart(); +end; +procedure TInjectTelegramReceiverConsole.DoOnStop; +begin + inherited; + if Assigned(OnStop) then + OnStop(); +end; +procedure TInjectTelegramReceiverConsole.DoOnUpdate(AUpdate: ItdUpdate); +begin + inherited; + if Assigned(OnUpdate) then + OnUpdate(AUpdate); +end; +procedure TInjectTelegramReceiverConsole.DoOnUpdates(AUpdates: TArray); +begin + inherited; + if Assigned(OnUpdates) then + OnUpdates(AUpdates); +end; +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.Manager.Base.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.Manager.Base.pas new file mode 100644 index 0000000..77dac5b --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.Manager.Base.pas @@ -0,0 +1,164 @@ +unit TinjectTelegram.Receiver.Manager.Base; +interface +uses + System.Classes, + System.SysUtils, + System.Generics.Collections, + TInjectTelegram.UpdateParser, + TInjectTelegram.Bot, + TInjectTelegram.Bot.Impl, + TInjectTelegram.Types, + TInjectTelegram.Types.Enums, + TInjectTelegram.Bot.Chat; +type + TtdOnRuning = procedure(AChatBot: TInjectTelegramChat) of object; + + TtdOnUpdate = procedure(ASender: TObject; AUpdate: ItdUpdate) of object; + TtdOnUpdates = procedure(ASender: TObject; AUpdates: TArray) of object; + TtdOnMessage = procedure(ASender: TObject; AMessage: ItdMessage) of object; + TtdOnInlineQuery = procedure(ASender: TObject; AInlineQuery: ItdInlineQuery) of object; + TtdOnInlineResultChosen = procedure(ASender: TObject; AChosenInlineResult: ItdChosenInlineResult) of object; + TtdOnCallbackQuery = procedure(ASender: TObject; ACallbackQuery: ItdCallbackQuery) of object; + TtdOnChannelPost = procedure(ASender: TObject; AChanelPost: ItdMessage) of object; + TtdOnShippingQuery = procedure(ASender: TObject; AShippingQuery: ItdShippingQuery) of object; + TtdOnPreCheckoutQuery = procedure(ASender: TObject; APreCheckoutQuery: ItdPreCheckoutQuery) of object; + TtdOnPollStatus = procedure(ASender: TObject; APoll: ItdPoll) of object; + TtdOnPollAnswer = procedure(ASender: TObject; APollAnswer: ItdPollAnswer) of object; + TtdOnMyChatMember = procedure(ASender: TObject; AMyChatMember: ItdChatMemberUpdated) of object; + TtdOnChatMember = procedure(ASender: TObject; AChatMember: ItdChatMemberUpdated) of object; + TtdOnMessageEntityReceiver = procedure(ASender: TObject; AMessageEntityType: TtdMessageEntityType) of object; + TtdOnWebAppData = procedure(ASender: TObject; AWebAppData: ItdWebAppData) of object; + + {TInjectTelegramBotReceiverManagerBase} + TInjectTelegramBotReceiverManagerBase = class(TInjectTelegramBotUpdateParser) + private + FBotDonor: TInjectTelegramBot; + FAllowedUpdates: TAllowedUpdates; + FMessageOffset: Int64; + FPollingInterval: Integer; + FThread: TThread; + FIsActive: Boolean; + FConversas: TObjectList; + FConversa: TInjectTelegramChat; procedure SetIsActive(const AValue: Boolean); + protected + function ReadUpdates: TArray; virtual; + procedure Go; virtual; + //Ruan Diego + procedure DoOnRuning(AChatBot: TInjectTelegramChat); virtual; abstract; + procedure DoOnStart; virtual; abstract; + procedure DoOnStop; virtual; abstract; + procedure DoOnUpdates(AUpdates: TArray); virtual; abstract; + procedure DoOnUpdate(AUpdate: ItdUpdate); virtual; abstract; + procedure DoOnMessage(AMessage: ItdMessage); virtual; abstract; + procedure DoOnInlineQuery(AInlineQuery: ItdInlineQuery); virtual; abstract; + procedure DoOnChosenInlineResult(AChosenInlineResult: ItdChosenInlineResult); virtual; abstract; + procedure DoOnEditedMessage(AEditedMessage: ItdMessage); virtual; abstract; + procedure DoOnChannelPost(AChannelPost: ItdMessage); virtual; abstract; + procedure DoOnEditedChannelPost(AEditedChannelPost: ItdMessage); virtual; abstract; + procedure DoOnShippingQuery(AShippingQuery: ItdShippingQuery); virtual; abstract; + procedure DoOnPreCheckoutQuery(APreCheckoutQuery: ItdPreCheckoutQuery); virtual; abstract; + procedure DoOnCallbackQuery(ACallbackQuery: ItdCallbackQuery); virtual; abstract; + procedure DoOnPollStatus(APoll: ItdPoll); virtual; abstract; + procedure DoOnPollAnswer(APollAnswer: ItdPollAnswer); virtual; abstract; + procedure DoOnChatJoinRequest(AChatJoinRequest: ItdChatJoinRequest); virtual; abstract; + procedure DoOnMyChatMember(AMyChatMember: ItdChatMemberUpdated); virtual; abstract; + procedure DoOnChatMember(AChatMember: ItdChatMemberUpdated); virtual; abstract; + procedure DoOnMessageEntityReceiver(AMessageEntityReceiver: TtdMessageEntityType); virtual; abstract; + procedure DoOnWebAppData(AWebAppData: ItdWebAppData); virtual; abstract; + procedure Init; virtual; abstract; + public + constructor Create(AOwner: TComponent); overload; override; + constructor Create(ABot: IInjectTelegramBot); reintroduce; overload; + destructor Destroy; override; + procedure Start; + procedure Stop; + [Default(False)] + property IsActive: Boolean read FIsActive write SetIsActive; + property Conversas: TObjectList read FConversas; + property Conversa: TInjectTelegramChat read FConversa write FConversa; + published + property Bot: TInjectTelegramBot read FBotDonor write FBotDonor; + [Default(0)] + property MessageOffset: Int64 read FMessageOffset write FMessageOffset; + property AllowedUpdates: TAllowedUpdates read FAllowedUpdates write + FAllowedUpdates default UPDATES_ALLOWED_ALL; + [Default(1000)] + property PollingInterval: Integer read FPollingInterval write FPollingInterval; + end; +implementation + +{ TInjectTelegramBotReceiverManagerBase } +constructor TInjectTelegramBotReceiverManagerBase.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + MessageOffset := 0; + AllowedUpdates := UPDATES_ALLOWED_ALL; + PollingInterval := 1000; +end; +constructor TInjectTelegramBotReceiverManagerBase.Create(ABot: IInjectTelegramBot); +begin + Self.Create(nil); + FBotDonor := ABot as TInjectTelegramBot; +end; +destructor TInjectTelegramBotReceiverManagerBase.Destroy; +begin + // FBotDonor.Free; + Stop; + inherited; +end; +procedure TInjectTelegramBotReceiverManagerBase.Go; +var + LUpdates: TArray; +begin + DoOnStart; + while FIsActive do + begin + DoOnRuning(FConversa); + LUpdates := ReadUpdates; + if Length(LUpdates) = 0 then + begin + Sleep(FPollingInterval); + Continue; + end; + MessageOffset := LUpdates[High(LUpdates)].ID + 1; + EventParser(LUpdates); + Sleep(FPollingInterval); + end; + DoOnStop; +end; +function TInjectTelegramBotReceiverManagerBase.ReadUpdates: TArray; +var + LBot: TInjectTelegramBot; +begin + LBot := TInjectTelegramBot.Create(Self); + try + FBotDonor.AssignTo(LBot); + Result := LBot.GetUpdates(MessageOffset, 100, 0, AllowedUpdates); + except + on E: Exception do + Bot.Logger.Fatal('TInjectTelegramBotReceiverManagerBase.ReadUpdates', E) + end; +end; +procedure TInjectTelegramBotReceiverManagerBase.SetIsActive(const AValue: Boolean); +begin + if FIsActive = AValue then + Exit; + FIsActive := AValue; + if AValue then + begin + FThread := TThread.CreateAnonymousThread(Go); + FThread.FreeOnTerminate := False; + FThread.Start; + end + else + FreeAndNil(FThread); +end; +procedure TInjectTelegramBotReceiverManagerBase.Start; +begin + IsActive := True; +end; +procedure TInjectTelegramBotReceiverManagerBase.Stop; +begin + IsActive := False; +end; +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.Service.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.Service.pas new file mode 100644 index 0000000..afe4962 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.Service.pas @@ -0,0 +1,233 @@ +unit TinjectTelegram.Receiver.Service; +interface +uses + System.Classes, + TInjectTelegram.Receiver.Base, + TInjectTelegram.Types.Enums, + TInjectTelegram.Types; +type + TtdOnUpdate = procedure(ASender: TObject; AUpdate: ItdUpdate) of object; + TtdOnUpdates = procedure(ASender: TObject; AUpdates: TArray) of object; + TtdOnMessage = procedure(ASender: TObject; AMessage: ItdMessage) of object; + TtdOnInlineQuery = procedure(ASender: TObject; AInlineQuery: ItdInlineQuery) of object; + TtdOnInlineResultChosen = procedure(ASender: TObject; AChosenInlineResult: ItdChosenInlineResult) of object; + TtdOnCallbackQuery = procedure(ASender: TObject; ACallbackQuery: ItdCallbackQuery) of object; + TtdOnChannelPost = procedure(ASender: TObject; AChanelPost: ItdMessage) of object; + TtdOnShippingQuery = procedure(ASender: TObject; AShippingQuery: ItdShippingQuery) of object; + TtdOnPreCheckoutQuery = procedure(ASender: TObject; APreCheckoutQuery: ItdPreCheckoutQuery) of object; + TtdOnPollStatus = procedure(ASender: TObject; APoll: ItdPoll) of object; + TtdOnPollAnswer = procedure(ASender: TObject; APollAnswer: ItdPollAnswer) of object; + TtdOnMyChatMember = procedure(ASender: TObject; AMyChatMember: ItdChatMemberUpdated) of object; + TtdOnChatMember = procedure(ASender: TObject; AChatMember: ItdChatMemberUpdated) of object; + TtdOnChatJoinRequest = procedure(ASender: TObject; AChatJoinRequest: ItdChatJoinRequest) of object; + TtdOnMessageEntityReceiver = procedure(ASender: TObject; AMessageEntityType: TtdMessageEntityType) of object; + TtdOnWebAppData = procedure(ASender: TObject; AWebAppData: ItdWebAppData) of object; + + TInjectTelegramReceiverService = class(TInjectTelegramBotReceiverBase) + private + FOnUpdate: TtdOnUpdate; + FOnMessage: TtdOnMessage; + FOnUpdates: TtdOnUpdates; + FOnStop: TNotifyEvent; + FOnStart: TNotifyEvent; + FOnEditedMessage: TtdOnMessage; + FOnChannelPost: TtdOnMessage; + FOnPreCheckoutQuery: TtdOnPreCheckoutQuery; + FOnInlineQuery: TtdOnInlineQuery; + FOnShippingQuery: TtdOnShippingQuery; + FOnChosenInlineResult: TtdOnInlineResultChosen; + FOnEditedChannelPost: TtdOnMessage; + FOnCallbackQuery: TtdOnCallbackQuery; + FOnPollStatus: TtdOnPollStatus; + FOnPollAnswer: TtdOnPollAnswer; + FOnMyChatMember: TtdOnMyChatMember; + FOnChatMember: TtdOnChatMember; + FOnChatJoinRequest: TtdOnChatJoinRequest; + FOnMessageEntityReceiver: TtdOnMessageEntityReceiver; + FOnWebAppData: TtdOnWebAppData; + protected + procedure DoOnStart; override; + procedure DoOnStop; override; + procedure DoOnUpdates(AUpdates: TArray); override; + procedure DoOnUpdate(AUpdate: ItdUpdate); override; + procedure DoOnMessage(AMessage: ItdMessage); override; + procedure DoOnInlineQuery(AInlineQuery: ItdInlineQuery); override; + procedure DoOnChosenInlineResult(AChosenInlineResult: ItdChosenInlineResult); override; + procedure DoOnEditedMessage(AEditedMessage: ItdMessage); override; + procedure DoOnChannelPost(AChannelPost: ItdMessage); override; + procedure DoOnEditedChannelPost(AEditedChannelPost: ItdMessage); override; + procedure DoOnShippingQuery(AShippingQuery: ItdShippingQuery); override; + procedure DoOnPreCheckoutQuery(APreCheckoutQuery: ItdPreCheckoutQuery); override; + procedure DoOnCallbackQuery(ACallbackQuery: ItdCallbackQuery); override; + procedure DoOnPollStatus(APoll: ItdPoll); override; + procedure DoOnPollAnswer(APollAnswer: ItdPollAnswer); override; + procedure DoOnMyChatMember(AMyChatMember: ItdChatMemberUpdated); override; + procedure DoOnChatMember(AChatMember: ItdChatMemberUpdated); override; + procedure DoOnChatJoinRequest(AChatJoinRequest: ItdChatJoinRequest); override; + procedure DoOnMessageEntityReceiver(AMessageEntityReceiver: TtdMessageEntityType); override; + procedure DoOnWebAppData(AWebAppData: ItdWebAppData); override; + published + property OnStart: TNotifyEvent read FOnStart write FOnStart; + property OnStop: TNotifyEvent read FOnStop write FOnStop; + property OnUpdates: TtdOnUpdates read FOnUpdates write FOnUpdates; + property OnUpdate: TtdOnUpdate read FOnUpdate write FOnUpdate; + property OnMessage: TtdOnMessage read FOnMessage write FOnMessage; + property OnInlineQuery: TtdOnInlineQuery read FOnInlineQuery write FOnInlineQuery; + property OnChosenInlineResult: TtdOnInlineResultChosen read FOnChosenInlineResult write FOnChosenInlineResult; + property OnEditedMessage: TtdOnMessage read FOnEditedMessage write FOnEditedMessage; + property OnChannelPost: TtdOnMessage read FOnChannelPost write FOnChannelPost; + property OnEditedChannelPost: TtdOnMessage read FOnEditedChannelPost write FOnEditedChannelPost; + property OnShippingQuery: TtdOnShippingQuery read FOnShippingQuery write FOnShippingQuery; + property OnPreCheckoutQuery: TtdOnPreCheckoutQuery read FOnPreCheckoutQuery write FOnPreCheckoutQuery; + property OnCallbackQuery: TtdOnCallbackQuery read FOnCallbackQuery write FOnCallbackQuery; + property OnPollStatus: TtdOnPollStatus read FOnPollStatus write FOnPollStatus; + property OnPollAnswer: TtdOnPollAnswer read FOnPollAnswer write FOnPollAnswer; + property OnMyChatMember: TtdOnMyChatMember read FOnMyChatMember write FOnMyChatMember; + property OnChatMember: TtdOnChatMember read FOnChatMember write FOnChatMember; + property OnChatJoinRequest: TtdOnChatJoinRequest read FOnChatJoinRequest write FOnChatJoinRequest; + property OnMessageEntityReceiver : TtdOnMessageEntityReceiver read FOnMessageEntityReceiver write FOnMessageEntityReceiver; + property OnWebAppData: TtdOnWebAppData read FOnWebAppData write FOnWebAppData; + end; +implementation +{ TInjectTelegramReceiverService } +procedure TInjectTelegramReceiverService.DoOnCallbackQuery(ACallbackQuery: ItdCallbackQuery); +begin + inherited; + if Assigned(OnCallbackQuery) then + OnCallbackQuery(Self, ACallbackQuery); +end; +procedure TInjectTelegramReceiverService.DoOnChannelPost(AChannelPost: ItdMessage); +begin + inherited; + if Assigned(OnChannelPost) then + OnChannelPost(Self, AChannelPost); +end; +procedure TInjectTelegramReceiverService.DoOnChatJoinRequest( + AChatJoinRequest: ItdChatJoinRequest); +begin + inherited; + if Assigned(OnChatJoinRequest) then + OnChatJoinRequest(Self, AChatJoinRequest); +end; +procedure TInjectTelegramReceiverService.DoOnChatMember( + AChatMember: ItdChatMemberUpdated); +begin + inherited; + if Assigned(OnChatMember) then + OnChatMember(Self, AChatMember); +end; +procedure TInjectTelegramReceiverService.DoOnChosenInlineResult(AChosenInlineResult: ItdChosenInlineResult); +begin + inherited; + if Assigned(OnChosenInlineResult) then + OnChosenInlineResult(Self, AChosenInlineResult); +end; +procedure TInjectTelegramReceiverService.DoOnEditedChannelPost(AEditedChannelPost: ItdMessage); +begin + inherited; + if Assigned(OnEditedChannelPost) then + OnEditedChannelPost(Self, AEditedChannelPost); +end; +procedure TInjectTelegramReceiverService.DoOnEditedMessage(AEditedMessage: ItdMessage); +begin + inherited; + if Assigned(OnEditedMessage) then + OnEditedMessage(Self, AEditedMessage); +end; +procedure TInjectTelegramReceiverService.DoOnInlineQuery(AInlineQuery: ItdInlineQuery); +begin + inherited; + if Assigned(OnInlineQuery) then + OnInlineQuery(Self, AInlineQuery); +end; +procedure TInjectTelegramReceiverService.DoOnMessage(AMessage: ItdMessage); +begin + inherited; + if Assigned(OnMessage) then + OnMessage(Self, AMessage); +end; +procedure TInjectTelegramReceiverService.DoOnMessageEntityReceiver( + AMessageEntityReceiver: TtdMessageEntityType); +begin + inherited; + if Assigned(OnMessageEntityReceiver) then + OnMessageEntityReceiver(Self, AMessageEntityReceiver); +end; + +procedure TInjectTelegramReceiverService.DoOnMyChatMember( + AMyChatMember: ItdChatMemberUpdated); +begin + inherited; + if Assigned(OnMyChatMember) then + OnMyChatMember(Self, AMyChatMember); +end; +procedure TInjectTelegramReceiverService.DoOnPollAnswer( + APollAnswer: ItdPollAnswer); +begin + inherited; + if Assigned(OnPollAnswer) then + OnPollAnswer(Self, APollAnswer); +end; +procedure TInjectTelegramReceiverService.DoOnPollStatus( + APoll: ItdPoll); +begin + inherited; + if Assigned(OnPollStatus) then + OnPollStatus(Self, APoll); +end; +procedure TInjectTelegramReceiverService.DoOnPreCheckoutQuery(APreCheckoutQuery: ItdPreCheckoutQuery); +begin + inherited; + if Assigned(OnPreCheckoutQuery) then + OnPreCheckoutQuery(Self, APreCheckoutQuery); +end; +procedure TInjectTelegramReceiverService.DoOnShippingQuery(AShippingQuery: ItdShippingQuery); +begin + inherited; + if Assigned(OnShippingQuery) then + OnShippingQuery(Self, AShippingQuery); +end; +procedure TInjectTelegramReceiverService.DoOnStart; +begin + inherited; + if Assigned(OnStart) then + OnStart(Self); +end; +procedure TInjectTelegramReceiverService.DoOnStop; +begin + inherited; + if Assigned(OnStop) then + OnStop(Self); +end; +procedure TInjectTelegramReceiverService.DoOnUpdate(AUpdate: ItdUpdate); +begin + inherited; + if Assigned(OnUpdate) then + OnUpdate(Self, AUpdate); +end; +procedure TInjectTelegramReceiverService.DoOnUpdates(AUpdates: TArray); +begin + inherited; + if Assigned(OnUpdates) then + OnUpdates(Self, AUpdates); +end; +procedure TInjectTelegramReceiverService.DoOnWebAppData( + AWebAppData: ItdWebAppData); +begin + inherited; + if Assigned(OnWebAppData) then + OnWebAppData(Self, AWebAppData); +end; + +end.procedure TInjectTelegramReceiverService.SetOnChatMember( + const Value: TtdOnChatMember); +begin + FOnChatMember := Value; +end; + +procedure TInjectTelegramReceiverService.SetOnMyChatMember( + const Value: TtdOnMyChatMember); +begin + FOnMyChatMember := Value; +end; + diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.UI.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.UI.pas new file mode 100644 index 0000000..7e73521 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Receiver.UI.pas @@ -0,0 +1,31 @@ +unit TinjectTelegram.Receiver.UI; + +interface + +uses + TInjectTelegram.Types, + TInjectTelegram.Receiver.Service; + +type + TInjectTelegramReceiverUI = class(TInjectTelegramReceiverService) + protected + procedure EventParser(AUpdates: System.TArray); override; + end; + +implementation + +uses + System.Classes; +{ TInjectTelegramReceiverUI } + +procedure TInjectTelegramReceiverUI.EventParser(AUpdates: System.TArray); +begin + TThread.Synchronize(nil, + procedure + begin + inherited EventParser(AUpdates); + end); +end; + +end. + diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.RegisterIDE.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.RegisterIDE.pas new file mode 100644 index 0000000..19ebac1 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.RegisterIDE.pas @@ -0,0 +1,44 @@ +unit TinjectTelegram.RegisterIDE; + +interface + +procedure Register; + +implementation + +{ /$DEFINE REG_IN_LOAD } + +uses +{$IFDEF REG_IN_LOAD} + VCL.Graphics, + ToolsAPI, +{$ENDIF} + System.Classes, + {Add new components here} + TInjectTelegram.Receiver.UI, + TInjectTelegram.Logger.Old, + TInjectTelegram.Bot.Impl, + TInjectTelegram.Receiver.Service, + TInjectTelegram.Types.Enums, + TInjectTelegram.Ph, + TInjectTelegram.Bot.Manager; + +{$IFDEF REG_IN_LOAD} +{$ENDIF} + +procedure Register; +begin +{$IFDEF REG_IN_LOAD} + RegisterWithSplashScreen; +{$ENDIF} + RegisterComponents('InjectTelegram', [ + TInjectTelegramBot, + TInjectTelegramPh, + TInjectTelegramExceptionManagerUI, + TInjectTelegramReceiverService, + TInjectTelegramReceiverUI, + TInjectTelegramBotManager]); +end; + +end. + diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.Enums.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.Enums.pas new file mode 100644 index 0000000..dc7193f --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.Enums.pas @@ -0,0 +1,602 @@ +unit TinjectTelegram.Types.Enums; +interface +type +{$SCOPEDENUMS ON} + TtdEtapasAtendimento = ( + pvListarMenu = 0, + pvInserirItem = 1, + pvRemoverItem = 2, + pvAtualizarLista = 3, + pvLocalizacao = 4, + pvFormaPG = 5, + pvConfirmaRemocao = 6); + + TtdTipoArquivo = ( + taAudio = 14, + taVideo = 13, + taVoice = 12, + taVideoNote = 11, + taLocation = 10, + taVenue = 9, + taContact = 8, + taChatAction = 7, + taInvoice = 6, + taGame = 5, + taSticker = 4, + taMediaGroup = 3, + taTexto = 2, + taDocumento = 1, + taImagem = 0); + + TtdEndereco = record + IdEndereco : Integer; + Endereco : String; + PontoReferencia : String; + Latitude : Single; + Longetude : Single; + end; + + TtdTipoUsuario = (tpCliente, tpAdm); + + TtdSituacaoAtendimento = (saIndefinido, + saNova, + saEmAtendimento, + saEmEspera, + saInativa, + saFinalizada, + saEmFila, + saAguardandoEntrega, + saEntregue, + saFalha); + + /// + /// Type of action to broadcast. + /// + /// + /// We only recommend using this method when a response from the bot will + /// take a noticeable amount of time to arrive. + /// + /// + /// Example: The ImageBot needs some time to process a request and upload + /// the image. Instead of sending a text message along the lines of + /// “Retrieving image, please wait…”, the bot may use sendChatAction with + /// action = upload_photo. The user will see a “sending photo” status for + /// the bot. + /// + TtdSendChatAction = ( + /// + /// for text messages + /// + Typing, + /// + /// for photos + /// + UploadPhoto, + /// + /// for videos + /// + Record_video, + /// + /// for videos + /// + UploadVideo, + /// + /// for audio files + /// + Record_audio, + /// + /// for audio files + /// + Upload_audio, + /// + /// for general files + /// + Upload_document, + /// + /// for stickers + /// + Choose_sticker, + /// + /// for location data + /// + Find_location, + /// + /// for video notes + /// + Record_video_note, + /// + /// for video notes + /// + Upload_video_note); + /// + /// ChatMember status + /// + TtdChatMemberStatus = ( + /// + /// Creator of the + /// + Creator, + /// + /// Administrator of the + /// + Administrator, + /// + /// Normal member of the + /// + Member, Restricted, + /// + /// A who left the + /// + Left, + /// + /// A who was kicked from the + /// + Kicked); + /// + /// Type of a + /// + /// + /// Criado por Ruan Diego Lacerda Menezes + TtdQuizType = ( + /// + /// Define o modo regular + /// + qtPadrao, + /// + /// Define o modo regular + /// + qtRegular, + /// + /// Define o modo quiz + /// + qtQuiz); + /// Criado por Ruan Diego Lacerda Menezes + { TODO 3 -oRuan Diego -cEmojis : +adicionar os novos +⚰️ 🎃 🧛‍♀️ 🧟‍♂️ 🦇 🕷 🕸 🌜 🌛 or 🗿 } + TtdEmojiType = ( + /// + /// Define o emoji dice + /// + etDado, + /// + /// Define o emoji darts + /// + etDardo, + /// + /// Define o emoji BascketBoll + /// + etBasquete, + /// + /// Define o emoji FootBall + /// + etFootball, + /// + /// Define o emoji Slot Machine + /// + etSlotMachine, + /// + /// Define o emoji Bowling + /// + etBowling); + + TtdChatType = ( + /// + /// Normal one to one + /// + private, + /// + /// Normal groupchat + /// + Group, + /// + /// A channel + /// + Channel, + /// + /// A supergroup + /// + Supergroup); + /// + /// Type of a + /// + TtdFileType = ( + /// + /// Unknown FileType + /// + Unknown, + /// + /// FileStream + /// + Stream, + /// + /// FileId + /// + Id, + /// + /// File Url + /// + Url); + /// + /// The type of a Message + /// + TtdMessageType = (UnknownMessage = 0, TextMessage, PhotoMessage, AudioMessage, + VideoMessage, VideoNoteMessage, VoiceMessage, DocumentMessage, + StickerMessage, GameMessage, LocationMessage, ContactMessage, ServiceMessage, + VenueMessage, DiceMessage, PollMessage, AnimatoinMessage, InvoiceMessage, + PassportDataMessage); + + /// + /// Text parsing mode + /// + /// + /// + /// Markdown style + /// + /// + /// *bold text*
_italic text_
+ /// [text](http://www.example.com/)
`inline fixed-width code`
+ /// ```text
pre-formatted fixed-width code block
``` + ///
+ /// + /// Html: + /// + /// + /// <b>bold</b>, <strong>bold</strong>
+ /// <i>italic</i>, <em>italic</em>
<a + /// href="http://www.example.com/">inline URL</a>
+ /// <code>inline fixed-width code</code>
+ /// <pre>pre-formatted fixed-width code block</pre>

+ ///
+ ///
+ TtdParseMode = (default = 0, + /// + /// To use this mode, pass Markdown in the parse_mode field when using + /// sendMessage + /// + Markdown, + /// + /// To use this mode, pass MarkdownV2 in the parse_mode field when using + /// sendMessage + /// + MarkdownV2, + /// + /// To use this mode, pass HTML in the parse_mode field when using + /// sendMessage + /// + Html); + /// + /// The type of an Update + /// + TtdUpdateType = ( + /// + /// Update Type is unknown + /// + UnknownUpdate = 0, + /// + /// The contains a . + /// + MessageUpdate, + /// + /// The contains an . + /// + InlineQueryUpdate, + /// + /// The contains a + /// . + /// + ChosenInlineResultUpdate, + /// + /// The contins a + /// + CallbackQueryUpdate, + /// + /// The contains an edited + /// + EditedMessage, + /// + /// The contains a channel post + /// + ChannelPost, + /// + /// The contains an edited channel post + /// + EditedChannelPost, + /// + /// The contains an + /// + ShippingQueryUpdate, + /// + /// The contains an + /// + PreCheckoutQueryUpdate, + /// + /// The contains an + /// + PollState, + /// + /// The contains an + /// + PollAnswer, + /// + /// The contains an + /// + MyChatMember, + /// + /// The contains an + /// + ChatMember, + /// + /// Receive A request to join the chat has been sent. The bot must have + /// the can_invite_users administrator right in the chat to receive these + /// updates. Types + /// + ChatJoinRequest, +// /// +// /// Receive SuccessfulPayment Update Types +// /// +// SuccessfulPaymentUpdate, + /// + /// Receive all Types + /// + All = 255); + /// + /// The type of an EncryptedPassportElement + /// +TtdEncryptedPassportElementType = ( + /// + /// The contains an + /// + personal_details, + /// + /// The contains an + /// + passport, + /// + /// The contains an + /// + driver_license, + /// + /// The contains an + /// + identity_card, + /// + /// The contains an + /// + internal_passport, + /// + /// The contains an + /// + address, + /// + /// The contains an + /// + utility_bill, + /// + /// The contains an + /// + bank_statement, + /// + /// The contains an + /// + rental_agreement, + /// + /// The contains an + /// + passport_registration, + /// + /// The contains an + /// + temporary_registration, + /// + /// The contains an + /// + phone_number, + /// + /// The contains an + /// + email); + + /// + /// Type of a + /// Type of the entity. Currently, can be + /// “mention” (@username), + /// “hashtag” (#hashtag), + /// “cashtag” ($USD), + /// “bot_command” (/start@jobs_bot), + /// “url” (https://telegram.org), + /// “email” (do-not-reply@telegram.org), + /// “phone_number” (+1-212-555-0123), + /// “bold” (bold text), + /// “italic” (italic text), + /// “underline” (underlined text), + /// “strikethrough” (strikethrough text), + /// “spoiler” (spoiler message), + /// “code” (monowidth string), + /// “pre” (monowidth block), + /// “text_link” (for clickable text URLs), + /// “text_mention” (for users without usernames), + /// “custom_emoji” (for inline custom emoji stickers) + /// + TtdMessageEntityType = ( + /// + /// A mentioned + /// + mention, + /// + /// A searchable Hashtag + /// + hashtag, + /// + /// A cashtag + /// + cashtag, + /// + /// A Bot command + /// + bot_command, + /// + /// An url + /// + url, + /// + /// An email + /// + email, + /// + /// phone_number + /// + phone_number, + /// + /// Bold text + /// + bold, + /// + /// Italic text + /// + italic, + /// + /// underline + /// + underline, + /// + /// strikethrough + /// + strikethrough, + /// + /// Monowidth string + /// + code, + /// + /// Monowidth block + /// + pre, + /// + /// Clickable text urls + /// + text_link, + /// + /// Mentions for a without + /// + text_mention, + /// + /// "spoiler message" + /// + spoiler, + /// + /// “custom_emoji” (for inline custom emoji stickers) + /// + custom_emoji, + + N_A); + + + /// Type of the sticker, currently one of + /// “regular”, “mask”, “custom_emoji”. + /// The type of the sticker is independent from its format, + /// which is determined by the fields is_animated and is_video. +TtdStickerType = ( + /// + /// “regular” + /// + regular, + /// + /// “mask” + /// + mask, + /// + /// “custom_emoji” (for inline custom emoji stickers) + /// + custom_emoji +); +/// Format of stickers in the set, must be one of “static”, “animated”, “video” +TtdStickerFormat = ( + static, + animated, + video +); + /// + /// The part of the face relative to which the mask should be placed. One + /// of “forehead”, “eyes”, “mouth”, or “chin”. + /// + TtdMaskPositionPoint = ( + /// + /// The forehead + /// + forehead, + /// + /// The eyes + /// + eyes, + /// + /// The mouth + /// + mouth, + /// + /// The chin + chin); + + //substituido por classes... + TtdBotCommandScopeType = ( + /// + /// Represents the default scope of bot commands. Default commands + /// are used if no commands with a narrower scope are specified for the user. + /// Scope type, must be default + /// + BotCommandScopeDefault, + /// + /// Represents the scope of bot commands, covering all private chats. + /// Scope type, must be all_private_chats + /// + BotCommandScopeAllPrivateChats, + /// + /// Represents the scope of bot commands, covering all group and + /// supergroup chats. + /// Scope type, must be all_group_chats + /// + BotCommandScopeAllGroupChats, + /// + /// Represents the scope of bot commands, covering all group and + /// supergroup chat administrators. + /// Scope type, must be all_chat_administrators + /// + BotCommandScopeAllChatAdministrators, + /// + /// Represents the scope of bot commands, covering a specific chat. + /// Scope type, must be chat + /// + BotCommandScopeChat, + /// + /// Represents the scope of bot commands, covering all administrators of + /// a specific group or supergroup chat. + /// Scope type, must be chat_administrators + /// + BotCommandScopeChatAdministrators, + /// + /// Scope type, must be chat_member + /// Represents the scope of bot commands, covering a + /// specific member of a group or supergroup chat. + /// + BotCommandScopeChatMember + ); + + TtdMenuButtonType = ( + MenuButtonCommands, + MenuButtonWebApp, + MenuButtonDefault + ); + TtdGender = (Male, Female); + TtdPassportAvaibleData = (PersonalDetails, Passport, InternalPassport, + DriverLicense, IdentityCard, IdDocument, IdSelfie, Address, UtilityBill, + BankStatement, RentalAgreement, PassportRegistration, TemporaryRegistration, + AdressDocument, PhoneNumber, Email); + TAllowedUpdate = (Message, + Edited_message, Channel_post, Edited_channel_post, + Inline_query, Chosen_inline_result, Callback_query, + ShippingQuery, PreCheckoutQuery, PollState, PollAnswer, + MyChatMember, ChatMember, ChatJoinRequest); + TAllowedUpdates = set of TAllowedUpdate; +const + UPDATES_ALLOWED_ALL = [Low(TAllowedUpdate)..High(TAllowedUpdate)]; +implementation +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.Impl.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.Impl.pas new file mode 100644 index 0000000..d7df831 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.Impl.pas @@ -0,0 +1,4142 @@ +unit TinjectTelegram.Types.Impl; +interface +{$I ..\Source\config.inc} +uses + System.SysUtils, + System.Classes, + TinjectTelegram.Utils.JSON, + TinjectTelegram.Types, + TinjectTelegram.Helpers, + TinjectTelegram.Types.Enums, + TinjectTelegram.Types.Passport, Vcl.Graphics, Winapi.Windows; +type + TtdUser = class(TBaseJson, ItdUser) + public + function ID: Int64; + function IsBot: Boolean; + function FirstName: string; + function LastName: string; + function Username: string; + function LanguageCode: string; + function isPremium: Boolean; + function AddedToAttachmentMenu: string; + function CanJoinGroups: Boolean; + function CanReadAllGroupMessages: Boolean; + function SupportsInlineQueries: Boolean; + function ToJSonStr: String; + end; + TtdChatMemberOwner = class(TBaseJson, ItdChatMember) + public + function User: ItdUser; + function Status: TtdChatMemberStatus; + function CustomTitle: String; + function IsAnonymous : Boolean; + end; + TtdChatMemberAdministrator = class(TBaseJson, ItdChatMember) + public + function User: ItdUser; + function Status: TtdChatMemberStatus; + function CustomTitle: String; + function IsAnonymous : Boolean; + function CanBeEdited: Boolean; + function CanManageChat: Boolean; + function CanPostMessages: Boolean; + function CanEditMessages: Boolean; + function CanDeleteMessages: Boolean; + function CanManageVideoChats: Boolean; + function CanRestrictMembers: Boolean; + function CanPromoteMembers: Boolean; + function CanChangeInfo: Boolean; + function CanInviteUsers: Boolean; + function CanPinMessages: Boolean; + end; + TtdChatMemberMember = class(TBaseJson, ItdChatMember) + public + function User: ItdUser; + function Status : TtdChatMemberStatus; + end; + + TtdChatMemberRestricted = class(TBaseJson, ItdChatMember) + public + function User: ItdUser; + function Status: TtdChatMemberStatus; + function IsMember: Boolean; + function CanSendMessages: Boolean; + function CanSendAudios: Boolean; + function CanSendDocuments: Boolean; + function CanSendPhotos: Boolean; + function CanSendVideos: Boolean; + function CanSendVideoNotes: Boolean; + function CanSendVoiceNotes: Boolean; + function CanSendPolls: Boolean; + function CanSendOtherMessages: Boolean; + function CanAddWebPagePreviews: Boolean; + function CanChangeInfo: Boolean; + function CanInviteUsers: Boolean; + function CanPinMessages: Boolean; + function CanManageTopics: Boolean; + function UntilDate: TDateTime; + end; + TtdChatMemberLeft = class(TBaseJson, ItdChatMember) + public + function User: ItdUser; + function Status: TtdChatMemberStatus; + end; + TtdChatMemberBanned = class(TBaseJson, ItdChatMember) + public + function User: ItdUser; + function Status: TtdChatMemberStatus; + function UntilDate: TDateTime; + end; + TtdChatMemberUpdated = class(TBaseJson, ItdChatMemberUpdated) //New in API 5.1 + public + function Chat: ItdChat; + function From: ItdUser; + function Date: {Integer Unix Time}TDateTime; + function old_chat_member: ItdChatMember; + function new_chat_member: ItdChatMember; + function invite_link: ItdChatInviteLink; + function via_chat_folder_invite_link: Boolean; + End; +// TtdChatMemberUpdated = class(TBaseJson, ItdChatMember) +// public +// function chat: ItdChat; +// function from: ItdUser; +// function date: TDateTime; +// function old_chat_member: ItdChatMember; +// function new_chat_member: ItdChatMember; +// function invite_link: ItdChatInviteLink; +// end; + TtdChatMember = class(TBaseJson, ItdChatMember) + public + function ChatMemberOwner: TtdChatMemberOwner; + function ChatMemberAdministrator : TtdChatMemberAdministrator; + function ChatMemberMember :TtdChatMemberMember; + function ChatMemberRestricted : TtdChatMemberRestricted; + function ChatMemberLeft : TtdChatMemberLeft; + function ChatMemberBanned : TtdChatMemberBanned; + (* + function User: ItdUser; + function Status: TtdChatMemberStatus; + function CustomTitle: String; + function IsAnonymous : Boolean; + function CanBeEdited: Boolean; + function CanManageChat: Boolean; + function CanPostMessages: Boolean; + function CanEditMessages: Boolean; + function CanDeleteMessages: Boolean; + function CanManageVoiceChats: Boolean; + function CanRestrictMembers: Boolean; + function CanPromoteMembers: Boolean; + function CanChangeInfo: Boolean; + function CanInviteUsers: Boolean; + function CanPinMessages: Boolean; + function IsMember: Boolean; + function CanSendMessages: Boolean; + function CanSendMediaMessages: Boolean; + function CanSendPolls: Boolean; + function CanSendOtherMessages: Boolean; + function CanAddWebPagePreviews: Boolean; + function UntilDate: TDateTime; + *) + end; + TtdChatPhoto = class(TBaseJson, ItdChatPhoto) + function SmallFileId: string; + function SmallFileUniqueId: string; + function BigFileId: string; + function BigFileUniqueId: string; + end; + TtdChatPermissions = class(TBaseJson, ItdChatPermissions) + public + function CanSendMessages: Boolean; + function CanSendAudios: Boolean; + function CanSendDocuments: Boolean; + function CanSendPhotos: Boolean; + function CanSendVideos: Boolean; + function CanSendVideoNotes: Boolean; + function CanSendVoiceNotes: Boolean; + function CanSendPolls: Boolean; + function CanSendOtherMessages: Boolean; + function CanAddWebPagePreviews: Boolean; + function CanChangeInfo: Boolean; + function CanInviteUsers: Boolean; + function CanPinMessages: Boolean; + function CanManageTopics: Boolean; + end; + TtdChatLocation = class(TBaseJson, ItdChatLocation) + public + function Location: ItdLocation; + function Address: String; //Limit of a 64 character + end; + TtdChat = class(TBaseJson, ItdChat) + private + function IsGroup: Boolean; + public + function ID: Int64; + function TypeChat: TtdChatType; + function Title: string; + function Username: string; + function FirstName: string; + function LastName: string; + function is_forum: boolean; + function Photo: ItdChatPhoto; + function active_usernames: Tarray; + function emoji_status_custom_emoji_id: string; + function Bio: String; + function HasPrivateForwards: Boolean; + function has_restricted_voice_and_video_messages: boolean; + function JoinToSendMessages: Boolean; //New + function JoinByRequest: Boolean; //New + function Description: string; + function InviteLink: string; + function PinnedMessage: ItdMessage; + function Permissions: ItdChatPermissions; + function SlowModeDelay: Integer; + function MessageAutoDeleteTime: integer; + function has_aggressive_anti_spam_enabled: Boolean; + function has_hidden_members: Boolean; + function HasProtectedContent: boolean; + function StickerSetName: string; + function CanSetStickerSet: Boolean; + function LinkedChatId: Integer; + function location: ItdChatLocation; + function ToJSonStr: String; + function ToString: String; override; + end; + TtdMessageEntity = class(TBaseJson, ItdMessageEntity) + public + function TypeMessage: TtdMessageEntityType; + function Offset: Int64; + function Length: Int64; + function Url: string; + function User: ItdUser; + function language: string; + function custom_emoji_id: string; + end; + TtdFile = class(TBaseJson, ItdFile) + public + function FileId: string; + function FileUniqueId: string; //new + function FileSize: Int64; + function FilePath: string; + function CanDownload: Boolean; + function GetFileUrl(const AToken: string): string; + end; + TtdAudio = class(TtdFile, ItdAudio) + public + function Duration: Int64; + function Performer: string; + function Title: string; + function FileName: string; + function MimeType: string; + function Thumbnail: ItdPhotoSize; + end; + TtdPhotoSize = class(TtdFile, ItdPhotoSize) + public + function Width: Int64; + function Height: Int64; + end; + TtdDocument = class(TtdFile, ItdDocument) + public + function Thumbnail: ItdPhotoSize; + function FileName: string; + function MimeType: string; + end; + TtdMaskPosition = class(TBaseJson, ItdMaskPosition) + function Point: TtdMaskPositionPoint; + function XShift: Single; + function YShift: Single; + function Scale: Single; + end; + TtdSticker = class(TtdFile, ItdSticker) + public + function type_: string; + function Width: Int64; + function Height: Int64; + function is_animated: Boolean; + function is_video: Boolean; + function Thumbnail: ItdPhotoSize; + function Emoji: string; + function SetName: string; + function PremiumAnimation: ItdFile; + function MaskPosition: ItdMaskPosition; + function CustomEmojiId: Int64; + function NeedsRepainting: boolean; + end; + TtdStickerSet = class(TBaseJson, ItdStickerSet) + public + function Name: string; + function Title: string; + function StickerType: TtdStickerType; + function is_animated: Boolean; + function is_video: Boolean; + function ContainsMasks: Boolean; + function Stickers: TArray; + function Thumbnail: ItdPhotoSize; + end; + TtdVideo = class(TtdFile, ItdVideo) + public + function Width: Int64; + function Height: Int64; + function Duration: Int64; + function Thumbnail: ItdPhotoSize; + function FileName: string; + function MimeType: string; + end; + TtdVideoNote = class(TtdFile, ItdVideoNote) + public + function FileId: string; + function Length: Int64; + function Duration: Int64; + function Thumbnail: ItdPhotoSize; + function FileSize: Int64; + end; + TtdVoice = class(TtdFile, ItdVoice) + public + function Duration: Int64; + function MimeType: string; + end; + TtdContact = class(TBaseJson, ItdContact) + private + FJson : String; + procedure SetFirstName(const Value: string); + procedure SetLastName(const Value: string); + procedure SetPhoneNumber(const Value: string); + procedure SetVCard(const Value: string); + public + constructor Create(const ANumeroTelelefone, APrimeiroNome, UltimoNome, AVCard: String); reintroduce; overload; + constructor Create(const AJson: string); overload; override; + function PhoneNumber: string; + function FirstName: string; + function LastName: string; + function UserId: Int64; + function VCard: string; + end; + TtdPollOption = class(TBaseJson, ItdPollOption) + public + function text : String; + function voter_count: String; + end; + TtdPollAnswer = class(TBaseJson, ItdPollAnswer) + function poll_id: String; + function user: ItdUser; + function option_ids: TArray; + end; + TtdPoll = class(TBaseJson, ItdPoll) + function Id : String; + function Question: String; + function options: TArray; + function total_voter_count: Integer; + function is_closed: Boolean; + function is_anonymous: Boolean; + function &type: String; + function allows_multiple_answers: Boolean; + function correct_option_id: Integer; + end; + TtdDice = class(TBaseJson, ItdDice) + public + function Emoji: String; // Emoji on which the dice throw animation is based + function value: Integer; + end; + //New in API 5.0 + TtdProximityAlertTriggered = class(TBaseJson, ItdProximityAlertTriggered) + public + function traveler: ItdUser; // User that triggered the alert + function watcher: ItdUser; // User that set the alert + function distance: Integer; // The distance between the users + end; + TtdLocation = class(TBaseJson, ItdLocation) + private + FLat: Single; + FLng: Single; + FHorizontalAccuracy: Single; + FLivePeriod: Integer; + FHeading: Integer; + FProximityAlertRadius: Integer; + procedure SetLatitude(const Value: Single); + procedure SetLongitude(const Value: Single); + function GetLongitude: Single; + function GetLatitude: Single; + //New in API 5.0 + function GetHeading: Integer; + function GetHorizontalAccuracy: Single; + function GetLivePeriod: Integer; + function GetProximityAlertRadius: Integer; + procedure SetHeading(const Value: Integer); + procedure SetHorizontalAccuracy(const Value: Single); + procedure SetLivePeriod(const Value: Integer); + procedure SetProximityAlertRadius(const Value: Integer); + public + constructor Create(const ALatitude, ALongitude: Single); reintroduce; overload; + constructor Create(const AJson: string); overload; override; + property Latitude: Single read FLat write SetLatitude; + property Longitude: Single read FLng write SetLongitude; + //New in API 5.0 + property HorizontalAccuracy: Single read GetHorizontalAccuracy write SetHorizontalAccuracy; + property LivePeriod: Integer read GetLivePeriod write SetLivePeriod; + property Heading: Integer read GetHeading write SetHeading; + property ProximityAlertRadius: Integer read GetProximityAlertRadius write SetProximityAlertRadius; + end; + TtdVenue = class(TBaseJson, ItdVenue) + private + FLocation: ItdLocation; + FTitle: String; + FFoursquareId: string; + FFoursquareType: String; + FAddress: string; + FLatitude : Single; + FLongitude: Single; + FGooglePlaceId: string; + FGooglePlaceType: String; + procedure SetLatitude(const Value: Single); + procedure SetLongitude(const Value: Single); + procedure SetTitle(const Value: String); + procedure SetAddress(const Value: String); + procedure SetFoursquareId(const Value: String); + procedure SetFoursquareType(const Value: String); + procedure SetLocation(const Value: ItdLocation); + procedure SetGooglePlaceId(const Value: string); + procedure SetGooglePlaceType(const Value: String); + public + function Location: ItdLocation; + function Title: string; + function Address: string; + function FoursquareId: string; + function FoursquareType: string; + function google_place_id: string; + function google_place_type: string; + property sLocation : ItdLocation read FLocation write SetLocation; + property sLatitude : Single read FLatitude write SetLatitude; + property sLongitude : single read FLongitude write SetLongitude; + property sTitle : String read FTitle write SetTitle; + property sAddress : string read FAddress write SetAddress; + property sFoursquareId : string read FFoursquareId write SetFoursquareId; + property sFoursquareType: String read FFoursquareType write SetFoursquareType; + property sGooglePlaceId : string read FGooglePlaceId write SetGooglePlaceId; + property sGooglePlaceType: String read FGooglePlaceType write SetGooglePlaceType; + constructor Create(const ALocation: ItdLocation; ATitle, AAddress, + AFoursquareId, AFoursquareType : String); reintroduce; overload; + constructor Create(const ALatitude, ALongitude: Single; ATitle, AAddress, + AFoursquareId, AFoursquareType : String); reintroduce; overload; + constructor Create(const ALatitude, ALongitude: Single; ATitle, AAddress, + AFoursquareId, AFoursquareType, AGooglePlaceId, AGooglePlaceType : String); reintroduce; overload; + constructor Create(const AJson: string); overload; override; + destructor Destroy; override; + end; + TtdAnimation = class(TBaseJson, ItdAnimation) + public + function FileId: string; + function Thumbnail: ItdPhotoSize; + function FileName: string; + function MimeType: string; + function FileSize: Int64; + end; + TtdGameHighScore = class(TBaseJson, ItdGameHighScore) + public + function Position: Int64; + function User: ItdUser; + function Score: Int64; + end; + TtdGame = class(TBaseJson, ItdGame) + public + function Title: string; + function Description: string; + function Photo: TArray; + function Text: string; + function TextEntities: TArray; + function Animation: ItdAnimation; + end; + TtdChatInviteLink = class(TBaseJson, ItdChatInviteLink) //New in API 5.1 + public + function invite_link: String; + function creator: ItdUser; + function creates_join_request: Boolean; + function is_primary: Boolean; + function is_revoked: Boolean; + function name: String; + function expire_date: {Integer}TDateTime; + function member_limit: Integer; + function pending_join_request_count: Integer; + End; + /// + /// Represents a join request sent to a chat..
+ ///
+ /// + /// Chat to which the request was sent.
+ /// + /// + /// User that sent the join request.
+ /// + /// + /// Identifier of a private chat with the user who sent the join request. + /// This number may have more than 32 significant bits and some programming + /// languages may have difficulty/silent defects in interpreting it. But it + /// has at most 52 significant bits, so a 64-bit integer or double-precision + /// float type are safe for storing this identifier. The bot can use this + /// identifier for 24 hours to send messages until the join request is processed, + /// assuming no other administrator contacted the user.
+ /// + /// + /// Date the request was sent in Unix time.
+ /// + /// + /// Optional. Bio of the user..
+ /// + /// + /// Optional. Chat invite link that was used by the user to send the join request.
+ /// + TtdChatJoinRequest = class(TBaseJson, ItdChatJoinRequest) //New in API 5.4 + ['{1C15162D-4CB0-4F06-A1ED-A5987EF9C85A}'] + function chat: ItdChat; + function from: ItdUser; + function user_chat_id: Integer; + function date: TDateTime; {Integer Unix Time} + function bio: String; + function invite_link: ItdChatInviteLink; + end; + TtdVideoChatScheduled = class(TBaseJson, ItdVideoChatScheduled) //New in API 5.2 + public + function start_date: TDateTime; //Point in time (Unix timestamp) when the voice chat is supposed to be started by a chat administrator + End; + TtdVideoChatStarted = class(TBaseJson, ItdVideoChatStarted); //New in API 5.1 + TtdVideoChatEnded = class(TBaseJson, ItdVideoChatEnded) //New in API 5.1 + public + function duration: Integer; + End; + TtdVideoChatParticipantsInvited = class(TBaseJson, ItdVideoChatParticipantsInvited) //New in API 5.1 + public + function Users: TArray; + End; + TtdMessageAutoDeleteTimerChanged = class(TBaseJson, ItdMessageAutoDeleteTimerChanged) //New in API 5.1 + public + function message_auto_delete_time: TDateTime; + End; + + TtdWriteAccessAllowed = class(TBaseJson, ItdWriteAccessAllowed) + public + function web_app_name: string; + end; + + TtdForumTopic = class(TBaseJson, ItdForumTopic) + function message_thread_id: int64; + function name: string; + function icon_color: integer; + function icon_custom_emoji_id: string; + end; + + TtdForumTopicCreated = class(TBaseJson, ItdForumTopicCreated) + function name: string; + function icon_color: integer; + function icon_custom_emoji_id: string; + end; + + TtdForumTopicClosed = class(TBaseJson, ItdForumTopicClosed) + end; + + TtdForumTopicEdited = class(TBaseJson, ItdForumTopicEdited) + function name: string; + function icon_custom_emoji_id: string; + end; + + TtdForumTopicReopened = class(TBaseJson, ItdForumTopicReopened) + end; + + TtdGeneralForumTopicHidden = class(TBaseJson, ItdGeneralForumTopicHidden) + end; + + TtdGeneralForumTopicUnhidden = class(TBaseJson, ItdGeneralForumTopicUnhidden) + end; + + TtdMessage = class(TBaseJson, ItdMessage) + public + function MessageId: Int64; + function MessageThreadId: Int64; + function From: ItdUser; + function SenderChat: ItdChat; + function Date: TDateTime; + function Chat: ItdChat; + function ForwardFrom: ItdUser; + function ForwardFromChat: ItdChat; + function ForwardFromMessageId: Int64; + function ForwardSignature: string; + function ForwardSenderName: String; + function ForwardDate: TDateTime; + function IsTopicMessage : Boolean; + function IsAutomaticForward: boolean; + function ReplyToMessage: ItdMessage; + function ViaBot : ItdUser; + function EditDate: TDateTime; + function HasProtectedContent: boolean; + function MediaGroupId: string; + function AuthorSignature: string; + function Text: string; + function Entities: TArray; + function Animation : ItdAnimation; + function Audio: ItdAudio; + function Document: ItdDocument; + function Photo: TArray; + function Sticker: ItdSticker; + function Video: ItdVideo; + function VideoNote: ItdVideoNote; + function Voice: ItdVoice; + function Caption: string; + function CaptionEntities: TArray; + function HasMediaSpoiler: Boolean; + function Contact: ItdContact; + function Dice: ItdDice; + function Game: ItdGame; + function Poll: ItdPoll; + function Venue: ItdVenue; + function Location: ItdLocation; + function NewChatMembers: TArray; + function LeftChatMember: ItdUser; + function NewChatTitle: string; + function NewChatPhoto: TArray; + function DeleteChatPhoto: Boolean; + function GroupChatCreated: Boolean; + function SupergroupChatCreated: Boolean; + function ChannelChatCreated: Boolean; + function MigrateToChatId: Int64; + function MessageAutoDeleteTimerChanged: ItdMessageAutoDeleteTimerChanged; + function MigrateFromChatId: Int64; + function PinnedMessage: ItdMessage; + function Invoice: ItdInvoice; + function SuccessfulPayment: ItdSuccessfulPayment; + function UserShared: ItdUserShared; + function ChatShared: ItdChatShared; + function ConnectedWebsite: string; + function WriteAccessAllowed: ItdWriteAccessAllowed; + function PassportData: ItdPassportData; + function ProximityAlertTriggered: ItdProximityAlertTriggered; + function ForumTopicCreated: ItdForumTopicCreated; + function ForumTopicClosed: ItdForumTopicClosed; + function ForumTopicEdited: ItdForumTopicEdited; + function ForumTopicReopened: ItdForumTopicReopened; + function GeneralForumTopicHidden: ItdGeneralForumTopicHidden; + function GeneralForumTopicUnhidden: ItdGeneralForumTopicUnhidden; + function VideoChatScheduled: ItdVideoChatScheduled; + function VideoChatStarted: ItdVideoChatStarted; + function VideoChatEnded: ItdVideoChatEnded; + function VideoChatParticipantsInvited: ItdVideoChatParticipantsInvited; + function WebAppData: ItdWebAppData; + function ReplyMarkup : IReplyMarkup; + function NewChatMember: ItdUser; + function &Type: TtdMessageType; + function IsCommand(const AValue: string): Boolean; + end; + TtdMessageID = class(TBaseJson, ItdMessageID) + function MessageId: Int64; + end; + TtdUserProfilePhotos = class(TBaseJson, ItdUserProfilePhotos) + public + function TotalCount: Int64; + function Photos: TArray>; + end; + TtdCallbackGame = class + end; + TtdResponseParameters = class(TBaseJson, ItdResponseParameters) + public + function MigrateToChatId: Int64; + function RetryAfter: Int64; + end; + TtdInlineQuery = class(TBaseJson, ItdInlineQuery) + public + function ID: string; + function From: ItdUser; + function Query: string; + function Offset: string; + function chat_type: TtdChatType; // Optional. Type of the chat, from which the inline query was sent. Can be either “sender” for a private chat with the inline query sender, “private”, “group”, “supergroup”, or “channel”. The chat type should be always known for requests sent from official clients and most third-party clients, unless the request was sent from a secret chat + function location: ItdLocation; //Optional. Sender location, only for bots that request user location + end; + TtdChosenInlineResult = class(TBaseJson, ItdChosenInlineResult) + public + function ResultId: string; + function From: ItdUser; + function Location: ItdLocation; + function InlineMessageId: string; + function Query: string; + end; + TtdSwitchInlineQueryChosenChat = class(TBaseJson, ItdSwitchInlineQueryChosenChat) + public + function query: string; + function allow_user_chats: Boolean; + function allow_bot_chats: Boolean; + function allow_group_chats: Boolean; + function allow_channel_chats: Boolean; + end; + TtdCallbackQuery = class(TBaseJson, ItdCallbackQuery) + public + function ID: string; + function From: ItdUser; + function Message: ItdMessage; + function InlineMessageId: string; + function Data: string; + function GameShortName: string; + end; +{$REGION 'Payments'} + TtdInvoice = class(TBaseJson, ItdInvoice) + private + FTitle : string; + FStartParameter: string; + FDescription: string; + FCurrency: string; + FTotalAmount: Int64; + public + function Title: string; + function Description: string; + function StartParameter: string; + function Currency: string; + function TotalAmount: Int64; + property sTitle: string read Title write FTitle; + property sDescription: string read Description write FDescription; + property sStartParameter: string read StartParameter write FStartParameter; + property sCurrency: string read Currency write FCurrency; + property sTotalAmount: Int64 read TotalAmount write FTotalAmount; + constructor Create(const ATitle, ADescription, AStartParameter, Currency: string; ATotalAmount: Int64); + end; + TtdLabeledPrice = class(TBaseJson, ItdLabeledPrice) + private + AJSon : String; + [JSonName('amount')] + FAmount: Int64; + [JSonName('label')] + FLabel: String; + public + function &label: string; + function amount: Int64; + constructor Create(const ALabel: string; AAmount: Int64); reintroduce; overload; + constructor Create(const AJson: string); overload; override; + property sLabel: String read &label write FLabel; + property sAmount: Int64 read amount write FAmount; + end; + /// + /// This object represents a shipping address. + /// + TtdShippingAddress = class(TBaseJson, ItdShippingAddress) + public + function CountryCode: string; + function State: string; + function City: string; + function StreetLine1: string; + function StreetLine2: string; + function PostCode: string; + end; + TtdOrderInfo = class(TBaseJson, ItdOrderInfo) + public + function Name: string; + function PhoneNumber: string; + function Email: string; + function ShippingAddress: ItdShippingAddress; + end; + TtdPreCheckoutQuery = class(TBaseJson, ItdPreCheckoutQuery) + public + function ID: string; + function From: ItdUser; + function Currency: string; + function TotalAmount: Int64; + function InvoicePayload: string; + function ShippingOptionId: string; + function OrderInfo: ItdOrderInfo; + end; + TtdShippingOption = class(TBaseJson, ItdShippingOption) + public + function ID: string; + function Title: string; + function Prices: TArray; + end; + //Novo... + TtdAnswerShippingQuery = class(TBaseJson, ItdAnswerShippingQuery) + function ShippingQueryId : string; + function Ok : Boolean; + function ShippingOptions : TArray; + function ErrorMessage : string; + End; + //Novo + TtdAnswerPreCheckoutQuery = class(TBaseJson, ItdAnswerPreCheckoutQuery) + function PreCheckoutQueryId : string; + function Ok : Boolean; + function ErrorMessage : string; + end; + TtdShippingQuery = class(TBaseJson, ItdShippingQuery) + public + function ID: string; + function From: ItdUser; + function InvoicePayload: string; + function ShippingAddress: ItdShippingAddress; + end; + TtdSuccessfulPayment = class(TBaseJson, ItdSuccessfulPayment) + public + function Currency: string; + function TotalAmount: Int64; + function InvoicePayload: string; + function ShippingOptionId: string; + function OrderInfo: ItdOrderInfo; + function TelegramPaymentChargeId: string; + function ProviderPaymentChargeId: string; + end; + TtdPassportFile = class(TBaseJson, ItdPassportFile) + function file_id: string; + function file_unique_id: string; + function file_size: Integer; + function file_date: Integer; + end; + TtdEncryptedPassportElement = class(TBaseJson, ItdEncryptedPassportElement) + function &type : string; + function data: string; + function phone_number: string; + function email: string; + function files: TArray; + function front_side: ItdPassportFile; + function reverse_side: ItdPassportFile; + function selfie: ItdPassportFile; + function translation: TArray; + function hash: string; + end; + TtdEncryptedCredentials = class(TBaseJson, ItdEncryptedCredentials) + function Data: String; + function Hash: String; + function Secret: String; + end; + TtdPassportData = class(TBaseJson, ItdPassportData) + function Data: TArray; + function Credentials : ItdEncryptedCredentials; + end; +{$ENDREGION} + TtdUpdate = class(TBaseJson, ItdUpdate) + public + function ID: Int64; + function &Message: ItdMessage; + function EditedMessage: ItdMessage; + function InlineQuery: ItdInlineQuery; + function ChosenInlineResult: ItdChosenInlineResult; + function CallbackQuery: ItdCallbackQuery; + function ChannelPost: ItdMessage; + function EditedChannelPost: ItdMessage; + function ShippingQuery: ItdShippingQuery; + function PreCheckoutQuery: ItdPreCheckoutQuery; + function PollState: ItdPoll; + function PollAnswer: ItdPollAnswer; + function MyChatMember: ItdChatMemberUpdated; + function ChatMember: ItdChatMemberUpdated; + function ChatJoinRequest: ItdChatJoinRequest; + function &Type: TtdUpdateType; + end; + TtdWebhookInfo = class(TBaseJson, ItdWebhookInfo) + public + function Url: string; + function HasCustomCertificate: Boolean; + function PendingUpdateCount: Int64; + function IpAddress: String; + function LastErrorDate: TDateTime; + function LastErrorMessage: string; + function last_synchronization_error_date: TDateTime; + function MaxConnections: Int64; + function AllowedUpdates: TArray; + end; + TtdLoginURL = class(TBaseJson, ItdLoginURL) + private + FRequestWriteAccess: Boolean; + FURL: String; + FBotUserName: String; + FForwardText: String; + function URL: String; // + function ForwardText: String; // + function BotUserName: String; + function RequestWriteAccess: Boolean; + public +// constructor Create(const AJson: String); reintroduce; overload; + constructor Create(const AUrl: String;const AForwardText: String = ''; + const ABotUserName: String = '';const ARequestWriteAccess: Boolean = False); overload; + property sUrl: String read FURL write FURL; + property sForwardText: String read FForwardText write FForwardText; + property sBotUserName: String read FBotUserName write FBotUserName; + property sRequestWriteAccess: Boolean read FRequestWriteAccess write FRequestWriteAccess; + end; + TtdBotCommand = class(TBaseJson, ItdBotCommand) + private + [JsonName('command')] + FDesc: String; + [JsonName('description')] + FCMD: String; + published + constructor Create(const ACommand: String = ''; ADescription: String = ''); reintroduce; overload; + function Command: String; + function Description: String; + property CMD: String read FCMD write FCMD; + property Desc: String read FDesc write FDesc; + end; + TtdWebAppInfo = class(TBaseJson, ItdWebAppInfo) + private + [JsonName('url')] + Furl: string; + public + function url: String; + published + constructor Create(const Aurl: string); reintroduce; overload; + property surl: string read Furl write Furl; + end; + TtdWebAppData = class(TBaseJson, ItdWebAppData) + public + function data: String; + function button_text: String; + end; + TtdSentWebAppMessage = class(TBaseJson, ItdSentWebAppMessage) + public + function inline_message_id: String; + End; + + TtdMenuButton = class(TBaseJson, ItdMenuButton) + private + FMenuButtonType: TtdMenuButtonType; + procedure SetMenuButtonType(const Value: TtdMenuButtonType); + published + constructor Create(const AMenuButtonType: TtdMenuButtonType = TtdMenuButtonType.MenuButtonDefault); reintroduce; overload; + property MenuButtonType: TtdMenuButtonType read FMenuButtonType write SetMenuButtonType; + End; + TtdMenuButtonCommands = class(TBaseJson, ItdMenuButton) + private + Ftype_: string; + public + [JSONName('type')] + function &type: String; + published + constructor Create(const AMenuButtonType: TtdMenuButtonType = TtdMenuButtonType.MenuButtonDefault); reintroduce; overload; + property stype_: string read &type write Ftype_; + End; + TtdMenuButtonWebApp = class(TBaseJson, ItdMenuButton) + private + Ftype: String; + Ftext: string; + Fweb_app: ItdWebAppInfo; + public + function &type: String; + function text: String; + function web_app: ItdWebAppInfo; + published + constructor Create(const AMenuButtonType: TtdMenuButtonType = TtdMenuButtonType.MenuButtonDefault; AText: String = ''; AWebApp: ItdWebAppInfo = nil); reintroduce; overload; + [JSONName('type')] + property stype: String read Ftype write Ftype; + [JSONName('text')] + property stext: string read Ftext write Ftext; + [JSONName('web_app')] + property sweb_app: ItdWebAppInfo read Fweb_app write Fweb_app; + End; + TtdMenuButtonDefault = class(TBaseJson, ItdMenuButton) + private + Ftype_: string; + public + function &type: String; + published + constructor Create(const AMenuButtonType: TtdMenuButtonType = TtdMenuButtonType.MenuButtonDefault); reintroduce; overload; + property stype_: string read &type write Ftype_; + End; + TtdChatAdministratorRights = class(TBaseJson, ItdChatAdministratorRights) + private + FCanChangeInfo: Boolean; + FCanPromoteMembers: Boolean; + FCanManageChat: Boolean; + FCanManageVideoChats: Boolean; + FCanPostMessages: Boolean; + FCanRestrictMembers: Boolean; + FIsAnonymous: Boolean; + FCanDeleteMessages: Boolean; + FCanEditMessages: Boolean; + FCanPinMessages: Boolean; + FCanInviteUsers: Boolean; + public + function is_anonymous: Boolean; + function can_manage_chat: Boolean; + function can_delete_messages: Boolean; + function can_manage_video_chats: Boolean; + function can_restrict_members: Boolean; + function can_promote_members: Boolean; + function can_change_info: Boolean; + function can_invite_users: Boolean; + function can_post_messages: Boolean; + function can_edit_messages: Boolean; + function can_pin_messages: Boolean; + published + constructor Create; reintroduce; overload; + function ToJsonObject: string; + property IsAnonymous: Boolean read FIsAnonymous write FIsAnonymous; + property CanManageChat: Boolean read FCanManageChat write FCanManageChat; + property CanDeleteMessages: Boolean read FCanDeleteMessages write FCanDeleteMessages; + property CanManageVideoChats: Boolean read FCanManageVideoChats write FCanManageVideoChats; + property CanRestrictMembers: Boolean read FCanRestrictMembers write FCanRestrictMembers; + property CanPromoteMembers: Boolean read FCanPromoteMembers write FCanPromoteMembers; + property CanChangeInfo: Boolean read FCanChangeInfo write FCanChangeInfo; + property CanInviteUsers: Boolean read FCanInviteUsers write FCanInviteUsers; + property CanPostMessages: Boolean read FCanPostMessages write FCanPostMessages; + property CanEditMessages: Boolean read FCanEditMessages write FCanEditMessages; + property CanPinMessages: Boolean read FCanPinMessages write FCanPinMessages; + End; + + TtdThemeParams = class(TBaseJson, ItdThemeParams) + private + Fhint_color: TColor; + Fbutton_color: TColor; + Flink_color: TColor; + Fbutton_text_color: TColor; + Fbg_color: TColor; + Ftext_color: TColor; + Fsecondary_bg_color: TColor; + public + function Getbg_color: TColor; + function Gettext_color: TColor; + function Gethint_color: TColor; + function Getlink_color: TColor; + function Getbutton_color: TColor; + function Getbutton_text_color: TColor; + function Getsecondary_bg_color: TColor; + published + [JSONName('bg_color')] + property bg_color: TColor read Getbg_color write Fbg_color; + [JSONName('text_color')] + property text_color: TColor read Gettext_color write Ftext_color; + [JSONName('hint_color')] + property hint_color: TColor read Gethint_color write Fhint_color; + [JSONName('link_color')] + property link_color: TColor read Getlink_color write Flink_color; + [JSONName('button_color')] + property button_color: TColor read Getbutton_color write Fbutton_color; + [JSONName('button_text_color')] + property button_text_color: TColor read Getbutton_text_color write Fbutton_text_color; + [JSONName('secondary_bg_color')] + property secondary_bg_color: TColor read Getsecondary_bg_color write Fsecondary_bg_color; + End; + + TtdMainButton = class(TBaseJson, ItdMainButton) + public +// function text_: String; +// function color: String; +// function textColor: String; +// function isVisible: Boolean; +// function isActive: Boolean; +// function isProgressVisible: Boolean; + End; + + TtdUserShared = class(TBaseJson, ItdUserShared) + public + function request_id: integer; + function user_id: integer; + End; + + TtdChatShared = class(TBaseJson, ItdChatShared) + public + function request_id: integer; + function chat_id: integer; + End; + + TtdBotName = class(TBaseJson, ItdBotName) + public + function name: string; + end; + + [JsonName('BotCommandScope')] + TtdBotCommandScope = class(TBaseJson, ItdBotCommandScope) + end; + + [JsonName('BotCommandScopeDefault')] + TtdBotCommandScopeDefault = class(TtdBotCommandScope) + private + Ftype_p: string; + public + [JsonName('type')] + function type_: string; + + property type_p: string read Ftype_p write Ftype_p; + published + constructor Create(const AType: TtdBotCommandScopeType); reintroduce; overload; + function ToJsonObject: string; + end; + + [JsonName('BotCommandScopeAllPrivateChats')] + TtdBotCommandScopeAllPrivateChats = class(TtdBotCommandScopeDefault); + [JsonName('BotCommandScopeAllGroupChats')] + TtdBotCommandScopeAllGroupChats = class(TtdBotCommandScopeDefault); + [JsonName('BotCommandScopeAllChatAdministrators')] + TtdBotCommandScopeAllChatAdministrators = class(TtdBotCommandScopeDefault); + [JsonName('BotCommandScopeChat')] + TtdBotCommandScopeChat = class(TtdBotCommandScopeDefault) + public + function chat_id: string; + end; + [JsonName('BotCommandScopeChatAdministrators')] + TtdBotCommandScopeChatAdministrators = class(TtdBotCommandScopeChat); + [JsonName('BotCommandScopeChatMember')] + TtdBotCommandScopeChatMember = class(TtdBotCommandScopeChat) + public + function user_id: integer; + end; + + TtdBotDescription = class(TBaseJson, ItdBotDescription) + public + function description: string; + end; + + TtdBotShortDescription = class(TBaseJson, ItdBotShortDescription) + public + function short_description: string; + end; + + TtdInputSticker = class(TBaseJson, ItdInputSticker) + public + function sticker: string; + function emoji_list: TArray; + function mask_position: ItdMaskPosition; + function keywords: TArray; //List of 0-20 search keywords + end; + +implementation +uses + System.JSON, + System.TypInfo, + TinjectTelegram.Types.ReplyMarkups; +{ TtdAnimation } +function TtdAnimation.FileId: string; +begin + Result := ReadToSimpleType('file_id'); +end; +function TtdAnimation.FileName: string; +begin + Result := ReadToSimpleType('file_name'); +end; +function TtdAnimation.FileSize: Int64; +begin + Result := ReadToSimpleType('file_size'); +end; +function TtdAnimation.MimeType: string; +begin + Result := ReadToSimpleType('mime_type'); +end; +function TtdAnimation.Thumbnail: ItdPhotoSize; +begin + Result := ReadToClass('thumb'); +end; +{ TtdCallbackQuery } +function TtdCallbackQuery.Data: string; +begin + Result := ReadToSimpleType('data'); +end; +function TtdCallbackQuery.From: ItdUser; +begin + Result := ReadToClass('from'); +end; +function TtdCallbackQuery.GameShortName: string; +begin + Result := ReadToSimpleType('game_short_name'); +end; +function TtdCallbackQuery.ID: string; +begin + Result := ReadToSimpleType('id'); +end; +function TtdCallbackQuery.InlineMessageId: string; +begin + Result := ReadToSimpleType('inline_message_id'); +end; +function TtdCallbackQuery.Message: ItdMessage; +begin + Result := ReadToClass('message'); +end; +{ TtdDocument } +function TtdDocument.FileName: string; +begin + Result := ReadToSimpleType('file_name'); +end; +function TtdDocument.MimeType: string; +begin + Result := ReadToSimpleType('mime_type'); +end; +function TtdDocument.Thumbnail: ItdPhotoSize; +begin + Result := ReadToClass('thumbnail'); +end; +{ TtdFile } +function TtdFile.CanDownload: Boolean; +begin + Result := not FilePath.IsEmpty; +end; +function TtdFile.FileId: string; +begin + Result := ReadToSimpleType('file_id'); +end; +function TtdFile.FilePath: string; +begin + Result := ReadToSimpleType('file_path'); +end; +function TtdFile.FileSize: Int64; +begin + Result := ReadToSimpleType('file_size'); +end; +function TtdFile.FileUniqueId: string; +begin + Result := ReadToSimpleType('file_unique_id'); +end; +function TtdFile.GetFileUrl(const AToken: string): string; +begin + Result := 'https://api.telegram.org/file/bot' + AToken + '/' + FilePath; +end; +function TtdGameHighScore.Position: Int64; +begin + Result := ReadToSimpleType('position'); +end; +function TtdGameHighScore.Score: Int64; +begin + Result := ReadToSimpleType('score'); +end; +function TtdGameHighScore.User: ItdUser; +begin + Result := ReadToClass('user'); +end; +{ TtdMessage } +function TtdMessage.Document: ItdDocument; +begin + Result := ReadToClass('document'); +end; +function TtdMessage.EditDate: TDateTime; +begin + Result := ReadToDateTime('edit_date'); +end; +function TtdMessage.ForumTopicClosed: ItdForumTopicClosed; +begin + Result := ReadToClass('forum_topic_closed'); +end; + +function TtdMessage.ForumTopicCreated: ItdForumTopicCreated; +begin + Result := ReadToClass('forum_topic_created'); +end; + +function TtdMessage.ForumTopicEdited: ItdForumTopicEdited; +begin + Result := ReadToClass('forum_topic_edited'); +end; + +function TtdMessage.ForumTopicReopened: ItdForumTopicReopened; +begin + Result := ReadToClass('forum_topic_reopened'); +end; + +function TtdMessage.GeneralForumTopicHidden: ItdGeneralForumTopicHidden; +begin + Result := ReadToClass('general_forum_topic_hidden'); +end; + +function TtdMessage.GeneralForumTopicUnhidden: ItdGeneralForumTopicUnhidden; +begin + Result := ReadToClass('general_forum_topic_unhidden'); +end; + +function TtdMessage.ForwardDate: TDateTime; +begin + Result := ReadToDateTime('forward_date'); +end; +function TtdMessage.ForwardFrom: ItdUser; +begin + Result := ReadToClass('forward_from'); +end; +function TtdMessage.ForwardFromChat: ItdChat; +begin + Result := ReadToClass('forward_from_chat'); +end; +function TtdMessage.ForwardFromMessageId: Int64; +begin + Result := ReadToSimpleType('forward_from_message_id'); +end; +function TtdMessage.ForwardSenderName: String; +begin + Result := ReadToSimpleType('forward_sender_name'); +end; +function TtdMessage.ForwardSignature: string; +begin + Result := ReadToSimpleType('forward_signature'); +end; +function TtdMessage.From: ItdUser; +begin + Result := ReadToClass('from'); +end; +function TtdMessage.Game: ItdGame; +begin + Result := ReadToClass('game'); +end; +function TtdMessage.GroupChatCreated: Boolean; +begin + Result := ReadToSimpleType('group_chat_created'); +end; +function TtdMessage.HasMediaSpoiler: Boolean; +begin + Result := ReadToSimpleType('has_media_spoiler'); +end; + +function TtdMessage.HasProtectedContent: boolean; +begin + Result := ReadToSimpleType('has_protected_content'); +end; + +function TtdMessage.Invoice: ItdInvoice; +begin + Result := ReadToClass('invoice'); +end; +function TtdMessage.IsAutomaticForward: boolean; +begin + Result := ReadToSimpleType('is_automatic_forward'); +end; + +function TtdMessage.IsCommand(const AValue: string): Boolean; +var + LEnt: ItdMessageEntity; +begin + Result := False; + if Self.Entities = nil then + Exit; + for LEnt in Self.Entities do + if (LEnt.TypeMessage = TtdMessageEntityType.bot_command) then + if Text.Substring(LEnt.Offset, LEnt.Length).StartsWith(AValue, True) then + Exit(True); +end; +function TtdMessage.IsTopicMessage: Boolean; +begin + Result := ReadToSimpleType('is_topic_message'); +end; + +function TtdMessage.LeftChatMember: ItdUser; +begin + Result := ReadToClass('left_chat_member'); +end; +function TtdMessage.Location: ItdLocation; +begin + Result := ReadToClass('location'); +end; +function TtdMessage.MediaGroupId: string; +begin + Result := ReadToSimpleType('media_group_id'); +end; + +function TtdMessage.MessageAutoDeleteTimerChanged: ItdMessageAutoDeleteTimerChanged; +begin + Result := ReadToClass('message_auto_delete_timer_changed'); +end; +function TtdMessage.MessageId: Int64; +begin + Result := ReadToSimpleType('message_id'); +end; +function TtdMessage.MessageThreadId: Int64; +begin + Result := ReadToSimpleType('message_thread_id'); +end; + +function TtdMessage.MigrateFromChatId: Int64; +begin + Result := ReadToSimpleType('migrate_from_chat_id'); +end; +function TtdMessage.MigrateToChatId: Int64; +begin + Result := ReadToSimpleType('migrate_to_chat_id'); +end; +function TtdMessage.NewChatMember: ItdUser; +begin + Result := ReadToClass('new_chat_member'); +end; +function TtdMessage.NewChatMembers: TArray; +var + LValue: string; + LJsonArray: TJSONArray; + I: Integer; +begin + Result := nil; + if FJSON.TryGetValue('new_chat_members', LValue) then + begin + LJsonArray := TJSONObject.ParseJSONValue(LValue) as TJSONArray; + try + SetLength(Result, LJsonArray.Count); + for I := 0 to LJsonArray.Count - 1 do + Result[I] := ReadToClass('new_chat_members'); + finally + LJsonArray.Free; + end; + end; +end; +function TtdMessage.NewChatPhoto: TArray; +var + LValue: string; + LJsonArray: TJSONArray; + I: Integer; +begin + Result := nil; + if FJSON.TryGetValue('new_chat_photo', LValue) then + begin + LJsonArray := TJSONObject.ParseJSONValue(LValue) as TJSONArray; + try + SetLength(Result, LJsonArray.Count); + for I := 0 to LJsonArray.Count - 1 do + Result[I] := ReadToClass('new_chat_photo'); + finally + LJsonArray.Free; + end; + end; +end; +function TtdMessage.NewChatTitle: string; +begin + Result := ReadToSimpleType('new_chat_title'); +end; +function TtdMessage.Entities: TArray; +var + LJsonArray: TJSONArray; + I: Integer; +begin + LJsonArray := FJSON.GetValue('entities') as TJSONArray; + if (not Assigned(LJsonArray)) or LJsonArray.Null then + Exit(nil); + SetLength(Result, LJsonArray.Count); + for I := 0 to LJsonArray.Count - 1 do + Result[I] := TtdMessageEntity.Create(LJsonArray.Items[I].ToString); +end; +function TtdMessage.PassportData: ItdPassportData; +begin + Result := ReadToClass('passport_data'); +end; +function TtdMessage.Photo: TArray; +begin + Result := ReadToArray(TtdPhotoSize, 'photo'); +end; +function TtdMessage.PinnedMessage: ItdMessage; +begin + Result := ReadToClass('pinned_message'); +end; +function TtdMessage.Poll: ItdPoll; +begin + Result := ReadToClass('poll'); +end; +function TtdMessage.ProximityAlertTriggered: ItdProximityAlertTriggered; +begin + Result := ReadToClass('proximity_alert_triggered'); +end; +function TtdMessage.ReplyMarkup: IReplyMarkup; +begin + Result := ReadToClass('reply_markup'); +end; +function TtdMessage.ReplyToMessage: ItdMessage; +begin + Result := ReadToClass('reply_to_message'); +end; +function TtdMessage.SenderChat: ItdChat; +begin + Result := ReadToClass('sender_chat'); +end; +function TtdMessage.Sticker: ItdSticker; +begin + Result := ReadToClass('sticker'); +end; +function TtdMessage.SuccessfulPayment: ItdSuccessfulPayment; +begin + Result := ReadToClass('successful_payment'); +end; +function TtdMessage.SupergroupChatCreated: Boolean; +begin + Result := ReadToSimpleType('supergroup_chat_created'); +end; +function TtdMessage.Text: string; +begin + Result := ReadToSimpleType('text'); +end; +function TtdMessage.&Type: TtdMessageType; +begin + if Audio <> nil then + Exit(TtdMessageType.AudioMessage); + if Contact <> nil then + Exit(TtdMessageType.ContactMessage); + if Document <> nil then + Exit(TtdMessageType.DocumentMessage); + if Game <> nil then + Exit(TtdMessageType.GameMessage); + if (Location <> nil) then + Exit(TtdMessageType.LocationMessage); + if (NewChatMember <> nil) or (LeftChatMember <> nil) or ((NewChatPhoto <> nil) and (Length(NewChatPhoto) > 0)) or ((NewChatMembers <> nil) and (Length(NewChatMembers) > 0)) or (not NewChatTitle.IsEmpty) or DeleteChatPhoto or GroupChatCreated or SupergroupChatCreated or ChannelChatCreated or (MigrateToChatId <> 0) or (MigrateFromChatId <> 0) or (PinnedMessage <> nil) then + Exit(TtdMessageType.ServiceMessage); + if (Photo <> nil) and (Length(Photo) > 0) then + Exit(TtdMessageType.PhotoMessage); + if (Sticker <> nil) then + Exit(TtdMessageType.StickerMessage); + if (Dice <> nil) then + Exit(TtdMessageType.DiceMessage); + if (Poll <> nil) then + Exit(TtdMessageType.PollMessage); + if (Venue <> nil) then + Exit(TtdMessageType.VenueMessage); + if (Video <> nil) then + Exit(TtdMessageType.VideoMessage); + if (VideoNote <> nil) then + Exit(TtdMessageType.VideoNoteMessage); + if (Voice <> nil) then + Exit(TtdMessageType.VoiceMessage); + if (Animation <> nil) then + Exit(TtdMessageType.AnimatoinMessage); + if (Invoice <> nil) then + Exit(TtdMessageType.InvoiceMessage); + if (PassportData <> nil) then + Exit(TtdMessageType.PassportDataMessage); + if not Text.IsEmpty then + Exit(TtdMessageType.TextMessage); + Result := TtdMessageType.UnknownMessage; +end; +function TtdMessage.UserShared: ItdUserShared; +begin + Result := ReadToClass('UserShared'); +end; +function TtdMessage.ChatShared: ItdChatShared; +begin + Result := ReadToClass('ChatShared'); +end; +function TtdMessage.Animation: ItdAnimation; +begin + Result := ReadToClass('animation'); +end; +function TtdMessage.Audio: ItdAudio; +begin + Result := ReadToClass('audio'); +end; +function TtdMessage.AuthorSignature: string; +begin + Result := ReadToSimpleType('author_signature'); +end; +function TtdMessage.Caption: string; +begin + Result := ReadToSimpleType('caption'); +end; +function TtdMessage.CaptionEntities: TArray; +begin + Result := ReadToArray(TtdMessageEntity, 'caption_entities'); +end; +function TtdMessage.ChannelChatCreated: Boolean; +begin + Result := ReadToSimpleType('channel_chat_created'); +end; +function TtdMessage.Chat: ItdChat; +begin + Result := ReadToClass('chat'); +end; +function TtdMessage.ConnectedWebsite: string; +begin + Result := ReadToSimpleType('connected_website'); +end; +function TtdMessage.Contact: ItdContact; +begin + Result := ReadToClass('contact'); +end; +function TtdMessage.Date: TDateTime; +begin + Result := ReadToDateTime('date'); +end; +function TtdMessage.DeleteChatPhoto: Boolean; +begin + Result := ReadToSimpleType('delete_chat_photo'); +end; +function TtdMessage.Dice: ItdDice; +begin + Result := ReadToClass('dice'); +end; +function TtdMessage.Venue: ItdVenue; +begin + Result := ReadToClass('venue'); +end; +function TtdMessage.ViaBot: ItdUser; +begin + Result := ReadToClass('via_bot'); +end; +function TtdMessage.Video: ItdVideo; +begin + Result := ReadToClass('video'); +end; +function TtdMessage.VideoNote: ItdVideoNote; +begin + Result := ReadToClass('video_note'); +end; +function TtdMessage.Voice: ItdVoice; +begin + Result := ReadToClass('voice'); +end; +function TtdMessage.VideoChatParticipantsInvited: ItdVideoChatParticipantsInvited; +begin + Result := ReadToClass('video_chat_participants_invited'); +end; +function TtdMessage.VideoChatScheduled: ItdVideoChatScheduled; +begin + Result := ReadToClass('video_chat_scheduled'); +end; +function TtdMessage.VideoChatStarted: ItdVideoChatStarted; +begin + Result := ReadToClass('video_chat_started'); +end; +function TtdMessage.WebAppData: ItdWebAppData; +begin + Result := ReadToClass('web_app_data'); +end; + +function TtdMessage.WriteAccessAllowed: ItdWriteAccessAllowed; +begin + Result := ReadToClass('write_access_allowed'); +end; + +function TtdMessage.VideoChatEnded: ItdVideoChatEnded; +begin + Result := ReadToClass('video_chat_ended'); +end; +{ TtdShippingOption } +function TtdShippingOption.ID: string; +begin + Result := ReadToSimpleType('id'); +end; +function TtdShippingOption.Prices: TArray; +begin + Result := ReadToArray(TtdLabeledPrice, 'prices'); +end; +function TtdShippingOption.Title: string; +begin + Result := ReadToSimpleType('title'); +end; +{ TtdUpdate } +function TtdUpdate.CallbackQuery: ItdCallbackQuery; +begin + Result := ReadToClass('callback_query'); +end; +function TtdUpdate.ChannelPost: ItdMessage; +begin + Result := ReadToClass('channel_post'); +end; +function TtdUpdate.ChatJoinRequest: ItdChatJoinRequest; +begin + Result := ReadToClass('chat_join_request'); +end; +function TtdUpdate.ChatMember: ItdChatMemberUpdated; +begin + Result := ReadToClass('chat_member'); +end; +function TtdUpdate.ChosenInlineResult: ItdChosenInlineResult; +begin + Result := ReadToClass('chosen_inline_result'); +end; +function TtdUpdate.EditedChannelPost: ItdMessage; +begin + Result := ReadToClass('edited_channel_post'); +end; +function TtdUpdate.EditedMessage: ItdMessage; +begin + Result := ReadToClass('edited_message'); +end; +function TtdUpdate.ID: Int64; +begin + Result := ReadToSimpleType('update_id'); +end; +function TtdUpdate.InlineQuery: ItdInlineQuery; +begin + Result := ReadToClass('inline_query'); +end; +function TtdUpdate.&Message: ItdMessage; +begin + Result := ReadToClass('message'); +end; +function TtdUpdate.MyChatMember: ItdChatMemberUpdated; +begin + Result := ReadToClass('my_chat_member'); +end; +function TtdUpdate.PollAnswer: ItdPollAnswer; +begin + Result := ReadToClass('poll_answer'); +end; +function TtdUpdate.PollState: ItdPoll; +begin + Result := ReadToClass('poll'); +end; +function TtdUpdate.PreCheckoutQuery: ItdPreCheckoutQuery; +begin + Result := ReadToClass('pre_checkout_query'); +end; +function TtdUpdate.ShippingQuery: ItdShippingQuery; +begin + Result := ReadToClass('shipping_query'); +end; +function TtdUpdate.&Type: TtdUpdateType; +begin + if CallbackQuery <> nil then + Result := TtdUpdateType.CallbackQueryUpdate + else if ChannelPost <> nil then + Result := (TtdUpdateType.ChannelPost) + else if ChosenInlineResult <> nil then + Result := (TtdUpdateType.ChosenInlineResultUpdate) + else if EditedChannelPost <> nil then + Result := (TtdUpdateType.EditedChannelPost) + else if EditedMessage <> nil then + Result := (TtdUpdateType.EditedMessage) + else if InlineQuery <> nil then + Result := (TtdUpdateType.InlineQueryUpdate) + else if Message <> nil then + Result := (TtdUpdateType.MessageUpdate) + else if PreCheckoutQuery <> nil then + Result := (TtdUpdateType.PreCheckoutQueryUpdate) + else if ShippingQuery <> nil then + Result := (TtdUpdateType.ShippingQueryUpdate) + else + Result := TtdUpdateType.UnknownUpdate; +end; +{ TtdLocation } +constructor TtdLocation.Create(const ALatitude, ALongitude: Single); +var AJson: String; +begin +{ TODO 5 -oDieletro -cTypes : Preciso Fazer esta passagem dos paramentros nesse metodo } +// FHorizontalAccuracy: Single; +// FLivePeriod: Integer; +// FHeading: Integer; +// FProximityAlertRadius: Integer; + SetLongitude(ALongitude); + SetLatitude(ALatitude); + AJson := '{ "latitude":'+ALatitude.ToString+'",'; + AJson := AJson + '"longitude":'+ALongitude.ToString+'}'; + Create(AJson); +end; +constructor TtdLocation.Create(const AJson: string); +begin + inherited Create(AJson); +end; +function TtdLocation.GetHeading: Integer; +begin + Result := ReadToSimpleType('heading'); + FHeading := Result; +end; +function TtdLocation.GetHorizontalAccuracy: Single; +begin + Result := ReadToSimpleType('horizontal_accuracy'); + FHorizontalAccuracy := Result; +end; +function TtdLocation.GetLatitude: Single; +begin + Result := ReadToSimpleType('latitude'); + FLat := Result; +end; +function TtdLocation.GetLivePeriod: Integer; +begin + Result := ReadToSimpleType('live_period'); + FLivePeriod := Result; +end; +function TtdLocation.GetLongitude: Single; +begin + Result := ReadToSimpleType('longitude'); + FLng := Result; +end; +function TtdLocation.GetProximityAlertRadius: Integer; +begin + Result := ReadToSimpleType('proximity_alert_radius'); + FProximityAlertRadius := Result; +end; +procedure TtdLocation.SetHeading(const Value: Integer); +begin +end; +procedure TtdLocation.SetHorizontalAccuracy(const Value: Single); +begin +end; +procedure TtdLocation.SetLatitude(const Value: Single); +begin + FLat := Value; +// FJSON.AddPair('latitude', TJSONNumber.Create(Value)); +end; +procedure TtdLocation.SetLivePeriod(const Value: Integer); +begin +end; +procedure TtdLocation.SetLongitude(const Value: Single); +begin + FLng := Value; + // FJSON.AddPair('longitude', TJSONNumber.Create(Value)); +end; +{ TtdStickerSet } +procedure TtdLocation.SetProximityAlertRadius(const Value: Integer); +begin + FProximityAlertRadius := Value; +end; +function TtdStickerSet.ContainsMasks: Boolean; +begin + Result := ReadToSimpleType('contains_masks'); +end; +function TtdStickerSet.is_animated: Boolean; +begin + Result := ReadToSimpleType('is_animated'); +end; + +function TtdStickerSet.is_video: Boolean; +begin + Result := ReadToSimpleType('is_video'); +end; + +function TtdStickerSet.Name: string; +begin + Result := ReadToSimpleType('name'); +end; +function TtdStickerSet.Stickers: TArray; +begin + Result := ReadToArray(TtdSticker, 'stickers'); +end; +function TtdStickerSet.StickerType: TtdStickerType; +var + stickerout: string; +begin + stickerout := ReadToSimpleType('sticker_type'); + + if stickerout = TtdStickerType.regular.ToString then + Result := TtdStickerType.regular; + if stickerout = TtdStickerType.mask.ToString then + Result := TtdStickerType.mask; + if stickerout = TtdStickerType.custom_emoji.ToString then + Result := TtdStickerType.custom_emoji; +end; + +function TtdStickerSet.Thumbnail: ItdPhotoSize; +begin + Result := ReadToClass('thumb'); +end; + +function TtdStickerSet.Title: string; +begin + Result := ReadToSimpleType('title'); +end; +{ TtdLabeledPrice } +//UPDated By Ruan Diego Lacerda Menezes +constructor TtdLabeledPrice.Create(const ALabel: string; AAmount: Int64); +begin + FLabel := ALabel; + FAmount := AAmount; + FJSON := TJSONObject.Create; + FJSON.AddPair('label', TJSONString.Create(ALabel)); + FJSON.AddPair('amount', TJSONNumber.Create(AAmount)); + AJSon := '{"'+FJSON.ToString+'"}'; + inherited Create(AJSon); +end; +constructor TtdLabeledPrice.Create(const AJson: string); +begin + inherited Create(AJson); +end; +function TtdLabeledPrice.amount: Int64; +begin + FAmount := ReadToSimpleType('amount'); + Result := FAmount; +end; +function TtdLabeledPrice.&label: string; +begin + FLabel := ReadToSimpleType('label'); + Result := FLabel; +end; +{ TtdResponseParameters } +function TtdResponseParameters.MigrateToChatId: Int64; +begin + Result := ReadToSimpleType('migrate_to_chat_id'); +end; +function TtdResponseParameters.RetryAfter: Int64; +begin + Result := ReadToSimpleType('retry_after'); +end; +{ TtdUser } +function TtdUser.AddedToAttachmentMenu: string; +begin + Result := ReadToSimpleType('added_to_attachment_menu'); +end; + +function TtdUser.CanJoinGroups: Boolean; +begin + Result := ReadToSimpleType('can_join_groups'); +end; +function TtdUser.CanReadAllGroupMessages: Boolean; +begin + Result := ReadToSimpleType('can_read_all_group_messages'); +end; +function TtdUser.SupportsInlineQueries: Boolean; +begin + Result := ReadToSimpleType('supports_inline_queries'); +end; +function TtdUser.FirstName: string; +begin + Result := ReadToSimpleType('first_name'); +end; +function TtdUser.ID: Int64; +begin + Result := ReadToSimpleType('id'); +end; +function TtdUser.IsBot: Boolean; +begin + Result := ReadToSimpleType('is_bot'); +end; +function TtdUser.isPremium: Boolean; +begin + Result := ReadToSimpleType('is_premium'); +end; + +function TtdUser.ToJSonStr: String; +begin + Result := TJsonUtils.ObjectToJString(Self); +// '{"'+ID.ToJsonString+'","'+IsBot.ToJsonString+'","'+FirstName+'",'+ +// '"'+LastName+'","'+LanguageCode+'","'+CanJoinGroups.ToJsonString+'",'+ +// '"'+CanReadAllGroupMessages.ToJsonString+'","'+SupportsInlineQueries.ToJsonString+'"}'; +end; +function TtdUser.LanguageCode: string; +begin + Result := ReadToSimpleType('language_code'); +end; +function TtdUser.LastName: string; +begin + Result := ReadToSimpleType('last_name'); +end; +function TtdUser.Username: string; +begin + Result := ReadToSimpleType('username'); +end; +{ TtdInlineQuery } +function TtdInlineQuery.chat_type: TtdChatType; +var + OutStr: String; +begin + OutStr := ReadToSimpleType('chat_type'); + if OutStr = TtdChatType.private.ToString then + Result := TtdChatType.private + else + if OutStr = TtdChatType.Group.ToString then + Result := TtdChatType.Group + else + if OutStr = TtdChatType.Channel.ToString then + Result := TtdChatType.Channel + else + if OutStr = TtdChatType.Supergroup.ToString then + Result := TtdChatType.Supergroup; +end; +function TtdInlineQuery.location: ItdLocation; +begin + Result := ReadToClass('location'); +end; +function TtdInlineQuery.From: ItdUser; +begin + Result := ReadToClass('from'); +end; +function TtdInlineQuery.ID: string; +begin + Result := ReadToSimpleType('id'); +end; +function TtdInlineQuery.Offset: string; +begin + Result := ReadToSimpleType('offset'); +end; +function TtdInlineQuery.Query: string; +begin + Result := ReadToSimpleType('query'); +end; +{ TtdChosenInlineResult } +function TtdChosenInlineResult.From: ItdUser; +begin + Result := ReadToClass('from'); +end; +function TtdChosenInlineResult.InlineMessageId: string; +begin + Result := ReadToSimpleType('inline_message_id'); +end; +function TtdChosenInlineResult.Location: ItdLocation; +begin + Result := ReadToClass('location'); +end; +function TtdChosenInlineResult.Query: string; +begin + Result := ReadToSimpleType('query'); +end; +function TtdChosenInlineResult.ResultId: string; +begin + Result := ReadToSimpleType('result_id'); +end; +{ TtdPreCheckoutQuery } +function TtdPreCheckoutQuery.Currency: string; +begin + Result := ReadToSimpleType('currency'); +end; +function TtdPreCheckoutQuery.From: ItdUser; +begin + Result := ReadToClass('from'); +end; +function TtdPreCheckoutQuery.ID: string; +begin + Result := ReadToSimpleType('id'); +end; +function TtdPreCheckoutQuery.InvoicePayload: string; +begin + Result := ReadToSimpleType('invoice_payload'); +end; +function TtdPreCheckoutQuery.OrderInfo: ItdOrderInfo; +begin + Result := ReadToClass('order_info'); +end; +function TtdPreCheckoutQuery.ShippingOptionId: string; +begin + Result := ReadToSimpleType('shipping_option_id'); +end; +function TtdPreCheckoutQuery.TotalAmount: Int64; +begin + Result := ReadToSimpleType('total_amount'); +end; +{ TtdShippingQuery } +function TtdShippingQuery.From: ItdUser; +begin + Result := ReadToClass('from'); +end; +function TtdShippingQuery.ID: string; +begin + Result := ReadToSimpleType('id'); +end; +function TtdShippingQuery.InvoicePayload: string; +begin + Result := ReadToSimpleType('invoice_payload'); +end; +function TtdShippingQuery.ShippingAddress: ItdShippingAddress; +begin + Result := ReadToClass('shipping_address'); +end; +{ TtdChatPhoto } +function TtdChatPhoto.BigFileId: string; +begin + Result := ReadToSimpleType('big_file_id'); +end; +function TtdChatPhoto.BigFileUniqueId: string; +begin + Result := ReadToSimpleType('big_file_unique_id'); +end; +function TtdChatPhoto.SmallFileId: string; +begin + Result := ReadToSimpleType('small_file_id'); +end; +function TtdChatPhoto.SmallFileUniqueId: string; +begin + Result := ReadToSimpleType('small_file_unique_id'); +end; +{ TtdChat } +function TtdChat.active_usernames: Tarray; +var + LJsonArray: TJSONArray; + I: Integer; +begin + LJsonArray := FJSON.GetValue('active_usernames') as TJSONArray; + if (not Assigned(LJsonArray)) or LJsonArray.Null then + Exit(nil); + SetLength(Result, LJsonArray.Count); + for I := 0 to LJsonArray.Count - 1 do + Result[I] := ReadToSimpleType(LJsonArray.Items[I].ToString); +end; + +function TtdChat.Bio: String; +begin + Result := ReadToSimpleType('bio'); +end; +function TtdChat.CanSetStickerSet: Boolean; +begin + Result := ReadToSimpleType('can_set_sticker_set'); +end; +function TtdChat.Description: string; +begin + Result := ReadToSimpleType('description'); +end; +function TtdChat.emoji_status_custom_emoji_id: string; +begin + Result := ReadToSimpleType('emoji_status_custom_emoji_id'); +end; + +function TtdChat.FirstName: string; +begin + Result := ReadToSimpleType('first_name'); +end; +function TtdChat.HasPrivateForwards: Boolean; +begin + Result := ReadToSimpleType('has_private_forwards'); +end; + +function TtdChat.HasProtectedContent: boolean; +begin + Result := ReadToSimpleType('has_protected_content'); +end; + +function TtdChat.has_aggressive_anti_spam_enabled: Boolean; +begin + Result := ReadToSimpleType('has_aggressive_anti_spam_enabled'); +end; + +function TtdChat.has_hidden_members: Boolean; +begin + Result := ReadToSimpleType('has_hidden_members'); +end; + +function TtdChat.has_restricted_voice_and_video_messages: boolean; +begin + Result := ReadToSimpleType('has_restricted_voice_and_video_messages'); +end; + +function TtdChat.ID: Int64; +begin + Result := ReadToSimpleType('id'); +end; +function TtdChat.InviteLink: string; +begin + Result := ReadToSimpleType('invite_link'); +end; +function TtdChat.IsGroup: Boolean; +var + LValue: string; +begin + LValue := ReadToSimpleType('type'); + result := (LValue = 'group'); +end; +function TtdChat.is_forum: boolean; +begin + Result := ReadToSimpleType('is_forum'); +end; + +function TtdChat.JoinByRequest: Boolean; +begin + Result := ReadToSimpleType('join_by_request'); +end; + +function TtdChat.JoinToSendMessages: Boolean; +begin + Result := ReadToSimpleType('join_to_send_messages'); +end; + +function TtdChat.LastName: string; +begin + Result := ReadToSimpleType('last_name'); +end; +function TtdChat.LinkedChatId: Integer; +begin + Result := ReadToSimpleType('linked_chat_id'); +end; +function TtdChat.location: ItdChatLocation; +begin + Result := ReadToClass('location'); +end; +function TtdChat.MessageAutoDeleteTime: integer; +begin + Result := ReadToSimpleType('message_auto_delete_time'); +end; + +function TtdChat.Permissions: ItdChatPermissions; +begin + Result := ReadToClass('ChatPermissions'); +end; +function TtdChat.Photo: ItdChatPhoto; +begin + Result := ReadToClass('photo'); +end; +function TtdChat.PinnedMessage: ItdMessage; +begin + Result := ReadToClass('pinned_message'); +end; +function TtdChat.SlowModeDelay: Integer; +begin + Result := ReadToSimpleType('slow_mode_delay'); +end; +function TtdChat.StickerSetName: string; +begin + Result := ReadToSimpleType('sticker_set_name'); +end; +function TtdChat.Title: string; +begin + Result := ReadToSimpleType('title'); +end; +function TtdChat.ToJSonStr: String; +var + LValue: string; + Saida : Boolean; +begin + LValue := ReadToSimpleType('type'); + Saida := (LValue = 'group'); + Result := TJsonUtils.ObjectToJString(Self); + +// '[{'+ +// '"id":'+ReadToSimpleType('id').ToString+sLineBreak+ +// '","type":"'+ReadToSimpleType('type')+sLineBreak+ +// '","title":"'+ReadToSimpleType('title')+sLineBreak+ +// '","username":"'+ReadToSimpleType('username')+sLineBreak+ +// '","first_name":"'+ReadToSimpleType('first_name')+sLineBreak+ +// '","last_name":"'+ReadToSimpleType('last_name')+sLineBreak+ +// '","all_members_are_administrators":"'+ReadToSimpleType('all_members_are_administrators').ToJsonString + sLineBreak+ +// '","photo":"'+ReadToSimpleType('photo')+sLineBreak+ +// '","description":"'+ReadToSimpleType('description')+sLineBreak+ +// '","invite_link":"'+ReadToSimpleType('invite_link')+sLineBreak+ +// '","pinned_message":"'+ReadToSimpleType('pinned_message')+sLineBreak+ +// '","sticker_set_name":"'+ReadToSimpleType('sticker_set_name')+sLineBreak+ +// '","can_set_sticker_set":"'+ReadToSimpleType('can_set_sticker_set').ToString+sLineBreak+ +// '","is_group":"'+Saida.ToString+'"}]'; +end; +function TtdChat.ToString: String; +var + LValue: string; + Saida : Boolean; +begin + LValue := ReadToSimpleType('type'); + Saida := (LValue = 'group'); + Result := TJsonUtils.ObjectToJString(Self); +// '[id='+ReadToSimpleType('id').ToString+sLineBreak+ +// 'type='+ReadToSimpleType('type')+sLineBreak+ +// 'title='+ReadToSimpleType('title')+sLineBreak+ +// 'username='+ReadToSimpleType('username')+sLineBreak+ +// 'first_name='+ReadToSimpleType('first_name')+sLineBreak+ +// 'last_name='+ReadToSimpleType('last_name')+sLineBreak+ +// 'all_members_are_administrators='+ ReadToSimpleType('all_members_are_administrators').ToJsonString + sLineBreak+ +// 'photo='+ReadToSimpleType('photo')+sLineBreak+ +// 'description='+ReadToSimpleType('description')+sLineBreak+ +// 'invite_link='+ReadToSimpleType('invite_link')+sLineBreak+ +// 'pinned_message='+ReadToSimpleType('pinned_message')+sLineBreak+ +// 'sticker_set_name='+ReadToSimpleType('sticker_set_name')+sLineBreak+ +// 'can_set_sticker_set='+ReadToSimpleType('can_set_sticker_set').ToString+sLineBreak+ +// 'is_group='+Saida.ToJsonString+']'; +end; +function TtdChat.TypeChat: TtdChatType; +var + LValue: string; +begin + LValue := ReadToSimpleType('type'); + Result := TtdChatType.&private; + if LValue = 'private' then + Result := TtdChatType.&private + else if LValue = 'group' then + Result := TtdChatType.Group + else if LValue = 'channel' then + Result := TtdChatType.Channel + else if LValue = 'supergroup' then + Result := TtdChatType.Supergroup + else + UnSupported; +end; +function TtdChat.Username: string; +begin + Result := ReadToSimpleType('username'); +end; +{ TtdSuccessfulPayment } +function TtdSuccessfulPayment.Currency: string; +begin + Result := ReadToSimpleType('currency'); +end; +function TtdSuccessfulPayment.InvoicePayload: string; +begin + Result := ReadToSimpleType('invoice_payload'); +end; +function TtdSuccessfulPayment.OrderInfo: ItdOrderInfo; +begin + Result := ReadToClass('order_info'); +end; +function TtdSuccessfulPayment.ProviderPaymentChargeId: string; +begin + Result := ReadToSimpleType('provider_payment_charge_id'); +end; +function TtdSuccessfulPayment.ShippingOptionId: string; +begin + Result := ReadToSimpleType('shipping_option_id'); +end; +function TtdSuccessfulPayment.TelegramPaymentChargeId: string; +begin + Result := ReadToSimpleType('telegram_payment_charge_id'); +end; +function TtdSuccessfulPayment.TotalAmount: Int64; +begin + Result := ReadToSimpleType('total_amount'); +end; +{ TtdWebhookInfo } +function TtdWebhookInfo.AllowedUpdates: TArray; +var + LJsonArray: TJSONArray; + I: Integer; +begin + LJsonArray := FJSON.GetValue('allowed_updates') as TJSONArray; + if (not Assigned(LJsonArray)) or LJsonArray.Null then + Exit(nil); + SetLength(Result, LJsonArray.Count); + for I := 0 to LJsonArray.Count - 1 do + Result[I] := ReadToSimpleType(LJsonArray.Items[I].ToString); +end; +function TtdWebhookInfo.HasCustomCertificate: Boolean; +begin + Result := ReadToSimpleType('has_custom_certificate'); +end; +function TtdWebhookInfo.IpAddress: String; +begin + Result := ReadToSimpleType('ip_address'); +end; +function TtdWebhookInfo.LastErrorDate: TDateTime; +begin + Result := ReadToDateTime('last_error_date'); +end; +function TtdWebhookInfo.LastErrorMessage: string; +begin + Result := ReadToSimpleType('last_error_message'); +end; +function TtdWebhookInfo.last_synchronization_error_date: TDateTime; +begin + Result := ReadToDateTime('last_synchronization_error_date'); +end; + +function TtdWebhookInfo.MaxConnections: Int64; +begin + Result := ReadToSimpleType('max_connections'); +end; +function TtdWebhookInfo.PendingUpdateCount: Int64; +begin + Result := ReadToSimpleType('pending_update_count'); +end; +function TtdWebhookInfo.Url: string; +begin + Result := ReadToSimpleType('url'); +end; + +{ TtdMessageEntity } +function TtdMessageEntity.custom_emoji_id: string; +begin + Result := ReadToSimpleType('custom_emoji_id'); +end; + +function TtdMessageEntity.language: string; +begin + Result := ReadToSimpleType('language'); +end; +function TtdMessageEntity.Length: Int64; +begin + Result := ReadToSimpleType('length'); +end; +function TtdMessageEntity.Offset: Int64; +begin + Result := ReadToSimpleType('offset'); +end; +function TtdMessageEntity.TypeMessage: TtdMessageEntityType; +var + LValue: string; +begin + LValue := ReadToSimpleType('type'); + Result := TtdMessageEntityType.N_A; + if LValue = 'mention' then + Result := TtdMessageEntityType.mention + else if LValue = 'hashtag' then + Result := TtdMessageEntityType.hashtag + else if LValue = 'bot_command' then + Result := TtdMessageEntityType.bot_command + else if LValue = 'url' then + Result := TtdMessageEntityType.Url + else if LValue = 'bold' then + Result := TtdMessageEntityType.bold + else if LValue = 'italic' then + Result := TtdMessageEntityType.italic + else if LValue = 'code' then + Result := TtdMessageEntityType.code + else if LValue = 'pre' then + Result := TtdMessageEntityType.pre + else if LValue = 'text_link' then + Result := TtdMessageEntityType.text_link + else if LValue = 'text_mention' then + Result := TtdMessageEntityType.text_mention +end; +function TtdMessageEntity.Url: string; +begin + Result := ReadToSimpleType('url'); +end; +function TtdMessageEntity.User: ItdUser; +begin + Result := ReadToClass('user'); +end; +{ TtdAudio } +function TtdAudio.Duration: Int64; +begin + Result := ReadToSimpleType('duration'); +end; +function TtdAudio.FileName: string; +begin + Result := ReadToSimpleType('file_name'); +end; +function TtdAudio.MimeType: string; +begin + Result := ReadToSimpleType('mime_type'); +end; +function TtdAudio.Performer: string; +begin + Result := ReadToSimpleType('performer'); +end; +function TtdAudio.Thumbnail: ItdPhotoSize; +begin + Result := ReadToClass('thumbnail'); +end; +function TtdAudio.Title: string; +begin + Result := ReadToSimpleType('title'); +end; +{ TtdPhotoSize } +function TtdPhotoSize.Height: Int64; +begin + Result := ReadToSimpleType('height'); +end; +function TtdPhotoSize.Width: Int64; +begin + Result := ReadToSimpleType('width'); +end; +{ TtdMaskPosition } +function TtdMaskPosition.Point: TtdMaskPositionPoint; +var + LValue: string; +begin + LValue := ReadToSimpleType('point'); + Result := TtdMaskPositionPoint.forehead; + if LValue = 'forehead' then + Result := TtdMaskPositionPoint.forehead + else if LValue = 'eyes' then + Result := TtdMaskPositionPoint.eyes + else if LValue = 'mouth' then + Result := TtdMaskPositionPoint.mouth + else if LValue = 'chin' then + Result := TtdMaskPositionPoint.chin + else + UnSupported; +end; +function TtdMaskPosition.Scale: Single; +begin + Result := ReadToSimpleType('scale'); +end; +function TtdMaskPosition.XShift: Single; +begin + Result := ReadToSimpleType('x_shift'); +end; +function TtdMaskPosition.YShift: Single; +begin + Result := ReadToSimpleType('y_shift'); +end; +{ TtdSticker } +function TtdSticker.CustomEmojiId: Int64; +begin + Result := ReadToSimpleType('custom_emoji_id'); +end; + +function TtdSticker.Emoji: string; +begin + Result := ReadToSimpleType('emoji'); +end; +function TtdSticker.Height: Int64; +begin + Result := ReadToSimpleType('height'); +end; +function TtdSticker.is_animated: Boolean; +begin + Result := ReadToSimpleType('is_animated'); +end; + +function TtdSticker.is_video: Boolean; +begin + Result := ReadToSimpleType('is_video'); +end; + +function TtdSticker.MaskPosition: ItdMaskPosition; +begin + Result := ReadToClass('mask_position'); +end; +function TtdSticker.NeedsRepainting: Boolean; +begin + Result := ReadToSimpleType('needs_repainting'); +end; + +function TtdSticker.PremiumAnimation: ItdFile; +begin + Result := ReadToClass('premium_animation'); +end; + +function TtdSticker.SetName: string; +begin + Result := ReadToSimpleType('set_name'); +end; +function TtdSticker.Thumbnail: ItdPhotoSize; +begin + Result := ReadToClass('thumb'); +end; +function TtdSticker.type_: string; +begin + Result := ReadToSimpleType('type'); +end; + +function TtdSticker.Width: Int64; +begin + Result := ReadToSimpleType('width'); +end; +{ TtdGame } +function TtdGame.Animation: ItdAnimation; +begin + Result := ReadToClass('animation'); +end; +function TtdGame.Description: string; +begin + Result := ReadToSimpleType('description'); +end; +function TtdGame.Photo: TArray; +begin + Result := ReadToArray(TtdPhotoSize, 'photo'); +end; +function TtdGame.Text: string; +begin + Result := ReadToSimpleType('text'); +end; +function TtdGame.TextEntities: TArray; +begin + Result := ReadToArray(TtdMessageEntity, 'text_entities'); +end; +function TtdGame.Title: string; +begin + Result := ReadToSimpleType('title'); +end; +{ TtdInvoice } +constructor TtdInvoice.Create(const ATitle, ADescription, AStartParameter, + Currency: string; ATotalAmount: Int64); +begin + FTitle := ATitle; + FDescription := ADescription; + FStartParameter := AStartParameter; + FCurrency := Currency; + FTotalAmount := ATotalAmount; +end; +function TtdInvoice.Currency: string; +begin + //Result := ReadToSimpleType('currency'); + FCurrency := ReadToSimpleType('currency'); + Result := FCurrency; +end; +function TtdInvoice.Description: string; +begin + //Result := ReadToSimpleType('description'); + FDescription := ReadToSimpleType('description'); + Result := FDescription; +end; +function TtdInvoice.StartParameter: string; +begin + //Result := ReadToSimpleType('start_parameter'); + FStartParameter := ReadToSimpleType('start_parameter'); + Result := FStartParameter; +end; +function TtdInvoice.Title: string; +begin + // Result := ReadToSimpleType('title'); + FTitle := ReadToSimpleType('title'); + Result := FTitle; +end; +function TtdInvoice.TotalAmount: Int64; +begin + //Result := ReadToSimpleType('total_amount'); + FTotalAmount := ReadToSimpleType('total_amount'); + Result := FTotalAmount; +end; +{ TtdVideo } +function TtdVideo.Duration: Int64; +begin + Result := ReadToSimpleType('duration'); +end; +function TtdVideo.FileName: string; +begin + Result := ReadToSimpleType('file_name'); +end; +function TtdVideo.Height: Int64; +begin + Result := ReadToSimpleType('height'); +end; +function TtdVideo.MimeType: string; +begin + Result := ReadToSimpleType('mime_type'); +end; +function TtdVideo.Thumbnail: ItdPhotoSize; +begin + Result := ReadToClass('thumb'); +end; +function TtdVideo.Width: Int64; +begin + Result := ReadToSimpleType('width'); +end; +{ TtdContact } +constructor TtdContact.Create(const AJson: string); +begin + inherited Create(AJson); +end; +constructor TtdContact.Create(const ANumeroTelelefone, APrimeiroNome, UltimoNome, AVCard: String); +begin + SetPhoneNumber(ANumeroTelelefone); + SetFirstName(APrimeiroNome); + SetLastName(UltimoNome); + SetVCard(AVCard); + inherited Create(FJson); +end; +procedure TtdContact.SetFirstName(const Value: string); +begin + FJson := FJson + ' "first_name":"'+Value+'",'; +// FJSON.AddPair('first_name', TJSONString.Create(Value)); +end; +procedure TtdContact.SetLastName(const Value: string); +begin + FJson := FJson + ' "last_name":"'+Value+'"}'; +// FJSON.AddPair('last_name', TJSONString.Create(Value)); +end; +procedure TtdContact.SetPhoneNumber(const Value: string); +begin + FJson := '{"phone_number":"'+Value+'",'; + // FJSON.AddPair('phone_number', TJSONString.Create(Value)); +end; +procedure TtdContact.SetVCard(const Value: string); +begin + FJson := '{"vacard":"'+Value+'",'; +end; + +function TtdContact.FirstName: string; +begin + Result := ReadToSimpleType('first_name'); +end; +function TtdContact.LastName: string; +begin + Result := ReadToSimpleType('last_name'); +end; +function TtdContact.PhoneNumber: string; +begin + Result := ReadToSimpleType('phone_number'); +end; +function TtdContact.UserId: Int64; +begin + Result := ReadToSimpleType('user_id'); +end; +function TtdContact.VCard: string; +begin + Result := ReadToSimpleType('vcard'); +end; + +{ TtdVenue } +constructor TtdVenue.Create(const ALocation: ItdLocation; ATitle, AAddress, + AFoursquareId, AFoursquareType: String); +begin + SetLocation(ALocation); + SetTitle(ATitle); + SetAddress(AAddress); + SetFoursquareId(AFoursquareId); + SetFoursquareType(AFoursquareType); +end; +function TtdVenue.Address: string; +begin + Result := ReadToSimpleType('address'); +end; +function TtdVenue.FoursquareId: string; +begin + Result := ReadToSimpleType('foursquare_id'); +end; +function TtdVenue.FoursquareType: string; +begin + Result := ReadToSimpleType('foursquare_type'); +end; +function TtdVenue.google_place_id: string; +begin + Result := ReadToSimpleType('google_place_id'); +end; +function TtdVenue.google_place_type: string; +begin + Result := ReadToSimpleType('google_place_type'); +end; +function TtdVenue.Location: ItdLocation; +begin + Result := ReadToClass('location'); +end; +function TtdVenue.Title: string; +begin + Result := ReadToSimpleType('title'); +end; +constructor TtdVenue.Create(const AJson: string); +begin + inherited Create(AJson); +end; +constructor TtdVenue.Create(const ALatitude, ALongitude: Single; ATitle, + AAddress, AFoursquareId, AFoursquareType, AGooglePlaceId, + AGooglePlaceType: String); +begin + SetLongitude(ALongitude); + SetLatitude(ALatitude); + SetTitle(ATitle); + SetAddress(AAddress); + SetFoursquareId(AFoursquareId); + SetFoursquareType(AFoursquareType); + SetGooglePlaceId(AGooglePlaceId); + SetGooglePlaceType(AGooglePlaceType); + if Not Assigned(FLocation) then + FLocation := TtdLocation.Create(ALatitude, ALongitude); +end; +destructor TtdVenue.Destroy; +begin + {$IF NOT DEFINE DELPHI14_UP} + if Assigned(FLocation) then + FreeAndNil(FLocation); + {$ENDIF DELPHI14_UP} + Inherited Destroy; +end; +constructor TtdVenue.Create(const ALatitude, ALongitude: Single; ATitle, + AAddress, AFoursquareId, AFoursquareType: String); +begin + SetLongitude(ALongitude); + SetLatitude(ALatitude); + SetTitle(ATitle); + SetAddress(AAddress); + SetFoursquareId(AFoursquareId); + SetFoursquareType(AFoursquareType); + if Not Assigned(FLocation) then + FLocation := TtdLocation.Create(ALatitude, ALongitude); +end; +procedure TtdVenue.SetLatitude(const Value: Single); +begin + FLatitude := Value; +end; +procedure TtdVenue.SetLocation(const Value: ItdLocation); +begin + FLocation := Value; + SetLatitude(Value.Latitude); + SetLongitude(Value.Longitude); +end; +procedure TtdVenue.SetLongitude(const Value: Single); +begin + FLongitude := Value; +end; +procedure TtdVenue.SetTitle(const Value: String); +begin + FTitle := Value; +end; +procedure TtdVenue.SetAddress(const Value: String); +begin + FAddress := Value; +end; +procedure TtdVenue.SetFoursquareId(const Value: String); +begin + FFoursquareId := Value; +end; +procedure TtdVenue.SetFoursquareType(const Value: String); +begin + FFoursquareType := Value; +end; +procedure TtdVenue.SetGooglePlaceId(const Value: string); +begin + FGooglePlaceId := Value; +end; +procedure TtdVenue.SetGooglePlaceType(const Value: String); +begin + FGooglePlaceType := Value; +end; +{TtdVideoNote} +function TtdVideoNote.Duration: Int64; +begin + Result := ReadToSimpleType('duration'); +end; +function TtdVideoNote.FileId: string; +begin + Result := ReadToSimpleType('file_id'); +end; +function TtdVideoNote.FileSize: Int64; +begin + Result := ReadToSimpleType('file_size'); +end; +function TtdVideoNote.Length: Int64; +begin + Result := ReadToSimpleType('length'); +end; +function TtdVideoNote.Thumbnail: ItdPhotoSize; +begin + Result := ReadToClass('thumb'); +end; +{ TtdVoice } +function TtdVoice.Duration: Int64; +begin + Result := ReadToSimpleType('duration'); +end; +function TtdVoice.MimeType: string; +begin + Result := ReadToSimpleType('mime_type'); +end; +{ TtdOrderInfo } +function TtdOrderInfo.Email: string; +begin + Result := ReadToSimpleType('email'); +end; +function TtdOrderInfo.Name: string; +begin + Result := ReadToSimpleType('name'); +end; +function TtdOrderInfo.PhoneNumber: string; +begin + Result := ReadToSimpleType('phone_number'); +end; +function TtdOrderInfo.ShippingAddress: ItdShippingAddress; +begin + Result := ReadToClass('shipping_address'); +end; +{ TtdShippingAddress } +function TtdShippingAddress.City: string; +begin + Result := ReadToSimpleType('city'); +end; +function TtdShippingAddress.CountryCode: string; +begin + Result := ReadToSimpleType('country_code'); +end; +function TtdShippingAddress.PostCode: string; +begin + Result := ReadToSimpleType('post_code'); +end; +function TtdShippingAddress.State: string; +begin + Result := ReadToSimpleType('state'); +end; +function TtdShippingAddress.StreetLine1: string; +begin + Result := ReadToSimpleType('street_line1'); +end; +function TtdShippingAddress.StreetLine2: string; +begin + Result := ReadToSimpleType('street_line2'); +end; +{ TtdUserProfilePhotos } +function TtdUserProfilePhotos.Photos: TArray>; +var + PhotoArr, SizeArr: TJSONArray; + PhotoIndex, ResultPhotoIndex: Integer; + SizeIndex: Integer; + GUID: TGUID; +begin + Result := nil; + PhotoArr := FJSON.GetValue('photos') as TJSONArray; + if (not Assigned(PhotoArr)) or PhotoArr.Null then + Exit; + GUID := GetTypeData(TypeInfo(ItdPhotoSize))^.GUID; + SetLength(Result, PhotoArr.Count); + //Some photos could be empty(?), so we should + //use separated counter instead of copy of the FOR-loop variable value. + ResultPhotoIndex := 0; + for PhotoIndex := 0 to High(Result) do + begin + //get array of photoSizes from photoArr[i] + SizeArr := PhotoArr.Items[PhotoIndex] as TJSONArray; + //check for empty photo + if (not Assigned(SizeArr)) or SizeArr.Null then + Continue; + //set length of photoSize array + SetLength(Result[ResultPhotoIndex], SizeArr.Count); + //fills the result[RealIndex] with array of sizes + for SizeIndex := 0 to High(Result[ResultPhotoIndex]) do + GetTdClass.Create(SizeArr.Items[SizeIndex].ToString).GetInterface(GUID, Result[ResultPhotoIndex, SizeIndex]); + //inc counter of processed photos + Inc(ResultPhotoIndex); + end; + //Set real length of the result array. length = zero based index + 1; + SetLength(Result, ResultPhotoIndex + 1); +end; +function TtdUserProfilePhotos.TotalCount: Int64; +begin + Result := ReadToSimpleType('total_count'); +end; +{ TtdPollOption } +function TtdPollOption.text: String; +begin + Result := ReadToSimpleType('text'); +end; +function TtdPollOption.voter_count: String; +begin + Result := ReadToSimpleType('voter_count'); +end; +{ TtdPollAnswer } +function TtdPollAnswer.option_ids: TArray; +var + LJsonArray: TJSONArray; + I: Integer; +begin + LJsonArray := FJSON.GetValue('option_ids') as TJSONArray; + if (not Assigned(LJsonArray)) or LJsonArray.Null then + Exit(nil); + SetLength(Result, LJsonArray.Count); + for I := 0 to LJsonArray.Count - 1 do + Result[I] := ReadToSimpleType(LJsonArray.Items[I].ToString); +end; +function TtdPollAnswer.poll_id: String; +begin + Result := ReadToSimpleType('poll_id'); +end; +function TtdPollAnswer.user: ItdUser; +begin + Result := ReadToSimpleType('user'); +end; +{ TtdPoll } +function TtdPoll.allows_multiple_answers: Boolean; +begin + Result := ReadToSimpleType('allows_multiple_answers'); +end; +function TtdPoll.correct_option_id: Integer; +begin + Result := ReadToSimpleType('correct_option_id'); +end; +function TtdPoll.Id: String; +begin + Result := ReadToSimpleType('Id'); +end; +function TtdPoll.is_anonymous: Boolean; +begin + Result := ReadToSimpleType('is_anonymous'); +end; +function TtdPoll.is_closed: Boolean; +begin + Result := ReadToSimpleType('is_closed'); +end; +function TtdPoll.options: TArray; +begin + Result := ReadToArray(TtdPollOption, 'options'); +end; +function TtdPoll.question: String; +begin + Result := ReadToSimpleType('question'); +end; +function TtdPoll.total_voter_count: Integer; +begin + Result := ReadToSimpleType('total_voter_count'); +end; +function TtdPoll.&type: String; +begin + Result := ReadToSimpleType('type'); +end; +{ TtdDice } +function TtdDice.Emoji: String; +begin + Result := ReadToSimpleType('emoji'); +end; +function TtdDice.value: Integer; +begin + Result := ReadToSimpleType('value'); +end; + +{ TtdLoginURL } +function TtdLoginURL.BotUserName: String; +begin + Result := ReadToSimpleType('bot_username'); +end; +//constructor TtdLoginURL.Create(AJson: String); +//begin +// inherited Create(AJson); +//end; +constructor TtdLoginURL.Create(const AUrl: String;const AForwardText: String = ''; + const ABotUserName: String = '';const ARequestWriteAccess: Boolean = False); + var + AJson: String; +begin + FRequestWriteAccess := ARequestWriteAccess; + FUrl := AUrl; + FForwardText := AForwardText; + FBotUserName := ABotUserName; +// FJson.AddPair('url',TJSONString(FUrl)); +// FJson.AddPair('forward_text',TJSONString(FForwardText)); +// FJson.AddPair('bot_username',TJSONString(FBotUserName)); +// FJson.AddPair('request_write_access',TJSONBool(FRequestWriteAccess)); + + AJson := + '{"url":"'+FUrl+ + '","forward_text":"'+FForwardText+ + '","bot_username":"'+FBotUserName+ + '","request_write_access":"'+FRequestWriteAccess.ToJSONBool+'"}'; + inherited Create(AJson); +end; +function TtdLoginURL.ForwardText: String; +begin + Result := ReadToSimpleType('forward_text'); +end; +function TtdLoginURL.RequestWriteAccess: Boolean; +begin + Result := ReadToSimpleType('request_write_access'); +end; +function TtdLoginURL.URL: String; +begin + Result := ReadToSimpleType('url'); +end; +{ TtdBotCommand } +function TtdBotCommand.Command: String; +begin + Result := ReadToSimpleType('command'); +end; +constructor TtdBotCommand.Create(const ACommand: String; ADescription: String); +var + AJson: String; + I, X : Integer; +begin + + for I := 1 to Length(ACommand) do + Begin + If ACommand[I] in ['A'..'Z'] then + Begin + //if ACommand[I] = CharUpper(ACommand[I]) then + raise Exception.Create('Error: Uppercase letters Not allowed in the register of commands!'); + Break; + End; + End; + + if Length(ACommand) > 32 then + Begin + raise Exception.Create('Error: The Command Field is limited to 32 characters!'); + Exit; + End; + + if Length(ADescription) > 256 then + Begin + raise Exception.Create('Error: The Description Field is limited to 256 characters!'); + Exit; + End; + + AJson := '{"command":"'+ACommand+'","description":"'+ADescription+'"}'; + FDesc := ADescription; + FCMD := ACommand; + inherited Create(AJson); +end; +function TtdBotCommand.Description: String; +begin + Result := ReadToSimpleType('description'); +end; +{ TtdAnswerPreCheckoutQuery } +function TtdAnswerPreCheckoutQuery.ErrorMessage: string; +begin + Result := ReadToSimpleType('error_message'); +end; +function TtdAnswerPreCheckoutQuery.Ok: Boolean; +begin + Result := ReadToSimpleType('ok'); +end; +function TtdAnswerPreCheckoutQuery.PreCheckoutQueryId: string; +begin + Result := ReadToSimpleType('pre_checkout_query_id'); +end; +{ TtdAnswerShippingQuery } +function TtdAnswerShippingQuery.ErrorMessage: string; +begin + Result := ReadToSimpleType('error_message'); +end; +function TtdAnswerShippingQuery.Ok: Boolean; +begin + Result := ReadToSimpleType('ok'); +end; +function TtdAnswerShippingQuery.ShippingOptions: TArray; +begin + Result := ReadToArray(TtdShippingOption, 'shipping_options'); +end; +function TtdAnswerShippingQuery.ShippingQueryId: string; +begin + Result := ReadToSimpleType('shipping_query_id'); +end; +{ TtdPassportFile } +function TtdPassportFile.file_date: Integer; +begin + Result := ReadToSimpleType('file_date'); +end; +function TtdPassportFile.file_id: string; +begin + Result := ReadToSimpleType('file_id'); +end; +function TtdPassportFile.file_size: Integer; +begin + Result := ReadToSimpleType('file_size'); +end; +function TtdPassportFile.file_unique_id: string; +begin + Result := ReadToSimpleType('file_unique_id'); +end; +{ TtdEncryptedPassportElement } +function TtdEncryptedPassportElement.data: string; +begin + Result := ReadToSimpleType('data'); +end; +function TtdEncryptedPassportElement.email: string; +begin + Result := ReadToSimpleType('email'); +end; +function TtdEncryptedPassportElement.files: TArray; +begin + Result := ReadToArray(TtdPassportFile, 'files'); +end; +function TtdEncryptedPassportElement.front_side: ItdPassportFile; +begin + Result := ReadToClass('front_side'); +end; +function TtdEncryptedPassportElement.hash: string; +begin + Result := ReadToSimpleType('hash'); +end; +function TtdEncryptedPassportElement.phone_number: string; +begin + Result := ReadToSimpleType('phone_number'); +end; +function TtdEncryptedPassportElement.reverse_side: ItdPassportFile; +begin + Result := ReadToClass('reverse_side'); +end; +function TtdEncryptedPassportElement.selfie: ItdPassportFile; +begin + Result := ReadToClass('selfie'); +end; +function TtdEncryptedPassportElement.translation: TArray; +begin + Result := ReadToArray(TtdPassportFile, 'translation'); +end; +function TtdEncryptedPassportElement.&type: string; +begin + Result := ReadToSimpleType('type'); +end; +{ TtdEncryptedCredentials } +function TtdEncryptedCredentials.Data: String; +begin + Result := ReadToSimpleType('data'); +end; +function TtdEncryptedCredentials.Hash: String; +begin + Result := ReadToSimpleType('hash'); +end; +function TtdEncryptedCredentials.Secret: String; +begin + Result := ReadToSimpleType('secret'); +end; +{ TtdPassportData } +function TtdPassportData.Credentials: ItdEncryptedCredentials; +begin + Result := ReadToClass('credentials'); +end; +function TtdPassportData.Data: TArray; +begin + Result := ReadToArray(TtdEncryptedPassportElement, 'data'); +end; +{ TtdProximityAlertTriggered } +function TtdProximityAlertTriggered.distance: Integer; +begin + Result := ReadToSimpleType('distance'); +end; +function TtdProximityAlertTriggered.traveler: ItdUser; +begin + Result := ReadToClass('traveler'); +end; +function TtdProximityAlertTriggered.watcher: ItdUser; +begin + Result := ReadToClass('watcher'); +end; +{ TtdChatPermissions } +function TtdChatPermissions.CanAddWebPagePreviews: Boolean; +begin + Result := ReadToSimpleType('can_add_web_page_previews'); +end; +function TtdChatPermissions.CanChangeInfo: Boolean; +begin + Result := ReadToSimpleType('can_change_info'); +end; +function TtdChatPermissions.CanInviteUsers: Boolean; +begin + Result := ReadToSimpleType('can_invite_users'); +end; +function TtdChatPermissions.CanManageTopics: Boolean; +begin + Result := ReadToSimpleType('can_manage_topics'); +end; + +function TtdChatPermissions.CanPinMessages: Boolean; +begin + Result := ReadToSimpleType('can_pin_messages'); +end; +function TtdChatPermissions.CanSendAudios: Boolean; +begin + Result := ReadToSimpleType('can_send_audios'); +end; + +function TtdChatPermissions.CanSendDocuments: Boolean; +begin + Result := ReadToSimpleType('can_send_documents'); +end; + +function TtdChatPermissions.CanSendMessages: Boolean; +begin + Result := ReadToSimpleType('can_send_messages'); +end; +function TtdChatPermissions.CanSendOtherMessages: Boolean; +begin + Result := ReadToSimpleType('can_send_other_messages'); +end; +function TtdChatPermissions.CanSendPhotos: Boolean; +begin + Result := ReadToSimpleType('can_send_photos'); +end; + +function TtdChatPermissions.CanSendPolls: Boolean; +begin + Result := ReadToSimpleType('can_send_polls'); +end; +function TtdChatPermissions.CanSendVideoNotes: Boolean; +begin + Result := ReadToSimpleType('can_send_video_notes'); +end; + +function TtdChatPermissions.CanSendVideos: Boolean; +begin + Result := ReadToSimpleType('can_send_videos'); +end; + +function TtdChatPermissions.CanSendVoiceNotes: Boolean; +begin + Result := ReadToSimpleType('can_send_voice_notes'); +end; + +{ TtdChatLocation } +function TtdChatLocation.Address: String; +begin + Result := ReadToSimpleType('address'); +end; +function TtdChatLocation.Location: ItdLocation; +begin + Result := ReadToClass('location'); +end; +{ TtdChatInviteLink } +function TtdChatInviteLink.creates_join_request: Boolean; +begin + Result := ReadToSimpleType('creates_join_request'); +end; +function TtdChatInviteLink.creator: ItdUser; +begin + Result := ReadToClass('creator'); +end; +function TtdChatInviteLink.expire_date: TDateTime; +begin + Result := ReadToDateTime('expire_date'); +end; +function TtdChatInviteLink.invite_link: String; +begin + Result := ReadToSimpleType('invite_link'); +end; +function TtdChatInviteLink.is_primary: Boolean; +begin + Result := ReadToSimpleType('is_primary'); +end; +function TtdChatInviteLink.is_revoked: Boolean; +begin + Result := ReadToSimpleType('is_revoked'); +end; +function TtdChatInviteLink.member_limit: Integer; +begin + Result := ReadToSimpleType('member_limit'); +end; +function TtdChatInviteLink.name: String; +begin + Result := ReadToSimpleType('name'); +end; +function TtdChatInviteLink.pending_join_request_count: Integer; +begin + Result := ReadToSimpleType('pending_join_request_count'); +end; +{ TtdChatMemberUpdated } +function TtdChatMemberUpdated.Chat: ItdChat; +begin + Result := ReadToClass('chat'); +end; +function TtdChatMemberUpdated.Date: TDateTime; +begin + Result := ReadToDateTime('date'); +end; +function TtdChatMemberUpdated.From: ItdUser; +begin + Result := ReadToClass('from'); +end; +function TtdChatMemberUpdated.invite_link: ItdChatInviteLink; +begin + Result := ReadToClass('invite_link'); +end; +function TtdChatMemberUpdated.new_chat_member: ItdChatMember; +begin + Result := ReadToClass('new_chat_member'); +end; +function TtdChatMemberUpdated.old_chat_member: ItdChatMember; +begin + Result := ReadToClass('old_chat_member'); +end; +function TtdChatMemberUpdated.via_chat_folder_invite_link: Boolean; +begin + Result := ReadToSimpleType('via_chat_folder_invite_link'); +end; + +{ TtdVoiceChatEnded } +function TtdVideoChatEnded.duration: Integer; +begin + Result := ReadToSimpleType('duration'); +end; +{ TtdVoiceChatParticipantsInvited } +function TtdVideoChatParticipantsInvited.Users: TArray; +begin + Result := ReadToArray(TtdUser, 'users'); +end; +{ TtdMessageAutoDeleteTimerChanged } +function TtdMessageAutoDeleteTimerChanged.message_auto_delete_time: TDateTime; +begin + Result := ReadToDateTime('message_auto_delete_time'); +end; +{ TtdVoiceChatScheduled } +function TtdVideoChatScheduled.start_date: TDateTime; +begin + Result := ReadToDateTime('start_date'); +end; +{ TtdChatMember } +function TtdChatMember.ChatMemberAdministrator: TtdChatMemberAdministrator; +begin + Result := ReadToClass('ChatMemberAdministrator'); +end; +function TtdChatMember.ChatMemberBanned: TtdChatMemberBanned; +begin + Result := ReadToClass('ChatMemberBanned'); +end; +function TtdChatMember.ChatMemberLeft: TtdChatMemberLeft; +begin + Result := ReadToClass('ChatMemberLeft'); +end; +function TtdChatMember.ChatMemberMember: TtdChatMemberMember; +begin + Result := ReadToClass('ChatMemberMember'); +end; +function TtdChatMember.ChatMemberOwner: TtdChatMemberOwner; +begin + Result := ReadToClass('ChatMemberOwner'); +end; +function TtdChatMember.ChatMemberRestricted: TtdChatMemberRestricted; +begin +end; +{ TtdChatMemberOwner } +function TtdChatMemberOwner.CustomTitle: String; +begin + Result := ReadToSimpleType('custom_title'); +end; +function TtdChatMemberOwner.IsAnonymous: Boolean; +begin + Result := ReadToSimpleType('is_anonymous'); +end; +function TtdChatMemberOwner.Status: TtdChatMemberStatus; +var + LStatus: string; +begin + Result := TtdChatMemberStatus.Member; + LStatus := ReadToSimpleType('status'); + if LStatus = 'creator' then + Result := TtdChatMemberStatus.Creator + else if LStatus = 'administrator' then + Result := TtdChatMemberStatus.Administrator + else if LStatus = 'member' then + Result := TtdChatMemberStatus.Member + else if LStatus = 'restricted' then + Result := TtdChatMemberStatus.Restricted + else if LStatus = 'left' then + Result := TtdChatMemberStatus.Left + else if LStatus = 'kicked' then + Result := TtdChatMemberStatus.Kicked + else + TBaseJson.UnSupported; +end; +function TtdChatMemberOwner.User: ItdUser; +begin + Result := ReadToClass('user'); +end; +{ TtdChatMemberAdministrator } +function TtdChatMemberAdministrator.CanBeEdited: Boolean; +begin + Result := ReadToSimpleType('can_be_edited'); +end; +function TtdChatMemberAdministrator.CanChangeInfo: Boolean; +begin + Result := ReadToSimpleType('can_change_info'); +end; +function TtdChatMemberAdministrator.CanDeleteMessages: Boolean; +begin + Result := ReadToSimpleType('can_delete_messages'); +end; +function TtdChatMemberAdministrator.CanEditMessages: Boolean; +begin + Result := ReadToSimpleType('can_edit_messages'); +end; +function TtdChatMemberAdministrator.CanInviteUsers: Boolean; +begin + Result := ReadToSimpleType('can_invite_users'); +end; +function TtdChatMemberAdministrator.CanManageChat: Boolean; +begin + Result := ReadToSimpleType('can_manage_chat'); +end; +function TtdChatMemberAdministrator.CanManageVideoChats: Boolean; +begin + Result := ReadToSimpleType('can_manage_video_chats '); +end; +function TtdChatMemberAdministrator.CanPinMessages: Boolean; +begin + Result := ReadToSimpleType('can_pin_messages'); +end; +function TtdChatMemberAdministrator.CanPostMessages: Boolean; +begin + Result := ReadToSimpleType('can_post_messages'); +end; +function TtdChatMemberAdministrator.CanPromoteMembers: Boolean; +begin + Result := ReadToSimpleType('can_promote_members'); +end; +function TtdChatMemberAdministrator.CanRestrictMembers: Boolean; +begin + Result := ReadToSimpleType('can_restrict_members'); +end; +function TtdChatMemberAdministrator.CustomTitle: String; +begin + Result := ReadToSimpleType('custom_title'); +end; +function TtdChatMemberAdministrator.IsAnonymous: Boolean; +begin + Result := ReadToSimpleType('is_anonymous'); +end; +function TtdChatMemberAdministrator.Status: TtdChatMemberStatus; +var + LStatus: string; +begin + Result := TtdChatMemberStatus.Member; + LStatus := ReadToSimpleType('status'); + if LStatus = 'creator' then + Result := TtdChatMemberStatus.Creator + else if LStatus = 'administrator' then + Result := TtdChatMemberStatus.Administrator + else if LStatus = 'member' then + Result := TtdChatMemberStatus.Member + else if LStatus = 'restricted' then + Result := TtdChatMemberStatus.Restricted + else if LStatus = 'left' then + Result := TtdChatMemberStatus.Left + else if LStatus = 'kicked' then + Result := TtdChatMemberStatus.Kicked + else + TBaseJson.UnSupported; +end; +function TtdChatMemberAdministrator.User: ItdUser; +begin + Result := ReadToClass('user'); +end; +{ TtdChatMemberMember } +function TtdChatMemberMember.Status: TtdChatMemberStatus; +var + LStatus: string; +begin + Result := TtdChatMemberStatus.Member; + LStatus := ReadToSimpleType('status'); + if LStatus = 'creator' then + Result := TtdChatMemberStatus.Creator + else if LStatus = 'administrator' then + Result := TtdChatMemberStatus.Administrator + else if LStatus = 'member' then + Result := TtdChatMemberStatus.Member + else if LStatus = 'restricted' then + Result := TtdChatMemberStatus.Restricted + else if LStatus = 'left' then + Result := TtdChatMemberStatus.Left + else if LStatus = 'kicked' then + Result := TtdChatMemberStatus.Kicked + else + TBaseJson.UnSupported; +end; +function TtdChatMemberMember.User: ItdUser; +begin + Result := ReadToClass('user'); +end; +{ TtdChatMemberRestricted } +function TtdChatMemberRestricted.CanAddWebPagePreviews: Boolean; +begin + Result := ReadToSimpleType('can_add_web_page_previews'); +end; +function TtdChatMemberRestricted.CanChangeInfo: Boolean; +begin + Result := ReadToSimpleType('can_change_info'); +end; +function TtdChatMemberRestricted.CanInviteUsers: Boolean; +begin + Result := ReadToSimpleType('can_invite_users'); +end; +function TtdChatMemberRestricted.CanManageTopics: Boolean; +begin + Result := ReadToSimpleType('can_manage_topics'); +end; + +function TtdChatMemberRestricted.CanPinMessages: Boolean; +begin + Result := ReadToSimpleType('can_pin_messages'); +end; +function TtdChatMemberRestricted.CanSendAudios: Boolean; +begin + Result := ReadToSimpleType('can_send_audios'); +end; + +function TtdChatMemberRestricted.CanSendDocuments: Boolean; +begin + Result := ReadToSimpleType('can_send_documents'); +end; + +function TtdChatMemberRestricted.CanSendMessages: Boolean; +begin + Result := ReadToSimpleType('can_send_messages'); +end; +function TtdChatMemberRestricted.CanSendOtherMessages: Boolean; +begin + Result := ReadToSimpleType('can_send_other_messages'); +end; +function TtdChatMemberRestricted.CanSendPhotos: Boolean; +begin + Result := ReadToSimpleType('can_send_photos'); +end; + +function TtdChatMemberRestricted.CanSendPolls: Boolean; +begin + Result := ReadToSimpleType('can_send_polls'); +end; +function TtdChatMemberRestricted.CanSendVideoNotes: Boolean; +begin + Result := ReadToSimpleType('can_send_video_notes'); +end; + +function TtdChatMemberRestricted.CanSendVideos: Boolean; +begin + Result := ReadToSimpleType('can_send_videos'); +end; + +function TtdChatMemberRestricted.CanSendVoiceNotes: Boolean; +begin + Result := ReadToSimpleType('can_send_voice_notes'); +end; + +function TtdChatMemberRestricted.IsMember: Boolean; +begin + Result := ReadToSimpleType('is_member'); +end; +function TtdChatMemberRestricted.Status: TtdChatMemberStatus; +var + LStatus: string; +begin + Result := TtdChatMemberStatus.Member; + LStatus := ReadToSimpleType('status'); + if LStatus = 'creator' then + Result := TtdChatMemberStatus.Creator + else if LStatus = 'administrator' then + Result := TtdChatMemberStatus.Administrator + else if LStatus = 'member' then + Result := TtdChatMemberStatus.Member + else if LStatus = 'restricted' then + Result := TtdChatMemberStatus.Restricted + else if LStatus = 'left' then + Result := TtdChatMemberStatus.Left + else if LStatus = 'kicked' then + Result := TtdChatMemberStatus.Kicked + else + TBaseJson.UnSupported; +end; +function TtdChatMemberRestricted.UntilDate: TDateTime; +begin + Result := ReadToDateTime('until_date'); +end; +function TtdChatMemberRestricted.User: ItdUser; +begin + Result := ReadToClass('user'); +end; +{ TtdChatMemberLeft } +function TtdChatMemberLeft.Status: TtdChatMemberStatus; +var + LStatus: string; +begin + Result := TtdChatMemberStatus.Member; + LStatus := ReadToSimpleType('status'); + if LStatus = 'creator' then + Result := TtdChatMemberStatus.Creator + else if LStatus = 'administrator' then + Result := TtdChatMemberStatus.Administrator + else if LStatus = 'member' then + Result := TtdChatMemberStatus.Member + else if LStatus = 'restricted' then + Result := TtdChatMemberStatus.Restricted + else if LStatus = 'left' then + Result := TtdChatMemberStatus.Left + else if LStatus = 'kicked' then + Result := TtdChatMemberStatus.Kicked + else + TBaseJson.UnSupported; +end; +function TtdChatMemberLeft.User: ItdUser; +begin + Result := ReadToClass('user'); +end; +{ TtdChatMemberBanned } +function TtdChatMemberBanned.Status: TtdChatMemberStatus; +var + LStatus: string; +begin + Result := TtdChatMemberStatus.Member; + LStatus := ReadToSimpleType('status'); + if LStatus = 'creator' then + Result := TtdChatMemberStatus.Creator + else if LStatus = 'administrator' then + Result := TtdChatMemberStatus.Administrator + else if LStatus = 'member' then + Result := TtdChatMemberStatus.Member + else if LStatus = 'restricted' then + Result := TtdChatMemberStatus.Restricted + else if LStatus = 'left' then + Result := TtdChatMemberStatus.Left + else if LStatus = 'kicked' then + Result := TtdChatMemberStatus.Kicked + else + TBaseJson.UnSupported; +end; +function TtdChatMemberBanned.UntilDate: TDateTime; +begin + Result := ReadToDateTime('until_date'); +end; +function TtdChatMemberBanned.User: ItdUser; +begin + Result := ReadToClass('user'); +end; +{ TtdChatJoinRequest } +function TtdChatJoinRequest.bio: String; +begin + Result := ReadToSimpleType('bio'); +end; +function TtdChatJoinRequest.chat: ItdChat; +begin + Result := ReadToClass('chat'); +end; +function TtdChatJoinRequest.date: TDateTime; +begin + Result := ReadToDateTime('date'); +end; +function TtdChatJoinRequest.from: ItdUser; +begin + Result := ReadToClass('from'); +end; +function TtdChatJoinRequest.invite_link: ItdChatInviteLink; +begin + Result := ReadToClass('invite_link'); +end; +function TtdChatJoinRequest.user_chat_id: Integer; +begin + Result := ReadToSimpleType('user_chat_id'); +end; + +{ TtdMessageID } + +function TtdMessageID.MessageId: Int64; +begin + Result := ReadToSimpleType('message_id'); +end; + +{ TtdWebAppInfo } + +constructor TtdWebAppInfo.Create(const Aurl: string); +var + AJson: String; +begin + surl := Aurl; + AJson := '{"url":"'+Aurl+'"}'; + inherited Create(AJson); +end; + +function TtdWebAppInfo.url: String; +begin + Result := ReadToSimpleType('url'); +end; + +{ TtdSentWebAppMessage } + +function TtdSentWebAppMessage.inline_message_id: String; +begin + Result := ReadToSimpleType('inline_message_id'); +end; + +{ TtdWebAppData } + +function TtdWebAppData.button_text: String; +begin + Result := ReadToSimpleType('button_text'); +end; + +function TtdWebAppData.data: String; +begin + Result := ReadToSimpleType('data'); +end; + +{ TtdMenuButtonCommands } + +constructor TtdMenuButtonCommands.Create( + const AMenuButtonType: TtdMenuButtonType); +var + AJson: String; +begin + AJson := '{"type":"'+AMenuButtonType.ToString+'"}'; + //Ftype_ := AMenuButtonType.ToString; + inherited Create(AJson); +end; + +function TtdMenuButtonCommands.&type: String; +begin + Result := ReadToSimpleType('type'); +end; + +{ TtdMenuButtonWebApp } + +constructor TtdMenuButtonWebApp.Create( + const AMenuButtonType: TtdMenuButtonType; AText: String; AWebApp: ItdWebAppInfo); +var + AJson: String; +begin + Ftype := AMenuButtonType.ToString; + Ftext := AText; + Fweb_app := AWebApp; + AJson := '{"type":"'+AMenuButtonType.ToString+ + ',"text":"'+AText+'","web_app":"{"url":"'+TtdWebAppInfo(AWebApp).url+'"}}'; + inherited Create(AJson); +end; + +function TtdMenuButtonWebApp.text: String; +begin + Result := ReadToSimpleType('text'); +end; + +function TtdMenuButtonWebApp.&type: String; +begin + Result := ReadToSimpleType('type'); + +{if VType = TtdMenuButtonType.MenuButtonCommands then + Result := TtdMenuButtonType.MenuButtonCommands + Else + if VType = TtdMenuButtonType.MenuButtonWebApp then + Result := TtdMenuButtonType.MenuButtonWebApp + Else + if VType = TtdMenuButtonType.MenuButtonDefault then + Result := TtdMenuButtonType.MenuButtonDefault;} + +end; + +function TtdMenuButtonWebApp.web_app: ItdWebAppInfo; +begin + Result := ReadToClass('web_app'); +end; + +{ TtdMenuButtonDefault } + +constructor TtdMenuButtonDefault.Create( + const AMenuButtonType: TtdMenuButtonType); +var + AJson: String; +begin + AJson := '{"type":"'+AMenuButtonType.ToString+'"}'; +// Ftype_ := AMenuButtonType.ToString; + inherited Create(AJson); +end; + +function TtdMenuButtonDefault.&type: String; +begin + Result := ReadToSimpleType('type'); +end; + +{ TtdChatAdministratorRights } + +function TtdChatAdministratorRights.can_change_info: Boolean; +begin + Result := ReadToSimpleType('can_change_info'); +end; + +function TtdChatAdministratorRights.can_delete_messages: Boolean; +begin + Result := ReadToSimpleType('can_delete_messages'); +end; + +function TtdChatAdministratorRights.can_edit_messages: Boolean; +begin + Result := ReadToSimpleType('can_edit_messages'); +end; + +function TtdChatAdministratorRights.can_invite_users: Boolean; +begin + Result := ReadToSimpleType('can_invite_users'); +end; + +function TtdChatAdministratorRights.can_manage_chat: Boolean; +begin + Result := ReadToSimpleType('can_manage_chat'); +end; + +function TtdChatAdministratorRights.can_manage_video_chats: Boolean; +begin + Result := ReadToSimpleType('can_manage_video_chats'); +end; + +function TtdChatAdministratorRights.can_pin_messages: Boolean; +begin + Result := ReadToSimpleType('can_pin_messages'); +end; + +function TtdChatAdministratorRights.can_post_messages: Boolean; +begin + Result := ReadToSimpleType('can_post_messages'); +end; + +function TtdChatAdministratorRights.can_promote_members: Boolean; +begin + Result := ReadToSimpleType('can_promote_members'); +end; + +function TtdChatAdministratorRights.can_restrict_members: Boolean; +begin + Result := ReadToSimpleType('can_restrict_members'); +end; + +constructor TtdChatAdministratorRights.Create; +var + AJson: String; +begin + AJson := '{"is_anonymous":"'+FIsAnonymous.ToJSONBool+'",'+ + '"can_manage_chat":"'+FCanManageChat.ToJSONBool+'",'+ + '"can_delete_messages":"'+FCanDeleteMessages.ToJSONBool+'",'+ + '"can_manage_video_chats":"'+FCanManageVideoChats.ToJSONBool+'",'+ + '"can_restrict_members":"'+FCanRestrictMembers.ToJSONBool+'",'+ + '"can_promote_members":"'+FCanPromoteMembers.ToJSONBool+'",'+ + '"can_change_info":"'+FCanChangeInfo.ToJSONBool+'",'+ + '"can_invite_users":"'+FCanInviteUsers.ToJSONBool+'",'+ + '"can_post_messages":"'+FCanPostMessages.ToJSONBool+'",'+ + '"can_edit_messages":"'+FCanEditMessages.ToJSONBool+'",'+ + '"can_pin_messages":"'+FCanPinMessages.ToJSONBool+'"}'; + + inherited Create(AJson); +end; + +function TtdChatAdministratorRights.is_anonymous: Boolean; +begin + Result := ReadToSimpleType('is_anonymous'); +end; + +function TtdChatAdministratorRights.ToJsonObject: string; +begin + Result := '{"is_anonymous":'+FIsAnonymous.ToJSONBool+','+ + '"can_manage_chat":'+FCanManageChat.ToJSONBool+','+ + '"can_delete_messages":'+FCanDeleteMessages.ToJSONBool+','+ + '"can_manage_video_chats":'+FCanManageVideoChats.ToJSONBool+','+ + '"can_restrict_members":'+FCanRestrictMembers.ToJSONBool+','+ + '"can_promote_members":'+FCanPromoteMembers.ToJSONBool+','+ + '"can_change_info":'+FCanChangeInfo.ToJSONBool+','+ + '"can_invite_users":'+FCanInviteUsers.ToJSONBool+','+ + '"can_post_messages":'+FCanPostMessages.ToJSONBool+','+ + '"can_edit_messages":'+FCanEditMessages.ToJSONBool+','+ + '"can_pin_messages":'+FCanPinMessages.ToJSONBool+'}'; +end; + +{ TtdThemeParams } + +function TtdThemeParams.Getbg_color: TColor; +var + StrColor : String; +begin + StrColor := ReadToSimpleType('bg_color'); + + Result := RGB( + StrToInt('$'+Copy(StrColor, 1, 2)), + StrToInt('$'+Copy(StrColor, 3, 2)), + StrToInt('$'+Copy(StrColor, 5, 2)) + ) ; + +{ +function TColorToHex(Color : TColor) : string; +begin + Result := + IntToHex(GetRValue(ColorToRGB(Color)), 2) + + IntToHex(GetGValue(ColorToRGB(Color)), 2) + + IntToHex(GetBValue(ColorToRGB(Color)), 2) ; +end; + + RGB( + StrToInt('$'+Copy(sColor, 1, 2)), + StrToInt('$'+Copy(sColor, 3, 2)), + StrToInt('$'+Copy(sColor, 5, 2)) + ) ; +} + +end; + +function TtdThemeParams.Getbutton_color: TColor; +var + StrColor : String; +begin + StrColor := ReadToSimpleType('button_color'); + + Result := RGB( + StrToInt('$'+Copy(StrColor, 1, 2)), + StrToInt('$'+Copy(StrColor, 3, 2)), + StrToInt('$'+Copy(StrColor, 5, 2)) + ) ; + +end; + +function TtdThemeParams.Getbutton_text_color: TColor; +var + StrColor : String; +begin + StrColor := ReadToSimpleType('button_text_color'); + + Result := RGB( + StrToInt('$'+Copy(StrColor, 1, 2)), + StrToInt('$'+Copy(StrColor, 3, 2)), + StrToInt('$'+Copy(StrColor, 5, 2)) + ) ; + +end; + +function TtdThemeParams.Gethint_color: TColor; +var + StrColor : String; +begin + StrColor := ReadToSimpleType('hint_color'); + + Result := RGB( + StrToInt('$'+Copy(StrColor, 1, 2)), + StrToInt('$'+Copy(StrColor, 3, 2)), + StrToInt('$'+Copy(StrColor, 5, 2)) + ) ; + +end; + +function TtdThemeParams.Getlink_color: TColor; +var + StrColor : String; +begin + StrColor := ReadToSimpleType('link_color'); + + Result := RGB( + StrToInt('$'+Copy(StrColor, 1, 2)), + StrToInt('$'+Copy(StrColor, 3, 2)), + StrToInt('$'+Copy(StrColor, 5, 2)) + ) ; + +end; + +function TtdThemeParams.Getsecondary_bg_color: TColor; +var + StrColor : String; +begin + StrColor := ReadToSimpleType('secondary_bg_color'); + + Result := RGB( + StrToInt('$'+Copy(StrColor, 1, 2)), + StrToInt('$'+Copy(StrColor, 3, 2)), + StrToInt('$'+Copy(StrColor, 5, 2)) + ) ; + +end; + +function TtdThemeParams.Gettext_color: TColor; +var + StrColor : String; +begin + StrColor := ReadToSimpleType('text_color'); + + Result := RGB( + StrToInt('$'+Copy(StrColor, 1, 2)), + StrToInt('$'+Copy(StrColor, 3, 2)), + StrToInt('$'+Copy(StrColor, 5, 2)) + ) ; + +end; + +{ TtdMenuButton } + +constructor TtdMenuButton.Create(const AMenuButtonType: TtdMenuButtonType); +var + AJson: String; +begin + AJson := '{"type":"'+AMenuButtonType.ToString+'"}'; + FMenuButtonType := AMenuButtonType; + inherited Create(AJson); +end; + +procedure TtdMenuButton.SetMenuButtonType(const Value: TtdMenuButtonType); +begin + FMenuButtonType := Value; +end; + +{ TtdForumTopicCreated } + +function TtdForumTopicCreated.icon_color: integer; +begin + Result := ReadToSimpleType('icon_color'); +end; + +function TtdForumTopicCreated.icon_custom_emoji_id: string; +begin + Result := ReadToSimpleType('icon_custom_emoji_id'); +end; + +function TtdForumTopicCreated.name: string; +begin + Result := ReadToSimpleType('name'); +end; + +{ TtdForumTopicEdited } + +function TtdForumTopicEdited.icon_custom_emoji_id: string; +begin + Result := ReadToSimpleType('icon_custom_emoji_id'); +end; + +function TtdForumTopicEdited.name: string; +begin + Result := ReadToSimpleType('name'); +end; + +{ TtdForumTopic } + +function TtdForumTopic.icon_color: integer; +begin + Result := ReadToSimpleType('icon_color'); +end; + +function TtdForumTopic.icon_custom_emoji_id: string; +begin + Result := ReadToSimpleType('icon_custom_emoji_id'); +end; + +function TtdForumTopic.message_thread_id: int64; +begin + Result := ReadToSimpleType('message_thread_id'); +end; + +function TtdForumTopic.name: string; +begin + Result := ReadToSimpleType('name'); +end; + +{ TtdUserShared } + +function TtdUserShared.request_id: integer; +begin + Result := ReadToSimpleType('request_id'); +end; + +function TtdUserShared.user_id: integer; +begin + Result := ReadToSimpleType('user_id'); +end; + +{ TtdChatShared } + +function TtdChatShared.chat_id: integer; +begin + Result := ReadToSimpleType('chat_id'); +end; + +function TtdChatShared.request_id: integer; +begin + Result := ReadToSimpleType('request_id'); +end; + +{ TtdBotDescription } + +function TtdBotDescription.description: string; +begin + Result := ReadToSimpleType('description'); +end; + +{ TtdBotShortDescription } + +function TtdBotShortDescription.short_description: string; +begin + Result := ReadToSimpleType('short_description'); +end; + +{ TtdInputSticker } + +function TtdInputSticker.emoji_list: TArray; +begin + Result := ReadToTArrayString('emoji_list'); +end; + +function TtdInputSticker.keywords: TArray; +begin + Result := ReadToTArrayString('keywords'); +end; + +function TtdInputSticker.mask_position: ItdMaskPosition; +begin + Result := ReadToClass('mask_position'); +end; + +function TtdInputSticker.sticker: string; +begin + Result := ReadToSimpleType('sticker'); +end; + +{ TtdWriteAccessAllowed } + +function TtdWriteAccessAllowed.web_app_name: string; +begin + Result := ReadToSimpleType('web_app_name'); +end; + +{ TtdSwitchInlineQueryChosenChat } + +function TtdSwitchInlineQueryChosenChat.allow_bot_chats: Boolean; +begin + Result := ReadToSimpleType('allow_bot_chats'); +end; + +function TtdSwitchInlineQueryChosenChat.allow_channel_chats: Boolean; +begin + Result := ReadToSimpleType('allow_channel_chats'); +end; + +function TtdSwitchInlineQueryChosenChat.allow_group_chats: Boolean; +begin + Result := ReadToSimpleType('allow_group_chats'); +end; + +function TtdSwitchInlineQueryChosenChat.allow_user_chats: Boolean; +begin + Result := ReadToSimpleType('allow_user_chats'); +end; + +function TtdSwitchInlineQueryChosenChat.query: string; +begin + Result := ReadToSimpleType('query'); +end; + +{ TtdtdBotName } + +function TtdBotName.name: string; +begin + Result := ReadToSimpleType('name'); +end; + +{ TODO 5 -oDiego -cTipos de Dados : Promover a Integração do metodo de leitura de lista de classes para correção deste tipo de dado } +{ TtdBotCommandScope } + +constructor TtdBotCommandScopeDefault.Create(const AType: TtdBotCommandScopeType); +var + AJson: String; +begin + AJson := AType.ToJsonObject; + + inherited Create(AJson); + +end; + + +function TtdBotCommandScopeDefault.ToJsonObject: string; +begin + +end; + +function TtdBotCommandScopeDefault.type_: string; +begin + Result := ReadToSimpleType('type'); +end; + +{ TtdBotCommandScopeChat } + +function TtdBotCommandScopeChat.chat_id: string; +begin + Result := ReadToSimpleType('chat_id'); +end; + +{ TtdBotCommandScopeChatMember } + +function TtdBotCommandScopeChatMember.user_id: integer; +begin + Result := ReadToSimpleType('user_id'); +end; + +End. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.InlineQueryResults.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.InlineQueryResults.pas new file mode 100644 index 0000000..d1c788e --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.InlineQueryResults.pas @@ -0,0 +1,897 @@ +unit TinjectTelegram.Types.InlineQueryResults; + +interface + +uses + REST.Json.Types, + TInjectTelegram.Types.ReplyMarkups, + TInjectTelegram.Types.InputMessageContents, + TInjectTelegram.Types.Enums, + TInjectTelegram.Types; + +type + + /// + /// This object represents a button to be shown above inline query results. + /// You must use exactly one of the optional fields. + /// + [JSONName('InlineQueryResultsButton')] + TtdInlineQueryResultsButton = class abstract + public + /// + /// Label text on the button + /// + [JSONName('text')] + Text: string; + + /// + /// Optional. Description of the Web App that will be launched when the + /// user presses the button. The Web App will be able to switch back to + /// the inline mode using the method switchInlineQuery inside the Web App. + /// + [JSONName('web_app')] + WebApp: ItdWebAppInfo; + + /// + /// Optional. Deep-linking parameter for the /start message sent to the + /// bot when a user presses the button. 1-64 characters, + /// only A-Z, a-z, 0-9, _ and - are allowed. + /// + [JSONName('start_parameter')] + StartParameter: string; + + end; + + + /// + /// This object represents one result of an inline query. Telegram clients + /// currently support results of the following 20 types /// + /// + TtdInlineQueryResult = class abstract + public + /// + /// Unique identifier for this result, 1-64 bytes + /// + [JSONName('id')] + ID: string; + /// + /// Type of the result + /// + [JSONName('type')] + &Type: string; + /// + /// Title of the result + /// + [JSonName('title')] + Title: String; + /// + /// Optional. Mode for parsing entities in the caption. + /// See formatting options for more details. + /// + [JSonName('parse_mode')] + ParseMode: TtdParseMode; + /// + /// Optional. Inline keyboard attached to the message + /// + [JSonName('input_message_content')] + InputMessageContent: TtdInputMessageContent; + /// + /// Optional. Inline keyboard attached to the message + /// + [JSonName('reply_markup')] + ReplyMarkup: TtdInlineKeyboardMarkup; + constructor Create; + destructor Destroy; override; + end; + + TtdInlineQueryResultNew = class(TtdInlineQueryResult) + public + /// + /// Optional. Url of the thumbnail for the result + /// + [JSONName('thumbnail_url')] + Thumbnail_url: string; + /// + /// Optional. Thumbnail width + /// + [JSONName('thumbnail_width')] + Thumbnail_width: Integer; + /// + /// Optional. Thumbnail height + /// + [JSONName('thumbnail_height')] + Thumbnail_height: Integer; + end; + + /// + /// Represents a link to an article or web page. + /// + [JSONName('InlineQueryResultArticle')] + TtdInlineQueryResultArticle = class(TtdInlineQueryResultNew) + public + /// + /// Optional. URL of the result + /// + [JSONName('url')] + Url: string; + /// + /// Optional. Pass True, if you don't want the URL to be shown in the + /// message + /// + [JSONName('hide_url')] + HideUrl: Boolean; + /// + /// Optional. Short description of the result + /// + [JSONName('description')] + Description: string; + constructor Create; + end; + + /// + /// Represents a link to an mp3 audio file. By default, this audio file + /// will be sent by the user. Alternatively, you can use + /// input_message_content to send a message with the specified content + /// instead of the audio. + /// + [JSONName('InlineQueryResultAudio')] + TtdInlineQueryResultAudio = class(TtdInlineQueryResultNew) + public + /// + /// A valid file identifier for the audio file + /// + [JSONName('audio_file_id')] + FileId: string; + /// + /// A valid URL for the audio file + /// + [JSONName('audio_url')] + Url: string; + /// + /// Optional. Performer + /// + [JSONName('performer')] + Performer: string; + /// + /// Optional. Audio duration in seconds + /// + [JSONName('audio_duration')] + Duration: Integer; + constructor Create; + end; + + /// + /// Represents a link to a result stored on the Telegram servers. By + /// default, this result will be sent by the user with an optional caption. + /// Alternatively, you can use input_message_content to send a message with + /// the specified content instead of the photo. + /// + TtdInlineQueryResultCached = class(TtdInlineQueryResult) + /// + /// Optional. Caption of the result to be sent, 0-200 characters + /// + [JSONName('caption')] + Caption: string; + end; + + /// + /// Represents a link to an mp3 audio file stored on the Telegram servers. + /// By default, this audio file will be sent by the user. Alternatively, + /// you can use input_message_content to send a message with the specified + /// content instead of the audio. + /// + [JSONName('InlineQueryResultCachedAudio')] + TtdInlineQueryResultCachedAudio = class(TtdInlineQueryResultCached) + public + /// + /// A valid file identifier for the audio file + /// + [JSONName('audio_file_id')] + FileId: string; + constructor Create; + end; + + /// + /// Represents a link to a file stored on the Telegram servers. By default, + /// this file will be sent by the user with an optional caption. + /// Alternatively, you can use input_message_content to send a message with + /// the specified content instead of the file. Currently, only pdf-files + /// and zip archives can be sent using this method. + /// + [JSONName('InlineQueryResultCachedDocument')] + TTgInlineQueryResultCachedDocument = class(TtdInlineQueryResultCached) + public + /// + /// A valid file identifier for the file + /// + [JSONName('document_file_id')] + FileId: string; + /// + /// Optional. Short description of the result + /// + [JSONName('description')] + Description: string; + constructor Create; + end; + + /// + /// Represents a link to an animated GIF file stored on the Telegram + /// servers. By default, this animated GIF file will be sent by the user + /// with an optional caption. Alternatively, you can use + /// input_message_content to send a message with specified content instead + /// of the animation. + /// + [JSONName('InlineQueryResultCachedGif')] + TtdInlineQueryResultCachedGif = class(TtdInlineQueryResultCached) + public + /// + /// A valid file identifier for the GIF file + /// + [JSONName('gif_file_id')] + FileId: string; + constructor Create; + end; + + /// + /// Represents a link to a video animation (H.264/MPEG-4 AVC video without + /// sound) stored on the Telegram servers. By default, this animated MPEG-4 + /// file will be sent by the user with an optional caption. Alternatively, + /// you can use input_message_content to send a message with the specified + /// content instead of the animation. + /// + [JSONName('InlineQueryResultCachedMpeg4Gif')] + TtdInlineQueryResultCachedMpeg4Gif = class(TtdInlineQueryResultCached) + public + /// + /// A valid file identifier for the MP4 file + /// + [JSONName('mpeg4_file_id')] + FileId: string; + constructor Create; + end; + + /// + /// Represents a link to a photo stored on the Telegram servers. By + /// default, this photo will be sent by the user with an optional caption. + /// Alternatively, you can use input_message_content to send a message with + /// the specified content instead of the photo. + /// + [JSONName('InlineQueryResultCachedPhoto')] + TtdInlineQueryResultCachedPhoto = class(TtdInlineQueryResultCached) + public + /// + /// A valid file identifier of the photo + /// + [JSONName('photo_file_id')] + FileId: string; + /// + /// Optional. Short description of the result + /// + [JSONName('description')] + Description: string; + constructor Create; + end; + + /// + /// Represents a link to a sticker stored on the Telegram servers. By + /// default, this sticker will be sent by the user. Alternatively, you can + /// use input_message_content to send a message with the specified content + /// instead of the sticker. + /// + [JSONName('InlineQueryResultCachedSticker')] + TtdInlineQueryResultCachedSticker = class(TtdInlineQueryResultCached) + public + /// + /// A valid file identifier of the sticker + /// + [JSONName('sticker_file_id')] + FileId: string; + constructor Create; + end; + + /// + /// Represents a link to a video file stored on the Telegram servers. By + /// default, this video file will be sent by the user with an optional + /// caption. Alternatively, you can use input_message_content to send a + /// message with the specified content instead of the video. + /// + [JSONName('InlineQueryResultCachedVideo')] + TtdInlineQueryResultCachedVideo = class(TtdInlineQueryResultCached) + public + /// + /// A valid file identifier for the video + /// + [JSONName('video_file_id')] + FileId: string; + /// + /// Optional. Short description of the result + /// + [JSONName('description')] + Description: string; + constructor Create; + end; + + /// + /// Represents a link to a voice message stored on the Telegram servers. By + /// default, this voice message will be sent by the user. Alternatively, + /// you can use input_message_content to send a message with the specified + /// content instead of the voice message. + /// + [JSONName('InlineQueryResultCachedVoice')] + TtdInlineQueryResultCachedVoice = class(TtdInlineQueryResultCached) + public + /// + /// A valid file identifier for the voice message + /// + [JSONName('voice_file_id')] + FileId: string; + constructor Create; + end; + + /// + /// Represents a contact with a phone number. By default, this contact will + /// be sent by the user. Alternatively, you can use input_message_content + /// to send a message with the specified content instead of the contact. + /// + [JSONName('InlineQueryResultContact')] + TtdInlineQueryResultContact = class(TtdInlineQueryResultNew) + public + /// + /// Contact's phone number + /// + [JSONName('phone_number')] + PhoneNumber: string; + /// + /// Contact's first name + /// + [JSONName('first_name')] + FirstName: string; + /// + /// Optional. Contact's last name + /// + [JSONName('last_name')] + LastName: string; + constructor Create; + end; + + /// + /// Represents a link to a file. By default, this file will be sent by the + /// user with an optional caption. Alternatively, you can use + /// input_message_content to send a message with the specified content + /// instead of the file. Currently, only .PDF and .ZIP files can be sent + /// using this method. + /// + [JSONName('InlineQueryResultDocument')] + TtdInlineQueryResultDocument = class(TtdInlineQueryResultNew) + public + /// + /// Optional. Caption of the document to be sent, 0-200 characters + /// + [JSONName('caption')] + Caption: string; + /// + /// A valid URL for the file + /// + [JSONName('document_url')] + Url: string; + /// + /// Mime type of the content of the file, either application/pdf or + /// application/zip + /// + [JSONName('mime_type')] + MimeType: string; + /// + /// Optional. Short description of the result + /// + [JSONName('description')] + Description: string; + constructor Create; + end; + + TtdInlineQueryResultGame = class + public + /// + /// Type of the result, must be game + /// + [JSONName('type')] + &type: String; + /// + /// Unique identifier for this result, 1-64 bytes + /// + [JSONName('id')] + id: String; + /// + /// Short name of the game. + /// + [JSONName('game_short_name')] + GameShortName: String; + /// + /// Optional. Inline keyboard attached to the message + /// + [JSONName('reply_markup')] + reply_markup: TtdInlineKeyboardMarkup; + constructor Create; + end; + + /// + /// Represents a link to an animated GIF file. By default, this animated + /// GIF file will be sent by the user with optional caption. Alternatively, + /// you can use input_message_content to send a message with the specified + /// content instead of the animation. + /// + [JSONName('InlineQueryResultGif')] + TtdInlineQueryResultGif = class(TtdInlineQueryResultNew) + public + /// + /// A valid URL for the GIF file. File size must not exceed 1MB + /// + [JSONName('gif_url')] + Url: string; + /// + /// Optional. Width of the GIF + /// + [JSONName('gif_width')] + Width: Integer; + /// + /// Optional. Height of the GIF + /// + [JSONName('gif_height')] + Height: Integer; + /// + /// Optional. Duration of the GIF + /// + [JSONName('gif_duration')] + Duration: Integer; + /// + /// Optional. Caption of the GIF file to be sent, 0-200 characters + /// + [JSONName('caption')] + Caption: string; + /// + /// URL of the static thumbnail for the result (jpeg or gif) + /// + [JSONName('thumbnail_url')] + ThumbnailUrl: string; + /// + /// Optional. MIME type of the thumbnail, must be one of + /// image/jpeg, image/gif, or video/mp4. + /// Defaults to image/jpeg + /// + [JSONName('thumbnail_mime_type')] + ThumbnailMimeType: string; + constructor Create; + end; + + /// + /// Represents a location on a map. By default, the location will be sent + /// by the user. Alternatively, you can use input_message_content to send a + /// message with the specified content instead of the location. + /// + [JSONName('InlineQueryResultLocation')] + TtdInlineQueryResultLocation = class(TtdInlineQueryResultNew) + public + /// + /// Location latitude in degrees + /// + [JSONName('latitude')] + Latitude: Single; + /// + /// Location longitude in degrees + /// + [JSONName('longitude')] + Longitude: Single; + /// + /// The direction in which user is moving, in degrees; 1-360. + /// For active live locations only. + /// + [JSONName('heading')] + Heading : Integer; + /// + /// The radius of uncertainty for the location, measured in meters; 0-1500 + /// + [JSONName('horizontal_accuracy')] + HorizontalAccuracy : Single; + /// + /// Period in seconds for which the location can be updated, + /// should be between 60 and 86400. + /// + [JSONName('live_period')] + LivePeriod : Integer; + /// + /// For live locations, a maximum distance for proximity alerts about + /// approaching another chat member, in meters. + /// Must be between 1 and 100000 if specified. + /// + [JSONName('proximity_alert_radius')] + ProximityAlertRadius : Integer; + constructor Create; + end; + + /// + /// Represents a link to a video animation (H.264/MPEG-4 AVC video without + /// sound). By default, this animated MPEG-4 file will be sent by the user + /// with optional caption. Alternatively, you can use input_message_content + /// to send a message with the specified content instead of the animation. + /// + [JSONName('InlineQueryResultMpeg4Gif')] + TtdInlineQueryResultMpeg4Gif = class(TtdInlineQueryResult) + public + /// + /// A valid URL for the MP4 file. File size must not exceed 1MB + /// + [JSONName('mpeg4_url')] + Url: string; + /// + /// Optional. Video width + /// + [JSONName('mpeg4_width')] + Width: Integer; + /// + /// Optional. Video height + /// + [JSONName('mpeg4_height')] + Height: Integer; + /// + /// Optional. Video height + /// + [JSONName('mpeg4_duration')] + Duration: Integer; + /// + /// Optional. Url of the thumbnail for the result + /// + [JSONName('thumbnail_url')] + ThumbnailUrl: string; + /// + /// Optional. MIME type of the thumbnail, must be one of + /// image/jpeg, image/gif, or video/mp4. + /// Defaults to image/jpeg + /// + [JSONName('thumbnail_mime_type ')] + ThumbnailMimeType : string; + /// + /// Optional. Caption of the MPEG-4 file to be sent, 0-200 characters + /// + [JSONName('caption')] + Caption: string; + constructor Create; + end; + + /// + /// Represents a link to a photo. By default, this photo will be sent by + /// the user with optional caption. Alternatively, you can use + /// input_message_content to send a message with the specified content + /// instead of the photo. + /// + [JSONName('InlineQueryResultPhoto')] + TtdInlineQueryResultPhoto = class(TtdInlineQueryResult) //TtdInlineQueryResult //TtdInlineQueryResultNew + public + /// + /// A valid URL of the photo. Photo must be in jpeg format. Photo size + /// must not exceed 5MB + /// + [JSONName('photo_url')] + Url: string; + /// + /// Optional. Width of the photo + /// + [JSONName('photo_width')] + Width: Integer; + /// + /// Optional. Height of the photo + /// + [JSONName('photo_height')] + Height: Integer; + /// + /// Optional. Url of the thumbnail for the result + /// + [JSONName('thumbnail_url')] + Thumbnail_url: string; + /// + /// Optional. Short description of the result + /// + [JSONName('description')] + Description: string; + /// + /// Optional. Caption of the photo to be sent, 0-200 characters + /// + [JSONName('caption')] + Caption: string; + constructor Create; + end; + + /// + /// Represents a venue. By default, the venue will be sent by the user. + /// Alternatively, you can use input_message_content to send a message with + /// the specified content instead of the venue. + /// + [JSONName('InlineQueryResultVenue')] + TtdInlineQueryResultVenue = class(TtdInlineQueryResultNew) + public + /// + /// Latitude of the venue location in degrees + /// + [JSONName('latitude')] + Latitude: Single; + /// + /// Longitude of the venue location in degrees + /// + [JSONName('longitude')] + Longitude: Single; + /// + /// Address of the venue + /// + [JSONName('address')] + Address: string; + /// + /// Optional. Foursquare identifier of the venue if known + /// + [JSONName('foursquare_id')] + FoursquareId: string; + /// + /// Optional. Google Place Id + /// + [JSONName('google_place_id')] + GooglePlaceId: string; + /// + /// Optional. Google Place Type + /// + [JSONName('google_place_type')] + GooglePlaceType : string; + constructor Create; + end; + + /// + /// Represents a link to a page containing an embedded video player or a + /// video file. By default, this video file will be sent by the user with + /// an optional caption. Alternatively, you can use input_message_content + /// to send a message with the specified content instead of the video. + /// + [JSONName('InlineQueryResultVideo')] + TtdInlineQueryResultVideo = class(TtdInlineQueryResult) //TtdInlineQueryResultNew + public + /// + /// A valid URL for the embedded video player or video file + /// + [JSONName('video_url')] + Url: string; + /// + /// Mime type of the content of video url, text/html or video/mp4 + /// + [JSONName('mime_type')] + MimeType: string; + /// + /// Optional. Video width + /// + [JSONName('video_width')] + Width: Integer; + /// + /// Optional. Video height + /// + [JSONName('video_height')] + Height: Integer; + /// + /// Optional. Video duration in seconds + /// + [JSONName('video_duration')] + Duration: Integer; + /// + /// Optional. Url of the thumbnail for the result + /// + [JSONName('thumbnail_url')] + Thumbnail_url: string; + /// + /// Optional. Short description of the result + /// + [JSONName('description')] + Description: string; + /// + /// Optional. Caption of the video to be sent, 0-200 characters + /// + [JSONName('caption')] + Caption: string; + constructor Create; + end; + + /// + /// Represents a link to a voice recording in an .ogg container encoded + /// with OPUS. By default, this voice recording will be sent by the user. + /// Alternatively, you can use input_message_content to send a message with + /// the specified content instead of the the voice message. + /// + [JSONName('InlineQueryResultVoice')] + TtdInlineQueryResultVoice = class(TtdInlineQueryResultNew) + public + /// + /// A valid URL for the voice recording + /// + [JSONName('voice_url')] + Url: string; + /// + /// Optional. Recording duration in seconds + /// + [JSONName('voice_duration')] + Duration: Integer; + constructor Create; + end; + +implementation + +uses + System.SysUtils; + +{ TtdInlineQueryResult } + +constructor TtdInlineQueryResult.Create; +begin + InputMessageContent := TtdInputMessageContent.Create; + ReplyMarkup := TtdInlineKeyboardMarkup.Create; +end; + +destructor TtdInlineQueryResult.Destroy; +begin + FreeAndNil(ReplyMarkup); + FreeAndNil(InputMessageContent); + inherited; +end; + +{ TtdInlineQueryResultArticle } + +constructor TtdInlineQueryResultArticle.Create; +begin + inherited; + &Type := 'article'; +end; + +{ TtdInlineQueryResultAudio } + +constructor TtdInlineQueryResultAudio.Create; +begin + inherited; + &Type := 'audio'; +end; + +{ TtdInlineQueryResultCachedAudio } + +constructor TtdInlineQueryResultCachedAudio.Create; +begin + inherited; + &Type := 'audio'; +end; + +{ TTgInlineQueryResultCachedDocument } + +constructor TTgInlineQueryResultCachedDocument.Create; +begin + inherited; + &Type := 'document'; +end; + +{ TtdInlineQueryResultCachedGif } + +constructor TtdInlineQueryResultCachedGif.Create; +begin + inherited; + &Type := 'gif'; +end; + +{ TtdInlineQueryResultCachedMpeg4Gif } + +constructor TtdInlineQueryResultCachedMpeg4Gif.Create; +begin + inherited; + &Type := 'mpeg4_gif'; +end; + +{ TtdInlineQueryResultCachedPhoto } + +constructor TtdInlineQueryResultCachedPhoto.Create; +begin + inherited; + &Type := 'photo'; +end; + +{ TtdInlineQueryResultCachedSticker } + +constructor TtdInlineQueryResultCachedSticker.Create; +begin + inherited; + &Type := 'sticker'; +end; + +{ TtdInlineQueryResultCachedVideo } + +constructor TtdInlineQueryResultCachedVideo.Create; +begin + inherited; + &Type := 'video'; +end; + +{ TtdInlineQueryResultCachedVoice } + +constructor TtdInlineQueryResultCachedVoice.Create; +begin + inherited; + &Type := 'voice'; +end; + +{ TtdInlineQueryResultContact } + +constructor TtdInlineQueryResultContact.Create; +begin + inherited; + &Type := 'contact'; +end; + +{ TtdInlineQueryResultDocument } + +constructor TtdInlineQueryResultDocument.Create; +begin + inherited; + &Type := 'document'; +end; + +{ TtdInlineQueryResultGame } + +constructor TtdInlineQueryResultGame.Create; +begin + inherited; + &Type := 'document'; +end; + +{ TtdInlineQueryResultGif } + +constructor TtdInlineQueryResultGif.Create; +begin + inherited; + &Type := 'gif'; +end; + +{ TtdInlineQueryResultLocation } + +constructor TtdInlineQueryResultLocation.Create; +begin + inherited; + &Type := 'location'; +end; + +{ TtdInlineQueryResultMpeg4Gif } + +constructor TtdInlineQueryResultMpeg4Gif.Create; +begin + inherited; + &Type := 'mpeg4_gif'; +end; + +{ TtdInlineQueryResultPhoto } + +constructor TtdInlineQueryResultPhoto.Create; +begin + inherited; + &Type := 'photo'; +end; + +{ TtdInlineQueryResultVenue } + +constructor TtdInlineQueryResultVenue.Create; +begin + inherited; + &Type := 'venue'; +end; + +{ TtdInlineQueryResultVideo } + +constructor TtdInlineQueryResultVideo.Create; +begin + inherited; + &Type := 'video'; +end; + +{ TtdInlineQueryResultVoice } + +constructor TtdInlineQueryResultVoice.Create; +begin + inherited; + &Type := 'voice'; +end; + +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.InputMessageContents.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.InputMessageContents.pas new file mode 100644 index 0000000..a45d4d6 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.InputMessageContents.pas @@ -0,0 +1,340 @@ +unit TinjectTelegram.Types.InputMessageContents; +interface +uses + REST.Json.Types, + TinjectTelegram.Types; +type + /// + /// This object represents the content of a message to be sent as a result + /// of an inline query. + /// + TtdInputMessageContent = class(TObject); + /// + /// Represents the content of a contact message to be sent as the result of + /// an inline query. + /// + TtdInputContactMessageContent = class(TtdInputMessageContent) + public + /// + /// Contact's phone number + /// + [JSONName('phone_number')] + PhoneNumber: string; + /// + /// Contact's first name + /// + [JSONName('first_name')] + FirstName: string; + /// + /// Optional. Contact's last name + /// + [JSONName('last_name')] + LastName: string; + constructor Create(const APhoneNumber, AFirstName, ALastName: string); + end; + /// + /// Represents the content of a location message to be sent as the result + /// of an inline query. + /// + TtdInputLocationMessageContent = class(TtdInputMessageContent) + public + /// + /// Latitude of the location in degrees + /// + [JSONName('latitude')] + Latitude: Single; + /// + /// Longitude of the location in degrees + /// + [JSONName('longitude')] + Longitude: Single; + /// + /// The direction in which user is moving, in degrees; 1-360. + /// For active live locations only. + /// + [JSONName('heading')] + Heading : Integer; + /// + /// The radius of uncertainty for the location, measured in meters; 0-1500 + /// + [JSONName('horizontal_accuracy')] + HorizontalAccuracy : Single; + /// + /// Period in seconds for which the location can be updated, + /// should be between 60 and 86400. + /// + [JSONName('live_period')] + LivePeriod : Integer; + /// + /// For live locations, a maximum distance for proximity alerts about + /// approaching another chat member, in meters. + /// Must be between 1 and 100000 if specified. + /// + [JSONName('proximity_alert_radius')] + ProximityAlertRadius : Integer; + constructor Create(ALatitude, ALongitude: Single); + end; + /// + /// Represents the content of a text message to be sent as the result of an + /// inline query. + /// + TtdInputTextMessageContent = class(TtdInputMessageContent) + public + /// + /// Text of the message to be sent, 1-4096 characters + /// + [JSONName('message_text')] + MessageText: string; + /// + /// Optional. Send Markdown or HTML, if you want Telegram apps to show + /// bold, italic, fixed-width text or inline URLs in your bot's message. + /// + [JSONName('parse_mode')] + ParseMode: string; + /// + /// Optional. Disables link previews for links in the sent message + /// + [JSONName('disable_web_page_preview')] + DisableWebPagePreview: Boolean; + constructor Create(const AMessageText, AParseMode: string; + ADisableWebPagePreview: Boolean); + end; + /// + /// Represents the content of a venue message to be sent as the result of + /// an inline query. + /// + TtdInputVenueMessageContent = class(TtdInputMessageContent) + public + /// + /// Latitude of the venue in degrees + /// + [JSONName('latitude')] + Latitude: Single; + /// + /// Longitude of the venue in degrees + /// + [JSONName('longitude')] + Longitude: Single; + /// + /// Name of the venue + /// + [JSONName('title')] + Title: string; + /// + /// Address of the venue + /// + [JSONName('address')] + Address: string; + /// + /// Optional. Foursquare identifier of the venue, if known + /// + [JSONName('foursquare_id')] + FoursquareId: string; + /// + /// Optional. Google Place Id + /// + [JSONName('google_place_id')] + GooglePlaceId: string; + /// + /// Optional. Google Place Type + /// + [JSONName('google_place_type')] + GooglePlaceType : string; + constructor Create(ALatitude, ALongitude: Single; const ATitle, AAddress, + AFoursquareId: string); + end; + + /// + /// Represents the content of an invoice message to be sent as the result + /// of an inline query. + /// + TtdInputInvoiceMessageContent = class(TtdInputMessageContent) + public + /// + /// Product name, 1-32 characters + /// + [JSONName('title')] + Title: String; + + /// + /// Product description, 1-255 characters + /// + [JSONName('description')] + Description: String; + + /// + /// Bot-defined invoice payload, 1-128 bytes. + /// This will not be displayed to the user, use for + /// your internal processes. + /// + [JSONName('payload')] + Payload: String; + + /// + /// Payment provider token, obtained via Botfather + /// + [JSONName('provider_token')] + ProviderToken: String; + + /// + /// Three-letter ISO 4217 currency code, see more on currencies + /// https://core.telegram.org/bots/payments#supported-currencies + /// + [JSONName('currency')] + Currency: String; + + /// + /// Price breakdown, a JSON-serialized list of + /// components (e.g. product price, tax, discount, + /// delivery cost, delivery tax, bonus, etc.) + /// + [JSONName('prices')] + Prices: TArray; + + /// + /// Optional. The maximum accepted amount for tips in + /// the smallest units of the currency (integer, not + /// float/double). For example, for a maximum tip of + /// US$ 1.45 pass max_tip_amount = 145. See the exp + /// parameter in currencies.json, it shows the number + /// of digits past the decimal point for each currency + /// (2 for the majority of currencies). Defaults to 0 + /// + [JSONName('max_tip_amount')] + MaxTipAmount: Integer; + + /// + /// Optional. A JSON-serialized array of suggested + /// amounts of tip in the smallest units of the + /// currency (integer, not float/double). At most 4 + /// suggested tip amounts can be specified. The + /// suggested tip amounts must be positive, passed in + /// a strictly increased order and must not exceed + /// max_tip_amount. + /// + [JSONName('suggested_tip_amounts')] + SuggestedTipAmounts: TArray; + + /// + /// Optional. A JSON-serialized object for data about + /// the invoice, which will be shared with the payment + /// provider. A detailed description of the required + /// fields should be provided by the payment provider. + /// + [JSONName('provider_data')] + ProviderData: String; + + /// + /// Optional. URL of the product photo for the invoice. + /// Can be a photo of the goods or a marketing image for + /// a service. People like it better when they see what + /// they are paying for. + /// + [JSONName('photo_url')] + PhotoUrl: String; + + /// + /// Optional. Photo size. + /// + [JSONName('photo_size')] + PhotoSize: Integer; + + /// + /// Optional. Photo width. + /// + [JSONName('photo_width')] + PhotoWidth: Integer; + + /// + /// Optional. Photo height. + /// + [JSONName('photo_height')] + PhotoHeight: Integer; + + /// + /// Optional. Pass True, if you require the user's + /// full name to complete the order + /// + [JSONName('need_name')] + NeedName: Boolean; + + /// + /// Optional. Pass True, if you require the user's + /// phone number to complete the order + /// + [JSONName('need_phone_number')] + NeedPhoneNumber: Boolean; + + /// + /// Optional. Pass True, if you require the user's + /// email to complete the order + /// + [JSONName('need_email')] + NeedEmail: Boolean; + + /// + /// Optional. Pass True, if you require the user's + /// shipping address to complete the order + /// + [JSONName('need_shipping_address')] + NeedShippingAddress: Boolean; + + /// + /// Optional. Pass True, if user's phone number + /// should be sent to provider. + /// + [JSONName('send_phone_number_to_provider')] + SendPhoneNumberToProvider: Boolean; + + /// + /// Optional. Pass True, if user's email address + /// should be sent to provider. + /// + [JSONName('send_email_to_provider')] + SendEmailToProvider: Boolean; + + /// + /// Optional. Pass True, if the final price depends + /// on the shipping method. + /// + [JSONName('is_flexible')] + IsFlexible: Boolean; + end; +implementation +{ TtdInputTextMessageContent } +constructor TtdInputTextMessageContent.Create(const AMessageText, AParseMode: + string; ADisableWebPagePreview: Boolean); +begin + inherited Create; + MessageText := AMessageText; + ParseMode := AParseMode; + DisableWebPagePreview := ADisableWebPagePreview; +end; +{ TtdInputContactMessageContent } +constructor TtdInputContactMessageContent.Create(const APhoneNumber, AFirstName, + ALastName: string); +begin + inherited Create; + PhoneNumber := APhoneNumber; + FirstName := AFirstName; + LastName := ALastName; +end; +{ TtdInputLocationMessageContent } +constructor TtdInputLocationMessageContent.Create(ALatitude, ALongitude: Single); +begin + inherited Create; + Latitude := ALatitude; + Longitude := ALongitude; +end; +{ TtdInputVenueMessageContent } +constructor TtdInputVenueMessageContent.Create(ALatitude, ALongitude: Single; + const ATitle, AAddress, AFoursquareId: string); +begin + inherited Create; + Latitude := ALatitude; + Longitude := ALongitude; + Title := ATitle; + Address := AAddress; + FoursquareId := AFoursquareId; +end; +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.Passport.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.Passport.pas new file mode 100644 index 0000000..d8e95bf --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.Passport.pas @@ -0,0 +1,126 @@ +unit TinjectTelegram.Types.Passport; + +interface + +uses + TInjectTelegram.Types.Enums; + +type + ItdPersonalDetails = interface + ['{F77CD641-E826-40C2-B0C3-4EFBB6779555}'] + function FirstName: string; + function LastName: string; + function BirthDate: TDate; + function Gender: TtdGender; + function CountryCode: string; + function ResidenceCountryCode: string; + end; + + ItdResidentialAdress = interface + ['{C7738CB9-9D6C-4635-9E78-657435238F76}'] + function StreetLine1: string; + function StreetLine2: string; + function City: string; + function State: string; + function CountryCode: string; + function PostCode: string; + end; + + ItdIdDocumentData = interface + ['{DF2A60A9-7D1D-424F-9001-D7F9E6390D1F}'] + function DocumentNo: string; + function ExpiryDate: TDate; + end; + + ItdPassportFile = interface + ['{17077F10-C8AE-462B-B11D-9C04B24D5327}'] + function file_id: string; + function file_unique_id: string; + function file_size: Integer; + function file_date: Integer; + end; + + ItdEncryptedPassportElement = interface + ['{17D1FDC0-B494-40A8-AB94-0E72681F9EFB}'] + function &type : string; + function data: string; + function phone_number: string; + function email: string; + function files: TArray; + function front_side: ItdPassportFile; + function reverse_side: ItdPassportFile; + function selfie: ItdPassportFile; + function translation: TArray; + function hash: string; + end; + + ItdEncryptedCredentials = interface + ['{48DD05EB-FD11-49C9-825B-75C8C3967A41}'] + function Data: String; + function Hash: String; + function Secret: String; + end; + + ItdPassportData = interface + ['{CB0B44FB-44D9-4BEC-9465-873C88DF9C67}'] + function Data: TArray; + function Credentials : ItdEncryptedCredentials; + end; + + ItdPassportElementError = interface + ['{7D48435F-5C65-40A1-B16E-309EEA297082}'] + function Source: String; + function &Type: String; + function message: String; + end; + + ItdPassportElementErrorDataField = interface(ItdPassportElementError) + ['{43CAAB75-E121-46E6-BC63-8714B87027B8}'] + function FieldName: String; + function DataHash: String; + end; + + ItdPassportElementErrorFrontSide = interface(ItdPassportElementError) + ['{8C3C2F4A-4E81-455A-BBA7-A9D56F21F4C3}'] + function FileHash: String; + end; + + ItdPassportElementErrorReverseSide = interface(ItdPassportElementError) + ['{E487FE0E-5DBE-4D34-A91C-9EF40B4512ED}'] + function FileHash: String; + end; + + ItdPassportElementErrorSelfie = interface(ItdPassportElementError) + ['{B504BB81-ECAD-4402-844F-8B715A6C84C6}'] + function FileHash: String; + end; + + ItdPassportElementErrorFile = interface(ItdPassportElementError) + ['{EF409AF3-102E-4877-8066-98CBE5BDEA1B}'] + function FileHash: String; + end; + + ItdPassportElementErrorFiles = interface(ItdPassportElementError) + ['{5CE829D4-6FE0-45B7-95F8-30E5E763568E}'] + function FileHashes: TArray; + end; + + ItdPassportElementErrorTranslationFile = interface(ItdPassportElementError) + ['{0CD91880-C6C5-42F8-8554-0343970A5EFC}'] + function FileHash: String; + end; + + ItdPassportElementErrorTranslationFiles = interface(ItdPassportElementError) + ['{0B94CFC6-F3AC-43D5-B8C3-E11DF85CCD31}'] + function FileHashes: TArray; + end; + + ItdPassportElementErrorUnspecified = interface(ItdPassportElementError) + ['{8670B86C-A54D-4A14-A686-8E164C3A8D9E}'] + function ElementHash: String; + end; + +implementation + +end. + diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.ReplyMarkups.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.ReplyMarkups.pas new file mode 100644 index 0000000..b6c665c --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.ReplyMarkups.pas @@ -0,0 +1,379 @@ +unit TinjectTelegram.Types.ReplyMarkups; +interface +uses + REST.Json.Types, + TInjectTelegram.Types, + TinjectTelegram.Types.Impl, + TinjectTelegram.Utils.JSON; +type + TtdButtonBase = class + private + [JSONName('text')] + FText: string; + public + property Text: string read FText write FText; + end; + TtdKeyboardButtonPollType = class + private + [JSONName('type')] + FType: string; + public + property &Type: string read FType write FType; + constructor Create(const AType: string); overload; + end; + + TtdKeyboardButtonRequestUser = class + private + [JSONName('request_id')] + Frequest_id: string; + [JSONName('user_is_bot')] + Fuser_is_bot: string; + [JSONName('user_is_premium')] + Fuser_is_premium: string; + public + property request_id: string read Frequest_id write Frequest_id; + property user_is_bot: string read Fuser_is_bot write Fuser_is_bot; + property user_is_premium: string read Fuser_is_premium write Fuser_is_premium; + constructor Create(const Arequest_id: string); overload; + end; + + TtdKeyboardButtonRequestChat = class + private + Fchat_is_created: boolean; + [JSONName('request_id')] + Frequest_id: integer; + Fbot_is_member: boolean; + Fuser_administrator_rights: TtdChatAdministratorRights; + Fchat_has_username: boolean; + Fchat_is_forum: boolean; + Fbot_administrator_rights: TtdChatAdministratorRights; + Fchat_is_channel: boolean; + public + property request_id: integer read Frequest_id write Frequest_id; + property chat_is_channel: boolean read Fchat_is_channel write Fchat_is_channel; + property chat_is_forum: boolean read Fchat_is_forum write Fchat_is_forum; + property chat_has_username: boolean read Fchat_has_username write Fchat_has_username; + property chat_is_created: boolean read Fchat_is_created write Fchat_is_created; + property user_administrator_rights: TtdChatAdministratorRights read Fuser_administrator_rights write Fuser_administrator_rights; + property bot_administrator_rights: TtdChatAdministratorRights read Fbot_administrator_rights write Fbot_administrator_rights; + property bot_is_member: boolean read Fbot_is_member write Fbot_is_member; + constructor Create(const Arequest_id: integer); overload; + end; + + TtdInlineKeyboardButton = class(TInterfacedObject, IReplyMarkup) + private + [JSONName('text')] + FText: string; + [JSONName('url')] + FURL: string; + [JSONName('callback_data')] + FCallbackData: string; + [JSONName('web_app')] + FWebApp: TtdWebAppInfo; + [JSONName('login_url')] + FLoginURL : ItdLoginURL; + [JSONName('switch_inline_query')] + FSwitchInlineQuery: string; + [JSONName('switch_inline_query_current_chat')] + FSwitchInlineQueryCurrentChat: string; + [JSONName('switch_inline_query_chosen_chat')] + FSwitchInlineQueryChosenChat: ItdSwitchInlineQueryChosenChat; + [JSONName('callback_game')] + FCallbackGame: string; + [JSONName('pay')] + FPay: Boolean; + public + constructor Create(const AText: string); overload; + constructor Create(const AText, ACallbackData: string); overload; + constructor Create(const AText, ACallbackData: string; url: string); overload; + constructor Create(const AText: string; AWebApp: TtdWebAppInfo); overload; + property Text: string read FText write FText; + property Url: string read FURL write FURL; + property CallbackData: string read FCallbackData write FCallbackData; + property WebApp: TtdWebAppInfo read FWebApp write FWebApp; + property LoginURL : ItdLoginURL read FLoginURL write FLoginURL; + property SwitchInlineQuery: string read FSwitchInlineQuery write FSwitchInlineQuery; + property SwitchInlineQueryCurrentChat: string read + FSwitchInlineQueryCurrentChat write FSwitchInlineQueryCurrentChat; + property SwitchInlineQueryChosenChat: ItdSwitchInlineQueryChosenChat read FSwitchInlineQueryChosenChat write FSwitchInlineQueryChosenChat; + property CallbackGame: string read FCallbackGame write FCallbackGame; + property Pay: Boolean read FPay write FPay; + + end; + + TtdInlineKeyboardWebAppButton = class(TInterfacedObject, IReplyMarkup) + private + [JSONName('text')] + FText: string; + [JSONName('web_app')] + FWebApp: TtdWebAppInfo; + public + constructor Create(const AText: string; AWebApp: TtdWebAppInfo); overload; + property Text: string read FText write FText; + property WebApp: TtdWebAppInfo read FWebApp write FWebApp; + end; + + TtdKeyboardButton = class (TInterfacedObject, IReplyMarkup){= class(TtdButtonBase)} + private + [JSONName('text')] + FText: string; + [JSONName('request_location')] + FRequestLocation: Boolean; + [JSONName('request_contact')] + FRequestContact: Boolean; + FRequestPoll : TtdKeyboardButtonPollType; + FRequestUser: TtdKeyboardButtonRequestUser; + FRequestChat: TtdKeyboardButtonRequestChat; + public + constructor Create(Const ARequestPoll: TtdKeyboardButtonPollType; AText: string; ARequestContact: Boolean = False; + ARequestLocation: Boolean = False); overload; + constructor Create(const AText: string; ARequestContact: Boolean = False; + ARequestLocation: Boolean = False); overload; + [JSONName('request_user')] + property RequestUser: TtdKeyboardButtonRequestUser read FRequestUser write FRequestUser; + [JSONName('request_chat')] + property RequestChat: TtdKeyboardButtonRequestChat read FRequestChat write FRequestChat; + + property RequestContact: Boolean read FRequestContact write FRequestContact; + property RequestLocation: Boolean read FRequestLocation write FRequestLocation; + [JSONName('request_poll')] //Resolvido + property RequestPoll : TtdKeyboardButtonPollType read FRequestPoll write FRequestPoll; + property Text: string read FText write FText; + end; + + TtdKeyboardWebAppButton = class (TtdKeyboardButton){= class(TtdButtonBase)} + private + [JSONName('web_app')] + FWebApp: TtdWebAppInfo; + public + constructor Create(const AText: string; AWebApp: TtdWebAppInfo); overload; + property WebApp: TtdWebAppInfo read FWebApp write FWebApp; + end; + + TtdReplyMarkup = class abstract(TInterfacedObject, IReplyMarkup) + private + [JSONName('selective')] + FSelective: Boolean; + public + property Selective: Boolean read FSelective write FSelective; + end; + TtdForceReply = class(TtdReplyMarkup) + private + [JSONName('force_reply')] + FForce: Boolean; + [JSONName('input_field_placeholder')] + FInputFieldPlaceholder: String; + public + property Force: Boolean read FForce write FForce; + property InputFieldPlaceholder: String read FInputFieldPlaceholder write FInputFieldPlaceholder; + end; + TtdInlineKeyboardMarkup = class(TInterfacedObject, IReplyMarkup) + private + [JSONName('inline_keyboard')] + FKeyboard: TArray>; + public + procedure AddRow(AKeyboardRow: TArray); + constructor Create; overload; + constructor Create(AInlineKeyboardRow: TArray); overload; + constructor Create(AInlineKeyboard: TArray>); + overload; + destructor Destroy; override; + property Keyboard: TArray> read FKeyboard + write FKeyboard; + end; + TtdReplyKeyboardMarkup = class(TtdReplyMarkup) + private + [JSONName('resize_keyboard')] + FResizeKeyboard: Boolean; + [JSONName('one_time_keyboard')] + FOneTimeKeyboard: Boolean; + [JSONName('selective')] + FSelective: Boolean; + [JSONName('keyboard')] + FKeyboard: TArray>; + [JSONName('input_field_placeholder')] + FInputFieldPlaceholder: String; + [JSONName('is_persistent')] + FIsPersistent: Boolean; + public + procedure AddRow(AKeyboardRow: TArray); + constructor Create(AResizeKeyboard, AOneTimeKeyboard: Boolean); overload; + constructor Create(AKeyboardRow: TArray; AResizeKeyboard: + Boolean = False; AOneTimeKeyboard: Boolean = False); overload; + constructor Create(AKeyboard: TArray>; + AResizeKeyboard: Boolean = False; AOneTimeKeyboard: Boolean = False); overload; + destructor Destroy; override; + property Keyboard: TArray> read FKeyboard write FKeyboard; + property OneTimeKeyboard: Boolean read FOneTimeKeyboard write FOneTimeKeyboard; + property ResizeKeyboard: Boolean read FResizeKeyboard write FResizeKeyboard; + property Selective: Boolean read FSelective write FSelective; + property IsPersistent: Boolean read FIsPersistent write FIsPersistent; + property InputFieldPlaceholder: String read FInputFieldPlaceholder write FInputFieldPlaceholder; + end; + TtdReplyKeyboardRemove = class(TtdReplyMarkup) + private + [JSONName('remove_keyboard')] + FRemoveKeyboard: Boolean; + public + constructor Create(ARemoveKeyboard: Boolean = True); + property RemoveKeyboard: Boolean read FRemoveKeyboard write FRemoveKeyboard; + end; +implementation +uses + System.SysUtils; +constructor TtdInlineKeyboardButton.Create(const AText: string); +begin + Text := AText; +end; +constructor TtdInlineKeyboardButton.Create(const AText, ACallbackData: string); +begin + Self.Create(AText); + Self.CallbackData := ACallbackData; +end; +constructor TtdKeyboardButton.Create(Const ARequestPoll: TtdKeyboardButtonPollType; AText: string; ARequestContact: Boolean = False; + ARequestLocation: Boolean = False); +begin + inherited Create; + Self.Text := AText; + Self.RequestContact := ARequestContact; + Self.RequestLocation := ARequestLocation; + if ARequestPoll <> nil then + Begin + Self.RequestPoll := ARequestPoll; + End; +end; +constructor TtdInlineKeyboardMarkup.Create(AInlineKeyboardRow: TArray< + TtdInlineKeyboardButton>); +begin + inherited Create; + AddRow(AInlineKeyboardRow); +end; +procedure TtdInlineKeyboardMarkup.AddRow(AKeyboardRow: TArray); +begin + SetLength(FKeyboard, Length(FKeyboard) + 1); + FKeyboard[High(FKeyboard)] := AKeyboardRow; +end; +constructor TtdInlineKeyboardMarkup.Create(AInlineKeyboard: TArray>); +var + i: Integer; +begin + Self.Create; + for i := Low(AInlineKeyboard) to High(AInlineKeyboard) do + AddRow(AInlineKeyboard[i]); +end; +destructor TtdInlineKeyboardMarkup.Destroy; +var + i, j: Integer; +begin + for i := Low(FKeyboard) to High(FKeyboard) do + for j := Low(FKeyboard[i]) to High(FKeyboard[i]) do + FKeyboard[i, j].Free; + inherited; +end; +constructor TtdInlineKeyboardMarkup.Create; +begin + inherited Create; +end; +constructor TtdReplyKeyboardMarkup.Create(AKeyboardRow: TArray; AResizeKeyboard, AOneTimeKeyboard: Boolean); +begin + inherited Create; + AddRow(AKeyboardRow); + ResizeKeyboard := AResizeKeyboard; + OneTimeKeyboard := AOneTimeKeyboard; +end; +procedure TtdReplyKeyboardMarkup.AddRow(AKeyboardRow: TArray); +begin + SetLength(FKeyboard, Length(FKeyboard) + 1); + FKeyboard[High(FKeyboard)] := AKeyboardRow; +end; +constructor TtdReplyKeyboardMarkup.Create(AKeyboard: TArray>; AResizeKeyboard, AOneTimeKeyboard: Boolean); +begin + inherited Create; + Keyboard := AKeyboard; + ResizeKeyboard := AResizeKeyboard; + OneTimeKeyboard := AOneTimeKeyboard; +end; +destructor TtdReplyKeyboardMarkup.Destroy; +var + i, j: Integer; +begin + for i := Low(FKeyboard) to High(FKeyboard) do + for j := Low(FKeyboard[i]) to High(FKeyboard[i]) do + FKeyboard[i, j].Free; + inherited; +end; +constructor TtdReplyKeyboardMarkup.Create(AResizeKeyboard, AOneTimeKeyboard: Boolean); +begin + inherited Create; + ResizeKeyboard := AResizeKeyboard; + OneTimeKeyboard := AOneTimeKeyboard; +end; +constructor TtdReplyKeyboardRemove.Create(ARemoveKeyboard: Boolean); +begin + inherited Create; + RemoveKeyboard := ARemoveKeyboard; +end; +{ TtdKeyboardButtonPollType } +constructor TtdKeyboardButtonPollType.Create(const AType: string); +begin + &Type := AType; +end; +constructor TtdKeyboardButton.Create(const AText: string; ARequestContact, + ARequestLocation: Boolean); +begin + Self.Text := AText; + Self.RequestContact := ARequestContact; + Self.RequestLocation := ARequestLocation; + inherited Create; +end; +constructor TtdInlineKeyboardButton.Create(const AText, ACallbackData: string; + url: string); +begin + Self.Create(AText); + Self.CallbackData := ACallbackData; + Self.Url := url; +end; + +{ TtdInlineKeyboardWebAppButton } + +constructor TtdInlineKeyboardWebAppButton.Create(const AText: string; + AWebApp: TtdWebAppInfo); +begin + Text := AText; + WebApp := AWebApp; +end; + +{ TtdKeyboardWebAppButton } + +constructor TtdKeyboardWebAppButton.Create(const AText: string; + AWebApp: TtdWebAppInfo); +begin + Self.Create(AText); + Self.FWebApp := AWebApp; +end; + +constructor TtdInlineKeyboardButton.Create(const AText: string; + AWebApp: TtdWebAppInfo); +begin + WebApp := AWebApp; + Text := AText;; +end; + +{ TtdKeyboardButtonRequestUser } + +constructor TtdKeyboardButtonRequestUser.Create(const Arequest_id: string); +begin + Frequest_id := Arequest_id; +end; + +{ TtdKeyboardButtonRequestChat } + +constructor TtdKeyboardButtonRequestChat.Create(const Arequest_id: integer); +begin + Frequest_id := Arequest_id; +end; + +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.pas new file mode 100644 index 0000000..f44bb7f --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Types.pas @@ -0,0 +1,977 @@ +unit TInjectTelegram.Types; +interface +uses + REST.Json.Types, + System.Classes, + TinjectTelegram.Types.Enums, + TinjectTelegram.Types.Passport, Vcl.Graphics; +type + ItdUser = interface + ['{EEE1275B-F21B-476F-9F0C-768C702FF34B}'] + function ID: Int64; + function IsBot: Boolean; + function FirstName: string; + function LastName: string; + function Username: string; + function LanguageCode: string; + function isPremium: Boolean; + function AddedToAttachmentMenu: string; + function CanJoinGroups: Boolean; //can_join_groups Boolean Optional. True, if the bot can be invited to groups. Returned only in getMe. + function CanReadAllGroupMessages: Boolean; //can_read_all_group_messages Boolean Optional. True, if privacy mode is disabled for the bot. Returned only in getMe. + function SupportsInlineQueries: Boolean; //supports_inline_queries Boolean Optional. True, if the bot supports inline queries. Returned only in + end; + + ItdChatMember = interface + ['{BE073F97-DA34-43E6-A15E-14A2B90CAB7E}'] + end; + + ItdChatPhoto = interface + ['{011E7CC4-8777-4E0F-95A6-6E5C87461DCD}'] + function SmallFileId: string; + function SmallFileUniqueId: string; + function BigFileId: string; + function BigFileUniqueId: string; + end; + ItdMessage = interface; + ItdLocation = interface; + ItdChatLocation = interface + ['{718CA534-E831-41F8-A976-68501F6DCA02}'] + function Location: ItdLocation; + function Address: String; //Limit of a 64 character + end; + + ItdChatPermissions = interface; + + ItdChat = interface + ['{5CE94B3E-312E-48FA-98A4-4C34E16A5DC7}'] + function ID: Int64; + function TypeChat: TtdChatType; + function Title: string; + function Username: string; + function FirstName: string; + function LastName: string; + function is_forum: boolean; + function Photo: ItdChatPhoto; + function active_usernames: Tarray; + function emoji_status_custom_emoji_id: string; + function Bio: String; + function HasPrivateForwards: Boolean; + function has_restricted_voice_and_video_messages: boolean; + function JoinToSendMessages: Boolean; //New + function JoinByRequest: Boolean; //New + function Description: string; + function InviteLink: string; + function PinnedMessage: ItdMessage; + function Permissions: ItdChatPermissions; + function SlowModeDelay: Integer; + function MessageAutoDeleteTime: integer; + function has_aggressive_anti_spam_enabled: Boolean; + function has_hidden_members: Boolean; + function HasProtectedContent: boolean; + function StickerSetName: string; + function CanSetStickerSet: Boolean; + function LinkedChatId: Integer; + function location: ItdChatLocation; + function ToJSonStr: String; + function ToString: String; + end; + ItdMessageEntity = interface + ['{0F510BB7-8436-426E-8ECC-46742E3183E1}'] + function TypeMessage: TtdMessageEntityType; + function Offset: Int64; + function Length: Int64; + function Url: string; + function User: ItdUser; + function language: string; + function custom_emoji_id: string; + end; + ItdFile = interface + ['{7A0DE9B9-939C-4079-B6A5-997AEA9497C9}'] + function FileId: string; + function FileUniqueId: string; + function FileSize: Int64; + function FilePath: string; + function CanDownload: Boolean; + function GetFileUrl(const AToken: string): string; + end; + ItdPhotoSize = interface(ItdFile) + ['{FF71291C-4E00-483E-8363-AF160CE78A4F}'] + function Width: Int64; + function Height: Int64; + end; + ItdAudio = interface(ItdFile) + ['{8220DE57-2A5E-4B77-8B62-A3268E15D938}'] + function Duration: Int64; + function Performer: string; + function Title: string; + function FileName: string; + function MimeType: string; + function Thumbnail: ItdPhotoSize; + end; + ItdDocument = interface(ItdFile) + ['{2B4DF418-FE55-490B-B119-46B9CB846609}'] + function Thumbnail: ItdPhotoSize; + function FileName: string; + function MimeType: string; + end; + ItdMaskPosition = interface + ['{D74500FF-8332-4BDF-BC26-9854A2D10529}'] + function Point: TtdMaskPositionPoint; + function XShift: Single; + function YShift: Single; + function Scale: Single; + end; + ItdSticker = interface(ItdFile) + ['{C2598C8D-506F-4208-80AA-ED2731C92192}'] + function type_: string; + function Width: Int64; + function Height: Int64; + function is_animated: Boolean; + function is_video: Boolean; + function Thumbnail: ItdPhotoSize; + function Emoji: string; + function SetName: string; + function PremiumAnimation: ItdFile; + function MaskPosition: ItdMaskPosition; + function CustomEmojiId: Int64; + function NeedsRepainting: boolean; + end; + ItdStickerSet = interface + ['{FCE66210-3EFF-4D97-9077-473AAFE9FC97}'] + function Name: string; + function Title: string; + function StickerType: TtdStickerType; + function is_animated: Boolean; + function is_video: Boolean; + function Stickers: TArray; + function Thumbnail: ItdPhotoSize; + end; + ItdVideo = interface(ItdFile) + ['{520EB672-788A-4B7B-9BD9-1A569FD7C417}'] + function Width: Int64; + function Height: Int64; + function Duration: Int64; + function Thumbnail: ItdPhotoSize; + function FileName: string; + function MimeType: string; + end; + ItdVideoNote = interface(ItdFile) + ['{D15B034D-9C4E-459A-9735-E63973813C6F}'] + function Length: Int64; + function Duration: Int64; + function Thumbnail: ItdPhotoSize; + end; + ItdVoice = interface(ItdFile) + ['{99D91D3C-FC16-40CA-BA72-EFA8F5D0F5F9}'] + function Duration: Int64; + function MimeType: string; + end; + ItdContact = interface + ['{57113A43-41E0-4846-9CBA-A355400E3938}'] + function PhoneNumber: string; + function FirstName: string; + function LastName: string; + function UserId: Int64; + function VCard: string; + end; + ItdPollOption = interface + ['{2D275027-A366-4D2E-A211-176A17DF2880}'] + function text : String; + function voter_count: String; + end; + ItdPollAnswer = interface + ['{E9FDBD08-6728-44AC-B9F8-31FAF9CD8669}'] + function poll_id: String; + function user: ItdUser; + function option_ids: TArray; + end; + ItdPoll = interface + ['{6FD83DB0-02CA-4840-9A40-CB257589EC3B}'] + function id : String; + function question: String; + function options: TArray; + function total_voter_count: Integer; + function is_closed: Boolean; + function is_anonymous: Boolean; + function &type: String; + function allows_multiple_answers: Boolean; + function correct_option_id: Integer; + end; + ItdDice = interface + ['{2B88A5D6-F4B6-40D5-A324-52B2B7CE999C}'] + function Emoji: String; // Emoji on which the dice throw animation is based + function value: Integer; + end; + ItdLocation = interface + ['{6FE14ED9-0C53-4C24-8033-390A5F31B414}'] + // + function GetLongitude: Single; + function GetLatitude: Single; + procedure SetLatitude(const Value: Single); + procedure SetLongitude(const Value: Single); + //New in API 5.0 + function GetHorizontalAccuracy: Single; + procedure SetHorizontalAccuracy(const Value: Single); + function GetLivePeriod: Integer; + procedure SetLivePeriod(const Value: Integer); + function GetHeading: Integer; + procedure SetHeading(const Value: Integer); + function GetProximityAlertRadius: Integer; + procedure SetProximityAlertRadius(const Value: Integer); + // + property Longitude: Single read GetLongitude write SetLongitude; + property Latitude: Single read GetLatitude write SetLatitude; + //New in API 5.0 + property horizontal_accuracy: Single read GetHorizontalAccuracy write SetHorizontalAccuracy; + property live_period: Integer read GetLivePeriod write SetLivePeriod; + property heading: Integer read GetHeading write SetHeading; + property proximity_alert_radius: Integer read GetProximityAlertRadius write SetProximityAlertRadius; + end; + //Atualizado para versão 4.8 + ItdVenue = interface + ['{26E74395-EAA1-4668-BB6A-A2B8F61DE6BF}'] + function Location: ItdLocation; + function Title: string; + function Address: string; + function FoursquareId: string; + function FoursquareType: string; + //New in API 5.0 + function google_place_id: string; + function google_place_type: string; + end; + //New in API 5.0 + ItdProximityAlertTriggered = Interface + ['{6D51B8A0-575C-491C-A5A0-E77AEAD44952}'] + function traveler: ItdUser; + function watcher: ItdUser; + function distance: Integer; + End; + ItdAnimation = interface + ['{A0C6E374-590C-469B-AC76-F91135899FC5}'] + function FileId: string; + function Thumbnail: ItdPhotoSize; + function FileName: string; + function MimeType: string; + function FileSize: Int64; + end; + ItdGameHighScore = interface + ['{19B46591-74A9-425F-BD3E-8342CE0B61C9}'] + function Position: Int64; + function User: ItdUser; + function Score: Int64; + end; + ItdGame = interface + ['{29F4A7BE-07AB-4F9C-B7AE-1058B65F3AAD}'] + function Title: string; + function Description: string; + function Photo: TArray; + function Text: string; + function TextEntities: TArray; + function Animation: ItdAnimation; + end; + ItdInvoice = interface + ['{1D8923E1-068C-4747-84DE-A1B3B4674FD3}'] + function Title: string; + function Description: string; + function StartParameter: string; + function Currency: string; + function TotalAmount: Int64; + end; + ItdOrderInfo = interface; + ItdSuccessfulPayment = interface + ['{B2BE36C2-61F9-4D4B-AB9D-75BB524661AB}'] + function Currency: string; + function TotalAmount: Int64; + function InvoicePayload: string; + function ShippingOptionId: string; + function OrderInfo: ItdOrderInfo; + function TelegramPaymentChargeId: string; + function ProviderPaymentChargeId: string; + end; + ItdChatInviteLink = Interface //New in API 5.1 + ['{0F5B2D9E-8372-496E-9D30-7454D67D5F29}'] + function invite_link: String; + function creator: ItdUser; + function creates_join_request: Boolean; + function is_primary: Boolean; + function is_revoked: Boolean; + function name: String; + function expire_date: {Integer}TDateTime; + function member_limit: Integer; + function pending_join_request_count: Integer; + End; + //New Methodo in de version 5.0.1 + ItdChatPermissions = interface + ['{D6EDBDCF-30DE-4597-B39B-5E31FFBF8E68}'] + function CanSendMessages: Boolean; + function CanSendAudios: Boolean; + function CanSendDocuments: Boolean; + function CanSendPhotos: Boolean; + function CanSendVideos: Boolean; + function CanSendVideoNotes: Boolean; + function CanSendVoiceNotes: Boolean; + function CanSendPolls: Boolean; + function CanSendOtherMessages: Boolean; + function CanAddWebPagePreviews: Boolean; + function CanChangeInfo: Boolean; + function CanInviteUsers: Boolean; + function CanPinMessages: Boolean; + function CanManageTopics: Boolean; + end; + ItdChatJoinRequest = interface //New in API 5.4 + ['{1C15162D-4CB0-4F06-A1ED-A5987EF9C85A}'] + function chat: ItdChat; + function from: ItdUser; + function user_chat_id: Integer; + function date: TDateTime; {Integer Unix Time} + function bio: String; + function invite_link: ItdChatInviteLink; + end; + ItdChatMemberUpdated = Interface //New in API 5.1 + ['{C88B26D2-29F1-4EB9-B812-7FF7A4E73212}'] + function chat: ItdChat; + function from: ItdUser; + function date: {Integer Unix Time}TDateTime; + function old_chat_member: ItdChatMember; + function new_chat_member: ItdChatMember; + function invite_link: ItdChatInviteLink; + function via_chat_folder_invite_link: Boolean; + End; + ItdVideoChatScheduled = Interface //New in API 5.2 + ['{94AF9767-8E9E-4FE8-96AC-BC27A0853E2A}'] + function start_date: TDateTime; //Point in time (Unix timestamp) when the voice chat is supposed to be started by a chat administrator + End; + ItdVideoChatStarted = Interface //New in API 5.1 + ['{9877BC33-72C7-4BC9-B462-C1D5E90EF902}'] + End; + ItdVideoChatEnded = Interface //New in API 5.1 + ['{B769F63E-11FA-42D0-9DAF-6AC9B41FB5E5}'] + function duration: Integer; + End; + ItdVideoChatParticipantsInvited = Interface //New in API 5.1 + ['{7F82D50A-0FED-4E80-882B-16125D169627}'] + function Users: TArray; + End; + ItdMessageAutoDeleteTimerChanged = Interface + ['{DC738F55-8786-4DB2-B3EC-2EEEBA369665}'] + function message_auto_delete_time: TDateTime; + End; + IReplyMarkup = interface + ['{4DCF23BA-8A37-46EF-A832-F325532B509A}'] + end; + + ItdInlineKeyboardMarkup = interface + ['{62153B8C-D895-418A-BB2A-F82C36BFD276}'] + end; + + ItdWebAppData = interface; + + ItdWriteAccessAllowed = interface + ['{6D9779F7-356F-4ACB-AC51-B48ED3ACAC8B}'] + function web_app_name: string; + end; + + ItdForumTopic = interface + ['{5043B054-7881-48CD-A370-218F3E7A45AC}'] + function message_thread_id: int64; + function name: string; + function icon_color: integer; + function icon_custom_emoji_id: string; + end; + + ItdForumTopicCreated = interface + ['{4271D7D3-93F6-4A54-917A-45F0ECAB2EC5}'] + function name: string; + function icon_color: integer; + function icon_custom_emoji_id: string; + end; + + ItdForumTopicClosed = interface + ['{46763DBB-1D31-45E4-9A0A-B690FB4D5A3D}'] + end; + + ItdForumTopicEdited = interface + ['{5284D187-B7D8-48B6-BCED-9FCAF77F5CE0}'] + function name: string; + function icon_custom_emoji_id: string; + end; + + ItdForumTopicReopened = interface + ['{0158DEF3-A221-42C0-AD0F-F69E726157EB}'] + end; + + ItdGeneralForumTopicHidden = interface + ['{DB0916EC-020E-4E14-ADD2-18F7B5AFA852}'] + end; + + ItdGeneralForumTopicUnhidden = interface + ['{91AEC975-5CFF-4FD0-B8F6-EDB6C3DE0151}'] + end; + + ItdUserShared = Interface + ['{B975E2B8-8A86-4E59-83A5-6148FC04B055}'] + function request_id: integer; + function user_id: integer; + End; + + ItdChatShared = Interface + ['{309FB1B9-3ED7-48AE-99DF-28B1EC447D5A}'] + function request_id: integer; + function chat_id: integer; + End; + + ItdMessage = interface + ['{66BC2558-00C0-4BDD-BDDE-E83249787B30}'] + function MessageId: Int64; + function MessageThreadId: Int64; + function From: ItdUser; + function SenderChat: ItdChat; + function Date: TDateTime; + function Chat: ItdChat; + function ForwardFrom: ItdUser; + function ForwardFromChat: ItdChat; + function ForwardFromMessageId: Int64; + function ForwardSignature: string; + function ForwardSenderName: String; + function ForwardDate: TDateTime; + function IsTopicMessage: Boolean; + function IsAutomaticForward: boolean; + function ReplyToMessage: ItdMessage; + function ViaBot : ItdUser; + function EditDate: TDateTime; + function HasProtectedContent: boolean; + function MediaGroupId: string; + function AuthorSignature: string; + function Text: string; + function Entities: TArray; + function Animation : ItdAnimation; + function Audio: ItdAudio; + function Document: ItdDocument; + function Photo: TArray; + function Sticker: ItdSticker; + function Video: ItdVideo; + function VideoNote: ItdVideoNote; + function Voice: ItdVoice; + function Caption: string; + function CaptionEntities: TArray; + function HasMediaSpoiler: Boolean; + function Contact: ItdContact; + function Dice: ItdDice; + function Game: ItdGame; + function Poll: ItdPoll; + function Venue: ItdVenue; + function Location: ItdLocation; + function NewChatMembers: TArray; + function LeftChatMember: ItdUser; + function NewChatTitle: string; + function NewChatPhoto: TArray; + function DeleteChatPhoto: Boolean; + function GroupChatCreated: Boolean; + function SupergroupChatCreated: Boolean; + function ChannelChatCreated: Boolean; + function MessageAutoDeleteTimerChanged: ItdMessageAutoDeleteTimerChanged; + function MigrateToChatId: Int64; + function MigrateFromChatId: Int64; + function PinnedMessage: ItdMessage; + function Invoice: ItdInvoice; + function SuccessfulPayment: ItdSuccessfulPayment; + function UserShared: ItdUserShared; + function ChatShared: ItdChatShared; + function ConnectedWebsite: string; + function WriteAccessAllowed: ItdWriteAccessAllowed; + function PassportData: ItdPassportData; + function ProximityAlertTriggered: ItdProximityAlertTriggered; + function ForumTopicCreated: ItdForumTopicCreated; + function ForumTopicClosed: ItdForumTopicClosed; + function ForumTopicEdited: ItdForumTopicEdited; + function ForumTopicReopened: ItdForumTopicReopened; + function GeneralForumTopicHidden: ItdGeneralForumTopicHidden; + function GeneralForumTopicUnhidden: ItdGeneralForumTopicUnhidden; + function VideoChatScheduled: ItdVideoChatScheduled; + function VideoChatStarted: ItdVideoChatStarted; + function VideoChatEnded: ItdVideoChatEnded; + function VideoChatParticipantsInvited: ItdVideoChatParticipantsInvited; + function WebAppData: ItdWebAppData; + function ReplyMarkup : IReplyMarkup; + function NewChatMember: ItdUser; //Resource... + function &Type: TtdMessageType; //Resource... + function IsCommand(const AValue: string): Boolean; //Resource... + end; + ItdMessageID = interface + ['{8F988303-9873-47DF-969E-E6F72391E214}'] + function MessageId: Int64; + end; + ItdUserProfilePhotos = interface + ['{DD667B04-15A3-47B1-A729-C75ED5BFE719}'] + function TotalCount: Int64; + function Photos: TArray>; + end; + ItdResponseParameters = interface + ['{24701677-9BEB-42ED-8400-F465E4B2AECA}'] + function MigrateToChatId: Int64; + function RetryAfter: Int64; + end; + ItdInlineQuery = interface + ['{5DDE73CE-ABDF-47CE-8989-B62DF0543B02}'] + function ID: string; + function From: ItdUser; + function Query: string; + function Offset: string; + function chat_type: TtdChatType; // Optional. Type of the chat, from which the inline query was sent. Can be either “sender” for a private chat with the inline query sender, “private”, “group”, “supergroup”, or “channel”. The chat type should be always known for requests sent from official clients and most third-party clients, unless the request was sent from a secret chat + function location: ItdLocation; //Optional. Sender location, only for bots that request user location + end; + ItdChosenInlineResult = interface + ['{0A293C7F-922D-4D9A-9CED-046942A20377}'] + function ResultId: string; + function From: ItdUser; + function Location: ItdLocation; + function InlineMessageId: string; + function Query: string; + end; + ItdSwitchInlineQueryChosenChat = interface + ['{697ADCB7-45C2-4E9F-A19B-9DF2AFC84246}'] + function query: string; + function allow_user_chats: Boolean; + function allow_bot_chats: Boolean; + function allow_group_chats: Boolean; + function allow_channel_chats: Boolean; + end; + ItdCallbackQuery = interface + ['{83D9BF94-033A-44BA-8AD5-DCE25937A7B3}'] + function ID: string; + function From: ItdUser; + function message: ItdMessage; + function InlineMessageId: string; + function Data: string; + function GameShortName: string; + end; + ItdShippingAddress = interface + ['{7AE45A81-A19B-4A7C-AB2B-DEC68F1498BF}'] + function CountryCode: string; + function State: string; + function City: string; + function StreetLine1: string; + function StreetLine2: string; + function PostCode: string; + end; + ItdShippingQuery = interface + ['{09C65D9A-6323-455C-9B16-37FB7C542394}'] + function ID: string; + function From: ItdUser; + function InvoicePayload: string; + function ShippingAddress: ItdShippingAddress; + end; + ItdOrderInfo = interface + ['{BE2FEF98-2DCD-489D-862C-A88EB1A60913}'] + function Name: string; + function PhoneNumber: string; + function Email: string; + function ShippingAddress: ItdShippingAddress; + end; + ItdPreCheckoutQuery = interface + ['{BB511CA3-3E28-4B30-A5FB-87FBFC07A599}'] + function ID: string; + function From: ItdUser; + function Currency: string; + function TotalAmount: Int64; + function InvoicePayload: string; + function ShippingOptionId: string; + function OrderInfo: ItdOrderInfo; + end; + ItdLabeledPrice = interface + ['{3EB70EDB-1D5D-42E4-AACD-A225316482E3}'] + function &label: string; + function amount: Int64; + end; + ItdShippingOption = interface + ['{1E1BCD22-8F26-4EA7-BDB6-770250DF5BF6}'] + function ID: string; + function Title: string; + function Prices: TArray; + end; + ItdAnswerShippingQuery = Interface + ['{D040E5D4-6CAA-48A0-BBDD-0B6E645D1018}'] + function ShippingQueryId : string; + function Ok : Boolean; + function ShippingOptions : TArray; + function ErrorMessage : string; + End; + ItdAnswerPreCheckoutQuery = interface + ['{1258425C-A0BA-4F6B-9EEE-1D775D6F34C7}'] + function PreCheckoutQueryId : string; + function Ok : Boolean; + function ErrorMessage : string; + end; + ItdUpdate = interface + ['{5D001F9B-B0BC-4A44-85E3-E0586DAAABD2}'] + function ID: Int64; + function &message: ItdMessage; + function EditedMessage: ItdMessage; + function ChannelPost: ItdMessage; + function EditedChannelPost: ItdMessage; + function InlineQuery: ItdInlineQuery; + function ChosenInlineResult: ItdChosenInlineResult; + function CallbackQuery: ItdCallbackQuery; + function ShippingQuery: ItdShippingQuery; + function PreCheckoutQuery: ItdPreCheckoutQuery; + function PollState: ItdPoll; + function PollAnswer: ItdPollAnswer; + function MyChatMember: ItdChatMemberUpdated; + function ChatMember: ItdChatMemberUpdated; + function ChatJoinRequest: ItdChatJoinRequest; + function &Type: TtdUpdateType; + end; + ItdWebhookInfo = interface + ['{C77FA5C3-EF01-4571-AA1B-2BE80724BE3B}'] + function Url: string; + function HasCustomCertificate: Boolean; + function PendingUpdateCount: Int64; + function IpAddress: String; + function LastErrorDate: TDateTime; + function LastErrorMessage: string; + function last_synchronization_error_date: TDateTime; + function MaxConnections: Int64; + function AllowedUpdates: TArray; + end; + ItdLoginURL = Interface + ['{DC372234-7B40-4EED-8FD6-362977BCDEE8}'] + function URL: String; // + function ForwardText: String; // + function BotUserName: String; + function RequestWriteAccess: Boolean; + End; + ItdBotCommand = interface + ['{D8F751A3-BEAF-4565-875D-1F5B5D78CA7C}'] + function Command: String; + function Description: String; + end; + ItdWebAppInfo = interface + ['{D03A303A-4C29-46C9-AAA6-65051C9F43D2}'] + function url: String; + end; + ItdWebAppData = interface + ['{78571DEF-6B98-4141-8FD6-C1B6D3FFFC7D}'] + function data: String; + function button_text: String; + end; + ItdSentWebAppMessage = Interface + ['{692F487E-2724-44B0-AA57-DD3AA6FFE609}'] + function inline_message_id: String; + End; + ItdMenuButton = Interface + ['{7D216A5D-3B0B-43D5-9AEF-DAC0231DD49E}'] + End; + ItdChatAdministratorRights = Interface + ['{1DBB2D74-BB40-4C25-9F6F-5D0739551F03}'] + function is_anonymous: Boolean; + function can_manage_chat: Boolean; + function can_delete_messages: Boolean; + function can_manage_video_chats: Boolean; + function can_restrict_members: Boolean; + function can_promote_members: Boolean; + function can_change_info: Boolean; + function can_invite_users: Boolean; + function can_post_messages: Boolean; + function can_edit_messages: Boolean; + function can_pin_messages: Boolean; + End; + + ItdThemeParams = Interface + ['{0EA0EC1C-CF18-4A32-92B0-02594AF4C565}'] + function Getbg_color: TColor; + function Gettext_color: TColor; + function Gethint_color: TColor; + function Getlink_color: TColor; + function Getbutton_color: TColor; + function Getbutton_text_color: TColor; + function Getsecondary_bg_color: TColor; + End; + + ItdMainButton = Interface + ['{BB9280C0-6E35-402A-8966-4C686E5DA5D3}'] + End; + + ItdBotCommandScope = interface + ['{29D8983A-5596-461F-B7F3-6E05F703C5E2}'] + end; + + ItdBotName = interface + ['{D1412E29-64D8-4920-89FA-EABB99A1049D}'] + function name: string; + end; + + ItdBotDescription = interface + ['{B81B2985-8086-430D-A59E-A6C1CE728886}'] + function description: string; + end; + + ItdBotShortDescription = interface + ['{15B54686-7F4E-4198-925B-ED29A7E757E5}'] + function short_description: string; + end; + + {$SCOPEDENUMS ON} + TtdFileToSendTag = (ERROR = 254, ID = 0, FromURL = 1, FromFile = 2, FromStream = 3); + {$SCOPEDENUMS OFF} + + TtdFileToSend = class + public + Data: string; + Content: TStream; + Tag: TtdFileToSendTag; + constructor Create(const ATag: TtdFileToSendTag = TtdFileToSendTag.ERROR; + const AData: string = ''; AContent: TStream = nil); + class function FromFile(const AFileName: string): TtdFileToSend; + class function FromID(const AID: string): TtdFileToSend; + class function FromURL(const AURL: string): TtdFileToSend; + class function FromStream(const AContent: TStream; const AFileName: string): + TtdFileToSend; + class function Empty: TtdFileToSend; + function IsEmpty: Boolean; + end; + TtdInputMedia = class + private + FType: string; + FMedia: string; + FCaption: string; + FParseMode: string; + [JSONMarshalled(False)] + FFileToSend: TtdFileToSend; + FCaptionEntities: TArray; + FThumb: TtdFileToSend; public + function GetFileToSend: TtdFileToSend; + public + constructor Create(AMedia: TtdFileToSend; const ACaption: string = ''); overload; virtual; + constructor Create(AType: String; AMedia: TtdFileToSend; const ACaption: string = ''); overload; + [JsonName('type')] + property &Type: string read FType write FType; + [JsonName('media')] + property Media: string read FMedia write FMedia; + [JsonName('thumb')] + property Thumb: TtdFileToSend read FThumb write FThumb; + [JsonName('caption')] + property Caption: string read FCaption write FCaption; + [JsonName('parse_mode')] + property ParseMode: string read FParseMode write FParseMode; + [JsonName('caption_entities')] + property CaptionEntities: TArray read FCaptionEntities write FCaptionEntities; + end; + TtdInputMediaPhoto = class(TtdInputMedia) + private + FHasSpoiler: boolean; + public + constructor Create(AMedia: TtdFileToSend; const ACaption: string = ''); override; + [JsonName('has_spoiler')] + property HasSpoiler: boolean read FHasSpoiler write FHasSpoiler; + end; + TtdInputMediaVideo = class(TtdInputMedia) + private + FWidth: Integer; + FHeight: Integer; + FDuration: Integer; + FSupportsStreaming: Boolean; + FHasSpoiler: boolean; + public + constructor Create(AMedia: TtdFileToSend; const ACaption: string = ''; + AWidth: Integer = 0; AHeight: Integer = 0; ADuration: Integer = 0; + ASupportsStreaming: Boolean = True; AHasSpoiler: Boolean = False); reintroduce; + [JsonName('width')] + property Width: Integer read FWidth write FWidth; + [JsonName('height')] + property Height: Integer read FHeight write FHeight; + [JsonName('duration')] + property Duration: Integer read FDuration write FDuration; + [JsonName('has_spoiler')] + property HasSpoiler: boolean read FHasSpoiler write FHasSpoiler; + [JsonName('supports_streaming')] + property SupportsStreaming: Boolean read FSupportsStreaming write FSupportsStreaming; + end; + TtdInputMediaAnimation = class(TtdInputMedia) + private + FDuration: Integer; + FPerformer: String; + FTitle: String; + public + constructor Create(AMedia: TtdFileToSend; const ACaption: string = ''; ADuration: Integer = 0; APerformer: String = ''; ATitle: String = ''); reintroduce; + [JsonName('duration')] + property Duration: Integer read FDuration write FDuration; + [JsonName('performer')] + property Performer: String read FPerformer write FPerformer; + [JsonName('title')] + property Title: String read FTitle write FTitle; + end; + + TtdInputMediaDocument = class(TtdInputMedia) + private + FDisableContentTypeDetection: Boolean; + public + constructor Create(AMedia: TtdFileToSend; const ACaption: string = ''; ADisableContentTypeDetection: Boolean = False); reintroduce; + [JsonName('disable_content_type_detection')] + property DisableContentTypeDetection: Boolean read FDisableContentTypeDetection write FDisableContentTypeDetection; + end; + + TtdUserLink = record + ID: Int64; + Username: string; + class function FromID(const AID: Int64): TtdUserLink; static; + class function FromUserName(const AUsername: string): TtdUserLink; static; + class operator Implicit(AID: Int64): TtdUserLink; + class operator Implicit(AUsername: string): TtdUserLink; + function ToString: string; + function IsIDEmpty: Boolean; + function IsUsernameEmpty: Boolean; + end; + + ItdInputSticker = interface + ['{A795D244-B5D5-408C-A801-24550E45F838}'] + function sticker: string; + function emoji_list: TArray; + function mask_position: ItdMaskPosition; + function keywords: TArray; //List of 0-20 search keywords + end; + +implementation +uses + System.SysUtils; +{ TtdInputMedia } +constructor TtdInputMedia.Create(AMedia: TtdFileToSend; const ACaption: string); +begin + FCaption := ACaption; + FFileToSend := AMedia; + case AMedia.Tag of + TtdFileToSendTag.ID, TtdFileToSendTag.FromURL: + FMedia := ExtractFileName(AMedia.Data); + TtdFileToSendTag.FromFile, TtdFileToSendTag.FromStream: + FMedia := 'attach://' + ExtractFileName(AMedia.Data); + end; +end; +constructor TtdInputMedia.Create(AType: String; AMedia: TtdFileToSend; + const ACaption: string); +begin + Self.Create(AMedia, ACaption); + FType := AType; +end; +function TtdInputMedia.GetFileToSend: TtdFileToSend; +begin + Result := FFileToSend; +end; +{ TtdInputMediaPhoto } +constructor TtdInputMediaPhoto.Create(AMedia: TtdFileToSend; const ACaption: string); +begin + inherited Create(AMedia, ACaption); + FType := 'photo'; +end; +{ TtdInputMediaVideo } +constructor TtdInputMediaVideo.Create(AMedia: TtdFileToSend; const ACaption: + string; AWidth, AHeight, ADuration: Integer; ASupportsStreaming: Boolean; + AHasSpoiler: Boolean); +begin + inherited Create(AMedia, ACaption); + FType := 'video'; + FWidth := AWidth; + FHeight := AHeight; + FDuration := ADuration; + FHasSpoiler := AHasSpoiler; + Self.FSupportsStreaming := ASupportsStreaming; +end; +{ TtdFileToSend } +constructor TtdFileToSend.Create(const ATag: TtdFileToSendTag; const AData: + string; AContent: TStream); +begin + Tag := ATag; + Data := AData; + Content := AContent; +end; +class function TtdFileToSend.Empty: TtdFileToSend; +begin + Result := TtdFileToSend.Create(); +end; +class function TtdFileToSend.FromFile(const AFileName: string): TtdFileToSend; +begin + if not FileExists(AFileName) then + raise EFileNotFoundException.CreateFmt('File %S not found!', [AFileName]); + Result := TtdFileToSend.Create(TtdFileToSendTag.FromFile, AFileName, nil); +end; +class function TtdFileToSend.FromID(const AID: string): TtdFileToSend; +begin + Result := TtdFileToSend.Create(TtdFileToSendTag.ID, AID, nil); +end; +class function TtdFileToSend.FromStream(const AContent: TStream; const AFileName: + string): TtdFileToSend; +begin + // I guess, in most cases, AFilename param should contain a non-empty string. + // It is odd to receive a file with filename and + // extension which both are not connected with its content. + if AFileName.IsEmpty then + raise Exception.Create('TtdFileToSend: Filename is empty!'); + if not Assigned(AContent) then + raise EStreamError.Create('Stream not assigned!'); + Result := TtdFileToSend.Create(TtdFileToSendTag.FromStream, AFileName, AContent); +end; +class function TtdFileToSend.FromURL(const AURL: string): TtdFileToSend; +begin + Result := TtdFileToSend.Create(TtdFileToSendTag.FromURL, AURL, nil); +end; +function TtdFileToSend.IsEmpty: Boolean; +begin + Result := Data.IsEmpty and not Assigned(Content); +end; +{ TtdUserLink } +class function TtdUserLink.FromID(const AID: Int64): TtdUserLink; +begin + Result.ID := AID; +end; +class function TtdUserLink.FromUserName(const AUsername: string): TtdUserLink; +begin + Result.Username := AUsername; +end; +class operator TtdUserLink.Implicit(AUsername: string): TtdUserLink; +begin + Result := TtdUserLink.FromUserName(AUsername); +end; +function TtdUserLink.IsIDEmpty: Boolean; +begin + if ID = 0 then + result := True + Else + result := False; +end; +function TtdUserLink.IsUsernameEmpty: Boolean; +begin + if Username = '' then + Result := True + Else + Result := False; +end; +function TtdUserLink.ToString: string; +begin + if Username.IsEmpty then + Result := ID.ToString + else + Result := Username; +end; +class operator TtdUserLink.Implicit(AID: Int64): TtdUserLink; +begin + Result := TtdUserLink.FromID(AID); +end; +{ TtdInputMediaAnimation } + +constructor TtdInputMediaAnimation.Create(AMedia: TtdFileToSend; + const ACaption: string; ADuration: Integer; APerformer: String; ATitle: String); +begin + inherited Create(AMedia, ACaption); + FDuration := ADuration; + FPerformer := APerformer; + FTitle := ATitle; +end; + +{ TtdInputMediaDocument } + +constructor TtdInputMediaDocument.Create(AMedia: TtdFileToSend; + const ACaption: string; ADisableContentTypeDetection: Boolean); +begin + inherited Create(AMedia, ACaption); + FDisableContentTypeDetection := ADisableContentTypeDetection; +end; + +End. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.UpdateParser.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.UpdateParser.pas new file mode 100644 index 0000000..d98eda3 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.UpdateParser.pas @@ -0,0 +1,104 @@ +unit TinjectTelegram.UpdateParser; +interface +uses + System.Classes, + System.SysUtils, + TInjectTelegram.Base, + TInjectTelegram.Bot, + TInjectTelegram.Types, + TInjectTelegram.Types.Enums; +type + TtdOnMessageEntityReceiver = procedure(ASender: TObject; AMessageEntityType: TtdMessageEntityType) of object; + + TInjectTelegramBotUpdateParser = class(TInjectTelegramAbstractComponent) + private + protected + procedure EventParser(AUpdates: TArray); virtual; + procedure TypeUpdate(AUpdate: ItdUpdate); virtual; + procedure DoOnStarted(AOut: String); virtual; abstract; + procedure DoOnUpdates(AUpdates: TArray); virtual; abstract; + procedure DoOnUpdate(AUpdate: ItdUpdate); virtual; abstract; + procedure DoOnMessage(AMessage: ItdMessage); virtual; abstract; + procedure DoOnInlineQuery(AInlineQuery: ItdInlineQuery); virtual; abstract; + procedure DoOnChosenInlineResult(AChosenInlineResult: ItdChosenInlineResult); virtual; abstract; + procedure DoOnCallbackQuery(ACallbackQuery: ItdCallbackQuery); virtual; abstract; + procedure DoOnEditedMessage(AEditedMessage: ItdMessage); virtual; abstract; + procedure DoOnChannelPost(AChannelPost: ItdMessage); virtual; abstract; + procedure DoOnEditedChannelPost(AEditedChannelPost: ItdMessage); virtual; abstract; + procedure DoOnShippingQuery(AShippingQuery: ItdShippingQuery); virtual; abstract; + procedure DoOnPreCheckoutQuery(APreCheckoutQuery: ItdPreCheckoutQuery); virtual; abstract; + procedure DoOnPollStatus(APoll: ItdPoll); virtual; abstract; + procedure DoOnPollAnswer(APollAnswer: ItdPollAnswer); virtual; abstract; + procedure DoOnChatJoinRequest(AChatJoinRequest: ItdChatJoinRequest); virtual; abstract; + procedure DoOnMyChatMember(AMyChatMember: ItdChatMemberUpdated); virtual; abstract; + procedure DoOnChatMember(AChatMember: ItdChatMemberUpdated); virtual; abstract; + procedure DoOnSuccessfulPayment(ASuccessfulPayment: ItdSuccessfulPayment); virtual; abstract; + procedure DoOnForumTopicCreated(AForumTopicCreated: ItdForumTopicCreated); virtual; abstract; + procedure DoOnForumTopicReopened(AForumTopicReopened: ItdForumTopicReopened); virtual; abstract; + procedure DoOnForumTopicEdited(AForumTopicEdited: ItdForumTopicEdited); virtual; abstract; + procedure DoOnForumTopicClosed(AForumTopicClosed: ItdForumTopicClosed); virtual; abstract; + procedure DoOnGeneralForumTopicHidden(AGeneralForumTopicHidden: ItdGeneralForumTopicHidden); virtual; abstract; + procedure DoOnGeneralForumTopicUnhidden(AGeneralForumTopicUnhidden: ItdGeneralForumTopicUnhidden); virtual; abstract; + procedure DoOnMessageEntityReceiver(AMessageEntityReceiver: TtdMessageEntityType); virtual; abstract; + procedure DoOnWebAppData(AWebAppData: ItdWebAppData); virtual; abstract; + public + procedure ParseResponse(const JSON: string); + end; +implementation +uses + TInjectTelegram.Bot.Impl; +{ TInjectTelegramBotUpdateParser } +procedure TInjectTelegramBotUpdateParser.EventParser(AUpdates: TArray); +var + LUpdate: ItdUpdate; +begin + DoOnUpdates(AUpdates); + for LUpdate in AUpdates do + begin + DoOnUpdate(LUpdate); + TypeUpdate(LUpdate); + end; +end; +procedure TInjectTelegramBotUpdateParser.ParseResponse(const JSON: string); +var + LUpdates: TArray; + LBot: IInjectTelegramBot; +begin + LBot := TInjectTelegramBot.Create(nil); + LUpdates := LBot.GetUpdates(JSON); + EventParser(LUpdates); +end; +procedure TInjectTelegramBotUpdateParser.TypeUpdate(AUpdate: ItdUpdate); +begin + case AUpdate.&Type of + TtdUpdateType.MessageUpdate: + DoOnMessage(AUpdate.Message); + TtdUpdateType.InlineQueryUpdate: + DoOnInlineQuery(AUpdate.InlineQuery); + TtdUpdateType.ChosenInlineResultUpdate: + DoOnChosenInlineResult(AUpdate.ChosenInlineResult); + TtdUpdateType.CallbackQueryUpdate: + DoOnCallbackQuery(AUpdate.CallbackQuery); + TtdUpdateType.EditedMessage: + DoOnEditedMessage(AUpdate.EditedMessage); + TtdUpdateType.ChannelPost: + DoOnChannelPost(AUpdate.ChannelPost); + TtdUpdateType.EditedChannelPost: + DoOnEditedChannelPost(AUpdate.EditedChannelPost); + TtdUpdateType.ShippingQueryUpdate: + DoOnShippingQuery(AUpdate.ShippingQuery); + TtdUpdateType.PreCheckoutQueryUpdate: + DoOnPreCheckoutQuery(AUpdate.PreCheckoutQuery); + TtdUpdateType.PollState: + DoOnPollStatus(AUpdate.PollState); + TtdUpdateType.PollAnswer: + DoOnPollAnswer(AUpdate.PollAnswer); + TtdUpdateType.MyChatMember: + DoOnMyChatMember(AUpdate.MyChatMember); + TtdUpdateType.ChatMember: + DoOnChatMember(AUpdate.ChatMember); + TtdUpdateType.ChatJoinRequest: + DoOnChatJoinRequest(AUpdate.ChatJoinRequest); + end; +end; +end. diff --git a/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Utils.JSON.pas b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Utils.JSON.pas new file mode 100644 index 0000000..ed2aff6 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/TinjectTelegram.Utils.JSON.pas @@ -0,0 +1,417 @@ +unit TinjectTelegram.Utils.Json; +interface +{$I ..\Source\config.inc} +uses + System.Json, REST.Json, REST.JsonReflect, REST.Json.Types; +type + TBaseJsonClass = class of TBaseJson; + TBaseJson = class(TInterfacedObject) + private + protected + FJSON: TJSONObject; + FJsonRaw: string; //for debbuger + function ReadToClass(const AKey: string): T; + function ReadToSimpleType(const AKey: string): T; + function ReadToDateTime(const AKey: string): TDateTime; + function ReadToArray(TdClass: TBaseJsonClass; const AKey: + string): TArray; + function ReadToTArrayString(const AKey: string): TArray; + procedure Write(const AKey, AValue: string); + procedure SetJson(const AJson: string); + public + function AsJson: string; + class function FromJson(const AJson: string): TBaseJson; + class function GetTdClass: TBaseJsonClass; virtual; // abstract; + class procedure UnSupported; + constructor Create(const AJson: string); virtual; + destructor Destroy; override; + end; + TJsonUtils = class + /// Nova Função ArrayStringToJString By Ruan Diego Lacerda Menezes + /// para compatibilizar e add o SendPoll + class function ObjectToJsonValue(AObject: TObject; AOptions: TJsonOptions): TJSONValue; static; + class procedure ProcessOptions(AJsonObject: TJSONObject; AOptions: TJsonOptions); static; + class function ArrayStringToJString(LArray: Array of String): string; + class function ArrayLebeledPriceToJString(LArray: TArray): string; static; + class function ArrayCommandsToJString(LArray: TArray): string; static; + class function ArrayToJString2(LArray: TArray): string; + class function ArrayToJString(LArray: TArray): string; + class function ArrayIntToJString(LArray: TArray): string; + class function ObjectToJString(AObj: TObject): string; + class function BoolToJString(ABoll: Boolean): string; + class function FileToObject(const AFileName: string): T; + class procedure ObjectToFile(AObj: TObject; const AFileName: string); + end; + TJSONValueHelper = class helper for TJSONValue + strict private + private + function GetS(const APath: string): string; + procedure SetS(const APath, AValue: string); + public + property S[const APath: string]: string read GetS write SetS; + end; +implementation +uses + TInjectTelegram.Types.Impl, + System.DateUtils, + System.IOUtils, + System.SysUtils, + System.TypInfo; +{ TJSONValueHelper } +type + TJSONStringHack = class(TJSONString); +function TJSONValueHelper.GetS(const APath: string): string; +begin + if (not Self.TryGetValue(APath, Result)) then + Result := string.Empty; +end; +//By Ruan Diego Lacerda Menezes +procedure TJSONValueHelper.SetS(const APath, AValue: string); +var + LValue: TJSONValue; +begin + LValue := Self.FindValue(APath); + if (LValue is TJSONString) then + begin + {$IFDEF DELPHI13_UP} + TJSONStringHack(LValue).FValue := ''; + TJSONStringHack(LValue).FValue := AValue; + {$ELSE} + TJSONStringHack(LValue).FStrBuffer.Clear; + TJSONStringHack(LValue).FStrBuffer.Append(AValue); + {$ENDIF} + end; +end; +{ TJsonUtils } +//By Ruan Diego Lacerda Menezes +class function TJsonUtils.ArrayStringToJString(LArray: Array of String): string; +Var + I: Integer; +begin + result := '['; + for I := Low(LArray) to High(LArray) do + if LArray[I] <> '' then + begin + Result := Result + '"' +LArray[I] + '"' ; + if I <> High(LArray) then + result := result +','; + End; + Result := Result + ']'; + Result := Result.Replace('"inline_keyboard":null', '', [rfReplaceAll]); + +end; + +class function TJsonUtils.ArrayCommandsToJString(LArray: TArray): string; +Var + I: Integer; +begin + result := '['; + for I := Low(LArray) to High(LArray) do + begin + if ((LArray[I] as TtdBotCommand).CMD <> '') and (Length((LArray[I] as TtdBotCommand).CMD) <= 32) then + Result := Result + '{"command":"' + (LArray[I] as TtdBotCommand).CMD + '"' + else + raise Exception.Create('Error : O número de caracteres do comando não pode ser superior a 32!'); + if ((LArray[I] as TtdBotCommand).Desc <> '' ) and + (Length((LArray[I] as TtdBotCommand).Desc) >= 3) and + (Length((LArray[I] as TtdBotCommand).Desc) <= 256) then + Result := Result + ',"description":"' +(LArray[I] as TtdBotCommand).Desc +'"}' + else + raise Exception.Create('Error : O número de caracteres da descrição não pode ser menor que 3 e maior que 256 caracteres!'); + if I <> High(LArray) then + result := result +','; + End; + Result := Result + ']'; +end; + +class function TJsonUtils.ArrayIntToJString(LArray: TArray): string; +var + I: Integer; +begin + Result := '['; + for I := Low(LArray) to High(LArray) do + if LArray[I].ToString <> '' then + begin + if (I = Low(LArray)) then + Result := Result + LArray[I].ToString + Else + Result := Result + ',' + LArray[I].ToString; + end; + Result := Result + ']'; +end; + +class function TJsonUtils.ArrayLebeledPriceToJString(LArray: TArray): string; +Var + I: Integer; +begin + result := '[{"jSon":"{'; + for I := Low(LArray) to High(LArray) do + begin + if (LArray[I] as TtdLabeledPrice).sLabel <> '' then + Result := Result + '"label":"' + (LArray[I] as TtdLabeledPrice).sLabel + '"'; + if (LArray[I] as TtdLabeledPrice).sAmount.ToString <> '' then + Result := Result + ',"amount":"' +(LArray[I] as TtdLabeledPrice).sAmount.ToString +'"}' ; + if I <> High(LArray) then + result := result +','; + End; + Result := Result + '}]'; + Result := Result.Replace('"inline_keyboard":null', '', [rfReplaceAll]); +end; + +class function TJsonUtils.ArrayToJString2(LArray: TArray): string; +var + I: Integer; +begin + Result := '['; + for I := Low(LArray) to High(LArray) do + if Assigned(LArray[I]) then + begin + Result := Result + ObjectToJString(LArray[I]); + if I <> High(LArray) then + Result := Result + ','; + end; + Result := Result + ']'; + Result := Result.Replace('"inline_keyboard":null', '', [rfReplaceAll]); +// +end; + +class function TJsonUtils.ArrayToJString(LArray: TArray): string; +var + I: Integer; +begin + Result := '['; + for I := Low(LArray) to High(LArray) do + if Assigned(LArray[I]) then + begin + if (I = Low(LArray)) then + Result := Result + TJson.ObjectToJsonString(LArray[I]) + Else + Result := Result + ',' + TJson.ObjectToJsonString(LArray[I]); + end; + Result := Result + ']'; + Result := Result.Replace('"inline_keyboard":null', '', [rfReplaceAll]); +end; +class function TJsonUtils.BoolToJString(ABoll: Boolean): string; +var + StrOut: String; +begin + if ABoll then + StrOut := 'True' + else + StrOut := 'False'; + + Result := StrOut; +end; + +class function TJsonUtils.FileToObject(const AFileName: string): T; +var + LContent: string; +begin + Result := nil; + if TFile.Exists(AFileName) then + begin + LContent := TFile.ReadAllText(AFileName, TEncoding.UTF8); + Result := TJson.JsonToObject(LContent); + end; +end; +class procedure TJsonUtils.ObjectToFile(AObj: TObject; const AFileName: string); +var + LContent: string; +begin + LContent := ObjectToJString(AObj); + TFile.WriteAllText(AFileName, LContent, TEncoding.UTF8); +end; +class function TJsonUtils.ObjectToJString(AObj: TObject): string; +begin // IF DELPHI_VERSION < TOKIO + if Assigned(AObj) then + Result := TJson.ObjectToJsonString(AObj) + else + Result := 'null'; +end; + +class function TJsonUtils.ObjectToJsonValue(AObject: TObject; AOptions: TJsonOptions): TJSONValue; +var + LMarshaler: TJSONMarshal; +begin + + LMarshaler := TJSONMarshal.Create(TJSONConverter.Create); + try + LMarshaler.DateTimeIsUTC := joDateIsUTC in AOptions; + if joDateFormatUnix in AOptions then + LMarshaler.DateFormat :=jdfUnix + else if joDateFormatISO8601 in AOptions then + LMarshaler.DateFormat := jdfISO8601 + else if joDateFormatMongo in AOptions then + LMarshaler.DateFormat := jdfMongo + else if joDateFormatParse in AOptions then + LMarshaler.DateFormat := jdfParse; + + Result := LMarshaler.Marshal(AObject); + if Result is TJSONObject then + ProcessOptions(TJSONObject(Result), AOptions); + finally + LMarshaler.Free; + end; +end; +class procedure TJsonUtils.ProcessOptions(AJsonObject: TJSONObject; + AOptions: TJsonOptions); +var + LPair: TJSONPair; + LItem: TObject; + i: Integer; + + function IsEmpty(ASet: TJsonOptions): Boolean; + var + LElement: TJsonOption; + begin + Result := True; + for LElement in ASet do + begin + Result := False; + break; + end; + end; + +begin + if Assigned(AJsonObject) and not IsEmpty(AOptions) then + + for i := AJsonObject.Count - 1 downto 0 do + begin + LPair := TJSONPair(AJsonObject.Pairs[i]); + if LPair.JsonValue is TJSONObject then + ProcessOptions(TJSONObject(LPair.JsonValue), AOptions) + else if LPair.JsonValue is TJSONArray then + begin + if (joIgnoreEmptyArrays in AOptions) and (TJSONArray(LPair.JsonValue).Count = 0) then + AJsonObject.RemovePair(LPair.JsonString.Value).DisposeOf + else + for LItem in TJSONArray(LPair.JsonValue) do + if LItem is TJSONObject then + ProcessOptions(TJSONObject(LItem), AOptions) + end + else + if (joIgnoreEmptyStrings in AOptions) and (LPair.JsonValue.value = '') then + AJsonObject.RemovePair(LPair.JsonString.Value).DisposeOf; + end; +end; + +{ TBaseJson } +function TBaseJson.AsJson: string; +begin + if Assigned(FJSON) then + Result := FJSON.ToJSON + else + Result := ''; +end; +constructor TBaseJson.Create(const AJson: string); +begin + inherited Create; + SetJson(AJson); +end; +function TBaseJson.ReadToArray(TdClass: TBaseJsonClass; const AKey: string): + TArray; +var + LJsonArray: TJSONArray; + I: Integer; + GUID: TGUID; +begin +// estágio 1: verificação de tipo +// valor do cache para uso posterior + GUID := GetTypeData(TypeInfo(TI))^.GUID; + // verifique o suporte da interface TI + if TdClass.GetInterfaceEntry(GUID) = nil then + raise Exception.Create('GetArrayFromMethod: unsupported interface for ' + + TdClass.ClassName); + // estágio 2: continuar dados + LJsonArray := FJSON.GetValue(AKey) as TJSONArray; + if (not Assigned(LJsonArray)) or LJsonArray.Null then + Exit(nil); + SetLength(Result, LJsonArray.Count); + for I := 0 to High(Result) do + begin + TdClass.GetTdClass.Create(LJsonArray.Items[I].ToString).GetInterface(GUID, Result[I]); + end; +end; +function TBaseJson.ReadToClass(const AKey: string): T; +var + LValue: string; + LObj: TJSONValue; +begin + Result := nil; + LObj := FJSON.GetValue(AKey); + if Assigned(LObj) and (not LObj.Null) then + begin +{$IFDEF USE_INDY} + // A diretiva não se encaixa bem. Este é o caso se você estiver usando a versão antiga da IDE + LValue := LObj.ToString; +{$ELSE} + LValue := LObj.ToJSON; +{$ENDIF} + Result := TBaseJsonClass(T).Create(LValue) as T; + end +end; +destructor TBaseJson.Destroy; +begin + FJSON.Free; + inherited; +end; +class function TBaseJson.FromJson(const AJson: string): TBaseJson; +begin + if AJson.IsEmpty then + Result := nil + else + Result := TBaseJson.Create(AJson); +end; +class function TBaseJson.GetTdClass: TBaseJsonClass; +begin + Result := Self; +end; +function TBaseJson.ReadToDateTime(const AKey: string): TDateTime; +var + LValue: Int64; +begin + Result := 0; + if FJSON.TryGetValue(AKey, LValue) then + Result := UnixToDateTime(LValue, False); +end; +function TBaseJson.ReadToSimpleType(const AKey: string): T; +begin + if (not Assigned(FJSON)) or (not FJSON.TryGetValue(AKey, Result)) then + Result := Default(T); +end; +function TBaseJson.ReadToTArrayString(const AKey: string): TArray; +var + LJsonArray: TJSONArray; + I: Integer; +begin + LJsonArray := FJSON.GetValue(AKey) as TJSONArray; + if (not Assigned(LJsonArray)) or LJsonArray.Null then + Exit(nil); + SetLength(Result, LJsonArray.Count); + for I := 0 to LJsonArray.Count - 1 do + Result[I] := ReadToSimpleType(LJsonArray.Items[I].ToString); +end; + +procedure TBaseJson.SetJson(const AJson: string); +begin + FJsonRaw := AJson; + if FJsonRaw.IsEmpty then + Exit; + if Assigned(FJSON) then + FreeAndNil(FJSON); + FJSON := TJSONObject.ParseJSONValue(AJson) as TJSONObject; +end; +class procedure TBaseJson.UnSupported; +begin + raise Exception.Create('Método do Telegram não suportado na Biblioteca TinjectTelegram. Desculpe!'); +end; +procedure TBaseJson.Write(const AKey, AValue: string); +var + JoX: TJSONPair; +begin + JoX := FJSON.GetValue(AKey); + if Assigned(JoX.JsonValue) then + JoX.JsonValue.Free; + JoX.JsonValue := TJSONString.Create(AValue); +end; +end. diff --git a/v1.4.4/TInjectTelegram/Source/config.inc b/v1.4.4/TInjectTelegram/Source/config.inc new file mode 100644 index 0000000..09c2a45 --- /dev/null +++ b/v1.4.4/TInjectTelegram/Source/config.inc @@ -0,0 +1,551 @@ +{$IF CompilerVersion < 28} + {$DEFINE USE_INDY} +{$ELSE} + {$DEFINE USE_SYS_NET} +{$ENDIF} + +{$IFDEF VER350} + {$DEFINE DELPHI15} +{$ENDIF} + +{$IFDEF VER340} + {$DEFINE DELPHI14} +{$ENDIF} + +{$IFDEF VER330} + {$DEFINE DELPHI13} +{$ENDIF} + +{$IFDEF VER320} + {$DEFINE DELPHI12} +{$ENDIF} + +{$IFDEF VER310} + {$DEFINE DELPHI11} +{$ENDIF} + +{$IFDEF VER300} + {$DEFINE DELPHI10} +{$ENDIF} + +{$IFDEF VER290} + {$DEFINE DELPHIXE8} +{$ENDIF} + +{$IFDEF VER280} + {$DEFINE DELPHIXE7} +{$ENDIF} + +{$IFDEF VER270} + {$DEFINE DELPHIXE6} +{$ENDIF} + +{$IFDEF VER260} + {$DEFINE DELPHIXE5} +{$ENDIF} + +{$IFDEF VER250} + {$DEFINE DELPHIXE4} +{$ENDIF} + +{$IFDEF VER240} + {$DEFINE DELPHIXE3} +{$ENDIF} + +{$IFDEF VER230} + {$DEFINE DELPHIXE2} +{$ENDIF} + +{$IFDEF VER220} + {$DEFINE DELPHIXE} +{$ENDIF} + +{$IFDEF VER210} + {$DEFINE DELPHI2010} +{$ENDIF} + +{$IFDEF VER200} + {$DEFINE DELPHI2009} +{$ENDIF} + +{$IFDEF VER190} + {$DEFINE DELPHI2007} +{$ENDIF} + +{$IFDEF VER180} + {$DEFINE DELPHI2006} +{$ENDIF} + +{$IFDEF VER170} + {$DEFINE DELPHI2005} +{$ENDIF} + +{$IFDEF VER160} + {$DEFINE DELPHI2004} +{$ENDIF} + +{$IFDEF VER150} + {$DEFINE DELPHI7} +{$ENDIF} + +{$IFDEF VER140} + {$DEFINE DELPHI6} +{$ENDIF} + +{$IFDEF VER130} + {$DEFINE DELPHI5} +{$ENDIF} + +{$IFDEF VER125} + {$DEFINE CPPB4} +{$ENDIF} + +{$IFDEF VER120} + {$DEFINE DELPHI4} +{$ENDIF} + +{$IFDEF VER110} + {$DEFINE CPPB3} +{$ENDIF} + +{$IFDEF VER100} + {$DEFINE DELPHI3} +{$ENDIF} + +{$IFDEF VER93} + {$DEFINE CPPB1} +{$ENDIF} + +{$IFDEF VER90} + {$DEFINE DELPHI2} +{$ENDIF} + + +{$IFDEF DELPHI2} + {$DEFINE DELPHI2_UP} +{$ENDIF} + +{$IFDEF DELPHI3} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} +{$ENDIF} + +{$IFDEF DELPHI4} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} +{$ENDIF} + +{$IFDEF DELPHI5} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} +{$ENDIF} + +{$IFDEF DELPHI6} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} +{$ENDIF} + +{$IFDEF DELPHI7} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} +{$ENDIF} + +{$IFDEF DELPHI8} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} +{$ENDIF} + +{$IFDEF DELPHI2005} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI2006} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} +{$ENDIF} + +{$IFDEF DELPHI2007} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} +{$ENDIF} + +{$IFDEF DELPHI2009} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} +{$ENDIF} + +{$IFDEF DELPHI2010} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} +{$ENDIF} + +{$IFDEF DELPHIXE} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} +{$ENDIF} + +{$IFDEF DELPHIXE2} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} +{$ENDIF} + +{$IFDEF DELPHIXE3} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} +{$ENDIF} + +{$IFDEF DELPHIXE4} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE4_UP} +{$ENDIF} + +{$IFDEF DELPHIXE5} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE5_UP} +{$ENDIF} + +{$IFDEF DELPHIXE6} // Delphi XE6 By Dieletro + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE6_UP} +{$ENDIF} + +{$IFDEF DELPHIXE7} // Delphi XE7 By Dieletro + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE7_UP} +{$ENDIF} + +{$IFDEF DELPHIXE8} // Delphi XE8 By Dieletro + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE8_UP} +{$ENDIF} + +{$IFDEF DELPHI10} // Delphi 10 Seattle By Dieletro + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHI10_UP} +{$ENDIF} + +{$IFDEF DELPHI11} // Delphi 10.1 Berlin By Dieletro + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} +{$ENDIF} + +{$IFDEF DELPHI12} // Delphi 10.2 Tokio By Dieletro + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} +{$ENDIF} + +{$IFDEF DELPHI13} // Delphi 10.3 Rio By Dieletro + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI13_UP} +{$ENDIF} + +{$IFDEF DELPHI14} // Delphi 10.4 Sydiney + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI13_UP} + {$DEFINE DELPHI14_UP} +{$ENDIF} + +{$IFDEF DELPHI15} // Delphi 10.X Verses futuras + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI2005_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHIXE_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI13_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} +{$ENDIF} \ No newline at end of file