generates multi page PDF from input JSON

6 slips to a page. The formatting needs to be cleaned up a little to be
honest, but this version actually seems to work for at least small
numbers of swimmers.

This works when interfaced with a google sheet that I've created with
a script that pings this particular endpoint. I'm actually very happy
with this solution so far.
This commit is contained in:
Zeddy 2018-04-14 15:51:42 -04:00
parent d23ada9594
commit 3e3ca7375c
7 changed files with 169 additions and 126 deletions

View File

@ -1,6 +1,5 @@
buildscript { buildscript {
ext.kotlin_version = '1.2.30' ext.kotlin_version = '1.2.30'
repositories { repositories {
mavenCentral() mavenCentral()
} }
@ -26,4 +25,5 @@ dependencies {
compileKotlin2Js.kotlinOptions { compileKotlin2Js.kotlinOptions {
moduleKind = "commonjs" moduleKind = "commonjs"
outputFile = "functions/index.js" outputFile = "functions/index.js"
sourceMap = true
} }

View File

@ -1,7 +1,2 @@
{ {
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
]
}
} }

View File

@ -1,14 +1,16 @@
(function (_, Kotlin) { (function (_, Kotlin) {
'use strict'; 'use strict';
var Kind_CLASS = Kotlin.Kind.CLASS; var Kind_CLASS = Kotlin.Kind.CLASS;
var listOf = Kotlin.kotlin.collections.listOf_i5x0yv$; var throwCCE = Kotlin.throwCCE;
var until = Kotlin.kotlin.ranges.until_dqglrj$;
var chunked = Kotlin.kotlin.collections.chunked_ba2ldo$;
function get_cm($receiver) { function get_cm($receiver) {
return $receiver / 2.54; return $receiver / 2.54;
} }
function get_asPoints($receiver) { function get_asPoints($receiver) {
return $receiver * 72; return $receiver * 72;
} }
function SlipInfo(eventNbr, event, lane, heat, swimmer, team) { function Entry(eventNbr, event, lane, heat, swimmer, team) {
this.eventNbr = eventNbr; this.eventNbr = eventNbr;
this.event = event; this.event = event;
this.lane = lane; this.lane = lane;
@ -16,36 +18,36 @@
this.swimmer = swimmer; this.swimmer = swimmer;
this.team = team; this.team = team;
} }
SlipInfo.$metadata$ = { Entry.$metadata$ = {
kind: Kind_CLASS, kind: Kind_CLASS,
simpleName: 'SlipInfo', simpleName: 'Entry',
interfaces: [] interfaces: []
}; };
SlipInfo.prototype.component1 = function () { Entry.prototype.component1 = function () {
return this.eventNbr; return this.eventNbr;
}; };
SlipInfo.prototype.component2 = function () { Entry.prototype.component2 = function () {
return this.event; return this.event;
}; };
SlipInfo.prototype.component3 = function () { Entry.prototype.component3 = function () {
return this.lane; return this.lane;
}; };
SlipInfo.prototype.component4 = function () { Entry.prototype.component4 = function () {
return this.heat; return this.heat;
}; };
SlipInfo.prototype.component5 = function () { Entry.prototype.component5 = function () {
return this.swimmer; return this.swimmer;
}; };
SlipInfo.prototype.component6 = function () { Entry.prototype.component6 = function () {
return this.team; return this.team;
}; };
SlipInfo.prototype.copy_cdqwiw$ = function (eventNbr, event, lane, heat, swimmer, team) { Entry.prototype.copy_cdqwiw$ = function (eventNbr, event, lane, heat, swimmer, team) {
return new SlipInfo(eventNbr === void 0 ? this.eventNbr : eventNbr, event === void 0 ? this.event : event, lane === void 0 ? this.lane : lane, heat === void 0 ? this.heat : heat, swimmer === void 0 ? this.swimmer : swimmer, team === void 0 ? this.team : team); return new Entry(eventNbr === void 0 ? this.eventNbr : eventNbr, event === void 0 ? this.event : event, lane === void 0 ? this.lane : lane, heat === void 0 ? this.heat : heat, swimmer === void 0 ? this.swimmer : swimmer, team === void 0 ? this.team : team);
}; };
SlipInfo.prototype.toString = function () { Entry.prototype.toString = function () {
return 'SlipInfo(eventNbr=' + Kotlin.toString(this.eventNbr) + (', event=' + Kotlin.toString(this.event)) + (', lane=' + Kotlin.toString(this.lane)) + (', heat=' + Kotlin.toString(this.heat)) + (', swimmer=' + Kotlin.toString(this.swimmer)) + (', team=' + Kotlin.toString(this.team)) + ')'; return 'Entry(eventNbr=' + Kotlin.toString(this.eventNbr) + (', event=' + Kotlin.toString(this.event)) + (', lane=' + Kotlin.toString(this.lane)) + (', heat=' + Kotlin.toString(this.heat)) + (', swimmer=' + Kotlin.toString(this.swimmer)) + (', team=' + Kotlin.toString(this.team)) + ')';
}; };
SlipInfo.prototype.hashCode = function () { Entry.prototype.hashCode = function () {
var result = 0; var result = 0;
result = result * 31 + Kotlin.hashCode(this.eventNbr) | 0; result = result * 31 + Kotlin.hashCode(this.eventNbr) | 0;
result = result * 31 + Kotlin.hashCode(this.event) | 0; result = result * 31 + Kotlin.hashCode(this.event) | 0;
@ -55,25 +57,89 @@
result = result * 31 + Kotlin.hashCode(this.team) | 0; result = result * 31 + Kotlin.hashCode(this.team) | 0;
return result; return result;
}; };
SlipInfo.prototype.equals = function (other) { Entry.prototype.equals = function (other) {
return this === other || (other !== null && (typeof other === 'object' && (Object.getPrototypeOf(this) === Object.getPrototypeOf(other) && (Kotlin.equals(this.eventNbr, other.eventNbr) && Kotlin.equals(this.event, other.event) && Kotlin.equals(this.lane, other.lane) && Kotlin.equals(this.heat, other.heat) && Kotlin.equals(this.swimmer, other.swimmer) && Kotlin.equals(this.team, other.team))))); return this === other || (other !== null && (typeof other === 'object' && (Object.getPrototypeOf(this) === Object.getPrototypeOf(other) && (Kotlin.equals(this.eventNbr, other.eventNbr) && Kotlin.equals(this.event, other.event) && Kotlin.equals(this.lane, other.lane) && Kotlin.equals(this.heat, other.heat) && Kotlin.equals(this.swimmer, other.swimmer) && Kotlin.equals(this.team, other.team)))));
}; };
function Meet(meet, entries) {
this.meet = meet;
this.entries = entries;
}
Meet.$metadata$ = {
kind: Kind_CLASS,
simpleName: 'Meet',
interfaces: []
};
Meet.prototype.component1 = function () {
return this.meet;
};
Meet.prototype.component2 = function () {
return this.entries;
};
Meet.prototype.copy_khic54$ = function (meet, entries) {
return new Meet(meet === void 0 ? this.meet : meet, entries === void 0 ? this.entries : entries);
};
Meet.prototype.toString = function () {
return 'Meet(meet=' + Kotlin.toString(this.meet) + (', entries=' + Kotlin.toString(this.entries)) + ')';
};
Meet.prototype.hashCode = function () {
var result = 0;
result = result * 31 + Kotlin.hashCode(this.meet) | 0;
result = result * 31 + Kotlin.hashCode(this.entries) | 0;
return result;
};
Meet.prototype.equals = function (other) {
return this === other || (other !== null && (typeof other === 'object' && (Object.getPrototypeOf(this) === Object.getPrototypeOf(other) && (Kotlin.equals(this.meet, other.meet) && Kotlin.equals(this.entries, other.entries)))));
};
function hydrateEntry(entry) {
return new Entry(entry.eventNbr, entry.event, entry.lane, entry.heat, entry.swimmer, entry.team);
}
var collectionSizeOrDefault = Kotlin.kotlin.collections.collectionSizeOrDefault_ba2ldo$;
var ArrayList_init = Kotlin.kotlin.collections.ArrayList_init_ww73n8$;
function iterate(list) {
var tmp$;
var $receiver = until(0, typeof (tmp$ = list.length) === 'number' ? tmp$ : throwCCE());
var destination = ArrayList_init(collectionSizeOrDefault($receiver, 10));
var tmp$_0;
tmp$_0 = $receiver.iterator();
while (tmp$_0.hasNext()) {
var item = tmp$_0.next();
destination.add_11rb$(list[item]);
}
return destination;
}
function hydrateMeet(meet) {
var tmp$ = meet.meet;
var $receiver = iterate(meet.entries);
var destination = ArrayList_init(collectionSizeOrDefault($receiver, 10));
var tmp$_0;
tmp$_0 = $receiver.iterator();
while (tmp$_0.hasNext()) {
var item = tmp$_0.next();
destination.add_11rb$(hydrateEntry(item));
}
return new Meet(tmp$, destination);
}
function main$lambda(req, res) { function main$lambda(req, res) {
var doc = new (require('pdfkit'))(); var doc = new (require('pdfkit'))({autoFirstPage: false});
var meetInfo = hydrateMeet(req.body);
res.setHeader('Content-Disposition', 'attachment;filename=' + '"' + 'lane-slips-' + meetInfo.meet + '.pdf' + '"');
res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Type', 'application/pdf');
var slips = listOf([new SlipInfo(1, 'Girls 8&U 100 Yd Medley Relay', 1, 1, 'A', 'Delshire'), new SlipInfo(1, 'Girls 8&U 100 Yd Medley Relay', 1, 3, 'B', 'Delshire'), new SlipInfo(19, 'Boys 15-18 50 Yd Freestyle', 3, 5, 'Jack Hart', 'Delshire'), new SlipInfo(19, 'Boys 15-18 50 Yd Freestyle', 6, 1, 'Joseph Obert', 'Delshire'), new SlipInfo(1, 'Girls 8&U 100 Yd Medley Relay', 1, 1, 'A', 'Delshire'), new SlipInfo(1, 'Girls 8&U 100 Yd Medley Relay', 1, 3, 'B', 'Delshire')]);
doc.pipe(res); doc.pipe(res);
writeSlip(slips.get_za3lpa$(0), doc, 0, 0); var tmp$;
writeSlip(slips.get_za3lpa$(1), doc, 1, 0); tmp$ = chunked(meetInfo.entries, 6).iterator();
writeSlip(slips.get_za3lpa$(2), doc, 0, 1); while (tmp$.hasNext()) {
writeSlip(slips.get_za3lpa$(3), doc, 1, 1); var element = tmp$.next();
writeSlip(slips.get_za3lpa$(4), doc, 0, 2); doc.addPage();
writeSlip(slips.get_za3lpa$(5), doc, 1, 2); var tmp$_0, tmp$_0_0;
var dashOptions = {}; var index = 0;
dashOptions.space = 10; tmp$_0 = element.iterator();
doc.moveTo(get_asPoints(get_cm(10.25)), get_asPoints(get_cm(1.0))).lineTo(get_asPoints(get_cm(10.25)), get_asPoints(get_cm(27.0))).dash(5, dashOptions).stroke(); while (tmp$_0.hasNext()) {
doc.moveTo(get_asPoints(get_cm(1.0)), get_asPoints(get_cm(8.5))).lineTo(get_asPoints(get_cm(21.0)), get_asPoints(get_cm(8.5))).dash(5, dashOptions).stroke(); var item = tmp$_0.next();
doc.moveTo(get_asPoints(get_cm(1.0)), get_asPoints(get_cm(16.5))).lineTo(get_asPoints(get_cm(21.0)), get_asPoints(get_cm(16.5))).dash(5, dashOptions).stroke(); var index_0 = (tmp$_0_0 = index, index = tmp$_0_0 + 1 | 0, tmp$_0_0);
writeSlip(item, doc, index_0 % 2, index_0 / 2 | 0);
}
drawDashes(doc);
}
return doc.end(); return doc.end();
} }
function main(args) { function main(args) {
@ -81,6 +147,13 @@
fireFunctions.config(); fireFunctions.config();
exports.laneslips = fireFunctions.https.onRequest(main$lambda); exports.laneslips = fireFunctions.https.onRequest(main$lambda);
} }
function drawDashes(doc) {
var dashOptions = {};
dashOptions.space = 10;
doc.moveTo(get_asPoints(get_cm(10.25)), get_asPoints(get_cm(1.0))).lineTo(get_asPoints(get_cm(10.25)), get_asPoints(get_cm(27.0))).dash(5, dashOptions).stroke();
doc.moveTo(get_asPoints(get_cm(1.0)), get_asPoints(get_cm(8.5))).lineTo(get_asPoints(get_cm(21.0)), get_asPoints(get_cm(8.5))).dash(5, dashOptions).stroke();
doc.moveTo(get_asPoints(get_cm(1.0)), get_asPoints(get_cm(16.5))).lineTo(get_asPoints(get_cm(21.0)), get_asPoints(get_cm(16.5))).dash(5, dashOptions).stroke();
}
function writeSlip($receiver, doc, x, y) { function writeSlip($receiver, doc, x, y) {
var xOffset = get_asPoints(get_cm(10.0)) * x; var xOffset = get_asPoints(get_cm(10.0)) * x;
var yOffset = get_asPoints(get_cm(8.0)) * y; var yOffset = get_asPoints(get_cm(8.0)) * y;
@ -143,10 +216,17 @@
var package$laneslips = package$cinphart.laneslips || (package$cinphart.laneslips = {}); var package$laneslips = package$cinphart.laneslips || (package$cinphart.laneslips = {});
package$laneslips.get_cm_yrwdxr$ = get_cm; package$laneslips.get_cm_yrwdxr$ = get_cm;
package$laneslips.get_asPoints_yrwdxr$ = get_asPoints; package$laneslips.get_asPoints_yrwdxr$ = get_asPoints;
package$laneslips.SlipInfo = SlipInfo; package$laneslips.Entry = Entry;
package$laneslips.Meet = Meet;
package$laneslips.hydrateEntry_za3rmp$ = hydrateEntry;
package$laneslips.iterate_za3rmp$ = iterate;
package$laneslips.hydrateMeet_za3rmp$ = hydrateMeet;
package$laneslips.main_kand9s$ = main; package$laneslips.main_kand9s$ = main;
package$laneslips.writeSlip_xwsitz$ = writeSlip; package$laneslips.drawDashes_za3rmp$ = drawDashes;
package$laneslips.writeSlip_dmpztf$ = writeSlip;
main([]); main([]);
Kotlin.defineModule('index', _); Kotlin.defineModule('index', _);
return _; return _;
}(module.exports, require('kotlin'))); }(module.exports, require('kotlin')));
//# sourceMappingURL=index.js.map

View File

@ -1 +1 @@
// Kotlin.kotlin_module_metadata(513, "index", "H4sIAAAAAAAAAF2Ty27TQBSGfYs9OUnbwaU0mAIh3CuBjLmIbUtBaRdV5YLEgo3rDI1FPBPsCW32KA8AG9Z9Cp6AR8gL8CKccYYksPH/zZl/5sx/JBvE9r978NsCV/BBxhmQNOPDflJIqA8SzspBNiyBHKPs848C3E9Cog/sHT4Gwr4wLg9PCrD3uYRatQT3WBYZPwVHnQenzxIJXnmW5TkrwJEsyQFSkQ8FR/eTJY6W+OkSP1vi50v8ApxUDMfgss+jZFCCtyvEgCUcakL2sRfpJ2X/lehhKCn0ozx2PhSFRPMhmlTFnyV6vDfmSZ6lb8dD9Cflkcg42tw9MToZMLDSHJw8weTOO55JcJLitITaTlEkY/AKfEFWMHBz0Ruhu35WZJKpoYHdEymY52CO/Q9gUQMcYlATvybFoROL2i0D6w6yQ2vISj2tda1XtF7TekPrLa23W0ZwYQabtB1YYSNq0k5AfMe3Qi9s/iRGsEXvBNDe2nZaZlgL65FL76LR607aavcRvaeObVuhHa3S+/85H+Cei/pQKdo7GzRYtryffDVVeY1eRwfgLfDyzaxw85/CD2J1LiwyIS07ssLabui71FWXohL1HFTQ64bWpq6vKD2o01VV7/6yEdeqBBXSRfXSAv2FYf0vvqaXAxWT4OCr3hVV3SuCea0xp+Z8d2V2jXmwTjcQSUToZlCNoTtVbVpV86mJeLWyTs1YZ4t11lhni3XWWGeMdUac0zdigRHoH+0PWtUuxaEDAAA="); // Kotlin.kotlin_module_metadata(513, "index", "H4sIAAAAAAAAAJVUTVMTQRDNfmR30knIuAiEBRVBRVFwCWh5BcFCSikraJXXZTNFttzsxN1ByN3iB3jy4MmDR8/+Af0J/B57JkNY8ORl35t+Pd39eqq2RCzvJ8BvCxyeJnHKgERx2u+GmYBKEqYsT+J+DuXtVGQDcD5wgUlgbaQDIOwTS8XeQQbWy1RAWR3B2RdZnB6CLS+D3WWhADc/jns9loEtWNgDiHivz1PMXi3wVoGvFfh6gT8p8KdgR7yPM7GPR2GSg7vJecLCFMpcdLEX6YZ59znvoCPBz4d6zZgAuye/LtbIYpZDNeJJwiIR8zQH+1WcS+2kzzOBRfewmLzpDZ2vbA3SsBdHbwd9rBvmb3icYpqzxY8OEgZmhO46WXi8hb2xtP0ujQVYHR5BrTtAQbDhIstMQVUH1VhuLJg84OrkDHYvxE3bYXaI69/IsnAAboZe44yB0+OdI+xXOc7w0j4+ERgnYAy8DExaApuUqIFfg5rgEJNazRLGbeQ2LSOX6GqsaJxUaFK/Ke/b9AaegN7U6pzGBY33ND5ulvxvpj9N7/pmMNYao4s+zN1esptGUA5qv0gJpfsoWSg9+FdaQqmC0sxVaZE+9KlX8wrhoIqJj64mTtFl1blGV3zi2Z4ZuEFDCrM0KOa2HLqKie7O6ZxUl2lLXlsaTrZ4JXMNNQdxXSKmz0/QW8WU96efDRlu0HnMqGOV+rMXw8CdS4GvxJz/bpJT0rRaZlDeDDyHOrIoIpHjIII+VzXWdLwucbdCx2R854+FtKEcKEovotcuqHeRMH5Ot+l19QAEH1f1Vkx1VwxGseqI1UZqfVjG2B2nE0hJi9ApX61h50y2aarmZwbSaZV6ZrS1t7b22tbe2tprW3tsa49ycT8MuaSKWtIkmp9RS6jRWf2oVlDVq1CeGriKkSADC8pkRY2s7rbGkM0Wk/7LwqXObT0PDvqFmFDy9W/wL9qlo788BQAA");

View File

@ -248,7 +248,7 @@
"@types/body-parser": { "@types/body-parser": {
"version": "1.16.8", "version": "1.16.8",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.16.8.tgz", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.16.8.tgz",
"integrity": "sha1-aH7DQUBiSjvsKxqOqSaEeK6PO+M=", "integrity": "sha512-BdN2PXxOFnTXFcyONPW6t0fHjz2fvRZHVMFpaS0wYr+Y8fWEaNOs4V8LEu/fpzQlMx+ahdndgTaGTwPC+J/EeA==",
"requires": { "requires": {
"@types/express": "4.11.1", "@types/express": "4.11.1",
"@types/node": "8.10.3" "@types/node": "8.10.3"
@ -257,7 +257,7 @@
"@types/cors": { "@types/cors": {
"version": "2.8.3", "version": "2.8.3",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.3.tgz", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.3.tgz",
"integrity": "sha1-6vbkdtoNNr7msGGiTVfjQ93OhtY=", "integrity": "sha512-wiZ7yYSIKZ005QJeyoUk5OHHEamNHTxaYwaFQWfTPohBjyhgIDHTgV8oGn+zBYTWQCb9WQYg54PhtntFTD7GVg==",
"requires": { "requires": {
"@types/express": "4.11.1" "@types/express": "4.11.1"
} }
@ -265,12 +265,12 @@
"@types/events": { "@types/events": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz",
"integrity": "sha1-gaZzHOTfQ2GeXIyUU4Oz5iqJ6oY=" "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA=="
}, },
"@types/express": { "@types/express": {
"version": "4.11.1", "version": "4.11.1",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.11.1.tgz", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.11.1.tgz",
"integrity": "sha1-+ZZjs6sy0EyxHbYS713Xkz91Rls=", "integrity": "sha512-ttWle8cnPA5rAelauSWeWJimtY2RsUf2aspYZs7xPHiWgOlPn6nnUfBMtrkcnjFJuIHJF4gNOdVvpLK2Zmvh6g==",
"requires": { "requires": {
"@types/body-parser": "1.16.8", "@types/body-parser": "1.16.8",
"@types/express-serve-static-core": "4.11.1", "@types/express-serve-static-core": "4.11.1",
@ -280,7 +280,7 @@
"@types/express-serve-static-core": { "@types/express-serve-static-core": {
"version": "4.11.1", "version": "4.11.1",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.11.1.tgz", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.11.1.tgz",
"integrity": "sha1-9vchI4LVmxnWlmd7yqSKNygPXUU=", "integrity": "sha512-EehCl3tpuqiM8RUb+0255M8PhhSwTtLfmO7zBBdv0ay/VTd/zmrqDfQdZFsa5z/PVMbH2yCMZPXsnrImpATyIw==",
"requires": { "requires": {
"@types/events": "1.2.0", "@types/events": "1.2.0",
"@types/node": "8.10.3" "@types/node": "8.10.3"
@ -297,7 +297,7 @@
"@types/jsonwebtoken": { "@types/jsonwebtoken": {
"version": "7.2.6", "version": "7.2.6",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-7.2.6.tgz", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-7.2.6.tgz",
"integrity": "sha1-jQGMIcpZELXrPryzhWVmBqIVAy8=", "integrity": "sha512-SuCA16HtLqPy0yerKEvMdaEAeLRgm6zPUJE1sF7bwGq0hAO4xW9UJZxTcDBaBwr5rcz1HST5QC1+1qXQ1+R9yw==",
"requires": { "requires": {
"@types/node": "8.10.3" "@types/node": "8.10.3"
} }
@ -305,7 +305,7 @@
"@types/lodash": { "@types/lodash": {
"version": "4.14.106", "version": "4.14.106",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.106.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.106.tgz",
"integrity": "sha1-YJPpoCqlZ93s/pr63KieU+Xc5N0=" "integrity": "sha512-tOSvCVrvSqFZ4A/qrqqm6p37GZoawsZtoR0SJhlF7EonNZUgrn8FfT+RNQ11h+NUpMt6QVe36033f3qEKBwfWA=="
}, },
"@types/long": { "@types/long": {
"version": "3.0.32", "version": "3.0.32",
@ -315,7 +315,7 @@
"@types/mime": { "@types/mime": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz",
"integrity": "sha1-WnMG42fFObn2VDSZ3o3VGfrDeos=" "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA=="
}, },
"@types/node": { "@types/node": {
"version": "8.10.3", "version": "8.10.3",
@ -325,7 +325,7 @@
"@types/serve-static": { "@types/serve-static": {
"version": "1.13.1", "version": "1.13.1",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.1.tgz", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.1.tgz",
"integrity": "sha1-HSgB+mNdJ0zZfU7AfiayG0QSdJI=", "integrity": "sha512-jDMH+3BQPtvqZVIcsH700Dfi8Q3MIcEx16g/VdxjoqiGR/NntekB10xdBpirMKnPe9z2C5cBmL0vte0YttOr3Q==",
"requires": { "requires": {
"@types/express-serve-static-core": "4.11.1", "@types/express-serve-static-core": "4.11.1",
"@types/mime": "2.0.0" "@types/mime": "2.0.0"
@ -706,7 +706,7 @@
"debug": { "debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": { "requires": {
"ms": "2.0.0" "ms": "2.0.0"
} }
@ -1107,7 +1107,7 @@
"content-type": { "content-type": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=" "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
}, },
"convert-source-map": { "convert-source-map": {
"version": "1.5.1", "version": "1.5.1",
@ -1712,7 +1712,7 @@
"debug": { "debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": { "requires": {
"ms": "2.0.0" "ms": "2.0.0"
} }
@ -1919,7 +1919,7 @@
"finalhandler": { "finalhandler": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
"integrity": "sha1-7r9O2EAHnIP0JJA4ydcDAIMBsQU=", "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"requires": { "requires": {
"debug": "2.6.9", "debug": "2.6.9",
"encodeurl": "1.0.2", "encodeurl": "1.0.2",
@ -1933,7 +1933,7 @@
"debug": { "debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": { "requires": {
"ms": "2.0.0" "ms": "2.0.0"
} }
@ -3939,7 +3939,7 @@
"moment": { "moment": {
"version": "2.22.0", "version": "2.22.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.22.0.tgz", "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.0.tgz",
"integrity": "sha1-eSGt4BAX3UUYbn/uX0JPC4ZjpzA=" "integrity": "sha512-1muXCh8jb1N/gHRbn9VDUBr0GYb8A/aVcHlII9QSB68a50spqEVLIGN6KVmCOnSvJrUhC0edGgKU5ofnGXdYdg=="
}, },
"ms": { "ms": {
"version": "2.0.0", "version": "2.0.0",
@ -4357,7 +4357,7 @@
"proxy-addr": { "proxy-addr": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz",
"integrity": "sha1-NV8mJQWmIWRrMTCnKOtkfiIFU0E=", "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==",
"requires": { "requires": {
"forwarded": "0.1.2", "forwarded": "0.1.2",
"ipaddr.js": "1.6.0" "ipaddr.js": "1.6.0"
@ -4652,7 +4652,7 @@
"send": { "send": {
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
"integrity": "sha1-bsyh4PjBVtFBWXVZhI32RzCmu8E=", "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
"requires": { "requires": {
"debug": "2.6.9", "debug": "2.6.9",
"depd": "1.1.2", "depd": "1.1.2",
@ -4672,7 +4672,7 @@
"debug": { "debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": { "requires": {
"ms": "2.0.0" "ms": "2.0.0"
} }
@ -4680,14 +4680,14 @@
"mime": { "mime": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
"integrity": "sha1-Eh+evEnjdm8xGnbh+hyAA8SwOqY=" "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
} }
} }
}, },
"serve-static": { "serve-static": {
"version": "1.13.2", "version": "1.13.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
"integrity": "sha1-CV6Ecv1bRiN9tQzkhqQ/S4bGzsE=", "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
"requires": { "requires": {
"encodeurl": "1.0.2", "encodeurl": "1.0.2",
"escape-html": "1.0.3", "escape-html": "1.0.3",
@ -4719,7 +4719,7 @@
"setprototypeof": { "setprototypeof": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
"integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=" "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
}, },
"shallow-copy": { "shallow-copy": {
"version": "0.0.1", "version": "0.0.1",
@ -4997,7 +4997,7 @@
"statuses": { "statuses": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
"integrity": "sha1-u3PURtonlhBu/MG2AaJT1sRr0Ic=" "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
}, },
"stream-events": { "stream-events": {
"version": "1.0.3", "version": "1.0.3",
@ -5252,7 +5252,7 @@
"type-is": { "type-is": {
"version": "1.6.16", "version": "1.6.16",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
"integrity": "sha1-+JzjQVQcZysl7nrjxz3uOyvlAZQ=", "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
"requires": { "requires": {
"media-typer": "0.3.0", "media-typer": "0.3.0",
"mime-types": "2.1.18" "mime-types": "2.1.18"

View File

@ -9,7 +9,7 @@ val Double.cm: Double
val Double.asPoints: Double val Double.asPoints: Double
get() = this * 72 get() = this * 72
data class SlipInfo( data class Entry(
val eventNbr: Int, val eventNbr: Int,
val event: String, val event: String,
val lane: Int, val lane: Int,
@ -17,83 +17,51 @@ data class SlipInfo(
val swimmer: String, val swimmer: String,
val team: String) val team: String)
data class Meet(val meet : String, val entries : List<Entry>)
fun hydrateEntry(entry : dynamic) = Entry(entry.eventNbr, entry.event, entry.lane, entry.heat, entry.swimmer, entry.team)
fun iterate(list : dynamic) : List<dynamic> = (0 until (list.length as Int)).map { list[it] }
fun hydrateMeet(meet : dynamic) = Meet(meet.meet, iterate(meet.entries).map { hydrateEntry(it) })
fun main(args: Array<String>) { fun main(args: Array<String>) {
val fireFunctions = require("firebase-functions") val fireFunctions = require("firebase-functions")
fireFunctions.config() fireFunctions.config()
exports.laneslips = fireFunctions.https.onRequest { req, res -> exports.laneslips = fireFunctions.https.onRequest { req, res ->
val doc = js("new (require('pdfkit'))()") val doc = js("new (require('pdfkit'))({autoFirstPage:false})")
//res.setHeader("Content-Disposition", "attachment;filename=\"lane-slips.pdf\"")
res.setHeader("Content-Type", "application/pdf")
val slips = listOf( val meetInfo = hydrateMeet(req.body)
SlipInfo(
eventNbr = 1, res.setHeader("Content-Disposition", "attachment;filename=\"lane-slips-${meetInfo.meet}.pdf\"")
event = "Girls 8&U 100 Yd Medley Relay", res.setHeader("Content-Type", "application/pdf")
lane = 1,
heat = 1,
swimmer = "A",
team = "Delshire"),
SlipInfo(
eventNbr = 1,
event = "Girls 8&U 100 Yd Medley Relay",
lane = 1,
heat = 3,
swimmer = "B",
team = "Delshire"),
SlipInfo(
eventNbr = 19,
event = "Boys 15-18 50 Yd Freestyle",
lane = 3,
heat = 5,
swimmer = "Jack Hart",
team = "Delshire"),
SlipInfo(
eventNbr = 19,
event = "Boys 15-18 50 Yd Freestyle",
lane = 6,
heat = 1,
swimmer = "Joseph Obert",
team = "Delshire"),
SlipInfo(
eventNbr = 1,
event = "Girls 8&U 100 Yd Medley Relay",
lane = 1,
heat = 1,
swimmer = "A",
team = "Delshire"),
SlipInfo(
eventNbr = 1,
event = "Girls 8&U 100 Yd Medley Relay",
lane = 1,
heat = 3,
swimmer = "B",
team = "Delshire")
)
doc.pipe(res) doc.pipe(res)
slips[0].writeSlip(doc, 0, 0) meetInfo.entries.chunked(6).forEach {
slips[1].writeSlip(doc, 1, 0) doc.addPage()
slips[2].writeSlip(doc, 0, 1) it.forEachIndexed { index, slip ->
slips[3].writeSlip(doc, 1, 1) slip.writeSlip(doc, index % 2, index / 2)
slips[4].writeSlip(doc, 0, 2) }
slips[5].writeSlip(doc, 1, 2) drawDashes(doc)
}
val dashOptions = js("{}")
dashOptions.space = 10
doc.moveTo(10.25.cm.asPoints, 1.0.cm.asPoints).lineTo(10.25.cm.asPoints, 27.0.cm.asPoints).dash(5, dashOptions).stroke()
doc.moveTo(1.0.cm.asPoints, 8.5.cm.asPoints).lineTo(21.0.cm.asPoints, 8.5.cm.asPoints).dash(5, dashOptions).stroke()
doc.moveTo(1.0.cm.asPoints, 16.5.cm.asPoints).lineTo(21.0.cm.asPoints, 16.5.cm.asPoints).dash(5, dashOptions).stroke()
doc.end() doc.end()
} }
} }
fun SlipInfo.writeSlip(doc: dynamic, x: Int, y: Int) { fun drawDashes(doc : dynamic) {
val dashOptions = js("{}")
dashOptions.space = 10
doc.moveTo(10.25.cm.asPoints, 1.0.cm.asPoints).lineTo(10.25.cm.asPoints, 27.0.cm.asPoints).dash(5, dashOptions).stroke()
doc.moveTo(1.0.cm.asPoints, 8.5.cm.asPoints).lineTo(21.0.cm.asPoints, 8.5.cm.asPoints).dash(5, dashOptions).stroke()
doc.moveTo(1.0.cm.asPoints, 16.5.cm.asPoints).lineTo(21.0.cm.asPoints, 16.5.cm.asPoints).dash(5, dashOptions).stroke()
}
fun Entry.writeSlip(doc: dynamic, x: Int, y: Int) {
val xOffset = 10.0.cm.asPoints * x val xOffset = 10.0.cm.asPoints * x
val yOffset = 8.0.cm.asPoints * y val yOffset = 8.0.cm.asPoints * y
val leftMargin = 1.0.cm.asPoints + xOffset val leftMargin = 1.0.cm.asPoints + xOffset