<commit_before>/*jslint browser: true, for: true, node: true */
/*global window */

/*!

   hlsjs engine plugin for Flowplayer HTML5

   Copyright (c) 2015-2016, Flowplayer Oy

   Released under the MIT License:
   http://www.opensource.org/licenses/mit-license.php

   Includes hls.js
   Copyright (c) 2015 Dailymotion (http://www.dailymotion.com)
   https://github.com/dailymotion/hls.js/blob/master/LICENSE

   requires:
   - Flowplayer HTML5 version 6.x or greater
   - hls.js https://github.com/dailymotion/hls.js
   revision: $GIT_ID$

*/

(function (flowplayer, Hls) {
    "use strict";
    var engineName = "hlsjs",
        hlsconf,
        common = flowplayer.common,
        extend = flowplayer.extend,
        support = flowplayer.support,
        version = flowplayer.version,

        isHlsType = function (typ) {
            return typ.toLowerCase().indexOf("mpegurl") > -1;
        },

        engineImpl = function hlsjsEngine(player, root) {
            var bean = flowplayer.bean,
                videoTag,
                hls,
                recover,

                bc,
                has_bg,
                posterHack = function () {
                    // abuse timeupdate to re-instate poster
                    var posterClass = "is-poster",
                        etype = "progress." + engineName;

                    player.one(etype, function () {
                        common.addClass(root, posterClass);
                        player.poster = true;
                        player.one(etype, function () {
                            common.removeClass(root, posterClass);
                            player.poster = false;
                        });
                    });
                },

                getStartLevelConf = function () {
                    var value = hlsconf.startLevel;

                    switch (value) {
                    case "auto":
                        value = -1;
                        break;
                    case "firstLevel":
                        value = undefined;
                        break;
                    }
                    return value;
                },

                qActive = "active",
                removeAllQualityClasses = function () {
                    var qualities = player.qualities;

                    if (!qualities || !qualities.length) {
                        return;
                    }
                    qualities.forEach(function (quality) {
                        common.removeClass(root, 'quality-' + quality);
                    });
                },
                qClean = function () {
                    delete player.hlsQualities;
                    player.qualities = [];
                    removeAllQualityClasses();
                    common.find(".fp-quality-selector li", root).forEach(bean.off);
                    common.find(".fp-quality-selector", root).forEach(common.removeNode);
                },
                qIndex = function () {
                    return player.hlsQualities[player.qualities.indexOf(player.quality) + 1];
                },
                initQualitySelection = function (hlsQualitiesConf, data) {
                    var levels = data.levels,
                        levelIndex = 0,
                        selector;

                    player.hlsQualities = [];
                    levels.forEach(function (level) {
                        if ((hlsQualitiesConf === true || hlsQualitiesConf.indexOf(levelIndex) > -1) &&
                                level.videoCodec &&
                                window.MediaSource.isTypeSupported('video/mp4;codecs=' + level.videoCodec)) {
                            // do not check audioCodec,
                            // as e.g. HE_AAC is decoded as LC_AAC by hls.js on Android
                            player.hlsQualities.push(levelIndex);
                        }
                        levelIndex += 1;
                    });
                    if (player.hlsQualities.length < 2) {
                        qClean();
                        return;
                    }

                    player.qualities = [];
                    player.hlsQualities.forEach(function (levelIndex) {
                        var level = levels[levelIndex],
                            width = level.width,
                            height = level.height,
                            label = (width && height)
                                ? Math.min(width, height) + "p"
                                : "Level " + (levelIndex + 1);

                        player.qualities.push(label);
                    });

                    selector = common.createElement("ul", {
                        "class": "fp-quality-selector"
                    });
                    common.find(".fp-ui", root)[0].appendChild(selector);

                    player.hlsQualities.unshift(-1);

                    if (!player.quality || player.qualities.indexOf(player.quality) < 0) {
                        hls.startLevel = getStartLevelConf();
                        player.quality = "abr";
                    } else {
                        hls.startLevel = qIndex();
                    }

                    selector.appendChild(common.createElement("li", {
                        "data-quality": "abr"
                    }, "Auto"));
                    player.qualities.forEach(function (q) {
                        selector.appendChild(common.createElement("li", {
                            "data-quality": q
                        }, q));
                    });

                    common.addClass(root, "quality-" + player.quality);

                    bean.on(root, "click", ".fp-quality-selector li", function (e) {
                        var choice = e.currentTarget,
                            selectors,
                            active,
                            i;

                        if (common.hasClass(choice, qActive)) {
                            return;
                        }

                        selectors = common.find(".fp-quality-selector li", root);

                        for (i = 0; i < selectors.length; i += 1) {
                            active = selectors[i] === choice;
                            if (active) {
                                player.quality = i > 0
                                    ? player.qualities[i - 1]
                                    : "abr";
                                if (hlsconf.smoothSwitching) {
                                    hls.nextLevel = qIndex();
                                } else {
                                    hls.currentLevel = qIndex();
                                }
                                player.resume();
                                common.addClass(choice, qActive);
                            }
                            common.toggleClass(selectors[i], qActive, active);
                        }
                        removeAllQualityClasses();
                        common.addClass(root, "quality-" + player.quality);
                    });
                },

                engine = {
                    engineName: engineName,

                    pick: function (sources) {
                        var i,
                            source;

                        for (i = 0; i < sources.length; i += 1) {
                            source = sources[i];
                            if (isHlsType(source.type)
                                    && (!source.engine || source.engine === engineName)) {
                                if (typeof source.src === 'string') {
                                    source.src = common.createAbsoluteUrl(source.src);
                                }
                                return source;
                            }
                        }
                    },

                    load: function (video) {
                        var init = !hls,
                            conf = player.conf,
                            hlsQualitiesConf = conf.clip.hlsQualities || conf.hlsQualities,
                            hlsClientConf = extend({}, hlsconf),
                            hlsParams = [
                                "anamorphic", "autoLevelCapping", "recover",
                                "smoothSwitching", "startLevel", "strict"
                            ],
                            hlsEvents = [
                                "MEDIA_ATTACHING", "MEDIA_ATTACHED", "MEDIA_DETACHING", "MEDIA_DETACHED",
                                "MANIFEST_LOADING", "MANIFEST_LOADED", "MANIFEST_PARSED",
                                "LEVEL_LOADING", "LEVEL_LOADED", "LEVEL_UPDATED", "LEVEL_PTS_UPDATED", "LEVEL_SWITCH",
                                "KEY_LOADING", "KEY_LOADED",
                                "FRAG_LOADING", "FRAG_LOAD_PROGRESS", "FRAG_LOADED",
                                "FRAG_PARSING_INIT_SEGMENT", "FRAG_PARSING_METADATA", "FRAG_PARSING_DATA", "FRAG_PARSED",
                                "FRAG_BUFFERED", "FRAG_CHANGED",
                                "FPS_DROP",
                                "DESTROYING",
                                "ERROR"
                            ];

                        if (init) {
                            common.removeNode(common.findDirect("video", root)[0]
                                    || common.find(".fp-player > video", root)[0]);
                            videoTag = common.createElement("video", {
                                className: "fp-engine " + engineName + "-engine",
                                autoplay: conf.autoplay
                                    ? "autoplay"
                                    : false
                            });
                            videoTag.setAttribute("x-webkit-airplay", "allow");

                        } else {
                            hls.destroy();
                        }

                        bean.on(videoTag, "play", function () {
                            player.trigger('resume', [player]);
                        });
                        bean.on(videoTag, "pause", function () {
                            player.trigger('pause', [player]);
                        });
                        bean.on(videoTag, "timeupdate", function () {
                            player.trigger('progress', [player, videoTag.currentTime]);
                        });
                        bean.on(videoTag, "loadeddata", function () {
                            video = extend(video, {
                                duration: videoTag.duration,
                                seekable: videoTag.seekable.end(null),
                                width: videoTag.videoWidth,
                                height: videoTag.videoHeight,
                                url: videoTag.currentSrc
                            });
                            player.trigger('ready', [player, video]);

                            var quality = player.quality,
                                abr = quality === "abr",
                                selectorIndex;

                            if (quality) {
                                if (!abr) {
                                    hls.currentLevel = hls.startLevel;
                                }
                                selectorIndex = abr
                                    ? 0
                                    : player.qualities.indexOf(quality) + 1;
                                common.addClass(common.find(".fp-quality-selector li", root)[selectorIndex], qActive);
                            }
                        });
                        bean.on(videoTag, "seeked", function () {
                            player.trigger('seek', [player, videoTag.currentTime]);
                        });
                        bean.on(videoTag, "progress", function (e) {
                            var ct = videoTag.currentTime,
                                buffer = 0,
                                buffend,
                                buffered,
                                last,
                                i;

                            try {
                                buffered = videoTag.buffered;
                                last = buffered.length - 1;
                                buffend = 0;
                                // cycle through time ranges to obtain buffer
                                // nearest current time
                                if (ct) {
                                    for (i = last; i > -1; i -= 1) {
                                        buffend = buffered.end(i);

                                        if (buffend >= ct) {
                                            buffer = buffend;
                                        }
                                    }
                                }
                            } catch (ignore) {}

                            video.buffer = buffer;
                            player.trigger('buffer', [player, e]);
                        });
                        bean.on(videoTag, "ended", function () {
                            player.trigger('finish', [player]);
                        });
                        bean.on(videoTag, "volumechange", function () {
                            player.trigger('volume', [player, videoTag.volume]);
                        });

                        hlsParams.forEach(function (key) {
                            delete hlsClientConf[key];
                        });
                        hls = new Hls(hlsClientConf);
                        player.engine[engineName] = hls;

                        hlsParams.forEach(function (key) {
                            var value = hlsconf[key];

                            switch (key) {
                            case "autoLevelCapping":
                                if (value === false) {
                                    value = -1;
                                }
                                break;
                            case "recover":
                                recover = hlsconf.strict
                                    ? 0
                                    : value;
                                break;
                            case "startLevel":
                                value = (player.hlsQualities && player.quality)
                                    ? qIndex()
                                    : getStartLevelConf();
                                break;
                            }

                            if (key !== "strict" && key !== "recover" && value !== undefined) {
                                hls[key] = value;
                            }
                        });

                        qClean();

                        hlsEvents.forEach(function (e) {
                            hls.on(Hls.Events[e], function (etype, data) {
                                var fperr,
                                    errobj = {};

                                switch (e) {
                                case "MANIFEST_PARSED":
                                    if (support.inlineVideo && hlsQualitiesConf) {
                                        initQualitySelection(hlsQualitiesConf, data);
                                    } else {
                                        delete player.quality;
                                    }
                                    break;

                                case "ERROR":
                                    if (data.fatal || hlsconf.strict > 0) {
                                        switch (data.type) {
                                        case Hls.ErrorTypes.NETWORK_ERROR:
                                            if (recover) {
                                                hls.startLoad();
                                                if (recover > 0) {
                                                    recover -= 1;
                                                }
                                            } else if (data.frag && data.frag.url) {
                                                errobj.url = data.frag.url;
                                                fperr = 2;
                                            } else {
                                                fperr = 4;
                                            }
                                            break;
                                        case Hls.ErrorTypes.MEDIA_ERROR:
                                            if (recover) {
                                                hls.recoverMediaError();
                                                if (recover > 0) {
                                                    recover -= 1;
                                                }
                                            } else {
                                                fperr = 3;
                                            }
                                            break;
                                        default:
                                            fperr = 5;
                                        }

                                        if (fperr !== undefined) {
                                            errobj.code = fperr;
                                            if (fperr > 2) {
                                                errobj.video = extend(video, {
                                                    src: video.src,
                                                    url: data.url || video.src
                                                });
                                            }
                                            player.trigger('error', [player, errobj]);
                                            return;
                                        }
                                    }
                                    // log non fatals?
                                    break;
                                }

                                player.trigger(etype, [player, data]);
                            });
                        });

                        if (init) {
                            common.prepend(common.find(".fp-player", root)[0], videoTag);
                        }

                        hls.loadSource(video.src);
                        hls.attachMedia(videoTag);

                        if (videoTag.paused && (video.autoplay || conf.autoplay)) {
                            videoTag.play();
                        }
                    },

                    resume: function () {
                        videoTag.play();
                    },

                    pause: function () {
                        videoTag.pause();
                    },

                    seek: function (time) {
                        videoTag.currentTime = time;
                    },

                    volume: function (level) {
                        if (videoTag) {
                            videoTag.volume = level;
                        }
                    },

                    speed: function (val) {
                        videoTag.playbackRate = val;
                        player.trigger('speed', [player, val]);
                    },

                    unload: function () {
                        // hls conditional probably not needed once
                        // https://github.com/flowplayer/flowplayer/commit/871ff783a8f23aa603e1120f4319d4a892125b0a
                        // is released
                        if (hls) {
                            hls.destroy();
                            hls = 0;
                            bean.off(videoTag);
                            common.removeNode(videoTag);
                            videoTag = 0;
                            qClean();
                        }
                    }
                };

            // pre 6.0.4: no boolean api.conf.poster and no poster with autoplay
            if (/^6\.0\.[0-3]$/.test(version) &&
                    !player.conf.splash && !player.conf.poster && !player.conf.autoplay) {
                bc = common.css(root, 'backgroundColor');
                // spaces in rgba arg mandatory for recognition
                has_bg = common.css(root, 'backgroundImage') !== "none" ||
                        (bc && bc !== "rgba(0, 0, 0, 0)" && bc !== "transparent");
                if (has_bg) {
                    player.conf.poster = true;
                }
            }
            if (player.conf.poster) {
                // when engine is loaded or player stopped
                // the engine is too late to the party:
                // poster is already removed and api.poster is false
                // poster state must be set again
                player.on("ready." + engineName + " stop." + engineName, posterHack);
            }

            return engine;
        };

    if (Hls.isSupported() && version.indexOf("5.") !== 0) {
        // only load engine if it can be used
        engineImpl.engineName = engineName; // must be exposed
        engineImpl.canPlay = function (type, conf) {
            var b = support.browser,
                wn = window.navigator,
                IE11 = wn.userAgent.indexOf("Trident/7") > -1;

            if (conf[engineName] === false || conf.clip[engineName] === false) {
                // engine disabled for player or clip
                return false;
            }

            // merge hlsjs clip config at earliest opportunity
            hlsconf = extend({
                smoothSwitching: true,
                recover: 0
            }, flowplayer.conf[engineName], conf[engineName], conf.clip[engineName]);

            if (isHlsType(type)) {
                // allow all browsers for hlsjs debugging
                if (hlsconf.debug) {
                    return true;
                }
                // https://bugzilla.mozilla.org/show_bug.cgi?id=1244294
                if (hlsconf.anamorphic &&
                        wn.platform.indexOf("Win") === 0 && b.mozilla && b.version.indexOf("44.") === 0) {
                    return false;
                }

                // https://github.com/dailymotion/hls.js/issues/9
                return IE11 || !b.safari;
            }
            return false;
        };

        // put on top of engine stack
        // so hlsjs is tested before html5 video hls and flash hls
        flowplayer.engines.unshift(engineImpl);

        flowplayer(function (api) {
            // to take precedence over VOD quality selector
            // hlsQualities must be configure at player or global level
            var hlsQualities = api.conf.hlsQualities || flowplayer.conf.hlsQualities;
            if (hlsQualities) {
                api.pluginQualitySelectorEnabled = engineImpl.canPlay("application/x-mpegurl", api.conf);
            }
        });

    }

}.apply(null, (typeof module === 'object' && module.exports)
    ? [require('flowplayer'), require('hls.js')]
    : [window.flowplayer, window.Hls]));
