Compare commits

..

2 commits

Author SHA1 Message Date
Carlos Fernandez
cff85b7899 Rename variable to dh-button-background 2026-05-13 20:54:17 -04:00
Carlos Fernandez
b2bda3e76c Implement new button styling 2026-05-13 06:31:04 -04:00
97 changed files with 584 additions and 1313 deletions

View file

@ -37,7 +37,6 @@ jobs:
url: https://github.com/${{github.repository}}
manifest: https://raw.githubusercontent.com/${{github.repository}}/v14/system.json
download: https://github.com/${{github.repository}}/releases/download/${{github.event.release.tag_name}}/system.zip
flags.hotReload: false
# Create a zip file with all files required by the module to add to the release
- run: zip -r ./system.zip system.json README.md LICENSE build/daggerheart.js build/tagify.css styles/daggerheart.css assets/ templates/ packs/ lang/

1
.gitignore vendored
View file

@ -6,4 +6,3 @@ Build
build
foundry
styles/daggerheart.css
styles/daggerheart.css.map

View file

@ -1,15 +1,9 @@
// Less configuration
var gulp = require('gulp');
var less = require('gulp-less');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('less', function (cb) {
gulp.src('styles/daggerheart.less')
.pipe(sourcemaps.init())
.pipe(less())
.on('error', console.error.bind(console))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('styles'));
gulp.src('styles/daggerheart.less').pipe(less()).on('error', console.error.bind(console)).pipe(gulp.dest('styles'));
cb();
});

View file

