text:
/* The idea is that we use 32bit integers for string sort IDs which specifiy
   the sort order for primary sort condition. The whole 32bit integer space is
   used and whenever adding a string, the available space is halved and the new
   ID is added in the middle. For example if we add one mail the first time, it
   gets ID 2^31. If we then add two mails which are sorted before the first
   one, they get IDs 2^31/3 and 2^31/3*2. Once we run out of the available
   space between IDs, more space is made by renumbering some IDs.
*/
#include "lib.h"
#include "array.h"
#include "str.h"
#include "index-storage.h"
#include "index-sort-private.h"

struct mail_sort_node {
	uint32_t seq:29;
	uint32_t wanted:1;
	uint32_t no_update:1;
	uint32_t sort_id_changed:1;
	uint32_t sort_id;
};
ARRAY_DEFINE_TYPE(mail_sort_node, struct mail_sort_node);

struct sort_string_context {
	struct mail_search_sort_program *program;
	const char *primary_sort_name;

	ARRAY_TYPE(mail_sort_node) zero_nodes, nonzero_nodes, sorted_nodes;
	const char **sort_strings;
	pool_t sort_string_pool;
	unsigned int first_missing_sort_id_idx;

	uint32_t ext_id, last_seq, highest_reset_id, prev_seq;
	uint32_t lowest_nonexpunged_zero;

	unsigned int regetting:1;
	unsigned int have_all_wanted:1;
	unsigned int no_writing:1;
	unsigned int reverse:1;
	unsigned int seqs_nonsorted:1;
	unsigned int broken:1;
};

static char expunged_msg;
static struct sort_string_context *static_zero_cmp_context;

static void index_sort_list_reset_broken(struct sort_string_context *ctx);
static void index_sort_node_add(struct sort_string_context *ctx,
				struct mail_sort_node *node);

void index_sort_list_init_string(struct mail_search_sort_program *program)
{
	struct sort_string_context *ctx;
	const char *name;

	switch (program->sort_program[0] & MAIL_SORT_MASK) {
	case MAIL_SORT_CC:
		name = "sort-c";
		break;
	case MAIL_SORT_FROM:
		name = "sort-f";
		break;
	case MAIL_SORT_SUBJECT:
		name = "sort-s";
		break;
	case MAIL_SORT_TO:
		name = "sort-t";
		break;
	case MAIL_SORT_DISPLAYFROM:
		name = "sort-df";
		break;
	case MAIL_SORT_DISPLAYTO:
		name = "sort-dt";
		break;
	default:
		i_unreached();
	}

	program->context = ctx = i_new(struct sort_string_context, 1);
	ctx->reverse = (program->sort_program[0] & MAIL_SORT_FLAG_REVERSE) != 0;
	ctx->program = program;
	ctx->primary_sort_name = name;
	ctx->ext_id = mail_index_ext_register(program->t->box->index, name, 0,
					      sizeof(uint32_t),
					      sizeof(uint32_t));
	i_array_init(&ctx->zero_nodes, 128);
	i_array_init(&ctx->nonzero_nodes, 128);
}

static int sort_node_seq_cmp(const struct mail_sort_node *n1,
			     const struct mail_sort_node *n2)
{
	if (n1->seq < n2->seq)
		return -1;
	if (n1->seq > n2->seq)
		return 1;
	return 0;
}

static void index_sort_generate_seqs(struct sort_string_context *ctx)
{
	struct mail_sort_node *nodes, *nodes2;
	unsigned int i, j, count, count2;
	uint32_t seq;

	nodes = array_get_modifiable(&ctx->nonzero_nodes, &count);
	nodes2 = array_get_modifiable(&ctx->zero_nodes, &count2);

	if (!array_is_created(&ctx->program->seqs))
		i_array_init(&ctx->program->seqs, count + count2);
	else
		array_clear(&ctx->program->seqs);

	for (i = j = 0;;) {
		if (i < count && j < count2) {
			if (nodes[i].seq < nodes2[j].seq)
				seq = nodes[i++].seq;
			else
				seq = nodes2[j++].seq;
		} else if (i < count) {
			seq = nodes[i++].seq;
		} else if (j < count2) {
			seq = nodes2[j++].seq;
		} else {
			break;
		}
		array_append(&ctx->program->seqs, &seq, 1);
	}
}

static void index_sort_reget_sort_ids(struct sort_string_context *ctx)
{
	struct mail_sort_node node;
	const uint32_t *seqs;
	unsigned int i, count;

	i_assert(!ctx->regetting);
	ctx->regetting = TRUE;

	index_sort_generate_seqs(ctx);
	array_clear(&ctx->zero_nodes);
	array_clear(&ctx->nonzero_nodes);

	memset(&node, 0, sizeof(node));
	node.wanted = TRUE;
	seqs = array_get(&ctx->program->seqs, &count);
	for (i = 0; i < count; i++) {
		node.seq = seqs[i];
		index_sort_node_add(ctx, &node);
	}
	ctx->regetting = FALSE;
}

static void index_sort_node_add(struct sort_string_context *ctx,
				struct mail_sort_node *node)
{
	struct mail_index_map *map;
	const void *data;
	uint32_t reset_id;
	bool expunged;

	mail_index_lookup_ext_full(ctx->program->t->view, node->seq,
				   ctx->ext_id, &map, &data, &expunged);
	if (expunged) {
		/* we don't want to update expunged messages' sort IDs */
		node->no_update = TRUE;
		/* we can't trust expunged messages' sort IDs. they might be
		   valid, but it's also possible that sort IDs were updated
		   and the expunged messages' sort IDs became invalid. we could
		   use sort ID if we could know the extension's reset_id at the
		   time of the expunge so we could compare it to
		   highest_reset_id, but this isn't currently possible. */
		node->sort_id = 0;
	} else {
		node->sort_id = ctx->broken || data == NULL ? 0 :
			*(const uint32_t *)data;
		if (node->sort_id == 0) {
			if (ctx->lowest_nonexpunged_zero > node->seq ||
			    ctx->lowest_nonexpunged_zero == 0)
				ctx->lowest_nonexpunged_zero = node->seq;
		} else if (ctx->lowest_nonexpunged_zero != 0 &&
			   ctx->lowest_nonexpunged_zero <= node->seq) {
			index_sort_list_reset_broken(ctx);
			ctx->broken = TRUE;
			node->sort_id = 0;
		}
	}

	if (node->sort_id != 0) {
		/* if reset ID increases, lookup all existing messages' sort
		   IDs again. if it decreases, ignore the sort ID. */
		if (!mail_index_ext_get_reset_id(ctx->program->t->view, map,
						 ctx->ext_id, &reset_id))
			reset_id = 0;
		if (reset_id != ctx->highest_reset_id) {
			if (reset_id < ctx->highest_reset_id) {
				i_assert(expunged);
				node->sort_id = 0;
			} else if (ctx->have_all_wanted) {
				/* a bit late to start changing the reset_id.
				   the node lists aren't ordered by sequence
				   anymore. */
				node->sort_id = 0;
				ctx->no_writing = TRUE;
			} else {
				ctx->highest_reset_id = reset_id;
				index_sort_reget_sort_ids(ctx);
			}
		}
	}

	if (node->sort_id == 0)
		array_append(&ctx->zero_nodes, node, 1);
	else
		array_append(&ctx->nonzero_nodes, node, 1);
	if (ctx->last_seq < node->seq)
		ctx->last_seq = node->seq;
}

void index_sort_list_add_string(struct mail_search_sort_program *program,
				struct mail *mail)
{
	struct sort_string_context *ctx = program->context;
	struct mail_sort_node node;

	memset(&node, 0, sizeof(node));
	node.seq = mail->seq;
	node.wanted = TRUE;

	if (mail->seq < ctx->prev_seq)
		ctx->seqs_nonsorted = TRUE;
	ctx->prev_seq = mail->seq;

	index_sort_node_add(ctx, &node);
}

static int sort_node_zero_string_cmp(const struct mail_sort_node *n1,
				     const struct mail_sort_node *n2)
{
	struct sort_string_context *ctx = static_zero_cmp_context;
	int ret;

	ret = strcmp(ctx->sort_strings[n1->seq], ctx->sort_strings[n2->seq]);
	if (ret != 0)
		return !ctx->reverse ? ret : -ret;

	return index_sort_node_cmp_type(ctx->program->temp_mail,
					ctx->program->sort_program + 1,
					n1->seq, n2->seq);
}

static void index_sort_zeroes(struct sort_string_context *ctx)
{
	struct mail *mail = ctx->program->temp_mail;
	enum mail_sort_type sort_type = ctx->program->sort_program[0];
	string_t *str;
	pool_t pool;
	struct mail_sort_node *nodes;
	unsigned int i, count;

	/* first get all the messages' sort strings. although this takes more
	   memory, it makes error handling easier and probably also helps
	   CPU caching. */
	ctx->sort_strings = i_new(const char *, ctx->last_seq + 1);
	ctx->sort_string_pool = pool =
		pool_alloconly_create("sort strings", 1024*64);
	str = str_new(default_pool, 512);
	nodes = array_get_modifiable(&ctx->zero_nodes, &count);
	for (i = 0; i < count; i++) {
		i_assert(nodes[i].seq <= ctx->last_seq);

		T_BEGIN {
			(void)index_sort_header_get(mail, nodes[i].seq,
						    sort_type, str);
			ctx->sort_strings[nodes[i].seq] =
				str_len(str) == 0 ? "" :
				p_strdup(pool, str_c(str));
		} T_END;
	}
	str_free(&str);

	/* we have all strings, sort nodes based on them */
	static_zero_cmp_context = ctx;
	array_sort(&ctx->zero_nodes, sort_node_zero_string_cmp);
}

static const char *
index_sort_get_expunged_string(struct sort_string_context *ctx, uint32_t idx,
			       string_t *str)
{
	struct mail *mail = ctx->program->temp_mail;
	enum mail_sort_type sort_type = ctx->program->sort_program[0];
	const struct mail_sort_node *nodes;
	const char *result = NULL;
	unsigned int i, count;
	uint32_t sort_id;

	/* Look forwards and backwards to see if there are
	   identical sort_ids. If we do find them, try to get
	   their sort string and use it to update the rest. */
	nodes = array_get(&ctx->nonzero_nodes, &count);
	sort_id = nodes[idx].sort_id;
	/* If previous sort ID is identical and its sort string is set, we can
	   trust it. If it's expunged, we already verified that there are no
	   non-expunged messages. */
	if (idx > 0 && nodes[idx-1].sort_id == sort_id &&
	    ctx->sort_strings[nodes[idx].seq] != NULL)
		return ctx->sort_strings[nodes[idx].seq];

	/* Go forwards as long as there are identical sort IDs. If we find one
	   that's not expunged, update string table for all messages with
	   identical sort IDs. */
	for (i = idx + 1; i < count; i++) {
		if (nodes[i].sort_id != sort_id)
			break;

		if (ctx->sort_strings[nodes[i].seq] != NULL) {
			/* usually we fill all identical sort_ids and this
			   shouldn't happen, but we can get here if we skipped
			   over messages when binary searching */
			result = ctx->sort_strings[nodes[i].seq];
			break;
		}
		if (index_sort_header_get(mail, nodes[i].seq,
					  sort_type, str) >= 0) {
			result = str_len(str) == 0 ? "" :
				p_strdup(ctx->sort_string_pool, str_c(str));
			break;
		}
	}
	if (result == NULL) {
		/* unknown */
		return &expunged_msg;
	}

	/* fill all identical sort_ids with the same value */
	for (i = idx; i > 0 && nodes[i-1].sort_id == sort_id; i--) ;
	for (i = idx; i < count && nodes[i].sort_id == sort_id; i++)
		ctx->sort_strings[nodes[i].seq] = result;
	return result;
}

