<commit_before>/**
 * Created by jag on 14/04/2014.
 */
var genomeViewer;
angular.module('variantWidgetModule', []).directive('variantWidget', function () {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        templateUrl: 'views/variation-browser-view.html',
        controller: function($scope) {
        },
        link: function($scope, element, attr) {

            var location = '21:9411240-9711260';
            //var gene = 'TMEM51';
            $scope.location = location;
            $scope.gene = gene;

            var conTypeTree;
            var studiesTree;
            var varClassesTree;

            $scope.variantTableId            = 'variantBrowserTable';
            $scope.variantEffectTableId      = 'variantEffectTable';
            $scope.variantFilesTableId       = 'variantFilesTable';
            $scope.variantStatsViewId        = 'variantStatsView';
            $scope.variantStatsChartId       = 'variantStatsChart';
            $scope.variantGenoTypeTableId    = 'variantGenoTypeTable';
            $scope.variantGenomeViewerId     = 'variant-browser-gv';
            $scope.variantBrowserSubTabsId   = 'variantSubTabs';
            $scope.studiesTreeId             = 'studiesTreeID';
            $scope.consequenceTypeTreeId     = 'consequenceTypeTreeID';
            $scope.variationClassesTreeId    = 'variationClassesTreeID';

            $scope.searchVariants = function(){
                eventManager.trigger("variant:search");
            }

            $scope.reloadVariants = function(){
                $scope.location = location;
                // $scope.gene = gene;
                eventManager.trigger("variant:search");
            }

            $scope.clearVariants = function(){
                $scope.location = '';
                $scope.gene = '';
                clearCheckedFilters(studiesTree);
                clearCheckedFilters(conTypeTree);
                clearCheckedFilters(varClassesTree);
                eventManager.trigger("variant:search");
            }

            jQuery('#topMenuTab a[data-toggle="tab"]').on('shown.bs.tab', function (e) {

                var variantTreeWidget;
                variantTreeWidget = new VariantWidget({});

                var studiesTreeArgs = [];
                studiesTreeArgs.id =  $scope.studiesTreeId;
                studiesTreeArgs.data = $scope.studies;

                var consequenceTypeTreeArgs = [];
                consequenceTypeTreeArgs.id =  $scope.consequenceTypeTreeId;
                consequenceTypeTreeArgs.data = consequenceTypes;

                var variationClassesTreeArgs = [];
                variationClassesTreeArgs.id =  $scope.variationClassesTreeId;
                variationClassesTreeArgs.data = variationClasses;

                if(e.target.parentElement.id === 'variationLi'){

                    if(jQuery("#"+$scope.studiesTreeId).contents().length === 0 ){
                        studiesTree = variantTreeWidget.createTreePanel(studiesTreeArgs);
                    }
                    if(jQuery("#"+$scope.consequenceTypeTreeId).contents().length === 0 ){
                        conTypeTree = variantTreeWidget.createTreePanel(consequenceTypeTreeArgs);
                    }

                    if(jQuery("#"+$scope.variationClassesTreeId).contents().length === 0 ){
                        varClassesTree = variantTreeWidget.createTreePanel(variationClassesTreeArgs);
                    }
                    eventManager.trigger("variant:search");
                }

            });

            eventManager.on("gene:search variant:search" , function(e) {
                updateRegion( $scope.gene);
            });

            eventManager.on("variant:search", function(e) {

                var studyFilter  = getCheckedFilters(studiesTree.getView().getChecked());
                var conTypeFilter  = getCheckedFilters(conTypeTree.getView().getChecked());
                var varClassesFilter  = getCheckedFilters(varClassesTree.getView().getChecked());

//                    console.log(studyFilter)
//                    console.log(conTypeFilter)
//                    console.log(varClassesFilter)
                console.log(studyFilter)
                console.log(conTypeFilter)

                if(conTypeFilter){
                    $scope.CTfilter = '&effect='+conTypeFilter;
                }else{
                    $scope.CTfilter = '';
                }

                if(studyFilter){
                    $scope.studyFilter = '&studies='+studyFilter;
                }else{
                    $scope.studyFilter = '';
                }

                $scope.filters =  $scope.CTfilter+$scope.studyFilter;

                var variantWidget;
                variantWidget = new VariantWidget({
                    variantTableID          : $scope.variantTableId,
                    variantEffectTableID    : $scope.variantEffectTableId,
                    variantFilesTableID     : $scope.variantFilesTableId,
                    variantStatsViewID      : $scope.variantStatsViewId,
                    variantStatsChartID     : $scope.variantStatsChartId,
                    variantGenoTypeTableID  : $scope.variantGenoTypeTableId,
                    location                : $scope.location,
                    filters                 : $scope.filters,
                    variantGenomeViewerID   : $scope.variantGenomeViewerId,
                    variantSubTabsID        : $scope.variantBrowserSubTabsId,
                });

                variantWidget.draw();

                if(!genomeViewer.rendered) {
                    genomeViewer.render();
                    genomeViewer.draw();
                    genomeViewer.addTrack(tracks);
                    genomeViewer.addOverviewTrack(geneOverview);
                }

                var region = new Region();
                region.parse($scope.location);
                genomeViewer.setRegion(region);

            });

            var region = new Region({chromosome: "13", start: 32889611, end: 32889611});
            var availableSpecies = {
                "text": "Species",
                "items": [
                    {
                        "text": "Vertebrates",
                        "items": [
                            {"text": "Homo sapiens", "assembly": "GRCh37.p10", "region": {"chromosome": "13", "start": 32889611, "end": 32889611}, "chromosomes": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "X", "Y", "MT"], "url": "ftp://ftp.ensembl.org/pub/release-71/"},
                            {"text": "Mus musculus", "assembly": "GRCm38.p1", "region": {"chromosome": "1", "start": 18422009, "end": 18422009}, "chromosomes": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "X", "Y", "MT"], "url": "ftp://ftp.ensembl.org/pub/release-71/"}
                        ]
                    }
                ]
            };
            var species = availableSpecies.items[0].items[0];

            genomeViewer = new GenomeViewer({
                targetId: 'variant-browser-gv',
                region: region,
                availableSpecies: availableSpecies,
                species: species,
                sidePanel: false,
                autoRender: false,
                border: true,
                resizable: true,
                karyotypePanelConfig: {
                    collapsed: false,
                    collapsible: true
                },
                chromosomePanelConfig: {
                    collapsed: false,
                    collapsible: true
                },
                handlers:{
                    'region:change':function(e){
                        console.log(e)
                    }
                }
            }); //the div must exist

            var tracks = [];
            var sequence = new SequenceTrack({
                targetId: null,
                id: 1,
                height: 30,
                visibleRegionSize: 200,

                renderer: new SequenceRenderer(),

                dataAdapter: new SequenceAdapter({
                    category: "genomic",
                    subCategory: "region",
                    resource: "sequence",
                    species: genomeViewer.species
                })
            });
            tracks.push(sequence);

            var gene = new GeneTrack({
                targetId: null,
                id: 2,
                title: 'Gene',
                minHistogramRegionSize: 20000000,
                maxLabelRegionSize: 10000000,
                minTranscriptRegionSize: 200000,
                height: 140,

                renderer: new GeneRenderer(),

                dataAdapter: new CellBaseAdapter({
                    category: "genomic",
                    subCategory: "region",
                    resource: "gene",
                    species: genomeViewer.species,
                    params: {
                        exclude: 'transcripts.tfbs,transcripts.xrefs,transcripts.exons.sequence'
                    },
                    cacheConfig: {
                        chunkSize: 100000
                    }
                })
            });
            tracks.push(gene);

            var renderer = new FeatureRenderer(FEATURE_TYPES.gene);
            renderer.on({
                'feature:click': function (event) {
                    // feature click event example
                    console.log(event)
                }
            });
            var geneOverview = new FeatureTrack({
                targetId: null,
                id: 2,
//        title: 'Gene',
                minHistogramRegionSize: 20000000,
                maxLabelRegionSize: 10000000,
                height: 100,

                renderer: renderer,

                dataAdapter: new CellBaseAdapter({
                    category: "genomic",
                    subCategory: "region",
                    resource: "gene",
                    params: {
                        exclude: 'transcripts'
                    },
                    species: genomeViewer.species,
                    cacheConfig: {
                        chunkSize: 100000
                    }
                })
            });

            this.snp = new FeatureTrack({
                targetId: null,
                id: 4,
                title: 'SNP',
                featureType:'SNP',
                minHistogramRegionSize: 12000,
                maxLabelRegionSize: 3000,
                height: 100,

                renderer: new FeatureRenderer(FEATURE_TYPES.snp),

                dataAdapter: new CellBaseAdapter({
                    category: "genomic",
                    subCategory: "region",
                    resource: "snp",
                    params: {
                        exclude: 'transcriptVariations,xrefs,samples'
                    },
                    species: genomeViewer.species,
                    cacheConfig: {
                        chunkSize: 10000
                    }
                })
            });

            tracks.push(this.snp);

//            genomeViewer.draw();

            //function to update region by geneId
            function updateRegion(args){
                if(args){
                    var geneInfoURL = CELLBASE_HOST+'/'+CELLBASE_VERSION+'/hsa/feature/gene/'+$scope.gene+'/info?of=json';

                    var regionData;
                    CellBaseManager.get({
                        species: 'hsa',
                        category: 'feature',
                        subCategory: 'gene',
                        resource: 'info',
                        query: $scope.gene,
                        async: false,
                        success: function (data) {
                            regionData = data;
                        },
                        error: function (data) {
                            console.log('Could not get variant effects list');
                        }
                    });

                    var region = regionData[0][0].chromosome+':'+regionData[0][0].start+'-'+regionData[0][0].end;
                    $scope.$apply(function(){
                        $scope.location = region;
                    })

                }
            }

            //Function to get checked filters
            function getCheckedFilters(args){
                if(args.length > 0){
                    var filters = [];
                    Ext.Array.each(args , function(rec){
                        filters.push(rec.get('name'));
                    });
                    return filters.join();
                }
            }

            //Function to clear checked filters
            function clearCheckedFilters(args){
                args.store.getRootNode().cascadeBy(function(){
                    this.set( 'checked', false );
                });
            }

        }

    };

}).directive('variantView', function () {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        templateUrl: 'views/variant-view.html',
        controller: function($scope) {
        },
        link: function($scope, element, attr) {

            var data = getUrlParameters("");

            if(data.value){
                var variantData;
                evaManager.get({
                    category: 'variants',
                    resource: 'info',
                    params: {
                        of: 'json'
                    },
                    query: data.value,
                    async: false,
                    success: function (data) {
                        variantData = data;
                    },
                    error: function (data) {
                        console.log('Could not get variant info');
                    }
                });
                var tmpData = variantData;

            }else{
                return;
            }
            if(!tmpData || !tmpData.response.numResults){
                return;
            }

            $scope.variant = data.value;

            $scope.variantInfoData  = tmpData.response.result[0];

            var position = $scope.variantInfoData.chr + ":" + $scope.variantInfoData.start + ":" + $scope.variantInfoData.ref + ":" + $scope.variantInfoData.alt;
            var effectsTempData;
            CellBaseManager.get({
                species: 'hsa',
                category: 'genomic',
                subCategory: 'variant',
                resource: 'consequence_type',
                query: position,
                async: false,
                success: function (data) {
                    effectsTempData = data;
                },
                error: function (data) {
                    console.log('Could not get variant effects list');
                }
            });
            var effectsTempDataArray = [];

            $.each(effectsTempData, function(key, value) {
                var consequenceType = value.consequenceType;
                if(!effectsTempDataArray[consequenceType]) effectsTempDataArray[consequenceType] = [];
                effectsTempDataArray[consequenceType].push({'featureId':value.featureId,'featureType':value.featureType,'featureChromosome':value.featureChromosome,'featureStart':value.featureStart,'featureEnd':value.featureEnd,'consequenceTypeType':value.consequenceTypeType});
            });

            var effectsDataArray = new Array();
            for (key in effectsTempDataArray){
                effectsDataArray.push({id:key,name:effectsTempDataArray[key][0].consequenceTypeType,data:effectsTempDataArray[key]});
            }

            $scope.effectsData = effectsDataArray;

            var variantStudyWidget;
            variantStudyWidget = new VariantStudyWidget({
                render_id    : 'variantViewStudyID',
                variantId    :  data.value
            });

            variantStudyWidget.draw('files');

        }

    };

});<commit_msg>study filter and submisiion form added<commit_after>/**
 * Created by jag on 14/04/2014.
 */
var genomeViewer;
angular.module('variantWidgetModule', []).directive('variantWidget', function () {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        templateUrl: 'views/variation-browser-view.html',
        controller: function($scope) {
        },
        link: function($scope, element, attr) {

            var location = '21:9411240-9711260';
            //var gene = 'TMEM51';
            $scope.location = location;
            $scope.gene = gene;

            var conTypeTree;
            var studiesTree;
            var varClassesTree;

            $scope.variantTableId            = 'variantBrowserTable';
            $scope.variantEffectTableId      = 'variantEffectTable';
            $scope.variantFilesTableId       = 'variantFilesTable';
            $scope.variantStatsViewId        = 'variantStatsView';
            $scope.variantStatsChartId       = 'variantStatsChart';
            $scope.variantGenoTypeTableId    = 'variantGenoTypeTable';
            $scope.variantGenomeViewerId     = 'variant-browser-gv';
            $scope.variantBrowserSubTabsId   = 'variantSubTabs';
            $scope.studiesTreeId             = 'studiesTreeID';
            $scope.consequenceTypeTreeId     = 'consequenceTypeTreeID';
            $scope.variationClassesTreeId    = 'variationClassesTreeID';

            $scope.searchVariants = function(){
                eventManager.trigger("variant:search");
            }

            $scope.reloadVariants = function(){
                $scope.location = location;
                // $scope.gene = gene;
                eventManager.trigger("variant:search");
            }

            $scope.clearVariants = function(){
                $scope.location = '';
                $scope.gene = '';
                clearCheckedFilters(studiesTree);
                clearCheckedFilters(conTypeTree);
                clearCheckedFilters(varClassesTree);
                eventManager.trigger("variant:search");
            }

            jQuery('#topMenuTab a[data-toggle="tab"]').on('shown.bs.tab', function (e) {

                var variantTreeWidget;
                variantTreeWidget = new VariantWidget({});

                var studiesTreeArgs = [];
                studiesTreeArgs.id =  $scope.studiesTreeId;
                studiesTreeArgs.data = $scope.studies;

                var consequenceTypeTreeArgs = [];
                consequenceTypeTreeArgs.id =  $scope.consequenceTypeTreeId;
                consequenceTypeTreeArgs.data = consequenceTypes;

                var variationClassesTreeArgs = [];
                variationClassesTreeArgs.id =  $scope.variationClassesTreeId;
                variationClassesTreeArgs.data = variationClasses;

                if(e.target.parentElement.id === 'variationLi'){

                    if(jQuery("#"+$scope.studiesTreeId).contents().length === 0 ){
                        studiesTree = variantTreeWidget.createTreePanel(studiesTreeArgs);
                    }
                    if(jQuery("#"+$scope.consequenceTypeTreeId).contents().length === 0 ){
                        conTypeTree = variantTreeWidget.createTreePanel(consequenceTypeTreeArgs);
                    }

                    if(jQuery("#"+$scope.variationClassesTreeId).contents().length === 0 ){
                        varClassesTree = variantTreeWidget.createTreePanel(variationClassesTreeArgs);
                    }
                    eventManager.trigger("variant:search");
                }

            });

            eventManager.on("gene:search variant:search" , function(e) {
                updateRegion( $scope.gene);
            });

            eventManager.on("variant:search", function(e) {

                var studyFilter  = getCheckedFilters(studiesTree.getView().getChecked());
                var conTypeFilter  = getCheckedFilters(conTypeTree.getView().getChecked());
                var varClassesFilter  = getCheckedFilters(varClassesTree.getView().getChecked());

//                    console.log(studyFilter)
//                    console.log(conTypeFilter)
//                    console.log(varClassesFilter)

                if(conTypeFilter){
                    $scope.CTfilter = '&effect='+conTypeFilter;
                }else{
                    $scope.CTfilter = '';
                }

                if(studyFilter){
                    $scope.studyFilter = '&studies='+studyFilter;
                }else{
                    $scope.studyFilter = '';
                }

                $scope.filters =  $scope.CTfilter+$scope.studyFilter;

                var variantWidget;
                variantWidget = new VariantWidget({
                    variantTableID          : $scope.variantTableId,
                    variantEffectTableID    : $scope.variantEffectTableId,
                    variantFilesTableID     : $scope.variantFilesTableId,
                    variantStatsViewID      : $scope.variantStatsViewId,
                    variantStatsChartID     : $scope.variantStatsChartId,
                    variantGenoTypeTableID  : $scope.variantGenoTypeTableId,
                    location                : $scope.location,
                    filters                 : $scope.filters,
                    variantGenomeViewerID   : $scope.variantGenomeViewerId,
                    variantSubTabsID        : $scope.variantBrowserSubTabsId,
                });

                variantWidget.draw();

                if(!genomeViewer.rendered) {
                    genomeViewer.render();
                    genomeViewer.draw();
                    genomeViewer.addTrack(tracks);
                    genomeViewer.addOverviewTrack(geneOverview);
                }

                var region = new Region();
                region.parse($scope.location);
                genomeViewer.setRegion(region);

            });

            var region = new Region({chromosome: "13", start: 32889611, end: 32889611});
            var availableSpecies = {
                "text": "Species",
                "items": [
                    {
                        "text": "Vertebrates",
                        "items": [
                            {"text": "Homo sapiens", "assembly": "GRCh37.p10", "region": {"chromosome": "13", "start": 32889611, "end": 32889611}, "chromosomes": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "X", "Y", "MT"], "url": "ftp://ftp.ensembl.org/pub/release-71/"},
                            {"text": "Mus musculus", "assembly": "GRCm38.p1", "region": {"chromosome": "1", "start": 18422009, "end": 18422009}, "chromosomes": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "X", "Y", "MT"], "url": "ftp://ftp.ensembl.org/pub/release-71/"}
                        ]
                    }
                ]
            };
            var species = availableSpecies.items[0].items[0];

            genomeViewer = new GenomeViewer({
                targetId: 'variant-browser-gv',
                region: region,
                availableSpecies: availableSpecies,
                species: species,
                sidePanel: false,
                autoRender: false,
                border: true,
                resizable: true,
                karyotypePanelConfig: {
                    collapsed: false,
                    collapsible: true
                },
                chromosomePanelConfig: {
                    collapsed: false,
                    collapsible: true
                },
                handlers:{
                    'region:change':function(e){
                        console.log(e)
                    }
                }
            }); //the div must exist

            var tracks = [];
            var sequence = new SequenceTrack({
                targetId: null,
                id: 1,
                height: 30,
                visibleRegionSize: 200,

                renderer: new SequenceRenderer(),

                dataAdapter: new SequenceAdapter({
                    category: "genomic",
                    subCategory: "region",
                    resource: "sequence",
                    species: genomeViewer.species
                })
            });
            tracks.push(sequence);

            var gene = new GeneTrack({
                targetId: null,
                id: 2,
                title: 'Gene',
                minHistogramRegionSize: 20000000,
                maxLabelRegionSize: 10000000,
                minTranscriptRegionSize: 200000,
                height: 140,

                renderer: new GeneRenderer(),

                dataAdapter: new CellBaseAdapter({
                    category: "genomic",
                    subCategory: "region",
                    resource: "gene",
                    species: genomeViewer.species,
                    params: {
                        exclude: 'transcripts.tfbs,transcripts.xrefs,transcripts.exons.sequence'
                    },
                    cacheConfig: {
                        chunkSize: 100000
                    }
                })
            });
            tracks.push(gene);

            var renderer = new FeatureRenderer(FEATURE_TYPES.gene);
            renderer.on({
                'feature:click': function (event) {
                    // feature click event example
                    console.log(event)
                }
            });
            var geneOverview = new FeatureTrack({
                targetId: null,
                id: 2,
//        title: 'Gene',
                minHistogramRegionSize: 20000000,
                maxLabelRegionSize: 10000000,
                height: 100,

                renderer: renderer,

                dataAdapter: new CellBaseAdapter({
                    category: "genomic",
                    subCategory: "region",
                    resource: "gene",
                    params: {
                        exclude: 'transcripts'
                    },
                    species: genomeViewer.species,
                    cacheConfig: {
                        chunkSize: 100000
                    }
                })
            });

            this.snp = new FeatureTrack({
                targetId: null,
                id: 4,
                title: 'SNP',
                featureType:'SNP',
                minHistogramRegionSize: 12000,
                maxLabelRegionSize: 3000,
                height: 100,

                renderer: new FeatureRenderer(FEATURE_TYPES.snp),

                dataAdapter: new CellBaseAdapter({
                    category: "genomic",
                    subCategory: "region",
                    resource: "snp",
                    params: {
                        exclude: 'transcriptVariations,xrefs,samples'
                    },
                    species: genomeViewer.species,
                    cacheConfig: {
                        chunkSize: 10000
                    }
                })
            });

            tracks.push(this.snp);

//            genomeViewer.draw();

            //function to update region by geneId
            function updateRegion(args){
                if(args){
                    var geneInfoURL = CELLBASE_HOST+'/'+CELLBASE_VERSION+'/hsa/feature/gene/'+$scope.gene+'/info?of=json';

                    var regionData;
                    CellBaseManager.get({
                        species: 'hsa',
                        category: 'feature',
                        subCategory: 'gene',
                        resource: 'info',
                        query: $scope.gene,
                        async: false,
                        success: function (data) {
                            regionData = data;
                        },
                        error: function (data) {
                            console.log('Could not get variant effects list');
                        }
                    });

                    var region = regionData[0][0].chromosome+':'+regionData[0][0].start+'-'+regionData[0][0].end;
                    $scope.$apply(function(){
                        $scope.location = region;
                    })

                }
            }

            //Function to get checked filters
            function getCheckedFilters(args){
                if(args.length > 0){
                    var filters = [];
                    Ext.Array.each(args , function(rec){
                        filters.push(rec.get('name'));
                    });
                    return filters.join();
                }
            }

            //Function to clear checked filters
            function clearCheckedFilters(args){
                args.store.getRootNode().cascadeBy(function(){
                    this.set( 'checked', false );
                });
            }

        }

    };

}).directive('variantView', function () {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        templateUrl: 'views/variant-view.html',
        controller: function($scope) {
        },
        link: function($scope, element, attr) {

            var data = getUrlParameters("");

            if(data.value){
                var variantData;
                evaManager.get({
                    category: 'variants',
                    resource: 'info',
                    params: {
                        of: 'json'
                    },
                    query: data.value,
                    async: false,
                    success: function (data) {
                        variantData = data;
                    },
                    error: function (data) {
                        console.log('Could not get variant info');
                    }
                });
                var tmpData = variantData;

            }else{
                return;
            }
            if(!tmpData || !tmpData.response.numResults){
                return;
            }

            $scope.variant = data.value;

            $scope.variantInfoData  = tmpData.response.result[0];

            var position = $scope.variantInfoData.chr + ":" + $scope.variantInfoData.start + ":" + $scope.variantInfoData.ref + ":" + $scope.variantInfoData.alt;
            var effectsTempData;
            CellBaseManager.get({
                species: 'hsa',
                category: 'genomic',
                subCategory: 'variant',
                resource: 'consequence_type',
                query: position,
                async: false,
                success: function (data) {
                    effectsTempData = data;
                },
                error: function (data) {
                    console.log('Could not get variant effects list');
                }
            });
            var effectsTempDataArray = [];

            $.each(effectsTempData, function(key, value) {
                var consequenceType = value.consequenceType;
                if(!effectsTempDataArray[consequenceType]) effectsTempDataArray[consequenceType] = [];
                effectsTempDataArray[consequenceType].push({'featureId':value.featureId,'featureType':value.featureType,'featureChromosome':value.featureChromosome,'featureStart':value.featureStart,'featureEnd':value.featureEnd,'consequenceTypeType':value.consequenceTypeType});
            });

            var effectsDataArray = new Array();
            for (key in effectsTempDataArray){
                effectsDataArray.push({id:key,name:effectsTempDataArray[key][0].consequenceTypeType,data:effectsTempDataArray[key]});
            }

            $scope.effectsData = effectsDataArray;

            var variantStudyWidget;
            variantStudyWidget = new VariantStudyWidget({
                render_id    : 'variantViewStudyID',
                variantId    :  data.value
            });

            variantStudyWidget.draw('files');

        }

    };

});<|endoftext|>


<commit_before>/*
 * https://github.com/FarmBuild/farmbuild-dairy-nutrient-calculator/wiki/TC09:-Calculate-nutrient-of-fertilizer-purchased-(new-farm-data)
 * */

describe('Calculate nutrient of fertilizer purchased (new farm data)', function() {

  describe('Using FarmBuild Nutrient Calculator to calculate the weighted average for fertilizer purchased (Dried & Wet)', function() {

    var page = 'angularjs/fertilizers-purchased/index.html',
      title = 'Farmbuild Diary Nutrient Calculator - Fertilizer Purchased (angularJS)'

    beforeEach(function() {
      browser.get(page);
    });

    it('should render sample when user navigates to angularjs/fertilizers-purchased/index.html', function() {
      expect(element.all(by.css('body h3')).first().getText()).toContain(title);
    });

    var selectDropdownbyNum = function ( element, optionNum ) {
      if (!optionNum){
        return undefined;
      };
      var options = element.findElements(by.tagName('option'))
        .then(function(options){
          options[optionNum].click();
        });
    };
    it('Select a Fertilizer Purchased Type to be "DAP"', function() {
//      var select =element(by.id('fertilizerType'));

//      expect(select).toBe();

//      expect(selectDropdownbyNum(select, 1));

//      expect(element(by.model('newFertilizer.weight')).sendKeys('1000').getAttribute('value')).
//        toBe('1000');
//      element(by.buttonText('Add fertilizer')).click().then(function(){
//        expect(element.all(by.css('table#fertilizersTbl tr')).count()).
//          toMatch(3);
//      });
    });

//    it('Enter 1000 kg/year as Amount Purchased', function() {
//      var weight = 1000, type = 'Lucerne Hay';
//      expect(element(by.model('newFertilizer.type')).sendKeys(type));
//      expect(element(by.model('newFertilizer.weight')).sendKeys(weight).getAttribute('value')).
//        toBe('1000');
//      element(by.buttonText('Add fertilizer')).click().then(function(){
//        expect(element.all(by.css('table#fertilizersTbl tr')).count()).
//          toMatch(3);
//      })
//      element(by.buttonText('Calculate nutrient')).click().then(function(){
//        expect(element.all(by.css('summary .form-group')).first().getText()).
//          toMatch('1,000');
//      });
//    });

  });

});
<commit_msg>proceeded with e2e<commit_after>/*
 * https://github.com/FarmBuild/farmbuild-dairy-nutrient-calculator/wiki/TC09:-Calculate-nutrient-of-fertilizer-purchased-(new-farm-data)
 * */

describe('Calculate nutrient of fertilizer purchased (new farm data)', function() {

  describe('Using FarmBuild Nutrient Calculator to calculate the weighted average for fertilizer purchased (Dried & Wet)', function() {

    var page = 'angularjs/fertilizers-purchased/index.html',
      title = 'Farmbuild Diary Nutrient Calculator - Fertilizer Purchased (angularJS)'

    beforeEach(function() {
      browser.get(page);
    });

    it('should render sample when user navigates to angularjs/fertilizers-purchased/index.html', function() {
      expect(element.all(by.css('body h3')).first().getText()).toContain(title);
    });

    it('Select a Fertilizer Purchased Type to be "DAP"', function() {
      expect(element(by.model('newFertilizer.type')).sendKeys('DAP'));
      expect(element(by.model('newFertilizer.weight')).sendKeys('1000').getAttribute('value')).
        toBe('1000');
      expect(element(by.model('newFertilizer.isDry')).sendKeys('Dry'));
      //expect(element(by.model('newFertilizer.type.dryMatterPercentage'))).toBe(100);

//      element(by.buttonText('Add fertilizer')).click().then(function(){
//        expect(element.all(by.css('table#fertilizersTbl tr')).count()).
//          toMatch(3);
//      });
    });

//    it('Enter 1000 kg/year as Amount Purchased', function() {
//      var weight = 1000, type = 'Lucerne Hay';
//      expect(element(by.model('newFertilizer.type')).sendKeys(type));
//      expect(element(by.model('newFertilizer.weight')).sendKeys(weight).getAttribute('value')).
//        toBe('1000');
//      element(by.buttonText('Add fertilizer')).click().then(function(){
//        expect(element.all(by.css('table#fertilizersTbl tr')).count()).
//          toMatch(3);
//      })
//      element(by.buttonText('Calculate nutrient')).click().then(function(){
//        expect(element.all(by.css('summary .form-group')).first().getText()).
//          toMatch('1,000');
//      });
//    });

  });

});
<|endoftext|>


<commit_before>import React from 'react';

import { storiesOf } from '@storybook/react';

import { Button } from '@storybook/react/demo';

for (let i = 0; i < 0; i += 1) {
  const randomDemoName = Math.random()
    .toString(36)
    .substring(7);
  const stories = storiesOf(`Perf|${i}/${randomDemoName}`);

  for (let j = 0; j < 100; j += 1) {
    stories
      .add(`with text ${j}`, () => <Button>Hello Button</Button>)
      .add(`with emoji ${j}`, () => (
        <Button>

            😀 😎 👍 💯

        </Button>
      ));
  }
}
<commit_msg>Cra-kitchen-sink: Simplify perf test<commit_after>import React from 'react';

import { storiesOf } from '@storybook/react';

import { Button } from '@storybook/react/demo';

for (let i = 0; i < 1; i += 1) {
  const randomDemoName = Math.random()
    .toString(36)
    .substring(7);
  const stories = storiesOf(`Perf.${randomDemoName}`);

  for (let j = 0; j < 10; j += 1) {
    stories
      .add(`with text ${j}`, () => <Button>Hello Button</Button>)
      .add(`with emoji ${j}`, () => (
        <Button>

            😀 😎 👍 💯

        </Button>
      ));
  }
}
<|endoftext|>


<commit_before>const path = require('path')
const util = require('util')
const mkdirp = require('mkdirp')
const fs = require('fs')
const { readObjects, readFile } = require('@frontiernav/filesystem')
const { mapMappings, tileMappings } = require('./mappings')
const csv = require('csv')
const parseCSV = util.promisify(csv.parse)
const _ = require('lodash')
const log = require('pino')({ prettyPrint: true }).child({ name: path.basename(__filename, '.js') })
const jsdom = require('jsdom')
const { JSDOM } = jsdom
const Collectibles = require('./entities/Collectibles')
const CollectionPoints = require('./entities/CollectionPoints')
const FieldSkills = require('./entities/FieldSkills')
const Locations = require('./entities/Locations')

const dom = new JSDOM('')
global.window = dom.window
global.document = dom.window.document
global.navigator = dom.window.navigator

const L = require('leaflet')

function toTiles ({ content }) {
  return _(content)
    .mapValues(row => {
      const mapping = _.find(tileMappings, mapping => mapping.game_id === row.Name)
      return {
        ...row,
        mapping
      }
    })
    .value()
}

function withinBox ({ point: { x, y, z }, box: { minX, maxX, minY, maxY, minZ, maxZ } }) {
  return (x > minX && y > minY && z > minZ) && (x < maxX && y < maxY && z < maxZ)
}

function assignTarget ({ marker, Target }) {
  return Target.getByName({ name: marker.game_id })
    .then(target => {
      marker.target = target.name
      return marker
    })
}

function getLatLng({ region, coords }) {
  /*
 * Y is altitude
 */
  const tile = _(region.tiles)
    .filter(tile => {
      return withinBox({
        point: {
          x: coords.PosX,
          y: coords.PosY,
          z: coords.PosZ
        },
        box: {
          minX: tile.LowerX,
          maxX: tile.UpperX,
          minY: tile.LowerY,
          maxY: tile.UpperY,
          minZ: tile.LowerZ,
          maxZ: tile.UpperZ
        }
      })
    })
    .orderBy('Priority')
    .head()

  if (!tile) {
    return Promise.reject(new Error(`MapTile not found for Coords[${coords.Name}] in Region[${region.gameId}]`))
  }

  const widthBigger = tile.Width > tile.Height

  const pixel = L.point(coords.PosX, coords.PosZ)
    .add(
      // Relative to the map it's on
      L.point(-tile.LowerX, -tile.LowerZ)
    )
    .multiplyBy(2) // Game coords are scaled down for some reason.
    .add(
      // Adjust to squared tiles
      widthBigger
        ? L.point(0, (tile.Width - tile.Height) / 2) // Move down
        : L.point((tile.Height - tile.Width) / 2, 0) // Move right
    )

  const zoom = L.CRS.EPSG3857.zoom(widthBigger ? tile.Width : tile.Height)
  return Promise.resolve({
    coords,
    tile,
    latLng: L.CRS.EPSG3857.pointToLatLng(pixel, zoom)
  })
}

function createMarker ({ coords, tile, latLng }) {
  return {
    name: `${coords.Name} (Map Feature)`,
    game_id: coords.Name,
    map: tile.mapping.map_name,
    target: '',
    geometry: JSON.stringify({
      type: 'Point',
      'coordinates': [
        latLng.lng,
        latLng.lat
      ]
    }),
    shape: 'image',
    notes: ''
  }
}

function toMarkers ({ region, content, Target }) {
  return Promise
    .all((
      content
        .filter(row => !!row.Name)
        .map(coords => (
          getLatLng({ region, coords })
            .then(({ coords, latLng, tile }) => createMarker({ coords, latLng, tile }))
            .then(marker => assignTarget({ Target, marker }))
            .catch(e => {
              log.warn(e)
              return null
            })
        ))
    ))
    .then(markers => markers.filter(marker => !!marker))
}

function toRegion ({ absoluteFilePath, content }) {
  const gameId = path.basename(absoluteFilePath, '.csv')
  const mapping = _.find(mapMappings, mapping => mapping.game_id === gameId)
  return {
    absoluteFilePath,
    gameId,
    mapping,
    tiles: toTiles({ absoluteFilePath, content })
  }
}

const getAllRawMarkers = _.memoize(() => {
  return readFile(path.resolve(__dirname, '../data/all.csv'))
    .then(content => parseCSV(content, { columns: true, auto_parse: true }))
})

function getMarkersForRegion ({ region, type, Target }) {
  return getAllRawMarkers()
    .then(markers => markers
      .filter(marker => marker.Map === region.gameId && marker.Filename === type)
    )
    .then(content => toMarkers({ Target, region, content }))
}

function parseMapFeatures ({ absoluteFilePath, content }) {
  return Promise.resolve(content)
    .then(content => toRegion({ absoluteFilePath, content }))
    .then(region => {
      return Promise
        .all([
          getMarkersForRegion({ region, type: 'collection', Target: CollectionPoints }),
          getMarkersForRegion({ region, type: 'landmark', Target: Locations })
        ])
    })
    .then(featuresPerType => _.flatten(featuresPerType))
}

function toTSV ({ objects }) {
  return _(objects)
    .map(row => _(row)
      .map(v => typeof v === 'object' ? JSON.stringify(v) : `${v}`)
      .map(v => v.replace(/"/g, '""'))
      .map(v => `"${v}"`)
      .join('\t')
    )
    .join('\n')
}

function writeOut ({ filename, content }) {
  const outputPath = path.resolve(__dirname, '../out')
  mkdirp.sync(outputPath)

  const filePath = path.resolve(outputPath, filename)
  log.info('Writing', filePath)
  fs.writeFileSync(filePath, content)
}

CollectionPoints.getAll()
  .then(result => toTSV({ objects: result }))
  .then(result => writeOut({ filename: 'CollectionPoints.tsv', content: result }))

Collectibles.getAll()
  .then(result => toTSV({ objects: result }))
  .then(result => writeOut({ filename: 'Collectibles.tsv', content: result }))

FieldSkills.getAll()
  .then(result => toTSV({ objects: result }))
  .then(result => writeOut({ filename: 'FieldSkills.tsv', content: result }))

Locations.getAll()
  .then(result => toTSV({ objects: result }))
  .then(result => writeOut({ filename: 'Locations.tsv', content: result }))

const inputPath = path.resolve(__dirname, '../data/mapinfo')
log.info('Reading files', inputPath)
const result = readObjects(
  inputPath,
  i => i,
  {
    '.csv': content => parseCSV(content, { columns: true, objname: 'Name', auto_parse: true })
  }
)

Promise
  .all(
    result.map(({ absoluteFilePath, content: contentPromise }) => {
      return contentPromise
        .then(content => parseMapFeatures({ absoluteFilePath, content }))
        .catch(error => {
          log.warn(absoluteFilePath, error)
        })
    })
  )
  .then(results => results.reduce((acc, next) => {
    return acc.concat(next)
  }, []))
  .then(mapFeatures => toTSV({ objects: mapFeatures }))
  .then(result => {
    writeOut({ filename: 'MapFeatures.tsv', content: result })
  })
<commit_msg>refactor: group and memoize markers before parsing<commit_after>const path = require('path')
const util = require('util')
const mkdirp = require('mkdirp')
const fs = require('fs')
const { readObjects, readFile } = require('@frontiernav/filesystem')
const { mapMappings, tileMappings } = require('./mappings')
const csv = require('csv')
const parseCSV = util.promisify(csv.parse)
const _ = require('lodash')
const pino = require('pino')
const log = pino({
  prettyPrint: true,
  serializers: {
    error: pino.stdSerializers.err
  }
}).child({ name: path.basename(__filename, '.js') })
const jsdom = require('jsdom')
const { JSDOM } = jsdom
const Collectibles = require('./entities/Collectibles')
const CollectionPoints = require('./entities/CollectionPoints')
const FieldSkills = require('./entities/FieldSkills')
const Locations = require('./entities/Locations')

const dom = new JSDOM('')
global.window = dom.window
global.document = dom.window.document
global.navigator = dom.window.navigator

const L = require('leaflet')

function toTiles ({ mapInfo }) {
  return _(mapInfo)
    .mapValues(rawTile => {
      const mapping = _.find(tileMappings, mapping => mapping.game_id === rawTile.Name)
      return {
        ...rawTile,
        mapping
      }
    })
    .value()
}

function withinBox ({ point: { x, y, z }, box: { minX, maxX, minY, maxY, minZ, maxZ } }) {
  return (x > minX && y > minY && z > minZ) && (x < maxX && y < maxY && z < maxZ)
}

function assignTarget ({ marker, Target }) {
  return Target.getByName({ name: marker.game_id })
    .then(target => {
      marker.target = target.name
      return marker
    })
}

function getLatLng ({ region, coords }) {
  /*
   * Y is altitude
   */
  const tile = _(region.tiles)
    .filter(tile => {
      return withinBox({
        point: {
          x: coords.PosX,
          y: coords.PosY,
          z: coords.PosZ
        },
        box: {
          minX: tile.LowerX,
          maxX: tile.UpperX,
          minY: tile.LowerY,
          maxY: tile.UpperY,
          minZ: tile.LowerZ,
          maxZ: tile.UpperZ
        }
      })
    })
    .orderBy('Priority')
    .head()

  if (!tile) {
    return Promise.reject(new Error(`MapTile not found for Coords[${coords.Name}] in Region[${region.gameId}]`))
  }

  const widthBigger = tile.Width > tile.Height

  const pixel = L.point(coords.PosX, coords.PosZ)
    .add(
      // Relative to the map it's on
      L.point(-tile.LowerX, -tile.LowerZ)
    )
    .multiplyBy(2) // Game coords are scaled down for some reason.
    .add(
      // Adjust to squared tiles
      widthBigger
        ? L.point(0, (tile.Width - tile.Height) / 2) // Move down
        : L.point((tile.Height - tile.Width) / 2, 0) // Move right
    )

  const zoom = L.CRS.EPSG3857.zoom(widthBigger ? tile.Width : tile.Height)
  return Promise.resolve({
    coords,
    tile,
    latLng: L.CRS.EPSG3857.pointToLatLng(pixel, zoom)
  })
}

function createMarker ({ coords, tile, latLng }) {
  return {
    name: `${coords.Name} (Map Feature)`,
    game_id: coords.Name,
    map: tile.mapping.map_name,
    target: '',
    geometry: JSON.stringify({
      type: 'Point',
      'coordinates': [
        latLng.lng,
        latLng.lat
      ]
    }),
    shape: 'image',
    notes: ''
  }
}

function toMarkers ({ region, markers, Target }) {
  return Promise
    .all(
      markers
        .filter(coords => !!coords.Name)
        .map(coords => (
          getLatLng({ region, coords })
            .then(({ coords, latLng, tile }) => createMarker({ coords, latLng, tile }))
            .then(marker => assignTarget({ Target, marker }))
            .catch(e => {
              log.warn(e)
              return null
            })
        ))
    )
    .then(markers => markers.filter(marker => !!marker))
}

function toRegion ({ absoluteFilePath, mapInfo }) {
  const gameId = path.basename(absoluteFilePath, '.csv')
  const mapping = _.find(mapMappings, mapping => mapping.game_id === gameId)
  return {
    absoluteFilePath,
    gameId,
    mapping,
    tiles: toTiles({ absoluteFilePath, mapInfo })
  }
}

const getAllRawMarkerTables = _.memoize(() => {
  return readFile(path.resolve(__dirname, '../data/all.csv'))
    .then(content => parseCSV(content, { columns: true, auto_parse: true }))
    .then(markers => _.groupBy(markers, m => `${m.Filename}_${m.GmkType}_${m.Map}`))
})

function getTableName ({ filename, type, region }) {
  return `${filename}_${type}_${region.gameId}`
}

function getMarkersForRegion ({ region, filename, type, Target }) {
  return getAllRawMarkerTables()
    .then(markerTables => markerTables[getTableName({ filename, type, region })] || [])
    .then(markers => toMarkers({ Target, region, markers }))
}

function parseMapFeatures ({ absoluteFilePath, mapInfo }) {
  return Promise.resolve(mapInfo)
    .then(mapInfo => toRegion({ absoluteFilePath, mapInfo }))
    .then(region => (
      Promise.all([
        getMarkersForRegion({ region, filename: 'collection', type: 'GmkCollection', Target: CollectionPoints }),
        getMarkersForRegion({ region, filename: 'landmark', type: 'GmkLandmark', Target: Locations })
      ])
    ))
    .then(featuresPerType => _.flatten(featuresPerType))
}

function toTSV ({ objects }) {
  return _(objects)
    .map(row => _(row)
      .map(v => typeof v === 'object' ? JSON.stringify(v) : `${v}`)
      .map(v => v.replace(/"/g, '""'))
      .map(v => `"${v}"`)
      .join('\t')
    )
    .join('\n')
}

function writeOut ({ filename, content }) {
  const outputPath = path.resolve(__dirname, '../out')
  mkdirp.sync(outputPath)

  const filePath = path.resolve(outputPath, filename)
  log.info('Writing', filePath)
  fs.writeFileSync(filePath, content)
}

CollectionPoints.getAll()
  .then(result => toTSV({ objects: result }))
  .then(result => writeOut({ filename: 'CollectionPoints.tsv', content: result }))

Collectibles.getAll()
  .then(result => toTSV({ objects: result }))
  .then(result => writeOut({ filename: 'Collectibles.tsv', content: result }))

FieldSkills.getAll()
  .then(result => toTSV({ objects: result }))
  .then(result => writeOut({ filename: 'FieldSkills.tsv', content: result }))

Locations.getAll()
  .then(result => toTSV({ objects: result }))
  .then(result => writeOut({ filename: 'Locations.tsv', content: result }))

const mapInfos = readObjects(
  path.resolve(__dirname, '../data/mapinfo'),
  ({ absoluteFilePath, content: contentPromise }) => {
    return contentPromise
      .then(mapInfo => parseMapFeatures({ absoluteFilePath, mapInfo }))
      .catch(error => {
        log.warn({ absoluteFilePath, error }, `failed to parse region`)
        return null
      })
  },
  {
    '.csv': content => parseCSV(content, { columns: true, objname: 'Name', auto_parse: true })
  }
)

Promise
  .all(mapInfos)
  .then(results => results.filter(result => !!result))
  .then(results => _.flatten(results))
  .then(result => toTSV({ objects: result }))
  .then(result => writeOut({ filename: 'MapFeatures.tsv', content: result }))
<|endoftext|>


<commit_before>var _ = require('lodash');
var assign = require('object-assign');
var async = require('async');
var FieldType = require('../Type');
var keystone = require('../../../');
var util = require('util');
var utils = require('keystone-utils');

function getEmptyValue () {
	return {
		public_id: '',
		version: 0,
		signature: '',
		format: '',
		resource_type: '',
		url: '',
		width: 0,
		height: 0,
		secure_url: '',
	};
}

function truthy (value) {
	return value;
}

/**
 * CloudinaryImages FieldType Constructor
 */
function cloudinaryimages (list, path, options) {
	this._underscoreMethods = ['format'];
	this._fixedSize = 'full';
	this._properties = ['select', 'selectPrefix', 'autoCleanup', 'publicID', 'folder', 'filenameAsPublicID'];

	// TODO: implement filtering, usage disabled for now
	options.nofilter = true;

	cloudinaryimages.super_.call(this, list, path, options);

	// validate cloudinary config
	if (!keystone.get('cloudinary config')) {
		throw new Error('Invalid Configuration\n\n'
			+ 'CloudinaryImages fields (' + list.key + '.' + this.path + ') require the "cloudinary config" option to be set.\n\n'
			+ 'See http://keystonejs.com/docs/configuration/#services-cloudinary for more information.\n');
	}
}
cloudinaryimages.properName = 'CloudinaryImages';
util.inherits(cloudinaryimages, FieldType);

/**
 * Gets the folder for images in this field
 */
cloudinaryimages.prototype.getFolder = function () {
	var folder = null;

	if (keystone.get('cloudinary folders') || this.options.folder) {
		if (typeof this.options.folder === 'string') {
			folder = this.options.folder;
		} else {
			var folderList = keystone.get('cloudinary prefix') ? [keystone.get('cloudinary prefix')] : [];
			folderList.push(this.list.path);
			folderList.push(this.path);
			folder = folderList.join('/');
		}
	}

	return folder;
};

/**
 * Registers the field on the List's Mongoose Schema.
 */
cloudinaryimages.prototype.addToSchema = function (schema) {

	var cloudinary = require('cloudinary');
	var mongoose = keystone.mongoose;
	var field = this;

	this.paths = {
		// virtuals
		folder: this._path.append('.folder'),
		// form paths
		upload: this._path.append('_upload'),
		uploads: this._path.append('_uploads'),
		action: this._path.append('_action'),
		order: this._path.append('_order'),
	};

	var ImageSchema = new mongoose.Schema({
		public_id: String,
		version: Number,
		signature: String,
		format: String,
		resource_type: String,
		url: String,
		width: Number,
		height: Number,
		secure_url: String,
	});

	// Generate cloudinary folder used to upload/select images
	var folder = function (item) { // eslint-disable-line no-unused-vars
		var folderValue = '';

		if (keystone.get('cloudinary folders')) {
			if (field.options.folder) {
				folderValue = field.options.folder;
			} else {
				var folderList = keystone.get('cloudinary prefix') ? [keystone.get('cloudinary prefix')] : [];
				folderList.push(field.list.path);
				folderList.push(field.path);
				folderValue = folderList.join('/');
			}
		}

		return folderValue;
	};

	// The .folder virtual returns the cloudinary folder used to upload/select images
	schema.virtual(field.paths.folder).get(function () {
		return folder(this);
	});

	var src = function (img, options) {
		if (keystone.get('cloudinary secure')) {
			options = options || {};
			options.secure = true;
		}
		options.format = options.format || img.format;
		return img.public_id ? cloudinary.url(img.public_id, options) : '';
	};

	var addSize = function (options, width, height, other) {
		if (width) options.width = width;
		if (height) options.height = height;
		if (typeof other === 'object') {
			assign(options, other);
		}
		return options;
	};
	ImageSchema.method('src', function (options) {
		return src(this, options);
	});
	ImageSchema.method('scale', function (width, height, options) {
		return src(this, addSize({ crop: 'scale' }, width, height, options));
	});
	ImageSchema.method('fill', function (width, height, options) {
		return src(this, addSize({ crop: 'fill', gravity: 'faces' }, width, height, options));
	});
	ImageSchema.method('lfill', function (width, height, options) {
		return src(this, addSize({ crop: 'lfill', gravity: 'faces' }, width, height, options));
	});
	ImageSchema.method('fit', function (width, height, options) {
		return src(this, addSize({ crop: 'fit' }, width, height, options));
	});
	ImageSchema.method('limit', function (width, height, options) {
		return src(this, addSize({ crop: 'limit' }, width, height, options));
	});
	ImageSchema.method('pad', function (width, height, options) {
		return src(this, addSize({ crop: 'pad' }, width, height, options));
	});
	ImageSchema.method('lpad', function (width, height, options) {
		return src(this, addSize({ crop: 'lpad' }, width, height, options));
	});
	ImageSchema.method('crop', function (width, height, options) {
		return src(this, addSize({ crop: 'crop', gravity: 'faces' }, width, height, options));
	});
	ImageSchema.method('thumbnail', function (width, height, options) {
		return src(this, addSize({ crop: 'thumb', gravity: 'faces' }, width, height, options));
	});

	schema.add(this._path.addTo({}, [ImageSchema]));

	this.removeImage = function (item, id, method, callback) {
		var images = item.get(field.path);
		if (typeof id !== 'number') {
			for (var i = 0; i < images.length; i++) {
				if (images[i].public_id === id) {
					id = i;
					break;
				}
			}
		}
		var img = images[id];
		if (!img) return;
		if (method === 'delete') {
			cloudinary.uploader.destroy(img.public_id, function () {});
		}
		images.splice(id, 1);
		if (callback) {
			item.save((typeof callback !== 'function') ? callback : undefined);
		}
	};
	this.underscoreMethod('remove', function (id, callback) {
		field.removeImage(this, id, 'remove', callback);
	});
	this.underscoreMethod('delete', function (id, callback) {
		field.removeImage(this, id, 'delete', callback);
	});
	this.bindUnderscoreMethods();
};

/**
 * Formats the field value
 */
cloudinaryimages.prototype.format = function (item) {
	return _.map(item.get(this.path), function (img) {
		return img.src();
	}).join(', ');
};

/**
 * Validates that a value for this field has been provided in a data object
 *
 * Deprecated
 */
cloudinaryimages.prototype.inputIsValid = function (data) { // eslint-disable-line no-unused-vars
	// TODO - how should image field input be validated?
	return true;
};

/**
 * Updates the value for this field in the item from a data object
 */
cloudinaryimages.prototype.updateItem = function (item, data, callback) {

	var cloudinary = require('cloudinary');
	var field = this;
	var values = this.getValueFromData(data);

	// Early exit path: reset value when falsy, or bail if no value was provided
	if (!values) {
		if (values !== undefined) {
			item.set(field.path, []);
		}
		return process.nextTick(callback);
	}

	// When the value exists, but isn't an array, turn it into one (this just
	// means a single field was submitted in the formdata)
	if (!Array.isArray(values)) {
		values = [values];
	}

	// Precalc these options, it's inefficient when not uploading images but
	// avoids recalculating them on each iteration in the map below
	// TODO: is this worth optimising?
	var tagPrefix = keystone.get('cloudinary prefix') || '';
	var uploadOptions = {
		tags: [],
	};
	if (tagPrefix.length) {
		uploadOptions.tags.push(tagPrefix);
		tagPrefix += '_';
	}
	uploadOptions.tags.push(tagPrefix + field.list.path + '_' + field.path);
	if (keystone.get('env') !== 'production') {
		uploadOptions.tags.push(tagPrefix + 'dev');
	}
	var folder = this.getFolder();
	if (folder) {
		uploadOptions.folder = folder;
	}

	async.map(values, function (value, next) {
		// TODO: Do we actually want to support JSON encoded data here? Seems messy

		// When the value is a string, it may be JSON serialised data. If so, parse
		// it. Otherwiser, we assume it's base64 data or a remote URL and upload it
		// to cloudinary as a file path. More logic could be added here to
		// detect/prevent invalid uploads (as per cloudinaryimage field)
		if (typeof value === 'string') {
			if (value.charAt(0) === '{' && value.charAt(value.length - 1) === '}') {
				try {
					value = JSON.parse(value);
				} catch (e) {
					// value isn't JSON
				}
			} else {
				value = { path: value };
			}
		}
		if (typeof value === 'object' && value.uploadFromKey) {
			value = data[value.uploadFromKey];
		}
		if (typeof value === 'object' && 'public_id' in value) {
			// Cloudinary Image data provided
			if (value.public_id) {
				var v = assign(getEmptyValue(), value);
				return next(null, v);
			} else {
				return next(null);
			}
		} else if (typeof value === 'object' && value.path) {
			// File provided - upload it
			// NOTE: field.options.publicID has been deprecated (tbc)
			if (field.options.filenameAsPublicID && value.originalname && typeof value.originalname === 'string') {
				uploadOptions = assign({}, uploadOptions, {
					public_id: value.originalname.substring(0, value.originalname.lastIndexOf('.')),
				});
			}
			// TODO: implement autoCleanup; should delete existing images before uploading
			cloudinary.uploader.upload(value.path, function (result) {
				if (result.error) {
					next(result.error);
				} else {
					next(null, result);
				}
			}, uploadOptions);
		} else {
			// Nothing to do
			return next();
		}
	}, function (err, result) {
		if (err) return callback(err);
		result = result.filter(truthy);
		item.set(field.path, result);
		return callback();
	});
};

/**
 * Returns a callback that handles a standard form submission for the field
 *
 * Expected form parts are
 * - `field.paths.action` in `req.body` in syntax `delete:public_id,public_id|remove:public_id,public_id`
 * - `field.paths.upload` in `req.files` (uploads the images to cloudinary)
 */
cloudinaryimages.prototype.getRequestHandler = function (item, req, paths, callback) {

	var cloudinary = require('cloudinary');
	var field = this;

	if (utils.isFunction(paths)) {
		callback = paths;
		paths = field.paths;
	} else if (!paths) {
		paths = field.paths;
	}

	callback = callback || function () {};

	return function () {

		// Order
		if (req.body[paths.order]) {
			var images = item.get(field.path);
			var newOrder = req.body[paths.order].split(',');

			images.sort(function (a, b) {
				return (newOrder.indexOf(a.public_id) > newOrder.indexOf(b.public_id)) ? 1 : -1;
			});
		}

		// Removals & Deletes
		if (req.body && req.body[paths.action]) {
			var actions = req.body[paths.action].split('|');

			actions.forEach(function (action) {
				action = action.split(':');
				var method = action[0];
				var ids = action[1];

				if (!method.match(/^(remove|delete)$/) || !ids) return;

				ids.split(',').forEach(function (id) {
					field.removeImage(item, id, method);
				});
			});
		}

		// Upload References (direct uploading)
		if (req.body[paths.uploads]) {
			var uploads = JSON.parse(req.body[paths.uploads]);

			uploads.forEach(function (file) {
				item.get(field.path).push(file);
			});
		}

		// Upload Data (form submissions)
		if (req.files && req.files[paths.upload]) {
			var files = [].concat(req.files[paths.upload]);

			var tp = keystone.get('cloudinary prefix') || '';

			if (tp.length) {
				tp += '_';
			}

			var uploadOptions = {
				tags: [tp + field.list.path + '_' + field.path, tp + field.list.path + '_' + field.path + '_' + item.id],
			};

			if (keystone.get('cloudinary folders')) {
				uploadOptions.folder = item.get(paths.folder);
			}

			if (keystone.get('cloudinary prefix')) {
				uploadOptions.tags.push(keystone.get('cloudinary prefix'));
			}

			if (keystone.get('env') !== 'production') {
				uploadOptions.tags.push(tp + 'dev');
			}

			async.each(files, function (file, next) {

				if (!file.size) return next();

				if (field.options.filenameAsPublicID) {
					uploadOptions.public_id = file.originalname.substring(0, file.originalname.lastIndexOf('.'));
				}

				cloudinary.uploader.upload(file.path, function (result) {
					if (result.error) {
						return next(result.error);
					} else {
						item.get(field.path).push(result);
						return next();
					}
				}, uploadOptions);

			}, function (err) {
				return callback(err);
			});
		} else {
			return callback();
		}
	};
};

/**
 * Immediately handles a standard form submission for the field (see `getRequestHandler()`)
 */
cloudinaryimages.prototype.handleRequest = function (item, req, paths, callback) {
	this.getRequestHandler(item, req, paths, callback)();
};

/*!
 * Export class
 */
module.exports = cloudinaryimages;
<commit_msg>Improving Cloudinary Images options calculation for uploads<commit_after>var _ = require('lodash');
var assign = require('object-assign');
var async = require('async');
var FieldType = require('../Type');
var keystone = require('../../../');
var util = require('util');
var utils = require('keystone-utils');

function getEmptyValue () {
	return {
		public_id: '',
		version: 0,
		signature: '',
		format: '',
		resource_type: '',
		url: '',
		width: 0,
		height: 0,
		secure_url: '',
	};
}

function truthy (value) {
	return value;
}

/**
 * CloudinaryImages FieldType Constructor
 */
function cloudinaryimages (list, path, options) {
	this._underscoreMethods = ['format'];
	this._fixedSize = 'full';
	this._properties = ['select', 'selectPrefix', 'autoCleanup', 'publicID', 'folder', 'filenameAsPublicID'];

	// TODO: implement filtering, usage disabled for now
	options.nofilter = true;

	cloudinaryimages.super_.call(this, list, path, options);

	// validate cloudinary config
	if (!keystone.get('cloudinary config')) {
		throw new Error('Invalid Configuration\n\n'
			+ 'CloudinaryImages fields (' + list.key + '.' + this.path + ') require the "cloudinary config" option to be set.\n\n'
			+ 'See http://keystonejs.com/docs/configuration/#services-cloudinary for more information.\n');
	}
}
cloudinaryimages.properName = 'CloudinaryImages';
util.inherits(cloudinaryimages, FieldType);

/**
 * Gets the folder for images in this field
 */
cloudinaryimages.prototype.getFolder = function () {
	var folder = null;

	if (keystone.get('cloudinary folders') || this.options.folder) {
		if (typeof this.options.folder === 'string') {
			folder = this.options.folder;
		} else {
			var folderList = keystone.get('cloudinary prefix') ? [keystone.get('cloudinary prefix')] : [];
			folderList.push(this.list.path);
			folderList.push(this.path);
			folder = folderList.join('/');
		}
	}

	return folder;
};

/**
 * Registers the field on the List's Mongoose Schema.
 */
cloudinaryimages.prototype.addToSchema = function (schema) {

	var cloudinary = require('cloudinary');
	var mongoose = keystone.mongoose;
	var field = this;

	this.paths = {
		// virtuals
		folder: this._path.append('.folder'),
		// form paths
		upload: this._path.append('_upload'),
		uploads: this._path.append('_uploads'),
		action: this._path.append('_action'),
		order: this._path.append('_order'),
	};

	var ImageSchema = new mongoose.Schema({
		public_id: String,
		version: Number,
		signature: String,
		format: String,
		resource_type: String,
		url: String,
		width: Number,
		height: Number,
		secure_url: String,
	});

	// Generate cloudinary folder used to upload/select images
	var folder = function (item) { // eslint-disable-line no-unused-vars
		var folderValue = '';

		if (keystone.get('cloudinary folders')) {
			if (field.options.folder) {
				folderValue = field.options.folder;
			} else {
				var folderList = keystone.get('cloudinary prefix') ? [keystone.get('cloudinary prefix')] : [];
				folderList.push(field.list.path);
				folderList.push(field.path);
				folderValue = folderList.join('/');
			}
		}

		return folderValue;
	};

	// The .folder virtual returns the cloudinary folder used to upload/select images
	schema.virtual(field.paths.folder).get(function () {
		return folder(this);
	});

	var src = function (img, options) {
		if (keystone.get('cloudinary secure')) {
			options = options || {};
			options.secure = true;
		}
		options.format = options.format || img.format;
		return img.public_id ? cloudinary.url(img.public_id, options) : '';
	};

	var addSize = function (options, width, height, other) {
		if (width) options.width = width;
		if (height) options.height = height;
		if (typeof other === 'object') {
			assign(options, other);
		}
		return options;
	};
	ImageSchema.method('src', function (options) {
		return src(this, options);
	});
	ImageSchema.method('scale', function (width, height, options) {
		return src(this, addSize({ crop: 'scale' }, width, height, options));
	});
	ImageSchema.method('fill', function (width, height, options) {
		return src(this, addSize({ crop: 'fill', gravity: 'faces' }, width, height, options));
	});
	ImageSchema.method('lfill', function (width, height, options) {
		return src(this, addSize({ crop: 'lfill', gravity: 'faces' }, width, height, options));
	});
	ImageSchema.method('fit', function (width, height, options) {
		return src(this, addSize({ crop: 'fit' }, width, height, options));
	});
	ImageSchema.method('limit', function (width, height, options) {
		return src(this, addSize({ crop: 'limit' }, width, height, options));
	});
	ImageSchema.method('pad', function (width, height, options) {
		return src(this, addSize({ crop: 'pad' }, width, height, options));
	});
	ImageSchema.method('lpad', function (width, height, options) {
		return src(this, addSize({ crop: 'lpad' }, width, height, options));
	});
	ImageSchema.method('crop', function (width, height, options) {
		return src(this, addSize({ crop: 'crop', gravity: 'faces' }, width, height, options));
	});
	ImageSchema.method('thumbnail', function (width, height, options) {
		return src(this, addSize({ crop: 'thumb', gravity: 'faces' }, width, height, options));
	});

	schema.add(this._path.addTo({}, [ImageSchema]));

	this.removeImage = function (item, id, method, callback) {
		var images = item.get(field.path);
		if (typeof id !== 'number') {
			for (var i = 0; i < images.length; i++) {
				if (images[i].public_id === id) {
					id = i;
					break;
				}
			}
		}
		var img = images[id];
		if (!img) return;
		if (method === 'delete') {
			cloudinary.uploader.destroy(img.public_id, function () {});
		}
		images.splice(id, 1);
		if (callback) {
			item.save((typeof callback !== 'function') ? callback : undefined);
		}
	};
	this.underscoreMethod('remove', function (id, callback) {
		field.removeImage(this, id, 'remove', callback);
	});
	this.underscoreMethod('delete', function (id, callback) {
		field.removeImage(this, id, 'delete', callback);
	});
	this.bindUnderscoreMethods();
};

/**
 * Formats the field value
 */
cloudinaryimages.prototype.format = function (item) {
	return _.map(item.get(this.path), function (img) {
		return img.src();
	}).join(', ');
};

/**
 * Validates that a value for this field has been provided in a data object
 *
 * Deprecated
 */
cloudinaryimages.prototype.inputIsValid = function (data) { // eslint-disable-line no-unused-vars
	// TODO - how should image field input be validated?
	return true;
};

/**
 * Updates the value for this field in the item from a data object
 */
cloudinaryimages.prototype.updateItem = function (item, data, callback) {

	var cloudinary = require('cloudinary');
	var field = this;
	var values = this.getValueFromData(data);

	// Early exit path: reset value when falsy, or bail if no value was provided
	if (!values) {
		if (values !== undefined) {
			item.set(field.path, []);
		}
		return process.nextTick(callback);
	}

	// When the value exists, but isn't an array, turn it into one (this just
	// means a single field was submitted in the formdata)
	if (!Array.isArray(values)) {
		values = [values];
	}

	// We cache options to avoid recalculating them on each iteration in the map below
	var cachedUploadOptions;
	function getUploadOptions () {
		if (cachedUploadOptions) {
			return cachedUploadOptions;
		}
		var tagPrefix = keystone.get('cloudinary prefix') || '';
		var uploadOptions = {
			tags: [],
		};
		if (tagPrefix.length) {
			uploadOptions.tags.push(tagPrefix);
			tagPrefix += '_';
		}
		uploadOptions.tags.push(tagPrefix + field.list.path + '_' + field.path);
		if (keystone.get('env') !== 'production') {
			uploadOptions.tags.push(tagPrefix + 'dev');
		}
		var folder = this.getFolder();
		if (folder) {
			uploadOptions.folder = folder;
		}
		cachedUploadOptions = uploadOptions;
		return uploadOptions;
	}

	async.map(values, function (value, next) {
		// TODO: Do we actually want to support JSON encoded data here? Seems messy

		// When the value is a string, it may be JSON serialised data. If so, parse
		// it. Otherwiser, we assume it's base64 data or a remote URL and upload it
		// to cloudinary as a file path. More logic could be added here to
		// detect/prevent invalid uploads (as per cloudinaryimage field)
		if (typeof value === 'string') {
			if (value.charAt(0) === '{' && value.charAt(value.length - 1) === '}') {
				try {
					value = JSON.parse(value);
				} catch (e) {
					// value isn't JSON
				}
			} else {
				value = { path: value };
			}
		}
		if (typeof value === 'object' && value.uploadFromKey) {
			value = data[value.uploadFromKey];
		}
		if (typeof value === 'object' && 'public_id' in value) {
			// Cloudinary Image data provided
			if (value.public_id) {
				var v = assign(getEmptyValue(), value);
				return next(null, v);
			} else {
				return next(null);
			}
		} else if (typeof value === 'object' && value.path) {
			// File provided - upload it
			var uploadOptions = getUploadOptions();
			// NOTE: field.options.publicID has been deprecated (tbc)
			if (field.options.filenameAsPublicID && value.originalname && typeof value.originalname === 'string') {
				uploadOptions = assign({}, uploadOptions, {
					public_id: value.originalname.substring(0, value.originalname.lastIndexOf('.')),
				});
			}
			// TODO: implement autoCleanup; should delete existing images before uploading
			cloudinary.uploader.upload(value.path, function (result) {
				if (result.error) {
					next(result.error);
				} else {
					next(null, result);
				}
			}, uploadOptions);
		} else {
			// Nothing to do
			return next();
		}
	}, function (err, result) {
		if (err) return callback(err);
		result = result.filter(truthy);
		item.set(field.path, result);
		return callback();
	});
};

/**
 * Returns a callback that handles a standard form submission for the field
 *
 * Expected form parts are
 * - `field.paths.action` in `req.body` in syntax `delete:public_id,public_id|remove:public_id,public_id`
 * - `field.paths.upload` in `req.files` (uploads the images to cloudinary)
 */
cloudinaryimages.prototype.getRequestHandler = function (item, req, paths, callback) {

	var cloudinary = require('cloudinary');
	var field = this;

	if (utils.isFunction(paths)) {
		callback = paths;
		paths = field.paths;
	} else if (!paths) {
		paths = field.paths;
	}

	callback = callback || function () {};

	return function () {

		// Order
		if (req.body[paths.order]) {
			var images = item.get(field.path);
			var newOrder = req.body[paths.order].split(',');

			images.sort(function (a, b) {
				return (newOrder.indexOf(a.public_id) > newOrder.indexOf(b.public_id)) ? 1 : -1;
			});
		}

		// Removals & Deletes
		if (req.body && req.body[paths.action]) {
			var actions = req.body[paths.action].split('|');

			actions.forEach(function (action) {
				action = action.split(':');
				var method = action[0];
				var ids = action[1];

				if (!method.match(/^(remove|delete)$/) || !ids) return;

				ids.split(',').forEach(function (id) {
					field.removeImage(item, id, method);
				});
			});
		}

		// Upload References (direct uploading)
		if (req.body[paths.uploads]) {
			var uploads = JSON.parse(req.body[paths.uploads]);

			uploads.forEach(function (file) {
				item.get(field.path).push(file);
			});
		}

		// Upload Data (form submissions)
		if (req.files && req.files[paths.upload]) {
			var files = [].concat(req.files[paths.upload]);

			var tp = keystone.get('cloudinary prefix') || '';

			if (tp.length) {
				tp += '_';
			}

			var uploadOptions = {
				tags: [tp + field.list.path + '_' + field.path, tp + field.list.path + '_' + field.path + '_' + item.id],
			};

			if (keystone.get('cloudinary folders')) {
				uploadOptions.folder = item.get(paths.folder);
			}

			if (keystone.get('cloudinary prefix')) {
				uploadOptions.tags.push(keystone.get('cloudinary prefix'));
			}

			if (keystone.get('env') !== 'production') {
				uploadOptions.tags.push(tp + 'dev');
			}

			async.each(files, function (file, next) {

				if (!file.size) return next();

				if (field.options.filenameAsPublicID) {
					uploadOptions.public_id = file.originalname.substring(0, file.originalname.lastIndexOf('.'));
				}

				cloudinary.uploader.upload(file.path, function (result) {
					if (result.error) {
						return next(result.error);
					} else {
						item.get(field.path).push(result);
						return next();
					}
				}, uploadOptions);

			}, function (err) {
				return callback(err);
			});
		} else {
			return callback();
		}
	};
};

/**
 * Immediately handles a standard form submission for the field (see `getRequestHandler()`)
 */
cloudinaryimages.prototype.handleRequest = function (item, req, paths, callback) {
	this.getRequestHandler(item, req, paths, callback)();
};

/*!
 * Export class
 */
module.exports = cloudinaryimages;
<|endoftext|>


<commit_before>requirejs.config({
  baseUrl: '../bower_components',
  paths: {
    config: '../_fe/js/config',
    getUserMedia: 'getUserMedia/getusermedia.bundle',
    gifJS: 'gif-js/dist/gif',
    imagesloaded: 'imagesloaded/imagesloaded',
    jade: 'jade/runtime',
    jquery: 'jquery/jquery',
    js: '../_fe/js',
    json: '../_fe/json',
    komponent: 'komponent/komponent',
    lodash: 'lodash/lodash',
    main: '../_fe/js/main',
    templates: '../_fe/compiled/jade-templates',
    text: 'text/text',
    uuid: 'node-uuid/uuid'
  },
  shim: {
    'gifJS': {
      exports: 'GIF'
    }
  }
});

require([
  'js/device',
  'jquery',
  'js/tiles',
  'js/database',
  'js/localstrings',
  'js/render'
], function (device, $, tiles, db, localStrings, render) {
  var servicesToLoad = 2;
  var servicesLoaded = 0;

  function initUI() {
    if (servicesLoaded === servicesToLoad) {
      var $body = $('body');
      var $tileContainer = $(render('tile-container'));

      $body.append(render('header', {
        avatarSrc: db.get('avatarSrc'),
        name: db.get('realName'),
        username: db.get('username')
      }));

      $body.append($tileContainer);

      tiles.init($tileContainer);
      tiles.render(db.get('makes'));
    }
  }

  // Set up device characteristics and feature detection
  device.init();

  // Initialize UI after localization strings load
  localStrings.on('load', function () {
    servicesLoaded++;
    initUI();
  });

  // TODO - Sniff locale instead of hard coding
  localStrings.init('en-us');

  // Initialize database
  db.on('load', function () {
    servicesLoaded++;
    initUI();
  });

  // Grab username from QueryString, if it exists
  var username = 'reanimator';
  var qs = window.location.search;
  if (qs) {
    qs = qs.replace('?', ''); // get rid of '?'
    var qsArray = qs.split('&');
    for (var i = 0, l = qsArray.length; i < l; i++) {
      var v = qsArray[i].split('=');
      if (v[0] === 'u') {
        username = v[1];
      }
    }
  }

  db.init(username);
});
<commit_msg>changing u to user<commit_after>requirejs.config({
  baseUrl: '../bower_components',
  paths: {
    config: '../_fe/js/config',
    getUserMedia: 'getUserMedia/getusermedia.bundle',
    gifJS: 'gif-js/dist/gif',
    imagesloaded: 'imagesloaded/imagesloaded',
    jade: 'jade/runtime',
    jquery: 'jquery/jquery',
    js: '../_fe/js',
    json: '../_fe/json',
    komponent: 'komponent/komponent',
    lodash: 'lodash/lodash',
    main: '../_fe/js/main',
    templates: '../_fe/compiled/jade-templates',
    text: 'text/text',
    uuid: 'node-uuid/uuid'
  },
  shim: {
    'gifJS': {
      exports: 'GIF'
    }
  }
});

require([
  'js/device',
  'jquery',
  'js/tiles',
  'js/database',
  'js/localstrings',
  'js/render'
], function (device, $, tiles, db, localStrings, render) {
  var servicesToLoad = 2;
  var servicesLoaded = 0;

  function initUI() {
    if (servicesLoaded === servicesToLoad) {
      var $body = $('body');
      var $tileContainer = $(render('tile-container'));

      $body.append(render('header', {
        avatarSrc: db.get('avatarSrc'),
        name: db.get('realName'),
        username: db.get('username')
      }));

      $body.append($tileContainer);

      tiles.init($tileContainer);
      tiles.render(db.get('makes'));
    }
  }

  // Set up device characteristics and feature detection
  device.init();

  // Initialize UI after localization strings load
  localStrings.on('load', function () {
    servicesLoaded++;
    initUI();
  });

  // TODO - Sniff locale instead of hard coding
  localStrings.init('en-us');

  // Initialize database
  db.on('load', function () {
    servicesLoaded++;
    initUI();
  });

  // Grab username from QueryString, if it exists
  var username = 'reanimator';
  var qs = window.location.search;
  if (qs) {
    qs = qs.replace('?', ''); // get rid of '?'
    var qsArray = qs.split('&');
    for (var i = 0, l = qsArray.length; i < l; i++) {
      var v = qsArray[i].split('=');
      if (v[0] === 'user') {
        username = v[1];
      }
    }
  }

  db.init(username);
});
<|endoftext|>


<commit_before>import React from 'react'
import i18n from 'app/utils/i18n'
import cache from 'app/utils/cache'
import {map_get} from 'app/utils'

class DL extends React.Component{
  constructor(props){
    super(props)

    this.state = {
      open: this.props.open
    }
  }
  render(){
    const {open} = this.state
    const {label, value} = this.props
    const simple = !(value instanceof Object)

    if (simple)
      return (

 this.setState({open: true})}>
          {label}:
          {value}

      )

    if (!open)
      return (

 this.setState({open: true})}>

          {label}

      )

    return (

         this.setState({open: false})}>

          {label}

          {Object.keys(value).sort().map( k => (

          ))}

    )
  }
}

function process_actions(actions){
  if (actions.type){
    if (actions.type=="condition"){
      return {...process_actions(actions.then), ...process_actions(actions.else)}
    } else if (actions.type=="action"){
      return {
        [actions.id] : actions.params
      }
    }
  }
  else{
    let ret = {}
    actions.map( ac => {
      ret = {...ret, ...process_actions(ac)}
    })
    return ret
  }
}

class RulesHelp extends React.Component{
  constructor(props){
    super(props)

    this.state = {
      extra_help: {}
    }
  }
  componentDidMount(){
    const id = this.props.rule.rule.when.id
    if (id){
      cache.trigger(this.props.rule.rule.when.trigger).then( trigger => {
        // console.log("Got data from rule ", trigger)
        if (trigger && trigger.result){
          const extra_help = this.state.extra_help
          this.setState({extra_help: {...extra_help, [id]: trigger.result }})
        }
        // console.log("Trigger ", trigger.result || {})
      })
    }

    // Get the other actions params
    this.cacheGetActions(this.props.rule.rule.actions)
  }
  cacheGetActions(actions){
    console.log(actions)
    for (let ac of actions){
      console.log(ac)
      if (ac.type=="action"){
        this.cacheGetAction(ac)
      } else if (ac.type=="condition") {
        this.cacheGetActions(ac.then)
        this.cacheGetActions(ac.else)
      }
    }
  }
  cacheGetAction(action){
    if (!action.id)
      return
    cache.action(action.action).then( ac => {
      if (map_get(ac, ["extra","call","result"])){
        const extra_help=this.state.extra_help
        this.setState({extra_help: {...extra_help, [action.id]: ac.extra.call.result}})
      }
    })
  }
  render(){
    const {rule} = this.props

    // console.log(rule)

    const help = {
      "rule" : {
        "uuid" : i18n("Rule UUID"),
        "name" : i18n("Rule name"),
        "description" : i18n("Rule description")
      },
      ...this.state.extra_help,
      "changes" : this.state.extra_help,
      "prev" : this.state.extra_help
    }

    return (

{i18n("Conditional template help")}

          {i18n("You can use these variables to construct your exapression, for example 'A.exit == 0'")}

          {Object.keys(help).sort().map( k => (

          ))}

    )
  }
}

export default RulesHelp
<commit_msg>Show also params from original parameters<commit_after>import React from 'react'
import i18n from 'app/utils/i18n'
import cache from 'app/utils/cache'
import {map_get} from 'app/utils'

class DL extends React.Component{
  constructor(props){
    super(props)

    this.state = {
      open: this.props.open
    }
  }
  render(){
    const {open} = this.state
    const {label, value} = this.props
    const simple = !(value instanceof Object)

    if (simple)
      return (

 this.setState({open: true})}>
          {label}:
          {value}

      )

    if (!open)
      return (

 this.setState({open: true})}>

          {label}

      )

    return (

         this.setState({open: false})}>

          {label}

          {Object.keys(value).sort().map( k => (

          ))}

    )
  }
}

