diff --git a/runtime/src/main/kotlin/generated/_ArraysNative.kt b/runtime/src/main/kotlin/generated/_ArraysNative.kt index b199ffbde02..10a21cc433f 100644 --- a/runtime/src/main/kotlin/generated/_ArraysNative.kt +++ b/runtime/src/main/kotlin/generated/_ArraysNative.kt @@ -240,7 +240,25 @@ public actual fun CharArray.asList(): List { * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual infix fun Array.contentDeepEquals(other: Array): Boolean { + return this.contentDeepEquals(other) +} + +/** + * Returns `true` if the two specified arrays are *deeply* equal to one another, + * i.e. contain the same number of the same elements in the same order. + * + * The specified arrays are also considered deeply equal if both are `null`. + * + * If two corresponding elements are nested arrays, they are also compared deeply. + * If any of arrays contains itself on any nesting level the behavior is undefined. + * + * The elements of other types are compared for equality with the [equals][Any.equals] function. + * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. + */ +@SinceKotlin("1.4") +public actual infix fun Array?.contentDeepEquals(other: Array?): Boolean { return contentDeepEqualsImpl(other) } @@ -251,7 +269,19 @@ public actual infix fun Array.contentDeepEquals(other: Array): * If any of arrays contains itself on any nesting level the behavior is undefined. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun Array.contentDeepHashCode(): Int { + return this.contentDeepHashCode() +} + +/** + * Returns a hash code based on the contents of this array as if it is [List]. + * Nested arrays are treated as lists too. + * + * If any of arrays contains itself on any nesting level the behavior is undefined. + */ +@SinceKotlin("1.4") +public actual fun Array?.contentDeepHashCode(): Int { return contentDeepHashCodeImpl() } @@ -265,7 +295,22 @@ public actual fun Array.contentDeepHashCode(): Int { * @sample samples.collections.Arrays.ContentOperations.contentDeepToString */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun Array.contentDeepToString(): String { + return this.contentDeepToString() +} + +/** + * Returns a string representation of the contents of this array as if it is a [List]. + * Nested arrays are treated as lists too. + * + * If any of arrays contains itself on any nesting level that reference + * is rendered as `"[...]"` to prevent recursion. + * + * @sample samples.collections.Arrays.ContentOperations.contentDeepToString + */ +@SinceKotlin("1.4") +public actual fun Array?.contentDeepToString(): String { return contentDeepToStringImpl() } @@ -277,13 +322,9 @@ public actual fun Array.contentDeepToString(): String { * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual infix fun Array.contentEquals(other: Array): Boolean { - if (this === other) return true - if (size != other.size) return false - for (i in indices) { - if (this[i] != other[i]) return false - } - return true + return this.contentEquals(other) } /** @@ -294,13 +335,9 @@ public actual infix fun Array.contentEquals(other: Array): Boo * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual infix fun ByteArray.contentEquals(other: ByteArray): Boolean { - if (this === other) return true - if (size != other.size) return false - for (i in indices) { - if (this[i] != other[i]) return false - } - return true + return this.contentEquals(other) } /** @@ -311,13 +348,9 @@ public actual infix fun ByteArray.contentEquals(other: ByteArray): Boolean { * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual infix fun ShortArray.contentEquals(other: ShortArray): Boolean { - if (this === other) return true - if (size != other.size) return false - for (i in indices) { - if (this[i] != other[i]) return false - } - return true + return this.contentEquals(other) } /** @@ -328,13 +361,9 @@ public actual infix fun ShortArray.contentEquals(other: ShortArray): Boolean { * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual infix fun IntArray.contentEquals(other: IntArray): Boolean { - if (this === other) return true - if (size != other.size) return false - for (i in indices) { - if (this[i] != other[i]) return false - } - return true + return this.contentEquals(other) } /** @@ -345,13 +374,9 @@ public actual infix fun IntArray.contentEquals(other: IntArray): Boolean { * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual infix fun LongArray.contentEquals(other: LongArray): Boolean { - if (this === other) return true - if (size != other.size) return false - for (i in indices) { - if (this[i] != other[i]) return false - } - return true + return this.contentEquals(other) } /** @@ -362,13 +387,9 @@ public actual infix fun LongArray.contentEquals(other: LongArray): Boolean { * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual infix fun FloatArray.contentEquals(other: FloatArray): Boolean { - if (this === other) return true - if (size != other.size) return false - for (i in indices) { - if (!this[i].equals(other[i])) return false - } - return true + return this.contentEquals(other) } /** @@ -379,8 +400,138 @@ public actual infix fun FloatArray.contentEquals(other: FloatArray): Boolean { * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual infix fun DoubleArray.contentEquals(other: DoubleArray): Boolean { + return this.contentEquals(other) +} + +/** + * Returns `true` if the two specified arrays are *structurally* equal to one another, + * i.e. contain the same number of the same elements in the same order. + * + * The elements are compared for equality with the [equals][Any.equals] function. + * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. + */ +@SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution +public actual infix fun BooleanArray.contentEquals(other: BooleanArray): Boolean { + return this.contentEquals(other) +} + +/** + * Returns `true` if the two specified arrays are *structurally* equal to one another, + * i.e. contain the same number of the same elements in the same order. + * + * The elements are compared for equality with the [equals][Any.equals] function. + * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. + */ +@SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution +public actual infix fun CharArray.contentEquals(other: CharArray): Boolean { + return this.contentEquals(other) +} + +/** + * Returns `true` if the two specified arrays are *structurally* equal to one another, + * i.e. contain the same number of the same elements in the same order. + * + * The elements are compared for equality with the [equals][Any.equals] function. + * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. + */ +@SinceKotlin("1.4") +public actual infix fun Array?.contentEquals(other: Array?): Boolean { if (this === other) return true + if (this === null || other === null) return false + if (size != other.size) return false + for (i in indices) { + if (this[i] != other[i]) return false + } + return true +} + +/** + * Returns `true` if the two specified arrays are *structurally* equal to one another, + * i.e. contain the same number of the same elements in the same order. + * + * The elements are compared for equality with the [equals][Any.equals] function. + * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. + */ +@SinceKotlin("1.4") +public actual infix fun ByteArray?.contentEquals(other: ByteArray?): Boolean { + if (this === other) return true + if (this === null || other === null) return false + if (size != other.size) return false + for (i in indices) { + if (this[i] != other[i]) return false + } + return true +} + +/** + * Returns `true` if the two specified arrays are *structurally* equal to one another, + * i.e. contain the same number of the same elements in the same order. + * + * The elements are compared for equality with the [equals][Any.equals] function. + * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. + */ +@SinceKotlin("1.4") +public actual infix fun ShortArray?.contentEquals(other: ShortArray?): Boolean { + if (this === other) return true + if (this === null || other === null) return false + if (size != other.size) return false + for (i in indices) { + if (this[i] != other[i]) return false + } + return true +} + +/** + * Returns `true` if the two specified arrays are *structurally* equal to one another, + * i.e. contain the same number of the same elements in the same order. + * + * The elements are compared for equality with the [equals][Any.equals] function. + * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. + */ +@SinceKotlin("1.4") +public actual infix fun IntArray?.contentEquals(other: IntArray?): Boolean { + if (this === other) return true + if (this === null || other === null) return false + if (size != other.size) return false + for (i in indices) { + if (this[i] != other[i]) return false + } + return true +} + +/** + * Returns `true` if the two specified arrays are *structurally* equal to one another, + * i.e. contain the same number of the same elements in the same order. + * + * The elements are compared for equality with the [equals][Any.equals] function. + * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. + */ +@SinceKotlin("1.4") +public actual infix fun LongArray?.contentEquals(other: LongArray?): Boolean { + if (this === other) return true + if (this === null || other === null) return false + if (size != other.size) return false + for (i in indices) { + if (this[i] != other[i]) return false + } + return true +} + +/** + * Returns `true` if the two specified arrays are *structurally* equal to one another, + * i.e. contain the same number of the same elements in the same order. + * + * The elements are compared for equality with the [equals][Any.equals] function. + * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. + */ +@SinceKotlin("1.4") +public actual infix fun FloatArray?.contentEquals(other: FloatArray?): Boolean { + if (this === other) return true + if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (!this[i].equals(other[i])) return false @@ -395,9 +546,28 @@ public actual infix fun DoubleArray.contentEquals(other: DoubleArray): Boolean { * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ -@SinceKotlin("1.1") -public actual infix fun BooleanArray.contentEquals(other: BooleanArray): Boolean { +@SinceKotlin("1.4") +public actual infix fun DoubleArray?.contentEquals(other: DoubleArray?): Boolean { if (this === other) return true + if (this === null || other === null) return false + if (size != other.size) return false + for (i in indices) { + if (!this[i].equals(other[i])) return false + } + return true +} + +/** + * Returns `true` if the two specified arrays are *structurally* equal to one another, + * i.e. contain the same number of the same elements in the same order. + * + * The elements are compared for equality with the [equals][Any.equals] function. + * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. + */ +@SinceKotlin("1.4") +public actual infix fun BooleanArray?.contentEquals(other: BooleanArray?): Boolean { + if (this === other) return true + if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (this[i] != other[i]) return false @@ -412,9 +582,10 @@ public actual infix fun BooleanArray.contentEquals(other: BooleanArray): Boolean * The elements are compared for equality with the [equals][Any.equals] function. * For floating point numbers it means that `NaN` is equal to itself and `-0.0` is not equal to `0.0`. */ -@SinceKotlin("1.1") -public actual infix fun CharArray.contentEquals(other: CharArray): Boolean { +@SinceKotlin("1.4") +public actual infix fun CharArray?.contentEquals(other: CharArray?): Boolean { if (this === other) return true + if (this === null || other === null) return false if (size != other.size) return false for (i in indices) { if (this[i] != other[i]) return false @@ -426,84 +597,89 @@ public actual infix fun CharArray.contentEquals(other: CharArray): Boolean { * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun Array.contentHashCode(): Int { - var result = 1 - for (element in this) - result = 31 * result + element.hashCode() - return result + return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun ByteArray.contentHashCode(): Int { - var result = 1 - for (element in this) - result = 31 * result + element.hashCode() - return result + return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun ShortArray.contentHashCode(): Int { - var result = 1 - for (element in this) - result = 31 * result + element.hashCode() - return result + return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun IntArray.contentHashCode(): Int { - var result = 1 - for (element in this) - result = 31 * result + element.hashCode() - return result + return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun LongArray.contentHashCode(): Int { - var result = 1 - for (element in this) - result = 31 * result + element.hashCode() - return result + return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun FloatArray.contentHashCode(): Int { - var result = 1 - for (element in this) - result = 31 * result + element.hashCode() - return result + return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun DoubleArray.contentHashCode(): Int { - var result = 1 - for (element in this) - result = 31 * result + element.hashCode() - return result + return this.contentHashCode() } /** * Returns a hash code based on the contents of this array as if it is [List]. */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun BooleanArray.contentHashCode(): Int { + return this.contentHashCode() +} + +/** + * Returns a hash code based on the contents of this array as if it is [List]. + */ +@SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution +public actual fun CharArray.contentHashCode(): Int { + return this.contentHashCode() +} + +/** + * Returns a hash code based on the contents of this array as if it is [List]. + */ +@SinceKotlin("1.4") +public actual fun Array?.contentHashCode(): Int { + if (this === null) return 0 var result = 1 for (element in this) result = 31 * result + element.hashCode() @@ -513,8 +689,93 @@ public actual fun BooleanArray.contentHashCode(): Int { /** * Returns a hash code based on the contents of this array as if it is [List]. */ -@SinceKotlin("1.1") -public actual fun CharArray.contentHashCode(): Int { +@SinceKotlin("1.4") +public actual fun ByteArray?.contentHashCode(): Int { + if (this === null) return 0 + var result = 1 + for (element in this) + result = 31 * result + element.hashCode() + return result +} + +/** + * Returns a hash code based on the contents of this array as if it is [List]. + */ +@SinceKotlin("1.4") +public actual fun ShortArray?.contentHashCode(): Int { + if (this === null) return 0 + var result = 1 + for (element in this) + result = 31 * result + element.hashCode() + return result +} + +/** + * Returns a hash code based on the contents of this array as if it is [List]. + */ +@SinceKotlin("1.4") +public actual fun IntArray?.contentHashCode(): Int { + if (this === null) return 0 + var result = 1 + for (element in this) + result = 31 * result + element.hashCode() + return result +} + +/** + * Returns a hash code based on the contents of this array as if it is [List]. + */ +@SinceKotlin("1.4") +public actual fun LongArray?.contentHashCode(): Int { + if (this === null) return 0 + var result = 1 + for (element in this) + result = 31 * result + element.hashCode() + return result +} + +/** + * Returns a hash code based on the contents of this array as if it is [List]. + */ +@SinceKotlin("1.4") +public actual fun FloatArray?.contentHashCode(): Int { + if (this === null) return 0 + var result = 1 + for (element in this) + result = 31 * result + element.hashCode() + return result +} + +/** + * Returns a hash code based on the contents of this array as if it is [List]. + */ +@SinceKotlin("1.4") +public actual fun DoubleArray?.contentHashCode(): Int { + if (this === null) return 0 + var result = 1 + for (element in this) + result = 31 * result + element.hashCode() + return result +} + +/** + * Returns a hash code based on the contents of this array as if it is [List]. + */ +@SinceKotlin("1.4") +public actual fun BooleanArray?.contentHashCode(): Int { + if (this === null) return 0 + var result = 1 + for (element in this) + result = 31 * result + element.hashCode() + return result +} + +/** + * Returns a hash code based on the contents of this array as if it is [List]. + */ +@SinceKotlin("1.4") +public actual fun CharArray?.contentHashCode(): Int { + if (this === null) return 0 var result = 1 for (element in this) result = 31 * result + element.hashCode() @@ -527,8 +788,9 @@ public actual fun CharArray.contentHashCode(): Int { * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun Array.contentToString(): String { - return joinToString(", ", "[", "]") + return this.contentToString() } /** @@ -537,8 +799,9 @@ public actual fun Array.contentToString(): String { * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun ByteArray.contentToString(): String { - return joinToString(", ", "[", "]") + return this.contentToString() } /** @@ -547,8 +810,9 @@ public actual fun ByteArray.contentToString(): String { * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun ShortArray.contentToString(): String { - return joinToString(", ", "[", "]") + return this.contentToString() } /** @@ -557,8 +821,9 @@ public actual fun ShortArray.contentToString(): String { * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun IntArray.contentToString(): String { - return joinToString(", ", "[", "]") + return this.contentToString() } /** @@ -567,8 +832,9 @@ public actual fun IntArray.contentToString(): String { * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun LongArray.contentToString(): String { - return joinToString(", ", "[", "]") + return this.contentToString() } /** @@ -577,8 +843,9 @@ public actual fun LongArray.contentToString(): String { * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun FloatArray.contentToString(): String { - return joinToString(", ", "[", "]") + return this.contentToString() } /** @@ -587,8 +854,9 @@ public actual fun FloatArray.contentToString(): String { * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun DoubleArray.contentToString(): String { - return joinToString(", ", "[", "]") + return this.contentToString() } /** @@ -597,8 +865,9 @@ public actual fun DoubleArray.contentToString(): String { * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun BooleanArray.contentToString(): String { - return joinToString(", ", "[", "]") + return this.contentToString() } /** @@ -607,8 +876,99 @@ public actual fun BooleanArray.contentToString(): String { * @sample samples.collections.Arrays.ContentOperations.contentToString */ @SinceKotlin("1.1") +@kotlin.internal.LowPriorityInOverloadResolution public actual fun CharArray.contentToString(): String { - return joinToString(", ", "[", "]") + return this.contentToString() +} + +/** + * Returns a string representation of the contents of the specified array as if it is [List]. + * + * @sample samples.collections.Arrays.ContentOperations.contentToString + */ +@SinceKotlin("1.4") +public actual fun Array?.contentToString(): String { + return this?.joinToString(", ", "[", "]") ?: "null" +} + +/** + * Returns a string representation of the contents of the specified array as if it is [List]. + * + * @sample samples.collections.Arrays.ContentOperations.contentToString + */ +@SinceKotlin("1.4") +public actual fun ByteArray?.contentToString(): String { + return this?.joinToString(", ", "[", "]") ?: "null" +} + +/** + * Returns a string representation of the contents of the specified array as if it is [List]. + * + * @sample samples.collections.Arrays.ContentOperations.contentToString + */ +@SinceKotlin("1.4") +public actual fun ShortArray?.contentToString(): String { + return this?.joinToString(", ", "[", "]") ?: "null" +} + +/** + * Returns a string representation of the contents of the specified array as if it is [List]. + * + * @sample samples.collections.Arrays.ContentOperations.contentToString + */ +@SinceKotlin("1.4") +public actual fun IntArray?.contentToString(): String { + return this?.joinToString(", ", "[", "]") ?: "null" +} + +/** + * Returns a string representation of the contents of the specified array as if it is [List]. + * + * @sample samples.collections.Arrays.ContentOperations.contentToString + */ +@SinceKotlin("1.4") +public actual fun LongArray?.contentToString(): String { + return this?.joinToString(", ", "[", "]") ?: "null" +} + +/** + * Returns a string representation of the contents of the specified array as if it is [List]. + * + * @sample samples.collections.Arrays.ContentOperations.contentToString + */ +@SinceKotlin("1.4") +public actual fun FloatArray?.contentToString(): String { + return this?.joinToString(", ", "[", "]") ?: "null" +} + +/** + * Returns a string representation of the contents of the specified array as if it is [List]. + * + * @sample samples.collections.Arrays.ContentOperations.contentToString + */ +@SinceKotlin("1.4") +public actual fun DoubleArray?.contentToString(): String { + return this?.joinToString(", ", "[", "]") ?: "null" +} + +/** + * Returns a string representation of the contents of the specified array as if it is [List]. + * + * @sample samples.collections.Arrays.ContentOperations.contentToString + */ +@SinceKotlin("1.4") +public actual fun BooleanArray?.contentToString(): String { + return this?.joinToString(", ", "[", "]") ?: "null" +} + +/** + * Returns a string representation of the contents of the specified array as if it is [List]. + * + * @sample samples.collections.Arrays.ContentOperations.contentToString + */ +@SinceKotlin("1.4") +public actual fun CharArray?.contentToString(): String { + return this?.joinToString(", ", "[", "]") ?: "null" } /** diff --git a/runtime/src/main/kotlin/kotlin/collections/Arrays.kt b/runtime/src/main/kotlin/kotlin/collections/Arrays.kt index bf3caad308a..6768b62d610 100644 --- a/runtime/src/main/kotlin/kotlin/collections/Arrays.kt +++ b/runtime/src/main/kotlin/kotlin/collections/Arrays.kt @@ -46,7 +46,8 @@ public inline fun Array.subarrayContentToString(offset: Int, length: */ @SinceKotlin("1.1") @UseExperimental(ExperimentalUnsignedTypes::class) -internal fun Array.contentDeepHashCodeImpl(): Int { +internal fun Array?.contentDeepHashCodeImpl(): Int { + if (this == null) return 0 var result = 1 for (element in this) { val elementHash = when (element) {