<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { handleRoute } from 'fluxible-router';
import PresentationSlide from './PresentationSlide';
import { connectToStores } from 'fluxible-addons-react';
import { Microservices } from '../../../configs/microservices';
import PresentationStore from '../../../stores/PresentationStore';

// if(process.env.BROWSER){
//    require('../../../assets/css/PresentationDefaults.css');
// }

class Presentation extends React.Component{
    constructor(props){
        super(props);
        this.playerCss = { height: '100%', position: 'absolute', top: '0' };
        this.clearStyle = { clear: 'both' };
        this.startingSlide = this.props.PresentationStore.selector.sid;
        this.revealDiv = null;
        this.secret = props.currentRoute.query.secret;
        this.id = props.currentRoute.query.id;
    }

    componentDidMount(){
        if(process.env.BROWSER){
            //$('[style*="absolute"]').children().attr('tabindex', 0);

            //remove existing tabindices
            $('[style*="absolute"]').each(function () {
                let el = $(this);
                if(el.attr('tabindex') !== 0)
                    el.attr('tabindex', 0);
            });
            //add tabindices to all children in absolute elements
            $('[style*="absolute"]').each(function () {
                $(this).children().attr('tabindex', 0);
                //if($(this).attr('tabindex') !== 0)
                //{
                //    $(this).attr('tabindex', 0);
                //}
            });
            //TODO: add hidden element at start of PPTX slide content + to focus on this.

             //loading reveal style

            // $('html.ios, html.ios body').css('height': '100% !important');
            // Get the theme information, and download the stylesheet

            this.revealDiv.style.display = 'inline';

            //SWIK-1321 - Non-canvas/pptx2html content is not scaled in presentation mode and bottom content is hidden
            let pptxwidth = '100%'; //use 100% of screen width
            let pptxheight = '100%'; //use 100% of screen height
            //if($('.pptx2html').html() !== ''){
            if($('.pptx2html').html()){
                pptxwidth = $('.pptx2html').width();
                pptxheight = $('.pptx2html').height();
            } else {
                pptxwidth = '100%';
                pptxheight = '100%';
            }

            window.location.hash = '#slide-' + this.startingSlide;

            let multiplexFileToLoad = (this.secret) ? '/custom_modules/reveal.js/plugin/multiplex/master.js' : '/custom_modules/reveal.js/plugin/multiplex/client.js' ;
            multiplexFileToLoad = (this.id) ? multiplexFileToLoad : '' ;
            let multiplexConfig = (this.secret) ? {secret: this.secret, id: this.id} : {secret: null, id: this.id};
            multiplexConfig.url = Microservices.webrtc.uri;
            multiplexConfig = (this.id) ? multiplexConfig : {};
            let dependencySocketIO = (this.id) ? Microservices.webrtc.uri.replace('http:','').replace('https:','') + '/socket.io/socket.io.js' : '' ;
            Reveal.initialize({
                width: pptxwidth,
                height: pptxheight,
                // margin: 0.2,
                transition: 'none',
                backgroundTransition: 'none',
                history: true,
                viewDistance: 2,
                dependencies: [
                    { src: dependencySocketIO, async: true },
                    { src: multiplexFileToLoad, async: true },
                    { src: '/custom_modules/reveal.js/plugin/notes/notes.js', async: true },
                    { src: '/custom_modules/reveal.js/plugin/zoom-js/zoom.js', async: true },
                    // { src: '/custom_modules/reveal.js/plugin/reveal.js-toolbar/toolbar.js', async: true},
                    { src: '/reveal.js-menu/menu.js', async: true},
                    { src: '/custom_modules/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
                    // Plugin from https://github.com/marcysutton/reveal-a11y
                    //{ src: '/custom_modules/reveal.js/plugin/accessibility/helper.js', async: false,condition: function() {return !!document.body.classList;}}
                ],
                keyboard: {
                    72: null,
                    78: null
                },
                toolbar: {
                    captureMenu: false,  // set to false so it doesn't crash the plugin
                    deckUrl: ['/deck', this.props.PresentationStore.selector.id, this.props.PresentationStore.deckSlug].join('/')
                },
                menu: {
                    deckUrl: ['/deck', this.props.PresentationStore.selector.id, this.props.PresentationStore.deckSlug].join('/'),
                    speakerNotes: '/custom_modules/reveal.js/plugin/notes/notes.html',
                    overview: true,
                    side: 'left',
                    width: 'normal',
                    numbers: false,
                    titleSelector: 'h1, h2, h3, h4, h5, h6',
                    useTextContentForMissingTitles: true,
                    hideMissingTitles: false,
                    markers: true,

                    // Specify custom panels to be included in the menu, by
                    // providing an array of objects with 'title', 'icon'
                    // properties, and either a 'src' or 'content' property.
                    custom: false,

                    // Specifies the themes that will be available in the themes
                    // menu panel. Set to 'true' to show the themes menu panel
                    // with the default themes list. Alternatively, provide an
                    // array to specify the themes to make available in the
                    // themes menu panel, for example...
                    // [
                    //     { name: 'Black', theme: 'css/theme/black.css' },
                    //     { name: 'White', theme: 'css/theme/white.css' },
                    //     { name: 'League', theme: 'css/theme/league.css' }
                    // ]
                    themes: false,

                    themesPath: 'css/theme/',
                    transitions: false,
                    openButton: true,
                    openSlideNumber: false,
                    keyboard: true,
                    sticky: false,
                    autoOpen: true,
                    delayInit: false,
                    openOnInit: false,
                    loadIcons: true
                },
                multiplex: multiplexConfig
            });

            Reveal.addEventListener( 'ready', ( event ) => {
                //$('.accessibilityWrapper').attr('tabindex', '');
                //$('.present > .accessibilityWrapper > .pptx2html div:first-child').focus();
                //console.log($('.present > .accessibilityWrapper > .pptx2html div:first').html());
            	// event.currentSlide, event.indexh, event.indexv
                this.resize();
            } );

            Reveal.addEventListener( 'slidechanged', ( event ) => {
                //console.log('slidechanged: ' + $('.present > .accessibilityWrapper > .pptx2html div:first').html());
                //$('.present > .accessibilityWrapper > .pptx2html div:first-child').focus();
                //console.log('resize non-pptx2html slide content - presentwidth: ' + presentwidth + ' and height: ' + presentheight);
                this.resize();
            } );

            //$('.present > .pptx2html div:first').focus();

        //listen to resize event and resize.
        /*ReactDOM.findDOMNode(this.refs.container).addEventListener('resize', (evt) =>
            {
            //console.log('resize');
            this.resize();
        });*/
            window.addEventListener('resize', this.resize());
        }
        //$('.present >  .pptx2html div:first').focus();

        // update mathjax rendering
        // add to the mathjax rendering queue the command to type-set the slide content
        MathJax.Hub.Queue(['Typeset',MathJax.Hub,'slides']);

    }
    resize(){
        if(process.env.BROWSER){
            let pptxwidth;
            let pptxheight;
            if( $('.present > .pptx2html').html() ){
                pptxwidth = $('.present > .pptx2html').width();
                pptxheight = $('.present > .pptx2html').height();
            } else {

                pptxwidth = '100%';
                pptxheight = '100%';

                //resize non-pptx2html slide content based on current height of window
                //reimplemented based on old SlideWiki https://github.com/AKSW/SlideWiki/blob/307e9e87aee08543e46d270fe267aeaa5cdbfe3b/slidewiki/static/js/scale.js
                //let presentwidth = $('.present').width();
                let presentheight = $('.present').height();
                //console.log('resize non-pptx2html slide content - presentwidth: ' + presentwidth + ' and height: ' + presentheight);
                //let screenwidth = document.getElementsByClassName('reveal')[0].offsetWidth * 0.85;
                //let screenwidth = document.getElementsByClassName('reveal')[0].offsetWidth * 0.85;
                //let screenheight = (document.getElementsByClassName('reveal')[0].offsetHeight * 0.85);
                let screenheight = document.getElementsByClassName('reveal')[0].offsetHeight;
                //console.log('resize non-pptx2html slide content - screenwidth: ' + screenwidth + ' and height: ' + screenheight);
                let heightratio = screenheight / presentheight ;
                //let widthratio = screenwidth / presentwidth;
                let scaleratio = 1;
                //if (widthratio < heightratio){scaleratio = widthratio;} else {scaleratio = heightratio;}
                if (presentheight > screenheight){scaleratio = heightratio;}
                //console.log('resize non-pptx2html slide content - widthratio: ' + widthratio + ' and heightratioratio: ' + heightratio);
                //console.log('resize non-pptx2html slide content - scaleratio: ' + scaleratio);

                $('.present').css({'transform': '', 'transform-origin': ''});
                $('.present').css({'transform': 'scale('+scaleratio+','+scaleratio+')', 'transform-origin': 'center top'});

            }
            // event.previousSlide, event.currentSlide, event.indexh, event.indexv
            //let state = Reveal.getState();
            //console.log('state: ' + JSON.stringify(state));
            //console.log('slidechanged dimensions: ' + pptxheight + ' by ' + pptxwidth);
            Reveal.configure({
                width: pptxwidth,
                height: pptxheight,
                slideNumber: true
            });

        }
    }

    render(){

        // Load the theme stylesheet
        let styleName = 'default';
        if(this.props.PresentationStore.theme && typeof this.props.PresentationStore.theme !== 'undefined')
            styleName = this.props.PresentationStore.theme;
        if (styleName === '' || typeof styleName === 'undefined' || styleName === 'undefined')//if none of above yield a theme they will be legacy decks:
            styleName = 'white';
        let style = require('../../../custom_modules/reveal.js/css/theme/' + styleName + '.css');
        let slides = this.getSlides();
        return(
            //<ResizeAware ref='container' id='container'>

 this.revealDiv = refToDiv} data-transition="none" data-background-transition="none">

      			     	     {slides}

            //</ResizeAware>
        );
    }