static const char *
index_sort_get_string(struct sort_string_context *ctx,
		      uint32_t idx, uint32_t seq)
{
	struct mail *mail = ctx->program->temp_mail;
	int ret;

	if (ctx->sort_strings[seq] == NULL) T_BEGIN {
		string_t *str;

		str = t_str_new(256);
		ret = index_sort_header_get(mail, seq,
					    ctx->program->sort_program[0], str);
		if (str_len(str) > 0) {
			ctx->sort_strings[seq] =
				p_strdup(ctx->sort_string_pool, str_c(str));
		} else if (ret >= 0) {
			ctx->sort_strings[seq] = "";
		} else {
			ctx->sort_strings[seq] =
				index_sort_get_expunged_string(ctx, idx, str);
		}
	} T_END;

	return ctx->sort_strings[seq];
}

static void
index_sort_bsearch(struct sort_string_context *ctx, const char *key,
		   unsigned int start_idx, unsigned int *idx_r,
		   const char **prev_str_r)
{
	const struct mail_sort_node *nodes;
	const char *str, *str2;
	unsigned int idx, left_idx, right_idx, prev;
	int ret;

	nodes = array_get_modifiable(&ctx->nonzero_nodes, &right_idx);
	i_assert(right_idx < INT_MAX);
	idx = left_idx = start_idx;
	while (left_idx < right_idx) {
		idx = (left_idx + right_idx) / 2;
		str = index_sort_get_string(ctx, idx, nodes[idx].seq);
		if (str != &expunged_msg)
			ret = strcmp(key, str);
		else {
			/* put expunged messages first */
			ret = 1;
			for (prev = idx; prev > 0; ) {
				prev--;
				str2 = index_sort_get_string(ctx, prev,
							     nodes[prev].seq);
				if (str2 != &expunged_msg) {
					ret = strcmp(key, str2);
					if (ret <= 0) {
						idx = prev;
						str = str2;
					}
					break;
				}
			}
		}
		if (ret > 0)
			left_idx = idx+1;
		else if (ret < 0)
			right_idx = idx;
		else {
			*idx_r = idx + 1;
			*prev_str_r = str;
			return;
		}
	}

	if (left_idx > idx)
		idx++;

	*idx_r = idx;
	if (idx > start_idx) {
		prev = idx;
		do {
			prev--;
			str2 = index_sort_get_string(ctx, prev,
						     nodes[prev].seq);
		} while (str2 == &expunged_msg && prev > 0 &&
			 nodes[prev-1].sort_id == nodes[prev].sort_id);
		*prev_str_r = str2;
	}
}

static void index_sort_merge(struct sort_string_context *ctx)
{
	struct mail_sort_node *znodes, *nznodes;
	const char *zstr, *nzstr, *prev_str;
	unsigned int zpos, nzpos, nz_next_pos, zcount, nzcount;
	int ret;

	/* both zero_nodes and nonzero_nodes are sorted. we'll now just have
	   to merge them together. use sorted_nodes as the result array. */
	i_array_init(&ctx->sorted_nodes, array_count(&ctx->nonzero_nodes) +
		     array_count(&ctx->zero_nodes));

	znodes = array_get_modifiable(&ctx->zero_nodes, &zcount);
	nznodes = array_get_modifiable(&ctx->nonzero_nodes, &nzcount);

	prev_str = NULL;
	for (zpos = nzpos = 0; zpos < zcount && nzpos < nzcount; ) {
		zstr = ctx->sort_strings[znodes[zpos].seq];
		nzstr = index_sort_get_string(ctx, nzpos, nznodes[nzpos].seq);

		if (nzstr != &expunged_msg)
			ret = strcmp(zstr, nzstr);
		else if (prev_str != NULL && strcmp(zstr, prev_str) == 0) {
			/* identical to previous message, must keep them
			   together */
			ret = -1;
		} else {
			/* we can't be yet sure about the order, but future
			   nznodes may reveal that the znode must be added
			   later. if future nznodes don't reveal that, we have
			   no idea about these nodes' order. so just always
			   put the expunged message first. */
			ret = 1;
		}

		if (ret <= 0) {
			array_append(&ctx->sorted_nodes, &znodes[zpos], 1);
			prev_str = zstr;
			zpos++;
		} else {
			array_append(&ctx->sorted_nodes, &nznodes[nzpos], 1);
			prev_str = nzstr;
			nzpos++;

			/* avoid looking up all existing messages' strings by
			   binary searching the next zero-node position. don't
			   bother if it looks like more work than linear
			   scanning. */
			if (zcount - zpos < (nzcount - nzpos)/2) {
				index_sort_bsearch(ctx, zstr, nzpos,
						   &nz_next_pos, &prev_str);
				array_append(&ctx->sorted_nodes,
					     &nznodes[nzpos],
					     nz_next_pos - nzpos);
				nzpos = nz_next_pos;
			}
		}
	}
	/* only one of zero_nodes and nonzero_nodes can be non-empty now */
	for (; zpos < zcount; zpos++)
		array_append(&ctx->sorted_nodes, &znodes[zpos], 1);
	for (; nzpos < nzcount; nzpos++)
		array_append(&ctx->sorted_nodes, &nznodes[nzpos], 1);

	/* future index_sort_get_string() calls use ctx->nonzero_nodes, but we
	   use only ctx->sorted_nodes. make them identical. */
	array_free(&ctx->nonzero_nodes);
	ctx->nonzero_nodes = ctx->sorted_nodes;
}

static int
index_sort_add_ids_range(struct sort_string_context *ctx,
			 unsigned int left_idx, unsigned int right_idx)
{

	struct mail_sort_node *nodes;
	unsigned int i, count, rightmost_idx, skip;
	const char *left_str = NULL, *right_str = NULL, *str = NULL;
	uint32_t left_sort_id, right_sort_id, diff;
	bool no_left_str = FALSE, no_right_str = FALSE;
	int ret;

	nodes = array_get_modifiable(&ctx->sorted_nodes, &count);
	rightmost_idx = count - 1;

	/* get the sort IDs from left and right */
	left_sort_id = nodes[left_idx].sort_id;
	right_sort_id = nodes[right_idx].sort_id;
	/* check if all of them should have the same sort IDs. we don't want
	   to hit the renumbering code in that situation. */
	if (left_sort_id == right_sort_id && left_sort_id != 0) {
		/* they should all have the same sort ID */
		for (i = left_idx + 1; i < right_idx; i++) {
			nodes[i].sort_id = left_sort_id;
			nodes[i].sort_id_changed = TRUE;
		}
		return 0;
	}

	if (left_sort_id == 0) {
		i_assert(left_idx == 0);
		left_sort_id = 1;
	}
	if (right_sort_id == 0) {
		i_assert(right_idx == rightmost_idx);
		right_sort_id = (uint32_t)-1;
	}
	i_assert(left_sort_id <= right_sort_id);

	diff = right_sort_id - left_sort_id;
	while (diff / (right_idx-left_idx + 2) == 0) {
		/* we most likely don't have enough space. we have to
		   renumber some of the existing sort IDs. do this by
		   widening the area we're giving sort IDs. */
		while (left_idx > 0) {
			if (nodes[--left_idx].sort_id != left_sort_id) {
				left_sort_id = nodes[left_idx].sort_id;
				if (left_sort_id == 0) {
					i_assert(left_idx == 0);
					left_sort_id = 1;
				}
				break;
			}
		}

		while (right_idx < rightmost_idx) {
			right_idx++;
			if (nodes[right_idx].sort_id > right_sort_id)
				break;
		}
		right_sort_id = nodes[right_idx].sort_id;
		if (right_sort_id == 0) {
			i_assert(right_idx == rightmost_idx);
			right_sort_id = (uint32_t)-1;
		}
		i_assert(left_sort_id <= right_sort_id);

		if (diff == right_sort_id - left_sort_id) {
			/* we did nothing, but there's still not enough space.
			   have to renumber the leftmost/rightmost node(s) */
			i_assert(left_idx == 0 && right_idx == rightmost_idx);
			if (left_sort_id > 1) {
				left_sort_id = 1;
				no_left_str = TRUE;
			} else {
				i_assert(right_sort_id != (uint32_t)-1);
				right_sort_id = (uint32_t)-1;
				no_right_str = TRUE;
			}
		}
		diff = right_sort_id - left_sort_id;
	}

	if (nodes[left_idx].sort_id != 0 && !no_left_str) {
		left_str = index_sort_get_string(ctx, left_idx,
						 nodes[left_idx].seq);
		if (left_str == &expunged_msg) {
			/* not equivalent with any message */
			left_str = NULL;
		}
		left_idx++;
	}
	if (nodes[right_idx].sort_id != 0 && !no_right_str) {
		right_str = index_sort_get_string(ctx, right_idx,
						  nodes[right_idx].seq);
		if (right_str == &expunged_msg) {
			/* not equivalent with any message */
			right_str = NULL;
		}
		right_idx--;
	}
	i_assert(left_idx <= right_idx);

	/* give (new) sort IDs to all nodes in left_idx..right_idx range.
	   divide the available space so that each message gets an equal sized
	   share. some messages' sort strings may be equivalent, so give them
	   the same sort IDs. */
	for (i = left_idx; i <= right_idx; i++) {
		str = index_sort_get_string(ctx, i, nodes[i].seq);
		if (str == &expunged_msg) {
			/* it doesn't really matter what we give to this
			   message, since it's only temporary and we don't
			   know its correct position anyway. so let's assume
			   it's equivalent to previous message. */
			nodes[i].sort_id = left_sort_id;
			continue;
		}

		ret = left_str == NULL ? 1 : strcmp(str, left_str);
		if (ret <= 0) {
			if (ret < 0) {
				/* broken sort_ids */
				return -1;
			}
			nodes[i].sort_id = left_sort_id;
		} else if (right_str != NULL && strcmp(str, right_str) == 0) {
			/* the rest of the sort IDs should be the same */
			nodes[i].sort_id = right_sort_id;
			left_sort_id = right_sort_id;
		} else {
			/* divide the available space equally. leave the same
			   sized space also between the first and the last
			   messages */
			skip = (right_sort_id - left_sort_id) /
				(right_idx - i + 2);
			if (skip == 0) {
				/* broken sort IDs (we previously assigned
				   left_sort_id=right_sort_id) */
				return -1;
			}
			left_sort_id += skip;
			i_assert(left_sort_id < right_sort_id);

			nodes[i].sort_id = left_sort_id;
			left_str = str;
		}
		nodes[i].sort_id_changed = TRUE;
	}
	i_assert(str != NULL);

	return right_str == NULL || strcmp(str, right_str) < 0 ||
		(strcmp(str, right_str) == 0 &&
		 nodes[i-1].sort_id == right_sort_id) ? 0 : -1;
}

static int
index_sort_add_sort_ids(struct sort_string_context *ctx)
{
	const struct mail_sort_node *nodes;
	unsigned int i, left_idx, right_idx, count;

	nodes = array_get(&ctx->sorted_nodes, &count);
	for (i = 0; i < count; i++) {
		if (nodes[i].sort_id != 0)
			continue;

		/* get the range for all sort_id=0 nodes. include the nodes
		   left and right of the range as well */
		for (right_idx = i + 1; right_idx < count; right_idx++) {
			if (nodes[right_idx].sort_id != 0)
				break;
		}
		if (right_idx == count)
			right_idx--;
		left_idx = i == 0 ? 0 : i - 1;
		if (index_sort_add_ids_range(ctx, left_idx, right_idx) < 0)
			return -1;
	}
	return 0;
}

