Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
flutter_plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
林生雨
flutter_plugin
Commits
a4dd2854
Commit
a4dd2854
authored
Nov 05, 2019
by
林生雨
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
commit
parent
e751423d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
96 additions
and
95 deletions
+96
-95
workspace.xml
.idea/workspace.xml
+0
-1
Info.plist
example/ios/Runner/Info.plist
+0
-12
GengmeiFlutterPlugin.m
ios/Classes/GengmeiFlutterPlugin.m
+96
-82
No files found.
.idea/workspace.xml
View file @
a4dd2854
...
@@ -292,7 +292,6 @@
...
@@ -292,7 +292,6 @@
</component>
</component>
<component
name=
"ToolWindowManager"
>
<component
name=
"ToolWindowManager"
>
<frame
x=
"3"
y=
"23"
width=
"1440"
height=
"811"
extended-state=
"6"
/>
<frame
x=
"3"
y=
"23"
width=
"1440"
height=
"811"
extended-state=
"6"
/>
<editor
active=
"true"
/>
<layout>
<layout>
<window_info
content_ui=
"combo"
id=
"Project"
order=
"0"
visible=
"true"
weight=
"0.19742489"
/>
<window_info
content_ui=
"combo"
id=
"Project"
order=
"0"
visible=
"true"
weight=
"0.19742489"
/>
<window_info
id=
"Captures"
order=
"1"
side_tool=
"true"
/>
<window_info
id=
"Captures"
order=
"1"
side_tool=
"true"
/>
...
...
example/ios/Runner/Info.plist
View file @
a4dd2854
...
@@ -2,22 +2,10 @@
...
@@ -2,22 +2,10 @@
<
!
D
O
C
TYP
E
plist
PU
B
LI
C
"-//
A
ppl
e
//
D
T
D
PLIST
1
.
0
//
E
N"
"http://www.
a
ppl
e
.
c
om/
D
T
D
s/Prop
e
rtyList-
1
.
0
.
d
t
d
"
>
<
!
D
O
C
TYP
E
plist
PU
B
LI
C
"-//
A
ppl
e
//
D
T
D
PLIST
1
.
0
//
E
N"
"http://www.
a
ppl
e
.
c
om/
D
T
D
s/Prop
e
rtyList-
1
.
0
.
d
t
d
"
>
<
plist
v
e
rsion="
1
.
0
"
>
<
plist
v
e
rsion="
1
.
0
"
>
<
d
i
c
t
>
<
d
i
c
t
>
<
k
e
y
>
NSLocationAlwaysAndWhenInUseUsageDescription
<
/k
e
y
>
<
string
>
wwww
啥
<
/string
>
<
k
e
y
>
NSLocationAlwaysAndWhenInUseUsageDescription
<
/k
e
y
>
<
string
>
wwww
啥
<
/string
>
<
k
e
y
>
NSLocationAlwaysUsageDescription
<
/k
e
y
>
<
string
>
ww
说啥
<
/string
>
<
k
e
y
>
NSLocationWhenInUseUsageDescription
<
/k
e
y
>
<
string
>
sm
说啥
<
/string
>
<
k
e
y
>
NSAppleMusicUsageDescription
<
/k
e
y
>
<
string
>
不知道说啥
<
/string
>
<
k
e
y
>
NSCameraUsageDescription
<
/k
e
y
>
<
k
e
y
>
NSCameraUsageDescription
<
/k
e
y
>
<
string
>
照相机
<
/string
>
<
string
>
照相机
<
/string
>
<
k
e
y
>
NSContactsUsageDescription
<
/k
e
y
>
<
k
e
y
>
NSContactsUsageDescription
<
/k
e
y
>
<
string
>
contactsDesciption
<
/string
>
<
string
>
contactsDesciption
<
/string
>
<
k
e
y
>
NSMicrophoneUsageDescription
<
/k
e
y
>
<
string
>
麦克风
<
/string
>
<
k
e
y
>
NSPhotoLibraryAddUsageDescription
<
/k
e
y
>
<
k
e
y
>
NSPhotoLibraryAddUsageDescription
<
/k
e
y
>
<
string
>
相册
11
<
/string
>
<
string
>
相册
11
<
/string
>
<
k
e
y
>
NSPhotoLibraryUsageDescription
<
/k
e
y
>
<
k
e
y
>
NSPhotoLibraryUsageDescription
<
/k
e
y
>
...
...
ios/Classes/GengmeiFlutterPlugin.m
View file @
a4dd2854
...
@@ -69,11 +69,19 @@ NSString *cacheDirectory;
...
@@ -69,11 +69,19 @@ NSString *cacheDirectory;
ALAuthorizationStatus
author
=
[
ALAssetsLibrary
authorizationStatus
];
ALAuthorizationStatus
author
=
[
ALAssetsLibrary
authorizationStatus
];
NSString
*
mediaType
=
AVMediaTypeVideo
;
//读取媒体类型
NSString
*
mediaType
=
AVMediaTypeVideo
;
//读取媒体类型
AVAuthorizationStatus
authStatus
=
[
AVCaptureDevice
authorizationStatusForMediaType
:
mediaType
];
//读取设备授权状态
AVAuthorizationStatus
authStatus
=
[
AVCaptureDevice
authorizationStatusForMediaType
:
mediaType
];
//读取设备授权状态
if
(
author
==
AVAuthorizationStatusRestricted
||
authStatus
==
AVAuthorizationStatusDenied
)
{
NSLog
(
@"STATE %d"
,
authStatus
);
if
(
author
==
AVAuthorizationStatusAuthorized
){
NSLog
(
@"相机可用"
);
long
temp
=
self
.
resultKey
;
[
self
scanPhone
:
temp
];
}
else
if
(
author
==
AVAuthorizationStatusRestricted
||
authStatus
==
AVAuthorizationStatusDenied
)
{
NSLog
(
@"没给权限!!!"
);
NSLog
(
@"没给权限!!!"
);
NSString
*
errorStr
=
@"应用相机权限受限,请在iPhone的“设置-隐私-相机”选项中,允许好享玩访问你的相机。"
;
NSString
*
errorStr
=
@"应用相机权限受限,请在iPhone的“设置-隐私-相册”选项中,允许好享玩访问你的相册。"
;
[
self
showToast
:
errorStr
inView
:[
UIApplication
sharedApplication
].
windows
.
lastObject
];
UIAlertView
*
alert
=
[[
UIAlertView
alloc
]
initWithTitle
:
nil
message
:
errorStr
delegate
:
nil
cancelButtonTitle
:
@"确定"
otherButtonTitles
:
nil
];
}
else
if
(
author
==
AVAuthorizationStatusNotDetermined
){
[
alert
show
];
}
else
{
NSLog
(
@"HERRRRRRRR"
);
[
PHPhotoLibrary
requestAuthorization
:
^
(
PHAuthorizationStatus
status
)
{
[
PHPhotoLibrary
requestAuthorization
:
^
(
PHAuthorizationStatus
status
)
{
if
(
status
==
PHAuthorizationStatusAuthorized
)
{
if
(
status
==
PHAuthorizationStatusAuthorized
)
{
dispatch_async
(
dispatch_get_main_queue
(),
^
{
dispatch_async
(
dispatch_get_main_queue
(),
^
{
...
@@ -84,36 +92,42 @@ NSString *cacheDirectory;
...
@@ -84,36 +92,42 @@ NSString *cacheDirectory;
}
else
{
}
else
{
dispatch_async
(
dispatch_get_main_queue
(),
^
{
dispatch_async
(
dispatch_get_main_queue
(),
^
{
// 用户点击 不允许访问
// 用户点击 不允许访问
NSString
*
errorStr
=
@"应用相机权限受限,请在iPhone的“设置-隐私-相册”选项中,允许好享玩访问你的相册。"
;
UIAlertView
*
alert
=
[[
UIAlertView
alloc
]
initWithTitle
:
nil
message
:
errorStr
delegate
:
nil
cancelButtonTitle
:
@"确定"
otherButtonTitles
:
nil
];
[
alert
show
];
NSLog
(
@"被拒绝 TODO!!"
);
NSLog
(
@"被拒绝 TODO!!"
);
});
});
}
}
}];
}];
}
else
{
NSLog
(
@"相机可用"
);
long
temp
=
self
.
resultKey
;
[
self
scanPhone
:
temp
];
}
}
}
else
if
([
@"native_camera"
isEqualToString
:
call
.
method
]){
}
else
if
([
@"native_camera"
isEqualToString
:
call
.
method
]){
self
.
nativeCameraKey
=
self
.
resultKey
;
self
.
nativeCameraKey
=
self
.
resultKey
;
NSString
*
mediaType
=
AVMediaTypeVideo
;
//读取媒体类型
NSString
*
mediaType
=
AVMediaTypeVideo
;
//读取媒体类型
AVAuthorizationStatus
authStatus
=
[
AVCaptureDevice
authorizationStatusForMediaType
:
mediaType
];
//读取设备授权状态
AVAuthorizationStatus
authStatus
=
[
AVCaptureDevice
authorizationStatusForMediaType
:
mediaType
];
//读取设备授
if
(
authStatus
==
AVAuthorizationStatusRestricted
||
authStatus
==
AVAuthorizationStatusDenied
){
if
(
authStatus
==
AVAuthorizationStatusAuthorized
){
NSLog
(
@"相机可用"
);
dispatch_async
(
dispatch_get_main_queue
(),
^
{
[
self
nativeCamera
];
});
}
else
if
(
authStatus
==
AVAuthorizationStatusRestricted
||
authStatus
==
AVAuthorizationStatusDenied
){
NSString
*
errorStr
=
@"应用相机权限受限,请在iPhone的“设置-隐私-相机”选项中,允许好享玩访问你的相机。"
;
NSString
*
errorStr
=
@"应用相机权限受限,请在iPhone的“设置-隐私-相机”选项中,允许好享玩访问你的相机。"
;
NSLog
(
@"相机不可用"
);
NSLog
(
@"相机不可用"
);
[
self
showToast
:
errorStr
inView
:[
UIApplication
sharedApplication
].
windows
.
lastObject
];
}
else
if
(
authStatus
==
AVAuthorizationStatusNotDetermined
){
UIAlertView
*
alert
=
[[
UIAlertView
alloc
]
initWithTitle
:
nil
message
:
errorStr
delegate
:
nil
cancelButtonTitle
:
@"确定"
otherButtonTitles
:
nil
];
[
alert
show
];
}
else
{
[
AVCaptureDevice
requestAccessForMediaType
:
AVMediaTypeVideo
completionHandler
:
^
(
BOOL
granted
)
{
[
AVCaptureDevice
requestAccessForMediaType
:
AVMediaTypeVideo
completionHandler
:
^
(
BOOL
granted
)
{
if
(
granted
){
if
(
granted
){
dispatch_async
(
dispatch_get_main_queue
(),
^
{
dispatch_async
(
dispatch_get_main_queue
(),
^
{
[
self
nativeCamera
];
[
self
nativeCamera
];
});
});
}
else
{
NSString
*
errorStr
=
@"应用相机权限受限,请在iPhone的“设置-隐私-相册”选项中,允许好享玩访问你的相册。"
;
UIAlertView
*
alert
=
[[
UIAlertView
alloc
]
initWithTitle
:
nil
message
:
errorStr
delegate
:
nil
cancelButtonTitle
:
@"确定"
otherButtonTitles
:
nil
];
[
alert
show
];
}
}
}];
}];
}
else
{
NSLog
(
@"相机可用"
);
dispatch_async
(
dispatch_get_main_queue
(),
^
{
[
self
nativeCamera
];
});
}
}
}
else
if
([
@"quit_page"
isEqualToString
:
call
.
method
]){
}
else
if
([
@"quit_page"
isEqualToString
:
call
.
method
]){
self
.
quitPage
=
true
;
self
.
quitPage
=
true
;
...
@@ -360,7 +374,7 @@ NSString *cacheDirectory;
...
@@ -360,7 +374,7 @@ NSString *cacheDirectory;
PHImageRequestOptions
*
imageRequestOption
=
[[
PHImageRequestOptions
alloc
]
init
];
PHImageRequestOptions
*
imageRequestOption
=
[[
PHImageRequestOptions
alloc
]
init
];
imageRequestOption
.
synchronous
=
NO
;
imageRequestOption
.
synchronous
=
NO
;
imageRequestOption
.
networkAccessAllowed
=
YES
;
imageRequestOption
.
networkAccessAllowed
=
YES
;
imageRequestOption
.
deliveryMode
=
PHImageRequestOptionsDeliveryModeHighQualityFormat
;
imageRequestOption
.
deliveryMode
=
PHImageRequestOptionsDeliveryModeHighQualityFormat
;
imageRequestOption
.
resizeMode
=
PHImageRequestOptionsResizeModeFast
;
imageRequestOption
.
resizeMode
=
PHImageRequestOptionsResizeModeFast
;
imageRequestOption
.
version
=
PHImageRequestOptionsVersionUnadjusted
;
imageRequestOption
.
version
=
PHImageRequestOptionsVersionUnadjusted
;
NSString
*
tempPath
=
NSTemporaryDirectory
();
NSString
*
tempPath
=
NSTemporaryDirectory
();
...
@@ -370,58 +384,58 @@ NSString *cacheDirectory;
...
@@ -370,58 +384,58 @@ NSString *cacheDirectory;
NSString
*
tempTake
=
[
tempPath
stringByAppendingPathComponent
:[
NSString
stringWithFormat
:
@"%@%@"
,
name
,
@"_preview"
]];
NSString
*
tempTake
=
[
tempPath
stringByAppendingPathComponent
:[
NSString
stringWithFormat
:
@"%@%@"
,
name
,
@"_preview"
]];
PHAsset
*
assets
=
self
.
scanMap
[
path
];
PHAsset
*
assets
=
self
.
scanMap
[
path
];
MyPreviewController
*
video
=
[[
MyPreviewController
alloc
]
init
];
MyPreviewController
*
video
=
[[
MyPreviewController
alloc
]
init
];
[
viewController
presentViewController
:
video
animated
:
YES
completion
:
nil
];
[
viewController
presentViewController
:
video
animated
:
YES
completion
:
nil
];
[
video
setImagePre
:
assets
];
[
video
setImagePre
:
assets
];
[[
ResultManager
sharedSingleton
]
resultSuccess
:[
NSNumber
numberWithLong
:
resultTemp
]
:
@YES
];
[[
ResultManager
sharedSingleton
]
resultSuccess
:[
NSNumber
numberWithLong
:
resultTemp
]
:
@YES
];
// if([fileManager fileExistsAtPath:tempTake]){
// if([fileManager fileExistsAtPath:tempTake]){
// NSMutableDictionary *dict=[[NSMutableDictionary alloc] init];
// NSMutableDictionary *dict=[[NSMutableDictionary alloc] init];
// [dict setObject:path forKey:@"path"];
// [dict setObject:path forKey:@"path"];
// [dict setObject:tempTake forKey:@"realImagePath"];
// [dict setObject:tempTake forKey:@"realImagePath"];
// [[ResultManager sharedSingleton] resultSuccess:[NSNumber numberWithLong:resultTemp] :dict];
// [[ResultManager sharedSingleton] resultSuccess:[NSNumber numberWithLong:resultTemp] :dict];
// }else{
// }else{
// dispatch_async(queue, ^{
// dispatch_async(queue, ^{
// CFAbsoluteTime start=CFAbsoluteTimeGetCurrent();
// CFAbsoluteTime start=CFAbsoluteTimeGetCurrent();
// int picWidth=[assets pixelWidth];
// int picWidth=[assets pixelWidth];
// int picHeight=[assets pixelHeight];
// int picHeight=[assets pixelHeight];
// float tempScareSize=1;
// float tempScareSize=1;
// float limit=1024.0;
// float limit=1024.0;
// float max=MAX(picWidth, picHeight);
// float max=MAX(picWidth, picHeight);
// if(max>limit){
// if(max>limit){
// tempScareSize=limit/max;
// tempScareSize=limit/max;
// }
// }
// CGSize temp=CGSizeMake(picWidth*tempScareSize, picHeight*tempScareSize);
// CGSize temp=CGSizeMake(picWidth*tempScareSize, picHeight*tempScareSize);
// __block bool isResult=false;
// __block bool isResult=false;
// [[PHImageManager defaultManager] requestImageForAsset:assets targetSize:temp contentMode:PHImageContentModeDefault options:imageRequestOption resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
// [[PHImageManager defaultManager] requestImageForAsset:assets targetSize:temp contentMode:PHImageContentModeDefault options:imageRequestOption resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
// if(isResult){
// if(isResult){
// return ;
// return ;
// }
// }
// isResult=true;
// isResult=true;
// @autoreleasepool{
// @autoreleasepool{
// NSData *data = UIImageJPEGRepresentation(result, 0.7) ;
// NSData *data = UIImageJPEGRepresentation(result, 0.7) ;
// [data writeToFile:tempTake atomically:YES];
// [data writeToFile:tempTake atomically:YES];
// // result=nil;
// // result=nil;
// // data=nil;
// // data=nil;
// }
// }
// NSMutableDictionary *dict=[[NSMutableDictionary alloc] init];
// NSMutableDictionary *dict=[[NSMutableDictionary alloc] init];
// [dict setObject:path forKey:@"path"];
// [dict setObject:path forKey:@"path"];
// [dict setObject:tempTake forKey:@"realImagePath"];
// [dict setObject:tempTake forKey:@"realImagePath"];
// dispatch_async(dispatch_get_main_queue(), ^{
// dispatch_async(dispatch_get_main_queue(), ^{
// NSLog(@"压缩预览图片耗时:%f ms Temp路径%@",(CFAbsoluteTimeGetCurrent()-start)*1000,tempTake);
// NSLog(@"压缩预览图片耗时:%f ms Temp路径%@",(CFAbsoluteTimeGetCurrent()-start)*1000,tempTake);
// [[ResultManager sharedSingleton] resultSuccess:[NSNumber numberWithLong:resultTemp] :dict];
// [[ResultManager sharedSingleton] resultSuccess:[NSNumber numberWithLong:resultTemp] :dict];
// });
// });
// }];
// }];
// });
// });
// }
// }
}
else
if
([[
self
.
takePhotoMap
allKeys
]
containsObject
:
path
]){
}
else
if
([[
self
.
takePhotoMap
allKeys
]
containsObject
:
path
]){
MyPreviewController
*
video
=
[[
MyPreviewController
alloc
]
init
];
MyPreviewController
*
video
=
[[
MyPreviewController
alloc
]
init
];
[
viewController
presentViewController
:
video
animated
:
YES
completion
:
nil
];
[
viewController
presentViewController
:
video
animated
:
YES
completion
:
nil
];
[
video
setImagePrePath
:
self
.
takePhotoMap
[
path
]];
[
video
setImagePrePath
:
self
.
takePhotoMap
[
path
]];
[[
ResultManager
sharedSingleton
]
resultSuccess
:[
NSNumber
numberWithLong
:
resultTemp
]
:
@YES
];
[[
ResultManager
sharedSingleton
]
resultSuccess
:[
NSNumber
numberWithLong
:
resultTemp
]
:
@YES
];
// NSMutableDictionary *dict=[[NSMutableDictionary alloc] init];
// NSMutableDictionary *dict=[[NSMutableDictionary alloc] init];
// [dict setObject:path forKey:@"path"];
// [dict setObject:path forKey:@"path"];
// [dict setObject:self.takePhotoMap[path] forKey:@"realImagePath"];
// [dict setObject:self.takePhotoMap[path] forKey:@"realImagePath"];
// [[ResultManager sharedSingleton] resultSuccess:[NSNumber numberWithLong:resultTemp] :dict];
// [[ResultManager sharedSingleton] resultSuccess:[NSNumber numberWithLong:resultTemp] :dict];
}
else
{
}
else
{
[[
ResultManager
sharedSingleton
]
resultSuccess
:[
NSNumber
numberWithLong
:
resultTemp
]
:
nil
];
[[
ResultManager
sharedSingleton
]
resultSuccess
:[
NSNumber
numberWithLong
:
resultTemp
]
:
nil
];
}
}
...
@@ -431,21 +445,21 @@ NSString *cacheDirectory;
...
@@ -431,21 +445,21 @@ NSString *cacheDirectory;
if
([[
self
.
scanMap
allKeys
]
containsObject
:
path
]){
if
([[
self
.
scanMap
allKeys
]
containsObject
:
path
]){
PHAsset
*
assets
=
self
.
scanMap
[
path
];
PHAsset
*
assets
=
self
.
scanMap
[
path
];
MyPlayerViewController
*
video
=
[[
MyPlayerViewController
alloc
]
init
];
MyPlayerViewController
*
video
=
[[
MyPlayerViewController
alloc
]
init
];
[
viewController
presentViewController
:
video
animated
:
YES
completion
:
nil
];
[
viewController
presentViewController
:
video
animated
:
YES
completion
:
nil
];
// video.player= [[AVPlayeralloc]initWithURL:url];
// video.player= [[AVPlayeralloc]initWithURL:url];
[
video
playMovie
:
assets
];
[
video
playMovie
:
assets
];
[[
ResultManager
sharedSingleton
]
resultSuccess
:[
NSNumber
numberWithLong
:
resultTemp
]
:
@YES
];
[[
ResultManager
sharedSingleton
]
resultSuccess
:[
NSNumber
numberWithLong
:
resultTemp
]
:
@YES
];
// PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
// PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
// options.version = PHImageRequestOptionsVersionCurrent;
// options.version = PHImageRequestOptionsVersionCurrent;
// options.networkAccessAllowed = true;
// options.networkAccessAllowed = true;
// options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
// options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
// [[PHImageManager defaultManager]requestAVAssetForVideo:assets options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
// [[PHImageManager defaultManager]requestAVAssetForVideo:assets options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
// AVURLAsset *urlAsset = (AVURLAsset *)asset;
// AVURLAsset *urlAsset = (AVURLAsset *)asset;
// AVPlayerViewController* video=[[AVPlayerViewController alloc] init];
// AVPlayerViewController* video=[[AVPlayerViewController alloc] init];
// [viewController presentViewController:video animated:YES completion:nil];
// [viewController presentViewController:video animated:YES completion:nil];
// [video playMovie:urlAsset.URL];
// [video playMovie:urlAsset.URL];
// [[ResultManager sharedSingleton] resultSuccess:[NSNumber numberWithLong:resultTemp] :@YES];
// [[ResultManager sharedSingleton] resultSuccess:[NSNumber numberWithLong:resultTemp] :@YES];
// }];
// }];
}
}
}
else
{
}
else
{
result
(
FlutterMethodNotImplemented
);
result
(
FlutterMethodNotImplemented
);
...
@@ -724,7 +738,7 @@ CFAbsoluteTime startTime;
...
@@ -724,7 +738,7 @@ CFAbsoluteTime startTime;
}
}
}
}
if
(
!
haveIt
){
if
(
!
haveIt
){
[
self
.
finalMap
[
@"IsGengmeiAlbumAllImages"
]
addObject
:
queryItemDict
];
[
self
.
finalMap
[
@"IsGengmeiAlbumAllImages"
]
addObject
:
queryItemDict
];
}
}
if
(
self
.
needSize
>
300
){
if
(
self
.
needSize
>
300
){
if
(
self
.
copySize
<=
301
){
if
(
self
.
copySize
<=
301
){
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment