//! > Test expansion of a simple starknet contract with ownable component.

//! > test_runner_name
ExpandContractFromCrateTestRunner(expect_diagnostics: false)

//! > contract_file_name
cairo_level_tests/contracts/upgradable_counter.cairo

//! > generated_cairo_code
#[starknet::interface]
trait ICounterContract<TContractState> {
    fn increase_counter(ref self: TContractState, amount: u128);
    fn decrease_counter(ref self: TContractState, amount: u128);
    fn get_counter(self: @TContractState) -> u128;
}

#[starknet::contract]
mod counter_contract {
    use starknet::storage::{StoragePointerWriteAccess, StoragePointerReadAccess};
    use crate::components::upgradable::upgradable as upgradable_comp;
    use crate::components::ownable::ownable as ownable_comp;

    #[storage]
    struct Storage {
        counter: u128,
        #[substorage(v0)]
        upgradable: upgradable_comp::Storage,
        #[substorage(v0)]
        ownable: ownable_comp::Storage,
    }

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        CounterIncreased: CounterIncreased,
        CounterDecreased: CounterDecreased,
        UpgradableEvent: upgradable_comp::Event,
        OwnableEvent: ownable_comp::Event,
    }

    #[derive(Drop, starknet::Event)]
    struct CounterIncreased {
        amount: u128,
    }

    #[derive(Drop, starknet::Event)]
    struct CounterDecreased {
        amount: u128,
    }

    #[constructor]
    fn constructor(ref self: ContractState, initial_counter: u128) {
        self.counter.write(initial_counter);
    }

    #[abi(embed_v0)]
    impl CounterContract of super::ICounterContract<ContractState> {
        fn get_counter(self: @ContractState) -> u128 {
            self.counter.read()
        }

        fn increase_counter(ref self: ContractState, amount: u128) {
            let current = self.counter.read();
            self.counter.write(current + amount);
            self.emit(CounterIncreased { amount });
        }

        fn decrease_counter(ref self: ContractState, amount: u128) {
            let current = self.counter.read();
            self.counter.write(current - amount);
            self.emit(CounterDecreased { amount });
        }
    }

    #[abi(embed_v0)]
    impl Upgradable = upgradable_comp::UpgradableImpl<ContractState>;



#[derive(Drop, Copy)]
#[doc(hidden)]
struct StorageStorageBase {
    counter: starknet::storage::StorageBase<u128>,
        #[substorage(v0)]
    upgradable: starknet::storage::FlattenedStorage<upgradable_comp::Storage>,
        #[substorage(v0)]
    ownable: starknet::storage::FlattenedStorage<ownable_comp::Storage>,
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        let __counter_value__ = starknet::storage::StorageBase {__base_address__: selector!("counter")};
        let __upgradable_value__ = starknet::storage::FlattenedStorage {};
        let __ownable_value__ = starknet::storage::FlattenedStorage {};
        StorageStorageBase {
           counter: __counter_value__,
           upgradable: __upgradable_value__,
           ownable: __ownable_value__,
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
struct StorageStorageBaseMut {
    counter: starknet::storage::StorageBase<starknet::storage::Mutable::<u128>>,
        #[substorage(v0)]
    upgradable: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<upgradable_comp::Storage>>,
        #[substorage(v0)]
    ownable: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<ownable_comp::Storage>>,
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        let __counter_value__ = starknet::storage::StorageBase {__base_address__: selector!("counter")};
        let __upgradable_value__ = starknet::storage::FlattenedStorage {};
        let __ownable_value__ = starknet::storage::FlattenedStorage {};
        StorageStorageBaseMut {
           counter: __counter_value__,
           upgradable: __upgradable_value__,
           ownable: __ownable_value__,
        }
    }
}

pub struct ContractState {
        #[substorage(v0)]
         upgradable: upgradable_comp::ComponentState<ContractState>,
        #[substorage(v0)]
         ownable: ownable_comp::ComponentState<ContractState>,
}

impl ContractStateDrop of Drop<ContractState> {}
 
impl ContractStateDeref of core::ops::SnapshotDeref<ContractState> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn snapshot_deref(self: @ContractState) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ContractStateDerefMut of core::ops::DerefMut<ContractState> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ContractState) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_contract_state() -> ContractState {
    ContractState {
            upgradable: upgradable_comp::unsafe_new_component_state::<ContractState>(),
            ownable: ownable_comp::unsafe_new_component_state::<ContractState>(),
    }
}

// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;

#[doc(hidden)]
#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)]
fn __wrapper__constructor(mut data: Span::<felt252>) -> Span::<felt252> {
    core::internal::require_implicit::<System>();
    core::internal::revoke_ap_tracking();
    core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas');
    let __arg_initial_counter = core::option::OptionTraitImpl::expect(
        core::serde::Serde::<u128>::deserialize(ref data),
        'Failed to deserialize param #1'
    );
    assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments');
    core::option::OptionTraitImpl::expect(
        core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas',
    );
    let mut contract_state = unsafe_new_contract_state();
    constructor(ref contract_state, __arg_initial_counter);
    let mut arr = ArrayTrait::new();
    // References.
    // Result.
    core::array::ArrayTrait::span(@arr)
}

#[doc(hidden)]
#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)]
fn __wrapper__CounterContract__get_counter(mut data: Span::<felt252>) -> Span::<felt252> {
    core::internal::require_implicit::<System>();
    core::internal::revoke_ap_tracking();
    core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas');
    
    assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments');
    core::option::OptionTraitImpl::expect(
        core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas',
    );
    let mut contract_state = unsafe_new_contract_state();
    let res = CounterContract::get_counter(@contract_state, );
    let mut arr = ArrayTrait::new();
    // References.
    // Result.
    core::serde::Serde::<u128>::serialize(@res, ref arr);
    core::array::ArrayTrait::span(@arr)
}

#[doc(hidden)]
#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)]
fn __wrapper__CounterContract__increase_counter(mut data: Span::<felt252>) -> Span::<felt252> {
    core::internal::require_implicit::<System>();
    core::internal::revoke_ap_tracking();
    core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas');
    let __arg_amount = core::option::OptionTraitImpl::expect(
        core::serde::Serde::<u128>::deserialize(ref data),
        'Failed to deserialize param #1'
    );
    assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments');
    core::option::OptionTraitImpl::expect(
        core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas',
    );
    let mut contract_state = unsafe_new_contract_state();
    CounterContract::increase_counter(ref contract_state, __arg_amount);
    let mut arr = ArrayTrait::new();
    // References.
    // Result.
    core::array::ArrayTrait::span(@arr)
}

#[doc(hidden)]
#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)]
fn __wrapper__CounterContract__decrease_counter(mut data: Span::<felt252>) -> Span::<felt252> {
    core::internal::require_implicit::<System>();
    core::internal::revoke_ap_tracking();
    core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas');
    let __arg_amount = core::option::OptionTraitImpl::expect(
        core::serde::Serde::<u128>::deserialize(ref data),
        'Failed to deserialize param #1'
    );
    assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments');
    core::option::OptionTraitImpl::expect(
        core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas',
    );
    let mut contract_state = unsafe_new_contract_state();
    CounterContract::decrease_counter(ref contract_state, __arg_amount);
    let mut arr = ArrayTrait::new();
    // References.
    // Result.
    core::array::ArrayTrait::span(@arr)
}

