<commit_before>nrj("soundmanager2/script/soundmanager2-nodebug-jsmin.js", 1);

(function(env) {
    "use strict"

    var SOUNDCLOUD_CLIENT_ID = 'df14a65559c0e555d9f9fd950c2d5b17',
        script = $('[src*="/js/spice/sound_cloud/"]')[0],
        source = $(script).attr("src"),
        query = source.match(/sound_cloud\/([^\/]*)/)[1],

        // Blacklist some adult results.
        skip_ids = {
            80320921: 1,
            75349402: 1
        };

    // global SM var:
    window.SM2_DEFER = true;

    /**
     * Tile Audio player
     *
     * I kept this separate from the spice and self contained so
     * we could potentially refactor it out at some point.
     *
     * If we create another spice with
     * playable audio tiles, we're probably going to want a
     * single controller to manage audio playback
     * across tabs/spices.
     */
    var player = {
        // queue up commands to run once
        // sound manager is ready:
        _onReady: [],

        // flipped to 1 on ready:
        _ready: 0,

        init: function() {
            var self = this;

            // don't init more than once:
            if (this._ready) { return; }

            // make sure the lib is loaded and in memory,
            // otherwise poll for it until it is:
            if (!window["SoundManager"]) {
                return setTimeout(this.init.bind(this),50);
            }

            window.soundManager = new SoundManager();
            soundManager.url = "/soundmanager2/swf";
            soundManager.flashVersion = 9;
            soundManager.useFlashBlock = false;
            soundManager.useHTML5Audio = true;
            //soundManager.onerror(function(){
            //    console.log("error loading soundmanager",arguments);
            //});
            soundManager.ontimeout(function(){
                console.log("timeout loading soundmanager",arguments);
            });
            soundManager.beginDelayedInit();
            soundManager.onready(function() {
                for (var i=0,evt; evt=self._onReady[i]; i++) {
                    self[evt[0]](evt[1]);
                }
                self._ready = 1;
                self._onReady = [];
            });
        },

        play: function(item) {
            if (!this._ready) {
                return this._onReady.push(['play',item]);
            }

            // if a different item is playing, stop it:
            if (this._curItem && this._curItem.id !== item.id) {
                this.stop();
            }

            if (item.sound) {
                item.sound.play();
            } else {
                item.$action = item.$html.find('.audio-controls__action');
                item.$time = item.$html.find('.audio-controls__time');
                item.$progress = item.$html.find('.audio-controls__progress');
                item.$loadProgress = item.$html.find('.audio-controls__progress-loading');
                item.$loadProgressFill = item.$html.find('.audio-controls__progress-loading .rotated-fill');
                item.$playProgress = item.$html.find('.audio-controls__progress-playback');
                item.$playProgressFill = item.$html.find('.audio-controls__progress-playback .rotated-fill');

                item.sound = soundManager.createSound({
                    id: item.id,
                    url: item.streamURL,
                    autoPlay: true,
                    whileloading: this._onLoadProgress.bind(this,item),
                    whileplaying: this._onPlayProgress.bind(this,item),
                    onload: this._onLoadFinished.bind(this,item),
                    onfinish: this._onPlayFinished.bind(this,item)
                });
            }

            item.$html.removeClass('is-paused');
            item.$action.text('║');

            // update the UI

            this._curItem = item;
        },

        pause: function(item) {
            if (!this._ready) {
                return this._onReady.push(['pause',item]);
            }

            if (this._curItem && item && this._curItem.id === item.id && item.sound) {
                item.sound.pause();
                item.$html.addClass('is-paused');
                item.$action.text('►');
            }

            // update the UI
        },

        stop: function() {
            if (!this._ready) {
                return this._onReady.push(['stop']);
            }

            soundManager.stopAll();

            if (this._curItem) {
                // update the UI
                this._curItem.$html.removeClass('is-paused');
                this._curItem.$action.text('►');

                // don't want to clear the 'Stream Unavailable text, only the -0:00 time:
                if (!this._curItem.$html.hasClass('is-unavailable')) {
                    this._curItem.$time.text('');
                }
                this._curItem.$loadProgress.removeClass('gt50');
                this._curItem.$playProgress.removeClass('gt50');
                this._updateProgress(this._curItem.$loadProgressFill,0);
                this._updateProgress(this._curItem.$playProgressFill,0);

                // free up resources:
                this._curItem.sound.destruct();
                delete this._curItem.sound
                delete this._curItem;
            }
        },

        _updateProgress: function(elem,pct) {
            var deg = (360 / 100 * pct) + 'deg';

            elem.css({
                '-moz-transform': 'rotate(' + deg + ')',
                '-webkit-transform': 'rotate(' + deg + ')',
                '-o-transform': 'rotate(' + deg + ')',
                'transform': 'rotate(' + deg + ')'
            });
        },

        _onLoadProgress: function(item) {
            if (!item || !item.sound || !item.$loadProgress) { return; }

            var pctLoaded = (item.sound.bytesLoaded / item.sound.bytesTotal) * 100;

            // hacking for now fill to 100 after 50%,
            // not sure how to handle
            // the circle with opacity
            if (pctLoaded > 50) {
                item.$loadProgress.addClass('gt50');
                return this._updateProgress(item.$loadProgressFill, 100);
            }

            this._updateProgress(item.$loadProgressFill, pctLoaded);
        },

        _onLoadFinished: function(item, success) {
            if (success || !item || !item.$time || !item.$html) { return; }

            // handle load error:
            item.$time.text('Stream Unavailable');
            item.$html.addClass('is-unavailable');

            this.stop();

            if (this._autoplaying) {
                Spice.selectNextItem('soundcloud');
            }
        },

        _onPlayProgress: function(item) {
            if (!item || !item.sound || !item.$time || !item.duration) { return; }

            var msLeft = item.duration - item.sound.position,
                pctPlayed = (item.sound.position / item.duration) * 100;

            // update text label:
            item.$time.text( '-' + DDG.formatDuration(msLeft));

            if (pctPlayed > 50) {
                item.$playProgress.addClass('gt50');
            }

            this._updateProgress(item.$playProgressFill, pctPlayed);
        },

        _onPlayFinished: function(item) {
            this.stop();
            this._autoplaying = 1;
            Spice.selectNextItem('soundcloud');
        }
    };

    env.ddg_spice_sound_cloud = function(api_result) {
        Spice.add({
            id: 'soundcloud',
            name: 'Audio',
            data: api_result,
            meta: {
                sourceName: 'SoundCloud',
                sourceUrl: 'https://soundcloud.com/search?q=' + query,
                sourceIcon: true,
                itemType: 'Tracks'
            },
            templates: {
                item_custom: Spice.sound_cloud.item
            },
            normalize: function(o) {
                var image = o.artwork_url || o.user.avatar_url,
                    usingWaveformImage = 0;

                // Check if it's using the default avatar, if
                // so switch to waveform and set the flag
                if (/default_avatar_large/.test(image)) {
                    image = o.waveform_url;
                    usingWaveformImage = 1;
                } else {
                    // Get the larger image for our IA.
                    image = image.replace(/large\.jpg/, "t200x200.jpg");
                }

                // skip items that can't be streamed or explicit id's we
                // want to skip for adult content:
                if (!o.stream_url || skip_ids[o.id]) {
                    return;
                }

                var streamURL = '/audio?u=' + o.stream_url + '?client_id=' + SOUNDCLOUD_CLIENT_ID;

                return {
                    image: image,
                    usingWaveformImage: usingWaveformImage,
                    hearts: o.favoritings_count || 0,
                    duration: o.duration,
                    link: o.permalink_url,
                    title: o.title,
                    streamURL: streamURL
                };
            },
            onItemSelected: function(item) {
                player.play(item);
            },
            onItemUnselected: function(item) {
                player.pause(item);
            },
            onShow: function() {
                player.init();
            },
            onHide: function() {
                // could kill the player here, not sure, kind
                // of nice that it still plays while you flip to other tabs?
            }
        });
    };
}(this));
<commit_msg>sound cloud: filter by number of likes<commit_after>nrj("soundmanager2/script/soundmanager2-nodebug-jsmin.js", 1);

