Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
Cryptomx@P8yKK1jNIP1MpC3aSzBc91_ybdPTJEu1EbwsE6nJ45PjRz73WB"FVoYJ1Ws_
wHGt9uLy5B4ZZMR9k"OO9iL4CWKxz6V4bUA4p2KOFCY9Tg"yVRQzF3Nul0Z1
jhECC8D2j6CjFWwEk_jSkUFX5sgOMcuA_CEE8N9XQLRIFB_e6Lhw"3KIaR1b
OZ"g_GJXV2ELhcTVSgqI25i0mEBAFMYXP8"lbvan0lLlkTUJy9M59IO_tcOs
KvM93mG1ljyeNMlkJs"mXOfJYTQsAGs6lp5WcOjo"BPFiLZ6KaWlos1A3DON
DeLsiwUIx"E9kqWH"TzV9H4CrcsCRuaAePJujkUJNdBR0mVw4DKZKwZRXpZ0
VDodIa4EdfT7zYd4Oupe28xaIj"Irb8fRFQOIFZZURE5ei8I"xf6FpSow2qk
4S4l8418g3uS7V3FEtBbE_QoeNctEm5LdbRWWgbdFFdmDsCH1sv61oUP6ymQ
0tR"eQgP2tXbwAQDpPoOhoSWAqXdtkguhV6AS3zlm46MLMHrTbnWGQEYSsIa
5v69TiguRJYECSR9WfojNPeYUIyJohzYVAOZrmFtcTf_1YktOiOU1XA2Zc9y
SF1dOqj_h6xeWGv50LDGSsYYBqTrD"bluFJ_nKwyPo91E16YliDmHrXO3JTx
YHxfi"3xciIieatJ6rcY1tmWf7VD9sd_uVX52urvm1UdBKGf2vAT4Od61nYY
"ORfzY0uxDnoTtF6hGcte279g""vaiRHHN6hweOP1lsAWDoesShonpp8W64y
SgWwvKPWQcQShyt6fguN3rddH7Ee"xu0e42VjvcSonPOoUZSV8C7rk_okME"
HuSlHPPxCX0_jFambpvPxhQLt8p"TTkbx1eSMQ"LYTYNpI0Mg1Zm0Se3EISJ
KtPY0f_KjKGAxh3ZVM7jf9xxdJxAmMCXBzsBnsEQYyVTOykQh1CkQsjWTFF1
T5_f20sALNLhw6ZMJfh1hDlYlhNQGiipoa6VsG0lnyC2JQVKt7792Zo8yeFv
Vwi2qBo5_A8GLE95SN1hhZ1OFxRVJhI7XE8xxKEiPF8W5ZBLZ9cDlEeUD1ct
r94OLAYING2UHy6nYjBaIEl0Et6fzbFA9ZCCP_zpNggHqt6YvPmSwRYRKAT0
gJWXkwr"v0vO4Tq3GRS7LDIEXyfcoh0L1AOKLOiMD"uFmZaVr0ILzqx55BGx
J6DYmGel1RM1YjEQG0_nTt0drZBxt3d8A"7xuRjBZiumhMBG3jlxJ8Yk8f35
jd3mhGC_v6Gu7GdvWkirCbUdW3i5GY9veGc6HATdsFSc0bNY70"hhNrrAfDm
MV5MwP_e2lSabXHbZTDj2vUHJE6l"tQq62Tgn99ftmP6kySJqjW7GIBCegB7
o6uK514sM2HNUbUWvBslERoResiooueWtXlKn"YZ
/***
|''Name:''|EncryptedVaultPlugin|
|''Description:''|Adds RC4 encryption and password protection to tiddywiki.|
|''Version:''|1.0.1|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.2.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Description
*Create an ''encrypted vault'' where all tiddlers are ''password protected''.
*By default, only the system tiddlers aren't encrypted.
*Even shadow tiddlers (MainMenu, SiteTitle, PageTemplate, StyleSheet, ...) ''can be encrypted''. The shadow version is used until unlocking.
!Demo
Use <<unlock>> button on a protected wiki. By example : http://visualtw.ouvaton.org/demo/EncryptedVaultPlugin.html
!Installation
#Import the plugin (tagged as systemConfig)
#Save and reload
#Save once more time to create the encrypted vault
#Reload and set a password
!Usage
*Use <<unlock>><<setPassword>> button (available by default in SideBarOptions)
*Use a blank password to save unencrypted (disable vault usage)
*Use {{{unencrypted}}} tag to avoid encryption for some tiddler
*Use {{{forceEncryption}}} tag to force some shadow tiddler to be encrypted
!Configuration
The following macros are available :
*{{{<<unlock ButtonTitle ButtonTooltip OpenTiddlersWhenUnlock CloseTiddlersWhenUnlock>>}}} creates a button to unlock the encrypted vault (all parameters are optionnal)
*{{{<<setPassword ButtonTitle ButtonTooltip>>}}} if unlocked, creates a button to set the current password (all parameters are optionnal)
*{{{<<purge ButtonTitle ButtonTooltip>>}}} if locked, creates a button to purge a locked vault, useful for lost password (encrypted content is the deleted)
*{{{<<ifLocked tiddlyText>>}}} displays tiddlyText (wikified) if the vault is locked
*{{{<<ifUnlocked tiddlyText>>}}} displays tiddlyText (wikified) if the vault is unlocked
<<ifLocked "!!!!Lost password ?">><<ifLocked "Click on">> <<purge>><<ifLocked "to delete any content locked in the encrypted vault.">>
***/
//{{{
config.messages.vaultCreationInfo = "The encrypted vault has been created";
config.messages.purgeConfirm = "Purge the encrypted vault ?\n\nAll unlocked content will be lost.";
config.messages.vaultPurgedInfo = "All contents have been purged from encrypted vault.\nPassword has been blanked.\nYou must save once to apply this changes.";
config.messages.vaultEncryptedInfo = "Saving with encryption";
config.messages.vaultUnchangedInfo = "No changes in Encrypted vault";
config.messages.noLockedVaultWarning = "Unable to proceed. No locked encrypted vault.";
config.messages.emptyVaultInfo = "Saving without encryption";
config.messages.saveWithLockedVaultConfirm = "Encrypted vault is locked. No changes will apply inside.\n\nAre you sure ?";
config.messages.confirmOverload = "This following tiddler already exists in system store. Overload ?\nOK : the encrypted version will replace the system store version\nCancel : the system store version will replace the encrypted version";
SaverBase.systemStore="unencrypted";
SaverBase.vault="forceEncryption";
var startSaveVaultArea = '<div id="' + 'vaultArea">'; // Split up into two so that indexOf() of this source doesn't find it
var endSaveVaultArea = '</d' + 'iv>';
config.shadowTiddlers.SideBarOptions = config.shadowTiddlers.SideBarOptions.replace(/<<saveChanges>>/,"<<unlock>><<setPassword>><<saveChanges>>");
config.shadowTiddlers.GettingStarted+="\n\n<<ifLocked 'This TiddlyWiki use EncryptedVaultPlugin. To load protected content click on'>><<unlock>><<ifUnlocked 'This TiddlyWiki use EncryptedVaultPlugin. To set or change password click on'>><<setPassword>>"
window.updateOriginal= function(original,posDiv) // overriding the TW2.2 standard function
{
var vaultIsUpdatable = (!locateVaultArea(original) || !vault.isLocked() || vault.purge); // vault is new, unlocked or must be purged
if(!posDiv)
posDiv = locateStoreArea(original);
if(!posDiv) {
alert(config.messages.invalidFileError.format([localPath]));
return null;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
convertUnicodeToUTF8((vaultIsUpdatable && vault.password) ? store.allUnencryptedTiddlersAsHtml() : store.allTiddlersAsHtml()) + "\n" +
original.substr(posDiv[1]);
if (vaultIsUpdatable) {
posVault = locateVaultArea(original)
if(!posVault) {
revised=createVault(revised);
posVault = locateVaultArea(revised);
if(!posVault) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
}
var revised = revised.substr(0,posVault[0] + startSaveVaultArea.length) +
convertUnicodeToUTF8(vault.password ? vault.encrypt(store.allEncryptedTiddlersAsHtml()) : "") +
revised.substr(posVault[1]);
if (vault.password) displayMessage(config.messages.vaultEncryptedInfo);
else displayMessage(config.messages.emptyVaultInfo);
}
else displayMessage(config.messages.vaultUnchangedInfo);
var newSiteTitle = convertUnicodeToUTF8(getPageTitle()).htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateLanguageAttribute(revised);
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
}
function createVault(original) {
var revised=original.replace(/<!--POST-SHADOWAREA-->/,'<!--POST-SHADOWAREA-->\n<div id="vaultArea"></div>\n<!--POST-VAULTAREA-->');
var vaultStyles = '<!--PRE-VAULTSTYLE-START-->\n<style type="text/css">\n#vaultArea {display:none;}\n#vaultArea div {padding:0.5em; margin:1em 0em 0em 0em; border-color:#fff #666 #444 #ddd; border-style:solid; border-width:2px; overflow:auto;}\n</style>\n<!--PRE-VAULTSTYLE-END-->\n';
if (revised.search("<!--PRE-VAULTSTYLE-START-->")<0) var revised=revised.replace(/<!--POST-HEAD-START-->/,vaultStyles +'<!--POST-HEAD-START-->');
alert(config.messages.vaultCreationInfo);
return revised;
}
function locateVaultArea(original) //cloned from the TW2.2 standard function
{
// Locate the vaultArea div's. Should be just before the storeArea div
var posOpeningDiv = original.indexOf(startSaveVaultArea);
var limitClosingDiv = original.indexOf("<"+"!--POST-VAULTAREA--"+">");
if(limitClosingDiv == -1)
limitClosingDiv = original.indexOf("<div id="+'"storeArea"'+">");
var posClosingDiv = original.lastIndexOf(endSaveVaultArea,limitClosingDiv);
return (posOpeningDiv != -1 && posClosingDiv != -1) ? [posOpeningDiv,posClosingDiv] : null;
}
TiddlyWiki.prototype.allUnencryptedTiddlersAsHtml = function() {
return store.getSaver().externalize(store, SaverBase.systemStore);
};
TiddlyWiki.prototype.allEncryptedTiddlersAsHtml = function() {
return store.getSaver().externalize(store, SaverBase.vault);
};
SaverBase.prototype.externalize = function(store, tiddlerType) // overriding the TW2.2 standard function
{
var results = [];
var tiddlers = store.getTiddlers("title");
for(var t = 0; t < tiddlers.length; t++)
if (!tiddlerType || (this.getTiddlerType(tiddlers[t]) == tiddlerType)) // this line was changed from standard function
results.push(this.externalizeTiddler(store,tiddlers[t]));
return results.join("\n");
};
SaverBase.prototype.getTiddlerType= function(tiddler) {
if (tiddler.isTagged(SaverBase.vault)) return SaverBase.vault;
if (store.isShadowTiddler([tiddler.title])) return SaverBase.systemStore;
if (tiddler.isTagged("systemConfig")||tiddler.isTagged(SaverBase.systemStore)) return SaverBase.systemStore;
return SaverBase.vault;
};
LoaderBase.prototype.loadTiddler = function(store,node,tiddlers) // overriding the TW2.2 standard function
{
var title = this.getTitle(store,node);
if (store.getTiddler(title) && !confirm(config.messages.confirmOverload+"\n\n"+title)) // this line was changed from standard function
return;
if(title) {
var tiddler = store.createTiddler(title);
this.internalizeTiddler(store,tiddler,title,node);
tiddlers.push(tiddler);
}
};
window.saveChanges_noVault = window.saveChanges;
window.saveChanges= function(onlyIfDirty,tiddlers){
if (!vault.isLocked() || vault.purge || !vault.exists() || (vault.isLocked() && confirm(config.messages.saveWithLockedVaultConfirm)))
saveChanges_noVault(onlyIfDirty,tiddlers);
}
vault = {
load : function(){
if (!vault.isLocked()) {
alert(config.messages.vaultAlreadyUnlockedWarning);
return false;
}
else {
var storeElem = document.getElementById("vaultArea");
if (storeElem) {
var src = storeElem.innerHTML;
var pwd = vault.password ? vault.password : "";
while ((vault.isEncrypted(src)) && (pwd!=null)) {
if (pwd) src = vault.decrypt(src, pwd);
if (vault.isEncrypted(src)) pwd = prompt(vault.prompt,pwd);
}
if (pwd!=null) vault.password = pwd;
if (!vault.isEncrypted(src)) {
var wasDirty = store.isDirty();
var e = document.createElement("div");
e.innerHTML=src;
if (src) store.getLoader().loadTiddlers(store,e.childNodes);
vault.loaded = true;
refreshAll();
story.refreshAllTiddlers();
store.setDirty(wasDirty);
return true;
}
else return false;
}
}
},
decrypt : function(src,pwd){
var res = Crypto.cryptomx.decrypt(pwd,src.substr(vault.prefix.length));
return res ? res : src;
},
isEncrypted : function(src) {
return (src.substr(0,vault.prefix.length) == vault.prefix);
},
encrypt : function(src){
return vault.password ? vault.prefix + Crypto.cryptomx.encrypt(vault.password,src) : src;
},
isLocked : function(){
if (vault.loaded) return false;
var storeElem = document.getElementById("vaultArea");
return (!storeElem || (storeElem && vault.isEncrypted(storeElem.innerHTML)));
},
exists : function() {
return (document.getElementById("vaultArea")!=null);
},
prefix : "Cryptomx@",
prompt : "Enter a password",
loaded : false,
purge : false
}
config.macros.unlock = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
var label = params[0] ? params[0] : "unlock vault";
var tooltip = params[1] ? params[1] : "unlock encrypted vault";
var openTiddlers = params[2] ? params[2] : "";
var closeTiddlers = params[3] ? params[3] : "";
if (vault.isLocked() && vault.exists()) {
var btn = createTiddlyButton(place,label, tooltip,this.onClick);
btn.setAttribute("openTiddlers",openTiddlers);
btn.setAttribute("closeTiddlers",closeTiddlers);
}
},
onClick:function(){
var openTiddlers = this.getAttribute("openTiddlers");
var closeTiddlers = this.getAttribute("closeTiddlers");
if (vault.load()) {
if (closeTiddlers) {
var tiddlers = store.filterTiddlers(closeTiddlers);
for(var t=0; t<tiddlers.length; t++) {
var elem = document.getElementById(story.idPrefix + tiddlers[t].title);
if (elem && elem.getAttribute("dirty")!="true")
story.closeTiddler(tiddlers[t].title);
}
}
if (openTiddlers) {
var tiddlers = store.filterTiddlers(openTiddlers);
for(var t=0; t<tiddlers.length; t++)
story.displayTiddler("bottom",tiddlers[t].title);
}
}
return false;
}
}
config.macros.setPassword = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
var label = params[0] ? params[0] : "set password";
var tooltip = params[1] ? params[1] : "Set password for encrypted vault";
if (!vault.isLocked()) createTiddlyButton(place, label, tooltip,this.onClick);
},
onClick:function(){
var pwd = prompt(vault.prompt,(vault.password ? vault.password : ""));
if (pwd != null) vault.password = pwd;
return false;
}
}
config.macros.purge = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
var label = params[0] ? params[0] : "purge vault";
var tooltip = params[1] ? params[1] : "Delete locked vault";
if (vault.isLocked() && vault.exists()) createTiddlyButton(place,label, tooltip,this.onClick);
},
onClick:function(){
if (!vault.isLocked())
alert(config.messages.noLockedVaultWarning);
else
if (confirm(config.messages.purgeConfirm)) {
vault.purge=true;
alert(config.messages.vaultPurgedInfo);
}
return false;
}
}
config.macros.ifLocked = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if (vault.isLocked() && vault.exists()) wikify(params[0],place,null,tiddler);
}
}
config.macros.ifUnlocked = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
if (!vault.isLocked()) wikify(params[0],place,null,tiddler);
}
}
//}}}
/***
Cryptomx code from http://cryptomx.sourceforge.net
***/
//{{{
Crypto.cryptomx = {
dg :'',
makeArray: function(n) {
for (var i=1; i<=n; i++) {
this[i]=0
}
return this
},
rc4: function(key, text) {
var i, x, y, t, x2;
this.status("rc4")
s=this.makeArray(0);
for (i=0; i<256; i++) {
s[i]=i
}
y=0
for (x=0; x<256; x++) {
y=(key.charCodeAt(x % key.length) + s[x] + y) % 256
t=s[x]; s[x]=s[y]; s[y]=t
}
x=0; y=0;
var z=""
for (x=0; x<text.length; x++) {
x2=x % 256
y=( s[x2] + y) % 256
t=s[x2]; s[x2]=s[y]; s[y]=t
z+= String.fromCharCode((text.charCodeAt(x) ^ s[(s[x2] + s[y]) % 256]))
}
return z
},
badd: function(a,b) { // binary add
var r=''
var c=0
while(a || b) {
c=this.chop(a)+this.chop(b)+c
a=a.slice(0,-1); b=b.slice(0,-1)
if(c & 1) {
r="1"+r
} else {
r="0"+r
}
c>>=1
}
if(c) {r="1"+r}
return r
},
chop:function(a) {
if(a.length) {
return parseInt(a.charAt(a.length-1))
} else {
return 0
}
},
bsub:function(a,b) { // binary subtract
var r=''
var c=0
while(a) {
c=this.chop(a)-this.chop(b)-c
a=a.slice(0,-1); b=b.slice(0,-1)
if(c==0) {
r="0"+r
}
if(c == 1) {
r="1"+r
c=0
}
if(c == -1) {
r="1"+r
c=1
}
if(c==-2) {
r="0"+r
c=1
}
}
if(b || c) {return ''}
return this.bnorm(r)
},
bnorm:function(r) { // trim off leading 0s
var i=r.indexOf('1')
if(i == -1) {
return '0'
} else {
return r.substr(i)
}
},
bmul:function(a,b) { // binary multiply
var r=''; var p=''
while(a) {
if(this.chop(a) == '1') {
r=this.badd(r,b+p)
}
a=a.slice(0,-1)
p+='0'
}
return r;
},
bmod:function(a,m) { // binary modulo
return this.bdiv(a,m).mod
},
bdiv:function(a,m) { // binary divide & modulo
// this.q = quotient this.mod=remainder
var lm=m.length, al=a.length
var p='',d
this.q=''
for(n=0; n<al; n++) {
p=p+a.charAt(n);
if(p.length<lm || (d=this.bsub(p,m)) == '') {
this.q+='0'
} else {
if(this.q.charAt(0)=='0') {
this.q='1'
} else {
this.q+="1"
}
p=d
}
}
this.mod=this.bnorm(p)
return this
},
bmodexp:function(x,y,m) { // binary modular exponentiation
var r='1'
this.status("bmodexp "+x+" "+y+" "+m)
while(y) {
if(this.chop(y) == 1) {
r=this.bmod(this.bmul(r,x),m)
}
y=y.slice(0,y.length-1)
x=this.bmod(this.bmul(x,x),m)
}
return this.bnorm(r)
},
modexp:function(x,y,m) { // modular exponentiation
// convert packed bits (text) into strings of 0s and 1s
return this.b2t(this.bmodexp(this.t2b(x),this.t2b(y),this.t2b(m)))
},
i2b: function(i) { // convert integer to binary
var r=''
while(i) {
if(i & 1) { r="1"+r} else {r="0"+r}
i>>=1;
}
return r? r:'0'
},
t2b:function(s) {
var r=''
if(s=='') {return '0'}
while(s.length) {
var i=s.charCodeAt(0)
s=s.substr(1)
for(n=0; n<8; n++) {
r=((i & 1)? '1':'0') + r
i>>=1;
}
}
return this.bnorm(r)
},
b2t:function(b) {
var r=''; var v=0; var m=1
while(b.length) {
v|=this.chop(b)*m
b=b.slice(0,-1)
m<<=1
if(m==256 || b=='') {
r+=String.fromCharCode(v)
v=0; m=1
}
}
return r
},
b64s:'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"',
textToBase64:function(t) {
this.status("t 2 b64")
var r=''; var m=0; var a=0; var tl=t.length-1; var c
for(n=0; n<=tl; n++) {
c=t.charCodeAt(n)
r+=this.b64s.charAt((c << m | a) & 63)
a = c >> (6-m)
m+=2
if(m==6 || n==tl) {
r+=this.b64s.charAt(a)
if((n%45)==44) {r+="\n"}
m=0
a=0
}
}
return r
},
base64ToText:function(t) {
this.status("b64 2 t")
var r=''; var m=0; var a=0; var c
for(n=0; n<t.length; n++) {
c=this.b64s.indexOf(t.charAt(n))
if(c >= 0) {
if(m) {
r+=String.fromCharCode((c << (8-m))&255 | a)
}
a = c >> m
m+=2
if(m==8) { m=0 }
}
}
return r
},
rand:function(n) { return Math.floor(Math.random() * n) },
rstring:function(s,l) {
var r=""
var sl=s.length
while(l>0) {
l=l-1;
r+=s.charAt(rand(sl))
}
//status("rstring "+r)
return r
},
key2:function(k) {
var l=k.length
var kl=l
var r=''
while(l--) {
r+=k.charAt((l*3)%kl)
}
return r
},
rsaEncrypt:function(keylen,key,mod,text) {
// I read that rc4 with keys larger than 256 bytes doesn't significantly
// increase the level of rc4 encryption because it's sbuffer is 256 bytes
// makes sense to me, but what do i know...
this.status("encrypt")
if(text.length >= keylen) {
var sessionkey=this.rc4(rstring(text,keylen),rstring(text,keylen))
// session key must be less than mod, so mod it
sessionkey=this.b2t(bmod(t2b(sessionkey),t2b(mod)))
alert("sessionkey="+sessionkey)
// return the rsa encoded key and the encrypted text
// i'm double encrypting because it would seem to me to
// lessen known-plaintext attacks, but what do i know
return this.modexp(sessionkey,key,mod) +
this.rc4(this.key2(sessionkey),this.rc4(sessionkey,text))
} else {
// don't need a session key
return this.modexp(text,key,mod)
}
},
rsaDecrypt:function(keylen,key,mod,text) {
this.status("decrypt")
if(text.length <= keylen) {
return this.modexp(text,key,mod)
} else {
// sessionkey is first keylen bytes
var sessionkey=text.substr(0,keylen)
text=text.substr(keylen)
// un-rsa the session key
sessionkey=this.modexp(sessionkey,key,mod)
alert("sessionkey="+sessionkey)
// double decrypt the text
return this.rc4(sessionkey,this.rc4(this.key2(sessionkey,text),text))
}
},
trim2:function(d) { return d.substr(0,d.lastIndexOf('1')+1) },
bgcd:function(u,v) { // return greatest common divisor
// algorythm from http://algo.inria.fr/banderier/Seminar/Vallee/index.html
var d, t
while(1) {
d=this.bsub(v,u)
//alert(v+" - "+u+" = "+d)
if(d=='0') {return u}
if(d) {
if(d.substr(-1)=='0') {
v=d.substr(0,d.lastIndexOf('1')+1) // v=(v-u)/2^val2(v-u)
} else v=d
} else {
t=v; v=u; u=t // swap u and v
}
}
},
isPrime:function(p) {
var n,p1,p12,t
p1=this.bsub(p,'1')
t=p1.length-p1.lastIndexOf('1')
p12=this.trim2(p1)
for(n=0; n<2; n+=this.mrtest(p,p1,p12,t)) {
if(n<0) return 0
}
return 1
},
mrtest:function(p,p1,p12,t) {
// Miller-Rabin test from forum.swathmore.edu/dr.math/
var n,a,u
a='1'+this.rstring('01',Math.floor(p.length/2)) // random a
//alert("mrtest "+p+", "+p1+", "+a+"-"+p12)
u=this.bmodexp(a,p12,p)
if(u=='1') {return 1}
for(n=0;n<t;n++) {
u=this.bmod(this.bmul(u,u),p)
//dg+=u+" "
if(u=='1') return -100
if(u==p1) return 1
}
return -100
},
pfactors:'11100011001110101111000110001101',
// this number is 3*5*7*11*13*17*19*23*29*31*37
prime:function(bits) {
// return a prime number of bits length
var p='1'+this.rstring('001',bits-2)+'1'
while( ! this.isPrime(p)) {
p=badd(p,'10'); // add 2
}
alert("p is "+p)
return p
},
genkey:function(bits) {
q=prime(bits)
do {
p=q
q=prime(bits)
} while(bgcd(p,q)!='1')
p1q1=this.bmul(this.bsub(p,'1'),this.bsub(q,'1'))
// now we need a d, e, and an n so that:
// p1q1*n-1=de -> bmod(bsub(bmul(d,e),'1'),p1q1)='0'
// or more specifically an n so that d & p1q1 are rel prime and factor e
n='1'+this.rstring('001',Math.floor(bits/3)+2)
alert('n is '+n)
factorMe=this.badd(this.bmul(p1q1,n),'1')
alert('factor is '+factorMe)
//e=bgcd(factorMe,p1q1)
//alert('bgcd='+e)
e='1'
// is this always 1?
//r=bdiv(factorMe,e)
//alert('r='+r.q+" "+r.mod)
//if(r.mod != '0') {alert('Mod Error!')}
//factorMe=r.q
d=this.bgcd(factorMe,'11100011001110101111000110001101')
alert('d='+d)
if(d == '1' && e == '1') {alert('Factoring failed '+factorMe+' p='+p+' q='+q)}
e=this.bmul(e,d)
r=this.bdiv(factorMe,d)
d=r.q
if(r.mod != '0') {alert('Mod Error 2!')}
this.mod=this.b2t(bmul(p,q))
this.pub=this.b2t(e)
this.priv=this.b2t(d)
},
status:function(a) { },//alert(a)}
encrypt:function(key,text) {
return this.textToBase64(this.rc4(key,"check:"+text));
},
decrypt:function(key,text){
var uncrypt = this.rc4(key,this.base64ToText(text));
return (uncrypt.substr(0,6)=="check:") ? uncrypt.substr(6) : null;
}
}
//}}}
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
major: 1, minor: 1, revision: 0,
date: new Date("mar 17, 2007"),
source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};
if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};
bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){
url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
}
return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
major: 1, minor: 0, revision: 2,
date: new Date("Apr 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
coreVersion: '2.2.0 (Beta 5)'
};
config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");
merge(config.macros.option.types, {
'pas': {
elementType: "input",
valueField: "value",
eventName: "onkeyup",
className: "pasOptionInput",
typeValue: config.macros.option.passwordInputType,
create: function(place,type,opt,className,desc) {
// password field
config.macros.option.genericCreate(place,'pas',opt,className,desc);
// checkbox linked with this password "save this password on this computer"
config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);
// text savePasswordCheckboxLabel
place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
},
onChange: config.macros.option.genericOnChange
}
});
merge(config.optionHandlers['chk'], {
get: function(name) {
// is there an option linked with this chk ?
var opt = name.substr(3);
if (config.options[opt])
saveOptionCookie(opt);
return config.options[name] ? "true" : "false";
}
});
merge(config.optionHandlers, {
'pas': {
get: function(name) {
if (config.options["chk"+name]) {
return encodeCookie(config.options[name].toString());
} else {
return "";
}
},
set: function(name,value) {config.options[name] = decodeCookie(value);}
}
});
// need to reload options to load passwordOptions
loadOptionsCookie();
/*
if (!config.options['pasPassword'])
config.options['pasPassword'] = '';
merge(config.optionsDesc,{
pasPassword: "Test password"
});
*/
//}}}
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{
// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'devoroumov';
// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too
// disable autosave in d3
if (window.location.protocol != "file:")
config.options.chkGTDLazyAutoSave = false;
// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}
// create some shadow tiddler content
merge(config.shadowTiddlers,{
'WelcomeToTiddlyspot':[
"This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
"<<tiddler TspotControls>>",
"See also GettingStarted.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),
'TspotControls':[
"| tiddlyspot password:|<<option pasUploadPassword>>|",
"| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
"| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),
'TspotSidebar':[
"<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n"),
'TspotOptions':[
"tiddlyspot password:",
"<<option pasUploadPassword>>",
""
].join("\n")
});
//}}}
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 16/09/2008 15:10:33 | YourName | [[/|http://devoroumov.tiddlyspot.com/]] | [[store.cgi|http://devoroumov.tiddlyspot.com/store.cgi]] | . | [[index.html | http://devoroumov.tiddlyspot.com/index.html]] | . | failed |
| 16/09/2008 15:11:10 | YourName | [[/|http://devoroumov.tiddlyspot.com/]] | [[store.cgi|http://devoroumov.tiddlyspot.com/store.cgi]] | . | [[index.html | http://devoroumov.tiddlyspot.com/index.html]] | . |
| 16/09/2008 15:11:44 | YourName | [[/|http://devoroumov.tiddlyspot.com/]] | [[store.cgi|http://devoroumov.tiddlyspot.com/store.cgi]] | . | [[index.html | http://devoroumov.tiddlyspot.com/index.html]] | . |
| 16/09/2008 15:16:53 | YourName | [[/|http://devoroumov.tiddlyspot.com/]] | [[store.cgi|http://devoroumov.tiddlyspot.com/store.cgi]] | . | [[index.html | http://devoroumov.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
major: 4, minor: 1, revision: 3,
date: new Date("Feb 24, 2008"),
source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
//
// Upload Macro
//
config.macros.upload = {
// default values
defaultBackupDir: '', //no backup
defaultStoreScript: "store.php",
defaultToFilename: "index.html",
defaultUploadDir: ".",
authenticateUser: true // UploadService Authenticate User
};
config.macros.upload.label = {
promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
promptParamMacro: "Save and Upload this TiddlyWiki in %0",
saveLabel: "save to web",
saveToDisk: "save to disk",
uploadLabel: "upload"
};
config.macros.upload.messages = {
noStoreUrl: "No store URL in parmeters or options",
usernameOrPasswordMissing: "Username or password missing"
};
config.macros.upload.handler = function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = this.label.saveLabel;
else
label = this.label.uploadLabel;
var prompt;
if (params[0]) {
prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0],
(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
} else {
prompt = this.label.promptOption;
}
createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};
config.macros.upload.action = function(params)
{
// for missing macro parameter set value from options
if (!params) params = {};
var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
var username = params[4] ? params[4] : config.options.txtUploadUserName;
var password = config.options.pasUploadPassword; // for security reason no password as macro parameter
// for still missing parameter set default value
if ((!storeUrl) && (document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
if (storeUrl.substr(0,4) != "http")
storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
if (!toFilename)
toFilename = bidix.basename(window.location.toString());
if (!toFilename)
toFilename = config.macros.upload.defaultToFilename;
if (!uploadDir)
uploadDir = config.macros.upload.defaultUploadDir;
if (!backupDir)
backupDir = config.macros.upload.defaultBackupDir;
// report error if still missing
if (!storeUrl) {
alert(config.macros.upload.messages.noStoreUrl);
clearMessage();
return false;
}
if (config.macros.upload.authenticateUser && (!username || !password)) {
alert(config.macros.upload.messages.usernameOrPasswordMissing);
clearMessage();
return false;
}
bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password);
return false;
};
config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir)
{
if (!storeUrl)
return null;
var dest = bidix.dirname(storeUrl);
if (uploadDir && uploadDir != '.')
dest = dest + '/' + uploadDir;
dest = dest + '/' + toFilename;
return dest;
};
//
// uploadOptions Macro
//
config.macros.uploadOptions = {
handler: function(place,macroName,params) {
var wizard = new Wizard();
wizard.createWizard(place,this.wizardTitle);
wizard.addStep(this.step1Title,this.step1Html);
var markList = wizard.getElement("markList");
var listWrapper = document.createElement("div");
markList.parentNode.insertBefore(listWrapper,markList);
wizard.setValue("listWrapper",listWrapper);
this.refreshOptions(listWrapper,false);
var uploadCaption;
if (document.location.toString().substr(0,4) == "http")
uploadCaption = config.macros.upload.label.saveLabel;
else
uploadCaption = config.macros.upload.label.uploadLabel;
wizard.setButtons([
{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
onClick: config.macros.upload.action},
{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
]);
},
options: [
"txtUploadUserName",
"pasUploadPassword",
"txtUploadStoreUrl",
"txtUploadDir",
"txtUploadFilename",
"txtUploadBackupDir",
"chkUploadLog",
"txtUploadLogMaxLine"
],
refreshOptions: function(listWrapper) {
var opts = [];
for(i=0; i<this.options.length; i++) {
var opt = {};
opts.push();
opt.option = "";
n = this.options[i];
opt.name = n;
opt.lowlight = !config.optionsDesc[n];
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
opts.push(opt);
}
var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
for(n=0; n<opts.length; n++) {
var type = opts[n].name.substr(0,3);
var h = config.macros.option.types[type];
if (h && h.create) {
h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
}
}
},
onCancel: function(e)
{
backstage.switchTab(null);
return false;
},
wizardTitle: "Upload with options",
step1Title: "These options are saved in cookies in your browser",
step1Html: "<input type='hidden' name='markList'></input><br>",
cancelButton: "Cancel",
cancelButtonPrompt: "Cancel prompt",
listViewTemplate: {
columns: [
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
};
//
// upload functions
//
if (!bidix.upload) bidix.upload = {};
if (!bidix.upload.messages) bidix.upload.messages = {
//from saving
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
backupSaved: "Backup saved",
backupFailed: "Failed to upload backup file",
rssSaved: "RSS feed uploaded",
rssFailed: "Failed to upload RSS feed file",
emptySaved: "Empty template uploaded",
emptyFailed: "Failed to upload empty template file",
mainSaved: "Main TiddlyWiki file uploaded",
mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
//specific upload
loadOriginalHttpPostError: "Can't get original file",
aboutToSaveOnHttpPost: 'About to upload on %0 ...',
storePhpNotFound: "The store script '%0' was not found."
};
bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
var callback = function(status,uploadParams,original,url,xhr) {
if (!status) {
displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
return;
}
if (bidix.debugMode)
alert(original.substr(0,500)+"\n...");
// Locate the storeArea div's
var posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
bidix.upload.uploadRss(uploadParams,original,posDiv);
};
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
// save on localdisk ?
if (document.location.toString().substr(0,4) == "file") {
var path = document.location.toString();
var localPath = getLocalPath(path);
saveChanges();
}
// get original
var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
var originalPath = document.location.toString();
// If url is a directory : add index.html
if (originalPath.charAt(originalPath.length-1) == "/")
originalPath = originalPath + "index.html";
var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
var log = new bidix.UploadLog();
log.startUpload(storeUrl, dest, uploadDir, backupDir);
displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
if (bidix.debugMode)
alert("about to execute Http - GET on "+originalPath);
var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
bidix.upload.uploadRss = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
if(status) {
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
bidix.upload.uploadMain(params[0],params[1],params[2]);
} else {
displayMessage(bidix.upload.messages.rssFailed);
}
};
// do uploadRss
if(config.options.chkGenerateAnRssFeed) {
var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
var rssString = generateRss();
// no UnicodeToUTF8 conversion needed when location is "file" !!!
if (document.location.toString().substr(0,4) != "file")
rssString = convertUnicodeToUTF8(rssString);
bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
} else {
bidix.upload.uploadMain(uploadParams,original,posDiv);
}
};
bidix.upload.uploadMain = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
var log = new bidix.UploadLog();
if(status) {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
store.setDirty(false);
log.endUpload("ok");
} else {
alert(bidix.upload.messages.mainFailed);
displayMessage(bidix.upload.messages.mainFailed);
log.endUpload("failed");
}
};
// do uploadMain
var revised = bidix.upload.updateOriginal(original,posDiv);
bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};
bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
var localCallback = function(status,params,responseText,url,xhr) {
url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
if (xhr.status == 404)
alert(bidix.upload.messages.storePhpNotFound.format([url]));
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
if (responseText.charAt(0) != '0')
status = null;
callback(status,params,responseText,url,xhr);
};
// do httpUpload
var boundary = "---------------------------"+"AaB03x";
var uploadFormName = "UploadPlugin";
// compose headers data
var sheader = "";
sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
sheader += uploadFormName +"\"\r\n\r\n";
sheader += "backupDir="+uploadParams[3] +
";user=" + uploadParams[4] +
";password=" + uploadParams[5] +
";uploaddir=" + uploadParams[2];
if (bidix.debugMode)
sheader += ";debug=1";
sheader += ";;\r\n";
sheader += "\r\n" + "--" + boundary + "\r\n";
sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
sheader += "Content-Length: " + data.length + "\r\n\r\n";
// compose trailer data
var strailer = new String();
strailer = "\r\n--" + boundary + "--\r\n";
data = sheader + data + strailer;
if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
if (!posDiv)
posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
store.allTiddlersAsHtml() + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = getPageTitle().htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
};
//
// UploadLog
//
// config.options.chkUploadLog :
// false : no logging
// true : logging
// config.options.txtUploadLogMaxLine :
// -1 : no limit
// 0 : no Log lines but UploadLog is still in place
// n : the last n lines are only kept
// NaN : no limit (-1)
bidix.UploadLog = function() {
if (!config.options.chkUploadLog)
return; // this.tiddler = null
this.tiddler = store.getTiddler("UploadLog");
if (!this.tiddler) {
this.tiddler = new Tiddler();
this.tiddler.title = "UploadLog";
this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
this.tiddler.created = new Date();
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
}
return this;
};
bidix.UploadLog.prototype.addText = function(text) {
if (!this.tiddler)
return;
// retrieve maxLine when we need it
var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
if (isNaN(maxLine))
maxLine = -1;
// add text
if (maxLine != 0)
this.tiddler.text = this.tiddler.text + text;
// Trunck to maxLine
if (maxLine >= 0) {
var textArray = this.tiddler.text.split('\n');
if (textArray.length > maxLine + 1)
textArray.splice(1,textArray.length-1-maxLine);
this.tiddler.text = textArray.join('\n');
}
// update tiddler fields
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
// refresh and notifiy for immediate update
story.refreshTiddler(this.tiddler.title);
store.notify(this.tiddler.title, true);
};
bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {
if (!this.tiddler)
return;
var now = new Date();
var text = "\n| ";
var filename = bidix.basename(document.location.toString());
if (!filename) filename = '/';
text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
text += config.options.txtUserName + " | ";
text += "[["+filename+"|"+location + "]] |";
text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
text += uploadDir + " | ";
text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
text += backupDir + " |";
this.addText(text);
};
bidix.UploadLog.prototype.endUpload = function(status) {
if (!this.tiddler)
return;
this.addText(" "+status+" |");
};
//
// Utilities
//
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.dirname = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(0, lastpos);
} else {
return filePath.substring(0, filePath.lastIndexOf("\\"));
}
};
bidix.basename = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("#")) != -1)
filePath = filePath.substring(0, lastpos);
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(lastpos + 1);
} else
return filePath.substring(filePath.lastIndexOf("\\")+1);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);
// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
txtUploadUserName: "Upload Username",
pasUploadPassword: "Upload Password",
chkUploadLog: "do Logging in UploadLog (default: true)",
txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});
// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');
// Backstage
merge(config.tasks,{
uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");
//}}}
This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.
@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://devoroumov.tiddlyspot.com/controlpanel]] (your control panel username is //devoroumov//).
<<tiddler TspotControls>>
See also GettingStarted.
@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the "save to web" button in the column on the right.
@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click "upload" and your ~TiddlyWiki will be saved back to tiddlyspot.com.
@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].
@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions.