#include <LibJS/Runtime/Error.h>
#include <LibJS/Runtime/Object.h>
#include <LibJS/Runtime/PrimitiveString.h>
#include <LibJS/Runtime/VM.h>
#include <LibJS/Runtime/Value.h>
#include <LibJS/Runtime/ValueInlines.h>
#include <LibWeb/Bindings/ExceptionOrUtils.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/PerformanceEntry.h>
#include <LibWeb/Bindings/PerformanceResourceTiming.h>
#include <LibWeb/ResourceTiming/PerformanceResourceTiming.h>
#include <LibWeb/WebIDL/AbstractOperations.h>
#include <LibWeb/WebIDL/Tracing.h>
#include <LibWeb/WebIDL/Types.h>

namespace Web::Bindings {

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

    object.set_prototype(&ensure_web_constructor<PerformanceEntryPrototype>(realm, "PerformanceEntry"_fly_string));
    object.define_direct_property(vm.names.length, JS::Value(0), JS::Attribute::Configurable);
    object.define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "PerformanceResourceTiming"_utf16), JS::Attribute::Configurable);
    object.define_direct_property(vm.names.prototype, &ensure_web_prototype<PerformanceResourceTimingPrototype>(realm, "PerformanceResourceTiming"_fly_string), 0);
}

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

