<commit_before>(function (webgl) {

    var c_SystemUpdate = {
        "pointLightOn": {
            staticValue : "MAX_POINTLIGHTS",
            staticSize: ["pointLightOn", "pointLightAttenuation", "pointLightIntensity", "pointLightPosition"]
        },
        "directionalLightOn" : {
            staticValue: "MAX_DIRECTIONALLIGHTS",
            staticSize: ["directionalLightOn", "directionalLightIntensity", "directionalLightDirection" ]
        },
        "spotLightOn" : {
            staticValue: "MAX_SPOTLIGHTS",
            staticSize: ["spotLightOn", "spotLightAttenuation", "spotLightIntensity",
                "spotLightPosition", "spotLightDirection", "spotLightCosFalloffAngle", "spotLightCosSoftFalloffAngle", "spotLightCastShadow", "spotLightShadowBias", "spotLightShadowMap", "spotLightMatrix"]
        }
    };

    function addDefaultChanneling(vsConfig, inputName){
        var outputName = XML3D.webgl.JSShaderComposer.convertEnvName(inputName);
        vsConfig.channelAttribute(inputName, outputName, null);
    }

    function channelVsAttribute(vsConfig, inputName, spaceInfo){
        if(!spaceInfo[inputName]){
            addDefaultChanneling(vsConfig, inputName);
            return;
        }

        var i = spaceInfo[inputName].length;
        while(i--){
            var entry = spaceInfo[inputName][i];
            var outputName = XML3D.webgl.JSShaderComposer.convertEnvName(entry.name), code = null;
            switch(entry.space){
                case Shade.SPACE_VECTOR_TYPES.OBJECT: break;
                case Shade.SPACE_VECTOR_TYPES.VIEW_POINT:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelViewMatrix", true);
                    code = outputName + " = ( modelViewMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                    break;
                case Shade.SPACE_VECTOR_TYPES.VIEW_NORMAL:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT3X3, "modelViewMatrixN", true);
                    code =  outputName + " = normalize( modelViewMatrixN * #I{" + inputName + "} );";
                    break;
                case Shade.SPACE_VECTOR_TYPES.WORLD_POINT:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelMatrix", true);
                    code = outputName + " = ( modelMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                    break;
                case Shade.SPACE_VECTOR_TYPES.WORLD_NORMAL:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT3X3, "modelMatrixN", true);
                    code =  outputName + " = normalize( modelMatrixN * #I{" + inputName + "} );";
                    break;
                default:
                    throw new Error("Can't handle Space Type: " + entry.space);
            }
            vsConfig.channelAttribute(inputName, outputName, code);
        }
    }

    /**
     * @param {Xflow.DATA_TYPE} xflowType
     */
    var convertXflow2ShadeType = function(xflowType, source) {
        var result = {}
        switch (xflowType) {
            case Xflow.DATA_TYPE.BOOL:
                result.type = Shade.TYPES.BOOLEAN;
                break;
            case Xflow.DATA_TYPE.INT:
                result.type = Shade.TYPES.INT;
                break;
            case Xflow.DATA_TYPE.FLOAT:
                result.type = Shade.TYPES.NUMBER;
                break;
            case Xflow.DATA_TYPE.FLOAT2:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT2;
                break;
            case Xflow.DATA_TYPE.FLOAT3:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT3;
                break;
            case Xflow.DATA_TYPE.FLOAT4:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT4;
                break;
            case Xflow.DATA_TYPE.TEXTURE:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.TEXTURE;
                break;
            case Xflow.DATA_TYPE.UNKNOWN:
            default:
                throw new Error("Unknown Xflow DataType: " + xflowType);
        }
        result.source = source;
        return result;
    }

    /**
     * @param context
     * @param sourceTemplate
     * @param dataCallback
     * @constructor
     */
    var JSShaderClosure = function(context, sourceTemplate, extractedParams) {
        webgl.AbstractShaderClosure.call(this, context);
        this.sourceTemplate = sourceTemplate;
        this.extractedParams = extractedParams;
        this.uniformSetter = function() {};
        this.uniformConverter = [];
    };

    XML3D.createClass(JSShaderClosure, webgl.AbstractShaderClosure, {
        /**
         *
         * @param {GLScene} scene
         * @param {Xflow.ComputeResult} shaderResult
         * @param objectData
         */
        createSources: function(scene, shaderResult, vsRequest) {

            var vsDataResult = vsRequest.getResult();

            var contextData = {
                "this" : webgl.getJSSystemConfiguration(this.context),
                "global.shade" :[{"extra": {"type": "object","kind": "any","global" : true,"info" : {}}}]
            };

            var systemUniforms = scene.systemUniforms, systemInfo = contextData["this"].info;
            for(var systemSource in c_SystemUpdate){
                var entry = c_SystemUpdate[systemSource];
                var length = systemUniforms[systemSource] && systemUniforms[systemSource].length;
                systemInfo[entry.staticValue].staticValue = length;
                for(var i = 0; i < entry.staticSize.length; ++i)
                    systemInfo[entry.staticSize[i]].staticSize = length;
            }

            var contextInfo = contextData["global.shade"][0].extra.info;

            var shaderEntries = shaderResult && shaderResult.getOutputMap(),
                vsShaderOutput = vsDataResult && vsDataResult.outputNames;

            for(var i = 0; i < this.extractedParams.length; ++i){
                var paramName = this.extractedParams[i];
                if(vsShaderOutput && vsShaderOutput.indexOf(paramName) != -1){
                    contextInfo[paramName] = convertXflow2ShadeType(vsDataResult.getOutputType(paramName),
                        vsDataResult.isOutputUniform(paramName) ? Shade.SOURCES.UNIFORM : Shade.SOURCES.VERTEX);
                }
                else if(shaderEntries && shaderEntries[paramName]){
                    contextInfo[paramName] = convertXflow2ShadeType(shaderEntries[paramName].type, Shade.SOURCES.UNIFORM);
                }
            }

            XML3D.debug.logDebug("CONTEXT:", contextData);
            try{
                var implementation = scene.deferred ? "xml3d-glsl-deferred" : "xml3d-glsl-forward";
                var workSet = new Shade.WorkingSet();
                workSet.parse(this.sourceTemplate);
                workSet.analyze(contextData, implementation, {
                    propagateConstants: true,
                    validate: true,
                    sanitize: true,
                    transformSpaces: true
                });
                var spaceInfo = workSet.getProcessingData('spaceInfo');
                var glslShader = workSet.compileFragmentShader({useStatic: true});
                this.uniformSetter = glslShader.uniformSetter;
                this.source = {
                    fragment: glslShader.source,
                    vertex:  this.createVertexShader(vsRequest, vsDataResult, spaceInfo)
                }
                if(scene.deferred){
                    var signatures = workSet.getProcessingData("colorClosureSignatures");
                    scene.colorClosureSignatures.push.apply(scene.colorClosureSignatures, signatures);
                }

            }
            catch(e){
                webgl.SystemNotifier.sendEvent('shadejs', {
                    shadejsType : "error",
                    event: e,
                    code: this.sourceTemplate
                });

                var errorMessage = "Shade.js Compile Error:\n" + e.message + "\n------------\n"
                + "Shader Source:" + "\n------------\n" + XML3D.debug.formatSourceCode(this.sourceTemplate);
                throw new Error(errorMessage);
            }

            // TODO: Handle errors.
            XML3D.debug.logDebug(this.source.vertex);
            XML3D.debug.logDebug(this.source.fragment);

            webgl.SystemNotifier.sendEvent('shadejs', {
                shadejsType : "success",
                vertexShader: this.source.vertex,
                fragmentShader: this.source.fragment
            });

            return true;
        },

        createVertexShader: function(vsRequest, vsDataResult, spaceInfo){
            var vsConfig = vsRequest.getConfig();
            var names = vsDataResult.outputNames;
            for(var i = 0; i < names.length; ++i){
                channelVsAttribute(vsConfig, names[i], spaceInfo);
            }
            vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelViewProjectionMatrix", true);
            vsConfig.addCodeFragment( "gl_Position = modelViewProjectionMatrix * vec4(#I{position}, 1.0);");
            return vsRequest.getVertexShader().getGLSLCode();
        },

        setUniformVariables: function(envNames, sysNames, inputCollection){
            this.uniformSetter(envNames, sysNames, inputCollection, this.program.setUniformVariable.bind(this.program));
        },

        getTransparencyFromInputData: function(dataMap){
            // TODO: Compute Transparency
            return false;
        },

        /* Default values are compiled into shade.js */
        setDefaultUniforms: function() {}

    });
    webgl.JSShaderClosure = JSShaderClosure;

}(XML3D.webgl));
<commit_msg>Activated extraction of uniform expressions<commit_after>(function (webgl) {

    var c_SystemUpdate = {
        "pointLightOn": {
            staticValue : "MAX_POINTLIGHTS",
            staticSize: ["pointLightOn", "pointLightAttenuation", "pointLightIntensity", "pointLightPosition"]
        },
        "directionalLightOn" : {
            staticValue: "MAX_DIRECTIONALLIGHTS",
            staticSize: ["directionalLightOn", "directionalLightIntensity", "directionalLightDirection" ]
        },
        "spotLightOn" : {
            staticValue: "MAX_SPOTLIGHTS",
            staticSize: ["spotLightOn", "spotLightAttenuation", "spotLightIntensity",
                "spotLightPosition", "spotLightDirection", "spotLightCosFalloffAngle", "spotLightCosSoftFalloffAngle", "spotLightCastShadow", "spotLightShadowBias", "spotLightShadowMap", "spotLightMatrix"]
        }
    };

    function addDefaultChanneling(vsConfig, inputName){
        var outputName = XML3D.webgl.JSShaderComposer.convertEnvName(inputName);
        vsConfig.channelAttribute(inputName, outputName, null);
    }

    function channelVsAttribute(vsConfig, inputName, spaceInfo){
        if(!spaceInfo[inputName]){
            addDefaultChanneling(vsConfig, inputName);
            return;
        }

        var i = spaceInfo[inputName].length;
        while(i--){
            var entry = spaceInfo[inputName][i];
            var outputName = XML3D.webgl.JSShaderComposer.convertEnvName(entry.name), code = null;
            switch(entry.space){
                case Shade.SPACE_VECTOR_TYPES.OBJECT: break;
                case Shade.SPACE_VECTOR_TYPES.VIEW_POINT:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelViewMatrix", true);
                    code = outputName + " = ( modelViewMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                    break;
                case Shade.SPACE_VECTOR_TYPES.VIEW_NORMAL:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT3X3, "modelViewMatrixN", true);
                    code =  outputName + " = normalize( modelViewMatrixN * #I{" + inputName + "} );";
                    break;
                case Shade.SPACE_VECTOR_TYPES.WORLD_POINT:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelMatrix", true);
                    code = outputName + " = ( modelMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                    break;
                case Shade.SPACE_VECTOR_TYPES.WORLD_NORMAL:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT3X3, "modelMatrixN", true);
                    code =  outputName + " = normalize( modelMatrixN * #I{" + inputName + "} );";
                    break;
                default:
                    throw new Error("Can't handle Space Type: " + entry.space);
            }
            vsConfig.channelAttribute(inputName, outputName, code);
        }
    }

    /**
     * @param {Xflow.DATA_TYPE} xflowType
     */
    var convertXflow2ShadeType = function(xflowType, source) {
        var result = {}
        switch (xflowType) {
            case Xflow.DATA_TYPE.BOOL:
                result.type = Shade.TYPES.BOOLEAN;
                break;
            case Xflow.DATA_TYPE.INT:
                result.type = Shade.TYPES.INT;
                break;
            case Xflow.DATA_TYPE.FLOAT:
                result.type = Shade.TYPES.NUMBER;
                break;
            case Xflow.DATA_TYPE.FLOAT2:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT2;
                break;
            case Xflow.DATA_TYPE.FLOAT3:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT3;
                break;
            case Xflow.DATA_TYPE.FLOAT4:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT4;
                break;
            case Xflow.DATA_TYPE.TEXTURE:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.TEXTURE;
                break;
            case Xflow.DATA_TYPE.UNKNOWN:
            default:
                throw new Error("Unknown Xflow DataType: " + xflowType);
        }
        result.source = source;
        return result;
    }

    /**
     * @param context
     * @param sourceTemplate
     * @param dataCallback
     * @constructor
     */
    var JSShaderClosure = function(context, sourceTemplate, extractedParams) {
        webgl.AbstractShaderClosure.call(this, context);
        this.sourceTemplate = sourceTemplate;
        this.extractedParams = extractedParams;
        this.uniformSetter = function() {};
        this.uniformConverter = [];
    };

    XML3D.createClass(JSShaderClosure, webgl.AbstractShaderClosure, {
        /**
         *
         * @param {GLScene} scene
         * @param {Xflow.ComputeResult} shaderResult
         * @param objectData
         */
        createSources: function(scene, shaderResult, vsRequest) {

            var vsDataResult = vsRequest.getResult();

            var contextData = {
                "this" : webgl.getJSSystemConfiguration(this.context),
                "global.shade" :[{"extra": {"type": "object","kind": "any","global" : true,"info" : {}}}]
            };

            var systemUniforms = scene.systemUniforms, systemInfo = contextData["this"].info;
            for(var systemSource in c_SystemUpdate){
                var entry = c_SystemUpdate[systemSource];
                var length = systemUniforms[systemSource] && systemUniforms[systemSource].length;
                systemInfo[entry.staticValue].staticValue = length;
                for(var i = 0; i < entry.staticSize.length; ++i)
                    systemInfo[entry.staticSize[i]].staticSize = length;
            }

            var contextInfo = contextData["global.shade"][0].extra.info;

            var shaderEntries = shaderResult && shaderResult.getOutputMap(),
                vsShaderOutput = vsDataResult && vsDataResult.outputNames;

            for(var i = 0; i < this.extractedParams.length; ++i){
                var paramName = this.extractedParams[i];
                if(vsShaderOutput && vsShaderOutput.indexOf(paramName) != -1){
                    contextInfo[paramName] = convertXflow2ShadeType(vsDataResult.getOutputType(paramName),
                        vsDataResult.isOutputUniform(paramName) ? Shade.SOURCES.UNIFORM : Shade.SOURCES.VERTEX);
                }
                else if(shaderEntries && shaderEntries[paramName]){
                    contextInfo[paramName] = convertXflow2ShadeType(shaderEntries[paramName].type, Shade.SOURCES.UNIFORM);
                }
            }

            XML3D.debug.logDebug("CONTEXT:", contextData);
            try{
                var implementation = scene.deferred ? "xml3d-glsl-deferred" : "xml3d-glsl-forward";
                var workSet = new Shade.WorkingSet();
                workSet.parse(this.sourceTemplate);
                var options = {
                    propagateConstants: true,
                    validate: true,
                    sanitize: true,
                    transformSpaces: true,
                    extractUniformExpressions: true
                };

                workSet.analyze(contextData, implementation, options);
                var spaceInfo = workSet.getProcessingData('spaceInfo');
                var glslShader = workSet.compileFragmentShader({useStatic: true, uniformExpressions: options.uniformExpressions});
                this.uniformSetter = glslShader.uniformSetter;
                this.source = {
                    fragment: glslShader.source,
                    vertex:  this.createVertexShader(vsRequest, vsDataResult, spaceInfo)
                }
                if(scene.deferred){
                    var signatures = workSet.getProcessingData("colorClosureSignatures");
                    scene.colorClosureSignatures.push.apply(scene.colorClosureSignatures, signatures);
                }

            }
            catch(e){
                webgl.SystemNotifier.sendEvent('shadejs', {
                    shadejsType : "error",
                    event: e,
                    code: this.sourceTemplate
                });

                var errorMessage = "Shade.js Compile Error:\n" + e.message + "\n------------\n"
                + "Shader Source:" + "\n------------\n" + XML3D.debug.formatSourceCode(this.sourceTemplate);
                throw new Error(errorMessage);
            }

            // TODO: Handle errors.
            XML3D.debug.logDebug(this.source.vertex);
            XML3D.debug.logDebug(this.source.fragment);

            webgl.SystemNotifier.sendEvent('shadejs', {
                shadejsType : "success",
                vertexShader: this.source.vertex,
                fragmentShader: this.source.fragment
            });

            return true;
        },

        createVertexShader: function(vsRequest, vsDataResult, spaceInfo){
            var vsConfig = vsRequest.getConfig();
            var names = vsDataResult.outputNames;
            for(var i = 0; i < names.length; ++i){
                channelVsAttribute(vsConfig, names[i], spaceInfo);
            }
            vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelViewProjectionMatrix", true);
            vsConfig.addCodeFragment( "gl_Position = modelViewProjectionMatrix * vec4(#I{position}, 1.0);");
            return vsRequest.getVertexShader().getGLSLCode();
        },

        setUniformVariables: function(envNames, sysNames, inputCollection){
            this.uniformSetter(envNames, sysNames, inputCollection, this.program.setUniformVariable.bind(this.program));
        },

        getTransparencyFromInputData: function(dataMap){
            // TODO: Compute Transparency
            return false;
        },

        /* Default values are compiled into shade.js */
        setDefaultUniforms: function() {}

    });
    webgl.JSShaderClosure = JSShaderClosure;

}(XML3D.webgl));
<|endoftext|>


