<commit_before>/*
 * Copyright (c) 2013-2014, Paul Fischer, Intel Corporation. All rights reserved.
 * Please see http://software.intel.com/html5/license/samples for license terms and conditions.
 */

/*
 * The functions in this file are designed to reliably detect various "ready" events
 * within a variety of containers (Intel XDK "legacy" container, Cordova 3.x container,
 * standard browser, App Preview, Crosswalk, etc.). It "unifies" the commonly used
 * ready events and is very helpful for moving a "web app" to a "hybrid app" scenario.
 *
 * This file has no dependencies. It will generate a custom "app.Ready" event
 * that you should use once to start your application, rather than waiting on a
 * "device ready" or "document ready" or "window load" or similar events.
 *
 * You should not have to modify anything in this file to use it. See the example
 * index.html file that accompanies this file (in its sample repo location) for
 * recommendations on the best placement of this file relative to other files and
 * for recommendations regarding the loading of other JavaScript files.
 *
 * There are a large number of console.log messages contained within this file.
 * They can be used to debug initialization problems and understand how it works.
 * It is highly recommended that you leave them in your app, they will not unduly
 * slow down or burden your application.
 *
 * There are many comments in this file and the accompanying index.html file.
 * Please read the comments within for details and further documentation.
 *
 * BTW: "dev" means "device" in this context, not "develop," because it grew out
 * of a desire to build a more reliable and flexible "device ready" detector.
 */

/*jslint browser:true, devel:true, white:true, vars:true */
/*global $:false, intel:false, dev:false, performance:false */

window.dev = window.dev || {} ;         // there should only be one of these, but...

// Use performance counter if it is available, otherwise, use milliseconds since 1970

if( window.performance && performance.now ) {
    dev.timeStamp = function() { return performance.now().toFixed(3) ; } ;
} else {
    dev.timeStart = Date.now() ;        // feeble zero ref for relative time in ms
    dev.timeStamp = function() { return (Date.now() - dev.timeStart) ; } ;
}

// Defines some delays constants used throughout for ready detections.
// Each should be smaller than the next; most cases should work as is.
// Lowering dev.BROWSER will speed up detection of browser scenario...
// ...at expense of possible false detects of browser environment...
// ...probably okay to go as low as 3000ms, depends on external libraries, etc.

dev.INSURANCE = 250 ;                   // ms, insurance on registering ready events detected
dev.WINDOW_LOAD = 500 ;                 // ms, for combating premature window load events
dev.BROWSER = 7000 ;                    // ms, detecting in a browser (probably best at >5 seconds)
dev.FAIL_SAFE = 10000 ;                 // ms, if all else fails, this saves our bacon :-)

// Used to keep track of time when each of these items was triggered.
// Sorry for the weird names in the isDeviceReady structure, it's done for
// easier debugging and comparison of numbers when displayed in console.log messages.

dev.isDeviceReady = {                   // listed in approximate order expected
    a_startTime______:dev.timeStamp(),  // when we started execution of this module
    b_fnDocumentReady:false,            // detected document.readyState == "complete"
    c_cordova_ready__:false,            // detected cordova device ready event
    d_xdk_ready______:false,            // detected xdk device ready event
    e_fnDeviceReady__:false,            // entered onDeviceReady()
    f_browser_ready__:false             // detected browser container
} ;

// Where the device ready event ultimately ends up, regardless of environment.
// Runs after underlying device native code and browser is initialized.
// Usually not much needed here, just additional "device init" code.
// See initDeviceReady() below for code that kicks off this function.
// This function works with Cordova and XDK webview or in a browser.

// NOTE: Customize this function, if necessary, for low-level init of your app.
// NOTE: In most cases, you can leave this code alone and use it as is.

dev.onDeviceReady = function() {
    var fName = "dev.onDeviceReady():" ;
    console.log(fName, "entry") ;

    // Useful for debug and understanding initialization flow.
    if( dev.isDeviceReady.e_fnDeviceReady__ ) {
        console.log(fName, "function terminated") ;
        return ;
    } else {
        dev.isDeviceReady.e_fnDeviceReady__ = dev.timeStamp() ;
    }

    // TODO: change this to use new custom events if I confirm it works in all webviews.
    // All device initialization is done; create and issue custom event named "app.Ready".
    // Using deprecated custom events until I can confirm new method works in all webviews...

    var evt = document.createEvent("Event") ;
    evt.initEvent("app.Ready", false, false) ;
    document.dispatchEvent(evt) ;

    console.log(fName, dev.isDeviceReady) ;
    console.log(fName, "exit") ;
} ;

/*
 * The following is an excerpt from the 2.9.0 cordova.js file and is useful for understanding
 * Cordova events. The order of events during page load and Cordova startup is as follows:
 *
 * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.
 * onNativeReady*              Internal event that indicates the Cordova native side is ready.
 * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.
 * onCordovaInfoReady*         Internal event fired when device properties are available.
 * onCordovaConnectionReady*   Internal event fired when the connection property has been set.
 * onDeviceReady*              User event fired to indicate that Cordova is ready
 * onResume                    User event fired to indicate a start/resume lifecycle event
 * onPause                     User event fired to indicate a pause lifecycle event
 * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
 *
 * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
 * Listeners that subscribe to a sticky (*) event, after the event is fired, will execute right away.
 *
 * The only Cordova events that user code should register for are:
 *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
 *      pause                 App has moved to background
 *      resume                App has returned to foreground
 *
 * Listeners can be registered as follows:
 *      document.addEventListener("deviceready", myDeviceReadyListener, false);
 *      document.addEventListener("resume", myResumeListener, false);
 *      document.addEventListener("pause", myPauseListener, false);
 *
 * The following DOM lifecycle events should be used for saving and restoring state:
 *      window.onload
 *      window.onunload
 */

// The following is not fool-proof, we're mostly interested in detecting one
// or both events to insure device init is finished, detecting either will do.
// Even though the timing should indicate which container, it does not always work.

// NOTE: In most cases, you can leave these functions alone and use them as is.

// If this event is called first, we should be in the Cordova container.

dev.onDeviceReadyCordova = function() {
    dev.isDeviceReady.c_cordova_ready__ = dev.timeStamp() ;
    var fName = "dev.onDeviceReadyCordova():" ;
    console.log(fName, dev.isDeviceReady.c_cordova_ready__) ;
    window.setTimeout(dev.onDeviceReady, dev.INSURANCE) ;
} ;

// If this event is called first, we should be in the legacy XDK container.

dev.onDeviceReadyXDK = function() {
    dev.isDeviceReady.d_xdk_ready______ = dev.timeStamp() ;
    var fName = "dev.onDeviceReadyXDK():" ;
    console.log(fName, dev.isDeviceReady.d_xdk_ready______) ;
    window.setTimeout(dev.onDeviceReady, dev.INSURANCE) ;
} ;

// This is a faux onDeviceReady for browser scenario, mostly for code symmetry and fail-safe.

dev.onDeviceReadyBrowser = function() {
    dev.isDeviceReady.f_browser_ready__ = dev.timeStamp() ;
    var fName = "dev.onDeviceReadyBrowser():" ;
    console.log(fName, dev.isDeviceReady.f_browser_ready__) ;
    window.setTimeout(dev.onDeviceReady, dev.INSURANCE) ;
} ;

// Runs after document is loaded, and sets up wait for native (device) init to finish.
// If we're running in a browser we're ready to go when document is loaded, but...
// if we're running on a device we need to wait for native code to finish its init.

// NOTE: In most cases, you can leave this code alone and use it as is.

dev.initDeviceReady = function() {
    var fName = "dev.initDeviceReady():" ;
    console.log(fName, "entry") ;

    // Useful for debug and understanding initialization flow.
    if( dev.isDeviceReady.b_fnDocumentReady ) {
        console.log(fName, "function terminated") ;
        return ;
    } else {
        dev.isDeviceReady.b_fnDocumentReady = dev.timeStamp() ;
    }

    document.addEventListener("intel.xdk.device.ready", dev.onDeviceReadyXDK, false) ;
    document.addEventListener("deviceready", dev.onDeviceReadyCordova, false) ;
    window.setTimeout(dev.onDeviceReadyBrowser, dev.BROWSER) ;

    // Last one, above, is fail-safe, in case we got no device ready event from Cordova or XDK.
    // Cordova will timeout after five seconds, so we use a longer timeout to be conservative.
    // Very end of this file includes a "fail-safe, fail-safe" in case all else fails!

    // TODO: might want to double-check for Cordova deviceready, shouldn't be required...
    // "if" logic (below) needs further investigation in Cordova, legacy and debug containers
    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
    // if( window.channel && channel.onCordovaReady && (channel.onCordovaReady.state === 2) )
    //     dev.onDeviceReadyCordova() ;

    console.log(fName, "navigator.vendor:", navigator.vendor) ;
    console.log(fName, "navigator.platform:", navigator.platform) ;
    console.log(fName, "navigator.userAgent:", navigator.userAgent) ;

    console.log(fName, "exit") ;
} ;

// Wait for document ready before looking for device ready.
// This insures the app does not start running until DOM is ready and...
// ...makes it easier to deal with both in-browser and on-device scenarios and...
// ...makes it easier to init device-dependent and device-independent code in one place.

// NOTE: In most cases, you can leave this code alone and use it as is.
// NOTE: document.readyState seems to be more reliable, but seems not to be omnipresent.
// NOTE: Delay after "load" event is added because some webviews appear to trigger prematurely.

if( document.readyState ) {                     // some devices don't support this, why???
    console.log("document.readyState:", document.readyState) ;
    document.onreadystatechange = function () {
        console.log("document.readyState:", document.readyState) ;
        if (document.readyState === "complete") {
            dev.initDeviceReady() ;             // call when document is "ready ready" :)
        }
    } ;
}
console.log("addEventListener:", dev.timeStamp()) ;
window.addEventListener("load", function(){window.setTimeout(dev.initDeviceReady,dev.WINDOW_LOAD);}.bind(dev), false) ;
window.setTimeout(dev.initDeviceReady, dev.FAIL_SAFE) ;     // fail-safe fail-safe, just in case we miss all events!
<commit_msg>minor reformatting<commit_after>/*
 * Copyright (c) 2013-2014, Paul Fischer, Intel Corporation. All rights reserved.
 * Please see http://software.intel.com/html5/license/samples for license terms and conditions.
 */

