新增开箱日志以及自动更新武器箱

This commit is contained in:
HibiKier 2023-03-04 20:32:03 +08:00
parent bdfdbbcaeb
commit e32f086b8a
230 changed files with 223 additions and 92 deletions

View File

@ -1,5 +1,5 @@
import random import random
from typing import Any, Tuple, Type from typing import Any, List, Tuple
from nonebot import on_command from nonebot import on_command
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message, MessageEvent from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message, MessageEvent
@ -14,15 +14,15 @@ from configs.config import Config
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from utils.utils import is_number, scheduler from utils.utils import is_number, scheduler
from .config import CASE2ID
from .open_cases_c import ( from .open_cases_c import (
get_my_knifes,
group_statistics, group_statistics,
my_knifes_name,
open_case, open_case,
open_multiple_case, open_multiple_case,
total_open_statistics, total_open_statistics,
update,
) )
from .utils import CaseManager, reset_count_daily, update_case_data from .utils import CASE2ID, CaseManager, reset_count_daily, update_case_data
__zx_plugin_name__ = "开箱" __zx_plugin_name__ = "开箱"
__plugin_usage__ = """ __plugin_usage__ = """
@ -94,6 +94,11 @@ __plugin_configs__ = {
"help": "BUFF的cookie", "help": "BUFF的cookie",
}, },
"BUFF_PROXY": {"value": None, "help": "使用代理访问BUFF"}, "BUFF_PROXY": {"value": None, "help": "使用代理访问BUFF"},
"DAILY_UPDATE": {
"value": None,
"help": "每日自动更新的武器箱,存在'ALL'时则更新全部武器箱",
"type": List[str],
},
} }
Config.add_plugin_config( Config.add_plugin_config(
@ -110,8 +115,14 @@ cases_matcher_group = MatcherGroup(priority=5, permission=GROUP, block=True)
k_open_case = cases_matcher_group.on_command("开箱") k_open_case = cases_matcher_group.on_command("开箱")
reload_count = cases_matcher_group.on_command("重置开箱", permission=SUPERUSER) reload_count = cases_matcher_group.on_command("重置开箱", permission=SUPERUSER)
total_case_data = cases_matcher_group.on_command(
"我的开箱", aliases={"开箱统计", "开箱查询", "查询开箱"}
)
group_open_case_statistics = cases_matcher_group.on_command("群开箱统计")
open_multiple = cases_matcher_group.on_regex("(.*)连开箱(.*)?")
update_data = on_command("更新武器箱", priority=1, permission=SUPERUSER, block=True)
my_knifes = on_command("我的金色", priority=1, permission=GROUP, block=True)
@reload_count.handle() @reload_count.handle()
@ -127,11 +138,6 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
await k_open_case.finish(result, at_sender=True) await k_open_case.finish(result, at_sender=True)
total_case_data = cases_matcher_group.on_command(
"我的开箱", aliases={"开箱统计", "开箱查询", "查询开箱"}
)
@total_case_data.handle() @total_case_data.handle()
async def _(event: GroupMessageEvent): async def _(event: GroupMessageEvent):
await total_case_data.finish( await total_case_data.finish(
@ -140,27 +146,18 @@ async def _(event: GroupMessageEvent):
) )
group_open_case_statistics = cases_matcher_group.on_command("群开箱统计")
@group_open_case_statistics.handle() @group_open_case_statistics.handle()
async def _(event: GroupMessageEvent): async def _(event: GroupMessageEvent):
await group_open_case_statistics.finish(await group_statistics(event.group_id)) await group_open_case_statistics.finish(await group_statistics(event.group_id))
my_kinfes = on_command("我的金色", priority=1, permission=GROUP, block=True) @my_knifes.handle()
@my_kinfes.handle()
async def _(event: GroupMessageEvent): async def _(event: GroupMessageEvent):
await my_kinfes.finish( await my_knifes.finish(
await my_knifes_name(event.user_id, event.group_id), at_sender=True await get_my_knifes(event.user_id, event.group_id), at_sender=True
) )
open_multiple: Type[Matcher] = cases_matcher_group.on_regex("(.*)连开箱(.*)?")
@open_multiple.handle() @open_multiple.handle()
async def _( async def _(
event: GroupMessageEvent, state: T_State, reg_group: Tuple[Any, ...] = RegexGroup() event: GroupMessageEvent, state: T_State, reg_group: Tuple[Any, ...] = RegexGroup()
@ -218,9 +215,6 @@ num_dict = {
} }
update_data = on_command("更新武器箱", priority=1, permission=SUPERUSER, block=True)
@update_data.handle() @update_data.handle()
async def _(event: MessageEvent, arg: Message = CommandArg()): async def _(event: MessageEvent, arg: Message = CommandArg()):
msg = arg.extract_plain_text().strip() msg = arg.extract_plain_text().strip()

View File

@ -1,5 +1,3 @@
from typing import List, Optional
from tortoise import fields from tortoise import fields
from tortoise.contrib.postgres.functions import Random from tortoise.contrib.postgres.functions import Random

View File

@ -0,0 +1,38 @@
from typing import List, Optional
from tortoise import fields
from tortoise.contrib.postgres.functions import Random
from services.db_context import Model
class OpenCasesLog(Model):
id = fields.IntField(pk=True, generated=True, auto_increment=True)
"""自增id"""
user_qq = fields.BigIntField()
"""用户id"""
group_id = fields.BigIntField()
"""群聊id"""
case_name = fields.CharField(255)
"""箱子名称"""
name = fields.CharField(255)
"""武器/手套/刀名称"""
skin_name = fields.CharField(255)
"""皮肤名称"""
is_stattrak = fields.BooleanField(default=False)
"""是否暗金(计数)"""
abrasion = fields.CharField(255)
"""磨损度"""
abrasion_value = fields.FloatField()
"""磨损数值"""
color = fields.CharField(255)
"""颜色(品质)"""
price = fields.FloatField(default=0)
"""价格"""
create_time = fields.DatetimeField(auto_add_now=True)
"""创建日期"""
class Meta:
table = "open_cases_log"
table_description = "开箱日志表"

View File

@ -1,23 +1,23 @@
import asyncio import asyncio
import random import random
from datetime import datetime import re
from datetime import datetime, timedelta
from typing import Union from typing import Union
import pypinyin from nonebot.adapters.onebot.v11 import Message, MessageSegment
from nonebot.adapters.onebot.v11 import Message
from PIL import Image
from configs.config import Config from configs.config import Config
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from models.sign_group_user import SignGroupUser from models.sign_group_user import SignGroupUser
from services.log import logger from services.log import logger
from utils.image_utils import BuildImage, alpha2white_pil from utils.image_utils import BuildImage
from utils.message_builder import image from utils.message_builder import image
from utils.utils import cn2py from utils.utils import cn2py, scheduler
from .config import * from .config import *
from .models.open_cases_log import OpenCasesLog
from .models.open_cases_user import OpenCasesUser from .models.open_cases_user import OpenCasesUser
from .utils import CaseManager from .utils import CaseManager, update_case_data
RESULT_MESSAGE = { RESULT_MESSAGE = {
"BLUE": ["这样看着才舒服", "是自己人,大伙把刀收好", "非常舒适~"], "BLUE": ["这样看着才舒服", "是自己人,大伙把刀收好", "非常舒适~"],
@ -119,11 +119,6 @@ async def open_case(user_qq: int, group_id: int, case_name: str) -> Union[str, M
add_count(user, skin) add_count(user, skin)
ridicule_result = random.choice(RESULT_MESSAGE[skin.color]) ridicule_result = random.choice(RESULT_MESSAGE[skin.color])
price_result = skin.sell_min_price price_result = skin.sell_min_price
if skin.color == "KNIFE":
user.knifes_name = (
user.knifes_name
+ f"{case}||{skin.name}{'StatTrak™' if skin.is_stattrak else ''} | {skin.skin_name} ({skin.abrasion}) 磨损:{rand} 价格:{skin.sell_min_price},"
)
name = skin.name + "-" + skin.skin_name + "-" + skin.abrasion name = skin.name + "-" + skin.skin_name + "-" + skin.abrasion
img_path = IMAGE_PATH / "csgo_cases" / case / f"{cn2py(name)}.jpg" img_path = IMAGE_PATH / "csgo_cases" / case / f"{cn2py(name)}.jpg"
logger.info( logger.info(
@ -133,6 +128,20 @@ async def open_case(user_qq: int, group_id: int, case_name: str) -> Union[str, M
group_id, group_id,
) )
await user.save() await user.save()
await OpenCasesLog.create(
user_qq=user_qq,
group_id=group_id,
case_name=case_name,
name=skin.name,
skin_name=skin.skin_name,
is_stattrak=skin.is_stattrak,
abrasion=skin.abrasion,
color=skin.color,
price=skin.sell_min_price,
abrasion_value=rand,
create_time=datetime.now(),
)
logger.debug(f"添加 1 条开箱日志", "开箱", user_qq, group_id)
over_count = max_count - user.today_open_total over_count = max_count - user.today_open_total
return ( return (
f"开启{case_name}武器箱.\n剩余开箱次数:{over_count}.\n" f"开启{case_name}武器箱.\n剩余开箱次数:{over_count}.\n"
@ -148,6 +157,17 @@ async def open_case(user_qq: int, group_id: int, case_name: str) -> Union[str, M
async def open_multiple_case( async def open_multiple_case(
user_qq: int, group_id: int, case_name: str, num: int = 10 user_qq: int, group_id: int, case_name: str, num: int = 10
): ):
"""多连开箱
Args:
user_qq (int): 用户id
group_id (int): 群号
case_name (str): 箱子名称
num (int, optional): 数量. Defaults to 10.
Returns:
_type_: _description_
"""
if not CaseManager.CURRENT_CASES: if not CaseManager.CURRENT_CASES:
return "未收录任何武器箱" return "未收录任何武器箱"
if not case_name: if not case_name:
@ -180,6 +200,8 @@ async def open_multiple_case(
if not skin_list: if not skin_list:
return "未抽取到任何皮肤..." return "未抽取到任何皮肤..."
total_price = 0 total_price = 0
log_list = []
now = datetime.now()
for skin, rand in skin_list: for skin, rand in skin_list:
total_price += skin.sell_min_price total_price += skin.sell_min_price
rand = str(rand)[:11] rand = str(rand)[:11]
@ -213,7 +235,25 @@ async def open_multiple_case(
user_qq, user_qq,
group_id, group_id,
) )
log_list.append(
OpenCasesLog(
user_qq=user_qq,
group_id=group_id,
case_name=case_name,
name=skin.name,
skin_name=skin.skin_name,
is_stattrak=skin.is_stattrak,
abrasion=skin.abrasion,
color=skin.color,
price=skin.sell_min_price,
abrasion_value=rand,
create_time=now,
)
)
await user.save() await user.save()
if log_list:
await OpenCasesLog.bulk_create(log_list, 10)
logger.debug(f"添加 {len(log_list)} 条开箱日志", "开箱", user_qq, group_id)
markImg = BuildImage(1000, h, 200, 270) markImg = BuildImage(1000, h, 200, 270)
for img in img_list: for img in img_list:
markImg.paste(img) markImg.paste(img)
@ -291,62 +331,123 @@ async def group_statistics(group: int):
) )
async def my_knifes_name(user_id: int, group: int): async def get_my_knifes(user_id: int, group_id: int) -> Union[str, MessageSegment]:
user, _ = await OpenCasesUser.get_or_create(user_qq=user_id, group_id=group) """获取我的金色
Args:
user_id (int): 用户id
group_id (int): 群号
Returns:
Union[str, MessageSegment]: 回复消息或图片
"""
data_list = await get_old_knife(user_id, group_id)
data_list += await OpenCasesLog.filter(
user_qq=user_id, group_id=group_id, color="KNIFE"
).all()
if not data_list:
return "您木有开出金色级别的皮肤喔"
length = len(data_list)
if length < 5:
h = 600
w = length * 540
elif length % 5 == 0:
h = 600 * int(length / 5)
w = 540 * 5
else:
h = 600 * int(length / 5) + 600
w = 540 * 5
A = BuildImage(w, h, 540, 600)
for skin in data_list:
name = skin.name + "-" + skin.skin_name + "-" + skin.abrasion
img_path = (
IMAGE_PATH / "csgo_cases" / cn2py(skin.case_name) / f"{cn2py(name)}.jpg"
)
knife_img = BuildImage(470, 600, 470, 470, font_size=20)
await knife_img.apaste(
BuildImage(470, 470, background=img_path if img_path.exists() else None),
(0, 0),
True,
)
await knife_img.atext(
(5, 500), f"\t{skin.name}|{skin.skin_name}({skin.abrasion})"
)
await knife_img.atext((5, 530), f"\t磨损:{skin.abrasion_value}")
await knife_img.atext((5, 560), f"\t价格:{skin.price}")
await A.apaste(knife_img)
return image(A)
async def get_old_knife(user_id: int, group_id: int) -> List[OpenCasesLog]:
"""获取旧数据字段
Args:
user_id (int): 用户id
group_id (int): 群号
Returns:
List[OpenCasesLog]: 旧数据兼容
"""
user, _ = await OpenCasesUser.get_or_create(user_qq=user_id, group_id=group_id)
knifes_name = user.knifes_name knifes_name = user.knifes_name
data_list = []
if knifes_name: if knifes_name:
knifes_list = knifes_name[:-1].split(",") knifes_list = knifes_name[:-1].split(",")
length = len(knifes_list) for knife in knifes_list:
if length < 5: try:
h = 600 if r := re.search(
w = length * 540 "(.*)\|\|(.*) \| (.*)\((.*)\) 磨损:(.*) 价格:(.*)", knife
elif length % 5 == 0: ):
h = 600 * int(length / 5) case_name_py = r.group(1)
w = 540 * 5 name = r.group(2)
else: skin_name = r.group(3)
h = 600 * int(length / 5) + 600 abrasion = r.group(4)
w = 540 * 5 abrasion_value = r.group(5)
A = await asyncio.get_event_loop().run_in_executor( price = r.group(6)
None, _pst_my_knife, w, h, knifes_list name = name.replace("StatTrak™", "")
) data_list.append(
return image(b64=A.pic2bs4()) OpenCasesLog(
else: user_qq=user_id,
return "您木有开出金色级别的皮肤喔" group_id=group_id,
name=name.strip(),
case_name=case_name_py.strip(),
skin_name=skin_name.strip(),
abrasion=abrasion.strip(),
abrasion_value=abrasion_value,
price=price,
)
)
except Exception as e:
logger.error(f"获取兼容旧数据错误: {knife}", "我的金色", user_id, group_id, e=e)
return data_list
def _pst_my_knife(w, h, knifes_list): @scheduler.scheduled_job(
A = BuildImage(w, h, 540, 600) "cron",
for knife in knifes_list: hour=0,
case = knife.split("||")[0] minute=1,
knife = knife.split("||")[1] )
name = knife[: knife.find("(")].strip() async def _():
itype = knife[knife.find("(") + 1 : knife.find(")")].strip() now = datetime.now()
mosun = knife[knife.find("磨损:") + 3 : knife.rfind("价格:")].strip() hour = random.choice([0, 1, 2, 3])
if mosun[-1] == "," or mosun[-1] == "": date = now + timedelta(hours=hour)
mosun = mosun[:-1] scheduler.add_job(
price = knife[knife.find("价格:") + 3 :] update,
skin_name = "" "date",
for i in pypinyin.pinyin( run_date=date.replace(microsecond=0),
name.replace("|", "-").replace("StatTrak™", "").strip(), id=f"auto_update_csgo_cases",
style=pypinyin.NORMAL, )
):
skin_name += "".join(i)
knife_img = BuildImage(470, 600, 470, 470, font_size=20)
knife_img.paste(
alpha2white_pil(
Image.open(IMAGE_PATH / f"cases" / case / f"{skin_name}.png").resize(
(470, 470), Image.ANTIALIAS
)
),
(0, 0),
)
knife_img.text((5, 500), f"\t{name}({itype})")
knife_img.text((5, 530), f"\t磨损:{mosun}")
knife_img.text((5, 560), f"\t价格:{price}")
A.paste(knife_img)
return A
# G3SG1StatTrak™ | 血腥迷彩 (战痕累累) async def update():
# G3SG1StatTrak™ | 血腥迷彩 (战痕累累) if case_list := Config.get_config("open_cases", "DAILY_UPDATE"):
# G3SG1StatTrak™ | 血腥迷彩 (战痕累累) logger.debug("尝试自动更新武器箱", "更新武器箱")
if "ALL" in case_list:
case_list = CASE2ID.keys()
logger.debug(f"预计自动更新武器箱 {len(case_list)}", "更新武器箱")
for case_name in case_list:
logger.debug(f"开始自动更新武器箱: {case_name}", "更新武器箱")
await update_case_data(case_name)
rand = random.randint(300, 500)
logger.debug(f"成功自动更新武器箱: {case_name}, 将在 {rand} 秒后再次更新下一武器箱", "更新武器箱")
await asyncio.sleep(rand)

View File

@ -36,7 +36,7 @@ class CaseManager:
@classmethod @classmethod
async def reload(cls): async def reload(cls):
cls.CURRENT_CASES = ( cls.CURRENT_CASES = (
await BuffSkin.annotate().distinct().values_list("case_name", flat=True) await BuffSkin.annotate().distinct().values_list("case_name", flat=True) # type: ignore
) )

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Some files were not shown because too many files have changed in this diff Show More