<commit_msg>Also remove quality-abr state class on quality classes refresh<commit_after>/*jslint browser: true, for: true, node: true */
/*global window */

/*!

   hlsjs engine plugin for Flowplayer HTML5

   Copyright (c) 2015-2016, Flowplayer Oy

   Released under the MIT License:
   http://www.opensource.org/licenses/mit-license.php

   Includes hls.js
   Copyright (c) 2015 Dailymotion (http://www.dailymotion.com)
   https://github.com/dailymotion/hls.js/blob/master/LICENSE

   requires:
   - Flowplayer HTML5 version 6.x or greater
   - hls.js https://github.com/dailymotion/hls.js
   revision: $GIT_ID$

*/

(function (flowplayer, Hls) {
    "use strict";
    var engineName = "hlsjs",
        hlsconf,
        common = flowplayer.common,
        extend = flowplayer.extend,
        support = flowplayer.support,
        version = flowplayer.version,

        isHlsType = function (typ) {
            return typ.toLowerCase().indexOf("mpegurl") > -1;
        },

        engineImpl = function hlsjsEngine(player, root) {
            var bean = flowplayer.bean,
                videoTag,
                hls,
                recover,

                bc,
                has_bg,
                posterHack = function () {
                    // abuse timeupdate to re-instate poster
                    var posterClass = "is-poster",
                        etype = "progress." + engineName;

                    player.one(etype, function () {
                        common.addClass(root, posterClass);
                        player.poster = true;
                        player.one(etype, function () {
                            common.removeClass(root, posterClass);
                            player.poster = false;
                        });
                    });
                },

                getStartLevelConf = function () {
                    var value = hlsconf.startLevel;

                    switch (value) {
                    case "auto":
                        value = -1;
                        break;
                    case "firstLevel":
                        value = undefined;
                        break;
                    }
                    return value;
                },

                qActive = "active",
                removeAllQualityClasses = function () {
                    var qualities = player.qualities;

                    if (!qualities || !qualities.length) {
                        return;
                    }
                    common.removeClass(root, "quality-abr");
                    qualities.forEach(function (quality) {
                        common.removeClass(root, "quality-" + quality);
                    });
                },
                qClean = function () {
                    delete player.hlsQualities;
                    player.qualities = [];
                    removeAllQualityClasses();
                    common.find(".fp-quality-selector li", root).forEach(bean.off);
                    common.find(".fp-quality-selector", root).forEach(common.removeNode);
                },
                qIndex = function () {
                    return player.hlsQualities[player.qualities.indexOf(player.quality) + 1];
                },
                initQualitySelection = function (hlsQualitiesConf, data) {
                    var levels = data.levels,
                        levelIndex = 0,
                        selector;

                    player.hlsQualities = [];
                    levels.forEach(function (level) {
                        if ((hlsQualitiesConf === true || hlsQualitiesConf.indexOf(levelIndex) > -1) &&
                                level.videoCodec &&
                                window.MediaSource.isTypeSupported('video/mp4;codecs=' + level.videoCodec)) {
                            // do not check audioCodec,
                            // as e.g. HE_AAC is decoded as LC_AAC by hls.js on Android
                            player.hlsQualities.push(levelIndex);
                        }
                        levelIndex += 1;
                    });
                    if (player.hlsQualities.length < 2) {
                        qClean();
                        return;
                    }

                    player.qualities = [];
                    player.hlsQualities.forEach(function (levelIndex) {
                        var level = levels[levelIndex],
                            width = level.width,
                            height = level.height,
                            label = (width && height)
                                ? Math.min(width, height) + "p"
                                : "Level " + (levelIndex + 1);

                        player.qualities.push(label);
                    });

                    selector = common.createElement("ul", {
                        "class": "fp-quality-selector"
                    });
                    common.find(".fp-ui", root)[0].appendChild(selector);

                    player.hlsQualities.unshift(-1);

                    if (!player.quality || player.qualities.indexOf(player.quality) < 0) {
                        hls.startLevel = getStartLevelConf();
                        player.quality = "abr";
                    } else {
                        hls.startLevel = qIndex();
                    }

                    selector.appendChild(common.createElement("li", {
                        "data-quality": "abr"
                    }, "Auto"));
                    player.qualities.forEach(function (q) {
                        selector.appendChild(common.createElement("li", {
                            "data-quality": q
                        }, q));
                    });

                    common.addClass(root, "quality-" + player.quality);

                    bean.on(root, "click", ".fp-quality-selector li", function (e) {
                        var choice = e.currentTarget,
                            selectors,
                            active,
                            i;

                        if (common.hasClass(choice, qActive)) {
                            return;
                        }

                        selectors = common.find(".fp-quality-selector li", root);

                        for (i = 0; i < selectors.length; i += 1) {
                            active = selectors[i] === choice;
                            if (active) {
                                player.quality = i > 0
                                    ? player.qualities[i - 1]
                                    : "abr";
                                if (hlsconf.smoothSwitching) {
                                    hls.nextLevel = qIndex();
                                } else {
                                    hls.currentLevel = qIndex();
                                }
                                player.resume();
                                common.addClass(choice, qActive);
                            }
                            common.toggleClass(selectors[i], qActive, active);
                        }
                        removeAllQualityClasses();
                        common.addClass(root, "quality-" + player.quality);
                    });
                },

                engine = {
                    engineName: engineName,

                    pick: function (sources) {
                        var i,
                            source;

                        for (i = 0; i < sources.length; i += 1) {
                            source = sources[i];
                            if (isHlsType(source.type)
                                    && (!source.engine || source.engine === engineName)) {
                                if (typeof source.src === 'string') {
                                    source.src = common.createAbsoluteUrl(source.src);
                                }
                                return source;
                            }
                        }
                    },

                    load: function (video) {
                        var init = !hls,
                            conf = player.conf,
                            hlsQualitiesConf = conf.clip.hlsQualities || conf.hlsQualities,
                            hlsClientConf = extend({}, hlsconf),
                            hlsParams = [
                                "anamorphic", "autoLevelCapping", "recover",
                                "smoothSwitching", "startLevel", "strict"
                            ],
                            hlsEvents = [
                                "MEDIA_ATTACHING", "MEDIA_ATTACHED", "MEDIA_DETACHING", "MEDIA_DETACHED",
                                "MANIFEST_LOADING", "MANIFEST_LOADED", "MANIFEST_PARSED",
                                "LEVEL_LOADING", "LEVEL_LOADED", "LEVEL_UPDATED", "LEVEL_PTS_UPDATED", "LEVEL_SWITCH",
                                "KEY_LOADING", "KEY_LOADED",
                                "FRAG_LOADING", "FRAG_LOAD_PROGRESS", "FRAG_LOADED",
                                "FRAG_PARSING_INIT_SEGMENT", "FRAG_PARSING_METADATA", "FRAG_PARSING_DATA", "FRAG_PARSED",
                                "FRAG_BUFFERED", "FRAG_CHANGED",
                                "FPS_DROP",
                                "DESTROYING",
                                "ERROR"
                            ];

                        if (init) {
                            common.removeNode(common.findDirect("video", root)[0]
                                    || common.find(".fp-player > video", root)[0]);
                            videoTag = common.createElement("video", {
                                className: "fp-engine " + engineName + "-engine",
                                autoplay: conf.autoplay
                                    ? "autoplay"
                                    : false
                            });
                            videoTag.setAttribute("x-webkit-airplay", "allow");

                        } else {
                            hls.destroy();
                        }

                        bean.on(videoTag, "play", function () {
                            player.trigger('resume', [player]);
                        });
                        bean.on(videoTag, "pause", function () {
                            player.trigger('pause', [player]);
                        });
                        bean.on(videoTag, "timeupdate", function () {
                            player.trigger('progress', [player, videoTag.currentTime]);
                        });
                        bean.on(videoTag, "loadeddata", function () {
                            video = extend(video, {
                                duration: videoTag.duration,
                                seekable: videoTag.seekable.end(null),
                                width: videoTag.videoWidth,
                                height: videoTag.videoHeight,
                                url: videoTag.currentSrc
                            });
                            player.trigger('ready', [player, video]);

                            var quality = player.quality,
                                abr = quality === "abr",
                                selectorIndex;

                            if (quality) {
                                if (!abr) {
                                    hls.currentLevel = hls.startLevel;
                                }
                                selectorIndex = abr
                                    ? 0
                                    : player.qualities.indexOf(quality) + 1;
                                common.addClass(common.find(".fp-quality-selector li", root)[selectorIndex], qActive);
                            }
                        });
                        bean.on(videoTag, "seeked", function () {
                            player.trigger('seek', [player, videoTag.currentTime]);
                        });
                        bean.on(videoTag, "progress", function (e) {
                            var ct = videoTag.currentTime,
                                buffer = 0,
                                buffend,
                                buffered,
                                last,
                                i;

                            try {
                                buffered = videoTag.buffered;
                                last = buffered.length - 1;
                                buffend = 0;
                                // cycle through time ranges to obtain buffer
                                // nearest current time
                                if (ct) {
                                    for (i = last; i > -1; i -= 1) {
                                        buffend = buffered.end(i);

                                        if (buffend >= ct) {
                                            buffer = buffend;
                                        }
                                    }
                                }
                            } catch (ignore) {}

                            video.buffer = buffer;
                            player.trigger('buffer', [player, e]);
                        });
                        bean.on(videoTag, "ended", function () {
                            player.trigger('finish', [player]);
                        });
                        bean.on(videoTag, "volumechange", function () {
                            player.trigger('volume', [player, videoTag.volume]);
                        });

                        hlsParams.forEach(function (key) {
                            delete hlsClientConf[key];
                        });
                        hls = new Hls(hlsClientConf);
                        player.engine[engineName] = hls;

                        hlsParams.forEach(function (key) {
                            var value = hlsconf[key];

                            switch (key) {
                            case "autoLevelCapping":
                                if (value === false) {
                                    value = -1;
                                }
                                break;
                            case "recover":
                                recover = hlsconf.strict
                                    ? 0
                                    : value;
                                break;
                            case "startLevel":
                                value = (player.hlsQualities && player.quality)
                                    ? qIndex()
                                    : getStartLevelConf();
                                break;
                            }

                            if (key !== "strict" && key !== "recover" && value !== undefined) {
                                hls[key] = value;
                            }
                        });

                        qClean();

                        hlsEvents.forEach(function (e) {
                            hls.on(Hls.Events[e], function (etype, data) {
                                var fperr,
                                    errobj = {};

                                switch (e) {
                                case "MANIFEST_PARSED":
                                    if (support.inlineVideo && hlsQualitiesConf) {
                                        initQualitySelection(hlsQualitiesConf, data);
                                    } else {
                                        delete player.quality;
                                    }
                                    break;

                                case "ERROR":
                                    if (data.fatal || hlsconf.strict > 0) {
                                        switch (data.type) {
                                        case Hls.ErrorTypes.NETWORK_ERROR:
                                            if (recover) {
                                                hls.startLoad();
                                                if (recover > 0) {
                                                    recover -= 1;
                                                }
                                            } else if (data.frag && data.frag.url) {
                                                errobj.url = data.frag.url;
                                                fperr = 2;
                                            } else {
                                                fperr = 4;
                                            }
                                            break;
                                        case Hls.ErrorTypes.MEDIA_ERROR:
                                            if (recover) {
                                                hls.recoverMediaError();
                                                if (recover > 0) {
                                                    recover -= 1;
                                                }
                                            } else {
                                                fperr = 3;
                                            }
                                            break;
                                        default:
                                            fperr = 5;
                                        }

                                        if (fperr !== undefined) {
                                            errobj.code = fperr;
                                            if (fperr > 2) {
                                                errobj.video = extend(video, {
                                                    src: video.src,
                                                    url: data.url || video.src
                                                });
                                            }
                                            player.trigger('error', [player, errobj]);
                                            return;
                                        }
                                    }
                                    // log non fatals?
                                    break;
                                }

                                player.trigger(etype, [player, data]);
                            });
                        });

                        if (init) {
                            common.prepend(common.find(".fp-player", root)[0], videoTag);
                        }

                        hls.loadSource(video.src);
                        hls.attachMedia(videoTag);

                        if (videoTag.paused && (video.autoplay || conf.autoplay)) {
                            videoTag.play();
                        }
                    },

                    resume: function () {
                        videoTag.play();
                    },

                    pause: function () {
                        videoTag.pause();
                    },

                    seek: function (time) {
                        videoTag.currentTime = time;
                    },

                    volume: function (level) {
                        if (videoTag) {
                            videoTag.volume = level;
                        }
                    },

                    speed: function (val) {
                        videoTag.playbackRate = val;
                        player.trigger('speed', [player, val]);
                    },

                    unload: function () {
                        // hls conditional probably not needed once
                        // https://github.com/flowplayer/flowplayer/commit/871ff783a8f23aa603e1120f4319d4a892125b0a
                        // is released
                        if (hls) {
                            hls.destroy();
                            hls = 0;
                            bean.off(videoTag);
                            common.removeNode(videoTag);
                            videoTag = 0;
                            qClean();
                        }
                    }
                };

            // pre 6.0.4: no boolean api.conf.poster and no poster with autoplay
            if (/^6\.0\.[0-3]$/.test(version) &&
                    !player.conf.splash && !player.conf.poster && !player.conf.autoplay) {
                bc = common.css(root, 'backgroundColor');
                // spaces in rgba arg mandatory for recognition
                has_bg = common.css(root, 'backgroundImage') !== "none" ||
                        (bc && bc !== "rgba(0, 0, 0, 0)" && bc !== "transparent");
                if (has_bg) {
                    player.conf.poster = true;
                }
            }
            if (player.conf.poster) {
                // when engine is loaded or player stopped
                // the engine is too late to the party:
                // poster is already removed and api.poster is false
                // poster state must be set again
                player.on("ready." + engineName + " stop." + engineName, posterHack);
            }

            return engine;
        };

    if (Hls.isSupported() && version.indexOf("5.") !== 0) {
        // only load engine if it can be used
        engineImpl.engineName = engineName; // must be exposed
        engineImpl.canPlay = function (type, conf) {
            var b = support.browser,
                wn = window.navigator,
                IE11 = wn.userAgent.indexOf("Trident/7") > -1;

            if (conf[engineName] === false || conf.clip[engineName] === false) {
                // engine disabled for player or clip
                return false;
            }

            // merge hlsjs clip config at earliest opportunity
            hlsconf = extend({
                smoothSwitching: true,
                recover: 0
            }, flowplayer.conf[engineName], conf[engineName], conf.clip[engineName]);

            if (isHlsType(type)) {
                // allow all browsers for hlsjs debugging
                if (hlsconf.debug) {
                    return true;
                }
                // https://bugzilla.mozilla.org/show_bug.cgi?id=1244294
                if (hlsconf.anamorphic &&
                        wn.platform.indexOf("Win") === 0 && b.mozilla && b.version.indexOf("44.") === 0) {
                    return false;
                }

                // https://github.com/dailymotion/hls.js/issues/9
                return IE11 || !b.safari;
            }
            return false;
        };

        // put on top of engine stack
        // so hlsjs is tested before html5 video hls and flash hls
        flowplayer.engines.unshift(engineImpl);

        flowplayer(function (api) {
            // to take precedence over VOD quality selector
            // hlsQualities must be configure at player or global level
            var hlsQualities = api.conf.hlsQualities || flowplayer.conf.hlsQualities;
            if (hlsQualities) {
                api.pluginQualitySelectorEnabled = engineImpl.canPlay("application/x-mpegurl", api.conf);
            }
        });

    }

}.apply(null, (typeof module === 'object' && module.exports)
    ? [require('flowplayer'), require('hls.js')]
    : [window.flowplayer, window.Hls]));
