Compare commits

...

29 commits

Author SHA1 Message Date
07009a1f98 Merge branch 'feature/spells-officialJSON' into feature/spells
# Conflicts:
#	.vscode/spells-schemas.json
2023-03-21 14:45:51 +01:00
1da611e2f3 Add final fateforge_spells + issue tracker
TODO:
- verify spells description and attributes
- update json.schema
- advance on #1
2023-03-17 01:57:39 +01:00
b314104ab6 update spells body style 2023-03-16 00:48:48 +01:00
62ce42afc1 WIP: add & Edit Agate JSON file 2023-03-16 00:48:10 +01:00
e14e1c8b83 make table responsive 2023-03-13 16:13:25 +01:00
3609e60f19 add csv & json agate source 2023-03-12 23:50:11 +01:00
eea47d851d remove selection column 2023-03-12 23:42:58 +01:00
f034968c51 Merge branch 'feature/spells' into develop
# Conflicts:
#	css/style.css
#	index.html
#	js/language.js
#	lang/main-en.json
#	spells.html
2023-03-12 23:41:39 +01:00
8da6559f73 add LEG6 cover 2023-03-12 16:59:43 +01:00
acb87b0c50 Merge branch 'feature/bookdisplay' into develop 2023-03-12 16:58:25 +01:00
e0e9246f32 update jquery.localize to detect arrays 2023-03-12 16:58:15 +01:00
b8786b2f47 Merge branch 'develop' into feature/bookdisplay
# Conflicts:
#	data/spells/spells-grimoire-fr.json
#	index.html
#	spells.html
2023-03-12 14:58:00 +01:00
270dd5ab19 add meta for responsiveness 2023-03-12 02:07:46 +01:00
89e6349c3f generate slideshow based on books length 2023-03-11 23:23:12 +01:00
cbb0a652f7 make view update with slideshow selection ! 2023-03-11 01:50:55 +01:00
7185f78eee Add books cover and slideshow with flickity 2023-03-10 22:59:45 +01:00
7a2a243013 add book button 2023-03-10 01:59:28 +01:00
10ac885cb8 Merge branch 'master' into feature/spells
# Conflicts:
#	lang/main-fr.json
2023-03-10 01:58:27 +01:00
17851ac2e2 make footer in js 2023-03-10 01:56:09 +01:00
c8bddd3ef6 Move json struct to json.schema 2023-03-10 00:54:45 +01:00
b8fa191734 update spell.js + add 3 spells to debug purpose 2023-03-07 21:40:23 +01:00
84f547e3d4 Update spell renderer 2023-03-07 00:06:27 +01:00
ae5a0582a2 fix spell.js 2023-03-06 14:42:32 +01:00
caeae71203 ChatGPT advice 2023-03-06 01:43:27 +01:00
7652f6623c update 2023-03-06 01:22:24 +01:00
b1d30b0010 add lib description to readme 2023-03-05 23:58:36 +01:00
7bfeeb578f add w2ui lib 2023-03-05 23:58:21 +01:00
a1be0791a0 start spell.js 2023-03-05 02:03:48 +01:00
e6b6b93597 add spells json 2023-03-04 12:12:36 +01:00
89 changed files with 141048 additions and 154 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
*.psd
*.pdf

7
.issuetracker Normal file
View file

@ -0,0 +1,7 @@
# Integration with Issue Tracker
#
# (note that '\' need to be escaped).
[issuetracker "Issue Tracker Rule"]
regex = "((?<=#)[0-9]+)"
url = "http://185.216.25.221:3000/lucastucious/fateforge-tool/issues/$1"

15
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://127.0.0.1:5500",
"webRoot": "${workspaceFolder}"
}
]
}

11
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,11 @@
{
"json.schemas": [
{
"fileMatch": [
"data/spells/*.json"
],
"url": "/./.vscode/spells-schemas.json"
}
],
}

270
.vscode/spells-schemas.json vendored Normal file
View file

@ -0,0 +1,270 @@
{
"$comment": "TODO: Subdivide the schema to have a common definition for each data (spellss, books, creatures)",
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/object1678401116.json",
"title": "Root",
"type": "object",
"required": ["spells"],
"properties": {
"spells": {
"$id": "#root/spells",
"title": "spells",
"type": "array",
"default": [],
"items": {
"$id": "#root/spells/items",
"title": "Items",
"type": "object",
"required": [
"recid",
"name",
"source",
"page",
"fateforge_exclusive",
"level",
"school",
"time",
"range",
"components",
"duration",
"desc"
],
"properties": {
"recid": {
"$id": "#root/spells/items/recid",
"title": "Recid",
"type": "integer",
"examples": [0],
"default": 0,
"description": "unique id for the spells, for localization purpose",
"uniqueItems": true,
"autoIncrement": true
},
"name": {
"$id": "#root/spells/items/name",
"title": "Name",
"type": "string",
"default": "",
"examples": ["Acid Arrow"],
"pattern": "^.*$"
},
"source": {
"$id": "#root/spells/items/source",
"title": "Source",
"description": "what's the source. Each enum is a book code",
"type": "string",
"default": "GRI01",
"enum": ["GRI01", "ENC01", "CRE01", "GRI02", "ENC02", "CRE02"],
"examples": ["GRI01"],
"pattern": "^.*$"
},
"page": {
"$id": "#root/spells/items/page",
"description": "in the book, page source",
"title": "Page",
"type": "integer",
"examples": [110],
"default": 0
},
"fateforge_exclusive": {
"$id": "#root/spells/items/fateforge_exclusive",
"description": "is srd or a creation",
"title": "fateforge_exclusive",
"type": "boolean",
"examples": [true],
"default": true
},
"level": {
"$id": "#root/spells/items/level",
"title": "Level",
"type": "integer",
"examples": [2],
"default": 0
},
"school": {
"$id": "#root/spells/items/school",
"description": " 'A' : Abjuration,'C' : Conjuration, 'D': Divination, 'E': Enchantment, 'N': Necromancy, 'T' : Transmutation, 'I' : Illusion, 'V' : Evocation",
"enum": ["A", "C", "D", "E", "I", "N", "T", "V"],
"title": "School",
"type": "string",
"examples": ["E"],
"pattern": "^.*$"
},
"time": {
"$id": "#root/spells/items/time",
"title": "Time",
"type": "array",
"default": [],
"items": {
"$id": "#root/spells/items/time/items",
"title": "Items",
"type": "object",
"required": ["number", "unit"],
"properties": {
"number": {
"$id": "#root/spells/items/time/items/number",
"title": "Number",
"type": "integer",
"examples": [1],
"default": 0
},
"unit": {
"$id": "#root/spells/items/time/items/unit",
"title": "Unit",
"type": "string",
"default": "",
"examples": ["action"],
"pattern": "^.*$"
}
},
"dependentRequired": {
"number": ["unit"]
}
}
},
"range": {
"$id": "#root/spells/items/range",
"title": "Range",
"type": "string"
},
"components": {
"$id": "#root/spells/items/components",
"title": "Components",
"type": "object",
"properties": {
"v": {
"$id": "#root/spells/items/components/v",
"title": "V",
"type": "boolean",
"examples": [true],
"default": true
},
"s": {
"$id": "#root/spells/items/components/s",
"title": "S",
"type": "boolean",
"examples": [true],
"default": true
},
"m": {
"$id": "#root/spells/items/components/m",
"title": "M",
"type": "string",
"default": "",
"examples": ["powdered rhubarb leaf and an adders stomach"],
"pattern": "^.*$"
}
}
},
"duration": {
"$id": "#root/spells/items/duration",
"title": "Duration",
"type": "array",
"default": [],
"items": {
"$id": "#root/spells/items/duration/items",
"title": "Items",
"type": "object",
"required": ["type"],
"properties": {
"type": {
"$id": "#root/spells/items/duration/items/type",
"title": "Type",
"type": "string",
"enum": ["timed", "permanent", "special", "instant"],
"default": "",
"examples": ["instant"],
"pattern": "^.*$"
}
}
}
},
"concentration": {
"$id": "#root/spells/items/concentration",
"title": "Concentration",
"type": "boolean",
"default": false
},
"desc": {
"$id": "#root/spells/items/desc",
"title": "Desc",
"type": "array",
"default": [],
"items": {
"$id": "#root/spells/items/desc/items",
"title": "Items",
"type": "string",
"description": "A description for the entry. Do not copy-paste gameplay infos to prevent copyright",
"default": "",
"examples": [
"A shimmering green arrow streaks toward a target within range and bursts in a spray of acid."
],
"pattern": "^.*$"
}
},
"damageInflict": {
"$id": "#root/spells/items/damageInflict",
"title": "Damageinflict",
"type": "array",
"default": [],
"items": {
"$id": "#root/spells/items/damageInflict/items",
"title": "Items",
"type": "string",
"default": "",
"examples": ["acid"],
"pattern": "^.*$"
}
},
"savingThrow": {
"$id": "#root/spells/items/savingThrow",
"title": "Savingthrow",
"description": "array of saving Throw available",
"type": "array",
"default": [],
"items": {
"$id": "#root/spells/items/savingThrow/items",
"title": "Items",
"type": "string",
"default": "",
"enum": ["Dex", "Str", "Sag", "Cha", "Int", "Con"],
"examples": [""],
"pattern": "^.*$",
"minItems": 1,
"uniqueItems": true
}
},
"miscTags": {
"$id": "#root/spells/items/miscTags",
"title": "Misctags",
"type": "array",
"default": [],
"items": {
"$id": "#root/spells/items/miscTags/items",
"title": "Items",
"type": "string",
"default": "",
"examples": [""],
"pattern": "^.*$"
}
},
"areaTags": {
"$id": "#root/spells/items/areaTags",
"title": "Areatags",
"type": "array",
"default": [],
"items": {
"$id": "#root/spells/items/areaTags/items",
"title": "Items",
"type": "string",
"default": "",
"examples": [""],
"pattern": "^.*$"
}
}
}
}
}
}
}

