# DO NOT EDIT THIS FILE!
#
# This file is generated from the CDP specification. If you need to make
# changes, edit the generator and regenerate all of the modules.
#
# CDP domain: Storage (experimental)

from __future__ import annotations
import enum
import typing
from dataclasses import dataclass
from .util import event_class, T_JSON_DICT
from . import browser
from . import network
from . import page


class SerializedStorageKey(str):
    def to_json(self) -> str:
        return self

    @classmethod
    def from_json(cls, json: str) -> SerializedStorageKey:
        return cls(json)

    def __repr__(self):
        return "SerializedStorageKey({})".format(super().__repr__())


class StorageType(enum.Enum):
    """Enum of possible storage types."""
    APPCACHE = "appcache"
    COOKIES = "cookies"
    FILE_SYSTEMS = "file_systems"
    INDEXEDDB = "indexeddb"
    LOCAL_STORAGE = "local_storage"
    SHADER_CACHE = "shader_cache"
    WEBSQL = "websql"
    SERVICE_WORKERS = "service_workers"
    CACHE_STORAGE = "cache_storage"
    INTEREST_GROUPS = "interest_groups"
    SHARED_STORAGE = "shared_storage"
    STORAGE_BUCKETS = "storage_buckets"
    ALL_ = "all"
    OTHER = "other"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> StorageType:
        return cls(json)


@dataclass
class UsageForType:
    """Usage for a storage type."""
    #: Name of storage type.
    storage_type: StorageType
    #: Storage usage (bytes).
    usage: float

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["storageType"] = self.storage_type.to_json()
        json["usage"] = self.usage
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> UsageForType:
        return cls(
            storage_type=StorageType.from_json(json["storageType"]),
            usage=float(json["usage"]),
        )


@dataclass
class TrustTokens:
    """
    Pair of issuer origin and number of available (signed, but not used) Trust
    Tokens from that issuer.
    """
    issuer_origin: str
    count: float

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["issuerOrigin"] = self.issuer_origin
        json["count"] = self.count
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> TrustTokens:
        return cls(
            issuer_origin=str(json["issuerOrigin"]),
            count=float(json["count"]),
        )


class InterestGroupAuctionId(str):
    """Protected audience interest group auction identifier."""

    def to_json(self) -> str:
        return self

    @classmethod
    def from_json(cls, json: str) -> InterestGroupAuctionId:
        return cls(json)

    def __repr__(self):
        return "InterestGroupAuctionId({})".format(super().__repr__())


class InterestGroupAccessType(enum.Enum):
    """Enum of interest group access types."""
    JOIN = "join"
    LEAVE = "leave"
    UPDATE = "update"
    LOADED = "loaded"
    BID = "bid"
    WIN = "win"
    ADDITIONAL_BID = "additionalBid"
    ADDITIONAL_BID_WIN = "additionalBidWin"
    TOP_LEVEL_BID = "topLevelBid"
    TOP_LEVEL_ADDITIONAL_BID = "topLevelAdditionalBid"
    CLEAR = "clear"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> InterestGroupAccessType:
        return cls(json)


class InterestGroupAuctionEventType(enum.Enum):
    """Enum of auction events."""
    STARTED = "started"
    CONFIG_RESOLVED = "configResolved"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> InterestGroupAuctionEventType:
        return cls(json)


class InterestGroupAuctionFetchType(enum.Enum):
    """Enum of network fetches auctions can do."""
    BIDDER_JS = "bidderJs"
    BIDDER_WASM = "bidderWasm"
    SELLER_JS = "sellerJs"
    BIDDER_TRUSTED_SIGNALS = "bidderTrustedSignals"
    SELLER_TRUSTED_SIGNALS = "sellerTrustedSignals"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> InterestGroupAuctionFetchType:
        return cls(json)


class SharedStorageAccessType(enum.Enum):
    """Enum of shared storage access types."""
    DOCUMENT_ADD_MODULE = "documentAddModule"
    DOCUMENT_SELECT_URL = "documentSelectURL"
    DOCUMENT_RUN = "documentRun"
    DOCUMENT_SET = "documentSet"
    DOCUMENT_APPEND = "documentAppend"
    DOCUMENT_DELETE = "documentDelete"
    DOCUMENT_CLEAR = "documentClear"
    DOCUMENT_GET = "documentGet"
    WORKLET_SET = "workletSet"
    WORKLET_APPEND = "workletAppend"
    WORKLET_DELETE = "workletDelete"
    WORKLET_CLEAR = "workletClear"
    WORKLET_GET = "workletGet"
    WORKLET_KEYS = "workletKeys"
    WORKLET_ENTRIES = "workletEntries"
    WORKLET_LENGTH = "workletLength"
    WORKLET_REMAINING_BUDGET = "workletRemainingBudget"
    HEADER_SET = "headerSet"
    HEADER_APPEND = "headerAppend"
    HEADER_DELETE = "headerDelete"
    HEADER_CLEAR = "headerClear"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> SharedStorageAccessType:
        return cls(json)


@dataclass
class SharedStorageEntry:
    """Struct for a single key-value pair in an origin's shared storage."""
    key: str
    value: str

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["key"] = self.key
        json["value"] = self.value
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> SharedStorageEntry:
        return cls(
            key=str(json["key"]),
            value=str(json["value"]),
        )


@dataclass
class SharedStorageMetadata:
    """Details for an origin's shared storage."""
    #: Time when the origin's shared storage was last created.
    creation_time: network.TimeSinceEpoch
    #: Number of key-value pairs stored in origin's shared storage.
    length: int
    #: Current amount of bits of entropy remaining in the navigation budget.
    remaining_budget: float
    #: Total number of bytes stored as key-value pairs in origin's shared
    #: storage.
    bytes_used: int

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["creationTime"] = self.creation_time.to_json()
        json["length"] = self.length
        json["remainingBudget"] = self.remaining_budget
        json["bytesUsed"] = self.bytes_used
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> SharedStorageMetadata:
        return cls(
            creation_time=network.TimeSinceEpoch.from_json(
                json["creationTime"]
            ),
            length=int(json["length"]),
            remaining_budget=float(json["remainingBudget"]),
            bytes_used=int(json["bytesUsed"]),
        )


@dataclass
class SharedStorageReportingMetadata:
    """
    Pair of reporting metadata details for a candidate URL for ``selectURL()``.
    """
    event_type: str
    reporting_url: str

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["eventType"] = self.event_type
        json["reportingUrl"] = self.reporting_url
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> SharedStorageReportingMetadata:
        return cls(
            event_type=str(json["eventType"]),
            reporting_url=str(json["reportingUrl"]),
        )


