#include <AK/String.h>
#include <AK/TypeCasts.h>
#include <AK/Utf16String.h>
#include <AK/Variant.h>
#include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/ArrayBuffer.h>
#include <LibJS/Runtime/DataView.h>
#include <LibJS/Runtime/Error.h>
#include <LibJS/Runtime/Iterator.h>
#include <LibJS/Runtime/Promise.h>
#include <LibJS/Runtime/TypedArray.h>
#include <LibJS/Runtime/Value.h>
#include <LibJS/Runtime/ValueInlines.h>
#include <LibWeb/Bindings/ExceptionOrUtils.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/MediaKeySystemAccess.h>
#include <LibWeb/Bindings/Navigator.h>
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/Bindings/PrincipalHostDefined.h>
#include <LibWeb/Clipboard/Clipboard.h>
#include <LibWeb/CredentialManagement/CredentialsContainer.h>
#include <LibWeb/DOMURL/URLSearchParams.h>
#include <LibWeb/FileAPI/Blob.h>
#include <LibWeb/Gamepad/Gamepad.h>
#include <LibWeb/Geolocation/Geolocation.h>
#include <LibWeb/HTML/MimeTypeArray.h>
#include <LibWeb/HTML/Navigator.h>
#include <LibWeb/HTML/PluginArray.h>
#include <LibWeb/HTML/UniversalGlobalScope.h>
#include <LibWeb/HTML/UserActivation.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/MediaCapabilitiesAPI/MediaCapabilities.h>
#include <LibWeb/MediaCapture/MediaDevices.h>
#include <LibWeb/PermissionsAPI/Permissions.h>
#include <LibWeb/Serial/Serial.h>
#include <LibWeb/ServiceWorker/ServiceWorkerContainer.h>
#include <LibWeb/StorageAPI/StorageManager.h>
#include <LibWeb/Streams/ReadableStream.h>
#include <LibWeb/WebIDL/AbstractOperations.h>
#include <LibWeb/WebIDL/Promise.h>
#include <LibWeb/WebIDL/Tracing.h>
#include <LibWeb/WebIDL/Types.h>
#include <LibWeb/WebLocks/LockManager.h>
#include <LibWeb/WebXR/XRSystem.h>
#include <LibWeb/XHR/FormData.h>

