text:
/*
 * 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.
 */
package io.trino.plugin.jdbc;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import io.airlift.log.Logging;
import io.trino.plugin.jdbc.mapping.IdentifierMappingModule;
import io.trino.plugin.jdbc.mapping.SchemaMappingRule;
import io.trino.plugin.jdbc.mapping.TableMappingRule;
import io.trino.testing.AbstractTestQueryFramework;
import io.trino.testing.sql.SqlExecutor;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.nio.file.Path;
import java.util.List;
import java.util.stream.Stream;

import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.MoreCollectors.onlyElement;
import static io.airlift.log.Level.WARN;
import static io.trino.plugin.jdbc.mapping.RuleBasedIdentifierMappingUtils.updateRuleBasedIdentifierMappingFile;
import static java.lang.String.format;
import static java.util.Locale.ENGLISH;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testng.Assert.assertEquals;

// Tests are using JSON based identifier mapping which is one for all tests
@Test(singleThreaded = true)
public abstract class BaseCaseInsensitiveMappingTest
        extends AbstractTestQueryFramework
{
    protected abstract Path getMappingFile();

    protected abstract SqlExecutor onRemoteDatabase();

    @BeforeClass
    public void disableMappingRefreshVerboseLogging()
    {
        Logging logging = Logging.initialize();
        logging.setLevel(IdentifierMappingModule.class.getName(), WARN);
    }

    @Test
    public void testNonLowerCaseSchemaName()
            throws Exception
    {
        try (AutoCloseable ignore1 = withSchema("NonLowerCaseSchema");
                AutoCloseable ignore2 = withTable("NonLowerCaseSchema", "lower_case_name", "(c varchar(5))");
                AutoCloseable ignore3 = withTable("NonLowerCaseSchema", "Mixed_Case_Name", "(c varchar(5))");
                AutoCloseable ignore4 = withTable("NonLowerCaseSchema", "UPPER_CASE_NAME", "(c varchar(5))")) {
            assertThat(computeActual("SHOW SCHEMAS").getOnlyColumn()).contains("nonlowercaseschema");
            assertQuery("SHOW SCHEMAS LIKE 'nonlowerc%'", "VALUES 'nonlowercaseschema'");
            assertQuery("SELECT schema_name FROM information_schema.schemata WHERE schema_name LIKE '%nonlowercaseschema'", "VALUES 'nonlowercaseschema'");
            assertQuery("SHOW TABLES FROM nonlowercaseschema", "VALUES 'lower_case_name', 'mixed_case_name', 'upper_case_name'");
            assertQuery("SELECT table_name FROM information_schema.tables WHERE table_schema = 'nonlowercaseschema'", "VALUES 'lower_case_name', 'mixed_case_name', 'upper_case_name'");
            assertQueryReturnsEmptyResult("SELECT * FROM nonlowercaseschema.lower_case_name");
        }
    }

    @Test
    public void testNonLowerCaseTableName()
            throws Exception
    {
        try (AutoCloseable ignore1 = withSchema("SomeSchema");
                AutoCloseable ignore2 = withTable(
                        "SomeSchema",
                        "NonLowerCaseTable",
                        "(" +
                                quoted("lower_case_name") + " varchar(1), " +
                                quoted("Mixed_Case_Name") + " varchar(1), " +
                                quoted("UPPER_CASE_NAME") + " varchar(1))")) {
            onRemoteDatabase().execute("INSERT INTO " + (quoted("SomeSchema") + "." + quoted("NonLowerCaseTable")) + " SELECT 'a', 'b', 'c'");
            assertQuery(
                    "SELECT column_name FROM information_schema.columns WHERE table_schema = 'someschema' AND table_name = 'nonlowercasetable'",
                    "VALUES 'lower_case_name', 'mixed_case_name', 'upper_case_name'");
            assertQuery(
                    "SELECT column_name FROM information_schema.columns WHERE table_name = 'nonlowercasetable'",
                    "VALUES 'lower_case_name', 'mixed_case_name', 'upper_case_name'");
            assertEquals(
                    computeActual("SHOW COLUMNS FROM someschema.nonlowercasetable").getMaterializedRows().stream()
                            .map(row -> row.getField(0))
                            .collect(toImmutableSet()),
                    ImmutableSet.of("lower_case_name", "mixed_case_name", "upper_case_name"));

            // Note: until https://github.com/prestodb/presto/issues/2863 is resolved, this is *the* way to access the tables.

            assertQuery("SELECT lower_case_name FROM someschema.nonlowercasetable", "VALUES 'a'");
            assertQuery("SELECT mixed_case_name FROM someschema.nonlowercasetable", "VALUES 'b'");
            assertQuery("SELECT upper_case_name FROM someschema.nonlowercasetable", "VALUES 'c'");
            assertQuery("SELECT upper_case_name FROM SomeSchema.NonLowerCaseTable", "VALUES 'c'");
            assertQuery("SELECT upper_case_name FROM \"SomeSchema\".\"NonLowerCaseTable\"", "VALUES 'c'");

            assertUpdate("INSERT INTO someschema.nonlowercasetable (lower_case_name) VALUES ('l')", 1);
            assertUpdate("INSERT INTO someschema.nonlowercasetable (mixed_case_name) VALUES ('m')", 1);
            assertUpdate("INSERT INTO someschema.nonlowercasetable (upper_case_name) VALUES ('u')", 1);
            assertQuery(
                    "SELECT * FROM someschema.nonlowercasetable",
                    "VALUES ('a', 'b', 'c')," +
                            "('l', NULL, NULL)," +
                            "(NULL, 'm', NULL)," +
                            "(NULL, NULL, 'u')");
        }
    }

    @Test
    public void testSchemaNameClash()
            throws Exception
    {
        String[] nameVariants = {"casesensitivename", "CaseSensitiveName", "CASESENSITIVENAME"};
        assertThat(Stream.of(nameVariants)
                .map(name -> name.toLowerCase(ENGLISH))
                .collect(toImmutableSet()))
                .hasSize(1);

        for (int i = 0; i < nameVariants.length; i++) {
            for (int j = i + 1; j < nameVariants.length; j++) {
                String schemaName = nameVariants[i];
                String otherSchemaName = nameVariants[j];
                try (AutoCloseable ignore1 = withSchema(schemaName);
                        AutoCloseable ignore2 = withSchema(otherSchemaName);
                        AutoCloseable ignore3 = withTable(schemaName, "some_table_name", "(c varchar(5))");
                        AutoCloseable ignore4 = withSchema("some_schema");
                        AutoCloseable ignore5 = withTable("some_schema", "some_table", "(c int)")) {
                    assertThat(computeActual("SHOW SCHEMAS").getOnlyColumn().filter("casesensitivename"::equals)).hasSize(1); // TODO change io.trino.plugin.jdbc.JdbcClient.getSchemaNames to return a List
                    assertQueryFails("SHOW TABLES FROM casesensitivename", "Failed to find remote schema name: Ambiguous name: casesensitivename");
                    assertQueryFails("SELECT * FROM casesensitivename.some_table_name", "Failed to find remote schema name: Ambiguous name: casesensitivename");
                    assertQuery("SHOW TABLES FROM some_schema", "VALUES 'some_table'");
                    assertQueryReturnsEmptyResult("SELECT * FROM some_schema.some_table");
                }
            }
        }
    }

    @Test
    public void testTableNameClash()
            throws Exception
    {
        String[] nameVariants = {"casesensitivename", "CaseSensitiveName", "CASESENSITIVENAME"};
        assertThat(Stream.of(nameVariants)
                .map(name -> name.toLowerCase(ENGLISH))
                .collect(toImmutableSet()))
                .hasSize(1);

        for (int i = 0; i < nameVariants.length; i++) {
            for (int j = i + 1; j < nameVariants.length; j++) {
                try (AutoCloseable ignore1 = withTable(nameVariants[i], "(c varchar(5))");
                        AutoCloseable ignore2 = withTable(nameVariants[j], "(d varchar(5))");
                        AutoCloseable ignore3 = withTable("some_table", "(d varchar(5))")) {
                    assertThat(computeActual("SHOW TABLES").getOnlyColumn().filter("casesensitivename"::equals)).hasSize(1); // TODO, should be 2
                    assertQueryFails("SHOW COLUMNS FROM casesensitivename", "Failed to find remote table name: Ambiguous name: casesensitivename");
                    assertQueryFails("SELECT * FROM casesensitivename", "Failed to find remote table name: Ambiguous name: casesensitivename");
                    assertQuery("SHOW COLUMNS FROM some_table", "SELECT 'd', 'varchar(5)', '', ''");
                    assertQueryReturnsEmptyResult("SELECT * FROM some_table");
                }
            }
        }
    }

    @Test
    public void testSchemaNameRuleMapping()
            throws Exception
    {
        updateRuleBasedIdentifierMappingFile(
                getMappingFile(),
                ImmutableList.of(new SchemaMappingRule("remote_schema", "trino_schema")),
                ImmutableList.of());

        try (AutoCloseable ignore1 = withSchema("remote_schema");
                AutoCloseable ignore3 = withTable("remote_schema", "some_table_name", "(c varchar(5))")) {
            assertThat(computeActual("SHOW SCHEMAS ")
                    .getOnlyColumn())
                    .contains("trino_schema");
            assertQuery("SHOW TABLES FROM trino_schema", "VALUES 'some_table_name'");
            assertUpdate("INSERT INTO trino_schema.some_table_name VALUES 'a'", 1);
            assertQuery("SELECT * FROM trino_schema.some_table_name", "VALUES 'a'");
        }
    }

    @Test
    public void testSchemaNameClashWithRuleMapping()
            throws Exception
    {
        List<SchemaMappingRule> schemaMappingRules = ImmutableList.of(
                new SchemaMappingRule("casesensitivename", "casesensitivename_a"),
                new SchemaMappingRule("CaseSensitiveName", "casesensitivename_b"),
                new SchemaMappingRule("CASESENSITIVENAME", "casesensitivename_c"));
        updateRuleBasedIdentifierMappingFile(getMappingFile(), schemaMappingRules, ImmutableList.of());

        String[] nameVariants = {"casesensitivename", "CaseSensitiveName", "CASESENSITIVENAME"};
        assertThat(Stream.of(nameVariants)
                .map(name -> name.toLowerCase(ENGLISH))
                .collect(toImmutableSet()))
                .hasSize(1);

        for (int i = 0; i < nameVariants.length; i++) {
            for (int j = i + 1; j < nameVariants.length; j++) {
                String remoteSchema = nameVariants[i];
                String otherRemoteSchema = nameVariants[j];

                try (AutoCloseable ignore1 = withSchema(remoteSchema);
                        AutoCloseable ignore2 = withSchema(otherRemoteSchema);
                        AutoCloseable ignore3 = withTable(remoteSchema, "some_table_name", "(c varchar(5))")) {
                    String schema = schemaMappingRules.stream()
                            .filter(rule -> rule.getRemoteSchema().equals(remoteSchema))
                            .map(SchemaMappingRule::getMapping)
                            .collect(onlyElement());

                    assertThat(computeActual("SHOW SCHEMAS ")
                            .getOnlyColumn()
                            .map(String.class::cast)
                            .filter(anObject -> anObject.startsWith("casesensitivename")))
                            .hasSize(2);
                    assertQuery("SHOW TABLES FROM " + schema, "VALUES 'some_table_name'");
                    assertUpdate(format("INSERT INTO %s.some_table_name VALUES 'a'", schema), 1);
                    assertQuery(format("SELECT * FROM %s.some_table_name", schema), "VALUES 'a'");
                }
            }
        }
    }

    @Test
    public void testTableNameRuleMapping()
            throws Exception
    {
        updateRuleBasedIdentifierMappingFile(
                getMappingFile(),
                ImmutableList.of(),
                ImmutableList.of(new TableMappingRule(getSession().getSchema().orElseThrow(), "remote_table", "trino_table")));

        try (AutoCloseable ignore1 = withTable("remote_table", "(c varchar(5))")) {
            assertThat(computeActual("SHOW TABLES").getOnlyColumn())
                    .contains("trino_table");
            assertQuery("SHOW COLUMNS FROM trino_table", "SELECT 'c', 'varchar(5)', '', ''");
            assertUpdate("INSERT INTO trino_table VALUES 'dane'", 1);
            assertQuery("SELECT * FROM trino_table", "VALUES 'dane'");
        }
    }

    @Test
    public void testTableNameClashWithRuleMapping()
            throws Exception
    {
        String schema = getSession().getSchema().orElseThrow();
        List<TableMappingRule> tableMappingRules = ImmutableList.of(
                new TableMappingRule(schema, "casesensitivename", "casesensitivename_a"),
                new TableMappingRule(schema, "CaseSensitiveName", "casesensitivename_b"),
                new TableMappingRule(schema, "CASESENSITIVENAME", "casesensitivename_c"));
        updateRuleBasedIdentifierMappingFile(getMappingFile(), ImmutableList.of(), tableMappingRules);

        String[] nameVariants = {"casesensitivename", "CaseSensitiveName", "CASESENSITIVENAME"};
        assertThat(Stream.of(nameVariants)
                .map(name -> name.toLowerCase(ENGLISH))
                .collect(toImmutableSet()))
                .hasSize(1);

        for (int i = 0; i < nameVariants.length; i++) {
            for (int j = i + 1; j < nameVariants.length; j++) {
                String remoteTable = nameVariants[i];
                String otherRemoteTable = nameVariants[j];
                try (AutoCloseable ignore1 = withTable(remoteTable, "(c varchar(5))");
                        AutoCloseable ignore2 = withTable(otherRemoteTable, "(d varchar(5))")) {
                    String table = tableMappingRules.stream()
                            .filter(rule -> rule.getRemoteTable().equals(remoteTable))
                            .map(TableMappingRule::getMapping)
                            .collect(onlyElement());

                    assertThat(computeActual("SHOW TABLES")
                            .getOnlyColumn()
                            .map(String.class::cast)
                            .filter(anObject -> anObject.startsWith("casesensitivename")))
                            .hasSize(2);
                    assertQuery("SHOW COLUMNS FROM " + table, "SELECT 'c', 'varchar(5)', '', ''");
                    assertUpdate("INSERT INTO " + table + " VALUES 'dane'", 1);
                    assertQuery("SELECT * FROM " + table, "VALUES 'dane'");
                }
            }
        }
    }

    @Test
    public void testSchemaAndTableNameRuleMapping()
            throws Exception
    {
        updateRuleBasedIdentifierMappingFile(
                getMappingFile(),
                ImmutableList.of(new SchemaMappingRule("remote_schema", "trino_schema")),
                ImmutableList.of(new TableMappingRule("remote_schema", "remote_table", "trino_table")));

        try (AutoCloseable ignore1 = withSchema("remote_schema");
                AutoCloseable ignore2 = withTable("remote_schema", "remote_table", "(c varchar(5))")) {
            assertThat(computeActual("SHOW SCHEMAS").getOnlyColumn())
                    .contains("trino_schema");
            assertThat(computeActual("SHOW TABLES IN trino_schema").getOnlyColumn())
                    .contains("trino_table");
            assertQuery("SHOW COLUMNS FROM trino_schema.trino_table", "SELECT 'c', 'varchar(5)', '', ''");
            assertUpdate("INSERT INTO trino_schema.trino_table VALUES 'dane'", 1);
            assertQuery("SELECT * FROM trino_schema.trino_table", "VALUES 'dane'");
        }
    }

    protected AutoCloseable withSchema(String schemaName)
    {
        onRemoteDatabase().execute("CREATE SCHEMA " + quoted(schemaName));
        return () -> onRemoteDatabase().execute("DROP SCHEMA " + quoted(schemaName));
    }

    protected AutoCloseable withTable(String remoteSchemaName, String remoteTableName, String tableDefinition)
    {
        String quotedName = quoted(remoteSchemaName) + "." + quoted(remoteTableName);
        onRemoteDatabase().execute(format("CREATE TABLE %s %s", quotedName, tableDefinition));
        return () -> onRemoteDatabase().execute("DROP TABLE " + quotedName);
    }

    protected String quoted(String name)
    {
        String identifierQuote = "\"";
        name = name.replace(identifierQuote, identifierQuote + identifierQuote);
        return identifierQuote + name + identifierQuote;
    }

    private AutoCloseable withTable(String remoteTableName, String definition)
    {
        return withTable(getSession().getSchema().orElseThrow(), remoteTableName, definition);
    }
}


