src/lightspeed@component@template_ergonomics.erl

-module(lightspeed@component@template_ergonomics).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/component/template_ergonomics.gleam").
-export([attr_alias/3, slot_default/2, slot_default_html/2, ergonomic_schema/3, routine_schema/5, string_attr/2, int_attr/2, bool_attr/2, slot/2, slot_html/2, optional_string/3, optional_int/3, optional_bool/3, required_slot_html/2, slot_html_or_empty/2, compile/3, diagnostic_label/1, diagnostics_signature/1, signature/1, html/1, fingerprint/1, compiled_template/1, applied_aliases/1, applied_slot_defaults/1]).
-export_type([attr_alias/0, slot_default/0, ergonomic_schema/2, diagnostic/0, compiled/2]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

?MODULEDOC(" Template ergonomics helpers and migration-hint diagnostics for M39.\n").

-type attr_alias() :: {attr_alias, binary(), binary(), binary()}.

-type slot_default() :: {slot_default,
        binary(),
        lightspeed@component:rendered()}.

-type ergonomic_schema(IZJ, IZK) :: {ergonomic_schema,
        lightspeed@component@template_compiler:schema(IZJ, IZK),
        list(attr_alias()),
        list(slot_default())}.

-type diagnostic() :: {diagnostic, binary(), binary(), binary()}.

-type compiled(IZL, IZM) :: {compiled,
        lightspeed@component@template_compiler:compiled_template(IZL, IZM),
        list({binary(), binary()}),
        list(binary()),
        binary()}.

-file("src/lightspeed/component/template_ergonomics.gleam", 44).
?DOC(" Build one attr alias.\n").
-spec attr_alias(binary(), binary(), binary()) -> attr_alias().
attr_alias(Alias, Canonical, Migration_hint) ->
    {attr_alias, Alias, Canonical, Migration_hint}.

-file("src/lightspeed/component/template_ergonomics.gleam", 53).
?DOC(" Build one slot default from rendered content.\n").
-spec slot_default(binary(), lightspeed@component:rendered()) -> slot_default().
slot_default(Name, Rendered) ->
    {slot_default, Name, Rendered}.

-file("src/lightspeed/component/template_ergonomics.gleam", 58).
?DOC(" Build one slot default from raw HTML.\n").
-spec slot_default_html(binary(), binary()) -> slot_default().
slot_default_html(Name, Html) ->
    {slot_default, Name, lightspeed@component:html(Html)}.

-file("src/lightspeed/component/template_ergonomics.gleam", 63).
?DOC(" Build ergonomic schema wrapper.\n").
-spec ergonomic_schema(
    lightspeed@component@template_compiler:schema(IZN, IZO),
    list(attr_alias()),
    list(slot_default())
) -> ergonomic_schema(IZN, IZO).
ergonomic_schema(Schema, Attr_aliases, Slot_defaults) ->
    {ergonomic_schema, Schema, Attr_aliases, Slot_defaults}.

-file("src/lightspeed/component/template_ergonomics.gleam", 76).
?DOC(" Build one routine schema that uses automatic slot passthrough.\n").
-spec routine_schema(
    binary(),
    list(lightspeed@component@template_compiler:attr_schema()),
    list(lightspeed@component@template_compiler:slot_schema()),
    fun((list({binary(), lightspeed@component@template_compiler:attr_value()})) -> {ok,
            IZY} |
        {error, binary()}),
    fun((IZY, list({binary(), lightspeed@component:rendered()})) -> lightspeed@component:rendered())
) -> lightspeed@component@template_compiler:schema(IZY, list({binary(),
    lightspeed@component:rendered()})).
routine_schema(Name, Attrs, Slots, Build_assigns, Render) ->
    lightspeed@component@template_compiler:schema(
        Name,
        Attrs,
        Slots,
        Build_assigns,
        fun(Value) -> {ok, Value} end,
        lightspeed@component@template:function(
            fun(Assigns, Slots@1) -> Render(Assigns, Slots@1) end
        )
    ).

-file("src/lightspeed/component/template_ergonomics.gleam", 95).
?DOC(" Convenience constructor for string attr input.\n").
-spec string_attr(binary(), binary()) -> {binary(),
    lightspeed@component@template_compiler:attr_value()}.
string_attr(Name, Value) ->
    {Name, {string_attr, Value}}.

-file("src/lightspeed/component/template_ergonomics.gleam", 103).
?DOC(" Convenience constructor for int attr input.\n").
-spec int_attr(binary(), integer()) -> {binary(),
    lightspeed@component@template_compiler:attr_value()}.
int_attr(Name, Value) ->
    {Name, {int_attr, Value}}.

-file("src/lightspeed/component/template_ergonomics.gleam", 111).
?DOC(" Convenience constructor for bool attr input.\n").
-spec bool_attr(binary(), boolean()) -> {binary(),
    lightspeed@component@template_compiler:attr_value()}.
bool_attr(Name, Value) ->
    {Name, {bool_attr, Value}}.

-file("src/lightspeed/component/template_ergonomics.gleam", 119).
?DOC(" Convenience constructor for slot input.\n").
-spec slot(binary(), lightspeed@component:rendered()) -> {binary(),
    lightspeed@component:rendered()}.
slot(Name, Rendered) ->
    {Name, Rendered}.

-file("src/lightspeed/component/template_ergonomics.gleam", 127).
?DOC(" Convenience constructor for slot input from raw HTML.\n").
-spec slot_html(binary(), binary()) -> {binary(),
    lightspeed@component:rendered()}.
slot_html(Name, Html) ->
    {Name, lightspeed@component:html(Html)}.

-file("src/lightspeed/component/template_ergonomics.gleam", 648).
-spec value_kind_label(lightspeed@component@template_compiler:attr_value()) -> binary().
value_kind_label(Value) ->
    case Value of
        {string_attr, _} ->
            <<"string"/utf8>>;

        {int_attr, _} ->
            <<"int"/utf8>>;

        {bool_attr, _} ->
            <<"bool"/utf8>>
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 587).
-spec find_attr(
    list({binary(), lightspeed@component@template_compiler:attr_value()}),
    binary()
) -> gleam@option:option(lightspeed@component@template_compiler:attr_value()).
find_attr(Attrs, Name) ->
    case Attrs of
        [] ->
            none;

        [{Entry_name, Entry_value} | Rest] ->
            case Entry_name =:= Name of
                true ->
                    {some, Entry_value};

                false ->
                    find_attr(Rest, Name)
            end
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 132).
?DOC(" Optional string accessor with fallback default.\n").
-spec optional_string(
    list({binary(), lightspeed@component@template_compiler:attr_value()}),
    binary(),
    binary()
) -> {ok, binary()} | {error, binary()}.
optional_string(Attrs, Name, Default) ->
    case find_attr(Attrs, Name) of
        none ->
            {ok, Default};

        {some, {string_attr, Value}} ->
            {ok, Value};

        {some, Other} ->
            {error,
                <<<<<<"invalid_attr_type:"/utf8, Name/binary>>/binary,
                        ":expected=string:actual="/utf8>>/binary,
                    (value_kind_label(Other))/binary>>}
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 151).
?DOC(" Optional int accessor with fallback default.\n").
-spec optional_int(
    list({binary(), lightspeed@component@template_compiler:attr_value()}),
    binary(),
    integer()
) -> {ok, integer()} | {error, binary()}.
optional_int(Attrs, Name, Default) ->
    case find_attr(Attrs, Name) of
        none ->
            {ok, Default};

        {some, {int_attr, Value}} ->
            {ok, Value};

        {some, Other} ->
            {error,
                <<<<<<"invalid_attr_type:"/utf8, Name/binary>>/binary,
                        ":expected=int:actual="/utf8>>/binary,
                    (value_kind_label(Other))/binary>>}
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 170).
?DOC(" Optional bool accessor with fallback default.\n").
-spec optional_bool(
    list({binary(), lightspeed@component@template_compiler:attr_value()}),
    binary(),
    boolean()
) -> {ok, boolean()} | {error, binary()}.
optional_bool(Attrs, Name, Default) ->
    case find_attr(Attrs, Name) of
        none ->
            {ok, Default};

        {some, {bool_attr, Value}} ->
            {ok, Value};

        {some, Other} ->
            {error,
                <<<<<<"invalid_attr_type:"/utf8, Name/binary>>/binary,
                        ":expected=bool:actual="/utf8>>/binary,
                    (value_kind_label(Other))/binary>>}
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 189).
?DOC(" Return one required slot HTML as string.\n").
-spec required_slot_html(
    list({binary(), lightspeed@component:rendered()}),
    binary()
) -> {ok, binary()} | {error, binary()}.
required_slot_html(Slots, Name) ->
    case lightspeed@component@template_compiler:require_slot(Slots, Name) of
        {ok, Rendered} ->
            {ok, lightspeed@component:to_html(Rendered)};

        {error, Reason} ->
            {error, Reason}
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 200).
?DOC(" Return one optional slot HTML as string, defaulting to empty.\n").
-spec slot_html_or_empty(
    list({binary(), lightspeed@component:rendered()}),
    binary()
) -> binary().
slot_html_or_empty(Slots, Name) ->
    case lightspeed@component@template_compiler:slot_rendered(Slots, Name) of
        {some, Rendered} ->
            lightspeed@component:to_html(Rendered);

        none ->
            <<""/utf8>>
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 642).
-spec schema_slot_names(
    list(lightspeed@component@template_compiler:slot_schema())
) -> list(binary()).
schema_slot_names(Slots) ->
    _pipe = Slots,
    gleam@list:map(_pipe, fun(Slot) -> erlang:element(2, Slot) end).

-file("src/lightspeed/component/template_ergonomics.gleam", 656).
-spec join_with(binary(), list(binary())) -> binary().
join_with(Separator, Values) ->
    case Values of
        [] ->
            <<""/utf8>>;

        [Value] ->
            Value;

        [Value@1 | Rest] ->
            <<<<Value@1/binary, Separator/binary>>/binary,
                (join_with(Separator, Rest))/binary>>
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 504).
-spec unknown_slot_hint(
    binary(),
    lightspeed@component@template_compiler:schema(any(), any())
) -> binary().
unknown_slot_hint(Slot, Schema) ->
    <<<<<<"unknown slot `"/utf8, Slot/binary>>/binary,
            "`, supported slots: "/utf8>>/binary,
        (join_with(<<","/utf8>>, schema_slot_names(erlang:element(4, Schema))))/binary>>.

-file("src/lightspeed/component/template_ergonomics.gleam", 611).
-spec slot_default_exists(list(slot_default()), binary()) -> boolean().
slot_default_exists(Defaults, Name) ->
    case Defaults of
        [] ->
            false;

        [Default | Rest] ->
            case erlang:element(2, Default) =:= Name of
                true ->
                    true;

                false ->
                    slot_default_exists(Rest, Name)
            end
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 493).
-spec missing_slot_hint(binary(), list(slot_default())) -> binary().
missing_slot_hint(Slot, Defaults) ->
    case slot_default_exists(Defaults, Slot) of
        true ->
            <<<<"slot `"/utf8, Slot/binary>>/binary,
                "` is required; add it or keep default through `slot_default`"/utf8>>;

        false ->
            <<<<"add required slot `"/utf8, Slot/binary>>/binary, "`"/utf8>>
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 514).
-spec expected_helper_label(lightspeed@component@template_compiler:attr_kind()) -> binary().
expected_helper_label(Kind) ->
    case Kind of
        attr_string ->
            <<"string_attr"/utf8>>;

        attr_int ->
            <<"int_attr"/utf8>>;

        attr_bool ->
            <<"bool_attr"/utf8>>
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 636).
-spec schema_attr_names(
    list(lightspeed@component@template_compiler:attr_schema())
) -> list(binary()).
schema_attr_names(Attrs) ->
    _pipe = Attrs,
    gleam@list:map(_pipe, fun(Attr) -> erlang:element(2, Attr) end).

-file("src/lightspeed/component/template_ergonomics.gleam", 601).
-spec first_similar_attr(
    binary(),
    list(lightspeed@component@template_compiler:attr_schema())
) -> gleam@option:option(binary()).
first_similar_attr(_, Attrs) ->
    case Attrs of
        [] ->
            none;

        [Attr | _] ->
            {some, erlang:element(2, Attr)}
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 550).
-spec find_alias(list(attr_alias()), binary()) -> gleam@option:option(attr_alias()).
find_alias(Aliases, Name) ->
    case Aliases of
        [] ->
            none;

        [Alias_rule | Rest] ->
            case erlang:element(2, Alias_rule) =:= Name of
                true ->
                    {some, Alias_rule};

                false ->
                    find_alias(Rest, Name)
            end
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 464).
-spec unknown_attribute_hint(
    binary(),
    list(attr_alias()),
    lightspeed@component@template_compiler:schema(any(), any())
) -> binary().
unknown_attribute_hint(Attribute, Aliases, Schema) ->
    case find_alias(Aliases, Attribute) of
        {some, Alias_rule} ->
            <<<<<<<<<<<<"rename `"/utf8, Attribute/binary>>/binary,
                                "` to `"/utf8>>/binary,
                            (erlang:element(3, Alias_rule))/binary>>/binary,
                        "` ("/utf8>>/binary,
                    (erlang:element(4, Alias_rule))/binary>>/binary,
                ")"/utf8>>;

        none ->
            case first_similar_attr(Attribute, erlang:element(3, Schema)) of
                {some, Name} ->
                    <<<<<<<<"unknown attr `"/utf8, Attribute/binary>>/binary,
                                "`, did you mean `"/utf8>>/binary,
                            Name/binary>>/binary,
                        "`?"/utf8>>;

                none ->
                    <<<<<<"unknown attr `"/utf8, Attribute/binary>>/binary,
                            "`, supported attrs: "/utf8>>/binary,
                        (join_with(
                            <<","/utf8>>,
                            schema_attr_names(erlang:element(3, Schema))
                        ))/binary>>
            end
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 568).
-spec aliases_for_canonical_loop(list(attr_alias()), binary(), list(binary())) -> list(binary()).
aliases_for_canonical_loop(Aliases, Canonical, Acc_rev) ->
    case Aliases of
        [] ->
            lists:reverse(Acc_rev);

        [Alias_rule | Rest] ->
            case erlang:element(3, Alias_rule) =:= Canonical of
                true ->
                    aliases_for_canonical_loop(
                        Rest,
                        Canonical,
                        [erlang:element(2, Alias_rule) | Acc_rev]
                    );

                false ->
                    aliases_for_canonical_loop(Rest, Canonical, Acc_rev)
            end
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 561).
-spec aliases_for_canonical(list(attr_alias()), binary()) -> list(binary()).
aliases_for_canonical(Aliases, Canonical) ->
    aliases_for_canonical_loop(Aliases, Canonical, []).

