text:
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include "opencdk.h"
#include "main.h"
#include "filters.h"
#include "stream.h"
#include "types.h"

/* This is the maximal amount of bytes we map. */
#define MAX_MAP_SIZE 16777216

static cdk_error_t stream_flush(cdk_stream_t s);
static cdk_error_t stream_filter_write(cdk_stream_t s);
static int stream_cache_flush(cdk_stream_t s, FILE * fp);
struct stream_filter_s *filter_add(cdk_stream_t s, filter_fnct_t fnc,
				   int type);

/* FIXME: The read/write/putc/getc function cannot directly
          return an error code. It is stored in an error variable
          inside the string. Right now there is no code to
          return the error code or to reset it. */

/**
 * cdk_stream_open:
 * @file: The file to open
 * @ret_s: The new STREAM object
 *
 * Creates a new stream based on an existing file. The stream is
 * opened in read-only mode.
 **/
cdk_error_t cdk_stream_open(const char *file, cdk_stream_t * ret_s)
{
	return _cdk_stream_open_mode(file, "rb", ret_s);
}

/* Helper function to allow to open a stream in different modes. */
cdk_error_t
_cdk_stream_open_mode(const char *file, const char *mode,
		      cdk_stream_t * ret_s)
{
	cdk_stream_t s;

	if (!file || !ret_s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}
#ifdef DEBUG_STREAM
	_gnutls_read_log("open stream `%s'\n", file);
#endif
	*ret_s = NULL;
	s = cdk_calloc(1, sizeof *s);
	if (!s) {
		gnutls_assert();
		return CDK_Out_Of_Core;
	}
	s->fname = cdk_strdup(file);
	if (!s->fname) {
		cdk_free(s);
		gnutls_assert();
		return CDK_Out_Of_Core;
	}
	s->fp = fopen(file, mode);
	if (!s->fp) {
		cdk_free(s->fname);
		cdk_free(s);
		gnutls_assert();
		return CDK_File_Error;
	}
#ifdef DEBUG_STREAM
	_gnutls_read_log("open stream fd=%d\n", fileno(s->fp));
#endif
	s->flags.write = 0;
	*ret_s = s;
	return 0;
}

/**
 * cdk_stream_new_from_cbs:
 * @cbs: the callback context with all user callback functions
 * @opa: uint8_t handle which is passed to all callbacks.
 * @ret_s: the allocated stream
 *
 * This function creates a stream which uses user callback
 * for the core operations (open, close, read, write, seek).
 */
cdk_error_t
cdk_stream_new_from_cbs(cdk_stream_cbs_t cbs, void *opa,
			cdk_stream_t * ret_s)
{
	cdk_stream_t s;

	if (!cbs || !opa || !ret_s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}

	*ret_s = NULL;
	s = cdk_calloc(1, sizeof *s);
	if (!s) {
		gnutls_assert();
		return CDK_Out_Of_Core;
	}

	s->cbs.read = cbs->read;
	s->cbs.write = cbs->write;
	s->cbs.seek = cbs->seek;
	s->cbs.release = cbs->release;
	s->cbs.open = cbs->open;
	s->cbs_hd = opa;
	*ret_s = s;

	/* If there is a user callback for open, we need to call it
	   here because read/write expects an open stream. */
	if (s->cbs.open)
		return s->cbs.open(s->cbs_hd);
	return 0;
}

/**
 * cdk_stream_new:
 * @file: The name of the new file
 * @ret_s: The new STREAM object
 *
 * Create a new stream into the given file.
 **/
cdk_error_t cdk_stream_new(const char *file, cdk_stream_t * ret_s)
{
	cdk_stream_t s;

	if (!ret_s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}
#ifdef DEBUG_STREAM
	_gnutls_read_log("new stream `%s'\n", file ? file : "[temp]");
#endif
	*ret_s = NULL;
	s = cdk_calloc(1, sizeof *s);
	if (!s) {
		gnutls_assert();
		return CDK_Out_Of_Core;
	}
	s->flags.write = 1;
	if (!file)
		s->flags.temp = 1;
	else {
		s->fname = cdk_strdup(file);
		if (!s->fname) {
			cdk_free(s);
			gnutls_assert();
			return CDK_Out_Of_Core;
		}
	}
	s->fp = _cdk_tmpfile();
	if (!s->fp) {
		cdk_free(s->fname);
		cdk_free(s);
		gnutls_assert();
		return CDK_File_Error;
	}
#ifdef DEBUG_STREAM
	_gnutls_read_log("new stream fd=%d\n", fileno(s->fp));
#endif
	*ret_s = s;
	return 0;
}

/**
 * cdk_stream_create:
 * @file: the filename
 * @ret_s: the object
 *
 * Creates a new stream.
 * The difference to cdk_stream_new is, that no filtering can be used with
 * this kind of stream and everything is written directly to the stream.
 **/
cdk_error_t cdk_stream_create(const char *file, cdk_stream_t * ret_s)
{
	cdk_stream_t s;

	if (!file || !ret_s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}
#ifdef DEBUG_STREAM
	_gnutls_read_log("create stream `%s'\n", file);
#endif
	*ret_s = NULL;
	s = cdk_calloc(1, sizeof *s);
	if (!s) {
		gnutls_assert();
		return CDK_Out_Of_Core;
	}
	s->flags.write = 1;
	s->flags.filtrated = 1;
	s->fname = cdk_strdup(file);
	if (!s->fname) {
		cdk_free(s);
		gnutls_assert();
		return CDK_Out_Of_Core;
	}
	s->fp = fopen(file, "w+b");
	if (!s->fp) {
		cdk_free(s->fname);
		cdk_free(s);
		gnutls_assert();
		return CDK_File_Error;
	}
#ifdef DEBUG_STREAM
	_gnutls_read_log("stream create fd=%d\n", fileno(s->fp));
#endif
	*ret_s = s;
	return 0;
}

/**
 * cdk_stream_tmp_new:
 * @r_out: the new temp stream.
 *
 * Allocates a new tempory stream which is not associated with a file.
 */
cdk_error_t cdk_stream_tmp_new(cdk_stream_t * r_out)
{
	return cdk_stream_new(NULL, r_out);
}

/**
 * cdk_stream_tmp_from_mem:
 * @buf: the buffer which shall be written to the temp stream.
 * @buflen: how large the buffer is
 * @r_out: the new stream with the given contents.
 *
 * Creates a new tempory stream with the given contests.
 */
cdk_error_t
cdk_stream_tmp_from_mem(const void *buf, size_t buflen,
			cdk_stream_t * r_out)
{
	cdk_stream_t s;
	cdk_error_t rc;
	int nwritten;

	*r_out = NULL;
	rc = cdk_stream_tmp_new(&s);
	if (rc) {
		gnutls_assert();
		return rc;
	}

	nwritten = cdk_stream_write(s, buf, buflen);
	if (nwritten == EOF) {
		cdk_stream_close(s);
		gnutls_assert();
		return s->error;
	}
	cdk_stream_seek(s, 0);
	*r_out = s;
	return 0;
}

cdk_error_t
_cdk_stream_fpopen(FILE * fp, unsigned write_mode, cdk_stream_t * ret_out)
{
	cdk_stream_t s;

	*ret_out = NULL;
	s = cdk_calloc(1, sizeof *s);
	if (!s) {
		gnutls_assert();
		return CDK_Out_Of_Core;
	}
#ifdef DEBUG_STREAM
	_gnutls_read_log("stream ref fd=%d\n", fileno(fp));
#endif
	s->fp = fp;
	s->fp_ref = 1;
	s->flags.filtrated = 1;
	s->flags.write = write_mode;

	*ret_out = s;
	return 0;
}

cdk_error_t _cdk_stream_append(const char *file, cdk_stream_t * ret_s)
{
	cdk_stream_t s;
	cdk_error_t rc;

	if (!ret_s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}
	*ret_s = NULL;

	rc = _cdk_stream_open_mode(file, "a+b", &s);
	if (rc) {
		gnutls_assert();
		return rc;
	}

	/* In the append mode, we need to write to the flag. */
	s->flags.write = 1;
	*ret_s = s;
	return 0;
}

/**
 * cdk_stream_is_compressed:
 * @s: the stream
 *
 * Check whether stream is compressed.
 *
 * Returns: 0 if the stream is uncompressed, otherwise the compression
 *   algorithm.
 */
int cdk_stream_is_compressed(cdk_stream_t s)
{
	if (!s)
		return 0;
	return s->flags.compressed;
}

void _cdk_stream_set_compress_algo(cdk_stream_t s, int algo)
{
	if (!s)
		return;
	s->flags.compressed = algo;
}

cdk_error_t cdk_stream_flush(cdk_stream_t s)
{
	cdk_error_t rc;

	if (!s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}

	/* The user callback does not support flush */
	if (s->cbs_hd)
		return 0;

	/* For read-only streams, no flush is needed. */
	if (!s->flags.write)
		return 0;

	if (!s->flags.filtrated) {
		if (!cdk_stream_get_length(s))
			return 0;
		rc = cdk_stream_seek(s, 0);
		if (!rc)
			rc = stream_flush(s);
		if (!rc)
			rc = stream_filter_write(s);
		s->flags.filtrated = 1;
		if (rc) {
			s->error = rc;
			gnutls_assert();
			return rc;
		}
	}
	return 0;
}

void cdk_stream_tmp_set_mode(cdk_stream_t s, int val)
{
	if (s && s->flags.temp)
		s->fmode = val;
}

/**
 * cdk_stream_close:
 * @s: The STREAM object.
 *
 * Close a stream and flush all buffers.  This function work different
 * for read or write streams. When the stream is for reading, the
 * filtering is already done and we can simply close the file and all
 * buffers.  But for the case it's a write stream, we need to apply
 * all registered filters now. The file is closed in the filter
 * function and not here.
 **/
cdk_error_t cdk_stream_close(cdk_stream_t s)
{
	struct stream_filter_s *f, *f2;
	cdk_error_t rc;

	if (!s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}
#ifdef DEBUG_STREAM
	_gnutls_read_log("close stream ref=%d `%s'\n",
			 s->fp_ref, s->fname ? s->fname : "[temp]");
#endif

	/* In the user callback mode, we call the release cb if possible
	   and just free the stream. */
	if (s->cbs_hd) {
		if (s->cbs.release)
			rc = s->cbs.release(s->cbs_hd);
		else
			rc = 0;
		cdk_free(s);
		gnutls_assert();
		return rc;
	}

	rc = 0;
	if (!s->flags.filtrated && !s->error)
		rc = cdk_stream_flush(s);
	if (!s->fp_ref && (s->fname || s->flags.temp)) {
		int err;

#ifdef DEBUG_STREAM
		_gnutls_read_log("close stream fd=%d\n", fileno(s->fp));
#endif
		err = fclose(s->fp);
		s->fp = NULL;
		if (err)
			rc = CDK_File_Error;
	}

	/* Iterate over the filter list and use the cleanup flag to
	   free the allocated internal structures. */
	f = s->filters;
	while (f) {
		f2 = f->next;
		if (f->fnct)
			f->fnct(f->uint8_t, STREAMCTL_FREE, NULL, NULL);
		cdk_free(f);
		f = f2;
	}

	if (s->fname) {
		cdk_free(s->fname);
		s->fname = NULL;
	}

	cdk_free(s->cache.buf);
	s->cache.alloced = 0;

	cdk_free(s);

	if (rc)
		gnutls_assert();

	return rc;
}