(function(env) {
    "use strict"

    var SOUNDCLOUD_CLIENT_ID = 'df14a65559c0e555d9f9fd950c2d5b17',
        script = $('[src*="/js/spice/sound_cloud/"]')[0],
        source = $(script).attr("src"),
        query = source.match(/sound_cloud\/([^\/]*)/)[1],

        // Blacklist some adult results.
        skip_ids = {
            80320921: 1,
            75349402: 1
        };

    // global SM var:
    window.SM2_DEFER = true;

    /**
     * Tile Audio player
     *
     * I kept this separate from the spice and self contained so
     * we could potentially refactor it out at some point.
     *
     * If we create another spice with
     * playable audio tiles, we're probably going to want a
     * single controller to manage audio playback
     * across tabs/spices.
     */
    var player = {
        // queue up commands to run once
        // sound manager is ready:
        _onReady: [],

        // flipped to 1 on ready:
        _ready: 0,

        init: function() {
            var self = this;

            // don't init more than once:
            if (this._ready) { return; }

            // make sure the lib is loaded and in memory,
            // otherwise poll for it until it is:
            if (!window["SoundManager"]) {
                return setTimeout(this.init.bind(this),50);
            }

            window.soundManager = new SoundManager();
            soundManager.url = "/soundmanager2/swf";
            soundManager.flashVersion = 9;
            soundManager.useFlashBlock = false;
            soundManager.useHTML5Audio = true;
            //soundManager.onerror(function(){
            //    console.log("error loading soundmanager",arguments);
            //});
            soundManager.ontimeout(function(){
                console.log("timeout loading soundmanager",arguments);
            });
            soundManager.beginDelayedInit();
            soundManager.onready(function() {
                for (var i=0,evt; evt=self._onReady[i]; i++) {
                    self[evt[0]](evt[1]);
                }
                self._ready = 1;
                self._onReady = [];
            });
        },

        play: function(item) {
            if (!this._ready) {
                return this._onReady.push(['play',item]);
            }

            // if a different item is playing, stop it:
            if (this._curItem && this._curItem.id !== item.id) {
                this.stop();
            }

            if (item.sound) {
                item.sound.play();
            } else {
                item.$action = item.$html.find('.audio-controls__action');
                item.$time = item.$html.find('.audio-controls__time');
                item.$progress = item.$html.find('.audio-controls__progress');
                item.$loadProgress = item.$html.find('.audio-controls__progress-loading');
                item.$loadProgressFill = item.$html.find('.audio-controls__progress-loading .rotated-fill');
                item.$playProgress = item.$html.find('.audio-controls__progress-playback');
                item.$playProgressFill = item.$html.find('.audio-controls__progress-playback .rotated-fill');

                item.sound = soundManager.createSound({
                    id: item.id,
                    url: item.streamURL,
                    autoPlay: true,
                    whileloading: this._onLoadProgress.bind(this,item),
                    whileplaying: this._onPlayProgress.bind(this,item),
                    onload: this._onLoadFinished.bind(this,item),
                    onfinish: this._onPlayFinished.bind(this,item)
                });
            }

            item.$html.removeClass('is-paused');
            item.$action.text('║');

            // update the UI

            this._curItem = item;
        },

        pause: function(item) {
            if (!this._ready) {
                return this._onReady.push(['pause',item]);
            }

            if (this._curItem && item && this._curItem.id === item.id && item.sound) {
                item.sound.pause();
                item.$html.addClass('is-paused');
                item.$action.text('►');
            }

            // update the UI
        },

        stop: function() {
            if (!this._ready) {
                return this._onReady.push(['stop']);
            }

            soundManager.stopAll();

            if (this._curItem) {
                // update the UI
                this._curItem.$html.removeClass('is-paused');
                this._curItem.$action.text('►');

                // don't want to clear the 'Stream Unavailable text, only the -0:00 time:
                if (!this._curItem.$html.hasClass('is-unavailable')) {
                    this._curItem.$time.text('');
                }
                this._curItem.$loadProgress.removeClass('gt50');
                this._curItem.$playProgress.removeClass('gt50');
                this._updateProgress(this._curItem.$loadProgressFill,0);
                this._updateProgress(this._curItem.$playProgressFill,0);

                // free up resources:
                this._curItem.sound.destruct();
                delete this._curItem.sound
                delete this._curItem;
            }
        },

        _updateProgress: function(elem,pct) {
            var deg = (360 / 100 * pct) + 'deg';

            elem.css({
                '-moz-transform': 'rotate(' + deg + ')',
                '-webkit-transform': 'rotate(' + deg + ')',
                '-o-transform': 'rotate(' + deg + ')',
                'transform': 'rotate(' + deg + ')'
            });
        },

        _onLoadProgress: function(item) {
            if (!item || !item.sound || !item.$loadProgress) { return; }

            var pctLoaded = (item.sound.bytesLoaded / item.sound.bytesTotal) * 100;

            // hacking for now fill to 100 after 50%,
            // not sure how to handle
            // the circle with opacity
            if (pctLoaded > 50) {
                item.$loadProgress.addClass('gt50');
                return this._updateProgress(item.$loadProgressFill, 100);
            }

            this._updateProgress(item.$loadProgressFill, pctLoaded);
        },

        _onLoadFinished: function(item, success) {
            if (success || !item || !item.$time || !item.$html) { return; }

            // handle load error:
            item.$time.text('Stream Unavailable');
            item.$html.addClass('is-unavailable');

            this.stop();

            if (this._autoplaying) {
                Spice.selectNextItem('soundcloud');
            }
        },

        _onPlayProgress: function(item) {
            if (!item || !item.sound || !item.$time || !item.duration) { return; }

            var msLeft = item.duration - item.sound.position,
                pctPlayed = (item.sound.position / item.duration) * 100;

            // update text label:
            item.$time.text( '-' + DDG.formatDuration(msLeft));

            if (pctPlayed > 50) {
                item.$playProgress.addClass('gt50');
            }

            this._updateProgress(item.$playProgressFill, pctPlayed);
        },

        _onPlayFinished: function(item) {
            this.stop();
            this._autoplaying = 1;
            Spice.selectNextItem('soundcloud');
        }
    };

    env.ddg_spice_sound_cloud = function(api_result) {

        var resultThreshold = 3;
        var filteredResults = [];

        for(var item in api_result){
            if(api_result[item].favoritings_count > resultThreshold)
                filteredResults.push(api_result[item]);
        }

        Spice.add({
            id: 'soundcloud',
            name: 'Audio',
            data: filteredResults,
            meta: {
                sourceName: 'SoundCloud',
                sourceUrl: 'https://soundcloud.com/search?q=' + query,
                sourceIcon: true,
                itemType: 'Tracks'
            },
            templates: {
                item_custom: Spice.sound_cloud.item
            },
            normalize: function(o) {
                var image = o.artwork_url || o.user.avatar_url,
                    usingWaveformImage = 0;

                // Check if it's using the default avatar, if
                // so switch to waveform and set the flag
                if (/default_avatar_large/.test(image)) {
                    image = o.waveform_url;
                    usingWaveformImage = 1;
                } else {
                    // Get the larger image for our IA.
                    image = image.replace(/large\.jpg/, "t200x200.jpg");
                }

                // skip items that can't be streamed or explicit id's we
                // want to skip for adult content:
                if (!o.stream_url || skip_ids[o.id]) {
                    return;
                }

                var streamURL = '/audio?u=' + o.stream_url + '?client_id=' + SOUNDCLOUD_CLIENT_ID;

                return {
                    image: image,
                    usingWaveformImage: usingWaveformImage,
                    hearts: o.favoritings_count || 0,
                    duration: o.duration,
                    link: o.permalink_url,
                    title: o.title,
                    streamURL: streamURL
                };
            },
            onItemSelected: function(item) {
                player.play(item);
            },
            onItemUnselected: function(item) {
                player.pause(item);
            },
            onShow: function() {
                player.init();
            },
            onHide: function() {
                // could kill the player here, not sure, kind
                // of nice that it still plays while you flip to other tabs?
            }
        });
    };
}(this));
<|endoftext|>


<commit_before>import express from "express";
const router = new express.Router();
import fs from "fs";
import multipart from "connect-multiparty";
const multipartMiddleware = multipart();

router.post("/", multipartMiddleware, (req, res) => {
    const newPath = `${__dirname}/../project-scp-files/project.scp`;

    if (req.files.project.name.endsWith(".scp")) {
        fs.rename(req.files.project.path, newPath, (err) => {
            if (err) {
                console.log(err);
                res.json({
                    succes: false, message: "Some error occurred, please try again later!" });
            } else {
                res.json({ succes: true, message: "Project successfully uploaden!" });
            }
        });
    } else {
        res.json({ succes: false, message: "Please upload a .scp file." });
    }
});

module.exports = router;
<commit_msg>fixed eslint errors<commit_after>import express from "express";
const router = new express.Router();
import fs from "fs";
import multipart from "connect-multiparty";
const multipartMiddleware = multipart();

router.post("/", multipartMiddleware, (req, res) => {
    const newPath = `${__dirname}/../project-scp-files/project.scp`;

    if (req.files.project.name.endsWith(".scp")) {
        fs.rename(req.files.project.path, newPath, (err) => {
            if (err) {
                res.json({
                    succes: false, message: "Some error occurred, please try again later!" });
            } else {
                res.json({ succes: true, message: "Project successfully uploaden!" });
            }
        });
    } else {
        res.json({ succes: false, message: "Please upload a .scp file." });
    }
});

module.exports = router;
<|endoftext|>


<commit_before>/**
 * Lite Scroll
 *
 * @version    0.3.1
 * @author     Aiden Foxx
 * @license    MIT License
 * @copyright  2015 Aiden Foxx
 * @link       http://github.com/aidenfoxx
 * @twitter    @furiousfoxx
 */
"use strict";function LiteScroll(t,i){if(!(this instanceof LiteScroll))return new LiteScroll(t,i);this.container=t,this.content=t.children[0],this.scrollCallback=null,this.scrollLock=null,this.scrollEvent=null,this.scrollBegin=null,this.scrollFrame=null,this.scrollInitVec={x:0,y:0},this.scrollInitMouseVec={x:0,y:0},this.resizeTimeout=null,this.x=0,this.y=0,this.options={scrollX:!1,scrollY:!0,snap:!1,snapSpeed:300,dynamicResize:!0,scrollLock:!0,scrollLockThreshold:20,momentum:!0,momentumFalloff:.008};for(var s in i)this.options[s]=i[s];this.containerRect=this.container.getBoundingClientRect(),this.contentRect=this.content.getBoundingClientRect(),this.childRect=this.getChildRect(),this.bindEvents()}LiteScroll.prototype.scrollStart=function(){},LiteScroll.prototype.scroll=function(){},LiteScroll.prototype.scrollEnd=function(){},LiteScroll.prototype.calcRelativePos=function(t,i){return{x:t-this.containerRect.left,y:i-this.containerRect.top}},LiteScroll.prototype.calcTouchCoords=function(t){return this.calcRelativePos(t.changedTouches?t.changedTouches[0].pageX:t.pageX,t.changedTouches?t.changedTouches[0].pageY:t.pageY)},LiteScroll.prototype.clacPointDistance=function(t,i){var s=i.x-t.x,o=i.y-t.y;return Math.sqrt(s*s+o*o)},LiteScroll.prototype.getChildRect=function(){var t=[],i=this.content.style.transform;this.content.style.transitionDuration="0ms",this.content.style.transform="translate(0px, 0px) translateZ(0px)";for(var s=0,o=this.content.children.length;o>s;s++)t.push(this.content.children[s].getBoundingClientRect());return this.content.style.transform=i,t},LiteScroll.prototype.bindEvents=function(){this.container.addEventListener("mousedown",this._scrollStart.bind(this)),this.container.addEventListener("touchstart",this._scrollStart.bind(this)),window.addEventListener("mouseup",this._scrollEnd.bind(this)),window.addEventListener("touchend",this._scrollEnd.bind(this)),window.addEventListener("touchcancel",this._scrollEnd.bind(this)),this.options.dynamicResize&&window.addEventListener("resize",this.resize.bind(this))},LiteScroll.prototype.resize=function(){clearTimeout(this.resizeTimeout),this.resizeTimeout=setTimeout(function(){this.containerRect=this.container.getBoundingClientRect(),this.contentRect=this.content.getBoundingClientRect(),this.childRect=this.getChildRect(),this.snapToNearest()}.bind(this),500)},LiteScroll.prototype.scrollTo=function(t,i,s,o,e){var n=!1;if(t=Math.round(t),i=Math.round(i),this.options.scrollX&&"y"!==this.scrollLock&&this.x!==t){var c=this.contentRect.width-this.containerRect.width;if(t>0||-c>t){var l=this.x-t;t=t>0?0:-c,n=Math.abs(this.x-t)/Math.abs(l)}this.x=t}if(this.options.scrollY&&"x"!==this.scrollLock&&this.y!==i){var r=this.contentRect.height-this.containerRect.height;if(i>0||-r>i){var h=this.y-i;i=i>0?0:-r;var a=Math.abs(this.y-i)/Math.abs(h);n=!n||n>a?a:n}this.y=i}n&&(s*=n),this.content.style.transitionDuration=s+"ms",this.content.style.transitionTimingFunction=o,this.content.style.transform="translate("+this.x+"px, "+this.y+"px) translateZ(0px)",clearTimeout(this.scrollCallback),e&&(this.scrollCallback=setTimeout(e.bind(this),s))},LiteScroll.prototype.snapTo=function(t,i){var s=this.calcRelativePos(this.childRect[t].left,this.childRect[t].top);this.scrollTo(-s.x,-s.y,this.options.snapSpeed,"cubic-bezier(0.1, 0.55, 0.1, 1)",i)},LiteScroll.prototype.snapToNearest=function(t){for(var i=null,s=0,o=0,e=this.childRect.length;e>o;o++){var n=this.calcRelativePos(this.childRect[o].left,this.childRect[o].top);n.x=-n.x,n.y=-n.y;var c=this.clacPointDistance(this,n);(!o||i>c)&&(i=c,s=o)}this.snapTo(s,t)},LiteScroll.prototype._scrollStart=function(t){t.preventDefault(),this.scrollEvent||(this.scrollBegin=Date.now(),this.scrollInitMouseVec=this.calcTouchCoords(t),this.scrollInitVec={x:this.x,y:this.y},this.scrollEvent=this._scroll.bind(this),this.container.addEventListener("mousemove",this.scrollEvent),this.container.addEventListener("touchmove",this.scrollEvent),this.scrollStart(t))},LiteScroll.prototype._scroll=function(t){t.preventDefault(),window.cancelAnimationFrame(this.scrollFrame),this.scrollFrame=window.requestAnimationFrame(function(){this._scrollFrame(t)}.bind(this))},LiteScroll.prototype._scrollFrame=function(t){var i=this.calcTouchCoords(t),s=i.x-this.scrollInitMouseVec.x,o=i.y-this.scrollInitMouseVec.y;this.options.scrollLock&&!this.scrollLock&&(this.options.scrollX&&(s>this.options.scrollLockThreshold||s<-this.options.scrollLockThreshold)&&o<this.options.scrollLockThreshold&&o>-this.options.scrollLockThreshold&&(this.scrollLock="x"),this.options.scrollY&&(o>this.options.scrollLockThreshold||o<-this.options.scrollLockThreshold)&&s<this.options.scrollLockThreshold&&s>-this.options.scrollLockThreshold&&(this.scrollLock="y")),this.scrollTo(this.scrollInitVec.x+s,this.scrollInitVec.y+o,0,"linear"),this.scroll(t)},LiteScroll.prototype._scrollEnd=function(t){if(this.scrollEvent){if(window.cancelAnimationFrame(this.scrollFrame),this.options.momentum){var i=this.calcTouchCoords(t),s=Date.now()-this.scrollBegin,o=(i.x-this.scrollInitMouseVec.x)/s,e=(i.y-this.scrollInitMouseVec.y)/s,n=Math.abs("x"===this.scrollLock||Math.abs(o)>Math.abs(e)?o:e)/this.options.momentumFalloff,c=this.x+Math.abs(o)*o/(2*this.options.momentumFalloff),l=this.y+Math.abs(e)*e/(2*this.options.momentumFalloff);this.scrollTo(c,l,n,"cubic-bezier(0.25, 0.45, 0.45, 0.95)",this.options.snap?this.snapToNearest:null)}else this.options.snap&&this.snapToNearest();this.container.removeEventListener("mousemove",this.scrollEvent),this.container.removeEventListener("touchmove",this.scrollEvent),this.scrollEvent=null,this.scrollLock=null,this.scrollEnd(t)}};<commit_msg>Forgot to minify<commit_after>/**
 * Lite Scroll
 *
 * @version    0.3.1
 * @author     Aiden Foxx
 * @license    MIT License
 * @copyright  2015 Aiden Foxx
 * @link       http://github.com/aidenfoxx
 * @twitter    @furiousfoxx
 */