-file("src/lightspeed/component/template_ergonomics.gleam", 443).
-spec missing_attribute_hint(
    binary(),
    list(attr_alias()),
    lightspeed@component@template_compiler:schema(any(), any())
) -> binary().
missing_attribute_hint(Attribute, Aliases, Schema) ->
    case aliases_for_canonical(Aliases, Attribute) of
        [] ->
            <<<<<<<<"provide required attr `"/utf8, Attribute/binary>>/binary,
                        "` (known attrs: "/utf8>>/binary,
                    (join_with(
                        <<","/utf8>>,
                        schema_attr_names(erlang:element(3, Schema))
                    ))/binary>>/binary,
                ")"/utf8>>;

        Alias_names ->
            <<<<<<"provide required attr `"/utf8, Attribute/binary>>/binary,
                    "` or migrate from alias(es): "/utf8>>/binary,
                (join_with(<<","/utf8>>, Alias_names))/binary>>
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 369).
-spec diagnostic_with_hint(
    lightspeed@component@template_compiler:diagnostic(),
    lightspeed@component@template_compiler:schema(any(), any()),
    list(attr_alias()),
    list(slot_default())
) -> diagnostic().
diagnostic_with_hint(Diagnostic, Schema, Aliases, Slot_defaults) ->
    Label = lightspeed@component@template_compiler:diagnostic_label(Diagnostic),
    case Diagnostic of
        {missing_attribute, _, Attribute} ->
            {diagnostic,
                <<"missing_attribute"/utf8>>,
                Label,
                missing_attribute_hint(Attribute, Aliases, Schema)};

        {duplicate_attribute, _, Attribute@1} ->
            {diagnostic,
                <<"duplicate_attribute"/utf8>>,
                Label,
                <<<<"keep a single `"/utf8, Attribute@1/binary>>/binary,
                    "` value"/utf8>>};

        {unknown_attribute, _, Attribute@2} ->
            {diagnostic,
                <<"unknown_attribute"/utf8>>,
                Label,
                unknown_attribute_hint(Attribute@2, Aliases, Schema)};

        {invalid_attribute_type, _, _, Expected, _} ->
            {diagnostic,
                <<"invalid_attribute_type"/utf8>>,
                Label,
                <<<<"use the `"/utf8, (expected_helper_label(Expected))/binary>>/binary,
                    "` attr helper"/utf8>>};

        {missing_slot, _, Slot} ->
            {diagnostic,
                <<"missing_slot"/utf8>>,
                Label,
                missing_slot_hint(Slot, Slot_defaults)};

        {duplicate_slot, _, Slot@1} ->
            {diagnostic,
                <<"duplicate_slot"/utf8>>,
                Label,
                <<<<"keep a single `"/utf8, Slot@1/binary>>/binary,
                    "` slot entry"/utf8>>};

        {unknown_slot, _, Slot@2} ->
            {diagnostic,
                <<"unknown_slot"/utf8>>,
                Label,
                unknown_slot_hint(Slot@2, Schema)};

        {assign_build_failed, _, _} ->
            {diagnostic,
                <<"assign_build_failed"/utf8>>,
                Label,
                <<"verify typed assign mapping and migration adapters"/utf8>>};

        {slot_build_failed, _, _} ->
            {diagnostic,
                <<"slot_build_failed"/utf8>>,
                Label,
                <<"verify slot mapping and optional-slot fallback handling"/utf8>>}
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 352).
-spec enhance_diagnostics(
    list(lightspeed@component@template_compiler:diagnostic()),
    lightspeed@component@template_compiler:schema(any(), any()),
    list(attr_alias()),
    list(slot_default()),
    list(diagnostic())
) -> list(diagnostic()).
enhance_diagnostics(Diagnostics, Schema, Aliases, Slot_defaults, Acc_rev) ->
    case Diagnostics of
        [] ->
            lists:reverse(Acc_rev);

        [Diagnostic | Rest] ->
            enhance_diagnostics(
                Rest,
                Schema,
                Aliases,
                Slot_defaults,
                [diagnostic_with_hint(
                        Diagnostic,
                        Schema,
                        Aliases,
                        Slot_defaults
                    ) |
                    Acc_rev]
            )
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 522).
-spec compile_signature(
    lightspeed@component@template_compiler:compiled_template(any(), any()),
    list({binary(), binary()}),
    list(binary())
) -> binary().
compile_signature(Compiled, Applied_aliases, Applied_defaults) ->
    Alias_signature = case Applied_aliases of
        [] ->
            <<"none"/utf8>>;

        _ ->
            join_with(
                <<","/utf8>>,
                gleam@list:map(
                    Applied_aliases,
                    fun(Value) ->
                        {Alias, Canonical} = Value,
                        <<<<Alias/binary, "->"/utf8>>/binary, Canonical/binary>>
                    end
                )
            )
    end,
    Defaults_signature = case Applied_defaults of
        [] ->
            <<"none"/utf8>>;

        _ ->
            join_with(<<","/utf8>>, Applied_defaults)
    end,
    <<<<<<<<(lightspeed@component@template_compiler:signature(Compiled))/binary,
                    "|aliases="/utf8>>/binary,
                Alias_signature/binary>>/binary,
            "|defaults="/utf8>>/binary,
        Defaults_signature/binary>>.

