commit 90c6f444e9c1212866dba1206c97ef6d07ba4a29 Author: Documentation Date: Sun May 30 14:00:11 2021 +0000 Updates diff --git a/CardCreator.html b/CardCreator.html new file mode 100644 index 0000000..c9edf97 --- /dev/null +++ b/CardCreator.html @@ -0,0 +1,463 @@ + + + + + JSDoc: Class: CardCreator + + + + + + + + + + +
+ +

Class: CardCreator

+ + + + + + +
+ +
+ +

CardCreator()

+ + +
+ +
+
+ + + + + + +

new CardCreator()

+ + + + + + +
+ Creates a new card creator. +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async) createCard(charaId) → {Promise.<Buffer>}

+ + + + + + +
+ Creates a character card for a character. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
charaId + + +number +| + +string + + + + The Lodestone ID of the character to generate a card for.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ A promise representating the construction of the card's image data. +
+ + + +
+
+ Type +
+
+ +Promise.<Buffer> + + +
+
+ + + + + + +
Example
+ +
const fs = require("fs");
+
+const card = new CardCreator();
+const lodestoneId = "13821878";
+
+await card.ensureInit();
+const png = await card.createCard(lodestoneId);
+
+fs.writeFile("./test.png", png, err => {
+  if (err) console.error(err);
+});
+ + + + + + + + + +

(async) ensureInit() → {Promise}

+ + + + + + +
+ Ensures that the instance is ready to generate character cards. +This function must be resolved before using character card +generation methods. +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ A promise representing the initialization state of this generator. +
+ + + +
+
+ Type +
+
+ +Promise + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/create-card.js.html b/create-card.js.html new file mode 100644 index 0000000..7121ad9 --- /dev/null +++ b/create-card.js.html @@ -0,0 +1,657 @@ + + + + + JSDoc: Source: create-card.js + + + + + + + + + + +
+ +

Source: create-card.js