    getSlides(){
        let slides = this.props.PresentationStore.content;

        let html =
;
        if(slides){
            html = slides.map((slide) => {
                let content = slide.content.replace(' src=', ' data-src=') + ((slide.speakernotes) ? '' + slide.speakernotes + '' : '');
                let bgTemp = content.split('background-color: ');
                //need to check if bg is provided
                let backgroundColour = bgTemp.length > 1 ? content.split('background-color: ')[1].split(';')[0] : '';
                return
;
            });
        }
        return html;
    }

}

Presentation = connectToStores(Presentation, [PresentationStore], (context, props) => {
    return {
        PresentationStore: context.getStore(PresentationStore).getState()
    };
});
Presentation = handleRoute(Presentation);//NOTE add currentRoute attribute to constructor props

export default Presentation;
<commit_msg>First Approach<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { handleRoute } from 'fluxible-router';
import PresentationSlide from './PresentationSlide';
import { connectToStores } from 'fluxible-addons-react';
import { Microservices } from '../../../configs/microservices';
import PresentationStore from '../../../stores/PresentationStore';

// if(process.env.BROWSER){
//    require('../../../assets/css/PresentationDefaults.css');
// }

class Presentation extends React.Component{
    constructor(props){
        super(props);
        this.playerCss = { height: '100%', position: 'absolute', top: '0' };
        this.clearStyle = { clear: 'both' };
        this.startingSlide = this.props.PresentationStore.selector.sid;
        this.revealDiv = null;
        this.secret = props.currentRoute.query.secret;
        this.id = props.currentRoute.query.id;
    }

    componentDidMount(){
        if(process.env.BROWSER){
            //$('[style*="absolute"]').children().attr('tabindex', 0);

            //remove existing tabindices
            $('[style*="absolute"]').each(function () {
                let el = $(this);
                if(el.attr('tabindex') !== 0)
                    el.attr('tabindex', 0);
            });
            //add tabindices to all children in absolute elements
            $('[style*="absolute"]').each(function () {
                $(this).children().attr('tabindex', 0);
                //if($(this).attr('tabindex') !== 0)
                //{
                //    $(this).attr('tabindex', 0);
                //}
            });
            //TODO: add hidden element at start of PPTX slide content + to focus on this.

             //loading reveal style

            // $('html.ios, html.ios body').css('height': '100% !important');
            // Get the theme information, and download the stylesheet

            this.revealDiv.style.display = 'inline';

            //SWIK-1321 - Non-canvas/pptx2html content is not scaled in presentation mode and bottom content is hidden
            let pptxwidth = '100%'; //use 100% of screen width
            let pptxheight = '100%'; //use 100% of screen height
            //if($('.pptx2html').html() !== ''){
            if($('.pptx2html').html()){
                pptxwidth = $('.pptx2html').width();
                pptxheight = $('.pptx2html').height();
            } else {
                pptxwidth = '100%';
                pptxheight = '100%';
            }

            window.location.hash = '#slide-' + this.startingSlide;

            let multiplexFileToLoad = (this.secret) ? '/custom_modules/reveal.js/plugin/multiplex/master.js' : '/custom_modules/reveal.js/plugin/multiplex/client.js' ;
            multiplexFileToLoad = (this.id) ? multiplexFileToLoad : '' ;
            let multiplexConfig = (this.secret) ? {secret: this.secret, id: this.id} : {secret: null, id: this.id};
            multiplexConfig.url = Microservices.webrtc.uri;
            multiplexConfig = (this.id) ? multiplexConfig : {};
            let dependencySocketIO = (this.id) ? Microservices.webrtc.uri.replace('http:','').replace('https:','') + '/socket.io/socket.io.js' : '' ;
            Reveal.initialize({
                width: pptxwidth,
                height: pptxheight,
                // margin: 0.2,
                transition: 'none',
                backgroundTransition: 'none',
                history: true,
                viewDistance: 2,
                dependencies: [
                    { src: dependencySocketIO, async: true },
                    { src: multiplexFileToLoad, async: true },
                    { src: '/custom_modules/reveal.js/plugin/notes/notes.js', async: true },
                    { src: '/custom_modules/reveal.js/plugin/zoom-js/zoom.js', async: true },
                    // { src: '/custom_modules/reveal.js/plugin/reveal.js-toolbar/toolbar.js', async: true},
                    { src: '/reveal.js-menu/menu.js', async: true},
                    { src: '/custom_modules/reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
                    // Plugin from https://github.com/marcysutton/reveal-a11y
                    //{ src: '/custom_modules/reveal.js/plugin/accessibility/helper.js', async: false,condition: function() {return !!document.body.classList;}}
                ],
                keyboard: {
                    72: null,
                    78: null
                },
                toolbar: {
                    captureMenu: false,  // set to false so it doesn't crash the plugin
                    deckUrl: ['/deck', this.props.PresentationStore.selector.id, this.props.PresentationStore.deckSlug].join('/')
                },
                menu: {
                    deckUrl: ['/deck', this.props.PresentationStore.selector.id, this.props.PresentationStore.deckSlug].join('/'),
                    speakerNotes: '/custom_modules/reveal.js/plugin/notes/notes.html',
                    overview: true,
                    side: 'left',
                    width: 'normal',
                    numbers: false,
                    titleSelector: 'h1, h2, h3, h4, h5, h6',
                    useTextContentForMissingTitles: true,
                    hideMissingTitles: false,
                    markers: true,

                    // Specify custom panels to be included in the menu, by
                    // providing an array of objects with 'title', 'icon'
                    // properties, and either a 'src' or 'content' property.
                    custom: false,

                    // Specifies the themes that will be available in the themes
                    // menu panel. Set to 'true' to show the themes menu panel
                    // with the default themes list. Alternatively, provide an
                    // array to specify the themes to make available in the
                    // themes menu panel, for example...
                    // [
                    //     { name: 'Black', theme: 'css/theme/black.css' },
                    //     { name: 'White', theme: 'css/theme/white.css' },
                    //     { name: 'League', theme: 'css/theme/league.css' }
                    // ]
                    themes: false,

                    themesPath: 'css/theme/',
                    transitions: false,
                    openButton: true,
                    openSlideNumber: false,
                    keyboard: true,
                    sticky: false,
                    autoOpen: true,
                    delayInit: false,
                    openOnInit: false,
                    loadIcons: true
                },
                multiplex: multiplexConfig
            });

            Reveal.addEventListener( 'ready', ( event ) => {
                //$('.accessibilityWrapper').attr('tabindex', '');
                //$('.present > .accessibilityWrapper > .pptx2html div:first-child').focus();
                //console.log($('.present > .accessibilityWrapper > .pptx2html div:first').html());
            	// event.currentSlide, event.indexh, event.indexv
                this.resize();
            } );

            Reveal.addEventListener( 'slidechanged', ( event ) => {
                //console.log('slidechanged: ' + $('.present > .accessibilityWrapper > .pptx2html div:first').html());
                //$('.present > .accessibilityWrapper > .pptx2html div:first-child').focus();
                //console.log('resize non-pptx2html slide content - presentwidth: ' + presentwidth + ' and height: ' + presentheight);
                this.resize();
            } );

            //$('.present > .pptx2html div:first').focus();

        //listen to resize event and resize.
        /*ReactDOM.findDOMNode(this.refs.container).addEventListener('resize', (evt) =>
            {
            //console.log('resize');
            this.resize();
        });*/
            window.addEventListener('resize', this.resize());
        }
        //$('.present >  .pptx2html div:first').focus();

        // update mathjax rendering
        // add to the mathjax rendering queue the command to type-set the slide content
        MathJax.Hub.Queue(['Typeset',MathJax.Hub,'slides']);

    }
    resize(){
        if(process.env.BROWSER){
            let pptxwidth;
            let pptxheight;
            if( $('.present > .pptx2html').html() ){
                pptxwidth = $('.present > .pptx2html').width();
                pptxheight = $('.present > .pptx2html').height();
            } else {

                pptxwidth = '100%';
                pptxheight = '100%';

                //resize non-pptx2html slide content based on current height of window
                //reimplemented based on old SlideWiki https://github.com/AKSW/SlideWiki/blob/307e9e87aee08543e46d270fe267aeaa5cdbfe3b/slidewiki/static/js/scale.js
                //let presentwidth = $('.present').width();
                let presentheight = $('.present').height();
                //console.log('resize non-pptx2html slide content - presentwidth: ' + presentwidth + ' and height: ' + presentheight);
                //let screenwidth = document.getElementsByClassName('reveal')[0].offsetWidth * 0.85;
                //let screenwidth = document.getElementsByClassName('reveal')[0].offsetWidth * 0.85;
                //let screenheight = (document.getElementsByClassName('reveal')[0].offsetHeight * 0.85);
                let screenheight = document.getElementsByClassName('reveal')[0].offsetHeight;
                //console.log('resize non-pptx2html slide content - screenwidth: ' + screenwidth + ' and height: ' + screenheight);
                let heightratio = screenheight / presentheight ;
                //let widthratio = screenwidth / presentwidth;
                let scaleratio = 1;
                //if (widthratio < heightratio){scaleratio = widthratio;} else {scaleratio = heightratio;}
                if (presentheight > screenheight){scaleratio = heightratio;}
                //console.log('resize non-pptx2html slide content - widthratio: ' + widthratio + ' and heightratioratio: ' + heightratio);
                //console.log('resize non-pptx2html slide content - scaleratio: ' + scaleratio);

                $('.present').css({'transform': '', 'transform-origin': ''});
                $('.present').css({'transform': 'scale('+scaleratio+','+scaleratio+')', 'transform-origin': 'center top'});

            }
            // event.previousSlide, event.currentSlide, event.indexh, event.indexv
            //let state = Reveal.getState();
            //console.log('state: ' + JSON.stringify(state));
            //console.log('slidechanged dimensions: ' + pptxheight + ' by ' + pptxwidth);
            Reveal.configure({
                width: pptxwidth,
                height: pptxheight,
                slideNumber: true
            });

        }
    }

    render(){

        // Load the theme stylesheet
        let styleName = 'default';
        if(this.props.PresentationStore.theme && typeof this.props.PresentationStore.theme !== 'undefined')
            styleName = this.props.PresentationStore.theme;
        if (styleName === '' || typeof styleName === 'undefined' || styleName === 'undefined')//if none of above yield a theme they will be legacy decks:
            styleName = 'white';
        let style = require('../../../custom_modules/reveal.js/css/theme/' + styleName + '.css');
        let slides = this.getSlides();
        return(
            //<ResizeAware ref='container' id='container'>

 this.revealDiv = refToDiv} data-transition="none" data-background-transition="none">

      			     	     {slides}

            //</ResizeAware>
        );
    }

