text:
#include <string>
#include "base/os.h"
#if defined(__linux__)
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/genetlink.h>
#include <linux/sockios.h>
#elif defined(__FreeBSD__)
#include "vr_os.h"
#endif
#include <sys/socket.h>

#include <boost/bind.hpp>

#include <base/logging.h>
#include <db/db.h>
#include <db/db_entry.h>
#include <db/db_table.h>
#include <db/db_table_partition.h>

#include "ksync_index.h"
#include "ksync_entry.h"
#include "ksync_object.h"
#include "ksync_sock.h"
#include "ksync_sock_user.h"
#include "ksync_types.h"

#include "nl_util.h"
#include "udp_util.h"
#include "vr_genetlink.h"
#include "vr_types.h"

using namespace boost::asio;

/* Note SO_RCVBUFFORCE is supported only for linux version 2.6.14 and above */
typedef boost::asio::detail::socket_option::integer<SOL_SOCKET,
        SO_RCVBUFFORCE> ReceiveBuffForceSize;

int KSyncSock::vnsw_netlink_family_id_;
AgentSandeshContext *KSyncSock::agent_sandesh_ctx_[kRxWorkQueueCount];
std::auto_ptr<KSyncSock> KSyncSock::sock_;
pid_t KSyncSock::pid_;
tbb::atomic<bool> KSyncSock::shutdown_;

// Name of task used in KSync Response work-queues
const char* IoContext::io_wq_names[IoContext::MAX_WORK_QUEUES] =
                                                {
                                                    "Agent::Uve",
                                                    "Agent::KSync"
                                                };

static uint32_t IoVectorLength(KSyncBufferList *iovec) {
    KSyncBufferList::iterator it = iovec->begin();
    int offset = 0;
    while (it != iovec->end()) {
        offset +=  boost::asio::buffer_size(*it);
        it++;
    }
    return offset;
}

// Copy data from io-vector to a buffer
static uint32_t IoVectorToData(char *data, KSyncBufferList *iovec) {
    KSyncBufferList::iterator it = iovec->begin();
    int offset = 0;
    while (it != iovec->end()) {
        unsigned char *buf = boost::asio::buffer_cast<unsigned char *>(*it);
        memcpy(data + offset, buf, boost::asio::buffer_size(*it));
        offset +=  boost::asio::buffer_size(*it);
        it++;
    }
    return offset;
}
/////////////////////////////////////////////////////////////////////////////
// Netlink utilities
/////////////////////////////////////////////////////////////////////////////
static uint32_t GetNetlinkSeqno(char *data) {
    struct nlmsghdr *nlh = (struct nlmsghdr *)data;
    return nlh->nlmsg_seq;
}

static bool NetlinkMsgDone(char *data) {
    struct nlmsghdr *nlh = (struct nlmsghdr *)data;
    return ((nlh->nlmsg_flags & NLM_F_MULTI) != 0);
}

// Common validation for netlink messages
static bool ValidateNetlink(char *data) {
    struct nlmsghdr *nlh = (struct nlmsghdr *)data;
    if (nlh->nlmsg_type == NLMSG_ERROR) {
        LOG(ERROR, "Netlink error for seqno " << nlh->nlmsg_seq << " len "
            << nlh->nlmsg_len);
        assert(0);
        return false;
    }

    if (nlh->nlmsg_len > KSyncSock::kBufLen) {
        LOG(ERROR, "Length of " << nlh->nlmsg_len << " is more than expected "
            "length of " << KSyncSock::kBufLen);
        assert(0);
        return false;
    }

    if (nlh->nlmsg_type == NLMSG_DONE) {
        return true;
    }

    // Sanity checks for generic-netlink message
    if (nlh->nlmsg_type != KSyncSock::GetNetlinkFamilyId()) {
        LOG(ERROR, "Netlink unknown message type : " << nlh->nlmsg_type);
        assert(0);
        return false;
    }

    struct genlmsghdr *genlh = (struct genlmsghdr *) (data + NLMSG_HDRLEN);
    if (genlh->cmd != SANDESH_REQUEST) {
        LOG(ERROR, "Unknown generic netlink cmd : " << genlh->cmd);
        assert(0);
        return false;
    }

    struct nlattr * attr = (struct nlattr *)(data + NLMSG_HDRLEN
                                             + GENL_HDRLEN);
    if (attr->nla_type != NL_ATTR_VR_MESSAGE_PROTOCOL) {
        LOG(ERROR, "Unknown generic netlink TLV type : " << attr->nla_type);
        assert(0);
        return false;
    }

    return true;
}

static void GetNetlinkPayload(char *data, char **buf, uint32_t *buf_len) {
    struct nlmsghdr *nlh = (struct nlmsghdr *)data;
    int len = 0;
    if (nlh->nlmsg_type == NLMSG_DONE) {
        len = NLMSG_HDRLEN;
    } else {
        len = NLMSG_HDRLEN + GENL_HDRLEN + NLA_HDRLEN;
    }

    *buf = data + len;
    *buf_len = nlh->nlmsg_len - len;
}

static void InitNetlink(nl_client *client) {
    nl_init_generic_client_req(client, KSyncSock::GetNetlinkFamilyId());
    unsigned char *nl_buf;
    uint32_t nl_buf_len;
    assert(nl_build_header(client, &nl_buf, &nl_buf_len) >= 0);
}

static void ResetNetlink(nl_client *client) {
    unsigned char *nl_buf;
    uint32_t nl_buf_len;
    client->cl_buf_offset = 0;
    nl_build_header(client, &nl_buf, &nl_buf_len);
}

static void UpdateNetlink(nl_client *client, uint32_t len, uint32_t seq_no) {
    nl_update_header(client, len);
    struct nlmsghdr *nlh = (struct nlmsghdr *)client->cl_buf;
    nlh->nlmsg_pid = KSyncSock::GetPid();
    nlh->nlmsg_seq = seq_no;
}

static void DecodeSandeshMessages(char *buf, uint32_t buf_len,
                                  SandeshContext *sandesh_context,
                                  uint32_t alignment) {
    while (buf_len > (alignment - 1)) {
        int error;
        int decode_len = Sandesh::ReceiveBinaryMsgOne((uint8_t *)buf, buf_len,
                                                      &error, sandesh_context);
        if (decode_len < 0) {
            LOG(DEBUG, "Incorrect decode len " << decode_len);
            break;
        }
        buf += decode_len;
        buf_len -= decode_len;
    }
}

/////////////////////////////////////////////////////////////////////////////
// KSyncSock routines
/////////////////////////////////////////////////////////////////////////////
KSyncSock::KSyncSock() :
    nl_client_(NULL), wait_tree_(), send_queue_(this),
    max_bulk_msg_count_(kMaxBulkMsgCount), max_bulk_buf_size_(kMaxBulkMsgSize),
    bulk_seq_no_(kInvalidBulkSeqNo), bulk_buf_size_(0), bulk_msg_count_(0),
    rx_buff_(NULL), read_inline_(true), bulk_msg_context_(NULL),
    ksync_bulk_sandesh_context_(), uve_bulk_sandesh_context_(),
    tx_count_(0), ack_count_(0), err_count_(0) {
    TaskScheduler *scheduler = TaskScheduler::GetInstance();

    uint32_t uve_task_id =
        scheduler->GetTaskId(IoContext::io_wq_names[IoContext::IOC_UVE]);
    uint32_t ksync_task_id =
        scheduler->GetTaskId(IoContext::io_wq_names[IoContext::IOC_KSYNC]);
    for(uint32_t i = 0; i < kRxWorkQueueCount; i++) {
        ksync_rx_queue[i] = AllocQueue(ksync_bulk_sandesh_context_,
                                       ksync_task_id, i, "KSync Receive Queue");
        uve_rx_queue[i] = AllocQueue(uve_bulk_sandesh_context_,
                                     uve_task_id, i, "KSync UVE Receive Queue");
    }

    nl_client_ = (nl_client *)malloc(sizeof(nl_client));
    bzero(nl_client_, sizeof(nl_client));
    rx_buff_ = NULL;
    seqno_ = 0;
    uve_seqno_ = 0;
}

KSyncSock::~KSyncSock() {
    assert(wait_tree_.size() == 0);

    if (rx_buff_) {
        delete [] rx_buff_;
        rx_buff_ = NULL;
    }

    for(int i = 0; i < kRxWorkQueueCount; i++) {
        ksync_rx_queue[i]->Shutdown();
        delete ksync_rx_queue[i];

        uve_rx_queue[i]->Shutdown();
        delete uve_rx_queue[i];
    }

    if (nl_client_->cl_buf) {
        free(nl_client_->cl_buf);
    }
    free(nl_client_);
}

void KSyncSock::Shutdown() {
    shutdown_ = true;
    sock_->send_queue_.Shutdown();
    sock_.release();
}

void KSyncSock::Init(bool use_work_queue, const std::string &cpu_pin_policy) {
    sock_->send_queue_.Init(use_work_queue, cpu_pin_policy);
    pid_ = getpid();
    shutdown_ = false;
}

KSyncSock::KSyncReceiveQueue *KSyncSock::AllocQueue
(KSyncBulkSandeshContext ctxt[], uint32_t task_id, uint32_t instance,
 const char *name) {
    KSyncReceiveQueue *queue;
    queue = new KSyncReceiveQueue
        (task_id, instance, boost::bind(&KSyncSock::ProcessKernelData, this,
                                        &ctxt[instance], _1));
    char tmp[128];
    sprintf(tmp, "%s-%d", name, instance);
    queue->set_name(tmp);
    return queue;
}

void KSyncSock::SetMeasureQueueDelay(bool val) {
    sock_->send_queue_.set_measure_busy_time(val);
    for (int i = 0; i < kRxWorkQueueCount; i++) {
        ksync_rx_queue[i]->set_measure_busy_time(val);
    }
}

void KSyncSock::Start(bool read_inline) {
    sock_->read_inline_ = read_inline;
    if (sock_->read_inline_) {
        return;
    }
    sock_->rx_buff_ = new char[kBufLen];
    sock_->AsyncReceive(boost::asio::buffer(sock_->rx_buff_, kBufLen),
                        boost::bind(&KSyncSock::ReadHandler, sock_.get(),
                                    placeholders::error,
                                    placeholders::bytes_transferred));
}

void KSyncSock::SetSockTableEntry(KSyncSock *sock) {
    assert(sock_.get() == NULL);
    sock_.reset(sock);
}

void KSyncSock::SetNetlinkFamilyId(int id) {
    vnsw_netlink_family_id_ = id;
    InitNetlink(sock_->nl_client_);
}

uint32_t KSyncSock::WaitTreeSize() const {
    return wait_tree_.size();
}

void KSyncSock::SetSeqno(uint32_t seq) {
    seqno_ = seq;
    uve_seqno_ = seq;
}

uint32_t KSyncSock::AllocSeqNo(IoContext::Type type, uint32_t instance) {
    uint32_t seq;
    if (type == IoContext::IOC_UVE) {
        seq = uve_seqno_.fetch_and_add(1);
        seq = (seq * kRxWorkQueueCount + (instance % kRxWorkQueueCount)) << 1;
    } else {
        seq = seqno_.fetch_and_add(1);
        seq = (seq * kRxWorkQueueCount + (instance % kRxWorkQueueCount)) << 1;
        seq |= KSYNC_DEFAULT_Q_ID_SEQ;
    }
    if (seq == kInvalidBulkSeqNo) {
        return AllocSeqNo(type, instance);
    }
    return seq;
}

uint32_t KSyncSock::AllocSeqNo(IoContext::Type type) {
    return AllocSeqNo(type, 0);
}

KSyncSock::KSyncReceiveQueue *KSyncSock::GetReceiveQueue(IoContext::Type type,
                                                         uint32_t instance) {
    if (type == IoContext::IOC_UVE) {
        return uve_rx_queue[instance % kRxWorkQueueCount];
    } else {
        return ksync_rx_queue[instance % kRxWorkQueueCount];
    }
}

KSyncSock::KSyncReceiveQueue *KSyncSock::GetReceiveQueue(uint32_t seqno) {
    IoContext::Type type;
    if (seqno & KSYNC_DEFAULT_Q_ID_SEQ)
        type = IoContext::IOC_UVE;
    else
        type = IoContext::IOC_KSYNC;

    uint32_t instance = (seqno >> 1) % kRxWorkQueueCount;
    return GetReceiveQueue(type, instance);
}

KSyncSock *KSyncSock::Get(DBTablePartBase *partition) {
    return sock_.get();
}

KSyncSock *KSyncSock::Get(int idx) {
    assert(idx == 0);
    return sock_.get();
}

bool KSyncSock::ValidateAndEnqueue(char *data, KSyncBulkMsgContext *context) {
    Validate(data);

    KSyncReceiveQueue *queue;
    if (context) {
        queue = GetReceiveQueue(context->io_context_type(),
                                context->work_queue_index());
    } else {
        queue = GetReceiveQueue(GetSeqno(data));
    }
    queue->Enqueue(KSyncRxData(data, context));
    return true;
}

// Read handler registered with boost::asio. Demux done based on seqno_
void KSyncSock::ReadHandler(const boost::system::error_code& error,
                            size_t bytes_transferred) {
    if (error) {
        LOG(ERROR, "Error reading from Ksync sock. Error : " <<
            boost::system::system_error(error).what());
        if (shutdown_ == false) {
            assert(0);
        }
        return;
    }

    ValidateAndEnqueue(rx_buff_, NULL);

    rx_buff_ = new char[kBufLen];
    AsyncReceive(boost::asio::buffer(rx_buff_, kBufLen),
                 boost::bind(&KSyncSock::ReadHandler, this,
                             placeholders::error,
                             placeholders::bytes_transferred));
}

// Process kernel data - executes in the task specified by IoContext
// Currently only Agent::KSync and Agent::Uve are possibilities
bool KSyncSock::ProcessKernelData(KSyncBulkSandeshContext *bulk_sandesh_context,
                                  const KSyncRxData &data) {
    KSyncBulkMsgContext *bulk_message_context = data.bulk_msg_context_;
    WaitTree::iterator it;
    if (data.bulk_msg_context_ == NULL) {
        uint32_t seqno = GetSeqno(data.buff_);
        {
            tbb::mutex::scoped_lock lock(mutex_);
            it = wait_tree_.find(seqno);
        }
        if (it == wait_tree_.end()) {
            LOG(ERROR, "KSync error in finding for sequence number : "
                << seqno);
            assert(0);
        }
        bulk_message_context = &(it->second);
    }

    bulk_sandesh_context->set_bulk_message_context(bulk_message_context);
    BulkDecoder(data.buff_, bulk_sandesh_context);
    // Remove the IoContext only on last netlink message
    if (IsMoreData(data.buff_) == false) {
        if (data.bulk_msg_context_ != NULL) {
            delete data.bulk_msg_context_;
        } else {
            tbb::mutex::scoped_lock lock(mutex_);
            wait_tree_.erase(it);
        }
    }
    delete[] data.buff_;
    return true;
}

bool KSyncSock::BlockingRecv() {
    char data[kBufLen];
    bool ret = false;

    do {
        Receive(boost::asio::buffer(data, kBufLen));
        AgentSandeshContext *ctxt = KSyncSock::GetAgentSandeshContext(0);
        ctxt->SetErrno(0);
        // BlockingRecv used only during Init and doesnt support bulk messages
        // Use non-bulk version of decoder
        Decoder(data, ctxt);
        if (ctxt->GetErrno() != 0 && ctxt->GetErrno() != EEXIST) {
            KSYNC_ERROR(VRouterError, "VRouter operation failed. Error <",
                        ctxt->GetErrno(), ":",
                        KSyncEntry::VrouterErrorToString(ctxt->GetErrno()),
                        ">. Object <", "N/A", ">. State <", "N/A",
                        ">. Message number :", 0);
            ret = true;
        }
    } while (IsMoreData(data));

    return ret;
}

// BlockingSend does not support bulk messages.
size_t KSyncSock::BlockingSend(char *msg, int msg_len) {
    KSyncBufferList iovec;
    iovec.push_back(buffer(msg, msg_len));
    bulk_buf_size_ = msg_len;
    return SendTo(&iovec, 0);
}

void KSyncSock::GenericSend(IoContext *ioc) {
    send_queue_.Enqueue(ioc);
}

void KSyncSock::SendAsync(KSyncEntry *entry, int msg_len, char *msg,
                          KSyncEntry::KSyncEvent event) {
    KSyncIoContext *ioc = new KSyncIoContext(this, entry, msg_len, msg, event);
    // Pre-allocate buffers to minimize processing in KSyncTxQueue context
    if (entry->pre_alloc_rx_buffer()) {
        ioc->rx_buffer1_ = new char [kBufLen];
        ioc->rx_buffer2_ = new char [kBufLen];
    }
    send_queue_.Enqueue(ioc);
}

// Write handler registered with boost::asio
void KSyncSock::WriteHandler(const boost::system::error_code& error,
                             size_t bytes_transferred) {
    if (error) {
        LOG(ERROR, "Ksync sock write error : " <<
            boost::system::system_error(error).what());
        if (shutdown_ == false) {
            assert(0);
        }
    }
}

// End of messages in the work-queue. Send messages pending in bulk context
void KSyncSock::OnEmptyQueue(bool done) {
    if (bulk_seq_no_ == kInvalidBulkSeqNo)
        return;

    KSyncBulkMsgContext *bulk_message_context = NULL;
    if (read_inline_ == false) {
        tbb::mutex::scoped_lock lock(mutex_);
        WaitTree::iterator it = wait_tree_.find(bulk_seq_no_);
        assert(it != wait_tree_.end());
        bulk_message_context = &it->second;
    } else {
        bulk_message_context = bulk_msg_context_;
    }

    SendBulkMessage(bulk_message_context, bulk_seq_no_);
}

// Send messages accumilated in bulk context
int KSyncSock::SendBulkMessage(KSyncBulkMsgContext *bulk_message_context,
                               uint32_t seqno) {
    KSyncBufferList iovec;
    // Get all buffers to send into single io-vector
    bulk_message_context->Data(&iovec);
    tx_count_++;

    if (!read_inline_) {
        AsyncSendTo(&iovec, seqno,
                    boost::bind(&KSyncSock::WriteHandler, this,
                                placeholders::error,
                                placeholders::bytes_transferred));
    } else {
        SendTo(&iovec, seqno);
        bool more_data = false;
        do {
            char *rxbuf = bulk_message_context->GetReceiveBuffer();
            Receive(boost::asio::buffer(rxbuf, kBufLen));
            more_data = IsMoreData(rxbuf);
            ValidateAndEnqueue(rxbuf, bulk_message_context);
        } while(more_data);
    }

    bulk_msg_context_ = NULL;
    bulk_seq_no_ = kInvalidBulkSeqNo;
    return true;
}

// Get the bulk-context for sequence-number
KSyncBulkMsgContext *KSyncSock::LocateBulkContext
(uint32_t seqno, IoContext::Type io_context_type,
 uint32_t work_queue_index) {
    if (read_inline_) {
        if (bulk_seq_no_ == kInvalidBulkSeqNo) {
            assert(bulk_msg_context_ == NULL);
            bulk_seq_no_ = seqno;
            bulk_buf_size_ = 0;
            bulk_msg_count_ = 0;
            bulk_msg_context_ = new KSyncBulkMsgContext(io_context_type,
                                                        work_queue_index);
        }
        return bulk_msg_context_;
    }

    tbb::mutex::scoped_lock lock(mutex_);
    if (bulk_seq_no_ == kInvalidBulkSeqNo) {
        bulk_seq_no_ = seqno;
        bulk_buf_size_ = 0;
        bulk_msg_count_ = 0;
        wait_tree_.insert(WaitTreePair(seqno,
                                       KSyncBulkMsgContext(io_context_type,
                                                           work_queue_index)));
    }

    WaitTree::iterator it = wait_tree_.find(bulk_seq_no_);
    assert(it != wait_tree_.end());
    return &it->second;
}

// Try adding an io-context to bulk context. Returns
//  - true  : if message can be added to bulk context
//  - false : if message cannot be added to bulk context
bool KSyncSock::TryAddToBulk(KSyncBulkMsgContext *bulk_message_context,
                             IoContext *ioc) {
    if ((bulk_buf_size_ + ioc->GetMsgLen()) > max_bulk_buf_size_)
        return false;

    if (bulk_msg_count_ >= max_bulk_msg_count_)
        return false;

    if (bulk_message_context->io_context_type() != ioc->type())
        return false;

    if (bulk_message_context->work_queue_index() != ioc->index())
        return false;

    bulk_buf_size_ += ioc->GetMsgLen();
    bulk_msg_count_++;

    bulk_message_context->Insert(ioc);
    if (ioc->rx_buffer1()) {
        bulk_message_context->AddReceiveBuffer(ioc->rx_buffer1());
        ioc->reset_rx_buffer1();

    }
    if (ioc->rx_buffer2()) {
        bulk_message_context->AddReceiveBuffer(ioc->rx_buffer2());
        ioc->reset_rx_buffer2();
    }
    return true;
}

bool KSyncSock::SendAsyncImpl(IoContext *ioc) {
    KSyncBulkMsgContext *bulk_message_context =
        LocateBulkContext(ioc->GetSeqno(), ioc->type(), ioc->index());
    // Try adding message to bulk-message list
    if (TryAddToBulk(bulk_message_context, ioc)) {
        // Message added to bulk-list. Nothing more to do
        return true;
    }

    // Message cannot be added to bulk-list. Send the current list
    SendBulkMessage(bulk_message_context, bulk_seq_no_);

    // Allocate a new context and add message to it
    bulk_message_context = LocateBulkContext(ioc->GetSeqno(), ioc->type(),
                                             ioc->index());
    assert(TryAddToBulk(bulk_message_context, ioc));
    return true;
}

/////////////////////////////////////////////////////////////////////////////
// KSyncSockNetlink routines
/////////////////////////////////////////////////////////////////////////////
KSyncSockNetlink::KSyncSockNetlink(boost::asio::io_service &ios, int protocol)
    : sock_(ios, protocol) {
    ReceiveBuffForceSize set_rcv_buf;
    set_rcv_buf = KSYNC_SOCK_RECV_BUFF_SIZE;
    boost::system::error_code ec;
    sock_.set_option(set_rcv_buf, ec);
    if (ec.value() != 0) {
        LOG(ERROR, "Error Changing netlink receive sock buffer size to " <<
                set_rcv_buf.value() << " error = " <<
                boost::system::system_error(ec).what());
    }
    boost::asio::socket_base::receive_buffer_size rcv_buf_size;
    boost::system::error_code ec1;
    sock_.get_option(rcv_buf_size, ec);
    LOG(INFO, "Current receive sock buffer size is " << rcv_buf_size.value());
}

KSyncSockNetlink::~KSyncSockNetlink() {
}