+ + + + + + +
+
+
const fetch = require("node-fetch");
+const path = require("path");
+const { createCanvas, loadImage, registerFont } = require("canvas");
+
+function absolute(relativePath) {
+    return path.join(__dirname, relativePath);
+}
+
+registerFont(absolute('SourceSansPro-Regular.ttf'), { family: 'Source Sans Pro', style: 'Regular' });
+registerFont(absolute('SourceSansPro-SemiBold.ttf'), { family: 'Source Sans Pro', style: 'SemiBold' });
+
+const primary = "rgba(178, 214, 249, 1)";
+const white = "rgba(255, 255, 255,1)";
+const grey = "#868686";
+const black = "rgba(0,0,0,0.5)";
+const copyright = '"11px "Source Sans Pro"';
+const small = '"18px "Source Sans Pro"';
+const med = '30px "Source Sans Pro"';
+const smed = '25px "Source Sans Pro"';
+const large = '45px "Source Sans Pro SemiBold"';
+
+const jobsRowTextStartX = 495;
+const jobsRowTextSize = 30;
+const jobsRowTextSpacer = jobsRowTextSize * 2;
+
+const rectHeightRow1 = 120; // Title, Name, World
+const rectHeightRow2 = 40; // Mounts, Minions
+const rectHeightRow3 = 215; // Info
+const rectHeightRow4 = 120; // Jobs
+const rectHeightRow5 = 175; // Jobs
+
+const rectSpacing = 8;
+const rectHalfWidthSpacing = 10;
+
+const rectFullWidth = 400;
+const rectHalfWidth = (rectFullWidth / 2) - (rectHalfWidthSpacing / 2);
+
+const rectStartX = 464;
+const rectStartXHalf = rectStartX + rectHalfWidth + rectHalfWidthSpacing;
+
+const rectStartRow1Y = 0;
+const rectStartRow2Y = rectStartRow1Y + rectHeightRow1 + rectSpacing;
+const rectStartRow3Y = rectStartRow2Y + rectHeightRow2 + rectSpacing;
+const rectStartRow4Y = rectStartRow3Y + rectHeightRow3 + rectSpacing;
+const rectStartRow5Y = rectStartRow4Y + rectHeightRow4 + rectSpacing;
+
+const jobsStartSpacing = 10;
+const jobsRowSpacing = 8;
+
+const jobsRowIcon1Y = rectStartRow5Y + jobsStartSpacing;
+const jobsRowText1Y = jobsRowIcon1Y + 45;
+
+const jobsRowIcon2Y = jobsRowText1Y + jobsRowSpacing;
+const jobsRowText2Y = jobsRowIcon2Y + 45;
+
+const jobsRowIcon3Y = jobsRowText2Y + jobsRowSpacing;
+const jobsRowText3Y = jobsRowIcon3Y + 45;
+
+const textTitleY = rectStartRow1Y + 34;
+const textServerY = rectStartRow1Y + 104;
+const textNameNoTitleY = rectStartRow1Y + 59;
+const textNameTitleY = rectStartRow1Y + 79;
+
+const textMountMinionY = rectStartRow2Y + 28;
+const iconMountMinionY = rectStartRow2Y + 5;
+
+const deityIconY = rectStartRow3Y + 69;
+const deityIconX = 805;
+
+const gcRankIconY = rectStartRow3Y + 110;
+const gcRankIconX = 799;
+
+const fcCrestScale = 38;
+const fcCrestY = rectStartRow3Y + 162;
+const fcCrestX = 800;
+
+const infoTextStartSpacing = 22;
+const infoTextSmallStartY = rectStartRow3Y + infoTextStartSpacing;
+const infoTextBigStartY = infoTextSmallStartY + 25;
+const infoTextSpacing = 50;
+
+class CardCreator {
+  /**
+   * Creates a new card creator.
+   * @constructor
+   */
+  constructor() {
+    this.isInit = false;
+  }
+
+  /**
+   * Ensures that the instance is ready to generate character cards.
+   * This function must be resolved before using character card
+   * generation methods.
+   * @returns {Promise} A promise representing the initialization state of this generator.
+   */
+  async ensureInit() {
+    if (this.isInit) {
+      return;
+    }
+
+    await this.init();
+    this.isInit = true;
+  }
+
+  async init() {
+    var d = new Date();
+    this.copyrightYear = d.getFullYear();
+
+    this.bgImage = await loadImage(absolute("./chara_top.png"));
+
+    this.imgMinion = await loadImage(absolute("./minion.png"));
+    this.imgMount = await loadImage(absolute("./mount.png"));
+    this.imgIlvl = await loadImage(absolute("./ilvl_n.png"));
+    this.imgShadow = await loadImage(absolute("./shadow.png"));
+
+    this.imgAlchemist = await loadImage(absolute("./cj/1/alchemist.png"));
+    this.imgArmorer = await loadImage(absolute("./cj/1/armorer.png"));
+    this.imgBlacksmith = await loadImage(absolute("./cj/1/blacksmith.png"));
+    this.imgCarpenter = await loadImage(absolute("./cj/1/carpenter.png"));
+    this.imgCulinarian = await loadImage(absolute("./cj/1/culinarian.png"));
+    this.imgGoldsmith = await loadImage(absolute("./cj/1/goldsmith.png"));
+    this.imgLeatherworker = await loadImage(absolute("./cj/1/leatherworker.png"));
+    this.imgWeaver = await loadImage(absolute("./cj/1/weaver.png"));
+
+    this.imgBotanist = await loadImage(absolute("./cj/1/botanist.png"));
+    this.imgFisher = await loadImage(absolute("./cj/1/fisher.png"));
+    this.imgMiner = await loadImage(absolute("./cj/1/miner.png"));
+
+    this.imgGladiator = await loadImage(absolute("./cj/1/gladiator.png"));
+    this.imgPaladin = await loadImage(absolute("./cj/1/paladin.png"));
+    this.imgMarauder = await loadImage(absolute("./cj/1/marauder.png"));
+    this.imgWarrior = await loadImage(absolute("./cj/1/warrior.png"));
+    this.imgDarkKnight = await loadImage(absolute("./cj/1/darkknight.png"));
+    this.imgGunbreaker = await loadImage(absolute("./cj/1/gunbreaker.png"));
+
+    this.imgConjurer = await loadImage(absolute("./cj/1/conjurer.png"));
+    this.imgWhitemage = await loadImage(absolute("./cj/1/whitemage.png"));
+    this.imgScholar = await loadImage(absolute("./cj/1/scholar.png"));
+    this.imgAstrologian = await loadImage(absolute("./cj/1/astrologian.png"));
+
+    this.imgArcher = await loadImage(absolute("./cj/1/archer.png"));
+    this.imgBard = await loadImage(absolute("./cj/1/bard.png"));
+    this.imgMachinist = await loadImage(absolute("./cj/1/machinist.png"));
+    this.imgDancer = await loadImage(absolute("./cj/1/dancer.png"));
+
+    this.imgLancer = await loadImage(absolute("./cj/1/lancer.png"));
+    this.imgDragoon = await loadImage(absolute("./cj/1/dragoon.png"));
+    this.imgPugilist = await loadImage(absolute("./cj/1/pugilist.png"));
+    this.imgMonk = await loadImage(absolute("./cj/1/monk.png"));
+    this.imgRogue = await loadImage(absolute("./cj/1/rogue.png"));
+    this.imgNinja = await loadImage(absolute("./cj/1/ninja.png"));
+    this.imgSamurai = await loadImage(absolute("./cj/1/samurai.png"));
+
+    this.imgThaumaturge = await loadImage(absolute("./cj/1/thaumaturge.png"));
+    this.imgBlackmage = await loadImage(absolute("./cj/1/blackmage.png"));
+    this.imgArcanist = await loadImage(absolute("./cj/1/arcanist.png"));
+    this.imgSummoner = await loadImage(absolute("./cj/1/summoner.png"));
+    this.imgRedmage = await loadImage(absolute("./cj/1/redmage.png"));
+
+    this.imgBluemage = await loadImage(absolute('./cj/1/bluemage.png'));
+
+    this.imgJobBg = {};
+    for (var i = 1; i <= 38; i++) {
+      this.imgJobBg[i] = await loadImage(absolute(`./cj/bg/${i}.png`));
+    }
+
+    await this.countMountsMinions();
+  }
+
+  async countMountsMinions() {
+    var response = await fetch(`https://ffxivcollect.com/api/minions/`);
+    var data = await response.json();
+
+    this.countMinion = data.count;
+
+    var response = await fetch(`https://ffxivcollect.com/api/mounts/`);
+    var data = await response.json();
+
+    this.countMount = data.count;
+
+    console.log(`Refreshed counts: ${this.countMinion} - ${this.countMount}`);
+  }
+
+  async createCrest(crestAry) {
+    const canvas = createCanvas(128, 128);
+    const ctx = canvas.getContext("2d");
+
+    if (crestAry.length == 0)
+      return null;
+
+    for (var i = 0; i < crestAry.length; i++) {
+      var crestLayer = await loadImage(crestAry[i]);
+      ctx.drawImage(crestLayer, 0, 0, 128, 128);
+    }
+
+    var imgd = ctx.getImageData(0, 0, 128, 128),
+      pix = imgd.data,
+      newColor = { r: 0, g: 0, b: 0, a: 0 };
+
+    for (var i = 0, n = pix.length; i < n; i += 4) {
+      var r = pix[i],
+        g = pix[i + 1],
+        b = pix[i + 2];
+
+      // If its white then change it
+      if (r == 64 && g == 64 && b == 64) {
+        // Change the white to whatever.
+        pix[i] = newColor.r;
+        pix[i + 1] = newColor.g;
+        pix[i + 2] = newColor.b;
+        pix[i + 3] = newColor.a;
+      }
+    }
+
+    ctx.putImageData(imgd, 0, 0);
+
+    return canvas;
+  }
+
+  getItemLevel(gearset) {
+    var ilvl = 0;
+    var cnt = 0;
+    var mainHandLvl = 0;
+    var hasOffHand = false;
+
+    for (var key in gearset) {
+      var piece = gearset[key];
+
+      if (key == 'SoulCrystal')
+        continue;
+
+      if (key == 'MainHand')
+        mainHandLvl = piece.Item.LevelItem;
+
+      if (key == 'OffHand')
+        hasOffHand = true;
+
+      ilvl += piece.Item.LevelItem;
+      cnt++;
+    }
+
+    if (!hasOffHand) {
+      ilvl += mainHandLvl;
+      cnt++;
+    }
+
+    if (cnt == 0)
+      return 0;
+
+    return this.pad(Math.floor(ilvl / cnt), 4);
+  }
+
+  pad(num, size) {
+    num = num.toString();
+    while (num.length < size) num = "0" + num;
+    return num;
+  }
+
+  /**
+   * Creates a character card for a character.
+   * @param {number | string} charaId The Lodestone ID of the character to generate a card for.
+   * @example
+   * const fs = require("fs");
+   * 
+   * const card = new CardCreator();
+   * const lodestoneId = "13821878";
+   * 
+   * await card.ensureInit();
+   * const png = await card.createCard(lodestoneId);
+   * 
+   * fs.writeFile("./test.png", png, err => {
+   *   if (err) console.error(err);
+   * });
+   * @returns {Promise<Buffer>} A promise representating the construction of the card's image data.
+   */
+  async createCard(charaId) {
+    var response = await fetch(`https://xivapi.com/character/${charaId}?extended=1&data=FC,mimo`);
+    var data = await response.json();
+
+    const canvas = createCanvas(890, 720);
+    const ctx = canvas.getContext("2d");  
+
+    var portrait = await loadImage(data.Character.Portrait);
+
+    ctx.drawImage(this.bgImage, 0, 0, 890, 722);
+
+    ctx.drawImage(portrait, 0, 120, 441, 600);
+
+    ctx.strokeStyle = white;
+    ctx.fillStyle = black;
+    ctx.beginPath();
+    // Name, Title, Server Rect
+    ctx.fillRect(25, 10, 840, 100);
+
+    ctx.drawImage(this.imgJobBg[data.Character.ActiveClassJob.UnlockedState.ID], 450, 4, rectFullWidth, 110);
+
+    ctx.fillRect(rectStartX, rectStartRow2Y, rectHalfWidth, rectHeightRow2);
+    ctx.fillRect(rectStartXHalf, rectStartRow2Y, rectHalfWidth, rectHeightRow2);
+
+    ctx.fillRect(rectStartX, rectStartRow3Y, rectFullWidth, rectHeightRow3); //info
+    ctx.fillRect(rectStartX, rectStartRow4Y, rectFullWidth, rectHeightRow4); // bozja
+    ctx.fillRect(rectStartX, rectStartRow5Y, rectFullWidth, rectHeightRow5);
+    ctx.stroke();
+
+    ctx.textAlign = "center";
+    ctx.font = med;
+    ctx.fillStyle = primary;
+    
+    if (data.Character.Title.Name !== undefined)
+      ctx.fillText(data.Character.Title.Name, 450, 40);
+
+    ctx.font = small;
+    ctx.fillText(`${data.Character.Server} (${data.Character.DC})`, 450, 100);
+
+    // Race, Clan, Guardian, GC, FC Titles
+    ctx.font = small;
+    ctx.textAlign = "left";
+    ctx.fillText("Race & Clan", 480, infoTextSmallStartY);
+    ctx.fillText("Guardian", 480, infoTextSmallStartY + infoTextSpacing);
+    if (data.Character.GrandCompany.Company != null) {
+      ctx.fillText("Grand Company", 480, infoTextSmallStartY + infoTextSpacing * 2);
+    }
+    if (data.Character.FreeCompanyName != null) {
+      ctx.fillText("Free Company", 480, infoTextSmallStartY + infoTextSpacing * 3);
+    }
+      ctx.fillText("Elemental Level", 480, 425);
+      ctx.fillText("Resistance Rank", 480, 475);
+
+
+    ctx.fillStyle = grey;
+    ctx.font = smed;
+
+    var ilvl = this.getItemLevel(data.Character.GearSet.Gear);
+    ctx.drawImage(this.imgShadow, 441 - 143, 110, 170, 90);
+    ctx.drawImage(this.imgIlvl, 441 - 92, 132, 24, 27);
+    ctx.fillText(ilvl, 441 - 65, 155);
+
+    ctx.fillStyle = white;
+    ctx.font = large;
+
+    ctx.textAlign = "center";
+    // Chara Name
+    if (data.Character.Title === undefined || data.Character.Title.Name == null || data.Character.Title.Name == "") {
+      ctx.fillText(data.Character.Name, 450, 80);
+    } else {
+      ctx.fillText(data.Character.Name, 450, 80);
+    }
+    // Race, Clan, Guardian, GC, FC Info
+    ctx.font = smed;
+    ctx.textAlign = "left";
+    ctx.fillText(`${data.Character.Race.Name}, ${data.Character.Tribe.Name}`, 480, infoTextBigStartY);
+
+    ctx.fillText(data.Character.GuardianDeity.Name, 480, infoTextBigStartY + infoTextSpacing);
+    var deityIcon = await loadImage('https://xivapi.com/' + data.Character.GuardianDeity.Icon);
+    ctx.drawImage(deityIcon, deityIconX, deityIconY, 28, 28);
+
+    if (data.Character.GrandCompany.Company != null) {
+      ctx.fillText(data.Character.GrandCompany.Company.Name, 480, infoTextBigStartY + infoTextSpacing * 2);
+
+      var gcRankIcon = await loadImage('https://xivapi.com/' + data.Character.GrandCompany.Rank.Icon);
+      ctx.drawImage(gcRankIcon, gcRankIconX, gcRankIconY, 40, 40);
+    }
+
+    if (data.Character.FreeCompanyName != null) {
+      var crestImage = await this.createCrest(data.FreeCompany.Crest);
+
+      if (crestImage !== null)
+        ctx.drawImage(crestImage, fcCrestX, fcCrestY, fcCrestScale, fcCrestScale);
+
+
+      const fcMeasure = ctx.measureText(data.Character.FreeCompanyName);
+      ctx.fillText(data.Character.FreeCompanyName, 480, infoTextBigStartY + infoTextSpacing * 3);
+
+      ctx.fillStyle = grey;
+      ctx.font = small;
+      ctx.fillText(`«${data.FreeCompany.Tag}»`, 480 + fcMeasure.width + 10, infoTextBigStartY + infoTextSpacing * 3);
+    }
+
+    ctx.font = smed;
+    ctx.fillStyle = white;
+
+    if (data.Character.ClassJobsElemental.Level != null) {
+      ctx.fillText(`Level ${data.Character.ClassJobsElemental.Level}`, 480, 450);
+    } else {
+      ctx.fillText(`Level 0`, 480, 450);
+    }
+
+    if (data.Character.ClassJobsBozjan.Level != null) {
+      ctx.fillText(`Rank ${data.Character.ClassJobsBozjan.Level}`, 480, 500);
+    } else {
+      ctx.fillText(`Rank 0`, 480, 500);
+    }
+
+    // Minion & Mount percentages
+    var mountsPct = '0';
+    if (data.Mounts !== null) {
+      mountsPct = Math.ceil((data.Mounts.length / this.countMount) * 100);
+    }
+    
+    var minionsPct = '0';
+    if (data.Minions !== null) {
+      minionsPct = Math.ceil((data.Minions.length / this.countMinion) * 100);
+    }
+
+    const mountsMeasure = ctx.measureText(`${mountsPct}%`);
+    const minionsMeasure = ctx.measureText(`${minionsPct}%`);
+
+    ctx.fillText(`${mountsPct}%`, 480, textMountMinionY);
+    ctx.fillText(`${minionsPct}%`, 685, textMountMinionY);
+
+    ctx.fillStyle = grey;
+    ctx.font = small;
+
+    ctx.fillText("Mounts", 480 + mountsMeasure.width + 5, textMountMinionY);
+    ctx.fillText("Minions", 685 + minionsMeasure.width + 5, textMountMinionY);
+
+    ctx.drawImage(this.imgMount, 620, iconMountMinionY, 32, 32);
+    ctx.drawImage(this.imgMinion, 834, iconMountMinionY, 19, 32);
+
+    ctx.fillStyle = white;
+
+
+    // Why are there so many fucking jobs in this game?
+    // Crafting
+    ctx.textAlign = "center";
+
+    var cJobsRowTextX = jobsRowTextStartX;
+    ctx.drawImage(this.imgAlchemist, 480, jobsRowIcon3Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[24].Level, cJobsRowTextX, jobsRowText3Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgArmorer, 510, jobsRowIcon3Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[20].Level, cJobsRowTextX, jobsRowText3Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgBlacksmith, 540, jobsRowIcon3Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[19].Level, cJobsRowTextX, jobsRowText3Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgCarpenter, 570, jobsRowIcon3Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[18].Level, cJobsRowTextX, jobsRowText3Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgCulinarian, 600, jobsRowIcon3Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[25].Level, cJobsRowTextX, jobsRowText3Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgGoldsmith, 630, jobsRowIcon3Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[21].Level, cJobsRowTextX, jobsRowText3Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgLeatherworker, 660, jobsRowIcon3Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[22].Level, cJobsRowTextX, jobsRowText3Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgWeaver, 690, jobsRowIcon3Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[23].Level, cJobsRowTextX, jobsRowText3Y);
+    cJobsRowTextX += jobsRowTextSpacer;
+
+    // Gathering
+    ctx.drawImage(this.imgBotanist, 750, jobsRowIcon3Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[27].Level, cJobsRowTextX, jobsRowText3Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgFisher, 780, jobsRowIcon3Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[28].Level, cJobsRowTextX, jobsRowText3Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgMiner, 810, jobsRowIcon3Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[26].Level, cJobsRowTextX, jobsRowText3Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    // Tanks
+    cJobsRowTextX = jobsRowTextStartX;
+
+    if (data.Character.ClassJobs[0].UnlockedState.ID == 19) {
+      ctx.drawImage(this.imgPaladin, 480, jobsRowIcon1Y, 30, 30);
+    } else {
+      ctx.drawImage(this.imgGladiator, 480, jobsRowIcon1Y, 30, 30);
+    }
+    ctx.fillText(data.Character.ClassJobs[0].Level, cJobsRowTextX, jobsRowText1Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    if (data.Character.ClassJobs[1].UnlockedState.ID == 21) {
+      ctx.drawImage(this.imgWarrior, 510, jobsRowIcon1Y, 30, 30);
+    } else {
+      ctx.drawImage(this.imgMarauder, 510, jobsRowIcon1Y, 30, 30);
+    }
+    ctx.fillText(data.Character.ClassJobs[1].Level, cJobsRowTextX, jobsRowText1Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgDarkKnight, 540, jobsRowIcon1Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[2].Level, cJobsRowTextX, jobsRowText1Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgGunbreaker, 570, jobsRowIcon1Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[3].Level, cJobsRowTextX, jobsRowText1Y);
+    cJobsRowTextX += jobsRowTextSpacer;
+
+    // Healers
+    if (data.Character.ClassJobs[8].UnlockedState.ID == 24) {
+      ctx.drawImage(this.imgWhitemage, 630, jobsRowIcon1Y, 30, 30);  
+    } else {
+      ctx.drawImage(this.imgConjurer, 630, jobsRowIcon1Y, 30, 30);
+    }
+    ctx.fillText(data.Character.ClassJobs[8].Level, cJobsRowTextX, jobsRowText1Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgScholar, 660, jobsRowIcon1Y, 30, 30);
+    if (data.Character.ClassJobs[9].Level >= 30) {
+      ctx.fillText(data.Character.ClassJobs[9].Level, cJobsRowTextX, jobsRowText1Y);
+    } else {
+      ctx.fillText("0", cJobsRowTextX, jobsRowText1Y);
+    }
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgAstrologian, 690, jobsRowIcon1Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[10].Level, cJobsRowTextX, jobsRowText1Y);
+    cJobsRowTextX += jobsRowTextSpacer;
+
+    // DPS
+    // Ranged
+    if (data.Character.ClassJobs[11].UnlockedState.ID == 23) {
+      ctx.drawImage(this.imgBard, 750, jobsRowIcon1Y, 30, 30);
+    } else {
+      ctx.drawImage(this.imgArcher, 750, jobsRowIcon1Y, 30, 30);
+    }
+    ctx.fillText(data.Character.ClassJobs[11].Level, cJobsRowTextX, jobsRowText1Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgMachinist, 780, jobsRowIcon1Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[12].Level, cJobsRowTextX, jobsRowText1Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgDancer, 810, jobsRowIcon1Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[13].Level, cJobsRowTextX, jobsRowText1Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    // Melee
+    cJobsRowTextX = jobsRowTextStartX;
+
+    if (data.Character.ClassJobs[5].UnlockedState.ID == 22) {
+      ctx.drawImage(this.imgDragoon, 480, jobsRowIcon2Y, 30, 30);
+    } else {
+      ctx.drawImage(this.imgLancer, 480, jobsRowIcon2Y, 30, 30);
+    }
+    ctx.fillText(data.Character.ClassJobs[5].Level, cJobsRowTextX, jobsRowText2Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    if (data.Character.ClassJobs[4].UnlockedState.ID == 20) {
+      ctx.drawImage(this.imgMonk, 510, jobsRowIcon2Y, 30, 30);
+    } else {
+      ctx.drawImage(this.imgPugilist, 510, jobsRowIcon2Y, 30, 30);
+    }
+    ctx.fillText(data.Character.ClassJobs[4].Level, cJobsRowTextX, jobsRowText2Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    if (data.Character.ClassJobs[6].UnlockedState.ID == 30) {
+      ctx.drawImage(this.imgNinja, 540, jobsRowIcon2Y, 30, 30);
+    } else {
+      ctx.drawImage(this.imgRogue, 540, jobsRowIcon2Y, 30, 30);
+    }
+    ctx.fillText(data.Character.ClassJobs[6].Level, cJobsRowTextX, jobsRowText2Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgSamurai, 570, jobsRowIcon2Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[7].Level, cJobsRowTextX, jobsRowText2Y);
+    cJobsRowTextX += jobsRowTextSpacer;
+
+    // Caster
+    if (data.Character.ClassJobs[14].UnlockedState.ID == 25) {
+      ctx.drawImage(this.imgBlackmage, 630, jobsRowIcon2Y, 30, 30); 
+    } else {
+      ctx.drawImage(this.imgThaumaturge, 630, jobsRowIcon2Y, 30, 30); 
+    }
+    ctx.fillText(data.Character.ClassJobs[14].Level, cJobsRowTextX, jobsRowText2Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    if (data.Character.ClassJobs[15].UnlockedState.ID == 27) {
+      ctx.drawImage(this.imgSummoner, 660, jobsRowIcon2Y, 30, 30);
+    } else {
+      ctx.drawImage(this.imgArcanist, 660, jobsRowIcon2Y, 30, 30);
+    }
+    ctx.fillText(data.Character.ClassJobs[15].Level, cJobsRowTextX, jobsRowText2Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    ctx.drawImage(this.imgRedmage, 690, jobsRowIcon2Y, 30, 30);
+    ctx.fillText(data.Character.ClassJobs[16].Level, cJobsRowTextX, jobsRowText2Y);
+    cJobsRowTextX += jobsRowTextSize;
+
+    // Limited
+    ctx.drawImage(this.imgBluemage, 780, jobsRowIcon2Y, 33, 33);
+    ctx.fillText(data.Character.ClassJobs[17].Level, 796, jobsRowText2Y);
+
+    ctx.textAlign = "left";
+    ctx.fillStyle = black;
+    ctx.font = copyright;
+
+    ctx.fillText(`© 2010 - ${this.copyrightYear} SQUARE ENIX CO., LTD. All Rights Reserved`, rectStartX, 720 - 5);
+
+    return canvas.toBuffer();
+  }
+}
+
+exports.CardCreator = CardCreator;
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/fonts/OpenSans-Bold-webfont.eot b/fonts/OpenSans-Bold-webfont.eot new file mode 100644 index 0000000..5d20d91 Binary files /dev/null and b/fonts/OpenSans-Bold-webfont.eot differ diff --git a/fonts/OpenSans-Bold-webfont.svg b/fonts/OpenSans-Bold-webfont.svg new file mode 100644 index 0000000..3ed7be4 --- /dev/null +++ b/fonts/OpenSans-Bold-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-Bold-webfont.woff b/fonts/OpenSans-Bold-webfont.woff new file mode 100644 index 0000000..1205787 Binary files /dev/null and b/fonts/OpenSans-Bold-webfont.woff differ diff --git a/fonts/OpenSans-BoldItalic-webfont.eot b/fonts/OpenSans-BoldItalic-webfont.eot new file mode 100644 index 0000000..1f639a1 Binary files /dev/null and b/fonts/OpenSans-BoldItalic-webfont.eot differ diff --git a/fonts/OpenSans-BoldItalic-webfont.svg b/fonts/OpenSans-BoldItalic-webfont.svg new file mode 100644 index 0000000..6a2607b --- /dev/null +++ b/fonts/OpenSans-BoldItalic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-BoldItalic-webfont.woff b/fonts/OpenSans-BoldItalic-webfont.woff new file mode 100644 index 0000000..ed760c0 Binary files /dev/null and b/fonts/OpenSans-BoldItalic-webfont.woff differ diff --git a/fonts/OpenSans-Italic-webfont.eot b/fonts/OpenSans-Italic-webfont.eot new file mode 100644 index 0000000..0c8a0ae Binary files /dev/null and b/fonts/OpenSans-Italic-webfont.eot differ diff --git a/fonts/OpenSans-Italic-webfont.svg b/fonts/OpenSans-Italic-webfont.svg new file mode 100644 index 0000000..e1075dc --- /dev/null +++ b/fonts/OpenSans-Italic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-Italic-webfont.woff b/fonts/OpenSans-Italic-webfont.woff new file mode 100644 index 0000000..ff652e6 Binary files /dev/null and b/fonts/OpenSans-Italic-webfont.woff differ diff --git a/fonts/OpenSans-Light-webfont.eot b/fonts/OpenSans-Light-webfont.eot new file mode 100644 index 0000000..1486840 Binary files /dev/null and b/fonts/OpenSans-Light-webfont.eot differ diff --git a/fonts/OpenSans-Light-webfont.svg b/fonts/OpenSans-Light-webfont.svg new file mode 100644 index 0000000..11a472c --- /dev/null +++ b/fonts/OpenSans-Light-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-Light-webfont.woff b/fonts/OpenSans-Light-webfont.woff new file mode 100644 index 0000000..e786074 Binary files /dev/null and b/fonts/OpenSans-Light-webfont.woff differ diff --git a/fonts/OpenSans-LightItalic-webfont.eot b/fonts/OpenSans-LightItalic-webfont.eot new file mode 100644 index 0000000..8f44592 Binary files /dev/null and b/fonts/OpenSans-LightItalic-webfont.eot differ diff --git a/fonts/OpenSans-LightItalic-webfont.svg b/fonts/OpenSans-LightItalic-webfont.svg new file mode 100644 index 0000000..431d7e3 --- /dev/null +++ b/fonts/OpenSans-LightItalic-webfont.svg @@ -0,0 +1,1835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-LightItalic-webfont.woff b/fonts/OpenSans-LightItalic-webfont.woff new file mode 100644 index 0000000..43e8b9e Binary files /dev/null and b/fonts/OpenSans-LightItalic-webfont.woff differ diff --git a/fonts/OpenSans-Regular-webfont.eot b/fonts/OpenSans-Regular-webfont.eot new file mode 100644 index 0000000..6bbc3cf Binary files /dev/null and b/fonts/OpenSans-Regular-webfont.eot differ diff --git a/fonts/OpenSans-Regular-webfont.svg b/fonts/OpenSans-Regular-webfont.svg new file mode 100644 index 0000000..25a3952 --- /dev/null +++ b/fonts/OpenSans-Regular-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/OpenSans-Regular-webfont.woff b/fonts/OpenSans-Regular-webfont.woff new file mode 100644 index 0000000..e231183 Binary files /dev/null and b/fonts/OpenSans-Regular-webfont.woff differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..c2e44df --- /dev/null +++ b/index.html @@ -0,0 +1,127 @@ + + + + + JSDoc: Home + + + + + + + + + + +
+ +

Home

+ + + + + + + + +

+ + + + + + + + + + + + + + + +
+

XIV Character Cards

+

npm Version +Documentation

+

API to create fancy cards for FFXIV characters based on their Lodestone data, hosted at https://ffxiv-character-cards.herokuapp.com.

+

Demo image

+

Endpoints

+

Getting images

+

https://ffxiv-character-cards.herokuapp.com/characters/id/<LODESTONE ID>.png +
Get the PNG for a character by its Lodestone ID.

+
+

https://ffxiv-character-cards.herokuapp.com/characters/name/<WORLD>/<CHARACTER NAME>.png +
Get the PNG for a character by its world and name.

+

Requesting images to be cached

+

If you are using this API together with an application that requires the API to respond very quickly, like Discord, you need to ask it to "prepare" the image for a character beforehand.

+

https://ffxiv-character-cards.herokuapp.com/prepare/id/<LODESTONE ID> +
Request a character image to be cached by its Lodestone ID.

+
+

https://ffxiv-character-cards.herokuapp.com/prepare/name/<WORLD>/<CHARACTER NAME> +
Request a character image to be cached by its world and name.

+

The API will reply with its status, and in case of success, the URL to the final image. +{"status":"ok","url":"/characters/id/123456789.png"}

+

Using in your application

+
yarn add xiv-character-cards
+# or
+npm i xiv-character-cards
+
+

You will receive a PNG-buffer for you to use in your bot or application.
Check index.js for other usage examples.

+

Example

+
const { CardCreator } = require("xiv-character-cards");
+const fs = require("fs");
+
+const card = new CardCreator();
+const lodestoneid = "13821878";
+
+function example(cb) {
+  card.ensureInit()
+    .then(
+      () => card.createCard(lodestoneid),
+      (reason) => cb("Init failed: " + reason, null)
+    )
+    .then((image) =>
+      cb(null, {
+        binary: {
+          image: image,
+        },
+      })
+    )
+    .catch((reason) => cb("createCard failed: " + reason, null));
+}
+
+example((err, response) => {
+  const buffer = response.binary.image;
+  fs.writeFileSync(`./${lodestoneid}.png`, response.binary.image, (err) => {
+    if (err) {
+      console.log(err);
+    }
+  });
+});
+
+
+ + + + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/scripts/linenumber.js b/scripts/linenumber.js new file mode 100644 index 0000000..4354785 --- /dev/null +++ b/scripts/linenumber.js @@ -0,0 +1,25 @@ +/*global document */ +(() => { + const source = document.getElementsByClassName('prettyprint source linenums'); + let i = 0; + let lineNumber = 0; + let lineId; + let lines; + let totalLines; + let anchorHash; + + if (source && source[0]) { + anchorHash = document.location.hash.substring(1); + lines = source[0].getElementsByTagName('li'); + totalLines = lines.length; + + for (; i < totalLines; i++) { + lineNumber++; + lineId = `line${lineNumber}`; + lines[i].id = lineId; + if (lineId === anchorHash) { + lines[i].className += ' selected'; + } + } + } +})(); diff --git a/scripts/prettify/Apache-License-2.0.txt b/scripts/prettify/Apache-License-2.0.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/scripts/prettify/Apache-License-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/scripts/prettify/lang-css.js b/scripts/prettify/lang-css.js new file mode 100644 index 0000000..041e1f5 --- /dev/null +++ b/scripts/prettify/lang-css.js @@ -0,0 +1,2 @@ +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", +/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/scripts/prettify/prettify.js b/scripts/prettify/prettify.js new file mode 100644 index 0000000..eef5ad7 --- /dev/null +++ b/scripts/prettify/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p th:last-child { border-right: 1px solid #ddd; } + +.ancestors, .attribs { color: #999; } +.ancestors a, .attribs a +{ + color: #999 !important; + text-decoration: none; +} + +.clear +{ + clear: both; +} + +.important +{ + font-weight: bold; + color: #950B02; +} + +.yes-def { + text-indent: -1000px; +} + +.type-signature { + color: #aaa; +} + +.name, .signature { + font-family: Consolas, Monaco, 'Andale Mono', monospace; +} + +.details { margin-top: 14px; border-left: 2px solid #DDD; } +.details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } +.details dd { margin-left: 70px; } +.details ul { margin: 0; } +.details ul { list-style-type: none; } +.details li { margin-left: 30px; padding-top: 6px; } +.details pre.prettyprint { margin: 0 } +.details .object-value { padding-top: 0; } + +.description { + margin-bottom: 1em; + margin-top: 1em; +} + +.code-caption +{ + font-style: italic; + font-size: 107%; + margin: 0; +} + +.source +{ + border: 1px solid #ddd; + width: 80%; + overflow: auto; +} + +.prettyprint.source { + width: inherit; +} + +.source code +{ + font-size: 100%; + line-height: 18px; + display: block; + padding: 4px 12px; + margin: 0; + background-color: #fff; + color: #4D4E53; +} + +.prettyprint code span.line +{ + display: inline-block; +} + +.prettyprint.linenums +{ + padding-left: 70px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.prettyprint.linenums ol +{ + padding-left: 0; +} + +.prettyprint.linenums li +{ + border-left: 3px #ddd solid; +} + +.prettyprint.linenums li.selected, +.prettyprint.linenums li.selected * +{ + background-color: lightyellow; +} + +.prettyprint.linenums li * +{ + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +.params .name, .props .name, .name code { + color: #4D4E53; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 100%; +} + +.params td.description > p:first-child, +.props td.description > p:first-child +{ + margin-top: 0; + padding-top: 0; +} + +.params td.description > p:last-child, +.props td.description > p:last-child +{ + margin-bottom: 0; + padding-bottom: 0; +} + +.disabled { + color: #454545; +} diff --git a/styles/prettify-jsdoc.css b/styles/prettify-jsdoc.css new file mode 100644 index 0000000..5a2526e --- /dev/null +++ b/styles/prettify-jsdoc.css @@ -0,0 +1,111 @@ +/* JSDoc prettify.js theme */ + +/* plain text */ +.pln { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* string content */ +.str { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a keyword */ +.kwd { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a comment */ +.com { + font-weight: normal; + font-style: italic; +} + +/* a type name */ +.typ { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a literal value */ +.lit { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* punctuation */ +.pun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp open bracket */ +.opn { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp close bracket */ +.clo { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a markup tag name */ +.tag { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute name */ +.atn { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute value */ +.atv { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a declaration */ +.dec { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a variable name */ +.var { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a function name */ +.fun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; +} diff --git a/styles/prettify-tomorrow.css b/styles/prettify-tomorrow.css new file mode 100644 index 0000000..b6f92a7 --- /dev/null +++ b/styles/prettify-tomorrow.css @@ -0,0 +1,132 @@ +/* Tomorrow Theme */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* Pretty printing styles. Used with prettify.js. */ +/* SPAN elements with the classes below are added by prettyprint. */ +/* plain text */ +.pln { + color: #4d4d4c; } + +@media screen { + /* string content */ + .str { + color: #718c00; } + + /* a keyword */ + .kwd { + color: #8959a8; } + + /* a comment */ + .com { + color: #8e908c; } + + /* a type name */ + .typ { + color: #4271ae; } + + /* a literal value */ + .lit { + color: #f5871f; } + + /* punctuation */ + .pun { + color: #4d4d4c; } + + /* lisp open bracket */ + .opn { + color: #4d4d4c; } + + /* lisp close bracket */ + .clo { + color: #4d4d4c; } + + /* a markup tag name */ + .tag { + color: #c82829; } + + /* a markup attribute name */ + .atn { + color: #f5871f; } + + /* a markup attribute value */ + .atv { + color: #3e999f; } + + /* a declaration */ + .dec { + color: #f5871f; } + + /* a variable name */ + .var { + color: #c82829; } + + /* a function name */ + .fun { + color: #4271ae; } } +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { + color: #060; } + + .kwd { + color: #006; + font-weight: bold; } + + .com { + color: #600; + font-style: italic; } + + .typ { + color: #404; + font-weight: bold; } + + .lit { + color: #044; } + + .pun, .opn, .clo { + color: #440; } + + .tag { + color: #006; + font-weight: bold; } + + .atn { + color: #404; } + + .atv { + color: #060; } } +/* Style */ +/* +pre.prettyprint { + background: white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 12px; + line-height: 1.5; + border: 1px solid #ccc; + padding: 10px; } +*/ + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; } + +/* IE indents via margin-left */ +li.L0, +li.L1, +li.L2, +li.L3, +li.L4, +li.L5, +li.L6, +li.L7, +li.L8, +li.L9 { + /* */ } + +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { + /* */ }