text:
package ssh

import (
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"log"
	"net"
	"sync"
	"sync/atomic"
	"time"
)

const (
	minPacketLength = 9
	// channelMaxPacket contains the maximum number of bytes that will be
	// sent in a single packet. As per RFC 4253, section 6.1, 32k is also
	// the minimum.
	channelMaxPacket = 1 << 15
	// We follow OpenSSH here.
	channelWindowSize = 64 * channelMaxPacket
)

// verify interface satisfied.
var _ net.Conn = &channel{}

type HasTimeout interface {
	timeout()
}

// NewChannel represents an incoming request to a channel. It must either be
// accepted for use by calling Accept, or rejected by calling Reject.
type NewChannel interface {
	// Accept accepts the channel creation request. It returns the Channel
	// and a Go channel containing SSH requests. The Go channel must be
	// serviced otherwise the Channel will hang.
	Accept() (Channel, <-chan *Request, error)

	// Reject rejects the channel creation request. After calling
	// this, no other methods on the Channel may be called.
	Reject(reason RejectionReason, message string) error

	// ChannelType returns the type of the channel, as supplied by the
	// client.
	ChannelType() string

	// ExtraData returns the arbitrary payload for this channel, as supplied
	// by the client. This data is specific to the channel type.
	ExtraData() []byte
}

// A Channel is an ordered, reliable, flow-controlled, duplex stream
// that is multiplexed over an SSH connection.
type Channel interface {
	// Read reads up to len(data) bytes from the channel.
	Read(data []byte) (int, error)

	// Write writes len(data) bytes to the channel.
	Write(data []byte) (int, error)

	// Close signals end of channel use. No data may be sent after this
	// call.
	Close() error

	// CloseWrite signals the end of sending in-band
	// data. Requests may still be sent, and the other side may
	// still send data
	CloseWrite() error

	// SendRequest sends a channel request.  If wantReply is true,
	// it will wait for a reply and return the result as a
	// boolean, otherwise the return value will be false. Channel
	// requests are out-of-band messages so they may be sent even
	// if the data stream is closed or blocked by flow control.
	// If the channel is closed before a reply is returned, io.EOF
	// is returned.
	SendRequest(name string, wantReply bool, payload []byte) (bool, error)

	// Stderr returns an io.ReadWriter that writes to this channel
	// with the extended data type set to stderr. Stderr may
	// safely be read and written from a different goroutine than
	// Read and Write respectively.
	Stderr() io.ReadWriter

	// Done can be used to await connection shutdown. The
	// returned channel will be closed when the Channel is closed.
	Done() <-chan struct{}

	// 	GetHalter returns the Channel specific Halter.
	GetHalter() *Halter

	// SetReadIdleTimeout starts an idle timer on
	// Reads that will cause them to timeout after dur.
	// A successful Read will bump the idle
	// timeout into the future.
	//
	// Providing dur of 0 will disable the idle timeout.
	// Zero is the default until SetReadIdleTimeout() is called.
	//
	// SetReadIdleTimeout() will always reset and
	// clear any raised timeout left over from prior use.
	// Any new timer (if dur > 0) begins from the return of
	// the SetReadIdleTimeout() invocation.
	//
	// Idle timeouts are easier to use than deadlines,
	// as they don't need to be refreshed after
	// every read and write. Hence routines like io.Copy()
	// that make many calls to Read() and Write()
	// can be leveraged, while still having a timeout in
	// the case of no activity.
	//
	// Moreover idle timeouts are more
	// efficient because we don't guess at a
	// deadline and then interrupt a perfectly
	// good ongoing copy that happens to be
	// taking a few seconds longer than our
	// guesstimate. We avoid the pain of trying
	// to restart long interrupted transfers that
	// were making fine progress.
	//
	SetReadIdleTimeout(dur time.Duration) error

	// SetWriteIdleTimeout is the same as SetReadIdleTimeout,
	// but applies to writes rather than reads.
	// Note that Write() to
	// a Channel will "succeed" in the sense of
	// returning a nil error long before they
	// reach the remote end (or not). Writes
	// are buffered internally. Hence the write
	// idle timer may be less useful than
	// the read timer.
	SetWriteIdleTimeout(dur time.Duration) error

	// SetIdleTimeout does both SetReadIdleTimeout
	// and SetWriteIdleTimeout.
	SetIdleTimeout(dur time.Duration) error

	// GetReadIdleTimer allows monitoring of idle timeout
	// by other parties. It doesn't disturb the
	// timer if it happens to be running.
	GetReadIdleTimer() *IdleTimer

	// GetWriteIdleTimer allows monitoring of idle timeout
	// by other parties. It doesn't disturb the
	// timer if it happens to be running.
	GetWriteIdleTimer() *IdleTimer

	// SetReadDeadline sets the deadline for future Read calls
	// and any currently-blocked Read call.
	// A zero value for t means Read will not time out.
	SetReadDeadline(t time.Time) error

	// SetWriteDeadline sets the deadline for future Write calls
	// and any currently-blocked Write call.
	// A zero value for t means Write will not time out.
	SetWriteDeadline(t time.Time) error

	// SetDeadline sets the read and write deadlines.
	SetDeadline(t time.Time) error

	// Status lets clients query this Channel's lifecycle
	// progress.
	Status() *RunStatus

	LocalAddr() net.Addr
	RemoteAddr() net.Addr
}

// Request is a request sent outside of the normal stream of
// data. Requests can either be specific to an SSH channel, or they
// can be global.
type Request struct {
	Type      string
	WantReply bool
	Payload   []byte

	ch  *channel
	mux *mux
}

// Reply sends a response to a request. It must be called for all requests
// where WantReply is true and is a no-op otherwise. The payload argument is
// ignored for replies to channel-specific requests.
func (r *Request) Reply(ok bool, payload []byte) error {
	if !r.WantReply {
		return nil
	}

	if r.ch == nil {
		return r.mux.ackRequest(ok, payload)
	}

	return r.ch.ackRequest(ok)
}

// RejectionReason is an enumeration used when rejecting channel creation
// requests. See RFC 4254, section 5.1.
type RejectionReason uint32

const (
	Prohibited RejectionReason = iota + 1
	ConnectionFailed
	UnknownChannelType
	ResourceShortage
)

// String converts the rejection reason to human readable form.
func (r RejectionReason) String() string {
	switch r {
	case Prohibited:
		return "administratively prohibited"
	case ConnectionFailed:
		return "connect failed"
	case UnknownChannelType:
		return "unknown channel type"
	case ResourceShortage:
		return "resource shortage"
	}
	return fmt.Sprintf("unknown reason %d", int(r))
}

func min(a uint32, b int) uint32 {
	if a < uint32(b) {
		return a
	}
	return uint32(b)
}

type channelDirection uint8

const (
	channelInbound channelDirection = iota
	channelOutbound
)

// channel is an implementation of the Channel interface that works
// with the mux class.
type channel struct {
	// R/O after creation
	chanType          string
	extraData         []byte
	localId, remoteId uint32

	// maxIncomingPayload and maxRemotePayload are the maximum
	// payload sizes of normal and extended data packets for
	// receiving and sending, respectively. The wire packet will
	// be 9 or 13 bytes larger (excluding encryption overhead).
	maxIncomingPayload uint32
	maxRemotePayload   uint32

	mux *mux

	// decided is set to true if an accept or reject message has been sent
	// (for outbound channels) or received (for inbound channels).
	decided bool

	// direction contains either channelOutbound, for channels created
	// locally, or channelInbound, for channels created by the peer.
	direction channelDirection

	// Pending internal channel messages.
	msg chan interface{}

	// Since requests have no ID, there can be only one request
	// with WantReply=true outstanding.  This lock is held by a
	// goroutine that has such an outgoing request pending.
	sentRequestMu sync.Mutex

	incomingRequests chan *Request

	sentEOF bool

	// thread-safe data
	remoteWin  window
	pending    *buffer
	extPending *buffer

	// windowMu protects myWindow, the flow-control window.
	windowMu sync.Mutex
	myWindow uint32

	// writeMu serializes calls to mux.conn.writePacket() and
	// protects sentClose and packetPool. This mutex must be
	// different from windowMu, as writePacket can block if there
	// is a key exchange pending.
	writeMu   sync.Mutex
	sentClose bool

	// packetPool has a buffer for each extended channel ID to
	// save allocations during writes.
	packetPool map[uint32][]byte

	// hasClosed makes Close() idempotent. Only
	// the first invocation of Close() has any
	// effect; the result return nil immediately.
	hasClosed int32

	// idleR provides a means
	// for ssh.Channel users to check how
	// many nanoseconds have elapsed since the last
	// error-free read. It is safe for
	// use by multiple goroutines. Users
	// should call SetIdleDur() and BeginAttempt() on it to before
	// any subsequent calls to TimedOut().
	idleR *IdleTimer

	// idleW is for writes, idleR is for reads.
	idleW *IdleTimer

	halt *Halter
}

// writePacket sends a packet. If the packet is a channel close, it updates
// sentClose. This method takes the lock c.writeMu.
func (c *channel) writePacket(packet []byte) error {
	c.writeMu.Lock()
	if c.sentClose {
		c.writeMu.Unlock()
		return io.EOF // TestClientWriteEOF depends on this being io.EOF
	}
	c.sentClose = (packet[0] == msgChannelClose)
	err := c.mux.conn.writePacket(packet)
	if err == nil {
		c.idleW.AttemptOK()
	}
	c.writeMu.Unlock()
	return err
}

func (c *channel) sendMessage(msg interface{}) error {
	if debugMux {
		log.Printf("send(%d): %#v", c.mux.chanList.offset, msg)
	}

	p := Marshal(msg)
	binary.BigEndian.PutUint32(p[1:], c.remoteId)
	return c.writePacket(p)
}

// WriteExtended writes data to a specific extended stream. These streams are
// used, for example, for stderr.
func (c *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err error) {
	c.idleW.BeginAttempt()
	defer func() {
		if err == nil {
			c.idleW.AttemptOK()
		}
	}()
	if c.sentEOF {
		return 0, io.EOF
	}
	// 1 byte message type, 4 bytes remoteId, 4 bytes data length
	opCode := byte(msgChannelData)
	headerLength := uint32(9)
	if extendedCode > 0 {
		headerLength += 4
		opCode = msgChannelExtendedData
	}

	c.writeMu.Lock()
	packet := c.packetPool[extendedCode]
	// We don't remove the buffer from packetPool, so
	// WriteExtended calls from different goroutines will be
	// flagged as errors by the race detector.
	c.writeMu.Unlock()

	for len(data) > 0 {
		space := min(c.maxRemotePayload, len(data))
		if space, err = c.remoteWin.reserve(space); err != nil {
			return n, err
		}
		c.idleW.AttemptOK()
		if want := headerLength + space; uint32(cap(packet)) < want {
			packet = make([]byte, want)
		} else {
			packet = packet[:want]
		}

		todo := data[:space]

		packet[0] = opCode
		binary.BigEndian.PutUint32(packet[1:], c.remoteId)
		if extendedCode > 0 {
			binary.BigEndian.PutUint32(packet[5:], uint32(extendedCode))
		}
		binary.BigEndian.PutUint32(packet[headerLength-4:], uint32(len(todo)))
		copy(packet[headerLength:], todo)
		if err = c.writePacket(packet); err != nil {
			return n, err
		}
		c.idleW.AttemptOK()

		n += len(todo)
		data = data[len(todo):]
	}

	c.writeMu.Lock()
	c.packetPool[extendedCode] = packet
	c.writeMu.Unlock()

	return n, err
}

