mirror of https://github.com/asterisk/asterisk
demonstrate the capability of manager over http. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@16850 65c4cc65-6c06-0410-ace0-fbb531ad65f31.4
parent
46a1b7c73b
commit
bfba044b5f
@ -0,0 +1,91 @@
|
||||
Asynchronous Javascript Asterisk Manger (AJAM)
|
||||
==============================================
|
||||
|
||||
AJAM is a new technology which allows web browsers or other HTTP enabled
|
||||
applications and web pages to directly access the Asterisk Manger
|
||||
Interface (AMI) via HTTP. Setting up your server to process AJAM
|
||||
involves a few steps:
|
||||
|
||||
Setup the Asterisk HTTP server
|
||||
------------------------------
|
||||
|
||||
1) Uncomment the line "enabled=yes" in /etc/asterisk/http.conf to enable
|
||||
Asterisk's builtin micro HTTP server.
|
||||
|
||||
2) If you want Asterisk to actually deliver simple HTML pages, CSS,
|
||||
javascript, etc. you should uncomment "enablestatic=yes"
|
||||
|
||||
3) Adjust your "bindaddr" and "bindport" settings as appropriate for
|
||||
your desired accessibility
|
||||
|
||||
4) Adjust your "prefix" if appropriate, which must be the beginning of
|
||||
any URI on the server to match. The default is "asterisk" and the
|
||||
rest of these instructions assume that value.
|
||||
|
||||
Allow Manager Access via HTTP
|
||||
-----------------------------
|
||||
|
||||
1) Make sure you have both "enabled = yes" and "webenabled = yes" setup
|
||||
in /etc/asterisk/manager.conf
|
||||
|
||||
2) You may also use "httptimeout" to set a default timeout for HTTP
|
||||
connections.
|
||||
|
||||
3) Make sure you have a manager username/secret
|
||||
|
||||
Once those configurations are complete you can reload or restart
|
||||
Asterisk and you should be able to point your web browser to specific
|
||||
URI's which will allow you to access various web functions. A complete
|
||||
list can be found by typing "show http" at the Asterisk CLI.
|
||||
|
||||
examples:
|
||||
|
||||
http://localhost:8088/asterisk/manager?action=login&username=foo&secret=bar
|
||||
|
||||
This logs you into the manager interface's "HTML" view. Once you're
|
||||
logged in, Asterisk stores a cookie on your browser (valid for the
|
||||
length of httptimeout) which is used to connect to the same session.
|
||||
|
||||
http://localhost:8088/asterisk/rawman?action=status
|
||||
|
||||
Assuming you've already logged into manager, this URI will give you a
|
||||
"raw" manager output for the "status" command.
|
||||
|
||||
http://localhost:8088/asterisk/mxml?action=status
|
||||
|
||||
This will give you the same status view but represented as AJAX data,
|
||||
theoretically compatible with RICO (http://www.openrico.org).
|
||||
|
||||
http://localhost:8088/asterisk/static/ajamdemo.html
|
||||
|
||||
If you have enabled static content support and have done a make install,
|
||||
Asterisk will serve up a demo page which presents a live, but very
|
||||
basic, "astman" like interface. You can login with your username/secret
|
||||
for manager and have a basic view of channels as well as transfer and
|
||||
hangup calls. It's only tested in Firefox, but could probably be made
|
||||
to run in other browsers as well.
|
||||
|
||||
A sample library (astman.js) is included to help ease the creation of
|
||||
manager HTML interfaces.
|
||||
|
||||
Note that for the demo, there is no need for *any* external web server.
|
||||
|
||||
Integration with other web servers
|
||||
----------------------------------
|
||||
|
||||
Asterisk's micro HTTP server is *not* designed to replace a general
|
||||
purpose web server and it is intentionally created to provide only the
|
||||
minimal interfaces required. Even without the addition of an external
|
||||
web server, one can use Asterisk's interfaces to implement screen pops
|
||||
and similar tools pulling data from other web servers using iframes,
|
||||
div's etc. If you want to integrate CGI's, databases, PHP, etc. you
|
||||
will likely need to use a more traditional web server like Apache and
|
||||
link in your Asterisk micro HTTP server with something like this:
|
||||
|
||||
ProxyPass /asterisk http://localhost:8088/asterisk
|
||||
|
||||
This is a fairly new technology so I'd love to hear if it's useful for
|
||||
you!
|
||||
|
||||
Mark
|
||||
|
@ -0,0 +1,215 @@
|
||||
<script src="prototype.js"></script>
|
||||
<script src="astman.js"></script>
|
||||
<link href="astman.css" media="all" rel="Stylesheet" type="text/css" />
|
||||
|
||||
<script>
|
||||
var logins = new Object;
|
||||
var logoffs = new Object;
|
||||
var channels = new Object;
|
||||
var pongs = new Object;
|
||||
var loggedon = 0;
|
||||
var selectedchan = null;
|
||||
var hungupchan = "";
|
||||
var transferedchan = "";
|
||||
|
||||
var demo = new Object;
|
||||
|
||||
function loggedOn() {
|
||||
if (loggedon)
|
||||
return;
|
||||
loggedon = 1;
|
||||
updateButtons();
|
||||
$('statusbar').innerHTML = "<i>Retrieving channel status...</i>";
|
||||
astmanEngine.pollEvents();
|
||||
astmanEngine.sendRequest('action=status', demo.channels);
|
||||
}
|
||||
|
||||
function clearChannelList() {
|
||||
$('channellist').innerHTML = "<i class='light'>Not connected</i>";
|
||||
}
|
||||
|
||||
function loggedOff() {
|
||||
if (!loggedon)
|
||||
return;
|
||||
loggedon = 0;
|
||||
selectedchan = null;
|
||||
updateButtons();
|
||||
astmanEngine.channelClear();
|
||||
clearChannelList();
|
||||
}
|
||||
|
||||
function updateButtons()
|
||||
{
|
||||
if ($(selectedchan)) {
|
||||
$('transfer').disabled = 0;
|
||||
$('hangup').disabled = 0;
|
||||
} else {
|
||||
$('transfer').disabled = 1;
|
||||
$('hangup').disabled = 1;
|
||||
selectedchan = null;
|
||||
}
|
||||
if (loggedon) {
|
||||
$('logoff').disabled = 0;
|
||||
$('login').disabled = 1;
|
||||
$('refresh').disabled = 0;
|
||||
} else {
|
||||
$('logoff').disabled = 1;
|
||||
$('login').disabled = 0;
|
||||
$('refresh').disabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
demo.channelCallback = function(target) {
|
||||
selectedchan = target;
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
demo.channels = function(msgs) {
|
||||
resp = msgs[0].headers['response'];
|
||||
if (resp == "Success") {
|
||||
loggedOn();
|
||||
} else
|
||||
loggedOff();
|
||||
|
||||
for (i=1;i<msgs.length - 1;i++)
|
||||
astmanEngine.channelUpdate(msgs[i]);
|
||||
$('channellist').innerHTML = astmanEngine.channelTable(demo.channelCallback);
|
||||
$('statusbar').innerHTML = "Ready";
|
||||
}
|
||||
|
||||
demo.logins = function(msgs) {
|
||||
$('statusbar').innerHTML = msgs[0].headers['message'];
|
||||
resp = msgs[0].headers['response'];
|
||||
if (resp == "Success")
|
||||
loggedOn();
|
||||
else
|
||||
loggedOff();
|
||||
};
|
||||
|
||||
|
||||
demo.logoffs = function(msgs) {
|
||||
$('statusbar').innerHTML = msgs[0].headers['message'];
|
||||
loggedOff();
|
||||
};
|
||||
|
||||
demo.hungup = function(msgs) {
|
||||
$('statusbar').innerHTML = "Hungup " + hungupchan;
|
||||
}
|
||||
|
||||
demo.transferred = function(msgs) {
|
||||
$('statusbar').innerHTML = "Transferred " + transferredchan;
|
||||
}
|
||||
|
||||
function doHangup() {
|
||||
hungupchan = selectedchan;
|
||||
astmanEngine.sendRequest('action=hangup&channel=' + selectedchan, demo.hungup);
|
||||
}
|
||||
|
||||
function doStatus() {
|
||||
$('statusbar').innerHTML = "<i>Updating channel status...</i>";
|
||||
astmanEngine.channelClear();
|
||||
astmanEngine.sendRequest('action=status', demo.channels);
|
||||
}
|
||||
|
||||
function doLogin() {
|
||||
$('statusbar').innerHTML = "<i>Logging in...</i>";
|
||||
astmanEngine.sendRequest('action=login&username=' + $('username').value + "&secret=" + $('secret').value, demo.logins);
|
||||
}
|
||||
|
||||
function doTransfer() {
|
||||
var channel = astmanEngine.channelInfo(selectedchan);
|
||||
var exten = prompt("Enter new extension for " + selectedchan);
|
||||
var altchan;
|
||||
if (exten) {
|
||||
if (channel.link) {
|
||||
if (confirm("Transfer " + channel.link + " too?"))
|
||||
altchan = channel.link;
|
||||
}
|
||||
if (altchan) {
|
||||
transferredchan = selectedchan + " and " + altchan + " to " + exten;
|
||||
astmanEngine.sendRequest('action=redirect&channel=' + selectedchan + "&priority=1&extrachannel=" + altchan + "&exten=" + exten, demo.transferred);
|
||||
} else {
|
||||
transferredchan = selectedchan + " to " + exten;
|
||||
astmanEngine.sendRequest('action=redirect&channel=' + selectedchan + "&priority=1&exten=" + exten, demo.transferred);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function doLogoff() {
|
||||
$('statusbar').innerHTML = "<i>Logging off...</i>";
|
||||
astmanEngine.sendRequest('action=logoff', demo.logoffs);
|
||||
}
|
||||
|
||||
demo.pongs = function(msgs) {
|
||||
resp = msgs[0].headers['response'];
|
||||
if (resp == "Pong") {
|
||||
$('statusbar').innerHTML = "<i>Already connected...</i>";
|
||||
loggedOn();
|
||||
} else {
|
||||
$('statusbar').innerHTML = "<i>Please login...</i>";
|
||||
loggedOff();
|
||||
}
|
||||
}
|
||||
|
||||
demo.eventcb = function(msgs) {
|
||||
var x;
|
||||
if (loggedon) {
|
||||
for (i=1;i<msgs.length - 1;i++) {
|
||||
astmanEngine.channelUpdate(msgs[i]);
|
||||
}
|
||||
$('channellist').innerHTML = astmanEngine.channelTable(demo.channelCallback);
|
||||
astmanEngine.pollEvents();
|
||||
}
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
function localajaminit() {
|
||||
astmanEngine.setURL('../rawman');
|
||||
astmanEngine.setEventCallback(demo.eventcb);
|
||||
//astmanEngine.setDebug($('ditto'));
|
||||
clearChannelList();
|
||||
astmanEngine.sendRequest('action=ping', demo.pongs);
|
||||
}
|
||||
</script>
|
||||
|
||||
<title>Asterisk™ AJAM Demo</title>
|
||||
<body onload="localajaminit()">
|
||||
<table align="center" width=600>
|
||||
<tr valign="top"><td>
|
||||
<table align="left">
|
||||
<tr><td colspan="2"><h2>Asterisk™ AJAM Demo</h2></td>
|
||||
<tr><td>Username:</td><td><input id="username"></td></tr>
|
||||
<tr><td>Secret:</td><td><input type="password" id="secret"></td></tr>
|
||||
<tr><td colspan=2 align="center">
|
||||
<div id="statusbar">
|
||||
<span style="margin-left: 4px;font-weight:bold"> </span>
|
||||
</div>
|
||||
</td></tr>
|
||||
|
||||
<tr><td><input type="submit" id="login" value="Login" onClick="doLogin()"></td>
|
||||
<td><input type="submit" id="logoff" value="Logoff" disabled=1 onClick="doLogoff()"></td></tr>
|
||||
</table>
|
||||
</td><td valign='bottom'>
|
||||
<table>
|
||||
<div style="margin-left:10;margin-right:50;margin-top:10;margin-bottom:20">
|
||||
<i>This is a demo of the Asynchronous Javascript Asterisk Manager interface. You can login with a
|
||||
valid, appropriately permissioned manager username and secret.</i>
|
||||
</div>
|
||||
<tr>
|
||||
<td><input type="submit" onClick="doStatus()" id="refresh" value="Refresh"></td>
|
||||
<td><input type="submit" onClick="doTransfer()" id="transfer" value="Transfer..."></td>
|
||||
<td><input type="submit" onClick="doHangup()" id="hangup" value="Hangup"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
<tr><td colspan=2>
|
||||
<div id="channellist" class="chanlist">
|
||||
</div>
|
||||
</td></tr>
|
||||
<tr><td align="center" colspan=2>
|
||||
<font size=-1><i>
|
||||
Copyright (C) 2006 Digium, Inc. Asterisk and Digium are trademarks of Digium, Inc.
|
||||
</i></font>
|
||||
</td></tr>
|
||||
</table>
|
||||
</body>
|
@ -0,0 +1,34 @@
|
||||
.chanlist {
|
||||
border : 1px solid #1f669b;
|
||||
height : 150px;
|
||||
overflow : auto;
|
||||
background-color : #f1f1f1;
|
||||
width : 600;
|
||||
}
|
||||
|
||||
.chantable {
|
||||
border : 0px;
|
||||
background-color : #f1f1f1;
|
||||
width : 100%;
|
||||
}
|
||||
|
||||
.labels {
|
||||
background-color : #000000;
|
||||
color : #ffffff;
|
||||
}
|
||||
|
||||
.chanlisteven {
|
||||
background-color : #fff8e4;
|
||||
}
|
||||
|
||||
.chanlistodd {
|
||||
background-color : #f0f5ff;
|
||||
}
|
||||
|
||||
.chanlistselected {
|
||||
background-color : #ffb13d;
|
||||
}
|
||||
|
||||
.light {
|
||||
color : #717171;
|
||||
}
|
@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Asterisk -- An open source telephony toolkit.
|
||||
*
|
||||
* Javascript routines or accessing manager routines over HTTP.
|
||||
*
|
||||
* Copyright (C) 1999 - 2006, Digium, Inc.
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2. See the LICENSE file
|
||||
* at the top of the source tree.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function Astman() {
|
||||
var me = this;
|
||||
var channels = new Array;
|
||||
var lastselect;
|
||||
var selecttarget;
|
||||
this.setURL = function(url) {
|
||||
this.url = url;
|
||||
};
|
||||
this.setEventCallback = function(callback) {
|
||||
this.eventcallback = callback;
|
||||
};
|
||||
this.setDebug = function(debug) {
|
||||
this.debug = debug;
|
||||
};
|
||||
this.clickChannel = function(ev) {
|
||||
var target = ev.target;
|
||||
// XXX This is icky, we statically use astmanEngine to call the callback XXX
|
||||
if (me.selecttarget)
|
||||
me.restoreTarget(me.selecttarget);
|
||||
while(!target.id || !target.id.length)
|
||||
target=target.parentNode;
|
||||
me.selecttarget = target.id;
|
||||
target.className = "chanlistselected";
|
||||
me.chancallback(target.id);
|
||||
};
|
||||
this.restoreTarget = function(targetname) {
|
||||
var other;
|
||||
target = $(targetname);
|
||||
if (!target)
|
||||
return;
|
||||
if (target.previousSibling) {
|
||||
other = target.previousSibling.previousSibling.className;
|
||||
} else if (target.nextSibling) {
|
||||
other = target.nextSibling.nextSibling.className;
|
||||
}
|
||||
if (other) {
|
||||
if (other == "chanlisteven")
|
||||
target.className = "chanlistodd";
|
||||
else
|
||||
target.className = "chanlisteven";
|
||||
} else
|
||||
target.className = "chanlistodd";
|
||||
};
|
||||
this.channelUpdate = function(msg, channame) {
|
||||
var fields = new Array("callerid", "calleridname", "context", "extension", "priority", "account", "state", "link", "uniqueid" );
|
||||
|
||||
if (!channame || !channame.length)
|
||||
channame = msg.headers['channel'];
|
||||
|
||||
if (!channels[channame])
|
||||
channels[channame] = new Array();
|
||||
|
||||
if (msg.headers.event) {
|
||||
if (msg.headers.event == "Hangup") {
|
||||
delete channels[channame];
|
||||
} else if (msg.headers.event == "Link") {
|
||||
var chan1 = msg.headers.channel1;
|
||||
var chan2 = msg.headers.channel2;
|
||||
if (chan1 && channels[chan1])
|
||||
channels[chan1].link = chan2;
|
||||
if (chan2 && channels[chan2])
|
||||
channels[chan2].link = chan1;
|
||||
} else if (msg.headers.event == "Unlink") {
|
||||
var chan1 = msg.headers.channel1;
|
||||
var chan2 = msg.headers.channel2;
|
||||
if (chan1 && channels[chan1])
|
||||
delete channels[chan1].link;
|
||||
if (chan2 && channels[chan2])
|
||||
delete channels[chan2].link;
|
||||
} else if (msg.headers.event == "Rename") {
|
||||
var oldname = msg.headers.oldname;
|
||||
var newname = msg.headers.newname;
|
||||
if (oldname && channels[oldname]) {
|
||||
channels[newname] = channels[oldname];
|
||||
delete channels[oldname];
|
||||
}
|
||||
} else {
|
||||
channels[channame]['channel'] = channame;
|
||||
for (x=0;x<fields.length;x++) {
|
||||
if (msg.headers[fields[x]])
|
||||
channels[channame][fields[x]] = msg.headers[fields[x]];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
channels[channame]['channel'] = channame;
|
||||
for (x=0;x<fields.length;x++) {
|
||||
if (msg.headers[fields[x]])
|
||||
channels[channame][fields[x]] = msg.headers[fields[x]];
|
||||
}
|
||||
}
|
||||
};
|
||||
this.channelClear = function() {
|
||||
channels = new Array;
|
||||
}
|
||||
this.channelInfo = function(channame) {
|
||||
return channels[channame];
|
||||
};
|
||||
this.channelTable = function(callback) {
|
||||
var s, x;
|
||||
var cclass, count=0;
|
||||
var found = 0;
|
||||
var fieldlist = new Array("channel", "callerid", "calleridname", "context", "extension", "priority");
|
||||
|
||||
me.chancallback = callback;
|
||||
s = "<table class='chantable' align='center'>\n";
|
||||
s = s + "\t<tr class='labels' id='labels'><td>Channel</td><td>State</td><td>Caller</td><td>Location</td><td>Link</td></tr>";
|
||||
count=0;
|
||||
for (x in channels) {
|
||||
if (channels[x].channel) {
|
||||
if (count % 2)
|
||||
cclass = "chanlistodd";
|
||||
else
|
||||
cclass = "chanlisteven";
|
||||
if (me.selecttarget && (me.selecttarget == x))
|
||||
cclass = "chanlistselected";
|
||||
count++;
|
||||
s = s + "\t<tr class='" + cclass + "' id='" + channels[x].channel + "' onClick='astmanEngine.clickChannel(event)'>";
|
||||
s = s + "<td>" + channels[x].channel + "</td>";
|
||||
if (channels[x].state)
|
||||
s = s + "<td>" + channels[x].state + "</td>";
|
||||
else
|
||||
s = s + "<td><i class='light'>unknown</i></td>";
|
||||
if (channels[x].calleridname && channels[x].callerid && channels[x].calleridname != "<unknown>") {
|
||||
cid = channels[x].calleridname.escapeHTML() + " <" + channels[x].callerid.escapeHTML() + ">";
|
||||
} else if (channels[x].calleridname && (channels[x].calleridname != "<unknown>")) {
|
||||
cid = channels[x].calleridname.escapeHTML();
|
||||
} else if (channels[x].callerid) {
|
||||
cid = channels[x].callerid.escapeHTML();
|
||||
} else {
|
||||
cid = "<i class='light'>Unknown</i>";
|
||||
}
|
||||
s = s + "<td>" + cid + "</td>";
|
||||
if (channels[x].extension) {
|
||||
s = s + "<td>" + channels[x].extension + "@" + channels[x].context + ":" + channels[x].priority + "</td>";
|
||||
} else {
|
||||
s = s + "<td><i class='light'>None</i></td>";
|
||||
}
|
||||
if (channels[x].link) {
|
||||
s = s + "<td>" + channels[x].link + "</td>";
|
||||
} else {
|
||||
s = s + "<td><i class='light'>None</i></td>";
|
||||
}
|
||||
s = s + "</tr>\n";
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
s += "<tr><td colspan=" + fieldlist.length + "><i class='light'>No active channels</i></td>\n";
|
||||
s += "</table>\n";
|
||||
return s;
|
||||
};
|
||||
this.parseResponse = function(t, callback) {
|
||||
var msgs = new Array();
|
||||
var inmsg = 0;
|
||||
var msgnum = 0;
|
||||
var x,y;
|
||||
var s = t.responseText;
|
||||
var allheaders = s.split('\r\n');
|
||||
if (me.debug)
|
||||
me.debug.value = "\n";
|
||||
for (x=0;x<allheaders.length;x++) {
|
||||
if (allheaders[x].length) {
|
||||
var fields = allheaders[x].split(': ');
|
||||
if (!inmsg) {
|
||||
msgs[msgnum] = new Object();
|
||||
msgs[msgnum].headers = new Array();
|
||||
msgs[msgnum].names = new Array();
|
||||
y=0;
|
||||
}
|
||||
msgs[msgnum].headers[fields[0].toLowerCase()] = fields[1];
|
||||
msgs[msgnum].names[y++] = fields[0].toLowerCase();
|
||||
if (me.debug)
|
||||
me.debug.value = me.debug.value + "field " + fields[0] + "/" + fields[1] + "\n";
|
||||
inmsg=1;
|
||||
} else {
|
||||
if (inmsg) {
|
||||
if (me.debug)
|
||||
me.debug.value = me.debug.value + " new message\n";
|
||||
inmsg = 0;
|
||||
msgnum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (me.debug) {
|
||||
me.debug.value = me.debug.value + "msgnum is " + msgnum + " and array length is " + msgs.length + "\n";
|
||||
me.debug.value = me.debug.value + "length is " + msgs.length + "\n";
|
||||
var x, y;
|
||||
for (x=0;x<msgs.length;x++) {
|
||||
for (y=0;y<msgs[x].names.length;y++) {
|
||||
me.debug.value = me.debug.value + "msg "+ (x + 1) + "/" + msgs[x].names[y] + "/" + msgs[x].headers[msgs[x].names[y]] + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
callback(msgs);
|
||||
};
|
||||
this.managerResponse = function(t) {
|
||||
me.parseResponse(t, me.callback);
|
||||
};
|
||||
this.doEvents = function(msgs) {
|
||||
me.eventcallback(msgs);
|
||||
};
|
||||
this.eventResponse = function(t) {
|
||||
me.parseResponse(t, me.doEvents);
|
||||
};
|
||||
this.sendRequest = function(request, callback) {
|
||||
var tmp;
|
||||
var opt = {
|
||||
method: 'get',
|
||||
asynchronous: true,
|
||||
onSuccess: this.managerResponse,
|
||||
onFailure: function(t) {
|
||||
alert("Error: " + t.status + ": " + t.statusText);
|
||||
},
|
||||
};
|
||||
me.callback = callback;
|
||||
opt.parameters = request;
|
||||
tmp = new Ajax.Request(this.url, opt);
|
||||
};
|
||||
this.pollEvents = function() {
|
||||
var tmp;
|
||||
var opt = {
|
||||
method: 'get',
|
||||
asynchronous: true,
|
||||
onSuccess: this.eventResponse,
|
||||
onFailure: function(t) {
|
||||
alert("Event Error: " + t.status + ": " + t.statusText);
|
||||
},
|
||||
};
|
||||
opt.parameters="action=waitevent";
|
||||
tmp = new Ajax.Request(this.url, opt);
|
||||
};
|
||||
};
|
||||
|
||||
astmanEngine = new Astman();
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue