#include "TcpServerDialog.h"
#include "ui_TcpServerDialog.h"

#include <QMessageBox>

TcpServerDialog::TcpServerDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::TcpServerDialog),
    server(new QTcpServer(this))
{
    ui->setupUi(this);
    connect(server, &QTcpServer::newConnection, this, &TcpServerDialog::onNewConnection);

    connect(ui->lineEditMessage, &QLineEdit::returnPressed,
            this, &TcpServerDialog::on_sendButton_clicked);
}

TcpServerDialog::~TcpServerDialog()
{
    delete ui;
}

void TcpServerDialog::on_startButton_clicked()
{
    QString portStr = ui->lineEditPort->text().trimmed();

    bool ok;
    quint16 port = portStr.toUShort(&ok);
    if (!ok || port == 0 || port > 65535)
    {
        QMessageBox::warning(this, "Input Error", "Please enter a valid port number (1-65535).");
        return;
    }

    if (server->isListening())
    {
        QMessageBox::information(this, "Server", "Server is already running.");
        return;
    }

    if (server->listen(QHostAddress::Any, port))
    {
        ui->textEditIncoming->append("Server started...");
    }
    else
    {
        QMessageBox::warning(this, "Server Error", "Failed to start server. Port may be in use.");
    }
}

void TcpServerDialog::on_stopButton_clicked()
{
    if (!server->isListening())
    {
        QMessageBox::information(this, "Server", "Server is not running.");
        return;
    }

    server->close();

    for (QTcpSocket *client : clients)
    {
        client->disconnectFromHost();
    }
    clients.clear();

    ui->textEditIncoming->append("Server stopped.");
}

void TcpServerDialog::on_sendButton_clicked()
{
    QString msg = ui->lineEditMessage->text().trimmed();
    if (msg.isEmpty())
    {
        QMessageBox::warning(this, "Send Error", "Please enter a message to send.");
        return;
    }

    if (clients.isEmpty())
    {
        QMessageBox::information(this, "Send", "No clients connected to send the message.");
        return;
    }

    for (QTcpSocket *client : clients)
    {
        if (client->state() == QAbstractSocket::ConnectedState)
        {
            client->write(msg.toUtf8());
        }
    }

    ui->textEditIncoming->append("Server: " + msg);
    ui->lineEditMessage->clear();
}

void TcpServerDialog::on_clearButton_clicked()
{
    ui->textEditIncoming->clear();
}

void TcpServerDialog::onNewConnection()
{
    while (server->hasPendingConnections())
    {
        QTcpSocket *client = server->nextPendingConnection();
        clients << client;
        connect(client, &QTcpSocket::readyRead, this, &TcpServerDialog::onReadyRead);
        connect(client, &QTcpSocket::disconnected, this, &TcpServerDialog::onClientDisconnected);
        ui->textEditIncoming->append("Client connected.");
    }
}

void TcpServerDialog::onClientDisconnected()
{
    QTcpSocket *client = qobject_cast<QTcpSocket*>(sender());
    if (client)
    {
        clients.removeAll(client);
        client->deleteLater();
        ui->textEditIncoming->append("Client disconnected.");
    }
}

void TcpServerDialog::onReadyRead()
{
    QTcpSocket *client = qobject_cast<QTcpSocket*>(sender());
    if (client)
    {
        QByteArray data = client->readAll();
        ui->textEditIncoming->append("Client: " + QString::fromUtf8(data));
    }
}


#include "detections.h"
#define NT_GLOBAL_FLAG_DEBUGGED (0x10 | 0x20 | 0x40)

/*
* Here we check if DebugPort is valid. If DebugPort is valid, it means that a debugger is attached.
* DebugPort is located inside the EPROCESS structure.
* VOID* DebugPort; 0x578 -> https://www.vergiliusproject.com/kernels/x64/windows-11/21h2/_EPROCESS
* Here we can also use the undocumented function PsGetProcessDebugPort:
* __int64 __fastcall PsGetProcessDebugPort(__int64 a1)
* {
*   return *(_QWORD *)(a1 + 0x578);
* }
*/
bool kdbg::DebugPort()
{
	VOID* DebugPortAddress = *reinterpret_cast<VOID**>((PUCHAR)process + 0x578);
	if (DebugPortAddress)
		return true;

	return false;
}

/*
* Here we check if BeingDebugged is valid. If BeingDebugged is valid, it means that a debugger is attached.
* BeingDebugged is located inside the _PEB structure.
* UCHAR BeingDebugged; 0x2 -> https://www.vergiliusproject.com/kernels/x64/windows-11/21h2/_PEB
*/
bool kdbg::BeingDebugged()
{
	UCHAR BeingDebugged{ };
	SIZE_T BytesRead{ };

	NTSTATUS status = MmCopyVirtualMemory(process, (PVOID)((PUCHAR)pebAddress + 0x2), PsGetCurrentProcess(), &BeingDebugged, sizeof(UCHAR), KernelMode, &BytesRead);
	if (NT_SUCCESS(status) && BeingDebugged)
		return true;

	return false;
}

/*
* Here we check the NtGlobalFlag flags to see if the process is created by a debugger.
* NtGlobalFlag is located inside the _PEB structure.
* ULONG NtGlobalFlag; 0xbc -> https://www.vergiliusproject.com/kernels/x64/windows-11/21h2/_PEB
* 0xbc for 64-bit windows, 0x68 for 32-bit windows
*/
bool kdbg::NtGlobalFlag()
{
	UCHAR NtGlobalFlag{ };
	SIZE_T BytesRead{ };

	NTSTATUS status = MmCopyVirtualMemory(process, (PVOID)((PUCHAR)pebAddress + 0xbc), PsGetCurrentProcess(), &NtGlobalFlag, sizeof(UCHAR), KernelMode, &BytesRead);
	if (NT_SUCCESS(status) && NtGlobalFlag && NT_GLOBAL_FLAG_DEBUGGED)
		return true;

	return false;
}

/*
* Here we check the DebugObjectHandle. If DebugObjectHandle is valid, it means that a debugger is attached.
* DebugObjectHandle is located inside the EPROCESS structure ( undocumented ).
* Here we access DebugObjectHandle via ZwQueryInformationProcess. -> 0x1e
*/
bool kdbg::DebugObjectHandle()
{
	HANDLE hProcess{ };
	OBJECT_ATTRIBUTES oa;
	CLIENT_ID cid = { kdbg::processId, nullptr };
	InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL);

	if (!NT_SUCCESS(ZwOpenProcess(&hProcess, STANDARD_RIGHTS_ALL, &oa, &cid)))
		return false;

	HANDLE hDebugObject{ };
	NTSTATUS status = ZwQueryInformationProcess(hProcess, ProcessDebugObjectHandle, &hDebugObject, sizeof(hDebugObject), nullptr);

	ZwClose(hProcess);

	if (NT_SUCCESS(status) && hDebugObject != nullptr)
		return true;

	return false;
}

/*
* Here we check the DebugFlags. If DebugFlags is 0, it means that a debugger is attached.
* DebugFlags is located inside the EPROCESS structure ( undocumented ).
* Here we access DebugFlags via ZwQueryInformationProcess. -> 0x1f
*/
bool kdbg::DebugFlags()
{
	HANDLE hProcess{ };
	OBJECT_ATTRIBUTES oa;
	CLIENT_ID cid = { kdbg::processId, nullptr };
	InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL);

	if (!NT_SUCCESS(ZwOpenProcess(&hProcess, 0x0400, &oa, &cid)))
		return false;

	ULONG hDebugFlags = 0;
	NTSTATUS status = ZwQueryInformationProcess(hProcess, ProcessDebugFlags, &hDebugFlags, sizeof(hDebugFlags), nullptr);

	ZwClose(hProcess);

	if (NT_SUCCESS(status) && hDebugFlags == 0)
		return true;

	return false;
}

/*
* Here we check if there are any open debuggers so we can close them, you can add anything you want to the blacklist
*/
void kdbg::ExeCheck()
{
	const PCWSTR blacklisted[] = {
	L"ida.exe",
	L"idaq.exe",
	L"idaq64.exe",
	L"ida64.exe",
	L"x64dbg.exe",
	L"cheatengine-x86_64.exe",
	L"Ghidra.exe",
	L"ollydbg.exe",
	L"HTTPDebuggerUI.exe",
	L"FolderChangesView.exe",
	L"HxD.exe",
	L"Scylla_x64.exe",
	L"Scylla_x86.exe",
	L"ProcessHacker.exe",
	L"x64dbg-unsigned.exe",
	};

	for (int i = 0; i < ARRAYSIZE(blacklisted); i++) {
		HANDLE pid = util::retrieve_pid(blacklisted[i]);
		if (pid) {
			util::terminate_process(pid);
		}
	}
}


// 7zUpdate.cpp

#include "StdAfx.h"

#include "../../../../C/CpuArch.h"

#include "../../Common/LimitedStreams.h"
#include "../../Common/ProgressUtils.h"

#include "../../Common/CreateCoder.h"

#include "../../Compress/CopyCoder.h"

#include "../Common/ItemNameUtils.h"
#include "../Common/OutStreamWithCRC.h"

#include "7zDecode.h"
#include "7zEncode.h"
#include "7zFolderInStream.h"
#include "7zHandler.h"
#include "7zOut.h"
#include "7zUpdate.h"

namespace NArchive {
namespace N7z {

static const UInt64 k_LZMA = 0x030101;
static const UInt64 k_BCJ  = 0x03030103;
static const UInt64 k_BCJ2 = 0x0303011B;

static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";
static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;

#ifdef MY_CPU_X86_OR_AMD64
#define USE_86_FILTER
#endif

static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
    UInt64 position, UInt64 size, ICompressProgressInfo *progress)
{
  RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
  CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
  CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
  streamSpec->SetStream(inStream);
  streamSpec->Init(size);

  NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
  CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
  RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
  return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL);
}

static int GetReverseSlashPos(const UString &name)
{
  int slashPos = name.ReverseFind(L'/');
  #ifdef _WIN32
  int slash1Pos = name.ReverseFind(L'\\');
  slashPos = MyMax(slashPos, slash1Pos);
  #endif
  return slashPos;
}

int CUpdateItem::GetExtensionPos() const
{
  int slashPos = GetReverseSlashPos(Name);
  int dotPos = Name.ReverseFind(L'.');
  if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
    return Name.Length();
  return dotPos + 1;
}

UString CUpdateItem::GetExtension() const
{
  return Name.Mid(GetExtensionPos());
}

#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }

#define RINOZ_COMP(a, b) RINOZ(MyCompare(a, b))

static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
{
  size_t c1 = a1.GetCapacity();
  size_t c2 = a2.GetCapacity();
  RINOZ_COMP(c1, c2);
  for (size_t i = 0; i < c1; i++)
    RINOZ_COMP(a1[i], a2[i]);
  return 0;
}

static int CompareCoders(const CCoderInfo &c1, const CCoderInfo &c2)
{
  RINOZ_COMP(c1.NumInStreams, c2.NumInStreams);
  RINOZ_COMP(c1.NumOutStreams, c2.NumOutStreams);
  RINOZ_COMP(c1.MethodID, c2.MethodID);
  return CompareBuffers(c1.Props, c2.Props);
}

static int CompareBindPairs(const CBindPair &b1, const CBindPair &b2)
{
  RINOZ_COMP(b1.InIndex, b2.InIndex);
  return MyCompare(b1.OutIndex, b2.OutIndex);
}

static int CompareFolders(const CFolder &f1, const CFolder &f2)
{
  int s1 = f1.Coders.Size();
  int s2 = f2.Coders.Size();
  RINOZ_COMP(s1, s2);
  int i;
  for (i = 0; i < s1; i++)
    RINOZ(CompareCoders(f1.Coders[i], f2.Coders[i]));
  s1 = f1.BindPairs.Size();
  s2 = f2.BindPairs.Size();
  RINOZ_COMP(s1, s2);
  for (i = 0; i < s1; i++)
    RINOZ(CompareBindPairs(f1.BindPairs[i], f2.BindPairs[i]));
  return 0;
}

/*
static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
{
  return MyStringCompareNoCase(f1.Name, f2.Name);
}
*/

struct CFolderRepack
{
  int FolderIndex;
  int Group;
  CNum NumCopyFiles;
};

