/* link_preview.c generated by valac 0.56.19, the Vala compiler
 * generated from link_preview.vala, do not modify */

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gobject/gvaluecollector.h>
#include <errno.h>

#define DC_LINK_PREVIEW_MAX_LINKS 5
#define DC_LINK_PREVIEW_MAX_HTML_BYTES (1024 * 1024)
#define DC_LINK_PREVIEW_MAX_IMAGE_BYTES ((gint64) ((8 * 1024) * 1024))
#define DC_LINK_PREVIEW_MAX_TITLE_CHARS 120
#define DC_LINK_PREVIEW_MAX_DESCRIPTION_CHARS 200
#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define DC_LINK_PREVIEW_TYPE_METADATA (dc_link_preview_metadata_get_type ())
#define DC_LINK_PREVIEW_METADATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_LINK_PREVIEW_TYPE_METADATA, DcLinkPreviewMetadata))
#define DC_LINK_PREVIEW_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_LINK_PREVIEW_TYPE_METADATA, DcLinkPreviewMetadataClass))
#define DC_LINK_PREVIEW_IS_METADATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_LINK_PREVIEW_TYPE_METADATA))
#define DC_LINK_PREVIEW_IS_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_LINK_PREVIEW_TYPE_METADATA))
#define DC_LINK_PREVIEW_METADATA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_LINK_PREVIEW_TYPE_METADATA, DcLinkPreviewMetadataClass))

typedef struct _DcLinkPreviewMetadata DcLinkPreviewMetadata;
typedef struct _DcLinkPreviewMetadataClass DcLinkPreviewMetadataClass;
typedef struct _DcLinkPreviewMetadataPrivate DcLinkPreviewMetadataPrivate;
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _DcLinkPreviewParamSpecMetadata DcLinkPreviewParamSpecMetadata;
#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
#define _dc_link_preview_metadata_unref0(var) ((var == NULL) ? NULL : (var = (dc_link_preview_metadata_unref (var), NULL)))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))

struct _DcLinkPreviewMetadata {
	GTypeInstance parent_instance;
	volatile int ref_count;
	DcLinkPreviewMetadataPrivate * priv;
	gchar* title;
	gchar* description;
	gchar* image_url;
};

struct _DcLinkPreviewMetadataClass {
	GTypeClass parent_class;
	void (*finalize) (DcLinkPreviewMetadata *self);
};

struct _DcLinkPreviewParamSpecMetadata {
	GParamSpec parent_instance;
};

static gpointer dc_link_preview_metadata_parent_class = NULL;

VALA_EXTERN gpointer dc_link_preview_metadata_ref (gpointer instance);
VALA_EXTERN void dc_link_preview_metadata_unref (gpointer instance);
VALA_EXTERN GParamSpec* dc_link_preview_param_spec_metadata (const gchar* name,
                                                 const gchar* nick,
                                                 const gchar* blurb,
                                                 GType object_type,
                                                 GParamFlags flags);
VALA_EXTERN void dc_link_preview_value_set_metadata (GValue* value,
                                         gpointer v_object);
VALA_EXTERN void dc_link_preview_value_take_metadata (GValue* value,
                                          gpointer v_object);
VALA_EXTERN gpointer dc_link_preview_value_get_metadata (const GValue* value);
VALA_EXTERN GType dc_link_preview_metadata_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcLinkPreviewMetadata, dc_link_preview_metadata_unref)
VALA_EXTERN gchar* dc_link_preview_metadata_caption (DcLinkPreviewMetadata* self);
VALA_EXTERN DcLinkPreviewMetadata* dc_link_preview_metadata_new (void);
VALA_EXTERN DcLinkPreviewMetadata* dc_link_preview_metadata_construct (GType object_type);
static void dc_link_preview_metadata_finalize (DcLinkPreviewMetadata * obj);
static GType dc_link_preview_metadata_get_type_once (void);
VALA_EXTERN gchar** dc_link_preview_pick_urls (const gchar* text,
                                   gint* result_length1);
VALA_EXTERN gchar** dc_link_cleaner_find_urls (const gchar* text,
                                   gint* result_length1);
static void _vala_array_add32 (gchar** * array,
                        gint* length,
                        gint* size,
                        gchar* value);
VALA_EXTERN DcLinkPreviewMetadata* dc_link_preview_parse_html (const gchar* html,
                                                   const gchar* base_url);
VALA_EXTERN gint dc_link_preview_find_tag_end (const gchar* doc,
                                   gint from);
VALA_EXTERN gboolean dc_link_preview_is_tag_boundary (const gchar* lower,
                                          gint at);
VALA_EXTERN GHashTable* dc_link_preview_parse_attributes (const gchar* s);
VALA_EXTERN gchar* dc_link_preview_decode_entities (const gchar* text);
static gboolean _vala_string_array_contains (gchar* * stack,
                                      gssize stack_length,
                                      const gchar* needle);
VALA_EXTERN gint dc_link_preview_index_of_ci (const gchar* doc,
                                  const gchar* needle,
                                  gint from);
VALA_EXTERN gchar* dc_link_preview_shorten (const gchar* text,
                                gint max_chars);
VALA_EXTERN gchar* dc_link_preview_resolve_url (const gchar* base_url,
                                    const gchar* href);
VALA_EXTERN gchar* dc_link_preview_image_fetch_url (const gchar* url,
                                        gboolean clean);
VALA_EXTERN gchar* dc_link_cleaner_clean_url (const gchar* url);
VALA_EXTERN gchar* dc_link_preview_image_extension (const gchar* mimetype,
                                        const gchar* url);
static void _g_free0_ (gpointer var);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static gssize _vala_array_length (gpointer array);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

/** Short caption for the attached image: title, plus the
                description when there is room. */
gchar*
dc_link_preview_metadata_caption (DcLinkPreviewMetadata* self)
{
	const gchar* _tmp0_ = NULL;
	const gchar* _tmp1_;
	gchar* t = NULL;
	gchar* _tmp2_;
	const gchar* _tmp3_ = NULL;
	const gchar* _tmp4_;
	gchar* d = NULL;
	gchar* _tmp5_;
	const gchar* _tmp6_;
	gint _tmp7_;
	gint _tmp8_;
	const gchar* _tmp9_;
	gint _tmp10_;
	gint _tmp11_;
	const gchar* _tmp12_;
	const gchar* _tmp13_;
	gchar* _tmp14_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = self->title;
	_tmp0_ = _tmp1_;
	if (_tmp0_ == NULL) {
		_tmp0_ = "";
	}
	_tmp2_ = g_strdup (_tmp0_);
	t = _tmp2_;
	_tmp4_ = self->description;
	_tmp3_ = _tmp4_;
	if (_tmp3_ == NULL) {
		_tmp3_ = "";
	}
	_tmp5_ = g_strdup (_tmp3_);
	d = _tmp5_;
	_tmp6_ = t;
	_tmp7_ = strlen (_tmp6_);
	_tmp8_ = _tmp7_;
	if (_tmp8_ == 0) {
		result = d;
		_g_free0 (t);
		return result;
	}
	_tmp9_ = d;
	_tmp10_ = strlen (_tmp9_);
	_tmp11_ = _tmp10_;
	if (_tmp11_ == 0) {
		result = t;
		_g_free0 (d);
		return result;
	}
	_tmp12_ = t;
	_tmp13_ = d;
	_tmp14_ = g_strdup_printf ("%s\n%s", _tmp12_, _tmp13_);
	result = _tmp14_;
	_g_free0 (d);
	_g_free0 (t);
	return result;
}

DcLinkPreviewMetadata*
dc_link_preview_metadata_construct (GType object_type)
{
	DcLinkPreviewMetadata* self = NULL;
	self = (DcLinkPreviewMetadata*) g_type_create_instance (object_type);
	return self;
}

DcLinkPreviewMetadata*
dc_link_preview_metadata_new (void)
{
	return dc_link_preview_metadata_construct (DC_LINK_PREVIEW_TYPE_METADATA);
}

static void
dc_link_preview_value_metadata_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
dc_link_preview_value_metadata_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		dc_link_preview_metadata_unref (value->data[0].v_pointer);
	}
}

static void
dc_link_preview_value_metadata_copy_value (const GValue* src_value,
                                           GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = dc_link_preview_metadata_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
dc_link_preview_value_metadata_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
dc_link_preview_value_metadata_collect_value (GValue* value,
                                              guint n_collect_values,
                                              GTypeCValue* collect_values,
                                              guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		DcLinkPreviewMetadata * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = dc_link_preview_metadata_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
dc_link_preview_value_metadata_lcopy_value (const GValue* value,
                                            guint n_collect_values,
                                            GTypeCValue* collect_values,
                                            guint collect_flags)
{
	DcLinkPreviewMetadata ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = dc_link_preview_metadata_ref (value->data[0].v_pointer);
	}
	return NULL;
}

GParamSpec*
dc_link_preview_param_spec_metadata (const gchar* name,
                                     const gchar* nick,
                                     const gchar* blurb,
                                     GType object_type,
                                     GParamFlags flags)
{
	DcLinkPreviewParamSpecMetadata* spec;
	g_return_val_if_fail (g_type_is_a (object_type, DC_LINK_PREVIEW_TYPE_METADATA), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}

gpointer
dc_link_preview_value_get_metadata (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DC_LINK_PREVIEW_TYPE_METADATA), NULL);
	return value->data[0].v_pointer;
}

void
dc_link_preview_value_set_metadata (GValue* value,
                                    gpointer v_object)
{
	DcLinkPreviewMetadata * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DC_LINK_PREVIEW_TYPE_METADATA));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, DC_LINK_PREVIEW_TYPE_METADATA));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		dc_link_preview_metadata_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		dc_link_preview_metadata_unref (old);
	}
}

void
dc_link_preview_value_take_metadata (GValue* value,
                                     gpointer v_object)
{
	DcLinkPreviewMetadata * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, DC_LINK_PREVIEW_TYPE_METADATA));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, DC_LINK_PREVIEW_TYPE_METADATA));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		dc_link_preview_metadata_unref (old);
	}
}

static void
dc_link_preview_metadata_class_init (DcLinkPreviewMetadataClass * klass,
                                     gpointer klass_data)
{
	dc_link_preview_metadata_parent_class = g_type_class_peek_parent (klass);
	((DcLinkPreviewMetadataClass *) klass)->finalize = dc_link_preview_metadata_finalize;
}

static void
dc_link_preview_metadata_instance_init (DcLinkPreviewMetadata * self,
                                        gpointer klass)
{
	self->title = NULL;
	self->description = NULL;
	self->image_url = NULL;
	self->ref_count = 1;
}

static void
dc_link_preview_metadata_finalize (DcLinkPreviewMetadata * obj)
{
	DcLinkPreviewMetadata * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_LINK_PREVIEW_TYPE_METADATA, DcLinkPreviewMetadata);
	g_signal_handlers_destroy (self);
	_g_free0 (self->title);
	_g_free0 (self->description);
	_g_free0 (self->image_url);
}

static GType
dc_link_preview_metadata_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { dc_link_preview_value_metadata_init, dc_link_preview_value_metadata_free_value, dc_link_preview_value_metadata_copy_value, dc_link_preview_value_metadata_peek_pointer, "p", dc_link_preview_value_metadata_collect_value, "p", dc_link_preview_value_metadata_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (DcLinkPreviewMetadataClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_link_preview_metadata_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcLinkPreviewMetadata), 0, (GInstanceInitFunc) dc_link_preview_metadata_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType dc_link_preview_metadata_type_id;
	dc_link_preview_metadata_type_id = g_type_register_fundamental (g_type_fundamental_next (), "DcLinkPreviewMetadata", &g_define_type_info, &g_define_type_fundamental_info, 0);
	return dc_link_preview_metadata_type_id;
}