/*
 * The functions in this file are designed to reliably detect various "ready" events
 * within a variety of containers (Intel XDK "legacy" container, Cordova 3.x container,
 * standard browser, App Preview, Crosswalk, etc.). It "unifies" the commonly used
 * ready events and is very helpful for moving a "web app" to a "hybrid app" scenario.
 *
 * This file has no dependencies. It will generate a custom "app.Ready" event
 * that you should use once to start your application, rather than waiting on a
 * "device ready" or "document ready" or "window load" or similar events.
 *
 * You should not have to modify anything in this file to use it. See the example
 * index.html file that accompanies this file (in its sample repo location) for
 * recommendations on the best placement of this file relative to other files and
 * for recommendations regarding the loading of other JavaScript files.
 *
 * There are a large number of console.log messages contained within this file.
 * They can be used to debug initialization problems and understand how it works.
 * It is highly recommended that you leave them in your app, they will not unduly
 * slow down or burden your application.
 *
 * There are many comments in this file and the accompanying index.html file.
 * Please read the comments within for details and further documentation.
 *
 * BTW: "dev" means "device" in this context, not "develop," because it grew out
 * of a desire to build a more reliable and flexible "device ready" detector.
 */

/*jslint browser:true, devel:true, white:true, vars:true */
/*global $:false, intel:false, dev:false, performance:false */

window.dev = window.dev || {} ;         // there should only be one of these, but...

// Use performance counter if it is available, otherwise, use milliseconds since 1970

if( window.performance && performance.now ) {
    dev.timeStamp = function() { return performance.now().toFixed(3) ; } ;
}
else {
    dev.timeStart = Date.now() ;        // feeble zero ref for relative time in ms
    dev.timeStamp = function() { return (Date.now() - dev.timeStart) ; } ;
}

// Defines some delays constants used throughout for ready detections.
// Each should be smaller than the next; most cases should work as is.
// Lowering dev.BROWSER will speed up detection of browser scenario...
// ...at expense of possible false detects of browser environment...
// ...probably okay to go as low as 3000ms, depends on external libraries, etc.

dev.INSURANCE = 250 ;                   // ms, insurance on registering ready events detected
dev.WINDOW_LOAD = 500 ;                 // ms, for combating premature window load events
dev.BROWSER = 7000 ;                    // ms, detecting in a browser (probably best at >5 seconds)
dev.FAIL_SAFE = 10000 ;                 // ms, if all else fails, this saves our bacon :-)

// Used to keep track of time when each of these items was triggered.
// Sorry for the weird names in the isDeviceReady structure, it's done for
// easier debugging and comparison of numbers when displayed in console.log messages.

dev.isDeviceReady = {                   // listed in approximate order expected
    a_startTime______:dev.timeStamp(),  // when we started execution of this module
    b_fnDocumentReady:false,            // detected document.readyState == "complete"
    c_cordova_ready__:false,            // detected cordova device ready event
    d_xdk_ready______:false,            // detected xdk device ready event
    e_fnDeviceReady__:false,            // entered onDeviceReady()
    f_browser_ready__:false             // detected browser container
} ;

// Where the device ready event ultimately ends up, regardless of environment.
// Runs after underlying device native code and browser is initialized.
// Usually not much needed here, just additional "device init" code.
// See initDeviceReady() below for code that kicks off this function.
// This function works with Cordova and XDK webview or in a browser.

// NOTE: Customize this function, if necessary, for low-level init of your app.
// NOTE: In most cases, you can leave this code alone and use it as is.

dev.onDeviceReady = function() {
    var fName = "dev.onDeviceReady():" ;
    console.log(fName, "entry") ;

    // Useful for debug and understanding initialization flow.
    if( dev.isDeviceReady.e_fnDeviceReady__ ) {
        console.log(fName, "function terminated") ;
        return ;
    } else {
        dev.isDeviceReady.e_fnDeviceReady__ = dev.timeStamp() ;
    }

    // TODO: change this to use new custom events if I confirm it works in all webviews.
    // All device initialization is done; create and issue custom event named "app.Ready".
    // Using deprecated custom events until I can confirm new method works in all webviews...

    var evt = document.createEvent("Event") ;
    evt.initEvent("app.Ready", false, false) ;
    document.dispatchEvent(evt) ;

    console.log(fName, dev.isDeviceReady) ;
    console.log(fName, "exit") ;
} ;

/*
 * The following is an excerpt from the 2.9.0 cordova.js file and is useful for understanding
 * Cordova events. The order of events during page load and Cordova startup is as follows:
 *
 * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.
 * onNativeReady*              Internal event that indicates the Cordova native side is ready.
 * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.
 * onCordovaInfoReady*         Internal event fired when device properties are available.
 * onCordovaConnectionReady*   Internal event fired when the connection property has been set.
 * onDeviceReady*              User event fired to indicate that Cordova is ready
 * onResume                    User event fired to indicate a start/resume lifecycle event
 * onPause                     User event fired to indicate a pause lifecycle event
 * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
 *
 * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
 * Listeners that subscribe to a sticky (*) event, after the event is fired, will execute right away.
 *
 * The only Cordova events that user code should register for are:
 *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
 *      pause                 App has moved to background
 *      resume                App has returned to foreground
 *
 * Listeners can be registered as follows:
 *      document.addEventListener("deviceready", myDeviceReadyListener, false);
 *      document.addEventListener("resume", myResumeListener, false);
 *      document.addEventListener("pause", myPauseListener, false);
 *
 * The following DOM lifecycle events should be used for saving and restoring state:
 *      window.onload
 *      window.onunload
 */

// The following is not fool-proof, we're mostly interested in detecting one
// or both events to insure device init is finished, detecting either will do.
// Even though the timing should indicate which container, it does not always work.

// NOTE: In most cases, you can leave these functions alone and use them as is.

// If this event is called first, we should be in the Cordova container.

dev.onDeviceReadyCordova = function() {
    dev.isDeviceReady.c_cordova_ready__ = dev.timeStamp() ;
    var fName = "dev.onDeviceReadyCordova():" ;
    console.log(fName, dev.isDeviceReady.c_cordova_ready__) ;
    window.setTimeout(dev.onDeviceReady, dev.INSURANCE) ;
} ;

// If this event is called first, we should be in the legacy XDK container.

dev.onDeviceReadyXDK = function() {
    dev.isDeviceReady.d_xdk_ready______ = dev.timeStamp() ;
    var fName = "dev.onDeviceReadyXDK():" ;
    console.log(fName, dev.isDeviceReady.d_xdk_ready______) ;
    window.setTimeout(dev.onDeviceReady, dev.INSURANCE) ;
} ;

// This is a faux onDeviceReady for browser scenario, mostly for code symmetry and fail-safe.

dev.onDeviceReadyBrowser = function() {
    dev.isDeviceReady.f_browser_ready__ = dev.timeStamp() ;
    var fName = "dev.onDeviceReadyBrowser():" ;
    console.log(fName, dev.isDeviceReady.f_browser_ready__) ;
    window.setTimeout(dev.onDeviceReady, dev.INSURANCE) ;
} ;

// Runs after document is loaded, and sets up wait for native (device) init to finish.
// If we're running in a browser we're ready to go when document is loaded, but...
// if we're running on a device we need to wait for native code to finish its init.

// NOTE: In most cases, you can leave this code alone and use it as is.

dev.initDeviceReady = function() {
    var fName = "dev.initDeviceReady():" ;
    console.log(fName, "entry") ;

    // Useful for debug and understanding initialization flow.
    if( dev.isDeviceReady.b_fnDocumentReady ) {
        console.log(fName, "function terminated") ;
        return ;
    } else {
        dev.isDeviceReady.b_fnDocumentReady = dev.timeStamp() ;
    }

    document.addEventListener("intel.xdk.device.ready", dev.onDeviceReadyXDK, false) ;
    document.addEventListener("deviceready", dev.onDeviceReadyCordova, false) ;
    window.setTimeout(dev.onDeviceReadyBrowser, dev.BROWSER) ;

    // Last one, above, is fail-safe, in case we got no device ready event from Cordova or XDK.
    // Cordova will timeout after five seconds, so we use a longer timeout to be conservative.
    // Very end of this file includes a "fail-safe, fail-safe" in case all else fails!

    // TODO: might want to double-check for Cordova deviceready, shouldn't be required...
    // "if" logic (below) needs further investigation in Cordova, legacy and debug containers
    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
    // if( window.channel && channel.onCordovaReady && (channel.onCordovaReady.state === 2) )
    //     dev.onDeviceReadyCordova() ;

    console.log(fName, "navigator.vendor:", navigator.vendor) ;
    console.log(fName, "navigator.platform:", navigator.platform) ;
    console.log(fName, "navigator.userAgent:", navigator.userAgent) ;

    console.log(fName, "exit") ;
} ;

// Wait for document ready before looking for device ready.
// This insures the app does not start running until DOM is ready and...
// ...makes it easier to deal with both in-browser and on-device scenarios and...
// ...makes it easier to init device-dependent and device-independent code in one place.

// NOTE: In most cases, you can leave this code alone and use it as is.
// NOTE: document.readyState seems to be more reliable, but seems not to be omnipresent.
// NOTE: Delay after "load" event is added because some webviews appear to trigger prematurely.

if( document.readyState ) {                     // some devices don't support this, why???
    console.log("document.readyState:", document.readyState) ;
    document.onreadystatechange = function () {
        console.log("document.readyState:", document.readyState) ;
        if (document.readyState === "complete") {
            dev.initDeviceReady() ;             // call when document is "ready ready" :)
        }
    } ;
}
console.log("addEventListener:", dev.timeStamp()) ;
window.addEventListener("load", function(){window.setTimeout(dev.initDeviceReady,dev.WINDOW_LOAD);}.bind(dev), false) ;
window.setTimeout(dev.initDeviceReady, dev.FAIL_SAFE) ;     // fail-safe fail-safe, just in case we miss all events!
<|endoftext|>