text:
package org.camunda.bpm.engine.rest;

import static com.jayway.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.Collections;
import java.util.List;

import javax.ws.rs.core.Response.Status;

import org.camunda.bpm.engine.AuthorizationException;
import org.camunda.bpm.engine.management.ActivityStatistics;
import org.camunda.bpm.engine.management.ActivityStatisticsQuery;
import org.camunda.bpm.engine.management.ProcessDefinitionStatistics;
import org.camunda.bpm.engine.management.ProcessDefinitionStatisticsQuery;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.camunda.bpm.engine.repository.ProcessDefinitionQuery;
import org.camunda.bpm.engine.rest.helper.MockProvider;
import org.camunda.bpm.engine.rest.util.container.TestContainerRule;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.mockito.InOrder;
import org.mockito.Mockito;

import com.jayway.restassured.http.ContentType;

public class StatisticsRestTest extends AbstractRestServiceTest {

  @ClassRule
  public static TestContainerRule rule = new TestContainerRule();

  protected static final String PROCESS_DEFINITION_STATISTICS_URL = TEST_RESOURCE_ROOT_PATH + "/process-definition/statistics";
  protected static final String ACTIVITY_STATISTICS_URL = TEST_RESOURCE_ROOT_PATH + "/process-definition/{id}/statistics";
  protected static final String ACTIVITY_STATISTICS_BY_KEY_URL = TEST_RESOURCE_ROOT_PATH + "/process-definition/key/{key}/statistics";
  private ProcessDefinitionStatisticsQuery processDefinitionStatisticsQueryMock;
  private ActivityStatisticsQuery activityQueryMock;
  private ProcessDefinitionQuery processDefinitionQueryMock;

  @Before
  public void setUpRuntimeData() {
    setupProcessDefinitionStatisticsMock();
    setupActivityStatisticsMock();
    setupProcessDefinitionMock();
  }

  private void setupActivityStatisticsMock() {
    List<ActivityStatistics> mocks = MockProvider.createMockActivityStatistics();

    activityQueryMock = mock(ActivityStatisticsQuery.class);
    when(activityQueryMock.list()).thenReturn(mocks);
    when(processEngine.getManagementService().createActivityStatisticsQuery(any(String.class))).thenReturn(activityQueryMock);
  }

  private void setupProcessDefinitionStatisticsMock() {
    List<ProcessDefinitionStatistics> mocks = MockProvider.createMockProcessDefinitionStatistics();

    processDefinitionStatisticsQueryMock = mock(ProcessDefinitionStatisticsQuery.class);
    when(processDefinitionStatisticsQueryMock.list()).thenReturn(mocks);
    when(processEngine.getManagementService().createProcessDefinitionStatisticsQuery()).thenReturn(processDefinitionStatisticsQueryMock);
  }

  private void setupProcessDefinitionMock() {
    ProcessDefinition mockDefinition = MockProvider.createMockDefinition();
    processDefinitionQueryMock = mock(ProcessDefinitionQuery.class);
    when(processDefinitionQueryMock.processDefinitionKey(MockProvider.EXAMPLE_PROCESS_DEFINITION_KEY)).thenReturn(processDefinitionQueryMock);
    when(processDefinitionQueryMock.latestVersion()).thenReturn(processDefinitionQueryMock);
    when(processDefinitionQueryMock.singleResult()).thenReturn(mockDefinition);
    when(processDefinitionQueryMock.list()).thenReturn(Collections.singletonList(mockDefinition));
    when(processDefinitionQueryMock.count()).thenReturn(1L);
    when(processEngine.getRepositoryService().createProcessDefinitionQuery()).thenReturn(processDefinitionQueryMock);
  }

  @Test
  public void testStatisticsRetrievalPerProcessDefinitionVersion() {
    given()
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
      .body("$.size()", is(2))
      .body("definition.size()", is(2))
      .body("definition.id", hasItems(MockProvider.EXAMPLE_PROCESS_DEFINITION_ID, MockProvider.ANOTHER_EXAMPLE_PROCESS_DEFINITION_ID))
    .when().get(PROCESS_DEFINITION_STATISTICS_URL);
  }

  @Test
  public void testActivityStatisticsRetrieval() {
    given().pathParam("id", "aDefinitionId")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
      .body("$.size()", is(2))
      .body("id", hasItems(MockProvider.EXAMPLE_ACTIVITY_ID, MockProvider.ANOTHER_EXAMPLE_ACTIVITY_ID))
    .when().get(ACTIVITY_STATISTICS_URL);
  }

  @Test
  public void testActivityStatisticsRetrievalByKey() {
    given().pathParam("key", MockProvider.EXAMPLE_PROCESS_DEFINITION_KEY)
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
      .body("$.size()", is(2))
      .body("id", hasItems(MockProvider.EXAMPLE_ACTIVITY_ID, MockProvider.ANOTHER_EXAMPLE_ACTIVITY_ID))
    .when().get(ACTIVITY_STATISTICS_BY_KEY_URL);
  }

