Gutter and margin fixes

This commit is contained in:
Pfeil, Scott Robert 2021-03-25 13:44:21 -04:00
parent ba6f52e182
commit 9cde90fdf4
9 changed files with 84 additions and 37 deletions

View File

@ -346,6 +346,7 @@
D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; }; D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; };
D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; }; D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; };
D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; }; D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; };
D23A8FD9260CE004007E14CE /* MFStyler+PaddingExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23A8FD5260CDF01007E14CE /* MFStyler+PaddingExtension.swift */; };
D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */; }; D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */; };
D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */; }; D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */; };
D23EA800247EBD6C00D60C34 /* LabelBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */; }; D23EA800247EBD6C00D60C34 /* LabelBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */; };
@ -902,6 +903,7 @@
D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescription.swift; sourceTree = "<group>"; }; D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescription.swift; sourceTree = "<group>"; };
D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = "<group>"; }; D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = "<group>"; };
D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = "<group>"; }; D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = "<group>"; };
D23A8FD5260CDF01007E14CE /* MFStyler+PaddingExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFStyler+PaddingExtension.swift"; sourceTree = "<group>"; };
D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemProtocol.swift; sourceTree = "<group>"; }; D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemProtocol.swift; sourceTree = "<group>"; };
D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationLabelButtonModel.swift; sourceTree = "<group>"; }; D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationLabelButtonModel.swift; sourceTree = "<group>"; };
D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelBarButtonItem.swift; sourceTree = "<group>"; }; D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelBarButtonItem.swift; sourceTree = "<group>"; };
@ -2000,6 +2002,7 @@
D29DF13921E68637003B2FB9 /* MFStyler.m */, D29DF13921E68637003B2FB9 /* MFStyler.m */,
0A6682A92435125F00AD3CA1 /* Styler.swift */, 0A6682A92435125F00AD3CA1 /* Styler.swift */,
0A6682AB243531C300AD3CA1 /* Padding.swift */, 0A6682AB243531C300AD3CA1 /* Padding.swift */,
D23A8FD5260CDF01007E14CE /* MFStyler+PaddingExtension.swift */,
); );
path = Styles; path = Styles;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2843,6 +2846,7 @@
D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */, D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */,
D2C78CD224228BBD00B69FDE /* ActionOpenPanelModel.swift in Sources */, D2C78CD224228BBD00B69FDE /* ActionOpenPanelModel.swift in Sources */,
AA617AB02453010A00910B8F /* ListDeviceComplexLinkSmall.swift in Sources */, AA617AB02453010A00910B8F /* ListDeviceComplexLinkSmall.swift in Sources */,
D23A8FD9260CE004007E14CE /* MFStyler+PaddingExtension.swift in Sources */,
C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */, C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */,
01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */, 01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */,
D27CD4102339057800C1DC07 /* EyebrowHeadlineBodyLink.swift in Sources */, D27CD4102339057800C1DC07 /* EyebrowHeadlineBodyLink.swift in Sources */,

View File

@ -32,7 +32,7 @@ import UIKit
if let rightView = createRightView() { if let rightView = createRightView() {
addSubview(rightView) addSubview(rightView)
rightView.leftAnchor.constraint(equalTo: radioButton.rightAnchor, constant: PaddingHorizontalBetweenRelatedItems).isActive = true rightView.leftAnchor.constraint(equalTo: radioButton.rightAnchor, constant: Padding.Component.gutterForApplicationWidth).isActive = true
rightView.rightAnchor.constraint(equalTo: layoutMarginsGuide.rightAnchor, constant: 0).isActive = true rightView.rightAnchor.constraint(equalTo: layoutMarginsGuide.rightAnchor, constant: 0).isActive = true
var constraint = rightView.topAnchor.constraint(greaterThanOrEqualTo: layoutMarginsGuide.topAnchor, constant: PaddingOne) var constraint = rightView.topAnchor.constraint(greaterThanOrEqualTo: layoutMarginsGuide.topAnchor, constant: PaddingOne)

View File

@ -44,7 +44,7 @@ import UIKit
//constant //constant
let TabCellId = "TabCell" let TabCellId = "TabCell"
public let sectionPadding: CGFloat = 20.0 public let sectionPadding: CGFloat = Padding.Component.gutterForApplicationWidth
public let cellSpacing: CGFloat = 34.0 public let cellSpacing: CGFloat = 34.0
public let cellHeight: CGFloat = 27.0 public let cellHeight: CGFloat = 27.0
public let selectionLineHeight: CGFloat = 4.0 public let selectionLineHeight: CGFloat = 4.0
@ -198,11 +198,13 @@ extension Tabs: UICollectionViewDelegateFlowLayout {
} }
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
if !paddingBeforeFirstTab && section == 0 { guard section == 0 else {
return .zero
} else {
return UIEdgeInsets(top: 0, left: sectionPadding, bottom: 0, right: 0) return UIEdgeInsets(top: 0, left: sectionPadding, bottom: 0, right: 0)
} }
guard paddingBeforeFirstTab else {
return .zero
}
return UIEdgeInsets(top: 0, left: Padding.Component.horizontalPaddingForApplicationWidth, bottom: 0, right: 0)
} }
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {

View File

@ -51,7 +51,7 @@ import UIKit
stack.addArrangedSubview(primaryButton) stack.addArrangedSubview(primaryButton)
NSLayoutConstraint.constraintPinSubview(toSuperview: stack) NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
stack.axis = .horizontal stack.axis = .horizontal
stack.spacing = 12 stack.spacing = Padding.Component.gutterForApplicationWidth
equalWidthConstraint = secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1) equalWidthConstraint = secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1)
equalWidthConstraint?.isActive = true equalWidthConstraint?.isActive = true
} }