@dataclass
class SharedStorageUrlWithMetadata:
    """Bundles a candidate URL with its reporting metadata."""
    #: Spec of candidate URL.
    url: str
    #: Any associated reporting metadata.
    reporting_metadata: typing.List[SharedStorageReportingMetadata]

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["url"] = self.url
        json["reportingMetadata"] = [
            i.to_json() for i in self.reporting_metadata
        ]
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> SharedStorageUrlWithMetadata:
        return cls(
            url=str(json["url"]),
            reporting_metadata=[
                SharedStorageReportingMetadata.from_json(i)
                for i in json["reportingMetadata"]
            ],
        )


@dataclass
class SharedStorageAccessParams:
    """
    Bundles the parameters for shared storage access events whose
    presence/absence can vary according to SharedStorageAccessType.
    """
    #: Spec of the module script URL.
    #: Present only for SharedStorageAccessType.documentAddModule.
    script_source_url: typing.Optional[str] = None
    #: Name of the registered operation to be run.
    #: Present only for SharedStorageAccessType.documentRun and
    #: SharedStorageAccessType.documentSelectURL.
    operation_name: typing.Optional[str] = None
    #: The operation's serialized data in bytes (converted to a string).
    #: Present only for SharedStorageAccessType.documentRun and
    #: SharedStorageAccessType.documentSelectURL.
    serialized_data: typing.Optional[str] = None
    #: Array of candidate URLs' specs, along with any associated metadata.
    #: Present only for SharedStorageAccessType.documentSelectURL.
    urls_with_metadata: typing.Optional[
        typing.List[SharedStorageUrlWithMetadata]
    ] = None
    #: Key for a specific entry in an origin's shared storage.
    #: Present only for SharedStorageAccessType.documentSet,
    #: SharedStorageAccessType.documentAppend,
    #: SharedStorageAccessType.documentDelete,
    #: SharedStorageAccessType.workletSet,
    #: SharedStorageAccessType.workletAppend,
    #: SharedStorageAccessType.workletDelete,
    #: SharedStorageAccessType.workletGet,
    #: SharedStorageAccessType.headerSet,
    #: SharedStorageAccessType.headerAppend, and
    #: SharedStorageAccessType.headerDelete.
    key: typing.Optional[str] = None
    #: Value for a specific entry in an origin's shared storage.
    #: Present only for SharedStorageAccessType.documentSet,
    #: SharedStorageAccessType.documentAppend,
    #: SharedStorageAccessType.workletSet,
    #: SharedStorageAccessType.workletAppend,
    #: SharedStorageAccessType.headerSet, and
    #: SharedStorageAccessType.headerAppend.
    value: typing.Optional[str] = None
    #: Whether or not to set an entry for a key if that key is already present.
    #: Present only for SharedStorageAccessType.documentSet,
    #: SharedStorageAccessType.workletSet, and
    #: SharedStorageAccessType.headerSet.
    ignore_if_present: typing.Optional[bool] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        if self.script_source_url is not None:
            json["scriptSourceUrl"] = self.script_source_url
        if self.operation_name is not None:
            json["operationName"] = self.operation_name
        if self.serialized_data is not None:
            json["serializedData"] = self.serialized_data
        if self.urls_with_metadata is not None:
            json["urlsWithMetadata"] = [
                i.to_json() for i in self.urls_with_metadata
            ]
        if self.key is not None:
            json["key"] = self.key
        if self.value is not None:
            json["value"] = self.value
        if self.ignore_if_present is not None:
            json["ignoreIfPresent"] = self.ignore_if_present
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> SharedStorageAccessParams:
        return cls(
            script_source_url=(
                str(json["scriptSourceUrl"])
                if json.get("scriptSourceUrl", None) is not None
                else None
            ),
            operation_name=(
                str(json["operationName"])
                if json.get("operationName", None) is not None
                else None
            ),
            serialized_data=(
                str(json["serializedData"])
                if json.get("serializedData", None) is not None
                else None
            ),
            urls_with_metadata=(
                [
                    SharedStorageUrlWithMetadata.from_json(i)
                    for i in json["urlsWithMetadata"]
                ]
                if json.get("urlsWithMetadata", None) is not None
                else None
            ),
            key=(
                str(json["key"]) if json.get("key", None) is not None else None
            ),
            value=(
                str(json["value"])
                if json.get("value", None) is not None
                else None
            ),
            ignore_if_present=(
                bool(json["ignoreIfPresent"])
                if json.get("ignoreIfPresent", None) is not None
                else None
            ),
        )


class StorageBucketsDurability(enum.Enum):
    RELAXED = "relaxed"
    STRICT = "strict"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> StorageBucketsDurability:
        return cls(json)


@dataclass
class StorageBucket:
    storage_key: SerializedStorageKey
    #: If not specified, it is the default bucket of the storageKey.
    name: typing.Optional[str] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["storageKey"] = self.storage_key.to_json()
        if self.name is not None:
            json["name"] = self.name
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> StorageBucket:
        return cls(
            storage_key=SerializedStorageKey.from_json(json["storageKey"]),
            name=(
                str(json["name"])
                if json.get("name", None) is not None
                else None
            ),
        )


@dataclass
class StorageBucketInfo:
    bucket: StorageBucket
    id_: str
    expiration: network.TimeSinceEpoch
    #: Storage quota (bytes).
    quota: float
    persistent: bool
    durability: StorageBucketsDurability

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["bucket"] = self.bucket.to_json()
        json["id"] = self.id_
        json["expiration"] = self.expiration.to_json()
        json["quota"] = self.quota
        json["persistent"] = self.persistent
        json["durability"] = self.durability.to_json()
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> StorageBucketInfo:
        return cls(
            bucket=StorageBucket.from_json(json["bucket"]),
            id_=str(json["id"]),
            expiration=network.TimeSinceEpoch.from_json(json["expiration"]),
            quota=float(json["quota"]),
            persistent=bool(json["persistent"]),
            durability=StorageBucketsDurability.from_json(json["durability"]),
        )


class AttributionReportingSourceType(enum.Enum):
    NAVIGATION = "navigation"
    EVENT = "event"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> AttributionReportingSourceType:
        return cls(json)


class UnsignedInt64AsBase10(str):
    def to_json(self) -> str:
        return self

    @classmethod
    def from_json(cls, json: str) -> UnsignedInt64AsBase10:
        return cls(json)

    def __repr__(self):
        return "UnsignedInt64AsBase10({})".format(super().__repr__())


class UnsignedInt128AsBase16(str):
    def to_json(self) -> str:
        return self

    @classmethod
    def from_json(cls, json: str) -> UnsignedInt128AsBase16:
        return cls(json)

    def __repr__(self):
        return "UnsignedInt128AsBase16({})".format(super().__repr__())


class SignedInt64AsBase10(str):
    def to_json(self) -> str:
        return self

    @classmethod
    def from_json(cls, json: str) -> SignedInt64AsBase10:
        return cls(json)

    def __repr__(self):
        return "SignedInt64AsBase10({})".format(super().__repr__())