"use strict";function LiteScroll(t,s){if(!(this instanceof LiteScroll))return new LiteScroll(t,s);this.container=t,this.content=t.children[0],this.scrollCallback=null,this.scrollLock=null,this.scrollEvent=null,this.scrollBegin=null,this.scrollFrame=null,this.scrollInitVec={x:0,y:0},this.scrollInitMouseVec={x:0,y:0},this.resizeTimeout=null,this.x=0,this.y=0,this.options={scrollX:!1,scrollY:!0,snap:!1,snapSpeed:300,dynamicResize:!0,scrollLock:!0,scrollLockThreshold:20,momentum:!0,momentumFalloff:.008};for(var i in s)this.options[i]=s[i];this.containerRect=this.container.getBoundingClientRect(),this.contentRect=this.content.getBoundingClientRect(),this.childRect=this.getChildRect(),this.bindEvents()}LiteScroll.prototype.scrollStart=function(){},LiteScroll.prototype.scroll=function(){},LiteScroll.prototype.scrollEnd=function(){},LiteScroll.prototype.calcRelativePos=function(t,s){return{x:t-this.containerRect.left,y:s-this.containerRect.top}},LiteScroll.prototype.calcTouchCoords=function(t){return this.calcRelativePos(t.changedTouches?t.changedTouches[0].pageX:t.pageX,t.changedTouches?t.changedTouches[0].pageY:t.pageY)},LiteScroll.prototype.clacPointDistance=function(t,s){var i=s.x-t.x,o=s.y-t.y;return Math.sqrt(i*i+o*o)},LiteScroll.prototype.getChildRect=function(){var t=[],s=this.content.style.transform;this.content.style.transitionDuration="0ms",this.content.style.transform="translate(0px, 0px)";for(var i=0,o=this.content.children.length;o>i;i++)t.push(this.content.children[i].getBoundingClientRect());return this.content.style.transform=s,t},LiteScroll.prototype.bindEvents=function(){this.container.addEventListener("mousedown",this._scrollStart.bind(this)),this.container.addEventListener("touchstart",this._scrollStart.bind(this)),window.addEventListener("mouseup",this._scrollEnd.bind(this)),window.addEventListener("touchend",this._scrollEnd.bind(this)),window.addEventListener("touchcancel",this._scrollEnd.bind(this)),this.options.dynamicResize&&window.addEventListener("resize",this.resize.bind(this))},LiteScroll.prototype.resize=function(){clearTimeout(this.resizeTimeout),this.resizeTimeout=setTimeout(function(){this.containerRect=this.container.getBoundingClientRect(),this.contentRect=this.content.getBoundingClientRect(),this.childRect=this.getChildRect(),this.snapToNearest()}.bind(this),500)},LiteScroll.prototype.scrollTo=function(t,s,i,o,e){var n=!1;if(t=Math.round(t),s=Math.round(s),this.options.scrollX&&"y"!==this.scrollLock&&this.x!==t){var l=this.contentRect.width-this.containerRect.width;if(t>0||-l>t){var c=this.x-t;t=t>0?0:-l,n=Math.abs(this.x-t)/Math.abs(c)}this.x=t}if(this.options.scrollY&&"x"!==this.scrollLock&&this.y!==s){var r=this.contentRect.height-this.containerRect.height;if(s>0||-r>s){var h=this.y-s;s=s>0?0:-r;var a=Math.abs(this.y-s)/Math.abs(h);n=!n||n>a?a:n}this.y=s}n&&(i*=n),this.content.style.transitionDuration=i+"ms",this.content.style.transitionTimingFunction=o,this.content.style.transform="translate("+this.x+"px, "+this.y+"px) translateZ(0px)",clearTimeout(this.scrollCallback),e&&(this.scrollCallback=setTimeout(e.bind(this),i))},LiteScroll.prototype.snapTo=function(t,s){var i=this.calcRelativePos(this.childRect[t].left,this.childRect[t].top);this.scrollTo(-i.x,-i.y,this.options.snapSpeed,"cubic-bezier(0.1, 0.55, 0.1, 1)",s)},LiteScroll.prototype.snapToNearest=function(t){for(var s=null,i=0,o=0,e=this.childRect.length;e>o;o++){var n=this.calcRelativePos(this.childRect[o].left,this.childRect[o].top);n.x=-n.x,n.y=-n.y;var l=this.clacPointDistance(this,n);(!o||s>l)&&(s=l,i=o)}this.snapTo(i,t)},LiteScroll.prototype._scrollStart=function(t){t.preventDefault(),this.scrollEvent||(this.scrollBegin=Date.now(),this.scrollInitMouseVec=this.calcTouchCoords(t),this.scrollInitVec={x:this.x,y:this.y},this.scrollEvent=this._scroll.bind(this),this.container.addEventListener("mousemove",this.scrollEvent),this.container.addEventListener("touchmove",this.scrollEvent),this.scrollStart(t))},LiteScroll.prototype._scroll=function(t){t.preventDefault(),window.cancelAnimationFrame(this.scrollFrame),this.scrollFrame=window.requestAnimationFrame(function(){this._scrollFrame(t)}.bind(this))},LiteScroll.prototype._scrollFrame=function(t){var s=this.calcTouchCoords(t),i=s.x-this.scrollInitMouseVec.x,o=s.y-this.scrollInitMouseVec.y;this.options.scrollLock&&!this.scrollLock&&(this.options.scrollX&&(i>this.options.scrollLockThreshold||i<-this.options.scrollLockThreshold)&&o<this.options.scrollLockThreshold&&o>-this.options.scrollLockThreshold&&(this.scrollLock="x"),this.options.scrollY&&(o>this.options.scrollLockThreshold||o<-this.options.scrollLockThreshold)&&i<this.options.scrollLockThreshold&&i>-this.options.scrollLockThreshold&&(this.scrollLock="y")),this.scrollTo(this.scrollInitVec.x+i,this.scrollInitVec.y+o,0,"linear"),this.scroll(t)},LiteScroll.prototype._scrollEnd=function(t){if(this.scrollEvent){if(window.cancelAnimationFrame(this.scrollFrame),this.options.momentum){var s=this.calcTouchCoords(t),i=Date.now()-this.scrollBegin,o=(s.x-this.scrollInitMouseVec.x)/i,e=(s.y-this.scrollInitMouseVec.y)/i,n=Math.abs("x"===this.scrollLock||Math.abs(o)>Math.abs(e)?o:e)/this.options.momentumFalloff,l=this.x+Math.abs(o)*o/(2*this.options.momentumFalloff),c=this.y+Math.abs(e)*e/(2*this.options.momentumFalloff);this.scrollTo(l,c,n,"cubic-bezier(0.25, 0.45, 0.45, 0.95)",this.options.snap?this.snapToNearest:null)}else this.options.snap&&this.snapToNearest();this.container.removeEventListener("mousemove",this.scrollEvent),this.container.removeEventListener("touchmove",this.scrollEvent),this.scrollEvent=null,this.scrollLock=null,this.scrollEnd(t)}};<|endoftext|>


<commit_before><commit_msg>VTK-3603 - check that UIOWS / TP is unequal from vrtx data before saving it<commit_after><|endoftext|>


<commit_before><commit_msg>context passed as JavaScript - object is not processed in a right way<commit_after><|endoftext|>


<commit_before>/* Python 'tuple' type */

function tuple(seq) {
    if (arguments.length <= 1) {
        return new _tuple(seq);
    } else {
        throw new py_builtins.TypeError("tuple() takes at most 1 argument (" + arguments.length + " given)");
    }
}

function _tuple(seq) {
    this.__init__(seq);
}

_tuple.__name__ = 'tuple';
_tuple.prototype.__class__ = _tuple;

_tuple.prototype.__init__ = function(seq) {
    if (!defined(seq)) {
        this._items = [];
        this._len = 0;
    } else {
        this._items = copy(iter(seq));
        this._len = -1;
    }
};

_tuple.prototype.__str__ = function () {
    if (this.__len__() == 1) {
        return str("(" + this._items[0] + ",)");
    } else {
        return str("(" + this._items.join(", ") + ")");
    }
};