static void index_sort_write_changed_sort_ids(struct sort_string_context *ctx)
{
	struct mail_index_transaction *itrans = ctx->program->t->itrans;
	uint32_t ext_id = ctx->ext_id;
	const struct mail_sort_node *nodes;
	unsigned int i, count;

	if (ctx->no_writing) {
		/* our reset_id is already stale - don't even bother
		   trying to write */
		return;
	}

	mail_index_ext_reset_inc(itrans, ext_id,
				 ctx->highest_reset_id, FALSE);

	/* add the missing sort IDs to index */
	nodes = array_get_modifiable(&ctx->sorted_nodes, &count);
	for (i = 0; i < count; i++) {
		i_assert(nodes[i].sort_id != 0);
		if (!nodes[i].sort_id_changed || nodes[i].no_update)
			continue;

		mail_index_update_ext(itrans, nodes[i].seq, ext_id,
				      &nodes[i].sort_id, NULL);
	}
}

static int sort_node_cmp(const struct mail_sort_node *n1,
			 const struct mail_sort_node *n2)
{
	struct sort_string_context *ctx = static_zero_cmp_context;

	if (n1->sort_id < n2->sort_id)
		return !ctx->reverse ? -1 : 1;
	if (n1->sort_id > n2->sort_id)
		return !ctx->reverse ? 1 : -1;

	return index_sort_node_cmp_type(ctx->program->temp_mail,
					ctx->program->sort_program + 1,
					n1->seq, n2->seq);
}

static void index_sort_add_missing(struct sort_string_context *ctx)
{
	struct mail_sort_node node;
	const uint32_t *seqs;
	unsigned int i, count;
	uint32_t seq, next_seq;

	ctx->have_all_wanted = TRUE;

	seqs = array_get(&ctx->program->seqs, &count);
	for (i = 0, next_seq = 1; i < count; i++) {
		if (seqs[i] == next_seq)
			next_seq++;
		else {
			i_assert(next_seq < seqs[i]);
			for (seq = next_seq; seq < seqs[i]; seq++) {
				memset(&node, 0, sizeof(node));
				node.seq = seq;
				index_sort_node_add(ctx, &node);
			}
			next_seq = seqs[i] + 1;
		}
	}

	if (ctx->lowest_nonexpunged_zero == 0) {
		/* we're handling only expunged zeros. if it causes us to
		   renumber some existing sort IDs, don't save them. */
		ctx->no_writing = TRUE;
	}
}

static void index_sort_list_reset_broken(struct sort_string_context *ctx)
{
	struct mailbox *box = ctx->program->t->box;
	struct mail_sort_node *node;

	mail_storage_set_critical(box->storage,
				  "%s: Broken %s indexes, resetting",
				  box->name, ctx->primary_sort_name);

	array_clear(&ctx->zero_nodes);
	array_append_array(&ctx->zero_nodes,
			   &ctx->nonzero_nodes);
	array_clear(&ctx->nonzero_nodes);

	array_foreach_modifiable(&ctx->zero_nodes, node)
		node->sort_id = 0;
}

void index_sort_list_finish_string(struct mail_search_sort_program *program)
{
	struct sort_string_context *ctx = program->context;
	const struct mail_sort_node *nodes;
	unsigned int i, count;
	uint32_t seq;

	static_zero_cmp_context = ctx;
	if (array_count(&ctx->zero_nodes) == 0) {
		/* fast path: we have all sort IDs */
		array_sort(&ctx->nonzero_nodes, sort_node_cmp);

		nodes = array_get(&ctx->nonzero_nodes, &count);
		if (!array_is_created(&program->seqs))
			i_array_init(&program->seqs, count);
		else
			array_clear(&program->seqs);

		for (i = 0; i < count; i++) {
			seq = nodes[i].seq;
			array_append(&program->seqs, &seq, 1);
		}
		array_free(&ctx->nonzero_nodes);
	} else {
		if (ctx->seqs_nonsorted) {
			/* the nodes need to be sorted by sequence initially */
			array_sort(&ctx->zero_nodes, sort_node_seq_cmp);
			array_sort(&ctx->nonzero_nodes, sort_node_seq_cmp);
		}

		/* we have to add some sort IDs. we'll do this for all
		   messages, so first remember what messages we wanted
		   to know about. */
		index_sort_generate_seqs(ctx);
		/* add messages not in seqs list */
		index_sort_add_missing(ctx);
		/* sort all messages with sort IDs */
		array_sort(&ctx->nonzero_nodes, sort_node_cmp);
		for (;;) {
			/* sort all messages without sort IDs */
			index_sort_zeroes(ctx);

			if (ctx->reverse) {
				/* sort lists are descending currently, but
				   merging and sort ID assigning works only
				   with ascending lists. reverse the lists
				   temporarily. we can't do this while earlier
				   because secondary sort conditions must not
				   be reversed in results (but while assigning
				   sort IDs it doesn't matter). */
				array_reverse(&ctx->nonzero_nodes);
				array_reverse(&ctx->zero_nodes);
			}

			/* merge zero and non-zero arrays into sorted_nodes */
			index_sort_merge(ctx);
			/* give sort IDs to messages missing them */
			if (index_sort_add_sort_ids(ctx) == 0)
				break;

			/* broken, try again with sort IDs reset */
			index_sort_list_reset_broken(ctx);
		}
		index_sort_write_changed_sort_ids(ctx);

		if (ctx->reverse) {
			/* restore the correct sort order */
			array_reverse(&ctx->sorted_nodes);
		}

		nodes = array_get(&ctx->sorted_nodes, &count);
		array_clear(&program->seqs);
		for (i = 0; i < count; i++) {
			if (nodes[i].wanted) {
				seq = nodes[i].seq;
				array_append(&program->seqs, &seq, 1);
			}
		}
		pool_unref(&ctx->sort_string_pool);
		i_free(ctx->sort_strings);
		array_free(&ctx->sorted_nodes);
		/* NOTE: we already freed nonzero_nodes and made it point to
		   sorted_nodes. */
	}

	array_free(&ctx->zero_nodes);
	i_free(ctx);
	program->context = NULL;
}

redpajama_set_name: RedPajamaGithub


USDA Dietary Guidelines Controversy Hartke Is Online!
Good nutrition is key to any weight loss plan. Learn to use nutrition labels and guidelines to pick the foods and portions that are right for you.... Food buying Guide for Child Nutrition Program. food items in your Favorites list, A Level 1 USDA eAuthentication account is needed to access the tool.


A bathroom is a key part of your house which you will need to take time before you can choose the best shower enclosure kit to install in the bathroom. The perfect design for your bathroom will transform the bathroom and give it elegance and a sense of style. Similarly, the right design will help in maximizing the bathroom space hence making it more comfortable. For this reason, when you are looking for a shower enclosure kits you may face some difficulties because of the many choices you are to choose from.
If you are planning to choose a shower enclosure kit but you don't a clue on how to go about it, worry no more. In this article, we give some of the factors you will consider when choosing a shower enclosure which will suit you.
Before you can even g out shopping, you will need to understand the kind of space that your bathroom has. This knowledge will help you understand whether you will need a wet room, shower bath or a walk in shower. This aspect will be essential to look for because, for example, you might buy a walk in shower enclosure kit which will not fit the space in your bathroom. In addition, you will need to understand whether the enclosure will be ensuite or it will be the main bathroom or a separate bathroom. With this aspect in mind then you will not go wrong I choosing the best shower enclosure kit.
You will also be required to understand where you will lace your shower enclosure before you go out purchasing one. Determine whether the enclosure will be installed in the center or a corner in the bathroom. This aspect will be crucial when you will be shopping for shower trays and the kind of doors that the enclosure will have. For instance, if you will choose to place your shower enclosure kit at the center position of the bathroom, you will need to purchase a D shaped shower enclosure kit.
There are several types of doors which you will need to choose from. For this reason, you will be required to understand what you need. When choosing a glass or the shower enclosure, you can consider going for tempered glass which is known t be highly durable, easy to clean and also very safe. A toughened glass will be a perfect choice for a wet shower enclosure. It is also essential to note that thicker glass will require more support because of the additional weight they have.


In light of the County's aggregate indebtedness, the Firm believes that these amounts are not material. This way all parties concerned will be on the same page with regards to what is happening to the investments. While bondholders have suffered minor losses or delayed payments in previous chapter 9 cases, if Stockton's case proceeds as planned, it would mark the first time that a municipality significantly impaired its obligations to bondholders. Those notes will come due next June. Members of the Tongva, Juaneño, and Luiseño Native American groups long inhabited the area. Further, you can have past due taxes, student loans and child support payments paid off within the plan as well.
In particular, the bankruptcy court determined that the Alabama statute authorizing chapter 9 filings only enabled permitted municipalities with bonded debt to file. At the court's encouragement, the parties negotiated new labor agreements. Specifically, the developer was aware that one class of the town's creditors would vote to confirm the plan, which would allow the debtor to cram down the plan over the developer's objection. This information on this website is not intended to create, and receipt or viewing of this information does not constitute, an attorney-client relationship. The construction and operation of the plant went over budget, and the original forecasts of the revenues that would be generated from the plant proved to be overly optimistic. The local economy was doing very well and in a matter of 18 months was able to haul itself out of bankruptcy.
Detroit's bankruptcy filing presents numerous complicated issues, which will be resolved over the course of the case. Consult with your attorney if your debt is unusually high. Generally, property acquired after the commencement of a case is not subject to any lien resulting from a pre-petition security agreement. Bildisco, which was decided prior to the enactment of section 1113, held that under section 365, a debtor could unilaterally reject or modify a collective bargaining agreement without complying with applicable state law. Merrill Lynch lawyers filed the most vigorous objection to the county's recovery plan, arguing that the document contains improper language stating that the county was insolvent at the time of its bankruptcy filing and had no other option but to seek Chapter 9 protection. Unlike most general purpose municipalities that file for bankruptcy, Vallejo's financial distress was not caused by excessive debt.
The district court therefore reversed the bankruptcy court's decision and remanded the case. Use, Sale or Lease of Property § 363 A chapter 9 debtor can use, sell or lease its property without bankruptcy court approval or oversight. County attorneys say Merrill's risky investments caused the losses, and the firm must accept blame for its actions. The monthly payments have become more than he can handle and the creditor phone calls are driving him crazy. Chapter 13 Reorganization If your disposable income is too high, or if you wish to continue operating your small business, or you face foreclosure of your home, then a Chapter 13 is an option. Importantly, the plan of adjustment must also be in the best interest of creditors. In addition, the county lowered the costs of its debt service by entering into swap agreements under which the county would swap long-term fixed higher interest rate debt into short-term variable rate debt.
A chapter 11 debtor cannot use, sell or lease property outside of the ordinary course without bankruptcy court approval. A chapter 9 debtor also must file a list of all of its creditors. Next, the advisory discusses significant chapter 9 cases since the Orange County bankruptcy case in 1994—the largest municipal bankruptcy at the time. Solution: Bob and Lucy contacted us about their mortgage crisis. In 2008, Jefferson County defaulted on its debt obligations, which resulted in the acceleration of the debt.
Citron had a fairly free hand in investment decisions with low priority on reporting. Ambac's municipal bond obligations remained in the general account and, therefore, were not affected by the rehabilitation proceeding. The Firm may also represent the County, an affiliated entity, in its related case under chapter 9. To pay for the property, they took out a first and a second mortgage and both loans were interest only. Result: By filing bankruptcy, Jenny was able to put an immediate stop to the lawsuit against her without any of her wages being garnished. Litigation and a buoyant economy helped right many of the wrongs. It compiles the chronological events which led to the bankruptcy of Orange County.
The investments had been made by a county desperate to get additional profits on its investments to pay for government services. Individuals not guaranteed assistance after 10:00 a. As part of the confirmed plan, the city closed fire stations, reduced public services, cut staffing requirements, laid off city workers, required new city workers to contribute more to their pensions and all employees to contribute more for their health insurance and sought new revenue. Our firm filed a Motion for Contempt and for Sanctions for Violations of the Automatic Stay within the core bankruptcy proceeding. His principal advisors for the kind of instruments he could invest in were Merrill Lynch. By making the minimum payments each month, you are ensuring that you repay the amount you borrowed many times over and digging yourself out of the financial hole becomes more and more difficult.
However, bankruptcy courts have found that municipal debtors have not acted in good faith where the debtors never exercised their assessment powers prior to initiating proceedings in bankruptcy court. In addition, the city experienced budgetary stress as 75 percent of Stockton's general fund was used for the public safety payroll and to service debt, and satisfying pension obligations accounted for nearly 13 percent of the city's overall spending. San Bernardino has indicated that it intends to resume making payments. Any claim listed on the list of creditors is a proof of claim deemed filed under § 501, unless filed as contingent, disputed or unliquidated. One of her credit card companies has now filed a lawsuit against her and she is worried a wage garnishment will push her over the edge.