@dataclass
class AttributionReportingFilterDataEntry:
    key: str
    values: typing.List[str]

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["key"] = self.key
        json["values"] = [i for i in self.values]
        return json

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingFilterDataEntry:
        return cls(
            key=str(json["key"]),
            values=[str(i) for i in json["values"]],
        )


@dataclass
class AttributionReportingFilterConfig:
    filter_values: typing.List[AttributionReportingFilterDataEntry]
    #: duration in seconds
    lookback_window: typing.Optional[int] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["filterValues"] = [i.to_json() for i in self.filter_values]
        if self.lookback_window is not None:
            json["lookbackWindow"] = self.lookback_window
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> AttributionReportingFilterConfig:
        return cls(
            filter_values=[
                AttributionReportingFilterDataEntry.from_json(i)
                for i in json["filterValues"]
            ],
            lookback_window=(
                int(json["lookbackWindow"])
                if json.get("lookbackWindow", None) is not None
                else None
            ),
        )


@dataclass
class AttributionReportingFilterPair:
    filters: typing.List[AttributionReportingFilterConfig]
    not_filters: typing.List[AttributionReportingFilterConfig]

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["filters"] = [i.to_json() for i in self.filters]
        json["notFilters"] = [i.to_json() for i in self.not_filters]
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> AttributionReportingFilterPair:
        return cls(
            filters=[
                AttributionReportingFilterConfig.from_json(i)
                for i in json["filters"]
            ],
            not_filters=[
                AttributionReportingFilterConfig.from_json(i)
                for i in json["notFilters"]
            ],
        )


@dataclass
class AttributionReportingAggregationKeysEntry:
    key: str
    value: UnsignedInt128AsBase16

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["key"] = self.key
        json["value"] = self.value.to_json()
        return json

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingAggregationKeysEntry:
        return cls(
            key=str(json["key"]),
            value=UnsignedInt128AsBase16.from_json(json["value"]),
        )


@dataclass
class AttributionReportingEventReportWindows:
    #: Duration in seconds
    start: int
    #: Duration in seconds
    ends: typing.List[int]

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["start"] = self.start
        json["ends"] = [i for i in self.ends]
        return json

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingEventReportWindows:
        return cls(
            start=int(json["start"]),
            ends=[int(i) for i in json["ends"]],
        )


@dataclass
class AttributionReportingTriggerSpec:
    #: Number instead of integer
    #: because not all uint32 can be represented by int
    trigger_data: typing.List[float]
    event_report_windows: AttributionReportingEventReportWindows

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["triggerData"] = [i for i in self.trigger_data]
        json["eventReportWindows"] = self.event_report_windows.to_json()
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> AttributionReportingTriggerSpec:
        return cls(
            trigger_data=[float(i) for i in json["triggerData"]],
            event_report_windows=AttributionReportingEventReportWindows.from_json(  # noqa
                json["eventReportWindows"]
            ),
        )


class AttributionReportingTriggerDataMatching(enum.Enum):
    EXACT = "exact"
    MODULUS = "modulus"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> AttributionReportingTriggerDataMatching:
        return cls(json)


@dataclass
class AttributionReportingSourceRegistration:
    time: network.TimeSinceEpoch
    #: duration in seconds
    expiry: int
    trigger_specs: typing.List[AttributionReportingTriggerSpec]
    #: duration in seconds
    aggregatable_report_window: int
    type_: AttributionReportingSourceType
    source_origin: str
    reporting_origin: str
    destination_sites: typing.List[str]
    event_id: UnsignedInt64AsBase10
    priority: SignedInt64AsBase10
    filter_data: typing.List[AttributionReportingFilterDataEntry]
    aggregation_keys: typing.List[AttributionReportingAggregationKeysEntry]
    trigger_data_matching: AttributionReportingTriggerDataMatching
    debug_key: typing.Optional[UnsignedInt64AsBase10] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["time"] = self.time.to_json()
        json["expiry"] = self.expiry
        json["triggerSpecs"] = [i.to_json() for i in self.trigger_specs]
        json["aggregatableReportWindow"] = self.aggregatable_report_window
        json["type"] = self.type_.to_json()
        json["sourceOrigin"] = self.source_origin
        json["reportingOrigin"] = self.reporting_origin
        json["destinationSites"] = [i for i in self.destination_sites]
        json["eventId"] = self.event_id.to_json()
        json["priority"] = self.priority.to_json()
        json["filterData"] = [i.to_json() for i in self.filter_data]
        json["aggregationKeys"] = [i.to_json() for i in self.aggregation_keys]
        json["triggerDataMatching"] = self.trigger_data_matching.to_json()
        if self.debug_key is not None:
            json["debugKey"] = self.debug_key.to_json()
        return json

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingSourceRegistration:
        return cls(
            time=network.TimeSinceEpoch.from_json(json["time"]),
            expiry=int(json["expiry"]),
            trigger_specs=[
                AttributionReportingTriggerSpec.from_json(i)
                for i in json["triggerSpecs"]
            ],
            aggregatable_report_window=int(json["aggregatableReportWindow"]),
            type_=AttributionReportingSourceType.from_json(json["type"]),
            source_origin=str(json["sourceOrigin"]),
            reporting_origin=str(json["reportingOrigin"]),
            destination_sites=[str(i) for i in json["destinationSites"]],
            event_id=UnsignedInt64AsBase10.from_json(json["eventId"]),
            priority=SignedInt64AsBase10.from_json(json["priority"]),
            filter_data=[
                AttributionReportingFilterDataEntry.from_json(i)
                for i in json["filterData"]
            ],
            aggregation_keys=[
                AttributionReportingAggregationKeysEntry.from_json(i)
                for i in json["aggregationKeys"]
            ],
            trigger_data_matching=AttributionReportingTriggerDataMatching.from_json(  # noqa
                json["triggerDataMatching"]
            ),
            debug_key=(
                UnsignedInt64AsBase10.from_json(json["debugKey"])
                if json.get("debugKey", None) is not None
                else None
            ),
        )


class AttributionReportingSourceRegistrationResult(enum.Enum):
    SUCCESS = "success"
    INTERNAL_ERROR = "internalError"
    INSUFFICIENT_SOURCE_CAPACITY = "insufficientSourceCapacity"
    INSUFFICIENT_UNIQUE_DESTINATION_CAPACITY = (
        "insufficientUniqueDestinationCapacity"
    )
    EXCESSIVE_REPORTING_ORIGINS = "excessiveReportingOrigins"
    PROHIBITED_BY_BROWSER_POLICY = "prohibitedByBrowserPolicy"
    SUCCESS_NOISED = "successNoised"
    DESTINATION_REPORTING_LIMIT_REACHED = "destinationReportingLimitReached"
    DESTINATION_GLOBAL_LIMIT_REACHED = "destinationGlobalLimitReached"
    DESTINATION_BOTH_LIMITS_REACHED = "destinationBothLimitsReached"
    REPORTING_ORIGINS_PER_SITE_LIMIT_REACHED = (
        "reportingOriginsPerSiteLimitReached"
    )
    EXCEEDS_MAX_CHANNEL_CAPACITY = "exceedsMaxChannelCapacity"
    EXCEEDS_MAX_TRIGGER_STATE_CARDINALITY = "exceedsMaxTriggerStateCardinality"
    DESTINATION_PER_DAY_REPORTING_LIMIT_REACHED = (
        "destinationPerDayReportingLimitReached"
    )

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(
        cls, json: str
    ) -> AttributionReportingSourceRegistrationResult:
        return cls(json)