function process_actions(actions){
  if (actions.type){
    if (actions.type=="condition"){
      return {...process_actions(actions.then), ...process_actions(actions.else)}
    } else if (actions.type=="action"){
      return {
        [actions.id] : actions.params
      }
    }
  }
  else{
    let ret = {}
    actions.map( ac => {
      ret = {...ret, ...process_actions(ac)}
    })
    return ret
  }
}

class RulesHelp extends React.Component{
  constructor(props){
    super(props)

    this.state = {
      extra_help: {}
    }
  }
  componentDidMount(){
    const id = this.props.rule.rule.when.id
    if (id){
      cache.trigger(this.props.rule.rule.when.trigger).then( trigger => {
        console.log("Got data from rule ", trigger)
        if (trigger && trigger.result){
          const extra_help = this.state.extra_help
          let params = {}
          map_get(trigger, ["start","params"], []).map( p => {
            params[p.name]=p.label
          })
          this.setState({extra_help: {...extra_help, [id]: {...trigger.result, ...params} }})
        }
        // console.log("Trigger ", trigger.result || {})
      })
    }

    // Get the other actions params
    this.cacheGetActions(this.props.rule.rule.actions)
  }
  cacheGetActions(actions){
    console.log(actions)
    for (let ac of actions){
      console.log(ac)
      if (ac.type=="action"){
        this.cacheGetAction(ac)
      } else if (ac.type=="condition") {
        this.cacheGetActions(ac.then)
        this.cacheGetActions(ac.else)
      }
    }
  }
  cacheGetAction(action){
    if (!action.id)
      return
    cache.action(action.action).then( ac => {
      if (map_get(ac, ["extra","call","result"])){
        const extra_help=this.state.extra_help
        let params = ac.extra.call.result || {}
        map_get(ac, ["extra","call","params"], []).map( p => {
          params[p.name]=p.label
        })

        this.setState({extra_help: {...extra_help, [action.id]: params}})
      }
    })
  }
  render(){
    const {rule} = this.props

    // console.log(rule)

    const help = {
      "rule" : {
        "uuid" : i18n("Rule UUID"),
        "name" : i18n("Rule name"),
        "description" : i18n("Rule description")
      },
      ...this.state.extra_help,
      "changes" : this.state.extra_help,
      "prev" : this.state.extra_help
    }

    return (

{i18n("Conditional template help")}

          {i18n("You can use these variables to construct your exapression, for example 'A.exit == 0'")}

          {Object.keys(help).sort().map( k => (

          ))}

    )
  }
}