text:
What are the themes of boy?
What film techniques are used in hunt for the Wilderpeople?
Where in NZ is boy filmed?
What does the movie Boy teach us?
What are two major themes found in about a boy?
What are the main themes in The Boy in the Striped Pyjamas?
What is the moral of hunt for the Wilderpeople?
How does hunt for the Wilderpeople end?
What happens at the end of Boy?
What was the budget for Boy?
What happens at the end of the movie Boy?
How is Shmuel innocent?
Where was the movie Boy filmed in New Zealand?
Who are the producers of the movie Boy?
Where was the movie Boy by Taika Waititi filmed?
What was the soundtrack to the movie Boy?
Boy deals with themes of family, fatherhood, responsibility, the innocence and imagination of childhood that is lost when one grows up, hero worship, and the heartbreaking loss of innocence.
Hunt for the Wilderpeople
Direct Sound. Music, noise, and dialogue, recorded live while filming.
180-Degree Rule.
Non-Diegetic Sound.
Score.
Aerial Shot.
Parallel Action.
Sequence.
Wipe.
Waihau Bay
BOY was filmed in Waihau Bay in the Bay of Plenty, where Waititi grew up. The film is inspired by "true and imagined memories".
Taika Waititi's Boy: Exploring Masculinity from an Indigenous Perspective. New Zealand filmmaker Taika Waititi's comedy-drama Boy (2010) that explores the complexity of familial dysfunction and hero worship through a Māori (indigenous people of New Zealand) perspective.
The theme of depression/mental illness is one that concerns the author, Nick Hornby, very much. Fiona, Marcus' mother, suffers from depression and attempts suicide at one point in the novel. This naturally affects not just Fiona, but Marcus as well, and even has wider repercussions among their friends.
The Boy in the Striped Pajamas Themes
Innocence and Ignorance. Bruno, the main character of The Boy in the Striped Pajamas, is a nine-year-old boy who is the son of a German Commandant (Father) during World War II.
Boundaries.
Family and Friendship.
Nationalism.
Gender Roles.
Complicity.
Hunt for the Wilderpeople is a heart-warming and funny movie about family, friendship and belonging. It's also about being a teenager and rebelling against authority. There's a real magic between Sam Neil as Hector, the gruff loner, and Julian Dennison as Ricky. the importance of family, including foster families.
It seems that by the end of The Hunt for The Wilderpeople, Ricky is finally comfortable being himself and that means shedding the style that makes him seem tougher. We the audience also witness Ricky learn to survive in the wild. He's a city kid who learns to hunt, navigate, and other survivalist things.
The mirror explodes; from a hole behind it emerges the real, now-adult Brahms wearing a porcelain mask identical to the doll's face; after surviving the fire, Brahms has been living in the walls of the house and is abnormal. Brahms kills Cole, then turns on Malcolm and Greta.
In scenario that would be perfect for a film script, Taika Waititi has just 12 days to raise over $63,000 so he can release his movie Boy in the United States. Using the funding website Kickstarter, the Kiwi director has already raised $23,000 of the $90,000 he needs to get the movie released.
In the closing scene of the film, Brahms can be seen putting back pieces of the doll together, suggesting that he is probably still alive. From all of this, we can deduce that Brahms never died in the first place. He was always a twisted little kid and he ended up murdering Emily Cribbs on his 8th birthday.
Shmuel is a prisoner in Auschwitz. This creates a political tension between them, one where the ethics of the aggressor meets that of the prisoner. However, their innocence is enhanced because their friendship transcends the political.
Instead of making BOY his first film, Waititi went on to make Eagle vs Shark and continued to develop the screenplay over the next 3 years. BOY was filmed in Waihau Bay in the Bay of Plenty, where Waititi grew up. The film is inspired by "true and imagined memories".
It is produced by Cliff Curtis, Ainsley Gardiner and Emanuel Michael and financed by the New Zealand Film Commission. In New Zealand, the film eclipsed previous records for a first week's box office takings for a local production. Boy went on to become the highest-grossing New Zealand film at the local box office.
BOY was filmed in Waihau Bay in the Bay of Plenty, where Waititi grew up. The film is inspired by "true and imagined memories". Says Waititi, "Part of what makes this film distinct is the humour; I want to explore the painful comedy of growing up and interpreting the world.
In New Zealand, the film eclipsed previous records for a first week's box office takings for a local production. Boy went on to become the highest-grossing New Zealand film at the local box office. The soundtrack to Boy features New Zealand artists such as The Phoenix Foundation, who previously provided music for Waititi's film Eagle vs Shark .
Who is E-40 son?
What is lace stitching?

redpajama_set_name: RedPajamaCommonCrawl


text:
Q: После выполнения php скрипта, выполняется замена содержимого формы, как выполнить ещё одну замену чтобы всё обработалось снова? Выполняю вот такой скрипт.
   <?php
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        if (isset($_POST['name'])) {$name = $_POST['name'];}
        if (isset($_POST['phone'])) {$phone = $_POST['phone'];}
        if (isset($_POST['formData'])) {$formData = $_POST['formData'];}
        if (isset($_POST['formCalc'])) {$formCalc = $_POST['formCalc'];}
        $to = "222@rr.com";
        $to = "asd@asd.ru";
        $headers  = "From: " . strip_tags($sendfrom) . "\r\n";
        $headers .= "Reply-To: ". strip_tags($sendfrom) . "\r\n";
        $headers .= "MIME-Version: 1.0\r\n";
        $headers .= "Content-Type: text/html;charset=utf-8 \r\n";
        $subject = "$formData";
        if ($formCalc != null && $formCalc != 0 ) {
            $message = "$formData
 Имя пославшего: $name
Телефон: $phone
 Результат вычислений $formCalc";
        } else {
            $message = "$formData
 Имя пославшего: $name
Телефон: $phone";
        }

        $send = mail ($to, $subject, $message, $headers, "-fpotolki@jurgomel.ru");
        if ($send == 'true')
        { echo '
Спасибо за отправку вашего сообщения!
';
        }
        else
        {
        echo '
Ошибка. Сообщение не отправлено!
';
        }
    } else {
        http_response_code(403);
        echo "Попробуйте еще раз";
    }?>

После, через js, обновляю на нажатие крестика, форму. И когда собираюсь совершить снова отправку сообщения - обновляется страница. Что я делаю не так?
$('#modal_close, #overlay').click( function(){
        $('#modal_form')
            .animate({opacity: 0, top: '45%'}, 200,
                function(){
                    $(this).css('display', 'none');
                    $('#overlay').fadeOut(400);
                }
            );
        $(".form_modal").html('<form id="form">
Оставьте ваши контактные данные и наш консультант свяжется
с вами
 ' +
            '<input type="text" class="putName" name="name" placeholder="Ваше ваше имя" required>'+
            '<input name="phone" type="tel" class="putPhone" placeholder="Введите номер телефона" required>'+
            '<input type="submit" name="submit" class="btn" value="ОТПРАВИТЬ">' +
            '<input type="hidden" name="formData" value="Заявка с сайта">'+
            '<input type="hidden" name="formCalc" id="Calc-feedback" value="0">'+
            '</form>');
    });

Вот сам код на сайте:

          <form id="form">

Оставьте ваши контактные данные и наш консультант свяжется
с вами

            <input type="text" class="putName" name="name" placeholder="Ваше ваше имя" required>
            <input name="phone" type="tel" class="putPhone" placeholder="Введите номер телефона" required>
            <input type="submit" name="submit" class="btn" value="ОТПРАВИТЬ">
            <input type="hidden" name="formData" value="Заявка с сайта потолки Буда-Кошелёво">
            <input type="hidden" name="formCalc" id="Calc-feedback" value="0">
          </form>

A: Потому что вы пересоздаете элемент. Тогда AJAX работать не будет. Проще так: формы вроде как одинаковые, просто очищайте инпуты.
ВТОРОЙ ВАРИАНТ:
<form id="form">

замените на
<form id="form" class="form_modal">

удалите:

 и его закрывающий

и в JS удалите:
<form id="form"> и </form>

A: Похоже что ваша формы отправляет данные... в никуда.  Попробуйте добавить тегу form атрибуты method и action. Укажите в action URL своего скрипта и форма отправит запрос по нужному адресу.

redpajama_set_name: RedPajamaStackExchange


text:
Sabrina lived in unbearable conditions and her landlord kept refusing to make repairs to her unit. The home was infested with rats, cockroaches, and mold; and there were numerous problems with the plumbing and electricity. "We didn't have heat for months at a time," she recalls. "Sometimes the lights in the house didn't even work."
Sabrina contacted the SF Housing Authority to conduct inspections, which the landlord failed. As a result, the landlord lost his rent subsidy from the Housing Authority. Defeated and furious, the landlord tried to persecute Sabrina, attempting to have her government housing benefits taken away. When this did not happen, he attempted to evict Sabrina and her children from their home for physical damage that Sabrina had nothing to do with.
At this point, she decided to seek legal advice. She was first referred to the Housing Rights Committee, who helped get her hearings with the City and County of San Francisco. As a result of the hearings, the landlord was legally obligated to make the repairs and pass inspections, or else face fines. However, at the time of inspection, the landlord would "patch up" or make temporary repairs, and in the meantime continued to try to evict Sabrina. Terrified of losing her government housing benefits, she was compelled to move out of her apartment but continued to seek justice for her cause.
She found out about Open Door Legal through a Salvation Army program, which shares space with our legal services office. Her case was soon taken on by one of our volunteer attorneys, Julia Quinn. Julia secured $20,000 in damages, partly for the possessions Sabrina had to throw away when she moved because she could not afford a moving truck.
"The only thing I got to take were my kids' clothes, because that's all that fit in the car," she recounts. After years of facing eviction, living in appalling conditions, and losing most of her possessions, Sabrina was relieved to finally receive justice and begin to rebuild her life. Although Open Door Legal did help her win the case, Sabrina says legal support wasn't the only thing that they offered.
"The people who helped me really were compassionate, understanding about my issues, and gave me support more than just doing the paperwork. There were times when I was stressed and crying, and they just helped me through everything. They rock." She walked away with more than just money in her pocket; she also had the reassurance that "[the landlord] can no longer do that to me or anybody else."
Everett →