<commit_before>import Page from './Page';
import Global from './global';

class FlexTab extends Page {
	// Channel Info Tab
	get channelTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--info-circled'); }
	get channelSettings() { return browser.element('.channel-settings'); }
	get archiveBtn() { return browser.element('.clearfix:last-child .icon-pencil'); }
	get archiveRadio() { return browser.element('.editing'); }
	get archiveSave() { return browser.element('.save'); }
	get editNameBtn() { return browser.element('[data-edit="name"]'); }
	get editTopicBtn() { return browser.element('[data-edit="topic"]'); }
	get editAnnouncementBtn() { return browser.element('[data-edit="announcement"]'); }
	get editDescriptionBtn() { return browser.element('[data-edit="description"]'); }
	get editNotificationBtn() { return browser.element('[data-edit="desktopNotifications"]'); }
	get editMobilePushBtn() { return browser.element('[data-edit="mobilePushNotifications"]'); }
	get editEmailNotificationBtn() { return browser.element('[data-edit="emailNotifications"]'); }
	get editUnreadAlertBtn() { return browser.element('[data-edit="unreadAlert"]'); }
	get editNameTextInput() { return browser.element('.channel-settings input[name="name"]'); }
	get editTopicTextInput() { return browser.element('.channel-settings input[name="topic"]'); }
	get editAnnouncementTextInput() { return browser.element('.channel-settings input[name="announcement"]'); }
	get editDescriptionTextInput() { return browser.element('.channel-settings input[name="description"]'); }
	get editNameSave() { return browser.element('.channel-settings .save'); }

	// Members Tab
	get membersTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--team'); }
	get membersTabContent() { return browser.element('.animated'); }
	get userSearchBar() { return browser.element('#user-add-search'); }
	get removeUserBtn() { return browser.element('.remove-user'); }
	get setOwnerBtn() { return browser.element('.set-owner'); }
	get setModeratorBtn() { return browser.element('.set-moderator'); }
	get muteUserBtn() { return browser.element('.mute-user'); }
	get viewAllBtn() { return browser.element('.button.back'); }
	get startVideoCall() { return browser.element('.start-video-call'); }
	get startAudioCall() { return browser.element('.start-audio-call'); }
	get showAll() { return browser.element('.see-all'); }
	get membersUserInfo() { return browser.element('.flex-tab-container .info'); }
	get avatarImage() { return browser.element('.flex-tab-container .avatar-image'); }
	get memberUserName() { return browser.element('.info h3'); }
	get memberRealName() { return browser.element('.info p'); }

	// Search Tab
	get searchTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--magnifier'); }
	get searchTabContent() { return browser.element('.search-messages-list'); }
	get messageSearchBar() { return browser.element('#message-search'); }
	get searchResult() { return browser.element('.new-day'); }

	// Notifications Tab
	get notificationsTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--bell'); }
	get notificationsSettings() { return browser.element('.push-notifications'); }

	// Files Tab
	get filesTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--clip'); }
	get fileItem() { return browser.element('.uploaded-files-list ul:first-child'); }
	get filesTabContent() { return browser.element('.uploaded-files-list'); }
	get fileDelete() { return browser.element('.uploaded-files-list ul:first-child .file-delete'); }
	get fileDownload() { return browser.element('.uploaded-files-list ul:first-child .file-download'); }
	get fileName() { return browser.element('.uploaded-files-list ul:first-child .room-file-item'); }

	// Mentions Tab
	get mentionsTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--at'); }
	get mentionsTabContent() { return browser.element('.mentioned-messages-list'); }

	// Starred Tab
	get starredTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--star'); }
	get starredTabContent() { return browser.element('.starred-messages-list'); }

	// Pinned Tab
	get pinnedTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--pin'); }
	get pinnedTabContent() { return browser.element('.pinned-messages-list'); }

	get firstSetting() { return browser.element('.clearfix li:nth-child(1) .current-setting'); }
	get secondSetting() { return browser.element('.clearfix li:nth-child(2) .current-setting'); }
	get thirdSetting() { return browser.element('.clearfix li:nth-child(3) .current-setting'); }
	get fourthSetting() { return browser.element('.clearfix li:nth-child(4) .current-setting'); }

	//admin view flextab items
	get usersSendInvitationTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--paper-plane'); }
	get usersAddUserTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--plus'); }
	get usersSendInvitationTextArea() { return browser.element('#inviteEmails'); }
	get usersButtonCancel() { return browser.element('button.cancel'); }
	get usersSendInvitationSend() { return browser.element('button.send'); }
	get usersButtonSave() { return browser.element('button.save'); }
	get usersAddUserName() { return browser.element('#name'); }
	get usersAddUserUsername() { return browser.element('#username'); }
	get usersAddUserEmail() { return browser.element('#email'); }
	get usersAddUserRoleList() { return browser.element('#roleSelect'); }
	get usersAddUserPassword() { return browser.element('#password'); }
	get usersAddUserRoleButton() { return browser.element('#addRole'); }
	get usersAddUserVerifiedCheckbox() { return browser.element('#verified'); }
	get usersAddUserChangePasswordCheckbox() { return browser.element('#changePassword'); }
	get usersAddUserDefaultChannelCheckbox() { return browser.element('#joinDefaultChannels'); }
	get usersAddUserWelcomeEmailCheckbox() { return browser.element('#sendWelcomeEmail'); }
	get usersAddUserRandomPassword() { return browser.element('#randomPassword'); }
	get emojiNewAliases() { return browser.element('#aliases'); }
	get emojiNewImageInput() { return browser.element('#image'); }
	get usersView() { return browser.element('.user-view'); }
	get usersEditUser() { return browser.element('.user-view .edit-user'); }
	get usersActivate() { return browser.element('.button.activate'); }
	get usersDeactivate() { return browser.element('.button.deactivate'); }

	getUserEl(username) { return browser.element(`.flex-tab button[title="${ username }"] > p`); }

	archiveChannel() {
		this.archiveBtn.waitForVisible();
		this.archiveBtn.click();
		this.archiveRadio.waitForVisible();
		this.archiveRadio.click();
		this.archiveSave.click();
	}

	addPeopleToChannel(user) {
		this.userSearchBar.waitForVisible();
		this.userSearchBar.setValue(user);
		browser.waitForVisible('.-autocomplete-item', 5000);
		browser.click('.-autocomplete-item');
	}

	removePeopleFromChannel(user) {
		this.enterUserView(user);
		this.removeUserBtn.waitForVisible(5000);
		this.removeUserBtn.click();
	}

	addRole(role) {
		this.usersAddUserRoleList.waitForVisible(5000);
		this.usersAddUserRoleList.click();
		browser.waitForVisible(`option[value=${ role }]`, 5000);
		browser.click(`option[value=${ role }]`);
		this.usersAddUserRoleButton.waitForVisible(5000);
		this.usersAddUserRoleButton.click();
		browser.waitForVisible(`.remove-role=${ role }`);
	}

	operateFlexTab(desiredTab, desiredState) {
		//desiredState true=open false=closed
		switch (desiredTab) {
			case 'info':
				if ((!this.channelSettings.isVisible() && desiredState) || (this.channelSettings.isVisible() && !desiredState)) {
					this.channelTab.waitForVisible(5000);
					this.channelTab.click();
					this.channelSettings.waitForVisible(5000, !desiredState);
				}
				break;

			case 'search':
				if ((!this.messageSearchBar.isVisible() && desiredState) || (this.messageSearchBar.isVisible() && !desiredState)) {
					this.searchTab.waitForVisible(5000);
					this.searchTab.click();
					this.messageSearchBar.waitForVisible(5000, !desiredState);
				}
				break;

			case 'members':
				if ((!this.avatarImage.isVisible() && desiredState) || (this.userSearchBar.isVisible() && !desiredState)) {
					this.membersTab.waitForVisible(5000);
					this.membersTab.click();
					this.avatarImage.waitForVisible(5000, !desiredState);
				}
				break;

			case 'notifications':
				if ((!this.notificationsSettings.isVisible() && desiredState) || (this.notificationsSettings.isVisible() && !desiredState)) {
					this.notificationsTab.waitForVisible(5000);
					this.notificationsTab.click();
					this.notificationsSettings.waitForVisible(5000, !desiredState);
				}
				break;
			case 'files':
				if ((!this.filesTabContent.isVisible() && desiredState) || (this.filesTabContent.isVisible() && !desiredState)) {
					this.filesTab.waitForVisible(5000);
					this.filesTab.click();
					this.filesTabContent.waitForVisible(5000, !desiredState);
				}
				break;

			case 'mentions':
				if ((!this.mentionsTabContent.isVisible() && desiredState) || (this.mentionsTabContent.isVisible() && !desiredState)) {
					this.mentionsTab.waitForVisible(5000);
					this.mentionsTab.click();
					this.mentionsTabContent.waitForVisible(5000, !desiredState);
				}
				break;

			case 'starred':
				if ((!this.starredTabContent.isVisible() && desiredState) || (this.starredTabContent.isVisible() && !desiredState)) {
					this.starredTab.waitForVisible(5000);
					this.starredTab.click();
					this.starredTabContent.waitForVisible(5000, !desiredState);
				}
				break;

			case 'pinned':
				if ((!this.pinnedTabContent.isVisible() && desiredState) || (this.pinnedTabContent.isVisible() && !desiredState)) {
					this.pinnedTab.waitForVisible(5000);
					this.pinnedTab.click();
					this.pinnedTabContent.waitForVisible(5000, !desiredState);
				}
				break;
		}
	}

	setUserOwner(user) {
		this.enterUserView(user);
		this.setOwnerBtn.waitForVisible(5000);
		this.setOwnerBtn.click();
		this.viewAllBtn.click();
		browser.pause(100);
	}

