text:
/* global define, require */
(function (root, factory) {
	'use strict';

	if (typeof exports === 'object') {
		// Node/CommonJS
		factory(require('seriously'));
	} else if (typeof define === 'function' && define.amd) {
		// AMD. Register as an anonymous module.
		define(['seriously'], factory);
	} else {
		if (!root.Seriously) {
			root.Seriously = { plugin: function (name, opt) { this[name] = opt; } };
		}
		factory(root.Seriously);
	}
}(this, function (Seriously, undefined) {
	'use strict';

	//particle parameters
	var minVelocity = 0.2,
		maxVelocity = 0.8,
		minSize = 0.02,
		maxSize = 0.3,
		particleCount = 20;

	Seriously.plugin('tvglitch', function () {
		var lastHeight,
			lastTime,
			particleBuffer,
			particleShader,
			particleFrameBuffer,
			gl;

		return {
			initialize: function (parent) {
				var i,
					sizeRange,
					velocityRange,
					particleVertex,
					particleFragment,
					particles;

				gl = this.gl;

				lastHeight = this.height;

				//initialize particles
				particles = [];
				sizeRange = maxSize - minSize;
				velocityRange = maxVelocity - minVelocity;
				for (i = 0; i < particleCount; i++) {
					particles.push(Math.random() * 2 - 1); //position
					particles.push(Math.random() * velocityRange + minVelocity); //velocity
					particles.push(Math.random() * sizeRange + minSize); //size
					particles.push(Math.random() * 0.2); //intensity
				}

				particleBuffer = gl.createBuffer();
				gl.bindBuffer(gl.ARRAY_BUFFER, particleBuffer);
				gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(particles), gl.STATIC_DRAW);
				particleBuffer.itemSize = 4;
				particleBuffer.numItems = particleCount;

				particleVertex = '#ifdef GL_ES\n' +
				'precision mediump float;\n' +
				'#endif \n' +
				'\n' +
				'attribute vec4 particle;\n' +
				'\n' +
				'uniform float time;\n' +
				'uniform float height;\n' +
				'\n' +
				'varying float intensity;\n' +
				'\n' +
				'void main(void) {\n' +
				'	float y = particle.x + time * particle.y;\n' +
				'	y = fract((y + 1.0) / 2.0) * 4.0 - 2.0;\n' +
				'	intensity = particle.w;\n' +
				'	gl_Position = vec4(0.0, -y , 1.0, 2.0);\n' +
				//'	gl_Position = vec4(0.0, 1.0 , 1.0, 1.0);\n' +
				'	gl_PointSize = height * particle.z;\n' +
				'}\n';

				particleFragment = '#ifdef GL_ES\n\n' +
				'precision mediump float;\n\n' +
				'#endif\n\n' +
				'\n' +
				'varying float intensity;\n' +
				'\n' +
				'void main(void) {\n' +
				'	gl_FragColor = vec4(1.0);\n' +
				'	gl_FragColor.a = 2.0 * intensity * (1.0 - abs(gl_PointCoord.y - 0.5));\n' +
				'}\n';

				particleShader = new Seriously.util.ShaderProgram(gl, particleVertex, particleFragment);

				particleFrameBuffer = new Seriously.util.FrameBuffer(gl, 1, Math.max(1, this.height / 2));
				parent();
			},
			commonShader: true,
			shader: function (inputs, shaderSource) {
				//baseShader = this.baseShader;

				shaderSource.fragment = '#ifdef GL_ES\n\n' +
					'precision mediump float;\n\n' +
					'#endif\n\n' +
					'\n' +
					//'#define HardLight(top, bottom) (top < 0.5 ? (2.0 * top * bottom) : (1.0 - 2.0 * (1.0 - top) * (1.0 - bottom)))\n' +
					'#define HardLight(top, bottom)  (1.0 - 2.0 * (1.0 - top) * (1.0 - bottom))\n' +
					'\n' +
					'varying vec2 vTexCoord;\n' +
					'varying vec4 vPosition;\n' +
					'\n' +
					'uniform sampler2D source;\n' +
					'uniform sampler2D particles;\n' +
					'uniform float time;\n' +
					'uniform float scanlines;\n' +
					'uniform float lineSync;\n' +
					'uniform float lineHeight;\n' + //for scanlines and distortion
					'uniform float distortion;\n' +
					'uniform float vsync;\n' +
					'uniform float bars;\n' +
					'uniform float frameSharpness;\n' +
					'uniform float frameShape;\n' +
					'uniform float frameLimit;\n' +
					'uniform vec4 frameColor;\n' +
					'\n' +
					//todo: need much better pseudo-random number generator
					Seriously.util.shader.noiseHelpers +
					Seriously.util.shader.snoise2d +
					'\n' +
					'void main(void) {\n' +
					'	vec2 texCoord = vTexCoord;\n' +

						//distortion
					'	float drandom = snoise(vec2(time * 50.0, texCoord.y /lineHeight));\n' +
					'	float distortAmount = distortion * (drandom - 0.25) * 0.5;\n' +
						//line sync
					'	vec4 particleOffset = texture2D(particles, vec2(0.0, texCoord.y));\n' +
					'	distortAmount -= lineSync * (2.0 * particleOffset.a - 0.5);\n' +

					'	texCoord.x -= distortAmount;\n' +
					//'	texCoord.x = max(0.0, texCoord.x);\n' +
					//'	texCoord.x = min(1.0, texCoord.x);\n' +
					'	texCoord.x = mod(texCoord.x, 1.0);\n' +

						//vertical sync
					'	float roll;\n' +
					'	if (vsync != 0.0) {\n' +
					'		roll = fract(time / vsync);\n' +
					'		texCoord.y = mod(texCoord.y - roll, 1.0);\n' +
					'	}\n' +

					'	vec4 pixel = texture2D(source, texCoord);\n' +

						//horizontal bars
					'	float barsAmount = particleOffset.r;\n' +
					'	if (barsAmount > 0.0) {\n' +
					/*
					'		pixel = vec4(HardLight(pixel.r * bars, barsAmount),' +
								'HardLight(pixel.g * bars, barsAmount),' +
								'HardLight(pixel.b * bars, barsAmount),' +
								'pixel.a);\n' +
					*/
					'		pixel = vec4(pixel.r + bars * barsAmount,' +
								'pixel.g + bars * barsAmount,' +
								'pixel.b + bars * barsAmount,' +
								'pixel.a);\n' +
					'	}\n' +

					'	if (mod(texCoord.y / lineHeight, 2.0) < 1.0 ) {\n' +
					'		pixel.rgb *= (1.0 - scanlines);\n' +
					'	}\n' +

					'	float f = (1.0 - vPosition.x * vPosition.x) * (1.0 - vPosition.y * vPosition.y);\n' +
					'	float frame = clamp( frameSharpness * (pow(f, frameShape) - frameLimit), 0.0, 1.0);\n' +

					//'	gl_FragColor.r = vec4(1.0);\n' +

					'	gl_FragColor = mix(frameColor, pixel, frame); //vec4(vec3(particleOffset), 1.0);\n' +
					//'	gl_FragColor = vec4(particleOffset);\n' +
					//'	gl_FragColor.a = 1.0;\n' +
					'}\n';

				return shaderSource;
			},
			resize: function () {
				particleFrameBuffer.resize(1, Math.max(1, this.height / 2));
			},
			draw: function (shader, model, uniforms, frameBuffer, parent) {
				var doParticles = (lastTime !== this.inputs.time),
					vsyncPeriod;

				if (lastHeight !== this.height) {
					lastHeight = this.height;
					doParticles = true;
				}

				//todo: make this configurable?
				uniforms.lineHeight = 1 / this.height;

				if (this.inputs.verticalSync) {
					vsyncPeriod = 0.2 / this.inputs.verticalSync;
					uniforms.vsync = vsyncPeriod;
				} else {
					vsyncPeriod = 1;
					uniforms.vsync = 0;
				}
				uniforms.time = (this.inputs.time % (10000 * vsyncPeriod)) / 1000;
				uniforms.distortion = Math.random() * this.inputs.distortion;

				//render particle canvas and attach uniform
				//todo: this is a good spot for parallel processing. ParallelArray maybe?
				if (doParticles && (this.inputs.lineSync || this.inputs.bars)) {
					particleShader.use();
					gl.viewport(0, 0, 1, this.height / 2);
					gl.bindFramebuffer(gl.FRAMEBUFFER, particleFrameBuffer.frameBuffer);
					gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
					gl.enableVertexAttribArray(particleShader.location.particle);
					gl.bindBuffer(gl.ARRAY_BUFFER, particleBuffer);
					gl.vertexAttribPointer(particleShader.location.particle, particleBuffer.itemSize, gl.FLOAT, false, 0, 0);
					gl.enable(gl.BLEND);
					gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
					particleShader.time.set(uniforms.time);
					particleShader.height.set(this.height);
					gl.drawArrays(gl.POINTS, 0, particleCount);

					lastTime = this.inputs.time;
				}
				uniforms.particles = particleFrameBuffer.texture;

				parent(shader, model, uniforms, frameBuffer);
			},
			destroy: function () {
				particleBuffer = null;
				if (particleFrameBuffer) {
					particleFrameBuffer.destroy();
					particleFrameBuffer = null;
				}
			}
		};
	},
	{
		inPlace: false,
		inputs: {
			source: {
				type: 'image',
				uniform: 'source',
				shaderDirty: false
			},
			time: {
				type: 'number',
				defaultValue: 0
			},
			distortion: {
				type: 'number',
				defaultValue: 0.1,
				min: 0,
				max: 1
			},
			verticalSync: {
				type: 'number',
				defaultValue: 0.1,
				min: 0,
				max: 1
			},
			lineSync: {
				type: 'number',
				uniform: 'lineSync',
				defaultValue: 0.2,
				min: 0,
				max: 1
			},
			scanlines: {
				type: 'number',
				uniform: 'scanlines',
				defaultValue: 0.3,
				min: 0,
				max: 1
			},
			bars: {
				type: 'number',
				uniform: 'bars',
				defaultValue: 0,
				min: 0,
				max: 1
			},
			frameShape: {
				type: 'number',
				uniform: 'frameShape',
				min: 0,
				max: 2,
				defaultValue: 0.27
			},
			frameLimit: {
				type: 'number',
				uniform: 'frameLimit',
				min: -1,
				max: 1,
				defaultValue: 0.34
			},
			frameSharpness: {
				type: 'number',
				uniform: 'frameSharpness',
				min: 0,
				max: 40,
				defaultValue: 8.4
			},
			frameColor: {
				type: 'color',
				uniform: 'frameColor',
				defaultValue: [0, 0, 0, 1]
			}
		},
		title: 'TV Glitch'
	});
}));


text:
$packageName = 'esedatabaseview'
$url = 'http://www.nirsoft.net/utils/esedatabaseview.zip'
$checksum = '86d3bbea7a279ac2f4068128bd96e5352c076f91'
$checksumType = 'sha1'
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
$installFile = Join-Path $toolsDir "$($packageName).exe"

Install-ChocolateyZipPackage -PackageName "$packageName" `
                             -Url "$url" `
                             -UnzipLocation "$toolsDir" `
                             -Url64bit "" `
                             -Checksum "$checksum" `
                             -ChecksumType "$checksumType"

Set-Content -Path ("$installFile.gui") `
            -Value $null

redpajama_set_name: RedPajamaGithub


text:
RSpec.describe TTY::Prompt::ConverterRegistry do
  context "contain" do
    it "doesn't have conversion" do
      registry = described_class.new
      expect(registry.contain?(:unknown)).to eq(false)
    end

    it "contains conversion" do
      registry = described_class.new(foo: ->(val) { val })
      expect(registry.contain?(:foo)).to eq(true)
    end

    it "checks conversion with object type" do
      registry = described_class.new(integer: ->(val) { val })
      expect(registry.contain?(Integer)).to eq(true)
    end
  end

  context "register" do
    it "registers new conversion under single name" do
      registry = described_class.new

      registry.register(:foo) { |val| val }

      expect(registry.contain?(:foo)).to eq(true)
    end

    it "registers new conversion under multiple names" do
      registry = described_class.new

      registry.register(:foo, :fum) { |val| val }

      expect(registry.contain?(:foo)).to eq(true)
      expect(registry.contain?(:fum)).to eq(true)
    end

    it "fails to register conversion" do
      registry = described_class.new(foo: ->(val) { val })

      expect {
        registry.register(:foo) { "value2" }
      }.to raise_error(TTY::Prompt::ConversionAlreadyDefined,
                       "converter for :foo is already registered")
    end
  end

  context "fetch" do
    it "retrieves converter from the registry" do
      conversion = ->(val) { val }
      registry = described_class.new(foo: conversion)

      expect(registry[:foo]).to eq(conversion)
      expect(registry.fetch(:foo)).to eq(conversion)
    end

    it "retrieves uppcase named converter" do
      conversion = ->(val) { val }
      registry = described_class.new(foo: conversion)

      expect(registry["FOO"]).to eq(conversion)
    end

    it "fails to retrieve conversion" do
      registry = described_class.new

      expect {
        registry[:foo]
      }.to raise_error(TTY::Prompt::UnsupportedConversion,
                       "converter :foo is not registered")
    end
  end
end


text:
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using Microsoft.Spark.CSharp.Core;
using Microsoft.Spark.CSharp.Services;
using Microsoft.Spark.CSharp.Sql;
using System.IO;

namespace Microsoft.Spark.CSharp.Examples
{
    /// <summary>
    /// This example shows how to use Hive in SparkCLR's C# API for Apache Spark DataFrame to
    /// load data from Hive.
    /// </summary>
    class HiveDataFrameExample
    {
        static void Main(string[] args)
        {
            LoggerServiceFactory.SetLoggerService(Log4NetLoggerService.Instance); //this is optional - DefaultLoggerService will be used if not set
            var logger = LoggerServiceFactory.GetLogger(typeof(HiveDataFrameExample));

            var sparkConf = new SparkConf();
            var sparkContext = new SparkContext(sparkConf);
            var hiveContext = new HiveContext(sparkContext);
            var peopleDataFrame = hiveContext.Read().Json(Path.Combine(Environment.CurrentDirectory, @"data\people.json"));

            const string dbName = "SampleHiveDataBaseForMobius";
            const string tableName = "people";

            hiveContext.Sql(string.Format("CREATE DATABASE IF NOT EXISTS {0}", dbName)); // create database if not exists
            hiveContext.Sql(string.Format("USE {0}", dbName));
            hiveContext.Sql(string.Format("DROP TABLE {0}", tableName)); // drop table if exists

            peopleDataFrame.Write().Mode(SaveMode.Overwrite).SaveAsTable(tableName); // create table
            var tablesDataFrame = hiveContext.Tables(dbName); // get all tables in database
            logger.LogInfo(string.Format("table count in database {0}: {1}", dbName, tablesDataFrame.Count()));
            tablesDataFrame.Show();

            hiveContext.Sql(string.Format("SELECT * FROM {0}", tableName)).Show(); // select from table
        }
    }
}


text:
package com.vmware.vim25;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

/**
 *
Java class for UpdateVirtualMachineFilesResultFailedVmFileInfo complex type.
 *
 *
The following schema fragment specifies the expected content contained within this class.
 *
 *

 * <complexType name="UpdateVirtualMachineFilesResultFailedVmFileInfo">
 *   <complexContent>
 *     <extension base="{urn:vim25}DynamicData">
 *       <sequence>
 *         <element name="vmFile" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *         <element name="fault" type="{urn:vim25}LocalizedMethodFault"/>
 *       </sequence>
 *     </extension>
 *   </complexContent>
 * </complexType>
 *

 *
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "UpdateVirtualMachineFilesResultFailedVmFileInfo", propOrder = {
    "vmFile",
    "fault"
})
public class UpdateVirtualMachineFilesResultFailedVmFileInfo
    extends DynamicData
{

    @XmlElement(required = true)
    protected String vmFile;
    @XmlElement(required = true)
    protected LocalizedMethodFault fault;

    /**
     * Gets the value of the vmFile property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getVmFile() {
        return vmFile;
    }

    /**
     * Sets the value of the vmFile property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setVmFile(String value) {
        this.vmFile = value;
    }

    /**
     * Gets the value of the fault property.
     *
     * @return
     *     possible object is
     *     {@link LocalizedMethodFault }
     *
     */
    public LocalizedMethodFault getFault() {
        return fault;
    }

    /**
     * Sets the value of the fault property.
     *
     * @param value
     *     allowed object is
     *     {@link LocalizedMethodFault }
     *
     */
    public void setFault(LocalizedMethodFault value) {
        this.fault = value;
    }

}


text:
layout: post
title: "Weekly meeting #96"
description: "Weekly meeting #96"
date: 2018-10-29 07:30:000
tags: [.Net Core 2, Pdf, MoreLinq, async]
---

## Reading