void KSyncSockNetlink::Init(io_service &ios, int protocol,
                            const std::string &cpu_pin_policy) {
    KSyncSock::SetSockTableEntry(new KSyncSockNetlink(ios, protocol));
    KSyncSock::Init(false, cpu_pin_policy);
}

uint32_t KSyncSockNetlink::GetSeqno(char *data) {
    return GetNetlinkSeqno(data);
}

bool KSyncSockNetlink::IsMoreData(char *data) {
    return NetlinkMsgDone(data);
}

bool KSyncSockNetlink::Validate(char *data) {
    return ValidateNetlink(data);
}

//netlink socket class for interacting with kernel
void KSyncSockNetlink::AsyncSendTo(KSyncBufferList *iovec, uint32_t seq_no,
                                   HandlerCb cb) {
    ResetNetlink(nl_client_);
    KSyncBufferList::iterator it = iovec->begin();
    iovec->insert(it, buffer((char *)nl_client_->cl_buf,
                             nl_client_->cl_buf_offset));
    UpdateNetlink(nl_client_, bulk_buf_size_, seq_no);

    boost::asio::netlink::raw::endpoint ep;
    sock_.async_send_to(*iovec, ep, cb);
}

size_t KSyncSockNetlink::SendTo(KSyncBufferList *iovec, uint32_t seq_no) {
    ResetNetlink(nl_client_);
    KSyncBufferList::iterator it = iovec->begin();
    iovec->insert(it, buffer((char *)nl_client_->cl_buf,
                             nl_client_->cl_buf_offset));
    UpdateNetlink(nl_client_, bulk_buf_size_, seq_no);

    boost::asio::netlink::raw::endpoint ep;
    return sock_.send_to(*iovec, ep);
}

// Static method to decode non-bulk message
void KSyncSockNetlink::NetlinkDecoder(char *data, SandeshContext *ctxt) {
    assert(ValidateNetlink(data));
    char *buf = NULL;
    uint32_t buf_len = 0;
    GetNetlinkPayload(data, &buf, &buf_len);
    DecodeSandeshMessages(buf, buf_len, ctxt, NLA_ALIGNTO);
}

bool KSyncSockNetlink::Decoder(char *data, AgentSandeshContext *context) {
    NetlinkDecoder(data, context);
    return true;
}

// Static method used in ksync_sock_user only
void KSyncSockNetlink::NetlinkBulkDecoder(char *data, SandeshContext *ctxt,
                                          bool more) {
    assert(ValidateNetlink(data));
    char *buf = NULL;
    uint32_t buf_len = 0;
    GetNetlinkPayload(data, &buf, &buf_len);
    KSyncBulkSandeshContext *bulk_sandesh_context =
        dynamic_cast<KSyncBulkSandeshContext *>(ctxt);
    bulk_sandesh_context->Decoder(buf, buf_len, NLA_ALIGNTO, more);
}

bool KSyncSockNetlink::BulkDecoder(char *data,
                                   KSyncBulkSandeshContext *bulk_sandesh_context) {
    // Get sandesh buffer and buffer-length
    uint32_t buf_len = 0;
    char *buf = NULL;
    GetNetlinkPayload(data, &buf, &buf_len);
    return bulk_sandesh_context->Decoder(buf, buf_len, NLA_ALIGNTO, IsMoreData(data));
}

void KSyncSockNetlink::AsyncReceive(mutable_buffers_1 buf, HandlerCb cb) {
    sock_.async_receive(buf, cb);
}

void KSyncSockNetlink::Receive(mutable_buffers_1 buf) {
    sock_.receive(buf);
    struct nlmsghdr *nlh = buffer_cast<struct nlmsghdr *>(buf);
    if (nlh->nlmsg_type == NLMSG_ERROR) {
        LOG(ERROR, "Netlink error for seqno " << nlh->nlmsg_seq
                << " len " << nlh->nlmsg_len);
        assert(0);
    }
}

/////////////////////////////////////////////////////////////////////////////
// KSyncSockUdp routines
/////////////////////////////////////////////////////////////////////////////
//Udp socket class for interacting with kernel
KSyncSockUdp::KSyncSockUdp(boost::asio::io_service &ios, int port) :
    sock_(ios, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)),
    server_ep_(boost::asio::ip::address::from_string("127.0.0.1"), port) {
}

void KSyncSockUdp::Init(io_service &ios, int port,
                        const std::string &cpu_pin_policy) {
    KSyncSock::SetSockTableEntry(new KSyncSockUdp(ios, port));
    KSyncSock::Init(false, cpu_pin_policy);
}

uint32_t KSyncSockUdp::GetSeqno(char *data) {
    struct uvr_msg_hdr *hdr = (struct uvr_msg_hdr *)data;
    return hdr->seq_no;
}

bool KSyncSockUdp::IsMoreData(char *data) {
    struct uvr_msg_hdr *hdr = (struct uvr_msg_hdr *)data;
    return ((hdr->flags & UVR_MORE) == UVR_MORE);
}

// We dont expect any non-bulk operation on UDP
bool KSyncSockUdp::Decoder(char *data, AgentSandeshContext *context) {
    assert(0);
}

bool KSyncSockUdp::BulkDecoder(char *data,
                               KSyncBulkSandeshContext *bulk_sandesh_context) {
    struct uvr_msg_hdr *hdr = (struct uvr_msg_hdr *)data;
    uint32_t buf_len = hdr->msg_len;
    char *buf = data + sizeof(struct uvr_msg_hdr);
    return bulk_sandesh_context->Decoder(buf, buf_len, 1, IsMoreData(data));
}

void KSyncSockUdp::AsyncSendTo(KSyncBufferList *iovec, uint32_t seq_no,
                               HandlerCb cb) {
    struct uvr_msg_hdr hdr;
    hdr.seq_no = seq_no;
    hdr.flags = 0;
    hdr.msg_len = bulk_buf_size_;

    KSyncBufferList::iterator it = iovec->begin();
    iovec->insert(it, buffer((char *)(&hdr), sizeof(hdr)));

    sock_.async_send_to(*iovec, server_ep_, cb);
}

size_t KSyncSockUdp::SendTo(KSyncBufferList *iovec, uint32_t seq_no) {
    struct uvr_msg_hdr hdr;
    hdr.seq_no = seq_no;
    hdr.flags = 0;
    hdr.msg_len = bulk_buf_size_;

    KSyncBufferList::iterator it = iovec->begin();
    iovec->insert(it, buffer((char *)(&hdr), sizeof(hdr)));

    return sock_.send_to(*iovec, server_ep_, MSG_DONTWAIT);
}

bool KSyncSockUdp::Validate(char *data) {
    return true;
}

void KSyncSockUdp::AsyncReceive(mutable_buffers_1 buf, HandlerCb cb) {
    boost::asio::ip::udp::endpoint ep;
    sock_.async_receive_from(buf, ep, cb);
}

void KSyncSockUdp::Receive(mutable_buffers_1 buf) {
    boost::asio::ip::udp::endpoint ep;
    sock_.receive_from(buf, ep);
}

/////////////////////////////////////////////////////////////////////////////
// KSyncSockTcp routines
/////////////////////////////////////////////////////////////////////////////
//TCP socket class for interacting with vrouter
KSyncSockTcp::KSyncSockTcp(EventManager *evm,
    boost::asio::ip::address ip_address, int port) : TcpServer(evm), evm_(evm),
    session_(NULL), server_ep_(ip_address, port), connect_complete_(false) {
    session_ = CreateSession();
    Connect(session_, server_ep_);
}

void KSyncSockTcp::Init(EventManager *evm, boost::asio::ip::address ip_addr,
                        int port, const std::string &cpu_pin_policy) {
    KSyncSock::SetSockTableEntry(new KSyncSockTcp(evm, ip_addr, port));
    SetNetlinkFamilyId(10);
    KSyncSock::Init(false, cpu_pin_policy);
}

TcpSession* KSyncSockTcp::AllocSession(Socket *socket) {
    TcpSession *session = new KSyncSockTcpSession(this, socket, false);
    session->set_observer(boost::bind(&KSyncSockTcp::OnSessionEvent,
                                      this, _1, _2));
    return session;
}

uint32_t KSyncSockTcp::GetSeqno(char *data) {
    return GetNetlinkSeqno(data);
}

bool KSyncSockTcp::IsMoreData(char *data) {
    return NetlinkMsgDone(data);
}

size_t KSyncSockTcp::SendTo(KSyncBufferList *iovec, uint32_t seq_no) {
    ResetNetlink(nl_client_);
    int offset = nl_client_->cl_buf_offset;
    UpdateNetlink(nl_client_, bulk_buf_size_, seq_no);

    KSyncBufferList::iterator it = iovec->begin();
    iovec->insert(it, buffer((char *)nl_client_->cl_buf, offset));

    uint32_t alloc_len = IoVectorLength(iovec);
    char msg[alloc_len];

    uint32_t len = IoVectorToData(msg, iovec);

    session_->Send((const uint8_t *)(msg), len, NULL);
    return nl_client_->cl_buf_offset;
}

void KSyncSockTcp::AsyncSendTo(KSyncBufferList *iovec, uint32_t seq_no,
                               HandlerCb cb) {
    SendTo(iovec, seq_no);
    return;
}

bool KSyncSockTcp::Validate(char *data) {
    return ValidateNetlink(data);
}

bool KSyncSockTcp::Decoder(char *data, AgentSandeshContext *context) {
    KSyncSockNetlink::NetlinkDecoder(data, context);
    return true;
}

bool KSyncSockTcp::BulkDecoder(char *data,
                               KSyncBulkSandeshContext *bulk_sandesh_context) {
    // Get sandesh buffer and buffer-length
    uint32_t buf_len = 0;
    char *buf = NULL;
    GetNetlinkPayload(data, &buf, &buf_len);
    return bulk_sandesh_context->Decoder(buf, buf_len, NLA_ALIGNTO, IsMoreData(data));
}

void KSyncSockTcp::AsyncReceive(mutable_buffers_1 buf, HandlerCb cb) {
    //Data would be read from ksync tcp session
    //hence no socket operation would be required
}

void KSyncSockTcp::Receive(mutable_buffers_1 buf) {
    uint32_t bytes_read = 0;
    boost::system::error_code ec;
    const struct nlmsghdr *nlh = NULL;

    //Create a buffer to read netlink header first
    mutable_buffers_1 netlink_header(buffer_cast<void *>(buf),
                                     sizeof(struct nlmsghdr));

    bool blocking_socket = session_->socket()->non_blocking();
    session_->socket()->non_blocking(false, ec);
    while (bytes_read < sizeof(struct nlmsghdr)) {
        mutable_buffers_1 buffer =
            static_cast<mutable_buffers_1>(netlink_header + bytes_read);
        bytes_read += session_->socket()->receive(buffer, 0, ec);
        if (ec != 0) {
            assert(0);
        }
        //Data read is lesser than netlink header
        //continue reading
        if (bytes_read == sizeof(struct nlmsghdr)) {
            nlh =  buffer_cast<struct nlmsghdr *>(buf);
        }
    }

    if (nlh->nlmsg_type == NLMSG_ERROR) {
        LOG(ERROR, "Netlink error for seqno " << nlh->nlmsg_seq
                << " len " << nlh->nlmsg_len);
        assert(0);
    }

    bytes_read = 0;
    uint32_t payload_size = nlh->nlmsg_len - sizeof(struct nlmsghdr);
    //Read data
    mutable_buffers_1 data(buffer_cast<void *>(buf + sizeof(struct nlmsghdr)),
                           payload_size);

    while (bytes_read < payload_size) {
        mutable_buffers_1 buffer =
            static_cast<mutable_buffers_1>(data + bytes_read);
        bytes_read += session_->socket()->receive(buffer, 0, ec);
        if (ec != 0) {
            assert(0);
        }
    }
    session_->socket()->non_blocking(blocking_socket, ec);
}