func (c *channel) handleData(packet []byte) error {
	headerLen := 9
	isExtendedData := packet[0] == msgChannelExtendedData
	if isExtendedData {
		headerLen = 13
	}
	if len(packet) < headerLen {
		// malformed data packet
		return parseError(packet[0])
	}

	var extended uint32
	if isExtendedData {
		extended = binary.BigEndian.Uint32(packet[5:])
	}

	length := binary.BigEndian.Uint32(packet[headerLen-4 : headerLen])
	if length == 0 {
		return nil
	}
	if length > c.maxIncomingPayload {
		// TODO(hanwen): should send Disconnect?
		return errors.New("ssh: incoming packet exceeds maximum payload size")
	}

	data := packet[headerLen:]
	if length != uint32(len(data)) {
		return errors.New("ssh: wrong packet length")
	}

	c.windowMu.Lock()
	if c.myWindow < length {
		c.windowMu.Unlock()
		// TODO(hanwen): should send Disconnect with reason?
		return errors.New("ssh: remote side wrote too much")
	}
	c.myWindow -= length
	c.windowMu.Unlock()

	if extended == 1 {
		c.extPending.write(data)
	} else if extended > 0 {
		// discard other extended data.
	} else {
		c.pending.write(data)
	}
	return nil
}

func (c *channel) adjustWindow(n uint32) error {
	c.windowMu.Lock()
	// Since myWindow is managed on our side, and can never exceed
	// the initial window setting, we don't worry about overflow.
	c.myWindow += uint32(n)
	c.windowMu.Unlock()
	return c.sendMessage(windowAdjustMsg{
		AdditionalBytes: uint32(n),
	})
}

func (c *channel) ReadExtended(data []byte, extended uint32) (n int, err error) {
	c.idleR.BeginAttempt()
	switch extended {
	case 1:
		n, err = c.extPending.Read(data)
	case 0:
		n, err = c.pending.Read(data)
	default:
		return 0, fmt.Errorf("ssh: extended code %d unimplemented", extended)
	}
	if err == nil {
		c.idleR.AttemptOK()
	}

	if n > 0 {
		err = c.adjustWindow(uint32(n))
		// sendWindowAdjust can return io.EOF if the remote
		// peer has closed the connection, however we want to
		// defer forwarding io.EOF to the caller of Read until
		// the buffer has been drained.
		if n > 0 && err == io.EOF {
			err = nil
		}
	}

	return n, err
}

func (c *channel) close() {
	c.pending.eof()
	c.extPending.eof()
	close(c.msg)
	close(c.incomingRequests)
	c.writeMu.Lock()
	// This is not necessary for a normal channel teardown, but if
	// there was another error, it is.
	c.sentClose = true
	c.writeMu.Unlock()
	// Unblock writers.
	c.remoteWin.close()
	c.halt.RequestStop()
	c.halt.MarkDone()
	c.idleR.Stop()
	c.idleW.Stop()
}

func (c *channel) timeout() {
	c.pending.timeout()
	c.extPending.timeout()
	// Unblock writers.
	c.remoteWin.timeout()
	mt, ok := c.mux.conn.(HasTimeout)
	if ok {
		mt.timeout() // unblock goroutines stuck in *memTransport
	}
}

// responseMessageReceived is called when a success or failure message is
// received on a channel to check that such a message is reasonable for the
// given channel.
func (c *channel) responseMessageReceived() error {
	if c.direction == channelInbound {
		return errors.New("ssh: channel response message received on inbound channel")
	}
	if c.decided {
		return errors.New("ssh: duplicate response received for channel")
	}
	c.decided = true
	return nil
}

func (c *channel) handlePacket(packet []byte) error {
	c.idleR.AttemptOK()
	switch packet[0] {
	case msgChannelData, msgChannelExtendedData:
		return c.handleData(packet)
	case msgChannelClose:
		c.sendMessage(channelCloseMsg{PeersId: c.remoteId})
		c.mux.chanList.remove(c.localId)
		c.close()
		return nil
	case msgChannelEOF:
		// RFC 4254 is mute on how EOF affects dataExt messages but
		// it is logical to signal EOF at the same time.
		c.extPending.eof()
		c.pending.eof()
		return nil
	}

	decoded, err := decode(packet)
	if err != nil {
		return err
	}

	reqStopCh := c.halt.ReqStopChan()
	var reqStopMux chan struct{}
	if c.mux.halt != nil {
		reqStopMux = c.mux.halt.ReqStopChan()
	}

	switch msg := decoded.(type) {
	case *channelOpenFailureMsg:
		if err := c.responseMessageReceived(); err != nil {
			return err
		}
		c.mux.chanList.remove(msg.PeersId)
		select {
		case c.msg <- msg:
		case <-reqStopMux:
			return io.EOF
		case <-reqStopCh:
			return io.EOF
		}
	case *channelOpenConfirmMsg:
		if err := c.responseMessageReceived(); err != nil {
			return err
		}
		if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
			return fmt.Errorf("ssh: invalid MaxPacketSize %d from peer", msg.MaxPacketSize)
		}
		c.remoteId = msg.MyId
		c.maxRemotePayload = msg.MaxPacketSize
		c.remoteWin.add(msg.MyWindow)
		select {
		case c.msg <- msg:
		case <-reqStopMux:
			return io.EOF
		case <-reqStopCh:
			return io.EOF
		}
	case *windowAdjustMsg:
		if !c.remoteWin.add(msg.AdditionalBytes) {
			return fmt.Errorf("ssh: invalid window update for %d bytes", msg.AdditionalBytes)
		}
	case *channelRequestMsg:
		req := Request{
			Type:      msg.Request,
			WantReply: msg.WantReply,
			Payload:   msg.RequestSpecificData,
			ch:        c,
		}
		select {
		case c.incomingRequests <- &req:
		case <-reqStopMux:
			return io.EOF
		case <-reqStopCh:
			return io.EOF
		}
	default:
		select {
		case c.msg <- msg:
		case <-reqStopMux:
			return io.EOF
		case <-reqStopCh:
			return io.EOF
		}
	}
	return nil
}

func (m *mux) newChannel(chanType string, direction channelDirection, extraData []byte) *channel {
	idleR, idleW := NewIdleTimer(nil, 0), NewIdleTimer(nil, 0)
	ch := &channel{
		remoteWin:        window{Cond: newCond(), idle: idleR},
		myWindow:         channelWindowSize,
		pending:          newBuffer(idleR),
		extPending:       newBuffer(idleR),
		direction:        direction,
		incomingRequests: make(chan *Request, chanSize),
		msg:              make(chan interface{}, chanSize),
		chanType:         chanType,
		extraData:        extraData,
		mux:              m,
		packetPool:       make(map[uint32][]byte),
		idleR:            idleR,
		idleW:            idleW,
		halt:             NewHalter(),
	}
	idleR.AddTimeoutCallback(ch.timeout)
	idleW.AddTimeoutCallback(ch.timeout)
	ch.localId = m.chanList.add(ch)
	return ch
}

var errUndecided = errors.New("ssh: must Accept or Reject channel")
var errDecidedAlready = errors.New("ssh: can call Accept or Reject only once")

type extChannel struct {
	code uint32
	ch   *channel
}

func (e *extChannel) Write(data []byte) (n int, err error) {
	return e.ch.WriteExtended(data, e.code)
}

func (e *extChannel) Read(data []byte) (n int, err error) {
	return e.ch.ReadExtended(data, e.code)
}

func (c *channel) Accept() (Channel, <-chan *Request, error) {
	if c.decided {
		return nil, nil, errDecidedAlready
	}
	c.maxIncomingPayload = channelMaxPacket
	confirm := channelOpenConfirmMsg{
		PeersId:       c.remoteId,
		MyId:          c.localId,
		MyWindow:      c.myWindow,
		MaxPacketSize: c.maxIncomingPayload,
	}
	c.decided = true
	if err := c.sendMessage(confirm); err != nil {
		return nil, nil, err
	}

	return c, c.incomingRequests, nil
}

func (ch *channel) Reject(reason RejectionReason, message string) error {
	if ch.decided {
		return errDecidedAlready
	}
	reject := channelOpenFailureMsg{
		PeersId:  ch.remoteId,
		Reason:   reason,
		Message:  message,
		Language: "en",
	}
	ch.decided = true
	ch.idleR.Halt.RequestStop()
	ch.idleW.Halt.RequestStop()

	return ch.sendMessage(reject)
}

func (ch *channel) Read(data []byte) (int, error) {
	if !ch.decided {
		return 0, errUndecided
	}
	return ch.ReadExtended(data, 0)
}

func (ch *channel) Write(data []byte) (int, error) {
	if !ch.decided {
		return 0, errUndecided
	}
	return ch.WriteExtended(data, 0)
}

func (ch *channel) CloseWrite() error {
	if !ch.decided {
		return errUndecided
	}
	ch.sentEOF = true
	return ch.sendMessage(channelEOFMsg{
		PeersId: ch.remoteId})
}

func (ch *channel) Close() error {
	if !atomic.CompareAndSwapInt32(&ch.hasClosed, 0, 1) {
		// idempotent Close
		return nil
	}
	ch.idleR.Halt.RequestStop()
	ch.idleW.Halt.RequestStop()
	ch.halt.RequestStop()
	ch.halt.MarkDone()

	if !ch.decided {
		return errUndecided
	}

	return ch.sendMessage(channelCloseMsg{
		PeersId: ch.remoteId})
}

// Extended returns an io.ReadWriter that sends and receives data on the given,
// SSH extended stream. Such streams are used, for example, for stderr.
func (ch *channel) Extended(code uint32) io.ReadWriter {
	if !ch.decided {
		return nil
	}
	return &extChannel{code, ch}
}

func (ch *channel) Stderr() io.ReadWriter {
	return ch.Extended(1)
}

// Done returns the mux's halt.ReqStopChan(), so
// it lasts until the connection is lost. Use
// GetHalter() below to get a Channel specific
// done channel.
func (ch *channel) Done() <-chan struct{} {
	if ch.mux.halt != nil {
		return ch.mux.halt.ReqStopChan()
	}
	return nil
}

// GetHalter returns the channel ch specific Halter.
func (ch *channel) GetHalter() *Halter {
	return ch.halt
}

func (ch *channel) SendRequest(name string, wantReply bool, payload []byte) (bool, error) {
	if !ch.decided {
		return false, errUndecided
	}

	if wantReply {
		ch.sentRequestMu.Lock()
		defer ch.sentRequestMu.Unlock()
	}

	msg := channelRequestMsg{
		PeersId:             ch.remoteId,
		Request:             name,
		WantReply:           wantReply,
		RequestSpecificData: payload,
	}

	if err := ch.sendMessage(msg); err != nil {
		return false, err
	}
	var reqStopMux chan struct{}
	if ch.mux.halt != nil {
		reqStopMux = ch.mux.halt.ReqStopChan()
	}
	reqStopCh := ch.halt.ReqStopChan()

	if wantReply {
		select {
		case <-reqStopMux:
			return false, io.EOF
		case <-reqStopCh:
			return false, io.EOF
		case m, ok := (<-ch.msg):
			if !ok {
				return false, io.EOF
			}
			switch m.(type) {
			case *channelRequestFailureMsg:
				return false, nil
			case *channelRequestSuccessMsg:
				return true, nil
			default:
				return false, fmt.Errorf("ssh: unexpected response to channel request: %#v", m)
			}

		}

	}

	return false, nil
}

// ackRequest either sends an ack or nack to the channel request.
func (ch *channel) ackRequest(ok bool) error {
	if !ch.decided {
		return errUndecided
	}

	var msg interface{}
	if !ok {
		msg = channelRequestFailureMsg{
			PeersId: ch.remoteId,
		}
	} else {
		msg = channelRequestSuccessMsg{
			PeersId: ch.remoteId,
		}
	}
	return ch.sendMessage(msg)
}

func (ch *channel) ChannelType() string {
	return ch.chanType
}

func (ch *channel) ExtraData() []byte {
	return ch.extraData
}

// net.Conn compat:

type chanAddr struct {
	name string
}

// name of the network (for example, "tcp", "udp")
func (c *chanAddr) Network() string {
	return "ssh-channel"
}

// string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80")
func (c *chanAddr) String() string {
	return c.name
}

var sshChanAddr chanAddr

// LocalAddr returns the local network address.
func (c *channel) LocalAddr() net.Addr {
	return &sshChanAddr
}

// RemoteAddr returns the remote network address.
func (c *channel) RemoteAddr() net.Addr {
	return &sshChanAddr
}

// SetReadIdleTimeout establishes a new timeout duration
// and starts the timing machinery off and running.
// A dur of zero will disable timeouts.
//
// SetReadIdleTimeout() will always reset and
// clear any raised timeout left over from prior use.
// Any new timer (if dur > 0) begins from the return of
// the SetReadIdleTimeout() invocation.
//
func (c *channel) SetReadIdleTimeout(dur time.Duration) error {
	c.idleR.SetIdleTimeout(dur)
	return nil
}

// SetWriteIdleTimeout establishes a new timeout duration
// and starts the timing machinery off and running.
// A dur of zero will disable timeouts.
//
// SetWriteIdleTimeout() will always reset and
// clear any raised timeout left over from prior use.
// Any new timer (if dur > 0) begins from the return of
// the SetWriteIdleTimeout() invocation.
//
func (c *channel) SetWriteIdleTimeout(dur time.Duration) error {
	c.idleW.SetIdleTimeout(dur)
	return nil
}

// SetIdleTimeout does both SetReadIdleTimeout and SetWriteIdleTimeout.
func (c *channel) SetIdleTimeout(dur time.Duration) error {
	c.idleR.SetIdleTimeout(dur)
	c.idleW.SetIdleTimeout(dur)
	return nil
}

func (c *channel) SetReadDeadline(t time.Time) error {
	return c.setDeadline(t, true)
}

func (c *channel) SetWriteDeadline(t time.Time) error {
	return c.setDeadline(t, false)
}

func (c *channel) SetDeadline(t time.Time) error {
	c.setDeadline(t, false)
	return c.setDeadline(t, true)
}

func (c *channel) setDeadline(t time.Time, reads bool) error {
	if t.IsZero() {
		if reads {
			c.idleR.SetOneshotIdleTimeout(0)
		} else {
			c.idleW.SetOneshotIdleTimeout(0)
		}
	} else {
		var dur time.Duration
		now := time.Now()
		if !now.Before(t) {
			// they are late, but they don't want to block,
			// or they would have sent us a zero time.
			// So set a minimal timeout that will unblock
			// any reads immediately.
			dur = time.Nanosecond
		} else {
			dur = t.Sub(now)
		}
		if reads {
			c.idleR.SetOneshotIdleTimeout(dur)
		} else {
			c.idleW.SetOneshotIdleTimeout(dur)
		}
	}
	return nil
}

func (c *channel) GetReadIdleTimer() *IdleTimer {
	return c.idleR
}

func (c *channel) GetWriteIdleTimer() *IdleTimer {
	return c.idleW
}

// Status observes the goroutine lifecycle.
func (c *channel) Status() (r *RunStatus) {
	r = &RunStatus{}
	r.Ready = c.idleR.Halt.IsReady()
	r.StopRequested = c.idleR.Halt.IsStopRequested()
	r.Done = c.idleR.Halt.IsDone()
	if r.Done {
		r.Err = c.idleR.Halt.Err()
	}
	r.DoneCh = c.idleR.Halt.DoneChan()
	return
}


text:
<?php

namespace Flarum\Locale;

class LocaleManager
{
    protected $locales = [];

    protected $translations = [];

    protected $js = [];

    protected $config = [];

    public function addLocale($locale, $name)
    {
        $this->locales[$locale] = $name;
    }

    public function getLocales()
    {
        return $this->locales;
    }

    public function hasLocale($locale)
    {
        return isset($this->locales[$locale]);
    }

    public function addTranslations($locale, $translations)
    {
        $this->translations[$locale][] = $translations;
    }

    public function addJsFile($locale, $js)
    {
        $this->js[$locale][] = $js;
    }

    public function addConfig($locale, $config)
    {
        $this->config[$locale][] = $config;
    }

    public function getTranslations($locale)
    {
        $files = array_get($this->translations, $locale, []);

        $parts = explode('-', $locale);

        if (count($parts) > 1) {
            $files = array_merge(array_get($this->translations, $parts[0], []), $files);
        }

        $compiler = new TranslationCompiler($locale, $files);

        return $compiler->getTranslations();
    }

    public function getJsFiles($locale)
    {
        $files = array_get($this->js, $locale, []);

        $parts = explode('-', $locale);

        if (count($parts) > 1) {
            $files = array_merge(array_get($this->js, $parts[0], []), $files);
        }

        return $files;
    }

    public function getConfig($locale)
    {
        if (empty($this->config[$locale])) {
            return [];
        }

        $config = [];

        foreach ($this->config[$locale] as $file) {
            $config = array_merge($config, include $file);
        }

        return $config;
    }
}

redpajama_set_name: RedPajamaGithub


text:
<?php

use kartik\builder\TabularForm;
use kartik\widgets\ActiveForm;
use yii\data\ActiveDataProvider;
use yii\helpers\Html;
use yii\grid\GridView;
use yii\helpers\Url;

/* @var $this yii\web\View */
/* @var $searchModel common\modules\rapid_assessment\models\search\ReportItemIncidentSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */

$this->title = Yii::t('app', 'Report Item Incidents');
$this->params['breadcrumbs'][] = $this->title;
?>

    <?php // echo $this->render('_search', ['model' => $searchModel]); ?>

        <?= Html::a(Yii::t('app', 'Create Report Item Incident'), ['create'], ['class' => 'btn btn-success']) ?>

    <?php  GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],

            'id',
            'type',
            'item_name',
            'class_basis',
            'class_name',
            // 'title',
            // 'description:ntext',
            // 'is_verified:boolean',
            // 'status',
            // 'timestamp_occurance',
            // 'timestamp_created_at',
            // 'timestamp_updated_at',
            // 'tags',
            // 'meta_hstore',
            // 'meta_json',
            // 'declared_by',
            // 'timestamp_declared_at',
            // 'magnitude',
            // 'units',
            // 'wkt:ntext',
            // 'geom',
            // 'latitude',
            // 'longitude',
            // 'address',
            // 'user_id',
            // 'owner_name',
            // 'owner_contact',
            // 'supplied_per_person',
            // 'event',
            // 'event_name',

            // 'income_source',
            // 'income_level',
            // 'no_of_occupants',
            // 'current_condition:ntext',
            // 'construction_type:ntext',
            // 'occupancy_type:ntext',
            // 'current_income_status:ntext',

            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>

    <?php $form = ActiveForm::begin()?>
    <?php
    echo TabularForm::widget([
        'form' => $form,
        'dataProvider' => $dataProvider,//new ActiveDataProvider(['query' => $model]),
        'attributes' => [
            'item_name' => ['type' => TabularForm::INPUT_TEXT],
            'magnitude' => [
                'label'=>'Count',
                'type' => TabularForm::INPUT_TEXT
            ],

        ],
        'gridSettings' => [
            'floatHeader' => true,
            'panel' => [
                //'heading' => '
 Reports
',
                'type' => \kartik\grid\GridView::TYPE_PRIMARY,
                'after'=>'
'.
                    Html::a(
                        '',
                        Url::to(['/rapid_assessment/crud-report-item-incident/create']),
                        ['class'=>'btn btn-success']
                    ) . ' ' .
                    Html::a(
                        '',
                        '$deleteUrl',
                        ['class'=>'btn btn-danger']
                    ).'
'
            ]
        ]
    ]);
    ?>
    <?php $form->end();?>


text:
<?php

namespace Bartlett\Tests\Reflect\Analyser;

class BarAnalyser
{
}


text: Playing with generating some test data for SQL Server DBs as this is sometimes useful.


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Neodroid: droid.Runtime.Messaging.FBS.FVector2 Struct Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

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

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

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

Neodroid
    0.2.0

Machine Learning Environment Prototyping Tool

Public Member Functions |
Static Public Member Functions |
Properties |
List of all members

droid.Runtime.Messaging.FBS.FVector2 Struct Reference

Inheritance diagram for droid.Runtime.Messaging.FBS.FVector2:

[legend]

Collaboration diagram for droid.Runtime.Messaging.FBS.FVector2:

[legend]

Public Member Functions

void 	__init (int _i, ByteBuffer _bb)

FVector2 	__assign (int _i, ByteBuffer _bb)

Static Public Member Functions

static Offset< FVector2 > 	CreateFVector2 (FlatBufferBuilder builder, double X, double Y)

Properties

ByteBuffer 	ByteBuffer [get]

double 	X [get]

double 	Y [get]

Detailed Description

Definition at line 51 of file NeodroidFBSShared.cs.

Member Function Documentation

◆ __assign()

          FVector2 droid.Runtime.Messaging.FBS.FVector2.__assign
          (
          int
          _i,

          ByteBuffer
          _bb

          )

Definition at line 56 of file NeodroidFBSShared.cs.

◆ __init()

          void droid.Runtime.Messaging.FBS.FVector2.__init
          (
          int
          _i,

          ByteBuffer
          _bb

          )

Definition at line 55 of file NeodroidFBSShared.cs.

◆ CreateFVector2()

          static Offset<FVector2> droid.Runtime.Messaging.FBS.FVector2.CreateFVector2
          (
          FlatBufferBuilder
          builder,

          double
          X,

          double
          Y

          )

static

Definition at line 61 of file NeodroidFBSShared.cs.

Property Documentation

◆ ByteBuffer

          ByteBuffer droid.Runtime.Messaging.FBS.FVector2.ByteBuffer

get

Definition at line 54 of file NeodroidFBSShared.cs.

◆ X

          double droid.Runtime.Messaging.FBS.FVector2.X

get

Definition at line 58 of file NeodroidFBSShared.cs.

◆ Y

          double droid.Runtime.Messaging.FBS.FVector2.Y

get

Definition at line 59 of file NeodroidFBSShared.cs.

The documentation for this struct was generated from the following file:

/home/heider/Projects/Neodroid/Unity/Examples/Assets/droid/Runtime/Messaging/FBS/NeodroidFBSShared.cs

droid

Runtime

Messaging

FBS

FVector2

Generated by

     1.8.13


text:
This is the workflow that I use for getting from a check scanned with the mail
to a 200 dpi JPEG that my bank will accept for e-Deposit.

This depends on pdftk and imagemagick.


text:
from warnings import warn
from sympy.utilities.exceptions import SymPyDeprecationWarning
from pygletplot import PygletPlot

def Plot(*args, **kwargs):
    """ A temporary proxy for an interface under deprecation.

    This proxy is the one imported by `from sympy import *`.

    The Plot class will change in future versions of sympy to use the new
    plotting module. That new plotting module is already used by the
    plot() function (lowercase). To write code compatible with future versions
    of sympy use that function (plot() lowercase). Or if you want to use the
    old plotting module just import it directly:
    `from sympy.plotting.pygletplot import PygletPlot`

    To use Plot from the new plotting module do:
    `from sympy.plotting.plot import Plot`

    In future version of sympy you will also be able to use
    `from sympy.plotting import Plot` but in the current version this will
    import this proxy object. It's done for backward compatibility.

    The old plotting module is not deprecated. Only the location will
    change. The new location is sympy.plotting.pygletplot.
    """
    SymPyDeprecationWarning(value="This interface will change in future "
        "versions of SymPy.  As a precatuion use the plot() function "
        "(lowercase), or use sympy.plotting.pygletplot.PygletPlot to "
        "continue using Pyglet.  See the docstring of this function for "
        "details.", feature="Plot as an interface to Pyglet",
        issue=2845, deprecated_since_version="0.7.2"
    ).warn()

    return PygletPlot(*args, **kwargs)


