text:
extern std::mutex                       mboxLock;
extern std::vector<std::pair<int, int>> mbox;
extern std::condition_variable          mbox_cv;

namespace {
        [[maybe_unused]] std::atomic<bool> bootstrap_failed{false};
}

int rebuild_segment(const char *);

int Service::start(int argc, char **argv) {
        static constexpr bool trace{false};
        sockaddr_in           sa;
        int                   r;
        struct stat64         st;
        size_t                totalPartitions{0};

        this_service = this;
        startup_ts   = time(nullptr);

#ifndef LEAN_SWITCH
        // See: https://github.com/markpapadakis/BacktraceResolver
        Switch::trapCommonUnexpectedSignals();
#endif

        if (argc > 1 and !strcmp(argv[1], "verify")) {
                // https://github.com/phaistos-networks/TANK/wiki/Managing-Segments-files
                return verify(argv + 2, argc - 2);
        }

        prom_endpoint.unset();

        if (argc == 1) {
                goto help;
        }

        while ((r = getopt(argc, argv, "p:l:hvP:rC:R:")) != -1) {
                switch (r) {
			case 'R':
				return rebuild_segment(optarg);

                        case 'C': {
                                auto [id_repr, cluster_name] = str_view32::make_with_cstr(optarg).divided('@');
                                str_view32 endpoint_repr;

                                if (const auto p = cluster_name.Search('|')) {
                                        endpoint_repr = cluster_name.SuffixFrom(p + 1);
                                        cluster_name.set_end(p);
                                }

                                if (!id_repr or !id_repr.all_of_digits()) {
                                        Print("Invalid cluster ID\n");
                                        return 1;
                                } else if (!cluster_name or cluster_name.size() > 32) {
                                        Print("Invalid cluster name\n");
                                        return 1;
                                }

                                const auto cluster_id = id_repr.as_uint32();

                                if (cluster_id > std::numeric_limits<uint16_t>::max()) {
                                        Print("Invalid cluster node id, allowed values [0, ", std::numeric_limits<uint16_t>::max(), "]\n");
                                        return 1;
                                }

                                cluster_state._name_len = cluster_name.size();
                                cluster_name.CopyTo(cluster_state._name);
                                cluster_state.local_node.id = cluster_id;

                                if (!endpoint_repr) {
                                        consul_state.srv.endpoint.addr4 = IP4Addr(127, 0, 0, 1);
                                        consul_state.srv.endpoint.port  = 8500;
                                } else {
                                        const auto e = Switch::ParseSrvEndpoint(endpoint_repr, {}, 8500);

                                        if (!e) {
                                                Print("Unable to parse Consul Agent endpoint ", e, "\n");
                                                return 1;
                                        }

                                        consul_state.srv.endpoint = e;
                                }

                                if (int fd = open("tank_consul.token", O_RDONLY); - 1 == fd) {
                                        Print(ansifmt::color_red, "Failed to access tank_consul.token: ", ansifmt::reset, strerror(errno), "\n");
                                        Print("The consul agent API token should be stored in that file so that interfacing with the Consul Cluster can be accomplished.\n");
                                        return 1;
                                } else if (const auto file_size = lseek(fd, 0, SEEK_END); file_size == 0 or file_size > 64) {
                                        TANKUtil::safe_close(fd);
                                        Print("Not valid consul agent API token found in tank_consul.token.\n");
                                        Print("That file should only contain a valid consul API token\n");
                                        return 1;
                                } else {
                                        char buf[file_size];

                                        if (pread(fd, buf, file_size, 0) != file_size) {
                                                Print(ansifmt::color_red, "Failed to access tank_consul.token: ", ansifmt::reset, strerror(errno), "\n");
                                                TANKUtil::safe_close(fd);
                                                return 1;
                                        }

                                        const auto token = str_view32(buf, file_size).ws_trimmed();

                                        memcpy(consul_state._token, token.data(), token.size());
                                        consul_state._token_len = token.size();
                                        TANKUtil::safe_close(fd);
                                }
                        } break;

                        case 'r':
                                read_only = true;
                                break;

                        case 'P':
                                prom_endpoint = Switch::ParseSrvEndpoint(str_view32::make_with_cstr(optarg), "http"_s8, 9102);
                                if (not prom_endpoint) {
                                        Print("Failed to parse endpoint for prometheus metrics from ", optarg, "\n");
                                        return 1;
                                }
                                break;

                        case 'p':
                                basePath_.clear();
                                basePath_.append(strwlen32_t(optarg, strlen(optarg)));
                                break;

                        case 'l':
                                tank_listen_ep = Switch::ParseSrvEndpoint(str_view32::make_with_cstr(optarg), _S8("tank"), 11011);
                                if (not tank_listen_ep) {
                                        Print("Failed to parse endpoint from ", optarg, "\n");
                                        return 1;
                                }
                                break;

                        case 'h':
                        help:
                                Print("Usage: ./tank <settings> [-h] [-v] [-C <spec>]\n\n");
                                Print("Settings:\n");
                                Print(Buffer{}.append(align_to(5), "-p <path>"_s32, align_to(24), "Specifies the base path for all TANK data"_s32), "\n");
                                Print(Buffer{}.append(align_to(5), "-l <endpoint>"_s32, align_to(24), "Specifies the endpoint to to listen for incoming connections."_s32), "\n", Buffer{}.append(align_to(24), "Endpoint notation is [address:]port"_s32), "\n");
                                Print(Buffer{}.append(align_to(5), "-C <spec>"_s32, align_to(24), "Have this node join a TANK cluster. spec notation is nodeid@cluster_name"_s32), "\n", Buffer{}.append(left_aligned(24, "This is how TANK clusters are built. One or more TANK nodes can form clusters. Multiple TANK clusters can be defined. Each TANK node is identified by a unique node id that is specified using this option.\nCurrently, Consul is supported for leadership election and metadata storage, so TANK will connect to the local Consul node.\nFor more information about Consul, please see https://www.consul.io/ and TANK's Documentation"_s32, 76), "\n\n"));

                                Print("\nOther Options:\n");
                                Print(Buffer{}.append(align_to(5), "-v"_s32, align_to(24), "Enable verbose messages output"_s32), "\n");
                                Print(Buffer{}.append(align_to(5), "-h"_s32, align_to(24), "This help message"_s32), "\n");
                                Print("\n\nExamples:\n");
                                Print(Buffer{}.append(left_aligned(7, "./tank -p /data/TANK -l :11011 :Starts a TANK node where the TANK data files are stored in /tmp/TANK and accepts requests at localhost:11011"_s32, 76)), "\n\n");
                                Print(Buffer{}.append(left_aligned(7, "./tank -p /data/TANK -l 10.5.5.10:11011 :Starts a TANK node where the TANK data files are stored in /tmp/TANK and accepts requests at 10.5.5.10:11011"_s32, 76)), "\n\n");
                                Print(Buffer{}.append(left_aligned(7, "./tank -p /data/TANK -l 10.5.5.10:11011 -C 1@my_cluster: Starts a TANK node where the TANK data files are stored in /tmp/TANK and accepts requests at 10.5.5.10:11011, and joins or creates the TANK cluster 'my_cluster'\nThe node maybe become the cluster leader and may replicate data from existing topic parttiions immediately. Please see TANK's documentation for Clusters terminology and guides"_s32, 76)), "\n");
                                return 0;

                        case 'v':
                                Print("TANK v", TANK_VERSION / 100, ".", TANK_VERSION % 100, ", (C) Phaistos Networks, S.A | http://phaistosnetworks.gr/\n");
                                Print("You can always get the latest release from the GitHub hosted repository at https://github.com/phaistos-networks/TANK\n");
                                return 0;

                        default:
                                return 1;
                }
        }

        if (not tank_listen_ep) {
                Print("Listen address not specified. Use -l address to specify it\n");
                return 1;
        } else if (cluster_aware() and tank_listen_ep.addr4 == INADDR_ANY) {
                Print("Expected address:port for cluster aware TANK mode\n");
                return 1;
        }

        if (trace) {
                SLog("cluster_aware() = ", cluster_aware(), ", basePath_ = ", basePath_, "\n");
        }

        curTime = time(nullptr);

        if (basePath_.empty()) {
                Print("Base path not specified. Use -p path to specify it\n");
                return 1;
        } else if (stat64(basePath_.data(), &st) == -1) {
                Print("Failed to stat(", basePath_, "): ", strerror(errno), ". Please verify base path\n");
                return 1;
        } else if (!(st.st_mode & S_IFDIR)) {
                Print(basePath_, " is not a directory\n");
                return 1;
        } else if (!cluster_aware()) {
                try {
                        // We will parallelize this across multiple threads so that we can support many thousands of topics and partitions
                        // without incurring a long startup-sequence time
                        const auto                                                        basePathLen = basePath_.size();
                        std::vector<std::pair<topic *, size_t>>                           pendingPartitions;
                        uint64_t                                                          before;
                        simple_allocator                                                  a{8192};
                        std::vector<strwlen8_t>                                           collectedTopics;
                        std::mutex                                                        collectLock;
                        std::vector<std::pair<std::pair<strwlen8_t, uint16_t>, uint64_t>> cleanupCheckpoints;
                        char                                                              fullPath[PATH_MAX];

                        if (trace) {
                                before = Timings::Microseconds::Tick();
                        }

                        if (trace) {
                                SLog("Attempting to iterate names in ", basePath_, "\n");
                        }

                        Print("Initializing topics and partitions from ", basePath_, " ..\n");

                        try {
                                for (const auto &&name : DirectoryEntries(basePath_.data())) {
                                        if (name.Eq(_S(".cleanup.log"))) {
                                                int fd = open(Buffer::build(basePath_, "/", name).data(), O_RDONLY | O_LARGEFILE);

                                                if (fd == -1) {
                                                        Print(ansifmt::bold, ansifmt::color_red, "Failed to access ", name, ansifmt::reset, ": ", strerror(errno), "\n");
                                                        Print("Aborting Now\n");
                                                        return 1;
                                                }

                                                const auto fileSize = lseek64(fd, 0, SEEK_END);

                                                if (!fileSize) {
                                                        TANKUtil::safe_close(fd);
                                                        continue;
                                                }

                                                auto      fileData = mmap(nullptr, fileSize, PROT_READ, MAP_SHARED, fd, 0);
                                                str_view8 topicName;

                                                TANKUtil::safe_close(fd);
                                                if (fileData == MAP_FAILED) {
                                                        Print(ansifmt::bold, ansifmt::color_red, "mmap() failed", name, ansifmt::reset, ": ", strerror(errno), "\n");
                                                        Print("Aborting Now\n");
                                                        return 1;
                                                }

                                                DEFER(
                                                    {
                                                            munmap(fileData, fileSize);
                                                    });

                                                madvise(fileData, fileSize, MADV_SEQUENTIAL | MADV_DONTDUMP);

                                                for (const auto *p = static_cast<uint8_t *>(fileData), *const e = p + fileSize; p < e;) {
                                                        topicName.Set((char *)p + 1, *p);

                                                        p += topicName.size() + sizeof(uint8_t);

                                                        const auto partition = decode_pod<uint16_t>(p);
                                                        const auto seqNum    = decode_pod<uint64_t>(p);

                                                        if (seqNum) {
                                                                cleanupCheckpoints.push_back({{{a.CopyOf(topicName.p, topicName.len), topicName.len}, partition}, seqNum});
                                                        }
                                                }
                                        } else if (name == "."_s8 or name == ".."_s8) {
                                                continue;
                                        } else {
                                                struct stat64 st;

                                                basePath_.ToCString(fullPath, sizeof(fullPath));
                                                fullPath[basePath_.size()] = '/';
                                                name.ToCString(fullPath + basePath_.size() + 1);

                                                if (stat64(fullPath, &st) == -1)
                                                        throw Switch::system_error("Failed to stat(", fullPath, "): ", strerror(errno));
                                                else if (!S_ISDIR(st.st_mode)) {
                                                        // Just ignore whatever isn't a directory
                                                        if (trace) {
                                                                SLog("Ignoring [", name, "]: not a directory\n");
                                                        }
                                                } else {
                                                        if (name.front() == '.') {
                                                                if (false and false == read_only) {
                                                                        Print(ansifmt::color_red, "Found stray topic '", name, "'. Will attempt to delete it", ansifmt::reset, "\n");
                                                                        rm_tankdir(fullPath);
                                                                } else {
                                                                        // TODO: https://github.com/phaistos-networks/TANK/issues/70
                                                                        Print(ansifmt::color_red, "Found stray topic '", name, "'. Will NOT attempt to delete it", ansifmt::reset, "\n");
                                                                }
                                                        } else {
                                                                collectedTopics.emplace_back(a.CopyOf(name.p, name.len), name.len);
                                                        }
                                                }
                                        }
                                }
                        } catch (const std::exception &e) {
                                Print(ansifmt::bold, ansifmt::color_red, "Initialization failed:", ansifmt::reset, e.what(), ". Aborting startup-sequence\n");
                                return 1;
                        }

                        if (trace) {
                                SLog("Took ", duration_repr(Timings::Microseconds::Since(before)),
                                     " for initial walk ", collectedTopics.size(), " topics\n");
                        }

                        try {
                                for (const auto &name : collectedTopics) {
                                        // we are not going to be using std::async()
                                        // it creates a new thread for each call, which is far from optimal
                                        // for now, we will not parallelize the work, but eventually we will use a fixed-size thread pool
                                        // to register all those topics, although it shouldn't really matter match
                                        basePath_.resize(basePathLen);
                                        basePath_.append('/', name, '/');

                                        // XXX: make sure you access basePath_.data() after Buffer::append()
                                        auto       path = basePath_.c_str();
                                        const auto len  = basePath_.size();

                                        if (stat64(path, &st) == -1) {
#if defined(TANK_THROW_SWITCH_EXCEPTIONS) or __cplusplus <= 201703L
                                                throw Switch::system_error("stat(", str_view32(path, len), ") failed:", strerror(errno));
#else
                                                throw std::filesystem::filesystem_error(std::string{}
                                                                                .append("stat(")
                                                                                .append(path, len)
                                                                                .append(") failed:")
                                                                                .append(strerror(errno)),
                                                                                std::error_code{});
#endif
                                        } else if (st.st_mode & S_IFDIR) {
                                                uint32_t         partitionsCnt{0}, min{UINT32_MAX}, max{0};
                                                partition_config partitionConfig;

                                                try {
                                                        for (const auto &&name : DirectoryEntries(path)) {
                                                                basePath_.resize(len);
                                                                basePath_.append(name);

                                                                if (name.Eq(_S("config"))) {
                                                                        // topic overrides defaults
                                                                        parse_partition_config(basePath_.c_str(), &partitionConfig);
                                                                } else if (name.IsDigits()) {
#if 0 // for faster-startup, we assume names comprised of digits are indeed partitioons/directories
									if (stat64(path, &st) == -1) {
										throw Switch::system_error("Failed to stat(", basePath_, "): ", strerror(errno));
									}

									if (!(st.st_mode & S_IFDIR)) {
										continue;
									}
#endif

                                                                        const auto id = name.as_uint32();

                                                                        min = std::min<uint32_t>(min, id);
                                                                        max = std::max<uint32_t>(max, id);
                                                                        ++partitionsCnt;
                                                                }
                                                        }
                                                } catch (...) {
                                                        throw;
                                                }

                                                try {
                                                        if (partitionsCnt) {
                                                                if (min != 0 and max != partitionsCnt - 1) {
                                                                        throw Switch::system_error("Unexpected partitions list; expected [0, ", partitionsCnt - 1, "]");
                                                                }

                                                                auto t = std::make_shared<topic>(name, partitionConfig);

                                                                collectLock.lock();
                                                                pendingPartitions.emplace_back(t.get(), partitionsCnt);
                                                                register_topic(std::move(t));
                                                                collectLock.unlock();
                                                        } else {
                                                                path[len] = '\0'; // this is important

                                                                if (false and false == read_only) {
                                                                        Print(ansifmt::color_red, "No partions found in ", path,
                                                                              ": Will delete topic", ansifmt::reset, "\n");

                                                                        rm_tankdir(path);
                                                                } else {
                                                                        // TODO: https://github.com/phaistos-networks/TANK/issues/70
                                                                        Print(ansifmt::color_red, "No partions found in ", path,
                                                                              ": Will NOT delete topic", ansifmt::reset, "\n");
                                                                }
                                                        }
                                                } catch (...) {
                                                        throw;
                                                }
                                        }
                                }
                        } catch (const std::exception &e) {
                                Print(ansifmt::bold, ansifmt::color_red, "Initialization failed:", ansifmt::reset,
                                      e.what(), ". Aborting startup-sequence\n");
                                return 1;
                        }

                        basePath_.resize(basePathLen);

                        if (trace) {
                                SLog("Took ", duration_repr(Timings::Microseconds::Since(before)),
                                     " for topics, pendingPartitions.size() = ", pendingPartitions.size(), "\n");
                        }

                        before = Timings::Microseconds::Tick();
                        if (!pendingPartitions.empty()) {
                                static constexpr bool                                                   trace{false};
                                std::vector<std::pair<topic *, std::shared_ptr<topic_partition>>> list;

                                if (trace) {
                                        SLog("pendingPartitions.size() = ", pendingPartitions.size(), "\n");
                                }

                                for (auto &it : pendingPartitions) {
                                        auto t = it.first;

                                        for (uint16_t i{0}; i < it.second; ++i) {
                                                try {
                                                        const auto partition = i;
                                                        auto       p         = init_local_partition(partition, t, t->partitionConf, false);

                                                        if (p) {
                                                                list.emplace_back(t, std::move(p));
                                                        }

                                                } catch (std::exception &e) {
                                                        Print(ansifmt::bold, ansifmt::color_red, "Initialization failed:", ansifmt::reset, e.what(), ". Aborting startup-sequence\n");
                                                        return 1;
                                                }
                                        }
                                }

                                if (trace) {
                                        SLog("Done with partitions\n");
                                }

                                if (trace) {
                                        SLog("Took ", duration_repr(Timings::Microseconds::Since(before)), " for all partitions\n");
                                }

                                std::sort(list.begin(), list.end(), [](const auto &a, const auto &b) noexcept {
                                        return uintptr_t(a.first) < uintptr_t(b.first);
                                });

                                const auto                     n = list.size();
                                std::vector<std::shared_ptr<topic_partition>> partitions;

                                if (trace) {
                                        before = Timings::Microseconds::Tick();
                                }

                                for (uint32_t i{0}; i < n;) {
                                        auto t = list[i].first;

                                        do {
                                                partitions.emplace_back(std::move(list[i].second));
                                        } while (++i < n and list[i].first == t);

                                        t->register_partitions(partitions.data(), partitions.size());
                                        totalPartitions += partitions.size();
                                        partitions.clear();
                                }

                                for (const auto &it : cleanupCheckpoints) {
                                        const auto topic     = it.first.first;
                                        const auto partition = it.first.second;
                                        auto       seqNum    = it.second;

                                        if (auto t = topic_by_name(topic)) {
                                                if (partition < t->partitions_->size()) {
                                                        auto log = partition_log(t->partitions_->at(partition).get());

                                                        if (seqNum < log->firstAvailableSeqNum) {
                                                                seqNum = log->firstAvailableSeqNum - 1;
                                                        }

                                                        log->lastCleanupMaxSeqNum = seqNum;
                                                        cleanup_tracker.push_back(log); // TODO(markp): If we support topic/partitions deletes, we need to remove from cleanup_tracker
                                                }
                                        }
                                }

                                if (trace) {
                                        SLog("Took ", duration_repr(Timings::Microseconds::Since(before)), " to initialize all partitions\n");
                                }
                        }
                } catch (const std::exception &e) {
                        Print(ansifmt::bold, ansifmt::color_red, "Failed to initialize topics and partitions:", e.what(), ansifmt::reset, "\n");
                        return 1;
                }
        }

        if (not cluster_aware()) {
                Print(ansifmt::bold, "<=TANK=>", ansifmt::reset, " v", TANK_VERSION / 100, ".", TANK_VERSION % 100,
                      " | ", dotnotation_repr(topics.size()), " topics registered, ",
                      dotnotation_repr(totalPartitions), " partitions; will listen for new connections at ", tank_listen_ep, "\n");
        } else {
                Print(ansifmt::bold, "<=TANK=>", ansifmt::reset, " v", TANK_VERSION / 100, ".", TANK_VERSION % 100,
                      " | will listen for new connections at ", tank_listen_ep, "\n");
        }

        if (prom_endpoint) {
                Print("> Prometheus Exporter enabled, will respond to http://", prom_endpoint, "/metrics\n");
        }

        if (read_only) {
                Print("> Read-Only mode; some functionality/APIs will be unavailable\n");
        }

        Print("(C) Phaistos Networks, S.A. - ", ansifmt::color_green, "http://phaistosnetworks.gr/", ansifmt::reset, ". Licensed under the Apache License\n\n");

        if (topics.empty() and not cluster_aware()) {
                Print("No topics found in ", basePath_, ". You may want to create a few, like so:\n");
                Print("mkdir -p ", basePath_, "/events/0 ", basePath_, "/orders/0 \n");
                Print("This will create topics events and orders and define one partition with id 0 for each of them.\nRestart TANK after you have created a few topics/partitions\n");
                Print(R"EOF(Or, you can use tank-cli's "create topic" command to create new topics instead)EOF", "\n");
        }

        if (not cluster_aware() and not enable_listener()) {
                // we are going to until we have bootstrapped
                return 1;
        }

        if (prom_endpoint) {
                prom_listen_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);

                if (-1 == prom_listen_fd) {
                        Print("socket() failed:", strerror(errno), "\n");
                        return 1;
                }

                memset(&sa, 0, sizeof(sa));
                sa.sin_addr.s_addr = prom_endpoint.addr4;
                sa.sin_port        = htons(prom_endpoint.port);
                sa.sin_family      = AF_INET;

                if (Switch::SetReuseAddr(prom_listen_fd, 1) == -1) {
                        Print("SO_REUSEADDR: ", strerror(errno), "\n");
                        return 1;
                } else if (bind(prom_listen_fd, reinterpret_cast<sockaddr *>(&sa), sizeof(sa)) == -1) {
                        Print("bind() failed:", strerror(errno), ". Cannot accept Prometheus connections.\n");
                        return 1;
                } else if (listen(prom_listen_fd, 128)) {
                        Print("listen() failed:", strerror(errno), "\n");
                        return 1;
                }
        }

        sync_thread.reset(new std::thread([] {
                std::vector<std::pair<int, int>> local;
                sigset_t                         mask;

                sigfillset(&mask);
                pthread_sigmask(SIG_SETMASK, &mask, nullptr);
                for (;;) {
                        {
                                std::unique_lock<std::mutex> g(mboxLock);

                                while (mbox.empty()) {
                                        mbox_cv.wait(g);
                                }

                                local = std::move(mbox);
                                TANK_EXPECT(mbox.empty());
                        }

                        for (auto &it : local) {
                                if (-1 == it.first) {
                                        return;
                                }

                                fsync(it.first);
                                fsync(it.second);
                        }

                        local.clear();
                }
        }));

        if (prom_listen_fd != -1) {
                poller.insert(prom_listen_fd, POLLIN, &prom_listen_fd);
        }

        main_thread_id = pthread_self();
        curTime        = time(nullptr);

        // setup signals delivery
        sigset_t   mask;
        const auto signal_handler = [](int sig) { pending_signals.fetch_or(1ull << sig); };

        signal(SIGINT, signal_handler);
        signal(SIGUSR1, signal_handler);

        sigemptyset(&mask);
        sigaddset(&mask, SIGPIPE);
        sigaddset(&mask, SIGHUP);
        sigdelset(&mask, SIGUSR1);
        if (-1 == pthread_sigmask(SIG_BLOCK, &mask, nullptr)) {
                Print("pthread_sigmask():", strerror(errno), "\n");
                return 1;
        }

        // we need to make sure now_ms is initialized before we register_with_cluster()
        now_ms = Timings::Milliseconds::Tick();

        if (cluster_aware()) {
                if (int fd = open(Buffer{}.append(basePath_, "/.cluster_session_"_s32, cluster_state.local_node.id).c_str(), O_RDONLY); - 1 == fd) {
                        if (errno != ENOENT) {
                                Print("Failed to access cluster_session: ", strerror(errno), "\n");
                                return 1;
                        }
                } else {
                        const auto file_size = lseek(fd, 0, SEEK_END);

                        if (file_size != 36) {
                                TANKUtil::safe_close(fd);
                                Print("Unexpected cluster_session file contents\n");
                                return 1;
                        }

                        if (pread(fd, consul_state._session_id, file_size, 0) != file_size) {
                                Print("Failed to access cluster session: ", strerror(errno), "\n");
                                TANKUtil::safe_close(fd);
                                return 1;
                        } else {
                                // We have a session already, so we 'll try to renew it first
                                // and if it fails only then create a new session
                                //
                                // see register_with_cluster()
                                consul_state._session_id_len = file_size;
                                TANKUtil::safe_close(fd);
                        }
                }

                register_with_cluster();
        }

        return reactor_main();
}