We start from Molyvos Camping about 10:00.
Following the treks up to Vafios where we will stay for coffee.
We start from Molyvos Camping.
for a delicious BBQ with wine before returning to Molyvos.
The 8,00 been paid to the owner of Donkey Farm.


Thanks to his great disposition and Wes Anderson, Bill Murray has managed to remain a leading man at 65 years-old. Unfortunately, this is one of those kitchen-sink movies where everything gets thrown in to see what floats.
Sure, Murray is here. Hollywood legend Barry Levinson is brought to direct, and they toss Mitch Glazer ("Scrooged") in a chair to write Murray some material. It's all paint by numbers.
Current cutie Zooey Deschanel has a small role, but her cute is rubbed off and replaced with annoying. I'm still not sure what Kate Hudson and Bruce Willis do in this movie. Danny McBride and Scott Caan show up for some fun reason. A plot comes into play involving gender violence in the Middle East which gets extremely unbelievable.
The good news is Palestinian actress Leem Lubany is delightful, and Murray has some nice moments, but it's still barely worth a watch.
Let's start with the goodbye. This is Philip Seymour Hoffman's last film. You will be missed, Mr. Hoffman. Now, let's get hungry, because four films in, and this franchise finale still feels like it has something to prove. The chemistry between Jennifer Lawrence, Josh Hutcherson and Liam Hemsworth has only evolved into pure weirdness (in a good way).
Director Francis Lawrence took the helm on the second film and built the action-packed world of Suzanne Collins' novels. This world is intensely alive with her characters because of the performances of Woody Harrelson, Donald Sutherland, Julianne Moore, Elizabeth Banks, Jena Malone, Jeffrey Wright, Stanley Tucci and the other well-placed actors. This should be the model of how young-adult franchises are done. It propelled a well-deserved Lawrence into stardom. It gave girls a kickass action hero, and it's worth a watch.


ClipsFatale contains adult content which some viewers may find offensive.
Due to the adult nature of the site, access is restricted to persons over the age of 18.
All material on ClipsFatale portrays consenting adults.
Sorry, can't find domstrapon1. Return to the home page.
© 2019 Sunkat Ltd. All rights reserved.


When Danny got down on one knee, almost six months ago in Carmel, California, I said yes instantly and then collapsed in hysterics.
I didn't see it coming. Sounds weird as we had been together almost three years (or over three years, depending on when you take the dates from), we lived together, we had two cats, were happy. But I didn't.
The day after he proposed we drove to Santa Barbara, met my friend Jess and I started to think about the wedding.
come to the wedding. This list, too, seemed endless.
Since then I have written around eight different lists. I have put them on excel sheets, on google spreadsheets, back to my Donald Duck pad, on my iPad, on my iPhone, on my work PC.
Am I any closer to having anything organised? Am I hell.
The wedding is in six months. I have a dress, he has a suit. We have a menu, we have a website. We have flights, a venue. We have some decorations. We have about a million candle holders.
We have a stressed bride to be.


text:
Q: Is there an elegant way in Ruby to filter a hash of arrays of hashses? Let's say I have a this type of data structure:
{
  "foo": [{state: on}, {state: off}, {state: on}],
  "bar": [{state: off}, {state: off}, {state: on}],
  "baz": [{state: on}, {state: on}, {state: on}]
}

How can I filter the nested hash arrays in an elegant way so I can get back this:
{
  "foo": [{state: on}, {state: on}],
  "bar": [{state: on}],
  "baz": [{state: on}, {state: on}, {state: on}]
}

A: a={
    "foo": [{state: "on"}, {state: "off"}, {state: "on"}],
    "bar": [{state: "off"}, {state: "off"}, {state: "on"}],
    "baz": [{state: "on"}, {state: "on"}, {state: "on"}]
}

Code
p a.transform_values{|arr| arr.select{|h|h[:state].eql?'on'}}

Result
{:foo=>[{:state=>"on"}, {:state=>"on"}], :bar=>[{:state=>"on"}], :baz=>[{:state=>"on"}, {:state=>"on"}, {:state=>"on"}]}

A: Given:
data = {
  "foo": [{state: :on}, {state: :off}, {state: :on}],
  "bar": [{state: :off}, {state: :off}, {state: :on}],
  "baz": [{state: :on}, {state: :on}, {state: :on}]
}

Use #transform_values to iterate and replace the hash values and #select to filter the elements in the array:
data.transform_values do |value|
  value.select { |hash| hash[:state] == :on  }
end


# Write a shell script which deletes all even numbered line from a text file.
for some reason your simplified command does not work on my mac. But the following works like a charm.
I want to combine to text file in unix. Both text files have 100 lines each, i want to only take the 1st 60 line from the 1st file and combine it with the 2nd file.


AnticStore > Catalogue > Sculpture > Marble Sculpture > Middle age > 16th century > St Roch panel in painted alabaster, Nottingham XVth c.
St Roch panel in painted alabaster, Nottingham XVth c.
Relief depicting St Roch, accompanied by his dog bringing a loaf, and an angel.
Breaks in the upper part. Broken nose with trace of restoration. Lacks to St Roch's hands. Important rest of the original polychromy.
These reliefs were generally included in altarpieces.
See Nottingham's St Roch in Alabaster kept at the Victoria & Albert Museum for similar iconography.


The Zimbabwean network provider Telecel must meet the government's requirements in order to get its license renewed. 60% of the company is held by the Egyptian telecom company Orascom Telecom, and 40% by the holding firm led by Leo MUGABE, the President's nephew. The company does not meet the standards upheld by the Indigenisation and Economic Empowerment Act.
The program's goal is to transfer at least 51% of control of all its companies with foreign investors to local investors or to the government.


Check removal quotes for your move from Ottershaw to Ireland, Bulgaria and other places in Europe.
Inspect various financial estimates chargeless and with no bond for your shipment to Greece, Serbia and everywhere you desire.
Do you have a yen to relocate abroad from Ottershaw to France, Belarus or Romania? Do you aim to haul your household goods and alternative movables like stepladder, chair or potato ricer to Germany, Czech Republic or Kosovo? On our website you are able to request and compare relocation proposals from true-hearted European freight forwarders in Ottershaw, exceptionally free of charge. We could help you investigate trusted transportation services from Ottershaw to Spain, Russia, Amsterdam or Slovakia at special offer rates.
Our cargo shippers have been forwarding to Holland and Lithuania private belongings like midi Hi-Fi, table or mixing spoonall for years. Chiefly they carry out rhythmic shipping from Ottershaw to Belgium and United Kingdom. There is a selection of extra very crowd-pleasing towns like San Marino, Paris or Vatican City. British people are also exporting their everyday-use items from Ottershaw to Italy, Azerbaijan and Vilnius. Doesn't matter what you are shipping, step machine, wireless set or electric mixer you will check Up to six moving offers for your removals from Ottershaw to Portugal, Poland, Murcia, Bayat, Simav or La Neuveville. To summarise on our web portal you can receive and compare removal prices for every type of removals you need.
1 case removals to Switzerland from Ottershaw, outboard motor, game tables or funnel moving to Hungary, Stockholm, Suşehri, and further regions.
Every time pick-up and transport to Sweden, Montenegro, Nuremberg, Güroymak from Ottershaw.
family gear transportation to Finland, Monaco, Stuttgart, Elvas from Ottershaw.
Please take into consideration that we have touched up on exclusively small number of areas that you may examine bids for. Trough our service you are in position to obtain removal costs for any carton, table + 4 chairs, folding table or even pestle removals to Iceland, Georgia, Bucharest, Krems and wherever in Europe. Fill out entirely one easy online form and request rates for moving from Ottershaw to Austria, Bosnia & Herzegovina, Cluj-Napoca, Gökçe or Newbridge.
You will also inspect transport from Ottershaw to Slovenia, Serbia and Montenegro, Malta, Bulgaria, Athens, Gandra and more.
My flat has been entirely unspoiled and they provided so much heart with our chattels and our spick-and-span apartment. The relocation firms are trusty and exacting, and the user services optimal.
Willy, Russel and Sheldon are wholly perfect! The export packing firms has been sensational. The relocation from Ottershaw to Ellezelles in Belgium has gone completely no swet.
The relocation to Spilimbergo in Italy from Ottershaw was my groom,'s desire for so long. Therefore we mapped out our move. Your attractive WWW portal enabled us to request the most meaningful financial estimate could negotiate. Your bunch are fully unreal! I've never been more pleased!
That cumulus congestus has been immensely unpleasant and her wife has been quite fearful on the grounds of the transport of our wares from Ottershaw to Merscheid in Luxemburg. With flying colors each thing rolled as planned!
We were very fascinated with your services available at your website - your porters have been all wholly dedicated - and I would clearly call you again. I have managed to save masses of whiles and tracked down a trusted Ottershaw removal company by checking your services.