-file("src/lightspeed/component/template_ergonomics.gleam", 622).
-spec slot_exists(list({binary(), lightspeed@component:rendered()}), binary()) -> boolean().
slot_exists(Slots, Expected) ->
    case Slots of
        [] ->
            false;

        [{Name, _} | Rest] ->
            case Name =:= Expected of
                true ->
                    true;

                false ->
                    slot_exists(Rest, Expected)
            end
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 332).
-spec apply_slot_defaults_loop(
    list({binary(), lightspeed@component:rendered()}),
    list(slot_default()),
    list(binary())
) -> {list({binary(), lightspeed@component:rendered()}), list(binary())}.
apply_slot_defaults_loop(Slots, Defaults, Applied_rev) ->
    case Defaults of
        [] ->
            {Slots, Applied_rev};

        [Default | Rest] ->
            case slot_exists(Slots, erlang:element(2, Default)) of
                true ->
                    apply_slot_defaults_loop(Slots, Rest, Applied_rev);

                false ->
                    apply_slot_defaults_loop(
                        [{erlang:element(2, Default),
                                erlang:element(3, Default)} |
                            Slots],
                        Rest,
                        [erlang:element(2, Default) | Applied_rev]
                    )
            end
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 324).
-spec apply_slot_defaults(
    list({binary(), lightspeed@component:rendered()}),
    list(slot_default()),
    list(binary())
) -> {list({binary(), lightspeed@component:rendered()}), list(binary())}.
apply_slot_defaults(Slots, Defaults, Applied_rev) ->
    apply_slot_defaults_loop(Slots, Defaults, Applied_rev).