class AttributionReportingSourceRegistrationTimeConfig(enum.Enum):
    INCLUDE = "include"
    EXCLUDE = "exclude"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(
        cls, json: str
    ) -> AttributionReportingSourceRegistrationTimeConfig:
        return cls(json)


@dataclass
class AttributionReportingAggregatableValueDictEntry:
    key: str
    #: float because not all uint32 can be represented by an int
    value: float

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["key"] = self.key
        json["value"] = self.value
        return json

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingAggregatableValueDictEntry:
        return cls(
            key=str(json["key"]),
            value=float(json["value"]),
        )


@dataclass
class AttributionReportingAggregatableValueEntry:
    values: typing.List[AttributionReportingAggregatableValueDictEntry]
    filters: AttributionReportingFilterPair

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["values"] = [i.to_json() for i in self.values]
        json["filters"] = self.filters.to_json()
        return json

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingAggregatableValueEntry:
        return cls(
            values=[
                AttributionReportingAggregatableValueDictEntry.from_json(i)
                for i in json["values"]
            ],
            filters=AttributionReportingFilterPair.from_json(json["filters"]),
        )


@dataclass
class AttributionReportingEventTriggerData:
    data: UnsignedInt64AsBase10
    priority: SignedInt64AsBase10
    filters: AttributionReportingFilterPair
    dedup_key: typing.Optional[UnsignedInt64AsBase10] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["data"] = self.data.to_json()
        json["priority"] = self.priority.to_json()
        json["filters"] = self.filters.to_json()
        if self.dedup_key is not None:
            json["dedupKey"] = self.dedup_key.to_json()
        return json

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingEventTriggerData:
        return cls(
            data=UnsignedInt64AsBase10.from_json(json["data"]),
            priority=SignedInt64AsBase10.from_json(json["priority"]),
            filters=AttributionReportingFilterPair.from_json(json["filters"]),
            dedup_key=(
                UnsignedInt64AsBase10.from_json(json["dedupKey"])
                if json.get("dedupKey", None) is not None
                else None
            ),
        )


@dataclass
class AttributionReportingAggregatableTriggerData:
    key_piece: UnsignedInt128AsBase16
    source_keys: typing.List[str]
    filters: AttributionReportingFilterPair

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["keyPiece"] = self.key_piece.to_json()
        json["sourceKeys"] = [i for i in self.source_keys]
        json["filters"] = self.filters.to_json()
        return json

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingAggregatableTriggerData:
        return cls(
            key_piece=UnsignedInt128AsBase16.from_json(json["keyPiece"]),
            source_keys=[str(i) for i in json["sourceKeys"]],
            filters=AttributionReportingFilterPair.from_json(json["filters"]),
        )


@dataclass
class AttributionReportingAggregatableDedupKey:
    filters: AttributionReportingFilterPair
    dedup_key: typing.Optional[UnsignedInt64AsBase10] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["filters"] = self.filters.to_json()
        if self.dedup_key is not None:
            json["dedupKey"] = self.dedup_key.to_json()
        return json

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingAggregatableDedupKey:
        return cls(
            filters=AttributionReportingFilterPair.from_json(json["filters"]),
            dedup_key=(
                UnsignedInt64AsBase10.from_json(json["dedupKey"])
                if json.get("dedupKey", None) is not None
                else None
            ),
        )


@dataclass
class AttributionReportingTriggerRegistration:
    filters: AttributionReportingFilterPair
    aggregatable_dedup_keys: typing.List[
        AttributionReportingAggregatableDedupKey
    ]
    event_trigger_data: typing.List[AttributionReportingEventTriggerData]
    aggregatable_trigger_data: typing.List[
        AttributionReportingAggregatableTriggerData
    ]
    aggregatable_values: typing.List[
        AttributionReportingAggregatableValueEntry
    ]
    debug_reporting: bool
    source_registration_time_config: (
        AttributionReportingSourceRegistrationTimeConfig
    )
    debug_key: typing.Optional[UnsignedInt64AsBase10] = None
    aggregation_coordinator_origin: typing.Optional[str] = None
    trigger_context_id: typing.Optional[str] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["filters"] = self.filters.to_json()
        json["aggregatableDedupKeys"] = [
            i.to_json() for i in self.aggregatable_dedup_keys
        ]
        json["eventTriggerData"] = [
            i.to_json() for i in self.event_trigger_data
        ]
        json["aggregatableTriggerData"] = [
            i.to_json() for i in self.aggregatable_trigger_data
        ]
        json["aggregatableValues"] = [
            i.to_json() for i in self.aggregatable_values
        ]
        json["debugReporting"] = self.debug_reporting
        json["sourceRegistrationTimeConfig"] = (
            self.source_registration_time_config.to_json()
        )
        if self.debug_key is not None:
            json["debugKey"] = self.debug_key.to_json()
        if self.aggregation_coordinator_origin is not None:
            json["aggregationCoordinatorOrigin"] = (
                self.aggregation_coordinator_origin
            )
        if self.trigger_context_id is not None:
            json["triggerContextId"] = self.trigger_context_id
        return json

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingTriggerRegistration:
        return cls(
            filters=AttributionReportingFilterPair.from_json(json["filters"]),
            aggregatable_dedup_keys=[
                AttributionReportingAggregatableDedupKey.from_json(i)
                for i in json["aggregatableDedupKeys"]
            ],
            event_trigger_data=[
                AttributionReportingEventTriggerData.from_json(i)
                for i in json["eventTriggerData"]
            ],
            aggregatable_trigger_data=[
                AttributionReportingAggregatableTriggerData.from_json(i)
                for i in json["aggregatableTriggerData"]
            ],
            aggregatable_values=[
                AttributionReportingAggregatableValueEntry.from_json(i)
                for i in json["aggregatableValues"]
            ],
            debug_reporting=bool(json["debugReporting"]),
            source_registration_time_config=AttributionReportingSourceRegistrationTimeConfig.from_json(  # noqa
                json["sourceRegistrationTimeConfig"]
            ),
            debug_key=(
                UnsignedInt64AsBase10.from_json(json["debugKey"])
                if json.get("debugKey", None) is not None
                else None
            ),
            aggregation_coordinator_origin=(
                str(json["aggregationCoordinatorOrigin"])
                if json.get("aggregationCoordinatorOrigin", None) is not None
                else None
            ),
            trigger_context_id=(
                str(json["triggerContextId"])
                if json.get("triggerContextId", None) is not None
                else None
            ),
        )


