text:
package org.influxdb.impl;

import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import okhttp3.logging.HttpLoggingInterceptor.Level;
import okio.BufferedSource;
import org.influxdb.BatchOptions;
import org.influxdb.InfluxDB;
import org.influxdb.InfluxDBException;
import org.influxdb.InfluxDBIOException;
import org.influxdb.dto.BatchPoints;
import org.influxdb.dto.BoundParameterQuery;
import org.influxdb.dto.Point;
import org.influxdb.dto.Pong;
import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult;
import org.influxdb.impl.BatchProcessor.HttpBatchEntry;
import org.influxdb.impl.BatchProcessor.UdpBatchEntry;
import org.influxdb.msgpack.MessagePackConverterFactory;
import org.influxdb.msgpack.MessagePackTraverser;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Converter.Factory;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.moshi.MoshiConverterFactory;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Implementation of a InluxDB API.
 *
 * @author stefan.majer [at] gmail.com
 */
public class InfluxDBImpl implements InfluxDB {

  private static final String APPLICATION_MSGPACK = "application/x-msgpack";

  static final okhttp3.MediaType MEDIA_TYPE_STRING = MediaType.parse("text/plain");

  private static final String SHOW_DATABASE_COMMAND_ENCODED = Query.encode("SHOW DATABASES");

  /**
   * This static constant holds the http logging log level expected in DEBUG mode
   * It is set by System property {@code org.influxdb.InfluxDB.logLevel}.
   *
   * @see org.influxdb.InfluxDB#LOG_LEVEL_PROPERTY
   */
  private static final LogLevel LOG_LEVEL = LogLevel.parseLogLevel(System.getProperty(LOG_LEVEL_PROPERTY));

  private final String hostName;
  private String version;
  private final Retrofit retrofit;
  private final OkHttpClient client;
  private final InfluxDBService influxDBService;
  private BatchProcessor batchProcessor;
  private final AtomicBoolean batchEnabled = new AtomicBoolean(false);
  private final LongAdder writeCount = new LongAdder();
  private final LongAdder unBatchedCount = new LongAdder();
  private final LongAdder batchedCount = new LongAdder();
  private volatile DatagramSocket datagramSocket;
  private final HttpLoggingInterceptor loggingInterceptor;
  private final GzipRequestInterceptor gzipRequestInterceptor;
  private LogLevel logLevel = LogLevel.NONE;
  private String database;
  private String retentionPolicy = "autogen";
  private ConsistencyLevel consistency = ConsistencyLevel.ONE;
  private final boolean messagePack;
  private Boolean messagePackSupport;
  private final ChunkProccesor chunkProccesor;

  /**
   * Constructs a new {@code InfluxDBImpl}.
   *
   * @param url
   *          The InfluxDB server API URL
   * @param username
   *          The InfluxDB user name
   * @param password
   *          The InfluxDB user password
   * @param okHttpBuilder
   *          The OkHttp Client Builder
   * @param responseFormat
   *          The {@code ResponseFormat} to use for response from InfluxDB
   *          server
   */
  public InfluxDBImpl(final String url, final String username, final String password,
                      final OkHttpClient.Builder okHttpBuilder, final ResponseFormat responseFormat) {
    this(url, username, password, okHttpBuilder, new Retrofit.Builder(), responseFormat);
  }

  /**
   * Constructs a new {@code InfluxDBImpl}.
   *
   * @param url
   *          The InfluxDB server API URL
   * @param username
   *          The InfluxDB user name
   * @param password
   *          The InfluxDB user password
   * @param okHttpBuilder
   *          The OkHttp Client Builder
   * @param retrofitBuilder
   *          The Retrofit Builder
   * @param responseFormat
   *          The {@code ResponseFormat} to use for response from InfluxDB
   *          server
   */
  public InfluxDBImpl(final String url, final String username, final String password,
                      final OkHttpClient.Builder okHttpBuilder, final Retrofit.Builder retrofitBuilder,
                      final ResponseFormat responseFormat) {
    this.messagePack = ResponseFormat.MSGPACK.equals(responseFormat);
    this.hostName = parseHost(url);

    this.loggingInterceptor = new HttpLoggingInterceptor();
    setLogLevel(LOG_LEVEL);

    this.gzipRequestInterceptor = new GzipRequestInterceptor();
    OkHttpClient.Builder clonedOkHttpBuilder = okHttpBuilder.build().newBuilder()
            .addInterceptor(loggingInterceptor)
            .addInterceptor(gzipRequestInterceptor);
    if (username != null && password != null) {
      clonedOkHttpBuilder.addInterceptor(new BasicAuthInterceptor(username, password));
    }
    Factory converterFactory = null;
    switch (responseFormat) {
    case MSGPACK:
      clonedOkHttpBuilder.addInterceptor(chain -> {
        Request request = chain.request().newBuilder().addHeader("Accept", APPLICATION_MSGPACK).build();
        return chain.proceed(request);
      });

      converterFactory = MessagePackConverterFactory.create();
      chunkProccesor = new MessagePackChunkProccesor();
      break;
    case JSON:
    default:
      converterFactory = MoshiConverterFactory.create();

      Moshi moshi = new Moshi.Builder().build();
      JsonAdapter<QueryResult> adapter = moshi.adapter(QueryResult.class);
      chunkProccesor = new JSONChunkProccesor(adapter);
      break;
    }

    this.client = clonedOkHttpBuilder.build();
    Retrofit.Builder clonedRetrofitBuilder = retrofitBuilder.baseUrl(url).build().newBuilder();
    this.retrofit = clonedRetrofitBuilder.client(this.client)
            .addConverterFactory(converterFactory).build();
    this.influxDBService = this.retrofit.create(InfluxDBService.class);

  }

  public InfluxDBImpl(final String url, final String username, final String password,
      final OkHttpClient.Builder client) {
    this(url, username, password, client, ResponseFormat.JSON);

  }

  InfluxDBImpl(final String url, final String username, final String password, final OkHttpClient.Builder client,
      final InfluxDBService influxDBService, final JsonAdapter<QueryResult> adapter) {
    super();
    this.messagePack = false;
    this.hostName = parseHost(url);

    this.loggingInterceptor = new HttpLoggingInterceptor();
    setLogLevel(LOG_LEVEL);

    this.gzipRequestInterceptor = new GzipRequestInterceptor();
    OkHttpClient.Builder clonedBuilder = client.build().newBuilder()
            .addInterceptor(loggingInterceptor)
            .addInterceptor(gzipRequestInterceptor)
            .addInterceptor(new BasicAuthInterceptor(username, password));
    this.client = clonedBuilder.build();
    this.retrofit = new Retrofit.Builder().baseUrl(url)
        .client(this.client)
        .addConverterFactory(MoshiConverterFactory.create()).build();
    this.influxDBService = influxDBService;

    chunkProccesor = new JSONChunkProccesor(adapter);
  }

  public InfluxDBImpl(final String url, final String username, final String password, final OkHttpClient.Builder client,
      final String database, final String retentionPolicy, final ConsistencyLevel consistency) {
    this(url, username, password, client);

    setConsistency(consistency);
    setDatabase(database);
    setRetentionPolicy(retentionPolicy);
  }

  private String parseHost(final String url) {
    String hostName;
    try {
      URI uri = new URI(url);
      hostName = uri.getHost();
    } catch (URISyntaxException e1) {
      throw new IllegalArgumentException("Unable to parse url: " + url, e1);
    }

    if (hostName == null) {
      throw new IllegalArgumentException("Unable to parse url: " + url);
    }

    try {
      InetAddress.getByName(hostName);
    } catch (UnknownHostException e) {
      throw new InfluxDBIOException(e);
    }
    return hostName;
  }