_tuple.prototype.__eq__ = function (other) {
    if (other.__class__ == this.__class__) {
        if (len(this) != len(other))
            return false;
        for (var i = 0; i < len(this); i++) {
            // TODO: use __eq__ here as well:
            if (this._items[i] != other._items[i])
                return false;
        }
        return true;
        // This doesn't take into account hash collisions:
        //return hash(this) == hash(other)
    } else
        return false;
};

_tuple.prototype.toString = function () {
    return js(this.__str__());
};

_tuple.prototype._js_ = function () {
    var items = [];

    iterate(iter(this), function(item) {
        items.push(js(item));
    });

    return items;
};

_tuple.prototype.__hash__ = function () {
    var value = 0x345678;
    var length = this.__len__();

    for (var index in this._items) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ hash(this._items[index]);
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

_tuple.prototype.__len__ = function() {
    if (this._len == -1) {
        var count = 0;

        for (var index in this._items) {
            count += 1;
        }

        this._len = count;
        return count;
    } else
        return this._len;
};

_tuple.prototype.__iter__ = function() {
    return new _iter(this._items);
};

_tuple.prototype.__contains__ = function(item) {
    for (var index in this._items) {
        if (py_builtins.eq(item, this._items[index])) {
            return true;
        }
    }

    return false;
};

_tuple.prototype.__getitem__ = function(index) {
    var seq;
    if (isinstance(index, _slice)) {
        var s = index;
        var inds = s.indices(len(this));
        var start = inds.__getitem__(0);
        var stop = inds.__getitem__(1);
        var step = inds.__getitem__(2);
        seq = [];
        for (var i = start; i < stop; i += step) {
            seq.push(this.__getitem__(i));
        }
        return new this.__class__(seq);
    } else if ((index >= 0) && (index < len(this)))
        return this._items[index];
    else if ((index < 0) && (index >= -len(this)))
        return this._items[index+len(this)];
    else
        throw new py_builtins.IndexError("list assignment index out of range");
};

_tuple.prototype.__setitem__ = function(index, value) {
    throw new py_builtins.TypeError("'tuple' object doesn't support item assignment");
};

_tuple.prototype.__delitem__ = function(index) {
    throw new py_builtins.TypeError("'tuple' object doesn't support item deletion");
};

_tuple.prototype.count = function(value) {
    var count = 0;

    for (var index in this._items) {
        if (value == this._items[index]) {
            count += 1;
        }
    }

    return count;
};

_tuple.prototype.index = function(value, start, end) {
    if (!defined(start)) {
        start = 0;
    }

    for (var i = start; !defined(end) || (start < end); i++) {
        var _value = this._items[i];

        if (!defined(_value)) {
            break;
        }

        if (_value == value) {
            return i;
        }
    }

    throw new py_builtins.ValueError("tuple.index(x): x not in list");
};

<commit_msg> * Updated tuple to use x.__call__ for str and iter<commit_after>/* Python 'tuple' type */

function tuple(seq) {
    if (arguments.length <= 1) {
        return new _tuple(seq);
    } else {
        throw new py_builtins.TypeError("tuple() takes at most 1 argument (" + arguments.length + " given)");
    }
}

function _tuple(seq) {
    this.__init__(seq);
}

_tuple.__name__ = 'tuple';
_tuple.prototype.__class__ = _tuple;

_tuple.prototype.__init__ = function(seq) {
    if (!defined(seq)) {
        this._items = [];
        this._len = 0;
    } else {
        this._items = copy(iter.__call__(seq));
        this._len = -1;
    }
};

_tuple.prototype.__str__ = function () {
    if (this.__len__() == 1) {
        return str.__call__("(" + this._items[0] + ",)");
    } else {
        return str.__call__("(" + this._items.join(", ") + ")");
    }
};

_tuple.prototype.__eq__ = function (other) {
    if (other.__class__ == this.__class__) {
        if (len(this) != len(other))
            return false;
        for (var i = 0; i < len(this); i++) {
            // TODO: use __eq__ here as well:
            if (this._items[i] != other._items[i])
                return false;
        }
        return true;
        // This doesn't take into account hash collisions:
        //return hash(this) == hash(other)
    } else
        return false;
};

_tuple.prototype.toString = function () {
    return js(this.__str__());
};

_tuple.prototype._js_ = function () {
    var items = [];

    iterate(iter.__call__(this), function(item) {
        items.push(js(item));
    });

    return items;
};

_tuple.prototype.__hash__ = function () {
    var value = 0x345678;
    var length = this.__len__();

    for (var index in this._items) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ hash(this._items[index]);
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

_tuple.prototype.__len__ = function() {
    if (this._len == -1) {
        var count = 0;

        for (var index in this._items) {
            count += 1;
        }

        this._len = count;
        return count;
    } else
        return this._len;
};

_tuple.prototype.__iter__ = function() {
    return iter.__call__(this._items);
};

_tuple.prototype.__contains__ = function(item) {
    for (var index in this._items) {
        if (py_builtins.eq(item, this._items[index])) {
            return true;
        }
    }

    return false;
};

_tuple.prototype.__getitem__ = function(index) {
    var seq;
    if (isinstance(index, _slice)) {
        var s = index;
        var inds = s.indices(len(this));
        var start = inds.__getitem__(0);
        var stop = inds.__getitem__(1);
        var step = inds.__getitem__(2);
        seq = [];
        for (var i = start; i < stop; i += step) {
            seq.push(this.__getitem__(i));
        }
        return new this.__class__(seq);
    } else if ((index >= 0) && (index < len(this)))
        return this._items[index];
    else if ((index < 0) && (index >= -len(this)))
        return this._items[index+len(this)];
    else
        throw new py_builtins.IndexError("list assignment index out of range");
};

_tuple.prototype.__setitem__ = function(index, value) {
    throw new py_builtins.TypeError("'tuple' object doesn't support item assignment");
};

_tuple.prototype.__delitem__ = function(index) {
    throw new py_builtins.TypeError("'tuple' object doesn't support item deletion");
};

_tuple.prototype.count = function(value) {
    var count = 0;

    for (var index in this._items) {
        if (value == this._items[index]) {
            count += 1;
        }
    }

    return count;
};

_tuple.prototype.index = function(value, start, end) {
    if (!defined(start)) {
        start = 0;
    }

    for (var i = start; !defined(end) || (start < end); i++) {
        var _value = this._items[i];

        if (!defined(_value)) {
            break;
        }

        if (_value == value) {
            return i;
        }
    }

    throw new py_builtins.ValueError("tuple.index(x): x not in list");
};

<|endoftext|>


<commit_before>'use strict';

import multi from '../multi';
import * as xenaQuery from '../xenaQuery';
import {Observable, Scheduler} from '../rx';
import * as _ from '../underscore_ext';
import parsePos from '../parsePos';
import parseInput from '../parseInput';
import parseGeneSignature from '../parseGeneSignature';
import {signatureField} from '../models/fieldSpec';
import {defaultColorClass} from '../heatmapColors';

// XXX duplicated in VariableSelect.
var getAssembly = (datasets, dsID) =>
	_.getIn(datasets, [dsID, 'assembly'],
		_.getIn(datasets, [dsID, 'probemapMeta', 'assembly']));

export var guessFields = (text, assembly) => {
	var value = text.trim(),
		sig = parseGeneSignature(value),
		pos = parsePos(value, assembly),
		hasCoord = value.match(/^chr[0-9xyXY]+[pq]?:/),
		fields = sig ? sig.genes :
			pos ? [value] :
			parseInput(value);

	return {
		value,
		fields,
		sig,
		pos,
		hasCoord
	};
};

export var matchDatasetFields = multi((datasets, dsID) => {
	var meta = datasets[dsID];
	// Do field matching against probemap if we have one & aren't doing a signature.
	return meta.type === 'genomicMatrix' && meta.probemap ? 'genomicMatrix-probemap' : meta.type;
});

// XXX The error handling here isn't great, because it can leave us with a
// field of the wrong case, e.g. foxm1 vs. FOXM1, or treat a probe as a gene.
// However, it's better to handle it than to lose the observable, which wedges
// the widget. Better handling would warn the user and wait for the network
// error to clear.

// default to probes
matchDatasetFields.dflt = (datasets, dsID, input) => {
	var guess = guessFields(input, getAssembly(datasets, dsID)),
		{fields, pos} = guess,
		warning = pos ? 'position-unsupported' : undefined;
	return xenaQuery.matchFields(dsID, fields).map(fields => ({
		...guess,
		type: 'probes',
		warning,
		fields
	})).catch(err => {
		console.log(err);
		return Observable.of({type: 'probes', warning, fields: fields}, Scheduler.asap);
	});
};

var geneProbeMatch = (host, dsID, probemap, guess) =>
	Observable.zip(
		xenaQuery.sparseDataMatchGenes(host, probemap, guess.fields),
		xenaQuery.matchFields(dsID, guess.fields),
		(genes, probes) => _.filter(probes).length > _.filter(genes).length ?
			{...guess, type: 'probes', fields: probes} :
			{...guess, type: 'genes', fields: genes}
	).catch(err => {
		console.log(err);
		return Observable.of({...guess, type: 'genes'}, Scheduler.asap);
	});

var MAX_PROBES = 500;
var chromLimit = (host, probemap, guess) =>
	xenaQuery.maxRange(host, probemap, guess.pos.chrom,
				guess.pos.baseStart, guess.pos.baseEnd, MAX_PROBES)
		.map(([end]) => ({
			...guess,
			type: 'chrom',
			...(end != null ? {
				warning: 'too-many-probes',
				start: guess.pos.baseStart,
				end: end - 1} : {})
		}));

matchDatasetFields.add('genomicMatrix-probemap', (datasets, dsID, input) => {
	const guess = guessFields(input, getAssembly(datasets, dsID)),
		{host} = JSON.parse(dsID),
		probemap = datasets[dsID].probemap;
	return guess.pos ? chromLimit(host, probemap, guess)
		: geneProbeMatch(host, dsID, probemap, guess);
});

var matchAnyPosition = guess => Observable.of({...guess, type: 'chrom'}, Scheduler.asap);

var normalizeGenes = (host, dsID, guess) =>
	xenaQuery.sparseDataMatchField(host, 'name2', dsID, guess.fields).map(fields => ({
			...guess,
			type: 'genes',
			fields
		}));

function matchWithAssembly(datasets, dsID, input) {
	var guess = guessFields(input, getAssembly(datasets, dsID)),
		ref = xenaQuery.refGene[datasets[dsID].assembly];
	return (guess.pos ? matchAnyPosition(guess) : normalizeGenes(ref.host, ref.name, guess)).catch(err => {
		console.log(err);
		return Observable.of({...guess, type: 'genes'}, Scheduler.asap);
	});
}

matchDatasetFields.add('genomicSegment', matchWithAssembly);
matchDatasetFields.add('mutationVector', matchWithAssembly);

function matchPhenotype(datasets, dsID, input) {
	return Observable.of({value: input, fields: [input]}, Scheduler.asap);
}

matchDatasetFields.add('clinicalMatrix', matchPhenotype);

// need to handle
// phenotypic,
// null field, null dataset
// sparse,
// dense with probemap,
// dense without probemap

export var typeWidth = {
	matrix: 136,
	chrom: 200
};

// 'features' is a problem here, because they are not unique across datasets.
// How do we look up features w/o a dataset?
function getValueType(dataset, features, fields) {
	var {type} = dataset,
		valuetype = _.getIn(features, [fields[0], 'valuetype']);
	return type === 'mutationVector' ? 'mutation' :
		type === 'genomicSegment' ? 'segmented' :
		type === 'clinicalMatrix' && valuetype === 'category' ? 'coded' :
		'float';
}

function getFieldType(dataset, fields, probes, pos) {
	if (dataset.type === 'mutationVector') {
		return dataset.dataSubType.search(/SV|structural/i) !== -1 ? 'SV' : 'mutation';
	}
	if (dataset.type === 'genomicSegment') {
		return 'segmented';
	}
	if (dataset.type === 'clinicalMatrix') {
		return 'clinical';
	}
	// We treat probes in chrom view (pos) as geneProbes
	return  probes ? 'probes' : ((fields.length > 1 && !pos) ? 'genes' : 'geneProbes');
}

function sigFields(fields, {genes, weights}) {
	return {
		missing: genes.filter((p, i) => !fields[i]),
		genes: fields.filter(p => p),
		weights: weights.filter((p, i) => fields[i])
	};
}

// use default vizSettings if we have min and max.
var getDefaultVizSettings = meta => _.has(meta, 'min') && _.has(meta, 'max') ?
	{vizSettings: _.pick(meta, 'min', 'max', 'minstart', 'maxstart')} : {};

function columnSettings(datasets, features, dsID, matches) {
	var {fields, value: input, pos, sig} = matches,
		probes = matches.type === 'probes',
		meta = datasets[dsID],
		fieldType = getFieldType(meta, fields, probes, pos),
		normalizedFields =
			pos ? [`${pos.chrom}:${pos.baseStart}-${pos.baseEnd}`] :
			_.contains(['segmented', 'mutation', 'SV'], fieldType) ? [fields[0]] :
			fields;

	// My god, this is a disaster.
	if (sig) {
		let {missing, genes, weights} = sigFields(fields, sig),
			missingLabel = _.isEmpty(missing) ? '' : ` (missing terms: ${missing.join(', ')})`;
		return signatureField('signature' + missingLabel, {
			signature: ['geneSignature', dsID, genes, weights],
			missing,
			fieldType: matches.type,
			defaultNormalization: meta.colnormalization,
			colorClass: defaultColorClass,
			fields: [input],
			dsID
		});
	}

	return {
		...(fieldType === 'geneProbes' ? {showIntrons: true} : {}),
		...(_.getIn(meta, ['probemapMeta', 'dataSubType']) === 'regulon' ? {clustering: 'probes'} : {}),
		...getDefaultVizSettings(meta),
		fields: normalizedFields,
		fetchType: 'xena',
		valueType: getValueType(meta, features[dsID], fields),
		fieldType,
		dsID,
		defaultNormalization: meta.colnormalization,
		// XXX this assumes fields[0] doesn't appear in features if ds is genomic
		fieldLabel: _.getIn(features, [dsID, fields[0], 'longtitle']) || normalizedFields.join(', '),
		colorClass: defaultColorClass,
		assembly: getAssembly(datasets, dsID)
	};
}

export var computeSettings = _.curry((datasets, features, opts, dataset, matches) => {
	var ds = datasets[dataset];
	var settings = columnSettings(datasets, features, dataset, matches),
		columnLabel = ((ds.dataSubType && !ds.dataSubType.match(/phenotype/i)) ? (ds.dataSubType + ' - ') : '') +
			(ds.dataSubType && ds.dataSubType.match(/phenotype/i) ? '' : ds.label);

	// XXX need a way to validate settings that depend on column type, i.e.
	// fieldType geneProbes only works for matrix with probemap.
	// Or, a possible refactor of the schema to make this simpler?
	return _.assocIn(settings,
		['width'], _.contains(['mutationVector', 'segmented'], ds.type) ? typeWidth.chrom : typeWidth.matrix,
		['dataset'], ds,
		['columnLabel'], columnLabel,
		['user'], {columnLabel: columnLabel, fieldLabel: settings.fieldLabel},
		...(opts || []).flatten()
	);

});

<commit_msg>Refactor of column setting code.<commit_after>'use strict';

import multi from '../multi';
import * as xenaQuery from '../xenaQuery';
import {Observable, Scheduler} from '../rx';
import * as _ from '../underscore_ext';
import parsePos from '../parsePos';
import parseInput from '../parseInput';
import parseGeneSignature from '../parseGeneSignature';
import {signatureField} from '../models/fieldSpec';
import {defaultColorClass} from '../heatmapColors';

// XXX duplicated in VariableSelect.
var getAssembly = (datasets, dsID) =>
	_.getIn(datasets, [dsID, 'assembly'],
		_.getIn(datasets, [dsID, 'probemapMeta', 'assembly']));

export var guessFields = (text, assembly) => {
	var value = text.trim(),
		sig = parseGeneSignature(value),
		pos = parsePos(value, assembly),
		hasCoord = value.match(/^chr[0-9xyXY]+[pq]?:/),
		fields = sig ? sig.genes :
			pos ? [value] :
			parseInput(value);

	return {
		value,
		fields,
		sig,
		pos,
		hasCoord
	};
};

export var matchDatasetFields = multi((datasets, dsID) => {
	var meta = datasets[dsID];
	// Do field matching against probemap if we have one & aren't doing a signature.
	return meta.type === 'genomicMatrix' && meta.probemap ? 'genomicMatrix-probemap' : meta.type;
});

// XXX The error handling here isn't great, because it can leave us with a
// field of the wrong case, e.g. foxm1 vs. FOXM1, or treat a probe as a gene.
// However, it's better to handle it than to lose the observable, which wedges
// the widget. Better handling would warn the user and wait for the network
// error to clear.

// default to probes
matchDatasetFields.dflt = (datasets, dsID, input) => {
	var guess = guessFields(input, getAssembly(datasets, dsID)),
		{fields, pos} = guess,
		warning = pos ? 'position-unsupported' : undefined;
	return xenaQuery.matchFields(dsID, fields).map(fields => ({
		...guess,
		type: 'probes',
		warning,
		fields
	})).catch(err => {
		console.log(err);
		return Observable.of({type: 'probes', warning, fields: fields}, Scheduler.asap);
	});
};

var geneProbeMatch = (host, dsID, probemap, guess) =>
	Observable.zip(
		xenaQuery.sparseDataMatchGenes(host, probemap, guess.fields),
		xenaQuery.matchFields(dsID, guess.fields),
		(genes, probes) => _.filter(probes).length > _.filter(genes).length ?
			{...guess, type: 'probes', fields: probes} :
			{...guess, type: 'genes', fields: genes}
	).catch(err => {
		console.log(err);
		return Observable.of({...guess, type: 'genes'}, Scheduler.asap);
	});

var MAX_PROBES = 500;
var chromLimit = (host, probemap, guess) =>
	xenaQuery.maxRange(host, probemap, guess.pos.chrom,
				guess.pos.baseStart, guess.pos.baseEnd, MAX_PROBES)
		.map(([end]) => ({
			...guess,
			type: 'chrom',
			...(end != null ? {
				warning: 'too-many-probes',
				start: guess.pos.baseStart,
				end: end - 1} : {})
		}));

matchDatasetFields.add('genomicMatrix-probemap', (datasets, dsID, input) => {
	const guess = guessFields(input, getAssembly(datasets, dsID)),
		{host} = JSON.parse(dsID),
		probemap = datasets[dsID].probemap;
	return guess.pos ? chromLimit(host, probemap, guess)
		: geneProbeMatch(host, dsID, probemap, guess);
});

var matchAnyPosition = guess => Observable.of({...guess, type: 'chrom'}, Scheduler.asap);

var normalizeGenes = (host, dsID, guess) =>
	xenaQuery.sparseDataMatchField(host, 'name2', dsID, guess.fields).map(fields => ({
			...guess,
			type: 'genes',
			fields
		}));

function matchWithAssembly(datasets, dsID, input) {
	var guess = guessFields(input, getAssembly(datasets, dsID)),
		ref = xenaQuery.refGene[datasets[dsID].assembly];
	return (guess.pos ? matchAnyPosition(guess) : normalizeGenes(ref.host, ref.name, guess)).catch(err => {
		console.log(err);
		return Observable.of({...guess, type: 'genes'}, Scheduler.asap);
	});
}

matchDatasetFields.add('genomicSegment', matchWithAssembly);
matchDatasetFields.add('mutationVector', matchWithAssembly);

function matchPhenotype(datasets, dsID, input) {
	return Observable.of({value: input, fields: [input]}, Scheduler.asap);
}

matchDatasetFields.add('clinicalMatrix', matchPhenotype);

// need to handle
// phenotypic,
// null field, null dataset
// sparse,
// dense with probemap,
// dense without probemap

export var typeWidth = {
	matrix: 136,
	chrom: 200
};

var typeClass = dataset =>
	_.contains(['mutationVector', 'segmented'], dataset.type) ? 'chrom' :
	'matrix';

// 'features' is a problem here, because they are not unique across datasets.
// How do we look up features w/o a dataset?
function getValueType(dataset, features, fields) {
	var {type} = dataset,
		valuetype = _.getIn(features, [fields[0], 'valuetype']);
	return type === 'mutationVector' ? 'mutation' :
		type === 'genomicSegment' ? 'segmented' :
		type === 'clinicalMatrix' && valuetype === 'category' ? 'coded' :
		'float';
}

function getFieldType(dataset, fields, matches, pos) {
	var {sig, type} = matches;
	if (sig) {
		return type;
	}
	if (dataset.type === 'mutationVector') {
		return dataset.dataSubType.search(/SV|structural/i) !== -1 ? 'SV' : 'mutation';
	}
	if (dataset.type === 'genomicSegment') {
		return 'segmented';
	}
	if (dataset.type === 'clinicalMatrix') {
		return 'clinical';
	}
	// We treat probes in chrom view (pos) as geneProbes
	return  type === 'probes' ? 'probes' : ((fields.length > 1 && !pos) ? 'genes' : 'geneProbes');
}

function sigFields(fields, {genes, weights}) {
	return {
		missing: genes.filter((p, i) => !fields[i]),
		genes: fields.filter(p => p),
		weights: weights.filter((p, i) => fields[i])
	};
}

// use default vizSettings if we have min and max.
var getDefaultVizSettings = meta => _.has(meta, 'min') && _.has(meta, 'max') ?
	{vizSettings: _.pick(meta, 'min', 'max', 'minstart', 'maxstart')} : {};

var xenaField = (datasets, features, settings) => ({
	...settings,
	fetchType: 'xena',
	...(_.getIn(settings.dataset, ['probemapMeta', 'dataSubType']) === 'regulon' ? {clustering: 'probes'} : {}),
	...getDefaultVizSettings(settings.dataset),
	valueType: getValueType(settings.dataset, features[settings.dsID], settings.fields),
	assembly: getAssembly(datasets, settings.dsID)
});

function columnSettings(datasets, features, dsID, matches) {
	var {fields, value, pos, sig} = matches,
		dataset = datasets[dsID],
		fieldType = getFieldType(dataset, fields, matches, pos),
		{missing, genes, weights} = sig ? sigFields(fields, sig) : {},
		normalizedFields =
			sig ? [value] :
			pos ? [`${pos.chrom}:${pos.baseStart}-${pos.baseEnd}`] :
			_.contains(['segmented', 'mutation', 'SV'], fieldType) ? [fields[0]] :
			fields,
		columnLabel =
			!dataset.dataSubType ? dataset.label :
			dataset.dataSubType.match(/phenotype/i) ? '' :
			`${dataset.dataSubType} - ${dataset.label}`,
		fieldLabel =
			sig ? `signature${_.isEmpty(missing) ? '' : ` (missing terms: ${missing.join(', ')})`}` :
			dataset.type === 'clinicalMatrix' ? _.getIn(features, [dsID, fields[0], 'longtitle']) || fields[0] :
			normalizedFields.join(', '),
		defaults = {
			...(fieldType === 'geneProbes' ? {showIntrons: true} : {}),
			colorClass: defaultColorClass,
			columnLabel,
			dataset,
			defaultNormalization: dataset.colnormalization,
			dsID,
			fields: normalizedFields,
			fieldLabel,
			fieldType,
			user: {columnLabel, fieldLabel},
			width: typeWidth[typeClass(dataset)],
		};

	return sig ? signatureField(fieldLabel, {
			...defaults,
			signature: ['geneSignature', dsID, genes, weights],
			missing
		}) : xenaField(datasets, features, defaults);
}

export var computeSettings = _.curry((datasets, features, opts, dataset, matches) => {
	var settings = columnSettings(datasets, features, dataset, matches);

	// XXX need a way to validate settings that depend on column type, i.e.
	// fieldType geneProbes only works for matrix with probemap.
	// Or, a possible refactor of the schema to make this simpler?
	return _.assocIn(settings, ...(opts || []).flatten());

});
<|endoftext|>


<commit_before><commit_msg>fb meta<commit_after><|endoftext|>


<commit_before>'use strict';
(function (ns) {
  ns.InvoiceEditor = tp.view.Loader.extend({
    $context:null,
    events: {
      'click .edit': 'edit_clickHandler',
      'click .edit-button': 'editButton_clickHandler',
      'click .invoice-button': 'invoiceButton_clickHandler',
      'click #reapply-button': 'reapplyButton_clickHandler',
      'success': 'success_handler'
    },
    render: function () {
      var products = this.model.get('products');
      var opt = this.model.options;
      var cpa_first_total = 0
        , cpa_after_total =0
        , income_before_total = 0
        , income_after_total = 0
        , rmb = ''
        , joy_income = 0
        , red_ad_income = 0
        , red_ios_income = 0;

      _.each(products,function (e) {
        if(!e.quote_rmb_after){
          _.extend(e,{
            quote_rmb_after: e.quote_rmb,
            cpa_after: e.cpa,
            income_after: e.income,
            rate: ((1 - e.cpa * e.quote_rmb / e.income) * 100).toFixed(2),
            money_cut: e.income - e.income,
            remark: ''
          });
        } else{
          _.extend(e,{
            income_after: e.quote_rmb_after * e.cpa_after,
            rate: ((1 - e.cpa_after * e.quote_rmb_after / e.income) * 100).toFixed(2),
            money_cut: e.income - e.quote_rmb_after * e.cpa_after
          })
        }

        cpa_first_total += Number(e.cpa);
        cpa_after_total += Number(e.cpa_after);
        income_after_total += e.income_after;
        income_before_total += e.income;
        rmb = tp.utils.convertCurrency(income_after_total);

        switch (e.sdk_type){
          case "0":
            joy_income += e.income_after;
            break;
          case "1":
            red_ad_income += e.income_after;
            break;
          case "2":
            red_ios_income += e.income_after;
            break;
        }
      });

      _.extend(this.model.options,{
        cpa_first_total: cpa_first_total,
        cpa_after_total: cpa_after_total,
        income_after_total: income_after_total,
        income_before_total: income_before_total,
        joy_income: joy_income,
        red_ad_income: red_ad_income,
        red_ios_income:red_ios_income
      });

      tp.view.Loader.prototype.render.call(this);

      var smartTable = this.$context.createInstance(tp.component.SmartTable,{el:this.$('#ad_table'),url: " "});

      products.push({rmb:rmb});
      smartTable.collection.options = opt;
      smartTable.collection.reset(products);
      products.pop();
    },
    reapplyButton_clickHandler: function () {
      this.model.id = null;
      this.model.urlRoot = tp.API + 'invoice/init';
    },
    editButton_clickHandler: function (event) {
      var target = event.currentTarget;
      var options = {
        model:this.model,
        title:'编辑',
        confirm: '确定',
        content:'page/stat/invoice-detail-edit.hbs',
        isRemote: true,
        target: target
      };
      switch ($(target).attr('class')){
        case 'edit-button cpa-after':
          this.model.options.val = $(target).text();
          break;

        case 'edit-button price-after':
          this.model.options.val = $(target).text().substr(1);
          break;

        case 'edit-button comment':
          this.model.options.isComment = true;
          this.model.options.val = $(target).text() == '编辑' ? '' : $(target).text();
          break;
      }

      var popup = tp.popup.Manager.popup(options);
      popup.on('confirm', this.editPopup_confirmHandler, this);
    },
    editPopup_confirmHandler: function (popup) {
      var val = popup.$('input').val()
         ,target = popup.options.target
         ,ad_id = $(target).closest('tr').attr('id')
         ,product = _.findWhere(this.model.get('products'),{ad_id: ad_id});

      if(val){
        switch ($(target).attr('class')){
          case 'edit-button cpa-after':
            product = _.extend(product,{cpa_after: val});
            break;

          case 'edit-button price-after':
            product = _.extend(product,{quote_rmb_after: val});
            break;

          case 'edit-button comment':
            product = _.extend(product,{remark: val.trim()});
            break;
        }
      }
      this.render();

      if(!this.model.get('init')){
        this.model.save({
          products: this.model.get('products'),
          income: this.model.options.income_after_total,
          income_first: this.model.options.income_before_total
        },{patch:true});
      }
    },
    success_handler: function () {
      window.location ='#/invoice/';
    },
    invoiceButton_clickHandler: function (event) {
      var target = event.currentTarget;
      var start = this.model.get('start');
      var end = this.model.get('end');
      var ad_id = this.$('#ad_table tbody tr').eq(0).attr('id');
      var options = {
        title: target.title,
        id: ad_id,
        confirm: '确定',
        content: "page/stat/choose-ad.hbs",
        isRemote: true,
        start: start,
        end: end,
        fromInvoice: true
      };

      var popup = tp.popup.Manager.popup(options);
      popup.on('confirm', this.invoicePopup_confirmHandler, this);
    },
    invoicePopup_confirmHandler: function (popup) {
      var ids = ""
        , start = this.model.get('start')
        , end = this.model.get('end')
        , len = popup.$(':checked').length
        , self = this;

      if(len){
        popup.$(':checked').each(function (i) {
          if(i + 1 != len){
            ids += $(this).val() + ',';
          } else{
            ids += $(this).val();
          }
        });
        var newModel = new tp.model.InvoiceDetail({
          start:start,
          end:end,
          ids: ids
        });
        newModel.fetch({
          success: function (model,response) {
            var products = response.invoice.products;
            self.model.set('products',products);
            self.render();
            if(!self.model.get('init')){
              self.model.save({products:self.model.get("products")},{patch:true}); //如果是二次编辑，就直接save
            }
          }
        });
      }
    }
  });
}(Nervenet.createNameSpace('tp.page')));<commit_msg>  修复一个bug。<commit_after>'use strict';
(function (ns) {
  ns.InvoiceEditor = tp.view.Loader.extend({
    $context:null,
    events: {
      'click .edit': 'edit_clickHandler',
      'click .edit-button': 'editButton_clickHandler',
      'click .invoice-button': 'invoiceButton_clickHandler',
      'click #reapply-button': 'reapplyButton_clickHandler',
      'success': 'success_handler'
    },
    render: function () {
      var products = this.model.get('products');
      var opt = this.model.options;
      var cpa_first_total = 0
        , cpa_after_total =0
        , income_before_total = 0
        , income_after_total = 0
        , rmb = ''
        , joy_income = 0
        , red_ad_income = 0
        , red_ios_income = 0;

      _.each(products,function (e) {
        if(!e.quote_rmb_after){
          _.extend(e,{
            quote_rmb_after: e.quote_rmb,
            cpa_after: e.cpa,
            income_after: e.income,
            rate: ((1 - e.cpa * e.quote_rmb / e.income) * 100).toFixed(2),
            money_cut: e.income - e.income,
            remark: ''
          });
        } else{
          _.extend(e,{
            income_after: e.quote_rmb_after * e.cpa_after,
            rate: ((1 - e.cpa_after * e.quote_rmb_after / e.income) * 100).toFixed(2),
            money_cut: e.income - e.quote_rmb_after * e.cpa_after
          })
        }

        cpa_first_total += Number(e.cpa);
        cpa_after_total += Number(e.cpa_after);
        income_after_total += e.income_after;
        income_before_total += e.income;
        rmb = tp.utils.convertCurrency(income_after_total);

        switch (e.sdk_type){
          case "0":
            joy_income += e.income_after;
            break;
          case "1":
            red_ad_income += e.income_after;
            break;
          case "2":
            red_ios_income += e.income_after;
            break;
        }
      });

      _.extend(this.model.options,{
        cpa_first_total: cpa_first_total,
        cpa_after_total: cpa_after_total,
        income_after_total: income_after_total,
        income_before_total: income_before_total,
        joy_income: joy_income,
        red_ad_income: red_ad_income,
        red_ios_income:red_ios_income
      });

      tp.view.Loader.prototype.render.call(this);

      var smartTable = this.$context.createInstance(tp.component.SmartTable,{el:this.$('#ad_table'),url: " "});

      products.push({rmb:rmb});
      smartTable.collection.options = opt;
      smartTable.collection.reset(products);
      products.pop();
    },
    reapplyButton_clickHandler: function () {
      this.model.id = null;
      this.model.urlRoot = tp.API + 'invoice/init';
    },
    editButton_clickHandler: function (event) {
      var target = event.currentTarget;
      var options = {
        model:this.model,
        title:'编辑',
        confirm: '确定',
        content:'page/stat/invoice-detail-edit.hbs',
        isRemote: true,
        target: target
      };
      switch ($(target).attr('class')){
        case 'edit-button cpa-after':
          this.model.options.val = $(target).text();
          break;

        case 'edit-button price-after':
          this.model.options.val = $(target).text().substr(1);
          break;

        case 'edit-button comment':
          this.model.options.isComment = true;
          this.model.options.val = $(target).text() == '编辑' ? '' : $(target).text();
          break;
      }

      var popup = tp.popup.Manager.popup(options);
      popup.on('confirm', this.editPopup_confirmHandler, this);
    },
    editPopup_confirmHandler: function (popup) {
      var val = popup.$('input').val()
         ,target = popup.options.target
         ,ad_id = $(target).closest('tr').attr('id')
         ,product = _.findWhere(this.model.get('products'),{ad_id: ad_id});

      if(val){
        switch ($(target).attr('class')){
          case 'edit-button cpa-after':
            product = _.extend(product,{cpa_after: val});
            break;

          case 'edit-button price-after':
            product = _.extend(product,{quote_rmb_after: val});
            break;

          case 'edit-button comment':
            product = _.extend(product,{remark: val.trim()});
            break;
        }
      }
      this.render();

      if(!this.model.get('init')){
        this.model.save({
          products: this.model.get('products'),
          income: this.model.options.income_after_total,
          income_first: this.model.options.income_before_total
        },{patch:true});
      }
    },
    success_handler: function () {
      window.location ='#/invoice/';
    },
    invoiceButton_clickHandler: function (event) {
      var target = event.currentTarget;
      var start = this.model.get('start');
      var end = this.model.get('end');
      var ad_id = this.$('#ad_table tbody tr').eq(0).attr('id');
      var options = {
        title: target.title,
        id: ad_id,
        confirm: '确定',
        content: "page/stat/choose-ad.hbs",
        isRemote: true,
        start: start,
        end: end,
        fromInvoice: true
      };

      var popup = tp.popup.Manager.popup(options);
      popup.on('confirm', this.invoicePopup_confirmHandler, this);
    },
    invoicePopup_confirmHandler: function (popup) {
      var ids = ""
        , start = this.model.get('start')
        , end = this.model.get('end')
        , len = popup.$(':checked').length
        , self = this;

      if(len){
        popup.$(':checked').each(function (i) {
          if(i + 1 != len){
            ids += $(this).val() + ',';
          } else{
            ids += $(this).val();
          }
        });
        var newModel = new tp.model.InvoiceDetail({
          start:start,
          end:end,
          ids: ids
        });
        newModel.fetch({
          success: function (model,response) {
            var products = response.invoice.products;
            self.model.set('products',products);
            self.render();
            if(!self.model.get('init')){
              self.model.save({
                products:self.model.get("products"),
                income:self.model.options.income_after_total,
                income_first:self.model.options.income_before_total
              },{patch:true}); //如果是二次编辑，就直接save
            }
          }
        });
      }
    }
  });
}(Nervenet.createNameSpace('tp.page')));<|endoftext|>


<commit_before>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

exports.defineAutoTests = function() {
  describe('Device Information (window.device)', function () {
    it("should exist", function() {
      expect(window.device).toBeDefined();
    });

    it("should contain a platform specification that is a string", function() {
      expect(window.device.platform).toBeDefined();
      expect((new String(window.device.platform)).length > 0).toBe(true);
    });

    it("should contain a version specification that is a string", function() {
      expect(window.device.version).toBeDefined();
      expect((new String(window.device.version)).length > 0).toBe(true);
    });

    it("should contain a UUID specification that is a string or a number", function() {
      expect(window.device.uuid).toBeDefined();
      if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') {
        expect((new String(window.device.uuid)).length > 0).toBe(true);
      } else {
        expect(window.device.uuid > 0).toBe(true);
      }
    });

    it("should contain a cordova specification that is a string", function() {
      expect(window.device.cordova).toBeDefined();
      expect((new String(window.device.cordova)).length > 0).toBe(true);
    });

    it("should depend on the precense of cordova.version string", function() {
      expect(window.cordova.version).toBeDefined();
      expect((new String(window.cordova.version)).length > 0).toBe(true);
    });

    it("should contain device.cordova equal to cordova.version", function() {
      expect(window.device.cordova).toBe(window.cordova.version);
    });

    it("should contain a model specification that is a string", function() {
      expect(window.device.model).toBeDefined();
      expect((new String(window.device.model)).length > 0).toBe(true);
    });
  });
};

exports.defineManualTests = function(contentEl, createActionButton) {
  var logMessage = function (message, color) {
        var log = document.getElementById('info');
        var logLine = document.createElement('div');
        if (color) {
            logLine.style.color = color;
        }
        logLine.innerHTML = message;
        log.appendChild(logLine);
    }

    var clearLog = function () {
        var log = document.getElementById('info');
        log.innerHTML = '';
    }

    var device_tests = '
Press Dump Device button to get device information
' +
        '

' +
        'Expected result: Status box will get updated with device info. (i.e. platform, version, uuid, model, etc)';

    contentEl.innerHTML = '

' + device_tests;

    createActionButton('Dump device', function() {
      clearLog();
      logMessage(JSON.stringify(window.device, null, '\t'));
    }, "dump_device");
};
<commit_msg>[CB-7285] Add test for manufacturer property<commit_after>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

exports.defineAutoTests = function() {
  describe('Device Information (window.device)', function () {
    it("should exist", function() {
      expect(window.device).toBeDefined();
    });

    it("should contain a platform specification that is a string", function() {
      expect(window.device.platform).toBeDefined();
      expect((new String(window.device.platform)).length > 0).toBe(true);
    });

    it("should contain a version specification that is a string", function() {
      expect(window.device.version).toBeDefined();
      expect((new String(window.device.version)).length > 0).toBe(true);
    });

    it("should contain a UUID specification that is a string or a number", function() {
      expect(window.device.uuid).toBeDefined();
      if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') {
        expect((new String(window.device.uuid)).length > 0).toBe(true);
      } else {
        expect(window.device.uuid > 0).toBe(true);
      }
    });

    it("should contain a cordova specification that is a string", function() {
      expect(window.device.cordova).toBeDefined();
      expect((new String(window.device.cordova)).length > 0).toBe(true);
    });

    it("should depend on the presence of cordova.version string", function() {
      expect(window.cordova.version).toBeDefined();
      expect((new String(window.cordova.version)).length > 0).toBe(true);
    });

    it("should contain device.cordova equal to cordova.version", function() {
      expect(window.device.cordova).toBe(window.cordova.version);
    });

    it("should contain a model specification that is a string", function() {
      expect(window.device.model).toBeDefined();
      expect((new String(window.device.model)).length > 0).toBe(true);
    });

    it("should contain a manufacturer property that is a string", function() {
      expect(window.device.manufacturer).toBeDefined();
      expect((new String(window.device.manufacturer)).length > 0).toBe(true);
    });
  });
};

