Skip to content

Commit 3adaee7

Browse files
author
Fumito Nakazawa
authored
Merge pull request #17 from cats-oss/support-xcode10
Support Xcode10
2 parents 50fa42d + 2ae99bb commit 3adaee7

File tree

10 files changed

+125
-28
lines changed

10 files changed

+125
-28
lines changed

Demo/SicaDemo.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@
320320
PRODUCT_BUNDLE_IDENTIFIER = "com.funzin.sica-demo-app";
321321
PRODUCT_NAME = "$(TARGET_NAME)";
322322
PROVISIONING_PROFILE_SPECIFIER = "";
323-
SWIFT_VERSION = 4.0;
323+
SWIFT_VERSION = 4.2;
324324
TARGETED_DEVICE_FAMILY = "1,2";
325325
};
326326
name = Debug;
@@ -341,7 +341,7 @@
341341
PRODUCT_BUNDLE_IDENTIFIER = "com.funzin.sica-demo-app";
342342
PRODUCT_NAME = "$(TARGET_NAME)";
343343
PROVISIONING_PROFILE_SPECIFIER = "";
344-
SWIFT_VERSION = 4.0;
344+
SWIFT_VERSION = 4.2;
345345
TARGETED_DEVICE_FAMILY = "1,2";
346346
};
347347
name = Release;

Demo/SicaDemo/AppDelegate.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
1313

1414
var window: UIWindow?
1515

16-
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
16+
#if swift(>=4.2)
17+
typealias LaunchOptionsKey = UIApplication.LaunchOptionsKey
18+
#else
19+
typealias LaunchOptionsKey = UIApplicationLaunchOptionsKey
20+
#endif
21+
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [LaunchOptionsKey: Any]?) -> Bool {
1722
// Override point for customization after application launch.
1823
return true
1924
}

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<p align="center">
77
<img src="http://img.shields.io/badge/platform-iOS | tvOS | macOS-blue.svg?style=flat" alt="Platform" />
88
<a href="https://developer.apple.com/swift">
9-
<img src="http://img.shields.io/badge/language-swift-brightgreen.svg?style=flat" alt="Language" />
9+
<img src="http://img.shields.io/badge/Swift-4.1%20|%204.2-brightgreen.svg?style=flat" alt="Language">
1010
</a>
1111
<a href="https://github.com/Carthage/Carthage">
1212
<img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat" alt="Carthage" />
@@ -33,10 +33,11 @@ Sica can execute various animations sequentially or parallelly.
3333
- Transition
3434

3535
## Requirements
36-
- Xcode 9.3
36+
- Xcode 9.3 or greater
3737
- iOS 9 or greater
3838
- tvOS 10.0 or greater
3939
- macOS 10.11 or greater
40+
- Swift 4.2 (since 0.3.4)
4041

4142

4243
## Installation
@@ -63,7 +64,7 @@ pod 'Sica'
6364
Sica is available through `SwiftPM`, create ` Package.swift` and add `dependencies` value
6465
```Package.swift
6566
dependencies: [
66-
.package(url: "https://github.com/cats-oss/Sica.git", from: "0.3.3")
67+
.package(url: "https://github.com/cats-oss/Sica.git", from: "0.3.4")
6768
]
6869
```
6970
See also: [GitHub - j-channings/swift-package-manager-ios: Example of how to use SPM v4 to manage iOS dependencies](https://github.com/j-channings/swift-package-manager-ios)

Sica.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Pod::Spec.new do |s|
1010
s.name = "Sica"
11-
s.version = "0.3.3"
11+
s.version = "0.3.4"
1212
s.summary = "Sica can execute various animations sequentially or parallely"
1313
s.homepage = "https://github.com/cats-oss/Sica"
1414
s.license = { :type => "MIT", :file => "LICENSE" }
@@ -18,5 +18,5 @@ Pod::Spec.new do |s|
1818
s.osx.deployment_target = "10.11"
1919
s.source = { :git => "https://github.com/cats-oss/Sica.git", :tag => "#{s.version}" }
2020
s.source_files = "Sica/**/*.{swift}"
21-
s.swift_version = '4.1'
21+
s.swift_version = '4.2'
2222
end

Sica.xcodeproj/project.pbxproj

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
313DA7AB215D2C3100842816 /* FillMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313DA7AA215D2C3100842816 /* FillMode.swift */; };
11+
313DA7AC215D2DBC00842816 /* FillMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313DA7AA215D2C3100842816 /* FillMode.swift */; };
12+
313DA7AD215D2DBD00842816 /* FillMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313DA7AA215D2C3100842816 /* FillMode.swift */; };
1013
9D436C3220E9E4DD00A1B938 /* TimingFunction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4CB78C620AC2BDD003232F6 /* TimingFunction.swift */; };
1114
9D436C3320E9E4DD00A1B938 /* Transition.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4CB78C220AC2BDD003232F6 /* Transition.swift */; };
1215
9D436C3420E9E4DD00A1B938 /* CAAnimation+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4CB78C120AC2BDD003232F6 /* CAAnimation+Extension.swift */; };
@@ -64,6 +67,7 @@
6467
/* End PBXContainerItemProxy section */
6568