GType
dc_link_preview_metadata_get_type (void)
{
	static volatile gsize dc_link_preview_metadata_type_id__once = 0;
	if (g_once_init_enter (&dc_link_preview_metadata_type_id__once)) {
		GType dc_link_preview_metadata_type_id;
		dc_link_preview_metadata_type_id = dc_link_preview_metadata_get_type_once ();
		g_once_init_leave (&dc_link_preview_metadata_type_id__once, dc_link_preview_metadata_type_id);
	}
	return dc_link_preview_metadata_type_id__once;
}

gpointer
dc_link_preview_metadata_ref (gpointer instance)
{
	DcLinkPreviewMetadata * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

void
dc_link_preview_metadata_unref (gpointer instance)
{
	DcLinkPreviewMetadata * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		DC_LINK_PREVIEW_METADATA_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

/** Distinct http(s) URLs in paste order, capped at MAX_LINKS. */
static void
_vala_array_add32 (gchar** * array,
                   gint* length,
                   gint* size,
                   gchar* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gchar*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

gchar**
dc_link_preview_pick_urls (const gchar* text,
                           gint* result_length1)
{
	gchar** out = NULL;
	gchar** _tmp0_;
	gint out_length1;
	gint _out_size_;
	gint _tmp1_ = 0;
	gchar** _tmp2_;
	gchar** _tmp14_;
	gint _tmp14__length1;
	gchar** result;
	g_return_val_if_fail (text != NULL, NULL);
	_tmp0_ = g_new0 (gchar*, 0 + 1);
	out = _tmp0_;
	out_length1 = 0;
	_out_size_ = out_length1;
	_tmp2_ = dc_link_cleaner_find_urls (text, &_tmp1_);
	{
		gchar** url_collection = NULL;
		gint url_collection_length1 = 0;
		gint _url_collection_size_ = 0;
		gint url_it = 0;
		url_collection = _tmp2_;
		url_collection_length1 = _tmp1_;
		for (url_it = 0; url_it < url_collection_length1; url_it = url_it + 1) {
			gchar* _tmp3_;
			gchar* url = NULL;
			_tmp3_ = g_strdup (url_collection[url_it]);
			url = _tmp3_;
			{
				gboolean _tmp4_ = FALSE;
				const gchar* _tmp5_;
				gboolean dup = FALSE;
				gchar** _tmp7_;
				gint _tmp7__length1;
				const gchar* _tmp11_;
				gchar* _tmp12_;
				gchar** _tmp13_;
				gint _tmp13__length1;
				_tmp5_ = url;
				if (!g_str_has_prefix (_tmp5_, "http://")) {
					const gchar* _tmp6_;
					_tmp6_ = url;
					_tmp4_ = !g_str_has_prefix (_tmp6_, "https://");
				} else {
					_tmp4_ = FALSE;
				}
				if (_tmp4_) {
					_g_free0 (url);
					continue;
				}
				dup = FALSE;
				_tmp7_ = out;
				_tmp7__length1 = out_length1;
				{
					gchar** seen_collection = NULL;
					gint seen_collection_length1 = 0;
					gint _seen_collection_size_ = 0;
					gint seen_it = 0;
					seen_collection = _tmp7_;
					seen_collection_length1 = _tmp7__length1;
					for (seen_it = 0; seen_it < seen_collection_length1; seen_it = seen_it + 1) {
						gchar* _tmp8_;
						gchar* seen = NULL;
						_tmp8_ = g_strdup (seen_collection[seen_it]);
						seen = _tmp8_;
						{
							const gchar* _tmp9_;
							const gchar* _tmp10_;
							_tmp9_ = seen;
							_tmp10_ = url;
							if (g_strcmp0 (_tmp9_, _tmp10_) == 0) {
								dup = TRUE;
								_g_free0 (seen);
								break;
							}
							_g_free0 (seen);
						}
					}
				}
				if (dup) {
					_g_free0 (url);
					continue;
				}
				_tmp11_ = url;
				_tmp12_ = g_strdup (_tmp11_);
				_vala_array_add32 (&out, &out_length1, &_out_size_, _tmp12_);
				_tmp13_ = out;
				_tmp13__length1 = out_length1;
				if (_tmp13__length1 >= DC_LINK_PREVIEW_MAX_LINKS) {
					_g_free0 (url);
					break;
				}
				_g_free0 (url);
			}
		}
		url_collection = (_vala_array_free (url_collection, url_collection_length1, (GDestroyNotify) g_free), NULL);
	}
	_tmp14_ = out;
	_tmp14__length1 = out_length1;
	if (result_length1) {
		*result_length1 = _tmp14__length1;
	}
	result = _tmp14_;
	return result;
}

/** Extracts preview metadata from an HTML document. `base_url` is
            the final page URL, used to resolve relative image references.
            Returns null when the page yields neither an image nor a
            title. */
static glong
string_strnlen (gchar* str,
                glong maxlen)
{
	gchar* end = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	glong result;
	_tmp0_ = memchr (str, 0, (gsize) maxlen);
	end = _tmp0_;
	_tmp1_ = end;
	if (_tmp1_ == NULL) {
		result = maxlen;
		return result;
	} else {
		gchar* _tmp2_;
		_tmp2_ = end;
		result = (glong) (_tmp2_ - str);
		return result;
	}
}

static gchar*
string_substring (const gchar* self,
                  glong offset,
                  glong len)
{
	glong string_length = 0L;
	gboolean _tmp0_ = FALSE;
	gchar* _tmp3_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	if (offset >= ((glong) 0)) {
		_tmp0_ = len >= ((glong) 0);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		string_length = string_strnlen ((gchar*) self, offset + len);
	} else {
		gint _tmp1_;
		gint _tmp2_;
		_tmp1_ = strlen (self);
		_tmp2_ = _tmp1_;
		string_length = (glong) _tmp2_;
	}
	if (offset < ((glong) 0)) {
		offset = string_length + offset;
		g_return_val_if_fail (offset >= ((glong) 0), NULL);
	} else {
		g_return_val_if_fail (offset <= string_length, NULL);
	}
	if (len < ((glong) 0)) {
		len = string_length - offset;
	}
	g_return_val_if_fail ((offset + len) <= string_length, NULL);
	_tmp3_ = g_strndup (((gchar*) self) + offset, (gsize) len);
	result = _tmp3_;
	return result;
}

static gint
string_index_of_char (const gchar* self,
                      gunichar c,
                      gint start_index)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	_tmp0_ = g_utf8_strchr (((gchar*) self) + start_index, (gssize) -1, c);
	_result_ = _tmp0_;
	_tmp1_ = _result_;
	if (_tmp1_ != NULL) {
		gchar* _tmp2_;
		_tmp2_ = _result_;
		result = (gint) (_tmp2_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}

static gint
string_index_of (const gchar* self,
                 const gchar* needle,
                 gint start_index)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* _tmp1_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	g_return_val_if_fail (needle != NULL, -1);
	_tmp0_ = strstr (((gchar*) self) + start_index, (gchar*) needle);
	_result_ = _tmp0_;
	_tmp1_ = _result_;
	if (_tmp1_ != NULL) {
		gchar* _tmp2_;
		_tmp2_ = _result_;
		result = (gint) (_tmp2_ - ((gchar*) self));
		return result;
	} else {
		result = -1;
		return result;
	}
}

static gchar*
string_strip (const gchar* self)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup (self);
	_result_ = _tmp0_;
	g_strstrip (_result_);
	result = _result_;
	return result;
}

static gboolean
_vala_string_array_contains (gchar* * stack,
                             gssize stack_length,
                             const gchar* needle)
{
	gssize i;
	for (i = 0; i < stack_length; i++) {
		if (g_strcmp0 (stack[i], needle) == 0) {
			return TRUE;
		}
	}
	return FALSE;
}

DcLinkPreviewMetadata*
dc_link_preview_parse_html (const gchar* html,
                            const gchar* base_url)
{
	gchar* _tmp0_ = NULL;
	gint _tmp1_;
	gint _tmp2_;
	gchar* doc = NULL;
	gchar* _tmp5_;
	const gchar* _tmp6_;
	gchar* og_title = NULL;
	gchar* og_desc = NULL;
	gchar* og_image = NULL;
	gchar* tw_title = NULL;
	gchar* tw_desc = NULL;
	gchar* tw_image = NULL;
	gchar* html_title = NULL;
	gchar* meta_desc = NULL;
	gchar* link_image = NULL;
	gint pos = 0;
	DcLinkPreviewMetadata* meta = NULL;
	DcLinkPreviewMetadata* _tmp120_;
	const gchar* _tmp121_ = NULL;
	const gchar* _tmp122_;
	DcLinkPreviewMetadata* _tmp126_;
	gchar* _tmp127_;
	const gchar* _tmp128_ = NULL;
	const gchar* _tmp129_;
	DcLinkPreviewMetadata* _tmp133_;
	gchar* _tmp134_;
	const gchar* _tmp135_ = NULL;
	const gchar* _tmp136_;
	gchar* img = NULL;
	gchar* _tmp140_;
	const gchar* _tmp141_;
	gboolean _tmp145_ = FALSE;
	DcLinkPreviewMetadata* _tmp146_;
	const gchar* _tmp147_;
	DcLinkPreviewMetadata* result;
	g_return_val_if_fail (html != NULL, NULL);
	g_return_val_if_fail (base_url != NULL, NULL);
	_tmp1_ = strlen (html);
	_tmp2_ = _tmp1_;
	if (_tmp2_ > DC_LINK_PREVIEW_MAX_HTML_BYTES) {
		gchar* _tmp3_;
		_tmp3_ = string_substring (html, (glong) 0, (glong) DC_LINK_PREVIEW_MAX_HTML_BYTES);
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp3_;
	} else {
		gchar* _tmp4_;
		_tmp4_ = g_strdup (html);
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp4_;
	}
	_tmp5_ = _tmp0_;
	_tmp0_ = NULL;
	doc = _tmp5_;
	_tmp6_ = doc;
	if (!g_utf8_validate (_tmp6_, (gssize) -1, NULL)) {
		const gchar* _tmp7_;
		gchar* _tmp8_;
		_tmp7_ = doc;
		_tmp8_ = g_utf8_make_valid (_tmp7_, (gssize) -1);
		_g_free0 (doc);
		doc = _tmp8_;
	}
	og_title = NULL;
	og_desc = NULL;
	og_image = NULL;
	tw_title = NULL;
	tw_desc = NULL;
	tw_image = NULL;
	html_title = NULL;
	meta_desc = NULL;
	link_image = NULL;
	pos = 0;
	while (TRUE) {
		gint lt = 0;
		const gchar* _tmp9_;
		const gchar* _tmp10_;
		gchar* _tmp11_;
		gchar* _tmp12_;
		gboolean _tmp13_;
		gint gt = 0;
		const gchar* _tmp15_;
		gchar* tag = NULL;
		const gchar* _tmp16_;
		gchar* _tmp17_;
		gchar* lower = NULL;
		const gchar* _tmp18_;
		gchar* _tmp19_;
		gboolean _tmp20_ = FALSE;
		const gchar* _tmp21_;
		_tmp9_ = doc;
		lt = string_index_of_char (_tmp9_, (gunichar) '<', pos);
		if (lt < 0) {
			break;
		}
		_tmp10_ = doc;
		_tmp11_ = string_substring (_tmp10_, (glong) lt, (glong) 4);
		_tmp12_ = _tmp11_;
		_tmp13_ = g_strcmp0 (_tmp12_, "<!--") == 0;
		_g_free0 (_tmp12_);
		if (_tmp13_) {
			gint close = 0;
			const gchar* _tmp14_;
			_tmp14_ = doc;
			close = string_index_of (_tmp14_, "-->", lt + 4);
			if (close < 0) {
				break;
			}
			pos = close + 3;
			continue;
		}
		_tmp15_ = doc;
		gt = dc_link_preview_find_tag_end (_tmp15_, lt + 1);
		if (gt < 0) {
			break;
		}
		_tmp16_ = doc;
		_tmp17_ = string_substring (_tmp16_, (glong) (lt + 1), (glong) ((gt - lt) - 1));
		tag = _tmp17_;
		pos = gt + 1;
		_tmp18_ = tag;
		_tmp19_ = g_utf8_strdown (_tmp18_, (gssize) -1);
		lower = _tmp19_;
		_tmp21_ = lower;
		if (g_str_has_prefix (_tmp21_, "meta")) {
			const gchar* _tmp22_;
			_tmp22_ = lower;
			_tmp20_ = dc_link_preview_is_tag_boundary (_tmp22_, 4);
		} else {
			_tmp20_ = FALSE;
		}
		if (_tmp20_) {
			GHashTable* attrs = NULL;
			const gchar* _tmp23_;
			gchar* _tmp24_;
			gchar* _tmp25_;
			GHashTable* _tmp26_;
			GHashTable* _tmp27_;
			const gchar* _tmp28_ = NULL;
			GHashTable* _tmp29_;
			gconstpointer _tmp30_;
			gchar* key = NULL;
			gchar* _tmp34_;
			gchar* _tmp35_;
			gchar* _tmp36_;
			gchar* _tmp37_;
			gchar* content = NULL;
			GHashTable* _tmp38_;
			gconstpointer _tmp39_;
			gchar* _tmp40_;
			const gchar* _tmp41_;
			const gchar* _tmp42_;
			gchar* _tmp43_;
			gchar* _tmp44_;
			gchar* _tmp45_;
			const gchar* _tmp46_;
			gint _tmp47_;
			gint _tmp48_;
			const gchar* _tmp49_;
			const gchar* _tmp50_;
			GQuark _tmp52_ = 0U;
			static GQuark _tmp51_label0 = 0;
			static GQuark _tmp51_label1 = 0;
			static GQuark _tmp51_label2 = 0;
			static GQuark _tmp51_label3 = 0;
			static GQuark _tmp51_label4 = 0;
			static GQuark _tmp51_label5 = 0;
			static GQuark _tmp51_label6 = 0;
			static GQuark _tmp51_label7 = 0;
			static GQuark _tmp51_label8 = 0;
			static GQuark _tmp51_label9 = 0;
			_tmp23_ = tag;
			_tmp24_ = string_substring (_tmp23_, (glong) 4, (glong) -1);
			_tmp25_ = _tmp24_;
			_tmp26_ = dc_link_preview_parse_attributes (_tmp25_);
			_tmp27_ = _tmp26_;
			_g_free0 (_tmp25_);
			attrs = _tmp27_;
			_tmp29_ = attrs;
			_tmp30_ = g_hash_table_lookup (_tmp29_, "property");
			_tmp28_ = (const gchar*) _tmp30_;
			if (_tmp28_ == NULL) {
				const gchar* _tmp31_ = NULL;
				GHashTable* _tmp32_;
				gconstpointer _tmp33_;
				_tmp32_ = attrs;
				_tmp33_ = g_hash_table_lookup (_tmp32_, "name");
				_tmp31_ = (const gchar*) _tmp33_;
				if (_tmp31_ == NULL) {
					_tmp31_ = "";
				}
				_tmp28_ = _tmp31_;
			}
			_tmp34_ = g_utf8_strdown (_tmp28_, (gssize) -1);
			_tmp35_ = _tmp34_;
			_tmp36_ = string_strip (_tmp35_);
			_tmp37_ = _tmp36_;
			_g_free0 (_tmp35_);
			key = _tmp37_;
			_tmp38_ = attrs;
			_tmp39_ = g_hash_table_lookup (_tmp38_, "content");
			_tmp40_ = g_strdup ((const gchar*) _tmp39_);
			content = _tmp40_;
			_tmp41_ = content;
			if (_tmp41_ == NULL) {
				_g_free0 (content);
				_g_free0 (key);
				_g_hash_table_unref0 (attrs);
				_g_free0 (lower);
				_g_free0 (tag);
				continue;
			}
			_tmp42_ = content;
			_tmp43_ = dc_link_preview_decode_entities (_tmp42_);
			_tmp44_ = _tmp43_;
			_tmp45_ = string_strip (_tmp44_);
			_g_free0 (content);
			content = _tmp45_;
			_g_free0 (_tmp44_);
			_tmp46_ = content;
			_tmp47_ = strlen (_tmp46_);
			_tmp48_ = _tmp47_;
			if (_tmp48_ == 0) {
				_g_free0 (content);
				_g_free0 (key);
				_g_hash_table_unref0 (attrs);
				_g_free0 (lower);
				_g_free0 (tag);
				continue;
			}
			_tmp49_ = key;
			_tmp50_ = _tmp49_;
			_tmp52_ = (NULL == _tmp50_) ? 0 : g_quark_from_string (_tmp50_);
			if (_tmp52_ == ((0 != _tmp51_label0) ? _tmp51_label0 : (_tmp51_label0 = g_quark_from_static_string ("og:title")))) {
				switch (0) {
					default:
					{
						const gchar* _tmp53_;
						_tmp53_ = og_title;
						if (_tmp53_ == NULL) {
							const gchar* _tmp54_;
							gchar* _tmp55_;
							_tmp54_ = content;
							_tmp55_ = g_strdup (_tmp54_);
							_g_free0 (og_title);
							og_title = _tmp55_;
						}
						break;
					}
				}
			} else if (_tmp52_ == ((0 != _tmp51_label1) ? _tmp51_label1 : (_tmp51_label1 = g_quark_from_static_string ("og:description")))) {
				switch (0) {
					default:
					{
						const gchar* _tmp56_;
						_tmp56_ = og_desc;
						if (_tmp56_ == NULL) {
							const gchar* _tmp57_;
							gchar* _tmp58_;
							_tmp57_ = content;
							_tmp58_ = g_strdup (_tmp57_);
							_g_free0 (og_desc);
							og_desc = _tmp58_;
						}
						break;
					}
				}
			} else if (((_tmp52_ == ((0 != _tmp51_label2) ? _tmp51_label2 : (_tmp51_label2 = g_quark_from_static_string ("og:image")))) || (_tmp52_ == ((0 != _tmp51_label3) ? _tmp51_label3 : (_tmp51_label3 = g_quark_from_static_string ("og:image:url"))))) || (_tmp52_ == ((0 != _tmp51_label4) ? _tmp51_label4 : (_tmp51_label4 = g_quark_from_static_string ("og:image:secure_url"))))) {
				switch (0) {
					default:
					{
						gboolean _tmp59_ = FALSE;
						const gchar* _tmp60_;
						_tmp60_ = og_image;
						if (_tmp60_ == NULL) {
							_tmp59_ = TRUE;
						} else {
							gboolean _tmp61_ = FALSE;
							const gchar* _tmp62_;
							_tmp62_ = key;
							if (g_strcmp0 (_tmp62_, "og:image:secure_url") == 0) {
								const gchar* _tmp63_;
								_tmp63_ = og_image;
								_tmp61_ = g_str_has_prefix (_tmp63_, "http://");
							} else {
								_tmp61_ = FALSE;
							}
							_tmp59_ = _tmp61_;
						}
						if (_tmp59_) {
							const gchar* _tmp64_;
							gchar* _tmp65_;
							_tmp64_ = content;
							_tmp65_ = g_strdup (_tmp64_);
							_g_free0 (og_image);
							og_image = _tmp65_;
						}
						break;
					}
				}
			} else if (_tmp52_ == ((0 != _tmp51_label5) ? _tmp51_label5 : (_tmp51_label5 = g_quark_from_static_string ("twitter:title")))) {
				switch (0) {
					default:
					{
						const gchar* _tmp66_;
						_tmp66_ = tw_title;
						if (_tmp66_ == NULL) {
							const gchar* _tmp67_;
							gchar* _tmp68_;
							_tmp67_ = content;
							_tmp68_ = g_strdup (_tmp67_);
							_g_free0 (tw_title);
							tw_title = _tmp68_;
						}
						break;
					}
				}
			} else if (_tmp52_ == ((0 != _tmp51_label6) ? _tmp51_label6 : (_tmp51_label6 = g_quark_from_static_string ("twitter:description")))) {
				switch (0) {
					default:
					{
						const gchar* _tmp69_;
						_tmp69_ = tw_desc;
						if (_tmp69_ == NULL) {
							const gchar* _tmp70_;
							gchar* _tmp71_;
							_tmp70_ = content;
							_tmp71_ = g_strdup (_tmp70_);
							_g_free0 (tw_desc);
							tw_desc = _tmp71_;
						}
						break;
					}
				}
			} else if ((_tmp52_ == ((0 != _tmp51_label7) ? _tmp51_label7 : (_tmp51_label7 = g_quark_from_static_string ("twitter:image")))) || (_tmp52_ == ((0 != _tmp51_label8) ? _tmp51_label8 : (_tmp51_label8 = g_quark_from_static_string ("twitter:image:src"))))) {
				switch (0) {
					default:
					{
						const gchar* _tmp72_;
						_tmp72_ = tw_image;
						if (_tmp72_ == NULL) {
							const gchar* _tmp73_;
							gchar* _tmp74_;
							_tmp73_ = content;
							_tmp74_ = g_strdup (_tmp73_);
							_g_free0 (tw_image);
							tw_image = _tmp74_;
						}
						break;
					}
				}
			} else if (_tmp52_ == ((0 != _tmp51_label9) ? _tmp51_label9 : (_tmp51_label9 = g_quark_from_static_string ("description")))) {
				switch (0) {
					default:
					{
						const gchar* _tmp75_;
						_tmp75_ = meta_desc;
						if (_tmp75_ == NULL) {
							const gchar* _tmp76_;
							gchar* _tmp77_;
							_tmp76_ = content;
							_tmp77_ = g_strdup (_tmp76_);
							_g_free0 (meta_desc);
							meta_desc = _tmp77_;
						}
						break;
					}
				}
			} else {
				switch (0) {
					default:
					{
						break;
					}
				}
			}
			_g_free0 (content);
			_g_free0 (key);
			_g_hash_table_unref0 (attrs);
		} else {
			gboolean _tmp78_ = FALSE;
			const gchar* _tmp79_;
			_tmp79_ = lower;
			if (g_str_has_prefix (_tmp79_, "link")) {
				const gchar* _tmp80_;
				_tmp80_ = lower;
				_tmp78_ = dc_link_preview_is_tag_boundary (_tmp80_, 4);
			} else {
				_tmp78_ = FALSE;
			}
			if (_tmp78_) {
				GHashTable* attrs = NULL;
				const gchar* _tmp81_;
				gchar* _tmp82_;
				gchar* _tmp83_;
				GHashTable* _tmp84_;
				GHashTable* _tmp85_;
				const gchar* _tmp86_ = NULL;
				GHashTable* _tmp87_;
				gconstpointer _tmp88_;
				gchar* rel = NULL;
				gchar* _tmp89_;
				gchar* href = NULL;
				GHashTable* _tmp90_;
				gconstpointer _tmp91_;
				gchar* _tmp92_;
				gboolean _tmp93_ = FALSE;
				gboolean _tmp94_ = FALSE;
				const gchar* _tmp95_;
				_tmp81_ = tag;
				_tmp82_ = string_substring (_tmp81_, (glong) 4, (glong) -1);
				_tmp83_ = _tmp82_;
				_tmp84_ = dc_link_preview_parse_attributes (_tmp83_);
				_tmp85_ = _tmp84_;
				_g_free0 (_tmp83_);
				attrs = _tmp85_;
				_tmp87_ = attrs;
				_tmp88_ = g_hash_table_lookup (_tmp87_, "rel");
				_tmp86_ = (const gchar*) _tmp88_;
				if (_tmp86_ == NULL) {
					_tmp86_ = "";
				}
				_tmp89_ = g_utf8_strdown (_tmp86_, (gssize) -1);
				rel = _tmp89_;
				_tmp90_ = attrs;
				_tmp91_ = g_hash_table_lookup (_tmp90_, "href");
				_tmp92_ = g_strdup ((const gchar*) _tmp91_);
				href = _tmp92_;
				_tmp95_ = href;
				if (_tmp95_ != NULL) {
					const gchar* _tmp96_;
					_tmp96_ = link_image;
					_tmp94_ = _tmp96_ == NULL;
				} else {
					_tmp94_ = FALSE;
				}
				if (_tmp94_) {
					const gchar* _tmp97_;
					gchar** _tmp98_;
					gchar** _tmp99_;
					gchar** _tmp100_;
					gint _tmp100__length1;
					_tmp97_ = rel;
					_tmp99_ = _tmp98_ = g_strsplit (_tmp97_, " ", 0);
					_tmp100_ = _tmp99_;
					_tmp100__length1 = _vala_array_length (_tmp98_);
					_tmp93_ = _vala_string_array_contains (_tmp100_, _vala_array_length (_tmp98_), "image_src");
					_tmp100_ = (_vala_array_free (_tmp100_, _tmp100__length1, (GDestroyNotify) g_free), NULL);
				} else {
					_tmp93_ = FALSE;
				}
				if (_tmp93_) {
					const gchar* _tmp101_;
					gchar* _tmp102_;
					gchar* _tmp103_;
					gchar* _tmp104_;
					_tmp101_ = href;
					_tmp102_ = dc_link_preview_decode_entities (_tmp101_);
					_tmp103_ = _tmp102_;
					_tmp104_ = string_strip (_tmp103_);
					_g_free0 (link_image);
					link_image = _tmp104_;
					_g_free0 (_tmp103_);
				}
				_g_free0 (href);
				_g_free0 (rel);
				_g_hash_table_unref0 (attrs);
			} else {
				gboolean _tmp105_ = FALSE;
				gboolean _tmp106_ = FALSE;
				const gchar* _tmp107_;
				_tmp107_ = lower;
				if (g_str_has_prefix (_tmp107_, "title")) {
					const gchar* _tmp108_;
					_tmp108_ = lower;
					_tmp106_ = dc_link_preview_is_tag_boundary (_tmp108_, 5);
				} else {
					_tmp106_ = FALSE;
				}
				if (_tmp106_) {
					const gchar* _tmp109_;
					_tmp109_ = html_title;
					_tmp105_ = _tmp109_ == NULL;
				} else {
					_tmp105_ = FALSE;
				}
				if (_tmp105_) {
					gint close = 0;
					const gchar* _tmp110_;
					const gchar* _tmp111_;
					gchar* _tmp112_;
					gchar* _tmp113_;
					gchar* _tmp114_;
					gchar* _tmp115_;
					gchar* _tmp116_;
					_tmp110_ = doc;
					close = dc_link_preview_index_of_ci (_tmp110_, "</title", pos);
					if (close < 0) {
						_g_free0 (lower);
						_g_free0 (tag);
						break;
					}
					_tmp111_ = doc;
					_tmp112_ = string_substring (_tmp111_, (glong) pos, (glong) (close - pos));
					_tmp113_ = _tmp112_;
					_tmp114_ = dc_link_preview_decode_entities (_tmp113_);
					_tmp115_ = _tmp114_;
					_tmp116_ = string_strip (_tmp115_);
					_g_free0 (html_title);
					html_title = _tmp116_;
					_g_free0 (_tmp115_);
					_g_free0 (_tmp113_);
					pos = close;
				} else {
					gboolean _tmp117_ = FALSE;
					const gchar* _tmp118_;
					_tmp118_ = lower;
					if (g_str_has_prefix (_tmp118_, "/head")) {
						_tmp117_ = TRUE;
					} else {
						const gchar* _tmp119_;
						_tmp119_ = lower;
						_tmp117_ = g_str_has_prefix (_tmp119_, "body");
					}
					if (_tmp117_) {
						_g_free0 (lower);
						_g_free0 (tag);
						break;
					}
				}
			}
		}
		_g_free0 (lower);
		_g_free0 (tag);
	}
	_tmp120_ = dc_link_preview_metadata_new ();
	meta = _tmp120_;
	_tmp122_ = og_title;
	_tmp121_ = _tmp122_;
	if (_tmp121_ == NULL) {
		const gchar* _tmp123_ = NULL;
		const gchar* _tmp124_;
		_tmp124_ = tw_title;
		_tmp123_ = _tmp124_;
		if (_tmp123_ == NULL) {
			const gchar* _tmp125_;
			_tmp125_ = html_title;
			_tmp123_ = _tmp125_;
		}
		_tmp121_ = _tmp123_;
	}
	_tmp126_ = meta;
	_tmp127_ = dc_link_preview_shorten (_tmp121_, DC_LINK_PREVIEW_MAX_TITLE_CHARS);
	_g_free0 (_tmp126_->title);
	_tmp126_->title = _tmp127_;
	_tmp129_ = og_desc;
	_tmp128_ = _tmp129_;
	if (_tmp128_ == NULL) {
		const gchar* _tmp130_ = NULL;
		const gchar* _tmp131_;
		_tmp131_ = tw_desc;
		_tmp130_ = _tmp131_;
		if (_tmp130_ == NULL) {
			const gchar* _tmp132_;
			_tmp132_ = meta_desc;
			_tmp130_ = _tmp132_;
		}
		_tmp128_ = _tmp130_;
	}
	_tmp133_ = meta;
	_tmp134_ = dc_link_preview_shorten (_tmp128_, DC_LINK_PREVIEW_MAX_DESCRIPTION_CHARS);
	_g_free0 (_tmp133_->description);
	_tmp133_->description = _tmp134_;
	_tmp136_ = og_image;
	_tmp135_ = _tmp136_;
	if (_tmp135_ == NULL) {
		const gchar* _tmp137_ = NULL;
		const gchar* _tmp138_;
		_tmp138_ = tw_image;
		_tmp137_ = _tmp138_;
		if (_tmp137_ == NULL) {
			const gchar* _tmp139_;
			_tmp139_ = link_image;
			_tmp137_ = _tmp139_;
		}
		_tmp135_ = _tmp137_;
	}
	_tmp140_ = g_strdup (_tmp135_);
	img = _tmp140_;
	_tmp141_ = img;
	if (_tmp141_ != NULL) {
		DcLinkPreviewMetadata* _tmp142_;
		const gchar* _tmp143_;
		gchar* _tmp144_;
		_tmp142_ = meta;
		_tmp143_ = img;
		_tmp144_ = dc_link_preview_resolve_url (base_url, _tmp143_);
		_g_free0 (_tmp142_->image_url);
		_tmp142_->image_url = _tmp144_;
	}
	_tmp146_ = meta;
	_tmp147_ = _tmp146_->image_url;
	if (_tmp147_ == NULL) {
		DcLinkPreviewMetadata* _tmp148_;
		const gchar* _tmp149_;
		_tmp148_ = meta;
		_tmp149_ = _tmp148_->title;
		_tmp145_ = _tmp149_ == NULL;
	} else {
		_tmp145_ = FALSE;
	}
	if (_tmp145_) {
		result = NULL;
		_g_free0 (img);
		_dc_link_preview_metadata_unref0 (meta);
		_g_free0 (link_image);
		_g_free0 (meta_desc);
		_g_free0 (html_title);
		_g_free0 (tw_image);
		_g_free0 (tw_desc);
		_g_free0 (tw_title);
		_g_free0 (og_image);
		_g_free0 (og_desc);
		_g_free0 (og_title);
		_g_free0 (doc);
		_g_free0 (_tmp0_);
		return result;
	}
	result = meta;
	_g_free0 (img);
	_g_free0 (link_image);
	_g_free0 (meta_desc);
	_g_free0 (html_title);
	_g_free0 (tw_image);
	_g_free0 (tw_desc);
	_g_free0 (tw_title);
	_g_free0 (og_image);
	_g_free0 (og_desc);
	_g_free0 (og_title);
	_g_free0 (doc);
	_g_free0 (_tmp0_);
	return result;
}

/** Resolves `href` against `base_url`; only http(s) results are
            accepted. */
gchar*
dc_link_preview_resolve_url (const gchar* base_url,
                             const gchar* href)
{
	gchar* h = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	gchar* resolved = NULL;
	const gchar* _tmp13_;
	gboolean _tmp14_ = FALSE;
	const gchar* _tmp15_;
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (base_url != NULL, NULL);
	g_return_val_if_fail (href != NULL, NULL);
	_tmp0_ = string_strip (href);
	h = _tmp0_;
	_tmp1_ = h;
	_tmp2_ = strlen (_tmp1_);
	_tmp3_ = _tmp2_;
	if (_tmp3_ == 0) {
		result = NULL;
		_g_free0 (h);
		return result;
	}
	resolved = NULL;
	{
		gboolean _tmp4_ = FALSE;
		const gchar* _tmp5_;
		_tmp5_ = h;
		if (g_str_has_prefix (_tmp5_, "http://")) {
			_tmp4_ = TRUE;
		} else {
			const gchar* _tmp6_;
			_tmp6_ = h;
			_tmp4_ = g_str_has_prefix (_tmp6_, "https://");
		}
		if (_tmp4_) {
			const gchar* _tmp7_;
			gchar* _tmp8_;
			_tmp7_ = h;
			_tmp8_ = g_strdup (_tmp7_);
			_g_free0 (resolved);
			resolved = _tmp8_;
		} else {
			gchar* _tmp9_ = NULL;
			const gchar* _tmp10_;
			gchar* _tmp11_;
			gchar* _tmp12_;
			_tmp10_ = h;
			_tmp11_ = g_uri_resolve_relative (base_url, _tmp10_, G_URI_FLAGS_ENCODED | G_URI_FLAGS_PARSE_RELAXED, &_inner_error0_);
			_tmp9_ = _tmp11_;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				goto __catch0_g_error;
			}
			_tmp12_ = _tmp9_;
			_tmp9_ = NULL;
			_g_free0 (resolved);
			resolved = _tmp12_;
			_g_free0 (_tmp9_);
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
		result = NULL;
		_g_free0 (resolved);
		_g_free0 (h);
		return result;
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_free0 (resolved);
		_g_free0 (h);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return NULL;
	}
	_tmp13_ = resolved;
	if (_tmp13_ == NULL) {
		result = NULL;
		_g_free0 (resolved);
		_g_free0 (h);
		return result;
	}
	_tmp15_ = resolved;
	if (!g_str_has_prefix (_tmp15_, "http://")) {
		const gchar* _tmp16_;
		_tmp16_ = resolved;
		_tmp14_ = !g_str_has_prefix (_tmp16_, "https://");
	} else {
		_tmp14_ = FALSE;
	}
	if (_tmp14_) {
		result = NULL;
		_g_free0 (resolved);
		_g_free0 (h);
		return result;
	}
	result = resolved;
	_g_free0 (h);
	return result;
}

/** Collapses whitespace and truncates to `max_chars` with an
            ellipsis. Returns null for empty input. */
static gboolean
string_get_next_char (const gchar* self,
                      gint* index,
                      gunichar* c)
{
	gunichar _vala_c = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_vala_c = g_utf8_get_char (((gchar*) self) + (*index));
	if (_vala_c != ((gunichar) 0)) {
		gchar* _tmp0_;
		_tmp0_ = g_utf8_next_char (((gchar*) self) + (*index));
		*index = (gint) (_tmp0_ - ((gchar*) self));
		result = TRUE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	} else {
		result = FALSE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	}
}

static gint
string_index_of_nth_char (const gchar* self,
                          glong c)
{
	gchar* _tmp0_;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	_tmp0_ = g_utf8_offset_to_pointer (self, c);
	result = (gint) (_tmp0_ - ((gchar*) self));
	return result;
}

static gchar*
string_chomp (const gchar* self)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup (self);
	_result_ = _tmp0_;
	g_strchomp (_result_);
	result = _result_;
	return result;
}

gchar*
dc_link_preview_shorten (const gchar* text,
                         gint max_chars)
{
	GString* sb = NULL;
	GString* _tmp0_;
	gboolean space = FALSE;
	gint i = 0;
	gunichar c = 0U;
	gchar* s = NULL;
	GString* _tmp7_;
	const gchar* _tmp8_;
	gchar* _tmp9_;
	const gchar* _tmp10_;
	gint _tmp11_;
	gint _tmp12_;
	const gchar* _tmp13_;
	gint cut = 0;
	const gchar* _tmp14_;
	const gchar* _tmp15_;
	gchar* _tmp16_;
	gchar* _tmp17_;
	gchar* _tmp18_;
	gchar* _tmp19_;
	gchar* _tmp20_;
	gchar* _tmp21_;
	gchar* result;
	if (text == NULL) {
		result = NULL;
		return result;
	}
	_tmp0_ = g_string_new ("");
	sb = _tmp0_;
	space = FALSE;
	i = 0;
	while (TRUE) {
		gunichar _tmp1_ = 0U;
		gboolean _tmp2_;
		gboolean _tmp3_ = FALSE;
		GString* _tmp6_;
		_tmp2_ = string_get_next_char (text, &i, &_tmp1_);
		c = _tmp1_;
		if (!_tmp2_) {
			break;
		}
		if (g_unichar_isspace (c)) {
			space = TRUE;
			continue;
		}
		if (space) {
			GString* _tmp4_;
			_tmp4_ = sb;
			_tmp3_ = _tmp4_->len > ((gssize) 0);
		} else {
			_tmp3_ = FALSE;
		}
		if (_tmp3_) {
			GString* _tmp5_;
			_tmp5_ = sb;
			g_string_append_c (_tmp5_, ' ');
		}
		space = FALSE;
		_tmp6_ = sb;
		g_string_append_unichar (_tmp6_, c);
	}
	_tmp7_ = sb;
	_tmp8_ = _tmp7_->str;
	_tmp9_ = g_strdup (_tmp8_);
	s = _tmp9_;
	_tmp10_ = s;
	_tmp11_ = strlen (_tmp10_);
	_tmp12_ = _tmp11_;
	if (_tmp12_ == 0) {
		result = NULL;
		_g_free0 (s);
		_g_string_free0 (sb);
		return result;
	}
	_tmp13_ = s;
	if (g_utf8_strlen (_tmp13_, (gssize) -1) <= max_chars) {
		result = s;
		_g_string_free0 (sb);
		return result;
	}
	_tmp14_ = s;
	cut = string_index_of_nth_char (_tmp14_, (glong) (max_chars - 1));
	_tmp15_ = s;
	_tmp16_ = string_substring (_tmp15_, (glong) 0, (glong) cut);
	_tmp17_ = _tmp16_;
	_tmp18_ = string_chomp (_tmp17_);
	_tmp19_ = _tmp18_;
	_tmp20_ = g_strconcat (_tmp19_, "…", NULL);
	_tmp21_ = _tmp20_;
	_g_free0 (_tmp19_);
	_g_free0 (_tmp17_);
	result = _tmp21_;
	_g_free0 (s);
	_g_string_free0 (sb);
	return result;
}

/** Decodes the named and numeric character references that show
            up in meta content. */
static gboolean
int64_try_parse (const gchar* str,
                 gint64* _result_,
                 const gchar** unparsed,
                 guint _base)
{
	gint64 _vala__result_ = 0LL;
	const gchar* _vala_unparsed = NULL;
	gchar* endptr = NULL;
	gchar* _tmp0_ = NULL;
	gint64 _tmp1_;
	gchar* _tmp2_;
	gint _tmp3_;
	gint _tmp4_;
	gboolean result;
	g_return_val_if_fail (str != NULL, FALSE);
	errno = 0;
	_tmp1_ = g_ascii_strtoll (str, &_tmp0_, _base);
	endptr = _tmp0_;
	_vala__result_ = _tmp1_;
	_tmp2_ = endptr;
	_tmp3_ = strlen (str);
	_tmp4_ = _tmp3_;
	if (_tmp2_ == (((gchar*) str) + _tmp4_)) {
		gboolean _tmp5_ = FALSE;
		_vala_unparsed = "";
		if (errno != ERANGE) {
			_tmp5_ = errno != EINVAL;
		} else {
			_tmp5_ = FALSE;
		}
		result = _tmp5_;
		if (_result_) {
			*_result_ = _vala__result_;
		}
		if (unparsed) {
			*unparsed = _vala_unparsed;
		}
		return result;
	} else {
		gchar* _tmp6_;
		_tmp6_ = endptr;
		_vala_unparsed = (const gchar*) _tmp6_;
		result = FALSE;
		if (_result_) {
			*_result_ = _vala__result_;
		}
		if (unparsed) {
			*unparsed = _vala_unparsed;
		}
		return result;
	}
}

static gchar*
g_unichar_to_string (gunichar self)
{
	gchar* str = NULL;
	gchar* _tmp0_;
	gchar* result;
	_tmp0_ = g_new0 (gchar, 7);
	str = (gchar*) _tmp0_;
	g_unichar_to_utf8 (self, str);
	result = str;
	return result;
}

gchar*
dc_link_preview_decode_entities (const gchar* text)
{
	GString* sb = NULL;
	GString* _tmp1_;
	gint pos = 0;
	GString* _tmp64_;
	const gchar* _tmp65_;
	gchar* _tmp66_;
	gchar* result;
	g_return_val_if_fail (text != NULL, NULL);
	if (string_index_of_char (text, (gunichar) '&', 0) < 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (text);
		result = _tmp0_;
		return result;
	}
	_tmp1_ = g_string_new ("");
	sb = _tmp1_;
	pos = 0;
	while (TRUE) {
		gint _tmp2_;
		gint _tmp3_;
		gint amp = 0;
		GString* _tmp7_;
		gchar* _tmp8_;
		gchar* _tmp9_;
		gint semi = 0;
		gboolean _tmp10_ = FALSE;
		gchar* name = NULL;
		gchar* _tmp12_;
		gchar* rep = NULL;
		gboolean _tmp13_ = FALSE;
		const gchar* _tmp14_;
		const gchar* _tmp60_;
		_tmp2_ = strlen (text);
		_tmp3_ = _tmp2_;
		if (!(pos < _tmp3_)) {
			break;
		}
		amp = string_index_of_char (text, (gunichar) '&', pos);
		if (amp < 0) {
			GString* _tmp4_;
			gchar* _tmp5_;
			gchar* _tmp6_;
			_tmp4_ = sb;
			_tmp5_ = string_substring (text, (glong) pos, (glong) -1);
			_tmp6_ = _tmp5_;
			g_string_append (_tmp4_, _tmp6_);
			_g_free0 (_tmp6_);
			break;
		}
		_tmp7_ = sb;
		_tmp8_ = string_substring (text, (glong) pos, (glong) (amp - pos));
		_tmp9_ = _tmp8_;
		g_string_append (_tmp7_, _tmp9_);
		_g_free0 (_tmp9_);
		semi = string_index_of_char (text, (gunichar) ';', amp);
		if (semi < 0) {
			_tmp10_ = TRUE;
		} else {
			_tmp10_ = (semi - amp) > 12;
		}
		if (_tmp10_) {
			GString* _tmp11_;
			_tmp11_ = sb;
			g_string_append_c (_tmp11_, '&');
			pos = amp + 1;
			continue;
		}
		_tmp12_ = string_substring (text, (glong) (amp + 1), (glong) ((semi - amp) - 1));
		name = _tmp12_;
		rep = NULL;
		_tmp14_ = name;
		if (g_str_has_prefix (_tmp14_, "#x")) {
			_tmp13_ = TRUE;
		} else {
			const gchar* _tmp15_;
			_tmp15_ = name;
			_tmp13_ = g_str_has_prefix (_tmp15_, "#X");
		}
		if (_tmp13_) {
			gint64 v = 0LL;
			gboolean _tmp16_ = FALSE;
			gboolean _tmp17_ = FALSE;
			const gchar* _tmp18_;
			gchar* _tmp19_;
			gchar* _tmp20_;
			gint64 _tmp21_ = 0LL;
			gboolean _tmp22_;
			gboolean _tmp23_;
			_tmp18_ = name;
			_tmp19_ = string_substring (_tmp18_, (glong) 2, (glong) -1);
			_tmp20_ = _tmp19_;
			_tmp22_ = int64_try_parse (_tmp20_, &_tmp21_, NULL, (guint) 16);
			v = _tmp21_;
			_tmp23_ = _tmp22_;
			_g_free0 (_tmp20_);
			if (_tmp23_) {
				_tmp17_ = v > ((gint64) 0);
			} else {
				_tmp17_ = FALSE;
			}
			if (_tmp17_) {
				_tmp16_ = v <= ((gint64) 0x10FFFF);
			} else {
				_tmp16_ = FALSE;
			}
			if (_tmp16_) {
				gchar* _tmp24_;
				_tmp24_ = g_unichar_to_string ((gunichar) v);
				_g_free0 (rep);
				rep = _tmp24_;
			}
		} else {
			const gchar* _tmp25_;
			_tmp25_ = name;
			if (g_str_has_prefix (_tmp25_, "#")) {
				gint64 v = 0LL;
				gboolean _tmp26_ = FALSE;
				gboolean _tmp27_ = FALSE;
				const gchar* _tmp28_;
				gchar* _tmp29_;
				gchar* _tmp30_;
				gint64 _tmp31_ = 0LL;
				gboolean _tmp32_;
				gboolean _tmp33_;
				_tmp28_ = name;
				_tmp29_ = string_substring (_tmp28_, (glong) 1, (glong) -1);
				_tmp30_ = _tmp29_;
				_tmp32_ = int64_try_parse (_tmp30_, &_tmp31_, NULL, (guint) 10);
				v = _tmp31_;
				_tmp33_ = _tmp32_;
				_g_free0 (_tmp30_);
				if (_tmp33_) {
					_tmp27_ = v > ((gint64) 0);
				} else {
					_tmp27_ = FALSE;
				}
				if (_tmp27_) {
					_tmp26_ = v <= ((gint64) 0x10FFFF);
				} else {
					_tmp26_ = FALSE;
				}
				if (_tmp26_) {
					gchar* _tmp34_;
					_tmp34_ = g_unichar_to_string ((gunichar) v);
					_g_free0 (rep);
					rep = _tmp34_;
				}
			} else {
				const gchar* _tmp35_;
				const gchar* _tmp36_;
				GQuark _tmp38_ = 0U;
				static GQuark _tmp37_label0 = 0;
				static GQuark _tmp37_label1 = 0;
				static GQuark _tmp37_label2 = 0;
				static GQuark _tmp37_label3 = 0;
				static GQuark _tmp37_label4 = 0;
				static GQuark _tmp37_label5 = 0;
				static GQuark _tmp37_label6 = 0;
				static GQuark _tmp37_label7 = 0;
				static GQuark _tmp37_label8 = 0;
				static GQuark _tmp37_label9 = 0;
				static GQuark _tmp37_label10 = 0;
				static GQuark _tmp37_label11 = 0;
				static GQuark _tmp37_label12 = 0;
				static GQuark _tmp37_label13 = 0;
				static GQuark _tmp37_label14 = 0;
				static GQuark _tmp37_label15 = 0;
				static GQuark _tmp37_label16 = 0;
				static GQuark _tmp37_label17 = 0;
				static GQuark _tmp37_label18 = 0;
				static GQuark _tmp37_label19 = 0;
				static GQuark _tmp37_label20 = 0;
				_tmp35_ = name;
				_tmp36_ = _tmp35_;
				_tmp38_ = (NULL == _tmp36_) ? 0 : g_quark_from_string (_tmp36_);
				if (_tmp38_ == ((0 != _tmp37_label0) ? _tmp37_label0 : (_tmp37_label0 = g_quark_from_static_string ("amp")))) {
					switch (0) {
						default:
						{
							gchar* _tmp39_;
							_tmp39_ = g_strdup ("&");
							_g_free0 (rep);
							rep = _tmp39_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label1) ? _tmp37_label1 : (_tmp37_label1 = g_quark_from_static_string ("lt")))) {
					switch (0) {
						default:
						{
							gchar* _tmp40_;
							_tmp40_ = g_strdup ("<");
							_g_free0 (rep);
							rep = _tmp40_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label2) ? _tmp37_label2 : (_tmp37_label2 = g_quark_from_static_string ("gt")))) {
					switch (0) {
						default:
						{
							gchar* _tmp41_;
							_tmp41_ = g_strdup (">");
							_g_free0 (rep);
							rep = _tmp41_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label3) ? _tmp37_label3 : (_tmp37_label3 = g_quark_from_static_string ("quot")))) {
					switch (0) {
						default:
						{
							gchar* _tmp42_;
							_tmp42_ = g_strdup ("\"");
							_g_free0 (rep);
							rep = _tmp42_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label4) ? _tmp37_label4 : (_tmp37_label4 = g_quark_from_static_string ("apos")))) {
					switch (0) {
						default:
						{
							gchar* _tmp43_;
							_tmp43_ = g_strdup ("'");
							_g_free0 (rep);
							rep = _tmp43_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label5) ? _tmp37_label5 : (_tmp37_label5 = g_quark_from_static_string ("nbsp")))) {
					switch (0) {
						default:
						{
							gchar* _tmp44_;
							_tmp44_ = g_strdup (" ");
							_g_free0 (rep);
							rep = _tmp44_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label6) ? _tmp37_label6 : (_tmp37_label6 = g_quark_from_static_string ("ndash")))) {
					switch (0) {
						default:
						{
							gchar* _tmp45_;
							_tmp45_ = g_strdup ("–");
							_g_free0 (rep);
							rep = _tmp45_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label7) ? _tmp37_label7 : (_tmp37_label7 = g_quark_from_static_string ("mdash")))) {
					switch (0) {
						default:
						{
							gchar* _tmp46_;
							_tmp46_ = g_strdup ("—");
							_g_free0 (rep);
							rep = _tmp46_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label8) ? _tmp37_label8 : (_tmp37_label8 = g_quark_from_static_string ("hellip")))) {
					switch (0) {
						default:
						{
							gchar* _tmp47_;
							_tmp47_ = g_strdup ("…");
							_g_free0 (rep);
							rep = _tmp47_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label9) ? _tmp37_label9 : (_tmp37_label9 = g_quark_from_static_string ("laquo")))) {
					switch (0) {
						default:
						{
							gchar* _tmp48_;
							_tmp48_ = g_strdup ("«");
							_g_free0 (rep);
							rep = _tmp48_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label10) ? _tmp37_label10 : (_tmp37_label10 = g_quark_from_static_string ("raquo")))) {
					switch (0) {
						default:
						{
							gchar* _tmp49_;
							_tmp49_ = g_strdup ("»");
							_g_free0 (rep);
							rep = _tmp49_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label11) ? _tmp37_label11 : (_tmp37_label11 = g_quark_from_static_string ("lsquo")))) {
					switch (0) {
						default:
						{
							gchar* _tmp50_;
							_tmp50_ = g_strdup ("‘");
							_g_free0 (rep);
							rep = _tmp50_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label12) ? _tmp37_label12 : (_tmp37_label12 = g_quark_from_static_string ("rsquo")))) {
					switch (0) {
						default:
						{
							gchar* _tmp51_;
							_tmp51_ = g_strdup ("’");
							_g_free0 (rep);
							rep = _tmp51_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label13) ? _tmp37_label13 : (_tmp37_label13 = g_quark_from_static_string ("ldquo")))) {
					switch (0) {
						default:
						{
							gchar* _tmp52_;
							_tmp52_ = g_strdup ("“");
							_g_free0 (rep);
							rep = _tmp52_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label14) ? _tmp37_label14 : (_tmp37_label14 = g_quark_from_static_string ("rdquo")))) {
					switch (0) {
						default:
						{
							gchar* _tmp53_;
							_tmp53_ = g_strdup ("”");
							_g_free0 (rep);
							rep = _tmp53_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label15) ? _tmp37_label15 : (_tmp37_label15 = g_quark_from_static_string ("copy")))) {
					switch (0) {
						default:
						{
							gchar* _tmp54_;
							_tmp54_ = g_strdup ("©");
							_g_free0 (rep);
							rep = _tmp54_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label16) ? _tmp37_label16 : (_tmp37_label16 = g_quark_from_static_string ("reg")))) {
					switch (0) {
						default:
						{
							gchar* _tmp55_;
							_tmp55_ = g_strdup ("®");
							_g_free0 (rep);
							rep = _tmp55_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label17) ? _tmp37_label17 : (_tmp37_label17 = g_quark_from_static_string ("trade")))) {
					switch (0) {
						default:
						{
							gchar* _tmp56_;
							_tmp56_ = g_strdup ("™");
							_g_free0 (rep);
							rep = _tmp56_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label18) ? _tmp37_label18 : (_tmp37_label18 = g_quark_from_static_string ("euro")))) {
					switch (0) {
						default:
						{
							gchar* _tmp57_;
							_tmp57_ = g_strdup ("€");
							_g_free0 (rep);
							rep = _tmp57_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label19) ? _tmp37_label19 : (_tmp37_label19 = g_quark_from_static_string ("middot")))) {
					switch (0) {
						default:
						{
							gchar* _tmp58_;
							_tmp58_ = g_strdup ("·");
							_g_free0 (rep);
							rep = _tmp58_;
							break;
						}
					}
				} else if (_tmp38_ == ((0 != _tmp37_label20) ? _tmp37_label20 : (_tmp37_label20 = g_quark_from_static_string ("bull")))) {
					switch (0) {
						default:
						{
							gchar* _tmp59_;
							_tmp59_ = g_strdup ("•");
							_g_free0 (rep);
							rep = _tmp59_;
							break;
						}
					}
				} else {
					switch (0) {
						default:
						{
							break;
						}
					}
				}
			}
		}
		_tmp60_ = rep;
		if (_tmp60_ == NULL) {
			GString* _tmp61_;
			_tmp61_ = sb;
			g_string_append_c (_tmp61_, '&');
			pos = amp + 1;
		} else {
			GString* _tmp62_;
			const gchar* _tmp63_;
			_tmp62_ = sb;
			_tmp63_ = rep;
			g_string_append (_tmp62_, _tmp63_);
			pos = semi + 1;
		}
		_g_free0 (rep);
		_g_free0 (name);
	}
	_tmp64_ = sb;
	_tmp65_ = _tmp64_->str;
	_tmp66_ = g_strdup (_tmp65_);
	result = _tmp66_;
	_g_string_free0 (sb);
	return result;
}

/** The URL to fetch an image from. With `clean` unset the URL is
            returned untouched; otherwise tracking parameters are stripped
            (the same rules as pasted links) and, for URLs whose path is a
            plain image file, the whole query is dropped: CDNs such as
            i.ytimg.com append rendering hints and signatures the bare
            .jpg serves fine without. Callers fall back to the original
            URL when the cleaned one fails, so a signed URL still works. */
gchar*
dc_link_preview_image_fetch_url (const gchar* url,
                                 gboolean clean)
{
	gchar* cleaned = NULL;
	gchar* _tmp1_;
	gint q = 0;
	const gchar* _tmp2_;
	gchar* path = NULL;
	const gchar* _tmp3_;
	gchar* _tmp4_;
	gint hash = 0;
	const gchar* _tmp5_;
	gchar* lower = NULL;
	const gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* _tmp11_;
	gchar* _tmp12_;
	gchar* _tmp13_;
	gchar* _tmp14_;
	gchar* _tmp15_;
	gchar** _tmp16_;
	gchar* result;
	g_return_val_if_fail (url != NULL, NULL);
	if (!clean) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (url);
		result = _tmp0_;
		return result;
	}
	_tmp1_ = dc_link_cleaner_clean_url (url);
	cleaned = _tmp1_;
	_tmp2_ = cleaned;
	q = string_index_of_char (_tmp2_, (gunichar) '?', 0);
	if (q < 0) {
		result = cleaned;
		return result;
	}
	_tmp3_ = cleaned;
	_tmp4_ = string_substring (_tmp3_, (glong) 0, (glong) q);
	path = _tmp4_;
	_tmp5_ = path;
	hash = string_index_of_char (_tmp5_, (gunichar) '#', 0);
	if (hash >= 0) {
		const gchar* _tmp6_;
		gchar* _tmp7_;
		_tmp6_ = path;
		_tmp7_ = string_substring (_tmp6_, (glong) 0, (glong) hash);
		_g_free0 (path);
		path = _tmp7_;
	}
	_tmp8_ = path;
	_tmp9_ = g_utf8_strdown (_tmp8_, (gssize) -1);
	lower = _tmp9_;
	_tmp10_ = g_strdup (".jpg");
	_tmp11_ = g_strdup (".jpeg");
	_tmp12_ = g_strdup (".png");
	_tmp13_ = g_strdup (".gif");
	_tmp14_ = g_strdup (".webp");
	_tmp15_ = g_strdup (".avif");
	_tmp16_ = g_new0 (gchar*, 6 + 1);
	_tmp16_[0] = _tmp10_;
	_tmp16_[1] = _tmp11_;
	_tmp16_[2] = _tmp12_;
	_tmp16_[3] = _tmp13_;
	_tmp16_[4] = _tmp14_;
	_tmp16_[5] = _tmp15_;
	{
		gchar** ext_collection = NULL;
		gint ext_collection_length1 = 0;
		gint _ext_collection_size_ = 0;
		gint ext_it = 0;
		ext_collection = _tmp16_;
		ext_collection_length1 = 6;
		for (ext_it = 0; ext_it < ext_collection_length1; ext_it = ext_it + 1) {
			gchar* _tmp17_;
			gchar* ext = NULL;
			_tmp17_ = g_strdup (ext_collection[ext_it]);
			ext = _tmp17_;
			{
				const gchar* _tmp18_;
				const gchar* _tmp19_;
				_tmp18_ = lower;
				_tmp19_ = ext;
				if (g_str_has_suffix (_tmp18_, _tmp19_)) {
					result = path;
					_g_free0 (ext);
					ext_collection = (_vala_array_free (ext_collection, ext_collection_length1, (GDestroyNotify) g_free), NULL);
					_g_free0 (lower);
					_g_free0 (cleaned);
					return result;
				}
				_g_free0 (ext);
			}
		}
		ext_collection = (_vala_array_free (ext_collection, ext_collection_length1, (GDestroyNotify) g_free), NULL);
	}
	result = cleaned;
	_g_free0 (lower);
	_g_free0 (path);
	return result;
}