/**
 * cdk_stream_eof:
 * @s: The STREAM object.
 *
 *  Return if the associated file handle was set to EOF.  This
 *  function will only work with read streams.
 **/
int cdk_stream_eof(cdk_stream_t s)
{
	return s ? s->flags.eof : -1;
}

const char *_cdk_stream_get_fname(cdk_stream_t s)
{
	if (!s)
		return NULL;
	if (s->flags.temp)
		return NULL;
	return s->fname ? s->fname : NULL;
}

/* Return the underlying FP of the stream.
   WARNING: This handle should not be closed. */
FILE *_cdk_stream_get_fp(cdk_stream_t s)
{
	return s ? s->fp : NULL;
}

int _cdk_stream_get_errno(cdk_stream_t s)
{
	return s ? s->error : CDK_Inv_Value;
}

/**
 * cdk_stream_get_length:
 * @s: The STREAM object.
 *
 * Return the length of the associated file handle.  This function
 * should work for both read and write streams. For write streams an
 * additional flush is used to write possible pending data.
 **/
off_t cdk_stream_get_length(cdk_stream_t s)
{
	struct stat statbuf;
	cdk_error_t rc;

	if (!s) {
		gnutls_assert();
		return (off_t) - 1;
	}

	/* The user callback does not support stat. */
	if (s->cbs_hd)
		return 0;

	rc = stream_flush(s);
	if (rc) {
		s->error = rc;
		gnutls_assert();
		return (off_t) - 1;
	}

	if (fstat(fileno(s->fp), &statbuf)) {
		s->error = CDK_File_Error;
		gnutls_assert();
		return (off_t) - 1;
	}

	return statbuf.st_size;
}

static struct stream_filter_s *filter_add2(cdk_stream_t s)
{
	struct stream_filter_s *f;

	assert(s);

	f = cdk_calloc(1, sizeof *f);
	if (!f)
		return NULL;
	f->next = s->filters;
	s->filters = f;
	return f;
}

static struct stream_filter_s *filter_search(cdk_stream_t s,
					     filter_fnct_t fnc)
{
	struct stream_filter_s *f;

	assert(s);

	for (f = s->filters; f; f = f->next) {
		if (f->fnct == fnc)
			return f;
	}

	return NULL;
}

static inline void set_uint8_t(struct stream_filter_s *f)
{
	switch (f->type) {
	case fARMOR:
		f->uint8_t = &f->u.afx;
		break;
	case fCIPHER:
		f->uint8_t = &f->u.cfx;
		break;
	case fLITERAL:
		f->uint8_t = &f->u.pfx;
		break;
	case fCOMPRESS:
		f->uint8_t = &f->u.zfx;
		break;
	case fHASH:
		f->uint8_t = &f->u.mfx;
		break;
	case fTEXT:
		f->uint8_t = &f->u.tfx;
		break;
	default:
		f->uint8_t = NULL;
	}

}

struct stream_filter_s *filter_add(cdk_stream_t s, filter_fnct_t fnc,
				   int type)
{
	struct stream_filter_s *f;

	assert(s);

	s->flags.filtrated = 0;
	f = filter_search(s, fnc);
	if (f)
		return f;
	f = filter_add2(s);
	if (!f)
		return NULL;
	f->fnct = fnc;
	f->flags.enabled = 1;
	f->tmp = NULL;
	f->type = type;

	set_uint8_t(f);

	return f;
}

static int stream_get_mode(cdk_stream_t s)
{
	assert(s);

	if (s->flags.temp)
		return s->fmode;
	return s->flags.write;
}

static filter_fnct_t stream_id_to_filter(int type)
{
	switch (type) {
	case fARMOR:
		return _cdk_filter_armor;
	case fLITERAL:
		return _cdk_filter_literal;
	case fTEXT:
		return _cdk_filter_text;
/*    case fCIPHER  : return _cdk_filter_cipher; */
/*    case fCOMPRESS: return _cdk_filter_compress; */
	default:
		return NULL;
	}
}

/**
 * cdk_stream_filter_disable:
 * @s: The STREAM object
 * @type: The numberic filter ID.
 *
 * Disables the filter with the type 'type'.
 **/
cdk_error_t cdk_stream_filter_disable(cdk_stream_t s, int type)
{
	struct stream_filter_s *f;
	filter_fnct_t fnc;

	if (!s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}

	fnc = stream_id_to_filter(type);
	if (!fnc) {
		gnutls_assert();
		return CDK_Inv_Value;
	}
	f = filter_search(s, fnc);
	if (f)
		f->flags.enabled = 0;
	return 0;
}

/* WARNING: tmp should not be closed by the caller. */
static cdk_error_t stream_fp_replace(cdk_stream_t s, FILE ** tmp)
{
	int rc;

	assert(s);

#ifdef DEBUG_STREAM
	_gnutls_read_log("replace stream fd=%d with fd=%d\n",
			 fileno(s->fp), fileno(*tmp));
#endif
	rc = fclose(s->fp);
	if (rc) {
		s->fp = NULL;
		gnutls_assert();
		return CDK_File_Error;
	}
	s->fp = *tmp;
	*tmp = NULL;
	return 0;
}

/* This function is exactly like filter_read, except the fact that we can't
   use tmpfile () all the time. That's why we open the real file when there
   is no last filter. */
static cdk_error_t stream_filter_write(cdk_stream_t s)
{
	struct stream_filter_s *f;
	cdk_error_t rc = 0;

	assert(s);

	if (s->flags.filtrated) {
		gnutls_assert();
		return CDK_Inv_Value;
	}

	for (f = s->filters; f; f = f->next) {
		if (!f->flags.enabled)
			continue;
		/* if there is no next filter, create the final output file */
#ifdef DEBUG_STREAM
		_gnutls_read_log
		    ("filter [write]: last filter=%d fname=%s\n",
		     f->next ? 1 : 0, s->fname);
#endif
		if (!f->next && s->fname)
			f->tmp = fopen(s->fname, "w+b");
		else
			f->tmp = _cdk_tmpfile();
		if (!f->tmp) {
			rc = CDK_File_Error;
			break;
		}
		/* If there is no next filter, flush the cache. We also do this
		   when the next filter is the armor filter because this filter
		   is special and before it starts, all data should be written. */
		if ((!f->next || f->next->type == fARMOR) && s->cache.size) {
			rc = stream_cache_flush(s, f->tmp);
			if (rc)
				break;
		}
		rc = f->fnct(f->uint8_t, f->ctl, s->fp, f->tmp);
#ifdef DEBUG_STREAM
		_gnutls_read_log("filter [write]: type=%d rc=%d\n",
				 f->type, rc);
#endif
		if (!rc)
			rc = stream_fp_replace(s, &f->tmp);
		if (!rc)
			rc = cdk_stream_seek(s, 0);
		if (rc) {
#ifdef DEBUG_STREAM
			_gnutls_read_log("filter [close]: fd=%d\n",
					 fileno(f->tmp));
#endif
			fclose(f->tmp);
			f->tmp = NULL;
			break;
		}
	}
	return rc;
}

/* Here all data from the file handle is passed through all filters.
   The scheme works like this:
   Create a tempfile and use it for the output of the filter. Then the
   original file handle will be closed and replace with the temp handle.
   The file pointer will be set to the begin and the game starts again. */
static cdk_error_t stream_filter_read(cdk_stream_t s)
{
	struct stream_filter_s *f;
	cdk_error_t rc = 0;

	assert(s);

	if (s->flags.filtrated)
		return 0;

	for (f = s->filters; f; f = f->next) {
		if (!f->flags.enabled)
			continue;
		if (f->flags.error) {
#ifdef DEBUG_STREAM
			_gnutls_read_log
			    ("filter %s [read]: has the error flag; skipped\n",
			     s->fname ? s->fname : "[temp]");
#endif
			continue;
		}

		f->tmp = _cdk_tmpfile();
		if (!f->tmp) {
			rc = CDK_File_Error;
			break;
		}
		rc = f->fnct(f->uint8_t, f->ctl, s->fp, f->tmp);
#ifdef DEBUG_STREAM
		_gnutls_read_log("filter %s [read]: type=%d rc=%d\n",
				 s->fname ? s->fname : "[temp]", f->type,
				 rc);
#endif
		if (rc) {
			f->flags.error = 1;
			break;
		}

		f->flags.error = 0;
		/* If the filter is read-only, do not replace the FP because
		   the contents were not altered in any way. */
		if (!f->flags.rdonly) {
			rc = stream_fp_replace(s, &f->tmp);
			if (rc)
				break;
		} else {
			fclose(f->tmp);
			f->tmp = NULL;
		}
		rc = cdk_stream_seek(s, 0);
		if (rc)
			break;
		/* Disable the filter after it was successfully used. The idea
		   is the following: let's say the armor filter was pushed and
		   later more filters were added. The second time the filter code
		   will be executed, only the new filter should be started but
		   not the old because we already used it. */
		f->flags.enabled = 0;
	}

	return rc;
}

void *_cdk_stream_get_uint8_t(cdk_stream_t s, int fid)
{
	struct stream_filter_s *f;

	if (!s)
		return NULL;

	for (f = s->filters; f; f = f->next) {
		if ((int) f->type == fid)
			return f->uint8_t;
	}
	return NULL;
}

/**
 * cdk_stream_read:
 * @s: The STREAM object.
 * @buf: The buffer to insert the readed bytes.
 * @count: Request so much bytes.
 *
 * Tries to read count bytes from the STREAM object.
 * When this function is called the first time, it can take a while
 * because all filters need to be processed. Please remember that you
 * need to add the filters in reserved order.
 **/
int cdk_stream_read(cdk_stream_t s, void *buf, size_t buflen)
{
	int nread;
	int rc;

	if (!s) {
		gnutls_assert();
		return EOF;
	}

	if (s->cbs_hd) {
		if (s->cbs.read)
			return s->cbs.read(s->cbs_hd, buf, buflen);
		return 0;
	}

	if (s->flags.write && !s->flags.temp) {
		s->error = CDK_Inv_Mode;
		gnutls_assert();
		return EOF;	/* This is a write stream */
	}

	if (!s->flags.no_filter && !s->cache.on && !s->flags.filtrated) {
		rc = stream_filter_read(s);
		if (rc) {
			s->error = rc;
			if (s->fp && feof(s->fp))
				s->flags.eof = 1;
			gnutls_assert();
			return EOF;
		}
		s->flags.filtrated = 1;
	}

	if (!buf && !buflen)
		return 0;

	nread = fread(buf, 1, buflen, s->fp);
	if (!nread)
		nread = EOF;

	if (feof(s->fp)) {
		s->error = 0;
		s->flags.eof = 1;
	}
	return nread;
}

int cdk_stream_getc(cdk_stream_t s)
{
	unsigned char buf[2];
	int nread;

	if (!s) {
		gnutls_assert();
		return EOF;
	}
	nread = cdk_stream_read(s, buf, 1);
	if (nread == EOF) {
		s->error = CDK_File_Error;
		gnutls_assert();
		return EOF;
	}
	return buf[0];
}