View File

@ -11,9 +11,7 @@
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
static let defaultSpacing: CGFloat = 16.0
public class var identifier: String { public class var identifier: String {
return "stack" return "stack"
} }
@ -21,7 +19,7 @@
public var backgroundColor: Color? public var backgroundColor: Color?
public var molecules: [StackItemModelProtocol & MoleculeModelProtocol] public var molecules: [StackItemModelProtocol & MoleculeModelProtocol]
public var axis: NSLayoutConstraint.Axis = .vertical public var axis: NSLayoutConstraint.Axis = .vertical
public var spacing: CGFloat = StackModel.defaultSpacing public var spacing: CGFloat = Padding.Four
public var useStackSpacingBeforeFirstItem = false public var useStackSpacingBeforeFirstItem = false
//-------------------------------------------------- //--------------------------------------------------
@ -35,6 +33,8 @@
} }
if let spacing = spacing { if let spacing = spacing {
self.spacing = spacing self.spacing = spacing
} else if axis == .horizontal {
self.spacing = Padding.Component.gutterForApplicationWidth
} }
super.init() super.init()
} }
@ -63,6 +63,8 @@
} }
if let spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing) { if let spacing = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .spacing) {
self.spacing = spacing self.spacing = spacing
} else if axis == .horizontal {
self.spacing = Padding.Component.gutterForApplicationWidth
} }
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
try super.init(from: decoder) try super.init(from: decoder)

View File

@ -55,6 +55,6 @@ public extension NSLayoutConstraint {
} }
leftView.leadingAnchor.constraint(equalTo: superView.layoutMarginsGuide.leadingAnchor).isActive = true leftView.leadingAnchor.constraint(equalTo: superView.layoutMarginsGuide.leadingAnchor).isActive = true
superView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightView.trailingAnchor).isActive = true superView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: rightView.trailingAnchor).isActive = true
rightView.leftAnchor.constraint(greaterThanOrEqualTo: leftView.rightAnchor, constant: PaddingHorizontalBetweenRelatedItems).isActive = true rightView.leftAnchor.constraint(greaterThanOrEqualTo: leftView.rightAnchor, constant: Padding.Component.gutterForApplicationWidth).isActive = true
} }
} }

View File

@ -0,0 +1,36 @@
//
// MFStyler+PaddingExtension.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/25/21.
// Copyright © 2021 Verizon Wireless. All rights reserved.
//
import Foundation
@objc public extension MFStyler {
@objc static func bridgeGetGutterSizeForForApplicationWidth() -> CGFloat {
Padding.Component.gutterForApplicationWidth
}
@objc static func bridgeGetGutterSize(for size: CGFloat) -> CGFloat {
Padding.Component.gutterFor(size: size)
}
@objc static func bridgeHorizontalPaddingFor(size: CGFloat) -> CGFloat {
Padding.Component.horizontalPaddingForSize(size)
}
@objc static func bridgeVerticalPaddingFor(size: CGFloat) -> CGFloat {
Padding.Component.verticalPaddingForSize(size)
}
@objc static func bridgeSetDefaultMarginsFor(view: UIView, size: CGFloat, horizontal: Bool = true, vertical: Bool = false) {
Styler.setDefaultMarginsFor(view, size: size, horizontal: horizontal, vertical: vertical)
}
@objc static func bridgeSetMarginsFor(view: UIView, size: CGFloat, horizontal: CGFloat, top: CGFloat, bottom: CGFloat) {
Styler.setMarginsFor(view, size: size, horizontal: horizontal, top: top, bottom: bottom)
}
}