<|endoftext|>


<commit_before>/*!
 * Dependent questions jQuery plugin.
 *
 * Author: jsinclair@squiz.com.au
 *
 * Written using boilerplate code from
 * http://coding.smashingmagazine.com/2011/10/11/essential-jquery-plugin-patterns/
 *
 * © 2012 James Sinclair
 * MIT License.
 */

/*jslint nomen:true, browser:true*/
/*globals jQuery*/
;
(function ($, window, document, undefined) {
    "use strict";
    // See http://bit.ly/rc0Nzl for reasoning on why window, document and undefined
    // are passed in here.

    // The some() method is not implemented in some browsers.
    // See https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/some
    // for the origin of this polyfill.
    if (!Array.prototype.some) {
        Array.prototype.some = function (fun, thisp) {
            var t, len, i;
            if (this === null) { throw new TypeError(); }

            t   = Object(this);
            len = t.length >>> 0;
            if (typeof fun !== "function") { throw new TypeError(); }

            for (i = 0; i < len; i += 1) {
                if (i in t && fun.call(thisp, t[i], i, t)) { return true; }
            }
            return false;
        };
    }

    // Return true if haystack contains needle
    function contains(haystack, needle) {
        function equals(haystrand) {
            return haystrand === needle;
        }
        return haystack.some(equals);
    }

    // Configuration and defaults.
    var pluginName = 'dependentQuestions',
        defaults = {
            "effect": "slide",
            // Must be one of 'slide' or 'fade'
            "duration": "fast"
        },
        effectsMap = {
            "slide": {
                "show": "slideDown",
                "hide": "slideUp"
            },
            "fade": {
                "show": "fadeIn",
                "hide": "fadeOut"
            }
        };

    // The actual plugin constructor
    function QuestionToggler(element, options) {
        this.element = element;

        // Handle options.
        this.options   = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name     = pluginName;

        this.init();
    }

    // Initialisation. Parses all the 'data-depends-on' attributes and sets event
    // listeners.
    QuestionToggler.prototype.init = function () {
        // Find all elements that have a 'data-depends-on' attribute.
        var questions, dataRe, dependentsMap, effect, duration;

        effect        = this.options.effect;
        duration      = this.options.duration;
        dependentsMap = {};

        // Regular expression for parsing data attribute.
        dataRe = new RegExp('([^=]*)=(.*)');

        // Fetch all the elements with 'data-depends-on' attributes.
        if (!this.element.find) { this.element = $(this.element); }
        questions = this.element.find('[data-depends-on]');

        // Get the value of a form element by name, even if it is a radio button
        // or checkbox
        function getValueByName(inputName) {
            var multiInputs, el, elType, multi, modifier, checkVals;
            multiInputs = ['radio', 'checkbox'];
            el = $('[name="' + inputName + '"]');
            if (el.length === 0) { return undefined; }

            elType = el.attr('type');
            multi  = contains(multiInputs, elType);
            if (!multi) { return el.val(); }

            if (elType === 'radio') { return el.filter(':checked').val(); }

            if (elType === 'checkbox') {
                checkVals = $.map(el.filter(':checked'), function (checkbox) {
                    return $(checkbox).val();
                });
                return checkVals;
            }
        }

        // Event handler for when a toggling element changes value.
        function onTogglerChange(evt) {
            var toggler, dependents, showVal, val, show, effectFunc, action;
            toggler    = $(evt.target);
            dependents = toggler.data('dependents');
            showVal    = toggler.data('showVal');
            val        = getValueByName(toggler.attr('name'));
            show       = (typeof val === 'object')
                       ? contains(val, showVal)
                       : (val === showVal);
            action     = (show) ? 'show' : 'hide';
            effectFunc = effectsMap[effect][action];
            dependents[effectFunc](duration);
        }

        // Create a map of things that need to be toggled.
        function addMapEntry(i, element) {
            var data, el;
            el   = $(element);
            data = el.data('depends-on');
            if (!dependentsMap[data]) {
                dependentsMap[data] = el;
            } else {
                dependentsMap[data] = el.add(dependentsMap[data]);
            }
        }
        questions.each(addMapEntry);

        // Create event listeners
        function setListener(key, dependents) {
            var matches, name, showVal, toggler;
            // Parse the key value
            matches = dataRe.exec(key);
            if (!matches) { return; }
            name    = matches[1];
            showVal = matches[2];

            // Grab the relevant elements
            toggler = $('[name="' + name + '"]');
            toggler.data('dependents', dependents);
            toggler.data('showVal', showVal);
            toggler.change(onTogglerChange);
        }
        $.each(dependentsMap, setListener);

        // Set the initial state of each dependent question to match form state.
        function showHideByValue(key, dependents) {
            var matches, name, showVal, toggler, val, func, show;
            // Parse the key value
            matches = dataRe.exec(key);
            if (!matches) { return; }
            name    = matches[1];
            showVal = matches[2];

            // Work out whether or not to show the value
            toggler = $('[name="' + name + '"]');
            val     = getValueByName(name);
            if (typeof val === 'object') {
                show = contains(val, showVal);
            } else {
                show = (val === showVal);
            }
            func = (show) ? 'show' : 'hide';
            dependents[func]();
        }
        $.each(dependentsMap, showHideByValue);
    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, 'plugin_' + pluginName)) {
                $.data(
                    this,
                    'plugin_' + pluginName,
                    new QuestionToggler(this, options)
                );
            }
        });
    };

}(jQuery, window, document));<commit_msg>Tidying up for linter consistency<commit_after>/*!
 * Dependent questions jQuery plugin.
 *
 * Author: jsinclair@squiz.com.au
 *
 * Written using boilerplate code from
 * http://coding.smashingmagazine.com/2011/10/11/essential-jquery-plugin-patterns/
 *
 * © 2012 James Sinclair
 * MIT License.
 */