bool KSyncSockTcp::ReceiveMsg(const u_int8_t *msg, size_t size) {
    char *rx_buff = new char[kBufLen];
    memcpy(rx_buff, msg, size);
    ValidateAndEnqueue(rx_buff, NULL);
    return true;
}

void KSyncSockTcp::AsyncReadStart() {
    session_->AsyncReadStart();
}

void KSyncSockTcp::OnSessionEvent(TcpSession *session,
                                  TcpSession::Event event) {
    switch (event) {
    case TcpSession::CONNECT_FAILED:
        //Retry
        Connect(session_, server_ep_);
        break;
    case TcpSession::CLOSE:
        LOG(ERROR, "Connection to dpdk-vrouter lost.");
        sleep(10);
        exit(EXIT_FAILURE);
        break;
    case TcpSession::CONNECT_COMPLETE:
        connect_complete_ = true;
        session_->SetTcpNoDelay();
    default:
        break;
    }
}

/////////////////////////////////////////////////////////////////////////////
// KSyncSockTcpSession routines
/////////////////////////////////////////////////////////////////////////////
KSyncSockTcpSession::KSyncSockTcpSession(TcpServer *server, Socket *sock,
    bool async_ready) : TcpSession(server, sock, async_ready) {
    KSyncSockTcp *tcp_ptr = static_cast<KSyncSockTcp *>(server);
    reader_ = new KSyncSockTcpSessionReader(this,
                       boost::bind(&KSyncSockTcp::ReceiveMsg, tcp_ptr, _1, _2));
}

void KSyncSockTcpSession::OnRead(Buffer buffer) {
    reader_->OnRead(buffer);
}

KSyncSockTcpSessionReader::KSyncSockTcpSessionReader(
    TcpSession *session, ReceiveCallback callback) :
    TcpMessageReader(session, callback) {
}

int KSyncSockTcpSessionReader::MsgLength(Buffer buffer, int offset) {
    size_t size = TcpSession::BufferSize(buffer);
    int remain = size - offset;
    if (remain < GetHeaderLenSize()) {
        return -1;
    }

    //Byte ordering?
    const struct nlmsghdr *nlh =
        (const struct nlmsghdr *)(TcpSession::BufferData(buffer) + offset);
    return nlh->nlmsg_len;
}

/////////////////////////////////////////////////////////////////////////////
// KSyncIoContext routines
/////////////////////////////////////////////////////////////////////////////
KSyncIoContext::KSyncIoContext(KSyncSock *sock, KSyncEntry *sync_entry,
                               int msg_len, char *msg,
                               KSyncEntry::KSyncEvent event) :
    IoContext(msg, msg_len, 0,
              sock->GetAgentSandeshContext(sync_entry->GetTableIndex()),
              IoContext::IOC_KSYNC, sync_entry->GetTableIndex()),
    entry_(sync_entry), event_(event) {
    SetSeqno(sock->AllocSeqNo(type(), index()));
}

void KSyncIoContext::Handler() {
    if (KSyncObject *obj = entry_->GetObject()) {
        obj->NetlinkAck(entry_, event_);
    }
}

void KSyncIoContext::ErrorHandler(int err) {
    entry_->ErrorHandler(err, GetSeqno(), event_);
}

/////////////////////////////////////////////////////////////////////////////
// Routines for KSyncBulkSandeshContext
/////////////////////////////////////////////////////////////////////////////
KSyncBulkSandeshContext::KSyncBulkSandeshContext() :
    AgentSandeshContext(), bulk_msg_context_(NULL)  { }

KSyncBulkSandeshContext::~KSyncBulkSandeshContext() {
}

// Sandesh responses for old context are done. Check for any errors
void KSyncBulkSandeshContext::IoContextDone() {
    IoContext *io_context = &(*bulk_msg_context_->io_context_list_it_);
    AgentSandeshContext *sandesh_context = io_context->GetSandeshContext();

    sandesh_context->set_ksync_io_ctx(NULL);
    if (sandesh_context->GetErrno() != 0 &&
        sandesh_context->GetErrno() != EEXIST) {
        io_context->ErrorHandler(sandesh_context->GetErrno());
    }
    io_context->Handler();
}

void KSyncBulkSandeshContext::IoContextStart() {
    bulk_msg_context_->vr_response_count_++;
    IoContext &io_context = *bulk_msg_context_->io_context_list_it_;
    AgentSandeshContext *sandesh_context = io_context.GetSandeshContext();
    sandesh_context->set_ksync_io_ctx
        (static_cast<KSyncIoContext *>(&io_context));
}

// Process the sandesh messages
// There can be more then one sandesh messages in the netlink buffer.
// Iterate and process all of them
bool KSyncBulkSandeshContext::Decoder(char *data, uint32_t len,
                                      uint32_t alignment, bool more) {
    DecodeSandeshMessages(data, len, this, alignment);
    assert(bulk_msg_context_->io_context_list_it_ !=
           bulk_msg_context_->io_context_list_.end());
    if (more == true)
        return false;

    IoContextDone();

    // No more netlink messages. Validate that iterator points to last element
    // in IoContextList
    bulk_msg_context_->io_context_list_it_++;
    assert(bulk_msg_context_->io_context_list_it_ ==
           bulk_msg_context_->io_context_list_.end());
    return true;
}

void KSyncBulkSandeshContext::SetErrno(int err) {
    AgentSandeshContext *context = GetSandeshContext();
    context->SetErrno(err);
}

AgentSandeshContext *KSyncBulkSandeshContext::GetSandeshContext() {
    assert(bulk_msg_context_->vr_response_count_);
    return bulk_msg_context_->io_context_list_it_->GetSandeshContext();
}

void KSyncBulkSandeshContext::IfMsgHandler(vr_interface_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->IfMsgHandler(req);
}

void KSyncBulkSandeshContext::NHMsgHandler(vr_nexthop_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->NHMsgHandler(req);
}

void KSyncBulkSandeshContext::RouteMsgHandler(vr_route_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->RouteMsgHandler(req);
}

void KSyncBulkSandeshContext::MplsMsgHandler(vr_mpls_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->MplsMsgHandler(req);
}

void KSyncBulkSandeshContext::QosConfigMsgHandler(vr_qos_map_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->QosConfigMsgHandler(req);
}

void KSyncBulkSandeshContext::ForwardingClassMsgHandler(vr_fc_map_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->ForwardingClassMsgHandler(req);
}

// vr_response message is treated as delimiter in a bulk-context. So, move to
// next io-context within bulk-message context.
int KSyncBulkSandeshContext::VrResponseMsgHandler(vr_response *resp) {
    AgentSandeshContext *sandesh_context = NULL;
    // If this is first vr_reponse received, move io-context to first entry in
    // bulk context
    if (bulk_msg_context_->vr_response_count_ == 0) {
        bulk_msg_context_->io_context_list_it_ =
            bulk_msg_context_->io_context_list_.begin();
        sandesh_context =
            bulk_msg_context_->io_context_list_it_->GetSandeshContext();
        IoContextStart();
    } else {
        // Sandesh responses for old io-context are done.
        // Check for any errors and trigger state-machine for old io-context
        IoContextDone();
        // Move to the next io-context
        bulk_msg_context_->io_context_list_it_++;
        assert(bulk_msg_context_->io_context_list_it_ !=
               bulk_msg_context_->io_context_list_.end());
        sandesh_context =
            bulk_msg_context_->io_context_list_it_->GetSandeshContext();
        IoContextStart();
    }
    return sandesh_context->VrResponseMsgHandler(resp);
}

void KSyncBulkSandeshContext::MirrorMsgHandler(vr_mirror_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->MirrorMsgHandler(req);
}

void KSyncBulkSandeshContext::FlowMsgHandler(vr_flow_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->FlowMsgHandler(req);
}

void KSyncBulkSandeshContext::FlowResponseHandler(vr_flow_response *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->FlowResponseHandler(req);
}

void KSyncBulkSandeshContext::VrfAssignMsgHandler(vr_vrf_assign_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->VrfAssignMsgHandler(req);
}

void KSyncBulkSandeshContext::VrfStatsMsgHandler(vr_vrf_stats_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->VrfStatsMsgHandler(req);
}

void KSyncBulkSandeshContext::DropStatsMsgHandler(vr_drop_stats_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->DropStatsMsgHandler(req);
}

void KSyncBulkSandeshContext::VxLanMsgHandler(vr_vxlan_req *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->VxLanMsgHandler(req);
}

void KSyncBulkSandeshContext::VrouterOpsMsgHandler(vrouter_ops *req) {
    AgentSandeshContext *context = GetSandeshContext();
    context->VrouterOpsMsgHandler(req);
}

/////////////////////////////////////////////////////////////////////////////
// KSyncBulkMsgContext routines
/////////////////////////////////////////////////////////////////////////////
KSyncBulkMsgContext::KSyncBulkMsgContext(IoContext::Type type,
                                         uint32_t index) :
    io_context_list_(), io_context_type_(type), work_queue_index_(index),
    rx_buffer_index_(0), vr_response_count_(0), io_context_list_it_() {
}

KSyncBulkMsgContext::KSyncBulkMsgContext(const KSyncBulkMsgContext &rhs) :
    io_context_list_(), io_context_type_(rhs.io_context_type_),
    work_queue_index_(rhs.work_queue_index_),
    rx_buffer_index_(0), vr_response_count_(0), io_context_list_it_() {
    assert(rhs.vr_response_count_ == 0);
    assert(rhs.rx_buffer_index_ == 0);
    assert(rhs.io_context_list_.size() == 0);
}

struct IoContextDisposer {
    void operator() (IoContext *io_context) { delete io_context; }
};

KSyncBulkMsgContext::~KSyncBulkMsgContext() {
    assert(vr_response_count_ == io_context_list_.size());
    io_context_list_.clear_and_dispose(IoContextDisposer());
    for (uint32_t i = 0; i < rx_buffer_index_; i++) {
        delete[] rx_buffers_[i];
    }
}

char *KSyncBulkMsgContext::GetReceiveBuffer() {
    if (rx_buffer_index_ == 0)
        return new char[KSyncSock::kBufLen];

    return rx_buffers_[--rx_buffer_index_];
}

void KSyncBulkMsgContext::AddReceiveBuffer(char *buff) {
    assert(rx_buffer_index_ < kMaxRxBufferCount);
    rx_buffers_[rx_buffer_index_++] = buff;
}

void KSyncBulkMsgContext::Insert(IoContext *ioc) {
    io_context_list_.push_back(*ioc);
    return;
}

void KSyncBulkMsgContext::Data(KSyncBufferList *iovec) {
    IoContextList::iterator it = io_context_list_.begin();
    while (it != io_context_list_.end()) {
        iovec->push_back(buffer(it->GetMsg(), it->GetMsgLen()));
        it++;
    }
}


Posted on 29/03/2019 at 12:13.
Hosted by the KTN, Heathrow & Mace recently held the first workshop in the Offsite Logistics priority project this month to capture our industries perceived 'Current State' & 'Ideal State' of logistics in relation to offsite.
We had fantastic attendance from the clients, contractors and consultants of i3P as well as additional industry partners.


