webgui/www/extras/yui-ext/docs/overview-summary-SelectionModel.js.html
JT Smith 4f68a0933c added YUI and YUI-ext
fixed the resizable text area with IE problem
fixed the ad space with IE problem
merged the 7.2.0 and 7.1.4 change logs
2006-11-07 23:15:57 +00:00

499 lines
27 KiB
HTML

<!doctype html public "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
<html>
<head>
<title>
Overview
</title>
<link rel ="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script>
function asd() {
parent.document.title="SelectionModel.js Overview";
}
</script>
</head>
<body bgcolor="white" onload="asd();" style="margin:15px;">
<center>
<h2>SelectionModel.js</h2>
</center>
<h4>Summary</h4>
<p>
</p>
<table border="1" cellpadding="3" cellspacing="0" width="100%">
<tr bgcolor="#CCCCFF" class="TableHeadingColor">
<td colspan="2" class="title-cell">
<b>Class Summary</b>
</td>
</tr>
<tr bgcolor="white" class="TableRowColor">
<td width="15%"><b><a href="YAHOO.ext.grid.DefaultSelectionModel.html">YAHOO.ext.grid.DefaultSelectionModel</a></b></td>
<td>The default SelectionModel used by <a href="YAHOO.ext.grid.Grid.html#">YAHOO.ext.grid.Grid</a>.</td>
</tr>
<tr bgcolor="white" class="TableRowColor">
<td width="15%"><b><a href="YAHOO.ext.grid.DisableSelectionModel.html">YAHOO.ext.grid.DisableSelectionModel</a></b></td>
<td>Extends <a href="YAHOO.ext.grid.DefaultSelectionModel.html#">YAHOO.ext.grid.DefaultSelectionModel</a> to disable row selection.</td>
</tr>
<tr bgcolor="white" class="TableRowColor">
<td width="15%"><b><a href="YAHOO.ext.grid.SingleSelectionModel.html">YAHOO.ext.grid.SingleSelectionModel</a></b></td>
<td>Extends <a href="YAHOO.ext.grid.DefaultSelectionModel.html#">YAHOO.ext.grid.DefaultSelectionModel</a> to allow only one row to be selected at a time.</td>
</tr>
</table>
<hr/>
<!-- ========== METHOD SUMMARY =========== -->
<!-- ========== END METHOD SUMMARY =========== -->
<pre class="sourceview"><span class="comment">/**
<span class="attrib">@class</span> The default SelectionModel used by {<span class="attrib">@link</span> YAHOO.ext.grid.Grid}.
It supports multiple selections and keyboard selection/navigation. &lt;br&gt;&lt;br&gt;
<span class="attrib">@constructor</span>
*/</span>
YAHOO.ext.grid.DefaultSelectionModel = <span class="reserved">function</span>(){
<span class="comment">/** <span class="attrib">@private</span> */</span>
<span class="reserved">this</span>.selectedRows = [];
<span class="comment">/** <span class="attrib">@private</span> */</span>
<span class="reserved">this</span>.selectedRowIds = [];
<span class="comment">/** <span class="attrib">@private</span> */</span>
<span class="reserved">this</span>.lastSelectedRow = null;
<span class="comment">/** Fires when a row is selected or deselected - fireDirect sig: (this, row, isSelected)
* <span class="attrib">@type</span> YAHOO.util.CustomEvent
* <span class="attrib">@deprecated</span>
*/</span>
<span class="reserved">this</span>.onRowSelect = new YAHOO.util.CustomEvent(<span class="literal">'SelectionTable.rowSelected'</span>);
<span class="comment">/** Fires when the selection changes on the Grid - fireDirect sig: (this, selectedRows[], selectedRowIds[])
* <span class="attrib">@type</span> YAHOO.util.CustomEvent
* <span class="attrib">@deprecated</span>
*/</span>
<span class="reserved">this</span>.onSelectionChange = new YAHOO.util.CustomEvent(<span class="literal">'SelectionTable.selectionChanged'</span>);
<span class="reserved">this</span>.events = {
<span class="literal">'selectionchange'</span> : <span class="reserved">this</span>.onSelectionChange,
<span class="literal">'rowselect'</span> : <span class="reserved">this</span>.onRowSelect
};
<span class="reserved">this</span>.locked = false;
};
YAHOO.ext.grid.DefaultSelectionModel.<span class="reserved">prototype</span> = {
<span class="comment">/** <span class="attrib">@ignore</span> Called by the grid automatically. Do not call directly. */</span>
init : <span class="reserved">function</span>(grid){
<span class="reserved">this</span>.grid = grid;
<span class="reserved">this</span>.initEvents();
},
lock : <span class="reserved">function</span>(){
<span class="reserved">this</span>.locked = true;
},
unlock : <span class="reserved">function</span>(){
<span class="reserved">this</span>.locked = false;
},
isLocked : <span class="reserved">function</span>(){
<span class="reserved">return</span> <span class="reserved">this</span>.locked;
},
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
initEvents : <span class="reserved">function</span>(){
<span class="reserved">if</span>(<span class="reserved">this</span>.grid.trackMouseOver){
<span class="reserved">this</span>.grid.addListener(<span class="literal">"mouseover"</span>, <span class="reserved">this</span>.handleOver, <span class="reserved">this</span>, true);
<span class="reserved">this</span>.grid.addListener(<span class="literal">"mouseout"</span>, <span class="reserved">this</span>.handleOut, <span class="reserved">this</span>, true);
}
<span class="reserved">this</span>.grid.addListener(<span class="literal">"rowclick"</span>, <span class="reserved">this</span>.rowClick, <span class="reserved">this</span>, true);
<span class="reserved">this</span>.grid.addListener(<span class="literal">"keydown"</span>, <span class="reserved">this</span>.keyDown, <span class="reserved">this</span>, true);
},
addListener : YAHOO.ext.grid.Grid.<span class="reserved">prototype</span>.addListener,
removeListener : YAHOO.ext.grid.Grid.<span class="reserved">prototype</span>.removeListener,
fireEvent : YAHOO.ext.grid.Grid.<span class="reserved">prototype</span>.fireEvent,
<span class="comment">/** <span class="attrib">@ignore</span> Syncs selectedRows with the correct row by looking it up by id.
Used after a sort moves data around. */</span>
syncSelectionsToIds : <span class="reserved">function</span>(){
<span class="reserved">if</span>(<span class="reserved">this</span>.getCount() &gt; 0){
var ids = <span class="reserved">this</span>.selectedRowIds.concat();
<span class="reserved">this</span>.clearSelections();
<span class="reserved">this</span>.selectRowsById(ids, true);
}
},
<span class="comment">/**
* Set the selected rows by their ID(s). IDs must match what is returned by the DataModel getRowId(index).
* <span class="attrib">@param</span> {String/Array} id The id(s) to select
* <span class="attrib">@param</span> {&lt;i&gt;Boolean&lt;/i&gt;} keepExisting (optional) True to retain existing selections
*/</span>
selectRowsById : <span class="reserved">function</span>(id, keepExisting){
var rows = <span class="reserved">this</span>.grid.getRowsById(id);
<span class="reserved">this</span>.selectRows(rows, keepExisting);
},
<span class="comment">/**
* Gets the number of selected rows.
* <span class="attrib">@return</span> {Number}
*/</span>
getCount : <span class="reserved">function</span>(){
<span class="reserved">return</span> <span class="reserved">this</span>.selectedRows.length;
},
<span class="comment">/**
* Selects the first row in the grid.
*/</span>
selectFirstRow : <span class="reserved">function</span>(){
<span class="reserved">for</span>(var j = 0; j &lt; <span class="reserved">this</span>.grid.rows.length; j++){
<span class="reserved">if</span>(<span class="reserved">this</span>.isSelectable(<span class="reserved">this</span>.grid.rows[j])){
<span class="reserved">this</span>.focusRow(<span class="reserved">this</span>.grid.rows[j]);
<span class="reserved">this</span>.setRowState(<span class="reserved">this</span>.grid.rows[j], true);
<span class="reserved">return</span>;
}
}
},
<span class="comment">/**
* Selects the row immediately following the last selected row.
* <span class="attrib">@param</span> {&lt;i&gt;Boolean&lt;/i&gt;} keepExisting (optional) True to retain existing selections
*/</span>
selectNext : <span class="reserved">function</span>(keepExisting){
<span class="reserved">if</span>(<span class="reserved">this</span>.lastSelectedRow){
<span class="reserved">for</span>(var j = (<span class="reserved">this</span>.lastSelectedRow.rowIndex+1); j &lt; <span class="reserved">this</span>.grid.rows.length; j++){
var row = <span class="reserved">this</span>.grid.rows[j];
<span class="reserved">if</span>(<span class="reserved">this</span>.isSelectable(row)){
<span class="reserved">this</span>.focusRow(row);
<span class="reserved">this</span>.setRowState(row, true, keepExisting);
<span class="reserved">return</span>;
}
}
}
},
<span class="comment">/**
* Selects the row that precedes the last selected row.
* <span class="attrib">@param</span> {&lt;i&gt;Boolean&lt;/i&gt;} keepExisting (optional) True to retain existing selections
*/</span>
selectPrevious : <span class="reserved">function</span>(keepExisting){
<span class="reserved">if</span>(<span class="reserved">this</span>.lastSelectedRow){
<span class="reserved">for</span>(var j = (<span class="reserved">this</span>.lastSelectedRow.rowIndex-1); j &gt;= 0; j--){
var row = <span class="reserved">this</span>.grid.rows[j];
<span class="reserved">if</span>(<span class="reserved">this</span>.isSelectable(row)){
<span class="reserved">this</span>.focusRow(row);
<span class="reserved">this</span>.setRowState(row, true, keepExisting);
<span class="reserved">return</span>;
}
}
}
},
<span class="comment">/**
* Returns the selected rows.
* <span class="attrib">@return</span> {Array} Array of DOM row elements
*/</span>
getSelectedRows : <span class="reserved">function</span>(){
<span class="reserved">return</span> <span class="reserved">this</span>.selectedRows;
},
<span class="comment">/**
* Returns the selected row ids.
* <span class="attrib">@return</span> {Array} Array of String ids
*/</span>
getSelectedRowIds : <span class="reserved">function</span>(){
<span class="reserved">return</span> <span class="reserved">this</span>.selectedRowIds;
},
<span class="comment">/**
* Clears all selections.
*/</span>
clearSelections : <span class="reserved">function</span>(){
<span class="reserved">if</span>(<span class="reserved">this</span>.isLocked()) <span class="reserved">return</span>;
var oldSelections = <span class="reserved">this</span>.selectedRows.concat();
<span class="reserved">for</span>(var j = 0; j &lt; oldSelections.length; j++){
<span class="reserved">this</span>.setRowState(oldSelections[j], false);
}
<span class="reserved">this</span>.selectedRows = [];
<span class="reserved">this</span>.selectedRowIds = [];
},
<span class="comment">/**
* Selects all rows.
*/</span>
selectAll : <span class="reserved">function</span>(){
<span class="reserved">if</span>(<span class="reserved">this</span>.isLocked()) <span class="reserved">return</span>;
<span class="reserved">for</span>(var j = 0; j &lt; <span class="reserved">this</span>.grid.rows.length; j++){
<span class="reserved">this</span>.setRowState(<span class="reserved">this</span>.grid.rows[j], true, true);
}
},
<span class="comment">/**
* Returns True if there is a selection.
* <span class="attrib">@return</span> {Boolean}
*/</span>
hasSelection : <span class="reserved">function</span>(){
<span class="reserved">return</span> <span class="reserved">this</span>.selectedRows.length &gt; 0;
},
<span class="comment">/**
* Returns True if the specified row is selected.
* <span class="attrib">@param</span> {HTMLElement} row The row to check
* <span class="attrib">@return</span> {Boolean}
*/</span>
isSelected : <span class="reserved">function</span>(row){
<span class="reserved">return</span> row &amp;&amp; (row.selected === true || row.getAttribute(<span class="literal">'selected'</span>) == <span class="literal">'true'</span>);
},
<span class="comment">/**
* Returns True if the specified row is selectable.
* <span class="attrib">@param</span> {HTMLElement} row The row to check
* <span class="attrib">@return</span> {Boolean}
*/</span>
isSelectable : <span class="reserved">function</span>(row){
<span class="reserved">return</span> row &amp;&amp; row.getAttribute(<span class="literal">'selectable'</span>) != <span class="literal">'false'</span>;
},
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
rowClick : <span class="reserved">function</span>(grid, rowIndex, e){
<span class="reserved">if</span>(<span class="reserved">this</span>.isLocked()) <span class="reserved">return</span>;
var row = grid.getRow(rowIndex);
<span class="reserved">if</span>(<span class="reserved">this</span>.isSelectable(row)){
<span class="reserved">if</span>(e.shiftKey &amp;&amp; <span class="reserved">this</span>.lastSelectedRow){
var lastIndex = <span class="reserved">this</span>.lastSelectedRow.rowIndex;
<span class="reserved">this</span>.selectRange(<span class="reserved">this</span>.lastSelectedRow, row, e.ctrlKey);
<span class="reserved">this</span>.lastSelectedRow = <span class="reserved">this</span>.grid.el.dom.rows[lastIndex];
}<span class="reserved">else</span>{
<span class="reserved">this</span>.focusRow(row);
var rowState = e.ctrlKey ? !<span class="reserved">this</span>.isSelected(row) : true;
<span class="reserved">this</span>.setRowState(row, rowState, e.hasModifier());
}
}
},
<span class="comment">/**
* Deprecated. Tries to focus the row and scroll it into view - Use grid.scrollTo or grid.getView().focusRow() instead.
* <span class="attrib">@deprecated</span>
* <span class="attrib">@param</span> {HTMLElement} row The row to focus
*/</span>
focusRow : <span class="reserved">function</span>(row){
<span class="reserved">this</span>.grid.view.focusRow(row);
},
<span class="comment">/**
* Selects a row.
* <span class="attrib">@param</span> {Number/HTMLElement} row The row or index of the row to select
* <span class="attrib">@param</span> {&lt;i&gt;Boolean&lt;/i&gt;} keepExisting (optional) True to retain existing selections
*/</span>
selectRow : <span class="reserved">function</span>(row, keepExisting){
<span class="reserved">this</span>.setRowState(<span class="reserved">this</span>.getRow(row), true, keepExisting);
},
<span class="comment">/**
* Selects multiple rows.
* <span class="attrib">@param</span> {Array} rows Array of the rows or indexes of the row to select
* <span class="attrib">@param</span> {&lt;i&gt;Boolean&lt;/i&gt;} keepExisting (optional) True to retain existing selections
*/</span>
selectRows : <span class="reserved">function</span>(rows, keepExisting){
<span class="reserved">if</span>(!keepExisting){
<span class="reserved">this</span>.clearSelections();
}
<span class="reserved">for</span>(var i = 0; i &lt; rows.length; i++){
<span class="reserved">this</span>.selectRow(rows[i], true);
}
},
<span class="comment">/**
* Deselects a row.
* <span class="attrib">@param</span> {Number/HTMLElement} row The row or index of the row to deselect
*/</span>
deselectRow : <span class="reserved">function</span>(row){
<span class="reserved">this</span>.setRowState(<span class="reserved">this</span>.getRow(row), false);
},
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
getRow : <span class="reserved">function</span>(row){
<span class="reserved">if</span>(typeof row == <span class="literal">'number'</span>){
row = <span class="reserved">this</span>.grid.rows[row];
}
<span class="reserved">return</span> row;
},
<span class="comment">/**
* Selects a range of rows. All rows in between startRow and endRow are also selected.
* <span class="attrib">@param</span> {Number/HTMLElement} startRow The row or index of the first row in the range
* <span class="attrib">@param</span> {Number/HTMLElement} endRow The row or index of the last row in the range
* <span class="attrib">@param</span> {&lt;i&gt;Boolean&lt;/i&gt;} keepExisting (optional) True to retain existing selections
*/</span>
selectRange : <span class="reserved">function</span>(startRow, endRow, keepExisting){
startRow = <span class="reserved">this</span>.getRow(startRow);
endRow = <span class="reserved">this</span>.getRow(endRow);
<span class="reserved">this</span>.setRangeState(startRow, endRow, true, keepExisting);
},
<span class="comment">/**
* Deselects a range of rows. All rows in between startRow and endRow are also deselected.
* <span class="attrib">@param</span> {Number/HTMLElement} startRow The row or index of the first row in the range
* <span class="attrib">@param</span> {Number/HTMLElement} endRow The row or index of the last row in the range
*/</span>
deselectRange : <span class="reserved">function</span>(startRow, endRow){
startRow = <span class="reserved">this</span>.getRow(startRow);
endRow = <span class="reserved">this</span>.getRow(endRow);
<span class="reserved">this</span>.setRangeState(startRow, endRow, false, true);
},
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
setRowStateFromChild : <span class="reserved">function</span>(childEl, selected, keepExisting){
var row = <span class="reserved">this</span>.grid.getRowFromChild(childEl);
<span class="reserved">this</span>.setRowState(row, selected, keepExisting);
},
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
setRangeState : <span class="reserved">function</span>(startRow, endRow, selected, keepExisting){
<span class="reserved">if</span>(<span class="reserved">this</span>.isLocked()) <span class="reserved">return</span>;
<span class="reserved">if</span>(!keepExisting){
<span class="reserved">this</span>.clearSelections();
}
var curRow = startRow;
<span class="reserved">while</span>(curRow.rowIndex != endRow.rowIndex){
<span class="reserved">this</span>.setRowState(curRow, selected, true);
curRow = (startRow.rowIndex &lt; endRow.rowIndex ?
<span class="reserved">this</span>.grid.getRowAfter(curRow) : <span class="reserved">this</span>.grid.getRowBefore(curRow))
}
<span class="reserved">this</span>.setRowState(endRow, selected, true);
},
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
setRowState : <span class="reserved">function</span>(row, selected, keepExisting){
<span class="reserved">if</span>(<span class="reserved">this</span>.isLocked()) <span class="reserved">return</span>;
<span class="reserved">if</span>(<span class="reserved">this</span>.isSelectable(row)){
<span class="reserved">if</span>(selected){
<span class="reserved">if</span>(!keepExisting){
<span class="reserved">this</span>.clearSelections();
}
<span class="reserved">this</span>.setRowClass(row, <span class="literal">'selected'</span>);
row.selected = true;
<span class="reserved">this</span>.selectedRows.push(row);
<span class="reserved">this</span>.selectedRowIds.push(<span class="reserved">this</span>.grid.dataModel.getRowId(row.rowIndex));
<span class="reserved">this</span>.lastSelectedRow = row;
}<span class="reserved">else</span>{
<span class="reserved">this</span>.setRowClass(row, <span class="literal">''</span>);
row.selected = false;
<span class="reserved">this</span>._removeSelected(row);
}
<span class="reserved">this</span>.fireEvent(<span class="literal">'rowselect'</span>, <span class="reserved">this</span>, row, selected);
<span class="reserved">this</span>.fireEvent(<span class="literal">'selectionchange'</span>, <span class="reserved">this</span>, <span class="reserved">this</span>.selectedRows, <span class="reserved">this</span>.selectedRowIds);
}
},
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
handleOver : <span class="reserved">function</span>(e){
var row = <span class="reserved">this</span>.grid.getRowFromChild(e.getTarget());
<span class="reserved">if</span>(<span class="reserved">this</span>.isSelectable(row) &amp;&amp; !<span class="reserved">this</span>.isSelected(row)){
<span class="reserved">this</span>.setRowClass(row, <span class="literal">'over'</span>);
}
},
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
handleOut : <span class="reserved">function</span>(e){
var row = <span class="reserved">this</span>.grid.getRowFromChild(e.getTarget());
<span class="reserved">if</span>(<span class="reserved">this</span>.isSelectable(row) &amp;&amp; !<span class="reserved">this</span>.isSelected(row)){
<span class="reserved">this</span>.setRowClass(row, <span class="literal">''</span>);
}
},
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
keyDown : <span class="reserved">function</span>(e){
<span class="reserved">if</span>(e.browserEvent.keyCode == e.DOWN){
<span class="reserved">this</span>.selectNext(e.shiftKey);
e.preventDefault();
}<span class="reserved">else</span> <span class="reserved">if</span>(e.browserEvent.keyCode == e.UP){
<span class="reserved">this</span>.selectPrevious(e.shiftKey);
e.preventDefault();
}
},
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
setRowClass : <span class="reserved">function</span>(row, cssClass){
<span class="reserved">if</span>(<span class="reserved">this</span>.isSelectable(row)){
<span class="reserved">if</span>(cssClass == <span class="literal">'selected'</span>){
YAHOO.util.Dom.removeClass(row, <span class="literal">'ygrid-row-over'</span>);
YAHOO.util.Dom.addClass(row, <span class="literal">'ygrid-row-selected'</span>);
}<span class="reserved">else</span> <span class="reserved">if</span>(cssClass == <span class="literal">'over'</span>){
YAHOO.util.Dom.removeClass(row, <span class="literal">'ygrid-row-selected'</span>);
YAHOO.util.Dom.addClass(row, <span class="literal">'ygrid-row-over'</span>);
}<span class="reserved">else</span> <span class="reserved">if</span>(cssClass == <span class="literal">''</span>){
YAHOO.util.Dom.removeClass(row, <span class="literal">'ygrid-row-selected'</span>);
YAHOO.util.Dom.removeClass(row, <span class="literal">'ygrid-row-over'</span>);
}
}
},
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
_removeSelected : <span class="reserved">function</span>(row){
var sr = <span class="reserved">this</span>.selectedRows;
<span class="reserved">for</span> (var i = 0; i &lt; sr.length; i++) {
<span class="reserved">if</span> (sr[i] === row){
<span class="reserved">this</span>.selectedRows.splice(i, 1);
<span class="reserved">this</span>.selectedRowIds.splice(i, 1);
<span class="reserved">return</span>;
}
}
}
};
<span class="comment">/**
<span class="attrib">@class</span> Extends {<span class="attrib">@link</span> YAHOO.ext.grid.DefaultSelectionModel} to allow only one row to be selected at a time. &lt;br&gt;&lt;br&gt;
<span class="attrib">@extends</span> YAHOO.ext.grid.DefaultSelectionModel
<span class="attrib">@constructor</span>
*/</span>
YAHOO.ext.grid.SingleSelectionModel = <span class="reserved">function</span>(){
YAHOO.ext.grid.SingleSelectionModel.superclass.constructor.call(<span class="reserved">this</span>);
};
YAHOO.extendX(YAHOO.ext.grid.SingleSelectionModel, YAHOO.ext.grid.DefaultSelectionModel);
<span class="comment">/** <span class="attrib">@ignore</span> */</span>
YAHOO.ext.grid.SingleSelectionModel.<span class="reserved">prototype</span>.setRowState = <span class="reserved">function</span>(row, selected){
YAHOO.ext.grid.SingleSelectionModel.superclass.setRowState.call(<span class="reserved">this</span>, row, selected, false);
};
<span class="comment">/**
<span class="attrib">@class</span> Extends {<span class="attrib">@link</span> YAHOO.ext.grid.DefaultSelectionModel} to disable row selection. &lt;br&gt;&lt;br&gt;
<span class="attrib">@extends</span> YAHOO.ext.grid.DefaultSelectionModel
<span class="attrib">@constructor</span>
*/</span>
YAHOO.ext.grid.DisableSelectionModel = <span class="reserved">function</span>(){
YAHOO.ext.grid.DisableSelectionModel.superclass.constructor.call(<span class="reserved">this</span>);
};
YAHOO.extendX(YAHOO.ext.grid.DisableSelectionModel, YAHOO.ext.grid.DefaultSelectionModel);
YAHOO.ext.grid.DisableSelectionModel.<span class="reserved">prototype</span>.initEvents = <span class="reserved">function</span>(){
};</pre>
<hr>
<hr>
<font size="-1">
</font>
<div class="jsdoc_ctime">Documentation generated by <a href="http://jsdoc.sourceforge.net/" target="_parent">JSDoc</a> on Sat Oct 14 06:07:10 2006</div>
</body>
</html>