exports.defineManualTests = function(contentEl, createActionButton) {
  var logMessage = function (message, color) {
        var log = document.getElementById('info');
        var logLine = document.createElement('div');
        if (color) {
            logLine.style.color = color;
        }
        logLine.innerHTML = message;
        log.appendChild(logLine);
    }

    var clearLog = function () {
        var log = document.getElementById('info');
        log.innerHTML = '';
    }

    var device_tests = '
Press Dump Device button to get device information
' +
        '

' +
        'Expected result: Status box will get updated with device info. (i.e. platform, version, uuid, model, etc)';

    contentEl.innerHTML = '

' + device_tests;

    createActionButton('Dump device', function() {
      clearLog();
      logMessage(JSON.stringify(window.device, null, '\t'));
    }, "dump_device");
};
<|endoftext|>


<commit_before>/**
  Copyright 2010-2011 Ondrej Certik <ondrej@certik.cz>
  Copyright 2010-2011 Mateusz Paprocki <mattpap@gmail.com>
  Copyright 2011 Christian Iversen <ci@sikkerhed.org>

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation
  files (the "Software"), to deal in the Software without
  restriction, including without limitation the rights to use,
  copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  OTHER DEALINGS IN THE SOFTWARE.
**/

var tuple = __inherit(object, "tuple");