  @Test
  public void testAdditionalFailedJobsOption() {
    given().queryParam("failedJobs", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(PROCESS_DEFINITION_STATISTICS_URL);

    InOrder inOrder = Mockito.inOrder(processDefinitionStatisticsQueryMock);
    inOrder.verify(processDefinitionStatisticsQueryMock).includeFailedJobs();
    inOrder.verify(processDefinitionStatisticsQueryMock).list();
  }

  @Test
  public void testAdditionalIncidentsOption() {
    given().queryParam("incidents", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(PROCESS_DEFINITION_STATISTICS_URL);

    InOrder inOrder = Mockito.inOrder(processDefinitionStatisticsQueryMock);
    inOrder.verify(processDefinitionStatisticsQueryMock).includeIncidents();
    inOrder.verify(processDefinitionStatisticsQueryMock).list();
  }

  @Test
  public void testAdditionalIncidentsForTypeOption() {
    given().queryParam("incidentsForType", "failedJob")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(PROCESS_DEFINITION_STATISTICS_URL);

    InOrder inOrder = Mockito.inOrder(processDefinitionStatisticsQueryMock);
    inOrder.verify(processDefinitionStatisticsQueryMock).includeIncidentsForType("failedJob");
    inOrder.verify(processDefinitionStatisticsQueryMock).list();
  }

  @Test
  public void testAdditionalIncidentsAndFailedJobsOption() {
    given().queryParam("incidents", "true").queryParam("failedJobs", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(PROCESS_DEFINITION_STATISTICS_URL);

    InOrder inOrder = Mockito.inOrder(processDefinitionStatisticsQueryMock);
    inOrder.verify(processDefinitionStatisticsQueryMock).includeFailedJobs();
    inOrder.verify(processDefinitionStatisticsQueryMock).includeIncidents();
    inOrder.verify(processDefinitionStatisticsQueryMock).list();
  }

  @Test
  public void testAdditionalIncidentsForTypeAndFailedJobsOption() {
    given().queryParam("incidentsForType", "failedJob").queryParam("failedJobs", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(PROCESS_DEFINITION_STATISTICS_URL);

    InOrder inOrder = Mockito.inOrder(processDefinitionStatisticsQueryMock);
    inOrder.verify(processDefinitionStatisticsQueryMock).includeFailedJobs();
    inOrder.verify(processDefinitionStatisticsQueryMock).includeIncidentsForType("failedJob");
    inOrder.verify(processDefinitionStatisticsQueryMock).list();
  }

  @Test
  public void testAdditionalIncidentsAndIncidentsForType() {
    given().queryParam("incidents", "true").queryParam("incidentsForType", "anIncidentTpye")
    .then().expect()
      .statusCode(Status.BAD_REQUEST.getStatusCode())
    .when().get(PROCESS_DEFINITION_STATISTICS_URL);
  }

  @Test
  public void testActivityStatisticsWithFailedJobs() {
    given().pathParam("id", "aDefinitionId").queryParam("failedJobs", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_URL);

    InOrder inOrder = Mockito.inOrder(activityQueryMock);
    inOrder.verify(activityQueryMock).includeFailedJobs();
    inOrder.verify(activityQueryMock).list();
  }

  @Test
  public void testActivityStatisticsWithFailedJobsByKey() {
    given().pathParam("key", MockProvider.EXAMPLE_PROCESS_DEFINITION_KEY).queryParam("failedJobs", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_BY_KEY_URL);

    InOrder inOrder = Mockito.inOrder(activityQueryMock);
    inOrder.verify(activityQueryMock).includeFailedJobs();
    inOrder.verify(activityQueryMock).list();
  }

  @Test
  public void testActivityStatisticsWithIncidents() {
    given().pathParam("id", "aDefinitionId").queryParam("incidents", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_URL);

    InOrder inOrder = Mockito.inOrder(activityQueryMock);
    inOrder.verify(activityQueryMock).includeIncidents();
    inOrder.verify(activityQueryMock).list();
  }

  @Test
  public void testActivityStatisticsWithIncidentsByKey() {
    given().pathParam("key", MockProvider.EXAMPLE_PROCESS_DEFINITION_KEY).queryParam("incidents", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_BY_KEY_URL);

    InOrder inOrder = Mockito.inOrder(activityQueryMock);
    inOrder.verify(activityQueryMock).includeIncidents();
    inOrder.verify(activityQueryMock).list();
  }

  @Test
  public void testActivityStatisticsIncidentsForTypeTypeOption() {
    given().pathParam("id", "aDefinitionId").queryParam("incidentsForType", "failedJob")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_URL);

    InOrder inOrder = Mockito.inOrder(activityQueryMock);
    inOrder.verify(activityQueryMock).includeIncidentsForType("failedJob");
    inOrder.verify(activityQueryMock).list();
  }

  @Test
  public void testActivityStatisticsIncidentsForTypeTypeOptionByKey() {
    given().pathParam("key", MockProvider.EXAMPLE_PROCESS_DEFINITION_KEY).queryParam("incidentsForType", "failedJob")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_BY_KEY_URL);

    InOrder inOrder = Mockito.inOrder(activityQueryMock);
    inOrder.verify(activityQueryMock).includeIncidentsForType("failedJob");
    inOrder.verify(activityQueryMock).list();
  }

  @Test
  public void testActivtyStatisticsIncidentsAndFailedJobsOption() {
    given().pathParam("id", "aDefinitionId")
    .queryParam("incidents", "true").queryParam("failedJobs", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_URL);

    InOrder inOrder = Mockito.inOrder(activityQueryMock);
    inOrder.verify(activityQueryMock).includeFailedJobs();
    inOrder.verify(activityQueryMock).includeIncidents();
    inOrder.verify(activityQueryMock).list();
  }

  @Test
  public void testActivtyStatisticsIncidentsAndFailedJobsOptionByKey() {
    given().pathParam("key", MockProvider.EXAMPLE_PROCESS_DEFINITION_KEY)
    .queryParam("incidents", "true").queryParam("failedJobs", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_BY_KEY_URL);

    InOrder inOrder = Mockito.inOrder(activityQueryMock);
    inOrder.verify(activityQueryMock).includeFailedJobs();
    inOrder.verify(activityQueryMock).includeIncidents();
    inOrder.verify(activityQueryMock).list();
  }

  @Test
  public void testActivtyStatisticsIncidentsForTypeAndFailedJobsOption() {
    given().pathParam("id", "aDefinitionId")
    .queryParam("incidentsForType", "failedJob").queryParam("failedJobs", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_URL);

    InOrder inOrder = Mockito.inOrder(activityQueryMock);
    inOrder.verify(activityQueryMock).includeFailedJobs();
    inOrder.verify(activityQueryMock).includeIncidentsForType("failedJob");
    inOrder.verify(activityQueryMock).list();
  }

  @Test
  public void testActivtyStatisticsByIdThrowsAuthorizationException() {
    String message = "expected exception";
    when(activityQueryMock.list()).thenThrow(new AuthorizationException(message));

    given()
      .pathParam("id", "aDefinitionId")
    .then().expect()
      .statusCode(Status.FORBIDDEN.getStatusCode()).contentType(ContentType.JSON)
      .body("type", equalTo(AuthorizationException.class.getSimpleName()))
      .body("message", equalTo(message))
    .when()
      .get(ACTIVITY_STATISTICS_URL);
  }

  @Test
  public void testActivtyStatisticsIncidentsForTypeAndFailedJobsOptionByKey() {
    given().pathParam("key", MockProvider.EXAMPLE_PROCESS_DEFINITION_KEY)
    .queryParam("incidentsForType", "failedJob").queryParam("failedJobs", "true")
    .then().expect()
      .statusCode(Status.OK.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_BY_KEY_URL);

    InOrder inOrder = Mockito.inOrder(activityQueryMock);
    inOrder.verify(activityQueryMock).includeFailedJobs();
    inOrder.verify(activityQueryMock).includeIncidentsForType("failedJob");
    inOrder.verify(activityQueryMock).list();
  }

  @Test
  public void testActivtyStatisticsIncidentsAndIncidentsForType() {
    given().pathParam("id", "aDefinitionId")
    .queryParam("incidents", "true").queryParam("incidentsForType", "anIncidentTpye")
    .then().expect()
      .statusCode(Status.BAD_REQUEST.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_URL);
  }

  @Test
  public void testActivtyStatisticsIncidentsAndIncidentsForTypeByKey() {
    given().pathParam("key", MockProvider.EXAMPLE_PROCESS_DEFINITION_KEY)
    .queryParam("incidents", "true").queryParam("incidentsForType", "anIncidentTpye")
    .then().expect()
      .statusCode(Status.BAD_REQUEST.getStatusCode())
    .when().get(ACTIVITY_STATISTICS_BY_KEY_URL);
  }

  @Test
  public void testActivtyStatisticsByIdThrowsAuthorizationExceptionByKey() {
    String message = "expected exception";
    when(activityQueryMock.list()).thenThrow(new AuthorizationException(message));

    given()
      .pathParam("key", MockProvider.EXAMPLE_PROCESS_DEFINITION_KEY)
    .then().expect()
      .statusCode(Status.FORBIDDEN.getStatusCode()).contentType(ContentType.JSON)
      .body("type", equalTo(AuthorizationException.class.getSimpleName()))
      .body("message", equalTo(message))
    .when()
      .get(ACTIVITY_STATISTICS_BY_KEY_URL);
  }

}

redpajama_set_name: RedPajamaGithub


text:
module nid
{
    export var kEnd:number                     = 1;
    export var kHeader:number                  = 2;
    export var kArchiveProperties:number       = 3;
    export var kAdditionalStreamsInfo:number   = 4;
    export var kMainStreamsInfo:number         = 5;
    export var kFilesInfo:number               = 6;
    export var kPackInfo:number                = 7;
    export var kUnpackInfo:number              = 8;
    export var kSubStreamsInfo:number          = 9;
    export var kSize:number                    = 10;
    export var kCRC:number                     = 11;
    export var kFolder:number                  = 12;
    export var kCodersUnpackSize:number        = 13;
    export var kNumUnpackStream:number         = 14;
    export var kEmptyStream:number             = 14;
    export var kEmptyFile:number               = 15;
    export var kAnti:number                    = 16;
    export var kName:number                    = 17;
    export var kCTime:number                   = 18;
    export var kATime:number                   = 19;
    export var kMTime:number                   = 20;
    export var kWinAttributes:number           = 21;
    export var kComment:number                 = 22;
    export var kEncodedHeader:number           = 23;
    export var kStartPos:number                = 24;
    export var kDummy:number                   = 25;
}


text:
var assert = require('assert');

module.exports = function() {};

module.exports.prototype = {

    configure: function(requireLineFeedAtFileEnd) {
        assert(
            typeof requireLineFeedAtFileEnd === 'boolean',
            'requireLineFeedAtFileEnd option requires boolean value'
        );
        assert(
            requireLineFeedAtFileEnd === true,
            'requireLineFeedAtFileEnd option requires true value or should be removed'
        );
    },

    getOptionName: function() {
        return 'requireLineFeedAtFileEnd';
    },

    check: function(file, errors) {
        var lines = file.getLines();
        if (lines[lines.length - 1] !== '') {
            errors.add('Missing line feed at file end', lines.length, 0);
        }
    }

};


text:
<?php

assert_options(ASSERT_BAIL, 1);
define("ROOT", dirname(__FILE__));
define("BASENAME", basename(__FILE__, ".php"));

// LOAD PHABRICATOR

define("PHABRICATOR_ROOT", ROOT . "/../phabricator");
require_once PHABRICATOR_ROOT  . "/scripts/__init_script__.php";

// LOAD UTILITY FUNCTIONS

require_once ROOT . "/" . BASENAME . ".inc.php";

// LOAD CONFIG

require_once ROOT . "/" . BASENAME . ".cfg";

assert(LDAP_BASE !== null);
assert(LDAP_USER_SUBTREE !== null);
assert(LDAP_GROUP_SUBTREE !== null);

assert(LDAP_USER_FILTER !== null);
assert(LDAP_USER_NAME_ATTR !== null);
assert(LDAP_USER_MAIL_ATTR !== null);
assert(LDAP_USER_GROUP_ATTR !== null);
assert(LDAP_USER_GROUP_TRGT !== null);

assert(LDAP_GROUP_FILTER !== null);
assert(LDAP_GROUP_NAME_ATTR !== null);
assert(LDAP_GROUP_MEMBER_ATTR !== null);
assert(LDAP_GROUP_MEMBER_TRGT !== null);

assert(PHAB_ADMIN_USERNAME !== null);
assert(PHAB_PROJECT_LDAP_DN_FIELD !== null);
assert(PHAB_USER_LDAP_DN_FIELD !== null);
assert(PHAB_USER_ACCOUNT_TYPE !== null);

// With PHP7 this variable can be changed to a constant
assert($PHAB_PROTECTED_USERS !== null);

// LOAD CONNECTION INFO FROM ENVIRONMENT

$ldap_uri = getenv('LDAP_URI');
assert($ldap_uri !== false);
$ldap_binddn = getenv('LDAP_BINDDN');
$ldap_bindpw = getenv('LDAP_BINDPW');
assert(($ldap_binddn === false && $ldap_bindpw !== false) || ($ldap_binddn !== false && $ldap_bindpw !== false));

if (DRY_RUN) {
	debug(">>> DRY RUN <<<\n");
}

// LDAP

if ($ldap_binddn === false && $ldap_bindpw === false) {
	debug("Attempting anonymous bind ...\n");
	$ldap_binddn = NULL;
	$ldap_bindpw = NULL;
}

$ld = array(
	"connection" => create_ldap_connection($ldap_uri, $ldap_binddn, $ldap_bindpw),
	"base_dn" => LDAP_BASE,
	"user" => array(
		"search_base" => LDAP_BASE ? LDAP_USER_SUBTREE . ',' . LDAP_BASE : LDAP_USER_SUBTREE,
		"filter" => LDAP_USER_FILTER,
		"name_attr" => LDAP_USER_NAME_ATTR,
	),
	"group" => array(
		"search_base" => LDAP_BASE ? LDAP_GROUP_SUBTREE . ',' . LDAP_BASE : LDAP_GROUP_SUBTREE,
		"filter" => LDAP_GROUP_FILTER,
		"name_attr" => LDAP_GROUP_NAME_ATTR,
		"member_attr" => LDAP_GROUP_MEMBER_ATTR,
	),
);

$ldap_users = query_ldap($ld["connection"], $ld["user"]["search_base"], $ld["user"]["filter"]);
$ldap_users = associate_ldap_list_with_dn($ldap_users);

$ldap_groups = query_ldap($ld["connection"], $ld["group"]["search_base"], $ld["group"]["filter"]);
$ldap_groups = associate_ldap_list_with_dn($ldap_groups);

// PHABRICATOR

$phab_admin = id(new PhabricatorPeopleQuery())
	->setViewer(PhabricatorUser::getOmnipotentUser())
	->withUsernames(array(PHAB_ADMIN_USERNAME))
	->executeOne();
assert($phab_admin !== null);

$phab = array(
	"admin" => $phab_admin,
	"project_ldap_dn_field" => PHAB_PROJECT_LDAP_DN_FIELD,
	"user_ldap_dn_field" => PHAB_USER_LDAP_DN_FIELD,
	"user_account_type" => PHAB_USER_ACCOUNT_TYPE,
	// With PHP7 this variable can be changed to a constant
	"protected_users" => $PHAB_PROTECTED_USERS,
);

$phab_projects = id(new PhabricatorProjectQuery())
		->setViewer(PhabricatorUser::getOmnipotentUser())
		->needMembers(true)
		->execute();
$phab_projects = mpull($phab_projects, null, "getPHID");

$phab_accounts = id(new PhabricatorExternalAccountQuery())
		->setViewer(PhabricatorUser::getOmnipotentUser())
		->withAccountTypes(array(PHAB_USER_ACCOUNT_TYPE))
		->execute();
// FIXME: Useful at least for creating debug output! Should be provided to the update_* functions!
$phab_user_account_map = mpull($phab_accounts, null, "getuserPHID");

$user_map = map_users($phab_accounts, $ld);
$project_map = map_projects($phab_projects, $phab);

update_phab_users($user_map, $ldap_users, $ld, $phab);

update_phab_projects($project_map, $ldap_groups, $ld, $phab);

$phab_projects = id(new PhabricatorProjectQuery())
		->setViewer(PhabricatorUser::getOmnipotentUser())
		->needMembers(true)
		->execute();
$phab_projects = mpull($phab_projects, null, "getPHID");

// Recreate user/project maps and ignore those missing in LDAP
$user_map = map_users($phab_accounts, $ld, false);
$project_map = map_projects($phab_projects, $phab);

update_phab_project_members($project_map, $user_map, $phab_projects, $ldap_groups, $ld, $phab);


text:
git add -A .
git commit -m "."
git push


text:
package mocks

import (
	"unsafe"

	mock "github.com/stretchr/testify/mock"
)

// UnsafeInterface is an autogenerated mock type for the UnsafeInterface type
type UnsafeInterface struct {
	mock.Mock
}

// Do provides a mock function with given fields: ptr
func (_m *UnsafeInterface) Do(ptr *unsafe.Pointer) {
	_m.Called(ptr)
}

type mockConstructorTestingTNewUnsafeInterface interface {
	mock.TestingT
	Cleanup(func())
}

// NewUnsafeInterface creates a new instance of UnsafeInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewUnsafeInterface(t mockConstructorTestingTNewUnsafeInterface) *UnsafeInterface {
	mock := &UnsafeInterface{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}


text:
#include "map.h"

#include "../core/global.h"
#include "../util/path.h"

/*!
 * @author kovlev
 */

Map::Map() {
	tileMapPath = "data/map/tilemap.data";
	tileMapCodesPath = "data/map/tilemapcodes.data";

	loadTileMap();

	//NOTE ugly solution but i could not come up with a better idea
	getTile(Global::player->getPosition())->entities.push_back(Global::player);

	allowDebug = false;
	allowCoordinateRendering = false;

	displayInfo = NULL;
	displayInfoPos = Point::INVALID;
	displayDim = Dimension(500, 200);
}

Map::~Map() {
	//delete tilemap
	for (int i = 0; i < width; i++) {
		for (int j = 0; j < height; j++) {
			delete tiles[i][j];
		}
	}

	for (int i = 0; i < width; i++) {
		delete[] tiles[i];
	}

	delete[] tiles;
}

int Map::getWidth() {
	return width;
}

int Map::getHeight() {
	return height;
}

int Map::getSize() {
	return size;
}

Tile* Map::getTile(int x, int y) {
	//Index checking
	if (x < 0 || x >= width || y < 0 || y >= height) {
		return NULL;
	}
	return tiles[x][y];
}

Tile* Map::getTile(Point pos) {
	return getTile(pos.getX(), pos.getY());
}

Army* Map::getDisplayInfo() {
	return displayInfo;
}

Point Map::getDisplayInfoPos() {
	return displayInfoPos;
}

void Map::setDisplayInfo(Army* newDisplayInfo) {
	displayInfo = newDisplayInfo;
}

void Map::setDisplayInfoPos(Point newDisplayInfoPos) {
	displayInfoPos = newDisplayInfoPos;
}

void Map::render() {
	//We can set the rendering order here

	//Render every layer
	//It does not render the whole map
	renderTileMap();
	renderMapEntities();

	//We only render the player's planned path, if we have one
	if (Global::player->getHasPlannedPath()) {
		renderPath();
	}

	//DEBUG stuff
	if (allowDebug) {
		renderPassabilityDebugInfo();
	}

	if (allowCoordinateRendering) {
		renderTileCoordinates();
	}

	//Army info if struct or npc is right clicked
	if (displayInfo != NULL) {
		renderDisplayInfo();
	}
}

Point Map::getTileFromCursorPosition(Point cursorPosition) {
	//If we pass an invalid cursor position we return Point::INVALID
	if (cursorPosition.getX() < 0 ||
		cursorPosition.getX() >= Global::screenWidth ||
		cursorPosition.getY() < 0 ||
		cursorPosition.getY() >= Global::screenHeight) {
		return Point::INVALID;
	}

	Point positionOnFullPixmap = Global::camera->getPosition() + cursorPosition;

	return positionOnFullPixmap / Global::tileSize;
}

NPC* Map::getNPCOnTile(int x, int y) {
	return getNPCOnTile(Point(x, y));
}

NPC* Map::getNPCOnTile(Point tilePos) {
	if (getTile(tilePos) != NULL) {
		return getNPCOnTile(getTile(tilePos));
	}
	return NULL;
}

NPC* Map::getNPCOnTile(Tile* tile) {
	//We travesrse through the entities list and return the first npc item
	for (unsigned int i = 0; i < tile->entities.size(); i++) {
		NPC* possibleNPC = dynamic_cast<NPC*>(tile->entities[i]);
		if (possibleNPC != NULL) {
			return possibleNPC;
		}
	}
	return NULL;
}

InteractiveWorldObject* Map::getInteractiveOnTile(int x, int y) {
	return getInteractiveOnTile(Point(x, y));
}

InteractiveWorldObject* Map::getInteractiveOnTile(Point tilePos) {
	if (getTile(tilePos) != NULL) {
		return getInteractiveOnTile(getTile(tilePos));
	}
	return NULL;
}

InteractiveWorldObject* Map::getInteractiveOnTile(Tile* tile) {
	return tile->getInterOnTile();
}

bool Map::getAllowDebug() {
	return allowDebug;
}

void Map::setAllowDebug(bool newAllowDebug) {
	allowDebug = newAllowDebug;
}

bool Map::getAllowCoordinateRendering() {
	return allowCoordinateRendering;
}

void Map::setAllowCoordinateRendering(bool newAllowCoordinateRendering) {
	allowCoordinateRendering = newAllowCoordinateRendering;
}

void Map::renderTileMap() {
	//Needed becase threading
	Point camPos = Global::camera->getPosition();

	//We only render visible tiles
	Point startTileCoordinates = Point(camPos.getX() / Global::tileSize, camPos.getY() / Global::tileSize);
	Point endTileCoordinates = Point((camPos.getX() + Global::screenWidth) / Global::tileSize + 1, (camPos.getY() + Global::screenHeight) / Global::tileSize + 1);

	for (int i = startTileCoordinates.getX(); i <= endTileCoordinates.getX(); i++) {
		for (int j = startTileCoordinates.getY(); j <= endTileCoordinates.getY(); j++) {
			//If Tile does not exist, we do not render it
			//NOTE this should be unnecessary later since we will fix the camera position
			if (getTile(i, j) == NULL) {
				continue;
			}

			//Setting rectangle
			SDL_Rect destinationRect;
			destinationRect.x = i * Global::tileSize - camPos.getX();
			destinationRect.y = j * Global::tileSize - camPos.getY();
			//tileSize is a double now
			destinationRect.w = std::ceil(Global::tileSize);
			destinationRect.h = std::ceil(Global::tileSize);
			getTile(i, j)->texture->render(destinationRect);
		}
	}
}

void Map::renderMapEntities() {
	//Needed becase threading
	Point camPos = Global::camera->getPosition();

	//We only render obects on visible tiles
	Point startTileCoordinates = Point(camPos.getX() / Global::tileSize, camPos.getY() / Global::tileSize);
	Point endTileCoordinates = Point((camPos.getX() + Global::screenWidth) / Global::tileSize + 1, (camPos.getY() + Global::screenHeight) / Global::tileSize + 1);

	for (int stage = 2; stage <= 3; stage++) {
		for (int i = startTileCoordinates.getY(); i <= endTileCoordinates.getY(); i++) {
			for (int j = startTileCoordinates.getX(); j <= endTileCoordinates.getX(); j++) {
				Tile* current = getTile(j, i);

				//If Tile does not exist, we do not render it
				//NOTE this should be unnecessary later since we will fix the camera position
				if (current == NULL) {
					continue;
				}
				if (stage == 2) {
					for (unsigned int k = 0; k < current->backgroundEntities.size(); k++) {
						//currEnt get it?:D
						MapEntity* currEnt = current->backgroundEntities[k];

						//NULL-checking
						if (currEnt == NULL) {
							continue;
						}

						Dimension d = currEnt->texture->getDimensions();

						//Setting rectangle
						SDL_Rect destinationRect;

						//We are setting the width and the height first
						//Ugly casting becasue scale is a double member
						destinationRect.w = (int)(((double)d.W() * Global::tileSize / 64) * currEnt->getScale());
						destinationRect.h = (int)(((double)d.H() * Global::tileSize / 64) * currEnt->getScale());

						//Every rectangle looks like this:
						// 123
						// 4 5
						// 678
						//By default we are fixing the '7' points (down-center)
						//So the texture's down-center point will be at the same position as its tile's

						//The top-left corner of its tile
						destinationRect.x = currEnt->getPosition().getX() * Global::tileSize - camPos.getX();
						destinationRect.y = currEnt->getPosition().getY() * Global::tileSize - camPos.getY();

						//We need to move this point with a vector
						destinationRect.x -= (destinationRect.w - Global::tileSize) / 2;
						destinationRect.y -= destinationRect.h - Global::tileSize;

						currEnt->texture->render(destinationRect);
					}
				} else {
					for (unsigned int k = 0; k < current->entities.size(); k++) {
						//currEnt get it?:D
						MapEntity* currEnt = current->entities[k];

						//NULL-checking
						if (currEnt == NULL) {
							continue;
						}

						Dimension d = currEnt->texture->getDimensions();

						//Setting rectangle
						SDL_Rect destinationRect;

						//We are setting the width and the height first
						//Ugly casting becasue scale is a double member
						destinationRect.w = (int)(((double)d.W() * Global::tileSize / 64) * currEnt->getScale());
						destinationRect.h = (int)(((double)d.H() * Global::tileSize / 64) * currEnt->getScale());

						//Every rectangle looks like this:
						// 123
						// 4 5
						// 678
						//By default we are fixing the '7' points (down-center)
						//So the texture's down-center point will be at the same position as its tile's

						//The top-left corner of its tile
						destinationRect.x = currEnt->getPosition().getX() * Global::tileSize - camPos.getX();
						destinationRect.y = currEnt->getPosition().getY() * Global::tileSize - camPos.getY();

						//We need to move this point with a vector
						destinationRect.x -= (destinationRect.w - Global::tileSize) / 2;
						destinationRect.y -= destinationRect.h - Global::tileSize;

						//If the entity is an npc or a player, we add the progressvector
						if (currEnt == Global::player) {
							destinationRect.x += Global::player->getProgressVector().getX() * Global::tileSize;
							destinationRect.y += Global::player->getProgressVector().getY() * Global::tileSize;
						}
						NPC* possibleNPC = dynamic_cast<NPC*>(currEnt);
						if (possibleNPC != NULL && possibleNPC->getMovementType() != NPCMovement::STANDING) {
							if (possibleNPC->getPath() == NULL) continue; //Ugly threading strikes again
							PointD corrigation = (possibleNPC->getPath()->current() - possibleNPC->getPosition()) * Global::tileSize;

							destinationRect.x += possibleNPC->getProgressVector().getX() * Global::tileSize;
							destinationRect.x += corrigation.getX();
							destinationRect.y += possibleNPC->getProgressVector().getY() * Global::tileSize;
							destinationRect.y += corrigation.getY();
						}

						currEnt->texture->render(destinationRect);
					}
				}
			}
		}
	}
}

void Map::renderPath() {
	SDL_Rect destinationRect;
	destinationRect.w = Global::tileSize;
	destinationRect.h = Global::tileSize;
	//We render only the remaining part of the path
	for (unsigned int i = Global::player->getTileProgress() == 0 ? 1 : Global::player->getTileProgress() + 1; i < Global::player->getPath().size()-1; i++) {

		Point thisPoint = Global::player->getPath()[i];
		Point nextPoint = Global::player->getPath()[i + 1];
		Point diff = nextPoint - thisPoint;

		//We do not render the path over interactive objects
		if (getTile(thisPoint)->getTileInfo() != TileInfo::FREE) continue;

		ATexture* texture;

		if (diff == Point(1, -1)) {
			//Up right
			texture = Global::resourceHandler->getATexture(TT::PATH, "upright");
		} else if (diff == Point(1, 0)) {
			//Right
			texture = Global::resourceHandler->getATexture(TT::PATH, "right");
		} else if (diff == Point(1, 1)) {
			//Down right
			texture = Global::resourceHandler->getATexture(TT::PATH, "downright");
		} else if (diff == Point(0, 1)) {
			//Down
			texture = Global::resourceHandler->getATexture(TT::PATH, "down");
		} else if (diff == Point(-1, 1)) {
			//Down left
			texture = Global::resourceHandler->getATexture(TT::PATH, "downleft");
		} else if (diff == Point(-1, 0)) {
			//Left
			texture = Global::resourceHandler->getATexture(TT::PATH, "left");
		} else if (diff == Point(-1, -1)) {
			//Up left
			texture = Global::resourceHandler->getATexture(TT::PATH, "upleft");
		} else if (diff == Point(0, -1)) {
			//Up
			texture = Global::resourceHandler->getATexture(TT::PATH, "up");
		} else {
			std::clog << "Warning: Path rendering bug" << std::endl;
			return;
		}

		//Setting renctangle
		destinationRect.x = thisPoint.getX() * Global::tileSize - Global::camera->getPosition().getX();
		destinationRect.y = thisPoint.getY() * Global::tileSize - Global::camera->getPosition().getY();
		texture->render(destinationRect);
	}

	//Destination tile
	destinationRect.x = Global::player->getPath()[Global::player->getPath().size() - 1].getX() * Global::tileSize - Global::camera->getPosition().getX();
	destinationRect.y = Global::player->getPath()[Global::player->getPath().size() - 1].getY() * Global::tileSize - Global::camera->getPosition().getY();
	Global::resourceHandler->getATexture(TT::PATH, "destination")->render(destinationRect);
}

void Map::renderDisplayInfo() {
	//Setting rectangle
	SDL_Rect destinationRect;
	destinationRect.x = displayInfoPos.getX() * Global::tileSize - Global::camera->getPosition().getX() + Global::tileSize / 2 - displayDim.W() / 2;
	destinationRect.y = displayInfoPos.getY() * Global::tileSize - Global::camera->getPosition().getY() - displayDim.H();
	destinationRect.w = displayDim.W();
	destinationRect.h = displayDim.H();

	//Correcting destinationRect if needed
	if (displayInfoPos.getX() * Global::tileSize + Global::tileSize / 2 - displayDim.W() / 2 < 0) {
		destinationRect.x -= displayInfoPos.getX() * Global::tileSize + Global::tileSize / 2 - displayDim.W() / 2;
	}
	if (displayInfoPos.getX() * Global::tileSize + Global::tileSize / 2 - displayDim.W() / 2 + displayDim.W() > Global::screenWidth) {
		destinationRect.x -= displayInfoPos.getX() * Global::tileSize + Global::tileSize / 2 - displayDim.W() / 2 + displayDim.W() - Global::screenWidth;
	}
	if (displayInfoPos.getY() * Global::tileSize - displayDim.H() < 0) {
		destinationRect.y -= displayInfoPos.getY() * Global::tileSize - displayDim.H();
	}

	for (int i = 0; i < displayInfo->getWidth(); i++) {
		for (int j = 0; j < displayInfo->getHeight(); j++) {
			Unit* currentUnit = displayInfo->getUnit(i, j);
			SDL_Rect unitRect = destinationRect;
			unitRect.x += i * 100;
			unitRect.y += j * 100;
			unitRect.w = 100;
			unitRect.h = 100;
			if (currentUnit != NULL && !currentUnit->isDead()) {
				currentUnit->render(unitRect);
			} else {
				switch (displayInfo->getUPFromPos(i, j)) {
					case UnitPosition::FRONTROW:
						Global::resourceHandler->getATexture(TT::GUI, "armyslotbg_front")->render(unitRect);
						break;
					case UnitPosition::BACKROW:
						Global::resourceHandler->getATexture(TT::GUI, "armyslotbg_back")->render(unitRect);
						break;
					case UnitPosition::SUPPORT:
						Global::resourceHandler->getATexture(TT::GUI, "armyslotbg_support")->render(unitRect);
						break;
				}
			}
		}
	}
}

void Map::loadTileMap() {
	std::fstream file;

	//Loads the codes for the tilemap
	std::map<int, std::string> tileMapCodes;
	file.open(tileMapCodesPath, std::ios::in);
	file >> width;
	file >> height;

	//We load the maps dimensions first
	Global::gameBoardWidth = width;
	Global::gameBoardHeight = height;
	size = width * height;

	//Generating the tile arrays
	tiles = new Tile**[width];
	for (int i = 0; i < width; ++i) {
		tiles[i] = new Tile*[height];
	}

	std::string isImpassable;
	int tileCode;
	std::string tileName;
	while (file >> isImpassable && file >> tileCode && file >> std::quoted(tileName)) {
		tileMapCodes[tileCode] = tileName;
		if (isImpassable == "x" || isImpassable == "X") {
			baseImpassable.push_back(tileName);
		}
	}
	file.close();

	//Loads the actual tilemap
	file.open(tileMapPath, std::ios::in);

	//Initializing the contents of the 2D array
	for (int i = 0; i < height; i++) {
		for (int j = 0; j < width; j++) {
			int tempType;
			file >> tempType;
			tiles[j][i] = new Tile(tileMapCodes[tempType]);
		}
	}
	if (!file) {
		//std::clog << "Warning: Map might be corrupted" << std::endl;
	}
	file.close();
}

void Map::createPassabilityMap() {

	//Setting impassables
	for (unsigned int i = 0; i < Global::worldObjectHandler->impassables.size(); i++) {
		ImpassableWorldObject* tempImpassableObject = Global::worldObjectHandler->impassables[i];
		for (unsigned int j = 0; j < tempImpassableObject->getImpassableTiles().size(); j++) {
			Point absolute = tempImpassableObject->getImpassableTiles()[j] + tempImpassableObject->getPosition();

			//in case the object extends beyond the borders of the map
			if (getTile(absolute) == NULL) continue;

			getTile(absolute)->setTileInfo(TileInfo::IMPASSABLE);
		}
	}

	//Setting interactives
	for (unsigned int i = 0; i < Global::worldObjectHandler->interactives.size(); i++) {
		InteractiveWorldObject* tempInteractiveObject = Global::worldObjectHandler->interactives[i];
		for (unsigned int j = 0; j < tempInteractiveObject->getInteractiveTiles().size(); j++) {
			Point absolute = tempInteractiveObject->getInteractiveTiles()[j] + tempInteractiveObject->getPosition();

			//in case the object extends beyond the borders of the map
			if (getTile(absolute) == NULL) continue;

			getTile(absolute)->setTileInfo(TileInfo::INTERACTIVE);
			getTile(absolute)->setInterOnTile(tempInteractiveObject);
		}
	}

	//Some tiles are impassable eventough we do not place terrain objects on the top of them
	for (int i = 0; i < width; i++) {
		for (int j = 0; j < height; j++) {
			if (std::find(baseImpassable.begin(), baseImpassable.end(), getTile(i, j)->getType()) != baseImpassable.end()) {
				getTile(i, j)->setTileInfo(TileInfo::IMPASSABLE);
			}
		}
	}
}

bool Map::isTileVisible(int x, int y) {
	if (Global::camera->getPosition().getX() / Global::tileSize <= x &&
		Global::camera->getPosition().getY() / Global::tileSize <= y &&
		(Global::camera->getPosition().getX() + Global::screenWidth) / Global::tileSize + 1 >= x &&
		(Global::camera->getPosition().getY() + Global::screenHeight) / Global::tileSize + 1 >= y) {

		return true;
	}
	return false;
}

bool Map::isTileVisible(Point tPos) {
	return isTileVisible(tPos.getX(), tPos.getY());
}

void Map::renderPassabilityDebugInfo() {
	//Same as the normal tilerendering
	Point startTileCoordinates = Point(Global::camera->getPosition().getX() / Global::tileSize, Global::camera->getPosition().getY() / Global::tileSize);
	Point endTileCoordinates = Point((Global::camera->getPosition().getX() + Global::screenWidth) / Global::tileSize + 1, (Global::camera->getPosition().getY() + Global::screenHeight) / Global::tileSize + 1);

	for (int i = startTileCoordinates.getX(); i <= endTileCoordinates.getX(); i++) {
		for (int j = startTileCoordinates.getY(); j <= endTileCoordinates.getY(); j++) {
			if (getTile(i, j) == NULL) {
				continue;
			}

			//Setting rectangle
			SDL_Rect destinationRect;
			destinationRect.x = i * Global::tileSize - Global::camera->getPosition().getX();
			destinationRect.y = j * Global::tileSize - Global::camera->getPosition().getY();
			destinationRect.w = Global::tileSize;
			destinationRect.h = Global::tileSize;

			//sets the color of the rect
			if (getTile(i, j)->getTileInfo() == TileInfo::FREE) {
				//Green
				SDL_SetRenderDrawColor(Global::renderer, 0x00, 0xDD, 0x00, 0x00);
			} else if (getTile(i, j)->getTileInfo() == TileInfo::IMPASSABLE) {
				//Red
				SDL_SetRenderDrawColor(Global::renderer, 0xDD, 0x00, 0x00, 0xAF);
			} else {
				//Yellow
				SDL_SetRenderDrawColor(Global::renderer, 0xDD, 0xDD, 0x00, 0xAF);
			}

			SDL_RenderFillRect(Global::renderer, &destinationRect);
		}
	}
}

void Map::renderTileCoordinates() {
	//Same as the normal tilerendering
	Point startTileCoordinates = Point(Global::camera->getPosition().getX() / Global::tileSize, Global::camera->getPosition().getY() / Global::tileSize);
	Point endTileCoordinates = Point((Global::camera->getPosition().getX() + Global::screenWidth) / Global::tileSize + 1, (Global::camera->getPosition().getY() + Global::screenHeight) / Global::tileSize + 1);

	for (int i = startTileCoordinates.getX(); i <= endTileCoordinates.getX(); i++) {
		for (int j = startTileCoordinates.getY(); j <= endTileCoordinates.getY(); j++) {
			if (getTile(i, j) == NULL) {
				continue;
			}

			SDL_SetRenderDrawColor(Global::renderer, 0xFF, 0xFF, 0xFF, 0xFF);
			SDL_RenderDrawLine(Global::renderer,
				i * Global::tileSize - Global::camera->getPosition().getX(),
				Global::permaGUI->getUpperHeight(),
				i * Global::tileSize - Global::camera->getPosition().getX(),
				Global::screenHeight - Global::permaGUI->getLowerHeight()
			);

			SDL_RenderDrawLine(Global::renderer,
				0,
				j * Global::tileSize - Global::camera->getPosition().getY(),
				Global::screenWidth,
				j * Global::tileSize - Global::camera->getPosition().getY()
			);

			int textSize = Global::tileSize / 4;

			ATexture* textTextureX = Global::resourceHandler->getTextTexture(std::to_string(i), Global::resourceHandler->getColor("debug-coord"), textSize);
			Dimension d = textTextureX->getDimensions();

			//Setting rectangle
			SDL_Rect destinationRect;
			destinationRect.x = i * Global::tileSize - Global::camera->getPosition().getX() + Global::tileSize / 2 - d.W() / 2;
			destinationRect.y = j * Global::tileSize - Global::camera->getPosition().getY() + Global::tileSize / 4 - d.H() / 2;
			destinationRect.w = d.W();
			destinationRect.h = d.H();

			textTextureX->render(destinationRect);

			ATexture* textTextureY = Global::resourceHandler->getTextTexture(std::to_string(j), Global::resourceHandler->getColor("debug-coord"), textSize);
			d = textTextureY->getDimensions();

			//Setting rectangle
			destinationRect.x = i * Global::tileSize - Global::camera->getPosition().getX() + Global::tileSize / 2 - d.W() / 2;
			destinationRect.y = j * Global::tileSize - Global::camera->getPosition().getY() + Global::tileSize * 3 / 4 - d.H() / 2;
			destinationRect.w = d.W();
			destinationRect.h = d.H();

			textTextureY->render(destinationRect);
		}
	}
}


text:
@implementation LCSearchResultsTableViewController

@synthesize bookLookup = _bookLookup;
@synthesize delegate = _delegate;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad {
    [super viewDidLoad];

    self.clearsSelectionOnViewWillAppear = NO;

}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        return YES;
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)bookLookupGotResults:(LCBookLookup *)bookLookup {
    [self.tableView reloadData];
}

- (void)bookLookup:(LCBookLookup *)bookLookup downloadedCoverAtIndex:(NSInteger)index {
    if (index >= [self.bookLookup.results count])
        return;

    NSIndexPath * indexPath = [NSIndexPath indexPathForRow:index inSection:0];
    [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                          withRowAnimation:UITableViewRowAnimationNone];

}

- (IBAction)cancel:(id)sender {
    [self.delegate searchResultsControllerCanceled];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    DEBUG(@"Number of Books: %d", [self.bookLookup.results count]);
    DEBUG(@"Number of Results: %d", self.bookLookup.numberOfResults);

    // Add one to the number of available results if the total number of items in Google Books
    // exceeds the available number we've downloaded so far.
    if ([self.bookLookup.results count] < self.bookLookup.numberOfResults)
        return [self.bookLookup.results count] + 1;

    return [self.bookLookup.results count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString * BookCellIdentifier = @"BookSearchListCell";
    static NSString * ActivityCellIndicator = @"LoadingResultsCell";

    if ([self.bookLookup.results count] == indexPath.row) {
        // we do not have this row in our results. Fetch it and display an activity row.
        UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:ActivityCellIndicator];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ActivityCellIndicator];
        }
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        return cell;

    }

    NSDictionary * bookInfo = [self.bookLookup.results objectAtIndex:indexPath.row];

    LCBookCell * cell = (LCBookCell *)[tableView dequeueReusableCellWithIdentifier:BookCellIdentifier];
    if (cell == nil) {
        cell = (LCBookCell *)[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:BookCellIdentifier];
    }

    cell.titleLabel.text = [bookInfo objectForKey:@"title"];
    cell.authorLabel.text = [bookInfo objectForKey:@"authors"];

    if ([bookInfo objectForKey:@"publishedDate"] != nil) {
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        dateFormatter.dateFormat = @"YYYY";

        NSString * formattedDateString = [dateFormatter stringFromDate:[bookInfo objectForKey:@"publishedDate"]];
        cell.publishedLabel.text = formattedDateString;
    }

    NSString * coverPath = pathToCoverForISBN([bookInfo objectForKey:@"isbn13"]);
    if ([[NSFileManager defaultManager] fileExistsAtPath:coverPath])
        cell.coverImageView.image = [UIImage imageWithContentsOfFile:coverPath];
    else {
        cell.coverImageView.image = [UIImage imageNamed:@"cover.png"];
        [self.bookLookup downloadCoverImageForIndex:indexPath.row];
    }

    return cell;

}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSDictionary * bookInfo = [self.bookLookup.results objectAtIndex:indexPath.row];
    [self.delegate searchResultsControllerSelectedBook:bookInfo];
}

