<commit_before>(function(global) {
"use strict";

let ConstantRef = function(type, idx) {
    this.type = type;
    this.idx = idx;
}

let CompositeConstantRef = function(type, idx1, idx2) {
    this.type = type;
    this.idx1 = idx1;
    this.idx2 = idx2;
}

let JavaField = function(access, name, descriptor, attributes) {
    this.access = access;
    this.name = name;
    this.descriptor = descriptor;
    this.attributes = attributes;
}

let JavaMethod = function(access, name, descriptor, attributes) {
    this.access = access;
    this.name = name;
    this.descriptor = descriptor;
    this.attributes = attributes;
}

let JavaClass = function(access, name, parent, interfaces, constants, fields, methods, attributes) {
    this.access = access;
    this.name = name;
    this.parent = parent;
    this.interfaces = interfaces;
    this.constants = constants;
    this.fields = fields;
    this.methods = methods;
    this.attributes = attributes;
}

const prv = {
    magic : 0xCAFEBABE,
    supportedVersion : [52, 0],

    u1 : function(arr, offset) {
        return arr[offset] >>> 0;
    },

    u2 : function(arr, offset) {
        return (arr[offset] << 8 >>> 0) + (arr[offset + 1] >>> 0);
    },

    u4 : function(arr, offset) {
        return (arr[offset] << 24 >>> 0) + (arr[offset + 1] << 16 >>> 0) + (arr[offset + 2] << 8 >>> 0) + (arr[offset + 3] >>> 0);
    },

    compareArrays : function(a, b) {
        if (a.length === undefined || b.length === undefined || !isFinite(a.length) || !isFinite(b.length)) {
            return false;
        }
        if (a.length !== b.length) {
            return false;
        }
        const length = a.length;
        for (let i = 0; i < length; ++i) {
            if (a[i] !== b[i]) {
                return false;
            }
        }
        return true;
    },

    readMultiple : function(arr, base, entryReader, seed) {
        let size = prv.u2(arr, base);
        let offset = base + 2;
        let entries = seed === undefined ? [] : seed;
        for (let i = entries.length; i < size; ++i) {
            var [entry, next] = entryReader(arr, offset);
            entries.push(entry);
            offset += next;
        }
        return [entries, offset];
    },

    checkMagic : function(arr) {
        let magic = prv.u4(arr, 0);
        return magic === prv.magic;
    },

    checkVersion : function(arr) {
        let minor = prv.u2(arr, 4);
        let major = prv.u2(arr, 6);
        return this.compareArrays([major, minor], prv.supportedVersion);
    },

    validateClass : function(arr) {
        if (prv.checkMagic(arr)) {
            console.debug("It's a Java class!");
        }
        else {
            throw new Error("It's not a Java class - magic bytes do not match");
        }
        if (prv.checkVersion(arr)) {
            console.debug("Detected supported class file format version")
        }
        else {
            console.warn("Detected unsupported class file format version")
        }
    },

    readConstant : function(arr, offset) {
        let tag = prv.u1(arr, offset);
        offset += 1;

        switch (tag) {
            // Utf8
            case 1:
                let length = prv.u2(arr, offset);
                return [new StringView(arr, "UTF-8", offset + 2, length), length + 3 ]
                break;
            // Methodref
            case 10:
                return [new CompositeConstantRef("method", prv.u2(arr, offset), prv.u2(arr, offset + 2)), 5];
                break;
            // Fieldref
            case 9:
                return [new CompositeConstantRef("field", prv.u2(arr, offset), prv.u2(arr, offset + 2)), 5];
                break;
            // String
            case 8:
                return [new ConstantRef("string", prv.u2(arr, offset)), 3];
                break;
            // Class
            case 7:
                return [new ConstantRef("class", prv.u2(arr, offset)), 3];
                break;
            // NameAndType
            case 12:
                return [new CompositeConstantRef("name&type", prv.u2(arr, offset), prv.u2(arr, offset + 2)), 5];
                break;
            default:
                throw new Error("Unsupported tag: " + tag);
        }
    },

    readConstants : function(arr, base) {
        return prv.readMultiple(arr, base, prv.readConstant, [null]);
    },

    readMeta : function(arr, base) {
        let offset = base;
        let meta = {};
        meta.access = prv.u2(arr, offset);
        meta.name = new ConstantRef("this", prv.u2(arr, offset + 2))
        meta.parent = new ConstantRef("super", prv.u2(arr, offset + 4))
        let [interfaces, lastOffset] = prv.readInterfaces(arr, offset + 6);
        meta.interfaces = interfaces;
        return [meta, lastOffset];
    },

    readInterface : function(arr, base) {
        return [new ConstantRef("interface", prv.u2(arr, base)), 2];
    },

    readInterfaces : function(arr, base) {
        return prv.readMultiple(arr, base, prv.readInterface);
    },

    readFieldOrMethod : function(Factory) {
        return function(arr, base) {
            let access = prv.u2(arr, base);
            let name = new ConstantRef("name", prv.u2(arr, base + 2));
            let descriptor = new ConstantRef("name", prv.u2(arr, base + 4));
            let [attributes, lastOffset] = prv.readAttributes(arr, base + 6);
            let field = new Factory(access, name, descriptor, attributes);
            return [field, lastOffset - base];
        }
    },

    readFields : function(arr, base) {
        return prv.readMultiple(arr, base, prv.readFieldOrMethod(JavaField));
    },

    readMethods : function(arr, base) {
        return prv.readMultiple(arr, base, prv.readFieldOrMethod(JavaMethod));
    },

    readAttribute : function(arr, base) {
        let name = prv.u2(arr, base);
        let size = prv.u4(arr, base + 2);
        console.info("readAttribute", base, size + 6);
        return [{}, size + 6];
    },

    readAttributes : function(arr, base) {
        return prv.readMultiple(arr, base, prv.readAttribute);
    },
}

let JavaJS = function() {
    this.classes = new Map();
}

JavaJS.prototype.register = function(javaClass) {
    if (this.classes.has(javaClass.name)) {
        return false;
    }

    this.classes.set(javaClass.name, javaClass);
    return true;
}

JavaJS.prototype.load = function(binary) {
    console.log("Read:", binary.byteLength);
    let clazz = new Uint8Array(binary);
    console.log(clazz);

    prv.validateClass(clazz);

    let constantsOffset = 8;
    let [constants, metaOffset] = prv.readConstants(clazz, constantsOffset);
    let [meta, fieldsOffset] = prv.readMeta(clazz, metaOffset);
    let [fields, methodsOffset] = prv.readFields(clazz, fieldsOffset);
    let [methods, attribsOffset] = prv.readMethods(clazz, methodsOffset);
    let [attributes, end] = prv.readAttributes(clazz, attribsOffset);

    if (end !== binary.byteLength) {
        console.warn("Class binary was not fully consumed");
    }

    let newClass = new JavaClass(meta.access, meta.name, meta.parent, meta.interfaces, constants, fields, methods, attributes);
    if (this.register(newClass)) {
        console.info("Class", newClass, "registered");
    }
    else {
        console.warn("Class", newClass, "not registered");
    }
}

global.Java = new JavaJS();
})(window);
<commit_msg>Let's see the code<commit_after>(function(global) {
"use strict";

let ConstantRef = function(type, idx) {
    this.type = type;
    this.idx = idx;
}

let CompositeConstantRef = function(type, idx1, idx2) {
    this.type = type;
    this.idx1 = idx1;
    this.idx2 = idx2;
}

let JavaField = function(access, name, descriptor, attributes) {
    this.access = access;
    this.name = name;
    this.descriptor = descriptor;
    this.attributes = attributes;
}

let JavaMethod = function(access, name, descriptor, attributes) {
    this.access = access;
    this.name = name;
    this.descriptor = descriptor;
    this.attributes = attributes;
}

let JavaClass = function(access, name, parent, interfaces, constants, fields, methods, attributes) {
    this.access = access;
    this.name = name;
    this.parent = parent;
    this.interfaces = interfaces;
    this.constants = constants;
    this.fields = fields;
    this.methods = methods;
    this.attributes = attributes;
}