/*jslint nomen:true, browser:true*/
/*globals jQuery*/
;
(function ($, undefined) {
    "use strict";
    // See http://bit.ly/rc0Nzl for reasoning on why window, document and undefined
    // are passed in here.

    // The some() method is not implemented in some browsers.
    // See https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/some
    // for the origin of this polyfill.
    if (!Array.prototype.some) {
        Array.prototype.some = function (fun, thisp) {
            var t, len, i;
            if (this === null) { throw new TypeError(); }

            t   = Object(this);
            len = t.length >>> 0;
            if (typeof fun !== "function") { throw new TypeError(); }

            for (i = 0; i < len; i += 1) {
                if (i in t && fun.call(thisp, t[i], i, t)) { return true; }
            }
            return false;
        };
    }

    // Return true if haystack contains needle
    function contains(haystack, needle) {
        function equals(haystrand) {
            return haystrand === needle;
        }
        return haystack.some(equals);
    }

    // Configuration and defaults.
    var pluginName = "dependentQuestions",
        defaults = {
            "effect": "slide",
            // Must be one of 'slide' or 'fade'
            "duration": "fast"
        },
        effectsMap = {
            "slide": {
                "show": "slideDown",
                "hide": "slideUp"
            },
            "fade": {
                "show": "fadeIn",
                "hide": "fadeOut"
            }
        };

    // The actual plugin constructor
    function QuestionToggler(element, options) {
        this.element = element;

        // Handle options.
        this.options   = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name     = pluginName;

        this.init();
    }

    // Initialisation. Parses all the 'data-depends-on' attributes and sets event
    // listeners.
    QuestionToggler.prototype.init = function () {
        // Find all elements that have a 'data-depends-on' attribute.
        var questions, dataRe, dependentsMap, effect, duration;

        effect        = this.options.effect;
        duration      = this.options.duration;
        dependentsMap = {};

        // Regular expression for parsing data attribute.
        dataRe = new RegExp("([^=]*)=(.*)");

        // Fetch all the elements with 'data-depends-on' attributes.
        if (!this.element.find) { this.element = $(this.element); }
        questions = this.element.find("[data-depends-on]");

        // Get the value of a form element by name, even if it is a radio button
        // or checkbox
        function getValueByName(inputName) {
            var multiInputs, el, elType, multi, checkVals;
            multiInputs = ["radio", "checkbox"];
            el = $("[name='" + inputName + "']");
            if (el.length === 0) { return undefined; }

            elType = el.attr("type");
            multi  = contains(multiInputs, elType);
            if (!multi) { return el.val(); }

            if (elType === "radio") { return el.filter(":checked").val(); }

            if (elType === "checkbox") {
                checkVals = $.map(el.filter(":checked"), function (checkbox) {
                    return $(checkbox).val();
                });
                return checkVals;
            }
        }

        // Event handler for when a toggling element changes value.
        function onTogglerChange(evt) {
            var toggler, dependents, showVal, val, show, effectFunc, action;
            toggler    = $(evt.target);
            dependents = toggler.data("dependents");
            showVal    = toggler.data("showVal");
            val        = getValueByName(toggler.attr("name"));
            show       = (typeof val === "object")
                       ? contains(val, showVal)
                       : (val === showVal);
            action     = (show) ? "show" : "hide";
            effectFunc = effectsMap[effect][action];
            dependents[effectFunc](duration);
        }

        // Create a map of things that need to be toggled.
        function addMapEntry(i, element) {
            var data, el;
            el   = $(element);
            data = el.data("depends-on");
            if (!dependentsMap[data]) {
                dependentsMap[data] = el;
            } else {
                dependentsMap[data] = el.add(dependentsMap[data]);
            }
        }
        questions.each(addMapEntry);

        // Create event listeners
        function setListener(key, dependents) {
            var matches, name, showVal, toggler;
            // Parse the key value
            matches = dataRe.exec(key);
            if (!matches) { return; }
            name    = matches[1];
            showVal = matches[2];

            // Grab the relevant elements
            toggler = $("[name='" + name + "']");
            toggler.data("dependents", dependents);
            toggler.data("showVal", showVal);
            toggler.change(onTogglerChange);
        }
        $.each(dependentsMap, setListener);

        // Set the initial state of each dependent question to match form state.
        function showHideByValue(key, dependents) {
            var matches, name, showVal, val, func, show;
            // Parse the key value
            matches = dataRe.exec(key);
            if (!matches) { return; }
            name    = matches[1];
            showVal = matches[2];

            // Work out whether or not to show the value
            val = getValueByName(name);
            if (typeof val === "object") {
                show = contains(val, showVal);
            } else {
                show = (val === showVal);
            }
            func = (show) ? "show" : "hide";
            dependents[func]();
        }
        $.each(dependentsMap, showHideByValue);
    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(
                    this,
                    "plugin_" + pluginName,
                    new QuestionToggler(this, options)
                );
            }
        });
    };

}(jQuery, undefined));<|endoftext|>