#pragma mark - Scroll View Delegate

// http://stackoverflow.com/questions/5137943/how-to-know-when-uitableview-did-scroll-to-bottom
- (void)scrollViewDidScroll:(UIScrollView *)aScrollView {
    CGPoint offset = aScrollView.contentOffset;
    CGRect bounds = aScrollView.bounds;
    CGSize size = aScrollView.contentSize;
    UIEdgeInsets inset = aScrollView.contentInset;
    float y = offset.y + bounds.size.height - inset.bottom;
    float h = size.height;
    // NSLog(@"offset: %f", offset.y);
    // NSLog(@"content.height: %f", size.height);
    // NSLog(@"bounds.height: %f", bounds.size.height);
    // NSLog(@"inset.top: %f", inset.top);
    // NSLog(@"inset.bottom: %f", inset.bottom);
    // NSLog(@"pos: %f of %f", y, h);

    float reload_distance = 10;
    if(y > h + reload_distance) {
        // NSLog(@"load more rows");
        [self.bookLookup loadMoreResults];
    }

}

@end


text:
<?xml version="1.0" encoding="utf-8"?>
<skin>
  <meta name="name" value="silva" />
  <meta name="developer" value="Raimund Meyer" />
  <meta name="developer_url" value="http://x-webservice.net" />
  <meta name="sponsor" value="" />
  <meta name="sponsor_url" value="" />
  <meta name="version" value="1.0" />
  <meta name="license" value="htmlArea" />
  <recommendedIcons>Crystal</recommendedIcons>
