Compare commits
129 Commits
@ -0,0 +1,239 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
import Cookies from 'js-cookie'; |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建AI报表任务 |
||||||
|
* @param {string} prompt - 用户输入的提示词 |
||||||
|
* @returns {Promise<{taskId: string}>} |
||||||
|
*/ |
||||||
|
export function createReportTask(prompt) { |
||||||
|
return request({ |
||||||
|
url: "/ai/reports/async", |
||||||
|
method: "post", |
||||||
|
data: prompt, |
||||||
|
headers: { |
||||||
|
"Content-Type": "text/plain", |
||||||
|
}, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 下载AI报表(带token认证) |
||||||
|
* @param {string} downloadUrl - 下载URL |
||||||
|
* @returns {Promise<{ blob: Blob, fileName: string }>} |
||||||
|
*/ |
||||||
|
export function downloadReport(downloadUrl) { |
||||||
|
const token = Cookies.get("Admin-Token"); |
||||||
|
const baseURL = process.env.VUE_APP_BASE_API; |
||||||
|
const url = downloadUrl.startsWith('http') ? downloadUrl : `${baseURL}${downloadUrl}`; |
||||||
|
|
||||||
|
return fetch(url, { |
||||||
|
method: 'GET', |
||||||
|
headers: { |
||||||
|
'Authorization': `Bearer ${token}`, |
||||||
|
}, |
||||||
|
}).then(response => { |
||||||
|
if (!response.ok) { |
||||||
|
throw new Error(`Download failed with status: ${response.status}`); |
||||||
|
} |
||||||
|
|
||||||
|
// 解析Content-Disposition头获取文件名
|
||||||
|
let fileName = 'report.docx'; // 默认文件名
|
||||||
|
const contentDisposition = response.headers.get('Content-Disposition'); |
||||||
|
|
||||||
|
if (contentDisposition) { |
||||||
|
// 尝试解析 filename*=UTF-8'' 格式
|
||||||
|
const utf8FilenameMatch = contentDisposition.match(/filename\*=UTF-8''(.+)/); |
||||||
|
if (utf8FilenameMatch) { |
||||||
|
try { |
||||||
|
fileName = decodeURIComponent(utf8FilenameMatch[1]); |
||||||
|
} catch (e) { |
||||||
|
console.error('Failed to decode filename:', e); |
||||||
|
} |
||||||
|
} else { |
||||||
|
// 尝试解析 filename="..." 或 filename=... 格式
|
||||||
|
const filenameMatch = contentDisposition.match(/filename="?([^"]+)"?/); |
||||||
|
if (filenameMatch) { |
||||||
|
fileName = filenameMatch[1]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return response.blob().then(blob => ({ blob, fileName })); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建SSE连接(使用fetch实现,支持Authorization请求头) |
||||||
|
* @param {string} taskId - 任务ID |
||||||
|
* @param {Object} callbacks - 回调函数集合 |
||||||
|
* @param {Function} callbacks.onReasoning - 推理内容回调 |
||||||
|
* @param {Function} callbacks.onCompleted - 完成回调 |
||||||
|
* @param {Function} callbacks.onFailed - 失败回调 |
||||||
|
* @param {Function} callbacks.onError - 错误回调 |
||||||
|
* @param {number} timeout - 超时时间(毫秒),默认30000(30秒) |
||||||
|
* @returns {Object} SSE连接实例,包含close方法 |
||||||
|
*/ |
||||||
|
export function createSSEConnection(taskId, callbacks, timeout = 30000) { |
||||||
|
const { |
||||||
|
onReasoning = () => {}, |
||||||
|
onCompleted = () => {}, |
||||||
|
onFailed = () => {}, |
||||||
|
onError = () => {}, |
||||||
|
} = callbacks; |
||||||
|
|
||||||
|
const token = Cookies.get("Admin-Token"); |
||||||
|
const baseURL = process.env.VUE_APP_BASE_API; |
||||||
|
const url = `${baseURL}/ai/reports/async/${taskId}/subscribe`; |
||||||
|
|
||||||
|
let controller = new AbortController(); |
||||||
|
let timeoutId = null; |
||||||
|
let isCompleted = false; |
||||||
|
|
||||||
|
const connect = async () => { |
||||||
|
// 设置超时
|
||||||
|
timeoutId = setTimeout(() => { |
||||||
|
if (!isCompleted) { |
||||||
|
controller.abort(); |
||||||
|
const error = new Error(`SSE connection timeout after ${timeout}ms`); |
||||||
|
onError(error); |
||||||
|
} |
||||||
|
}, timeout); |
||||||
|
|
||||||
|
try { |
||||||
|
const response = await fetch(url, { |
||||||
|
method: 'GET', |
||||||
|
headers: { |
||||||
|
'Authorization': `Bearer ${token}`, |
||||||
|
'Accept': 'text/event-stream', |
||||||
|
}, |
||||||
|
signal: controller.signal, |
||||||
|
}); |
||||||
|
|
||||||
|
if (!response.ok) { |
||||||
|
throw new Error(`HTTP error! status: ${response.status}`); |
||||||
|
} |
||||||
|
|
||||||
|
const reader = response.body.getReader(); |
||||||
|
const decoder = new TextDecoder(); |
||||||
|
let buffer = ''; |
||||||
|
let lastDataTime = Date.now(); |
||||||
|
|
||||||
|
// 数据超时检测(如果超过超时时间没有收到新数据)
|
||||||
|
const dataTimeoutId = setInterval(() => { |
||||||
|
if (!isCompleted && Date.now() - lastDataTime > timeout) { |
||||||
|
clearInterval(dataTimeoutId); |
||||||
|
controller.abort(); |
||||||
|
const error = new Error(`SSE no data received for ${timeout}ms`); |
||||||
|
onError(error); |
||||||
|
} |
||||||
|
}, 5000); |
||||||
|
|
||||||
|
let currentEventType = null; |
||||||
|
let currentData = ''; |
||||||
|
|
||||||
|
while (true) { |
||||||
|
const { done, value } = await reader.read(); |
||||||
|
if (done) break; |
||||||
|
|
||||||
|
lastDataTime = Date.now(); |
||||||
|
buffer += decoder.decode(value, { stream: true }); |
||||||
|
const lines = buffer.split('\n'); |
||||||
|
buffer = lines.pop() || ''; |
||||||
|
|
||||||
|
for (const line of lines) { |
||||||
|
const trimmedLine = line.trim(); |
||||||
|
if (trimmedLine.startsWith('event:')) { |
||||||
|
currentEventType = trimmedLine.slice(6).trim(); |
||||||
|
} else if (trimmedLine.startsWith('data:')) { |
||||||
|
currentData = trimmedLine.slice(5).trim(); |
||||||
|
if (currentEventType && currentData) { |
||||||
|
if (currentEventType.toLowerCase() === 'reasoning') { |
||||||
|
// reasoning 数据通常是文本内容,直接传递
|
||||||
|
onReasoning(currentData); |
||||||
|
} else if (currentEventType.toLowerCase() === 'completed') { |
||||||
|
// COMPLETED 数据可能是JSON对象,尝试解析
|
||||||
|
try { |
||||||
|
const parsedData = JSON.parse(currentData); |
||||||
|
onCompleted(parsedData); |
||||||
|
} catch (e) { |
||||||
|
onCompleted(currentData); |
||||||
|
} |
||||||
|
isCompleted = true; |
||||||
|
clearTimeout(timeoutId); |
||||||
|
clearInterval(dataTimeoutId); |
||||||
|
} else if (currentEventType.toLowerCase() === 'failed') { |
||||||
|
try { |
||||||
|
const parsedData = JSON.parse(currentData); |
||||||
|
onFailed(parsedData); |
||||||
|
} catch (e) { |
||||||
|
onFailed(currentData); |
||||||
|
} |
||||||
|
isCompleted = true; |
||||||
|
clearTimeout(timeoutId); |
||||||
|
clearInterval(dataTimeoutId); |
||||||
|
} |
||||||
|
} |
||||||
|
} else if (trimmedLine === '') { |
||||||
|
// 空行,事件分隔符,重置事件和数据
|
||||||
|
currentEventType = null; |
||||||
|
currentData = ''; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
if (error.name === 'AbortError') { |
||||||
|
if (!isCompleted) { |
||||||
|
console.log('SSE connection closed'); |
||||||
|
} |
||||||
|
} else { |
||||||
|
console.error('SSE error:', error); |
||||||
|
onError(error); |
||||||
|
} |
||||||
|
} finally { |
||||||
|
clearTimeout(timeoutId); |
||||||
|
isCompleted = true; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
connect(); |
||||||
|
|
||||||
|
return { |
||||||
|
close: () => { |
||||||
|
clearTimeout(timeoutId); |
||||||
|
isCompleted = true; |
||||||
|
controller.abort(); |
||||||
|
}, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取 AI报表数据(用于前端生成报表) |
||||||
|
* @param {string} reportType - 报表类型:comprehensive(综合), air conditioning(空调), lighting(照明), pump(水泵) |
||||||
|
* @param {Object} params - 查询参数 |
||||||
|
* @returns {Promise} |
||||||
|
*/ |
||||||
|
export function getReportData(reportType, params) { |
||||||
|
return request({ |
||||||
|
url: `/ai/reports/${reportType}/data`, |
||||||
|
method: "get", |
||||||
|
params: params, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* AI 对话接口(实时交互) |
||||||
|
* @param {string} message - 用户消息 |
||||||
|
* @param {string} conversationId - 会话 ID |
||||||
|
* @returns {Promise} |
||||||
|
*/ |
||||||
|
export function chat(message, conversationId) { |
||||||
|
return request({ |
||||||
|
url: "/ai/chat", |
||||||
|
method: "post", |
||||||
|
data: { |
||||||
|
message, |
||||||
|
conversationId, |
||||||
|
}, |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
// 查询运行记录
|
||||||
|
export function boilerSysList(data) { |
||||||
|
return request({ |
||||||
|
url: "/reportSteam/list", |
||||||
|
method: "post", |
||||||
|
data, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 编辑运行记录
|
||||||
|
export function boilerSysEdit(data) { |
||||||
|
return request({ |
||||||
|
url: "/reportSteam/edit", |
||||||
|
method: "put", |
||||||
|
data, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 导出
|
||||||
|
export function boilerSysExport(data) { |
||||||
|
return request({ |
||||||
|
url: "/reportSteam/export", |
||||||
|
method: "post", |
||||||
|
data, |
||||||
|
responseType: "blob", |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
// 采暖泵列表
|
||||||
|
export function heatPumpList(query) { |
||||||
|
return request({ |
||||||
|
url: "/device/heatPump/list", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 采暖泵在线情况
|
||||||
|
export function heatPumpOnlineList(query) { |
||||||
|
return request({ |
||||||
|
url: "/device/heatPump/online", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 采暖泵报警列表
|
||||||
|
export function heatPumpAlarmList(query) { |
||||||
|
return request({ |
||||||
|
url: "/device/heatPump/alarmList", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
@ -0,0 +1,27 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
// 查询运行记录
|
||||||
|
export function boilerSysList(data) { |
||||||
|
return request({ |
||||||
|
url: "/reportHeating/list", |
||||||
|
method: "post", |
||||||
|
data, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 编辑运行记录
|
||||||
|
export function boilerSysEdit(data) { |
||||||
|
return request({ |
||||||
|
url: "/reportHeating/edit", |
||||||
|
method: "put", |
||||||
|
data, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 导出
|
||||||
|
export function boilerSysExport(data) { |
||||||
|
return request({ |
||||||
|
url: "/reportHeating/export", |
||||||
|
method: "post", |
||||||
|
data, |
||||||
|
responseType: "blob", |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
// 热水锅炉设备参数列表
|
||||||
|
export function hotWaterBoiler(query) { |
||||||
|
return request({ |
||||||
|
url: "/device/hotWaterBoiler/list", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
// 蒸汽锅炉设备参数列表
|
||||||
|
export function steamBoilerBoiler(query) { |
||||||
|
return request({ |
||||||
|
url: "/device/steamBoiler/list", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
// 查询运行记录
|
||||||
|
export function reportSysList(data) { |
||||||
|
return request({ |
||||||
|
url: "/reportSys/list", |
||||||
|
method: "post", |
||||||
|
data, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 编辑运行记录
|
||||||
|
export function reportSysEdit(data) { |
||||||
|
return request({ |
||||||
|
url: "/reportSys/edit", |
||||||
|
method: "put", |
||||||
|
data, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 导出
|
||||||
|
export function reportSysExport(data) { |
||||||
|
return request({ |
||||||
|
url: "/reportSys/export", |
||||||
|
method: "post", |
||||||
|
data, |
||||||
|
responseType: 'blob', |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
// 历史天气查询
|
||||||
|
export function weatherTempData(query) { |
||||||
|
return request({ |
||||||
|
url: "/device/cs/getWeatherTemp", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
export const hotWaterList = (data) => { |
||||||
|
return request({ |
||||||
|
url: "/reportHotWater/list", |
||||||
|
method: "post", |
||||||
|
data: data, |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// 导出
|
||||||
|
export const hotWaterExport = (data) => { |
||||||
|
return request({ |
||||||
|
url: "/reportHotWater/export", |
||||||
|
method: "post", |
||||||
|
data, |
||||||
|
responseType: "blob", |
||||||
|
}); |
||||||
|
}; |
||||||
|
// 修改
|
||||||
|
export const hotWaterEdit = (data) => { |
||||||
|
return request({ |
||||||
|
url: "/reportHotWater/edit", |
||||||
|
method: "put", |
||||||
|
data: data, |
||||||
|
}); |
||||||
|
}; |
||||||
@ -0,0 +1,19 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
export const meterReadingsList = (data) => { |
||||||
|
return request({ |
||||||
|
url: "/reportMeterReadings/list", |
||||||
|
method: "post", |
||||||
|
data: data, |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
// 导出
|
||||||
|
export const meterReadingsExport = (data) => { |
||||||
|
return request({ |
||||||
|
url: "/reportMeterReadings/export", |
||||||
|
method: "post", |
||||||
|
data, |
||||||
|
responseType: "blob", |
||||||
|
}); |
||||||
|
}; |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
export const compreReport = (data) => { |
||||||
|
return request({ |
||||||
|
url: "/compre/report", |
||||||
|
method: "post", |
||||||
|
data, |
||||||
|
}); |
||||||
|
}; |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
// 工艺流程图数据列表
|
||||||
|
export function monitorList(query) { |
||||||
|
return request({ |
||||||
|
url: "/device/ers/monitor/list", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 累积热量框数据
|
||||||
|
export function monitorTotalDatas(query) { |
||||||
|
return request({ |
||||||
|
url: "/device/ers/monitor/totalDatas", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
// 数据分析-月
|
||||||
|
export function queryMonthDatas(query) { |
||||||
|
return request({ |
||||||
|
url: "/hot_energy/analysis/queryMonth", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 数据分析-年
|
||||||
|
export function queryYearDatas(query) { |
||||||
|
return request({ |
||||||
|
url: "/hot_energy/analysis/queryYear", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,34 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
// 楼层
|
||||||
|
export function hotBuildList(query) { |
||||||
|
return request({ |
||||||
|
url: "/space/building/hot_list", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 楼栋能耗环比
|
||||||
|
export function hotEnergySum(query) { |
||||||
|
return request({ |
||||||
|
url: "/hot_energy/energySum", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 温度变化表
|
||||||
|
export function hotWaterTemp(query) { |
||||||
|
return request({ |
||||||
|
url: "/hot_energy/waterTemp", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 温度变化表
|
||||||
|
export function hotWaterLevel(query) { |
||||||
|
return request({ |
||||||
|
url: "/hot_energy/waterLevel", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
// 水电表读数
|
||||||
|
export function queryDeviceDatas(query) { |
||||||
|
return request({ |
||||||
|
url: "/hot_energy/queryDeviceDatas", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
@ -0,0 +1,18 @@ |
|||||||
|
import request from "@/utils/request"; |
||||||
|
|
||||||
|
// 设备状态
|
||||||
|
export function deviceState(query) { |
||||||
|
return request({ |
||||||
|
url: "/device/hotWater/deviceState", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
|
// 楼栋能耗
|
||||||
|
export function hotEnergyQuery(query) { |
||||||
|
return request({ |
||||||
|
url: "/hot_energy/query", |
||||||
|
method: "get", |
||||||
|
params: query, |
||||||
|
}); |
||||||
|
} |
||||||
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 197 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 248 KiB After Width: | Height: | Size: 468 KiB |
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 284 KiB After Width: | Height: | Size: 284 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1000 B After Width: | Height: | Size: 1000 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 283 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 576 KiB After Width: | Height: | Size: 576 KiB |
|
After Width: | Height: | Size: 738 KiB |
|
After Width: | Height: | Size: 340 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 119 KiB |
|
After Width: | Height: | Size: 342 KiB |
|
After Width: | Height: | Size: 531 KiB |
|
Before Width: | Height: | Size: 410 KiB After Width: | Height: | Size: 410 KiB |
|
Before Width: | Height: | Size: 531 KiB After Width: | Height: | Size: 307 KiB |
|
Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 417 KiB |
|
After Width: | Height: | Size: 5.2 MiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 2.8 MiB |
|
After Width: | Height: | Size: 13 MiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 6.4 MiB |
|
After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 3.3 KiB |