class AttributionReportingEventLevelResult(enum.Enum):
    SUCCESS = "success"
    SUCCESS_DROPPED_LOWER_PRIORITY = "successDroppedLowerPriority"
    INTERNAL_ERROR = "internalError"
    NO_CAPACITY_FOR_ATTRIBUTION_DESTINATION = (
        "noCapacityForAttributionDestination"
    )
    NO_MATCHING_SOURCES = "noMatchingSources"
    DEDUPLICATED = "deduplicated"
    EXCESSIVE_ATTRIBUTIONS = "excessiveAttributions"
    PRIORITY_TOO_LOW = "priorityTooLow"
    NEVER_ATTRIBUTED_SOURCE = "neverAttributedSource"
    EXCESSIVE_REPORTING_ORIGINS = "excessiveReportingOrigins"
    NO_MATCHING_SOURCE_FILTER_DATA = "noMatchingSourceFilterData"
    PROHIBITED_BY_BROWSER_POLICY = "prohibitedByBrowserPolicy"
    NO_MATCHING_CONFIGURATIONS = "noMatchingConfigurations"
    EXCESSIVE_REPORTS = "excessiveReports"
    FALSELY_ATTRIBUTED_SOURCE = "falselyAttributedSource"
    REPORT_WINDOW_PASSED = "reportWindowPassed"
    NOT_REGISTERED = "notRegistered"
    REPORT_WINDOW_NOT_STARTED = "reportWindowNotStarted"
    NO_MATCHING_TRIGGER_DATA = "noMatchingTriggerData"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> AttributionReportingEventLevelResult:
        return cls(json)


class AttributionReportingAggregatableResult(enum.Enum):
    SUCCESS = "success"
    INTERNAL_ERROR = "internalError"
    NO_CAPACITY_FOR_ATTRIBUTION_DESTINATION = (
        "noCapacityForAttributionDestination"
    )
    NO_MATCHING_SOURCES = "noMatchingSources"
    EXCESSIVE_ATTRIBUTIONS = "excessiveAttributions"
    EXCESSIVE_REPORTING_ORIGINS = "excessiveReportingOrigins"
    NO_HISTOGRAMS = "noHistograms"
    INSUFFICIENT_BUDGET = "insufficientBudget"
    NO_MATCHING_SOURCE_FILTER_DATA = "noMatchingSourceFilterData"
    NOT_REGISTERED = "notRegistered"
    PROHIBITED_BY_BROWSER_POLICY = "prohibitedByBrowserPolicy"
    DEDUPLICATED = "deduplicated"
    REPORT_WINDOW_PASSED = "reportWindowPassed"
    EXCESSIVE_REPORTS = "excessiveReports"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> AttributionReportingAggregatableResult:
        return cls(json)


@dataclass
class RelatedWebsiteSet:
    """A single Related Website Set object."""
    #: The primary site of this set, along with the ccTLDs if there is any.
    primary_sites: typing.List[str]
    #: The associated sites of this set, along with the ccTLDs if there is any.
    associated_sites: typing.List[str]
    #: The service sites of this set, along with the ccTLDs if there is any.
    service_sites: typing.List[str]

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json["primarySites"] = [i for i in self.primary_sites]
        json["associatedSites"] = [i for i in self.associated_sites]
        json["serviceSites"] = [i for i in self.service_sites]
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> RelatedWebsiteSet:
        return cls(
            primary_sites=[str(i) for i in json["primarySites"]],
            associated_sites=[str(i) for i in json["associatedSites"]],
            service_sites=[str(i) for i in json["serviceSites"]],
        )


def get_storage_key_for_frame(
    frame_id: page.FrameId,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, SerializedStorageKey]:
    """
    Returns a storage key given a frame id.
    :param frame_id:
    """
    params: T_JSON_DICT = dict()
    params["frameId"] = frame_id.to_json()
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.getStorageKeyForFrame",
        "params": params,
    }
    json = yield cmd_dict
    return SerializedStorageKey.from_json(json["storageKey"])


def clear_data_for_origin(
    origin: str, storage_types: str
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Clears storage for origin.
    :param origin: Security origin.
    :param storage_types: Comma separated list of StorageType to clear.
    """
    params: T_JSON_DICT = dict()
    params["origin"] = origin
    params["storageTypes"] = storage_types
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.clearDataForOrigin",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def clear_data_for_storage_key(
    storage_key: str, storage_types: str
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Clears storage for storage key.
    :param storage_key: Storage key.
    :param storage_types: Comma separated list of StorageType to clear.
    """
    params: T_JSON_DICT = dict()
    params["storageKey"] = storage_key
    params["storageTypes"] = storage_types
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.clearDataForStorageKey",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def get_cookies(
    browser_context_id: typing.Optional[browser.BrowserContextID] = None,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, typing.List[network.Cookie]]:
    """
    Returns all browser cookies.
    :param browser_context_id: *(Optional)*
     Browser context to use when called on the browser endpoint.
    :returns: Array of cookie objects.
    """
    params: T_JSON_DICT = dict()
    if browser_context_id is not None:
        params["browserContextId"] = browser_context_id.to_json()
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.getCookies",
        "params": params,
    }
    json = yield cmd_dict
    return [network.Cookie.from_json(i) for i in json["cookies"]]


def set_cookies(
    cookies: typing.List[network.CookieParam],
    browser_context_id: typing.Optional[browser.BrowserContextID] = None,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Sets given cookies.
    :param cookies: Cookies to be set.
    :param browser_context_id: *(Optional)*
     Browser context to use when called on the browser endpoint.
    """
    params: T_JSON_DICT = dict()
    params["cookies"] = [i.to_json() for i in cookies]
    if browser_context_id is not None:
        params["browserContextId"] = browser_context_id.to_json()
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.setCookies",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def clear_cookies(
    browser_context_id: typing.Optional[browser.BrowserContextID] = None,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Clears cookies.
    :param browser_context_id: *(Optional)*
     Browser context to use when called on the browser endpoint.
    """
    params: T_JSON_DICT = dict()
    if browser_context_id is not None:
        params["browserContextId"] = browser_context_id.to_json()
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.clearCookies",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def get_usage_and_quota(
    origin: str,
) -> typing.Generator[
    T_JSON_DICT,
    T_JSON_DICT,
    typing.Tuple[float, float, bool, typing.List[UsageForType]],
]:
    """
    Returns usage and quota in bytes.
    :param origin: Security origin.
    :returns: A tuple with the following items:
        0. **usage** - Storage usage (bytes).
        1. **quota** - Storage quota (bytes).
        2. **overrideActive** -
         Whether or not the origin has an active storage quota override
        3. **usageBreakdown** - Storage usage per type (bytes).
    """
    params: T_JSON_DICT = dict()
    params["origin"] = origin
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.getUsageAndQuota",
        "params": params,
    }
    json = yield cmd_dict
    return (
        float(json["usage"]),
        float(json["quota"]),
        bool(json["overrideActive"]),
        [UsageForType.from_json(i) for i in json["usageBreakdown"]],
    )


