/*!
 * typeahead.js 0.10.2
 * https://github.com/twitter/typeahead.js
 * Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT
 */

(function($) {
    var _ = {
        isMsie: function() {
            return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
        },
        isBlankString: function(str) {
            return !str || /^\s*$/.test(str);
        },
        escapeRegExChars: function(str) {
            return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
        },
        isString: function(obj) {
            return typeof obj === "string";
        },
        isNumber: function(obj) {
            return typeof obj === "number";
        },
        isArray: $.isArray,
        isFunction: $.isFunction,
        isObject: $.isPlainObject,
        isUndefined: function(obj) {
            return typeof obj === "undefined";
        },
        bind: $.proxy,
        each: function(collection, cb) {
            $.each(collection, reverseArgs);
            function reverseArgs(index, value) {
                return cb(value, index);
            }
        },
        map: $.map,
        filter: $.grep,
        every: function(obj, test) {
            var result = true;
            if (!obj) {
                return result;
            }
            $.each(obj, function(key, val) {
                if (!(result = test.call(null, val, key, obj))) {
                    return false;
                }
            });
            return !!result;
        },
        some: function(obj, test) {
            var result = false;
            if (!obj) {
                return result;
            }
            $.each(obj, function(key, val) {
                if (result = test.call(null, val, key, obj)) {
                    return false;
                }
            });
            return !!result;
        },
        mixin: $.extend,
        getUniqueId: function() {
            var counter = 0;
            return function() {
                return counter++;
            };
        }(),
        templatify: function templatify(obj) {
            return $.isFunction(obj) ? obj : template;
            function template() {
                return String(obj);
            }
        },
        defer: function(fn) {
            setTimeout(fn, 0);
        },
        debounce: function(func, wait, immediate) {
            var timeout, result;
            return function() {
                var context = this, args = arguments, later, callNow;
                later = function() {
                    timeout = null;
                    if (!immediate) {
                        result = func.apply(context, args);
                    }
                };
                callNow = immediate && !timeout;
                clearTimeout(timeout);
                timeout = setTimeout(later, wait);
                if (callNow) {
                    result = func.apply(context, args);
                }
                return result;
            };
        },
        throttle: function(func, wait) {
            var context, args, timeout, result, previous, later;
            previous = 0;
            later = function() {
                previous = new Date();
                timeout = null;
                result = func.apply(context, args);
            };
            return function() {
                var now = new Date(), remaining = wait - (now - previous);
                context = this;
                args = arguments;
                if (remaining <= 0) {
                    clearTimeout(timeout);
                    timeout = null;
                    previous = now;
                    result = func.apply(context, args);
                } else if (!timeout) {
                    timeout = setTimeout(later, remaining);
                }
                return result;
            };
        },
        noop: function() {}
    };
    var VERSION = "0.10.2";
    var tokenizers = function(root) {
        return {
            nonword: nonword,
            whitespace: whitespace,
            obj: {
                nonword: getObjTokenizer(nonword),
                whitespace: getObjTokenizer(whitespace)
            }
        };
        function whitespace(s) {
            return s.split(/\s+/);
        }
        function nonword(s) {
            return s.split(/\W+/);
        }
        function getObjTokenizer(tokenizer) {
            return function setKey(key) {
                return function tokenize(o) {
                    return tokenizer(o[key]);
                };
            };
        }
    }();
    var LruCache = function() {
        function LruCache(maxSize) {
            this.maxSize = maxSize || 100;
            this.size = 0;
            this.hash = {};
            this.list = new List();
        }
        _.mixin(LruCache.prototype, {
            set: function set(key, val) {
                var tailItem = this.list.tail, node;
                if (this.size >= this.maxSize) {
                    this.list.remove(tailItem);
                    delete this.hash[tailItem.key];
                }
                if (node = this.hash[key]) {
                    node.val = val;
                    this.list.moveToFront(node);
                } else {
                    node = new Node(key, val);
                    this.list.add(node);
                    this.hash[key] = node;
                    this.size++;
                }
            },
            get: function get(key) {
                var node = this.hash[key];
                if (node) {
                    this.list.moveToFront(node);
                    return node.val;
                }
            }
        });
        function List() {
            this.head = this.tail = null;
        }
        _.mixin(List.prototype, {
            add: function add(node) {
                if (this.head) {
                    node.next = this.head;
                    this.head.prev = node;
                }
                this.head = node;
                this.tail = this.tail || node;
            },
            remove: function remove(node) {
                node.prev ? node.prev.next = node.next : this.head = node.next;
                node.next ? node.next.prev = node.prev : this.tail = node.prev;
            },
            moveToFront: function(node) {
                this.remove(node);
                this.add(node);
            }
        });
        function Node(key, val) {
            this.key = key;
            this.val = val;
            this.prev = this.next = null;
        }
        return LruCache;
    }();
    var PersistentStorage = function() {
        var ls, methods;
        try {
            ls = window.localStorage;
            ls.setItem("~~~", "!");
            ls.removeItem("~~~");
        } catch (err) {
            ls = null;
        }
        function PersistentStorage(namespace) {
            this.prefix = [ "__", namespace, "__" ].join("");
            this.ttlKey = "__ttl__";
            this.keyMatcher = new RegExp("^" + this.prefix);
        }
        if (ls && window.JSON) {
            methods = {
                _prefix: function(key) {
                    return this.prefix + key;
                },
                _ttlKey: function(key) {
                    return this._prefix(key) + this.ttlKey;
                },
                get: function(key) {
                    if (this.isExpired(key)) {
                        this.remove(key);
                    }
                    return decode(ls.getItem(this._prefix(key)));
                },
                set: function(key, val, ttl) {
                    if (_.isNumber(ttl)) {
                        ls.setItem(this._ttlKey(key), encode(now() + ttl));
                    } else {
                        ls.removeItem(this._ttlKey(key));
                    }
                    return ls.setItem(this._prefix(key), encode(val));
                },
                remove: function(key) {
                    ls.removeItem(this._ttlKey(key));
                    ls.removeItem(this._prefix(key));
                    return this;
                },
                clear: function() {
                    var i, key, keys = [], len = ls.length;
                    for (i = 0; i < len; i++) {
                        if ((key = ls.key(i)).match(this.keyMatcher)) {
                            keys.push(key.replace(this.keyMatcher, ""));
                        }
                    }
                    for (i = keys.length; i--; ) {
                        this.remove(keys[i]);
                    }
                    return this;
                },
                isExpired: function(key) {
                    var ttl = decode(ls.getItem(this._ttlKey(key)));
                    return _.isNumber(ttl) && now() > ttl ? true : false;
                }
            };
        } else {
            methods = {
                get: _.noop,
                set: _.noop,
                remove: _.noop,
                clear: _.noop,
                isExpired: _.noop
            };
        }
        _.mixin(PersistentStorage.prototype, methods);
        return PersistentStorage;
        function now() {
            return new Date().getTime();
        }
        function encode(val) {
            return JSON.stringify(_.isUndefined(val) ? null : val);
        }
        function decode(val) {
            return JSON.parse(val);
        }
    }();
    var Transport = function() {
        var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, requestCache = new LruCache(10);
        function Transport(o) {
            o = o || {};
            this._send = o.transport ? callbackToDeferred(o.transport) : $.ajax;
            this._get = o.rateLimiter ? o.rateLimiter(this._get) : this._get;
        }
        Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
            maxPendingRequests = num;
        };
        Transport.resetCache = function clearCache() {
            requestCache = new LruCache(10);
        };
        _.mixin(Transport.prototype, {
            _get: function(url, o, cb) {
                var that = this, jqXhr;
                if (jqXhr = pendingRequests[url]) {
                    jqXhr.done(done).fail(fail);
                } else if (pendingRequestsCount < maxPendingRequests) {
                    pendingRequestsCount++;
                    pendingRequests[url] = this._send(url, o).done(done).fail(fail).always(always);
                } else {
                    this.onDeckRequestArgs = [].slice.call(arguments, 0);
                }
                function done(resp) {
                    cb && cb(null, resp);
                    requestCache.set(url, resp);
                }
                function fail() {
                    cb && cb(true);
                }
                function always() {
                    pendingRequestsCount--;
                    delete pendingRequests[url];
                    if (that.onDeckRequestArgs) {
                        that._get.apply(that, that.onDeckRequestArgs);
                        that.onDeckRequestArgs = null;
                    }
                }
            },
            get: function(url, o, cb) {
                var resp;
                if (_.isFunction(o)) {
                    cb = o;
                    o = {};
                }
                if (resp = requestCache.get(url)) {
                    _.defer(function() {
                        cb && cb(null, resp);
                    });
                } else {
                    this._get(url, o, cb);
                }
                return !!resp;
            }
        });
        return Transport;
        function callbackToDeferred(fn) {
            return function customSendWrapper(url, o) {
                var deferred = $.Deferred();
                fn(url, o, onSuccess, onError);
                return deferred;
                function onSuccess(resp) {
                    _.defer(function() {
                        deferred.resolve(resp);
                    });
                }
                function onError(err) {
                    _.defer(function() {
                        deferred.reject(err);
                    });
                }
            };
        }
    }();
    var SearchIndex = function() {
        function SearchIndex(o) {
            o = o || {};
            if (!o.datumTokenizer || !o.queryTokenizer) {
                $.error("datumTokenizer and queryTokenizer are both required");
            }
            this.datumTokenizer = o.datumTokenizer;
            this.queryTokenizer = o.queryTokenizer;
            this.reset();
        }
        _.mixin(SearchIndex.prototype, {
            bootstrap: function bootstrap(o) {
                this.datums = o.datums;
                this.trie = o.trie;
            },
            add: function(data) {
                var that = this;
                data = _.isArray(data) ? data : [ data ];
                _.each(data, function(datum) {
                    var id, tokens;
                    id = that.datums.push(datum) - 1;
                    tokens = normalizeTokens(that.datumTokenizer(datum));
                    _.each(tokens, function(token) {
                        var node, chars, ch;
                        node = that.trie;
                        chars = token.split("");
                        while (ch = chars.shift()) {
                            node = node.children[ch] || (node.children[ch] = newNode());
                            node.ids.push(id);
                        }
                    });
                });
            },
            get: function get(query) {
                var that = this, tokens, matches;
                tokens = normalizeTokens(this.queryTokenizer(query));
                _.each(tokens, function(token) {
                    var node, chars, ch, ids;
                    if (matches && matches.length === 0) {
                        return false;
                    }
                    node = that.trie;
                    chars = token.split("");
                    while (node && (ch = chars.shift())) {
                        node = node.children[ch];
                    }
                    if (node && chars.length === 0) {
                        ids = node.ids.slice(0);
                        matches = matches ? getIntersection(matches, ids) : ids;
                    } else {
                        matches = [];
                        return false;
                    }
                });
                return matches ? _.map(unique(matches), function(id) {
                    return that.datums[id];
                }) : [];
            },
            reset: function reset() {
                this.datums = [];
                this.trie = newNode();
            },
            serialize: function serialize() {
                return {
                    datums: this.datums,
                    trie: this.trie
                };
            }
        });
        return SearchIndex;
        function normalizeTokens(tokens) {
            tokens = _.filter(tokens, function(token) {
                return !!token;
            });
            tokens = _.map(tokens, function(token) {
                return token.toLowerCase();
            });
            return tokens;
        }
        function newNode() {
            return {
                ids: [],
                children: {}
            };
        }
        function unique(array) {
            var seen = {}, uniques = [];
            for (var i = 0; i < array.length; i++) {
                if (!seen[array[i]]) {
                    seen[array[i]] = true;
                    uniques.push(array[i]);
                }
            }
            return uniques;
        }
        function getIntersection(arrayA, arrayB) {
            var ai = 0, bi = 0, intersection = [];
            arrayA = arrayA.sort(compare);
            arrayB = arrayB.sort(compare);
            while (ai < arrayA.length && bi < arrayB.length) {
                if (arrayA[ai] < arrayB[bi]) {
                    ai++;
                } else if (arrayA[ai] > arrayB[bi]) {
                    bi++;
                } else {
                    intersection.push(arrayA[ai]);
                    ai++;
                    bi++;
                }
            }
            return intersection;
            function compare(a, b) {
                return a - b;
            }
        }
    }();
    var oParser = function() {
        return {
            local: getLocal,
            prefetch: getPrefetch,
            remote: getRemote
        };
        function getLocal(o) {
            return o.local || null;
        }
        function getPrefetch(o) {
            var prefetch, defaults;
            defaults = {
                url: null,
                thumbprint: "",
                ttl: 24 * 60 * 60 * 1e3,
                filter: null,
                ajax: {}
            };
            if (prefetch = o.prefetch || null) {
                prefetch = _.isString(prefetch) ? {
                    url: prefetch
                } : prefetch;
                prefetch = _.mixin(defaults, prefetch);
                prefetch.thumbprint = VERSION + prefetch.thumbprint;
                prefetch.ajax.type = prefetch.ajax.type || "GET";
                prefetch.ajax.dataType = prefetch.ajax.dataType || "json";
                !prefetch.url && $.error("prefetch requires url to be set");
            }
            return prefetch;
        }
        function getRemote(o) {
            var remote, defaults;
            defaults = {
                url: null,
                wildcard: "%QUERY",
                replace: null,
                rateLimitBy: "debounce",
                rateLimitWait: 300,
                send: null,
                filter: null,
                ajax: {}
            };
            if (remote = o.remote || null) {
                remote = _.isString(remote) ? {
                    url: remote
                } : remote;
                remote = _.mixin(defaults, remote);
                remote.rateLimiter = /^throttle$/i.test(remote.rateLimitBy) ? byThrottle(remote.rateLimitWait) : byDebounce(remote.rateLimitWait);
                remote.ajax.type = remote.ajax.type || "GET";
                remote.ajax.dataType = remote.ajax.dataType || "json";
                delete remote.rateLimitBy;
                delete remote.rateLimitWait;
                !remote.url && $.error("remote requires url to be set");
            }
            return remote;
            function byDebounce(wait) {
                return function(fn) {
                    return _.debounce(fn, wait);
                };
            }
            function byThrottle(wait) {
                return function(fn) {
                    return _.throttle(fn, wait);
                };
            }
        }
    }();
    (function(root) {
        var old, keys;
        old = root.Bloodhound;
        keys = {
            data: "data",
            protocol: "protocol",
            thumbprint: "thumbprint"
        };
        root.Bloodhound = Bloodhound;
        function Bloodhound(o) {
            if (!o || !o.local && !o.prefetch && !o.remote) {
                $.error("one of local, prefetch, or remote is required");
            }
            this.limit = o.limit || 5;
            this.sorter = getSorter(o.sorter);
            this.dupDetector = o.dupDetector || ignoreDuplicates;
            this.local = oParser.local(o);
            this.prefetch = oParser.prefetch(o);
            this.remote = oParser.remote(o);
            this.cacheKey = this.prefetch ? this.prefetch.cacheKey || this.prefetch.url : null;
            this.index = new SearchIndex({
                datumTokenizer: o.datumTokenizer,
                queryTokenizer: o.queryTokenizer
            });
            this.storage = this.cacheKey ? new PersistentStorage(this.cacheKey) : null;
        }
        Bloodhound.noConflict = function noConflict() {
            root.Bloodhound = old;
            return Bloodhound;
        };
        Bloodhound.tokenizers = tokenizers;
        _.mixin(Bloodhound.prototype, {
            _loadPrefetch: function loadPrefetch(o) {
                var that = this, serialized, deferred;
                if (serialized = this._readFromStorage(o.thumbprint)) {
                    this.index.bootstrap(serialized);
                    deferred = $.Deferred().resolve();
                } else {
                    deferred = $.ajax(o.url, o.ajax).done(handlePrefetchResponse);
                }
                return deferred;
                function handlePrefetchResponse(resp) {
                    that.clear();
                    that.add(o.filter ? o.filter(resp) : resp);
                    that._saveToStorage(that.index.serialize(), o.thumbprint, o.ttl);
                }
            },
            _getFromRemote: function getFromRemote(query, cb) {
                var that = this, url, uriEncodedQuery;
                query = query || "";
                uriEncodedQuery = encodeURIComponent(query);
                url = this.remote.replace ? this.remote.replace(this.remote.url, query) : this.remote.url.replace(this.remote.wildcard, uriEncodedQuery);
                return this.transport.get(url, this.remote.ajax, handleRemoteResponse);
                function handleRemoteResponse(err, resp) {
                    err ? cb([]) : cb(that.remote.filter ? that.remote.filter(resp) : resp);
                }
            },
            _saveToStorage: function saveToStorage(data, thumbprint, ttl) {
                if (this.storage) {
                    this.storage.set(keys.data, data, ttl);
                    this.storage.set(keys.protocol, location.protocol, ttl);
                    this.storage.set(keys.thumbprint, thumbprint, ttl);
                }
            },
            _readFromStorage: function readFromStorage(thumbprint) {
                var stored = {}, isExpired;
                if (this.storage) {
                    stored.data = this.storage.get(keys.data);
                    stored.protocol = this.storage.get(keys.protocol);
                    stored.thumbprint = this.storage.get(keys.thumbprint);
                }
                isExpired = stored.thumbprint !== thumbprint || stored.protocol !== location.protocol;
                return stored.data && !isExpired ? stored.data : null;
            },
            _initialize: function initialize() {
                var that = this, local = this.local, deferred;
                deferred = this.prefetch ? this._loadPrefetch(this.prefetch) : $.Deferred().resolve();
                local && deferred.done(addLocalToIndex);
                this.transport = this.remote ? new Transport(this.remote) : null;
                return this.initPromise = deferred.promise();
                function addLocalToIndex() {
                    that.add(_.isFunction(local) ? local() : local);
                }
            },
            initialize: function initialize(force) {
                return !this.initPromise || force ? this._initialize() : this.initPromise;
            },
            add: function add(data) {
                this.index.add(data);
            },
            get: function get(query, cb) {
                var that = this, matches = [], cacheHit = false;
                matches = this.index.get(query);
                matches = this.sorter(matches).slice(0, this.limit);
                if (matches.length < this.limit && this.transport) {
                    cacheHit = this._getFromRemote(query, returnRemoteMatches);
                }
                if (!cacheHit) {
                    (matches.length > 0 || !this.transport) && cb && cb(matches);
                }
                function returnRemoteMatches(remoteMatches) {
                    var matchesWithBackfill = matches.slice(0);
                    _.each(remoteMatches, function(remoteMatch) {
                        var isDuplicate;
                        isDuplicate = _.some(matchesWithBackfill, function(match) {
                            return that.dupDetector(remoteMatch, match);
                        });
                        !isDuplicate && matchesWithBackfill.push(remoteMatch);
                        return matchesWithBackfill.length < that.limit;
                    });
                    cb && cb(that.sorter(matchesWithBackfill));
                }
            },
            clear: function clear() {
                this.index.reset();
            },
            clearPrefetchCache: function clearPrefetchCache() {
                this.storage && this.storage.clear();
            },
            clearRemoteCache: function clearRemoteCache() {
                this.transport && Transport.resetCache();
            },
            ttAdapter: function ttAdapter() {
                return _.bind(this.get, this);
            }
        });
        return Bloodhound;
        function getSorter(sortFn) {
            return _.isFunction(sortFn) ? sort : noSort;
            function sort(array) {
                return array.sort(sortFn);
            }
            function noSort(array) {
                return array;
            }
        }
        function ignoreDuplicates() {
            return false;
        }
    })(this);
    var html = {
        wrapper: '<span class="twitter-typeahead"></span>',
        dropdown: '<span class="tt-dropdown-menu"></span>',
        dataset: '<div class="tt-dataset-%CLASS%"></div>',
        suggestions: '<span class="tt-suggestions"></span>',
        suggestion: '<div class="tt-suggestion"></div>'
    };
    var css = {
        wrapper: {
            position: "relative",
            display: "inline-block"
        },
        hint: {
            position: "absolute",
            top: "0",
            left: "0",
            borderColor: "transparent",
            boxShadow: "none"
        },
        input: {
            position: "relative",
            verticalAlign: "top",
            backgroundColor: "transparent"
        },
        inputWithNoHint: {
            position: "relative",
            verticalAlign: "top"
        },
        dropdown: {
            position: "absolute",
            top: "100%",
            left: "0",
            zIndex: "100",
            display: "none"
        },
        suggestions: {
            display: "block"
        },
        suggestion: {
            whiteSpace: "nowrap",
            cursor: "pointer"
        },
        suggestionChild: {
            whiteSpace: "normal"
        },
        ltr: {
            left: "0",
            right: "auto"
        },
        rtl: {
            left: "auto",
            right: " 0"
        }
    };
    if (_.isMsie()) {
        _.mixin(css.input, {
            backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"
        });
    }
    if (_.isMsie() && _.isMsie() <= 7) {
        _.mixin(css.input, {
            marginTop: "-1px"
        });
    }
    var EventBus = function() {
        var namespace = "typeahead:";
        function EventBus(o) {
            if (!o || !o.el) {
                $.error("EventBus initialized without el");
            }
            this.$el = $(o.el);
        }
        _.mixin(EventBus.prototype, {
            trigger: function(type) {
                var args = [].slice.call(arguments, 1);
                this.$el.trigger(namespace + type, args);
            }
        });
        return EventBus;
    }();
    var EventEmitter = function() {
        var splitter = /\s+/, nextTick = getNextTick();
        return {
            onSync: onSync,
            onAsync: onAsync,
            off: off,
            trigger: trigger
        };
        function on(method, types, cb, context) {
            var type;
            if (!cb) {
                return this;
            }
            types = types.split(splitter);
            cb = context ? bindContext(cb, context) : cb;
            this._callbacks = this._callbacks || {};
            while (type = types.shift()) {
                this._callbacks[type] = this._callbacks[type] || {
                    sync: [],
                    async: []
                };
                this._callbacks[type][method].push(cb);
            }
            return this;
        }
        function onAsync(types, cb, context) {
            return on.call(this, "async", types, cb, context);
        }
        function onSync(types, cb, context) {
            return on.call(this, "sync", types, cb, context);
        }
        function off(types) {
            var type;
            if (!this._callbacks) {
                return this;
            }
            types = types.split(splitter);
            while (type = types.shift()) {
                delete this._callbacks[type];
            }
            return this;
        }
        function trigger(types) {
            var type, callbacks, args, syncFlush, asyncFlush;
            if (!this._callbacks) {
                return this;
            }
            types = types.split(splitter);
            args = [].slice.call(arguments, 1);
            while ((type = types.shift()) && (callbacks = this._callbacks[type])) {
                syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args));
                asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args));
                syncFlush() && nextTick(asyncFlush);
            }
            return this;
        }
        function getFlush(callbacks, context, args) {
            return flush;
            function flush() {
                var cancelled;
                for (var i = 0; !cancelled && i < callbacks.length; i += 1) {
                    cancelled = callbacks[i].apply(context, args) === false;
                }
                return !cancelled;
            }
        }
        function getNextTick() {
            var nextTickFn;
            if (window.setImmediate) {
                nextTickFn = function nextTickSetImmediate(fn) {
                    setImmediate(function() {
                        fn();
                    });
                };
            } else {
                nextTickFn = function nextTickSetTimeout(fn) {
                    setTimeout(function() {
                        fn();
                    }, 0);
                };
            }
            return nextTickFn;
        }
        function bindContext(fn, context) {
            return fn.bind ? fn.bind(context) : function() {
                fn.apply(context, [].slice.call(arguments, 0));
            };
        }
    }();
    var highlight = function(doc) {
        var defaults = {
            node: null,
            pattern: null,
            tagName: "strong",
            className: null,
            wordsOnly: false,
            caseSensitive: false
        };
        return function hightlight(o) {
            var regex;
            o = _.mixin({}, defaults, o);
            if (!o.node || !o.pattern) {
                return;
            }
            o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];
            regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);
            traverse(o.node, hightlightTextNode);
            function hightlightTextNode(textNode) {
                var match, patternNode;
                if (match = regex.exec(textNode.data)) {
                    wrapperNode = doc.createElement(o.tagName);
                    o.className && (wrapperNode.className = o.className);
                    patternNode = textNode.splitText(match.index);
                    patternNode.splitText(match[0].length);
                    wrapperNode.appendChild(patternNode.cloneNode(true));
                    textNode.parentNode.replaceChild(wrapperNode, patternNode);
                }
                return !!match;
            }
            function traverse(el, hightlightTextNode) {
                var childNode, TEXT_NODE_TYPE = 3;
                for (var i = 0; i < el.childNodes.length; i++) {
                    childNode = el.childNodes[i];
                    if (childNode.nodeType === TEXT_NODE_TYPE) {
                        i += hightlightTextNode(childNode) ? 1 : 0;
                    } else {
                        traverse(childNode, hightlightTextNode);
                    }
                }
            }
        };
        function getRegex(patterns, caseSensitive, wordsOnly) {
            var escapedPatterns = [], regexStr;
            for (var i = 0; i < patterns.length; i++) {
                escapedPatterns.push(_.escapeRegExChars(patterns[i]));
            }
            regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
            return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
        }
    }(window.document);
    var Input = function() {
        var specialKeyCodeMap;
        specialKeyCodeMap = {
            9: "tab",
            27: "esc",
            37: "left",
            39: "right",
            13: "enter",
            38: "up",
            40: "down"
        };
        function Input(o) {
            var that = this, onBlur, onFocus, onKeydown, onInput;
            o = o || {};
            if (!o.input) {
                $.error("input is missing");
            }
            onBlur = _.bind(this._onBlur, this);
            onFocus = _.bind(this._onFocus, this);
            onKeydown = _.bind(this._onKeydown, this);
            onInput = _.bind(this._onInput, this);
            this.$hint = $(o.hint);
            this.$input = $(o.input).on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown);
            if (this.$hint.length === 0) {
                this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
            }
            if (!_.isMsie()) {
                this.$input.on("input.tt", onInput);
            } else {
                this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) {
                    if (specialKeyCodeMap[$e.which || $e.keyCode]) {
                        return;
                    }
                    _.defer(_.bind(that._onInput, that, $e));
                });
            }
            this.query = this.$input.val();
            this.$overflowHelper = buildOverflowHelper(this.$input);
        }
        Input.normalizeQuery = function(str) {
            return (str || "").replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
        };
        _.mixin(Input.prototype, EventEmitter, {
            _onBlur: function onBlur() {
                this.resetInputValue();
                this.trigger("blurred");
            },
            _onFocus: function onFocus() {
                this.trigger("focused");
            },
            _onKeydown: function onKeydown($e) {
                var keyName = specialKeyCodeMap[$e.which || $e.keyCode];
                this._managePreventDefault(keyName, $e);
                if (keyName && this._shouldTrigger(keyName, $e)) {
                    this.trigger(keyName + "Keyed", $e);
                }
            },
            _onInput: function onInput() {
                this._checkInputValue();
            },
            _managePreventDefault: function managePreventDefault(keyName, $e) {
                var preventDefault, hintValue, inputValue;
                switch (keyName) {
                  case "tab":
                    hintValue = this.getHint();
                    inputValue = this.getInputValue();
                    preventDefault = hintValue && hintValue !== inputValue && !withModifier($e);
                    break;

                  case "up":
                  case "down":
                    preventDefault = !withModifier($e);
                    break;

                  default:
                    preventDefault = false;
                }
                preventDefault && $e.preventDefault();
            },
            _shouldTrigger: function shouldTrigger(keyName, $e) {
                var trigger;
                switch (keyName) {
                  case "tab":
                    trigger = !withModifier($e);
                    break;

                  default:
                    trigger = true;
                }
                return trigger;
            },
            _checkInputValue: function checkInputValue() {
                var inputValue, areEquivalent, hasDifferentWhitespace;
                inputValue = this.getInputValue();
                areEquivalent = areQueriesEquivalent(inputValue, this.query);
                hasDifferentWhitespace = areEquivalent ? this.query.length !== inputValue.length : false;
                if (!areEquivalent) {
                    this.trigger("queryChanged", this.query = inputValue);
                } else if (hasDifferentWhitespace) {
                    this.trigger("whitespaceChanged", this.query);
                }
            },
            focus: function focus() {
                this.$input.focus();
            },
            blur: function blur() {
                this.$input.blur();
            },
            getQuery: function getQuery() {
                return this.query;
            },
            setQuery: function setQuery(query) {
                this.query = query;
            },
            getInputValue: function getInputValue() {
                return this.$input.val();
            },
            setInputValue: function setInputValue(value, silent) {
                this.$input.val(value);
                silent ? this.clearHint() : this._checkInputValue();
            },
            resetInputValue: function resetInputValue() {
                this.setInputValue(this.query, true);
            },
            getHint: function getHint() {
                return this.$hint.val();
            },
            setHint: function setHint(value) {
                this.$hint.val(value);
            },
            clearHint: function clearHint() {
                this.setHint("");
            },
            clearHintIfInvalid: function clearHintIfInvalid() {
                var val, hint, valIsPrefixOfHint, isValid;
                val = this.getInputValue();
                hint = this.getHint();
                valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
                isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow();
                !isValid && this.clearHint();
            },
            getLanguageDirection: function getLanguageDirection() {
                return (this.$input.css("direction") || "ltr").toLowerCase();
            },
            hasOverflow: function hasOverflow() {
                var constraint = this.$input.width() - 2;
                this.$overflowHelper.text(this.getInputValue());
                return this.$overflowHelper.width() >= constraint;
            },
            isCursorAtEnd: function() {
                var valueLength, selectionStart, range;
                valueLength = this.$input.val().length;
                selectionStart = this.$input[0].selectionStart;
                if (_.isNumber(selectionStart)) {
                    return selectionStart === valueLength;
                } else if (document.selection) {
                    range = document.selection.createRange();
                    range.moveStart("character", -valueLength);
                    return valueLength === range.text.length;
                }
                return true;
            },
            destroy: function destroy() {
                this.$hint.off(".tt");
                this.$input.off(".tt");
                this.$hint = this.$input = this.$overflowHelper = null;
            }
        });
        return Input;
        function buildOverflowHelper($input) {
            return $('<pre aria-hidden="true"></pre>').css({
                position: "absolute",
                visibility: "hidden",
                whiteSpace: "pre",
                fontFamily: $input.css("font-family"),
                fontSize: $input.css("font-size"),
                fontStyle: $input.css("font-style"),
                fontVariant: $input.css("font-variant"),
                fontWeight: $input.css("font-weight"),
                wordSpacing: $input.css("word-spacing"),
                letterSpacing: $input.css("letter-spacing"),
                textIndent: $input.css("text-indent"),
                textRendering: $input.css("text-rendering"),
                textTransform: $input.css("text-transform")
            }).insertAfter($input);
        }
        function areQueriesEquivalent(a, b) {
            return Input.normalizeQuery(a) === Input.normalizeQuery(b);
        }
        function withModifier($e) {
            return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;
        }
    }();
    var Dataset = function() {
        var datasetKey = "ttDataset", valueKey = "ttValue", datumKey = "ttDatum";
        function Dataset(o) {
            o = o || {};
            o.templates = o.templates || {};
            if (!o.source) {
                $.error("missing source");
            }
            if (o.name && !isValidName(o.name)) {
                $.error("invalid dataset name: " + o.name);
            }
            this.query = null;
            this.highlight = !!o.highlight;
            this.name = o.name || _.getUniqueId();
            this.source = o.source;
            this.displayFn = getDisplayFn(o.display || o.displayKey);
            this.templates = getTemplates(o.templates, this.displayFn);
            this.$el = $(html.dataset.replace("%CLASS%", this.name));
        }
        Dataset.extractDatasetName = function extractDatasetName(el) {
            return $(el).data(datasetKey);
        };
        Dataset.extractValue = function extractDatum(el) {
            return $(el).data(valueKey);
        };
        Dataset.extractDatum = function extractDatum(el) {
            return $(el).data(datumKey);
        };
        _.mixin(Dataset.prototype, EventEmitter, {
            _render: function render(query, suggestions) {
                if (!this.$el) {
                    return;
                }
                var that = this, hasSuggestions;
                this.$el.empty();
                hasSuggestions = suggestions && suggestions.length;
                if (!hasSuggestions && this.templates.empty) {
                    this.$el.html(getEmptyHtml()).prepend(that.templates.header ? getHeaderHtml() : null).append(that.templates.footer ? getFooterHtml() : null);
                } else if (hasSuggestions) {
                    this.$el.html(getSuggestionsHtml()).prepend(that.templates.header ? getHeaderHtml() : null).append(that.templates.footer ? getFooterHtml() : null);
                }
                this.trigger("rendered");
                function getEmptyHtml() {
                    return that.templates.empty({
                        query: query,
                        isEmpty: true
                    });
                }
                function getSuggestionsHtml() {
                    var $suggestions, nodes;
                    $suggestions = $(html.suggestions).css(css.suggestions);
                    nodes = _.map(suggestions, getSuggestionNode);
                    $suggestions.append.apply($suggestions, nodes);
                    that.highlight && highlight({
                        node: $suggestions[0],
                        pattern: query
                    });
                    return $suggestions;
                    function getSuggestionNode(suggestion) {
                        var $el;
                        $el = $(html.suggestion).append(that.templates.suggestion(suggestion)).data(datasetKey, that.name).data(valueKey, that.displayFn(suggestion)).data(datumKey, suggestion);
                        $el.children().each(function() {
                            $(this).css(css.suggestionChild);
                        });
                        return $el;
                    }
                }
                function getHeaderHtml() {
                    return that.templates.header({
                        query: query,
                        isEmpty: !hasSuggestions
                    });
                }
                function getFooterHtml() {
                    return that.templates.footer({
                        query: query,
                        isEmpty: !hasSuggestions
                    });
                }
            },
            getRoot: function getRoot() {
                return this.$el;
            },
            update: function update(query) {
                var that = this;
                this.query = query;
                this.canceled = false;
                this.source(query, render);
                function render(suggestions) {
                    if (!that.canceled && query === that.query) {
                        that._render(query, suggestions);
                    }
                }
            },
            cancel: function cancel() {
                this.canceled = true;
            },
            clear: function clear() {
                this.cancel();
                this.$el.empty();
                this.trigger("rendered");
            },
            isEmpty: function isEmpty() {
                return this.$el.is(":empty");
            },
            destroy: function destroy() {
                this.$el = null;
            }
        });
        return Dataset;
        function getDisplayFn(display) {
            display = display || "value";
            return _.isFunction(display) ? display : displayFn;
            function displayFn(obj) {
                return obj[display];
            }
        }
        function getTemplates(templates, displayFn) {
            return {
                empty: templates.empty && _.templatify(templates.empty),
                header: templates.header && _.templatify(templates.header),
                footer: templates.footer && _.templatify(templates.footer),
                suggestion: templates.suggestion || suggestionTemplate
            };
            function suggestionTemplate(context) {
                return "<p>" + displayFn(context) + "</p>";
            }
        }
        function isValidName(str) {
            return /^[_a-zA-Z0-9-]+$/.test(str);
        }
    }();
    var Dropdown = function() {
        function Dropdown(o) {
            var that = this, onSuggestionClick, onSuggestionMouseEnter, onSuggestionMouseLeave;
            o = o || {};
            if (!o.menu) {
                $.error("menu is required");
            }
            this.isOpen = false;
            this.isEmpty = true;
            this.datasets = _.map(o.datasets, initializeDataset);
            onSuggestionClick = _.bind(this._onSuggestionClick, this);
            onSuggestionMouseEnter = _.bind(this._onSuggestionMouseEnter, this);
            onSuggestionMouseLeave = _.bind(this._onSuggestionMouseLeave, this);
            this.$menu = $(o.menu).on("click.tt", ".tt-suggestion", onSuggestionClick).on("mouseenter.tt", ".tt-suggestion", onSuggestionMouseEnter).on("mouseleave.tt", ".tt-suggestion", onSuggestionMouseLeave);
            _.each(this.datasets, function(dataset) {
                that.$menu.append(dataset.getRoot());
                dataset.onSync("rendered", that._onRendered, that);
            });
        }
        _.mixin(Dropdown.prototype, EventEmitter, {
            _onSuggestionClick: function onSuggestionClick($e) {
                this.trigger("suggestionClicked", $($e.currentTarget));
            },
            _onSuggestionMouseEnter: function onSuggestionMouseEnter($e) {
                this._removeCursor();
                this._setCursor($($e.currentTarget), true);
            },
            _onSuggestionMouseLeave: function onSuggestionMouseLeave() {
                this._removeCursor();
            },
            _onRendered: function onRendered() {
                this.isEmpty = _.every(this.datasets, isDatasetEmpty);
                this.isEmpty ? this._hide() : this.isOpen && this._show();
                this.trigger("datasetRendered");
                function isDatasetEmpty(dataset) {
                    return dataset.isEmpty();
                }
            },
            _hide: function() {
                this.$menu.hide();
            },
            _show: function() {
                this.$menu.css("display", "block");
            },
            _getSuggestions: function getSuggestions() {
                return this.$menu.find(".tt-suggestion");
            },
            _getCursor: function getCursor() {
                return this.$menu.find(".tt-cursor").first();
            },
            _setCursor: function setCursor($el, silent) {
                $el.first().addClass("tt-cursor");
                !silent && this.trigger("cursorMoved");
            },
            _removeCursor: function removeCursor() {
                this._getCursor().removeClass("tt-cursor");
            },
            _moveCursor: function moveCursor(increment) {
                var $suggestions, $oldCursor, newCursorIndex, $newCursor;
                if (!this.isOpen) {
                    return;
                }
                $oldCursor = this._getCursor();
                $suggestions = this._getSuggestions();
                this._removeCursor();
                newCursorIndex = $suggestions.index($oldCursor) + increment;
                newCursorIndex = (newCursorIndex + 1) % ($suggestions.length + 1) - 1;
                if (newCursorIndex === -1) {
                    this.trigger("cursorRemoved");
                    return;
                } else if (newCursorIndex < -1) {
                    newCursorIndex = $suggestions.length - 1;
                }
                this._setCursor($newCursor = $suggestions.eq(newCursorIndex));
                this._ensureVisible($newCursor);
            },
            _ensureVisible: function ensureVisible($el) {
                var elTop, elBottom, menuScrollTop, menuHeight;
                elTop = $el.position().top;
                elBottom = elTop + $el.outerHeight(true);
                menuScrollTop = this.$menu.scrollTop();
                menuHeight = this.$menu.height() + parseInt(this.$menu.css("paddingTop"), 10) + parseInt(this.$menu.css("paddingBottom"), 10);
                if (elTop < 0) {
                    this.$menu.scrollTop(menuScrollTop + elTop);
                } else if (menuHeight < elBottom) {
                    this.$menu.scrollTop(menuScrollTop + (elBottom - menuHeight));
                }
            },
            close: function close() {
                if (this.isOpen) {
                    this.isOpen = false;
                    this._removeCursor();
                    this._hide();
                    this.trigger("closed");
                }
            },
            open: function open() {
                if (!this.isOpen) {
                    this.isOpen = true;
                    !this.isEmpty && this._show();
                    this.trigger("opened");
                }
            },
            setLanguageDirection: function setLanguageDirection(dir) {
                this.$menu.css(dir === "ltr" ? css.ltr : css.rtl);
            },
            moveCursorUp: function moveCursorUp() {
                this._moveCursor(-1);
            },
            moveCursorDown: function moveCursorDown() {
                this._moveCursor(+1);
            },
            getDatumForSuggestion: function getDatumForSuggestion($el) {
                var datum = null;
                if ($el.length) {
                    datum = {
                        raw: Dataset.extractDatum($el),
                        value: Dataset.extractValue($el),
                        datasetName: Dataset.extractDatasetName($el)
                    };
                }
                return datum;
            },
            getDatumForCursor: function getDatumForCursor() {
                return this.getDatumForSuggestion(this._getCursor().first());
            },
            getDatumForTopSuggestion: function getDatumForTopSuggestion() {
                return this.getDatumForSuggestion(this._getSuggestions().first());
            },
            update: function update(query) {
                _.each(this.datasets, updateDataset);
                function updateDataset(dataset) {
                    dataset.update(query);
                }
            },
            empty: function empty() {
                _.each(this.datasets, clearDataset);
                this.isEmpty = true;
                function clearDataset(dataset) {
                    dataset.clear();
                }
            },
            isVisible: function isVisible() {
                return this.isOpen && !this.isEmpty;
            },
            destroy: function destroy() {
                this.$menu.off(".tt");
                this.$menu = null;
                _.each(this.datasets, destroyDataset);
                function destroyDataset(dataset) {
                    dataset.destroy();
                }
            }
        });
        return Dropdown;
        function initializeDataset(oDataset) {
            return new Dataset(oDataset);
        }
    }();
    var Typeahead = function() {
        var attrsKey = "ttAttrs";
        function Typeahead(o) {
            var $menu, $input, $hint;
            o = o || {};
            if (!o.input) {
                $.error("missing input");
            }
            this.isActivated = false;
            this.autoselect = !!o.autoselect;
            this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
            this.$node = buildDomStructure(o.input, o.withHint);
            $menu = this.$node.find(".tt-dropdown-menu");
            $input = this.$node.find(".tt-input");
            $hint = this.$node.find(".tt-hint");
            $input.on("blur.tt", function($e) {
                var active, isActive, hasActive;
                active = document.activeElement;
                isActive = $menu.is(active);
                hasActive = $menu.has(active).length > 0;
                if (_.isMsie() && (isActive || hasActive)) {
                    $e.preventDefault();
                    $e.stopImmediatePropagation();
                    _.defer(function() {
                        $input.focus();
                    });
                }
            });
            $menu.on("mousedown.tt", function($e) {
                $e.preventDefault();
            });
            this.eventBus = o.eventBus || new EventBus({
                el: $input
            });
            this.dropdown = new Dropdown({
                menu: $menu,
                datasets: o.datasets
            }).onSync("suggestionClicked", this._onSuggestionClicked, this).onSync("cursorMoved", this._onCursorMoved, this).onSync("cursorRemoved", this._onCursorRemoved, this).onSync("opened", this._onOpened, this).onSync("closed", this._onClosed, this).onAsync("datasetRendered", this._onDatasetRendered, this);
            this.input = new Input({
                input: $input,
                hint: $hint
            }).onSync("focused", this._onFocused, this).onSync("blurred", this._onBlurred, this).onSync("enterKeyed", this._onEnterKeyed, this).onSync("tabKeyed", this._onTabKeyed, this).onSync("escKeyed", this._onEscKeyed, this).onSync("upKeyed", this._onUpKeyed, this).onSync("downKeyed", this._onDownKeyed, this).onSync("leftKeyed", this._onLeftKeyed, this).onSync("rightKeyed", this._onRightKeyed, this).onSync("queryChanged", this._onQueryChanged, this).onSync("whitespaceChanged", this._onWhitespaceChanged, this);
            this._setLanguageDirection();
        }
        _.mixin(Typeahead.prototype, {
            _onSuggestionClicked: function onSuggestionClicked(type, $el) {
                var datum;
                if (datum = this.dropdown.getDatumForSuggestion($el)) {
                    this._select(datum);
                }
            },
            _onCursorMoved: function onCursorMoved() {
                var datum = this.dropdown.getDatumForCursor();
                this.input.setInputValue(datum.value, true);
                this.eventBus.trigger("cursorchanged", datum.raw, datum.datasetName);
            },
            _onCursorRemoved: function onCursorRemoved() {
                this.input.resetInputValue();
                this._updateHint();
            },
            _onDatasetRendered: function onDatasetRendered() {
                this._updateHint();
            },
            _onOpened: function onOpened() {
                this._updateHint();
                this.eventBus.trigger("opened");
            },
            _onClosed: function onClosed() {
                this.input.clearHint();
                this.eventBus.trigger("closed");
            },
            _onFocused: function onFocused() {
                this.isActivated = true;
                this.dropdown.open();
            },
            _onBlurred: function onBlurred() {
                this.isActivated = false;
                this.dropdown.empty();
                this.dropdown.close();
            },
            _onEnterKeyed: function onEnterKeyed(type, $e) {
                var cursorDatum, topSuggestionDatum;
                cursorDatum = this.dropdown.getDatumForCursor();
                topSuggestionDatum = this.dropdown.getDatumForTopSuggestion();
                if (cursorDatum) {
                    this._select(cursorDatum);
                    $e.preventDefault();
                } else if (this.autoselect && topSuggestionDatum) {
                    this._select(topSuggestionDatum);
                    $e.preventDefault();
                }
            },
            _onTabKeyed: function onTabKeyed(type, $e) {
                var datum;
                if (datum = this.dropdown.getDatumForCursor()) {
                    this._select(datum);
                    $e.preventDefault();
                } else {
                    this._autocomplete(true);
                }
            },
            _onEscKeyed: function onEscKeyed() {
                this.dropdown.close();
                this.input.resetInputValue();
            },
            _onUpKeyed: function onUpKeyed() {
                var query = this.input.getQuery();
                this.dropdown.isEmpty && query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.moveCursorUp();
                this.dropdown.open();
            },
            _onDownKeyed: function onDownKeyed() {
                var query = this.input.getQuery();
                this.dropdown.isEmpty && query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.moveCursorDown();
                this.dropdown.open();
            },
            _onLeftKeyed: function onLeftKeyed() {
                this.dir === "rtl" && this._autocomplete();
            },
            _onRightKeyed: function onRightKeyed() {
                this.dir === "ltr" && this._autocomplete();
            },
            _onQueryChanged: function onQueryChanged(e, query) {
                this.input.clearHintIfInvalid();
                query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.empty();
                this.dropdown.open();
                this._setLanguageDirection();
            },
            _onWhitespaceChanged: function onWhitespaceChanged() {
                this._updateHint();
                this.dropdown.open();
            },
            _setLanguageDirection: function setLanguageDirection() {
                var dir;
                if (this.dir !== (dir = this.input.getLanguageDirection())) {
                    this.dir = dir;
                    this.$node.css("direction", dir);
                    this.dropdown.setLanguageDirection(dir);
                }
            },
            _updateHint: function updateHint() {
                var datum, val, query, escapedQuery, frontMatchRegEx, match;
                datum = this.dropdown.getDatumForTopSuggestion();
                if (datum && this.dropdown.isVisible() && !this.input.hasOverflow()) {
                    val = this.input.getInputValue();
                    query = Input.normalizeQuery(val);
                    escapedQuery = _.escapeRegExChars(query);
                    frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i");
                    match = frontMatchRegEx.exec(datum.value);
                    match ? this.input.setHint(val + match[1]) : this.input.clearHint();
                } else {
                    this.input.clearHint();
                }
            },
            _autocomplete: function autocomplete(laxCursor) {
                var hint, query, isCursorAtEnd, datum;
                hint = this.input.getHint();
                query = this.input.getQuery();
                isCursorAtEnd = laxCursor || this.input.isCursorAtEnd();
                if (hint && query !== hint && isCursorAtEnd) {
                    datum = this.dropdown.getDatumForTopSuggestion();
                    datum && this.input.setInputValue(datum.value);
                    this.eventBus.trigger("autocompleted", datum.raw, datum.datasetName);
                }
            },
            _select: function select(datum) {
                this.input.setQuery(datum.value);
                this.input.setInputValue(datum.value, true);
                this._setLanguageDirection();
                this.eventBus.trigger("selected", datum.raw, datum.datasetName);
                this.dropdown.close();
                _.defer(_.bind(this.dropdown.empty, this.dropdown));
            },
            open: function open() {
                this.dropdown.open();
            },
            close: function close() {
                this.dropdown.close();
            },
            setVal: function setVal(val) {
                if (this.isActivated) {
                    this.input.setInputValue(val);
                } else {
                    this.input.setQuery(val);
                    this.input.setInputValue(val, true);
                }
                this._setLanguageDirection();
            },
            getVal: function getVal() {
                return this.input.getQuery();
            },
            destroy: function destroy() {
                this.input.destroy();
                this.dropdown.destroy();
                destroyDomStructure(this.$node);
                this.$node = null;
            }
        });
        return Typeahead;
        function buildDomStructure(input, withHint) {
            var $input, $wrapper, $dropdown, $hint;
            $input = $(input);
            $wrapper = $(html.wrapper).css(css.wrapper);
            $dropdown = $(html.dropdown).css(css.dropdown);
            $hint = $input.clone().css(css.hint).css(getBackgroundStyles($input));
            $hint.val("").removeData().addClass("tt-hint").removeAttr("id name placeholder").prop("disabled", true).attr({
                autocomplete: "off",
                spellcheck: "false"
            });
            $input.data(attrsKey, {
                dir: $input.attr("dir"),
                autocomplete: $input.attr("autocomplete"),
                spellcheck: $input.attr("spellcheck"),
                style: $input.attr("style")
            });
            $input.addClass("tt-input").attr({
                autocomplete: "off",
                spellcheck: false
            }).css(withHint ? css.input : css.inputWithNoHint);
            try {
                !$input.attr("dir") && $input.attr("dir", "auto");
            } catch (e) {}
            return $input.wrap($wrapper).parent().prepend(withHint ? $hint : null).append($dropdown);
        }
        function getBackgroundStyles($el) {
            return {
                backgroundAttachment: $el.css("background-attachment"),
                backgroundClip: $el.css("background-clip"),
                backgroundColor: $el.css("background-color"),
                backgroundImage: $el.css("background-image"),
                backgroundOrigin: $el.css("background-origin"),
                backgroundPosition: $el.css("background-position"),
                backgroundRepeat: $el.css("background-repeat"),
                backgroundSize: $el.css("background-size")
            };
        }
        function destroyDomStructure($node) {
            var $input = $node.find(".tt-input");
            _.each($input.data(attrsKey), function(val, key) {
                _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);
            });
            $input.detach().removeData(attrsKey).removeClass("tt-input").insertAfter($node);
            $node.remove();
        }
    }();
    (function() {
        var old, typeaheadKey, methods;
        old = $.fn.typeahead;
        typeaheadKey = "ttTypeahead";
        methods = {
            initialize: function initialize(o, datasets) {
                datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1);
                o = o || {};
                return this.each(attach);
                function attach() {
                    var $input = $(this), eventBus, typeahead;
                    _.each(datasets, function(d) {
                        d.highlight = !!o.highlight;
                    });
                    typeahead = new Typeahead({
                        input: $input,
                        eventBus: eventBus = new EventBus({
                            el: $input
                        }),
                        withHint: _.isUndefined(o.hint) ? true : !!o.hint,
                        minLength: o.minLength,
                        autoselect: o.autoselect,
                        datasets: datasets
                    });
                    $input.data(typeaheadKey, typeahead);
                }
            },
            open: function open() {
                return this.each(openTypeahead);
                function openTypeahead() {
                    var $input = $(this), typeahead;
                    if (typeahead = $input.data(typeaheadKey)) {
                        typeahead.open();
                    }
                }
            },
            close: function close() {
                return this.each(closeTypeahead);
                function closeTypeahead() {
                    var $input = $(this), typeahead;
                    if (typeahead = $input.data(typeaheadKey)) {
                        typeahead.close();
                    }
                }
            },
            val: function val(newVal) {
                return !arguments.length ? getVal(this.first()) : this.each(setVal);
                function setVal() {
                    var $input = $(this), typeahead;
                    if (typeahead = $input.data(typeaheadKey)) {
                        typeahead.setVal(newVal);
                    }
                }
                function getVal($input) {
                    var typeahead, query;
                    if (typeahead = $input.data(typeaheadKey)) {
                        query = typeahead.getVal();
                    }
                    return query;
                }
            },
            destroy: function destroy() {
                return this.each(unattach);
                function unattach() {
                    var $input = $(this), typeahead;
                    if (typeahead = $input.data(typeaheadKey)) {
                        typeahead.destroy();
                        $input.removeData(typeaheadKey);
                    }
                }
            }
        };
        $.fn.typeahead = function(method) {
            if (methods[method]) {
                return methods[method].apply(this, [].slice.call(arguments, 1));
            } else {
                return methods.initialize.apply(this, arguments);
            }
        };
        $.fn.typeahead.noConflict = function noConflict() {
            $.fn.typeahead = old;
            return this;
        };
    })();
})(window.jQuery);




