Skip to content
This repository has been archived by the owner on Dec 6, 2023. It is now read-only.

Commit

Permalink
Added a callback to the VSLEndpoint for missed calls (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
Redmer Loen authored Aug 17, 2017
1 parent bf75d80 commit 8c0513a
Show file tree
Hide file tree
Showing 17 changed files with 131 additions and 43 deletions.
16 changes: 8 additions & 8 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,29 @@ PODS:
- CocoaLumberjack/Default
- OCMock (3.4)
- Reachability (3.2)
- Vialer-pjsip-iOS (2.0.0)
- VialerSIPLib (2.5.0):
- Vialer-pjsip-iOS (2.0.1)
- VialerSIPLib (2.6.0):
- CocoaLumberjack
- Reachability
- Vialer-pjsip-iOS

DEPENDENCIES:
- CocoaLumberjack
- OCMock
- Reachability
- Vialer-pjsip-iOS
- VialerSIPLib (from `../`)

EXTERNAL SOURCES:
VialerSIPLib:
:path: "../"
:path: ../

SPEC CHECKSUMS:
CocoaLumberjack: c823149bccc5519a9447aeb433be7b1212a7d6a5
OCMock: 35ae71d6a8fcc1b59434d561d1520b9dd4f15765
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
Vialer-pjsip-iOS: e5287013fb3e0d74e79dd53e6d0bd9c92c3f52ce
VialerSIPLib: cfc554f12eb5f63f41ff366d4c1243fd16f0d6be
Vialer-pjsip-iOS: 8f9073448404525d53f3aa4b9517e3b2b9aae2c7
VialerSIPLib: dafb8b08b1c91a63b1cdc2148b435bc6d3754a8f

PODFILE CHECKSUM: a628ea4bf991636055e59a5a5193665110f91ffe
PODFILE CHECKSUM: 0f7b04fb045caf39ed7c2486524959b2d2be90e8

COCOAPODS: 1.2.0
COCOAPODS: 1.3.1
32 changes: 22 additions & 10 deletions Example/VialerSIPLib.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
1BA7C28357B3D0A901524F1D /* libPods-VialerSIPLib_Example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C992E639BDE1BC3A2E6AFDA /* libPods-VialerSIPLib_Example.a */; };
6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; };
6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
Expand All @@ -15,7 +16,7 @@
6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; };
A42E3E5E62665AFFE2C35A04 /* libPods-VialerSIPLib_Example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BA5E4030173982511E62EFFA /* libPods-VialerSIPLib_Example.a */; };
69A42F4168CC25692250FC2E /* libPods-VialerSIPLib_Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 77C1CF471F4C687176799590 /* libPods-VialerSIPLib_Tests.a */; };
C4021B691D426D5B003560F6 /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = C4021B681D426D5B003560F6 /* .gitignore */; };
C4021B6B1D426F22003560F6 /* Keys.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4021B6A1D426F22003560F6 /* Keys.swift */; };
C424B50B1C3BD27500178E52 /* VSLAccountConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C424B50A1C3BD27500178E52 /* VSLAccountConfigurationTests.m */; };
Expand All @@ -32,7 +33,6 @@
C457E49D1D3D070D0005D4B4 /* VSLTransferCallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C457E49C1D3D070D0005D4B4 /* VSLTransferCallViewController.swift */; };
C48B488E1D421CB100AB2875 /* SipUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48B488D1D421CB100AB2875 /* SipUser.swift */; };
C48B48901D42228900AB2875 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48B488F1D42228900AB2875 /* AppDelegate.swift */; };
DAEE78D0DFEE673BBB2D3BFA /* libPods-VialerSIPLib_Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FC9964E9ED02C94D58D97B6B /* libPods-VialerSIPLib_Tests.a */; };
EE79A6C51E2CFC0F00AC4AC7 /* VSLEndOfCallViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE79A6C41E2CFC0E00AC4AC7 /* VSLEndOfCallViewController.swift */; };
F26407E11DA7D6FE00393D4B /* CallKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F26407E01DA7D6FE00393D4B /* CallKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
F271B54E1DABD18F0028D620 /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F271B54D1DABD18F0028D620 /* IntentHandler.swift */; };
Expand Down Expand Up @@ -83,6 +83,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
2C992E639BDE1BC3A2E6AFDA /* libPods-VialerSIPLib_Example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VialerSIPLib_Example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
5D24E0A5A14D1689830035B2 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
6003F58A195388D20070C39A /* VialerSIPLib_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VialerSIPLib_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
Expand All @@ -97,8 +98,8 @@
606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; };
751644FF6D649E93790619BF /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
76745CA0AC066D9140030E21 /* Pods-VialerSIPLib_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VialerSIPLib_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VialerSIPLib_Tests/Pods-VialerSIPLib_Tests.debug.xcconfig"; sourceTree = "<group>"; };
77C1CF471F4C687176799590 /* libPods-VialerSIPLib_Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VialerSIPLib_Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
B5A48BF25EBC27EB07E2EE6C /* Pods-VialerSIPLib_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VialerSIPLib_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-VialerSIPLib_Example/Pods-VialerSIPLib_Example.release.xcconfig"; sourceTree = "<group>"; };
BA5E4030173982511E62EFFA /* libPods-VialerSIPLib_Example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VialerSIPLib_Example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
C4021B681D426D5B003560F6 /* .gitignore */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = .gitignore; path = ../.gitignore; sourceTree = "<group>"; };
C4021B6A1D426F22003560F6 /* Keys.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Keys.swift; sourceTree = "<group>"; };
C424B50A1C3BD27500178E52 /* VSLAccountConfigurationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VSLAccountConfigurationTests.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -150,7 +151,6 @@
F9906C221C3A85E80044EA99 /* VSLEndpointTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VSLEndpointTests.m; sourceTree = "<group>"; };
F9906C241C3A87EB0044EA99 /* NSStringPlusPJStringTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSStringPlusPJStringTests.m; sourceTree = "<group>"; };
F9D9EE551C51058800E10546 /* ringtone.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ringtone.wav; sourceTree = "<group>"; };
FC9964E9ED02C94D58D97B6B /* libPods-VialerSIPLib_Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VialerSIPLib_Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -162,7 +162,7 @@
6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */,
6003F592195388D20070C39A /* UIKit.framework in Frameworks */,
6003F58E195388D20070C39A /* Foundation.framework in Frameworks */,
A42E3E5E62665AFFE2C35A04 /* libPods-VialerSIPLib_Example.a in Frameworks */,
1BA7C28357B3D0A901524F1D /* libPods-VialerSIPLib_Example.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -173,7 +173,7 @@
6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */,
6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */,
6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */,
DAEE78D0DFEE673BBB2D3BFA /* libPods-VialerSIPLib_Tests.a in Frameworks */,
69A42F4168CC25692250FC2E /* libPods-VialerSIPLib_Tests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -218,8 +218,8 @@
6003F58F195388D20070C39A /* CoreGraphics.framework */,
6003F591195388D20070C39A /* UIKit.framework */,
6003F5AF195388D20070C39A /* XCTest.framework */,
BA5E4030173982511E62EFFA /* libPods-VialerSIPLib_Example.a */,
FC9964E9ED02C94D58D97B6B /* libPods-VialerSIPLib_Tests.a */,
2C992E639BDE1BC3A2E6AFDA /* libPods-VialerSIPLib_Example.a */,
77C1CF471F4C687176799590 /* libPods-VialerSIPLib_Tests.a */,
);
name = Frameworks;
sourceTree = "<group>";
Expand Down Expand Up @@ -534,13 +534,16 @@
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-VialerSIPLib_Tests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
1BAA19F4D9CB2AEC9D857651 /* [CP] Embed Pods Frameworks */ = {
Expand All @@ -564,9 +567,12 @@
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-VialerSIPLib_Example/Pods-VialerSIPLib_Example-resources.sh",
"$PODS_CONFIGURATION_BUILD_DIR/VialerSIPLib/VialerSIPLib.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
Expand All @@ -579,13 +585,16 @@
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-VialerSIPLib_Example-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
A7DA8E38CA26A0D6E7F924EC /* [CP] Copy Pods Resources */ = {
Expand All @@ -594,9 +603,12 @@
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-VialerSIPLib_Tests/Pods-VialerSIPLib_Tests-resources.sh",
"$PODS_CONFIGURATION_BUILD_DIR/VialerSIPLib/VialerSIPLib.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
Expand Down
2 changes: 1 addition & 1 deletion Example/VialerSIPLib/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

VialerSIPLib.sharedInstance().callManager.startCall(toNumber: handle, for:account, completion: { (call, error) in
if error != nil {
DDLogWrapper.logError("Could not create outbound call. Error:\(error)")
DDLogWrapper.logError("Could not create outbound call. Error: \(error!)")
}
})
}
Expand Down
8 changes: 4 additions & 4 deletions Example/VialerSIPLib/VSLCallViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class VSLCallViewController: UIViewController, VSLKeypadViewControllerDelegate {

callManager.toggleMute(for: call) { error in
if error != nil {
DDLogWrapper.logError("Error muting call: \(error)")
DDLogWrapper.logError("Error muting call: \(error!)")
}
DispatchQueue.main.async {
self.updateUI()
Expand Down Expand Up @@ -116,7 +116,7 @@ class VSLCallViewController: UIViewController, VSLKeypadViewControllerDelegate {

callManager.toggleHold(for: call) { error in
if error != nil {
DDLogWrapper.logError("Error holding call: \(error)")
DDLogWrapper.logError("Error holding call: \(error!)")
}
DispatchQueue.main.async {
self.updateUI()
Expand All @@ -141,7 +141,7 @@ class VSLCallViewController: UIViewController, VSLKeypadViewControllerDelegate {

callManager.toggleHold(for: call) { error in
if error != nil {
DDLogWrapper.logError("Error holding current call: \(error)")
DDLogWrapper.logError("Error holding current call: \(error!)")
return
}
DispatchQueue.main.async {
Expand All @@ -163,7 +163,7 @@ class VSLCallViewController: UIViewController, VSLKeypadViewControllerDelegate {

callManager.end(call) { error in
if error != nil {
DDLogWrapper.logError("error hanging up call(\(call.uuid.uuidString)): \(error)")
DDLogWrapper.logError("error hanging up call(\(call.uuid.uuidString)): \(error!)")
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Example/VialerSIPLib/VSLIncomingCallViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class VSLIncomingCallViewController: UIViewController {
guard let call = call else { return }
callManager.end(call) { error in
if error != nil {
DDLogWrapper.logError("cannot decline call: \(error)")
DDLogWrapper.logError("cannot decline call: \(error!)")
} else {
self.performSegue(withIdentifier: Configuration.Segues.UnwindToMainViewController, sender: nil)
}
Expand All @@ -77,7 +77,7 @@ class VSLIncomingCallViewController: UIViewController {
guard let call = call, call.callState == .incoming else { return }
callManager.answer(call) { error in
if error != nil {
DDLogWrapper.logError("error answering call: \(error)")
DDLogWrapper.logError("error answering call: \(error!)")
} else {
self.performSegue(withIdentifier: Configuration.Segues.ShowCall, sender: nil)
}
Expand Down
2 changes: 1 addition & 1 deletion Example/VialerSIPLib/VSLKeypadViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class VSLKeypadViewController: UIViewController {
guard let call = call, call.callState == .confirmed, let button = sender as? UIButton else { return }
callManager.sendDTMF(for: call, character: button.currentTitle!) { error in
if error != nil {
DDLogWrapper.logError("Error sending DTMF: \(error)")
DDLogWrapper.logError("Error sending DTMF: \(error ?? "Unknown Error" as! Error)")
} else {
DispatchQueue.main.async {
self.dtmfSent = self.dtmfSent + button.currentTitle!
Expand Down
8 changes: 4 additions & 4 deletions Example/VialerSIPLib/VSLSecondCallViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ class VSLSecondCallViewController: VSLCallViewController {
if firstCall.transfer(to: secondCall) {
callManager.end(firstCall) { error in
if error != nil {
DDLogWrapper.logError("Error hanging up call: \(error)")
DDLogWrapper.logError("Error hanging up call: \(error!)")
}
}
callManager.end(secondCall) { error in
if error != nil {
DDLogWrapper.logError("Error hanging up call: \(error)")
DDLogWrapper.logError("Error hanging up call: \(error!)")
}
}
performSegue(withIdentifier: Configuration.Segues.TransferInProgress, sender: nil)
Expand All @@ -76,7 +76,7 @@ class VSLSecondCallViewController: VSLCallViewController {

callManager.end(call) { error in
if error != nil {
DDLogWrapper.logError("Could not end call: \(error)")
DDLogWrapper.logError("Could not end call: \(error!))")
} else {
self.performSegue(withIdentifier: Configuration.Segues.UnwindToFirstCall, sender: nil)
}
Expand All @@ -90,7 +90,7 @@ class VSLSecondCallViewController: VSLCallViewController {
}
callManager.end(call) { error in
if error != nil {
DDLogWrapper.logError("Could not end call: \(error)")
DDLogWrapper.logError("Could not end call: \(error!)")
} else {
self.performSegue(withIdentifier: Configuration.Segues.UnwindToFirstCall, sender: nil)
}
Expand Down
2 changes: 1 addition & 1 deletion Example/VialerSIPLib/VSLTransferCallViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private var myContext = 0

callManager.startCall(toNumber: number, for: currentCall!.account! ) { (call, error) in
if error != nil {
DDLogWrapper.logError("Could not start second call: \(error)")
DDLogWrapper.logError("Could not start second call: \(error!)")
} else {
self.newCall = call
DispatchQueue.main.async {
Expand Down
2 changes: 0 additions & 2 deletions Pod/Classes/CallKitProviderDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
NSString * const CallKitProviderDelegateInboundCallAcceptedNotification = @"CallKitProviderDelegateInboundCallAccepted";
NSString * const CallKitProviderDelegateInboundCallRejectedNotification = @"CallKitProviderDelegateInboundCallRejected";

static const DDLogLevel ddLogLevel = DDLogLevelVerbose;

@interface CallKitProviderDelegate()
@property (strong, nonatomic) CXProvider *provider;
@property (weak, nonatomic) VSLCallManager *callManager;
Expand Down
2 changes: 1 addition & 1 deletion Pod/Classes/Configurations/VSLAccountConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//

#import <Foundation/Foundation.h>
#include <VialerPJSIP/pjsua-lib/pjsua.h>
#include <VialerPJSIP/pjsua.h>

/**
* The available stun to configure.
Expand Down
Loading

0 comments on commit 8c0513a

Please sign in to comment.