static int CompareFolderRepacks(const CFolderRepack *p1, const CFolderRepack *p2, void *param)
{
  RINOZ_COMP(p1->Group, p2->Group);
  int i1 = p1->FolderIndex;
  int i2 = p2->FolderIndex;
  const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param;
  RINOZ(CompareFolders(
      db.Folders[i1],
      db.Folders[i2]));
  return MyCompare(i1, i2);
  /*
  RINOZ_COMP(
      db.NumUnpackStreamsVector[i1],
      db.NumUnpackStreamsVector[i2]);
  if (db.NumUnpackStreamsVector[i1] == 0)
    return 0;
  return CompareFiles(
      db.Files[db.FolderStartFileIndex[i1]],
      db.Files[db.FolderStartFileIndex[i2]]);
  */
}

////////////////////////////////////////////////////////////

static int CompareEmptyItems(const int *p1, const int *p2, void *param)
{
  const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
  const CUpdateItem &u1 = updateItems[*p1];
  const CUpdateItem &u2 = updateItems[*p2];
  if (u1.IsDir != u2.IsDir)
    return (u1.IsDir) ? 1 : -1;
  if (u1.IsDir)
  {
    if (u1.IsAnti != u2.IsAnti)
      return (u1.IsAnti ? 1 : -1);
    int n = MyStringCompareNoCase(u1.Name, u2.Name);
    return -n;
  }
  if (u1.IsAnti != u2.IsAnti)
    return (u1.IsAnti ? 1 : -1);
  return MyStringCompareNoCase(u1.Name, u2.Name);
}

static const char *g_Exts =
  " lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo"
  " zip jar ear war msi"
  " 3gp avi mov mpeg mpg mpe wmv"
  " aac ape fla flac la mp3 m4a mp4 ofr


// Replacement for sympy's factorInt()

#include "./stdc++.h"
#include <numeric>
#include <cstdlib>
#include <fstream>
using namespace std;

// Multiplication modulo n (avoids overflow)
long long mulmod(long long a, long long b, long long mod) {
    __int128 res = (__int128)a * b % mod;
    return (long long)res;
}

// Fast modular exponentiation
long long modpow(long long base, long long exp, long long mod) {
    long long result = 1;
    while (exp > 0) {
        if (exp & 1) result = mulmod(result, base, mod);
        base = mulmod(base, base, mod);
        exp >>= 1;
    }
    return result;
}

// Miller–Rabin primality test
bool isPrime(long long n) {
    if (n < 2) return false;
    for (long long p : {2,3,5,7,11,13,17,19,23,29,31,37}) {
        if (n % p == 0) return n == p;
    }

    long long d = n-1, s = 0;
    while ((d & 1) == 0) { d >>= 1; s++; }

    auto check = [&](long long a) {
        if (a % n == 0) return true;
        long long x = modpow(a, d, n);
        if (x == 1 || x == n-1) return true;
        for (int i = 1; i < s; i++) {
            x = mulmod(x, x, n);
            if (x == n-1) return true;
        }
        return false;
    };

    for (long long a : {2,325,9375,28178,450775,9780504,1795265022}) {
        if (!check(a)) return false;
    }
    return true;
}

// Pollard's Rho
long long rho(long long n) {
    if (n % 2 == 0) return 2;
    long long x = rand() % (n-2) + 2;
    long long y = x;
    long long c = rand() % (n-1) + 1;
    long long d = 1;
    while (d == 1) {
        x = (mulmod(x, x, n) + c) % n;
        y = (mulmod(y, y, n) + c) % n;
        y = (mulmod(y, y, n) + c) % n;
        d = gcd(abs(x-y), n);
        if (d == n) return rho(n);
    }
    return d;
}

// Recursive factorization
void factorize(long long n, map<long long,int>& factors) {
    if (n == 1) return;
    if (isPrime(n)) {
        factors[n]++;
        return;
    }
    long long d = rho(n);
    factorize(d, factors);
    factorize(n/d, factors);
}

int main() {
    long long n;
    cout << "Enter value: ";
    cin >> n;
    map<long long,int> factors;
    factorize(n, factors);

    cout << n << " = 1";
    for (auto [p, e] : factors) {
        cout << " x " << p << "^" << e << " ";
    }

}


// Asqarjon Anvarov 220050
// Tuesday 09:00

// Question 1
#include <iostream>
using namespace std;

int main(int argCount, char *argValues[])
{
  cout << "Total arguments: " << argCount << endl;
  cout << "List of arguments:" << endl;

  for (int index = 0; index < argCount; ++index)
  {
    cout << "Arg " << index << ": " << argValues[index] << endl;
  }

  return 0;
}

// Question 2
// In C++, program execution always begins at main().

// Question 3
// In Java main is public static and has no return type. In C++ it returns an int status code.

// Question 4
// In C++, 0 = success, nonzero = failure. Java uses System.exit(value) for similar purpose.

// VARIABLES
// Question 1
#include <iostream>
using namespace std;

int main()
{
  int firstNum = 10, secondNum = 20;

  cout << "Before swap: firstNum = " << firstNum << ", secondNum = " << secondNum << endl;

  firstNum = firstNum + secondNum;
  secondNum = firstNum - secondNum;
  firstNum = firstNum - secondNum;

  cout << "After swap: firstNum = " << firstNum << ", secondNum = " << secondNum << endl;
  return 0;
}

// Question 2
// Primitive types keep raw values, reference ones hold memory locations.

// Question 3
// Local scope → exists inside block/function. Static/global → persists for whole program.

// Question 4
// C++ checks types during compilation.

// CONTROL FLOW
// Question 1
#include <iostream>
using namespace std;

int main()
{
  int prev = 0, curr = 1, nextNum;
  cout << "First 10 Fibonacci numbers: ";

  for (int i = 1; i <= 10; ++i)
  {
    if (i == 1)
    {
      cout << prev << " ";
      continue;
    }
    if (i == 2)
    {
      cout << curr << " ";
      continue;
    }
    nextNum = prev + curr;
    prev = curr;
    curr = nextNum;
    cout << nextNum << " ";
  }
  cout << endl;
  return 0;
}

// Question 2
// while: check first, may not run. do-while: check last, runs at least once.

// Question 3
// switch allows multiple paths using case/default/break.

// Question 4
// Short-circuit stops once outcome is clear. Example: (x!=0 && 10/x>1) avoids zero division.

// FUNCTION METHODS
// Question 1
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

bool checkPalindrome(const string &text)
{
  return equal(text.begin(), text.begin() + text.size() / 2, text.rbegin());
}

int main()
{
  cout << "madam palindrome? " << (checkPalindrome("madam") ? "true" : "false") << endl;
  cout << "hello palindrome? " << (checkPalindrome("hello") ? "true" : "false") << endl;
  return 0;
}

// Question 2
// C++: pass by value/ref/pointer. Java: always pass by value.

// Question 3
// Overloading requires different parameters. Changing only return type is not enough.

// Question 4
// Recursion: function calls itself. Needs a base case to stop.

// COMMENTS
// Question 1
#include <iostream>
using namespace std;

/**
 * Documentation style comment
 */
int main()
{
  // single-line comment
  int number = 5; // inline comment

  /*
     multi-line
     explanation
  */
  cout << "Comment example" << endl;
  return 0;
}

// Question 2
// Comments help understand code and teamwork.

// Question 3
// Tools like Doxygen/Javadoc turn them into docs.

// Question 4
// Clear code is good, but comments explain tricky logic.

// CLASSES
// Question 1
#include <iostream>
using namespace std;

class BankAccount
{
private:
  double funds;

public:
  BankAccount(double startBalance)
  {
    funds = (startBalance >= 0) ? startBalance : 0;
  }
  void deposit(double sum)
  {
    if (sum > 0)
      funds += sum;
  }
  double getBalance()
  {
    return funds;
  }
};

int main()
{
  BankAccount wallet(100.5);
  cout << "Initial: " << wallet.getBalance() << endl;
  wallet.deposit(50.25);
  cout << "After deposit: " << wallet.getBalance() << endl;
  return 0;
}

// Question 2
// Class = blueprint, object = actual instance.

// Question 3
// Public = everywhere, Private = inside class, Protected = class + children.

// Question 4
// Constructor sets up object. Default one has no arguments.

// ENUMS
// Question 1
#include <iostream>
#include <string>
using namespace std;

enum class Season
{
  SPRING,
  SUMMER,
  AUTUMN,
  WINTER
};

string suggestActivity(Season s)
{
  switch (s)
  {
  case Season::SPRING:
    return "Go hiking";
  case Season::SUMMER:
    return "Swim at the beach";
  case Season::AUTUMN:
    return "Collect leaves";
  case Season::WINTER:
    return "Make a snowman";
  default:
    return "Just relax";
  }
}

int main()
{
  Season current = Season::AUTUMN;
  cout << suggestActivity(current) << endl;
  return 0;
}

// Question 2
// Enums safer than plain numbers or strings.

// Question 3
// They improve clarity and prevent invalid values.

// Question 4
// C++11 enums are


// Fill out your copyright notice in the Description page of Project Settings.

#include "Weapon.h"
#include "Ninja.h"
#include "Components/SphereComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Components/SphereComponent.h"
#include "Components/BoxComponent.h"
#include "Kismet/KismetSystemLibrary.h"

AWeapon::AWeapon() {
	WeaponBox = CreateDefaultSubobject<UBoxComponent>(TEXT("WeaponBox"));
	WeaponBox->SetupAttachment(GetRootComponent());
	WeaponBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
	WeaponBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap);
	WeaponBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);

	StartTraceBox = CreateDefaultSubobject<USceneComponent>(TEXT("StartTraceBox"));
	StartTraceBox->SetupAttachment(GetRootComponent());
	EndTraceBox = CreateDefaultSubobject<USceneComponent>(TEXT("EndTraceBox"));
	EndTraceBox->SetupAttachment(GetRootComponent());

}

void AWeapon::BeginPlay()
{
	Super::BeginPlay();

	WeaponBox->OnComponentBeginOverlap.AddDynamic(this, &AWeapon::OnBoxOverlapBegin);

}

void AWeapon::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult){

	Super::OnOverlapBegin(OverlappedComp, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult);

}

void AWeapon::OnOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex){

	Super::OnOverlapEnd(OverlappedComp, OtherActor, OtherComp, OtherBodyIndex);

}

void AWeapon::OnBoxOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) {

	const FVector Start = StartTraceBox->GetComponentLocation();
	const FVector End = EndTraceBox->GetComponentLocation();
	 DrawDebugLine(GetWorld(), Start, End, FColor::Red, false, 2.f);

	 TArray<AActor*> ActorToIgnore;
	 ActorToIgnore.Add(this);
	 FHitResult BoxHit;
	 UKismetSystemLibrary::BoxTraceSingle(
		 this,
		 Start,
		 End,
		 FVector(5, 5, 5),
		 StartTraceBox->GetComponentRotation(),
		 ETraceTypeQuery::TraceTypeQuery1,
		 false,
		 ActorToIgnore,
		 EDrawDebugTrace::ForDuration,
		 BoxHit,
		 true

	 );

}
void AWeapon::Equip(class ANinja* Char, FName SocketName) {
	if (Char) {
		// Attach the weapon to the character's hand

		FAttachmentTransformRules AttachRules(EAttachmentRule::SnapToTarget, true);
		ItemMesh->AttachToComponent(Char->GetMesh(), AttachRules, SocketName);

		if (EquipSound)
		{
		UGameplayStatics::PlaySoundAtLocation(this, EquipSound, GetActorLocation());

		}

		if (Sphere)
		{

			Sphere->SetCollisionEnabled(ECollisionEnabled::NoCollision);
		}

	}
}


#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <windows.h>

#include "flutter_window.h"
#include "utils.h"

int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
                      _In_ wchar_t *command_line, _In_ int show_command) {
  // Attach to console when present (e.g., 'flutter run') or create a
  // new console when running with a debugger.
  if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
    CreateAndAttachConsole();
  }

  // Initialize COM, so that it is available for use in the library and/or
  // plugins.
  ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

  flutter::DartProject project(L"data");

  std::vector<std::string> command_line_arguments =
      GetCommandLineArguments();

  project.set_dart_entrypoint_arguments(std::move(command_line_arguments));

  FlutterWindow window(project);
  Win32Window::Point origin(10, 10);
  Win32Window::Size size(1280, 720);
  if (!window.Create(L"meme_app_flutter", origin, size)) {
    return EXIT_FAILURE;
  }
  window.SetQuitOnClose(true);

  ::MSG msg;
  while (::GetMessage(&msg, nullptr, 0, 0)) {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
  }

  ::CoUninitialize();
  return EXIT_SUCCESS;
}