namespace Web::Bindings {

void NavigatorConstructor::initialize(JS::Realm& realm, JS::NativeFunction& object)
{
    auto& vm = realm.vm();
    [[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable;

    
    object.define_direct_property(vm.names.length, JS::Value(0), JS::Attribute::Configurable);
    object.define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "Navigator"_utf16), JS::Attribute::Configurable);
    object.define_direct_property(vm.names.prototype, &ensure_web_prototype<NavigatorPrototype>(realm, "Navigator"_fly_string), 0);
}

JS::ThrowCompletionOr<GC::Ref<JS::Object>> NavigatorConstructor::construct([[maybe_unused]] InterfaceConstructor& constructor, [[maybe_unused]] JS::FunctionObject& new_target)
{
    WebIDL::log_trace(constructor.vm(), "NavigatorConstructor::construct");
    return constructor.vm().throw_completion<JS::TypeError>(JS::ErrorType::NotAConstructor, "Navigator");
}

void NavigatorPrototype::initialize(JS::Realm& realm, JS::Object& object)
{
    [[maybe_unused]] auto& vm = realm.vm();
    [[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable | JS::Attribute::Configurable | JS::Attribute::Writable;

    object.set_prototype(realm.intrinsics().object_prototype());

    if (HTML::is_secure_context(Bindings::principal_host_defined_environment_settings_object(realm))) {
        auto clipboard_id = "clipboard"_utf16_fly_string;
        auto native_clipboard_getter = JS::NativeFunction::create(realm, clipboard_getter, 0, clipboard_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_clipboard_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto clipboard_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(clipboard_id, native_clipboard_getter, native_clipboard_setter, clipboard_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    auto geolocation_id = "geolocation"_utf16_fly_string;
    auto native_geolocation_getter = JS::NativeFunction::create(realm, geolocation_getter, 0, geolocation_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_geolocation_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto geolocation_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(geolocation_id, native_geolocation_getter, native_geolocation_setter, geolocation_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto max_touch_points_id = "maxTouchPoints"_utf16_fly_string;
    auto native_max_touch_points_getter = JS::NativeFunction::create(realm, max_touch_points_getter, 0, max_touch_points_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_max_touch_points_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto max_touch_points_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(max_touch_points_id, native_max_touch_points_getter, native_max_touch_points_setter, max_touch_points_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto serial_id = "serial"_utf16_fly_string;
    auto native_serial_getter = JS::NativeFunction::create(realm, serial_getter, 0, serial_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_serial_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto serial_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(serial_id, native_serial_getter, native_serial_setter, serial_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto user_activation_id = "userActivation"_utf16_fly_string;
    auto native_user_activation_getter = JS::NativeFunction::create(realm, user_activation_getter, 0, user_activation_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_user_activation_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto user_activation_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(user_activation_id, native_user_activation_getter, native_user_activation_setter, user_activation_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    if (HTML::is_secure_context(Bindings::principal_host_defined_environment_settings_object(realm))) {
        auto service_worker_id = "serviceWorker"_utf16_fly_string;
        auto native_service_worker_getter = JS::NativeFunction::create(realm, service_worker_getter, 0, service_worker_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_service_worker_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto service_worker_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(service_worker_id, native_service_worker_getter, native_service_worker_setter, service_worker_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    auto media_capabilities_id = "mediaCapabilities"_utf16_fly_string;
    auto native_media_capabilities_getter = JS::NativeFunction::create(realm, media_capabilities_getter, 0, media_capabilities_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_media_capabilities_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto media_capabilities_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(media_capabilities_id, native_media_capabilities_getter, native_media_capabilities_setter, media_capabilities_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    if (HTML::is_secure_context(Bindings::principal_host_defined_environment_settings_object(realm))) {
        auto media_devices_id = "mediaDevices"_utf16_fly_string;
        auto native_media_devices_getter = JS::NativeFunction::create(realm, media_devices_getter, 0, media_devices_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_media_devices_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto media_devices_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(media_devices_id, native_media_devices_getter, native_media_devices_setter, media_devices_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    if (HTML::is_secure_context(Bindings::principal_host_defined_environment_settings_object(realm))) {
        auto credentials_id = "credentials"_utf16_fly_string;
        auto native_credentials_getter = JS::NativeFunction::create(realm, credentials_getter, 0, credentials_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_credentials_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto credentials_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(credentials_id, native_credentials_getter, native_credentials_setter, credentials_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    if (HTML::is_secure_context(Bindings::principal_host_defined_environment_settings_object(realm))) {
        auto xr_id = "xr"_utf16_fly_string;
        auto native_xr_getter = JS::NativeFunction::create(realm, xr_getter, 0, xr_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_xr_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto xr_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(xr_id, native_xr_getter, native_xr_setter, xr_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    if (HTML::UniversalGlobalScopeMixin::expose_experimental_interfaces()) {
        auto permissions_id = "permissions"_utf16_fly_string;
        auto native_permissions_getter = JS::NativeFunction::create(realm, permissions_getter, 0, permissions_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_permissions_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto permissions_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(permissions_id, native_permissions_getter, native_permissions_setter, permissions_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    auto global_privacy_control_id = "globalPrivacyControl"_utf16_fly_string;
    auto native_global_privacy_control_getter = JS::NativeFunction::create(realm, global_privacy_control_getter, 0, global_privacy_control_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_global_privacy_control_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto global_privacy_control_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(global_privacy_control_id, native_global_privacy_control_getter, native_global_privacy_control_setter, global_privacy_control_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto app_code_name_id = "appCodeName"_utf16_fly_string;
    auto native_app_code_name_getter = JS::NativeFunction::create(realm, app_code_name_getter, 0, app_code_name_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_app_code_name_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto app_code_name_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(app_code_name_id, native_app_code_name_getter, native_app_code_name_setter, app_code_name_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto app_name_id = "appName"_utf16_fly_string;
    auto native_app_name_getter = JS::NativeFunction::create(realm, app_name_getter, 0, app_name_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_app_name_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto app_name_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(app_name_id, native_app_name_getter, native_app_name_setter, app_name_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto app_version_id = "appVersion"_utf16_fly_string;
    auto native_app_version_getter = JS::NativeFunction::create(realm, app_version_getter, 0, app_version_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_app_version_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto app_version_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(app_version_id, native_app_version_getter, native_app_version_setter, app_version_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto platform_id = "platform"_utf16_fly_string;
    auto native_platform_getter = JS::NativeFunction::create(realm, platform_getter, 0, platform_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_platform_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto platform_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(platform_id, native_platform_getter, native_platform_setter, platform_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto product_id = "product"_utf16_fly_string;
    auto native_product_getter = JS::NativeFunction::create(realm, product_getter, 0, product_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_product_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto product_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(product_id, native_product_getter, native_product_setter, product_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    if (is<HTML::Window>(realm.global_object())) {
        auto product_sub_id = "productSub"_utf16_fly_string;
        auto native_product_sub_getter = JS::NativeFunction::create(realm, product_sub_getter, 0, product_sub_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_product_sub_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto product_sub_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(product_sub_id, native_product_sub_getter, native_product_sub_setter, product_sub_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    auto user_agent_id = "userAgent"_utf16_fly_string;
    auto native_user_agent_getter = JS::NativeFunction::create(realm, user_agent_getter, 0, user_agent_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_user_agent_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto user_agent_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(user_agent_id, native_user_agent_getter, native_user_agent_setter, user_agent_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    if (is<HTML::Window>(realm.global_object())) {
        auto vendor_id = "vendor"_utf16_fly_string;
        auto native_vendor_getter = JS::NativeFunction::create(realm, vendor_getter, 0, vendor_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_vendor_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto vendor_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(vendor_id, native_vendor_getter, native_vendor_setter, vendor_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    if (is<HTML::Window>(realm.global_object())) {
        auto vendor_sub_id = "vendorSub"_utf16_fly_string;
        auto native_vendor_sub_getter = JS::NativeFunction::create(realm, vendor_sub_getter, 0, vendor_sub_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_vendor_sub_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto vendor_sub_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(vendor_sub_id, native_vendor_sub_getter, native_vendor_sub_setter, vendor_sub_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    auto language_id = "language"_utf16_fly_string;
    auto native_language_getter = JS::NativeFunction::create(realm, language_getter, 0, language_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_language_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto language_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(language_id, native_language_getter, native_language_setter, language_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto languages_id = "languages"_utf16_fly_string;
    auto native_languages_getter = JS::NativeFunction::create(realm, languages_getter, 0, languages_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_languages_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto languages_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(languages_id, native_languages_getter, native_languages_setter, languages_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto on_line_id = "onLine"_utf16_fly_string;
    auto native_on_line_getter = JS::NativeFunction::create(realm, on_line_getter, 0, on_line_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_on_line_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto on_line_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(on_line_id, native_on_line_getter, native_on_line_setter, on_line_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto cookie_enabled_id = "cookieEnabled"_utf16_fly_string;
    auto native_cookie_enabled_getter = JS::NativeFunction::create(realm, cookie_enabled_getter, 0, cookie_enabled_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_cookie_enabled_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto cookie_enabled_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(cookie_enabled_id, native_cookie_enabled_getter, native_cookie_enabled_setter, cookie_enabled_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto plugins_id = "plugins"_utf16_fly_string;
    auto native_plugins_getter = JS::NativeFunction::create(realm, plugins_getter, 0, plugins_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_plugins_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto plugins_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(plugins_id, native_plugins_getter, native_plugins_setter, plugins_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto mime_types_id = "mimeTypes"_utf16_fly_string;
    auto native_mime_types_getter = JS::NativeFunction::create(realm, mime_types_getter, 0, mime_types_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_mime_types_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto mime_types_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(mime_types_id, native_mime_types_getter, native_mime_types_setter, mime_types_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto pdf_viewer_enabled_id = "pdfViewerEnabled"_utf16_fly_string;
    auto native_pdf_viewer_enabled_getter = JS::NativeFunction::create(realm, pdf_viewer_enabled_getter, 0, pdf_viewer_enabled_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_pdf_viewer_enabled_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto pdf_viewer_enabled_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(pdf_viewer_enabled_id, native_pdf_viewer_enabled_getter, native_pdf_viewer_enabled_setter, pdf_viewer_enabled_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto hardware_concurrency_id = "hardwareConcurrency"_utf16_fly_string;
    auto native_hardware_concurrency_getter = JS::NativeFunction::create(realm, hardware_concurrency_getter, 0, hardware_concurrency_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_hardware_concurrency_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto hardware_concurrency_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(hardware_concurrency_id, native_hardware_concurrency_getter, native_hardware_concurrency_setter, hardware_concurrency_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto webdriver_id = "webdriver"_utf16_fly_string;
    auto native_webdriver_getter = JS::NativeFunction::create(realm, webdriver_getter, 0, webdriver_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_webdriver_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto webdriver_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(webdriver_id, native_webdriver_getter, native_webdriver_setter, webdriver_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    if (HTML::is_secure_context(Bindings::principal_host_defined_environment_settings_object(realm))) {
        auto storage_id = "storage"_utf16_fly_string;
        auto native_storage_getter = JS::NativeFunction::create(realm, storage_getter, 0, storage_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_storage_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto storage_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(storage_id, native_storage_getter, native_storage_setter, storage_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    if (HTML::is_secure_context(Bindings::principal_host_defined_environment_settings_object(realm))) {
        auto locks_id = "locks"_utf16_fly_string;
        auto native_locks_getter = JS::NativeFunction::create(realm, locks_getter, 0, locks_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_locks_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto locks_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(locks_id, native_locks_getter, native_locks_setter, locks_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    if (HTML::is_secure_context(Bindings::principal_host_defined_environment_settings_object(realm))) {
        auto device_memory_id = "deviceMemory"_utf16_fly_string;
        auto native_device_memory_getter = JS::NativeFunction::create(realm, device_memory_getter, 0, device_memory_id, &realm, "get"sv);
        GC::Ptr<JS::NativeFunction> native_device_memory_setter;
    
        // 4. Let configurable be false if attr is unforgeable and true otherwise.
        auto device_memory_attributes = default_attributes;
    
        // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.
    
        // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
        object.define_direct_accessor(device_memory_id, native_device_memory_getter, native_device_memory_setter, device_memory_attributes);
    
        // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
        }
    if (HTML::UniversalGlobalScopeMixin::expose_experimental_interfaces()) {
        if (HTML::is_secure_context(Bindings::principal_host_defined_environment_settings_object(realm))) {
            object.define_native_function(realm, "getBattery"_utf16_fly_string, get_battery, 0, default_attributes);
        
            }
        }
    if (is<HTML::Window>(realm.global_object())) {
        if (HTML::is_secure_context(Bindings::principal_host_defined_environment_settings_object(realm))) {
            object.define_native_function(realm, "requestMediaKeySystemAccess"_utf16_fly_string, request_media_key_system_access, 2, default_attributes);
        
            }
        }
    if (is<HTML::Window>(realm.global_object())) {
        object.define_native_function(realm, "getGamepads"_utf16_fly_string, get_gamepads, 0, default_attributes);
    
        }
    object.define_native_function(realm, "sendBeacon"_utf16_fly_string, send_beacon, 1, default_attributes);

    object.define_native_function(realm, "javaEnabled"_utf16_fly_string, java_enabled, 0, default_attributes);

    object.define_direct_property("registerProtocolHandler"_utf16_fly_string, JS::js_undefined(), default_attributes | JS::Attribute::Unimplemented);

    object.define_direct_property("unregisterProtocolHandler"_utf16_fly_string, JS::js_undefined(), default_attributes | JS::Attribute::Unimplemented);

    object.define_direct_property(vm.well_known_symbol_to_string_tag(), JS::PrimitiveString::create(vm, "Navigator"_utf16), JS::Attribute::Configurable);
}

void NavigatorPrototype::define_unforgeable_attributes(JS::Realm& realm, [[maybe_unused]] JS::Object& object)
{
    [[maybe_unused]] auto& vm = realm.vm();
    [[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable;
}

[[maybe_unused]] static JS::ThrowCompletionOr<HTML::Navigator*> impl_from(JS::VM& vm, JS::Value js_value)
{

    if (auto impl = js_value.as_if<HTML::Navigator>())
        return impl.ptr();
    return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Navigator");
}

[[maybe_unused]] static JS::ThrowCompletionOr<HTML::Navigator*> impl_from(JS::VM& vm)
{
    auto this_value = vm.this_value();
    if (this_value.is_nullish())
        this_value = &vm.current_realm()->global_object();
    return impl_from(vm, this_value);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::clipboard_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::clipboard_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->clipboard(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::geolocation_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::geolocation_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->geolocation(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::max_touch_points_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::max_touch_points_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->max_touch_points(); }));

    return JS::Value(static_cast<WebIDL::Long>(R));
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::serial_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::serial_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->serial(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::user_activation_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::user_activation_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->user_activation(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::service_worker_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::service_worker_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->service_worker(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::media_capabilities_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::media_capabilities_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->media_capabilities(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::media_devices_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::media_devices_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->media_devices(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::credentials_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::credentials_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->credentials(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::xr_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::xr_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->xr(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::permissions_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::permissions_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->permissions(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::global_privacy_control_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::global_privacy_control_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->global_privacy_control(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::app_code_name_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::app_code_name_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->app_code_name(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::app_name_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::app_name_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->app_name(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::app_version_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::app_version_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->app_version(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::platform_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::platform_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->platform(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::product_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::product_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->product(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::product_sub_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::product_sub_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->product_sub(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::user_agent_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::user_agent_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->user_agent(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::vendor_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::vendor_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->vendor(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::vendor_sub_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::vendor_sub_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->vendor_sub(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::language_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::language_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->language(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::languages_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::languages_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->languages(); }));

    return [&]() -> JS::Value {
        // An IDL sequence<T> value S is converted to a JavaScript value as follows:
        // 1. Let n be the length of S.
        auto sequence_length = R.size();

        // 2. Let A be a new Array object created as if by the expression [].
        auto sequence_array = MUST(JS::Array::create(realm, sequence_length));

        // 3. Initialize i to be 0.
        // 4. While i < n:
        for (size_t sequence_index = 0; sequence_index < sequence_length; ++sequence_index) {
            // 1. Let V be the value in S at index i.
            auto& sequence_element = R.at(sequence_index);

            // 2. Let E be the result of converting V to a JavaScript value.
            JS::Value js_sequence_element = WebIDL::primitive_string_from_string(vm, sequence_element);

            // 3. Let P be the result of calling ! ToString(i).
            // 4. Perform ! CreateDataPropertyOrThrow(A, P, E).
            MUST(sequence_array->create_data_property(JS::PropertyKey { sequence_index }, js_sequence_element));

            // 5. Set i to i + 1.
        }

        MUST(sequence_array->set_integrity_level(JS::Object::IntegrityLevel::Frozen));

        // 5. Return A.
        return sequence_array;
    }();
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::on_line_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::on_line_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->on_line(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::cookie_enabled_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::cookie_enabled_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->cookie_enabled(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::plugins_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::plugins_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->plugins(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::mime_types_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::mime_types_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->mime_types(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::pdf_viewer_enabled_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::pdf_viewer_enabled_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->pdf_viewer_enabled(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::hardware_concurrency_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::hardware_concurrency_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->hardware_concurrency(); }));

    return JS::Value(static_cast<double>(R));
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::webdriver_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::webdriver_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->webdriver(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::storage_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::storage_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->storage(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::locks_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::locks_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->locks(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::device_memory_getter)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::device_memory_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->device_memory(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::get_battery)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::get_battery");
    [[maybe_unused]] auto& realm = *vm.current_realm();
    auto steps = [&realm, &vm]() -> JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> {
        (void)realm;
    [[maybe_unused]] HTML::Navigator* idl_object = TRY(impl_from(vm));

    [[maybe_unused]] auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->get_battery(); }));
        return R;
    };

    auto maybe_R = steps();

    // And then, if an exception E was thrown:
    // 1. If op has a return type that is a promise type, then return ! Call(%Promise.reject%, %Promise%, «E»).
    // 2. Otherwise, end these steps and allow the exception to propagate.
    if (maybe_R.is_throw_completion())
        return WebIDL::create_rejected_promise(realm, maybe_R.error_value())->promise();

    return GC::Ref { as<JS::Promise>(*maybe_R.release_value()->promise()) };
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::request_media_key_system_access)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::request_media_key_system_access");
    [[maybe_unused]] auto& realm = *vm.current_realm();
    auto steps = [&realm, &vm]() -> JS::ThrowCompletionOr<GC::Ref<WebIDL::Promise>> {
        (void)realm;
    [[maybe_unused]] HTML::Navigator* idl_object = TRY(impl_from(vm));

    if (vm.argument_count() < 2)
        return vm.throw_completion<JS::TypeError>(JS::ErrorType::BadArgCountMany, "requestMediaKeySystemAccess", "2");

    auto arg0 = vm.argument(0);
    auto key_system = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<Utf16String> {
        return TRY(WebIDL::to_utf16_string(vm, arg0));
    }(); }));

    auto arg1 = vm.argument(1);
    auto supported_configurations = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<Vector<MediaKeySystemConfiguration>> {
        if (!arg1.is_object())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObject, arg1);

        auto method = TRY(arg1.get_method(vm, vm.well_known_symbol_iterator()));
        if (!method)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotIterable, arg1);

        return TRY([&]() -> JS::ThrowCompletionOr<Vector<MediaKeySystemConfiguration>> {
        // To create an IDL value of type sequence<T> given an iterable iterable and an iterator getter method, perform the following steps:
        // 1. Let iteratorRecord be ? GetIteratorFromMethod(iterable, method).
        auto iterator = TRY(JS::get_iterator_from_method(vm, arg1, *method));

        Vector<MediaKeySystemConfiguration> sequence;

        // 2. Initialize i to be 0.
        // 3. Repeat
        for (;;) {
            // 1. Let next be ? IteratorStepValue(iteratorRecord).
            auto next = TRY(JS::iterator_step_value(vm, iterator));

            // 2. If next is done, then return an IDL sequence value of type sequence<T> of length i, where the value of the element at index j is Sj.
            if (!next.has_value())
                break;

            // 3. Initialize Si to the result of converting next to an IDL value of type T.
            auto next_value = next.release_value();
            auto sequence_item = TRY(throw_dom_exception_if_needed(vm, [&] { return convert_to_idl_value_for_media_key_system_configuration(vm, next_value); }));

            // 4. Set i to i + 1.
            sequence.append(sequence_item);
        }

        return sequence;
    }());
    }(); }));

    [[maybe_unused]] auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->request_media_key_system_access(key_system, supported_configurations); }));
        return R;
    };

    auto maybe_R = steps();

    // And then, if an exception E was thrown:
    // 1. If op has a return type that is a promise type, then return ! Call(%Promise.reject%, %Promise%, «E»).
    // 2. Otherwise, end these steps and allow the exception to propagate.
    if (maybe_R.is_throw_completion())
        return WebIDL::create_rejected_promise(realm, maybe_R.error_value())->promise();

    return GC::Ref { as<JS::Promise>(*maybe_R.release_value()->promise()) };
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::get_gamepads)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::get_gamepads");
    [[maybe_unused]] auto& realm = *vm.current_realm();
    [[maybe_unused]] HTML::Navigator* idl_object = TRY(impl_from(vm));

    [[maybe_unused]] auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->get_gamepads(); }));
    return [&]() -> JS::Value {
        // An IDL sequence<T> value S is converted to a JavaScript value as follows:
        // 1. Let n be the length of S.
        auto sequence_length = R.size();

        // 2. Let A be a new Array object created as if by the expression [].
        auto sequence_array = MUST(JS::Array::create(realm, sequence_length));

        // 3. Initialize i to be 0.
        // 4. While i < n:
        for (size_t sequence_index = 0; sequence_index < sequence_length; ++sequence_index) {
            // 1. Let V be the value in S at index i.
            auto& sequence_element = R.at(sequence_index);

            // 2. Let E be the result of converting V to a JavaScript value.
            JS::Value js_sequence_element = [&]() -> JS::Value {
        // 1. If the IDL nullable type T? value is null, then the JavaScript value is null.
        if (!sequence_element)
            return JS::js_null();

        // 2. Otherwise, the JavaScript value is the result of converting the IDL nullable type value to the inner IDL type T.
        return JS::Value(JS::Value(sequence_element));
    }();

            // 3. Let P be the result of calling ! ToString(i).
            // 4. Perform ! CreateDataPropertyOrThrow(A, P, E).
            MUST(sequence_array->create_data_property(JS::PropertyKey { sequence_index }, js_sequence_element));

            // 5. Set i to i + 1.
        }

        // 5. Return A.
        return sequence_array;
    }();
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::send_beacon)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::send_beacon");
    [[maybe_unused]] auto& realm = *vm.current_realm();
    [[maybe_unused]] HTML::Navigator* idl_object = TRY(impl_from(vm));

    if (vm.argument_count() < 1)
        return vm.throw_completion<JS::TypeError>(JS::ErrorType::BadArgCountOne, "sendBeacon");

    auto arg0 = vm.argument(0);
    auto url = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, arg0));
    }(); }));

    auto arg1 = vm.argument(1);
    Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String, Empty> data = Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String, Empty> { Empty {} };
    if (!arg1.is_undefined())
        data = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String, Empty>> {
        Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String, Empty> value;

        if (!arg1.is_nullish()) {

            value = TRY([&]() -> JS::ThrowCompletionOr<Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String>> {

        if (arg1.is_object()) {
            [[maybe_unused]] auto& object = arg1.as_object();

            if (is<PlatformObject>(object)) {

                if (auto* result = as_if<Streams::ReadableStream>(object))
                    return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { GC::Ref { *result } };

                if (auto* result = as_if<FileAPI::Blob>(object))
                    return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { GC::Ref { *result } };

                if (auto* result = as_if<XHR::FormData>(object))
                    return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { GC::Ref { *result } };

                if (auto* result = as_if<DOMURL::URLSearchParams>(object))
                    return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { GC::Ref { *result } };
            }

            if (auto* array_buffer = as_if<JS::ArrayBuffer>(object)) {
                if (!array_buffer->is_shared_array_buffer()) {
                    // 1. If types includes ArrayBuffer, then return the result of converting V to ArrayBuffer.
                    auto array_buffer_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::ArrayBuffer>> {
        // A JavaScript value V is converted to an IDL ArrayBuffer value by running the following algorithm:
        // 1. If V is not an Object, or V does not have an [[ArrayBufferData]] internal slot, then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::ArrayBuffer>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "ArrayBuffer");

        // 2. If IsSharedArrayBuffer(V) is true, then throw a TypeError.
        if (builtin_buffer->is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V) is false, then throw a TypeError.
        if (!builtin_buffer->is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length ArrayBuffer");

        // 4. Return the IDL ArrayBuffer value that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                    return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { array_buffer_union_type };
                }
            }

            if (as_if<JS::DataView>(object)) {
                // 1. If types includes DataView, then return the result of converting V to DataView.
                auto data_view_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::DataView>> {
        // A JavaScript value V is converted to an IDL DataView value by running the following algorithm:
        // 1. If V is not an Object, or V does not have a [[DataView]] internal slot, then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::DataView>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "DataView");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length DataView");

        // 4. Return the IDL DataView value that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { data_view_union_type };
            }

            if (as_if<JS::Int8Array>(object)) {
                auto int8_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::Int8Array>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::Int8Array>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Int8Array");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length Int8Array");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { int8_array_union_type };
            }

            if (as_if<JS::Int16Array>(object)) {
                auto int16_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::Int16Array>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::Int16Array>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Int16Array");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length Int16Array");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { int16_array_union_type };
            }

            if (as_if<JS::Int32Array>(object)) {
                auto int32_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::Int32Array>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::Int32Array>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Int32Array");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length Int32Array");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { int32_array_union_type };
            }

            if (as_if<JS::Uint8Array>(object)) {
                auto uint8_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::Uint8Array>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::Uint8Array>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Uint8Array");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length Uint8Array");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { uint8_array_union_type };
            }

            if (as_if<JS::Uint16Array>(object)) {
                auto uint16_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::Uint16Array>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::Uint16Array>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Uint16Array");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length Uint16Array");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { uint16_array_union_type };
            }

            if (as_if<JS::Uint32Array>(object)) {
                auto uint32_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::Uint32Array>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::Uint32Array>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Uint32Array");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length Uint32Array");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { uint32_array_union_type };
            }

            if (as_if<JS::Uint8ClampedArray>(object)) {
                auto uint8_clamped_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::Uint8ClampedArray>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::Uint8ClampedArray>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Uint8ClampedArray");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length Uint8ClampedArray");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { uint8_clamped_array_union_type };
            }

            if (as_if<JS::BigInt64Array>(object)) {
                auto big_int64_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::BigInt64Array>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::BigInt64Array>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BigInt64Array");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length BigInt64Array");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { big_int64_array_union_type };
            }

            if (as_if<JS::BigUint64Array>(object)) {
                auto big_uint64_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::BigUint64Array>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::BigUint64Array>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "BigUint64Array");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length BigUint64Array");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { big_uint64_array_union_type };
            }

            if (as_if<JS::Float16Array>(object)) {
                auto float16_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::Float16Array>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::Float16Array>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Float16Array");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length Float16Array");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { float16_array_union_type };
            }

            if (as_if<JS::Float32Array>(object)) {
                auto float32_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::Float32Array>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::Float32Array>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Float32Array");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length Float32Array");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { float32_array_union_type };
            }

            if (as_if<JS::Float64Array>(object)) {
                auto float64_array_union_type = TRY([&]() -> JS::ThrowCompletionOr<GC::Ref<JS::Float64Array>> {
        // A JavaScript value V is converted to an IDL typed array value by running the following algorithm:
        // 1. Let T be the IDL type V is being converted to.
        // 2. If V is not an Object, or V does not have a [[TypedArrayName]] internal slot with a value equal to T's name,
        //    then throw a TypeError.
        auto builtin_buffer = arg1.as_if<JS::Float64Array>();
        if (!builtin_buffer)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Float64Array");

        auto& viewed_array_buffer = *builtin_buffer->viewed_array_buffer();

        // 2. If the conversion is not to an IDL type associated with the [AllowShared] extended attribute, and
        //    IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, then throw a TypeError.
        if (viewed_array_buffer.is_shared_array_buffer())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::SharedArrayBuffer);

        // 3. If the conversion is not to an IDL type associated with the [AllowResizable] extended attribute, and
        //    IsFixedLengthArrayBuffer(V.[[ViewedArrayBuffer]]) is false, then throw a TypeError.
        if (!viewed_array_buffer.is_fixed_length())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "fixed-length Float64Array");

        // 5. Return the IDL value of type T that is a reference to the same object as V.
        return GC::Ref { *builtin_buffer };
    }());
                return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { float64_array_union_type };
            }
        }

        auto data_string = TRY([&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, arg1));
    }());
        return Variant<GC::Ref<Streams::ReadableStream>, GC::Ref<FileAPI::Blob>, GC::Ref<JS::Int8Array>, GC::Ref<JS::Int16Array>, GC::Ref<JS::Int32Array>, GC::Ref<JS::Uint8Array>, GC::Ref<JS::Uint16Array>, GC::Ref<JS::Uint32Array>, GC::Ref<JS::Uint8ClampedArray>, GC::Ref<JS::BigInt64Array>, GC::Ref<JS::BigUint64Array>, GC::Ref<JS::Float16Array>, GC::Ref<JS::Float32Array>, GC::Ref<JS::Float64Array>, GC::Ref<JS::DataView>, GC::Ref<JS::ArrayBuffer>, GC::Ref<XHR::FormData>, GC::Ref<DOMURL::URLSearchParams>, String> { data_string };

        return vm.throw_completion<JS::TypeError>("No union types matched"_utf16);
    }());
        }
        return value;
    }(); }));

    [[maybe_unused]] auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->send_beacon(url, data); }));
    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(NavigatorPrototype::java_enabled)
{
    WebIDL::log_trace(vm, "NavigatorPrototype::java_enabled");
    [[maybe_unused]] auto& realm = *vm.current_realm();
    [[maybe_unused]] HTML::Navigator* idl_object = TRY(impl_from(vm));

    [[maybe_unused]] auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->java_enabled(); }));
    return JS::Value(R);
}

} // namespace Web::Bindings