* [.Net Core 2: Managing Secrets in Web Apps](https://social.technet.microsoft.com/wiki/contents/articles/51871.net-core-2-managing-secrets-in-web-apps.aspx)
* [CREATING PDF FILES IN ASP.NET CORE](https://damienbod.com/2018/09/30/creating-pdf-files-in-asp-net-core/) by Damien Bod
* [Exploring MoreLINQ Part 23 - Joining](https://markheath.net/post/exploring-morelinq-23-joining) by Mark Heath
* [I didn't understand why people struggled with (.NET's) async](https://www.productiverage.com/i-didnt-understand-why-people-struggled-with-nets-async) by Dan


text:
package org.mozartoz.truffle.nodes.builtins;

import static org.mozartoz.truffle.nodes.builtins.Builtin.ALL;

import org.mozartoz.truffle.nodes.OzNode;
import org.mozartoz.truffle.runtime.OzName;

import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;

public abstract class LiteralBuiltins {

	@Builtin(name = "is", deref = ALL)
	@GenerateNodeFactory
	@NodeChild("value")
	public static abstract class IsLiteralNode extends OzNode {

		@Specialization
		boolean isLiteral(String atom) {
			return true;
		}

		@Specialization
		boolean isLiteral(OzName name) {
			return true;
		}

		@Specialization(guards = "!isLiteral(value)")
		boolean isLiteral(Object value) {
			return false;
		}

	}

}


text:
namespace Engine
{
    using Engine.Interfaces;

    public abstract class LivingCreature : ILiving
    {
        //Properties
        public int CurrentHitPoints { get; set; }

        public int MaximumHitPoints { get; set; }

        //Constructor
        public LivingCreature(int currentHitPoints, int maximumHitPoints)
        {
            this.CurrentHitPoints = currentHitPoints;
            this.MaximumHitPoints = maximumHitPoints;
        }
    }
}


text:
namespace P4Tools {

namespace P4Testgen {

namespace EBPF {

const big_int EBPFTestBackend::ZERO_PKT_VAL = 0x2000000;
const big_int EBPFTestBackend::ZERO_PKT_MAX = 0xffffffff;
const std::vector<std::string> EBPFTestBackend::SUPPORTED_BACKENDS = {"STF"};

EBPFTestBackend::EBPFTestBackend(const ProgramInfo& programInfo, ExplorationStrategy& symbex,
                                 const boost::filesystem::path& testPath,
                                 boost::optional<uint32_t> seed)
    : TestBackEnd(programInfo, symbex) {
    cstring testBackendString = TestgenOptions::get().testBackend;
    if (testBackendString == "STF") {
        testWriter = new STF(testPath.c_str(), seed);
    } else {
        std::stringstream supportedBackendString;
        bool isFirst = true;
        for (const auto& backend : SUPPORTED_BACKENDS) {
            if (!isFirst) {
                supportedBackendString << ", ";
            } else {
                isFirst = false;
            }
            supportedBackendString << backend;
        }
        P4C_UNIMPLEMENTED(
            "Test back end %1% not implemented for this target. Supported back ends are %2%.",
            testBackendString, supportedBackendString.str());
    }
}

TestBackEnd::TestInfo EBPFTestBackend::produceTestInfo(
    const ExecutionState* executionState, const Model* completedModel,
    const IR::Expression* outputPacketExpr, const IR::Expression* outputPortExpr,
    const std::vector<gsl::not_null<const TraceEvent*>>* programTraces) {
    auto testInfo = TestBackEnd::produceTestInfo(executionState, completedModel, outputPacketExpr,
                                                 outputPortExpr, programTraces);
    // This is a hack to deal with an virtual kernel interface quirk.
    // Packets that are too small are truncated to 02000000 (in hex) with width 32 bit.
    if (testInfo.outputPacket->type->width_bits() == 0) {
        int outPktSize = ZERO_PKT_WIDTH;
        testInfo.outputPacket =
            IR::getConstant(IR::getBitType(outPktSize), EBPFTestBackend::ZERO_PKT_VAL);
        testInfo.packetTaintMask =
            IR::getConstant(IR::getBitType(outPktSize), EBPFTestBackend::ZERO_PKT_MAX);
    }
    // eBPF actually can not modify the input packet. It can only filter. Thus we reuse our input
    // packet here.
    testInfo.outputPacket = testInfo.inputPacket;
    testInfo.packetTaintMask =
        IR::getConstant(testInfo.inputPacket->type, IR::getMaxBvVal(testInfo.inputPacket->type));
    return testInfo;
}

const TestSpec* EBPFTestBackend::createTestSpec(const ExecutionState* executionState,
                                                const Model* completedModel,
                                                const TestInfo& testInfo) {
    // Create a testSpec.
    TestSpec* testSpec = nullptr;

    const auto* ingressPayload = testInfo.inputPacket;
    const auto* ingressPayloadMask = IR::getConstant(IR::getBitType(1), 1);
    const auto ingressPacket = Packet(testInfo.inputPort, ingressPayload, ingressPayloadMask);

    boost::optional<Packet> egressPacket = boost::none;
    if (!testInfo.packetIsDropped) {
        egressPacket = Packet(testInfo.outputPort, testInfo.outputPacket, testInfo.packetTaintMask);
    }
    testSpec = new TestSpec(ingressPacket, egressPacket, testInfo.programTraces);
    // We retrieve the individual table configurations from the execution state.
    const auto uninterpretedTableConfigs = executionState->getTestObjectCategory("tableconfigs");
    // Since these configurations are uninterpreted we need to convert them. We launch a
    // helper function to solve the variables involved in each table configuration.
    for (const auto& tablePair : uninterpretedTableConfigs) {
        const auto tableName = tablePair.first;
        const auto* uninterpretedTableConfig = tablePair.second->checkedTo<TableConfig>();
        const auto* const tableConfig = uninterpretedTableConfig->evaluate(*completedModel);
        testSpec->addTestObject("tables", tableName, tableConfig);
    }
    return testSpec;
}

}  // namespace EBPF

}  // namespace P4Testgen

}  // namespace P4Tools


text:
package com.datastax.oss.protocol.internal.request;

import static com.datastax.oss.protocol.internal.Assertions.assertThat;

import com.datastax.oss.protocol.internal.*;
import com.datastax.oss.protocol.internal.binary.MockBinaryString;
import com.datastax.oss.protocol.internal.request.query.QueryOptions;
import com.datastax.oss.protocol.internal.request.query.QueryOptionsBuilder;
import com.datastax.oss.protocol.internal.util.Bytes;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(DataProviderRunner.class)
public class ExecuteTest extends MessageTestBase<Execute> {

  private byte[] queryId = Bytes.getArray(Bytes.fromHexString("0xcafebabe"));
  private byte[] resultMetadataId = Bytes.getArray(Bytes.fromHexString("0xdeadbeef"));

  public ExecuteTest() {
    super(Execute.class);
  }

  @Override
  protected Message.Codec newCodec(int protocolVersion) {
    return new Execute.Codec(protocolVersion);
  }

  @Test
  @UseDataProvider(location = TestDataProviders.class, value = "protocolV3OrV4")
  public void should_encode_and_decode_with_default_options_v3_v4(int protocolVersion) {
    Execute initial = new Execute(queryId, QueryOptions.DEFAULT);

    MockBinaryString encoded = encode(initial, protocolVersion);

    assertThat(encoded)
        .isEqualTo(
            new MockBinaryString()
                .shortBytes("0xcafebabe")
                .unsignedShort(ProtocolConstants.ConsistencyLevel.ONE)
                .byte_(0) // no flags
            );
    assertThat(encodedSize(initial, protocolVersion))
        .isEqualTo(
            (PrimitiveSizes.SHORT + queryId.length) + PrimitiveSizes.SHORT + PrimitiveSizes.BYTE);

    Execute decoded = decode(encoded, protocolVersion);

    assertThat(decoded.queryId).isEqualTo(initial.queryId);
    assertThat(decoded.options.consistency).isEqualTo(ProtocolConstants.ConsistencyLevel.ONE);
    assertThat(decoded.options.positionalValues).isEmpty();
    assertThat(decoded.options.namedValues).isEmpty();
    assertThat(decoded.options.skipMetadata).isFalse();
    assertThat(decoded.options.pageSize).isEqualTo(-1);
    assertThat(decoded.options.pagingState).isNull();
    assertThat(decoded.options.serialConsistency)
        .isEqualTo(ProtocolConstants.ConsistencyLevel.SERIAL);
    assertThat(decoded.options.defaultTimestamp).isEqualTo(Long.MIN_VALUE);
  }

  @Test
  @UseDataProvider(location = TestDataProviders.class, value = "protocolV5OrAbove")
  public void should_encode_and_decode_with_default_options(int protocolVersion) {
    Execute initial = new Execute(queryId, resultMetadataId, QueryOptions.DEFAULT);

    MockBinaryString encoded = encode(initial, protocolVersion);

    assertThat(encoded)
        .isEqualTo(
            new MockBinaryString()
                .shortBytes("0xcafebabe")
                .shortBytes("0xdeadbeef")
                .unsignedShort(ProtocolConstants.ConsistencyLevel.ONE)
                .int_(0) // no flags
            );
    assertThat(encodedSize(initial, protocolVersion))
        .isEqualTo(
            (PrimitiveSizes.SHORT + queryId.length)
                + (PrimitiveSizes.SHORT + resultMetadataId.length)
                + PrimitiveSizes.SHORT
                + PrimitiveSizes.INT);

    Execute decoded = decode(encoded, protocolVersion);

    assertThat(decoded.queryId).isEqualTo(initial.queryId);
    assertThat(decoded.resultMetadataId).isEqualTo(initial.resultMetadataId);
    assertThat(decoded.options.consistency).isEqualTo(ProtocolConstants.ConsistencyLevel.ONE);
    assertThat(decoded.options.positionalValues).isEmpty();
    assertThat(decoded.options.namedValues).isEmpty();
    assertThat(decoded.options.skipMetadata).isFalse();
    assertThat(decoded.options.pageSize).isEqualTo(-1);
    assertThat(decoded.options.pagingState).isNull();
    assertThat(decoded.options.serialConsistency)
        .isEqualTo(ProtocolConstants.ConsistencyLevel.SERIAL);
    assertThat(decoded.options.defaultTimestamp).isEqualTo(Long.MIN_VALUE);
  }

  @Test
  @UseDataProvider(location = TestDataProviders.class, value = "protocolV5OrAbove")
  public void should_encode_and_decode_with_now_in_seconds(int protocolVersion) {
    int nowInSeconds = 123456789;
    QueryOptions options = new QueryOptionsBuilder().withNowInSeconds(nowInSeconds).build();
    Execute initial = new Execute(queryId, resultMetadataId, options);

    MockBinaryString encoded = encode(initial, protocolVersion);

    assertThat(encoded)
        .isEqualTo(
            new MockBinaryString()
                .shortBytes("0xcafebabe")
                .shortBytes("0xdeadbeef")
                .unsignedShort(ProtocolConstants.ConsistencyLevel.ONE)
                .int_(0x100) // NOW_IN_SECONDS
                .int_(nowInSeconds));
    assertThat(encodedSize(initial, protocolVersion))
        .isEqualTo(
            (PrimitiveSizes.SHORT + queryId.length)
                + (PrimitiveSizes.SHORT + resultMetadataId.length)
                + PrimitiveSizes.SHORT
                + PrimitiveSizes.INT
                + PrimitiveSizes.INT);

    Execute decoded = decode(encoded, protocolVersion);

    assertThat(decoded.options.nowInSeconds).isEqualTo(nowInSeconds);
  }
}


text:
import Hapi from 'hapi'
import test from 'tape'
import RedisEngine from 'catbox-redis'

import authPlugin from './index'
import dbPlugin from '../../db'
import hasherPlugin from '../../hasher'

test('[End to End] auth endpoints', (t) => {
  const server = new Hapi.Server({
    cache: {
      name: 'redis',
      engine: RedisEngine,
      host: process.env.REDIS_HOST,
      port: process.env.REDIS_PORT,
      partition: process.env.REDIS_PARTITION,
    },
  })

  server.connection({
    host: 'localhost',
    port: 80,
    labels: ['api'],
  })

  const dbConfig = {
    host: process.env.MYSQL_HOST,
    database: process.env.MYSQL_DATABASE,
    username: process.env.MYSQL_USERNAME,
  }

  server.app.secret = process.env.SECRET

  /* eslint-disable global-require */
  server.register([
    { register: require('hapi-auth-basic') },
    { register: require('hapi-auth-jwt2') },
    { register: hasherPlugin },
    { register: dbPlugin, options: dbConfig },
    { register: authPlugin, options: { prefix: '/api' } },
  ], (err) => {
    if (err) {
      console.log(err)
      t.fail('failed to load metrics plugin for end to end tests')
    }

    t.test('GET /api/authenticate', (t) => {
      t.plan(1)

      const data = {
        email: 'test@test.com',
        password: 'test',
      }

      server.inject({
        url: '/api/authenticate',
        payload: data,
        method: 'POST',
      }, (response) => {
        t.equal(response.result.success, true, 'authentication method working as expected')
      })
    })
  })
})


text:
{extend name="default/template/base_index" /}

{block name="area_header"}

{/block}

{block name="area_body"}
	{include file="default/Widget/topbar" /}

{/block}

{block name="area_footer"}

{/block}


text:
/**
 * TBusiCodeFeeDao.java	2010/02/25
 */

package com.ycsoft.business.dao.config;

import org.springframework.stereotype.Component;

import com.ycsoft.beans.config.TBusiCodeFee;
import com.ycsoft.daos.abstracts.BaseEntityDao;
import com.ycsoft.daos.core.JDBCException;

/**
 * TBusiCodeFeeDao -> T_BUSI_CODE_FEE table's operator
 */
@Component
public class TBusiCodeFeeDao extends BaseEntityDao<TBusiCodeFee> {

	/**
	 *
	 */
	private static final long serialVersionUID = -3858321005763850249L;

	/**
	 * default empty constructor
	 */
	public TBusiCodeFeeDao() {
	}

	/**
	 * 根据费用id删除记录
	 * @param feeId
	 * @throws Exception
	 */
	public void deleteByFeeId(String feeId) throws Exception {
		String sql = "delete from t_busi_code_fee t where t.fee_id=?";
		executeUpdate(sql, feeId);
	}

	/**
	 * 根据模板ID删除记录
	 *
	 * @param templateId
	 * @throws JDBCException
	 */
	public void deleteByTplId(String templateId) throws JDBCException {
		String sql = "delete from t_busi_code_fee t where t.template_id=?";
		executeUpdate(sql, templateId);
	}

	/**
	 * @Description:判断模板业务费用规则是否已经存在
	 * @param template_id
	 * @param busi_code
	 * @param fee_id
	 * @param value_id
	 * @return
	 * @throws Exception
	 * @return Object
	 */
	public Object isupdate(String template_id, String busi_code, String fee_id,
			String value_id) throws JDBCException {
		String sql = "  select * from t_busi_code_fee where  template_id = ? and busi_code = ? and fee_id = ? and value_id = ?  ";
		Object request = findUnique(sql, template_id, busi_code, fee_id,
				value_id) == null ? false : true;
		if (request.equals(true)) {
			request = "该模板业务费用组合已经存在";
		}
		return request;
	}

	public void updateTemplateBusi(String template_id, String busi_code,
			String fee_id, String value_id, String template_id_back,
			String busi_code_back, String fee_id_back, String value_id_back)
			throws JDBCException {
		String sql = " UPDATE t_busi_code_fee  SET   template_id = ? ,busi_code= ? , fee_id = ?,value_id = ?  WHERE template_id = ? and busi_code= ? and fee_id = ?  and value_id = ?    ";
		executeUpdate(sql, template_id, busi_code, fee_id, value_id,
				template_id_back, busi_code_back, fee_id_back, value_id_back);
	}

	public void logoffTF(String template_id, String busi_code, String fee_id,
			String value_id) throws JDBCException {
		String sql = " DELETE t_busi_code_fee   WHERE   template_id = ?  and busi_code = ? and fee_id = ? and value_id = ? ";
		executeUpdate(sql, template_id, busi_code, fee_id, value_id);
	}

}


text:
//
//  DrawerView.m
//  stretchProblems
//
//  Created by Taylor Mott on 25 Mar 15.
//  Copyright (c) 2015 Taylor Mott. All rights reserved.
//

#import "DrawerView.h"

@implementation DrawerView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self)
    {
        self.dismissButton = [UIButton new];
        [self.dismissButton setTitle:@"Dismiss" forState:UIControlStateNormal];
        [self.dismissButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [self.dismissButton addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:self.dismissButton];
        [self.dismissButton sizeToFit];
        self.dismissButton.center = self.center;
//        NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:dismissButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0];
//        [self addConstraint:constraint];
//        constraint = [NSLayoutConstraint constraintWithItem:dismissButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0];
//        [self addConstraint:constraint];
//        constraint = [NSLayoutConstraint constraintWithItem:dismissButton attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0];
//        [self addConstraint:constraint];
    }

    return self;
}

-(void)buttonAction
{
    [self.delegate dismissButtonWasTapped];
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end


text:
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// 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.

/*!
 * @file Property.h
 */
#ifndef _RTPS_COMMON_PROPERTYQOS_H_
#define  _RTPS_COMMON_PROPERTYQOS_H_

#include <fastdds/rtps/common/Property.h>

#endif // _RTPS_COMMON_PROPERTYQOS_H_


text:
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.bazaarvoice.auth</groupId>
        <artifactId>jersey-hmac-auth</artifactId>
        <version>0.18-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>jersey-hmac-auth-common</artifactId>
    <packaging>jar</packaging>

    <description>Common code for the Client and Server modules</description>

    <dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>

        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>


text:
avr-cpp-lib
===========

avr-cpp-lib is a library containing a few C++ classes,
to make your avr programming easier.

Main codebase is located on github: https://github.com/matematik7/avr-cpp-lib

Documentation can be generated from source using doxygen.

Copyright (c) 2012-2016 Domen Ipavec (domen@ipavec.net)

See the file license.txt for copying permission.


text:
namespace Trinity {
        using exec_term_id_t = uint16_t;

        // a materialized document term hit
        struct term_hit final {
                uint64_t   payload;
                tokenpos_t pos;
                uint8_t    payloadLen;

                inline auto bytes() const noexcept {
                        return reinterpret_cast<const uint8_t *>(&payload);
                }

                inline auto bytes() noexcept {
                        return reinterpret_cast<uint8_t *>(&payload);
                }
        };
} // namespace Trinity


text:
namespace proximity_auth {

ProximityAuthPrefManager::ProximityAuthPrefManager(PrefService* pref_service)
    : pref_service_(pref_service) {}

ProximityAuthPrefManager::~ProximityAuthPrefManager() {}

// static
void ProximityAuthPrefManager::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterDictionaryPref(prefs::kProximityAuthRemoteBleDevices);
}

bool ProximityAuthPrefManager::HasDeviceWithAddress(
    const std::string& bluetooth_address) const {
  return pref_service_->GetDictionary(prefs::kProximityAuthRemoteBleDevices)
      ->HasKey(bluetooth_address);
}

bool ProximityAuthPrefManager::HasDeviceWithPublicKey(
    const std::string& public_key) const {
  return !GetDeviceAddress(public_key).empty();
}

std::string ProximityAuthPrefManager::GetDevicePublicKey(
    const std::string& bluetooth_address) const {
  std::string public_key;
  GetRemoteBleDevices()->GetStringWithoutPathExpansion(bluetooth_address,
                                                       &public_key);
  return public_key;
}

std::string ProximityAuthPrefManager::GetDeviceAddress(
    const std::string& public_key) const {
  const base::DictionaryValue* remote_ble_devices = GetRemoteBleDevices();
  for (base::DictionaryValue::Iterator it(*remote_ble_devices); !it.IsAtEnd();
       it.Advance()) {
    std::string value_string;
    DCHECK(it.value().IsType(base::Value::TYPE_STRING));
    if (it.value().GetAsString(&value_string) && value_string == public_key)
      return it.key();
  }
  return std::string();
}

std::vector<std::string> ProximityAuthPrefManager::GetPublicKeys() const {
  std::vector<std::string> public_keys;
  const base::DictionaryValue* remote_ble_devices = GetRemoteBleDevices();
  for (base::DictionaryValue::Iterator it(*remote_ble_devices); !it.IsAtEnd();
       it.Advance()) {
    std::string value_string;
    DCHECK(it.value().IsType(base::Value::TYPE_STRING));
    it.value().GetAsString(&value_string);
    public_keys.push_back(value_string);
  }
  return public_keys;
}

void ProximityAuthPrefManager::AddOrUpdateDevice(
    const std::string& bluetooth_address,
    const std::string& public_key) {
  PA_LOG(INFO) << "Adding " << public_key << " , " << bluetooth_address
               << " pair.";
  if (HasDeviceWithPublicKey(public_key) &&
      GetDeviceAddress(public_key) != bluetooth_address) {
    PA_LOG(WARNING) << "Two devices with different bluetooth address, but the "
                       "same public key were added: "
                    << public_key;
    RemoveDeviceWithPublicKey(public_key);
  }

  DictionaryPrefUpdate remote_ble_devices_update(
      pref_service_, prefs::kProximityAuthRemoteBleDevices);
  remote_ble_devices_update->SetStringWithoutPathExpansion(bluetooth_address,
                                                           public_key);
}

bool ProximityAuthPrefManager::RemoveDeviceWithAddress(
    const std::string& bluetooth_address) {
  DictionaryPrefUpdate remote_ble_devices_update(
      pref_service_, prefs::kProximityAuthRemoteBleDevices);
  return remote_ble_devices_update->RemoveWithoutPathExpansion(
      bluetooth_address, nullptr);
}

bool ProximityAuthPrefManager::RemoveDeviceWithPublicKey(
    const std::string& public_key) {
  return RemoveDeviceWithAddress(GetDeviceAddress(public_key));
}

const base::DictionaryValue* ProximityAuthPrefManager::GetRemoteBleDevices()
    const {
  return pref_service_->GetDictionary(prefs::kProximityAuthRemoteBleDevices);
}

}  // namespace proximity_auth


text:
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.GraphModel;
using Microsoft.VisualStudio.GraphModel.Schemas;
using Microsoft.VisualStudio.Progression;

namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression
{
    internal sealed class ImplementsGraphQuery : IGraphQuery
    {
        public async Task<GraphBuilder> GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken)
        {
            var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false);

            foreach (var node in context.InputNodes)
            {
                var symbol = graphBuilder.GetSymbol(node);
                if (symbol is INamedTypeSymbol namedType)
                {
                    var implementedSymbols = namedType.AllInterfaces;

                    await AddImplementedSymbols(graphBuilder, node, implementedSymbols).ConfigureAwait(false);
                }
                else if (symbol is IMethodSymbol || symbol is IPropertySymbol || symbol is IEventSymbol)
                {
                    var implements = await SymbolFinder.FindImplementedInterfaceMembersAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false);
                    await AddImplementedSymbols(graphBuilder, node, implements).ConfigureAwait(false);
                }
            }

            return graphBuilder;
        }

        private static async Task AddImplementedSymbols(GraphBuilder graphBuilder, GraphNode node, IEnumerable<ISymbol> implementedSymbols)
        {
            foreach (var interfaceType in implementedSymbols)
            {
                var interfaceTypeNode = await graphBuilder.AddNodeForSymbolAsync(interfaceType, relatedNode: node).ConfigureAwait(false);
                graphBuilder.AddLink(node, CodeLinkCategories.Implements, interfaceTypeNode);
            }
        }
    }
}