#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;

// Product class
class Product {
public:
    int id;
    string name;
    double price;

    Product(int id, string name, double price) {
        this->id = id;
        this->name = name;
        this->price = price;
    }
};

// Cart Item (Product + Quantity)
class CartItem {
public:
    Product product;
    int quantity;

    CartItem(Product product, int quantity) : product(product), quantity(quantity) {}
};

// Shopping Cart
class ShoppingCart {
private:
    vector<CartItem> items;

public:
    // Add product to cart
    void addItem(Product product, int quantity) {
        for (auto &item : items) {
            if (item.product.id == product.id) {
                item.quantity += quantity;
                cout << "Updated quantity of " << product.name << " to " << item.quantity << endl;
                return;
            }
        }
        items.push_back(CartItem(product, quantity));
        cout << product.name << " added to cart." << endl;
    }

    // Remove product from cart
    void removeItem(int productId) {
        for (auto it = items.begin(); it != items.end(); ++it) {
            if (it->product.id == productId) {
                cout << it->product.name << " removed from cart." << endl;
                items.erase(it);
                return;
            }
        }
        cout << "Product not found in cart!" << endl;
    }

    // View all items in cart
    void viewCart() {
        if (items.empty()) {
            cout << " Cart is empty!" << endl;
            return;
        }

        cout << "\n Shopping Cart \n";
        cout << left << setw(5) << "ID" << setw(15) << "Product"
             << setw(10) << "Price" << setw(10) << "Quantity"
             << setw(10) << "Total" << endl;

        double total = 0;
        for (auto &item : items) {
            double itemTotal = item.product.price * item.quantity;
            total += itemTotal;
            cout << left << setw(5) << item.product.id
                 << setw(15) << item.product.name
                 << setw(10) << item.product.price
                 << setw(10) << item.quantity
                 << setw(10) << itemTotal << endl;
        }
        cout << "-----------------------------\n";
        cout << "Total Bill: $" << total << "\n";
    }
};

// Main Function
int main() {
    // Sample product list
    vector<Product> products = {
        Product(1, "Laptop", 75000.0),
        Product(2, "Smartphone", 25000.0),
        Product(3, "Headphones", 2000.0),
        Product(4, "Keyboard", 1500.0)
    };

    ShoppingCart cart;
    int choice;

    while (true) {
        cout << "\n Shopping Cart Menu \n";
        cout << "1. View Products\n";
        cout << "2. Add to Cart\n";
        cout << "3. Remove from Cart\n";
        cout << "4. View Cart\n";
        cout << "5. Exit\n";
        cout << "Enter your choice: ";
        cin >> choice;

        if (choice == 1) {
            cout << "\nAvailable Products:\n";
            for (auto &p : products) {
                cout << p.id << ". " << p.name << " - $" << p.price << endl;
            }
        }
        else if (choice == 2) {
            int pid, qty;
            cout << "Enter Product ID: ";
            cin >> pid;
            cout << "Enter Quantity: ";
            cin >> qty;

            bool found = false;
            for (auto &p : products) {
                if (p.id == pid) {
                    cart.addItem(p, qty);
                    found = true;
                    break;
                }
            }
            if (!found) cout << "Invalid Product ID!\n";
        }
        else if (choice == 3) {
            int pid;
            cout << "Enter Product ID to remove: ";
            cin >> pid;
            cart.removeItem(pid);
        }
        else if (choice == 4) {
            cart.viewCart();
        }
        else if (choice == 5) {
            cout << "Thank you for shopping! \n";
            break;
        }
        else {
            cout << "Invalid choice! Try again.\n";
        }
    }

    return 0;
}


#include <bits/stdc++.h>
#include "json.hpp"
using namespace std;
using json = nlohmann::json;

struct BigInt {
    string digits;
    BigInt(string s="0") {
        int i = 0; while (i+1 < (int)s.size() && s[i] == '0') i++;
        digits = s.substr(i);
    }
    BigInt(long long x) { digits = to_string(x); }

    static BigInt add(const BigInt &a, const BigInt &b) {
        string A = a.digits, B = b.digits;
        if (A.size() < B.size()) swap(A, B);
        int carry = 0; string res = "";
        int i = A.size()-1, j = B.size()-1;
        while (i >= 0 || j >= 0 || carry) {
            int x = (i >= 0 ? A[i]-'0' : 0);
            int y = (j >= 0 ? B[j]-'0' : 0);
            int sum = x + y + carry;
            res.push_back(char('0' + (sum % 10)));
            carry = sum / 10;
            i--; j--;
        }
        reverse(res.begin(), res.end());
        return BigInt(res);
    }

    static BigInt sub(const BigInt &a, const BigInt &b) {
        string A = a.digits, B = b.digits;
        while (B.size() < A.size()) B = "0" + B;
        int borrow = 0; string res="";
        for (int i = A.size()-1; i >= 0; i--) {
            int x = (A[i]-'0') - borrow;
            int y = (i >= 0 ? B[i]-'0' : 0);
            if (x < y) { x += 10; borrow = 1; }
            else borrow = 0;
            res.push_back(char('0' + (x-y)));
        }
        while (res.size() > 1 && res.back()=='0') res.pop_back();
        reverse(res.begin(), res.end());
        return BigInt(res);
    }

    static BigInt mul(const BigInt &a, const BigInt &b) {
        vector<int> res(a.digits.size()+b.digits.size(), 0);
        for (int i = a.digits.size()-1; i >= 0; i--) {
            for (int j = b.digits.size()-1; j >= 0; j--) {
                int p = (a.digits[i]-'0') * (b.digits[j]-'0');
                int pos1 = i+j, pos2 = i+j+1;
                int sum = p + res[pos2];
                res[pos1] += sum/10;
                res[pos2] = sum%10;
            }
        }
        string s=""; for (int x: res) s.push_back(char('0'+x));
        int k=0; while (k+1<s.size() && s[k]=='0') k++;
        return BigInt(s.substr(k));
    }

    friend ostream& operator<<(ostream &os, const BigInt &x) {
        os << x.digits; return os;
    }
};

BigInt convertToDecimal(const string &value, int base) {
    BigInt result("0");
    for (char c : value) {
        int digit;
        if (isdigit(c)) digit = c - '0';
        else digit = tolower(c) - 'a' + 10;
        result = BigInt::mul(result, BigInt(base));
        result = BigInt::add(result, BigInt(digit));
    }
    return result;
}

vector<BigInt> multiplyPoly(const vector<BigInt> &coeffs, BigInt root) {
    vector<BigInt> newCoeffs(coeffs.size() + 1, BigInt("0"));
    for (size_t i = 0; i < coeffs.size(); i++) {
        newCoeffs[i] = BigInt::add(newCoeffs[i], coeffs[i]);
        BigInt prod = BigInt::mul(coeffs[i], root);
        newCoeffs[i+1] = BigInt::sub(newCoeffs[i+1], prod);
    }
    return newCoeffs;
}

int main(int argc, char* argv[]) {
    if (argc < 2) return 1;
    ifstream file(argv[1]);
    if (!file.is_open()) return 1;

    json input;
    file >> input;
    int n = input["keys"]["n"];
    int k = input["keys"]["k"];
    int degree = k - 1;

    vector<BigInt> roots;
    for (auto it = input.begin(); it != input.end(); ++it) {
        if (it.key() == "keys") continue;
        string baseStr = it.value()["base"];
        string value = it.value()["value"];
        int base = stoi(baseStr);
        BigInt decimal = convertToDecimal(value, base);
        roots.push_back(decimal);
    }

    vector<BigInt> coeffs; coeffs.push_back(BigInt("1"));
    for (int i = 0; i < degree && i < (int)roots.size(); i++) {
        coeffs = multiplyPoly(coeffs, roots[i]);
    }

    for (int i = 0; i < (int)coeffs.size(); i++) {
        cout << coeffs[i];
        if (i < (int)coeffs.size()-1) cout << " ";
    }
    cout << endl;
}


#include <bits/stdc++.h>
#include "parser.h"

#define all(v) v.begin(), v.end()

using namespace std;

/** Global Constants **/
const string TRACE = "trace";
const string SHOW_STATISTICS = "stats";
const string ALGORITHMS[9] = {"", "FCFS", "RR", "SPN", "SRT", "PS", "FB-1", "FB-2i", "AGING"};

bool sortByServiceTime(const tuple<string, int, int> &a, const tuple<string, int, int> &b)
{
    return (get<2>(a) < get<2>(b));
}
bool sortByArrivalTime(const tuple<string, int, int> &a, const tuple<string, int, int> &b)
{
    return (get<1>(a) < get<1>(b));
}

bool descendingly_by_response_ratio(tuple<string, double, int> a, tuple<string, double, int> b)
{
    return get<1>(a) > get<1>(b);
}

bool byPriorityLevel (const tuple<int,int,int>&a,const tuple<int,int,int>&b){
    if(get<0>(a)==get<0>(b))
        return get<2>(a)> get<2>(b);
    return get<0>(a) > get<0>(b);
}

void clear_timeline()
{
    for(int i=0; i<last_instant; i++)
        for(int j=0; j<process_count; j++)
            timeline[i][j] = ' ';
}

string getProcessName(tuple<string, int, int> &a)
{
    return get<0>(a);
}

int getArrivalTime(tuple<string, int, int> &a)
{
    return get<1>(a);
}

int getServiceTime(tuple<string, int, int> &a)
{
    return get<2>(a);
}

int getPriorityLevel(tuple<string, int, int> &a)
{
    return get<2>(a);
}

double calculate_response_ratio(int wait_time, int service_time)
{
    return (wait_time + service_time)*1.0 / service_time;
}

void fillInWaitTime(){
    for (int i = 0; i < process_count; i++)
    {
        int arrivalTime = getArrivalTime(processes[i]);
        for (int k = arrivalTime; k < finishTime[i]; k++)
        {
            if (timeline[k][i] != '*')
                timeline[k][i] = '.';
        }
    }
}

void firstComeFirstServe()
{
    int time = getArrivalTime(processes[0]);
    for (int i = 0; i < process_count; i++)
    {
        int processIndex = i;
        int arrivalTime = getArrivalTime(processes[i]);
        int serviceTime = getServiceTime(processes[i]);

        finishTime[processIndex] = (time + serviceTime);
        turnAroundTime[processIndex] = (finishTime[processIndex] - arrivalTime);
        normTurn[processIndex] = (turnAroundTime[processIndex] * 1.0 / serviceTime);

        for (int j = time; j < finishTime[processIndex]; j++)
            timeline[j][processIndex] = '*';
        for (int j = arrivalTime; j < time; j++)
            timeline[j][processIndex] = '.';
        time += serviceTime;
    }
}

void roundRobin(int originalQuantum)
{
    queue<pair<int,int>>q;
    int j=0;
    if(getArrivalTime(processes[j])==0){
        q.push(make_pair(j,getServiceTime(processes[j])));
        j++;
    }
    int currentQuantum = originalQuantum;
    for(int time =0;time<last_instant;time++){
        if(!q.empty()){
            int processIndex = q.front().first;
            q.front().second = q.front().second-1;
            int remainingServiceTime = q.front().second;
            int arrivalTime = getArrivalTime(processes[processIndex]);
            int serviceTime = getServiceTime(processes[processIndex]);
            currentQuantum--;
            timeline[time][processIndex]='*';
            while(j<process_count && getArrivalTime(processes[j])==time+1){
                q.push(make_pair(j,getServiceTime(processes[j])));
                j++;
            }

            if(currentQuantum==0 && remainingServiceTime==0){
                finishTime[processIndex]=time+1;
                turnAroundTime[processIndex] = (finishTime[processIndex] - arrivalTime);
                normTurn[processIndex] = (turnAroundTime[processIndex] * 1.0 / serviceTime);
                currentQuantum=originalQuantum;
                q.pop();
            }else if(currentQuantum==0 && remainingServiceTime!=0){
                q.pop();
                q.push(make_pair(processIndex,remainingServiceTime));
                currentQuantum=originalQuantum;
            }else if(currentQuantum!=0 && remainingServiceTime==0){
                finishTime[processIndex]=time+1;
                turnAroundTime[processIndex] = (finishTime[processIndex] - arrivalTime);
                normTurn[processIndex] = (turnAroundTime[processIndex] * 1.0 / serviceTime);
                q.pop();
                currentQuantum=originalQuantum;
            }
        }
        while(j<process_count && getArrivalTime(processes[j])==time+1){
            q.push(make_pair(j,getServiceTime(processes[j])));
            j++;
        }
    }
    fillInWaitTime();
}