37
README
View file

@ -1,37 +0,0 @@
## Spells
### JSON structure
| field | type | value |
| ------------------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id | _number_ | unique id for the spell, for localization purpose |
| name | _string_ | spell's name |
| source | _number_ | where the spell is coming from |
| page | _number_ | page source |
| srd | _boolean_ | is this a srd or a creation |
| level | _number_ | spell's level |
| school | _string_ | spell school : "A" : Abjuration,"C" : Conjuration, "D": Divination, "E": Enchantment, "N": Necromancy, "T" : Transmutation, "I" : Illusion, "V" : Evocation |
| time | _array_ | incantation time |
| time.number | _number_ | |
| time.unit | _string_ | |
| range | _module_ | |
| range.type | _string_ | point by default, but can be cone, sphere, cylinder, special |
| range.distance | _module_ | |
| range.distance.type | _string_ | feet or meter or other unit measure |
| range.distance.amount | _number_ | amount of distance in `range.distance.type` |
| components | _module_ | |
| components.v | _boolean_ | verbal component |
| components.s | _boolean_ | somatic component |
| components.m | _string_ | materials components |
| duration | _array_ | |
| duration.type | _string_ | timed, permanent, special or instant |
| duration.duration | _module_ | |
| duration.duration.type | _string_ | minute or hours |
| duration.duration.amount | _number_ | amount of `duration.duration.type` |
| concentration | _boolena_ | does spell need concentration ? |
| desc | _array_ | markdown description of the spell |
| damageInflict | _string_ | |
| conditionInflict | _string_ | |
| savingThrow | _array_ | array of string of saving Throw available |
| miscTags | _array_ | |
| | | |

9
README.md Normal file
View file

@ -0,0 +1,9 @@
# FateforgeTools
A suite of tools for Fateforge players and Masters.
### Lib
- bryntum-grid
- water.css
- data localize
- jquery
- w2ui

52
books.html Normal file
View file

@ -0,0 +1,52 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Books - fateforge.tools</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css" />
<link href="css/all.min.css" rel="stylesheet" />
<script src="lib/flickity.pkgd.min.js"></script>
<script src="lib/flickity.hash.js"></script>
<link rel="icon" type="image/x-icon" href="/img/FateforgeTool_logo_80.png" />
</head>
<body>
<button onclick="changeLangEN()">
<img src="img\flags\en-UK-400.png" width="20" />
English
</button>
<button onclick="changeLangFR()">
<img src="img\flags\fr-FR-400.png" width="20" />
Français
</button>
<a href="index.html">
<h1>FateforgeTools</h1>
</a>
<div class="gallery"></div>
<div class="view-container" style="display: flex;align-items: center;flex-direction: column;">
<h1 id="view-title"></h1>
<p class="book-desc" id="view-desc"></p>
</div>
<link href="css/flickity.css" rel="stylesheet" />
<link href="css/style.css" rel="stylesheet" />
<script type="text/javascript" src="lib/showdown.js"></script>
<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="lib/jquery.localize-dev.js"></script>
<script type="text/javascript" src="js/language.js"></script>
<script type="module" src="js/books.js"></script>
</body>
</html>

137
css/flickity.css Normal file
View file

@ -0,0 +1,137 @@
/*! Flickity v2.3.0
https://flickity.metafizzy.co
---------------------------------------------- */
.flickity-enabled {
position: relative;
}
.flickity-enabled:focus { outline: none; }
.flickity-viewport {
overflow: hidden;
position: relative;
height: 100%;
}
.flickity-slider {
position: absolute;
width: 100%;
height: 100%;
}
/* draggable */
.flickity-enabled.is-draggable {
-webkit-tap-highlight-color: transparent;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.flickity-enabled.is-draggable .flickity-viewport {
cursor: move;
cursor: -webkit-grab;
cursor: grab;
}
.flickity-enabled.is-draggable .flickity-viewport.is-pointer-down {
cursor: -webkit-grabbing;
cursor: grabbing;
}
/* ---- flickity-button ---- */
.flickity-button {
position: absolute;
background: hsla(0, 0%, 100%, 0.75);
border: none;
color: #333;
}
.flickity-button:hover {
background: white;
cursor: pointer;
}
.flickity-button:focus {
outline: none;
box-shadow: 0 0 0 5px #19F;
}
.flickity-button:active {
opacity: 0.6;
}
.flickity-button:disabled {
opacity: 0.3;
cursor: auto;
/* prevent disabled button from capturing pointer up event. #716 */
pointer-events: none;
}
.flickity-button-icon {
fill: currentColor;
}
/* ---- previous/next buttons ---- */
.flickity-prev-next-button {
top: 50%;
width: 44px;
height: 44px;
border-radius: 50%;
/* vertically center */
transform: translateY(-50%);
}
.flickity-prev-next-button.previous { left: 10px; }
.flickity-prev-next-button.next { right: 10px; }
/* right to left */
.flickity-rtl .flickity-prev-next-button.previous {
left: auto;
right: 10px;
}
.flickity-rtl .flickity-prev-next-button.next {
right: auto;
left: 10px;
}
.flickity-prev-next-button .flickity-button-icon {
position: absolute;
left: 20%;
top: 20%;
width: 60%;
height: 60%;
}
/* ---- page dots ---- */
.flickity-page-dots {
position: absolute;
width: 100%;
bottom: -25px;
padding: 0;
margin: 0;
list-style: none;
text-align: center;
line-height: 1;
}
.flickity-rtl .flickity-page-dots { direction: rtl; }
.flickity-page-dots .dot {
display: inline-block;
width: 10px;
height: 10px;
margin: 0 8px;
background: #333;
border-radius: 50%;
opacity: 0.25;
cursor: pointer;
}
.flickity-page-dots .dot.is-selected {
opacity: 1;
}

168
css/style.css Normal file
View file

@ -0,0 +1,168 @@
/**** BOOK 3D***/
*,
:after,
:before {
box-sizing: border-box;
border: 0 solid #e5e7eb;
}
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.book-container {
display: flex;
align-items: center;
justify-content: center;
perspective: 600px;
flex-direction: column;
}
.book-container .book {
width: 200px;
height: 300px;
position: relative;
transform-style: preserve-3d;
transform: rotateY(-30deg);
transition: transform 1s ease;
animation: 1s ease 0s 1 initAnimation-fd6a;
margin-bottom: 3px;
margin-top: 39px;
}
.book-container .book > :first-child {
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 283px;
transform: translateZ(25px);
background-color: #01060f;
border-radius: 0 2px 2px 0;
box-shadow: 5px 5px 20px #aaaaaa9d;
background-color: #01060f;
}
.book-container .book::before {
position: absolute;
content: " ";
left: 0;
top: 3px;
width: 48px;
height: 277px;
transform: translateX(172px) rotateY(90deg);
background: linear-gradient(
90deg,
#fff 0%,
#f9f9f9 5%,
#fff 10%,
#f9f9f9 15%,
#fff 20%,
#f9f9f9 25%,
#fff 30%,
#f9f9f9 35%,
#fff 40%,
#f9f9f9 45%,
#fff 50%,
#f9f9f9 55%,
#fff 60%,
#f9f9f9 65%,
#fff 70%,
#f9f9f9 75%,
#fff 80%,
#f9f9f9 85%,
#fff 90%,
#f9f9f9 95%,
#fff 100%
);
}
.book-container .book:hover {
transform: rotateY(0deg);
}
.book-container .book::after {
position: absolute;
top: 0;
left: 0;
content: " ";
width: 200px;
height: 283px;
transform: translateZ(-25px);
background-color: #01060f;
border-radius: 0 2px 2px 0;
box-shadow: -05px 0 20px 10px #aaaaaa9d;
}
.book-container .book-title {
}
/**** Slideshow***/
.gallery {
background: #01060f00;
margin-bottom: 40px;
}
.gallery-cell {
width: 66%;
margin-right: 10px;
counter-increment: gallery-cell;
}
.flickity-viewport {
background-color: #01060f00;
}
.flickity-page-dots .dot {
background: #0093cd;
}
.flickity-prev-next-button {
border-radius: 6px;
}
.flickity-button {
background: #588597;
}
/* Spells */
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: stretch;
}
.list-col {
width: 75%;
float: left;
}
.view-col {
width: 25%;
float: left;
}
@media screen and (max-width: 768px) {
.list-col,
.view-col {
width: 100%;
float: none;
}
.list-col{
zoom:70%
};
}
.w2ui-grid-data {
color: black;
word-wrap: normal;
}
.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data > div {
overflow: visible;
white-space: break-spaces;
}
.w2ui-grid .w2ui-grid-body table {
}
body.spells{
max-width: 100%;
}