/** Maps the mimetype (or, failing that, the URL suffix) of a
            fetched image to a file extension; null for anything that is
            not a raster image we can attach. */
gchar*
dc_link_preview_image_extension (const gchar* mimetype,
                                 const gchar* url)
{
	const gchar* _tmp0_ = NULL;
	gchar* mt = NULL;
	gchar* _tmp1_;
	gint semi = 0;
	const gchar* _tmp2_;
	const gchar* _tmp7_;
	const gchar* _tmp8_;
	GQuark _tmp10_ = 0U;
	static GQuark _tmp9_label0 = 0;
	static GQuark _tmp9_label1 = 0;
	static GQuark _tmp9_label2 = 0;
	static GQuark _tmp9_label3 = 0;
	static GQuark _tmp9_label4 = 0;
	static GQuark _tmp9_label5 = 0;
	gchar* path = NULL;
	gchar* _tmp16_;
	gint q = 0;
	const gchar* _tmp17_;
	gint hash = 0;
	const gchar* _tmp20_;
	gchar* _tmp23_;
	gchar* _tmp24_;
	gchar* _tmp25_;
	gchar* _tmp26_;
	gchar* _tmp27_;
	gchar* _tmp28_;
	gchar** _tmp29_;
	gboolean _tmp40_ = FALSE;
	gboolean _tmp41_ = FALSE;
	const gchar* _tmp42_;
	gint _tmp43_;
	gint _tmp44_;
	gchar* result;
	g_return_val_if_fail (url != NULL, NULL);
	_tmp0_ = mimetype;
	if (_tmp0_ == NULL) {
		_tmp0_ = "";
	}
	_tmp1_ = g_utf8_strdown (_tmp0_, (gssize) -1);
	mt = _tmp1_;
	_tmp2_ = mt;
	semi = string_index_of_char (_tmp2_, (gunichar) ';', 0);
	if (semi >= 0) {
		const gchar* _tmp3_;
		gchar* _tmp4_;
		gchar* _tmp5_;
		gchar* _tmp6_;
		_tmp3_ = mt;
		_tmp4_ = string_substring (_tmp3_, (glong) 0, (glong) semi);
		_tmp5_ = _tmp4_;
		_tmp6_ = string_strip (_tmp5_);
		_g_free0 (mt);
		mt = _tmp6_;
		_g_free0 (_tmp5_);
	}
	_tmp7_ = mt;
	_tmp8_ = _tmp7_;
	_tmp10_ = (NULL == _tmp8_) ? 0 : g_quark_from_string (_tmp8_);
	if ((_tmp10_ == ((0 != _tmp9_label0) ? _tmp9_label0 : (_tmp9_label0 = g_quark_from_static_string ("image/jpeg")))) || (_tmp10_ == ((0 != _tmp9_label1) ? _tmp9_label1 : (_tmp9_label1 = g_quark_from_static_string ("image/jpg"))))) {
		switch (0) {
			default:
			{
				gchar* _tmp11_;
				_tmp11_ = g_strdup ("jpg");
				result = _tmp11_;
				_g_free0 (mt);
				return result;
			}
		}
	} else if (_tmp10_ == ((0 != _tmp9_label2) ? _tmp9_label2 : (_tmp9_label2 = g_quark_from_static_string ("image/png")))) {
		switch (0) {
			default:
			{
				gchar* _tmp12_;
				_tmp12_ = g_strdup ("png");
				result = _tmp12_;
				_g_free0 (mt);
				return result;
			}
		}
	} else if (_tmp10_ == ((0 != _tmp9_label3) ? _tmp9_label3 : (_tmp9_label3 = g_quark_from_static_string ("image/gif")))) {
		switch (0) {
			default:
			{
				gchar* _tmp13_;
				_tmp13_ = g_strdup ("gif");
				result = _tmp13_;
				_g_free0 (mt);
				return result;
			}
		}
	} else if (_tmp10_ == ((0 != _tmp9_label4) ? _tmp9_label4 : (_tmp9_label4 = g_quark_from_static_string ("image/webp")))) {
		switch (0) {
			default:
			{
				gchar* _tmp14_;
				_tmp14_ = g_strdup ("webp");
				result = _tmp14_;
				_g_free0 (mt);
				return result;
			}
		}
	} else if (_tmp10_ == ((0 != _tmp9_label5) ? _tmp9_label5 : (_tmp9_label5 = g_quark_from_static_string ("image/avif")))) {
		switch (0) {
			default:
			{
				gchar* _tmp15_;
				_tmp15_ = g_strdup ("avif");
				result = _tmp15_;
				_g_free0 (mt);
				return result;
			}
		}
	} else {
		switch (0) {
			default:
			{
				break;
			}
		}
	}
	_tmp16_ = g_utf8_strdown (url, (gssize) -1);
	path = _tmp16_;
	_tmp17_ = path;
	q = string_index_of_char (_tmp17_, (gunichar) '?', 0);
	if (q >= 0) {
		const gchar* _tmp18_;
		gchar* _tmp19_;
		_tmp18_ = path;
		_tmp19_ = string_substring (_tmp18_, (glong) 0, (glong) q);
		_g_free0 (path);
		path = _tmp19_;
	}
	_tmp20_ = path;
	hash = string_index_of_char (_tmp20_, (gunichar) '#', 0);
	if (hash >= 0) {
		const gchar* _tmp21_;
		gchar* _tmp22_;
		_tmp21_ = path;
		_tmp22_ = string_substring (_tmp21_, (glong) 0, (glong) hash);
		_g_free0 (path);
		path = _tmp22_;
	}
	_tmp23_ = g_strdup ("jpg");
	_tmp24_ = g_strdup ("jpeg");
	_tmp25_ = g_strdup ("png");
	_tmp26_ = g_strdup ("gif");
	_tmp27_ = g_strdup ("webp");
	_tmp28_ = g_strdup ("avif");
	_tmp29_ = g_new0 (gchar*, 6 + 1);
	_tmp29_[0] = _tmp23_;
	_tmp29_[1] = _tmp24_;
	_tmp29_[2] = _tmp25_;
	_tmp29_[3] = _tmp26_;
	_tmp29_[4] = _tmp27_;
	_tmp29_[5] = _tmp28_;
	{
		gchar** ext_collection = NULL;
		gint ext_collection_length1 = 0;
		gint _ext_collection_size_ = 0;
		gint ext_it = 0;
		ext_collection = _tmp29_;
		ext_collection_length1 = 6;
		for (ext_it = 0; ext_it < ext_collection_length1; ext_it = ext_it + 1) {
			gchar* _tmp30_;
			gchar* ext = NULL;
			_tmp30_ = g_strdup (ext_collection[ext_it]);
			ext = _tmp30_;
			{
				const gchar* _tmp31_;
				const gchar* _tmp32_;
				gchar* _tmp33_;
				gchar* _tmp34_;
				gboolean _tmp35_;
				_tmp31_ = path;
				_tmp32_ = ext;
				_tmp33_ = g_strconcat (".", _tmp32_, NULL);
				_tmp34_ = _tmp33_;
				_tmp35_ = g_str_has_suffix (_tmp31_, _tmp34_);
				_g_free0 (_tmp34_);
				if (_tmp35_) {
					const gchar* _tmp36_ = NULL;
					const gchar* _tmp37_;
					gchar* _tmp39_;
					_tmp37_ = ext;
					if (g_strcmp0 (_tmp37_, "jpeg") == 0) {
						_tmp36_ = "jpg";
					} else {
						const gchar* _tmp38_;
						_tmp38_ = ext;
						_tmp36_ = _tmp38_;
					}
					_tmp39_ = g_strdup (_tmp36_);
					result = _tmp39_;
					_g_free0 (ext);
					ext_collection = (_vala_array_free (ext_collection, ext_collection_length1, (GDestroyNotify) g_free), NULL);
					_g_free0 (path);
					_g_free0 (mt);
					return result;
				}
				_g_free0 (ext);
			}
		}
		ext_collection = (_vala_array_free (ext_collection, ext_collection_length1, (GDestroyNotify) g_free), NULL);
	}
	_tmp42_ = mt;
	_tmp43_ = strlen (_tmp42_);
	_tmp44_ = _tmp43_;
	if (_tmp44_ == 0) {
		_tmp41_ = TRUE;
	} else {
		const gchar* _tmp45_;
		_tmp45_ = mt;
		_tmp41_ = g_str_has_prefix (_tmp45_, "image/");
	}
	if (_tmp41_) {
		_tmp40_ = TRUE;
	} else {
		const gchar* _tmp46_;
		_tmp46_ = mt;
		_tmp40_ = g_strcmp0 (_tmp46_, "application/octet-stream") == 0;
	}
	if (_tmp40_) {
		gchar* _tmp47_;
		_tmp47_ = g_strdup ("img");
		result = _tmp47_;
		_g_free0 (path);
		_g_free0 (mt);
		return result;
	}
	result = NULL;
	_g_free0 (path);
	_g_free0 (mt);
	return result;
}