void shortestProcessNext()
{
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; // pair of service time and index
    int j = 0;
    for (int i = 0; i < last_instant; i++)
    {
        while(j<process_count && getArrivalTime(processes[j]) <= i){
            pq.push(make_pair(getServiceTime(processes[j]), j));
            j++;
        }
        if (!pq.empty())
        {
            int processIndex = pq.top().second;
            int arrivalTime = getArrivalTime


class Solution {
public:
    #define P pair<double, int>
    double maxAverageRatio(vector<vector<int>>& classes, int extraStudents) {
        int n = classes.size();

        priority_queue<P> pq; //max-heap  -  //{max-delta, idx}

        for(int i = 0; i < n; i++) {
            double current_PR = (double)classes[i][0]/classes[i][1];
            double new_PR = (double)(classes[i][0]+1)/(classes[i][1]+1);
            double delta = new_PR - current_PR;
            pq.push({delta, i});
        }

        //O(extraStudents * log(n))
        while(extraStudents--) { //O(k)
            auto curr = pq.top(); //log(n)
            pq.pop();

            double delta = curr.first;
            int idx = curr.second;

            classes[idx][0]++; //incremeent total passing students in the class
            classes[idx][1]++; //increment total students oin the class

            double current_PR = (double)classes[idx][0]/classes[idx][1];
            double new_PR = (double)(classes[idx][0]+1)/(classes[idx][1]+1);
            delta = new_PR - current_PR;
            pq.push({delta, idx}); //log(n)
        }

        double result = 0.0;
        for(int i = 0; i < n; i++) {
            result += (double)classes[i][0]/classes[i][1];
        }

        return result/n;
    }
};


#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <windows.h>

#include "flutter_window.h"
#include "utils.h"

int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
                      _In_ wchar_t *command_line, _In_ int show_command) {
  // Attach to console when present (e.g., 'flutter run') or create a
  // new console when running with a debugger.
  if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
    CreateAndAttachConsole();
  }

  // Initialize COM, so that it is available for use in the library and/or
  // plugins.
  ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

  flutter::DartProject project(L"data");

  std::vector<std::string> command_line_arguments =
      GetCommandLineArguments();

  project.set_dart_entrypoint_arguments(std::move(command_line_arguments));

  FlutterWindow window(project);
  Win32Window::Point origin(10, 10);
  Win32Window::Size size(1280, 720);
  if (!window.Create(L"chatapp", origin, size)) {
    return EXIT_FAILURE;
  }
  window.SetQuitOnClose(true);

  ::MSG msg;
  while (::GetMessage(&msg, nullptr, 0, 0)) {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
  }

  ::CoUninitialize();
  return EXIT_SUCCESS;
}


#include "RWA/Input/InputModifier_VirtualJoystick.h"

#include "EnhancedPlayerInput.h"

FInputActionValue UInputModifier_RWA_VirtualJoystick::ModifyRaw_Implementation(
	UEnhancedPlayerInput const* input,
	FInputActionValue value,
	float deltaTime)
{
	if (m_NeedsInit)
		SetupCurves();

	FInputActionValue result;

	switch (value.GetValueType()) {
		case EInputActionValueType::Boolean:
			return value;

		case EInputActionValueType::Axis1D:
			result = ModifyRaw(value.Get<float>(), deltaTime);
			break;

		case EInputActionValueType::Axis2D:
			result = ModifyRaw(value.Get<FVector2D>(), deltaTime);
			break;

		case EInputActionValueType::Axis3D:
			result = ModifyRaw(value.Get<FVector>(), deltaTime);
			break;
	}

	m_PrevInput = value;

	return result;
}

#if WITH_EDITOR
void UInputModifier_RWA_VirtualJoystick::PostEditChangeProperty(FPropertyChangedEvent& event)
{
	Super::PostEditChangeProperty(event);
	SetupCurves();
}
#endif

void UInputModifier_RWA_VirtualJoystick::PostLoad()
{
	Super::PostLoad();
	SetupCurves();
}

void UInputModifier_RWA_VirtualJoystick::SetupCurves()
{
	auto setupCurve = [](
		FCubicBezier& curve,
		float scaleX, float slope, float easing, float balance)
	{
		FVector2f p2_wgt1 { (1.f - slope) * scaleX, 1 };
		FVector2f p3 { p2_wgt1.X + (easing * scaleX), 1 };

		FVector2f p2_wgt0 = FMath::Lerp({ 0, 0 }, p2_wgt1, 0.5f);
		p2_wgt0 = FMath::Lerp(p2_wgt0, { 0, 1 }, easing * 0.5f);

		FVector2f p2 = FMath::Lerp(p2_wgt0, p2_wgt1, balance);

		curve.P0 = { 0, 0 };
		curve.P1 = { 0, 0 };
		curve.P2 = p2;
		curve.P3 = p3;
	};

	setupCurve(m_CurveIn, Resistance, Attack, SpringTension, SpringBalance);
	setupCurve(m_CurveOut, Resistance, SpringTension, Damping, 1.f - SpringBalance);

	m_ActiveCurve = &m_CurveIn;
	m_NeedsInit = false;
}

FInputActionValue UInputModifier_RWA_VirtualJoystick::ModifyRaw(float value, float deltaTime)
{
	float prev = m_PrevInput.Get<float>();
	float delta = value - prev;

	// Have we changed direction this tick?
	if (FMath::Abs(delta) > 0.5f) {
		m_Phase = FMath::IsNearlyZero(value) ? Falling : Rising;

		if (m_PrevCurve) {
			Swap(m_PrevCurve, m_ActiveCurve);
			m_PrevX = m_ActiveCurve->XForY(1.f - m_PrevY);
		}
		else {
			m_PrevCurve = m_ActiveCurve;
			m_ActiveCurve = m_Phase == Falling ? &m_CurveOut : &m_CurveIn;
		}
	}

	if (m_Phase == None)
		return FInputActionValue(value);

	float x = FMath::Min(
		m_ActiveCurve->Duration(),
		m_PrevX + (deltaTime * m_ActiveCurve->Duration()));

	float result = m_ActiveCurve->YForX(x);

	m_PrevX = x;
	m_PrevY = result;

	if (FMath::IsNearlyEqual(result, value)) {
		m_Phase = None;

		return FInputActionValue(result);
	}

	if (m_Phase == Falling)
		return FInputActionValue(1.f - result);

	return FInputActionValue(result);
}

FInputActionValue UInputModifier_RWA_VirtualJoystick::ModifyRaw(
	FVector2D value,
	float deltaTime)
	const
{
	if (value.IsNearlyZero())
		return FInputActionValue(value);

	FVector2D prev = m_PrevInput.Get<FVector2D>();
	FVector2D result = FMath::Vector2DInterpTo(prev, value, deltaTime, SpringTension);
	return FInputActionValue(result);
}

FInputActionValue UInputModifier_RWA_VirtualJoystick::ModifyRaw(
	FVector value,
	float deltaTime)
	const
{
	if (value.IsNearlyZero())
		return FInputActionValue(value);

	FVector prev = m_PrevInput.Get<FVector>();
	FVector result = FMath::VInterpTo(prev, value, deltaTime, SpringTension);
	return FInputActionValue(result);
}


#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <windows.h>

#include "flutter_window.h"
#include "utils.h"

int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
                      _In_ wchar_t *command_line, _In_ int show_command) {
  // Attach to console when present (e.g., 'flutter run') or create a
  // new console when running with a debugger.
  if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
    CreateAndAttachConsole();
  }

  // Initialize COM, so that it is available for use in the library and/or
  // plugins.
  ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

  flutter::DartProject project(L"data");

  std::vector<std::string> command_line_arguments =
      GetCommandLineArguments();

  project.set_dart_entrypoint_arguments(std::move(command_line_arguments));

  FlutterWindow window(project);
  Win32Window::Point origin(10, 10);
  Win32Window::Size size(1280, 720);
  if (!window.Create(L"DeskDoodles", origin, size)) {
    return EXIT_FAILURE;
  }
  window.SetQuitOnClose(true);

  ::MSG msg;
  while (::GetMessage(&msg, nullptr, 0, 0)) {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
  }

  ::CoUninitialize();
  return EXIT_SUCCESS;
}


#include <random>
#include <chrono>
#include <algorithm>
#include <vector>
#include <iostream>
#include "vector_ops.h"
using namespace std;
void print ( const vector <float>& m, int n_rows, int n_columns ) {

    /*  "Couts" the input vector as n_rows x n_columns matrix.
     Inputs:
     m: vector, matrix of size n_rows x n_columns
     n_rows: int, number of rows in the left matrix m1
     n_columns: int, number of columns in the left matrix m1
     */

    for( int i = 0; i != n_rows; ++i ) {
        for( int j = 0; j != n_columns; ++j ) {
            cout << m[ i * n_columns + j ] << " ";
        }
        cout << '\n';
    }
    cout << endl;
}

int argmax ( const vector <float>& m ) {
    return distance(m.begin(), max_element(m.begin(), m.end()));
}

vector<float> random_vector(const int size)
{
    /*  Generates a random vector with uniform distribution
     Inputs:
     size: the vector size
     */
    random_device rd;
    mt19937 gen(rd());
    uniform_real_distribution<> distribution(0.0, 0.05);
    static default_random_engine generator;

    vector<float> data(size);
    generate(data.begin(), data.end(), [&]() { return distribution(generator); });
    return data;
}

vector <float> operator+(const vector <float>& m1, const vector <float>& m2){

    /*  Returns the elementwise sum of two vectors.
     Inputs:
     m1: a vector
     m2: a vector
     Output: a vector, sum of the vectors m1 and m2.
     */

    const unsigned long VECTOR_SIZE = m1.size();
    vector <float> sum (VECTOR_SIZE);

    for (unsigned i = 0; i != VECTOR_SIZE; ++i){
        sum[i] = m1[i] + m2[i];
    };

    return sum;
}

vector <float> operator-(const vector <float>& m1, const vector <float>& m2){

    /*  Returns the difference between two vectors.
     Inputs:
     m1: vector
     m2: vector
     Output: vector, m1 - m2, difference between two vectors m1 and m2.
     */

    const unsigned long VECTOR_SIZE = m1.size();
    vector <float> difference (VECTOR_SIZE);

    for (unsigned i = 0; i != VECTOR_SIZE; ++i){
        difference[i] = m1[i] - m2[i];
    };

    return difference;
}

vector <float> operator*(const vector <float>& m1, const vector <float>& m2){

    /*  Returns the product of two vectors (elementwise multiplication).
     Inputs:
     m1: vector
     m2: vector
     Output: vector, m1 * m2, product of two vectors m1 and m2
     */

    const unsigned long VECTOR_SIZE = m1.size();
    vector <float> product (VECTOR_SIZE);

    for (unsigned i = 0; i != VECTOR_SIZE; ++i){
        product[i] = m1[i] * m2[i];
    };

    return product;
}

vector <float> operator*(const float m1, const vector <float>& m2){

    /*  Returns the product of a float and a vectors (elementwise multiplication).
     Inputs:
     m1: float
     m2: vector
     Output: vector, m1 * m2, product of two vectors m1 and m2
     */

    const unsigned long VECTOR_SIZE = m2.size();
    vector <float> product (VECTOR_SIZE);

    for (unsigned i = 0; i != VECTOR_SIZE; ++i){
        product[i] = m1 * m2[i];
    };

    return product;
}

vector <float> operator/(const vector <float>& m2, const float m1){

    /*  Returns the product of a float and a vectors (elementwise multiplication).
     Inputs:
     m1: float
     m2: vector
     Output: vector, m1 * m2, product of two vectors m1 and m2
     */

    const unsigned long VECTOR_SIZE = m2.size();
    vector <float> product (VECTOR_SIZE);

    for (unsigned i = 0; i != VECTOR_SIZE; ++i){
        product[i] = m2[i] / m1;
    };

    return product;
}

vector <float> transpose (float *m, const int C, const int R) {

    /*  Returns a transpose matrix of input matrix.
     Inputs:
     m: vector, input matrix
     C: int, number of columns in the input matrix
     R: int, number of rows in the input matrix
     Output: vector, transpose matrix mT of input matrix m
     */

    vector <float> mT (C*R);

    for(unsigned n = 0; n != C*R; n++) {
        unsigned i = n/C;
        unsigned j = n%C;
        mT[n] = m[R*j + i];
    }

    return mT;
}

