);
}
// Display the total cost
- final_cost(){
+ final_cost(conv){
let disps='';
if(projectduration>1) disps='s';
+ let convout='';
+ if (conv.Enable) {
+ let value=Money.convert(this.state.total);
+ value=tomoney(value,conv.Cur);
+ convout=;
+ }
return(
{/**/}
Total Cost for {projectduration} year{disps}
+ {convout}
);
}
// Define the head (top) of the page
page_head(){
return(
EPFL Library Cost Calculator for Data Management
Welcome to our cost calculator this tool will help researcher to have an
estimate of the cost of managing, storing and publishing data.
Many providers are included in the service and you will be able to calculate a cost
based on your needs.
Total cost is calculated dynamically based on your inputs.
We hope you will enjoy this tool and it will be useful for you.
);
}
//Define the foot (bottom) of the page
page_foot(){
return(
The values published on this service are only informative and cannot be used for exact calculation. If you see some mistake or would like to
have another services please contact us.
Last Database Update : {MainData.Updated}
This service has been developed by the Resarch Data Management Team of the EPFL Library
This software is publish under GPL-3.0-only license and your are using Version {MainData.Version}
Source code can be download here
Icons are from the Noun Project (Book by Randi NI, Storage by I Pitu, Database by Novalyi, data cloud by Vectors Market, Information and Next by Gregor Cresnar, Database by Creative Mahira)
);
}
// Define the howto (user guide)
howto(){
return(
HOWTO
Categories
This tool is divided by categories (for example Activate storage). Click
on the category name, and it will expand.
Providers
Providers can be chosen from the Select a provider box. You can then tune your setting for this provider to fit your needs.
If the provider you want is not registered, you can add it manually with Provide your own provider and then enter your provider/service and cost.
Add or Remove Line
If you want to add a new provider use the }
tips={"Add a new category"} onClick={this.fctnull}/> button.
You can also remove a provider with }
tips={"Remove this line"} onClick={this.fctnull}/> button.
To know more about
Some extra information about the category or the provider can be obtained with the }
tips={"Know more"} onClick={this.fctnull}/> button.
Comments your input
Comments are for your own usage, you can use for remembering what each section is and for a nice export.
Export
You can export your work into different format : HTML : This format can be used in any wordprocessing software (such as Microsoft Word or Libreoffice). HTML Source code, Markdown, and CSV formats are also possible.
Click on the in order to copy your work into your clipboard. A simple Paste will transfer your work into any software.
);
}
// Function use by the howto btn to move the page
move2howto(){
$('html,body').animate({
scrollTop: $("#howto").offset().top},
'slow');
}
fctnull(){}
}
//Main Declaration
// ---------------------
// ---------------------
ReactDOM.render(,document.getElementById('root'));
$(function () {
$('[data-toggle="tooltip"]').tooltip()
});
diff --git a/js/costcalc_money.jsx b/js/costcalc_money.jsx
new file mode 100644
index 0000000..a7c281a
--- /dev/null
+++ b/js/costcalc_money.jsx
@@ -0,0 +1,112 @@
+"use strict";
+// Money is the http://openexchangerates.github.io/money.js/#playground Lib
+var Money = fx.noConflict();
+// Become true if money conv is configured and connected correctly
+var Money_Enable=false;
+
+class CurrencySelect extends React.Component {
+ constructor(props) {
+ super(props);
+ this.handleCurChange = this.handleCurChange.bind(this);
+ let selectable=MainData.Conv;
+ selectable.unshift(MainData.Currency);
+ this.state={
+ Enable:false,
+ SelectCur : 0,
+ Cur : selectable[0],
+ Selectable: selectable,
+ prevselec:-1,
+ };
+ //this.make_export();
+ this.moneyset(0);
+ }
+
+ moneyset(select){
+ Money.settings =
+ {
+ from: MainData.Currency,
+ to: this.state.Selectable[select],
+ };
+ }
+ handleCurChange(select) {
+ if(select==='0'){
+ this.setState({Enable: false});
+ }
+ else{
+ this.setState({Enable: true});
+ }
+ this.setState({SelectCur: select});
+ this.setState({Cur: this.state.Selectable[select]});
+ this.moneyset(select);
+ }
+ // make_export(){
+ // this.export=[
+ // {Name:this.props.data.CurName,Value:Object.keys(this.props.data.Cur)[this.state.SelectCurt]},
+ // ];
+ // this.props.export(this.export);
+ // }
+ componentDidUpdate(){
+ // this.makecost(this.state.Cat);
+ // this.make_export();
+ if(this.state.prevselec!==this.state.SelectCur) {
+ this.props.money({Enable: this.state.Enable, Cur: this.state.Cur});
+ this.state.prevselec = this.state.SelectCur;
+ }
+
+ }
+ render() {
+ if (Money_Enable) {
+ if(this.state.Enable){
+ let r = Money.convert(1).toFixed(2);;
+ let rate = '1' + MainData.Currency + '=' + r + this.state.Cur;
+ return (
+
+ );
+ }else{
+ return(
+
+ );
+ }
+ } else {
+ return (null);
+ }
+ }
+ makecost(cat) {
+ var total=cat;
+ total=tomoney(total);
+ this.props.onCostChange(this.props.n,total);
+ return total;
+ }
+}
+
+/**
+ * @return {boolean}
+ */
+function Money_GetRates(){
+ // Load exchange rates data via AJAX:
+ if(MainData.OEXRApi!=='') {
+ let com = $.ajax({
+ // NB: using Open Exchange Rates here, but you can use any source!
+ url:'https://openexchangerates.org/api/latest.json?app_id=' +MainData.OEXRApi,
+ dataType: 'json',
+ async: false,
+ success: function(data) {
+ Money.rates = data.rates;
+ Money.base = data.base;
+ },
+
+ })
+ .done(function(){
+ console.log("Money data loaded");
+ Money_Enable = true;
+ })
+ .fail(function(){
+ console.log("Error loading data money");
+ Money_Enable = false;
+ });
+ }
+ return Money_Enable;
+}
\ No newline at end of file
diff --git a/js/data.js b/js/data.js
index 5056945..b671bb1 100644
--- a/js/data.js
+++ b/js/data.js
@@ -1,476 +1,478 @@
// Providers
// ----------------------------------------------------
// ----------------------------------------------------
// Storage
const NasEpfl = {
Style: "AmountRatesCost",
Provider : "EPFL-VPSI",
Name:'NAS',
Url : [
{Name:'VPSI-Website',Url:'https://support.epfl.ch/help/epfl?id=epfl_service_status&service=49a363acdb34c700ef64731b8c96191f'},
{Name:'SV-IT Storage Website',Url:'https://sv-it.epfl.ch/stockage'}
],
ExtraInfo:"The first TB is free",
ByYear:true,
Adaptive:false,
AmountName: "Amount",
AmountUnit: "TB",
AmountMin : 1,
AmountMax : 500,
AmountStep : 1,
AmountFree:1,
AmountFreeCumulative:false,
RateName : 'Performance',
Rates : {
'Collaborative': 165,
'On-line archive': 110,
'Raw': 55
},
RateUnit : "CHF / TB"
};
const SwitchEpfl = {
Style : 'CategoryCost',
Provider : "Switch-EPFL",
Name:'Online Storage',
ByYear:true,
Url : [
{Name:'Switch Website',Url:'https://drive.switch.ch/'}
],
CatName:'Options',
Cat:{
'Cloud Based max 50GB':0,
},
CatUnit:'CHF',
};
const GoogleDriveEdu = {
Style : 'CategoryCost',
Provider : "Google Drive Educ",
Name:'Online Storage',
ByYear:true,
Adaptive:false,
ExtraInfo : "Google Storage is not recommended as the data are stored outside of Switzerland",
ExtraInfoUrl :"https://support.epfl.ch/kb_view_customer.do?sysparm_article=KB0012829",
Url : [
{Name :'Google Education Page',Url:'https://edu.google.com/?modal_active=none'}
],
CatName:'Options',
Cat:{
'Cloud Based illimited':0,
},
CatUnit:'CHF',
};
const Dropbox_perso = {
Style : 'CategoryCost',
Provider : "Dropbox Personnal",
Name:'Online Storage',
ByYear:true,
ExtraInfo : "Dropbox is not recommended as the data are stored outside of Switzerland",
ExtraInfoUrl :"https://support.epfl.ch/kb_view_customer.do?sysparm_article=KB0012829",
Url : [
{Name :'Dropbox',Url:'https://www.dropbox.com/plans?trigger=nr'}
],
CatName:'Plan',
Cat:{
'Personal Free 2Go':0,
'Personal Plus 1TB':112,
'Personal Pro 2TB':226,
},
CatUnit:'CHF',
};
const Dropbox_team = {
Style : 'AmountRatesCost',
Provider : "Dropbox for Team",
Name:'Online Storage',
ByYear:true,
ExtraInfo : "Dropbox is not recommended as the data are stored outside of Switzerland",
ExtraInfoUrl :"https://support.epfl.ch/kb_view_customer.do?sysparm_article=KB0012829",
Url : [
{Name :'Dropbox',Url:'https://www.dropbox.com/plans?trigger=nr'}
],
Adaptive:false,
AmountName: "Number of Users",
AmountUnit: "Users",
AmountMin : 1,
AmountMax : 500,
AmountStep : 1,
AmountFree:0,
AmountFreeCumulative:false,
RateName : 'Plan',
Rates : {
'Standard': 136,
'Advanced': 204,
},
RateUnit : "CHF / User"
};
// ELN
const SLIMSEpfl = {
Style:'CategoryAmountRatesCost',
Provider : "EPFL-SV-IT",
Name:'SLIMS',
ByYear:true,
Url : [
{Name:'SLIMS on SV-IT Website',Url:'https://sv-it.epfl.ch/lims'},
{Name: 'Genohm (SLIMS Company)',Url:'https://www.genohm.com/'}
],
CatName:'PI Status',
Cat:{
'Full Professor':3000,
'Associate Professor':2000,
'Tenure Track Assistant Professor or Core Facility':1000
},
CatUnit:'CHF',
Adaptive:false,
AmountName: "Storage",
AmountUnit: "TB",
AmountMin : 1,
AmountMax : 100,
AmountStep : 1,
AmountFree:0,
AmountFreeCumulative:false,
RateName: 'ELN Storage',
Rates : {
'Stored on EPFL Server': 165,
},
RateUnit : "CHF / TB"
};
const ELNEpfl = {
Style : 'CategoryCost',
Provider : "ELN-EPFL",
Name:'ELN',
ByYear:true,
Url : [
{Name:'ELN Website',Url:'https://eln.epfl.ch/'}
],
CatName:'Options',
Cat:{
'Free for EPFL community':0,
},
CatUnit:'CHF',
};
const Rspace = {
Style : 'CategoryCost',
Provider : "Rspace community",
Name:'Rspace',
ByYear:true,
Url : [
{Name:'Rspace Website',Url:'https://www.researchspace.com/'}
],
CatName:'Options',
Cat:{
'Cloud Based unlimited storage and user':0,
},
CatUnit:'CHF',
};
const Benchling = {
Style : 'CategoryCost',
Provider : "Benchling",
Name:'ELN',
ByYear:true,
ExtraInfo : "The first 10GB are free",
ExtraInfoUrl :"",
Url : [
{Name :'Benchling website',Url:'https://benchling.com/academic'}
],
CatName:'Options',
Cat:{
'Cloud Based 10GB':0,
},
CatUnit:'CHF',
};
// Database
const MysqlEpfl = {
Style : 'CategoryCost',
Provider : "EPFL-VPSI",
Name:'MySql',
ByYear:true,
Adaptive:false,
Url : [
{Name:'EPFL VPSI ',Url:'https://support.epfl.ch/epfl?id=epfl_service_status&service=eb026fa0db34c700ef64731b8c96198e'}
],
CatName:'Options',
Cat:{
'MySQL max 2GB':0,
},
CatUnit:'CHF',
};
// Repository
const Zenodo = {
Style : 'CategoryCost',
Provider : "Zenodo-CERN",
Name:'Zenodo',
ByYear:false,
Adaptive:false,
Url : [
{Name:'Zenodo Website',Url:'https://www.zenodo.org/'},
{Name:'About Zenodo',Url:'http://about.zenodo.org/'},
],
CatName:'Options',
Cat:{
'Max 50GB per Dataset':0,
},
CatUnit:'CHF',
};
const C4science = {
Style : 'CategoryCost',
Provider : "EPFL-SCITAS",
Name:'C4Science',
Url : [
{Name:'C4Science Website',Url:'https://www.c4science.ch/'}
],
ByYear:true,
Adaptive:false,
ExtraInfo:'C4Science is the repository recommended by EPFL for code repository',
CatName:'Options',
Cat:{
'Free for text file':0,
},
CatUnit:'CHF',
};
const Github = {
Style: "AmountRatesCost",
Provider : "GitHub",
Name:'GitHub',
Url : [
{Name:'Github Website Pricing',Url:'https://github.com/pricing'}
],
AmountName: "Number of user",
AmountUnit: "User(s)",
Adaptive:true,
ByYear:true,
AmountMin : [1,1,5,10],
AmountMax : [100,1,100,100],
AmountStep : [1,1,1,1],
AmountFree:[0,0,0,0],
AmountFreeCumulative:false,
RateName:'Plan',
Rates:{
'OpenSource project':0,
'Developer (for one user)':81.6,
'Team (min 5 users)':104.9,
'Business Cloud':244.7
},
RateUnit:'CHF / Users',
};
const Bitbucket= {
Style: "AmountRatesCost",
Provider : "Bitbucket",
Name:'BitBucket',
Url : [
{Name:'Bitbucket Website Pricing',Url:'https://bitbucket.org/product/pricing'}
],
AmountName: "Number of user",
AmountUnit: "User(s)",
Adaptive:true,
ByYear:true,
AmountMin : [1,5,5],
AmountMax : [5,100,100],
AmountStep : [1,1,1],
AmountFree:[0,0,0],
AmountFreeCumulative:false,
RateName:'Plan',
Rates:{
'Free (up to 5 users)':0,
'Standard for growing teams (min 5 users)':24,
'Premium for large teams (min 5 users)':60,
},
RateUnit:'CHF / Users',
};
const Gitlab= {
Style: "AmountRatesCost",
Provider : "Gitlab",
Name:'Gitlab',
Url : [
{Name:'Gitlab Website Pricing',Url:'https://about.gitlab.com/pricing/'}
],
AmountName: "Number of user",
AmountUnit: "User(s)",
AmountMin : 1,
AmountMax : 100,
AmountStep : 1,
AmountFree:0,
Adaptive:false,
AmountFreeCumulative:false,
ByYear:true,
RateName:'Plan',
Rates:{
'Core Self Hosted':0,
'Free Cloud Based' : 0,
'Starter Self Hosted':48,
'Bronze Cloud based':48,
'Premium Self Hosted':228,
'Silver Cloud Based':228
},
RateUnit:'CHF / Users',
};
const Figshare = {
Style : 'CategoryCost',
Provider : "FigShare",
Name:'Figshare',
ByYear:false,
Adaptive:false,
Url : [
{Name:'Figshare website',Url:'https://figshare.com/'},
{Name:'Figshare Pricing',Url:'https://www.g2crowd.com/products/figshare/pricing'}
],
ExtraInfo:'The costs of enabling access to research data under an SNSF grant are eligible. The data archives (data repositories) have to meet the FAIR principles.',
ExtraInfoUrl:'http://www.snf.ch/SiteCollectionDocuments/snsf-general-implementation-regulations-for-the-funding-regulations-e.pdf#page=14',
CatName:'Options',
Cat:{
'Free 1GB':0,
'10GB':96,
'15GB':132,
'20GB':180
},
CatUnit:'CHF',
};
const Dryad = {
Style : 'CategoryAmountRatesCost',
Provider : "Dryad",
Name:'Dyrad',
Url : [
{Name:'Dryad Website Pricing',Url:'https://Datadryad.org/pages/payment'}
],
ByYear:false,
ExtraInfo:'The costs of enabling access to research data under an SNSF grant are eligible. The data archives (data repositories) have to meet the FAIR principles.',
ExtraInfoUrl:'http://www.snf.ch/SiteCollectionDocuments/snsf-general-implementation-regulations-for-the-funding-regulations-e.pdf#page=14',
CatName:'Options',
Cat:{
'up to 20GB if DPC covered':0,
'up to 20GB if no DPC covered':120
},
CatUnit:'CHF',
AmountName: "Storage",
AmountUnit: "GB",
Adaptive:false,
AmountMin : 20,
AmountMax : 100,
AmountStep : 10,
AmountFree:20,
AmountFreeCumulative:false,
RateName: 'Storage',
Rates : {
'Extra Storage': 50,
},
RateUnit : "CHF / GB"
};
// System variable definition
// ----------------------------------------------------
// ----------------------------------------------------
const NoneSelected={
Style: 'NoneSelect',
Provider:'None',
Name:'Select a Provider',
Url:'',
ByYear:false,
};
const UserCostSelect={
Style : 'UserCost',
Provider:'Manual Provider',
Name:'',
Url:'',
ByYear:false,
};
// Categories definition
// ----------------------------------------------------
// ----------------------------------------------------
const storage={
Name : 'Active Storage',
Icon : 'storage.png',
Url : [
{Name:'EPFL RDM',Url:'https://researchData.epfl.ch/work-with-Data/storage/'},
{Name:'Comparison of file synchronization software',Url:'https://en.wikipedia.org/wiki/Comparison_of_file_synchronization_software'}
],
Data :[NoneSelected,
NasEpfl,
SwitchEpfl,
GoogleDriveEdu,
Dropbox_perso,
Dropbox_team,
UserCostSelect,
]
};
const ELN={
Name : 'Electronic LabBook',
Icon : 'eln.png',
Url : [
{Name: 'EPFL RDM',Url:'https://researchData.epfl.ch/work-with-Data/active-Data-management/'}
],
Data :[NoneSelected,
SLIMSEpfl,
ELNEpfl,
Rspace,
Benchling,
UserCostSelect,
]
};
const Database={
Name : 'Database',
Icon : 'database.png',
Url : '',
Data :[NoneSelected,
MysqlEpfl,
UserCostSelect,
]
};
const datarepository={
Name : 'Data Repository',
Icon : 'drepos.png',
Url : [
{Name:'EPFL RDM WebPage',Url:'https://researchData.epfl.ch/publish-preserve/'}
],
Data :[
NoneSelected,
Zenodo,
Figshare,
Dryad,
UserCostSelect,
]
};
const coderepository={
Name : 'Collaborative Repository',
Icon : 'crepos.png',
Url : '',
Data :[
NoneSelected,
C4science,
Github,
Bitbucket,
Gitlab,
UserCostSelect,
]
};
// Combine Categories
// ----------------------------------------------------
// ----------------------------------------------------
const MainData={
Updated:'30/01/2019',
HelpUrl:'mailto:researchdata@epfl.ch',
Currency:'CHF',
+ OEXRApi:'cd8d785bdb6646b0a7e4c0eba5a74199',
+ Conv:['EUR','USD','GBP'],
Version : 'v1.5',
DefaultDuration:1,
Data:[storage,ELN,Database,datarepository,coderepository],
};
diff --git a/js/money.js b/js/money.js
new file mode 100644
index 0000000..359df37
--- /dev/null
+++ b/js/money.js
@@ -0,0 +1,166 @@
+/*!
+ * money.js / fx() v0.2
+ * Copyright 2014 Open Exchange Rates
+ *
+ * JavaScript library for realtime currency conversion and exchange rate calculation.
+ *
+ * Freely distributable under the MIT license.
+ * Portions of money.js are inspired by or borrowed from underscore.js
+ *
+ * For details, examples and documentation:
+ * http://openexchangerates.github.io/money.js/
+ */
+(function(root, undefined) {
+
+ // Create a safe reference to the money.js object for use below.
+ var fx = function(obj) {
+ return new fxWrapper(obj);
+ };
+
+ // Current version.
+ fx.version = '0.2';
+
+
+ /* --- Setup --- */
+
+ // fxSetup can be defined before loading money.js, to set the exchange rates and the base
+ // (and default from/to) currencies - or the rates can be loaded in later if needed.
+ var fxSetup = root.fxSetup || {
+ rates : {},
+ base : ""
+ };
+
+ // Object containing exchange rates relative to the fx.base currency, eg { "GBP" : "0.64" }
+ fx.rates = fxSetup.rates;
+
+ // Default exchange rate base currency (eg "USD"), which all the exchange rates are relative to
+ fx.base = fxSetup.base;
+
+ // Default from / to currencies for conversion via fx.convert():
+ fx.settings = {
+ from : fxSetup.from || fx.base,
+ to : fxSetup.to || fx.base
+ };
+
+
+ /* --- Conversion --- */
+
+ // The base function of the library: converts a value from one currency to another
+ var convert = fx.convert = function(val, opts) {
+ // Convert arrays recursively
+ if (typeof val === 'object' && val.length) {
+ for (var i = 0; i< val.length; i++ ) {
+ val[i] = convert(val[i], opts);
+ }
+ return val;
+ }
+
+ // Make sure we gots some opts
+ opts = opts || {};
+
+ // We need to know the `from` and `to` currencies
+ if( !opts.from ) opts.from = fx.settings.from;
+ if( !opts.to ) opts.to = fx.settings.to;
+
+ // Multiple the value by the exchange rate
+ return val * getRate( opts.to, opts.from );
+ };
+
+ // Returns the exchange rate to `target` currency from `base` currency
+ var getRate = function(to, from) {
+ // Save bytes in minified version
+ var rates = fx.rates;
+
+ // Make sure the base rate is in the rates object:
+ rates[fx.base] = 1;
+
+ // Throw an error if either rate isn't in the rates array
+ if ( !rates[to] || !rates[from] ) throw "fx error";
+
+ // If `from` currency === fx.base, return the basic exchange rate for the `to` currency
+ if ( from === fx.base ) {
+ return rates[to];
+ }
+
+ // If `to` currency === fx.base, return the basic inverse rate of the `from` currency
+ if ( to === fx.base ) {
+ return 1 / rates[from];
+ }
+
+ // Otherwise, return the `to` rate multipled by the inverse of the `from` rate to get the
+ // relative exchange rate between the two currencies
+ return rates[to] * (1 / rates[from]);
+ };
+
+
+ /* --- OOP wrapper and chaining --- */
+
+ // If fx(val) is called as a function, it returns a wrapped object that can be used OO-style
+ var fxWrapper = function(val) {
+ // Experimental: parse strings to pull out currency code and value:
+ if ( typeof val === "string" ) {
+ this._v = parseFloat(val.replace(/[^0-9-.]/g, ""));
+ this._fx = val.replace(/([^A-Za-z])/g, "");
+ } else {
+ this._v = val;
+ }
+ };
+
+ // Expose `wrapper.prototype` as `fx.prototype`
+ var fxProto = fx.prototype = fxWrapper.prototype;
+
+ // fx(val).convert(opts) does the same thing as fx.convert(val, opts)
+ fxProto.convert = function() {
+ var args = Array.prototype.slice.call(arguments);
+ args.unshift(this._v);
+ return convert.apply(fx, args);
+ };
+
+ // fx(val).from(currency) returns a wrapped `fx` where the value has been converted from
+ // `currency` to the `fx.base` currency. Should be followed by `.to(otherCurrency)`
+ fxProto.from = function(currency) {
+ var wrapped = fx(convert(this._v, {from: currency, to: fx.base}));
+ wrapped._fx = fx.base;
+ return wrapped;
+ };
+
+ // fx(val).to(currency) returns the value, converted from `fx.base` to `currency`
+ fxProto.to = function(currency) {
+ return convert(this._v, {from: this._fx ? this._fx : fx.settings.from, to: currency});
+ };
+
+
+ /* --- Module Definition --- */
+
+ // Export the fx object for CommonJS. If being loaded as an AMD module, define it as such.
+ // Otherwise, just add `fx` to the global object
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = fx;
+ }
+ exports.fx = fx;
+ } else if (typeof define === 'function' && define.amd) {
+ // Return the library as an AMD module:
+ define([], function() {
+ return fx;
+ });
+ } else {
+ // Use fx.noConflict to restore `fx` back to its original value before money.js loaded.
+ // Returns a reference to the library's `fx` object; e.g. `var money = fx.noConflict();`
+ fx.noConflict = (function(previousFx) {
+ return function() {
+ // Reset the value of the root's `fx` variable:
+ root.fx = previousFx;
+ // Delete the noConflict function:
+ fx.noConflict = undefined;
+ // Return reference to the library to re-assign it:
+ return fx;
+ };
+ })(root.fx);
+
+ // Declare `fx` on the root (global/window) object:
+ root['fx'] = fx;
+ }
+
+ // Root will be `window` in browser or `global` on the server:
+}(this));
diff --git a/js/money.min.js b/js/money.min.js
new file mode 100644
index 0000000..0b22ca2
--- /dev/null
+++ b/js/money.min.js
@@ -0,0 +1,2 @@
+/* money.js 0.2, MIT license, http://openexchangerates.github.io/money.js */
+(function(g,j){var b=function(a){return new i(a)};b.version="0.1.3";var c=g.fxSetup||{rates:{},base:""};b.rates=c.rates;b.base=c.base;b.settings={from:c.from||b.base,to:c.to||b.base};var h=b.convert=function(a,e){if("object"===typeof a&&a.length){for(var d=0;d