/**
 * cdk_stream_write:
 * @s: The STREAM object
 * @buf: The buffer with the values to write.
 * @count: The size of the buffer.
 *
 * Tries to write count bytes into the stream.
 * In this function we simply write the bytes to the stream. We can't
 * use the filters here because it would mean they have to support
 * partial flushing.
 **/
int cdk_stream_write(cdk_stream_t s, const void *buf, size_t count)
{
	int nwritten;

	if (!s) {
		gnutls_assert();
		return EOF;
	}

	if (s->cbs_hd) {
		if (s->cbs.write)
			return s->cbs.write(s->cbs_hd, buf, count);
		return 0;
	}

	if (!s->flags.write) {
		s->error = CDK_Inv_Mode;	/* this is a read stream */
		gnutls_assert();
		return EOF;
	}

	if (!buf || !count)
		return stream_flush(s);

	if (s->cache.on) {
#ifdef DEBUG_STREAM
		_gnutls_read_log("stream[ref=%u]: written %d bytes\n",
				 s->fp_ref, (int) count);
#endif

		/* We need to resize the buffer if the additional data wouldn't
		   fit into it. We allocate more memory to avoid to resize it the
		   next time the function is used. */
		if (s->cache.size + count > s->cache.alloced) {
			byte *old = s->cache.buf;

			s->cache.buf =
			    cdk_calloc(1,
				       s->cache.alloced + count +
				       STREAM_BUFSIZE);
			s->cache.alloced += (count + STREAM_BUFSIZE);
			memcpy(s->cache.buf, old, s->cache.size);
			cdk_free(old);
#ifdef DEBUG_STREAM
			_gnutls_read_log
			    ("stream: enlarge cache to %d octets\n",
			     (int) s->cache.alloced);
#endif
		}

		memcpy(s->cache.buf + s->cache.size, buf, count);
		s->cache.size += count;
		return count;
	}
#ifdef DEBUG_STREAM
	_gnutls_read_log("stream[fd=%u]: written %d bytes\n",
			 fileno(s->fp), (int) count);
#endif

	nwritten = fwrite(buf, 1, count, s->fp);
	if (!nwritten)
		nwritten = EOF;
	return nwritten;
}

int cdk_stream_putc(cdk_stream_t s, int c)
{
	byte buf[2];
	int nwritten;

	if (!s) {
		gnutls_assert();
		return EOF;
	}
	buf[0] = c;
	nwritten = cdk_stream_write(s, buf, 1);
	if (nwritten == EOF)
		return EOF;
	return 0;
}

off_t cdk_stream_tell(cdk_stream_t s)
{
	return s ? ftell(s->fp) : (off_t) - 1;
}

cdk_error_t cdk_stream_seek(cdk_stream_t s, off_t offset)
{
	off_t len;

	if (!s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}

	if (s->cbs_hd) {
		if (s->cbs.seek)
			return s->cbs.seek(s->cbs_hd, offset);
		return 0;
	}

	/* Set or reset the EOF flag. */
	len = cdk_stream_get_length(s);
	if (len == offset)
		s->flags.eof = 1;
	else
		s->flags.eof = 0;

	if (fseek(s->fp, offset, SEEK_SET)) {
		gnutls_assert();
		return CDK_File_Error;
	}
	return 0;
}

static cdk_error_t stream_flush(cdk_stream_t s)
{
	assert(s);

	/* For some constellations it cannot be assured that the
	   return value is defined, thus we ignore it for now. */
	(void) fflush(s->fp);
	return 0;
}

/**
 * cdk_stream_set_armor_flag:
 * @s: the stream object
 * @type: the type of armor to use
 *
 * If the file is in read-mode, no armor type needs to be
 * defined (armor_type=0) because the armor filter will be
 * used for decoding existing armor data.
 * For the write mode, @armor_type can be set to any valid
 * armor type (message, key, sig).
 **/
cdk_error_t cdk_stream_set_armor_flag(cdk_stream_t s, int armor_type)
{
	struct stream_filter_s *f;

	if (!s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}
	f = filter_add(s, _cdk_filter_armor, fARMOR);
	if (!f) {
		gnutls_assert();
		return CDK_Out_Of_Core;
	}
	f->u.afx.idx = f->u.afx.idx2 = armor_type;
	f->ctl = stream_get_mode(s);
	return 0;
}

/**
 * cdk_stream_set_literal_flag:
 * @s: the stream object
 * @mode: the mode to use (binary, text, unicode)
 * @fname: the file name to store in the packet.
 *
 * In read mode it kicks off the literal decoding routine to
 * unwrap the data from the packet. The @mode parameter is ignored.
 * In write mode the function can be used to wrap the stream data
 * into a literal packet with the given mode and file name.
 **/
cdk_error_t
cdk_stream_set_literal_flag(cdk_stream_t s, cdk_lit_format_t mode,
			    const char *fname)
{
	struct stream_filter_s *f;
	const char *orig_fname;

#ifdef DEBUG_STREAM
	_gnutls_read_log("stream: enable literal mode.\n");
#endif

	if (!s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}

	orig_fname = _cdk_stream_get_fname(s);
	f = filter_add(s, _cdk_filter_literal, fLITERAL);
	if (!f) {
		gnutls_assert();
		return CDK_Out_Of_Core;
	}
	f->u.pfx.mode = mode;
	f->u.pfx.filename = fname ? cdk_strdup(fname) : NULL;
	f->u.pfx.orig_filename =
	    orig_fname ? cdk_strdup(orig_fname) : NULL;
	f->ctl = stream_get_mode(s);
	if (s->blkmode > 0) {
		f->u.pfx.blkmode.on = 1;
		f->u.pfx.blkmode.size = s->blkmode;
	}
	return 0;
}

/**
 * cdk_stream_set_compress_flag:
 * @s: the stream object
 * @algo: the compression algo
 * @level: level of compression (0..9)
 *
 * In read mode it kicks off the decompression filter to retrieve
 * the uncompressed data.
 * In write mode the stream data will be compressed with the
 * given algorithm at the given level.
 **/
cdk_error_t
cdk_stream_set_compress_flag(cdk_stream_t s, int algo, int level)
{

	gnutls_assert();
	return CDK_Not_Implemented;
}

/**
 * cdk_stream_set_text_flag:
 * @s: the stream object
 * @lf: line ending
 *
 * Pushes the text filter to store the stream data in cannoncial format.
 **/
cdk_error_t cdk_stream_set_text_flag(cdk_stream_t s, const char *lf)
{
	struct stream_filter_s *f;

	if (!s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}
	f = filter_add(s, _cdk_filter_text, fTEXT);
	if (!f) {
		gnutls_assert();
		return CDK_Out_Of_Core;
	}
	f->ctl = stream_get_mode(s);
	f->u.tfx.lf = lf;
	return 0;
}

/**
 * cdk_stream_enable_cache:
 * @s: the stream object
 * @val: 1=on, 0=off
 *
 * Enables or disable the cache section of a stream object.
 **/
cdk_error_t cdk_stream_enable_cache(cdk_stream_t s, int val)
{
	if (!s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}
	if (!s->flags.write) {
		gnutls_assert();
		return CDK_Inv_Mode;
	}
	s->cache.on = val;
	if (!s->cache.buf) {
		s->cache.buf = cdk_calloc(1, STREAM_BUFSIZE);
		s->cache.alloced = STREAM_BUFSIZE;
#ifdef DEBUG_STREAM
		_gnutls_read_log("stream: allocate cache of %d octets\n",
				 STREAM_BUFSIZE);
#endif
	}
	return 0;
}

static int stream_cache_flush(cdk_stream_t s, FILE * fp)
{
	int nwritten;

	assert(s);

	/* FIXME: We should find a way to use cdk_stream_write here. */
	if (s->cache.size > 0) {
		nwritten = fwrite(s->cache.buf, 1, s->cache.size, fp);
		if (!nwritten) {
			gnutls_assert();
			return CDK_File_Error;
		}
		s->cache.size = 0;
		s->cache.on = 0;
		memset(s->cache.buf, 0, s->cache.alloced);
	}
	return 0;
}

/**
 * cdk_stream_kick_off:
 * @inp: the input stream
 * @out: the output stream.
 *
 * Passes the entire data from @inp into the output stream @out
 * with all the activated filters.
 */
cdk_error_t cdk_stream_kick_off(cdk_stream_t inp, cdk_stream_t out)
{
	byte buf[BUFSIZE];
	int nread, nwritten;
	cdk_error_t rc;

	if (!inp || !out) {
		gnutls_assert();
		return CDK_Inv_Value;
	}
	rc = CDK_Success;
	while (!cdk_stream_eof(inp)) {
		nread = cdk_stream_read(inp, buf, DIM(buf));
		if (!nread || nread == EOF)
			break;
		nwritten = cdk_stream_write(out, buf, nread);
		if (!nwritten || nwritten == EOF) {	/* In case of errors, we leave the loop. */
			rc = inp->error;
			break;
		}
	}

	memset(buf, 0, sizeof(buf));
	return rc;
}

/**
 * cdk_stream_mmap_part:
 * @s: the stream
 * @off: the offset where to start
 * @len: how much bytes shall be mapped
 * @ret_buf: the buffer to store the content
 * @ret_buflen: length of the buffer
 *
 * Maps the data of the given stream into a memory section. @ret_count
 * contains the length of the buffer.
 **/
cdk_error_t
cdk_stream_mmap_part(cdk_stream_t s, off_t off, size_t len,
		     byte ** ret_buf, size_t * ret_buflen)
{
	cdk_error_t rc;
	off_t oldpos;
	unsigned int n;

	if (!ret_buf || !ret_buflen) {
		gnutls_assert();
		return CDK_Inv_Value;
	}
	*ret_buf = NULL;
	*ret_buflen = 0;

	if (!s) {
		gnutls_assert();
		return CDK_Inv_Value;
	}

	/* Memory mapping is not supported on custom I/O objects. */
	if (s->cbs_hd) {
#ifdef DEBUG_STREAM
		_gnutls_read_log
		    ("cdk_stream_mmap_part: not supported on callbacks\n");
#endif
		gnutls_assert();
		return CDK_Inv_Mode;
	}

	oldpos = cdk_stream_tell(s);
	rc = cdk_stream_flush(s);
	if (rc) {
		gnutls_assert();
		return rc;
	}
	rc = cdk_stream_seek(s, off);
	if (rc) {
		gnutls_assert();
		return rc;
	}
	if (!len)
		len = cdk_stream_get_length(s);
	if (!len) {
		_gnutls_read_log
		    ("cdk_stream_mmap_part: invalid file size %lu\n",
		     (unsigned long) len);
		gnutls_assert();
		return s->error;
	}
	if (len > MAX_MAP_SIZE) {
		gnutls_assert();
		return CDK_Too_Short;
	}

	*ret_buf = cdk_calloc(1, len + 1);
	*ret_buflen = len;
	n = cdk_stream_read(s, *ret_buf, len);
	if (n != len)
		*ret_buflen = n;
	rc = cdk_stream_seek(s, oldpos);
	if (rc)
		gnutls_assert();
	return rc;
}

cdk_error_t cdk_stream_mmap(cdk_stream_t inp, byte ** buf, size_t * buflen)
{
	off_t len;

	/* We need to make sure all data is flushed before we retrieve the size. */
	cdk_stream_flush(inp);
	len = cdk_stream_get_length(inp);
	return cdk_stream_mmap_part(inp, 0, len, buf, buflen);
}

