Skip to content

Commit

Permalink
fix bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
JmoVxia authored and JmoVxia committed Dec 15, 2021
1 parent 8073a9c commit 0c8f83e
Show file tree
Hide file tree
Showing 34 changed files with 157 additions and 93 deletions.
4 changes: 2 additions & 2 deletions CLPlayer.podspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Pod::Spec.new do |s|
s.name = 'CLPlayer'
s.version = '1.3.0'
s.version = '1.3.1'
s.summary = 'AVPlayer定制的视频播放器'
s.homepage = 'https://github.com/JmoVxia/CLPlayer'
s.license = 'MIT'
s.authors = {'JmoVxia' => '[email protected]'}
s.platform = :ios, '7.0'
s.platform = :ios, '10.0'
s.source = {:git => 'https://github.com/JmoVxia/CLPlayer.git', :tag => s.version}
s.source_files = 'CLPlayer/**/*.{h,m}'
s.resource = 'CLPlayer/Resource/CLPlayer.bundle'
Expand Down
19 changes: 19 additions & 0 deletions CLPlayer/CLImageHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// CLImageHelper.h
// CLPlayerDemo
//
// Created by JmoVxia on 2020/4/30.
// Copyright © 2020 JmoVxia. All rights reserved.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface CLImageHelper : NSObject

+ (UIImage *)imageWithName:(NSString *)name;

@end

NS_ASSUME_NONNULL_END
23 changes: 23 additions & 0 deletions CLPlayer/CLImageHelper.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// CLImageHelper.m
// CLPlayerDemo
//
// Created by JmoVxia on 2020/4/30.
// Copyright © 2020 JmoVxia. All rights reserved.
//

#import "CLImageHelper.h"

@implementation CLImageHelper

+ (UIImage *)imageWithName:(NSString *)name {
int scale = (int)UIScreen.mainScreen.scale;
scale = MIN(MAX(scale, 2), 3);
NSString *imageName = [NSString stringWithFormat:@"%@@%dx", name, scale];
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"CLPlayer" ofType:@"bundle"]];
NSString *path = [bundle pathForResource:imageName ofType:@"png"];
return [[UIImage imageWithContentsOfFile:path] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}


@end
34 changes: 13 additions & 21 deletions CLPlayer/CLPlayerMaskView.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
#import "CLPlayerMaskView.h"
#import "CLSlider.h"
#import "Masonry.h"
#import "CLImageHelper.h"

//间隙
#define Padding 10
//顶部底部工具条高度
#define ToolBarHeight 50
#define ToolBarHeight 40

@interface CLPlayerMaskView ()