    getSlides(){
        let slides = this.props.PresentationStore.content;

        let html =
;
        if(slides){
            html = slides.map((slide) => {
                let content = slide.content.replace(' src=', ' data-src=') + ((slide.speakernotes) ? '' + slide.speakernotes + '' : '');
                let bgColor = content.split('background-color: ');
                let bgImgTemp = content.split('background-image: ');
                let resultingSlide =
;
                //need to check if bg is provided
                if (bgImgTemp.length > 1) {
                    let backgroundImage = content.split('background-image: url("')[1].split('");')[0];
                    resultingSlide =
;
                } else if (bgColor.length > 1) {
                    let backgroundColour = content.split('background-color: ')[1].split(';')[0] ;
                    resultingSlide =
;
                }

                return resultingSlide;
            });
        }
        return html;
    }

}

Presentation = connectToStores(Presentation, [PresentationStore], (context, props) => {
    return {
        PresentationStore: context.getStore(PresentationStore).getState()
    };
});
Presentation = handleRoute(Presentation);//NOTE add currentRoute attribute to constructor props

export default Presentation;
<|endoftext|>


<commit_before>'use strict';
import VectorLayer from 'ol/layer/Vector';
import { Vector as VectorSource } from 'ol/source';

describe('layermanager', function () {
    var scope;
    var $componentController, scope;

    var layerForCluster = new VectorLayer({
        title: 'Bookmarks',
        source: new VectorSource({})
    })

    beforeEach(function () {
        angular.mock.module(function ($provide) {
            $provide.value('config', {
                default_layers: [layerForCluster]
            });
        });

        angular.mock.module('hs.layermanager')
    }); //<--- Hook module

    beforeEach(inject(function (_$componentController_, $rootScope) {
        scope = $rootScope.$new();
        $componentController = _$componentController_;
    }));

    it('Clusterization', function () {
        var ctrl = $componentController('hs.layerEditor', { $scope: scope }, { currentLayer: { layer: layerForCluster } });
        scope.cluster(true);

        expect(layerForCluster.get('cluster')).toBe(true);
        expect(layerForCluster.getSource().getSource).toBeDefined();

        scope.changeDistance($scope.distance)
    });
});

<commit_msg>Test for clusterization distance and turning off<commit_after>'use strict';
import VectorLayer from 'ol/layer/Vector';
import { Vector as VectorSource } from 'ol/source';

describe('layermanager', function () {
    var scope;
    var $componentController, scope;

    var layerForCluster = new VectorLayer({
        title: 'Bookmarks',
        source: new VectorSource({})
    })

    beforeEach(function () {
        angular.mock.module(function ($provide) {
            $provide.value('config', {
                default_layers: [layerForCluster]
            });
        });

        angular.mock.module('hs.layermanager')
    }); //<--- Hook module

    beforeEach(inject(function (_$componentController_, $rootScope) {
        scope = $rootScope.$new();
        $componentController = _$componentController_;
    }));

    it('clusterization', function () {
        var ctrl = $componentController('hs.layerEditor', { $scope: scope }, { currentLayer: { layer: layerForCluster } });
        scope.cluster(true);

        expect(layerForCluster.get('cluster')).toBe(true);
        expect(layerForCluster.getSource().getSource).toBeDefined();

        scope.distance.value = 15;
        scope.changeDistance(scope.distance.value);
        expect(layerForCluster.getSource().getDistance()).toBe(15);

        //Turn clusterization off
        scope.cluster(false);
        expect(layerForCluster.getSource().getSource).toBeUndefined();

    });
});

<|endoftext|>


<commit_before>// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

const compute = require('@google-cloud/compute');

const {describe, it} = require('mocha');
const cp = require('child_process');
const {assert} = require('chai');

const {generateTestId, getStaleVMInstances, deleteInstance} = require('./util');

const instancesClient = new compute.InstancesClient();
const firewallsClient = new compute.FirewallsClient();
const routesClient = new compute.RoutesClient();
const globalOperationsClient = new compute.GlobalOperationsClient();

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});

const deleteFirewallRule = async (projectId, firewallRule) => {
  const [response] = await firewallsClient.delete({
    project: projectId,
    firewall: firewallRule,
  });
  let operation = response.latestResponse;

  // Wait for the delete operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await globalOperationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }
};

const deleteRoute = async (projectId, routeName) => {
  const [response] = await routesClient.delete({
    project: projectId,
    route: routeName,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.GlobalOperationsClient();

  // Wait for the delete operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }
};

describe('creating managing windows instances tests', () => {
  const instanceName = generateTestId();
  const firewallRuleName = generateTestId();
  const networkName = 'global/networks/default-compute';
  const subnetworkName = 'regions/europe-central2/subnetworks/default-compute';
  const routeName = generateTestId();
  const zone = 'europe-central2-b';
  const machineType = 'n1-standard-1';
  const sourceImageFamily = 'windows-2012-r2';

  before(async () => {
    const instances = await getStaleVMInstances();
    await Promise.all(
      instances.map(instance =>
        deleteInstance(instance.zone, instance.instanceName)
      )
    );
  });

  it('should create windows server instance with external IP', async () => {
    const projectId = await instancesClient.getProjectId();

    const output = execSync(
      `node instances/windows/creating-managing-windows-instances/createWindowsServerInstanceExternalIP ${projectId} ${zone} ${instanceName}`
    );
    assert.match(output, /Instance created./);

    execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`);
  });

  it('should create windows server instance with internal IP and firewall rule', async () => {
    const projectId = await instancesClient.getProjectId();

    const output = execSync(
      `node instances/windows/creating-managing-windows-instances/createWindowsServerInstanceInternalIP ${projectId} ${zone} ${instanceName} ${machineType} ${sourceImageFamily} ${networkName} ${subnetworkName}`
    );

    assert.match(output, /Instance created./);

    await deleteRoute(projectId, routeName);
    await deleteFirewallRule(projectId, firewallRuleName);
    execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`);
  });
});
<commit_msg>Remove unused cleanup code to fix tests<commit_after>// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

const compute = require('@google-cloud/compute');

const {describe, it} = require('mocha');
const cp = require('child_process');
const {assert} = require('chai');

const {generateTestId, getStaleVMInstances, deleteInstance} = require('./util');

const instancesClient = new compute.InstancesClient();
const firewallsClient = new compute.FirewallsClient();
const routesClient = new compute.RoutesClient();
const globalOperationsClient = new compute.GlobalOperationsClient();

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});