text:
<!DOCTYPE html>

 <html <?php language_attributes(); ?> class="no-js">

	<meta charset="utf-8">

	<title><?php wp_title(' | ', true, 'right'); ?> <?php bloginfo('name'); ?></title>

	<meta name="viewport" content="width=device-width">
	<?php if (of_get_option('meta') == '1'){?>
<meta name="keywords" content="<?php echo of_get_option('metakeywords'); ?>" />
	<meta name="description" content="<?php echo of_get_option('metadescription'); ?>" />
	<?php }else {?>
	<?php }?>

	<link rel="stylesheet" media="all" href="<?php bloginfo('stylesheet_url'); ?>"/>

<?php if(of_get_option('customtypography') == '1') { ?>
<?php if(of_get_option('headingfontlink') != '') { ?>
<?php echo stripslashes(html_entity_decode(of_get_option('headingfontlink')));?>
<?php } ?>

<?php if(of_get_option('bodyfontlink') != '') { ?>
<?php echo stripslashes(html_entity_decode(of_get_option('bodyfontlink')));?>
<?php } ?>

<?php if(of_get_option('logofontlink') != '') { ?>
<?php echo stripslashes(html_entity_decode(of_get_option('logofontlink')));?>
<?php } ?>
<?php load_template( get_template_directory() . '/custom.typography.css.php' );?>

<?php } ?>

<?php load_template( get_template_directory() . '/custom.colors.css.php' );?>

<?php wp_head(); ?>

	<body <?php body_class(); ?> <?php if(of_get_option('layout') != 'left' && of_get_option('layout') != ''):?>id="right-sidebar"<?php endif;?>>

			<div <?php if(of_get_option('sidebar') ==fixed){?>class="header_container_fixed"<?php }else{?>class="header_container_flat"<?php }?>>

					<h1 <?php if(of_get_option('image_logo') != 1){?>class="textlogo"<?php }else{?>class="logo"<?php }?> title="<?php  echo get_bloginfo('name');?>">
						<a href="<?php bloginfo('url');?>">

	                    <?php if(of_get_option('image_logo') != 1){?>

	                        <?php if(of_get_option('logo_text')) : echo of_get_option('logo_text'); endif;?>

	                        <?php }else{?>

                            <?php if(of_get_option('logo')) : echo ''; endif;?>
						<?php }?>

<?php  echo get_bloginfo('description');?>

                    <?php if ( has_nav_menu( 'main_nav' ) ) {?>
                    	<?php  site5_main_nav(''); ?>
                  	<?php }?>

	                	<?php get_search_form(); ?>


text:
gem install xcode-install
xcode-install list
xcode-install install "7 beta 5"
xcode-install select "7 beta 5"

#carthage build --no-skip-current

xcodebuild -workspace git2.xcworkspace -scheme git2-iOS -configuration Release build
xcodebuild -workspace git2.xcworkspace -scheme git2-Mac -configuration Release build


text:
def remove_duplicates(nums)
    return 0 if nums.length == 0

    current_unique_length = 1
    previous_value = nums[0]

    nums.each do |current_value|
        if current_value != previous_value
            nums[current_unique_length] = current_value
            previous_value = current_value
            current_unique_length += 1
        end
    end

    current_unique_length
end


text:
package org.jivesoftware.openfire.handler;

import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.QName;
import org.jivesoftware.admin.AdminConsole;
import org.jivesoftware.openfire.IQHandlerInfo;
import org.jivesoftware.openfire.PacketException;
import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
import org.xmpp.packet.IQ;
import org.xmpp.packet.PacketError;

import java.util.Collections;
import java.util.Iterator;

/**
 * Implements the TYPE_IQ jabber:iq:version protocol (version info). Allows
 * XMPP entities to query each other's application versions.  The server
 * will respond with its current version info.
 *
 * @author Iain Shigeoka
 */
public class IQVersionHandler extends IQHandler implements ServerFeaturesProvider {

    private static Element bodyElement;
    private IQHandlerInfo info;

    public IQVersionHandler() {
        super("XMPP Server Version Handler");
        info = new IQHandlerInfo("query", "jabber:iq:version");
        if (bodyElement == null) {
            bodyElement = DocumentHelper.createElement(QName.get("query", "jabber:iq:version"));
            bodyElement.addElement("name").setText(AdminConsole.getAppName());
            bodyElement.addElement("version").setText(AdminConsole.getVersionString());
        }
    }

	@Override
	public IQ handleIQ(IQ packet) throws PacketException {
		if (IQ.Type.get == packet.getType()) {
			// Could cache this information for every server we see
			Element answerElement = bodyElement.createCopy();
			try {
				// Try to retrieve this for every request - security settings
				// might be changed runtime!
				final String os = System.getProperty("os.name") + ' '
						+ System.getProperty("os.version") + " ("
						+ System.getProperty("os.arch") + ')';
				final String java = "Java " + System.getProperty("java.version");
				answerElement.addElement("os").setText(os + " - " + java);
			} catch (SecurityException ex) {
				// Security settings don't allow the OS to be read. We'll honor
				// this and simply not report it.
			}
			IQ result = IQ.createResultIQ(packet);
			result.setChildElement(answerElement);
			return result;
		} else if (IQ.Type.set == packet.getType()) {
			// Answer an not-acceptable error since IQ should be of type GET
			IQ result = IQ.createResultIQ(packet);
			result.setError(PacketError.Condition.not_acceptable);
			return result;
		}
		// Ignore any other type of packet
		return null;
	}

    @Override
	public IQHandlerInfo getInfo() {
        return info;
    }

	@Override
    public Iterator<String> getFeatures() {
        return Collections.singleton("jabber:iq:version").iterator();
    }
}


text:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.rajendarreddyj</groupId>
    <artifactId>eclipse-weblogic-plugin</artifactId>
    <version>1.1.0</version>
  </parent>
  <artifactId>com.rajendarreddyj.eclipse.plugins.weblogic.site</artifactId>
  <packaging>eclipse-repository</packaging>
</project>


text:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.jms.JMSException;
import javax.jms.Destination;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.MessageConsumer;
import javax.jms.Session;

/**
 * Asynchronous MessageConsumer example.
 *
 * @author Tim Anderson
 * @version $Revision: 1.2 $ $Date: 2005/11/18 03:28:00 $
 */
public class Listener {

    /**
     * Main line.
     *
     * @param args command line arguments
     */
    public static void main(String[] args) {
        Context context = null;
        ConnectionFactory factory = null;
        Connection connection = null;
        String factoryName = "ConnectionFactory";
        String destName = null;
        Destination dest = null;
        Session session = null;
        MessageConsumer receiver = null;
        BufferedReader waiter = null;

        if (args.length != 1) {
            System.out.println("usage: Listener <destination>");
            System.exit(1);
        }

        destName = args[0];

        try {
            // create the JNDI initial context.
            context = new InitialContext();

            // look up the ConnectionFactory
            factory = (ConnectionFactory) context.lookup(factoryName);

            // look up the Desination
            dest = (Destination) context.lookup(destName);

            // create the connection
            connection = factory.createConnection();

            // create the session
            session = connection.createSession(
                false, Session.AUTO_ACKNOWLEDGE);

            // create the receiver
            receiver = session.createConsumer(dest);

            // register a listener
            receiver.setMessageListener(new SampleListener());

            // start the connection, to enable message receipt
            connection.start();

            System.out.println("Waiting for messages...");
            System.out.println("Press [return] to quit");

            waiter = new BufferedReader(new InputStreamReader(System.in));
            waiter.readLine();
        } catch (IOException exception) {
            exception.printStackTrace();
        } catch (JMSException exception) {
            exception.printStackTrace();
        } catch (NamingException exception) {
            exception.printStackTrace();
        } finally {
            // close the context
            if (context != null) {
                try {
                    context.close();
                } catch (NamingException exception) {
                    exception.printStackTrace();
                }
            }

            // close the connection
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException exception) {
                    exception.printStackTrace();
                }
            }
        }
    }
}


text:
import {
    createAskSdkError,
    DefaultApiClient,
    DynamoDbPersistenceAdapter,
    RequestHandler,
    SkillBuilders
} from 'ask-sdk';
import {
    RequestEnvelope,
    Response,
    ResponseEnvelope
} from 'ask-sdk-model';
import { DynamoDB } from 'aws-sdk';
import { EventEmitter } from 'events';
import * as i18n from 'i18next';
import * as sprintf from 'i18next-sprintf-postprocessor';
import { CopySessionAttributesInterceptor } from './copySessionAttributesInterceptor';
import { SkillEventHandlers } from './defaultHandlers/skillEventHandlers';
import { Handler } from './handler';
import { ResponseBuilder } from './responseBuilderShim';
import { ResponseHandlers } from './responseHandlers';
import { V1Handler } from './v1Handler';

export class Adapter extends EventEmitter {
    public readonly _event: RequestEnvelope;
    public readonly _context: any;
    public readonly _callback: (err: Error, result? : any) => void;
    public state: string;
    public appId: string;
    public response: ResponseEnvelope;
    public dynamoDBClient: DynamoDB;
    public dynamoDBTableName: string;
    public saveBeforeResponse: boolean;
    public i18n: i18n;
    public locale: string;
    public resources: object;  /* eslint-disable-line @typescript-eslint/ban-types */
    public promiseResolve: (value? : Response | PromiseLike<Response>) => void;
    private v2RequestHandlers: RequestHandler[];

    constructor(event: RequestEnvelope, context: any, callback? : (err: Error, result? : any) => void) {
        super();

        if (!event.session) {
            event.session = {
                new : undefined,
                sessionId : undefined,
                user : undefined,
                application : undefined,
                attributes : {},
            };
        } else if (!event.session.attributes) {
            event.session.attributes = {};
        }

        this.setMaxListeners(Infinity);

        this._event = event;
        this._context = context;
        this._callback = callback;
        this.response = {
            version : '1.0',
            response : {},
        };
        this.dynamoDBClient = new DynamoDB({
            apiVersion: 'latest',
        });
        this.saveBeforeResponse = false;
        this.v2RequestHandlers = [];
        this.i18n = i18n;
        this.registerHandlers(SkillEventHandlers);
        this.registerHandlers(ResponseHandlers);
    }

    public registerHandlers(...v1Handlers: V1Handler[]): void {
        for (const handler of v1Handlers) {
            if (!IsObject(handler)) {
                throw createAskSdkError(this.constructor.name, `Argument #${handler.constructor.name} was not an Object`);
            }
            const eventNames = Object.keys(handler);
            for (const eventName of eventNames) {
                if (typeof(handler[eventName]) !== 'function') {
                    throw createAskSdkError(this.constructor.name, `Event handler for '${eventName}' was not a function`);
                }

                let targetEventName = eventName;

                if (handler[StateString as any]) {
                    targetEventName += handler[StateString as any];
                }

                const handlerContext = {
                    on: this.on.bind(this),
                    emit: this.emit.bind(this),
                    emitWithState: EmitWithState.bind(this),
                    handler: this,
                    i18n: this.i18n,
                    locale: this.locale,
                    t : (...argArray: string[]): string => this.i18n.t.apply(this.i18n, argArray),
                    event: this._event,
                    attributes : this._event.session.attributes,
                    context: this._context,
                    callback : this._callback,
                    name: targetEventName,
                    isOverridden:  IsOverridden.bind(this, targetEventName),
                    response: new ResponseBuilder(this),
                };
                this.on(targetEventName, handler[eventName].bind(handlerContext));
            }
        }
    }

    public registerV2Handlers(...requestHandlers: RequestHandler[]): void {
        this.v2RequestHandlers = [...this.v2RequestHandlers, ...requestHandlers];
    }

    public execute(): void {
        // tslint:disable-next-line
        this.locale = this._event.request['locale'] ? this._event.request['locale'] : 'en-US';
        if (this.resources) {
            this.i18n.use(sprintf).init({
                lng : this.locale,
                overloadTranslationOptionHandler: sprintf.overloadTranslationOptionHandler,
                resources : this.resources,
                returnObjects : true,
            }, (err) => {
                if (err) {
                    throw createAskSdkError(this.constructor.name, `Error initializing i19next: ${ err}`);
                }
                ValidateRequest.call(this);
            });
        } else {
            ValidateRequest.call(this);
        }
    }
}