-file("src/lightspeed/component/template_ergonomics.gleam", 295).
-spec apply_aliases(
    list({binary(), lightspeed@component@template_compiler:attr_value()}),
    list(attr_alias()),
    list({binary(), lightspeed@component@template_compiler:attr_value()}),
    list({binary(), binary()})
) -> {list({binary(), lightspeed@component@template_compiler:attr_value()}),
    list({binary(), binary()})}.
apply_aliases(Attrs, Aliases, Normalized_rev, Applied_rev) ->
    case Attrs of
        [] ->
            {lists:reverse(Normalized_rev), Applied_rev};

        [{Name, Value} | Rest] ->
            case find_alias(Aliases, Name) of
                {some, Alias_rule} ->
                    apply_aliases(
                        Rest,
                        Aliases,
                        [{erlang:element(3, Alias_rule), Value} |
                            Normalized_rev],
                        [{erlang:element(2, Alias_rule),
                                erlang:element(3, Alias_rule)} |
                            Applied_rev]
                    );

                none ->
                    apply_aliases(
                        Rest,
                        Aliases,
                        [{Name, Value} | Normalized_rev],
                        Applied_rev
                    )
            end
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 211).
?DOC(" Compile one ergonomic template invocation.\n").
-spec compile(
    ergonomic_schema(JAS, JAT),
    list({binary(), lightspeed@component@template_compiler:attr_value()}),
    list({binary(), lightspeed@component:rendered()})
) -> {ok, compiled(JAS, JAT)} | {error, list(diagnostic())}.
compile(Schema, Attrs, Slots) ->
    {Normalized_attrs, Applied_aliases} = apply_aliases(
        Attrs,
        erlang:element(3, Schema),
        [],
        []
    ),
    {Normalized_slots, Applied_defaults} = apply_slot_defaults(
        Slots,
        erlang:element(4, Schema),
        []
    ),
    case lightspeed@component@template_compiler:compile(
        erlang:element(2, Schema),
        Normalized_attrs,
        Normalized_slots
    ) of
        {ok, Compiled_template} ->
            {ok,
                {compiled,
                    Compiled_template,
                    lists:reverse(Applied_aliases),
                    lists:reverse(Applied_defaults),
                    compile_signature(
                        Compiled_template,
                        lists:reverse(Applied_aliases),
                        lists:reverse(Applied_defaults)
                    )}};

        {error, Diagnostics} ->
            {error,
                enhance_diagnostics(
                    Diagnostics,
                    erlang:element(2, Schema),
                    erlang:element(3, Schema),
                    erlang:element(4, Schema),
                    []
                )}
    end.