const prv = {
    magic : 0xCAFEBABE,
    supportedVersion : [52, 0],

    u1 : function(arr, offset) {
        return arr[offset] >>> 0;
    },

    u2 : function(arr, offset) {
        return (arr[offset] << 8 >>> 0) + (arr[offset + 1] >>> 0);
    },

    u4 : function(arr, offset) {
        return (arr[offset] << 24 >>> 0) + (arr[offset + 1] << 16 >>> 0) + (arr[offset + 2] << 8 >>> 0) + (arr[offset + 3] >>> 0);
    },

    compareArrays : function(a, b) {
        if (a.length === undefined || b.length === undefined || !isFinite(a.length) || !isFinite(b.length)) {
            return false;
        }
        if (a.length !== b.length) {
            return false;
        }
        const length = a.length;
        for (let i = 0; i < length; ++i) {
            if (a[i] !== b[i]) {
                return false;
            }
        }
        return true;
    },

    readMultiple : function(arr, base, entryReader, seed) {
        let size = prv.u2(arr, base);
        let offset = base + 2;
        let entries = seed === undefined ? [] : seed;
        for (let i = entries.length; i < size; ++i) {
            var [entry, next] = entryReader(arr, offset);
            entries.push(entry);
            offset += next;
        }
        return [entries, offset];
    },

    checkMagic : function(arr) {
        let magic = prv.u4(arr, 0);
        return magic === prv.magic;
    },

    checkVersion : function(arr) {
        let minor = prv.u2(arr, 4);
        let major = prv.u2(arr, 6);
        return this.compareArrays([major, minor], prv.supportedVersion);
    },

    validateClass : function(arr) {
        if (prv.checkMagic(arr)) {
            console.debug("It's a Java class!");
        }
        else {
            throw new Error("It's not a Java class - magic bytes do not match");
        }
        if (prv.checkVersion(arr)) {
            console.debug("Detected supported class file format version")
        }
        else {
            console.warn("Detected unsupported class file format version")
        }
    },

    readConstant : function(arr, offset) {
        let tag = prv.u1(arr, offset);
        offset += 1;

        switch (tag) {
            // Utf8
            case 1:
                let length = prv.u2(arr, offset);
                return [new StringView(arr, "UTF-8", offset + 2, length), length + 3 ]
                break;
            // Methodref
            case 10:
                return [new CompositeConstantRef("method", prv.u2(arr, offset), prv.u2(arr, offset + 2)), 5];
                break;
            // Fieldref
            case 9:
                return [new CompositeConstantRef("field", prv.u2(arr, offset), prv.u2(arr, offset + 2)), 5];
                break;
            // String
            case 8:
                return [new ConstantRef("string", prv.u2(arr, offset)), 3];
                break;
            // Class
            case 7:
                return [new ConstantRef("class", prv.u2(arr, offset)), 3];
                break;
            // NameAndType
            case 12:
                return [new CompositeConstantRef("name&type", prv.u2(arr, offset), prv.u2(arr, offset + 2)), 5];
                break;
            default:
                throw new Error("Unsupported tag: " + tag);
        }
    },

    readConstants : function(arr, base) {
        return prv.readMultiple(arr, base, prv.readConstant, [null]);
    },

    readMeta : function(arr, base) {
        let offset = base;
        let meta = {};
        meta.access = prv.u2(arr, offset);
        meta.name = new ConstantRef("this", prv.u2(arr, offset + 2))
        meta.parent = new ConstantRef("super", prv.u2(arr, offset + 4))
        let [interfaces, lastOffset] = prv.readInterfaces(arr, offset + 6);
        meta.interfaces = interfaces;
        return [meta, lastOffset];
    },

    readInterface : function(arr, base) {
        return [new ConstantRef("interface", prv.u2(arr, base)), 2];
    },

    readInterfaces : function(arr, base) {
        return prv.readMultiple(arr, base, prv.readInterface);
    },

    readFieldOrMethod : function(Factory) {
        return function(arr, base) {
            let access = prv.u2(arr, base);
            let name = new ConstantRef("name", prv.u2(arr, base + 2));
            let descriptor = new ConstantRef("name", prv.u2(arr, base + 4));
            let [attributes, lastOffset] = prv.readAttributes(arr, base + 6);
            let field = new Factory(access, name, descriptor, attributes);
            return [field, lastOffset - base];
        }
    },

    readFields : function(arr, base) {
        return prv.readMultiple(arr, base, prv.readFieldOrMethod(JavaField));
    },

    readMethods : function(arr, base) {
        return prv.readMultiple(arr, base, prv.readFieldOrMethod(JavaMethod));
    },

    readAttribute : function(arr, base) {
        let name = prv.u2(arr, base);
        let size = prv.u4(arr, base + 2);
        console.info("readAttribute", base, size + 6);
        return [arr.slice(base, base + size), size + 6];
    },

    readAttributes : function(arr, base) {
        return prv.readMultiple(arr, base, prv.readAttribute);
    },
}

let JavaJS = function() {
    this.classes = new Map();
}

JavaJS.prototype.register = function(javaClass) {
    if (this.classes.has(javaClass.name)) {
        return false;
    }

    this.classes.set(javaClass.name, javaClass);
    return true;
}

JavaJS.prototype.load = function(binary) {
    console.log("Read:", binary.byteLength);
    let clazz = new Uint8Array(binary);
    console.log(clazz);

    prv.validateClass(clazz);

    let constantsOffset = 8;
    let [constants, metaOffset] = prv.readConstants(clazz, constantsOffset);
    let [meta, fieldsOffset] = prv.readMeta(clazz, metaOffset);
    let [fields, methodsOffset] = prv.readFields(clazz, fieldsOffset);
    let [methods, attribsOffset] = prv.readMethods(clazz, methodsOffset);
    let [attributes, end] = prv.readAttributes(clazz, attribsOffset);

    if (end !== binary.byteLength) {
        console.warn("Class binary was not fully consumed");
    }

    let newClass = new JavaClass(meta.access, meta.name, meta.parent, meta.interfaces, constants, fields, methods, attributes);
    if (this.register(newClass)) {
        console.info("Class", newClass, "registered");
    }
    else {
        console.warn("Class", newClass, "not registered");
    }
}

global.Java = new JavaJS();
})(window);
<|endoftext|>


<commit_before>/* D3 function for drawing temperatures and rain bars in same svg */
var temprain = function(el, json, attr, xformat, yaxisleg, width, height) {
    var margin = {top: 20, right: 20, bottom: 30, left: 50},
        width = width - margin.left - margin.right,
        height = height - margin.top - margin.bottom;

    var svg = d3.select(el).append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    addGradient(svg, width, height);

    var x = d3.time.scale()
        .range([0, width]);

    var y = d3.scale.linear()
        .range([height, 0]);

    var xAxis = d3.svg.axis()
        .scale(x)
        .tickFormat(xformat)
        .orient("bottom");

    var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left");

    x.domain(d3.extent(json, function(d) { return d.date; }));
    y.domain([d3.min(json, function(d) { return d.tempmin }), d3.max(json, function(d) { return d.tempmax; })]);

    // Y Axis grid
    var yrule = svg.selectAll("g.y")
        .data(y.ticks(10))
        .enter().append("g")
        .attr("class", "y axis")
      .append("svg:line")
        .attr("class", "yLine")
        .attr("x1", 0)
        .attr("x2", width)
        .attr("y1", y)
        .attr("y2", y)
        .style('stroke', function(d, i) {
            if(d == 0) {
                return 'steelblue';
            }
            return '#ededed';
        })
        .style("shape-rendering", "crispEdges")
        ;

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

    // Y Axis legend
    svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text(yaxisleg);

    // Temp line
    var line = d3.svg.line()
        .x(function(d) { return x(d.date); })
        .y(function(d) { return y(d.temp); })
        .interpolate("basis")

    var pathos = svg.append("path")
      .datum(json)
      .attr("class", "line")
      .attr("stroke", "red")
      .attr("d", line)
    // Low Temp line
    var line = d3.svg.line()
        .x(function(d) { return x(d.date); })
        .y(function(d) { return y(d.tempmin); })
        .interpolate("basis")
    var pathoslow = svg.append("path")
      .datum(json)
      .attr("class", "line")
      .attr("stroke-dasharray", "5,5")
      .attr("stroke", "steelblue")
      .attr("d", line)
    // High Temp line
    var line = d3.svg.line()
        .x(function(d) { return x(d.date); })
        .y(function(d) { return y(d.tempmax); })
        .interpolate("basis")
    var pathoslow = svg.append("path")
      .datum(json)
      .attr("class", "line")
      .attr("stroke-dasharray", "5,5")
      .attr("stroke", "darkred")
      .attr("d", line)

    /* Pressure section */

    x.domain(d3.extent(json, function(d) { return d.date; }));
    var y = d3.scale.linear()
        .range([height, 0]);
    //y.domain(d3.extent(json, function(d) { return d.barometer; }));
    // hard coded minmax
    y.domain([950, 1050]);
    // Pressure line
    var line = d3.svg.line()
        .x(function(d) { return x(d.date); })
        .y(function(d) { return y(d.barometer); })
        .interpolate("basis")

    // Pressure path
    var pathospressure = svg.append("path")
      .datum(json)
      .attr("class", "line")
      .attr("stroke", "darkgreen")
      .attr("stroke-opacity", "0.2")
      .attr("d", line)

    /* Rain bar section */

    var x = d3.time.scale()
        .range([0, 1]);

    var y = d3.scale.linear()
        .range([height, 0]);

    x.domain(json.map(function(d) { return d.date; }));
    y.domain([0, d3.max(json, function(d) { return d.daily_rain; })]);

    var barxpos = function(d) {
      var nr = x(d.date);
      var bwidth = (width/json.length)*0.8
      var barmargin = (width/json.length)*0.2
      var barx = width-bwidth;
      return  nr*bwidth + nr*barmargin;
    }

    svg.selectAll(".bar")
      .data(json)
    .enter().append("rect")
      .attr("class", "bar")
      .attr('rx', 3)
      .attr('ry', 3)
      .attr("x", barxpos )
      .attr("width", (width/json.length)*0.8)
      .attr("y", function(d) { return height; })
      .attr("height", function(d) { return 0; })
      .on("mouseover", function(d,i){
          d3.select(this)
          .attr("stroke-width", "3px");

      var x; var y;
      if (d3.event.pageX != undefined && d3.event.pageY != undefined) {
          x = d3.event.pageX;
          y = d3.event.pageY;
      } else {
          x = d3.event.clientX + document.body.scrollLeft +
          document.documentElement.scrollLeft;
      y = d3.event.clientY + document.body.scrollTop +
          document.documentElement.scrollTop;
      }

      var bubble_code = "
Date: "
          + d.timestamp + "
  Rain: " + Number(d.daily_rain).toFixed(1) + " mm
"
          + "
";
      $("body").append(bubble_code);

      }).on("mouseout", function(d,i){
          d3.select(this)
          .attr("stroke-width", "1px");
      $("#tt").remove();
      })

      .transition().delay(function (d,i){ return 300;})
      .duration(150)
      .attr("y", function(d) { return y(d.daily_rain); })
      .attr("height", function(d) { return height - y(d.daily_rain); })

      ;

    var valfmt = function(d) {
        var nr = d.daily_rain;
        if (nr == 0) return '';
        if (nr < 1 )
            return Number(nr).toFixed(1);
        return parseInt(nr);
    }
    svg.selectAll("text.score")
        .data(json)
        .enter().append("text")
        .attr("x", barxpos)
        .attr("y", function(d){ return y(d.daily_rain) + 10 } )
        .attr("dx", (width/json.length)*0.4)
        .attr("dy", (width/json.length)*0.4)
        .attr("text-anchor", "middle")
        .attr('class', 'score')
        .style('font-size', function(d) {
            // Compute proper font size
            w = (width/json.length)*0.6;
            return w + 'px' })
        .text(valfmt)

  var focus = svg.append("g")
      .attr("class", "focus");

  focus.append("line")
      .attr("class", "x")
      .attr("y1", y(0) - 6)
      .attr("y2", y(0) + 6);

  focus.append("line")
      .attr("class", "y")
      .attr("x1", width - 6)
      .attr("x2", width + 6);

  focus.append("circle")
      .attr("r", 3.5);

  /*
  svg.append("rect")
      .attr("class", "overlay")
      .attr("width", width)
      .attr("height", height)
      .on("mousemove", mousemove);

  function mousemove() {
    var d = json[Math.round((x.invert(d3.mouse(this)[0]) - json[0].date) / 60*60*24)];
    focus.select("circle").attr("transform", "translate(" + x(d[0]) + "," + y(d[1]) + ")");
    focus.select(".x").attr("transform", "translate(" + x(d[0]) + ",0)");
    focus.select(".y").attr("transform", "translate(0," + y(d[1]) + ")");
    svg.selectAll(".x.axis path").style("fill-opacity", Math.random()); // XXX Chrome redraw bug
  }*/
}