	setUserModerator(user) {
		this.enterUserView(user);
		this.setModeratorBtn.waitForVisible();
		this.setModeratorBtn.click();
		this.viewAllBtn.click();
		browser.pause(100);
	}

	muteUser(user) {
		this.enterUserView(user);
		this.muteUserBtn.waitForVisible(5000);
		this.muteUserBtn.click();
		Global.confirmPopup();
		this.viewAllBtn.click();
		browser.pause(100);
	}

	enterUserView(user) {
		if (!this.membersUserInfo.isVisible()) {
			const userEl = this.getUserEl(user);
			userEl.waitForVisible();
			userEl.click();
		}
	}
}

module.exports = new FlexTab();
<commit_msg>fix tests again<commit_after>import Page from './Page';
import Global from './global';

class FlexTab extends Page {
	// Channel Info Tab
	get channelTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--info-circled'); }
	get channelSettings() { return browser.element('.channel-settings'); }
	get archiveBtn() { return browser.element('.clearfix:last-child .icon-pencil'); }
	get archiveRadio() { return browser.element('.editing'); }
	get archiveSave() { return browser.element('.save'); }
	get editNameBtn() { return browser.element('[data-edit="name"]'); }
	get editTopicBtn() { return browser.element('[data-edit="topic"]'); }
	get editAnnouncementBtn() { return browser.element('[data-edit="announcement"]'); }
	get editDescriptionBtn() { return browser.element('[data-edit="description"]'); }
	get editNotificationBtn() { return browser.element('[data-edit="desktopNotifications"]'); }
	get editMobilePushBtn() { return browser.element('[data-edit="mobilePushNotifications"]'); }
	get editEmailNotificationBtn() { return browser.element('[data-edit="emailNotifications"]'); }
	get editUnreadAlertBtn() { return browser.element('[data-edit="unreadAlert"]'); }
	get editNameTextInput() { return browser.element('.channel-settings input[name="name"]'); }
	get editTopicTextInput() { return browser.element('.channel-settings input[name="topic"]'); }
	get editAnnouncementTextInput() { return browser.element('.channel-settings input[name="announcement"]'); }
	get editDescriptionTextInput() { return browser.element('.channel-settings input[name="description"]'); }
	get editNameSave() { return browser.element('.channel-settings .save'); }

	// Members Tab
	get membersTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--team'); }
	get membersTabContent() { return browser.element('.animated'); }
	get userSearchBar() { return browser.element('#user-add-search'); }
	get removeUserBtn() { return browser.element('.remove-user'); }
	get setOwnerBtn() { return browser.element('.set-owner'); }
	get setModeratorBtn() { return browser.element('.set-moderator'); }
	get muteUserBtn() { return browser.element('.mute-user'); }
	get viewAllBtn() { return browser.element('.button.back'); }
	get startVideoCall() { return browser.element('.start-video-call'); }
	get startAudioCall() { return browser.element('.start-audio-call'); }
	get showAll() { return browser.element('.see-all'); }
	get membersUserInfo() { return browser.element('.flex-tab-container .info'); }
	get avatarImage() { return browser.element('.flex-tab-container .avatar-image'); }
	get memberUserName() { return browser.element('.info h3'); }
	get memberRealName() { return browser.element('.info p'); }

	// Search Tab
	get searchTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--magnifier'); }
	get searchTabContent() { return browser.element('.search-messages-list'); }
	get messageSearchBar() { return browser.element('#message-search'); }
	get searchResult() { return browser.element('.new-day'); }

	// Notifications Tab
	get notificationsTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--bell'); }
	get notificationsSettings() { return browser.element('.push-notifications'); }

	// Files Tab
	get filesTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--clip'); }
	get fileItem() { return browser.element('.uploaded-files-list ul:first-child'); }
	get filesTabContent() { return browser.element('.uploaded-files-list'); }
	get fileDelete() { return browser.element('.uploaded-files-list ul:first-child .file-delete'); }
	get fileDownload() { return browser.element('.uploaded-files-list ul:first-child .file-download'); }
	get fileName() { return browser.element('.uploaded-files-list ul:first-child .room-file-item'); }

	// Mentions Tab
	get mentionsTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--at'); }
	get mentionsTabContent() { return browser.element('.mentioned-messages-list'); }

	// Starred Tab
	get starredTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--star'); }
	get starredTabContent() { return browser.element('.starred-messages-list'); }

	// Pinned Tab
	get pinnedTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--pin'); }
	get pinnedTabContent() { return browser.element('.pinned-messages-list'); }

	get firstSetting() { return browser.element('.clearfix li:nth-child(1) .current-setting'); }
	get secondSetting() { return browser.element('.clearfix li:nth-child(2) .current-setting'); }
	get thirdSetting() { return browser.element('.clearfix li:nth-child(3) .current-setting'); }
	get fourthSetting() { return browser.element('.clearfix li:nth-child(4) .current-setting'); }

	//admin view flextab items
	get usersSendInvitationTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--send'); }
	get usersAddUserTab() { return browser.element('.tab-button:not(.hidden) .tab-button-icon--plus'); }
	get usersSendInvitationTextArea() { return browser.element('#inviteEmails'); }
	get usersButtonCancel() { return browser.element('button.cancel'); }
	get usersSendInvitationSend() { return browser.element('button.send'); }
	get usersButtonSave() { return browser.element('button.save'); }
	get usersAddUserName() { return browser.element('#name'); }
	get usersAddUserUsername() { return browser.element('#username'); }
	get usersAddUserEmail() { return browser.element('#email'); }
	get usersAddUserRoleList() { return browser.element('#roleSelect'); }
	get usersAddUserPassword() { return browser.element('#password'); }
	get usersAddUserRoleButton() { return browser.element('#addRole'); }
	get usersAddUserVerifiedCheckbox() { return browser.element('#verified'); }
	get usersAddUserChangePasswordCheckbox() { return browser.element('#changePassword'); }
	get usersAddUserDefaultChannelCheckbox() { return browser.element('#joinDefaultChannels'); }
	get usersAddUserWelcomeEmailCheckbox() { return browser.element('#sendWelcomeEmail'); }
	get usersAddUserRandomPassword() { return browser.element('#randomPassword'); }
	get emojiNewAliases() { return browser.element('#aliases'); }
	get emojiNewImageInput() { return browser.element('#image'); }
	get usersView() { return browser.element('.user-view'); }
	get usersEditUser() { return browser.element('.user-view .edit-user'); }
	get usersActivate() { return browser.element('.button.activate'); }
	get usersDeactivate() { return browser.element('.button.deactivate'); }

	getUserEl(username) { return browser.element(`.flex-tab button[title="${ username }"] > p`); }

	archiveChannel() {
		this.archiveBtn.waitForVisible();
		this.archiveBtn.click();
		this.archiveRadio.waitForVisible();
		this.archiveRadio.click();
		this.archiveSave.click();
	}

	addPeopleToChannel(user) {
		this.userSearchBar.waitForVisible();
		this.userSearchBar.setValue(user);
		browser.waitForVisible('.-autocomplete-item', 5000);
		browser.click('.-autocomplete-item');
	}

	removePeopleFromChannel(user) {
		this.enterUserView(user);
		this.removeUserBtn.waitForVisible(5000);
		this.removeUserBtn.click();
	}

	addRole(role) {
		this.usersAddUserRoleList.waitForVisible(5000);
		this.usersAddUserRoleList.click();
		browser.waitForVisible(`option[value=${ role }]`, 5000);
		browser.click(`option[value=${ role }]`);
		this.usersAddUserRoleButton.waitForVisible(5000);
		this.usersAddUserRoleButton.click();
		browser.waitForVisible(`.remove-role=${ role }`);
	}

	operateFlexTab(desiredTab, desiredState) {
		//desiredState true=open false=closed
		switch (desiredTab) {
			case 'info':
				if ((!this.channelSettings.isVisible() && desiredState) || (this.channelSettings.isVisible() && !desiredState)) {
					this.channelTab.waitForVisible(5000);
					this.channelTab.click();
					this.channelSettings.waitForVisible(5000, !desiredState);
				}
				break;

			case 'search':
				if ((!this.messageSearchBar.isVisible() && desiredState) || (this.messageSearchBar.isVisible() && !desiredState)) {
					this.searchTab.waitForVisible(5000);
					this.searchTab.click();
					this.messageSearchBar.waitForVisible(5000, !desiredState);
				}
				break;

			case 'members':
				if ((!this.avatarImage.isVisible() && desiredState) || (this.userSearchBar.isVisible() && !desiredState)) {
					this.membersTab.waitForVisible(5000);
					this.membersTab.click();
					this.avatarImage.waitForVisible(5000, !desiredState);
				}
				break;

			case 'notifications':
				if ((!this.notificationsSettings.isVisible() && desiredState) || (this.notificationsSettings.isVisible() && !desiredState)) {
					this.notificationsTab.waitForVisible(5000);
					this.notificationsTab.click();
					this.notificationsSettings.waitForVisible(5000, !desiredState);
				}
				break;
			case 'files':
				if ((!this.filesTabContent.isVisible() && desiredState) || (this.filesTabContent.isVisible() && !desiredState)) {
					this.filesTab.waitForVisible(5000);
					this.filesTab.click();
					this.filesTabContent.waitForVisible(5000, !desiredState);
				}
				break;

			case 'mentions':
				if ((!this.mentionsTabContent.isVisible() && desiredState) || (this.mentionsTabContent.isVisible() && !desiredState)) {
					this.mentionsTab.waitForVisible(5000);
					this.mentionsTab.click();
					this.mentionsTabContent.waitForVisible(5000, !desiredState);
				}
				break;

			case 'starred':
				if ((!this.starredTabContent.isVisible() && desiredState) || (this.starredTabContent.isVisible() && !desiredState)) {
					this.starredTab.waitForVisible(5000);
					this.starredTab.click();
					this.starredTabContent.waitForVisible(5000, !desiredState);
				}
				break;

			case 'pinned':
				if ((!this.pinnedTabContent.isVisible() && desiredState) || (this.pinnedTabContent.isVisible() && !desiredState)) {
					this.pinnedTab.waitForVisible(5000);
					this.pinnedTab.click();
					this.pinnedTabContent.waitForVisible(5000, !desiredState);
				}
				break;
		}
	}