-file("src/lightspeed/component/template_ergonomics.gleam", 250).
?DOC(" Stable diagnostic label.\n").
-spec diagnostic_label(diagnostic()) -> binary().
diagnostic_label(Diagnostic) ->
    <<<<<<<<(erlang:element(2, Diagnostic))/binary, ":"/utf8>>/binary,
                (erlang:element(3, Diagnostic))/binary>>/binary,
            ":hint="/utf8>>/binary,
        (erlang:element(4, Diagnostic))/binary>>.

-file("src/lightspeed/component/template_ergonomics.gleam", 255).
?DOC(" Stable diagnostics signature.\n").
-spec diagnostics_signature(list(diagnostic())) -> binary().
diagnostics_signature(Diagnostics) ->
    join_with(<<";"/utf8>>, gleam@list:map(Diagnostics, fun diagnostic_label/1)).

-file("src/lightspeed/component/template_ergonomics.gleam", 260).
?DOC(" Compiled artifact signature.\n").
-spec signature(compiled(any(), any())) -> binary().
signature(Compiled) ->
    erlang:element(5, Compiled).

-file("src/lightspeed/component/template_ergonomics.gleam", 265).
?DOC(" Compiled HTML.\n").
-spec html(compiled(any(), any())) -> binary().
html(Compiled) ->
    lightspeed@component@template_compiler:html(erlang:element(2, Compiled)).

-file("src/lightspeed/component/template_ergonomics.gleam", 270).
?DOC(" Compiled fingerprint.\n").
-spec fingerprint(compiled(any(), any())) -> binary().
fingerprint(Compiled) ->
    lightspeed@component@template_compiler:fingerprint(
        erlang:element(2, Compiled)
    ).

-file("src/lightspeed/component/template_ergonomics.gleam", 275).
?DOC(" Underlying compiled template accessor.\n").
-spec compiled_template(compiled(JBQ, JBR)) -> lightspeed@component@template_compiler:compiled_template(JBQ, JBR).
compiled_template(Compiled) ->
    erlang:element(2, Compiled).

-file("src/lightspeed/component/template_ergonomics.gleam", 282).
?DOC(" Applied alias migrations.\n").
-spec applied_aliases(compiled(any(), any())) -> list({binary(), binary()}).
applied_aliases(Compiled) ->
    erlang:element(3, Compiled).

-file("src/lightspeed/component/template_ergonomics.gleam", 289).
?DOC(" Applied slot defaults.\n").
-spec applied_slot_defaults(compiled(any(), any())) -> list(binary()).
applied_slot_defaults(Compiled) ->
    erlang:element(4, Compiled).