export default RulesHelp
<|endoftext|>


<commit_before>dojo.provide("dojox.charting.plot2d.Candlesticks");

dojo.require("dojox.charting.plot2d.common");
dojo.require("dojox.charting.plot2d.Base");

dojo.require("dojox.lang.utils");
dojo.require("dojox.lang.functional");
dojo.require("dojox.lang.functional.reversed");

(function(){
	var df = dojox.lang.functional, du = dojox.lang.utils,
		dc = dojox.charting.plot2d.common,
		purgeGroup = df.lambda("item.purgeGroup()");

	//	Candlesticks are based on the Bars plot type; we expect the following passed
	//	as values in a series:
	//	{ x?, open, close, high, low, mid? }
	//	if x is not provided, the array index is used.
	//	failing to provide the OHLC values will throw an error.
	dojo.declare("dojox.charting.plot2d.Candlesticks", dojox.charting.plot2d.Base, {
		defaultParams: {
			hAxis: "x",		// use a horizontal axis named "x"
			vAxis: "y",		// use a vertical axis named "y"
			gap:	2,		// gap between columns in pixels
			shadows: null	// draw shadows
		},
		optionalParams: {
			minBarSize: 1,	// minimal bar size in pixels
			maxBarSize: 1	// maximal bar size in pixels
		},

		constructor: function(chart, kwArgs){
			this.opt = dojo.clone(this.defaultParams);
			du.updateWithObject(this.opt, kwArgs);
			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
			this.series = [];
			this.hAxis = this.opt.hAxis;
			this.vAxis = this.opt.vAxis;
		},

		collectStats: function(series){
			//	we have to roll our own, since we need to use all four passed
			//	values to figure out our stats, and common only assumes x and y.
			var stats = dojo.clone(dc.defaultStats);
			for(var i=0; i<series.length; i++){
				var run = series[i];
				if(!run.data.length){ continue; }
				var old_vmin = stats.vmin, old_vmax = stats.vmax;
				if(!("ymin" in run) || !("ymax" in run)){
					dojo.forEach(run.data, function(val, idx){
						var x = val.x || idx + 1;
						stats.hmin = Math.min(stats.hmin, x);
						stats.hmax = Math.max(stats.hmax, x);
						stats.vmin = Math.min(stats.vmin, val.open, val.close, val.high, val.low);
						stats.vmax = Math.max(stats.vmax, val.open, val.close, val.high, val.low);
					});
				}
				if("ymin" in run){ stats.vmin = Math.min(old_vmin, run.ymin); }
				if("ymax" in run){ stats.vmax = Math.max(old_vmax, run.ymax); }
			}
			return stats;
		},

		calculateAxes: function(dim){
			var stats = this.collectStats(this.series), t;
			stats.hmin -= 0.5;
			stats.hmax += 0.5;
			this._calc(dim, stats);
			return this;
		},

		render: function(dim, offsets){
			this.dirty = this.isDirty();
			if(this.dirty){
				dojo.forEach(this.series, purgeGroup);
				this.cleanGroup();
				var s = this.group;
				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
			}
			var t = this.chart.theme, color, stroke, fill, f, gap, width,
				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
				baseline = Math.max(0, this._vScaler.bounds.lower),
				baselineHeight = vt(baseline),
				events = this.events();
			f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt);
			gap = f.gap;
			width = f.size;
			this.resetEvents();
			for(var i = this.series.length - 1; i >= 0; --i){
				var run = this.series[i];
				if(!this.dirty && !run.dirty){ continue; }
				run.cleanGroup();
				var s = run.group;
				if(!run.fill || !run.stroke){
					// need autogenerated color
					color = run.dyn.color = new dojo.Color(t.next("color"));
				}
				stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
				fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);

				for(var j = 0; j < run.data.length; ++j){
					var v = run.data[j];

					//	calculate the points we need for OHLC
					var x = ht(v.x || (j+0.5)) + offsets.l + gap,
						y = dim.height - offsets.b,
						open = vt(v.open),
						close = vt(v.close),
						high = vt(v.high),
						low = vt(v.low);
					if(v.mid){
						var mid = vt(v.mid);
					}
					if(low > high){
						var tmp = high;
						high = low;
						low = tmp;
					}

					if(width >= 1){
						//	draw the line and rect, set up as a group and pass that to the events.
						var doFill = open > close;
						var line = { x1: width/2, x2: width/2, y1: y - high, y2: y - low },
							rect = {
								x: 0, y: y-Math.max(open, close),
								width: width, height: doFill ? open-close : close-open
							};
						shape = s.createGroup();
						shape.setTransform({dx: x, dy: 0 });
						shape.createLine(line).setStroke(stroke);
						shape.createRect(rect).setStroke(stroke).setFill(doFill?fill:"white");
						if(v.mid){
							//	add the mid line.
							shape.createLine({ x1: (stroke.width||1), x2: width-(stroke.width||1), y1: y - mid, y2: y - mid})
								.setStroke(doFill?{color:"white"}:stroke);
						}

						//	TODO: double check this.
						run.dyn.fill   = fill;
						run.dyn.stroke = stroke;
						if(events){
							var o = {
								element: "candlestick",
								index:   j,
								run:     run,
								plot:    this,
								hAxis:   this.hAxis || null,
								vAxis:   this.vAxis || null,
								shape:   shape,
								x:       v,
								y:       j + 1.5
							};
							this._connectEvents(shape, o);
						}
					}
				}
				run.dirty = false;
			}
			this.dirty = false;
			return this;
		}
	});
})();
<commit_msg>Fixed the test for the mid data point.  !strict.<commit_after>dojo.provide("dojox.charting.plot2d.Candlesticks");