text:
/*
  Calparse.js
  by Daniel Ma (danielghma@gmail.com)

  Written for the digital signage system at YWAM Kona
  4th qtr 2011
*/

/*jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, curly:true, browser:true, jquery:true, maxerr:50 */
/*global google*/

/*
  Title: Calparse.js
  One file with all the classes, objects, and functions to run the DigitalSignage app (or http://gniux.uofnkona.edu/)

  About: Format Strings

  Description:
  Understanding how format strings work in Calparse.js is required to properly configure the DigitalSignage app

.

  The syntax of the special format strings used here allows for custom formatting of dates, titles, and descriptions

.

  Format strings consist of formatters in the form t(), d(), etc and sometimes with a format string inside the parentheses. Formatting within parentheses is processed using the DateJS <toString at http://code.google.com/p/datejs/wiki/FormatSpecifiers> method

  (start code)
  Format      Description
  ----------- -------------------------
  s(format)   The start time formatted
  e(format)   The end time formatted
  t()         The title
  d()         The description

  \n          Newline
  |           For use in tables, divides  cells
  (end)

  Examples:
  > "s(dddd, MMMM d at h:mm tt)"            -> "Monday, December 1 at 7:00 PM"
  > "s(dddd, MMMM d h:mm tt) - e(h:mm tt)"  -> "Monday, December 1 7:00 PM - 9:00 PM"
  > "t()|-|d()"                             -> "Event Title	-	A Really cool event!	"
  > "s(h:mm) - e(h:mm tt)|-|t()"            -> "7:00 - 9:00 PM	-	Event Title	"

  See Also:
  <DateJS Format Strings at http://code.google.com/p/datejs/wiki/FormatSpecifiers>
*/

/*
  Object: tickers
  A global object containing all the tickers being used on the page. Key is the element, value is the object
*/

var tickers = {};

/*
  Function: appendScript
  Appends a javascript file to the  tag

  Parameters:

    url {String} - the url of the script to append (absolute or relative to index.html)
*/
function appendScript(url) {
  "use strict";
	var scriptTag = document.createElement("script");
	scriptTag.setAttribute("type", "text/javascript");
	scriptTag.setAttribute("src", url);
	document.getElementsByTagName("head")[0].appendChild(scriptTag);
}

/*
  Function: String.prototype.capitalize
  Capitalizes a string

  Usage:

  >  "tomorrow".capitalize -> "Tomorrow"
*/
String.prototype.capitalize = function () {
  "use strict";
  return this.replace(/(^|\s)([a-z])/g, function (m, p1, p2) {
    return p1 + p2.toUpperCase();
  });
};

/*
  Function: String.prototype.repeat
  Repeats a string

  Parameters:

    num {Integer} - the number of times to repeat the string

  Usage:

  >  "1".repeat(2) -> "11"
*/
String.prototype.repeat = function (num) {
  "use strict";
  return [num + 1].join(this);
};

/*
  Function: by_mealtime
  Sorting function to sort <Event>s by breakfast, lunch, dinner

  Usage:

  > events.sort(by_mealtime);
*/
var by_mealtime = function (a, b) { // array sorter
  // console.log("a: " + a.title + " b: " + b.title);
  "use strict";
  var vals = [a, b];
  for (var i = 0; i < vals.length; i ++) {
    switch (vals[i].title.toLowerCase()) {
    case "breakfast":
      vals[i] = 0;
      break;
    case "lunch":
      vals[i] = 1;
      break;
    case "dinner":
      vals[i] = 2;
      break;
    default:
      // nil
    }
  }
  // console.log(vals);

  return vals[0] - vals[1];
};

/*
  Function: by_time
  Sorting function to sort <Event>s by start time

  Usage:

  > events.sort(by_time);
*/
var by_time = function (a, b) { // array sorter
  // console.log("a: " + a.title + " b: " + b.title);
  "use strict";
  return a.start_time - b.start_time;
};

/*
  Class: Event
  A simple class that unifies the events from different sources

  Properties:

    title {String}        - the event's title
    start_time {Date}     - the event's starting time
    end_time {Date}       - the event's end time
    location {String}     - the event's location
    description {String}  - the event's description

  Constructor:

    Initializes an event object with any properties passed

  Parameters:

    opts {Object} - an object with attributes

      - *title {String}* the event's title (*required*)
      - *start_time {Date}* the event's starting time (defaults to today at 00:00)
      - *end_time {Date}* the event's end time (defaults to today at 23:59)
      - *location {String}* the event's location (defaults to an empty string)
      - *description {String}* the event's description (defaults to an empty string)

  Returns:

    A new <Event>

  Usage:

    > event = new Event(object)

  Example:

    (start code)
      start_time = Date.today().set({year: 2055, month: 1, day: 1, hour: 6, minute: 15});

      event = new Event({
        title: "Breakfast",
        start_time: start_time,
        end_time: start_time.add({hour: 1}),
        location: "Cafeteria",
        description: "Pancackes"
      });
    (end)
*/

function Event(opts) {
  "use strict";
  if (typeof (opts) !== "undefined") {
    this.title        = opts.title;
    this.start_time   = opts.start_time || Date.today();
    this.end_time     = opts.end_time || Date.today().set({hour: 23, minute: 59, second: 59});
    this.location     = opts.location || "";
    this.description  = opts.description || "";
    this.attachment   = opts.attachment;
    this.all_day      = !!opts.all_day
  }
}

Event.fromGoogleEvent = function(event) {
  return new Event({
    title: event.summary,
    start_time: GCal.parse_google_date(event.start.dateTime || event.start.date),
    end_time: GCal.parse_google_date(event.end.dateTime || event.end.date),
    location: event.location,
    description: event.description,
    all_day: event.start.date
  })
}