void PerformanceResourceTimingPrototype::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(GC::Ref { ensure_web_prototype<PerformanceEntryPrototype>(realm, "PerformanceEntry"_fly_string) });

    auto initiator_type_id = "initiatorType"_utf16_fly_string;
    auto native_initiator_type_getter = JS::NativeFunction::create(realm, initiator_type_getter, 0, initiator_type_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_initiator_type_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto initiator_type_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(initiator_type_id, native_initiator_type_getter, native_initiator_type_setter, initiator_type_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 delivery_type_id = "deliveryType"_utf16_fly_string;
    auto native_delivery_type_getter = JS::NativeFunction::create(realm, delivery_type_getter, 0, delivery_type_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_delivery_type_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto delivery_type_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(delivery_type_id, native_delivery_type_getter, native_delivery_type_setter, delivery_type_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 next_hop_protocol_id = "nextHopProtocol"_utf16_fly_string;
    auto native_next_hop_protocol_getter = JS::NativeFunction::create(realm, next_hop_protocol_getter, 0, next_hop_protocol_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_next_hop_protocol_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto next_hop_protocol_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(next_hop_protocol_id, native_next_hop_protocol_getter, native_next_hop_protocol_setter, next_hop_protocol_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 worker_start_id = "workerStart"_utf16_fly_string;
    auto native_worker_start_getter = JS::NativeFunction::create(realm, worker_start_getter, 0, worker_start_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_worker_start_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto worker_start_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(worker_start_id, native_worker_start_getter, native_worker_start_setter, worker_start_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 redirect_start_id = "redirectStart"_utf16_fly_string;
    auto native_redirect_start_getter = JS::NativeFunction::create(realm, redirect_start_getter, 0, redirect_start_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_redirect_start_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto redirect_start_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(redirect_start_id, native_redirect_start_getter, native_redirect_start_setter, redirect_start_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 redirect_end_id = "redirectEnd"_utf16_fly_string;
    auto native_redirect_end_getter = JS::NativeFunction::create(realm, redirect_end_getter, 0, redirect_end_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_redirect_end_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto redirect_end_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(redirect_end_id, native_redirect_end_getter, native_redirect_end_setter, redirect_end_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 fetch_start_id = "fetchStart"_utf16_fly_string;
    auto native_fetch_start_getter = JS::NativeFunction::create(realm, fetch_start_getter, 0, fetch_start_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_fetch_start_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto fetch_start_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(fetch_start_id, native_fetch_start_getter, native_fetch_start_setter, fetch_start_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 domain_lookup_start_id = "domainLookupStart"_utf16_fly_string;
    auto native_domain_lookup_start_getter = JS::NativeFunction::create(realm, domain_lookup_start_getter, 0, domain_lookup_start_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_domain_lookup_start_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto domain_lookup_start_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(domain_lookup_start_id, native_domain_lookup_start_getter, native_domain_lookup_start_setter, domain_lookup_start_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 domain_lookup_end_id = "domainLookupEnd"_utf16_fly_string;
    auto native_domain_lookup_end_getter = JS::NativeFunction::create(realm, domain_lookup_end_getter, 0, domain_lookup_end_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_domain_lookup_end_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto domain_lookup_end_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(domain_lookup_end_id, native_domain_lookup_end_getter, native_domain_lookup_end_setter, domain_lookup_end_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 connect_start_id = "connectStart"_utf16_fly_string;
    auto native_connect_start_getter = JS::NativeFunction::create(realm, connect_start_getter, 0, connect_start_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_connect_start_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto connect_start_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(connect_start_id, native_connect_start_getter, native_connect_start_setter, connect_start_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 connect_end_id = "connectEnd"_utf16_fly_string;
    auto native_connect_end_getter = JS::NativeFunction::create(realm, connect_end_getter, 0, connect_end_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_connect_end_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto connect_end_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(connect_end_id, native_connect_end_getter, native_connect_end_setter, connect_end_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 secure_connection_start_id = "secureConnectionStart"_utf16_fly_string;
    auto native_secure_connection_start_getter = JS::NativeFunction::create(realm, secure_connection_start_getter, 0, secure_connection_start_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_secure_connection_start_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto secure_connection_start_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(secure_connection_start_id, native_secure_connection_start_getter, native_secure_connection_start_setter, secure_connection_start_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 request_start_id = "requestStart"_utf16_fly_string;
    auto native_request_start_getter = JS::NativeFunction::create(realm, request_start_getter, 0, request_start_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_request_start_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto request_start_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(request_start_id, native_request_start_getter, native_request_start_setter, request_start_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 final_response_headers_start_id = "finalResponseHeadersStart"_utf16_fly_string;
    auto native_final_response_headers_start_getter = JS::NativeFunction::create(realm, final_response_headers_start_getter, 0, final_response_headers_start_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_final_response_headers_start_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto final_response_headers_start_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(final_response_headers_start_id, native_final_response_headers_start_getter, native_final_response_headers_start_setter, final_response_headers_start_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 first_interim_response_start_id = "firstInterimResponseStart"_utf16_fly_string;
    auto native_first_interim_response_start_getter = JS::NativeFunction::create(realm, first_interim_response_start_getter, 0, first_interim_response_start_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_first_interim_response_start_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto first_interim_response_start_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(first_interim_response_start_id, native_first_interim_response_start_getter, native_first_interim_response_start_setter, first_interim_response_start_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 response_start_id = "responseStart"_utf16_fly_string;
    auto native_response_start_getter = JS::NativeFunction::create(realm, response_start_getter, 0, response_start_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_response_start_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto response_start_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(response_start_id, native_response_start_getter, native_response_start_setter, response_start_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 response_end_id = "responseEnd"_utf16_fly_string;
    auto native_response_end_getter = JS::NativeFunction::create(realm, response_end_getter, 0, response_end_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_response_end_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto response_end_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(response_end_id, native_response_end_getter, native_response_end_setter, response_end_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 transfer_size_id = "transferSize"_utf16_fly_string;
    auto native_transfer_size_getter = JS::NativeFunction::create(realm, transfer_size_getter, 0, transfer_size_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_transfer_size_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto transfer_size_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(transfer_size_id, native_transfer_size_getter, native_transfer_size_setter, transfer_size_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 encoded_body_size_id = "encodedBodySize"_utf16_fly_string;
    auto native_encoded_body_size_getter = JS::NativeFunction::create(realm, encoded_body_size_getter, 0, encoded_body_size_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_encoded_body_size_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto encoded_body_size_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(encoded_body_size_id, native_encoded_body_size_getter, native_encoded_body_size_setter, encoded_body_size_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 decoded_body_size_id = "decodedBodySize"_utf16_fly_string;
    auto native_decoded_body_size_getter = JS::NativeFunction::create(realm, decoded_body_size_getter, 0, decoded_body_size_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_decoded_body_size_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto decoded_body_size_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(decoded_body_size_id, native_decoded_body_size_getter, native_decoded_body_size_setter, decoded_body_size_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 response_status_id = "responseStatus"_utf16_fly_string;
    auto native_response_status_getter = JS::NativeFunction::create(realm, response_status_getter, 0, response_status_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_response_status_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto response_status_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(response_status_id, native_response_status_getter, native_response_status_setter, response_status_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 render_blocking_status_id = "renderBlockingStatus"_utf16_fly_string;
    auto native_render_blocking_status_getter = JS::NativeFunction::create(realm, render_blocking_status_getter, 0, render_blocking_status_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_render_blocking_status_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto render_blocking_status_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(render_blocking_status_id, native_render_blocking_status_getter, native_render_blocking_status_setter, render_blocking_status_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 content_type_id = "contentType"_utf16_fly_string;
    auto native_content_type_getter = JS::NativeFunction::create(realm, content_type_getter, 0, content_type_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_content_type_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto content_type_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(content_type_id, native_content_type_getter, native_content_type_setter, content_type_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.
    object.define_native_function(realm, "toJSON"_utf16_fly_string, to_json, 0, default_attributes);

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

void PerformanceResourceTimingPrototype::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<ResourceTiming::PerformanceResourceTiming*> impl_from(JS::VM& vm, JS::Value js_value)
{

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

[[maybe_unused]] static JS::ThrowCompletionOr<ResourceTiming::PerformanceResourceTiming*> 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(PerformanceResourceTimingPrototype::initiator_type_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::initiator_type_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->initiator_type(); }));

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

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::delivery_type_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::delivery_type_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->delivery_type(); }));

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

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::next_hop_protocol_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::next_hop_protocol_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->next_hop_protocol(); }));

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

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::worker_start_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::worker_start_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->worker_start(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::redirect_start_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::redirect_start_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->redirect_start(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::redirect_end_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::redirect_end_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->redirect_end(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::fetch_start_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::fetch_start_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->fetch_start(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::domain_lookup_start_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::domain_lookup_start_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->domain_lookup_start(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::domain_lookup_end_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::domain_lookup_end_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->domain_lookup_end(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::connect_start_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::connect_start_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->connect_start(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::connect_end_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::connect_end_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->connect_end(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::secure_connection_start_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::secure_connection_start_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->secure_connection_start(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::request_start_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::request_start_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->request_start(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::final_response_headers_start_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::final_response_headers_start_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->final_response_headers_start(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::first_interim_response_start_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::first_interim_response_start_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->first_interim_response_start(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::response_start_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::response_start_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->response_start(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::response_end_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::response_end_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->response_end(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::transfer_size_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::transfer_size_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->transfer_size(); }));

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

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::encoded_body_size_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::encoded_body_size_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->encoded_body_size(); }));

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

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::decoded_body_size_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::decoded_body_size_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->decoded_body_size(); }));

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

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::response_status_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::response_status_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->response_status(); }));

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

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::render_blocking_status_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::render_blocking_status_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->render_blocking_status(); }));

    return JS::PrimitiveString::create(vm, idl_enum_to_string(R));
}

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::content_type_getter)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::content_type_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->content_type(); }));

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

JS_DEFINE_NATIVE_FUNCTION(PerformanceResourceTimingPrototype::to_json)
{
    WebIDL::log_trace(vm, "PerformanceResourceTimingPrototype::to_json");
    auto& realm = *vm.current_realm();

    [[maybe_unused]] auto* idl_object = TRY(impl_from(vm));

    // 4. Let result be OrdinaryObjectCreate(%Object.prototype%).
    auto result = JS::Object::create(realm, realm.intrinsics().object_prototype());

    // 5. For each key → value of map:
    auto name_0_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->name(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto name_0_key = "name"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto name_0_value_js = WebIDL::primitive_string_from_string(vm, name_0_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(name_0_key, name_0_value_js));
    auto entry_type_1_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->entry_type(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto entry_type_1_key = "entryType"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto entry_type_1_value_js = WebIDL::primitive_string_from_string(vm, entry_type_1_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(entry_type_1_key, entry_type_1_value_js));
    auto start_time_2_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->start_time(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto start_time_2_key = "startTime"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto start_time_2_value_js = JS::Value(start_time_2_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(start_time_2_key, start_time_2_value_js));
    auto duration_3_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->duration(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto duration_3_key = "duration"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto duration_3_value_js = JS::Value(duration_3_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(duration_3_key, duration_3_value_js));
    auto initiator_type_4_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->initiator_type(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto initiator_type_4_key = "initiatorType"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto initiator_type_4_value_js = WebIDL::primitive_string_from_string(vm, initiator_type_4_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(initiator_type_4_key, initiator_type_4_value_js));
    auto delivery_type_5_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->delivery_type(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto delivery_type_5_key = "deliveryType"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto delivery_type_5_value_js = WebIDL::primitive_string_from_string(vm, delivery_type_5_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(delivery_type_5_key, delivery_type_5_value_js));
    auto next_hop_protocol_6_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->next_hop_protocol(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto next_hop_protocol_6_key = "nextHopProtocol"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto next_hop_protocol_6_value_js = WebIDL::primitive_string_from_string(vm, next_hop_protocol_6_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(next_hop_protocol_6_key, next_hop_protocol_6_value_js));
    auto worker_start_7_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->worker_start(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto worker_start_7_key = "workerStart"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto worker_start_7_value_js = JS::Value(worker_start_7_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(worker_start_7_key, worker_start_7_value_js));
    auto redirect_start_8_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->redirect_start(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto redirect_start_8_key = "redirectStart"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto redirect_start_8_value_js = JS::Value(redirect_start_8_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(redirect_start_8_key, redirect_start_8_value_js));
    auto redirect_end_9_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->redirect_end(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto redirect_end_9_key = "redirectEnd"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto redirect_end_9_value_js = JS::Value(redirect_end_9_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(redirect_end_9_key, redirect_end_9_value_js));
    auto fetch_start_10_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->fetch_start(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto fetch_start_10_key = "fetchStart"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto fetch_start_10_value_js = JS::Value(fetch_start_10_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(fetch_start_10_key, fetch_start_10_value_js));
    auto domain_lookup_start_11_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->domain_lookup_start(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto domain_lookup_start_11_key = "domainLookupStart"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto domain_lookup_start_11_value_js = JS::Value(domain_lookup_start_11_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(domain_lookup_start_11_key, domain_lookup_start_11_value_js));
    auto domain_lookup_end_12_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->domain_lookup_end(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto domain_lookup_end_12_key = "domainLookupEnd"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto domain_lookup_end_12_value_js = JS::Value(domain_lookup_end_12_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(domain_lookup_end_12_key, domain_lookup_end_12_value_js));
    auto connect_start_13_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->connect_start(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto connect_start_13_key = "connectStart"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto connect_start_13_value_js = JS::Value(connect_start_13_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(connect_start_13_key, connect_start_13_value_js));
    auto connect_end_14_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->connect_end(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto connect_end_14_key = "connectEnd"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto connect_end_14_value_js = JS::Value(connect_end_14_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(connect_end_14_key, connect_end_14_value_js));
    auto secure_connection_start_15_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->secure_connection_start(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto secure_connection_start_15_key = "secureConnectionStart"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto secure_connection_start_15_value_js = JS::Value(secure_connection_start_15_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(secure_connection_start_15_key, secure_connection_start_15_value_js));
    auto request_start_16_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->request_start(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto request_start_16_key = "requestStart"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto request_start_16_value_js = JS::Value(request_start_16_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(request_start_16_key, request_start_16_value_js));
    auto final_response_headers_start_17_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->final_response_headers_start(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto final_response_headers_start_17_key = "finalResponseHeadersStart"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto final_response_headers_start_17_value_js = JS::Value(final_response_headers_start_17_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(final_response_headers_start_17_key, final_response_headers_start_17_value_js));
    auto first_interim_response_start_18_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->first_interim_response_start(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto first_interim_response_start_18_key = "firstInterimResponseStart"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto first_interim_response_start_18_value_js = JS::Value(first_interim_response_start_18_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(first_interim_response_start_18_key, first_interim_response_start_18_value_js));
    auto response_start_19_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->response_start(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto response_start_19_key = "responseStart"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto response_start_19_value_js = JS::Value(response_start_19_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(response_start_19_key, response_start_19_value_js));
    auto response_end_20_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->response_end(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto response_end_20_key = "responseEnd"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto response_end_20_value_js = JS::Value(response_end_20_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(response_end_20_key, response_end_20_value_js));
    auto transfer_size_21_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->transfer_size(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto transfer_size_21_key = "transferSize"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto transfer_size_21_value_js = JS::Value(static_cast<double>(transfer_size_21_value));

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(transfer_size_21_key, transfer_size_21_value_js));
    auto encoded_body_size_22_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->encoded_body_size(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto encoded_body_size_22_key = "encodedBodySize"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto encoded_body_size_22_value_js = JS::Value(static_cast<double>(encoded_body_size_22_value));

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(encoded_body_size_22_key, encoded_body_size_22_value_js));
    auto decoded_body_size_23_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->decoded_body_size(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto decoded_body_size_23_key = "decodedBodySize"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto decoded_body_size_23_value_js = JS::Value(static_cast<double>(decoded_body_size_23_value));

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(decoded_body_size_23_key, decoded_body_size_23_value_js));
    auto response_status_24_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->response_status(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto response_status_24_key = "responseStatus"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto response_status_24_value_js = JS::Value(static_cast<WebIDL::UnsignedShort>(response_status_24_value));

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(response_status_24_key, response_status_24_value_js));
    auto render_blocking_status_25_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->render_blocking_status(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto render_blocking_status_25_key = "renderBlockingStatus"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto render_blocking_status_25_value_js = JS::PrimitiveString::create(vm, idl_enum_to_string(render_blocking_status_25_value));

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(render_blocking_status_25_key, render_blocking_status_25_value_js));
    auto content_type_26_value = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->content_type(); }));

    // 1. Let k be key converted to a JavaScript value.
    auto content_type_26_key = "contentType"_utf16_fly_string;

    // 2. Let v be value converted to a JavaScript value.
    auto content_type_26_value_js = WebIDL::primitive_string_from_string(vm, content_type_26_value);

    // 3. Perform ! CreateDataPropertyOrThrow(result, k, v).
    MUST(result->create_data_property(content_type_26_key, content_type_26_value_js));

    // 6. Return result.
    return result;
}

// https://webidl.spec.whatwg.org/#idl-enumeration
JS::ThrowCompletionOr<RenderBlockingStatusType> convert_to_idl_value_for_render_blocking_status_type(JS::VM& vm, JS::Value value)
{
    // 1. Let S be the result of calling ? ToString(V).
    auto value_as_string = TRY(value.to_utf16_string(vm));

    // 2. If S is not one of E’s enumeration values, then throw a TypeError.
    // 3. Return the enumeration value of type E that is equal to S.
    if (value_as_string == "blocking"sv)
        return RenderBlockingStatusType::Blocking;
    if (value_as_string == "non-blocking"sv)
        return RenderBlockingStatusType::NonBlocking;
    return vm.throw_completion<JS::TypeError>(JS::ErrorType::InvalidEnumerationValue, value_as_string, "RenderBlockingStatusType");
}

// https://webidl.spec.whatwg.org/#idl-enumeration
Utf16String idl_enum_to_string(RenderBlockingStatusType value)
{
    // The result of converting an IDL enumeration type value to a JavaScript value is the String value that represents the same sequence of code units as the enumeration value.
    switch (value) {
    case RenderBlockingStatusType::Blocking:
        return "blocking"_utf16;
    case RenderBlockingStatusType::NonBlocking:
        return "non-blocking"_utf16;
    }
    VERIFY_NOT_REACHED();
}

} // namespace Web::Bindings