$PY.tuple = tuple;

tuple.PY$__init__ = function(seq) {
    if (arguments.length > 1) {
        throw py_builtins.TypeError("tuple() takes at most 1 argument (" + arguments.length + " given)");
    } else if (seq === undefined) {
        this.items = [];
    } else if (seq.PY$__class__ === list || seq.PY$__class__ === tuple) {
        this.items = seq.items.concat();
    } else {
        var that = this;
        this.items = [];
        iterate(seq, function(elm) {
                    if (typeof(elm) == 'number')
                        that.items.push(int(elm));
                    else if (typeof(elm) == 'string')
                        that.items.push(str(elm));
                    else
                        that.items.push(elm);
                });
    }
};

tuple.PY$__str__ = function () {
    var len = js(this.PY$__len__());
    if (len === 0) {
        return str("()");
    } else if (len === 1) {
        return str("(" + str(this.items[0]) + ",)");
    } else {
        var res = "(" + js(py_builtins.repr(this.items[0]));
        for (var i = 1; i < this.items.length; i++)  {
            res += ", " + js(py_builtins.repr(this.items[i]));
        }
        return res + ")";
    }
};

tuple.PY$__repr__ = tuple.PY$__str__;

tuple.PY$__eq__ = function (other) {
    if (other.PY$__class__ == this.PY$__class__) {
        if (js(py_builtins.len(this)) != js(py_builtins.len(other))) {
            return False;
        }
        var len = js(py_builtins.len(this));
        for (var i = 0; i < len; i++) {
            if (this.items[i].PY$__ne__(other.items[i]) == true) {
                return False;
            }
        }
        return True;
    } else {
        return False;
    }
};