<commit_before>(function (webgl) {

    var c_SystemUpdate = {
        "pointLightOn": {
            staticValue : "MAX_POINTLIGHTS",
            staticSize: ["pointLightOn", "pointLightAttenuation", "pointLightIntensity", "pointLightPosition"]
        },
        "directionalLightOn" : {
            staticValue: "MAX_DIRECTIONALLIGHTS",
            staticSize: ["directionalLightOn", "directionalLightIntensity", "directionalLightDirection" ]
        },
        "spotLightOn" : {
            staticValue: "MAX_SPOTLIGHTS",
            staticSize: ["spotLightOn", "spotLightAttenuation", "spotLightIntensity",
                "spotLightPosition", "spotLightDirection", "spotLightCosFalloffAngle", "spotLightCosSoftFalloffAngle"]
        }
    };

    function addDefaultChanneling(vsConfig, inputName){
        var outputName = XML3D.webgl.JSShaderComposer.convertEnvName(inputName);
        vsConfig.channelAttribute(inputName, outputName, null);
    }

    function channelVsAttribute(vsConfig, inputName, spaceInfo){
        if(!spaceInfo[inputName]){
            addDefaultChanneling(vsConfig, inputName);
            return;
        }

        var i = spaceInfo[inputName].length;
        while(i--){
            var entry = spaceInfo[inputName][i];
            var outputName = XML3D.webgl.JSShaderComposer.convertEnvName(entry.name), code = null;
            switch(entry.space){
                case Shade.SPACE_VECTOR_TYPES.OBJECT: break;
                case Shade.SPACE_VECTOR_TYPES.VIEW_POINT:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelViewMatrix", true);
                    code = outputName + " = ( modelViewMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                    break;
                case Shade.SPACE_VECTOR_TYPES.VIEW_NORMAL:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT3X3, "modelViewMatrixN", true);
                    code =  outputName + " = normalize( modelViewMatrixN * #I{" + inputName + "} );";
                    break;
                case Shade.SPACE_VECTOR_TYPES.WORLD_POINT:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelMatrix", true);
                    code = outputName + " = ( modelMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                    break;
                case Shade.SPACE_VECTOR_TYPES.WORLD_NORMAL:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT3X3, "modelMatrixN", true);
                    code =  outputName + " = normalize( modelMatrixN * #I{" + inputName + "} );";
                    break;
                default:
                    throw new Error("Can't handle Space Type: " + entry.space);
            }
            vsConfig.channelAttribute(inputName, outputName, code);
        }
    }

    /**
     * @param {Xflow.DATA_TYPE} xflowType
     */
    var convertXflow2ShadeType = function(xflowType, source) {
        var result = {}
        switch (xflowType) {
            case Xflow.DATA_TYPE.BOOL:
                result.type = Shade.TYPES.BOOLEAN;
                break;
            case Xflow.DATA_TYPE.INT:
                result.type = Shade.TYPES.INT;
                break;
            case Xflow.DATA_TYPE.FLOAT:
                result.type = Shade.TYPES.NUMBER;
                break;
            case Xflow.DATA_TYPE.FLOAT2:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT2;
                break;
            case Xflow.DATA_TYPE.FLOAT3:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT3;
                break;
            case Xflow.DATA_TYPE.FLOAT4:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT4;
                break;
            case Xflow.DATA_TYPE.TEXTURE:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.TEXTURE;
                break;
            case Xflow.DATA_TYPE.UNKNOWN:
            default:
                throw new Error("Unknown Xflow DataType: " + xflowType);
        }
        result.source = source;
        return result;
    }

    /**
     * @param context
     * @param sourceTemplate
     * @param dataCallback
     * @constructor
     */
    var JSShaderClosure = function(context, sourceTemplate, extractedParams) {
        webgl.AbstractShaderClosure.call(this, context);
        this.sourceTemplate = sourceTemplate;
        this.extractedParams = extractedParams;
        this.uniformSetter = function() {};
        this.uniformConverter = [];
    };

    XML3D.createClass(JSShaderClosure, webgl.AbstractShaderClosure, {
        /**
         *
         * @param {GLScene} scene
         * @param {Xflow.ComputeResult} shaderResult
         * @param objectData
         */
        createSources: function(scene, shaderResult, vsRequest) {

            var vsDataResult = vsRequest.getResult();

            var contextData = {
                "this" : webgl.getJSSystemConfiguration(this.context),
                "global.shade" :[{"extra": {"type": "object","kind": "any","global" : true,"info" : {}}}]
            };

            var systemUniforms = scene.systemUniforms, systemInfo = contextData["this"].info;
            for(var systemSource in c_SystemUpdate){
                var entry = c_SystemUpdate[systemSource];
                var length = systemUniforms[systemSource] && systemUniforms[systemSource].length;
                systemInfo[entry.staticValue].staticValue = length;
                for(var i = 0; i < entry.staticSize.length; ++i)
                    systemInfo[entry.staticSize[i]].staticSize = length;
            }

            var contextInfo = contextData["global.shade"][0].extra.info;

            var shaderEntries = shaderResult && shaderResult.getOutputMap(),
                vsShaderOutput = vsDataResult && vsDataResult.outputNames;

            for(var i = 0; i < this.extractedParams.length; ++i){
                var paramName = this.extractedParams[i];
                if(vsShaderOutput && vsShaderOutput.indexOf(paramName) != -1){
                    contextInfo[paramName] = convertXflow2ShadeType(vsDataResult.getOutputType(paramName),
                        vsDataResult.isOutputUniform(paramName) ? Shade.SOURCES.UNIFORM : Shade.SOURCES.VERTEX);
                }
                else if(shaderEntries && shaderEntries[paramName]){
                    contextInfo[paramName] = convertXflow2ShadeType(shaderEntries[paramName].type, Shade.SOURCES.UNIFORM);
                }
            }

            XML3D.debug.logDebug("CONTEXT:", contextData);
            try{
                var aast = Shade.parseAndInferenceExpression(this.sourceTemplate, {
                    inject: contextData,
                    implementation: "xml3d-glsl-forward",
                    propagateConstants: true,
                    validate: true,
                    sanitize: true,
                    transformSpaces: false
                });
                var spaceInfo = Shade.resolveSpaces(aast);
                var glslShader = Shade.compileFragmentShader(aast, {useStatic: true});
                this.uniformSetter = glslShader.uniformSetter;
                this.source = {
                    fragment: glslShader.source,
                    vertex:  this.createVertexShader(vsRequest, vsDataResult, spaceInfo)
                }
            }
            catch(e){
                webgl.SystemNotifier.sendEvent('shadejs', {
                    shadejsType : "error",
                    event: e,
                    code: this.sourceTemplate
                });

                var errorMessage = "Shade.js Compile Error:\n" + e.message + "\n------------\n"
                + "Shader Source:" + "\n------------\n" + XML3D.debug.formatSourceCode(this.sourceTemplate);
                throw new Error(errorMessage);
            }

            // TODO: Handle errors.
            XML3D.debug.logDebug(this.source.vertex);
            XML3D.debug.logDebug(this.source.fragment);

            webgl.SystemNotifier.sendEvent('shadejs', {
                shadejsType : "success",
                vertexShader: this.source.vertex,
                fragmentShader: this.source.fragment
            });

            return true;
        },

        createVertexShader: function(vsRequest, vsDataResult, spaceInfo){
            var vsConfig = vsRequest.getConfig();
            var names = vsDataResult.outputNames;
            for(var i = 0; i < names.length; ++i){
                channelVsAttribute(vsConfig, names[i], spaceInfo);
            }
            vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelViewProjectionMatrix", true);
            vsConfig.addCodeFragment( "gl_Position = modelViewProjectionMatrix * vec4(#I{position}, 1.0);");
            return vsRequest.getVertexShader().getGLSLCode();
        },

        setUniformVariables: function(envNames, sysNames, inputCollection){
            this.uniformSetter(envNames, sysNames, inputCollection, this.program.setUniformVariable.bind(this.program));
        },

        getTransparencyFromInputData: function(dataMap){
            // TODO: Compute Transparency
            return false;
        },

        /* Default values are compiled into shade.js */
        setDefaultUniforms: function() {}

    });
    webgl.JSShaderClosure = JSShaderClosure;

}(XML3D.webgl));
<commit_msg>Use new WorkSet as interface to shade.js<commit_after>(function (webgl) {

    var c_SystemUpdate = {
        "pointLightOn": {
            staticValue : "MAX_POINTLIGHTS",
            staticSize: ["pointLightOn", "pointLightAttenuation", "pointLightIntensity", "pointLightPosition"]
        },
        "directionalLightOn" : {
            staticValue: "MAX_DIRECTIONALLIGHTS",
            staticSize: ["directionalLightOn", "directionalLightIntensity", "directionalLightDirection" ]
        },
        "spotLightOn" : {
            staticValue: "MAX_SPOTLIGHTS",
            staticSize: ["spotLightOn", "spotLightAttenuation", "spotLightIntensity",
                "spotLightPosition", "spotLightDirection", "spotLightCosFalloffAngle", "spotLightCosSoftFalloffAngle"]
        }
    };

    function addDefaultChanneling(vsConfig, inputName){
        var outputName = XML3D.webgl.JSShaderComposer.convertEnvName(inputName);
        vsConfig.channelAttribute(inputName, outputName, null);
    }

    function channelVsAttribute(vsConfig, inputName, spaceInfo){
        if(!spaceInfo[inputName]){
            addDefaultChanneling(vsConfig, inputName);
            return;
        }

        var i = spaceInfo[inputName].length;
        while(i--){
            var entry = spaceInfo[inputName][i];
            var outputName = XML3D.webgl.JSShaderComposer.convertEnvName(entry.name), code = null;
            switch(entry.space){
                case Shade.SPACE_VECTOR_TYPES.OBJECT: break;
                case Shade.SPACE_VECTOR_TYPES.VIEW_POINT:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelViewMatrix", true);
                    code = outputName + " = ( modelViewMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                    break;
                case Shade.SPACE_VECTOR_TYPES.VIEW_NORMAL:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT3X3, "modelViewMatrixN", true);
                    code =  outputName + " = normalize( modelViewMatrixN * #I{" + inputName + "} );";
                    break;
                case Shade.SPACE_VECTOR_TYPES.WORLD_POINT:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelMatrix", true);
                    code = outputName + " = ( modelMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                    break;
                case Shade.SPACE_VECTOR_TYPES.WORLD_NORMAL:
                    vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT3X3, "modelMatrixN", true);
                    code =  outputName + " = normalize( modelMatrixN * #I{" + inputName + "} );";
                    break;
                default:
                    throw new Error("Can't handle Space Type: " + entry.space);
            }
            vsConfig.channelAttribute(inputName, outputName, code);
        }
    }

    /**
     * @param {Xflow.DATA_TYPE} xflowType
     */
    var convertXflow2ShadeType = function(xflowType, source) {
        var result = {}
        switch (xflowType) {
            case Xflow.DATA_TYPE.BOOL:
                result.type = Shade.TYPES.BOOLEAN;
                break;
            case Xflow.DATA_TYPE.INT:
                result.type = Shade.TYPES.INT;
                break;
            case Xflow.DATA_TYPE.FLOAT:
                result.type = Shade.TYPES.NUMBER;
                break;
            case Xflow.DATA_TYPE.FLOAT2:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT2;
                break;
            case Xflow.DATA_TYPE.FLOAT3:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT3;
                break;
            case Xflow.DATA_TYPE.FLOAT4:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.FLOAT4;
                break;
            case Xflow.DATA_TYPE.TEXTURE:
                result.type = Shade.TYPES.OBJECT;
                result.kind = Shade.OBJECT_KINDS.TEXTURE;
                break;
            case Xflow.DATA_TYPE.UNKNOWN:
            default:
                throw new Error("Unknown Xflow DataType: " + xflowType);
        }
        result.source = source;
        return result;
    }

    /**
     * @param context
     * @param sourceTemplate
     * @param dataCallback
     * @constructor
     */
    var JSShaderClosure = function(context, sourceTemplate, extractedParams) {
        webgl.AbstractShaderClosure.call(this, context);
        this.sourceTemplate = sourceTemplate;
        this.extractedParams = extractedParams;
        this.uniformSetter = function() {};
        this.uniformConverter = [];
    };

    XML3D.createClass(JSShaderClosure, webgl.AbstractShaderClosure, {
        /**
         *
         * @param {GLScene} scene
         * @param {Xflow.ComputeResult} shaderResult
         * @param objectData
         */
        createSources: function(scene, shaderResult, vsRequest) {

            var vsDataResult = vsRequest.getResult();

            var contextData = {
                "this" : webgl.getJSSystemConfiguration(this.context),
                "global.shade" :[{"extra": {"type": "object","kind": "any","global" : true,"info" : {}}}]
            };

            var systemUniforms = scene.systemUniforms, systemInfo = contextData["this"].info;
            for(var systemSource in c_SystemUpdate){
                var entry = c_SystemUpdate[systemSource];
                var length = systemUniforms[systemSource] && systemUniforms[systemSource].length;
                systemInfo[entry.staticValue].staticValue = length;
                for(var i = 0; i < entry.staticSize.length; ++i)
                    systemInfo[entry.staticSize[i]].staticSize = length;
            }

            var contextInfo = contextData["global.shade"][0].extra.info;

            var shaderEntries = shaderResult && shaderResult.getOutputMap(),
                vsShaderOutput = vsDataResult && vsDataResult.outputNames;

            for(var i = 0; i < this.extractedParams.length; ++i){
                var paramName = this.extractedParams[i];
                if(vsShaderOutput && vsShaderOutput.indexOf(paramName) != -1){
                    contextInfo[paramName] = convertXflow2ShadeType(vsDataResult.getOutputType(paramName),
                        vsDataResult.isOutputUniform(paramName) ? Shade.SOURCES.UNIFORM : Shade.SOURCES.VERTEX);
                }
                else if(shaderEntries && shaderEntries[paramName]){
                    contextInfo[paramName] = convertXflow2ShadeType(shaderEntries[paramName].type, Shade.SOURCES.UNIFORM);
                }
            }

            XML3D.debug.logDebug("CONTEXT:", contextData);
            try{
                var workSet = new Shade.WorkingSet();
                workSet.parse(this.sourceTemplate);
                workSet.analyze(contextData, "xml3d-glsl-forward", {
                    propagateConstants: true,
                    validate: true,
                    sanitize: true,
                    transformSpaces: true
                });
                var spaceInfo = workSet.getProcessingData('spaceInfo');
                var glslShader = workSet.compileFragmentShader({useStatic: true});
                this.uniformSetter = glslShader.uniformSetter;
                this.source = {
                    fragment: glslShader.source,
                    vertex:  this.createVertexShader(vsRequest, vsDataResult, spaceInfo)
                }
            }
            catch(e){
                webgl.SystemNotifier.sendEvent('shadejs', {
                    shadejsType : "error",
                    event: e,
                    code: this.sourceTemplate
                });

                var errorMessage = "Shade.js Compile Error:\n" + e.message + "\n------------\n"
                + "Shader Source:" + "\n------------\n" + XML3D.debug.formatSourceCode(this.sourceTemplate);
                throw new Error(errorMessage);
            }

            // TODO: Handle errors.
            XML3D.debug.logDebug(this.source.vertex);
            XML3D.debug.logDebug(this.source.fragment);

            webgl.SystemNotifier.sendEvent('shadejs', {
                shadejsType : "success",
                vertexShader: this.source.vertex,
                fragmentShader: this.source.fragment
            });

            return true;
        },

        createVertexShader: function(vsRequest, vsDataResult, spaceInfo){
            var vsConfig = vsRequest.getConfig();
            var names = vsDataResult.outputNames;
            for(var i = 0; i < names.length; ++i){
                channelVsAttribute(vsConfig, names[i], spaceInfo);
            }
            vsConfig.addInputParameter(Xflow.DATA_TYPE.FLOAT4X4, "modelViewProjectionMatrix", true);
            vsConfig.addCodeFragment( "gl_Position = modelViewProjectionMatrix * vec4(#I{position}, 1.0);");
            return vsRequest.getVertexShader().getGLSLCode();
        },

        setUniformVariables: function(envNames, sysNames, inputCollection){
            this.uniformSetter(envNames, sysNames, inputCollection, this.program.setUniformVariable.bind(this.program));
        },

        getTransparencyFromInputData: function(dataMap){
            // TODO: Compute Transparency
            return false;
        },

        /* Default values are compiled into shade.js */
        setDefaultUniforms: function() {}

    });
    webgl.JSShaderClosure = JSShaderClosure;

}(XML3D.webgl));
<|endoftext|>


<commit_before>// countries data taken from https://github.com/johan/world.geo.json
var dataURLPoly = './data/countries.geo.json';
// population data source http://peric.github.io/GetCountries/
var popDataURL = './data/population.json';

//get population data
var popData;
getjson(popDataURL, function(resp) {
  popData = JSON.parse(resp);
  // get countries geojson
  getjson(dataURLPoly,drawGeoJSON);
});

function drawGeoJSON(resp) {
  var geojson = JSON.parse(resp);
  // extend geojson properties with country's population
  var joinMap = {
    geoKey: 'properties.name',
    dataKey: 'countryName',
    propertyMap: [{
      geoProperty: 'population',
      dataProperty: 'population'
    }]
  };
  extendGeoJSON(geojson.features,popData.countries,joinMap);
  // covert wgs84 data to Web Mercator projection
  var geojson = reproject.reproject(
    geojson,'EPSG:4326','EPSG:3857',proj4.defs);
  //render on svg
  var svgMap = document.getElementById('map');
  var convertor = geojson2svg(
    {width:800,height:800},
    {
      attributes: {
        'style': 'stroke:#006600; fill: #F0F8FF;stroke-width:0.5px;',
        'vector-effect':'non-scaling-stroke'
      },
      explode: false
    }
  );
  // render feature based on population
  var cat1StyleOpt = { attributes : {
    style: 'stroke:red; fill: pink; stroke-width:0.5px;'}};
  var cat2StyleOpt = { attributes : {
    style: 'stroke:blue; fill: skyblue; stroke-width:0.5px;'}};
  var svgElements = [];
  geojson.features
    .filter( function(f) {
      return f.properties.population > 50000000; })
    .forEach( function(f) {
      svgElements.push(convertor.convert(f,cat1StyleOpt)); });
  geojson.features
    .filter( function(f) {
      return f.properties.population <= 50000000; })
    .forEach( function(f) {
      svgElements.push(convertor.convert(f,cat2StyleOpt)); });

  //var svgElements = convertor.convert(geojson);
  var parser = new DOMParser();
  svgElements.forEach(function(svgStr) {
    var svg = parseSVG(svgStr);
    svgMap.appendChild(svg);
  });
}
<commit_msg>color coded map example added<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env node
//
// Copyright 2018, Google, Inc.
//
// 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 shiritori = require('./index')

const process = require('process')
const readline = require('readline')
const corpus = require('./corpus.json')

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
})

const chain = ['しりとり']
console.log(chain[0])
rl.prompt()
shiritori.loaded.then(() => {
  rl.on('line', input => {
    shiritori
        .interact(
            kana => Promise.resolve(corpus[kana]),
            input,
            chain
        )
        .then(result => {
          console.log(`${result.word} [${result.kana}]`)
          chain.unshift(input)
          chain.unshift(result.word)
          rl.prompt()
        })
        .catch(reason => {
          if (reason.win) {
            console.log('すごい！')
            process.exit(0)
          } else if (reason.loose) {
            console.log('ざんねん。')
            process.exit(-1)
          } else {
            throw reason
          }
        })
  })
})
<commit_msg>shiritori: store history as kanas<commit_after>#!/usr/bin/env node
//
// Copyright 2018, Google, Inc.
//
// 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 shiritori = require('./index')

const process = require('process')
const readline = require('readline')
const corpus = require('./corpus.json')

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
})

const chain = ['しりとり']
console.log(chain[0])
rl.prompt()
shiritori.loaded.then(() => {
  rl.on('line', input => {
    shiritori
        .interact(
            kana => Promise.resolve(corpus[kana]),
            input,
            chain
        )
        .then(result => {
          console.log(`${result.word} [${result.kana}]`)
          chain.unshift(input)
          chain.unshift(result.kana)
          rl.prompt()
        })
        .catch(reason => {
          if (reason.win) {
            console.log('すごい！')
            process.exit(0)
          } else if (reason.loose) {
            console.log('ざんねん。')
            process.exit(-1)
          } else {
            throw reason
          }
        })
  })
})
<|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.
*/

var loglevel_path = null;
var logging_handler = function( response, text_status, xhr )
{
  var self = this;
  var loggers = response.loggers;

  var levels = '

' + "\n"
             + 'null' + "\n"
             + '
' + "\n";

  for( var key in response.levels )
  {
    var level = response.levels[key].esc();
    levels += '
' + level + '
' + "\n";
  }

  levels += '
UNSET
' + "\n"
         + '
' + "\n"
         + '[x]' + "\n"
         + '

';

  var logger_tree = function( filter )
  {
    var logger_content = '';
    var filter_regex = new RegExp( '^' + filter + '\\.\\w+$' );

    for( var i in loggers )
    {
      var logger = loggers[i];
      var continue_matcher = false;

      if( !filter )
      {
        continue_matcher = logger.name.indexOf( '.' ) !== -1;
      }
      else
      {
        continue_matcher = !logger.name.match( filter_regex );
      }

      if( continue_matcher )
      {
        continue;
      }

      var logger_class = '';

      if( logger.set )
      {
        logger_class = 'set';
      }

      if( !logger.level )
      {
        logger_class = 'null';
      }

      var logger_name = logger.name.split( '.' );
      var display_name = logger_name.pop();

      var leaf_class = 'jstree-leaf';
      if( logger.level )
      {
        leaf_class += ' level-' + logger.level.esc().toLowerCase();
      }

      logger_content += '
';
      logger_content += ' ' + "\n";
      logger_content += '' + "\n";

      if( 0 !== logger_name.length )
      {
        logger_content += '' + logger_name.join( '.' ).esc() + '.';
      }

      logger_content += '' + display_name.esc() + '' + "\n";
      logger_content += '';

      logger_content += levels;

      var child_logger_content = logger_tree( logger.name );
      if( child_logger_content )
      {
        logger_content += '
';
        logger_content += child_logger_content;
        logger_content += '
';
      }

      logger_content += '
';
    }

    return logger_content;
  };

  var logger_content = '
' + "\n"
                     + '
' + response.watcher.esc() + '
' + "\n"
                     + '
' + logger_tree( null ) + '
' + "\n"
                     + '
';

  self
    .html( logger_content );

  $( 'li:last-child', this )
    .addClass( 'jstree-last' );

  $( 'li.jstree-leaf > a', this )
    .each
    (
      function( index, element )
      {
        element = $( element );
        var level = element.attr( 'rel' );

        if( level )
        {
          var selector = $( '.selector-holder', element.closest( 'li' ) );

          var trigger = $( 'a.trigger', selector );

          trigger
            .text( level.esc() );

          if( element.hasClass( 'set' ) )
          {
            trigger.first()
              .addClass( 'set' );
          }

          $( 'ul a[data-level="' + level + '"]', selector ).first()
            .addClass( 'level' );
        }
      }
    )

  $( '.trigger, .selector .close', this )
    .die( 'click' )
    .live
    (
      'click',
      function( event )
      {
        $( '.selector-holder', $( this ).parents( 'li' ).first() ).first()
          .trigger( 'toggle' );

        return false;
      }
    );

  $( '.selector-holder', this )
    .die( 'toggle')
    .live
    (
      'toggle',
      function( event )
      {
        var row = $( this ).closest( 'li' );

        $( 'a:first', row )
          .toggleClass( 'open' );

        $( '.selector-holder:first', row )
          .toggleClass( 'open' );
      }
    );

  $( '.selector ul a', this )
    .die( 'click' )
    .live
    (
      'click',
      function( event )
      {
        var element = $( this );

        $.ajax
        (
          {
            url : loglevel_path,
            dataType : 'json',
            data : {
              'wt' : 'json',
              'set' : $( this ).parents( 'li[data-logger]' ).data( 'logger' ) + ':' + element.data( 'level' )
            },
            type : 'POST',
            context : self,
            beforeSend : function( xhr, settings )
            {
              element
                .addClass( 'loader' );
            },
            success : logging_handler
          }
        );

        return false;
      }
    );

};