6669
/* Begin PBXFileReference section */
70+
313DA7AA215D2C3100842816 /* FillMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FillMode.swift; sourceTree = "<group>"; };
6771
9D436C3F20E9E4DD00A1B938 /* Sica.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Sica.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6872
9D436C4120E9E62700A1B938 /* Info-macOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-macOS.plist"; sourceTree = "<group>"; };
6973
9D436C5120E9E71900A1B938 /* Sica.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Sica.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -196,6 +200,7 @@
196200
D4CB78C420AC2BDD003232F6 /* Animator.swift */,
197201
D4CB78C120AC2BDD003232F6 /* CAAnimation+Extension.swift */,
198202
D449535220EE1F20004C8AB9 /* CALayer+Sica.swift */,
203+
313DA7AA215D2C3100842816 /* FillMode.swift */,
199204
D4CB78C620AC2BDD003232F6 /* TimingFunction.swift */,
200205
D4CB78C220AC2BDD003232F6 /* Transition.swift */,
201206
D449535020EE1BAF004C8AB9 /* View+Sica.swift */,
@@ -482,6 +487,7 @@
482487
9D436C3420E9E4DD00A1B938 /* CAAnimation+Extension.swift in Sources */,
483488
9D436C3520E9E4DD00A1B938 /* Animator.swift in Sources */,
484489
9D68159820EF10BF007B3FB0 /* View+Sica.swift in Sources */,
490+
313DA7AC215D2DBC00842816 /* FillMode.swift in Sources */,
485491
9D436C3620E9E4DD00A1B938 /* AnimationKeyPaths.swift in Sources */,
486492
9D68159620EF10BB007B3FB0 /* CALayer+Sica.swift in Sources */,
487493
);
@@ -496,6 +502,7 @@
496502
9D436C4620E9E71900A1B938 /* CAAnimation+Extension.swift in Sources */,
497503
9D436C4720E9E71900A1B938 /* Animator.swift in Sources */,
498504
9D68159920EF10BF007B3FB0 /* View+Sica.swift in Sources */,
505+
313DA7AD215D2DBD00842816 /* FillMode.swift in Sources */,
499506
9D436C4820E9E71900A1B938 /* AnimationKeyPaths.swift in Sources */,
500507
9D68159720EF10BC007B3FB0 /* CALayer+Sica.swift in Sources */,
501508
);
@@ -526,6 +533,7 @@
526533
D4CB78CA20AC2BDD003232F6 /* CAAnimation+Extension.swift in Sources */,
527534
D4CB78CD20AC2BDD003232F6 /* Animator.swift in Sources */,
528535
D449535320EE1F20004C8AB9 /* CALayer+Sica.swift in Sources */,
536+
313DA7AB215D2C3100842816 /* FillMode.swift in Sources */,
529537
D449535120EE1BAF004C8AB9 /* View+Sica.swift in Sources */,
530538
D4CB78CE20AC2BDD003232F6 /* AnimationKeyPaths.swift in Sources */,
531539
);
@@ -584,7 +592,7 @@
584592
PROVISIONING_PROFILE_SPECIFIER = "";
585593
SDKROOT = macosx;
586594
SKIP_INSTALL = YES;
587-
SWIFT_VERSION = 4.0;
595+
SWIFT_VERSION = 4.2;
588596
TARGETED_DEVICE_FAMILY = "1,2";
589597
};
590598
name = Debug;
@@ -613,7 +621,7 @@
613621
PROVISIONING_PROFILE_SPECIFIER = "";
614622
SDKROOT = macosx;
615623
SKIP_INSTALL = YES;
616-
SWIFT_VERSION = 4.0;
624+
SWIFT_VERSION = 4.2;
617625
TARGETED_DEVICE_FAMILY = "1,2";
618626
};
619627
name = Release;
@@ -641,7 +649,7 @@
641649
PROVISIONING_PROFILE_SPECIFIER = "";
642650
SDKROOT = appletvos;
643651
SKIP_INSTALL = YES;
644-
SWIFT_VERSION = 4.0;
652+
SWIFT_VERSION = 4.2;
645653
TARGETED_DEVICE_FAMILY = 3;
646654
TVOS_DEPLOYMENT_TARGET = 10.0;
647655
};
@@ -670,7 +678,7 @@
670678
PROVISIONING_PROFILE_SPECIFIER = "";
671679
SDKROOT = appletvos;
672680
SKIP_INSTALL = YES;
673-
SWIFT_VERSION = 4.0;
681+
SWIFT_VERSION = 4.2;
674682
TARGETED_DEVICE_FAMILY = 3;
675683
TVOS_DEPLOYMENT_TARGET = 10.0;
676684
};
@@ -693,7 +701,7 @@
693701
PRODUCT_NAME = SicaTests;
694702
PROVISIONING_PROFILE_SPECIFIER = "";
695703
SDKROOT = appletvos;
696-
SWIFT_VERSION = 4.0;
704+
SWIFT_VERSION = 4.2;
697705
TARGETED_DEVICE_FAMILY = 3;
698706
};
699707
name = Debug;
@@ -715,7 +723,7 @@
715723
PRODUCT_NAME = SicaTests;
716724
PROVISIONING_PROFILE_SPECIFIER = "";
717725
SDKROOT = appletvos;
718-
SWIFT_VERSION = 4.0;
726+
SWIFT_VERSION = 4.2;
719727
TARGETED_DEVICE_FAMILY = 3;
720728
};
721729
name = Release;
@@ -737,7 +745,7 @@
737745
PRODUCT_NAME = SicaTests;
738746
PROVISIONING_PROFILE_SPECIFIER = "";
739747
SDKROOT = macosx;
740-
SWIFT_VERSION = 4.0;
748+
SWIFT_VERSION = 4.2;
741749
TARGETED_DEVICE_FAMILY = "1,2";
742750
};
743751
name = Debug;
@@ -759,7 +767,7 @@
759767
PRODUCT_NAME = SicaTests;
760768
PROVISIONING_PROFILE_SPECIFIER = "";
761769
SDKROOT = macosx;
762-
SWIFT_VERSION = 4.0;
770+
SWIFT_VERSION = 4.2;
763771
TARGETED_DEVICE_FAMILY = "1,2";
764772
};
765773
name = Release;
@@ -906,7 +914,7 @@
906914
PRODUCT_NAME = Sica;
907915
PROVISIONING_PROFILE_SPECIFIER = "";
908916
SKIP_INSTALL = YES;
909-
SWIFT_VERSION = 4.0;
917+
SWIFT_VERSION = 4.2;
910918
TARGETED_DEVICE_FAMILY = "1,2";
911919
};
912920
name = Debug;
@@ -933,7 +941,7 @@
933941
PRODUCT_NAME = Sica;
934942
PROVISIONING_PROFILE_SPECIFIER = "";
935943
SKIP_INSTALL = YES;
936-
SWIFT_VERSION = 4.0;
944+
SWIFT_VERSION = 4.2;
937945
TARGETED_DEVICE_FAMILY = "1,2";
938946
};
939947
name = Release;
@@ -954,7 +962,7 @@
954962
PRODUCT_BUNDLE_IDENTIFIER = "com.cats-oss.SicaTests";
955963
PRODUCT_NAME = SicaTests;
956964
PROVISIONING_PROFILE_SPECIFIER = "";
957-
SWIFT_VERSION = 4.0;
965+
SWIFT_VERSION = 4.2;
958966
TARGETED_DEVICE_FAMILY = "1,2";
959967
};
960968
name = Debug;
@@ -975,7 +983,7 @@
975983
PRODUCT_BUNDLE_IDENTIFIER = "com.cats-oss.SicaTests";
976984
PRODUCT_NAME = SicaTests;
977985
PROVISIONING_PROFILE_SPECIFIER = "";
978-
SWIFT_VERSION = 4.0;
986+
SWIFT_VERSION = 4.2;
979987
TARGETED_DEVICE_FAMILY = "1,2";
980988
};
981989
name = Release;