/**
 * cdk_stream_peek:
 * @inp: the input stream handle
 * @s: buffer
 * @count: number of bytes to peek
 *
 * The function acts like cdk_stream_read with the difference that
 * the file pointer is moved to the old position after the bytes were read.
 **/
int cdk_stream_peek(cdk_stream_t inp, byte * buf, size_t buflen)
{
	off_t off;
	int nbytes;

	if (!inp || !buf)
		return 0;
	if (inp->cbs_hd)
		return 0;

	off = cdk_stream_tell(inp);
	nbytes = cdk_stream_read(inp, buf, buflen);
	if (nbytes == -1)
		return 0;
	if (cdk_stream_seek(inp, off))
		return 0;
	return nbytes;
}

/* Try to read a line from the given stream. */
int _cdk_stream_gets(cdk_stream_t s, char *buf, size_t count)
{
	int c, i;

	assert(s);

	i = 0;
	while (!cdk_stream_eof(s) && count > 0) {
		c = cdk_stream_getc(s);
		if (c == EOF || c == '\r' || c == '\n') {
			buf[i++] = '\0';
			break;
		}
		buf[i++] = c;
		count--;
	}
	return i;
}

/* Try to write string into the stream @s. */
int _cdk_stream_puts(cdk_stream_t s, const char *buf)
{
	return cdk_stream_write(s, buf, strlen(buf));
}

/* Activate the block mode for the given stream. */
cdk_error_t _cdk_stream_set_blockmode(cdk_stream_t s, size_t nbytes)
{
	assert(s);

#ifdef DEBUG_STREAM
	_gnutls_read_log("stream: activate block mode with blocksize %d\n",
			 (int) nbytes);
#endif
	s->blkmode = nbytes;
	return 0;
}

/* Return the block mode state of the given stream. */
int _cdk_stream_get_blockmode(cdk_stream_t s)
{
	return s ? s->blkmode : 0;
}


To celebrate the holiday season, Frye has created a limited edition crossbody bag using "leftover" leathers. For every bag sold, Frye will donate $100 to Feeding America. The bag will arrive in stores on December 4, 2018 and will be sold while supplies last.
Frye store locations can be found on their website at www.thefryecompany.com/stores.


Most homeless people are hidden from public view. What we're currently seeing on the streets of Melbourne represents only a tiny proportion, about 6-10% of the homeless population. The characteristics of the visible homeless are very different to those that we don't see. The invisible homeless are people who because they lack accommodation options are forced to couch surf, stay in boarding houses, caravan parks, or double up with family and friends. They are often families, more often women, younger people and they are more directly affected by structural factors.
Those that sleep rough (the visible homeless) are affected by these problems as well but they tend to have a lot of other problems like mental health and drug use. These problems are, however, often a consequence of homelessness not its cause.
While much media attention has focused on rough sleepers in Melbourne, sleeping rough is not an inner city phenomenon. Rough sleeping is an issue in the suburbs, in regional, rural and remote areas as well.
Johnson, G. and C. Chamberlain (2008). 'Homelessness and Substance Abuse: Which Comes First?', Australian Social Work. 61(4): 342-356.
This post is part of our series on homelessness.


text:
Paola - Malta
CPTM signs a Memorandum of Understanding with the Ministry of Health of the Republic of North Macedonia
Cannapharm Technologies Malta Limited ("CPTM" or the "Company") today announced the signature of an MoU with the Ministry of Health of the Republic of North Macedonia, following on from the Letter of Intent (LoI) received in February 2019.
"This is consecration of the parties' commitment to a full cooperation for the development of a Medical Cannabis (MC) sector in north Macedonia" said Bruce H. Gaston, Director of CPTM. " CPTM will now conduct an assessment of opportunities and prepare feasibility and development plans".
The primary aim is the establishment of a complete-cycle medical cannabis project, that includes cultivation, postharvest, API manufacturing, R&D and packaging facilities according to EU-GMP standards . Particular focus will be on the establishment of a clinical trials facility, with the purpose of conducting and boosting the research on cancer-related diseases treatment using, among others, MC-based drugs.
Bruce H. Gaston
bruce@cptm.com.mt
About CPTM
Cannapharm Technologies Malta Limited (CPTM) is a limited company, registered under the Companies Act, 1995 of the Republic of Malta.
CPTM believes in long-term, incremental growth, based on the latest technological advances. It works closely with governments, regulatory authorities and local municipalities, to utilise, integrate and grow existing local infrastructures, within the framework of regional and governmental development programs and targets.
As an EU-based enterprise, CPTM adheres to and implements the strictest of standards in its productions, whilst maintaining a result-driven, qualitative approach to its pharmaceutical operations in Europe and Asia.

redpajama_set_name: RedPajamaCommonCrawl


The candidates who ran and the the stakeholders who voted deserve our gratitude.
The Hollywood United Neighborhood Council (HUNC) elections went off without a hitch. We appreciate all the efforts of the candidates who chose to run for a seat on the board, the stakeholders who came to the candidate forums or mixers and took the time to vote, and those that at the City Clerk's office who ran a very professional and efficient voting operation. We especially appreciate the efforts of HUNC board members Adam Miller, Andrew Chadsey and Erin Penner who pitched in make these elections happen.
This was an excellent example of citizen democracy and community involvement. Kudos all around.


Posted on April 12, 2019 at 5:15 pm.
It was another week of increased number of homes and for condos for sale.
As has been the trend for three weeks now, we currently have over double the inventory we had at this same time in 2018, yet we are seeing less pended properties each week when comparing that metric to 2018 also. With double the inventory, and slightly less demand, we are managing to have a less competitive real estate market this Spring than we have seen in the last 4 years.
It is nice to note that the balance of new listings and old listings has continued to show signs of a healthier market. Less than 3 months ago, over half of the number of available homes and condos for sale had been on the market for over 60 days (the Crusty Rusty), and each week it has slowly lost that stronghold, and this week the Crusty Rusty listings are less than 25% of the total properties for sale.


Too Darn Hot received quotes for next year's 2000 Guineas and Derby after he caught the eye on his debut at Sandown on Thursday evening.
The young Dubawi colt, out of Dar Re Mi, pulled seven lengths clear in a one-mile maiden as the 8-11 favourite – much to the satisfaction of Frankie Dettori.
"Any horse winning by seven lengths first time, you've got to take notice," said the jockey.
Trainer John Gosden was similarly impressed with Too Darn Hot, owned and bred by Lord Lloyd-Webber.
The Clarehaven handler told Racing UK: "He's a charming horse.
"There was a nice ease in the ground and he enjoyed it. He'll have learned a lot.
"He'll go for a novice next and then we'll see from there.
Too Darn Hot, who holds an entry in the Champagne Stakes at Doncaster next month, is as low as 12-1 with Paddy Power about winning next season's Guineas. He is available at 14s with the same firm for the Derby.


PestBusters is a progressive pest management company founded in Singapore in 1991 that pioneers new techniques in pest control technology.
To protect the health of people and property through the PestBusters standard of professionalism and excellence.
Established in 1991, PestBusters has grown rapidly to emerge as Asia's most progressive pest management company. With our fast growing presence abroad and international quality, we're truly a global company, on a mission to set new standards in the industry. Our methodology at PestBusters is designed to fight pests smart, not hard, to give you a pest management solution that lasts longer. With our innovative SkillsFuture monitoring system, we combine science and technology to achieve the best results and solutions to your pest problems. That's why we're one of the most trusted names in the business today. PestBusters is remarkable for its commitment to identify and develop the skills and potential of every member of the team. We believe the key to success is developing our associates to their full potential. I am excited that the PestBusters brand is expanding with a burgeoning presence in Singapore, the Philippines, and Malaysia, and that the clamor for our level of service will be addressed as we continue to expand in the region.
At PestBusters Philippines, our clients become our best allies in solving infestation problems. More than cleaning their place of business, we become partners–teaching them how to maintain health and cleanliness in their workplace and home. We make sure that the quality we provide is top-notch, and that we continuously seek to heighten our standard of excellence. Why? Because we want to help protect the well-being of every Filipino.
With the Integrated Pest Management (IPM) System, we don't merely target pests.
Our process considers all factors in pest management and prevention.
We inform our clients of the possible causes of pest problems to give them a better understanding of the necessary actions for prevention and cure.
We carefully inspect and help our clients keep their premises free of areas where unwanted pests may thrive.
We use a combination of both chemical and non-chemical techniques, always uniquely tailored to fit our clients' specific needs.
We make recommendations as to what key structural repairs clients might need, in order to keep their property pest-free for the long term.
We follow an effective and environmentally sensitive approach to pest management with the least possible hazard to people, property, and the environment.
Given the strong track record of PestBusters in many of the top local hotels, we felt aspiring for hospitality grade pest control would create a more hygienic and pleasant working environment for our tenants—and we were right. PestBusters is one of the partners that help The Net Group maintain top quality office spaces. Their service is not only effective, but also environmentally friendly. They are one of the few pest management firms that are strategic and that combine science, years of experience, and minimal use of eco-friendly chemicals in their services. We have been very happy and pleased with PestBusters, and highly recommend them to other businesses! They are a top quality service provider and their professionalism, effectiveness, responsiveness, and social responsibility are well worth the premium.
The PestBusters Team in Mactan and the support we get from the Operations Manager has been excellent. Preventive maintenance is very strong and the PestBusters team keeps the hotel in high level of maintenance and service. The team response is very fast, and on-site service is excellent! You can even see them around the resort, assisting all departments with professionalism and a sense of urgency. Overall, we are very satisfied with the performance of the PestBusters team, and I can say that their service and our working relationship has been excellent. I definitely recommend PestBusters to other businesses!


