mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-12-01 06:18:06 +00:00
Merge branch 'master' into http-server
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
# Optional parameter is the username for signing edits
|
||||
|
||||
node ./tiddlywiki.js \
|
||||
editions/server \
|
||||
editions/tw5.com-server \
|
||||
--verbose \
|
||||
--server 8080 $:/core/save/lazy-images text/plain text/html $1 $2\
|
||||
|| exit 1
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<h1 class="">Script Files</h1><p>The <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a> repository contains several scripts in the <code>bin</code> folder that you can use to automate common tasks, or as a useful starting point for your own scripts. See <a class="tc-tiddlylink tc-tiddlylink-missing" href="http://tiddlywiki.com/static/Scripts%2520for%2520building%2520tiddlywiki.com.html">Scripts for building tiddlywiki.com</a> for details of the scripts used to build and release <a class="tc-tiddlylink-external" href="http://tiddlywiki.com/" rel="noopener noreferrer" target="_blank">http://tiddlywiki.com/</a>.</p><p>All the scripts expect to be run from the root folder of the repository.</p><h2 class=""><code>serve</code>: serves tw5.com</h2><pre><code>./bin/serve.sh -h
|
||||
<h1 class="">Script Files</h1><p>The <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a> repository contains several scripts in the <code>bin</code> folder that you can use to automate common tasks, or as a useful starting point for your own scripts. See <a class="tc-tiddlylink tc-tiddlylink-missing" href="https://tiddlywiki.com/static/Scripts%2520for%2520building%2520tiddlywiki.com.html">Scripts for building tiddlywiki.com</a> for details of the scripts used to build and release <a class="tc-tiddlylink-external" href="https://tiddlywiki.com/" rel="noopener noreferrer" target="_blank">https://tiddlywiki.com/</a>.</p><p>All the scripts expect to be run from the root folder of the repository.</p><h2 class=""><code>serve</code>: serves tw5.com</h2><pre><code>./bin/serve.sh -h
|
||||
./bin/serve.sh [edition dir] [username] [password] [host] [port]</code></pre><p>Or:</p><pre><code>./bin/serve.cmd -h
|
||||
./bin/serve.cmd [edition dir] [username] [password] [host] [port]</code></pre><p>This script starts <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a> running as an HTTP server, defaulting to the content from the <code>tw5.com-server</code> edition. By default, the Node.js serves on port 8080. If the optional <code>username</code> parameter is provided, it is used for signing edits. If the <code>password</code> is provided then HTTP basic authentication is used. Run the script with the <code>-h</code> parameter to see online help.</p><p>To experiment with this configuration, run the script and then visit <code>http://127.0.0.1:8080</code> in a browser.</p><p>Changes made in the browser propagate to the server over HTTP (use the browser developer console to see these requests). The server then syncs changes to the file system (and logs each change to the screen).</p><h2 class=""><code>test</code>: build and run tests</h2><p>This script runs the <code>test</code> edition of <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> on the server to perform the server-side tests and to build <code>test.html</code> for running the tests in the browser.</p><h2 class=""><code>lazy</code>: serves tw5.com with lazily loaded images</h2><pre><code>./bin/lazy.sh <username> [<password>]</code></pre><p>Or:</p><pre><code>./bin/lazy.cmd <username> [<password>]</code></pre><p>This script serves the <code>tw5.com-server</code> edition content with <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/LazyLoading.html">LazyLoading</a> applied to images.</p><h2 class=""><code>2bld</code>: builds <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> 2.6.5</h2><p>This script builds <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> 2.6.5 from the original source and then displays the differences between them (<code>diff</code> is used for *nix, <code>fc</code> for Windows).</p>
|
||||
./bin/serve.cmd [edition dir] [username] [password] [host] [port]</code></pre><p>This script starts <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a> running as an HTTP server, defaulting to the content from the <code>tw5.com-server</code> edition. By default, the Node.js serves on port 8080. If the optional <code>username</code> parameter is provided, it is used for signing edits. If the <code>password</code> is provided then HTTP basic authentication is used. Run the script with the <code>-h</code> parameter to see online help.</p><p>To experiment with this configuration, run the script and then visit <code>http://127.0.0.1:8080</code> in a browser.</p><p>Changes made in the browser propagate to the server over HTTP (use the browser developer console to see these requests). The server then syncs changes to the file system (and logs each change to the screen).</p><h2 class=""><code>test</code>: build and run tests</h2><p>This script runs the <code>test</code> edition of <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> on the server to perform the server-side tests and to build <code>test.html</code> for running the tests in the browser.</p><h2 class=""><code>lazy</code>: serves tw5.com with lazily loaded images</h2><pre><code>./bin/lazy.sh <username> [<password>]</code></pre><p>Or:</p><pre><code>./bin/lazy.cmd <username> [<password>]</code></pre><p>This script serves the <code>tw5.com-server</code> edition content with <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/LazyLoading.html">LazyLoading</a> applied to images.</p><h2 class=""><code>2bld</code>: builds <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> 2.6.5</h2><p>This script builds <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> 2.6.5 from the original source and then displays the differences between them (<code>diff</code> is used for *nix, <code>fc</code> for Windows).</p>
|
||||
@@ -9,37 +9,50 @@ Basic styles used before we boot up the parsing engine
|
||||
Error message and password prompt
|
||||
*/
|
||||
|
||||
.tc-password-wrapper, .tc-error-form {
|
||||
.tc-error-form {
|
||||
font-family: sans-serif;
|
||||
color: #fff;
|
||||
z-index: 20000;
|
||||
position: fixed;
|
||||
background-color: rgb(255, 75, 75);
|
||||
border: 8px solid rgb(255, 0, 0);
|
||||
border-radius: 8px;
|
||||
width: 50%;
|
||||
margin-left: 25%;
|
||||
margin-top: 4em;
|
||||
padding: 0 2em 1em 2em;
|
||||
}
|
||||
|
||||
.tc-error-form h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tc-error-prompt {
|
||||
text-align: center;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.tc-error-message {
|
||||
overflow: auto;
|
||||
max-height: 40em;
|
||||
padding-right: 1em;
|
||||
margin: 1em 0;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.tc-password-wrapper {
|
||||
font-family: sans-serif;
|
||||
z-index: 20000;
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
width: 200px;
|
||||
top: 4em;
|
||||
left: 50%;
|
||||
margin-left: -144px; /* - width/2 - paddingHorz/2 - border */
|
||||
left: 50%;
|
||||
margin-left: -144px; /* - width/2 - paddingHorz/2 - border */
|
||||
padding: 16px 16px 16px 16px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.tc-error-form {
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
|
||||
background-color: rgb(255, 75, 75);
|
||||
border: 8px solid rgb(255, 0, 0);
|
||||
width: 480px;
|
||||
margin-left: -244px; /* - width/2 - paddingHorz/2 - border */
|
||||
}
|
||||
|
||||
.tc-error-form div {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.tc-error-prompt {
|
||||
color: #000;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.tc-password-wrapper {
|
||||
color: #000;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||
|
||||
354
boot/boot.js
354
boot/boot.js
@@ -135,8 +135,8 @@ $tw.utils.error = function(err) {
|
||||
var dm = $tw.utils.domMaker,
|
||||
heading = dm("h1",{text: errHeading}),
|
||||
prompt = dm("div",{text: promptMsg, "class": "tc-error-prompt"}),
|
||||
message = dm("div",{text: err}),
|
||||
button = dm("button",{text: ( $tw.language == undefined ? "close" : $tw.language.getString("Buttons/Close/Caption") )}),
|
||||
message = dm("div",{text: err, "class":"tc-error-message"}),
|
||||
button = dm("div",{children: [dm("button",{text: ( $tw.language == undefined ? "close" : $tw.language.getString("Buttons/Close/Caption") )})], "class": "tc-error-prompt"}),
|
||||
form = dm("form",{children: [heading,prompt,message,button], "class": "tc-error-form"});
|
||||
document.body.insertBefore(form,document.body.firstChild);
|
||||
form.addEventListener("submit",function(event) {
|
||||
@@ -251,29 +251,35 @@ $tw.utils.parseDate = function(value) {
|
||||
|
||||
// Stringify an array of tiddler titles into a list string
|
||||
$tw.utils.stringifyList = function(value) {
|
||||
var result = [];
|
||||
for(var t=0; t<value.length; t++) {
|
||||
if(value[t].indexOf(" ") !== -1) {
|
||||
result.push("[[" + value[t] + "]]");
|
||||
} else {
|
||||
result.push(value[t]);
|
||||
if($tw.utils.isArray(value)) {
|
||||
var result = [];
|
||||
for(var t=0; t<value.length; t++) {
|
||||
var entry = value[t] || "";
|
||||
if(entry.indexOf(" ") !== -1) {
|
||||
result.push("[[" + entry + "]]");
|
||||
} else {
|
||||
result.push(entry);
|
||||
}
|
||||
}
|
||||
return result.join(" ");
|
||||
} else {
|
||||
return value || "";
|
||||
}
|
||||
return result.join(" ");
|
||||
};
|
||||
|
||||
// Parse a string array from a bracketted list. For example "OneTiddler [[Another Tiddler]] LastOne"
|
||||
$tw.utils.parseStringArray = function(value) {
|
||||
if(typeof value === "string") {
|
||||
var memberRegExp = /(?:^|[^\S\xA0])(?:\[\[(.*?)\]\])(?=[^\S\xA0]|$)|([\S\xA0]+)/mg,
|
||||
results = [],
|
||||
results = [], names = {},
|
||||
match;
|
||||
do {
|
||||
match = memberRegExp.exec(value);
|
||||
if(match) {
|
||||
var item = match[1] || match[2];
|
||||
if(item !== undefined && results.indexOf(item) === -1) {
|
||||
if(item !== undefined && !$tw.utils.hop(names,item)) {
|
||||
results.push(item);
|
||||
names[item] = true;
|
||||
}
|
||||
}
|
||||
} while(match);
|
||||
@@ -514,6 +520,9 @@ $tw.utils.PasswordPrompt.prototype.createPrompt = function(options) {
|
||||
if(options.canCancel) {
|
||||
children.push(dm("button",{
|
||||
text: $tw.language.getString("Encryption/Cancel"),
|
||||
attributes: {
|
||||
type: "button"
|
||||
},
|
||||
eventListeners: [{
|
||||
name: "click",
|
||||
handlerFunction: function(event) {
|
||||
@@ -635,9 +644,25 @@ $tw.utils.Crypto = function() {
|
||||
Execute the module named 'moduleName'. The name can optionally be relative to the module named 'moduleRoot'
|
||||
*/
|
||||
$tw.modules.execute = function(moduleName,moduleRoot) {
|
||||
var name = moduleName[0] === "." ? $tw.utils.resolvePath(moduleName,moduleRoot) : moduleName,
|
||||
moduleInfo = $tw.modules.titles[name] || $tw.modules.titles[name + ".js"] || $tw.modules.titles[moduleName] || $tw.modules.titles[moduleName + ".js"] ,
|
||||
tiddler = $tw.wiki.getTiddler(name) || $tw.wiki.getTiddler(name + ".js") || $tw.wiki.getTiddler(moduleName) || $tw.wiki.getTiddler(moduleName + ".js") ,
|
||||
var name = moduleName;
|
||||
if(moduleName.charAt(0) === ".") {
|
||||
name = $tw.utils.resolvePath(moduleName,moduleRoot)
|
||||
}
|
||||
if(!$tw.modules.titles[name]) {
|
||||
if($tw.modules.titles[name + ".js"]) {
|
||||
name = name + ".js";
|
||||
} else if($tw.modules.titles[name + "/index.js"]) {
|
||||
name = name + "/index.js";
|
||||
} else if($tw.modules.titles[moduleName]) {
|
||||
name = moduleName;
|
||||
} else if($tw.modules.titles[moduleName + ".js"]) {
|
||||
name = moduleName + ".js";
|
||||
} else if($tw.modules.titles[moduleName + "/index.js"]) {
|
||||
name = moduleName + "/index.js";
|
||||
}
|
||||
}
|
||||
var moduleInfo = $tw.modules.titles[name],
|
||||
tiddler = $tw.wiki.getTiddler(name),
|
||||
_exports = {},
|
||||
sandbox = {
|
||||
module: {exports: _exports},
|
||||
@@ -648,7 +673,7 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
|
||||
clearInterval: clearInterval,
|
||||
setTimeout: setTimeout,
|
||||
clearTimeout: clearTimeout,
|
||||
Buffer: $tw.browser ? {} : Buffer,
|
||||
Buffer: $tw.browser ? undefined : Buffer,
|
||||
$tw: $tw,
|
||||
require: function(title) {
|
||||
return $tw.modules.execute(title, name);
|
||||
@@ -802,6 +827,7 @@ taking precedence to the right
|
||||
*/
|
||||
$tw.Tiddler = function(/* [fields,] fields */) {
|
||||
this.fields = Object.create(null);
|
||||
this.cache = Object.create(null);
|
||||
for(var c=0; c<arguments.length; c++) {
|
||||
var arg = arguments[c],
|
||||
src = (arg instanceof $tw.Tiddler) ? arg.fields : arg;
|
||||
@@ -876,9 +902,23 @@ $tw.Wiki = function(options) {
|
||||
options = options || {};
|
||||
var self = this,
|
||||
tiddlers = Object.create(null), // Hashmap of tiddlers
|
||||
tiddlerTitles = null, // Array of tiddler titles
|
||||
getTiddlerTitles = function() {
|
||||
if(!tiddlerTitles) {
|
||||
tiddlerTitles = Object.keys(tiddlers);
|
||||
}
|
||||
return tiddlerTitles;
|
||||
},
|
||||
pluginTiddlers = [], // Array of tiddlers containing registered plugins, ordered by priority
|
||||
pluginInfo = Object.create(null), // Hashmap of parsed plugin content
|
||||
shadowTiddlers = options.shadowTiddlers || Object.create(null); // Hashmap by title of {source:, tiddler:}
|
||||
shadowTiddlers = options.shadowTiddlers || Object.create(null), // Hashmap by title of {source:, tiddler:}
|
||||
shadowTiddlerTitles = null,
|
||||
getShadowTiddlerTitles = function() {
|
||||
if(!shadowTiddlerTitles) {
|
||||
shadowTiddlerTitles = Object.keys(shadowTiddlers);
|
||||
}
|
||||
return shadowTiddlerTitles;
|
||||
};
|
||||
|
||||
// Add a tiddler to the store
|
||||
this.addTiddler = function(tiddler) {
|
||||
@@ -892,6 +932,9 @@ $tw.Wiki = function(options) {
|
||||
// Uncomment the following line for detailed logs of all tiddler writes
|
||||
// console.log("Adding",title,tiddler)
|
||||
tiddlers[title] = tiddler;
|
||||
if(tiddlerTitles && tiddlerTitles.indexOf(title) === -1) {
|
||||
tiddlerTitles.push(title);
|
||||
}
|
||||
this.clearCache(title);
|
||||
this.clearGlobalCache();
|
||||
this.enqueueTiddlerEvent(title);
|
||||
@@ -902,9 +945,15 @@ $tw.Wiki = function(options) {
|
||||
// Delete a tiddler
|
||||
this.deleteTiddler = function(title) {
|
||||
// Uncomment the following line for detailed logs of all tiddler deletions
|
||||
// console.log("Deleting",title,tiddler)
|
||||
// console.log("Deleting",title)
|
||||
if($tw.utils.hop(tiddlers,title)) {
|
||||
delete tiddlers[title];
|
||||
if(tiddlerTitles) {
|
||||
var index = tiddlerTitles.indexOf(title);
|
||||
if(index !== -1) {
|
||||
tiddlerTitles.splice(index,1);
|
||||
}
|
||||
}
|
||||
this.clearCache(title);
|
||||
this.clearGlobalCache();
|
||||
this.enqueueTiddlerEvent(title,true);
|
||||
@@ -917,7 +966,7 @@ $tw.Wiki = function(options) {
|
||||
var t = tiddlers[title];
|
||||
if(t instanceof $tw.Tiddler) {
|
||||
return t;
|
||||
} else if(title !== undefined && Object.prototype.hasOwnProperty.call(shadowTiddlers,title)) {
|
||||
} else if(title !== undefined && shadowTiddlers[title]) {
|
||||
return shadowTiddlers[title].tiddler;
|
||||
}
|
||||
return undefined;
|
||||
@@ -926,12 +975,12 @@ $tw.Wiki = function(options) {
|
||||
|
||||
// Get an array of all tiddler titles
|
||||
this.allTitles = function() {
|
||||
return Object.keys(tiddlers);
|
||||
return getTiddlerTitles().slice(0);
|
||||
};
|
||||
|
||||
// Iterate through all tiddler titles
|
||||
this.each = function(callback) {
|
||||
var titles = Object.keys(tiddlers),
|
||||
var titles = getTiddlerTitles(),
|
||||
index,titlesLength,title;
|
||||
for(index = 0, titlesLength = titles.length; index < titlesLength; index++) {
|
||||
title = titles[index];
|
||||
@@ -941,12 +990,12 @@ $tw.Wiki = function(options) {
|
||||
|
||||
// Get an array of all shadow tiddler titles
|
||||
this.allShadowTitles = function() {
|
||||
return Object.keys(shadowTiddlers);
|
||||
return getShadowTiddlerTitles().slice(0);
|
||||
};
|
||||
|
||||
// Iterate through all shadow tiddler titles
|
||||
this.eachShadow = function(callback) {
|
||||
var titles = Object.keys(shadowTiddlers),
|
||||
var titles = getShadowTiddlerTitles(),
|
||||
index,titlesLength,title;
|
||||
for(index = 0, titlesLength = titles.length; index < titlesLength; index++) {
|
||||
title = titles[index];
|
||||
@@ -957,16 +1006,16 @@ $tw.Wiki = function(options) {
|
||||
|
||||
// Iterate through all tiddlers and then the shadows
|
||||
this.eachTiddlerPlusShadows = function(callback) {
|
||||
var titles = Object.keys(tiddlers),
|
||||
index,titlesLength,title;
|
||||
var index,titlesLength,title,
|
||||
titles = getTiddlerTitles();
|
||||
for(index = 0, titlesLength = titles.length; index < titlesLength; index++) {
|
||||
title = titles[index];
|
||||
callback(tiddlers[title],title);
|
||||
}
|
||||
titles = Object.keys(shadowTiddlers);
|
||||
titles = getShadowTiddlerTitles();
|
||||
for(index = 0, titlesLength = titles.length; index < titlesLength; index++) {
|
||||
title = titles[index];
|
||||
if(!Object.prototype.hasOwnProperty.call(tiddlers,title)) {
|
||||
if(!tiddlers[title]) {
|
||||
var shadowInfo = shadowTiddlers[title];
|
||||
callback(shadowInfo.tiddler,title);
|
||||
}
|
||||
@@ -975,21 +1024,21 @@ $tw.Wiki = function(options) {
|
||||
|
||||
// Iterate through all the shadows and then the tiddlers
|
||||
this.eachShadowPlusTiddlers = function(callback) {
|
||||
var titles = Object.keys(shadowTiddlers),
|
||||
index,titlesLength,title;
|
||||
var index,titlesLength,title,
|
||||
titles = getShadowTiddlerTitles();
|
||||
for(index = 0, titlesLength = titles.length; index < titlesLength; index++) {
|
||||
title = titles[index];
|
||||
if(Object.prototype.hasOwnProperty.call(tiddlers,title)) {
|
||||
if(tiddlers[title]) {
|
||||
callback(tiddlers[title],title);
|
||||
} else {
|
||||
var shadowInfo = shadowTiddlers[title];
|
||||
callback(shadowInfo.tiddler,title);
|
||||
}
|
||||
}
|
||||
titles = Object.keys(tiddlers);
|
||||
titles = getTiddlerTitles();
|
||||
for(index = 0, titlesLength = titles.length; index < titlesLength; index++) {
|
||||
title = titles[index];
|
||||
if(!Object.prototype.hasOwnProperty.call(shadowTiddlers,title)) {
|
||||
if(!shadowTiddlers[title]) {
|
||||
callback(tiddlers[title],title);
|
||||
}
|
||||
}
|
||||
@@ -1104,6 +1153,7 @@ $tw.Wiki = function(options) {
|
||||
});
|
||||
}
|
||||
});
|
||||
shadowTiddlerTitles = null;
|
||||
this.clearCache(null);
|
||||
this.clearGlobalCache();
|
||||
};
|
||||
@@ -1176,7 +1226,7 @@ $tw.Wiki.prototype.processSafeMode = function() {
|
||||
// Assemble a report tiddler
|
||||
var titleReportTiddler = "TiddlyWiki Safe Mode",
|
||||
report = [];
|
||||
report.push("TiddlyWiki has been started in [[safe mode|http://tiddlywiki.com/static/SafeMode.html]]. All plugins are temporarily disabled. Most customisations have been disabled by renaming the following tiddlers:")
|
||||
report.push("TiddlyWiki has been started in [[safe mode|https://tiddlywiki.com/static/SafeMode.html]]. All plugins are temporarily disabled. Most customisations have been disabled by renaming the following tiddlers:")
|
||||
// Delete the overrides
|
||||
overrides.forEach(function(title) {
|
||||
var tiddler = self.getTiddler(title),
|
||||
@@ -1194,10 +1244,14 @@ $tw.Wiki.prototype.processSafeMode = function() {
|
||||
/*
|
||||
Extracts tiddlers from a typed block of text, specifying default field values
|
||||
*/
|
||||
$tw.Wiki.prototype.deserializeTiddlers = function(type,text,srcFields) {
|
||||
$tw.Wiki.prototype.deserializeTiddlers = function(type,text,srcFields,options) {
|
||||
srcFields = srcFields || Object.create(null);
|
||||
var deserializer = $tw.Wiki.tiddlerDeserializerModules[type],
|
||||
options = options || {};
|
||||
var deserializer = $tw.Wiki.tiddlerDeserializerModules[options.deserializer],
|
||||
fields = Object.create(null);
|
||||
if(!deserializer) {
|
||||
deserializer = $tw.Wiki.tiddlerDeserializerModules[type];
|
||||
}
|
||||
if(!deserializer && $tw.utils.getFileExtensionInfo(type)) {
|
||||
// If we didn't find the serializer, try converting it from an extension to a content type
|
||||
type = $tw.utils.getFileExtensionInfo(type).type;
|
||||
@@ -1227,8 +1281,7 @@ $tw.Wiki.prototype.deserializeTiddlers = function(type,text,srcFields) {
|
||||
/*
|
||||
Register the built in tiddler deserializer modules
|
||||
*/
|
||||
$tw.modules.define("$:/boot/tiddlerdeserializer/js","tiddlerdeserializer",{
|
||||
"application/javascript": function(text,fields) {
|
||||
var deserializeHeaderComment = function(text,fields) {
|
||||
var headerCommentRegExp = new RegExp($tw.config.jsModuleHeaderRegExpString,"mg"),
|
||||
match = headerCommentRegExp.exec(text);
|
||||
fields.text = text;
|
||||
@@ -1236,7 +1289,12 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/js","tiddlerdeserializer",{
|
||||
fields = $tw.utils.parseFields(match[1].split(/\r?\n\r?\n/mg)[0],fields);
|
||||
}
|
||||
return [fields];
|
||||
}
|
||||
};
|
||||
$tw.modules.define("$:/boot/tiddlerdeserializer/js","tiddlerdeserializer",{
|
||||
"application/javascript": deserializeHeaderComment
|
||||
});
|
||||
$tw.modules.define("$:/boot/tiddlerdeserializer/css","tiddlerdeserializer",{
|
||||
"text/css": deserializeHeaderComment
|
||||
});
|
||||
$tw.modules.define("$:/boot/tiddlerdeserializer/tid","tiddlerdeserializer",{
|
||||
"application/x-tiddler": function(text,fields) {
|
||||
@@ -1261,15 +1319,15 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/tids","tiddlerdeserializer",{
|
||||
for(var t=0; t<lines.length; t++) {
|
||||
var line = lines[t];
|
||||
if(line.charAt(0) !== "#") {
|
||||
var colonPos= line.indexOf(": ");
|
||||
var colonPos= line.indexOf(":");
|
||||
if(colonPos !== -1) {
|
||||
var tiddler = $tw.utils.extend(Object.create(null),fields);
|
||||
tiddler.title = (tiddler.title || "") + line.substr(0,colonPos);
|
||||
tiddler.title = (tiddler.title || "") + line.substr(0,colonPos).trim();
|
||||
if(titles.indexOf(tiddler.title) !== -1) {
|
||||
console.log("Warning: .multids file contains multiple definitions for " + tiddler.title);
|
||||
}
|
||||
titles.push(tiddler.title);
|
||||
tiddler.text = line.substr(colonPos + 2);
|
||||
tiddler.text = line.substr(colonPos + 2).trim();
|
||||
tiddlers.push(tiddler);
|
||||
}
|
||||
}
|
||||
@@ -1294,8 +1352,8 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/html","tiddlerdeserializer",{
|
||||
});
|
||||
$tw.modules.define("$:/boot/tiddlerdeserializer/json","tiddlerdeserializer",{
|
||||
"application/json": function(text,fields) {
|
||||
var tiddlers = JSON.parse(text);
|
||||
return tiddlers;
|
||||
var data = JSON.parse(text);
|
||||
return $tw.utils.isArray(data) ? data : [data];
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1448,17 +1506,26 @@ $tw.loadTiddlersFromFile = function(filepath,fields) {
|
||||
typeInfo = type ? $tw.config.contentTypeInfo[type] : null,
|
||||
data = fs.readFileSync(filepath,typeInfo ? typeInfo.encoding : "utf8"),
|
||||
tiddlers = $tw.wiki.deserializeTiddlers(ext,data,fields),
|
||||
metafile = filepath + ".meta",
|
||||
metadata;
|
||||
if(ext !== ".json" && tiddlers.length === 1 && fs.existsSync(metafile)) {
|
||||
metadata = fs.readFileSync(metafile,"utf8");
|
||||
if(metadata) {
|
||||
tiddlers = [$tw.utils.parseFields(metadata,tiddlers[0])];
|
||||
}
|
||||
if(ext !== ".json" && tiddlers.length === 1) {
|
||||
metadata = $tw.loadMetadataForFile(filepath);
|
||||
tiddlers = [$tw.utils.extend({},tiddlers[0],metadata)];
|
||||
}
|
||||
return {filepath: filepath, type: type, tiddlers: tiddlers, hasMetaFile: !!metadata};
|
||||
};
|
||||
|
||||
/*
|
||||
Load the metadata fields in the .meta file corresponding to a particular file
|
||||
*/
|
||||
$tw.loadMetadataForFile = function(filepath) {
|
||||
var metafilename = filepath + ".meta";
|
||||
if(fs.existsSync(metafilename)) {
|
||||
return $tw.utils.parseFields(fs.readFileSync(metafilename,"utf8") || "");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
A default set of files for TiddlyWiki to ignore during load.
|
||||
This matches what NPM ignores, and adds "*.meta" to ignore tiddler
|
||||
@@ -1478,44 +1545,7 @@ $tw.loadTiddlersFromPath = function(filepath,excludeRegExp) {
|
||||
var files = fs.readdirSync(filepath);
|
||||
// Look for a tiddlywiki.files file
|
||||
if(files.indexOf("tiddlywiki.files") !== -1) {
|
||||
// If so, process the files it describes
|
||||
var filesInfo = JSON.parse(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
|
||||
// First the tiddlers
|
||||
$tw.utils.each(filesInfo.tiddlers,function(tidInfo) {
|
||||
var type = tidInfo.fields.type || "text/plain",
|
||||
typeInfo = $tw.config.contentTypeInfo[type],
|
||||
pathname = path.resolve(filepath,tidInfo.file),
|
||||
text = fs.readFileSync(pathname,typeInfo ? typeInfo.encoding : "utf8");
|
||||
if(tidInfo.isTiddlerFile) {
|
||||
var fileTiddlers = $tw.wiki.deserializeTiddlers(path.extname(pathname),text) || [];
|
||||
$tw.utils.each(fileTiddlers,function(tiddler) {
|
||||
$tw.utils.extend(tiddler,tidInfo.fields);
|
||||
if(tidInfo.prefix) {
|
||||
tiddler.text = tidInfo.prefix + tiddler.text;
|
||||
}
|
||||
if(tidInfo.suffix) {
|
||||
tiddler.text = tiddler.text + tidInfo.suffix;
|
||||
}
|
||||
});
|
||||
tiddlers.push({tiddlers: fileTiddlers});
|
||||
} else {
|
||||
if(tidInfo.prefix) {
|
||||
text = tidInfo.prefix + text;
|
||||
}
|
||||
if(tidInfo.suffix) {
|
||||
text = text + tidInfo.suffix;
|
||||
}
|
||||
tidInfo.fields.text = text;
|
||||
tiddlers.push({tiddlers: [tidInfo.fields]});
|
||||
}
|
||||
});
|
||||
// Then any recursive directories
|
||||
$tw.utils.each(filesInfo.directories,function(dirPath) {
|
||||
var pathname = path.resolve(filepath,dirPath);
|
||||
if(fs.existsSync(pathname) && fs.statSync(pathname).isDirectory()) {
|
||||
tiddlers.push.apply(tiddlers,$tw.loadTiddlersFromPath(pathname,excludeRegExp));
|
||||
}
|
||||
});
|
||||
Array.prototype.push.apply(tiddlers,$tw.loadTiddlersFromSpecification(filepath,excludeRegExp));
|
||||
} else {
|
||||
// If not, read all the files in the directory
|
||||
$tw.utils.each(files,function(file) {
|
||||
@@ -1525,20 +1555,125 @@ $tw.loadTiddlersFromPath = function(filepath,excludeRegExp) {
|
||||
});
|
||||
}
|
||||
} else if(stat.isFile()) {
|
||||
tiddlers.push($tw.loadTiddlersFromFile(filepath));
|
||||
tiddlers.push($tw.loadTiddlersFromFile(filepath,{title: filepath}));
|
||||
}
|
||||
}
|
||||
return tiddlers;
|
||||
};
|
||||
|
||||
/*
|
||||
Load all the tiddlers defined by a `tiddlywiki.files` specification file
|
||||
filepath: pathname of the directory containing the specification file
|
||||
*/
|
||||
$tw.loadTiddlersFromSpecification = function(filepath,excludeRegExp) {
|
||||
var tiddlers = [];
|
||||
// Read the specification
|
||||
var filesInfo = JSON.parse(fs.readFileSync(filepath + path.sep + "tiddlywiki.files","utf8"));
|
||||
// Helper to process a file
|
||||
var processFile = function(filename,isTiddlerFile,fields) {
|
||||
var extInfo = $tw.config.fileExtensionInfo[path.extname(filename)],
|
||||
type = (extInfo || {}).type || fields.type || "text/plain",
|
||||
typeInfo = $tw.config.contentTypeInfo[type] || {},
|
||||
pathname = path.resolve(filepath,filename),
|
||||
text = fs.readFileSync(pathname,typeInfo.encoding || "utf8"),
|
||||
metadata = $tw.loadMetadataForFile(pathname) || {},
|
||||
fileTiddlers;
|
||||
if(isTiddlerFile) {
|
||||
fileTiddlers = $tw.wiki.deserializeTiddlers(path.extname(pathname),text,metadata) || [];
|
||||
} else {
|
||||
fileTiddlers = [$tw.utils.extend({text: text},metadata)];
|
||||
}
|
||||
var combinedFields = $tw.utils.extend({},fields,metadata);
|
||||
$tw.utils.each(fileTiddlers,function(tiddler) {
|
||||
$tw.utils.each(combinedFields,function(fieldInfo,name) {
|
||||
if(typeof fieldInfo === "string" || $tw.utils.isArray(fieldInfo)) {
|
||||
tiddler[name] = fieldInfo;
|
||||
} else {
|
||||
var value = tiddler[name];
|
||||
switch(fieldInfo.source) {
|
||||
case "filename":
|
||||
value = path.basename(filename);
|
||||
break;
|
||||
case "filename-uri-decoded":
|
||||
value = decodeURIComponent(path.basename(filename));
|
||||
break;
|
||||
case "basename":
|
||||
value = path.basename(filename,path.extname(filename));
|
||||
break;
|
||||
case "basename-uri-decoded":
|
||||
value = decodeURIComponent(path.basename(filename,path.extname(filename)));
|
||||
break;
|
||||
case "extname":
|
||||
value = path.extname(filename);
|
||||
break;
|
||||
case "created":
|
||||
value = new Date(fs.statSync(pathname).birthtime);
|
||||
break;
|
||||
case "modified":
|
||||
value = new Date(fs.statSync(pathname).mtime);
|
||||
break;
|
||||
}
|
||||
if(fieldInfo.prefix) {
|
||||
value = fieldInfo.prefix + value;
|
||||
}
|
||||
if(fieldInfo.suffix) {
|
||||
value = value + fieldInfo.suffix;
|
||||
}
|
||||
tiddler[name] = value;
|
||||
}
|
||||
});
|
||||
});
|
||||
tiddlers.push({tiddlers: fileTiddlers});
|
||||
};
|
||||
// Process the listed tiddlers
|
||||
$tw.utils.each(filesInfo.tiddlers,function(tidInfo) {
|
||||
if(tidInfo.prefix && tidInfo.suffix) {
|
||||
tidInfo.fields.text = {prefix: tidInfo.prefix,suffix: tidInfo.suffix};
|
||||
} else if(tidInfo.prefix) {
|
||||
tidInfo.fields.text = {prefix: tidInfo.prefix};
|
||||
} else if(tidInfo.suffix) {
|
||||
tidInfo.fields.text = {suffix: tidInfo.suffix};
|
||||
}
|
||||
processFile(tidInfo.file,tidInfo.isTiddlerFile,tidInfo.fields);
|
||||
});
|
||||
// Process any listed directories
|
||||
$tw.utils.each(filesInfo.directories,function(dirSpec) {
|
||||
// Read literal directories directly
|
||||
if(typeof dirSpec === "string") {
|
||||
var pathname = path.resolve(filepath,dirSpec);
|
||||
if(fs.existsSync(pathname) && fs.statSync(pathname).isDirectory()) {
|
||||
tiddlers.push.apply(tiddlers,$tw.loadTiddlersFromPath(pathname,excludeRegExp));
|
||||
}
|
||||
} else {
|
||||
// Process directory specifier
|
||||
var dirPath = path.resolve(filepath,dirSpec.path),
|
||||
files = fs.readdirSync(dirPath),
|
||||
fileRegExp = new RegExp(dirSpec.filesRegExp || "^.*$"),
|
||||
metaRegExp = /^.*\.meta$/;
|
||||
for(var t=0; t<files.length; t++) {
|
||||
var filename = files[t];
|
||||
if(filename !== "tiddlywiki.files" && !metaRegExp.test(filename) && fileRegExp.test(filename)) {
|
||||
processFile(dirPath + path.sep + filename,dirSpec.isTiddlerFile,dirSpec.fields);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return tiddlers;
|
||||
};
|
||||
|
||||
/*
|
||||
Load the tiddlers from a plugin folder, and package them up into a proper JSON plugin tiddler
|
||||
*/
|
||||
$tw.loadPluginFolder = function(filepath,excludeRegExp) {
|
||||
excludeRegExp = excludeRegExp || $tw.boot.excludeRegExp;
|
||||
var infoPath = filepath + path.sep + "plugin.info";
|
||||
if(fs.existsSync(filepath) && fs.statSync(filepath).isDirectory()) {
|
||||
// Read the plugin information
|
||||
var pluginInfo = JSON.parse(fs.readFileSync(filepath + path.sep + "plugin.info","utf8"));
|
||||
if(!fs.existsSync(infoPath) || !fs.statSync(infoPath).isFile()) {
|
||||
console.log("Warning: missing plugin.info file in " + filepath);
|
||||
return null;
|
||||
}
|
||||
var pluginInfo = JSON.parse(fs.readFileSync(infoPath,"utf8"));
|
||||
// Read the plugin files
|
||||
var pluginFiles = $tw.loadTiddlersFromPath(filepath,excludeRegExp);
|
||||
// Save the plugin tiddlers into the plugin info
|
||||
@@ -1699,9 +1834,13 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
|
||||
// Save the original tiddler file locations if requested
|
||||
var config = wikiInfo.config || {};
|
||||
if(config["retain-original-tiddler-path"]) {
|
||||
var output = {};
|
||||
var output = {}, relativePath;
|
||||
for(var title in $tw.boot.files) {
|
||||
output[title] = path.relative(resolvedWikiPath,$tw.boot.files[title].filepath);
|
||||
relativePath = path.relative(resolvedWikiPath,$tw.boot.files[title].filepath);
|
||||
output[title] =
|
||||
path.sep === path.posix.sep ?
|
||||
relativePath :
|
||||
relativePath.split(path.sep).join(path.posix.sep);
|
||||
}
|
||||
$tw.wiki.addTiddler({title: "$:/config/OriginalTiddlerPaths", type: "application/json", text: JSON.stringify(output)});
|
||||
}
|
||||
@@ -1807,7 +1946,7 @@ $tw.boot.startup = function(options) {
|
||||
// For writable tiddler files, a hashmap of title to {filepath:,type:,hasMetaFile:}
|
||||
$tw.boot.files = Object.create(null);
|
||||
// System paths and filenames
|
||||
$tw.boot.bootPath = path.dirname(module.filename);
|
||||
$tw.boot.bootPath = options.bootPath || path.dirname(module.filename);
|
||||
$tw.boot.corePath = path.resolve($tw.boot.bootPath,"../core");
|
||||
// If there's no arguments then default to `--help`
|
||||
if($tw.boot.argv.length === 0) {
|
||||
@@ -1849,12 +1988,21 @@ $tw.boot.startup = function(options) {
|
||||
$tw.utils.registerFileType("image/svg+xml","utf8",".svg",{flags:["image"]});
|
||||
$tw.utils.registerFileType("image/x-icon","base64",".ico",{flags:["image"]});
|
||||
$tw.utils.registerFileType("application/font-woff","base64",".woff");
|
||||
$tw.utils.registerFileType("application/x-font-ttf","base64",".woff");
|
||||
$tw.utils.registerFileType("audio/ogg","base64",".ogg");
|
||||
$tw.utils.registerFileType("video/mp4","base64",".mp4");
|
||||
$tw.utils.registerFileType("audio/mp3","base64",".mp3");
|
||||
$tw.utils.registerFileType("audio/mp4","base64",[".mp4",".m4a"]);
|
||||
$tw.utils.registerFileType("text/markdown","utf8",[".md",".markdown"],{deserializerType:"text/x-markdown"});
|
||||
$tw.utils.registerFileType("text/x-markdown","utf8",[".md",".markdown"]);
|
||||
$tw.utils.registerFileType("application/enex+xml","utf8",".enex");
|
||||
$tw.utils.registerFileType("application/enex+xml","utf8",".enex");
|
||||
$tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.wordprocessingml.document","base64",".docx");
|
||||
$tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","base64",".xlsx");
|
||||
$tw.utils.registerFileType("application/vnd.openxmlformats-officedocument.presentationml.presentation","base64",".pptx");
|
||||
$tw.utils.registerFileType("text/x-bibtex","utf8",".bib",{deserializerType:"application/x-bibtex"});
|
||||
$tw.utils.registerFileType("application/x-bibtex","utf8",".bib");
|
||||
$tw.utils.registerFileType("application/epub+zip","base64",".epub");
|
||||
$tw.utils.registerFileType("application/octet-stream","base64",".octet-stream");
|
||||
// Create the wiki store for the app
|
||||
$tw.wiki = new $tw.Wiki();
|
||||
// Install built in tiddler fields modules
|
||||
@@ -1913,7 +2061,7 @@ $tw.boot.startup = function(options) {
|
||||
$tw.boot.executedStartupModules = Object.create(null);
|
||||
$tw.boot.disabledStartupModules = $tw.boot.disabledStartupModules || [];
|
||||
// Repeatedly execute the next eligible task
|
||||
$tw.boot.executeNextStartupTask();
|
||||
$tw.boot.executeNextStartupTask(options.callback);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1928,14 +2076,14 @@ $tw.addUnloadTask = function(task) {
|
||||
/*
|
||||
Execute the remaining eligible startup tasks
|
||||
*/
|
||||
$tw.boot.executeNextStartupTask = function() {
|
||||
$tw.boot.executeNextStartupTask = function(callback) {
|
||||
// Find the next eligible task
|
||||
var taskIndex = 0, task,
|
||||
asyncTaskCallback = function() {
|
||||
if(task.name) {
|
||||
$tw.boot.executedStartupModules[task.name] = true;
|
||||
}
|
||||
return $tw.boot.executeNextStartupTask();
|
||||
return $tw.boot.executeNextStartupTask(callback);
|
||||
};
|
||||
while(taskIndex < $tw.boot.remainingStartupModules.length) {
|
||||
task = $tw.boot.remainingStartupModules[taskIndex];
|
||||
@@ -1960,7 +2108,7 @@ $tw.boot.executeNextStartupTask = function() {
|
||||
if(task.name) {
|
||||
$tw.boot.executedStartupModules[task.name] = true;
|
||||
}
|
||||
return $tw.boot.executeNextStartupTask();
|
||||
return $tw.boot.executeNextStartupTask(callback);
|
||||
} else {
|
||||
task.startup(asyncTaskCallback);
|
||||
return true;
|
||||
@@ -1968,6 +2116,9 @@ $tw.boot.executeNextStartupTask = function() {
|
||||
}
|
||||
taskIndex++;
|
||||
}
|
||||
if(typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -2041,18 +2192,19 @@ $tw.hooks.addHook = function(hookName,definition) {
|
||||
/*
|
||||
Invoke the hook by key
|
||||
*/
|
||||
$tw.hooks.invokeHook = function(hookName, value) {
|
||||
$tw.hooks.invokeHook = function(hookName /*, value,... */) {
|
||||
var args = Array.prototype.slice.call(arguments,1);
|
||||
if($tw.utils.hop($tw.hooks.names,hookName)) {
|
||||
for (var i = 0; i < $tw.hooks.names[hookName].length; i++) {
|
||||
value = $tw.hooks.names[hookName][i](value);
|
||||
args[0] = $tw.hooks.names[hookName][i].apply(null,args);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
return args[0];
|
||||
};
|
||||
|
||||
/////////////////////////// Main boot function to decrypt tiddlers and then startup
|
||||
|
||||
$tw.boot.boot = function() {
|
||||
$tw.boot.boot = function(callback) {
|
||||
// Initialise crypto object
|
||||
$tw.crypto = new $tw.utils.Crypto();
|
||||
// Initialise password prompter
|
||||
@@ -2062,7 +2214,7 @@ $tw.boot.boot = function() {
|
||||
// Preload any encrypted tiddlers
|
||||
$tw.boot.decryptEncryptedTiddlers(function() {
|
||||
// Startup
|
||||
$tw.boot.startup();
|
||||
$tw.boot.startup({callback: callback});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
100
boot/sjcl.js
100
boot/sjcl.js
@@ -1,42 +1,60 @@
|
||||
"use strict";var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}};
|
||||
if(typeof module!="undefined"&&module.exports)module.exports=sjcl;
|
||||
sjcl.cipher.aes=function(a){this.h[0][0][0]||this.z();var b,c,d,e,f=this.h[0][4],g=this.h[1];b=a.length;var h=1;if(b!==4&&b!==6&&b!==8)throw new sjcl.exception.invalid("invalid aes key size");this.a=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(a%b===0||b===8&&a%b===4){c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255];if(a%b===0){c=c<<8^c>>>24^h<<24;h=h<<1^(h>>7)*283}}d[a]=d[a-b]^c}for(b=0;a;b++,a--){c=d[b&3?a:a-4];e[b]=a<=4||b<4?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^
|
||||
g[3][f[c&255]]}};
|
||||
sjcl.cipher.aes.prototype={encrypt:function(a){return this.I(a,0)},decrypt:function(a){return this.I(a,1)},h:[[[],[],[],[],[]],[[],[],[],[],[]]],z:function(){var a=this.h[0],b=this.h[1],c=a[4],d=b[4],e,f,g,h=[],i=[],k,j,l,m;for(e=0;e<0x100;e++)i[(h[e]=e<<1^(e>>7)*283)^e]=e;for(f=g=0;!c[f];f^=k||1,g=i[g]||1){l=g^g<<1^g<<2^g<<3^g<<4;l=l>>8^l&255^99;c[f]=l;d[l]=f;j=h[e=h[k=h[f]]];m=j*0x1010101^e*0x10001^k*0x101^f*0x1010100;j=h[l]*0x101^l*0x1010100;for(e=0;e<4;e++){a[e][f]=j=j<<24^j>>>8;b[e][l]=m=m<<24^m>>>8}}for(e=
|
||||
0;e<5;e++){a[e]=a[e].slice(0);b[e]=b[e].slice(0)}},I:function(a,b){if(a.length!==4)throw new sjcl.exception.invalid("invalid aes block size");var c=this.a[b],d=a[0]^c[0],e=a[b?3:1]^c[1],f=a[2]^c[2];a=a[b?1:3]^c[3];var g,h,i,k=c.length/4-2,j,l=4,m=[0,0,0,0];g=this.h[b];var n=g[0],o=g[1],p=g[2],q=g[3],r=g[4];for(j=0;j<k;j++){g=n[d>>>24]^o[e>>16&255]^p[f>>8&255]^q[a&255]^c[l];h=n[e>>>24]^o[f>>16&255]^p[a>>8&255]^q[d&255]^c[l+1];i=n[f>>>24]^o[a>>16&255]^p[d>>8&255]^q[e&255]^c[l+2];a=n[a>>>24]^o[d>>16&
|
||||
255]^p[e>>8&255]^q[f&255]^c[l+3];l+=4;d=g;e=h;f=i}for(j=0;j<4;j++){m[b?3&-j:j]=r[d>>>24]<<24^r[e>>16&255]<<16^r[f>>8&255]<<8^r[a&255]^c[l++];g=d;d=e;e=f;f=a;a=g}return m}};
|
||||
sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.P(a.slice(b/32),32-(b&31)).slice(1);return c===undefined?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<<c)-1},concat:function(a,b){if(a.length===0||b.length===0)return a.concat(b);var c=a[a.length-1],d=sjcl.bitArray.getPartial(c);return d===32?a.concat(b):sjcl.bitArray.P(b,d,c|0,a.slice(0,a.length-1))},bitLength:function(a){var b=a.length;
|
||||
if(b===0)return 0;return(b-1)*32+sjcl.bitArray.getPartial(a[b-1])},clamp:function(a,b){if(a.length*32<b)return a;a=a.slice(0,Math.ceil(b/32));var c=a.length;b&=31;if(c>0&&b)a[c-1]=sjcl.bitArray.partial(b,a[c-1]&2147483648>>b-1,1);return a},partial:function(a,b,c){if(a===32)return b;return(c?b|0:b<<32-a)+a*0x10000000000},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return false;var c=0,d;for(d=0;d<a.length;d++)c|=
|
||||
a[d]^b[d];return c===0},P:function(a,b,c,d){var e;e=0;if(d===undefined)d=[];for(;b>=32;b-=32){d.push(c);c=0}if(b===0)return d.concat(a);for(e=0;e<a.length;e++){d.push(c|a[e]>>>b);c=a[e]<<32-b}e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,b+a>32?c:d.pop(),1));return d},k:function(a,b){return[a[0]^b[0],a[1]^b[1],a[2]^b[2],a[3]^b[3]]}};
|
||||
sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d<c/8;d++){if((d&3)===0)e=a[d/4];b+=String.fromCharCode(e>>>24);e<<=8}return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c<a.length;c++){d=d<<8|a.charCodeAt(c);if((c&3)===3){b.push(d);d=0}}c&3&&b.push(sjcl.bitArray.partial(8*(c&3),d));return b}};
|
||||
sjcl.codec.hex={fromBits:function(a){var b="",c;for(c=0;c<a.length;c++)b+=((a[c]|0)+0xf00000000000).toString(16).substr(4);return b.substr(0,sjcl.bitArray.bitLength(a)/4)},toBits:function(a){var b,c=[],d;a=a.replace(/\s|0x/g,"");d=a.length;a+="00000000";for(b=0;b<a.length;b+=8)c.push(parseInt(a.substr(b,8),16)^0);return sjcl.bitArray.clamp(c,d*4)}};
|
||||
sjcl.codec.base64={F:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(a,b,c){var d="",e=0,f=sjcl.codec.base64.F,g=0,h=sjcl.bitArray.bitLength(a);if(c)f=f.substr(0,62)+"-_";for(c=0;d.length*6<h;){d+=f.charAt((g^a[c]>>>e)>>>26);if(e<6){g=a[c]<<6-e;e+=26;c++}else{g<<=6;e-=6}}for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d=0,e=sjcl.codec.base64.F,f=0,g;if(b)e=e.substr(0,62)+"-_";for(b=0;b<a.length;b++){g=e.indexOf(a.charAt(b));
|
||||
if(g<0)throw new sjcl.exception.invalid("this isn't base64!");if(d>26){d-=26;c.push(f^g>>>d);f=g<<32-d}else{d+=6;f^=g<<32-d}}d&56&&c.push(sjcl.bitArray.partial(d&56,f,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.a[0]||this.z();if(a){this.n=a.n.slice(0);this.i=a.i.slice(0);this.e=a.e}else this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()};
|
||||
sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.n=this.N.slice(0);this.i=[];this.e=0;return this},update:function(a){if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);var b,c=this.i=sjcl.bitArray.concat(this.i,a);b=this.e;a=this.e=b+sjcl.bitArray.bitLength(a);for(b=512+b&-512;b<=a;b+=512)this.D(c.splice(0,16));return this},finalize:function(){var a,b=this.i,c=this.n;b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.e/
|
||||
4294967296));for(b.push(this.e|0);b.length;)this.D(b.splice(0,16));this.reset();return c},N:[],a:[],z:function(){function a(e){return(e-Math.floor(e))*0x100000000|0}var b=0,c=2,d;a:for(;b<64;c++){for(d=2;d*d<=c;d++)if(c%d===0)continue a;if(b<8)this.N[b]=a(Math.pow(c,0.5));this.a[b]=a(Math.pow(c,1/3));b++}},D:function(a){var b,c,d=a.slice(0),e=this.n,f=this.a,g=e[0],h=e[1],i=e[2],k=e[3],j=e[4],l=e[5],m=e[6],n=e[7];for(a=0;a<64;a++){if(a<16)b=d[a];else{b=d[a+1&15];c=d[a+14&15];b=d[a&15]=(b>>>7^b>>>18^
|
||||
b>>>3^b<<25^b<<14)+(c>>>17^c>>>19^c>>>10^c<<15^c<<13)+d[a&15]+d[a+9&15]|0}b=b+n+(j>>>6^j>>>11^j>>>25^j<<26^j<<21^j<<7)+(m^j&(l^m))+f[a];n=m;m=l;l=j;j=k+b|0;k=i;i=h;h=g;g=b+(h&i^k&(h^i))+(h>>>2^h>>>13^h>>>22^h<<30^h<<19^h<<10)|0}e[0]=e[0]+g|0;e[1]=e[1]+h|0;e[2]=e[2]+i|0;e[3]=e[3]+k|0;e[4]=e[4]+j|0;e[5]=e[5]+l|0;e[6]=e[6]+m|0;e[7]=e[7]+n|0}};
|
||||
sjcl.mode.ccm={name:"ccm",encrypt:function(a,b,c,d,e){var f,g=b.slice(0),h=sjcl.bitArray,i=h.bitLength(c)/8,k=h.bitLength(g)/8;e=e||64;d=d||[];if(i<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;f<4&&k>>>8*f;f++);if(f<15-i)f=15-i;c=h.clamp(c,8*(15-f));b=sjcl.mode.ccm.H(a,b,c,d,e,f);g=sjcl.mode.ccm.J(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),i=f.clamp(b,h-e),k=f.bitSlice(b,
|
||||
h-e);h=(h-e)/8;if(g<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;b<4&&h>>>8*b;b++);if(b<15-g)b=15-g;c=f.clamp(c,8*(15-b));i=sjcl.mode.ccm.J(a,i,c,k,e,b);a=sjcl.mode.ccm.H(a,i.data,c,d,e,b);if(!f.equal(i.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match");return i.data},H:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,i=h.k;e/=8;if(e%2||e<4||e>16)throw new sjcl.exception.invalid("ccm: invalid tag length");if(d.length>0xffffffff||b.length>0xffffffff)throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data");
|
||||
f=[h.partial(8,(d.length?64:0)|e-2<<2|f-1)];f=h.concat(f,c);f[3]|=h.bitLength(b)/8;f=a.encrypt(f);if(d.length){c=h.bitLength(d)/8;if(c<=65279)g=[h.partial(16,c)];else if(c<=0xffffffff)g=h.concat([h.partial(16,65534)],[c]);g=h.concat(g,d);for(d=0;d<g.length;d+=4)f=a.encrypt(i(f,g.slice(d,d+4).concat([0,0,0])))}for(d=0;d<b.length;d+=4)f=a.encrypt(i(f,b.slice(d,d+4).concat([0,0,0])));return h.clamp(f,e*8)},J:function(a,b,c,d,e,f){var g,h=sjcl.bitArray;g=h.k;var i=b.length,k=h.bitLength(b);c=h.concat([h.partial(8,
|
||||
f-1)],c).concat([0,0,0]).slice(0,4);d=h.bitSlice(g(d,a.encrypt(c)),0,e);if(!i)return{tag:d,data:[]};for(g=0;g<i;g+=4){c[3]++;e=a.encrypt(c);b[g]^=e[0];b[g+1]^=e[1];b[g+2]^=e[2];b[g+3]^=e[3]}return{tag:d,data:h.clamp(b,k)}}};
|
||||
sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.B,i=sjcl.bitArray,k=i.k,j=[0,0,0,0];c=h(a.encrypt(c));var l,m=[];d=d||[];e=e||64;for(g=0;g+4<b.length;g+=4){l=b.slice(g,g+4);j=k(j,l);m=m.concat(k(c,a.encrypt(k(c,l))));c=h(c)}l=b.slice(g);b=i.bitLength(l);g=a.encrypt(k(c,[0,0,0,b]));l=i.clamp(k(l.concat([0,0,0]),g),b);j=k(j,k(l.concat([0,0,0]),g));j=a.encrypt(k(j,k(c,h(c))));
|
||||
if(d.length)j=k(j,f?d:sjcl.mode.ocb2.pmac(a,d));return m.concat(i.concat(l,i.clamp(j,e)))},decrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");e=e||64;var g=sjcl.mode.ocb2.B,h=sjcl.bitArray,i=h.k,k=[0,0,0,0],j=g(a.encrypt(c)),l,m,n=sjcl.bitArray.bitLength(b)-e,o=[];d=d||[];for(c=0;c+4<n/32;c+=4){l=i(j,a.decrypt(i(j,b.slice(c,c+4))));k=i(k,l);o=o.concat(l);j=g(j)}m=n-c*32;l=a.encrypt(i(j,[0,0,0,m]));l=i(l,h.clamp(b.slice(c),
|
||||
m).concat([0,0,0]));k=i(k,l);k=a.encrypt(i(k,i(j,g(j))));if(d.length)k=i(k,f?d:sjcl.mode.ocb2.pmac(a,d));if(!h.equal(h.clamp(k,e),h.bitSlice(b,n)))throw new sjcl.exception.corrupt("ocb: tag doesn't match");return o.concat(h.clamp(l,m))},pmac:function(a,b){var c,d=sjcl.mode.ocb2.B,e=sjcl.bitArray,f=e.k,g=[0,0,0,0],h=a.encrypt([0,0,0,0]);h=f(h,d(d(h)));for(c=0;c+4<b.length;c+=4){h=d(h);g=f(g,a.encrypt(f(h,b.slice(c,c+4))))}b=b.slice(c);if(e.bitLength(b)<128){h=f(h,d(h));b=e.concat(b,[2147483648|0,0,
|
||||
0,0])}g=f(g,b);return a.encrypt(f(d(f(h,d(h))),g))},B:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^(a[0]>>>31)*135]}};sjcl.misc.hmac=function(a,b){this.M=b=b||sjcl.hash.sha256;var c=[[],[]],d=b.prototype.blockSize/32;this.l=[new b,new b];if(a.length>d)a=b.hash(a);for(b=0;b<d;b++){c[0][b]=a[b]^909522486;c[1][b]=a[b]^1549556828}this.l[0].update(c[0]);this.l[1].update(c[1])};
|
||||
sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(a,b){a=(new this.M(this.l[0])).update(a,b).finalize();return(new this.M(this.l[1])).update(a).finalize()};
|
||||
sjcl.misc.pbkdf2=function(a,b,c,d,e){c=c||1E3;if(d<0||c<0)throw sjcl.exception.invalid("invalid params to pbkdf2");if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,i,k=[],j=sjcl.bitArray;for(i=1;32*k.length<(d||1);i++){e=f=a.encrypt(j.concat(b,[i]));for(g=1;g<c;g++){f=a.encrypt(f);for(h=0;h<f.length;h++)e[h]^=f[h]}k=k.concat(e)}if(d)k=j.clamp(k,d);return k};
|
||||
sjcl.random={randomWords:function(a,b){var c=[];b=this.isReady(b);var d;if(b===0)throw new sjcl.exception.notReady("generator isn't seeded");else b&2&&this.U(!(b&1));for(b=0;b<a;b+=4){(b+1)%0x10000===0&&this.L();d=this.w();c.push(d[0],d[1],d[2],d[3])}this.L();return c.slice(0,a)},setDefaultParanoia:function(a){this.t=a},addEntropy:function(a,b,c){c=c||"user";var d,e,f=(new Date).valueOf(),g=this.q[c],h=this.isReady(),i=0;d=this.G[c];if(d===undefined)d=this.G[c]=this.R++;if(g===undefined)g=this.q[c]=
|
||||
0;this.q[c]=(this.q[c]+1)%this.b.length;switch(typeof a){case "number":if(b===undefined)b=1;this.b[g].update([d,this.u++,1,b,f,1,a|0]);break;case "object":c=Object.prototype.toString.call(a);if(c==="[object Uint32Array]"){e=[];for(c=0;c<a.length;c++)e.push(a[c]);a=e}else{if(c!=="[object Array]")i=1;for(c=0;c<a.length&&!i;c++)if(typeof a[c]!="number")i=1}if(!i){if(b===undefined)for(c=b=0;c<a.length;c++)for(e=a[c];e>0;){b++;e>>>=1}this.b[g].update([d,this.u++,2,b,f,a.length].concat(a))}break;case "string":if(b===
|
||||
undefined)b=a.length;this.b[g].update([d,this.u++,3,b,f,a.length]);this.b[g].update(a);break;default:i=1}if(i)throw new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string");this.j[g]+=b;this.f+=b;if(h===0){this.isReady()!==0&&this.K("seeded",Math.max(this.g,this.f));this.K("progress",this.getProgress())}},isReady:function(a){a=this.C[a!==undefined?a:this.t];return this.g&&this.g>=a?this.j[0]>80&&(new Date).valueOf()>this.O?3:1:this.f>=a?2:0},getProgress:function(a){a=
|
||||
this.C[a?a:this.t];return this.g>=a?1:this.f>a?1:this.f/a},startCollectors:function(){if(!this.m){if(window.addEventListener){window.addEventListener("load",this.o,false);window.addEventListener("mousemove",this.p,false)}else if(document.attachEvent){document.attachEvent("onload",this.o);document.attachEvent("onmousemove",this.p)}else throw new sjcl.exception.bug("can't attach event");this.m=true}},stopCollectors:function(){if(this.m){if(window.removeEventListener){window.removeEventListener("load",
|
||||
this.o,false);window.removeEventListener("mousemove",this.p,false)}else if(window.detachEvent){window.detachEvent("onload",this.o);window.detachEvent("onmousemove",this.p)}this.m=false}},addEventListener:function(a,b){this.r[a][this.Q++]=b},removeEventListener:function(a,b){var c;a=this.r[a];var d=[];for(c in a)a.hasOwnProperty(c)&&a[c]===b&&d.push(c);for(b=0;b<d.length;b++){c=d[b];delete a[c]}},b:[new sjcl.hash.sha256],j:[0],A:0,q:{},u:0,G:{},R:0,g:0,f:0,O:0,a:[0,0,0,0,0,0,0,0],d:[0,0,0,0],s:undefined,
|
||||
t:6,m:false,r:{progress:{},seeded:{}},Q:0,C:[0,48,64,96,128,192,0x100,384,512,768,1024],w:function(){for(var a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}return this.s.encrypt(this.d)},L:function(){this.a=this.w().concat(this.w());this.s=new sjcl.cipher.aes(this.a)},T:function(a){this.a=sjcl.hash.sha256.hash(this.a.concat(a));this.s=new sjcl.cipher.aes(this.a);for(a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}},U:function(a){var b=[],c=0,d;this.O=b[0]=(new Date).valueOf()+3E4;for(d=
|
||||
0;d<16;d++)b.push(Math.random()*0x100000000|0);for(d=0;d<this.b.length;d++){b=b.concat(this.b[d].finalize());c+=this.j[d];this.j[d]=0;if(!a&&this.A&1<<d)break}if(this.A>=1<<this.b.length){this.b.push(new sjcl.hash.sha256);this.j.push(0)}this.f-=c;if(c>this.g)this.g=c;this.A++;this.T(b)},p:function(a){sjcl.random.addEntropy([a.x||a.clientX||a.offsetX||0,a.y||a.clientY||a.offsetY||0],2,"mouse")},o:function(){sjcl.random.addEntropy((new Date).valueOf(),2,"loadtime")},K:function(a,b){var c;a=sjcl.random.r[a];
|
||||
var d=[];for(c in a)a.hasOwnProperty(c)&&d.push(a[c]);for(c=0;c<d.length;c++)d[c](b)}};try{var s=new Uint32Array(32);crypto.getRandomValues(s);sjcl.random.addEntropy(s,1024,"crypto['getRandomValues']")}catch(t){}
|
||||
sjcl.json={defaults:{v:1,iter:1E3,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},encrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.c({iv:sjcl.random.randomWords(4,0)},e.defaults),g;e.c(f,c);c=f.adata;if(typeof f.salt==="string")f.salt=sjcl.codec.base64.toBits(f.salt);if(typeof f.iv==="string")f.iv=sjcl.codec.base64.toBits(f.iv);if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||typeof a==="string"&&f.iter<=100||f.ts!==64&&f.ts!==96&&f.ts!==128||f.ks!==128&&f.ks!==192&&f.ks!==0x100||f.iv.length<
|
||||
2||f.iv.length>4)throw new sjcl.exception.invalid("json encrypt: invalid parameters");if(typeof a==="string"){g=sjcl.misc.cachedPbkdf2(a,f);a=g.key.slice(0,f.ks/32);f.salt=g.salt}if(typeof b==="string")b=sjcl.codec.utf8String.toBits(b);if(typeof c==="string")c=sjcl.codec.utf8String.toBits(c);g=new sjcl.cipher[f.cipher](a);e.c(d,f);d.key=a;f.ct=sjcl.mode[f.mode].encrypt(g,b,f.iv,c,f.ts);return e.encode(f)},decrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json;b=e.c(e.c(e.c({},e.defaults),e.decode(b)),
|
||||
c,true);var f;c=b.adata;if(typeof b.salt==="string")b.salt=sjcl.codec.base64.toBits(b.salt);if(typeof b.iv==="string")b.iv=sjcl.codec.base64.toBits(b.iv);if(!sjcl.mode[b.mode]||!sjcl.cipher[b.cipher]||typeof a==="string"&&b.iter<=100||b.ts!==64&&b.ts!==96&&b.ts!==128||b.ks!==128&&b.ks!==192&&b.ks!==0x100||!b.iv||b.iv.length<2||b.iv.length>4)throw new sjcl.exception.invalid("json decrypt: invalid parameters");if(typeof a==="string"){f=sjcl.misc.cachedPbkdf2(a,b);a=f.key.slice(0,b.ks/32);b.salt=f.salt}if(typeof c===
|
||||
"string")c=sjcl.codec.utf8String.toBits(c);f=new sjcl.cipher[b.cipher](a);c=sjcl.mode[b.mode].decrypt(f,b.ct,b.iv,c,b.ts);e.c(d,b);d.key=a;return sjcl.codec.utf8String.fromBits(c)},encode:function(a){var b,c="{",d="";for(b in a)if(a.hasOwnProperty(b)){if(!b.match(/^[a-z0-9]+$/i))throw new sjcl.exception.invalid("json encode: invalid property name");c+=d+'"'+b+'":';d=",";switch(typeof a[b]){case "number":case "boolean":c+=a[b];break;case "string":c+='"'+escape(a[b])+'"';break;case "object":c+='"'+
|
||||
sjcl.codec.base64.fromBits(a[b],1)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type");}}return c+"}"},decode:function(a){a=a.replace(/\s/g,"");if(!a.match(/^\{.*\}$/))throw new sjcl.exception.invalid("json decode: this isn't json!");a=a.replace(/^\{|\}$/g,"").split(/,/);var b={},c,d;for(c=0;c<a.length;c++){if(!(d=a[c].match(/^(?:(["']?)([a-z][a-z0-9]*)\1):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i)))throw new sjcl.exception.invalid("json decode: this isn't json!");b[d[2]]=
|
||||
d[3]?parseInt(d[3],10):d[2].match(/^(ct|salt|iv)$/)?sjcl.codec.base64.toBits(d[4]):unescape(d[4])}return b},c:function(a,b,c){if(a===undefined)a={};if(b===undefined)return a;var d;for(d in b)if(b.hasOwnProperty(d)){if(c&&a[d]!==undefined&&a[d]!==b[d])throw new sjcl.exception.invalid("required parameter overridden");a[d]=b[d]}return a},W:function(a,b){var c={},d;for(d in a)if(a.hasOwnProperty(d)&&a[d]!==b[d])c[d]=a[d];return c},V:function(a,b){var c={},d;for(d=0;d<b.length;d++)if(a[b[d]]!==undefined)c[b[d]]=
|
||||
a[b[d]];return c}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.S={};sjcl.misc.cachedPbkdf2=function(a,b){var c=sjcl.misc.S,d;b=b||{};d=b.iter||1E3;c=c[a]=c[a]||{};d=c[d]=c[d]||{firstSalt:b.salt&&b.salt.length?b.salt.slice(0):sjcl.random.randomWords(2,0)};c=b.salt===undefined?d.firstSalt:b.salt;d[c]=d[c]||sjcl.misc.pbkdf2(a,c,b.iter);return{key:d[c].slice(0),salt:c.slice(0)}};
|
||||
sjcl.cipher.aes=function(a){this.s[0][0][0]||this.O();var b,c,d,e,f=this.s[0][4],g=this.s[1];b=a.length;var h=1;if(4!==b&&6!==b&&8!==b)throw new sjcl.exception.invalid("invalid aes key size");this.b=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(0===a%b||8===b&&4===a%b)c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255],0===a%b&&(c=c<<8^c>>>24^h<<24,h=h<<1^283*(h>>7));d[a]=d[a-b]^c}for(b=0;a;b++,a--)c=d[b&3?a:a-4],e[b]=4>=a||4>b?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^g[3][f[c&
|
||||
255]]};
|
||||
sjcl.cipher.aes.prototype={encrypt:function(a){return t(this,a,0)},decrypt:function(a){return t(this,a,1)},s:[[[],[],[],[],[]],[[],[],[],[],[]]],O:function(){var a=this.s[0],b=this.s[1],c=a[4],d=b[4],e,f,g,h=[],k=[],l,n,m,p;for(e=0;0x100>e;e++)k[(h[e]=e<<1^283*(e>>7))^e]=e;for(f=g=0;!c[f];f^=l||1,g=k[g]||1)for(m=g^g<<1^g<<2^g<<3^g<<4,m=m>>8^m&255^99,c[f]=m,d[m]=f,n=h[e=h[l=h[f]]],p=0x1010101*n^0x10001*e^0x101*l^0x1010100*f,n=0x101*h[m]^0x1010100*m,e=0;4>e;e++)a[e][f]=n=n<<24^n>>>8,b[e][m]=p=p<<24^p>>>8;for(e=
|
||||
0;5>e;e++)a[e]=a[e].slice(0),b[e]=b[e].slice(0)}};
|
||||
function t(a,b,c){if(4!==b.length)throw new sjcl.exception.invalid("invalid aes block size");var d=a.b[c],e=b[0]^d[0],f=b[c?3:1]^d[1],g=b[2]^d[2];b=b[c?1:3]^d[3];var h,k,l,n=d.length/4-2,m,p=4,r=[0,0,0,0];h=a.s[c];a=h[0];var q=h[1],v=h[2],w=h[3],x=h[4];for(m=0;m<n;m++)h=a[e>>>24]^q[f>>16&255]^v[g>>8&255]^w[b&255]^d[p],k=a[f>>>24]^q[g>>16&255]^v[b>>8&255]^w[e&255]^d[p+1],l=a[g>>>24]^q[b>>16&255]^v[e>>8&255]^w[f&255]^d[p+2],b=a[b>>>24]^q[e>>16&255]^v[f>>8&255]^w[g&255]^d[p+3],p+=4,e=h,f=k,g=l;for(m=
|
||||
0;4>m;m++)r[c?3&-m:m]=x[e>>>24]<<24^x[f>>16&255]<<16^x[g>>8&255]<<8^x[b&255]^d[p++],h=e,e=f,f=g,g=b,b=h;return r}
|
||||
sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.$(a.slice(b/32),32-(b&31)).slice(1);return void 0===c?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<<c)-1},concat:function(a,b){if(0===a.length||0===b.length)return a.concat(b);var c=a[a.length-1],d=sjcl.bitArray.getPartial(c);return 32===d?a.concat(b):sjcl.bitArray.$(b,d,c|0,a.slice(0,a.length-1))},bitLength:function(a){var b=a.length;return 0===
|
||||
b?0:32*(b-1)+sjcl.bitArray.getPartial(a[b-1])},clamp:function(a,b){if(32*a.length<b)return a;a=a.slice(0,Math.ceil(b/32));var c=a.length;b=b&31;0<c&&b&&(a[c-1]=sjcl.bitArray.partial(b,a[c-1]&2147483648>>b-1,1));return a},partial:function(a,b,c){return 32===a?b:(c?b|0:b<<32-a)+0x10000000000*a},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return!1;var c=0,d;for(d=0;d<a.length;d++)c|=a[d]^b[d];return 0===
|
||||
c},$:function(a,b,c,d){var e;e=0;for(void 0===d&&(d=[]);32<=b;b-=32)d.push(c),c=0;if(0===b)return d.concat(a);for(e=0;e<a.length;e++)d.push(c|a[e]>>>b),c=a[e]<<32-b;e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,32<b+a?c:d.pop(),1));return d},i:function(a,b){return[a[0]^b[0],a[1]^b[1],a[2]^b[2],a[3]^b[3]]},byteswapM:function(a){var b,c;for(b=0;b<a.length;++b)c=a[b],a[b]=c>>>24|c>>>8&0xff00|(c&0xff00)<<8|c<<24;return a}};
|
||||
sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d<c/8;d++)0===(d&3)&&(e=a[d/4]),b+=String.fromCharCode(e>>>8>>>8>>>8),e<<=8;return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c<a.length;c++)d=d<<8|a.charCodeAt(c),3===(c&3)&&(b.push(d),d=0);c&3&&b.push(sjcl.bitArray.partial(8*(c&3),d));return b}};
|
||||
sjcl.codec.hex={fromBits:function(a){var b="",c;for(c=0;c<a.length;c++)b+=((a[c]|0)+0xf00000000000).toString(16).substr(4);return b.substr(0,sjcl.bitArray.bitLength(a)/4)},toBits:function(a){var b,c=[],d;a=a.replace(/\s|0x/g,"");d=a.length;a=a+"00000000";for(b=0;b<a.length;b+=8)c.push(parseInt(a.substr(b,8),16)^0);return sjcl.bitArray.clamp(c,4*d)}};
|
||||
sjcl.codec.base32={B:"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",X:"0123456789ABCDEFGHIJKLMNOPQRSTUV",BITS:32,BASE:5,REMAINING:27,fromBits:function(a,b,c){var d=sjcl.codec.base32.BASE,e=sjcl.codec.base32.REMAINING,f="",g=0,h=sjcl.codec.base32.B,k=0,l=sjcl.bitArray.bitLength(a);c&&(h=sjcl.codec.base32.X);for(c=0;f.length*d<l;)f+=h.charAt((k^a[c]>>>g)>>>e),g<d?(k=a[c]<<d-g,g+=e,c++):(k<<=d,g-=d);for(;f.length&7&&!b;)f+="=";return f},toBits:function(a,b){a=a.replace(/\s|=/g,"").toUpperCase();var c=sjcl.codec.base32.BITS,
|
||||
d=sjcl.codec.base32.BASE,e=sjcl.codec.base32.REMAINING,f=[],g,h=0,k=sjcl.codec.base32.B,l=0,n,m="base32";b&&(k=sjcl.codec.base32.X,m="base32hex");for(g=0;g<a.length;g++){n=k.indexOf(a.charAt(g));if(0>n){if(!b)try{return sjcl.codec.base32hex.toBits(a)}catch(p){}throw new sjcl.exception.invalid("this isn't "+m+"!");}h>e?(h-=e,f.push(l^n>>>h),l=n<<c-h):(h+=d,l^=n<<c-h)}h&56&&f.push(sjcl.bitArray.partial(h&56,l,1));return f}};
|
||||
sjcl.codec.base32hex={fromBits:function(a,b){return sjcl.codec.base32.fromBits(a,b,1)},toBits:function(a){return sjcl.codec.base32.toBits(a,1)}};
|
||||
sjcl.codec.base64={B:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(a,b,c){var d="",e=0,f=sjcl.codec.base64.B,g=0,h=sjcl.bitArray.bitLength(a);c&&(f=f.substr(0,62)+"-_");for(c=0;6*d.length<h;)d+=f.charAt((g^a[c]>>>e)>>>26),6>e?(g=a[c]<<6-e,e+=26,c++):(g<<=6,e-=6);for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d,e=0,f=sjcl.codec.base64.B,g=0,h;b&&(f=f.substr(0,62)+"-_");for(d=0;d<a.length;d++){h=f.indexOf(a.charAt(d));
|
||||
if(0>h)throw new sjcl.exception.invalid("this isn't base64!");26<e?(e-=26,c.push(g^h>>>e),g=h<<32-e):(e+=6,g^=h<<32-e)}e&56&&c.push(sjcl.bitArray.partial(e&56,g,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.b[0]||this.O();a?(this.F=a.F.slice(0),this.A=a.A.slice(0),this.l=a.l):this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()};
|
||||
sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.F=this.Y.slice(0);this.A=[];this.l=0;return this},update:function(a){"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));var b,c=this.A=sjcl.bitArray.concat(this.A,a);b=this.l;a=this.l=b+sjcl.bitArray.bitLength(a);if(0x1fffffffffffff<a)throw new sjcl.exception.invalid("Cannot hash more than 2^53 - 1 bits");if("undefined"!==typeof Uint32Array){var d=new Uint32Array(c),e=0;for(b=512+b-(512+b&0x1ff);b<=a;b+=512)u(this,d.subarray(16*e,
|
||||
16*(e+1))),e+=1;c.splice(0,16*e)}else for(b=512+b-(512+b&0x1ff);b<=a;b+=512)u(this,c.splice(0,16));return this},finalize:function(){var a,b=this.A,c=this.F,b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.l/0x100000000));for(b.push(this.l|0);b.length;)u(this,b.splice(0,16));this.reset();return c},Y:[],b:[],O:function(){function a(a){return 0x100000000*(a-Math.floor(a))|0}for(var b=0,c=2,d,e;64>b;c++){e=!0;for(d=2;d*d<=c;d++)if(0===c%d){e=
|
||||
!1;break}e&&(8>b&&(this.Y[b]=a(Math.pow(c,.5))),this.b[b]=a(Math.pow(c,1/3)),b++)}}};
|
||||
function u(a,b){var c,d,e,f=a.F,g=a.b,h=f[0],k=f[1],l=f[2],n=f[3],m=f[4],p=f[5],r=f[6],q=f[7];for(c=0;64>c;c++)16>c?d=b[c]:(d=b[c+1&15],e=b[c+14&15],d=b[c&15]=(d>>>7^d>>>18^d>>>3^d<<25^d<<14)+(e>>>17^e>>>19^e>>>10^e<<15^e<<13)+b[c&15]+b[c+9&15]|0),d=d+q+(m>>>6^m>>>11^m>>>25^m<<26^m<<21^m<<7)+(r^m&(p^r))+g[c],q=r,r=p,p=m,m=n+d|0,n=l,l=k,k=h,h=d+(k&l^n&(k^l))+(k>>>2^k>>>13^k>>>22^k<<30^k<<19^k<<10)|0;f[0]=f[0]+h|0;f[1]=f[1]+k|0;f[2]=f[2]+l|0;f[3]=f[3]+n|0;f[4]=f[4]+m|0;f[5]=f[5]+p|0;f[6]=f[6]+r|0;f[7]=
|
||||
f[7]+q|0}
|
||||
sjcl.mode.ccm={name:"ccm",G:[],listenProgress:function(a){sjcl.mode.ccm.G.push(a)},unListenProgress:function(a){a=sjcl.mode.ccm.G.indexOf(a);-1<a&&sjcl.mode.ccm.G.splice(a,1)},fa:function(a){var b=sjcl.mode.ccm.G.slice(),c;for(c=0;c<b.length;c+=1)b[c](a)},encrypt:function(a,b,c,d,e){var f,g=b.slice(0),h=sjcl.bitArray,k=h.bitLength(c)/8,l=h.bitLength(g)/8;e=e||64;d=d||[];if(7>k)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;4>f&&l>>>8*f;f++);f<15-k&&(f=15-k);c=h.clamp(c,
|
||||
8*(15-f));b=sjcl.mode.ccm.V(a,b,c,d,e,f);g=sjcl.mode.ccm.C(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),k=f.clamp(b,h-e),l=f.bitSlice(b,h-e),h=(h-e)/8;if(7>g)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;4>b&&h>>>8*b;b++);b<15-g&&(b=15-g);c=f.clamp(c,8*(15-b));k=sjcl.mode.ccm.C(a,k,c,l,e,b);a=sjcl.mode.ccm.V(a,k.data,c,d,e,b);if(!f.equal(k.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match");
|
||||
return k.data},na:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,k=h.i;d=[h.partial(8,(b.length?64:0)|d-2<<2|f-1)];d=h.concat(d,c);d[3]|=e;d=a.encrypt(d);if(b.length)for(c=h.bitLength(b)/8,65279>=c?g=[h.partial(16,c)]:0xffffffff>=c&&(g=h.concat([h.partial(16,65534)],[c])),g=h.concat(g,b),b=0;b<g.length;b+=4)d=a.encrypt(k(d,g.slice(b,b+4).concat([0,0,0])));return d},V:function(a,b,c,d,e,f){var g=sjcl.bitArray,h=g.i;e/=8;if(e%2||4>e||16<e)throw new sjcl.exception.invalid("ccm: invalid tag length");
|
||||
if(0xffffffff<d.length||0xffffffff<b.length)throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data");c=sjcl.mode.ccm.na(a,d,c,e,g.bitLength(b)/8,f);for(d=0;d<b.length;d+=4)c=a.encrypt(h(c,b.slice(d,d+4).concat([0,0,0])));return g.clamp(c,8*e)},C:function(a,b,c,d,e,f){var g,h=sjcl.bitArray;g=h.i;var k=b.length,l=h.bitLength(b),n=k/50,m=n;c=h.concat([h.partial(8,f-1)],c).concat([0,0,0]).slice(0,4);d=h.bitSlice(g(d,a.encrypt(c)),0,e);if(!k)return{tag:d,data:[]};for(g=0;g<k;g+=4)g>n&&(sjcl.mode.ccm.fa(g/
|
||||
k),n+=m),c[3]++,e=a.encrypt(c),b[g]^=e[0],b[g+1]^=e[1],b[g+2]^=e[2],b[g+3]^=e[3];return{tag:d,data:h.clamp(b,l)}}};
|
||||
sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(128!==sjcl.bitArray.bitLength(c))throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.S,k=sjcl.bitArray,l=k.i,n=[0,0,0,0];c=h(a.encrypt(c));var m,p=[];d=d||[];e=e||64;for(g=0;g+4<b.length;g+=4)m=b.slice(g,g+4),n=l(n,m),p=p.concat(l(c,a.encrypt(l(c,m)))),c=h(c);m=b.slice(g);b=k.bitLength(m);g=a.encrypt(l(c,[0,0,0,b]));m=k.clamp(l(m.concat([0,0,0]),g),b);n=l(n,l(m.concat([0,0,0]),g));n=a.encrypt(l(n,l(c,h(c))));
|
||||
d.length&&(n=l(n,f?d:sjcl.mode.ocb2.pmac(a,d)));return p.concat(k.concat(m,k.clamp(n,e)))},decrypt:function(a,b,c,d,e,f){if(128!==sjcl.bitArray.bitLength(c))throw new sjcl.exception.invalid("ocb iv must be 128 bits");e=e||64;var g=sjcl.mode.ocb2.S,h=sjcl.bitArray,k=h.i,l=[0,0,0,0],n=g(a.encrypt(c)),m,p,r=sjcl.bitArray.bitLength(b)-e,q=[];d=d||[];for(c=0;c+4<r/32;c+=4)m=k(n,a.decrypt(k(n,b.slice(c,c+4)))),l=k(l,m),q=q.concat(m),n=g(n);p=r-32*c;m=a.encrypt(k(n,[0,0,0,p]));m=k(m,h.clamp(b.slice(c),p).concat([0,
|
||||
0,0]));l=k(l,m);l=a.encrypt(k(l,k(n,g(n))));d.length&&(l=k(l,f?d:sjcl.mode.ocb2.pmac(a,d)));if(!h.equal(h.clamp(l,e),h.bitSlice(b,r)))throw new sjcl.exception.corrupt("ocb: tag doesn't match");return q.concat(h.clamp(m,p))},pmac:function(a,b){var c,d=sjcl.mode.ocb2.S,e=sjcl.bitArray,f=e.i,g=[0,0,0,0],h=a.encrypt([0,0,0,0]),h=f(h,d(d(h)));for(c=0;c+4<b.length;c+=4)h=d(h),g=f(g,a.encrypt(f(h,b.slice(c,c+4))));c=b.slice(c);128>e.bitLength(c)&&(h=f(h,d(h)),c=e.concat(c,[-2147483648,0,0,0]));g=f(g,c);
|
||||
return a.encrypt(f(d(f(h,d(h))),g))},S:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^135*(a[0]>>>31)]}};
|
||||
sjcl.mode.gcm={name:"gcm",encrypt:function(a,b,c,d,e){var f=b.slice(0);b=sjcl.bitArray;d=d||[];a=sjcl.mode.gcm.C(!0,a,f,d,c,e||128);return b.concat(a.data,a.tag)},decrypt:function(a,b,c,d,e){var f=b.slice(0),g=sjcl.bitArray,h=g.bitLength(f);e=e||128;d=d||[];e<=h?(b=g.bitSlice(f,h-e),f=g.bitSlice(f,0,h-e)):(b=f,f=[]);a=sjcl.mode.gcm.C(!1,a,f,d,c,e);if(!g.equal(a.tag,b))throw new sjcl.exception.corrupt("gcm: tag doesn't match");return a.data},ka:function(a,b){var c,d,e,f,g,h=sjcl.bitArray.i;e=[0,0,
|
||||
0,0];f=b.slice(0);for(c=0;128>c;c++){(d=0!==(a[Math.floor(c/32)]&1<<31-c%32))&&(e=h(e,f));g=0!==(f[3]&1);for(d=3;0<d;d--)f[d]=f[d]>>>1|(f[d-1]&1)<<31;f[0]>>>=1;g&&(f[0]^=-0x1f000000)}return e},j:function(a,b,c){var d,e=c.length;b=b.slice(0);for(d=0;d<e;d+=4)b[0]^=0xffffffff&c[d],b[1]^=0xffffffff&c[d+1],b[2]^=0xffffffff&c[d+2],b[3]^=0xffffffff&c[d+3],b=sjcl.mode.gcm.ka(b,a);return b},C:function(a,b,c,d,e,f){var g,h,k,l,n,m,p,r,q=sjcl.bitArray;m=c.length;p=q.bitLength(c);r=q.bitLength(d);h=q.bitLength(e);
|
||||
g=b.encrypt([0,0,0,0]);96===h?(e=e.slice(0),e=q.concat(e,[1])):(e=sjcl.mode.gcm.j(g,[0,0,0,0],e),e=sjcl.mode.gcm.j(g,e,[0,0,Math.floor(h/0x100000000),h&0xffffffff]));h=sjcl.mode.gcm.j(g,[0,0,0,0],d);n=e.slice(0);d=h.slice(0);a||(d=sjcl.mode.gcm.j(g,h,c));for(l=0;l<m;l+=4)n[3]++,k=b.encrypt(n),c[l]^=k[0],c[l+1]^=k[1],c[l+2]^=k[2],c[l+3]^=k[3];c=q.clamp(c,p);a&&(d=sjcl.mode.gcm.j(g,h,c));a=[Math.floor(r/0x100000000),r&0xffffffff,Math.floor(p/0x100000000),p&0xffffffff];d=sjcl.mode.gcm.j(g,d,a);k=b.encrypt(e);
|
||||
d[0]^=k[0];d[1]^=k[1];d[2]^=k[2];d[3]^=k[3];return{tag:q.bitSlice(d,0,f),data:c}}};sjcl.misc.hmac=function(a,b){this.W=b=b||sjcl.hash.sha256;var c=[[],[]],d,e=b.prototype.blockSize/32;this.w=[new b,new b];a.length>e&&(a=b.hash(a));for(d=0;d<e;d++)c[0][d]=a[d]^909522486,c[1][d]=a[d]^1549556828;this.w[0].update(c[0]);this.w[1].update(c[1]);this.R=new b(this.w[0])};
|
||||
sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(a){if(this.aa)throw new sjcl.exception.invalid("encrypt on already updated hmac called!");this.update(a);return this.digest(a)};sjcl.misc.hmac.prototype.reset=function(){this.R=new this.W(this.w[0]);this.aa=!1};sjcl.misc.hmac.prototype.update=function(a){this.aa=!0;this.R.update(a)};sjcl.misc.hmac.prototype.digest=function(){var a=this.R.finalize(),a=(new this.W(this.w[1])).update(a).finalize();this.reset();return a};
|
||||
sjcl.misc.pbkdf2=function(a,b,c,d,e){c=c||1E4;if(0>d||0>c)throw new sjcl.exception.invalid("invalid params to pbkdf2");"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));"string"===typeof b&&(b=sjcl.codec.utf8String.toBits(b));e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,k,l=[],n=sjcl.bitArray;for(k=1;32*l.length<(d||1);k++){e=f=a.encrypt(n.concat(b,[k]));for(g=1;g<c;g++)for(f=a.encrypt(f),h=0;h<f.length;h++)e[h]^=f[h];l=l.concat(e)}d&&(l=n.clamp(l,d));return l};
|
||||
sjcl.prng=function(a){this.c=[new sjcl.hash.sha256];this.m=[0];this.P=0;this.H={};this.N=0;this.U={};this.Z=this.f=this.o=this.ha=0;this.b=[0,0,0,0,0,0,0,0];this.h=[0,0,0,0];this.L=void 0;this.M=a;this.D=!1;this.K={progress:{},seeded:{}};this.u=this.ga=0;this.I=1;this.J=2;this.ca=0x10000;this.T=[0,48,64,96,128,192,0x100,384,512,768,1024];this.da=3E4;this.ba=80};
|
||||
sjcl.prng.prototype={randomWords:function(a,b){var c=[],d;d=this.isReady(b);var e;if(d===this.u)throw new sjcl.exception.notReady("generator isn't seeded");if(d&this.J){d=!(d&this.I);e=[];var f=0,g;this.Z=e[0]=(new Date).valueOf()+this.da;for(g=0;16>g;g++)e.push(0x100000000*Math.random()|0);for(g=0;g<this.c.length&&(e=e.concat(this.c[g].finalize()),f+=this.m[g],this.m[g]=0,d||!(this.P&1<<g));g++);this.P>=1<<this.c.length&&(this.c.push(new sjcl.hash.sha256),this.m.push(0));this.f-=f;f>this.o&&(this.o=
|
||||
f);this.P++;this.b=sjcl.hash.sha256.hash(this.b.concat(e));this.L=new sjcl.cipher.aes(this.b);for(d=0;4>d&&(this.h[d]=this.h[d]+1|0,!this.h[d]);d++);}for(d=0;d<a;d+=4)0===(d+1)%this.ca&&y(this),e=z(this),c.push(e[0],e[1],e[2],e[3]);y(this);return c.slice(0,a)},setDefaultParanoia:function(a,b){if(0===a&&"Setting paranoia=0 will ruin your security; use it only for testing"!==b)throw new sjcl.exception.invalid("Setting paranoia=0 will ruin your security; use it only for testing");this.M=a},addEntropy:function(a,
|
||||
b,c){c=c||"user";var d,e,f=(new Date).valueOf(),g=this.H[c],h=this.isReady(),k=0;d=this.U[c];void 0===d&&(d=this.U[c]=this.ha++);void 0===g&&(g=this.H[c]=0);this.H[c]=(this.H[c]+1)%this.c.length;switch(typeof a){case "number":void 0===b&&(b=1);this.c[g].update([d,this.N++,1,b,f,1,a|0]);break;case "object":c=Object.prototype.toString.call(a);if("[object Uint32Array]"===c){e=[];for(c=0;c<a.length;c++)e.push(a[c]);a=e}else for("[object Array]"!==c&&(k=1),c=0;c<a.length&&!k;c++)"number"!==typeof a[c]&&
|
||||
(k=1);if(!k){if(void 0===b)for(c=b=0;c<a.length;c++)for(e=a[c];0<e;)b++,e=e>>>1;this.c[g].update([d,this.N++,2,b,f,a.length].concat(a))}break;case "string":void 0===b&&(b=a.length);this.c[g].update([d,this.N++,3,b,f,a.length]);this.c[g].update(a);break;default:k=1}if(k)throw new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string");this.m[g]+=b;this.f+=b;h===this.u&&(this.isReady()!==this.u&&A("seeded",Math.max(this.o,this.f)),A("progress",this.getProgress()))},
|
||||
isReady:function(a){a=this.T[void 0!==a?a:this.M];return this.o&&this.o>=a?this.m[0]>this.ba&&(new Date).valueOf()>this.Z?this.J|this.I:this.I:this.f>=a?this.J|this.u:this.u},getProgress:function(a){a=this.T[a?a:this.M];return this.o>=a?1:this.f>a?1:this.f/a},startCollectors:function(){if(!this.D){this.a={loadTimeCollector:B(this,this.ma),mouseCollector:B(this,this.oa),keyboardCollector:B(this,this.la),accelerometerCollector:B(this,this.ea),touchCollector:B(this,this.qa)};if(window.addEventListener)window.addEventListener("load",
|
||||
this.a.loadTimeCollector,!1),window.addEventListener("mousemove",this.a.mouseCollector,!1),window.addEventListener("keypress",this.a.keyboardCollector,!1),window.addEventListener("devicemotion",this.a.accelerometerCollector,!1),window.addEventListener("touchmove",this.a.touchCollector,!1);else if(document.attachEvent)document.attachEvent("onload",this.a.loadTimeCollector),document.attachEvent("onmousemove",this.a.mouseCollector),document.attachEvent("keypress",this.a.keyboardCollector);else throw new sjcl.exception.bug("can't attach event");
|
||||
this.D=!0}},stopCollectors:function(){this.D&&(window.removeEventListener?(window.removeEventListener("load",this.a.loadTimeCollector,!1),window.removeEventListener("mousemove",this.a.mouseCollector,!1),window.removeEventListener("keypress",this.a.keyboardCollector,!1),window.removeEventListener("devicemotion",this.a.accelerometerCollector,!1),window.removeEventListener("touchmove",this.a.touchCollector,!1)):document.detachEvent&&(document.detachEvent("onload",this.a.loadTimeCollector),document.detachEvent("onmousemove",
|
||||
this.a.mouseCollector),document.detachEvent("keypress",this.a.keyboardCollector)),this.D=!1)},addEventListener:function(a,b){this.K[a][this.ga++]=b},removeEventListener:function(a,b){var c,d,e=this.K[a],f=[];for(d in e)e.hasOwnProperty(d)&&e[d]===b&&f.push(d);for(c=0;c<f.length;c++)d=f[c],delete e[d]},la:function(){C(this,1)},oa:function(a){var b,c;try{b=a.x||a.clientX||a.offsetX||0,c=a.y||a.clientY||a.offsetY||0}catch(d){c=b=0}0!=b&&0!=c&&this.addEntropy([b,c],2,"mouse");C(this,0)},qa:function(a){a=
|
||||
a.touches[0]||a.changedTouches[0];this.addEntropy([a.pageX||a.clientX,a.pageY||a.clientY],1,"touch");C(this,0)},ma:function(){C(this,2)},ea:function(a){a=a.accelerationIncludingGravity.x||a.accelerationIncludingGravity.y||a.accelerationIncludingGravity.z;if(window.orientation){var b=window.orientation;"number"===typeof b&&this.addEntropy(b,1,"accelerometer")}a&&this.addEntropy(a,2,"accelerometer");C(this,0)}};
|
||||
function A(a,b){var c,d=sjcl.random.K[a],e=[];for(c in d)d.hasOwnProperty(c)&&e.push(d[c]);for(c=0;c<e.length;c++)e[c](b)}function C(a,b){"undefined"!==typeof window&&window.performance&&"function"===typeof window.performance.now?a.addEntropy(window.performance.now(),b,"loadtime"):a.addEntropy((new Date).valueOf(),b,"loadtime")}function y(a){a.b=z(a).concat(z(a));a.L=new sjcl.cipher.aes(a.b)}function z(a){for(var b=0;4>b&&(a.h[b]=a.h[b]+1|0,!a.h[b]);b++);return a.L.encrypt(a.h)}
|
||||
function B(a,b){return function(){b.apply(a,arguments)}}sjcl.random=new sjcl.prng(6);
|
||||
a:try{var D,E,F,G;if(G="undefined"!==typeof module&&module.exports){var H;try{H=require("crypto")}catch(a){H=null}G=E=H}if(G&&E.randomBytes)D=E.randomBytes(128),D=new Uint32Array((new Uint8Array(D)).buffer),sjcl.random.addEntropy(D,1024,"crypto['randomBytes']");else if("undefined"!==typeof window&&"undefined"!==typeof Uint32Array){F=new Uint32Array(32);if(window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(F);else if(window.msCrypto&&window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(F);
|
||||
else break a;sjcl.random.addEntropy(F,1024,"crypto['getRandomValues']")}}catch(a){"undefined"!==typeof window&&window.console&&(console.log("There was an error collecting entropy from the browser:"),console.log(a))}
|
||||
sjcl.json={defaults:{v:1,iter:1E4,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},ja:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.g({iv:sjcl.random.randomWords(4,0)},e.defaults),g;e.g(f,c);c=f.adata;"string"===typeof f.salt&&(f.salt=sjcl.codec.base64.toBits(f.salt));"string"===typeof f.iv&&(f.iv=sjcl.codec.base64.toBits(f.iv));if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||"string"===typeof a&&100>=f.iter||64!==f.ts&&96!==f.ts&&128!==f.ts||128!==f.ks&&192!==f.ks&&0x100!==f.ks||2>f.iv.length||
|
||||
4<f.iv.length)throw new sjcl.exception.invalid("json encrypt: invalid parameters");"string"===typeof a?(g=sjcl.misc.cachedPbkdf2(a,f),a=g.key.slice(0,f.ks/32),f.salt=g.salt):sjcl.ecc&&a instanceof sjcl.ecc.elGamal.publicKey&&(g=a.kem(),f.kemtag=g.tag,a=g.key.slice(0,f.ks/32));"string"===typeof b&&(b=sjcl.codec.utf8String.toBits(b));"string"===typeof c&&(f.adata=c=sjcl.codec.utf8String.toBits(c));g=new sjcl.cipher[f.cipher](a);e.g(d,f);d.key=a;f.ct="ccm"===f.mode&&sjcl.arrayBuffer&&sjcl.arrayBuffer.ccm&&
|
||||
b instanceof ArrayBuffer?sjcl.arrayBuffer.ccm.encrypt(g,b,f.iv,c,f.ts):sjcl.mode[f.mode].encrypt(g,b,f.iv,c,f.ts);return f},encrypt:function(a,b,c,d){var e=sjcl.json,f=e.ja.apply(e,arguments);return e.encode(f)},ia:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json;b=e.g(e.g(e.g({},e.defaults),b),c,!0);var f,g;f=b.adata;"string"===typeof b.salt&&(b.salt=sjcl.codec.base64.toBits(b.salt));"string"===typeof b.iv&&(b.iv=sjcl.codec.base64.toBits(b.iv));if(!sjcl.mode[b.mode]||!sjcl.cipher[b.cipher]||"string"===
|
||||
typeof a&&100>=b.iter||64!==b.ts&&96!==b.ts&&128!==b.ts||128!==b.ks&&192!==b.ks&&0x100!==b.ks||!b.iv||2>b.iv.length||4<b.iv.length)throw new sjcl.exception.invalid("json decrypt: invalid parameters");"string"===typeof a?(g=sjcl.misc.cachedPbkdf2(a,b),a=g.key.slice(0,b.ks/32),b.salt=g.salt):sjcl.ecc&&a instanceof sjcl.ecc.elGamal.secretKey&&(a=a.unkem(sjcl.codec.base64.toBits(b.kemtag)).slice(0,b.ks/32));"string"===typeof f&&(f=sjcl.codec.utf8String.toBits(f));g=new sjcl.cipher[b.cipher](a);f="ccm"===
|
||||
b.mode&&sjcl.arrayBuffer&&sjcl.arrayBuffer.ccm&&b.ct instanceof ArrayBuffer?sjcl.arrayBuffer.ccm.decrypt(g,b.ct,b.iv,b.tag,f,b.ts):sjcl.mode[b.mode].decrypt(g,b.ct,b.iv,f,b.ts);e.g(d,b);d.key=a;return 1===c.raw?f:sjcl.codec.utf8String.fromBits(f)},decrypt:function(a,b,c,d){var e=sjcl.json;return e.ia(a,e.decode(b),c,d)},encode:function(a){var b,c="{",d="";for(b in a)if(a.hasOwnProperty(b)){if(!b.match(/^[a-z0-9]+$/i))throw new sjcl.exception.invalid("json encode: invalid property name");c+=d+'"'+
|
||||
b+'":';d=",";switch(typeof a[b]){case "number":case "boolean":c+=a[b];break;case "string":c+='"'+escape(a[b])+'"';break;case "object":c+='"'+sjcl.codec.base64.fromBits(a[b],0)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type");}}return c+"}"},decode:function(a){a=a.replace(/\s/g,"");if(!a.match(/^\{.*\}$/))throw new sjcl.exception.invalid("json decode: this isn't json!");a=a.replace(/^\{|\}$/g,"").split(/,/);var b={},c,d;for(c=0;c<a.length;c++){if(!(d=a[c].match(/^\s*(?:(["']?)([a-z][a-z0-9]*)\1)\s*:\s*(?:(-?\d+)|"([a-z0-9+\/%*_.@=\-]*)"|(true|false))$/i)))throw new sjcl.exception.invalid("json decode: this isn't json!");
|
||||
null!=d[3]?b[d[2]]=parseInt(d[3],10):null!=d[4]?b[d[2]]=d[2].match(/^(ct|adata|salt|iv)$/)?sjcl.codec.base64.toBits(d[4]):unescape(d[4]):null!=d[5]&&(b[d[2]]="true"===d[5])}return b},g:function(a,b,c){void 0===a&&(a={});if(void 0===b)return a;for(var d in b)if(b.hasOwnProperty(d)){if(c&&void 0!==a[d]&&a[d]!==b[d])throw new sjcl.exception.invalid("required parameter overridden");a[d]=b[d]}return a},sa:function(a,b){var c={},d;for(d in a)a.hasOwnProperty(d)&&a[d]!==b[d]&&(c[d]=a[d]);return c},ra:function(a,
|
||||
b){var c={},d;for(d=0;d<b.length;d++)void 0!==a[b[d]]&&(c[b[d]]=a[b[d]]);return c}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.pa={};sjcl.misc.cachedPbkdf2=function(a,b){var c=sjcl.misc.pa,d;b=b||{};d=b.iter||1E3;c=c[a]=c[a]||{};d=c[d]=c[d]||{firstSalt:b.salt&&b.salt.length?b.salt.slice(0):sjcl.random.randomWords(2,0)};c=void 0===b.salt?d.firstSalt:b.salt;d[c]=d[c]||sjcl.misc.pbkdf2(a,c,b.iter);return{key:d[c].slice(0),salt:c.slice(0)}};
|
||||
"undefined"!==typeof module&&module.exports&&(module.exports=sjcl);"function"===typeof define&&define([],function(){return sjcl});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<h1 class="">Contributing to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a></h1><p>We welcome contributions to the code and documentation of <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> in several ways:</p><ul><li><a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/ReportingBugs.html">ReportingBugs</a></li><li>Helping to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/Improving%2520TiddlyWiki%2520Documentation.html">improve our documentation</a></li><li>Contributing to the code via <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5" rel="noopener noreferrer" target="_blank">GitHub</a><ul><li>See <a class="tc-tiddlylink-external" href="http://tiddlywiki.com/dev" rel="noopener noreferrer" target="_blank">http://tiddlywiki.com/dev</a> for more details</li></ul></li></ul><p>There are other ways to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/HelpingTiddlyWiki.html">help TiddlyWiki</a> too.</p><h1 class="">Contributor License Agreement</h1><p>Like other <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/OpenSource.html">OpenSource</a> projects, <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a> needs a signed contributor license agreement from individual contributors. This is a legal agreement that allows contributors to assert that they own the copyright of their contribution, and that they agree to license it to the <a class="tc-tiddlylink tc-tiddlylink-missing" href="http://tiddlywiki.com/static/UnaMesa.html">UnaMesa</a> Association (the legal entity that owns <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> on behalf of the community).</p><ul><li>For individuals use: <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md" rel="noopener noreferrer" target="_blank">licenses/CLA-individual</a></li><li>For entities use: <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md" rel="noopener noreferrer" target="_blank">licenses/CLA-entity</a></li></ul><h1 class="">How to sign the CLA</h1><p>Create a <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/GitHub.html">GitHub</a> pull request to add your name to <code>cla-individual.md</code> or <code>cla-entity.md</code>, with the date in the format (YYYY/MM/DD).</p><p><strong>step by step</strong></p><ol><li>Navigate to <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md" rel="noopener noreferrer" target="_blank">licenses/CLA-individual</a> or <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md" rel="noopener noreferrer" target="_blank">licenses/CLA-entity</a> according to whether you are signing as an individual or representative of an organisation</li><li>Click the "edit" button at the top-right corner (clicking this button will fork the project so you can edit the file)</li><li>Add your name at the bottom<ul><li>eg: <code>Jeremy Ruston, @Jermolene, 2011/11/22</code></li></ul></li><li>Below the edit box for the CLA text you should see a box labelled <strong>Propose file change</strong></li><li>Enter a brief title to explain the change (eg, "Signing the CLA")</li><li>Click the green button labelled <strong>Propose file change</strong></li><li>On the following screen, click the green button labelled <strong>Create pull request</strong></li></ol><hr><p><em>The CLA documents used for this project were created using <a class="tc-tiddlylink-external" href="http://www.harmonyagreements.org" rel="noopener noreferrer" target="_blank">Harmony Project Templates</a>. "HA-CLA-I-LIST Version 1.0" for "CLA-individual" and "HA-CLA-E-LIST Version 1.0" for "CLA-entity".</em></p><p>Remarks
|
||||
<h1 class="">Contributing to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a></h1><p>We welcome contributions to the code and documentation of <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> in several ways:</p><ul><li><a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/ReportingBugs.html">ReportingBugs</a></li><li>Helping to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/Improving%2520TiddlyWiki%2520Documentation.html">improve our documentation</a></li><li>Contributing to the code via <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5" rel="noopener noreferrer" target="_blank">GitHub</a><ul><li>See <a class="tc-tiddlylink-external" href="https://tiddlywiki.com/dev" rel="noopener noreferrer" target="_blank">https://tiddlywiki.com/dev</a> for more details</li></ul></li></ul><p>There are other ways to <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/HelpingTiddlyWiki.html">help TiddlyWiki</a> too.</p><h1 class="">Contributor License Agreement</h1><p>Like other <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/OpenSource.html">OpenSource</a> projects, <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a> needs a signed contributor license agreement from individual contributors. This is a legal agreement that allows contributors to assert that they own the copyright of their contribution, and that they agree to license it to the <a class="tc-tiddlylink tc-tiddlylink-missing" href="https://tiddlywiki.com/static/UnaMesa.html">UnaMesa</a> Association (the legal entity that owns <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki.html">TiddlyWiki</a> on behalf of the community).</p><ul><li>For individuals use: <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md" rel="noopener noreferrer" target="_blank">licenses/CLA-individual</a></li><li>For entities use: <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md" rel="noopener noreferrer" target="_blank">licenses/CLA-entity</a></li></ul><h1 class="">How to sign the CLA</h1><p>Create a <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/GitHub.html">GitHub</a> pull request to add your name to <code>cla-individual.md</code> or <code>cla-entity.md</code>, with the date in the format (YYYY/MM/DD).</p><p><strong>step by step</strong></p><ol><li>Navigate to <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-individual.md" rel="noopener noreferrer" target="_blank">licenses/CLA-individual</a> or <a class="tc-tiddlylink-external" href="https://github.com/Jermolene/TiddlyWiki5/tree/master/licenses/cla-entity.md" rel="noopener noreferrer" target="_blank">licenses/CLA-entity</a> according to whether you are signing as an individual or representative of an organisation</li><li>Click the "edit" button at the top-right corner (clicking this button will fork the project so you can edit the file)</li><li>Add your name at the bottom<ul><li>eg: <code>Jeremy Ruston, @Jermolene, 2011/11/22</code></li></ul></li><li>Below the edit box for the CLA text you should see a box labelled <strong>Propose file change</strong></li><li>Enter a brief title to explain the change (eg, "Signing the CLA")</li><li>Click the green button labelled <strong>Propose file change</strong></li><li>On the following screen, click the green button labelled <strong>Create pull request</strong></li></ol><hr><p><em>The CLA documents used for this project were created using <a class="tc-tiddlylink-external" href="http://www.harmonyagreements.org" rel="noopener noreferrer" target="_blank">Harmony Project Templates</a>. "HA-CLA-I-LIST Version 1.0" for "CLA-individual" and "HA-CLA-E-LIST Version 1.0" for "CLA-entity".</em></p><p>Remarks
|
||||
----—</p><ul><li><ul><li>When not owning the copyright in the entire work of authorship**</li></ul></li></ul><p>In this case, please clearly state so, since otherwise we assume that you are the legal copyright holder of the contributed work! Please provide links and additional information that clarify under which license the rest of the code is distributed.
|
||||
</p><p><em>This file was automatically generated by <a class="tc-tiddlylink tc-tiddlylink-resolves" href="http://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a></em>
|
||||
</p><p><em>This file was automatically generated by <a class="tc-tiddlylink tc-tiddlylink-resolves" href="https://tiddlywiki.com/static/TiddlyWiki5.html">TiddlyWiki5</a></em>
|
||||
</p>
|
||||
@@ -1,5 +1,4 @@
|
||||
title: $:/Acknowledgements
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
TiddlyWiki incorporates code from these fine OpenSource projects:
|
||||
|
||||
|
||||
@@ -3,30 +3,31 @@ type: text/plain
|
||||
|
||||
TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)
|
||||
|
||||
Copyright © Jeremy Ruston 2004-2007
|
||||
Copyright © UnaMesa Association 2007-2016
|
||||
Copyright (c) 2004-2007, Jeremy Ruston
|
||||
Copyright (c) 2007-2018, UnaMesa Association
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the name of the UnaMesa Association nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
4
core/images/add-comment.tid
Normal file
4
core/images/add-comment.tid
Normal file
@@ -0,0 +1,4 @@
|
||||
title: $:/core/images/add-comment
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tc-image-add-comment tc-image-button" width="22pt" height="22pt" viewBox="0 0 128 128"><path d="M56 56H36a8 8 0 1 0 0 16h20v20a8 8 0 1 0 16 0V72h20a8 8 0 1 0 0-16H72V36a8 8 0 1 0-16 0v20zm-12.595 58.362c-6.683 7.659-20.297 12.903-36.006 12.903-2.196 0-4.35-.102-6.451-.3 9.652-3.836 17.356-12.24 21.01-22.874C8.516 94.28 0 79.734 0 63.5 0 33.953 28.206 10 63 10s63 23.953 63 53.5S97.794 117 63 117c-6.841 0-13.428-.926-19.595-2.638z" fill-rule="evenodd"/></svg>
|
||||
15
core/images/copy-clipboard.tid
Normal file
15
core/images/copy-clipboard.tid
Normal file
@@ -0,0 +1,15 @@
|
||||
title: $:/core/images/copy-clipboard
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tc-image-copy-clipboard tc-image-button" width="22pt" height="22pt" viewBox="0 0 128 128">
|
||||
<g fill-rule="evenodd">
|
||||
<rect x="40" y="40" width="33" height="8" rx="4"></rect>
|
||||
<rect x="40" y="82" width="17" height="8" rx="4"></rect>
|
||||
<rect x="40" y="54" width="17" height="8" rx="4"></rect>
|
||||
<rect x="40" y="96" width="33" height="8" rx="4"></rect>
|
||||
<rect x="40" y="68" width="12" height="8" rx="4"></rect>
|
||||
<path d="M40,16 L23.9992458,16 C19.5813843,16 16,19.5907123 16,24 C16,24.0016363 16.0000005,24.0032725 16.0000015,24.0049086 C16.0000005,24.0065441 16,24.0081803 16,24.0098166 L16,119.990183 C16,119.99182 16.0000005,119.993456 16.0000015,119.995092 C16.0000005,119.996727 16,119.998364 16,120 C16,124.409288 19.5813843,128 23.9992458,128 L104.000754,128 C106.205061,128 108.203844,127.105595 109.652065,125.659342 C111.102424,124.21251 112,122.214511 112,120.007595 L112,103.992405 C112,99.5776607 108.418278,96 104,96 C99.5907123,96 96,99.5783218 96,103.992405 L96,112 L32,112 L32,32 L96,32 L96,40.0075946 C96,44.4223393 99.581722,48 104,48 C108.409288,48 112,44.4216782 112,40.0075946 L112,23.9924054 C112,21.7851587 111.104671,19.7871591 109.657101,18.3409203 C108.203844,16.8944047 106.205061,16 104.000754,16 L88,16 C88,11.5907123 84.4151006,8 79.9929031,8 L48.0070969,8 C43.5881712,8 40,11.581722 40,16 Z M44,14.9958262 C44,12.7889923 45.7964248,11 48.0000255,11 L79.9999745,11 C82.2091276,11 84,12.7965212 84,14.9958262 L84,19.0041738 C84,21.2110077 82.2035752,23 79.9999745,23 L48.0000255,23 C45.7908724,23 44,21.2034788 44,19.0041738 L44,14.9958262 Z"></path>
|
||||
<rect x="62" y="64" width="66" height="16" rx="8"></rect>
|
||||
<path d="M60.6568542,85.6568542 L76.6568542,69.6568543 L65.3431458,69.6568542 L81.3431458,85.6568542 C84.4673401,88.7810486 89.5326599,88.7810486 92.6568542,85.6568542 C95.7810486,82.5326599 95.7810486,77.4673401 92.6568542,74.3431458 L76.6568542,58.3431458 C73.5326599,55.2189514 68.4673401,55.2189514 65.3431458,58.3431457 L49.3431458,74.3431457 C46.2189514,77.4673401 46.2189514,82.5326599 49.3431457,85.6568542 C52.4673401,88.7810486 57.5326599,88.7810486 60.6568542,85.6568542 L60.6568542,85.6568542 Z" transform="translate(71.000000, 72.000000) rotate(-90.000000) translate(-71.000000, -72.000000) "></path>
|
||||
</g>
|
||||
</svg>
|
||||
4
core/images/linkify.tid
Normal file
4
core/images/linkify.tid
Normal file
@@ -0,0 +1,4 @@
|
||||
title: $:/core/images/linkify
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tc-linkify-button tc-image-button" viewBox="0 0 128 128" width="22pt" height="22pt"><path d="M17.031 31.919H9.048V96.85h7.983v6.92H0V25h17.031v6.919zm24.66 0h-7.983V96.85h7.983v6.92H24.66V25h17.03v6.919zM67.77 56.422l11.975-3.903 2.306 7.096-12.063 3.903 7.628 10.379-6.12 4.435-7.63-10.467-7.45 10.2-5.943-4.523L58.1 63.518 45.95 59.35l2.306-7.096 12.064 4.17V43.825h7.45v12.596zM86.31 96.85h7.982V31.92H86.31V25h17.031v78.77H86.31v-6.92zm24.659 0h7.983V31.92h-7.983V25H128v78.77h-17.031v-6.92z" fill-rule="evenodd"/></svg>
|
||||
9
core/images/list.tid
Normal file
9
core/images/list.tid
Normal file
@@ -0,0 +1,9 @@
|
||||
title: $:/core/images/list
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tc-image-list tc-image-button" width="22pt" height="22pt" viewBox="0 0 128 128">
|
||||
<g fill-rule="evenodd">
|
||||
<path d="M0.719999312,185.568543 C2.21955287,181.862817 3.0452019,177.812144 3.0452019,173.568542 C3.0452019,155.891545 -11.2816707,141.568542 -28.9547636,141.568542 L-60.9548326,141.568542 C-78.6344937,141.568542 -92.9547981,155.895431 -92.9547981,173.568542 C-92.9547981,191.24554 -78.6279255,205.568542 -60.9548326,205.568542 L-28.9547636,205.568542 C-27.593228,205.568542 -26.2516158,205.483573 -24.9349335,205.31865 C-31.5207556,201.78951 -36.8809788,196.272192 -40.2126959,189.568542 L-60.9493786,189.568542 C-69.7889277,189.568542 -76.9547981,182.407041 -76.9547981,173.568542 C-76.9547981,164.731986 -69.7994766,157.568542 -60.9493786,157.568542 L-28.9602176,157.568542 C-20.1206685,157.568542 -12.9547981,164.730044 -12.9547981,173.568542 C-12.9547981,176.946528 -14.0004297,180.080016 -15.7866505,182.6623 C-13.6856165,184.473592 -10.949961,185.568542 -7.9585771,185.568542 L0.720002586,185.568542 Z" transform="translate(-44.954798, 173.568542) rotate(-225.000000) translate(44.954798, -173.568542) "></path>
|
||||
<path d="M87.7480315,128 L23.9992458,128 C19.5813843,128 16,124.409247 16,119.993027 L16,8.00697327 C16,3.58484404 19.5881049,0 23.9992458,0 L104.000754,0 C108.418616,0 112,3.59075293 112,8.00697327 L112,104 L91.2492027,104 C90.2848199,104 89.410573,104.391703 88.7768998,105.025201 C88.1373658,105.661376 87.7480315,106.53563 87.7480315,107.501171 L87.7480315,128 Z M95.7480315,127.879386 L111.627417,112 L95.7480315,112 L95.7480315,127.879386 Z M40,15.5089165 C40,13.5709954 41.5636015,12 43.4998101,12 L98.5001899,12 C100.433082,12 102,13.5614718 102,15.5089165 L102,16.4910835 C102,18.4290046 100.436399,20 98.5001899,20 L43.4998101,20 C41.5669183,20 40,18.4385282 40,16.4910835 L40,15.5089165 Z M32,22 C35.3137085,22 38,19.3137085 38,16 C38,12.6862915 35.3137085,10 32,10 C28.6862915,10 26,12.6862915 26,16 C26,19.3137085 28.6862915,22 32,22 Z M40,31.5089165 C40,29.5709954 41.5636015,28 43.4998101,28 L98.5001899,28 C100.433082,28 102,29.5614718 102,31.5089165 L102,32.4910835 C102,34.4290046 100.436399,36 98.5001899,36 L43.4998101,36 C41.5669183,36 40,34.4385282 40,32.4910835 L40,31.5089165 Z M40,47.5089165 C40,45.5709954 41.5636015,44 43.4998101,44 L98.5001899,44 C100.433082,44 102,45.5614718 102,47.5089165 L102,48.4910835 C102,50.4290046 100.436399,52 98.5001899,52 L43.4998101,52 C41.5669183,52 40,50.4385282 40,48.4910835 L40,47.5089165 Z M40,63.5089165 C40,61.5709954 41.5636015,60 43.4998101,60 L98.5001899,60 C100.433082,60 102,61.5614718 102,63.5089165 L102,64.4910835 C102,66.4290046 100.436399,68 98.5001899,68 L43.4998101,68 C41.5669183,68 40,66.4385282 40,64.4910835 L40,63.5089165 Z M40,79.5089165 C40,77.5709954 41.5636015,76 43.4998101,76 L98.5001899,76 C100.433082,76 102,77.5614718 102,79.5089165 L102,80.4910835 C102,82.4290046 100.436399,84 98.5001899,84 L43.4998101,84 C41.5669183,84 40,82.4385282 40,80.4910835 L40,79.5089165 Z M40,95.5089165 C40,93.5709954 41.5636015,92 43.4998101,92 L98.5001899,92 C100.433082,92 102,93.5614718 102,95.5089165 L102,96.4910835 C102,98.4290046 100.436399,100 98.5001899,100 L43.4998101,100 C41.5669183,100 40,98.4385282 40,96.4910835 L40,95.5089165 Z M40,111.508916 C40,109.570995 41.5680474,108 43.4972017,108 L76.5027983,108 C78.4342495,108 80,109.561472 80,111.508916 L80,112.491084 C80,114.429005 78.4319526,116 76.5027983,116 L43.4972017,116 C41.5657505,116 40,114.438528 40,112.491084 L40,111.508916 Z M32,38 C35.3137085,38 38,35.3137085 38,32 C38,28.6862915 35.3137085,26 32,26 C28.6862915,26 26,28.6862915 26,32 C26,35.3137085 28.6862915,38 32,38 Z M32,54 C35.3137085,54 38,51.3137085 38,48 C38,44.6862915 35.3137085,42 32,42 C28.6862915,42 26,44.6862915 26,48 C26,51.3137085 28.6862915,54 32,54 Z M32,70 C35.3137085,70 38,67.3137085 38,64 C38,60.6862915 35.3137085,58 32,58 C28.6862915,58 26,60.6862915 26,64 C26,67.3137085 28.6862915,70 32,70 Z M32,86 C35.3137085,86 38,83.3137085 38,80 C38,76.6862915 35.3137085,74 32,74 C28.6862915,74 26,76.6862915 26,80 C26,83.3137085 28.6862915,86 32,86 Z M32,102 C35.3137085,102 38,99.3137085 38,96 C38,92.6862915 35.3137085,90 32,90 C28.6862915,90 26,92.6862915 26,96 C26,99.3137085 28.6862915,102 32,102 Z M32,118 C35.3137085,118 38,115.313708 38,112 C38,108.686292 35.3137085,106 32,106 C28.6862915,106 26,108.686292 26,112 C26,115.313708 28.6862915,118 32,118 Z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
12
core/images/print-button.tid
Normal file
12
core/images/print-button.tid
Normal file
@@ -0,0 +1,12 @@
|
||||
title: $:/core/images/print-button
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tc-image-print-button tc-image-button" viewBox="0 0 128 128" width="22pt" height="22pt">
|
||||
<g fill-rule="evenodd">
|
||||
<path d="M112,71 L112,30.5 L111.96811,30.5 L111.96811,30.5 C111.932942,28.4998414 111.151676,26.510538 109.625176,24.9840387 L86.9982489,2.35711116 C85.3482153,0.707077645 83.1589869,-0.071534047 81,0.0201838424 L81,0 L23.9992458,0 C19.5808867,0 16,3.58213437 16,8.00092105 L16,71 L24,71 L24,8 L81,8 L81,22.4996539 C81,26.9216269 84.5818769,30.5 89.0003461,30.5 L104,30.5 L104,71 L112,71 Z"></path>
|
||||
<rect x="32" y="36" width="64" height="8" rx="4"></rect>
|
||||
<rect x="32" y="52" width="64" height="8" rx="4"></rect>
|
||||
<rect x="32" y="20" width="40" height="8" rx="4"></rect>
|
||||
<path d="M0,80.0054195 C0,71.1658704 7.15611005,64 16.0008841,64 L111.999116,64 C120.83616,64 128,71.1553215 128,80.0054195 L128,111.99458 C128,120.83413 120.84389,128 111.999116,128 L16.0008841,128 C7.16383982,128 0,120.844679 0,111.99458 L0,80.0054195 Z M104,96 C108.418278,96 112,92.418278 112,88 C112,83.581722 108.418278,80 104,80 C99.581722,80 96,83.581722 96,88 C96,92.418278 99.581722,96 104,96 Z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
4
core/images/rotate-left.tid
Normal file
4
core/images/rotate-left.tid
Normal file
@@ -0,0 +1,4 @@
|
||||
title: $:/core/images/rotate-left
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tc-image-rotate-left tc-image-button" width="22pt" height="22pt" viewBox="0 0 128 128"><g fill-rule="evenodd"><rect width="32" height="80" rx="8"/><rect x="48" y="96" width="80" height="32" rx="8"/><path d="M61.32 36.65c19.743 2.45 35.023 19.287 35.023 39.693a4 4 0 0 1-8 0c0-15.663-11.254-28.698-26.117-31.46l3.916 3.916a4 4 0 1 1-5.657 5.657L49.172 43.142a4 4 0 0 1 0-5.657l11.313-11.313a4 4 0 1 1 5.657 5.656l-4.821 4.822z"/></g></svg>
|
||||
8
core/images/timestamp-off.tid
Normal file
8
core/images/timestamp-off.tid
Normal file
@@ -0,0 +1,8 @@
|
||||
title: $:/core/images/timestamp-off
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tc-image-timestamp-off tc-image-button" width="22pt" height="22pt" viewBox="0 0 128 128">
|
||||
<g fill-rule="evenodd">
|
||||
<path d="M58.25 11C26.08 11 0 37.082 0 69.25s26.08 58.25 58.25 58.25c32.175 0 58.25-26.082 58.25-58.25S90.425 11 58.25 11zm0 100.5C34.914 111.5 16 92.586 16 69.25 16 45.92 34.914 27 58.25 27s42.25 18.92 42.25 42.25c0 23.336-18.914 42.25-42.25 42.25zM49.704 10c-2.762 0-5-2.24-5-5-.004-2.756 2.238-5 5-5H66.69c2.762 0 5.002 2.24 5 5 .006 2.757-2.238 5-5 5H49.705z"/><path d="M58.25 35.88c-18.777 0-33.998 15.224-33.998 33.998 0 18.773 15.22 34.002 33.998 34.002 18.784 0 34.002-15.23 34.002-34.002 0-18.774-15.218-33.998-34.002-33.998zm-3.03 50.123H44.196v-34H55.22v34zm16.976 0H61.17v-34h11.025v34z"/>
|
||||
</g>
|
||||
</svg>
|
||||
8
core/images/timestamp-on.tid
Normal file
8
core/images/timestamp-on.tid
Normal file
@@ -0,0 +1,8 @@
|
||||
title: $:/core/images/timestamp-on
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tc-image-timestamp-on tc-image-button" width="22pt" height="22pt" viewBox="0 0 128 128">
|
||||
<g fill-rule="evenodd">
|
||||
<path d="M58.25 11C26.08 11 0 37.082 0 69.25s26.08 58.25 58.25 58.25c32.175 0 58.25-26.082 58.25-58.25S90.425 11 58.25 11zm0 100.5C34.914 111.5 16 92.586 16 69.25 16 45.92 34.914 27 58.25 27s42.25 18.92 42.25 42.25c0 23.336-18.914 42.25-42.25 42.25zM49.704 10c-2.762 0-5-2.24-5-5-.004-2.756 2.238-5 5-5H66.69c2.762 0 5.002 2.24 5 5 .006 2.757-2.238 5-5 5H49.705z"/><path d="M13.41 27.178c-2.116 1.775-5.27 1.498-7.045-.613-1.772-2.11-1.498-5.27.616-7.047l9.95-8.348c2.115-1.774 5.27-1.5 7.045.618 1.775 2.108 1.498 5.27-.616 7.043l-9.95 8.348zM102.983 27.178c2.116 1.775 5.27 1.498 7.045-.613 1.772-2.11 1.498-5.27-.616-7.047l-9.95-8.348c-2.114-1.774-5.27-1.5-7.044.618-1.775 2.108-1.498 5.27.616 7.043l9.95 8.348zM65.097 71.072c0 3.826-3.09 6.928-6.897 6.928-3.804.006-6.9-3.102-6.903-6.928 0 0 4.76-39.072 6.903-39.072s6.897 39.072 6.897 39.072z"/>
|
||||
</g>
|
||||
</svg>
|
||||
4
core/images/transcludify.tid
Normal file
4
core/images/transcludify.tid
Normal file
@@ -0,0 +1,4 @@
|
||||
title: $:/core/images/transcludify
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tc-transcludify-button tc-image-button" viewBox="0 0 128 128" width="22pt" height="22pt"><path d="M0 59.482c.591 0 1.36-.089 2.306-.266a10.417 10.417 0 0 0 2.75-.932 6.762 6.762 0 0 0 2.306-1.907c.651-.828.976-1.863.976-3.104V35.709c0-2.01.414-3.74 1.242-5.19.828-1.448 1.833-2.66 3.016-3.636s2.425-1.7 3.726-2.173c1.3-.473 2.424-.71 3.37-.71h8.073v7.451h-4.88c-1.241 0-2.232.207-2.97.621-.74.414-1.302.932-1.686 1.552a4.909 4.909 0 0 0-.71 1.996c-.089.71-.133 1.39-.133 2.04v16.677c0 1.715-.325 3.134-.976 4.258-.65 1.123-1.434 2.025-2.35 2.705-.917.68-1.863 1.168-2.839 1.464-.976.296-1.818.473-2.528.532v.178c.71.059 1.552.207 2.528.443.976.237 1.922.68 2.839 1.33.916.651 1.7 1.583 2.35 2.795.65 1.212.976 2.853.976 4.923v16.144c0 .65.044 1.33.133 2.04.089.71.325 1.375.71 1.996.384.621.946 1.139 1.685 1.553.74.414 1.73.62 2.972.62h4.879v7.452h-8.073c-.946 0-2.07-.237-3.37-.71-1.301-.473-2.543-1.197-3.726-2.173-1.183-.976-2.188-2.188-3.016-3.637-.828-1.449-1.242-3.179-1.242-5.19V74.119c0-1.42-.325-2.572-.976-3.46-.65-.886-1.419-1.581-2.306-2.084a8.868 8.868 0 0 0-2.75-1.02C1.36 67.377.591 67.288 0 67.288v-7.806zm24.66 0c.591 0 1.36-.089 2.306-.266a10.417 10.417 0 0 0 2.75-.932 6.762 6.762 0 0 0 2.306-1.907c.65-.828.976-1.863.976-3.104V35.709c0-2.01.414-3.74 1.242-5.19.828-1.448 1.833-2.66 3.016-3.636s2.425-1.7 3.726-2.173c1.3-.473 2.424-.71 3.37-.71h8.073v7.451h-4.88c-1.241 0-2.232.207-2.97.621-.74.414-1.302.932-1.686 1.552a4.909 4.909 0 0 0-.71 1.996c-.089.71-.133 1.39-.133 2.04v16.677c0 1.715-.325 3.134-.976 4.258-.65 1.123-1.434 2.025-2.35 2.705-.917.68-1.863 1.168-2.839 1.464-.976.296-1.818.473-2.528.532v.178c.71.059 1.552.207 2.528.443.976.237 1.922.68 2.839 1.33.916.651 1.7 1.583 2.35 2.795.65 1.212.976 2.853.976 4.923v16.144c0 .65.044 1.33.133 2.04.089.71.325 1.375.71 1.996.384.621.946 1.139 1.685 1.553.74.414 1.73.62 2.972.62h4.879v7.452h-8.073c-.946 0-2.07-.237-3.37-.71-1.301-.473-2.543-1.197-3.726-2.173-1.183-.976-2.188-2.188-3.016-3.637-.828-1.449-1.242-3.179-1.242-5.19V74.119c0-1.42-.325-2.572-.976-3.46-.65-.886-1.419-1.581-2.306-2.084a8.868 8.868 0 0 0-2.75-1.02c-.946-.177-1.715-.266-2.306-.266v-7.806zm43.965-3.538L80.6 52.041l2.306 7.097-12.063 3.903 7.628 10.378-6.12 4.435-7.63-10.467-7.45 10.201-5.943-4.524 7.628-10.023-12.152-4.17 2.306-7.096 12.064 4.17V43.347h7.451v12.596zm34.425 11.344c-.65 0-1.449.089-2.395.266-.946.177-1.863.488-2.75.931a6.356 6.356 0 0 0-2.262 1.908c-.62.828-.931 1.862-.931 3.104v17.564c0 2.01-.414 3.74-1.242 5.189-.828 1.449-1.833 2.661-3.016 3.637s-2.425 1.7-3.726 2.173c-1.3.473-2.424.71-3.37.71h-8.073v-7.451h4.88c1.241 0 2.232-.207 2.97-.621.74-.414 1.302-.932 1.686-1.553a4.9 4.9 0 0 0 .71-1.995c.089-.71.133-1.39.133-2.04V72.432c0-1.715.325-3.134.976-4.258.65-1.124 1.434-2.01 2.35-2.661.917-.65 1.863-1.124 2.839-1.42.976-.295 1.818-.502 2.528-.62v-.178c-.71-.059-1.552-.207-2.528-.443-.976-.237-1.922-.68-2.839-1.33-.916-.651-1.7-1.583-2.35-2.795-.65-1.212-.976-2.853-.976-4.923V37.66c0-.651-.044-1.331-.133-2.04a4.909 4.909 0 0 0-.71-1.997c-.384-.62-.946-1.138-1.685-1.552-.74-.414-1.73-.62-2.972-.62h-4.879V24h8.073c.946 0 2.07.237 3.37.71 1.301.473 2.543 1.197 3.726 2.173 1.183.976 2.188 2.188 3.016 3.637.828 1.449 1.242 3.178 1.242 5.189v16.943c0 1.419.31 2.572.931 3.46a6.897 6.897 0 0 0 2.262 2.084 8.868 8.868 0 0 0 2.75 1.02c.946.177 1.745.266 2.395.266v7.806zm24.66 0c-.65 0-1.449.089-2.395.266-.946.177-1.863.488-2.75.931a6.356 6.356 0 0 0-2.262 1.908c-.62.828-.931 1.862-.931 3.104v17.564c0 2.01-.414 3.74-1.242 5.189-.828 1.449-1.833 2.661-3.016 3.637s-2.425 1.7-3.726 2.173c-1.3.473-2.424.71-3.37.71h-8.073v-7.451h4.88c1.241 0 2.232-.207 2.97-.621.74-.414 1.302-.932 1.686-1.553a4.9 4.9 0 0 0 .71-1.995c.089-.71.133-1.39.133-2.04V72.432c0-1.715.325-3.134.976-4.258.65-1.124 1.434-2.01 2.35-2.661.917-.65 1.863-1.124 2.839-1.42.976-.295 1.818-.502 2.528-.62v-.178c-.71-.059-1.552-.207-2.528-.443-.976-.237-1.922-.68-2.839-1.33-.916-.651-1.7-1.583-2.35-2.795-.65-1.212-.976-2.853-.976-4.923V37.66c0-.651-.044-1.331-.133-2.04a4.909 4.909 0 0 0-.71-1.997c-.384-.62-.946-1.138-1.685-1.552-.74-.414-1.73-.62-2.972-.62h-4.879V24h8.073c.946 0 2.07.237 3.37.71 1.301.473 2.543 1.197 3.726 2.173 1.183.976 2.188 2.188 3.016 3.637.828 1.449 1.242 3.178 1.242 5.189v16.943c0 1.419.31 2.572.931 3.46a6.897 6.897 0 0 0 2.262 2.084 8.868 8.868 0 0 0 2.75 1.02c.946.177 1.745.266 2.395.266v7.806z" fill-rule="evenodd"/></svg>
|
||||
@@ -14,6 +14,8 @@ CloseOthers/Caption: close others
|
||||
CloseOthers/Hint: Close other tiddlers
|
||||
ControlPanel/Caption: control panel
|
||||
ControlPanel/Hint: Open control panel
|
||||
CopyToClipboard/Caption: copy to clipboard
|
||||
CopyToClipboard/Hint: Copy this text to the clipboard
|
||||
Delete/Caption: delete
|
||||
Delete/Hint: Delete this tiddler
|
||||
Edit/Caption: edit
|
||||
@@ -54,6 +56,8 @@ Home/Caption: home
|
||||
Home/Hint: Open the default tiddlers
|
||||
Language/Caption: language
|
||||
Language/Hint: Choose the user interface language
|
||||
Manager/Caption: tiddler manager
|
||||
Manager/Hint: Open tiddler manager
|
||||
More/Caption: more
|
||||
More/Hint: More actions
|
||||
NewHere/Caption: new here
|
||||
@@ -76,6 +80,8 @@ Permalink/Caption: permalink
|
||||
Permalink/Hint: Set browser address bar to a direct link to this tiddler
|
||||
Permaview/Caption: permaview
|
||||
Permaview/Hint: Set browser address bar to a direct link to all the tiddlers in this story
|
||||
Print/Caption: print page
|
||||
Print/Hint: Print the current page
|
||||
Refresh/Caption: refresh
|
||||
Refresh/Hint: Perform a full refresh of the wiki
|
||||
Save/Caption: ok
|
||||
@@ -90,6 +96,12 @@ ShowSideBar/Caption: show sidebar
|
||||
ShowSideBar/Hint: Show sidebar
|
||||
TagManager/Caption: tag manager
|
||||
TagManager/Hint: Open tag manager
|
||||
Timestamp/Caption: timestamps
|
||||
Timestamp/Hint: Choose whether modifications update timestamps
|
||||
Timestamp/On/Caption: timestamps are on
|
||||
Timestamp/On/Hint: Update timestamps when tiddlers are modified
|
||||
Timestamp/Off/Caption: timestamps are off
|
||||
Timestamp/Off/Hint: Don't update timestamps when tiddlers are modified
|
||||
Theme/Caption: theme
|
||||
Theme/Hint: Choose the display theme
|
||||
Bold/Caption: bold
|
||||
@@ -129,6 +141,8 @@ LineWidth/Caption: line width
|
||||
LineWidth/Hint: Set line width for painting
|
||||
Link/Caption: link
|
||||
Link/Hint: Create wikitext link
|
||||
Linkify/Caption: wikilink
|
||||
Linkify/Hint: Wrap selection in square brackets
|
||||
ListBullet/Caption: bulleted list
|
||||
ListBullet/Hint: Apply bulleted list formatting to lines containing selection
|
||||
ListNumber/Caption: numbered list
|
||||
@@ -149,6 +163,8 @@ PreviewType/Caption: preview type
|
||||
PreviewType/Hint: Choose preview type
|
||||
Quote/Caption: quote
|
||||
Quote/Hint: Apply quoted text formatting to lines containing selection
|
||||
RotateLeft/Caption: rotate left
|
||||
RotateLeft/Hint: Rotate image left by 90 degrees
|
||||
Size/Caption: image size
|
||||
Size/Caption/Height: Height:
|
||||
Size/Caption/Resize: Resize image
|
||||
@@ -165,5 +181,7 @@ Subscript/Caption: subscript
|
||||
Subscript/Hint: Apply subscript formatting to selection
|
||||
Superscript/Caption: superscript
|
||||
Superscript/Hint: Apply superscript formatting to selection
|
||||
Transcludify/Caption: transclusion
|
||||
Transcludify/Hint: Wrap selection in curly brackets
|
||||
Underline/Caption: underline
|
||||
Underline/Hint: Apply underline formatting to selection
|
||||
|
||||
@@ -11,7 +11,9 @@ Basics/DefaultTiddlers/Prompt: Default tiddlers:
|
||||
Basics/DefaultTiddlers/TopHint: Choose which tiddlers are displayed at startup:
|
||||
Basics/Language/Prompt: Hello! Current language:
|
||||
Basics/NewJournal/Title/Prompt: Title of new journal tiddlers
|
||||
Basics/NewJournal/Text/Prompt: Text for new journal tiddlers
|
||||
Basics/NewJournal/Tags/Prompt: Tags for new journal tiddlers
|
||||
Basics/NewTiddler/Title/Prompt: Title of new tiddlers
|
||||
Basics/OverriddenShadowTiddlers/Prompt: Number of overridden shadow tiddlers:
|
||||
Basics/ShadowTiddlers/Prompt: Number of shadow tiddlers:
|
||||
Basics/Subtitle/Prompt: Subtitle:
|
||||
@@ -52,7 +54,7 @@ Palette/HideEditor/Caption: hide editor
|
||||
Palette/Prompt: Current palette:
|
||||
Palette/ShowEditor/Caption: show editor
|
||||
Parsing/Caption: Parsing
|
||||
Parsing/Hint: Here you can globally disable individual wiki parser rules. Take care as disabling some parser rules can prevent ~TiddlyWiki functioning correctly (you can restore normal operation with [[safe mode|http://tiddlywiki.com/#SafeMode]] )
|
||||
Parsing/Hint: Here you can globally disable/enable wiki parser rules. For changes to take effect, save and reload your wiki. Disabling certain parser rules can prevent <$text text="TiddlyWiki"/> from functioning correctly. Use [[safe mode|https://tiddlywiki.com/#SafeMode]] to restore normal operation.
|
||||
Parsing/Block/Caption: Block Parse Rules
|
||||
Parsing/Inline/Caption: Inline Parse Rules
|
||||
Parsing/Pragma/Caption: Pragma Parse Rules
|
||||
@@ -71,19 +73,26 @@ Plugins/Installed/Hint: Currently installed plugins:
|
||||
Plugins/Languages/Caption: Languages
|
||||
Plugins/Languages/Hint: Language pack plugins
|
||||
Plugins/NoInfoFound/Hint: No ''"<$text text=<<currentTab>>/>"'' found
|
||||
Plugins/NoInformation/Hint: No information provided
|
||||
Plugins/NotInstalled/Hint: This plugin is not currently installed
|
||||
Plugins/OpenPluginLibrary: open plugin library
|
||||
Plugins/ClosePluginLibrary: close plugin library
|
||||
Plugins/Plugins/Caption: Plugins
|
||||
Plugins/Plugins/Hint: Plugins
|
||||
Plugins/Reinstall/Caption: reinstall
|
||||
Plugins/Themes/Caption: Themes
|
||||
Plugins/Themes/Hint: Theme plugins
|
||||
Saving/Caption: Saving
|
||||
Saving/Heading: Saving
|
||||
Saving/DownloadSaver/AutoSave/Description: Permit automatic saving for the download saver
|
||||
Saving/DownloadSaver/AutoSave/Hint: Enable Autosave for Download Saver
|
||||
Saving/DownloadSaver/Caption: Download Saver
|
||||
Saving/DownloadSaver/Hint: These settings apply to the HTML5-compatible download saver
|
||||
Saving/General/Caption: General
|
||||
Saving/General/Hint: These settings apply to all the loaded savers
|
||||
Saving/Hint: Settings used for saving the entire TiddlyWiki as a single file via a saver module
|
||||
Saving/TiddlySpot/Advanced/Heading: Advanced Settings
|
||||
Saving/TiddlySpot/BackupDir: Backup Directory
|
||||
Saving/TiddlySpot/Backups: Backups
|
||||
Saving/TiddlySpot/Caption: ~TiddlySpot Saver
|
||||
Saving/TiddlySpot/Description: These settings are only used when saving to http://tiddlyspot.com or a compatible remote server
|
||||
Saving/TiddlySpot/Filename: Upload Filename
|
||||
Saving/TiddlySpot/Heading: ~TiddlySpot
|
||||
@@ -95,7 +104,7 @@ Saving/TiddlySpot/UserName: Wiki Name
|
||||
Settings/AutoSave/Caption: Autosave
|
||||
Settings/AutoSave/Disabled/Description: Do not save changes automatically
|
||||
Settings/AutoSave/Enabled/Description: Save changes automatically
|
||||
Settings/AutoSave/Hint: Automatically save changes during editing
|
||||
Settings/AutoSave/Hint: Attempt to automatically save changes during editing when using a supporting saver
|
||||
Settings/CamelCase/Caption: Camel Case Wiki Links
|
||||
Settings/CamelCase/Hint: You can globally disable automatic linking of ~CamelCase phrases. Requires reload to take effect
|
||||
Settings/CamelCase/Description: Enable automatic ~CamelCase linking
|
||||
@@ -103,6 +112,10 @@ Settings/Caption: Settings
|
||||
Settings/EditorToolbar/Caption: Editor Toolbar
|
||||
Settings/EditorToolbar/Hint: Enable or disable the editor toolbar:
|
||||
Settings/EditorToolbar/Description: Show editor toolbar
|
||||
Settings/InfoPanelMode/Caption: Tiddler Info Panel Mode
|
||||
Settings/InfoPanelMode/Hint: Control when the tiddler info panel closes:
|
||||
Settings/InfoPanelMode/Popup/Description: Tiddler info panel closes automatically
|
||||
Settings/InfoPanelMode/Sticky/Description: Tiddler info panel stays open until explicitly closed
|
||||
Settings/Hint: These settings let you customise the behaviour of TiddlyWiki.
|
||||
Settings/NavigationAddressBar/Caption: Navigation Address Bar
|
||||
Settings/NavigationAddressBar/Hint: Behaviour of the browser address bar when navigating to a tiddler:
|
||||
@@ -127,6 +140,8 @@ Settings/ToolbarButtons/Icons/Description: Include icon
|
||||
Settings/ToolbarButtons/Text/Description: Include text
|
||||
Settings/DefaultSidebarTab/Caption: Default Sidebar Tab
|
||||
Settings/DefaultSidebarTab/Hint: Specify which sidebar tab is displayed by default
|
||||
Settings/DefaultMoreSidebarTab/Caption: Default More Sidebar Tab
|
||||
Settings/DefaultMoreSidebarTab/Hint: Specify which More sidebar tab is displayed by default
|
||||
Settings/LinkToBehaviour/Caption: Tiddler Opening Behaviour
|
||||
Settings/LinkToBehaviour/InsideRiver/Hint: Navigation from //within// the story river
|
||||
Settings/LinkToBehaviour/OutsideRiver/Hint: Navigation from //outside// the story river
|
||||
@@ -143,18 +158,22 @@ Settings/MissingLinks/Hint: Choose whether to link to tiddlers that do not exist
|
||||
Settings/MissingLinks/Description: Enable links to missing tiddlers
|
||||
StoryView/Caption: Story View
|
||||
StoryView/Prompt: Current view:
|
||||
Stylesheets/Caption: Stylesheets
|
||||
Stylesheets/Expand/Caption: Expand All
|
||||
Stylesheets/Hint: This is the rendered CSS of the current stylesheet tiddlers tagged with <<tag "$:/tags/Stylesheet">>
|
||||
Stylesheets/Restore/Caption: Restore
|
||||
Theme/Caption: Theme
|
||||
Theme/Prompt: Current theme:
|
||||
TiddlerFields/Caption: Tiddler Fields
|
||||
TiddlerFields/Hint: This is the full set of TiddlerFields in use in this wiki (including system tiddlers but excluding shadow tiddlers).
|
||||
Toolbars/Caption: Toolbars
|
||||
Toolbars/EditToolbar/Caption: Edit Toolbar
|
||||
Toolbars/EditToolbar/Hint: Choose which buttons are displayed for tiddlers in edit mode
|
||||
Toolbars/EditToolbar/Hint: Choose which buttons are displayed for tiddlers in edit mode. Drag and drop to change the ordering
|
||||
Toolbars/Hint: Select which toolbar buttons are displayed
|
||||
Toolbars/PageControls/Caption: Page Toolbar
|
||||
Toolbars/PageControls/Hint: Choose which buttons are displayed on the main page toolbar
|
||||
Toolbars/PageControls/Hint: Choose which buttons are displayed on the main page toolbar. Drag and drop to change the ordering
|
||||
Toolbars/EditorToolbar/Caption: Editor Toolbar
|
||||
Toolbars/EditorToolbar/Hint: Choose which buttons are displayed in the editor toolbar. Note that some buttons will only appear when editing tiddlers of a certain type
|
||||
Toolbars/EditorToolbar/Hint: Choose which buttons are displayed in the editor toolbar. Note that some buttons will only appear when editing tiddlers of a certain type. Drag and drop to change the ordering
|
||||
Toolbars/ViewToolbar/Caption: View Toolbar
|
||||
Toolbars/ViewToolbar/Hint: Choose which buttons are displayed for tiddlers in view mode
|
||||
Toolbars/ViewToolbar/Hint: Choose which buttons are displayed for tiddlers in view mode. Drag and drop to change the ordering
|
||||
Tools/Download/Full/Caption: Download full wiki
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
title: $:/language/Docs/ModuleTypes/
|
||||
|
||||
allfilteroperator: A sub-operator for the ''all'' filter operator.
|
||||
animation: Animations that may be used with the RevealWidget.
|
||||
bitmapeditoroperation: A bitmap editor toolbar operation.
|
||||
command: Commands that can be executed under Node.js.
|
||||
config: Data to be inserted into `$tw.config`.
|
||||
filteroperator: Individual filter operator methods.
|
||||
global: Global data to be inserted into `$tw`.
|
||||
info: Publishes system information via the [[$:/temp/info-plugin]] pseudo-plugin.
|
||||
isfilteroperator: Operands for the ''is'' filter operator.
|
||||
library: Generic module type for general purpose JavaScript modules.
|
||||
macro: JavaScript macro definitions.
|
||||
parser: Parsers for different content types.
|
||||
saver: Savers handle different methods for saving files from the browser.
|
||||
serverroute: Server routes handle different HTTP requests when using the `--server` command.
|
||||
startup: Startup functions.
|
||||
storyview: Story views customise the animation and behaviour of list widgets.
|
||||
texteditoroperation: A text editor toolbar operation.
|
||||
tiddlerdeserializer: Converts different content types into tiddlers.
|
||||
tiddlerfield: Defines the behaviour of an individual tiddler field.
|
||||
tiddlermethod: Adds methods to the `$tw.Tiddler` prototype.
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
title: $:/language/EditTemplate/
|
||||
|
||||
Body/External/Hint: This is an external tiddler stored outside of the main TiddlyWiki file. You can edit the tags and fields but cannot directly edit the content itself
|
||||
Body/External/Hint: This tiddler shows content stored outside of the main TiddlyWiki file. You can edit the tags and fields but cannot directly edit the content itself
|
||||
Body/Placeholder: Type the text for this tiddler
|
||||
Body/Preview/Type/Output: output
|
||||
Field/Remove/Caption: remove field
|
||||
Field/Remove/Hint: Remove field
|
||||
Field/Dropdown/Caption: field list
|
||||
Field/Dropdown/Hint: Show field list
|
||||
Fields/Add/Button: add
|
||||
Fields/Add/Name/Placeholder: field name
|
||||
Fields/Add/Prompt: Add a new field:
|
||||
@@ -18,6 +20,8 @@ Tags/Add/Placeholder: tag name
|
||||
Tags/Dropdown/Caption: tag list
|
||||
Tags/Dropdown/Hint: Show tag list
|
||||
Title/BadCharacterWarning: Warning: avoid using any of the characters <<bad-chars>> in tiddler titles
|
||||
Title/Exists/Prompt: Target tiddler already exists
|
||||
Title/Relink/Prompt: Update ''<$text text=<<fromTitle>>/>'' to ''<$text text=<<toTitle>>/>'' in the //tags// and //list// fields of other tiddlers
|
||||
Type/Dropdown/Caption: content type list
|
||||
Type/Dropdown/Hint: Show content type list
|
||||
Type/Delete/Caption: delete content type
|
||||
|
||||
@@ -18,7 +18,7 @@ icon: The title of the tiddler containing the icon associated with a tiddler
|
||||
library: If set to "yes" indicates that a tiddler should be saved as a JavaScript library
|
||||
list: An ordered list of tiddler titles associated with a tiddler
|
||||
list-before: If set, the title of a tiddler before which this tiddler should be added to the ordered list of tiddler titles, or at the start of the list if this field is present but empty
|
||||
list-after: If set, the title of the tiddler after which this tiddler should be added to the ordered list of tiddler titles
|
||||
list-after: If set, the title of the tiddler after which this tiddler should be added to the ordered list of tiddler titles, or at the end of the list if this field is present but empty
|
||||
modified: The date and time at which a tiddler was last modified
|
||||
modifier: The tiddler title associated with the person who last modified a tiddler
|
||||
name: The human readable name associated with a plugin tiddler
|
||||
|
||||
@@ -11,4 +11,5 @@ SystemTiddlers: System tiddlers
|
||||
ShadowTiddlers: Shadow tiddlers
|
||||
OverriddenShadowTiddlers: Overridden shadow tiddlers
|
||||
SystemTags: System tags
|
||||
StoryList: Tiddlers in the story river, excluding <$text text="$:/AdvancedSearch"/>
|
||||
TypedTiddlers: Non wiki-text tiddlers
|
||||
@@ -3,7 +3,7 @@ title: GettingStarted
|
||||
\define lingo-base() $:/language/ControlPanel/Basics/
|
||||
Welcome to ~TiddlyWiki and the ~TiddlyWiki community
|
||||
|
||||
Before you start storing important information in ~TiddlyWiki it is important to make sure that you can reliably save changes. See http://tiddlywiki.com/#GettingStarted for details
|
||||
Before you start storing important information in ~TiddlyWiki it is vital to make sure that you can reliably save changes. See https://tiddlywiki.com/#GettingStarted for details
|
||||
|
||||
!! Set up this ~TiddlyWiki
|
||||
|
||||
|
||||
38
core/language/en-GB/Help/fetch.tid
Normal file
38
core/language/en-GB/Help/fetch.tid
Normal file
@@ -0,0 +1,38 @@
|
||||
title: $:/language/Help/fetch
|
||||
description: Fetch tiddlers from wiki by URL
|
||||
|
||||
Fetch one or more files over HTTP/HTTPS, and import the tiddlers matching a filter, optionally transforming the incoming titles.
|
||||
|
||||
```
|
||||
--fetch file <url> <import-filter> <transform-filter>
|
||||
--fetch files <url-filter> <import-filter> <transform-filter>
|
||||
--fetch raw-file <url> <transform-filter>
|
||||
--fetch raw-files <url-filter> <transform-filter>
|
||||
```
|
||||
|
||||
The "file" and "files" variants fetch the specified files and attempt to import the tiddlers within them (the same processing as if the files were dragged into the browser window). The "raw-file" and "raw-files" variants fetch the specified files and then store the raw file data in tiddlers, without applying the import logic.
|
||||
|
||||
With the "file" and "raw-file" variants only a single file is fetched and the first parameter is the URL of the file to read.
|
||||
|
||||
With the "files" and "raw-files" variants, multiple files are fetched and the first parameter is a filter yielding a list of URLs of the files to read. For example, given a set of tiddlers tagged "remote-server" that have a field "url" the filter `[tag[remote-server]get[url]]` will retrieve all the available URLs.
|
||||
|
||||
For the "file" and "files" variants, the `<import-filter>` parameter specifies a filter determining which tiddlers are imported. It defaults to `[all[tiddlers]]` if not provided.
|
||||
|
||||
For all variants, the `<transform-filter>` parameter specifies an optional filter that transforms the titles of the imported tiddlers. For example, `[addprefix[$:/myimports/]]` would add the prefix `$:/myimports/` to each title.
|
||||
|
||||
Preceding the `--fetch` command with `--verbose` will output progress information during the import.
|
||||
|
||||
Note that TiddlyWiki will not fetch an older version of an already loaded plugin.
|
||||
|
||||
The following example retrieves all the non-system tiddlers from https://tiddlywiki.com and saves them to a JSON file:
|
||||
|
||||
```
|
||||
tiddlywiki --verbose --fetch file "https://tiddlywiki.com/" "[!is[system]]" "" --rendertiddler "$:/core/templates/exporters/JsonFile" output.json text/plain "" exportFilter "[!is[system]]"
|
||||
```
|
||||
|
||||
The following example retrieves the "favicon" file from tiddlywiki.com and saves it in a file called "output.ico". Note that the intermediate tiddler "Icon Tiddler" is quoted in the "--fetch" command because it is being used as a transformation filter to replace the default title, while there are no quotes for the "--savetiddler" command because it is being used directly as a title.
|
||||
|
||||
```
|
||||
tiddlywiki --verbose --fetch raw-file "https://tiddlywiki.com/favicon.ico" "[[Icon Tiddler]]" --savetiddler "Icon Tiddler" output.ico
|
||||
```
|
||||
|
||||
24
core/language/en-GB/Help/import.tid
Normal file
24
core/language/en-GB/Help/import.tid
Normal file
@@ -0,0 +1,24 @@
|
||||
title: $:/language/Help/import
|
||||
description: Import tiddlers from a file
|
||||
|
||||
Import tiddlers from TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` or other local files. The deserializer must be explicitly specified, unlike the `load` command which infers the deserializer from the file extension.
|
||||
|
||||
```
|
||||
--import <filepath> <deserializer> [<title>] [<encoding>]
|
||||
```
|
||||
|
||||
The deserializers in the core include:
|
||||
|
||||
* application/javascript
|
||||
* application/json
|
||||
* application/x-tiddler
|
||||
* application/x-tiddler-html-div
|
||||
* application/x-tiddlers
|
||||
* text/html
|
||||
* text/plain
|
||||
|
||||
The title of the imported tiddler defaults to the filename.
|
||||
|
||||
The encoding defaults to "utf8", but can be "base64" for importing binary files.
|
||||
|
||||
Note that TiddlyWiki will not import an older version of an already loaded plugin.
|
||||
@@ -1,10 +1,11 @@
|
||||
title: $:/language/Help/load
|
||||
description: Load tiddlers from a file
|
||||
|
||||
Load tiddlers from 2.x.x TiddlyWiki files (`.html`), `.tiddler`, `.tid`, `.json` or other files
|
||||
Load tiddlers from TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` or other local files. The processing applied to incoming files is determined by the file extension. Use the alternative `import` command if you need to specify the deserializer and encoding explicitly.
|
||||
|
||||
```
|
||||
--load <filepath>
|
||||
--load <dirpath>
|
||||
```
|
||||
|
||||
To load tiddlers from an encrypted TiddlyWiki file you should first specify the password with the PasswordCommand. For example:
|
||||
|
||||
34
core/language/en-GB/Help/render.tid
Normal file
34
core/language/en-GB/Help/render.tid
Normal file
@@ -0,0 +1,34 @@
|
||||
title: $:/language/Help/render
|
||||
description: Renders individual tiddlers to files
|
||||
|
||||
Render individual tiddlers identified by a filter and save the results to the specified files.
|
||||
|
||||
Optionally, the title of a template tiddler can be specified. In this case, instead of directly rendering each tiddler, the template tiddler is rendered with the "currentTiddler" variable set to the title of the tiddler that is being rendered.
|
||||
|
||||
A name and value for an additional variable may optionally also be specified.
|
||||
|
||||
```
|
||||
--render <tiddler-filter> [<filename-filter>] [<render-type>] [<template>] [<name>] [<value>]
|
||||
```
|
||||
|
||||
* ''tiddler-filter'': A filter identifying the tiddler(s) to be rendered
|
||||
* ''filename-filter'': Optional filter transforming tiddler titles into pathnames. If omitted, defaults to `[is[tiddler]addsuffix[.html]]`, which uses the unchanged tiddler title as the filename
|
||||
* ''template'': Optional template through which each tiddler is rendered
|
||||
* ''render-type'': Optional render type: `text/html` (the default) returns the full HTML text and `text/plain` just returns the text content (ie it ignores HTML tags and other unprintable material)
|
||||
* ''name'': Name of optional variable
|
||||
* ''value'': Value of optional variable
|
||||
|
||||
By default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.
|
||||
|
||||
Notes:
|
||||
|
||||
* The output directory is not cleared of any existing files
|
||||
* Any missing directories in the path to the filename are automatically created.
|
||||
* When referring to a tiddler with spaces in its title, take care to use both the quotes required by your shell and also TiddlyWiki's double square brackets : `--render "[[Motovun Jack.jpg]]"`
|
||||
* The filename filter is evaluated with the selected items being set to the title of the tiddler currently being rendered, allowing the title to be used as the basis for computing the filename. For example `[encodeuricomponent[]addprefix[static/]]` applies URI encoding to each title, and then adds the prefix `static/`
|
||||
* The `--render` command is a more flexible replacement for both the `--rendertiddler` and `--rendertiddlers` commands, which are deprecated
|
||||
|
||||
Examples:
|
||||
|
||||
* `--render "[!is[system]]" "[encodeuricomponent[]addprefix[tiddlers/]addsuffix[.html]]"` -- renders all non-system tiddlers as files in the subdirectory "tiddlers" with URL-encoded titles and the extension HTML
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
title: $:/language/Help/rendertiddler
|
||||
description: Render an individual tiddler as a specified ContentType
|
||||
|
||||
Render an individual tiddler as a specified ContentType, defaulting to `text/html` and save it to the specified filename. Optionally a template can be specified, in which case the template tiddler is rendered with the "currentTiddler" variable set to the tiddler that is being rendered (the first parameter value).
|
||||
(Note: The `--rendertiddler` command is deprecated in favour of the new, more flexible `--render` command)
|
||||
|
||||
Render an individual tiddler as a specified ContentType, defaulting to `text/html` and save it to the specified filename.
|
||||
|
||||
Optionally the title of a template tiddler can be specified, in which case the template tiddler is rendered with the "currentTiddler" variable set to the tiddler that is being rendered (the first parameter value).
|
||||
|
||||
A name and value for an additional variable may optionally also be specified.
|
||||
|
||||
```
|
||||
--rendertiddler <title> <filename> [<type>] [<template>]
|
||||
--rendertiddler <title> <filename> [<type>] [<template>] [<name>] [<value>]
|
||||
```
|
||||
|
||||
By default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.
|
||||
|
||||
Any missing directories in the path to the filename are automatically created.
|
||||
|
||||
For example, the following command saves all tiddlers matching the filter `[tag[done]]` to a JSON file titled `output.json` by employing the core template `$:/core/templates/exporters/JsonFile`.
|
||||
|
||||
```
|
||||
--rendertiddler "$:/core/templates/exporters/JsonFile" output.json text/plain "" exportFilter "[tag[done]]"
|
||||
```
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
title: $:/language/Help/rendertiddlers
|
||||
description: Render tiddlers matching a filter to a specified ContentType
|
||||
|
||||
(Note: The `--rendertiddlers` command is deprecated in favour of the new, more flexible `--render` command)
|
||||
|
||||
Render a set of tiddlers matching a filter to separate files of a specified ContentType (defaults to `text/html`) and extension (defaults to `.html`).
|
||||
|
||||
```
|
||||
|
||||
25
core/language/en-GB/Help/save.tid
Normal file
25
core/language/en-GB/Help/save.tid
Normal file
@@ -0,0 +1,25 @@
|
||||
title: $:/language/Help/save
|
||||
description: Saves individual raw tiddlers to files
|
||||
|
||||
Saves individual tiddlers identified by a filter in their raw text or binary format to the specified files.
|
||||
|
||||
```
|
||||
--save <tiddler-filter> <filename-filter>
|
||||
```
|
||||
|
||||
* ''tiddler-filter'': A filter identifying the tiddler(s) to be saved
|
||||
* ''filename-filter'': Optional filter transforming tiddler titles into pathnames. If omitted, defaults to `[is[tiddler]]`, which uses the unchanged tiddler title as the filename
|
||||
|
||||
By default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.
|
||||
|
||||
Notes:
|
||||
|
||||
* The output directory is not cleared of any existing files
|
||||
* Any missing directories in the path to the filename are automatically created.
|
||||
* When saving a tiddler with spaces in its title, take care to use both the quotes required by your shell and also TiddlyWiki's double square brackets : `--save "[[Motovun Jack.jpg]]"`
|
||||
* The filename filter is evaluated with the selected items being set to the title of the tiddler currently being saved, allowing the title to be used as the basis for computing the filename. For example `[encodeuricomponent[]addprefix[static/]]` applies URI encoding to each title, and then adds the prefix `static/`
|
||||
* The `--save` command is a more flexible replacement for both the `--savetiddler` and `--savetiddlers` commands, which are deprecated
|
||||
|
||||
Examples:
|
||||
|
||||
* `--save "[!is[system]is[image]]" "[encodeuricomponent[]addprefix[tiddlers/]]"` -- saves all non-system image tiddlers as files in the subdirectory "tiddlers" with URL-encoded titles
|
||||
@@ -1,6 +1,8 @@
|
||||
title: $:/language/Help/savetiddler
|
||||
description: Saves a raw tiddler to a file
|
||||
|
||||
(Note: The `--savetiddler` command is deprecated in favour of the new, more flexible `--save` command)
|
||||
|
||||
Saves an individual tiddler in its raw text or binary format to the specified filename.
|
||||
|
||||
```
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
title: $:/language/Help/savetiddlers
|
||||
description: Saves a group of raw tiddlers to a directory
|
||||
|
||||
(Note: The `--savetiddlers` command is deprecated in favour of the new, more flexible `--save` command)
|
||||
|
||||
Saves a group of tiddlers in their raw text or binary format to the specified directory.
|
||||
|
||||
```
|
||||
|
||||
@@ -11,7 +11,7 @@ At the root, it serves a rendering of a specified tiddler. Away from the root, i
|
||||
|
||||
The parameters are:
|
||||
|
||||
* ''port'' - port number to serve from (defaults to "8080")
|
||||
* ''port'' - port number on which to listen; non-numeric values are interpreted as a system environment variable from which the port number is extracted (defaults to "8080")
|
||||
* ''roottiddler'' - the tiddler to serve at the root (defaults to "$:/core/save/all")
|
||||
* ''rendertype'' - the content type to which the root tiddler should be rendered (defaults to "text/plain")
|
||||
* ''servetype'' - the content type with which the root tiddler should be served (defaults to "text/html")
|
||||
@@ -19,6 +19,7 @@ The parameters are:
|
||||
* ''password'' - optional password for basic authentication
|
||||
* ''host'' - optional hostname to serve from (defaults to "127.0.0.1" aka "localhost")
|
||||
* ''pathprefix'' - optional prefix for paths
|
||||
* ''debuglevel'' - optional debug level; set to "debug" to view request details (defaults to "none")
|
||||
|
||||
If the password parameter is specified then the browser will prompt the user for the username and password. Note that the password is transmitted in plain text so this implementation isn't suitable for general use.
|
||||
|
||||
@@ -34,4 +35,9 @@ The username and password can be specified as empty strings if you need to set t
|
||||
--server 8080 $:/core/save/all text/plain text/html "" "" 192.168.0.245
|
||||
```
|
||||
|
||||
To run multiple TiddlyWiki servers at the same time you'll need to put each one on a different port.
|
||||
To run multiple TiddlyWiki servers at the same time you'll need to put each one on a different port. It can be useful to use an environment variable to pass the port number to the Node.js process. This example references an environment variable called "MY_PORT_NUMBER":
|
||||
|
||||
|
||||
```
|
||||
--server MY_PORT_NUMBER $:/core/save/all text/plain text/html MyUserName passw0rd
|
||||
```
|
||||
|
||||
@@ -7,6 +7,12 @@ Listing/Import/Caption: Import
|
||||
Listing/Select/Caption: Select
|
||||
Listing/Status/Caption: Status
|
||||
Listing/Title/Caption: Title
|
||||
Listing/Preview: Preview:
|
||||
Listing/Preview/Text: Text
|
||||
Listing/Preview/TextRaw: Text (Raw)
|
||||
Listing/Preview/Fields: Fields
|
||||
Listing/Preview/Diff: Diff
|
||||
Listing/Preview/DiffFields: Diff (Fields)
|
||||
Upgrader/Plugins/Suppressed/Incompatible: Blocked incompatible or obsolete plugin
|
||||
Upgrader/Plugins/Suppressed/Version: Blocked plugin (due to incoming <<incoming>> being older than existing <<existing>>)
|
||||
Upgrader/Plugins/Upgraded: Upgraded plugin from <<incoming>> to <<upgraded>>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
title: $:/language/
|
||||
|
||||
AboveStory/ClassicPlugin/Warning: It looks like you are trying to load a plugin designed for ~TiddlyWiki Classic. Please note that [[these plugins do not work with TiddlyWiki version 5.x.x|http://tiddlywiki.com/#TiddlyWikiClassic]]. ~TiddlyWiki Classic plugins detected:
|
||||
AboveStory/ClassicPlugin/Warning: It looks like you are trying to load a plugin designed for ~TiddlyWiki Classic. Please note that [[these plugins do not work with TiddlyWiki version 5.x.x|https://tiddlywiki.com/#TiddlyWikiClassic]]. ~TiddlyWiki Classic plugins detected:
|
||||
BinaryWarning/Prompt: This tiddler contains binary data
|
||||
ClassicWarning/Hint: This tiddler is written in TiddlyWiki Classic wiki text format, which is not fully compatible with TiddlyWiki version 5. See http://tiddlywiki.com/static/Upgrading.html for more details.
|
||||
ClassicWarning/Hint: This tiddler is written in TiddlyWiki Classic wiki text format, which is not fully compatible with TiddlyWiki version 5. See https://tiddlywiki.com/static/Upgrading.html for more details.
|
||||
ClassicWarning/Upgrade/Caption: upgrade
|
||||
CloseAll/Button: close all
|
||||
ColourPicker/Recent: Recent:
|
||||
@@ -12,6 +12,7 @@ ConfirmOverwriteTiddler: Do you wish to overwrite the tiddler "<$text text=<<tit
|
||||
ConfirmEditShadowTiddler: You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit "<$text text=<<title>>/>"?
|
||||
Count: count
|
||||
DefaultNewTiddlerTitle: New Tiddler
|
||||
Diffs/CountMessage: <<diff-count>> differences
|
||||
DropMessage: Drop here (or use the 'Escape' key to cancel)
|
||||
Encryption/Cancel: Cancel
|
||||
Encryption/ConfirmClearPassword: Do you wish to clear the password? This will remove the encryption applied when saving this wiki
|
||||
@@ -22,6 +23,7 @@ Encryption/RepeatPassword: Repeat password
|
||||
Encryption/PasswordNoMatch: Passwords do not match
|
||||
Encryption/SetPassword: Set password
|
||||
Error/Caption: Error
|
||||
Error/EditConflict: File changed on server
|
||||
Error/Filter: Filter error
|
||||
Error/FilterSyntax: Syntax error in filter expression
|
||||
Error/IsFilterOperator: Filter Error: Unknown operand for the 'is' filter operator
|
||||
@@ -34,15 +36,33 @@ Error/XMLHttpRequest: XMLHttpRequest error code
|
||||
InternalJavaScriptError/Title: Internal JavaScript Error
|
||||
InternalJavaScriptError/Hint: Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser
|
||||
InvalidFieldName: Illegal characters in field name "<$text text=<<fieldName>>/>". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`)
|
||||
LazyLoadingWarning: <p>Loading external text from ''<$text text={{!!_canonical_uri}}/>''</p><p>If this message doesn't disappear you may be using a browser that doesn't support external text in this configuration. See http://tiddlywiki.com/#ExternalText</p>
|
||||
LazyLoadingWarning: <p>Trying to load external content from ''<$text text={{!!_canonical_uri}}/>''</p><p>If this message doesn't disappear, either the tiddler content type doesn't match the type of the external content, or you may be using a browser that doesn't support external content for wikis loaded as standalone files. See https://tiddlywiki.com/#ExternalText</p>
|
||||
LoginToTiddlySpace: Login to TiddlySpace
|
||||
MissingTiddler/Hint: Missing tiddler "<$text text=<<currentTiddler>>/>" - click {{$:/core/images/edit-button}} to create
|
||||
Manager/Controls/FilterByTag/None: (none)
|
||||
Manager/Controls/FilterByTag/Prompt: Filter by tag:
|
||||
Manager/Controls/Order/Prompt: Reverse order
|
||||
Manager/Controls/Search/Placeholder: Search
|
||||
Manager/Controls/Search/Prompt: Search:
|
||||
Manager/Controls/Show/Option/Tags: tags
|
||||
Manager/Controls/Show/Option/Tiddlers: tiddlers
|
||||
Manager/Controls/Show/Prompt: Show:
|
||||
Manager/Controls/Sort/Prompt: Sort by:
|
||||
Manager/Item/Colour: Colour
|
||||
Manager/Item/Fields: Fields
|
||||
Manager/Item/Icon/None: (none)
|
||||
Manager/Item/Icon: Icon
|
||||
Manager/Item/RawText: Raw text
|
||||
Manager/Item/Tags: Tags
|
||||
Manager/Item/Tools: Tools
|
||||
Manager/Item/WikifiedText: Wikified text
|
||||
MissingTiddler/Hint: Missing tiddler "<$text text=<<currentTiddler>>/>" -- click {{||$:/core/ui/Buttons/edit}} to create
|
||||
No: No
|
||||
OfficialPluginLibrary: Official ~TiddlyWiki Plugin Library
|
||||
OfficialPluginLibrary/Hint: The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team.
|
||||
PluginReloadWarning: Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to plugins to take effect
|
||||
RecentChanges/DateFormat: DDth MMM YYYY
|
||||
SystemTiddler/Tooltip: This is a system tiddler
|
||||
SystemTiddlers/Include/Prompt: Include system tiddlers
|
||||
TagManager/Colour/Heading: Colour
|
||||
TagManager/Count/Heading: Count
|
||||
TagManager/Icon/Heading: Icon
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
title: $:/language/Modals/Download
|
||||
type: text/vnd.tiddlywiki
|
||||
subtitle: Download changes
|
||||
footer: <$button message="tm-close-tiddler">Close</$button>
|
||||
help: http://tiddlywiki.com/static/DownloadingChanges.html
|
||||
help: https://tiddlywiki.com/static/DownloadingChanges.html
|
||||
|
||||
Your browser only supports manual saving.
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
title: $:/language/Modals/SaveInstructions
|
||||
type: text/vnd.tiddlywiki
|
||||
subtitle: Save your work
|
||||
footer: <$button message="tm-close-tiddler">Close</$button>
|
||||
help: http://tiddlywiki.com/static/SavingChanges.html
|
||||
help: https://tiddlywiki.com/static/SavingChanges.html
|
||||
|
||||
Your changes to this wiki need to be saved as a ~TiddlyWiki HTML file.
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
title: $:/config/NewJournal/
|
||||
|
||||
Title: DDth MMM YYYY
|
||||
Text:
|
||||
Tags: Journal
|
||||
|
||||
@@ -2,3 +2,5 @@ title: $:/language/Notifications/
|
||||
|
||||
Save/Done: Saved wiki
|
||||
Save/Starting: Starting to save wiki
|
||||
CopiedToClipboard/Succeeded: Copied!
|
||||
CopiedToClipboard/Failed: Failed to copy to clipboard!
|
||||
|
||||
@@ -2,12 +2,13 @@ title: $:/language/Search/
|
||||
|
||||
DefaultResults/Caption: List
|
||||
Filter/Caption: Filter
|
||||
Filter/Hint: Search via a [[filter expression|http://tiddlywiki.com/static/Filters.html]]
|
||||
Filter/Hint: Search via a [[filter expression|https://tiddlywiki.com/static/Filters.html]]
|
||||
Filter/Matches: //<small><<resultCount>> matches</small>//
|
||||
Matches: //<small><<resultCount>> matches</small>//
|
||||
Matches/All: All matches:
|
||||
Matches/Title: Title matches:
|
||||
Search: Search
|
||||
Search/TooShort: Search text too short
|
||||
Shadows/Caption: Shadows
|
||||
Shadows/Hint: Search for shadow tiddlers
|
||||
Shadows/Matches: //<small><<resultCount>> matches</small>//
|
||||
|
||||
@@ -3,6 +3,7 @@ title: $:/language/SideBar/
|
||||
All/Caption: All
|
||||
Contents/Caption: Contents
|
||||
Drafts/Caption: Drafts
|
||||
Explorer/Caption: Explorer
|
||||
Missing/Caption: Missing
|
||||
More/Caption: More
|
||||
Open/Caption: Open
|
||||
|
||||
@@ -7,11 +7,12 @@ Options/SidebarLayout: Sidebar layout
|
||||
Options/SidebarLayout/Fixed-Fluid: Fixed story, fluid sidebar
|
||||
Options/SidebarLayout/Fluid-Fixed: Fluid story, fixed sidebar
|
||||
Options/StickyTitles: Sticky titles
|
||||
Options/StickyTitles/Hint: Causes tiddler titles to "stick" to the top of the browser window. Caution: Does not work at all with Chrome, and causes some layout issues in Firefox
|
||||
Options/StickyTitles/Hint: Causes tiddler titles to "stick" to the top of the browser window
|
||||
Options/CodeWrapping: Wrap long lines in code blocks
|
||||
Settings: Settings
|
||||
Settings/FontFamily: Font family
|
||||
Settings/CodeFontFamily: Code font family
|
||||
Settings/EditorFontFamily: Editor font family
|
||||
Settings/BackgroundImage: Page background image
|
||||
Settings/BackgroundImageAttachment: Page background image attachment
|
||||
Settings/BackgroundImageAttachment/Scroll: Scroll with tiddlers
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/application/javascript
|
||||
description: JavaScript code
|
||||
name: application/javascript
|
||||
group: Developer
|
||||
group-sort: 2
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/application/json
|
||||
description: JSON data
|
||||
name: application/json
|
||||
group: Developer
|
||||
group-sort: 2
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/application/x-tiddler-dictionary
|
||||
description: Data dictionary
|
||||
name: application/x-tiddler-dictionary
|
||||
group: Developer
|
||||
group-sort: 2
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/image/gif
|
||||
description: GIF image
|
||||
name: image/gif
|
||||
group: Image
|
||||
group-sort: 1
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/image/jpeg
|
||||
description: JPEG image
|
||||
name: image/jpeg
|
||||
group: Image
|
||||
group-sort: 1
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/image/png
|
||||
description: PNG image
|
||||
name: image/png
|
||||
group: Image
|
||||
group-sort: 1
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/image/svg+xml
|
||||
description: Structured Vector Graphics image
|
||||
name: image/svg+xml
|
||||
group: Image
|
||||
group-sort: 1
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/image/x-icon
|
||||
description: ICO format icon file
|
||||
name: image/x-icon
|
||||
group: Image
|
||||
group-sort: 1
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/text/css
|
||||
description: Static stylesheet
|
||||
name: text/css
|
||||
group: Developer
|
||||
group-sort: 2
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/text/html
|
||||
description: HTML markup
|
||||
name: text/html
|
||||
group: Text
|
||||
group-sort: 0
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/text/plain
|
||||
description: Plain text
|
||||
name: text/plain
|
||||
group: Text
|
||||
group-sort: 0
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/text/vnd.tiddlywiki
|
||||
description: TiddlyWiki 5
|
||||
name: text/vnd.tiddlywiki
|
||||
group: Text
|
||||
group-sort: 0
|
||||
|
||||
@@ -2,3 +2,4 @@ title: $:/language/Docs/Types/text/x-tiddlywiki
|
||||
description: TiddlyWiki Classic
|
||||
name: text/x-tiddlywiki
|
||||
group: Text
|
||||
group-sort: 0
|
||||
|
||||
@@ -29,6 +29,24 @@ var Commander = function(commandTokens,callback,wiki,streams) {
|
||||
this.outputPath = path.resolve($tw.boot.wikiPath,$tw.config.wikiOutputSubDir);
|
||||
};
|
||||
|
||||
/*
|
||||
Log a string if verbose flag is set
|
||||
*/
|
||||
Commander.prototype.log = function(str) {
|
||||
if(this.verbose) {
|
||||
this.streams.output.write(str + "\n");
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Write a string if verbose flag is set
|
||||
*/
|
||||
Commander.prototype.write = function(str) {
|
||||
if(this.verbose) {
|
||||
this.streams.output.write(str);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Add a string of tokens to the command queue
|
||||
*/
|
||||
|
||||
175
core/modules/commands/fetch.js
Normal file
175
core/modules/commands/fetch.js
Normal file
@@ -0,0 +1,175 @@
|
||||
/*\
|
||||
title: $:/core/modules/commands/fetch.js
|
||||
type: application/javascript
|
||||
module-type: command
|
||||
|
||||
Commands to fetch external tiddlers
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.info = {
|
||||
name: "fetch",
|
||||
synchronous: false
|
||||
};
|
||||
|
||||
var Command = function(params,commander,callback) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
if(this.params.length < 2) {
|
||||
return "Missing subcommand and url";
|
||||
}
|
||||
switch(this.params[0]) {
|
||||
case "raw-file":
|
||||
return this.fetchFiles({
|
||||
raw: true,
|
||||
url: this.params[1],
|
||||
transformFilter: this.params[2] || "",
|
||||
callback: this.callback
|
||||
});
|
||||
break;
|
||||
case "file":
|
||||
return this.fetchFiles({
|
||||
url: this.params[1],
|
||||
importFilter: this.params[2],
|
||||
transformFilter: this.params[3] || "",
|
||||
callback: this.callback
|
||||
});
|
||||
break;
|
||||
case "raw-files":
|
||||
return this.fetchFiles({
|
||||
raw: true,
|
||||
urlFilter: this.params[1],
|
||||
transformFilter: this.params[2] || "",
|
||||
callback: this.callback
|
||||
});
|
||||
break;
|
||||
case "files":
|
||||
return this.fetchFiles({
|
||||
urlFilter: this.params[1],
|
||||
importFilter: this.params[2],
|
||||
transformFilter: this.params[3] || "",
|
||||
callback: this.callback
|
||||
});
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
Command.prototype.fetchFiles = function(options) {
|
||||
var self = this;
|
||||
// Get the list of URLs
|
||||
var urls;
|
||||
if(options.url) {
|
||||
urls = [options.url]
|
||||
} else if(options.urlFilter) {
|
||||
urls = $tw.wiki.filterTiddlers(options.urlFilter);
|
||||
} else {
|
||||
return "Missing URL";
|
||||
}
|
||||
// Process each URL in turn
|
||||
var next = 0;
|
||||
var getNextFile = function(err) {
|
||||
if(err) {
|
||||
return options.callback(err);
|
||||
}
|
||||
if(next < urls.length) {
|
||||
self.fetchFile(urls[next++],options,getNextFile);
|
||||
} else {
|
||||
options.callback(null);
|
||||
}
|
||||
};
|
||||
getNextFile(null);
|
||||
// Success
|
||||
return null;
|
||||
};
|
||||
|
||||
Command.prototype.fetchFile = function(url,options,callback,redirectCount) {
|
||||
if(redirectCount > 10) {
|
||||
return callback("Error too many redirects retrieving " + url);
|
||||
}
|
||||
var self = this,
|
||||
lib = url.substr(0,8) === "https://" ? require("https") : require("http");
|
||||
lib.get(url).on("response",function(response) {
|
||||
var type = (response.headers["content-type"] || "").split(";")[0],
|
||||
data = [];
|
||||
self.commander.write("Reading " + url + ": ");
|
||||
response.on("data",function(chunk) {
|
||||
data.push(chunk);
|
||||
self.commander.write(".");
|
||||
});
|
||||
response.on("end",function() {
|
||||
self.commander.write("\n");
|
||||
if(response.statusCode === 200) {
|
||||
self.processBody(Buffer.concat(data),type,options,url);
|
||||
callback(null);
|
||||
} else {
|
||||
if(response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {
|
||||
return self.fetchFile(response.headers.location,options,callback,redirectCount + 1);
|
||||
} else {
|
||||
return callback("Error " + response.statusCode + " retrieving " + url)
|
||||
}
|
||||
}
|
||||
});
|
||||
response.on("error",function(e) {
|
||||
console.log("Error on GET request: " + e);
|
||||
callback(e);
|
||||
});
|
||||
});
|
||||
return null;
|
||||
};
|
||||
|
||||
Command.prototype.processBody = function(body,type,options,url) {
|
||||
var self = this;
|
||||
// Collect the tiddlers in a wiki
|
||||
var incomingWiki = new $tw.Wiki();
|
||||
if(options.raw) {
|
||||
var typeInfo = type ? $tw.config.contentTypeInfo[type] : null,
|
||||
encoding = typeInfo ? typeInfo.encoding : "utf8";
|
||||
incomingWiki.addTiddler(new $tw.Tiddler({
|
||||
title: url,
|
||||
type: type,
|
||||
text: body.toString(encoding)
|
||||
}));
|
||||
} else {
|
||||
// Deserialise the file to extract the tiddlers
|
||||
var tiddlers = this.commander.wiki.deserializeTiddlers(type || "text/html",body.toString("utf8"),{});
|
||||
$tw.utils.each(tiddlers,function(tiddler) {
|
||||
incomingWiki.addTiddler(new $tw.Tiddler(tiddler));
|
||||
});
|
||||
}
|
||||
// Filter the tiddlers to select the ones we want
|
||||
var filteredTitles = incomingWiki.filterTiddlers(options.importFilter || "[all[tiddlers]]");
|
||||
// Import the selected tiddlers
|
||||
var count = 0;
|
||||
incomingWiki.each(function(tiddler,title) {
|
||||
if(filteredTitles.indexOf(title) !== -1) {
|
||||
var newTiddler;
|
||||
if(options.transformFilter) {
|
||||
var transformedTitle = (incomingWiki.filterTiddlers(options.transformFilter,null,self.commander.wiki.makeTiddlerIterator([title])) || [""])[0];
|
||||
if(transformedTitle) {
|
||||
self.commander.log("Importing " + title + " as " + transformedTitle)
|
||||
newTiddler = new $tw.Tiddler(tiddler,{title: transformedTitle});
|
||||
}
|
||||
} else {
|
||||
self.commander.log("Importing " + title)
|
||||
newTiddler = tiddler;
|
||||
}
|
||||
self.commander.wiki.importTiddler(newTiddler);
|
||||
count++;
|
||||
}
|
||||
});
|
||||
self.commander.log("Imported " + count + " tiddlers")
|
||||
};
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
||||
48
core/modules/commands/import.js
Normal file
48
core/modules/commands/import.js
Normal file
@@ -0,0 +1,48 @@
|
||||
/*\
|
||||
title: $:/core/modules/commands/import.js
|
||||
type: application/javascript
|
||||
module-type: command
|
||||
|
||||
Command to import tiddlers from a file
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.info = {
|
||||
name: "import",
|
||||
synchronous: true
|
||||
};
|
||||
|
||||
var Command = function(params,commander,callback) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
var self = this,
|
||||
fs = require("fs"),
|
||||
path = require("path");
|
||||
if(this.params.length < 2) {
|
||||
return "Missing parameters";
|
||||
}
|
||||
var filename = self.params[0],
|
||||
deserializer = self.params[1],
|
||||
title = self.params[2] || filename,
|
||||
encoding = self.params[3] || "utf8",
|
||||
text = fs.readFileSync(filename,encoding),
|
||||
tiddlers = this.commander.wiki.deserializeTiddlers(null,text,{title: title},{deserializer: deserializer});
|
||||
$tw.utils.each(tiddlers,function(tiddler) {
|
||||
self.commander.wiki.importTiddler(new $tw.Tiddler(tiddler));
|
||||
});
|
||||
this.commander.log(tiddlers.length + " tiddler(s) imported");
|
||||
return null;
|
||||
};
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
||||
@@ -3,7 +3,7 @@ title: $:/core/modules/commands/load.js
|
||||
type: application/javascript
|
||||
module-type: command
|
||||
|
||||
Command to load tiddlers from a file
|
||||
Command to load tiddlers from a file or directory
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@@ -30,24 +30,19 @@ Command.prototype.execute = function() {
|
||||
if(this.params.length < 1) {
|
||||
return "Missing filename";
|
||||
}
|
||||
var ext = path.extname(self.params[0]);
|
||||
fs.readFile(this.params[0],$tw.utils.getTypeEncoding(ext),function(err,data) {
|
||||
if (err) {
|
||||
self.callback(err);
|
||||
} else {
|
||||
var fields = {title: self.params[0]},
|
||||
type = path.extname(self.params[0]);
|
||||
var tiddlers = self.commander.wiki.deserializeTiddlers(type,data,fields);
|
||||
if(!tiddlers) {
|
||||
self.callback("No tiddlers found in file \"" + self.params[0] + "\"");
|
||||
} else {
|
||||
for(var t=0; t<tiddlers.length; t++) {
|
||||
self.commander.wiki.importTiddler(new $tw.Tiddler(tiddlers[t]));
|
||||
}
|
||||
self.callback(null);
|
||||
}
|
||||
}
|
||||
var tiddlers = $tw.loadTiddlersFromPath(self.params[0]),
|
||||
count = 0;
|
||||
$tw.utils.each(tiddlers,function(tiddlerInfo) {
|
||||
$tw.utils.each(tiddlerInfo.tiddlers,function(tiddler) {
|
||||
self.commander.wiki.importTiddler(new $tw.Tiddler(tiddler));
|
||||
count++;
|
||||
});
|
||||
});
|
||||
if(!count) {
|
||||
self.callback("No tiddlers found in file \"" + self.params[0] + "\"");
|
||||
} else {
|
||||
self.callback(null);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
65
core/modules/commands/render.js
Normal file
65
core/modules/commands/render.js
Normal file
@@ -0,0 +1,65 @@
|
||||
/*\
|
||||
title: $:/core/modules/commands/render.js
|
||||
type: application/javascript
|
||||
module-type: command
|
||||
|
||||
Render individual tiddlers and save the results to the specified files
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var widget = require("$:/core/modules/widgets/widget.js");
|
||||
|
||||
exports.info = {
|
||||
name: "render",
|
||||
synchronous: true
|
||||
};
|
||||
|
||||
var Command = function(params,commander,callback) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
if(this.params.length < 1) {
|
||||
return "Missing tiddler filter";
|
||||
}
|
||||
var self = this,
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
wiki = this.commander.wiki,
|
||||
tiddlerFilter = this.params[0],
|
||||
filenameFilter = this.params[1] || "[is[tiddler]addsuffix[.html]]",
|
||||
type = this.params[2] || "text/html",
|
||||
template = this.params[3],
|
||||
varName = this.params[4],
|
||||
varValue = this.params[5],
|
||||
tiddlers = wiki.filterTiddlers(tiddlerFilter);
|
||||
$tw.utils.each(tiddlers,function(title) {
|
||||
var parser = wiki.parseTiddler(template || title),
|
||||
variables = {currentTiddler: title};
|
||||
if(varName) {
|
||||
variables[varName] = varValue || "";
|
||||
}
|
||||
var widgetNode = wiki.makeWidget(parser,{variables: variables}),
|
||||
container = $tw.fakeDocument.createElement("div");
|
||||
widgetNode.render(container,null);
|
||||
var text = type === "text/html" ? container.innerHTML : container.textContent,
|
||||
filepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);
|
||||
if(self.commander.verbose) {
|
||||
console.log("Rendering \"" + title + "\" to \"" + filepath + "\"");
|
||||
}
|
||||
$tw.utils.createFileDirectories(filepath);
|
||||
fs.writeFileSync(filepath,text,"utf8");
|
||||
});
|
||||
return null;
|
||||
};
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
||||
@@ -34,12 +34,17 @@ Command.prototype.execute = function() {
|
||||
filename = path.resolve(this.commander.outputPath,this.params[1]),
|
||||
type = this.params[2] || "text/html",
|
||||
template = this.params[3],
|
||||
name = this.params[4],
|
||||
value = this.params[5],
|
||||
variables = {};
|
||||
$tw.utils.createFileDirectories(filename);
|
||||
if(template) {
|
||||
variables.currentTiddler = title;
|
||||
title = template;
|
||||
}
|
||||
if(name && value) {
|
||||
variables[name] = value;
|
||||
}
|
||||
fs.writeFile(filename,this.commander.wiki.renderTiddler(type,title,{variables: variables}),"utf8",function(err) {
|
||||
self.callback(err);
|
||||
});
|
||||
|
||||
53
core/modules/commands/save.js
Normal file
53
core/modules/commands/save.js
Normal file
@@ -0,0 +1,53 @@
|
||||
/*\
|
||||
title: $:/core/modules/commands/save.js
|
||||
type: application/javascript
|
||||
module-type: command
|
||||
|
||||
Saves individual tiddlers in their raw text or binary format to the specified files
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.info = {
|
||||
name: "save",
|
||||
synchronous: true
|
||||
};
|
||||
|
||||
var Command = function(params,commander,callback) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
if(this.params.length < 1) {
|
||||
return "Missing filename filter";
|
||||
}
|
||||
var self = this,
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
wiki = this.commander.wiki,
|
||||
tiddlerFilter = this.params[0],
|
||||
filenameFilter = this.params[1] || "[is[tiddler]]",
|
||||
tiddlers = wiki.filterTiddlers(tiddlerFilter);
|
||||
$tw.utils.each(tiddlers,function(title) {
|
||||
var tiddler = self.commander.wiki.getTiddler(title),
|
||||
type = tiddler.fields.type || "text/vnd.tiddlywiki",
|
||||
contentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: "utf8"},
|
||||
filepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);
|
||||
if(self.commander.verbose) {
|
||||
console.log("Saving \"" + title + "\" to \"" + filepath + "\"");
|
||||
}
|
||||
$tw.utils.createFileDirectories(filepath);
|
||||
fs.writeFileSync(filepath,tiddler.fields.text,contentTypeInfo.encoding);
|
||||
});
|
||||
return null;
|
||||
};
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
||||
@@ -58,7 +58,7 @@ SimpleServer.prototype.findMatchingRoute = function(request,state) {
|
||||
match;
|
||||
if(pathprefix) {
|
||||
if(pathname.substr(0,pathprefix.length) === pathprefix) {
|
||||
pathname = pathname.substr(pathprefix.length);
|
||||
pathname = pathname.substr(pathprefix.length) || "/";
|
||||
match = potentialRoute.path.exec(pathname);
|
||||
} else {
|
||||
match = false;
|
||||
@@ -91,57 +91,64 @@ SimpleServer.prototype.checkCredentials = function(request,incomingUsername,inco
|
||||
}
|
||||
};
|
||||
|
||||
SimpleServer.prototype.listen = function(port,host) {
|
||||
SimpleServer.prototype.requestHandler = function(request,response) {
|
||||
// Compose the state object
|
||||
var self = this;
|
||||
http.createServer(function(request,response) {
|
||||
// Compose the state object
|
||||
var state = {};
|
||||
state.wiki = self.wiki;
|
||||
state.server = self;
|
||||
state.urlInfo = url.parse(request.url);
|
||||
// Find the route that matches this path
|
||||
var route = self.findMatchingRoute(request,state);
|
||||
// Check for the username and password if we've got one
|
||||
var username = self.get("username"),
|
||||
password = self.get("password");
|
||||
if(username && password) {
|
||||
// Check they match
|
||||
if(self.checkCredentials(request,username,password) !== "ALLOWED") {
|
||||
var servername = state.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5";
|
||||
response.writeHead(401,"Authentication required",{
|
||||
"WWW-Authenticate": 'Basic realm="Please provide your username and password to login to ' + servername + '"'
|
||||
});
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Return a 404 if we didn't find a route
|
||||
if(!route) {
|
||||
response.writeHead(404);
|
||||
var state = {};
|
||||
state.wiki = self.wiki;
|
||||
state.server = self;
|
||||
state.urlInfo = url.parse(request.url);
|
||||
// Optionally output debug info
|
||||
if(self.get("debugLevel") !== "none") {
|
||||
console.log("Request path:",JSON.stringify(state.urlInfo));
|
||||
console.log("Request headers:",JSON.stringify(request.headers));
|
||||
}
|
||||
// Find the route that matches this path
|
||||
var route = self.findMatchingRoute(request,state);
|
||||
// Check for the username and password if we've got one
|
||||
var username = self.get("username"),
|
||||
password = self.get("password");
|
||||
if(username && password) {
|
||||
// Check they match
|
||||
if(self.checkCredentials(request,username,password) !== "ALLOWED") {
|
||||
var servername = state.wiki.getTiddlerText("$:/SiteTitle") || "TiddlyWiki5";
|
||||
response.writeHead(401,"Authentication required",{
|
||||
"WWW-Authenticate": 'Basic realm="Please provide your username and password to login to ' + servername + '"'
|
||||
});
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
// Set the encoding for the incoming request
|
||||
// TODO: Presumably this would need tweaking if we supported PUTting binary tiddlers
|
||||
request.setEncoding("utf8");
|
||||
// Dispatch the appropriate method
|
||||
switch(request.method) {
|
||||
case "GET": // Intentional fall-through
|
||||
case "DELETE":
|
||||
}
|
||||
// Return a 404 if we didn't find a route
|
||||
if(!route) {
|
||||
response.writeHead(404);
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
// Set the encoding for the incoming request
|
||||
// TODO: Presumably this would need tweaking if we supported PUTting binary tiddlers
|
||||
request.setEncoding("utf8");
|
||||
// Dispatch the appropriate method
|
||||
switch(request.method) {
|
||||
case "GET": // Intentional fall-through
|
||||
case "DELETE":
|
||||
route.handler(request,response,state);
|
||||
break;
|
||||
case "PUT":
|
||||
var data = "";
|
||||
request.on("data",function(chunk) {
|
||||
data += chunk.toString();
|
||||
});
|
||||
request.on("end",function() {
|
||||
state.data = data;
|
||||
route.handler(request,response,state);
|
||||
break;
|
||||
case "PUT":
|
||||
var data = "";
|
||||
request.on("data",function(chunk) {
|
||||
data += chunk.toString();
|
||||
});
|
||||
request.on("end",function() {
|
||||
state.data = data;
|
||||
route.handler(request,response,state);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}).listen(port,host);
|
||||
});
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
SimpleServer.prototype.listen = function(port,host) {
|
||||
return http.createServer(this.requestHandler.bind(this)).listen(port,host);
|
||||
};
|
||||
|
||||
var Command = function(params,commander,callback) {
|
||||
@@ -171,22 +178,28 @@ Command.prototype.execute = function() {
|
||||
username = this.params[4],
|
||||
password = this.params[5],
|
||||
host = this.params[6] || "127.0.0.1",
|
||||
pathprefix = this.params[7];
|
||||
pathprefix = this.params[7],
|
||||
debugLevel = this.params[8] || "none";
|
||||
if(parseInt(port,10).toString() !== port) {
|
||||
port = process.env[port] || 8080;
|
||||
}
|
||||
this.server.set({
|
||||
rootTiddler: rootTiddler,
|
||||
renderType: renderType,
|
||||
serveType: serveType,
|
||||
username: username,
|
||||
password: password,
|
||||
pathprefix: pathprefix
|
||||
pathprefix: pathprefix,
|
||||
debugLevel: debugLevel
|
||||
});
|
||||
this.server.listen(port,host);
|
||||
console.log("Serving on " + host + ":" + port);
|
||||
console.log("(press ctrl-C to exit)");
|
||||
var nodeServer = this.server.listen(port,host);
|
||||
$tw.utils.log("Serving on " + host + ":" + port,"brown/orange");
|
||||
$tw.utils.log("(press ctrl-C to exit)","red");
|
||||
// Warn if required plugins are missing
|
||||
if(!$tw.wiki.getTiddler("$:/plugins/tiddlywiki/tiddlyweb") || !$tw.wiki.getTiddler("$:/plugins/tiddlywiki/filesystem")) {
|
||||
$tw.utils.warning("Warning: Plugins required for client-server operation (\"tiddlywiki/filesystem\" and \"tiddlywiki/tiddlyweb\") are missing from tiddlywiki.info file");
|
||||
}
|
||||
$tw.hooks.invokeHook('th-server-command-post-start', this.server, nodeServer);
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
@@ -72,19 +72,28 @@ exports["application/x-tiddler-html-div"] = function(text,fields) {
|
||||
};
|
||||
|
||||
exports["application/json"] = function(text,fields) {
|
||||
var incoming = JSON.parse(text),
|
||||
var incoming,
|
||||
results = [];
|
||||
if($tw.utils.isArray(incoming)) {
|
||||
for(var t=0; t<incoming.length; t++) {
|
||||
var incomingFields = incoming[t],
|
||||
fields = {};
|
||||
for(var f in incomingFields) {
|
||||
if(typeof incomingFields[f] === "string") {
|
||||
fields[f] = incomingFields[f];
|
||||
}
|
||||
try {
|
||||
incoming = JSON.parse(text);
|
||||
} catch(e) {
|
||||
incoming = [{
|
||||
title: "JSON error: " + e,
|
||||
text: ""
|
||||
}]
|
||||
}
|
||||
if(!$tw.utils.isArray(incoming)) {
|
||||
incoming = [incoming];
|
||||
}
|
||||
for(var t=0; t<incoming.length; t++) {
|
||||
var incomingFields = incoming[t],
|
||||
fields = {};
|
||||
for(var f in incomingFields) {
|
||||
if(typeof incomingFields[f] === "string") {
|
||||
fields[f] = incomingFields[f];
|
||||
}
|
||||
results.push(fields);
|
||||
}
|
||||
results.push(fields);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
@@ -74,6 +74,7 @@ function FramedEngine(options) {
|
||||
this.copyStyles();
|
||||
// Add event listeners
|
||||
$tw.utils.addEventListeners(this.domNode,[
|
||||
{name: "click",handlerObject: this,handlerMethod: "handleClickEvent"},
|
||||
{name: "input",handlerObject: this,handlerMethod: "handleInputEvent"},
|
||||
{name: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"}
|
||||
]);
|
||||
@@ -147,6 +148,14 @@ FramedEngine.prototype.focus = function() {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Handle a click
|
||||
*/
|
||||
FramedEngine.prototype.handleClickEvent = function(event) {
|
||||
this.fixHeight();
|
||||
return true;
|
||||
};
|
||||
|
||||
/*
|
||||
Handle a dom "input" event which occurs when the text has changed
|
||||
*/
|
||||
|
||||
@@ -64,7 +64,7 @@ Set the text of the engine if it doesn't currently have focus
|
||||
*/
|
||||
SimpleEngine.prototype.setText = function(text,type) {
|
||||
if(!this.domNode.isTiddlyWikiFakeDom) {
|
||||
if(this.domNode.ownerDocument.activeElement !== this.domNode) {
|
||||
if(this.domNode.ownerDocument.activeElement !== this.domNode || text === "") {
|
||||
this.domNode.value = text;
|
||||
}
|
||||
// Fix the height if needed
|
||||
|
||||
@@ -198,7 +198,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
|
||||
this.makeChildWidgets();
|
||||
// Determine whether to show the toolbar
|
||||
this.editShowToolbar = this.wiki.getTiddlerText(ENABLE_TOOLBAR_TITLE,"yes");
|
||||
this.editShowToolbar = (this.editShowToolbar === "yes") && !!(this.children && this.children.length > 0);
|
||||
this.editShowToolbar = (this.editShowToolbar === "yes") && !!(this.children && this.children.length > 0) && (!this.document.isTiddlyWikiFakeDom);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
24
core/modules/editor/operations/bitmap/rotate-left.js
Normal file
24
core/modules/editor/operations/bitmap/rotate-left.js
Normal file
@@ -0,0 +1,24 @@
|
||||
/*\
|
||||
title: $:/core/modules/editor/operations/bitmap/rotate-left.js
|
||||
type: application/javascript
|
||||
module-type: bitmapeditoroperation
|
||||
|
||||
Bitmap editor operation to rotate the image left by 90 degrees
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports["rotate-left"] = function(event) {
|
||||
// Rotate the canvas left by 90 degrees
|
||||
this.rotateCanvasLeft();
|
||||
// Update the input controls
|
||||
this.refreshToolbar();
|
||||
// Save the image into the tiddler
|
||||
this.saveChanges();
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -20,7 +20,7 @@ Parses an operation (i.e. a run) within a filter string
|
||||
Returns the new start position, after the parsed operation
|
||||
*/
|
||||
function parseFilterOperation(operators,filterString,p) {
|
||||
var operator, operand, bracketPos, curlyBracketPos;
|
||||
var nextBracketPos, operator;
|
||||
// Skip the starting square bracket
|
||||
if(filterString.charAt(p++) !== "[") {
|
||||
throw "Missing [ in filter expression";
|
||||
@@ -33,14 +33,14 @@ function parseFilterOperation(operators,filterString,p) {
|
||||
operator.prefix = filterString.charAt(p++);
|
||||
}
|
||||
// Get the operator name
|
||||
var nextBracketPos = filterString.substring(p).search(/[\[\{<\/]/);
|
||||
nextBracketPos = filterString.substring(p).search(/[\[\{<\/]/);
|
||||
if(nextBracketPos === -1) {
|
||||
throw "Missing [ in filter expression";
|
||||
}
|
||||
nextBracketPos += p;
|
||||
var bracket = filterString.charAt(nextBracketPos);
|
||||
operator.operator = filterString.substring(p,nextBracketPos);
|
||||
|
||||
|
||||
// Any suffix?
|
||||
var colon = operator.operator.indexOf(':');
|
||||
if(colon > -1) {
|
||||
@@ -79,7 +79,7 @@ console.log("WARNING: Filter",operator.operator,"has a deprecated regexp operand
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(nextBracketPos === -1) {
|
||||
throw "Missing closing bracket in filter expression";
|
||||
}
|
||||
@@ -87,7 +87,7 @@ console.log("WARNING: Filter",operator.operator,"has a deprecated regexp operand
|
||||
operator.operand = filterString.substring(p,nextBracketPos);
|
||||
}
|
||||
p = nextBracketPos + 1;
|
||||
|
||||
|
||||
// Push this operator
|
||||
operators.push(operator);
|
||||
} while(filterString.charAt(p) !== "]");
|
||||
|
||||
22
core/modules/filters/all/tags.js
Normal file
22
core/modules/filters/all/tags.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/all/tags.js
|
||||
type: application/javascript
|
||||
module-type: allfilteroperator
|
||||
|
||||
Filter function for [all[tags]]
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.tags = function(source,prefix,options) {
|
||||
return Object.keys(options.wiki.getTagMap());
|
||||
};
|
||||
|
||||
})();
|
||||
26
core/modules/filters/count.js
Normal file
26
core/modules/filters/count.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/count.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator returning the number of entries in the current list.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.count = function(source,operator,options) {
|
||||
var count = 0;
|
||||
source(function(tiddler,title) {
|
||||
count++;
|
||||
});
|
||||
return [count + ""];
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -18,18 +18,34 @@ Export our filter function
|
||||
*/
|
||||
exports.each = function(source,operator,options) {
|
||||
var results =[] ,
|
||||
value,values = {},
|
||||
field = operator.operand || "title";
|
||||
if(operator.suffix !== "list-item") {
|
||||
value,values = {},
|
||||
field = operator.operand || "title";
|
||||
if(operator.suffix === "value" && field === "title") {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler) {
|
||||
value = (field === "title") ? title : tiddler.getFieldString(field);
|
||||
if(!$tw.utils.hop(values,value)) {
|
||||
values[value] = true;
|
||||
results.push(title);
|
||||
}
|
||||
if(!$tw.utils.hop(values,title)) {
|
||||
values[title] = true;
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else if(operator.suffix !== "list-item") {
|
||||
if(field === "title") {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler && !$tw.utils.hop(values,title)) {
|
||||
values[title] = true;
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler) {
|
||||
value = tiddler.getFieldString(field);
|
||||
if(!$tw.utils.hop(values,value)) {
|
||||
values[value] = true;
|
||||
results.push(title);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler) {
|
||||
|
||||
91
core/modules/filters/encodings.js
Normal file
91
core/modules/filters/encodings.js
Normal file
@@ -0,0 +1,91 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/decodeuricomponent.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator for applying decodeURIComponent() to each item.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter functions
|
||||
*/
|
||||
|
||||
exports.decodeuricomponent = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(decodeURIComponent(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.encodeuricomponent = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(encodeURIComponent(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.decodeuri = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(decodeURI(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.encodeuri = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(encodeURI(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.decodehtml = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push($tw.utils.htmlDecode(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.encodehtml = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push($tw.utils.htmlEncode(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.stringify = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push($tw.utils.stringify(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.jsonstringify = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push($tw.utils.jsonStringify(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.escaperegexp = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push($tw.utils.escapeRegExp(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
33
core/modules/filters/enlist.js
Normal file
33
core/modules/filters/enlist.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/enlist.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator returning its operand parsed as a list
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.enlist = function(source,operator,options) {
|
||||
var list = $tw.utils.parseStringArray(operator.operand);
|
||||
if(operator.prefix === "!") {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
if(list.indexOf(title) === -1) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
return results;
|
||||
} else {
|
||||
return list;
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -16,19 +16,37 @@ Filter operator for checking if a tiddler has the specified field
|
||||
Export our filter function
|
||||
*/
|
||||
exports.has = function(source,operator,options) {
|
||||
var results = [];
|
||||
if(operator.prefix === "!") {
|
||||
source(function(tiddler,title) {
|
||||
if(!tiddler || (tiddler && (!$tw.utils.hop(tiddler.fields,operator.operand) || tiddler.fields[operator.operand] === ""))) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
var results = [],
|
||||
invert = operator.prefix === "!";
|
||||
|
||||
if(operator.suffix === "field") {
|
||||
if(invert) {
|
||||
source(function(tiddler,title) {
|
||||
if(!tiddler || (tiddler && (!$tw.utils.hop(tiddler.fields,operator.operand)))) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand)) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && !(tiddler.fields[operator.operand] === "" || tiddler.fields[operator.operand].length === 0)) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
if(invert) {
|
||||
source(function(tiddler,title) {
|
||||
if(!tiddler || !$tw.utils.hop(tiddler.fields,operator.operand) || (tiddler.fields[operator.operand] === "")) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && !(tiddler.fields[operator.operand] === "" || tiddler.fields[operator.operand].length === 0)) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
41
core/modules/filters/insertbefore.js
Normal file
41
core/modules/filters/insertbefore.js
Normal file
@@ -0,0 +1,41 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/insertbefore.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Insert an item before another item in a list
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Order a list
|
||||
*/
|
||||
exports.insertbefore = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
});
|
||||
var target = options.widget && options.widget.getVariable(operator.suffix || "currentTiddler");
|
||||
if(target !== operator.operand) {
|
||||
// Remove the entry from the list if it is present
|
||||
var pos = results.indexOf(operator.operand);
|
||||
if(pos !== -1) {
|
||||
results.splice(pos,1);
|
||||
}
|
||||
// Insert the entry before the target marker
|
||||
pos = results.indexOf(target);
|
||||
if(pos !== -1) {
|
||||
results.splice(pos,0,operator.operand);
|
||||
} else {
|
||||
results.push(operator.operand);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -28,12 +28,21 @@ Export our filter function
|
||||
exports.is = function(source,operator,options) {
|
||||
// Dispatch to the correct isfilteroperator
|
||||
var isFilterOperators = getIsFilterOperators();
|
||||
var isFilterOperator = isFilterOperators[operator.operand];
|
||||
if(isFilterOperator) {
|
||||
return isFilterOperator(source,operator.prefix,options);
|
||||
if(operator.operand) {
|
||||
var isFilterOperator = isFilterOperators[operator.operand];
|
||||
if(isFilterOperator) {
|
||||
return isFilterOperator(source,operator.prefix,options);
|
||||
} else {
|
||||
return [$tw.language.getString("Error/IsFilterOperator")];
|
||||
}
|
||||
} else {
|
||||
return [$tw.language.getString("Error/IsFilterOperator")];
|
||||
// Return all tiddlers if the operand is missing
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
});
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
})();
|
||||
@@ -12,6 +12,23 @@ Filter operators for manipulating the current selection list
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Order a list
|
||||
*/
|
||||
exports.order = function(source,operator,options) {
|
||||
var results = [];
|
||||
if(operator.operand.toLowerCase() === "reverse") {
|
||||
source(function(tiddler,title) {
|
||||
results.unshift(title);
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
/*
|
||||
Reverse list
|
||||
*/
|
||||
@@ -27,7 +44,7 @@ exports.reverse = function(source,operator,options) {
|
||||
First entry/entries in list
|
||||
*/
|
||||
exports.first = function(source,operator,options) {
|
||||
var count = parseInt(operator.operand) || 1,
|
||||
var count = $tw.utils.getInt(operator.operand,1),
|
||||
results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
@@ -39,7 +56,7 @@ exports.first = function(source,operator,options) {
|
||||
Last entry/entries in list
|
||||
*/
|
||||
exports.last = function(source,operator,options) {
|
||||
var count = parseInt(operator.operand) || 1,
|
||||
var count = $tw.utils.getInt(operator.operand,1),
|
||||
results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
@@ -51,7 +68,7 @@ exports.last = function(source,operator,options) {
|
||||
All but the first entry/entries of the list
|
||||
*/
|
||||
exports.rest = function(source,operator,options) {
|
||||
var count = parseInt(operator.operand) || 1,
|
||||
var count = $tw.utils.getInt(operator.operand,1),
|
||||
results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
@@ -65,7 +82,7 @@ exports.bf = exports.rest;
|
||||
All but the last entry/entries of the list
|
||||
*/
|
||||
exports.butlast = function(source,operator,options) {
|
||||
var count = parseInt(operator.operand) || 1,
|
||||
var count = $tw.utils.getInt(operator.operand,1),
|
||||
results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
@@ -78,7 +95,7 @@ exports.bl = exports.butlast;
|
||||
The nth member of the list
|
||||
*/
|
||||
exports.nth = function(source,operator,options) {
|
||||
var count = parseInt(operator.operand) || 1,
|
||||
var count = $tw.utils.getInt(operator.operand,1),
|
||||
results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(title);
|
||||
|
||||
30
core/modules/filters/lookup.js
Normal file
30
core/modules/filters/lookup.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/lookup.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator that looks up values via a title prefix
|
||||
|
||||
[lookup:<field>[<prefix>]]
|
||||
|
||||
Prepends the prefix to the selected items and returns the specified field value
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.lookup = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(options.wiki.getTiddlerText(operator.operand + title) || options.wiki.getTiddlerText(operator.operand + operator.suffix));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
29
core/modules/filters/minlength.js
Normal file
29
core/modules/filters/minlength.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/minlength.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator for filtering out titles that don't meet the minimum length in the operand
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.minlength = function(source,operator,options) {
|
||||
var results = [],
|
||||
minLength = parseInt(operator.operand || "",10) || 0;
|
||||
source(function(tiddler,title) {
|
||||
if(title.length >= minLength) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -20,12 +20,9 @@ exports.sameday = function(source,operator,options) {
|
||||
fieldName = operator.suffix || "modified",
|
||||
targetDate = (new Date($tw.utils.parseDate(operator.operand))).setHours(0,0,0,0);
|
||||
// Function to convert a date/time to a date integer
|
||||
var isSameDay = function(dateField) {
|
||||
return (new Date(dateField)).setHours(0,0,0,0) === targetDate;
|
||||
};
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler && tiddler.fields[fieldName]) {
|
||||
if(isSameDay($tw.utils.parseDate(tiddler.fields[fieldName]))) {
|
||||
if(tiddler) {
|
||||
if(tiddler.getFieldDay(fieldName) === targetDate) {
|
||||
results.push(title);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,12 @@ exports.nsort = function(source,operator,options) {
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.sortan = function(source, operator, options) {
|
||||
var results = prepare_results(source);
|
||||
options.wiki.sortTiddlers(results, operator.operand || "title", operator.prefix === "!",false,false,true);
|
||||
return results;
|
||||
};
|
||||
|
||||
exports.sortcs = function(source,operator,options) {
|
||||
var results = prepare_results(source);
|
||||
options.wiki.sortTiddlers(results,operator.operand || "title",operator.prefix === "!",true,false);
|
||||
|
||||
31
core/modules/filters/subtiddlerfields.js
Normal file
31
core/modules/filters/subtiddlerfields.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/subtiddlerfields.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator for returning the names of the fields on the selected subtiddlers of the plugin named in the operand
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.subtiddlerfields = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
var subtiddler = options.wiki.getSubTiddler(operator.operand,title);
|
||||
if(subtiddler) {
|
||||
for(var fieldName in subtiddler.fields) {
|
||||
$tw.utils.pushTop(results,fieldName);
|
||||
}
|
||||
}
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -17,19 +17,31 @@ Export our filter function
|
||||
*/
|
||||
exports.tag = function(source,operator,options) {
|
||||
var results = [];
|
||||
if(operator.prefix === "!") {
|
||||
if((operator.suffix || "").toLowerCase() === "strict" && !operator.operand) {
|
||||
// New semantics:
|
||||
// Always return copy of input if operator.operand is missing
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler && !tiddler.hasTag(operator.operand)) {
|
||||
results.push(title);
|
||||
}
|
||||
results.push(title);
|
||||
});
|
||||
} else {
|
||||
source(function(tiddler,title) {
|
||||
if(tiddler && tiddler.hasTag(operator.operand)) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
results = options.wiki.sortByList(results,operator.operand);
|
||||
// Old semantics:
|
||||
var tiddlers = options.wiki.getTiddlersWithTag(operator.operand);
|
||||
if(operator.prefix === "!") {
|
||||
// Returns a copy of the input if operator.operand is missing
|
||||
source(function(tiddler,title) {
|
||||
if(tiddlers.indexOf(title) === -1) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Returns empty results if operator.operand is missing
|
||||
source(function(tiddler,title) {
|
||||
if(tiddlers.indexOf(title) !== -1) {
|
||||
results.push(title);
|
||||
}
|
||||
});
|
||||
results = options.wiki.sortByList(results,operator.operand);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
@@ -16,10 +16,11 @@ Filter operator for returning the names of the wiki parser rules in this wiki
|
||||
Export our filter function
|
||||
*/
|
||||
exports.wikiparserrules = function(source,operator,options) {
|
||||
var results = [];
|
||||
var results = [],
|
||||
operand = operator.operand;
|
||||
$tw.utils.each($tw.modules.types.wikirule,function(mod) {
|
||||
var exp = mod.exports;
|
||||
if(exp.types[operator.operand]) {
|
||||
if(!operand || exp.types[operand]) {
|
||||
results.push(exp.name);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@ Extended filter operators to manipulate the current list.
|
||||
exports.putbefore = function (source, operator) {
|
||||
var results = prepare_results(source),
|
||||
index = results.indexOf(operator.operand),
|
||||
count = parseInt(operator.suffix) || 1;
|
||||
count = $tw.utils.getInt(operator.suffix,1);
|
||||
return (index === -1) ?
|
||||
results.slice(0, -1) :
|
||||
results.slice(0, index).concat(results.slice(-count)).concat(results.slice(index, -count));
|
||||
@@ -41,7 +41,7 @@ Extended filter operators to manipulate the current list.
|
||||
exports.putafter = function (source, operator) {
|
||||
var results = prepare_results(source),
|
||||
index = results.indexOf(operator.operand),
|
||||
count = parseInt(operator.suffix) || 1;
|
||||
count = $tw.utils.getInt(operator.suffix,1);
|
||||
return (index === -1) ?
|
||||
results.slice(0, -1) :
|
||||
results.slice(0, index + 1).concat(results.slice(-count)).concat(results.slice(index + 1, -count));
|
||||
@@ -53,7 +53,7 @@ Extended filter operators to manipulate the current list.
|
||||
exports.replace = function (source, operator) {
|
||||
var results = prepare_results(source),
|
||||
index = results.indexOf(operator.operand),
|
||||
count = parseInt(operator.suffix) || 1;
|
||||
count = $tw.utils.getInt(operator.suffix,1);
|
||||
return (index === -1) ?
|
||||
results.slice(0, -count) :
|
||||
results.slice(0, index).concat(results.slice(-count)).concat(results.slice(index + 1, -count));
|
||||
@@ -64,7 +64,7 @@ Extended filter operators to manipulate the current list.
|
||||
*/
|
||||
exports.putfirst = function (source, operator) {
|
||||
var results = prepare_results(source),
|
||||
count = parseInt(operator.suffix) || 1;
|
||||
count = $tw.utils.getInt(operator.suffix,1);
|
||||
return results.slice(-count).concat(results.slice(0, -count));
|
||||
};
|
||||
|
||||
@@ -73,7 +73,7 @@ Extended filter operators to manipulate the current list.
|
||||
*/
|
||||
exports.putlast = function (source, operator) {
|
||||
var results = prepare_results(source),
|
||||
count = parseInt(operator.suffix) || 1;
|
||||
count = $tw.utils.getInt(operator.suffix,1);
|
||||
return results.slice(count).concat(results.slice(0, count));
|
||||
};
|
||||
|
||||
@@ -83,9 +83,10 @@ Extended filter operators to manipulate the current list.
|
||||
exports.move = function (source, operator) {
|
||||
var results = prepare_results(source),
|
||||
index = results.indexOf(operator.operand),
|
||||
count = parseInt(operator.suffix) || 1,
|
||||
marker = results.splice(index, 1);
|
||||
return results.slice(0, index + count).concat(marker).concat(results.slice(index + count));
|
||||
count = $tw.utils.getInt(operator.suffix,1),
|
||||
marker = results.splice(index, 1),
|
||||
offset = (index + count) > 0 ? index + count : 0;
|
||||
return results.slice(0, offset).concat(marker).concat(results.slice(offset));
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -105,7 +106,7 @@ Extended filter operators to manipulate the current list.
|
||||
exports.allbefore = function (source, operator) {
|
||||
var results = prepare_results(source),
|
||||
index = results.indexOf(operator.operand);
|
||||
return (index <= 0) ? [] :
|
||||
return (index < 0) ? [] :
|
||||
(operator.suffix) ? results.slice(0, index + 1) :
|
||||
results.slice(0, index);
|
||||
};
|
||||
@@ -128,7 +129,7 @@ Extended filter operators to manipulate the current list.
|
||||
exports.prepend = function (source, operator) {
|
||||
var prepend = $tw.utils.parseStringArray(operator.operand, "true"),
|
||||
results = prepare_results(source),
|
||||
count = parseInt(operator.suffix) || prepend.length;
|
||||
count = $tw.utils.getInt(operator.suffix,prepend.length);
|
||||
return (prepend.length === 0) ? results :
|
||||
(operator.prefix) ? prepend.slice(-count).concat(results) :
|
||||
prepend.slice(0, count).concat(results);
|
||||
|
||||
@@ -18,6 +18,24 @@ exports.getInfoTiddlerFields = function() {
|
||||
// Basics
|
||||
infoTiddlerFields.push({title: "$:/info/browser", text: mapBoolean(!!$tw.browser)});
|
||||
infoTiddlerFields.push({title: "$:/info/node", text: mapBoolean(!!$tw.node)});
|
||||
if($tw.browser) {
|
||||
// Document location
|
||||
var setLocationProperty = function(name,value) {
|
||||
infoTiddlerFields.push({title: "$:/info/url/" + name, text: value});
|
||||
},
|
||||
location = document.location;
|
||||
setLocationProperty("full", (location.toString()).split("#")[0]);
|
||||
setLocationProperty("host", location.host);
|
||||
setLocationProperty("hostname", location.hostname);
|
||||
setLocationProperty("protocol", location.protocol);
|
||||
setLocationProperty("port", location.port);
|
||||
setLocationProperty("pathname", location.pathname);
|
||||
setLocationProperty("search", location.search);
|
||||
setLocationProperty("origin", location.origin);
|
||||
// Screen size
|
||||
infoTiddlerFields.push({title: "$:/info/browser/screen/width", text: window.screen.width.toString()});
|
||||
infoTiddlerFields.push({title: "$:/info/browser/screen/height", text: window.screen.height.toString()});
|
||||
}
|
||||
return infoTiddlerFields;
|
||||
};
|
||||
|
||||
|
||||
40
core/modules/macros/jsontiddler.js
Normal file
40
core/modules/macros/jsontiddler.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/*\
|
||||
title: $:/core/modules/macros/jsontiddler.js
|
||||
type: application/javascript
|
||||
module-type: macro
|
||||
|
||||
Macro to output a single tiddler to JSON
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Information about this macro
|
||||
*/
|
||||
|
||||
exports.name = "jsontiddler";
|
||||
|
||||
exports.params = [
|
||||
{name: "title"}
|
||||
];
|
||||
|
||||
/*
|
||||
Run the macro
|
||||
*/
|
||||
exports.run = function(title) {
|
||||
title = title || this.getVariable("currentTiddler");
|
||||
var tiddler = !!title && this.wiki.getTiddler(title),
|
||||
fields = new Object();
|
||||
if(tiddler) {
|
||||
for(var field in tiddler.fields) {
|
||||
fields[field] = tiddler.getFieldString(field);
|
||||
}
|
||||
}
|
||||
return JSON.stringify(fields,null,$tw.config.preferences.jsonSpaces);
|
||||
};
|
||||
|
||||
})();
|
||||
29
core/modules/parsers/binaryparser.js
Normal file
29
core/modules/parsers/binaryparser.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/*\
|
||||
title: $:/core/modules/parsers/binaryparser.js
|
||||
type: application/javascript
|
||||
module-type: parser
|
||||
|
||||
The video parser parses a video tiddler into an embeddable HTML element
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var BINARY_WARNING_MESSAGE = "$:/core/ui/BinaryWarning";
|
||||
|
||||
var BinaryParser = function(type,text,options) {
|
||||
this.tree = [{
|
||||
type: "transclude",
|
||||
attributes: {
|
||||
tiddler: {type: "string", value: BINARY_WARNING_MESSAGE}
|
||||
}
|
||||
}];
|
||||
};
|
||||
|
||||
exports["application/octet-stream"] = BinaryParser;
|
||||
|
||||
})();
|
||||
|
||||
@@ -17,18 +17,11 @@ var ImageParser = function(type,text,options) {
|
||||
type: "element",
|
||||
tag: "img",
|
||||
attributes: {}
|
||||
},
|
||||
src;
|
||||
};
|
||||
if(options._canonical_uri) {
|
||||
element.attributes.src = {type: "string", value: options._canonical_uri};
|
||||
if(type === "application/pdf" || type === ".pdf") {
|
||||
element.tag = "embed";
|
||||
}
|
||||
} else if(text) {
|
||||
if(type === "application/pdf" || type === ".pdf") {
|
||||
element.attributes.src = {type: "string", value: "data:application/pdf;base64," + text};
|
||||
element.tag = "embed";
|
||||
} else if(type === "image/svg+xml" || type === ".svg") {
|
||||
if(type === "image/svg+xml" || type === ".svg") {
|
||||
element.attributes.src = {type: "string", value: "data:image/svg+xml," + encodeURIComponent(text)};
|
||||
} else {
|
||||
element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
|
||||
@@ -42,7 +35,6 @@ exports["image/jpg"] = ImageParser;
|
||||
exports["image/jpeg"] = ImageParser;
|
||||
exports["image/png"] = ImageParser;
|
||||
exports["image/gif"] = ImageParser;
|
||||
exports["application/pdf"] = ImageParser;
|
||||
exports["image/x-icon"] = ImageParser;
|
||||
|
||||
})();
|
||||
|
||||
@@ -218,6 +218,7 @@ exports.parseAttribute = function(source,pos) {
|
||||
// Define our regexps
|
||||
var reAttributeName = /([^\/\s>"'=]+)/g,
|
||||
reUnquotedAttribute = /([^\/\s<>"'=]+)/g,
|
||||
reFilteredValue = /\{\{\{(.+?)\}\}\}/g,
|
||||
reIndirectValue = /\{\{([^\}]+)\}\}/g;
|
||||
// Skip whitespace
|
||||
pos = $tw.utils.skipWhiteSpace(source,pos);
|
||||
@@ -243,29 +244,37 @@ exports.parseAttribute = function(source,pos) {
|
||||
node.type = "string";
|
||||
node.value = stringLiteral.value;
|
||||
} else {
|
||||
// Look for an indirect value
|
||||
var indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);
|
||||
if(indirectValue) {
|
||||
pos = indirectValue.end;
|
||||
node.type = "indirect";
|
||||
node.textReference = indirectValue.match[1];
|
||||
// Look for a filtered value
|
||||
var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);
|
||||
if(filteredValue) {
|
||||
pos = filteredValue.end;
|
||||
node.type = "filtered";
|
||||
node.filter = filteredValue.match[1];
|
||||
} else {
|
||||
// Look for a unquoted value
|
||||
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
|
||||
if(unquotedValue) {
|
||||
pos = unquotedValue.end;
|
||||
node.type = "string";
|
||||
node.value = unquotedValue.match[1];
|
||||
// Look for an indirect value
|
||||
var indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);
|
||||
if(indirectValue) {
|
||||
pos = indirectValue.end;
|
||||
node.type = "indirect";
|
||||
node.textReference = indirectValue.match[1];
|
||||
} else {
|
||||
// Look for a macro invocation value
|
||||
var macroInvocation = $tw.utils.parseMacroInvocation(source,pos);
|
||||
if(macroInvocation) {
|
||||
pos = macroInvocation.end;
|
||||
node.type = "macro";
|
||||
node.value = macroInvocation;
|
||||
} else {
|
||||
// Look for a unquoted value
|
||||
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
|
||||
if(unquotedValue) {
|
||||
pos = unquotedValue.end;
|
||||
node.type = "string";
|
||||
node.value = "true";
|
||||
node.value = unquotedValue.match[1];
|
||||
} else {
|
||||
// Look for a macro invocation value
|
||||
var macroInvocation = $tw.utils.parseMacroInvocation(source,pos);
|
||||
if(macroInvocation) {
|
||||
pos = macroInvocation.end;
|
||||
node.type = "macro";
|
||||
node.value = macroInvocation;
|
||||
} else {
|
||||
node.type = "string";
|
||||
node.value = "true";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
33
core/modules/parsers/pdfparser.js
Normal file
33
core/modules/parsers/pdfparser.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/*\
|
||||
title: $:/core/modules/parsers/pdfparser.js
|
||||
type: application/javascript
|
||||
module-type: parser
|
||||
|
||||
The PDF parser embeds a PDF viewer
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var ImageParser = function(type,text,options) {
|
||||
var element = {
|
||||
type: "element",
|
||||
tag: "embed",
|
||||
attributes: {}
|
||||
},
|
||||
src;
|
||||
if(options._canonical_uri) {
|
||||
element.attributes.src = {type: "string", value: options._canonical_uri};
|
||||
} else if(text) {
|
||||
element.attributes.src = {type: "string", value: "data:application/pdf;base64," + text};
|
||||
}
|
||||
this.tree = [element];
|
||||
};
|
||||
|
||||
exports["application/pdf"] = ImageParser;
|
||||
|
||||
})();
|
||||
|
||||
@@ -12,7 +12,7 @@ The video parser parses a video tiddler into an embeddable HTML element
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var AudioParser = function(type,text,options) {
|
||||
var VideoParser = function(type,text,options) {
|
||||
var element = {
|
||||
type: "element",
|
||||
tag: "video",
|
||||
@@ -29,7 +29,8 @@ var AudioParser = function(type,text,options) {
|
||||
this.tree = [element];
|
||||
};
|
||||
|
||||
exports["video/mp4"] = AudioParser;
|
||||
exports["video/mp4"] = VideoParser;
|
||||
exports["video/quicktime"] = VideoParser;
|
||||
|
||||
})();
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ module-type: wikirule
|
||||
Wiki text inline rule for external links. For example:
|
||||
|
||||
```
|
||||
An external link: http://www.tiddlywiki.com/
|
||||
An external link: https://www.tiddlywiki.com/
|
||||
|
||||
A suppressed external link: ~http://www.tiddlyspace.com/
|
||||
```
|
||||
|
||||
@@ -97,10 +97,17 @@ exports.parseTag = function(source,pos,options) {
|
||||
return null;
|
||||
}
|
||||
node.tag = token.match[1];
|
||||
if(node.tag.slice(1).indexOf("$") !== -1) {
|
||||
return null;
|
||||
}
|
||||
if(node.tag.charAt(0) === "$") {
|
||||
node.type = node.tag.substr(1);
|
||||
}
|
||||
pos = token.end;
|
||||
// Check that the tag is terminated by a space, / or >
|
||||
if(!$tw.utils.parseWhiteSpace(source,pos) && !(source.charAt(pos) === "/") && !(source.charAt(pos) === ">") ) {
|
||||
return null;
|
||||
}
|
||||
// Process attributes
|
||||
var attribute = $tw.utils.parseAttribute(source,pos);
|
||||
while(attribute) {
|
||||
|
||||
@@ -6,10 +6,10 @@ module-type: wikirule
|
||||
Wiki text inline rule for embedding images. For example:
|
||||
|
||||
```
|
||||
[img[http://tiddlywiki.com/fractalveg.jpg]]
|
||||
[img width=23 height=24 [http://tiddlywiki.com/fractalveg.jpg]]
|
||||
[img width={{!!width}} height={{!!height}} [http://tiddlywiki.com/fractalveg.jpg]]
|
||||
[img[Description of image|http://tiddlywiki.com/fractalveg.jpg]]
|
||||
[img[https://tiddlywiki.com/fractalveg.jpg]]
|
||||
[img width=23 height=24 [https://tiddlywiki.com/fractalveg.jpg]]
|
||||
[img width={{!!width}} height={{!!height}} [https://tiddlywiki.com/fractalveg.jpg]]
|
||||
[img[Description of image|https://tiddlywiki.com/fractalveg.jpg]]
|
||||
[img[TiddlerTitle]]
|
||||
[img[Description of image|TiddlerTitle]]
|
||||
```
|
||||
|
||||
@@ -61,7 +61,7 @@ exports.parse = function() {
|
||||
reEnd = /(\r?\n\\end[^\S\n\r]*(?:$|\r?\n))/mg;
|
||||
} else {
|
||||
// Otherwise, the end of the definition is marked by the end of the line
|
||||
reEnd = /(\r?\n)/mg;
|
||||
reEnd = /($|\r?\n)/mg;
|
||||
// Move past any whitespace
|
||||
this.parser.pos = $tw.utils.skipWhiteSpace(this.parser.source,this.parser.pos);
|
||||
}
|
||||
@@ -84,7 +84,8 @@ exports.parse = function() {
|
||||
value: {type: "string", value: text}
|
||||
},
|
||||
children: [],
|
||||
params: params
|
||||
params: params,
|
||||
isMacroDefinition: true
|
||||
}];
|
||||
};
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ module-type: wikirule
|
||||
Wiki text inline rule for external links. For example:
|
||||
|
||||
```
|
||||
[ext[http://tiddlywiki.com/fractalveg.jpg]]
|
||||
[ext[Tooltip|http://tiddlywiki.com/fractalveg.jpg]]
|
||||
[ext[https://tiddlywiki.com/fractalveg.jpg]]
|
||||
[ext[Tooltip|https://tiddlywiki.com/fractalveg.jpg]]
|
||||
```
|
||||
|
||||
\*/
|
||||
|
||||
@@ -18,7 +18,12 @@ exports.types = {inline: true};
|
||||
exports.init = function(parser) {
|
||||
this.parser = parser;
|
||||
// Regexp to match
|
||||
this.matchRegExp = /~?\$:\/[a-zA-Z0-9/.\-_]+/mg;
|
||||
this.matchRegExp = new RegExp(
|
||||
"~?\\$:\\/[" +
|
||||
$tw.config.textPrimitives.anyLetter.substr(1,$tw.config.textPrimitives.anyLetter.length - 2) +
|
||||
"\/._-]+",
|
||||
"mg"
|
||||
);
|
||||
};
|
||||
|
||||
exports.parse = function() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user