@ -406,11 +406,7 @@
"giveSpotlight": "Give The Spotlight",
"requestingSpotlight": "Requesting The Spotlight",
"requestSpotlight": "Request The Spotlight",
"openCountdowns": "Countdowns",
"adversaryCategories": {
"friendly": "Friendly",
"adversaries": "Adversaries"
}
"openCountdowns": "Countdowns"
},
"CompendiumBrowserSettings": {
"title": "Enable Compendiums",
@ -778,9 +774,7 @@
"title": "Group Roll"
},
"TokenConfig": {
"actorSizeUsed": "Actor size is set, determining the dimensions",
"tokenSize": "Token Size",
"sizeCategory": "Size Category"
"actorSizeUsed": "Actor size is set, determining the dimensions"
}
},
"CLASS": {
@ -2567,11 +2561,10 @@
"tokenImg": { "label": "Token Image" },
"tokenRingImg": { "label": "Subject Texture" },
"tokenSize": {
"placeholder": "Token Size",
"disabledPlaceholder": "Token Size",
"placeholder": "Using character dimensions",
"disabledPlaceholder": "Set by character size",
"height": { "label": "Height" },
"width": { "label": "Width" },
"depth": { "label": "Depth" },
"scale": { "label": "Token Scale" }
},
"evolved": {

View file

@ -50,7 +50,7 @@ export default class CompendiumBrowserSettings extends HandlebarsApplicationMixi
const excludedSourceData = this.browserSettings.excludedSources;
const excludedPackData = this.browserSettings.excludedPacks;
context.typePackCollections = game.packs.reduce((acc, pack) => {
const { type, label, packageType, packageName: basePackageName, name, id } = pack.metadata;
const { type, label, packageType, packageName: basePackageName, id } = pack.metadata;
if (!CompendiumBrowserSettings.#browserPackTypes.includes(type)) return acc;
const isWorldPack = packageType === 'world';
@ -68,15 +68,13 @@ export default class CompendiumBrowserSettings extends HandlebarsApplicationMixi
if (!acc[type].sources[packageName])
acc[type].sources[packageName] = { label: sourceLabel, checked: sourceChecked, packs: [] };
const included =
!excludedPackData[packageName] ||
!excludedPackData[packageName][name]?.excludedDocumentTypes.includes(type);
const checked = !excludedPackData[id] || !excludedPackData[id].excludedDocumentTypes.includes(type);
acc[type].sources[packageName].packs.push({
name,
pack: id,
type,
label: id === game.system.id ? game.system.title : game.i18n.localize(label),
checked: included
checked: checked
});
return acc;
@ -108,16 +106,16 @@ export default class CompendiumBrowserSettings extends HandlebarsApplicationMixi
toggleTypedPack(event) {
event.stopPropagation();
const { type, source, packName } = event.target.dataset;
const currentlyExcluded = this.browserSettings.excludedPacks[source]?.[packName]
? this.browserSettings.excludedPacks[source][packName].excludedDocumentTypes.includes(type)
const { type, pack } = event.target.dataset;
const currentlyExcluded = this.browserSettings.excludedPacks[pack]
? this.browserSettings.excludedPacks[pack].excludedDocumentTypes.includes(type)
: false;
this.browserSettings.excludedPacks[source] ??= {};
this.browserSettings.excludedPacks[source][packName] ??= { excludedDocumentTypes: [] };
this.browserSettings.excludedPacks[source][packName].excludedDocumentTypes = currentlyExcluded
? this.browserSettings.excludedPacks[source][packName].excludedDocumentTypes.filter(x => x !== type)
: [...(this.browserSettings.excludedPacks[source][packName]?.excludedDocumentTypes ?? []), type];
if (!this.browserSettings.excludedPacks[pack])
this.browserSettings.excludedPacks[pack] = { excludedDocumentTypes: [] };
this.browserSettings.excludedPacks[pack].excludedDocumentTypes = currentlyExcluded
? this.browserSettings.excludedPacks[pack].excludedDocumentTypes.filter(x => x !== type)
: [...(this.browserSettings.excludedPacks[pack]?.excludedDocumentTypes ?? []), type];
this.render();
}

View file

@ -57,7 +57,6 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
let returnMessage = game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.avoidScar');
if (config.roll.fate.value <= this.actor.system.levelData.level.current) {
const maxHope = this.actor.system.resources.hope.max + this.actor.system.scars;
const newScarAmount = this.actor.system.scars + 1;
await this.actor.update({
system: {
@ -65,7 +64,7 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
}
});
if (newScarAmount >= maxHope) {
if (newScarAmount >= this.actor.system.resources.hope.max) {
await this.actor.setDeathMoveDefeated(CONFIG.DH.GENERAL.defeatedConditionChoices.dead.id);
return game.i18n.format('DAGGERHEART.UI.Chat.deathMove.journeysEnd', { scars: newScarAmount });
}

View file

@ -38,9 +38,6 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
tag: 'form',
classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'tag-team-dialog'],
position: { width: 550, height: 'auto' },
window: {
icon: 'fa-solid fa-user-group'
},
actions: {
toggleSelectMember: TagTeamDialog.#toggleSelectMember,
startTagTeamRoll: TagTeamDialog.#startTagTeamRoll,

View file

@ -124,9 +124,7 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD {
const animationDuration = 500;
const scene = game.scenes.get(game.user.viewedScene);
/* getDependentTokens returns already removed tokens with id = null. Need to filter that until it's potentially fixed from Foundry */
const activeTokens = actors.flatMap(member =>
member.getDependentTokens({ scenes: scene }).filter(x => x._id && !x._destroyed)
);
const activeTokens = actors.flatMap(member => member.getDependentTokens({ scenes: scene }).filter(x => x._id));
const { x: actorX, y: actorY } = this.document;
if (activeTokens.length > 0) {
for (let token of activeTokens) {

View file

@ -156,7 +156,6 @@ export default class DhCharacterLevelUp extends LevelUpBase {
if (multiclasses?.[0]) {
const data = multiclasses[0];
const multiclass = data.data.length > 0 ? await foundry.utils.fromUuid(data.data[0]) : {};
const subclasses = (await multiclass?.system?.fetchSubclasses()) ?? [];
context.multiclass = {
...data,
@ -176,12 +175,13 @@ export default class DhCharacterLevelUp extends LevelUpBase {
alreadySelected
};
}) ?? [],
subclasses: subclasses.map(subclass => ({
...subclass,
uuid: subclass.uuid,
selected: data.secondaryData.subclass === subclass.uuid,
disabled: data.secondaryData.subclass && data.secondaryData.subclass !== subclass.uuid
})),
subclasses:
multiclass?.system?.subclasses.map(subclass => ({
...subclass,
uuid: subclass.uuid,
selected: data.secondaryData.subclass === subclass.uuid,
disabled: data.secondaryData.subclass && data.secondaryData.subclass !== subclass.uuid
})) ?? [],
compendium: 'classes',
limit: 1
};

View file

@ -1,5 +1,6 @@
import { DhHomebrew } from '../../data/settings/_module.mjs';
import { Resource } from '../../data/settings/Homebrew.mjs';
import { slugify } from '../../helpers/utils.mjs';
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
@ -402,12 +403,12 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
const domainName = button.form.elements.domainName.value;
if (!domainName) return;
const newSlug = domainName.slugify();
const newSlug = slugify(domainName);
const existingDomains = [
...Object.values(this.settings.domains),
...Object.values(CONFIG.DH.DOMAIN.domains)
];
if (existingDomains.find(x => x.id === newSlug)) {
if (existingDomains.find(x => slugify(game.i18n.localize(x.label)) === newSlug)) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.duplicateDomain'));
return;
}
@ -528,7 +529,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
const identifier = button.form.elements.identifier.value;
if (!identifier) return;
const sluggedIdentifier = identifier.slugify();
const sluggedIdentifier = slugify(identifier);
await this.settings.updateSource({
[`resources.${actorType}.resources.${sluggedIdentifier}`]: Resource.getDefaultResourceData(identifier)

View file

@ -57,14 +57,6 @@ export default class CharacterSheet extends DHBaseActorSheet {
}
],
contextMenus: [
{
handler: CharacterSheet.#getCreationMainContextOptions,
selector: '.character-details [data-action="editDoc"]',
options: {
parentClassHooks: false,
fixed: true
}
},
{
handler: CharacterSheet.#getDomainCardContextOptions,
selector: '[data-item-uuid][data-type="domainCard"]',
@ -327,56 +319,6 @@ export default class CharacterSheet extends DHBaseActorSheet {
/* Context Menu */
/* -------------------------------------------- */
static #getCreationMainContextOptions() {
/** Returns true if the item is managed by the level up wizard. Such items shouldn't allow things like manual removal */
function isItemWizardManaged(item) {
const actor = item?.actor;
if (!actor) return false;
// If levelup automation is off in general or for this character, all items are unmanaged
// This is disabled until we have proper granted feature removal, for now this feature is to correct errors
// const levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
// if (!levelupAuto) return false;
// Core items aren't part of levelup data. TODO: add some way to flag a specific character as no auto leveling
const classPair = actor.system.class;
const coreItems = [actor.system.ancestry, actor.system.community, classPair?.value, classPair?.subclass];
if (coreItems.includes(item)) return true;
const levelups = Object.values(actor.system.levelData?.levelups) ?? [];
const uuid = item.uuid;
const sourceUuid = item._stats.compendiumSource; // on older characters this may be missing
return levelups.some(data => {
if (item.type === 'subclass') {
const selectedSubclasses = data.selections.map(s => s.secondaryData?.subclass).filter(s => !!s);
return sourceUuid
? selectedSubclasses.includes(sourceUuid)
: selectedSubclasses.length && item.system.isMulticlass;
}
const matchesCard = data.achievements.domainCards.some(i => i.itemUuid === uuid);
const matchesSelection = data.selections.some(s => s.itemUuid === uuid);
return matchesCard || matchesSelection;
});
}
return [
{
label: 'CONTROLS.CommonDelete',
icon: 'fa-solid fa-trash',
visible: target => {
const doc = getDocFromElementSync(target);
return doc?.isOwner && !isItemWizardManaged(doc);
},
callback: async (target, event) => {
const doc = await getDocFromElement(target);
if (event.shiftKey) return doc.delete();
else return doc.deleteDialog();
}
}
];
}
/**
* Get the set of ContextMenu options for DomainCards.
* @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} - The Array of context options passed to the ContextMenu instance
@ -776,7 +718,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
? {
'system.linkedClass.uuid': {
key: 'system.linkedClass.uuid',
value: this.document.system.class.value?._stats.compendiumSource
value: this.document.system.class.value._stats.compendiumSource
}
}
: undefined,

View file

@ -26,6 +26,7 @@ export default class Party extends DHBaseActorSheet {
actions: {
openDocument: Party.#openDocument,
deletePartyMember: Party.#deletePartyMember,
deleteItem: Party.#deleteItem,
toggleHope: Party.#toggleHope,
toggleHitPoints: Party.#toggleHitPoints,
toggleStress: Party.#toggleStress,
@ -43,10 +44,7 @@ export default class Party extends DHBaseActorSheet {
static PARTS = {
header: { template: 'systems/daggerheart/templates/sheets/actors/party/header.hbs' },
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
partyMembers: {
template: 'systems/daggerheart/templates/sheets/actors/party/party-members.hbs',
scrollable: ['']
},
partyMembers: { template: 'systems/daggerheart/templates/sheets/actors/party/party-members.hbs' },
/* NOT YET IMPLEMENTED */
// projects: {
// template: 'systems/daggerheart/templates/sheets/actors/party/projects.hbs',
@ -508,4 +506,23 @@ export default class Party extends DHBaseActorSheet {
const newMembersList = currentMembers.filter(uuid => uuid !== doc.uuid);
await this.document.update({ 'system.partyMembers': newMembersList });
}
static async #deleteItem(event, target) {
const doc = await getDocFromElement(target.closest('.inventory-item'));
if (!event.shiftKey) {
const confirmed = await foundry.applications.api.DialogV2.confirm({
window: {
title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', {
type: game.i18n.localize('TYPES.Actor.party'),
name: doc.name
})
},
content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: doc.name })
});
if (!confirmed) return;
}
this.document.deleteEmbeddedDocuments('Item', [doc.id]);
}
}

View file

@ -89,7 +89,7 @@ export default function DHApplicationMixin(Base) {
classes: ['daggerheart', 'sheet', 'dh-style'],
actions: {
triggerContextMenu: DHSheetV2.#triggerContextMenu,
createDoc: DHSheetV2.#onCreateDoc,
createDoc: DHSheetV2.#createDoc,
editDoc: DHSheetV2.#editDoc,
deleteDoc: DHSheetV2.#deleteDoc,
toChat: DHSheetV2.#toChat,
@ -97,8 +97,8 @@ export default function DHApplicationMixin(Base) {
viewItem: DHSheetV2.#viewItem,
toggleEffect: DHSheetV2.#toggleEffect,
toggleExtended: DHSheetV2.#toggleExtended,
addNewItem: DHSheetV2.#onAddNewItem,
browseItem: DHSheetV2.#onBrowseItem,
addNewItem: DHSheetV2.#addNewItem,
browseItem: DHSheetV2.#browseItem,
editAttribution: DHSheetV2.#editAttribution
},
contextMenus: [
@ -639,7 +639,7 @@ export default function DHApplicationMixin(Base) {
/* Application Clicks Actions */
/* -------------------------------------------- */
static async #onAddNewItem(event, target) {
static async #addNewItem(event, target) {
const createChoice = await foundry.applications.api.DialogV2.wait({
classes: ['dh-style', 'two-big-buttons'],
buttons: [
@ -658,11 +658,11 @@ export default function DHApplicationMixin(Base) {
if (!createChoice) return;
if (createChoice === 'browse') return DHSheetV2.#onBrowseItem.call(this, event, target);
else return DHSheetV2.#onCreateDoc.call(this, event, target);
if (createChoice === 'browse') return DHSheetV2.#browseItem.call(this, event, target);
else return DHSheetV2.#createDoc.call(this, event, target);
}
static async #onBrowseItem(_event, target) {
static async #browseItem(event, target) {
const type = target.dataset.compendium ?? target.dataset.type;
const presets = {
@ -713,7 +713,7 @@ export default function DHApplicationMixin(Base) {
* Create an embedded document.
* @type {ApplicationClickAction}
*/
static async #onCreateDoc(event, target) {
static async #createDoc(event, target) {
const { documentClass, type, inVault, disabled } = target.dataset;
const parentIsItem = this.document.documentName === 'Item';
const featureOnCharacter = this.document.parent?.type === 'character' && type === 'feature';
@ -725,7 +725,7 @@ export default function DHApplicationMixin(Base) {
: null
: this.document;
let systemData = {};
let systemData = null;
if (featureOnCharacter) {
systemData = {
originItemType: this.document.type,
@ -738,18 +738,15 @@ export default function DHApplicationMixin(Base) {
const data = {
name: cls.defaultName({ type, parent }),
type,
system: systemData
type
};
if (disabled) data.disabled = true;
if (type === 'domainCard') {
if (parent?.system.domains?.length) data.system.domain = parent.system.domains[0];
if (inVault) data.system.inVault = true;
} else if (type === 'weapon') {
// Passing an empty system object to weapon causes validation failure due to attack action initialization
// todo: determine why, fix it at its source, then remove this fallback
delete data.system;
if (systemData) data.system = systemData;
if (inVault) data['system.inVault'] = true;
if (disabled) data.disabled = true;
if (type === 'domainCard' && parent?.system.domains?.length) {
data.system.domain = parent.system.domains[0];
}
const doc = await cls.create(data, { parent, renderSheet: !event.shiftKey });

View file

@ -56,9 +56,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
async _prepareTrackerContext(context, options) {
await super._prepareTrackerContext(context, options);
const npcs = context.turns?.filter(x => x.isNPC) ?? [];
const adversaries = npcs.filter(x => x.disposition !== CONST.TOKEN_DISPOSITIONS.FRIENDLY);
const friendlies = npcs.filter(x => x.disposition === CONST.TOKEN_DISPOSITIONS.FRIENDLY);
const adversaries = context.turns?.filter(x => x.isNPC) ?? [];
const characters = context.turns?.filter(x => !x.isNPC) ?? [];
const spotlightQueueEnabled = game.settings.get(
CONFIG.DH.id,
@ -77,7 +75,6 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
Object.assign(context, {
actionTokens: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).actionTokens,
adversaries,
friendlies,
allCharacters: characters,
characters: characters.filter(x => !spotlightQueueEnabled || x.system.spotlight.requestOrderIndex == 0),
spotlightRequests
@ -132,8 +129,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
active: index === combat.turn,
canPing: combatant.sceneId === canvas.scene?.id && game.user.hasPermission('PING_CANVAS'),
type: combatant.actor?.system?.type,
img: await this._getCombatantThumbnail(combatant),
disposition: combatant.token.disposition
img: await this._getCombatantThumbnail(combatant)
};
turn.css = [turn.active ? 'active' : null, hidden ? 'hide' : null, isDefeated ? 'defeated' : null].filterJoin(

View file

@ -21,10 +21,10 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
static DEFAULT_OPTIONS = {
id: 'countdowns',
tag: 'div',
classes: ['daggerheart', 'dh-style', 'countdowns'],
classes: ['daggerheart', 'dh-style', 'countdowns', 'faded-ui'],
window: {
icon: 'fa-solid fa-clock-rotate-left',
frame: false,
frame: true,
title: 'DAGGERHEART.UI.Countdowns.title',
positioned: false,
resizable: false,
@ -62,6 +62,20 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
if (iconOnly) frame.classList.add('icon-only');
else frame.classList.remove('icon-only');
const header = frame.querySelector('.window-header');
header.querySelector('button[data-action="close"]').remove();
header.querySelector('button[data-action="toggleControls"]').remove();
if (game.user.isGM) {
const editTooltip = game.i18n.localize('DAGGERHEART.APPLICATIONS.CountdownEdit.editTitle');
const editButton = `<a style="margin-right: 8px;" class="header-control" data-tooltip="${editTooltip}" aria-label="${editTooltip}" data-action="editCountdowns"><i class="fa-solid fa-wrench"></i></a>`;
header.insertAdjacentHTML('beforeEnd', editButton);
}
const minimizeTooltip = game.i18n.localize('DAGGERHEART.UI.Countdowns.toggleIconMode');
const minimizeButton = `<a class="header-control" data-tooltip="${minimizeTooltip}" aria-label="${minimizeTooltip}" data-action="toggleViewMode"><i class="fa-solid fa-down-left-and-up-right-to-center"></i></a>`;
header.insertAdjacentHTML('beforeEnd', minimizeButton);
return frame;
}

View file

@ -109,8 +109,8 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
CONFIG.DH.id,
CONFIG.DH.FLAGS[`${this.compendiumBrowserTypeKey}`].position
);
options.position = userPresetPosition ?? ItemBrowser.DEFAULT_OPTIONS.position;
delete options.position.zIndex;
if (!userPresetPosition) {
const width = noFolder === true || lite === true ? 600 : 850;

View file

@ -249,6 +249,9 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token {
/** @inheritDoc */
_drawBar(number, bar, data) {
const val = Number(data.value);
const pct = Math.clamp(val, 0, data.max) / data.max;
// Determine sizing
const { width, height } = this.document.getSize();
const s = canvas.dimensions.uiScale;
@ -256,19 +259,17 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token {
const bh = 8 * (this.document.height >= 2 ? 1.5 : 1) * s;
// Determine the color to use
const Color = foundry.utils.Color;
const fillColor = number === 0 ? Color.fromRGB([1, 0, 0]) : Color.fromString('#0032b1');
const emptyColor = Color.fromRGB([0, 0, 0]);
const fillColor =
number === 0 ? foundry.utils.Color.fromRGB([1, 0, 0]) : foundry.utils.Color.fromString('#0032b1');
// Draw the bar (accounting floating point numbers from bar animations)
const widthUnit = bw / Math.ceil(data.max);
// Draw the bar
const widthUnit = bw / data.max;
bar.clear().lineStyle(s, 0x000000, 1.0);
const sections = [...Array(Math.ceil(data.max)).keys()];
for (const mark of sections) {
const sections = [...Array(data.max).keys()];
for (let mark of sections) {
const x = mark * widthUnit;
const marked = mark < Math.ceil(data.value);
const remainder = mark === Math.ceil(data.value) - 1 ? data.value % 1 : 0;
const color = !marked ? emptyColor : remainder ? emptyColor.mix(fillColor, remainder) : fillColor;
const marked = mark + 1 <= data.value;
const color = marked ? fillColor : foundry.utils.Color.fromRGB([0, 0, 0]);
if (mark === 0 || mark === sections.length - 1) {
bar.beginFill(color, marked ? 1.0 : 0.5).drawRect(x, 0, widthUnit, bh, 2 * s); // Would like drawRoundedRect, but it's very troublsome with the corners. Leaving for now.
} else {

View file

@ -70,49 +70,6 @@ export const typeConfig = {
}
]
},
environments: {
columns: [
{
key: 'system.tier',
label: 'DAGGERHEART.GENERAL.Tiers.singular'
},
{
key: 'system.type',
label: 'DAGGERHEART.GENERAL.type',
format: type => {
if (!type) return '-';
return CONFIG.DH.ACTOR.environmentTypes[type].label;
}
}
],
filters: [
{
key: 'system.tier',
label: 'DAGGERHEART.GENERAL.Tiers.singular',
field: 'system.api.models.actors.DhEnvironment.schema.fields.tier'
},
{
key: 'system.type',
label: 'DAGGERHEART.GENERAL.type',
field: 'system.api.models.actors.DhEnvironment.schema.fields.type'
},
{
key: 'system.difficulty',
name: 'difficulty.min',
label: 'DAGGERHEART.UI.ItemBrowser.difficultyMin',
field: 'system.api.models.actors.DhEnvironment.schema.fields.difficulty',
operator: 'gte'
},
{
key: 'system.difficulty',
name: 'difficulty.max',
label: 'DAGGERHEART.UI.ItemBrowser.difficultyMax',
field: 'system.api.models.actors.DhEnvironment.schema.fields.difficulty',
operator: 'lte'
}
]
},
items: {
columns: [
{
@ -443,12 +400,10 @@ export const typeConfig = {
const list = [];
for (const item of items.filter(item => item.system.linkedClass)) {
const linkedClass = await foundry.utils.fromUuid(item.system.linkedClass);
if (linkedClass) {
list.push({
value: linkedClass.uuid,
label: linkedClass.name
});
}
list.push({
value: linkedClass.uuid,
label: linkedClass.name
});
}
return list.reduce((a, c) => {
@ -604,8 +559,7 @@ export const compendiumConfig = {
id: 'environments',
keys: ['environments'],
label: 'DAGGERHEART.UI.ItemBrowser.folders.environments',
type: ['environment'],
listType: 'environments'
type: ['environment']
},
beastforms: {
id: 'beastforms',

View file

@ -35,7 +35,6 @@ export default class BeastformEffect extends BaseEffect {
static migrateData(source) {
if (!source.characterTokenData.tokenSize.height) source.characterTokenData.tokenSize.height = 1;
if (!source.characterTokenData.tokenSize.width) source.characterTokenData.tokenSize.width = 1;
if (!source.characterTokenData.tokenSize.depth) source.characterTokenData.tokenSize.depth = 1;
return super.migrateData(source);
}
@ -53,8 +52,7 @@ export default class BeastformEffect extends BaseEffect {
if (this.parent.parent.type === 'character') {
const baseUpdate = {
height: this.characterTokenData.tokenSize.height,
width: this.characterTokenData.tokenSize.width,
depth: this.characterTokenData.tokenSize.depth
width: this.characterTokenData.tokenSize.width
};
const update = {
...baseUpdate,

View file

@ -577,8 +577,6 @@ export default class DhCharacter extends DhCreature {
communityFeatures = [],
classFeatures = [],
subclassFeatures = [],
multiclassFeatures = [],
multiclassSubclassFeatures = [],
companionFeatures = [],
features = [];
@ -588,9 +586,9 @@ export default class DhCharacter extends DhCreature {
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.community.id) {
communityFeatures.push(item);
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.class.id) {
(item.system.multiclassOrigin ? multiclassFeatures : classFeatures).push(item);
classFeatures.push(item);
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.subclass.id) {
(item.system.multiclassOrigin ? multiclassSubclassFeatures : subclassFeatures).push(item);
subclassFeatures.push(item);
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.companion.id) {
companionFeatures.push(item);
} else if (item.type === 'feature' && !item.system.type) {
@ -619,24 +617,6 @@ export default class DhCharacter extends DhCreature {
type: 'subclass',
values: subclassFeatures
},
...(multiclassFeatures.length
? {
multiclassFeatures: {
title: `${game.i18n.localize('DAGGERHEART.GENERAL.multiclass')} - ${this.multiclass.value?.name}`,
type: 'multiclass',
values: multiclassFeatures
}
}
: {}),
...(multiclassSubclassFeatures.length
? {
multiclassSubclassFeatures: {
title: `${game.i18n.localize('DAGGERHEART.GENERAL.multiclass')} ${game.i18n.localize('TYPES.Item.subclass')} - ${this.multiclass.subclass?.name}`,
type: 'multiclassSubclass',
values: multiclassSubclassFeatures
}
}
: {}),
companionFeatures: {
title: game.i18n.localize('DAGGERHEART.ACTORS.Character.companionFeatures'),
type: 'companion',
@ -860,13 +840,12 @@ export default class DhCharacter extends DhCreature {
const newHopeMax = this.resources.hope.max + diff;
const newHopeValue = Math.min(newHopeMax, this.resources.hope.value);
if (newHopeValue != this.resources.hope.value) {
changes.system = foundry.utils.mergeObject(changes.system ?? {}, {
resources: {
hope: {
value: (changes.system?.resources?.hope?.value ?? 0) + newHopeMax
}
}
});
if (!changes.system.resources.hope) changes.system.resources.hope = { value: 0 };
changes.system.resources.hope = {
...changes.system.resources.hope,
value: changes.system.resources.hope.value + newHopeValue
};
}
}

View file

@ -11,13 +11,11 @@ export default class CompendiumBrowserSettings extends foundry.abstract.DataMode
})
),
excludedPacks: new fields.TypedObjectField(
new fields.TypedObjectField(
new fields.SchemaField({
excludedDocumentTypes: new fields.ArrayField(
new fields.StringField({ required: true, choices: CONST.SYSTEM_SPECIFIC_COMPENDIUM_TYPES })
)
})
)
new fields.SchemaField({
excludedDocumentTypes: new fields.ArrayField(
new fields.StringField({ required: true, choices: CONST.SYSTEM_SPECIFIC_COMPENDIUM_TYPES })
)
})
)
};
}
@ -30,7 +28,7 @@ export default class CompendiumBrowserSettings extends foundry.abstract.DataMode
const excludedSourceData = this.excludedSources[packageName];
if (excludedSourceData && excludedSourceData.excludedDocumentTypes.includes(pack.metadata.type)) return true;
const excludedPackData = this.excludedPacks[packageName]?.[pack.metadata.name];
const excludedPackData = this.excludedPacks[item.pack];
if (excludedPackData && excludedPackData.excludedDocumentTypes.includes(pack.metadata.type)) return true;
return false;

View file

@ -141,6 +141,16 @@ export default class DHArmor extends AttachableItem {
}
}
_onUpdate(a, b, c) {
super._onUpdate(a, b, c);
if (this.actor?.type === 'character') {
for (const party of this.actor.parties) {
party.render();
}
}
}
/** @inheritDoc */
static migrateDocumentData(source) {
if (!source.system.armor) {

View file

@ -51,8 +51,7 @@ export default class DHBeastform extends BaseDataItem {
}),
scale: new fields.NumberField({ nullable: false, min: 0.2, max: 3, step: 0.05, initial: 1 }),
height: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }),
width: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }),
depth: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true })
width: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true })
}),
mainTrait: new fields.StringField({
required: true,
@ -193,8 +192,7 @@ export default class DHBeastform extends BaseDataItem {
tokenSize: {
scale: this.parent.parent.prototypeToken.texture.scaleX,
height: this.parent.parent.prototypeToken.height,
width: this.parent.parent.prototypeToken.width,
depth: this.parent.parent.prototypeToken.depth
width: this.parent.parent.prototypeToken.width
}
},
advantageOn: this.advantageOn,
@ -213,12 +211,10 @@ export default class DHBeastform extends BaseDataItem {
: null;
const width = autoTokenSize ?? this.tokenSize.width;
const height = autoTokenSize ?? this.tokenSize.height;
const depth = autoTokenSize ?? this.tokenSize.depth;
const prototypeTokenUpdate = {
height,
width,
depth,
texture: {
src: this.tokenImg,
scaleX: this.tokenSize.scale,

View file

@ -56,30 +56,38 @@ export default class DHSubclass extends BaseDataItem {
if (allowed === false) return;
if (this.actor?.type === 'character') {
const { value: actorClass, subclass: existingSubclass } = this.actor.system.class;
const { value: multiclass, subclass: existingMultisubclass } = this.actor.system.multiclass;
if (!actorClass && !multiclass) {
ui.notifications.warn('DAGGERHEART.UI.Notifications.missingClass', { localize: true });
return false;
}
if (existingSubclass && existingMultisubclass) {
ui.notifications.warn('DAGGERHEART.UI.Notifications.subclassesAlreadyPresent', { localize: true });
return false;
}
if (existingSubclass && !multiclass) {
ui.notifications.warn('DAGGERHEART.UI.Notifications.missingMulticlass', { localize: true });
return false;
}
const dataUuid = data.uuid ?? data._stats.compendiumSource ?? `Item.${data._id}`;
if (this.actor.system.class.subclass) {
if (this.actor.system.multiclass.subclass) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.subclassesAlreadyPresent'));
return false;
} else {
const multiclass = this.actor.items.find(x => x.type === 'class' && x.system.isMulticlass);
if (!multiclass) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.missingMulticlass'));
return false;
}
const match = [multiclass, actorClass].find(
c => c && (c._stats.compendiumSource ?? c.uuid) === this.linkedClass
);
if (!match) {
const key = multiclass ? 'subclassNotInMulticlass' : 'subclassNotInClass';
ui.notifications.warn(`DAGGERHEART.UI.Notifications.${key}`, { localize: true });
return false;
} else if (match.system.isMulticlass) {
await this.updateSource({ isMulticlass: true });
if (multiclass.system.subclasses.every(x => x.uuid !== dataUuid)) {
ui.notifications.error(
game.i18n.localize('DAGGERHEART.UI.Notifications.subclassNotInMulticlass')
);
return false;
}
await this.updateSource({ isMulticlass: true });
}
} else {
const actorClass = this.actor.items.find(x => x.type === 'class' && !x.system.isMulticlass);
if (!actorClass) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.missingClass'));
return false;
}
if ((await actorClass.system.fetchSubclasses()).every(x => x.uuid !== dataUuid)) {
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.subclassNotInClass'));
return false;
}
}
}
}

View file

@ -112,22 +112,10 @@ export default class DhpActor extends Actor {
this.updateSource(update);
}
/** Perform a render, debounced in order to prevent overloading repeat render requests */
renderDebounced = foundry.utils.debounce(options => {
return this.render(options);
}, 10);
_onUpdateDescendantDocuments(parent, collection, documents, changes, options, userId) {
super._onUpdateDescendantDocuments(parent, collection, documents, changes, options, userId);
for (const party of this.parties) {
party.renderDebounced({ parts: ['partyMembers'] });
}
}
_onUpdate(changes, options, userId) {
super._onUpdate(changes, options, userId);
for (const party of this.parties) {
party.renderDebounced({ parts: ['partyMembers'] });
party.render({ parts: ['partyMembers'] });
}
}
@ -146,20 +134,17 @@ export default class DhpActor extends Actor {
_onDelete(options, userId) {
super._onDelete(options, userId);
for (const party of this.parties) {
party.renderDebounced({ parts: ['partyMembers'] });
party.render({ parts: ['partyMembers'] });
}
}
async updateLevel(newLevel) {
if (!['character', 'companion'].includes(this.type) || newLevel === this.system.levelData.level.changed) return;
const tiers = Object.values(game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers);
const maxLevel = tiers.reduce((acc, tier) => Math.max(acc, tier.levels.end), 0);
const multiclassMinLevel = Math.min(
maxLevel,
...tiers.filter(t => t.options.multiclass).map(t => t.levels.start)
);
if (newLevel > this.system.levelData.level.current) {
const maxLevel = Object.values(
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers
).reduce((acc, tier) => Math.max(acc, tier.levels.end), 0);
if (newLevel > maxLevel) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.tooHighLevel'));
}
@ -234,19 +219,18 @@ export default class DhpActor extends Actor {
this.system.multiclass.subclass.update({ 'system.featureState': subclassFeatureState.multiclass });
}
// Remove multiclass if we're removing a multiclass feature or if we're below the multiclass minimum level
// Multclasses cannot be manually removed on the sheet, so this allows recovering in the case of errors
if (multiclass || newLevel < multiclassMinLevel) {
const multiclassItems = this.items.filter(
x =>
x.uuid === multiclass?.itemUuid ||
x.system.isMulticlass ||
(['class', 'subclass'].includes(x.system.originItemType) && x.system.multiclassOrigin)
if (multiclass) {
const multiclassItem = this.items.find(x => x.uuid === multiclass.itemUuid);
const multiclassFeatures = this.items.filter(
x => x.system.originItemType === 'class' && x.system.multiclassOrigin
);
const subclassFeatures = this.items.filter(
x => x.system.originItemType === 'subclass' && x.system.multiclassOrigin
);
this.deleteEmbeddedDocuments(
'Item',
multiclassItems.map(x => x.id)
[multiclassItem, ...multiclassFeatures, ...subclassFeatures].map(x => x.id)
);
this.update({
@ -285,7 +269,6 @@ export default class DhpActor extends Actor {
async levelUp(levelupData) {
const levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
const getStatsWithSource = document => ({ ...(document._stats ?? {}), compendiumSource: document.uuid });
const levelups = {};
for (var levelKey of Object.keys(levelupData)) {
@ -398,8 +381,8 @@ export default class DhpActor extends Actor {
const embeddedItem = await this.createEmbeddedDocuments('Item', [
{
...multiclassData,
uuid: multiclassItem.uuid, // todo: replace with setting an id and using keepId
_stats: getStatsWithSource(multiclassItem),
uuid: multiclassItem.uuid,
_stats: multiclassItem._stats,
system: {
...multiclassData.system,
features: multiclassData.system.features.filter(x => x.type !== 'hope'),
@ -412,8 +395,8 @@ export default class DhpActor extends Actor {
await this.createEmbeddedDocuments('Item', [
{
...subclassData,
uuid: subclassItem.uuid, // todo: replace with setting an id and using keepId
_stats: getStatsWithSource(subclassItem),
uuid: subclassItem.uuid,
_stats: subclassItem._stats,
system: {
...subclassData.system,
isMulticlass: true
@ -433,8 +416,8 @@ export default class DhpActor extends Actor {
const embeddedItem = await this.createEmbeddedDocuments('Item', [
{
...cardData,
uuid: cardItem.uuid, // todo: replace with setting an id and using keepId
_stats: getStatsWithSource(cardItem),
uuid: cardItem.uuid,
_stats: cardItem._stats,
system: {
...cardData.system,
inVault: true
@ -455,7 +438,8 @@ export default class DhpActor extends Actor {
const embeddedItem = await this.createEmbeddedDocuments('Item', [
{
...cardData,
_stats: getStatsWithSource(cardItem),
uuid: cardItem.uuid,
_stats: cardItem._stats,
system: {
...cardData.system,
inVault: true

View file

@ -20,7 +20,7 @@ export default class DhScene extends Scene {
const prototype = tokenDoc.actor?.prototypeToken ?? tokenDoc;
this.#sizeSyncBatch.set(tokenDoc.id, {
size: tokenSize,
prototypeSize: { width: prototype.width, height: prototype.height, depth: prototype.depth },
prototypeSize: { width: prototype.width, height: prototype.height },
position: { x: tokenDoc.x, y: tokenDoc.y, elevation: tokenDoc.elevation }
});
this.#processSyncBatch();
@ -36,13 +36,11 @@ export default class DhScene extends Scene {
const tokenSize = tokenSizes[size];
const width = size !== CONFIG.DH.ACTOR.tokenSize.custom.id ? tokenSize : prototypeSize.width;
const height = size !== CONFIG.DH.ACTOR.tokenSize.custom.id ? tokenSize : prototypeSize.height;
const depth = size !== CONFIG.DH.ACTOR.tokenSize.custom.id ? tokenSize : prototypeSize.depth;
const updatedPosition = DHToken.getSnappedPositionInSquareGrid(this.grid, position, width, height);
return {
_id,
width,
height,
depth,
...updatedPosition
};
});

View file

@ -66,8 +66,7 @@ export default class DHToken extends CONFIG.Token.documentClass {
if (tokenSize && actor.system.size !== CONFIG.DH.ACTOR.tokenSize.custom.id) {
document.updateSource({
width: tokenSize,
height: tokenSize,
depth: tokenSize
height: tokenSize
});
}
}
@ -91,7 +90,7 @@ export default class DHToken extends CONFIG.Token.documentClass {
) {
const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes;
const tokenSize = tokenSizes[update.system.size];
if (tokenSize !== this.width || tokenSize !== this.height || tokenSize !== this.depth) {
if (tokenSize !== this.width || tokenSize !== this.height) {
this.parent?.syncTokenDimensions(this, update.system.size);
}
}

View file

@ -15,7 +15,6 @@ export default class DhTokenManager {
if (tokenSize && actor.system.size !== CONFIG.DH.ACTOR.tokenSize.custom.id) {
tokenData.width = tokenSize;
tokenData.height = tokenSize;
tokenData.depth = tokenSize;
}
}

View file

@ -350,9 +350,7 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
async getBattlepointHTML(combatId) {
const combat = game.combats.get(combatId);
const adversaries =
combat.turns
?.filter(x => x.actor?.isNPC && x.token.disposition === CONST.TOKEN_DISPOSITIONS.HOSTILE)
?.map(x => ({ ...x.actor, type: x.actor.system.type })) ?? [];
combat.turns?.filter(x => x.actor?.isNPC)?.map(x => ({ ...x.actor, type: x.actor.system.type })) ?? [];
const characters = combat.turns?.filter(x => !x.isNPC && x.actor) ?? [];
const nrCharacters = characters.length;

View file

@ -449,9 +449,14 @@ export async function createEmbeddedItemsWithEffects(actor, baseData) {
effects: data.effects?.map(effect => effect.toObject())
});
}
await actor.createEmbeddedDocuments('Item', effectData);
}
export const slugify = name => {
return name.toLowerCase().replaceAll(' ', '-').replaceAll('.', '');
};
export function shuffleArray(array) {
let currentIndex = array.length;
while (currentIndex != 0) {

477
package-lock.json generated
View file

@ -9,7 +9,6 @@
"autocompleter": "^9.3.2",
"gulp": "^5.0.0",
"gulp-less": "^5.0.0",
"gulp-sourcemaps": "^3.0.0",
"rollup": "^4.40.0"
},
"devDependencies": {
@ -203,132 +202,6 @@
"node": ">17.0.0"
}
},
"node_modules/@gulp-sourcemaps/identity-map": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz",
"integrity": "sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q==",
"license": "MIT",
"dependencies": {
"acorn": "^6.4.1",
"normalize-path": "^3.0.0",
"postcss": "^7.0.16",
"source-map": "^0.6.0",
"through2": "^3.0.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/@gulp-sourcemaps/identity-map/node_modules/acorn": {
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
"integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/@gulp-sourcemaps/identity-map/node_modules/picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
"license": "ISC"
},
"node_modules/@gulp-sourcemaps/identity-map/node_modules/postcss": {
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"license": "MIT",
"dependencies": {
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
},
"engines": {
"node": ">=6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
}
},
"node_modules/@gulp-sourcemaps/identity-map/node_modules/through2": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
"integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.4",
"readable-stream": "2 || 3"
}
},
"node_modules/@gulp-sourcemaps/map-sources": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz",
"integrity": "sha512-o/EatdaGt8+x2qpb0vFLC/2Gug/xYPRXb6a+ET1wGYKozKN3krDWC/zZFZAtrzxJHuDL12mwdfEFKcKMNvc55A==",
"license": "MIT",
"dependencies": {
"normalize-path": "^2.0.1",
"through2": "^2.0.3"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/@gulp-sourcemaps/map-sources/node_modules/normalize-path": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
"integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
"license": "MIT",
"dependencies": {
"remove-trailing-separator": "^1.0.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@gulp-sourcemaps/map-sources/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/@gulp-sourcemaps/map-sources/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/@gulp-sourcemaps/map-sources/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/@gulp-sourcemaps/map-sources/node_modules/through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
"license": "MIT",
"dependencies": {
"readable-stream": "~2.3.6",
"xtend": "~4.0.1"
}
},
"node_modules/@gulpjs/messages": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz",
@ -1021,18 +894,6 @@
"node": ">= 10.13.0"
}
},
"node_modules/atob": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
"license": "(MIT OR Apache-2.0)",
"bin": {
"atob": "bin/atob.js"
},
"engines": {
"node": ">= 4.5.0"
}
},
"node_modules/autocompleter": {
"version": "9.3.2",
"resolved": "https://registry.npmjs.org/autocompleter/-/autocompleter-9.3.2.tgz",
@ -1621,12 +1482,6 @@
"node": ">= 10.13.0"
}
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@ -1641,17 +1496,6 @@
"node": ">= 8"
}
},
"node_modules/css": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz",
"integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.4",
"source-map": "^0.6.1",
"source-map-resolve": "^0.6.0"
}
},
"node_modules/css-declaration-sorter": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz",
@ -1823,19 +1667,6 @@
"node": ">=8.0.0"
}
},
"node_modules/d": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
"integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
"license": "ISC",
"dependencies": {
"es5-ext": "^0.10.64",
"type": "^2.7.2"
},
"engines": {
"node": ">=0.12"
}
},
"node_modules/date-fns": {
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
@ -1869,35 +1700,6 @@
}
}
},
"node_modules/debug-fabulous": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz",
"integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==",
"license": "MIT",
"dependencies": {
"debug": "3.X",
"memoizee": "0.4.X",
"object-assign": "4.X"
}
},
"node_modules/debug-fabulous/node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.1"
}
},
"node_modules/decode-uri-component": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
"license": "MIT",
"engines": {
"node": ">=0.10"
}
},
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@ -1939,15 +1741,6 @@
"node": ">=0.10.0"
}
},
"node_modules/detect-newline": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
"integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/dom-serializer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
@ -2112,58 +1905,6 @@
"node": ">= 0.4"
}
},
"node_modules/es5-ext": {
"version": "0.10.64",
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
"integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
"hasInstallScript": true,
"license": "ISC",
"dependencies": {
"es6-iterator": "^2.0.3",
"es6-symbol": "^3.1.3",
"esniff": "^2.0.1",
"next-tick": "^1.1.0"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/es6-iterator": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
"integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
"license": "MIT",
"dependencies": {
"d": "1",
"es5-ext": "^0.10.35",
"es6-symbol": "^3.1.1"
}
},
"node_modules/es6-symbol": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
"integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
"license": "ISC",
"dependencies": {
"d": "^1.0.2",
"ext": "^1.7.0"
},
"engines": {
"node": ">=0.12"
}
},
"node_modules/es6-weak-map": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
"integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
"license": "ISC",
"dependencies": {
"d": "1",
"es5-ext": "^0.10.46",
"es6-iterator": "^2.0.3",
"es6-symbol": "^3.1.1"
}
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@ -2365,21 +2106,6 @@
"node": ">=6"
}
},
"node_modules/esniff": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
"integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
"license": "ISC",
"dependencies": {
"d": "^1.0.1",
"es5-ext": "^0.10.62",
"event-emitter": "^0.3.5",
"type": "^2.7.2"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/espree": {
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz",
@ -2450,16 +2176,6 @@
"node": ">=0.10.0"
}
},
"node_modules/event-emitter": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
"integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
"license": "MIT",
"dependencies": {
"d": "1",
"es5-ext": "~0.10.14"
}
},
"node_modules/eventemitter3": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
@ -2478,15 +2194,6 @@
"node": ">=0.10.0"
}
},
"node_modules/ext": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
"integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
"license": "ISC",
"dependencies": {
"type": "^2.7.2"
}
},
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@ -3113,86 +2820,6 @@
"node": ">=6"
}
},
"node_modules/gulp-sourcemaps": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-3.0.0.tgz",
"integrity": "sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ==",
"license": "ISC",
"dependencies": {
"@gulp-sourcemaps/identity-map": "^2.0.1",
"@gulp-sourcemaps/map-sources": "^1.0.0",
"acorn": "^6.4.1",
"convert-source-map": "^1.0.0",
"css": "^3.0.0",
"debug-fabulous": "^1.0.0",
"detect-newline": "^2.0.0",
"graceful-fs": "^4.0.0",
"source-map": "^0.6.0",
"strip-bom-string": "^1.0.0",
"through2": "^2.0.0"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/gulp-sourcemaps/node_modules/acorn": {
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
"integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/gulp-sourcemaps/node_modules/convert-source-map": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"license": "MIT"
},
"node_modules/gulp-sourcemaps/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/gulp-sourcemaps/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/gulp-sourcemaps/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/gulp-sourcemaps/node_modules/through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
"license": "MIT",
"dependencies": {
"readable-stream": "~2.3.6",
"xtend": "~4.0.1"
}
},
"node_modules/gulplog": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz",
@ -3621,12 +3248,6 @@
"node": ">=0.10.0"
}
},
"node_modules/is-promise": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
"integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
"license": "MIT"
},
"node_modules/is-reference": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
@ -3712,12 +3333,6 @@
"node": ">=0.10.0"
}
},
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"license": "MIT"
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -4032,15 +3647,6 @@
"loose-envify": "cli.js"
}
},
"node_modules/lru-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
"integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==",
"license": "MIT",
"dependencies": {
"es5-ext": "~0.10.2"
}
},
"node_modules/magic-string": {
"version": "0.30.17",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
@ -4086,25 +3692,6 @@
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
"dev": true
},
"node_modules/memoizee": {
"version": "0.4.17",
"resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz",
"integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==",
"license": "ISC",
"dependencies": {
"d": "^1.0.2",
"es5-ext": "^0.10.64",
"es6-weak-map": "^2.0.3",
"event-emitter": "^0.3.5",
"is-promise": "^2.2.2",
"lru-queue": "^0.1.0",
"next-tick": "^1.1.0",
"timers-ext": "^0.1.7"
},
"engines": {
"node": ">=0.12"
}
},
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@ -4192,7 +3779,8 @@
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
"node_modules/mute-stdout": {
"version": "2.0.0",
@ -4258,12 +3846,6 @@
"node": ">= 4.4.x"
}
},
"node_modules/next-tick": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
"license": "ISC"
},
"node_modules/node-gyp-build": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
@ -5245,12 +4827,6 @@
"node": ">=6.0.0"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"license": "MIT"
},
"node_modules/promise.series": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/promise.series/-/promise.series-0.2.0.tgz",
@ -5800,6 +5376,7 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"devOptional": true,
"engines": {
"node": ">=0.10.0"
}
@ -5813,17 +5390,6 @@
"node": ">=0.10.0"
}
},
"node_modules/source-map-resolve": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
"integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
"deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
"license": "MIT",
"dependencies": {
"atob": "^2.1.2",
"decode-uri-component": "^0.2.0"
}
},
"node_modules/sparkles": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz",
@ -5949,15 +5515,6 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/strip-bom-string": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
"integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/style-inject": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/style-inject/-/style-inject-0.3.0.tgz",
@ -6093,19 +5650,6 @@
"readable-stream": "3"
}
},
"node_modules/timers-ext": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz",
"integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==",
"license": "ISC",
"dependencies": {
"es5-ext": "^0.10.64",
"next-tick": "^1.1.0"
},
"engines": {
"node": ">=0.12"
}
},
"node_modules/tinyexec": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.1.tgz",
@ -6152,12 +5696,6 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
},
"node_modules/type": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz",
"integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==",
"license": "ISC"
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@ -6451,15 +5989,6 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"license": "MIT",
"engines": {
"node": ">=0.4"
}
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

View file

@ -4,7 +4,6 @@
"autocompleter": "^9.3.2",
"gulp": "^5.0.0",
"gulp-less": "^5.0.0",
"gulp-sourcemaps": "^3.0.0",
"rollup": "^4.40.0"
},
"scripts": {

View file

@ -114,6 +114,9 @@
.card-preview-container {
flex: 1;
}
.card-preview-container {
border-color: light-dark(@dark-blue, @golden);
}

View file

@ -1,7 +1,9 @@
h1 {
color: light-dark(@dark-blue, @golden);
font: 700 var(--font-size-24) var(--dh-font-subtitle);
font-family: var(--dh-font-subtitle);
font-size: var(--font-size-24);
text-align: center;
font-weight: 700;
}
header {

View file

@ -1,5 +1,10 @@
@import './attribution/sheet.less';
@import './level-up/index.less';
@import './level-up/navigation-container.less';
@import './level-up/selections-container.less';
@import './level-up/sheet.less';
@import './level-up/summary-container.less';
@import './level-up/tiers-container.less';
@import './level-up/footer.less';
@import './resource-dice/sheet.less';

View file

@ -1,6 +0,0 @@
@import './navigation-container.less';
@import './selections-container.less';
@import './summary-container.less';
@import './tiers-container.less';
@import './footer.less';
@import './sheet.less';

View file

@ -3,7 +3,12 @@
.daggerheart.levelup {
.levelup-selections-container {
overflow: auto;
padding: 10px 0;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
max-height: 500px;
mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
.achievement-experience-cards {
display: flex;
@ -40,22 +45,20 @@
.levelup-card-selection {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 40px;
height: 190px;
align-items: stretch;
.card-preview-container {
height: 190px;
height: 100%;
max-width: 200px;
}
.levelup-domains-selection-container {
display: grid;
grid-auto-flow: column;
grid-template-rows: repeat(2, minmax(0, 1fr));
height: 100%;
gap: 4px;
display: flex;
flex-direction: column;
gap: 8px;
.levelup-domain-selection-container {
display: flex;
@ -63,8 +66,6 @@
align-items: center;
position: relative;
cursor: pointer;
overflow: hidden;
width: 93px;
&.disabled {
pointer-events: none;
@ -73,20 +74,16 @@
.levelup-domain-label {
position: absolute;
left: 0;
right: 0;
bottom: 0;
text-align: center;
top: 4px;
background: grey;
padding: 2px 12px;
padding: 0 12px;
border-radius: 6px;
z-index: 2;
line-height: 1;
}
img {
object-fit: cover;
width: auto;
height: auto;
height: 124px;
&.svg {
filter: @beige-filter;
@ -95,18 +92,17 @@
.levelup-domain-selected {
position: absolute;
height: 40px;
width: 40px;
height: 54px;
width: 54px;
border-radius: 50%;
border: 2px solid @golden;
font-size: var(--font-size-24);
border: 2px solid;
font-size: var(--font-size-48);
display: flex;
align-items: center;
justify-content: center;
background: @dark-golden;
color: @golden;
top: 10px;
z-index: 2;
background-image: url(../assets/parchments/dh-parchment-light.png);
color: var(--color-dark-5);
top: calc(50% - 29px);
i {
position: relative;

View file

@ -11,11 +11,9 @@
});
.daggerheart.levelup {
.tab.active {
flex: 1;
.window-content {
max-height: 960px;
overflow: auto;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
div[data-application-part='form'] {
@ -24,13 +22,15 @@
gap: 8px;
}
.section-container {
display: flex;
flex-direction: row;
justify-content: center;
gap: 20px 8px;
margin-top: 8px;
flex-wrap: wrap;
section {
.section-container {
display: flex;
flex-direction: row;
justify-content: center;
gap: 20px 8px;
margin-top: 8px;
flex-wrap: wrap;
}
}
.levelup-footer {

View file

@ -17,6 +17,8 @@
.levelup-summary-container {
overflow: auto;
padding: 10px 0;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
max-height: 700px;
mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);

View file

@ -7,85 +7,39 @@
}
.daggerheart.dialog.dh-style.views.tag-team-dialog {
.initialization-container.active {
display: flex;
flex-direction: column;
gap: var(--spacer-4);
.initialization-container {
h2 {
text-align: center;
}
.members-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 8px;
// Force 3 columns for 5 -> 6 players
&:has(> :nth-child(5)):not(:has(> :nth-child(7))) {
padding-left: 10%;
padding-right: 10%;
}
.member-container {
position: relative;
display: flex;
align-items: stretch;
justify-content: center;
border-radius: 6px;
border: 1px solid light-dark(@dark-blue, @golden);
overflow: hidden;
height: 11.5rem;
width: 122px;
&.inactive {
border-color: light-dark(@dark-blue-40, @golden-40);
img {
opacity: 0.4;
}
opacity: 0.4;
}
.member-name {
--shadow-color: light-dark(white, black);
position: absolute;
bottom: 0;
left: 0;
right: 0;
display: flex;
flex-direction: column;
justify-content: flex-end;
min-height: 4rem;
padding: 5rem 4px var(--spacer-8) 4px;
padding: 0 2px;
border: 1px solid;
border-radius: 6px;
margin-top: 4px;
color: light-dark(@dark, @beige);
background-image: url('../assets/parchments/dh-parchment-dark.png');
text-align: center;
color: var(--color-text-primary);
text-shadow: 1px 1px 2px var(--shadow-color), 0 0 10px var(--shadow-color);
// Basic "scrim" gradient
background-image: linear-gradient(
to top,
var(--shadow-color),
rgba(from var(--shadow-color) r g b / 0.834) 10.6%,
rgba(from var(--shadow-color) r g b / 0.541) 34%,
rgba(from var(--shadow-color) r g b / 0.382) 47%,
rgba(from var(--shadow-color) r g b / 0.194) 65%,
transparent 100%
);
}
img {
object-fit: cover;
object-position: top center;
flex: 1;
}
.leader-mark {
position: absolute;
top: 4px;
right: 4px;
text-shadow: var(--shadow-text-stroke), 0 0 20px black;
border-radius: 6px;
border: 1px solid light-dark(@dark-blue, @golden);
}
}
}

View file

@ -1,10 +1,4 @@
.daggerheart.dialog.dh-style.views.tag-team-dialog .window-content {
h1 {
color: light-dark(@dark-blue, @golden);
font: 700 var(--font-size-24) var(--dh-font-subtitle);
text-align: center;
}
.daggerheart.dialog.dh-style.views.tag-team-dialog {
.team-container {
display: flex;
gap: 16px;

View file

@ -7,12 +7,12 @@
input[type='text'],
input[type='number'],
textarea,
file-picker,
.input[contenteditable] {
background: light-dark(transparent, transparent);
border-radius: 6px;
box-shadow: 0 4px 30px @soft-shadow;
backdrop-filter: blur(9.5px);
-webkit-backdrop-filter: blur(9.5px);
outline: 2px solid transparent;
color: light-dark(@dark-blue, @golden);
border: 1px solid light-dark(@dark, @beige);
@ -96,9 +96,11 @@
textarea {
color: light-dark(@dark, @beige);
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
button:where(:not(.plain, color-picker *, file-picker *)) {
button:where(:not(.plain, .icon)) {
background: var(--dh-button-background);
border: 1px solid light-dark(@dark-blue, #efe6d850);
color: light-dark(@dark-blue, #efe6d8);
@ -246,15 +248,6 @@
text-shadow: 0 0 1px currentColor, 0 0 1px currentColor, 0 0 8px light-dark(@dark-blue, @golden);
}
file-picker, color-picker {
> input[type=text] {
background: transparent;
border: none;
outline: none;
backdrop-filter: unset;
}
}
fieldset {
align-items: center;
margin-top: 5px;
@ -593,6 +586,59 @@
}
}
.application.setting.dh-style {
h2,
h3,
h4 {
margin: 8px 0 4px;
text-align: center;
}
footer {
margin-top: 8px;
display: flex;
gap: 8px;
button {
flex: 1;
}
}
.form-group {
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.25rem 0.5rem;
flex-wrap: wrap;
label {
font-size: var(--font-size-14);
font-weight: normal;
}
.form-fields {
display: flex;
gap: 4px;
align-items: center;
}
&.setting-two-values {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.25rem 0.5rem;
.form-group {
justify-content: end;
flex-wrap: nowrap;
}
.hint {
grid-column: 1 / -1;
}
}
}
}
.system-daggerheart {
.tagify {
background: light-dark(transparent, transparent);
@ -752,7 +798,6 @@
.preview-image-container {
width: 100%;
min-height: 0;
flex-grow: 1;
object-fit: cover;
border-radius: 4px 4px 0 0;

View file

@ -5,6 +5,8 @@
.tab.features {
padding: 0 10px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
.feature-list {
display: flex;
flex-direction: column;

View file

@ -12,11 +12,6 @@
}
.daggerheart.dh-style {
* {
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
.hint {
flex: 0 0 100%;
margin: 0;
@ -38,7 +33,7 @@
}
&:before {
font-family: var(--font-awesome);
font-family: 'Font Awesome 6 Pro';
content: '\f110';
position: absolute;
height: 100%;

View file

@ -10,6 +10,8 @@
background-color: transparent;
}
.editor-content {
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
h1 {
font-size: var(--font-size-32);
}

View file

@ -4,8 +4,8 @@
// Theme handling
.appTheme({
background: @dark-blue-d0;
backdrop-filter: blur(7px);
background: @dark-blue-90;
backdrop-filter: blur(8px);
}, {
background: url('../assets/parchments/dh-parchment-light.png') no-repeat center;
});

View file

@ -5,6 +5,8 @@
.tab.features {
max-height: 450px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
.add-feature-btn {
width: 100%;

View file

@ -5,6 +5,8 @@
.tab.adversaries {
max-height: 450px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
.add-action-btn {
width: 100%;

View file

@ -5,6 +5,8 @@
.tab.features {
max-height: 450px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
.add-feature-btn {
width: 100%;

View file

@ -10,6 +10,9 @@
overflow-y: auto;
mask-image: linear-gradient(0deg, transparent 0%, black 5%);
padding-bottom: 20px;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}
}

View file

@ -9,6 +9,9 @@
overflow-y: auto;
mask-image: linear-gradient(0deg, transparent 0%, black 5%);
padding-bottom: 20px;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}
}

View file

@ -287,11 +287,12 @@
padding-top: 10px;
padding-bottom: 20px;
mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
scrollbar-width: thin;
scrollbar-gutter: stable;
&:hover {
overflow-y: auto;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}

View file

@ -13,6 +13,9 @@
padding-top: 8px;
padding-bottom: 20px;
height: 100%;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
.characteristics-section {

View file

@ -10,6 +10,9 @@
overflow-y: auto;
mask-image: linear-gradient(0deg, transparent 0%, black 5%);
padding-bottom: 20px;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}
}

View file

@ -10,6 +10,9 @@
overflow-y: auto;
mask-image: linear-gradient(0deg, transparent 0%, black 5%);
padding-bottom: 20px;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}
}

View file

@ -10,6 +10,9 @@
overflow-y: auto;
mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
padding: 20px 0;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}
}

View file

@ -92,6 +92,9 @@
overflow-y: auto;
mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%);
padding: 20px 0;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}
}

View file

@ -541,9 +541,11 @@
padding-bottom: 20px;
mask-image: linear-gradient(0deg, transparent 0%, black 5%);
scrollbar-gutter: stable;
scrollbar-width: thin;
&:hover {
overflow-y: auto;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}

View file

@ -9,6 +9,9 @@
overflow-y: auto;
mask-image: linear-gradient(0deg, transparent 0%, black 5%);
padding-bottom: 20px;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}
}

View file

@ -10,6 +10,9 @@
overflow-y: auto;
mask-image: linear-gradient(0deg, transparent 0%, black 5%);
padding-bottom: 20px;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}
}

View file

@ -9,6 +9,9 @@
overflow-y: auto;
mask-image: linear-gradient(0deg, transparent 0%, black 5%);
padding-bottom: 20px;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}
}

View file

@ -20,6 +20,8 @@
.tab {
flex: 1;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
&.active {
overflow: hidden;

View file

@ -10,6 +10,9 @@
overflow-y: auto;
mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
padding: 20px 0;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}
}

View file

@ -2,6 +2,16 @@
@import '../../../utils/fonts.less';
@import '../../../utils/mixin.less';
body.game:is(.performance-low, .noblur) {
.application.sheet.daggerheart.actor.dh-style.party .tab.resources .actors-list .actor-resources {
background: light-dark(@dark-blue, @dark-golden);
.actor-name {
background: light-dark(@dark-blue, @dark-golden);
}
}
}
.application.sheet.daggerheart.actor.dh-style.party .tab.partyMembers {
overflow: auto;

View file

@ -20,6 +20,8 @@
.tab {
flex: 1;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
scrollbar-gutter: stable;
&.active {

View file

@ -5,5 +5,7 @@
section.tab {
height: 400px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}

View file

@ -14,5 +14,7 @@
section.tab {
height: 400px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
}

View file

@ -195,7 +195,7 @@ fieldset.daggerheart.chat {
&:before,
&:after {
content: '\f0d8';
font-family: var(--font-awesome);
font-family: 'Font Awesome 6 Pro';
}
}
&.expanded {

View file

@ -60,6 +60,8 @@
overflow-y: auto;
overflow-x: hidden;
max-height: 500px;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
.countdown-edit-outer-container {
display: flex;

View file

@ -1,47 +1,28 @@
@import '../../utils/colors.less';
@import '../../utils/fonts.less';
#interface.theme-dark {
.theme-dark {
.daggerheart.dh-style.countdowns {
--background: url(../assets/parchments/dh-parchment-dark.png);
background-image: url(../assets/parchments/dh-parchment-dark.png);
.window-header {
background-image: url(../assets/parchments/dh-parchment-dark.png);
}
}
}
#interface.theme-light {
.daggerheart.dh-style.countdowns {
--background: url('../assets/parchments/dh-parchment-light.png') no-repeat center;
}
}
.daggerheart.dh-style.countdowns {
.daggerheart.dh-style.countdowns {
position: relative;
border: 0;
border-radius: 4px;
box-shadow: none;
color: var(--color-text-primary);
width: 300px;
pointer-events: all;
align-self: flex-end;
transition: 0.3s right ease-in-out;
display: flex;
flex-direction: column;
&::before {
content: ' ';
position: absolute;
inset: 0;
background: var(--background);
border-radius: 4px;
opacity: var(--ui-fade-opacity);
transition: opacity var(--ui-fade-duration);
}
:not(.performance-low, .noblur) {
backdrop-filter: blur(5px);
}
&:hover::before {
opacity: 1;
.window-title {
font-family: @font-body;
}
#ui-right:has(#effects-display .effect-container) & {
@ -53,136 +34,123 @@
min-width: 180px;
}
.countdowns-header,
.countdowns-container {
position: relative; // allow rendering over the background
.window-header {
cursor: default;
border-bottom: 0;
}
.countdowns-header {
display: flex;
align-items: center;
gap: 0.25rem;
flex: 0 0 36px;
padding: 0 0.5rem;
overflow: hidden;
font-size: var(--font-size-13);
.window-title {
font-family: @font-body;
flex: 1;
}
.header-control + .header-control {
margin-left: 8px;
}
}
.countdowns-container {
display: flex;
flex-direction: column;
gap: 8px;
padding: 4px var(--spacer-16) var(--spacer-16) var(--spacer-16);
.window-content {
padding-top: 4px;
padding-bottom: 16px;
overflow: auto;
max-height: 312px;
.countdown-container {
.countdowns-container {
display: flex;
width: 100%;
flex-direction: column;
gap: 8px;
&.icon-only {
gap: 8px;
.countdown-container {
display: flex;
width: 100%;
.countdown-main-container {
.countdown-content {
justify-content: center;
&.icon-only {
gap: 8px;
.countdown-tools {
gap: 8px;
.countdown-main-container {
.countdown-content {
justify-content: center;
.countdown-tools {
gap: 8px;
}
}
}
}
}
.countdown-main-container {
width: 100%;
display: flex;
align-items: center;
gap: 16px;
img {
width: 44px;
height: 44px;
border-radius: 6px;
}
.countdown-content {
flex: 1;
.countdown-main-container {
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
gap: 16px;
.countdown-tools {
img {
width: 44px;
height: 44px;
border-radius: 6px;
}
.countdown-content {
flex: 1;
display: flex;
align-items: center;
flex-direction: column;
justify-content: space-between;
.countdown-tool-controls {
.countdown-tools {
display: flex;
align-items: center;
gap: 16px;
}
justify-content: space-between;
.progress-tag {
border: 1px solid;
border-radius: 4px;
padding: 2px 4px;
background-color: light-dark(@beige, @dark-blue);
}
.countdown-tool-controls {
display: flex;
align-items: center;
gap: 16px;
}
.countdown-tool-icons {
display: flex;
align-items: center;
gap: 8px;
.looping-container {
position: relative;
border: 1px solid light-dark(@dark-blue, white);
border-radius: 6px;
.progress-tag {
border: 1px solid;
border-radius: 4px;
padding: 2px 4px;
background-color: light-dark(@beige, @dark-blue);
}
&.should-loop {
background: light-dark(@golden, @golden);
.countdown-tool-icons {
display: flex;
align-items: center;
gap: 8px;
.loop-marker {
color: light-dark(@dark-blue, @dark-blue);
.looping-container {
position: relative;
border: 1px solid light-dark(@dark-blue, white);
border-radius: 6px;
padding: 2px 4px;
&.should-loop {
background: light-dark(@golden, @golden);
.loop-marker {
color: light-dark(@dark-blue, @dark-blue);
}
}
}
.direction-marker {
position: absolute;
font-size: 10px;
filter: drop-shadow(0 0 3px black);
top: -3px;
.direction-marker {
position: absolute;
font-size: 10px;
filter: drop-shadow(0 0 3px black);
top: -3px;
}
}
}
}
}
}
}
/* Keep incase we want to reintroduce the player pips */
// .countdown-access-container {
// display: grid;
// grid-template-columns: 1fr 1fr 1fr;
// grid-auto-rows: min-content;
// width: 38px;
// gap: 4px;
/* Keep incase we want to reintroduce the player pips */
// .countdown-access-container {
// display: grid;
// grid-template-columns: 1fr 1fr 1fr;
// grid-auto-rows: min-content;
// width: 38px;
// gap: 4px;
// .countdown-access {
// height: 10px;
// width: 10px;
// border-radius: 50%;
// border: 1px solid light-dark(@dark-blue, @beige-80);
// content: '';
// }
// }
// .countdown-access {
// height: 10px;
// width: 10px;
// border-radius: 50%;
// border: 1px solid light-dark(@dark-blue, @beige-80);
// content: '';
// }
// }
}
}
}
}

View file

@ -125,7 +125,6 @@
.form-group {
white-space: nowrap;
gap: 0;
}
.filter-header {
@ -169,10 +168,6 @@
}
}
}
.filter-content {
margin-top: 8px;
}
}
.folder-list {
@ -242,6 +237,8 @@
.compendium-sidebar > .folder-list {
overflow-y: auto;
scrollbar-gutter: stable;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
}
.item-list-header,
@ -277,7 +274,7 @@
div[data-sort-key] {
&:after {
font-family: var(--font-awesome);
font-family: 'Font Awesome 6 Pro';
margin-left: 5px;
}

View file

@ -55,6 +55,8 @@
gap: 8px;
max-height: 184px;
overflow: auto;
scrollbar-width: thin;
scrollbar-color: light-dark(#18162e, #f3c267) transparent;
.domain-container {
position: relative;

View file

@ -24,7 +24,7 @@
.resource-icons-container {
display: flex;
justify-content: space-between;
gap: 10px;
gap: 8px;
width: 100%;
.resource-icon-container {

View file

@ -1,67 +1,6 @@
@import '../../utils/colors.less';
.daggerheart.dh-style.setting {
--color-form-label: var(--color-text-primary);
h2,
h3,
h4 {
margin: 8px 0 4px;
text-align: center;
}
footer {
margin-top: 8px;
display: flex;
gap: 8px;
button {
flex: 1;
}
}
.standard-form {
gap: var(--spacer-8);
.form-group .form-fields {
width: unset;
}
}
.form-group {
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.25rem 0.5rem;
flex-wrap: wrap;
label {
font-size: var(--font-size-14);
font-weight: normal;
line-height: var(--input-height);
}
.form-fields {
display: flex;
gap: 4px;
align-items: center;
}
&.setting-two-values {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.25rem 0.5rem;
.form-group {
justify-content: end;
flex-wrap: nowrap;
}
.hint {
grid-column: 1 / -1;
}
}
}
fieldset {
display: flex;
flex-direction: column;
@ -80,10 +19,7 @@
&.three-columns {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 4px;
.form-group label {
line-height: unset;
}
gap: 2px;
}
&.six-columns {

View file

@ -51,7 +51,6 @@
--dark-blue-50: #18162e50;
--dark-blue-60: #18162e60;
--dark-blue-90: #18162e90;
--dark-blue-d0: #18162ed0;
--semi-transparent-dark-blue: rgba(24, 22, 46, 0.33);
--dark: #222222;
@ -137,7 +136,6 @@
@dark-blue-50: var(--dark-blue-50, #18162e50);
@dark-blue-60: var(--dark-blue-60, #18162e60);
@dark-blue-90: var(--dark-blue-90, #18162e90);
@dark-blue-d0: var(--dark-blue-d0, #18162ed0);
@semi-transparent-dark-blue: var(--semi-transparent-dark-blue, rgba(24, 22, 46, 0.33));
@dark: var(--dark, #222222);

View file

@ -21,6 +21,8 @@
flex-direction: column;
gap: 2px;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
.group {
font-weight: bold;
font-size: var(--font-size-14);

View file

@ -48,6 +48,9 @@ aside[role='tooltip']:has(div.daggerheart.dh-style.tooltip),
overflow-y: auto;
position: relative;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
.tooltip-tag {
display: flex;
gap: 10px;

View file

@ -2,24 +2,19 @@
"id": "daggerheart",
"title": "Daggerheart",
"description": "An unofficial implementation of the Daggerheart system",
"version": "2.2.6",
"version": "2.2.4",
"compatibility": {
"minimum": "14.361",
"verified": "14.363",
"minimum": "14.359",
"verified": "14.361",
"maximum": "14"
},
"url": "https://github.com/Foundryborne/daggerheart",
"manifest": "https://raw.githubusercontent.com/Foundryborne/daggerheart/v14/system.json",
"download": "https://github.com/Foundryborne/daggerheart/releases/download/2.2.6/system.zip",
"download": "https://github.com/Foundryborne/daggerheart/releases/download/2.2.4/system.zip",
"authors": [
{
"name": "WBHarry"
},
{
"name": "Supe",
"url": "https://github.com/CarlosFdez",
"discord": "supe"
},
{
"name": "cptn-cosmo",
"url": "https://github.com/cptn-cosmo",
@ -303,11 +298,5 @@
},
"background": "systems/daggerheart/assets/logos/FoundrybornBackgroundLogo.png",
"primaryTokenAttribute": "resources.hitPoints",
"secondaryTokenAttribute": "resources.stress",
"flags": {
"hotReload": {
"extensions": ["css", "hbs", "json"],
"paths": ["styles/daggerheart.css", "templates", "lang"]
}
}
"secondaryTokenAttribute": "resources.stress"
}

View file

@ -22,7 +22,7 @@
<div class="checks-container {{#unless source.checked}}collapsed{{/unless}}">
{{#each source.packs as |pack|}}
<div class="check-container">
<input type="checkbox" class="pack-checkbox" data-type="{{pack.type}}" data-source="{{@../key}}" data-pack-name="{{pack.name}}" {{checked pack.checked}} />
<input type="checkbox" class="pack-checkbox" data-type="{{pack.type}}" data-pack="{{pack.pack}}" {{checked pack.checked}} />
<label>{{pack.label}}</label>
</div>
{{/each}}

View file

@ -1,18 +1,13 @@
<section class="initialization-container tab {{#if tabs.initialization.active}} active{{/if}}" data-group="{{tabs.initialization.group}}" data-tab="{{tabs.initialization.id}}">
<h1>{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.selectParticipants"}}</h1>
<h2>{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.selectParticipants"}}</h2>
<div class="members-container">
{{#each memberSelection as |member|}}
<a
class="member-container {{#unless member.selected}}inactive {{#if ../allselected}}locked{{/if}}{{/unless}}"
data-action="toggleSelectMember" data-id="{{member.id}}" {{#if (and (not member.selected) ../allSelected)}}disabled{{/if}}
>
<img src="{{member.img}}" />
<span class="member-name">{{member.name}}</span>
{{#if (eq @root.initiator.memberId member.id)}}
<div class="leader-mark">
<i class="fa-solid fa-crown" inert></i>
</div>
{{/if}}
<img src="{{member.img}}" />
</a>
{{/each}}
</div>
@ -35,13 +30,10 @@
</div>
<footer>
<button type="button" data-action="startTagTeamRoll" {{#unless canStartTagTeam}}disabled{{/unless}}>{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.startTagTeamRoll"}} <i class="fa-solid fa-arrow-right-long"></i></button>
<div class="finish-tools {{#unless canStartTagTeam}}inactive{{/unless}}">
<span>{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.openDialogForAll"}}</span>
<input type="checkbox" class="openforall-field" {{#unless canStartTagTeam}}disabled{{/unless}} {{checked openForAllPlayers}} />
</div>
<button type="button" data-action="startTagTeamRoll" {{#unless canStartTagTeam}}disabled{{/unless}}>
<i class="fa-solid fa-arrow-right-long" inert></i>
{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.startTagTeamRoll"}}
</button>
</footer>
</section>

View file

@ -32,10 +32,7 @@
<div class="finish-container">
<button type="button" data-action="cancelRoll">{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.cancelTagTeamRoll"}}</button>
<button type="button" data-action="finishRoll" {{#if hintText}}disabled{{/if}} class="finish-button">
<i class="fa-solid fa-dice" inert></i>
{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.finishTagTeamRoll"}}
</button>
<button type="button" data-action="finishRoll" {{#if hintText}}disabled{{/if}} class="finish-button">{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.finishTagTeamRoll"}}</button>
</div>
</div>
</section>

View file

@ -4,6 +4,10 @@
<input type="text" name="elevation" value="{{elevation}}" {{disabled (or locked (and isGamePaused (not isGM)))}}>
</div>
<button type="button" class="control-icon" data-action="sort" data-tooltip="HUD.ToFrontOrBack">
<i class="fa-solid fa-arrow-down-arrow-up" inert></i>
</button>
{{#if canChangeLevel}}
<button type="button" class="control-icon" data-action="togglePalette" data-palette="levels"
aria-label="{{ localize "HUD.ChangeLevel" }}" data-tooltip>
@ -16,25 +20,14 @@
</div>
{{/if}}
<button type="button" class="control-icon" data-action="sort" data-tooltip aria-label="HUD.ToFrontOrBack">
<i class="fa-solid fa-bring-forward" inert></i>
</button>
{{#if hasCompanion}}
<button type="button" class="control-icon clown-car" data-action="toggleCompanions" data-tooltip="{{#if companionOnCanvas}}{{localize "DAGGERHEART.APPLICATIONS.HUD.tokenHUD.retrieveCompanionTokens"}}{{else}}{{localize "DAGGERHEART.APPLICATIONS.HUD.tokenHUD.depositCompanionTokens"}}{{/if}}">
<img {{#if companionOnCanvas}}class="flipped"{{/if}} src="{{icons.toggleClowncar}}">
</button>
{{/if}}
{{#if isGM}}
<button type="button" class="control-icon {{lockedClass}}" data-action="locked"
data-tooltip aria-label="{{localize (ifThen lockedClass "HUD.Unlock" "HUD.Lock")}}">
<i class="fa-solid {{ifThen lockedClass "fa-lock" "fa-lock-open"}}" inert></i>
</button>
{{/if}}
{{#if canConfigure}}
<button type="button" class="control-icon" data-action="config" data-tooltip aria-label="HUD.OpenConfig">
<button type="button" class="control-icon" data-action="config" data-tooltip="HUD.OpenConfig">
<i class="fa-solid fa-gear" inert></i>
</button>
{{/if}}
@ -56,9 +49,8 @@
<div class="col right">
{{#if isGM}}
<button type="button" class="control-icon {{visibilityClass}}" data-action="visibility"
data-tooltip aria-label="{{localize (ifThen visibilityClass "HUD.Show" "HUD.Hide")}}">
<i class="fa-solid {{ifThen hidden "fa-eye-slash" "fa-eye"}}" inert></i>
<button type="button" class="control-icon {{visibilityClass}}" data-action="visibility" data-tooltip="HUD.ToggleVis">
<img src="{{icons.visibility}}">
</button>
{{/if}}
@ -127,15 +119,13 @@
{{/each}}
</div>
<button type="button" class="control-icon {{targetClass}}" data-action="target"
data-tooltip aria-label="{{localize (ifThen targetClass "HUD.Untarget" "HUD.Target")}}">
<button type="button" class="control-icon {{targetClass}}" data-action="target" data-tooltip="HUD.ToggleTargetState">
<i class="fa-solid fa-bullseye" inert></i>
</button>
{{#if canToggleCombat}}
<button type="button" class="control-icon {{combatClass}}" data-action="combat"
data-tooltip aria-label="{{localize (ifThen combatClass "HUD.ExitCombat" "HUD.EnterCombat")}}">
<i class="fa-solid fa-swords" inert></i>
<button type="button" class="control-icon {{combatClass}}" data-action="combat" data-tooltip="HUD.ToggleCombatState">
<img src="{{icons.combat}}">
</button>
{{/if}}
</div>

View file

@ -43,6 +43,45 @@
</fieldset>
{{/if}}
{{#if (gt this.domainCards.length 0)}}
<div class="card-section">
<div class="card-section-header">
<side-line-div class="invert"></side-line-div>
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.domainCards"}}</h3>
<side-line-div></side-line-div>
</div>
<div class="tip">
</div>
<div class="levelup-card-selection domain-cards">
{{#each this.domainCards}}
{{#> "systems/daggerheart/templates/components/card-preview.hbs" this }}
{{#each this.emptySubtexts}}
<div class="">{{this}}</div>
{{/each}}
{{/"systems/daggerheart/templates/components/card-preview.hbs"}}
{{/each}}
</div>
</div>
{{/if}}
{{#if (gt this.subclassCards.length 0)}}
<div class="card-section">
<div class="card-section-header">
<side-line-div class="invert"></side-line-div>
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.subclass"}}</h3>
<side-line-div></side-line-div>
</div>
<div class="levelup-card-selection subclass-cards">
{{#each this.subclassCards}}
{{> "systems/daggerheart/templates/levelup/parts/selectable-card-preview.hbs" img=this.img header=this.featureLabel name=this.name path=this.path selected=this.selected uuid=this.uuid isMulticlass=this.isMulticlass featureState=this.featureState disabled=this.disabled }}
{{/each}}
</div>
</div>
{{/if}}
{{#if this.multiclass}}
<div class="card-section">
<div class="card-section-header">
@ -89,45 +128,6 @@
</div>
{{/if}}
{{#if (gt this.domainCards.length 0)}}
<div class="card-section">
<div class="card-section-header">
<side-line-div class="invert"></side-line-div>
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.domainCards"}}</h3>
<side-line-div></side-line-div>
</div>
<div class="tip">
</div>
<div class="levelup-card-selection domain-cards">
{{#each this.domainCards}}
{{#> "systems/daggerheart/templates/components/card-preview.hbs" this }}
{{#each this.emptySubtexts}}
<div class="">{{this}}</div>
{{/each}}
{{/"systems/daggerheart/templates/components/card-preview.hbs"}}
{{/each}}
</div>
</div>
{{/if}}
{{#if (gt this.subclassCards.length 0)}}
<div class="card-section">
<div class="card-section-header">
<side-line-div class="invert"></side-line-div>
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.subclass"}}</h3>
<side-line-div></side-line-div>
</div>
<div class="levelup-card-selection subclass-cards">
{{#each this.subclassCards}}
{{> "systems/daggerheart/templates/levelup/parts/selectable-card-preview.hbs" img=this.img header=this.featureLabel name=this.name path=this.path selected=this.selected uuid=this.uuid isMulticlass=this.isMulticlass featureState=this.featureState disabled=this.disabled }}
{{/each}}
</div>
</div>
{{/if}}
{{#if this.vicious}}
<div>
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.vicious"}}</h3>

View file

@ -1,4 +1,4 @@
<div class="standard-form">
<div>
{{formGroup settingFields.schema.fields.hideObserverPermissionInChat value=settingFields._source.hideObserverPermissionInChat localize=true}}
{{formGroup settingFields.schema.fields.hidePartyStats value=settingFields._source.hidePartyStats localize=true}}
</div>
{{formGroup settingFields.schema.fields.hidePartyStats value=settingFields._source.hidePartyStats localize=true}}
</div>

View file

@ -1,43 +1,20 @@
<div class="tab scrollable{{#if tab.active}} active{{/if}}" data-group="{{tab.group}}" data-tab="{{tab.id}}">
<div class="token-image-group">
{{formGroup fields.texture.fields.src value=source.texture.src rootId=rootId}}
{{#if randomImgEnabled}}
{{formGroup fields.randomImg value=source.randomImg classes="slim" rootId=rootId}}
{{else if hasAlternates}}
<div class="form-group">
<label for="{{rootId}}-alternateImages">{{localize "TOKEN.ImageAlts"}}</label>
<select id="{{rootId}}-alternateImages" class="alternate-images" name="alternateImages">
{{selectOptions alternateImages selected=source.texture.src blank=""}}
</select>
</div>
{{/if}}
{{#if imagePreview}}
<div class="{{imagePreview.cls}}">
{{#if imagePreview.isVideo}}
<video class="token-image-thumb" src="{{imagePreview.src}}" autoplay muted loop playsinline
disablepictureinpicture></video>
{{else}}
<img class="token-image-thumb" src="{{imagePreview.src}}" alt="{{localize "TOKEN.ImagePreview"}}">
{{/if}}
<div class="token-image-controls">
<button type="button" class="cycle-prev icon fa-solid fa-chevron-left" data-action="cycleImage"
data-delta="-1" aria-label="{{localize "TOKEN.ImageCyclePrev"}}"
{{#unless imagePreview.hasPrev}} disabled{{/unless}}></button>
<span class="counter">{{imagePreview.current}} / {{imagePreview.total}}</span>
<button type="button" class="cycle-next icon fa-solid fa-chevron-right" data-action="cycleImage"
data-delta="1" aria-label="{{localize "TOKEN.ImageCycleNext"}}"
{{#unless imagePreview.hasNext}} disabled{{/unless}}></button>
</div>
</div>
{{/if}}
{{formGroup fields.texture.fields.src value=source.texture.src rootId=rootId}}
{{#if randomImgEnabled}}
{{formGroup fields.randomImg value=source.randomImg classes="slim" rootId=rootId}}
{{else if hasAlternates}}
<div class="form-group">
<label for="{{rootId}}-alternateImages">{{localize "TOKEN.ImageAlts"}}</label>
<select id="{{rootId}}-alternateImages" class="alternate-images" name="alternateImages">
{{selectOptions alternateImages selected=source.texture.src blank=""}}
</select>
</div>
{{/if}}
<fieldset>
<legend>{{localize "DAGGERHEART.APPLICATIONS.TokenConfig.tokenSize"}}</legend>
<legend>{{localize "Token Size"}}</legend>
{{#if usesActorSize}}
<div class="form-group slim">
<label>{{localize "DAGGERHEART.APPLICATIONS.TokenConfig.sizeCategory"}}</label>
<div class="form-group lim">
<label>{{localize "Size Category"}}</label>
<select id="dhTokenSize">
{{selectOptions tokenSizes selected=tokenSize valueAttr="id" labelAttr="label" localize=true}}
@ -46,17 +23,15 @@
{{/if}}
<div id="tokenSizeDimensions" class="form-group slim" {{#if actorSizeDisable}}data-tooltip="{{localize "DAGGERHEART.APPLICATIONS.TokenConfig.actorSizeUsed"}}"{{/if}}>
<span class="label">
{{localize "TOKEN.Size"}}
<span class="units">({{localize "MEASUREMENT.GridSpaces"}})</span>
</span>
<div class="form-group slim">
<label>
{{localize "TOKEN.Dimensions"}} <span class="units">({{localize "GridSpaces"}})</span>
<i class="fa-solid fa-lock" {{#unless actorSizeDisable}}style="opacity: 0%;"{{/unless}}></i>
</label>
<div class="form-fields">
<label for="{{rootId}}-width">{{localize "DOCUMENT.FIELDS.width.label"}}</label>
{{formInput fields.width value=source.width id=(concat rootId "-width") disabled=actorSizeDisable}}
<label for="{{rootId}}-height">{{localize "DOCUMENT.FIELDS.height.label"}}</label>
{{formInput fields.height value=source.height id=(concat rootId "-height") disabled=actorSizeDisable}}
<label for="{{rootId}}-depth">Z</label>
{{formInput fields.depth value=source.depth id=(concat rootId "-depth") disabled=actorSizeDisable}}
</div>
</div>
</fieldset>

View file

@ -6,7 +6,6 @@
type='feature'
collection=@root.features
hideContextMenu=true
hideModifyControls=true
canCreate=@root.editable
showActions=@root.editable
}}

View file

@ -64,7 +64,7 @@
{{/if}}
</div>
{{#if (or document.system.multiclass.value document.system.multiclass.subclass)}}
{{#if document.system.multiclass.value}}
<div class="multiclass">
{{#if document.system.multiclass.value}}
<span data-action="editDoc"data-item-uuid="{{document.system.multiclass.value.uuid}}">{{document.system.multiclass.value.name}}</span>

View file

@ -44,7 +44,7 @@
</div>
{{else}}
<div class='status-value'>
<input class="bar-input armor-marks-input" value="{{document.system.armorScore.value}}" type="number" id="{{document.uuid}}-armor-slots">
<input class="bar-input armor-marks-input" value="{{document.system.armorScore.value}}" type="number">
<span>/</span>
<span class="bar-label">{{document.system.armorScore.max}}</span>
</div>

View file

@ -9,7 +9,6 @@
type='feature'
collection=@root.features
hideContextMenu=true
hideModifyControls=true
canCreate=@root.editable
showActions=@root.editable
}}

View file

@ -19,8 +19,6 @@ Parameters:
- showLabels {boolean} : If true, show label-tags else show simple tags.
- hideTooltip {boolean} : If true, disables the tooltip on the item image.
- hideControls {boolean} : If true, hides the controls inside inventory-item partials.
- hideContextMenu {boolean}: If true, hides the context menu dropdown button
- hideModifyControls {boolean}: If true, hides the edit and delete options
- hideDescription {boolean} : If true, hides the item's description.
- hideResources {boolean} : If true, hides the item's resources.
- showActions {boolean} : If true show feature's actions.
@ -61,7 +59,6 @@ Parameters:
actorType=(ifThen ../actorType ../actorType @root.document.type)
hideControls=../hideControls
hideContextMenu=../hideContextMenu
hideModifyControls=../hideModifyControls
isActor=../isActor
categoryAdversary=../categoryAdversary
hideTooltip=../hideTooltip

View file

@ -12,8 +12,6 @@ Parameters:
- hideTags {boolean} : If true, hide simple-tags else show simple-tags.
- hideTooltip {boolean} : If true, disables the tooltip on the item image.
- hideControls {boolean} : If true, hides the controls inside inventory-item partials.
- hideContextMenu {boolean}: If true, hides the context menu dropdown button
- hideModifyControls {boolean}: If true, hides the edit and delete options (todo: swap to show, only party cares to show this)
- hideDescription {boolean} : If true, hides the item's description.
- hideResources {boolean} : If true, hides the item's resources.
- showActions {boolean} : If true show feature's actions.
@ -114,12 +112,12 @@ Parameters:
<a data-action="triggerContextMenu" data-tooltip="DAGGERHEART.UI.Tooltip.moreOptions">
<i class="fa-solid fa-fw fa-ellipsis-vertical" inert></i>
</a>
{{else if (and @root.editable (not hideModifyControls))}}
{{else if @root.editable}}
<a data-action="editDoc" data-tooltip="DAGGERHEART.UI.Tooltip.edit">
<i class="fa-solid fa-edit" inert></i>
</a>
{{#if (not isActor)}}
<a data-action="deleteDoc" data-tooltip="DAGGERHEART.UI.Tooltip.deleteItem">
<a data-action="deleteItem" data-tooltip="DAGGERHEART.UI.Tooltip.deleteItem">
<i class="fa-solid fa-trash" inert></i>
</a>
{{else if (eq type 'adversary')}}

View file

@ -46,13 +46,6 @@
placeholder=(localize (ifThen dimensionsDisabled "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.disabledPlaceholder" "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder"))
disabled=dimensionsDisabled
}}
{{formGroup
systemFields.tokenSize.fields.depth
value=source.system.tokenSize.depth
localize=true
placeholder=(localize (ifThen dimensionsDisabled "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.disabledPlaceholder" "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder"))
disabled=dimensionsDisabled
}}
</div>
<div class="full-width">
{{formGroup systemFields.tokenSize.fields.scale value=source.system.tokenSize.scale localize=true }}

View file

@ -6,7 +6,7 @@
{{#if roll.isCritical}}
<span>{{localize "DAGGERHEART.GENERAL.criticalShort"}}</span>
{{else}}
{{#if (and roll.dHope (not (eq roll.options.roll.type "reaction")))}}
{{#if (and roll.dHope (not (eq roll.type "reaction")))}}
<span>{{localize "DAGGERHEART.GENERAL.withThing" thing=roll.totalLabel}}</span>
{{/if}}
{{/if}}

View file

@ -5,10 +5,7 @@
{{#if (gt this.characters.length 0)}}
{{> 'systems/daggerheart/templates/ui/combatTracker/combatTrackerSection.hbs' this title=(localize "DAGGERHEART.GENERAL.Character.plural") turns=this.characters}}
{{/if}}
{{#if (gt this.friendlies.length 0)}}
{{> 'systems/daggerheart/templates/ui/combatTracker/combatTrackerSection.hbs' this title=(localize "DAGGERHEART.APPLICATIONS.CombatTracker.adversaryCategories.friendly") turns=this.friendlies}}
{{/if}}
{{#if (gt this.adversaries.length 0)}}
{{> 'systems/daggerheart/templates/ui/combatTracker/combatTrackerSection.hbs' this title=(localize "DAGGERHEART.APPLICATIONS.CombatTracker.adversaryCategories.adversaries") turns=this.adversaries}}
{{> 'systems/daggerheart/templates/ui/combatTracker/combatTrackerSection.hbs' this title=(localize "DAGGERHEART.GENERAL.Adversary.plural") turns=this.adversaries}}
{{/if}}
</div>

View file

@ -13,20 +13,20 @@
<div class="combatant-controls flex-0">
{{#if @root.user.isGM}}
<button type="button" class="inline-control combatant-control icon fa-solid fa-eye-slash {{#if hidden}}active{{/if}}"
data-action="toggleHidden" data-tooltip aria-label="{{ localize (ifThen hidden "COMBATANT.Show" "COMBATANT.Hide") }}"></button>
data-action="toggleHidden" data-tooltip aria-label="{{ localize "COMBAT.ToggleVis" }}"></button>
<button type="button" class="inline-control combatant-control icon fa-solid fa-skull {{#if isDefeated}}active{{/if}}"
data-action="toggleDefeated" data-tooltip
aria-label="{{ localize (ifThen isDefeated "COMBATANT.UnmarkDefeated" "COMBATANT.MarkDefeated") }}"></button>
aria-label="{{ localize "COMBAT.ToggleDead" }}"></button>
{{/if}}
{{#if canPing}}
<button type="button" class="inline-control combatant-control icon fa-solid fa-bullseye-arrow"
data-action="pingCombatant" data-tooltip
aria-label="{{ localize "COMBATANT.Ping" }}"></button>
aria-label="{{ localize "COMBAT.PingCombatant" }}"></button>
{{/if}}
{{#unless @root.user.isGM}}
<button type="button" class="inline-control combatant-control icon fa-solid fa-arrows-to-eye"
data-action="panToCombatant" data-tooltip
aria-label="{{ localize "COMBATANT.PanTo" }}"></button>
aria-label="{{ localize "COMBAT.PanToCombatant" }}"></button>
{{/unless}}
</div>

View file

@ -1,14 +1,4 @@
<div>
<header class="countdowns-header">
<i class="fa-solid fa-clock-rotate-left" inert></i>
<span class="window-title">{{localize "DAGGERHEART.UI.Countdowns.title"}}</span>
<a class="header-control" data-tooltip aria-label="DAGGERHEART.APPLICATIONS.CountdownEdit.editTitle" data-action="editCountdowns">
<i class="fa-solid fa-wrench" inert></i>
</a>
<a class="header-control" data-tooltip aria-label="DAGGERHEART.UI.Countdowns.toggleIconMode" data-action="toggleViewMode">
<i class="fa-solid fa-down-left-and-up-right-to-center" inert></i>
</a>
</header>
<div class="countdowns-container">
{{#each countdowns as | countdown id |}}
<div class="countdown-container {{#if ../iconOnly}}icon-only{{/if}}">

View file

@ -12,20 +12,15 @@
</menu>
{{/with}}
{{#if scenes.levels}}
<menu id="scene-navigation-levels" class="scene-levels scene-navigation-menu flexcol"
style="--max-levels: {{ scenes.levels.length }}">
<menu id="scene-navigation-levels" class="scene-levels scene-navigation-menu flexcol" style="--max-levels: {{ scenes.levels.length }}">
{{#each scenes.levels}}
<li class="level-row">
{{#with button}}
<button type="button" class="ui-control icon fa-solid {{ css }}" data-action="cycleLevel"
data-direction="{{ direction }}" aria-label="{{ label }}"></button>
{{/with}}
<div class="ui-control scene scene-level {{ css }}" data-scene-id="{{ sceneId }}" data-level-id="{{ id }}" data-action="viewLevel">
<span class="ellipsis">{{ name }}</span>
{{#if users}}
<ul class="scene-players">
{{#each users}}
<li class="scene-player" style="--color-bg: {{ color }}; --color-border: {{ border }}" data-tooltip
aria-label="{{ name }}">{{ letter }}</li>
{{/each}}
</ul>
{{/if}}
</div>
</li>
{{/each}}
@ -45,8 +40,7 @@
{{#*inline ".scene"}}
<li class="scene-wrapper">
<div class="ui-control scene {{ cssClass }}" data-scene-id="{{ id }}" data-action="viewScene"
{{#if tooltip}}data-tooltip-text="{{ tooltip }}"{{/if}}>
<div class="ui-control scene {{ cssClass }}" data-scene-id="{{ id }}" data-action="viewScene" {{#if tooltip}}data-tooltip-text="{{ tooltip }}"{{/if}}>
<span class="scene-name ellipsis">{{ name }}</span>
{{#if users}}
<ul class="scene-players">