</skin>


text:
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>or-tools/examples/cpp/golomb.cc File Reference - Doxy</title>
    <link rel="shortcut icon" href="../../../favicon.ico">

    <link href="../../../doxygen.css" rel="stylesheet" type="text/css">
    <link href="../../../tabs.css" rel="stylesheet" type="text/css">

          Generated on: Thu Mar 29 07:46:58 PDT 2012
            for custom file set

        <tt>//
            doxy/
            or-tools/
            examples/
            cpp/
            </tt>

Main Page

Related Pages

Namespaces

Classes

Files

or-tools/examples/cpp/golomb.cc File Reference
#include <cstdio>

#include "base/commandlineflags.h"

#include "base/integral_types.h"

#include "base/logging.h"

#include "base/scoped_ptr.h"

#include "base/stringprintf.h"

#include "constraint_solver/constraint_solver.h"

Go to the source code of this file.

Namespaces

namespace  	operations_research

Functions

 	DEFINE_bool (print, false,"If true, print the minimal solution.")

 	Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.

 	DEFINE_int32 (size, 0,"Size of the problem. If equal to 0, will test several increasing sizes.")

void 	operations_research::GolombRuler (int size)

int 	main (int argc, char **argv)

 	namespace operations_research

Variables

static const int 	kBestSolutions []