<commit_before>define(["dojo/_base/declare", "./PpwCodeObject", "ppwcode/contracts/_Mixin",
        "ppwcode/oddsAndEnds/js", "module"],
    function(declare, PpwCodeObject, _ContractMixin,
             js, module) {

      var Value = declare([PpwCodeObject, _ContractMixin], {
        // summary:
        //   Values are immutable after construction.
        //   They are constructed with a kwargs argument.
        //   For JSON-inification, toString, typeDescription, see PpwCodeObject.

        _c_invar: [

        ],

        constructor: function(/*Object*/ props) {
          this._c_pre(function() {return props /* exists and not null */;});
          this._c_pre(function() {return js.typeOf(props) === "object";});

          this._c_NOP(props);
        },

        compare: function(/*Value*/ other) {
          // summary:
          //   Return a negative number if this is considered smaller than other;
          //   return a positive number if this is considered larger than other;
          //   return 0 is this.equals(other)
          // description:
          //   This method should return consistent results: given a this and an other,
          //   it should return the same result whenever the method is called, during
          //   the entire live time of the object.
          //   This extra requirement can be asked of Values, since they are immutable.
          //   This method should realize a total order: it should be complete,
          //   transitive, and anti-symmetric.
          //
          //   The pattern to express `this # other` is `this.compare(other) # 0`, with
          //   # either <, =, or >.
          //
          //   In the order, undefined comes first and null comes second. However, it is impossible
          //   to compare null and undefined, since neither can be used as the left-side in calling this method.
          // tags:
          //   public extension
          this._c_pre(function() {return !other || (other.isInstanceOf && other.isInstanceOf(this.constructor));});

          return this._c_ABSTRACT(); // return Number
        },

        equals: function(/*Value*/ other) {
          // summary:
          // description:
          //   Must be overriden in subtypes with the pattern:
          //   | return this.inherited(arguments) && (EXTRA CONDITIONS);
          //   This implementation checks whether other is null.
          //
          //   This method is also used by dojox/mvc/sync! There can be no preconditions!
          // tags:
          //   public extension

          // Note: not a good candidate for chaining: look at what the overrider should write (it is the same)

          // we force to actually return a Boolean (!!)

          return !!(other && // return boolean
                    other.constructor &&
                    (other.constructor === this.constructor)); // same type;
        },

        getValue: function() { // TODO what is this method for? Remove it?
          this._c_ABSTRACT();
          return null; // return object
        }

      });

      Value.persistenceType = module.id;

      return Value;
    }
);
<commit_msg>comment about converter functionality<commit_after>define(["dojo/_base/declare", "./PpwCodeObject", "ppwcode/contracts/_Mixin",
        "ppwcode/oddsAndEnds/js", "module"],
    function(declare, PpwCodeObject, _ContractMixin,
             js, module) {

      var Value = declare([PpwCodeObject, _ContractMixin], {
        // summary:
        //   Values are immutable after construction.
        //   They are constructed with a kwargs argument.
        //   For JSON-inification, toString, typeDescription, see PpwCodeObject.
        // description:
        //   Constructors of concrete types should have a property format
        //   and parse, that are functions that can format (turn into a user-oriented
        //   string) instances of that type, and parse strings into instances
        //   of that type.
        //   format: Value x Options --> String
        //   parse: String x Options --> Value, ParseException

        _c_invar: [

        ],

        constructor: function(/*Object*/ props) {
          this._c_pre(function() {return props /* exists and not null */;});
          this._c_pre(function() {return js.typeOf(props) === "object";});

          this._c_NOP(props);
        },

        compare: function(/*Value*/ other) {
          // summary:
          //   Return a negative number if this is considered smaller than other;
          //   return a positive number if this is considered larger than other;
          //   return 0 is this.equals(other)
          // description:
          //   This method should return consistent results: given a this and an other,
          //   it should return the same result whenever the method is called, during
          //   the entire live time of the object.
          //   This extra requirement can be asked of Values, since they are immutable.
          //   This method should realize a total order: it should be complete,
          //   transitive, and anti-symmetric.
          //
          //   The pattern to express `this # other` is `this.compare(other) # 0`, with
          //   # either <, =, or >.
          //
          //   In the order, undefined comes first and null comes second. However, it is impossible
          //   to compare null and undefined, since neither can be used as the left-side in calling this method.
          // tags:
          //   public extension
          this._c_pre(function() {return !other || (other.isInstanceOf && other.isInstanceOf(this.constructor));});

          return this._c_ABSTRACT(); // return Number
        },

        equals: function(/*Value*/ other) {
          // summary:
          // description:
          //   Must be overriden in subtypes with the pattern:
          //   | return this.inherited(arguments) && (EXTRA CONDITIONS);
          //   This implementation checks whether other is null.
          //
          //   This method is also used by dojox/mvc/sync! There can be no preconditions!
          // tags:
          //   public extension

          // Note: not a good candidate for chaining: look at what the overrider should write (it is the same)

          // we force to actually return a Boolean (!!)

          return !!(other && // return boolean
                    other.constructor &&
                    (other.constructor === this.constructor)); // same type;
        },

        getValue: function() { // TODO what is this method for? Remove it?
          this._c_ABSTRACT();
          return null; // return object
        }

      });

      Value.persistenceType = module.id;

      return Value;
    }
);
<|endoftext|>