tuple.PY$__cmp__ = function (other) {
    if (other.PY$__class__ !== this.PY$__class__) {
        if (object.PY$__gt__.call(this, other) == true) {
            return $c1;
        } else {
            if (object.PY$__lt__.call(this, other) == true) {
                return $cn1;
            } else {
                return $c0;
            }
        }
    } else {
        var count = 0;
        var res = $c0;
        try {
            var it = iter(other);
        } catch (exc) {
            if ($PY.isinstance(exc, py_builtins.TypeError)) {
                return $c1;
            } else {
                throw exc;
            }
        }

        while (true) {
            try {
                var elm = it.PY$next();
            } catch (exc) {
                if ($PY.isinstance(exc, py_builtins.StopIteration)) {
                    break;
                } else {
                    throw exc;
                }
            }
            if (count >= this.items.length) {
                res = $cn1;
                break;
            }
            var r = this.items[count].PY$__cmp__(elm);

            if (r.PY$__gt__($c0) == true) {
                res = $c1;
                break;
            } else if (r.PY$__lt__($c0) == true) {
                res = $cn1;
                break;
            }
            count++;
        }

        if (res == 0) {
            if (this.items.length > count) {
                return $c1;
            } else {
                return $c0;
            }
        } else {
            return res;
        }
    }
};

tuple.PY$__gt__ = function (other) {
    return this.PY$__cmp__(other).PY$__gt__($c0);
};

tuple.PY$__lt__ = function (other) {
    return this.PY$__cmp__(other).PY$__lt__($c0);
};

tuple.PY$__mul__ = function(num) {
    if ($PY.isinstance(num, int) == true) {
        var res = [];
        var count = num._js_();
        for (var i = 0; i < count; i++) {
            res = res.concat(this.items);
        }
        return this.PY$__class__(res);
    } else {
        throw py_builtins.NotImplementedError();
    }
};