text:
Home Archive Embracing Technology
Front News
The traditional travel management company model has had to evolve, largely due to the technological advancement that has changed our lives and changed the way people book and engage in travel.
It's a different world out there.
The times are changing and they are changing quickly. Technology dominates our lives and it's technology that is ever evolving, with increased information at our fingertips and trends changing all the time. Throw in some economic uncertainty and increased competition, and you have a challenging environment in which to operate.
That applies to just about every industry, but what does it mean for the travel industry, and specifically those in travel management?
Well, quite simply, the role of a travel manager has become increasingly complex. The influx of online travel agencies and platforms has meant that more and more consumers are opting to be their own travel manager.
The demands of the corporate traveller are becoming more challenging too. Budgets have contracted, yet the travel needs of businesses have largely remained the same. In fact, many travel managers believe the cost of travel is actually increasing.
So, where does that leave the travel management company?
"Defining our value as travel professionals is perhaps the biggest challenge facing TMCs today," says Euan McNeil, General Manager of FCM Travel Solutions, part of the Flight Centre group in South Africa. "Corporate travel agents were in the past transactional and earned their revenue based on the transactions they performed on behalf of the client – booking a flight or hotel, changing the date of a ticket etc. With the advent of travel technology, customers have become empowered (although not necessary inclined) to conclude some of these transactions themselves. The result is that the transactional part of the job of travel agent has been eroded, and the requirement by customers is thus a more consultative approach. Herein lies the challenge, as TMCs work to define and communicate effectively the consultative value they bring to the end customer and determine what to charge for that value."
McNeil touches on the essence of the thread that will be explored throughout this piece, as there is no doubt that technological advancement has had the greatest impact on the role that TMCs now play, as it relates to their clients.
"Every TMC is currently under pressure to showcase their value to clients due to enhanced technology available in the market," says Yasmeen Khan, Head: Business Development, Corporate at Wings Travel. "This requires a consistent approach in terms of managing the clients' travel spend and demonstrating in various ways the true value of our partnership."
"Our challenges are the same as most TMCs," says Bronwyn Humphries, Marketing Co- Ordinator, Harvey World Travel Franchise Support Team. "This would be new competitors in the market as well as online travel agents. There's also a definite shift to online tools for corporate clients, with corporates more likely to book their own 'bleisure' trips, for example, along with cutting their costs."
"Corporate travel is finally starting to learn lessons from the consumer travel space, mostly because business travellers have been trained by their leisure travel to expect robust booking tools and more control over their trips," says Andrew Sheivachman, Senior Writer at Skift, an intelligence platform providing media, insights and marketing to key sectors of travel. "The travel management companies that focus the most on improving their traveller-facing technology will win this battle, and improve their clients' travel experience in the process."
So, what are TMCs doing to stay ahead of the game and remain relevant? Specifically, what technology and services are they developing to remain of value to their clients? One way is to go the 'whole hog' and develop your own tech.
"At Tourvest Travel Services we have developed our own online travel management solution called Travelit, which was developed not just with the customer in mind, but also the travel consultant," says Claude Vankeirsbilck, Chief Sales & Marketing Officer. "This means our travel consultants work on the same technology platform as our clients, offering full transparency and a more efficient service delivery process. There are weekly product enhancements and developments driven by our own developmental team. This allows TTS to be more competitive, more efficient in service delivery, and ultimately offer more value to our customers, as our technology solution adds value to the customer's bottom line."
That's the key, isn't it? Adding value by recognising the complementary relationship between the TMC and the technology. It seems almost obvious to say that those TMCs who view technology as a threat are dead in the water. It's all about embracing the tech out there, identifying which tech complements the TMC's existing offering, and then rolling it out in a way that provides the customer with that value and ultimately strengthens the supplier-customer relationship.
"One of the biggest challenges is the accessibility that a traveller now has to a range of pricing across various consolidator websites etc," says Khan. "In order to be ahead of the game, Wings Travel Management has developed its own proprietary technology in order to integrate such developments outside of our normal reservations system, thereby enhancing content and ensuring that we offer the best price to our customers."
The Wings model is slightly different from other TMC models in that the group favours wholly-owned global offices over franchise agreements, but the benefits of that model extend into the tech space.
"Our Wings globally-owned offices allow us to truly standardise our sales platforms across the globe by giving our clients consistent and reliable data, and offering them access to all our proprietary products," says Khan. "Wings boasts a reporting tool which is accessible via URL and includes live data with many enhanced features, offering clients a snapshot view of their travel spend, travel patterns and detailed insights into traveller behaviour, allowing a proactive approach in terms of managing their spend."
Another area where Wings has focused its technological efforts is the increasingly important duty of care space. It recently launched goSecure, a risk management solution for their clientele that allows them to track and communicate directly with their travellers via a mobile application, coupled with the Wings24 emergency contact centre, which manages risk and traveller safety on behalf of Wings' clients.
For McNeil, the technology has to be complementary, and he believes a lot more thought needs to be given to this area before a TMC rolls out the latest tech. Specifically, he believes there almost needs to be a 'division of labour' between what the technology can offer and what the TMC and its staff are best equipped to focus on.
"To remain relevant and viable, it is essential that we use technology to drive automation and improve service for our mutual benefit," he says. "Non-complex bookings should be automated, freeing up skilled travel professionals to focus on areas in which they can truly add value beyond the transaction, for example in the areas of data analysis, duty of care and supplier negotiations."
To this end, FCM has developed a chatbot in the United States. It's called 'Sam' and promises the expertise of a skilled FCM consultant available at all times: pre, during, and post-trip. Sam is a travel-savvy chatbot that can assist with all aspects of travel – itineraries, gate changes, driving directions, weather, restaurant recommendations and reservations. There's also 'call or SMS my consultant' functionality, which gives travellers access to a live FCM consultant 24 hours a day for live assistance on the go.
"Every travel programme should have technology that clearly focuses on improving the traveller, travel booker and travel manager's experience," says McNeil. "That's whether it be by improving the booking experience through mobile apps, improving security through better duty of care tools, or maximising spend visibility through enhanced data analytics. As we look to the future, the discussion around artificial intelligence (chat bots, virtual assistants, etc.) is beginning to become common-place internationally – once again to fulfil a certain type of transaction through technology. This in turn helps to improve the level of efficiency for our clients, but also help to enhance the TMC's ability to leverage their expertise and personalise the customer's experience through technology."
While it's interesting that FCM has delved into the chatbot space with Sam, Humphries of Harvey World Travel makes a telling observation regarding the uptake of technology, as it relates to this group's clients.
"We offer our own in-house corporate booking tool for clients who require this," she says. "However, interestingly, in recent months we have seen a shift in business from online travel agents back to the traditional Harvey World Travel Stores."
So, whilst technology obviously has a huge role to play in travel management going forward, there are going to be instances where travel managers and/or travellers will defer to the consultant for that human touch. How the two elements co-exist is explored further in the chatbot sidebar.
PRESSURE ON FEES
Of course, the threat of, or greater influence of, technology is not the only challenge facing travel management companies.
Spend is down in the corporate space and TMCs are having to fight hard to justify their fees. Again, as is the case with technology, these TMCs are under pressure to 'show value' and prove their worth.
"We do find an extraordinary amount of focus on a cost that equates to less than 8% of the overall total costs of a corporate travel programme," says Vankeirsbilck. "Our focus as TTS is to find value opportunity where we actively encourage clients to focus their attention on the overall cost of their travel programme, rather than just the service fees, by focusing on travel policy adherence, traveller behaviour, travel supplier consolidation, and technology solutions, which will achieve far greater savings on their total cost of travel rather than saving a relatively small amount on service fees. It is imperative for a TMC to add value to a client's total cost of travel programme, and this is where the true value is derived."
McNeil agrees that the discussion needs to move away from the transaction fee.
"In the current economic environment, procurement departments are under pressure to drive cost savings, and one of the easiest targets within the travel procurement space is the transaction fee," he says. "While TMCs could add great value in helping procurement departments derive savings within their travel programme by proactively managing their travel spend, the knee-jerk requirement to cut costs sees corporates appointing TMCs based on the cost of the transaction fee and the result then is a zero-sum game where TMCs are introducing unsustainable pricing levels just to stay in the game. Standard annual increases are becoming harder to pass in an environment where customer expectations from their TMCs are increasing: better service, more expertise and technology. We are increasingly seeing customers wanting commission and override payments without any expectation that their TMC's service fees would have to increase commensurately."
Ole Mortensen is a partner in AMM Consulting in Denmark, and he believes that fee structures need to change, if TMCs "want to regain some of the power they've lost."
According to Mortensen, that 'power' has decreased substantially because:
– The internet suddenly made the opaque airfare structure transparent
– Customers insisted on working with transparency, showing and selling net fares
– Online booking engines enabled the traveller control over their booking
– Metasearch engines increased transparency
– Low-cost carriers launched new business models
"It has become clear that the business model needs to change to benefit not only the TMC but also the airlines, other vendors and the travel managers," says Mortensen.
"I still strongly believe in making a retail multi-source structure where customers are forced to compare total price, as it will benefit the travel managers and suppliers in the long run. Travel managers will have a harder time considering and identifying the right supplier and evaluating their offerings and differential advantages. However, competition will force TMCs to develop more products and services."
In closing, what Mortensen suggests is the following, in terms of "future pricing models":
– Subscriptions based on the hours a travel manager/company may need for a TMC
– Consulting, including management information and other soft services, at hourly pricing
– If the TMC offers duty of care, a subscription based on number of travellers
– Vendor negotiation per hour
– Concierge arranging VIP and group travel charges reasonable fee structure ensuring profit for the vendor
"Many other services have a similar structure and while it will move focus away from bookings, it will start a much-needed change for the industry," he says.
All of this adds up to a challenging environment for TMCs and a difficult one in which to prosper.
As always, those that survive and indeed are successful, are going to be those that embrace the change that technology offers, use it to their advantage, and integrate it in such a way as to remain relevant and of value to their customers.
That will be key to the TMC success of the future.
ABTA SURVEY
Almost 60% of corporates say TMCs are 'good to great' at helping them manage compliance within their travel policy, according to a recent study conducted by FCM Travel Solutions and the African Business Travel Association (ABTA) among travel buyers in South Africa.
Over 80% of South African corporates polled in the study indicated that their employees rarely or only occasionally booked out of policy and that in most cases, this non-compliance was from senior management.
Achieving compliance at a time when corporate travel is becoming increasingly consumerised requires a more flexible approach, according to ABTA founder Monique Swart.
"Business travellers are demanding personalisation and relying on the same tools they use and travel experiences they have in their personal lives," she says. "The indication, thus, that over 70% of surveyed corporates' policies are strict or rigid should raise concerns."
"The survey also indicated that only 30% of corporates actually consider and cater to the needs of their business travellers regularly and more than half were not concerned about the negative impacts of business travel on their travelling staff and trying to mitigate these. Traveller friction has an impact not only on the staff member, but also their ability to perform to achieve company goals."
Among those most-cited areas of anxiety for South African business travellers were flight delays, missed flights and perceived poor service from airlines and hotels. Corporates that are aware of the impact of traveller friction say they are looking at ways in which to mitigate the effects, including limiting travel where possible and introducing traveller-centric policies, including 'bleisure' and wellness programmes.
The study further showed that among those most desired ancillaries by business travellers in South Africa are seat selection, access to airport lounges and good service, with on-board entertainment and on-board wi-fi being the least-demanded ancillaries.
From a sharing economy perspective, almost 90% of business travellers are using Uber and Airbnb for business travel purposes, according to the study. As many as 40% are doing so without the permission or endorsement of their companies.
Technology in the corporate travel space is clearly important to South African companies.
"The survey found that over 65% of corporates like to use all the technology that is relevant to them," says Swart. "There is a cost associated with this, however, and with cost savings being one of the key objectives of a company's travel programme, technology should be used to help with cost cutting efforts."
TRAVEL BOTS
FCM has its own travel bot called Sam, an "itinerary management tool on steroids", according to Euan McNeil, FCM GM for South Africa. Sam has been released in the USA and is expected to be launched early in 2018 in South Africa.
McNeil believes Sam will be how most business travellers interact with their travel programme in the future and explains that corporate travellers can book a car and hotel themselves and complete the booking without having to work with a consultant.
Travel policy will also not be a problem for Sam.
"We will have a generic policy based on best practice in the market," says McNeil. "Then, if customers want to take their full travel policy and load that into Sam, there will be a level of commercial uplift."
Ben Lamm, CEO of Conversable, agrees that if successfully integrated with a company's travel policy, bots will be able to match the user's preferences and information with the businesses' requirements around travel.
"To keep track of all travel, most policies require that travel is booked through a specific company or channel," he says. "Because bots serve as a single access point for multiple sources of information, travellers will be able to access more options from more places, giving them more flexibility within the framework of the travel policy."
So, is there a 'shared' future for TMCs and travel bots?
"Travel bots, such as Sam, have been developed to provide an additional interface for travellers, which will complement but never replace the skills and insights of the TMC," says McNeil. "The travel expert will always have a key role to play when it comes to managing business travel for large corporations as well as SMEs."
According to Norm Rose, President of Travel Tech Consulting, travel chatbots could also be deployed to handle redundant questions such as policy questions, baggage fees, customer support, and limited booking capabilities.
"Progressive TMCs could use chatbots to reduce call volumes by answering simple questions about policy or travel options," he says.
With smartphone adoption nearing 100% and considering that an average business traveller checks their smartphone 34 times a day, it's not difficult to understand the popularity and attraction a mobile or virtual assistant holds.
The nearly ubiquitous adoption of smartphones by the modern business traveller, says Lamm, means that a digital solution to travel needs is now a business imperative for the corporate travel industry.
The travel bot is the perfect technological answer to address the business traveller's need and desire to manage their trip on their own, and give them much-needed freedom within framework. TMCs can make use of bots to improve their service to travellers in a format the travellers desire in a cost-effective way.
"If corporations are going to succeed in winning over the largest generation in the world today and improve retention rates within a group that is notorious for changing paths quickly, building in freedom within framework will certainly be a company imperative," says Lamm.
SOURCEDylan Rogers
Previous articleAn Eye on West Africa
Next articleTreading water