<commit_before>// Description:
//   This bot listen to every word and forward the data to a wamp channel
//
// Dependencies:
//   http://autobahn.ws
//
// Configuration:
//   None
//
// Commands:
//   hubot meow - < Sends you feline talk. >
//
// Notes:
//   Version 1.0
//
// Author:
//   munroenet | Cameron Munroe ~ Mun

var autobahn = require("autobahn");

var router_url = process.env.WAMP_ROUTER_URL ? process.env.WAMP_ROUTER_URL : "ws://wamp_router:8080/ws";

var router_realm = process.env.WAMP_RELAM ? process.env.WAMP_RELAM : "realm1";

var env = process.env.env ? process.env.env.toUpperCase() : "production";

module.exports = function (robot) {
    console.log("Verson 1   ");

    var session = undefined;

    var connection = new autobahn.Connection({
            url: router_url,
            realm: router_realm
        }
    );
    console.log("Try to connect to wamp router: " + router_url + " R: " + router_realm)
    connection.onopen = function (sess) {
        console.log("Connection is open to ", router_url, router_realm);
        session = sess;
        session.subscribe('sofia.channel..messages.OUTGOING_MESSAGE', function (args, obj, event) {
            console.log(arguments);
            var msg = args[0];
            console.log("Got outgoing msg for channel " + msg.channel + " and msg: " + msg.text);
            robot.adapter.chatdriver.sendMessageByRoomId(msg.text, msg.channel)
        }, {match: "wildcard"});
    };
    connection.onclose = function (reason, details) {
        if (reason == "unreachable" || reason == "unsupported") {
            console.log("Connection not established", reason, details);
        } else {
            console.log("Connection lost", reason, details);
        }
    };
    connection.open();

    robot.respond(/meow/i, function (res) {
        res.send("Mew mew mew~");
    });

    robot.hear(/.*/, function (res) {
        if (session == undefined) {
            robot.send("Oh we got a problem here.... ");
            robot.send("I can't forward your message because we got a connection problem to the router: " + router_url + " realm:" + router_realm)
            return
        }
        var topic = 'sofia.channel.' + res.message.room.toLowerCase() + '.messages.INCOMING_MESSAGE';
        console.log("Forward  message to " + topic);
        console.log(res);
        session.publish(topic, [res.message]);
        console.log("Published.... ");

    })
};
<commit_msg>- add log to get the room id<commit_after>// Description:
//   This bot listen to every word and forward the data to a wamp channel
//
// Dependencies:
//   http://autobahn.ws
//
// Configuration:
//   None
//
// Commands:
//   hubot meow - < Sends you feline talk. >
//
// Notes:
//   Version 1.0
//
// Author:
//   munroenet | Cameron Munroe ~ Mun

