(function (root, initialize){
    var Bionya = initialize();
    if(typeof define !== "undefined" && define.amd)define(Bionya);
    root.Bionya = Bionya;
}(this, function(){
    //modules here
/**
 * @license almond 0.2.9 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
 * Available via the MIT or new BSD license.
 * see: http://github.com/jrburke/almond for details
 */
//Going sloppy to avoid 'use strict' string cost, but strict practices should
//be followed.
/*jslint sloppy: true */
/*global setTimeout: false */

var requirejs, require, define;
(function (undef) {
    var main, req, makeMap, handlers,
        defined = {},
        waiting = {},
        config = {},
        defining = {},
        hasOwn = Object.prototype.hasOwnProperty,
        aps = [].slice,
        jsSuffixRegExp = /\.js$/;

    function hasProp(obj, prop) {
        return hasOwn.call(obj, prop);
    }

    /**
     * Given a relative module name, like ./something, normalize it to
     * a real name that can be mapped to a path.
     * @param {String} name the relative name
     * @param {String} baseName a real name that the name arg is relative
     * to.
     * @returns {String} normalized name
     */
    function normalize(name, baseName) {
        var nameParts, nameSegment, mapValue, foundMap, lastIndex,
            foundI, foundStarMap, starI, i, j, part,
            baseParts = baseName && baseName.split("/"),
            map = config.map,
            starMap = (map && map['*']) || {};

        //Adjust any relative paths.
        if (name && name.charAt(0) === ".") {
            //If have a base name, try to normalize against it,
            //otherwise, assume it is a top-level require that will
            //be relative to baseUrl in the end.
            if (baseName) {
                //Convert baseName to array, and lop off the last part,
                //so that . matches that "directory" and not name of the baseName's
                //module. For instance, baseName of "one/two/three", maps to
                //"one/two/three.js", but we want the directory, "one/two" for
                //this normalization.
                baseParts = baseParts.slice(0, baseParts.length - 1);
                name = name.split('/');
                lastIndex = name.length - 1;

                // Node .js allowance:
                if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
                    name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
                }

                name = baseParts.concat(name);

                //start trimDots
                for (i = 0; i < name.length; i += 1) {
                    part = name[i];
                    if (part === ".") {
                        name.splice(i, 1);
                        i -= 1;
                    } else if (part === "..") {
                        if (i === 1 && (name[2] === '..' || name[0] === '..')) {
                            //End of the line. Keep at least one non-dot
                            //path segment at the front so it can be mapped
                            //correctly to disk. Otherwise, there is likely
                            //no path mapping for a path starting with '..'.
                            //This can still fail, but catches the most reasonable
                            //uses of ..
                            break;
                        } else if (i > 0) {
                            name.splice(i - 1, 2);
                            i -= 2;
                        }
                    }
                }
                //end trimDots

                name = name.join("/");
            } else if (name.indexOf('./') === 0) {
                // No baseName, so this is ID is resolved relative
                // to baseUrl, pull off the leading dot.
                name = name.substring(2);
            }
        }

        //Apply map config if available.
        if ((baseParts || starMap) && map) {
            nameParts = name.split('/');

            for (i = nameParts.length; i > 0; i -= 1) {
                nameSegment = nameParts.slice(0, i).join("/");

                if (baseParts) {
                    //Find the longest baseName segment match in the config.
                    //So, do joins on the biggest to smallest lengths of baseParts.
                    for (j = baseParts.length; j > 0; j -= 1) {
                        mapValue = map[baseParts.slice(0, j).join('/')];

                        //baseName segment has  config, find if it has one for
                        //this name.
                        if (mapValue) {
                            mapValue = mapValue[nameSegment];
                            if (mapValue) {
                                //Match, update name to the new value.
                                foundMap = mapValue;
                                foundI = i;
                                break;
                            }
                        }
                    }
                }

                if (foundMap) {
                    break;
                }

                //Check for a star map match, but just hold on to it,
                //if there is a shorter segment match later in a matching
                //config, then favor over this star map.
                if (!foundStarMap && starMap && starMap[nameSegment]) {
                    foundStarMap = starMap[nameSegment];
                    starI = i;
                }
            }

            if (!foundMap && foundStarMap) {
                foundMap = foundStarMap;
                foundI = starI;
            }

            if (foundMap) {
                nameParts.splice(0, foundI, foundMap);
                name = nameParts.join('/');
            }
        }

        return name;
    }

    function makeRequire(relName, forceSync) {
        return function () {
            //A version of a require function that passes a moduleName
            //value for items that may need to
            //look up paths relative to the moduleName
            return req.apply(undef, aps.call(arguments, 0).concat([relName, forceSync]));
        };
    }

    function makeNormalize(relName) {
        return function (name) {
            return normalize(name, relName);
        };
    }

    function makeLoad(depName) {
        return function (value) {
            defined[depName] = value;
        };
    }

    function callDep(name) {
        if (hasProp(waiting, name)) {
            var args = waiting[name];
            delete waiting[name];
            defining[name] = true;
            main.apply(undef, args);
        }

        if (!hasProp(defined, name) && !hasProp(defining, name)) {
            throw new Error('No ' + name);
        }
        return defined[name];
    }

    //Turns a plugin!resource to [plugin, resource]
    //with the plugin being undefined if the name
    //did not have a plugin prefix.
    function splitPrefix(name) {
        var prefix,
            index = name ? name.indexOf('!') : -1;
        if (index > -1) {
            prefix = name.substring(0, index);
            name = name.substring(index + 1, name.length);
        }
        return [prefix, name];
    }

    /**
     * Makes a name map, normalizing the name, and using a plugin
     * for normalization if necessary. Grabs a ref to plugin
     * too, as an optimization.
     */
    makeMap = function (name, relName) {
        var plugin,
            parts = splitPrefix(name),
            prefix = parts[0];

        name = parts[1];

        if (prefix) {
            prefix = normalize(prefix, relName);
            plugin = callDep(prefix);
        }

        //Normalize according
        if (prefix) {
            if (plugin && plugin.normalize) {
                name = plugin.normalize(name, makeNormalize(relName));
            } else {
                name = normalize(name, relName);
            }
        } else {
            name = normalize(name, relName);
            parts = splitPrefix(name);
            prefix = parts[0];
            name = parts[1];
            if (prefix) {
                plugin = callDep(prefix);
            }
        }

        //Using ridiculous property names for space reasons
        return {
            f: prefix ? prefix + '!' + name : name, //fullName
            n: name,
            pr: prefix,
            p: plugin
        };
    };

    function makeConfig(name) {
        return function () {
            return (config && config.config && config.config[name]) || {};
        };
    }

    handlers = {
        require: function (name) {
            return makeRequire(name);
        },
        exports: function (name) {
            var e = defined[name];
            if (typeof e !== 'undefined') {
                return e;
            } else {
                return (defined[name] = {});
            }
        },
        module: function (name) {
            return {
                id: name,
                uri: '',
                exports: defined[name],
                config: makeConfig(name)
            };
        }
    };

    main = function (name, deps, callback, relName) {
        var cjsModule, depName, ret, map, i,
            args = [],
            callbackType = typeof callback,
            usingExports;

        //Use name if no relName
        relName = relName || name;

        //Call the callback to define the module, if necessary.
        if (callbackType === 'undefined' || callbackType === 'function') {
            //Pull out the defined dependencies and pass the ordered
            //values to the callback.
            //Default to [require, exports, module] if no deps
            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
            for (i = 0; i < deps.length; i += 1) {
                map = makeMap(deps[i], relName);
                depName = map.f;

                //Fast path CommonJS standard dependencies.
                if (depName === "require") {
                    args[i] = handlers.require(name);
                } else if (depName === "exports") {
                    //CommonJS module spec 1.1
                    args[i] = handlers.exports(name);
                    usingExports = true;
                } else if (depName === "module") {
                    //CommonJS module spec 1.1
                    cjsModule = args[i] = handlers.module(name);
                } else if (hasProp(defined, depName) ||
                           hasProp(waiting, depName) ||
                           hasProp(defining, depName)) {
                    args[i] = callDep(depName);
                } else if (map.p) {
                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
                    args[i] = defined[depName];
                } else {
                    throw new Error(name + ' missing ' + depName);
                }
            }

            ret = callback ? callback.apply(defined[name], args) : undefined;

            if (name) {
                //If setting exports via "module" is in play,
                //favor that over return value and exports. After that,
                //favor a non-undefined return value over exports use.
                if (cjsModule && cjsModule.exports !== undef &&
                        cjsModule.exports !== defined[name]) {
                    defined[name] = cjsModule.exports;
                } else if (ret !== undef || !usingExports) {
                    //Use the return value from the function.
                    defined[name] = ret;
                }
            }
        } else if (name) {
            //May just be an object definition for the module. Only
            //worry about defining if have a module name.
            defined[name] = callback;
        }
    };

    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
        if (typeof deps === "string") {
            if (handlers[deps]) {
                //callback in this case is really relName
                return handlers[deps](callback);
            }
            //Just return the module wanted. In this scenario, the
            //deps arg is the module name, and second arg (if passed)
            //is just the relName.
            //Normalize module name, if it contains . or ..
            return callDep(makeMap(deps, callback).f);
        } else if (!deps.splice) {
            //deps is a config object, not an array.
            config = deps;
            if (config.deps) {
                req(config.deps, config.callback);
            }
            if (!callback) {
                return;
            }

            if (callback.splice) {
                //callback is an array, which means it is a dependency list.
                //Adjust args if there are dependencies
                deps = callback;
                callback = relName;
                relName = null;
            } else {
                deps = undef;
            }
        }

        //Support require(['a'])
        callback = callback || function () {};

        //If relName is a function, it is an errback handler,
        //so remove it.
        if (typeof relName === 'function') {
            relName = forceSync;
            forceSync = alt;
        }

        //Simulate async callback;
        if (forceSync) {
            main(undef, deps, callback, relName);
        } else {
            //Using a non-zero value because of concern for what old browsers
            //do, and latest browsers "upgrade" to 4 if lower value is used:
            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
            //If want a value immediately, use require('id') instead -- something
            //that works in almond on the global level, but not guaranteed and
            //unlikely to work in other AMD implementations.
            setTimeout(function () {
                main(undef, deps, callback, relName);
            }, 4);
        }

        return req;
    };

    /**
     * Just drops the config on the floor, but returns req in case
     * the config return value is used.
     */
    req.config = function (cfg) {
        return req(cfg);
    };

    /**
     * Expose module registry for debugging and tooling
     */
    requirejs._defined = defined;

    define = function (name, deps, callback) {

        //This module may not have dependencies
        if (!deps.splice) {
            //deps is not an array, so probably means
            //an object literal or factory function for
            //the value. Adjust args.
            callback = deps;
            deps = [];
        }

        if (!hasProp(defined, name) && !hasProp(waiting, name)) {
            waiting[name] = [name, deps, callback];
        }
    };

    define.amd = {
        jQuery: true
    };
}());

define("contrib/almond/almond", function(){});

define('tools',[], function(){
    var Tools = {
        STL: Nyaplot.STL,
        _: Nyaplot._,
        uuid: Nyaplot.uuid,
        Manager: Nyaplot.Manager
    };

    return Tools;
});

define('components/scale',['tools'], function(Tools){
    var _ = Tools._;

    function scale(domains, ranges, _options){
        var width = Math.abs(ranges.x[1] - ranges.x[0]);
        var height = Math.abs(ranges.y[1] - ranges.y[0]);

        this.scales = {};
        this.center = {x: width/2, y: height/2};
        this.max_r = Math.min(width, height)/2;
        return this;
    }

    scale.prototype.init = function(inner_radius, outer_radius, inner_num, outer_num){
        this.inner_radius = inner_radius;
        this.outer_radius = outer_radius;
        this.inner_num = inner_num;
        this.outer_num = outer_num;
        this.inner_thickness = inner_radius/(inner_num+1);
        this.outer_thickness = (this.max_r - outer_radius)/outer_num;
    };

    scale.prototype.addGroup = function(name, axis, startAngle, endAngle){
        var scale = d3.scale.ordinal().domain(axis).rangePoints([startAngle, endAngle], 1);
        this.scales[name] = scale;
        this.width = (endAngle - startAngle)/(axis.length+1);
    };

    scale.prototype.groups = function(){
        return _.keys(this.scales);
    };

    scale.prototype.getWidth = function(){
        return this.width;
    };

    scale.prototype.getHeight = function(layer){
        if(layer >= 0)return this.outer_thickness;
        else return this.inner_thickness;
    };

    scale.prototype.getCenter = function(){
        return this.center;
    };

    scale.prototype.getRange = function(layer){
        var min, max;
        if(layer > 0){
            min = this.outer_radius + this.outer_thickness*(layer-1);
            max = min + this.outer_thickness;
        }else{
            max = this.inner_radius;
            min = max - this.inner_thickness;
        }
        return [min, max];
    };

    scale.prototype.get = function(layer, group, x){
        var r, theta;
        if(layer > 0)r = this.outer_radius + this.outer_thickness*layer;
        else r = this.inner_radius - this.inner_thickness*layer*-1;
        theta = this.scales[group](x);
        return {x: r*Math.sin(theta), y: -r*Math.cos(theta), r:r, theta:theta};
    };

    return scale;
});

define('components/axis',['tools'], function(Tools){
    function Axis(parent, scales, _options){
        var _ = Tools._;
        var Manager = Tools.Manager;

        var options = {
            width:0,
            height:0,
            margin: {top:0,bottom:0,left:0,right:0},
            x_label:'X',
            y_label:'Y',
            zoom:true,
            zoom_range:[0.5, 5],
            rotate_x_label:0,
            rotate_y_label:0,
            pane_uuid: null,
            z_index:0,
            extra: {}
        };

        var options_extra = {
            df_id: null,
            inner_radius: 150,
            outer_radius: 170,
            group_by: null,
            fill_by: null,
            axis: null,
            chord: false,
            matrix: null,
            padding: 0.05,
            inner_num: 0,
            outer_num: 1,
            color: ['#253494'],
            text_color: '#fff',
            text_size: '1em'
        };

        if(arguments.length>2){
            _.extend(options, _options);
            _.extend(options_extra, _options.extra);
            options.extra = options_extra;
        }

        var df = Manager.getData(options.extra.df_id);
        var groups = df.column(options.extra.group_by);
        var axies = {};
        var matrix = (options.extra.chord ? options.extra.matrix: []);

        var fill_scale = (function(){
            if(options.extra.fill_by){
                var scale = df.scale(options.extra.fill_by, options.extra.color);
                var pairs = _.zip.apply(null, _.map(df.column(options.extra.fill_by), function(val, i){
                    return [i, scale(val)];
                }));
                return d3.scale.ordinal().domain(pairs[0]).range(pairs[1]);
            }else{
                return d3.scale.ordinal().range(options.extra.color);
            }
        })();

        _.each(groups, function(group, i){
            var axis = df.nested_column(i, options.extra.axis);
            axies[group] = axis;
            if(options.extra.matrix==null){
                matrix[i] = [];
                for(var j=0; j<groups.length; j++){
                    if(j==i)matrix[i][j] = axis.length;
                    else matrix[i][j] = 0;
                }
            }
        });

        var chord = d3.layout.chord().padding(options.extra.padding).matrix(matrix);
        var model = parent.append("g").attr('transform', 'translate(' + options.width/2 + ',' + options.height/2 + ')');
        var clip_id = "clip" + options.pane_uuid;

        model.append("clipPath")
            .attr("id", clip_id)
            .append("rect")
            .attr({
                "x": -options.width/2,
                "y": -options.height/2,
                "width": options.width,
                "height": options.height
            });

        model
            .attr("clip-path", "url(#" + clip_id + ")")
            .style("z-index", options.z_index);

        var prefix = options.pane_uuid + "group";

        // group arcs
        model.append("g")
            .selectAll("g")
            .data(chord.groups)
            .enter().append("g")
            .attr("class", "group_arcs")
            .append("path")
            .style("fill", function(d){return fill_scale(d.index);})
            .style("stroke", function(d){return fill_scale(d.index);})
            .attr("d", d3.svg.arc()
                  .innerRadius(options.extra.inner_radius)
                  .outerRadius(options.extra.outer_radius))
            .attr("id", function(d, i){return prefix+i;});

        // labels for group arcs
        model.selectAll(".group_arcs")
            .append("text")
            .attr("x",6)
            .attr("dy",15)
            .append("textPath")
            .attr("xlink:href", function(d,i){return "#" + prefix + i;})
            .text(function(d,i){return groups[i];})
            .attr("fill", options.extra.text_color)
            .attr("font-size", options.extra.text_size);

        // chord
        if(options.extra.chord){
            model.append("g").selectAll("path")
                .data(chord.chords)
                .enter().append("path")
                .attr("d", d3.svg.chord().radius(options.extra.inner_radius))
                .style("fill", "#fff");
        }

        // scales
        scales.init(
            options.extra.inner_radius, options.extra.outer_radius,
            options.extra.inner_num, options.extra.outer_num);

        model.selectAll(".group_arcs").each(function(d, i){
            scales.addGroup(groups[i], axies[groups[i]], d.startAngle, d.endAngle);
        });

        // tick
        var tick_data = _.flatten(_.map(axies, function(x_arr, group){
            return _.map(x_arr, function(x){
                return scales.get(0, group, x);
            });
        }));

        // dirty code. should be modified soon.
        if(options.zoom){
            parent.call(
                d3.behavior.zoom()
                    .scaleExtent(options.zoom_range)
                    .on("zoom", function(){
                        var translate = d3.event.translate;
                        var scale = d3.event.scale;
                        parent.select(".context_child").attr('transform', 'translate(' + translate + ') scale(' + scale + ')');
                        translate[0] += (scale-1)*options.width/2;
                        translate[1] += (scale-1)*options.height/2;
                        model.select("g").attr('transform', 'translate(' + translate + ') scale(' + scale + ')');
                    }));
        }
    }

    return Axis;
});

define('diagrams/arc',['tools'], function(Tools){
    var _ = Tools._;
    var Manager = Tools.Manager;

    function Arc(parent, scales, df_id, _options){
        var options = {
            range: [0, 0],
            width: 0.5,
            color: ['rgb(166,206,227)', 'rgb(31,120,180)', 'rgb(178,223,138)', 'rgb(51,160,44)', 'rgb(251,154,153)', 'rgb(227,26,28)', 'rgb(253,191,111)', 'rgb(255,127,0)' ,'rgb(202,178,214)'],
            fill_by: null,
            x: null,
            y: null,
            layer: 1,
            axis: true
        };
        if(arguments.length>3)_.extend(options, _options);

        this.height_scale = (function(){
            var height = scales.getHeight(options.layer);
            return d3.scale.linear().domain(options.range).range([0, height]);
        })();

        this.inner_radius = scales.getRange(options.layer)[0];
        this.model = (function(){
            var center = scales.getCenter();
            return parent.append("g").attr('transform', 'translate(' + center.x + ',' + center.y + ')');
        })();
        this.scales = scales;
        this.df = Manager.getData(df_id);
        this.color_scale = d3.scale.ordinal().range(options.color);
        this.uuid = options.uuid;
        this.options = options;

        return this;
    };
    
    Arc.prototype.update = function(){
        var groups = this.scales.groups();
        var thisObj = this;

        if(this.options.axis){
            (function(){
                var values = thisObj.height_scale.ticks(5);
                values.reverse().pop();

                var group = thisObj.model
                    .append("g")
                    .selectAll("g")
                    .data(values)
                    .enter()
                    .append("g");

                group.append("circle")
                    .attr("fill", "none")
                    .attr("stroke", "#000")
                    .attr("r", function(d){return thisObj.inner_radius + thisObj.height_scale(d);});

                group.append("text")
                    .attr("y", function(d){return -1*(thisObj.inner_radius + thisObj.height_scale(d) + 4);})
                    .text(function(d){return d;});
            })();
        }

        _.each(groups, function(group, i){
            var x = thisObj.df.nested_column(i, thisObj.options.x);
            var y = thisObj.df.nested_column(i, thisObj.options.y);
            var fill_scale = (function(){
                var color = thisObj.options.color;
                if(thisObj.options.fill_by){
                    var fill_by = thisObj.options.fill_by;
                    var scale = thisObj.df.scale(fill_by, color);
                    var pairs = _.zip.apply(null, _.map(thisObj.df.column(fill_by), function(val, i){
                        return [i, scale(val)];
                    }));
                    return d3.scale.ordinal().domain(pairs[0]).range(pairs[1]);
                }else{
                    return d3.scale.ordinal().range(color);
                }
            })();
            var data = thisObj.processData(group, x, y, fill_scale);
            thisObj.updateModels(data);
        });
    };

    Arc.prototype.processData = function(group, x_arr, y_arr, fill_scale){
        var thisObj = this;
        return _.map(x_arr, function(x, i){
            var hash = thisObj.scales.get(thisObj.options.layer, group, x);
            hash['height'] = thisObj.height_scale(y_arr[i]);
            hash['fill'] = fill_scale(i);
            return hash;
        });
    };

    Arc.prototype.updateModels = function(data){
        var baseline = this.height_scale(0);
        var inner_radius = this.inner_radius;
        var width = this.scales.getWidth() * this.options.width;

        this.model.append("g")
            .selectAll("path")
            .data(data)
            .enter()
            .append("path")
            .attr("d", d3.svg.arc()
                  .startAngle(function(d){return d.theta - width/2;})
                  .endAngle(function(d){return d.theta + width/2;})
                  .innerRadius(inner_radius + baseline)
                  .outerRadius(function(d){return inner_radius + d.height;}))
            .attr("stroke", function(d){return d.fill;})
            .attr("fill", function(d){return d.fill;});
    };

    Arc.prototype.getLegend = function(){
    };

    Arc.prototype.checkSelectedData = function(ranges){
        return;
    };
    
    return Arc;
});

define('diagrams/connector',['tools'], function(Tools){
    var _ = Tools._;
    var Manager = Tools.Manager;

    function Connector(parent, scales, df_id, _options){
        var options = {
            color: "#737373",
            fill_by: null,
            from: null,
            to: null,
            shape: 'circle',
            stroke_width: 2,
            size: 100,
            shape_fill: '#fff',
            shape_stroke: '#3182bd',
            shape_stroke_width: 2,
            arc_height: 30,
            layer: 0
        };
        if(arguments.length>3)_.extend(options, _options);

        this.model = (function(){
            var center = scales.getCenter();
            return parent.append("g").attr('transform', 'translate(' + center.x + ',' + center.y + ')');
        })();

        this.scales = scales;
        this.df = Manager.getData(df_id);
        this.uuid = options.uuid;
        this.options = options;
    }

    Connector.prototype.update = function(){
        var from = this.df.column(this.options.from);
        var to = this.df.column(this.options.to);
        var data = this.processData(from, to);
        this.updateModels(data);
    };
    
    Connector.prototype.processData = function(from ,to){
        var scales = this.scales, layer = this.options.layer, height = this.options.arc_height;
        return _.map(_.zip(from, to), function(row){
            var points = _.map(row, function(str){
                var strs = str.split(/(.+)\.(.+)/);
                var group = strs[1], x = strs[2];
                var point = scales.get(layer, group, x);
                return {x: point.x, y: point.y};
            });

            var mid = (function(){
                var center = _.map(['x', 'y'], function(label){
                    return (points[0][label] + points[1][label])/2;
                });
                var abs = Math.sqrt(center[0]*center[0] + center[1]*center[1]);
                var norm = _.map(center, function(c){return c/abs;});
                return ({x: norm[0]*(abs - height), y:norm[1]*(abs - height)});
            })();

            return [points[0], mid ,points[1]];
        });
        
    };

    Connector.prototype.updateModels = function(data){
        var scales = this.scales;
        var layer = this.layer;
        var options = this.options;

        var groups = this.model.selectAll("g")
                .data(data)
                .enter()
                .append("g");
        
        groups.append("path")
            .attr("d", d3.svg.line()
                  .tension(0.2)
                  .x(function(d){return d.x;})
                  .y(function(d){return d.y;})
                  .interpolate("cardinal"))
            .attr("fill", "none")
            .attr("stroke", options.color)
            .attr("stroke-width", options.stroke_width);

        groups.append("g")
            .selectAll("path")
            .data(_.filter(_.flatten(data), function(val, i){return i%3 != 1;}))
            .enter()
            .append("path")
            .attr("d" ,d3.svg.symbol().type(options.shape).size(options.size))
            .attr("fill", options.shape_fill)
            .attr("stroke", options.shape_stroke)
            .attr("stroke-width", options.shape_stroke_width)
            .attr("transform", function(d){return 'translate(' + d.x + ',' + d.y + ')';});
    };

    Connector.prototype.getLegend = function(){
        return;
    };

    Connector.prototype.checkSelectedData = function(ranges){
        return;
    };

    return Connector;
});

define('diagrams/labels',['tools'], function(Tools){
    var _ = Tools._;
    var Manager = Tools.Manager;

    function Labels(parent, scales, df_id, _options){
        var options = {
            color: "#000",
            fill_by: null,
            x: null,
            text: null,
            stroke_width: 4,
            text_size: '1em',
            layer: 1
        };
        if(arguments.length>3)_.extend(options, _options);

        this.model = (function(){
            var center = scales.getCenter();
            return parent.append("g").attr('transform', 'translate(' + center.x + ',' + center.y + ')');
        })();

        this.scales = scales;
        this.df = Manager.getData(df_id);
        this.uuid = options.uuid;
        this.options = options;
    }

    Labels.prototype.update = function(){
        var groups = this.scales.groups();
        var thisObj = this;
        _.each(groups, function(group, i){
            var x = thisObj.df.nested_column(i, thisObj.options.x);
            var text = thisObj.df.nested_column(i, thisObj.options.text);
            var data = thisObj.processData(group, x, text);
            thisObj.updateModels(data);
        });
    };
    
    Labels.prototype.processData = function(group, x, text){
        var scales = this.scales, layer = this.options.layer;
        return _.filter(_.map(_.zip(x, text), function(row){
            return {theta: scales.get(layer, group, row[0]).theta,text: row[1]};
        }), function(row){return row.text != null && row.text.length > 0;});
    };

    Labels.prototype.updateModels = function(data){
        var scales = this.scales, layer = this.options.layer, options = this.options;
        var inner_radius = scales.getRange(layer)[0];

        var groups = this.model.append("g")
                .selectAll("g")
                .data(data)
                .enter()
                .append("g")
                .attr("transform", function(d){
                    return "rotate(" + 180*((d.theta-Math.PI/2)/Math.PI) + ")";
                });
        
        groups.append("text")
            .text(function(d){return d.text;})
            .attr("text-anchor", "start")
            .attr("dominant-baseline", "middle")
            .attr("fill", options.color)
            .attr("x", inner_radius + 10)
            .attr("y", 0)
            .attr("font-size", options.text_size);

        groups.append("line")
            .attr("x1", inner_radius)
            .attr("x2", inner_radius + 5)
            .attr("y1", 0)
            .attr("y2", 0)
            .attr("stroke", "#000");
    };

    Labels.prototype.getLegend = function(){
        return;
    };

    Labels.prototype.checkSelectedData = function(ranges){
        return;
    };

    return Labels;
});

define('main',['require','exports','module','components/scale','components/axis','diagrams/arc','diagrams/connector','diagrams/labels'],function(require, exports, module){
    var Bionya = {};
    Bionya.Nya = {
        'scale':require('components/scale'),
        'axis':require('components/axis'),
        'diagrams': {
            'arc': require('diagrams/arc'),
            'connector': require('diagrams/connector'),
            'labels': require('diagrams/labels')
        }
    };

    return Bionya;
});

return require('main');
}));