static const int 	kKnownSolutions = 19

Function Documentation

          DEFINE_bool
          (
          print
          ,

          false
          ,

          "If
           true,

          print the minimal solution."

          )

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.

Golomb ruler problem

find minimal ruler so that the differences between ticks are unique.

First solutions: 0, 1 0, 1, 3 0, 1, 4, 6 0, 1, 4, 9, 11 0, 1, 4, 10, 12, 17 0, 1, 4, 10, 18, 23, 25

          DEFINE_int32
          (
          size
          ,

          0
          ,

          "Size of the problem. If equal to
           0,

          will test several increasing sizes."

          )

          int main
          (
          int
           argc,

          char **
           argv

          )

namespace operations_research

Definition at line 97 of file golomb.cc.

Variable Documentation

          const int kBestSolutions[] [static]

Initial value:

 {
  0, 1, 3, 6, 11, 17, 25, 34, 44, 55, 72, 85,

  106, 127, 151, 177, 199, 216, 246
}

Definition at line 40 of file golomb.cc.

          const int kKnownSolutions = 19 [static]

Definition at line 46 of file golomb.cc.


text:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

	<context:component-scan base-package="org.kay" />
	<context:annotation-config />

	<mvc:default-servlet-handler />
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />

	<!-- 配置JSON全局日期转换 -->
	<mvc:annotation-driven>
		<mvc:message-converters>
			<bean
				class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
				<property name="objectMapper">
					<bean class="org.codehaus.jackson.map.ObjectMapper">
						<property name="dateFormat">
							<bean class="java.text.SimpleDateFormat">
								<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss"></constructor-arg>
							</bean>
						</property>
					</bean>
				</property>
			</bean>
		</mvc:message-converters>
	</mvc:annotation-driven>

	<!-- RESOLVES CONFIG -->

	<!-- 文件上传 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
		p:maxUploadSize="500000" />

	<!-- JSP ViewResolver.-->
	<!--
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver"
		p:viewClass="org.springframework.web.servlet.view.JstlView"
		p:prefix="/WEB-INF/jsp/"
		p:suffix=".jsp" />
	-->

	<!-- Jasper Report ViewResolver. -->
	<!--
	<bean class="org.springframework.web.servlet.view.XmlViewResolver"
		p:location="/WEB-INF/report-views.xml" p:order="0" />
	-->

	<!-- Freemarker ViewResolver. -->
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"
		p:viewClass="org.kay.sattan.web.framework.ExtFreeMarkerView"
		p:contentType="text/html;charset=UTF-8"
		p:exposeRequestAttributes="true"
        p:exposeSessionAttributes="true"
        p:exposeSpringMacroHelpers="true"
		p:suffix=".ftl" />

	<bean id="freemarkerConfig"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<property name="templateLoaderPath" value="/WEB-INF/freemarker/" />
		<property name="defaultEncoding" value="utf-8" />
		<property name="freemarkerSettings">
			<props>
				<prop key="number_format">0</prop>
				<prop key="template_update_delay">10</prop>
				<prop key="locale">zh_CN</prop>
				<prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
                <prop key="date_format">yyyy-MM-dd</prop>
                <prop key="number_format">#.##</prop>
			</props>
		</property>
	</bean>