	setUserOwner(user) {
		this.enterUserView(user);
		this.setOwnerBtn.waitForVisible(5000);
		this.setOwnerBtn.click();
		this.viewAllBtn.click();
		browser.pause(100);
	}

	setUserModerator(user) {
		this.enterUserView(user);
		this.setModeratorBtn.waitForVisible();
		this.setModeratorBtn.click();
		this.viewAllBtn.click();
		browser.pause(100);
	}

	muteUser(user) {
		this.enterUserView(user);
		this.muteUserBtn.waitForVisible(5000);
		this.muteUserBtn.click();
		Global.confirmPopup();
		this.viewAllBtn.click();
		browser.pause(100);
	}

	enterUserView(user) {
		if (!this.membersUserInfo.isVisible()) {
			const userEl = this.getUserEl(user);
			userEl.waitForVisible();
			userEl.click();
		}
	}
}

module.exports = new FlexTab();
<|endoftext|>


<commit_before><commit_msg>Add message to loading template to inform users about long delay<commit_after><|endoftext|>


<commit_before>function processData(input) {
    console.log("Hello World!");
}

process.stdin.resume();
process.stdin.setEncoding("ascii");
_input = "";
process.stdin.on("data", function (input) {
    _input += input;
});

process.stdin.on("end", function () {
    processData(_input);
});
<commit_msg>Update day1-helloWorld.js<commit_after>"use strict";

function processData() {
    console.log("Hello World!");
}

process.stdin.resume();
process.stdin.setEncoding("ascii");
var _input = "";
process.stdin.on("data", function (input) {
    _input += input;
});

process.stdin.on("end", function () {
    processData(_input);
});
<|endoftext|>


<commit_before>/**
 * Utility functions.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

'use strict';

const Utils = {
  /**
   * @param {String} str
   * @return {String} the string with the first letter capitalized
   */
  capitalize: function(str) {
    return str[0].toUpperCase() + str.substr(1);
  },
  escapeHtml: function(text) {
    if (typeof (text) !== 'string') {
      text = `${text}`;
    }

    return text
      .replace(/&/g, '&')
      .replace(/</g, '<')
      .replace(/>/g, '>')
      .replace(/"/g, '"')
      .replace(/'/g, ''')
      .replace(/°/g, '°');
  },
  escapeHtmlForIdClass: function(text) {
    if (typeof (text) !== 'string') {
      text = `${text}`;
    }

    text = text.replace(/[^_a-zA-Z0-9-]/g, '_');
    if (/^[0-9-]/.test(text)) {
      text = `_${text}`;
    }

    return text;
  },
  fuzzyTime: function(date) {
    const now = new Date();
    const delta = Math.round((now - date) / 1000);

    const minute = 60;
    const hour = minute * 60;
    const day = hour * 24;
    const week = day * 7;
    const month = day * 30;
    const year = day * 365;

    let fuzzy;
    if (delta < 5) {
      fuzzy = 'now';
    } else if (delta < minute) {
      fuzzy = `${delta} secs ago`;
    } else if (delta < 2 * minute) {
      fuzzy = '1 min ago';
    } else if (delta < hour) {
      fuzzy = `${Math.floor(delta / minute)} mins ago`;
    } else if (delta < 2 * hour) {
      fuzzy = '1 hour ago';
    } else if (delta < day) {
      fuzzy = `${Math.floor(delta / hour)} hours ago`;
    } else if (delta < 2 * day) {
      fuzzy = '1 day ago';
    } else if (delta < week) {
      fuzzy = `${Math.floor(delta / day)} days ago`;
    } else if (delta < 2 * week) {
      fuzzy = '1 week ago';
    } else if (delta < month) {
      fuzzy = `${Math.floor(delta / week)} weeks ago`;
    } else if (delta < 2 * month) {
      fuzzy = '1 month ago';
    } else if (delta < year) {
      fuzzy = `${Math.floor(delta / month)} months ago`;
    } else if (delta < 2 * year) {
      fuzzy = '1 year ago';
    } else {
      fuzzy = `${Math.floor(delta / year)} years ago`;
    }

    return fuzzy;
  },
  debounce: function(delay, callback) {
    return Utils.throttle(delay, callback, true);
  },
  throttle: function(delay, callback, debounceMode = false) {
    let timeout = null;
    let lastExec = 0;
    const throttleMode = !debounceMode;

    return function wrapper() {
      const elapsed = Number(new Date()) - lastExec;
      const args = arguments;

      const exec = () => {
        lastExec = Number(new Date());
        callback(args);
      };

      if (timeout) {
        clearTimeout(timeout);
      }

      if (throttleMode === true && elapsed > delay) {
        exec();
      } else {
        timeout = setTimeout(exec, debounceMode ? delay : delay - elapsed);
      }
    };
  },
  unitNameToAbbreviation: function(unit) {
    switch (unit.toLowerCase()) {
      case 'volt':
      case 'volts':
        return 'V';

      case 'hertz':
        return 'Hz';

      case 'amp':
      case 'amps':
      case 'ampere':
      case 'amperes':
        return 'A';

      case 'watt':
      case 'watts':
        return 'W';

      case 'percent':
        return '%';

      case 'fahrenheit':
        return '°F';

      case 'celsius':
        return '°C';

      case 'kelvin':
        return 'K';

      case 'meter':
      case 'meters':
      case 'metre':
      case 'metres':
        return 'm';

      case 'day':
      case 'days':
        return 'd';

      case 'hour':
      case 'hours':
        return 'h';

      case 'minute':
      case 'minutes':
        return 'min';

      case 'second':
      case 'seconds':
        return 's';

      case 'millisecond':
      case 'milliseconds':
        return 'ms';

      default:
        return unit;
    }
  },
  colorTemperatureToRGB: function(value) {
    /**
     * Algorithm found here:
     * http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
     */
    value /= 100;

    let r;
    if (value <= 66) {
      r = 255;
    } else {
      r = value - 60;
      r = 329.698727446 * Math.pow(r, -0.1332047592);
      r = Math.max(r, 0);
      r = Math.min(r, 255);
    }

    let g;
    if (value <= 66) {
      g = value;
      g = 99.4708025861 * Math.log(g) - 161.1195681661;
    } else {
      g = value - 60;
      g = 288.1221695283 * Math.pow(g, -0.0755148492);
    }

    g = Math.max(g, 0);
    g = Math.min(g, 255);

    let b;
    if (value >= 66) {
      b = 255;
    } else if (value <= 19) {
      b = 0;
    } else {
      b = value - 10;
      b = 138.5177312231 * Math.log(b) - 305.0447927307;
      b = Math.max(b, 0);
      b = Math.min(b, 255);
    }

    r = Math.round(r).toString(16);
    g = Math.round(g).toString(16);
    b = Math.round(b).toString(16);

    return `#${r}${g}${b}`;
  },
  legacyTypeToCapabilities: function(type) {
    switch (type) {
      case 'binarySensor':
        return ['BinarySensor'];
      case 'multiLevelSensor':
        // legacy multiLevelSensor includes an 'on' member
        return ['BinarySensor', 'MultiLevelSensor'];
      case 'onOffLight':
      case 'dimmableLight':
        return ['OnOffSwitch', 'Light'];
      case 'onOffColorLight':
      case 'dimmableColorLight':
        return ['OnOffSwitch', 'Light', 'ColorControl'];
      case 'multiLevelSwitch':
        return ['OnOffSwitch', 'MultiLevelSwitch'];
      case 'onOffSwitch':
        return ['OnOffSwitch'];
      case 'smartPlug':
        return ['OnOffSwitch', 'SmartPlug', 'EnergyMonitor'];
      default:
        return [];
    }
  },
  sortCapabilities: function(capabilities) {
    // copy the array, as we're going to sort in place.
    const list = capabilities.slice();

    const priority = [
      'SmartPlug',
      'Light',
      'MultiLevelSwitch',
      'OnOffSwitch',
      'ColorControl',
      'EnergyMonitor',
      'DoorSensor',
      'MotionSensor',
      'PushButton',
      'MultiLevelSensor',
      'BinarySensor',
    ];

    list.sort((a, b) => {
      if (!priority.includes(a) && !priority.includes(b)) {
        return 0;
      } else if (!priority.includes(a)) {
        return 1;
      } else if (!priority.includes(b)) {
        return -1;
      }

      return priority.indexOf(a) - priority.indexOf(b);
    });

    return list;
  },
};

