<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery shapeshift Plugin Basic Demo</title>
<!-- jQuery / jQuery UI -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<!-- jQuery Touch Punch - Enable Touch Drag and Drop -->
<script>
(function(b){b.support.touch="ontouchend" in document;if(!b.support.touch){return;}var c=b.ui.mouse.prototype,e=c._mouseInit,a;function d(g,h){if(g.originalEvent.touches.length>1){return;}g.preventDefault();var i=g.originalEvent.changedTouches[0],f=document.createEvent("MouseEvents");f.initMouseEvent(h,true,true,window,1,i.screenX,i.screenY,i.clientX,i.clientY,false,false,false,false,0,null);g.target.dispatchEvent(f);}c._touchStart=function(g){var f=this;if(a||!f._mouseCapture(g.originalEvent.changedTouches[0])){return;}a=true;f._touchMoved=false;d(g,"mouseover");d(g,"mousemove");d(g,"mousedown");};c._touchMove=function(f){if(!a){return;}this._touchMoved=true;d(f,"mousemove");};c._touchEnd=function(f){if(!a){return;}d(f,"mouseup");d(f,"mouseout");if(!this._touchMoved){d(f,"click");}a=false;};c._mouseInit=function(){var f=this;f.element.bind("touchstart",b.proxy(f,"_touchStart")).bind("touchmove",b.proxy(f,"_touchMove")).bind("touchend",b.proxy(f,"_touchEnd"));e.call(f);};})(jQuery);
// Generated by CoffeeScript 1.4.0
(function() {
(function($, window, document) {
var Plugin, defaults, pluginName;
pluginName = "shapeshift";
defaults = {
selector: "*",
enableDrag: true,
enableCrossDrop: true,
enableResize: true,
enableTrash: false,
align: "center",
colWidth: null,
columns: null,
minColumns: 1,
autoHeight: true,
maxHeight: null,
minHeight: 100,
gutterX: 10,
gutterY: 10,
paddingX: 10,
paddingY: 10,
animated: true,
animateOnInit: false,
animationSpeed: 225,
animationThreshold: 100,
dragClone: false,
deleteClone: true,
dragRate: 100,
dragWhitelist: "*",
crossDropWhitelist: "*",
cutoffStart: null,
cutoffEnd: null,
handle: false,
cloneClass: "ss-cloned-child",
activeClass: "ss-active-child",
draggedClass: "ss-dragged-child",
placeholderClass: "ss-placeholder-child",
originalContainerClass: "ss-original-container",
currentContainerClass: "ss-current-container",
previousContainerClass: "ss-previous-container"
};
Plugin = (function() {
function Plugin(element, options) {
this.element = element;
this.options = $.extend({}, defaults, options);
this.globals = {};
this.$container = $(element);
if (this.errorCheck()) {
this.init();
}
}
Plugin.prototype.errorCheck = function() {
var $children, error_msg, errors, options;
options = this.options;
errors = false;
error_msg = "Shapeshift ERROR:";
if (options.colWidth === null) {
$children = this.$container.children(options.selector);
if ($children.length === 0) {
errors = true;
console.error("" + error_msg + " option colWidth must be specified if Shapeshift is initialized with no active children.");
}
}
return !errors;
};
Plugin.prototype.init = function() {
this.createEvents();
this.setGlobals();
this.setIdentifier();
this.setActiveChildren();
this.enableFeatures();
this.gridInit();
this.render();
return this.afterInit();
};
Plugin.prototype.createEvents = function() {
var $container, options,
_this = this;
options = this.options;
$container = this.$container;
$container.off("ss-arrange").on("ss-arrange", function(e, trigger_drop_finished) {
if (trigger_drop_finished == null) {
trigger_drop_finished = false;
}
return _this.render(false, trigger_drop_finished);
});
$container.off("ss-rearrange").on("ss-rearrange", function() {
return _this.render(true);
});
$container.off("ss-setTargetPosition").on("ss-setTargetPosition", function() {
return _this.setTargetPosition();
});
$container.off("ss-destroy").on("ss-destroy", function() {
return _this.destroy();
});
return $container.off("ss-shuffle").on("ss-shuffle", function() {
return _this.shuffle();
});
};
Plugin.prototype.setGlobals = function() {
this.globals.animated = this.options.animateOnInit;
return this.globals.dragging = false;
};
Plugin.prototype.afterInit = function() {
return this.globals.animated = this.options.animated;
};
Plugin.prototype.setIdentifier = function() {
this.identifier = "shapeshifted_container_" + Math.random().toString(36).substring(7);
return this.$container.addClass(this.identifier);
};
Plugin.prototype.enableFeatures = function() {
if (this.options.enableResize) {
this.enableResize();
}
if (this.options.enableDrag || this.options.enableCrossDrop) {
return this.enableDragNDrop();
}
};
Plugin.prototype.setActiveChildren = function() {
var $children, active_child_class, colspan, columns, i, min_columns, options, total, _i, _j, _ref, _results;
options = this.options;
$children = this.$container.children(options.selector);
active_child_class = options.activeClass;
total = $children.length;
for (i = _i = 0; 0 <= total ? _i < total : _i > total; i = 0 <= total ? ++_i : --_i) {
$($children[i]).addClass(active_child_class);
}
this.setParsedChildren();
columns = options.columns;
_results = [];
for (i = _j = 0, _ref = this.parsedChildren.length; 0 <= _ref ? _j < _ref : _j > _ref; i = 0 <= _ref ? ++_j : --_j) {
colspan = this.parsedChildren[i].colspan;
min_columns = options.minColumns;
if (colspan > columns && colspan > min_columns) {
options.minColumns = colspan;
_results.push(console.error("Shapeshift ERROR: There are child elements that have a larger colspan than the minimum columns set through options.\noptions.minColumns has been set to " + colspan));
} else {
_results.push(void 0);
}
}
return _results;
};
Plugin.prototype.setParsedChildren = function() {
var $child, $children, child, i, parsedChildren, total, _i;
$children = this.$container.find("." + this.options.activeClass).filter(":visible");
total = $children.length;
parsedChildren = [];
for (i = _i = 0; 0 <= total ? _i < total : _i > total; i = 0 <= total ? ++_i : --_i) {
$child = $($children[i]);
child = {
i: i,
el: $child,
colspan: parseInt($child.attr("data-ss-colspan")) || 1,
height: $child.outerHeight()
};
parsedChildren.push(child);
}
return this.parsedChildren = parsedChildren;
};
Plugin.prototype.gridInit = function() {
var fc_colspan, fc_width, first_child, gutter_x, single_width;
gutter_x = this.options.gutterX;
if (!(this.options.colWidth >= 1)) {
first_child = this.parsedChildren[0];
fc_width = first_child.el.outerWidth();
fc_colspan = first_child.colspan;
single_width = (fc_width - ((fc_colspan - 1) * gutter_x)) / fc_colspan;
return this.globals.col_width = single_width + gutter_x;
} else {
return this.globals.col_width = this.options.colWidth + gutter_x;
}
};
Plugin.prototype.render = function(reparse, trigger_drop_finished) {
if (reparse == null) {
reparse = false;
}
if (reparse) {
this.setActiveChildren();
}
this.setGridColumns();
return this.arrange(false, trigger_drop_finished);
};
Plugin.prototype.setGridColumns = function() {
var actual_columns, children_count, col_width, colspan, columns, globals, grid_width, gutter_x, i, inner_width, minColumns, options, padding_x, _i, _ref;
globals = this.globals;
options = this.options;
col_width = globals.col_width;
gutter_x = options.gutterX;
padding_x = options.paddingX;
inner_width = this.$container.innerWidth() - (padding_x * 2);
minColumns = options.minColumns;
columns = options.columns || Math.floor((inner_width + gutter_x) / col_width);
if (minColumns && minColumns > columns) {
columns = minColumns;
}
globals.columns = columns;
children_count = this.parsedChildren.length;
if (columns > children_count) {
actual_columns = 0;
for (i = _i = 0, _ref = this.parsedChildren.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
colspan = this.parsedChildren[i].colspan;
if (colspan + actual_columns <= columns) {
actual_columns += colspan;
}
}
columns = actual_columns;
}
globals.child_offset = padding_x;
switch (options.align) {
case "center":
grid_width = (columns * col_width) - gutter_x;
return globals.child_offset += (inner_width - grid_width) / 2;
case "right":
grid_width = (columns * col_width) - gutter_x;
return globals.child_offset += inner_width - grid_width;
}
};
Plugin.prototype.arrange = function(reparse, trigger_drop_finished) {
var $child, $container, animated, animation_speed, attributes, child_positions, container_height, dragged_class, globals, i, is_dragged_child, max_height, min_height, options, parsed_children, placeholder_class, total_children, _i;
if (reparse) {
this.setParsedChildren();
}
globals = this.globals;
options = this.options;
$container = this.$container;
child_positions = this.getPositions();
parsed_children = this.parsedChildren;
total_children = parsed_children.length;
animated = globals.animated && total_children <= options.animationThreshold;
animation_speed = options.animationSpeed;
dragged_class = options.draggedClass;
for (i = _i = 0; 0 <= total_children ? _i < total_children : _i > total_children; i = 0 <= total_children ? ++_i : --_i) {
$child = parsed_children[i].el;
attributes = child_positions[i];
is_dragged_child = $child.hasClass(dragged_class);
if (is_dragged_child) {
placeholder_class = options.placeholderClass;
$child = $child.siblings("." + placeholder_class);
}
if (animated && !is_dragged_child) {
$child.stop(true, false).animate(attributes, animation_speed, function() {});
} else {
$child.css(attributes);
}
}
if (trigger_drop_finished) {
if (animated) {
setTimeout((function() {
return $container.trigger("ss-drop-complete");
}), animation_speed);
} else {
$container.trigger("ss-drop-complete");
}
}
$container.trigger("ss-arranged");
if (options.autoHeight) {
container_height = globals.container_height;
max_height = options.maxHeight;
min_height = options.minHeight;
if (min_height && container_height < min_height) {
container_height = min_height;
} else if (max_height && container_height > max_height) {
container_height = max_height;
}
return $container.height(container_height);
}
};
Plugin.prototype.getPositions = function(include_dragged) {
var col_heights, determineMultiposition, determinePositions, dragged_class, globals, grid_height, gutter_y, i, options, padding_y, parsed_children, positions, recalculateSavedChildren, savePosition, saved_children, total_children, _i, _ref,
_this = this;
if (include_dragged == null) {
include_dragged = true;
}
globals = this.globals;
options = this.options;
gutter_y = options.gutterY;
padding_y = options.paddingY;
dragged_class = options.draggedClass;
parsed_children = this.parsedChildren;
total_children = parsed_children.length;
col_heights = [];
for (i = _i = 0, _ref = globals.columns; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
col_heights.push(padding_y);
}
savePosition = function(child) {
var col, colspan, j, offset_x, offset_y, _j, _results;
col = child.col;
colspan = child.colspan;
offset_x = (child.col * globals.col_width) + globals.child_offset;
offset_y = col_heights[col];
positions[child.i] = {
left: offset_x,
top: offset_y
};
col_heights[col] += child.height + gutter_y;
if (colspan >= 1) {
_results = [];
for (j = _j = 1; 1 <= colspan ? _j < colspan : _j > colspan; j = 1 <= colspan ? ++_j : --_j) {
_results.push(col_heights[col + j] = col_heights[col]);
}
return _results;
}
};
determineMultiposition = function(child) {
var chosen_col, col, colspan, height, kosher, next_height, offset, possible_col_heights, possible_cols, span, _j, _k;
possible_cols = col_heights.length - child.colspan + 1;
possible_col_heights = col_heights.slice(0).splice(0, possible_cols);
chosen_col = void 0;
for (offset = _j = 0; 0 <= possible_cols ? _j < possible_cols : _j > possible_cols; offset = 0 <= possible_cols ? ++_j : --_j) {
col = _this.lowestCol(possible_col_heights, offset);
colspan = child.colspan;
height = col_heights[col];
kosher = true;
for (span = _k = 1; 1 <= colspan ? _k < colspan : _k > colspan; span = 1 <= colspan ? ++_k : --_k) {
next_height = col_heights[col + span];
if (height < next_height) {
kosher = false;
break;
}
}
if (kosher) {
chosen_col = col;
break;
}
}
return chosen_col;
};
saved_children = [];
recalculateSavedChildren = function() {
var index, pop_i, saved_child, saved_i, to_pop, _j, _k, _ref1, _ref2, _results;
to_pop = [];
for (saved_i = _j = 0, _ref1 = saved_children.length; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; saved_i = 0 <= _ref1 ? ++_j : --_j) {
saved_child = saved_children[saved_i];
saved_child.col = determineMultiposition(saved_child);
if (saved_child.col >= 0) {
savePosition(saved_child);
to_pop.push(saved_i);
}
}
_results = [];
for (pop_i = _k = _ref2 = to_pop.length - 1; _k >= 0; pop_i = _k += -1) {
index = to_pop[pop_i];
_results.push(saved_children.splice(index, 1));
}
return _results;
};
positions = [];
(determinePositions = function() {
var child, _j, _results;
_results = [];
for (i = _j = 0; 0 <= total_children ? _j < total_children : _j > total_children; i = 0 <= total_children ? ++_j : --_j) {
child = parsed_children[i];
if (!(!include_dragged && child.el.hasClass(dragged_class))) {
if (child.colspan > 1) {
child.col = determineMultiposition(child);
} else {
child.col = _this.lowestCol(col_heights);
}
if (child.col === void 0) {
saved_children.push(child);
} else {
savePosition(child);
}
_results.push(recalculateSavedChildren());
} else {
_results.push(void 0);
}
}
return _results;
})();
if (options.autoHeight) {
grid_height = col_heights[this.highestCol(col_heights)] - gutter_y;
globals.container_height = grid_height + padding_y;
}
return positions;
};
Plugin.prototype.enableDragNDrop = function() {
var $clone, $container, $placeholder, $selected, active_class, clone_class, current_container_class, delete_clone, drag_clone, drag_rate, drag_timeout, dragged_class, options, original_container_class, placeholder_class, previous_container_class, selected_offset_x, selected_offset_y,
_this = this;
options = this.options;
$container = this.$container;
active_class = options.activeClass;
dragged_class = options.draggedClass;
placeholder_class = options.placeholderClass;
original_container_class = options.originalContainerClass;
current_container_class = options.currentContainerClass;
previous_container_class = options.previousContainerClass;
delete_clone = options.deleteClone;
drag_rate = options.dragRate;
drag_clone = options.dragClone;
clone_class = options.cloneClass;
$selected = $placeholder = $clone = selected_offset_y = selected_offset_x = null;
drag_timeout = false;
if (options.enableDrag) {
$container.children("." + active_class).filter(options.dragWhitelist).draggable({
addClasses: false,
containment: 'document',
handle: options.handle,
zIndex: 9999,
start: function(e, ui) {
var selected_tag;
_this.globals.dragging = true;
$selected = $(e.target);
if (drag_clone) {
$clone = $selected.clone(false, false).insertBefore($selected).addClass(clone_class);
}
$selected.addClass(dragged_class);
selected_tag = $selected.prop("tagName");
$placeholder = $("<" + selected_tag + " class='" + placeholder_class + "' style='height: " + ($selected.height()) + "px; width: " + ($selected.width()) + "px'></" + selected_tag + ">");
$selected.parent().addClass(original_container_class).addClass(current_container_class);
selected_offset_y = $selected.outerHeight() / 2;
return selected_offset_x = $selected.outerWidth() / 2;
},
drag: function(e, ui) {
if (!drag_timeout && !(drag_clone && delete_clone && $("." + current_container_class)[0] === $("." + original_container_class)[0])) {
$placeholder.remove().appendTo("." + current_container_class);
$("." + current_container_class).trigger("ss-setTargetPosition");
drag_timeout = true;
window.setTimeout((function() {
return drag_timeout = false;
}), drag_rate);
}
ui.position.left = e.pageX - $selected.parent().offset().left - selected_offset_x;
return ui.position.top = e.pageY - $selected.parent().offset().top - selected_offset_y;
},
stop: function() {
var $current_container, $original_container, $previous_container;
_this.globals.dragging = false;
$original_container = $("." + original_container_class);
$current_container = $("." + current_container_class);
$previous_container = $("." + previous_container_class);
$selected.removeClass(dragged_class);
$("." + placeholder_class).remove();
if (drag_clone) {
if (delete_clone && $("." + current_container_class)[0] === $("." + original_container_class)[0]) {
$clone.remove();
$("." + current_container_class).trigger("ss-rearrange");
} else {
$clone.removeClass(clone_class);
$original_container.shapeshift($original_container.data("plugin_shapeshift").options);
$current_container.shapeshift($current_container.data("plugin_shapeshift").options);
}
}
if ($original_container[0] === $current_container[0]) {
$current_container.trigger("ss-rearranged", $selected);
} else {
$original_container.trigger("ss-removed", $selected);
$current_container.trigger("ss-added", $selected);
}
$original_container.trigger("ss-arrange").removeClass(original_container_class);
$current_container.trigger("ss-arrange", true).removeClass(current_container_class);
$previous_container.trigger("ss-arrange").removeClass(previous_container_class);
return $selected = $placeholder = null;
}
});
}
if (options.enableCrossDrop) {
return $container.droppable({
accept: options.crossDropWhitelist,
tolerance: 'intersect',
over: function(e) {
$("." + previous_container_class).removeClass(previous_container_class);
$("." + current_container_class).removeClass(current_container_class).addClass(previous_container_class);
return $(e.target).addClass(current_container_class);
},
drop: function(e, selected) {
var $current_container, $original_container, $previous_container;
if (_this.options.enableTrash) {
$original_container = $("." + original_container_class);
$current_container = $("." + current_container_class);
$previous_container = $("." + previous_container_class);
$selected = $(selected.helper);
$current_container.trigger("ss-trashed", $selected);
$selected.remove();
$original_container.trigger("ss-rearrange").removeClass(original_container_class);
$current_container.trigger("ss-rearrange").removeClass(current_container_class);
return $previous_container.trigger("ss-arrange").removeClass(previous_container_class);
}
}
});
}
};
Plugin.prototype.setTargetPosition = function() {
var $selected, $start_container, $target, attributes, child_positions, cutoff_end, cutoff_start, distance, dragged_class, options, parsed_children, placeholder_class, position_i, previous_container_class, selected_x, selected_y, shortest_distance, target_position, total_positions, x_dist, y_dist, _i;
options = this.options;
if (!options.enableTrash) {
dragged_class = options.draggedClass;
$selected = $("." + dragged_class);
$start_container = $selected.parent();
parsed_children = this.parsedChildren;
child_positions = this.getPositions(false);
total_positions = child_positions.length;
selected_x = $selected.offset().left - $start_container.offset().left + (this.globals.col_width / 2);
selected_y = $selected.offset().top - $start_container.offset().top + ($selected.height() / 2);
shortest_distance = 9999999;
target_position = 0;
if (total_positions > 1) {
cutoff_start = options.cutoffStart + 1 || 0;
cutoff_end = options.cutoffEnd || total_positions;
for (position_i = _i = cutoff_start; cutoff_start <= cutoff_end ? _i < cutoff_end : _i > cutoff_end; position_i = cutoff_start <= cutoff_end ? ++_i : --_i) {
attributes = child_positions[position_i];
if (attributes) {
y_dist = selected_x - attributes.left;
x_dist = selected_y - attributes.top;
if (y_dist > 0 && x_dist > 0) {
distance = Math.sqrt((x_dist * x_dist) + (y_dist * y_dist));
if (distance < shortest_distance) {
shortest_distance = distance;
target_position = position_i;
if (position_i === total_positions - 1) {
if (y_dist > parsed_children[position_i].height / 2) {
target_position++;
}
}
}
}
}
}
if (target_position === parsed_children.length) {
$target = parsed_children[target_position - 1].el;
$selected.insertAfter($target);
} else {
$target = parsed_children[target_position].el;
$selected.insertBefore($target);
}
} else {
if (total_positions === 1) {
attributes = child_positions[0];
if (attributes.left < selected_x) {
this.$container.append($selected);
} else {
this.$container.prepend($selected);
}
} else {
this.$container.append($selected);
}
}
this.arrange(true);
if ($start_container[0] !== $selected.parent()[0]) {
previous_container_class = options.previousContainerClass;
if ($("." + previous_container_class).data("plugin_shapeshift").options.enableCrossDrop == true) {
return $("." + previous_container_class).trigger("ss-rearrange");
} else {
return $("." + previous_container_class);
}
}
} else {
placeholder_class = this.options.placeholderClass;
return $("." + placeholder_class).remove();
}
};
Plugin.prototype.enableResize = function() {
var animation_speed, binding, resizing,
_this = this;
animation_speed = this.options.animationSpeed;
resizing = false;
binding = "resize." + this.identifier;
return $(window).on(binding, function() {
if (!resizing) {
resizing = true;
setTimeout((function() {
return _this.render();
}), animation_speed / 3);
setTimeout((function() {
return _this.render();
}), animation_speed / 3);
return setTimeout(function() {
resizing = false;
return _this.render();
}, animation_speed / 3);
}
});
};
Plugin.prototype.shuffle = function() {
var calculateShuffled;
calculateShuffled = function(container, activeClass) {
var shuffle;
shuffle = function(arr) {
var i, j, x;
j = void 0;
x = void 0;
i = arr.length;
while (i) {
j = parseInt(Math.random() * i);
x = arr[--i];
arr[i] = arr[j];
arr[j] = x;
}
return arr;
};
return container.each(function() {
var items;
items = container.find("." + activeClass).filter(":visible");
if (items.length) {
return container.html(shuffle(items));
} else {
return this;
}
});
};
if (!this.globals.dragging) {
calculateShuffled(this.$container, this.options.activeClass);
this.enableFeatures();
return this.$container.trigger("ss-rearrange");
}
};
Plugin.prototype.lowestCol = function(array, offset) {
var augmented_array, i, length, _i;
if (offset == null) {
offset = 0;
}
length = array.length;
augmented_array = [];
for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) {
augmented_array.push([array[i], i]);
}
augmented_array.sort(function(a, b) {
var ret;
ret = a[0] - b[0];
if (ret === 0) {
ret = a[1] - b[1];
}
return ret;
});
return augmented_array[offset][1];
};
Plugin.prototype.highestCol = function(array) {
return $.inArray(Math.max.apply(window, array), array);
};
Plugin.prototype.destroy = function() {
var $active_children, $container, active_class;
$container = this.$container;
$container.off("ss-arrange");
$container.off("ss-rearrange");
$container.off("ss-setTargetPosition");
$container.off("ss-destroy");
active_class = this.options.activeClass;
$active_children = $container.find("." + active_class);
if (this.options.enableDrag) {
$active_children.draggable('destroy');
}
if (this.options.enableCrossDrop) {
$container.droppable('destroy');
}
$active_children.removeClass(active_class);
return $container.removeClass(this.identifier);
};
return Plugin;
})();
return $.fn[pluginName] = function(options) {
return this.each(function() {
var bound_indentifier, old_class, _ref, _ref1;
old_class = (_ref = $(this).attr("class")) != null ? (_ref1 = _ref.match(/shapeshifted_container_\w+/)) != null ? _ref1[0] : void 0 : void 0;
if (old_class) {
bound_indentifier = "resize." + old_class;
$(window).off(bound_indentifier);
$(this).removeClass(old_class);
}
return $.data(this, "plugin_" + pluginName, new Plugin(this, options));
});
};
})(jQuery, window, document);
}).call(this);
</script>
<!-- jQuery.Shapeshift -->
<!-- CSS -->
<style>
.container {
border: 0px dashed #CCC;
position: relative;
}
.container > div {
background: #AAA;
position: absolute;
height: 100px;
width: 100px;
}
.container > .ss-placeholder-child {
background: transparent;
border: 0px dashed blue;
}
</style>
<!-- Javascript -->
<script>
$(document).ready(function() {
$(".container").shapeshift();
})
</script>
</head>
<body>
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</body>
</html>