static gchar
string_get (const gchar* self,
            glong index)
{
	gchar _tmp0_;
	gchar result;
	g_return_val_if_fail (self != NULL, '\0');
	_tmp0_ = ((gchar*) self)[index];
	result = _tmp0_;
	return result;
}

gboolean
dc_link_preview_is_tag_boundary (const gchar* lower,
                                 gint at)
{
	gint _tmp0_;
	gint _tmp1_;
	gchar c = '\0';
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	gboolean _tmp6_ = FALSE;
	gboolean result;
	g_return_val_if_fail (lower != NULL, FALSE);
	_tmp0_ = strlen (lower);
	_tmp1_ = _tmp0_;
	if (_tmp1_ <= at) {
		result = TRUE;
		return result;
	}
	c = string_get (lower, (glong) at);
	if (c == ' ') {
		_tmp6_ = TRUE;
	} else {
		_tmp6_ = c == '\t';
	}
	if (_tmp6_) {
		_tmp5_ = TRUE;
	} else {
		_tmp5_ = c == '\n';
	}
	if (_tmp5_) {
		_tmp4_ = TRUE;
	} else {
		_tmp4_ = c == '\r';
	}
	if (_tmp4_) {
		_tmp3_ = TRUE;
	} else {
		_tmp3_ = c == '/';
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = c == '>';
	}
	result = _tmp2_;
	return result;
}