// #/~logging
sammy.get
(
  /^#\/~(logging)$/,
  function( context )
  {
    loglevel_path = app_config.solr_path + '/admin/logging';
    var content_element = $( '#content' );

    content_element
      .html( '

' );

    $.ajax
    (
      {
        url : loglevel_path + '?wt=json',
        dataType : 'json',
        context : $( '#logging', content_element ),
        beforeSend : function( xhr, settings )
        {
          this
            .html( '
Loading ...
' );
        },
        success : logging_handler
      }
    );
  }
);<commit_msg>SOLR-3238: fix logging page to work with multicore setup<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.
*/

var loglevel_path = null;
var logging_handler = function( response, text_status, xhr )
{
  var self = this;
  var loggers = response.loggers;

  var levels = '

' + "\n"
             + 'null' + "\n"
             + '
' + "\n";

  for( var key in response.levels )
  {
    var level = response.levels[key].esc();
    levels += '
' + level + '
' + "\n";
  }

  levels += '
UNSET
' + "\n"
         + '
' + "\n"
         + '[x]' + "\n"
         + '

';

  var logger_tree = function( filter )
  {
    var logger_content = '';
    var filter_regex = new RegExp( '^' + filter + '\\.\\w+$' );

    for( var i in loggers )
    {
      var logger = loggers[i];
      var continue_matcher = false;

      if( !filter )
      {
        continue_matcher = logger.name.indexOf( '.' ) !== -1;
      }
      else
      {
        continue_matcher = !logger.name.match( filter_regex );
      }

      if( continue_matcher )
      {
        continue;
      }

      var logger_class = '';

      if( logger.set )
      {
        logger_class = 'set';
      }

      if( !logger.level )
      {
        logger_class = 'null';
      }

      var logger_name = logger.name.split( '.' );
      var display_name = logger_name.pop();

      var leaf_class = 'jstree-leaf';
      if( logger.level )
      {
        leaf_class += ' level-' + logger.level.esc().toLowerCase();
      }

      logger_content += '
';
      logger_content += ' ' + "\n";
      logger_content += '' + "\n";

      if( 0 !== logger_name.length )
      {
        logger_content += '' + logger_name.join( '.' ).esc() + '.';
      }

      logger_content += '' + display_name.esc() + '' + "\n";
      logger_content += '';

      logger_content += levels;

      var child_logger_content = logger_tree( logger.name );
      if( child_logger_content )
      {
        logger_content += '
';
        logger_content += child_logger_content;
        logger_content += '
';
      }

      logger_content += '
';
    }

    return logger_content;
  };

  var logger_content = '
' + "\n"
                     + '
' + response.watcher.esc() + '
' + "\n"
                     + '
' + logger_tree( null ) + '
' + "\n"
                     + '
';

  self
    .html( logger_content );

  $( 'li:last-child', this )
    .addClass( 'jstree-last' );

  $( 'li.jstree-leaf > a', this )
    .each
    (
      function( index, element )
      {
        element = $( element );
        var level = element.attr( 'rel' );

        if( level )
        {
          var selector = $( '.selector-holder', element.closest( 'li' ) );

          var trigger = $( 'a.trigger', selector );

          trigger
            .text( level.esc() );

          if( element.hasClass( 'set' ) )
          {
            trigger.first()
              .addClass( 'set' );
          }

          $( 'ul a[data-level="' + level + '"]', selector ).first()
            .addClass( 'level' );
        }
      }
    )

  $( '.trigger, .selector .close', this )
    .die( 'click' )
    .live
    (
      'click',
      function( event )
      {
        $( '.selector-holder', $( this ).parents( 'li' ).first() ).first()
          .trigger( 'toggle' );

        return false;
      }
    );

  $( '.selector-holder', this )
    .die( 'toggle')
    .live
    (
      'toggle',
      function( event )
      {
        var row = $( this ).closest( 'li' );

        $( 'a:first', row )
          .toggleClass( 'open' );

        $( '.selector-holder:first', row )
          .toggleClass( 'open' );
      }
    );

  $( '.selector ul a', this )
    .die( 'click' )
    .live
    (
      'click',
      function( event )
      {
        var element = $( this );

        $.ajax
        (
          {
            url : loglevel_path,
            dataType : 'json',
            data : {
              'wt' : 'json',
              'set' : $( this ).parents( 'li[data-logger]' ).data( 'logger' ) + ':' + element.data( 'level' )
            },
            type : 'POST',
            context : self,
            beforeSend : function( xhr, settings )
            {
              element
                .addClass( 'loader' );
            },
            success : logging_handler
          }
        );

        return false;
      }
    );

};

// #/~logging
sammy.get
(
  /^#\/~(logging)$/,
  function( context )
  {
    var core_basepath = $( 'li[data-basepath]', app.menu_element ).attr( 'data-basepath' );
    loglevel_path = core_basepath + '/admin/logging';
    var content_element = $( '#content' );

    content_element
      .html( '

' );

    $.ajax
    (
      {
        url : loglevel_path + '?wt=json',
        dataType : 'json',
        context : $( '#logging', content_element ),
        beforeSend : function( xhr, settings )
        {
          this
            .html( '
Loading ...
' );
        },
        success : logging_handler
      }
    );
  }
);<|endoftext|>


<commit_before>// Copyright 2021 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 assert = require('assert');
const expect = require('chai').expect;
const uuid = require('uuid');
const compute = require('../');

const DiskType = compute.protos.google.cloud.compute.v1.AttachedDisk.Type;

const delay = async test => {
  const retries = test.currentRetry();
  if (retries === 0) return; // no retry on the first failure.
  // see: https://github.com/grpc/proposal/blob/master/A6-client-retries.md#exponential-backoff
  const ms = Math.pow(2, retries) * 500 + Math.random() * 1000;
  return new Promise(done => {
    console.info(`retrying "${test.title}" in ${ms}ms`);
    setTimeout(done, ms);
  });
};

describe('Compute', () => {
  const region = 'us-central1';
  const zone = 'us-central1-a';
  let client = null;
  let project = null;
  let dirty = false;
  let operationsClient = null;
  let instancesClient = null;

  before(async () => {
    operationsClient = new compute.ZoneOperationsClient({fallback: 'rest'});
    project = await operationsClient.getProjectId();
  });

  describe('Addresses', () => {
    let ADDRESS_NAME = null;

    before(async () => {
      client = new compute.AddressesClient({fallback: 'rest'});
      ADDRESS_NAME = generateName('address');
    });

    after(async () => {
      if (dirty) {
        await client.delete({
          project,
          region,
          address: ADDRESS_NAME,
        });
      }
    });

    it('addresses create, get', async () => {
      const addressResource = {
        name: ADDRESS_NAME,
        description: 'тест',
      };

      await client.insert({
        project,
        region,
        addressResource,
      });
      dirty = true;

      const [getResponse] = await client.get({
        project,
        region,
        address: addressResource.name,
      });

      assert.strictEqual(getResponse.name, ADDRESS_NAME);
    });

    it('addresses list, aggregated_list', async () => {
      const [listResponse] = await client.list({
        project,
        region,
      });
      let presented = false;
      for (const item of listResponse) {
        if (item.name === ADDRESS_NAME) {
          presented = true;
        }
      }
      assert.strictEqual(
        presented,
        true,
        'address was not found in list response.'
      );

      const iterable = client.aggregatedListAsync({
        project,
      });
      presented = false;
      for await (const [location, addressesObject] of iterable) {
        if (location === 'regions/' + region) {
          const addresses = addressesObject.addresses;
          addresses.forEach(address => {
            if (address.name === ADDRESS_NAME) {
              presented = true;
            }
          });
        }
      }
      assert.strictEqual(
        presented,
        true,
        'address was not found in aggregated list response.'
      );
    });

    it('addresses delete', async () => {
      await client.delete({
        project,
        region,
        address: ADDRESS_NAME,
      });
      dirty = false;
    });
  });

  describe('Images', () => {
    let NAME = null;

    before(async () => {
      client = new compute.ImagesClient({fallback: 'rest'});
      NAME = generateName('image');
    });

    after(async () => {
      await client.delete({
        project,
        image: NAME,
      });
    });
  });

  describe('Firewall', () => {
    let NAME = null;

    before(async () => {
      client = new compute.FirewallsClient({fallback: 'rest'});
      instancesClient = new compute.InstancesClient({fallback: 'rest'});

      const FOUR_HOURS = 1000 * 60 * 60 * 4;
      const projectId = await instancesClient.getProjectId();
      for await (const rule of client.listAsync({
        project: projectId,
      })) {
        const created = new Date(rule.creationTimestamp).getTime();
        // Delete firewalls that are older than 4 hours and match our
        // test prefix.
        if (
          created < Date.now() - FOUR_HOURS &&
          rule.name.startsWith('tsgapic-firewall')
        ) {
          console.info(`deleting stale firewall ${rule.name}`);
          await client.delete({
            project: projectId,
            firewall: rule.name,
          });
        }
      }
      NAME = generateName('firewall');
    });

    after(async function () {
      this.timeout(10 * 60 * 1000);
      await client.delete({
        project,
        firewall: NAME,
      });
    });

    it('create and fetch firewall, test capital letter field like "IPProtocol"', async function () {
      this.retries(3);
      await delay(this.test);

      this.timeout(10 * 60 * 1000);
      const resource = {
        name: NAME,
        sourceRanges: ['0.0.0.0/0'],
        allowed: [
          {
            IPProtocol: 'tcp',
            ports: ['80'],
          },
        ],
      };
      const [op] = await client.insert({
        project,
        firewallResource: resource,
      });
      await waitGlobalOperation(op);
      const [fetched] = await client.get({
        project,
        firewall: NAME,
      });
      assert.strictEqual(fetched.allowed[0].IPProtocol, 'tcp');
    });
  });

  describe('Instances', () => {
    let INSTANCE_NAME = null;

    before(async () => {
      client = new compute.InstancesClient({fallback: 'rest'});
      INSTANCE_NAME = generateName('instance');
    });

    after(async function () {
      this.timeout(10 * 60 * 1000);
      if (dirty) {
        await client.delete({
          project,
          zone,
          instance: INSTANCE_NAME,
        });
      }
    });

    it('instance create and fetch', async function () {
      this.timeout(10 * 60 * 1000);
      const instanceResource = {
        name: INSTANCE_NAME,
        description: 'test',
        machineType: `zones/${zone}/machineTypes/n1-standard-1`,
        disks: [
          {
            boot: true,
            initializeParams: {
              sourceImage:
                'projects/debian-cloud/global/images/family/debian-10',
            },
            autoDelete: true,
            type: DiskType.PERSISTENT,
          },
        ],
        networkInterfaces: [
          {
            name: 'default',
          },
        ],
      };
      const [insertResponse] = await client.insert({
        project,
        zone,
        instanceResource,
      });
      dirty = true;

      await waitZonalOperation(insertResponse);

      const [getResponse] = await client.get({
        project,
        zone,
        instance: INSTANCE_NAME,
      });

      assert.strictEqual(getResponse.name, INSTANCE_NAME);
      assert.strictEqual(
        getResponse.shieldedInstanceConfig.enableSecureBoot,
        false
      );
    });

    it('instances patch', async function () {
      this.timeout(10 * 60 * 1000);
      this.retries(3);
      await delay(this.test);
      const [stopResponse] = await client.stop({
        project,
        zone,
        instance: INSTANCE_NAME,
      });

      await waitZonalOperation(stopResponse);

      const [patchResponse] = await client.updateShieldedInstanceConfig({
        project,
        zone,
        shieldedInstanceConfigResource: {
          enableSecureBoot: true,
        },
        instance: INSTANCE_NAME,
      });

      await waitZonalOperation(patchResponse);

      const [fetched] = await client.get({
        project,
        zone,
        instance: INSTANCE_NAME,
      });
      assert.strictEqual(fetched.shieldedInstanceConfig.enableSecureBoot, true);
    });

    it('API errors propagated', async () => {
      let error = null;
      try {
        await client.get({
          project,
          zone,
          instance: 'notexist555',
        });
      } catch (err) {
        error = err;
      }
      expect(error).to.be.an('Error');
      expect(error.message).to.contain('was not found');
      expect(error.code).to.equal(5);
    });

    it('instances update desc to an empty string', async function () {
      this.timeout(10 * 60 * 1000);
      this.retries(10);
      await delay(this.test);
      const [instance] = await client.get({
        project,
        zone,
        instance: INSTANCE_NAME,
      });
      assert.strictEqual(instance.description, 'test');
      instance.description = '';
      const [updateOp] = await client.update({
        project: project,
        zone: zone,
        instance: INSTANCE_NAME,
        instanceResource: instance,
      });
      await waitZonalOperation(updateOp);
      const [fetched] = await client.get({
        project,
        zone,
        instance: INSTANCE_NAME,
      });
      assert.strictEqual(fetched.description, '');
    });
  });

  describe('InstancesGroup Manager', () => {
    let clientTemplates = null;
    let clientInstanceGroups = null;
    let instanceGroupName = null;
    let instanceTemplateName = null;

    before(async () => {
      clientTemplates = new compute.InstanceTemplatesClient({fallback: 'rest'});
      clientInstanceGroups = new compute.InstanceGroupManagersClient({
        fallback: 'rest',
      });
      instanceGroupName = generateName('instance-group');
      instanceTemplateName = generateName('instance-group');
    });

    after(async function () {
      this.timeout(10 * 60 * 1000);
      const [deleteIgm] = await clientInstanceGroups.delete({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
      });
      await waitZonalOperation(deleteIgm);

      await clientTemplates.delete({
        project,
        instanceTemplate: instanceTemplateName,
      });
    });

    it('create instance group manager with size 0', async function () {
      //  we want to test that body field can be set to 0
      this.timeout(10 * 60 * 1000);
      const instanceTemplate = {
        name: instanceTemplateName,
        properties: {
          disks: [
            {
              boot: true,
              initializeParams: {
                sourceImage:
                  'projects/debian-cloud/global/images/family/debian-10',
              },
              autoDelete: true,
              type: DiskType.PERSISTENT,
            },
          ],
          networkInterfaces: [
            {
              name: 'default',
            },
          ],
          machineType: 'n1-standard-1',
        },
      };
      const [insertOp] = await clientTemplates.insert({
        instanceTemplateResource: instanceTemplate,
        project: project,
      });
      await waitGlobalOperation(insertOp);
      const instanceGroupManager = {
        baseInstanceName: 'tsgapic',
        instanceTemplate: insertOp.latestResponse.targetLink,
        name: instanceGroupName,
        targetSize: 0,
      };
      const [insertGroup] = await clientInstanceGroups.insert({
        project,
        zone,
        instanceGroupManagerResource: instanceGroupManager,
      });
      await waitZonalOperation(insertGroup);

      const [fetch] = await clientInstanceGroups.get({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
      });
      assert.strictEqual(fetch.targetSize, 0);
    });

    it('Resize group to 1 and then back to 0.', async function () {
      //  we want to test that query param field can be set to 0
      this.timeout(10 * 60 * 1000);
      const [resize] = await clientInstanceGroups.resize({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
        size: 1,
      });
      await waitZonalOperation(resize);

      const [fetch] = await clientInstanceGroups.get({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
      });
      assert.strictEqual(fetch.targetSize, 1);

      const [resizeBack] = await clientInstanceGroups.resize({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
        size: 0,
      });
      await waitZonalOperation(resizeBack);

      const [resized] = await clientInstanceGroups.get({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
      });
      assert.strictEqual(resized.targetSize, 0);
    });
  });

  async function waitZonalOperation(operation) {
    for (;;) {
      const [getResp] = await operationsClient.wait({
        project,
        zone,
        operation: operation.name,
      });
      if (getResp.status === 'DONE') {
        //  b/191191972
        break;
      } else {
        await new Promise(resolve => setTimeout(resolve, 4000));
      }
    }
  }

  describe('Pagination', () => {
    let client = null;

    before(async () => {
      client = new compute.AcceleratorTypesClient({fallback: 'rest'});
    });

    it('Pagination in list response', async () => {
      const [listResponse] = await client.list({
        project,
        zone,
        maxResults: 1,
      });
      let presented = false;
      for (const item of listResponse) {
        if (item.name === 'nvidia-tesla-t4') {
          presented = true;
        }
      }
      assert.strictEqual(
        presented,
        true,
        'accelerator type nvidia-tesla-t4 was not found in list response.'
      );
    });

    it('Pagination in map responses', async function () {
      this.timeout(10 * 60 * 1000);
      const iterable = client.aggregatedListAsync({
        project,
        maxResults: 2,
      });
      let presented = false;
      for await (const [location, acceleratorTypesObj] of iterable) {
        if (location === 'zones/' + zone) {
          const acceleratorTypes = acceleratorTypesObj.acceleratorTypes;
          acceleratorTypes.forEach(acceleratorType => {
            if (acceleratorType.name === 'nvidia-tesla-t4') {
              presented = true;
            }
          });
        }
      }
      assert.strictEqual(
        presented,
        true,
        'accelerator type nvidia-tesla-t4 was not found in map response.'
      );
    });
  });

  async function waitGlobalOperation(operation) {
    const globalClient = new compute.GlobalOperationsClient({fallback: 'rest'});
    for (;;) {
      const [getResp] = await globalClient.get({
        project,
        operation: operation.name,
      });
      if (getResp.status === 'DONE') {
        //  b/191191972
        break;
      } else {
        await new Promise(resolve => setTimeout(resolve, 4000));
      }
    }
  }

  function generateName(customPrefix) {
    const TESTS_PREFIX = 'tsgapic';
    const resourceId = uuid.v4().split('-')[0];
    return `${TESTS_PREFIX}-${customPrefix}-${resourceId}`;
  }
});
<commit_msg>build: add retries to flaky tests (#794)<commit_after>// Copyright 2021 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 assert = require('assert');
const expect = require('chai').expect;
const uuid = require('uuid');
const compute = require('../');

const DiskType = compute.protos.google.cloud.compute.v1.AttachedDisk.Type;

const delay = async test => {
  const retries = test.currentRetry();
  if (retries === 0) return; // no retry on the first failure.
  // see: https://github.com/grpc/proposal/blob/master/A6-client-retries.md#exponential-backoff
  const ms = Math.pow(2, retries) * 500 + Math.random() * 1000;
  return new Promise(done => {
    console.info(`retrying "${test.title}" in ${ms}ms`);
    setTimeout(done, ms);
  });
};

describe('Compute', () => {
  const region = 'us-central1';
  const zone = 'us-central1-a';
  let client = null;
  let project = null;
  let dirty = false;
  let operationsClient = null;
  let instancesClient = null;

  before(async () => {
    operationsClient = new compute.ZoneOperationsClient({fallback: 'rest'});
    project = await operationsClient.getProjectId();
  });

  describe('Addresses', () => {
    let ADDRESS_NAME = null;

    before(async () => {
      client = new compute.AddressesClient({fallback: 'rest'});
      ADDRESS_NAME = generateName('address');
    });

    after(async () => {
      if (dirty) {
        await client.delete({
          project,
          region,
          address: ADDRESS_NAME,
        });
      }
    });

    it('addresses create, get', async () => {
      const addressResource = {
        name: ADDRESS_NAME,
        description: 'тест',
      };

      await client.insert({
        project,
        region,
        addressResource,
      });
      dirty = true;

      const [getResponse] = await client.get({
        project,
        region,
        address: addressResource.name,
      });

      assert.strictEqual(getResponse.name, ADDRESS_NAME);
    });

    it('addresses list, aggregated_list', async () => {
      const [listResponse] = await client.list({
        project,
        region,
      });
      let presented = false;
      for (const item of listResponse) {
        if (item.name === ADDRESS_NAME) {
          presented = true;
        }
      }
      assert.strictEqual(
        presented,
        true,
        'address was not found in list response.'
      );

      const iterable = client.aggregatedListAsync({
        project,
      });
      presented = false;
      for await (const [location, addressesObject] of iterable) {
        if (location === 'regions/' + region) {
          const addresses = addressesObject.addresses;
          addresses.forEach(address => {
            if (address.name === ADDRESS_NAME) {
              presented = true;
            }
          });
        }
      }
      assert.strictEqual(
        presented,
        true,
        'address was not found in aggregated list response.'
      );
    });

    it('addresses delete', async () => {
      await client.delete({
        project,
        region,
        address: ADDRESS_NAME,
      });
      dirty = false;
    });
  });

  describe('Images', () => {
    let NAME = null;

    before(async () => {
      client = new compute.ImagesClient({fallback: 'rest'});
      NAME = generateName('image');
    });

    after(async () => {
      await client.delete({
        project,
        image: NAME,
      });
    });
  });

  describe('Firewall', () => {
    let NAME = null;

    before(async () => {
      client = new compute.FirewallsClient({fallback: 'rest'});
      instancesClient = new compute.InstancesClient({fallback: 'rest'});

      const FOUR_HOURS = 1000 * 60 * 60 * 4;
      const projectId = await instancesClient.getProjectId();
      for await (const rule of client.listAsync({
        project: projectId,
      })) {
        const created = new Date(rule.creationTimestamp).getTime();
        // Delete firewalls that are older than 4 hours and match our
        // test prefix.
        if (
          created < Date.now() - FOUR_HOURS &&
          rule.name.startsWith('tsgapic-firewall')
        ) {
          console.info(`deleting stale firewall ${rule.name}`);
          await client.delete({
            project: projectId,
            firewall: rule.name,
          });
        }
      }
      NAME = generateName('firewall');
    });

    after(async function () {
      this.timeout(10 * 60 * 1000);
      await client.delete({
        project,
        firewall: NAME,
      });
    });

    it('create and fetch firewall, test capital letter field like "IPProtocol"', async function () {
      this.retries(3);
      await delay(this.test);

      this.timeout(10 * 60 * 1000);
      const resource = {
        name: NAME,
        sourceRanges: ['0.0.0.0/0'],
        allowed: [
          {
            IPProtocol: 'tcp',
            ports: ['80'],
          },
        ],
      };
      const [op] = await client.insert({
        project,
        firewallResource: resource,
      });
      await waitGlobalOperation(op);
      const [fetched] = await client.get({
        project,
        firewall: NAME,
      });
      assert.strictEqual(fetched.allowed[0].IPProtocol, 'tcp');
    });
  });

  describe('Instances', () => {
    let INSTANCE_NAME = null;

    before(async () => {
      client = new compute.InstancesClient({fallback: 'rest'});
      INSTANCE_NAME = generateName('instance');
    });

    after(async function () {
      this.timeout(10 * 60 * 1000);
      this.retries(3);
      await delay(this.test);
      if (dirty) {
        await client.delete({
          project,
          zone,
          instance: INSTANCE_NAME,
        });
      }
    });

    it('instance create and fetch', async function () {
      this.timeout(10 * 60 * 1000);
      const instanceResource = {
        name: INSTANCE_NAME,
        description: 'test',
        machineType: `zones/${zone}/machineTypes/n1-standard-1`,
        disks: [
          {
            boot: true,
            initializeParams: {
              sourceImage:
                'projects/debian-cloud/global/images/family/debian-10',
            },
            autoDelete: true,
            type: DiskType.PERSISTENT,
          },
        ],
        networkInterfaces: [
          {
            name: 'default',
          },
        ],
      };
      const [insertResponse] = await client.insert({
        project,
        zone,
        instanceResource,
      });
      dirty = true;

      await waitZonalOperation(insertResponse);

      const [getResponse] = await client.get({
        project,
        zone,
        instance: INSTANCE_NAME,
      });

      assert.strictEqual(getResponse.name, INSTANCE_NAME);
      assert.strictEqual(
        getResponse.shieldedInstanceConfig.enableSecureBoot,
        false
      );
    });

    it('instances patch', async function () {
      this.timeout(10 * 60 * 1000);
      this.retries(3);
      await delay(this.test);
      const [stopResponse] = await client.stop({
        project,
        zone,
        instance: INSTANCE_NAME,
      });

      await waitZonalOperation(stopResponse);

      const [patchResponse] = await client.updateShieldedInstanceConfig({
        project,
        zone,
        shieldedInstanceConfigResource: {
          enableSecureBoot: true,
        },
        instance: INSTANCE_NAME,
      });

      await waitZonalOperation(patchResponse);

      const [fetched] = await client.get({
        project,
        zone,
        instance: INSTANCE_NAME,
      });
      assert.strictEqual(fetched.shieldedInstanceConfig.enableSecureBoot, true);
    });

    it('API errors propagated', async () => {
      let error = null;
      try {
        await client.get({
          project,
          zone,
          instance: 'notexist555',
        });
      } catch (err) {
        error = err;
      }
      expect(error).to.be.an('Error');
      expect(error.message).to.contain('was not found');
      expect(error.code).to.equal(5);
    });

    it('instances update desc to an empty string', async function () {
      this.timeout(10 * 60 * 1000);
      this.retries(10);
      await delay(this.test);
      const [instance] = await client.get({
        project,
        zone,
        instance: INSTANCE_NAME,
      });
      assert.strictEqual(instance.description, 'test');
      instance.description = '';
      const [updateOp] = await client.update({
        project: project,
        zone: zone,
        instance: INSTANCE_NAME,
        instanceResource: instance,
      });
      await waitZonalOperation(updateOp);
      const [fetched] = await client.get({
        project,
        zone,
        instance: INSTANCE_NAME,
      });
      assert.strictEqual(fetched.description, '');
    });
  });

  describe('InstancesGroup Manager', () => {
    let clientTemplates = null;
    let clientInstanceGroups = null;
    let instanceGroupName = null;
    let instanceTemplateName = null;

    before(async () => {
      clientTemplates = new compute.InstanceTemplatesClient({fallback: 'rest'});
      clientInstanceGroups = new compute.InstanceGroupManagersClient({
        fallback: 'rest',
      });
      instanceGroupName = generateName('instance-group');
      instanceTemplateName = generateName('instance-group');
    });

    after(async function () {
      this.timeout(10 * 60 * 1000);
      const [deleteIgm] = await clientInstanceGroups.delete({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
      });
      await waitZonalOperation(deleteIgm);

      await clientTemplates.delete({
        project,
        instanceTemplate: instanceTemplateName,
      });
    });

    it('create instance group manager with size 0', async function () {
      //  we want to test that body field can be set to 0
      this.timeout(10 * 60 * 1000);
      const instanceTemplate = {
        name: instanceTemplateName,
        properties: {
          disks: [
            {
              boot: true,
              initializeParams: {
                sourceImage:
                  'projects/debian-cloud/global/images/family/debian-10',
              },
              autoDelete: true,
              type: DiskType.PERSISTENT,
            },
          ],
          networkInterfaces: [
            {
              name: 'default',
            },
          ],
          machineType: 'n1-standard-1',
        },
      };
      const [insertOp] = await clientTemplates.insert({
        instanceTemplateResource: instanceTemplate,
        project: project,
      });
      await waitGlobalOperation(insertOp);
      const instanceGroupManager = {
        baseInstanceName: 'tsgapic',
        instanceTemplate: insertOp.latestResponse.targetLink,
        name: instanceGroupName,
        targetSize: 0,
      };
      const [insertGroup] = await clientInstanceGroups.insert({
        project,
        zone,
        instanceGroupManagerResource: instanceGroupManager,
      });
      await waitZonalOperation(insertGroup);

      const [fetch] = await clientInstanceGroups.get({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
      });
      assert.strictEqual(fetch.targetSize, 0);
    });

    it('Resize group to 1 and then back to 0.', async function () {
      //  we want to test that query param field can be set to 0
      this.timeout(10 * 60 * 1000);
      const [resize] = await clientInstanceGroups.resize({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
        size: 1,
      });
      await waitZonalOperation(resize);

      const [fetch] = await clientInstanceGroups.get({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
      });
      assert.strictEqual(fetch.targetSize, 1);

      const [resizeBack] = await clientInstanceGroups.resize({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
        size: 0,
      });
      await waitZonalOperation(resizeBack);

      const [resized] = await clientInstanceGroups.get({
        project,
        zone,
        instanceGroupManager: instanceGroupName,
      });
      assert.strictEqual(resized.targetSize, 0);
    });
  });

  async function waitZonalOperation(operation) {
    for (;;) {
      const [getResp] = await operationsClient.wait({
        project,
        zone,
        operation: operation.name,
      });
      if (getResp.status === 'DONE') {
        //  b/191191972
        break;
      } else {
        await new Promise(resolve => setTimeout(resolve, 4000));
      }
    }
  }

  describe('Pagination', () => {
    let client = null;

    before(async () => {
      client = new compute.AcceleratorTypesClient({fallback: 'rest'});
    });

    it('Pagination in list response', async () => {
      const [listResponse] = await client.list({
        project,
        zone,
        maxResults: 1,
      });
      let presented = false;
      for (const item of listResponse) {
        if (item.name === 'nvidia-tesla-t4') {
          presented = true;
        }
      }
      assert.strictEqual(
        presented,
        true,
        'accelerator type nvidia-tesla-t4 was not found in list response.'
      );
    });

    it('Pagination in map responses', async function () {
      this.timeout(10 * 60 * 1000);
      const iterable = client.aggregatedListAsync({
        project,
        maxResults: 2,
      });
      let presented = false;
      for await (const [location, acceleratorTypesObj] of iterable) {
        if (location === 'zones/' + zone) {
          const acceleratorTypes = acceleratorTypesObj.acceleratorTypes;
          acceleratorTypes.forEach(acceleratorType => {
            if (acceleratorType.name === 'nvidia-tesla-t4') {
              presented = true;
            }
          });
        }
      }
      assert.strictEqual(
        presented,
        true,
        'accelerator type nvidia-tesla-t4 was not found in map response.'
      );
    });
  });

  async function waitGlobalOperation(operation) {
    const globalClient = new compute.GlobalOperationsClient({fallback: 'rest'});
    for (;;) {
      const [getResp] = await globalClient.get({
        project,
        operation: operation.name,
      });
      if (getResp.status === 'DONE') {
        //  b/191191972
        break;
      } else {
        await new Promise(resolve => setTimeout(resolve, 4000));
      }
    }
  }

  function generateName(customPrefix) {
    const TESTS_PREFIX = 'tsgapic';
    const resourceId = uuid.v4().split('-')[0];
    return `${TESTS_PREFIX}-${customPrefix}-${resourceId}`;
  }
});
<|endoftext|>


<commit_before>"use strict";

// Dependency:
var fs = require("fs");
var path = require("path");
var cwd = __dirname;
var nooocl = require("../");
var CLHost = nooocl.CLHost;
var CLContext = nooocl.CLContext;
// var CLSVM = nooocl.clSVM;
var CLSVM = require("../lib/clSVM");
var CLCommandQueue = nooocl.CLCommandQueue;
var NDRange = nooocl.NDRange;
var CLError = nooocl.CLError;
var ref = require("ref");
var double = ref.types.double;

// Initialize OpenCL then we get host, device, context, and a queue
var host = CLHost.createV20();
var defs = host.cl.defs;

var platforms = host.getPlatforms();
var device;
function searchForDevice(hardware) {
    platforms.forEach(function (p) {
        var devices = hardware === "gpu" ? p.gpuDevices() : p.cpuDevices();
        devices = devices.filter(function (d) {
            // Is double precision supported?
            // See: https://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html
            return d.doubleFpConfig &
                (defs.CL_FP_FMA | defs.CL_FP_ROUND_TO_NEAREST | defs.CL_FP_ROUND_TO_ZERO | defs.CL_FP_ROUND_TO_INF | defs.CL_FP_INF_NAN | defs.CL_FP_DENORM);
        });
        if (devices.length) {
            device = devices[0];
        }
        if (device) {
            return false;
        }
    });
}

searchForDevice("gpu");
if (!device) {
    console.warn("No GPU device has been found, searching for a CPU fallback.");
    searchForDevice("cpu");
}

if (!device) {
    throw new Error("No capable OpenCL 2.0 device has been found.");
}
else {
    console.log("Running on device: " + device.name + " - " + device.platform.name);
}

var context = new CLContext(device);
var queue = new CLCommandQueue(context, device);

// Initialize data on the host side:
var n = 1000;
var bytes = n * double.size;

/*
var cl20 = require("../lib/cl20");
var abd = new cl20();

console.log(nooocl.clSVM == null);
console.log(CLSVM == null);
console.log(CLHost == null);
console.log(host == null);
console.log(CLCommandQueue == null);
console.log(CLContext == null);
console.log(nooocl.CL11 == null);
console.log(nooocl.CL12 == null);
console.log(nooocl.CL20 == null);
console.log(abd == null);
*/

var h_a = new CLSVM(context, defs.CL_MEM_READ_ONLY, bytes, 0);
var h_b = new CLSVM(context, defs.CL_MEM_READ_ONLY, bytes, 0);
var h_c = new CLSVM(context, defs.CL_MEM_WRITE_ONLY, bytes, 0);

//console.log(queue.cl.libName);
queue.enqueueSVMMap(false, defs.CL_MAP_WRITE, h_a, bytes, null);
queue.enqueueSVMMap(false, defs.CL_MAP_WRITE, h_b, bytes, null);

// Initialize vectors on host
for (var i = 0; i < n; i++) {
/*
    var offset = i * double.size;
    double.set(h_a.handle, offset, Math.sin(i) * Math.sin(i));
    double.set(h_b.handle, offset, Math.cos(i) * Math.cos(i));
*/
    h_a.handle[i] = Math.sin(i) * Math.sin(i);
    h_b.handle[i] = Math.cos(i) * Math.cos(i);
	console.log("a="+h_a.handle[i]);
}

queue.enqueueSVMUnmap(h_a, null);
queue.enqueueSVMUnmap(h_b, null);

// It's time to build the program.
var kernelSourceCode = fs.readFileSync(path.join(cwd, "vecAdd.cl"), { encoding: "utf8" });
var program = context.createProgram(kernelSourceCode);

console.log("Building ...");
// Building is always asynchronous in NOOOCL!
program.build("-cl-fast-relaxed-math -cl-std=CL2.0").then(
    function () {
        var buildStatus = program.getBuildStatus(device);
        var buildLog = program.getBuildLog(device);
        console.log(buildLog);
        if (buildStatus < 0) {
            throw new CLError(buildStatus, "Build failed.");
        }
        console.log("Build completed.");

        // Kernel stuff:
        var kernel = program.createKernel("vecAdd");

        kernel.setArgSVM(0, h_a);
        kernel.setArgSVM(1, h_b);
        kernel.setArgSVM(2, h_c);
        // Notice: in NOOOCL you have specify type of value arguments,
        // because there is no C compatible type system exists in JavaScript.
        kernel.setArg(3, n, "uint");

        // Ranges:
        // Number of work items in each local work group
        var localSize = new NDRange(64);
        // Number of total work items - localSize must be devisor
        var globalSize = new NDRange(Math.ceil(n / 64) * 64);

        console.log("Launching the kernel.");

        // Enqueue the kernel asynchronously
        queue.enqueueNDRangeKernel(kernel, globalSize, localSize);

        // Then copy back the result from the device to the host asynchronously,
        // when the queue ends.
        // We should query a waitable queue which returns an event for each enqueue operations,
        // and the event's promise can be used for continuation of the control flow on the host side.
        console.log("Waiting for result.");
        queue.waitable().enqueueSVMMap(true, defs.CL_MAP_READ ,h_c, bytes, null).promise
            .then(function() {
                queue.enqueueSVMMap(true, defs.CL_MAP_READ, h_a, bytes, null);
                queue.enqueueSVMMap(true, defs.CL_MAP_READ, h_b, bytes, null);
                // Data gets back to host, we're done:

                var sum = 0;
                for (var i = 0; i < n; i++) {
/*
                    var offset = i * double.size;
*/
                    sum += h_c.handle[i];
                    console.log("a=" + h_a.handle[i]);
                    console.log("b=" + h_b.handle[i]);
                    console.log("c=" + h_c.handle[i]);
                }

                console.log("Final result: " + sum / n);
            });
        queue.enqueueSVMUnmap(h_a, null);
        queue.enqueueSVMUnmap(h_b, null);
        queue.enqueueSVMUnmap(h_c, null);
    });

console.log("(Everything after this point is asynchronous.)");
<commit_msg>svm object access bug<commit_after>"use strict";

// Dependency:
var fs = require("fs");
var path = require("path");
var cwd = __dirname;
var nooocl = require("../");
var CLHost = nooocl.CLHost;
var CLContext = nooocl.CLContext;
// var CLSVM = nooocl.clSVM;
var CLSVM = require("../lib/clSVM");
var CLCommandQueue = nooocl.CLCommandQueue;
var NDRange = nooocl.NDRange;
var CLError = nooocl.CLError;
var ref = require("ref");
var double = ref.types.double;

// Initialize OpenCL then we get host, device, context, and a queue
var host = CLHost.createV20();
var defs = host.cl.defs;

var platforms = host.getPlatforms();
var device;
function searchForDevice(hardware) {
    platforms.forEach(function (p) {
        var devices = hardware === "gpu" ? p.gpuDevices() : p.cpuDevices();
        devices = devices.filter(function (d) {
            // Is double precision supported?
            // See: https://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html
            return d.doubleFpConfig &
                (defs.CL_FP_FMA | defs.CL_FP_ROUND_TO_NEAREST | defs.CL_FP_ROUND_TO_ZERO | defs.CL_FP_ROUND_TO_INF | defs.CL_FP_INF_NAN | defs.CL_FP_DENORM);
        });
        if (devices.length) {
            device = devices[0];
        }
        if (device) {
            return false;
        }
    });
}

searchForDevice("gpu");
if (!device) {
    console.warn("No GPU device has been found, searching for a CPU fallback.");
    searchForDevice("cpu");
}

if (!device) {
    throw new Error("No capable OpenCL 2.0 device has been found.");
}
else {
    console.log("Running on device: " + device.name + " - " + device.platform.name);
}

var context = new CLContext(device);
var queue = new CLCommandQueue(context, device);

// Initialize data on the host side:
var n = 1000;
var bytes = n * double.size;

/*
var cl20 = require("../lib/cl20");
var abd = new cl20();

console.log(nooocl.clSVM == null);
console.log(CLSVM == null);
console.log(CLHost == null);
console.log(host == null);
console.log(CLCommandQueue == null);
console.log(CLContext == null);
console.log(nooocl.CL11 == null);
console.log(nooocl.CL12 == null);
console.log(nooocl.CL20 == null);
console.log(abd == null);
*/

var h_a = new CLSVM(context, defs.CL_MEM_READ_ONLY, bytes, 0);
var h_b = new CLSVM(context, defs.CL_MEM_READ_ONLY, bytes, 0);
var h_c = new CLSVM(context, defs.CL_MEM_WRITE_ONLY, bytes, 0);

//console.log(queue.cl.libName);
queue.enqueueSVMMap(false, defs.CL_MAP_WRITE | defs.CL_MAP_READ, h_a, bytes, null);
queue.enqueueSVMMap(false, defs.CL_MAP_WRITE, h_b, bytes, null);

// Initialize vectors on host
for (var i = 0; i < n; i++) {
/*
    var offset = i * double.size;
    double.set(h_a.handle, offset, Math.sin(i) * Math.sin(i));
    double.set(h_b.handle, offset, Math.cos(i) * Math.cos(i));
*/
    h_a.handle[i] = Math.sin(i) * Math.sin(i);
    h_b.handle[i] = Math.cos(i) * Math.cos(i);
    console.log("a="+h_a.handle[i]+", i="+i);
    console.log(typeof h_a.handle);
}

queue.enqueueSVMUnmap(h_a, null);
queue.enqueueSVMUnmap(h_b, null);

// It's time to build the program.
var kernelSourceCode = fs.readFileSync(path.join(cwd, "vecAdd.cl"), { encoding: "utf8" });
var program = context.createProgram(kernelSourceCode);

console.log("Building ...");
// Building is always asynchronous in NOOOCL!
program.build("-cl-fast-relaxed-math -cl-std=CL2.0").then(
    function () {
        var buildStatus = program.getBuildStatus(device);
        var buildLog = program.getBuildLog(device);
        console.log(buildLog);
        if (buildStatus < 0) {
            throw new CLError(buildStatus, "Build failed.");
        }
        console.log("Build completed.");

        // Kernel stuff:
        var kernel = program.createKernel("vecAdd");

        kernel.setArgSVM(0, h_a);
        kernel.setArgSVM(1, h_b);
        kernel.setArgSVM(2, h_c);
        // Notice: in NOOOCL you have specify type of value arguments,
        // because there is no C compatible type system exists in JavaScript.
        kernel.setArg(3, n, "uint");

        // Ranges:
        // Number of work items in each local work group
        var localSize = new NDRange(64);
        // Number of total work items - localSize must be devisor
        var globalSize = new NDRange(Math.ceil(n / 64) * 64);

        console.log("Launching the kernel.");

        // Enqueue the kernel asynchronously
        queue.enqueueNDRangeKernel(kernel, globalSize, localSize);

        // Then copy back the result from the device to the host asynchronously,
        // when the queue ends.
        // We should query a waitable queue which returns an event for each enqueue operations,
        // and the event's promise can be used for continuation of the control flow on the host side.
        console.log("Waiting for result.");
        queue.waitable().enqueueSVMMap(true, defs.CL_MAP_READ ,h_c, bytes, null).promise
            .then(function() {
                queue.enqueueSVMMap(true, defs.CL_MAP_READ, h_a, bytes, null);
                queue.enqueueSVMMap(true, defs.CL_MAP_READ, h_b, bytes, null);
                // Data gets back to host, we're done:

                var sum = 0;
                for (var i = 0; i < n; i++) {
/*
                    var offset = i * double.size;
*/
                    sum += h_c.handle[i];
                    console.log("a=" + h_a.handle[i]);
                    console.log("b=" + h_b.handle[i]);
                    console.log("c=" + h_c.handle[i]);
                }

                console.log("Final result: " + sum / n);
            });
        queue.enqueueSVMUnmap(h_a, null);
        queue.enqueueSVMUnmap(h_b, null);
        queue.enqueueSVMUnmap(h_c, null);
    });

console.log("(Everything after this point is asynchronous.)");
<|endoftext|>