For the first time, a country district was allowed to enter into the Golf SA Women's metropolitan pennants in the A2 Pike Cup. It all started with Mid North committee member Lesley Montfort, speaking with the Golf SA competitions manager at an event in Adelaide last year. Montfort inquired about the possibility of the Mid North joining the competition. Golf SA asked the current affiliated metropolitan clubs if they would be interested in letting the club join, and they all voted in favour. The 'home club' was nominated as Tanunda Pines. Unfortunately, Mid North was unable to obtain players from Highercombe or Penfield, whose women are in the Mid North district, as they are categorised as City Clubs by Golf SA. Although affiliated with Mid North; they could not represent the region in the competition. So a team was assembled from the Mid North – Players were Sue Keylock, Sandy Francas, Helen Kelly (Sandy Creek), Reo Jenner, Julianne Smith, Michelle Pearson (Clare), Fiona Hockings (Barossa) and Sharyn Roberts (Burra). Team managers were Gloria Maynard (Clare) and Di Day (Burra). Results were: Mid North V Grange at Flagstaff Hill – Lost 0-5 Mid North V Tea Tree Gully at Tanunda Pines – Won 3½ to 1½ Mid North V Glenelg at Tea Tree Gully – Won 3½ to 1½ Mid North V Kooyonga at The Grange – Match drawn 2½ to 2½ Mid North V Royal Adelaide at Royal Adelaide – Lost 4-1 Mid North V Flagstaff Hill at Kooyonga – Won 3½ to 1½ Finishing equal with Royal Adelaide, the team missed out on playing in the final, but only by points as the top two teams only could advance. A great effort by the team for their first year in the metropolitan pennants. The group is looking forward to playing in the competition next year, when the players will be more familiar with the process, and have now all played on the magnificent golf courses in Adelaide, which most of the team had never played on before this year's comp.
Almost - Reo Jenner, Sharyn Roberts, Michelle Pearson, Julianne Smith, Di Day, Sandy Francas, Sue Keylock, Stephanie Keylock, Gloria Maynard.
For the first time, a country district was allowed to enter into the Golf SA Women's metropolitan pennants in the A2 Pike Cup.
It all started with Mid North committee member Lesley Montfort, speaking with the Golf SA competitions manager at an event in Adelaide last year.
Montfort inquired about the possibility of the Mid North joining the competition.
Golf SA asked the current affiliated metropolitan clubs if they would be interested in letting the club join, and they all voted in favour.
The 'home club' was nominated as Tanunda Pines.
Unfortunately, Mid North was unable to obtain players from Highercombe or Penfield, whose women are in the Mid North district, as they are categorised as City Clubs by Golf SA.
Although affiliated with Mid North; they could not represent the region in the competition.
So a team was assembled from the Mid North – Players were Sue Keylock, Sandy Francas, Helen Kelly (Sandy Creek), Reo Jenner, Julianne Smith, Michelle Pearson (Clare), Fiona Hockings (Barossa) and Sharyn Roberts (Burra). Team managers were Gloria Maynard (Clare) and Di Day (Burra).
Finishing equal with Royal Adelaide, the team missed out on playing in the final, but only by points as the top two teams only could advance.
A great effort by the team for their first year in the metropolitan pennants.
The group is looking forward to playing in the competition next year, when the players will be more familiar with the process, and have now all played on the magnificent golf courses in Adelaide, which most of the team had never played on before this year's comp.
Paul Hockings, Julianne Smith, Reo Jenner, Fiona Hockings, Sue Keylock, Stephanie Keylock, Sandy Francas, Sharyn Roberts, Di Day.


text:
DAISO is a variety store in Yamagata.
Sakurambo-Higashine
Sakurambo-Higashine Station is a railway station in Higashine, Yamagata Prefecture, Japan, operated by East Japan Railway Company.
Yamagata Airport
Yamagata Airport is a 2nd-class airport in Higashine, Yamagata, Japan.
Higashine
Higashine Station is a JR East railway station located in Higashine, Yamagata Prefecture, Japan.
Jimmachi
Jimmachi Station is a railway station on the Ou Main Line in Higashine, Yamagata Prefecture, Japan, operated by East Japan Railway Company.
Murayama
Murayama Station is a railway station in Murayama, Yamagata, Japan, operated by East Japan Railway Company.
Higashine is a city located in Yamagata Prefecture, Japan.
Murayama is a city located in Yamagata Prefecture, Japan.
Kahoku
Kahoku is a town located in Yamagata Prefecture, Japan.
Tendō is a city located in Yamagata Prefecture, Japan.
Type: variety store
Location: Yamagata, Tohoku, Japan, East Asia, Asia
Latitude: 38.432° or 38° 25' 55.2" north
Longitude: 140.3943° or 140° 23' 39.6" east
OpenStreetMap ID: way 184692469
Japanese: Daiso
Japanese: ダイソー
SagaeTown, 12 km southwest
NakayamaTown, 15 km southwest
OeTown, 17 km west
OishidaTown, 18 km north
ObanazawaTown, 19 km north
YamanobeTown, 20 km southwest
TREnTARestaurant
YakuodoPharmacy, 190 meters west
Higashine City HallTown hall, 300 meters west
LawsonConvenience store, 350 meters north
YAMADAElectronics store, 370 meters northwest
LawsonConvenience store, 470 meters southwest
One's destination is never a place, but rather a new way of looking at things. - Henry Miller
Popular Destinations in Tohoku
Yurihonjo


text:
Brought to you by Newscorp Australia
Australia's famous endangered Goodfellow's tree-kangaroo becomes a dad
Donna Coutts, August 6, 2020 7:00PM
media_cameraMakaia the Goodfellow's tree-kangaroo. Picture: Wildlife Reserves Singapore
Reading level: green
Adelaide Zoo's 'world-first' tree-kangaroo with three mums has become a dad.
Makaia, an endangered Goodfellow's tree-kangaroo, made news around the world in 2014 when the then five-week-old orphaned joey was kept alive by cross-fostering — being transferred to a wallaby's pouch.
Now, five years later, Makaia, who moved to Singapore Zoo in 2016 as part of a Global Species Management Plan, has become a father, meaning there is one more of this endangered species in the world.
Makaia and Nupela — who came to Singapore from Taronga Zoo in Sydney, NSW — are now parents to a male joey.
When tree-kangaroos are born after a gestation* of about 40 days, they are still in an embryonic* state. This newest joey was born on February 4. The jelly bean-sized newborn then crawled into his mother's pouch. After eight months, he has now emerged* into the world.
media_cameraKeepers conduct a pouch check on Nupela and her joey on June 11 to ensure the young one was developing well. Picture: Wildlife Reserves Singapore
Speaking about the new arrival, Mark Smith, Curator at Adelaide Zoo said: "We are delighted to learn that Makaia has gone on to become a father. Huge congratulations to Makaia and everyone at Singapore Zoo."
Saving even one tiny Goodfellow's tree-kangaroo is very important.
Goodfellow's tree-kangaroos inhabit the rainforests of New Guinea. A distant relative of the kangaroo and wallaby, the species lives in trees and rarely descends* to the ground. Distinguishable* by its striking back stripe, the Goodfellow's tree-kangaroo is classified by the IUCN* as endangered in the wild due to overhunting and loss of habitat.
Dr Cheng Wen-Haur of Wildlife Reserves Singapore said: "In these uncertain times, the birth of this Goodfellow's tree-kangaroo is certainly a ray of light for the Global Species Management Plan. Such programs enable zoos the world over to breed threatened species in a scientific and co-ordinated manner to achieve demographic* and genetic sustainability. Together with conservation efforts in the animals' natural habitats, these breeding programs help to ensure the survival of the species."
media_cameraNupela and the new male joey. Picture: Wildlife Reserves Singapore
MAKAIA'S STORY
Sadly, Makaia's biological mum Kia died when a tree fell in November 2014, when Makaia was only five weeks old. There are so few Goodfellow's tree-kangaroos left that the only way to try to keep Makaia alive was to cross-foster him with another species.
"Cross-fostering is a technique that Adelaide Zoo began pioneering in the 1990s and involves the transfer of endangered joeys to the pouch of a surrogate mother of a different wallaby species," Mr Smith said.
"Although Zoos SA had success with cross-fostering wallaby species the technique had never been used on a tree-kangaroo."
Tiny Makaia was transferred to the pouch of a yellow-footed rock-wallaby named Missy Fitton.
"Tree-kangaroos are distant relatives of wallabies but they have many behavioural and physical differences. We had no idea if the yellow-footed rock-wallaby would accept the tree-kangaroo joey, but if we wanted to save the joey we had to try our luck. Fortunately it worked."
Makaia stayed with his wallaby mum for about three and a half months until he became too big for her pouch. Then his third mum, keeper Gayl Males, took over caring for him until his big move to Singapore in 2016.
media_cameraA precious Goodfellow's tree-kangaroo joey pops its head out of its mother's pouch in 2011 at Adelaide Zoo. Picture: Marschall Michael
gestation: the time while a foetus before birth
embryonic: relating to an embryo, or foetus, before a baby is born
emerged: came out from somewhere
descends: goes down
distinguishable: able to be distinguished or seen as different
IUCN: International Union for Conservation of Nature
demographic: relating to the structure of a population
EXTRA READING
Lost kangaroo species found
Baby koala saved in world-first operation
Baby hope for last northern white rhinos
Isolation baby boom for Australian zoos
Virtual safaris into the wild, from home
What does IUCN stand for?
Where do Goodfellow's tree-kangaroos live in the wild?
Why is it important to breed this species in captivity?
How does the joey get to the pouch after it is born?
Who is Missy Fitton?
Kids News · Goodfellow's tree-kangaroo becomes a dad
1. Write a Lullaby
A lullaby is a special song for babies to help to calm them and help them fall asleep. Write the words for a very special lullaby for the new baby joey. Your lullaby should be about how and why he is so special. If you want, use the tune of a lullaby that you might know or make one up!
Time: allow 30 minutes to complete this activity
Curriculum Links: English, Science
2. Extension
The breeding program that helped Makaia to become a father is an important one to help save the endangered tree-kangaroos. Can you think of other things that should be done to help endangered species to survive? Think of as many ideas as you can. Use your ideas to create a Plan of Action poster. The purpose of your poster is to help other kids understand what needs to be done to help endangered species like the Goodfellow's tree-kangaroo.
Time: allow at least 20 minutes to complete this activity
Curriculum Links: English, Visual Communication Design, Science
VCOP ACTIVITY
Proper Noun Police
A proper noun is a noun that names a particular person, place or thing. It always has a capital letter.
How many proper nouns can you find within this article? Find them all and sort them into the category of name, place, time (date/month).
Can you find any proper nouns included in your writing?
Can you sort them into their categories?
HAVE YOUR SAY: Name Makaia and Nupela's new joey.
No one-word answers. Use full sentences to explain your thinking. No comments will be published until approved by editors.
Top stories on Kids News
Explainer answering the question what is at the centre of the Earth and what are volcanoes, earthqua
Broomsticks for Muggles glide through the streets of Sao Paulo, Brazil
Great Barrier Reef coral spawning broadcast live on TV
Kids News explainer: the Bermuda Triangle
Extra Reading in animals
Bushfire Poetry Comp: author Jackie French's five rules for writing a poem
A year of wonderful news at our zoos
Kids News launches Bushfire Poetry Competition
Guardian dogs saving bandicoots from extinction
Kidsnews
Newscorp Australia
Andrell Education
Everyday Activities
Quiz Word
Nationwide News Pty Ltd Copyright © 2021. All times on this site are AEDT (GMT +11)