module.exports = Utils;
<commit_msg>Add support for updated degree units. (#1489)<commit_after>/**
 * Utility functions.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

'use strict';

const Utils = {
  /**
   * @param {String} str
   * @return {String} the string with the first letter capitalized
   */
  capitalize: function(str) {
    return str[0].toUpperCase() + str.substr(1);
  },
  escapeHtml: function(text) {
    if (typeof (text) !== 'string') {
      text = `${text}`;
    }

    return text
      .replace(/&/g, '&')
      .replace(/</g, '<')
      .replace(/>/g, '>')
      .replace(/"/g, '"')
      .replace(/'/g, ''')
      .replace(/°/g, '°');
  },
  escapeHtmlForIdClass: function(text) {
    if (typeof (text) !== 'string') {
      text = `${text}`;
    }

    text = text.replace(/[^_a-zA-Z0-9-]/g, '_');
    if (/^[0-9-]/.test(text)) {
      text = `_${text}`;
    }

    return text;
  },
  fuzzyTime: function(date) {
    const now = new Date();
    const delta = Math.round((now - date) / 1000);

    const minute = 60;
    const hour = minute * 60;
    const day = hour * 24;
    const week = day * 7;
    const month = day * 30;
    const year = day * 365;

    let fuzzy;
    if (delta < 5) {
      fuzzy = 'now';
    } else if (delta < minute) {
      fuzzy = `${delta} secs ago`;
    } else if (delta < 2 * minute) {
      fuzzy = '1 min ago';
    } else if (delta < hour) {
      fuzzy = `${Math.floor(delta / minute)} mins ago`;
    } else if (delta < 2 * hour) {
      fuzzy = '1 hour ago';
    } else if (delta < day) {
      fuzzy = `${Math.floor(delta / hour)} hours ago`;
    } else if (delta < 2 * day) {
      fuzzy = '1 day ago';
    } else if (delta < week) {
      fuzzy = `${Math.floor(delta / day)} days ago`;
    } else if (delta < 2 * week) {
      fuzzy = '1 week ago';
    } else if (delta < month) {
      fuzzy = `${Math.floor(delta / week)} weeks ago`;
    } else if (delta < 2 * month) {
      fuzzy = '1 month ago';
    } else if (delta < year) {
      fuzzy = `${Math.floor(delta / month)} months ago`;
    } else if (delta < 2 * year) {
      fuzzy = '1 year ago';
    } else {
      fuzzy = `${Math.floor(delta / year)} years ago`;
    }

    return fuzzy;
  },
  debounce: function(delay, callback) {
    return Utils.throttle(delay, callback, true);
  },
  throttle: function(delay, callback, debounceMode = false) {
    let timeout = null;
    let lastExec = 0;
    const throttleMode = !debounceMode;

    return function wrapper() {
      const elapsed = Number(new Date()) - lastExec;
      const args = arguments;

      const exec = () => {
        lastExec = Number(new Date());
        callback(args);
      };

      if (timeout) {
        clearTimeout(timeout);
      }

      if (throttleMode === true && elapsed > delay) {
        exec();
      } else {
        timeout = setTimeout(exec, debounceMode ? delay : delay - elapsed);
      }
    };
  },
  unitNameToAbbreviation: function(unit) {
    switch (unit.toLowerCase()) {
      case 'volt':
      case 'volts':
        return 'V';

      case 'hertz':
        return 'Hz';

      case 'amp':
      case 'amps':
      case 'ampere':
      case 'amperes':
        return 'A';

      case 'watt':
      case 'watts':
        return 'W';

      case 'percent':
        return '%';

      case 'degree fahrenheit':
      case 'degrees fahrenheit':
      case 'fahrenheit':
        return '°F';

      case 'degree celsius':
      case 'degrees celsius':
      case 'celsius':
        return '°C';

      case 'kelvin':
        return 'K';

      case 'meter':
      case 'meters':
      case 'metre':
      case 'metres':
        return 'm';

      case 'day':
      case 'days':
        return 'd';

      case 'hour':
      case 'hours':
        return 'h';

      case 'minute':
      case 'minutes':
        return 'min';

      case 'second':
      case 'seconds':
        return 's';

      case 'millisecond':
      case 'milliseconds':
        return 'ms';

      default:
        return unit;
    }
  },
  colorTemperatureToRGB: function(value) {
    /**
     * Algorithm found here:
     * http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
     */
    value /= 100;

    let r;
    if (value <= 66) {
      r = 255;
    } else {
      r = value - 60;
      r = 329.698727446 * Math.pow(r, -0.1332047592);
      r = Math.max(r, 0);
      r = Math.min(r, 255);
    }

    let g;
    if (value <= 66) {
      g = value;
      g = 99.4708025861 * Math.log(g) - 161.1195681661;
    } else {
      g = value - 60;
      g = 288.1221695283 * Math.pow(g, -0.0755148492);
    }

    g = Math.max(g, 0);
    g = Math.min(g, 255);

    let b;
    if (value >= 66) {
      b = 255;
    } else if (value <= 19) {
      b = 0;
    } else {
      b = value - 10;
      b = 138.5177312231 * Math.log(b) - 305.0447927307;
      b = Math.max(b, 0);
      b = Math.min(b, 255);
    }

    r = Math.round(r).toString(16);
    g = Math.round(g).toString(16);
    b = Math.round(b).toString(16);

    return `#${r}${g}${b}`;
  },
  legacyTypeToCapabilities: function(type) {
    switch (type) {
      case 'binarySensor':
        return ['BinarySensor'];
      case 'multiLevelSensor':
        // legacy multiLevelSensor includes an 'on' member
        return ['BinarySensor', 'MultiLevelSensor'];
      case 'onOffLight':
      case 'dimmableLight':
        return ['OnOffSwitch', 'Light'];
      case 'onOffColorLight':
      case 'dimmableColorLight':
        return ['OnOffSwitch', 'Light', 'ColorControl'];
      case 'multiLevelSwitch':
        return ['OnOffSwitch', 'MultiLevelSwitch'];
      case 'onOffSwitch':
        return ['OnOffSwitch'];
      case 'smartPlug':
        return ['OnOffSwitch', 'SmartPlug', 'EnergyMonitor'];
      default:
        return [];
    }
  },
  sortCapabilities: function(capabilities) {
    // copy the array, as we're going to sort in place.
    const list = capabilities.slice();

    const priority = [
      'SmartPlug',
      'Light',
      'MultiLevelSwitch',
      'OnOffSwitch',
      'ColorControl',
      'EnergyMonitor',
      'DoorSensor',
      'MotionSensor',
      'PushButton',
      'MultiLevelSensor',
      'BinarySensor',
    ];

    list.sort((a, b) => {
      if (!priority.includes(a) && !priority.includes(b)) {
        return 0;
      } else if (!priority.includes(a)) {
        return 1;
      } else if (!priority.includes(b)) {
        return -1;
      }

      return priority.indexOf(a) - priority.indexOf(b);
    });

    return list;
  },
};

module.exports = Utils;
<|endoftext|>


<commit_before>"use strict";

/*
BsTable - http://bs-table.com
Licensed under the MIT license

Copyright (c) 2014 Jan Holinka

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.
*/

angular.module("bsTable", [])
    .directive("bsTable", function () {
        return {
            restrict: "A",
            scope: true,
            compile: function (tElement, tAttrs) {
                // create thead for table
                var totalCols = 0,
                    tBody = tElement.find("tbody"),
                    tBodyRow = tBody.find("tr"),
                    ngRepeatAttr = tBodyRow.attr("ng-repeat") !== undefined ? tBodyRow.attr("ng-repeat") : tBody.attr("ng-repeat"),
                    ngRepeatExtension = " | bsTableSkip:bsTablePagination.skipAt | limitTo:bsTablePagination.pageSize";
                // set ng-repeat attribute
                tBodyRow.attr("ng-repeat") !== undefined ? tBodyRow.attr("ng-repeat", ngRepeatAttr + ngRepeatExtension) : tBody.attr("ng-repeat", ngRepeatAttr + ngRepeatExtension);
                // get total cols
                totalCols = tBodyRow.children("td").size();
                // create tfoot for table
                var footer = "
" +
                                "
" +
                                    "

" +
                                    "<select ng-model=\"bsTablePagination.pageSize\" class=\"form-control select-page-size\">" +
                                        "<option value=\"5\" selected=\"selected\">5</option>" +
                                        "<option value=\"10\">10</option>" +
                                        "<option value=\"20\">20</option><option value=\"40\">40</option></select>" +
                                    "	" +
                                "
" +
                             "
";
                // add tfoot to table
                tElement.append(footer);

                return {
                    pre: function (scope, linkElement) {
                        // get and set scope model
                        var grid = scope.bsTablePagination = {};
                        // create pagination for table
                        var pager = linkElement.children("tfoot").children("tr").children("td"),
                            collectionName = ngRepeatAttr.match(/^\s*(.+)\s+in\s+(.*)\s*$/)[2],
                            collection = scope.$eval(collectionName),
                            totalRows = collection.length;
                        // watch changes with collection
                        scope.$watchCollection(collectionName, function () {
                            // get total totalRows of rows
                            totalRows = scope.$eval(collectionName).length;
                            // set last page
                            grid.lastPage = Math.ceil(totalRows / grid.pageSize);
                            // recreate pagination
                            RenderPagination();
                        });
                        // watch changes with grid pageSize
                        scope.$watch("bsTablePagination.pageSize", function () {
                            // recreate pagination
                            RenderPagination();
                        });
                        // set grid properties
                        grid.pageSize = 5;
                        grid.lastPage = Math.ceil(totalRows / grid.pageSize);
                        grid.page = 1;
                        grid.skipAt = (grid.page - 1) * grid.pageSize;
                        // on page size change
                        pager.children(".select-page-size").change(function () {
                            // get current element
                            var gridLimit = parseInt($(this).val());
                            // update grid properties
                            grid.lastPage = Math.ceil(totalRows / gridLimit);
                            grid.page = 1;
                            grid.skipAt = (grid.page - 1) * gridLimit;
                            // process all $watch(es)
                            scope.$digest();
                        });
                        // render pagination function
                        var RenderPagination = function () {
                            // prepare empty string
                            var paging = "";
                            // create list items
                            for (var i = 0; i < Math.ceil(totalRows / scope.bsTablePagination.pageSize) ; i++) {
                                paging += "
" + (i + 1) + "
";
                            }
                            // add paging to tfoot of table
                            linkElement.find(".pagination").html(paging);
                            // add event to each list item
                            linkElement.find(".pagination").find("li").bind("click", ListenerPagination);
                        }
                        // pagination on click
                        var ListenerPagination = function () {
                            // get clicked value
                            var index = parseInt($(this).find("a").text());
                            // remove active class from all elements
                            $(this).parent().find("li").removeClass("active");
                            // add active class to clicked element
                            $(this).addClass("active");
                            // update grid properties
                            grid.page = index;
                            grid.skipAt = (grid.page - 1) * grid.pageSize;
                            // process all $watch(es)
                            scope.$digest();
                        };
                    }
                }
            }
        };
    })
    .filter("bsTableSkip", function () {
        return function (array, skipAt) {
            return array.slice(skipAt);
        };
    });
<commit_msg>Updated tr and tbody selector<commit_after>"use strict";

/*
BsTable - http://bs-table.com
Licensed under the MIT license

Copyright (c) 2014 Jan Holinka

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.
*/

angular.module("bsTable", [])
    .directive("bsTable", function () {
        return {
            restrict: "A",
            scope: true,
            compile: function (tElement, tAttrs) {
                // create thead for table
                var totalCols = 0,
                    tBody = tElement.find("tbody").first(),
                    tBodyRow = tBody.find("tr").first(),
                    ngRepeatAttr = tBodyRow.attr("ng-repeat") !== undefined ? tBodyRow.attr("ng-repeat") : tBody.attr("ng-repeat"),
                    ngRepeatExtension = " | bsTableSkip:bsTablePagination.skipAt | limitTo:bsTablePagination.pageSize";
                // set ng-repeat attribute
                tBodyRow.attr("ng-repeat") !== undefined ? tBodyRow.attr("ng-repeat", ngRepeatAttr + ngRepeatExtension) : tBody.attr("ng-repeat", ngRepeatAttr + ngRepeatExtension);
                // get total cols
                totalCols = tBodyRow.children("td").size();
                // create tfoot for table
                var footer = "
" +
                                "
" +
                                    "

" +
                                    "<select ng-model=\"bsTablePagination.pageSize\" class=\"form-control select-page-size\">" +
                                        "<option value=\"5\" selected=\"selected\">5</option>" +
                                        "<option value=\"10\">10</option>" +
                                        "<option value=\"20\">20</option><option value=\"40\">40</option></select>" +
                                    "	" +
                                "
" +
                             "
";
                // add tfoot to table
                tElement.append(footer);

                return {
                    pre: function (scope, linkElement) {
                        // get and set scope model
                        var grid = scope.bsTablePagination = {};
                        // create pagination for table
                        var pager = linkElement.children("tfoot").children("tr").children("td"),
                            collectionName = ngRepeatAttr.match(/^\s*(.+)\s+in\s+(.*)\s*$/)[2],
                            collection = scope.$eval(collectionName),
                            totalRows = collection.length;
                        // watch changes with collection
                        scope.$watchCollection(collectionName, function () {
                            // get total totalRows of rows
                            totalRows = scope.$eval(collectionName).length;
                            // set last page
                            grid.lastPage = Math.ceil(totalRows / grid.pageSize);
                            // recreate pagination
                            RenderPagination();
                        });
                        // watch changes with grid pageSize
                        scope.$watch("bsTablePagination.pageSize", function () {
                            // recreate pagination
                            RenderPagination();
                        });
                        // set grid properties
                        grid.pageSize = 5;
                        grid.lastPage = Math.ceil(totalRows / grid.pageSize);
                        grid.page = 1;
                        grid.skipAt = (grid.page - 1) * grid.pageSize;
                        // on page size change
                        pager.children(".select-page-size").change(function () {
                            // get current element
                            var gridLimit = parseInt($(this).val());
                            // update grid properties
                            grid.lastPage = Math.ceil(totalRows / gridLimit);
                            grid.page = 1;
                            grid.skipAt = (grid.page - 1) * gridLimit;
                            // process all $watch(es)
                            scope.$digest();
                        });
                        // render pagination function
                        var RenderPagination = function () {
                            // prepare empty string
                            var paging = "";
                            // create list items
                            for (var i = 0; i < Math.ceil(totalRows / scope.bsTablePagination.pageSize) ; i++) {
                                paging += "
" + (i + 1) + "
";
                            }
                            // add paging to tfoot of table
                            linkElement.find(".pagination").html(paging);
                            // add event to each list item
                            linkElement.find(".pagination").find("li").bind("click", ListenerPagination);
                        }
                        // pagination on click
                        var ListenerPagination = function () {
                            // get clicked value
                            var index = parseInt($(this).find("a").text());
                            // remove active class from all elements
                            $(this).parent().find("li").removeClass("active");
                            // add active class to clicked element
                            $(this).addClass("active");
                            // update grid properties
                            grid.page = index;
                            grid.skipAt = (grid.page - 1) * grid.pageSize;
                            // process all $watch(es)
                            scope.$digest();
                        };
                    }
                }
            }
        };
    })
    .filter("bsTableSkip", function () {
        return function (array, skipAt) {
            return array.slice(skipAt);
        };
    });
<|endoftext|>


<commit_before>var NewsTable = function () {
    this.tableId = '#news-table';

    this.table = $(this.tableId).DataTable({
        "oLanguage": {
          "sSearch": "Pesquisar "
        },
        "sAjaxSource": "/news/publication/all",
        "sAjaxDataProp": "publications",
        "order": [],
        "columnDefs": [
            {
                "targets": 0,
                "orderable": false,
                "className": "column-checkbox",
                "render": function (data, type, publication, meta){
                    var checkbox = '
' +
                                   '    <input name="selected-item" id="item'+publication[0]+'" value="'+publication[0]+'" type="checkbox">' +
                                   '    '
                                   '
';

                    return checkbox;
                }
            },
            {
                "targets": 1,
                "className": "column-title",
                "render": function (data, type, publication, meta){
                    return ''+publication[1]+'';
                }
            },
            {
                "targets": 4,
                "orderable": false,
                "className": "column-checkbox",
                "render": function (data, type, publication, meta){
                   return '<input type="checkbox" name="show_home" id="show_home'+publication[0]+
                   '" value="'+publication[0]+ (data ? '" checked>' : '" >');
                }
            },
            {
                "targets": 5,
                "orderable": false,
                "className": "column-checkbox",
                "render": function (data, type, publication, meta){
                   return '<input type="checkbox" name="active" id="active'+publication[0]+
                   '" value="'+publication[0]+ (data ? '" checked>' : '" >');
                }
            }],
        "paging": false,
        "bFilter": true,
        "info": false,
        "initComplete": function(settings, json) {
            $( 'input[name="show_home"]' ).each(function() {
                var switchery = new Switchery(this, {
                    size: 'small'
                });

                $(this).next().click(function() {
                    var checkbox = $(this).siblings().get(0);

                    var ids = [checkbox.value],
                        status = $(checkbox).attr('name'),
                        status_value = checkbox.checked;

                    changeStatus(ids, status, status_value);
                });
            });

            $( 'input[name="active"]' ).each(function() {
                var switchery = new Switchery(this, {
                    size: 'small',
                    color: '#5A9DC4'
                });

                $(this).next().click(function() {
                    var checkbox = $(this).siblings().get(0);

                    var ids = [checkbox.value],
                        status = $(checkbox).attr('name'),
                        status_value = checkbox.checked;

                    changeStatus(ids, status, status_value);
                });
            });

            $('input[name="selected-item"]').change(function() {
                checkManySelected();
            });
        }
    });

    $('#news-table thead tr th').first().addClass('check-all')

    $('#news-table .check-all').click(function() {
        var checked = $('#news-table .check-all input:checkbox').get(0).checked;
        $('input[name="selected-item"]').each(function() {
            $(this).prop('checked', checked);
        });
        checkManySelected();
    })
};

NewsTable.prototype.getCheckedIds = function(first_argument) {
    var checkedIds = [];
    $('#news-table input[name="selected-item"]').each(function() {
        if (this.checked) {
            checkedIds.push(this.value);
        }
    });
    return checkedIds;
};

var newsTable = new NewsTable();

var changeStatus = function(ids, status, status_value){
    if (ids.length) {
        $.ajax({
            method: "POST",
            url: "/"+lang+"/news/admin/publication/"+status+"/"+status_value,
            data: {ids:ids},
            statusCode: {
                500: function () {
                    showMessage('Não foi possível alterar a(s) notícia(s) selecionada(s) devido a um erro no servidor.', 'danger', 8000);
                },
                404: function () {
                    showMessage('Uma ou mais notícias selecionadas não puderam ser encontradas, a lista de notícias será atualizada.', 'info', 8000);
                    newsTable.table.fnReloadAjax();
                }
            },
            success: function (message) {
                for (item in ids) {
                    if ($('#'+status+ids[item])[0].checked !== status_value) {
                        $('#'+status+ids[item]).click();
                    }
                }

                showMessage(message, 'success', 8000);
            }
        });
    } else {
        showMessage('Por favor selecione algum post para alterar.', 'warning', 8000);
    }
}

var destroy = function(ids){
    if (ids.length) {
        $.ajax({
            method: "POST",
            url: "/"+lang+"/news/admin/delete",
            data: {ids:ids},
            statusCode: {
                500: function () {
                    showMessage('Não foi possível alterar a(s) notícia(s) selecionada(s) devido a um erro no servidor.', 'danger', 8000);
                },
                404: function () {
                    showMessage('Uma ou mais notícias selecionados não puderam ser encontradas, a lista de notícias será atualizada.', 'info', 8000);
                    newsTable.table.fnReloadAjax();
                }
            },
            success: function (message) {
                for (item in ids) {
                    itemId = '#item'+ids[item];
                    newsTable.table.row($(itemId).parents('tr')).remove().draw();
                }

                showMessage(message, 'success', 8000);
            }
        });
    } else {
        showMessage('Por favor selecione para excluir.', 'warning', 8000);
    }
}

var edit = function(ids){
    if (ids.length) {
        window.location = '/'+lang+'/news/admin/publication/'+ids[0]+'/edit';
    } else {
        showMessage('Por favor selecione para editar.', 'warning', 8000);
    }
}

var checkManySelected = function() {
    if (newsTable.getCheckedIds().length > 1) {
        $('#admin-edit').prop('disabled', true);
    } else {
        $('#admin-edit').prop('disabled', false);
    }
}

$(document).ready(function(){
    $('#admin-delete').click(function() {
        destroy(newsTable.getCheckedIds());
    });
    $('#admin-edit').click(function() {
        edit(newsTable.getCheckedIds());
    });
    $('#admin-activate').click(function() {
        changeStatus(newsTable.getCheckedIds(), 'active', true);
    });
    $('#admin-deactivate').click(function() {
        changeStatus(newsTable.getCheckedIds(), 'active', false);
    });

    setAlertTimeOut(8000);
});
<commit_msg>Updates label for checkbox in admin table.<commit_after>var NewsTable = function () {
    this.tableId = '#news-table';

    this.table = $(this.tableId).DataTable({
        "oLanguage": {
          "sSearch": "Pesquisar "
        },
        "sAjaxSource": "/news/publication/all",
        "sAjaxDataProp": "publications",
        "order": [[ 3, "desc" ]],
        "columnDefs": [
            {
                "targets": 0,
                "orderable": false,
                "className": "column-checkbox",
                "render": function (data, type, publication, meta){
                    var checkbox = '
' +
                                   '    <input name="selected-item" id="item'+publication[0]+'" value="'+publication[0]+'" type="checkbox">' +
                                   '    '
                                   '
';

                    return checkbox;
                }
            },
            {
                "targets": 1,
                "className": "column-title",
                "render": function (data, type, publication, meta){
                    return ''+publication[1]+'';
                }
            },
            {
                "targets": 4,
                "orderable": false,
                "className": "column-checkbox",
                "render": function (data, type, publication, meta){
                   return '<input type="checkbox" name="show_home" id="show_home'+publication[0]+
                   '" value="'+publication[0]+ (data ? '" checked>' : '" >');
                }
            },
            {
                "targets": 5,
                "orderable": false,
                "className": "column-checkbox",
                "render": function (data, type, publication, meta){
                   return '<input type="checkbox" name="active" id="active'+publication[0]+
                   '" value="'+publication[0]+ (data ? '" checked>' : '" >');
                }
            }],
        "paging": false,
        "bFilter": true,
        "info": false,
        "initComplete": function(settings, json) {
            $( 'input[name="show_home"]' ).each(function() {
                var switchery = new Switchery(this, {
                    size: 'small'
                });

                $(this).next().click(function() {
                    var checkbox = $(this).siblings().get(0);

                    var ids = [checkbox.value],
                        status = $(checkbox).attr('name'),
                        status_value = checkbox.checked;

                    changeStatus(ids, status, status_value);
                });
            });

            $( 'input[name="active"]' ).each(function() {
                var switchery = new Switchery(this, {
                    size: 'small',
                    color: '#5A9DC4'
                });

                $(this).next().click(function() {
                    var checkbox = $(this).siblings().get(0);

                    var ids = [checkbox.value],
                        status = $(checkbox).attr('name'),
                        status_value = checkbox.checked;

                    changeStatus(ids, status, status_value);
                });
            });

            $('input[name="selected-item"]').change(function() {
                checkManySelected();
            });
        }
    });

    $('#news-table thead tr th').first().addClass('check-all')

    $('#news-table .check-all').click(function() {
        var checked = $('#news-table .check-all input:checkbox').get(0).checked;
        $('input[name="selected-item"]').each(function() {
            $(this).prop('checked', checked);
        });
        checkManySelected();
    })
};

NewsTable.prototype.getCheckedIds = function(first_argument) {
    var checkedIds = [];
    $('#news-table input[name="selected-item"]').each(function() {
        if (this.checked) {
            checkedIds.push(this.value);
        }
    });
    return checkedIds;
};

var newsTable = new NewsTable();

var changeStatus = function(ids, status, status_value){
    if (ids.length) {
        $.ajax({
            method: "POST",
            url: "/"+lang+"/news/admin/publication/"+status+"/"+status_value,
            data: {ids:ids},
            statusCode: {
                500: function () {
                    showMessage('Não foi possível alterar a(s) notícia(s) selecionada(s) devido a um erro no servidor.', 'danger', 8000);
                },
                404: function () {
                    showMessage('Uma ou mais notícias selecionadas não puderam ser encontradas, a lista de notícias será atualizada.', 'info', 8000);
                    newsTable.table.fnReloadAjax();
                }
            },
            success: function (message) {
                for (item in ids) {
                    if ($('#'+status+ids[item])[0].checked !== status_value) {
                        $('#'+status+ids[item]).click();
                    }
                }

                showMessage(message, 'success', 8000);
            }
        });
    } else {
        showMessage('Por favor selecione algum post para alterar.', 'warning', 8000);
    }
}

var destroy = function(ids){
    if (ids.length) {
        $.ajax({
            method: "POST",
            url: "/"+lang+"/news/admin/delete",
            data: {ids:ids},
            statusCode: {
                500: function () {
                    showMessage('Não foi possível alterar a(s) notícia(s) selecionada(s) devido a um erro no servidor.', 'danger', 8000);
                },
                404: function () {
                    showMessage('Uma ou mais notícias selecionados não puderam ser encontradas, a lista de notícias será atualizada.', 'info', 8000);
                    newsTable.table.fnReloadAjax();
                }
            },
            success: function (message) {
                for (item in ids) {
                    itemId = '#item'+ids[item];
                    newsTable.table.row($(itemId).parents('tr')).remove().draw();
                }

                showMessage(message, 'success', 8000);
            }
        });
    } else {
        showMessage('Por favor selecione para excluir.', 'warning', 8000);
    }
}

var edit = function(ids){
    if (ids.length) {
        window.location = '/'+lang+'/news/admin/publication/'+ids[0]+'/edit';
    } else {
        showMessage('Por favor selecione para editar.', 'warning', 8000);
    }
}

var checkManySelected = function() {
    if (newsTable.getCheckedIds().length > 1) {
        $('#admin-edit').prop('disabled', true);
    } else {
        $('#admin-edit').prop('disabled', false);
    }
}

$(document).ready(function(){
    $('#admin-delete').click(function() {
        destroy(newsTable.getCheckedIds());
    });
    $('#admin-edit').click(function() {
        edit(newsTable.getCheckedIds());
    });
    $('#admin-activate').click(function() {
        changeStatus(newsTable.getCheckedIds(), 'active', true);
    });
    $('#admin-deactivate').click(function() {
        changeStatus(newsTable.getCheckedIds(), 'active', false);
    });

    setAlertTimeOut(8000);
});
<|endoftext|>


<commit_before>window.addComment = function (content, num, top, left) {
    if (content) {
        const commentElm = $(`

${content}

          ${num}

    `).addClass('comment').appendTo('body');
        commentElm.css({
            top: top,
            left: left,
        });

        commentElm.draggable();

        // 绑定like按钮
        $(document).on('click', '.like', function () {
            const likeElm = $(this);

            if (likeElm.attr('allowClick') === 'true') {
                const numElm = likeElm.next();
                numElm.html(parseInt(numElm.html(), 10) + 1);

                likeElm.attr('allowClick', 'false');
                likeElm.css({
                    'background-position': '0 30',
                    cursor: 'default',
                });
            }
        });

        // 绑定close按钮
        $(document).on('click', '.close', function () {
            $(this).parent().parent().parent().remove();
        });

        // like和close的显示隐藏
        commentElm.mouseenter(() => {
            commentElm.children('.action').css({
                display: 'inline-block',
            });
        });
        commentElm.mouseleave(() => {
            commentElm.children('.action').css({
                display: 'none',
            });
        });
    }
}

$(document).ready(() => {
    const endpoint_url = "http://hq.shisoft.net:8080/comment?url=" + encodeURIComponent(window.location.href);
    $.get(endpoint_url, null, function (res) {
        $(res).each(function (_, comment) {
            window.addComment(comment.text, 0, comment.y, comment.x);
        });
    }, "json");

    $(document).dblclick((event) => {
        const inputElm = $(`<input type="text"></input>`).addClass('comment-input').appendTo('body');
        inputElm.css({
            top: event.pageY,
            left: event.pageX,
        });
        inputElm.focus();
        inputElm.bind('keypress', function (event) {
            if (event.keyCode === 13) {
                window.addComment(inputElm.val(), 0, inputElm.css('top'), inputElm.css('left'));
                inputElm.remove();

                $.post(endpoint_url, {
                    author: null,
                    text: inputElm.val(),
                    x: inputElm.css('left'),
                    y: inputElm.css('top'),
                }, "json");
            }
        });
        inputElm.focusout(() => {
            inputElm.remove();
        });
    });
});
<commit_msg>fix network request<commit_after>window.addComment = function (content, num, top, left) {
    if (content) {
        const commentElm = $(`

${content}

          ${num}

    `).addClass('comment').appendTo('body');
        commentElm.css({
            top: top,
            left: left,
        });

        commentElm.draggable();

        // 绑定like按钮
        $(document).on('click', '.like', function () {
            const likeElm = $(this);

            if (likeElm.attr('allowClick') === 'true') {
                const numElm = likeElm.next();
                numElm.html(parseInt(numElm.html(), 10) + 1);

                likeElm.attr('allowClick', 'false');
                likeElm.css({
                    'background-position': '0 30',
                    cursor: 'default',
                });
            }
        });

        // 绑定close按钮
        $(document).on('click', '.close', function () {
            $(this).parent().parent().parent().remove();
        });

        // like和close的显示隐藏
        commentElm.mouseenter(() => {
            commentElm.children('.action').css({
                display: 'inline-block',
            });
        });
        commentElm.mouseleave(() => {
            commentElm.children('.action').css({
                display: 'none',
            });
        });
    }
}

$(document).ready(() => {
    const endpoint_url = "http://hq.shisoft.net:9090/comment?url=" + encodeURIComponent(window.location.href);
    $.get(endpoint_url, null, function (res) {
        res.forEach(function (comment) {
            window.addComment(comment.Text, 0, comment.Y, comment.X);
        });
    }, "json");

    $(document).dblclick((event) => {
        const inputElm = $(`<input type="text"></input>`).addClass('comment-input').appendTo('body');
        inputElm.css({
            top: event.pageY,
            left: event.pageX,
        });
        inputElm.focus();
        inputElm.bind('keypress', function (event) {
            if (event.keyCode === 13) {
                window.addComment(inputElm.val(), 0, inputElm.css('top'), inputElm.css('left'));
                inputElm.remove();

                $.post(endpoint_url, {
                    author: null,
                    text: inputElm.val(),
                    x: parseInt(inputElm.css('left')),
                    y: parseInt(inputElm.css('top')),
                }, "json");
            }
        });
        inputElm.focusout(() => {
            inputElm.remove();
        });
    });
});
<|endoftext|>