</beans>


text:
import { boughtContractsSelector, portfolioSelector, ticksSelector } from '../_store/directSelectors';
import { createSelector, createStructuredSelector } from 'reselect';

const activeOpenContractSelector = createSelector(
    boughtContractsSelector,
    boughtContracts =>
        /**
         * check 'contract_id' is a synchronization, as contracts is combination of 2 data point,
         * transaction_id is from transactions stream, the rest from open contract stream
         * this check ensure open contract response is received before rendering,
         * but does not ensure `transaction_id` is sync
         */
        boughtContracts
            .filter(c => !c.get('sell_price') && c.get('contract_id'))
);

export const indicativeTotalSelector = createSelector(
    activeOpenContractSelector,
    contracts =>
        contracts
            .map(x => +x.get('bid_price'))
            .reduce((x, y) => x + y, 0)
);

export const purchaseTotalSelector = createSelector(
    activeOpenContractSelector,
    contracts =>
        contracts
            .map(x => +x.get('buy_price'))
            .reduce((x, y) => x + y, 0)
);

export default createStructuredSelector({
    ticks: ticksSelector,
    contracts: activeOpenContractSelector,
    portfolio: portfolioSelector,
    purchaseTotal: purchaseTotalSelector,
    indicativeTotal: indicativeTotalSelector,
});


text:
using System.Reflection;

[assembly: AssemblyTitle("xUnit.BDDExtensions.MVC.Specs.dll")]


text:
title: "Web UI configuration reference"
linkTitle: "Web UI Configuration Reference"
reference_title: "Web UI configuration"
type: "reference"
description: "Sensu's web UI configuration feature allows you to customize your web UI displays. Read the reference to create and update web UI configurations."
weight: 150
version: "6.7"
product: "Sensu Go"
menu:
  sensu-go-6.7:
    parent: web-ui
---

{{% notice commercial %}}
**COMMERCIAL FEATURE**: Access web UI configuration in the packaged Sensu Go distribution.
For more information, read [Get started with commercial features](../../commercial/).
{{% /notice %}}

Web UI configuration allows you to define certain display options for the Sensu [web UI][3], such as which web UI theme to use, the number of items to list on each page, and which URLs and linked images to expand.
You can define a single custom web UI configuration to federate to all, some, or only one of your clusters.

{{% notice note %}}
**NOTE**: Each cluster should have only one web configuration.
{{% /notice %}}

## Web UI configuration example

In this web UI configuration example:

- Users will receive a customized sign-in message that is formatted with [Markdown][10]
- Details for the local cluster will not be displayed
- Each page will list 50 items (except the checks page, which will list 100 items)
- The web UI will use the classic theme
- The entities page will list only entities with the `proxy` subscription, in ascending order based on `last_seen` value
- The checks page will list checks alphabetically by name
- The web UI will begin to display the license expiration banner 45 days before the organization license expires
- Expanded links and images will be allowed for the listed URLs
- YAML will be the default format for [resource definitions in the web UI][9]

{{< language-toggle >}}

{{}}
---
type: GlobalConfig
api_version: web/v1
metadata:
  name: custom-web-ui
spec:
  signin_message: with your *LDAP or system credentials*
  always_show_local_cluster: false
  default_preferences:
    poll_interval: 120000
    page_size: 50
    serialization_format: YAML
    theme: classic
  page_preferences:
  - page: entities
    page_size: 50
    order: LASTSEEN
    selector: proxy in entity.subscriptions
  - page: checks
    page_size: 100
    order: NAME
  license_expiry_reminder: 1080h0m0s
  link_policy:
    allow_list: true
    urls:
    - https://example.com
    - steamapp://34234234
    - "//google.com"
    - "//*.google.com"
    - "//bob.local"
    - https://grafana-host/render/metrics?width=500&height=250#sensu.io.graphic
{{}}

{{}}
{
  "type": "GlobalConfig",
  "api_version": "web/v1",
  "metadata": {
    "name": "custom-web-ui"
  },
  "spec": {
    "signin_message": "with your *LDAP or system credentials*",
    "always_show_local_cluster": false,
    "default_preferences": {
      "poll_interval": 120000,
      "page_size": 50,
      "serialization_format": "YAML",
      "theme": "classic"
    },
    "page_preferences": [
      {
        "page": "entities",
        "page_size": 50,
        "order": "LASTSEEN",
        "selector": "proxy in entity.subscriptions"
      },
      {
        "page": "checks",
        "page_size": 100,
        "order": "NAME"
      }
    ],
    "license_expiry_reminder": "1080h0m0s",
    "link_policy": {
      "allow_list": true,
      "urls": [
        "https://example.com",
        "steamapp://34234234",
        "//google.com",
        "//*.google.com",
        "//bob.local",
        "https://grafana-host/render/metrics?width=500&height=250#sensu.io.graphic"
      ]
    }
  }
}
{{}}

{{< /language-toggle >}}

## Page preferences order values

Available values for the `order` attribute in [page_preferences][11] vary depending on the page.

Page | Order value and description
---- | ---------------------------
events | `ENTITY`: List events by the entities that created them, in ascending order by entity name

`ENTITY_DESC`: List events by the entities that created them, in descending order by entity name

`LASTOK`: List events by their last OK status, starting with the most recent

`NEWEST`: List events by their timestamps, starting with the most recent

`OLDEST`: List events by their timestamps, starting with the oldest

`SEVERITY`: List events by their status, starting with the most severe
entities | `ID`: List entities by their IDs, in ascending order

`ID_DESC`: List entities by their IDs, in descending order

`LASTSEEN`: List entities by their `last_seen` timestamp, starting with the most recent
silences | `ID`: List silences by their IDs, in ascending order

`ID_DESC`: List silences by their IDs, in descending order

`BEGIN`: List silences by the time they begin, starting with the silence that begins soonest

`BEGIN_DESC`: List silences by the time they begin, ending with the silence that begins first
checks | `NAME`: List checks by name, in alphabetical order

`NAME_DESC`: List checks by name, in reverse alphabetical order
event-filters | `NAME`: List event filters by name, in alphabetical order

`NAME_DESC`: List event filters by name, in reverse alphabetical order
handlers | `NAME`: List handlers by name, in alphabetical order

`NAME_DESC`: List handlers by name, in reverse alphabetical order
mutators | `NAME`: List mutators by name, in alphabetical order

`NAME_DESC`: List mutators by name, in reverse alphabetical order

## Web UI configuration specification

### Top-level attributes

api_version  |
-------------|------
description  | Top-level attribute that specifies the Sensu API group and version. For web UI configuration in this version of Sensu, the api_version should always be `web/v1`.
required     | Required for web UI configuration in `wrapped-json` or `yaml` format.
type         | String
example      | {{< language-toggle >}}
{{}}
api_version: web/v1
{{}}
{{}}
{
  "api_version": "web/v1"
}
{{}}
{{< /language-toggle >}}

metadata     |      |
-------------|------
description  | Top-level scope that contains the web UI configuration's `name` and `created_by` information.
required     | true
type         | Map of key-value pairs
example      | {{< language-toggle >}}
{{}}
metadata:
  name: custom-web-ui
  created_by: admin
{{}}
{{}}
{
  "metadata": {
    "name": "custom-web-ui",
    "created_by": "admin"
  }
}
{{}}

{{< /language-toggle >}}

spec         |
-------------|------
description  | Top-level map that includes web UI configuration [spec attributes][4].
required     | Required for web UI configuration in `wrapped-json` or `yaml` format.
type         | Map of key-value pairs
example      | {{< language-toggle >}}
{{}}
spec:
  signin_message: with your *LDAP or system credentials*
  always_show_local_cluster: false
  default_preferences:
    poll_interval: 120000
    page_size: 50
    serialization_format: YAML
    theme: classic
  page_preferences:
    - page: entities
      page_size: 50
      order: LASTSEEN
      selector: proxy in entity.subscriptions
    - page: checks
      page_size: 100
      order: NAME
  license_expiry_reminder: 1080h0m0s
  link_policy:
    allow_list: true
    urls:
    - https://example.com
    - steamapp://34234234
    - "//google.com"
    - "//*.google.com"
    - "//bob.local"
    - https://grafana-host/render/metrics?width=500&height=250#sensu.io.graphic
{{}}
{{}}
{
  "spec": {
    "signin_message": "with your *LDAP or system credentials*",
    "always_show_local_cluster": false,
    "default_preferences": {
      "poll_interval": 120000,
      "page_size": 50,
      "serialization_format": "YAML",
      "theme": "classic"
    },
    "page_preferences": [
      {
        "page": "entities",
        "page_size": 50,
        "order": "LASTSEEN",
        "selector": "proxy in entity.subscriptions"
      },
      {
        "page": "checks",
        "page_size": 100,
        "order": "NAME"
      }
    ],
    "license_expiry_reminder": "1080h0m0s",
    "link_policy": {
      "allow_list": true,
      "urls": [
        "https://example.com",
        "steamapp://34234234",
        "//google.com",
        "//*.google.com",
        "//bob.local",
        "https://grafana-host/render/metrics?width=500&height=250#sensu.io.graphic"
      ]
    }
  }
}
{{}}
{{< /language-toggle >}}

type         |
-------------|------
description  | Top-level attribute that specifies the resource type. For web UI configuration, the type should always be `GlobalConfig`.
required     | Required for web UI configuration in `wrapped-json` or `yaml` format.
type         | String
example      | {{< language-toggle >}}
{{}}
type: GlobalConfig
{{}}
{{}}
{
  "type": "GlobalConfig"
}
{{}}
{{< /language-toggle >}}

### Metadata attributes

| created_by |      |
-------------|------
description  | Username of the Sensu user who created or last updated the web UI configuration. Sensu automatically populates the `created_by` field when the web UI configuration is created or updated. The admin user, cluster admins, and any user with access to the [`GlobalConfig`][2] resource can create and update web UI configurations.
required     | false
type         | String
example      | {{< language-toggle >}}
{{}}
created_by: admin
{{}}
{{}}
{
  "created_by": "admin"
}
{{}}
{{< /language-toggle >}}

name         |      |
-------------|------
description  | Name for the web UI configuration that is used internally by Sensu.
required     | true
type         | String
example      | {{< language-toggle >}}
{{}}
name: custom-web-ui
{{}}
{{}}
{
  "name": "custom-web-ui"
}
{{}}
{{< /language-toggle >}}

### Spec attributes

always_show_local_cluster |
-------------|------
description  | Use only in federated environments. Set to `true` to display the cluster the user is currently connected to in the [namespace switcher][5]. To omit local cluster details, set to `false`.
required     | false
type         | Boolean
default      | `false`
example      | {{< language-toggle >}}
{{}}
always_show_local_cluster: false
{{}}
{{}}
{
  "always_show_local_cluster": false
}
{{}}
{{< /language-toggle >}}

default_preferences |
-------------|------
description  | Global [default preferences][1] page size and theme preferences for all users.
required     | false
type         | Map of key-value pairs
example      | {{< language-toggle >}}
{{}}
default_preferences:
  poll_interval: 120000
  page_size: 50
  theme: classic
{{}}
{{}}
{
  "default_preferences": {
    "poll_interval": 120000,
    "page_size": 50,
    "theme": "classic"
  }
}
{{}}
{{< /language-toggle >}}

license_expiry_reminder |
-------------|------
description  | Number of days before license expiration to begin displaying the [license expiration banner][12] in the web UI. The value must be a valid duration, such as `1080h`, `14400m`, or `24h59m59s`.{{% notice note %}}
**NOTE**: By default, the web UI displays the banner starting 30 days before license expiration.
{{% /notice %}}
required     | false
type         | String
example      | {{< language-toggle >}}
{{}}
license_expiry_reminder: 1080h0m0s
{{}}
{{}}
{
  "license_expiry_reminder": "1080h0m0s"
}
{{}}
{{< /language-toggle >}}