def override_quota_for_origin(
    origin: str, quota_size: typing.Optional[float] = None
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Override quota for the specified origin
    **EXPERIMENTAL**
    :param origin: Security origin.
    :param quota_size: *(Optional)* The quota size (in bytes)
     to override the original quota with. If this is called multiple times,
     the overridden quota will be equal to the quotaSize provided in the
     final call. If this is called without specifying a quotaSize,
     the quota will be reset to the default value for the specified origin.
     If this is called multiple times with different origins,
     the override will be maintained for each origin until it is disabled
     (called without a quotaSize).
    """
    params: T_JSON_DICT = dict()
    params["origin"] = origin
    if quota_size is not None:
        params["quotaSize"] = quota_size
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.overrideQuotaForOrigin",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def track_cache_storage_for_origin(
    origin: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Registers origin to be notified when an update occurs
    to its cache storage list.
    :param origin: Security origin.
    """
    params: T_JSON_DICT = dict()
    params["origin"] = origin
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.trackCacheStorageForOrigin",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def track_cache_storage_for_storage_key(
    storage_key: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Registers storage key to be notified when an update occurs
    to its cache storage list.
    :param storage_key: Storage key.
    """
    params: T_JSON_DICT = dict()
    params["storageKey"] = storage_key
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.trackCacheStorageForStorageKey",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def track_indexed_db_for_origin(
    origin: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Registers origin to be notified when an update occurs to its IndexedDB.
    :param origin: Security origin.
    """
    params: T_JSON_DICT = dict()
    params["origin"] = origin
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.trackIndexedDBForOrigin",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def track_indexed_db_for_storage_key(
    storage_key: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Registers storage key to be notified when an update occurs
    to its IndexedDB.
    :param storage_key: Storage key.
    """
    params: T_JSON_DICT = dict()
    params["storageKey"] = storage_key
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.trackIndexedDBForStorageKey",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def untrack_cache_storage_for_origin(
    origin: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Unregisters origin from receiving notifications for cache storage.
    :param origin: Security origin.
    """
    params: T_JSON_DICT = dict()
    params["origin"] = origin
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.untrackCacheStorageForOrigin",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def untrack_cache_storage_for_storage_key(
    storage_key: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Unregisters storage key from receiving notifications for cache storage.
    :param storage_key: Storage key.
    """
    params: T_JSON_DICT = dict()
    params["storageKey"] = storage_key
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.untrackCacheStorageForStorageKey",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def untrack_indexed_db_for_origin(
    origin: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Unregisters origin from receiving notifications for IndexedDB.
    :param origin: Security origin.
    """
    params: T_JSON_DICT = dict()
    params["origin"] = origin
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.untrackIndexedDBForOrigin",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def untrack_indexed_db_for_storage_key(
    storage_key: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Unregisters storage key from receiving notifications for IndexedDB.
    :param storage_key: Storage key.
    """
    params: T_JSON_DICT = dict()
    params["storageKey"] = storage_key
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.untrackIndexedDBForStorageKey",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def get_trust_tokens() -> (
    typing.Generator[T_JSON_DICT, T_JSON_DICT, typing.List[TrustTokens]]
):
    """
    Returns the number of stored Trust Tokens per issuer for the
    current browsing context.
    **EXPERIMENTAL**
    """
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.getTrustTokens",
    }
    json = yield cmd_dict
    return [TrustTokens.from_json(i) for i in json["tokens"]]


def clear_trust_tokens(
    issuer_origin: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, bool]:
    """
    Removes all Trust Tokens issued by the provided issuerOrigin.
    Leaves other stored data, including the issuer's Redemption Records,
    intact.
    **EXPERIMENTAL**
    :param issuer_origin:
    :returns: True if any tokens were deleted, false otherwise.
    """
    params: T_JSON_DICT = dict()
    params["issuerOrigin"] = issuer_origin
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.clearTrustTokens",
        "params": params,
    }
    json = yield cmd_dict
    return bool(json["didDeleteTokens"])


def get_interest_group_details(
    owner_origin: str, name: str
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, dict]:
    """
    Gets details for a named interest group.
    **EXPERIMENTAL**
    :param owner_origin:
    :param name:
    :returns: This largely corresponds to:
    https://wicg.github.io/turtledove/#dictdef-generatebidinterestgroup
    but has absolute expirationTime instead of relative lifetimeMs
    and also adds joiningOrigin.
    """
    params: T_JSON_DICT = dict()
    params["ownerOrigin"] = owner_origin
    params["name"] = name
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.getInterestGroupDetails",
        "params": params,
    }
    json = yield cmd_dict
    return dict(json["details"])


def set_interest_group_tracking(
    enable: bool,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Enables/Disables issuing of interestGroupAccessed events.
    **EXPERIMENTAL**
    :param enable:
    """
    params: T_JSON_DICT = dict()
    params["enable"] = enable
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.setInterestGroupTracking",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def set_interest_group_auction_tracking(
    enable: bool,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Enables/Disables issuing of interestGroupAuctionEventOccurred and
    interestGroupAuctionNetworkRequestCreated.
    **EXPERIMENTAL**
    :param enable:
    """
    params: T_JSON_DICT = dict()
    params["enable"] = enable
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.setInterestGroupAuctionTracking",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def get_shared_storage_metadata(
    owner_origin: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, SharedStorageMetadata]:
    """
    Gets metadata for an origin's shared storage.
    **EXPERIMENTAL**
    :param owner_origin:
    """
    params: T_JSON_DICT = dict()
    params["ownerOrigin"] = owner_origin
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.getSharedStorageMetadata",
        "params": params,
    }
    json = yield cmd_dict
    return SharedStorageMetadata.from_json(json["metadata"])


def get_shared_storage_entries(
    owner_origin: str,
) -> typing.Generator[
    T_JSON_DICT, T_JSON_DICT, typing.List[SharedStorageEntry]
]:
    """
    Gets the entries in an given origin's shared storage.
    **EXPERIMENTAL**
    :param owner_origin:
    """
    params: T_JSON_DICT = dict()
    params["ownerOrigin"] = owner_origin
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.getSharedStorageEntries",
        "params": params,
    }
    json = yield cmd_dict
    return [SharedStorageEntry.from_json(i) for i in json["entries"]]


def set_shared_storage_entry(
    owner_origin: str,
    key: str,
    value: str,
    ignore_if_present: typing.Optional[bool] = None,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Sets entry with ``key`` and ``value`` for a given origin's shared storage.
    **EXPERIMENTAL**
    :param owner_origin:
    :param key:
    :param value:
    :param ignore_if_present: *(Optional)*
    If ``ignoreIfPresent`` is included and true,
    then only sets the entry if ``key`` doesn't already exist.
    """
    params: T_JSON_DICT = dict()
    params["ownerOrigin"] = owner_origin
    params["key"] = key
    params["value"] = value
    if ignore_if_present is not None:
        params["ignoreIfPresent"] = ignore_if_present
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.setSharedStorageEntry",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def delete_shared_storage_entry(
    owner_origin: str, key: str
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Deletes entry for ``key`` (if it exists)
    for a given origin's shared storage.
    **EXPERIMENTAL**
    :param owner_origin:
    :param key:
    """
    params: T_JSON_DICT = dict()
    params["ownerOrigin"] = owner_origin
    params["key"] = key
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.deleteSharedStorageEntry",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def clear_shared_storage_entries(
    owner_origin: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Clears all entries for a given origin's shared storage.
    **EXPERIMENTAL**
    :param owner_origin:
    """
    params: T_JSON_DICT = dict()
    params["ownerOrigin"] = owner_origin
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.clearSharedStorageEntries",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def reset_shared_storage_budget(
    owner_origin: str,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Resets the budget for ``ownerOrigin`` by clearing all budget withdrawals.
    **EXPERIMENTAL**
    :param owner_origin:
    """
    params: T_JSON_DICT = dict()
    params["ownerOrigin"] = owner_origin
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.resetSharedStorageBudget",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def set_shared_storage_tracking(
    enable: bool,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Enables/disables issuing of sharedStorageAccessed events.
    **EXPERIMENTAL**
    :param enable:
    """
    params: T_JSON_DICT = dict()
    params["enable"] = enable
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.setSharedStorageTracking",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def set_storage_bucket_tracking(
    storage_key: str, enable: bool
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Set tracking for a storage key's buckets.
    **EXPERIMENTAL**
    :param storage_key:
    :param enable:
    """
    params: T_JSON_DICT = dict()
    params["storageKey"] = storage_key
    params["enable"] = enable
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.setStorageBucketTracking",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def delete_storage_bucket(
    bucket: StorageBucket,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Deletes the Storage Bucket with the given storage key and bucket name.
    **EXPERIMENTAL**
    :param bucket:
    """
    params: T_JSON_DICT = dict()
    params["bucket"] = bucket.to_json()
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.deleteStorageBucket",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def run_bounce_tracking_mitigations() -> (
    typing.Generator[T_JSON_DICT, T_JSON_DICT, typing.List[str]]
):
    """
    Deletes state for sites identified as potential bounce trackers,
    immediately.
    **EXPERIMENTAL**
    """
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.runBounceTrackingMitigations",
    }
    json = yield cmd_dict
    return [str(i) for i in json["deletedSites"]]