Saiyok River House is cosily snuggled down by the magnificent River Kwai of Kanchanaburi Province. Blessed with the serene natural surroundings of mountain, river and lush greeneries, staying here is like being in a cradle of the nature. This is undoubtedly a perfect place if you yearn for a peaceful retreat away from the bustling crowd and hectic city life. Only 20 miles away from Kanchanaburi Downtown, located nearby the resort are numerous natural attractions and scenic architectures. Wireless internet is provided on-site. Enjoy a refreshing dip at the outdoor swimming pool, or relax your body and soul with traditional Thai massage. Other facilities include a reading room, movie rental, karaoke, half-court basketball, and fishing raft.


An old joke says that no one is actually from Roscommon, because the county doesn't have a maternity hospital, but you'd be hard-pressed to tell the proud people of Roscommon that. Neither the biggest nor the smallest county in Ireland, Roscommon is generally ignored by the rest of the country, which is odd, given that the county's pronounced shape on the map could make it the business end of a few more jokes.
In fact, Roscommon is quite beautiful, with a varied Connacht landscape that encompasses lakes, rivers and mountains. Plus, with the actual geographical centre of Ireland located on the shores of Lough Ree in Carnagh East, Roscommon has every right to hold its head high.
You can learn a lot about Ireland in Roscommon. For starters, it was the setting for numerous Irish myths, including the UNESCO World Heritage Site, Rathcroghan, which was the home of mythological queen Maeve. Roscommon also houses the National Famine Museum in Strokestown – one of the few museums in the world on the topic of the Famine.
In the town of Boyle, you can visit the stunning remains of Boyle Abbey, the first Cistercian monastery in Connacht, founded in 1142. Likewise, the King House in Boyle is a lofty old Georgian castle that faces onto the River Boyle, while the crumbling, ivy-covered remains of Roscommon Castle near the county town were constructed in 1269.
Roscommon has also produced its fair share of important Irish people, such as the first president of Ireland, Douglas Hyde, who is commemorated at the Doctor Douglas Hyde Interpretative Centre in Frenchpark. He also founded the Gaelic League in 1893, which, among other things, aiding in Irish becoming an official European Union language. Other famous Roscommoners include actor Chris O'Dowd (of The IT Crowd fame), entertainer Percy French and early Hollywood actress, Maureen O'Sullivan.
Arches in Boyle Abbey, Roscommon.
Lough Key Forest Park, Roscommon.
Boyle Abbey is an impressive and well preserved Cistercian Monastery which was founded in the 12th century.
Stone detail, Boyle Abbey, Roscommon.
How much do you know about Roscommon ?


Simple arcade, racing game with police and a lot of speed cars and destructive enviroments.
New game from very young polish games studio.
You are street race driver and you have to face many difficult challenges while you are being hunted by police.
There are many different types of cars to choose from. You can spend money on upgrading your car's performance and handling.
You will visit many different locations like suburbs and construction site.
Rate game and write your opinion in Google Play.


Accidents which occur while drivers are driving in the wrong direction continue to cause serious – and in many cases – fatal injuries. In most instances these "wrong-way driver" crashes happen when the driver is intoxicated. On this site, such crashes are summarized in the "Wrong-Way Drivers" category.
There was a fatal accident early Monday morning (January 2, 2016) in Chicago's Loop. The accident involved a driver heading in the wrong direction in the 100 block of South Wells.
Details on the accident are somewhat limited. According to Chicago Police, the accident happened at 12:05 a.m., as a 15-year-old girl (later identified as Hailee Melendez, of Chicago) was driving a Nissan Pathfinder. The accident happened as the Pathfinder struck a steel beam that supports a CTA platform.
The crash was a "pin-in" crash. The girl was pronounced dead at the accident scene.
This fatal Chicago accident remains under investigation by the Chicago Police Department's Major Accidents Investigation Unit.


Darmstadt takes the 8th position with 15 points after 9 rounds. The team is regressing in recent matches. The team couldn't win in 6 of 7 last away matches. The guests play worse away than at home. 34% of points were scored in away matches.
Dusseldorf takes the first position with 25 points. The team has rather good results in 8 recent matches: 7 victories and 1 defeat. The hosts scored 16 goals in them. The hosts play at home better than all the other teams of the championship. The hosts haven't lost for 7 matches at home in a row.
Teams have met once for 3 years and Dusseldorf won.
Here you will find the FOOTBALL prediction for the match of Dusseldorf & Darmstadt of the 2nd Bundesliga, Germany. The prediction is prepared by our analytical team and is based on the latest news of the 2nd Bundesliga, Dusseldorf and Darmstadt stats and lineups, insider news and our team's expert analysis. We publish our free betting tips and FOOTBALL predictions to help you win more. You can use the information from this Dusseldorf - Darmstadt match preview for your own purposes. The odds are valid at the moment of publication.


Late Sunday morning, the Yoknapatawpha County Sheriff's Department got a 911 call reporting a woman found dead in her home.
The dead woman was identified as Kimberly Pace by her sister, Becky, who was one of three people who made the heartbreaking discovery.
Kim's close friend, Cheryl Weston, was also there for the gruesome find along with friend and neighbor, Jeremy Gladwell.
Investigators spoke with nearby residents to find out if anyone witnessed anything unusual recently, while the Oxford Weekly Planet broke the news to the community.
The next morning, the detectives spoke to Kimberly's next door neighbor.
After lunch, her estranged boyfriend came in for a sitdown with the detectives.
Then the detectives tracked down the controversial column in the campus newspaper and Dr. Pace's rebuttal.
They also reviewed CSU's preliminary inventory of evidence collected at Dr. Pace's home and spoke to the young man seen riding his bike in her neighborhood the morning her body was found.
Later, Detectives Armstrong and Murphy went over to the university to meet with the student who reportedly wrote the inflammatory column in the campus newspaper.
The next morning, the detectives spoke with Dr. Bricker, one of Kimberly's colleagues who was not her biggest fan.
Later, Detectives Armstrong and Murphy talked to the friend Paul's been staying with about Paul's whereabouts the night Kimberly died and more.
Then they talked to Miguel's girlfriend to see if she corroborated Miguel's story.
The next morning, the detectives met with Dr. Bricker's wife to see if she could shed any light on the antipathy between her husband and Dr. Pace. Meanwhile, investigators mapped out locations relevant to the investigation.
Then Detectives Armstrong and Murphy examined Kimberly Pace's recent phone calls and voice mail.
Later, they sat down with the student who Patrick Richards claimed was behind the controversial column.
Meanwhile, investigators went over to the campus to talk to faculty and students who knew Dr. Pace.
The detectives talked to the veterinarian who examined Dr. Pace's dog after her body was found to find out if there was anything unexpected about the dog's condition.
After lunch, the coroner's office sent over a report on their preliminary findings.
Then Detectives Murphy and Armstrong got a preview of Dr. Pace's financial situation at the time of her death and what was on her computer, while analysts prepare more detailed reports.
Late that afternoon, they had a conversation with one of Dr. Pace's former students.
The next morning, the detectives met with a local physician to find out about Dr. Pace's medical condition before she died.
That afternoon, they and many others attended Kimberly Pace's funeral.
To find out more about Paul Evans's activities the night Kimberly died, the detectives talked to the C'est Belle Gallery owner and to the patron who's been supporting Paul's work. They also took some photos of Paul's creations.
Later that afternoon, they got a copy of Kimberly's last bank statement and some portions of her journal.
The next day, the detectives took another run at Carter Nichols to see if they could get a little more truth out of him.
They had a little more success prying a straight story out of Cody Matthews afterward.
Late that afternoon, new information came in from the crime lab about Kimberly's email and fingerprints in her residence.
To find out more about the death of Kimberly's dog, Emerson, the detectives talked to the dog sitter who was taking care of Emerson at the time.
Then they had another conversation with Jeremy, Kimberly's friend and neighbor, to see what he knew about Emerson's death and other open questions.
Meanwhile, other YCSD investigators started getting the results of several criminal background checks on some persons of interest.
Following up on the dog sitter's story, the detectives talked to her ex-boyfriend about the events surrounding Emerson's death.
Then they reviewed some more excerpts from Kimberly's journal that investigators had highlighted as potentially relevant.
While Detectives Armstrong and Murphy prepared for their next interview, a few more criminal background checks came in.
Later, they talked again with Kimberly's sister, Becky, to try to clear up some confusion and unanswered questions.
The next morning, the detectives followed up with Cheryl to see what she had to say about what Becky told them.
Then they met with Kimberly's neighbor again to get his side of the stories others told about him.
Later on, Kimberly's boyfriend, Paul, came in again to address some of the allegations people have made about him and about Kim.
Meanwhile, other YCSD investigators spoke to Carter Nichols' fraternity brothers about his whereabouts the night Kimberly was killed. They also looked into who Kim had been emailing with.
They also ran two more criminal background checks.
Detective Murphy took Arthur up on his invitation to get a tour of his garden, and then she and Detective Armstrong made another attempt to get something other than attitude out of Carter Nichols.
Shortly afterward, they got the crime lab's preliminary report on trace evidence recovered at Kimberly's residence.
Meanwhile, other YCSD investigators spoke to Cody's roommates about his whereabouts the night Kimberly was killed.
The detectives went back to Dr. Bricker to clarify his alibi for the time of Kim's death.
That afternoon, they obtained three search warrants and executed the first warrant on the university campus.
Bright and early the next morning, Detectives Armstrong and Murphy dropped in on Carter Nichols with another warrant. Later that afternoon, they went to take an official look around Arthur's place.
While they waited for the forensics, investigators compiled a timeline for the night Kimberly died and a chart of the alibis all the persons of interest gave.
The crime lab sent over preliminary reports on the evidence collected during the searches and more evidence from Kimberly Pace's residence.
When the detectives went to arrest a suspect, they were greeted with a surprise and looked for possible explanations.


1966 Plymouth Fury III By Jordan Hetrick featured in the mopars of the month section April 2000.
1966 Plymouth Satellite By James Ptacnik featured in the mopars of the month section March 2000.
1966 Plymouth Satellite By Bruce Babcock featured in the mopars of the month section February 2000.


28 And the angel came to her and said, "Rejoice, favored woman! The Lord is with you."
privilege. This was a shocking announce to Mary for several reasons. I certainly was a surprise to have an angel appear to her with this message. Although she respected and honored the Word of God it still was a big surprise and unsuspected by her.
She received some assurances from the angel as he delivered this message to Mary. He comforted her by saying his message came for God as she was chosen for a very special purpose. The purpose was to bear a son names Jesus. Then the fact that Jesus would be great and known as the Son of the most High. He will ultimately be given by God the David and will eventually reign over the house of Jacob. The reign of Jesus will have no end. Today we look forward to this promise and expect it to be filled as Jesus returns to this earth. Mary asked questions and we still ask questions about the reign of Jesus and many of us want it to hapen soon.
36 And consider your relative Elizabeth—even she has conceived a son in her old age, and this is the sixth mnth for her who was called barren.
she had some knowledge of this prophecy but never expected to be the girl to be chosen. The answer she was given was that the Holy Spirit would supply the seed for the promised Son. So this child does not have an earthly father and her child will be called the Son of God. Then the angel gave her the example of how God had allowed her relative Elizabeth to become pregnant. He also made the statement nothing will be impossible with God.


text:
Воловац () насеље је у Румунији у округу Сучава у општини Воловац. Oпштина се налази на надморској висини од 383 -{m}-.

Становништво
Према подацима из 2002. године у насељу је живело 6980 становника.

