|
|
@ -1,55 +1,5 @@ |
|
|
|
#!/bin/bash |
|
|
|
#!/bin/bash |
|
|
|
|
|
|
|
|
|
|
|
config_file=$1 |
|
|
|
|
|
|
|
if [ -z $config_file ]; then |
|
|
|
|
|
|
|
echo 'The cache directory must be specified' |
|
|
|
|
|
|
|
exit 1 |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
if [ ! -f $config_file ]; then |
|
|
|
|
|
|
|
echo 'config file:$config_file not found' |
|
|
|
|
|
|
|
exit 1 |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
if [ ! -f $(which jq) ]; then |
|
|
|
|
|
|
|
echo 'To run this script, you need to install jq,https://stedolan.github.io/jq/' |
|
|
|
|
|
|
|
exit 1 |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
echo "jq version:$(jq --version)" |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
if [ ! -f $(which xmlstarlet) ]; then |
|
|
|
|
|
|
|
echo 'To run this script, you need to install xmlstarlet,http://xmlstar.sourceforge.net/docs.php' |
|
|
|
|
|
|
|
exit 1 |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
echo "xmlstarlet version:$(xmlstarlet --version)" |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ==================== Config ==================== |
|
|
|
|
|
|
|
Host=$(cat $config_file | jq -r .aliyun_oss.Host) |
|
|
|
|
|
|
|
accelerateHost=$(cat $config_file | jq -r .aliyun_oss.accelerateHost) |
|
|
|
|
|
|
|
bucketname=$(cat $config_file | jq -r .aliyun_oss.bucketname) |
|
|
|
|
|
|
|
AccessKeyId=$(cat $config_file | jq -r .aliyun_oss.AccessKeyId) |
|
|
|
|
|
|
|
AccessKeySecret=$(cat $config_file | jq -r .aliyun_oss.AccessKeySecret) |
|
|
|
|
|
|
|
db_file=$(cat $config_file | jq -r .aliyun_oss.db) |
|
|
|
|
|
|
|
db_file_err=$db_file.err |
|
|
|
|
|
|
|
imageParam=$(cat $config_file | jq -r .aliyun_oss.imageParam) |
|
|
|
|
|
|
|
backup_time=$(cat $config_file | jq -r .aliyun_oss.backup_time) |
|
|
|
|
|
|
|
error_file=$(cat $config_file | jq -r .aliyun_oss.error_file) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
convertio_apikey=$(cat $config_file | jq -r .convertio.apikey) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CronitorKey=$(cat $config_file | jq -r .Cronitor.API_KEY) |
|
|
|
|
|
|
|
CronitorJobName=$(cat $config_file | jq -r .Cronitor.JOB_NAME) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
basePath=$(cat $config_file | jq -r .basePath) |
|
|
|
|
|
|
|
if [ ! -f $basePath ]; then |
|
|
|
|
|
|
|
mkdir -p $basePath |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
# ================================================ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cd $basePath |
|
|
|
|
|
|
|
if [ ! -f $db_file ]; then |
|
|
|
|
|
|
|
touch $db_file |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function PutObject() { |
|
|
|
function PutObject() { |
|
|
|
VERB="PUT" |
|
|
|
VERB="PUT" |
|
|
|
file=$1 |
|
|
|
file=$1 |
|
|
@ -118,12 +68,6 @@ function DeleteMultipleObjects() { |
|
|
|
else |
|
|
|
else |
|
|
|
echo "${backup_time}天以前的图片删除失败" |
|
|
|
echo "${backup_time}天以前的图片删除失败" |
|
|
|
fi |
|
|
|
fi |
|
|
|
echo '' >$db_file |
|
|
|
|
|
|
|
GetBucketV2 | xmlstarlet select -t -m '/ListBucketResult//Contents' -v 'Key' -n | while read line; do |
|
|
|
|
|
|
|
if [ $line != "$error_file" ]; then |
|
|
|
|
|
|
|
echo $line >>$db_file |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
done |
|
|
|
|
|
|
|
else |
|
|
|
else |
|
|
|
echo "没有${backup_time}天以前的图片需要删除" |
|
|
|
echo "没有${backup_time}天以前的图片需要删除" |
|
|
|
fi |
|
|
|
fi |
|
|
@ -139,17 +83,19 @@ function fileSizeStr() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function Request() { |
|
|
|
function Request() { |
|
|
|
|
|
|
|
original_param="$1" |
|
|
|
while true; do |
|
|
|
while true; do |
|
|
|
echo "发送消息命令:$1" |
|
|
|
echo "发送消息命令:$original_param" |
|
|
|
result=$(bash -c "$1") |
|
|
|
result=$(bash -c "$original_param") |
|
|
|
echo "请求响应:$result" |
|
|
|
echo "请求响应:$result" |
|
|
|
if [ $(echo $result | jq .ok) = true ]; then |
|
|
|
if [ $(echo $result | jq .ok) = true ]; then |
|
|
|
return 1 |
|
|
|
return 1 |
|
|
|
elif [ $(echo $result | jq .error_code) -eq 429 ]; then |
|
|
|
elif [ $(echo $result | jq .error_code) -eq 429 ]; then |
|
|
|
second=$(echo $result | jq .parameters.retry_after) |
|
|
|
second=$(echo $result | jq .parameters.retry_after) |
|
|
|
|
|
|
|
echo "${second}秒后再发起请求" |
|
|
|
sleep $second |
|
|
|
sleep $second |
|
|
|
echo "${second}后再发起请求" |
|
|
|
retry_result=$(Request "$original_param") |
|
|
|
Request $1 |
|
|
|
return "$retry_result" |
|
|
|
else |
|
|
|
else |
|
|
|
echo "执行命令遇到未知错误!" |
|
|
|
echo "执行命令遇到未知错误!" |
|
|
|
return 0 |
|
|
|
return 0 |
|
|
@ -157,6 +103,63 @@ function Request() { |
|
|
|
done |
|
|
|
done |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config_file=$1 |
|
|
|
|
|
|
|
if [ -z $config_file ]; then |
|
|
|
|
|
|
|
echo 'The cache directory must be specified' |
|
|
|
|
|
|
|
exit 1 |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
if [ ! -f $config_file ]; then |
|
|
|
|
|
|
|
echo 'config file:$config_file not found' |
|
|
|
|
|
|
|
exit 1 |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
if [ ! -f $(which jq) ]; then |
|
|
|
|
|
|
|
echo 'To run this script, you need to install jq,https://stedolan.github.io/jq/' |
|
|
|
|
|
|
|
exit 1 |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
echo "jq version:$(jq --version)" |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
if [ ! -f $(which xmlstarlet) ]; then |
|
|
|
|
|
|
|
echo 'To run this script, you need to install xmlstarlet,http://xmlstar.sourceforge.net/docs.php' |
|
|
|
|
|
|
|
exit 1 |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
echo "xmlstarlet version:$(xmlstarlet --version)" |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ==================== Config ==================== |
|
|
|
|
|
|
|
Host=$(cat $config_file | jq -r .aliyun_oss.Host) |
|
|
|
|
|
|
|
accelerateHost=$(cat $config_file | jq -r .aliyun_oss.accelerateHost) |
|
|
|
|
|
|
|
bucketname=$(cat $config_file | jq -r .aliyun_oss.bucketname) |
|
|
|
|
|
|
|
AccessKeyId=$(cat $config_file | jq -r .aliyun_oss.AccessKeyId) |
|
|
|
|
|
|
|
AccessKeySecret=$(cat $config_file | jq -r .aliyun_oss.AccessKeySecret) |
|
|
|
|
|
|
|
db_file=$(cat $config_file | jq -r .aliyun_oss.db) |
|
|
|
|
|
|
|
db_file_err=$db_file.err |
|
|
|
|
|
|
|
imageParam=$(cat $config_file | jq -r .aliyun_oss.imageParam) |
|
|
|
|
|
|
|
backup_time=$(cat $config_file | jq -r .aliyun_oss.backup_time) |
|
|
|
|
|
|
|
error_file=$(cat $config_file | jq -r .aliyun_oss.error_file) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
convertio_apikey=$(cat $config_file | jq -r .convertio.apikey) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CronitorKey=$(cat $config_file | jq -r .Cronitor.API_KEY) |
|
|
|
|
|
|
|
CronitorJobName=$(cat $config_file | jq -r .Cronitor.JOB_NAME) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
basePath=$(cat $config_file | jq -r .basePath) |
|
|
|
|
|
|
|
if [ ! -f $basePath ]; then |
|
|
|
|
|
|
|
mkdir -p $basePath |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
# ================================================ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cd $basePath |
|
|
|
|
|
|
|
if [ ! -f $db_file ]; then |
|
|
|
|
|
|
|
touch $db_file |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
echo '' >$db_file |
|
|
|
|
|
|
|
GetBucketV2 | xmlstarlet select -t -m '/ListBucketResult//Contents' -v 'Key' -n | while read line; do |
|
|
|
|
|
|
|
if [ $line != "$error_file" ]; then |
|
|
|
|
|
|
|
echo $line >>$db_file |
|
|
|
|
|
|
|
fi |
|
|
|
|
|
|
|
done |
|
|
|
|
|
|
|
|
|
|
|
telegramToken=$(cat $config_file | jq -r .telegramToken) |
|
|
|
telegramToken=$(cat $config_file | jq -r .telegramToken) |
|
|
|
baseApi="https://api.telegram.org/bot$telegramToken" |
|
|
|
baseApi="https://api.telegram.org/bot$telegramToken" |
|
|
|
chat_id=$(cat $config_file | jq .chatId) |
|
|
|
chat_id=$(cat $config_file | jq .chatId) |
|
|
@ -220,10 +223,10 @@ for index in $(seq 1 $length); do |
|
|
|
egrep -o "content='{\"timestamp.*" $png_html_file | sed -e "s/content='//" | sed -e "s/..$//" >$json_file |
|
|
|
egrep -o "content='{\"timestamp.*" $png_html_file | sed -e "s/content='//" | sed -e "s/..$//" >$json_file |
|
|
|
fi |
|
|
|
fi |
|
|
|
pageCount=$(jq --arg pid $pid '.illust[$pid].pageCount' $json_file) |
|
|
|
pageCount=$(jq --arg pid $pid '.illust[$pid].pageCount' $json_file) |
|
|
|
original_url=$(jq -r --arg pid $pid '.illust[$pid].urls.original' $json_file) |
|
|
|
|
|
|
|
small_url=$(jq -r --arg pid $pid '.illust[$pid].urls.small' $json_file) |
|
|
|
|
|
|
|
title=$(jq -r --arg pid $pid '.illust[$pid].title' $json_file | sed -e 's/\"/\\\"/g' | sed -e 's/<//g' | sed -e 's/>//g') |
|
|
|
title=$(jq -r --arg pid $pid '.illust[$pid].title' $json_file | sed -e 's/\"/\\\"/g' | sed -e 's/<//g' | sed -e 's/>//g') |
|
|
|
title=$(bash -c "echo '$title'|$rule") |
|
|
|
title=$(bash -c "echo '$title'|$rule") |
|
|
|
|
|
|
|
small_url=$(jq -r --arg pid $pid '.illust[$pid].urls.small' $json_file) |
|
|
|
|
|
|
|
|
|
|
|
description=$(jq -r --arg pid $pid '.illust[$pid].description' $json_file) |
|
|
|
description=$(jq -r --arg pid $pid '.illust[$pid].description' $json_file) |
|
|
|
userName=$(jq -r --arg pid $pid '.illust[$pid].userName' $json_file | sed -e 's/\"/\\\"/g') |
|
|
|
userName=$(jq -r --arg pid $pid '.illust[$pid].userName' $json_file | sed -e 's/\"/\\\"/g') |
|
|
|
userName=$(bash -c "echo '$userName'|$rule") |
|
|
|
userName=$(bash -c "echo '$userName'|$rule") |
|
|
@ -246,13 +249,22 @@ for index in $(seq 1 $length); do |
|
|
|
tag=$(jq -r --arg pid $pid '.illust[$pid].tags.tags[].tag' $json_file | sed -e 's/^/\\#/g' | sed ':a;N;s/\n/ /;t a;' | sed 's/"/\\"/g') |
|
|
|
tag=$(jq -r --arg pid $pid '.illust[$pid].tags.tags[].tag' $json_file | sed -e 's/^/\\#/g' | sed ':a;N;s/\n/ /;t a;' | sed 's/"/\\"/g') |
|
|
|
tag=$(bash -c "echo '$tag'|$rule") |
|
|
|
tag=$(bash -c "echo '$tag'|$rule") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
original_url=$(jq -r --arg pid $pid '.illust[$pid].urls.original' $json_file) |
|
|
|
echo -e "pageCount=$pageCount,original_url=$original_url,small_url=$small_url\n\ |
|
|
|
echo -e "pageCount=$pageCount,original_url=$original_url,small_url=$small_url\n\ |
|
|
|
title=$title,description=$description,userName=$userName\n\ |
|
|
|
title=$title,description=$description,userName=$userName\n\ |
|
|
|
likeCount=$likeCount,bookmarkCount=$bookmarkCount,viewCount=$viewCount\n\ |
|
|
|
likeCount=$likeCount,bookmarkCount=$bookmarkCount,viewCount=$viewCount\n\ |
|
|
|
tag=$tag" |
|
|
|
tag=$tag" |
|
|
|
|
|
|
|
|
|
|
|
for page in $(seq 1 $pageCount); do |
|
|
|
if [[ "$original_url" == "null" ]]; then |
|
|
|
page=$((page - 1)) |
|
|
|
echo "未能找到原始图片链接" |
|
|
|
|
|
|
|
url="https://$bucketname.$accelerateHost/$error_file?x-oss-process=image/watermark,text_$(echo "画作pid:$pid" | base64),g_center,voffset_50/watermark,text_5Zu-5rqQ5p-l5om-5aSx6LSlCg==,g_center,voffset_-50" |
|
|
|
|
|
|
|
webp_file_name="${pid}.webp" |
|
|
|
|
|
|
|
echo "文字水印请求url:$url,写入文件:${webp_file_name}" |
|
|
|
|
|
|
|
curl -v $url -o $webp_file_name |
|
|
|
|
|
|
|
media="$media,{\"type\":\"photo\",\"media\":\"attach://$webp_file_name\",\"parse_mode\":\"HTML\",\"caption\":\"$rank_info\n<a href=\\\"$artworkLink\\\">$title</a>\n<a href=\\\"https://www.pixiv.net/users/$userId\\\">$userName</a>\n$tag\"}" |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page=0 |
|
|
|
page_original_url=$(echo $original_url | sed -e "s/p0/p$page/") |
|
|
|
page_original_url=$(echo $original_url | sed -e "s/p0/p$page/") |
|
|
|
page_small_url=$(echo $small_url | sed -e"s/p0/p$page/") |
|
|
|
page_small_url=$(echo $small_url | sed -e"s/p0/p$page/") |
|
|
|
original_file_name=$(echo $page_original_url | egrep -o "$pid.*") |
|
|
|
original_file_name=$(echo $page_original_url | egrep -o "$pid.*") |
|
|
@ -284,10 +296,11 @@ for index in $(seq 1 $length); do |
|
|
|
echo "压缩无效,返回异常图片" |
|
|
|
echo "压缩无效,返回异常图片" |
|
|
|
FileSize=$(fileSizeStr $compress_size) |
|
|
|
FileSize=$(fileSizeStr $compress_size) |
|
|
|
url="https://$bucketname.$accelerateHost/$error_file?x-oss-process=image/watermark,text_$(echo "画作pid:$pid" | base64),g_north/watermark,text_$(echo 因为图片文件体积:${FileSize}不合法 | base64 | sed 's/+/-/g; s,/,_,g'),color_FF0000,y_50,g_north/watermark,text_5omA5Lul57yp55Wl5Zu-5peg5rOV5LiK5Lyg5YiwdGVsZWdyYW0=,color_FF0000,y_100,g_north/watermark,text_5bi46KeB5LqO6LaF6auY5YOP57Sg5Zu-54mH,y_150,g_north/watermark,text_5rOo5oSP77ya4oCc6aKE6KeI5Y6f5Zu-4oCd44CB4oCc5Yqg6YCf5LiL6L295Y6f5Zu-4oCd,color_008800,y_200,g_north/watermark,text_5Lul5LiK5Yqf6IO954Wn5bi45L2_55So,color_008800,y_250,g_north" |
|
|
|
url="https://$bucketname.$accelerateHost/$error_file?x-oss-process=image/watermark,text_$(echo "画作pid:$pid" | base64),g_north/watermark,text_$(echo 因为图片文件体积:${FileSize}不合法 | base64 | sed 's/+/-/g; s,/,_,g'),color_FF0000,y_50,g_north/watermark,text_5omA5Lul57yp55Wl5Zu-5peg5rOV5LiK5Lyg5YiwdGVsZWdyYW0=,color_FF0000,y_100,g_north/watermark,text_5bi46KeB5LqO6LaF6auY5YOP57Sg5Zu-54mH,y_150,g_north/watermark,text_5rOo5oSP77ya4oCc6aKE6KeI5Y6f5Zu-4oCd44CB4oCc5Yqg6YCf5LiL6L295Y6f5Zu-4oCd,color_008800,y_200,g_north/watermark,text_5Lul5LiK5Yqf6IO954Wn5bi45L2_55So,color_008800,y_250,g_north" |
|
|
|
echo "文字水印请求url:$url" |
|
|
|
echo "文字水印请求url:$url,写入文件:${webp_file_name}" |
|
|
|
curl -v $url -o $webp_file_name |
|
|
|
curl -v $url -o $webp_file_name |
|
|
|
else |
|
|
|
else |
|
|
|
echo $result | jq .data.output.url | xargs curl -v -o $webp_file_name |
|
|
|
echo $result | jq .data.output.url | xargs curl -v -o $webp_file_name |
|
|
|
|
|
|
|
echo "压缩图片写入文件:${webp_file_name}" |
|
|
|
original_file_name=$webp_file_name |
|
|
|
original_file_name=$webp_file_name |
|
|
|
fi |
|
|
|
fi |
|
|
|
break |
|
|
|
break |
|
|
@ -321,18 +334,18 @@ for index in $(seq 1 $length); do |
|
|
|
fi |
|
|
|
fi |
|
|
|
fi |
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
if [ $page -eq 0 ]; then |
|
|
|
|
|
|
|
info_file=$original_file_name.info |
|
|
|
info_file=$original_file_name.info |
|
|
|
curl -v -o $info_file https://$bucketname.$Host/$original_file_name?x-oss-process=image/info |
|
|
|
curl -v -o $info_file https://$bucketname.$Host/$original_file_name?x-oss-process=image/info |
|
|
|
FileSize=$(fileSizeStr $(cat $info_file | jq -r .FileSize.value)) |
|
|
|
FileSize=$(fileSizeStr $(cat $info_file | jq -r .FileSize.value)) |
|
|
|
ImageHeight=$(cat $info_file | jq -r .ImageHeight.value) |
|
|
|
ImageHeight=$(cat $info_file | jq -r .ImageHeight.value) |
|
|
|
ImageWidth=$(cat $info_file | jq -r .ImageWidth.value) |
|
|
|
ImageWidth=$(cat $info_file | jq -r .ImageWidth.value) |
|
|
|
media="$media,{\"type\":\"photo\",\"media\":\"attach://$webp_file_name\",\"parse_mode\":\"HTML\",\"caption\":\"$rank_info\n<a href=\\\"$artworkLink\\\">$title</a>\n<a href=\\\"https://www.pixiv.net/users/$userId\\\">$userName</a>\n$tag\n原图分辨率:${ImageWidth}X${ImageHeight}(宽X高),文件体积:$FileSize,<a href=\\\"https://$bucketname.$Host/$original_file_name\\\">预览原图</a> <a href=\\\"https://$bucketname.$accelerateHost/$original_file_name\\\">加速下载原图</a>\"}" |
|
|
|
media="$media,{\"type\":\"photo\",\"media\":\"attach://$webp_file_name\",\"parse_mode\":\"HTML\",\"caption\":\"$rank_info\n<a href=\\\"$artworkLink\\\">$title</a>\n<a href=\\\"https://www.pixiv.net/users/$userId\\\">$userName</a>\n$tag\n原图分辨率:${ImageWidth}X${ImageHeight}(宽X高),文件体积:$FileSize,<a href=\\\"https://$bucketname.$Host/$original_file_name\\\">预览原图</a> <a href=\\\"https://$bucketname.$accelerateHost/$original_file_name\\\">加速下载原图</a>\"}" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fi |
|
|
|
fileList="$fileList -F $webp_file_name=@$webp_file_name" |
|
|
|
fileList="$fileList -F $webp_file_name=@$webp_file_name" |
|
|
|
fileCount=$((fileCount + 1)) |
|
|
|
fileCount=$((fileCount + 1)) |
|
|
|
fileSize=$(du $webp_file_name | awk '{print $1}') |
|
|
|
|
|
|
|
echo "fileCount=$fileCount" |
|
|
|
echo "fileCount=$fileCount" |
|
|
|
fi |
|
|
|
|
|
|
|
if [[ $fileCount -eq $maxFileCount ]]; then |
|
|
|
if [[ $fileCount -eq $maxFileCount ]]; then |
|
|
|
Request "curl -v -F chat_id=$chat_id $fileList -F media='[$(echo $media | cut -c 2-)]' $baseApi/sendMediaGroup" |
|
|
|
Request "curl -v -F chat_id=$chat_id $fileList -F media='[$(echo $media | cut -c 2-)]' $baseApi/sendMediaGroup" |
|
|
|
if [ $(echo $?) -eq 1 ]; then |
|
|
|
if [ $(echo $?) -eq 1 ]; then |
|
|
@ -348,7 +361,6 @@ for index in $(seq 1 $length); do |
|
|
|
media='' |
|
|
|
media='' |
|
|
|
fileCount=0 |
|
|
|
fileCount=0 |
|
|
|
fi |
|
|
|
fi |
|
|
|
done |
|
|
|
|
|
|
|
done |
|
|
|
done |
|
|
|
|
|
|
|
|
|
|
|
next_expected_at=$(curl -v https://cronitor.io/api/monitors/$CronitorJobName -u $CronitorKey:'' | jq .next_expected_at) |
|
|
|
next_expected_at=$(curl -v https://cronitor.io/api/monitors/$CronitorJobName -u $CronitorKey:'' | jq .next_expected_at) |
|
|
|