var addGradient = function(target, w, h) {
    var gradient = target.append("svg:defs")
      .append("svg:linearGradient")
        .attr("id", "gradient")
        .attr("x1", "0%")
        .attr("y1", "0%")
        .attr("x2", "0%")
        .attr("y2", "100%")
        .attr("spreadMethod", "pad");

    gradient.append("svg:stop")
        .attr("offset", "0%")
        .attr("stop-color", "#fff")
        .attr("stop-opacity", 1);

    gradient.append("svg:stop")
        .attr("offset", "100%")
        .attr("stop-color", "#f2f2f2")
        .attr("stop-opacity", 1);

    target.append("svg:rect")
        .attr("width", w)
        .attr("height", h)
        .style("fill", "url(#gradient)");
}
<commit_msg>half bar height<commit_after>/* D3 function for drawing temperatures and rain bars in same svg */
var temprain = function(el, json, attr, xformat, yaxisleg, width, height) {
    var margin = {top: 20, right: 20, bottom: 30, left: 50},
        width = width - margin.left - margin.right,
        height = height - margin.top - margin.bottom;

    var svg = d3.select(el).append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    addGradient(svg, width, height);

    var x = d3.time.scale()
        .range([0, width]);

    var y = d3.scale.linear()
        .range([height, 0]);

    var xAxis = d3.svg.axis()
        .scale(x)
        .tickFormat(xformat)
        .orient("bottom");

    var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left");

    x.domain(d3.extent(json, function(d) { return d.date; }));
    y.domain([d3.min(json, function(d) { return d.tempmin }), d3.max(json, function(d) { return d.tempmax; })]);

    // Y Axis grid
    var yrule = svg.selectAll("g.y")
        .data(y.ticks(10))
        .enter().append("g")
        .attr("class", "y axis")
      .append("svg:line")
        .attr("class", "yLine")
        .attr("x1", 0)
        .attr("x2", width)
        .attr("y1", y)
        .attr("y2", y)
        .style('stroke', function(d, i) {
            if(d == 0) {
                return 'steelblue';
            }
            return '#ededed';
        })
        .style("shape-rendering", "crispEdges")
        ;

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

    // Y Axis legend
    svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text(yaxisleg);

    // Temp line
    var line = d3.svg.line()
        .x(function(d) { return x(d.date); })
        .y(function(d) { return y(d.temp); })
        .interpolate("basis")

    var pathos = svg.append("path")
      .datum(json)
      .attr("class", "line")
      .attr("stroke", "red")
      .attr("d", line)
    // Low Temp line
    var line = d3.svg.line()
        .x(function(d) { return x(d.date); })
        .y(function(d) { return y(d.tempmin); })
        .interpolate("basis")
    var pathoslow = svg.append("path")
      .datum(json)
      .attr("class", "line")
      .attr("stroke-dasharray", "5,5")
      .attr("stroke", "steelblue")
      .attr("d", line)
    // High Temp line
    var line = d3.svg.line()
        .x(function(d) { return x(d.date); })
        .y(function(d) { return y(d.tempmax); })
        .interpolate("basis")
    var pathoslow = svg.append("path")
      .datum(json)
      .attr("class", "line")
      .attr("stroke-dasharray", "5,5")
      .attr("stroke", "darkred")
      .attr("d", line)

    /* Pressure section */

    x.domain(d3.extent(json, function(d) { return d.date; }));
    var y = d3.scale.linear()
        .range([height, 0]);
    //y.domain(d3.extent(json, function(d) { return d.barometer; }));
    // hard coded minmax
    y.domain([950, 1050]);
    // Pressure line
    var line = d3.svg.line()
        .x(function(d) { return x(d.date); })
        .y(function(d) { return y(d.barometer); })
        .interpolate("basis")

    // Pressure path
    var pathospressure = svg.append("path")
      .datum(json)
      .attr("class", "line")
      .attr("stroke", "darkgreen")
      .attr("stroke-opacity", "0.2")
      .attr("d", line)

    /* Rain bar section */

    var x = d3.time.scale()
        .range([0, 1]);

    var y = d3.scale.linear()
        .range([height, height/2]);

    x.domain(json.map(function(d) { return d.date; }));
    y.domain([0, d3.max(json, function(d) { return d.daily_rain; })]);

    var barxpos = function(d) {
      var nr = x(d.date);
      var bwidth = (width/json.length)*0.8
      var barmargin = (width/json.length)*0.2
      var barx = width-bwidth;
      return  nr*bwidth + nr*barmargin;
    }

    svg.selectAll(".bar")
      .data(json)
    .enter().append("rect")
      .attr("class", "bar")
      .attr('rx', 3)
      .attr('ry', 3)
      .attr("x", barxpos )
      .attr("width", (width/json.length)*0.8)
      .attr("y", function(d) { return height; })
      .attr("height", function(d) { return 0; })
      .on("mouseover", function(d,i){
          d3.select(this)
          .attr("stroke-width", "3px");

      var x; var y;
      if (d3.event.pageX != undefined && d3.event.pageY != undefined) {
          x = d3.event.pageX;
          y = d3.event.pageY;
      } else {
          x = d3.event.clientX + document.body.scrollLeft +
          document.documentElement.scrollLeft;
      y = d3.event.clientY + document.body.scrollTop +
          document.documentElement.scrollTop;
      }

      var bubble_code = "
Date: "
          + d.timestamp + "
  Rain: " + Number(d.daily_rain).toFixed(1) + " mm
"
          + "
";
      $("body").append(bubble_code);

      }).on("mouseout", function(d,i){
          d3.select(this)
          .attr("stroke-width", "1px");
      $("#tt").remove();
      })

      .transition().delay(function (d,i){ return 300;})
      .duration(150)
      .attr("y", function(d) { return y(d.daily_rain); })
      .attr("height", function(d) { return height - y(d.daily_rain); })

      ;

    var valfmt = function(d) {
        var nr = d.daily_rain;
        if (nr == 0) return '';
        if (nr < 1 )
            return Number(nr).toFixed(1);
        return parseInt(nr);
    }
    svg.selectAll("text.score")
        .data(json)
        .enter().append("text")
        .attr("x", barxpos)
        .attr("y", function(d){ return y(d.daily_rain) + 10 } )
        .attr("dx", (width/json.length)*0.4)
        .attr("dy", (width/json.length)*0.4)
        .attr("text-anchor", "middle")
        .attr('class', 'score')
        .style('font-size', function(d) {
            // Compute proper font size
            w = (width/json.length)*0.6;
            return w + 'px' })
        .text(valfmt)

  var focus = svg.append("g")
      .attr("class", "focus");

  focus.append("line")
      .attr("class", "x")
      .attr("y1", y(0) - 6)
      .attr("y2", y(0) + 6);

  focus.append("line")
      .attr("class", "y")
      .attr("x1", width - 6)
      .attr("x2", width + 6);

  focus.append("circle")
      .attr("r", 3.5);

  /*
  svg.append("rect")
      .attr("class", "overlay")
      .attr("width", width)
      .attr("height", height)
      .on("mousemove", mousemove);

  function mousemove() {
    var d = json[Math.round((x.invert(d3.mouse(this)[0]) - json[0].date) / 60*60*24)];
    focus.select("circle").attr("transform", "translate(" + x(d[0]) + "," + y(d[1]) + ")");
    focus.select(".x").attr("transform", "translate(" + x(d[0]) + ",0)");
    focus.select(".y").attr("transform", "translate(0," + y(d[1]) + ")");
    svg.selectAll(".x.axis path").style("fill-opacity", Math.random()); // XXX Chrome redraw bug
  }*/
}

var addGradient = function(target, w, h) {
    var gradient = target.append("svg:defs")
      .append("svg:linearGradient")
        .attr("id", "gradient")
        .attr("x1", "0%")
        .attr("y1", "0%")
        .attr("x2", "0%")
        .attr("y2", "100%")
        .attr("spreadMethod", "pad");

    gradient.append("svg:stop")
        .attr("offset", "0%")
        .attr("stop-color", "#fff")
        .attr("stop-opacity", 1);

    gradient.append("svg:stop")
        .attr("offset", "100%")
        .attr("stop-color", "#f2f2f2")
        .attr("stop-opacity", 1);

    target.append("svg:rect")
        .attr("width", w)
        .attr("height", h)
        .style("fill", "url(#gradient)");
}
<|endoftext|>


<commit_before>import { discover } from 'opensearch-browser';

function prepareBox(bbox) {
  bbox[1] = Math.max(bbox[1], -90);
  bbox[3] = Math.min(bbox[3], 90);

  for (let i = 0; i <= 2; i += 2) {
    while (bbox[i] > 180) {
      bbox[i] -= 360;
    }
    while (bbox[i] < -180) {
      bbox[i] += 360;
    }
  }
  return bbox;
}

/**
 * Convert a filters model, map model, and options to an OpenSearch parameters
 * object
 */
function convertFilters(filtersModel, mapModel, options, format, service) {
  const description = service.getDescription();
  const url = description.getUrl(null, format || null);

  const parameters = {};

  const time = filtersModel.get('time');
  if (time) {
    if (Array.isArray(time)) {
      parameters['time:start'] = time[0];
      parameters['time:end'] = time[1];
    } else {
      parameters['time:start'] = time;
      parameters['time:end'] = time;
    }
  }

  const area = filtersModel.get('area');
  if (area) {
    if (Array.isArray(area)) {
      parameters['geo:box'] = prepareBox(area);
    } else if (area.geometry) {
      const geometry = area.geometry;
      if (geometry.type === 'Point') {
        parameters['geo:lon'] = geometry.coordinates[0];
        parameters['geo:lat'] = geometry.coordinates[1];
      } else {
        parameters['geo:geometry'] = geometry;
      }
    }
  } else if (mapModel) {
    // use the maps BBox by default
    parameters['geo:box'] = prepareBox(mapModel.get('bbox'));
  }

  if (options.hasOwnProperty('itemsPerPage') && url.hasParameter('count')) {
    parameters.count = options.itemsPerPage;
  }

  if (options.hasOwnProperty('page')) {
    if (url.hasParameter('startIndex') && options.hasOwnProperty('itemsPerPage')) {
      parameters.startIndex = options.page * options.itemsPerPage + url.indexOffset;
    } else if (url.hasParameter('startPage')) {
      parameters.startPage = options.page + url.pageOffset;
    }
  }

  Object.keys(filtersModel.attributes).forEach((key) => {
    if (url.hasParameter(key)) {
      parameters[key] = filtersModel.get(key);
    }
  });

  return parameters;
}

function getMaxPageSize(urlObj) {
  const param = urlObj.getParameter('count');
  if (param) {
    return param.maxInclusive ? param.maxInclusive : param.maxExclusive - 1;
  }
  return null;
}

function prepareRecords(records) {
  return records.map(record => {
    if (record.geometry && record.geometry.type === "Polygon") {
      for (let ringIndex = 0; ringIndex < record.geometry.coordinates.length; ++ringIndex) {
        const ring = record.geometry.coordinates[ringIndex];
        let last = null;
        for (let i = 0; i < ring.length; ++i) {
          const current = ring[i];
          if (last) {
            if (current[0] - last[0] < -180) {
              current[0] += 360;
            }
            if (current[0] - last[0] > 180) {
              current[0] -= 360;
            }
          }
          last = current;
        }
      }
    }
    return record;
  });
}

// cached services
const services = {};

function getService(url) {
  if (!services[url]) {
    // add a new promise
    services[url] = discover(url);
  }
  return services[url];
}

export function search(layerModel, filtersModel, mapModel, options = {}) {
  const url = layerModel.get('search.url');
  const method = layerModel.get('search.method');
  const format = options.mimeType || layerModel.get('search.format') || null;

  return getService(url)
    .then(service => {
      const parameters = convertFilters(filtersModel, mapModel, options, format, service);
      return service.search(parameters, format, method || 'GET', false, true);
    })
    .then(result => {
      result.records = prepareRecords(result.records);
      return result;
    });
}

export function searchAllRecords(layerModel, filtersModel, mapModel, options = {}) {
  const url = layerModel.get('search.url');
  const method = layerModel.get('search.method');
  const format = options.mimeType || layerModel.get('search.format') || null;
  const maxCount = options.maxCount;

  return getService(url)
    .then(service => {
      const parameters = convertFilters(filtersModel, mapModel, options, format, service);
      const paginator = service.getPaginator(parameters, format, method, true);
      if (maxCount) {
        return paginator.fetchFirstRecords(maxCount)
          .then(result => ({
            totalResults: result.totalResults,
            itemsPerPage: result.itemsPerPage,
            startIndex: result.startIndex,
            records: prepareRecords(result.records),
          }));
      }
      return paginator.fetchAllRecords()
        .then(result => ({
          totalResults: result.totalResults,
          itemsPerPage: result.itemsPerPage,
          startIndex: result.startIndex,
          records: prepareRecords(result.records),
        }));
    });
}

export function getParameters(layerModel) {
  const url = layerModel.get('search.url');
  const method = layerModel.get('search.method');
  const format = layerModel.get('search.format');

  return getService(url)
    .then(service => service
      .getDescription()
      .getUrl(null, format, method)
      .parameters
    );
}
<commit_msg>Improving compatibility with point queries<commit_after>import { discover } from 'opensearch-browser';

function prepareBox(bbox) {
  bbox[1] = Math.max(bbox[1], -90);
  bbox[3] = Math.min(bbox[3], 90);

  for (let i = 0; i <= 2; i += 2) {
    while (bbox[i] > 180) {
      bbox[i] -= 360;
    }
    while (bbox[i] < -180) {
      bbox[i] += 360;
    }
  }
  return bbox;
}

/**
 * Convert a filters model, map model, and options to an OpenSearch parameters
 * object
 */
function convertFilters(filtersModel, mapModel, options, format, service) {
  const description = service.getDescription();
  const url = description.getUrl(null, format || null);

  const parameters = {};

  const time = filtersModel.get('time');
  if (time) {
    if (Array.isArray(time)) {
      parameters['time:start'] = time[0];
      parameters['time:end'] = time[1];
    } else {
      parameters['time:start'] = time;
      parameters['time:end'] = time;
    }
  }

  const area = filtersModel.get('area');
  if (area) {
    if (Array.isArray(area)) {
      parameters['geo:box'] = prepareBox(area);
    } else if (area.geometry) {
      const geometry = area.geometry;
      if (geometry.type === 'Point' && url.hasParameter('geo:lon') && url.hasParameter('geo:lat')) {
        parameters['geo:lon'] = geometry.coordinates[0];
        parameters['geo:lat'] = geometry.coordinates[1];
      } else {
        parameters['geo:geometry'] = geometry;
      }
    }
  } else if (mapModel) {
    // use the maps BBox by default
    parameters['geo:box'] = prepareBox(mapModel.get('bbox'));
  }

  if (options.hasOwnProperty('itemsPerPage') && url.hasParameter('count')) {
    parameters.count = options.itemsPerPage;
  }

  if (options.hasOwnProperty('page')) {
    if (url.hasParameter('startIndex') && options.hasOwnProperty('itemsPerPage')) {
      parameters.startIndex = options.page * options.itemsPerPage + url.indexOffset;
    } else if (url.hasParameter('startPage')) {
      parameters.startPage = options.page + url.pageOffset;
    }
  }

  Object.keys(filtersModel.attributes).forEach((key) => {
    if (url.hasParameter(key)) {
      parameters[key] = filtersModel.get(key);
    }
  });

  return parameters;
}

function getMaxPageSize(urlObj) {
  const param = urlObj.getParameter('count');
  if (param) {
    return param.maxInclusive ? param.maxInclusive : param.maxExclusive - 1;
  }
  return null;
}

function prepareRecords(records) {
  return records.map(record => {
    if (record.geometry && record.geometry.type === 'Polygon') {
      for (let ringIndex = 0; ringIndex < record.geometry.coordinates.length; ++ringIndex) {
        const ring = record.geometry.coordinates[ringIndex];
        let last = null;
        for (let i = 0; i < ring.length; ++i) {
          const current = ring[i];
          if (last) {
            if (current[0] - last[0] < -180) {
              current[0] += 360;
            }
            if (current[0] - last[0] > 180) {
              current[0] -= 360;
            }
          }
          last = current;
        }
      }
    }
    return record;
  });
}

// cached services
const services = {};

function getService(url) {
  if (!services[url]) {
    // add a new promise
    services[url] = discover(url);
  }
  return services[url];
}

export function search(layerModel, filtersModel, mapModel, options = {}) {
  const url = layerModel.get('search.url');
  const method = layerModel.get('search.method');
  const format = options.mimeType || layerModel.get('search.format') || null;

  return getService(url)
    .then(service => {
      const parameters = convertFilters(filtersModel, mapModel, options, format, service);
      return service.search(parameters, format, method || 'GET', false, true);
    })
    .then(result => {
      result.records = prepareRecords(result.records);
      return result;
    });
}

export function searchAllRecords(layerModel, filtersModel, mapModel, options = {}) {
  const url = layerModel.get('search.url');
  const method = layerModel.get('search.method');
  const format = options.mimeType || layerModel.get('search.format') || null;
  const maxCount = options.maxCount;

  return getService(url)
    .then(service => {
      const parameters = convertFilters(filtersModel, mapModel, options, format, service);
      const paginator = service.getPaginator(parameters, format, method, true);
      if (maxCount) {
        return paginator.fetchFirstRecords(maxCount)
          .then(result => ({
            totalResults: result.totalResults,
            itemsPerPage: result.itemsPerPage,
            startIndex: result.startIndex,
            records: prepareRecords(result.records),
          }));
      }
      return paginator.fetchAllRecords()
        .then(result => ({
          totalResults: result.totalResults,
          itemsPerPage: result.itemsPerPage,
          startIndex: result.startIndex,
          records: prepareRecords(result.records),
        }));
    });
}

export function getParameters(layerModel) {
  const url = layerModel.get('search.url');
  const method = layerModel.get('search.method');
  const format = layerModel.get('search.format');

  return getService(url)
    .then(service => service
      .getDescription()
      .getUrl(null, format, method)
      .parameters
    );
}
<|endoftext|>


<commit_before>/*
 * Copyright 2020 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
 *
 *     https://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.
 */

/**
 * External dependencies
 */
import styled from 'styled-components';
import PropTypes from 'prop-types';
import { forwardRef, useRef } from 'react';
import { v4 as uuidv4 } from 'uuid';

/**
 * Internal dependencies
 */
import { Tab } from '../tab';

const StyledTabGroup = styled.div`
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;

  & > button {
    margin: 0 4px;
    &:first-of-type {
      margin-left: 0;
    }
    &:last-of-type {
      margin-right: 0;
    }
  }
`;

export const TabGroup = forwardRef(function TabGroup(
  {
    getTabId = (id) => id,
    getAriaControlsId,
    tabs,
    label,
    handleTabClicked,
    activeTabId,
  },
  ref
) {
  const tabRefs = useRef({});

  return (
    <StyledTabGroup ref={ref} aria-label={label}>
      {tabs.map(({ id, title, ...rest }) => {
        const isActive = activeTabId === id;
        return (
          <Tab
            key={uuidv4()}
            ref={(tabRef) => (tabRefs.current[id] = tabRef)}
            id={getTabId(id)}
            isActive={isActive}
            aria-controls={
              getAriaControlsId ? getAriaControlsId(id) : getTabId(id)
            }
            aria-selected={isActive}
            onClick={(e) => handleTabClicked(e, id, tabRefs)}
            {...rest}
          >
            {title}
          </Tab>
        );
      })}
    </StyledTabGroup>
  );
});

TabGroup.propTypes = {
  activeTabId: PropTypes.string,
  getTabId: PropTypes.func,
  getAriaControlsId: PropTypes.func,
  handleTabClicked: PropTypes.func,
  tabs: PropTypes.arrayOf({
    title: PropTypes.string,
    id: PropTypes.string.isRequired,
  }),
  label: PropTypes.string,
};
<commit_msg>adding tablist role<commit_after>/*
 * Copyright 2020 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
 *
 *     https://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.
 */

/**
 * External dependencies
 */
import styled from 'styled-components';
import PropTypes from 'prop-types';
import { forwardRef, useRef } from 'react';
import { v4 as uuidv4 } from 'uuid';

/**
 * Internal dependencies
 */
import { Tab } from '../tab';

const StyledTabGroup = styled.div`
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;

  & > button {
    margin: 0 4px;
    &:first-of-type {
      margin-left: 0;
    }
    &:last-of-type {
      margin-right: 0;
    }
  }
`;

export const TabGroup = forwardRef(function TabGroup(
  {
    getTabId = (id) => id,
    getAriaControlsId,
    tabs,
    label,
    handleTabClicked,
    activeTabId,
  },
  ref
) {
  const tabRefs = useRef({});

  return (
    <StyledTabGroup ref={ref} aria-label={label} role="tablist">
      {tabs.map(({ id, title, ...rest }) => {
        const isActive = activeTabId === id;
        return (
          <Tab
            key={uuidv4()}
            ref={(tabRef) => (tabRefs.current[id] = tabRef)}
            id={getTabId(id)}
            isActive={isActive}
            aria-controls={
              getAriaControlsId ? getAriaControlsId(id) : getTabId(id)
            }
            aria-selected={isActive}
            onClick={(e) => handleTabClicked(e, id, tabRefs)}
            {...rest}
          >
            {title}
          </Tab>
        );
      })}
    </StyledTabGroup>
  );
});

TabGroup.propTypes = {
  activeTabId: PropTypes.string,
  getTabId: PropTypes.func,
  getAriaControlsId: PropTypes.func,
  handleTabClicked: PropTypes.func,
  tabs: PropTypes.arrayOf({
    title: PropTypes.string,
    id: PropTypes.string.isRequired,
  }),
  label: PropTypes.string,
};
<|endoftext|>


<commit_before>// ==UserScript==
// @name        Redirect to up to date documentation
// @namespace   sieradzki.it
// @description Detects if currently viewed online documentation page is the most recent version available, and if not, redirects user to the latest version.
// @version     1.1.0
// @downloadURL https://github.com/kuc/Redirect-to-up-to-date-documentation/raw/master/redirectToUpToDateDocumentation.user.js

// @grant       GM_xmlhttpRequest

// @match       *://docs.oracle.com/*
// @match       *://wiki.eclipse.org/Jetty*
// @match       *://www.playframework.com/documentation/*
// @match       *://www.postgresql.org/docs/*
// @match       *://docs.spring.io/*
// ==/UserScript==

/*jshint nonew:true, curly:true, noarg:true, trailing:true, loopfunc:true, forin:true, noempty:true, eqeqeq:true,
 strict:true, undef:true, bitwise:true, newcap:false, browser:true, devel:true, nonbsp:true */
/*global GM_xmlhttpRequest */

(function () {
	'use strict';

	var documentations = {
		javaSE: {
			currentVersion: '8',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/docs\.oracle\.com\/javase\/([0-9\.]+)\/docs\/api\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				url = url.replace(/\/javase\/([0-9\.]+)\/docs\/api\//, '/javase/' + this.currentVersion + '/docs/api/');
				url = url.replace(/%2[8-9]|\(|\)/g, '-'); // "(" and ")" to "-"
				url = url.replace(/%5B/g, ':'); // "[" to ":"
				url = url.replace(/%5D/g, 'A'); // "]" to "A"
				return url;
			}
		},
		javaEE: {
			currentVersion: '7',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/docs\.oracle\.com\/javaee\/([0-9\.]+)\/api\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/javaee\/([0-9\.]+)\/api\//, '/javaee/' + this.currentVersion + '/api/');
			}
		},
		jetty: {
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/wiki\.eclipse\.org\/Jetty/);
				var messageBoxLinks =
					document.querySelectorAll('div.messagebox a[href^="http://www.eclipse.org/jetty/documentation"]');
				return matches !== null && messageBoxLinks !== null && messageBoxLinks.length === 2;
			},
			rewriteUrl: function () {
				return document.querySelectorAll('div.messagebox a[href^="http://www.eclipse.org/jetty/documentation"]')[1].href;
			}
		},
		postgreSQL: {
			currentVersion: 'current',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/www\.postgresql\.org\/docs\/([0-9\.]+)\/(static|interactive)\//);
				return matches !== null && matches[2] !== this.currentVersion && matches[2] !== 'devel';
			},
			rewriteUrl: function (url) {
				return url.replace(/\/docs\/([0-9\.]+)\//, '/docs/' + this.currentVersion + '/');
			}
		},
		playFrameworkJava: {
			currentVersion: '2.3.x',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/www\.playframework\.com\/documentation\/([0-9\.A-Zx\-]+)\/api\/java\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/documentation\/([0-9\.A-Zx\-]+)\/api\/java\//,
						'/documentation/' + this.currentVersion + '/api/java/');
			}
		},
		playFrameworkScala: {
			currentVersion: '2.3.x',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/www\.playframework\.com\/documentation\/([0-9\.A-Zx\-]+)\/api\/scala\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/documentation\/([0-9\.A-Zx\-]+)\/api\/scala\//,
						'/documentation/' + this.currentVersion + '/api/scala/');
			}
		},
		springData: {
			currentVersion: 'current',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(
					/^http(s)?:\/\/docs\.spring\.io\/spring\-data\/([0-9a-z\-]+)\/docs\/([0-9\.A-Zx\-]+)\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/docs\/([0-9\.A-Zx\-]+)\//, '/docs/' + this.currentVersion + '/');
			}
		},
		springFramework: {
			currentVersion: 'current',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/docs\.spring\.io\/spring\/docs\/([0-9\.A-Zx\-]+)\/(javadoc\-)?api\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/docs\/([0-9\.A-Zx\-]+)\/(javadoc\-)?api\//, '/docs/' + this.currentVersion +
					'/javadoc-api/');
			}
		},
		springSecurity: {
			currentVersion: 'current',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/docs\.spring\.io\/spring\-security\/site\/docs\/([0-9\.A-Zx\-]+)\/apidocs\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/site\/docs\/([0-9\.A-Zx\-]+)\/apidocs\//, '/site/docs/' + this.currentVersion +
					'/apidocs/');
			}
		},
		springSocial: {
			currentVersion: 'current',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/docs\.spring\.io\/spring\-social\/docs\/([0-9\.A-Zx\-]+)\/api(docs)?\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/docs\/([0-9\.A-Zx\-]+)\/api(docs)?\//, '/docs/' + this.currentVersion +
					'/apidocs/');
			}
		}
	};

	var DocumentationRedirect = function () {

		for (var key in documentations) {
			if (documentations.hasOwnProperty(key)) {
				if (documentations[key].isDocumentationPageOutdated(window.location.href)) {
					var rewrittenUrl = documentations[key].rewriteUrl(window.location.href);

					// In newer version of documentation e.g. current viewed class could be permanently deleted, so
					// redirection should only occur when we are sure that target page exists
					this.ifPageExists(rewrittenUrl, function (url) {
						window.location.replace(url);
					});

					break;
				}
			}
		}
	};

	/**
	 * @private
	 */
	DocumentationRedirect.prototype.ifPageExists = function (url, callback) {

		GM_xmlhttpRequest({
			method: 'HEAD',
			url: url,
			'onload': function (response) {
				if (response.status < 400) {
					callback(url);
				}
			}
		});
	};

	window.DocumentationRedirect = new DocumentationRedirect();
})();
<commit_msg>Add redirection for JavaFX<commit_after>// ==UserScript==
// @name        Redirect to up to date documentation
// @namespace   sieradzki.it
// @description Detects if currently viewed online documentation page is the most recent version available, and if not, redirects user to the latest version.
// @version     1.1.0
// @downloadURL https://github.com/kuc/Redirect-to-up-to-date-documentation/raw/master/redirectToUpToDateDocumentation.user.js

// @grant       GM_xmlhttpRequest

// @match       *://docs.oracle.com/*
// @match       *://wiki.eclipse.org/Jetty*
// @match       *://www.playframework.com/documentation/*
// @match       *://www.postgresql.org/docs/*
// @match       *://docs.spring.io/*
// ==/UserScript==

/*jshint nonew:true, curly:true, noarg:true, trailing:true, loopfunc:true, forin:true, noempty:true, eqeqeq:true,
 strict:true, undef:true, bitwise:true, newcap:false, browser:true, devel:true, nonbsp:true */
/*global GM_xmlhttpRequest */

(function () {
	'use strict';

	var documentations = {
		javaSE: {
			currentVersion: '8',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/docs\.oracle\.com\/javase\/([0-9\.]+)\/docs\/api\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				url = url.replace(/\/javase\/([0-9\.]+)\/docs\/api\//, '/javase/' + this.currentVersion + '/docs/api/');
				url = url.replace(/%2[8-9]|\(|\)/g, '-'); // "(" and ")" to "-"
				url = url.replace(/%5B/g, ':'); // "[" to ":"
				url = url.replace(/%5D/g, 'A'); // "]" to "A"
				return url;
			}
		},
		javaEE: {
			currentVersion: '7',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/docs\.oracle\.com\/javaee\/([0-9\.]+)\/api\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/javaee\/([0-9\.]+)\/api\//, '/javaee/' + this.currentVersion + '/api/');
			}
		},
		javaFX: {
			currentVersion: '8',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/docs\.oracle\.com\/javafx\/([0-9\.]+)\/api\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/javafx\/([0-9\.]+)\/api\//, '/javase/' + this.currentVersion + '/javafx/api/');
			}
		},
		jetty: {
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/wiki\.eclipse\.org\/Jetty/);
				var messageBoxLinks =
					document.querySelectorAll('div.messagebox a[href^="http://www.eclipse.org/jetty/documentation"]');
				return matches !== null && messageBoxLinks !== null && messageBoxLinks.length === 2;
			},
			rewriteUrl: function () {
				return document.querySelectorAll('div.messagebox a[href^="http://www.eclipse.org/jetty/documentation"]')[1].href;
			}
		},
		postgreSQL: {
			currentVersion: 'current',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/www\.postgresql\.org\/docs\/([0-9\.]+)\/(static|interactive)\//);
				return matches !== null && matches[2] !== this.currentVersion && matches[2] !== 'devel';
			},
			rewriteUrl: function (url) {
				return url.replace(/\/docs\/([0-9\.]+)\//, '/docs/' + this.currentVersion + '/');
			}
		},
		playFrameworkJava: {
			currentVersion: '2.3.x',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/www\.playframework\.com\/documentation\/([0-9\.A-Zx\-]+)\/api\/java\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/documentation\/([0-9\.A-Zx\-]+)\/api\/java\//,
						'/documentation/' + this.currentVersion + '/api/java/');
			}
		},
		playFrameworkScala: {
			currentVersion: '2.3.x',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/www\.playframework\.com\/documentation\/([0-9\.A-Zx\-]+)\/api\/scala\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/documentation\/([0-9\.A-Zx\-]+)\/api\/scala\//,
						'/documentation/' + this.currentVersion + '/api/scala/');
			}
		},
		springData: {
			currentVersion: 'current',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(
					/^http(s)?:\/\/docs\.spring\.io\/spring\-data\/([0-9a-z\-]+)\/docs\/([0-9\.A-Zx\-]+)\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/docs\/([0-9\.A-Zx\-]+)\//, '/docs/' + this.currentVersion + '/');
			}
		},
		springFramework: {
			currentVersion: 'current',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/docs\.spring\.io\/spring\/docs\/([0-9\.A-Zx\-]+)\/(javadoc\-)?api\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/docs\/([0-9\.A-Zx\-]+)\/(javadoc\-)?api\//, '/docs/' + this.currentVersion +
					'/javadoc-api/');
			}
		},
		springSecurity: {
			currentVersion: 'current',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/docs\.spring\.io\/spring\-security\/site\/docs\/([0-9\.A-Zx\-]+)\/apidocs\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/site\/docs\/([0-9\.A-Zx\-]+)\/apidocs\//, '/site/docs/' + this.currentVersion +
					'/apidocs/');
			}
		},
		springSocial: {
			currentVersion: 'current',
			isDocumentationPageOutdated: function (url) {
				var matches = url.match(/^http(s)?:\/\/docs\.spring\.io\/spring\-social\/docs\/([0-9\.A-Zx\-]+)\/api(docs)?\//);
				return matches !== null && matches[2] !== this.currentVersion;
			},
			rewriteUrl: function (url) {
				return url.replace(/\/docs\/([0-9\.A-Zx\-]+)\/api(docs)?\//, '/docs/' + this.currentVersion +
					'/apidocs/');
			}
		}
	};

	var DocumentationRedirect = function () {

		for (var key in documentations) {
			if (documentations.hasOwnProperty(key)) {
				if (documentations[key].isDocumentationPageOutdated(window.location.href)) {
					var rewrittenUrl = documentations[key].rewriteUrl(window.location.href);

					// In newer version of documentation e.g. current viewed class could be permanently deleted, so
					// redirection should only occur when we are sure that target page exists
					this.ifPageExists(rewrittenUrl, function (url) {
						window.location.replace(url);
					});

					break;
				}
			}
		}
	};

	/**
	 * @private
	 */
	DocumentationRedirect.prototype.ifPageExists = function (url, callback) {

		GM_xmlhttpRequest({
			method: 'HEAD',
			url: url,
			'onload': function (response) {
				if (response.status < 400) {
					callback(url);
				}
			}
		});
	};

	window.DocumentationRedirect = new DocumentationRedirect();
})();
<|endoftext|>


<commit_before>"use strict";

var assert = require('assert');

var statistics = function(s) {

    var minFn = function(x,y) { return Math.min(x,y); };

    return {
	count: s.length,
	minimum: s.length === 0 ? undefined : s.reduce(minFn, s[0])
    };
};

describe('sequence processing', function() {
    it('should return the count', function() {
	assert.equal(0, statistics([]).count);
	assert.equal(3, statistics([1,2,3]).count);
    });

    it('avg, min and max should be undefined for empty lists', function() {
	var stats = statistics([]);

	assert.equal(undefined, stats.minimum);
	assert.equal(undefined, stats.maximum);
	assert.equal(undefined, stats.average);
    });

    it('min works as expected on lists', function() {
	assert.equal(0, statistics([0]).minimum);
	assert.equal(3, statistics([5,4,3]).minimum);
    });

    it('max works as expected', function() {
	assert.equal(0, statistics([0]).maximum);
    });

});
<commit_msg>simplest possible pass<commit_after>"use strict";

var assert = require('assert');

var statistics = function(s) {

    var minFn = function(x,y) { return Math.min(x,y); };

    return {
	count: s.length,
	maximum: s.length === 0 ? undefined : 0,
	minimum: s.length === 0 ? undefined : s.reduce(minFn, s[0])
    };
};

describe('sequence processing', function() {
    it('should return the count', function() {
	assert.equal(0, statistics([]).count);
	assert.equal(3, statistics([1,2,3]).count);
    });

    it('avg, min and max should be undefined for empty lists', function() {
	var stats = statistics([]);

	assert.equal(undefined, stats.minimum);
	assert.equal(undefined, stats.maximum);
	assert.equal(undefined, stats.average);
    });

    it('min works as expected on lists', function() {
	assert.equal(0, statistics([0]).minimum);
	assert.equal(3, statistics([5,4,3]).minimum);
    });

    it('max works as expected', function() {
	assert.equal(0, statistics([0]).maximum);
    });

});
<|endoftext|>


<commit_before>/**
 * Created by ebbaholmstrom on 16-04-15.
 */
$ (function() {
    var d = new Date();
var weekday = new Array(7);
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";

var n = weekday[d.getDay()];
document.getElementById("getDay").innerHTML = n;
})

$ (function(){
    var p = new Date();
var q = p.getDate();
document.getElementById("getDate").innerHTML = q;
})

$ (function() {
    var a = new Date();
var month = new Array(12);

month[0] = "January";
month[1] = "February";
month[2] = "Mars";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "August";
month[8] = "September";
month[9] = "October";
month[10] = "November";
month[11] = "December";

var b = month[a.getMonth()];
document.getElementById("getMonth").innerHTML = b;
})
<commit_msg>test1 är skapad..<commit_after>/**
 * Created by ebbaholmstrom on 16-04-15.
 */
$ (function() {
    var d = new Date();
var weekday = new Array(7);
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";

var n = weekday[d.getDay()];
document.getElementById("getDay").innerHTML = n;
})

$ (function(){
    var p = new Date();
var q = p.getDate();
document.getElementById("getDate").innerHTML = q;
})

$ (function() {
    var a = new Date();
var month = new Array(12);

month[0] = "January";
month[1] = "February";
month[2] = "Mars";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "August";
month[8] = "September";
month[9] = "October";
month[10] = "November";
month[11] = "December";

var b = month[a.getMonth()];
document.getElementById("getMonth").innerHTML = b;
})
<|endoftext|>


<commit_before>import Shader from '../../low_level/shaders/Shader';
import DecalShader from './DecalShader';
import Vector4 from '../../low_level/math/Vector4';

export class PBRPrincipledShaderSource {

  FSDefine_PBRPrincipledShaderSource(in_, f, lights) {

    var sampler2D = this._sampler2DShadow_func();
    var shaderText = '';
    shaderText += 'uniform vec4 Kd;\n';
    shaderText += 'uniform vec4 ambient;\n'; // Ka * amount of ambient lights

    let lightNumExceptAmbient = lights.filter((light)=>{return !light.isTypeAmbient();}).length;
    if (lightNumExceptAmbient > 0) {
      shaderText += `uniform highp ${sampler2D} uDepthTexture[${lightNumExceptAmbient}];\n`;
      shaderText += `uniform int isShadowCasting[${lightNumExceptAmbient}];\n`;
    }

    return shaderText;
  }