text:
Q: How to fix the floating issue with Clearfix I have built a square with CSS, but i am getting a Floating issue. I used clearfix approach but i guess i am making a small mistake in CSS.
body{
  margin: 0;
}
article:before {
  clear: left;
}
article {
    border: 2px solid #ccc;
  float: left;
  padding: 0;
  margin: 0;

}

Here is the Fiddle

A: You need box-sizing:border-box in the article rule. Example below:

body {
  margin: 0;
}

article:before {
  clear: left;
}

article {
  border: 2px solid #ccc;
  float: left;
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

article:nth-of-type(1) {
  background-color: red;
  width: 50%;
  height: 100px;
  text-align: center;
  line-height: 100px;
}

article:nth-of-type(2) {
  background-color: blue;
  width: 50%;
  height: 100px;
  text-align: center;
  line-height: 100px;
}

article:nth-of-type(3) {
  background-color: grey;
  width: 50%;
  height: 100px;
  text-align: center;
  clear: left;
  line-height: 100px;
}

article:nth-of-type(4) {
  background-color: green;
  width: 50%;
  height: 100px;
  text-align: center;
  line-height: 100px;
}

1

2

3

4

redpajama_set_name: RedPajamaStackExchange


This is a simple black line bone pattern. The use of light teal makes this a very complimentary and soft addition to the Skeleton Collection.
These two-tone bones are plain but strangely appealing, and they make a great background or accompanying pattern for either the Halloween or the Skeleton Collection.


freshlyWORN is a PRINT and WEB Editorial magazine.
All editorial submissions should consist of a collaborating, creative team that is made up of, but not limited to, photographer, model(s), a makeup artist, a hair stylist, and a wardrobe stylist.
1. An editorial must contain a MINIMUM of FOUR (4) unique / different beauty looks or FOUR (4) unique/different fashion looks. We want to see a variety in your images, not just different views or angles of the same styling, be CREATIVE!
2. Editorials must contain a minimum of EIGHT (8) images and we will accept up to SIXTEEN (16) for final review.
3. ALL team members involved must be credited (photographers, models, stylists, etc) and YOU are responsible for the correct spelling of all members. We will NOT correct any spelling errors once the editorial has been published. Please provide weblinks for EACH team member's portfolio, instagram and/or facebook page if possible.
All parties involved in the shoot must consent to having their work published in freshlyWORN Magazine. Any models represented by agencies must have a signed release from their agent, even if they did the shoot as trade and the photographer must be able to provide the release with their submission or upon editorial request.
The mandate for freshlyWORN Magazine has always been the support and encouragement of new, emerging talent and continued promotion of established talent in the fashion and beauty industry. This includes photographers, models, designers, makeup artists, hairstylists and wardrobe stylists.
We are re-introducing our seasonal print-on-demand (POD) magazine in addition to our online webitorials.
- POD will be re-introduced on a quarterly/seasonal basis with potentially multiple issues per season depending on volume of submissions.
- All POD submissions will be reviewed for quality of image, diversity of "looks" and seasonal interest.
- It is the responsibility of the contributor to ensure that credits to models, photographers, stylists, designers, MUAs and hairstylists are CORRECT at the time of submission. We will not redo the magazine after publication if your provided content is incorrect.
- We will NOT be providing contributors with free magazines. We will however provide contributors with FREE high-resolution digital magazine issues and PDF tearsheets.
- web editorial content may increase, or decrease, depending on the volume of content received.
- editorial submissions will be published in large, web-ready galleries with complete team credits as provided.
- all team members will have the opportunity for reciprocal links to their websites, include portfolio, instagram and/or facebook page links.
We look forward to working with you and publishing your editorial stories.


Population growth and 10% economic growth in fast-developing countries will result in billions more people consuming at the rate of rich-world baby-boomers within a few decades. We'll have to change our eating habits in the long-run, but until then, how on earth are we going to produce enough food to feed a billion middle class Indians and Chinese who have suddenly developed a taste for hamburger? Meanwhile, a complex concoction of trade regimes, population growth, urbanisation and increasing temperatures mean that food security is an ever growing threat in Africa; but in this case not because the new middle classes are demanding hamburger, but because hunger is still real (more on all of this at Citizen Renaissance here.) So what can we do about it? We can further develop smart methods of farming to increase yields perhaps. And yet if you're a left-winger, you'll think GMOs or other farming technologies are Satan's spawn. That doesn't make sense. Surely if you're a left-winger, you want to feed people in developing countries.
If the worst predictions come true, we'll experience a 5-6ºC temperature increase by the end of the century, putting vast swaths of the world under water and destroying ecosystems and possibly the nature pyramid to god knows what effect. But climate-change scepticism has become a standard bearing right-wing issue: if you're right-wing, you'll claim it's all a load of tosh. That doesn't make sense. Surely if you're right-wing you should be just as worried as a left-winger if there's even a slight possibility that even the most rosy scenario regarding climate change may come true.
Immigration rates in Europe aren't really out of control as the populist press tend to claim. Three other trends are however. Declining birth rates, people reaching retirement age and Europe's pathetic economic competitiveness. Right-wingers claim to be pro-business, pro-growth and pro-wealth. And yet right-wingers tend to be, if not always hostile, at least very wary of immigration. Again, that doesn't make sense. Who is going to buy and build things? Where is the next generation of innovators going to come from if half our population is retired?
I'm fully aware that all three issues – and many others like them – are spuriously ideological in some way i.e. a right-winger will make a political argument for why they are anti-immigrant or a climate-change sceptic; while a left-winger can just as easily frame their hostility towards GMOs in genuinely left-wing terms.
The point I'm trying to make is that most issues are far too important and complex to fit neat political demarcations. And yet politicians and the media who support them are all too ready to politicise them to score an easy win. They're taking advantage of the age-old human instinct whereby people are comforted by thinking that everything can be defined by us or them / right or wrong; so if the opposition has taken a stand on an issue, the response is to take the opposite view, rather than debating or perhaps even – shock, horror – agreeing with it.
It's not all bad though. At European level, the strongly consensus-based political model makes complete polarisation difficult. Meanwhile, year after year, voters throughout Europe are increasingly struggling to tell the difference between parties (which I happen to think is a good thing) while age-old political affiliations based purely on family or geography are dying out. But given that the left-right divide can still characterise epoch-defining issues like food security, immigration and climate change, we still have some way to go.


I recently moved to China, and Vuze hasn't been working well since. I use a VPN.
Searches would yield very few results. Many common titles couldn't be found.
Anyone had such experiences, and how can I config Vuze in China?


text:
Film critic, aficionado opens series with an august visitor
Michael PhillipsCHICAGO TRIBUNE
'I went out and bought a pair of black loafers after that," Sydney Pollack tells critic and interviewer Elvis Mitchell in the premiere of "Elvis Mitchell: Under the Influence." Why the loafers? Because Gene Kelly wore loafers in "An American in Paris," a film the Leslie Caron-smitten Pollack says he saw six times back in 1951.
Conducted last July shortly before Pollack was diagnosed with the cancer that ultimately took his life, the interview kicks off Turner Classic Movies' new series Monday. Pollack's film "Tootsie" follows the half-hour segment; then, after a re-airing of the interview, Mitchell presents "An American in Paris."
"He was as full of energy and vitality as he always was," Mitchell says of Pollack. "He had the kind of charisma you'd expect in a movie star." Which he was, most effectively in his supporting roles in "Tootsie" and Woody Allen's "Husbands and Wives."
Mitchell conducted the Pollack interview in front of an audience in Los Angeles. The rest of the interviews in "Under the Influence" are in-studio, no audience, few distractions. Mitchell says the July 14 show devoted to Bill Murray ("A Night at the Opera" and "North by Northwest" are two of his favorites, and will be shown on TCM in conjunction with the interview) may surprise some Murray fans. "To see him without an audience, without pushing some movie he's halfheartedly trying to get people to see" -- puts Murray in a less antic mode, he says.
Murray talks about Margaret Sullavan and Henry Fonda (married and divorced in real life) in the largely ignored 1936 comedy "The Moon's Our Home." Regarding Cary Grant in Alfred Hitchock's 1959 whirlwind masterwork, he tells Mitchell: "He gets a suit out of the closet in 'North By Northwest,' and you're like, 'Wow, look at that man get that suit out of the closet.' It's breathtaking. And he always made other people look good. That's what they taught us at Second City [in Chicago]: Make the other person look good, and you don't have to worry about yourself."
In the Pollack interview airing Monday, the director who was so savvy with so many different types of movie stars says, "The trick in film acting is really about getting rid of tension. If you are really relaxed and you think a thought and the camera is on you, the camera will know it and register it and be impressed by it. ... That's really mostly what Steve McQueen did his whole life." Mitchell has learned a few things along those lines, pursuing his own line of work.
Michael Phillips fills in for Roger Ebert on "At the Movies with Ebert & Roeper," airing at 11:05 p.m. Sat. and 10:30 a.m. Sun. on WLS-Ch. 7.
mjphillips@tribune.com

redpajama_set_name: RedPajamaCommonCrawl


text:
Q: Angularjs - How do I output my custom filters to the dom correctly How can I best collect the current 'active' filter parameters (like type, price, etc etc) and for each one that angular is filtering by add them to my dom as a li/button/ahref along with the ability to click on the new dom element and remove it as a filter and from the dom.
I have built it out in the link below but when I add a filter it gets added to the dom multiple times. Can't seem to figure it out.
[FIDDLE]
(function(){
//$('.filterList').append('
cortney
');
var app = angular.module('filter',[]);

app.controller('FilterCtrl',function myFilter($scope){
  $scope.orderByField = 'type';
  $scope.reverseSort = false;
  $scope.filters = [];
  $scope.minprice = 0;
  $scope.filterCars = function(item){
      var index = $scope.filters.indexOf(item);

      if(index == -1) {
          $scope.filters.push(item);
      } else {
          $scope.filters.splice(index, 1);
      }

      //console.log($scope.filters);
  };
  $scope.filter = function(value) {
    return $scope.filters.length == 0 || ($scope.filters.indexOf(value._type) != -1) && (value._price > $scope.minprice);
  };
  $scope.getTotalFilters = function(){
      //console.log($scope.filters);
      return $scope.filters;
  };
  $scope.showTotalFilters = function(){
      var myfilters = $scope.getTotalFilters();

      $.each(myfilters,function(index,value){
         $('.filterList').append('
' + value + '
');
      });
      return myfilters

  };

  $scope.data = {
      models: [
          {
           "_name" : "sedan",
           "_ext" : "S Sedan",
           "_type" : "sedan",
           "_body_style": "sedan",
           "_price": "13865",
           "_mpg_city": "28",
           "_mpg_hwy": "36",
           "_fuel_eff": "31",
           "_year": "2014",
           "_seating": 5
         },{
           "_name" : "hatch",
           "_ext" : "S Hatch",
           "_type" : "hatch",
           "_body_style": "hatch",
           "_price": "14365",
           "_mpg_city": "28",
           "_mpg_hwy": "36",
           "_fuel_eff": "31",
           "_year": "2014",
           "_seating": 5
         },{
           "_name" : "suv",
           "_ext" : "SE Sedan",
           "_type" : "suv",
           "_body_style": "suv",
           "_price": "15095",
           "_mpg_city": "28",
           "_mpg_hwy": "36",
           "_fuel_eff": "31",
           "_year": "2014",
           "_seating": 5
         }]
  };
$scope.models = $scope.data.models;

});

})();

A: The first thing you should avoid is making any references to DOM elements from your controllers, always use binding or a directive for that matter. To illustrate better this should be avoided:
  $scope.showTotalFilters = function(){
      var myfilters = $scope.getTotalFilters();

      $.each(myfilters,function(index,value){
         $('.filterList').append('
' + value + '
');
      });
      return myfilters

  };

I updated your fiddle to work like you imagined, it is very coupled but I guess you can take a look and get a grasp on how it should be done:
http://jsfiddle.net/dqvadn6r/1/
I hope that I understood correctly.


text:
package org.dylanfoundry.deft.filetypes.dylan.psi.impl;

import java.util.List;
import org.jetbrains.annotations.*;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.util.PsiTreeUtil;
import static org.dylanfoundry.deft.filetypes.dylan.psi.DylanTypes.*;
import org.dylanfoundry.deft.filetypes.dylan.psi.*;

public class DylanAuxRulesImpl extends DylanCompositeElementImpl implements DylanAuxRules {

  public DylanAuxRulesImpl(ASTNode node) {
    super(node);
  }

  @Override
  @NotNull
  public List<DylanAuxRule> getAuxRuleList() {
    return PsiTreeUtil.getChildrenOfTypeAsList(this, DylanAuxRule.class);
  }

  public void accept(@NotNull PsiElementVisitor visitor) {
    if (visitor instanceof DylanVisitor) ((DylanVisitor)visitor).visitAuxRules(this);
    else super.accept(visitor);
  }

}

redpajama_set_name: RedPajamaGithub


Second last day. This is Celine the proud new owner of two purple Teddy bears. Was a pretty good night. Had a big argument with Janning about the stirer/straws you get from fast food or coffee places. Went to a fashion show at a Malaysian bar.


text:
USA Today Sports Images
Report: Alex Zendejas resigns from US national team as part of Chivas move
July 7, 20161:05PM EDT
Sam StejskalContributor
Follow@ samstejskal
Former FC Dallas midfielder and US youth international Alejandro Zendejas has reportedly resigned from the US national team as part of his recent move to Liga MX giants Chivas.
ESPN FC's Tom Marshall reported on Wednesday that Chivas head coach Matias Almeyda confirmed that the 18-year-old Zendejas, who completed his move from Dallas to Guadalajara on June 24, would give up his standing as a US international to join the club.
Chivas coach Matias Almeyda confirming that Alejandro Zendejas resigned from the US national team in order to join club.
— Tom Marshall (@mexicoworldcup) July 6, 2016
Chivas have a policy of fielding only Mexican players. Zendejas, who signed with FC Dallas as Homegrown player in October 2014, has a Mexican passport but has represented the US on the youth level, playing every minute for the Under-17 national team at last year's U-17 World Cup and recently earning a call-up to the U-20 national team.
Chivas have signed other players who have represented the US on youth levels in the past. One such player, Juan Pablo Ocegueda, gave up his status as a US international while on loan to Chivas in 2013, but returned to the US setup after leaving the club, playing four times for the US U-23s in 2014.
Zendejas made eight MLS appearances with FC Dallas last year, but did not play for the club this season before moving to Chivas.


In this day and age, windows defender and a spam filter on your email account just isn't going to cut it anymore. The landscape of cybersecurity breaches and vulnerabilities is constantly changing and to protect ourselves, we must evolve with it.
Sure, it's great that the majority of us are all educated enough to not click on "suspicious" links in an email or text, but what do you do when it happens by accident? You were browsing through your email and when you opened that fishy email, your hand slipped and you clicked into it? In this case, the preventive measures are simply not enough. To minimize the damage caused by a cybersecurity breach, a websecurity stance must be in place ahead of time.
A crucial part, but often overlooked part of cybersecurity prevention is a remidation service. In order to assist you, as well as make you more aware, we've listed the 3 most common cybersecurity problems that businesses face and how to go about fixing them.
The cost of a data breach can be very expensive, so much so that it depends on the severity of the breach. The more data that was compromised, usually the more expensive it becomes. The majority of data breaches are caused by compromised logon credentials. That being said, it's not just limited to logon credentials, the other common reasons include but are not limited to: Software misconfiguration, misplaced or lost hardware, and/or malware.
In order to prevent data breaches, good practices should be employed such as encrypting site traffic and transactions with SSL. Each user group should have carefully reviewed permissions and servers should be scanned regularly. A day to train the employees on how to common phishing attacks would also benefit the company greatly.
In the unfortunate event that your business discovers a possible data breach, you may face legal and/or compliance requirements for notifying your customers and regulatory authorities. Full disclosure requirements and strategies should be on standby ahead of time so that you can prevent any more data being stolen and repair the damage already caused by the breach. Once the attack has been countered and isolated, you should proceed with a thorough investigation to figure out what caused the breach and put all resources forward to make sure that this particular incident doesn't happen again.
A (DDoS) attack generally involves a large network of computers being user by a hacker to flood a target with enormous amounts of traffic.
If your business happens to be caught up in a DDoS attack, you will need to put your recovery plan into effect and notify your employees and customers about the ongoing disruption. There are many security tools available such as a WAF which is used to close off the port or protocol that is "under attack". This process may have to be repeated as attackers will adjust their network to attack other ports/protocols.
In the end, service would be quickly restored with a CDN (content distribution network) such as Cloudflare which is able to absorb a huge impact all whilst filtering and identifying traffic which is deemed malicious.
The large majority of businesses are aware on some level of the security threat that is posed by malware. Despite that, many people are still unaware that spam from your email is still the #1 vector of malware attacks.
Since malware comes from a wide range of sources, several tools are needed, sometimes in conjunction with each other to prevent infection. A solid email scanning and filtering system is a must, as well as malware and vulnerability scanners. This is quite similar to a data breach, which too are often caused by malware so employee training is crucial to keep businesses safe from incoming malware.
If any device becomes infected by malware in the company, it should be isolated, thoroughly analysed and cleaned, which means identifying and removing hidden portions of code and deleting ALL infected files before they have any chance to replicate. This task is near impossible to do by hand so an effective automated tool is a must.


Sick of the processes and that big company culture and love the idea of working in a smaller software driven company where you can make this happen at pace? Have been thinking that now is the time to start working with a modern web stack that generates a top quality product.
If you are looking for an opportunity where you can work in a full stack position with an awarding winning software company this could be for you.
This is a small focused team and there is no room for drifters. This will be a great option for you if you have proven problem-solving experience along with a wealth of knowledge in C#. You will work within a small server side team , contributing to the various websites and on-going development projects they are currently undertaking.
You must be comfortable with applying your experience to help solve problems and deliver solutions and should be able to demonstrate this at interview.
Good understanding of OOP Programming and Design patterns.
Have proven experience of solving problems and working to understand requirements.
For further information on this opportunity please reply with an up to date CV or contact me directly to find out more.


The maquis of Etobon had been busy avoiding German troops, making use of the woods to hide their guerilla attacks. Jules Perret wonders how they have escaped capture for so long, and whether it would be safer to try to join up with the American forces than to stay in Etobon.
"Our pig gave us 105 kilos of meat. I understand why we had so much trouble dragging it, last night, not daring to light the lantern. Jacques and Kuntz were exhausted from their day at Belfort, in a pouring rain, on the Champ de Mars, surrounded by thousands of cattle. Our guerrillas come home one by one, hands and faces scraped. They've seen some sights! They must have, not to have been picked off to the last man, there were so many Germans. Wouldn't they be better off slipping away to join the Americans than staying here in a trap? With all his gendarmes, the adjutant Henry will try to get back to Champagney by way of the woods.
"Tonight, they'll take away the German car and side-car left at the edge of the road and hide them in the fir trees at the Bouloie pass. They'll smooth out the two German graves and hide them with dry leaves."


VIET NAM - Shrimp exports from Viet Nam fell during the first quarter of 2015 as global prices tumbled.
Shrimp import demand from major markets and shrimp prices fell. Volatility in the Vietnamese currency's exchange rate against the US dollar significantly impacted shrimp export, reports VASEP.
In quarter one of 2015, Viet Nam shrimp exports reached $798 million, down 28.1 per cent year on year. Exports to most major markets fell sharply.
In particular, exports to the US fell by 55.8 per cent, and those to Japan decreased by 27.6 per cent.
Shrimp prices in the US market, especially for vannamei (whiteleg shrimp) reduced sharply. Statistics showed that US shrimp imports in January and February increased by only 5 per cent by volume but decreased by 11 per cent by value.
Average US import price of shrimp fell in two consecutive months in this year.
From $12/kg in the last quarter of 2014, it fell to $11/kg in January 2015 and then down to $10/kg in February 2015.
Furthermore, the US dollars rose sharply against other currencies that America become "destination" of so many shrimp suppliers.
By the end of March, Viet Nam shrimp exports to the US declined to $116.3 million, from $263.3 million in the same period last year.
Peeled frozen shrimp is the most imported in the US, accounting for over 50 per cent of US shrimp imports. Viet Nam is now the third largest supplier, after Indonesia and India.


text:
Sonia O'Sullivan: Next generation of Irish athletes growing up fast
Likes of John Fitzsimons, Gina Apke-Moses and Michaela Walsh on the right track
Thu, Jul 27, 2017, 07:00
Sonia O'Sullivan
Medalists John Fitzsimons (bronze in the men's 800m) Gina Akpe-Moses (gold in women's 100m) and Michaela Walsh (bronze in the Hammer) at the homecoming of the Irish team from the European Athletics Under-20 Championships in Italy. Photograph: Sam Barnes/Sportsfile
Four has always been something of a magic number in athletics. Only not quite when it comes to the four Irish athletes that will compete inside the London Olympic Stadium at the World Championships, which get under way on Friday week.
It's a little surprising, and doesn't quite add up. There are another seven – between the men's and women's marathons and the men's 20km/50km walks – who get to compete around the streets of London. Still that team of 11 makes for only a very small cross-section of what should be a wider body of Irish athletics.
At least those four on the track seem to be going well – Brian Gregan, Mark English, Thomas Barr and Ciara Mageean all showing their class when winning national titles in Santry at the weekend.
So nothing about their qualification should really be that much of a shock, as these four are currently the best Irish athletes. What is concerning is that there is no back-up squad, no track or field athletes that may not be at the level to reach a final yet, but would learn some considerable lessons from the experience.
It's not that the World Championships standards are any more difficult; in fact in a number of events those standards have been reduced.
It could be some of the desire to be in London is missing. The allure of the World Championships seems to have worn off in Irish eyes, even when they will be held so close to home in the London Olympic Stadium.
The Olympics still has a greater attraction and there is a noticeable drop off in the desperation to qualify the year after an Olympic Games. There is a natural comedown.
But when you think that the next World championships, in 2019, will be held in Qatar in horrendous conditions – no matter where athletes are coming from – this may well be a missed opportunity for athletes to compete on the world stage, in ideal conditions, in front of a packed stadium.
This all contrasted with my thoughts just a few weeks ago at the Irish juvenile athletics championships, staged in Tullamore. Again I was a little surprised – in a pleasant sense – such was the depth in numbers competing and the high standards of competition. I began to see hope for the future, but at the same time wondering where do they all go to?
There is so much talent and energy within Irish athletics underage clubs throughout the country: you do however have to question what happens in those years after school. It is like stepping into a void, and very few seem to survive, in athletics terms at least.
True benchmark
There was hope again last weekend while watching the European Junior Championships, which took place in Grosetto, Italy. This is a true benchmark for the future of athletics. So many young European athletes pass through these junior championships and go on to win medals at senior level at European, World and Olympics further into their athletic careers.
And this turned out to be the best ever representation at the European Junior Championships by an Irish team. I had just arrived back in Australia, but I was quite happy to wake up at 4.0am and switch on Eurosport, in the cold and darkness, so that I could catch up on the continual stream of Irish athletes qualifying to the finals.
This has not been a common occurrence in recent times; they were not just making finals, but you got the feeling there was always more to come.
Ciara Mageean on her way to victory in the 800m at the national track and field championships at Morton Stadium. Photograph: Ryan Byrne/Inpho
There was a hunger and desire that is sometimes missing at the senior level, where athletes can fall into the comfort zone, living the life of a professional athlete. There are often many rewards along the way that athletes want to hang onto and not take risks that could negate their current standings.
I was most impressed with John Fitzsimons in the 800m. It took a personal best 1:48.68 to make the final. This is something we often talk about. You can't look beyond the qualifying rounds of a championship.
So often the first round could be the only round, so it has to be run as a final to have any chance of making the final. What John did to qualify for the final was textbook perfect; do everything you can, run faster than you've ever gone before, worry about the final when you're in it.
The young Kildare man certainly didn't worry about the final, but looked to grab the opportunity with both hands and run with it. Sometimes these chances come along, gaps open up and you get in a break but you have to be prepared to just go with the flow and not worry what's going on behind you.
After already seeing Gina Apke-Moses take the gold medal in the 100m final, backed up by Ciara Neville also making the final, then Michaela Walsh claiming bronze in the hammer throw, you get the feeling everyone wanted to be a part of the action, and more importantly get close to the medals.
Overall Ireland placed in the top-eight positions 10 times, across eight different events, and that is certainly a very encouraging statistic to build on and grow towards the future.
So there is a new wave of young athletes coming along, across a variety of events. That challenge now is to make sure they are nurtured through the void that awaits them, or whatever other hazard of obstacles they are faced with along the way.
It is rarely plain sailing, but if they can overcome any hurdles and are allowed as smooth a transition as possible then there is no reason not to expect them to go on to even greater achievements at senior level.
Sometimes we can also expect too much from young athletes, when it can take up to seven years to grow a junior to be strong and competitive on the same stage at the senior level.
So often we see a glimmer of hope and expect too much too soon. It is a long tough road, going through the winter season each year, never knowing how you will be the following year. One year older doesn't always mean one year stronger.
In three years' time, many of these junior athletes could be on the cusp of Olympic qualification for Tokyo 2020, and after another positive few steps along the way it's not unrealistic. With a European Championships in Berlin next year, those 2017 World Championships one year later, there is a natural progression towards those Tokyo Olympics.
That also means dreaming big, and stepping up a level each year, with continuous forward momentum. When there is a new breed of athletes like this, all trying to match each other and progress together each year, and in some way trying to match each other's achievements, that in turn can push each other towards a higher level. I certainly felt a bit of that in my early years as an international runner.
The European Youth Olympic festival is also taking place this week in Gyor, and by day two Ireland had picked up two athletics medals in the girls 100m, won by Patience Jumbo-Gula, and in the hammer, by Jade Williams. Again, the new generation of Irish athletes, in every sense.
When you have a strong foundation of young athletes like this it's hard to fathom how Ireland can have such a small senior representation at the World Championships. These things do go in cycles but you have to hope that in the next few years with the right mindset and direction as these young athletes develop and grow, so too will the quantity and quality of Irish senior athletes.
Joanne O'Riordan: Chances are she's got game but not fame
Joanne O'Riordan: Is Serena Williams' genius appreciated?
Irish Sportswomen: Top 50 Memorable Moments - 50 to 41
Joanne O'Riordan: I love Barça but Cork City are my little secret
Sonia O'Sullivan: You still can't beat the intimacy of live sport
Sky's the limit for versatile Paralympian Niamh McCarthy
Sonia O'Sullivan: Women's 800m running is not a fair race
Sonia O'Sullivan: Hitting the ground running one way to deal with jet lag
Sonia O'Sullivan: Bringing a taste of the new normal home to Ireland
Sonia O'Sullivan: Summer is the track and field season
Fantasy Golf 2019 Pick your team to be in with a chance of winning a €10,000 first prize.
Here is your handy guide to sport on television this week
Monday – Sunday, July 15th – 21st
Munster and Leinster Hurling Round-Robins Keep up to date with the fixtures, results, TV coverage and tables
Allianz Cuman na mBunscol Finals 2019
Champions Cup Final
The Morning Sports Briefing
Keep informed with all you need to know in the world of sport along with the very best in opinion from our outstanding team of sports writers.
The Morning Sports Digest
0:59 Gary Hunt makes a splash by scoring perfect 10s at world cliff diving series
0:46 Liverpool fans troll Man United players with airplane banner
Connect with Irish Times Sport
Follow @IrishTimesSport


Interested in licensing Taneisha Jackson's music?
Taneisha Jackson, a singer/songwriter born in Jamaica, moved to England at the age of 9 where she was raised in the heart of South East London. With a love of old-school soul and funk, as well as pop and dance, Taneisha is one of the UK's most exciting young songwriters and on course for major success.
In 2014 John Legend recorded one of Taneisha's songs called 'A Place Called World' and it became the soundtrack to an international campaign by San Miguel. She's currently working on new material with Electric (Little Mix, Fleur East), Sub Focus, Unorthodox (Calvin Harris/ Disciples), Play Productions (Rascal Flats, Celine Dion). She has cuts on forthcoming releases by artists including Tamera Foster (Syco), Toyboy & Robin (Atlantic), Secaina Hudson (Capitol Records) & BBC Radio 2 favourites Ward Thomas.


A preacher was winding up his temperance sermon with great fervor, "If I had all the beer in the world, I'd take it and throw it into the river." And the congregation cried, "Amen!"
"And if I had all the whiskey and demon rum in the world, I'd take it all and throw it in the river." And the congregation cried, "Hallelujah!"


text:
=head1 PlanetsConstants

=over 19

=item PlanetsConstants -

Module containing planetary constants.

=back

=head1 SYNOPSIS

=over 18

=item USE PlanetsConstants

=back

=head1 DESCRIPTION

I<PlanetsConstants> defines several constants that are useful when working with gravity and topography data of the Earth, Mars, Venus, and Moon. All units are SI. Confer with the source file for exact values and references.

=head1 CONSTANTS

=head2 Fundamental Constants

=over 18

=item Grav_constant

Gravitational Constant.

=item pi_constant

PI.

=item mu0_constant

Magnetic constant.

=back

=head2 The Moon

=over 18

=item	R_Moon

Radius of the Moon.

=item	GM_Moon

Gravitational constant times the mass of the Moon.

=item Mass_Moon

Mass of the Moon.

=item rho_bar_Moon

Average density of the Moon.

=item a_Moon

Semi-major axis of the lunar orbit.

=item g0_Moon

Gravitational acceleration at R_Moon, not including rotation.

=item R0_pot_Moon

Reference radius of the gravitational-potential model.

=item Omega_Moon

Angular rotation rate of the Moon.

=item C_MOI

Polar moment of inertia, using R=1738 km.

=item I_MOI

Average moment of inertia, using R=1738 km.

=item Gamma_MOI

Gamma = (B-A)/C.

=item Beta_MOI

Beta = (C-A)/B.

=back

=head2 Mars

=over 18

=item R_Mars

Average radius of Mars

=item GM_Mars

Gravitational constant times the mass of the Mars.

=item Mass_Mars

Mass of Mars.

=item rho_bar_Mars

Average density of Mars

=item g0_Mars

Gravitational acceleration at R_Mars, not including rotation.

=item R0_pot_Mars

Reference radius of the gravitational-potential model.

=item Omega_Mars

Angular rotation rate of Mars.

=item f_Mars

Topographic flattening of Mars.

=item a_Mars

Mean equatorial radius of Mars.

=back

=head2 Venus

=over 18

=item R_Venus

Average radius of Venus.

=item R0_pot_Venus

Reference radius of the gravitational-potential model.

=item GM_Venus

Gravitational constant times the mass of the Venus.

=item Mass_Venus

Mass of Venus.

=item Omega_Venus

Angular rotation rate of Venus.

=item rho_bar_Venus

Average density of Venus.

=item g0_Venus

Gravitational acceleration at R_Mars, not including rotation.

=back

=head2 Earth

=over 18

=item GM_Earth

Gravitational constant times the mass of the Earth.

=item R0_pot_Earth

Reference radius of the gravitational-potential model.

=item Mass_Earth

The mass of the Earth.

=item WGS84_a

The semi-major axis of the WGS84 ellipsoid.

=item WGS84_b

The semi-minor axis of the WGS84 ellipsoid.

=item WGS84_r3

The radius of a sphere of Earth's volume.

=item WGS84_f

The flattening of the WGS84 ellipsoid.

=item WGS84_gm

The adopted GM of the WGS84 model, which includes the atmosphere.

=item WGS84_gma

The GM of the atmosphere adopted by the WGS84 model.

=item WGS84_omega

The adopted angular rotation rate of the Earth of the WGS84 model.

= item WGS84_U0

The theoretical normal potential associated with the WGS84 model.

=back

=head2 Mercury

=over 18

=item R_Mercury

Average radius of Mercury.

=item GM_Mercury

Gravitational constant times the mass of the Mercury.

=item Mass_Mercury

Mass of Mercury.

=item Omega_Mercury_orbit

Angular rotation rate of Mercury about the Sun.

=item Omega_Mercury_spin

Angular rotation rate of Mercury.

=item rho_bar_Mercury

Average density of Mercury.

=item g0_Mercury

Gravitational acceleration at R_Mercury, not including rotation.

=back

=head1 SEE ALSO

L<http://www.ipgp.jussieu.fr/~wieczor/SHTOOLS/SHTOOLS.html>

=head1 COPYRIGHT AND LICENSE

Copyright 2005-2011 by Mark Wieczorek <wieczor@ipgp.fr>.

This is free software; you can distribute and modify it under the terms of the revised BSD license.


text:
package org.apache.struts2.views.jsp.ui;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.components.Anchor;
import org.apache.struts2.components.Component;

import com.opensymphony.xwork2.util.ValueStack;

/**
 * @see Anchor
 */
public class AnchorTag extends AbstractClosingTag {

    private static final long serialVersionUID = -1034616578492431113L;

    protected String href;
    protected String includeParams;
    protected String scheme;
    protected String action;
    protected String namespace;
    protected String method;
    protected String encode;
    protected String includeContext;
    protected String escapeAmp;
    protected String portletMode;
    protected String windowState;
    protected String portletUrlType;
    protected String anchor;
    protected String forceAddSchemeHostAndPort;

    public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
        return new Anchor(stack, req, res);
    }

    protected void populateParams() {
        super.populateParams();

        Anchor tag = (Anchor) component;
        tag.setHref(href);
        tag.setIncludeParams(includeParams);
        tag.setScheme(scheme);
        tag.setValue(value);
        tag.setMethod(method);
        tag.setNamespace(namespace);
        tag.setAction(action);
        tag.setPortletMode(portletMode);
        tag.setPortletUrlType(portletUrlType);
        tag.setWindowState(windowState);
        tag.setAnchor(anchor);

        if (encode != null) {
            tag.setEncode(Boolean.valueOf(encode).booleanValue());
        }
        if (includeContext != null) {
            tag.setIncludeContext(Boolean.valueOf(includeContext).booleanValue());
        }
        if (escapeAmp != null) {
            tag.setEscapeAmp(Boolean.valueOf(escapeAmp).booleanValue());
        }
	    if (forceAddSchemeHostAndPort != null) {
            tag.setForceAddSchemeHostAndPort(Boolean.valueOf(forceAddSchemeHostAndPort).booleanValue());
        }
    }

    public void setHref(String href) {
        this.href = href;
    }

    public void setEncode(String encode) {
        this.encode = encode;
    }

    public void setIncludeContext(String includeContext) {
        this.includeContext = includeContext;
    }

    public void setEscapeAmp(String escapeAmp) {
        this.escapeAmp = escapeAmp;
    }

    public void setIncludeParams(String name) {
        includeParams = name;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public void setScheme(String scheme) {
        this.scheme = scheme;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public void setPortletMode(String portletMode) {
        this.portletMode = portletMode;
    }

    public void setPortletUrlType(String portletUrlType) {
        this.portletUrlType = portletUrlType;
    }

    public void setWindowState(String windowState) {
        this.windowState = windowState;
    }

    public void setAnchor(String anchor) {
        this.anchor = anchor;
    }

    public void setForceAddSchemeHostAndPort(String forceAddSchemeHostAndPort) {
        this.forceAddSchemeHostAndPort = forceAddSchemeHostAndPort;
    }
}


text:
Tag Archives: gillibrand
Iran, United States
Schumer's right — if Iran wants nukes, the US can't deter it indefinitely
August 7, 2015 Kevin Lees	Leave a comment
With the entire US political world focused on the Republican presidential debate last night, US senator Chuck Schumer quietly announced that, after much deliberation, he will vote against the nuclear energy deal negotiated between Iran and the P5+1 (the five members of the UN Security Council plus Germany).
If Schumer thought his Thursday night announcement would fly under the radar, he was wrong — and US secretary of state John Kerry was quick to say that he 'profoundly disagrees' with Schumer. With Senate minority leader Harry Reid retiring after the 2016 election, and with Democrats in a very good position to retake control of the US Senate in 2016, there's an exceedingly good chance that Schumer will be the Senate majority leader in less than 18 months' time. Moreover, he's one of the leading Jewish voices in American politics and, as a senator from New York, the US state with the highest proportion of Jewish voters in the country.
So it's not surprising that Schumer, a longtime ally of Israel, would reject a deal that Israeli prime minister Benjmain Netanyahu fiercely opposes. (Though New York's junior senator, Kirsten Gillibrand, announced her support for the Iran deal earlier this week).
RELATED: Winners and losers in the Iran nuclear deal
Schumer was careful to telegraph that he will not be working very hard to convince other Democrats to break ranks with the administration, and that's probably the wisest course for someone who still wants to become the Democratic leader in the Senate after angering the party's leftists. There's no doubt that Schumer's opposition will embolden the deal's critics, and it may convince a handful of Senate Democrats to oppose the deal. But the Obama administration still believes opponents of the Iran deal will not achieve the 60 votes that they need to defeat it in the US Senate — or the 67 votes they would need to override Obama's veto.
Chief among Schumer's problems with the deal is the fact that after 15 years, Iran could conceivably be free of both international sanctions and restrictions on its nuclear energy program, thereby giving it the ability to build a nuclear weapon: Continue reading Schumer's right — if Iran wants nukes, the US can't deter it indefinitely →
gillibrandindiairanisraelkerrykhameneinuclear energynuclear weaponsobamapakistanrowhanischumersenatetridentus senate


"Diversity is the one true thing we all have in common. Celebrate it every day."... Author Unknown Managing a Diverse Workforce will increase the attendee's cultural awareness, knowledge, and communication. This seminar aims to create a positive work environment by helping employees recognize and be tolerant of differences among co-workers. These differences include the following: •Generational •Cultural •Departmental •Unconscious Bias •Race •Gender •Religion •Other Attendees will also understand the benefits of having workplace diversity, whichnot only refers to the differences between employees, but also the acceptance and celebration of these differences at work. Who should attend: HR Managers, Recruiters, Office / Personnel Managers, Administrative Assistants, Small Business Owners, Marketing / Sales / Customer Service Professionals and anyone who works in a diverse office environment. This is a FREE event. Light lunch will be provided to the attendees. Speaker(s):Daniel D. Ragan, Partner — Edwards Ragan and Associates, LLC Co-Sponsor(s): The Kingsport Office of Small Business Development & Entrepreneurship (KOSBE), Kingsport Chamber, Edwards Ragan and Associates, LLC The cooperative agreement between KOSBE and East Tennessee State University is partially funded by the U.S. Small Business Administration (SBA). SBA's funding is not an endorsement of any products, opinions or services. SBA funded programs are extended to the public on a non-discriminatory basis. Additional funding is provided by the Tennessee Board of Regents and the state of Tennessee. Reasonable accommodations for persons with disabilities will be made if requested at least two weeks in advance. Please contact Aditi Bhave — 423.392.8825; abhave@tsbdc.org; 400 Clinchfield Street, Suite 100, Kingsport, Tennessee 37660.


The PXI XJLink2 module allows the integration of XJTAG into PXI-based test systems. PXI XJLink2 has one JTAG controller that can be connected to up to 4 JTAG chains, which are configurable for pinout and voltage. It is easily integrated with LabVIEWTM with a full set of Virtual Instruments (VIs) included.
32 bit PXI/cPCI bus interface.
NI LabVIEW Virtual Instruments (VIs) available (National Instruments).
Connects to up to 4 JTAG chains on the UUT.
Handles different cable and board configurations.
TCK clock frequencies up to 166 MHz.
Visual indication of test status.
JTAG signals are +5V tolerant.
Spare pins on the JTAG connector can be used to indicate the test status or to control other items — e.g. hold a board in reset / turn on a PSU.
Pins can also be used as general purpose I/O during testing, for example for fast Flash programming.


text:
'He gave his life to save his children': Daughter remembers Cathedral City man shot to death
In America Hernandez's eyes, her father died protecting his family.
Ruben Hernandez, 43, was fatally shot inside his family's home on March 23 in what Cathedral City police have called a "senseless" crime.
Police said the suspect had an "unvalidated inference" that a "hostile or adversary" lived at the home near Date Palm Drive and Interstate 10, which the family moved into a few months ago. The gunman opened fire and killed Hernandez and injured his 11-year-old daughter.
Police said they know of no connection between the suspect and Hernandez.
America Hernandez, 19, said the shooting occurred around 6:40 p.m., while she was in her room watching "Paranormal Activity 2."
After hearing shots erupt near the front door, Hernandez said she got on the floor and tried to locate her phone to call the police. She couldn't find it, and instead grabbed a stick while searching for a potential weapon, she said.
When she left her room, she heard her mom screaming and found her father on the floor, about 12 feet from the front door.
"It was very traumatic," she said.
"He tried to run to save my little brother and sister," America Hernandez said of her father, who was in the house with his wife and children. "He gave his life to save his children and family," she said.
Her 11-year-old sister, who was also shot near the neck and spine, is recovering, Hernandez said. Doctors weren't able to remove the bullet, which Hernandez described as not posing an immediate danger to her sister's health.
In talking with family members afterward, Hernandez said it appeared that someone knocked and demanded that someone open the front door. Ruben Hernandez, his daughter said, kept yelling, "No! Why?" before he was fatally shot.
Cathedral City Police Cmdr. Paul Herrera said via email that "the suspect contacted (Hernandez) at the front door, knew it was not the person he was looking for and fired multiple rounds from a handgun at him regardless of his unknown identity to the suspect."
Herrera described Hernandez as a "law-abiding" and "hard-working."
A few days after the homicide and another shooting on Wishing Well Trail hours later, which left no one injured, police arrested two suspects. But two more, including the suspected gunman, are at large.
Last week, police announced the arrests of Josue Casas, 23, and Ethan Bravo, 19. Authorities are still searching for Gabriel Hernandez, 22, and Joel Casas, 18.
Police identified Gabriel Hernandez — who is not related to the victim — as being responsible for both shootings. They arrested Bravo on suspicion of attempted murder in the Wishing Well Trail shooting and alleged the Casas brothers aided Hernandez in the shooting of Ruben Hernandez and his daughter, and afterward.
At the Wishing Well Trail shooting, police said they believe suspects thought they were at the residence of a rival or adversary.
"When this person did not appear at the door after demanding entry, the suspect(s) fired into this residence in similar fashion," he wrote. "This suspect was on a violent spree that was tragic — but truly could have been worse for others." No one was injured in that incident.
America Hernandez described her father as outgoing, nice and a huge soccer fan. He named his daughter after his favorite team, the Mexico City-based Club América.
She said her father sometimes held four jobs at the same time, which allowed her mother to stay at home. He most recently worked as a restaurant server. "He was really a family man," she said.
They were also inseparable.
"When I was younger, I was attached by the hip to him," she said.
Ruben Hernandez loved playing soccer at Demuth Park in Palm Springs, his daughter said, adding that he also would do things for others and not ask for favors in return.
With the coronavirus pandemic limiting the size of gatherings across the country, Hernandez said the family may have a small service that will also be live-streamed for friends.
"It is kind of hard to hold something since you can't have everybody there," she said.
A GoFundMe has been set up to help the family pay for funeral expenses.
Homicide:2 arrested, 2 wanted in Cathedral City shooting that killed man and injured his 11-year-old
STAY INFORMED: Sign up for our newsletters SIGN UP FOR FACEBOOK NEWS ALERTS: Message us here to get started SUPPORT LOCAL JOURNALISM: Subscribe to DesertSun.com
Shane Newell covers breaking news and the western Coachella Valley cities of Palm Springs, Cathedral City and Desert Hot Springs. He can be reached at shane.newell@desertsun.com, (760) 778-4649 or on Twitter at @journoshane.


text:
Richmond Nights
'Mad Skillz Day' honors Richmond rap legend
by: WRIC Newsroom
Posted: Feb 13, 2020 / 05:33 PM EST
Updated: Feb 13, 2020 / 08:32 PM EST
Rapper speaks with students at John Marshall High School
RICHMOND, Va. (WRIC) — One year ago, Mayor Levar Stoney proclaimed February 13 "Mad Skillz Day" to honor one of Richmond's own.
In honor of that proclamation, Mad Skillz – real name Donnie Lewis – spoke with students at John Marshall High School Thursday about his rise in the industry.
Skills gained fame in the late 1990s and is credited with helping solidify Virginia's rise on the music scene. He's worked alongside such artists as Will Smith and Sean "Puffy" Combs and is known nationwide for his influence on the hip-hop culture.
RELATED: Mayor honors local rapper, proclaims Feb. 13 'Mad Skillz Day'
During his visit at John Marshall, he shared advice to those looking to get into the business.
"For any person looking to pursue music, I would say make sure you pay attention to the business but don't let that stifle your creativity," he said.
RELATED: Mad Skillz paves the way for Richmond rappers: 'He put Virginia hip-hop on the map'
Skillz is now a highly sought after DJ and also teaches a hip-hop focused class at the University of Richmond.
In Celebration of "Mad Skillz Day," the Broadberry is holding a free, open-to-the-public conversation with the Richmond native tonight at 6 p.m.
'I'm retiring… for good': Tom Brady announces retirement


Today I am sponsoring Just Tracy's Crafts & they very kindly asked me to GD.
They're theme is Birthdays. I decided to use Barney. I coloured him with Promarkers & made a little boy's card as I rarely do boy cards & thought Barney was perfect for it.
I have also used Dovecraft back to basics II papers which you can buy from my shop with free p&p in UK!!
Please pop over & have a peak at the wonder JTC DT's crafts & join in their challenge for a chance to win 4 digis of your choice from Ellephantastic.


There are 11 other files named edt.bwr in the archive. Click here to see a list.
or copied only in accordance with the terms of that license.
software on this TOPS-20 update tape.
problem with EDT-20, please submit an SPR.
The following restrictions apply to EDT-20 V1.0.
o	The PUSH command is journalled.
sequence is replaced by ^Z.
o   VT200 keyboards may only be used in VT100 7 bit mode.


We are a family of five who decided to try taking a different path in life. We sold most of our things, rented out our house, and hit the road in a 5th wheel to drive around the U.S.
We are planning to do this full-time for at least a year. We have been traveling full-time now for 26 months (as of June 2017) and plan to keep going for now. We love it!
The goal of fiveina5th.com is to journal our experiences as we travel, share pictures with family and friends, and provide tips and information for other families who might be considering this lifestyle. Read our post about our philosophy and reasons for doing this.
We started our journey in San Diego, California at the end of April 2015. Our route will take took us north through California, Oregon, and Washington, then south through Idaho, Utah, and Arizona. From there we'll likely meander through The South during the winter months before traveling up the East Coast and finally head back west. we went to New Mexico and Texas for the winter, then back up to Colorado, Idaho, Nevada, and Utah for the summer. We'll We enjoy stopping at places we want to visit and seeing what life around the country has to offer.
Nate is the chief navigator, chauffeur, and household handyman. He just got out of the Marine Corps after 11 years and is now an Internet entrepreneur. He earns money to support our lifestyle by developing web sites, programming, and IT consulting. He specializes in network technologies, web servers, and back end development. Nate has always enjoyed traveling and exploring new places. The full-time lifestyle was a dream waiting to be fulfilled. When the opportunity to travel the country full-time became feasible, he just couldn't let it pass by.
Angie is the Home-Schooler-In-Chief, chef extraordinaire, and assistant navigator/co-pilot. She plans the kids' curriculum, keeps them on task, and keeps the house in order. She previously taught elementary school around the world and loves teaching our kids using using the world as her classroom.
Ali is the head cat keeper and chief helper. She a friendly 9-year-old 11-year-old who is enthusiastic about life. She loves to make new friends at each new destination. Her favorite activities include exploring new places, creating art, and leading the other children in make-believe.
Nathan is a typical 7-year-old 9-year-old boy. He enjoys making obnoxious noises, keeping his sisters in check, reading books, and playing the occasional video game.
Abby loves to learn. As a curious 4-year-old busy 7-year-old, she has soaked up all kinds of tidbits as she sits alongside Ali and Nathan during school time. She likes to do homework right along with them and is quickly learning to read, do math, She is an excellent reader, loves to do math and color, and is often the first one to shout out the correct answer to history or science questions.
Our two cats. Sukuh has been around since we got her as a kitten in Okinawa 10 years ago. She's known as the cranky one, but likes to jump on a lap and cozy up during movies or when we're working at the computer. Lilly is a friendly 23-year-old with plenty of energy. Her favorite activities include eating (pretty much constantly), tormenting Sukuh, and playfully biting at Angie's heels when she walks by. The cats have adjusted well to life on the road and have both settled in to our routine.
Get a new picture of Angie!!!!!!!!
Semper Fi to Nate and family. Appreciate all the info from your site.
Any advise on the litter box location? We will be full time soon in a Motorhome.


One wouldn't think books and whiskey easily blend. But they do. In ways, I surely never imagined when I started researching whiskey for my Lucky Whiskey series. The first book, A SHOT OF MURDER: A Lucky Whiskey Mystery, drops on June 8th.
So raise a glass and read on.
Both whiskey and books start with humble beginnings – Whiskey starts its life as beer and books start, at least for me, as half-form, often unpalatable ideas, that, like beer are foul and need to be changed into something infinitely better.
Both whiskey (Irish spelling) or whisky (Scottish/Canadian spelling) are grammatically correct, though the whiskey should be used as whisky looks like the writer is just drunk, much like the ridiculous use of gray (American spelling) when it should clearly be grey (British spelling). I mean, just look at it!
Both whiskey and words must watch out for sneaky thieves – With whiskey, nearly 2% of a barrel is stolen by angels each year in what is referred to as The Angel's Share, which is about the same amount of books stolen from libraries a year. Oddly, the most pilfered book is the Guinness Book of World Records.
Both whiskey and books take a while to age. Whiskey is stored for 3 years, at least, before it hits the shelves, books take about the same from conception to a bookstore. More for me. I type really, painfully slow. That sentence alone took me nearly twenty minutes. Speaking of sentences, the longest one ever written is 823 words in Les Miserables.
Both whiskey and books have a name for people who love the smell of each – Bibliosmia for books and J.A. Kazimer for whiskey.
Both whiskey and word consumption prevents death. Whiskey is known to prevent some cancers and other diseases, while reading keeps people from killing other people. At least it does for me. I would've been jailed long ago without books.
I did find a few more glorious facts about both books and whiskey while doing research. Facts that you NEED to know for your own self-preservation.
People in Iceland read the most of all countries. You'd think they'd also drink the most whiskey considering the average temperature doesn't go above 60 degrees (F) all year. But that honor goes to one of the hottest places on Earth, India, with 1.5 billion liters of whiskey consumed a year on average.
Whiskey is a basic ingredient in Tabasco sauce. The very idea is an insult to my taste buds.
68% of books are purchased by women (yay!), and a heck of a lot of us drink whiskey. Want proof (pun intended as I love a good pun, or a bad pun, or really, any pun)? Just look at the new marketing for whiskey targeting females that often falls short – Jane Walker (it is the same whiskey as Johnnie Walker but with a woman on the label. Lame, I know).
Whiskey is the state beverage (yes, that's a thing) of Alabama.
And, finally, my favorite factoids – The name whiskey came from the Gaelic language (uisge beath) meaning 'water of life'. And even better, the word nerd was invented by Dr. Seuss in his 1950 book, "If I Ran the Zoo". My only goal in life is to craft a word as perfect as NERD.
I hope you've enjoyed the sometimes bizarre pairings of whiskey and words as much as I enjoyed researching them, except without the hangovers. So many hangovers. That's what I get for chasing good whiskey with Mountain Dew….
I'd love to hear about your favorite whiskey brand. And please share any random fact you might have about books or booze. Who knows what sort of research I'll need for my next book.
Comment to Win: A set of Dragon Whiskey Tumblers and a digital copy of A SHOT OF MURDER, A Lucky Whiskey Mystery.
Ten years after leaving the small town of Gett, Florida, for Hollywood stardom, Charlotte "Charms" Lucky, who has never quite lived up to her surname, returns home to run the Lucky Whiskey distillery while her grandfather recovers from a heart attack.
Making whiskey is harder than Charlotte imagined, especially with longtime rivals and resentful townsfolk interfering at every turn. She'll need more than a lucky charm to keep the family afloat, after she discovers her former high school boyfriend's pickled corpse in a Lucky Whiskey cask, and her grandfather is arrested for the murder.
Charlotte has one shot to clear his name and save the family business, and that is to find the real killer among a town full of suspects.
Originally from Cleveland, Ohio, j.a. left at a young age, and now lives and writes in Denver, Colorado. J.A. Kazimer holds a master's degree in forensic psychology, and has worked as a PI, bartender, and most recently at the Jack Kerouac School of Disembodied Poetics.