/*

MAIN.JS

*/
/*
var round5decimalnom = ["round5nom", "HighValue", "LowValue"];
var round4decimalper = ["round4per", "BidYield", "AskYield", "PreviousClosingYield"];
var round3decimalnom = ["round3nom", "LastPrice", "Price", "PreviousClosingPrice", "Bid", "Ask", "IntradayNetChange", "IntradayHighPrice", "IntradayLowPrice", "IntradayFirstPrice", "CurrentValue", "DiffDayNom", "Buyrate", "Averagerate", "Sellrate", "MarketValue"];
var round2decimalnom = ["round2nom", "sliderAmount"];
var round2decimalper = ["round2per", "DiffDayPer", "DiffYearPer", "ChangePer4weeks", "ChangePer12months", "IntradayPerChange"];
var round1decimalper = ["round1per"];
var round0decimalnom = ["round0nom", "Quantity", "Remaining"];
var roundshortened = ["IntradayAccumulatedVolume", "IntradayAccumulatedTurnover", "Volume", "Turnover", "MarketSize"];
var sortableTables = [];
var dateFormat = 'd.M.yyyy';
var hourFormat = 'HH:mm';
var second = 1000, minute = 60 * second, hour = 60 * minute, day = 24 * hour, week = 7 * day, month = 30 * day, year = 360 * day;
var pollingTimer = 20 * second;

accounting.settings = {
    currency: {
        symbol: "%",
        format: "%v%s",
        decimal: ",",
        thousand: ".",
        precision: 2
    },
    number: {
        thousand: ".",
        decimal: ","
    }
};
accounting.formatBig = FormatShort;

function ReplaceAll(find, replace, str) {
    return str.replace(new RegExp('[' + find + ']', 'g'), replace);
}

function Colorize(row, data) {
    for (var propertyName in data) {
        if (propertyName.toLowerCase().indexOf('change') != -1 || propertyName.toLowerCase().indexOf('diff') != -1) {
            var container = row.find('.' + propertyName);
            if (data[propertyName] < 0)
                container.addClass('red');
            else if (data[propertyName] > 0)
                container.addClass('green');
            else
                container.addClass('blue');
        }
    }
}

function GetDate(date) {
    return new Date(parseInt(date.replace(/\D/g, '')));
}

function GetDateFormatted(date) {
    date = GetDate(date);
    if(isToday(date))
        return date.toString(hourFormat);
    return date.toString(dateFormat);
}

function Urlify(text) {
    return text.split(' ').join('_');
}

function Colorize(value) {
    var change = 'blue';
    if (value > 0)
        change = 'green';
    else if (value < 0)
        change = 'red';
    return change;
}

function Unformat(text) {
    if (typeof text == 'string' || text instanceof String)
        return parseFloat(text.split('.').join('').split(',').join('.'));
    return text;
}

function Placeholder(link, symbol) {
    if (symbol == undefined || link == undefined) return undefined;
    return link.split('PLACEHOLDER').join(symbol);
}

function isToday(date) {
    var now = new Date();
    if (date.getDate() != now.getDate()) return false;
    else if (date.getMonth() != now.getMonth()) return false;
    else if (date.getFullYear() != now.getFullYear()) return false;
    return true;
}

function SwapDateFormat(date) {
    return date.split(' ').join('T');
}

function UpdateClock() {
    var today = new Date();
    var h = today.getHours();
    var m = today.getMinutes();
    var s = today.getSeconds();
    // add a zero in front of numbers<10
    m = CheckTime(m);
    s = CheckTime(s);
    $('#clock').text(h + ':' + m + ':' + s);
}

function CheckTime(i) {
    if (i < 10) {
        i = "0" + i;
    }
    return i;
}

function Format(data, column, empty) {
    if (empty) {
        if (data == undefined || data == null || data == 0) {
            return '';
        }
    }
    if (round5decimalnom.indexOf(column) != -1) {
        return accounting.formatNumber(data, { precision: 5 });
    } else if (round4decimalper.indexOf(column) != -1) {
        return accounting.formatMoney(data * 100, { precision: 4 });
    } else if (round3decimalnom.indexOf(column) != -1) {
        return accounting.formatNumber(data, { precision: 3 });
    } else if (round2decimalnom.indexOf(column) != -1) {
        return accounting.formatNumber(data, { precision: 2 });
    } else if (round2decimalper.indexOf(column) != -1) {
        return accounting.formatMoney(data * 100);
    } else if (round1decimalper.indexOf(column) != -1) {
        return accounting.formatMoney(data * 100, { precision: 1 });
    } else if (round0decimalnom.indexOf(column) != -1) {
        return accounting.formatNumber(data, { precision: 0 });
    } else if (roundshortened.indexOf(column) != -1) {
        return FormatShort(data);
    } else {
        return data;
    }
}

function FormatShort(data) {
    if (data == 0 || data == null)
        return '-';
    if (data >= 1000000000)
        return accounting.formatMoney(data / 1000000000, { precision: 1, symbol: 'Mi' });
    else if (data >= 1000000)
        return accounting.formatMoney(data / 1000000, { precision: 1, symbol: 'M' });
    else if (data >= 1000)
        return accounting.formatMoney(data / 1000, { precision: 1, symbol: 'K' });
    else
        return data;
}

function ForceUpdate(tableName) {
    var table = $(tableName);
    table.trigger('update');

    // Bruteforce
    table.find('thead tr th.headerSortUp, thead tr th.headerSortDown').click().click();
}

function TrySortTable() {
    var newSortableTables = [];
    sortableTables.forEach(function (element) {
        var table = $(element);
        if (table.find('tbody tr').length > 0) {
            table.tablesorter({
                sortList: [[0, 0]],
                sortMultiSortKey: '', // Disables multi sorting
                textExtraction: function (node) {
                    var container = $(node);
                    while (container.children().length != 0)
                        container = container.children(':first');
                    if (container.hasClass('ui-slider-range')) {
                        return container.css('width').slice(0, -2);
                    }
                    var text = container.text();
                    var testDate = Date.parseExact(text, dateFormat);
                    if (testDate != null) {
                        return testDate.getTime().toString();
                    }
                    var testTime = Date.parseExact(text, hourFormat);
                    if (testTime != null) {
                        return Date.today().addHours(testTime.getHours()).addMinutes(testTime.getMinutes()).getTime().toString();
                    }
                    if (text.slice(-1) == 'K' && !isNaN(text.slice(0, 1)))
                        return (text.slice(0, -2).replace(',', '') * 100).toString();
                    else if (text.slice(-1) == 'M' && !isNaN(text.slice(0, 1)))
                        return (text.slice(0, -2).replace(',', '') * 100000).toString();
                    else if (text.slice(-2) == 'Mi' && !isNaN(text.slice(0, 1)))
                        return (text.slice(0, -3).replace(',', '') * 100000000).toString();
                    return text.replace(',', '').replace('.', '');
                }
            });
        } else {
            newSortableTables.push(element);
        }
    });
    sortableTables = newSortableTables;
}

function LoadTemplate(data, template) {
    template.find('td').each(function () {
        var column = $(this).attr('class');
        var thisData = data[column];
        var container = $(this);
        while (container.children().length != 0)
            container = container.children(':first');
        if (container.hasClass('slider')) {
            $(container).slider({
                min: data.LowPriceYear,
                max: data.HighPriceYear,
                value: data.LastPrice,
                disabled: true,
                range: "min"
            });
            var parent = $(container).parent();
            parent.find('.lowAmount').text(Format(data.LowPriceYear, 'sliderAmount'));
            parent.find('.highAmount').text(Format(data.HighPriceYear, 'sliderAmount'));
            return;
        }
        if (typeof (thisData) == "string" && thisData.indexOf('/Date') != -1)
            thisData = GetDateFormatted(thisData);
        thisData = Format(thisData, column);
        container.text(thisData);
        if (container.attr('href') !== undefined)
            container.attr('href', container.attr('href').replace('PLACEHOLDER', data.Symbol));
    });
    Colorize(template, data);
    return template;
}

function LoadFundTableTemplate(category, template) {
    $(template).find('caption').text(category);
    $(template).find('caption').click(function () {
        $(this).parent().toggleClass('closed');
        $(this).siblings().toggle();
    });
    $(template).attr('id', ReplaceAll(' ', '_', category));
    return (template);
}

function LoadCurrencyTemplate(data, template) {
    template.find('td').each(function () {
        var column = $(this).attr('class');
        var thisData = data[column];
        var container = $(this);
        while (container.children().length != 0)
            container = container.children(':first');
        if (typeof (thisData) == "string" && thisData.indexOf('/Date') != -1)
            thisData = GetDateFormatted(thisData);
        thisData = Format(thisData, column, true);
        container.text(thisData);
        if (container.attr('href') !== undefined)
            container.attr('href', container.attr('href').replace('PLACEHOLDER', data.Crosscurrency));
    });
    return template;
}

function LMDError(error) {
    console.error('error', error);
}

$(function () {
    var currentPage = $('#currentPage').val() + "Link";
    $('#menu .' + currentPage).addClass('currentPage');
    $('caption').click(function () {
        $(this).parent().toggleClass('closed');
        if ($(this).data("target") != undefined) {
            $('#' + $(this).data("target")).toggle();
        } else {
            $(this).siblings().toggle();
        }
    });
    UpdateClock();
});
*/