gint
dc_link_preview_find_tag_end (const gchar* doc,
                              gint from)
{
	gchar quote = '\0';
	gint result;
	g_return_val_if_fail (doc != NULL, -1);
	quote = (gchar) 0;
	{
		gint i = 0;
		i = from;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				gint _tmp2_;
				gint _tmp3_;
				gchar c = '\0';
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = i;
					i = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				_tmp2_ = strlen (doc);
				_tmp3_ = _tmp2_;
				if (!(i < _tmp3_)) {
					break;
				}
				c = string_get (doc, (glong) i);
				if (((gint) quote) != 0) {
					if (c == quote) {
						quote = (gchar) 0;
					}
				} else {
					gboolean _tmp4_ = FALSE;
					if (c == '"') {
						_tmp4_ = TRUE;
					} else {
						_tmp4_ = c == '\'';
					}
					if (_tmp4_) {
						quote = c;
					} else {
						if (c == '>') {
							result = i;
							return result;
						}
					}
				}
			}
		}
	}
	result = -1;
	return result;
}

gint
dc_link_preview_index_of_ci (const gchar* doc,
                             const gchar* needle,
                             gint from)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gint _tmp2_;
	gint result;
	g_return_val_if_fail (doc != NULL, -1);
	g_return_val_if_fail (needle != NULL, -1);
	_tmp0_ = g_utf8_strdown (doc, (gssize) -1);
	_tmp1_ = _tmp0_;
	_tmp2_ = string_index_of (_tmp1_, needle, from);
	_g_free0 (_tmp1_);
	result = _tmp2_;
	return result;
}