var autobahn = require("autobahn");

var router_url = process.env.WAMP_ROUTER_URL ? process.env.WAMP_ROUTER_URL : "ws://wamp_router:8080/ws";

var router_realm = process.env.WAMP_RELAM ? process.env.WAMP_RELAM : "realm1";

var env = process.env.env ? process.env.env.toUpperCase() : "production";

module.exports = function (robot) {
    console.log("Verson 1   ");

    var session = undefined;

    var connection = new autobahn.Connection({
            url: router_url,
            realm: router_realm
        }
    );
    console.log("Try to connect to wamp router: " + router_url + " R: " + router_realm)
    connection.onopen = function (sess) {
        console.log("Connection is open to ", router_url, router_realm);
        session = sess;
        session.subscribe('sofia.channel..messages.OUTGOING_MESSAGE', function (args, obj, event) {
            console.log(arguments);
            var msg = args[0];
            console.log("Got outgoing msg for channel " + msg.channel + " and msg: " + msg.text);
            robot.adapter.chatdriver.sendMessageByRoomId(msg.text, msg.channel)
            console.log("room id " + robot.adapter.chatdriver.getRoomId(msg.channel))
        }, {match: "wildcard"});
    };
    connection.onclose = function (reason, details) {
        if (reason == "unreachable" || reason == "unsupported") {
            console.log("Connection not established", reason, details);
        } else {
            console.log("Connection lost", reason, details);
        }
    };
    connection.open();

    robot.respond(/meow/i, function (res) {
        res.send("Mew mew mew~");
    });

    robot.hear(/.*/, function (res) {
        if (session == undefined) {
            robot.send("Oh we got a problem here.... ");
            robot.send("I can't forward your message because we got a connection problem to the router: " + router_url + " realm:" + router_realm)
            return
        }
        var topic = 'sofia.channel.' + res.message.room.toLowerCase() + '.messages.INCOMING_MESSAGE';
        console.log("Forward  message to " + topic);
        console.log(res);
        session.publish(topic, [res.message]);
        console.log("Published.... ");

    })
};
<|endoftext|>


<commit_before>/**
 * "Safe" utility methods.
 *
 * @package randy
 * @author Andrew Sliwinski <andrew@diy.org>
 */

/**
 * Constructor
 */
function Util () {};

/**
 * Prints input to stdout.
 *
 * @param {Object} Input
 *
 * @return {void}
 */
Util.prototype.stdout = function (input) {
    if (input) {
        console.log('Randy: ' + input.toString());
    }
};

/**
 * Safe object to JSON string encoder.
 *
 * @param {Object} Input
 *
 * @return {String}
 */
Util.prototype.stringify = function (obj, callback) {
    try {
        callback(null, JSON.stringify(obj));
    } catch (err) {
        callback(err);
    }
};

/**
 * Safe JSON string to object decoder.
 *
 * @param {String} Input
 *
 * @return {Object}
 */
Util.prototype.parse = function (obj, callback) {
    try {
        callback(null, JSON.parse(obj));
    } catch (err) {
        callback(err);
    }
};

/**
 * Export
 */
module.exports = new Util();<commit_msg>More verbose error message on JSON parse<commit_after>/**
 * "Safe" utility methods.
 *
 * @package randy
 * @author Andrew Sliwinski <andrew@diy.org>
 */

/**
 * Constructor
 */
function Util () {};

/**
 * Prints input to stdout.
 *
 * @param {Object} Input
 *
 * @return {void}
 */
Util.prototype.stdout = function (input) {
    if (input) {
        console.log('Randy: ' + input.toString());
    }
};

/**
 * Safe object to JSON string encoder.
 *
 * @param {Object} Input
 *
 * @return {String}
 */
Util.prototype.stringify = function (obj, callback) {
    try {
        callback(null, JSON.stringify(obj));
    } catch (err) {
        callback(err);
    }
};

/**
 * Safe JSON string to object decoder.
 *
 * @param {String} Input
 *
 * @return {Object}
 */