This is the first in a nine-part series on Boston.com about historic districts in the city of Boston.
Out of the nine historic districts in Boston, Beacon Hill is the first. In 1955, this brick- and-cobblestone-covered neighborhood, containing the Massachusetts State House, a passageway from the Underground Railroad, and now a variety of expensive shops, became the first city-designated historic district.
Today, Beacon Hill is known for antique shops, expensive restaurants, beautifully crafted doors, and narrow streets¬ it is filled with historic charm. But how does it stay that way, you ask?
Well, the commission that oversees this historic district has neighborhood-specific rules and guidelines for exteriors of the buildings. These guidelines not only apply to businesses and shops, but also to the historic homes in the district.
According to Boston City Hall, Beacon Hill got its name from a beacon that at one point sat up on the hill to warn people about foreign invasion. Development began on the hill in 1795 with the construction of the State House, and then residential development subsequently followed. In 1795, the Mount Vernon Proprietors, made up of six wealthy citizens, was created. The organization is considered to be one of the first land development operations in the country. Charles Bulfinch completed the State House in 1797, and major residential development began in 1800.
Beacon Hill became the first designated historic district in 1955. This was occurring around the same time that Boston's West End, which is right across Cambridge Street from Beacon Hill, was being threatened with demolition.
In Boston after World War II, demolition was becoming a trend to get out of the economic situation the city was facing. "It was considered the way of the future,'' Born said. Also, in general, there was a newfound desire to get out of the city and move to the suburbs.
The West End was demolished between 1958 and 1960, and there is now a museum in place to detail the neighborhood's history that has been physically lost.
"The West End was never a historic district and didn't have that protection,'' he said.
Born said that nowadays, people don't need to be as concerned with another large-scale renewal project, such as what happened in the West End in the 1950s. But today, the greater fear is of incremental loss.
"You have one homeowner who does something, and another one follows, and pretty soon you have a whole street, and it just continues street by street,'' he said.
Because it is now a historic district, Beacon Hill has almost eight full pages of guidelines and architectural regulations that citizens must abide by.
These three types are built mostly in the Federal and Greek Revival Style. According to the Boston Preservation Alliance, the Federal Style is known for classical columns, three-part windows, and flat facades. The State House is a typical example of this style.
-Third Otis House: Now the offices of the American Meteorological Society, this was Otis's most impressive house on Beacon Hill. Though this house is not open to the public, it is one of Historic New England's preservation easement houses, and they pay it an annual visit to assess the protection of the interior space.
-Museum of African American History: This is now the location of a museum, but in the 1800s, this was the African Meeting House. This is the oldest standing black church in the country.
There are a wide range of regulations for Beacon Hill, split up into the following categories: masonry, roofs, windows, doors, trim, paint, ironwork, signs, commemorative plaques, and street furniture. The regulations do not just apply to buildings within the historic district., they also apply to viewpoints, such as the Boston Common, Storrow Drive, the Longfellow Bridge, and Cambridge Street. Many of the guidelines state that repairing architectural features is better than replacing them completely or adding something new.
But, if an addition is needed, or you desire a contemporary design for building, it is OK, as long as it is compatible with the other buildings in the neighborhood. (You also need to get it approved by the commission.) Solar panels, heaters, wind energy equipment, and other contemporary devices must be out of public view.
Cleaning is also something that can lead to a problem. You need permission to clean masonry, as "the darkening over time of building facades tends to produce a distinctive and uniform appearance and because inappropriate cleaning practices may cause irreversible damage to the masonry,'' according to the regulations.
Any paint samples that you wish to use must be submitted to the commission before use, and no neon lights or electronic signs or displays are permitted on buildings.
As much as you might want to change something little on your house, violating these regulations can result in a fine of $1,000 per day. Make sure you get it approved!


text:
Did OC Weekly Just Publish Its Last Issue?
By Elina Shatkin
Published Nov 28, 2019 1:45 PM
A screengrab of recent OC Weekly covers, taken Nov. 28, 2019, from the alt weekly's website.
After nearly a quarter-century reporting on felonious mayors, scandal-plagued DAs, pedophile priests, neo-Nazis and corrupt business owners, the OC Weekly's future is unclear.
In a Wednesday afternoon tweet, the alt weekly announced it was shutting down: "Today, the day before Thanksgiving, our owner Duncan McIntosh Company has decided to shut us down. For the last quarter century, we've tried to bring good stories to Orange County. It's been fun, but now we're done."
But Duncan McIntosh, the president and publisher of his eponymous company, which mainly puts out boating magazines, tells LAist/KPCC he's in talks to sell the OC Weekly "to a local businessman."
McIntosh did not reveal the identity of the potential buyer, but in the statement he sent to LAist/KPCC, he said: "We hope to have more details after the holiday about the expected change of ownership by a local businessman."
According to Los Angeles magazine, OC Weekly editorial employees found out on Monday that McIntosh was "pulling the plug" but hoping "an eleventh-hour sale might save the paper, the Weekly's staff kept the news under their hats" and didn't publicly share the news until Wednesday.
Around Southern California, many people in the media world are treating the closure as permanent.
As a writer, I feel like I'm 100 years old and going to funerals of friends every other week these days. https://t.co/qTutm041TD
— Jake Kilroy (@jakekilroy) November 27, 2019
Gustavo Arellano, who spent more than 15 years at the alt-weekly including six as editor, says the paper's subversive nature is what makes it special.
"OC Weekly was always rude, not just to conservatives but also to liberals, and that's why as many people loved the OC Weekly as hated it. But the Orange County that we live in today is very much a product of what OC Weekly wanted it to be," Arellano says.
The paper, which had previously been owned by Voice Media Group, was sold to Duncan McIntosh in February 2016. In October 2017, Arellano left OC Weekly after being told he'd have to lay off a sizable chunk of the editorial staff.
Online, journalists paid tribute to the magazine.
Jeff Weiss, former music editor at LA Weekly and editor-in-chief of The LAnd, wrote on Twitter: "In its prime, OC Weekly employed some of the most gifted investigative reporters and culture critics in SoCal. And till the bitter end, they'd been punching far above their weight despite continually dwindling resources. What a loss."
Sarah Bennett, an editor-at-large at the Long Beach Post and managing editor of The LAnd, also mourned the dearth of news outlets in Orange County.
Sad. Mad. Frustrated to see another one of my alt weekly alma maters disappear at the hands of an incapable owner.
Stings more that my journalism students have one less place to practice their craft. Much of OC is a media desert as it is. Local news matters now and forever. https://t.co/KH3nz4Odru
— Sarah Bennett (@thesarahbennett) November 27, 2019
L.A. Taco editor Javier Cabral celebrated OC Weekly as a launching pad for young writers, especially people of color.
In decline for the past decade, alt-weeklies have been especially hard hit these last few years. Chicago's Newcity became a monthly publication in 2017. East Bay Express in Northern California laid off most of its staff earlier this year. The LA Weekly is a shell of itself since its sale to Semanal Media. The grandaddy of alt-weeklies, the Village Voice, stopped publishing in 2018.


As a dietary supplement, take 3 tablets daily with food.
Other Ingredients: Cellulose, Silica, Stearic Acid (vegetable source), Croscarmellose Sodium, Vegetarian Coating and Chlorophyll. Vitamin E from soy.
TRAACS is a registered trademarks of Albion Laboratories, Inc. U.S. Patent 7,838,042 and patents pending; Ferrochel is a registered trademarks of Albion Laboratories, Inc.; Aquamin is a registered trademark of Marigot Limited.


At a large, tastefully appointed Sneden's Landing townhouse, the Deputy Mayor of New York has just shot himself. Though only a flesh wound, four couples are about to experience a severe attack of Farce. Gathering for their tenth wedding anniversary, the host lies bleeding in the other room and his wife is nowhere in sight. His lawyer, Ken and wife Chris must get "the story" straight before the other guests arrive. As the confusions and miscommunications mount, the evening spins off into classic farcical hilarity.