  VSMethodDefine_PBRPrincipledShaderSource(f, lights, material, extraData) {
    let shaderText = '';

    shaderText += `
      const float M_PI = 3.141592653589793;
    `;

    shaderText += `
    float angular_n_h(float NH) {
      return acos(NH);
    }
    `;

    shaderText += `
    float sqr(float x) {
      return x*x;
    }
    `;

    shaderText += `
    float d_phong(float NH, float c1) {
      return pow(
        cos(acos(NH))
        , c1
      );
    }
    `;

    shaderText += `
    // GGX NDF
    float d_ggx(float NH, float alphaRoughness) {
      float roughnessSqr = alphaRoughness * alphaRoughness;
      float f = (roughnessSqr - 1) * NH * NH + 1.0;
      return roughnessSq / (M_PI * f * f);
    }
    `;

    shaderText += `
    float d_torrance_reiz(float NH, float c3) {
      float CosSquared = NH*NH;
      float TanSquared = (1.0 - CosSquared)/CosSquared;
      //return (1.0/PI) * sqr(c3/(CosSquared * (c3*c3 + TanSquared)));  // gamma = 2, aka GGX
      return (1.0/sqrt(PI)) * (sqr(c3)/(CosSquared * (c3*c3 + TanSquared))); // gamma = 1, D_Berry
    }
    `;

    shaderText += `
    float d_beckmann(float NH, float m) {
      float co = 1.0 / (4.0 * m * m * NH * NH * NH * NH);
      float expx = exp((NH * NH - 1.0) / (m * m * NH * NH));
      return co * expx;
    }
    `;

    shaderText += `
    // the same as glTF WebGL sample
    // https://github.com/KhronosGroup/glTF-WebGL-PBR/blob/88eda8c5358efe03128b72b6c5f5f6e5b6d023e1/shaders/pbr-frag.glsl#L188
    // That is, Unreal Engine based approach, but modified to use alphaRoughness (squared artist's roughness parameter),
    // and based on 'Separable Masking and Shadowing' approximation (propesed by Christophe Schlick)
    // https://www.cs.virginia.edu/~jdl/bib/appearance/analytic%20models/schlick94b.pdf
    float g_shielding(float NH, float NV, float NL, float VH, float alphaRoughness) {
      float r = alphaRoughness;

      // Local Shadowing using Smith Masking Function (Schlick's approximation version)
      float localShadowing = 2.0 * NL / (NL + sqrt(r * r + (1.0 - r * r) * (NL * NL)));

      // Local Masking using Smith Masking Function (Schlick's approximation version)
      float localMasking = 2.0 * NV / (NV + sqrt(r * r + (1.0 - r * r) * (NV * NV)));

      return localShadowing * localMasking;
    }
    `;

    shaderText += `
    // The Schlick Approximation to Fresnel
    float fresnel(float f0, float LH) {
      return f0 + (1.0 - f0) * pow(1.0 - LH, 5);
    }
    `;

    shaderText += `
    float cook_torrance_specular_brdf(float n, float NH, float NV, float NL, float VH, float power) {
      float D = d_torrance_reiz(NH, power);
      float G = g_shielding(NH, NV, NL, VH);
      float F = fresnel(n, VH);
      return D*G*F/(4*NL*NV);
    }
    `;

    return shaderText;
  }

  FSShade_PBRPrincipledShaderSource(f, gl, lights) {
    var shaderText = '';

    shaderText += '  vec4 surfaceColor = rt0;\n';
    shaderText += '  rt0 = vec4(0.0, 0.0, 0.0, 0.0);\n';

    for (let i=0; i<lights.length; i++) {
      let light = lights[i];
      let isShadowEnabledAsTexture = (light.camera && light.camera.texture) ? true:false;
      shaderText += `  {\n`;
      shaderText +=      Shader._generateLightStr(i);
      shaderText +=      Shader._generateShadowingStr(gl, i, isShadowEnabledAsTexture);
      shaderText += `    float diffuse = max(dot(lightDirection, normal), 0.0);\n`;
      shaderText += `    rt0 += spotEffect * vec4(visibility, visibility, visibility, 1.0) * Kd * lightDiffuse[${i}] * vec4(diffuse, diffuse, diffuse, 1.0) * surfaceColor;\n`;
      shaderText += `  }\n`;
    }
    shaderText += '  rt0.xyz += ambient.xyz;\n';

    //shaderText += '  rt0.a = 1.0;\n';
    // shaderText += '  rt0 = surfaceColor;\n';
//    shaderText += '  rt0 = vec4(v_shadowCoord[0].xy, 0.0, 1.0);\n';

    return shaderText;
  }

  prepare_PBRPrincipledShaderSource(gl, shaderProgram, expression, vertexAttribs, existCamera_f, lights, material, extraData) {

    var vertexAttribsAsResult = [];

    material.setUniform(shaderProgram, 'uniform_Kd', this._glContext.getUniformLocation(shaderProgram, 'Kd'));
    material.setUniform(shaderProgram, 'uniform_ambient', this._glContext.getUniformLocation(shaderProgram, 'ambient'));

    return vertexAttribsAsResult;
  }
}

export default class PBRPrincipledShader extends DecalShader {
  constructor(glBoostContext, basicShader) {

    super(glBoostContext, basicShader);
    LambertShader.mixin(LambertShaderSource);
  }

  setUniforms(gl, glslProgram, scene, material, camera, mesh, lights) {
    super.setUniforms(gl, glslProgram, scene, material, camera, mesh, lights);

  }

}

GLBoost['PBRPrincipledShader'] = PBRPrincipledShader;
<commit_msg>Implementing PBRPrincipledShader<commit_after>import Shader from '../../low_level/shaders/Shader';
import DecalShader from './DecalShader';
import Vector4 from '../../low_level/math/Vector4';

export class PBRPrincipledShaderSource {

  FSDefine_PBRPrincipledShaderSource(in_, f, lights) {

    var sampler2D = this._sampler2DShadow_func();
    var shaderText = '';
    shaderText += 'uniform vec4 Kd;\n';
    shaderText += 'uniform vec4 ambient;\n'; // Ka * amount of ambient lights

    let lightNumExceptAmbient = lights.filter((light)=>{return !light.isTypeAmbient();}).length;
    if (lightNumExceptAmbient > 0) {
      shaderText += `uniform highp ${sampler2D} uDepthTexture[${lightNumExceptAmbient}];\n`;
      shaderText += `uniform int isShadowCasting[${lightNumExceptAmbient}];\n`;
    }

    return shaderText;
  }

  VSMethodDefine_PBRPrincipledShaderSource(f, lights, material, extraData) {
    let shaderText = '';

    shaderText += `
      const float M_PI = 3.141592653589793;
    `;

    shaderText += `
    float angular_n_h(float NH) {
      return acos(NH);
    }
    `;

    shaderText += `
    float sqr(float x) {
      return x*x;
    }
    `;

    shaderText += `
    float d_phong(float NH, float c1) {
      return pow(
        cos(acos(NH))
        , c1
      );
    }
    `;

    shaderText += `
    // GGX NDF
    float d_ggx(float NH, float alphaRoughness) {
      float roughnessSqr = alphaRoughness * alphaRoughness;
      float f = (roughnessSqr - 1) * NH * NH + 1.0;
      return roughnessSq / (M_PI * f * f);
    }
    `;

    shaderText += `
    float d_torrance_reiz(float NH, float c3) {
      float CosSquared = NH*NH;
      float TanSquared = (1.0 - CosSquared)/CosSquared;
      //return (1.0/PI) * sqr(c3/(CosSquared * (c3*c3 + TanSquared)));  // gamma = 2, aka GGX
      return (1.0/sqrt(PI)) * (sqr(c3)/(CosSquared * (c3*c3 + TanSquared))); // gamma = 1, D_Berry
    }
    `;

    shaderText += `
    float d_beckmann(float NH, float m) {
      float co = 1.0 / (4.0 * m * m * NH * NH * NH * NH);
      float expx = exp((NH * NH - 1.0) / (m * m * NH * NH));
      return co * expx;
    }
    `;

    shaderText += `
    // the same as glTF WebGL sample
    // https://github.com/KhronosGroup/glTF-WebGL-PBR/blob/88eda8c5358efe03128b72b6c5f5f6e5b6d023e1/shaders/pbr-frag.glsl#L188
    // That is, Unreal Engine based approach, but modified to use alphaRoughness (squared artist's roughness parameter),
    // and based on 'Separable Masking and Shadowing' approximation (propesed by Christophe Schlick)
    // https://www.cs.virginia.edu/~jdl/bib/appearance/analytic%20models/schlick94b.pdf
    float g_shielding(float NL, float NV, float alphaRoughness) {
      float r = alphaRoughness;

      // Local Shadowing using "Schlick-Smith" Masking Function
      float localShadowing = 2.0 * NL / (NL + sqrt(r * r + (1.0 - r * r) * (NL * NL)));

      // Local Masking using "Schlick-Smith" Masking Function
      float localMasking = 2.0 * NV / (NV + sqrt(r * r + (1.0 - r * r) * (NV * NV)));

      return localShadowing * localMasking;
    }
    `;

    shaderText += `
    // The Schlick Approximation to Fresnel
    float fresnel(float f0, float LH) {
      return f0 + (1.0 - f0) * pow(1.0 - LH, 5);
    }
    `;

    shaderText += `
    float cook_torrance_specular_brdf(float f0, float NH, float NL, float NV, float alphaRoughness) {
      float D = d_ggx(NH, alphaRoughness);
      float G = g_shielding(NL, NV, alphaRoughness);
      float F = fresnel(f0, LH);
      return D*G*F/(4.0*NL*NV);
    }
    `;

    return shaderText;
  }