Util.prototype.parse = function (obj, callback) {
    try {
        callback(null, JSON.parse(obj));
    } catch (err) {
        callback('Invalid JSON');
    }
};

/**
 * Export
 */
module.exports = new Util();<|endoftext|>


<commit_before>"use strict";

var chalk = require("chalk");
// convention used : label and nodes
var archy = require("archy");

var BUILTINS = [
  "publish",
  "install",
  "uninstall",
  "test",
  "stop",
  "start",
  "restart",
  "version"
];

function archify (scripts, alpha) {
  var names = Object.keys(scripts);
  if (alpha) {
    names = names.sort();
  }
  return {
    label: names.length + " scripts",
    nodes: names.map(function (name) {
      return scripts[name];
    })
  }
}

function getLabel (script) {
  var name;
  if (script.isPre || script.isPost) {
    name = chalk.cyan(script.name);
  } else {
    name = chalk.bold(script.name);
  }
  return name + chalk.dim(" — " + script.cmd);
}

function isPreScript (name, scripts) {
  return isLifeCycleScript("pre", name, scripts);
}

function isPostScript (name, scripts) {
  return isLifeCycleScript("post", name, scripts);
}

function isLifeCycleScript (prefix, name, scripts) {
  var re = new RegExp("^" + prefix);
  var root = name.slice(prefix.length);
  return Boolean(name.match(re) && (scripts[root] || ~BUILTINS.indexOf(root)));
}

function getPreScript (name, scripts) {
  return scripts["pre" + name];
}

function getPostScript (name, scripts) {
  return scripts["post" + name];
}

function getNodesNames (name, scripts) {
  var cmd = scripts[name];
  var m = cmd.match(/(npm run (\S*))+/gi);
  if (!m) return null;

  return m.map(function (c) {
    return c.slice(8);
  });
}

function getDetailedScripts (scripts) {
  return Object.keys(scripts).reduce(function (all, name) {
    var s = {
      name: name,
      cmd: scripts[name],
      isPre: isPreScript(name, scripts),
      isPost: isPostScript(name, scripts),
      pre: getPreScript(name, scripts),
      post: getPostScript(name, scripts),
      nodesNames: getNodesNames(name, scripts)
    };

    s.label = getLabel(s);

    all[name] = s;
    return all;
  }, {});
}

function attachNodes (scripts) {
  return Object.keys(scripts).reduce(function (all, name) {
    var s = scripts[name];
    s.nodes = [];
    if (s.nodesNames) {
      s.nodes = s.nodesNames.map(function (c) {
        return scripts[c];
      });
    }

    if (s.pre) s.nodes.unshift(scripts["pre" + name]);
    if (s.post) s.nodes.push(scripts["post" + name]);

    all[name] = s;
    return all;
  }, {});
}

function main (scripts, options) {
  if (!scripts) throw new Error("No package.json or no scripts key in this dir");

  var detailedScripts = getDetailedScripts(scripts);
  detailedScripts = attachNodes(detailedScripts);

  // sort?
  var alpha = options.a || options.alpha;
  return archy(archify(detailedScripts, alpha));
}

module.exports = {
  main: main
};
<commit_msg>fix: broken regex in watch expression with quotes<commit_after>"use strict";

var chalk = require("chalk");
// convention used : label and nodes
var archy = require("archy");

var BUILTINS = [
  "publish",
  "install",
  "uninstall",
  "test",
  "stop",
  "start",
  "restart",
  "version"
];

function archify (scripts, alpha) {
  var names = Object.keys(scripts);
  if (alpha) {
    names = names.sort();
  }
  return {
    label: `${names.length} scripts`,
    nodes: names.map(n => scripts[n])
  }
}

function getLabel (script) {
  var name = script.isPre || script.isPost
    ? chalk.cyan(script.name)
    : chalk.bold(script.name)

  return name + chalk.dim(` —  ${script.cmd}`);
}

function isPreScript (name, scripts) {
  return isLifeCycleScript("pre", name, scripts);
}

function isPostScript (name, scripts) {
  return isLifeCycleScript("post", name, scripts);
}

function isLifeCycleScript (prefix, name, scripts) {
  var re = new RegExp("^" + prefix);
  var root = name.slice(prefix.length);
  return Boolean(name.match(re) && (scripts[root] || ~BUILTINS.indexOf(root)));
}

function getPreScript (name, scripts) {
  return scripts["pre" + name];
}

function getPostScript (name, scripts) {
  return scripts["post" + name];
}

function getNodesNames (name, scripts) {
  var cmd = scripts[name];
  var m = cmd.match(/(npm run (\w*))+/gi);
  if (!m) return null;

  return m.map(c => c.slice(8));
}

function getDetailedScripts (scripts) {
  return Object.keys(scripts).reduce((all, name) => {
    var s = {
      name: name,
      cmd: scripts[name],
      isPre: isPreScript(name, scripts),
      isPost: isPostScript(name, scripts),
      pre: getPreScript(name, scripts),
      post: getPostScript(name, scripts),
      nodesNames: getNodesNames(name, scripts)
    };

    s.label = getLabel(s);

    all[name] = s;
    return all;
  }, {});
}

function attachNodes (scripts) {
  return Object.keys(scripts).reduce((all, name) => {
    var s = scripts[name];
    s.nodes = s.nodesNames
      ? s.nodesNames.map(n => scripts[n])
      : []

    if (s.pre) s.nodes.unshift(scripts["pre" + name]);
    if (s.post) s.nodes.push(scripts["post" + name]);

    all[name] = s;
    return all;
  }, {});
}

function main (scripts, options) {
  if (!scripts) throw new Error("No package.json or no scripts key in this dir");

  var detailedScripts = getDetailedScripts(scripts);
  detailedScripts = attachNodes(detailedScripts);

  // sort?
  var alpha = options.a || options.alpha;
  return archy(archify(detailedScripts, alpha));
}

module.exports = { main }
<|endoftext|>


<commit_before>// This file is part of Indico.
// Copyright (C) 2002 - 2020 CERN
//
// Indico is free software; you can redistribute it and/or
// modify it under the terms of the MIT License; see the
// LICENSE file for more details.

import React from 'react';
import ReactDOM from 'react-dom';
import {WTFPrincipalListField} from 'indico/react/components';

window.setupPrincipalListWidget = function setupPrincipalListWidget({fieldId, ...options}) {
  options = {
    ...{
      eventId: null,
      withGroups: false,
      withExternalUsers: false,
      withEventRoles: false,
      withCategoryRoles: false,
      withRegistrants: false,
      withEmails: true,
    },
    ...options,
  };
  const field = document.getElementById(fieldId);
  const principals = JSON.parse(field.value);

  ReactDOM.render(
    <WTFPrincipalListField fieldId={fieldId} defaultValue={principals} {...options} />,
    document.getElementById(`userGroupList-${fieldId}`)
  );
};
<commit_msg>Change weird default<commit_after>// This file is part of Indico.
// Copyright (C) 2002 - 2020 CERN
//
// Indico is free software; you can redistribute it and/or
// modify it under the terms of the MIT License; see the
// LICENSE file for more details.

import React from 'react';
import ReactDOM from 'react-dom';
import {WTFPrincipalListField} from 'indico/react/components';

window.setupPrincipalListWidget = function setupPrincipalListWidget({fieldId, ...options}) {
  options = {
    ...{
      eventId: null,
      withGroups: false,
      withExternalUsers: false,
      withEventRoles: false,
      withCategoryRoles: false,
      withRegistrants: false,
      withEmails: false,
    },
    ...options,
  };
  const field = document.getElementById(fieldId);
  const principals = JSON.parse(field.value);

  ReactDOM.render(
    <WTFPrincipalListField fieldId={fieldId} defaultValue={principals} {...options} />,
    document.getElementById(`userGroupList-${fieldId}`)
  );
};
<|endoftext|>