Sica/Source/Animator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public final class Animator {
107107
}
108108
group.animations = animations
109109
group.duration = totalDuration(type: type)
110-
group.fillMode = kCAFillModeForwards
110+
group.fillMode = FillMode.forwards.rawValue
111111
group.isRemovedOnCompletion = isRemovedOnCompletion
112112

113113
if let completion = completion {

Sica/Source/CAAnimation+Extension.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ extension CAAnimation {
1313
self.beginTime = delay
1414
self.duration = duration
1515
self.timingFunction = timingFunction.rawValue
16-
self.fillMode = kCAFillModeForwards
16+
self.fillMode = FillMode.forwards.rawValue
1717
self.isRemovedOnCompletion = isRemovedOnCompletion
1818
}
1919
}

Sica/Source/FillMode.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// FillMode.swift
3+
// Sica-iOS
4+
//
5+
// Created by 中澤郁斗 on 2018/09/28.
6+
// Copyright © 2018年 中澤 郁斗. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
public struct FillMode {
12+
#if swift(>=4.2)
13+
typealias RawValue = CAMediaTimingFillMode
14+
public static let forwards = FillMode(rawValue: .forwards)
15+
public static let backwards = FillMode(rawValue: .backwards)
16+
public static let both = FillMode(rawValue: .both)
17+
public static let removed = FillMode(rawValue: .removed)
18+
#else
19+
typealias RawValue = String
20+
public static let forwards = FillMode(rawValue: kCAFillModeForwards)
21+
public static let backwards = FillMode(rawValue: kCAFillModeBackwards)
22+
public static let both = FillMode(rawValue: kCAFillModeBoth)
23+
public static let removed = FillMode(rawValue: kCAFillModeRemoved)
24+
#endif
25+
26+
let rawValue: RawValue
27+
}