vector <float> dot (const vector <float>& m1, const vector <float>& m2, const int m1_rows, const int m1_columns, const int m2_columns) {

    /*  Returns the product of two matrices: m1 x m2.
     Inputs:
     m1: vector, left matrix of size m1_rows x m1_columns
     m2: vector, right matrix of size m1_columns x m2_columns (the number of rows in the right matrix
     must be equal to the number of the columns in the left one)
     m1_rows: int, number of rows in the left matrix m1
     m1_columns: int, number of columns in the left matrix m1
     m2_columns: int, number of columns in the right matrix m2
     Output: vector, m1 * m2, product of two vectors m1 and m2, a matrix of size m1_rows x m2_columns
     */

    vector <float> output (m1_rows*m2_columns);
    for( int row = 0; row < m1_rows; ++row ) {
        for( int col = 0; col


/*
 * Copyright (C) 2020 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <cstdlib>
#include <pthread.h>

namespace {
    struct AtexitEntry {
        void (*fn)(void *);  // the __cxa_atexit callback
        void *arg;          // argument for `fn` callback
    };

    AtexitEntry *g_array = nullptr;
    size_t capacity = 8;
    size_t count = 0;
    pthread_mutex_t g_atexit_mutex = PTHREAD_MUTEX_INITIALIZER;
    inline void atexit_lock() {
        pthread_mutex_lock(&g_atexit_mutex);
    }

    inline void atexit_unlock() {
        pthread_mutex_unlock(&g_atexit_mutex);
    }

    // Register a function to be called either when a library is unloaded (dso != nullptr), or when the
    // program exits (dso == nullptr). The `dso` argument is typically the address of a hidden
    // __dso_handle variable. This function is also used as the backend for the atexit function.
    //
    // See https://itanium-cxx-abi.github.io/cxx-abi/abi.html#dso-dtor.
    //
    extern "C" [[gnu::used]] int __cxa_atexit(void (*func)(void *), void *arg, void * /* dso */) { // NOLINT(bugprone-reserved-identifier)
        int result = -1;

        if (func != nullptr) {
            atexit_lock();
            count++;
            if (!g_array) {
                g_array = reinterpret_cast<AtexitEntry*>(malloc(capacity * sizeof(AtexitEntry)));
            }
            if (count > capacity) [[unlikely]] {
                capacity *= 2;
                g_array = reinterpret_cast<AtexitEntry*>(realloc(g_array, capacity * sizeof(AtexitEntry)));
            }
            g_array[count - 1].fn = func;
            g_array[count - 1].arg = arg;
            result = 0;
            atexit_unlock();
        }

        return result;
    }

    // This function will be called by __on_dlclose, which is a destructor of dso
    // https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/arch-common/bionic/crtbegin_so.c;l=34;drc=5501003be73b73de59044b44b12f6e20ba6e0021
    extern "C" [[gnu::used]] void __cxa_finalize(void * /* dso */) { // NOLINT(bugprone-reserved-identifier)
        atexit_lock();
        restart:
        if (count > 0) {
            size_t total = count;
            for (size_t i = count - 1;; --i) {
                if (g_array[i].fn == nullptr) continue;

                // Clear the entry in the array to avoid calling an entry again
                // if __cxa_finalize is called recursively.
                const AtexitEntry entry = g_array[i];
                g_array[i] = {};

                atexit_unlock();
                entry.fn(entry.arg);
                atexit_lock();

                if (count != total) {
                    goto restart;
                }
                if (i == 0) break;
            }

            free(g_array);
        }
        atexit_unlock();
    }
}


#include "hashmap.hpp"

#include <algorithm>
#include <cstdint>
#include <cstring>

#include "rbv.hpp"

hashmap_t::entry_t::entry_t(Key key, Val *val, entry_t *next)
    : key(key), val_ptr(val), next(next) {}

void hashmap_t::entry_t::destroy() {
    if (val_ptr != nullptr) {
        free(val_ptr);
    }
}

void hashmap_t::entry_t::setv(Val val) {
    Val *new_val = (Val *)malloc(sizeof(Val));
    memcpy(new_val, &val, sizeof(Val));
    free(val_ptr);
    val_ptr = new_val;
}

const Val *hashmap_t::entry_t::getv() { return val_ptr; }

struct ordered_guard_t {
    ordered_mutex_t *mtx;
    ordered_guard_t(ordered_mutex_t *mtx) : mtx(mtx) {
#ifdef RBV_PRIMARY
        pthread_mutex_lock(&mtx->mtx);
#endif
        rbv::hasher.checkorder(mtx->order);
#ifndef RBV_PRIMARY
        pthread_mutex_lock(&mtx->mtx);
#endif
    }
    ~ordered_guard_t() {
#ifndef RBV_PRIMARY
        pthread_mutex_unlock(&mtx->mtx);
#endif
        rbv::hasher.checkorder(mtx->order);
#ifdef RBV_PRIMARY
        pthread_mutex_unlock(&mtx->mtx);
#endif
    }
};

hashmap_t *hashmap_t::make(size_t capacity) {
    hashmap_t *hm = (hashmap_t *)malloc(sizeof(hashmap_t));
    hm->capacity = capacity;
    if (capacity > 0) {
        hm->buckets = (entry_t **)malloc(capacity * sizeof(entry_t *));
        memset(hm->buckets, 0, capacity * sizeof(entry_t *));
        hm->locks =
            (ordered_mutex_t *)malloc(capacity * sizeof(ordered_mutex_t));
        for (size_t i = 0; i < capacity; ++i) {
            pthread_mutex_init(&hm->locks[i].mtx, nullptr);
            hm->locks[i].order = 0;
        }
    }
    return hm;
}

void hashmap_t::destroy() {
    if (capacity > 0) {
        for (size_t i = 0; i < capacity; ++i) {
            entry_t *entry = buckets[i];
            while (entry != nullptr) {  // next will not be nullptr
                entry_t *enext = entry->next;
                free(entry);
                entry = enext;
            }
        }
        free((void *)buckets);
        for (size_t i = 0; i < capacity; ++i) {
            pthread_mutex_destroy(&locks[i].mtx);
        }
        free(locks);
    }
    free(this);
}

const Val *hashmap_t::get(const Key &key) {
    uint32_t hv = key.hash() % capacity;
    ordered_guard_t guard(&locks[hv]);
    entry_t *bucket = buckets[hv];
    while (bucket != nullptr) {
        rbv::hasher.combine(std::string(bucket->key.ch, KEY_LEN));
        if (bucket->key == key) {
            rbv::hasher.combine(std::string(bucket->getv()->ch, VAL_LEN));
            return bucket->getv();
        }
        bucket = bucket->next;
    }
    return nullptr;
}

RetType hashmap_t::set(const Key &key, const Val &val) {
    uint32_t hv = key.hash() % capacity;
    ordered_guard_t guard(&locks[hv]);
    entry_t *bucket = buckets[hv];
    while (bucket != nullptr) {
        rbv::hasher.combine(std::string(bucket->key.ch, KEY_LEN));
        if (bucket->key == key) {
            rbv::hasher.combine(std::string(bucket->getv()->ch, VAL_LEN));
            bucket->setv(val);
            return kStored;
        }
        bucket = bucket->next;
    }
    entry_t *new_entry = (entry_t *)malloc(sizeof(entry_t));
    new_entry->key = key;
    Val *val_ptr = (Val *)malloc(sizeof(Val));
    memcpy(val_ptr, &val, sizeof(Val));
    new_entry->val_ptr = val_ptr;
    new_entry->next = buckets[hv];
    rbv::hasher.combine(std::string(new_entry->key.ch, KEY_LEN));
    rbv::hasher.combine(std::string(new_entry->getv()->ch, VAL_LEN));
    buckets[hv] = new_entry;
    rbv::hasher.combine(std::string(buckets[hv]->key.ch, KEY_LEN));
    return kCreated;
}

RetType hashmap_t::del(const Key &key) {
    uint32_t hv = key.hash() % capacity;
    ordered_guard_t guard(&locks[hv]);
    entry_t **bucket = &buckets[hv];
    while (*bucket != nullptr) {
        rbv::hasher.combine(std::string((*bucket)->key.ch, KEY_LEN));
        if ((*bucket)->key == key) {
            rbv::hasher.combine(std::string((*bucket)->getv()->ch, VAL_LEN));
            entry_t *old = *bucket;
            *bucket = (*bucket)->next;
            free(old);
            return kDeleted;
        }
        bucket = &(*bucket)->next;
    }
    return kNotFound;
}

const Val *hashmap_get(hashmap_t *hmap, Key key) { return hmap->get(key); }

RetType hashmap_set(hashmap_t *hmap, Key key, Val val) {
    return hmap->set(key, val);
}

RetType hashmap_del(hashmap_t *hmap, Key key) { return hmap->del(key); }


// dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications)
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)

// Implemented features:
//  [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
//  [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
//  [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
//  [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
//  [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.

// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ                  https://dearimgui.com/faq
// - Getting Started      https://dearimgui.com/getting-started
// - Documentation        https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp

// Configuration flags to add in your imconfig file:
//#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD              // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant.

// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
//  2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
//  2024-07-08: Inputs: Fixed ImGuiMod_Super being mapped to VK_APPS instead of VK_LWIN||VK_RWIN. (#7768)
//  2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
//  2023-09-25: Inputs: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit it (same behavior as GLFW/SDL).
//  2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window.
//  2023-04-19: Added ImGui_ImplWin32_InitForOpenGL() to facilitate combining raw Win32/Winapi with OpenGL. (#3218)
//  2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen. (#2702)
//  2023-02-15: Inputs: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse position over non-client area (e.g. OS decorations) when app is not focused. (#6045, #6162)
//  2023-02-02: Inputs: Flipping WM_MOUSEHWHEEL (horizontal mouse-wheel) value to match other backends and offer consistent horizontal scrolling direction. (#4019, #6096, #1463)
//  2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
//  2022-09-28: Inputs: Convert WM_CHAR values with MultiByteToWideChar() when window class was registered as MBCS (not Unicode).
//  2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
//  2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
//  2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
//  2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
//  2022-01-17: Inputs: always update key mods next and before a key event (not in NewFrame) to fix input queue with very low framerates.
//  2022-01-12: Inputs: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
//  2022-01-12: Inputs: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
//  2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
//  2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness.
//  2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
//  2021-08-02: Inputs: Fixed keyboard modifiers being reported when host window doesn't have focus.
//  2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using TrackMouseEvent() to receive WM_MOUSELEAVE events).
//  2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX


#include "BudgetManager.h"
#include <iostream>
#include <ctime>
#include <iomanip>
#include <sstream>

std::string getTodayDate() {
    time_t now = time(0);
    tm ltm;
    localtime_s(&ltm, &now); // safer, thread-safe version
    std::ostringstream oss;
    oss << std::setw(4) << std::setfill('0') << 1900 + ltm.tm_year << '-'
        << std::setw(2) << std::setfill('0') << 1 + ltm.tm_mon << '-'
        << std::setw(2) << std::setfill('0') << ltm.tm_mday;
    return oss.str();
}

int main() {
    BudgetManager manager("budget.txt");

    int choice;
    do {
        // Menü ausgeben
        std::cout << "\n--- Budgetverwaltung ---\n";
		std::cout << "1. Einnahme hinzufuegen\n";
        std::cout << "2. Ausgabe hinzufuegen\n";
        std::cout << "3. Kontostand anzeigen\n";
        std::cout << "4. Alle Transaktionen anzeigen\n";
        std::cout << "5. Speichern & Beenden\n";
        std::cout << "Bitte waelen";
        std::cin >> choice;

        if (choice == 1 || choice == 2) {
            double amount;
            std::string desc, date;

            std::cout << "Betrag eingeben: ";
            std::cin >> amount;
            std::cin.ignore();

            std::cout << "Beschreibung eingeben: ";
            getline(std::cin, desc);

			std::cout << "Datum eingeben (JJJJ-MM-TT) oder Enter fuer heute:";
            getline(std::cin, date);

            if (date.empty()) {
                date = getTodayDate();
            }

            if (choice == 1)
                manager.addIncome(amount, desc, date);
            else
                manager.addExpense(amount, desc, date);
        }

        else if (choice == 3) {
            std::cout << "Aktueller Kontostand: " << manager.getBalance() << " €\n";
        }

        else if (choice == 4) {
            manager.showTransactions();
        }

    } while (choice != 5);

    manager.saveToFile();
    std::cout << "Daten gespeichert. Auf Wiedersehen!\n";
}