dojo.require("dojox.charting.plot2d.common");
dojo.require("dojox.charting.plot2d.Base");

dojo.require("dojox.lang.utils");
dojo.require("dojox.lang.functional");
dojo.require("dojox.lang.functional.reversed");

(function(){
	var df = dojox.lang.functional, du = dojox.lang.utils,
		dc = dojox.charting.plot2d.common,
		purgeGroup = df.lambda("item.purgeGroup()");

	//	Candlesticks are based on the Bars plot type; we expect the following passed
	//	as values in a series:
	//	{ x?, open, close, high, low, mid? }
	//	if x is not provided, the array index is used.
	//	failing to provide the OHLC values will throw an error.
	dojo.declare("dojox.charting.plot2d.Candlesticks", dojox.charting.plot2d.Base, {
		defaultParams: {
			hAxis: "x",		// use a horizontal axis named "x"
			vAxis: "y",		// use a vertical axis named "y"
			gap:	2,		// gap between columns in pixels
			shadows: null	// draw shadows
		},
		optionalParams: {
			minBarSize: 1,	// minimal bar size in pixels
			maxBarSize: 1	// maximal bar size in pixels
		},

		constructor: function(chart, kwArgs){
			this.opt = dojo.clone(this.defaultParams);
			du.updateWithObject(this.opt, kwArgs);
			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
			this.series = [];
			this.hAxis = this.opt.hAxis;
			this.vAxis = this.opt.vAxis;
		},

		collectStats: function(series){
			//	we have to roll our own, since we need to use all four passed
			//	values to figure out our stats, and common only assumes x and y.
			var stats = dojo.clone(dc.defaultStats);
			for(var i=0; i<series.length; i++){
				var run = series[i];
				if(!run.data.length){ continue; }
				var old_vmin = stats.vmin, old_vmax = stats.vmax;
				if(!("ymin" in run) || !("ymax" in run)){
					dojo.forEach(run.data, function(val, idx){
						var x = val.x || idx + 1;
						stats.hmin = Math.min(stats.hmin, x);
						stats.hmax = Math.max(stats.hmax, x);
						stats.vmin = Math.min(stats.vmin, val.open, val.close, val.high, val.low);
						stats.vmax = Math.max(stats.vmax, val.open, val.close, val.high, val.low);
					});
				}
				if("ymin" in run){ stats.vmin = Math.min(old_vmin, run.ymin); }
				if("ymax" in run){ stats.vmax = Math.max(old_vmax, run.ymax); }
			}
			return stats;
		},

		calculateAxes: function(dim){
			var stats = this.collectStats(this.series), t;
			stats.hmin -= 0.5;
			stats.hmax += 0.5;
			this._calc(dim, stats);
			return this;
		},

		render: function(dim, offsets){
			this.dirty = this.isDirty();
			if(this.dirty){
				dojo.forEach(this.series, purgeGroup);
				this.cleanGroup();
				var s = this.group;
				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
			}
			var t = this.chart.theme, color, stroke, fill, f, gap, width,
				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
				baseline = Math.max(0, this._vScaler.bounds.lower),
				baselineHeight = vt(baseline),
				events = this.events();
			f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt);
			gap = f.gap;
			width = f.size;
			this.resetEvents();
			for(var i = this.series.length - 1; i >= 0; --i){
				var run = this.series[i];
				if(!this.dirty && !run.dirty){ continue; }
				run.cleanGroup();
				var s = run.group;
				if(!run.fill || !run.stroke){
					// need autogenerated color
					color = run.dyn.color = new dojo.Color(t.next("color"));
				}
				stroke = run.stroke ? run.stroke : dc.augmentStroke(t.series.stroke, color);
				fill = run.fill ? run.fill : dc.augmentFill(t.series.fill, color);

				for(var j = 0; j < run.data.length; ++j){
					var v = run.data[j];

					//	calculate the points we need for OHLC
					var x = ht(v.x || (j+0.5)) + offsets.l + gap,
						y = dim.height - offsets.b,
						open = vt(v.open),
						close = vt(v.close),
						high = vt(v.high),
						low = vt(v.low);
					if("mid" in v){
						var mid = vt(v.mid);
					}
					if(low > high){
						var tmp = high;
						high = low;
						low = tmp;
					}

					if(width >= 1){
						//	draw the line and rect, set up as a group and pass that to the events.
						var doFill = open > close;
						var line = { x1: width/2, x2: width/2, y1: y - high, y2: y - low },
							rect = {
								x: 0, y: y-Math.max(open, close),
								width: width, height: doFill ? open-close : close-open
							};
						shape = s.createGroup();
						shape.setTransform({dx: x, dy: 0 });
						shape.createLine(line).setStroke(stroke);
						shape.createRect(rect).setStroke(stroke).setFill(doFill?fill:"white");
						if("mid" in v){
							//	add the mid line.
							shape.createLine({ x1: (stroke.width||1), x2: width-(stroke.width||1), y1: y - mid, y2: y - mid})
								.setStroke(doFill?{color:"white"}:stroke);
						}

						//	TODO: double check this.
						run.dyn.fill   = fill;
						run.dyn.stroke = stroke;
						if(events){
							var o = {
								element: "candlestick",
								index:   j,
								run:     run,
								plot:    this,
								hAxis:   this.hAxis || null,
								vAxis:   this.vAxis || null,
								shape:   shape,
								x:       v,
								y:       j + 1.5
							};
							this._connectEvents(shape, o);
						}
					}
				}
				run.dirty = false;
			}
			this.dirty = false;
			return this;
		}
	});
})();
<|endoftext|>