Files
digiproof/js/app.js

1074 lines
30 KiB
JavaScript
Raw Normal View History

2013-09-12 23:13:49 +02:00
App = Ember.Application.create({
//LOG_TRANSITIONS: true
});
var attr = DS.attr;
App.SelfMixin = Ember.Mixin.create({
passwdset: null,
/*
didLoad: function() {
this._passwdset();
},
didUpdate: function() {
this.didLoad();
},
*/
validate: function() {
var valid = true;
var errors = {valid: true};
if(! this.get('password')) {
errors.password = translate('_error_password');
errors.valid = false;
}
if(! this.get('name')) {
errors.name = translate('_error_name');
errors.valid = false;
}
if(! this.get('birth')) {
errors.birth = translate('_error_birth');
errors.valid = false;
}
if(! this.get('address')) {
errors.address = translate('_error_address');
errors.valid = false;
}
return errors;
},
haspasswd: function() {
var p = this.get('password');
if(p) {
return true;
}
else {
return false;
}
}.property()
});
App.Order = DS.Model.extend({
name: attr('string')
});
App.Self = DS.Model.extend(App.SelfMixin, {
name: attr('string'),
address: attr('string'),
birth: attr('string'),
password: attr('string'),
toJson: function() {
return JSON.stringify({
name: this.get('name'),
address: this.get('address'),
birth: this.get('birth')
});
}.property()
});
App.ImportMixin = Ember.Mixin.create({
validate: function() {
var valid = true;
var errors = {valid: true};
if(! this.get('password')) {
errors.password = translate('_error_password');
errors.valid = false;
}
return errors;
}
});
App.Import = DS.Model.extend(App.ImportMixin, {
importdata: attr('string'),
password: attr('string')
});
App.SuccessorMixin = Ember.Mixin.create({
validate: function() {
var valid = true;
var errors = {valid: true};
if(! this.get('name')) {
errors.name = translate('_error_name');
errors.valid = false;
}
return errors;
}
});
App.Successor = DS.Model.extend(App.SuccessorMixin, {
name: attr('string'),
address: attr('string'),
birth: attr('string'),
name2: attr('string'),
address2: attr('string'),
birth2: attr('string'),
assets: DS.hasMany('App.Asset', {
inverse: 'successor'
}),
toJson: function() {
return JSON.stringify({
id: this.get('id'),
name: this.get('name'),
address: this.get('address'),
birth: this.get('birth'),
name2: this.get('name2'),
address2: this.get('address2'),
birth2: this.get('birth2')
});
}.property(),
has_assets: function() {
var has = false;
var assets = this.get('assets');
has = assets.forEach(function(asset) {
return true;
});
return has;
}.property()
});
App.AssetMixin = Ember.Mixin.create({
validate: function() {
var orderid;
var successorid;
var errors = {valid: true};
try {
orderid = this.get('order').get('id');
}
catch (e) { }
try {
successorid = this.get('successor').get('id');
}
catch (e) { }
//console.log("got o: %o, s: %o", orderid, successorid);
if(! orderid) {
errors.order = translate('_error_order');
errors.valid = false;
}
if(! successorid) {
errors.successor = translate('_error_successor');
errors.valid = false;
}
return errors;
}
});
App.Asset = DS.Model.extend(App.AssetMixin, {
name: attr('string'),
uri: attr('string'),
login: attr('string'),
password: attr('string'),
mail: attr('string'),
order: DS.belongsTo('App.Order'),
notes: attr('string'),
successor: DS.belongsTo('App.Successor'),
toJson: function() {
var orderid = "0";
var successorid = "0";
try {
orderid = this.get('order').get('id');
}
catch (e) {}
try {
successorid = this.get('successor').get('id');
}
catch (e) {}
return JSON.stringify({
id: this.get('id'),
name: this.get('name'),
uri: this.get('uri'),
login: this.get('login'),
password: this.get('password'),
mail: this.get('mail'),
notes: this.get('notes'),
order: orderid,
successor: successorid
});
}.property()
});
var lang = (navigator.language) ? navigator.language : navigator.userLanguage;
App.store = DS.Store.createWithMixins({
revision: 12,
adapter: DS.LSAdapter.create({
namespace: 'digiproof'
}),
init: function() {
this._super();
this.loadMany(App.Import,[ { 'id': 0, 'importdata': '' }]);
if(lang === 'de') {
this.loadMany(App.Order,
[
{ 'id': 0, 'name': 'weiter zu betreiben' },
{ 'id': 1, 'name': 'zu kündigen' },
{ 'id': 2, 'name': 'zu übertragen' },
{ 'id': 3, 'name': 'nach Gutdünken abzuwickeln' },
]
);
this.loadMany(App.Successor, [{ 'id': 0, 'name': 'Mein(e) regulären Erbe(n)' }]);
}
else {
this.loadMany(App.Order,
[
{ 'id': 0, 'name': 'maintain' },
{ 'id': 1, 'name': 'liquidate' },
{ 'id': 2, 'name': 'transfer' },
{ 'id': 3, 'name': 'decide herself' },
]
);
this.loadMany(App.Successor, [{ 'id': 0, 'name': 'My regular legal succesor(s)' }]);
}
}
});
App.Router.map(function() {
this.resource('assets', function() {
this.route('asset', { path: ':asset_id' });
this.route('new');
});
this.resource('successors', function() {
this.route('successor', { path: ':successor_id' });
this.route('new');
});
this.route('self');
this.route('testament');
this.resource('data', function() {
this.route('export');
this.route('import');
});
});
App.IndexController = Ember.Controller.extend({
has_self: App.Self.find(),
has_asset: App.Asset.find(),
has_successor: App.Successor.find(),
VERSION: VERSION
});
function CheckForEmptyDB() {
var assets = App.Asset.find();
var notempty = true;
notempty = assets.forEach(function(asset) {
return false;
});
return notempty;
}
/*
FIXME: checking for self.name doesnt work because
of delayed exec it returns null even if the
name is set.
function CheckForEmptyDB() {
var assets = App.Asset.find();
var self = App.Self.find(0);
var noassets = true;
var noself = true;
noassets = assets.forEach(function(asset) {
return false;
});
console.log("a: %o, s: %o", noassets, noself);
console.log("name: %s", self.get('name'));
if(self.get('name')) {
noself = false;
}
console.log("a: %o, s: %o", noassets, noself);
if(noassets && noself) {
return false;
}
else {
return true;
}
}
*/
App.TestamentController = Ember.ArrayController.extend({
needs: "self",
//self: Ember.computed.alias("controllers.self"),
successors: App.Successor.find(),
self: App.Self.find(0),
now: new Date(),
notempty: CheckForEmptyDB()
});
App.DataExportController = Ember.ArrayController.extend({
successors: App.Successor.find(),
self: App.Self.find(0),
assets: App.Asset.find(),
download: function() {
var raw = $('#rawdata').text();
//console.log("raw: %o", raw);
var blob = new Blob([raw], {type: "text/plain;charset=utf-8"});
saveAs(blob, "digiproof-export.txt");
}
});
/*
successors.forEach(function(successor) {
doc.text(20, line, utf2latin(successor.get('name')));
line += 10;
});
*/
App.AssetsRoute = Ember.Route.extend({
model: function() {
return App.Asset.find();
}
});
App.SelfRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('model', App.Self.find(0));
}
});
App.SelfController = Ember.ObjectController.extend({
isEditing: false,
errors: {},
edit: function() {
// prepare order to the actual object, not id
this.set('isEditing', true);
},
doneEditing: function() {
var validated = this.get('model').validate();
if(! validated.valid) {
this.set('errors', validated);
this.set('isEditing', true);
}
else {
this.set('isEditing', false);
this.get('model').get("store").commit();
}
},
cancelEditing: function() {
this.set('isEditing', false);
}
});
App.DataImportRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('model', App.Import.find(0));
}
});
// Convert hex string to ASCII.
// See http://stackoverflow.com/questions/11889329/word-array-to-string
function hex2a(hex) {
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
function decryptimport(pass, data) {
var enpass = CryptoJS.SHA512(pass).toString(CryptoJS.enc.Base64);
var clear = CryptoJS.AES.decrypt(data, enpass);
return unescape(hex2a(clear.toString()));
}
// from:
// http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html
function decode64(input) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
var keyStr = "ABCDEFGHIJKLMNOP" +
"QRSTUVWXYZabcdef" +
"ghijklmnopqrstuv" +
"wxyz0123456789+/" +
"=";
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
var base64test = /[^A-Za-z0-9\+\/\=]/g; //
if (base64test.exec(input)) {
alert("There were invalid base64 characters in the input text.\n" +
"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
"Expect errors in decoding.");
}
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return unescape(output);
}
var UploadedImport = null;
App.UploadFileView = Ember.TextField.extend({
// WARN: this one gets fired as soon as the user selected a file
// that is, before the submit button got clicked
type: 'file',
attributeBindings: ['name'],
change: function(evt) {
var self = this;
var input = evt.target;
if (input.files && input.files[0]) {
var reader = new FileReader();
var that = this;
reader.onload = function(e) {
var fileToUpload = e.srcElement.result;
UploadedImport = decode64(fileToUpload.split(',')[1]);
}
reader.readAsDataURL(input.files[0]);
}
}
});
App.DataImportController = Ember.ObjectController.extend({
isEditing: true,
clear: '',
errors: {},
doneEditing: function() {
var validated = this.get('model').validate();
// decrypt and reload models
if(validated.valid) {
this.set('isEditing', false);
pass = this.get('password');
try {
var entries = '';
if(UploadedImport) {
//console.log("using upload");
entries = UploadedImport.match(/[^\r\n]+/g);
UploadedImport = null;
}
else if (this.get('importdata')) {
//console.log("using input");
entries = this.get('importdata').match(/[^\r\n]+/g);
}
else {
throw 'No import data provided';
}
//console.log("got %d entries: %o", entries.length, entries);
var json = '';
for (var i = 0; i < entries.length; i++) {
var importline = entries[i].split(',');
//console.log("splitted: %o", importline);
if(importline[0] === 'asset') {
//console.log("import asset");
json = decryptimport(pass, importline[1]);
if(json) {
//console.log("evaluating: %s", json);
var obj = JSON.parse(json);
//console.log("code: %o", obj);
var exists = App.Asset.all().some(function(asset) {
return asset.get('id') === obj.id;
});
if(exists) {
/* update
FIXME: Updating doesn't work yet for some unknown reason
App.Asset.find(obj.id).then(function(asset) {
asset.set("name", obj.name);
asset.set("uri", obj.uri);
asset.set("login", obj.login);
asset.set("password", obj.password);
asset.set("mail", obj.mail);
asset.set("successor", App.Successor.find(obj.successor));
asset.set("order", App.Order.find(obj.order));
asset.set("notes", obj.notes);
});
*/
}
else {
// create
var asset = App.Asset.createRecord({
id: obj.id,
name: obj.name,
uri: obj.uri,
login: obj.login,
password: obj.password,
mail: obj.mail,
successor: App.Successor.find(obj.successor),
order: App.Order.find(obj.order),
notes: obj.notes
});
}
}
else {
throw 'decrypted variable $json doesnt contain anything, weird';
}
}
else if (importline[0] === 'successor') {
console.log("import successor");
json = decryptimport(pass, importline[1]);
console.log("evaluating: %s", json);
if(json) {
var obj = JSON.parse(json);
if(obj.id !== "0") {
var exists = App.Successor.all().some(function(successor) {
return successor.get('id') === obj.id;
});
if(! exists) {
var successor = App.Successor.createRecord(obj);
}
}
else {
//console.log("ignoring id 0");
}
}
else {
throw 'decrypted variable $json doesnt contain anything, weird';
}
}
else if (importline[0] === 'self') {
console.log("import self");
json = decryptimport(pass, importline[1]);
console.log("evaluating: %s", json);
if(json) {
var obj = JSON.parse(json);
var self = App.Self.find(0).then(function(self) {
//console.log("didLoad on self fired, putting %o with pass %s", obj, pass);
self.set('name', obj.name);
self.set('birth', obj.birth);
self.set('address', obj.address);
self.set('password', pass);
});
}
else {
throw 'decrypted variable $json doesnt contain anything, weird';
}
}
/*
else {
console.log("import unknown");
}
*/
}
App.store.commit();
this.set('clear', translate('_importdone'));
}
catch (e) {
console.log("decryption exception: %o", e);
this.set('clear', translate('_error_decrypt') + " (" + e + ")");
}
}
else {
// no password given
this.set('isEditing', true);
this.set('errors', validated);
this.set('clear', translate('_error_decrypt'));
}
},
repeatEditing: function() {
this.set('isEditing', true);
this.set('importdata', '');
this.set('password', '');
}
});
App.AssetsAssetController = Ember.ObjectController.extend({
isEditing: false,
orders: App.Order.find(),
errors: {},
edit: function() {
// prepare order to the actual object, not id
this.set('isEditing', true);
this.set('successors', App.Successor.find());
},
doneEditing: function() {
var validated = this.get('model').validate();
if(validated.valid){
this.set('isEditing', false);
this.get('model').get("store").commit();
}
else {
this.set('errors', validated);
this.set('isEditing', true);
}
},
cancelEditing: function() {
this.set('isEditing', false);
},
remove: function() {
var asset = this.get('model');
asset.deleteRecord();
asset.get("store").commit();
this.get("target").transitionTo("assets");
}
});
App.AssetsNewController = Ember.ArrayController.extend({
successors: App.Successor.find(),
orders: App.Order.find(),
next: 0,
selected_successor: 0,
selected_order: 0,
errors: {},
createNextAsset: function () {
this.set('next', 1);
this.createAsset();
},
createAsset: function () {
var name = this.get('name');
if (!name.trim()) { return; }
//console.log("successor: %o", this.get('order'));
var asset = App.Asset.createRecord({
name: name,
uri: this.get('uri'),
login: this.get('login'),
password: this.get('password'),
mail: this.get('mail'),
successor: this.get('successor'),
order: this.get('order'),
notes: this.get('notes')
});
var validated = asset.validate();
//console.log("validated: %o", validated);
if(! validated.valid) {
asset.deleteRecord();
this.set('errors', validated);
this.set('isEditing', true);
}
else {
// Save the new model
asset.get("store").commit();
// empty form fields so new entries starts from scratch
this.set('name', '');
this.set('uri', '');
this.set('login', '');
this.set('password', '');
this.set('mail', '');
this.set('order', '');
this.set('successor','');
this.set('notes', '');
if(this.get('next') == 1) {
this.get("target").transitionTo("assets.new");
}
else {
// redirect to newly created entry
this.get("target").transitionTo("assets.asset", asset);
}
}
}
});
App.NavView = Ember.View.extend({
tagName: 'li',
classNameBindings: 'active'.w(),
didInsertElement: function () {
this._super();
var _this = this;
this.get('parentView').on('click', function () {
_this.notifyPropertyChange('active');
});
},
active: function () {
return this.get('childViews.firstObject.active');
}.property()
});
App.SuccessorsRoute = Ember.Route.extend({
model: function() {
return App.Successor.find();
}
});
App.SuccessorsSuccessorController = Ember.ObjectController.extend({
isEditing: false,
errors: {},
edit: function() {
this.set('isEditing', true);
},
doneEditing: function() {
var validated = this.get('model').validate();
if(! validated.valid) {
this.set('errors', validated);
this.set('isEditing', true);
}
else {
this.set('isEditing', false);
this.get('model').get("store").commit();
}
},
cancelEditing: function() {
this.set('isEditing', false);
},
remove: function() {
var successor = this.get('model');
successor.deleteRecord();
successor.get("store").commit();
this.get("target").transitionTo("successors");
}
});
App.SuccessorsNewController = Ember.ArrayController.extend({
newName: '',
next: 0,
erros: {},
createNextSuccessor: function () {
this.set('next', 1);
this.createSuccessor();
},
createSuccessor: function () {
var successor = App.Successor.createRecord({
name: this.get('name'),
address: this.get('address'),
birth: this.get('birth'),
name2: this.get('name2'),
address2: this.get('address2'),
birth2: this.get('birth2')
});
var validated = successor.validate();
//console.log("validated: %o", validated);
if(! validated.valid) {
successor.deleteRecord();
this.set('errors', validated);
this.set('isEditing', true);
}
else {
// Save the new model
successor.get("store").commit();
// empty form fields so new entries starts from scratch
this.set('name', '');
this.set('address', '');
this.set('birth', '');
this.set('name2', '');
this.set('address2', '');
this.set('birth2', '');
if(this.get('next') == 1) {
this.get("target").transitionTo("successors.new");
}
else {
// redirect to newly created entry
this.get("target").transitionTo("successors.successor", successor);
}
}
}
});
window.locale = {
"en-US": {
"_successors": "Legal Successors",
"_successor": "Legal Successor",
"_addsuccessor": "Add Legal Successor",
"_substitute": "Substitute Successor",
"_assets": "Network Assets",
"_asset": "Network Asset",
"_addasset": "Network Asset",
"_add": "add",
"_name": "Name",
"_uri": "URI",
"_login": "Login/ID",
"_pass": "Password",
"_mail": "Mail",
"_ordered": "is ordered to",
"_preordered": "The successor is ordered to",
"_postordered": "the asset",
"_save": "Save",
"_savenext": "Save and add another",
"_cancel": "Cancel",
"_remove": "Remove",
"_edit": "Edit",
"_notes": "Special Notes",
"_address": "Address",
"_birth": "Birth Date",
"_testament": "View Testament",
"_print": "This is the complete digital testament.",
"_doprint": "Print it",
"_ttitle": "My Digital Testament",
"_appoint1": "I, ",
"_appoint2": ", being of sound mind and disposing memory, hereby appoint the following person as my legal "
+"successor for the listed network assets after my death:",
"_appoint3": "If the above person doesn't live anymore or cannot be "
+"found, this shall be the replacement legal successor:",
"_selftitle": "Information about yourself",
"_self": "Yourself",
"_place": "Place",
"_date": "Date",
"_sign": "Signature",
"_welcome": "Welcome to DigiProof",
"_intro": "You can use DigiProof to generate a digital testament. "
+"Enter your data, print it out, sign it and hand it to your solicitor.",
"_fill": "Data you have to enter",
"_fill_self": "Personal information about yourself",
"_fill_successor": "Information about your legal successor(s)",
"_fill_asset": "Information about network assets (logins, passwords)"
+" and how the successor has to handle it",
"_enterself": "Enter data about yourself",
"_entersuccessor": "Enter successors",
"_enterasset": "Enter network assets",
"_has_self": "You already entered data about yourself",
"_has_no_self": "You didn't yet enter data about yourself",
"_has_successor": "You already entered one or more successors",
"_has_no_successor": "You didn't yet enter any succesor",
"_has_asset": "You already entered one or more network assets",
"_has_no_asset": "You didn't yet enter yet any network assets",
"_data": "Manage Data",
"_export": "Export Data",
"_import": "Import Data",
"_exporthelp": "Copy the contents of the box into a textfile "
+"and save that somewhere. You can use it later to restore "
+"informations:",
"_importdone": "Data imported",
"_importhelp": "Paste previously exported data in here to restore your informations",
"_successorsindex": "This is the list of your legal successors. You may add one or "
+"more persons but you can leave it out as well. In this case the regular lawful successor "
+"will be responsible for your network assets. The regular successor is the person or "
+"persons you appoint in your official testament or are appointed by law according to "
+"legal order of succession.",
"_assetsindex": "This is the list of your network assets. A network asset is usually "
+"an account on a website, email accounts, social network account or webhosting credentials. "
+"Specify as much detail of the resource as possible so that your successor will be "
+"able to properly manage it after your death.",
"_error_address": "Address required",
"_error_birth": "Birth date required",
"_error_name": "Name required",
"_error_password": "Password required",
"_dataindex": "Maintain your data, save it for future uses and restore it from previous backups",
"_importpass": "Import password",
"_error_decrypt": "Failed to decrypt imported data",
"_error_order": "Select an order",
"_error_successor": "Select a legal successor",
"_importagain": "Import again",
"_download": "Save data to disk",
"_up_file": "Or, import from a previously exported file",
"_up_select": "Select Importfile",
"_up_change": "Change",
"_up_remove": "Remove",
"_successorshall": "My legal successor shall maintain the following network assets "
+"as ordered per asset.",
"_nopasswd": "No personal password has been set. Go to the 'Yourself' settings, "
+"enter one and then come back here",
"_testamentempty": "You have not entered any network assets and no legal successor, therefore you cannot print a testament yet. Start here: "
},
"de": {
"_successors": "Rechtsnachfolger",
"_successor": "Rechtsnachfolger",
"_addsuccessor": "Rechtsnachfolger Hinzufügen",
"_substitute": "Ersatzrechtsnachfolger",
"_assets": "Netzaccounts",
"_asset": "Netzaccount",
"_addasset": "Netzaccount hinzufügen",
"_add": "neu",
"_name": "Bezeichnung",
"_uri": "URL",
"_login": "Benutzername",
"_pass": "Passwort",
"_mail": "E-Mail",
"_ordered": "wird beauftragt",
"_preordered": "Der Rechtsnachfolger wird beauftragt, den Netzaccount",
"_postordered": "",
"_save": "Speichern",
"_savenext": "Speichern und Fortfahren",
"_cancel": "Abbrechen",
"_edit": "Bearbeiten",
"_remove": "Entfernen",
"_notes": "Besondere Hinweise",
"_birth": "Geburtsdatum",
"_testament": "Testament Anschauen",
"_address": "Adresse",
"_print": "Dies ist das vollständige digitale Testament.",
"_doprint": "Ausdrucken",
"_ttitle": "Mein digitales Testament",
"_appoint1": "Hiermit bestimme ich, ",
"_appoint2": ", im Vollbesitz meiner geistigen Kräfte, die folgende Person als Rechtsnachfolger "
+"für die aufgeführten Netzwerkaccounts nach meinem Tode:",
"_appoint3": "Falls die oben aufgeführte Person nicht mehr leben sollte "
+"oder unauffindbar sein, so soll dies der Ersatzrechtsnachfolger "
+"sein:",
"_successorshall": "Mein Rechtsnachfolger soll sich um die im folgenden "
+"aufgelisteten Netzaccounts den dabeistehenden Anweisungen entsprechend "
+"kümmern.",
"_selftitle": "Angaben über Sie",
"_self": "Eigene Angaben",
"_place": "Ort",
"_date": "Datum",
"_sign": "Unterschrift",
"_welcome": "Willkommen bei DigiProof",
"_intro": "Sie können DigiProof verwenden, um ein digitales Testament "
+"zu erstellen. Machen Sie Ihre Angaben, drucken Sie das Testament aus,"
+"unterschreiben Sie es und hinterlegen Sie es bei Ihrem Notar.",
"_fill": "Erforderliche Angaben",
"_fill_self": "Persönliche Angaben über Sie selbst",
"_fill_successor": "Informationen über Ihre(n) Rechtsnachfolger (Erbe)",
"_fill_asset": "Informationen über Netzwerkaccounts (Benutzernamen, "
+"Passwörter) und wie Ihr Erbe damit verfahren soll",
"_enterself": "Persönliche Angaben Eingeben",
"_entersuccessor": "Rechtsnachfolger Eingeben",
"_enterasset": "Netzwerkaccounts Eingeben",
"_has_self": "Sie haben bereits persönliche Angaben gemacht",
"_has_no_self": "Sie haben noch keine persönliche Angaben gemacht",
"_has_successor": "Sie haben bereits einen oder mehrere Rechtsnachfolger eingegeben",
"_has_no_successor": "Sie haben noch keinen Rechtsnachfolger eingegeben",
"_has_asset": "Sie haben bereits einen oder mehrere Netzwerkaccounts eingegeben",
"_has_no_asset": "Sie haben noch keine Netzwerkaccounts eingegeben",
"_data": "Daten Verwalten",
"_export": "Daten Exportieren",
"_import": "Daten Importieren",
"_importdone": "Daten wurden importiert",
"_exporthelp": "Kopieren Sie den Inhalt der Box in eine Textdatei und "
+"speichern Sie sie ab. Sie können damit Ihre Eingaben später "
+"wieder herstellen:",
"_dataindex": "Hier können Sie Ihre Daten verwalten, für die Zukunft sichern und wiederherstellen.",
"_importhelp": "Fügen Sie hier den Inhalt eines vorherigen Exports hinein um Ihre Daten wiederherzustellen",
"_successorsindex": "Dies ist die Liste Ihrer Rechtsnachfolger. Sie können eine oder "
+"mehrere Personen bestimmen, die sich nach Ihrem Tode um Ihre Netzwerkaccounts kümmern "
+"sollen. Sie können diesen Teil aber auch weglassen. In dem Fall werden Ihre legalen "
+"Erben, bestimmt durch Testament oder gesetzliche Erbfolge, für Ihre Accounts zuständig.",
"_assetsindex": "Dies ist die Liste Ihrer Netzwerkaccounts. Dabei handelt es sich um "
+"Zugänge zu Webseiten, Foren, sozialen Netzwerken, Email oder auch Webhosting. Geben Sie "
+"so viele Details wie möglich an, umso besser wird sich Ihr Rechtsnachfolger nach Ihrem "
+"Ableben darum kümmern können.",
"_error_address": "Addresse erforderlich",
"_error_birth": "Geburtsdatum erforderlich",
"_error_name": "Name erforderlich",
"_error_password": "Passwort erforderlich",
"_importpass": "Import Passwort",
"_error_decrypt": "Entschlüsseln der importierten Daten fehlgeschlagen",
"_error_order": "Wählen Sie einen Auftrag",
"_error_successor": "Wählen Sie einen Rechtsnachfolger",
"_importagain": "Import Wiederholen",
"_download": "Daten auf die Festplatte Speichern",
"_up_file": "Oder, verwenden Sie eine vorher exportierte Datei",
"_up_select": "Importdatei Auswählen",
"_up_change": "Ändern",
"_up_remove": "Entfernen",
"_nopasswd": "Es wurde bisher noch kein Passwort eingestellt. Gehen Sie zu 'Eigene Angaben', "
+"stellen Sie dort ein Passwort ein und versuchen Sie es dann erneut",
"_testamentempty": "Sie haben noch keine Netzwerkaccounts und keine Rechtsnachfolger eingeben, "
+"daher können Sie noch kein Testament ausdrucken. Beginnen Sie mit der Dateneingabe hier: "
}
};
// locale helper for use in app.js, not for templates
function translate(key) {
var locale = window.locale[lang] || window.locale['en-US'];
if(key) {
if(key in locale) {
return locale[key];
}
else {
return '__UNTRANSLATED_STRING__(' + key + ')';
}
}
else {
return '';
}
}
// https://gist.github.com/tracend/3261055
Ember.Handlebars.registerBoundHelper('loc', function(keyword, options) {
// pick the right dictionary
var locale = window.locale[lang] || window.locale['en-US'];
// loop through all the key hierarchy (if any)
var target = locale;
//console.log("key: %o", [keyword, options.data.properties[0]]);
var key;
if(keyword) {
key = keyword;
}
else {
key = options.data.properties[0];
}
keyword = '';
options.data.properties[0] = '';
if(key) {
if(key in locale) {
return locale[key];
}
else {
return '__UNTRANSLATED_STRING__(' + key + ')';
}
}
else {
return '';
}
});
Ember.Handlebars.registerBoundHelper('ifeq', function(v1, v2, options) {
return (this.get(v1) == v2) ? options.fn(this) : '';
});
Ember.Handlebars.registerBoundHelper('date', function(date) {
moment().lang(lang);
return moment(date).format('LL');
});
Ember.Handlebars.registerBoundHelper('encrypt', function(cleartext) {
pass = App.Self.find(0).get('password');
if(pass) {
var enpass = CryptoJS.SHA512(pass).toString(CryptoJS.enc.Base64);
//console.log("pass: %s, enpass: %s", pass, enpass);
var cr = CryptoJS.AES.encrypt(escape(cleartext), enpass);
return cr;
}
else {
return "Failed to encrypt, not password set";
}
});