//*****************************************************************************
//
// Copyright (C) 2000-2005 Quantic Dream SA
//
// These coded instructions, statements and computer programs contain
// unpublished information proprietary to Quantic Dream SA and are
// protected by French and EEC copyright laws. They may not be
// disclosed to third parties or copied or duplicated, in whole or in part,
// without prior written consent of Quantic Dream SA
//
// Unpublished-rights reserved under the Copyright Laws of the EEC.
//
//*****************************************************************************
//
//	CLASS:	SORTED_OBJECT
//
//	04-07-19:	RMA - Created
//*****************************************************************************

#include	"Root.h"
#include	INCL_3DENGINE(Display/SortedObject/SortedObject)

//=============================================================================
//	CODE STARTS HERE
//=============================================================================

//-----------------------------------------------------------------------------
//	Name:		SORTED_OBJECT constructor
//	Object:
//	04-07-19:	RMA - Created
//-----------------------------------------------------------------------------
SORTED_OBJECT::SORTED_OBJECT()
:
_pEntity(NULL)
{
	// Do nothing
}

//-----------------------------------------------------------------------------
//	Name:		SORTED_OBJECT constructor
//	Object:
//	04-07-19:	RMA - Created
//-----------------------------------------------------------------------------
SORTED_OBJECT::SORTED_OBJECT(const SORTED_OBJECT & C)
:
_pEntity(C._pEntity),
_vPrimitives(C._vPrimitives)
{
	// Do nothing
}

//-----------------------------------------------------------------------------
//	Name:		SORTED_OBJECT constructor
//	Object:
//	04-07-19:	RMA - Created
//-----------------------------------------------------------------------------
SORTED_OBJECT::SORTED_OBJECT(ENTITY_ABC *	pEntity,
							 UInt32			nPrimitive)
:
_pEntity(pEntity)
{
	_vPrimitives.PushTail(nPrimitive);
}

//-----------------------------------------------------------------------------
//	Name:		SORTED_OBJECT destructor
//	Object:
//	04-07-19:	RMA - Created
//-----------------------------------------------------------------------------
SORTED_OBJECT::~SORTED_OBJECT()
{
	// Do nothing
}

//-----------------------------------------------------------------------------
//	Name:		operator=
//	Object:
//	04-07-19:	RMA - Created
//-----------------------------------------------------------------------------
SORTED_OBJECT &	SORTED_OBJECT::operator=(const SORTED_OBJECT & C)
{
	_pEntity = C._pEntity;
	_vPrimitives = C._vPrimitives;

	return	(*this);
}

//-----------------------------------------------------------------------------
//	Name:		AddPrimitive
//	Object:
//	06-01-25:	ELE - Created
//-----------------------------------------------------------------------------
void	SORTED_OBJECT::AddPrimitive(UInt32	nPrimitive)
{
	_vPrimitives.PushTail(nPrimitive);
}

//=============================================================================
//	CODE ENDS HERE
//=============================================================================


#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <windows.h>

#include "flutter_window.h"
#include "utils.h"

int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
                      _In_ wchar_t *command_line, _In_ int show_command) {
  // Attach to console when present (e.g., 'flutter run') or create a
  // new console when running with a debugger.
  if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
    CreateAndAttachConsole();
  }

  // Initialize COM, so that it is available for use in the library and/or
  // plugins.
  ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

  flutter::DartProject project(L"data");

  std::vector<std::string> command_line_arguments =
      GetCommandLineArguments();

  project.set_dart_entrypoint_arguments(std::move(command_line_arguments));

  FlutterWindow window(project);
  Win32Window::Point origin(10, 10);
  Win32Window::Size size(1280, 720);
  if (!window.Create(L"aula6mobile", origin, size)) {
    return EXIT_FAILURE;
  }
  window.SetQuitOnClose(true);

  ::MSG msg;
  while (::GetMessage(&msg, nullptr, 0, 0)) {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
  }

  ::CoUninitialize();
  return EXIT_SUCCESS;
}


#include "mks_can_interface.hpp"
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <unistd.h>
#include <cstring>
#include <iostream>
#include <chrono>
#include <tuple>

