ENH: Layout rework
parent
2dfdfdf986
commit
6141ae7693
Binary file not shown.
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
|
@ -57,8 +57,12 @@
|
|||
"OSE.HealthShort": "HP",
|
||||
"OSE.HitDice": "Hit Dice",
|
||||
"OSE.HitDiceShort": "HD",
|
||||
"OSE.Movement": "Movement",
|
||||
"OSE.MovementShort": "MOV",
|
||||
"OSE.Movement": "Movement Rate",
|
||||
"OSE.MovementEncounter": "Encounter Movement Rate",
|
||||
"OSE.MovementEncounterShort": "ENC",
|
||||
"OSE.MovementOverland": "Overland Movement Rate",
|
||||
"OSE.MovementOverlandShort": "OVE",
|
||||
"OSE.MovementShort": "MR",
|
||||
"OSE.ArmorClass": "Armor Class",
|
||||
"OSE.ArmorClassShort": "AC",
|
||||
"OSE.AscArmorClassShort": "AAC",
|
||||
|
|
@ -67,8 +71,10 @@
|
|||
"OSE.Thac0": "THAC0",
|
||||
"OSE.MeleeShort": "MEL",
|
||||
"OSE.Melee": "Melee",
|
||||
"OSE.MeleeBonus": "Melee Bonus",
|
||||
"OSE.MissileShort": "MIS",
|
||||
"OSE.Missile": "Missile",
|
||||
"OSE.MissileBonus": "Missile Bonus",
|
||||
"OSE.Initiative": "Initiative",
|
||||
"OSE.InitiativeShort": "INIT",
|
||||
"OSE.Attacks": "Attacks Usable per Round",
|
||||
|
|
|
|||
|
|
@ -85,6 +85,13 @@ export class OseActorSheet extends ActorSheet {
|
|||
});
|
||||
});
|
||||
|
||||
html.find(".item-image").click(async (ev) => {
|
||||
const li = $(ev.currentTarget).parents(".item");
|
||||
const item = this.actor.getOwnedItem(li.data("itemId"));
|
||||
item.roll();
|
||||
});
|
||||
|
||||
|
||||
super.activateListeners(html);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,14 @@ export const registerHelpers = async function () {
|
|||
return parseInt(rh) - parseInt(lh);
|
||||
});
|
||||
|
||||
Handlebars.registerHelper("divide", function (lh, rh) {
|
||||
return Math.floor(parseFloat(lh) / parseFloat(rh));
|
||||
});
|
||||
|
||||
Handlebars.registerHelper("mult", function (lh, rh) {
|
||||
return parseInt(lh) * parseInt(rh);
|
||||
});
|
||||
|
||||
Handlebars.registerHelper("counter", function (status, value, max) {
|
||||
return status ? Math.clamped((100.0 * value) / max, 0, 100) : Math.clamped(100 - (100.0 * value) / max, 0, 100);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,4 +12,79 @@ export class OseItem extends Item {
|
|||
prepareData() {
|
||||
super.prepareData();
|
||||
}
|
||||
|
||||
getChatData(htmlOptions) {
|
||||
const data = duplicate(this.data.data);
|
||||
|
||||
// Rich text description
|
||||
data.description = TextEditor.enrichHTML(data.description, htmlOptions);
|
||||
|
||||
// Item properties
|
||||
const props = [];
|
||||
const labels = this.labels;
|
||||
|
||||
if (this.data.type == "weapon") {
|
||||
props.push(data.qualities);
|
||||
}
|
||||
if (this.data.type == "spell") {
|
||||
props.push(
|
||||
`${data.class} ${data.lvl}`,
|
||||
data.range,
|
||||
data.duration
|
||||
);
|
||||
}
|
||||
if (data.hasOwnProperty("equipped")) {
|
||||
props.push(data.equipped ? "Equipped" : "Not Equipped");
|
||||
}
|
||||
|
||||
// Filter properties and return
|
||||
data.properties = props.filter((p) => !!p);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll the item to Chat, creating a chat card which contains follow up attack or damage roll options
|
||||
* @return {Promise}
|
||||
*/
|
||||
async roll({ configureDialog = true } = {}) {
|
||||
// Basic template rendering data
|
||||
const token = this.actor.token;
|
||||
const templateData = {
|
||||
actor: this.actor,
|
||||
tokenId: token ? `${token.scene._id}.${token.id}` : null,
|
||||
item: this.data,
|
||||
data: this.getChatData(),
|
||||
labels: this.labels,
|
||||
hasAttack: this.hasAttack,
|
||||
isHealing: this.isHealing,
|
||||
hasDamage: this.hasDamage,
|
||||
isSpell: this.data.type === "spell",
|
||||
hasSave: this.hasSave,
|
||||
};
|
||||
|
||||
// Render the chat card template
|
||||
const template = `systems/ose/templates/chat/item-card.html`;
|
||||
const html = await renderTemplate(template, templateData);
|
||||
|
||||
// Basic chat message data
|
||||
const chatData = {
|
||||
user: game.user._id,
|
||||
type: CONST.CHAT_MESSAGE_TYPES.OTHER,
|
||||
content: html,
|
||||
speaker: {
|
||||
actor: this.actor._id,
|
||||
token: this.actor.token,
|
||||
alias: this.actor.name,
|
||||
},
|
||||
};
|
||||
|
||||
// Toggle default roll mode
|
||||
let rollMode = game.settings.get("core", "rollMode");
|
||||
if (["gmroll", "blindroll"].includes(rollMode))
|
||||
chatData["whisper"] = ChatMessage.getWhisperRecipients("GM");
|
||||
if (rollMode === "blindroll") chatData["blind"] = true;
|
||||
|
||||
// Create the chat message
|
||||
return ChatMessage.create(chatData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@
|
|||
padding: 0;
|
||||
.attribute {
|
||||
position: relative;
|
||||
margin: 10px;
|
||||
margin: 8px;
|
||||
border: 1px solid $colorTan;
|
||||
.attribute-name {
|
||||
color: whitesmoke;
|
||||
|
|
@ -104,25 +104,31 @@
|
|||
background: $colorDark;
|
||||
text-align: center;
|
||||
}
|
||||
.attribute-value {
|
||||
padding: 4px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
&.multiple input {
|
||||
min-width: 28px;
|
||||
&.attribute-secondaries {
|
||||
margin: 10px 5px;
|
||||
}
|
||||
&.ability-score {
|
||||
height: 40px;
|
||||
.attribute-value {
|
||||
line-height: 36px;
|
||||
}
|
||||
}
|
||||
.attribute-value {
|
||||
text-align: center;
|
||||
padding: 4px;
|
||||
}
|
||||
.attribute-mod {
|
||||
position: absolute;
|
||||
color: $colorTan;
|
||||
right: 5px;
|
||||
top: 0;
|
||||
top: -5px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.attribute-group {
|
||||
flex: 0 0 105px;
|
||||
margin: auto 0;
|
||||
.attributes {
|
||||
.attribute {
|
||||
display: flex;
|
||||
|
|
@ -130,7 +136,7 @@
|
|||
.attribute-name {
|
||||
width: 40px;
|
||||
margin: 0;
|
||||
line-height: 28px;
|
||||
line-height: 38px;
|
||||
a {
|
||||
margin: auto;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
|
||||
.ose.chat-card {
|
||||
font-style: normal;
|
||||
font-size: 12px;
|
||||
|
||||
.card-header {
|
||||
padding: 3px 0;
|
||||
border-top: 2px groove #FFF;
|
||||
border-bottom: 2px groove #FFF;
|
||||
|
||||
img {
|
||||
flex: 0 0 36px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
line-height: 36px;
|
||||
color: $colorOlive;
|
||||
&:hover {
|
||||
color: #111;
|
||||
text-shadow: 0 0 10px red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-content {
|
||||
margin: 5px 0;
|
||||
|
||||
h3 {
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
> * {
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
}
|
||||
|
||||
.card-buttons {
|
||||
margin: 5px 0;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
line-height: 28px;
|
||||
text-align: center;
|
||||
border: 1px solid $colorTan;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: 12px;
|
||||
height: 24px;
|
||||
line-height: 20px;
|
||||
margin: 2px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
padding: 3px 0 0;
|
||||
border-top: 2px groove #FFF;
|
||||
|
||||
span {
|
||||
border-right: 2px groove #FFF;
|
||||
padding: 0 5px 0 0;
|
||||
font-size: 10px;
|
||||
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dice-roll .dice-total {
|
||||
&.success {
|
||||
color: inherit;
|
||||
background: #c7d0c0;
|
||||
border: 1px solid #006c00;
|
||||
}
|
||||
&.failure {
|
||||
color: inherit;
|
||||
background: #ffdddd;
|
||||
border: 1px solid #6e0000;
|
||||
}
|
||||
&.critical {
|
||||
color: green;
|
||||
}
|
||||
&.fumble {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
|
|
@ -28,10 +28,10 @@
|
|||
.health {
|
||||
&.armor-class {
|
||||
background: url('/systems/ose/assets/shield.png') no-repeat center;
|
||||
background-size: 90px;
|
||||
background-size: 70px;
|
||||
}
|
||||
margin: 10px 0;
|
||||
height: 90px;
|
||||
height: 70px;
|
||||
position: relative;
|
||||
input {
|
||||
font-size: 16px;
|
||||
|
|
@ -42,25 +42,25 @@
|
|||
border-bottom: none;
|
||||
position: absolute;
|
||||
font-size: 24px;
|
||||
top: 28px;
|
||||
top: 10px;
|
||||
width: 70px;
|
||||
left: calc(50% - 35px);
|
||||
}
|
||||
.health-bottom {
|
||||
border-bottom: none;
|
||||
position: absolute;
|
||||
bottom: 12px;
|
||||
bottom: 8px;
|
||||
width: 40px;
|
||||
right: calc(50% + -20px);
|
||||
}
|
||||
.health-empty {
|
||||
background: url('/systems/ose/assets/heart_empty.png') no-repeat center;
|
||||
background-size: 90px;
|
||||
background-size: 70px;
|
||||
background-position: top;
|
||||
}
|
||||
.health-full {
|
||||
background: url('/systems/ose/assets/heart_full.png') no-repeat center;
|
||||
background-size: 90px;
|
||||
background-size: 70px;
|
||||
background-position: bottom;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,10 @@
|
|||
},
|
||||
"thac0": {
|
||||
"value": 19,
|
||||
"mod": 0
|
||||
"mod": {
|
||||
"missile": 0,
|
||||
"melee": 0
|
||||
}
|
||||
},
|
||||
"saves": {
|
||||
"death": 10,
|
||||
|
|
@ -34,8 +37,7 @@
|
|||
"spell": 10
|
||||
},
|
||||
"movement": {
|
||||
"base": 0,
|
||||
"encounter": 0
|
||||
"base": 120
|
||||
}
|
||||
},
|
||||
"spellcaster": {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,28 @@
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{localize "OSE.MeleeBonus"}}</label>
|
||||
<div class="form-fields">
|
||||
<input
|
||||
type="text"
|
||||
name="data.thac0.mod.melee"
|
||||
id="melee"
|
||||
value="{{data.thac0.mod.melee}}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{localize "OSE.MissileBonus"}}</label>
|
||||
<div class="form-fields">
|
||||
<input
|
||||
type="text"
|
||||
name="data.thac0.mod.missile"
|
||||
id="missile"
|
||||
value="{{data.thac0.mod.missile}}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<footer class="sheet-footer">
|
||||
<button type="submit">
|
||||
|
|
|
|||
|
|
@ -1,49 +1,3 @@
|
|||
<section class="flexrow">
|
||||
<ul class="attributes flexrow">
|
||||
<li class="attribute">
|
||||
<h4 class="attribute-name box-title" title="{{ localize 'OSE.HitDice' }}">{{ localize "OSE.HitDiceShort" }}
|
||||
</h4>
|
||||
<div class="attribute-value">
|
||||
<input name="data.hp.hd" type="text" value="{{data.hp.hd}}" placeholder="0" data-dtype="String" />
|
||||
</div>
|
||||
</li>
|
||||
<li class="attribute">
|
||||
<h4 class="attribute-name box-title" title="{{ localize 'OSE.Thac0' }}">{{ localize "OSE.Thac0" }}</h4>
|
||||
<div class="attribute-value">
|
||||
<input name="data.thac0.value" type="text" value="{{data.thac0.value}}" placeholder="0"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
</li>
|
||||
{{#if config.individualInit}}
|
||||
<li class="attribute">
|
||||
<h4 class="attribute-name box-title" title="{{ localize 'OSE.Initiative' }}">
|
||||
{{ localize "OSE.InitiativeShort" }}</h4>
|
||||
<div class="attribute-value">
|
||||
<input name="data.initiative.value" type="text" value="{{data.initiative.value}}" placeholder="0"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if data.retainer.enabled}}
|
||||
<li class="attribute">
|
||||
<h4 class="attribute-name box-title" title="{{ localize 'OSE.Loyalty' }}">{{ localize "OSE.LoyaltyShort" }}
|
||||
</h4>
|
||||
<div class="attribute-value">
|
||||
<input name="data.retainer.loyalty" type="text" value="{{data.retainer.loyalty}}" placeholder="0"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
</li>
|
||||
{{/if}}
|
||||
<li class="attribute">
|
||||
<h4 class="attribute-name box-title" title="{{ localize 'OSE.Movement' }}">
|
||||
{{ localize "OSE.MovementShort" }}</h4>
|
||||
<div class="attribute-value">
|
||||
<input name="data.movement.value" type="text" value="{{data.movement.value}}" placeholder="0"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="flexrow">
|
||||
{{!-- Scores --}}
|
||||
<div class="attribute-group">
|
||||
|
|
@ -96,10 +50,22 @@
|
|||
data-dtype="Number" />
|
||||
<span class="attribute-mod">{{mods.cha}}</span>
|
||||
</li>
|
||||
{{#if data.retainer.enabled}}
|
||||
<li class="attribute">
|
||||
<h4 class="attribute-name box-title" title="{{ localize 'OSE.Loyalty' }}">
|
||||
{{ localize "OSE.LoyaltyShort" }}
|
||||
</h4>
|
||||
<div class="attribute-value">
|
||||
<input name="data.retainer.loyalty" type="text" value="{{data.retainer.loyalty}}" placeholder="0"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</div>
|
||||
{{!-- Resource Tracking --}}
|
||||
<div class="flex2">
|
||||
<div class="flexrow">
|
||||
<div class="health">
|
||||
<input class="health-top" name="data.hp.value" type="text" value="{{data.hp.value}}" data-dtype="Number"
|
||||
placeholder="0" title="{{localize 'OSE.Health'}}" />
|
||||
|
|
@ -110,16 +76,100 @@
|
|||
</div>
|
||||
<div class="health armor-class">
|
||||
{{#if config.ascendingAC}}
|
||||
<input class="health-top" name="data.aac.value" type="text" value="{{data.aac.value}}" data-dtype="Number"
|
||||
placeholder="0" title="{{localize 'OSE.ArmorClass'}}" />
|
||||
<input class="health-bottom" type="text" value="{{add 10 mods.dex}}" title="{{localize 'OSE.ArmorClass'}}" disabled/>
|
||||
<input class="health-top" name="data.aac.value" type="text" value="{{data.aac.value}}"
|
||||
data-dtype="Number" placeholder="0" title="{{localize 'OSE.ArmorClass'}}" />
|
||||
<input class="health-bottom" type="text" value="{{add 10 mods.dex}}"
|
||||
title="{{localize 'OSE.ArmorClass'}}" disabled />
|
||||
{{else}}
|
||||
<input class="health-top" name="data.ac.value" type="text" value="{{data.ac.value}}" data-dtype="Number"
|
||||
placeholder="0" title="{{localize 'OSE.ArmorClass'}}" />
|
||||
<input class="health-bottom" type="text" value="{{subtract 9 mods.dex}}" title="{{localize 'OSE.ArmorClass'}}" disabled/>
|
||||
<input class="health-bottom" type="text" value="{{subtract mods.dex 9}}"
|
||||
title="{{localize 'OSE.ArmorClass'}}" disabled />
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flexrow">
|
||||
<ul class="attributes flexrow">
|
||||
<li class="attribute">
|
||||
<h4 class="attribute-name box-title" title="{{ localize 'OSE.HitDice' }}">
|
||||
{{ localize "OSE.HitDiceShort" }}
|
||||
</h4>
|
||||
<div class="attribute-value">
|
||||
<input name="data.hp.hd" type="text" value="{{data.hp.hd}}" placeholder="0"
|
||||
data-dtype="String" />
|
||||
</div>
|
||||
</li>
|
||||
{{#if config.individualInit}}
|
||||
<li class="attribute">
|
||||
<h4 class="attribute-name box-title" title="{{ localize 'OSE.Initiative' }}">
|
||||
{{ localize "OSE.InitiativeShort" }}</h4>
|
||||
<div class="attribute-value">
|
||||
<input name="data.initiative.value" type="text" value="{{data.initiative.value}}"
|
||||
placeholder="0" data-dtype="Number" />
|
||||
</div>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flexrow">
|
||||
<ul class="attributes flexrow">
|
||||
<li class="attribute attribute-secondaries">
|
||||
<h4 class="attribute-name box-title" title="{{localize 'OSE.Melee'}}">{{localize 'OSE.MeleeShort'}}</h4>
|
||||
<div class="flexrow">
|
||||
<div class="attribute-value">
|
||||
{{subtract data.thac0.mod.melee (subtract mods.str data.thac0.value)}}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="attribute">
|
||||
<h4 class="attribute-name box-title" title="{{ localize 'OSE.Thac0' }}">{{ localize "OSE.Thac0" }}
|
||||
</h4>
|
||||
<div class="flexrow">
|
||||
<div class="attribute-value">
|
||||
<input name="data.thac0.value" type="text" value="{{data.thac0.value}}" placeholder="0"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="attribute attribute-secondaries">
|
||||
<h4 class="attribute-name box-title" title="{{localize 'OSE.Missile'}}">{{localize 'OSE.MissileShort'}}</h4>
|
||||
<div class="flexrow">
|
||||
<div class="attribute-value">
|
||||
{{subtract data.thac0.mod.missile (subtract mods.dex data.thac0.value)}}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flexrow">
|
||||
<ul class="attributes flexrow">
|
||||
<li class="attribute attribute-secondaries">
|
||||
<h4 class="attribute-name box-title" title="{{localize 'OSE.MovementEncounter'}}">{{localize 'OSE.MovementEncounterShort'}}</h4>
|
||||
<div class="flexrow">
|
||||
<div class="attribute-value">
|
||||
{{divide data.movement.base 3}}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="attribute">
|
||||
<h4 class="attribute-name box-title" title="{{ localize 'OSE.Movement' }}">
|
||||
{{ localize "OSE.MovementShort" }}</h4>
|
||||
<div class="attribute-value flexrow">
|
||||
<input name="data.movement.base" type="text" value="{{data.movement.base}}" placeholder="0"
|
||||
data-dtype="Number" />
|
||||
</div>
|
||||
</li>
|
||||
<li class="attribute attribute-secondaries">
|
||||
<h4 class="attribute-name box-title" title="{{localize 'OSE.MovementOverland'}}">{{localize 'OSE.MovementOverlandShort'}}</h4>
|
||||
<div class="flexrow">
|
||||
<div class="attribute-value">
|
||||
{{divide data.movement.base 5}}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{!-- Saving throws --}}
|
||||
<div class="attribute-group">
|
||||
<ul class="attributes">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
<div class="ose chat-card item-card" data-actor-id="{{actor._id}}" data-item-id="{{item._id}}"
|
||||
{{#if tokenId}}data-token-id="{{tokenId}}"{{/if}}>
|
||||
<header class="card-header flexrow">
|
||||
<img src="{{item.img}}" title="{{item.name}}" width="36" height="36"/>
|
||||
<h3 class="item-name">{{item.name}}</h3>
|
||||
</header>
|
||||
|
||||
<div class="card-content">
|
||||
{{{data.description}}}
|
||||
</div>
|
||||
|
||||
<div class="card-buttons">
|
||||
{{#if hasAttack}}<button data-action="attack">{{ localize "OSE.Attack" }}</button>{{/if}}
|
||||
|
||||
{{#if hasDamage}}
|
||||
<button data-action="damage">
|
||||
{{#if isHealing}}{{ localize "OSE.Healing" }}
|
||||
{{else}}{{localize "OSE.Damage" }}{{/if}}
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if hasSave}}
|
||||
<button data-action="save" data-ability="{{data.save.ability}}" disabled>
|
||||
{{ localize "OSE.SavingThrow" }} {{labels.save}}
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if data.formula}}
|
||||
<button data-action="formula">{{ localize "OSE.OtherFormula"}}</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<footer class="card-footer">
|
||||
{{#each data.properties}}
|
||||
<span>{{this}}</span>
|
||||
{{/each}}
|
||||
</footer>
|
||||
</div>
|
||||
Loading…
Reference in New Issue