A 51-year-old man has appeared in court charged with the murder of a 41-year-old woman in Clondalkin in west Dublin yesterday.
Alan Ward, of Greenfort Drive, was charged with the murder of his wife Cathy at their home in Clondalkin in the early hours of Friday morning.
Sergeant Batt Moriarty of Ronanstown Garda Station gave evidence of his arrest.
Solicitor for the accused Wayne Kenny asked that his client be assessed by a doctor while in custody, as he said he had concerns about his mental health.
Judge Victor Blake granted Mr Ward legal aid and remanded him in custody, to appear before Cloverhill District Court on Friday 8 March.


text:
The 2016–17 season was the 114th in the history of the Southern League, which is an English football competition featuring semi-professional and amateur clubs from the South West, South Central and Midlands of England and South Wales. From the 2014–15 season onwards, the Southern League is known as Evo-Stik League Southern, following a sponsorship deal with Evo-Stik.

The league constitution was announced on 12 May 2016.

Premier Division

On 12 May 2016 the league constitution was announced. Later, Cinderford Town, who were originally promoted to the Southern Football League Premier Division as champions of Division One South & West, initially declined promotion due to financial concerns. On 27 May it was confirmed that Cinderford Town would remain in Division One South & West. As a consequence, the team with the best record among those relegated at level 7 - Stamford - were reprieved from relegation. Corby Town, who were originally placed in the Premier Division, were transferred to the Southern Football League to take the vacated place.

On 14 June 2016, Evesham United, who had been transferred from the Southern League Division One South & West to the Northern Premier League First Division South due to Cinderford's refusal to accept promotion, had an appeal against the decision to transfer them leagues heard by the Football Association. On 15 June 2016, they were informed they were successful in their appeal, meaning they would stay in their original league. The knock on effect of this was Cinderford Town were forced to take promotion to the Southern Football League Premier Division. This meant that Corby Town were placed back in the Northern Premier League Premier Division for the 2016-17 season.

The Premier Division consisted of 24 clubs, including 18 clubs from the previous season and six new clubs:
Two clubs promoted from Division One Central:
Kings Langley
St Ives Town

Two clubs promoted from Division One South & West:
Banbury United
Cinderford Town

Two clubs relegated from the National League South:
Basingstoke Town
Hayes & Yeading United

League table

Play-offs

Semi-finals

Final

Results

Stadia and locations

Division One Central

On 12 May 2016 the league constitution was announced. Three Division One Central clubs were moved to the parallel divisions: AFC Rushden & Diamonds were transferred to Northern Premier League Division One South, Godalming Town to Isthmian League Division One South and Ware to Isthmian League Division One North.

Division One Central consisted of 22 clubs, including 15 clubs from previous season and seven new clubs:
AFC Dunstable, promoted from the Spartan South Midlands League
AFC Kempston Rovers, promoted from the United Counties League
Ashford Town, promoted from the Combined Counties League
Farnborough, demoted from the Isthmian League Premier Division
Histon, relegated from the Premier Division
Kidlington, promoted from the Hellenic League
Marlow, transferred from Division One South & West

League table

Play-offs

Semi-finals

Final

Results

Stadia and locations

Division One South & West

On 12 May 2016 the league constitution was announced. One Division One South & West club were moved to the parallel division: Marlow were transferred to Division One Central. Later, Cinderford Town, who were originally promoted to the Premier Division as champions of Division One South & West, declined promotion due to financial concerns. On 27 May it was confirmed that Cinderford Town would remain in Division One South & West. As a consequence, Evesham United were transferred to the Northern Premier League Division One South to create a place for Cinderford Town.

On 14 June 2016, Evesham United, who had been transferred from the Southern League Division One South & West to the Northern Premier League First Division South due to Cinderford's refusal to accept promotion, had an appeal against the decision to transfer them leagues heard by the Football Association. On 15 June 2016, they were informed they were successful in their appeal, meaning they would stay in their original league. The knock on effect of this was Cinderford Town were forced to take promotion to the Southern Football League Premier Division.

Thus, Division One South & West featured five new clubs:
Barnstaple Town, promoted from the Western League
Bideford, relegated from the Premier Division
Hereford, promoted from the Midland League
Paulton Rovers, relegated from the Premier Division
Salisbury, promoted from the Wessex League

League table

Play-offs

Semi-finals

Final

Results

Stadia and locations

League Cup

The 2016–17 Southern League Cup (billed as The League Challenge Cup) was the 79th edition of the Southern League Cup, the cup competition of the Southern Football League.

1st round

2nd round

3rd round

Quarter-finals

Semi-finals

Final

See also
Southern Football League
2016–17 Isthmian League
2016–17 Northern Premier League

References

External links
Official website

Southern Football League seasons
7

redpajama_set_name: RedPajamaWikipedia


Fortune House Chinese Takeaway specialises in Chinese fast food, serving a wide variety of dishes.
Please check with Fortune House Chinese Takeaway for their exact delivery area and any delivery fees.
Tasty Chinese specialises in Chinese fast food, serving a wide variety of dishes.
May China specialises in Chinese takeaways, serving a wide range of dishes including Beverages, Starters, Soups, Spare ribs, Rice dishes, Chow mein dishes, Noodle dishes, Beef dishes, Lemon sauce dishes, Hoi sin sauce dishes, Garlic wine sauce, Specials, Special dishes, Crispy dishes, Chef`s special, Sweet sour dishes, Curry dishes, Thai dishes, Fillet steak dishes, King prawn dishes, Seafood dishes, Roast duck dishes, Lamb dishes, Appetisers, Chicken dishes, Roast pork dishes, Vegetarian dishes, Beancurd dishes, Thai curry dishes, Chop suey dishes, Foo yung dishes, European dishes, Extras, Desserts, Boxes, and Set meals.
Please check with May China for their exact delivery area and any delivery costs.
Mr Ping Restaurant specialises in Chinese and Japanese takeaway meals, serving a wide selection of dishes including Beverages, Appetisers, Soups, Chicken dishes, Beef dishes, Prawn dishes, Duck dishes, Pork dishes, Sweet sour dishes, Chop suey dishes, Curry dishes, Vegetable dishes, Chow mein dishes, Rice, English dishes, Egg foo yung dishes, Extras, Desserts, Set meals, Japanese dishes, Yaki noodles (main), Sushi, Sashimi, Maki, Temaki, Terriyaki dishes, and Side dishes.
So, welcome to Mr Ping Restaurant now serving Chinese and other takeaway meal combinations. At Mr Ping Restaurant you are certain to find the perfect dish for not only yourself but for your family and friends.
Magic Chef specialises in Chinese and Thai takeaway food, serving a wide variety of dishes including Beverages, Appetisers, Soups, Chicken dishes, Beef dishes, Pork dishes, Lamb dishes, Prawn dishes, Duck dishes, Sweet sour dishes, Chop suey dishes, Curry dishes, Vegetable dishes, Chow mein dishes, Rice dishes, English dishes, Egg foo yung dishes, Extras, Desserts, and Set meals.
Please check with Magic Chef for their exact delivery area and any delivery costs.
So, welcome to Magic Chef now serving Chinese and other takeaway meal combinations. At Magic Chef you are certain to find the perfect dish for not only yourself but for your family and friends.
Peking Noodle Bar specialises in Chinese takeaway, serving a wide variety of dishes including Beverages, Appetisers, Soups, Roast duck dishes, Pineapple dishes, Mushroom dishes, Satay dishes, Kung po dishes, Szechuan dishes, Black bean dishes, Ginger spring onion, Capital sauce dishes, Cashew nut dishes, Oyster sauce dishes, Bamboo chestnut, Black pepper dishes, Sweet sour dishes, Curry dishes, Vegetable dishes, Special dishes, Chop suey dishes, Vegetarian dishes, Omelettes, Thai dishes, Chef`s special, Fried rice dishes, Chow mein dishes, Vermicelli dishes, Extras, Desserts, Specialities, and Set meals.
So, welcome to Peking Noodle Bar now serving Chinese and other takeaway meal combinations. At Peking Noodle Bar you are certain to find the perfect dish for not only yourself but for your family and friends.
Man Lee Chinese Take Away specialises in Chinese takeaway food, serving a variety of dishes.
So, welcome to Man Lee Chinese Take Away now serving Chinese and other takeaway meal combinations. At Man Lee Chinese Take Away you are certain to find the perfect dish for not only yourself but for your family and friends.
Note: Please check with Man Lee Chinese Take Away for their exact home delivery area and any delivery fees.
Jade Palace specialises in Chinese takeaway, serving a wide range of dishes.
Mr Ping Chinese Restaurant specialises in Chinese fast food, serving a selection of dishes including Appetisers, Soups, Sweet sour dishes, Chicken dishes, Pork dishes, Beef dishes, Lamb dishes, Duck dishes, Prawn dishes, Chop suey dishes, Curry dishes, Vegetable dishes, Tofu dishes, Foo yung dishes, Chow mein dishes, Rice, Extras, Drinks, Desserts, and Set meals.
So, welcome to Mr Ping Chinese Restaurant now serving Chinese and other takeaway meal combinations. At Mr Ping Chinese Restaurant you are certain to find the perfect dish for not only yourself but for your family and friends.
Wongs Chinese Take Away specialises in Chinese fast food, serving a variety of dishes.
Shoebury Chinese Takeaway specialises in Chinese takeaways, serving a wide range of dishes.
So, welcome to Shoebury Chinese Takeaway now serving Chinese and other takeaway meal combinations. At Shoebury Chinese Takeaway you are certain to find the perfect dish for not only yourself but for your family and friends.
Note: Please check with Shoebury Chinese Takeaway for their exact home delivery area and any delivery costs.
Hong Wah specialises in Chinese takeaway meals, serving a large selection of dishes.
So, welcome to Hong Wah now serving Chinese and other takeaway meal combinations. At Hong Wah you are certain to find the perfect dish for not only yourself but for your family and friends.
Sun Lee specialises in Chinese takeaway, serving a wide range of dishes.
So, welcome to Sun Lee now serving Chinese and other takeaway meal combinations. At Sun Lee you are certain to find the perfect dish for not only yourself but for your family and friends.
"Chinese Takeaways in Southend-on-Sea Takeaway The Easy Way"


text:
The Henry M. Jackson School of International Studies, University of Washington
About the Jackson School
Faculty & Affiliate Faculty
UW-QUAL Program
Course Lists
Centers & Research
Meet an Adviser
Deepali Aparajita Dungdung
North-South Dialogue Fellow
Deepali Aparajita Dungdung has recently submitted her Ph.D. thesis at Centre for the Study of Social Systems in Jawaharlal Nehru University, New Delhi. She is an incoming Assistant Professor in Sociology at Ranchi University, Ranchi (India).
The Henry M. Jackson School is a proud member of the Association of Professional Schools of International Affairs.
The Henry M. Jackson School of International Studies, University of Washington, Box 353650, Seattle WA, 98195-3650
Phone: (206) 543-4370 | Fax: (206) 685-0668 | Email: jsis@uw.edu
© 2023 Henry M. Jackson School of International Studies, College of Arts and Sciences, University of Washington | Seattle, WA