text:
<!DOCTYPE html>

	<meta http-equiv="content-type" content="text/html; charset=utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta name="generator" content="Hugo 0.89.4" />

	<title>Pages · A Developer's Experience</title>

	<meta name="description" content="" />

<meta itemprop="name" content="Pages">
<meta itemprop="description" content="The romantic image of an über-programmer is someone who fires up Emacs, types like a machine gun, and delivers a flawless final product from scratch. A more accurate image would be someone who stares quietly into space for a few minutes and then says Hmm. I think I've seen something like this before – John D. Cook">

<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Pages"/>
<meta name="twitter:description" content="The romantic image of an über-programmer is someone who fires up Emacs, types like a machine gun, and delivers a flawless final product from scratch. A more accurate image would be someone who stares quietly into space for a few minutes and then says Hmm. I think I've seen something like this before – John D. Cook"/>

<meta property="og:title" content="Pages" />
<meta property="og:description" content="The romantic image of an über-programmer is someone who fires up Emacs, types like a machine gun, and delivers a flawless final product from scratch. A more accurate image would be someone who stares quietly into space for a few minutes and then says Hmm. I think I've seen something like this before – John D. Cook" />
<meta property="og:type" content="website" />
<meta property="og:url" content="/pages/" />

	<link type="text/css" rel="stylesheet" href="/css/print.css" media="print">

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

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

	<link type="text/css" rel="stylesheet" href="/css/blockquote.css"><link type="text/css" rel="stylesheet" href="/css/custom.css">

	<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700&display=swap">

	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css"
		integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous" />

	<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/apple-touch-icon-144-precomposed.png">

	<link rel="shortcut icon" href="/images/favicon.png">

	<link href="/pages/index.xml" rel="alternate" type="application/rss+xml" title="A Developer's Experience" />

A Developer's Experience

The romantic image of an über-programmer is someone who fires up Emacs, types like a machine gun, and delivers a flawless final product from scratch. A more accurate image would be someone who stares quietly into space for a few minutes and then says Hmm. I think I've seen something like this before – John D. Cook

          Posts

          Pages

          About

          Qs

	<button class="blog-search-btn"></button>
	<input type="text" class="blog-search-input" placeholder="Type to Search...">

	<form style='display: none;' action='/search/' method="get">
		<input name="q" type="text">
	</form>

Pages

        scala-cli Cheatsheet

        <time class="pull-right post-list" datetime="2021-10-21T00:00:00Z">Oct 21, 2021</time>

        Lo and Behold

        <time class="pull-right post-list" datetime="2017-03-16T00:00:00Z">Mar 16, 2017</time>

        Application Models

        <time class="pull-right post-list" datetime="2016-08-27T15:50:00Z">Aug 27, 2016</time>

        Written in Stone

        <time class="pull-right post-list" datetime="2015-12-30T06:58:42Z">Dec 30, 2015</time>

        Useful Unix Commands

        <time class="pull-right post-list" datetime="2015-02-07T08:02:58Z">Feb 7, 2015</time>

        The Court Room Climax

        <time class="pull-right post-list" datetime="2015-01-25T00:19:31Z">Jan 25, 2015</time>

        Just-In-Time (JIT) Compilation

        <time class="pull-right post-list" datetime="2014-10-01T04:27:30Z">Oct 1, 2014</time>

        Code Treats

        <time class="pull-right post-list" datetime="2014-10-01T03:55:02Z">Oct 1, 2014</time>

        Tree List View

        <time class="pull-right post-list" datetime="2014-10-01T03:45:22Z">Oct 1, 2014</time>

        C++0x Like Algorithms

        <time class="pull-right post-list" datetime="2014-10-01T03:32:28Z">Oct 1, 2014</time>

        Scrollable Image Viewer

        <time class="pull-right post-list" datetime="2010-10-09T00:00:00Z">Oct 9, 2010</time>

        Typesafe Logger

        <time class="pull-right post-list" datetime="2010-10-08T18:34:09Z">Oct 8, 2010</time>

        Pattern Conflict

        <time class="pull-right post-list" datetime="2010-10-08T17:56:18Z">Oct 8, 2010</time>

    ©  2021

    · CC BY-SA 4.0

	<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nanum+Gothic+Coding:wght@400;700&display=swap" />
	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.2.0/styles/default.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" />
	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/styles/base16/ocean.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" />


text:
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems                */
/*                                                                            */
/* 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.                                             */
/* -------------------------------------------------------------------------- */

define(function(require){
  var Locale = require('utils/locale');
  var Config = require('sunstone-config');
  var OpenNebula = require('opennebula');
  var OpenNebulaImage = require('opennebula/image');
  var UserInputs = require('utils/user-inputs');
  var WizardFields = require('utils/wizard-fields');
  var DisksResizeTemplate = require('hbs!./disks-resize/html');

  return {
    'insert': _insert,
    'retrieve': _retrieve
  };

  function _calculateCost(context, disk_cost, callback){
    var cost = 0;

    $(".diskContainer", context).each(function(){
      var size = 0;

      var fields = WizardFields.retrieve(this);

      if (fields.SIZE != undefined){
        size = fields.SIZE;
      } else{
        disk = $(this).data("template_disk");

        if (disk != undefined && disk['SIZE'] != undefined){
          size = disk['SIZE'];
        }
      }

      cost += size * disk_cost;
      cost += $(this).data('disk_snapshot_total_cost');
    });

    $(".cost_value", context).text(cost.toFixed(2));

    if(callback != undefined){
      callback();
    }
  }

  /**
   * @param {Object} opts - template_json: extended info template (with DISK/SIZE)
   *                      - disksContext: jquery selector, where to place the html
   *                      - force_persistent {bool}: mark all disks as if they
   *                          were persistent, disabling resize inputs
   *                      - cost_callback: function to call when the cost changes
   */
  function _insert(opts) {

    var disksContext = opts.disksContext;

    var template_disk = opts.template_json.VMTEMPLATE.TEMPLATE.DISK
    var disks = []
    if ($.isArray(template_disk)) {
      disks = template_disk
    } else if (!$.isEmptyObject(template_disk)) {
      disks = [template_disk]
    }

    if (disks.length > 0) {
      disksContext.html(DisksResizeTemplate());

      var disk_cost = opts.template_json.VMTEMPLATE.TEMPLATE.DISK_COST;

      if (disk_cost == undefined) {
        disk_cost = Config.onedConf.DEFAULT_COST.DISK_COST;
      }

      disksContext.off("input", "input");

      if (disk_cost != 0 && Config.isFeatureEnabled("showback")) {
        $(".provision_create_template_disk_cost_div", disksContext).show();

        disksContext.on("input", "input", function(){
          _calculateCost(disksContext, disk_cost, opts.cost_callback);
        });

        _calculateCost(disksContext, disk_cost, opts.cost_callback);
      } else {
        $(".provision_create_template_disk_cost_div", disksContext).hide();
      }

      var diskContext;
      $(".disksContainer", disksContext).html("");
      $.each(disks, function(disk_id, disk) {
        diskContext = $(
          '
'+
            '
'+
              ''+
            '
'+
            '
' +
            '
' +
          '
').appendTo($(".disksContainer", disksContext));

        diskContext.data('template_disk', disk);

        var disk_snapshot_total_size = 0;
        if (disk.DISK_SNAPSHOT_TOTAL_SIZE != undefined) {
          disk_snapshot_total_size = parseInt(disk.DISK_SNAPSHOT_TOTAL_SIZE);
        }

        diskContext.data('disk_snapshot_total_size', disk_snapshot_total_size);
        diskContext.data('disk_snapshot_total_cost', disk_snapshot_total_size * disk_cost);

        var volatile = (disk.IMAGE == undefined && disk.IMAGE_ID == undefined);

        var label;

        if (volatile){
          label = Locale.tr("Volatile Disk");
        } else {
          label = disk.IMAGE ? disk.IMAGE : Locale.tr("Image was not found");
        }

        $("label", diskContext).text(Locale.tr("DISK") + ' ' + disk_id + ': ' + label);

        var persistent =
          ( opts.force_persistent ||
            (disk.PERSISTENT && disk.PERSISTENT.toUpperCase() == "YES") );

        var disabled =
          ( persistent ||
            (disk.TYPE && OpenNebulaImage.TYPES[disk.TYPE] == OpenNebulaImage.TYPES.CDROM) );

        if (persistent){
          $("label", diskContext).append('')

        }else{
          $("label", diskContext).append('')

        }

        if (disk.IMAGE_STATE){
          var color_class = OpenNebulaImage.stateColor(disk.IMAGE_STATE) + "-color";

          $("label", diskContext).append('')
        } else if (disk.IMAGE || disk.IMAGE_ID) {
          var color_class = "error-color";

          $("label", diskContext).append('')
        } // else is volatile, does not have state

        var attr;

        if (disabled){
          if (disk.SIZE){
            attr = UserInputs.parse("SIZE","O|fixed|"+label+"||"+disk.SIZE);
          } else {
            attr = UserInputs.parse("SIZE","O|fixed|"+label+"||-");
          }
        } else {
          if (disk.SIZE != undefined){
            // Range from original size to size + 500GB
            var min = parseInt(disk.SIZE);
            var max = min + 512000;

            attr = UserInputs.parse(
              "SIZE",
              "O|range|"+label+"|"+min+".."+max+"|"+min);
          } else {
            attr = UserInputs.parse(
              "SIZE",
              "M|number|"+label+"||");
          }
        }

        UserInputs.insertAttributeInputMB(attr, $(".diskSlider", diskContext));
      })

    } else {
      disksContext.html("");
    }
  }

  function _retrieve(context) {
    var disks = [];
    var disk;
    $(".diskContainer", context).each(function(){
      if ($(this).data("template_disk")) {
        disk = $(this).data("template_disk");

        var fields = WizardFields.retrieve(this);

        if (fields.SIZE != undefined){
          disk['SIZE'] = fields.SIZE;
        }
      }

      if (disk) {
        disks.push(disk);
      }
    });

    return disks;
  }
});

redpajama_set_name: RedPajamaGithub


text:
require 'open3'

def run_boxes_ctl(command, *args)
  cmd = %w{ruby -r bundler/setup ./bin/boxesctl} + [command, '--mq_url', amqp_url] + args
  run_in_dir('admin', *cmd)
end

When(/ingest "([^"]*)" cut in (\d+)x(\d+)/) do |file, rows, cols|
  run_boxes_ctl('ingest', image_path(file), rows, cols)
  sleep 2 # let time for scalpel to finish
end


text:
foundation_sass_tiles
=====================

foundation_sass_tiles


text:
#if !defined(DOUBLETAKE_SOURCEINTERNALHEAP_H)
#define DOUBLETAKE_SOURCEINTERNALHEAP_H

/*
 * @file   source_internalheap.h
 * @author Emery Berger <http://www.cs.umass.edu/~emery>
 * @author Tongping Liu <http://www.cs.umass.edu/~tonyliu>
 */

#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "log.hh"
#include "mm.hh"
#include "real.hh"
#include "xdefines.hh"

class SourceInternalHeap {
public:
  SourceInternalHeap() {}

  void* initialize(void* startaddr, size_t initSize, size_t metasize) {
    void* ptr;
    char* base;
    size_t size = initSize;

    // Call mmap to allocate a shared map.
    // ptr = MM::mmapAllocatePrivate(size+metasize, (void *)xdefines::INTERNAL_HEAP_BASE);
    ptr = MM::mmapAllocatePrivate(size + metasize, (void*)startaddr);
    base = (char*)ptr;

    Real::pthread_mutex_init(&_mutex, NULL);

    // Initialize the following content according the values of xpersist class.
    base = (char*)((intptr_t)ptr + metasize);
    _start = base;
    _end = base + size;
    _position = (char*)_start;
    _remaining = size;
    _magic = 0xCAFEBABE;
    return ptr;
  }

  inline void* malloc(size_t sz) {
    //    PRINF("inside source internal heap, sz %lx magic %lx at %p\n", sz, _magic, &_magic);
    sanityCheck();

    // We need to page-align size, since we don't want two different
    // threads using the same page.

    // Round up the size to page aligned.
    sz = xdefines::PageSize * ((sz + xdefines::PageSize - 1) / xdefines::PageSize);

    lock();

    if(_remaining < sz) {
      fprintf(stderr, "Out of memory error: available = %zx, requested = %zx, thread = %d.\n",
              _remaining, sz, (int)pthread_self());
			unlock();
      exit(-1);
    }

    void* p = _position;

    // Increment the bump pointer and drop the amount of memory.
    _remaining -= sz;
    _position += sz;

    unlock();

    // fprintf (stderr, "%d : shareheapmalloc %p with size %x, remaining %x\n", getpid(), p, sz,
    // *_remaining);
    return p;
  }

  inline void* getHeapStart() {
    PRINF("*****XHEAP:_start %p*****\n", (void *)_start);
    return (void*)_start;
  }

  inline void* getHeapEnd() { return (void*)_end; }

  inline void* getHeapPosition() { return (void*)_position; }

  // These should never be used.
  inline void free(void*) { sanityCheck(); abort(); }
  inline size_t getSize(void*) {
    sanityCheck();
    abort();
    return 0;
  } // FIXME

private:
  void lock() { Real::pthread_mutex_lock(&_mutex); }

  void unlock() { Real::pthread_mutex_unlock(&_mutex); }

  void sanityCheck() {
    if(_magic != 0xCAFEBABE) {
      fprintf(stderr, "%d : WTF!\n", getpid());
      ::abort();
    }
  }

  /// The start of the heap area.
  volatile char* _start;

  /// The end of the heap area.
  volatile char* _end;

  /// Pointer to the current bump pointer.
  char* _position;

  /// Pointer to the amount of memory remaining.
  size_t _remaining;

  size_t _magic;

  // We will use a lock to protect the allocation request from different threads.
  pthread_mutex_t _mutex;
};

#endif


text:
import { Observable } from 'rxjs/Rx';
import { Client } from './models';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class ClientsService {

  // Observable string streams
  public clientSelected$: Observable<Client>;
  public clientsFiltered$: Observable<string>;
  public clientsNotFound$: Observable<boolean>;

  // Observable string sources
  private clientSelectedSource: Subject<Client>;
  private clientsFilteredSource: Subject<string>;
  private clientsNotFoundSource: Subject<boolean>;

constructor() {
  this.clientSelectedSource = new Subject<Client>();
  this.clientsFilteredSource = new Subject<string>();
  this.clientsNotFoundSource = new Subject<boolean>();
  this.clientSelected$ = this.clientSelectedSource.asObservable();
  this.clientsFiltered$ = this.clientsFilteredSource.asObservable();
  this.clientsNotFound$ = this.clientsNotFoundSource.asObservable();
}

  // Service message commands
  public selectClient(client: Client) {
    this.clientSelectedSource.next(client);
  }
  public filterClients(term: string) {
    this.clientsFilteredSource.next(term);
  }
  public clientsNotFound(notFound: boolean) {
    this.clientsNotFoundSource.next(notFound);
  }
}


text:
package de.bitbrain.braingdx.graphics.animation;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;
import de.bitbrain.braingdx.graphics.renderer.GameObject2DRenderer;
import de.bitbrain.braingdx.util.Enabler;
import de.bitbrain.braingdx.util.Factory;
import de.bitbrain.braingdx.world.GameObject;

/**
 * Renders an animation for a {@link GameObject} onto the screen for the position where
 * the game object is currently positioned in world coordinates.
 *

 * This implementation does not directly require an {@link Animation} object. Instead,
 * on initialisation it expects a {@link AnimationConfig} object which can be constructed via
 * the {@link AnimationConfig.AnimationConfigBuilder} implementation.
 * Animations are dynamically created based on the information provided by the configuration.
 *
 * @author Miguel Gonzalez Sanchez
 * @since 0.4.0
 */
public class AnimationRenderer extends GameObject2DRenderer {

   private static final Enabler<GameObject> DEFAULT_ENABLER = new Enabler<GameObject>() {
      @Override
      public boolean isEnabledFor(GameObject target) {
         return true;
      }
   };

   private static final AnimationTypeResolver<GameObject> DEFAULT_ANIMATION_TYPE_RESOLVER = new AnimationTypeResolver<GameObject>() {
      @Override
      public Object getAnimationType(GameObject object) {
         return object.getType();
      }
   };

   private class AnimationState {
      public float stateTime;
   }

   private final Factory<AnimationState> animationStateFactory = new Factory<AnimationState>() {

      @Override
      public AnimationState create() {
         return new AnimationState();
      }
   };

   private final AnimationConfig config;
   private final AnimationCache animationCache;
   private final Sprite sprite;
   private final AnimationTypeResolver<GameObject> animationTypeResolver;
   private final Enabler<GameObject> animationEnabler;
   private final Vector2 offset = new Vector2();
   private final Vector2 customSize = new Vector2();
   private boolean enabled = true;

   public AnimationRenderer(AnimationSpriteSheet spriteSheet, AnimationConfig config, Enabler<GameObject> animationEnabler) {
      this(spriteSheet, config, DEFAULT_ANIMATION_TYPE_RESOLVER, animationEnabler);
   }

   public AnimationRenderer(AnimationSpriteSheet spriteSheet, AnimationConfig config) {
      this(spriteSheet, config, DEFAULT_ANIMATION_TYPE_RESOLVER, DEFAULT_ENABLER);
   }

   public AnimationRenderer(AnimationSpriteSheet spriteSheet, AnimationConfig config, AnimationTypeResolver<GameObject> animationTypeResolver) {
      this(spriteSheet, config, animationTypeResolver, DEFAULT_ENABLER);
   }

   public AnimationRenderer(AnimationSpriteSheet spriteSheet, AnimationConfig config, AnimationTypeResolver<GameObject> animationTypeResolver, Enabler<GameObject> animationEnabler) {
      this.config = config;
      this.animationCache = new AnimationCache(spriteSheet, config);
      this.sprite = new Sprite();
      this.animationTypeResolver = animationTypeResolver;
      this.animationEnabler = animationEnabler;
   }

   @Override
   public void render(GameObject object, Batch batch, float delta) {
      TextureRegion region = retrieveRegionFor(object, delta);
      if (enabled) {
         batch.setColor(object.getColor());
         drawRegion(
               batch,
               region,
               object
         );
         batch.setColor(Color.WHITE);
      }
   }

   public AnimationRenderer offset(float x, float y) {
      this.offset.set(x, y);
      return this;
   }

   public AnimationRenderer size(float width, float height) {
      this.customSize.set(width, height);
      return this;
   }

   public AnimationRenderer enabled(boolean enabled) {
      this.enabled = enabled;
      return this;
   }

   private TextureRegion retrieveRegionFor(GameObject object, float delta) {
      Object currentAnimationType = animationTypeResolver.getAnimationType(object);
      AnimationState state = object.getOrSetAttribute(AnimationState.class, animationStateFactory);
      Animation<TextureRegion> animation = animationCache.getAnimation(currentAnimationType);
      AnimationFrames frames = config.getFrames(currentAnimationType);
      if (state.stateTime == 0f) {
         if (frames.isRandomOffset()) {
            state.stateTime = (float) (Math.random() * (frames.getDuration() * frames.getFrames()));
         } else {
            state.stateTime = frames.getOffset();
         }
      }
      state.stateTime += delta;
      boolean animationEnabled = animationEnabler.isEnabledFor(object);
      if (!animationEnabled) {
         if (frames.isRandomOffset()) {
            state.stateTime = (float) (Math.random() * (frames.getDuration() * frames.getFrames()));
         } else {
            state.stateTime = frames.getOffset();
         }
      }
      return animation.getKeyFrame(animationEnabled ? state.stateTime : frames.getDuration() * frames.getResetIndex());
   }

   private void drawRegion(Batch batch, TextureRegion region, GameObject object) {
      sprite.setRegion(region);
      sprite.setOrigin(object.getOriginX(), object.getOriginY());
      sprite.setColor(object.getColor());
      sprite.setBounds(
            object.getLeft() + object.getOffsetX() + offset.x,
            object.getTop() + object.getOffsetY() + offset.y,
            customSize.x != 0 ? customSize.x : object.getWidth(),
            customSize.y != 0 ? customSize.y : object.getHeight()
      );
      sprite.setScale(object.getScaleX(), object.getScaleY());
      sprite.draw(batch);
   }
}


text:
package org.jboss.pnc.common.json.moduleconfig;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.jboss.pnc.common.json.AbstractModuleConfig;

@ToString
public class IndyRepoDriverModuleConfig extends AbstractModuleConfig {

    public static final String MODULE_NAME = "indy-repo-driver";

    /**
     * Request timeout for the whole client in seconds
     */
    @Getter
    @Setter
    @JsonProperty(required = false)
    private Integer defaultRequestTimeout = 600;

    /**
     * Name of the target repo to which the build repo of a successful TEMPORARY build should be promoted.
     */
    @Getter
    @Setter
    @JsonProperty(required = false)
    private String tempBuildPromotionTarget = "temporary-builds";

}


text:
package org.apache.pulsar.proxy.server;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.flush.FlushConsolidationHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.ssl.SslProvider;
import java.util.concurrent.TimeUnit;
import org.apache.pulsar.common.protocol.Commands;
import org.apache.pulsar.common.protocol.OptionalProxyProtocolDecoder;
import org.apache.pulsar.common.util.NettyServerSslContextBuilder;
import org.apache.pulsar.common.util.SslContextAutoRefreshBuilder;
import org.apache.pulsar.common.util.keystoretls.NettySSLContextAutoRefreshBuilder;

/**
 * Initialize service channel handlers.
 *
 */
public class ServiceChannelInitializer extends ChannelInitializer<SocketChannel> {

    public static final String TLS_HANDLER = "tls";
    private final ProxyService proxyService;
    private final boolean enableTls;
    private final boolean tlsEnabledWithKeyStore;
    private final int brokerProxyReadTimeoutMs;
    private final int maxMessageSize;

    private SslContextAutoRefreshBuilder<SslContext> serverSslCtxRefresher;
    private NettySSLContextAutoRefreshBuilder serverSSLContextAutoRefreshBuilder;

    public ServiceChannelInitializer(ProxyService proxyService, ProxyConfiguration serviceConfig, boolean enableTls)
            throws Exception {
        super();
        this.proxyService = proxyService;
        this.enableTls = enableTls;
        this.tlsEnabledWithKeyStore = serviceConfig.isTlsEnabledWithKeyStore();
        this.brokerProxyReadTimeoutMs = serviceConfig.getBrokerProxyReadTimeoutMs();
        this.maxMessageSize = serviceConfig.getMaxMessageSize();

        if (enableTls) {
            if (tlsEnabledWithKeyStore) {
                serverSSLContextAutoRefreshBuilder = new NettySSLContextAutoRefreshBuilder(
                        serviceConfig.getTlsProvider(),
                        serviceConfig.getTlsKeyStoreType(),
                        serviceConfig.getTlsKeyStore(),
                        serviceConfig.getTlsKeyStorePassword(),
                        serviceConfig.isTlsAllowInsecureConnection(),
                        serviceConfig.getTlsTrustStoreType(),
                        serviceConfig.getTlsTrustStore(),
                        serviceConfig.getTlsTrustStorePassword(),
                        serviceConfig.isTlsRequireTrustedClientCertOnConnect(),
                        serviceConfig.getTlsCiphers(),
                        serviceConfig.getTlsProtocols(),
                        serviceConfig.getTlsCertRefreshCheckDurationSec());
            } else {
                SslProvider sslProvider = null;
                if (serviceConfig.getTlsProvider() != null) {
                    sslProvider = SslProvider.valueOf(serviceConfig.getTlsProvider());
                }
                serverSslCtxRefresher = new NettyServerSslContextBuilder(
                        sslProvider,
                        serviceConfig.isTlsAllowInsecureConnection(),
                        serviceConfig.getTlsTrustCertsFilePath(), serviceConfig.getTlsCertificateFilePath(),
                        serviceConfig.getTlsKeyFilePath(), serviceConfig.getTlsCiphers(),
                        serviceConfig.getTlsProtocols(),
                        serviceConfig.isTlsRequireTrustedClientCertOnConnect(),
                        serviceConfig.getTlsCertRefreshCheckDurationSec());
            }
        } else {
            this.serverSslCtxRefresher = null;
        }
    }

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ch.pipeline().addLast("consolidation", new FlushConsolidationHandler(1024,
                true));
        if (serverSslCtxRefresher != null && this.enableTls) {
            SslContext sslContext = serverSslCtxRefresher.get();
            if (sslContext != null) {
                ch.pipeline().addLast(TLS_HANDLER, sslContext.newHandler(ch.alloc()));
            }
        } else if (this.tlsEnabledWithKeyStore && serverSSLContextAutoRefreshBuilder != null) {
            ch.pipeline().addLast(TLS_HANDLER,
                    new SslHandler(serverSSLContextAutoRefreshBuilder.get().createSSLEngine()));
        }
        if (brokerProxyReadTimeoutMs > 0) {
            ch.pipeline().addLast("readTimeoutHandler",
                    new ProxyReadTimeoutHandler(brokerProxyReadTimeoutMs, TimeUnit.MILLISECONDS));
        }
        if (proxyService.getConfiguration().isHaProxyProtocolEnabled()) {
            ch.pipeline().addLast(OptionalProxyProtocolDecoder.NAME, new OptionalProxyProtocolDecoder());
        }
        ch.pipeline().addLast("frameDecoder", new LengthFieldBasedFrameDecoder(
                this.maxMessageSize + Commands.MESSAGE_SIZE_FRAME_PADDING, 0, 4, 0, 4));

        ch.pipeline().addLast("handler", new ProxyConnection(proxyService, proxyService.getDnsAddressResolverGroup()));
    }
}


text:
package org.vertx.spring;

import org.vertx.java.platform.Container;

/**
 * @author swilliams
 *
 */
public interface ContainerAware {

  void setContainer(Container container);

}


text:
#region Copyright(c) 2015 Cluster One
// Copyright(c) 2015 Cluster One

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#endregion

using System;
using System.Collections.Generic;
using System.Reflection;

namespace ClusterOne.Pipelines
{
    public interface IRequiredKeyProvider
    {
        IDictionary<string, PropertyInfo> GetKeys();
    }

    public class RequiredKeyProvider : IRequiredKeyProvider
    {
        public static IRequiredKeyProvider Create(object obj)
        {
            return new RequiredKeyProvider(obj);
        }

        public IDictionary<string, PropertyInfo> GetKeys()
        {
            IDictionary<string, PropertyInfo> keys = new Dictionary<string, PropertyInfo>();
            BindingFlags propertyFlags = BindingFlags.Instance  |
                                         BindingFlags.NonPublic |
                                         BindingFlags.Public    |
                                         BindingFlags.FlattenHierarchy;

            PropertyInfo[] propInfos = m_object.GetType().GetProperties(propertyFlags);

            foreach (PropertyInfo pi in propInfos)
            {
                RequiredAttribute attr = pi.GetCustomAttribute(typeof(RequiredAttribute)) as RequiredAttribute;

                if (attr != null)
                {
                    keys.Add(String.IsNullOrWhiteSpace(attr.Name) ? pi.Name : attr.Name, pi);
                }
            }

            return keys;
        }

        protected RequiredKeyProvider(object obj)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }

            m_object = obj;
        }

        private object m_object;
    }
}


text:
package ReverseLinkedList;

public class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }
}


text:
InputEditDialog::InputEditDialog(QWidget* parent) :
QDialog(parent)
{
	setWindowTitle(tr("Input edit dialog"));
	setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

	m_inputName = new QLineEdit;

	m_typeList = new QComboBox;
	for (std::size_t i = 0; i < PrimitiveTypeCount; ++i)
		m_typeList->addItem(EnumToString(static_cast<PrimitiveType>(i)));

	m_roleList = new QComboBox;
	for (std::size_t i = 0; i < InputRoleCount; ++i)
		m_roleList->addItem(EnumToString(static_cast<InputRole>(i)));

	m_locationIndex = new QSpinBox;

	m_roleIndex = new QSpinBox;

	QFormLayout* formLayout = new QFormLayout;
	formLayout->addRow(tr("Name"), m_inputName);
	formLayout->addRow(tr("Type"), m_typeList);
	formLayout->addRow(tr("Role"), m_roleList);
	formLayout->addRow(tr("Role index"), m_roleIndex);
	formLayout->addRow(tr("Input index"), m_locationIndex);

	QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
	connect(buttonBox, &QDialogButtonBox::accepted, this, &InputEditDialog::OnAccept);
	connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);

	QVBoxLayout* verticalLayout = new QVBoxLayout;
	verticalLayout->addLayout(formLayout);
	verticalLayout->addWidget(buttonBox);

	setLayout(verticalLayout);
}

InputEditDialog::InputEditDialog(const InputInfo& input, QWidget* parent) :
InputEditDialog(parent)
{
	m_inputName->setText(QString::fromStdString(input.name));
	m_locationIndex->setValue(int(input.locationIndex));
	m_roleIndex->setValue(int(input.roleIndex));
	m_roleList->setCurrentText(EnumToString(input.role));
	m_typeList->setCurrentText(EnumToString(input.type));
}

InputInfo InputEditDialog::GetInputInfo() const
{
	InputInfo inputInfo;
	inputInfo.locationIndex = static_cast<std::size_t>(m_locationIndex->value());
	inputInfo.name = m_inputName->text().toStdString();
	inputInfo.role = static_cast<InputRole>(m_roleList->currentIndex());
	inputInfo.roleIndex = static_cast<std::size_t>(m_roleIndex->value());
	inputInfo.type = static_cast<PrimitiveType>(m_typeList->currentIndex());

	return inputInfo;
}

void InputEditDialog::OnAccept()
{
	if (m_inputName->text().isEmpty())
	{
		QMessageBox::critical(this, tr("Empty name"), tr("Input name must be set"), QMessageBox::Ok);
		return;
	}

	if (m_typeList->currentIndex() < 0)
	{
		QMessageBox::critical(this, tr("Invalid type"), tr("You must select a type"), QMessageBox::Ok);
		return;
	}

	accept();
}


text:
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_INTERNAL_NON_CONSTRUCTIBLE_H
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_INTERNAL_NON_CONSTRUCTIBLE_H

#include "google/cloud/version.h"

namespace google {
namespace cloud {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace internal {

/**
 * A type that is not constructible.
 *
 * This type can be used to disallow the instantiation of an object. We might
 * use it, for example, to disambiguate overloaded functions that are passed an
 * empty initializer list.
 */
struct NonConstructible {
  NonConstructible() = delete;
  NonConstructible(NonConstructible const&) = delete;
  NonConstructible(NonConstructible&&) = delete;
};

}  // namespace internal
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
}  // namespace cloud
}  // namespace google

#endif  // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_INTERNAL_NON_CONSTRUCTIBLE_H


text:
/**
 * SVG support for jsPlumb.
 *
 * things to investigate:
 *
 * gradients:  https://developer.mozilla.org/en/svg_in_html_introduction
 * css:http://tutorials.jenkov.com/svg/svg-and-css.html
 * text on a path: http://www.w3.org/TR/SVG/text.html#TextOnAPath
 * pointer events: https://developer.mozilla.org/en/css/pointer-events
 *
 */
;(function() {

	var svgAttributeMap = {
		"stroke-linejoin":"stroke-linejoin",
		"joinstyle":"stroke-linejoin",
		"stroke-dashoffset":"stroke-dashoffset"
	};

	var ns = {
		svg:"http://www.w3.org/2000/svg",
		xhtml:"http://www.w3.org/1999/xhtml"
	},
	_attr = function(node, attributes) {
		for (var i in attributes)
			node.setAttribute(i, "" + attributes[i]);
	},
	_node = function(name, attributes) {
		var n = document.createElementNS(ns.svg, name);
		attributes = attributes || {};
		attributes["version"] = "1.1";
		attributes["xmnls"] = ns.xhtml;
		_attr(n, attributes);
		return n;
	},
	_pos = function(d) { return "position:absolute;left:" + d[0] + "px;top:" + d[1] + "px"; },
	_convertStyle = function(s, ignoreAlpha) {
		var o = s,
		pad = function(n) { return n.length == 1 ? "0" + n : n; },
		hex = function(k) { return pad(Number(k).toString(16)); },
		pattern = /(rgb[a]?\()(.*)(\))/;
		if (s.match(pattern)) {
			var parts = s.match(pattern)[2].split(",");
			o = "#" + hex(parts[0]) + hex(parts[1]) + hex(parts[2]);
			if (!ignoreAlpha && parts.length == 4)
				o = o + hex(parts[3]);
		}

		return o;
	},
	_clearGradient = function(parent) {
		for (var i = 0; i < parent.childNodes.length; i++) {
			if (parent.childNodes[i].tagName == "linearGradient" || parent.childNodes[i].tagName == "radialGradient")
				parent.removeChild(parent.childNodes[i]);
		}
	},
	_updateGradient = function(parent, node, style, dimensions) {
		var id = "jsplumb_gradient_" + (new Date()).getTime();
		// first clear out any existing gradient
		_clearGradient(parent);
		// this checks for an 'offset' property in the gradient, and in the absence of it, assumes
		// we want a linear gradient. if it's there, we create a radial gradient.
		// it is possible that a more explicit means of defining the gradient type would be
		// better. relying on 'offset' means that we can never have a radial gradient that uses
		// some default offset, for instance.
		if (!style.gradient.offset) {
			var g = _node("linearGradient", {id:id});
			parent.appendChild(g);
		}
		else {
			var g = _node("radialGradient", {
				id:id
			});
			parent.appendChild(g);
		}

		// the svg radial gradient seems to treat stops in the reverse
		// order to how canvas does it.  so we want to keep all the maths the same, but
		// iterate the actual style declarations in reverse order, if the x indexes are not in order.
		for (var i = 0; i < style.gradient.stops.length; i++) {
			// Straight Connectors and Bezier connectors act slightly differently; this code is a bit of a kludge.  but next version of
			// jsplumb will be replacing both Straight and Bezier to be generic instances of 'Connector', which has a list of segments.
			// so, not too concerned about leaving this in for now.
			var styleToUse = i;
			if (dimensions.length == 8)
				styleToUse = dimensions[4] < dimensions[6] ? i: style.gradient.stops.length - 1 - i;
			else
				styleToUse = dimensions[4] < dimensions[6] ? style.gradient.stops.length - 1 - i : i;
			var stopColor = _convertStyle(style.gradient.stops[styleToUse][1], true);
			var s = _node("stop", {"offset":Math.floor(style.gradient.stops[i][0] * 100) + "%", "stop-color":stopColor});
			g.appendChild(s);
		}
		var applyGradientTo = style.strokeStyle ? "stroke" : "fill";
		node.setAttribute("style", applyGradientTo + ":url(#" + id + ")");
	},
	_applyStyles = function(parent, node, style, dimensions) {

		if (style.gradient) {
		_updateGradient(parent, node, style, dimensions);
		}
		else {
			// make sure we clear any existing gradient
			_clearGradient(parent);
			node.setAttribute("style", "");
		}

		node.setAttribute("fill", style.fillStyle ? _convertStyle(style.fillStyle, true) : "none");
		node.setAttribute("stroke", style.strokeStyle ? _convertStyle(style.strokeStyle, true) : "none");
		if (style.lineWidth) {
			node.setAttribute("stroke-width", style.lineWidth);
		}

		// in SVG there is a stroke-dasharray attribute we can set, and its syntax looks like
		// the syntax in VML but is actually kind of nasty: values are given in the pixel
		// coordinate space, whereas in VML they are multiples of the width of the stroked
		// line, which makes a lot more sense.  for that reason, jsPlumb is supporting both
		// the native svg 'stroke-dasharray' attribute, and also the 'dashstyle' concept from
		// VML, which will be the preferred method.  the code below this converts a dashstyle
		// attribute given in terms of stroke width into a pixel representation, by using the
		// stroke's lineWidth.
		if(style["stroke-dasharray"]) {
			node.setAttribute("stroke-dasharray", style["stroke-dasharray"]);
		}
		if (style["dashstyle"] && style["lineWidth"]) {
			var sep = style["dashstyle"].indexOf(",") == -1 ? " " : ",",
			parts = style["dashstyle"].split(sep),
			styleToUse = "";
			parts.forEach(function(p) {
				styleToUse += (Math.floor(p * style.lineWidth) + sep);
			});
			node.setAttribute("stroke-dasharray", styleToUse);
		}

		// extra attributes such as join type, dash offset.
		for (var i in svgAttributeMap) {
			if (style[i]) {
				node.setAttribute(svgAttributeMap[i], style[i]);
			}
		}
	},
	_decodeFont = function(f) {
		var r = /([0-9].)(p[xt])\s(.*)/;
		var bits = f.match(r);
		return {size:bits[1] + bits[2], font:bits[3]};
	};

	/*
	 * Base class for SVG components.
	 */
	var SvgComponent = function(cssClass, originalArgs, pointerEventsSpec) {
		var self = this;
		pointerEventsSpec = pointerEventsSpec || "all";
		jsPlumb.jsPlumbUIComponent.apply(this, originalArgs);
		self.canvas = null, self.path = null, self.svg = null;

		this.setHover = function() { };

		self.canvas = document.createElement("div");
		self.canvas.style["position"] = "absolute";
		jsPlumb.sizeCanvas(self.canvas,0,0,1,1);

		var clazz = cssClass + " " + (originalArgs[0].cssClass || "");
		self.canvas.className = clazz;

		self.svg = _node("svg", {
			"style":"",
			"width":0,
			"height":0,
			"pointer-events":pointerEventsSpec/*,
			"class": clazz*/
		});

		jsPlumb.appendElement(self.canvas, originalArgs[0]["parent"]);
		self.canvas.appendChild(self.svg);

		// TODO this displayElement stuff is common between all components, across all
		// renderers.  would be best moved to jsPlumbUIComponent.
		var displayElements = [ self.canvas ];
		this.getDisplayElements = function() {
			return displayElements;
		};

		this.appendDisplayElement = function(el) {
			displayElements.push(el);
		};

		this.paint = function(d, style, anchor) {
			if (style != null) {
				jsPlumb.sizeCanvas(self.canvas, d[0], d[1], d[2], d[3]);
		    	_attr(self.svg, {
	    			"style":_pos([0,0,d[2], d[3]]),
	    			"width": d[2],
	    			"height": d[3]
	    		});
		    	self._paint.apply(this, arguments);
			}
	    };
	};

	/*
	 * Base class for SVG connectors.
	 */
	var SvgConnector = function(params) {
		var self = this;
		SvgComponent.apply(this, [ params["_jsPlumb"].connectorClass, arguments, "none" ]);
		this._paint = function(d, style) {
			var p = self.getPath(d), a = { "d":p }, outlineStyle = null;
			a["pointer-events"] = "all";

			// outline style.  actually means drawing an svg object underneath the main one.
			if (style.outlineColor) {
				var outlineWidth = style.outlineWidth || 1,
				outlineStrokeWidth = style.lineWidth + (2 * outlineWidth);
				outlineStyle = {
					strokeStyle:_convertStyle(style.outlineColor),
					lineWidth:outlineStrokeWidth
				};

				if (self.bgPath == null) {
					self.bgPath = _node("path", a);
			    	self.svg.appendChild(self.bgPath);
		    		self.attachListeners(self.bgPath, self);
				}
				else {
					_attr(self.bgPath, a);
				}

				_applyStyles(self.svg, self.bgPath, outlineStyle, d);
			}

	    	if (self.path == null) {
		    	self.path = _node("path", a);
		    	self.svg.appendChild(self.path);
	    		self.attachListeners(self.path, self);
	    	}
	    	else {
	    		_attr(self.path, a);
	    	}

	    	_applyStyles(self.svg, self.path, style, d);
		};
	};

	/*
	 * SVG Bezier Connector
	 */
	jsPlumb.Connectors.svg.Bezier = function(params) {
		jsPlumb.Connectors.Bezier.apply(this, arguments);
		SvgConnector.apply(this, arguments);
		this.getPath = function(d) { return "M " + d[4] + " " + d[5] + " C " + d[8] + " " + d[9] + " " + d[10] + " " + d[11] + " " + d[6] + " " + d[7]; };
	};

	/*
	 * SVG straight line Connector
	 */
	jsPlumb.Connectors.svg.Straight = function(params) {
		jsPlumb.Connectors.Straight.apply(this, arguments);
		SvgConnector.apply(this, arguments);
	    this.getPath = function(d) { return "M " + d[4] + " " + d[5] + " L " + d[6] + " " + d[7]; };
	};

	jsPlumb.Connectors.svg.Flowchart = function() {
    	var self = this;
    	jsPlumb.Connectors.Flowchart.apply(this, arguments);
		SvgConnector.apply(this, arguments);
    	this.getPath = function(dimensions) {
    		var p = "M " + dimensions[4] + "," + dimensions[5];
	        // loop through extra points
	        for (var i = 0; i < dimensions[8]; i++) {
	        	p = p + " L " + dimensions[9 + (i*2)] + " " + dimensions[10 + (i*2)];
	        }
	        // finally draw a line to the end
	        p = p  + " " + dimensions[6] + "," +  dimensions[7];
	        return p;
    	};
    };

    /*
	 * Base class for SVG endpoints.
	 */
	var SvgEndpoint = function(params) {
		var self = this;
		SvgComponent.apply(this, [ params["_jsPlumb"].endpointClass, arguments, "all" ]);
		this._paint = function(d, style) {
			var s = jsPlumb.extend({}, style);
			if (s.outlineColor) {
				s.strokeWidth = s.outlineWidth;
				s.strokeStyle = _convertStyle(s.outlineColor, true);
			}

			if (self.node == null) {
				self.node = self.makeNode(d, s);
				self.svg.appendChild(self.node);
				self.attachListeners(self.node, self);
			}
			_applyStyles(self.svg, self.node, s, d);
			_pos(self.node, d);
		};
	};

	/*
	 * SVG Dot Endpoint
	 */
	jsPlumb.Endpoints.svg.Dot = function() {
		jsPlumb.Endpoints.Dot.apply(this, arguments);
		SvgEndpoint.apply(this, arguments);
		this.makeNode = function(d, style) {
			return _node("circle", {
					"cx"	:	d[2] / 2,
					"cy"	:	d[3] / 2,
					"r"		:	d[2] / 2
				});
		};
	};

	/*
	 * SVG Rectangle Endpoint
	 */
	jsPlumb.Endpoints.svg.Rectangle = function() {
		jsPlumb.Endpoints.Rectangle.apply(this, arguments);
		SvgEndpoint.apply(this, arguments);
		this.makeNode = function(d, style) {
			return _node("rect", {
				"width":d[2],
				"height":d[3]
			});
		};
	};

	/*
	 * SVG Image Endpoint is the default image endpoint.
	 */
	jsPlumb.Endpoints.svg.Image = jsPlumb.Endpoints.Image;
	/*
	 * Blank endpoint in svg renderer is the default Blank endpoint.
	 */
	jsPlumb.Endpoints.svg.Blank = jsPlumb.Endpoints.Blank;
	/*
	 * Label endpoint in svg renderer is the default Label endpoint.
	 */
	jsPlumb.Overlays.svg.Label = jsPlumb.Overlays.Label;

	var AbstractSvgArrowOverlay = function(superclass, originalArgs) {
    	superclass.apply(this, originalArgs);
    	jsPlumb.jsPlumbUIComponent.apply(this, originalArgs);
    	var self = this, path =null;
    	this.paint = function(connector, d, lineWidth, strokeStyle, fillStyle) {
    		if (path == null) {
    			path = _node("path");
    			connector.svg.appendChild(path);
    			self.attachListeners(path, connector);
    			self.attachListeners(path, self);
    		}

    		_attr(path, {
    			"d"		:	makePath(d),
    			stroke 	: 	strokeStyle ? strokeStyle : null,
    			fill 	: 	fillStyle ? fillStyle : null
    		});
    	};
    	var makePath = function(d) {
    		return "M" + d.hxy.x + "," + d.hxy.y +
    				" L" + d.tail[0].x + "," + d.tail[0].y +
    				" L" + d.cxy.x + "," + d.cxy.y +
    				" L" + d.tail[1].x + "," + d.tail[1].y +
    				" L" + d.hxy.x + "," + d.hxy.y;
    	};
    };

    jsPlumb.Overlays.svg.Arrow = function() {
    	AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
    };

    jsPlumb.Overlays.svg.PlainArrow = function() {
    	AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
    };

    jsPlumb.Overlays.svg.Diamond = function() {
    	AbstractSvgArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
    };
})();


text:
dbGaP to bioCADDIE metadata conversion utilities

## Introduction
This package contains a general utility that allows you to:

1. Download study metadata from the dbGaP ftp site by study id.
2. Convert the study metadata from XML into JSON
3. Transform the dbGaP JSON into a structure that is compatible with the bioCADDIE [study schema](https://github.com/biocaddie/WG3-MetadataSpecifications/blob/master/json-schemas/study_schema.json), [dataset schema](https://github.com/biocaddie/WG3-MetadataSpecifications/blob/master/json-schemas/dataset_schema.json) and [dimension schema](https://github.com/biocaddie/WG3-MetadataSpecifications/blob/master/json-schemas/dimension_schema.json)
4. Transform the bioCADDIE compatible JSON into RDF for use in mapping functions.
5. Transform RDF into bioCADDIE compatible JSON

## Installation
1. [Make sure you have a running image of python 3](python3)
2. Enter the appropriate virtual environment

```bash
> . myenv/bin/activate
(myenv) >
```
3a. Install ```dbgap``` from github

```bash
(myenv) > git clone https://github.com/crDDI/dbgap
(myenv) > cd dbgap
(myenv) > python setup.py install
```

3b. Install ```dbgap``` from PyPi

```bash
(myenv) > pip install dbgap
```

4 . Run ```download_study```

```bash
(myenv) > download_study
usage: download_study [-h] [-i [INFILE [INFILE ...]]] [-id INDIR]
                      [-o [OUTFILE [OUTFILE ...]]] [-od OUTDIR] [-f] [-s]
                      [-v VERSION] [-p PVALUE] [--ftproot FTPROOT] [-r RDFDIR]
                      [--logfile LOGFILE]
                      [--loglevel {DEBUG,INFO,WARNING,ERROR}] [--port PORT]
                      [-c CONTEXT]
                      studyid [{d,j,r,a} [{d,j,r,a} ...]]
download_study: error: the following arguments are required: studyid
```

## Use

## Transformation description
### Downloading XML files
The utility allows any version of any study to be downloaded in XML from the dbGaP XML server

The default download directory is ```data/<studyid>/xml```.

As an example,

```bash
(myenv) > download_study 979 d
```
Creates a ```data/phs000979/xml``` directory with the following files:

```
(myenv) > ls xml
StudyDescription.xml
phs000979.v1.pht005193.v1.Mental_Disorders_Postmortem_Subject.data_dict.xml
phs000979.v1.pht005194.v1.Mental_Disorders_Postmortem_Sample.data_dict.xml
phs000979.v1.pht005195.v1.Mental_Disorders_Postmortem_Subject_Phenotypes.data_dict.xml
phs000979.v1.pht005196.v1.Mental_Disorders_Postmortem_Sample_Attributes.data_dict.xml
```
Where StudyDescription.xml was downloaded from ftp://ftp.ncbi.nlm.nih.gov/dbgap/studies/phs000979/phs000979.v1.p1/GapExchange_phs000979.v1.p1.xml

and the four data_dict files from ftp://ftp.ncbi.nlm.nih.gov/dbgap/studies/phs000979/phs000979.v1.p1/pheno_variable_summaries/

## Converting XML to JSON
This utility uses the Object Management Group (OMG) [XML to JSON](http://informatics.mayo.edu/cts2/services/xmlToJson/) conversion specification, as implemented in the [pyjxslt](https://github.com/CTS2/pyjxslt) utility, and loads the result as a first-class python object using the [jsonasobj]() utility.  The following transformations are performed on the input data:

### Study transformations
The transformations in the table below are implemented by the ```biocaddie_json``` method in https://github.com/crDDI/dbgap/blob/master/dbgap/dbgap_study_information.py, and generate bioCADDIE compatible output from a dbGaP Study record:

| key | value   | Notes  |
|---|---|---|
|  @type | "biocaddie:Study" | This is necessary to establish the type of the entire document  |
| @id  | "dbgap:"\<study>".v"\<version>  | This is necessary establish the subject of the entire document |
| identifierInfo  | identifier=  "dbgap:"\<study>".v"\<version> |  The bioCaddie schema calls for an identifier/scheme pair -- although, curiously, the identifier is specified to be a URI |
|  | identifierScheme = "dbGaP" |
| title |GapExchange.Studies.Study[0].Configuration.StudyNameEntrez | **ISSUE:** We need to determine what an entry with more than one study looks like |
| description | GapExchange.Studies.Study[0].Configuration.StudyNameReportPage | |
| studyType | GapExchange.Studies.Study[0].Configuration.StudyTypes.StudyType[0]  | **ISSUE:** The alignment between dbGaP study type(s) and bioCaddie StudyType is not obvious.  Mapping may be required or this may not be a valid field. |
| keywords | GapExchange.Studies.Study[0].Configuration.Diseases.Disease (prefixed with "MESH - ") **ISSUE:** There are no keywords in the latest bioCaddie schema. | Is there somewhere else this would work better? -- perhaps ```isAboutBiologicalProcess``` |
| resultsIn | (this is a list of the identifiers of all of the datasets) |

The transformations in the table below are implemented by the ```xform_dbgap_dataset``` method in https://github.com/crDDI/dbgap/blob/master/dbgap/xform_dbgap.py, and generate bioCADDIE compatible output from a dbGaP DataSet record:

| key | value   | Notes  |
|---|---|---|
| @type | ''biocaddie:Dataset" | |
| @id | "biocaddie:"data_table.study_id |
| identifierInfo | identifier="dbgap:"data_table.study_id | |
| | identifierScheme=dbgap | |
| date_info | date=data_table.date_created | |
| | dateType="dct:created" | Dublin core seemed to be a reasonable source for date_info |
| context | "fhir:Observation" | if dataset is "Subject Phenotypes" |
| | "fhir:Specimen" | if dataset is "Sample Attributes" |
| hasPartDimension | "dbgap:"v.id | for each data_table.variable |
| * | * | All other dbgap elements are copied as is.

The transformations in the table below are implemented by the ```xform_dbgap_dimension``` method in https://github.com/crDDI/dbgap/blob/master/dbgap/xform_dbgap.py, and generate bioCADDIE compatible output from a dbGaP dataset variable:

| key | value   | Notes  |
|---|---|---|
| @type | ''biocaddie:Dimension" | |
| @id | "biocaddie:"variable.id | |
| identifierInfo | identifier="dbgap:"variable.id | |
| | identifierScheme="dbgap" | |
| dimensionType | "xsd:string" | if variable.type == "string'.  **Note:** We need to decide whether this is the correct use of type and whether datatypes even belong in bioCaddie
| * | * | All other dbgap elements are copied as is.

   The JSON images of the XML are stored in the ```data/<studyid>/json``` directory.

### Study Transformation Example
```bash
(myenv) > download_study 979 j
(myenv) > ls data/phs000979/json
StudyDescription.biocaddie.json
StudyDescription.json
phs000979.v1.pht005193.v1.Mental_Disorders_Postmortem_Subject.data_dict.json
phs000979.v1.pht005194.v1.Mental_Disorders_Postmortem_Sample.data_dict.json
phs000979.v1.pht005195.v1.Mental_Disorders_Postmortem_Subject_Phenotypes.data_dict.json
phs000979.v1.pht005196.v1.Mental_Disorders_Postmortem_Sample_Attributes.data_dict.json
```
Where ```StudyDescription.json``` is the direct JSON image of ```../xml/StudyDescription.xml``` and ```StudyDescription.biocaddie.json``` has been mapped according to the rules above.
#### StudyDescription in XML
![Study in XML](images/phs000979.v1.p1.xml.png)

#### Mapped StudyDescription in JSON
```json
{
   "resultsIn": [
      "dbgap:pht005193.v1",
      "dbgap:pht005194.v1",
      "dbgap:pht005195.v1",
      "dbgap:pht005196.v1"
   ],
   "description": "Gene Expression in Postmortem DLPFC and Hippocampus from Schizophrenia and Mood Disorders",
   "studyType": "Case-Control",
   "identifierInfo": [
      {
         "identifierScheme": "dbGaP",
         "identifier": "dbgap:phs000979.v1"
      }
   ],
   "@type": "biocaddie:Study",
   "title": "Gene Expression in Postmortem DLPFC and Hippocampus from Schizophrenia and Mood Disorders",
   "@id": "dbgap:phs000979.v1",
   "keywords": "MESH - Schizophrenia, Schizophrenia,Bipolar Disorder,Major Depressive Disorder"
}
```
#### data_dict in XML
```xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="./datadict_v2.xsl"?>
<data_table id="pht005196.v1" study_id="phs000979.v1" participant_set="1" date_created="Wed Dec  9 12:55:00 2015">
    <description/>
    <variable id="phv00258279.v1">
        <name>SAMPLE_ID</name>
        <description>De-identified Sample ID</description>
        <type>string</type>
    </variable>
    <variable id="phv00258280.v1">
        <name>BODY_SITE</name>
        <description>Body site where sample was collected</description>
        <type>string</type>
    </variable>
    <variable id="phv00258281.v1">
        <name>ANALYTE_TYPE</name>
        <description>Analyte Type</description>
        <type>string</type>
    </variable>
    <variable id="phv00258282.v1">
        <name>IS_TUMOR</name>
        <description>Tumor status</description>
        <type>encoded values</type>
        <value code="N">Is not a tumor</value>
        <value code="Y">Is Tumor</value>
    </variable>
    <variable id="phv00258283.v1">
        <name>HISTOLOGICAL_TYPE</name>
        <description>Cell or tissue type or subtype of sample</description>
        <type>string</type>
    </variable>
    <variable id="phv00258284.v1">
        <name>RIN</name>
        <description>RNA integrity number</description>
        <type/>
    </variable>
    <variable id="phv00258285.v1">
        <name>BATCH</name>
        <description>Sample batch number</description>
        <type/>
    </variable>
</data_table>
```

#### Mapped data_dict in JSON

```json
{
   "data_table": {
      "study_id": "phs000979.v1",
      "participant_set": "1",
      "description": "",
      "date_created": "Wed Dec  9 12:55:02 2015",
      "id": "pht005193.v1",
      "identifierInfo": [
         {
            "identifierScheme": "dbgap",
            "identifier": "dbgap:phs000979.v1"
         }
      ],
      "variable": [
         {
            "name": "SUBJECT_ID",
            "identifierInfo": [
               {
                  "identifierScheme": "dbgap",
                  "identifier": "dbgap:phv00258253.v1"
               }
            ],
            "description": "Subject ID",
            "@type": "biocaddie:Dimension",
            "dimensionType": "xsd:string",
            "id": "phv00258253.v1",
            "@id": "dbgap:phv00258253.v1"
         },
         {
            "name": "CONSENT",
            "value": {
               "code": "1",
               "_content": "General Research Use (GRU)"
            },
            "identifierInfo": [
               {
                  "identifierScheme": "dbgap",
                  "identifier": "dbgap:phv00258254.v1"
               }
            ],
            "description": "Consent group as determined by DAC",
            "@type": "biocaddie:Dimension",
            "type": "encoded value",
            "id": "phv00258254.v1",
            "@id": "dbgap:phv00258254.v1"
         }
      ],
      "date_info": [
         {
            "dateType": "dct:created",
            "date": "Wed Dec  9 12:55:02 2015"
         }
      ],
      "hasPartDimension": [
         "dbgap:phv00258253.v1",
         "dbgap:phv00258254.v1"
      ],
      "@type": "biocaddie:Dataset",
      "@id": "dbgap:phs000979.v1"
   }
}
```

## Converting JSON to RDF
The JSON to RDF conversion uses the PyLD JSON-LD library to convert the JSON generated in the previous step into RDF.  It uses the output [schema_to_context](https://github.com/crDDI/schema_to_context) converter, which has been applied to the JSON Schema's in the [bioCaddie Working Group 3 Repository](https://github.com/biocaddie/WG3-MetadataSpecifications).  It adds one additional context:

```json
{
     "@context": {
         "dbgap": "http://www.ncbi.nlm.nih.gov/gap/mms#",
         "@vocab": "http://www.ncbi.nlm.nih.gov/gap/mms#"
      }
}
```
which assigns a prefix and URI for tags that are specifically identified as being part of dbGaP as well as assigning the default tag.

### Sample conversion
```bash
(myenv) > download_study 979 r -c http://localhost:8080/json-ld
```
#### Resulting Study in RDF Turtle
```turtle
@prefix biocaddie: <http://biocaddie.org/mms#> .
@prefix dbgap: <http://www.ncbi.nlm.nih.gov/gap/mms#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix fhir: <http://hl7.org/fhir/mms#> .
@prefix mms: <http://rdf.cdisc.org/mms#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

dbgap:phs000979.v1 a biocaddie:Study ;
    biocaddie:description "Gene Expression in Postmortem DLPFC and Hippocampus from Schizophrenia and Mood Disorders" ;
    biocaddie:identifierInfo ( [ biocaddie:identifier dbgap:phs000979.v1 ;
                                             biocaddie:identifierScheme "dbGaP" ] ) ;
    biocaddie:resultsIn ( "dbgap:pht005193.v1" "dbgap:pht005194.v1" "dbgap:pht005195.v1" "dbgap:pht005196.v1" ) ;
    biocaddie:title "Gene Expression in Postmortem DLPFC and Hippocampus from Schizophrenia and Mood Disorders" ;
    dbgap:keywords "MESH - Schizophrenia, Schizophrenia,Bipolar Disorder,Major Depressive Disorder" .
```
#### Resulting Dataset in RDF Turtle
```turtle
@prefix biocaddie: <http://biocaddie.org/mms#> .
@prefix dbgap: <http://www.ncbi.nlm.nih.gov/gap/mms#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix fhir: <http://hl7.org/fhir/mms#> .
@prefix mms: <http://rdf.cdisc.org/mms#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

dbgap:phs000979.v1 a biocaddie:Dataset ;
    biocaddie:date_info ( [ biocaddie:date "Wed Dec  9 12:55:00 2015"^^<xsd:dateTime> ;
                biocaddie:dateType <dct:created> ] ) ;
    biocaddie:description "" ;
    biocaddie:hasPartDimension ( "dbgap:phv00258279.v1" "dbgap:phv00258280.v1" "dbgap:phv00258281.v1" "dbgap:phv00258282.v1" "dbgap:phv00258283.v1" "dbgap:phv00258284.v1" "dbgap:phv00258285.v1" ) ;
    biocaddie:identifierInfo ( [ biocaddie:identifier dbgap:phs000979.v1 ;
                biocaddie:identifierScheme "dbgap" ] ) ;
    dbgap:context "fhir:Specimen" ;
    dbgap:date_created "Wed Dec  9 12:55:00 2015" ;
    dbgap:id "pht005196.v1" ;
    dbgap:participant_set "1" ;
    dbgap:study_id "phs000979.v1" ;
    dbgap:variable dbgap:phv00258279.v1,
        dbgap:phv00258280.v1,
        dbgap:phv00258281.v1,
        dbgap:phv00258282.v1,
        dbgap:phv00258283.v1,
        dbgap:phv00258284.v1,
        dbgap:phv00258285.v1 .
```

#### Sample Dimension Entry in RDF Turtle
```turtle
@prefix biocaddie: <http://biocaddie.org/mms#> .
@prefix dbgap: <http://www.ncbi.nlm.nih.gov/gap/mms#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix fhir: <http://hl7.org/fhir/mms#> .
@prefix mms: <http://rdf.cdisc.org/mms#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

dbgap:phv00258282.v1 a biocaddie:Dimension ;
    biocaddie:description "Tumor status" ;
    biocaddie:identifierInfo ( [ biocaddie:identifier dbgap:phv00258282.v1 ;
                biocaddie:identifierScheme "dbgap" ] ) ;
    biocaddie:name "IS_TUMOR" ;
    dbgap:id "phv00258282.v1" ;
    dbgap:type "encoded values" ;
    dbgap:value [ dbgap:_content "Is Tumor" ;
            dbgap:code "Y" ],
        [ dbgap:_content "Is not a tumor" ;
            dbgap:code "N" ] .
```


text:
<?php

/**
 * A query module to show basic page information.
 *
 * @ingroup API
 */
class ApiQueryInfo extends ApiQueryBase {

	private $fld_protection = false, $fld_talkid = false,
		$fld_subjectid = false, $fld_url = false,
		$fld_readable = false, $fld_watched = false, $fld_watchers = false,
		$fld_notificationtimestamp = false,
		$fld_preload = false, $fld_displaytitle = false;

	private $params, $titles, $missing, $everything, $pageCounter;

	private $pageRestrictions, $pageIsRedir, $pageIsNew, $pageTouched,
		$pageLatest, $pageLength;

	private $protections, $watched, $watchers, $notificationtimestamps,
		$talkids, $subjectids, $displaytitles;
	private $showZeroWatchers = false;

	private $tokenFunctions;

	public function __construct( $query, $moduleName ) {
		parent::__construct( $query, $moduleName, 'in' );
	}

	/**
	 * @param $pageSet ApiPageSet
	 * @return void
	 */
	public function requestExtraData( $pageSet ) {
		global $wgDisableCounters, $wgContentHandlerUseDB;

		$pageSet->requestField( 'page_restrictions' );
		// when resolving redirects, no page will have this field
		if ( !$pageSet->isResolvingRedirects() ) {
			$pageSet->requestField( 'page_is_redirect' );
		}
		$pageSet->requestField( 'page_is_new' );
		if ( !$wgDisableCounters ) {
			$pageSet->requestField( 'page_counter' );
		}
		$pageSet->requestField( 'page_touched' );
		$pageSet->requestField( 'page_latest' );
		$pageSet->requestField( 'page_len' );
		if ( $wgContentHandlerUseDB ) {
			$pageSet->requestField( 'page_content_model' );
		}
	}

	/**
	 * Get an array mapping token names to their handler functions.
	 * The prototype for a token function is func($pageid, $title)
	 * it should return a token or false (permission denied)
	 * @return array array(tokenname => function)
	 */
	protected function getTokenFunctions() {
		// Don't call the hooks twice
		if ( isset( $this->tokenFunctions ) ) {
			return $this->tokenFunctions;
		}

		// If we're in JSON callback mode, no tokens can be obtained
		if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
			return array();
		}

		$this->tokenFunctions = array(
			'edit' => array( 'ApiQueryInfo', 'getEditToken' ),
			'delete' => array( 'ApiQueryInfo', 'getDeleteToken' ),
			'protect' => array( 'ApiQueryInfo', 'getProtectToken' ),
			'move' => array( 'ApiQueryInfo', 'getMoveToken' ),
			'block' => array( 'ApiQueryInfo', 'getBlockToken' ),
			'unblock' => array( 'ApiQueryInfo', 'getUnblockToken' ),
			'email' => array( 'ApiQueryInfo', 'getEmailToken' ),
			'import' => array( 'ApiQueryInfo', 'getImportToken' ),
			'watch' => array( 'ApiQueryInfo', 'getWatchToken' ),
		);
		wfRunHooks( 'APIQueryInfoTokens', array( &$this->tokenFunctions ) );

		return $this->tokenFunctions;
	}

	static protected $cachedTokens = array();

	public static function resetTokenCache() {
		ApiQueryInfo::$cachedTokens = array();
	}

	public static function getEditToken( $pageid, $title ) {
		// We could check for $title->userCan('edit') here,
		// but that's too expensive for this purpose
		// and would break caching
		global $wgUser;
		if ( !$wgUser->isAllowed( 'edit' ) ) {
			return false;
		}

		// The token is always the same, let's exploit that
		if ( !isset( ApiQueryInfo::$cachedTokens['edit'] ) ) {
			ApiQueryInfo::$cachedTokens['edit'] = $wgUser->getEditToken();
		}

		return ApiQueryInfo::$cachedTokens['edit'];
	}

	public static function getDeleteToken( $pageid, $title ) {
		global $wgUser;
		if ( !$wgUser->isAllowed( 'delete' ) ) {
			return false;
		}

		// The token is always the same, let's exploit that
		if ( !isset( ApiQueryInfo::$cachedTokens['delete'] ) ) {
			ApiQueryInfo::$cachedTokens['delete'] = $wgUser->getEditToken();
		}

		return ApiQueryInfo::$cachedTokens['delete'];
	}

	public static function getProtectToken( $pageid, $title ) {
		global $wgUser;
		if ( !$wgUser->isAllowed( 'protect' ) ) {
			return false;
		}

		// The token is always the same, let's exploit that
		if ( !isset( ApiQueryInfo::$cachedTokens['protect'] ) ) {
			ApiQueryInfo::$cachedTokens['protect'] = $wgUser->getEditToken();
		}

		return ApiQueryInfo::$cachedTokens['protect'];
	}

	public static function getMoveToken( $pageid, $title ) {
		global $wgUser;
		if ( !$wgUser->isAllowed( 'move' ) ) {
			return false;
		}

		// The token is always the same, let's exploit that
		if ( !isset( ApiQueryInfo::$cachedTokens['move'] ) ) {
			ApiQueryInfo::$cachedTokens['move'] = $wgUser->getEditToken();
		}

		return ApiQueryInfo::$cachedTokens['move'];
	}

	public static function getBlockToken( $pageid, $title ) {
		global $wgUser;
		if ( !$wgUser->isAllowed( 'block' ) ) {
			return false;
		}

		// The token is always the same, let's exploit that
		if ( !isset( ApiQueryInfo::$cachedTokens['block'] ) ) {
			ApiQueryInfo::$cachedTokens['block'] = $wgUser->getEditToken();
		}

		return ApiQueryInfo::$cachedTokens['block'];
	}

	public static function getUnblockToken( $pageid, $title ) {
		// Currently, this is exactly the same as the block token
		return self::getBlockToken( $pageid, $title );
	}

	public static function getEmailToken( $pageid, $title ) {
		global $wgUser;
		if ( !$wgUser->canSendEmail() || $wgUser->isBlockedFromEmailUser() ) {
			return false;
		}

		// The token is always the same, let's exploit that
		if ( !isset( ApiQueryInfo::$cachedTokens['email'] ) ) {
			ApiQueryInfo::$cachedTokens['email'] = $wgUser->getEditToken();
		}

		return ApiQueryInfo::$cachedTokens['email'];
	}

	public static function getImportToken( $pageid, $title ) {
		global $wgUser;
		if ( !$wgUser->isAllowedAny( 'import', 'importupload' ) ) {
			return false;
		}

		// The token is always the same, let's exploit that
		if ( !isset( ApiQueryInfo::$cachedTokens['import'] ) ) {
			ApiQueryInfo::$cachedTokens['import'] = $wgUser->getEditToken();
		}

		return ApiQueryInfo::$cachedTokens['import'];
	}

	public static function getWatchToken( $pageid, $title ) {
		global $wgUser;
		if ( !$wgUser->isLoggedIn() ) {
			return false;
		}

		// The token is always the same, let's exploit that
		if ( !isset( ApiQueryInfo::$cachedTokens['watch'] ) ) {
			ApiQueryInfo::$cachedTokens['watch'] = $wgUser->getEditToken( 'watch' );
		}

		return ApiQueryInfo::$cachedTokens['watch'];
	}

	public static function getOptionsToken( $pageid, $title ) {
		global $wgUser;
		if ( !$wgUser->isLoggedIn() ) {
			return false;
		}

		// The token is always the same, let's exploit that
		if ( !isset( ApiQueryInfo::$cachedTokens['options'] ) ) {
			ApiQueryInfo::$cachedTokens['options'] = $wgUser->getEditToken();
		}

		return ApiQueryInfo::$cachedTokens['options'];
	}

	public function execute() {
		$this->params = $this->extractRequestParams();
		if ( !is_null( $this->params['prop'] ) ) {
			$prop = array_flip( $this->params['prop'] );
			$this->fld_protection = isset( $prop['protection'] );
			$this->fld_watched = isset( $prop['watched'] );
			$this->fld_watchers = isset( $prop['watchers'] );
			$this->fld_notificationtimestamp = isset( $prop['notificationtimestamp'] );
			$this->fld_talkid = isset( $prop['talkid'] );
			$this->fld_subjectid = isset( $prop['subjectid'] );
			$this->fld_url = isset( $prop['url'] );
			$this->fld_readable = isset( $prop['readable'] );
			$this->fld_preload = isset( $prop['preload'] );
			$this->fld_displaytitle = isset( $prop['displaytitle'] );
		}

		$pageSet = $this->getPageSet();
		$this->titles = $pageSet->getGoodTitles();
		$this->missing = $pageSet->getMissingTitles();
		$this->everything = $this->titles + $this->missing;
		$result = $this->getResult();

		uasort( $this->everything, array( 'Title', 'compare' ) );
		if ( !is_null( $this->params['continue'] ) ) {
			// Throw away any titles we're gonna skip so they don't
			// clutter queries
			$cont = explode( '|', $this->params['continue'] );
			$this->dieContinueUsageIf( count( $cont ) != 2 );
			$conttitle = Title::makeTitleSafe( $cont[0], $cont[1] );
			foreach ( $this->everything as $pageid => $title ) {
				if ( Title::compare( $title, $conttitle ) >= 0 ) {
					break;
				}
				unset( $this->titles[$pageid] );
				unset( $this->missing[$pageid] );
				unset( $this->everything[$pageid] );
			}
		}

		$this->pageRestrictions = $pageSet->getCustomField( 'page_restrictions' );
		// when resolving redirects, no page will have this field
		$this->pageIsRedir = !$pageSet->isResolvingRedirects()
			? $pageSet->getCustomField( 'page_is_redirect' )
			: array();
		$this->pageIsNew = $pageSet->getCustomField( 'page_is_new' );

		global $wgDisableCounters;

		if ( !$wgDisableCounters ) {
			$this->pageCounter = $pageSet->getCustomField( 'page_counter' );
		}
		$this->pageTouched = $pageSet->getCustomField( 'page_touched' );
		$this->pageLatest = $pageSet->getCustomField( 'page_latest' );
		$this->pageLength = $pageSet->getCustomField( 'page_len' );

		// Get protection info if requested
		if ( $this->fld_protection ) {
			$this->getProtectionInfo();
		}

		if ( $this->fld_watched || $this->fld_notificationtimestamp ) {
			$this->getWatchedInfo();
		}

		if ( $this->fld_watchers ) {
			$this->getWatcherInfo();
		}

		// Run the talkid/subjectid query if requested
		if ( $this->fld_talkid || $this->fld_subjectid ) {
			$this->getTSIDs();
		}

		if ( $this->fld_displaytitle ) {
			$this->getDisplayTitle();
		}

		/** @var $title Title */
		foreach ( $this->everything as $pageid => $title ) {
			$pageInfo = $this->extractPageInfo( $pageid, $title );
			$fit = $result->addValue( array(
				'query',
				'pages'
			), $pageid, $pageInfo );
			if ( !$fit ) {
				$this->setContinueEnumParameter( 'continue',
					$title->getNamespace() . '|' .
					$title->getText() );
				break;
			}
		}
	}

	/**
	 * Get a result array with information about a title
	 * @param int $pageid Page ID (negative for missing titles)
	 * @param $title Title object
	 * @return array
	 */
	private function extractPageInfo( $pageid, $title ) {
		$pageInfo = array();
		// $title->exists() needs pageid, which is not set for all title objects
		$titleExists = $pageid > 0;
		$ns = $title->getNamespace();
		$dbkey = $title->getDBkey();

		$pageInfo['contentmodel'] = $title->getContentModel();
		$pageInfo['pagelanguage'] = $title->getPageLanguage()->getCode();

		if ( $titleExists ) {
			global $wgDisableCounters;

			$pageInfo['touched'] = wfTimestamp( TS_ISO_8601, $this->pageTouched[$pageid] );
			$pageInfo['lastrevid'] = intval( $this->pageLatest[$pageid] );
			$pageInfo['counter'] = $wgDisableCounters
				? ''
				: intval( $this->pageCounter[$pageid] );
			$pageInfo['length'] = intval( $this->pageLength[$pageid] );

			if ( isset( $this->pageIsRedir[$pageid] ) && $this->pageIsRedir[$pageid] ) {
				$pageInfo['redirect'] = '';
			}
			if ( $this->pageIsNew[$pageid] ) {
				$pageInfo['new'] = '';
			}
		}

		if ( !is_null( $this->params['token'] ) ) {
			$tokenFunctions = $this->getTokenFunctions();
			$pageInfo['starttimestamp'] = wfTimestamp( TS_ISO_8601, time() );
			foreach ( $this->params['token'] as $t ) {
				$val = call_user_func( $tokenFunctions[$t], $pageid, $title );
				if ( $val === false ) {
					$this->setWarning( "Action '$t' is not allowed for the current user" );
				} else {
					$pageInfo[$t . 'token'] = $val;
				}
			}
		}

		if ( $this->fld_protection ) {
			$pageInfo['protection'] = array();
			if ( isset( $this->protections[$ns][$dbkey] ) ) {
				$pageInfo['protection'] =
					$this->protections[$ns][$dbkey];
			}
			$this->getResult()->setIndexedTagName( $pageInfo['protection'], 'pr' );
		}

		if ( $this->fld_watched && isset( $this->watched[$ns][$dbkey] ) ) {
			$pageInfo['watched'] = '';
		}

		if ( $this->fld_watchers ) {
			if ( isset( $this->watchers[$ns][$dbkey] ) ) {
				$pageInfo['watchers'] = $this->watchers[$ns][$dbkey];
			} elseif ( $this->showZeroWatchers ) {
				$pageInfo['watchers'] = 0;
			}
		}

		if ( $this->fld_notificationtimestamp ) {
			$pageInfo['notificationtimestamp'] = '';
			if ( isset( $this->notificationtimestamps[$ns][$dbkey] ) ) {
				$pageInfo['notificationtimestamp'] =
					wfTimestamp( TS_ISO_8601, $this->notificationtimestamps[$ns][$dbkey] );
			}
		}

		if ( $this->fld_talkid && isset( $this->talkids[$ns][$dbkey] ) ) {
			$pageInfo['talkid'] = $this->talkids[$ns][$dbkey];
		}

		if ( $this->fld_subjectid && isset( $this->subjectids[$ns][$dbkey] ) ) {
			$pageInfo['subjectid'] = $this->subjectids[$ns][$dbkey];
		}

		if ( $this->fld_url ) {
			$pageInfo['fullurl'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
			$pageInfo['editurl'] = wfExpandUrl( $title->getFullURL( 'action=edit' ), PROTO_CURRENT );
		}
		if ( $this->fld_readable && $title->userCan( 'read', $this->getUser() ) ) {
			$pageInfo['readable'] = '';
		}

		if ( $this->fld_preload ) {
			if ( $titleExists ) {
				$pageInfo['preload'] = '';
			} else {
				$text = null;
				wfRunHooks( 'EditFormPreloadText', array( &$text, &$title ) );

				$pageInfo['preload'] = $text;
			}
		}

		if ( $this->fld_displaytitle ) {
			if ( isset( $this->displaytitles[$pageid] ) ) {
				$pageInfo['displaytitle'] = $this->displaytitles[$pageid];
			} else {
				$pageInfo['displaytitle'] = $title->getPrefixedText();
			}
		}

		return $pageInfo;
	}

	/**
	 * Get information about protections and put it in $protections
	 */
	private function getProtectionInfo() {
		global $wgContLang;
		$this->protections = array();
		$db = $this->getDB();

		// Get normal protections for existing titles
		if ( count( $this->titles ) ) {
			$this->resetQueryParams();
			$this->addTables( 'page_restrictions' );
			$this->addFields( array( 'pr_page', 'pr_type', 'pr_level',
				'pr_expiry', 'pr_cascade' ) );
			$this->addWhereFld( 'pr_page', array_keys( $this->titles ) );

			$res = $this->select( __METHOD__ );
			foreach ( $res as $row ) {
				/** @var $title Title */
				$title = $this->titles[$row->pr_page];
				$a = array(
					'type' => $row->pr_type,
					'level' => $row->pr_level,
					'expiry' => $wgContLang->formatExpiry( $row->pr_expiry, TS_ISO_8601 )
				);
				if ( $row->pr_cascade ) {
					$a['cascade'] = '';
				}
				$this->protections[$title->getNamespace()][$title->getDBkey()][] = $a;
			}
			// Also check old restrictions
			foreach ( $this->titles as $pageId => $title ) {
				if ( $this->pageRestrictions[$pageId] ) {
					$namespace = $title->getNamespace();
					$dbKey = $title->getDBkey();
					$restrictions = explode( ':', trim( $this->pageRestrictions[$pageId] ) );
					foreach ( $restrictions as $restrict ) {
						$temp = explode( '=', trim( $restrict ) );
						if ( count( $temp ) == 1 ) {
							// old old format should be treated as edit/move restriction
							$restriction = trim( $temp[0] );

							if ( $restriction == '' ) {
								continue;
							}
							$this->protections[$namespace][$dbKey][] = array(
								'type' => 'edit',
								'level' => $restriction,
								'expiry' => 'infinity',
							);
							$this->protections[$namespace][$dbKey][] = array(
								'type' => 'move',
								'level' => $restriction,
								'expiry' => 'infinity',
							);
						} else {
							$restriction = trim( $temp[1] );
							if ( $restriction == '' ) {
								continue;
							}
							$this->protections[$namespace][$dbKey][] = array(
								'type' => $temp[0],
								'level' => $restriction,
								'expiry' => 'infinity',
							);
						}
					}
				}
			}
		}

		// Get protections for missing titles
		if ( count( $this->missing ) ) {
			$this->resetQueryParams();
			$lb = new LinkBatch( $this->missing );
			$this->addTables( 'protected_titles' );
			$this->addFields( array( 'pt_title', 'pt_namespace', 'pt_create_perm', 'pt_expiry' ) );
			$this->addWhere( $lb->constructSet( 'pt', $db ) );
			$res = $this->select( __METHOD__ );
			foreach ( $res as $row ) {
				$this->protections[$row->pt_namespace][$row->pt_title][] = array(
					'type' => 'create',
					'level' => $row->pt_create_perm,
					'expiry' => $wgContLang->formatExpiry( $row->pt_expiry, TS_ISO_8601 )
				);
			}
		}

		// Cascading protections
		$images = $others = array();
		foreach ( $this->everything as $title ) {
			if ( $title->getNamespace() == NS_FILE ) {
				$images[] = $title->getDBkey();
			} else {
				$others[] = $title;
			}
		}

		if ( count( $others ) ) {
			// Non-images: check templatelinks
			$lb = new LinkBatch( $others );
			$this->resetQueryParams();
			$this->addTables( array( 'page_restrictions', 'page', 'templatelinks' ) );
			$this->addFields( array( 'pr_type', 'pr_level', 'pr_expiry',
				'page_title', 'page_namespace',
				'tl_title', 'tl_namespace' ) );
			$this->addWhere( $lb->constructSet( 'tl', $db ) );
			$this->addWhere( 'pr_page = page_id' );
			$this->addWhere( 'pr_page = tl_from' );
			$this->addWhereFld( 'pr_cascade', 1 );

			$res = $this->select( __METHOD__ );
			foreach ( $res as $row ) {
				$source = Title::makeTitle( $row->page_namespace, $row->page_title );
				$this->protections[$row->tl_namespace][$row->tl_title][] = array(
					'type' => $row->pr_type,
					'level' => $row->pr_level,
					'expiry' => $wgContLang->formatExpiry( $row->pr_expiry, TS_ISO_8601 ),
					'source' => $source->getPrefixedText()
				);
			}
		}

		if ( count( $images ) ) {
			// Images: check imagelinks
			$this->resetQueryParams();
			$this->addTables( array( 'page_restrictions', 'page', 'imagelinks' ) );
			$this->addFields( array( 'pr_type', 'pr_level', 'pr_expiry',
				'page_title', 'page_namespace', 'il_to' ) );
			$this->addWhere( 'pr_page = page_id' );
			$this->addWhere( 'pr_page = il_from' );
			$this->addWhereFld( 'pr_cascade', 1 );
			$this->addWhereFld( 'il_to', $images );

			$res = $this->select( __METHOD__ );
			foreach ( $res as $row ) {
				$source = Title::makeTitle( $row->page_namespace, $row->page_title );
				$this->protections[NS_FILE][$row->il_to][] = array(
					'type' => $row->pr_type,
					'level' => $row->pr_level,
					'expiry' => $wgContLang->formatExpiry( $row->pr_expiry, TS_ISO_8601 ),
					'source' => $source->getPrefixedText()
				);
			}
		}
	}

	/**
	 * Get talk page IDs (if requested) and subject page IDs (if requested)
	 * and put them in $talkids and $subjectids
	 */
	private function getTSIDs() {
		$getTitles = $this->talkids = $this->subjectids = array();

		/** @var $t Title */
		foreach ( $this->everything as $t ) {
			if ( MWNamespace::isTalk( $t->getNamespace() ) ) {
				if ( $this->fld_subjectid ) {
					$getTitles[] = $t->getSubjectPage();
				}
			} elseif ( $this->fld_talkid ) {
				$getTitles[] = $t->getTalkPage();
			}
		}
		if ( !count( $getTitles ) ) {
			return;
		}

		$db = $this->getDB();

		// Construct a custom WHERE clause that matches
		// all titles in $getTitles
		$lb = new LinkBatch( $getTitles );
		$this->resetQueryParams();
		$this->addTables( 'page' );
		$this->addFields( array( 'page_title', 'page_namespace', 'page_id' ) );
		$this->addWhere( $lb->constructSet( 'page', $db ) );
		$res = $this->select( __METHOD__ );
		foreach ( $res as $row ) {
			if ( MWNamespace::isTalk( $row->page_namespace ) ) {
				$this->talkids[MWNamespace::getSubject( $row->page_namespace )][$row->page_title] =
					intval( $row->page_id );
			} else {
				$this->subjectids[MWNamespace::getTalk( $row->page_namespace )][$row->page_title] =
					intval( $row->page_id );
			}
		}
	}

	private function getDisplayTitle() {
		$this->displaytitles = array();

		$pageIds = array_keys( $this->titles );

		if ( !count( $pageIds ) ) {
			return;
		}

		$this->resetQueryParams();
		$this->addTables( 'page_props' );
		$this->addFields( array( 'pp_page', 'pp_value' ) );
		$this->addWhereFld( 'pp_page', $pageIds );
		$this->addWhereFld( 'pp_propname', 'displaytitle' );
		$res = $this->select( __METHOD__ );

		foreach ( $res as $row ) {
			$this->displaytitles[$row->pp_page] = $row->pp_value;
		}
	}

	/**
	 * Get information about watched status and put it in $this->watched
	 * and $this->notificationtimestamps
	 */
	private function getWatchedInfo() {
		$user = $this->getUser();

		if ( $user->isAnon() || count( $this->everything ) == 0
			|| !$user->isAllowed( 'viewmywatchlist' )
		) {
			return;
		}

		$this->watched = array();
		$this->notificationtimestamps = array();
		$db = $this->getDB();

		$lb = new LinkBatch( $this->everything );

		$this->resetQueryParams();
		$this->addTables( array( 'watchlist' ) );
		$this->addFields( array( 'wl_title', 'wl_namespace' ) );
		$this->addFieldsIf( 'wl_notificationtimestamp', $this->fld_notificationtimestamp );
		$this->addWhere( array(
			$lb->constructSet( 'wl', $db ),
			'wl_user' => $user->getID()
		) );

		$res = $this->select( __METHOD__ );

		foreach ( $res as $row ) {
			if ( $this->fld_watched ) {
				$this->watched[$row->wl_namespace][$row->wl_title] = true;
			}
			if ( $this->fld_notificationtimestamp ) {
				$this->notificationtimestamps[$row->wl_namespace][$row->wl_title] =
					$row->wl_notificationtimestamp;
			}
		}
	}

	/**
	 * Get the count of watchers and put it in $this->watchers
	 */
	private function getWatcherInfo() {
		global $wgUnwatchedPageThreshold;

		if ( count( $this->everything ) == 0 ) {
			return;
		}

		$user = $this->getUser();
		$canUnwatchedpages = $user->isAllowed( 'unwatchedpages' );
		if ( !$canUnwatchedpages && !is_int( $wgUnwatchedPageThreshold ) ) {
			return;
		}

		$this->watchers = array();
		$this->showZeroWatchers = $canUnwatchedpages;
		$db = $this->getDB();

		$lb = new LinkBatch( $this->everything );

		$this->resetQueryParams();
		$this->addTables( array( 'watchlist' ) );
		$this->addFields( array( 'wl_title', 'wl_namespace', 'count' => 'COUNT(*)' ) );
		$this->addWhere( array(
			$lb->constructSet( 'wl', $db )
		) );
		$this->addOption( 'GROUP BY', array( 'wl_namespace', 'wl_title' ) );
		if ( !$canUnwatchedpages ) {
			$this->addOption( 'HAVING', "COUNT(*) >= $wgUnwatchedPageThreshold" );
		}

		$res = $this->select( __METHOD__ );

		foreach ( $res as $row ) {
			$this->watchers[$row->wl_namespace][$row->wl_title] = (int)$row->count;
		}
	}

	public function getCacheMode( $params ) {
		$publicProps = array(
			'protection',
			'talkid',
			'subjectid',
			'url',
			'preload',
			'displaytitle',
		);
		if ( !is_null( $params['prop'] ) ) {
			foreach ( $params['prop'] as $prop ) {
				if ( !in_array( $prop, $publicProps ) ) {
					return 'private';
				}
			}
		}
		if ( !is_null( $params['token'] ) ) {
			return 'private';
		}

		return 'public';
	}

	public function getAllowedParams() {
		return array(
			'prop' => array(
				ApiBase::PARAM_DFLT => null,
				ApiBase::PARAM_ISMULTI => true,
				ApiBase::PARAM_TYPE => array(
					'protection',
					'talkid',
					'watched', # private
					'watchers', # private
					'notificationtimestamp', # private
					'subjectid',
					'url',
					'readable', # private
					'preload',
					'displaytitle',
					// If you add more properties here, please consider whether they
					// need to be added to getCacheMode()
				) ),
			'token' => array(
				ApiBase::PARAM_DFLT => null,
				ApiBase::PARAM_ISMULTI => true,
				ApiBase::PARAM_TYPE => array_keys( $this->getTokenFunctions() )
			),
			'continue' => null,
		);
	}

	public function getParamDescription() {
		return array(
			'prop' => array(
				'Which additional properties to get:',
				' protection            - List the protection level of each page',
				' talkid                - The page ID of the talk page for each non-talk page',
				' watched               - List the watched status of each page',
				' watchers              - The number of watchers, if allowed',
				' notificationtimestamp - The watchlist notification timestamp of each page',
				' subjectid             - The page ID of the parent page for each talk page',
				' url                   - Gives a full URL to the page, and also an edit URL',
				' readable              - Whether the user can read this page',
				' preload               - Gives the text returned by EditFormPreloadText',
				' displaytitle          - Gives the way the page title is actually displayed',
			),
			'token' => 'Request a token to perform a data-modifying action on a page',
			'continue' => 'When more results are available, use this to continue',
		);
	}

	public function getResultProperties() {
		$props = array(
			ApiBase::PROP_LIST => false,
			'' => array(
				'touched' => 'timestamp',
				'lastrevid' => 'integer',
				'counter' => array(
					ApiBase::PROP_TYPE => 'integer',
					ApiBase::PROP_NULLABLE => true
				),
				'length' => 'integer',
				'redirect' => 'boolean',
				'new' => 'boolean',
				'starttimestamp' => array(
					ApiBase::PROP_TYPE => 'timestamp',
					ApiBase::PROP_NULLABLE => true
				),
				'contentmodel' => 'string',
			),
			'watched' => array(
				'watched' => 'boolean'
			),
			'watchers' => array(
				'watchers' => array(
					ApiBase::PROP_TYPE => 'integer',
					ApiBase::PROP_NULLABLE => true
				)
			),
			'notificationtimestamp' => array(
				'notificationtimestamp' => array(
					ApiBase::PROP_TYPE => 'timestamp',
					ApiBase::PROP_NULLABLE => true
				)
			),
			'talkid' => array(
				'talkid' => array(
					ApiBase::PROP_TYPE => 'integer',
					ApiBase::PROP_NULLABLE => true
				)
			),
			'subjectid' => array(
				'subjectid' => array(
					ApiBase::PROP_TYPE => 'integer',
					ApiBase::PROP_NULLABLE => true
				)
			),
			'url' => array(
				'fullurl' => 'string',
				'editurl' => 'string'
			),
			'readable' => array(
				'readable' => 'boolean'
			),
			'preload' => array(
				'preload' => 'string'
			),
			'displaytitle' => array(
				'displaytitle' => 'string'
			)
		);

		self::addTokenProperties( $props, $this->getTokenFunctions() );

		return $props;
	}

	public function getDescription() {
		return 'Get basic page information such as namespace, title, last touched date, ...';
	}

	public function getExamples() {
		return array(
			'api.php?action=query&prop=info&titles=Main%20Page',
			'api.php?action=query&prop=info&inprop=protection&titles=Main%20Page'
		);
	}

	public function getHelpUrls() {
		return 'https://www.mediawiki.org/wiki/API:Properties#info_.2F_in';
	}
}


text:
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

/* System Headers */
#include <pthread.h> /* for pthread_key_*() */
#include <string.h>  /* for memset() */

/* Public Headers */
#include "qthread/cacheline.h"

/* Internal Headers */
#include "qt_spawncache.h"
#include "qt_visibility.h"
#include "qt_debug.h"
#include "qt_asserts.h"
#include "qt_macros.h"
#include "qt_aligned_alloc.h"
#include "qt_subsystems.h"
#include "qt_atomics.h"

/* Globals */
TLS_DECL_INIT(qt_threadqueue_private_t *, spawn_cache);
static qt_threadqueue_private_t *free_these = NULL;

/* Static Functions */
static void qt_spawncache_shutdown(void)
{
    qthread_debug(CORE_DETAILS, "destroy thread-local task queue\n");
    TLS_SET(spawn_cache, NULL);
    qt_threadqueue_private_t *freeme = free_these;
    while (freeme != NULL) {
        free_these = free_these->next;
        qthread_internal_aligned_free(freeme, qthread_cacheline());
        freeme = free_these;
    }
    TLS_DELETE(spawn_cache);
}

/* Internal-only Functions */
void INTERNAL qt_spawncache_init(void)
{
    TLS_INIT(spawn_cache);
    qthread_internal_cleanup(qt_spawncache_shutdown);
}

qt_threadqueue_private_t INTERNAL *qt_init_local_spawncache(void)
{
    qt_threadqueue_private_t *const ret = qthread_internal_aligned_alloc(sizeof(qt_threadqueue_private_t), qthread_cacheline());

    assert(ret);
    memset(ret, 0, sizeof(qt_threadqueue_private_t));

    /* Add this spawncache to the list of things to be freed during shutdown */
    do {
        ret->next = free_these;
    } while (qthread_cas_ptr(&free_these, ret->next, ret) != ret->next);

    TLS_SET(spawn_cache, ret);
    return ret;
}

qt_threadqueue_private_t INTERNAL *qt_spawncache_get()
{
    return TLS_GET(spawn_cache);
}

int INTERNAL qt_spawncache_spawn(qthread_t        *t,
                                 qt_threadqueue_t *q)
{
    qt_threadqueue_private_t *cache = TLS_GET(spawn_cache);

    if (cache) {
        int ret = qt_threadqueue_private_enqueue(cache, q, t);
        if( !ret) {
            return ret;
        }
        return ret;
    } else {
        return 0;
    }
}

int INTERNAL qt_spawncache_yield(qthread_t *t)
{
    qt_threadqueue_private_t *cache = TLS_GET(spawn_cache);

    if (cache) {
        return qt_threadqueue_private_enqueue_yielded(cache, t);
    } else {
        return 0;
    }
}

void INTERNAL qt_spawncache_filter(qt_threadqueue_filter_f f)
{
    qt_threadqueue_private_t *cache = TLS_GET(spawn_cache);

    if (cache) {
        qt_threadqueue_private_filter(cache, f);
    }
}

int INTERNAL qt_spawncache_flush(qt_threadqueue_t *q)
{
    qt_threadqueue_private_t *cache = TLS_GET(spawn_cache);

    if (cache) {
        qthread_debug(THREADQUEUE_BEHAVIOR, "attempting to flush cache %p\n", cache);
        if (cache->on_deck) {
            qthread_debug(THREADQUEUE_DETAILS, "attempting to flush cache %p into queue %p : %u items\n", cache, q, cache->qlength + 1);
            qt_threadqueue_enqueue_cache(q, cache);
            return 1;
        }
        return 0;
    } else {
        return 0;
    }
}

/* vim:set expandtab: */


text:
package avlTree.slpBuilders;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;

public class ParallelExecutor implements IParallelExecutor {

    private final ArrayList<Future<?>> futures = new ArrayList<>();
    private final ThreadFactory threadFactory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("ParallelExecutor-%d").build();
    private final ExecutorService executor;

    public ParallelExecutor(int threadCount) {
        executor = Executors.newFixedThreadPool(threadCount, threadFactory);
    }

    @Override
    public void append(Runnable task) {
        futures.add(executor.submit(task));
    }

    @Override
    public void await() {
        try {
            System.out.println("Tasks count " + futures.size());
            for (Future<?> future : futures) {
                future.get();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        finally {
            executor.shutdownNow();
        }
    }
}


text:
package com.giit.www.entity;

/**
 * Created by c0de8ug on 16-2-9.
 */
public class Book {

    String bookTitle;
    String isbn;
    String dateOfPrinting;
    String author;
    String press;
    String category;
    Short unitPrice;

    public String getBookTitle() {
        return bookTitle;
    }

    public void setBookTitle(String bookTitle) {
        this.bookTitle = bookTitle;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public String getDateOfPrinting() {
        return dateOfPrinting;
    }

    public void setDateOfPrinting(String dateOfPrinting) {
        this.dateOfPrinting = dateOfPrinting;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getPress() {
        return press;
    }

    public void setPress(String press) {
        this.press = press;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public Short getUnitPrice() {
        return unitPrice;
    }

    public void setUnitPrice(Short unitPrice) {
        this.unitPrice = unitPrice;
    }
}


text:
<!DOCTYPE html>

<title>Filament Remote</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1">
<link href="../favicon.png" rel="icon" type="image/x-icon" />
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700" rel="stylesheet">

    Connect to
    <input id="connection-url" type="text" value="localhost" />
    : 8082

<canvas id="webgl2-canvas"></canvas>

Disconnected.

    <button id="copyButton">Copy adb command to clipboard</button>


text:
class printable
{
public:
    // Contructors
    printable () = default;

    template <typename T>
    printable (T value) :
        handle_ (
            new handle<typename std::remove_reference<T>::type>(
                std::move(value)
            )
        )
    {}

    printable (const printable & rhs) :
        handle_ (rhs.handle_->clone())
    {}

    printable (printable && rhs) noexcept :
        handle_ (std::move(rhs.handle_))
    {}

    // Assignment
    template <typename T>
    printable & operator= (T value)
    {
        printable temp(std::move(value));
        std::swap(temp, *this);
        return *this;
    }

    printable & operator= (const printable & rhs)
    {
        printable temp(rhs);
        std::swap(temp, *this);
        return *this;
    }

    printable & operator= (printable && rhs) noexcept
    {
        handle_ = std::move(rhs.handle_);
        return *this;
    }

    // Public interface
    void print () const
    {
        assert(handle_);
        handle_->print();
    }

private:
    struct handle_base
    {
        virtual ~handle_base () {}
        virtual handle_base * clone () const = 0;

        // Public interface
        virtual void print () const = 0;
    };

    template <typename T>
    struct handle :
        handle_base
    {
#if ACCEPT_REFERENCE_WRAPPER
        template <typename U = T>
        handle (T value,
                typename std::enable_if<
                    std::is_reference<U>::value
                >::type * = 0) :
            value_ (value)
        {}

        template <typename U = T>
        handle (T value,
                typename std::enable_if<
                    !std::is_reference<U>::value,
                    int
                >::type * = 0) noexcept :
            value_ (std::move(value))
        {}
#else
        handle (T value) :
            value_ (std::move(value))
        {}
#endif

        virtual handle_base * clone () const
        { return new handle(value_); }

        // Public interface
        virtual void print () const
        { value_.print(); }

        T value_;
    };

#if ACCEPT_REFERENCE_WRAPPER
    template <typename T>
    struct handle<std::reference_wrapper<T>> :
        handle<T &>
    {
        handle (std::reference_wrapper<T> ref) :
            handle<T &> (ref.get())
        {}
    };
#endif

    std::unique_ptr<handle_base> handle_;
};

#endif


text:
<!DOCTYPE html>

Upload Image File

  <input type="file" name="file1" id="file1" onchange="uploadFile()" style="display:none">

<progress id="progressBar" value="0" max="100" style="width:300px;"></progress>


text:
<form
  name="templatedrivenform"
  #templatedrivenform="ngForm"
  (ngSubmit)="onSubmit()">

    firstname*
    <input
      type="text"
      id="firstname"
      name="firstname"
      required
      minlength="4"
      maxlength="56"
      [(ngModel)]="user.firstname"
      #firstname="ngModel" />

          {{ templatedrivenformErrors.firstname }}

    lastname*
    <input
      type="text"
      id="lastname"
      name="lastname"
      required
      [(ngModel)]="user.lastname"
      #lastname="ngModel" />

          {{ templatedrivenformErrors.lastname }}

  <button
    type="submit"
    [disabled]="!templatedrivenform.form.valid">
    send form
  </button>
</form>