/*
  Class: Ticker
  A class that contains data and manages rotation for an <Event> ticker

  Properties:

    element {jQuery}      - the parent object of the ticker
    items {Array}         - an array of html strings that define the content of the ticker
    speed {Integer}       - the rotation speed of the ticker in milliseconds
    running {Boolean}     - whether or not the ticker is currently running
    currentItem {Integer} - an that points to the current item in the items array

  Constructor:

  Initializes an instance of the ticker, calls <this.setSize>, starts the ticker if it is opts.running is true, and adds the instance to the global tickers variable

  Parameters:

    opts {Object} - an object with attributes

      - *element {String}* a jQuery selector for the ticker's parent element (*required*)
      - *items {Array}* an array of html items to go in the ticker (defaults to an empty Array)
      - *speed {Integer}* the speed of the ticker in milliseconds (defaults to 10000)
      - *running {Boolean}* whether or not the ticker should begin running immediately (defaults to false)

  Returns:

    A new <Ticker>

  Usage:

    > ticker = new Ticker(object)

  Example:

    A ticker with prepared content

    (start code)
      ticker = new Ticker({
        element: "#events .content",
        items: ["
Free Cookies
", "
Expensive Cookies
"],
        speed: 5000
      });
    (end)

    A ticker with generated html (this is how it's used in the code)

    (start code)
      var ticker = new Ticker({element: "#events .content"});

      for (var i = 0; i < events.length; i++) {
        var item = events[i];
        ticker.addItem(CalData.ticker_html(item, format, start_time, end_time));
      }
    (end)
*/
function Ticker(opts) {
  "use strict";

  /*

    Function: this.addItem
    Adds an item to the ticker. Used from within the <CalData> module to add generated <ticker_html> to a ticker

    Parameters:

      html {String} - a string of html content

    Example:

    > ticker.addItem("
Ticker item
")

  */
  this.addItem = function (html) {
    this.element.append(html);
    this.items.push(html);
    this.setSize();
    if (!this.running) {
      this.start();
    }
  };

  /*

    Function: this.start
    Starts the ticker (if it is not running already)

    Example:

    > ticker.start()

  */
  this.start = function () {
    // console.log("Starting the ticker")
    // console.log(this.element)
    // console.log(this.items)
    if (this.running) {
      clearInterval(this.interval);
    }
    // this.rotate();
    this.interval = setInterval(this.rotate, this.speed);
    this.running = true;
  };

  /*

    Function: this.stop
    Stops the ticker from rotating it's items

    Example:

    > ticker.stop()

  */
  this.stop = function () {
    clearInterval(this.interval);
    this.running = false;
  };

  /*

    Function: this.rotate
    Causes the ticker to rotate and display the next item

    Example:

    > ticker.rotate()

  */
  this.rotate = function () {
    // console.log("rotating");
    if (self.items.length > 1) {
      $(self.element.children()[self.currentItem]).fadeOut(function () {
        self.stepCurrentItem();

        $(self.element.children()[self.currentItem]).fadeIn();
      });
    } else {
      $(self.element.children()[0]).fadeIn();
      self.stop();
    }
  };

  /*

    Function: this.stepCurrentItem
    Increments the <Ticker>'s currentItem variable by 1

    Example:

    > ticker.stepCurrentItem()

  */
  this.stepCurrentItem = function () {
    this.currentItem += 1;

    if (this.currentItem > (this.items.length - 1)) {
      this.currentItem = 0;
    }
  };

  /*

    Function: this.setSize
    Causes the ticker to calculate and set the pixel height for itself and it's children

    Example:

    > ticker.setSize()

  */
  this.setSize = function () {
    var parentHeight = this.element.parent().outerHeight();
    // console.log("parentHeight = " + parentHeight)
    var siblingHeight = this.element.siblings().outerHeight();
    // console.log("siblingHeight = " + siblingHeight)
    var padding = this.element.outerHeight() - this.element.height();
    // console.log("padding = " + padding)
    this.tickerHeight = parentHeight - siblingHeight - padding;
    // console.log("this.tickerHeight = " + this.tickerHeight)

    // console.log(tickerHeight)

    // console.log(this.tickerHeight)
    // this.element //.css("height", "0px")
    //   .children().css("height", this.tickerHeight + "px")
    //   .find("img").css("height", this.tickerHeight - 20 + "px");

    this.element.find("img").css("height", this.tickerHeight + "px");
  };

  var self = this;

  if (typeof (opts) !== "undefined") {
    this.element      = $(opts.element);
    this.items        = opts.items || [];
    this.speed        = opts.speed || 10000;
    this.running      = opts.running || false;

    // just to define these. maybe javascript should use .h files :P
    this.currentItem  = 0;
    this.interval     = null;
    this.tickerHeight = 0;
  }

  this.setSize();
  if (this.running) {
    this.start();
  }
  if (typeof(tickers[opts.element]) !== "undefined") {
      tickers[opts.element].stop();
      delete(tickers[opts.element]);
  }
  tickers[opts.element] = this;
}

/*
  Struct: videoPlayer
  The videoPlayer object manages playing and rotating videos on the display

  All properties can be set by calling <playVideos> in layout.js

  Properties:

    - *list {Array}* an array of the video files with extensions (defaults to ['1.webm', '2.webm'])
    - *path {String}* the folder with trailing slash where the videos are stored (defaults to "videos/")
    - *fnQueue {Array}* an array of functions pending for execution

*/
var videoPlayer = {
  list: ['1.webm', '2.webm'], // '3', '4', '5', '6', '7', '8', '9', '10'],
  path: "videos/",
  currentVideo: 0,
  element: null,
  // refresh: false,
  fnQueue: [],

  /*

    Function: playVideos
    Sets properties for the videoPlayer and begins the play loop

    Parameters:

      opts {Object} - an object with the desired properties to overwrite

    Example:

    in layout.js

    > content: function() {videoPlayer.playVideos({path: "http://gniux.uofnkona.edu/videos/", list: ['1.m4v', '2.m4v', '3.m4v', '4.m4v']})}

  */
  playVideos: function (opts) {
    "use strict";
    if (typeof(opts) !== "undefined") {
      this.list = opts.list || this.list;
      this.path = opts.path || this.path;
    }
    $("#video .content").html("<video id='videoPlayer' src='" + this.path + this.list[0] + "' autoplay autobuffer />");

    var video = $("#video");
    var padding = video.children().outerHeight() - video.children().height();
    var maxHeight = video.outerHeight() - padding;
    this.element = $("#videoPlayer");
    this.element.css("max-height", maxHeight + "px").bind("ended", function () {
      videoPlayer.nextVideo();
    });
  },

  /*

    Function: nextVideo
    Executes any pending functions in the fnQueue and plays the next video

    Example:

    > videoPlayer.nextVideo()

  */
  nextVideo: function () {
    "use strict";
    if (this.fnQueue.length > 0) { // if it's time to reload the page
      for (var i=0; i < this.fnQueue.length; i++) {
        this.fnQueue.pop()(); // double () to execute functions in queue
      }
    }
    this.currentVideo += 1;
    if (this.currentVideo >= this.list.length) {
      this.currentVideo = 0;
    }
    this.element.attr("src", this.path + this.list[this.currentVideo]);
    this.element[0].play();
  },

  /*

    Function: queueFn
    Adds a function to the fnQueue to be executed after the current video is over

    Example:

      (start code)
        videoPlayer.queueFn(function() {
          layoutParser.loadData();
        })
      (end)

  */
  queueFn: function(callback) {
    "use strict";
    this.fnQueue.push(callback);
  },

  /*

    Function: queueRefresh
    Queues a reload of the page when the current video is over

    Example:

    > videoPlayer.queueRefresh()

  */
  queueRefresh: function() {
    "use strict";
    this.fnQueue.push(function() {location.reload(true);});
  }
};

/*

  Struct: layoutParser
  The layoutParser object contains methods for parsing layout.js and loading the data onto the screen

*/

var layoutParser = {
  output: "",
  // layoutFnQueue: [],
  layout: {},

  /*

    Function: parse
    Parses the layout variable defined in layout.js

    Executes <recursiveParse> on the layout array to insert all the html onto the screen, and executes <loadData> to fill the page with data

    Parameters:

      layout {Array} - the layout variable defined in layout.js

    Example:

    > layoutParser.parse(layout)

  */
  parse: function (layout) {
    "use strict";
    this.layout = layout;
    this.recursiveParse(layout, {id: layout[0].parent});

    $("div[data-height], div[data-width]").each(function(idx, el) {
      var element = $(el);
      var height  = element.attr("data-height");
      var width   = element.attr("data-width");
      var compute;

      if(typeof(height) !== "undefined") { // if there's data-height
        compute = (height/100 * (element.parent().height() - 1));
        element.height(compute + "px");
      } else {
        compute = (width/100 * (element.parent().width() - 1));
        element.width(compute + "px");
      }
    });

    // alert("are there stuff?")
    // $(".layout").layout();

    // $("#wrapper").append("<textarea cols=100 rows=100>" + this.output + "</textarea>")
    // $("#wrapper").css({width: "50%"}).layout({
    //   type: "flexgrid",
    //   hgap: 3,
    //   vgap: 3,
    //   rows: 1,
    //   columns: 2
    // }) //.children().layout();
    // for (var i = this.layoutFnQueue.length - 1; i >= 0; i--){
    //   $("#" + this.layoutFnQueue[i]).layout();
    // };
    // for (var i=0; i < this.layoutFnQueue.length; i++) {
    //   // eval(this.layoutFnQueue[i]);
    //   console.log("#" + this.layoutFnQueue[i] + ".layout()");
    //   $("#" + this.layoutFnQueue[i]).layout();
    // };
  },

  /*
    Function: queueReloadData
    Sets the timer interval to reload the data on the page

    Called from app.js to reload data every 15 minutes

    Parameters:

      time {Integer} - the interval in milliseconds

    Example:

    > videoPlayer.queueReloadData(15  * 60 * 100)

  */
  queueReloadData: function(time, exclude) {
    "use strict";
    setTimeout(function() {
      videoPlayer.queueFn(function() {layoutParser.loadData(layoutParser.layout, exclude);});
      // videoPlayer.queueFn(function() {Cocoa.log_("reload Data");});
    }, time);
    setTimeout(function() {
      layoutParser.queueReloadData(time);
    }, time);
  },

  /*
    Function: loadData
    A recursive function to load the data from the content functions in layout.js onto the page

    Parameters:

      obj {Object} - the object to load the data for (defaults to layoutParser.layout)
      exclude {String or Array} - either single string or Array of ids to exclude from reloading (ex. "video")

  */
  loadData: function (obj, exclude) {
    "use strict";
    if (typeof(obj) === "undefined") {
      obj = this.layout;
    }
    if (typeof(exclude) === "undefined") {
      exclude = [];
    } else if (typeof(exclude) === "string") {
      exclude = [exclude];
    }
    for (var i = 0; i < obj.length; i++) {
      var object = obj[i];
      if (typeof(object.content) === "function") {
        if ($.inArray(object.id, exclude) === -1) {
//          console.log(object.id + " loading data");
          object.content();
        }
      } else if (typeof(object.content) === "object") {
//        console.log(object.id + " is an object");
//        console.log(object.content);
        this.loadData(object.content, exclude);
      }
    } // for()

  },

  /*
    Function: recursiveParse
    A private recursive function that reads the layout and inserts html onto the page

    Parameters:

      obj {Object} - the object to parse
      parent {Object} - the object's parent object

  */
  recursiveParse: function (obj, parent) {
    "use strict";
    // var tab = "  ";

    // if (typeof(level) === "undefined") {
    //   level = 0;
    // }

    for (var i = 0; i < obj.length; i++) {
      var object = obj[i];
      // console.log(tab.repeat(level) + object.id)
      var beforeContent = "";
      var afterContent  = "";
      var output = "";

      // wType = typeof(parent);
      //
      // if (wType != "undefined") {
        // console.log(object.id + " has a parent!")

      var preWrap = "";
      var postWrap = "";
        // preWrap = "<" + tag + " id='" + object.id + "' " + wrapIn.sizeProp + "='" + object.size + "%'>";
      // if (typeof(object.content) === "object") {
      // var layout = {type:'grid', hgap: 3, vgap: 3};
      // layout[wrapIn.sizeProp] = 1

      preWrap = "
";
      postWrap = "
";
        // this.layoutFnQueue.push(object.id);
      // }
      beforeContent = preWrap + "\n" + beforeContent;
      // console.log(beforeContent)
      afterContent += postWrap + "\n";
        // console.log(afterContent)
      // }

      output += beforeContent;

      if (typeof(object.content) === "function") {
        // console.log(tab.repeat(level) + "recursiveParse-ing " + object.id);
        // console.log(wrapIn)
        // output += tab.repeat(level + 3) + "\n";
        // if (typeof(wrapIn) != "undefined") {
        //   this.layoutFnQueue.push('$("#' + object.id + '").layout({type: "grid", hgap: 3, vgap: 3, ' + wrapIn.sizeProp +': 1})');
        // }
        // output += tab.repeat(level + 3) + "\n";
        if (object.title) {
          output += "
" + object.title + "
";
        }
        output += "
" + object.id + "
\n";
      }

      output += afterContent;

      // console.log("#" + parent.id + ".append(#" + object.id + ")")
      // console.log(output)

      $(output).appendTo("#" + parent.id).css(object.css || {});

      var element = $("#" + object.id);
      if (typeof(object.content) === "object") {
        if (object.orient === "horizontal") {
          element.attr("data-height", object.size);
          // element.addClass("layout {layout: {type: 'flexGrid', resize: false, rows: 1, columns: " + object.content.length + "}}");
          // element.addClass("layout {layout: {type: 'flexGrid', resize: false, rows: 1}}");
          element.addClass("hbox");
        } else {
          element.attr("data-width", object.size);
          // element.addClass("layout {layout: {type: 'flexGrid', hgap: 3, columns: 1, rows: " + object.content.length + "}}");
          // element.addClass("layout {layout: {type: 'flexGrid', resize: false, hgap: 3, columns: 1}}");
          element.addClass("vbox");
        }
        this.recursiveParse(object.content, object);
      } else {
        if (parent.orient === "horizontal") {
          element.attr("data-width", object.size || 100 / parent.content.length);
        } else {
          element.attr("data-height", object.size || 100 / parent.content.length);
        }
      }

      // console.log(tab.repeat(level) + "made it to the end of " + object.id)
    } // for()
  }
};