Sica/Source/TimingFunction.swift

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,70 @@
99
import QuartzCore
1010

1111
public struct TimingFunction {
12+
#if swift(>=4.2)
13+
public typealias NameValue = CAMediaTimingFunctionName
14+
public static let `default` = TimingFunction(name: CAMediaTimingFunctionName.default)
15+
public static let linear = TimingFunction(name: CAMediaTimingFunctionName.linear)
16+
public static let easeIn = TimingFunction(name: CAMediaTimingFunctionName.easeIn)
17+
public static let easeOut = TimingFunction(name: CAMediaTimingFunctionName.easeOut)
18+
public static let easeInEaseOut = TimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
19+
#else
20+
public typealias NameValue = String
1221
public static let `default` = TimingFunction(name: kCAMediaTimingFunctionDefault)
1322
public static let linear = TimingFunction(name: kCAMediaTimingFunctionLinear)
1423
public static let easeIn = TimingFunction(name: kCAMediaTimingFunctionEaseIn)
1524
public static let easeOut = TimingFunction(name: kCAMediaTimingFunctionEaseOut)
1625
public static let easeInEaseOut = TimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
26+
#endif
1727

18-
public let name: String
28+
29+
public let name: NameValue
1930
public let rawValue: CAMediaTimingFunction
2031

21-
init(name: String) {
32+
init(name: NameValue) {
2233
self.name = name
2334
self.rawValue = CAMediaTimingFunction(name: name)
2435
}
2536

26-
init(name: String, rawValue: CAMediaTimingFunction) {
37+
init(name: NameValue, rawValue: CAMediaTimingFunction) {
2738
self.name = name
2839
self.rawValue = rawValue
2940
}
3041

31-
public init(name: String, controlPoints c1x: Float, _ c1y: Float, _ c2x: Float, _ c2y: Float) {
42+
public init(name: NameValue, controlPoints c1x: Float, _ c1y: Float, _ c2x: Float, _ c2y: Float) {
3243
self.name = name
3344
self.rawValue = CAMediaTimingFunction(controlPoints: c1x, c1y, c2x, c2y)
3445
}
3546
}
3647

3748
// - SeeAlso: https://github.com/ai/easings.net/
3849
extension TimingFunction {
50+
#if swift(>=4.2)
51+
public static let easeInSine = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInSine"), controlPoints: 0.47, 0, 0.745, 0.715)
52+
public static let easeOutSine = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeOutSine"), controlPoints: 0.39, 0.575, 0.565, 1)
53+
public static let easeInOutSine = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInOutSine"), controlPoints: 0.445, 0.05, 0.55, 0.95)
54+
public static let easeInQuad = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInQuad"), controlPoints: 0.55, 0.085, 0.68, 0.53)
55+
public static let easeOutQuad = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeOutQuad"), controlPoints: 0.25, 0.46, 0.45, 0.94)
56+
public static let easeInOutQuad = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInOutQuad"), controlPoints: 0.455, 0.03, 0.515, 0.955)
57+
public static let easeInCubic = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInCubic"), controlPoints: 0.55, 0.055, 0.675, 0.19)
58+
public static let easeOutCubic = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeOutCubic"), controlPoints: 0.215, 0.61, 0.355, 1)
59+
public static let easeInOutCubic = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInOutCubic"), controlPoints: 0.645, 0.045, 0.355, 1)
60+
public static let easeInQuart = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInQuart"), controlPoints: 0.895, 0.03, 0.685, 0.22)
61+
public static let easeOutQuart = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeOutQuart"), controlPoints: 0.165, 0.84, 0.44, 1)
62+
public static let easeInOutQuart = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInOutQuart"), controlPoints: 0.77, 0, 0.175, 1)
63+
public static let easeInQuint = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInQuint"), controlPoints: 0.755, 0.05, 0.855, 0.06)
64+
public static let easeOutQuint = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeOutQuint"), controlPoints: 0.23, 1, 0.32, 1)
65+
public static let easeInOutQuint = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInOutQuint"), controlPoints: 0.86, 0, 0.07, 1)
66+
public static let easeInExpo = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInExpo"), controlPoints: 0.95, 0.05, 0.795, 0.035)
67+
public static let easeOutExpo = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeOutExpo"), controlPoints: 0.19, 1, 0.22, 1)
68+
public static let easeInOutExpo = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInOutExpo"), controlPoints: 1, 0, 0, 1)
69+
public static let easeInCirc = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInCirc"), controlPoints: 0.6, 0.04, 0.98, 0.335)
70+
public static let easeOutCirc = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeOutCirc"), controlPoints: 0.075, 0.82, 0.165, 1)
71+
public static let easeInOutCirc = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInOutCirc"), controlPoints: 0.785, 0.135, 0.15, 0.86)
72+
public static let easeInBack = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInBack"), controlPoints: 0.6, -0.28, 0.735, 0.045)
73+
public static let easeOutBack = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeOutBack"), controlPoints: 0.175, 0.885, 0.32, 1.275)
74+
public static let easeInOutBack = TimingFunction(name: TimingFunction.NameValue(rawValue: "easeInOutBack"), controlPoints: 0.68, -0.55, 0.265, 1.55)
75+
#else
3976
public static let easeInSine = TimingFunction(name: "easeInSine", controlPoints: 0.47, 0, 0.745, 0.715)
4077
public static let easeOutSine = TimingFunction(name: "easeOutSine", controlPoints: 0.39, 0.575, 0.565, 1)
4178
public static let easeInOutSine = TimingFunction(name: "easeInOutSine", controlPoints: 0.445, 0.05, 0.55, 0.95)
@@ -60,4 +97,5 @@ extension TimingFunction {
6097
public static let easeInBack = TimingFunction(name: "easeInBack", controlPoints: 0.6, -0.28, 0.735, 0.045)
6198
public static let easeOutBack = TimingFunction(name: "easeOutBack", controlPoints: 0.175, 0.885, 0.32, 1.275)
6299
public static let easeInOutBack = TimingFunction(name: "easeInOutBack", controlPoints: 0.68, -0.55, 0.265, 1.55)
100+
#endif
63101
}

0 commit comments

Comments
 (0)