@ -0,0 +1,45 @@ |
|||
/** |
|||
* |
|||
* @param {HTMLElement} container |
|||
* @param {{ target: HTMLElement }} param1 |
|||
*/ |
|||
export function moveable(container, { target } = {}) { |
|||
if (!target) target = container; |
|||
|
|||
target.style.cursor = "move"; |
|||
|
|||
/** |
|||
* @type { { clientX: number; clientY: number } } |
|||
*/ |
|||
let lastPosition = { clientX: 0, clientY: 0 }; |
|||
|
|||
const down = (e) => { |
|||
const { clientX: x, clientY: y } = e; |
|||
|
|||
const move = (e) => { |
|||
const { clientX, clientY } = e; |
|||
|
|||
console.log(clientX, clientY, "move"); |
|||
|
|||
container.style.transform = `translate3d(${ |
|||
clientX - x + lastPosition.clientX |
|||
}px, ${clientY - y + lastPosition.clientY}px, 0)`;
|
|||
}; |
|||
|
|||
const up = (e) => { |
|||
const { clientX, clientY } = e; |
|||
lastPosition.clientX += clientX - x; |
|||
lastPosition.clientY += clientY - y; |
|||
|
|||
document.removeEventListener("pointermove", move); |
|||
document.removeEventListener("pointerup", up); |
|||
}; |
|||
|
|||
document.addEventListener("pointermove", move); |
|||
document.addEventListener("pointerup", up); |
|||
}; |
|||
|
|||
target.addEventListener("pointerdown", down); |
|||
|
|||
return () => target.removeEventListener("pointerdown", down); |
|||
} |
@ -0,0 +1,32 @@ |
|||
<template> |
|||
<video controls autoplay muted class="video-stream" v-bind="$attrs" ref="videoContainerRef" /> |
|||
</template> |
|||
|
|||
<script> |
|||
import { HttpLivePlayer } from "./videoStream.js" |
|||
|
|||
export default { |
|||
name: 'Video', |
|||
props: { |
|||
camId: { |
|||
type: String, |
|||
default: null |
|||
}, |
|||
url: { |
|||
type: String, |
|||
default: null |
|||
} |
|||
}, |
|||
mounted() { |
|||
const player = new HttpLivePlayer(this.$refs.videoContainerRef, { camId: this.camId, url: this.url }); |
|||
|
|||
this.$once("hook:beforeDestroy", () => player.destroy()); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang='scss' scoped> |
|||
.video-stream { |
|||
background-color: #000; |
|||
} |
|||
</style> |
After Width: | Height: | Size: 994 B |
Before Width: | Height: | Size: 950 B |
Before Width: | Height: | Size: 572 B |
Before Width: | Height: | Size: 584 B |
Before Width: | Height: | Size: 595 B |
After Width: | Height: | Size: 2.4 KiB |
@ -0,0 +1,193 @@ |
|||
<template> |
|||
<Dialog v-model="modelVisible" title="广播发布"> |
|||
<div class='BroadcastReleases'> |
|||
<div class="body"> |
|||
<div class="left"> |
|||
<div class="title">路测广播列表</div> |
|||
<CheckboxGroup class="checkbox-group" :value="[]" :options="options" /> |
|||
</div> |
|||
<div class="right"> |
|||
<div class="top-content"> |
|||
<Video class="item-video" /> |
|||
|
|||
<label>发布内容: </label> |
|||
<ElInput type="textarea" :autosize="{ minRows: 3, maxRows: 3 }" :maxlength="150" showWordLimit /> |
|||
</div> |
|||
|
|||
<div class="footer"> |
|||
<Button style="background-color: rgba(0, 179, 204, .3);" |
|||
@click.native="modelVisible = false, submitting = false"> |
|||
取消 |
|||
</Button> |
|||
<Button @click.native="handleSubmit" :loading="submitting"> |
|||
确定 |
|||
</Button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- <Form class="form" ref="FormConfigRef" :formList="formList" column="1" style="flex: 1;" labelWidth="120px" /> --> |
|||
|
|||
</div> |
|||
</Dialog> |
|||
</template> |
|||
|
|||
<script> |
|||
import Dialog from "@screen/components/Dialog/index.vue"; |
|||
import Button from "@screen/components/Buttons/Button.vue" |
|||
import Form from '@screen/components/FormConfig'; |
|||
import Video from "@screen/components/Video" |
|||
import CheckboxGroup from "@screen/components/FormConfig/components/ElCheckboxGroup.vue" |
|||
|
|||
import { delay } from "@screen/utils/common.js" |
|||
import request from "@/utils/request"; |
|||
|
|||
import { Message } from "element-ui"; |
|||
// import { axiosIns } from "@screen/utils/axios/auth.js"; |
|||
|
|||
export default { |
|||
name: 'BroadcastReleases', |
|||
components: { |
|||
Dialog, |
|||
Button, |
|||
Form, |
|||
Video, |
|||
CheckboxGroup |
|||
}, |
|||
model: { |
|||
prop: 'visible', |
|||
event: "update:value" |
|||
}, |
|||
props: { |
|||
visible: Boolean, |
|||
deviceId: String |
|||
}, |
|||
data() { |
|||
return { |
|||
submitting: false, |
|||
options: Array.from({ length: 24 }).map((_, index) => ({ |
|||
key: index, |
|||
label: "阿发" |
|||
})) |
|||
} |
|||
}, |
|||
computed: { |
|||
modelVisible: { |
|||
get() { |
|||
return this.visible |
|||
}, |
|||
set(val) { |
|||
this.$emit('update:value', val) |
|||
} |
|||
} |
|||
}, |
|||
watch: { |
|||
modelVisible: { |
|||
immediate: true, |
|||
handler(bool) { |
|||
if (!bool) return; |
|||
|
|||
this.reDisplay(); |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
reDisplay() { |
|||
}, |
|||
handleSubmit() { |
|||
const result = {}, formData = this.$refs.FormConfigRef?.formData; |
|||
|
|||
let functionId = 51; |
|||
|
|||
result.mode = formData.controlType === 'manual' ? "00" : "01"; |
|||
|
|||
delete result.controlType; |
|||
|
|||
if (result.mode === '01') { |
|||
if (!formData.displayTime?.length) return Message.error(`时间不能为空!`); |
|||
result.startDisplayTime = formData.displayTime[0]; |
|||
result.endDisplayTime = formData.displayTime[1]; |
|||
delete result.displayTime; |
|||
} else { |
|||
if (!formData.onWorkStatus || !formData.inWorkStatus) return Message.error(`工作状态不能为空!`); |
|||
|
|||
result.onWorkStatus = formData.onWorkStatus |
|||
result.inWorkStatus = formData.inWorkStatus |
|||
} |
|||
|
|||
this.submitting = true; |
|||
|
|||
// this.submitting = false; |
|||
// return; |
|||
} |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang='scss' scoped> |
|||
.BroadcastReleases { |
|||
// width: 450px; |
|||
height: 397px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 15px; |
|||
|
|||
.body { |
|||
display: flex; |
|||
gap: 9px; |
|||
height: 100%; |
|||
|
|||
.left { |
|||
width: 251px; |
|||
border-radius: 3px 3px 3px 3px; |
|||
border: 1px solid #3DE8FF; |
|||
padding: 3px 12px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 9px; |
|||
|
|||
.checkbox-group { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 6px; |
|||
overflow: auto; |
|||
height: 100%; |
|||
flex: 1; |
|||
flex-wrap: nowrap; |
|||
} |
|||
} |
|||
|
|||
.right { |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-between; |
|||
|
|||
.top-content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 9px; |
|||
|
|||
.item-video { |
|||
width: 545px; |
|||
height: 216px; |
|||
} |
|||
|
|||
label { |
|||
font-size: 16px; |
|||
font-family: PingFang SC, PingFang SC; |
|||
font-weight: 400; |
|||
color: #3DE8FF; |
|||
line-height: 19px; |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
.footer { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
gap: 9px; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,157 @@ |
|||
<template> |
|||
<Dialog v-model="obverseVisible" title="行车诱导"> |
|||
<Video class="item-video" /> |
|||
|
|||
<div class="Broadcast"> |
|||
<ElTabs v-model="activeName" @tab-click="handleClickTabs" class="tabs"> |
|||
<ElTabPane label="详细设计" name="first"> |
|||
<Descriptions :list="list" :data="data" style="gap: 18px" /> |
|||
</ElTabPane> |
|||
<ElTabPane label="设备参数" name="second">设备参数</ElTabPane> |
|||
</ElTabs> |
|||
|
|||
<div class="bottom"> |
|||
<Button @click.native="releaseVisible = true">广播发布</Button> |
|||
</div> |
|||
</div> |
|||
|
|||
<BroadcastReleases v-model="releaseVisible" :deviceId="dialogData.iotDeviceId || '8697-1'" /> |
|||
</Dialog> |
|||
</template> |
|||
|
|||
<script> |
|||
import Dialog from "@screen/components/Dialog/index.vue"; |
|||
import Button from "@screen/components/Buttons/Button.vue" |
|||
import Descriptions from '@screen/components/Descriptions.vue'; |
|||
import CustomControlVideo from '@screen/components/CustomControlVideo/index.vue'; |
|||
import BroadcastReleases from "./components/BroadcastReleases.vue" |
|||
import Video from "@screen/components/Video" |
|||
|
|||
import { getRoadInfoByStakeMark, getOrganizationName, getProduct } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js" |
|||
import { dialogDelayVisible } from "./../mixin" |
|||
|
|||
// 广播发布 |
|||
export default { |
|||
name: 'Broadcast', |
|||
mixins: [dialogDelayVisible], |
|||
components: { |
|||
Dialog, |
|||
Button, |
|||
Descriptions, |
|||
CustomControlVideo, |
|||
BroadcastReleases, |
|||
Video |
|||
}, |
|||
data() { |
|||
return { |
|||
activeName: 'first', |
|||
releaseVisible: false, |
|||
data: { |
|||
deviceName: "LH24", |
|||
roadName: "G35济泽高速", |
|||
stakeMarkId: "k094+079", |
|||
direction: "1", |
|||
organizationName: "山东高速济南发展公司", |
|||
brand: "XXX厂家", |
|||
deviceState: "0", |
|||
}, |
|||
list: [ |
|||
{ |
|||
label: '设备名称', |
|||
key: "deviceName", |
|||
}, |
|||
{ |
|||
label: '道路名称', |
|||
key: "roadName", |
|||
}, |
|||
{ |
|||
label: '设备桩号', |
|||
key: "stakeMarkId", |
|||
}, |
|||
{ |
|||
label: '所属方向', |
|||
key: "direction", |
|||
enum: "CameraDirectionEnum" |
|||
}, |
|||
{ |
|||
label: '所属机构', |
|||
key: "organizationName", |
|||
}, |
|||
{ |
|||
label: '设备厂商', |
|||
key: "brand", |
|||
}, |
|||
{ |
|||
label: '设备状态', |
|||
key: "deviceState", |
|||
enum: "DeviceTypeEnum" |
|||
}, |
|||
] |
|||
} |
|||
}, |
|||
async created() { |
|||
this.data = { ...this.dialogData, roadName: null } |
|||
|
|||
getProduct(this.dialogData.productId) |
|||
.then(data => { |
|||
this.dialogData.brand = data.brand; |
|||
}) |
|||
|
|||
getOrganizationName(this.dialogData.iotDeviceId) |
|||
.then(data => { |
|||
this.dialogData.organizationName = data.organizationName; |
|||
}) |
|||
|
|||
const roadInfo = await getRoadInfoByStakeMark(this.dialogData.stakeMarkId); |
|||
console.log("%c [ roadInfo ]-103-「index.vue」", "font-size:15px; background:#36347c; color:#7a78c0;", roadInfo.roadName); |
|||
|
|||
if (roadInfo) this.data.roadName = roadInfo.roadName; |
|||
}, |
|||
methods: { |
|||
handleClickTabs() { } |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang='scss' scoped> |
|||
.Broadcast { |
|||
width: 600px; |
|||
height: 240px; |
|||
color: #fff; |
|||
display: flex; |
|||
flex-direction: column; |
|||
|
|||
.camera-video { |
|||
flex: 1.5; |
|||
} |
|||
|
|||
.tabs { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
|
|||
::v-deep { |
|||
.el-tabs__content { |
|||
flex: 1; |
|||
|
|||
.el-tab-pane { |
|||
height: 100%; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.bottom { |
|||
margin-top: 12px; |
|||
display: flex; |
|||
gap: 9px; |
|||
align-items: center; |
|||
justify-content: end; |
|||
|
|||
>div { |
|||
font-size: 16px; |
|||
padding: 6px 12px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -1,122 +0,0 @@ |
|||
<template> |
|||
<div class='Descriptions'> |
|||
<p class="desc-item"> |
|||
<span>设备类型:</span> |
|||
<span> |
|||
{{ cameraType || '-' }} |
|||
<img src="@screen/images/dialog/icon-control.png"> |
|||
</span> |
|||
</p> |
|||
<p class="desc-item"> |
|||
<span>道路名称:</span> |
|||
<span>{{ roadName || '-' }}</span> |
|||
</p> |
|||
<p class="desc-item"> |
|||
<span>所属机构:</span> |
|||
<span>{{ organizationName || '-' }}</span> |
|||
</p> |
|||
<p class="desc-item"> |
|||
<span>设备桩号:</span> |
|||
<span>{{ data.stakeMarkId || '-' }}</span> |
|||
</p> |
|||
<p class="desc-item"> |
|||
<span>上行相机:</span> |
|||
<span> |
|||
米 |
|||
<img src="@screen/images/dialog/icon-monitor.png"> |
|||
</span> |
|||
</p> |
|||
<p class="desc-item"> |
|||
<span>下行相机:</span> |
|||
<span> |
|||
米 |
|||
<img src="@screen/images/dialog/icon-monitor.png"> |
|||
</span> |
|||
</p> |
|||
<p class="desc-item singleline"> |
|||
<span>设备状态:</span> |
|||
<span :style="{ color: statusEnum.color || '#19E1B1' }">{{ statusEnum.text }}</span> |
|||
</p> |
|||
<p class="desc-item singleline"> |
|||
<span>状态更新时间:</span> |
|||
<span>{{ data.updateTime }}</span> |
|||
</p> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { CameraStatusEnum, CameraControlTypeEnum } from "@screen/utils/enum.js" |
|||
import { getRoadInfoByStakeMark } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js" |
|||
import request from "@/utils/request"; |
|||
|
|||
export default { |
|||
name: 'Descriptions', |
|||
props: { |
|||
data: { |
|||
type: Object, |
|||
default: () => ({}) |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
statusEnum: CameraStatusEnum[this.data.status] || {}, |
|||
cameraType: CameraControlTypeEnum[this.data.ptzCtrl]?.text, |
|||
organizationName: null, |
|||
roadName: "" |
|||
} |
|||
}, |
|||
async created() { |
|||
request({ |
|||
url: `/business/organization/${id}`, |
|||
method: "get", |
|||
}) |
|||
.then(({ code, data }) => { |
|||
if (code != 200) return; |
|||
|
|||
this.organizationName = data.organizationName; |
|||
}) |
|||
.catch((err) => { |
|||
|
|||
}); |
|||
|
|||
|
|||
const roadInfo = await getRoadInfoByStakeMark(this.dialogData.stakeMarkId); |
|||
|
|||
if (roadInfo) this.roadName = roadInfo.roadName; |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang='scss' scoped> |
|||
.Descriptions { |
|||
height: 100%; |
|||
display: grid; |
|||
grid-template-columns: repeat(2, 1fr); |
|||
font-size: 16px; |
|||
// font-family: PingFang SC, PingFang SC; |
|||
font-weight: 400; |
|||
line-height: 19px; |
|||
grid-auto-rows: min-content; |
|||
gap: 15px; |
|||
// -webkit-background-clip: text; |
|||
// -webkit-text-fill-color: transparent; |
|||
|
|||
>p { |
|||
>span { |
|||
&:first-child { |
|||
color: #3DE8FF; |
|||
} |
|||
|
|||
&:last-child { |
|||
display: inline-flex; |
|||
align-items: center; |
|||
gap: 9px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.singleline { |
|||
grid-column: span 2; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,202 @@ |
|||
<template> |
|||
<Dialog v-model="modelVisible" title="相机控制" noneMask> |
|||
<div class='CameraControlDialog'> |
|||
<div class="direction"> |
|||
<div class="control-container top" @click="controlClick(21)"> |
|||
<div class="icon-horizontal" /> |
|||
<img src="../images/top.svg"> |
|||
</div> |
|||
<div class="control-container right" @click="controlClick(24)"> |
|||
<div class="icon-vertical" /> |
|||
<img src="../images/right.svg"> |
|||
</div> |
|||
<div class="center"></div> |
|||
<div class="control-container bottom" @click="controlClick(22)"> |
|||
<div class="icon-horizontal" style="transform: rotate(180deg);" /> |
|||
<img src="../images/bottom.svg"> |
|||
</div> |
|||
<div class="control-container left" @click="controlClick(23)"> |
|||
<div class="icon-vertical" style="transform: rotate(180deg);" /> |
|||
<img src="../images/left.svg"> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="options"> |
|||
<div v-for="item in options" :key="item.key"> |
|||
<img src="../images/sub.svg" @click="controlClick(item.sub)"> |
|||
<span>{{ item.label }}</span> |
|||
<img src="../images/add.svg" @click="controlClick(item.add)"> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</Dialog> |
|||
</template> |
|||
|
|||
<script> |
|||
import Dialog from "@screen/components/Dialog/index.vue"; |
|||
import { controlCamera } from "@screen/pages/Home/components/RoadAndEvents/utils/httpList.js" |
|||
import { throttle } from "lodash" |
|||
|
|||
export default { |
|||
name: 'CameraControlDialog', |
|||
components: { |
|||
Dialog |
|||
}, |
|||
model: { |
|||
prop: 'visible', |
|||
event: "update:value" |
|||
}, |
|||
props: { |
|||
visible: Boolean, |
|||
deviceId: String |
|||
}, |
|||
data() { |
|||
return { |
|||
options: [ |
|||
{ |
|||
label: "变倍", |
|||
key: "zoom", |
|||
add: "12", |
|||
sub: "11" |
|||
}, |
|||
{ |
|||
label: "光圈", |
|||
key: "aperture", |
|||
add: "15", |
|||
sub: "16" |
|||
}, |
|||
{ |
|||
label: "聚焦", |
|||
key: "focus", |
|||
add: "13", |
|||
sub: "14" |
|||
}, |
|||
] |
|||
} |
|||
}, |
|||
computed: { |
|||
modelVisible: { |
|||
get() { |
|||
return this.visible |
|||
}, |
|||
set(val) { |
|||
this.$emit('update:value', val) |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
controlClick: throttle(function (type) { |
|||
controlCamera(this.deviceId, type) |
|||
}, 150) |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang='scss' scoped> |
|||
.CameraControlDialog { |
|||
width: 360px; |
|||
height: 210px; |
|||
display: flex; |
|||
|
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-around; |
|||
gap: 36px; |
|||
|
|||
img { |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.control-container { |
|||
position: relative; |
|||
width: min-content; |
|||
|
|||
&:active { |
|||
[class^="icon"] { |
|||
background-color: #48B0CB; |
|||
} |
|||
} |
|||
|
|||
.icon-horizontal, |
|||
.icon-vertical { |
|||
position: absolute; |
|||
left: 0; |
|||
top: 0; |
|||
background-color: #006A96; |
|||
z-index: -1; |
|||
} |
|||
|
|||
.icon-horizontal { |
|||
clip-path: path('M53.807 19.0734C51.1049 21.3657 47.1722 21.2685 44.0948 19.512C35.7042 14.7227 25.2544 13.7636 15.6704 17.82C14.5092 18.3114 13.3921 18.8632 12.321 19.4703C9.23352 21.2201 5.29428 21.3087 2.59447 19.0054V19.0054C-0.433686 16.4219 -0.827317 11.8122 2.24787 9.28482C4.93936 7.07281 7.91063 5.2081 11.093 3.74265C16.4653 1.26882 22.3109 -0.00817108 28.2253 6.86646e-05C34.1398 0.0083065 39.9818 1.30157 45.3471 3.79036C48.527 5.26539 51.4944 7.13947 54.1807 9.36039C57.2464 11.8949 56.8402 16.5002 53.807 19.0734V19.0734Z'); |
|||
width: 57px; |
|||
height: 21px; |
|||
} |
|||
|
|||
.icon-vertical { |
|||
clip-path: path('M2.33992 53.8068C0.0475853 51.1047 0.14481 47.172 1.90137 44.0945C6.69064 35.7039 7.64974 25.2542 3.59338 15.6702C3.10192 14.509 2.55008 13.3918 1.94307 12.3208C0.193261 9.23327 0.1046 5.29403 2.40796 2.59423V2.59423C4.99146 -0.433928 9.60116 -0.827561 12.1285 2.24762C14.3405 4.93912 16.2052 7.91038 17.6707 11.0928C20.1445 16.465 21.4215 22.3106 21.4133 28.2251C21.405 34.1395 20.1117 39.9816 17.623 45.3469C16.1479 48.5267 14.2738 51.4941 12.0529 54.1805C9.51843 57.2461 4.91315 56.84 2.33992 53.8068V53.8068Z'); |
|||
width: 21px; |
|||
height: 57px; |
|||
} |
|||
} |
|||
|
|||
.direction { |
|||
display: grid; |
|||
grid-template-columns: 0.3fr 1fr 0.3fr; |
|||
grid-template-rows: 0.3fr 1fr 0.3fr; |
|||
align-items: center; |
|||
justify-items: center; |
|||
|
|||
gap: 3px; |
|||
|
|||
|
|||
.top { |
|||
grid-area: 1/2/1/2; |
|||
} |
|||
|
|||
.right { |
|||
grid-area: 2/3/2/3; |
|||
} |
|||
|
|||
.bottom { |
|||
grid-area: 3/2/3/2; |
|||
} |
|||
|
|||
.left { |
|||
grid-area: 2/1/2/1; |
|||
} |
|||
|
|||
.center { |
|||
grid-area: 2/2/2/2; |
|||
|
|||
width: 66px; |
|||
height: 66px; |
|||
background: #006A96; |
|||
border-radius: 50%; |
|||
opacity: 1; |
|||
border: 1px solid #3DE8FF |
|||
} |
|||
} |
|||
|
|||
.options { |
|||
display: flex; |
|||
flex-direction: column; |
|||
|
|||
gap: 18px; |
|||
|
|||
>div { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 9px; |
|||
|
|||
img { |
|||
background-color: #006A96; |
|||
border-radius: 50%; |
|||
|
|||
&:active { |
|||
background-color: #48B0CB; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 657 B After Width: | Height: | Size: 643 B |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.2 KiB |