link_policy |
-------------|------
description  | For labels or annotations that contain a URL, the policy for which domains are valid and invalid targets for conversion to a link or an image.
required     | false
type         | Map of key-value pairs
example      | {{< language-toggle >}}
{{}}
link_policy:
  allow_list: true
  urls:
  - https://example.com
  - steamapp://34234234
  - "//google.com"
  - "//*.google.com"
  - "//bob.local"
  - https://grafana-host/render/metrics?width=500&height=250#sensu.io.graphic
{{}}
{{}}
{
  "link_policy": {
    "allow_list": true,
    "urls": [
      "https://example.com",
      "steamapp://34234234",
      "//google.com",
      "//*.google.com",
      "//bob.local",
      "https://grafana-host/render/metrics?width=500&height=250#sensu.io.graphic"
    ]
  }
}
{{}}
{{< /language-toggle >}}

page_preferences |
-------------|------
description  | [Page-specific preferences][6] for page size, order, and selector for all users. Any page preferences will override default preferences for the specified page.
required     | false
type         | Array
example      | {{< language-toggle >}}
{{}}
page_preferences:
  - page: entities
    page_size: 50
    order: LASTSEEN
    selector: proxy in entity.subscriptions
  - page: checks
    page_size: 100
    order: NAME
{{}}
{{}}
{
  "page_preferences": [
    {
      "page": "entities",
      "page_size": 50,
      "order": "LASTSEEN",
      "selector": "proxy in entity.subscriptions"
    },
    {
      "page": "checks",
      "page_size": 100,
      "order": "NAME"
    }
  ]
}
{{}}
{{< /language-toggle >}}

signin_message |
-------------|------
description  | Custom message to display on the web UI sign-in modal. Accepts [Markdown][10] formatting.
required     | false
type         | String
default      | `with your credentials`
example      | {{< language-toggle >}}
{{}}
signin_message: with your *LDAP or system credentials*
{{}}
{{}}
{
  "signin_message": "with your *LDAP or system credentials*"
}
{{}}
{{< /language-toggle >}}

#### Default preferences attributes

page_size |
-------------|------
description  | The number of items to list on each page.
required     | false
type         | Integer
default      | `25`
example      | {{< language-toggle >}}
{{}}
page_size: 25
{{}}
{{}}
{
  "page_size": 25
}
{{}}
{{< /language-toggle >}}

poll_interval |
-------------|------
description  | The frequency at which web UI pages will poll for new data from the Sensu backend. In milliseconds.

Useful for increasing the polling interval duration if web UI sessions are causing heavy load. If you set the poll interval, all web UI views will use the poll interval value instead of their individual polling defaults.{{% notice note %}}
**NOTE**: If an individual user's settings conflict with the web UI configuration settings, Sensu will use the individual user's settings.
{{% /notice %}}
type         | Integer
default      | `10000` when page is visible. `300000` when page is not visible.
example      | {{< language-toggle >}}
{{}}
poll_interval: 120000
{{}}
{{}}
{
  "poll_interval": 120000
}
{{}}
{{< /language-toggle >}}

serialization_format |
-------------|------
description  | Default format for [resource definitions in the web UI][9].
required     | false
type         | String
default      | `YAML`
allowed values | `JSON`, `YAML`
example      | {{< language-toggle >}}
{{}}
serialization_format: YAML
{{}}
{{}}
{
  "serialization_format": "YAML"
}
{{}}
{{< /language-toggle >}}

theme |
---------------|------
description    | The theme used in the web UI.{{% notice note %}}
**NOTE**: If an individual user's settings conflict with the web UI configuration settings, Sensu will use the individual user's settings.
For example, if a user's system is set to dark mode and their web UI settings are configured to use their system settings, the web UI will use dark mode for that user, even if you set the theme to `classic` in your web UI configuration.
{{% /notice %}}
required       | false
type           | String
default        | `sensu`
allowed values | `sensu`, `classic`, `uchiwa`, `tritanopia`, `deuteranopia`
example        | {{< language-toggle >}}
{{}}
theme: classic
{{}}
{{}}
{
  "theme": "classic"
}
{{}}
{{< /language-toggle >}}

#### Page preferences attributes

order |
-------------|------
description  | The order in which to list items on the specified page. Read [Page preferences order values][8] to learn more.
required     | false
type         | String
example      | {{< language-toggle >}}
{{}}
order: LASTSEEN
{{}}
{{}}
{
  "order": "LASTSEEN"
}
{{}}
{{< /language-toggle >}}

page |
-------------|------
description  | The page to which the page preference settings apply.
required     | true
type         | String
allowed values | `events`, `entities`, `silences`, `checks`, `event-filters`, `handlers`, `mutators`
example      | {{< language-toggle >}}
{{}}
page: events
{{}}
{{}}
{
  "page": "events"
}
{{}}
{{< /language-toggle >}}

page_size |
-------------|------
description  | The number of items to list for the specified page.
required     | false
type         | Integer
example      | {{< language-toggle >}}
{{}}
page_size: 100
{{}}
{{}}
{
  "page_size": 100
}
{{}}
{{< /language-toggle >}}

selector |
-------------|------
description  | The [search expression][7] to apply to the specified page.
{{% notice note %}}
**NOTE**: The selector page preference is not available for the events page.
{{% /notice %}}
required     | false
type         | String
example      | {{< language-toggle >}}
{{}}
selector: proxy in entity.subscriptions
{{}}
{{}}
{
  "selector": "proxy in entity.subscriptions"
}
{{}}
{{< /language-toggle >}}

#### Link policy attributes

allow_list |
-------------|------
description  | If the list of URLs acts as an allow list, `true`. If the list of URLs acts as a deny list, `false`. As an allow list, only matching URLs will be expanded. As a deny list, matching URLs will not be expanded, but any other URLs will be expanded.
required     | false
type         | Boolean
default      | `false`
example      | {{< language-toggle >}}
{{}}
allow_list: true
{{}}
{{}}
{
  "allow_list": true
}
{{}}
{{< /language-toggle >}}

urls |
-------------|------
description  | The list of URLs to use as an allow or deny list.
{{% notice note %}}**NOTE**: For images from services that may not have an easily distinguishable file extension, append the anchor `#sensu.io.graphic` to the image URLs.
{{% /notice %}}
required     | false
type         | Array
example      | {{< language-toggle >}}
{{}}
urls:
- https://example.com
- steamapp://34234234
- "//google.com"
- "//*.google.com"
- "//bob.local"
- https://grafana-host/render/metrics?width=500&height=250#sensu.io.graphic
{{}}
{{}}
{
  "urls": [
    "https://example.com",
    "steamapp://34234234",
    "//google.com",
    "//*.google.com",
    "//bob.local",
    "https://grafana-host/render/metrics?width=500&height=250#sensu.io.graphic"
  ]
}
{{}}
{{< /language-toggle >}}

[1]: #default-preferences-attributes
[2]: ../../api/enterprise/webconfig/
[3]: ../
[4]: #spec-attributes
[5]: ../view-manage-resources/#use-the-namespace-switcher
[6]: #page-preferences-attributes
[7]: ../search/
[8]: #page-preferences-order-values
[9]: ../view-manage-resources/#view-resource-data-in-the-web-ui
[10]: https://www.markdownguide.org/
[11]: #page-preferences-attribute
[12]: ../#license-expiration-banner


text:
FROM stackbrew/ubuntu:trusty

RUN apt-get update && apt-get install -y git curl wget build-essential make libxslt-dev libxml2-dev libmysqlclient-dev libpq-dev libsqlite3-0 libsqlite3-dev software-properties-common libyaml-0-2
RUN add-apt-repository ppa:brightbox/ruby-ng && add-apt-repository ppa:nginx/development && apt-get update
RUN apt-get install -y nginx ruby2.1 ruby2.1-dev
RUN update-alternatives --set ruby /usr/bin/ruby2.1 && update-alternatives --set gem /usr/bin/gem2.1
RUN gem install foreman bundler --no-ri --no-rdoc
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
ADD default /etc/nginx/sites-available/default
ADD nginx.conf /etc/nginx/nginx.conf


text:
export interface TooltipConfig {
  containerClass?: string;
  horizontal?: boolean;
  delay?: number;
}


text:
(function() {
  var OldValue, Prefixer, Value, utils, vendor, _ref,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  Prefixer = require('./prefixer');

  OldValue = require('./old-value');

  vendor = require('postcss/lib/vendor');

  utils = require('./utils');

  Value = (function(_super) {
    __extends(Value, _super);

    function Value() {
      _ref = Value.__super__.constructor.apply(this, arguments);
      return _ref;
    }

    Value.save = function(prefixes, decl) {
      var cloned, prefix, prefixed, propPrefix, rule, value, _ref1, _results;
      _ref1 = decl._autoprefixerValues;
      _results = [];
      for (prefix in _ref1) {
        value = _ref1[prefix];
        if (value === decl.value) {
          continue;
        }
        propPrefix = vendor.prefix(decl.prop);
        if (propPrefix === utils.removeNote(prefix)) {
          _results.push(decl.value = value);
        } else if (propPrefix === '-pie-') {
          continue;
        } else {
          prefixed = prefixes.prefixed(decl.prop, prefix);
          rule = decl.parent;
          if (rule.every(function(i) {
            return i.prop !== prefixed;
          })) {
            if (rule.every(function(i) {
              return i.prop !== decl.prop || i.value !== value;
            })) {
              cloned = this.clone(decl, {
                value: value
              });
              _results.push(decl.parent.insertBefore(decl, cloned));
            } else {
              _results.push(void 0);
            }
          } else {
            _results.push(void 0);
          }
        }
      }
      return _results;
    };

    Value.prototype.check = function(decl) {
      var value;
      value = decl.value;
      if (value.indexOf(this.name) !== -1) {
        return !!value.match(this.regexp());
      } else {
        return false;
      }
    };

    Value.prototype.regexp = function() {
      return this.regexpCache || (this.regexpCache = utils.regexp(this.name));
    };

    Value.prototype.replace = function(string, prefix) {
      return string.replace(this.regexp(), '$1' + prefix + '$2');
    };

    Value.prototype.add = function(decl, prefix) {
      var value;
      decl._autoprefixerValues || (decl._autoprefixerValues = {});
      value = decl._autoprefixerValues[prefix] || decl.value;
      value = this.replace(value, prefix);
      if (value) {
        return decl._autoprefixerValues[prefix] = value;
      }
    };

    Value.prototype.old = function(prefix) {
      return new OldValue(prefix + this.name);
    };

    return Value;

  })(Prefixer);

  module.exports = Value;

}).call(this);


text:
Home Grown
===============
Tools & Utils built locally

Slider
-----------
Tiny responsive slider built with plain js
- Testing done with tape + testling
- Browserify for modular development
- Depends on a small set of utils such as pubsub, etc

Utils
------
Utilities include:
- Pubsub
- DOM Manipulation
- Swipe - touch events*
- Collection abstractions

Utilities are stored in the root folder but are [symlinked](#symlink-utilities) to
node_modules folder to avoid [relative path](https://github.com/substack/browserify-handbook#avoiding-)
hell.

The utilities can be required like so `require('utils/nameOfUtil');`

*Touch events not pointers, which means no current
support for windows mobile.

Getting Started
---------------

####Setup

Get [Browserify](https://www.npmjs.org/package/browserify) if you already don't :)
and add [Testling](https://www.npmjs.org/package/testling) to the mix.

`npm install -g browserify testling`

This will add the two npm packages to your global node_modules dir.

####Next run:

`npm install`

to get all of the local packages setup.

####Symlink utilities

Symlink to the node_modules dir like so:

`ln -s ../utils node_modules/utils`

now you have the proper setup.