Попис 2002.

Хронологија

Референце

Спољашње везе

Насељена места у Румунији
Википројект географија/Насеља у Румунији

redpajama_set_name: RedPajamaWikipedia


text:
Borchert Field
Welcome to BorchertField.com, the online museum of the American Association Milwaukee Brewers, 1902-1952
Because Milwaukee was playing baseball long before 1953.
On This Day - "The Camera Beat the Play"
On this day in 1944, the Milwaukee Chicks of the All-American Girls Professional Ball League were playing a double=header at Borchert Field.
They had originally been scheduled to play a four-game series against the Rockford Peaches, but bad weather had forced the cancellation of the first two games (including the initial tilt, when a storm had torn off part of Borchert Field's roof during the seventh inning of a Brewer game). Readers of the Milwaukee Sentinel were treated to this quarter-page ad promoting the games:
The AAGPBL certainly went all-out promoting the Chicks. The Brewers never had this kind of treatment. Of course, with four decades of history behind them, the Brewers didn't exactly need it.
So with the skies cleared and the storm damage cleared away, the games could resume. Although the Chicks might have wanted just one more rain check.
Is there anything more exciting than a play at the plate? The Journal's camera caught this one as it happened, with Chicks backstop Dorothy Maguire guarding the plate.
The camera beat the play Sunday as Jo Leonard of Rockford slid into home plate at Borchert field in the second inning of the first game of a double header with the Milwaukee Schnits of the All-American Girls' Professional Ball League. A second later, Catcher Dorothy Maguire of Milwaukee put the bal on her and Umpire Al Gembler called her out. Milwaukee lost, 6-5.
And talk about "dirt in the skirt". This is how the players got their famous "strawberries", sliding into home plate with only satin tap pants for protection. The sweet-sounding name belied the gruesomeness of the injury, nasty scrapes with dirt ground in.
The Chicks lost the first game 6-5, but managed a split by taking the second and final game of the series, 3-0, on RBI singles from third baseman Doris Tetzlaff and first baseman Betty Whiting.
This brought Milwaukee's record to 10-13, or .435, good for fifth place in the six-team league. The Chicks would have to step up if they wanted a shot at the AAGPBL post-season.
Posted by Chance Michaels at 12:40 PM
Labels: #ChicksOnThisDay, 1940s, AAGPBL
Welcome to BorchertField.com, the only online museum dedicated to the Milwaukee Brewers of the American Association (1902-1952), their ballpark, and all of the other events it hosted.
75 Years of the Chicks
For 2019, we're honoring the Milwaukee Chicks/Schnitts, on this 75th Anniversary summer of both their 1944 AAGPBL Championship and their one and only season.
"Brewer News" Newsletter Archive
Milwaukee Tavern Card Archive
Score Card Archive
"Milwaukee Chicks Night" at Miller Park!
Happy "The Milwaukee Chicks Day"!
The Gang's All Here, 1944
Happy #NationalSunglassesDay, Gladys!
I See You Shiver with An-tici....
"Diamond Lassies", 1944
On This Day - "Autograph, Miss?"
On This Day: Signing the Cast
"Girls of Summer" Merchandise to Come!
On This Day: "An Umpire's View of Girls' Baseball"...
1943 AAGPBL Scorecard on eBay
On This Day - "The Boss Speaks"
On This Day - Raise the Roof
"For the Boss", 1944
On This Day - "We Regret to Inform You"
On This Day - the Chicks Become the Chicks
Julio Acosta, 1944
On This Day - D-Day!
#ChicksOnThisDay (38)
AAGPBL (71)
All-Star Game (4)
around the blogosphere (3)
ballpark concessions (3)
barrelman (18)
baseball cards (2)
batboys (1)
beer barrel man (19)
Bill Veeck (57)
Borchert Field (97)
Brewer Band (2)
Brewer News (12)
Brewer Sportraits (7)
Casey Stengel (19)
championships (43)
Charlie Grimm (38)
Chicks 1944 Retrospective (1)
color photos (9)
County Stadium (6)
farm system (8)
Fatima the Goat (4)
Florence Killilea (3)
historical players (166)
Idabel Borchert (3)
Junior World Series (13)
Kenesaw Mountain Landis (5)
Ladies' Day (4)
letterhead (1)
Major League Namesake (5)
Mickey Heath (21)
Milwaukee Badgers (9)
Milwaukee Bears (9)
Milwaukee Braves (6)
Milwaukee Mollys (3)
Milwaukee Red Sox (2)
Milwaukee semi-pro teams (3)
Modern Museum Exhibitions (10)
National League Brewers (64)
Negro Leagues (7)
Nick Cullop (7)
on this date (8)
Opening Day (39)
other American Association clubs (4)
other sports (22)
Otto Borchert (10)
owgust (47)
ownership (21)
personal remembrances (1)
pocket schedules (15)
political rallies at the Orchard (2)
Red Smith (22)
Rudie Schaffer (2)
score cards (18)
Season Review (3)
spring training (26)
stadium giveaways (1)
streetcars (1)
tavern cards (8)
team photos (30)
team staff (17)
throwbacks (36)
ticket stubs (10)
Vintage Brew (22)
wire photos (19)
Click here to send questions, hot tips or suggestions for future articles.
Tweets by @BorchertField
Chance Michaels is a native New Yorker who spent many of his formative years in Milwaukee and developed a lifelong interest in the region's sporting history. In addition to his work with BorchertField.com, he runs the Green Bay Packers Uniform Database, an ongoing research project devoted to the design history of that other Wisconsin pro team. When not immersing himself in old game programs, wire service photos and newspaper archives, he produces theatre Off-Off-Broadway, and was formerly a contributor to The Onion. He lives in New York City with his family.
Paul Tenpenny was born, raised in and is proud to be a citizen of Milwaukee, Wisconsin. Paul lives within walking distance of Miller Park and its predecessor, Milwaukee County Stadium. A lifelong collector of various antiques and collectibles, he specializes in Milwaukee and Wisconsin related Sports and Historic Memorabilia. Paul has been writing articles on Milwaukee Sports collectibles since 2007 and is in his 3rd year of writing his popular Vintage Brew series. An active member of SABR and its local Ken Keltner chapter, his memorabilia has been displayed at both the Milwaukee Historical Society, the Milwaukee Public Library and the Wisconsin State Historical Museum.
Dennis Pajot is a life long resident of Milwaukee, who enjoys as a hobby researching Milwaukee baseball. He is an active member of SABR, both the local Ken Keltner chapter and the national group. His Milwaukee baseball publications include "The Rise of Milwaukee Baseball: The Cream City From Midwestern Outpost to the Major Leagues, 1859-1901" (McFarland & Company, 2009) (Winner - 2010 Sporting News-SABR Baseball Research Award) and "The Greatest Baseball Game Ever Played Anywhere" (Wisconsin Magazine of History, Spring 2009) detailing an 1899 baseball game in Milwaukee between City of Milwaukee officials and State of Wisconsin officials to help the sufferers of a tornado in New Richmond, Wisconsin.
All content written by Chance Michaels unless otherwise noted. All original material is copywrighted by the respective authors and published here by permission.
All team and league information, sports logos, sports uniforms and names contained within this site are properties of their respective leagues, teams, ownership groups and/or organizations, and may not be reproduced in any form without the permission of said entity. Copyrighted material is presented here under "fair use" and all attempts have been made to credit copyright holders. If you are the owner of any images presented here and wish to have them credited or removed, please contact us.
This site is maintained for research and historical purposes only. Any information obtained from this site may not be sold to any third parties.

redpajama_set_name: RedPajamaCommonCrawl


Writing Tutoring in Santa Monica, California.
Our office provides in home and online writing tutoring services in the following locations including Santa Monica, Venice, Oakwood, Ocean Park, Wilshire Montana, North of Montana, Mid-City, Northeast, West Gate Heights, Sawtelle and Picoin California.
Writing, which is one of the most critical background skills in life has been largely underdeveloped across the United States from grades k-12. However, with the help of a Club Z! Tutoring of Santa Monica, CA writing tutor, we can help you or your student get the writing grades they deserve. We understand how challenging writing may be for students across the United States. For the past 20+ years, Club Z! tutoring has been helping students learn how to write properly and coherently. Club Z! offers a proprietary in-home and online writing tutoring curriculum designed to help students in grades 5-12 improve and master writing skills for a lifetime! The Power of Words© is a highly effective writing tutoring program which teaches students everything from how to write well thought out paragraphs and journal entries, to how to write efficiently for timed essays.
Club Z! Tutoring of Santa Monica, CA writing tutors will tailor a specific writing strategy to each individual child and will work with both parents and teachers to ensure success. Club Z! writing tutors will help your student learn to write and ultimately master writing skills such as: Spelling, Grammar, Punctuation, Sentence Structure, Singular & Plural, Past & Present Tense, Parts of Speech, Creative Writing, Critical Writing.
In addition to Santa Monica, our office offers writing tutoring services in the following locations: Santa Monica, Venice, Brentwood, and Pacific in California.
To learn more about our proven in-home and online writing tutoring programs or to connect with one of our experienced writing tutors, fill out the form above or call Club Z! today at 424-214-0709.


text:
Interview: Local Natives
Features, Interviews, Local Natives — By Shannon Hutchison on September 7, 2010 2:09 pm
I re-he-heally hope that Andy from Local Natives has a Bluetooth, because if not, we were breaking
the law together today, and not in a cool way you want to tell people about when you're drinking. In a
ticket-getting way.
I got to chat with Andy Hamm, bassist, vocalist, writer, percussionist, etc. etc. etc…(more on that later)
of Local Natives, a folk-ish (although he says that they don't necessarily consider themselves folk. "I
think every time someone hears a three part harmony, they automatically consider it folk…we're kind
of all over the place…and still learning what our sound is.") band based out of LA on the phone today
while he was driving. He kept it together pretty well, and I never heard sirens, so I'm pretty sure he had
a Bluetooth.
[mp3 keywords="Local Natives" tag="coumuspri-20″ width="336″ height="280″ ]
Based on popular media, urban legend and stuff I heard from my cousin's friends, I was under
the impression that Local Natives basically magically became popular overnight, so when Andy
told me it was "actually sort of the opposite," I was initially surprised. Then he told me how they
actually hit it big, and I'm here to tell you is actually was sort of magical, even if it wasn't overnight.
The band had been writing and playing for a few years, trying to make their way, and at the point that
it all came to a head, Andy "…was working full time, a couple of guys were in school, another guy was
working full time," and they were "not happy with solutions from other people…you know, promotions
and other industry crap." So they decided to move to LA and totally take control of their own destinies.
"We're a total DIY band," Andy says, "…online, blogs, artwork…" they basically own it. The bad had
a collection of songs, many of which ended up on their debut album, Gorilla Manor, they decided to
quit jobs and school, they played the "right shows," and sent their music to the "right people" (he just
said "right," and I didn't ask what he meant, because, I mean, they obviously were "right"—look at
them now!), and here they are, just a few years later. So Andy may say "we really got lucky," but to
me…magic. Basically every guy I went to high school with was in a band that tried to make this happen,
but it didn't work out for them like it did for Local Natives.
At this point, Andy said something that I could not understand, then "Sorry…I'm driving." I get it. I'd like
to think he was rushing to some super important recording session just so I could say I was a part of that
drive right before they recorded that song that was THE BIGGEST SONG!!!!, but it was probably to get a
breakfast burrito. It was sort of early.
Another piece of Local Native lore that I'd heard is that they're really, really collaborative. Not like "we
have a band of five, and everyone is a part of the band!" collaborative…like "everyone does everything
for every song" collaborative. And that is also true. "Yeah, we definitely do it all together…everybody
has a hand in it." Andy described their creative process just as that—someone comes to the table with
one piece (lyrics, a chord progression, a melody) and from there, they work it out until they have a song.
"It's like we all have a stake in it…it really increases the level of accomplishment…" since everyone is
involved. At this point, Andy asked "Do you want me to go in here?," and once I realized he wasn't talking
to me, I imagined they had just arrived at the super important recording session (or the burrito shop).
As always, I like to hear the stories behind my favorite songs, and I wasn't disappointed when I asked
about how World News came about. "Actually, it started off almost as a joke," Andy remembered.
"Kelsey [Ayer, vocalist, keyboard and more] wrote those lyrics," and they had a melody that Andy
described as "uppity" and like "circus music…" In fact, "I think we called it Circus Time at first." After
trying to figure out where they were going with the song, they took it into the studio, and Kelsey, Andy
and Matt Frazier (the usual percussionist), were all on drums, and "that's when we really got it."
And that really seems to sum up Local Natives—they each bring their own ideas to the table, laugh
about it for a while, take it to the studio, and something amazing comes out. I have a feeling that they
won't be playing the side tents at festivals for long.


text:
@protocol RGBColorSliderDataOutlet;

@interface RGBColorSliderDelegate : NSObject <RGBColorSliderDelegate>

/// The delegate's delegate.  Used to report the aggregate color from all the sliders when they change.
@property (nonatomic, weak) id<RGBColorSliderDataOutlet> delegate;

/// Mutable array holding the colorvalues.        Functions as a dictionary using objectAtIndex:(RGBColorType). @see RGBColorSlider.h for RGBColorType definition
@property (nonatomic, strong) NSMutableArray *colorComponentsArray;

@property (nonatomic, strong) RGBColorSlider *redSlider;
@property (nonatomic, strong) RGBColorSlider *greenSlider;
@property (nonatomic, strong) RGBColorSlider *blueSlider;
@property (nonatomic, strong) RGBColorSlider *alphaSlider;

//// Delegate methods //////////////////////////////////////////////////////////////////////////////////////////
- (void)slider:(RGBColorSlider *)sender valueDidChangeTo:(float)value forSliderColor:(RGBColorType)color;
- (void)connectSlider:(RGBColorSlider *)sender toColor:(RGBColorType)color;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

- (void) setMaxSliderTrackImage:(RGBColorSlider *)slider forColor:(RGBColorType)color;
- (void) setMinSliderTrackImage:(RGBColorSlider *)slider forColor:(RGBColorType)color;

//// Use these methods to retrieve color data instead of waiting for -updateColor: ////////////////////////////
- (UIColor *)getCurrentColor;
- (float)getRedColorComponent;
- (float)getGreenColorComponent;
- (float)getBlueColorComponent;
- (float)getAlphaComponent;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

@end

@protocol RGBColorSliderDataOutlet <NSObject>

@required
- (void)updateColor:(UIColor *)color;

@end

redpajama_set_name: RedPajamaGithub


a sanctuary for Yoga, Meditation and Healing. Enjoy the serenity of the beautiful pond outside the large picture windows as you share space with liked minded souls looking to enrich their bodies and minds.
Inside you will find a schedule filled with all levels of yoga, ayurvedic traditions, holistic nutrition, children and family programming, meditation, personal healing services such as Reiki, Akashic Records, Chakra Harmonizing, Numerology, workshops, international retreats, Yoga Alliance Teacher Trainings and so much more to stimulate your mind, nurture your heart and invigorate your body!
With classes like Prana Yin/Yang, Prana Fusion, Prana Healing Circle, and Prana Alignment you will be sure to find the class that speaks to you. Discover your potential with the guidance of experienced and caring instructors ready to take you to the next level!
We offer services that promote mental, physical, and emotional health. Reiki, Prana Healing, Thai Bodywork and the LEAF Program are just a few of the ways we improve health and well being.
Live your best, healthiest life possible with our many events at The Prana Lab. We offer Feel Good Fridays, Mindfulness Meditation Circle, Akashic Records, Goddess Belly Dancing, and more!
Get your Hatha Yoga Teacher Training, become registered with Yoga Alliance to teach Children's Yoga, or connect with mothers on their journey as a Prenatal Yoga Teacher with our many certifications.
We enjoy providing you a serene retreat location.
Please be sure to follow a few simple requirements to maximize yours and others experience.
Place shoes in cubbies outside the studio.
If you need to leave class early please notify the instructor, practice near the exit and leave quietly.
Fatigue, back pain and stress are all commonly found in many workplaces and can lead to reduced productivity and employee absenteeism. Yoga has been proven to reduce headaches, stress, hypertension and depression and can help increase employee morale.
Conveniently located in Weston Florida, Prana Lab provides a sanctuary for Yoga, Healing, Meditation and Wellness. We would like to share this gift with you, in your office or meeting space, creating a sense of community by providing physical exercise and mental stimulation for your employees by bringing yoga into the workplace. For more info and to schedule a program at our facility or yours please contact our corporate director at info@pranalabyogastudio.com.
The Casey's Fund mission is to provide fully funded camperships,including transportation, to the Big Sky Kids Cancer Camp Young Adult Retreat.
The Fund is endowed and is managed by Eagle Mount, the parent organization of Big Sky Kids Cancer Camps.


text:
About RTA ›
Dec. 19: Vernon Jones Blues Cartel will play at Tower CIty
The Vernon Jones Blues Cartel was the crowd favorite for this year's Transit Tracks program. Listen to them play at Tower City, from 3:30-6:30 p.m. Thursday, Dec. 19.
Dec. 17: Agenda for Board Meeting
The RTA Board of Trustees meet at 9 a.m. Tuesday, Dec. 17, 2013, in the George F. Dixon, III Board Room, 1240 W. Sixth St., Cleveland, OH 44113.
Dec. 10: RTA's Executive Records Management Committee meets
RTA's Executive Records Management Committee meets at 11 a.m. Tuesday, Dec. 10, 2013, in the George F. Dixon III Board Room, 1240 West 6th St., Cleveland, OH 44113.
Dec. 3: Highlights from Board Committee meetings
RTA Board Committees met Dec. 3. All agenda items passed, including a pilot program to provide a U-Pass program for Tri-C students.That goes to the full Board on Dec. 17.
Dec 10-11: RTA unveils new Red Line cars
RTA displays its first renovated Red Line rail car on from 1 p.m. Tuesday, Dec. 10, through 7 p.m. Wednesday, Dec. 11,. in Tower City.
RTA urges pedestrians: Stay safe this holiday season
RTA wants you to have a safe Holiday season. Transit Police and Cleveland Police offer these tips to stay safe on vehicles, at stations and on the roads.
RTA partners with Tri-C for U-Pass
RTA and Cuyahoga Community College (Tri-C®) will offer eligible Tri-C students a U-Pass for unlimited RTA rides during qualifying semesters.
Dec 15: Quarterly Service Adjustments, evening service added
RTA adjusts its service quarterly: The next change will affect 30 routes on Dec. 15, 2013. This adjustment has lots of improvements for riders.
Dec. 3: Agenda for RTA Board Committee Meetings
Committees of the RTA Board of Trustees meet at 9 a.m., Tuesday, Dec. 3, 2013, at 1240 W. Sixth St., Cleveland, OH 44113.
Pick your favorite Transit Tracks artist for December encore performance
RTA is completing its pilot year of Transit Tracks. Help select the fan favorite to play on Dec. 19, 2013 at Tower City. This music program brings free music to RTA customers.


text:
De Primera División 1967/68 was de 37e uitvoering van de hoogste betaaldvoetbalafdeling in Spanje. Het seizoen begon op 9 september 1967 en eindigde op 28 april 1968. Real Madrid werd voor het tweede jaar op rij landskampioen.

Eindstand

Pos = Positie ; Wed = Wedstrijden ; W = Winst ; G = Gelijk ; V = Verlies ; DV = Doelpunten voor ; DT = Doelpunten tegen ; DS = Doelsaldo ; P = Punten

Córdoba CF en Real Sociedad handhaafden zich na het spelen van degradatieduels.

Uitslagen

Groen : Thuisteam heeft gewonnen
Blauw : Gelijkspel
Rood : Uitteam heeft gewonnen

Topscorers
De Pichichi-trofee wordt jaarlijks uitgereikt aan de topscorer van de Primera División.

Primera División
Competitievoetbal 1967/68


Map My Run is a handy app on my phone that logs all my workouts. It records my distance, duration time, average pace, split-pace times, calories burned and elevation gain. These details are very important as I reach out for my goals in preparation for the next race or just to keep in shape.
How do you track your growth in Christ?
As you read the Word each day, where do you record what God said to you?
When you attend church, how do you document what God is up to in your life during the service whether in singing, prayer, small group Sunday School or the preaching?
What has the Lord been teaching you in the school of trials and temptation?
How have you seen God answer prayer today?
What spiritual goals have you attained by the grace of God?
What sins have your overcome?
What victories have been won by faith and God's grace?
We are prone to soon forget the blessings of God, the impact of His Word, and the lessons He brings, but not so if we record them in a journal and then scan over them each week. Our Shepherd is leading us today (Psalm 23). Let's track His steps and His lessons in our lives. The Christian life is not a sprint but a marathon. Let's run well in His Word, burning off the calories of sin, the flesh and the world, and keep a good pace through all the elevations of life as we run for the prize.
I have fought the good fight, I have finished the race, I have kept the faith. Henceforth there is laid up for me the crown of righteousness, which the Lord, the righteous judge, will award to me on that Day, and not only to me but also to all who have loved his appearing (2 Timothy 4:7-8).


Success. We found Canadian Aircraft IFQT in the National Airplane Title Database. The IFQT is for a Advanced Ultra-light of the Aeroplane category and was manufactured by Canadian Ultralight Manufacturing Ltd..
IFQT is a 01/01/1998 Canadian Ultralight CHINOOK PLUS 2 (Aeroplane) used for Private purposes. If it was imported into Canada, then the date of import would be listed .
Our Aircraft decoder found that IFQT belongs to a Canadian Ultralight CHINOOK PLUS 2 with a serial number of 2142 and 1 engines made by the engine maker ROTAX SERIES to be an engine-type of Piston.
The number of seats on this aircraft was counted as 2 seats so it can actually take off with 431 kilograms of weight.
IFQT has its 'home' airport in Salmon Arm and is currently Registered with a status of A (A for active). The owner is a Individual with the name William G Hansen and has a street address in British Columbia, CANADA: 2330 8 Ave SE, Salmon Arm, V1E2H8.
What is the engine of IFQT? The DATE_BUILT Canadian Ultralight CHINOOK PLUS 2 has 1 ROTAX SERIES engines.
Who is the owner of mark IFQT? The owner of mark number IFQT is William G Hansen .


Deputy Prime Minister Gen Prawit Wongsuwan.
Bangkok – Deputy Prime Minister Gen Prawit Wongsuwan says the ban on political activities could be lifted after December 11.
Gen Prawit spoke this week of the recent meeting between the so-called five rivers and political parties, which some parties had refused to attend. He said he was not concerned about their absence as he believes those parties will follow election rules.
After the lifting of the ban, he said parties will be able to campaign for votes, although any distortion of facts will face punishment. As for calls for Gen Prayut to step down if he wishes to run for office, Gen Prawit said he won't be able to do so because he is head of the NCPO, which will remain in power until the formation of the new government.


A 5-minute walk from Pratunam Centre, Lemontea Hotel offers comfortable rooms with air conditioning. It has an on-site restaurant and free WiFi in all areas, which is available throughout the hotel.
Lemontea Hotel is less than a 10-minute walk from Pantip Plaza IT Mall. It is a 5-minute drive from Central World Department Store and a 40-minute drive from Suvarnabhumi International Airport.
Bright and airy rooms are equipped with a flat-screen cable TV, a fridge and a safety box. En suite bathrooms are fitted with shower facilities.
For convenience, the hotel provides a 24-hour front desk, parking and safety deposit facilities. Guests can relax with leisure activities at the garden areas.
Enjoy delicious Thai cuisine served at Biscuit Bar & Restaurant.
Please note that this is a non-smoking property. Smoking is not allowed in all public areas and guest rooms, including balconies and bathrooms. There is a designated smoking area in front of the hotel.
Air-conditioned room offers a flat-screen cable TV, a fridge and a safety box. En suite bathroom comes with shower facilities.
Rate: THB 2190.00 ... THB 5282.00; select dates below to get current rates.
Larger air-conditioned room features a sofa seating area. It includes a flat-screen cable TV, a fridge and a safety box. En suite bathroom comes with shower facilities.
This twin/double room has a balcony, air conditioning and seating area.


text:
Q: Convert SVG file to multiple different size PNG files I have a logo image in SVG format and I am wondering if theres a way to generate multiple different sized png files.
Eg, I set 20 different width and height and it generates 20 PNG files. It okay if I have to do it 5  images at a time.
I have illustrator installed and cant figure out how to do this on it.
Thanks for all of your help!

A: The accepted answer is fine. There is an official help on options available.
Also basic Shell commands will do nicely here:
for x in 10 100 200 ; do inkscape --export-png logo${x}.png -w ${x} logo.svg ; done

On the command line in windows use this line from @avalancha in the comments
for %x in (100 200 300) ; do inkscape --export-png logo%x.png -w %x logo.svg ; done

A: Take a look at inkmake. I actually made that tool just for batch exporting SVG files to PNG etc in different sizes. It was design because I wanted to save in Inkscape and then just run inkmake in a terminal and it will export all depending PNG files.

A: If you haven't already, install imagemagick.  On OSX, that requires rsvg support specifically:
brew install imagemagick --with-librsvg

You also need inkscape, otherwise you may find that your images come out all black (except for transparent areas).
brew install homebrew/gui/inkscape

Then, you should be able to convert as follows:
convert -density 1536 -background none -resize 100x100 input.svg output-100.png

The 1536 is a workaround for something I'm not able to find good answers to.  In my experiments, omitting the -density argument creates images that are terribly small.  Converting an image to -size 100x100 at -density 1024 gives me an output image of 96x96, so what I'm doing instead is overshooting on the density and resizing down to the target size.

TL;DR use a density that is 1500 times larger than your target size, and go from there.

There are many ways to bulk-run that command.  Here is one in the shell:
for s in 10 100 200 ; do convert -density 1536 -background none -resize ${s}x${s} input.svg output-${s}.png ; done

A: I don't know about Illustrator, but this should be easy using the Inkscape command line options. For example, using Ruby:
$ ruby -e '[10,100,200].each { |x| `inkscape --export-png logo#{x}.png -w #{x} logo.svg` }'

A: Here's how to make it much faster (3x for me for just 5 exports on an SSD) by launching Inkscape just once, and how to export the images to different directories (as Android uses):
#!/bin/sh
# Converts the Inkscape icon file ic_launcher_web.svg to the launcher web & app png files.

PROJECT="My Project Name"
INPUT="source-assets/ic_launcher_web.svg"
MAIN="${PROJECT}/src/main/"
RES="${MAIN}res/"
DRAWABLE="${RES}/drawable"

inkscape --shell <<COMMANDS
  --export-png "${MAIN}ic_launcher-web.png"         -w 512 "${INPUT}"
  --export-png "${DRAWABLE}-mdpi/ic_launcher.png"   -w  48 "${INPUT}"
  --export-png "${DRAWABLE}-hdpi/ic_launcher.png"   -w  72 "${INPUT}"
  --export-png "${DRAWABLE}-xhdpi/ic_launcher.png"  -w  96 "${INPUT}"
  --export-png "${DRAWABLE}-xxhdpi/ic_launcher.png" -w 144 "${INPUT}"
quit
COMMANDS

This is a bash shell script. On Windows you can run it in MINGW32 (e.g. GitHub's Git Shell) or convert it to a Windows DOS shell script. (For a DOS script, you'll have to change the "here document" COMMANDS into something DOS can handle. See heredoc for Windows batch? for techniques such as echoing multiple lines of text to a temp file.)

A: Based on zany's answer but updated to handle Inkscape 1.1 which requires the -o option for output filename and --export-type as opposed to --export-png to declare your export type.
for x in 10 100 200 ; do inkscape --export-type=png -o logo${x}.png -w ${x} logo.svg ; done

A: I created a tool to do exactly that. You can define which output sizes you want, and their folder structure. So it's as easy as just running it on your folder with svg files, and then png files are added to your project in correct folders.
https://github.com/Inrego/SvgToPng
I hope it's helpful.

A: I used the below command to create the icons for Angular PWA.
First "cd" into the inkscape installation folder before running the below command in windows command prompt.
for %x in (72 96 128 144 152 192 384 512) ; do inkscape --export-filename=C:\temp\icons\icon-%xx%x.png -w %x -h %x "{filePath}\{fileName}.svg"

A: On Ubuntu 20.04 with Inkscape 1.1.1 (eb90963e84, 2021-10-02) this generates 6 images with different resolutions (32x32, 64x64, etc) from icon.svg:
for x in 16 24 32 48 64 256 ; do inkscape --export-type="png" --export-filename=${x}x${x}.png -w ${x} -h ${x} icon.svg ; done

You can add or remove resolutions by adding elements (separated with spaces) right for x in <here> ;.
Remember this always will generate square images (same width and height).
Change icon.svg to your .svg file and to change the output filenames change --export-filename=<this> to the filename you want.
TIP: use ${x} to get the current resolution (32, 64, etc.).

redpajama_set_name: RedPajamaStackExchange


As yoga studio businesses are raking in big profits for owners and becoming a popular business option, both the challenges and competition for new or struggling studios are increasing. Even a small mistake can be significant enough to cause your business to stumble and lose track. But now you can write your own script for a successful yoga studio, with sure-to-succeed yoga studio blue prints, yoga studio business advice and consultations from Centered Business.
Coach Al Lipper, the man who has guided many yoga studios to flourishing starts and highly successful expansions is ready to be your business mentor so that you are sure to hit the target right from the start. Al has been studying yoga studio businesses for years. He has observed their success tactics and has interviewed many highly successful yoga studio business owners in order to get insight into their secrets of success. The outcome of his study is a well-crafted yoga studio success manual for starting a yoga studio business with easy to follow guidelines, a studio workbook and expert consultation on the possible issues that you might face.
Al Lipper has identified the key strategic tips and yoga studio business advice for current or hopeful studio owners so they can simply implement these tips to start, evolve or expand their yoga studio business successfully. So get your yoga studio success manual from Centered Business and take the first step toward a new venture as a successful yoga studio entrepreneur.


text:
Places to go / Paris /
Art Deco : Majestic but functional department stores
© JONATHAN - Fotolia.com
True cathedrals of commerce, Parisian department stores switched from Art Nouveau to Art Deco in the 1920s. Products were better showcased and the functionality of the store also taken into account.
Created in the mid-19th century, Parisian department stores offered a wealthy clientele a large variety of products. Architects and engineers (including Gustave Eiffel) used glass and iron domes and skylights to bring light into the lobbies, used as large retail spaces. Art Nouveau, its decorative luxury, its curved lines, its reference to plants and femininity appeared as the best way to decorate these large new retailing spaces, such as the department stores of the Louvre district, La Samaritaine, Printemps or the Galeries Lafayette. In the 1920s, these vast stores asked architects to renovate their retailing spaces. The goal was to redesign the store to better showcase the new products. The economic environment was very favourable and goods were produced on a much larger scale. With its straight lines and its taste for symmetry, Art Deco then became the latest trend, as it was both attractive and functional.
Captivated by the new designs presented at the International Exhibition of Decorative Arts in 1925, some department stores decided to create Art Deco buildings: Le Bon Marché (by Louis-Charles Boileau), the Galeries Lafayette (by Jean Hiriat, Georges Tribout and George Beau) or La Samaritaine (Henri Sauvage). Having since become a commercial centre, the Trois Quartiers (Madeleine) created in 1829, were rebuilt in 1932 in the style of the time by architect Paul-Louis Faure-Dujarric. The lobby was enlarged and the stairs and elevators made more accessible. The straight columns and large windows of the facade became the traditional features of this new architectural style. These large glass roofs and these facades with the structure showing can also be found at La Samaritaine, near the Pont Neuf. Fifty years after its opening, Henri Sauvage was entrusted with the renovation of this glass roofed building. The structure was covered with light coloured stone, with no mosaics and frescoes on the front, creating a square and massive building characteristic of Art Deco.
The restoration of the buildings used the technical progress of the time: better lighting, better electric ventilation and escalators. Le Bon Marché, in the 7th district, is particularly impressive. The facade of the store, slightly curved, with its sleek design based on geometric shapes, is particularly representative of Art Deco. The light flows in through the majestic white and gold windows that illuminate the large central lobby. As for the Galeries Lafayette, in the 9th district, they were renovated by Pierre Patout. Opting for an original approach, he chose to create windowless facades (no longer visible today), so that customers' attention was entirely focused on the products on sale. The only openings are long vertical bow windows created by the Lalique workshops. With its tall chimneys adorning the roof, the innovative style of its facade was inspired by cruise ships.
Prepare your stay in Paris-Île de France (External link)
Discover the Printemps story (External link)
Discover the Galeries Lafayette (website in French) (External link)
Discover Le Bon Marché (External link)
Discover La Samaritaine (External link)
FACEBOOK - Paris Tourisme (External link)
TWITTER - Paris Tourisme (External link)
FACEBOOK - Printemps (External link)
FACEBOOK - Galeries Lafayette (External link)
"Toulouse-Lautrec - Resolutely Modern" exhibition at the Grand Palais in Paris
Leonardo da Vinci exhibition at the Louvre, Paris
Until February 24
"Tolkien, A Journey to Middle-Earth" exhibition in Paris
"Versailles Revival - 1867-1937" exhibition
Until March 15
Exhibition: 'Marie-Antoinette: Metamorphoses of an Image' at the Conciergerie in Paris
Discover Paris
Exhibitions, musicals, lights...
Top family outings in Paris this winter
Exhibitions, musicals, light—in the winter, in Paris and the Paris region, the Tuileries Garden…
French art de vivre
Sneek-peak of the Domaine Royal de Marly museum
After three years of work, the museum of the Domaine Royal de Marly will reopen on November 30,…
Seasonal delights
8 essential autumn products in the Parisian…
Which fruits and vegetables are in season when autumn shows up? Local produce changes according to…
Delphine Plisson: a passion for local products
Delphine Plisson made groceries fashionable four years ago. Last year, she opened her second online…
The Grand Palais unveils its temporary structure
The Grand Palais will temporarily relocate to the base of the Eiffel Tower at the beginning of 2021…
7 must-dos in Paris this autumn
Leaves are turning, the sky is changing and the Seine is bathed in a new light... autumn is…