/*
  Struct: imdbAPI
  The imdbAPI object contains methods to get extra data from imdb for the Mauka Theater movie
*/
var imdbAPI = {

  /*

    Function: get_movie
    Searches imdb for data about the movie, updates the object if it finds a match, and executes a callback function on it

    Parameters:

      ev {Event} - an <Event> to search
      callback {Function} - a callback to execute on the event

  */
  get_movie: function (ev, callback) {
    "use strict";
    $.ajax({
      url : "http://www.imdbapi.com/",
      data: {t: ev.title},
      dataType : "jsonp",
      timeout : 10000,
      success: function (data) {
        // console.log(data.Title.toLowerCase() + " === " + ev.title.toLowerCase())
        if (data.hasOwnProperty("Title") && data.Title.toLowerCase() === ev.title.toLowerCase()) {
          // console.log(title);
          ev.attachment = data.Poster;
          ev.title = data.Title;
          ev.description = data.Plot;

          callback(ev);
        } else {
          // console.log("no match");
          callback(ev);
        }
      },
      error: function () {
        callback(ev);
      }
    });

    // ev.attachment = "http://ia.media-imdb.com/images/M/MV5BMjEzNjg1NTg2NV5BMl5BanBnXkFtZTYwNjY3MzQ5._V1._SX320.jpg";
    // ev.description = "A computer hacker learns from mysterious rebels about the true nature of his reality and his role in the war against its controllers."
    // callback(ev);
  }
};

/*
  Struct: CalData
  The CalData object contains methods for outputting event data to html for presentation
*/