export const StateString = Symbol('StateString');

export function CreateStateHandler(state: string, requestHandler: V1Handler): V1Handler {
    if (!requestHandler) {
        requestHandler = {};
    }

    Object.defineProperty(requestHandler, StateString, {
        value : state || '',
        enumerable : false,
    });

    return requestHandler;
}

let dynamoDbPersistenceAdapter: DynamoDbPersistenceAdapter;

function ValidateRequest(): void {
    let requestAppId = '';
    if (this._event.context) {
        requestAppId = this._event.context.System.application.applicationId;
    } else if (this._event.session) {
        requestAppId = this._event.session.application.applicationId;
    }

    if (!this.appId) {
        console.log('Warning: Application ID is not set');
    }
    try {
        if (this.appId && (requestAppId !== this.appId)) {
            console.log(`The applicationIds don't match: ${requestAppId} and ${this.appId}`);
            const error = createAskSdkError('In validating request', `Invalid ApplicationId: ${ this.appId}`);
            if (typeof this.callback === 'undefined') {
                this._context.fail(error);
            } else {
                this._callback(error);
            }
        }

        if (this.dynamoDBTableName && (!this._event.session.sessionId || this._event.session.new)) {
            if (!dynamoDbPersistenceAdapter) {
                dynamoDbPersistenceAdapter = new DynamoDbPersistenceAdapter({
                    createTable : true,
                    dynamoDBClient : this.dynamoDBClient,
                    partitionKeyName : 'userId',
                    attributesName : 'mapAttr',
                    tableName : this.dynamoDBTableName,
                });
            }

            dynamoDbPersistenceAdapter.getAttributes(this._event)
                .then((data) => {
                    Object.assign(this._event.session.attributes, data);
                    EmitEvent.call(this);
                })
                .catch((error) => {
                    const err = createAskSdkError(this.constructor.name, `Error fetching user state: ${ error}`);
                    if (typeof this._callback === 'undefined') {
                        return this._context.fail(err);
                    } else {
                        return this._callback(err);
                    }
                });
        } else {
            EmitEvent.call(this);
        }
    } catch (e) {
        console.log(`Unexpected exception '${e}':\n${e.stack}`);
        if (typeof this._callback === 'undefined') {
            return this._context.fail(e);
        } else {
            return this._callback(e);
        }
    }
}

function EmitEvent(): void {
    const packageInfo = require('../package.json');
    this.state = this._event.session.attributes.STATE || '';

    SkillBuilders.custom()
        .addRequestHandlers(new Handler(this), ...this.v2RequestHandlers)
        .addRequestInterceptors(new CopySessionAttributesInterceptor())
        .withPersistenceAdapter(dynamoDbPersistenceAdapter)
        .withApiClient(new DefaultApiClient())
        .withCustomUserAgent(`${packageInfo.name}/${packageInfo.version}`)
        .create()
        .invoke(this._event, this._context)
        .then((responseEnvelope) => {
            if (typeof this._callback === 'undefined') {
                this._context.succeed(responseEnvelope);
            } else {
                this._callback(null, responseEnvelope);
            }
        })
        .catch((err) => {
            if (typeof this._callback === 'undefined') {
                this._context.fail(err);
            } else {
                this._callback(err);
            }
        });
}

function EmitWithState(): void {
    if (arguments.length === 0) {
        throw createAskSdkError(this.constructor.name, 'EmitWithState called without arguments');
    }
    arguments[0] = arguments[0] + this.state;

    if (this.listenerCount(arguments[0]) < 1) {
        arguments[0] = `Unhandled${ this.state}`;
    }

    if (this.listenerCount(arguments[0]) < 1) {
        throw createAskSdkError(this.constructor.name, `No 'Unhandled' function defined for event: ${arguments[0]}`);
    }

    this.emit.apply(this, arguments);
}

function IsOverridden(name: string): boolean {
    return this.listenerCount(name) > 1;
}

function IsObject(obj: any): boolean {
    return (!!obj) && (obj.constructor === Object);
}

process.on('uncaughtException', function(err) {
    console.log(`Uncaught exception: ${err}\n${err.stack}`);
    throw err;
});


text:
//This file is part of Myoddweb.Piger.
//
//    Myoddweb.Piger is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    Myoddweb.Piger is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with Myoddweb.Piger.  If not, see<https://www.gnu.org/licenses/gpl-3.0.en.html>.
#include "stdafx.h"
#include "Application.h"
#include "../api/VirtualMachines.h"
#include "ActionBye.h"
#include "ActionLoad.h"
#include "ActionVersion.h"
#include "Actions.h"
#include "MessagesHandler.h"
#include "IpcListener.h"
#include "ActionsImmediate.h"
#include "ApplicationTray.h"
#include <functional>

Application::Application() :
  IApplication(),
  _lastForegroundWindow(nullptr),
  _messagesHandler(nullptr),
  _possibleActions(nullptr),
  _ipcListener(nullptr),
  _tray(nullptr),
  _virtualMachines(nullptr),
  _dlg(nullptr),
  _hookWnd(nullptr),
  _activeActionsRunner(nullptr),
  _startActions(nullptr),
  _messages( nullptr )
{
}

Application::~Application()
{
  // we have to destroy everything.
  DestroyForRestart();
  DestroyBase();
}

/**
 * \brief close the main application
 */
void Application::Close()
{
  _messages->Post(L"Close");
}

void Application::OnClose()
{
  // log that we are closing down
  myodd::log::LogMessage(_T("Piger is shutting down."));

  // prepare for closing
  PrepareForClose();

  // close it
  _messages->Close();
}

/**
 * \brief reload all the actions and re-create the base/actions/machines etc...
 */
void Application::Restart()
{
  _messages->Post(L"Restart");
}

void Application::OnRestart()
{
  // log that we are restarting
  myodd::log::LogMessage(_T("Piger is restarting."));

  // prepare to close.
  PrepareForClose();

  // remove the old stuff
  // and recreate it right away
  DestroyForRestart();
  CreateForRestart();

  // and then show the new start message.
  ShowStart();
}

/**
 * \brief reload all the actions and re-create the base/actions/machines etc...
 */
void Application::Version()
{
  _messages->Post(L"Version");
}

void Application::OnVersion()
{
  // Show the version
  ShowVersion();
}

void Application::Show()
{
  // show the dialog box and wait for it to complete.

  // create everything
  CreateBase();
  CreateForRestart();

  // sanity check
  assert(_dlg != nullptr);

  // show the dialog box
  _dlg->Create();

  // show the start messages.
  ShowStart();

  // then wait.
  _messages->Wait();

  // we are now closed, we can destroy everything
  DestroyForRestart();
  DestroyBase();
}

/**
 * \brief called before we destroy the variable to wait for certain actions/machines to complete
 *        we will send them messages to close/stop what they are doing
 *        so we do not destroy anything while threads are still running.
 */
void Application::PrepareForClose()
{
  // stop and destroy all the running virtual machines.
  // we need to do that now as we are about to go away
  //
  CloseAllVirtualMachines();

  // for them to finish properly
  WaitForHandlersToComplete();

  // call the end actions to run
  ShowClose();

  // wait all the active windows.
  // those are the ones created by the end Action list.
  WaitForHandlersToComplete();
}

/**
 * \brief create variables that are destroyed on application reload.
 */
void Application::DestroyForRestart()
{
  // the start actions
  delete _startActions;
  _startActions = nullptr;

  // hook window
  delete _hookWnd;
  _hookWnd = nullptr;

  // remove the actions
  // we are about to close, we are no longer monitoring anything
  delete _possibleActions;
  _possibleActions = nullptr;

  // stop the virtuall machines
  delete _virtualMachines;
  _virtualMachines = nullptr;
}

/**
 * \brief destroy all the variables that are unique to the application
 *        they are, (normally), only created once.
 */
void Application::DestroyBase()
{
  // the running active actions
  delete _activeActionsRunner;
  _activeActionsRunner = nullptr;

  // stop all the message handling
  delete _messagesHandler;
  _messagesHandler = nullptr;

  delete _ipcListener;
  _ipcListener = nullptr;

  delete _tray;
  _tray = nullptr;

  delete _dlg;
  _dlg = nullptr;

  delete _messages;
  _messages = nullptr;
}

#pragma region Create variables
void Application::CreateBase()
{
  // destroy the old one
  DestroyBase();

  // create the messages handler
  CreateMessages();

  // create the system tray
  CreateTray();

  // the actions runner
  CreateActiveActionsRunner();

  // create the messages handler.
  CreateMessageHandler();

  // create the messages/listener.
  CreateIpcListener();

  // create the actual dicali.
  _dlg = new ActionMonitorDlg(*_tray);
}

void Application::CreateForRestart()
{
  // create the possible actions
  CreateActionsList();

  // create the virtual machines
  CreateVirtualMachines();

  // sanity checks
  assert(_possibleActions != nullptr);
  assert(_ipcListener != nullptr);
  assert(_tray != nullptr);
  assert(_dlg != nullptr);

  // the hook window, we need dlg, so we have to this last.
  // also we do not want to fire the hook before needed.
  CreateHookWindow();
}

void Application::CreateHookWindow()
{
  delete _hookWnd;

  // sanity checks
  assert(_dlg != nullptr);
  assert(_possibleActions != nullptr);
  assert(_virtualMachines != nullptr);

  _hookWnd = new HookWnd(*this, *_dlg, *_possibleActions, *_virtualMachines);
  _hookWnd->Create();
}

void Application::CreateMessages()
{
  delete _messages;
  _messages = new myodd::threads::Messages();
  _messages->AddFunction(std::bind(&Application::OnClose, this), L"Close");
  _messages->AddFunction(std::bind(&Application::OnRestart, this), L"Restart");
  _messages->AddFunction(std::bind(&Application::OnVersion, this), L"Version");
}

void Application::CreateTray()
{
  delete _tray;
  auto tray = new ApplicationTray();
  tray->SetApplication(this);

  // we can pass the owneship.
  _tray = tray;
}

void Application::CreateVirtualMachines()
{
  // sanity checks
  assert(_messagesHandler != nullptr);
  assert(_ipcListener != nullptr);

  // stop the virtuall machines
  delete _virtualMachines;
  _virtualMachines = new VirtualMachines(*this, *_messagesHandler, *_ipcListener);
}

/**
 * \brief the IPC messages handler from the virtual machines.
 */
void Application::CreateIpcListener()
{
  // remove the old one
  delete _ipcListener;

  // create a new one
  _ipcListener = new IpcListener();
  _ipcListener->Initialize( );
}

/**
 * \brief (Re)build the message handler
 */
void Application::CreateMessageHandler()
{
  //  remove the old one
  delete _messagesHandler;

  //  create a new one.
  _messagesHandler = new MessagesHandler();
}

/**
 * \brief (Re)build the active action runner.
 */
void Application::CreateActiveActionsRunner()
{
  delete _activeActionsRunner;
  _activeActionsRunner = new ActiveActionsRunner();
}

/**
 * \brief (Re)build a list of possible actions.
 */
void Application::CreateActionsList()
{
  //  remove the old one
  delete _possibleActions;

  //  create a new one.
  _possibleActions = new Actions( *this );

  //  parse the directory for all possible files.
  _possibleActions->Initialize();

  //TODO these really need to move out of here
  //  add the default commands
  _possibleActions->Add(new ActionBye(*this));
  _possibleActions->Add(new ActionLoad(*this));
  _possibleActions->Add(new ActionVersion(*this));
}
#pragma endregion

/**
 * \brief Close all the virtual machines.
 *        we send them all a message to end what they are doing
 *        or we detach from them all so we no longer can handle their requests.
 */
void Application::CloseAllVirtualMachines() const
{
  if (_virtualMachines == nullptr)
  {
    return;
  }
  _virtualMachines->Destroy();
}

/**
 * \brief Wait for all the active windows to complete.
 */
void Application::WaitForHandlersToComplete() const
{
  // wait for the Ipc windows.
  if (_ipcListener != nullptr)
  {
    _ipcListener->WaitForAllToComplete();
  }

  if (_messagesHandler != nullptr)
  {
    // wait for all the messages
    _messagesHandler->WaitForAllToComplete();
  }
}

#pragma region Show common messages
void Application::ShowClose()
{
  // do we have anything to show.
  if (_dlg == nullptr)
  {
    return;
  }

  // sanity check
  assert(_possibleActions != nullptr);
  assert(_virtualMachines != nullptr);

  // start the new ones
  auto endActions = new ActionsImmediate(*this, AM_DIRECTORY_OUT, *_possibleActions, *_virtualMachines);
  endActions->Initialize();
  endActions->WaitForAll();
  delete endActions;
  endActions = nullptr;
}

void Application::ShowStart()
{
  // sanity check
  assert(_possibleActions != nullptr);
  assert(_virtualMachines != nullptr);
  assert(_dlg != nullptr);

  if (_startActions != nullptr)
  {
    _startActions->WaitForAll();
    delete _startActions;
    _startActions = nullptr;
  }

  // start the new ones
  _startActions = new ActionsImmediate(*this, AM_DIRECTORY_IN, *_possibleActions, *_virtualMachines);
  _startActions->Initialize();

  // we do not want to wait for start messages
  // we will continue in case of long running stat processes.
  // it is bad to have blocking scripts anyway
  // rather have a script to call another process.
}

void Application::ShowVersion()
{
  myodd::files::Version ver;
  const auto strSay = myodd::strings::Format(_T("<b>Version : </b>%d.%d.%d.%d"),
    ver.GetFileVersionMajor(),
    ver.GetFileVersionMinor(),
    ver.GetFileVersionMaintenance(),
    ver.GetFileVersionBuild());

  assert(_messagesHandler != nullptr);
  _messagesHandler->Show(strSay.c_str(), 500, 3000);
}
#pragma endregion

/**
 * \brief Execute a file.
 *        We will expend all the environment variables as needed.
 * \param argv [0] the file path, [1] the arguments to launch with, (optional).
 * \param isPrivileged if we need administrator privilege to run this.
 * \param hProcess if this value is not nullptr, we will return the handle of the started process.
 *               it is then up to the calling application to close this handle when done with it...
 * \return bool true|false success or not.
 */
bool Application::Execute(const std::vector<std::wstring>& argv, const bool isPrivileged, HANDLE* hProcess) const
{
  // get the number of arguments.
  const auto argc = argv.size();

  // sanity check
  if (argc < 1 || argc > 2)
  {
    ASSERT(0); //  wrong number of arguments.
    return false;
  }

  LPTSTR argvModule = nullptr;
  LPTSTR argvCmd = nullptr;

  // get the module name, (what we are running).
  // Expand the values that might have been passed.
  if (!myodd::files::ExpandEnvironment(argv[0].c_str(), argvModule))
  {
    myodd::log::LogError(_T("Could not execute statement: Unable to expand command line '%s'"), argv[0].c_str());
    return false;
  }

  // But we might also have a command line item.
  if (2 == argc)
  {
    // Expand the values that might have been passed.
    if (!myodd::files::ExpandEnvironment(argv[1].c_str(), argvCmd))
    {
      myodd::log::LogError(_T("Could not execute statement: Unable to expand arguments '%s'"), argv[1].c_str());
      delete[] argvModule;
      return false;
    }
  }

  //
  // ShellExecuteEx
  // https://msdn.microsoft.com/en-us/library/windows/desktop/bb759784(v=vs.85).aspx
  //
  SHELLEXECUTEINFO sei = {};
  sei.cbSize = sizeof(sei);     // in, required, sizeof of this structure
  sei.fMask = SEE_MASK_DEFAULT; // in, SEE_MASK_XXX values
  sei.hwnd = nullptr;           // in, optional
  sei.lpFile = argvModule;      // in, either this value or lpIDList must be specified
  sei.lpParameters = argvCmd;   // in, optional
  sei.lpDirectory = nullptr;    // in, optional
  sei.nShow = SW_NORMAL;        // in, required
  //sei.hInstApp;               // out when SEE_MASK_NOCLOSEPROCESS is specified
  //sei.lpIDList;               // in, valid when SEE_MASK_IDLIST is specified, PCIDLIST_ABSOLUTE, for use with SEE_MASK_IDLIST & SEE_MASK_INVOKEIDLIST
  //sei.lpClass;                // in, valid when SEE_MASK_CLASSNAME is specified
  //sei.hkeyClass;              // in, valid when SEE_MASK_CLASSKEY is specified
  //sei.dwHotKey;               // in, valid when SEE_MASK_HOTKEY is specified
  if (isPrivileged == true && !myodd::os::IsElevated())
  {
    sei.lpVerb = _T("runas"); // in, optional when unspecified the default verb is choosen
  }
  else
  {
    //  launch as a normal file.
    sei.lpVerb = _T("open");  // in, optional when unspecified the default verb is choosen
  }

  // did the user pass a handle?
  // if they did then they want to take ownership of the process and close the handle.
  if (hProcess != nullptr)
  {
    sei.fMask = SEE_MASK_NOCLOSEPROCESS; // in, SEE_MASK_XXX values
  }

  // Assume error
  auto result = false;
  if (!ShellExecuteEx(&sei))
  {
    myodd::log::LogError(_T("Could not execute statement: could not execute '%s'"), argvModule);
    myodd::log::LogError(_T("Could not execute statement: Last error '%d'"), ::GetLastError());
  }
  else
  {
    result = true;
    if (hProcess != nullptr)
    {
      // return the handle.
      *hProcess = sei.hProcess;
    }
  }

  // clean up the expended variable.
  delete[] argvCmd;
  delete[] argvModule;

  // return what we found
  return result;
}

bool Application::AddAction(IAction* action)
{
  if( nullptr == _possibleActions )
  {
    return false;
  }
  return _possibleActions->Add(action);
}

bool Application::RemoveAction(const std::wstring& szText, const std::wstring& szPath) const
{
  if (nullptr == _possibleActions)
  {
    return false;
  }
  return _possibleActions->Remove(szText, szPath );
}

const IAction* Application::FindAction(unsigned int idx, const std::wstring& szText) const
{
  if (nullptr == _possibleActions)
  {
    return nullptr;
  }
  return _possibleActions->Find(szText, idx );
}

bool Application::ExecuteCurrentAction()
{
  if( nullptr == _possibleActions)
  {
    return false;
  }
  if( nullptr == _virtualMachines )
  {
    return false;
  }

  //  We use the Actions to find the actual command
  //  because either it is an exact match, (and it doesn't matter)
  //  or it is not an exact match and this is what we meant to use
  //
  //  so if the user enters 'goo french victories'
  //  we will use the first command 'google' with the arguments 'french victories'
  //
  //  we use getCommand in case the user has chosen number 1, 2 ... in the list of possible commands

  // if there is an active action, get it.
  const auto action = _possibleActions->GetCommand();
  if (nullptr == action)
  {
    return false;
  }

  try
  {
    const auto pWnd = GetLastForegroundWindow();
    const auto commandLine = _possibleActions->GetCommandLine();
    const auto activeAction = action->CreateActiveAction(*_virtualMachines, pWnd, commandLine, false);
    return ExecuteActiveAction(activeAction);
  }
  catch( ... )
  {
    return false;
  }
}

bool Application::ExecuteActiveAction( IActiveAction* action) const
{
  try
  {
    if( nullptr == _activeActionsRunner )
    {
      return false;
    }
    _activeActionsRunner->QueueAndExecute(action);
    return true;
  }
  catch (...)
  {
    return false;
  }
}

bool Application::IsActiveActionRunning(IActiveAction* action) const
{
  if (nullptr == _activeActionsRunner)
  {
    return false;
  }
  return _activeActionsRunner->IsActiveActionRunning( action);
}

void Application::SetLastForegroundWindow()
{
  _lastForegroundWindow = CWnd::GetForegroundWindow();
}

CWnd* Application::GetLastForegroundWindow() const
{
  return _lastForegroundWindow;
}


text:
import { Stat } from 'engine/enums';
import { Player } from 'engine/models';

import { getStatLevel, randomStatChance } from 'shared/stat';
import { sendMessage } from 'shared/chat';
import { delayFunction } from 'shared/util';
import { runAnim, stopAnim } from 'shared/anim';

import { Pickaxe, getPickaxe } from './pickaxe';

/**
 * @author Im Frizzy <skype:kfriz1998>
 * @author Frosty Teh Snowman <skype:travis.mccorkle>
 * @author Arthur <skype:arthur.behesnilian>
 * @author Kayla <skype:ashbysmith1996>
 * @author Sundays211
 * @since 05/11/2014
 */

export interface MiningAction {
	/**
	 * Minimum level required to perform the action
	 */
	levelReq: number;

	/**
	 * The chance, out of 255, to perform the action successfully at level 1.
	 * Note: This doesn't take into account modifiers (better hatchets, familiars, boosts, etc)
	 */
	baseChance: number;

	/**
	 * The chance, out of 255, to perform the action successfully at level 99.
	 * Note: This doesn't take into account modifiers (better hatchets, familiars, boosts, etc)
	 */
	maxChance: number;
}

export function runMiningAction(player: Player, action: MiningAction, onSuccess: () => void) {
	if (getStatLevel(player, Stat.MINING) < action.levelReq) {
		sendMessage(player, "You require a mining level of " + action.levelReq + "  to mine this rock.");
		return;
	}
	var pic = getPickaxe(player);//Find the highest pickaxe the player holds and can use
	if (!pic) {
		sendMessage(player, "You need a pickaxe to mine this rock.");
		return;
	}
	runAnim(player, pic.anim);
	delayFunction(player, pic.speed, process, true);

	function process() {
		if (checkSuccess(player, action, pic)) {
			stopAnim(player);
			onSuccess();
		} else {
			runAnim(player, pic.anim);
			delayFunction(player, pic.speed, process, true);
		}
	}
}

function checkSuccess(player: Player, action: MiningAction, pic: Pickaxe): boolean {
	const extraChance = pic.bonus;
	//TODO: Add modifiers here

	return randomStatChance(
		player,
		Stat.MINING,
		action.baseChance + extraChance,
		action.maxChance + extraChance
	);
}


text:
window.onload = function(){

    /*
        Tipo boolean
        - true
        - false
    */

    // Solo se ejecuta cuando la condicion es verdadera
    if(true){
        console.log("La condicion es verdadera, esto se imprime");
    }
    //
    if(false){
        console.log("La condicion es falsa, esto no se imprime");
    }

    /*
        Operadores Logicos
        - > (Mayor que)
        - < (Menor que)
        - || (o)
        - && (y)
        - == (igual)
        - === (igual)
        - != (diferente)
        - !== (diferente)
        - ! (no)
    */

    // Operadore logico: no
    if(!false)
    {
        console.log("La negacion de un false es un true, esto se imprime");
    }

    // Operador logico: Mayor y Menor que
    var numero_Uno = 23;
    var numero_Dos = 30;
    if(numero_Uno > numero_Dos)
    {
        console.log("Numero uno es mayor que numero dos");
    }
    if(numero_Uno < numero_Dos)
    {
        console.log("Numero uno es menor que numero dos");
    }

    // Operador logico: y
    if(numero_Uno && true){
        console.log("Operador logico: y. El numero uno existe y true");
    }
    if(numero_Uno && false){
        console.log("Operador logico: y. El numero uno existe y false");
    }

    // Operador logico: o
    if(numero_Uno || true){
        console.log("Operador logico: o. El numero uno existe o true");
    }
    if(numero_Uno || false){
        console.log("Operador logico: o. El numero uno existe o false");
    }
    if(false || false){
        console.log("Operador logico: o. False o false");
    }

    // Operador logico: Igual
    var numero_tres = 30;
    var numero_tres_Cadena = "30";
    // El operador ==, antes de comparar los valores los convierte a lo mismo
    // Es decir, antes de comparar, convierte la cadena es un numero
    if(numero_tres == numero_tres_Cadena)
    {
        console.log("Operador logico: Igual. 30 == '30' ");
    }
    // El operador ===, NO convierte el dato antes de comparar
    // Se recomienda esta comparacion:
    //      - Es para tener consistencia
    //      - Es mas rapido que ==
    if(numero_tres === numero_tres_Cadena)
    {
        console.log("Operador logico: Igual. 30 === '30' ");
    }

    // Operador logico: Diferente
    // El operador !=, antes de comparar los valores los convierte a lo mismo
    // Es decir, antes de comparar, convierte la cadena es un numero
    // En este caso los numeros no son diferentes
    if(numero_tres != numero_tres_Cadena)
    {
        console.log("Operador logico: Diferente. 30 != '30'");
    }
    // El operador !==, NO convierte el dato antes de comparar
    // En este caso los numeros si son diferentes
    if(numero_tres !== numero_tres_Cadena)
    {
        console.log("Operador logico: Diferente. 30 !== '30' ");
    }

    // If-else y else
    if(false)
    {

    }else if(false){

    }else{
        console.log("Solo se imprime si las condiciones de arriba son false");
    }

}