impl ContractStateUpgradableImpl of
    upgradable_comp::UnsafeNewContractStateTraitForUpgradableImpl<ContractState> {
    fn unsafe_new_contract_state() -> ContractState {
        unsafe_new_contract_state()
    }
}

pub mod __external {
    pub use super::__wrapper__CounterContract__get_counter as get_counter;
    pub use super::__wrapper__CounterContract__increase_counter as increase_counter;
    pub use super::__wrapper__CounterContract__decrease_counter as decrease_counter;
}
pub mod __l1_handler {
}
pub mod __constructor {
    pub use super::__wrapper__constructor as constructor;
}
    impl ContractStateEventEmitter of starknet::event::EventEmitter<
        ContractState, Event
    > {
        fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(
            ref self: ContractState, event: S
        ) {
            let event: Event = core::traits::Into::into(event);
            let mut keys = Default::<core::array::Array>::default();
            let mut data = Default::<core::array::Array>::default();
            starknet::Event::append_keys_and_data(@event, ref keys, ref data);
            starknet::SyscallResultTrait::unwrap_syscall(
                starknet::syscalls::emit_event_syscall(
                    core::array::ArrayTrait::span(@keys),
                    core::array::ArrayTrait::span(@data),
                )
            )
        }
    }

impl HasComponentImpl_upgradable_comp of upgradable_comp::HasComponent<ContractState> {
    fn get_component(self: @ContractState) -> @upgradable_comp::ComponentState<ContractState> {
                 @upgradable_comp::unsafe_new_component_state::<ContractState>()
    }
    fn get_component_mut(ref self: ContractState) -> upgradable_comp::ComponentState<ContractState> {
        upgradable_comp::unsafe_new_component_state::<ContractState>()
    }
    fn get_contract(self: @upgradable_comp::ComponentState<ContractState>) -> @ContractState {
        @unsafe_new_contract_state()
    }
    fn get_contract_mut(ref self: upgradable_comp::ComponentState<ContractState>) -> ContractState {
        unsafe_new_contract_state()
    }
    fn emit<S, impl IntoImp: core::traits::Into<S, upgradable_comp::Event>>(ref self: upgradable_comp::ComponentState<ContractState>, event: S) {
        let event: upgradable_comp::Event = core::traits::Into::into(event);
        let mut contract = upgradable_comp::HasComponent::get_contract_mut(ref self);
        ContractStateEventEmitter::emit(ref contract, Event::UpgradableEvent(event));
    }
}
impl HasComponentImpl_ownable_comp of ownable_comp::HasComponent<ContractState> {
    fn get_component(self: @ContractState) -> @ownable_comp::ComponentState<ContractState> {
                 @ownable_comp::unsafe_new_component_state::<ContractState>()
    }
    fn get_component_mut(ref self: ContractState) -> ownable_comp::ComponentState<ContractState> {
        ownable_comp::unsafe_new_component_state::<ContractState>()
    }
    fn get_contract(self: @ownable_comp::ComponentState<ContractState>) -> @ContractState {
        @unsafe_new_contract_state()
    }
    fn get_contract_mut(ref self: ownable_comp::ComponentState<ContractState>) -> ContractState {
        unsafe_new_contract_state()
    }
    fn emit<S, impl IntoImp: core::traits::Into<S, ownable_comp::Event>>(ref self: ownable_comp::ComponentState<ContractState>, event: S) {
        let event: ownable_comp::Event = core::traits::Into::into(event);
        let mut contract = ownable_comp::HasComponent::get_contract_mut(ref self);
        ContractStateEventEmitter::emit(ref contract, Event::OwnableEvent(event));
    }
}
impl EventDrop of core::traits::Drop::<Event>;
impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
            Event::CounterIncreased(val) => {
                core::array::ArrayTrait::append(ref keys, selector!("CounterIncreased"));
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
            Event::CounterDecreased(val) => {
                core::array::ArrayTrait::append(ref keys, selector!("CounterDecreased"));
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
            Event::UpgradableEvent(val) => {
                core::array::ArrayTrait::append(ref keys, selector!("UpgradableEvent"));
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
            Event::OwnableEvent(val) => {
                core::array::ArrayTrait::append(ref keys, selector!("OwnableEvent"));
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        if __selector__ == selector!("CounterIncreased") {
                let val = starknet::Event::deserialize(
                    ref keys, ref data
                )?;
                return Option::Some(Event::CounterIncreased(val));
        }
        if __selector__ == selector!("CounterDecreased") {
                let val = starknet::Event::deserialize(
                    ref keys, ref data
                )?;
                return Option::Some(Event::CounterDecreased(val));
        }
        if __selector__ == selector!("UpgradableEvent") {
                let val = starknet::Event::deserialize(
                    ref keys, ref data
                )?;
                return Option::Some(Event::UpgradableEvent(val));
        }
        if __selector__ == selector!("OwnableEvent") {
                let val = starknet::Event::deserialize(
                    ref keys, ref data
                )?;
                return Option::Some(Event::OwnableEvent(val));
        }
        Option::None
    }
}
impl EventCounterIncreasedIntoEvent of Into<CounterIncreased, Event> {
    fn into(self: CounterIncreased) -> Event {
        Event::CounterIncreased(self)
    }
}
impl EventCounterDecreasedIntoEvent of Into<CounterDecreased, Event> {
    fn into(self: CounterDecreased) -> Event {
        Event::CounterDecreased(self)
    }
}
impl EventUpgradableEventIntoEvent of Into<upgradable_comp::Event, Event> {
    fn into(self: upgradable_comp::Event) -> Event {
        Event::UpgradableEvent(self)
    }
}
impl EventOwnableEventIntoEvent of Into<ownable_comp::Event, Event> {
    fn into(self: ownable_comp::Event) -> Event {
        Event::OwnableEvent(self)
    }
}
impl CounterIncreasedDrop of core::traits::Drop::<CounterIncreased>;
impl CounterIncreasedIsEvent of starknet::Event<CounterIncreased> {
    fn append_keys_and_data(
        self: @CounterIncreased, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
            core::serde::Serde::serialize(self.amount, ref data);
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<CounterIncreased> {
                let amount = core::serde::Serde::deserialize(
                    ref data
                )?;
        Option::Some(CounterIncreased {amount, })
    }
}
impl CounterDecreasedDrop of core::traits::Drop::<CounterDecreased>;
impl CounterDecreasedIsEvent of starknet::Event<CounterDecreased> {
    fn append_keys_and_data(
        self: @CounterDecreased, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
            core::serde::Serde::serialize(self.amount, ref data);
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<CounterDecreased> {
                let amount = core::serde::Serde::deserialize(
                    ref data
                )?;
        Option::Some(CounterDecreased {amount, })
    }
}
impl StorageStorageBaseDrop of core::traits::Drop::<StorageStorageBase>;
impl StorageStorageBaseCopy of core::traits::Copy::<StorageStorageBase>;
impl StorageStorageBaseMutDrop of core::traits::Drop::<StorageStorageBaseMut>;
impl StorageStorageBaseMutCopy of core::traits::Copy::<StorageStorageBaseMut>;
}
trait ICounterContractDispatcherTrait<T> {
    fn increase_counter(self: T, amount: u128);
    fn decrease_counter(self: T, amount: u128);
    fn get_counter(self: T) -> u128;
}

#[derive(Copy, Drop, starknet::Store, Serde)]
struct ICounterContractDispatcher {
    pub contract_address: starknet::ContractAddress,
}

impl ICounterContractDispatcherImpl of ICounterContractDispatcherTrait<ICounterContractDispatcher> {
    fn increase_counter(self: ICounterContractDispatcher, amount: u128) {
        let mut __calldata__ = core::traits::Default::default();
        core::serde::Serde::<u128>::serialize(@amount, ref __calldata__);

        let mut __dispatcher_return_data__ = starknet::syscalls::call_contract_syscall(
            self.contract_address,
            selector!("increase_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = starknet::SyscallResultTrait::unwrap_syscall(__dispatcher_return_data__);
        ()
    }
    fn decrease_counter(self: ICounterContractDispatcher, amount: u128) {
        let mut __calldata__ = core::traits::Default::default();
        core::serde::Serde::<u128>::serialize(@amount, ref __calldata__);

        let mut __dispatcher_return_data__ = starknet::syscalls::call_contract_syscall(
            self.contract_address,
            selector!("decrease_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = starknet::SyscallResultTrait::unwrap_syscall(__dispatcher_return_data__);
        ()
    }
    fn get_counter(self: ICounterContractDispatcher) -> u128 {
        let mut __calldata__ = core::traits::Default::default();

        let mut __dispatcher_return_data__ = starknet::syscalls::call_contract_syscall(
            self.contract_address,
            selector!("get_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = starknet::SyscallResultTrait::unwrap_syscall(__dispatcher_return_data__);
        core::option::OptionTrait::expect(
            core::serde::Serde::<u128>::deserialize(ref __dispatcher_return_data__),
            'Returned data too short',
        )
    }

}

#[derive(Copy, Drop, starknet::Store, Serde)]
struct ICounterContractLibraryDispatcher {
    pub class_hash: starknet::ClassHash,
}

impl ICounterContractLibraryDispatcherImpl of ICounterContractDispatcherTrait<ICounterContractLibraryDispatcher> {
    fn increase_counter(self: ICounterContractLibraryDispatcher, amount: u128) {
        let mut __calldata__ = core::traits::Default::default();
        core::serde::Serde::<u128>::serialize(@amount, ref __calldata__);

        let mut __dispatcher_return_data__ = starknet::syscalls::library_call_syscall(
            self.class_hash,
            selector!("increase_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = starknet::SyscallResultTrait::unwrap_syscall(__dispatcher_return_data__);
        ()
    }
    fn decrease_counter(self: ICounterContractLibraryDispatcher, amount: u128) {
        let mut __calldata__ = core::traits::Default::default();
        core::serde::Serde::<u128>::serialize(@amount, ref __calldata__);

        let mut __dispatcher_return_data__ = starknet::syscalls::library_call_syscall(
            self.class_hash,
            selector!("decrease_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = starknet::SyscallResultTrait::unwrap_syscall(__dispatcher_return_data__);
        ()
    }
    fn get_counter(self: ICounterContractLibraryDispatcher) -> u128 {
        let mut __calldata__ = core::traits::Default::default();

        let mut __dispatcher_return_data__ = starknet::syscalls::library_call_syscall(
            self.class_hash,
            selector!("get_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = starknet::SyscallResultTrait::unwrap_syscall(__dispatcher_return_data__);
        core::option::OptionTrait::expect(
            core::serde::Serde::<u128>::deserialize(ref __dispatcher_return_data__),
            'Returned data too short',
        )
    }

}

trait ICounterContractSafeDispatcherTrait<T> {
    #[unstable(feature: "safe_dispatcher")]
    fn increase_counter(self: T, amount: u128) -> starknet::SyscallResult<()>;
    #[unstable(feature: "safe_dispatcher")]
    fn decrease_counter(self: T, amount: u128) -> starknet::SyscallResult<()>;
    #[unstable(feature: "safe_dispatcher")]
    fn get_counter(self: T) -> starknet::SyscallResult<u128>;
}

#[derive(Copy, Drop, starknet::Store, Serde)]
struct ICounterContractSafeLibraryDispatcher {
    pub class_hash: starknet::ClassHash,
}

impl ICounterContractSafeLibraryDispatcherImpl of ICounterContractSafeDispatcherTrait<ICounterContractSafeLibraryDispatcher> {
    fn increase_counter(self: ICounterContractSafeLibraryDispatcher, amount: u128) -> starknet::SyscallResult<()> {
        let mut __calldata__ = core::traits::Default::default();
        core::serde::Serde::<u128>::serialize(@amount, ref __calldata__);

        let mut __dispatcher_return_data__ = starknet::syscalls::library_call_syscall(
            self.class_hash,
            selector!("increase_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = __dispatcher_return_data__?;
        Result::Ok(())
    }
    fn decrease_counter(self: ICounterContractSafeLibraryDispatcher, amount: u128) -> starknet::SyscallResult<()> {
        let mut __calldata__ = core::traits::Default::default();
        core::serde::Serde::<u128>::serialize(@amount, ref __calldata__);

        let mut __dispatcher_return_data__ = starknet::syscalls::library_call_syscall(
            self.class_hash,
            selector!("decrease_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = __dispatcher_return_data__?;
        Result::Ok(())
    }
    fn get_counter(self: ICounterContractSafeLibraryDispatcher) -> starknet::SyscallResult<u128> {
        let mut __calldata__ = core::traits::Default::default();

        let mut __dispatcher_return_data__ = starknet::syscalls::library_call_syscall(
            self.class_hash,
            selector!("get_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = __dispatcher_return_data__?;
        Result::Ok(
            core::option::OptionTrait::expect(
                core::serde::Serde::<u128>::deserialize(ref __dispatcher_return_data__),
                'Returned data too short',
            )
        )
    }

}


#[derive(Copy, Drop, starknet::Store, Serde)]
struct ICounterContractSafeDispatcher {
    pub contract_address: starknet::ContractAddress,
}

impl ICounterContractSafeDispatcherImpl of ICounterContractSafeDispatcherTrait<ICounterContractSafeDispatcher> {
    fn increase_counter(self: ICounterContractSafeDispatcher, amount: u128) -> starknet::SyscallResult<()> {
        let mut __calldata__ = core::traits::Default::default();
        core::serde::Serde::<u128>::serialize(@amount, ref __calldata__);

        let mut __dispatcher_return_data__ = starknet::syscalls::call_contract_syscall(
            self.contract_address,
            selector!("increase_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = __dispatcher_return_data__?;
        Result::Ok(())
    }
    fn decrease_counter(self: ICounterContractSafeDispatcher, amount: u128) -> starknet::SyscallResult<()> {
        let mut __calldata__ = core::traits::Default::default();
        core::serde::Serde::<u128>::serialize(@amount, ref __calldata__);

        let mut __dispatcher_return_data__ = starknet::syscalls::call_contract_syscall(
            self.contract_address,
            selector!("decrease_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = __dispatcher_return_data__?;
        Result::Ok(())
    }
    fn get_counter(self: ICounterContractSafeDispatcher) -> starknet::SyscallResult<u128> {
        let mut __calldata__ = core::traits::Default::default();

        let mut __dispatcher_return_data__ = starknet::syscalls::call_contract_syscall(
            self.contract_address,
            selector!("get_counter"),
            core::array::ArrayTrait::span(@__calldata__),
        );
        let mut __dispatcher_return_data__ = __dispatcher_return_data__?;
        Result::Ok(
            core::option::OptionTrait::expect(
                core::serde::Serde::<u128>::deserialize(ref __dispatcher_return_data__),
                'Returned data too short',
            )
        )
    }

}
impl ICounterContractDispatcherCopy of core::traits::Copy::<ICounterContractDispatcher>;
impl ICounterContractDispatcherDrop of core::traits::Drop::<ICounterContractDispatcher>;
impl ICounterContractDispatcherSerde of core::serde::Serde::<ICounterContractDispatcher> {
    fn serialize(self: @ICounterContractDispatcher, ref output: core::array::Array<felt252>) {
        core::serde::Serde::serialize(self.contract_address, ref output)
    }
    fn deserialize(ref serialized: core::array::Span<felt252>) -> core::option::Option<ICounterContractDispatcher> {
        core::option::Option::Some(ICounterContractDispatcher {
            contract_address: core::serde::Serde::deserialize(ref serialized)?,
        })
    }
}
impl StoreICounterContractDispatcher of starknet::Store::<ICounterContractDispatcher> {
    fn read(address_domain: u32, base: starknet::storage_access::StorageBaseAddress) -> starknet::SyscallResult<ICounterContractDispatcher> {
        let contract_address = starknet::Store::<starknet::ContractAddress>::read(address_domain, base)?;
        starknet::SyscallResult::Ok(
            ICounterContractDispatcher {
                contract_address,
            }
        )
    }
    fn write(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, value: ICounterContractDispatcher) -> starknet::SyscallResult<()> {
        starknet::Store::<starknet::ContractAddress>::write(address_domain, base, value.contract_address)?;
        starknet::SyscallResult::Ok(())
    }
    fn read_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8) -> starknet::SyscallResult<ICounterContractDispatcher> {
        let contract_address = starknet::Store::<starknet::ContractAddress>::read_at_offset(address_domain, base, offset)?;
        starknet::SyscallResult::Ok(
            ICounterContractDispatcher {
                contract_address,
            }
        )
    }
    #[inline(always)]
    fn write_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8, value: ICounterContractDispatcher) -> starknet::SyscallResult<()> {
        starknet::Store::<starknet::ContractAddress>::write_at_offset(address_domain, base, offset, value.contract_address)?;
        starknet::SyscallResult::Ok(())
    }
    #[inline(always)]
    fn size() -> u8 {
        starknet::Store::<starknet::ContractAddress>::size()
    }
}

#[derive(Drop, Copy)]
#[doc(hidden)]
struct ICounterContractDispatcherSubPointers {
    pub contract_address: starknet::storage::StoragePointer<starknet::ContractAddress>,
}
#[doc(hidden)]
impl ICounterContractDispatcherSubPointersImpl of starknet::storage::SubPointers<ICounterContractDispatcher> {
    type SubPointersType = ICounterContractDispatcherSubPointers;
    fn sub_pointers(self: starknet::storage::StoragePointer<ICounterContractDispatcher>) -> ICounterContractDispatcherSubPointers {
        let base_address = self.__storage_pointer_address__;
        let mut current_offset = self.__storage_pointer_offset__;
        let __contract_address_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
                ICounterContractDispatcherSubPointers {
           contract_address: __contract_address_value__,
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
struct ICounterContractDispatcherSubPointersMut {
    pub contract_address: starknet::storage::StoragePointer<starknet::storage::Mutable::<starknet::ContractAddress>>,
}
#[doc(hidden)]
impl ICounterContractDispatcherSubPointersMutImpl of starknet::storage::SubPointersMut<ICounterContractDispatcher> {
    type SubPointersType = ICounterContractDispatcherSubPointersMut;
    fn sub_pointers_mut(self: starknet::storage::StoragePointer<starknet::storage::Mutable::<ICounterContractDispatcher>>) -> ICounterContractDispatcherSubPointersMut {
        let base_address = self.__storage_pointer_address__;
        let mut current_offset = self.__storage_pointer_offset__;
        let __contract_address_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
                ICounterContractDispatcherSubPointersMut {
           contract_address: __contract_address_value__,
        }
    }
}
impl ICounterContractLibraryDispatcherCopy of core::traits::Copy::<ICounterContractLibraryDispatcher>;
impl ICounterContractLibraryDispatcherDrop of core::traits::Drop::<ICounterContractLibraryDispatcher>;
impl ICounterContractLibraryDispatcherSerde of core::serde::Serde::<ICounterContractLibraryDispatcher> {
    fn serialize(self: @ICounterContractLibraryDispatcher, ref output: core::array::Array<felt252>) {
        core::serde::Serde::serialize(self.class_hash, ref output)
    }
    fn deserialize(ref serialized: core::array::Span<felt252>) -> core::option::Option<ICounterContractLibraryDispatcher> {
        core::option::Option::Some(ICounterContractLibraryDispatcher {
            class_hash: core::serde::Serde::deserialize(ref serialized)?,
        })
    }
}
impl StoreICounterContractLibraryDispatcher of starknet::Store::<ICounterContractLibraryDispatcher> {
    fn read(address_domain: u32, base: starknet::storage_access::StorageBaseAddress) -> starknet::SyscallResult<ICounterContractLibraryDispatcher> {
        let class_hash = starknet::Store::<starknet::ClassHash>::read(address_domain, base)?;
        starknet::SyscallResult::Ok(
            ICounterContractLibraryDispatcher {
                class_hash,
            }
        )
    }
    fn write(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, value: ICounterContractLibraryDispatcher) -> starknet::SyscallResult<()> {
        starknet::Store::<starknet::ClassHash>::write(address_domain, base, value.class_hash)?;
        starknet::SyscallResult::Ok(())
    }
    fn read_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8) -> starknet::SyscallResult<ICounterContractLibraryDispatcher> {
        let class_hash = starknet::Store::<starknet::ClassHash>::read_at_offset(address_domain, base, offset)?;
        starknet::SyscallResult::Ok(
            ICounterContractLibraryDispatcher {
                class_hash,
            }
        )
    }
    #[inline(always)]
    fn write_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8, value: ICounterContractLibraryDispatcher) -> starknet::SyscallResult<()> {
        starknet::Store::<starknet::ClassHash>::write_at_offset(address_domain, base, offset, value.class_hash)?;
        starknet::SyscallResult::Ok(())
    }
    #[inline(always)]
    fn size() -> u8 {
        starknet::Store::<starknet::ClassHash>::size()
    }
}

#[derive(Drop, Copy)]
#[doc(hidden)]
struct ICounterContractLibraryDispatcherSubPointers {
    pub class_hash: starknet::storage::StoragePointer<starknet::ClassHash>,
}
#[doc(hidden)]
impl ICounterContractLibraryDispatcherSubPointersImpl of starknet::storage::SubPointers<ICounterContractLibraryDispatcher> {
    type SubPointersType = ICounterContractLibraryDispatcherSubPointers;
    fn sub_pointers(self: starknet::storage::StoragePointer<ICounterContractLibraryDispatcher>) -> ICounterContractLibraryDispatcherSubPointers {
        let base_address = self.__storage_pointer_address__;
        let mut current_offset = self.__storage_pointer_offset__;
        let __class_hash_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
                ICounterContractLibraryDispatcherSubPointers {
           class_hash: __class_hash_value__,
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
struct ICounterContractLibraryDispatcherSubPointersMut {
    pub class_hash: starknet::storage::StoragePointer<starknet::storage::Mutable::<starknet::ClassHash>>,
}
#[doc(hidden)]
impl ICounterContractLibraryDispatcherSubPointersMutImpl of starknet::storage::SubPointersMut<ICounterContractLibraryDispatcher> {
    type SubPointersType = ICounterContractLibraryDispatcherSubPointersMut;
    fn sub_pointers_mut(self: starknet::storage::StoragePointer<starknet::storage::Mutable::<ICounterContractLibraryDispatcher>>) -> ICounterContractLibraryDispatcherSubPointersMut {
        let base_address = self.__storage_pointer_address__;
        let mut current_offset = self.__storage_pointer_offset__;
        let __class_hash_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
                ICounterContractLibraryDispatcherSubPointersMut {
           class_hash: __class_hash_value__,
        }
    }
}
impl ICounterContractSafeLibraryDispatcherCopy of core::traits::Copy::<ICounterContractSafeLibraryDispatcher>;
impl ICounterContractSafeLibraryDispatcherDrop of core::traits::Drop::<ICounterContractSafeLibraryDispatcher>;
impl ICounterContractSafeLibraryDispatcherSerde of core::serde::Serde::<ICounterContractSafeLibraryDispatcher> {
    fn serialize(self: @ICounterContractSafeLibraryDispatcher, ref output: core::array::Array<felt252>) {
        core::serde::Serde::serialize(self.class_hash, ref output)
    }
    fn deserialize(ref serialized: core::array::Span<felt252>) -> core::option::Option<ICounterContractSafeLibraryDispatcher> {
        core::option::Option::Some(ICounterContractSafeLibraryDispatcher {
            class_hash: core::serde::Serde::deserialize(ref serialized)?,
        })
    }
}
impl StoreICounterContractSafeLibraryDispatcher of starknet::Store::<ICounterContractSafeLibraryDispatcher> {
    fn read(address_domain: u32, base: starknet::storage_access::StorageBaseAddress) -> starknet::SyscallResult<ICounterContractSafeLibraryDispatcher> {
        let class_hash = starknet::Store::<starknet::ClassHash>::read(address_domain, base)?;
        starknet::SyscallResult::Ok(
            ICounterContractSafeLibraryDispatcher {
                class_hash,
            }
        )
    }
    fn write(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, value: ICounterContractSafeLibraryDispatcher) -> starknet::SyscallResult<()> {
        starknet::Store::<starknet::ClassHash>::write(address_domain, base, value.class_hash)?;
        starknet::SyscallResult::Ok(())
    }
    fn read_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8) -> starknet::SyscallResult<ICounterContractSafeLibraryDispatcher> {
        let class_hash = starknet::Store::<starknet::ClassHash>::read_at_offset(address_domain, base, offset)?;
        starknet::SyscallResult::Ok(
            ICounterContractSafeLibraryDispatcher {
                class_hash,
            }
        )
    }
    #[inline(always)]
    fn write_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8, value: ICounterContractSafeLibraryDispatcher) -> starknet::SyscallResult<()> {
        starknet::Store::<starknet::ClassHash>::write_at_offset(address_domain, base, offset, value.class_hash)?;
        starknet::SyscallResult::Ok(())
    }
    #[inline(always)]
    fn size() -> u8 {
        starknet::Store::<starknet::ClassHash>::size()
    }
}

#[derive(Drop, Copy)]
#[doc(hidden)]
struct ICounterContractSafeLibraryDispatcherSubPointers {
    pub class_hash: starknet::storage::StoragePointer<starknet::ClassHash>,
}
#[doc(hidden)]
impl ICounterContractSafeLibraryDispatcherSubPointersImpl of starknet::storage::SubPointers<ICounterContractSafeLibraryDispatcher> {
    type SubPointersType = ICounterContractSafeLibraryDispatcherSubPointers;
    fn sub_pointers(self: starknet::storage::StoragePointer<ICounterContractSafeLibraryDispatcher>) -> ICounterContractSafeLibraryDispatcherSubPointers {
        let base_address = self.__storage_pointer_address__;
        let mut current_offset = self.__storage_pointer_offset__;
        let __class_hash_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
                ICounterContractSafeLibraryDispatcherSubPointers {
           class_hash: __class_hash_value__,
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
struct ICounterContractSafeLibraryDispatcherSubPointersMut {
    pub class_hash: starknet::storage::StoragePointer<starknet::storage::Mutable::<starknet::ClassHash>>,
}
#[doc(hidden)]
impl ICounterContractSafeLibraryDispatcherSubPointersMutImpl of starknet::storage::SubPointersMut<ICounterContractSafeLibraryDispatcher> {
    type SubPointersType = ICounterContractSafeLibraryDispatcherSubPointersMut;
    fn sub_pointers_mut(self: starknet::storage::StoragePointer<starknet::storage::Mutable::<ICounterContractSafeLibraryDispatcher>>) -> ICounterContractSafeLibraryDispatcherSubPointersMut {
        let base_address = self.__storage_pointer_address__;
        let mut current_offset = self.__storage_pointer_offset__;
        let __class_hash_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
                ICounterContractSafeLibraryDispatcherSubPointersMut {
           class_hash: __class_hash_value__,
        }
    }
}
impl ICounterContractSafeDispatcherCopy of core::traits::Copy::<ICounterContractSafeDispatcher>;
impl ICounterContractSafeDispatcherDrop of core::traits::Drop::<ICounterContractSafeDispatcher>;
impl ICounterContractSafeDispatcherSerde of core::serde::Serde::<ICounterContractSafeDispatcher> {
    fn serialize(self: @ICounterContractSafeDispatcher, ref output: core::array::Array<felt252>) {
        core::serde::Serde::serialize(self.contract_address, ref output)
    }
    fn deserialize(ref serialized: core::array::Span<felt252>) -> core::option::Option<ICounterContractSafeDispatcher> {
        core::option::Option::Some(ICounterContractSafeDispatcher {
            contract_address: core::serde::Serde::deserialize(ref serialized)?,
        })
    }
}
impl StoreICounterContractSafeDispatcher of starknet::Store::<ICounterContractSafeDispatcher> {
    fn read(address_domain: u32, base: starknet::storage_access::StorageBaseAddress) -> starknet::SyscallResult<ICounterContractSafeDispatcher> {
        let contract_address = starknet::Store::<starknet::ContractAddress>::read(address_domain, base)?;
        starknet::SyscallResult::Ok(
            ICounterContractSafeDispatcher {
                contract_address,
            }
        )
    }
    fn write(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, value: ICounterContractSafeDispatcher) -> starknet::SyscallResult<()> {
        starknet::Store::<starknet::ContractAddress>::write(address_domain, base, value.contract_address)?;
        starknet::SyscallResult::Ok(())
    }
    fn read_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8) -> starknet::SyscallResult<ICounterContractSafeDispatcher> {
        let contract_address = starknet::Store::<starknet::ContractAddress>::read_at_offset(address_domain, base, offset)?;
        starknet::SyscallResult::Ok(
            ICounterContractSafeDispatcher {
                contract_address,
            }
        )
    }
    #[inline(always)]
    fn write_at_offset(address_domain: u32, base: starknet::storage_access::StorageBaseAddress, offset: u8, value: ICounterContractSafeDispatcher) -> starknet::SyscallResult<()> {
        starknet::Store::<starknet::ContractAddress>::write_at_offset(address_domain, base, offset, value.contract_address)?;
        starknet::SyscallResult::Ok(())
    }
    #[inline(always)]
    fn size() -> u8 {
        starknet::Store::<starknet::ContractAddress>::size()
    }
}

#[derive(Drop, Copy)]
#[doc(hidden)]
struct ICounterContractSafeDispatcherSubPointers {
    pub contract_address: starknet::storage::StoragePointer<starknet::ContractAddress>,
}
#[doc(hidden)]
impl ICounterContractSafeDispatcherSubPointersImpl of starknet::storage::SubPointers<ICounterContractSafeDispatcher> {
    type SubPointersType = ICounterContractSafeDispatcherSubPointers;
    fn sub_pointers(self: starknet::storage::StoragePointer<ICounterContractSafeDispatcher>) -> ICounterContractSafeDispatcherSubPointers {
        let base_address = self.__storage_pointer_address__;
        let mut current_offset = self.__storage_pointer_offset__;
        let __contract_address_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
                ICounterContractSafeDispatcherSubPointers {
           contract_address: __contract_address_value__,
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
struct ICounterContractSafeDispatcherSubPointersMut {
    pub contract_address: starknet::storage::StoragePointer<starknet::storage::Mutable::<starknet::ContractAddress>>,
}
#[doc(hidden)]
impl ICounterContractSafeDispatcherSubPointersMutImpl of starknet::storage::SubPointersMut<ICounterContractSafeDispatcher> {
    type SubPointersType = ICounterContractSafeDispatcherSubPointersMut;
    fn sub_pointers_mut(self: starknet::storage::StoragePointer<starknet::storage::Mutable::<ICounterContractSafeDispatcher>>) -> ICounterContractSafeDispatcherSubPointersMut {
        let base_address = self.__storage_pointer_address__;
        let mut current_offset = self.__storage_pointer_offset__;
        let __contract_address_value__ = starknet::storage::StoragePointer {
            __storage_pointer_address__: base_address,
            __storage_pointer_offset__: current_offset,
        };
                ICounterContractSafeDispatcherSubPointersMut {
           contract_address: __contract_address_value__,
        }
    }
}
impl ICounterContractDispatcherSubPointersDrop of core::traits::Drop::<ICounterContractDispatcherSubPointers>;
impl ICounterContractDispatcherSubPointersCopy of core::traits::Copy::<ICounterContractDispatcherSubPointers>;
impl ICounterContractDispatcherSubPointersMutDrop of core::traits::Drop::<ICounterContractDispatcherSubPointersMut>;
impl ICounterContractDispatcherSubPointersMutCopy of core::traits::Copy::<ICounterContractDispatcherSubPointersMut>;
impl ICounterContractLibraryDispatcherSubPointersDrop of core::traits::Drop::<ICounterContractLibraryDispatcherSubPointers>;
impl ICounterContractLibraryDispatcherSubPointersCopy of core::traits::Copy::<ICounterContractLibraryDispatcherSubPointers>;
impl ICounterContractLibraryDispatcherSubPointersMutDrop of core::traits::Drop::<ICounterContractLibraryDispatcherSubPointersMut>;
impl ICounterContractLibraryDispatcherSubPointersMutCopy of core::traits::Copy::<ICounterContractLibraryDispatcherSubPointersMut>;
impl ICounterContractSafeLibraryDispatcherSubPointersDrop of core::traits::Drop::<ICounterContractSafeLibraryDispatcherSubPointers>;
impl ICounterContractSafeLibraryDispatcherSubPointersCopy of core::traits::Copy::<ICounterContractSafeLibraryDispatcherSubPointers>;
impl ICounterContractSafeLibraryDispatcherSubPointersMutDrop of core::traits::Drop::<ICounterContractSafeLibraryDispatcherSubPointersMut>;
impl ICounterContractSafeLibraryDispatcherSubPointersMutCopy of core::traits::Copy::<ICounterContractSafeLibraryDispatcherSubPointersMut>;
impl ICounterContractSafeDispatcherSubPointersDrop of core::traits::Drop::<ICounterContractSafeDispatcherSubPointers>;
impl ICounterContractSafeDispatcherSubPointersCopy of core::traits::Copy::<ICounterContractSafeDispatcherSubPointers>;
impl ICounterContractSafeDispatcherSubPointersMutDrop of core::traits::Drop::<ICounterContractSafeDispatcherSubPointersMut>;
impl ICounterContractSafeDispatcherSubPointersMutCopy of core::traits::Copy::<ICounterContractSafeDispatcherSubPointersMut>;

    use starknet::storage::{StoragePointerWriteAccess, StoragePointerReadAccess};
    use crate::components::upgradable::upgradable as upgradable_comp;
    use crate::components::ownable::ownable as ownable_comp;

    #[storage]
    struct Storage {
        counter: u128,
        #[substorage(v0)]
        upgradable: upgradable_comp::Storage,
        #[substorage(v0)]
        ownable: ownable_comp::Storage,
    }

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        CounterIncreased: CounterIncreased,
        CounterDecreased: CounterDecreased,
        UpgradableEvent: upgradable_comp::Event,
        OwnableEvent: ownable_comp::Event,
    }

    #[derive(Drop, starknet::Event)]
    struct CounterIncreased {
        amount: u128,
    }

    #[derive(Drop, starknet::Event)]
    struct CounterDecreased {
        amount: u128,
    }

    #[constructor]
    fn constructor(ref self: ContractState, initial_counter: u128) {
        self.counter.write(initial_counter);
    }

    #[abi(embed_v0)]
    impl CounterContract of super::ICounterContract<ContractState> {
        fn get_counter(self: @ContractState) -> u128 {
            self.counter.read()
        }

        fn increase_counter(ref self: ContractState, amount: u128) {
            let current = self.counter.read();
            self.counter.write(current + amount);
            self.emit(CounterIncreased { amount });
        }

        fn decrease_counter(ref self: ContractState, amount: u128) {
            let current = self.counter.read();
            self.counter.write(current - amount);
            self.emit(CounterDecreased { amount });
        }
    }

    #[abi(embed_v0)]
    impl Upgradable = upgradable_comp::UpgradableImpl<ContractState>;



#[derive(Drop, Copy)]
#[doc(hidden)]
struct StorageStorageBase {
    counter: starknet::storage::StorageBase<u128>,
        #[substorage(v0)]
    upgradable: starknet::storage::FlattenedStorage<upgradable_comp::Storage>,
        #[substorage(v0)]
    ownable: starknet::storage::FlattenedStorage<ownable_comp::Storage>,
}
#[doc(hidden)]
impl StorageStorageImpl of starknet::storage::StorageTrait<Storage> {
    type BaseType = StorageStorageBase;
    fn storage(self: starknet::storage::FlattenedStorage<Storage>) -> StorageStorageBase {
        let __counter_value__ = starknet::storage::StorageBase {__base_address__: selector!("counter")};
        let __upgradable_value__ = starknet::storage::FlattenedStorage {};
        let __ownable_value__ = starknet::storage::FlattenedStorage {};
        StorageStorageBase {
           counter: __counter_value__,
           upgradable: __upgradable_value__,
           ownable: __ownable_value__,
        }
    }
}
#[derive(Drop, Copy)]
#[doc(hidden)]
struct StorageStorageBaseMut {
    counter: starknet::storage::StorageBase<starknet::storage::Mutable::<u128>>,
        #[substorage(v0)]
    upgradable: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<upgradable_comp::Storage>>,
        #[substorage(v0)]
    ownable: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<ownable_comp::Storage>>,
}
#[doc(hidden)]
impl StorageStorageMutImpl of starknet::storage::StorageTraitMut<Storage> {
    type BaseType = StorageStorageBaseMut;
    fn storage_mut(self: starknet::storage::FlattenedStorage<starknet::storage::Mutable::<Storage>>) -> StorageStorageBaseMut {
        let __counter_value__ = starknet::storage::StorageBase {__base_address__: selector!("counter")};
        let __upgradable_value__ = starknet::storage::FlattenedStorage {};
        let __ownable_value__ = starknet::storage::FlattenedStorage {};
        StorageStorageBaseMut {
           counter: __counter_value__,
           upgradable: __upgradable_value__,
           ownable: __ownable_value__,
        }
    }
}

pub struct ContractState {
        #[substorage(v0)]
         upgradable: upgradable_comp::ComponentState<ContractState>,
        #[substorage(v0)]
         ownable: ownable_comp::ComponentState<ContractState>,
}

impl ContractStateDrop of Drop<ContractState> {}
 
impl ContractStateDeref of core::ops::SnapshotDeref<ContractState> {
    type Target = starknet::storage::FlattenedStorage<Storage>;
    fn snapshot_deref(self: @ContractState) -> starknet::storage::FlattenedStorage<Storage> {
        starknet::storage::FlattenedStorage {}
    }
}
impl ContractStateDerefMut of core::ops::DerefMut<ContractState> {
    type Target = starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> ;
    fn deref_mut(ref self: ContractState) -> starknet::storage::FlattenedStorage<starknet::storage::Mutable<Storage>> {
        starknet::storage::FlattenedStorage {}
    }
}
pub fn unsafe_new_contract_state() -> ContractState {
    ContractState {
            upgradable: upgradable_comp::unsafe_new_component_state::<ContractState>(),
            ownable: ownable_comp::unsafe_new_component_state::<ContractState>(),
    }
}

// TODO(Gil): This generates duplicate diagnostics because of the plugin system, squash the duplicates into one.
#[deprecated(
    feature: "deprecated_legacy_map",
    note: "Use `starknet::storage::Map` instead."
)]
#[allow(unused_imports)]
use starknet::storage::Map as LegacyMap;

#[doc(hidden)]
#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)]
fn __wrapper__constructor(mut data: Span::<felt252>) -> Span::<felt252> {
    core::internal::require_implicit::<System>();
    core::internal::revoke_ap_tracking();
    core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas');
    let __arg_initial_counter = core::option::OptionTraitImpl::expect(
        core::serde::Serde::<u128>::deserialize(ref data),
        'Failed to deserialize param #1'
    );
    assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments');
    core::option::OptionTraitImpl::expect(
        core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas',
    );
    let mut contract_state = unsafe_new_contract_state();
    constructor(ref contract_state, __arg_initial_counter);
    let mut arr = ArrayTrait::new();
    // References.
    // Result.
    core::array::ArrayTrait::span(@arr)
}

#[doc(hidden)]
#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)]
fn __wrapper__CounterContract__get_counter(mut data: Span::<felt252>) -> Span::<felt252> {
    core::internal::require_implicit::<System>();
    core::internal::revoke_ap_tracking();
    core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas');
    
    assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments');
    core::option::OptionTraitImpl::expect(
        core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas',
    );
    let mut contract_state = unsafe_new_contract_state();
    let res = CounterContract::get_counter(@contract_state, );
    let mut arr = ArrayTrait::new();
    // References.
    // Result.
    core::serde::Serde::<u128>::serialize(@res, ref arr);
    core::array::ArrayTrait::span(@arr)
}

#[doc(hidden)]
#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)]
fn __wrapper__CounterContract__increase_counter(mut data: Span::<felt252>) -> Span::<felt252> {
    core::internal::require_implicit::<System>();
    core::internal::revoke_ap_tracking();
    core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas');
    let __arg_amount = core::option::OptionTraitImpl::expect(
        core::serde::Serde::<u128>::deserialize(ref data),
        'Failed to deserialize param #1'
    );
    assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments');
    core::option::OptionTraitImpl::expect(
        core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas',
    );
    let mut contract_state = unsafe_new_contract_state();
    CounterContract::increase_counter(ref contract_state, __arg_amount);
    let mut arr = ArrayTrait::new();
    // References.
    // Result.
    core::array::ArrayTrait::span(@arr)
}

#[doc(hidden)]
#[implicit_precedence(core::pedersen::Pedersen, core::RangeCheck, core::integer::Bitwise, core::ec::EcOp, core::poseidon::Poseidon, core::SegmentArena, core::circuit::RangeCheck96, core::circuit::AddMod, core::circuit::MulMod, core::gas::GasBuiltin, System)]
fn __wrapper__CounterContract__decrease_counter(mut data: Span::<felt252>) -> Span::<felt252> {
    core::internal::require_implicit::<System>();
    core::internal::revoke_ap_tracking();
    core::option::OptionTraitImpl::expect(core::gas::withdraw_gas(), 'Out of gas');
    let __arg_amount = core::option::OptionTraitImpl::expect(
        core::serde::Serde::<u128>::deserialize(ref data),
        'Failed to deserialize param #1'
    );
    assert(core::array::SpanTrait::is_empty(data), 'Input too long for arguments');
    core::option::OptionTraitImpl::expect(
        core::gas::withdraw_gas_all(core::gas::get_builtin_costs()), 'Out of gas',
    );
    let mut contract_state = unsafe_new_contract_state();
    CounterContract::decrease_counter(ref contract_state, __arg_amount);
    let mut arr = ArrayTrait::new();
    // References.
    // Result.
    core::array::ArrayTrait::span(@arr)
}

impl ContractStateUpgradableImpl of
    upgradable_comp::UnsafeNewContractStateTraitForUpgradableImpl<ContractState> {
    fn unsafe_new_contract_state() -> ContractState {
        unsafe_new_contract_state()
    }
}

pub mod __external {
    pub use super::__wrapper__CounterContract__get_counter as get_counter;
    pub use super::__wrapper__CounterContract__increase_counter as increase_counter;
    pub use super::__wrapper__CounterContract__decrease_counter as decrease_counter;
}
pub mod __l1_handler {
}
pub mod __constructor {
    pub use super::__wrapper__constructor as constructor;
}
    impl ContractStateEventEmitter of starknet::event::EventEmitter<
        ContractState, Event
    > {
        fn emit<S, impl IntoImp: core::traits::Into<S, Event>>(
            ref self: ContractState, event: S
        ) {
            let event: Event = core::traits::Into::into(event);
            let mut keys = Default::<core::array::Array>::default();
            let mut data = Default::<core::array::Array>::default();
            starknet::Event::append_keys_and_data(@event, ref keys, ref data);
            starknet::SyscallResultTrait::unwrap_syscall(
                starknet::syscalls::emit_event_syscall(
                    core::array::ArrayTrait::span(@keys),
                    core::array::ArrayTrait::span(@data),
                )
            )
        }
    }

impl HasComponentImpl_upgradable_comp of upgradable_comp::HasComponent<ContractState> {
    fn get_component(self: @ContractState) -> @upgradable_comp::ComponentState<ContractState> {
                 @upgradable_comp::unsafe_new_component_state::<ContractState>()
    }
    fn get_component_mut(ref self: ContractState) -> upgradable_comp::ComponentState<ContractState> {
        upgradable_comp::unsafe_new_component_state::<ContractState>()
    }
    fn get_contract(self: @upgradable_comp::ComponentState<ContractState>) -> @ContractState {
        @unsafe_new_contract_state()
    }
    fn get_contract_mut(ref self: upgradable_comp::ComponentState<ContractState>) -> ContractState {
        unsafe_new_contract_state()
    }
    fn emit<S, impl IntoImp: core::traits::Into<S, upgradable_comp::Event>>(ref self: upgradable_comp::ComponentState<ContractState>, event: S) {
        let event: upgradable_comp::Event = core::traits::Into::into(event);
        let mut contract = upgradable_comp::HasComponent::get_contract_mut(ref self);
        ContractStateEventEmitter::emit(ref contract, Event::UpgradableEvent(event));
    }
}
impl HasComponentImpl_ownable_comp of ownable_comp::HasComponent<ContractState> {
    fn get_component(self: @ContractState) -> @ownable_comp::ComponentState<ContractState> {
                 @ownable_comp::unsafe_new_component_state::<ContractState>()
    }
    fn get_component_mut(ref self: ContractState) -> ownable_comp::ComponentState<ContractState> {
        ownable_comp::unsafe_new_component_state::<ContractState>()
    }
    fn get_contract(self: @ownable_comp::ComponentState<ContractState>) -> @ContractState {
        @unsafe_new_contract_state()
    }
    fn get_contract_mut(ref self: ownable_comp::ComponentState<ContractState>) -> ContractState {
        unsafe_new_contract_state()
    }
    fn emit<S, impl IntoImp: core::traits::Into<S, ownable_comp::Event>>(ref self: ownable_comp::ComponentState<ContractState>, event: S) {
        let event: ownable_comp::Event = core::traits::Into::into(event);
        let mut contract = ownable_comp::HasComponent::get_contract_mut(ref self);
        ContractStateEventEmitter::emit(ref contract, Event::OwnableEvent(event));
    }
}
impl EventDrop of core::traits::Drop::<Event>;
impl EventIsEvent of starknet::Event<Event> {
    fn append_keys_and_data(
        self: @Event, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
        match self {
            Event::CounterIncreased(val) => {
                core::array::ArrayTrait::append(ref keys, selector!("CounterIncreased"));
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
            Event::CounterDecreased(val) => {
                core::array::ArrayTrait::append(ref keys, selector!("CounterDecreased"));
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
            Event::UpgradableEvent(val) => {
                core::array::ArrayTrait::append(ref keys, selector!("UpgradableEvent"));
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
            Event::OwnableEvent(val) => {
                core::array::ArrayTrait::append(ref keys, selector!("OwnableEvent"));
                starknet::Event::append_keys_and_data(
                    val, ref keys, ref data
                );
            },
        }
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<Event> {
        let __selector__ = *core::array::SpanTrait::pop_front(ref keys)?;
        if __selector__ == selector!("CounterIncreased") {
                let val = starknet::Event::deserialize(
                    ref keys, ref data
                )?;
                return Option::Some(Event::CounterIncreased(val));
        }
        if __selector__ == selector!("CounterDecreased") {
                let val = starknet::Event::deserialize(
                    ref keys, ref data
                )?;
                return Option::Some(Event::CounterDecreased(val));
        }
        if __selector__ == selector!("UpgradableEvent") {
                let val = starknet::Event::deserialize(
                    ref keys, ref data
                )?;
                return Option::Some(Event::UpgradableEvent(val));
        }
        if __selector__ == selector!("OwnableEvent") {
                let val = starknet::Event::deserialize(
                    ref keys, ref data
                )?;
                return Option::Some(Event::OwnableEvent(val));
        }
        Option::None
    }
}
impl EventCounterIncreasedIntoEvent of Into<CounterIncreased, Event> {
    fn into(self: CounterIncreased) -> Event {
        Event::CounterIncreased(self)
    }
}
impl EventCounterDecreasedIntoEvent of Into<CounterDecreased, Event> {
    fn into(self: CounterDecreased) -> Event {
        Event::CounterDecreased(self)
    }
}
impl EventUpgradableEventIntoEvent of Into<upgradable_comp::Event, Event> {
    fn into(self: upgradable_comp::Event) -> Event {
        Event::UpgradableEvent(self)
    }
}
impl EventOwnableEventIntoEvent of Into<ownable_comp::Event, Event> {
    fn into(self: ownable_comp::Event) -> Event {
        Event::OwnableEvent(self)
    }
}
impl CounterIncreasedDrop of core::traits::Drop::<CounterIncreased>;
impl CounterIncreasedIsEvent of starknet::Event<CounterIncreased> {
    fn append_keys_and_data(
        self: @CounterIncreased, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
            core::serde::Serde::serialize(self.amount, ref data);
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<CounterIncreased> {
                let amount = core::serde::Serde::deserialize(
                    ref data
                )?;
        Option::Some(CounterIncreased {amount, })
    }
}
impl CounterDecreasedDrop of core::traits::Drop::<CounterDecreased>;
impl CounterDecreasedIsEvent of starknet::Event<CounterDecreased> {
    fn append_keys_and_data(
        self: @CounterDecreased, ref keys: Array<felt252>, ref data: Array<felt252>
    ) {
            core::serde::Serde::serialize(self.amount, ref data);
    }
    fn deserialize(
        ref keys: Span<felt252>, ref data: Span<felt252>,
    ) -> Option<CounterDecreased> {
                let amount = core::serde::Serde::deserialize(
                    ref data
                )?;
        Option::Some(CounterDecreased {amount, })
    }
}
impl StorageStorageBaseDrop of core::traits::Drop::<StorageStorageBase>;
impl StorageStorageBaseCopy of core::traits::Copy::<StorageStorageBase>;
impl StorageStorageBaseMutDrop of core::traits::Drop::<StorageStorageBaseMut>;
impl StorageStorageBaseMutCopy of core::traits::Copy::<StorageStorageBaseMut>;

//! > expected_diagnostics
