This commit is contained in:
27942
2026-01-20 12:56:22 +08:00
parent f651dbdf0f
commit 5f040d6f23
329 changed files with 1118 additions and 75118 deletions

17
1.html

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

BIN
dist/gui_app.exe vendored

Binary file not shown.

Binary file not shown.

3160
gui_app.py

File diff suppressed because it is too large Load Diff

View File

@@ -1,38 +0,0 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['c:\\Users\\27942\\Desktop\\haha\\gui_app.py'],
pathex=[],
binaries=[],
datas=[('c:\\Users\\27942\\Desktop\\haha\\main.py', '.')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='gui_app',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

340
main.py
View File

@@ -272,7 +272,7 @@ class Pdd:
print(f"下载失败: {e}")
return None
def action(self, folder_path=None):
def action(self, folder_path=None, collect_all_videos=False):
self.create_page()
if datas.get(self.user_id):
@@ -311,54 +311,196 @@ class Pdd:
datas[self.user_id] = creator_tab.url
# 从文件夹读取文件
file_paths = []
video_file_paths = [] # 视频文件列表
image_folder_paths = [] # 图片文件夹列表(用于存储图片文件夹路径)
if folder_path and os.path.exists(folder_path):
logger.info(f"开始读取文件夹: {folder_path}")
logger.info(f"查找序号为 '{self.index}' 的文件")
# 支持的视频格式
video_extensions = ['.mp4', '.avi', '.mov', '.mkv', '.flv', '.wmv', '.webm']
# 支持的图片格式
image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']
# 获取文件夹中的所有文件
for file in os.listdir(folder_path): # 获取文件夹下所有的文件夹
file_path = os.path.join(folder_path, file) # 拼接文件夹
# 检查是否为目录,跳过文件(如.lnk快捷方式
if not os.path.isdir(file_path):
continue
files = os.listdir(file_path) # 获取用户id下的文件
for file in files:
file_names = file.split("-")
if file_names[0] == self.index:
path = Path(os.path.join(file_path, file))
# 判断是否为文件
if path.is_file():
file_paths.append(path)
creator_tab.ele("x://*[text()='添加视频']").click.to_upload(file_paths)
# xpath_path = creator_tab.ele('x://*[text()="添加视频描述"]').xpath
# new_path = re.sub(r'div\[1\]$', 'div[2]', xpath_path)
# new_path += "/div[2]/div/div[1]/div[2]"
# creator_tab.ele(f'x:{new_path}').input(vals=self.title + self.ht, clear=True)
time.sleep(3)
creator_tab.ele(f'x://*[@id="magicdomid1"]').input(
vals=file_names[-1].split(".")[0] + self.ht, clear=True)
break
# 第一步:先收集所有匹配的视频文件和图片文件
logger.info("=" * 50)
if collect_all_videos:
logger.info("第一步:扫描文件夹,收集所有视频文件(批量上传模式,不限制序号)...")
else:
logger.info(f"第一步:扫描文件夹,收集序号为 '{self.index}' 的文件...")
# 获取最外层文件夹下的所有子文件夹多多ID文件夹
subdirs = [f for f in os.listdir(folder_path) if os.path.isdir(os.path.join(folder_path, f))]
logger.info(f"在最外层文件夹下找到 {len(subdirs)} 个子文件夹多多ID文件夹")
# 找到匹配当前多多ID的文件
target_subdir = None
for subdir_name in subdirs:
if subdir_name == str(self.user_id):
target_subdir = os.path.join(folder_path, subdir_name)
logger.info(f"✓ 找到匹配的多多ID文件夹: {subdir_name}")
break
if not target_subdir:
logger.warning(f"未找到多多ID为 {self.user_id} 的文件夹")
logger.info(f"可用的文件夹: {subdirs}")
logger.error("无法继续执行因为未找到匹配的多多ID文件夹")
return
else:
# 只扫描匹配的多多ID文件夹
logger.info(f" 正在扫描子文件夹: {os.path.basename(target_subdir)}")
# 获取该子文件夹下的所有文件和文件夹
try:
items = os.listdir(target_subdir)
logger.info(f" 该文件夹下有 {len(items)} 个项目")
for item_name in items:
item_path = os.path.join(target_subdir, item_name)
logger.info(f" 检查项目: {item_name}")
# 分割文件名,检查第一部分是否匹配序号
name_parts = item_name.split("-")
logger.info(f" 文件名分割结果: {name_parts}")
# 如果是批量上传模式,收集所有视频文件;否则只收集匹配序号的文件
should_collect = False
if collect_all_videos:
# 批量上传模式:只要文件名格式正确(有序号),就收集视频文件
if len(name_parts) > 0 and name_parts[0].isdigit():
should_collect = True
logger.info(f" 批量上传模式:序号 {name_parts[0]} 将被收集")
else:
for file in os.listdir(path):
file_paths.append(os.path.join(path, file))
# 单个上传模式:只收集匹配当前序号的文件
if len(name_parts) > 0 and name_parts[0] == str(self.index):
should_collect = True
logger.info(f" ✓ 序号匹配!序号: {name_parts[0]}, 目标序号: {self.index}")
if should_collect:
path = Path(item_path)
# 判断是否为文件(视频文件)
if path.is_file():
# 检查是否为视频文件
file_ext = path.suffix.lower()
logger.info(f" 这是一个文件,扩展名: {file_ext}")
if any(file_ext == ext for ext in video_extensions):
video_file_paths.append(path)
logger.info(f" ✓ 添加到视频列表: {path.name}")
logger.info(f" 当前视频总数: {len(video_file_paths)}")
else:
logger.info(f" ✗ 不是视频文件,跳过")
else:
# 这是一个图片文件夹(只在单个上传模式下处理)
if not collect_all_videos:
image_folder_paths.append(path)
logger.info(f" ✓ 添加到图片文件夹列表: {path.name}")
logger.info(f" 当前图片文件夹总数: {len(image_folder_paths)}")
else:
if len(name_parts) > 0:
if collect_all_videos:
logger.info(f" ✗ 文件名格式不正确(序号不是数字),跳过")
else:
logger.info(f" ✗ 序号不匹配: {name_parts[0]} != {self.index}")
else:
logger.info(f" ✗ 文件名格式不正确,无法提取序号")
except Exception as e:
logger.error(f" 扫描子文件夹 {target_subdir} 时出错: {e}")
import traceback
traceback.print_exc()
creator_tab.ele('x://*[text()="添加图片"]').click.to_upload(file_paths)
logger.info("=" * 50)
logger.info(f"文件收集完成!")
logger.info(f" 视频文件数量: {len(video_file_paths)}")
logger.info(f" 图片文件夹数量: {len(image_folder_paths)}")
if video_file_paths:
logger.info("视频文件列表:")
for idx, video_path in enumerate(video_file_paths, 1):
logger.info(f" {idx}. {video_path}")
time.sleep(3)
# 第二步:如果有视频文件,批量上传所有视频
if video_file_paths:
logger.info("=" * 50)
logger.info(f"第二步:开始批量上传 {len(video_file_paths)} 个视频文件...")
# 检查是否有"支持批量上传"按钮,如果有则使用批量上传
logger.info("查找批量上传按钮...")
batch_upload_btn = creator_tab.ele("x://*[text()='支持批量上传']", timeout=3)
if batch_upload_btn:
logger.info("✓ 找到'支持批量上传'按钮")
if len(video_file_paths) > 1:
logger.info(f"使用批量上传模式,准备上传 {len(video_file_paths)} 个视频")
logger.info(f"上传文件列表: {[str(p) for p in video_file_paths]}")
batch_upload_btn.click.to_upload(video_file_paths)
logger.info(f"✓ 已触发批量上传,上传 {len(video_file_paths)} 个视频")
else:
logger.info(f"只有1个视频使用批量上传按钮上传")
batch_upload_btn.click.to_upload(video_file_paths)
logger.info(f"✓ 已触发上传")
else:
logger.warning("✗ 未找到'支持批量上传'按钮,尝试使用'添加视频'按钮")
# 使用单个上传(兼容旧版本或只有一个视频的情况)
upload_btn = creator_tab.ele("x://*[text()='添加视频']", timeout=3)
if upload_btn:
logger.info("✓ 找到'添加视频'按钮")
logger.info(f"使用添加视频按钮,准备上传 {len(video_file_paths)} 个视频")
logger.info(f"上传文件列表: {[str(p) for p in video_file_paths]}")
upload_btn.click.to_upload(video_file_paths)
logger.info(f"✓ 已触发上传,上传 {len(video_file_paths)} 个视频")
else:
logger.error("✗ 未找到任何上传按钮!")
logger.info("等待上传完成...")
time.sleep(5)
# 输入视频描述(只输入第一个视频的描述,因为批量上传后可能需要单独处理每个视频)
if video_file_paths:
first_video_name = video_file_paths[0].name
file_names = first_video_name.split("-")
if len(file_names) > 0:
desc_text = file_names[-1].split(".")[0] + self.ht
logger.info(f"准备输入视频描述: {desc_text[:50]}...")
desc_input = creator_tab.ele(f'x://*[@id="magicdomid1"]', timeout=3)
if desc_input:
desc_input.input(vals=desc_text, clear=True)
logger.info(f"✓ 已输入视频描述")
else:
logger.warning("✗ 未找到描述输入框")
else:
logger.warning("未找到任何视频文件,跳过视频上传")
# 第三步:如果有图片文件夹,逐个上传图片
if image_folder_paths:
logger.info(f"找到 {len(image_folder_paths)} 个图片文件夹,开始逐个上传...")
for image_folder_path in image_folder_paths:
image_files = []
# 收集图片文件夹中的所有图片文件
if image_folder_path.is_dir():
for img_file in os.listdir(image_folder_path):
img_path = Path(os.path.join(image_folder_path, img_file))
if img_path.is_file() and any(img_path.suffix.lower() == ext for ext in image_extensions):
image_files.append(str(img_path))
if image_files:
creator_tab.ele('x://*[text()="添加图片"]').click.to_upload(image_files)
time.sleep(3)
# 提取文件夹名称用于标题和描述
folder_name = image_folder_path.name
file_names = folder_name.split("-")
if len(file_names) > 1:
creator_tab.ele('x://*[@placeholder="添加标题"]').input(vals=file_names[1], clear=True)
xpath_path = creator_tab.ele('x://*[text()="添加视频描述"]').xpath
# 方法2使用正则表达式替换最后一个div[1]
new_path = re.sub(r'div\[1\]$', 'div[2]', xpath_path)
new_path += "/div/div[3]/div/div/div"
xpath_path = creator_tab.ele('x://*[text()="添加视频描述"]').xpath
# 方法2使用正则表达式替换最后一个div[1]
new_path = re.sub(r'div\[1\]$', 'div[2]', xpath_path)
new_path += "/div/div[3]/div/div/div"
if len(file_names) > 2:
creator_tab.ele(f'x:{new_path}').input(vals=file_names[2] + " " + self.ht, clear=True)
break
logger.info(f"已上传图片文件夹: {folder_name}")
# if ".mp4" in file_path:
# # 上传视频
@@ -640,22 +782,55 @@ class Pdd:
datas[self.user_id] = creator_tab.url
# 批量上传视频
logger.info("=" * 50)
logger.info("开始准备批量上传视频...")
videos = []
for i in folder_path:
videos.append(i["path"])
for idx, video_info in enumerate(folder_path, 1):
video_path = video_info["path"]
videos.append(video_path)
logger.info(f" {idx}. {video_path.name} ({video_path})")
logger.info(f"开始批量上传 {len(videos)} 个视频")
creator_tab.ele("x://*[text()='支持批量上传']").click.to_upload(videos)
logger.info(f"=" * 50)
logger.info(f"准备批量上传 {len(videos)} 个视频")
logger.info(f"视频文件列表: {[str(v) for v in videos]}")
# 优先使用"支持批量上传"按钮,如果没有则使用"添加视频"按钮
logger.info("查找上传按钮...")
batch_upload_btn = creator_tab.ele("x://*[text()='支持批量上传']", timeout=3)
if batch_upload_btn:
logger.info("✓ 找到'支持批量上传'按钮")
logger.info(f"使用批量上传按钮,准备上传 {len(videos)} 个视频")
batch_upload_btn.click.to_upload(videos)
logger.info(f"✓ 已触发批量上传,上传 {len(videos)} 个视频")
else:
logger.warning("✗ 未找到'支持批量上传'按钮,尝试使用'添加视频'按钮")
# 备用方案:使用"添加视频"按钮(可能也支持批量上传)
add_video_btn = creator_tab.ele("x://*[text()='添加视频']", timeout=3)
if add_video_btn:
logger.info("✓ 找到'添加视频'按钮")
logger.info(f"使用添加视频按钮,准备上传 {len(videos)} 个视频")
add_video_btn.click.to_upload(videos)
logger.info(f"✓ 已触发上传,上传 {len(videos)} 个视频")
else:
logger.error("✗ 未找到任何视频上传按钮!")
return
# 等待一段时间让视频开始上传和页面渲染
logger.info("=" * 50)
logger.info("等待视频开始上传和页面渲染...")
logger.info(f"已上传 {len(videos)} 个视频,等待 {5} 秒...")
time.sleep(5)
# 不等待所有视频上传完成,而是检测每个视频的状态
# 只处理已上传完成的视频,跳过还在上传中的视频
logger.info("检测视频上传状态,只处理已上传完成的视频...")
logger.info("=" * 50)
logger.info("开始检测视频上传状态,只处理已上传完成的视频...")
logger.info(f"需要处理的视频总数: {len(folder_path)}")
# 针对每个视频单独处理
logger.info("=" * 50)
logger.info(f"开始处理 {len(folder_path)} 个视频的详细信息...")
for idx, video_info in enumerate(folder_path):
try:
video_path = video_info["path"]
@@ -664,73 +839,102 @@ class Pdd:
video_time_start = video_info.get("time_start", self.time_start)
video_url = video_info.get("url", self.url)
logger.info(f"处理第 {idx + 1}/{len(folder_path)} 个视频: {video_name}")
logger.info("=" * 50)
logger.info(f"处理第 {idx + 1}/{len(folder_path)} 个视频")
logger.info(f" 视频名称: {video_name}")
logger.info(f" 视频路径: {video_path}")
logger.info(f" 话题: {video_ht}")
logger.info(f" 定时时间: {video_time_start}")
logger.info(f" 绑定URL: {video_url[:50] if video_url else 'None'}...")
# 定位视频容器:优先按文件名匹配,其次按索引
logger.info(f" 正在定位视频容器...")
video_container = None
video_name_without_ext = video_name.rsplit(".", 1)[0]
logger.info(f" 完整文件名: {video_name}")
logger.info(f" 不含扩展名: {video_name_without_ext}")
container_xpath = (
'x://p[contains(text(), "文件名:") and contains(text(), "{name}")]'
'/ancestor::div[contains(@class, "y0VjbyIp")][1]'
)
logger.info(f" 方法1: 按完整文件名匹配...")
video_container = creator_tab.ele(
container_xpath.format(name=video_name), timeout=5
)
if not video_container:
if video_container:
logger.info(f" ✓ 通过完整文件名找到视频容器")
else:
logger.info(f" ✗ 未找到,尝试不含扩展名...")
video_container = creator_tab.ele(
container_xpath.format(name=video_name_without_ext), timeout=3
)
if video_container:
logger.info(f" ✓ 通过不含扩展名找到视频容器")
if not video_container:
logger.info(f" ✗ 按文件名未找到,尝试按索引匹配...")
containers = creator_tab.eles(
'x://p[contains(text(), "文件名:")]'
'/ancestor::div[contains(@class, "y0VjbyIp")][1]'
)
logger.info(f" 页面上共有 {len(containers)} 个视频容器")
if idx < len(containers):
video_container = containers[idx]
logger.warning(
f"通过索引方式定位到视频容器: {idx + 1}/{len(containers)}"
f"通过索引方式定位到视频容器: {idx + 1}/{len(containers)}"
)
else:
logger.error(f" ✗ 索引超出范围: {idx} >= {len(containers)}")
if not video_container:
logger.warning(f"未找到视频 {video_name} 的容器,跳过")
logger.error(f"未找到视频 {video_name} 的容器,跳过该视频")
continue
else:
logger.info(f" ✓ 成功定位到视频容器")
# 检测上传状态(在当前视频容器内)
logger.info(f" 检测视频上传状态...")
# 优先判断是否仍在上传,其次判断发布按钮是否可用
uploading_text = video_container.ele(
'x://*[contains(., "视频上传中")]', timeout=0.5
)
if uploading_text:
logger.warning(f"视频 {video_name} 还在上传中,跳过处理")
logger.warning(f"视频 {video_name} 还在上传中,跳过处理")
continue
success_text = video_container.ele(
'x://*[contains(., "视频上传成功")]', timeout=0.5
)
if success_text:
logger.info(f"检测到视频 {video_name} 上传成功标识")
logger.info(f"检测到视频 {video_name} 上传成功标识")
else:
logger.info(f" 未找到'上传成功'标识,检查发布按钮状态...")
# 备用判断:发布按钮未禁用即可认为已完成
disabled_publish = video_container.ele(
'x://button[@data-testid="beast-core-button" and (@disabled or contains(@class, "BTN_disabled"))]//span[text()="发布"]',
timeout=0.5
)
if disabled_publish:
logger.warning(f"视频 {video_name} 发布按钮仍禁用,跳过")
logger.warning(f"视频 {video_name} 发布按钮仍禁用,跳过")
continue
logger.info(f"未检测到成功标识,但发布按钮可用,继续处理 {video_name}")
logger.info(f"未检测到成功标识,但发布按钮可用,继续处理 {video_name}")
# 1. 输入视频描述
logger.info(f" 步骤1: 输入视频描述...")
try:
desc_text = video_name.split(".")[0].split("-")[-1] + video_ht
logger.info(f" 描述文本: {desc_text[:50]}...")
desc_inputs = video_container.eles('x://*[starts-with(@id, "magicdomid")]')
if desc_inputs:
logger.info(f" 找到 {len(desc_inputs)} 个描述输入框,使用第一个")
desc_inputs[0].input(vals=desc_text, clear=True)
logger.info(f"已输入视频描述: {desc_text[:50]}...")
logger.info(f"已输入视频描述")
else:
logger.warning("在视频容器中未找到描述输入框")
logger.warning(f"在视频容器中未找到描述输入框")
except Exception as e:
logger.warning(f"输入视频描述失败: {e}")
logger.warning(f"输入视频描述失败: {e}")
import traceback
traceback.print_exc()
@@ -752,51 +956,63 @@ class Pdd:
# 设置定时时间
self._set_schedule_time(creator_tab, video_time_start, video_container, idx)
except Exception as e:
logger.warning(f"设置定时任务失败: {e}")
logger.warning(f"设置定时任务失败: {e}")
import traceback
traceback.print_exc()
else:
logger.info(f" 步骤2: 跳过定时任务(未设置定时时间)")
# 3. 绑定任务如果该视频有URL
if video_url:
logger.info(f" 步骤3: 绑定任务...")
logger.info(f" 绑定URL: {video_url[:50]}...")
try:
bind_btn = video_container.ele('x://*[text()="点击绑定任务"]', timeout=3)
if bind_btn:
logger.info(f" ✓ 找到绑定任务按钮")
bind_btn.click()
time.sleep(1)
# 输入URL这个输入框可能在弹窗中使用全局查找
url_input = creator_tab.ele('x://*[@placeholder="请输入个人主页链接"]', timeout=3)
if url_input:
logger.info(f" ✓ 找到URL输入框")
url_input.input(video_url, clear=True)
time.sleep(1)
confirm_btn = creator_tab.ele('x://*[text()="确认"]', timeout=3)
if confirm_btn:
confirm_btn.click()
logger.info(f"已绑定任务: {video_url[:50]}...")
logger.info(f"已绑定任务")
time.sleep(1)
else:
logger.warning(f" ✗ 未找到确认按钮")
else:
logger.warning("未找到URL输入框")
logger.warning(f"未找到URL输入框")
else:
logger.warning("未找到绑定任务按钮")
logger.warning(f"未找到绑定任务按钮")
except Exception as e:
logger.warning(f"绑定任务失败: {e}")
logger.warning(f"绑定任务失败: {e}")
import traceback
traceback.print_exc()
else:
logger.info(f" 步骤3: 跳过绑定任务未设置URL")
# 4. 点击该视频的发布按钮(注意:这里应该是单个视频的"发布"按钮,不是"立即发布"
logger.info(f" 步骤4: 点击发布按钮...")
try:
publish_btn = video_container.ele(
'x://button[@data-testid="beast-core-button"]//span[text()="发布"]', timeout=3
)
if publish_btn:
publish_btn.click()
logger.info("已点击发布按钮")
logger.info(f"已点击发布按钮")
else:
logger.warning("在视频容器中未找到发布按钮")
logger.warning(f"在视频容器中未找到发布按钮")
except Exception as e:
logger.warning(f"点击发布按钮失败: {e}")
logger.warning(f"点击发布按钮失败: {e}")
import traceback
traceback.print_exc()
logger.info(f" ✓ 视频 {video_name} 处理完成")
time.sleep(2) # 每个视频处理间隔
except Exception as e:

View File

@@ -5,4 +5,3 @@ loguru>=0.6.0
beautifulsoup4>=4.9.0
curl-cffi>=0.5.0
DrissionPage>=4.0.0
qfluentwidgets

View File

@@ -8,5 +8,5 @@
"top_topics_and_observing_domains": [ ]
} ],
"hex_encoded_hmac_key": "434BF7DBD7DA573B45E0A11AD9045A61B6221D14AE2F9A341E2FEF659AF071F6",
"next_scheduled_calculation_time": "13413450070590271"
"next_scheduled_calculation_time": "13413450070590344"
}

View File

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 572 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 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: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 437 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 386 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

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