static void
_g_free0_ (gpointer var)
{
	var = (g_free (var), NULL);
}

GHashTable*
dc_link_preview_parse_attributes (const gchar* s)
{
	GHashTable* attrs = NULL;
	GHashFunc _tmp0_;
	GEqualFunc _tmp1_;
	GHashTable* _tmp2_;
	gint i = 0;
	gint n = 0;
	gint _tmp3_;
	gint _tmp4_;
	GHashTable* result;
	g_return_val_if_fail (s != NULL, NULL);
	_tmp0_ = g_str_hash;
	_tmp1_ = g_str_equal;
	_tmp2_ = g_hash_table_new_full (_tmp0_, _tmp1_, _g_free0_, _g_free0_);
	attrs = _tmp2_;
	i = 0;
	_tmp3_ = strlen (s);
	_tmp4_ = _tmp3_;
	n = _tmp4_;
	while (TRUE) {
		gint name_start = 0;
		gchar* name = NULL;
		gchar* _tmp19_;
		gchar* _tmp20_;
		gchar* _tmp21_;
		gchar* _tmp22_;
		const gchar* _tmp23_;
		gint _tmp24_;
		gint _tmp25_;
		gchar* value = NULL;
		gchar* _tmp32_;
		gboolean _tmp33_ = FALSE;
		GHashTable* _tmp54_;
		const gchar* _tmp55_;
		if (!(i < n)) {
			break;
		}
		while (TRUE) {
			gboolean _tmp5_ = FALSE;
			gint _tmp10_;
			if (i < n) {
				gboolean _tmp6_ = FALSE;
				gboolean _tmp7_ = FALSE;
				gboolean _tmp8_ = FALSE;
				gboolean _tmp9_ = FALSE;
				if (string_get (s, (glong) i) == ' ') {
					_tmp9_ = TRUE;
				} else {
					_tmp9_ = string_get (s, (glong) i) == '\t';
				}
				if (_tmp9_) {
					_tmp8_ = TRUE;
				} else {
					_tmp8_ = string_get (s, (glong) i) == '\n';
				}
				if (_tmp8_) {
					_tmp7_ = TRUE;
				} else {
					_tmp7_ = string_get (s, (glong) i) == '\r';
				}
				if (_tmp7_) {
					_tmp6_ = TRUE;
				} else {
					_tmp6_ = string_get (s, (glong) i) == '/';
				}
				_tmp5_ = _tmp6_;
			} else {
				_tmp5_ = FALSE;
			}
			if (!_tmp5_) {
				break;
			}
			_tmp10_ = i;
			i = _tmp10_ + 1;
		}
		if (i >= n) {
			break;
		}
		name_start = i;
		while (TRUE) {
			gboolean _tmp11_ = FALSE;
			gboolean _tmp12_ = FALSE;
			gboolean _tmp13_ = FALSE;
			gboolean _tmp14_ = FALSE;
			gboolean _tmp15_ = FALSE;
			gboolean _tmp16_ = FALSE;
			gboolean _tmp17_ = FALSE;
			gint _tmp18_;
			if (i < n) {
				_tmp17_ = string_get (s, (glong) i) != '=';
			} else {
				_tmp17_ = FALSE;
			}
			if (_tmp17_) {
				_tmp16_ = string_get (s, (glong) i) != ' ';
			} else {
				_tmp16_ = FALSE;
			}
			if (_tmp16_) {
				_tmp15_ = string_get (s, (glong) i) != '\t';
			} else {
				_tmp15_ = FALSE;
			}
			if (_tmp15_) {
				_tmp14_ = string_get (s, (glong) i) != '\n';
			} else {
				_tmp14_ = FALSE;
			}
			if (_tmp14_) {
				_tmp13_ = string_get (s, (glong) i) != '\r';
			} else {
				_tmp13_ = FALSE;
			}
			if (_tmp13_) {
				_tmp12_ = string_get (s, (glong) i) != '/';
			} else {
				_tmp12_ = FALSE;
			}
			if (_tmp12_) {
				_tmp11_ = string_get (s, (glong) i) != '>';
			} else {
				_tmp11_ = FALSE;
			}
			if (!_tmp11_) {
				break;
			}
			_tmp18_ = i;
			i = _tmp18_ + 1;
		}
		_tmp19_ = string_substring (s, (glong) name_start, (glong) (i - name_start));
		_tmp20_ = _tmp19_;
		_tmp21_ = g_utf8_strdown (_tmp20_, (gssize) -1);
		_tmp22_ = _tmp21_;
		_g_free0 (_tmp20_);
		name = _tmp22_;
		_tmp23_ = name;
		_tmp24_ = strlen (_tmp23_);
		_tmp25_ = _tmp24_;
		if (_tmp25_ == 0) {
			gint _tmp26_;
			_tmp26_ = i;
			i = _tmp26_ + 1;
			_g_free0 (name);
			continue;
		}
		while (TRUE) {
			gboolean _tmp27_ = FALSE;
			gint _tmp31_;
			if (i < n) {
				gboolean _tmp28_ = FALSE;
				gboolean _tmp29_ = FALSE;
				gboolean _tmp30_ = FALSE;
				if (string_get (s, (glong) i) == ' ') {
					_tmp30_ = TRUE;
				} else {
					_tmp30_ = string_get (s, (glong) i) == '\t';
				}
				if (_tmp30_) {
					_tmp29_ = TRUE;
				} else {
					_tmp29_ = string_get (s, (glong) i) == '\n';
				}
				if (_tmp29_) {
					_tmp28_ = TRUE;
				} else {
					_tmp28_ = string_get (s, (glong) i) == '\r';
				}
				_tmp27_ = _tmp28_;
			} else {
				_tmp27_ = FALSE;
			}
			if (!_tmp27_) {
				break;
			}
			_tmp31_ = i;
			i = _tmp31_ + 1;
		}
		_tmp32_ = g_strdup ("");
		value = _tmp32_;
		if (i < n) {
			_tmp33_ = string_get (s, (glong) i) == '=';
		} else {
			_tmp33_ = FALSE;
		}
		if (_tmp33_) {
			gint _tmp34_;
			gboolean _tmp40_ = FALSE;
			_tmp34_ = i;
			i = _tmp34_ + 1;
			while (TRUE) {
				gboolean _tmp35_ = FALSE;
				gint _tmp39_;
				if (i < n) {
					gboolean _tmp36_ = FALSE;
					gboolean _tmp37_ = FALSE;
					gboolean _tmp38_ = FALSE;
					if (string_get (s, (glong) i) == ' ') {
						_tmp38_ = TRUE;
					} else {
						_tmp38_ = string_get (s, (glong) i) == '\t';
					}
					if (_tmp38_) {
						_tmp37_ = TRUE;
					} else {
						_tmp37_ = string_get (s, (glong) i) == '\n';
					}
					if (_tmp37_) {
						_tmp36_ = TRUE;
					} else {
						_tmp36_ = string_get (s, (glong) i) == '\r';
					}
					_tmp35_ = _tmp36_;
				} else {
					_tmp35_ = FALSE;
				}
				if (!_tmp35_) {
					break;
				}
				_tmp39_ = i;
				i = _tmp39_ + 1;
			}
			if (i < n) {
				gboolean _tmp41_ = FALSE;
				if (string_get (s, (glong) i) == '"') {
					_tmp41_ = TRUE;
				} else {
					_tmp41_ = string_get (s, (glong) i) == '\'';
				}
				_tmp40_ = _tmp41_;
			} else {
				_tmp40_ = FALSE;
			}
			if (_tmp40_) {
				gchar q = '\0';
				gint vs = 0;
				gint _tmp42_;
				gchar* _tmp45_;
				q = string_get (s, (glong) i);
				i = i + 1;
				_tmp42_ = i;
				vs = _tmp42_;
				while (TRUE) {
					gboolean _tmp43_ = FALSE;
					gint _tmp44_;
					if (i < n) {
						_tmp43_ = string_get (s, (glong) i) != q;
					} else {
						_tmp43_ = FALSE;
					}
					if (!_tmp43_) {
						break;
					}
					_tmp44_ = i;
					i = _tmp44_ + 1;
				}
				_tmp45_ = string_substring (s, (glong) vs, (glong) (i - vs));
				_g_free0 (value);
				value = _tmp45_;
				if (i < n) {
					gint _tmp46_;
					_tmp46_ = i;
					i = _tmp46_ + 1;
				}
			} else {
				gint vs = 0;
				gchar* _tmp53_;
				vs = i;
				while (TRUE) {
					gboolean _tmp47_ = FALSE;
					gboolean _tmp48_ = FALSE;
					gboolean _tmp49_ = FALSE;
					gboolean _tmp50_ = FALSE;
					gboolean _tmp51_ = FALSE;
					gint _tmp52_;
					if (i < n) {
						_tmp51_ = string_get (s, (glong) i) != ' ';
					} else {
						_tmp51_ = FALSE;
					}
					if (_tmp51_) {
						_tmp50_ = string_get (s, (glong) i) != '\t';
					} else {
						_tmp50_ = FALSE;
					}
					if (_tmp50_) {
						_tmp49_ = string_get (s, (glong) i) != '\n';
					} else {
						_tmp49_ = FALSE;
					}
					if (_tmp49_) {
						_tmp48_ = string_get (s, (glong) i) != '\r';
					} else {
						_tmp48_ = FALSE;
					}
					if (_tmp48_) {
						_tmp47_ = string_get (s, (glong) i) != '>';
					} else {
						_tmp47_ = FALSE;
					}
					if (!_tmp47_) {
						break;
					}
					_tmp52_ = i;
					i = _tmp52_ + 1;
				}
				_tmp53_ = string_substring (s, (glong) vs, (glong) (i - vs));
				_g_free0 (value);
				value = _tmp53_;
			}
		}
		_tmp54_ = attrs;
		_tmp55_ = name;
		if (!g_hash_table_contains (_tmp54_, _tmp55_)) {
			GHashTable* _tmp56_;
			const gchar* _tmp57_;
			gchar* _tmp58_;
			const gchar* _tmp59_;
			gchar* _tmp60_;
			_tmp56_ = attrs;
			_tmp57_ = name;
			_tmp58_ = g_strdup (_tmp57_);
			_tmp59_ = value;
			_tmp60_ = g_strdup (_tmp59_);
			g_hash_table_insert (_tmp56_, _tmp58_, _tmp60_);
		}
		_g_free0 (value);
		_g_free0 (name);
	}
	result = attrs;
	return result;
}

static void
_vala_array_destroy (gpointer array,
                     gssize array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}

static void
_vala_array_free (gpointer array,
                  gssize array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}

static gssize
_vala_array_length (gpointer array)
{
	gssize length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