namespace mks {

MksCanInterface::MksCanInterface()
    : can_socket_(-1), initialized_(false), running_(false) {
    // Initialize motor states using piecewise_construct
    for (uint8_t i = 1; i <= 6; ++i) {
        JointId joint_id = static_cast<JointId>(i);
        motor_states_.emplace(std::piecewise_construct,
                             std::forward_as_tuple(joint_id),
                             std::forward_as_tuple());
    }
}

MksCanInterface::~MksCanInterface() {
    deinit();
}

bool MksCanInterface::init(const std::string& can_interface, int /* bitrate */) {
    if (initialized_) {
        std::cerr << "MksCanInterface already initialized" << std::endl;
        return false;
    }

    can_interface_ = can_interface;

    // Create CAN socket
    can_socket_ = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if (can_socket_ < 0) {
        std::cerr << "Failed to create CAN socket" << std::endl;
        return false;
    }

    // Set up CAN interface
    struct ifreq ifr;
    strcpy(ifr.ifr_name, can_interface.c_str());
    if (ioctl(can_socket_, SIOCGIFINDEX, &ifr) < 0) {
        std::cerr << "Failed to get interface index for " << can_interface << std::endl;
        close(can_socket_);
        can_socket_ = -1;
        return false;
    }

    // Bind socket to CAN interface
    struct sockaddr_can addr;
    memset(&addr, 0, sizeof(addr));
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;

    if (bind(can_socket_, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        std::cerr << "Failed to bind CAN socket to " << can_interface << std::endl;
        close(can_socket_);
        can_socket_ = -1;
        return false;
    }

    // Start receiver thread
    running_ = true;
    receiver_thread_ = std::thread(&MksCanInterface::receiverLoop, this);

    initialized_ = true;
    std::cout << "MksCanInterface initialized on " << can_interface << std::endl;
    return true;
}

void MksCanInterface::deinit() {
    if (!initialized_) {
        return;
    }

    // Stop receiver thread
    running_ = false;
    if (receiver_thread_.joinable()) {
        receiver_thread_.join();
    }

    // Close socket
    if (can_socket_ >= 0) {
        close(can_socket_);
        can_socket_ = -1;
    }

    initialized_ = false;
    std::cout << "MksCanInterface deinitialized" << std::endl;
}

bool MksCanInterface::setPosition(JointId joint_id, int32_t position, uint16_t speed) {
    if (!initialized_) {
        std::cerr << "MksCanInterface not initialized" << std::endl;
        return false;
    }

    MksMessage msg = MksProtocol::createPositionCommand(position, speed);
    return sendCanFrame(joint_id, msg);
}

bool MksCanInterface::enableMotor(JointId joint_id) {
    if (!initialized_) {
        std::cerr << "MksCanInterface not initialized" << std::endl;
        return false;
    }

    MksMessage msg = MksProtocol::createEnableDisableCommand(true);
    return sendCanFrame(joint_id, msg);
}

bool MksCanInterface::disableMotor(JointId joint_id) {
    if (!initialized_) {
        std::cerr << "MksCanInterface not initialized" << std::endl;
        return false;
    }

    MksMessage msg = MksProtocol::createEnableDisableCommand(false);
    return sendCanFrame(joint_id, msg);
}

bool MksCanInterface::readPosition(JointId joint_id) {
    if (!initialized_) {
        std::cerr << "MksCanInterface not initialized" << std::endl;
        return false;
    }

    MksMessage msg = MksProtocol::createPositionReadCommand();
    return sendCanFrame(joint_id, msg);
}

bool MksCanInterface::readVelocity(JointId joint_id) {
    if (!initialized_) {
        std::cerr << "MksCanInterface not initialized" << std::endl;
        return false;
    }

    MksMessage msg = MksProtocol::createVelocityReadCommand();
    return sendCanFrame(joint_id, msg);
}

bool MksCanInterface::calibrateMotor(JointId joint_id, int32_t old_position) {
    if (!initialized_) {
        std::cerr << "MksCanInterface not initialized" << std::endl;
        return false;
    }

    MksMessage msg = MksProtocol::createCalibrationCommand(old_position);
    return sendCanFrame(joint_id, msg);
}

bool MksCanInterface::emergencyStop(JointId joint_id) {
    if (!initialized_) {
        std::cerr << "MksCanInterface not initialized" << std::endl;
        return false;
    }

    MksMessage msg = MksProtocol::createEmergencyStopCommand();
    return sendCanFrame(joint_id, msg);
}

bool MksCanInterface::emergencyStopAll() {
    bool success = true;
    for (uint8_t i = 1; i <= 6; ++i) {
        JointId joint_id = static_cast<


#include <iostream>
#include <string>
#include <fstream>
#include <vector>

using namespace std;

void kayıt() {
	int sıra = 0;
	ifstream d("kayıt.txt");
	string sır;
	if (d.is_open()) {
		while (getline(d, sır)) {
			sıra++;
		}
	}
	string ad;
	string tc;
	cout << "Lütfen ilk önce adını griin:\n" << endl;
	cin >> ad;
	cout << "Tc numaranızı girin:\t" << endl;
	cin >> tc;
	while (tc.length() != 2) {
		cout << "Tc geçersiz yeniden girin :\t" << endl;
		cin >> tc;
	}
	ofstream x("kayıt.txt", ios::app);
	if (x.is_open()) {
		x << "\n" << sıra << ad << tc;
	}

	x.close();
	ofstream y("money.txt", ios::app);
	if (y.is_open()) {
		y << "\n" << sıra << ":" << "0" << "TL";
	}
	y.close();
}
void gos() {
	ifstream p("kayıt.txt");
	string de;
	if (p.is_open()) {
		while (getline(p, de)) {
			cout << de << endl;
		}
	}
}
bool regıs() {
	string kullan, password,tccc;
	cout << "-----------------------------------------"<<endl;
	cout << "Maybe Yapının Özel Banka Uygulamasına Hoş Geldiniz"<<endl;
	cout << "Lütfen Kayıt etmek istediğiniz kullanıcı adını girin" << endl;
	cin >> kullan;
	cout << "Lütfen Kayıt etmek istediğiniz şifreyi girin" << endl;
	cin >> password;
	cout << "Lütfen Kayıt etmek istediğiniz tc girin" << endl;
	cin >> tccc;
	while (2 != tccc.length()) {
		cout << "lütfen tc 2 haneli olacakşekilde yapın" << endl;
		cin >> tccc;
	}
	int sıra = 0;
	ifstream d("kayıt.txt");
	string sır;
	while (getline(d, sır)) {
		sıra++;
	}
	d.close();
	ofstream x("kayıt.txt", ios::app);
	if (x.is_open()) {
		x << sıra << kullan << tccc << "\n";
	}
	x.close();
	ofstream ı("money.txt", ios::app);
	if (ı.is_open()) {
		ı << sıra << ":0TL" << "\n";
	}
	ı.close();
	ofstream o("log.txt", ios::app);
	if (o.is_open()) {
		o << sıra << "." << kullan <<":" << password << "\n";
		}
	o.close();
	return true;

}
void money() {
	int ıd;
	int sıra = 0;
	int kayıt = 0;
	cout << "Görmek istediğinz id girin \t";
	cin >> ıd;
	ifstream r("kayıt.txt");
	string sıraa;
	if (r.is_open()) {
		while (getline(r, sıraa)) {
			kayıt++;
		}
	}
	while (ıd >= kayıt) {
		cout << "hatalı griiş ıd doğru griin";
		cin >> ıd;
	}
	ifstream d("money.txt");
	string sır;
	if (d.is_open()) {
		while (getline(d, sır)) {
			if (sıra == ıd) {
				cout << sır;
				break;
			}
			else
			{
				sıra++;
			}

		}

	}
}
void para() {
	int id;
	int toplamKullanici = 0;
	cout << "Lütfen ID girin: ";
	cin >> id;

	ifstream kayit("kayıt.txt");
	string satir;
	while (getline(kayit, satir)) {
		toplamKullanici++;
	}
	kayit.close();

	while (id >= toplamKullanici) {
		cout << "Geçersiz ID! Yeniden girin: ";
		cin >> id;
	}

	ifstream paraDosya("money.txt");
	vector<string> tumSatirlar;
	while (getline(paraDosya, satir)) {
		tumSatirlar.push_back(satir);
	}
	paraDosya.close();

	string paraSatiri = tumSatirlar[id];

	size_t ikiNokta = paraSatiri.find(':');
	string bakiyeStr = paraSatiri.substr(ikiNokta + 1);
	size_t tlPoz = bakiyeStr.find("TL");
	if (tlPoz != string::npos) {
		bakiyeStr = bakiyeStr.substr(0, tlPoz);
	}
	float bakiye = stof(bakiyeStr);

	int secim;
	float miktar;
	cout << "Mevcut bakiye: " << bakiye << " TL\n";
	cout << "1 - Para Yatır\n2 - Para Çek\nSeçiminiz: ";
	cin >> secim;

	cout << "Miktar: ";
	cin >> miktar;

	if (secim == 1) {
		bakiye += miktar;
	}
	else if (secim == 2) {
		while (miktar > bakiye) {
			cout << "Yetersiz bakiye!.Yeniden girin" << endl;
			cin >> miktar;
		}
		bakiye -= miktar;
	}
	else {
		cout << "Geçersiz işlem seçimi!" << endl;
		return;
	}

	tumSatirlar[id] = to_string(id) + ":" + to_string((int)bakiye) + "TL";

	ofstream yaz("money.txt", ios::trunc);
	for (const auto& s : tumSatirlar) {
		yaz << s << "\n";
	}
	yaz.close();

	cout << "Yeni bakiye: " << bakiye << " TL" << endl;
}

string lo() {

	vector<string> ve;
	string kull, pass;
	int sayma = 0;
	cout << "Giriş yapmak için kullanıcı adını girin:\t";
	cin >> kull;
	cout << "Giriş yapmak için şifreyi girin:\t";
	cin >> pass;
	ifstream ope("log.txt");
	string okuma;
	while (getline(ope, okuma)) {
		ve.push_back(okuma);
		sayma++;
	}
	ope.close();
	string verkull[100], verpass[100],verıd[100];
	for (int y = 0; sayma > y; y++) {
		string s = ve[y];
		verıd[y] = ve[y].substr(0, ve[y].find('.'));
		verkull[y] = ve[y].substr(ve[y].find('.')+1,ve[y].find(':')- ve[y].find('.')-1);
		verpass[y] = ve[y].substr(ve[y].find(':')+1);
	}
	bool bulundu = false;
	for (int i = 0; i < sayma; i++) {
		if (kull == verkull[i]) {
			while (pass != verpass[i]) {
				cout << "şifreniz yanlış yeniden gir:\t";
				cin >> pass;
			}
			bulundu = true;
			break;
		}
	}
	if (bulundu == true) {
		return "true";
	}
	else {
		return "false";
	}

}

int main() {
	setlocale(LC_ALL, "Turkish");
	int mai;
	cout << "----------------------------------"<<endl;
	cout << "Login için : 1" <


/* Copyright (c) 2021-2022 OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */

//
// Created by wangyunlai on 2024/01/30
//

#include "common/thread/thread_util.h"
#include "storage/clog/disk_log_handler.h"
#include "storage/clog/log_file.h"
#include "storage/clog/log_replayer.h"
#include "common/lang/chrono.h"

using namespace common;

////////////////////////////////////////////////////////////////////////////////
// LogHandler

RC DiskLogHandler::init(const char *path)
{
  const int max_entry_number_per_file = 1000;
  return file_manager_.init(path, max_entry_number_per_file);
}

RC DiskLogHandler::start()
{
  if (thread_) {
    LOG_ERROR("log has been started");
    return RC::INTERNAL;
  }

  running_.store(true);
  thread_ = make_unique<thread>(&DiskLogHandler::thread_func, this);
  LOG_INFO("log handler started");
  return RC::SUCCESS;
}

RC DiskLogHandler::stop()
{
  if (!thread_) {
    LOG_ERROR("log has not been started");
    return RC::INTERNAL;
  }

  running_.store(false);

  LOG_INFO("log handler stopped");
  return RC::SUCCESS;
}

RC DiskLogHandler::await_termination()
{
  if (!thread_) {
    LOG_ERROR("log has not been started");
    return RC::INTERNAL;
  }

  if (running_.load()) {
    LOG_ERROR("log handler is running");
    return RC::INTERNAL;
  }

  thread_->join();
  thread_.reset();
  LOG_INFO("log handler joined");
  return RC::SUCCESS;
}

RC DiskLogHandler::replay(LogReplayer &replayer, LSN start_lsn)
{
  LSN max_lsn = 0;
  auto replay_callback = [&replayer, &max_lsn](LogEntry &entry) -> RC {
    if (entry.lsn() > max_lsn) {
      max_lsn = entry.lsn();
    }
    return replayer.replay(entry);
  };

  RC rc = iterate(replay_callback, start_lsn);
  if (OB_FAIL(rc)) {
    LOG_WARN("failed to iterate log entries. rc=%s", strrc(rc));
    return rc;
  }

  rc = entry_buffer_.init(max_lsn);
  if (OB_FAIL(rc)) {
    LOG_WARN("failed to init log entry buffer. rc=%s", strrc(rc));
    return rc;
  }

  LOG_INFO("replay clog files done. start lsn=%ld, max_lsn=%ld", start_lsn, max_lsn);
  return rc;
}

RC DiskLogHandler::iterate(function<RC(LogEntry&)> consumer, LSN start_lsn)
{
  vector<string> log_files;
  RC rc = file_manager_.list_files(log_files, start_lsn);
  if (OB_FAIL(rc)) {
    LOG_WARN("failed to list clog files. rc=%s", strrc(rc));
    return rc;
  }

  for (auto &file : log_files) {
    LogFileReader file_handle;
    rc = file_handle.open(file.c_str());
    if (OB_FAIL(rc)) {
      LOG_WARN("failed to open clog file. rc=%s, file=%s", strrc(rc), file.c_str());
      return rc;
    }

    rc = file_handle.iterate(consumer, start_lsn);
    if (OB_FAIL(rc)) {
      LOG_WARN("failed to iterate clog file. rc=%s, file=%s", strrc(rc), file.c_str());
      return rc;
    }

    rc = file_handle.close();
    if (OB_FAIL(rc)) {
      LOG_WARN("failed to close clog file. rc=%s, file=%s", strrc(rc), file.c_str());
      return rc;
    }
  }

  LOG_INFO("iterate clog files done. rc=%s", strrc(rc));
  return RC::SUCCESS;
}

RC DiskLogHandler::_append(LSN &lsn, LogModule module, vector<char> &&data)
{
  ASSERT(running_.load(), "log handler is not running. lsn=%ld, module=%s, size=%d",
        lsn, module.name(), data.size());

  RC rc = entry_buffer_.append(lsn, module, std::move(data));
  if (OB_FAIL(rc)) {
    LOG_WARN("failed to append log entry to buffer. rc=%s", strrc(rc));
    return rc;
  }

  return RC::SUCCESS;
}

RC DiskLogHandler::wait_lsn(LSN lsn)
{
  // 直接强制等待。在生产系统中，我们可能会使用条件变量来等待。
  while (running_.load() && current_flushed_lsn() < lsn) {
    this_thread::sleep_for(chrono::milliseconds(100));
  }

  if (current_flushed_lsn() >= lsn) {
    return RC::SUCCESS;
  } else {
    return RC::INTERNAL;
  }
}

void DiskLogHandler::thread_func()
{
  /*
  这个线程一直不停的循环，检查日志缓冲区中是否有日志在内存中，如果在内存中就刷新到磁盘。
  这种做法很粗暴简单，与生产数据库的做法不同。生产数据库通常会在内存达到一定量，或者一定时间
  之后，会刷新一下磁盘。这样做的好处是减少磁盘的IO次数，提高性能。
  */
  thread_set_name("LogHandler");
  LOG_INFO("log handler thread started");

  LogFileWriter file_writer;

  RC rc = RC::SUCCESS;
  while (running_.load() || entry_buffer_.entry_number() > 0) {
    if (!file_writer.valid() || rc == RC::LOG_FILE_FULL) {
      if (rc == RC::LOG_FILE_FULL) {
        // 我们在这里判断日志文件是否写满了。
        rc = file_manager_.next_file(file_writer);
      } else {
        rc = file_manager_.last_file(file_writer);
      }
      if (OB_FAIL(rc)) {
        LOG_WARN("failed to open log file. rc=%s", strrc(rc));
        // 总是使用最简单的方法等待一段时间，期望错误会被修复。
        // 这在生产系统中是不被允许的。
        this_thread::sleep_for(chrono::milliseconds(100));
        con


#include <iostream>
#include "Render.h"
#include "AddNode.h"
#include "InputNode.h"

class VSNode : public VScritImgui::Layer
{
public:
    virtual void OnAttach() override
    {

    }

    virtual void OnDetach() override
    {

    }

    virtual void OnUpdate(float ts) override
    {

    }

    virtual void OnUIRender() override
    {
        ImGui::Begin("Empty Node");
        ImGui::Button("Button");
        ImGui::End();

        //ImGui::ShowDemoWindow();
    }
};

class PrintNode : public VScritImgui::Layer
{
public:
    virtual void OnAttach() override
    {

    }

    virtual void OnDetach() override
    {

    }

    virtual void OnUpdate(float ts) override
    {

    }

    virtual void OnUIRender() override
    {
        ImGui::Begin("Print Node");
        ImGui::Button("Button");
        ImGui::End();

        ImGui::ShowDemoWindow();
    }
};

VScritImgui::Render* VScritImgui::CreateRender(int argc, char** argv)
{
    VScritImgui::Render* render = new VScritImgui::Render();
    render->PushLayer<VSNode>();
    render->PushLayer<PrintNode>();
    render->PushLayer<AddNode>();
    render->PushLayer<InputNode>();

    // render->SetMenuBarCallback([render]()
    // {
    //     std::cout << "This got called!" << std::endl;
    //     if (ImGui::BeginMenu("File"))
    //     {
    //         if (ImGui::MenuItem("Exit"))
    //             render->Close();
    //         ImGui::EndMenu();
    //     }

    // });

    return render;
}

int main(int argc, char** argv) {
    static bool started = false;
    if(!started)
    {
        VScritImgui::Render* render = VScritImgui::CreateRender(argc, argv);
        started = true;
        render->Run();
        delete render;
    }
    return 0;
}


#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "textworker.h"

#include <QFileDialog>
#include <QMessageBox>
#include <QFile>
#include <QThread>
#include <QFile>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->treeWidget->setHeaderLabels({"Имя", "Путь"});
    ui->treeWidget->setColumnWidth(0, 250);

    connect(ui->treeWidget, &QTreeWidget::itemChanged,
            this, &MainWindow::onItemChanged);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButtonBrowse_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(this,
                                                    tr("Choose folder with input files"),
                                                    QString(),
                                                    QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);

    if (!dir.isEmpty()) {
        ui->lineEditBrowse->setText(dir);
        viewTreeFolder();
    }
}

void MainWindow::viewTreeFolder() {
    ui->treeWidget->clear();

    QString rootPath = ui->lineEditBrowse->text();
    QDir dir(rootPath);
    if (!dir.exists()) {
        qDebug() << "Нет такой папки:" << rootPath;
        return;
    }

    // Корневой элемент
    QTreeWidgetItem *root = new QTreeWidgetItem(ui->treeWidget);
    root->setText(0, dir.dirName().isEmpty() ? rootPath : dir.dirName());
    root->setText(1, rootPath);
    root->setCheckState(0, Qt::Checked);
    root->setIcon(0, QIcon(":/icons/folder.png"));

    // Добавляем содержимое
    addFolderItems(root, rootPath);

    ui->treeWidget->addTopLevelItem(root);
    root->setExpanded(true);
}

void MainWindow::addFolderItems(QTreeWidgetItem *parent, const QString &path) {
    QDir dir(path);
    QFileInfoList entries = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);

    for (const QFileInfo &entry : entries) {
        QTreeWidgetItem *item = new QTreeWidgetItem();
        item->setText(0, entry.fileName());
        item->setText(1, entry.absoluteFilePath());
        item->setCheckState(0, Qt::Checked);

        if (entry.isDir()) {
            item->setIcon(0, QIcon(":/icons/folder.png"));
            parent->addChild(item);
            addFolderItems(item, entry.absoluteFilePath());
        } else {
            item->setIcon(0, QIcon(":/icons/file.png"));
            parent->addChild(item);
        }
    }
}

void MainWindow::onItemChanged(QTreeWidgetItem *item){
    Qt::CheckState state = item->checkState(0);

    for (int i = 0; i < item->childCount(); i++) {
        QTreeWidgetItem *child = item->child(i);
        child->setCheckState(0, state);
    }
}

void MainWindow::collectChecked(QTreeWidgetItem *item, QStringList &result)
{
    if (item->checkState(0) == Qt::Checked) {
        // Берём путь (во второй колонке)
        result << item->text(1);
    }

    for (int i = 0; i < item->childCount(); i++) {
        collectChecked(item->child(i), result);
    }
}

QStringList MainWindow::getCheckedFiles()
{
    QStringList result;

    for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) {
        QTreeWidgetItem *root = ui->treeWidget->topLevelItem(i);
        collectChecked(root, result);
    }

    return result;
}

void MainWindow::on_pushButtonStart_clicked()
{
    ui->plainTextEdit->clear();

    if(ui->lineEditBrowse->text().trimmed().isEmpty()){
        QMessageBox::warning(this, "Ошибка", "Выберите папку!");
        return;
    }

    QStringList checkedFiles = getCheckedFiles();

    QThread *thread = new QThread;
    TextWorker *worker = new TextWorker();

    QString outputFilePath = "plaintext.txt";

    worker->moveToThread(thread);

    connect(thread, &QThread::started, worker, [=](){
        worker->runWriteTextInFile(outputFilePath, checkedFiles);
    });

    connect(worker, &TextWorker::editPlainText, this, [=](const QString &text){
        ui->plainTextEdit->appendPlainText(text);
    });

    connect(worker, &TextWorker::error, this, [=](const QString &message){
        QMessageBox::warning(this, "Ошибка", message);
    });

    connect(worker, &TextWorker::finished, thread, &QThread::quit);
    connect(worker, &TextWorker::finished, worker, &QObject::deleteLater);
    connect(thread, &QThread::finished, thread, &QObject::deleteLater);

    thread->start();
}


// Name - Akshit Chordia
// PRN - 24070123008
// Batch - EnTC - A1

#include <iostream>
using namespace std;

int main() {
    int a = 2;
    bool b = true;
    double c = 10.5;
    float d = 23.0;

    int* aptr;
    bool* bptr;
    double* cptr;
    float* dptr;

    cout<<"Data type: int."<<endl;
    cout << "Value of a: " << a << endl;
    aptr = &a;
    cout << "Initial address of a: " << aptr << endl;
    aptr++;
    cout << "Incremented address of a: " << aptr << endl << endl;

     cout<<"Data type: bool."<<endl;
    cout << "Value of b: " << b << endl;
    bptr = &b;
    cout << "Initial address of b: " << *bptr << endl;
    bptr++;
    cout << "Incremented address of b: " << *bptr << endl << endl;

     cout<<"Data type: double"<<endl;
    cout << "Value of c: " << c << endl;
    cptr = &c;
    cout << "Initial address of c: " << cptr << endl;
    cptr++;
    cout << "Incremented address of c: " << cptr << endl << endl;

    cout<<"Data type: float."<<endl;
    cout << "Value of d: " << d << endl;
    dptr = &d;
    cout << "Initial address of d: " << dptr << endl;
    dptr++;
    cout << "Incremented address of d: " << dptr << endl << endl;

    return 0;
}

/*Output:-
Data type: int.
Value of a: 2
Initial address of a: 0x7ffcb3bbb96c
Incremented address of a: 0x7ffcb3bbb970

Data type: bool.
Value of b: 1
Initial address of b: 1
Incremented address of b: 2

Data type: double
Value of c: 10.5
Initial address of c: 0x7ffcb3bbb960
Incremented address of c: 0x7ffcb3bbb968

Data type: float.
Value of d: 23
Initial address of d: 0x7ffcb3bbb95c
Incremented address of d: 0x7ffcb3bbb960
*/


/*
 * MIT License
 *
 * Copyright (c) 2025 Meher V.R. Malladi.
 *
 * 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.
 */

#include "node.hpp"
#include "rko_lio/core/profiler.hpp"
#include "rko_lio/ros_utils/rosbag_utils.hpp"
// other
#include <std_msgs/msg/float32_multi_array.hpp>

namespace {
template <typename T>
std::shared_ptr<T> deserialize_next_msg(const rclcpp::SerializedMessage& serialized_msg) {
  const auto msg = std::make_shared<T>();
  const rclcpp::Serialization<T> serializer;
  serializer.deserialize_message(&serialized_msg, msg.get());
  return msg;
}

using BagProgressPublisher = rclcpp::Publisher<std_msgs::msg::Float32MultiArray>;
void publish_bag_progress(const BagProgressPublisher::SharedPtr& publisher,
                          const size_t processed_bag_msgs,
                          const size_t total_bag_msgs) {
  if (total_bag_msgs == 0) {
    return;
  }
  static const auto start_time = std::chrono::steady_clock::now();
  const auto now = std::chrono::steady_clock::now();
  const float elapsed_seconds = std::chrono::duration<float>(now - start_time).count();

  const float percent_complete = 100.0F * processed_bag_msgs / total_bag_msgs;
  const float avg_time_per_msg = (processed_bag_msgs > 0) ? elapsed_seconds / processed_bag_msgs : 0.0F;
  const float seconds_remaining = avg_time_per_msg * (total_bag_msgs - processed_bag_msgs);

  std_msgs::msg::Float32MultiArray progress_msg;
  progress_msg.data.resize(2);
  progress_msg.data[0] = percent_complete;
  progress_msg.data[1] = seconds_remaining;

  publisher->publish(progress_msg);
}
} // namespace

namespace rko_lio::ros {
class OfflineNode : public Node {
public:
  std::unique_ptr<ros_utils::BufferableBag> bag;

  BagProgressPublisher::SharedPtr bag_progress_publisher;

  float total_bag_msgs = 0;
  float processed_bag_msgs = 0;

  explicit OfflineNode(const rclcpp::NodeOptions& options) : Node("rko_lio_offline_node", options) {
    // increase the lidar buffer limit because we're offline
    max_lidar_buffer_size = 100;
    // bag reading
    const tf2::Duration skip_to_time = tf2::durationFromSec(node->declare_parameter<double>("skip_to_time", 0.0));
    bag = std::make_unique<ros_utils::BufferableBag>(node->declare_parameter<std::string>("bag_path"),
                                                     std::make_shared<ros_utils::BufferableBag::TFBridge>(node),
                                                     std::vector<std::string>{imu_topic, lidar_topic}, skip_to_time);
    total_bag_msgs = bag->message_count();
    bag_progress_publisher = node->create_publisher<std_msgs::msg::Float32MultiArray>("/rko_lio/bag_progress", 10);
  }

  void run() {
    while (rclcpp::ok() && !bag->finished()) {
      {
        if (lidar_buffer.size() >= 0.9 * max_lidar_buffer_size) {
          RCLCPP_WARN_STREAM_ONCE(node->get_logger(),
                                  "Lidar buffer size: " << lidar_buffer.size()
                                                        << ", max_lidar_buffer_size: " << max_lidar_buffer_size
                                                        << ", throttling the bag reading thread as it's too fast.\n");
          // this is a hack. can be improved
          std::this_thread::sleep_for(std::chrono::milliseconds(50));
          continue;
        }
      }
      const rosbag2_storage::SerializedBagMessage serialized_bag_msg = bag->PopNextMessage();
      const auto& topic_name = serialized_bag_msg.topic_name;
      const rclcpp::SerializedMessage serialized_msg(*serialized_bag_msg.serialized_data);

      // check the topic and call the appropriate callback
      if (topic_name == imu_topic) {
        const auto& imu_msg = deserialize_next_msg<sensor_msgs::msg::Imu>(serialized_msg);
        imu_callback(imu_msg);
      } else if (topic_name == lidar_topic) {
        const auto& lidar_msg = deserialize_next_msg<sensor_msgs::msg::PointCloud2>(serialized_msg);
        lidar_callback(lidar_msg);
      }


#include <iostream>
#include <fstream>
#include <windows.h>
#include <sstream>
using namespace std;

class Account{
private:
string AccountNo, Password;
int Balance;
public:
Account():AccountNo(""), Password(""),Balance(0){}

setAccountNo(string id){
AccountNo = id;
}

setPassword(string pw){
 Password = pw;
}

setBalance(int balance){
 Balance = balance;
}

string getAccountNo(){
return AccountNo;
}

string getPassword(){
 return Password;
}

int getBalance(){
 return Balance;
}
};

openAccount(Account user){
system("cls");
string id, pw;

cout<<"\tEnter Account No: ";
cin>>id;
user.setAccountNo(id);

 cout<<"\tEnter A Strong Password: ";
 cin>>pw;
 user.setPassword(pw);

 user.setBalance(0);

 ofstream outfile("D:/Account.txt", ios::app);
 if(!outfile){
cout<<"\tError: File Can't Open!"<<endl;
 }
 else{
outfile<<"\t"<<user.getAccountNo()<<" : "<<user.getPassword()<<" : "<<user.getBalance()<<endl<<endl;
cout<<"\tAccount Created Successfuly!"<<endl;
 }
 outfile.close();
Sleep(5000);
}

addCash(){
system("cls");
string id;
cout<<"\tEnter Account No: ";
cin>>id;

ifstream infile("D:/Account.txt");
ofstream outfile("D:/Account Temp.txt");
if(!infile || !outfile){
cout<<"\tError: File Can't Open!"<<endl;
}

string line;
bool found = false;

while(getline(infile, line)){
stringstream ss;
ss<<line;
string userID, userPW;
int userBalance;
char delimiter;

ss>>userID>>delimiter>>userPW>>delimiter>>userBalance;
if(id == userID){
found = true;
int cash;
cout<<"\tEnter Cash: ";
cin>>cash;

int newBalance = userBalance + cash;
userBalance = newBalance;
outfile<<"\t"<<userID<<" : "<<userPW<<" : "<<userBalance<<endl;
cout<<"\tNew Balance Is: "<<userBalance<<endl;
}
else{
outfile<<line<<endl;
}
}
if(!found){
cout<<"\tEnter Valid Account No!"<<endl;
}
outfile.close();
infile.close();
remove("D:/Account.txt");
rename("D:/Account Temp.txt", "D:/Account.txt");
Sleep(5000);
}

withdraw(){
string id, pw;
cout<<"\tEnter Account No: ";
cin>>id;

cout<<"\tEnter Password: ";
cin>>pw;
ifstream infile("D:/Account.txt");
ofstream outfile("D:/Account Temp.txt");
if(!infile || !outfile){
 cout<<"\tError: File Can't Open!"<<endl;
}

string line;
bool found = false;
while(getline(infile,line)){
stringstream ss;
ss<<line;
string userID, userPW;
int userBalance;
char delimiter;

ss>>userID>>delimiter>>userPW>>delimiter>>userBalance;

if(id==userID && pw == userPW){
found = true;
int cash;
cout<<"\tEnter Cash: ";
cin>>cash;
if(cash <= userBalance){
int newBalance = userBalance - cash;
userBalance = newBalance;
outfile<<"\t"<<userID<<" : "<<userPW<<" : "<<userBalance<<endl;
cout<<"\tTransaction Was Successful!"<<endl;
cout<<"\tRemaining Balance: "<<userBalance<<endl;
}
else{
cout<<"\tLow Balance!"<<endl;
outfile<<"\t"<<userID<<" : "<<userPW<<" : "<<userBalance<<endl;
}
}
else{
outfile<<line<<endl;
}
}
if(!found){
cout<<"\tInvalid Account No or Password!"<<endl;
}
outfile.close();
infile.close();
remove("D:/Account.txt");
rename("D:/Account Temp.txt", "D:/Account.txt");
Sleep(5000);
}

int main(){
Account user;

bool exit = false;
while(!exit){
system("cls");
int val;
cout<<"\tWelcome To Bank Account Management System"<<endl;
cout<<"\t*****************************************"<<endl;
cout<<"\t1.Open New Account."<<endl;
cout<<"\t2.Add Cash."<<endl;
cout<<"\t3.Withdraw Cash."<<endl;
cout<<"\t4.Exit."<<endl;
cout<<"\tEnter Your Choice: ";
cin>>val;

if(val==1){
openAccount(user);
}

else if(val==2){
addCash();
}
else if(val==3){
withdraw();
}
else if(val==4){
system("cls");
exit = true;
cout<<"\tGood Luck!"<<endl;
Sleep(2000);
}
Sleep(3000);
}
}