| Title: | Table-Driven Insurance Rating |
| Version: | 0.2.0 |
| Description: | Provides a lightweight, table-driven engine for executing insurance rating plans, including coverage-specific rating specifications, entity aggregation, and trace output for auditing. Given policy data, an ordered rating specification, and rating factor tables, it returns rated policies and, optionally, a step-by-step trace of the calculation. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/gs-actuary/ratingtables |
| BugReports: | https://github.com/gs-actuary/ratingtables/issues |
| Encoding: | UTF-8 |
| Suggests: | testthat (≥ 3.0.0) |
| Config/testthat/edition: | 3 |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-08-04 22:03:58 UTC; yagre |
| Author: | Greg Sollenberger [aut, cre, cph] |
| Maintainer: | Greg Sollenberger <yagreg7@yahoo.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-08-09 08:40:02 UTC |
ratingtables: Table-driven insurance rating
Description
Provides a lightweight, table-driven engine for executing insurance rating plans, including coverage-specific rating specifications, entity aggregation, and trace output for auditing. Given policy data, an ordered rating specification, and rating factor tables, it returns rated policies and, optionally, a step-by-step trace of the calculation.
Author(s)
Maintainer: Greg Sollenberger yagreg7@yahoo.com [copyright holder]
Authors:
Greg Sollenberger yagreg7@yahoo.com [copyright holder]
See Also
Useful links:
Report bugs at https://github.com/gs-actuary/ratingtables/issues
Aggregate rated entity values to parent records
Description
Aggregate one or more numeric values from entity-level records to a parent or group level. This can be used, for example, to average driver factors or sum premiums for boats or scheduled items.
Usage
aggregate_entity_values(
rated_entity_data,
group_col,
value_cols,
aggregation = "mean",
weight_col = NULL,
output_names = NULL,
output_prefix = NULL
)
Arguments
rated_entity_data |
A data frame containing rated entity records. |
group_col |
A character string naming the column that identifies the parent or aggregation group. |
value_cols |
A character vector naming the numeric columns to aggregate. |
aggregation |
A character string specifying the aggregation method.
Supported values are |
weight_col |
An optional character string naming the weight column.
Required when |
output_names |
An optional character vector giving the names of the
aggregated output columns. It must have the same length as |
output_prefix |
An optional character string prepended to generated
output names when |
Value
A data frame with one row per unique value of group_col and one
aggregated column for each entry in value_cols.
Examples
rated_drivers <- data.frame(
policy_id = c("P1", "P1", "P2"),
indicated_BI = c(1.10, 0.90, 1.05)
)
aggregate_entity_values(
rated_entity_data = rated_drivers,
group_col = "policy_id",
value_cols = "indicated_BI",
aggregation = "mean",
output_names = "average_BI"
)
Append wide rating-step values to rated data
Description
Reshape normalized trace rows into wide applied-value columns and join them to the rated records.
Usage
append_rating_factors(rated_data, term_trace, by = "row_number")
Arguments
rated_data |
A data frame containing rated policy or entity records. |
term_trace |
A data frame containing normalized rating trace rows. |
by |
A character vector naming the columns used both to reshape
|
Details
The function creates or replaces a row_number column in rated_data using
its current row order.
Value
A data frame containing the rated records, a generated row_number
column, and wide step_<number>_<term> columns containing applied step
values.
Examples
ex <- example_rating_plan()
result <- rate_policies_with_trace(
ex$policies,
ex$plan
)
append_rating_factors(
rated_data = result$rated_data,
term_trace = result$term_trace,
by = "row_number"
)
Apply rate-change caps to indicated premiums
Description
Limit indicated premiums so that they do not increase or decrease by more than specified percentages relative to prior premiums.
Usage
apply_caps(
rating_data,
prior_data,
by,
coverages,
max_increase = NULL,
max_decrease = NULL
)
Arguments
rating_data |
A data frame containing indicated premium columns named
|
prior_data |
A data frame containing prior premium columns named
|
by |
A character vector naming the column or columns used to join
|
coverages |
A character vector naming the coverages to cap. |
max_increase |
An optional nonnegative numeric value giving the maximum
permitted proportional increase. For example, |
max_decrease |
An optional numeric value giving the maximum permitted proportional decrease. Its absolute value is used. |
Value
A merged data frame with one capped_<coverage> column for each
requested coverage.
Examples
indicated <- data.frame(
policy_id = c("P1", "P2"),
indicated_BI = c(125, 80)
)
prior <- data.frame(
policy_id = c("P1", "P2"),
prior_BI = c(100, 100)
)
apply_caps(
rating_data = indicated,
prior_data = prior,
by = "policy_id",
coverages = "BI",
max_increase = 0.10,
max_decrease = 0.15
)
Apply a rounding rule
Description
Apply a rounding rule
Usage
apply_rounding(x, rule = NA, digits = NA, increment = NA)
Arguments
x |
A numeric vector. |
rule |
A character string naming the rounding rule. Supported values
are |
digits |
The number of decimal places used when |
increment |
The numeric increment used when
|
Value
A numeric vector containing the rounded values. If rule is
missing or "none", x is returned unchanged.
Examples
premiums <- c(101.234, 105.678)
apply_rounding(
premiums,
rule = "nearest_cent"
)
apply_rounding(
premiums,
rule = "nearest_increment",
increment = 5
)
Average entity rating factors
Description
Average indicated coverage values across entity records belonging to the same parent record.
Usage
average_entity_factors(
scored_entity_data,
group_col,
coverages,
output_prefix = "avg_entity_factor_"
)
Arguments
scored_entity_data |
A data frame containing scored entity records and
columns named |
group_col |
A character string naming the column that identifies the parent or aggregation group. |
coverages |
A character vector of coverage names whose indicated values should be averaged. |
output_prefix |
A character string prepended to the generated output column names. |
Value
A data frame with one row per parent group and one average entity factor column for each requested coverage.
Examples
rated_drivers <- data.frame(
policy_id = c("P1", "P1", "P2"),
indicated_BI = c(1.10, 0.90, 1.05)
)
average_entity_factors(
scored_entity_data = rated_drivers,
group_col = "policy_id",
coverages = "BI"
)
Ensure variable/level slot columns exist
Description
Ensure variable/level slot columns exist
Usage
ensure_slot_columns(x, max_vars = 12)
Arguments
x |
Data frame. |
max_vars |
Number of variable/level slots. |
Value
A data frame containing the original columns in x plus any
missing variable and level slot columns.
Examples
factors <- data.frame(
term_name = "territory",
term_value = 1.10
)
factors <- ensure_slot_columns(
factors,
max_vars = 2
)
factors
Build a small example rating plan
Description
Build a small example rating plan
Usage
example_rating_plan()
Value
A list with two elements:
- plan
An example
rating_planobject.- policies
A data frame containing example policy records.
Examples
ex <- example_rating_plan()
ex$policies
ex$plan
Explain a rating calculation
Description
Extract and format the rating trace for one source-data row and, optionally, one coverage.
Usage
explain_rating(rating_result, row_number = 1, coverage = NULL)
Arguments
rating_result |
A |
row_number |
An integer identifying the source-data row to explain. |
coverage |
An optional character string identifying the coverage to
include. If |
Value
An Excel-style data frame showing the selected rating steps in calculation order.
Examples
ex <- example_rating_plan()
result <- rate_policies_with_trace(
ex$policies,
ex$plan
)
explain_rating(
rating_result = result,
row_number = 1,
coverage = "BI"
)
Find duplicate factor-table rows
Description
Identify factor-table rows that have duplicate lookup keys.
Usage
find_duplicate_factors(factor_table, max_vars = 12, ...)
Arguments
factor_table |
A normalized long-form factor table. |
max_vars |
Maximum number of variable-level slot pairs to inspect. |
... |
Additional arguments accepted for backward compatibility. |
Value
A data frame containing factor-table rows with duplicated lookup keys. An empty data frame is returned when no duplicates are found.
Examples
factor_table <- data.frame(
state = c("IL", "IL", "IL"),
coverage = c("BI", "BI", "BI"),
term_name = c("territory", "territory", "territory"),
term_value = c(1.10, 1.15, 0.95),
variable1 = c("territory", "territory", "territory"),
level1 = c("A", "A", "B"),
stringsAsFactors = FALSE
)
duplicates <- find_duplicate_factors(
factor_table,
max_vars = 1
)
duplicates[
,
c(
"state",
"coverage",
"term_name",
"term_value",
"variable1",
"level1"
)
]
Join entity factors to rating data
Description
Backward-compatible wrapper around join_entity_values() for joining
aggregated entity factors to parent-level rating data.
Usage
join_entity_factors(rating_data, entity_factor_data, by)
Arguments
rating_data |
A data frame containing the parent-level rating records. |
entity_factor_data |
A data frame containing aggregated entity factors. |
by |
A character vector naming the column or columns used to join the two data frames. |
Value
A data frame containing all rows from rating_data with matching
entity-factor columns appended.
Examples
policies <- data.frame(
policy_id = c("P1", "P2"),
base_premium = c(100, 120)
)
driver_factors <- data.frame(
policy_id = c("P1", "P2"),
average_driver_factor = c(1.05, 0.95)
)
join_entity_factors(
rating_data = policies,
entity_factor_data = driver_factors,
by = "policy_id"
)
Join aggregated entity values to parent records
Description
Left-join aggregated entity-level values back to the parent-level rating data.
Usage
join_entity_values(parent_data, entity_values, by)
Arguments
parent_data |
A data frame containing parent-level records. |
entity_values |
A data frame containing aggregated entity values. |
by |
A character vector naming the column or columns used to join the two data frames. |
Value
A data frame containing all rows from parent_data with matching
columns from entity_values.
Examples
policies <- data.frame(
policy_id = c("P1", "P2"),
base_premium = c(100, 120)
)
driver_values <- data.frame(
policy_id = c("P1", "P2"),
average_driver_factor = c(1.05, 0.95)
)
join_entity_values(
parent_data = policies,
entity_values = driver_values,
by = "policy_id"
)
Look up an exact rating-table value
Description
Select the single most specific factor-table row that matches a rating record, coverage, term, rate-set metadata, and variable-level conditions.
Usage
lookup_exact_value(row, coverage, plan, term_name)
Arguments
row |
A one-row data frame containing the rating record. |
coverage |
A character string identifying the coverage being rated. |
plan |
A |
term_name |
A character string identifying the rating term to look up. |
Value
A list containing the selected numeric value, the value source, the looked-up value, and the matching factor-row identifier.
Examples
ex <- example_rating_plan()
policy <- ex$policies[1, , drop = FALSE]
answer <- lookup_exact_value(
row = policy,
coverage = "BI",
plan = ex$plan,
term_name = "territory"
)
answer$value
answer$factor_row_id
Look up a factor value by source
Description
Dispatch a rating-table lookup to either exact matching or interpolated
lookup according to value_source.
Usage
lookup_factor_value(
row,
coverage,
plan,
term_name,
value_source = "factor_lookup",
lookup_var = NULL,
bounds = "error"
)
Arguments
row |
A one-row data frame containing the rating record. |
coverage |
A character string identifying the coverage being rated. |
plan |
A |
term_name |
A character string identifying the rating term to look up. |
value_source |
A character string specifying the lookup method.
Supported values are |
lookup_var |
An optional character string naming the interpolation
variable. Required for |
bounds |
A character string controlling out-of-range interpolation.
Supported values are |
Value
A list containing the selected or interpolated rating value and associated trace information.
Examples
ex <- example_rating_plan()
policy <- ex$policies[1, , drop = FALSE]
answer <- lookup_factor_value(
row = policy,
coverage = "BI",
plan = ex$plan,
term_name = "territory",
value_source = "factor_lookup"
)
answer
Look up an interpolated rating-table value
Description
Select the applicable interpolation curve for a rating record and calculate a linearly interpolated value from the surrounding table points.
Usage
lookup_interpolated_value(
row,
coverage,
plan,
term_name,
lookup_var,
bounds = "error"
)
Arguments
row |
A one-row data frame containing the rating record. |
coverage |
A character string identifying the coverage being rated. |
plan |
A |
term_name |
A character string identifying the rating term to look up. |
lookup_var |
A character string naming the numeric input variable used as the interpolation axis. |
bounds |
A character string controlling values outside the available
interpolation range. Supported values are |
Value
A list containing the interpolated value and supporting trace information, including the lower and upper levels, values, interpolation weight, and factor-row identifiers.
Examples
factor_table <- data.frame(
state = c("IL", "IL"),
charter = c("STD", "STD"),
book_segment = c("new", "new"),
rate_eff_date = as.Date(c("2025-01-01", "2025-01-01")),
rate_exp_date = as.Date(c("2025-12-31", "2025-12-31")),
coverage = c("BI", "BI"),
term_name = c("limit_factor", "limit_factor"),
term_value = c(1.00, 1.20),
variable1 = c("limit_value", "limit_value"),
level1 = c("100", "200"),
stringsAsFactors = FALSE
)
rating_spec <- data.frame(
step_number = 1,
term_name = "limit_factor",
value_source = "interpolated_lookup",
calculation_type = "multiplicative",
lookup_var = "limit_value",
stringsAsFactors = FALSE
)
plan <- new_rating_plan(
factor_table = factor_table,
rating_spec = rating_spec,
coverages = "BI"
)
policy <- data.frame(
policy_id = "P1",
state = "IL",
charter = "STD",
book_segment = "new",
rating_date = as.Date("2025-06-01"),
limit_value = 150,
stringsAsFactors = FALSE
)
answer <- lookup_interpolated_value(
row = policy,
coverage = "BI",
plan = plan,
term_name = "limit_factor",
lookup_var = "limit_value"
)
answer$value
answer$interpolation_weight
Look up an exact rating term value
Description
Compatibility wrapper around lookup_exact_value(). By default, it returns
only the numeric factor value.
Usage
lookup_term_value(row, coverage, plan, term_name, return_match = FALSE, ...)
Arguments
row |
A one-row data frame containing the rating record. |
coverage |
A character string identifying the coverage being rated. |
plan |
A |
term_name |
A character string identifying the rating term to look up. |
return_match |
Logical. If |
... |
Additional arguments accepted for backward compatibility. They are currently ignored. |
Value
If return_match = FALSE, a numeric rating value. If
return_match = TRUE, a list containing the value and matching-row
information.
Examples
ex <- example_rating_plan()
policy <- ex$policies[1, , drop = FALSE]
lookup_term_value(
row = policy,
coverage = "BI",
plan = ex$plan,
term_name = "territory"
)
lookup_term_value(
row = policy,
coverage = "BI",
plan = ex$plan,
term_name = "territory",
return_match = TRUE
)
Add empty variable/level slot columns
Description
Add empty variable/level slot columns
Usage
make_empty_slots(n = 1, max_vars = 12)
Arguments
n |
Number of rows. |
max_vars |
Number of variable/level slots. |
Value
A data frame with n rows and one variable and level column
pair for each requested slot.
Examples
slots <- make_empty_slots(
n = 2,
max_vars = 3
)
slots
Create a rating plan
Description
Create a rating plan
Usage
new_rating_plan(
factor_table,
rating_spec,
coverages,
use_rate_set_key = FALSE,
max_vars = 12,
policy_id_col = "policy_id",
custom_functions = list(),
validate = TRUE,
metadata = list()
)
Arguments
factor_table |
A normalized long-format data frame containing at least
|
rating_spec |
A data frame containing at least |
coverages |
A character vector naming the coverages to rate. |
use_rate_set_key |
Logical. If |
max_vars |
A nonnegative integer giving the maximum number of variable-level slot pairs in the factor table. |
policy_id_col |
A single character string naming the policy or record
identifier column. Its value is stored as |
custom_functions |
A named list of custom rating functions referenced
by |
validate |
Logical. If |
metadata |
An optional list stored unchanged in the rating-plan object. |
Value
A rating_plan object containing the normalized factor table,
rating specification, coverages, configuration, custom functions, and
metadata.
Examples
ex <- example_rating_plan()
plan <- new_rating_plan(
factor_table = ex$plan$factor_table,
rating_spec = ex$plan$rating_spec,
coverages = "BI"
)
print(plan)
summary(plan)
Populate variable/level slots from named values
Description
Populate variable/level slots from named values
Usage
populate_slots(x, ..., max_vars = 12)
Arguments
x |
A data frame to which slot columns will be added or updated. |
... |
Named vectors of levels. Each argument name becomes the value of
a |
max_vars |
A nonnegative integer giving the maximum number of variable-level slot pairs. |
Value
A data frame containing x with variable and level slot columns
populated from the named values supplied through ....
Examples
factors <- data.frame(
term_name = c("territory_limit", "territory_limit"),
term_value = c(1.10, 0.95)
)
factors <- populate_slots(
factors,
territory = c("A", "B"),
limit = "100/300",
max_vars = 2
)
factors
Rate child or entity records
Description
Apply a rating plan to entity-level records such as drivers, vehicles, boats, or scheduled items, returning both rated values and trace output.
Usage
rate_entities(entity_data, plan, validate = TRUE)
Arguments
entity_data |
A data frame containing one row per entity to be rated. |
plan |
A |
validate |
Logical. If |
Value
A rating_result object containing rated_data, term_trace,
and the rating plan.
Examples
ex <- example_rating_plan()
drivers <- ex$policies
drivers$household_id <- "H1"
drivers$policy_id <- c("D1", "D2")
result <- rate_entities(
entity_data = drivers,
plan = ex$plan
)
result$rated_data
result$term_trace
Rate one record for one coverage
Description
Execute the applicable rating specification one step at a time for a single record and coverage.
Usage
rate_one_row_one_coverage(row, coverage, plan, row_number = 1)
Arguments
row |
A one-row data frame containing the rating record. |
coverage |
A character string identifying the coverage to rate. |
plan |
A |
row_number |
An integer identifying the row within the source rating data. This value is included in the trace output. |
Value
A list with two elements: value, containing the final indicated
value, and trace, containing one trace row per rating-specification step.
Examples
ex <- example_rating_plan()
answer <- rate_one_row_one_coverage(
row = ex$policies[1, , drop = FALSE],
coverage = "BI",
plan = ex$plan,
row_number = 1
)
answer$value
answer$trace
Rate policy records
Description
Apply a rating plan to every row and coverage in a policy-level data frame, returning only the resulting rated data.
Usage
rate_policies(rating_data, plan, validate = TRUE)
Arguments
rating_data |
A data frame containing one row per policy or rating record. |
plan |
A |
validate |
Logical. If |
Value
A data frame containing the original rating data plus one
indicated_<coverage> column for each coverage in the rating plan.
Examples
ex <- example_rating_plan()
rated <- rate_policies(
rating_data = ex$policies,
plan = ex$plan
)
rated
Rate policy records with trace output
Description
Apply a rating plan to every row and coverage in a policy-level data frame and retain step-by-step trace information.
Usage
rate_policies_with_trace(rating_data, plan, validate = TRUE)
Arguments
rating_data |
A data frame containing one row per policy or rating record. |
plan |
A |
validate |
Logical. If |
Value
A rating_result object containing:
- rated_data
The original records with indicated coverage values.
- term_trace
Step-by-step rating trace rows.
- plan
The rating plan used for the calculation.
Examples
ex <- example_rating_plan()
result <- rate_policies_with_trace(
rating_data = ex$policies,
plan = ex$plan
)
result$rated_data
result$term_trace
Split a rate set into review-friendly tables
Description
Separate a normalized long-form factor table into a collection of smaller tables suitable for human review.
Usage
rate_set_to_tables(factor_table)
Arguments
factor_table |
A normalized long-form factor table. |
Value
A named list of data frames containing review-friendly subsets of the supplied factor table.
Examples
ex <- example_rating_plan()
tables <- rate_set_to_tables(
ex$plan$factor_table
)
names(tables)
tables$territory
Identify required rating-data fields
Description
Collect fields referenced by factor-table lookup slots, specification input and lookup columns, and applicable rate-set metadata.
Usage
required_policy_fields(plan)
Arguments
plan |
A |
Value
A character vector containing the unique input-data column names required by the plan.
Examples
ex <- example_rating_plan()
required_policy_fields(ex$plan)
Score child or entity records
Description
Backward-compatible wrapper around rate_entities() that returns only
the rated entity data and omits the trace and plan components.
Usage
score_entity_rows(entity_data, plan, validate = TRUE)
Arguments
entity_data |
A data frame containing one row per entity to be rated. |
plan |
A |
validate |
Logical. If |
Value
A data frame containing the original entity data and calculated indicated values.
Examples
ex <- example_rating_plan()
drivers <- ex$policies
drivers$household_id <- "H1"
drivers$policy_id <- c("D1", "D2")
scored <- score_entity_rows(
entity_data = drivers,
plan = ex$plan
)
scored
Reshape rating trace to an Excel-style step table
Description
Select and order the principal trace columns to produce a compact, human-readable view of the rating calculation.
Usage
trace_to_excel_style(term_trace)
Arguments
term_trace |
A data frame containing normalized rating trace rows,
typically from |
Value
A data frame ordered by row number, coverage, and step number. It
contains the available columns among row_number, record_id, coverage,
step_number, term_name, value_source, calculation_type,
applied_value, value_before_step, and value_after_step.
Examples
ex <- example_rating_plan()
result <- rate_policies_with_trace(
ex$policies,
ex$plan
)
trace_to_excel_style(
result$term_trace
)
Reshape rating trace to wide step-value columns
Description
Convert normalized trace rows into one row per unique combination of
identifying columns, with a separate column for each rating step. Generated
step columns contain the trace's applied_value.
Usage
trace_to_wide_factors(
term_trace,
id_cols = c("row_number", "record_id", "coverage")
)
Arguments
term_trace |
A data frame containing normalized rating trace rows,
typically from |
id_cols |
A character vector naming columns in |
Value
If term_trace is nonempty, a data frame with one row per unique
combination of the available id_cols and columns named
step_<number>_<term> containing applied step values. If term_trace is
empty, the empty input data frame is returned unchanged.
Examples
ex <- example_rating_plan()
result <- rate_policies_with_trace(
ex$policies,
ex$plan
)
trace_to_wide_factors(
result$term_trace
)
Check minimum factor-table structure
Description
Confirm that a factor table contains term_name and term_value and that
every term_value is numeric or coercible to numeric. This function does
not check for duplicate lookup keys; use find_duplicate_factors() for that.
Usage
validate_factor_table(factor_table, max_vars = 12)
Arguments
factor_table |
A data frame containing rating factors. |
max_vars |
A nonnegative integer giving the number of variable-level slot pairs to add before validation. |
Value
Invisibly returns TRUE if validation succeeds. Otherwise, the
function stops with an error.
Examples
ex <- example_rating_plan()
isTRUE(
validate_factor_table(
ex$plan$factor_table,
max_vars = ex$plan$max_vars
)
)
Check required rating-data columns
Description
Confirm that the input data contains every column returned by
required_policy_fields(). This function checks column presence but does
not validate individual values or column types.
Usage
validate_policy_data(rating_data, plan)
Arguments
rating_data |
A data frame containing policy, risk, or entity records. |
plan |
A |
Value
Invisibly returns TRUE if validation succeeds. Otherwise, the
function stops with an error.
Examples
ex <- example_rating_plan()
isTRUE(
validate_policy_data(
rating_data = ex$policies,
plan = ex$plan
)
)
Check rate-set identifiers and date ranges
Description
Check that rate_set_key contains no missing or blank values when present,
and that rate_eff_date is not later than rate_exp_date when both date
columns are present.
Usage
validate_rate_sets(factor_table)
Arguments
factor_table |
A data frame containing rating factors and optional rate-set fields. |
Value
Invisibly returns TRUE if validation succeeds. Otherwise, the
function stops with an error.
Examples
ex <- example_rating_plan()
isTRUE(
validate_rate_sets(
ex$plan$factor_table
)
)
Check a rating plan
Description
Run factor-table, rating-specification, and rate-set checks and confirm that custom functions referenced by the specification are registered as functions in the plan.
Usage
validate_rating_plan(plan)
Arguments
plan |
A |
Value
Invisibly returns TRUE if validation succeeds. Otherwise, the
function stops with an error.
Examples
ex <- example_rating_plan()
isTRUE(
validate_rating_plan(ex$plan)
)
Check rating-specification fields
Description
Normalize a rating specification and check its value sources, calculation types, and required lookup, input, or custom-function fields.
Usage
validate_rating_spec(rating_spec, ...)
Arguments
rating_spec |
A data frame containing the rating specification. It must
contain |
... |
Additional arguments accepted for backward compatibility and currently ignored. |
Value
Invisibly returns TRUE if validation succeeds. Otherwise, the
function stops with an error.
Examples
ex <- example_rating_plan()
isTRUE(
validate_rating_spec(
ex$plan$rating_spec
)
)