var CalData = {

  /*
    Function: write_table
    Writes event data into a table and inserts it onto the page

    Parameters:

      events {Array} - an array of events
      element {String} - a jQuery selector for the element that the table should be written into
      format {String} - a format string for how each event should be displayed

    Example:

    > CalData.write_table(event, "#events .content", "t()|-|d()")

    See Also:

      <Format Strings>
  */
  write_table: function (events, element, format) {
    "use strict";
    // Format:
    // Start Time: s(hh:mm:t)
    // End Time: e(hh:mm:t)
    // Column break: |

    var fmt = this.auto_format(format);

    format          = fmt[0];
    var startFormat = fmt[1];
    var endFormat   = fmt[2];

    var html = "No events"

    if (events.length > 0) {
      html = ["
",
              events.map(function(event) {
                return ["
",
                        CalData.timeString(event, format, startFormat, endFormat),
                        "
"].join('')
              }).join(''),
              "
"].join('')
    }

    $(element).html(html);
  },

  /*
    Function: ticker_html
    Generates html for a ticker item

    Parameters:

      item {Event} - an <Event> to generate html for
      format {String} - a format string for how to display the event data
      start_time {String} - a DateJS format string to display the start time
      end_time {String} - a DateJS format string to display the end time

    Returns:

      A string of html

    Example:

    > CalData.ticker_html(event, "s() - e()", "dddd, MMMM d\nh:mm tt", "h:mm tt")

    See Also:

      <Format Strings>

      <DateJS Format Strings at http://code.google.com/p/datejs/wiki/FormatSpecifiers>
  */
  ticker_html: function (item, format, start_time, end_time) {
    "use strict";
    var html = "";
    var timestr = this.timeString(item, format, start_time, end_time);
    html += "
";
    if (item.attachment) {
      html += "";
    }
    html += "
" + item.title + "
";
    html += "
" + timestr + "
";
    html += "
" + item.description + "
";
    html += "
";

    return html;
  },

  timeMatch: /hh?:mm?( tt)?/,

  timeString: function(item, format, startFormat, endFormat) {
    if (item.all_day) {
      startFormat = startFormat.replace(this.timeMatch, '')
      endFormat = endFormat.replace(this.timeMatch, '')
    }

    var formattedStartTime = startFormat ? item.start_time.toString(startFormat) : 'all day'
    var formattedEndTime = endFormat ? item.end_time.toString(endFormat) : ''

    return format
      .replace(/s\([^\)]*\)/gm, formattedStartTime)
      .replace(/e\([^\)]*\)/gm, formattedEndTime)
      .replace(/t\(\)/, item.title)
      .replace(/d\(\)/, item.description)
      .replace(/\|/g, "	")
      .replace(/\n/g, "
")
  },

  /*
    Function: write_ticker
    Generates a <Ticker> (and ticker_html) and places it on the page

    Parameters:

      events {Array} - an array of events for display in the ticker
      element {String} - a jQuery selector for the object that will contain the ticker
      format {String} - a format string for displaying the data
      movies {Boolean} - a boolean to tell the function if the events are movies or not. If they are, CalData will use <imdbAPI> to search for extra data

    Example:

    > CalData.write_ticker(events, "#events .content", "s(dddd, MMMM d\nh:mm tt) - e(h:mm tt)")

    See Also:

      <Ticker>

      <Format Strings>

      <DateJS Format Strings at http://code.google.com/p/datejs/wiki/FormatSpecifiers>
  */
  write_ticker: function (events, element, format, movies) {
    "use strict";
    var start_time, end_time;
    var ticker = new Ticker({element: element});

    var fmt = this.auto_format(format);

    format      = fmt[0];
    start_time  = fmt[1];
    end_time    = fmt[2];

    $(element).addClass("ticker");
    // console.log(data.feed);
    // console.log(element);
    if (events.length === 0) {
      $(element).html("No events");
      return;
    } else {
      $(element).html("");
      for (var i = 0; i < events.length; i++) {
        var item = events[i];
        // if (movies === true) {
          // imdbAPI.get_movie(item, this.makeCallback(ticker, item, format, start_time, end_time));
        // } else {
          ticker.addItem(this.ticker_html(item, format, start_time, end_time));
        // }
      }
    }
  },

  /*
    Function: write_movies
    Performs the same function as <write_ticker> but automatically sets movies to true

    Parameters:

      events {Array} - an array of events for display in the ticker
      element {String} - a jQuery selector for the object that will contain the ticker
      format {String} - a format string for displaying the data

    Example:

    > CalData.write_movies(events, "#theater .content", "s(dddd, MMMM d\nh:mm tt)")

    See Also:

      <Ticker>

      <Format Strings>

      <DateJS Format Strings at http://code.google.com/p/datejs/wiki/FormatSpecifiers>
  */
  write_movies: function (events, element, format) {
    "use strict";
    this.write_ticker(events, element, format, true);
  },

  auto_format: function (format) {
    "use strict";
    var start_time, end_time;

    if (typeof(format) === "undefined") {
      start_time  = "h:mm";
      end_time    = "h:mm";
      format      = "s() - e() — t()";
    } else {
      format.replace(/s\(([\s\S]*?)\)/m, "");
      start_time = RegExp.$1;
      format.replace(/e\(([\s\S]*?)\)/m, "");
      end_time = RegExp.$1;
    }

    return [format, start_time, end_time];
  },

  makeCallback: function (ticker, ev, format, start_time, end_time) {
    "use strict";
    return function () {
      ticker.addItem(CalData.ticker_html(ev, format, start_time, end_time));
    };
  }
};

/*
  Class: YConnect
  Contains methods for fetching data from YWAM Connect and creating <Event>s

  Array: date_format
  A <DateJS format string at http://code.google.com/p/datejs/wiki/FormatSpecifiers> that specifies how the dates are returned from YWAM Connect. Set to "yyyy/MM/dd" and will only need to be changed if the YWAM Connect API changes
*/

var YConnect = {

  date_format: "yyyy/MM/dd",

  /*
    Function: get_calendar
    Fetches the event data and executes a callback

    Parameters:

      range {String} - defines what data should be returned. Can be either "today" or "tomorrow" (defaults to "today")
      callback {Function} - callback function called on the <Event> data

    Example:

      (start code)
        YConnect.get_calendar("today", function(data) {
          CalData.write_table(data, "#menu .content", "t()|-|d()");
        }
      (end)

  */
  get_calendar: function (range, callback) {
    "use strict";
    var uri     = "http://api.ywamconnect.net/menu/get.php";
    var params  = {format: "json"};
    var query   = {};
    var events  = [];

    var today = Date.today();
    var time;

    switch (range) {
    case "today":
      time = today;
      break;
    case "tomorrow":
      time = today.addDays(1);
      break;
    // case "week":
    //   time = [today,
    //     today.clone().addDays(7)]
    //   break;
    // case "nextweek":
    //   time = [today.addDays(7),
    //     today.clone().addDays(7)]
    //   break;
    default:
      time = today;
    }

    // var multiple_days   = (time.length > 1);
    // var multiple_months;
    var parseable_days  = [];
    // console.log(events)

    // All the multiple_days code is on hold because it's unnecessary. Who needs multiple days worth of food data?
    // if (multiple_days) { // if time is more than just one day
    //
    //   if (time[0].getMonth() === time[1].getMonth()) { // if both in the same month
    //     params.month  = time[0].getMonth() + 1;
    //     params.year   = time[0].getFullYear();
    //     queries       = [params];
    //     multiple_months = false;
    //
    //     while(time[0].compareTo(time[1]) !== 1) { // while time[0] is before or equal to time[1]
    //       parseable_days.push(time[0].toString(this.date_format));
    //       time[0].addDays(1);
    //     }
    //   } else { // if multiple months
    //     queries[0] = $.extend({month: time[0].getMonth() + 1, year: time[0].getFullYear()}, params);
    //     queries[1] = $.extend({month: time[1].getMonth() + 1, year: time[1].getFullYear()}, params);
    //     multiple_months = true;
    //     parseable_days  = [[], []];
    //     var month       = time[0].getMonth();
    //
    //     while(time[0].compareTo(time[1]) !== 1) { // while time[0] is before or equal to time[1]
    //       if (time[0].getMonth() === month) {
    //         parseable_days[0].push(time[0].toString(this.date_format));
    //       } else {
    //         parseable_days[1].push(time[0].toString(this.date_format));
    //       }
    //       time[0].addDays(1);
    //     }
    //   }
    //
    // } else { // if only one day
      // console.log(time[0])
      // console.log(time[0].getMonth() + 1)
    params.month  = time.getMonth() + 1;
    params.year   = time.getFullYear();
    query       = params;
    // console.log(queries)
    parseable_days = time.toString(this.date_format);
      // console.log(parseable_days);

    // };

    // Again, multiple_days is on hold.
    //     //   this.create_events(data, events);
    //     // }
    //   // }).then(
    //   //   function () {console.log(events)}
    //   // )
    //   var req = $.ajax({
    //       url : uri,
    //       data: queries[0],
    //       dataType : "jsonp",
    //       timeout : 10000
    //   });
    //
    //   req.success(function (data) {
    //       // console.log('Yes! Success!');
    //       // console.log(data);
    //       for (var i = 0; i < parseable_days[0].length; i++) {
    //         // console.log("events = " + events);
    //         // console.log(data);
    //         // console.log(data.data[parseable_days[0][i]]);
    //
    //         YConnect.create_events(data.data[parseable_days[0][i]], parseable_days[0][i], events);
    //       }
    //
    //       CalData.write_table(events, $("#today .content"), "t()|—|d()")
    //   });
    //
    //   req.error(function (data) {
    //       console.log('Oh noes!');
    //   });
    // } else {
    var req = $.ajax({
      url : uri,
      data: query,
      dataType : "jsonp",
      timeout : 10000
    });

    req.success(function (data) {
      // console.log('Yes! Success!');
      // console.log(data);
      data = data.data[parseable_days];
      // console.log(data);
      for (var item in data) {
        if (data.hasOwnProperty(item)) {
        // console.log(item + " is " + data[item]);
          events.push(new Event({
            title: item.toLowerCase().capitalize(),
            description: data[item]
          }));
        }
      }
      events = events.sort(by_mealtime);
      // console.log(events);
      callback(events);
    });

    req.error(function () {
        // console.log('Error getting data');
    });
    // }
  } //,

  // create_events: function (data, date, events) {
  //   "use strict";
  //   // console.log(data);
  //   for(var item in data) {
  //     // console.log(item + " is " + data[item]);
  //     events.push(new Event({
  //       title: item.toLowerCase().capitalize(),
  //       description: data[item]
  //     }));
  //   }
  // },
};

function setGAPIKey() {
  gapi.client.setApiKey(GCal.api_key);
}

/*
  Class: GCal
  Contains methods for fetching data from Google Calendar and creating <Event>s

*/

var GCal = {
  /*
    Object: service
    A google data service object for getting data from Google Calendar

    String: kona_schedule
    The id of the Kona Schedule calendar

    String: kona_events
    The id of the Kona Events calendar

    String: mauka_theater
    The id of the Mauka Theater calendar

    See Also:
    <Google Data Javascript API at http://code.google.com/p/google-api-javascript-client/>
  */

  api_key: 'AIzaSyBqESjcUQVHE1HDahqvSXZMpF3qR9P4OH8',
  kona_schedule: "or2b5kqjl58ndf8ien8atkcplg%40group.calendar.google.com",
  kona_events: "o2jfjbba7bcrhkk5p3scfqj7vc%40group.calendar.google.com",
  mauka_theater: "oebubbrli984mh257hd986td80%40group.calendar.google.com",

  /*
    Function: get_calendar
    Gets data from a Google calendar and executes a callback function

    Parameters:

      name {String} - the id of the calendar
      range {String} - determines the range of the events returned. Options are today (events between 00:00 and 23:59 today), tomorrow (events between 00:00 and 23:59 tomorrow), week (events between 00:00 today and 23:59 7 days from today), and upcoming (events from today at 00:00 and forward)
      callback {Function} - the callback function to execute
      failcount {Integer} - and internal parameter used to catch failures and reload the page if the fail count is too high

    Example:

      (start code)
      GCal.get_calendar(GCal.kona_events, "week", function(data) {
        CalData.write_ticker(data, "#events .content", "s(dddd, MMMM d\nh:mm tt) - e(h:mm tt)");
      });
      (end)
  */

  get_calendar: function (name, range, callback, failcount) {
    "use strict";
		if (typeof(failcount) === "undefined") {
			failcount = 0;
		}

    var startMin, startMax;

    // options = $.extend(this.default_opts, options);
    var today = Date.today();
    var time = [];

    switch (range) {
    case "today":
      time = [today];
      break;
    case "tomorrow":
      time = [today.addDays(1)];
      break;
    case "week":
      time = [today,
        today.clone().addDays(7)];
      break;
    case "upcoming":
      time = [today,
        false];
      break;
    default:
      // nil
    }

    if (time.length > 1) { // if time is more than just one day
      startMin = time[0];
      if (time[1]) {
        startMax = time[1].clone().set({hour: 23, minute: 59, second: 59});
      } else {
        startMax = null;
      }
    } else {
      startMin = time[0];
      startMax = time[0].clone().set({hour: 23, minute: 59, second: 59});
    }

    var events = [];

    var request = gapi.client.request({
      path: '/calendar/v3/calendars/' + name + '/events',
      params: {
        timeMin:      startMin.toISOString(),
        timeMax:      startMax.toISOString(),
        singleEvents: true,
        orderBy:      'startTime'
      }
    });

    request.then(function(data) {
      var entries = data.result.items;

      var events = entries.map(function(event) {
        return Event.fromGoogleEvent(event)
      })

      callback(events);
    },
    function() {
      if (failcount >= 3) {
        videoPlayer.queueRefresh();
      } else {
        GCal.get_calendar(name, range, callback, failcount + 1);
      }
    }); // if there's a problem, you know i'll solve it (aka try again...)
  },

  /*
  Function: parse_google_date
  */

  parse_google_date: function(dateString) {
    return Date.parse(dateString.substring(0, 19));
  },

  /*
    Function: get_two_calendars
    Gets data from two Google calendars, combines the data, and executes a callback function

    Parameters:

      cal1 {String} - the id of the first calendar
      cal2 {String} - the id of the second calendar
      range {String} - determines the range of the events returned. Options are today (events between 00:00 and 23:59 today), tomorrow (events between 00:00 and 23:59 tomorrow), week (events between 00:00 today and 23:59 7 days from today), and upcoming (events from today at 00:00 and forward)
      callback {Function} - the callback function to execute

    Example:

      (start code)
      GCal.get_two_calendars(GCal.kona_events, GCal.kona_schedule, "today", function(data) {
        CalData.write_table(data, "#events-today .content", "s(h:mm) - e(h:mm tt)|-|t()")
      });
      (end)
  */

  get_two_calendars: function(cal1, cal2, range, callback) {
    "use strict";
    this.get_calendar(cal1, range, function(data1) {
      GCal.get_calendar(cal2, range, function(data2) {
        var mixData = $.merge(data1, data2);
        mixData = mixData.sort(by_time);
        callback(mixData);
      });
    });
  }
};


text:
<include file="../Public/header_list" />

  <form action="{:U('w3g/Index/doComment')}" method="post">
    <input type="hidden" name="weibo_id" value="{$weibo_id}" />
    <input type="hidden" name="comment_id" value="{$comment_id}"/>
    <textarea cols="" rows="12" style="width:100%" name="content" id="forwardcontent"></textarea>
    <input type="checkbox" name="transpond" value="1"/> 同时发一条微博
    <input type="submit" value="发布" class="btn_s R mt10"/>

  </form>

<include file="../Public/footer" />


text:
All the exceptions thrown in Redaktilo live in the `Gnugat\Redaktilo\Exception`
namespace and implement a common interface allowing you to catch any of them
easily:

```php
<?php

try {

    // any operations made with Redaktilo

} catch (\Gnugat\Redaktilo\Exception\Exception $e) { ... }
```

Redaktilo's exceptions all have a descriptive message allowing developers to
understand what went wrong. If the message is not enough, use their getter
to get more context.

Here's the list of the exceptions that can be thrown:

* [CommandNotFoundException](#commandnotfoundexception)
* [NotSupportedException](#notsupportedexception)
* [PatternNotFoundException](#patternnotfoundexception)
* [InvalidLineNumberException](#invalidlinenumberexception)
* [DifferentLineBreaksFoundException](#differentlinebreaksfoundexception)
* [FileNotFoundException](#filenotfoundexception)
* [IOException](#ioexception)
* [InvalidArgumentException](#invalidargumentexception)

## CommandNotFoundException

```php
<?php

namespace Gnugat\Redaktilo\Exception;

class CommandNotFoundException extends \Exception implements Exception
{
    public function getName();
    public function getCommands();
}
```

## NotSupportedException

```php
<?php

namespace Gnugat\Redaktilo\Exception;

class NotSupportedException extends \Exception implements Exception
{
    public function getPattern();
    public function getSearchStrategies();
}
```

## PatternNotFoundException

```php
<?php

namespace Gnugat\Redaktilo\Exception;

class PatternNotFoundException extends \Exception implements Exception
{
    public function getPattern();
    public function getText();
}
```

## InvalidLineNumberException

```php
<?php

namespace Gnugat\Redaktilo\Exception;

class InvalidLineNumberException extends \InvalidArgumentException implements Exception
{
    public function getLineNumber();
    public function getText();
}
```

## DifferentLineBreaksFoundException

```php
<?php

namespace Gnugat\Redaktilo\Exception;

class DifferentLineBreaksFoundException extends \Exception implements Exception
{
    public function getString();
    public function getNumberLineBreakOther();
    public function getNumberLineBreakWindows();
}
```

## FileNotFoundException

```php
<?php

namespace Gnugat\Redaktilo\Exception;

class FileNotFoundException extends \RuntimeException implements Exception
{
    public function getPath();
}
```

## IOException

```php
<?php

namespace Gnugat\Redaktilo\Exception;

class IOException extends \RuntimeException implements Exception
{
    public function getPath();
}
```

## InvalidArgumentException

```php
<?php

namespace Gnugat\Redaktilo\Exception;

class InvalidArgumentException extends \InvalidArgumentException implements Exception
{
}
```

## Previous readings

* [README](../README.md)
* [Tutorial](01-tutorial.md)
* [Use cases](02-use-cases.md)
* [Reference](03-reference.md)
* [Vocabulary](04-vocabulary.md)
* [Extending](05-extending.md)


text:
package it.webalice.alexcoppo.bookmarksmanager_struts.dbmsapi.bookmarks;

import it.webalice.alexcoppo.bookmarksmanager_struts.model.Bookmark;
import it.webalice.alexcoppo.bookmarksmanager_struts.model.BookmarkDAO;
import it.webalice.alexcoppo.strutsutils.AJAXAction;
import it.webalice.alexcoppo.strutsutils.HibernateResult;

import javax.servlet.http.HttpServletRequest;

import net.sf.jautl.json.JSONObjectBuilder;
import net.sf.jautl.text.BasicMarshaller;
import net.sf.jautl.text.StringMarshaller;

public class LoadAction extends AJAXAction {
    @Override
	protected String processAction(HttpServletRequest request) {
		StringMarshaller sm = new BasicMarshaller();
		long id = sm.asLong(request.getParameter("id"), 0);

		HibernateResult hr = BookmarkDAO.load(request, id);

		JSONObjectBuilder job = new JSONObjectBuilder();
		if (hr.isOK()) {
			Bookmark bm = (Bookmark)hr.getObject();

			job.put("id", bm.getId());
			job.put("url", bm.getURL());
			job.put("shortUrl", bm.getDomain());
		} else
			job.put("error", hr.getError());

        return job.asString();
    }
}


text:
#include "tensorflow/core/grappler/graph_analyzer/sig_node.h"

#include <algorithm>

#include "absl/strings/str_format.h"

namespace tensorflow {
namespace grappler {
namespace graph_analyzer {

static constexpr bool debug = false;

//=== SigNode

SigNode::SigNode(const NodeDef* node) : node_(node) {}

void SigNode::CopyLinks(const GenNode& from, const TranslationMap& map) {
  hash_to_link_.clear();
  hashed_peers_.clear();

  std::map<LinkTag, Link> link_map;
  CopyLinksPass1(from, map, &link_map);
  CopyLinksPass2(&link_map);
}

void SigNode::CopyLinksPass1(const GenNode& from, const TranslationMap& map,
                             std::map<LinkTag, Link>* link_map) {
  LinkTag::Hasher link_hasher;

  for (const auto& entry : from.links()) {
    for (const auto& target : entry.second) {
      auto nodeit = map.find(target.node);
      if (nodeit == map.end()) {
        // Node is not in the subgraph, ignore.
        continue;
      }

      LinkTag tag(entry.first, target.port);
      size_t hval = link_hasher(tag);

      // This instantiates the entry if it was not present.
      Link& map_entry = (*link_map)[tag];
      if (map_entry.peers.empty()) {
        map_entry.tag = tag;
        map_entry.unique_hash = hval;
      }
      map_entry.peers.push_back(nodeit->second);
    }
  }
}

void SigNode::CopyLinksPass2(std::map<LinkTag, Link>* link_map) {
  for (auto& entry : *link_map) {
    Link* hl_entry_ptr = &hash_to_link_[entry.second.unique_hash];
    // In case of a conflict, rehash. This should almost never happen.
    // Because the order of iteration is predictable, the rehashed values
    // will also be predictable.
    while (!hl_entry_ptr->peers.empty()) {
      CombineHash(1, &entry.second.unique_hash);
      hl_entry_ptr = &hash_to_link_[entry.second.unique_hash];
    }

    for (const auto& peer : entry.second.peers) {
      hashed_peers_.emplace_back(HashedPeer(entry.second.unique_hash, peer));
    }

    hl_entry_ptr->tag = entry.second.tag;
    hl_entry_ptr->unique_hash = entry.second.unique_hash;
    hl_entry_ptr->peers.swap(entry.second.peers);
  }
}

void SigNode::ComputeTopoHash0() {
  topo_hash_.clear();
  last_hashed_nodes_ = next_hashed_nodes_ = node_mask_;

  // TODO(babkin): include the attributes too, as an option.
  size_t hval = std::hash<string>()(opcode());

  // Getting the topology of the links in to the hash early should get more
  // conflicts resolved early.
  for (const auto& entry : hashed_peers_) {
    CombineHash(entry.link_hash, &hval);
  }

  topo_hash_.push_back(hval);
}

void SigNode::ComputeTopoHash(int distance) {
  // The new starting point.
  next_hashed_nodes_ = last_hashed_nodes_;
  if (debug) {
    LOG(INFO) << "DEBUG    node " << name() << " mask=" << std::hex
              << next_hashed_nodes_;
  }

  if (hash_is_final_) {
    return;
  }

  CHECK(topo_hash_.size() == distance);

  int prev = distance - 1;

  // Start with own's local topology hash. This value is stable, so
  // if the hashes of the surrounding nodes don't change on the following
  // distances, the hash of this node won't change either.
  size_t hval = topo_hash_[0];

  if (!hashed_peers_.empty()) {
    size_t last_link_hash = hashed_peers_[0].link_hash;
    size_t comm_hash = 0;

    for (const auto& entry : hashed_peers_) {
      if (entry.link_hash != last_link_hash) {
        CombineHash(last_link_hash, &hval);
        CombineHash(comm_hash, &hval);
        comm_hash = 0;
        last_link_hash = entry.link_hash;
      }

      // The links in the same vector are commutative, so combine their
      // hashes in a commutative way.
      CombineHashCommutative(entry.peer->GetTopoHash(prev), &comm_hash);
      next_hashed_nodes_ |= entry.peer->last_hashed_nodes_;
      if (debug) {
        LOG(INFO) << "DEBUG    node " << name() << " += " << entry.peer->name()
                  << " mask=" << std::hex << next_hashed_nodes_;
      }
    }

    // The last commutative group.
    CombineHash(last_link_hash, &hval);
    CombineHash(comm_hash, &hval);
  }

  topo_hash_.push_back(hval);
}

size_t SigNode::GetTopoHash(int distance) const {
  CHECK(!topo_hash_.empty());
  if (distance >= topo_hash_.size()) {
    CHECK(hash_is_final_);
    return topo_hash_.back();
  } else {
    return topo_hash_[distance];
  }
}

bool SigNode::operator==(const SigNode& other) const {
  // TODO(babkin): add attributes too.
  if (opcode() != other.opcode()) {
    return false;
  }

  // Normally the caller is expected to compare the nodes
  // at the same rank in different graphs, but just in case...
  if (unique_rank_ != other.unique_rank_) {
    return false;
  }

  if (hashed_peers_.size() != other.hashed_peers_.size()) {
    return false;
  }

  for (auto it1 = hashed_peers_.begin(), it2 = other.hashed_peers_.begin();
       it1 != hashed_peers_.end(); ++it1, ++it2) {
    // TODO(babkin): might compare the actual values too
    // but the hash is probably just as good.
    if (it1->link_hash != it2->link_hash) {
      return false;
    }
    if (it1->peer->unique_rank_ != it2->peer->unique_rank_) {
      return false;
    }
  }

  return true;
}

//=== Signature

constexpr int Signature::kMaxGraphSize;

string Signature::ToString() const {
  string result;
  for (size_t n = 0; n < nodes.size(); ++n) {
    // TODO(babkin): add attributes too.
    result += absl::StrFormat("%d:%s", n, nodes[n]->opcode());
    for (const auto& entry : nodes[n]->hashed_peers_) {
      const auto& link = nodes[n]->hash_to_link_[entry.link_hash];

      // The link entries are already sorted, by tags and then by the
      // node ranks.
      if (link.tag.local.IsInbound()) {
        result +=
            absl::StrFormat("[%s:%s:%d]", string(link.tag.local),
                            string(link.tag.remote), entry.peer->unique_rank_);
      }
    }
    result.push_back(',');
  }
  return result;
}

Status Signature::Compute() {
  if (map.size() > kMaxGraphSize) {
    return Status(
        error::INVALID_ARGUMENT,
        absl::StrFormat(
            "A graph of %d nodes is too big for signature computation, "
            "the maximal supported node count is %d.",
            map.size(), kMaxGraphSize));
  }

  // The value that will be assigned next as the unique node id.
  // This also means that all the entries in nodes at indexes less than this
  // have been finalized and don't need to be touched any more.
  size_t next_node_id = 0;

  sig_short = 0;
  sig_full.resize(0);  // Keep the storage.

  // The main signature generation.
  PrepareNodes();
  FindUniqueHashes(&next_node_id);
  while (next_node_id < map.size()) {
    ComputeOneRound(next_node_id);
    FindUniqueHashes(&next_node_id);
  }

  OrderLinks();

  return Status::OK();
}

void Signature::PrepareNodes() {
  nodes.resize(0);  // Keep the storage.

  // Initialize the nodes.
  int64_t mask = 1;
  for (const auto& entry : map) {
    SigNode* node = entry.second.get();
    node->last_hashed_nodes_ = node->node_mask_ = mask;
    mask <<= 1;
    node->unique_rank_ = ~0;
    node->hash_is_final_ = false;
    node->ComputeTopoHash0();
    if (node->GetHighTopoHash() <= map.size()) {
      // Would conflict with one of the reserved values.
      node->ReHighTopoHash();
    }

    // The initial order is random.
    nodes.emplace_back(node);
  }
}

void Signature::FindUniqueHashes(size_t* next_node_id_p) {
  // Start by sorting by the hash value.
  std::sort(nodes.begin() + *next_node_id_p, nodes.end(),
            SigNode::NodeOrderLess());

  // At each call, if no nodes have unique hashes, one node that has a
  // non-unique (shared) hash can be made unique by assigning a unique id.
  // This node gets picked predictably by taking the last node.
  // TODO(babkin): Technically, more than one node can be unshared,
  // as long as their last_hashed_nodes_ overlap only by the nodes that
  // already had the assigned ids before the current round. But it's not clear
  // yet, how often would this beneficial, because it looks like for many
  // subgraphs unsharing one node should be enough to untangle them. This
  // would need more measurement before implementing.
  bool found_unique = false;
  for (size_t n = *next_node_id_p; n < nodes.size(); ++n) {
    size_t cur_hash = nodes[n]->GetHighTopoHash();
    if (n + 1 < nodes.size() && nodes[n + 1]->GetHighTopoHash() == cur_hash) {
      // A sequence of nodes sharing the same hash. Skip over it.
      // TODO(babkin): check here for the arbitrary hash conflicts and resolve
      // them.
      for (++n;
           n + 1 < nodes.size() && nodes[n + 1]->GetHighTopoHash() == cur_hash;
           ++n) {
      }
      if (found_unique || n != nodes.size() - 1) {
        // Either some unique nodes have already been found, or this is
        // not the last chance, keep trying to find the unique nodes.
        continue;
      }
      // Here we're at the last node and haven't found any unique ones.
      // So fall through and make this last node unique.
    }

    found_unique = true;
    size_t id = (*next_node_id_p)++;
    nodes[n]->unique_rank_ = id;

    size_t last_hash = nodes[n]->GetHighTopoHash();
    CombineHash(last_hash, &sig_short);
    sig_full.push_back(last_hash);

    // Take the hash at 0 and mix the unique rank into it. After that it will
    // stay fixed.
    nodes[n]->topo_hash_.resize(1);
    nodes[n]->topo_hash_[0] = id + 1;  // Avoid the value of 0.

    nodes[n]->hash_is_final_ = true;
    nodes[n]->last_hashed_nodes_ = nodes[n]->node_mask_;
    if (n != id) {
      std::swap(nodes[id], nodes[n]);
    }
  }
}

void Signature::ComputeOneRound(size_t next_node_id) {
  // Reset the state of the nodes.
  int debug_i = 0;
  for (auto it = nodes.begin() + next_node_id; it != nodes.end(); ++it) {
    auto node = *it;
    // The hash at distance 0 never changes, so preserve it.
    node->topo_hash_.resize(1);
    node->last_hashed_nodes_ = node->node_mask_;
    node->hash_is_final_ = false;
    if (debug) {
      LOG(INFO) << "DEBUG distance=" << 0 << " node " << debug_i++ << " "
                << node->name() << " mask=" << std::hex
                << node->last_hashed_nodes_;
    }
  }

  bool stop = false;
  // The distance can reach up to nodes.size()+1, to include not only all the
  // nodes but also all the redundant paths.
  for (int distance = 1; !stop; ++distance) {
    for (auto it = nodes.begin() + next_node_id; it != nodes.end(); ++it) {
      auto node = *it;
      if (node->hash_is_final_) {
        continue;
      }
      node->ComputeTopoHash(distance);
      if (node->GetHighTopoHash() <= nodes.size()) {
        // Would conflict with one of the reserved values.
        node->ReHighTopoHash();
      }
    }

    // Will be looking for the indications to not stop.
    stop = true;

    debug_i = 0;
    // The bitmasks get moved after all the hash computations are done.
    for (auto it = nodes.begin() + next_node_id; it != nodes.end(); ++it) {
      auto node = *it;
      if (debug) {
        LOG(INFO) << "DEBUG distance=" << distance << " node " << debug_i++
                  << " " << node->name() << " oldmask=" << std::hex
                  << node->last_hashed_nodes_ << " mask=" << std::hex
                  << node->next_hashed_nodes_;
      }
      if (node->last_hashed_nodes_ == node->next_hashed_nodes_) {
        // Stopped growing, this part of the graph must be fully
        // surrounded by nodes that already have the unique ids.
        node->hash_is_final_ = true;
      } else {
        node->last_hashed_nodes_ = node->next_hashed_nodes_;
        stop = false;
      }
    }
  }
}

void Signature::OrderLinks() {
  for (const auto& node : nodes) {
    if (node->hashed_peers_.empty()) {
      continue;
    }

    size_t cur_link_hash = node->hashed_peers_[0].link_hash + 1;
    int first_idx = -1;

    int idx;
    for (idx = 0; idx < node->hashed_peers_.size(); ++idx) {
      auto& entry = node->hashed_peers_[idx];
      if (entry.link_hash == cur_link_hash) {
        continue;
      }
      if (idx - first_idx > 1) {
        // Need to sort.
        std::sort(node->hashed_peers_.begin() + first_idx,
                  node->hashed_peers_.begin() + idx,
                  SigNode::HashedPeer::LessByRank());
      }

      cur_link_hash = entry.link_hash;
      first_idx = idx;
    }
    if (idx - first_idx > 1) {
      // Sort the last bunch.
      std::sort(node->hashed_peers_.begin() + first_idx,
                node->hashed_peers_.begin() + idx,
                SigNode::HashedPeer::LessByRank());
    }
  }
}

bool Signature::operator==(const Signature& other) const {
  // Tries to find the differences as early as possible by
  // comparing the hashes first.

  if (sig_short != other.sig_short) {
    return false;
  }
  if (sig_full.size() != other.sig_full.size()) {
    return false;
  }

  for (auto it1 = sig_full.begin(), it2 = other.sig_full.begin();
       it1 != sig_full.end(); ++it1, ++it2) {
    if (*it1 != *it2) {
      return false;
    }
  }

  if (nodes.size() != other.nodes.size()) {
    return false;
  }
  for (auto it1 = nodes.begin(), it2 = other.nodes.begin(); it1 != nodes.end();
       ++it1, ++it2) {
    if (**it1 != **it2) {
      return false;
    }
  }

  return true;
}

}  // end namespace graph_analyzer
}  // end namespace grappler
}  // end namespace tensorflow