1691
css/water.css Normal file

File diff suppressed because it is too large Load diff

13430
data/spells/csvjson.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,3 @@
{ "GRI-fr": "spells-grimoire-fr.json"
{ "GRI1-fr": "spells-grimoire-fr.json",
"GRI1-en":"spells-grimoire-en.json"
}

160
data/spells/notes.md Normal file
View file

@ -0,0 +1,160 @@
# Notes
Pour transformer le json d'origine, on itérera sur le fichier pour le scinder en deux
on utilise le tools ici : https://jsoneditoronline.org/#right=cloud.f0a19b92543d4c7fa1bdb58a913707e8&left=local.xoliwi
##### Pour avoir le json en francais:
*Cette version de la fonction query utilise une récursion pour explorer les sous-objets de chaque objet dans la liste data. La fonction checkKey transforme les clés se terminant par "_fr" en supprimant cette terminaison, et elle vérifie si la clé contient un nombre avant de traiter ses sous-objets. Si la clé ne contient pas de nombre, la fonction ne traite pas les sous-objets de cette clé.*
```js
function query(data) {
function checkKey(obj) {
obj = _.mapKeys(obj, (value, key) => {
if (_.endsWith(key, "_fr") ) {
return key.slice(0, -3);
}
return key;
});
for (const [key, value] of Object.entries(obj)) {
if (_.isObject(value) && isNaN(value) ) {
obj[key] = checkKey(value);
}
}
return _.pickBy(obj, (value, key) => !_.endsWith(key, "_en"));
}
return _.chain(data)
.map(obj => checkKey(obj))
.value();
}
```
##### Pour deplacer les classes dans un objet "classes"
```js
function query(data) {
return _.chain(data)
.map(item => {
const {
bard = "",
cleric = "",
druid = "",
paladin = "",
ranger = "",
scholar = "",
sorcerer = "",
warlock = "",
wizard = "",
...rest
} = item;
return {
...rest,
classes: {
bard,
cleric,
druid,
paladin,
ranger,
scholar,
sorcerer,
warlock,
wizard
}
};
})
.value();
}
```
##### pour renommer les components :
```js
function query(data) {
return _.chain(data)
.map(obj => {
// Renommer les clés spécifiées
obj = _.mapKeys(obj, (value, key) => {
switch(key) {
case "composite_oral":
return "v";
case "composite_moves":
return "s";
case "composite_material":
return "m";
case "material_components_fr":
return "m_fr";
case "material_components_en":
return "m_en";
case "composite_material_destroyed":
return "m_destroyed"
default:
return key;
}
});
return obj;
})
.value();
}
```
##### Pour deplacer les components dans un objet "components"
```js
function query(data) {
return _.chain(data)
.map(item => {
const {
m_destroyed = "",
v = "",
s= "",
m= "",
m_fr= "",
m_en= "",
...rest
} = item;
return {
...rest,
components: {
m_destroyed,
v,
s,
m,
m_fr,
m_en,
}
};
})
.value();
}
```
##### Pour ajouter recid et source
```js
function query(data) {
return _.chain(data)
.map((item, index) => _.merge({ recid: index }, item))
.map((item, index) => _.merge({ source: "GRI01" }, item))
.value();
}
```
##### Pour transformer les clé 0/1 en true/false
```js
function query(data) {
return _.chain(data)
.map((item) => ({
...item,
composite_material_destroyed: item.composite_material_destroyed = "x"? true : false,
composite_oral: item.composite_oral == 1? true : false,
has_higher_level_details: item.has_higher_level_details == 1? true : false,
ritual: item.ritual == 1? true : false,
dragons_exclusive: item.dragons_exclusive == 1? true : false,
composite_moves: item.composite_moves == 1? true : false,
composite_material: item.composite_material == 1? true : false,
corrupted: item.corrupted == 1? true : false,
concentration: item.concentration == 1? true : false,
}))
.value();
}
```

View file

@ -1,9 +1,9 @@
{
"spell": [
{
"id": 0,
"recid": 0,
"name": "Acid Arrow",
"source": "GRI",
"source": "GRI01",
"page": 110,
"srd": true,
"level": 2,
@ -35,14 +35,13 @@
"A shimmering green arrow streaks toward a target within range and bursts in a spray of acid."
],
"damageInflict": ["acid"],
"savingThrow": [""],
"miscTags": ["", ""],
"areaTags": ["", ""]
},
{
"id": 1,
"recid": 1,
"name": "Acid Blob",
"source": "GRI",
"source": "GRI01",
"page": 110,
"srd": false,
"level": 1,
@ -73,7 +72,44 @@
"A yellowish bubble shoots from your pointed finger toward a creature of your choice within range"
],
"damageInflict": ["acid"],
"savingThrow": [""],
"miscTags": ["", ""],
"areaTags": ["", ""]
},
{
"recid": 2,
"name": "Acid Splash",
"source": "GRI01",
"page": 126,
"srd": true,
"level": 1,
"school": "I",
"time": [
{
"number": 1,
"unit": "action"
}
],
"range": {
"type": "point",
"distance": {
"type": "feet",
"amount": 60
}
},
"components": {
"v": true,
"s": true
},
"duration": [
{
"type": "instant"
}
],
"desc": [
"You hurl a bubble of acid. "
],
"damageInflict": ["acid"],
"savingThrow": ["Dex"],
"miscTags": ["", ""],
"areaTags": ["", ""]
}

View file

@ -1,9 +1,9 @@
{
"spell": [
{
"id": 0,
"recid": 0,
"name": "Flèche Acide",
"source": "GRI",
"source": "GRI01",
"page": 188,
"srd": true,
"level": 2,
@ -40,9 +40,9 @@
"areaTags": ["", ""]
},
{
"id": 1,
"recid": 1,
"name": "Bille Acide",
"source": "GRI",
"source": "GRI01",
"page": 134,
"srd": false,
"level": 1,
@ -76,6 +76,44 @@
"savingThrow": ["Constitution"],
"miscTags": ["", ""],
"areaTags": ["", ""]
},
{
"recid": 2,
"name": "Aspersion acide",
"source": "GRI01",
"page": 126,
"srd": true,
"level": 1,
"school": "I",
"time": [
{
"number": 1,
"unit": "action"
}
],
"range": {
"type": "point",
"distance": {
"type": "m",
"amount": 18
}
},
"components": {
"v": true,
"s": true
},
"duration": [
{
"type": "instant"
}
],
"desc": [
"Vous lancez une bulle dacide. "
],
"damageInflict": ["acid"],
"savingThrow": ["Dexterity"],
"miscTags": ["", ""],
"areaTags": ["", ""]
}
]
}

25
footer.html Normal file
View file

@ -0,0 +1,25 @@
<small style="text-align: center;">
<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/">
<a property="dct:title" rel="cc:attributionURL" href="http://fateforge.tool">fateforge.tool</a>
by <span property="cc:attributionName">Lucastucious</span> is licensed
under
<a href="http://creativecommons.org/licenses/by-nc/4.0/?ref=chooser-v1" target="_blank"
rel="license noopener noreferrer" style="display: inline-block">CC BY-NC 4.0<img style="
height: 22px !important;
margin-left: 3px;
vertical-align: text-bottom;
" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" /><img style="
height: 22px !important;
margin-left: 3px;
vertical-align: text-bottom;
" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" /><img style="
height: 22px !important;
margin-left: 3px;
vertical-align: text-bottom;
" src="https://mirrors.creativecommons.org/presskit/icons/nc.svg?ref=chooser-v1" /></a>
</p>
<div class="CUVD">
<p data-localize="CUVD">CUVD
<p data-localize="link"></a>
</div>
</small>

BIN
img/books/ADV1_BC_EN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

BIN
img/books/ADV1_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

BIN
img/books/Box_DR.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

BIN
img/books/Box_DR_2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
img/books/Box_GV.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

BIN
img/books/Box_GV_2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

BIN
img/books/Box_GV_3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

BIN
img/books/CRE1_BC_EN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

BIN
img/books/CRE1_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 MiB

BIN
img/books/CRE1_RD_EN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

BIN
img/books/CRE2_BC_EN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

BIN
img/books/CRE2_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

BIN
img/books/CRE2_DR_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

BIN
img/books/ECR_GV.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

BIN
img/books/ENC1_BC_EN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

BIN
img/books/ENC1_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

BIN
img/books/GRI1_BC_EN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

BIN
img/books/GRI1_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

BIN
img/books/GRI1_RD_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 MiB

BIN
img/books/GUI1_BC_EN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

BIN
img/books/GUI1_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

BIN
img/books/GUI2_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

BIN
img/books/LEG1_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 MiB

BIN
img/books/LEG2_BC_EN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
img/books/LEG2_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

BIN
img/books/LEG3_BC_EN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

BIN
img/books/LEG3_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

BIN
img/books/LEG4_BC_EN.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

BIN
img/books/LEG4_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

BIN
img/books/LEG6_BC_FR.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

BIN
img/flags/en-UK-400.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
img/flags/fr-FR-400.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

View file

@ -1,68 +1,57 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>fateforge-tools</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css" />
<link rel="stylesheet" href="css/water.css" />
<link href="css/all.min.css" rel="stylesheet" />
<link rel="icon" type="image/x-icon" href="/img/FateforgeTool_logo_80.png">
<link rel="icon" type="image/png" href="/img/FateforgeTool_logo_80.png">
<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="lib/jquery.localize-dev.js"></script>
</head>
<body>
<button onclick="changeLangEN()">English</button>
<button onclick="changeLangFR()">French</button>
<header>
<button onclick="changeLangEN()">English</button>
<button onclick="changeLangFR()">🇫🇷 Français</button>
<h1>FateforgeTools</h1>
<div data-localize="desc">
A suite of tools for Fateforge players and Masters.
</div>
<a href="index.html">
<h1>FateforgeTools</h1>
</a>
<div data-localize="desc">
A suite of tools for Fateforge players and Masters.
</div>
</header>
<br>
<div class="tools">
<button onclick="window.location.href='spells.html';">
<div><i class="fa-solid fa-wand-sparkles"></i></div>
<div data-localize="btn-spells">spells</div>
</button>
<button onclick="window.location.href='monsters.html';">
<button onclick="window.location.href='monsters.html';" disabled>
<div><i class="fa-solid fa-dragon"></i></div>
<div data-localize="btn-monsters">monsters</div>
</button>
<button onclick="window.location.href='items.html';">
<button onclick="window.location.href='items.html';" disabled>
<div><i class="fa-solid fa-hand-sparkles"></i></div>
<div data-localize="btn-items">items</div>
</button>
<button onclick="window.location.href='books.html';">
<div><i class="fa-solid fa-book"></i></div>
<div data-localize="btn-books">books</div>
</button>
</div>
<footer style="text-align: center;">
<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/">
<a property="dct:title" rel="cc:attributionURL" href="http://fateforge.tool">fateforge.tool</a>
by <span property="cc:attributionName">Lucas Peter</span> is licensed
under
<a href="http://creativecommons.org/licenses/by-nc/4.0/?ref=chooser-v1" target="_blank"
rel="license noopener noreferrer" style="display: inline-block">CC BY-NC 4.0<img style="
height: 22px !important;
margin-left: 3px;
vertical-align: text-bottom;
" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" /><img style="
height: 22px !important;
margin-left: 3px;
vertical-align: text-bottom;
" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" /><img style="
height: 22px !important;
margin-left: 3px;
vertical-align: text-bottom;
" src="https://mirrors.creativecommons.org/presskit/icons/nc.svg?ref=chooser-v1" /></a>
</p>
<div class="CUVD" > <p data-localize="CUVD">CUVD
<p data-localize="link"></a></div>
</footer>
<div id="footer"></div>
<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="lib/jquery.localize.js"></script>
<script type="text/javascript" src="js/language.js"></script>
<script type="text/javascript" src="js/footer.js"></script>
<script async type="text/javascript" src="js/language.js"></script>
<script src="https://kit.fontawesome.com/126cdd0e29.js" crossorigin="anonymous"></script>
<script rel="preload" src="https://kit.fontawesome.com/126cdd0e29.js" crossorigin="anonymous"></script>
</body>

52
js/books.js Normal file
View file

@ -0,0 +1,52 @@
import data from "/lang/books-en.json" assert { type: "json" };
console.log(data);
const gallery = document.getElementsByClassName("gallery")[0];
for (const key in data) {
console.log(data[key].code, data[key].title, data[key].cover);
var bookHTML = `<div class="gallery-cell" id="${data[key].code}">
<div class="book-container">
<div class="book">
<img data-localize="${data[key].code}.cover" />
</div>
<div data-localize="${data[key].code}.title" class="book-title">${data[key].title}</div>
</div>
</div>
`;
gallery.insertAdjacentHTML("afterbegin", bookHTML);
};
var lastbook;
var currentbook;
var flkty = new Flickity(".gallery", {
freeScroll: true,
wrapAround: true,
hash: true, // options
});
refreshBooks();
currentbook = document.getElementsByClassName("gallery-cell is-selected")[0].getAttribute("id");
//TODO: Fill view-container with books
fillBookView();
flkty.on("select", function (index) {
currentbook = document.getElementsByClassName("gallery-cell is-selected")[0].getAttribute("id");
if (currentbook == lastbook) {
return;
}
//TODO: Fill view-container with books
fillBookView();
});
/*flkty.on("settle", function (index) {
console.log("Flickity settled at " + index);
refreshBooks();
});*/
function fillBookView(){
setLocalizeDataAttr("view-title", currentbook + ".title");
setLocalizeDataAttr("view-desc", currentbook + ".desc");
lastbook = currentbook;
console.log(currentLang);
refreshBooks();
}

6
js/footer.js Normal file
View file

@ -0,0 +1,6 @@
$(function () {
$("#footer").load("footer.html",function (responseTxt, statusTxt, xhr) {
console.log("bla");
$("[data-localize]").localize("main", { pathPrefix: "lang" });
});
});

View file

@ -1,17 +1,46 @@
// In a browser where the language is set to French
$("[data-localize]").localize("main", { pathPrefix: "lang" });
$("[data-localize]")
.localize("main", { pathPrefix: "lang" })
.localize("books", { pathPrefix: "lang" });
var currentLang;
// You can also override the language detection, and pass in a language code
//$("[data-localize]").localize("main", { language: "fr" });
function changeLangFR() {
$("[data-localize]").localize("main", {
$("[data-localize]")
.localize("main", {
pathPrefix: "lang",
language: "fr",
})
.localize("books", {
pathPrefix: "lang",
language: "fr",
});
currentLang = "fr";
}
// This code defines a function that sets the language to English.
function changeLangEN() {
$("[data-localize]")
.localize("main", {
pathPrefix: "lang",
language: "en",
})
.localize("books", {
pathPrefix: "lang",
language: "en",
});
currentLang = "en";
}
function refreshBooks() {
$("[data-localize]").localize("books", {
pathPrefix: "lang",
language: "fr",
language: currentLang,
});
}
function changeLangEN() {
$("[data-localize]").localize("main", {
pathPrefix: "lang",
language: "en",
});
}
// Function to fill a data-localize attribute and update DOM
function setLocalizeDataAttr(className, dataValue) {
$("#" + className).data("localize", dataValue).attr("data-localize", dataValue);
}

View file

@ -0,0 +1,100 @@
// Get the spell json based on choosen language defaultLanguage
var jsonsource = "".concat(
"../data/spells/spells-grimoire-",
$.defaultLanguage.slice(0, 2),
".json"
);
var alldata;
// Fetch data from server
fetch(jsonsource)
.then((response) => response.json())
.then((data) => {
// load fetched data into grid
alldata = data.spell;
console.log(alldata);
//document.getElementById("spell-list")
var grid = $("#spell-list").w2grid({
name: "Spells",
box: "#spellgrid",
show: {
header: false,
toolbar: true,
footer: false,
/* selectColumn: true, */
},
multiSelect: true,
liveSearch: true,
multiSearch: true,
fixedBody: false,
records: alldata,
columns: [
{
field: "name",
text: "Name",
sortable: true,
resizable: true,
searchable: { operator: "contains" },
},
{
field: "source",
text: "Source",
sortable: true,
tooltip: "Which book is this from ?",
searchable: { operator: "contains" },
render(record, extra) {
return (
'<a href="http://w2ui.com" target="_blank" title="Click Me!"><u>' +
extra.value +
"</u></a>"
);
},
},
{ field: "page", text: "Page", sortable: true },
{ field: "level", text: "Level", sortable: true, size: 65 },
{ field: "school", text: "School", sortable: true },
{
field: "components",
text: '<span data-localize="gridColumns.components">Components</span>',
render(record) {
var v = record.components.v
? '<span data-localize="verbal">V</span>'
: "";
var s = record.components.s ? '<span data-localize="somatic">S</span>' : "";
var m = record.components.m ? '<span data-localize="material">M</span>' : "";
//var m = record.components.m ? record.components.m : "";
var vs=v.concat(', ',s);
return vs.concat(', ',m);
if ((record.components.v = true)) {
console.log(record.components);
}
},
},
{ field: "duration", text: "Duration" },
],
async onSelect(event) {
await event.complete;
console.log("select", event.detail, this.getSelection());
},
onClick(event) {
let record = this.get(event.detail.recid);
//grid2.clear()
/*grid2.add([
{ recid: 0, name: 'ID:', value: record.recid },
{ recid: 1, name: 'First Name:', value: record.fname },
{ recid: 2, name: 'Last Name:', value: record.lname },
{ recid: 3, name: 'Email:', value: record.email },
{ recid: 4, name: 'Date:', value: record.sdate }
])*/
console.log(record);
},
async onRefresh(event) {
await event.complete;
console.log("Le tableau est généré et le DOM est modifié.");
$("[data-localize]").localize("main", { pathPrefix: "lang" }); // mettre votre script ici
}
})
});

38
lang/books-en.json Normal file
View file

@ -0,0 +1,38 @@
{
"ADV1": {
"code": "ADV1",
"title": "Adventurers",
"desc": [
"*Découvrez lunivers dEana et ses multiples civilisations hautes en couleur, retrouvez les portails perdus des Voyageurs, gravissez les marches de la Forge du destin et mesurez-vous aux Dragons-dieux !* **Aventuriers** est le premier volume de la gamme de jeu de rôle Dragons. Destiné aux joueurs et au meneur, il se compose de trois parties :",
"**Création de personnage.** Déterminez avec votre meneur dans quelles conditions votre personnage accède à léveil à la magie, et faites votre choix parmi toutes les options qui soffrent à vous, notamment : neuf espèces jouables ; dix-huit civilisations ; un pas-à-pas pour concevoir des historiques personnalisés ; treize classes dont le lettré, un érudit inventif et capable dagir même dans les régions privées de magie ; de nombreux dons pour accompagner lévolution de votre héros.",
"**Vie quotidienne.** Découvrez la mythique Cité franche, ainsi que toutes les règles permettant de donner corps aux voyages et à la vie quotidienne. Le mystère, lexploration et la découverte sont au cœur de lexpérience du jeu. Que vous vous déplaciez à pied, en bateau ou en nefélytre, répondez à lappel de laventure !",
"**Règles du jeu.** Le système est organisé autour de quatre pôles : les caractéristiques, laventure, le combat et la santé. Les règles optionnelles sont présentées à laide dun système modulaire permettant à chaque meneur de définir son propre style de jeu."
],
"physical-link": "https://www.philibertnet.com/fr/dragons/62090-dragons-1-aventuriers-livre-de-base-9782919256365.html",
"pdf-link": "https://www.drivethrurpg.com/product/422886/Dragons--1--Livre-de-base--Aventuriers",
"author": ["Team Agate"],
"published-date": "01/04/2018",
"cf-date": "14/03/2016",
"cover":{
"src": "img\\books\\ADV1_BC_EN.png",
"alt": "ADV1_BC_EN",
"title": "ADV1_BC_EN"
}
},
"CRE2": {
"book": "<div class='book'> <img src='img\\books\\CRE2_BC_EN.png'></div><div class='book-title'>Creature : Netherworld</div>",
"code": "CRE2",
"title": "Creatures : Netherworld",
"desc": ["*"],
"physical-link": "",
"pdf-link": "",
"author": ["Team Agate"],
"published-date": "",
"cf-date": "",
"cover": {
"src": "img\\books\\CRE2_BC_EN.png",
"alt": "CRE2_BC_EN",
"title": "CRE2_BC_EN"
}
}
}

38
lang/books-fr.json Normal file
View file

@ -0,0 +1,38 @@
{
"ADV1": {
"code": "ADV1",
"title": "Aventuriers",
"desc": [
"*Découvrez lunivers dEana et ses multiples civilisations hautes en couleur, retrouvez les portails perdus des Voyageurs, gravissez les marches de la Forge du destin et mesurez-vous aux Dragons-dieux !* **Aventuriers** est le premier volume de la gamme de jeu de rôle Dragons. Destiné aux joueurs et au meneur, il se compose de trois parties :",
"**Création de personnage.** Déterminez avec votre meneur dans quelles conditions votre personnage accède à léveil à la magie, et faites votre choix parmi toutes les options qui soffrent à vous, notamment : neuf espèces jouables ; dix-huit civilisations ; un pas-à-pas pour concevoir des historiques personnalisés ; treize classes dont le lettré, un érudit inventif et capable dagir même dans les régions privées de magie ; de nombreux dons pour accompagner lévolution de votre héros.",
"**Vie quotidienne.** Découvrez la mythique Cité franche, ainsi que toutes les règles permettant de donner corps aux voyages et à la vie quotidienne. Le mystère, lexploration et la découverte sont au cœur de lexpérience du jeu. Que vous vous déplaciez à pied, en bateau ou en nefélytre, répondez à lappel de laventure !",
"**Règles du jeu.** Le système est organisé autour de quatre pôles : les caractéristiques, laventure, le combat et la santé. Les règles optionnelles sont présentées à laide dun système modulaire permettant à chaque meneur de définir son propre style de jeu."
],
"physical-link": "https://www.philibertnet.com/fr/dragons/62090-dragons-1-aventuriers-livre-de-base-9782919256365.html",
"pdf-link": "https://www.drivethrurpg.com/product/422886/Dragons--1--Livre-de-base--Aventuriers",
"author": ["Team Agate"],
"published-date": "01/04/2018",
"cf-date": "14/03/2016",
"cover":{
"src": "img\\books\\ADV1_BC_FR.png",
"alt": "ADV1_BC_FR",
"title": "ADV1_BC_FR"
}
},
"CRE2": {
"code": "CRE2",
"title": "Créatures : Inframonde",
"desc": ["*"],
"physical-link": "",
"pdf-link": "",
"author": ["Team Agate"],
"published-date": "",
"cf-date": "",
"cover": {
"src": "img\\books\\CRE2_BC_FR.png",
"alt": "CRE2_BC_FR",
"title": "CRE2_BC_FR"
}
},
"book-CRE2": "<div class='book'> <img src='img\\books\\CRE2_BC_FR.png'></div><div class='book-title'>Créature : Inframonde</div>"
}

View file

@ -8,5 +8,11 @@
"btn-monsters": "Creatures",
"btn-items": "Magic Items",
"CUVD": "Unofficial site for Fateforge RPG. Uses copyrighted content © Agate RPG, courtesy of the publisher under the CUVD license.",
"link": "Join the community: <a href='https://fateforge.org/en'>https://fateforge.org/en</a>"
"link": "Join the community: <a href='https://fateforge.org/en'>https://fateforge.org/en</a>",
"verbal": "Verbal",
"somatic": "Somatic",
"gridColumns":{
"components": "Components"
},
"btn-books": "Books"
}

View file

@ -7,6 +7,7 @@
"btn-spells": "Sorts",
"btn-monsters": "Créatures",
"btn-items": "Objets Magiques",
"btn-books": "Livres",
"CUVD": "Site non-officiel pour Dragons. Utilise des contenus protégés par la propriété intellectuelle © Agate RPG, avec laimable permission de léditeur dans le cadre de la licence CUVD.",
"link": "Rejoignez la communauté : <a href='www.dragons-rpg.com'>www.dragons-rpg.com</a>",
"verbal": "Verbale",

121
lib/flickity.hash.js Normal file
View file

@ -0,0 +1,121 @@
/*!
* Flickity hash v1.0.3
* Enable hash navigation for Flickity
*/
/*jshint browser: true, undef: true, unused: true, strict: true*/
( function( window, factory ) {
// universal module definition
/*jshint strict: false */ /*globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'flickity/js/index',
], factory );
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
require('flickity')
);
} else {
// browser global
factory(
window.Flickity
);
}
}( window, function factory( Flickity ) {
'use strict';
Flickity.createMethods.push('_createHash');
var proto = Flickity.prototype;
proto._createHash = function() {
if ( !this.options.hash ) {
return;
}
this.connectedHashLinks = [];
// hash link listener
// use HTML5 history pushState to prevent page scroll jump
this.onHashLinkClick = function( event ) {
event.preventDefault();
this.selectCell( event.currentTarget.hash );
history.replaceState( null, '', event.currentTarget.hash );
}.bind( this );
// events
this.on( 'activate', this.activateHash );
this.on( 'deactivate', this.deactivateHash );
};
proto.activateHash = function() {
this.on( 'change', this.onChangeHash );
// overwrite initialIndex
if ( this.options.initialIndex === undefined && location.hash ) {
var cell = this.queryCell( location.hash );
if ( cell ) {
this.options.initialIndex = this.getCellSlideIndex( cell );
}
}
this.connectHashLinks();
};
proto.deactivateHash = function() {
this.off( 'change', this.onChangeHash );
this.disconnectHashLinks();
};
proto.onChangeHash = function() {
var id = this.selectedElement.id;
if ( id ) {
var url = '#' + id;
history.replaceState( null, '', url );
}
};
proto.connectHashLinks = function() {
var links = document.querySelectorAll('a');
for ( var i=0; i < links.length; i++ ) {
this.connectHashLink( links[i] );
}
};
// used to test if link is on same page
var proxyLink = document.createElement('a');
proto.connectHashLink = function( link ) {
if ( !link.hash ) {
return;
}
// check that link is for the same page
proxyLink.href = link.href;
if ( proxyLink.pathname != location.pathname ) {
return;
}
var cell = this.queryCell( link.hash );
if ( !cell ) {
return;
}
link.addEventListener( 'click', this.onHashLinkClick );
this.connectedHashLinks.push( link );
};
proto.disconnectHashLinks = function() {
this.connectedHashLinks.forEach( function( link ) {
link.removeEventListener( 'click', this.onHashLinkClick );
}, this );
this.connectedHashLinks = [];
};
// ----- ----- //
return Flickity;
}));

56
lib/flickity.pkgd.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,3 @@
/*
Copyright (c) Jim Garvin (http://github.com/coderifous), 2008.
Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
@ -7,18 +6,39 @@ http://github.com/coderifous/jquery-localize
Based off of Keith Wood's Localisation jQuery plugin.
http://keith-wood.name/localisation.html
*/
(function($) {
(function ($) {
var normaliseLang;
normaliseLang = function(lang) {
lang = lang.replace(/_/, '-').toLowerCase();
normaliseLang = function (lang) {
lang = lang.replace(/_/, "-").toLowerCase();
if (lang.length > 3) {
lang = lang.substring(0, 3) + lang.substring(3).toUpperCase();
}
return lang;
};
$.defaultLanguage = normaliseLang(navigator.languages && navigator.languages.length > 0 ? navigator.languages[0] : navigator.language || navigator.userLanguage);
$.localize = function(pkg, options) {
var defaultCallback, deferred, fileExtension, intermediateLangData, jsonCall, lang, loadLanguage, localizeElement, localizeForSpecialKeys, localizeImageElement, localizeInputElement, localizeOptgroupElement, notifyDelegateLanguageLoaded, regexify, setAttrFromValueForKey, setTextFromValueForKey, valueForKey, wrappedSet;
$.defaultLanguage = normaliseLang(
navigator.languages && navigator.languages.length > 0
? navigator.languages[0]
: navigator.language || navigator.userLanguage
);
$.localize = function (pkg, options) {
var defaultCallback,
deferred,
fileExtension,
intermediateLangData,
jsonCall,
lang,
loadLanguage,
localizeElement,
localizeForSpecialKeys,
localizeImageElement,
localizeInputElement,
localizeOptgroupElement,
notifyDelegateLanguageLoaded,
regexify,
setAttrFromValueForKey,
setTextFromValueForKey,
valueForKey,
wrappedSet;
if (options == null) {
options = {};
}
@ -26,7 +46,7 @@ http://keith-wood.name/localisation.html
intermediateLangData = {};
fileExtension = options.fileExtension || "json";
deferred = $.Deferred();
loadLanguage = function(pkg, lang, level) {
loadLanguage = function (pkg, lang, level) {
var file;
if (level == null) {
level = 1;
@ -42,27 +62,36 @@ http://keith-wood.name/localisation.html
}
break;
case 2:
file = "" + pkg + "-" + (lang.split('-')[0]) + "." + fileExtension;
file = "" + pkg + "-" + lang.split("-")[0] + "." + fileExtension;
return jsonCall(file, pkg, lang, level);
case 3:
file = "" + pkg + "-" + (lang.split('-').slice(0, 2).join('-')) + "." + fileExtension;
file =
"" +
pkg +
"-" +
lang.split("-").slice(0, 2).join("-") +
"." +
fileExtension;
return jsonCall(file, pkg, lang, level);
default:
return deferred.resolve();
}
};
jsonCall = function(file, pkg, lang, level) {
jsonCall = function (file, pkg, lang, level) {
var ajaxOptions, errorFunc, successFunc;
if (options.pathPrefix != null) {
file = "" + options.pathPrefix + "/" + file;
}
successFunc = function(d) {
successFunc = function (d) {
$.extend(intermediateLangData, d);
notifyDelegateLanguageLoaded(intermediateLangData);
return loadLanguage(pkg, lang, level + 1);
};
errorFunc = function() {
if (level === 2 && lang.indexOf('-') > -1) {
errorFunc = function (xhr, status, error) {
if (status === "error" && xhr.status === 404) {
// Le fichier n'existe pas
console.log("Le fichier " + file + " n'existe pas.");
} else if (level === 2 && lang.indexOf("-") > -1) {
return loadLanguage(pkg, lang, level + 1);
} else if (options.fallback && options.fallback !== lang) {
return loadLanguage(pkg, options.fallback);
@ -74,25 +103,30 @@ http://keith-wood.name/localisation.html
async: true,
timeout: options.timeout != null ? options.timeout : 500,
success: successFunc,
error: errorFunc
error: errorFunc,
statusCode: {
404: function() {
console.log("Le fichier " + file + " n'existe pas.");
}
}
};
if (window.location.protocol === "file:") {
ajaxOptions.error = function(xhr) {
ajaxOptions.error = function (xhr) {
return successFunc($.parseJSON(xhr.responseText));
};
}
return $.ajax(ajaxOptions);
};
notifyDelegateLanguageLoaded = function(data) {
notifyDelegateLanguageLoaded = function (data) {
if (options.callback != null) {
return options.callback(data, defaultCallback);
} else {
return defaultCallback(data);
}
};
defaultCallback = function(data) {
defaultCallback = function (data) {
$.localize.data[pkg] = data;
return wrappedSet.each(function() {
return wrappedSet.each(function () {
var elem, key, value;
elem = $(this);
key = elem.data("localize");
@ -103,15 +137,23 @@ http://keith-wood.name/localisation.html
}
});
};
localizeElement = function(elem, key, value) {
if (elem.is('input')) {
localizeElement = function (elem, key, value) {
if (elem.is("input")) {
localizeInputElement(elem, key, value);
} else if (elem.is('textarea')) {
} else if (elem.is("textarea")) {
localizeInputElement(elem, key, value);
} else if (elem.is('img')) {
} else if (elem.is("img")) {
localizeImageElement(elem, key, value);
} else if (elem.is('optgroup')) {
} else if (elem.is("optgroup")) {
localizeOptgroupElement(elem, key, value);
} else if ($.isArray(value)) {
elem.empty();
for (const key in value) {
var converter = new showdown.Converter(),
text = value[key],
converted = converter.makeHtml(text);
elem.append(converted);
}
} else if (!$.isPlainObject(value)) {
elem.html(value);
}
@ -119,7 +161,7 @@ http://keith-wood.name/localisation.html
return localizeForSpecialKeys(elem, value);
}
};
localizeInputElement = function(elem, key, value) {
localizeInputElement = function (elem, key, value) {
var val;
val = $.isPlainObject(value) ? value.value : value;
if (elem.is("[placeholder]")) {
@ -128,19 +170,19 @@ http://keith-wood.name/localisation.html
return elem.val(val);
}
};
localizeForSpecialKeys = function(elem, value) {
localizeForSpecialKeys = function (elem, value) {
setAttrFromValueForKey(elem, "title", value);
setAttrFromValueForKey(elem, "href", value);
return setTextFromValueForKey(elem, "text", value);
};
localizeOptgroupElement = function(elem, key, value) {
localizeOptgroupElement = function (elem, key, value) {
return elem.attr("label", value);
};
localizeImageElement = function(elem, key, value) {
localizeImageElement = function (elem, key, value) {
setAttrFromValueForKey(elem, "alt", value);
return setAttrFromValueForKey(elem, "src", value);
};
valueForKey = function(key, data) {
valueForKey = function (key, data) {
var keys, value, _i, _len;
keys = key.split(/\./);
value = data;
@ -150,37 +192,43 @@ http://keith-wood.name/localisation.html
}
return value;
};
setAttrFromValueForKey = function(elem, key, value) {
setAttrFromValueForKey = function (elem, key, value) {
value = valueForKey(key, value);
if (value != null) {
return elem.attr(key, value);
}
};
setTextFromValueForKey = function(elem, key, value) {
setTextFromValueForKey = function (elem, key, value) {
value = valueForKey(key, value);
if (value != null) {
return elem.text(value);
}
};
regexify = function(string_or_regex_or_array) {
regexify = function (string_or_regex_or_array) {
var thing;
if (typeof string_or_regex_or_array === "string") {
return "^" + string_or_regex_or_array + "$";
} else if (string_or_regex_or_array.length != null) {
return ((function() {
return (function () {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = string_or_regex_or_array.length; _i < _len; _i++) {
for (
_i = 0, _len = string_or_regex_or_array.length;
_i < _len;
_i++
) {
thing = string_or_regex_or_array[_i];
_results.push(regexify(thing));
}
return _results;
})()).join("|");
})().join("|");
} else {
return string_or_regex_or_array;
}
};
lang = normaliseLang(options.language ? options.language : $.defaultLanguage);
lang = normaliseLang(
options.language ? options.language : $.defaultLanguage
);
if (options.skipLanguage && lang.match(regexify(options.skipLanguage))) {
deferred.resolve();
} else {
@ -190,5 +238,5 @@ http://keith-wood.name/localisation.html
return wrappedSet;
};
$.fn.localize = $.localize;
return $.localize.data = {};
return ($.localize.data = {});
})(jQuery);

View file

@ -1,4 +0,0 @@
/*! Localize - v0.2.0 - 2016-10-13
* https://github.com/coderifous/jquery-localize
* Copyright (c) 2016 coderifous; Licensed MIT */
!function(a){var b;return b=function(a){return a=a.replace(/_/,"-").toLowerCase(),a.length>3&&(a=a.substring(0,3)+a.substring(3).toUpperCase()),a},a.defaultLanguage=b(navigator.languages&&navigator.languages.length>0?navigator.languages[0]:navigator.language||navigator.userLanguage),a.localize=function(c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;return null==d&&(d={}),v=this,h={},g=d.fileExtension||"json",f=a.Deferred(),k=function(a,b,c){var e;switch(null==c&&(c=1),c){case 1:return h={},d.loadBase?(e=a+("."+g),i(e,a,b,c)):k(a,b,2);case 2:return e=""+a+"-"+b.split("-")[0]+"."+g,i(e,a,b,c);case 3:return e=""+a+"-"+b.split("-").slice(0,2).join("-")+"."+g,i(e,a,b,c);default:return f.resolve()}},i=function(b,c,e,f){var g,i,j;return null!=d.pathPrefix&&(b=""+d.pathPrefix+"/"+b),j=function(b){return a.extend(h,b),q(h),k(c,e,f+1)},i=function(){return 2===f&&e.indexOf("-")>-1?k(c,e,f+1):d.fallback&&d.fallback!==e?k(c,d.fallback):void 0},g={url:b,dataType:"json",async:!0,timeout:null!=d.timeout?d.timeout:500,success:j,error:i},"file:"===window.location.protocol&&(g.error=function(b){return j(a.parseJSON(b.responseText))}),a.ajax(g)},q=function(a){return null!=d.callback?d.callback(a,e):e(a)},e=function(b){return a.localize.data[c]=b,v.each(function(){var c,d,e;return c=a(this),d=c.data("localize"),d||(d=c.attr("rel").match(/localize\[(.*?)\]/)[1]),e=u(d,b),null!=e?l(c,d,e):void 0})},l=function(b,c,d){return b.is("input")?o(b,c,d):b.is("textarea")?o(b,c,d):b.is("img")?n(b,c,d):b.is("optgroup")?p(b,c,d):a.isPlainObject(d)||b.html(d),a.isPlainObject(d)?m(b,d):void 0},o=function(b,c,d){var e;return e=a.isPlainObject(d)?d.value:d,b.is("[placeholder]")?b.attr("placeholder",e):b.val(e)},m=function(a,b){return s(a,"title",b),s(a,"href",b),t(a,"text",b)},p=function(a,b,c){return a.attr("label",c)},n=function(a,b,c){return s(a,"alt",c),s(a,"src",c)},u=function(a,b){var c,d,e,f;for(c=a.split(/\./),d=b,e=0,f=c.length;f>e;e++)a=c[e],d=null!=d?d[a]:null;return d},s=function(a,b,c){return c=u(b,c),null!=c?a.attr(b,c):void 0},t=function(a,b,c){return c=u(b,c),null!=c?a.text(c):void 0},r=function(a){var b;return"string"==typeof a?"^"+a+"$":null!=a.length?function(){var c,d,e;for(e=[],c=0,d=a.length;d>c;c++)b=a[c],e.push(r(b));return e}().join("|"):a},j=b(d.language?d.language:a.defaultLanguage),d.skipLanguage&&j.match(r(d.skipLanguage))?f.resolve():k(c,j,1),v.localizePromise=f,v},a.fn.localize=a.localize,a.localize.data={}}(jQuery);

8078
lib/showdown.js Normal file

File diff suppressed because it is too large Load diff

1
lib/showdown.js.map Normal file

File diff suppressed because one or more lines are too long

3
lib/showdown.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
lib/showdown.min.js.map Normal file

File diff suppressed because one or more lines are too long

3720
lib/w2ui/w2ui-1.5.css Normal file

File diff suppressed because one or more lines are too long

21501
lib/w2ui/w2ui-1.5.js Normal file

File diff suppressed because it is too large Load diff

1
lib/w2ui/w2ui-1.5.js.map Normal file

File diff suppressed because one or more lines are too long

2
lib/w2ui/w2ui-1.5.min.css vendored Normal file

File diff suppressed because one or more lines are too long

2
lib/w2ui/w2ui-1.5.min.js vendored Normal file

File diff suppressed because one or more lines are too long

3714
lib/w2ui/w2ui.css Normal file

File diff suppressed because one or more lines are too long

22158
lib/w2ui/w2ui.es6.js Normal file

File diff suppressed because it is too large Load diff

486
lib/w2ui/w2ui.es6.min.js vendored Normal file

File diff suppressed because one or more lines are too long

22350
lib/w2ui/w2ui.js Normal file

File diff suppressed because it is too large Load diff

2
lib/w2ui/w2ui.min.css vendored Normal file

File diff suppressed because one or more lines are too long

486
lib/w2ui/w2ui.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,28 +1,78 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>fateforge-tools</title>
<head>
<meta charset="utf-8" />
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Spells - fateforge.tools</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css" />
<link href="css/all.min.css" rel="stylesheet" />
<link href="css/water.css" rel="stylesheet" />
<link type="text/css" rel="stylesheet" href="lib/w2ui/w2ui.css" />
<link rel="stylesheet" href="css/style.css" type="text/css">
<link rel="icon" type="image/x-icon" href="/img/FateforgeTool_logo_80.png">
<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="lib/jquery.localize-dev.js"></script>
</head>
<body>
<button onclick="changeLangEN()">English</button>
<button onclick="changeLangFR()">French</button>
<h1>FateforgeTools</h1>
<h2 data-localize="btn-spells">Spells</h2>
<body class="spells">
<header>
<button onclick="changeLangEN()">English</button>
<button onclick="changeLangFR()">Français</button>
<a href="index.html">
<h1>FateforgeTools</h1>
</a>
</header>
<h2 data-localize="btn-spells">Spells</h2>
<!--<div class="container" style="display: flex;flex-direction: row;flex-wrap: wrap;">-->
<div class="container" ">
<div class=" list-col" id="spell-list">
<!-- FILL WITH JS-->
</div>
<script type="text/javascript" src="lib/jquery.min.js"></script>
<script type="text/javascript" src="lib/jquery.localize.js"></script>
<script type="text/javascript" src="js/language.js"></script>
<script src="https://kit.fontawesome.com/126cdd0e29.js" crossorigin="anonymous"></script>
<div class="view-col" id="content">
<table id="pagecontent" class="view" style="border:solid">
<td class="initial-message">Select a spell from the list to view it here</td>
</table>
</div>
</div>
<div id="footer"></div>
<script type="text/javascript" src="lib/w2ui/w2ui.js"></script>
<script type="text/javascript" src="lib/w2ui/w2ui.es6.js"></script>
<script type="module" src="js/spells.js"></script>
<script type="text/javascript" src="js/footer.js"></script>
<script src="https://kit.fontawesome.com/126cdd0e29.js" crossorigin="anonymous"></script>
<script type="text/javascript" src="js/language.js"></script>
</body>
</html>

57
test-w2ui.html Normal file
View file

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<title>W2UI Demo: grid/6</title>
<link rel="stylesheet" type="text/css" href="https://rawgit.com/vitmalina/w2ui/master/dist/w2ui.min.css">
</head>
<body>
<div id="grid" style="min-width: 300px;max-width:900px;height: 300px;"></div>
<br>
<script type="module">
import { w2grid } from 'https://rawgit.com/vitmalina/w2ui/master/dist/w2ui.es6.min.js'
let grid = new w2grid({
name: 'grid',
box: '#grid',
show: { selectColumn: true },
multiSelect: true,
columns: [
{ field: 'recid', text: 'ID', size: '50px' },
{ field: 'lname', text: 'Last Name', size: '30%' },
{ field: 'fname', text: 'First Name', size: '30%' },
{ field: 'email', text: 'Email', size: '40%' },
{ field: 'sdate', text: 'Start Date', size: '120px' }
],
records: [
{ recid: 1, fname: 'John', lname: 'Doe', email: 'jdoe@gmail.com', sdate: '4/3/2012' },
{ recid: 2, fname: 'Stuart', lname: 'Motzart', email: 'jdoe@gmail.com', sdate: '4/3/2012' },
{ recid: 3, fname: 'Jin', lname: 'Franson', email: 'jdoe@gmail.com', sdate: '4/3/2012' },
{ recid: 4, fname: 'Susan', lname: 'Ottie', email: 'jdoe@gmail.com', sdate: '4/3/2012' },
{ recid: 5, fname: 'Kelly', lname: 'Silver', email: 'jdoe@gmail.com', sdate: '4/3/2012' },
{ recid: 6, fname: 'Francis', lname: 'Gatos', email: 'jdoe@gmail.com', sdate: '4/3/2012' },
{ recid: 7, fname: 'Mark', lname: 'Welldo', email: 'jdoe@gmail.com', sdate: '4/3/2012' },
{ recid: 8, fname: 'Thomas', lname: 'Bahh', email: 'jdoe@gmail.com', sdate: '4/3/2012' }
],
async onSelect(event) {
await event.complete
console.log('select', event.detail, this.getSelection())
}
})
window.multi = function(el) {
grid.multiSelect = el.checked
grid.selectNone()
grid.refresh()
}
window.selColumn = function(flag) {
grid.show.selectColumn = flag
grid.refresh()
}
</script>
</body>
</html>