text:
Storm the norm episode 02
Anisha Motwani,
Geetu Verma,
Narayan Devanathan,
Vikas Vasal
18 Dec 202024 min read
This norm may sound pretty obvious—and familiar, because it is an inescapable one these days, given the socio-political climate, not just in India but in many countries across the world. Recall the Donald Trump's MAGA ideology that almost demanded a nationalistic fervor from business (the integrity of that ideology is another debate altogether), Brexit has asked Britons to view business from a non-EU lens first. Even in something as critical as a Covid-19 vaccine, the US wants to favor the one developed by an American company (Pfizer, in this case) while India has its predilections towards the ones where Bharat Biotech or The Serum Institute have a hand.
So, will local geo-politics influence businesses & will brands start being vocal about showing off their nationalistic credentials and make that a key strategic pillar in their playbook?
To answer this, we have an expert who has straddled the line between both local and global. Our guest expert today is Geetu Verma from Unilever, a global marketer and business leader, part of Unilever's global Foods and Refreshment team based out of Rotterdam, Netherlands.
We also have insights from Vikas Vasal, National Managing Partner - Tax at Grant Thornton Bharat on conducive government policies that give impetus to nationalistic brands.
Narayan Devanathan: Welcome to Episode 18 of storm the norm, fortnightly podcast where we pick up norms that come in the way of businesses succeeding in a disruptive world. I am Narayan
Anisha Motwani: and I'm Anisha Motwani.
Narayan Devanathan: As you might have caught in our last episode, Storm the norm is now brought to you in association with one of the leading consulting companies in the world, Grant Thornton Bharat. So in addition to the STN hacks we bring you each time with every episode, you will now also get GT insight, a three minute capsule by a GT expert on the stormed norm. On to today's episode Now, Anisha we've explored shades of today's norm indirectly in past episodes with the libertarian, we look at how politics and business mix in contemporary contexts Mohit Malhotra, from dabur, we looked at how Indian brands can go global,
Anisha Motwani: I think I know where you're headed with this neuron.
Narayan Devanathan: I'm sure you know me enough. When I state the norm it is going to sound pretty obvious and familiar, because it is my most capable one these days given the socio political climate, and not just in India, but in many countries across the world, including the US. Although things are beginning to change, there a bit. The fact is the politics of business is such that regardless of globalisation, as long as national boundaries exists, local geopolitics will influence local business, whether it's in conducted by local businesses or global businesses, and today's now prevails in that sense. Let me state it for the record. nationalistic brands will have an edge over global brands in the post COVID era.
Anisha Motwani: These signs have been there for a while, haven't they? China has always been an exception that proves the rule because of its politics. But Donald Trump's MAGA ideology Make America Great Again, almost demanded a nationalistic fervour from businesses. And of course, the integrity of the ideology is another debate altogether. Brexit has asked Britains to view business from a non EU lens first, even in something as critical as a COVID-19 vaccine. The US wants to favour the one developed by an American company Pfizer in this case, well, India has its predilections towards the ones that Bharat biotech or the Serum Institute have a hand? Isn't it true?
Narayan Devanathan: I mean, on the surface, it rings true Anisha. But even in that most contemporary example, there's more to it than meets the eye. The Pfizer vaccine was actually developed by two Turkish immigrants in Germany by biontech. And the one that the serum Institute wants to supply has been developed at Oxford. But the norm still seems to hold true. I mean, if you look closer at India, the anti China sentiment throughout this year, or potentially his rise in the past few years, have been a different part of that section, the emphasis on Ayurveda currently, all these seem to reinforce norm.
Anisha Motwani: If this norm were to be here to stay, as those signs indicate narayan, it feels like we will have to do one of the two things throughout the entire playbook for how businesses are built by being customer centric, or include nationalism as the number one strategy in the playbook.
Narayan Devanathan: You are direct always. I mean, I have a feeling though. The consumer is smarter and more disturbing than media headlines and trending hashtags. Tell us though,
Anisha Motwani: So in which case, why are some brands being so vocal about showing off their nationalistic credentials? Is this norm unstoppable?
Narayan Devanathan: I'm glad we have somebody else answering the question. I'm very glad you asked that question. But instead of answering you, I'm going to conveniently pass it on to an expert who is better suited to responding to it. And someone who has straddled the line between local and global. Our guest expert today is Geetu Gidvani Verma from Unilever here with us today all the way from the Netherlands. Neetu is a global marketer and business leader at Unilever's global foods and refreshment team based out of Rotterdam. Welcome Geetu. And thank you for joining us today.
Anisha Motwani: Welcome Geetu. It's a pleasure to have you with us.
Narayan Devanathan: We'll start off with asking you this in the context of India, since Prime Minister Narendra Modi is called to be vocal about local brands is experiencing a resurgence of national identity that you've probably not seen since our independence from Great Britain in 1947. Back then, Swadeshi, was a political tool more than anything else. Whereas now this is more economic and it has a tinge of nationalism. It's obviously experienced, and expressed in the popularity of foods, traditional flavours, strong local Indian brands, and maybe influences a lot of opportunities and challenges that brands face today. So what's your take on this norm to begin with?
Geetu Verma: Firstly, Thanks, Narayan and thanks Anisha, for having me on your podcast and i think this is a great topic. So I'm delighted to be here to speak on this and to discuss this with y'all, you know, to win in the marketplace, you know, you need to earn brand love to win consumers minds and hearts, you have to get your basic marketing piece, right? The product price place promotion that we all know about. And that needs to start with the right shop insight. So for me, it is immaterial if you are a transnational brand, or an only one state based brand in India, you know, you could have a micro local state footprint, you could be a Gujarat only brand, you could be a South Asian brand or a global brand. But it's how you get this piece together that makes ultimately the difference between, you know, winning, with people becoming a winning brand.
Anisha Motwani: I believe there were three kinds of eras, you know, I mean, they were, of course, the era where the pre independence where the likes of Unilever and all came to the country and those brands have become more Indian than some of the Indian brands. And then there was the 1990s reforms when we had lots of the Hyundai, the Korean brand Samsung, and they entered India. And that was when India's economic scenario was opening up. And those brands actually leveraged the soul, India suddenly opening their doors to the world with with liberal economic reforms. And then there are the new brands now, like the world likes of IKEA, and you know, Amazon and all that are now coming into the country. And at this point in time, India is also ready with its own set of brands, now Indian brands, and companies have learned how to create strong, powerful businesses, which wasn't the case earlier. So in today's context, when I when I talk about some of the new age companies that are coming into the India, and at the back of this whole nationalistic fervour, that is going about there is something different that global brands need to do to make a place for themselves, isn't it?
Geetu Verma: So I hear you Anisha. But I don't know, again, whether it's about doing things differently, or it's really, you know, going back to the basics. So let me let me take the point that I shared earlier further, right. And, you know, I said to win in the marketplace, you've got to get your basic piece, right, you've got to start with the right shop inside. Now. Let's take a category like tea in India. Yeah. I mean, you would agree with me, it's so personal. Yeah. It's so local, in terms of its taste preference. You know, the Punjab likes, it's tea strong and milky. In East, it's the long leaf lighter, flavour full. It's the dust based format in the south strong as well. And tell me how many well entrenched successful players do we have in the tea category. And it's a good healthy mix of, you know, state based players, which are household names, or you've got players which have originated in India and been able to take their brands abroad. And you've got, you know, a global players like us, like Unilever, and we have loved brands, like Brooke bond, Red Label, Taj Mahal in the space. Now, tell me does the consumer think of any of these brands is either desi or pardesi, right? We consume our favourite Chai, because we love it. We love the taste, we love the idea behind it, we believe that this delivers the perfect value for me. And when I say value, it's not just the right price, but the right value, which means I get the right product, the right cup, ah, the right experience at a price that is worth paying for me. Yeah. And what is it that's enabling these brands to deliver this, you know, this right product, the right taste experience? It comes down to the depth and the quality of insights. You know, as you rightly said, Our country has a lot of diversity. Yeah. You know, when you take categories like foods and beverages, which cannot, you know, you can't get more local than that. You need micro insights. Because these preferences change, not merely by state, they change by topography. They're influenced by historical factors, by ethnicity by affordability. So the winners are the brands which can get beneath the skin of the obvious. They're able to sharp shoot their offerings based on a true understanding of what people are consuming. Why? how?
Narayan Devanathan: I'm going to pull that thread a little further. It's really interesting how you've kind of broken it down into into a fairly simple principle. But what I'm also hearing is you're saying it's horses for courses, there is no one rule that fits all one size fits all strategy, if you will, as long as you understand the consumer and deliver to them. That's what matters is what you're saying. Having said that, but then the interesting ones that are stirring this debate are brands like Xiaomi, which is purely a Chinese brand and then we've seen the boycott against Chinese brands this year. But as of last week, Xiaomi was the number one selling mobile device brand in India. But on the flip side, you know this, this nationalistic fervour also saw the birth of something called Twitter as an alternative to Twitter. So it can be a little confusing to navigate these loads, if you will. How should multinational brands be ready to win local and yet keeping their global identity if you will.
Geetu Verma: I just go back to some historical campaigns and some of the catchphrases that you know,of brands that we've grown up with so whether it's boost is, the secret of my energy or AMUL, taste of India, or its, 'Buland Bharat ki yehi tasveer', or 'lifeboy hai jahaan tandrusti hai wahaan', tell me across these lines, are you able to tell if any of these are not Indian and not close to the Indian consumers heart?
Anisha Motwani: So that how do you explain some of these Indian very Indian categories, you know, which are based on Indian rituals and Indian consumption habits, whether it is masalas, or whether it is hair oils, where Indian companies have succeeded far far more than global companies? How do you explain that,
Geetu Verma: I would actually again, challenge the hypothesis or the statement that Indian companies have done better than companies, you know, which are global. I would actually restate that, and I will say Indian companies have a huge opportunity. So, you know, you you pulled up some great examples. And, you know, let's talk about Dabur. And let's talk about Ayurveda. And let's talk about Chawanprash, or, you know, Hajmola, let's talk about snacking and haldiram. And these products are incredible capability and capacity to travel transnationally there is a fair amount of respect, you know, given to the land from which yoga came in Ayurveda is the twin sister of yoga, you know, there is nothing stopping our own grown, you know, companies to take these offerings abroad beyond the Indian diaspora.
Narayan Devanathan: But I want to circle back to where we started from, if you will, you know, again, Swadeshi was what it was called, whatever, 20-30 years back. And right now we have an English phrase for it 'Vocal for Local', and while it maybe a phrase that's caught on in India, I think there's kind of I don't want to call it anti globalisation that will be pushing it too far, I think. But this level of jingoism, I think is visible, not just in India and multiple markets. But what I'm hearing you say is, don't focus too much on the nationalistic undertones over there. But I would rather that every brand focuses on what is the best way to be relevant to the consumer. Having said that, is there a political risk? Or is there any kind of other risks to ignoring that sentiment,
Anisha Motwani: once it is linked to that, so therefore, nationalistic pride, it doesn't play a role in in purchase consideration.
Geetu Verma: Let's just take a couple of examples. I remember, you know, creating a campaign on Lay's potato chips several years ago. And, you know, you and I have worked together on the business Anisha. So you would remember the you could call it a very vocal for local campaign in the sense that you were cheering for your Indian cricket team who doesn't right. And that whole communication with Beto Carney just won with Steph and calf in the World Cup, you know, being played in South Africa, the finals cheering for India? You know, would we say that lays being a global brand didn't have the right to whip up that fervour for its local for the Indian cricket team? Of course not. Right. So, you know, let's, let's talk about another example. Let's talk about a, you know, a big global cause and you know, which is LGBTQ inclusion. And if you bring it closer home, you know, there are more than two and a half million members of this community in India and brooke bond in India has led on this, you know, the larger idea of the brand in that the hospitality extended by a great warm cup of tea can melt all hostilities. It's been translated into so many heartwarming stories of inclusiveness of being good neighbours. And you would have seen the Brooke bond, you know, six pack transgender band or the latest communication at the traffic light, you know, bringing this cause to life. If you care if you're genuine, if you're authentic, irrespective of who you are. Right, irrespective of your race, your gender, your ethnicity, your country of origin, you fight for that cause you bring it to life.
Anisha Motwani: So well summarised Geetu, thank you so much.
Geetu Verma: Thank you. It's been a pleasure to chat on the subject.
Narayan Devanathan: As promised at the beginning, we now have our special segment with a GT Bharat expert offering their take on the norm. This time around, we have Vikas Vasal, head of tax and Marketing Communications at GT Bharat. Thank you Vikas for joining us today. Now, the specific question for you, how can policy reform specifically help strong this norm? And is there something of special relevance for the MSME sector?
Vikas Vasal: I think the media and press in general have created an impression that probably the focus of the policy is to promote nationalist brands. Whereas when we look at the fine print and the intent of the larger policy initiatives of the Government of India, there is no distinction being made between a foreign brand or a domestic brand. Government policies actually aimed at encouraging manufacturing and ease of doing business in India. They are not distinguishing between whether it's a foreign investment or domestic investment policy. To take an example, if you look at the reduced corporate tax rates for the manufacturing or the new manufacturing setup, which is 15%. And one of the most competitive rates across the globe. It actually applies to all the companies, whether it's a foreign company or Indian company, it sets up a base in India makes the necessary investment and follows the policy. Another good example of this would be the recent labour reforms, which to my mind is one of the biggest reforms with the government has ushered in. 29 Central labour laws are being merged into four labour codes. Now, does that benefit only the Indian brands, not the foreign branch, not the case, it benefits everybody and the country at large. So I think to my mind, a policy does not distinguish per se, between a foreign brand and our national trend, it basically encourages to do business in India. Now, having said that, there has been lot of push from the government for micro small and medium enterprises that is MSMEs to scale up their options and contribute to the overall GDP growth, and also the employment generation. Traditionally, if we look at, there have been many reasons why msme businesses have preferred to remain small. This could be for lack of funds, various labour issues, or the incentives with the government used to offer that encourage them to remain small. Now, one big change that the government is trying to bring in is a shift in the overall mindset of the businesses, especially the MSMEs to scale up their operations. That's the reason recently, under the Atma Nirbhar Bharat programme, the government has increased the overall turnover and investment limits for MSMEs, to help them grow, and still enjoy the benefits of being classified as MSMEs. Thank you.
Anisha Motwani: Thank you so much, Vikas for that policy perspective on storming this norm, it brings a real world application that I'm sure many businesses can use so Narayan what's the single most important insight you're taking out of Geetu's perspectives.
Narayan Devanathan: To respond with a few examples, actually, a lot of these will be familiar to a lot of our listeners also. Bata the shows that many generations of Indians have grown up with thinking it could be undoubtedly Indian, are actually from a Swiss company, to Taj Mahal tea, is one of the most popular brands of tea in a country that is addicted to Chai, founded in Dutch and now hold the British company makes it, Maggie that most ubiquitous of instant food items across the length and breadth of country is again made by a Swiss company, and dairy milk, arguably the most popular and most consumed mitha in the country, is made by an American confectionery company. Oh, and that car that is most Indians first and sometimes second. And third cars is made by a company that is majority Japanese owned. So what it seems to me is that consumers are Vocal for local. Alright. But what they actually mean, is Vocal for what is locally, right, not merely locally made?
Anisha Motwani: Absolutely. I think you've just captured it so well.
Narayan Devanathan: So what's your take on it? And can nationalism be a strategy for businesses? So is this something they should avoid altogether? I mean, is there an opportunity at all in this for Indian brands,
Anisha Motwani: it's not about whether it can be a strategy. It's more about whether it can be an opportunity. And brands now find themselves at the cusp of an opportunity caught in the crossroads of political Economic and philosophical shifts that has made the homegrown proposition more attractive than it has ever been in the last decade. And we heard Vikas talk about what the government is doing to make the MSME segment attractive, you know, give them the SOPs that will make them scale up their business, the biggest challenge with Indian businesses have been that not too many have been able to achieve the scale that they truly deserve. So I'm offering these hacks in this context
Narayan Devanathan: I am all ears
Anisha Motwani: So the first one that Indian brands need to do actually, to make it big on the global stage is to shun the Adjust jugaad or the setting mindset. When India talks of vocal for local, it's not about isolating from the rest of the world. India has a bigger opportunity to play a key role at global stage and emerge as economic part to reckon with. To do so requires that Indian industry goes through a transformation of both mindset and priorities. In India, the word adjust is critical to the cultural philosophy in business context. jugaad or the phrase adjust curling your means a wide range of things from turning a blind eye to rules being clouded to finding a unique and inventive solution to a seemingly unsurmountable problem. Actually, it is this attitude that is both the cause of misery as well as the most important aspect of the mushrooming MSME industry, but with increasing regulatory oversight, those days are over. A critical factor today for succeeding in India is to legitimise this Jugaad and turn it towards a strong and sustainable innovation pipeline. In a sense, jugaad is all about the can do attitude that helps them push the boundaries and break down the social barriers. But how do we use this whole jugaad mindset to bring in a little bit of structure plus science and professionalism behind it is what will be a win win of this mindset being put to use in a structured manner.
Narayan Devanathan: I love this. You know the West has only woken up to a book phenomenon the last few years. But they've systematised it. And I think what you're saying is don't let it be an ad hoc thing. How can you make it into a set of applicable replicable principles?
Anisha Motwani: Absolutely, you know, legitimise it, put science instruction behind.
Narayan Devanathan: Okay, what's next?
Anisha Motwani: Many companies actually think and we've seen that more so now that they've made Indianess as a strategy and we heard Geetu also refer to it you know, in so many ways. Indian nationalism typically does not drive purchase decisions. consumer is much, much more smarter than this. Marketing Indianness as an advantage is a short term tactic that can never replace the importance of a strong strategy. Patriotism is a positive emotion, but it will not be the most relevant. The truth is people care about you only if they resonate with you, if they fall in love with your story. If your offerings adds something to their life, give them that value. And not just in terms of flies or the jingoistic line.
Narayan Devanathan: It's a hard call to stated so bluntly, but I think it's a it's true that we must confront and overcome this we have to hack this
Anisha Motwani: The third hack for me is, Indian companies do have an advantage when it comes to consumer intimacy and their understanding of what India is all about? We all know that India is a very, very unique country, and local brands must leverage the innate agility and consumer intimacy to rethink their brands, their strategies and the action. We all know that the complexity and diversity of India is not just limited to demographics, religion, income strata, but also includes behavioural nuances, current and emerging aspirations and social norms. Global companies take years to get that understanding, right. That brings me in many ways connected to the next point about workplace culture. Actually, the today's situation if you if you take in stock is that MNCs have an advantage as they are significantly ahead of Indian companies as preferred place to work. Nationalistic brands have the opportunity to catch up and be as good if not better. MNCs is are appreciated for their processes and professionalisms. While Indian companies are valued for job security and appreciating people rather than profiles. India's always been a traditionally collectivist community, where loyalty and familial paternal protectiveness were historically necessary to survive, and even to date persist in Indian businesses and relationships. So they have a unique advantage of creating a family culture of trust and care to bind employees and earn their loyalty.
Narayan Devanathan: Love that point about how to marry the advantage of trust with discipline of methodical systems.
Anisha Motwani: And that brings me to the last one mould your technology to the market and not the other way down. Everybody is talking about technology today. But local brands have an advantage in the sense that they can create success with a better understanding of Indian supply chain challenges by customising the technology to modernise logistics, but in a way that adapts to on ground realities and who better than Indian businesses to understand those on ground realities. For example, the case of really go a trucking company that's headquartered in Gurgaon. I mean, they transformed how trucking and delivery can be done in India, adapting both digital systems and the physical construction of its trucks to improve efficiencies and quality of life of its drivers. Hunan is another Indian startup connecting last mile retailers using technology. Now, in only Indians understand our last mile retail network, only they understand our truck ecosystem. And this can apply to several categories. So moulding your technology to the market, and not the other way around is the advantage that only Indian companies and Indian founders have, which they can put to great use to scale up their businesses.
Narayan Devanathan: Insightfully hacked as always Anisha and I'm going to try and stretch things a little bit, because I think you're kind of underplaying the hacks that you've outlined over here, because I think add up to something fairly big. I mean, it might seem like a stretch given globalisation and geopolitics that intertwine so closely, that storming today's norm is also tied to the highly visible conversations around social justice and equitable distribution of resources and the fruits of globalisation. But the point I wanted to actually make what it all added up to if businesses could use these hacks. Well, is, you know, I saw this headline just yesterday, this century is going to be the century of Asian dominance versus the previous ones that were dominated by Western cultures. And I can't help feeling you know, Indian businesses took the natural advantages that they have, and combined it with the systematic, you know, hacks that you outlined here. That could well be the roadmap for something much bigger, like you said, opportunity.
Anisha Motwani: Indeed, Narayan the implications of storming this norm and applying these hacks go far beyond just solving the immediate context.
Narayan Devanathan: A provocative non apathy just perspective, a policy perspective hacks to storm the norm, that's a full plate to wrap up Episode 18 of storm the norm now powered by Grant Thornton Bharat insights. As always, there are multiple places you can catch us on Spotify, apple podcasts, SoundCloud, and jiosaavn. All by just searching for storm the norm. and we're also on saregama Carvaan 2.0 devices on channel 453. This is Narayan
Anisha Motwani: I am Anisha,
Narayan Devanathan: Signing off for now. We will be back with a new episode shortly. Thank you and talk to you soon.
Listen now on:
Anisha Motwani Founder & CEO, Storm the Norm Ventures
Geetu Verma Global VP – Nutrition and Natural Platform, Unilever (Rotterdam, Netherlands)
Narayan Devanathan CEO, Dentsu Aegis Network
Vikas Vasal National Managing Partner, Tax, Grant Thornton Bharat