View File

@ -14,6 +14,7 @@
#import "MVMCoreUISplitViewController.h" #import "MVMCoreUISplitViewController.h"
@import MVMCore.MVMCoreDispatchUtility; @import MVMCore.MVMCoreDispatchUtility;
#import <MVMCoreUI/MVMCoreUIUtility.h> #import <MVMCoreUI/MVMCoreUIUtility.h>
#import <MVMCoreUI/MVMCoreUI-Swift.h>
CGFloat const PaddingDefault = 24; CGFloat const PaddingDefault = 24;
CGFloat const PaddingDefaultHorizontalSpacing = 32; CGFloat const PaddingDefaultHorizontalSpacing = 32;
@ -26,7 +27,7 @@ CGFloat const PaddingVerticalWhiteGrayView = 72;
CGFloat const PaddingVerticalHeadlineAlternate = 48; CGFloat const PaddingVerticalHeadlineAlternate = 48;
CGFloat const PaddingPrimaryButtonTop = 36; CGFloat const PaddingPrimaryButtonTop = 36;
CGFloat const PaddingHorizontalBetweenRelatedItems = 16; CGFloat const PaddingHorizontalBetweenRelatedItems = 12;
CGFloat const PaddingOne = 6; CGFloat const PaddingOne = 6;
CGFloat const PaddingTwo = 12; CGFloat const PaddingTwo = 12;
CGFloat const PaddingThree = 18; CGFloat const PaddingThree = 18;
@ -77,23 +78,19 @@ CGFloat const LabelWithInternalButtonLineSpace = 2;
#pragma mark - Spacing Defaults #pragma mark - Spacing Defaults
+ (CGFloat)defaultHorizontalPaddingForApplicationWidth { + (CGFloat)defaultHorizontalPaddingForApplicationWidth {
MFSizeObject *sizeObject = [MFSizeObject sizeObjectWithStandardSize:16]; return [self bridgeHorizontalPaddingForSize:[MVMCoreUISplitViewController getApplicationViewWidth]];
[sizeObject addLargerThanCustomSize:32 forThreshold:MFSizeMostlySweetSpotThreshold];
return [sizeObject getValueBasedOnApplicationWidth];
} }
+ (CGFloat)defaultVerticalPaddingForApplicationWidth { + (CGFloat)defaultVerticalPaddingForApplicationWidth {
return [[MFSizeObject sizeObjectWithScalingStandardSize:PaddingDefaultVerticalSpacing] getValueBasedOnApplicationWidth]; return [self bridgeVerticalPaddingForSize:[MVMCoreUISplitViewController getApplicationViewWidth]];
} }
+ (CGFloat)defaultHorizontalPaddingForSize:(CGFloat)size { + (CGFloat)defaultHorizontalPaddingForSize:(CGFloat)size {
MFSizeObject *sizeObject = [MFSizeObject sizeObjectWithStandardSize:16]; return [self bridgeHorizontalPaddingForSize:size];
[sizeObject addLargerThanCustomSize:32 forThreshold:MFSizeMostlySweetSpotThreshold];
return [sizeObject getValueBasedOnSize:size];
} }
+ (CGFloat)defaultVerticalPaddingForSize:(CGFloat)size { + (CGFloat)defaultVerticalPaddingForSize:(CGFloat)size {
return [[MFSizeObject sizeObjectWithScalingStandardSize:PaddingDefaultVerticalSpacing] getValueBasedOnSize:size]; return [self bridgeVerticalPaddingForSize:size];
} }
+ (void)setDefaultMarginsForView:(nullable UIView *)view size:(CGFloat)size { + (void)setDefaultMarginsForView:(nullable UIView *)view size:(CGFloat)size {
@ -101,18 +98,13 @@ CGFloat const LabelWithInternalButtonLineSpace = 2;
} }
+ (void)setDefaultMarginsForView:(nullable UIView *)view size:(CGFloat)size horizontal:(BOOL)horizontal vertical:(BOOL)vertical { + (void)setDefaultMarginsForView:(nullable UIView *)view size:(CGFloat)size horizontal:(BOOL)horizontal vertical:(BOOL)vertical {
CGFloat horizontalPadding = horizontal ? [MFStyler defaultHorizontalPaddingForSize:size] : 0; if (!view) { return; }
CGFloat verticalPadding = vertical ? PaddingDefaultVerticalSpacing3 : 0; [self bridgeSetDefaultMarginsForView:view size:size horizontal:horizontal vertical:vertical];
[MVMCoreDispatchUtility performBlockOnMainThread:^{
[MVMCoreUIUtility setMarginsForView:view leading:horizontalPadding top:verticalPadding trailing:horizontalPadding bottom:verticalPadding];
}];
} }
+ (void)setMarginsForView:(nullable UIView *)view size:(CGFloat)size defaultHorizontal:(BOOL)horizontal top:(CGFloat)top bottom:(CGFloat)bottom { + (void)setMarginsForView:(nullable UIView *)view size:(CGFloat)size defaultHorizontal:(BOOL)horizontal top:(CGFloat)top bottom:(CGFloat)bottom {
CGFloat horizontalPadding = horizontal ? [MFStyler defaultHorizontalPaddingForSize:size] : 0; if (!view) { return; }
[MVMCoreDispatchUtility performBlockOnMainThread:^{ [self bridgeSetMarginsForView:view size:size horizontal:horizontal top:top bottom:bottom];
[MVMCoreUIUtility setMarginsForView:view leading:horizontalPadding top:top trailing:horizontalPadding bottom:bottom];
}];
} }
#pragma mark - 3.0 fonts #pragma mark - 3.0 fonts