text:
use Observations
-- Station
Update
  Station
set
  Elevation = -Elevation
from
  Station
where
  (Code like 'ELW_%') and (Elevation > 0)
-- Station_Instrument
Update
  Station_Instrument
set
  Elevation = -Station_Instrument.Elevation
from
  Station_Instrument
  inner join Station
    on (Station_Instrument.StationID = Station.ID)
where
  (Code like 'ELW_%') and (Station_Instrument.Elevation > 0)
-- Instrument
Update
  Instrument
set
  Elevation = -Elevation
from
  Instrument
where
  (Code like 'ELW_%') and (Elevation > 0)
-- Instrument_Sensor
Update
  Instrument_Sensor
set
  Elevation = -Instrument_Sensor.Elevation
from
  Instrument_Sensor
  inner join Instrument
    on (Instrument_Sensor.InstrumentID = Instrument.ID)
  inner join Sensor
    on (Instrument_Sensor.SensorID = Sensor.ID)
where
  (Instrument.Code like 'ELW_%') and (Instrument_Sensor.Elevation > 0)
-- Sensor
Update
  Sensor
set
  Elevation = -Elevation
where
  (Code like 'ELW_%') and (Elevation > 0)
-- Observations
update
  Observation
set
  Elevation = -Observation.Elevation
from
  Observation
  inner join vObservationExpansion
    on (Observation.ID = vObservationExpansion.ID)
where
  (StationCode like 'ELW_%') and (Observation.Elevation > 0)


text:
package prompts

import (
	"fmt"

	"github.com/manifoldco/manifold-cli/errs"
	cModels "github.com/manifoldco/manifold-cli/generated/catalog/models"
	iModels "github.com/manifoldco/manifold-cli/generated/identity/models"
	mModels "github.com/manifoldco/manifold-cli/generated/marketplace/models"
	"github.com/manifoldco/manifold-cli/prompts/search"
	"github.com/manifoldco/manifold-cli/prompts/templates"
	"github.com/manifoldco/promptui"
)

// SelectProduct prompts the user to select a product from the given list.
func SelectProduct(list []*cModels.Product, name string) (int, string, error) {
	products := templates.Products(list)
	tpls := templates.TplProduct

	var idx int
	if name != "" {
		found := false
		for i, p := range products {
			if p.Name == name {
				idx = i
				found = true
				break
			}
		}

		if !found {
			msg := templates.PromptFailure("Product", name)
			fmt.Println(msg)
			return 0, "", errs.ErrProductNotFound
		}

		msg := templates.SelectSuccess(tpls, products[idx])
		fmt.Println(msg)
		return idx, name, nil
	}

	prompt := promptui.Select{
		Label:     "Select Product",
		Items:     products,
		Templates: tpls,
		Searcher:  search.ProductSearch(products),
	}

	return prompt.Run()
}

// SelectPlan prompts the user to select a plan from the given list.
func SelectPlan(list []*cModels.Plan, name string) (int, string, error) {
	plans := templates.Plans(list)
	tpls := templates.TplPlan

	var idx int
	if name != "" {
		found := false
		for i, p := range plans {
			if p.Name == name {
				idx = i
				found = true
				break
			}
		}

		if !found {
			msg := templates.PromptFailure("Plan", name)
			fmt.Println(msg)
			return 0, "", errs.ErrPlanNotFound
		}

		msg := templates.SelectSuccess(tpls, plans[idx])
		fmt.Println(msg)
		return idx, name, nil
	}

	prompt := promptui.Select{
		Label:     "Select Plan",
		Items:     plans,
		Templates: tpls,
		Searcher:  search.PlanSearch(plans),
	}

	return prompt.Run()
}

// SelectResource promps the user to select a provisioned resource from the given list
func SelectResource(list []*mModels.Resource, projects []*mModels.Project,
	name string) (int, string, error) {
	resources := templates.Resources(list, projects)
	tpls := templates.TplResource

	var idx int
	if name != "" {
		found := false
		for i, r := range resources {
			if r.Name == name {
				idx = i
				found = true
				break
			}
		}

		if !found {
			msg := templates.PromptFailure("Resource", name)
			fmt.Println(msg)
			return 0, "", errs.ErrResourceNotFound
		}

		msg := templates.SelectSuccess(tpls, resources[idx])
		fmt.Println(msg)

		return idx, name, nil
	}

	prompt := promptui.Select{
		Label:     "Select Resource",
		Items:     resources,
		Templates: tpls,
	}

	return prompt.Run()
}

// SelectRole prompts the user to select a role from the given list.
func SelectRole(roles []string) (string, error) {
	prompt := promptui.Select{
		Label: "Select Role",
		Items: roles,
	}
	_, role, err := prompt.Run()
	return role, err
}

// SelectRegion prompts the user to select a region from the given list.
func SelectRegion(list []*cModels.Region) (int, string, error) {
	regions := templates.Regions(list)
	tpls := templates.TplRegion

	// TODO: Build "auto" resolve into promptui in case of only one item
	if len(regions) == 1 {
		msg := templates.SelectSuccess(tpls, regions[0])
		fmt.Println(msg)

		return 0, string(regions[0].Name), nil
	}

	prompt := promptui.Select{
		Label:     "Select Region",
		Items:     regions,
		Templates: tpls,
		Searcher:  search.RegionSearch(regions),
	}

	return prompt.Run()
}

// SelectProject prompts the user to select a project from the given list.
func SelectProject(list []*mModels.Project, name string, emptyOption, showResult bool) (int, string, error) {
	projects := templates.Projects(list)
	tpls := templates.TplProject

	var idx int
	if name != "" {
		found := false
		for i, p := range projects {
			if p.Name == name {
				idx = i
				found = true
				break
			}
		}

		if !found {
			msg := templates.PromptFailure("Project", name)
			fmt.Println(msg)
			return 0, "", errs.ErrProjectNotFound
		}

		if showResult {
			msg := templates.SelectSuccess(tpls, projects[idx])
			fmt.Println(msg)
		}

		return idx, name, nil
	}

	if emptyOption {
		projects = append([]templates.Project{{Name: "No Project"}}, projects...)
	}

	prompt := promptui.Select{
		Label:     "Select Project",
		Items:     projects,
		Templates: tpls,
	}

	projectIdx, pname, err := prompt.Run()

	if emptyOption {
		return projectIdx - 1, pname, err
	}

	return projectIdx, pname, err
}

// SelectContext runs a SelectTeam for context purposes
func SelectContext(teams []*iModels.Team, name string, userTuple *[]string) (int, string, error) {
	return selectTeam(teams, "Switch To", name, userTuple)
}

// SelectTeam prompts the user to select a team from the given list. -1 as the first return value
// indicates no team has been selected
func SelectTeam(teams []*iModels.Team, name string, userTuple *[]string) (int, string, error) {
	return selectTeam(teams, "Select Team", name, userTuple)
}

func selectTeam(list []*iModels.Team, label, name string, userTuple *[]string) (int, string, error) {
	if label == "" {
		label = "Select Team"
	}

	teams := templates.Teams(list)
	tpls := templates.TplTeam
	tpls.Selected = fmt.Sprintf(tpls.Selected, label)

	var idx int
	if name != "" {
		found := false
		for i, t := range teams {
			if t.Name == name {
				idx = i
				found = true
				break
			}
		}

		if !found {
			msg := templates.PromptFailure("Team", name)
			fmt.Println(msg)
			return 0, "", errs.ErrTeamNotFound
		}

		msg := templates.SelectSuccess(tpls, teams[idx])
		fmt.Println(msg)

		return idx, name, nil
	}

	if userTuple != nil {
		u := *userTuple
		user := templates.Team{
			Name:  u[0],
			Title: u[1],
		}

		// treat user as a team for display purposes
		teams = append([]templates.Team{user}, teams...)
	}

	prompt := promptui.Select{
		Label:     label,
		Items:     teams,
		Templates: tpls,
	}

	teamIdx, tname, err := prompt.Run()

	if userTuple != nil {
		return teamIdx - 1, tname, err
	}

	return teamIdx, tname, err
}

func SelectCategory(list map[string][]*cModels.Product) (string, error) {
	categories := templates.Categories(list)

	prompt := promptui.Select{
		Label:     "Select Category",
		Items:     categories,
		Templates: templates.TplCategory,
	}

	idx, _, err := prompt.Run()
	if err != nil {
		return "", err
	}

	return categories[idx].Name, nil
}

// SelectProvider prompts the user to select a provider resource from the given
// list.
func SelectProvider(list []*cModels.Provider) (*cModels.Provider, error) {
	providers := templates.Providers(list)

	label := templates.Provider{Name: "All Providers"}
	providers = append([]templates.Provider{label}, providers...)

	prompt := promptui.Select{
		Label:     "Select Provider",
		Items:     providers,
		Templates: templates.TplProvider,
	}

	idx, _, err := prompt.Run()
	if err != nil {
		return nil, err
	}

	if idx == 0 {
		return nil, nil
	}

	return list[idx-1], nil
}

// SelectAPIToken prompts the user to choose from a list of tokens
func SelectAPIToken(tokens []*iModels.APIToken) (*iModels.APIToken, error) {
	var labels []string
	for _, t := range tokens {
		val := fmt.Sprintf("%s****%s", *t.Body.FirstFour, *t.Body.LastFour)
		labels = append(labels, fmt.Sprintf("%s - %s", val, *t.Body.Description))
	}

	prompt := promptui.Select{
		Label: "Select API token",
		Items: labels,
	}

	idx, _, err := prompt.Run()
	if err != nil {
		return nil, err
	}

	return tokens[idx], nil
}

// SelectCredential prompts the user to choose from a list of credentials
func SelectCredential(creds []*mModels.Credential) (*mModels.Credential, string, error) {
	var labels []string
	var keyNames []string
	var items []*mModels.Credential

	for _, c := range creds {
		for k := range c.Body.Values {
			value := k
			if c.Body.CustomNames != nil {
				if alias, ok := c.Body.CustomNames[k]; ok {
					value = fmt.Sprintf("%s (%s)", value, alias)
				}
			}
			keyNames = append(keyNames, k)
			labels = append(labels, value)
			items = append(items, c)
		}
	}

	prompt := promptui.Select{
		Label: "Select Credential",
		Items: labels,
	}

	idx, _, err := prompt.Run()
	if err != nil {
		return nil, "", err
	}

	return items[idx], keyNames[idx], nil
}