Grapefruit and oranges, with fresh herbs and lemon juice, make this a perfect accompaniment for any kind of lightly grilled fish seasoned with a bit of garlic infused olive oil.
Perfect anytime of year, this is a great summer combination. You'll love this recipe for Grapefruit Citrus Salsa!
Peel and trim the ends from each orange and grapefruit. Using a paring knife, cut along the membranes on both sides of each segment. Free the segments and add them to a medium bowl. Then squeeze what remains of orange and grapefruit membranes to extract all remaining juice. Add the olive oil, lemon juice, parsley, scallions, mint, orange zest, lemon zest and red pepper flakes. Toss lightly and season with salt and pepper. Set aside.
This is an adaptation of Citrus Salsa Verde.


How to overcome error on wi fi networking?
For those of you who have mobile devices with Wi-Fi feature, may often have been affected, especially the network is not stable and would not even function at all. To determine the condition of this kind is a lot of the cause, so you should pay attention to these problems one by one. Influences that … Continue reading How to overcome error on wi fi networking?


Mali's not the only country feeling the spillover effect of Libya's lawlessness as Gaddafi's arsenal gets spent and fighters fan out across the region. The cross-border attack on an Algerian gas complex has certainly caught the West's attention. As for Libyans, the challenge is to disarm local militias.
Oliver MILES, Former British Ambassador to Libya.


It's a bit alarming that there are only 4 shades available and quite scary that my shade is the darkest. It would be great to see this available for darker skin tones as I truly believe this is holy grail product.
Anyway – this is aaaaaamazing! I purchased this as something light to use after having my ordeal with Revlon's Photoready Foundation. It's nourishing, it magically adapts to your skin-tone and best of all it is great for the beach. I wore this every day in Dubai as it has SPF (I tend not to wear suncream on my face as my body is darker!). The coverage is very light, so I would recommend this only if you are comfortable with showing off your blemishes.
Don't get me wrong I absolutely loved the finish of this foundation, but it made me breakout like crazy. My face turned all red and blotchy as well as being constantly itchy. I'm not generally allergic to anything, but this clearly had something in it that didn't agree with my skin.
The bottle is a nightmare too as the lid never stays on, so if you like to keep foundation in your handbag, I would be very careful and put it in a sandwich bag to stop it spilling over your possessions. I learnt the hard way. If your skin can handle pretty much anything, I would recommend this foundation for that – airbrushed look without looking 'cakey'.
Not wanting to throw this foundation away, I use it very occasionally and I find using a primer underneath really helps. This is because it provides a lightweight barrier between your skin and your make-up (and it blurs your pores too!). I have been loving Instablur by The Body Shop, but another favourite of mine is Porefessional from Benefit which is a tad bit pricier.
At the moment I am on the hunt for the perfect foundation, something I can wear day or night. I really need something lightweight but medium to full coverage as I like looking like me, just a polished version.
What foundations do you use? Would you recommend any of these?
"Memoirs: Foundations for Darker Skintones."


text:
Rome-Jayden Owusu-Oduro (born 2 July 2004) is a Dutch footballer who plays for Jong AZ as a goalkeeper.

Career
He moved from DVC Buiksloot to the AZ Alkmaar academy, beginning to play for AZ at under-12 level. After continuing through the age group levels he signed his first professional contract on 2 October 2020 keeping him at AZ until the end of the 2022–23 season. He distinguished himself with critical saves as the AZ under-18 side won a league and cup double in the 2021–22 season. He made his Eerste Divisie debut on the 26 August 2022 away against FC Eindhoven.

He has been wildly tipped as a "wonderkid" in the football management computer game Football Manager by the likes of Goal (website), SPORTbible, and Planet Football in 2022.

Personal life
Dutch born, he has Ghanaian roots.

References

External links

Living people
2004 births
Dutch footballers
Eerste Divisie players

redpajama_set_name: RedPajamaWikipedia