View File

@ -24,27 +24,38 @@ public struct Padding {
public struct Component { public struct Component {
public static let Standard: CGFloat = 24 public static let Standard: CGFloat = 24
public static let HorizontalMarginSpacing: CGFloat = 16 public static let HorizontalMarginSpacing: CGFloat = 16
public static let LargeVerticalMarginSpacing: CGFloat = 32 public static let LargeMarginSpacingLarge: CGFloat = 32
public static let VerticalMarginSpacing: CGFloat = 24 public static let VerticalMarginSpacing: CGFloat = 24
public static let LargeVerticalMarginSpacing: CGFloat = 32
public static let HorizontalGutterSpacing: CGFloat = 12
public static let LargeHorizontalGutterSpacing: CGFloat = 24
public static var horizontalPaddingForApplicationWidth: CGFloat { public static var horizontalPaddingForApplicationWidth: CGFloat {
let sizeObject = MFSizeObject(standardSize: 16)! horizontalPaddingForSize(MVMCoreUISplitViewController.getApplicationViewWidth())
sizeObject.addLargerThanCustomSize(32, forThreshold: MFSizeMostlySweetSpotThreshold)
return sizeObject.getValueBasedOnApplicationWidth()
} }
public static var verticalPaddingForApplicationWidth: CGFloat { public static var verticalPaddingForApplicationWidth: CGFloat {
MFSizeObject(scalingStandardSize: VerticalMarginSpacing)?.getValueBasedOnApplicationWidth() ?? VerticalMarginSpacing verticalPaddingForSize(MVMCoreUISplitViewController.getApplicationViewWidth())
}
public static var gutterForApplicationWidth: CGFloat {
gutterFor(size: MVMCoreUISplitViewController.getApplicationViewWidth())
} }
public static func horizontalPaddingForSize(_ size: CGFloat) -> CGFloat { public static func horizontalPaddingForSize(_ size: CGFloat) -> CGFloat {
let sizeObject = MFSizeObject(standardSize: 16)! let sizeObject = MFSizeObject(standardSize: HorizontalMarginSpacing)!
sizeObject.addLargerThanCustomSize(32, forThreshold: MFSizeMostlySweetSpotThreshold) sizeObject.addLargerThanCustomSize(LargeMarginSpacingLarge, forThreshold: MFSizeMostlySweetSpotThreshold)
return sizeObject.getValueBased(onSize: size) return sizeObject.getValueBased(onSize: size)
} }
public static func verticalPaddingForSize(_ size: CGFloat) -> CGFloat { public static func verticalPaddingForSize(_ size: CGFloat) -> CGFloat {
MFSizeObject(scalingStandardSize: VerticalMarginSpacing)?.getValueBased(onSize: size) ?? VerticalMarginSpacing MFSizeObject(scalingStandardSize: VerticalMarginSpacing)?.getValueBased(onSize: size) ?? VerticalMarginSpacing
} }
public static func gutterFor(size: CGFloat) -> CGFloat {
let sizeObject = MFSizeObject(standardSize: HorizontalGutterSpacing)!
sizeObject.addLargerThanCustomSize(LargeHorizontalGutterSpacing, forThreshold: MFSizeMostlySweetSpotThreshold)
return sizeObject.getValueBased(onSize: size)
}
} }
} }