  FSShade_PBRPrincipledShaderSource(f, gl, lights) {
    var shaderText = '';

    shaderText += '  vec4 surfaceColor = rt0;\n';
    shaderText += '  rt0 = vec4(0.0, 0.0, 0.0, 0.0);\n';

    for (let i=0; i<lights.length; i++) {
      let light = lights[i];
      let isShadowEnabledAsTexture = (light.camera && light.camera.texture) ? true:false;
      shaderText += `  {\n`;
      shaderText +=      Shader._generateLightStr(i);
      shaderText +=      Shader._generateShadowingStr(gl, i, isShadowEnabledAsTexture);
      shaderText += `    float diffuse = max(dot(lightDirection, normal), 0.0);\n`;
      shaderText += `    rt0 += spotEffect * vec4(visibility, visibility, visibility, 1.0) * Kd * lightDiffuse[${i}] * vec4(diffuse, diffuse, diffuse, 1.0) * surfaceColor;\n`;
      shaderText += `    vec3 viewDirection = normalize(viewPosition_world - v_position_world);\n`;
      shaderText += '    vec3 halfVector = normalize(lightDirection + viewDirection);\n';
      shaderText += '    float NH = dot(normal, halfVector);\n';
      shaderText += '    float NV = dot(normal, viewDirection);\n';
      shaderText += '    float NL = dot(normal, lightDirection);\n';
      shaderText += '    float VH = dot(viewDirection, halfVector);\n';

      shaderText += `    float specular = cook_torrance_specular_brdf(f0, NH, NL, NV, alphaRoughness);\n`;
      shaderText += `  }\n`;
    }
    shaderText += '  rt0.xyz += ambient.xyz;\n';

    //shaderText += '  rt0.a = 1.0;\n';
    // shaderText += '  rt0 = surfaceColor;\n';
//    shaderText += '  rt0 = vec4(v_shadowCoord[0].xy, 0.0, 1.0);\n';

    return shaderText;
  }

  prepare_PBRPrincipledShaderSource(gl, shaderProgram, expression, vertexAttribs, existCamera_f, lights, material, extraData) {

    var vertexAttribsAsResult = [];

    material.setUniform(shaderProgram, 'uniform_Kd', this._glContext.getUniformLocation(shaderProgram, 'Kd'));
    material.setUniform(shaderProgram, 'uniform_ambient', this._glContext.getUniformLocation(shaderProgram, 'ambient'));

    return vertexAttribsAsResult;
  }
}

export default class PBRPrincipledShader extends DecalShader {
  constructor(glBoostContext, basicShader) {

    super(glBoostContext, basicShader);
    LambertShader.mixin(LambertShaderSource);
  }

  setUniforms(gl, glslProgram, scene, material, camera, mesh, lights) {
    super.setUniforms(gl, glslProgram, scene, material, camera, mesh, lights);

  }

}

GLBoost['PBRPrincipledShader'] = PBRPrincipledShader;
<|endoftext|>


<commit_before>'use strict';

var Runtime = require('../');

it('runs callback if fn throws from other stack', function(done){
  var error = Error('on no!');
  var runtime = Runtime.create();

  function one(next){ next(); }
  function two(){ throw error; }

  runtime.stack(one, runtime.stack(two))(function(err){
    err.should.be.eql(error);
    done();
  });
});

it('runs callback if error given to next from other stack', function(done){
  var error = Error('on no!');
  var runtime = Runtime.create();

  function one(next){ next(); }
  function two(next){ next(error); }

  runtime.stack(one, runtime.stack(two))(function(err){
    err.should.be.eql(error);
    done();
  });
});

it('runs the callback on completion of all stacks', function(done){
  var runtime = Runtime.create();

  var count = 0;
  function one(next){
    setTimeout(function(){
      ++count; next();
    }, Math.random()*10);
  }
  function two(next){
    setTimeout(function(){
      ++count; next();
    }, Math.random()*10*count);
  }

  runtime.stack(one, runtime.stack(two))(function(err){
    if(err){ return done(err); }
    count.should.be.eql(2);
    done();
  });
});

it('runs stacks in parallel by default', function(done){
  var runtime = Runtime.create();

  var stack = '';
  function one(next){
    setTimeout(function(){
      stack += 'one';
      next();
    }, Math.random()*10);
  }
  function two(next){
    stack += 'two';
    next();
  }

  runtime.stack(runtime.stack(one), runtime.stack(two))(function(err){
    if(err){ return done(err); }
    stack.should.be.eql('twoone');
    done();
  });
});

it('{wait: true} should run stacks in series', function(done){
  var runtime = Runtime.create();

  var stack = '';
  function one(next){
    setTimeout(function(){
      stack += 'one';
      next();
    }, Math.random()*10);
  }
  function two(next){
    stack += 'two';
    next();
  }

  runtime.stack(
    runtime.stack(one, {wait: true}),
    runtime.stack(two, {wait: true}), {wait: true})(function(err){
      if(err){ return done(err); }
      stack.should.be.eql('onetwo');
      done();
    }
  );
});

it('passes arguments when host and completed stack waits', function(done){
  var runtime = Runtime.create();

  function one(next, foo){
    foo.should.be.eql(1);
    next(2);
  }
  function two(next, foo){
    foo.should.be.eql(2);
    next();
  }

  runtime.stack(
    runtime.stack(one, {wait: true}),
    runtime.stack(two),
    {wait: true}
  )(1, 2, done);
});

it('does NOT pass arguments when stacks does NOT wait', function(done){
  var runtime = Runtime.create();

  function one(next, foo){
    foo.should.be.eql(1);
    next(2);
  }
  function two(next, foo){
    foo.should.be.eql(1);
    next();
  }

  runtime.stack(
    runtime.stack(one),
    runtime.stack(two)
  )(1, 2, done);
});
<commit_msg>test: more test for composed stacks<commit_after>'use strict';

var Runtime = require('../');

it('runs callback if fn throws from other stack', function(done){
  var error = Error('on no!');
  var runtime = Runtime.create();

  function one(next){ next(); }
  function two(){ throw error; }

  runtime.stack(one, runtime.stack(two))(function(err){
    err.should.be.eql(error);
    done();
  });
});

it('runs callback if error given to next from other stack', function(done){
  var error = Error('on no!');
  var runtime = Runtime.create();

  function one(next){ next(); }
  function two(next){ next(error); }

  runtime.stack(one, runtime.stack(two))(function(err){
    err.should.be.eql(error);
    done();
  });
});

it('runs the callback on completion of all stacks', function(done){
  var runtime = Runtime.create();

  var count = 0;
  function one(next){
    setTimeout(function(){
      ++count; next();
    }, Math.random()*10);
  }
  function two(next){
    setTimeout(function(){
      ++count; next();
    }, Math.random()*10*count);
  }

  runtime.stack(one, runtime.stack(two))(function(err){
    if(err){ return done(err); }
    count.should.be.eql(2);
    done();
  });
});

it('runs stacks in parallel by default', function(done){
  var runtime = Runtime.create();

  var stack = '';
  function one(next){
    setTimeout(function(){
      stack += 'one';
      next();
    }, Math.random()*10);
  }
  function two(next){
    stack += 'two';
    next();
  }
  function three(next){
    stack += 'three';
    next();
  }
  function four(next){
    stack += 'four';
    next();
  }

  runtime.stack(
    one,
    runtime.stack(two),
    runtime.stack(three, four)
  )(function(err){
    if(err){ return done(err); }
    stack.should.not.be.eql('onetwothreefour');
    done();
  });
});

it('{wait: true} should run stacks in series', function(done){
  var runtime = Runtime.create();

  var stack = '';
  function one(next){
    setTimeout(function(){
      stack += 'one';
      next();
    }, Math.random()*10);
  }
  function two(next){
    stack += 'two';
    next();
  }

  function three(next){
    setTimeout(function(){
      stack += 'three';
      next();
    }, Math.random()*10);
  }
  function four(next){
    stack += 'four';
    next();
  }

  runtime.stack(
    one,
    runtime.stack(one, two, {wait: true}),
    runtime.stack(one, two, three, four, {wait: true}),
    four,
    {wait: true})(function(err){
      if(err){ return done(err); }
      stack.should.be.eql('oneonetwoonetwothreefourfour');
      done();
    }
  );
});

it('series: callback is run after all stacks are finished', function(done){
  var runtime = Runtime.create();

  var count = -1;
  var stack = [];
  function one(next){
    var pos = ++count;
    setTimeout(function(){
      stack.push(pos);
      next();
    }, Math.random()*10);
  }

  runtime.stack(
      runtime.stack(one,
        runtime.stack(one,
          runtime.stack(one,
            runtime.stack(one,
              runtime.stack(one,
                runtime.stack(one,
                  runtime.stack(one,
                    runtime.stack(one,
                      runtime.stack(one,
                        runtime.stack(one, {wait: true}),
                      {wait: true}),
                    {wait: true}),
                  {wait: true}),
                {wait: true}),
              {wait: true}),
            {wait: true}),
          {wait: true}),
        {wait: true}),
      {wait: true}),
    {wait: true})(function(err){
      if(err){ return done(err); }
      stack.should.be.eql([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
      done();
    }
  );
});

it('passes arguments when host and completed stack waits', function(done){
  var runtime = Runtime.create();

  function one(next, foo){
    foo.should.be.eql(1);
    next(2);
  }
  function two(next, foo){
    foo.should.be.eql(2);
    next();
  }

  runtime.stack(
    runtime.stack(one, {wait: true}),
    runtime.stack(two),
    {wait: true}
  )(1, 2, done);
});

it('does NOT pass arguments when stacks does NOT wait', function(done){
  var runtime = Runtime.create();

  function one(next, foo){
    foo.should.be.eql(1);
    next(2);
  }
  function two(next, foo){
    foo.should.be.eql(1);
    next();
  }

  runtime.stack(
    runtime.stack(one),
    runtime.stack(two)
  )(1, 2, done);
});
<|endoftext|>