Expand All @@ -24,6 +26,7 @@ @implementation CLPlayerMaskView
-(instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
[self initViews];
[self makeConstraints];
}
return self;
}
Expand Down Expand Up @@ -106,7 +109,7 @@ - (void)makeConstraints{
}];
//缓冲条
[self.progress mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.currentTimeLabel.mas_right).mas_offset(Padding);
make.left.mas_equalTo(self.currentTimeLabel.mas_right).mas_offset(Padding).priority(50);
make.right.mas_equalTo(self.totalTimeLabel.mas_left).mas_offset(-Padding);
make.height.mas_equalTo(2);
make.centerY.mas_equalTo(self.bottomToolBar);
Expand Down Expand Up @@ -162,8 +165,8 @@ - (CLRotateAnimationView *) loadingView{
- (UIButton *) backButton{
if (_backButton == nil){
_backButton = [[UIButton alloc] init];
[_backButton setImage:[self getPictureWithName:@"CLBackBtn"] forState:UIControlStateNormal];
[_backButton setImage:[self getPictureWithName:@"CLBackBtn"] forState:UIControlStateHighlighted];
[_backButton setImage:[CLImageHelper imageWithName:@"CLBackBtn"] forState:UIControlStateNormal];
[_backButton setImage:[CLImageHelper imageWithName:@"CLBackBtn"] forState:UIControlStateHighlighted];
[_backButton addTarget:self action:@selector(backButtonAction:) forControlEvents:UIControlEventTouchUpInside];
}
return _backButton;
Expand All @@ -172,8 +175,8 @@ - (UIButton *) backButton{
- (UIButton *) playButton{
if (_playButton == nil){
_playButton = [[UIButton alloc] init];
[_playButton setImage:[self getPictureWithName:@"CLPlayBtn"] forState:UIControlStateNormal];
[_playButton setImage:[self getPictureWithName:@"CLPauseBtn"] forState:UIControlStateSelected];
[_playButton setImage:[CLImageHelper imageWithName:@"CLPlayBtn"] forState:UIControlStateNormal];
[_playButton setImage:[CLImageHelper imageWithName:@"CLPauseBtn"] forState:UIControlStateSelected];
[_playButton addTarget:self action:@selector(playButtonAction:) forControlEvents:UIControlEventTouchUpInside];
}
return _playButton;
Expand All @@ -182,8 +185,8 @@ - (UIButton *) playButton{
- (UIButton *) fullButton{
if (_fullButton == nil){
_fullButton = [[UIButton alloc] init];
[_fullButton setImage:[self getPictureWithName:@"CLMaxBtn"] forState:UIControlStateNormal];
[_fullButton setImage:[self getPictureWithName:@"CLMinBtn"] forState:UIControlStateSelected];
[_fullButton setImage:[CLImageHelper imageWithName:@"CLMaxBtn"] forState:UIControlStateNormal];
[_fullButton setImage:[CLImageHelper imageWithName:@"CLMinBtn"] forState:UIControlStateSelected];
[_fullButton addTarget:self action:@selector(fullButtonAction:) forControlEvents:UIControlEventTouchUpInside];
}
return _fullButton;
Expand All @@ -192,6 +195,7 @@ - (UIButton *) fullButton{
- (UILabel *) currentTimeLabel{
if (_currentTimeLabel == nil){
_currentTimeLabel = [[UILabel alloc] init];
_currentTimeLabel.font = [UIFont systemFontOfSize:14];
_currentTimeLabel.textColor = [UIColor whiteColor];
_currentTimeLabel.adjustsFontSizeToFitWidth = YES;
_currentTimeLabel.text = @"00:00";
Expand All @@ -203,6 +207,7 @@ - (UILabel *) currentTimeLabel{
- (UILabel *) totalTimeLabel{
if (_totalTimeLabel == nil){
_totalTimeLabel = [[UILabel alloc] init];
_totalTimeLabel.font = [UIFont systemFontOfSize:14];
_totalTimeLabel.textColor = [UIColor whiteColor];
_totalTimeLabel.adjustsFontSizeToFitWidth = YES;
_totalTimeLabel.text = @"00:00";
Expand Down Expand Up @@ -308,17 +313,4 @@ - (void)progressSliderTouchEnded:(CLSlider *)slider{
NSLog(@"没有实现代理或者没有设置代理人");
}
}
#pragma mark - 布局
-(void)layoutSubviews{
[super layoutSubviews];
[self makeConstraints];
}
#pragma mark - 获取资源图片
- (UIImage *)getPictureWithName:(NSString *)name{
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"CLPlayer" ofType:@"bundle"]];
NSString *path = [bundle pathForResource:name ofType:@"png"];
return [[UIImage imageWithContentsOfFile:path] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}


@end
9 changes: 1 addition & 8 deletions CLPlayer/CLPlayerView.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ + (instancetype)defaultConfigure {
green:0.51373
blue:0.50980
alpha:1.00000];
configure.progressPlayFinishColor = [UIColor whiteColor];
configure.progressPlayFinishColor = [UIColor greenColor];
configure.progressBufferColor = [UIColor colorWithRed:0.84118
green:0.81373
blue:0.80980
Expand Down Expand Up @@ -85,8 +85,6 @@ @interface CLPlayerView ()<CLPlayerMaskViewDelegate,UIGestureRecognizerDelegate>
@property (nonatomic, assign) BOOL isDisappear;
/**用户点击播放标记*/
@property (nonatomic, assign) BOOL isUserPlay;
/**记录控制器状态栏状态*/
@property (nonatomic, assign) BOOL statusBarHiddenState;
/**点击最大化标记*/
@property (nonatomic, assign) BOOL isUserTapMaxButton;
/**播放完成标记*/
Expand Down Expand Up @@ -761,12 +759,10 @@ - (void)fullScreenWithDirection:(UIInterfaceOrientation)direction{
//播放器所在控制器不支持旋转,采用旋转view的方式实现
CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
if (direction == UIInterfaceOrientationLandscapeLeft){
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
[UIView animateWithDuration:duration animations:^{
self.transform = CGAffineTransformMakeRotation(M_PI / 2);
}];
}else if (direction == UIInterfaceOrientationLandscapeRight) {
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:YES];
[UIView animateWithDuration:duration animations:^{
self.transform = CGAffineTransformMakeRotation( - M_PI / 2);
}];
Expand All @@ -782,7 +778,6 @@ - (void)originalscreen{
_isFullScreen = NO;
_isUserTapMaxButton = NO;
[self resetTopToolBarHiddenType];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
if (self.configure.isLandscape) {
//还原为竖屏
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:@"orientation"];
Expand Down Expand Up @@ -835,8 +830,6 @@ - (void)dealloc{
object:nil];
//回到竖屏
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:@"orientation"];
//重置状态条
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
#ifdef DEBUG
NSLog(@"播放器被销毁了");
#endif
Expand Down
10 changes: 9 additions & 1 deletion CLPlayer/CLRotateAnimationView.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ + (instancetype)defaultConfigure {
configure.intervalDuration = 0.12;
configure.duration = 2;
configure.diameter = 8;
configure.backgroundColor = [UIColor colorWithRed:0.96 green:0.67 blue:0.06 alpha:1.00];
configure.backgroundColor = [UIColor redColor];
return configure;
}

Expand All @@ -28,6 +28,8 @@ @interface CLRotateAnimationView ()

///默认配置
@property (nonatomic, strong) CLRotateAnimationViewConfigure *defaultConfigure;
///是否开始动画
@property (nonatomic, assign) BOOL isStart;
///是否暂停
@property (nonatomic, assign) BOOL isPause;
///layer数组
Expand Down Expand Up @@ -81,20 +83,26 @@ - (void)updateWithConfigure:(void(^)(CLRotateAnimationViewConfigure *configure))
}
CGFloat intervalDuration = (CGFloat)(self.defaultConfigure.duration / 2.0 / (CGFloat)self.defaultConfigure.number);
self.defaultConfigure.intervalDuration = MIN(self.defaultConfigure.intervalDuration, intervalDuration);
if (self.isStart) {
[self stopAnimation];
[self startAnimation];
}
}
//MARK:JmoVxia---开始动画
- (void)startAnimation {
[self animation];
for (CALayer *layer in self.layerArray) {
[self.layer addSublayer:layer];
}
self.isStart = YES;
}
//MARK:JmoVxia---结束动画
- (void)stopAnimation {
for (CALayer *layer in self.layerArray) {
[layer removeFromSuperlayer];
}
[self.layerArray removeAllObjects];
self.isStart = NO;
}
//MARK:JmoVxia---暂停动画
- (void)pauseAnimation {
Expand Down
9 changes: 3 additions & 6 deletions CLPlayer/CLSlider.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#import "CLSlider.h"
#import "CLImageHelper.h"

#define SLIDER_X_BOUND 30
#define SLIDER_Y_BOUND 40
Expand All @@ -25,7 +26,7 @@ -(instancetype)initWithFrame:(CGRect)frame{
return self;
}
- (void)setup {
UIImage *thumbImage = [self getPictureWithName:@"CLRound"];
UIImage *thumbImage = [CLImageHelper imageWithName:@"CLRound"];
[self setThumbImage:thumbImage forState:UIControlStateHighlighted];
[self setThumbImage:thumbImage forState:UIControlStateNormal];
}
Expand Down Expand Up @@ -77,11 +78,7 @@ - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
return result;
}
#pragma mark - 获取资源图片
- (UIImage *)getPictureWithName:(NSString *)name{
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"CLPlayer" ofType:@"bundle"]];
NSString *path = [bundle pathForResource:name ofType:@"png"];
return [[UIImage imageWithContentsOfFile:path] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}



@end
Binary file removed CLPlayer/Resource/CLPlayer.bundle/CLBackBtn.png
Binary file not shown.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed CLPlayer/Resource/CLPlayer.bundle/CLMaxBtn.png
Binary file not shown.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed CLPlayer/Resource/CLPlayer.bundle/CLMinBtn.png
Binary file not shown.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed CLPlayer/Resource/CLPlayer.bundle/CLPauseBtn.png
Binary file not shown.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed CLPlayer/Resource/CLPlayer.bundle/CLPlayBtn.png
Binary file not shown.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed CLPlayer/Resource/CLPlayer.bundle/CLRound.png
Binary file not shown.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added CLPlayer/Resource/CLPlayer.bundle/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions CLPlayerDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
5B1FC4D61DC850820036C489 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5B1FC4D41DC850820036C489 /* LaunchScreen.storyboard */; };
5B1FC4FB1DC850EF0036C489 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B1FC4FA1DC850EF0036C489 /* MediaPlayer.framework */; settings = {ATTRIBUTES = (Required, ); }; };
5B35DDE41DE07F9A00CEB057 /* Date.json in Resources */ = {isa = PBXBuildFile; fileRef = 5B35DDE31DE07F9A00CEB057 /* Date.json */; };
5B44EA09245A7EC900A99EA8 /* CLImageHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B44EA08245A7EC900A99EA8 /* CLImageHelper.m */; };
5B456F8F1E60164000C9599F /* UIView+CLSetRect.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B456F8E1E60164000C9599F /* UIView+CLSetRect.m */; };
5B47242221D53F2600840F92 /* video.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 5B47242121D53F2500840F92 /* video.mp4 */; };
5B73AAB91DCB0881007680C1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5B73AAB81DCB0881007680C1 /* Assets.xcassets */; };
Expand Down Expand Up @@ -53,6 +54,8 @@
5B1FC4D71DC850820036C489 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
5B1FC4FA1DC850EF0036C489 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
5B35DDE31DE07F9A00CEB057 /* Date.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Date.json; sourceTree = "<group>"; };
5B44EA07245A7EC900A99EA8 /* CLImageHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CLImageHelper.h; sourceTree = "<group>"; };
5B44EA08245A7EC900A99EA8 /* CLImageHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CLImageHelper.m; sourceTree = "<group>"; };
5B456F8D1E60164000C9599F /* UIView+CLSetRect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+CLSetRect.h"; sourceTree = "<group>"; };
5B456F8E1E60164000C9599F /* UIView+CLSetRect.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+CLSetRect.m"; sourceTree = "<group>"; };
5B47242121D53F2500840F92 /* video.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = video.mp4; sourceTree = "<group>"; };
Expand Down Expand Up @@ -317,6 +320,8 @@
0C78B788237ED9880072BB9E /* CLRotateAnimationView.m */,
5BDEA7131E63F4BB00953D5D /* CLSlider.h */,
5BDEA7141E63F4BB00953D5D /* CLSlider.m */,
5B44EA07245A7EC900A99EA8 /* CLImageHelper.h */,
5B44EA08245A7EC900A99EA8 /* CLImageHelper.m */,
5BA0AF501F4292670097B9B2 /* UINavigationController+CLPlayerRotation.h */,
5BA0AF511F4292670097B9B2 /* UINavigationController+CLPlayerRotation.m */,
5BA0AF521F4292670097B9B2 /* UITabBarController+CLPlayerRotation.h */,
Expand Down Expand Up @@ -443,6 +448,7 @@
5BB4D0EB1F31B775007A1742 /* CLViewController3.m in Sources */,
5BB4D0D91F31A1F1007A1742 /* CLTableViewViewController.m in Sources */,
5BB4D0F41F331FA1007A1742 /* CLNavigationViewController.m in Sources */,
5B44EA09245A7EC900A99EA8 /* CLImageHelper.m in Sources */,
5BB4D0E51F31AEC8007A1742 /* CLViewController2.m in Sources */,
5BB4D0DC1F31A2E3007A1742 /* CLTabBarViewController.m in Sources */,
5BA0AF581F4292670097B9B2 /* UIViewController+CLPlayerRotation.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1140"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand All @@ -27,8 +27,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
Expand All @@ -38,8 +36,8 @@
ReferencedContainer = "container:CLPlayerDemo.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
Expand All @@ -61,8 +59,6 @@
ReferencedContainer = "container:CLPlayerDemo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand Down
4 changes: 3 additions & 1 deletion CLPlayerDemo/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
return YES;
}


- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
Expand Down
Loading

0 comments on commit 0c8f83e

Please sign in to comment.