// SelectBillingProfileAction allows the user to define their next action
// when encountering a paid plan without stored payment information
func SelectBillingProfileAction() (string, error) {
	prompt := promptui.Select{
		Label: "Select Action",
		Items: []string{
			"Add credit card",
			"Select different plan",
			"Abort",
		},
	}

	_, value, err := prompt.Run()
	if err != nil {
		return "", err
	}
	return value, nil
}


text:
/***************************************************
  This is a library for the Adafruit RGB 16x2 LCD Shield
  Pick one up at the Adafruit shop!
  ---------> http://http://www.adafruit.com/products/714

  The shield uses I2C to communicate, 2 pins are required to
  interface
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include "Adafruit_RGBLCDShield.h"

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <Wire.h>
#ifdef __AVR__
 #define WIRE Wire
#else // Arduino Due
 #define WIRE Wire1
#endif

#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

// When the display powers up, it is configured as follows:
//
// 1. Display clear
// 2. Function set:
//    DL = 1; 8-bit interface data
//    N = 0; 1-line display
//    F = 0; 5x8 dot character font
// 3. Display on/off control:
//    D = 0; Display off
//    C = 0; Cursor off
//    B = 0; Blinking off
// 4. Entry mode set:
//    I/D = 1; Increment by 1
//    S = 0; No shift
//
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// RGBLCDShield constructor is called).

Adafruit_RGBLCDShield::Adafruit_RGBLCDShield() {
  _i2cAddr = 0;

  _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;

  // the I/O expander pinout
  _rs_pin = 15;
  _rw_pin = 14;
  _enable_pin = 13;
  _data_pins[0] = 12;  // really d4
  _data_pins[1] = 11;  // really d5
  _data_pins[2] = 10;  // really d6
  _data_pins[3] = 9;  // really d7

  _button_pins[0] = 0;
  _button_pins[1] = 1;
  _button_pins[2] = 2;
  _button_pins[3] = 3;
  _button_pins[4] = 4;
  // we can't begin() yet :(
}

void Adafruit_RGBLCDShield::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
			 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
			 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
{
  _rs_pin = rs;
  _rw_pin = rw;
  _enable_pin = enable;

  _data_pins[0] = d0;
  _data_pins[1] = d1;
  _data_pins[2] = d2;
  _data_pins[3] = d3;
  _data_pins[4] = d4;
  _data_pins[5] = d5;
  _data_pins[6] = d6;
  _data_pins[7] = d7;

  _i2cAddr = 255;

  _pinMode(_rs_pin, OUTPUT);
  // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin#
  if (_rw_pin != 255) {
    _pinMode(_rw_pin, OUTPUT);
  }
  _pinMode(_enable_pin, OUTPUT);

  if (fourbitmode)
    _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
  else
    _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;

  begin(16, 1);
}

void Adafruit_RGBLCDShield::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
  // check if i2c
  if (_i2cAddr != 255) {
    //_i2c.begin(_i2cAddr);
    WIRE.begin();
    _i2c.begin();

    _i2c.pinMode(8, OUTPUT);
    _i2c.pinMode(6, OUTPUT);
    _i2c.pinMode(7, OUTPUT);
    setBacklight(0x7);

    if (_rw_pin)
      _i2c.pinMode(_rw_pin, OUTPUT);

    _i2c.pinMode(_rs_pin, OUTPUT);
    _i2c.pinMode(_enable_pin, OUTPUT);
    for (uint8_t i=0; i<4; i++)
      _i2c.pinMode(_data_pins[i], OUTPUT);

    for (uint8_t i=0; i<5; i++) {
      _i2c.pinMode(_button_pins[i], INPUT);
      _i2c.pullUp(_button_pins[i], 1);
    }
  }

  if (lines > 1) {
    _displayfunction |= LCD_2LINE;
  }
  _numlines = lines;
  _currline = 0;

  // for some 1 line displays you can select a 10 pixel high font
  if ((dotsize != 0) && (lines == 1)) {
    _displayfunction |= LCD_5x10DOTS;
  }

  // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
  // according to datasheet, we need at least 40ms after power rises above 2.7V
  // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
  delayMicroseconds(50000);
  // Now we pull both RS and R/W low to begin commands
  _digitalWrite(_rs_pin, LOW);
  _digitalWrite(_enable_pin, LOW);
  if (_rw_pin != 255) {
    _digitalWrite(_rw_pin, LOW);
  }

  //put the LCD into 4 bit or 8 bit mode
  if (! (_displayfunction & LCD_8BITMODE)) {
    // this is according to the hitachi HD44780 datasheet
    // figure 24, pg 46

    // we start in 8bit mode, try to set 4 bit mode
    write4bits(0x03);
    delayMicroseconds(4500); // wait min 4.1ms

    // second try
    write4bits(0x03);
    delayMicroseconds(4500); // wait min 4.1ms

    // third go!
    write4bits(0x03);
    delayMicroseconds(150);

    // finally, set to 8-bit interface
    write4bits(0x02);
  } else {
    // this is according to the hitachi HD44780 datasheet
    // page 45 figure 23

    // Send function set command sequence
    command(LCD_FUNCTIONSET | _displayfunction);
    delayMicroseconds(4500);  // wait more than 4.1ms

    // second try
    command(LCD_FUNCTIONSET | _displayfunction);
    delayMicroseconds(150);

    // third go
    command(LCD_FUNCTIONSET | _displayfunction);
  }

  // finally, set # lines, font size, etc.
  command(LCD_FUNCTIONSET | _displayfunction);

  // turn the display on with no cursor or blinking default
  _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
  display();

  // clear it off
  clear();

  // Initialize to default text direction (for romance languages)
  _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
  // set the entry mode
  command(LCD_ENTRYMODESET | _displaymode);

}

/********** high level commands, for the user! */
void Adafruit_RGBLCDShield::clear()
{
  command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero
  delayMicroseconds(2000);  // this command takes a long time!
}

void Adafruit_RGBLCDShield::home()
{
  command(LCD_RETURNHOME);  // set cursor position to zero
  delayMicroseconds(2000);  // this command takes a long time!
}

void Adafruit_RGBLCDShield::setCursor(uint8_t col, uint8_t row)
{
  int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
  if ( row > _numlines ) {
    row = _numlines-1;    // we count rows starting w/0
  }

  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}

// Turn the display on/off (quickly)
void Adafruit_RGBLCDShield::noDisplay() {
  _displaycontrol &= ~LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void Adafruit_RGBLCDShield::display() {
  _displaycontrol |= LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// Turns the underline cursor on/off
void Adafruit_RGBLCDShield::noCursor() {
  _displaycontrol &= ~LCD_CURSORON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void Adafruit_RGBLCDShield::cursor() {
  _displaycontrol |= LCD_CURSORON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// Turn on and off the blinking cursor
void Adafruit_RGBLCDShield::noBlink() {
  _displaycontrol &= ~LCD_BLINKON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void Adafruit_RGBLCDShield::blink() {
  _displaycontrol |= LCD_BLINKON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// These commands scroll the display without changing the RAM
void Adafruit_RGBLCDShield::scrollDisplayLeft(void) {
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
}
void Adafruit_RGBLCDShield::scrollDisplayRight(void) {
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
}

// This is for text that flows Left to Right
void Adafruit_RGBLCDShield::leftToRight(void) {
  _displaymode |= LCD_ENTRYLEFT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This is for text that flows Right to Left
void Adafruit_RGBLCDShield::rightToLeft(void) {
  _displaymode &= ~LCD_ENTRYLEFT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This will 'right justify' text from the cursor
void Adafruit_RGBLCDShield::autoscroll(void) {
  _displaymode |= LCD_ENTRYSHIFTINCREMENT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This will 'left justify' text from the cursor
void Adafruit_RGBLCDShield::noAutoscroll(void) {
  _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// Allows us to fill the first 8 CGRAM locations
// with custom characters
void Adafruit_RGBLCDShield::createChar(uint8_t location, uint8_t charmap[]) {
  location &= 0x7; // we only have 8 locations 0-7
  command(LCD_SETCGRAMADDR | (location << 3));
  for (int i=0; i<8; i++) {
    write(charmap[i]);
  }
  command(LCD_SETDDRAMADDR);  // unfortunately resets the location to 0,0
}

/*********** mid level commands, for sending data/cmds */

inline void Adafruit_RGBLCDShield::command(uint8_t value) {
  send(value, LOW);
}

#if ARDUINO >= 100
inline size_t Adafruit_RGBLCDShield::write(uint8_t value) {
  send(value, HIGH);
  return 1;
}
#else
inline void Adafruit_RGBLCDShield::write(uint8_t value) {
  send(value, HIGH);
}
#endif

/************ low level data pushing commands **********/

// little wrapper for i/o writes
void  Adafruit_RGBLCDShield::_digitalWrite(uint8_t p, uint8_t d) {
  if (_i2cAddr != 255) {
    // an i2c command
    _i2c.digitalWrite(p, d);
  } else {
    // straightup IO
    digitalWrite(p, d);
  }
}

// Allows to set the backlight, if the LCD backpack is used
void Adafruit_RGBLCDShield::setBacklight(uint8_t status) {
  // check if i2c or SPI
  _i2c.digitalWrite(8, ~(status >> 2) & 0x1);
  _i2c.digitalWrite(7, ~(status >> 1) & 0x1);
  _i2c.digitalWrite(6, ~status & 0x1);
}

// little wrapper for i/o directions
void  Adafruit_RGBLCDShield::_pinMode(uint8_t p, uint8_t d) {
  if (_i2cAddr != 255) {
    // an i2c command
    _i2c.pinMode(p, d);
  } else {
    // straightup IO
    pinMode(p, d);
  }
}

// write either command or data, with automatic 4/8-bit selection
void Adafruit_RGBLCDShield::send(uint8_t value, uint8_t mode) {
  _digitalWrite(_rs_pin, mode);

  // if there is a RW pin indicated, set it low to Write
  if (_rw_pin != 255) {
    _digitalWrite(_rw_pin, LOW);
  }

  if (_displayfunction & LCD_8BITMODE) {
    write8bits(value);
  } else {
    write4bits(value>>4);
    write4bits(value);
  }
}

void Adafruit_RGBLCDShield::pulseEnable(void) {
  _digitalWrite(_enable_pin, LOW);
  delayMicroseconds(1);
  _digitalWrite(_enable_pin, HIGH);
  delayMicroseconds(1);    // enable pulse must be >450ns
  _digitalWrite(_enable_pin, LOW);
  delayMicroseconds(100);   // commands need > 37us to settle
}

void Adafruit_RGBLCDShield::write4bits(uint8_t value) {
  if (_i2cAddr != 255) {
    uint16_t out = 0;

    out = _i2c.readGPIOAB();

    // speed up for i2c since its sluggish
    for (int i = 0; i < 4; i++) {
      out &= ~(1 << _data_pins[i]);
      out |= ((value >> i) & 0x1) << _data_pins[i];
    }

    // make sure enable is low
    out &= ~(1 << _enable_pin);

    _i2c.writeGPIOAB(out);

    // pulse enable
    delayMicroseconds(1);
    out |= (1 << _enable_pin);
    _i2c.writeGPIOAB(out);
    delayMicroseconds(1);
    out &= ~(1 << _enable_pin);
    _i2c.writeGPIOAB(out);
    delayMicroseconds(100);

  } else {
    for (int i = 0; i < 4; i++) {
     _pinMode(_data_pins[i], OUTPUT);
     _digitalWrite(_data_pins[i], (value >> i) & 0x01);
    }
    pulseEnable();
  }
}

void Adafruit_RGBLCDShield::write8bits(uint8_t value) {
  for (int i = 0; i < 8; i++) {
    _pinMode(_data_pins[i], OUTPUT);
    _digitalWrite(_data_pins[i], (value >> i) & 0x01);
  }

  pulseEnable();
}

uint8_t Adafruit_RGBLCDShield::readButtons(void) {
  uint8_t reply = 0x1F;

  for (uint8_t i=0; i<5; i++) {
    reply &= ~((_i2c.digitalRead(_button_pins[i])) << i);
  }
  return reply;
}