  @Override
  public InfluxDB setLogLevel(final LogLevel logLevel) {
    switch (logLevel) {
    case NONE:
      this.loggingInterceptor.setLevel(Level.NONE);
      break;
    case BASIC:
      this.loggingInterceptor.setLevel(Level.BASIC);
      break;
    case HEADERS:
      this.loggingInterceptor.setLevel(Level.HEADERS);
      break;
    case FULL:
      this.loggingInterceptor.setLevel(Level.BODY);
      break;
    default:
      break;
    }
    this.logLevel = logLevel;
    return this;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public InfluxDB enableGzip() {
    this.gzipRequestInterceptor.enable();
    return this;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public InfluxDB disableGzip() {
    this.gzipRequestInterceptor.disable();
    return this;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isGzipEnabled() {
    return this.gzipRequestInterceptor.isEnabled();
  }

  @Override
  public InfluxDB enableBatch() {
    enableBatch(BatchOptions.DEFAULTS);
    return this;
  }

  @Override
  public InfluxDB enableBatch(final BatchOptions batchOptions) {

    if (this.batchEnabled.get()) {
      throw new IllegalStateException("BatchProcessing is already enabled.");
    }
    this.batchProcessor = BatchProcessor
            .builder(this)
            .actions(batchOptions.getActions())
            .exceptionHandler(batchOptions.getExceptionHandler())
            .interval(batchOptions.getFlushDuration(), batchOptions.getJitterDuration(), TimeUnit.MILLISECONDS)
            .threadFactory(batchOptions.getThreadFactory())
            .bufferLimit(batchOptions.getBufferLimit())
            .consistencyLevel(batchOptions.getConsistency())
            .precision(batchOptions.getPrecision())
            .dropActionsOnQueueExhaustion(batchOptions.isDropActionsOnQueueExhaustion())
            .droppedActionHandler(batchOptions.getDroppedActionHandler())
            .build();
    this.batchEnabled.set(true);
    return this;
  }

  @Override
  public InfluxDB enableBatch(final int actions, final int flushDuration,
                              final TimeUnit flushDurationTimeUnit) {
    enableBatch(actions, flushDuration, flushDurationTimeUnit, Executors.defaultThreadFactory());
    return this;
  }

  @Override
  public InfluxDB enableBatch(final int actions, final int flushDuration,
                              final TimeUnit flushDurationTimeUnit, final ThreadFactory threadFactory) {
    enableBatch(actions, flushDuration, flushDurationTimeUnit, threadFactory, (points, throwable) -> { });
    return this;
  }

  @Override
  public InfluxDB enableBatch(final int actions, final int flushDuration, final TimeUnit flushDurationTimeUnit,
                              final ThreadFactory threadFactory,
                              final BiConsumer<Iterable<Point>, Throwable> exceptionHandler,
                              final ConsistencyLevel consistency) {
    enableBatch(actions, flushDuration, flushDurationTimeUnit, threadFactory, exceptionHandler)
        .setConsistency(consistency);
    return this;
  }

  @Override
  public InfluxDB enableBatch(final int actions, final int flushDuration, final TimeUnit flushDurationTimeUnit,
                              final ThreadFactory threadFactory,
                              final BiConsumer<Iterable<Point>, Throwable> exceptionHandler) {
    enableBatch(actions, flushDuration, 0, flushDurationTimeUnit, threadFactory, exceptionHandler, false, null);
    return this;
  }

  private InfluxDB enableBatch(final int actions, final int flushDuration, final int jitterDuration,
                               final TimeUnit durationTimeUnit, final ThreadFactory threadFactory,
                               final BiConsumer<Iterable<Point>, Throwable> exceptionHandler,
                               final boolean dropActionsOnQueueExhaustion, final Consumer<Point> droppedActionHandler) {
    if (this.batchEnabled.get()) {
      throw new IllegalStateException("BatchProcessing is already enabled.");
    }
    this.batchProcessor = BatchProcessor
            .builder(this)
            .actions(actions)
            .exceptionHandler(exceptionHandler)
            .interval(flushDuration, jitterDuration, durationTimeUnit)
            .threadFactory(threadFactory)
            .consistencyLevel(consistency)
            .dropActionsOnQueueExhaustion(dropActionsOnQueueExhaustion)
            .droppedActionHandler(droppedActionHandler)
            .build();
    this.batchEnabled.set(true);
    return this;
  }

  @Override
  public void disableBatch() {
    this.batchEnabled.set(false);
    if (this.batchProcessor != null) {
      this.batchProcessor.flushAndShutdown();
    }
  }

  @Override
  public boolean isBatchEnabled() {
    return this.batchEnabled.get();
  }

  @Override
  public Pong ping() {
    final long started = System.currentTimeMillis();
    Call<ResponseBody> call = this.influxDBService.ping();
    try {
      Response<ResponseBody> response = call.execute();
      Headers headers = response.headers();
      String version = "unknown";
      for (String name : headers.toMultimap().keySet()) {
        if (null != name && "X-Influxdb-Version".equalsIgnoreCase(name)) {
          version = headers.get(name);
          break;
        }
      }
      Pong pong = new Pong();
      pong.setVersion(version);
      pong.setResponseTime(System.currentTimeMillis() - started);
      return pong;
    } catch (IOException e) {
      throw new InfluxDBIOException(e);
    }
  }

  @Override
  public String version() {
    if (version == null) {
      this.version = ping().getVersion();
    }
    return this.version;
  }

  @Override
  public void write(final Point point) {
    write(database, retentionPolicy, point);
  }

  @Override
  public void write(final String records) {
    write(database, retentionPolicy, consistency, records);
  }

  @Override
  public void write(final List<String> records) {
    write(database, retentionPolicy, consistency, records);
  }

  @Override
  public void write(final String database, final String retentionPolicy, final Point point) {
    if (this.batchEnabled.get()) {
      HttpBatchEntry batchEntry = new HttpBatchEntry(point, database, retentionPolicy);
      this.batchProcessor.put(batchEntry);
    } else {
      BatchPoints batchPoints = BatchPoints.database(database)
                                           .retentionPolicy(retentionPolicy).build();
      batchPoints.point(point);
      this.write(batchPoints);
      this.unBatchedCount.increment();
    }
    this.writeCount.increment();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void write(final int udpPort, final Point point) {
    if (this.batchEnabled.get()) {
      UdpBatchEntry batchEntry = new UdpBatchEntry(point, udpPort);
      this.batchProcessor.put(batchEntry);
    } else {
      this.write(udpPort, point.lineProtocol());
      this.unBatchedCount.increment();
    }
    this.writeCount.increment();
  }

  @Override
  public void write(final BatchPoints batchPoints) {
    this.batchedCount.add(batchPoints.getPoints().size());
    RequestBody lineProtocol = RequestBody.create(MEDIA_TYPE_STRING, batchPoints.lineProtocol());
    String db = batchPoints.getDatabase();
    if (db == null) {
        db = this.database;
    }
    execute(this.influxDBService.writePoints(
        db,
        batchPoints.getRetentionPolicy(),
        TimeUtil.toTimePrecision(batchPoints.getPrecision()),
        batchPoints.getConsistency().value(),
        lineProtocol));
  }

  @Override
  public void writeWithRetry(final BatchPoints batchPoints) {
    if (isBatchEnabled()) {
      batchProcessor.getBatchWriter().write(Collections.singleton(batchPoints));
    } else {
      write(batchPoints);
    }
  }

  @Override
  public void write(final String database, final String retentionPolicy, final ConsistencyLevel consistency,
          final TimeUnit precision, final String records) {
    execute(this.influxDBService.writePoints(
        database,
        retentionPolicy,
        TimeUtil.toTimePrecision(precision),
        consistency.value(),
        RequestBody.create(MEDIA_TYPE_STRING, records)));
  }

  @Override
  public void write(final String database, final String retentionPolicy, final ConsistencyLevel consistency,
      final String records) {
    write(database, retentionPolicy, consistency, TimeUnit.NANOSECONDS, records);
  }

  @Override
  public void write(final String database, final String retentionPolicy, final ConsistencyLevel consistency,
      final List<String> records) {
    write(database, retentionPolicy, consistency, TimeUnit.NANOSECONDS, records);
  }

  @Override
  public void write(final String database, final String retentionPolicy, final ConsistencyLevel consistency,
          final TimeUnit precision, final List<String> records) {
    write(database, retentionPolicy, consistency, precision, String.join("\n", records));
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void write(final int udpPort, final String records) {
    initialDatagramSocket();
    byte[] bytes = records.getBytes(StandardCharsets.UTF_8);
    try {
        datagramSocket.send(new DatagramPacket(bytes, bytes.length, new InetSocketAddress(hostName, udpPort)));
    } catch (IOException e) {
        throw new InfluxDBIOException(e);
    }
  }

  private void initialDatagramSocket() {
    if (datagramSocket == null) {
        synchronized (InfluxDBImpl.class) {
            if (datagramSocket == null) {
                try {
                    datagramSocket = new DatagramSocket();
                } catch (SocketException e) {
                    throw new InfluxDBIOException(e);
                }
            }
        }
    }
}

  /**
   * {@inheritDoc}
   */
  @Override
  public void write(final int udpPort, final List<String> records) {
    write(udpPort, String.join("\n", records));
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public QueryResult query(final Query query) {
    return executeQuery(callQuery(query));
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void query(final Query query, final Consumer<QueryResult> onSuccess, final Consumer<Throwable> onFailure) {
    final Call<QueryResult> call = callQuery(query);
    call.enqueue(new Callback<QueryResult>() {
      @Override
      public void onResponse(final Call<QueryResult> call, final Response<QueryResult> response) {
        if (response.isSuccessful()) {
          onSuccess.accept(response.body());
        } else {
          Throwable t = null;
          String errorBody = null;

          try {
            if (response.errorBody() != null) {
              errorBody = response.errorBody().string();
            }
          } catch (IOException e) {
            t = e;
          }

          if (t != null) {
            onFailure.accept(new InfluxDBException(response.message(), t));
          } else if (errorBody != null) {
            onFailure.accept(new InfluxDBException(response.message() + " - " + errorBody));
          } else {
            onFailure.accept(new InfluxDBException(response.message()));
          }
        }
      }

      @Override
      public void onFailure(final Call<QueryResult> call, final Throwable throwable) {
        onFailure.accept(throwable);
      }
    });
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void query(final Query query, final int chunkSize, final Consumer<QueryResult> onNext) {
    query(query, chunkSize, onNext, () -> { });
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void query(final Query query, final int chunkSize, final BiConsumer<Cancellable, QueryResult> onNext) {
    query(query, chunkSize, onNext, () -> { });
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void query(final Query query, final int chunkSize, final Consumer<QueryResult> onNext,
                    final Runnable onComplete) {
    query(query, chunkSize, (cancellable, queryResult) -> onNext.accept(queryResult), onComplete);
  }

  @Override
  public void query(final Query query, final int chunkSize, final BiConsumer<Cancellable, QueryResult> onNext,
                    final Runnable onComplete) {
    query(query, chunkSize, onNext, onComplete, null);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void query(final Query query, final int chunkSize, final BiConsumer<Cancellable, QueryResult> onNext,
                    final Runnable onComplete, final Consumer<Throwable> onFailure) {
    Call<ResponseBody> call;
    if (query instanceof BoundParameterQuery) {
      BoundParameterQuery boundParameterQuery = (BoundParameterQuery) query;
      call = this.influxDBService.query(getDatabase(query), query.getCommandWithUrlEncoded(), chunkSize,
          boundParameterQuery.getParameterJsonWithUrlEncoded());
    } else {
      if (query.requiresPost()) {
        call = this.influxDBService.query(getDatabase(query), query.getCommandWithUrlEncoded(), chunkSize, null);
      } else {
        call = this.influxDBService.query(getDatabase(query), query.getCommandWithUrlEncoded(), chunkSize);
      }
    }

    call.enqueue(new Callback<ResponseBody>() {
      @Override
      public void onResponse(final Call<ResponseBody> call, final Response<ResponseBody> response) {

        Cancellable cancellable = new Cancellable() {
          @Override
          public void cancel() {
            call.cancel();
          }

          @Override
          public boolean isCanceled() {
            return call.isCanceled();
          }
        };

        try {
          if (response.isSuccessful()) {
            ResponseBody chunkedBody = response.body();
            chunkProccesor.process(chunkedBody, cancellable, onNext, onComplete);
          } else {
            // REVIEW: must be handled consistently with IOException.
            ResponseBody errorBody = response.errorBody();
            if (errorBody != null) {
              InfluxDBException influxDBException = new InfluxDBException(errorBody.string());
              if (onFailure == null) {
                throw influxDBException;
              } else {
                onFailure.accept(influxDBException);
              }
            }
          }
        } catch (IOException e) {
          QueryResult queryResult = new QueryResult();
          queryResult.setError(e.toString());
          onNext.accept(cancellable, queryResult);
          //passing null onFailure consumer is here for backward compatibility
          //where the empty queryResult containing error is propagating into onNext consumer
          if (onFailure != null) {
            onFailure.accept(e);
          }
        } catch (Exception e) {
          call.cancel();
          if (onFailure != null) {
            onFailure.accept(e);
          }
        }

      }

      @Override
      public void onFailure(final Call<ResponseBody> call, final Throwable t) {
        if (onFailure == null) {
          throw new InfluxDBException(t);
        } else {
          onFailure.accept(t);
        }
      }
    });
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public QueryResult query(final Query query, final TimeUnit timeUnit) {
    Call<QueryResult> call;
    if (query instanceof BoundParameterQuery) {
        BoundParameterQuery boundParameterQuery = (BoundParameterQuery) query;
        call = this.influxDBService.query(getDatabase(query),
                TimeUtil.toTimePrecision(timeUnit), query.getCommandWithUrlEncoded(),
                boundParameterQuery.getParameterJsonWithUrlEncoded());
    } else {
        if (query.requiresPost()) {
          call = this.influxDBService.query(getDatabase(query),
                  TimeUtil.toTimePrecision(timeUnit), query.getCommandWithUrlEncoded(), null);
        } else {
          call = this.influxDBService.query(getDatabase(query),
                  TimeUtil.toTimePrecision(timeUnit), query.getCommandWithUrlEncoded());
        }
    }
    return executeQuery(call);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void createDatabase(final String name) {
    Preconditions.checkNonEmptyString(name, "name");
    String createDatabaseQueryString = String.format("CREATE DATABASE \"%s\"", name);
    executeQuery(this.influxDBService.postQuery(Query.encode(createDatabaseQueryString)));
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void deleteDatabase(final String name) {
    executeQuery(this.influxDBService.postQuery(Query.encode("DROP DATABASE \"" + name + "\"")));
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public List<String> describeDatabases() {
    QueryResult result = executeQuery(this.influxDBService.postQuery(SHOW_DATABASE_COMMAND_ENCODED));
    // {"results":[{"series":[{"name":"databases","columns":["name"],"values":[["mydb"]]}]}]}
    // Series [name=databases, columns=[name], values=[[mydb], [unittest_1433605300968]]]
    List<List<Object>> databaseNames = result.getResults().get(0).getSeries().get(0).getValues();
    List<String> databases = new ArrayList<>();
    if (databaseNames != null) {
      for (List<Object> database : databaseNames) {
        databases.add(database.get(0).toString());
      }
    }
    return databases;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean databaseExists(final String name) {
    List<String> databases = this.describeDatabases();
    for (String databaseName : databases) {
      if (databaseName.trim().equals(name)) {
        return true;
      }
    }
    return false;
  }

  /**
   * Calls the influxDBService for the query.
   */
  private Call<QueryResult> callQuery(final Query query) {
    Call<QueryResult> call;
    if (query instanceof BoundParameterQuery) {
        BoundParameterQuery boundParameterQuery = (BoundParameterQuery) query;
        call = this.influxDBService.postQuery(getDatabase(query), query.getCommandWithUrlEncoded(),
                boundParameterQuery.getParameterJsonWithUrlEncoded());
    } else {
        if (query.requiresPost()) {
          call = this.influxDBService.postQuery(getDatabase(query), query.getCommandWithUrlEncoded());
        } else {
          call = this.influxDBService.query(getDatabase(query), query.getCommandWithUrlEncoded());
        }
    }
    return call;
  }

  static class ErrorMessage {
    public String error;
  }

  private boolean checkMessagePackSupport() {
    Matcher matcher = Pattern.compile("(\\d+\\.*)+").matcher(version());
    if (!matcher.find()) {
      return false;
    }
    String s = matcher.group();
    String[] versionNumbers = s.split("\\.");
    final int major = Integer.parseInt(versionNumbers[0]);
    final int minor = Integer.parseInt(versionNumbers[1]);
    final int fromMinor = 4;
    return (major >= 2) || ((major == 1) && (minor >= fromMinor));
  }

  private QueryResult executeQuery(final Call<QueryResult> call) {
    if (messagePack) {
      if (messagePackSupport == null) {
        messagePackSupport = checkMessagePackSupport();
      }

      if (!messagePackSupport) {
        throw new UnsupportedOperationException(
            "MessagePack format is only supported from InfluxDB version 1.4 and later");
      }
    }
    return execute(call);
  }

  private <T> T execute(final Call<T> call) {
    try {
      Response<T> response = call.execute();
      if (response.isSuccessful()) {
        return response.body();
      }
      try (ResponseBody errorBody = response.errorBody()) {
        if (messagePack) {
          throw InfluxDBException.buildExceptionForErrorState(errorBody.byteStream());
        } else {
          throw InfluxDBException.buildExceptionForErrorState(errorBody.string());
        }
      }
    } catch (IOException e) {
      throw new InfluxDBIOException(e);
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void flush() {
    if (!batchEnabled.get()) {
      throw new IllegalStateException("BatchProcessing is not enabled.");
    }
    batchProcessor.flush();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void close() {
    try {
        this.disableBatch();
    } finally {
        if (datagramSocket != null && !datagramSocket.isClosed()) {
            datagramSocket.close();
        }
    }
    this.client.dispatcher().executorService().shutdown();
    this.client.connectionPool().evictAll();
  }

  @Override
  public InfluxDB setConsistency(final ConsistencyLevel consistency) {
    this.consistency = consistency;
    return this;
  }

  @Override
  public InfluxDB setDatabase(final String database) {
    this.database = database;
    return this;
  }

  @Override
  public InfluxDB setRetentionPolicy(final String retentionPolicy) {
    this.retentionPolicy = retentionPolicy;
    return this;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void createRetentionPolicy(final String rpName, final String database, final String duration,
                                    final String shardDuration, final int replicationFactor, final boolean isDefault) {
    Preconditions.checkNonEmptyString(rpName, "retentionPolicyName");
    Preconditions.checkNonEmptyString(database, "database");
    Preconditions.checkNonEmptyString(duration, "retentionDuration");
    Preconditions.checkDuration(duration, "retentionDuration");
    if (shardDuration != null && !shardDuration.isEmpty()) {
      Preconditions.checkDuration(shardDuration, "shardDuration");
    }
    Preconditions.checkPositiveNumber(replicationFactor, "replicationFactor");

    StringBuilder queryBuilder = new StringBuilder("CREATE RETENTION POLICY \"");
    queryBuilder.append(rpName)
        .append("\" ON \"")
        .append(database)
        .append("\" DURATION ")
        .append(duration)
        .append(" REPLICATION ")
        .append(replicationFactor);
    if (shardDuration != null && !shardDuration.isEmpty()) {
      queryBuilder.append(" SHARD DURATION ");
      queryBuilder.append(shardDuration);
    }
    if (isDefault) {
      queryBuilder.append(" DEFAULT");
    }
    executeQuery(this.influxDBService.postQuery(Query.encode(queryBuilder.toString())));
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void createRetentionPolicy(final String rpName, final String database, final String duration,
                                    final int replicationFactor, final boolean isDefault) {
    createRetentionPolicy(rpName, database, duration, null, replicationFactor, isDefault);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void createRetentionPolicy(final String rpName, final String database, final String duration,
                                    final String shardDuration, final int replicationFactor) {
    createRetentionPolicy(rpName, database, duration, null, replicationFactor, false);
  }

  /**
   * {@inheritDoc}
   * @param rpName the name of the retentionPolicy
   * @param database the name of the database
   */
  @Override
  public void dropRetentionPolicy(final String rpName, final String database) {
    Preconditions.checkNonEmptyString(rpName, "retentionPolicyName");
    Preconditions.checkNonEmptyString(database, "database");
    StringBuilder queryBuilder = new StringBuilder("DROP RETENTION POLICY \"");
    queryBuilder.append(rpName)
        .append("\" ON \"")
        .append(database)
        .append("\"");
    executeQuery(this.influxDBService.postQuery(Query.encode(queryBuilder.toString())));
  }

  private String getDatabase(final Query query) {
    String db = query.getDatabase();
    if (db == null) {
      return this.database;
    }
    return db;
  }

  private interface ChunkProccesor {
    void process(ResponseBody chunkedBody, Cancellable cancellable,
                 BiConsumer<Cancellable, QueryResult> consumer, Runnable onComplete) throws IOException;
  }

  private class MessagePackChunkProccesor implements ChunkProccesor {
    @Override
    public void process(final ResponseBody chunkedBody, final Cancellable cancellable,
                        final BiConsumer<Cancellable, QueryResult> consumer, final Runnable onComplete)
            throws IOException {
      MessagePackTraverser traverser = new MessagePackTraverser();
      try (InputStream is = chunkedBody.byteStream()) {
        for (Iterator<QueryResult> it = traverser.traverse(is).iterator(); it.hasNext() && !cancellable.isCanceled();) {
          QueryResult result = it.next();
          consumer.accept(cancellable, result);
        }
      }
      if (!cancellable.isCanceled()) {
        onComplete.run();
      }
    }
  }

  private class JSONChunkProccesor implements ChunkProccesor {
    private JsonAdapter<QueryResult> adapter;

    public JSONChunkProccesor(final JsonAdapter<QueryResult> adapter) {
      this.adapter = adapter;
    }

    @Override
    public void process(final ResponseBody chunkedBody, final Cancellable cancellable,
                        final BiConsumer<Cancellable, QueryResult> consumer, final Runnable onComplete)
            throws IOException {
      try {
        BufferedSource source = chunkedBody.source();
        while (!cancellable.isCanceled()) {
          QueryResult result = adapter.fromJson(source);
          if (result != null) {
            consumer.accept(cancellable, result);
          }
        }
      } catch (EOFException e) {
        QueryResult queryResult = new QueryResult();
        queryResult.setError("DONE");
        consumer.accept(cancellable, queryResult);
        if (!cancellable.isCanceled()) {
          onComplete.run();
        }
      } finally {
        chunkedBody.close();
      }
    }
  }
}


text:
package org.apereo.cas.services;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.FileUtils;
import org.apereo.cas.authentication.principal.Principal;
import org.junit.Test;

import java.io.File;
import java.io.IOException;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

/**
 * @author Misagh Moayyed
 * @since 4.1.0
 */
public class DefaultRegisteredServiceUsernameProviderTests {

    private static final File JSON_FILE = new File(FileUtils.getTempDirectoryPath(), "defaultRegisteredServiceUsernameProvider.json");
    private static final ObjectMapper MAPPER = new ObjectMapper();

    @Test
    public void verifyRegServiceUsername() {
        final DefaultRegisteredServiceUsernameProvider provider =
                new DefaultRegisteredServiceUsernameProvider();

        final Principal principal = mock(Principal.class);
        when(principal.getId()).thenReturn("id");
        final String id = provider.resolveUsername(principal, RegisteredServiceTestUtils.getService());
        assertEquals(id, principal.getId());
    }

    @Test
    public void verifyEquality() {
        final DefaultRegisteredServiceUsernameProvider provider =
                new DefaultRegisteredServiceUsernameProvider();

        final DefaultRegisteredServiceUsernameProvider provider2 =
                new DefaultRegisteredServiceUsernameProvider();

        assertEquals(provider, provider2);
    }

    @Test
    public void verifySerializeADefaultRegisteredServiceUsernameProviderToJson() throws IOException {
        final DefaultRegisteredServiceUsernameProvider providerWritten = new DefaultRegisteredServiceUsernameProvider();

        MAPPER.writeValue(JSON_FILE, providerWritten);

        final RegisteredServiceUsernameAttributeProvider providerRead = MAPPER.readValue(JSON_FILE, DefaultRegisteredServiceUsernameProvider.class);

        assertEquals(providerWritten, providerRead);
    }
}

redpajama_set_name: RedPajamaGithub


text:
package io.moquette.fce.service.validation;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.JsonLoader;
import com.github.fge.jsonschema.core.exceptions.ProcessingException;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;

/**
 * Utility class for json schema validation.
 *
 * @author lants1
 *
 */
public final class JsonSchemaValidationService implements ISchemaValidationService {

	private static final Logger LOGGER = Logger.getLogger(JsonSchemaValidationService.class.getName());

	private ByteBuffer schema;

	public JsonSchemaValidationService(ByteBuffer schema) {
		this.schema = schema;
	}

	@Override
	public boolean isSchemaValid(ByteBuffer msgToValidate) {
		try {
			final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();

			BufferedReader schemaReader = new BufferedReader(
					new InputStreamReader(new ByteArrayInputStream(schema.array()), StandardCharsets.UTF_8));
			BufferedReader msgReader = new BufferedReader(
					new InputStreamReader(new ByteArrayInputStream(msgToValidate.array()), StandardCharsets.UTF_8));

			JsonNode schemaJson = JsonLoader.fromReader(schemaReader);
			JsonNode jsonToVavlidate = JsonLoader.fromReader(msgReader);
			factory.getJsonSchema(schemaJson);
			JsonSchema validationSchema = factory.getJsonSchema(schemaJson);

			return validationSchema.validate(jsonToVavlidate).isSuccess();
		} catch (ProcessingException | IOException e) {
			LOGGER.log(Level.INFO, "json schema validation failed: ", e);
			return false;
		}
	}
}


text:
import base64
import hashlib
import os

from itsdangerous import (
    BadSignature, Signer as _Signer, TimestampSigner as _TimestampSigner,
)

__all__ = ["BadSignature", "Signer", "TimestampSigner", "random_token"]

def random_token():
    token = base64.urlsafe_b64encode(os.urandom(32)).rstrip(b"=")
    return token.decode("utf8")

class Signer(_Signer):

    default_digest_method = hashlib.sha512
    default_key_derivation = "hmac"

class TimestampSigner(_TimestampSigner):

    default_digest_method = hashlib.sha512
    default_key_derivation = "hmac"


text:
(function () {

  var app = angular.module('interactionFactory', ['ngResource']);

  app.factory('Interaction', ['$resource', '$rootScope', function($resource, $rootScope){
      return $resource($rootScope.server + "api/interactions/:id", {id: "@id"}, {
          get: { method: 'GET', isArray: false},
          create: { method: 'POST', isArray:true},
          delete: { method: 'DELETE', isArray:true},
          all: {method:'GET', isArray:true}
      });
  }]);

})();


text:
namespace Atata.IntegrationTests.Triggers;

public class PressHomeAttributeTests : UITestFixture
{
    [Test]
    public void Execute()
    {
        var sut = Go.To<ScrollablePage>()
            .Press(Keys.End)
            .TopText;

        sut.Should.Not.BeVisibleInViewPort();
        sut.Metadata.Add(new PressHomeAttribute(TriggerEvents.BeforeGet));

        sut.Get(out _);
        sut.Should.BeVisibleInViewPort();
    }
}


text:
package net.sourceforge.marathon.model;

import java.io.IOException;
import java.nio.file.Path;
import java.util.logging.Logger;

import junit.framework.Test;
import net.sourceforge.marathon.junit.TestCreator;
import net.sourceforge.marathon.runtime.api.IConsole;

public class GroupFolderEntry extends GroupEntry {

    public static final Logger LOGGER = Logger.getLogger(GroupFolderEntry.class.getName());

    private Path path;

    public GroupFolderEntry(String name) throws IOException {
        super(GroupEntryType.FOLDER, name);
        path = new TestCreator(false, null).getFile(name).toPath();
    }

    @Override
    public String getName() {
        return super.getRawName();
    }

    @Override
    public Path getFilePath() {
        return path;
    }

    @Override
    public void setName(String name) {
    }

    @Override
    public Test getTest(boolean acceptChecklist, IConsole console) throws IOException {
        return new TestCreator(acceptChecklist, console).getTest(super.getRawName());
    }

    @Override
    public boolean canPlaySingle() {
        return false;
    }

    @Override
    public String toString() {
        return super.getRawName();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + (path == null ? 0 : path.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        GroupFolderEntry other = (GroupFolderEntry) obj;
        if (path == null) {
            if (other.path != null) {
                return false;
            }
        } else if (!path.equals(other.path)) {
            return false;
        }
        return true;
    }

    @Override
    public void refresh() {
    }

    @Override
    public void rename(String text) {
    }
}


text:
<!DOCTYPE html>

    <meta charset="UTF-8" />
    <meta name="robots" content="index, follow, all" />
    <title>Michaels\Manager\Traits\ManagesIocTrait | Data Manager API</title>

            <link rel="stylesheet" type="text/css" href="../../../css/bootstrap.min.css">
        <link rel="stylesheet" type="text/css" href="../../../css/bootstrap-theme.min.css">
        <link rel="stylesheet" type="text/css" href="../../../css/sami.css">

        <meta name="MobileOptimized" content="width">
        <meta name="HandheldFriendly" content="true">
        <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">

                <form id="search-form" action="../../../search.html" method="GET">

            <input name="search"
                   class="typeahead form-control"
                   type="search"
                   placeholder="Search">
        </form>

                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-elements">
                    Toggle navigation

                </button>
                Data Manager API

Classes

Namespaces

Interfaces

Traits

Index

Search

trait

Michaels

Manager

Traits

ManagesIocTrait

            ManagesIocTrait

    trait
    ManagesIocTrait

Manages complex, nested data

Traits

                                            DependsOnManagesItemsTrait

Methods

                    $this

                    initManager(array $items = null)

Initializes a new manager instance.

from DependsOnManagesItemsTrait

                    $this

                    hydrate($data, bool $append = false)

Hydrate with external data, optionally append

from DependsOnManagesItemsTrait

                    $this

                    add(string $alias, callable|string|object $factory = null, array $declared = null)

Adds a dependency to the manager

                    $this

                    set(string $alias, null $item = null)

Updates an item

from DependsOnManagesItemsTrait

                    int

                    push(string $alias, mixed $value, null|mixed $other = null)

Push a value or values onto the end of an array inside manager

from DependsOnManagesItemsTrait

                    mixed

                    get(string $alias, string|mixed $fallback = '_michaels_no_fallback')

Returns the request object with all dependencies

                    NoItemFoundMessage

                    getIfExists($alias)

Return an item if it exist

from DependsOnManagesItemsTrait

                    NoItemFoundMessage

                    getIfHas($alias)

Return an item if it exist
Alias of getIfExists()

from DependsOnManagesItemsTrait

                    array

                    getAll()

Return all items as array

from DependsOnManagesItemsTrait

                    array

                    all()

Return all items as array
Alias of getAll()

from DependsOnManagesItemsTrait

                    bool

                    exists($alias)

Confirm or deny that an item exists

from DependsOnManagesItemsTrait

                    bool

                    has($alias)

Confirm or deny that an item exists
Alias of exists()

from DependsOnManagesItemsTrait

                    boolean

                    isEmpty()

Confirm that manager has no items

from DependsOnManagesItemsTrait

                    $this

                    remove($alias)

Deletes an item

from DependsOnManagesItemsTrait

                    $this

                    clear()

Clear the manager

from DependsOnManagesItemsTrait

                    mixed

                    reset(array $items)

Reset the manager with an array of items
Alias of initManager()

from DependsOnManagesItemsTrait

                    string

                    toJson(int $options)

Get the collection of items as JSON.

from DependsOnManagesItemsTrait

                    string

                    __toString()

When manager instance is used as a string, return json of items

from DependsOnManagesItemsTrait

                    mixed

                    fetch(string $alias, string|mixed $fallback = '_michaels_no_fallback')

Alias of get() for backwards comparability

                    mixed

                    share($alias)

Turns a dependency into a singleton.

                    $this

                    setup($alias, $pipeline)

Add a pipeline to to the que

Details

in DependsOnManagesItemsTrait at line         line 15

            abstract                $this
    initManager(array $items = null)

Initializes a new manager instance.

This is useful for implementations that have their own __construct method
This is an alias for reset()

Parameters

                array
                $items

Return Value

            $this

in DependsOnManagesItemsTrait at line         line 24

            abstract                $this
    hydrate($data, bool $append = false)

Hydrate with external data, optionally append

Parameters

                $data
                string     The data to be hydrated into the manager

                bool
                $append
                When true, data will be appended to the current set

Return Value

            $this

at line         line 87

                            $this
    add(string $alias, callable|string|object $factory = null, array $declared = null)

Adds a dependency to the manager

$factory can be a:
     string      Full class name for a new object each time
     callable    Factory to create new object (passed manager)
     object      The exact object to be returned

Parameters

                string
                $alias

                callable|string|object
                $factory

                array
                $declared

Return Value

            $this

in DependsOnManagesItemsTrait at line         line 46

            abstract                $this
    set(string $alias, null $item = null)

Updates an item

Parameters

                string
                $alias

                null
                $item

Return Value

            $this

in DependsOnManagesItemsTrait at line         line 56

            abstract                int
    push(string $alias, mixed $value, null|mixed $other = null)

Push a value or values onto the end of an array inside manager

Parameters

                string
                $alias
                The level of nested data

                mixed
                $value
                The first value to append

                null|mixed
                $other
                Optional other values to apend

Return Value

            int
            Number of items pushed

Exceptions

                ItemNotFoundException
                If pushing to unset array

at line         line 33

                            mixed
    get(string $alias, string|mixed $fallback = '_michaels_no_fallback')

Returns the request object with all dependencies

Overrides the get() method on ManagesItemsTrait
Use getRaw() to return the raw value

string      Full class name for a new object each time
callable    Factory to create new object (passed manager)
object      The exact object to be returned

Parameters

                string
                $alias

                string|mixed
                $fallback

Return Value

            mixed

Exceptions

                Exception

in DependsOnManagesItemsTrait at line         line 73

            abstract                NoItemFoundMessage
    getIfExists($alias)

Return an item if it exist

Parameters

                $alias

Return Value

            NoItemFoundMessage

in DependsOnManagesItemsTrait at line         line 82

            abstract                NoItemFoundMessage
    getIfHas($alias)

Return an item if it exist
Alias of getIfExists()

Parameters

                $alias

Return Value

            NoItemFoundMessage

in DependsOnManagesItemsTrait at line         line 89

            abstract                array
    getAll()

Return all items as array

Return Value

            array

in DependsOnManagesItemsTrait at line         line 96

            abstract                array
    all()

Return all items as array
Alias of getAll()

Return Value

            array

in DependsOnManagesItemsTrait at line         line 104

            abstract                bool
    exists($alias)

Confirm or deny that an item exists

Parameters

                $alias

Return Value

            bool

in DependsOnManagesItemsTrait at line         line 113

            abstract                bool
    has($alias)

Confirm or deny that an item exists
Alias of exists()

Parameters

                $alias

Return Value

            bool

in DependsOnManagesItemsTrait at line         line 119

            abstract                boolean
    isEmpty()

Confirm that manager has no items

Return Value

            boolean

in DependsOnManagesItemsTrait at line         line 127

            abstract                $this
    remove($alias)

Deletes an item

Parameters

                $alias

Return Value

            $this

in DependsOnManagesItemsTrait at line         line 133

            abstract                $this
    clear()

Clear the manager

Return Value

            $this

in DependsOnManagesItemsTrait at line         line 142

            abstract                mixed
    reset(array $items)

Reset the manager with an array of items
Alias of initManager()

Parameters

                array
                $items

Return Value

            mixed

in DependsOnManagesItemsTrait at line         line 150

            abstract                string
    toJson(int $options)

Get the collection of items as JSON.

Parameters

                int
                $options

Return Value

            string

in DependsOnManagesItemsTrait at line         line 156

            abstract                string
    __toString()

When manager instance is used as a string, return json of items

Return Value

            string

at line         line 69

                            mixed
    fetch(string $alias, string|mixed $fallback = '_michaels_no_fallback')

Alias of get() for backwards comparability

Parameters

                string
                $alias

                string|mixed
                $fallback

Return Value

            mixed

Exceptions

                Exception

at line         line 118

                            mixed
    share($alias)

Turns a dependency into a singleton.

Parameters

                $alias

Return Value

            mixed

at line         line 130

                            $this
    setup($alias, $pipeline)

Add a pipeline to to the que

Parameters

                $alias

                $pipeline

Return Value

            $this

        Generated by Sami, the API Documentation Generator.


text:
$(document).ready(function(){

  // function removeNo() {
  //   setTimeout(function(){ $(document).remove('body', '#no'); }, 2000);
  // }

  $('#button').on('click', function(e) {
    e.preventDefault();
    console.log("got here");
    $(this).remove();
    $('body').append('
NO
');
    // removeNo();
    $('body').prepend('
remove
');
  });

  $('body').on('click', '#remove-button', function(e) {
    $(this).remove();
    $('#no').remove();
  })

  $(".column").hover(function(e){
    $('.hover').remove()
    var columnId = $(this).attr('id');
    var column = $('#' + columnId).children();
    if (turnCounter % 2 === 0){
      $(column[0]).html("")}
    else
      $(column[0]).html("")

  });
  $(".column").on("click", function(e){
    // console.log(e)
    $('.hover').remove()
    var columnId = $(this).attr('id');

    var column = $('#' + columnId).children();

    var lastEmpty = ifFull(column);

    if (lastEmpty != undefined)
      appendToken(lastEmpty);
    brains(columnId);
  });

turnCounter = 0

  function findEmpty(column){
    for(i=0; i< column.length; i++){
      if ($(column[i]).attr('class') === "square full"){
        return column[i-1]
      }
    }
    return $(column).last()
  }

  function appendToken(lastEmpty){
    if (turnCounter % 2 === 0)
    $(lastEmpty).append("")
    else
    $(lastEmpty).append("");

    $(lastEmpty).addClass('full');
    turnCounter += 1
  }

  function ifFull(column){
    if($(column[1]).attr("class")=== "square full")
      alert("Column already full");
    else
      return findEmpty(column)
  }

var board = function() {

  var grid = [
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0]
  ];
  this.connectFour = function (collections) {
    oneCount = 0
    twoCount = 0
    for (var row = 0; row < collections.length; row++) {
      oneCount = 0
      twoCount = 0
      for (var column = 0; column < collections[row].length; column++) {

        if (collections[row][column] == 1) {
          oneCount++;
        }
        else {
          oneCount = 0;
        }
        if (oneCount == 4) {
          return 1;
        }
        if (collections[row][column] == 2) {
          twoCount++;
        }
        else {
          twoCount = 0;
        }
        //console.log(oneCount);
        if (twoCount == 4) {
          return 2;
        }
      }
      //if (oneCount == 4) {return true;}
    }
    return 0;
  }
  this.drop = function (column, playerId) {
    for (var i = 5; i >= 0; i--) {
      if (grid[i][column] == 0) {
        update(playerId, i, column)
        return [i, column];
      }
    }
  }
  this.grid = function () {
    return grid;
  }
function update(playerId, row, column) {
      grid[row][column] = playerId;
    }

}
var forwardslash= function(position, board){
  var positionAlias = [ position[0], position[1] ]

  while (positionAlias[0] < 5 && positionAlias[1] > 0) {
      positionAlias[0]++;
      positionAlias[1]--;
    };
    var collection = [ [ positionAlias[0], positionAlias[1] ] ];
    while (positionAlias[0] > 0 && positionAlias[1] < 6) {
      positionAlias[0]--;
      positionAlias[1]++;
      collection.push([ positionAlias[0], positionAlias[1] ]);
    };

    var values = collection.map(function(loc) {return board[ loc[0] ][ loc[1] ]});
    return values;
  }

var backslash= function(position, board){
  var positionAlias = [ position[0], position[1] ]

  while (positionAlias[0] > 0 && positionAlias[1] > 0) {
      positionAlias[0]--;
      positionAlias[1]--;
    };
    var collection = [ [ positionAlias[0], positionAlias[1] ] ];
    while (positionAlias[0] < 5 && positionAlias[1] < 6) {
      positionAlias[0]++;
      positionAlias[1]++;
      collection.push([ positionAlias[0], positionAlias[1] ]);
    };

    var values = collection.map(function(loc) {return board[ loc[0] ][ loc[1] ]});
    return values;
  }

function getCol(board, loc) {
  var column = [];
  for (var i = 0; i < board.length; i++) {
    column.push(board[i][loc[1]]);
  }
  return column;
}

b = new board();

  function brains(column) {

    var playerId = (turnCounter % 2) + 1;
    var coordinate = b.drop(column, playerId);

    var row = coordinate[0];
    var cols = getCol(b.grid(), coordinate);
    var frontSlash = forwardslash(coordinate, b.grid());
    var notbackslash = backslash(coordinate, b.grid());

    var collection = [cols, b.grid()[row], frontSlash, notbackslash];
    var winner = b.connectFour(collection);

    if(winner === 1) {
      // alert('Cthulhu Wins!!!');
    $('body').prepend('
Cthulhu Wins!!!');
    } else if(winner === 2) {
      $('body').prepend('
Bellatrix Wins!!');
      // alert('Bellatrix Wins!!!!');
    };
  };

});


text:
//
// Copyright 2011-2014 NimbusKit
//
// 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.
//

#import <UIKit/UIKit.h>

@class NICSSRuleset;
@class NIDOM;

@interface UILabel (NIStyleable)

/**
 * Applies the given rule set to this label.
 *
 * This method is exposed primarily for subclasses to use when implementing the
 * applyStyleWithRuleSet: method from NIStyleable.
 */
- (void)applyLabelStyleWithRuleSet:(NICSSRuleset *)ruleSet DEPRECATED_ATTRIBUTE;

/**
 * Applies the given rule set to this label.
 *
 * This method is exposed primarily for subclasses to use when implementing the
 * applyStyleWithRuleSet: method from NIStyleable.
 */
- (void)applyLabelStyleWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;

/**
 * Applies the given rule set to this label.
 *
 * This method is exposed primarily for subclasses to use when implementing the
 * applyStyleWithRuleSet: method from NIStyleable. Since some of the view
 * styles (e.g. positioning) may rely on some label elements (like text), this is called
 * before the view styling is done.
 */
- (void)applyLabelStyleBeforeViewWithRuleSet:(NICSSRuleset *)ruleSet inDOM: (NIDOM*) dom;

@end


text:
<?php

// variable functions
$trigFunctions = array("sin", "cos", "tan");
$degrees = 30;

foreach ($trigFunctions as $trigFunction) {
	echo "$trigFunction($degrees) = " . $trigFunction(deg2rad($degrees)) . "
";
}

// hello function
function hello() {
	echo "Hello, world!
";
}

hello();

// scope (includes scope.php)
function helloWithVariables() {
	$hello = "Hello, ";
	$world = "world!";
	return $hello . $world . "
";
}

echo helloWithVariables();

function describeMyDog() {
	$color = "brown";
	echo "My dog is $color
";
}

$color = "black";

describeMyDog();
echo "My cat is $color
";

// global variables
$myGlobal = "Hello there!";

function global_hello() {
	global $myGlobal;
	echo "$myGlobal
";
}

global_hello();

// superglobals i.e. $GLOBALS array
$myGlobal = "Hello there!";

function superglobal_hello() {
	echo $GLOBALS["myGlobal"] . "
";
}

superglobal_hello();

// static variables
function nextNumber() {
	$counter = 0;
	return ++$counter;
}

echo "I've counted to: " . nextNumber() . "
";
echo "I've counted to: " . nextNumber() . "
";
echo "I've counted to: " . nextNumber() . "

";

function static_nextNumber() {
	static $counter = 0;
	return ++$counter;
}

echo "I've counted to: " . static_nextNumber() . "
";
echo "I've counted to: " . static_nextNumber() . "
";
echo "I've counted to: " . static_nextNumber() . "

";

// anonymous functions
$mode = "+";
$processNumbers = create_function('$a, $b', "return \$a $mode \$b;");
echo $processNumbers(2,3);

?>


text:
//
//  LNSearchResultViewController.h
//  LookNovel
//
//  Created by wangchengshan on 2019/5/21.
//  Copyright © 2019 wcs Co.,ltd. All rights reserved.
//

#import "LNTableViewController.h"

NS_ASSUME_NONNULL_BEGIN

@interface LNSearchResultViewController : LNTableViewController
/**搜索的文本*/
@property (nonatomic, copy) NSString *searchText;
@end

NS_ASSUME_NONNULL_END


text:
// HotDocs Browser Language Module: German (generic/experimental)

/* language\hdlang_fr.js */
var HOTDOC$ = window.HOTDOC$ || {}; // namespace object for HotDocs Server interviews
if (!HOTDOC$.Locales) HOTDOC$.Locales = {};
// Register the new language module with the HotDocs locale infrastructure
HOTDOC$.Locales["fr-FR"] = {
  name: "French",
  // Date & Number formatting info
  dateOrder: "DMY",
  shortDateFormat: "dd/MM/yyyy",
  months: ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"],
  monthsShort: ["Jan", "Fév", "Mar", "Avr", "Mai", "Juin", "Juil", "Août", "Sept", "Oct", "Nov", "Déc"],
  days: ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"],
  daysShort: ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"],
  //yearPrefix: ["Ein", "Zwei"],
  calWeekBegin: 1,
  calWeekend: [0, 6],
  zeroFormats: ["Zéro"],
  numSeps: [",", " "], // first is decimal separator, followed by thousands separator
  // Localizable Strings

  strings: {
    // various standard user interface elements:
    ui_hd: "HotDocs", // used in the title bar of error message boxes, where possible
    ui_hdvers: "HotDocs Browser Interview Runtime version", // HotDocs Browser Interview Runtime version
    ui_logo: "Propulsé par HotDocs Server", // Powered by HotDocs Server
    ui_load: "Chargement du questionnaire...", // Chargement de l'Interview HotDocs... // Loading HotDocs Interview...
    ui_addl: "Des composants additionnels sont téléchargés ...", // Additional components are downloading...
    ui_wait: "Veuillez patienter", // Please wait
    ui_wait_cmp: "Merci de patienter pendant que d'autres composants sont téléchargés ...", // Please wait while additional components are downloaded...
    ui_help: "Aide HotDocs Server", // HotDocs Server Help
    ui_helpcaption: "Aide", // Help
    ui_io: "Structure du Questionnaire", // Interview Outline
    ui_yes: "Oui", // Yes
    ui_no: "Non", // No
    ui_unans: "*** Non répondu ***",
    ui_other: "Autre", // Other
    ui_nota: "Aucune de ces réponses", // None of the Above
    ui_cal: "Calendrier", // Calendar
    ui_ssbedit: "Editer la ligne", // Edit Row
    ui_ssbins: "Insérer une ligne", // Insert Row
    ui_ssbdel: "Effacer la ligne", // Delete Row
    ui_rownum: " [Ligne {0}]", // [Row {0}] (appended to dialog title during "edit row" operations)
    ui_rownew: " [Nouvelle Ligne]", // [New Row] (appended to dialog title during "edit row" operations)
    ui_new: "Nouveau", // New (prefix for unanswered dialog iterations)
    ui_rtntiv: "Retour au questionnaire", // Back to Interview
    ui_sresult: "Résultats du serveur", // Server Results (default title for server results pane, not typically seen but possible with JS API)
    ui_select: "Sele&ct", // Sele&ct
    ui_selectcaption: "Choisissez parmi les sources de réponses", // Select from Answer Source
    ui_cancel: "Annuler", // Cancel
    ui_addbtn: "&Ajouter", // Add Another
    ui_mnutt: "Menu Dialogue", // Dialog Menu
    ui_err: "Erreur", // Error
    ui_close: "Fermer", // Close
    ui_emptydlg: "Dialogue vide", // Empty Dialog
    ui_etc: ", etc.", // etc.
    ui_dataload: "Chargement des données...", // Loading data...

    // Interview Help page
    hlp_to: "Pour", // To
    hlp_do: "Faire", // Do This
    hlp_intro: "Ce guide décrit comment effectuer une interview HotDocs Server depuis un navigateur web. HotDocs Server est la version de HotDocs qui utilise un navigateur Web standard pour afficher les interviews HotDocs, ou des séances de collecte de réponses. Ces réponses sont ensuite utilisées pour assembler des documents sur un serveur Web. (Pour plus d'informations sur HotDocs Server, visitez www.hotdocs.com .)",
    hlp_intro2: "Lorsque vous sélectionnez un modèle pour l'assemblage, HotDocs Server présente une interview dans le navigateur Web pour recueillir des réponses requises par le modèle. Pour vous aider à répondre aux questions, la fenêtre d'interview est divisés en trois volets: la présentation de la structure du questionnaire, le volet de dialogue, et le volet des ressources. La structure du questionnaire donne un aperçu des questions auxquelles vous devez répondre, tandis que le volet de dialogue affiche les questions spécifiques. Le volet des ressources fournit des informations utiles pour vous aider à répondre à des questions ou des dialogues spécifiques.",
    // Interview Outline Help Section
    hlp_io_ovw: "La structure du questionnaire répertorie toutes les boîtes de dialogue (ou groupes de questions) de l'interview et vous permet de vous déplacer rapidement à n'importe quel dialogue dont vous avez besoin dans l'interview. Lorsque vous cliquez sur le nom d'une boîte de dialogue, la boîte de dialogue apparaît dans le volet dialogue afin que vous puissiez répondre aux questions qui la composent.",
    hlp_io_tbl: "Les icônes suivantes sont utilisées dans la structure du questionnaire pour montrer l'état des questions dans chaque boîte de dialogue, et peut vous aider à déterminer quels dialogues contiennent des questions auxquelles vous devez encore répondre: ",
    hlp_io_du: "Aucune des questions dans la boîte de dialogue n'a de réponse.", // None of the questions in the dialog are answered.
    hlp_io_dn: "Une nouvelle répétition d'un dialogue dans lequel aucune des questions n'a de réponse.", // A new repetition of a repeated dialog in which none of the questions are answered.
    hlp_io_dp: "Au moins une des questions posées dans la boîte de dialogue a une réponse.", // At least one of the questions in the dialog is answered.
    hlp_io_da: "Toutes les questions requises dans la boîte de dialogue ont une réponse.", // All required questions in the dialog are answered.
    hlp_io_dr: "Le dialogue contient au moins une question requise sans réponse.", // The dialog contains at least one unanswered required question.
    hlp_io_dug: "Le dialogue ne peut accepter de réponses tant que les questions requises dans les dialogues précédents n'ont pas de réponses.", // The dialog cannot be answered until required questions in previous dialogs are answered.
    hlp_io_loc: "Par défaut, la structure de l'interview apparaît à gauche de la fenêtre de dialogue, mais vous pouvez modifier sa largeur ou sa position si nécessaire. Par exemple, si vous avez besoin de plus d'espace pour répondre à des questions dans le volet de dialogue, vous pouvez réduire ou masquer la structure de l'interview. Le tableau suivant montre comment modifier la largeur et la position du contour de l'interview: ", // By default, the interview outline appears to the left of the dialog pane, but you can change its width or position as needed. For example, if you need more space for answering questions in the dialog pane, you can shrink or hide the interview outline. The following table shows how to change the width and position of the interview outline:
    hlp_io_widT: "Modifier la largeur de la partie structure de l'interview", // Change the width of the interview outline
    hlp_io_widD: "Faites glisser le séparateur entre le volet avec la structure de l'interview et le volet de dialogue.", // Drag the border separating the interview outline and dialog pane.
    hlp_io_clsT: "Fermer la structure du questionnaire",
    hlp_io_clsD: "Cliquez sur le bouton {0}Fermer dans le coin haut droit de la structure du questionnaire. Pour l'afficher à nouveau, cliquez sur le bouton {1}Afficher la structure du questionnaire.",
    hlp_io_vdlT: "Voir la structure du questionnaire sous forme de liste",
    hlp_io_vdlD: "Quand la structure du questionnaire est masquée, cliquez sur la flèche à côté du bouton {0}Afficher la structure du questionnaire. Quand la liste apparaît, cliquez sur un titre de dialogue pour aller vers ce dialogue.",
    // Dialog Pane Help Section
    hlp_dp: "Boîtes de dialogue",
    hlp_dp_ovw: "Les questions auxquelles vous devez répondre sont présentées dans des boîtes de dialogue. Certaines questions apparaissent plusieurs fois comme une série de dialogues ou comme un tableau de données. Cela permet d'entrer plusieurs réponses pour une même question, en créant ainsi une liste de réponses. Enfin, certaines questions apparaissent dans un dialogue imbriqué. Les dialogues imbriqués représentent généralement des questions qui dépendent les unes des autres ou qui sont liés à des questions dans la boîte de dialogue principale. Elles apparaissent généralement comme une icône dans la boîte de dialogue principale, mais elles peuvent aussi apparaître comme un tableau de données dans la boîte de dialogue principale.",
    hlp_dp_tbl: "Le tableau suivant vous montre comment naviguer entre les boîtes de dialogue et répondre à plusieurs types de questions :",
    hlp_dp_txtT: "Champs texte",
    hlp_dp_txtD: "Entrez votre réponse dans un champ texte.",
    hlp_dp_chkT: "Cases à cocher et choix d'options",
    hlp_dp_chkD: "Cochez la case avec votre souris ou appuyez sur la barre d'espace.",
    hlp_dp_calT: "Questions date",
    hlp_dp_calD: "Cliquez sur le bouton {0}Calendrier et choisissez une date. Vous pouvez aussi appuyer sur la touche T pour avoir la date d'aujourd'hui ou entrer une date manuellement sous le format : 3/6/90, 03/06/1990, 3 Juin 1990 etc.",
    hlp_dp_rptT: "Questions répétées dans la même boîte de dialogue",
    hlp_dp_rptD: "Répondez à toutes les questions dans la boîte de dialogue, puis cliquez sur le bouton {0}Ajouter une autre pour ajouter une autre répétition de la boîte de dialogue. Le nombre de répétitions à côté de l'icône dialogue augmente à chaque fois que vous entrez un nouveau lot de réponses. Pour aller à la boîte de dialogue suivante après avoir entré toutes les réponses dans la liste, cliquez sur Suivant dans la barre de navigation.",
    hlp_dp_sprT: "Réponses dans un tableau de données",
    hlp_dp_sprD: "Entrez chaque lot de données sur une ligne du tableau. Pour éditer une ligne de réponses, cliquez sur {0}. Pour insérer une nouvelle ligne entre deux lots de données, cliquez sur {1}. Pour supprimer un lot de réponses, cliquez sur {2}.",
    hlp_dp_nstT: "Questions dans une boîte de dialogue imbriquée",
    hlp_dp_nstD: "Cliquez sur l'icône dialogue. Quand vous avez terminé de répondre aux questions, vous pouvez soit cliquer sur le bouton {0}Suivant dans la barre de navigation, soit cliquer sur la boîte de dialogue principale dans la structure du questionnaire sur la gauche.",
    hlp_dp_nxdT: "Boîte de dialogue suivante ou précédente",
    hlp_dp_nxdD: "Cliquez soit sur le bouton {0}Suivant soit sur le bouton {1}Précédent. (Vous pouvez aussi appuyer sur les boutons Page Down/Page Up ou Alt+N/Alt+P.)",
    hlp_dp_nxuT: "Aller à la boîte de dialogue suivante ou précédente, qui contient une question sans réponse",
    hlp_dp_nxuD: "Cliquez soit sur le bouton {0}Dialogue sans réponse suivant ou sur le bouton {1}Dialogue sans réponse précédent. (Vous pouvez aussi appuyer sur les boutons Ctrl+Page Down/Ctrl+Page Up.)",
    hlp_dp_frsT: "Aller à la première ou dernière boîte de dialogue de l'interview",
    hlp_dp_frsD: "Cliquez soit sur le bouton {0}Première ou {1}Dernière. (Vous pouvez aussi appuyer sur les boutons Alt+R/Alt+L.)",
    hlp_dp_finT: "Terminer l'interview",
    hlp_dp_finD: "Cliquez sur le bouton {0}Terminer",
    // Resource Pane Help Section
    hlp_rp: "Aide contextuelle",
    hlp_rp_intro: "Il arrive parfois que l'auteur de l'interview propose des aides contextuelles (ou de l'information) pour vous aider à répondre à un question dans une boîte de dialogue. Par exemple, lire un certain article de loi vous aiderait à répondre à une question bien spécifique. Quand une aide contextuelle est disponible, elle apparaît dans le volet d'aide situé tout en bas, sous la boîte de dialogue.",
    hlp_rp_how: "Pour afficher ou masquer le volet d'aide, cliquez sur le bouton {0}Afficher/masquer le volet d'aide. Quand le volet d'aide est affiché, vous pouvez y voir l'aide contextuelle de la question en cours dans la boîte de dialogue. (Si une question n'a pas d'aide contextuelle disponible, le volet d'aide est vide.) D'autre part, vous pouvez cliquer sur le bouton {1}Voir l'aide à côté de chaque question qui dispose d'une aide contextuelle pour voir le contenu dans une fenêtre séparée.",
    hlp_rp_note: "Note : le volet d'aide n'est pas forcément disponible dans toutes les situations. Par exemple, l'auteur de l'interview peut choisir de masquer de façon permanente le volet d'aide d'une interview.",

    // various strings needed for formatting
    ui_and: "et", // and
    ui_or: "ou", // or
    ui_minus: "moins", // minus
    ui_percent: "pourcent", // percent
    ui_true: "vrai", // true
    ui_false: "faux", // false

    // answer summaries:
    ui_as: "Résumé des Réponses HotDocs", // HotDocs Answer Summary (answer summary title when printing)
    ui_astitle: "Modèle : ", // Template:
    ui_print: "Imprimer", // Print

    // toolbar button tooltips & status bar messages
    tb_as: 'Résumé des Réponses', // Answer Summary
    tb_ast: 'Afficher un résumé de toutes les réponses saisies dans cet interview.', // Display a summary of all answers entered in this interview.
    tb_sv: 'Enregistrer les réponses', // Save Answers
    tb_svt: 'Enregistrer les réponses actuelles.', // Save the current answers.
    tb_dp: 'Aperçu du Document', // Document Preview
    tb_dpt: 'Afficher un aperçu approximatif du document final.', // Display an approximate preview of the finished document.
    tb_ol0: 'Masquer la Structure du Questionnaire', // Hide Interview Outline
    tb_ol1: 'Afficher la Structure du Questionnaire', // Show Interview Outline
    tb_ol2: 'Afficher/Masquer la Structure du Questionnaire', // Show/Hide Interview Outline
    tb_ol3: 'Dérouler la Structure du Questionnaire', // Show Drop-down Interview Outline
    tb_olt: 'Activer ou Désactiver la Structure du Questionnaire.', // Toggle the Interview Outline on or off.
    tb_od: 'Afficher la Structure du Questionnaire', // Show Interview Outline
    tb_odt: 'Afficher la liste déroulante de la Structure du Questionnaire.', // Show the Interview Outline drop-down.
    tb_iu0: 'Désactiver la mise à jour instantanée', // Disable Instant Update
    tb_iu1: 'Activer la mise à jour instantanée', // Enable Instant Update
    tb_iut: 'Activer ou Désactiver la mise à jour instantanée du questionnaire.', // Toggle Instant Update of interview outline on or off.
    tb_pg0: 'Questionnaire Multi-page', // Multi-page Interview
    tb_pg1: 'Questionnaire Une-page', // Single-page Interview
    tb_pgt: 'Basculer entre le questionnaire Multi-page et Une-page.', // Toggle between Multi-page and Single-page interview.
    tb_rs0: 'Masquer le volet d\'aide', // Hide Resource Pane
    tb_rs1: 'Afficher le volet d\'aide', // Show Resource Pane
    tb_rst: 'Basculer entre l\'affichage des aides dans des fenêtres séparées ou le volet d\'aide.', // Toggle between showing resources in Pop-up windows or the Resource Pane.
    tb_hlp: 'Afficher la page d\'aide du Serveur HotDocs.', // Display the HotDocs Server help page.
    tb_mnu: "Menu",
    tb_mnu_tip: "Afficher la barre d'outils du Menu",

    // dialog navigation
    // (button captions beginning with navb_ can have keyboard shortcuts designated with an & sign,
    //  but these keyboard shortcuts only work in JavaScript interviews -- not Silverlight.)
    navb_First: "Pr&emier", // Fi&rst
    navb_Prev: "&Précédent", // &Previous
    navb_Next: "&Suivant", // &Next
    navb_Last: "&Dernier", // &Last
    navb_Finish: "Term&iner", // Finish
    navb_More: "Plus", // More
    nav_First: "Première boîte de dialogue", // First Dialog (command name for First button)
    nav_PrevU: "Boîte de Dialogue sans Réponse Précédente", // Previous Unanswered Dialog (command name for Previous Unanswered button)
    nav_Prev: "Boîte de dialogue précédente", // Previous Dialog (command name for Previous button)
    nav_Next: "Next Dialog", // Next Dialog (command name for Next button)
    nav_NextU: "Boîte de Dialogue sans Réponse Suivante", // Next Unanswered Dialog (command name for Next Unanswered button)
    nav_Last: "Dernière Boîte de Dialogue", // Last Dialog (command name for Last button)
    nav_Finish: "Terminer l'interview", // Finish Interview (tooltip for Finish button)
    nav_FinEM: "Terminer la modification de lignes / Retour à la liste", // Finish Editing Rows / Return to List (tooltip for Finish Edit Mode button)
    nav_FinPopup: "Retour au questionnaire parent", // Return to parent interview (Tooltip for the FinishPopup button)
    nav_More: "Plus d'options de navigation", // More Navigation Buttons
    nav_leave: "Cette action mettra fin à l'interview, et les réponses que vous avez saisies seront perdues. Cliquez sur les boutons Suivant ou Précédent en bas de page pour vous déplacer dans le questionnaire. Si vous avez terminé de répondre aux questions, cliquez sur Terminer pour terminer l'interview et soumettre vos réponses.", // This will terminate the interview, and any answers you have entered will be lost. Click the Next or Previous buttons at the bottom of the page to move through the interview. If you are finished answering questions, click Finish to complete the interview and submit your answers.
    nav_warnfin: "Il s'agit de la dernière boîte de dialogue du questionnaire.", // This is the last dialog of the interview.
    nav_warnfin_unans: "Vous avez {0} question(s) sans réponse", // You have {0} unanswered question(s)
    nav_warnfin_ok: "Cliquez sur OK lorsque vous avez terminé l'interview et que vous voulez soumettre vos réponses. Cliquez sur Annuler pour revenir à l'interview.", // Click OK when you are done with the interview and want to submit your answers. Click Cancel to return to the interview.

    // Various UI tooltips documenting keyboard accelerators
    uitt_First: "Première Boîte de Dialogue (Ctrl+Home)", // First Dialog (Ctrl+Home)
    uitt_PrevU: "Boîte de Dialogue sans Réponse Précédente (Ctrl+Page Up)", // Previous Unanswered Dialog (Ctrl+Page Up)
    uitt_Prev: "Boîte de Dialogue Précédente (Page Up)", // Previous Dialog (Page Up)
    uitt_Next: "Boîte de Dialogue Suivante (Page Down)", // Next Dialog (Page Down)
    uitt_NextU: "Boîte de Dialogue sans Réponse Suivante (Ctrl+Page Down)", // Next Unanswered Dialog (Ctrl+Page Down)
    uitt_Last: "Dernière boîte de dialogue (Ctrl+End)", // Last Dialog (Ctrl+End)
    uitt_ssbedit: "Editer la Ligne (Ctrl+Enter)", // Edit Row (Ctrl+Enter)
    uitt_ssbins: "Insérer une Ligne (Ctrl+Insert)", // Insert Row (Ctrl+Insert)
    uitt_ssbdel: "Effacer une Ligne (Ctrl+Delete)", // Delete Row (Ctrl+Delete)

    // HotDocs resource-related language
    rs_bcap: "Afficher l'aide contextuelle'", // View Resource
    rs_title: "Infos", // Resource
    rs_dis: "Voir chaque {0} pour les aides contextuelles disponibles", // See individual {0} for available resources
    rs_cols: "colonnes", // columns
    rs_opts: "options", // options
    rs_opt: "option", // option
    rs_fld: "champ réponse", // answer field
    rs_dlg: "boîte de Dialogue", // dialog
    rs_ind: "{0}{1}{2} pour {3}", // {0}{1}{2} for {3}: {0} & {2} are begin/end hyperlink markup, {1} is [rs_bcap], {3} is [rs_opt]/[rs_fld]/[rs_dlg].
    rs_dock: "Fixer le menu d'aide en bas du questionnaire", // Dock resource pane to bottom of interview

    // validation messages
    val_invdate: "Veuillez entrer une date valide.", // Please enter a valid date.
    val_invnum: "Veuillez entrer un nombre", // Please enter a number.
    val_numrng: "Veuillez entrer un nombre entre {0} et {1}.", // Please enter a number between {0} and {1}.
    val_numlt: "Veuillez entrer un nombre qui est inférieur ou égal à {0}.", // Please enter a number that is less than or equal to {0}.
    val_numgt: "Veuillez entrer un nombre qui est supérieur ou égal à {0}.", // Please enter a number that is greater than or equal to {0}.
    val_reqg: "Une ou plusieurs questions sont obligatoires et demandent une réponse avant que vous puissiez terminer l'interview.", // One or more questions are required and must be answered before you can complete the interview.
    val_reqp: "Une ou plusieurs questions sont obligatoires et demandent une réponse avant que vous puissiez continuer.", // One or more questions are required and must be answered before you can proceed.
    val_reqd: "Une ou plusieurs questions dans le dialogue {0} sont obligatoires et demandent une réponse avant que vous puissiez continuer.", // One or more questions in the {0} dialog are required and must be answered before you can proceed.
    val_dlg_errg: "Vous devez résoudre les erreurs restantes de la fenêtre avant de pouvoir terminer l'entrevue.", // You must resolve the outstanding dialog errors before you can complete the interview.
    val_dlg_errp: "L'erreur suivante doit être résolue avant de pouvoir continuer:\r\n\r\n{1}", // This dialog contains the following error, which must be resolved before you can proceed:
    val_dlg_errd: "La page {0} contient l'erreur suivante qui doit être résolue avant de pouvoir procéder:\r\n\r\n{1}", // The {0} dialog contains the following error, which must be resolved before you can proceed:
    val_rptlim: "Vous pouvez entrer seulement {0} ensembles de réponses pour ce dialogue.", // You can enter only {0} sets of answers for this dialog.
    val_repdel: "Etes-vous sûr de vouloir supprimer cette répétition ?", // Are you sure you want to delete this repetition?
    val_err: "Vous devez régler une ou plusieurs erreurs de saisie avant de pouvoir continuer.", // You must resolve one or more input errors before you can proceed.
    val_wait: "Merci de patienter pendant que vos réponses sont traitées.", // Please wait while your answers are being processed.

    // context menu items
    hdmnuClearAns: "Effacer la Réponse", // Erase Answer
    hdmnuCut: "Couper", // Cut
    hdmnuCopy: "Copier", // Copy
    hdmnuPaste: "Coller", // Paste
    hdmnuDel: "Effacer", // Delete
    hdmnuSelAll: "Sélectionner Tout", // Select All
    hdmnuEditRow: "Editer la Ligne", // Edit Row
    hdmnuInsRow: "Insérer une ligne", // Insert Row
    hdmnuDelRow: "Effacer la ligne", // Delete Row
    hdmnuMoveRowUp: "Déplacer la Ligne vers le Haut", // Move Row Up
    hdmnuMoveRowDn: "Déplacer la Ligne vers le Bas", // Move Row Down
    hdmnuClearDlg: "Effacer les Réponses", // Erase Answers
    hdmnuInsRep: "Insérez une Répétition", // Insert Repetition
    hdmnuDelRep: "Effacer une Répétition", // Delete Repetition
    hdmnuMoveUp: "Déplacer la Répétition vers le Haut", // Move Repetition Up
    hdmnuMoveDn: "Déplacer la Répétition vers le Bas", // Move Repetition Down
    hdmnuNewRep: "Nouvelle Répétition", // New Repetition
    hdmnuEraseAllAns: "Effacer toutes les Réponses", // Erase All Answers

    // regular expressions used for parsing date input (appropriate for localization)
    dateparse_today: "(a|aujourd'hui)", //when dates are entered, users can instead enter a "T" or "TODAY" as a shortcut to today's date
    dateparse_days: "(d|jour|jours)", //if the user enters a T, it can optionally be followed by +/- num days/months/years. If the desired unit is days, it can be designated with any of these strings
    dateparse_months: "(m|mois)", //if the user enters a T, it can optionally be followed by +/- num days/months/years. If the desired unit is months, it can be designated with any of these strings
    dateparse_years: "(a|année|annee|années|annees)", //if the user enters a T, it can optionally be followed by +/- num days/months/years. If the desired unit is years, it can be designated with any of these strings
    // simple "today"-based date arithmetic is possible (and localized) during date input, because simple
    // date expressions are parsed using a regular expression built out of the above pieces:
    // "^{dateparse_today}\s*([+-])\s*(\d+)\s*({dateparse_days}|{dateparse_months}|{dateparse_years})$"

    // HotDocs Embedded UI Strings
    hde_assembling: "Assemblage...", // Assembling...
    hde_complete: "Assemblage terminé", // Assembly Session Complete
    hde_download: "Vous pouvez télécharger {0} en utilisant {1} suivant", // You may download your {0} using the following {1}: // {0} is one of hde_dl_doc; {1} is one of hde_dl_lnk
    hde_warn: "Merci de télécharger tous les documents dont vous avez besoin avant de quitter la page.", // Please download all of the documents you need before leaving.
    hde_expired: "Les liens de téléchargements ont expiré", // The download links have expired.
    hde_error: "Erreur lors du contact avec le serveur {0}: {1}", // Error in contacting the server. {0}: {1} // {0} will be an error code; {1} will be an error message
    hde_expire: "Les liens vont expirer dans {0}, ou quand vous quitterez cette page. Merci de télécharger tous les documents dont vous avez besoin avant de quitter la page.", // "Links will expire in about {0}, or when you leave this page. Please download all of the documents you need before leaving.", // {0} will be a number followed by a space and one of hd_time_minute|hd_time_hour|hd_time_day.
    hde_dl_doc: "votre document|vos documents", // singular and plural forms of {0} in hde_download
    hde_dl_lnk: "le lien|les liens", // singular and plural forms of {1} in hde_download
    hde_no_docs: "Cette interview n'a produit aucun document.", // This interview produced no documents.
    hd_time_day: "jour|jours",
    hd_time_hour: "heure|heures",
    hd_time_minute: "minute|minutes",

    // user-facing error messages (appropriate for localization)
    err_invint: "Invalide Interview: Le dialogue actuel ne peut pas être affichée
 Vous pouvez toujours cliquer sur le bouton Terminer ci-dessous si vous souhaitez
 présenter les résultats de cette interview!.", // Invalid Interview: The current dialog cannot be displayed!

You may still click the Finish button below if you want to
submit the results of this interview.
    err_vers: 'Cette interview HotDocs (HDVers={0}) est incompatible avec le HotDocs Server interview runtime ({1}).', // This HotDocs interview (HDVers={0}) is incompatible with the current HotDocs Server interview runtime ({1}).
    err_slv: "Cette interview HotDocs Server nécessite Microsoft Silverlight version 3.0 ou ultérieure.", // This HotDocs Server interview requires Microsoft Silverlight version 3.0 or later.
    err_type: "Invalid Interview Type: {0}",
    err_load: 'Erreur: {0} a échoué à charger correctement.', // Error: {0} failed to load properly.
    err_noint: 'Interview incorrecte: il n\'y a rien à afficher!', // Invalid Interview: There is nothing to display!
    err_print: "L'impression a échoué en raison des restrictions de sécurité de votre navigateur.", // Printing failed due to your browser's security restrictions.
    err_mustret: "Vous devez revenir à l'interview avant d'effectuer cette action.", // You must return to the interview before performing this action.
    err_rowclck: "Merci de cliquer dans une cellule du tableau pour choisir une ligne.", // Please click in a table cell to choose a current row.
    err_nest: "Interview invalide: les instructions REPEAT sont imbriquées sur plus de 4 niveaux de profondeur.", // Invalid Interview: REPEAT instructions are nested more than 4 levels deep.
    err_cantadd: "Vous devez répondre à au moins une question dans cette boîte de dialogue avant de pouvoir ajouter une autre boîte de dialogue.", // You must answer at least one question in this dialog before you can add another dialog.
    err_brows: "Erreur du Navigateur Web", // browser error
    err_browsm: "Vous tentez d'utiliser une interview HotDocs Server sur une plate-forme ou un navigateur non pris en charge, l'entretien peut ne pas s'afficher correctement. Continuer malgré tout?", // You are attempting to use a HotDocs Server interview on an unsupported browser or platform; the interview may not appear correctly. Continue anyway?
    err_browssl: "HotDocs Server Silverlight interviews ne sont pris en charge que dans Internet Explorer (Windows), Chrome (Windows), Firefox (Windows or Mac), and Safari (Mac uniquement).", // HotDocs Server Silverlight interviews are only supported in Internet Explorer (Windows), Chrome (Windows), Firefox (Windows or Mac), and Safari (Mac only).
    err_browsjs: "HotDocs Server JavaScript interviews nécessite Microsoft Internet Explorer 6.0 ou une version ultérieure.", // HotDocs Server JavaScript interviews require Microsoft Internet Explorer 6.0 or later.
    err_dtype: "Veuillez vous assurer que la page héberge cette interview utilise un DOCTYPE strict: comme <!DOCTYPE html>.",
    err_compat: "Votre navigateur semble fonctionner dans le mode IE Affichage de compatibilité. Merci de désactiver l'affichage de compatibilité pour ce site et essayez à nouveau.",
    err_handler: "Une erreur s'est produite lors de l'enregistrement des handlers pour le(s) '{0}' événement(s).",
    err_baseclass: "An error occurred while extending base classes.",
    err_siteadm: "Merci de prévenir l'administrateur du site.",
    err_invprm: "Paramètre Non Valide",
    err_invprm_tb: "Impossible d'ajouter un bouton de barre d'outils: un paramètre est invalide pour AddCustomToolbarButton.",
    err_invprm_nb: "Impossible d'ajouter un bouton de barre de navigation: un paramètre est invalide pour AddCustomNavButton.",
    err_invprm_img: "Failed to set toolbar button image: invalid parameters to SetToolbarButtonImage.",
    err_unk: "Erreur Inconnu", // unknown error
    err_noastest: "Answer sources based on answer files are not available during test in browser.",
    err_mixedtypes: "Tentative de lecture des options de la question à choix multiples pour la variable nommée '{0}', mais son type était '{1}' au lieu de 'MC'. Vérifiez que le type de cette variable est la même dans tous les modèles liés.", // Attempted to read Multiple Choice options for the variable named '{0}', but its type was '{1}' instead of 'MC'. Verify that this variable's type is the same in all related templates.

    err_proc: "Failed to process the {0}() for the template '{1}'.",
    err_nocmp: "The component '{0}' does not exist.",
    err_idxgt0: "Index must be greater than or equal to 0.",
    err_emptyrptstk: "Cannot modify empty repeat stack",
    err_decidx: "Error: Unable to decrement a repeat index that is already at its lowest.",
    err_badrptstk: "Bad repeat stack: correct iteration of repeated dialog '{0}' not found.",
    err_badscrstk: "Bad script stack: dialog '{0}' not found.",
    err_limit: "Unable to set LIMIT; no dialog '{0}' found.",
    err_clear: "Unable to CLEAR options; multiple choice variable '{0}' not found.",
    err_grptf: "Cannot perform grouped true false operations on this type of node",
    err_grptf_un: "Cannot perform grouped true false operations on a dialog with ungrouped true false variables",
    err_invldloc: "Attempt to retrieve the Dialog Name from an invalid Interview Location object.",
    err_insrtlev: "There are too many INSERT levels in the template.",
    err_retrvbn: "Current Build Node cannot be retrieved unless an interview rebuild is in progress.",
    err_dateof: "Using the DATE OF function will create an invalid date. The first parameter must be in the range 1-31, the second 1-12, the third 1-9999, and the resulting date must be an actual calendar day.",
    err_setvar: "Tried to set an answer for something that was not a variable!",
    err_setdat: "Tried to set a date answer for something that was not a date variable!",
    err_settf: "Tried to set a true false answer for something that was not a true false variable or a dialog!",
    err_setmc: "Tried to set a multiple choice answer for something that was not a multiple choice variable!",
    err_retrvopt: "You can only retrieve options from multiple choice variables.",
    err_navstate: "Cannot update navigation state without a current dialog.",
    err_zeroiter: "Encountered a repeat node with zero iterations.",
    err_idxexceeds: "Index exceeds answered count.",
    err_nopath: "A navigation bar custom button image name must include a path.",
    err_serviceop: "Failed to define a data source for the following reason: ",
    err_datarequest: "Failed to download the data for a data source for the following reason: ",

    errnoact: "Interview could not be initialized: FormAction not specified.",
    errpath: "Interview could not be initialized: no {0} path was specified.",
    errdiv: "Error: Unable to render HotDocs interview because the interview container (hdMainDiv) does not exist on this page. Please contact your network administrator.",
    errinit: "Error: Interview attempted to start before initialization was complete. Please report situation to HotDocs development.",
    errslimg: "Silverlight supports only PNG and JPG images.  Has an invalid or missing image file been used?",
    errpoprslt: "Error: Attempted to pop an empty result stack.",
    errsetrslt: "Error: Attempt to set the top of an empty result stack.",
    errgetrslt: "Error: Attempt to get the top of an empty result stack.",
    errpopuans: "Error: Attempted to pop an empty unanswered stack.",
    errsetuans: "Error: Attempt to set the top of an empty unanswered stack.",
    errgetuans: "Error: Attempt to get the top of an empty unanswered stack.",
    errpop: "{0}: Pop of empty stack!",
    errget: "{0}: Get on empty stack!",
    badmojo: "Bad Mojo {0}: {1}!",
    errpoprpt: "Error: Unable to pop an empty repeat stack.",
    erraccrpt: "Error: Unable to access the top of an empty repeat stack.",
    errinfunc: "Error in {0}: {1}",

    vnf: "Var not found!",
    badcomp: "Inappropriate comparison.",
    txtcomp: "Inappropriate text comparison.",
    datecomp: "Inappropriate date comparison.",
    tmccomp: "Error: Invalid text-to-MC comparison.",
    mccomp: "Invalid MC to MC comparison.",
    dateop: "Error: Inappropriate operation on a date variable.",
    badtest: "Error: Testing an invalid variable or one that does not exist.",
    badcount: "Error: Invalid item passed to HDCount.",
    baddateof: 'Error: Invalid date used in "DATE OF" calculation.'

  },

  /*
  IsOrdinalSuffix: function(val, str)
  {
    // reports whether str begins with a valid ordinal suffix for val, and if so, returns the length of the suffix.
    // returns zero if str does not contain a valid ordinal suffix for val.
    return (str.charAt(0) == '.') ? 1 : 0;
  },

  GetOrdinalSuffix: function(val)
  {
    return ".";
  },
  */
  _zero: "null",
  _teens: ["zehn", "elf", "zwölf", "dreizehn", "vierzehn", "fünfzehn", "sechzehn", "siebzehn", "achtzehn", "neunzehn"],
  _ones: ["ein", "zwei", "drei", "vier", "fünf", "sechs", "sieben", "acht", "neun"],
  _tens: ["zwanzig", "dreißig", "vierzig", "fünfzig", "sechzig", "siebzig", "achtzig", "neunzig"],
  _hundred: "hundert",
  _one_Powers_Of_Ten: ["tausend", "e Million", "e Milliarde"],
  _mult_Powers_Of_Ten: ["tausend", " Millionen", " Milliarden"],
  _ord_Powers_Of_Ten: ["tausendste", " Millionste", " Milliardste"],
  _ord_Zero: "nullte",
  _ord_Ones: ["erste", "zweite", "dritte", "vierte", "fünfte", "sechste", "siebte", "achte", "neunte"],
  _ord_Teens: ["zehnte", "elfte", "zwölfte", "dreizehnte", "vierzehnte", "fünfzehnte", "sechzehnte", "siebzehnte", "achtzehnte", "neunzehnte"],
  _ord_Tens: ["zwanzigste", "dreißigste", "vierzigste", "fünfzigste", "sechzigste", "siebzigste", "achtzigste", "neunzigste"],
  _and: "und",
  _comma_Str: "komma",
  _eins_Str: "eins",
  /*
  SpellNum: function(amount, strZero, bOrdinal)
  {
    // NOTE: strZero is expected to be one of the "zeroFormats" array specified in this language module
    amount = parseInt(amount); // only handles integer input
    if (isNaN(amount))
    {
      return "";
    }

    var numStr = "",
      spaceStr = " ",
      space = "",
      useOrd, power, tempStr, strPiece, index, div1000, numPiece, tenPiece, powerPiece, ordWOPower, gtrOne;

    if (amount == 1 && !bOrdinal)
      return this._eins_Str;
    if (amount == 0)
      numStr = bOrdinal ? this._ord_Zero : this._zero;
    else if (amount > 100000000000)
      numStr = "grösser als 100 Milliarden";
    else
    {
      useOrd = bOrdinal;
      power = 0;
      while (amount != 0)
      {
        // strPiece is assigned one millenium with no leading or trailing blanks
        div1000 = parseInt(amount / 1000);
        numPiece = amount - (div1000 * 1000);
        amount = parseInt(amount / 1000);
        if (numPiece > 0)
        {
          strPiece = "";
          // as each piece is added, it must append a neccessary space or dash
          ordWOPower = useOrd && !power;
          gtrOne = numPiece > 1;
          if (numPiece > 99)
          {
            strPiece = (parseInt(numPiece / 100) > 1 || amount > 1) ? this._ones[parseInt(numPiece / 100) - 1] : "";
            //strPiece += " ";
            strPiece += this._hundred;
            numPiece %= 100;
            if (!power && numPiece)
              strPiece += spaceStr;
            else if (ordWOPower)
              strPiece += "ste";
          }
          if (numPiece > 19 || numPiece < 10)
          {
            tenPiece = parseInt(numPiece / 10);
            numPiece %= 10;
            if (numPiece)
            {
              index = numPiece - 1;
              strPiece += (ordWOPower && !tenPiece) ? this._ord_Ones[index] : this._ones[index];
            }
            if (tenPiece)
            {
              if (numPiece)
                strPiece += this._and;
              index = tenPiece - 2;
              strPiece += ordWOPower ? this._ord_Tens[index] : this._tens[index];
            }
          }
          else if (numPiece > 9)
          {
            index = numPiece - 10;
            strPiece += ordWOPower ? this._ord_Teens[index] : this._teens[index];
          }
          if (power)
          {
            if (useOrd)
              powerPiece = this._ord_Powers_Of_Ten[power - 1];
            else if (gtrOne)
              powerPiece = this._mult_Powers_Of_Ten[power - 1];
            else
              powerPiece = this._one_Powers_Of_Ten[power - 1];
            strPiece += powerPiece;
          }
          tempStr = numStr;
          numStr = strPiece;
          numStr += space;
          if (space === "" && power > 1)
            numStr += " ";
          numStr += tempStr;
          space = spaceStr;
          useOrd = false;
        }
        power++;
      }
    }

    // Trim trailing space, if any
    while (numStr[numStr.length - 1] == " ")
      numStr = numStr.substr(0, numStr.length - 1);

    return numStr;
  }
  */
};