/*MAIN.JS ENDS*/


















/*LIVE MARKET DATA JS*/
/*
var LiveMarketData = new function () {
    'use strict';
    var $ = jQuery;;
    var u = "https://api-1.livemarketdata.com", token, self = this;

    this.setUrl = function(url) {
        u = url;
    }

    this.getUrl = function() {
        return u;
    }

    this.setToken = function (t) {
        token = t;
    }

    this.getToken = function () {
        return token;
    }

    this.authenticate = function (username, password, authUrl, systemId) {
        var turl = authUrl + "/" + username, msg = {"client_id" : systemId, "grant_type" : "password", "password" : password};
        $.ajax({
            type: "POST",
            url: turl,
            contentType: 'json',
            dataType: 'json',
            async: false,
            data: msg,
            headers: {
                "Content-Type": "application/json"
            },
            success: function (resp) {
                console.log(resp);
                token = resp.access_token;
            },
            error: function (e) {
                console.log(e);
            }
        });
    }

    function getData(query, response, exception) {
        $.ajax({
            type: "GET",
            url: u+'/'+query,
            dataType: 'json',
            headers: {
                "Content-Type": "application/json",
                "Authorization": "Bearer "+token
            },
            success: function(reply) {
                if (!response) {
                    console.log('No callback defined');
                } else {
                    response(reply);
                }
            },
            error: exception
        });
    }

    this.tradablesByExchangesURL = function (params) {
        var formatString = "exchanges/{0}/tradables/{1}/?skip_expired={2}&bond={3}&share={4}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.symbol) {
            formatParams[1] = params.symbol;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.skip_expired) {
            formatParams[2] = params.skip_expired;
        } else {
            formatString = formatString.replace("skip_expired=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.bond) {
            formatParams[3] = params.bond;
        } else {
            formatString = formatString.replace("bond=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.share) {
            formatParams[4] = params.share;
        } else {
            formatString = formatString.replace("share=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.tradablesByExchanges = function (success, params, error) {
        getData(self.tradablesByExchangesURL(params), success, error);
    };


    this.shortTradablesByExchangesURL = function (params) {
        var formatString = "exchanges/{0}/tradables/short/{1}/?skip_expired={2}&bond={3}&share={4}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.symbol) {
            formatParams[1] = params.symbol;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.skip_expired) {
            formatParams[2] = params.skip_expired;
        } else {
            formatString = formatString.replace("skip_expired=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.bond) {
            formatParams[3] = params.bond;
        } else {
            formatString = formatString.replace("bond=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.share) {
            formatParams[4] = params.share;
        } else {
            formatString = formatString.replace("share=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.shortTradablesByExchanges = function (success, params, error) {
        getData(self.shortTradablesByExchangesURL(params), success, error);
    };


    this.tradablesByMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/tradables/{2}/?skip_expired={3}&bond={4}&share={5}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.skip_expired) {
            formatParams[3] = params.skip_expired;
        } else {
            formatString = formatString.replace("skip_expired=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.bond) {
            formatParams[4] = params.bond;
        } else {
            formatString = formatString.replace("bond=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (params && params.share) {
            formatParams[5] = params.share;
        } else {
            formatString = formatString.replace("share=","");
            formatString = formatString.replace("{5}&","");
            formatString = formatString.replace("{5}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.tradablesByMarketsAndExchanges = function (success, params, error) {
        getData(self.tradablesByMarketsAndExchangesURL(params), success, error);
    };


    this.shortTradablesByMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/tradables/short/{2}/?skip_expired={3}&bond={4}&share={5}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.skip_expired) {
            formatParams[3] = params.skip_expired;
        } else {
            formatString = formatString.replace("skip_expired=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.bond) {
            formatParams[4] = params.bond;
        } else {
            formatString = formatString.replace("bond=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (params && params.share) {
            formatParams[5] = params.share;
        } else {
            formatString = formatString.replace("share=","");
            formatString = formatString.replace("{5}&","");
            formatString = formatString.replace("{5}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.shortTradablesByMarketsAndExchanges = function (success, params, error) {
        getData(self.shortTradablesByMarketsAndExchangesURL(params), success, error);
    };


    this.bondsByExchangesURL = function (params) {
        var formatString = "exchanges/{0}/bonds/{1}/?skip_expired={2}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.symbol) {
            formatParams[1] = params.symbol;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.skip_expired) {
            formatParams[2] = params.skip_expired;
        } else {
            formatString = formatString.replace("skip_expired=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondsByExchanges = function (success, params, error) {
        getData(self.bondsByExchangesURL(params), success, error);
    };


    this.bondsByExchangesAndIDURL = function (params) {
        var formatString = "exchanges/{0}/bonds/id/{1}/?skip_expired={2}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.id) {
            formatParams[1] = params.id;
        } else {
            formatString = formatString.replace("id=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.skip_expired) {
            formatParams[2] = params.skip_expired;
        } else {
            formatString = formatString.replace("skip_expired=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondsByExchangesAndID = function (success, params, error) {
        getData(self.bondsByExchangesAndIDURL(params), success, error);
    };


    this.bondsByMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/bonds/{2}/?skip_expired={3}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.skip_expired) {
            formatParams[3] = params.skip_expired;
        } else {
            formatString = formatString.replace("skip_expired=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondsByMarketsAndExchanges = function (success, params, error) {
        getData(self.bondsByMarketsAndExchangesURL(params), success, error);
    };


    this.sharesByExchangesURL = function (params) {
        var formatString = "exchanges/{0}/shares/{1}/?skip_expired={2}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.symbol) {
            formatParams[1] = params.symbol;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.skip_expired) {
            formatParams[2] = params.skip_expired;
        } else {
            formatString = formatString.replace("skip_expired=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.sharesByExchanges = function (success, params, error) {
        getData(self.sharesByExchangesURL(params), success, error);
    };


    this.sharesByMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/shares/{2}/?skip_expired={3}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.skip_expired) {
            formatParams[3] = params.skip_expired;
        } else {
            formatString = formatString.replace("skip_expired=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.sharesByMarketsAndExchanges = function (success, params, error) {
        getData(self.sharesByMarketsAndExchangesURL(params), success, error);
    };


    this.sharesByExchangesAndIDURL = function (params) {
        var formatString = "exchanges/{0}/shares/id/{1}/?skip_expired={2}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.id) {
            formatParams[1] = params.id;
        } else {
            formatString = formatString.replace("id=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.skip_expired) {
            formatParams[2] = params.skip_expired;
        } else {
            formatString = formatString.replace("skip_expired=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.sharesByExchangesAndID = function (success, params, error) {
        getData(self.sharesByExchangesAndIDURL(params), success, error);
    };


    this.indexesURL = function (params) {
        var formatString = "indexes/{0}/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.indexes = function (success, params, error) {
        getData(self.indexesURL(params), success, error);
    };


    this.indexesByIDURL = function (params) {
        var formatString = "indexes/id/{0}/", formatParams = [], retVal;
        if (params && params.id) {
            formatParams[0] = params.id;
        } else {
            formatString = formatString.replace("id=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.indexesByID = function (success, params, error) {
        getData(self.indexesByIDURL(params), success, error);
    };


    this.indexesByCountryURL = function (params) {
        var formatString = "indexes/country/{0}/", formatParams = [], retVal;
        if (params && params.country) {
            formatParams[0] = params.country;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.indexesByCountry = function (success, params, error) {
        getData(self.indexesByCountryURL(params), success, error);
    };


    this.micByIndexesURL = function (params) {
        var formatString = "indexes/mic/{0}/", formatParams = [], retVal;
        if (params && params.mic) {
            formatParams[0] = params.mic;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.micByIndexes = function (success, params, error) {
        getData(self.micByIndexesURL(params), success, error);
    };


    this.marketsByExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.symbol) {
            formatParams[1] = params.symbol;
        } else {
            formatParams[1] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.marketsByExchanges = function (success, params, error) {
        getData(self.marketsByExchangesURL(params), success, error);
    };


    this.marketsByExchangesAndIDURL = function (params) {
        var formatString = "exchanges/{0}/markets/id/{1}/", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.id) {
            formatParams[1] = params.id;
        } else {
            formatString = formatString.replace("id=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.marketsByExchangesAndID = function (success, params, error) {
        getData(self.marketsByExchangesAndIDURL(params), success, error);
    };


    this.exchangesURL = function (params) {
        var formatString = "exchanges/{0}/", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.exchanges = function (success, params, error) {
        getData(self.exchangesURL(params), success, error);
    };


    this.exchangesByIDURL = function (params) {
        var formatString = "exchanges/id/{0}/", formatParams = [], retVal;
        if (params && params.id) {
            formatParams[0] = params.id;
        } else {
            formatString = formatString.replace("id=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.exchangesByID = function (success, params, error) {
        getData(self.exchangesByIDURL(params), success, error);
    };


    this.ticksizetablesURL = function (params) {
        var formatString = "ticksizetables/{0}/", formatParams = [], retVal;
        if (params && params.name) {
            formatParams[0] = params.name;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.ticksizetables = function (success, params, error) {
        getData(self.ticksizetablesURL(params), success, error);
    };


    this.ticksizetablesByIDURL = function (params) {
        var formatString = "ticksizetables/id/{0}/", formatParams = [], retVal;
        if (params && params.id) {
            formatParams[0] = params.id;
        } else {
            formatString = formatString.replace("id=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.ticksizetablesByID = function (success, params, error) {
        getData(self.ticksizetablesByIDURL(params), success, error);
    };


    this.bankdaysURL = function (params) {
        var formatString = "bankdays/?date={0}&country={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.country) {
            formatParams[1] = params.country;
        } else {
            formatString = formatString.replace("country=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bankdays = function (success, params, error) {
        getData(self.bankdaysURL(params), success, error);
    };


    this.isBankdayURL = function (params) {
        var formatString = "is_bankday/?date={0}&country={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.country) {
            formatParams[1] = params.country;
        } else {
            formatString = formatString.replace("country=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.isBankday = function (success, params, error) {
        getData(self.isBankdayURL(params), success, error);
    };


    this.nextBankdayURL = function (params) {
        var formatString = "next_bankday/?date={0}&country={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.country) {
            formatParams[1] = params.country;
        } else {
            formatString = formatString.replace("country=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.nextBankday = function (success, params, error) {
        getData(self.nextBankdayURL(params), success, error);
    };


    this.previousBankdayURL = function (params) {
        var formatString = "previous_bankday/?date={0}&country={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.country) {
            formatParams[1] = params.country;
        } else {
            formatString = formatString.replace("country=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.previousBankday = function (success, params, error) {
        getData(self.previousBankdayURL(params), success, error);
    };


    this.isSettlementdayURL = function (params) {
        var formatString = "is_settlementday/?date={0}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.isSettlementday = function (success, params, error) {
        getData(self.isSettlementdayURL(params), success, error);
    };


    this.nextSettlementdayURL = function (params) {
        var formatString = "next_settlementday/?date={0}&symbol={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.symbol) {
            formatParams[1] = params.symbol;
        } else {
            formatString = formatString.replace("symbol=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.nextSettlementday = function (success, params, error) {
        getData(self.nextSettlementdayURL(params), success, error);
    };


    this.previousSettlementdayURL = function (params) {
        var formatString = "previous_settlementday/?date={0}&symbol={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.symbol) {
            formatParams[1] = params.symbol;
        } else {
            formatString = formatString.replace("symbol=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.previousSettlementday = function (success, params, error) {
        getData(self.previousSettlementdayURL(params), success, error);
    };


    this.exchangesByAutocompleteURL = function (params) {
        var formatString = "autocomplete/exchanges/", formatParams = [], retVal;
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.exchangesByAutocomplete = function (success, params, error) {
        getData(self.exchangesByAutocompleteURL(params), success, error);
    };


    this.marketsByAutocompleteURL = function (params) {
        var formatString = "autocomplete/markets/?exchange={0}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatString = formatString.replace("exchange=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.marketsByAutocomplete = function (success, params, error) {
        getData(self.marketsByAutocompleteURL(params), success, error);
    };


    this.bondsByAutocompleteURL = function (params) {
        var formatString = "autocomplete/bonds/?exchange={0}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatString = formatString.replace("exchange=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondsByAutocomplete = function (success, params, error) {
        getData(self.bondsByAutocompleteURL(params), success, error);
    };


    this.sharesByAutocompleteURL = function (params) {
        var formatString = "autocomplete/shares/?exchange={0}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatString = formatString.replace("exchange=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.sharesByAutocomplete = function (success, params, error) {
        getData(self.sharesByAutocompleteURL(params), success, error);
    };


    this.etfsByAutocompleteURL = function (params) {
        var formatString = "autocomplete/etfs/?exchange={0}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatString = formatString.replace("exchange=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.etfsByAutocomplete = function (success, params, error) {
        getData(self.etfsByAutocompleteURL(params), success, error);
    };


    this.indexesByAutocompleteURL = function (params) {
        var formatString = "autocomplete/indexes/?exchange={0}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatString = formatString.replace("exchange=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.indexesByAutocomplete = function (success, params, error) {
        getData(self.indexesByAutocompleteURL(params), success, error);
    };


    this.bondIndexesByAutocompleteURL = function (params) {
        var formatString = "autocomplete/bond_indexes/?exchange={0}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatString = formatString.replace("exchange=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondIndexesByAutocomplete = function (success, params, error) {
        getData(self.bondIndexesByAutocompleteURL(params), success, error);
    };


    this.fundsByAutocompleteURL = function (params) {
        var formatString = "autocomplete/funds/?issuer={0}", formatParams = [], retVal;
        if (params && params.issuer) {
            formatParams[0] = params.issuer;
        } else {
            formatString = formatString.replace("issuer=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.fundsByAutocomplete = function (success, params, error) {
        getData(self.fundsByAutocompleteURL(params), success, error);
    };


    this.currencyByAutocompleteURL = function (params) {
        var formatString = "autocomplete/currency/?basecurrency={0}", formatParams = [], retVal;
        if (params && params.basecurrency) {
            formatParams[0] = params.basecurrency;
        } else {
            formatString = formatString.replace("basecurrency=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.currencyByAutocomplete = function (success, params, error) {
        getData(self.currencyByAutocompleteURL(params), success, error);
    };


    this.hagstofaIndexesByAutocompleteURL = function (params) {
        var formatString = "autocomplete/hagstofa_indexes/", formatParams = [], retVal;
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.hagstofaIndexesByAutocomplete = function (success, params, error) {
        getData(self.hagstofaIndexesByAutocompleteURL(params), success, error);
    };


    this.tickerTypeByTickerMasterURL = function (params) {
        var formatString = "ticker_master/ticker_type/{0}/", formatParams = [], retVal;
        if (params && params.ticker_type) {
            formatParams[0] = params.ticker_type;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.tickerTypeByTickerMaster = function (success, params, error) {
        getData(self.tickerTypeByTickerMasterURL(params), success, error);
    };


    this.sourceByTickerMasterURL = function (params) {
        var formatString = "ticker_master/source/{0}/", formatParams = [], retVal;
        if (params && params.source) {
            formatParams[0] = params.source;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.sourceByTickerMaster = function (success, params, error) {
        getData(self.sourceByTickerMasterURL(params), success, error);
    };


    this.tickerMasterByCountryURL = function (params) {
        var formatString = "ticker_master/country/{0}/", formatParams = [], retVal;
        if (params && params.country) {
            formatParams[0] = params.country;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.tickerMasterByCountry = function (success, params, error) {
        getData(self.tickerMasterByCountryURL(params), success, error);
    };


    this.symbolByTickerMasterURL = function (params) {
        var formatString = "ticker_master/symbol/{0}/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.symbolByTickerMaster = function (success, params, error) {
        getData(self.symbolByTickerMasterURL(params), success, error);
    };


    this.exchangeByTickerMasterURL = function (params) {
        var formatString = "ticker_master/exchange/{0}/", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.exchangeByTickerMaster = function (success, params, error) {
        getData(self.exchangeByTickerMasterURL(params), success, error);
    };


    this.sectorsURL = function (params) {
        var formatString = "sectors/{0}/", formatParams = [], retVal;
        if (params && params.name) {
            formatParams[0] = params.name;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.sectors = function (success, params, error) {
        getData(self.sectorsURL(params), success, error);
    };


    this.orderbookBySectorsURL = function (params) {
        var formatString = "sectors/orderbook/{0}/", formatParams = [], retVal;
        if (params && params.id) {
            formatParams[0] = params.id;
        } else {
            formatString = formatString.replace("id=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.orderbookBySectors = function (success, params, error) {
        getData(self.orderbookBySectorsURL(params), success, error);
    };


    this.sourcesURL = function (params) {
        var formatString = "sources/{0}/", formatParams = [], retVal;
        if (params && params.name) {
            formatParams[0] = params.name;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.sources = function (success, params, error) {
        getData(self.sourcesURL(params), success, error);
    };


    this.orderbookBySourcesURL = function (params) {
        var formatString = "sources/orderbook/{0}/", formatParams = [], retVal;
        if (params && params.id) {
            formatParams[0] = params.id;
        } else {
            formatString = formatString.replace("id=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.orderbookBySources = function (success, params, error) {
        getData(self.orderbookBySourcesURL(params), success, error);
    };


    this.fundsURL = function (params) {
        var formatString = "funds/{0}/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.funds = function (success, params, error) {
        getData(self.fundsURL(params), success, error);
    };


    this.fundInfoURL = function (params) {
        var formatString = "fund_info/{0}/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.fundInfo = function (success, params, error) {
        getData(self.fundInfoURL(params), success, error);
    };


    this.tradingSchemeURL = function (params) {
        var formatString = "trading_scheme/{0}/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.tradingScheme = function (success, params, error) {
        getData(self.tradingSchemeURL(params), success, error);
    };


    this.ssnByRegisterURL = function (params) {
        var formatString = "register/ssn/{0}/", formatParams = [], retVal;
        if (params && params.ssn) {
            formatParams[0] = params.ssn;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.ssnByRegister = function (success, params, error) {
        getData(self.ssnByRegisterURL(params), success, error);
    };


    this.registerByCountryURL = function (params) {
        var formatString = "register/country/{0}/", formatParams = [], retVal;
        if (params && params.country) {
            formatParams[0] = params.country;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.registerByCountry = function (success, params, error) {
        getData(self.registerByCountryURL(params), success, error);
    };


    this.postalCodesByRegisterURL = function (params) {
        var formatString = "register/postal_codes/", formatParams = [], retVal;
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.postalCodesByRegister = function (success, params, error) {
        getData(self.postalCodesByRegisterURL(params), success, error);
    };


    this.tradableListURL = function (params) {
        var formatString = "tradable_list/{0}/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.tradableList = function (success, params, error) {
        getData(self.tradableListURL(params), success, error);
    };


    this.tradableListsURL = function (params) {
        var formatString = "tradable_lists/", formatParams = [], retVal;
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.tradableLists = function (success, params, error) {
        getData(self.tradableListsURL(params), success, error);
    };


    this.seriesStaticURL = function (params) {
        var formatString = "series_static/{0}/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.seriesStatic = function (success, params, error) {
        getData(self.seriesStaticURL(params), success, error);
    };


    this.tradesByTradablesAndMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/tradables/{2}/trades/?from={3}&to={4}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.from) {
            formatParams[3] = params.from;
        } else {
            formatString = formatString.replace("from=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.to) {
            formatParams[4] = params.to;
        } else {
            formatString = formatString.replace("to=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.tradesByTradablesAndMarketsAndExchanges = function (success, params, error) {
        getData(self.tradesByTradablesAndMarketsAndExchangesURL(params), success, error);
    };


    this.delayedTradablesByMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/tradables/{2}/delayed_trades/?from={3}&to={4}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.from) {
            formatParams[3] = params.from;
        } else {
            formatString = formatString.replace("from=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.to) {
            formatParams[4] = params.to;
        } else {
            formatString = formatString.replace("to=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.delayedTradablesByMarketsAndExchanges = function (success, params, error) {
        getData(self.delayedTradablesByMarketsAndExchangesURL(params), success, error);
    };


    this.historicalTradesByTradablesAndMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/tradables/{2}/historical_trades/?from_date={3}&limit={4}&offset={5}&skip_cancelled={6}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.limit) {
            formatParams[4] = params.limit;
        } else {
            formatString = formatString.replace("limit=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (params && params.offset) {
            formatParams[5] = params.offset;
        } else {
            formatString = formatString.replace("offset=","");
            formatString = formatString.replace("{5}&","");
            formatString = formatString.replace("{5}","");
        }
        if (params && params.skip_cancelled) {
            formatParams[6] = params.skip_cancelled;
        } else {
            formatString = formatString.replace("skip_cancelled=","");
            formatString = formatString.replace("{6}&","");
            formatString = formatString.replace("{6}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.historicalTradesByTradablesAndMarketsAndExchanges = function (success, params, error) {
        getData(self.historicalTradesByTradablesAndMarketsAndExchangesURL(params), success, error);
    };


    this.latestTradesByTradablesAndMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/tradables/{2}/latest_trades/?limit={3}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.limit) {
            formatParams[3] = params.limit;
        } else {
            formatString = formatString.replace("limit=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.latestTradesByTradablesAndMarketsAndExchanges = function (success, params, error) {
        getData(self.latestTradesByTradablesAndMarketsAndExchangesURL(params), success, error);
    };


    this.historicalTradesByTradablesURL = function (params) {
        var formatString = "tradables/{0}/historical_trades/?from_date={1}&to_date={2}&offset={3}&limit={4}&skip_cancelled={5}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.offset) {
            formatParams[3] = params.offset;
        } else {
            formatString = formatString.replace("offset=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.limit) {
            formatParams[4] = params.limit;
        } else {
            formatString = formatString.replace("limit=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (params && params.skip_cancelled) {
            formatParams[5] = params.skip_cancelled;
        } else {
            formatString = formatString.replace("skip_cancelled=","");
            formatString = formatString.replace("{5}&","");
            formatString = formatString.replace("{5}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.historicalTradesByTradables = function (success, params, error) {
        getData(self.historicalTradesByTradablesURL(params), success, error);
    };


    this.snapshotByEquitiesAndMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/equities/{2}/snapshot/", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotByEquitiesAndMarketsAndExchanges = function (success, params, error) {
        getData(self.snapshotByEquitiesAndMarketsAndExchangesURL(params), success, error);
    };


    this.delayedEquitiesByMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/equities/{2}/delayed_snapshot/", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.delayedEquitiesByMarketsAndExchanges = function (success, params, error) {
        getData(self.delayedEquitiesByMarketsAndExchangesURL(params), success, error);
    };


    this.snapshotByBondsAndMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/bonds/{2}/snapshot/", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotByBondsAndMarketsAndExchanges = function (success, params, error) {
        getData(self.snapshotByBondsAndMarketsAndExchangesURL(params), success, error);
    };


    this.delayedBondsByMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/bonds/{2}/delayed_snapshot/", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.delayedBondsByMarketsAndExchanges = function (success, params, error) {
        getData(self.delayedBondsByMarketsAndExchangesURL(params), success, error);
    };


    this.snapshotByBondsAndActiveAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/active/bonds/snapshot/", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotByBondsAndActiveAndExchanges = function (success, params, error) {
        getData(self.snapshotByBondsAndActiveAndExchangesURL(params), success, error);
    };


    this.delayedBondsByActiveAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/active/bonds/delayed_snapshot/", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.delayedBondsByActiveAndExchanges = function (success, params, error) {
        getData(self.delayedBondsByActiveAndExchangesURL(params), success, error);
    };


    this.statisticsByTradablesAndMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/tradables/{2}/statistics/?trading_date={3}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.trading_date) {
            var y = params.trading_date.getFullYear().toString();
            var m = (params.trading_date.getMonth()+1).toString();
            var d = params.trading_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trading_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.statisticsByTradablesAndMarketsAndExchanges = function (success, params, error) {
        getData(self.statisticsByTradablesAndMarketsAndExchangesURL(params), success, error);
    };


    this.historyByTradablesAndMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/tradables/{2}/history/?from_date={3}&to_date={4}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[4] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.historyByTradablesAndMarketsAndExchanges = function (success, params, error) {
        getData(self.historyByTradablesAndMarketsAndExchangesURL(params), success, error);
    };


    this.newsByTradablesAndMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/tradables/{2}/news/?from_date={3}&to_date={4}&language={5}", formatParams = [], retVal;
        if (params && params.exchange) {
            formatParams[0] = params.exchange;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[4] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (params && params.language) {
            formatParams[5] = params.language;
        } else {
            formatString = formatString.replace("language=","");
            formatString = formatString.replace("{5}&","");
            formatString = formatString.replace("{5}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.newsByTradablesAndMarketsAndExchanges = function (success, params, error) {
        getData(self.newsByTradablesAndMarketsAndExchangesURL(params), success, error);
    };


    this.newsByIssuerURL = function (params) {
        var formatString = "issuer/{0}/news/?from_date={1}&to_date={2}&language={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.language) {
            formatParams[3] = params.language;
        } else {
            formatString = formatString.replace("language=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.newsByIssuer = function (success, params, error) {
        getData(self.newsByIssuerURL(params), success, error);
    };


    this.snapshotBySymbolAndIndexesURL = function (params) {
        var formatString = "indexes/symbol/{0}/snapshot/?from_date={1}&to_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotBySymbolAndIndexes = function (success, params, error) {
        getData(self.snapshotBySymbolAndIndexesURL(params), success, error);
    };


    this.snapshotByDateBySymbolAndIndexesURL = function (params) {
        var formatString = "indexes/symbol/{0}/snapshot_by_date/?value_date={1}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.value_date) {
            var y = params.value_date.getFullYear().toString();
            var m = (params.value_date.getMonth()+1).toString();
            var d = params.value_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("value_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotByDateBySymbolAndIndexes = function (success, params, error) {
        getData(self.snapshotByDateBySymbolAndIndexesURL(params), success, error);
    };


    this.indexStatisticsBySymbolAndIndexesURL = function (params) {
        var formatString = "indexes/symbol/{0}/index_statistics/?trading_date={1}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.trading_date) {
            var y = params.trading_date.getFullYear().toString();
            var m = (params.trading_date.getMonth()+1).toString();
            var d = params.trading_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trading_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.indexStatisticsBySymbolAndIndexes = function (success, params, error) {
        getData(self.indexStatisticsBySymbolAndIndexesURL(params), success, error);
    };


    this.snapshotByBondIndexesURL = function (params) {
        var formatString = "bond_indexes/snapshot/?trading_date={0}", formatParams = [], retVal;
        if (params && params.trading_date) {
            var y = params.trading_date.getFullYear().toString();
            var m = (params.trading_date.getMonth()+1).toString();
            var d = params.trading_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trading_date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotByBondIndexes = function (success, params, error) {
        getData(self.snapshotByBondIndexesURL(params), success, error);
    };


    this.indexationURL = function (params) {
        var formatString = "indexation/{0}/", formatParams = [], retVal;
        if (params && params.date) {
            var date = new Date(params.date);
            var y = date.getFullYear().toString();
            var m = (date.getMonth() + 1).toString();
            var d = date.getDate().toString();
            if (m.length == 1) { m = '0' + m };
            if (d.length == 1) { d = '0' + d };
            formatParams.push(y + '-' + m + '-' + d);
        } else {
            formatParams.push('today');
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.indexation = function (success, params, error) {
        getData(self.indexationURL(params), success, error);
    };


    this.historyByIndexationURL = function (params) {
        var formatString = "indexation/{0}/history/?from_date={1}&to_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.historyByIndexation = function (success, params, error) {
        getData(self.historyByIndexationURL(params), success, error);
    };


    this.snapshotByFundsURL = function (params) {
        var formatString = "funds/{0}/snapshot/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotByFunds = function (success, params, error) {
        getData(self.snapshotByFundsURL(params), success, error);
    };


    this.pricesByFundsURL = function (params) {
        var formatString = "funds/{0}/prices/?value_date={1}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.value_date) {
            var y = params.value_date.getFullYear().toString();
            var m = (params.value_date.getMonth()+1).toString();
            var d = params.value_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("value_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.pricesByFunds = function (success, params, error) {
        getData(self.pricesByFundsURL(params), success, error);
    };


    this.historyByFundsURL = function (params) {
        var formatString = "funds/{0}/history/?from_date={1}&to_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.historyByFunds = function (success, params, error) {
        getData(self.historyByFundsURL(params), success, error);
    };


    this.pricesHistoryByFundsURL = function (params) {
        var formatString = "funds/{0}/prices_history/?from_date={1}&to_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.pricesHistoryByFunds = function (success, params, error) {
        getData(self.pricesHistoryByFundsURL(params), success, error);
    };


    this.historyTimeseriesByFundsURL = function (params) {
        var formatString = "funds/{0}/history_timeseries/?from_date={1}&to_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.historyTimeseriesByFunds = function (success, params, error) {
        getData(self.historyTimeseriesByFundsURL(params), success, error);
    };


    this.snapshotByTypeAndRatesURL = function (params) {
        var formatString = "rates/{0}/type/{1}/snapshot/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.type) {
            formatParams[1] = params.type;
        } else {
            formatParams[1] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotByTypeAndRates = function (success, params, error) {
        getData(self.snapshotByTypeAndRatesURL(params), success, error);
    };


    this.historyByTypeAndRatesURL = function (params) {
        var formatString = "rates/{0}/type/{1}/history/?from_date={2}&to_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.type) {
            formatParams[1] = params.type;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.historyByTypeAndRates = function (success, params, error) {
        getData(self.historyByTypeAndRatesURL(params), success, error);
    };


    this.historyByCurrencyAndRatesURL = function (params) {
        var formatString = "rates/{0}/currency/{1}/history/?from_date={2}&to_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.currency) {
            formatParams[1] = params.currency;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.historyByCurrencyAndRates = function (success, params, error) {
        getData(self.historyByCurrencyAndRatesURL(params), success, error);
    };


    this.snapshotByCurrencyURL = function (params) {
        var formatString = "currency/{0}/snapshot/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotByCurrency = function (success, params, error) {
        getData(self.snapshotByCurrencyURL(params), success, error);
    };


    this.historyByCurrencyURL = function (params) {
        var formatString = "currency/{0}/history/?from_date={1}&to_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.historyByCurrency = function (success, params, error) {
        getData(self.historyByCurrencyURL(params), success, error);
    };


    this.snapshotByCurrencyCrossURL = function (params) {
        var formatString = "currency_cross/snapshot/", formatParams = [], retVal;
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotByCurrencyCross = function (success, params, error) {
        getData(self.snapshotByCurrencyCrossURL(params), success, error);
    };


    this.currencyStatisticsByCrossCurrencyAndBaseCurrencyAndCurrencyURL = function (params) {
        var formatString = "currency/base_currency/{0}/cross_currency/{1}/currency_statistics/?date={2}", formatParams = [], retVal;
        if (params && params.basecurrency) {
            formatParams[0] = params.basecurrency;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.crosscurrency) {
            formatParams[1] = params.crosscurrency;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.currencyStatisticsByCrossCurrencyAndBaseCurrencyAndCurrency = function (success, params, error) {
        getData(self.currencyStatisticsByCrossCurrencyAndBaseCurrencyAndCurrencyURL(params), success, error);
    };


    this.historyByCrossCurrencyAndBaseCurrencyAndCurrencyCrossURL = function (params) {
        var formatString = "currency_cross/base_currency/{0}/cross_currency/{1}/history/?from_date={2}&to_date={3}", formatParams = [], retVal;
        if (params && params.basecurrency) {
            formatParams[0] = params.basecurrency;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.crosscurrency) {
            formatParams[1] = params.crosscurrency;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.historyByCrossCurrencyAndBaseCurrencyAndCurrencyCross = function (success, params, error) {
        getData(self.historyByCrossCurrencyAndBaseCurrencyAndCurrencyCrossURL(params), success, error);
    };


    this.snapshotByCrossCurrencyAndBaseCurrencyAndCurrencyURL = function (params) {
        var formatString = "currency/base_currency/{0}/cross_currency/{1}/snapshot/?value_date={2}", formatParams = [], retVal;
        if (params && params.basecurrency) {
            formatParams[0] = params.basecurrency;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.crosscurrency) {
            formatParams[1] = params.crosscurrency;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.value_date) {
            var y = params.value_date.getFullYear().toString();
            var m = (params.value_date.getMonth()+1).toString();
            var d = params.value_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("value_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotByCrossCurrencyAndBaseCurrencyAndCurrency = function (success, params, error) {
        getData(self.snapshotByCrossCurrencyAndBaseCurrencyAndCurrencyURL(params), success, error);
    };


    this.netVolumeByTradablesAndMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/tradables/{2}/net_volume/?from_date={3}&to_date={4}", formatParams = [], retVal;
        if (params && params.exchanges) {
            formatParams[0] = params.exchanges;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[4] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.netVolumeByTradablesAndMarketsAndExchanges = function (success, params, error) {
        getData(self.netVolumeByTradablesAndMarketsAndExchangesURL(params), success, error);
    };


    this.netTurnoverByTradablesAndMarketsAndExchangesURL = function (params) {
        var formatString = "exchanges/{0}/markets/{1}/tradables/{2}/net_turnover/?from_date={3}&to_date={4}", formatParams = [], retVal;
        if (params && params.exchanges) {
            formatParams[0] = params.exchanges;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.market) {
            formatParams[1] = params.market;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.symbol) {
            formatParams[2] = params.symbol;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[4] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.netTurnoverByTradablesAndMarketsAndExchanges = function (success, params, error) {
        getData(self.netTurnoverByTradablesAndMarketsAndExchangesURL(params), success, error);
    };


    this.shareholdersURL = function (params) {
        var formatString = "{0}/shareholders/?date={1}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.shareholders = function (success, params, error) {
        getData(self.shareholdersURL(params), success, error);
    };


    this.ownSharesURL = function (params) {
        var formatString = "{0}/own_shares/?date={1}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.ownShares = function (success, params, error) {
        getData(self.ownSharesURL(params), success, error);
    };


    this.snapshotBySeriesURL = function (params) {
        var formatString = "series/{0}/snapshot/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotBySeries = function (success, params, error) {
        getData(self.snapshotBySeriesURL(params), success, error);
    };


    this.historyBySeriesURL = function (params) {
        var formatString = "series/{0}/history/?from_date={1}&to_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.historyBySeries = function (success, params, error) {
        getData(self.historyBySeriesURL(params), success, error);
    };


    this.dailyindexURL = function (params) {
        var formatString = "dailyindex/{0}/{1}/", formatParams = [], retVal;
        var date = new Date();
        var y = date.getFullYear().toString();
        var m = (date.getMonth()+1).toString();
        var d = date.getDate().toString();
        if (m.length == 1) { m = '0'+m };
        if (d.length == 1) { d = '0'+d };
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.push(y+'-'+m+'-'+d);
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.dailyindex = function (success, params, error) {
        getData(self.dailyindexURL(params), success, error);
    };


    this.speciesByFishURL = function (params) {
        var formatString = "fish/species/{0}/", formatParams = [], retVal;
        if (params && params.species) {
            formatParams[0] = params.species;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.speciesByFish = function (success, params, error) {
        getData(self.speciesByFishURL(params), success, error);
    };


    this.rsfSpeciesByFishURL = function (params) {
        var formatString = "fish/rsf_species/{0}/", formatParams = [], retVal;
        if (params && params.species) {
            formatParams[0] = params.species;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.rsfSpeciesByFish = function (success, params, error) {
        getData(self.rsfSpeciesByFishURL(params), success, error);
    };


    this.vesselsByFishURL = function (params) {
        var formatString = "fish/{0}/{1}/vessels/{2}/", formatParams = [], retVal;
        if (params && params.owner) {
            formatParams[0] = params.owner;
        } else {
            formatParams[0] = '*';
        }
        if (params && params._operator) {
            formatParams[1] = params._operator;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.vessel) {
            formatParams[2] = params.vessel;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.vesselsByFish = function (success, params, error) {
        getData(self.vesselsByFishURL(params), success, error);
    };


    this.quotaByVesselByFishURL = function (params) {
        var formatString = "fish/{0}/quota_by_vessel/{1}/{2}/{3}/", formatParams = [], retVal;
        if (params && params.country) {
            formatParams[0] = params.country;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.quota_period) {
            formatParams[1] = params.quota_period;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.vessel) {
            formatParams[2] = params.vessel;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.species) {
            formatParams[3] = params.species;
        } else {
            formatParams[3] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.quotaByVesselByFish = function (success, params, error) {
        getData(self.quotaByVesselByFishURL(params), success, error);
    };


    this.quotaBySpeciesByFishURL = function (params) {
        var formatString = "fish/{0}/quota_by_species/{1}/{2}/", formatParams = [], retVal;
        if (params && params.country) {
            formatParams[0] = params.country;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.quota_period) {
            formatParams[1] = params.quota_period;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.species) {
            formatParams[2] = params.species;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.quotaBySpeciesByFish = function (success, params, error) {
        getData(self.quotaBySpeciesByFishURL(params), success, error);
    };


    this.snapshotByFishURL = function (params) {
        var formatString = "fish/{0}/{1}/{2}/snapshot/?date={3}", formatParams = [], retVal;
        if (params && params.market) {
            formatParams[0] = params.market;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.species) {
            formatParams[1] = params.species;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.presentation_name) {
            formatParams[2] = params.presentation_name;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotByFish = function (success, params, error) {
        getData(self.snapshotByFishURL(params), success, error);
    };


    this.snapshotSumByFishURL = function (params) {
        var formatString = "fish/{0}/{1}/{2}/snapshot_sum/?from_date={3}&to_date={4}", formatParams = [], retVal;
        if (params && params.market) {
            formatParams[0] = params.market;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.species) {
            formatParams[1] = params.species;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.presentation_name) {
            formatParams[2] = params.presentation_name;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[4] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotSumByFish = function (success, params, error) {
        getData(self.snapshotSumByFishURL(params), success, error);
    };


    this.snapshotComparisonByFishURL = function (params) {
        var formatString = "fish/{0}/{1}/{2}/snapshot_comparison/?from_date={3}&to_date={4}", formatParams = [], retVal;
        if (params && params.market) {
            formatParams[0] = params.market;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.species) {
            formatParams[1] = params.species;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.presentation_name) {
            formatParams[2] = params.presentation_name;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[4] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotComparisonByFish = function (success, params, error) {
        getData(self.snapshotComparisonByFishURL(params), success, error);
    };


    this.landingsByFishURL = function (params) {
        var formatString = "fish/{0}/{1}/{2}/landings/?from_date={3}&to_date={4}", formatParams = [], retVal;
        if (params && params.harbour) {
            formatParams[0] = params.harbour;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.species) {
            formatParams[1] = params.species;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.vessel) {
            formatParams[2] = params.vessel;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[4] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.landingsByFish = function (success, params, error) {
        getData(self.landingsByFishURL(params), success, error);
    };


    this.landingsByStockByFishURL = function (params) {
        var formatString = "fish/{0}/{1}/landings_by_stock/?date={2}", formatParams = [], retVal;
        if (params && params.country) {
            formatParams[0] = params.country;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.species) {
            formatParams[1] = params.species;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.landingsByStockByFish = function (success, params, error) {
        getData(self.landingsByStockByFishURL(params), success, error);
    };


    this.landingsByStockSumByFishURL = function (params) {
        var formatString = "fish/{0}/{1}/landings_by_stock_sum/?from_date={2}&to_date={3}", formatParams = [], retVal;
        if (params && params.country) {
            formatParams[0] = params.country;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.species) {
            formatParams[1] = params.species;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.landingsByStockSumByFish = function (success, params, error) {
        getData(self.landingsByStockSumByFishURL(params), success, error);
    };


    this.landingsComparisonByFishURL = function (params) {
        var formatString = "fish/{0}/{1}/landings_comparison/?from_date={2}&to_date={3}", formatParams = [], retVal;
        if (params && params.country) {
            formatParams[0] = params.country;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.species) {
            formatParams[1] = params.species;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.landingsComparisonByFish = function (success, params, error) {
        getData(self.landingsComparisonByFishURL(params), success, error);
    };


    this.speciesCodeByFishURL = function (params) {
        var formatString = "fish/species_code/", formatParams = [], retVal;
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.speciesCodeByFish = function (success, params, error) {
        getData(self.speciesCodeByFishURL(params), success, error);
    };


    this.fishByCountryURL = function (params) {
        var formatString = "fish/country/", formatParams = [], retVal;
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.fishByCountry = function (success, params, error) {
        getData(self.fishByCountryURL(params), success, error);
    };


    this.tradingPartnerByFishURL = function (params) {
        var formatString = "fish/trading_partner/", formatParams = [], retVal;
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.tradingPartnerByFish = function (success, params, error) {
        getData(self.tradingPartnerByFishURL(params), success, error);
    };


    this.speciesCodeByPartnerAndTradeflowAndFishAndCountryURL = function (params) {
        var formatString = "fish/tradeflow/country/{0}/partner/{1}/species_code/{2}/?year={3}", formatParams = [], retVal;
        if (params && params.country) {
            formatParams[0] = params.country;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.partner) {
            formatParams[1] = params.partner;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.species_code) {
            formatParams[2] = params.species_code;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.year) {
            formatParams[3] = params.year;
        } else {
            formatString = formatString.replace("year=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.speciesCodeByPartnerAndTradeflowAndFishAndCountry = function (success, params, error) {
        getData(self.speciesCodeByPartnerAndTradeflowAndFishAndCountryURL(params), success, error);
    };


    this.snapshotHistoryByFishURL = function (params) {
        var formatString = "fish/{0}/{1}/{2}/snapshot_history/?from_date={3}&to_date={4}", formatParams = [], retVal;
        if (params && params.market) {
            formatParams[0] = params.market;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.species) {
            formatParams[1] = params.species;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.presentation_name) {
            formatParams[2] = params.presentation_name;
        } else {
            formatParams[2] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[4] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.snapshotHistoryByFish = function (success, params, error) {
        getData(self.snapshotHistoryByFishURL(params), success, error);
    };


    this.landingsByStockHistoryByFishURL = function (params) {
        var formatString = "fish/{0}/landings_by_stock_history/?from_date={1}&to_date={2}", formatParams = [], retVal;
        if (params && params.species) {
            formatParams[0] = params.species;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.landingsByStockHistoryByFish = function (success, params, error) {
        getData(self.landingsByStockHistoryByFishURL(params), success, error);
    };


    this.derivativesSnapshotByFishURL = function (params) {
        var formatString = "fish/{0}/derivatives_snapshot/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.derivativesSnapshotByFish = function (success, params, error) {
        getData(self.derivativesSnapshotByFishURL(params), success, error);
    };


    this.derivativesHistoryByFishURL = function (params) {
        var formatString = "fish/{0}/derivatives_history/?from_date={1}&to_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.derivativesHistoryByFish = function (success, params, error) {
        getData(self.derivativesHistoryByFishURL(params), success, error);
    };


    this.quotasByFishURL = function (params) {
        var formatString = "fish/{0}/quotas/{1}/?from_date={2}&to_date={3}", formatParams = [], retVal;
        if (params && params.country) {
            formatParams[0] = params.country;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.species) {
            formatParams[1] = params.species;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.quotasByFish = function (success, params, error) {
        getData(self.quotasByFishURL(params), success, error);
    };


    this.yieldByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/yield/?price={1}&dirty_price={2}&calc_date={3}&trade_date={4}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.price) {
            formatParams[1] = params.price;
        } else {
            formatString = formatString.replace("price=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.dirty_price) {
            formatParams[2] = params.dirty_price;
        } else {
            formatString = formatString.replace("dirty_price=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[4] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.yieldByBondscalc = function (success, params, error) {
        getData(self.yieldByBondscalcURL(params), success, error);
    };


    this.vpbByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/vpb/?yield={1}&calc_date={2}&trade_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.yield) {
            formatParams[1] = params.yield;
        } else {
            formatString = formatString.replace("yield=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.vpbByBondscalc = function (success, params, error) {
        getData(self.vpbByBondscalcURL(params), success, error);
    };


    this.durationByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/duration/?yield={1}&calc_date={2}&trade_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.yield) {
            formatParams[1] = params.yield;
        } else {
            formatString = formatString.replace("yield=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.durationByBondscalc = function (success, params, error) {
        getData(self.durationByBondscalcURL(params), success, error);
    };


    this.modifiedDurationByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/modified_duration/?yield={1}&calc_date={2}&trade_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.yield) {
            formatParams[1] = params.yield;
        } else {
            formatString = formatString.replace("yield=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.modifiedDurationByBondscalc = function (success, params, error) {
        getData(self.modifiedDurationByBondscalcURL(params), success, error);
    };


    this.presentValueByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/present_value/?yield={1}&calc_date={2}&trade_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.yield) {
            formatParams[1] = params.yield;
        } else {
            formatString = formatString.replace("yield=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.presentValueByBondscalc = function (success, params, error) {
        getData(self.presentValueByBondscalcURL(params), success, error);
    };


    this.presentValueDirtyByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/present_value_dirty/?price={1}&calc_date={2}&trade_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.price) {
            formatParams[1] = params.price;
        } else {
            formatString = formatString.replace("price=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.presentValueDirtyByBondscalc = function (success, params, error) {
        getData(self.presentValueDirtyByBondscalcURL(params), success, error);
    };


    this.accruedInterestsByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/accrued_interests/?calc_date={1}&trade_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.accruedInterestsByBondscalc = function (success, params, error) {
        getData(self.accruedInterestsByBondscalcURL(params), success, error);
    };


    this.accruedIndexationByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/accrued_indexation/?calc_date={1}&trade_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.accruedIndexationByBondscalc = function (success, params, error) {
        getData(self.accruedIndexationByBondscalcURL(params), success, error);
    };


    this.dirtyToQuoteByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/dirty_to_quote/?price={1}&calc_date={2}&trade_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.price) {
            formatParams[1] = params.price;
        } else {
            formatString = formatString.replace("price=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.dirtyToQuoteByBondscalc = function (success, params, error) {
        getData(self.dirtyToQuoteByBondscalcURL(params), success, error);
    };


    this.quoteToDirtyByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/quote_to_dirty/?price={1}&calc_date={2}&trade_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.price) {
            formatParams[1] = params.price;
        } else {
            formatString = formatString.replace("price=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.quoteToDirtyByBondscalc = function (success, params, error) {
        getData(self.quoteToDirtyByBondscalcURL(params), success, error);
    };


    this.remainingBalanceByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/remaining_balance/?calc_date={1}&trade_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.remainingBalanceByBondscalc = function (success, params, error) {
        getData(self.remainingBalanceByBondscalcURL(params), success, error);
    };


    this.numberOfInterestDaysByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/number_of_interest_days/?calc_date={1}&trade_date={2}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.numberOfInterestDaysByBondscalc = function (success, params, error) {
        getData(self.numberOfInterestDaysByBondscalcURL(params), success, error);
    };


    this.quotePriceByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/quote_price/?yield={1}&calc_date={2}&trade_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.yield) {
            formatParams[1] = params.yield;
        } else {
            formatString = formatString.replace("yield=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.quotePriceByBondscalc = function (success, params, error) {
        getData(self.quotePriceByBondscalcURL(params), success, error);
    };


    this.dirtyPriceByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/dirty_price/?yield={1}&calc_date={2}&trade_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.yield) {
            formatParams[1] = params.yield;
        } else {
            formatString = formatString.replace("yield=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.dirtyPriceByBondscalc = function (success, params, error) {
        getData(self.dirtyPriceByBondscalcURL(params), success, error);
    };


    this.cashflowByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/cashflow/?yield={1}&calc_date={2}&trade_date={3}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.yield) {
            formatParams[1] = params.yield;
        } else {
            formatString = formatString.replace("yield=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[2] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.cashflowByBondscalc = function (success, params, error) {
        getData(self.cashflowByBondscalcURL(params), success, error);
    };


    this.bondInfoByBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/bond_info/?yield={1}&price={2}&calc_date={3}&trade_date={4}", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.yield) {
            formatParams[1] = params.yield;
        } else {
            formatString = formatString.replace("yield=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (params && params.price) {
            formatParams[2] = params.price;
        } else {
            formatString = formatString.replace("price=","");
            formatString = formatString.replace("{2}&","");
            formatString = formatString.replace("{2}","");
        }
        if (params && params.calc_date) {
            var y = params.calc_date.getFullYear().toString();
            var m = (params.calc_date.getMonth()+1).toString();
            var d = params.calc_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[3] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("calc_date=","");
            formatString = formatString.replace("{3}&","");
            formatString = formatString.replace("{3}","");
        }
        if (params && params.trade_date) {
            var y = params.trade_date.getFullYear().toString();
            var m = (params.trade_date.getMonth()+1).toString();
            var d = params.trade_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[4] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("trade_date=","");
            formatString = formatString.replace("{4}&","");
            formatString = formatString.replace("{4}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondInfoByBondscalc = function (success, params, error) {
        getData(self.bondInfoByBondscalcURL(params), success, error);
    };


    this.bondInfoByCalcDateAndPriceAndBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/price/{1}/calc_date/{2}/bond_info/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.price) {
            formatParams[1] = params.price;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.calc_date) {
            formatParams[2] = params.calc_date;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondInfoByCalcDateAndPriceAndBondscalc = function (success, params, error) {
        getData(self.bondInfoByCalcDateAndPriceAndBondscalcURL(params), success, error);
    };


    this.bondInfoByTradeDateAndPriceAndBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/price/{1}/trade_date/{2}/bond_info/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.price) {
            formatParams[1] = params.price;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.trade_date) {
            formatParams[2] = params.trade_date;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondInfoByTradeDateAndPriceAndBondscalc = function (success, params, error) {
        getData(self.bondInfoByTradeDateAndPriceAndBondscalcURL(params), success, error);
    };


    this.bondInfoByCalcDateAndDirtyAndBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/dirty/{1}/calc_date/{2}/bond_info/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.dirty) {
            formatParams[1] = params.dirty;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.calc_date) {
            formatParams[2] = params.calc_date;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondInfoByCalcDateAndDirtyAndBondscalc = function (success, params, error) {
        getData(self.bondInfoByCalcDateAndDirtyAndBondscalcURL(params), success, error);
    };


    this.bondInfoByTradeDateAndDirtyAndBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/dirty/{1}/trade_date/{2}/bond_info/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.dirty) {
            formatParams[1] = params.dirty;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.trade_date) {
            formatParams[2] = params.trade_date;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondInfoByTradeDateAndDirtyAndBondscalc = function (success, params, error) {
        getData(self.bondInfoByTradeDateAndDirtyAndBondscalcURL(params), success, error);
    };


    this.bondInfoByCalcDateAndYieldAndBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/yield/{1}/calc_date/{2}/bond_info/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.yield) {
            formatParams[1] = params.yield;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.calc_date) {
            formatParams[2] = params.calc_date;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondInfoByCalcDateAndYieldAndBondscalc = function (success, params, error) {
        getData(self.bondInfoByCalcDateAndYieldAndBondscalcURL(params), success, error);
    };


    this.bondInfoByTradeDateAndYieldAndBondscalcURL = function (params) {
        var formatString = "bondscalc/{0}/yield/{1}/trade_date/{2}/bond_info/", formatParams = [], retVal;
        if (params && params.symbol) {
            formatParams[0] = params.symbol;
        } else {
            formatParams[0] = '*';
        }
        if (params && params.yield) {
            formatParams[1] = params.yield;
        } else {
            formatParams[1] = '*';
        }
        if (params && params.trade_date) {
            formatParams[2] = params.trade_date;
        } else {
            formatParams[2] = '*';
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bondInfoByTradeDateAndYieldAndBondscalc = function (success, params, error) {
        getData(self.bondInfoByTradeDateAndYieldAndBondscalcURL(params), success, error);
    };


    this.bankdaysByBondscalcURL = function (params) {
        var formatString = "bondscalc/bankdays/?date={0}&country={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.country) {
            formatParams[1] = params.country;
        } else {
            formatString = formatString.replace("country=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.bankdaysByBondscalc = function (success, params, error) {
        getData(self.bankdaysByBondscalcURL(params), success, error);
    };


    this.isBankdayByBondscalcURL = function (params) {
        var formatString = "bondscalc/is_bankday/?date={0}&country={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.country) {
            formatParams[1] = params.country;
        } else {
            formatString = formatString.replace("country=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.isBankdayByBondscalc = function (success, params, error) {
        getData(self.isBankdayByBondscalcURL(params), success, error);
    };


    this.nextBankdayByBondscalcURL = function (params) {
        var formatString = "bondscalc/next_bankday/?date={0}&country={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.country) {
            formatParams[1] = params.country;
        } else {
            formatString = formatString.replace("country=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.nextBankdayByBondscalc = function (success, params, error) {
        getData(self.nextBankdayByBondscalcURL(params), success, error);
    };


    this.previousBankdayByBondscalcURL = function (params) {
        var formatString = "bondscalc/previous_bankday/?date={0}&country={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.country) {
            formatParams[1] = params.country;
        } else {
            formatString = formatString.replace("country=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.previousBankdayByBondscalc = function (success, params, error) {
        getData(self.previousBankdayByBondscalcURL(params), success, error);
    };


    this.isSettlementdayByBondscalcURL = function (params) {
        var formatString = "bondscalc/is_settlementday/?date={0}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.isSettlementdayByBondscalc = function (success, params, error) {
        getData(self.isSettlementdayByBondscalcURL(params), success, error);
    };


    this.nextSettlementdayByBondscalcURL = function (params) {
        var formatString = "bondscalc/next_settlementday/?date={0}&symbol={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.symbol) {
            formatParams[1] = params.symbol;
        } else {
            formatString = formatString.replace("symbol=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.nextSettlementdayByBondscalc = function (success, params, error) {
        getData(self.nextSettlementdayByBondscalcURL(params), success, error);
    };


    this.previousSettlementdayByBondscalcURL = function (params) {
        var formatString = "bondscalc/previous_settlementday/?date={0}&symbol={1}", formatParams = [], retVal;
        if (params && params.date) {
            var y = params.date.getFullYear().toString();
            var m = (params.date.getMonth()+1).toString();
            var d = params.date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.symbol) {
            formatParams[1] = params.symbol;
        } else {
            formatString = formatString.replace("symbol=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.previousSettlementdayByBondscalc = function (success, params, error) {
        getData(self.previousSettlementdayByBondscalcURL(params), success, error);
    };


    this.getSettlementdaysByBondscalcURL = function (params) {
        var formatString = "bondscalc/get_settlementdays/?from_date={0}&to_date={1}", formatParams = [], retVal;
        if (params && params.from_date) {
            var y = params.from_date.getFullYear().toString();
            var m = (params.from_date.getMonth()+1).toString();
            var d = params.from_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[0] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("from_date=","");
            formatString = formatString.replace("{0}&","");
            formatString = formatString.replace("{0}","");
        }
        if (params && params.to_date) {
            var y = params.to_date.getFullYear().toString();
            var m = (params.to_date.getMonth()+1).toString();
            var d = params.to_date.getDate().toString();
            if (m.length == 1) { m = '0'+m };
            if (d.length == 1) { d = '0'+d };
            formatParams[1] = y+'-'+m+'-'+d;
        } else {
            formatString = formatString.replace("to_date=","");
            formatString = formatString.replace("{1}&","");
            formatString = formatString.replace("{1}","");
        }
        if (formatString[formatString.length - 1] === "?") {
            formatString = formatString.replace("?", "");
        }
        formatParams.forEach(function(element, i) {
            formatString = formatString.replace("{"+i+"}", element);
        });
        return formatString;
    };

    this.getSettlementdaysByBondscalc = function (success, params, error) {
        getData(self.getSettlementdaysByBondscalcURL(params), success, error);
    };

}
*/