text:
Online Support Solution > Privacy Policy
Privacy Policy – Online Support Solution
Onlinesupportsolution.com upload his privacy policy at the time of start and last updated on 15th august 2019. It governs the privacy terms on our site located at online support solution and the tools we are provided by you. We requested you to must our policy before to proceed
Customer is the first priority so their privacy is most important for Online support solution. You know the information about our online practices and its depend upon you that want the information you provided to us.
Please read our privacy policy carefully to get a clear understanding of how we collect, use, protect or otherwise handle your Personally Identifiable Information in accordance with our website.
Online Support solution is an online and onsite independent service provider for the variety of third party brand, and services. At Online Support Solution specialize in helping all the type of services and try to keep all the data secure as much as possible which is provided by the company.
We collect the following type of information when you create an account with us:
We collect all information just provided by you with the services. All the information which you have shared with us is not shared with anyone.
According to CalOPPA, we agree to the following Terms :
Our Privacy Policy link includes the word 'Privacy Policy' and can easily be found on the page specified above.
You will be notified of any Privacy Policy changes
– On our Privacy Policy Page Can change your personal information by calling us and By emailing us.
Our site following are legal requirements to protect your privacy. Our Privacy policy is a legal statement that explains how we may collect information from you and how we use and share your information with others. What is the limit to sharing information?. You will see the terms in our Privacy policy. These terms have described in the definition section below
Definition-
Personal Data– Personal Data means data about a living individual who can be identified from those data.
Usage Data– Usage Data collected data automatically either generated by the use of the Service or from the Service infrastructure itself
We collect personal information about you and we use where we are required to do so by law, and for the exercise or defense of the legal team. From time to time we may contact you for any research purpose, special offer or any technical updating. Personal information collected from you may include your name, payment processing information, postal address, email address, landline or mobile telephone number, delivery details as well as other non-sensitive personal information.
While using our Service, we may ask you to provide us with certain personally identifiable information that can be used to contact or identify you ("Personal Data"). Personally, identifiable information may include but is not limited to: Email address, Name, Address, State, Province, ZIP/Postal code, City, Cookies, and Usage Data.
We may use your Personal Data to contact you with newsletters, marketing or promotional materials and other information that may be of interest to you. You may opt-out of receiving any, or all, of these communications from us by following the unsubscribe link or instructions provided in any email we send.
We may also collect information about how the Service is accessed and used ("Usage Data"). This Usage Data may include information such as your computer's Internet Protocol address (e.g. IP address), browser type, browser version, the pages of our Service that you visit, the time and date of your visit, the time spent on those pages, unique device identifiers and other diagnostic data.
Examples of Cookies we use: session cookies (we use these cookies to operate our Service) and preference cookies (we use these cookies to remember your preferences and various settings).
We use of your website indicate your consent to the cookies described in the policy.
A web cookie, a commonly used data collection technology. A piece of text which can be placed on the browser of your personal computer or mobile device and subsequently read as you visit a web site. A cookie may be a session cookie, that is, a cookie that remains on your browser while you are logged on to a particular web site and then disappears when you close your browser, or it may be a persistent cookie, a cookie that remains on your browser over a period of time. Information from a cookie may be collected and used in aggregate form. Or data may be collected into an individual profile or record. That individual record may either be unique but anonymous, or the profile can be linked with information that identifies you as an individual.
We may use cookies for a number of purposes:
We allow third parties to set analytics, or performance, cookies to collect and report aggregate information. These cookies provide reporting to us on an aggregate basis and so, do not identify you at all. We use the aggregate reports to understand how our web sites are used and improve their usefulness to our audiences.
A number of cookies also support how our web sites function, identifying your pc or end device on a unique but anonymous basis. These cookies may, for example, remember your language preferences or recognize an individual's activity within a single session.
Some of our sites may also allow third-party ad servers to serve their own cookies to display advertising on our web sites. We do not determine, control or have access to their cookies. In addition, some of the ads they serve may generate their own cookies. We will list all cookies shortly so that you can review their privacy policies for more detail about their practices.
These third parties have access to your Personal Data only to perform these tasks on our behalf and are obligated not to disclose or use it for any other purpose
If you have any questions about this Privacy Policy, please contact us by using the contact information we provided on our Contact us page or Call us our Toll-free Number.
This Privacy Policy
If our use of cookies changes, we will post the changes to this policy. Please check frequently as online data collection practices and our use of them continue to evolve. To contact us about this policy, you may email [email protected] When emailing please indicate which of our sites you question relates to.
Copyright © 2015 Online Support Solution - Theme by WPCharming


text:
/**
 * Created by joelg on 1/25/17.
 */

import {open, save, load} from './file';

import {stdout} from './stdout';
import {value, print} from './editor/editor';
import {error} from './error/error';
import {canvas} from './graphics/canvas';
import {state} from './utils';

const types = {
    canvas,
    stdout,
    value,
    print,
    error,
    open,
    save,
    load
};

function pipe({type, data}) {
    if (type in types) {
        types[type](data);
        state.mode = type;
    } else {
        console.error('invalid message type');
    }
}

export {pipe};

redpajama_set_name: RedPajamaGithub


Who doesn't love receiving a handmade Valentine card? It's the ultimate way to show how much you care. We've fallen in love with these Valentine card ideas, which use materials that we find inspiring this season, including twine, rubber stamps, ink pads, hole punches, adhesive pearls and gems to name a few. Happy Valentine's Day!
Stamp and emboss little heart shapes before adhering in place using foam squares.
Stamp and emboss little heart shape before adhering in place using foam squares.
Print message on Mint and cut into banner shape. Use foam squares to adhere hearts into flower shape and accent center with a heart gem sticker.
Stamp and emboss little heart shape before adhering in place using foam squares. Layer and adhere more little heart shapes. Cut a band of Red text weight paper and adhere in place. Trim top and bottom of band with glitter tape. Adhere ribbon bow to center of band.
Alternate Glitter Lips Tape and Luxe Glitter Silver Tape on front of card as shown. Punch out tag shape from Fuchsia cover and create 1/8" hole at top for silver cord. Stamp and emboss punched tag shape. Thread cord through hole and tie into a bow. Adhere tag in place using foam squares. Layer and adhere more little heart shapes. Cut a band of Red text weight paper and adhere in place. Trim top and bottom of band with glitter tape. Adhere ribbon bow to center of band.
Stamp and emboss jar shape before adhering gold heart stickers in place. Tie twine around top of jar before adhering in place using foam squares.
Stamp glasses. Carefully cut out the "lenses" using the soft grip knife. Stick coral paper behind glasses using transparent tape before adhering to card using foam squares.


text:
Aquila Data Enabler, in partnership with the Quartz laboratory (ISAE-Supméca), wins the "AI for Industry 2021" challenge co-organized by the Paris Region and Dassault Aviation
The consortium formed by Aquila Data Enabler, a leading French consultancy in artificial intelligence, and the Quartz laboratory of ISAE-Supméca mechanical engineering school, wins the AI for Industry 2021 Challenge organized by the Paris Region and Dassault Aviation.
Paris-Le Bourget, May 28th, 2021 – The consortium formed by Aquila Data Enabler, a leading French consultancy in artificial intelligence, and the Quartz laboratory of ISAE-Supméca mechanical engineering school, wins the AI for Industry 2021 Challenge organized by the Paris Region and Dassault Aviation.
The proposed topic consisted of using AI algorithms to develop, by machine learning, virtual sensors capable of estimating local stress suffered by a Falcon business jet, based solely on available aircraft instruments.
The Challenge judges declared the consortium the winner after a two-month competition during which the ten selected candidates deployed more than 1,000 submitted algorithms.
This victory will allow the teams from Aquila Data Enabler and ISAE-Supméca to spend 18 months working with Dassault Aviation on a collaborative project subsidized by Paris Region in an amount of €500,000. The teams will therefore accelerate the development of date/time data processing tools thanks to artificial intelligence, and conduct advanced research into the topic of the Challenge.
© Dassault Aviation – S. Randé
Valérie Pécresse, President of the Paris Region, says: "The Paris Region is keen to play its role by giving our economic fabric the necessary keys and resources to access the formidable assets of the region's AI ecosystem. We must play together to win; this is what we have done by working with Dassault Aviation, our Astech and Systematic clusters, and Paris Saclay University and Startup Inside. Congratulations to Aquila and Supméca that will now be able to work with Dassault Aviation on reducing carbon emissions."
Eric Trappier, Chairman and CEO of Dassault Aviation, says: "We are delighted by our cooperation with the Paris Region and its AI ecosystem. We have met some outstanding teams and thanks to them, the Challenge has achieved all its goals. The winners' algorithms will give us further insight into the mechanical stress put on aircraft in service, with a view to optimizing our maintenance programs and developing lighter and therefore more fuel-efficient structures. Well done to everyone who took part in this Challenge. Through innovation, industry as a whole and aviation in particular will weather the current crisis and rise to the challenges ahead."
Stéphane Georges, CEO of Aquila, adds: "This victory is reward for our R&D Lab that has been working for over three years on concrete applications of AI in engineering and industry. We would like to thank the Paris Region for supporting local businesses and we look forward to building a real industrial solution with Dassault Aviation and Supméca to democratize the AI approach to virtual sensors, not only in aviation but in many other industries too."
About Paris Region
Paris Region is a driving force for French employment and growth, both in terms of its economic weight and its influence. As the leading economic region in Europe and the third-largest urban economy in the world, behind Tokyo and New York, Paris Region is a hotbed for innovation due to its concentration of 40% of France's R&D activities. By and large, Paris Region benefits from a great international appeal. Paris Region is active in most of the areas that affect the daily lives of its 12 million residents: transport, education, economic development, environment, etc. In an area that covers only 2% of France but is home to 18% of the country's population and nearly 30% of the national GDP, Paris Region is implementing a development policy which places the environment at the heart of its priorities. It is investing 10 billion euros towards it.
More information on: www.iledefrance.fr / twitter: @iledefrance
About Dassault Aviation
With over 10,000 military and civil aircraft (including 2,500 Falcons) delivered in more than 90 countries over the last century, Dassault Aviation has built up expertise recognized worldwide in the design, development, sale and support of all types of aircraft, ranging from the Rafale fighter, to the high-end Falcon family of business jets, military drones and space systems. In 2020, Dassault Aviation reported revenues of €5.5 billion. The company has 12,440 employees.
HD photos: mediaprophoto.dassault-aviation.com
HD videos: mediaprovideo.dassault-aviation.com
Video "Paris Region AI for Industry Challenge award ceremony"
Photo Gallery for the Press
Press Release "Aquila Data Enabler, in partnership with the Quartz laboratory (ISAE-Supméca), wins the "AI for Industry 2021" challenge co-organized by the Paris Region and Dassault Aviation"
Communiqué de presse "Aquila Data Enabler, en collaboration avec le laboratoire Quartz (ISAE-Supméca), remporte le challenge « AI for Industry 2021» co-organisé par la Région Ile-de-France et Dassault Aviation"
Paris Region Press Office
servicepresse@iledefrance.fr
Corporate Communications Dassault Aviation
Stéphane Fort
stephane.fort@dassault-aviation.com
Mathieu Durand
mathieu.durand@dassault-aviation.com
Back to the press kits
Rafale arrives in the Hellenic Air Force (HAF)
Read the press kit	Rafale arrives in the Hellenic Air Force (HAF)
Read the press kit	New support contract for French Mirage 2000s
Deliveries, order intakes and backlog in number of new aircraft as of December 31st 2021
Read the press kit	Deliveries, order intakes and backlog in number of new aircraft as of December 31st 2021
The Greater Paris AI Challenge for Industry


NEW YORK—Small business lending approval rates at credit unions improved slightly in February, according to the Biz2Credit Small Business Lending Index.
However, despite the increase, credit unions are still losing market share to big banks and institutional lenders.
Lending approval rates at big banks have increased in 10 out of the last 11 months, according to the Index, a monthly analysis of 1,000 loan applications on Biz2Credit.com.
Credit unions granted 43.3% of loan applications in January, a slight increase from the record low approval rate of 43.2% in January 2015. "Credit unions are still struggling to increase their presence in the small business finance marketplace," reported Biz2Credit.
Big banks ($10 billion-plus in assets) approved 21.5% of small business loan requests in February 2015, up from 21.3% in January, and are up 12.5% year over year.
Meanwhile, institutional lenders granted 60.7% of funding requests by small business owners in February, an increase from 60.5% in January 2015. Approval rates by institutional lenders have increased each month since Biz2Credit began monitoring this category of lenders one year ago.
"Institutional lenders are willing to offer more loans that are financially appealing to small business owners," Arora said. "The high approval rate in this category of lenders is a reflection of their strong investment in technology advancements, which enables them to quickly assess the risk of default. Thus, they are incredibly efficient; only a miniscule 0.77% of loans made by institutional lenders on our platform have defaulted."
Approval rates at alternative lenders—merchant cash advance companies, factors, and other non-bank institutions—dropped for the 13th consecutive month to 61.4% in February, from 61.6% in January. Their drop has coincided with the emergence of institutional lenders.


Here is a list of some vendors we have come across over the years. We hope this list will help you launch your product faster than ever before. Note that this list is in no particular order, not comprehensive nor do we endorse any of the companies listed.