def set_attribution_reporting_local_testing_mode(
    enabled: bool,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    https://wicg.github.io/attribution-reporting-api/
    **EXPERIMENTAL**
    :param enabled: If enabled, noise is suppressed
    and reports are sent immediately.
    """
    params: T_JSON_DICT = dict()
    params["enabled"] = enabled
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.setAttributionReportingLocalTestingMode",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def set_attribution_reporting_tracking(
    enable: bool,
) -> typing.Generator[T_JSON_DICT, T_JSON_DICT, None]:
    """
    Enables/disables issuing of Attribution Reporting events.
    **EXPERIMENTAL**
    :param enable:
    """
    params: T_JSON_DICT = dict()
    params["enable"] = enable
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.setAttributionReportingTracking",
        "params": params,
    }
    json = yield cmd_dict  # noqa


def send_pending_attribution_reports() -> (
    typing.Generator[T_JSON_DICT, T_JSON_DICT, int]
):
    """
    Sends all pending Attribution Reports immediately,
    regardless of their scheduled report time.
    **EXPERIMENTAL**
    :returns: The number of reports that were sent.
    """
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.sendPendingAttributionReports",
    }
    json = yield cmd_dict
    return int(json["numSent"])


def get_related_website_sets() -> (
    typing.Generator[T_JSON_DICT, T_JSON_DICT, typing.List[RelatedWebsiteSet]]
):
    """
    Returns the effective Related Website Sets in use by this profile
    for the browser session.
    The effective Related Website Sets will not change
    during a browser session.
    **EXPERIMENTAL**
    """
    cmd_dict: T_JSON_DICT = {
        "method": "Storage.getRelatedWebsiteSets",
    }
    json = yield cmd_dict
    return [RelatedWebsiteSet.from_json(i) for i in json["sets"]]


@event_class("Storage.cacheStorageContentUpdated")
@dataclass
class CacheStorageContentUpdated:
    """A cache's contents have been modified."""

    #: Origin to update.
    origin: str
    #: Storage key to update.
    storage_key: str
    #: Storage bucket to update.
    bucket_id: str
    #: Name of cache in origin.
    cache_name: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> CacheStorageContentUpdated:
        return cls(
            origin=str(json["origin"]),
            storage_key=str(json["storageKey"]),
            bucket_id=str(json["bucketId"]),
            cache_name=str(json["cacheName"]),
        )


@event_class("Storage.cacheStorageListUpdated")
@dataclass
class CacheStorageListUpdated:
    """A cache has been added/deleted."""

    #: Origin to update.
    origin: str
    #: Storage key to update.
    storage_key: str
    #: Storage bucket to update.
    bucket_id: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> CacheStorageListUpdated:
        return cls(
            origin=str(json["origin"]),
            storage_key=str(json["storageKey"]),
            bucket_id=str(json["bucketId"]),
        )


@event_class("Storage.indexedDBContentUpdated")
@dataclass
class IndexedDBContentUpdated:
    """The origin's IndexedDB object store has been modified."""

    #: Origin to update.
    origin: str
    #: Storage key to update.
    storage_key: str
    #: Storage bucket to update.
    bucket_id: str
    #: Database to update.
    database_name: str
    #: ObjectStore to update.
    object_store_name: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> IndexedDBContentUpdated:
        return cls(
            origin=str(json["origin"]),
            storage_key=str(json["storageKey"]),
            bucket_id=str(json["bucketId"]),
            database_name=str(json["databaseName"]),
            object_store_name=str(json["objectStoreName"]),
        )


@event_class("Storage.indexedDBListUpdated")
@dataclass
class IndexedDBListUpdated:
    """The origin's IndexedDB database list has been modified."""

    #: Origin to update.
    origin: str
    #: Storage key to update.
    storage_key: str
    #: Storage bucket to update.
    bucket_id: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> IndexedDBListUpdated:
        return cls(
            origin=str(json["origin"]),
            storage_key=str(json["storageKey"]),
            bucket_id=str(json["bucketId"]),
        )


@event_class("Storage.interestGroupAccessed")
@dataclass
class InterestGroupAccessed:
    """
    One of the interest groups was accessed.
    Note that these events are global to all targets
    sharing an interest group store.
    """
    access_time: network.TimeSinceEpoch
    type_: InterestGroupAccessType
    owner_origin: str
    name: str
    #: For topLevelBid/topLevelAdditionalBid, and when appropriate,
    #: win and additionalBidWin
    component_seller_origin: typing.Optional[str]
    #: For bid or somethingBid event, if done locally and not on a server.
    bid: typing.Optional[float]
    bid_currency: typing.Optional[str]
    #: For non-global events --- links to interestGroupAuctionEvent
    unique_auction_id: typing.Optional[InterestGroupAuctionId]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> InterestGroupAccessed:
        return cls(
            access_time=network.TimeSinceEpoch.from_json(json["accessTime"]),
            type_=InterestGroupAccessType.from_json(json["type"]),
            owner_origin=str(json["ownerOrigin"]),
            name=str(json["name"]),
            component_seller_origin=(
                str(json["componentSellerOrigin"])
                if json.get("componentSellerOrigin", None) is not None
                else None
            ),
            bid=(
                float(json["bid"])
                if json.get("bid", None) is not None
                else None
            ),
            bid_currency=(
                str(json["bidCurrency"])
                if json.get("bidCurrency", None) is not None
                else None
            ),
            unique_auction_id=(
                InterestGroupAuctionId.from_json(json["uniqueAuctionId"])
                if json.get("uniqueAuctionId", None) is not None
                else None
            ),
        )


@event_class("Storage.interestGroupAuctionEventOccurred")
@dataclass
class InterestGroupAuctionEventOccurred:
    """
    An auction involving interest groups is taking place.
    These events are target-specific.
    """
    event_time: network.TimeSinceEpoch
    type_: InterestGroupAuctionEventType
    unique_auction_id: InterestGroupAuctionId
    #: Set for child auctions.
    parent_auction_id: typing.Optional[InterestGroupAuctionId]
    #: Set for started and configResolved
    auction_config: typing.Optional[dict]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> InterestGroupAuctionEventOccurred:
        return cls(
            event_time=network.TimeSinceEpoch.from_json(json["eventTime"]),
            type_=InterestGroupAuctionEventType.from_json(json["type"]),
            unique_auction_id=InterestGroupAuctionId.from_json(
                json["uniqueAuctionId"]
            ),
            parent_auction_id=(
                InterestGroupAuctionId.from_json(json["parentAuctionId"])
                if json.get("parentAuctionId", None) is not None
                else None
            ),
            auction_config=(
                dict(json["auctionConfig"])
                if json.get("auctionConfig", None) is not None
                else None
            ),
        )


@event_class("Storage.interestGroupAuctionNetworkRequestCreated")
@dataclass
class InterestGroupAuctionNetworkRequestCreated:
    """
    Specifies which auctions a particular network fetch may be related to,
    and in what role. Note that it is not ordered with respect to
    Network.requestWillBeSent (but will happen before loadingFinished
    loadingFailed).
    """
    type_: InterestGroupAuctionFetchType
    request_id: network.RequestId
    #: This is the set of the auctions using the worklet that issued this
    #: request. In the case of trusted signals,
    #: it's possible that only some of them actually care
    #: about the keys being queried.
    auctions: typing.List[InterestGroupAuctionId]

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> InterestGroupAuctionNetworkRequestCreated:
        return cls(
            type_=InterestGroupAuctionFetchType.from_json(json["type"]),
            request_id=network.RequestId.from_json(json["requestId"]),
            auctions=[
                InterestGroupAuctionId.from_json(i) for i in json["auctions"]
            ],
        )


@event_class("Storage.sharedStorageAccessed")
@dataclass
class SharedStorageAccessed:
    """
    Shared storage was accessed by the associated page.
    The following parameters are included in all events.
    """
    #: Time of the access.
    access_time: network.TimeSinceEpoch
    #: Enum value indicating the Shared Storage API method invoked.
    type_: SharedStorageAccessType
    #: DevTools Frame Token for the primary frame tree's root.
    main_frame_id: page.FrameId
    #: Serialized origin for the context that invoked the Shared Storage API.
    owner_origin: str
    #: The sub-parameters wrapped by ``params`` are all optional and their
    #: presence/absence depends on ``type``.
    params: SharedStorageAccessParams

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> SharedStorageAccessed:
        return cls(
            access_time=network.TimeSinceEpoch.from_json(json["accessTime"]),
            type_=SharedStorageAccessType.from_json(json["type"]),
            main_frame_id=page.FrameId.from_json(json["mainFrameId"]),
            owner_origin=str(json["ownerOrigin"]),
            params=SharedStorageAccessParams.from_json(json["params"]),
        )


@event_class("Storage.storageBucketCreatedOrUpdated")
@dataclass
class StorageBucketCreatedOrUpdated:
    bucket_info: StorageBucketInfo

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> StorageBucketCreatedOrUpdated:
        return cls(bucket_info=StorageBucketInfo.from_json(json["bucketInfo"]))


@event_class("Storage.storageBucketDeleted")
@dataclass
class StorageBucketDeleted:
    bucket_id: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> StorageBucketDeleted:
        return cls(bucket_id=str(json["bucketId"]))


@event_class("Storage.attributionReportingSourceRegistered")
@dataclass
class AttributionReportingSourceRegistered:
    """
    **EXPERIMENTAL**
    """

    registration: AttributionReportingSourceRegistration
    result: AttributionReportingSourceRegistrationResult

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingSourceRegistered:
        return cls(
            registration=AttributionReportingSourceRegistration.from_json(
                json["registration"]
            ),
            result=AttributionReportingSourceRegistrationResult.from_json(
                json["result"]
            ),
        )


@event_class("Storage.attributionReportingTriggerRegistered")
@dataclass
class AttributionReportingTriggerRegistered:
    """
    **EXPERIMENTAL**
    """
    registration: AttributionReportingTriggerRegistration
    event_level: AttributionReportingEventLevelResult
    aggregatable: AttributionReportingAggregatableResult

    @classmethod
    def from_json(
        cls, json: T_JSON_DICT
    ) -> AttributionReportingTriggerRegistered:
        return cls(
            registration=AttributionReportingTriggerRegistration.from_json(
                json["registration"]
            ),
            event_level=AttributionReportingEventLevelResult.from_json(
                json["eventLevel"]
            ),
            aggregatable=AttributionReportingAggregatableResult.from_json(
                json["aggregatable"]
            ),
        )