/*
 AngularJS v1.4.5
 (c) 2010-2015 Google, Inc. http://angularjs.org
 License: MIT
*/
(function(n,h,p){'use strict';function E(a){var f=[];r(f,h.noop).chars(a);return f.join("")}function g(a,f){var d={},c=a.split(","),b;for(b=0;b<c.length;b++)d[f?h.lowercase(c[b]):c[b]]=!0;return d}function F(a,f){function d(a,b,d,l){b=h.lowercase(b);if(s[b])for(;e.last()&&t[e.last()];)c("",e.last());u[b]&&e.last()==b&&c("",b);(l=v[b]||!!l)||e.push(b);var m={};d.replace(G,function(b,a,f,c,d){m[a]=q(f||c||d||"")});f.start&&f.start(b,m,l)}function c(b,a){var c=0,d;if(a=h.lowercase(a))for(c=e.length-
1;0<=c&&e[c]!=a;c--);if(0<=c){for(d=e.length-1;d>=c;d--)f.end&&f.end(e[d]);e.length=c}}"string"!==typeof a&&(a=null===a||"undefined"===typeof a?"":""+a);var b,k,e=[],m=a,l;for(e.last=function(){return e[e.length-1]};a;){l="";k=!0;if(e.last()&&w[e.last()])a=a.replace(new RegExp("([\\W\\w]*)<\\s*\\/\\s*"+e.last()+"[^>]*>","i"),function(a,b){b=b.replace(H,"$1").replace(I,"$1");f.chars&&f.chars(q(b));return""}),c("",e.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",
b)===b&&(f.comment&&f.comment(a.substring(4,b)),a=a.substring(b+3),k=!1);else if(x.test(a)){if(b=a.match(x))a=a.replace(b[0],""),k=!1}else if(J.test(a)){if(b=a.match(y))a=a.substring(b[0].length),b[0].replace(y,c),k=!1}else K.test(a)&&((b=a.match(z))?(b[4]&&(a=a.substring(b[0].length),b[0].replace(z,d)),k=!1):(l+="<",a=a.substring(1)));k&&(b=a.indexOf("<"),l+=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),f.chars&&f.chars(q(l)))}if(a==m)throw L("badparse",a);m=a}c()}function q(a){if(!a)return"";A.innerHTML=
a.replace(/</g,"&lt;");return A.textContent}function B(a){return a.replace(/&/g,"&amp;").replace(M,function(a){var d=a.charCodeAt(0);a=a.charCodeAt(1);return"&#"+(1024*(d-55296)+(a-56320)+65536)+";"}).replace(N,function(a){return"&#"+a.charCodeAt(0)+";"}).replace(/</g,"&lt;").replace(/>/g,"&gt;")}function r(a,f){var d=!1,c=h.bind(a,a.push);return{start:function(a,k,e){a=h.lowercase(a);!d&&w[a]&&(d=a);d||!0!==C[a]||(c("<"),c(a),h.forEach(k,function(d,e){var k=h.lowercase(e),g="img"===a&&"src"===k||
"background"===k;!0!==O[k]||!0===D[k]&&!f(d,g)||(c(" "),c(e),c('="'),c(B(d)),c('"'))}),c(e?"/>":">"))},end:function(a){a=h.lowercase(a);d||!0!==C[a]||(c("</"),c(a),c(">"));a==d&&(d=!1)},chars:function(a){d||c(B(a))}}}var L=h.$$minErr("$sanitize"),z=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,y=/^<\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^</,J=/^<\//,H=/\x3c!--(.*?)--\x3e/g,x=/<!DOCTYPE([^>]*?)>/i,
I=/<!\[CDATA\[(.*?)]]\x3e/g,M=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,N=/([^\#-~| |!])/g,v=g("area,br,col,hr,img,wbr");n=g("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr");p=g("rp,rt");var u=h.extend({},p,n),s=h.extend({},n,g("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")),t=h.extend({},p,g("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
n=g("circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,radialGradient,rect,stop,svg,switch,text,title,tspan,use");var w=g("script,style"),C=h.extend({},v,s,t,u,n),D=g("background,cite,href,longdesc,src,usemap,xlink:href");n=g("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,valign,value,vspace,width");
p=g("accent-height,accumulate,additive,alphabetic,arabic-form,ascent,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan",
!0);var O=h.extend({},D,p,n),A=document.createElement("pre");h.module("ngSanitize",[]).provider("$sanitize",function(){this.$get=["$$sanitizeUri",function(a){return function(f){var d=[];F(f,r(d,function(c,b){return!/^unsafe/.test(a(c,b))}));return d.join("")}}]});h.module("ngSanitize").filter("linky",["$sanitize",function(a){var f=/((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,d=/^mailto:/i;return function(c,b){function k(a){a&&g.push(E(a))}function e(a,
c){g.push("<a ");h.isDefined(b)&&g.push('target="',b,'" ');g.push('href="',a.replace(/"/g,"&quot;"),'">');k(c);g.push("</a>")}if(!c)return c;for(var m,l=c,g=[],n,p;m=l.match(f);)n=m[0],m[2]||m[4]||(n=(m[3]?"http://":"mailto:")+n),p=m.index,k(l.substr(0,p)),e(n,m[0].replace(d,"")),l=l.substring(p+m[0].length);k(l);return a(g.join(""))}}])})(window,window.angular);
//# sourceMappingURL=angular-sanitize.min.js.map