const deleteFirewallRule = async (projectId, firewallRule) => {
  const [response] = await firewallsClient.delete({
    project: projectId,
    firewall: firewallRule,
  });
  let operation = response.latestResponse;

  // Wait for the delete operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await globalOperationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }
};

const deleteRoute = async (projectId, routeName) => {
  const [response] = await routesClient.delete({
    project: projectId,
    route: routeName,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.GlobalOperationsClient();

  // Wait for the delete operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }
};

describe('creating managing windows instances tests', () => {
  const instanceName = generateTestId();
  const firewallRuleName = generateTestId();
  const networkName = 'global/networks/default-compute';
  const subnetworkName = 'regions/europe-central2/subnetworks/default-compute';
  const routeName = generateTestId();
  const zone = 'europe-central2-b';
  const machineType = 'n1-standard-1';
  const sourceImageFamily = 'windows-2012-r2';

  before(async () => {
    const instances = await getStaleVMInstances();
    await Promise.all(
      instances.map(instance =>
        deleteInstance(instance.zone, instance.instanceName)
      )
    );
  });

  it('should create windows server instance with external IP', async () => {
    const projectId = await instancesClient.getProjectId();

    const output = execSync(
      `node instances/windows/creating-managing-windows-instances/createWindowsServerInstanceExternalIP ${projectId} ${zone} ${instanceName}`
    );
    assert.match(output, /Instance created./);

    execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`);
  });

  it('should create windows server instance with internal IP and firewall rule', async () => {
    const projectId = await instancesClient.getProjectId();

    const output = execSync(
      `node instances/windows/creating-managing-windows-instances/createWindowsServerInstanceInternalIP ${projectId} ${zone} ${instanceName} ${machineType} ${sourceImageFamily} ${networkName} ${subnetworkName}`
    );

    assert.match(output, /Instance created./);

    execSync(`node deleteInstance ${projectId} ${zone} ${instanceName}`);
  });
});
<|endoftext|>


<commit_before>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

/* jshint laxcomma:true */

var semver = require('semver'),
    npm = require('npm'),
    path = require('path'),
    url = require('url'),
    fs = require('fs'),
    rc = require('rc'),
    Q = require('q'),
    request = require('request'),
    pluginMapper = require('cordova-registry-mapper').oldToNew,
    npmhelper = require('../../util/npm-helper'),
    home = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE,
    events = require('../../events'),
    unpack = require('../../util/unpack'),
    // if PLUGMAN_HOME env var is specified use it as config directory (see CB-8190)
    plugmanConfigDir = process.env.PLUGMAN_HOME || path.resolve(home, '.plugman'),
    plugmanCacheDir = path.resolve(plugmanConfigDir, 'cache'),
    oneDay = 3600*24;

module.exports = {
    settings: null,
    /**
     * @method config
     * @param {Array} args Command argument
     * @return {Promise.<Object>} Promised configuration object.
     */
    config: function (args) {
        return initThenLoadSettingsWithRestore(function () {
            return Q.ninvoke(npm.commands, 'config', args);
        });
    },

    /**
     * @method owner
     * @param {Array} args Command argument
     * @return {Promise.<void>} Promise for completion.
     */
    owner: function(args) {
        var command = args && args[0];
        if (command && (command === 'add' || command === 'rm'))
            return Q.reject('Support for \'owner add/rm\' commands has been removed ' +
                'due to transition of Cordova plugins registry to read-only state');

        return initThenLoadSettingsWithRestore(function () {
            return Q.ninvoke(npm.commands, 'owner', args);
        });
    },

    /**
     * @method search
     * @param {Array} args Array of keywords
     * @return {Promise.<Object>} Promised search results.
     */
    search: function(args) {
        return initThenLoadSettingsWithRestore(function () {
            return Q.ninvoke(npm.commands, 'search', args, true);
        });
    },

    /**
     * @method fetch
     * @param {Array} with one element - the plugin id or "id@version"
     * @return {Promise.<string>} Promised path to fetched package.
     */
    fetch: function(plugin, client) {
        plugin = plugin.shift();
        return Q.fcall(function() {
            //fetch from npm
            return fetchPlugin(plugin, client, true);
        })
        .fail(function(error) {
            //check to see if pluginID is reverse domain name style
            if(isValidCprName(plugin)) {
                //fetch from CPR
                return fetchPlugin(plugin, client, false);
            } else {
                return Q.reject(error);
            }
        });
    },

    /**
     * @method info
     * @param {String} name Plugin name
     * @return {Promise.<Object>} Promised package info.
     */
    info: function(plugin) {
        plugin = plugin.shift();
        return initSettings()
        .then(Q.nbind(npm.load, npm))
        .then(function() {
            // Set cache timout limits to 0 to force npm to call the registry
            // even when it has a recent .cache.json file.
            npm.config.set('cache-min', 0);
            npm.config.set('cache-max', 0);
            return Q.ninvoke(npm.commands, 'view', [plugin], /* silent = */ true );
        })
        .then(function(info) {
            // Plugin info should be accessed as info[version]. If a version
            // specifier like >=x.y.z was used when calling npm view, info
            // can contain several versions, but we take the first one here.
            var version = Object.keys(info)[0];
            return info[version];
        });
    }
};

/**
 * @param {Boolean} determines if we are using the npm registry
 * @return {Promise.<Object>} Promised settings.
 */
function initSettings(returnEmptySettings) {
    var settings = module.exports.settings;

    // check if settings already set
    if(settings !== null) {
        return Q(returnEmptySettings ? {} : settings);
    }

    // setting up settings
    // obviously if settings dir does not exist settings is going to be empty
    if(!fs.existsSync(plugmanConfigDir)) {
        fs.mkdirSync(plugmanConfigDir);
        fs.mkdirSync(plugmanCacheDir);
    }

    settings =
    module.exports.settings =
    rc('plugman', {
        cache: plugmanCacheDir,
        registry: 'http://registry.cordova.io',
        logstream: fs.createWriteStream(path.resolve(plugmanConfigDir, 'plugman.log')),
        userconfig: path.resolve(plugmanConfigDir, 'config'),
        'cache-min': oneDay
    });

    return Q(returnEmptySettings ? {} : settings);
}

/**
 * @description Calls initSettings(), then npmhelper.loadWithSettingsThenRestore, which initializes npm.config with
 * settings, executes the promises, then restores npm.config. Use this rather than passing settings to npm.load, since
 * that only works the first time you try to load npm.
 */
function initThenLoadSettingsWithRestore(useEmptySettings, promises) {
    if (typeof useEmptySettings === 'function') {
        promises = useEmptySettings;
        useEmptySettings = false;
    }

    return initSettings(useEmptySettings).then(function (settings) {
        return npmhelper.loadWithSettingsThenRestore(settings, promises);
    });
}

// Send a message to the registry to update download counts.
function bumpCounter(info, client) {
    // Update the download count for this plugin.
    // Fingers crossed that the timestamps are unique, and that no plugin is downloaded
    // twice in a single millisecond.
    //
    // This is acceptable, because the failure mode is Couch gracefully rejecting the second one
    // (for lacking a _rev), and dropped a download count is not important.
    var settings = module.exports.settings;
    var now = new Date();
    var message = {
        day: now.getUTCFullYear() + '-' + (now.getUTCMonth()+1) + '-' + now.getUTCDate(),
        pkg: info.name,
        client: client,
        version: info.version
    };
    var remote = settings.registry + '/downloads';

    makeRequest('POST', remote, message, function (err, res, body) {
        // ignore errors
    });
}

function makeRequest (method, where, what, cb_) {
    var settings = module.exports.settings;
    var remote = url.parse(where);
    if (typeof cb_ !== 'function') {
        cb_ = what;
        what = null;
    }
    var cbCalled = false;
    function cb () {
        if (cbCalled) return;
        cbCalled = true;
        cb_.apply(null, arguments);
    }

    var strict = settings['strict-ssl'];
    if (strict === undefined) strict = true;
    var opts = { url: remote
               , method: method
               , ca: settings.ca
               , strictSSL: strict
               };

    var headers = opts.headers = {};

    headers.accept = 'application/json';

    headers['user-agent'] = settings['user-agent'] ||
                            'node/' + process.version;

    var p = settings.proxy;
    var sp = settings['https-proxy'] || p;
    opts.proxy = remote.protocol === 'https:' ? sp : p;

    // figure out wth 'what' is
    if (what) {
        if (Buffer.isBuffer(what) || typeof what === 'string') {
            opts.body = what;
            headers['content-type'] = 'application/json';
            headers['content-length'] = Buffer.byteLength(what);
        } else {
            opts.json = what;
        }
    }

    var req = request(opts, cb);

    req.on('error', cb);
    req.on('socket', function (s) {
        s.on('error', cb);
    });

    return req;
}

/**
* @param {Array} with one element - the plugin id or "id@version"
* @param useNpmRegistry: {Boolean} - to use the npm registry
* @return {Promise.<string>} Promised path to fetched package.
*/
function fetchPlugin(plugin, client, useNpmRegistry) {
    //set registry variable to use in log messages below
    var registryName;
    if(useNpmRegistry){
        registryName = 'npm';
    } else {
        registryName = 'cordova plugins registry';
    }

    return initThenLoadSettingsWithRestore(useNpmRegistry, function () {
        events.emit('log', 'Fetching plugin "' + plugin + '" via ' + registryName);
        return Q.ninvoke(npm.commands, 'cache', ['add', processPluginVersion(plugin)])
        .then(function (info) {
            var cl = (client === 'plugman' ? 'plugman' : 'cordova-cli');
            bumpCounter(info, cl);
            var pluginDir = path.resolve(npm.cache, info.name, info.version, 'package');
            // Unpack the plugin that was added to the cache (CB-8154)
            var package_tgz = path.resolve(npm.cache, info.name, info.version, 'package.tgz');
            return unpack.unpackTgz(package_tgz, pluginDir);
        });
    });
}

function processPluginVersion(plugin) {
    // If plugin includes a version that is a caret range, the ancient version of npm we're using won't know how to
    // handle it. So we'll use our current version of semver to turn it into a usable range.

    var parts = plugin.split('@');
    var version = parts[1];

    if (!version || version.charAt(0) !== '^') {
        return plugin;
    }

    var validRange = semver.validRange(version, /* loose */ true);
    if (!validRange) {
        return plugin;
    }

    // Because validRange may include spaces, we need to wrap it in quotes.
    return parts[0] + '@"' + validRange + '"';
}

/**
 * @param {Array} with one element - the plugin id or "id@version"
 * @return {Boolean} if plugin id is reverse domain name style.
 */
function isValidCprName(plugin) {
    // Split @Version from the plugin id if it exists.
    var splitVersion = plugin.split('@');

    //Create regex that checks for at least two dots with any characters except @ to determine if it is reverse domain name style.
    var matches = /([^@]*\.[^@]*\.[^@]*)/.exec(splitVersion[0]);

    //If matches equals null, plugin is not reverse domain name style
    if(matches === null) {
        return false;
    } else {
        warnIfIdInMapper(splitVersion[0]);
    }
    return true;
}

/**
 * @param plugin:{Array} - the plugin id or "id@version"
 * @param matches:{Array} - the array containing the RDN style plugin id without @version
 */
function warnIfIdInMapper(plugin) {
    //Reverse domain name style plugin ID
    //Check if a mapping exists for the plugin id
    //if it does, warn the users to use package-name
    var packageName = pluginMapper[plugin];
    if(packageName) {
        events.emit('log', 'WARNING: ' + plugin + ' has been renamed to ' + packageName + '. You may not be getting the latest version! We suggest you `cordova plugin rm ' + plugin + '` and `cordova plugin add ' + packageName + '`.');
    }
}
<commit_msg>CB-9559 Adding a plugin with caret in version results in an error<commit_after>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

/* jshint laxcomma:true */

var npm = require('npm'),
    path = require('path'),
    url = require('url'),
    fs = require('fs'),
    rc = require('rc'),
    Q = require('q'),
    request = require('request'),
    pluginMapper = require('cordova-registry-mapper').oldToNew,
    npmhelper = require('../../util/npm-helper'),
    home = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE,
    events = require('../../events'),
    unpack = require('../../util/unpack'),
    // if PLUGMAN_HOME env var is specified use it as config directory (see CB-8190)
    plugmanConfigDir = process.env.PLUGMAN_HOME || path.resolve(home, '.plugman'),
    plugmanCacheDir = path.resolve(plugmanConfigDir, 'cache'),
    oneDay = 3600*24;

module.exports = {
    settings: null,
    /**
     * @method config
     * @param {Array} args Command argument
     * @return {Promise.<Object>} Promised configuration object.
     */
    config: function (args) {
        return initThenLoadSettingsWithRestore(function () {
            return Q.ninvoke(npm.commands, 'config', args);
        });
    },

    /**
     * @method owner
     * @param {Array} args Command argument
     * @return {Promise.<void>} Promise for completion.
     */
    owner: function(args) {
        var command = args && args[0];
        if (command && (command === 'add' || command === 'rm'))
            return Q.reject('Support for \'owner add/rm\' commands has been removed ' +
                'due to transition of Cordova plugins registry to read-only state');

        return initThenLoadSettingsWithRestore(function () {
            return Q.ninvoke(npm.commands, 'owner', args);
        });
    },

    /**
     * @method search
     * @param {Array} args Array of keywords
     * @return {Promise.<Object>} Promised search results.
     */
    search: function(args) {
        return initThenLoadSettingsWithRestore(function () {
            return Q.ninvoke(npm.commands, 'search', args, true);
        });
    },

    /**
     * @method fetch
     * @param {Array} with one element - the plugin id or "id@version"
     * @return {Promise.<string>} Promised path to fetched package.
     */
    fetch: function(plugin, client) {
        plugin = plugin.shift();
        return Q.fcall(function() {
            //fetch from npm
            return fetchPlugin(plugin, client, true);
        })
        .fail(function(error) {
            //check to see if pluginID is reverse domain name style
            if(isValidCprName(plugin)) {
                //fetch from CPR
                return fetchPlugin(plugin, client, false);
            } else {
                return Q.reject(error);
            }
        });
    },

    /**
     * @method info
     * @param {String} name Plugin name
     * @return {Promise.<Object>} Promised package info.
     */
    info: function(plugin) {
        plugin = plugin.shift();
        return initSettings()
        .then(Q.nbind(npm.load, npm))
        .then(function() {
            // Set cache timout limits to 0 to force npm to call the registry
            // even when it has a recent .cache.json file.
            npm.config.set('cache-min', 0);
            npm.config.set('cache-max', 0);
            return Q.ninvoke(npm.commands, 'view', [plugin], /* silent = */ true );
        })
        .then(function(info) {
            // Plugin info should be accessed as info[version]. If a version
            // specifier like >=x.y.z was used when calling npm view, info
            // can contain several versions, but we take the first one here.
            var version = Object.keys(info)[0];
            return info[version];
        });
    }
};

/**
 * @param {Boolean} determines if we are using the npm registry
 * @return {Promise.<Object>} Promised settings.
 */
function initSettings(returnEmptySettings) {
    var settings = module.exports.settings;

    // check if settings already set
    if(settings !== null) {
        return Q(returnEmptySettings ? {} : settings);
    }

    // setting up settings
    // obviously if settings dir does not exist settings is going to be empty
    if(!fs.existsSync(plugmanConfigDir)) {
        fs.mkdirSync(plugmanConfigDir);
        fs.mkdirSync(plugmanCacheDir);
    }

    settings =
    module.exports.settings =
    rc('plugman', {
        cache: plugmanCacheDir,
        registry: 'http://registry.cordova.io',
        logstream: fs.createWriteStream(path.resolve(plugmanConfigDir, 'plugman.log')),
        userconfig: path.resolve(plugmanConfigDir, 'config'),
        'cache-min': oneDay
    });

    return Q(returnEmptySettings ? {} : settings);
}

/**
 * @description Calls initSettings(), then npmhelper.loadWithSettingsThenRestore, which initializes npm.config with
 * settings, executes the promises, then restores npm.config. Use this rather than passing settings to npm.load, since
 * that only works the first time you try to load npm.
 */
function initThenLoadSettingsWithRestore(useEmptySettings, promises) {
    if (typeof useEmptySettings === 'function') {
        promises = useEmptySettings;
        useEmptySettings = false;
    }

    return initSettings(useEmptySettings).then(function (settings) {
        return npmhelper.loadWithSettingsThenRestore(settings, promises);
    });
}

// Send a message to the registry to update download counts.
function bumpCounter(info, client) {
    // Update the download count for this plugin.
    // Fingers crossed that the timestamps are unique, and that no plugin is downloaded
    // twice in a single millisecond.
    //
    // This is acceptable, because the failure mode is Couch gracefully rejecting the second one
    // (for lacking a _rev), and dropped a download count is not important.
    var settings = module.exports.settings;
    var now = new Date();
    var message = {
        day: now.getUTCFullYear() + '-' + (now.getUTCMonth()+1) + '-' + now.getUTCDate(),
        pkg: info.name,
        client: client,
        version: info.version
    };
    var remote = settings.registry + '/downloads';

    makeRequest('POST', remote, message, function (err, res, body) {
        // ignore errors
    });
}

function makeRequest (method, where, what, cb_) {
    var settings = module.exports.settings;
    var remote = url.parse(where);
    if (typeof cb_ !== 'function') {
        cb_ = what;
        what = null;
    }
    var cbCalled = false;
    function cb () {
        if (cbCalled) return;
        cbCalled = true;
        cb_.apply(null, arguments);
    }

    var strict = settings['strict-ssl'];
    if (strict === undefined) strict = true;
    var opts = { url: remote
               , method: method
               , ca: settings.ca
               , strictSSL: strict
               };

    var headers = opts.headers = {};

    headers.accept = 'application/json';

    headers['user-agent'] = settings['user-agent'] ||
                            'node/' + process.version;

    var p = settings.proxy;
    var sp = settings['https-proxy'] || p;
    opts.proxy = remote.protocol === 'https:' ? sp : p;

    // figure out wth 'what' is
    if (what) {
        if (Buffer.isBuffer(what) || typeof what === 'string') {
            opts.body = what;
            headers['content-type'] = 'application/json';
            headers['content-length'] = Buffer.byteLength(what);
        } else {
            opts.json = what;
        }
    }

    var req = request(opts, cb);

    req.on('error', cb);
    req.on('socket', function (s) {
        s.on('error', cb);
    });

    return req;
}

/**
* @param {Array} with one element - the plugin id or "id@version"
* @param useNpmRegistry: {Boolean} - to use the npm registry
* @return {Promise.<string>} Promised path to fetched package.
*/
function fetchPlugin(plugin, client, useNpmRegistry) {
    //set registry variable to use in log messages below
    var registryName;
    if(useNpmRegistry){
        registryName = 'npm';
    } else {
        registryName = 'cordova plugins registry';
    }

    return initThenLoadSettingsWithRestore(useNpmRegistry, function () {
        events.emit('log', 'Fetching plugin "' + plugin + '" via ' + registryName);
        return Q.ninvoke(npm.commands, 'cache', ['add', plugin])
        .then(function (info) {
            var cl = (client === 'plugman' ? 'plugman' : 'cordova-cli');
            bumpCounter(info, cl);
            var pluginDir = path.resolve(npm.cache, info.name, info.version, 'package');
            // Unpack the plugin that was added to the cache (CB-8154)
            var package_tgz = path.resolve(npm.cache, info.name, info.version, 'package.tgz');
            return unpack.unpackTgz(package_tgz, pluginDir);
        });
    });
}

/**
 * @param {Array} with one element - the plugin id or "id@version"
 * @return {Boolean} if plugin id is reverse domain name style.
 */
function isValidCprName(plugin) {
    // Split @Version from the plugin id if it exists.
    var splitVersion = plugin.split('@');

    //Create regex that checks for at least two dots with any characters except @ to determine if it is reverse domain name style.
    var matches = /([^@]*\.[^@]*\.[^@]*)/.exec(splitVersion[0]);

    //If matches equals null, plugin is not reverse domain name style
    if(matches === null) {
        return false;
    } else {
        warnIfIdInMapper(splitVersion[0]);
    }
    return true;
}

/**
 * @param plugin:{Array} - the plugin id or "id@version"
 * @param matches:{Array} - the array containing the RDN style plugin id without @version
 */
function warnIfIdInMapper(plugin) {
    //Reverse domain name style plugin ID
    //Check if a mapping exists for the plugin id
    //if it does, warn the users to use package-name
    var packageName = pluginMapper[plugin];
    if(packageName) {
        events.emit('log', 'WARNING: ' + plugin + ' has been renamed to ' + packageName + '. You may not be getting the latest version! We suggest you `cordova plugin rm ' + plugin + '` and `cordova plugin add ' + packageName + '`.');
    }
}
<|endoftext|>


<commit_before>
function load_chart(){
        $('#container').highcharts({
            chart: {
                type: 'area'
            },
            title: {
                text: 'data file downloads'
            },
            subtitle: {
                text: 'Source: ' +
                    'Harvard University IQSS'
            },
            xAxis: {
                        categories: [{% for stat in download_stats %}'{{ stat.retrieval_date|date:"m/y" }}'{% if not forloop.last %},{% endif %}{% endfor %}],
                        title: {
                            enabled: false
                        },
                         tickInterval: 5,
                         tickPixelInterval: 80,
                         tickmarkPlacement: 'on'
                    },
            yAxis: {
                title: {
                    text: 'Count'
                },
                labels: {
                    formatter: function () {
                        return this.value / 1000 + 'k';
                    }
                }
            },
            tooltip: {
    //            pointFormat: '{series.name} produced {point.y:,.0f}
warheads in {point.x}'
                pointFormat: '{point.y:,.0f} files downloaded from dataverse'
            },
            plotOptions: {
                  area: {
                      stacking: 'normal',
                      lineColor: '#666666',
                      lineWidth: 1,
                      marker: {
                          lineWidth: 1,
                          lineColor: '#666666'
                      }
                  }
              },
            series: [{
                  name: 'Total Downloaded Data Files',
                  data: [{% for stat in download_stats %}{{ stat.cumulative_count }}{% if not forloop.last %},{% endif %}{% endfor %}]
                //    data: [100, 250, 1000, 3240, 5600, 7900, 11000]
                }
                , {
                    name: 'Monthly Downloads',
                    data: [{% for stat in download_stats %}{{ stat.month_count }}{% if not forloop.last %},{% endif %}{% endfor %}]
            }
            ]
        });
}

<commit_msg>updated chart script<commit_after>
function load_chart(){
        $('#container').highcharts({
            chart: {
                type: 'area'
            },
            title: {
                text: 'data file downloads'
            },
            subtitle: {
                text: 'Source: ' +
                    'Harvard University IQSS'
            },
            xAxis: {
                        categories: [{% for stat in download_stats %}'{{ stat.retrieval_date|date:"m/y" }}'{% if not forloop.last %},{% endif %}{% endfor %}],
                        title: {
                            enabled: false
                        },
                         tickInterval: 5,
                         tickPixelInterval: 80,
                         tickmarkPlacement: 'on'
                    },
            yAxis: {
                title: {
                    text: 'Count'
                },
                labels: {
                    formatter: function () {
                        return this.value / 1000 + 'k';
                    }
                }
            },
            tooltip: {
    //            pointFormat: '{series.name} produced {point.y:,.0f}
warheads in {point.x}'
                pointFormat: '{point.y:,.0f} files downloaded from dataverse'
            },
            plotOptions: {
                  area: {
                      stacking: 'normal',
                      lineColor: '#666666',
                      lineWidth: 1,
                      marker: {
                          lineWidth: 1,
                          lineColor: '#666666'
                      }
                  }
              },
            series: [
                {
                    name: 'Total Downloaded Data Files',
                    data: [{% for stat in download_stats %}{{ stat.cumulative_count }}{% if not forloop.last %},{% endif %}{% endfor %}]
                //    data: [100, 250, 1000, 3240, 5600, 7900, 11000]
                },

                {
                    name: 'Monthly Downloads',
                    data: [{% for stat in download_stats %}{{ stat.month_count }}{% if not forloop.last %},{% endif %}{% endfor %}],
                    marker: {
                                    symbol: 'triangle',
                                    fillColor: '#FFFFFF',

                                },
            }
            ]
        });
}

<|endoftext|>


<commit_before>var Configurations = {
    setpoints: {
        min: 0.5,
        max: 3.0
    }
}

var currentSelection = {
    x: 1,
    y: 1
}

var dataZ = [
    []
];

var plotXY = $.plot($("#PlotLocalXY"), [{
    label: "Local XY",
}], {
    yaxis: {
        min: 0,
        max: 4
    },
    xaxis: {
        min: 0,
        max: 4
    },
    points: {
        fill: false,
        radius: 7,
        show: true
    },
    colors: ["#26B99A", "#FE642E", "#808080"],
    grid: {
        borderWidth: {
            top: 0,
            right: 0,
            bottom: 1,
            left: 1
        },
        borderColor: {
            bottom: "#7F8790",
            left: "#7F8790"
        },
        hoverable: true,
        clickable: true
    },
    selection: {
        mode: "xy",
        show: false,
        color: 'rgba(0,0,0,0)'
    }
});

plotXY.getPlaceholder().bind("plothover", function(event, pos) {
    if (pos.x < Configurations.setpoints.min)
        currentSelection.x = Configurations.setpoints.min
    else if (pos.x > Configurations.setpoints.max)
        currentSelection.x = Configurations.setpoints.max
    else
        currentSelection.x = pos.x

    if (pos.y < Configurations.setpoints.min)
        currentSelection.y = Configurations.setpoints.min
    else if (pos.y > Configurations.setpoints.max)
        currentSelection.y = Configurations.setpoints.max
    else
        currentSelection.y = pos.y
        //console.log(currentSelection);
});

plotXY.getPlaceholder().bind("plotclick", function(event, pos) {
    // Send setpoint
    console.log("Sending setpoint : ", currentSelection);
});

var plotZ = $.plot($("#PlotLocalZ"), [{
    label: "Local Z",
    data: dataZ
}], {
    series: {
        curvedLines: {
            apply: true,
            active: true,
            monotonicFit: true
        }
    },
    yaxis: {
        min: 0,
        max: 2.5
    },
    lines: {
        fillColor: "rgba(150, 0, 89, 0.12)",
        show: true
    }, //#96CA59 rgba(150, 202, 89, 0.42)
    points: {
        //fillColor: "#fff",
        radius: 7,
        show: false,
        symbol: "circle"
    },
    colors: ["#26B99A"],
    grid: {
        borderWidth: {
            top: 0,
            right: 0,
            bottom: 1,
            left: 1
        },
        borderColor: {
            bottom: "#7F8790",
            left: "#7F8790"
        }
    }
});

var ros = new ROSLIB.Ros({
    url: 'ws://192.168.137.18:9090'
});

ros.on('connection', function() {
    console.log('Connected to websocket server.');
});

ros.on('error', function(error) {
    console.log('Error connecting to websocket server: ', error);
});

ros.on('close', function() {
    console.log('Connection to websocket server closed.');
});

// Publishing a Topic
// ------------------

/*var cmdVel = new ROSLIB.Topic({
  ros : ros,
  name : '/cmd_vel',
  messageType : 'geometry_msgs/Twist'
});

var exampleTopic = new ROSLIB.Topic({
      ros: ros,
    name: '/com/endpoint/examp', // use a sensible namespace
      messageType: 'std_msgs/String'
});

var twist = new ROSLIB.Message({
linear : {
  x : 0.1,
  y : 0.2,
  z : 0.3
},
angular : {
  x : -0.1,
  y : -0.2,
  z : -0.3
}
});

var msg = new ROSLIB.Message({
    data : "yesouiok"
});

  console.log("Publishing cmd_vel");
  cmdVel.publish(twist);

  console.log("Publishing data");
  exampleTopic.publish(msg);

*/
var listener = new ROSLIB.Topic({
    ros: ros,
    name: 'web/report',
    messageType: 'laserpack/Report'
});

var data = {};

listener.subscribe(function(message) {
    //console.log(message);
    data = message;

    changePose('#laser_filtered', data.laser_filtered.position)
    changePose('#mocap', data.mocap.position)
    changePose('#setpoint', data.setpoint.position)
    changePose('#laser_pose', data.lasers_pose.position)
    changePose('#local_pose', data.local.position)
    changeRaw('#lasers_raw', data.lasers_raw)

    document.getElementById("pitch").innerHTML = data.local.orientation.pitch.toFixed(3);
    document.getElementById("yaw").innerHTML = data.local.orientation.yaw.toFixed(3);
    document.getElementById("roll").innerHTML = data.local.orientation.roll.toFixed(3);
    document.getElementById("yaw_lasers").innerHTML = data.lasers_pose.orientation.yaw.toFixed(3);
    document.getElementById("yaw_filtered").innerHTML = data.laser_filtered.orientation.yaw.toFixed(3);
    //document.getElementById("battery_current").innerHTML = data.battery.current;
    //document.getElementById("battery_remaining").innerHTML = data.battery.remaining;
    document.getElementById("battery_voltage").innerHTML = data.battery.voltage.toFixed(3);
    document.getElementById("setpoint_yaw").innerHTML = data.setpoint.orientation.yaw.toFixed(3);
    document.getElementById("arm").innerHTML = data.armed;
    document.getElementById("mode").innerHTML = data.guided;

    data1 = data.local.position.x;
    data2 = data.local.position.y;

    plotLocalZ(data.header.seq / 25, data.local.position.z)
    plotLocalXY(data1, data2);

    $("div#selector").children().removeClass("btn-primary")
    $("button:contains('" + data.mode + "')").addClass("btn-primary")

});

function changePose(id, position) {
    var elem = $(id);
    elem.find('.datax').text(position.x.toFixed(3));
    elem.find('.datay').text(position.y.toFixed(3));
    elem.find('.dataz').text(position.z.toFixed(3));
}

function changeRaw(id, raw) {
    var elem = $(id);
    elem.find('.datax1').text(raw.lasers[0]);
    elem.find('.datax2').text(raw.lasers[1]);
    elem.find('.datay1').text(raw.lasers[2]);
    elem.find('.datay2').text(raw.lasers[3]);
    elem.find('.dataz1').text(raw.lasers[4]);
    elem.find('.dataz2').text(raw.lasers[5]);

}

function changeStatus(id, raw) {
    var elem = $(id);
    elem.find('.datax1').text(raw.status[0].toFixed(3));
    elem.find('.datax2').text(raw.status[1].toFixed(3));
    elem.find('.datay1').text(raw.status[2].toFixed(3));
    elem.find('.datay2').text(raw.status[3].toFixed(3));
    elem.find('.dataz1').text(raw.status[4].toFixed(3));
    elem.find('.dataz2').text(raw.status[5].toFixed(3));

}

$("button.landing").click(landing)

function landing() {
    alert("landing");
}

$("button.motorstop").click(motorstop)

function motorstop() {
    alert("motorstop");
}

$("button.actualpose").click(actualpose)

function actualpose() {
    alert("actualpose");

}

$("div#selector").children().click(function(event) {
    var modeToSend = event.target.innerHTML;
    console.log(modeToSend);
})

$("input.arm").change(function() {
    if (document.getElementById('option1').checked) {
        alert("Arm")
    } else {
        alert("disarm")
    }
});

function plotLocalXY(x, y, sx, sy) {
    var dataset = [{
        label: "position",
        data: [
            [x, y]
        ],

        points: {
            symbol: "circle",
        }
    }, {
        label: "setpoint",
        data: [
            [sx, sy]
        ],
        points: {
            symbol: "cross"
        }
    }, {
        data: [
            [currentSelection.x, currentSelection.y]
        ],
        points: {
            symbol: "square"
        }
    }];
    plotXY.setData(dataset);
    plotXY.draw();
}

function plotLocalZ(time, z) {
    dataZ.push([time, z])
    plotZ.setData([dataZ]);
    if (dataZ.length > 100)
        dataZ.shift()
    plotZ.setupGrid();
    plotZ.draw();
}<commit_msg>Correction of graphs<commit_after>var Configurations = {
    setpoints: {
        min: 0.5,
        max: 3.0
    }
}

var currentSelection = {
    x: 1,
    y: 1
}

var dataZ = [
    []
];

var plotXY = $.plot($("#PlotLocalXY"), [{
    label: "Local XY",
}], {
    yaxis: {
        min: 0,
        max: 4
    },
    xaxis: {
        min: 0,
        max: 4
    },
    points: {
        fill: false,
        radius: 7,
        show: true
    },
    colors: ["#26B99A", "#FE642E", "#808080"],
    grid: {
        borderWidth: {
            top: 0,
            right: 0,
            bottom: 1,
            left: 1
        },
        borderColor: {
            bottom: "#7F8790",
            left: "#7F8790"
        },
        hoverable: true,
        clickable: true,
        shadowSize: 0
    },
    selection: {
        mode: "xy",
        show: false,
        color: 'rgba(0,0,0,0)'
    }
});

plotXY.getPlaceholder().bind("plothover", function(event, pos) {
    if (pos.x < Configurations.setpoints.min)
        currentSelection.x = Configurations.setpoints.min
    else if (pos.x > Configurations.setpoints.max)
        currentSelection.x = Configurations.setpoints.max
    else
        currentSelection.x = pos.x

    if (pos.y < Configurations.setpoints.min)
        currentSelection.y = Configurations.setpoints.min
    else if (pos.y > Configurations.setpoints.max)
        currentSelection.y = Configurations.setpoints.max
    else
        currentSelection.y = pos.y
        //console.log(currentSelection);
});

plotXY.getPlaceholder().bind("plotclick", function(event, pos) {
    // Send setpoint
    console.log("Sending setpoint : ", currentSelection);
});

var plotZ = $.plot($("#PlotLocalZ"), [{
    label: "Local Z",
    data: dataZ
}], {
    series: {
        curvedLines: {
            apply: true,
            active: true,
            monotonicFit: true
        }
    },
    yaxis: {
        min: 0,
        max: 2.5
    },
    lines: {
        fillColor: "rgba(150, 0, 89, 0.12)",
        show: true
    }, //#96CA59 rgba(150, 202, 89, 0.42)
    points: {
        //fillColor: "#fff",
        radius: 7,
        show: false,
        symbol: "circle"
    },
    colors: ["#26B99A"],
    grid: {
        borderWidth: {
            top: 0,
            right: 0,
            bottom: 1,
            left: 1
        },
        borderColor: {
            bottom: "#7F8790",
            left: "#7F8790"
        }
    }
});

var ros = new ROSLIB.Ros({
    url: 'ws://192.168.137.18:9090'
});

ros.on('connection', function() {
    console.log('Connected to websocket server.');
});

ros.on('error', function(error) {
    console.log('Error connecting to websocket server: ', error);
});

ros.on('close', function() {
    console.log('Connection to websocket server closed.');
});

// Publishing a Topic
// ------------------

/*var cmdVel = new ROSLIB.Topic({
  ros : ros,
  name : '/cmd_vel',
  messageType : 'geometry_msgs/Twist'
});

var exampleTopic = new ROSLIB.Topic({
      ros: ros,
    name: '/com/endpoint/examp', // use a sensible namespace
      messageType: 'std_msgs/String'
});

var twist = new ROSLIB.Message({
linear : {
  x : 0.1,
  y : 0.2,
  z : 0.3
},
angular : {
  x : -0.1,
  y : -0.2,
  z : -0.3
}
});

var msg = new ROSLIB.Message({
    data : "yesouiok"
});

  console.log("Publishing cmd_vel");
  cmdVel.publish(twist);

  console.log("Publishing data");
  exampleTopic.publish(msg);

*/
var listener = new ROSLIB.Topic({
    ros: ros,
    name: 'web/report',
    messageType: 'laserpack/Report'
});

var data = {};

listener.subscribe(function(message) {
    //console.log(message);
    data = message;

    changePose('#laser_filtered', data.laser_filtered.position)
    changePose('#mocap', data.mocap.position)
    changePose('#setpoint', data.setpoint.position)
    changePose('#laser_pose', data.lasers_pose.position)
    changePose('#local_pose', data.local.position)
    changeRaw('#lasers_raw', data.lasers_raw)

    document.getElementById("pitch").innerHTML = data.local.orientation.pitch.toFixed(3);
    document.getElementById("yaw").innerHTML = data.local.orientation.yaw.toFixed(3);
    document.getElementById("roll").innerHTML = data.local.orientation.roll.toFixed(3);
    document.getElementById("yaw_lasers").innerHTML = data.lasers_pose.orientation.yaw.toFixed(3);
    document.getElementById("yaw_filtered").innerHTML = data.laser_filtered.orientation.yaw.toFixed(3);
    //document.getElementById("battery_current").innerHTML = data.battery.current;
    //document.getElementById("battery_remaining").innerHTML = data.battery.remaining;
    document.getElementById("battery_voltage").innerHTML = data.battery.voltage.toFixed(3);
    document.getElementById("setpoint_yaw").innerHTML = data.setpoint.orientation.yaw.toFixed(3);
    document.getElementById("arm").innerHTML = data.armed;
    document.getElementById("mode").innerHTML = data.guided;

    plotLocalXY(data.local.position.x, data.local.position.y,
        data.setpoint.position.x, data.setpoint.position.y);
    plotLocalZ(data.header.seq / 25, data.local.position.z)

    $("div#selector").children().removeClass("btn-primary")
    $("button:contains('" + data.mode + "')").addClass("btn-primary")

});

function changePose(id, position) {
    var elem = $(id);
    elem.find('.datax').text(position.x.toFixed(3));
    elem.find('.datay').text(position.y.toFixed(3));
    elem.find('.dataz').text(position.z.toFixed(3));
}

function changeRaw(id, raw) {
    var elem = $(id);
    elem.find('.datax1').text(raw.lasers[0]);
    elem.find('.datax2').text(raw.lasers[1]);
    elem.find('.datay1').text(raw.lasers[2]);
    elem.find('.datay2').text(raw.lasers[3]);
    elem.find('.dataz1').text(raw.lasers[4]);
    elem.find('.dataz2').text(raw.lasers[5]);

}

function changeStatus(id, raw) {
    var elem = $(id);
    elem.find('.datax1').text(raw.status[0].toFixed(3));
    elem.find('.datax2').text(raw.status[1].toFixed(3));
    elem.find('.datay1').text(raw.status[2].toFixed(3));
    elem.find('.datay2').text(raw.status[3].toFixed(3));
    elem.find('.dataz1').text(raw.status[4].toFixed(3));
    elem.find('.dataz2').text(raw.status[5].toFixed(3));

}

$("button.landing").click(landing)

function landing() {
    alert("landing");
}

$("button.motorstop").click(motorstop)

function motorstop() {
    alert("motorstop");
}

$("button.actualpose").click(actualpose)

function actualpose() {
    alert("actualpose");

}

$("div#selector").children().click(function(event) {
    var modeToSend = event.target.innerHTML;
    console.log(modeToSend);
})

$("input.arm").change(function() {
    if (document.getElementById('option1').checked) {
        alert("Arm")
    } else {
        alert("disarm")
    }
});

function plotLocalXY(x, y, sx, sy) {
    var dataset = [{
        label: "position",
        data: [
            [x, y]
        ],

        points: {
            symbol: "circle",
        }
    }, {
        label: "setpoint",
        data: [
            [sx, sy]
        ],
        points: {
            symbol: "cross"
        }
    }, {
        data: [
            [currentSelection.x, currentSelection.y]
        ],
        points: {
            symbol: "square"
        }
    }];
    plotXY.setData(dataset);
    plotXY.draw();
}

function plotLocalZ(time, z) {
    dataZ.push([time, z])
    plotZ.setData([dataZ]);
    if (dataZ.length > 100)
        dataZ.shift()
    plotZ.setupGrid();
    plotZ.draw();
}<|endoftext|>


<commit_before><commit_msg>Update LMexpress.js<commit_after><|endoftext|>


<commit_before><commit_msg>Update shop.js<commit_after><|endoftext|>


<commit_before>/**
 * @providesModule RNBeacon
 * @flow
 */
'use strict';

var NativeRNBeacon = require('NativeModules').RNBeacon;

module.exports = RNBeacon;
<commit_msg>:bug: Hotfix<commit_after>/**
 * @providesModule RNBeacon
 * @flow
 */
'use strict';

var NativeRNBeacon = require('NativeModules').RNBeacon;

module.exports = NativeRNBeacon;
<|endoftext|>


<commit_before>/**
 *
 * @providesModule RNMEvaluator
 * @flow
 */
'use strict';

var {
  DeviceEventEmitter,
  NativeModules: {
    RNMEvaluator
  }
} = require('react-native');

var execute = (data, executor) => {
  var {name,args,callId} = data,
      cb = res => {
      	if (res instanceof Error) {
      	  RNMEvaluator.functionCallCompleted(callId, `Function ${name} raised an error ${res.message}:${res.stack}`,null);
      	} else {
      	   RNMEvaluator.functionCallCompleted(callId, null, { _value:res });
        }
      }, func,err;

  try {
    func = eval(name);
  } catch (e) {
    err = e;
  }

  if (err) {
    return RNMEvaluator.functionCallCompleted(callId, `Error finding a function ${err.message}`,null);
  }

  if (!func) {
    return RNMEvaluator.functionCallCompleted(callId, `Function ${name} cannot be found`,null);
  }

  if (typeof func !== 'function') {
    return RNMEvaluator.functionCallCompleted(callId, `${name} is not a function`,null);
  }

  try {
    executor(func).apply(null,args.concat(cb))
  } catch (e) {
    RNMEvaluator.functionCallCompleted(callId, `Function ${name} raised an error ${e.message}:${e.stack}`,null);
  }
}

// TODO: move to AppEventEmitter once App events are supported on android.
DeviceEventEmitter.addListener('RNMEvaluator.callAsyncFunction',
				  data => execute(data, f => f));

DeviceEventEmitter.addListener('RNMEvaluator.callSyncFunction',
				  data => execute(data, f => (...args) => args.pop()(f.apply(null,args))));

exports.emit = (name, res) => {
  RNMEvaluator.emit(name, { _value:res });
};
<commit_msg>add check for Promises to RNMEvaluator<commit_after>/**
 *
 * @providesModule RNMEvaluator
 * @flow
 */
'use strict';

var {
  DeviceEventEmitter,
  NativeModules: {
    RNMEvaluator
  }
} = require('react-native');

var execute = (data, executor) => {
  var {name,args,callId} = data,
      cb = res => {
        if (res instanceof Promise) {
          res.then(result => RNMEvaluator.functionCallCompleted(callId, null, {_value: result}));
          return;
        }
      	if (res instanceof Error) {
      	  RNMEvaluator.functionCallCompleted(callId, `Function ${name} raised an error ${res.message}:${res.stack}`,null);
      	} else {
      	   RNMEvaluator.functionCallCompleted(callId, null, { _value:res });
        }
      }, func,err;

  try {
    func = eval(name);
  } catch (e) {
    err = e;
  }

  if (err) {
    return RNMEvaluator.functionCallCompleted(callId, `Error finding a function ${err.message}`,null);
  }

  if (!func) {
    return RNMEvaluator.functionCallCompleted(callId, `Function ${name} cannot be found`,null);
  }

  if (typeof func !== 'function') {
    return RNMEvaluator.functionCallCompleted(callId, `${name} is not a function`,null);
  }

  try {
    executor(func).apply(null,args.concat(cb))
  } catch (e) {
    RNMEvaluator.functionCallCompleted(callId, `Function ${name} raised an error ${e.message}:${e.stack}`,null);
  }
}

// TODO: move to AppEventEmitter once App events are supported on android.
DeviceEventEmitter.addListener('RNMEvaluator.callAsyncFunction',
				  data => execute(data, f => f));

DeviceEventEmitter.addListener('RNMEvaluator.callSyncFunction',
				  data => execute(data, f => (...args) => args.pop()(f.apply(null,args))));

exports.emit = (name, res) => {
  RNMEvaluator.emit(name, { _value:res });
};
<|endoftext|>