tuple.PY$__add__ = function(other) {
    if (this.PY$__class__ == other.PY$__class__) {
        var res = this.items.concat([]);
        iterate(other, function(elm) {
                    res.push(elm);
                });
        return this.PY$__class__(res);
    } else {
        throw py_builtins.NotImplementedError();
    }
};

tuple._js_ = function () {
    var items = [];

    iterate(this, function(item) {
        items.push(js(item));
    });

    return items;
};

tuple.PY$__hash__ = function () {
    var value = 0x345678;
    var length = js(this.PY$__len__());

    for (var index in this.items) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ py_builtins.hash(this.items[index]);
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

tuple.PY$__len__ = function() {
    return int(this.items.length);
};

tuple.PY$__iter__ = function() {
    return iter(this.items);
};

tuple.PY$__contains__ = function(item) {
    for (var index in this.items) {
        if (this.items[index].PY$__eq__(item) == true) {
            return True;
        }
    }

    return False;
};

tuple.PY$__getitem__ = function(index) {
    if (typeof(index) === 'number') index = int(index);
    var seq;
    if ($PY.isinstance(index, slice) == true) {
        var s = index;
        var inds = js(s.PY$indices(py_builtins.len(this)));
        var start = inds[0];
        var stop = inds[1];
        var step = inds[2];
        seq = [];
        for (var i = start; i < stop; i += step) {
            seq.push(this.PY$__getitem__(i));
        }
        return this.PY$__class__(seq);
    } else {
        if ($PY.isinstance(index, int) == false) {
            index = int(index);
        }

        if (js(index.PY$__ge__($c0)) && js(index.PY$__lt__(py_builtins.len(this)))) {
            return this.items[index.PY$__int__()];
        } else if (js(index.PY$__lt__($c0)) && js(index.PY$__ge__(py_builtins.len(this).PY$__neg__()))) {
            return this.items[index.PY$__add__(py_builtins.len(this)).PY$__int__()];
        } else {
            throw py_builtins.IndexError("list index out of range");
        }
    }
};

tuple.PY$__setitem__ = function() {
    throw py_builtins.TypeError("'tuple' object doesn't support item assignment");
};

tuple.PY$__delitem__ = function() {
    throw py_builtins.TypeError("'tuple' object doesn't support item deletion");
};

tuple.PY$count = function(value) {
    var count = 0;

    for (var index in this.items) {
        if (this.items[index].PY$__eq__(value) == true) {
            count += 1;
        }
    }

    return count;
};

tuple.PY$index = function(value, start, end) {
    if (start === undefined) {
        start = 0;
    }

    for (var i = start; (end === undefined) || (start < end); i++) {
        var _value = this.items[i];

        if (_value === undefined) {
            break;
        }

        if (_value.PY$__eq__(value) == true) {
            return int(i);
        }
    }

    throw py_builtins.ValueError(this.PY$__class__.PY$__name__ + ".index(x): x not in list");
};
<commit_msg> * Fixed a bug where one path in tuple.PY$__str__ would return a javascript string instead of a pythonic string<commit_after>/**
  Copyright 2010-2011 Ondrej Certik <ondrej@certik.cz>
  Copyright 2010-2011 Mateusz Paprocki <mattpap@gmail.com>
  Copyright 2011 Christian Iversen <ci@sikkerhed.org>

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation
  files (the "Software"), to deal in the Software without
  restriction, including without limitation the rights to use,
  copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  OTHER DEALINGS IN THE SOFTWARE.
**/

var tuple = __inherit(object, "tuple");

$PY.tuple = tuple;

tuple.PY$__init__ = function(seq) {
    if (arguments.length > 1) {
        throw py_builtins.TypeError("tuple() takes at most 1 argument (" + arguments.length + " given)");
    } else if (seq === undefined) {
        this.items = [];
    } else if (seq.PY$__class__ === list || seq.PY$__class__ === tuple) {
        this.items = seq.items.concat();
    } else {
        var that = this;
        this.items = [];
        iterate(seq, function(elm) {
                    if (typeof(elm) == 'number')
                        that.items.push(int(elm));
                    else if (typeof(elm) == 'string')
                        that.items.push(str(elm));
                    else
                        that.items.push(elm);
                });
    }
};

tuple.PY$__str__ = function () {
    var len = js(this.PY$__len__());
    if (len === 0) {
        return str("()");
    } else if (len === 1) {
        return str("(" + str(this.items[0]) + ",)");
    } else {
        var res = "(" + js(py_builtins.repr(this.items[0]));
        for (var i = 1; i < this.items.length; i++)  {
            res += ", " + js(py_builtins.repr(this.items[i]));
        }
        return str(res + ")");
    }
};

tuple.PY$__repr__ = tuple.PY$__str__;

tuple.PY$__eq__ = function (other) {
    if (other.PY$__class__ == this.PY$__class__) {
        if (js(py_builtins.len(this)) != js(py_builtins.len(other))) {
            return False;
        }
        var len = js(py_builtins.len(this));
        for (var i = 0; i < len; i++) {
            if (this.items[i].PY$__ne__(other.items[i]) == true) {
                return False;
            }
        }
        return True;
    } else {
        return False;
    }
};

tuple.PY$__cmp__ = function (other) {
    if (other.PY$__class__ !== this.PY$__class__) {
        if (object.PY$__gt__.call(this, other) == true) {
            return $c1;
        } else {
            if (object.PY$__lt__.call(this, other) == true) {
                return $cn1;
            } else {
                return $c0;
            }
        }
    } else {
        var count = 0;
        var res = $c0;
        try {
            var it = iter(other);
        } catch (exc) {
            if ($PY.isinstance(exc, py_builtins.TypeError)) {
                return $c1;
            } else {
                throw exc;
            }
        }

        while (true) {
            try {
                var elm = it.PY$next();
            } catch (exc) {
                if ($PY.isinstance(exc, py_builtins.StopIteration)) {
                    break;
                } else {
                    throw exc;
                }
            }
            if (count >= this.items.length) {
                res = $cn1;
                break;
            }
            var r = this.items[count].PY$__cmp__(elm);

            if (r.PY$__gt__($c0) == true) {
                res = $c1;
                break;
            } else if (r.PY$__lt__($c0) == true) {
                res = $cn1;
                break;
            }
            count++;
        }

        if (res == 0) {
            if (this.items.length > count) {
                return $c1;
            } else {
                return $c0;
            }
        } else {
            return res;
        }
    }
};

tuple.PY$__gt__ = function (other) {
    return this.PY$__cmp__(other).PY$__gt__($c0);
};

tuple.PY$__lt__ = function (other) {
    return this.PY$__cmp__(other).PY$__lt__($c0);
};

tuple.PY$__mul__ = function(num) {
    if ($PY.isinstance(num, int) == true) {
        var res = [];
        var count = num._js_();
        for (var i = 0; i < count; i++) {
            res = res.concat(this.items);
        }
        return this.PY$__class__(res);
    } else {
        throw py_builtins.NotImplementedError();
    }
};

tuple.PY$__add__ = function(other) {
    if (this.PY$__class__ == other.PY$__class__) {
        var res = this.items.concat([]);
        iterate(other, function(elm) {
                    res.push(elm);
                });
        return this.PY$__class__(res);
    } else {
        throw py_builtins.NotImplementedError();
    }
};

tuple._js_ = function () {
    var items = [];

    iterate(this, function(item) {
        items.push(js(item));
    });

    return items;
};

tuple.PY$__hash__ = function () {
    var value = 0x345678;
    var length = js(this.PY$__len__());

    for (var index in this.items) {
        value = ((1000003*value) & 0xFFFFFFFF) ^ py_builtins.hash(this.items[index]);
        value = value ^ length;
    }

    if (value == -1) {
        value = -2;
    }

    return value;
};

tuple.PY$__len__ = function() {
    return int(this.items.length);
};

tuple.PY$__iter__ = function() {
    return iter(this.items);
};

tuple.PY$__contains__ = function(item) {
    for (var index in this.items) {
        if (this.items[index].PY$__eq__(item) == true) {
            return True;
        }
    }

    return False;
};

tuple.PY$__getitem__ = function(index) {
    if (typeof(index) === 'number') index = int(index);
    var seq;
    if ($PY.isinstance(index, slice) == true) {
        var s = index;
        var inds = js(s.PY$indices(py_builtins.len(this)));
        var start = inds[0];
        var stop = inds[1];
        var step = inds[2];
        seq = [];
        for (var i = start; i < stop; i += step) {
            seq.push(this.PY$__getitem__(i));
        }
        return this.PY$__class__(seq);
    } else {
        if ($PY.isinstance(index, int) == false) {
            index = int(index);
        }

        if (js(index.PY$__ge__($c0)) && js(index.PY$__lt__(py_builtins.len(this)))) {
            return this.items[index.PY$__int__()];
        } else if (js(index.PY$__lt__($c0)) && js(index.PY$__ge__(py_builtins.len(this).PY$__neg__()))) {
            return this.items[index.PY$__add__(py_builtins.len(this)).PY$__int__()];
        } else {
            throw py_builtins.IndexError("list index out of range");
        }
    }
};

tuple.PY$__setitem__ = function() {
    throw py_builtins.TypeError("'tuple' object doesn't support item assignment");
};

tuple.PY$__delitem__ = function() {
    throw py_builtins.TypeError("'tuple' object doesn't support item deletion");
};

tuple.PY$count = function(value) {
    var count = 0;

    for (var index in this.items) {
        if (this.items[index].PY$__eq__(value) == true) {
            count += 1;
        }
    }

    return count;
};

tuple.PY$index = function(value, start, end) {
    if (start === undefined) {
        start = 0;
    }

    for (var i = start; (end === undefined) || (start < end); i++) {
        var _value = this.items[i];

        if (_value === undefined) {
            break;
        }

        if (_value.PY$__eq__(value) == true) {
            return int(i);
        }
    }

    throw py_builtins.ValueError(this.PY$__class__.PY$__name__ + ".index(x): x not in list");
};
<|endoftext|>


<commit_before>// Copyright 2017, University of Colorado Boulder

/**
 * phetioInherit tests
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var SimIFrameAPIIO = require( 'PHET_IO/types/SimIFrameAPIIO' );

  QUnit.module( 'phetioInherit' );

  // These tests run in brand=phet-io
  QUnit.test( 'IO types', function( assert ) {
    assert.ok( !!SimIFrameAPIIO.toStateObject, 'IO types should inherit static properties' );
  } );
} );<commit_msg>Renamed SimIFrameAPI => phetioCommandProcessor, see https://github.com/phetsims/phet-io/issues/1305<commit_after>// Copyright 2017, University of Colorado Boulder

/**
 * phetioInherit tests
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var phetioCommandProcessorIO = require( 'PHET_IO/types/phetioCommandProcessorIO' );

  QUnit.module( 'phetioInherit' );

  // These tests run in brand=phet-io
  QUnit.test( 'IO types', function( assert ) {
    assert.ok( !!phetioCommandProcessorIO.toStateObject, 'IO types should inherit static properties' );
  } );
} );<|endoftext|>