فهرست منبع

Removing unused files, adding assetic files.

Julio Montoya 10 سال پیش
والد
کامیت
86b16a2774
34فایلهای تغییر یافته به همراه47 افزوده شده و 9160 حذف شده
  1. 0 1
      main/admin/course_list.php
  2. 0 46
      tests/xhprof/INSTALL.txt
  3. 0 22
      tests/xhprof/footer.php
  4. 0 12
      tests/xhprof/header.php
  5. 0 91
      tests/xhprof/xhprof_html/callgraph.php
  6. 0 82
      tests/xhprof/xhprof_html/css/xhprof.css
  7. 0 826
      tests/xhprof/xhprof_html/docs/index.html
  8. BIN
      tests/xhprof/xhprof_html/docs/sample-callgraph-image.jpg
  9. BIN
      tests/xhprof/xhprof_html/docs/sample-diff-report-flat-view.jpg
  10. BIN
      tests/xhprof/xhprof_html/docs/sample-diff-report-parent-child-view.jpg
  11. BIN
      tests/xhprof/xhprof_html/docs/sample-flat-view.jpg
  12. BIN
      tests/xhprof/xhprof_html/docs/sample-parent-child-view.jpg
  13. 0 90
      tests/xhprof/xhprof_html/index.php
  14. BIN
      tests/xhprof/xhprof_html/jquery/indicator.gif
  15. 0 3549
      tests/xhprof/xhprof_html/jquery/jquery-1.2.6.js
  16. 0 61
      tests/xhprof/xhprof_html/jquery/jquery.autocomplete.css
  17. 0 759
      tests/xhprof/xhprof_html/jquery/jquery.autocomplete.js
  18. 0 24
      tests/xhprof/xhprof_html/jquery/jquery.tooltip.css
  19. 0 294
      tests/xhprof/xhprof_html/jquery/jquery.tooltip.js
  20. 0 204
      tests/xhprof/xhprof_html/js/xhprof_report.js
  21. 0 32
      tests/xhprof/xhprof_html/typeahead.php
  22. 0 80
      tests/xhprof/xhprof_lib/display/typeahead_common.php
  23. 0 1499
      tests/xhprof/xhprof_lib/display/xhprof.php
  24. 0 476
      tests/xhprof/xhprof_lib/utils/callgraph_utils.php
  25. 0 865
      tests/xhprof/xhprof_lib/utils/xhprof_lib.php
  26. 0 147
      tests/xhprof/xhprof_lib/utils/xhprof_runs.php
  27. 4 0
      web/assetic/sonata_admin_css.css
  28. 13 0
      web/assetic/sonata_admin_js.js
  29. 0 0
      web/assetic/sonata_formatter_css.css
  30. 0 0
      web/assetic/sonata_formatter_js.js
  31. 4 0
      web/assetic/sonata_front_css.css
  32. 13 0
      web/assetic/sonata_front_js.js
  33. 3 0
      web/assetic/sonata_jqueryui_css.css
  34. 10 0
      web/assetic/sonata_jqueryui_js.js

+ 0 - 1
main/admin/course_list.php

@@ -12,7 +12,6 @@
 // Language files that need to be included.
 $language_file = array('admin', 'courses');
 $cidReset = true;
-require_once '../inc/global.inc.php';
 $this_section = SECTION_PLATFORM_ADMIN;
 
 api_protect_admin_script();

+ 0 - 46
tests/xhprof/INSTALL.txt

@@ -1,46 +0,0 @@
-Install XHProf
---------------
-
-To install XHProf, use the following commands as described on http://techportal.inviqa.com/2009/12/01/profiling-with-xhprof/:
-
-  apt-get install php5-common
-  pecl config-set preferred_state beta
-  pecl install xhprof
-
-If it complains because it can't find config.m4, you can still build the extension manually, using the following steps:
-
-  wget http://pecl.php.net/get/xhprof-0.9.2.tgz
-  tar xvf xhprof-0.9.2.tgz
-  cd ./xhprof-0.9.2/extension/
-  phpize
-  ./configure --with-php-config=/usr/local/bin/php-config
-  make
-  make install
-  make test
-
-In the ./configure line above, if you use Ubuntu, it is likely you php-config
-will have to be declared as /usr/bin/php-config. Check it with 
-"which php-config".
-
-Once you have XHProf installed, you should enable it. Open your php.ini or 
-/etc/php5/conf.d/xhprof.ini and type:
-
-  [xhprof]
-  extension=xhprof.so
-  xhprof.output_dir="/tmp"
-
-If you use PHP 5.4, you will need to download xhprof from Git:
-git clone git://github.com/facebook/xhprof.git
-and sudo, make, make install
-
-Combine with Chamilo
---------------------
-
-To enable XHProf on your Chamilo, add this to your VirtualHost configuration
-(assuming your Chamilo install is as /var/www/chamilo):
-
-  php_value auto_prepend_file /var/www/chamilo/tests/xhprof/header.php
-  php_value auto_append_file /var/www/chamilo/tests/xhprof/footer.php
-
-Also check /var/www/chamilo/tests/xhprof/footer.php to update the sprintf
-command to use the name of your host.

+ 0 - 22
tests/xhprof/footer.php

@@ -1,22 +0,0 @@
-<?php
-/**
- * Comes at the end of every script if loaded from php config
- * @package chamilo.profiling
- */
-/**
- * Init
- */
-if (extension_loaded('xhprof')) {
-    $profiler_namespace = 'chamilolms';  // namespace for your application
-    $xhprof_data = xhprof_disable();
-    $xhprof_runs = new XHProfRuns_Default();
-    $run_id = $xhprof_runs->save_run($xhprof_data, $profiler_namespace);
-
-    // url to the XHProf UI libraries (change the host name and path)
-    require_once __DIR__.'/../../main/inc/lib/main_api.lib.php';
-    $url = api_get_path(WEB_PATH);
-    $profiler_url = sprintf($url.'tests/xhprof/xhprof_html/index.php?run=%s&source=%s', $run_id, $profiler_namespace);
-    $xhprof =  '<br /><a class="btn btn-primary" href="'. $profiler_url .'" target="_blank">xhprof profiler output</a><br /><br />';
-    echo $xhprof;
-    error_log("xhprof runid: $run_id");
-}

+ 0 - 12
tests/xhprof/header.php

@@ -1,12 +0,0 @@
-<?php
-/**
- * @package chamilo.profiling
- */
-/**
- * Init
- */
-if (extension_loaded('xhprof')) {
-    include_once dirname(__FILE__).'/xhprof_lib/utils/xhprof_lib.php';
-    include_once dirname(__FILE__).'/xhprof_lib/utils/xhprof_runs.php';
-    xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
-}

+ 0 - 91
tests/xhprof/xhprof_html/callgraph.php

@@ -1,91 +0,0 @@
-<?php
-//  Copyright (c) 2009 Facebook
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-/**
- *
- * A callgraph generator for XHProf.
- *
- * * This file is part of the UI/reporting component,
- *   used for viewing results of XHProf runs from a
- *   browser.
- *
- * Modification History:
- *  02/15/2008 - cjiang  - The first version of callgraph visualizer
- *                         based on Graphviz's DOT tool.
- *
- * @author Changhao Jiang (cjiang@facebook.com)
- */
-
-// by default assume that xhprof_html & xhprof_lib directories
-// are at the same level.
-$GLOBALS['XHPROF_LIB_ROOT'] = dirname(__FILE__) . '/../xhprof_lib';
-
-include_once $GLOBALS['XHPROF_LIB_ROOT'].'/display/xhprof.php';
-
-ini_set('max_execution_time', 100);
-
-$params = array(// run id param
-                'run' => array(XHPROF_STRING_PARAM, ''),
-
-                // source/namespace/type of run
-                'source' => array(XHPROF_STRING_PARAM, 'xhprof'),
-
-                // the focus function, if it is set, only directly
-                // parents/children functions of it will be shown.
-                'func' => array(XHPROF_STRING_PARAM, ''),
-
-                // image type, can be 'jpg', 'gif', 'ps', 'png'
-                'type' => array(XHPROF_STRING_PARAM, 'png'),
-
-                // only functions whose exclusive time over the total time
-                // is larger than this threshold will be shown.
-                // default is 0.01.
-                'threshold' => array(XHPROF_FLOAT_PARAM, 0.01),
-
-                // whether to show critical_path
-                'critical' => array(XHPROF_BOOL_PARAM, true),
-
-                // first run in diff mode.
-                'run1' => array(XHPROF_STRING_PARAM, ''),
-
-                // second run in diff mode.
-                'run2' => array(XHPROF_STRING_PARAM, '')
-                );
-
-// pull values of these params, and create named globals for each param
-xhprof_param_init($params);
-
-// if invalid value specified for threshold, then use the default
-if ($threshold < 0 || $threshold > 1) {
-  $threshold = $params['threshold'][1];
-}
-
-// if invalid value specified for type, use the default
-if (!array_key_exists($type, $xhprof_legal_image_types)) {
-  $type = $params['type'][1]; // default image type.
-}
-
-$xhprof_runs_impl = new XHProfRuns_Default();
-
-if (!empty($run)) {
-  // single run call graph image generation
-  xhprof_render_image($xhprof_runs_impl, $run, $type,
-                      $threshold, $func, $source, $critical);
-} else {
-  // diff report call graph image generation
-  xhprof_render_diff_image($xhprof_runs_impl, $run1, $run2,
-                           $type, $threshold, $source);
-}

+ 0 - 82
tests/xhprof/xhprof_html/css/xhprof.css

@@ -1,82 +0,0 @@
-/*  Copyright (c) 2009 Facebook
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-td.sorted {
-  color:#0000FF;
-}
-
-td.vbar, th.vbar {
-  text-align: right;
-  border-left:
-  solid 1px #bdc7d8;
-}
-
-td.vbbar, th.vbar {
-  text-align: right;
-  border-left:
-  solid 1px #bdc7d8;
-  color:blue;
-}
-
-/* diff reports: display regressions in red */
-td.vrbar {
-  text-align: right;
-  border-left:solid 1px #bdc7d8;
-  color:red;
-}
-
-/* diff reports: display improvements in green */
-td.vgbar {
-  text-align: right;
-  border-left: solid 1px #bdc7d8;
-  color:green;
-}
-
-td.vwbar, th.vwbar {
-  text-align: right;
-  border-left: solid 1px white;
-}
-
-td.vwlbar, th.vwlbar {
-  text-align: left;
-  border-left: solid 1px white;
-}
-
-p.blue  {
-  color:blue
-}
-
-.bubble {
-  background-color:#C3D9FF
-}
-
-ul.xhprof_actions {
-  float: right;
-  padding-left: 16px;
-  list-style-image: none;
-  list-style-type: none;
-  margin:10px 10px 10px 3em;
-  position:relative;
-}
-
-ul.xhprof_actions li {
-  border-bottom:1px solid #D8DFEA;
-}
-
-ul.xhprof_actions li a:hover {
-  background:#3B5998 none repeat scroll 0 0;
-  color:#FFFFFF;
-}
-

+ 0 - 826
tests/xhprof/xhprof_html/docs/index.html

@@ -1,826 +0,0 @@
-<html>
-<title>
-XHProf Documentation (Draft)
-</title>
-<body>
-<h3>XHProf Documentation (Draft)</h3>
-
-<b>Contents</b>
-<ol>
-<li><a href="#introduction">Introduction</a></li>
-
-<li><a href="#overview">XHProf Overview</a></li>
-
-<li><a href="#installation">Installing the XHProf extension</a></li>
-
-<li><a href="#using_extension">Profiling using XHProf</a></li>
-
-<li><a href="#ui_setup">Setting up the XHProf UI</a></li>
-
-<li><a href="#production_notes">Notes on using XHProf in production</a></li>
-
-<li><a href="#sampling_mode">Lightweight Sampling Mode</a>
-
-<li><a href="#misc">Additional features</a></li>
-
-<li><a href="#dependencies">Dependencies</a></li>
-
-<li><a href="#credits">Acknowledgements</a></li>
-</ol>
-
-<ol>
-<li><a name="introduction"><h2>Introduction</h2></a>
-
-<p>XHProf is a hierarchical profiler for PHP.  It reports
-function-level call counts and <a href="#inclusive">inclusive</a> and
-<a href="#exclusive">exclusive</a> metrics such as wall (elapsed)
-time, CPU time and memory usage. A function's profile can be broken
-down by callers or callees. The raw data collection component is
-implemented in C as a PHP Zend extension called
-<code><b>xhprof</b></code>. XHProf has a simple HTML based user
-interface (written in PHP). The browser based UI for viewing profiler
-results makes it easy to view results or to share results with peers.
-A callgraph image view is also supported.
-
-<p>XHProf reports can often be helpful in understanding the structure
-of the code being executed. The hierarchical nature of the reports can
-be used to determine, for example, what chain of calls led to a
-particular function getting called.
-
-<p>XHProf supports ability to compare two runs (a.k.a. "diff" reports)
-or aggregate data from multiple runs. Diff and aggregate reports, much
-like single run reports, offer "flat" as well as "hierarchical" views
-of the profile.
-
-<p>XHProf is a light-weight instrumentation based profiler. During the
-data collection phase, it keeps track of call counts and inclusive
-metrics for arcs in the dynamic callgraph of a program. It computes
-exclusive metrics in the reporting/post processing phase. XHProf
-handles recursive functions by detecting cycles in the callgraph at
-data collection time itself and avoiding the cycles by giving unique
-depth qualified names for the recursive invocations.
-</p>
-
-<p>XHProf's light-weight nature and aggregation capabilities make it
-well suited for collecting "function-level" performance statistics
-from production environments. [See <a
-href="#production_notes">additional notes</a> for use in production.]
-
-<ul>
-<hr>
-
-<p>XHProfLive (not part of the open source kit), for example, is a
-system-wide performance monitoring system in use at Facebook that is
-built on top of XHProf.  XHProfLive continually gathers function-level
-profiler data from production tier by running a sample of page
-requests under XHProf. XHProfLive then aggregates the profile data
-corresponding to individual requests by various dimensions such a
-time, page type, and can help answer a variety of questions such as:
-What is the function-level profile for a specific page? How expensive
-is function "foo" across all pages, or on a specific page? What
-functions regressed most in the last hour/day/week? What is the
-historical trend for execution time of a page/function? and so on.
-
-<hr>
-</ul>
-
-
-<p>Originally developed at Facebook, XHProf was open sourced in Mar, 2009.</p>
-
-
-</ul>
-
-
-<li><a name="overview"><h2>XHProf Overview</h2></a>
-
-<p>XHProf provides:
-
-<ul>
-<li><b>Flat profile</b> (<a href="sample-flat-view.jpg" >screenshot</a>)
-
-<p>Provides function-level summary information such number of calls,
-inclusive/exclusive wall time, memory usage, and CPU time.
-
-<p><li><b>Hierarchical profile (Parent/Child View)</b>
-(<a href="sample-parent-child-view.jpg" >screenshot</a>)
-
-<p>For each function, it provides a breakdown of calls and times per
-parent (caller) & child (callee), such as:
-
-<ul>
-
-<li> what functions call a particular function and how many times?
-
-<li> what functions does a particular function call?
-
-<li> The total time spent under a function when called from a particular parent.
-
-</ul>
-
-<p><li><b>Diff Reports</b>
-
-<p>You may want to compare data from two XHProf runs for various
-reasons-- to figure out what's causing a regression between one
-version of the code base to another, to evaluate the performance
-improvement of a code change you are making, and so on.
-
-<p>A diff report takes two runs as input and provides both flat
-function-level diff information, and hierarchical information
-(breakdown of diff by parent/children functions) for each function.
-
-<p>The "flat" view (<a href="sample-diff-report-flat-view.jpg"
->sample screenshot</a>) in the diff report points out the top
-regressions & improvements.
-
-<p>Clicking on functions in the "flat" view of the diff report, leads
-to the "hierarchical" (or parent/child) diff view of a function (<a href="sample-diff-report-parent-child-view.jpg"
->sample screenshot</a>). We can get a
-breakdown of the diff by parent/children functions.
-
-
-<p><li><b>Callgraph View</b> (<a href="sample-callgraph-image.jpg"
->sample screenshot</a>)
-
-<p>The profile data can also be viewed as a callgraph. The callgraph
-view highlights the critical path of the program.
-
-
-<p><li><b>Memory Profile</b>
-
-<p>XHProf's memory profile mode helps track functions that
-allocate lots of memory.
-
-<p>It is worth clarifying that that XHProf doesn't strictly track each
-allocation/free operation.  Rather it uses a more simplistic
-scheme. It tracks the increase/decrease in the amount of memory
-allocated to PHP between each function's entry and exit. It also
-tracks increase/decrease in the amount of <b>peak</b> memory allocated to
-PHP for each function.
-
-<li>XHProf tracks <code>include, include_once, require and
-require_once</code> operations as if they were functions. The name of
-the file being included is used to generate the name for these <a
-href="#include_funcs">"fake" functions</a>.
-
-
-</ul>
-
-<a name="Terminology"></a><h2>Terminology</h2>
-<ol>
-
-<a name="inclusive"></a><li><b>Inclusive Time (or Subtree Time)</b>:
-Includes time spent in the function as well as in descendant functions
-called from a given function.
-
-<a name="exclusive"></a><li><b>Exclusive Time/Self Time</b>: Measures
-time spent in the function itself. Does not include time in descendant
-functions.
-
-<li><b>Wall Time</b>: a.k.a. Elapsed time or wall clock time.
-
-<li><b>CPU Time</b>: CPU time in user space + CPU time in kernel space
-
-</ol>
-<a name="Naming_convention_for_special_functions"></a><h2>Naming convention for special functions</h2>
-
-<ol>
-<p><li><code><b>main()</b></code>: a fictitious function that is at the root of the call graph.
-
-<a name="include_funcs"></a>
-<p><li><code><b>load::&lt;filename&gt;</b></code>
-and <code><b>run_init::&lt;filename&gt;</b></code>:
-
-<p>XHProf tracks PHP <code>include/require</code> operations as
-function calls.
-
-<p>For example, an <b>include "lib/common.php";</b> operation will
-result in two XHProf function entries:
-
-<ul>
-
-<li> <code><b>load::lib/common.php</b></code> - This represents the work done by the
-interpreter to compile/load the file. [Note: If you are using a PHP
-opcode cache like APC, then the compile only happens on a cache miss
-in APC.]
-
-<li> <code><b>run_init::lib/common.php</b></code> - This represents
-initialization code executed at the file scope as a result of the
-include operation.
-
-</ul>
-
-<p><li><code><b>foo@&lt;n&gt;</b></code>: Implies that this is a
-recursive invocation of <code>foo()</code>, where <code>&lt;n&gt;</code> represents
-the recursion depth. The recursion may be direct (such as due to
-<code>foo()</code> --&gt; <code>foo()</code>), or indirect (such as
-due to </code>foo()</code> --&gt; <code>goo()</code> --&gt; foo()).
-
-</ol>
-
-
-<a name="Limitations"></a><h2>Limitations</h2>
-
-<p>True hierarchical profilers keep track of a full call stack at
-every data gathering point, and are later able to answer questions
-like: what was the cost of the 3rd invokation of foo()? or what was
-the cost of bar() when the call stack looked like
-a()-&gt;b()-&gt;bar()?
-
-</p>
-
-<p>XHProf keeps track of only 1-level of calling context and is
-therefore only able to answer questions about a function looking
-either 1-level up or 1-level down. It turns out that in practice this
-is sufficient for most use cases.
-</p>
-
-<p>To make this more concrete, take for instance the following
-example.
-</p>
-
-<pre>
-Say you have:
- 1 call from a() --&gt; c()
- 1 call from b() --&gt; c()
- 50 calls from c() --&gt; d()
-</pre>
-
-<p>While XHProf can tell you that d() was called from c() 50 times, it
-cannot tell you how many of those calls were triggered due to a()
-vs. b(). [We could speculate that perhaps 25 were due to a() and 25
-due to b(), but that's not necessarily true.]
-</p>
-
-<p>In practice however, this isn't a very big limitation.
-</p>
-
-<li><a name="installation"><h2>Installing the XHProf Extension</h2></a>
-
-<p> The extension lives in the "extension/" sub-directory.
-
-<ul><hr>
-
-<p><b>Note:</b> A windows port hasn't been implemented yet. We have
-tested <code>xhprof</code> on <b>Linux/FreeBSD</b> so far. 
-
-<p>Version 0.9.2 and above of XHProf is also expected to work on <b>Mac
-OS</b>. [We have tested on Mac OS 10.5.]
-
-<p><b>Note:</b> XHProf uses the RDTSC instruction (time stamp counter)
-to implement a really low overhead timer for elapsed time. So at the
-moment <code>xhprof</code> only works on <b>x86</b> architecture.
-Also, since RDTSC values may not be synchronized across CPUs,
-<code>xhprof</code> binds the program to a single CPU during the
-profiling period.
-
-<p>XHProf's RDTSC based timer functionality doesn't work correctly if
-<b>SpeedStep</b> technology is turned on. This technology is available on
-some Intel processors. [Note: Mac desktops and laptops typically have
-SpeedStep turned on by default. To use XHProf, you'll need to disable
-SpeedStep.]
-
-<hr></ul>
-
-<p> The steps
-below should work for Linux/Unix environments.
-
-
-<pre>
-% cd &lt;xhprof_source_directory&gt;/extension/
-% phpize
-% ./configure --with-php-config=&lt;path to php-config&gt;
-% make
-% make install
-% make test
-</pre>
-
-
-<p><a name="ini_file"></a><b>php.ini file</b>: You can update your
-php.ini file to automatically load your extension.  Add the following
-to your php.ini file.
-
-<pre>
-[xhprof]
-extension=xhprof.so
-;
-; directory used by default implementation of the iXHProfRuns
-; interface (namely, the XHProfRuns_Default class) for storing
-; XHProf runs.
-;
-xhprof.output_dir=&lt;directory_for_storing_xhprof_runs&gt;
-</pre>
-
-
-<li><a name="using_extension"><h2>Profiling using XHProf</h2></a>
-
-<p>Test generating raw profiler data using a sample test program like:
-
-<ul>
-<p><b>foo.php</b>
-<pre>
-&lt;?php
-
-function bar($x) {
-  if ($x > 0) {
-    bar($x - 1);
-  }
-}
-
-function foo() {
-  for ($idx = 0; $idx < 2; $idx++) {
-    bar($idx);
-    $x = strlen("abc");
-  }
-}
-
-// start profiling
-<b>xhprof_enable();</b>
-
-// run program
-foo();
-
-// stop profiler
-<b>$xhprof_data = xhprof_disable();</b>
-
-// display raw xhprof data for the profiler run
-print_r($xhprof_data);
-</pre>
-</ul>
-
-<p><b>Run the above test program:</b>
-
-<pre>
-% php -dextension=xhprof.so foo.php
-</pre>
-
-<p><b>You should get an output like:</b>
-
-<pre>
-Array
-(
-    [foo==>bar] => Array
-        (
-            [ct] => 2         # 2 calls to bar() from foo()
-            [wt] => 27        # inclusive time in bar() when called from foo()
-        )
-
-    [foo==>strlen] => Array
-        (
-            [ct] => 2
-            [wt] => 2
-        )
-
-    [bar==>bar@1] => Array    # a recursive call to bar()
-        (
-            [ct] => 1
-            [wt] => 2
-        )
-
-    [main()==>foo] => Array
-        (
-            [ct] => 1
-            [wt] => 74
-        )
-
-    [main()==>xhprof_disable] => Array
-        (
-            [ct] => 1
-            [wt] => 0
-        )
-
-    [main()] => Array         # fake symbol representing root
-        (
-            [ct] => 1
-            [wt] => 83
-        )
-
-)
-</pre>
-
-<p><b>Note:</b> The raw data only contains "inclusive" metrics. For
-example, the wall time metric in the raw data represents inclusive
-time in microsecs.  Exclusive times for any function are computed
-during the analysis/reporting phase.
-
-<p><b>Note:</b> By default only call counts & elapsed time is profiled.
-You can optionally also profile CPU time and/or memory usage. Replace,
-
-<ul><pre>
-<b>xhprof_enable();</b>
-</pre></ul>
-in the above program with, for example:
-<ul><pre>
-<b>xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY)</b>;
-</pre></ul>
-
-<p><b>You should now get an output like:</b>
-
-<pre>
-Array
-(
-    [foo==>bar] => Array
-        (
-            [ct] => 2        # number of calls to bar() from foo()
-            [wt] => 37       # time in bar() when called from foo()
-            [cpu] => 0       # cpu time in bar() when called from foo()
-            [mu] => 2208     # change in PHP memory usage in bar() when called from foo()
-            [pmu] => 0       # change in PHP peak memory usage in bar() when called from foo()
-        )
-
-    [foo==>strlen] => Array
-        (
-            [ct] => 2
-            [wt] => 3
-            [cpu] => 0
-            [mu] => 624
-            [pmu] => 0
-        )
-
-    [bar==>bar@1] => Array
-        (
-            [ct] => 1
-            [wt] => 2
-            [cpu] => 0
-            [mu] => 856
-            [pmu] => 0
-        )
-
-    [main()==>foo] => Array
-        (
-            [ct] => 1
-            [wt] => 104
-            [cpu] => 0
-            [mu] => 4168
-            [pmu] => 0
-        )
-
-    [main()==>xhprof_disable] => Array
-        (
-            [ct] => 1
-            [wt] => 1
-            [cpu] => 0
-            [mu] => 344
-            [pmu] => 0
-        )
-
-    [main()] => Array
-        (
-            [ct] => 1
-            [wt] => 139
-            [cpu] => 0
-            [mu] => 5936
-            [pmu] => 0
-        )
-
-)
-</pre>
-
-<p><b>Skipping builtin functions during profiling</b>
-
-<p>By default PHP builtin functions (such as <code>strlen</code>) are
-profiled. If you do not want to profile builtin functions (to either
-reduce the overhead of profiling further or size of generated raw
-data), you can use the <code><b>XHPROF_FLAGS_NO_BUILTINS</b></code>
-flag as in for example:
-
-<ul><pre>
-// do not profile builtin functions
-<b>xhprof_enable(XHPROF_FLAGS_NO_BUILTINS)</b>;
-</pre></ul>
-
-
-<p><b>Ignoring specific functions during profiling (0.9.2 or higher)</b>
-
-<p>Starting with release 0.9.2 of xhprof, you can tell XHProf to
-ignore a specified list of functions during profiling. This allows you
-to ignore, for example, functions used for indirect function calls
-such as <code>call_user_func</code> and
-<code>call_user_func_array</code>. These intermediate functions
-unnecessarily complicate the call hierarchy and make the XHProf
-reports harder to interpret since they muddle the parent-child
-relationship for functions called indirectly.
-
-<p> To specify the list of functions to be ignored during profiling
-use the 2nd (optional) argument to <code>xhprof_enable</code>.
-For example,
-
-<pre>
-<ul><pre>
-<b>
-// elapsed time profiling; ignore call_user_func* during profiling
-xhprof_enable(0,
-             array('ignored_functions' =>  array('call_user_func',
-                                                 'call_user_func_array')));
-</b>
-or,
-<b>
-// elapsed time + memory profiling; ignore call_user_func* during profiling
-xhprof_enable(XHPROF_FLAGS_MEMORY,
-              array('ignored_functions' =>  array('call_user_func',
-                                                  'call_user_func_array')));
-</b>
-</pre></ul>
-
-
-</li>
-
-<li><a name="ui_setup"><h2>Setting up XHProf UI</h2></a>
-
-
-<ol>
-
-<li><b>PHP source structure</b>
-<p>The XHProf UI is implemented in PHP. The code resides in two
-subdirectories, <code>xhprof_html/</code> and <code>xhprof_lib/</code>.
-
-<p>The <code>xhprof_html</code> directory contains the 3 top-level PHP pages.
-
-<ul>
-<li><code>index.php</code>: For viewing a single run or diff report.
-<li><code>callgraph.php</code>: For viewing a callgraph of a XHProf run as an image.
-<li><code>typeahead.php</code>: Used implicitly for the function typeahead form
-on a XHProf report.
-</ul>
-
-<p>The <code>xhprof_lib</code> directory contains supporting code for
-display as well as analysis (computing flat profile info, computing
-diffs, aggregating data from multiple runs, etc.).
-
-<li><p><b>Web server config: </b> You'll need to make sure that the
-<code>xhprof_html/</code> directory is accessible from your web server, and that
-your web server is setup to serve PHP scripts.
-
-<li><p><b>Managing XHProf Runs</b>
-
-<p>Clients have flexibility in how they save the XHProf raw data
-obtained from an XHProf run. The XHProf UI layer exposes an interface
-iXHProfRuns (see xhprof_lib/utils/xhprof_runs.php) that clients can
-implement. This allows the clients to tell the UI layer how to fetch
-the data corresponding to a XHProf run.
-
-<p>The XHProf UI libaries come with a default file based
-implementation of the iXHProfRuns interface, namely
-"XHProfRuns_Default" (also in xhprof_lib/utils/xhprof_runs.php).
-This default implementation stores runs in the directory specified by
-<a href="#ini_file"><b>xhprof.output_dir</b></a> INI parameter.
-
-<p>A XHProf run must be uniquely identified by a namespace and a run
-id.
-
-
-
-<p><b>a) Saving XHProf data persistently</b>:
-
-<p>Assuming you are using the default implementation
-<code><b>XHProfRuns_Default</b></code> of the
-<code><b>iXHProfRuns</b></code> interface, a typical XHProf run
-followed by the save step might look something like:
-
-
-<pre>
-// start profiling
-xhprof_enable();
-
-// run program
-....
-
-// stop profiler
-$xhprof_data = xhprof_disable();
-
-//
-// Saving the XHProf run
-// using the default implementation of iXHProfRuns.
-//
-include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php";
-include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php";
-
-$xhprof_runs = new <b>XHProfRuns_Default()</b>;
-
-// Save the run under a namespace "xhprof_foo".
-//
-// **NOTE**:
-// By default save_run() will automatically generate a unique
-// run id for you. [You can override that behavior by passing
-// a run id (optional arg) to the save_run() method instead.]
-//
-<b>$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_foo");</b>
-
-echo "---------------\n".
-     "Assuming you have set up the http based UI for \n".
-     "XHProf at some address, you can view run at \n".
-     "http://&lt;xhprof-ui-address&gt;/index.php?run=$run_id&source=xhprof_foo\n".
-     "---------------\n";
-
-</pre>
-
-<p>The above should save the run as a file in the directory specified
-by the <code><b>xhprof.output_dir</b></code> INI parameter. The file's
-name might be something like
-<b><code>49bafaa3a3f66.xhprof_foo</code></b>; the two parts being the
-run id ("49bafaa3a3f66") and the namespace ("xhprof_foo"). [If you
-want to create/assign run ids yourself (such as a database sequence
-number, or a timestamp), you can explicitly pass in the run id to the
-<code>save_run</code> method.
-
-
-<p><b>b) Using your own implementation of iXHProfRuns</b>
-
-<p> If you decide you want your XHProf runs to be stored differently
-(either in a compressed format, in an alternate place such as DB,
-etc.)  database, you'll need to implement a class that implements the
-iXHProfRuns() interface.
-
-<p> You'll also need to modify the 3 main PHP entry pages (index.php,
-callgraph.php, typeahead.php) in the "xhprof_html/" directory to use
-the new class instead of the default class <code>XHProfRuns_Default</code>.
-Change this line in the 3 files.
-
-<pre>
-$xhprof_runs_impl = new XHProfRuns_Default();
-</pre>
-
-<p>You'll also need to "include" the file that implements your class in
-the above files.
-
-
-<li><p><b>Accessing runs from UI</b>
-
-<p><b>a) Viewing a Single Run Report</b>
-
-<p>To view the report for run id say &lt;run_id&gt; and namespace
-&lt;namespace&gt; use a URL of the form:
-
-<p><code>
-http://&lt;xhprof-ui-address&gt;/index.php?run=&lt;run_id&gt;&source=&lt;namespace&gt;
-</code>
-
-<p>For example,
-<p><code>
-http://&lt;xhprof-ui-address&gt;/index.php?run=49bafaa3a3f66&source=xhprof_foo
-</code>
-
-
-<p><b>b) Viewing a Diff Report</b>
-
-<p>To view the report for run ids say &lt;run_id1&gt; and
-&lt;run_id2&gt; in namespace &lt;namespace&gt; use a URL of the form:
-
-<p><code>
-http://&lt;xhprof-ui-address&gt;/index.php?<b>run1=&lt;run_id1&gt;&run2=&lt;run_id2&gt;</b>&source=&lt;namespace&gt;
-</code>
-
-<p><b>c) Aggregate Report</b>
-
-<p>You can also specify a set of run ids for which you want an aggregated view/report.
-
-<p>Say you have three XHProf runs with ids 1, 2 & 3 in namespace
-"benchmark".  To view an aggregate report of these runs:
-
-<ul><p><code>
-http://&lt;xhprof-ui-address&gt;/index.php?<b>run=1,2,3</b>&source=benchmark
-</code></p></ul>
-
-<p><b>Weighted aggregations</b>: Further suppose that the above three runs
-correspond to three types of programs p1.php, p2.php and p3.php that
-typically occur in a mix of 20%, 30%, 50% respectively. To view an
-aggregate report that corresponds to a weighted average of these runs
-using:
-
-<ul><p><code>
-http://&lt;xhprof-ui-address&gt;/index.php?<b>run=1,2,3&wts=20,30,50</b>&source=benchmark
-</code></p></ul>
-
-
-</ol>
-
-<li><a name="production_notes"><h2>Notes on using XHProf in production</h2></a>
-
-<p>Some observations/guidelines. Your mileage may vary:
-
-<ul>
-
-<li>CPU timer (getrusage) on Linux has high overheads. It is also
-coarse grained (millisec accuracy rather than microsec level) to be
-useful at function level. Therefore, the skew in reported numbers
-when using XHPROF_FLAGS_CPU mode tends to be higher.
-
-<p>We recommend using elapsed time + memory profiling mode in
-production. [Note: The additional overhead of memory profiling
-mode is really low.]
-
-<p><ul><pre><b>
-  // elapsed time profiling (default) + memory profiling
-  xhprof_enable(XHPROF_FLAGS_MEMORY);
-</b></pre>
-</ul></p>
-
-
-<li>Profiling a random sample of pages/requests works well in capturing
-data that is representative of your production workload.
-
-<p>To profile say 1/10000 of your requests, instrument the beginning of
-your request processing with something along the lines of:
-
-<p><ul><pre><code>
- if (mt_rand(1, 10000) == 1) {
-   xhprof_enable(XHPROF_FLAGS_MEMORY);
-   $xhprof_on = true;
- }
-</code></pre></ul></p>
-
-<p>At the end of the request (or in a request shutdown function), you might
-then do something like:
-
-<p><ul><pre><code>
- if ($xhprof_on) {
-   // stop profiler
-   $xhprof_data = xhprof_disable();
-
-   // save $xhprof_data somewhere (say a central DB)
-   ...
- }
-</code></pre></ul></p>
-
-<p> You can then rollup/aggregate these individual profiles by time
-(e.g., 5 minutely/hourly/daily basis), page/request type,or other
-dimensions using <a href="#xhprof_aggregate_runs"><code><b>xhprof_aggregate_runs()</b></code></a>.
-
-</ul>
-
-
-<li><a name="sampling_mode"><h2>Lightweight Sampling Mode</h2></a>
-
-<p>The xhprof extension also provides a very light weight <b>sampling
-mode</b>. The sampling interval is 0.1 secs. Samples record the full
-function call stack. The sampling mode can be useful if an extremely
-low overhead means of doing performance monitoring and diagnostics is
-desired.
-
-<p> The relevant functions exposed by the extension for using the
-sampling mode are <code><b>xhprof_sample_enable()</b></code> and
-<code><b>xhprof_sample_disable()</b></code>.
-
-
-<p>[<b>TBD</b>: more detailed documentation on sampling mode.]
-
-
-<li><a name="misc"><h2>Additional Features</h2></a></li>
-
-<p>The <code><b>xhprof_lib/utils/xhprof_lib.php</b></code> file contains
-additional library functions that can be used for manipulating/
-aggregating XHProf runs.
-
-<p>For example:
-
-<ul>
-
-<a name="xhprof_aggregate_runs"></a>
-<p><li><code><b>xhprof_aggregate_runs()</b></code>:
-can be used to aggregate multiple XHProf runs into a single run. This
-can be helpful for building a system-wide "function-level" performance
-monitoring tool using XHProf. [For example, you might to roll up
-XHProf runs sampled from production periodically to generate hourly,
-daily, reports.]
-
-<p><li><code><b>xhprof_prune_run()</b></code>: Aggregating large number of
-XHProf runs (especially if they correspond to different types of
-programs) can result in the callgraph size becoming too large. You can
-use <code>xhprof_prune_run</code> function to prune the callgraph data
-by editing out subtrees that account for a very small portion of the
-total time.
-
-</ul>
-
-
-<ol>
-
-</ol>
-
-<li><a name="dependencies"><h2>Dependencies</h2></a></li>
-
-<ul>
-<li><b>JQuery Javascript</b>: For tooltips and function name
-typeahead, we make use of JQuery's javascript libraries. JQuery is
-available under both a MIT and GPL licencse
-(http://docs.jquery.com/Licensing). The relevant JQuery code, used by
-XHProf, is in the <code>xhprof_html/jquery</code> subdirectory.
-
-<li><b>dot (image generation utility):</b> The callgraph image
-visualization ([View Callgraph]) feature relies on the presence of
-Graphviz "dot" utility in your path. "dot" is a utility to
-draw/generate an image for a directed graph.
-
-</ul>
-<li><a name="credits"><h2>Acknowledgements</h2></a>
-
-<p>The HTML-based navigational interface for browsing profiler results
-is inspired by that of a similar tool that exists for Oracle's stored
-procedure language, PL/SQL. But that's where the similarity ends; the
-internals of the profiler itself are quite different.
-
-</li>
-
-</ol>
-
-</body>
-</html>

BIN
tests/xhprof/xhprof_html/docs/sample-callgraph-image.jpg


BIN
tests/xhprof/xhprof_html/docs/sample-diff-report-flat-view.jpg


BIN
tests/xhprof/xhprof_html/docs/sample-diff-report-parent-child-view.jpg


BIN
tests/xhprof/xhprof_html/docs/sample-flat-view.jpg


BIN
tests/xhprof/xhprof_html/docs/sample-parent-child-view.jpg


+ 0 - 90
tests/xhprof/xhprof_html/index.php

@@ -1,90 +0,0 @@
-<?php
-//  Copyright (c) 2009 Facebook
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-//
-// XHProf: A Hierarchical Profiler for PHP
-//
-// XHProf has two components:
-//
-//  * This module is the UI/reporting component, used
-//    for viewing results of XHProf runs from a browser.
-//
-//  * Data collection component: This is implemented
-//    as a PHP extension (XHProf).
-//
-//
-//
-// @author(s)  Kannan Muthukkaruppan
-//             Changhao Jiang
-//
-
-// by default assume that xhprof_html & xhprof_lib directories
-// are at the same level.
-$GLOBALS['XHPROF_LIB_ROOT'] = dirname(__FILE__) . '/../xhprof_lib';
-
-include_once $GLOBALS['XHPROF_LIB_ROOT'].'/display/xhprof.php';
-
-// param name, its type, and default value
-$params = array('run'        => array(XHPROF_STRING_PARAM, ''),
-                'wts'        => array(XHPROF_STRING_PARAM, ''),
-                'symbol'     => array(XHPROF_STRING_PARAM, ''),
-                'sort'       => array(XHPROF_STRING_PARAM, 'wt'), // wall time
-                'run1'       => array(XHPROF_STRING_PARAM, ''),
-                'run2'       => array(XHPROF_STRING_PARAM, ''),
-                'source'     => array(XHPROF_STRING_PARAM, 'xhprof'),
-                'all'        => array(XHPROF_UINT_PARAM, 0),
-                );
-
-// pull values of these params, and create named globals for each param
-xhprof_param_init($params);
-
-/* reset params to be a array of variable names to values
-   by the end of this page, param should only contain values that need
-   to be preserved for the next page. unset all unwanted keys in $params.
- */
-foreach ($params as $k => $v) {
-  $params[$k] = $$k;
-
-  // unset key from params that are using default values. So URLs aren't
-  // ridiculously long.
-  if ($params[$k] == $v[1]) {
-    unset($params[$k]);
-  }
-}
-
-echo "<html>";
-
-echo "<head><title>XHProf: Hierarchical Profiler Report</title>";
-xhprof_include_js_css();
-echo "</head>";
-
-echo "<body>";
-
-$vbar  = ' class="vbar"';
-$vwbar = ' class="vwbar"';
-$vwlbar = ' class="vwlbar"';
-$vbbar = ' class="vbbar"';
-$vrbar = ' class="vrbar"';
-$vgbar = ' class="vgbar"';
-
-$xhprof_runs_impl = new XHProfRuns_Default();
-
-displayXHProfReport($xhprof_runs_impl, $params, $source, $run, $wts,
-                    $symbol, $sort, $run1, $run2);
-
-
-echo "</body>";
-echo "</html>";

BIN
tests/xhprof/xhprof_html/jquery/indicator.gif


+ 0 - 3549
tests/xhprof/xhprof_html/jquery/jquery-1.2.6.js

@@ -1,3549 +0,0 @@
-(function(){
-/*
- * jQuery 1.2.6 - New Wave Javascript
- *
- * Copyright (c) 2008 John Resig (jquery.com)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * $Date: 2009/03/17 18:35:18 $
- * $Rev: 5685 $
- */
-
-// Map over jQuery in case of overwrite
-var _jQuery = window.jQuery,
-// Map over the $ in case of overwrite
-	_$ = window.$;
-
-var jQuery = window.jQuery = window.$ = function( selector, context ) {
-	// The jQuery object is actually just the init constructor 'enhanced'
-	return new jQuery.fn.init( selector, context );
-};
-
-// A simple way to check for HTML strings or ID strings
-// (both of which we optimize for)
-var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
-
-// Is it a simple selector
-	isSimple = /^.[^:#\[\.]*$/,
-
-// Will speed up references to undefined, and allows munging its name.
-	undefined;
-
-jQuery.fn = jQuery.prototype = {
-	init: function( selector, context ) {
-		// Make sure that a selection was provided
-		selector = selector || document;
-
-		// Handle $(DOMElement)
-		if ( selector.nodeType ) {
-			this[0] = selector;
-			this.length = 1;
-			return this;
-		}
-		// Handle HTML strings
-		if ( typeof selector == "string" ) {
-			// Are we dealing with HTML string or an ID?
-			var match = quickExpr.exec( selector );
-
-			// Verify a match, and that no context was specified for #id
-			if ( match && (match[1] || !context) ) {
-
-				// HANDLE: $(html) -> $(array)
-				if ( match[1] )
-					selector = jQuery.clean( [ match[1] ], context );
-
-				// HANDLE: $("#id")
-				else {
-					var elem = document.getElementById( match[3] );
-
-					// Make sure an element was located
-					if ( elem ){
-						// Handle the case where IE and Opera return items
-						// by name instead of ID
-						if ( elem.id != match[3] )
-							return jQuery().find( selector );
-
-						// Otherwise, we inject the element directly into the jQuery object
-						return jQuery( elem );
-					}
-					selector = [];
-				}
-
-			// HANDLE: $(expr, [context])
-			// (which is just equivalent to: $(content).find(expr)
-			} else
-				return jQuery( context ).find( selector );
-
-		// HANDLE: $(function)
-		// Shortcut for document ready
-		} else if ( jQuery.isFunction( selector ) )
-			return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
-
-		return this.setArray(jQuery.makeArray(selector));
-	},
-
-	// The current version of jQuery being used
-	jquery: "1.2.6",
-
-	// The number of elements contained in the matched element set
-	size: function() {
-		return this.length;
-	},
-
-	// The number of elements contained in the matched element set
-	length: 0,
-
-	// Get the Nth element in the matched element set OR
-	// Get the whole matched element set as a clean array
-	get: function( num ) {
-		return num == undefined ?
-
-			// Return a 'clean' array
-			jQuery.makeArray( this ) :
-
-			// Return just the object
-			this[ num ];
-	},
-
-	// Take an array of elements and push it onto the stack
-	// (returning the new matched element set)
-	pushStack: function( elems ) {
-		// Build a new jQuery matched element set
-		var ret = jQuery( elems );
-
-		// Add the old object onto the stack (as a reference)
-		ret.prevObject = this;
-
-		// Return the newly-formed element set
-		return ret;
-	},
-
-	// Force the current matched set of elements to become
-	// the specified array of elements (destroying the stack in the process)
-	// You should use pushStack() in order to do this, but maintain the stack
-	setArray: function( elems ) {
-		// Resetting the length to 0, then using the native Array push
-		// is a super-fast way to populate an object with array-like properties
-		this.length = 0;
-		Array.prototype.push.apply( this, elems );
-
-		return this;
-	},
-
-	// Execute a callback for every element in the matched set.
-	// (You can seed the arguments with an array of args, but this is
-	// only used internally.)
-	each: function( callback, args ) {
-		return jQuery.each( this, callback, args );
-	},
-
-	// Determine the position of an element within
-	// the matched set of elements
-	index: function( elem ) {
-		var ret = -1;
-
-		// Locate the position of the desired element
-		return jQuery.inArray(
-			// If it receives a jQuery object, the first element is used
-			elem && elem.jquery ? elem[0] : elem
-		, this );
-	},
-
-	attr: function( name, value, type ) {
-		var options = name;
-
-		// Look for the case where we're accessing a style value
-		if ( name.constructor == String )
-			if ( value === undefined )
-				return this[0] && jQuery[ type || "attr" ]( this[0], name );
-
-			else {
-				options = {};
-				options[ name ] = value;
-			}
-
-		// Check to see if we're setting style values
-		return this.each(function(i){
-			// Set all the styles
-			for ( name in options )
-				jQuery.attr(
-					type ?
-						this.style :
-						this,
-					name, jQuery.prop( this, options[ name ], type, i, name )
-				);
-		});
-	},
-
-	css: function( key, value ) {
-		// ignore negative width and height values
-		if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
-			value = undefined;
-		return this.attr( key, value, "curCSS" );
-	},
-
-	text: function( text ) {
-		if ( typeof text != "object" && text != null )
-			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
-
-		var ret = "";
-
-		jQuery.each( text || this, function(){
-			jQuery.each( this.childNodes, function(){
-				if ( this.nodeType != 8 )
-					ret += this.nodeType != 1 ?
-						this.nodeValue :
-						jQuery.fn.text( [ this ] );
-			});
-		});
-
-		return ret;
-	},
-
-	wrapAll: function( html ) {
-		if ( this[0] )
-			// The elements to wrap the target around
-			jQuery( html, this[0].ownerDocument )
-				.clone()
-				.insertBefore( this[0] )
-				.map(function(){
-					var elem = this;
-
-					while ( elem.firstChild )
-						elem = elem.firstChild;
-
-					return elem;
-				})
-				.append(this);
-
-		return this;
-	},
-
-	wrapInner: function( html ) {
-		return this.each(function(){
-			jQuery( this ).contents().wrapAll( html );
-		});
-	},
-
-	wrap: function( html ) {
-		return this.each(function(){
-			jQuery( this ).wrapAll( html );
-		});
-	},
-
-	append: function() {
-		return this.domManip(arguments, true, false, function(elem){
-			if (this.nodeType == 1)
-				this.appendChild( elem );
-		});
-	},
-
-	prepend: function() {
-		return this.domManip(arguments, true, true, function(elem){
-			if (this.nodeType == 1)
-				this.insertBefore( elem, this.firstChild );
-		});
-	},
-
-	before: function() {
-		return this.domManip(arguments, false, false, function(elem){
-			this.parentNode.insertBefore( elem, this );
-		});
-	},
-
-	after: function() {
-		return this.domManip(arguments, false, true, function(elem){
-			this.parentNode.insertBefore( elem, this.nextSibling );
-		});
-	},
-
-	end: function() {
-		return this.prevObject || jQuery( [] );
-	},
-
-	find: function( selector ) {
-		var elems = jQuery.map(this, function(elem){
-			return jQuery.find( selector, elem );
-		});
-
-		return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
-			jQuery.unique( elems ) :
-			elems );
-	},
-
-	clone: function( events ) {
-		// Do the clone
-		var ret = this.map(function(){
-			if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
-				// IE copies events bound via attachEvent when
-				// using cloneNode. Calling detachEvent on the
-				// clone will also remove the events from the orignal
-				// In order to get around this, we use innerHTML.
-				// Unfortunately, this means some modifications to
-				// attributes in IE that are actually only stored
-				// as properties will not be copied (such as the
-				// the name attribute on an input).
-				var clone = this.cloneNode(true),
-					container = document.createElement("div");
-				container.appendChild(clone);
-				return jQuery.clean([container.innerHTML])[0];
-			} else
-				return this.cloneNode(true);
-		});
-
-		// Need to set the expando to null on the cloned set if it exists
-		// removeData doesn't work here, IE removes it from the original as well
-		// this is primarily for IE but the data expando shouldn't be copied over in any browser
-		var clone = ret.find("*").andSelf().each(function(){
-			if ( this[ expando ] != undefined )
-				this[ expando ] = null;
-		});
-
-		// Copy the events from the original to the clone
-		if ( events === true )
-			this.find("*").andSelf().each(function(i){
-				if (this.nodeType == 3)
-					return;
-				var events = jQuery.data( this, "events" );
-
-				for ( var type in events )
-					for ( var handler in events[ type ] )
-						jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
-			});
-
-		// Return the cloned set
-		return ret;
-	},
-
-	filter: function( selector ) {
-		return this.pushStack(
-			jQuery.isFunction( selector ) &&
-			jQuery.grep(this, function(elem, i){
-				return selector.call( elem, i );
-			}) ||
-
-			jQuery.multiFilter( selector, this ) );
-	},
-
-	not: function( selector ) {
-		if ( selector.constructor == String )
-			// test special case where just one selector is passed in
-			if ( isSimple.test( selector ) )
-				return this.pushStack( jQuery.multiFilter( selector, this, true ) );
-			else
-				selector = jQuery.multiFilter( selector, this );
-
-		var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
-		return this.filter(function() {
-			return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
-		});
-	},
-
-	add: function( selector ) {
-		return this.pushStack( jQuery.unique( jQuery.merge(
-			this.get(),
-			typeof selector == 'string' ?
-				jQuery( selector ) :
-				jQuery.makeArray( selector )
-		)));
-	},
-
-	is: function( selector ) {
-		return !!selector && jQuery.multiFilter( selector, this ).length > 0;
-	},
-
-	hasClass: function( selector ) {
-		return this.is( "." + selector );
-	},
-
-	val: function( value ) {
-		if ( value == undefined ) {
-
-			if ( this.length ) {
-				var elem = this[0];
-
-				// We need to handle select boxes special
-				if ( jQuery.nodeName( elem, "select" ) ) {
-					var index = elem.selectedIndex,
-						values = [],
-						options = elem.options,
-						one = elem.type == "select-one";
-
-					// Nothing was selected
-					if ( index < 0 )
-						return null;
-
-					// Loop through all the selected options
-					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
-						var option = options[ i ];
-
-						if ( option.selected ) {
-							// Get the specifc value for the option
-							value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
-
-							// We don't need an array for one selects
-							if ( one )
-								return value;
-
-							// Multi-Selects return an array
-							values.push( value );
-						}
-					}
-
-					return values;
-
-				// Everything else, we just grab the value
-				} else
-					return (this[0].value || "").replace(/\r/g, "");
-
-			}
-
-			return undefined;
-		}
-
-		if( value.constructor == Number )
-			value += '';
-
-		return this.each(function(){
-			if ( this.nodeType != 1 )
-				return;
-
-			if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
-				this.checked = (jQuery.inArray(this.value, value) >= 0 ||
-					jQuery.inArray(this.name, value) >= 0);
-
-			else if ( jQuery.nodeName( this, "select" ) ) {
-				var values = jQuery.makeArray(value);
-
-				jQuery( "option", this ).each(function(){
-					this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
-						jQuery.inArray( this.text, values ) >= 0);
-				});
-
-				if ( !values.length )
-					this.selectedIndex = -1;
-
-			} else
-				this.value = value;
-		});
-	},
-
-	html: function( value ) {
-		return value == undefined ?
-			(this[0] ?
-				this[0].innerHTML :
-				null) :
-			this.empty().append( value );
-	},
-
-	replaceWith: function( value ) {
-		return this.after( value ).remove();
-	},
-
-	eq: function( i ) {
-		return this.slice( i, i + 1 );
-	},
-
-	slice: function() {
-		return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
-	},
-
-	map: function( callback ) {
-		return this.pushStack( jQuery.map(this, function(elem, i){
-			return callback.call( elem, i, elem );
-		}));
-	},
-
-	andSelf: function() {
-		return this.add( this.prevObject );
-	},
-
-	data: function( key, value ){
-		var parts = key.split(".");
-		parts[1] = parts[1] ? "." + parts[1] : "";
-
-		if ( value === undefined ) {
-			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
-
-			if ( data === undefined && this.length )
-				data = jQuery.data( this[0], key );
-
-			return data === undefined && parts[1] ?
-				this.data( parts[0] ) :
-				data;
-		} else
-			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
-				jQuery.data( this, key, value );
-			});
-	},
-
-	removeData: function( key ){
-		return this.each(function(){
-			jQuery.removeData( this, key );
-		});
-	},
-
-	domManip: function( args, table, reverse, callback ) {
-		var clone = this.length > 1, elems;
-
-		return this.each(function(){
-			if ( !elems ) {
-				elems = jQuery.clean( args, this.ownerDocument );
-
-				if ( reverse )
-					elems.reverse();
-			}
-
-			var obj = this;
-
-			if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
-				obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
-
-			var scripts = jQuery( [] );
-
-			jQuery.each(elems, function(){
-				var elem = clone ?
-					jQuery( this ).clone( true )[0] :
-					this;
-
-				// execute all scripts after the elements have been injected
-				if ( jQuery.nodeName( elem, "script" ) )
-					scripts = scripts.add( elem );
-				else {
-					// Remove any inner scripts for later evaluation
-					if ( elem.nodeType == 1 )
-						scripts = scripts.add( jQuery( "script", elem ).remove() );
-
-					// Inject the elements into the document
-					callback.call( obj, elem );
-				}
-			});
-
-			scripts.each( evalScript );
-		});
-	}
-};
-
-// Give the init function the jQuery prototype for later instantiation
-jQuery.fn.init.prototype = jQuery.fn;
-
-function evalScript( i, elem ) {
-	if ( elem.src )
-		jQuery.ajax({
-			url: elem.src,
-			async: false,
-			dataType: "script"
-		});
-
-	else
-		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
-
-	if ( elem.parentNode )
-		elem.parentNode.removeChild( elem );
-}
-
-function now(){
-	return +new Date;
-}
-
-jQuery.extend = jQuery.fn.extend = function() {
-	// copy reference to target object
-	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
-
-	// Handle a deep copy situation
-	if ( target.constructor == Boolean ) {
-		deep = target;
-		target = arguments[1] || {};
-		// skip the boolean and the target
-		i = 2;
-	}
-
-	// Handle case when target is a string or something (possible in deep copy)
-	if ( typeof target != "object" && typeof target != "function" )
-		target = {};
-
-	// extend jQuery itself if only one argument is passed
-	if ( length == i ) {
-		target = this;
-		--i;
-	}
-
-	for ( ; i < length; i++ )
-		// Only deal with non-null/undefined values
-		if ( (options = arguments[ i ]) != null )
-			// Extend the base object
-			for ( var name in options ) {
-				var src = target[ name ], copy = options[ name ];
-
-				// Prevent never-ending loop
-				if ( target === copy )
-					continue;
-
-				// Recurse if we're merging object values
-				if ( deep && copy && typeof copy == "object" && !copy.nodeType )
-					target[ name ] = jQuery.extend( deep, 
-						// Never move original objects, clone them
-						src || ( copy.length != null ? [ ] : { } )
-					, copy );
-
-				// Don't bring in undefined values
-				else if ( copy !== undefined )
-					target[ name ] = copy;
-
-			}
-
-	// Return the modified object
-	return target;
-};
-
-var expando = "jQuery" + now(), uuid = 0, windowData = {},
-	// exclude the following css properties to add px
-	exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
-	// cache defaultView
-	defaultView = document.defaultView || {};
-
-jQuery.extend({
-	noConflict: function( deep ) {
-		window.$ = _$;
-
-		if ( deep )
-			window.jQuery = _jQuery;
-
-		return jQuery;
-	},
-
-	// See test/unit/core.js for details concerning this function.
-	isFunction: function( fn ) {
-		return !!fn && typeof fn != "string" && !fn.nodeName &&
-			fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
-	},
-
-	// check if an element is in a (or is an) XML document
-	isXMLDoc: function( elem ) {
-		return elem.documentElement && !elem.body ||
-			elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
-	},
-
-	// Evalulates a script in a global context
-	globalEval: function( data ) {
-		data = jQuery.trim( data );
-
-		if ( data ) {
-			// Inspired by code by Andrea Giammarchi
-			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
-			var head = document.getElementsByTagName("head")[0] || document.documentElement,
-				script = document.createElement("script");
-
-			script.type = "text/javascript";
-			if ( jQuery.browser.msie )
-				script.text = data;
-			else
-				script.appendChild( document.createTextNode( data ) );
-
-			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
-			// This arises when a base node is used (#2709).
-			head.insertBefore( script, head.firstChild );
-			head.removeChild( script );
-		}
-	},
-
-	nodeName: function( elem, name ) {
-		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
-	},
-
-	cache: {},
-
-	data: function( elem, name, data ) {
-		elem = elem == window ?
-			windowData :
-			elem;
-
-		var id = elem[ expando ];
-
-		// Compute a unique ID for the element
-		if ( !id )
-			id = elem[ expando ] = ++uuid;
-
-		// Only generate the data cache if we're
-		// trying to access or manipulate it
-		if ( name && !jQuery.cache[ id ] )
-			jQuery.cache[ id ] = {};
-
-		// Prevent overriding the named cache with undefined values
-		if ( data !== undefined )
-			jQuery.cache[ id ][ name ] = data;
-
-		// Return the named cache data, or the ID for the element
-		return name ?
-			jQuery.cache[ id ][ name ] :
-			id;
-	},
-
-	removeData: function( elem, name ) {
-		elem = elem == window ?
-			windowData :
-			elem;
-
-		var id = elem[ expando ];
-
-		// If we want to remove a specific section of the element's data
-		if ( name ) {
-			if ( jQuery.cache[ id ] ) {
-				// Remove the section of cache data
-				delete jQuery.cache[ id ][ name ];
-
-				// If we've removed all the data, remove the element's cache
-				name = "";
-
-				for ( name in jQuery.cache[ id ] )
-					break;
-
-				if ( !name )
-					jQuery.removeData( elem );
-			}
-
-		// Otherwise, we want to remove all of the element's data
-		} else {
-			// Clean up the element expando
-			try {
-				delete elem[ expando ];
-			} catch(e){
-				// IE has trouble directly removing the expando
-				// but it's ok with using removeAttribute
-				if ( elem.removeAttribute )
-					elem.removeAttribute( expando );
-			}
-
-			// Completely remove the data cache
-			delete jQuery.cache[ id ];
-		}
-	},
-
-	// args is for internal usage only
-	each: function( object, callback, args ) {
-		var name, i = 0, length = object.length;
-
-		if ( args ) {
-			if ( length == undefined ) {
-				for ( name in object )
-					if ( callback.apply( object[ name ], args ) === false )
-						break;
-			} else
-				for ( ; i < length; )
-					if ( callback.apply( object[ i++ ], args ) === false )
-						break;
-
-		// A special, fast, case for the most common use of each
-		} else {
-			if ( length == undefined ) {
-				for ( name in object )
-					if ( callback.call( object[ name ], name, object[ name ] ) === false )
-						break;
-			} else
-				for ( var value = object[0];
-					i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
-		}
-
-		return object;
-	},
-
-	prop: function( elem, value, type, i, name ) {
-		// Handle executable functions
-		if ( jQuery.isFunction( value ) )
-			value = value.call( elem, i );
-
-		// Handle passing in a number to a CSS property
-		return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
-			value + "px" :
-			value;
-	},
-
-	className: {
-		// internal only, use addClass("class")
-		add: function( elem, classNames ) {
-			jQuery.each((classNames || "").split(/\s+/), function(i, className){
-				if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
-					elem.className += (elem.className ? " " : "") + className;
-			});
-		},
-
-		// internal only, use removeClass("class")
-		remove: function( elem, classNames ) {
-			if (elem.nodeType == 1)
-				elem.className = classNames != undefined ?
-					jQuery.grep(elem.className.split(/\s+/), function(className){
-						return !jQuery.className.has( classNames, className );
-					}).join(" ") :
-					"";
-		},
-
-		// internal only, use hasClass("class")
-		has: function( elem, className ) {
-			return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
-		}
-	},
-
-	// A method for quickly swapping in/out CSS properties to get correct calculations
-	swap: function( elem, options, callback ) {
-		var old = {};
-		// Remember the old values, and insert the new ones
-		for ( var name in options ) {
-			old[ name ] = elem.style[ name ];
-			elem.style[ name ] = options[ name ];
-		}
-
-		callback.call( elem );
-
-		// Revert the old values
-		for ( var name in options )
-			elem.style[ name ] = old[ name ];
-	},
-
-	css: function( elem, name, force ) {
-		if ( name == "width" || name == "height" ) {
-			var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
-
-			function getWH() {
-				val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
-				var padding = 0, border = 0;
-				jQuery.each( which, function() {
-					padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
-					border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
-				});
-				val -= Math.round(padding + border);
-			}
-
-			if ( jQuery(elem).is(":visible") )
-				getWH();
-			else
-				jQuery.swap( elem, props, getWH );
-
-			return Math.max(0, val);
-		}
-
-		return jQuery.curCSS( elem, name, force );
-	},
-
-	curCSS: function( elem, name, force ) {
-		var ret, style = elem.style;
-
-		// A helper method for determining if an element's values are broken
-		function color( elem ) {
-			if ( !jQuery.browser.safari )
-				return false;
-
-			// defaultView is cached
-			var ret = defaultView.getComputedStyle( elem, null );
-			return !ret || ret.getPropertyValue("color") == "";
-		}
-
-		// We need to handle opacity special in IE
-		if ( name == "opacity" && jQuery.browser.msie ) {
-			ret = jQuery.attr( style, "opacity" );
-
-			return ret == "" ?
-				"1" :
-				ret;
-		}
-		// Opera sometimes will give the wrong display answer, this fixes it, see #2037
-		if ( jQuery.browser.opera && name == "display" ) {
-			var save = style.outline;
-			style.outline = "0 solid black";
-			style.outline = save;
-		}
-
-		// Make sure we're using the right name for getting the float value
-		if ( name.match( /float/i ) )
-			name = styleFloat;
-
-		if ( !force && style && style[ name ] )
-			ret = style[ name ];
-
-		else if ( defaultView.getComputedStyle ) {
-
-			// Only "float" is needed here
-			if ( name.match( /float/i ) )
-				name = "float";
-
-			name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
-
-			var computedStyle = defaultView.getComputedStyle( elem, null );
-
-			if ( computedStyle && !color( elem ) )
-				ret = computedStyle.getPropertyValue( name );
-
-			// If the element isn't reporting its values properly in Safari
-			// then some display: none elements are involved
-			else {
-				var swap = [], stack = [], a = elem, i = 0;
-
-				// Locate all of the parent display: none elements
-				for ( ; a && color(a); a = a.parentNode )
-					stack.unshift(a);
-
-				// Go through and make them visible, but in reverse
-				// (It would be better if we knew the exact display type that they had)
-				for ( ; i < stack.length; i++ )
-					if ( color( stack[ i ] ) ) {
-						swap[ i ] = stack[ i ].style.display;
-						stack[ i ].style.display = "block";
-					}
-
-				// Since we flip the display style, we have to handle that
-				// one special, otherwise get the value
-				ret = name == "display" && swap[ stack.length - 1 ] != null ?
-					"none" :
-					( computedStyle && computedStyle.getPropertyValue( name ) ) || "";
-
-				// Finally, revert the display styles back
-				for ( i = 0; i < swap.length; i++ )
-					if ( swap[ i ] != null )
-						stack[ i ].style.display = swap[ i ];
-			}
-
-			// We should always get a number back from opacity
-			if ( name == "opacity" && ret == "" )
-				ret = "1";
-
-		} else if ( elem.currentStyle ) {
-			var camelCase = name.replace(/\-(\w)/g, function(all, letter){
-				return letter.toUpperCase();
-			});
-
-			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
-
-			// From the awesome hack by Dean Edwards
-			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-
-			// If we're not dealing with a regular pixel number
-			// but a number that has a weird ending, we need to convert it to pixels
-			if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
-				// Remember the original values
-				var left = style.left, rsLeft = elem.runtimeStyle.left;
-
-				// Put in the new values to get a computed value out
-				elem.runtimeStyle.left = elem.currentStyle.left;
-				style.left = ret || 0;
-				ret = style.pixelLeft + "px";
-
-				// Revert the changed values
-				style.left = left;
-				elem.runtimeStyle.left = rsLeft;
-			}
-		}
-
-		return ret;
-	},
-
-	clean: function( elems, context ) {
-		var ret = [];
-		context = context || document;
-		// !context.createElement fails in IE with an error but returns typeof 'object'
-		if (typeof context.createElement == 'undefined')
-			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
-
-		jQuery.each(elems, function(i, elem){
-			if ( !elem )
-				return;
-
-			if ( elem.constructor == Number )
-				elem += '';
-
-			// Convert html string into DOM nodes
-			if ( typeof elem == "string" ) {
-				// Fix "XHTML"-style tags in all browsers
-				elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
-					return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
-						all :
-						front + "></" + tag + ">";
-				});
-
-				// Trim whitespace, otherwise indexOf won't work as expected
-				var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
-
-				var wrap =
-					// option or optgroup
-					!tags.indexOf("<opt") &&
-					[ 1, "<select multiple='multiple'>", "</select>" ] ||
-
-					!tags.indexOf("<leg") &&
-					[ 1, "<fieldset>", "</fieldset>" ] ||
-
-					tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
-					[ 1, "<table>", "</table>" ] ||
-
-					!tags.indexOf("<tr") &&
-					[ 2, "<table><tbody>", "</tbody></table>" ] ||
-
-				 	// <thead> matched above
-					(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
-					[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
-
-					!tags.indexOf("<col") &&
-					[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
-
-					// IE can't serialize <link> and <script> tags normally
-					jQuery.browser.msie &&
-					[ 1, "div<div>", "</div>" ] ||
-
-					[ 0, "", "" ];
-
-				// Go to html and back, then peel off extra wrappers
-				div.innerHTML = wrap[1] + elem + wrap[2];
-
-				// Move to the right depth
-				while ( wrap[0]-- )
-					div = div.lastChild;
-
-				// Remove IE's autoinserted <tbody> from table fragments
-				if ( jQuery.browser.msie ) {
-
-					// String was a <table>, *may* have spurious <tbody>
-					var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
-						div.firstChild && div.firstChild.childNodes :
-
-						// String was a bare <thead> or <tfoot>
-						wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
-							div.childNodes :
-							[];
-
-					for ( var j = tbody.length - 1; j >= 0 ; --j )
-						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
-							tbody[ j ].parentNode.removeChild( tbody[ j ] );
-
-					// IE completely kills leading whitespace when innerHTML is used
-					if ( /^\s/.test( elem ) )
-						div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
-
-				}
-
-				elem = jQuery.makeArray( div.childNodes );
-			}
-
-			if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
-				return;
-
-			if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
-				ret.push( elem );
-
-			else
-				ret = jQuery.merge( ret, elem );
-
-		});
-
-		return ret;
-	},
-
-	attr: function( elem, name, value ) {
-		// don't set attributes on text and comment nodes
-		if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
-			return undefined;
-
-		var notxml = !jQuery.isXMLDoc( elem ),
-			// Whether we are setting (or getting)
-			set = value !== undefined,
-			msie = jQuery.browser.msie;
-
-		// Try to normalize/fix the name
-		name = notxml && jQuery.props[ name ] || name;
-
-		// Only do all the following if this is a node (faster for style)
-		// IE elem.getAttribute passes even for style
-		if ( elem.tagName ) {
-
-			// These attributes require special treatment
-			var special = /href|src|style/.test( name );
-
-			// Safari mis-reports the default selected property of a hidden option
-			// Accessing the parent's selectedIndex property fixes it
-			if ( name == "selected" && jQuery.browser.safari )
-				elem.parentNode.selectedIndex;
-
-			// If applicable, access the attribute via the DOM 0 way
-			if ( name in elem && notxml && !special ) {
-				if ( set ){
-					// We can't allow the type property to be changed (since it causes problems in IE)
-					if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
-						throw "type property can't be changed";
-
-					elem[ name ] = value;
-				}
-
-				// browsers index elements by id/name on forms, give priority to attributes.
-				if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
-					return elem.getAttributeNode( name ).nodeValue;
-
-				return elem[ name ];
-			}
-
-			if ( msie && notxml &&  name == "style" )
-				return jQuery.attr( elem.style, "cssText", value );
-
-			if ( set )
-				// convert the value to a string (all browsers do this but IE) see #1070
-				elem.setAttribute( name, "" + value );
-
-			var attr = msie && notxml && special
-					// Some attributes require a special call on IE
-					? elem.getAttribute( name, 2 )
-					: elem.getAttribute( name );
-
-			// Non-existent attributes return null, we normalize to undefined
-			return attr === null ? undefined : attr;
-		}
-
-		// elem is actually elem.style ... set the style
-
-		// IE uses filters for opacity
-		if ( msie && name == "opacity" ) {
-			if ( set ) {
-				// IE has trouble with opacity if it does not have layout
-				// Force it by setting the zoom level
-				elem.zoom = 1;
-
-				// Set the alpha filter to set the opacity
-				elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
-					(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
-			}
-
-			return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
-				(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
-				"";
-		}
-
-		name = name.replace(/-([a-z])/ig, function(all, letter){
-			return letter.toUpperCase();
-		});
-
-		if ( set )
-			elem[ name ] = value;
-
-		return elem[ name ];
-	},
-
-	trim: function( text ) {
-		return (text || "").replace( /^\s+|\s+$/g, "" );
-	},
-
-	makeArray: function( array ) {
-		var ret = [];
-
-		if( array != null ){
-			var i = array.length;
-			//the window, strings and functions also have 'length'
-			if( i == null || array.split || array.setInterval || array.call )
-				ret[0] = array;
-			else
-				while( i )
-					ret[--i] = array[i];
-		}
-
-		return ret;
-	},
-
-	inArray: function( elem, array ) {
-		for ( var i = 0, length = array.length; i < length; i++ )
-		// Use === because on IE, window == document
-			if ( array[ i ] === elem )
-				return i;
-
-		return -1;
-	},
-
-	merge: function( first, second ) {
-		// We have to loop this way because IE & Opera overwrite the length
-		// expando of getElementsByTagName
-		var i = 0, elem, pos = first.length;
-		// Also, we need to make sure that the correct elements are being returned
-		// (IE returns comment nodes in a '*' query)
-		if ( jQuery.browser.msie ) {
-			while ( elem = second[ i++ ] )
-				if ( elem.nodeType != 8 )
-					first[ pos++ ] = elem;
-
-		} else
-			while ( elem = second[ i++ ] )
-				first[ pos++ ] = elem;
-
-		return first;
-	},
-
-	unique: function( array ) {
-		var ret = [], done = {};
-
-		try {
-
-			for ( var i = 0, length = array.length; i < length; i++ ) {
-				var id = jQuery.data( array[ i ] );
-
-				if ( !done[ id ] ) {
-					done[ id ] = true;
-					ret.push( array[ i ] );
-				}
-			}
-
-		} catch( e ) {
-			ret = array;
-		}
-
-		return ret;
-	},
-
-	grep: function( elems, callback, inv ) {
-		var ret = [];
-
-		// Go through the array, only saving the items
-		// that pass the validator function
-		for ( var i = 0, length = elems.length; i < length; i++ )
-			if ( !inv != !callback( elems[ i ], i ) )
-				ret.push( elems[ i ] );
-
-		return ret;
-	},
-
-	map: function( elems, callback ) {
-		var ret = [];
-
-		// Go through the array, translating each of the items to their
-		// new value (or values).
-		for ( var i = 0, length = elems.length; i < length; i++ ) {
-			var value = callback( elems[ i ], i );
-
-			if ( value != null )
-				ret[ ret.length ] = value;
-		}
-
-		return ret.concat.apply( [], ret );
-	}
-});
-
-var userAgent = navigator.userAgent.toLowerCase();
-
-// Figure out what browser is being used
-jQuery.browser = {
-	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
-	safari: /webkit/.test( userAgent ),
-	opera: /opera/.test( userAgent ),
-	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
-	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
-};
-
-var styleFloat = jQuery.browser.msie ?
-	"styleFloat" :
-	"cssFloat";
-
-jQuery.extend({
-	// Check to see if the W3C box model is being used
-	boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
-
-	props: {
-		"for": "htmlFor",
-		"class": "className",
-		"float": styleFloat,
-		cssFloat: styleFloat,
-		styleFloat: styleFloat,
-		readonly: "readOnly",
-		maxlength: "maxLength",
-		cellspacing: "cellSpacing"
-	}
-});
-
-jQuery.each({
-	parent: function(elem){return elem.parentNode;},
-	parents: function(elem){return jQuery.dir(elem,"parentNode");},
-	next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
-	prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
-	nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
-	prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
-	siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
-	children: function(elem){return jQuery.sibling(elem.firstChild);},
-	contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
-}, function(name, fn){
-	jQuery.fn[ name ] = function( selector ) {
-		var ret = jQuery.map( this, fn );
-
-		if ( selector && typeof selector == "string" )
-			ret = jQuery.multiFilter( selector, ret );
-
-		return this.pushStack( jQuery.unique( ret ) );
-	};
-});
-
-jQuery.each({
-	appendTo: "append",
-	prependTo: "prepend",
-	insertBefore: "before",
-	insertAfter: "after",
-	replaceAll: "replaceWith"
-}, function(name, original){
-	jQuery.fn[ name ] = function() {
-		var args = arguments;
-
-		return this.each(function(){
-			for ( var i = 0, length = args.length; i < length; i++ )
-				jQuery( args[ i ] )[ original ]( this );
-		});
-	};
-});
-
-jQuery.each({
-	removeAttr: function( name ) {
-		jQuery.attr( this, name, "" );
-		if (this.nodeType == 1)
-			this.removeAttribute( name );
-	},
-
-	addClass: function( classNames ) {
-		jQuery.className.add( this, classNames );
-	},
-
-	removeClass: function( classNames ) {
-		jQuery.className.remove( this, classNames );
-	},
-
-	toggleClass: function( classNames ) {
-		jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
-	},
-
-	remove: function( selector ) {
-		if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
-			// Prevent memory leaks
-			jQuery( "*", this ).add(this).each(function(){
-				jQuery.event.remove(this);
-				jQuery.removeData(this);
-			});
-			if (this.parentNode)
-				this.parentNode.removeChild( this );
-		}
-	},
-
-	empty: function() {
-		// Remove element nodes and prevent memory leaks
-		jQuery( ">*", this ).remove();
-
-		// Remove any remaining nodes
-		while ( this.firstChild )
-			this.removeChild( this.firstChild );
-	}
-}, function(name, fn){
-	jQuery.fn[ name ] = function(){
-		return this.each( fn, arguments );
-	};
-});
-
-jQuery.each([ "Height", "Width" ], function(i, name){
-	var type = name.toLowerCase();
-
-	jQuery.fn[ type ] = function( size ) {
-		// Get window width or height
-		return this[0] == window ?
-			// Opera reports document.body.client[Width/Height] properly in both quirks and standards
-			jQuery.browser.opera && document.body[ "client" + name ] ||
-
-			// Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
-			jQuery.browser.safari && window[ "inner" + name ] ||
-
-			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
-			document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
-
-			// Get document width or height
-			this[0] == document ?
-				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
-				Math.max(
-					Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
-					Math.max(document.body["offset" + name], document.documentElement["offset" + name])
-				) :
-
-				// Get or set width or height on the element
-				size == undefined ?
-					// Get width or height on the element
-					(this.length ? jQuery.css( this[0], type ) : null) :
-
-					// Set the width or height on the element (default to pixels if value is unitless)
-					this.css( type, size.constructor == String ? size : size + "px" );
-	};
-});
-
-// Helper function used by the dimensions and offset modules
-function num(elem, prop) {
-	return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
-}var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
-		"(?:[\\w*_-]|\\\\.)" :
-		"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
-	quickChild = new RegExp("^>\\s*(" + chars + "+)"),
-	quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
-	quickClass = new RegExp("^([#.]?)(" + chars + "*)");
-
-jQuery.extend({
-	expr: {
-		"": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
-		"#": function(a,i,m){return a.getAttribute("id")==m[2];},
-		":": {
-			// Position Checks
-			lt: function(a,i,m){return i<m[3]-0;},
-			gt: function(a,i,m){return i>m[3]-0;},
-			nth: function(a,i,m){return m[3]-0==i;},
-			eq: function(a,i,m){return m[3]-0==i;},
-			first: function(a,i){return i==0;},
-			last: function(a,i,m,r){return i==r.length-1;},
-			even: function(a,i){return i%2==0;},
-			odd: function(a,i){return i%2;},
-
-			// Child Checks
-			"first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
-			"last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
-			"only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
-
-			// Parent Checks
-			parent: function(a){return a.firstChild;},
-			empty: function(a){return !a.firstChild;},
-
-			// Text Check
-			contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
-
-			// Visibility
-			visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
-			hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
-
-			// Form attributes
-			enabled: function(a){return !a.disabled;},
-			disabled: function(a){return a.disabled;},
-			checked: function(a){return a.checked;},
-			selected: function(a){return a.selected||jQuery.attr(a,"selected");},
-
-			// Form elements
-			text: function(a){return "text"==a.type;},
-			radio: function(a){return "radio"==a.type;},
-			checkbox: function(a){return "checkbox"==a.type;},
-			file: function(a){return "file"==a.type;},
-			password: function(a){return "password"==a.type;},
-			submit: function(a){return "submit"==a.type;},
-			image: function(a){return "image"==a.type;},
-			reset: function(a){return "reset"==a.type;},
-			button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
-			input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
-
-			// :has()
-			has: function(a,i,m){return jQuery.find(m[3],a).length;},
-
-			// :header
-			header: function(a){return /h\d/i.test(a.nodeName);},
-
-			// :animated
-			animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
-		}
-	},
-
-	// The regular expressions that power the parsing engine
-	parse: [
-		// Match: [@value='test'], [@foo]
-		/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
-
-		// Match: :contains('foo')
-		/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
-
-		// Match: :even, :last-child, #id, .class
-		new RegExp("^([:.#]*)(" + chars + "+)")
-	],
-
-	multiFilter: function( expr, elems, not ) {
-		var old, cur = [];
-
-		while ( expr && expr != old ) {
-			old = expr;
-			var f = jQuery.filter( expr, elems, not );
-			expr = f.t.replace(/^\s*,\s*/, "" );
-			cur = not ? elems = f.r : jQuery.merge( cur, f.r );
-		}
-
-		return cur;
-	},
-
-	find: function( t, context ) {
-		// Quickly handle non-string expressions
-		if ( typeof t != "string" )
-			return [ t ];
-
-		// check to make sure context is a DOM element or a document
-		if ( context && context.nodeType != 1 && context.nodeType != 9)
-			return [ ];
-
-		// Set the correct context (if none is provided)
-		context = context || document;
-
-		// Initialize the search
-		var ret = [context], done = [], last, nodeName;
-
-		// Continue while a selector expression exists, and while
-		// we're no longer looping upon ourselves
-		while ( t && last != t ) {
-			var r = [];
-			last = t;
-
-			t = jQuery.trim(t);
-
-			var foundToken = false,
-
-			// An attempt at speeding up child selectors that
-			// point to a specific element tag
-				re = quickChild,
-
-				m = re.exec(t);
-
-			if ( m ) {
-				nodeName = m[1].toUpperCase();
-
-				// Perform our own iteration and filter
-				for ( var i = 0; ret[i]; i++ )
-					for ( var c = ret[i].firstChild; c; c = c.nextSibling )
-						if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
-							r.push( c );
-
-				ret = r;
-				t = t.replace( re, "" );
-				if ( t.indexOf(" ") == 0 ) continue;
-				foundToken = true;
-			} else {
-				re = /^([>+~])\s*(\w*)/i;
-
-				if ( (m = re.exec(t)) != null ) {
-					r = [];
-
-					var merge = {};
-					nodeName = m[2].toUpperCase();
-					m = m[1];
-
-					for ( var j = 0, rl = ret.length; j < rl; j++ ) {
-						var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
-						for ( ; n; n = n.nextSibling )
-							if ( n.nodeType == 1 ) {
-								var id = jQuery.data(n);
-
-								if ( m == "~" && merge[id] ) break;
-
-								if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
-									if ( m == "~" ) merge[id] = true;
-									r.push( n );
-								}
-
-								if ( m == "+" ) break;
-							}
-					}
-
-					ret = r;
-
-					// And remove the token
-					t = jQuery.trim( t.replace( re, "" ) );
-					foundToken = true;
-				}
-			}
-
-			// See if there's still an expression, and that we haven't already
-			// matched a token
-			if ( t && !foundToken ) {
-				// Handle multiple expressions
-				if ( !t.indexOf(",") ) {
-					// Clean the result set
-					if ( context == ret[0] ) ret.shift();
-
-					// Merge the result sets
-					done = jQuery.merge( done, ret );
-
-					// Reset the context
-					r = ret = [context];
-
-					// Touch up the selector string
-					t = " " + t.substr(1,t.length);
-
-				} else {
-					// Optimize for the case nodeName#idName
-					var re2 = quickID;
-					var m = re2.exec(t);
-
-					// Re-organize the results, so that they're consistent
-					if ( m ) {
-						m = [ 0, m[2], m[3], m[1] ];
-
-					} else {
-						// Otherwise, do a traditional filter check for
-						// ID, class, and element selectors
-						re2 = quickClass;
-						m = re2.exec(t);
-					}
-
-					m[2] = m[2].replace(/\\/g, "");
-
-					var elem = ret[ret.length-1];
-
-					// Try to do a global search by ID, where we can
-					if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
-						// Optimization for HTML document case
-						var oid = elem.getElementById(m[2]);
-
-						// Do a quick check for the existence of the actual ID attribute
-						// to avoid selecting by the name attribute in IE
-						// also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
-						if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
-							oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
-
-						// Do a quick check for node name (where applicable) so
-						// that div#foo searches will be really fast
-						ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
-					} else {
-						// We need to find all descendant elements
-						for ( var i = 0; ret[i]; i++ ) {
-							// Grab the tag name being searched for
-							var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
-
-							// Handle IE7 being really dumb about <object>s
-							if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
-								tag = "param";
-
-							r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
-						}
-
-						// It's faster to filter by class and be done with it
-						if ( m[1] == "." )
-							r = jQuery.classFilter( r, m[2] );
-
-						// Same with ID filtering
-						if ( m[1] == "#" ) {
-							var tmp = [];
-
-							// Try to find the element with the ID
-							for ( var i = 0; r[i]; i++ )
-								if ( r[i].getAttribute("id") == m[2] ) {
-									tmp = [ r[i] ];
-									break;
-								}
-
-							r = tmp;
-						}
-
-						ret = r;
-					}
-
-					t = t.replace( re2, "" );
-				}
-
-			}
-
-			// If a selector string still exists
-			if ( t ) {
-				// Attempt to filter it
-				var val = jQuery.filter(t,r);
-				ret = r = val.r;
-				t = jQuery.trim(val.t);
-			}
-		}
-
-		// An error occurred with the selector;
-		// just return an empty set instead
-		if ( t )
-			ret = [];
-
-		// Remove the root context
-		if ( ret && context == ret[0] )
-			ret.shift();
-
-		// And combine the results
-		done = jQuery.merge( done, ret );
-
-		return done;
-	},
-
-	classFilter: function(r,m,not){
-		m = " " + m + " ";
-		var tmp = [];
-		for ( var i = 0; r[i]; i++ ) {
-			var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
-			if ( !not && pass || not && !pass )
-				tmp.push( r[i] );
-		}
-		return tmp;
-	},
-
-	filter: function(t,r,not) {
-		var last;
-
-		// Look for common filter expressions
-		while ( t && t != last ) {
-			last = t;
-
-			var p = jQuery.parse, m;
-
-			for ( var i = 0; p[i]; i++ ) {
-				m = p[i].exec( t );
-
-				if ( m ) {
-					// Remove what we just matched
-					t = t.substring( m[0].length );
-
-					m[2] = m[2].replace(/\\/g, "");
-					break;
-				}
-			}
-
-			if ( !m )
-				break;
-
-			// :not() is a special case that can be optimized by
-			// keeping it out of the expression list
-			if ( m[1] == ":" && m[2] == "not" )
-				// optimize if only one selector found (most common case)
-				r = isSimple.test( m[3] ) ?
-					jQuery.filter(m[3], r, true).r :
-					jQuery( r ).not( m[3] );
-
-			// We can get a big speed boost by filtering by class here
-			else if ( m[1] == "." )
-				r = jQuery.classFilter(r, m[2], not);
-
-			else if ( m[1] == "[" ) {
-				var tmp = [], type = m[3];
-
-				for ( var i = 0, rl = r.length; i < rl; i++ ) {
-					var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
-
-					if ( z == null || /href|src|selected/.test(m[2]) )
-						z = jQuery.attr(a,m[2]) || '';
-
-					if ( (type == "" && !!z ||
-						 type == "=" && z == m[5] ||
-						 type == "!=" && z != m[5] ||
-						 type == "^=" && z && !z.indexOf(m[5]) ||
-						 type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
-						 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
-							tmp.push( a );
-				}
-
-				r = tmp;
-
-			// We can get a speed boost by handling nth-child here
-			} else if ( m[1] == ":" && m[2] == "nth-child" ) {
-				var merge = {}, tmp = [],
-					// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
-					test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
-						m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
-						!/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
-					// calculate the numbers (first)n+(last) including if they are negative
-					first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
-
-				// loop through all the elements left in the jQuery object
-				for ( var i = 0, rl = r.length; i < rl; i++ ) {
-					var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
-
-					if ( !merge[id] ) {
-						var c = 1;
-
-						for ( var n = parentNode.firstChild; n; n = n.nextSibling )
-							if ( n.nodeType == 1 )
-								n.nodeIndex = c++;
-
-						merge[id] = true;
-					}
-
-					var add = false;
-
-					if ( first == 0 ) {
-						if ( node.nodeIndex == last )
-							add = true;
-					} else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
-						add = true;
-
-					if ( add ^ not )
-						tmp.push( node );
-				}
-
-				r = tmp;
-
-			// Otherwise, find the expression to execute
-			} else {
-				var fn = jQuery.expr[ m[1] ];
-				if ( typeof fn == "object" )
-					fn = fn[ m[2] ];
-
-				if ( typeof fn == "string" )
-					fn = eval("false||function(a,i){return " + fn + ";}");
-
-				// Execute it against the current filter
-				r = jQuery.grep( r, function(elem, i){
-					return fn(elem, i, m, r);
-				}, not );
-			}
-		}
-
-		// Return an array of filtered elements (r)
-		// and the modified expression string (t)
-		return { r: r, t: t };
-	},
-
-	dir: function( elem, dir ){
-		var matched = [],
-			cur = elem[dir];
-		while ( cur && cur != document ) {
-			if ( cur.nodeType == 1 )
-				matched.push( cur );
-			cur = cur[dir];
-		}
-		return matched;
-	},
-
-	nth: function(cur,result,dir,elem){
-		result = result || 1;
-		var num = 0;
-
-		for ( ; cur; cur = cur[dir] )
-			if ( cur.nodeType == 1 && ++num == result )
-				break;
-
-		return cur;
-	},
-
-	sibling: function( n, elem ) {
-		var r = [];
-
-		for ( ; n; n = n.nextSibling ) {
-			if ( n.nodeType == 1 && n != elem )
-				r.push( n );
-		}
-
-		return r;
-	}
-});
-/*
- * A number of helper functions used for managing events.
- * Many of the ideas behind this code orignated from
- * Dean Edwards' addEvent library.
- */
-jQuery.event = {
-
-	// Bind an event to an element
-	// Original by Dean Edwards
-	add: function(elem, types, handler, data) {
-		if ( elem.nodeType == 3 || elem.nodeType == 8 )
-			return;
-
-		// For whatever reason, IE has trouble passing the window object
-		// around, causing it to be cloned in the process
-		if ( jQuery.browser.msie && elem.setInterval )
-			elem = window;
-
-		// Make sure that the function being executed has a unique ID
-		if ( !handler.guid )
-			handler.guid = this.guid++;
-
-		// if data is passed, bind to handler
-		if( data != undefined ) {
-			// Create temporary function pointer to original handler
-			var fn = handler;
-
-			// Create unique handler function, wrapped around original handler
-			handler = this.proxy( fn, function() {
-				// Pass arguments and context to original handler
-				return fn.apply(this, arguments);
-			});
-
-			// Store data in unique handler
-			handler.data = data;
-		}
-
-		// Init the element's event structure
-		var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
-			handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
-				// Handle the second event of a trigger and when
-				// an event is called after a page has unloaded
-				if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
-					return jQuery.event.handle.apply(arguments.callee.elem, arguments);
-			});
-		// Add elem as a property of the handle function
-		// This is to prevent a memory leak with non-native
-		// event in IE.
-		handle.elem = elem;
-
-		// Handle multiple events separated by a space
-		// jQuery(...).bind("mouseover mouseout", fn);
-		jQuery.each(types.split(/\s+/), function(index, type) {
-			// Namespaced event handlers
-			var parts = type.split(".");
-			type = parts[0];
-			handler.type = parts[1];
-
-			// Get the current list of functions bound to this event
-			var handlers = events[type];
-
-			// Init the event handler queue
-			if (!handlers) {
-				handlers = events[type] = {};
-
-				// Check for a special event handler
-				// Only use addEventListener/attachEvent if the special
-				// events handler returns false
-				if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
-					// Bind the global event handler to the element
-					if (elem.addEventListener)
-						elem.addEventListener(type, handle, false);
-					else if (elem.attachEvent)
-						elem.attachEvent("on" + type, handle);
-				}
-			}
-
-			// Add the function to the element's handler list
-			handlers[handler.guid] = handler;
-
-			// Keep track of which events have been used, for global triggering
-			jQuery.event.global[type] = true;
-		});
-
-		// Nullify elem to prevent memory leaks in IE
-		elem = null;
-	},
-
-	guid: 1,
-	global: {},
-
-	// Detach an event or set of events from an element
-	remove: function(elem, types, handler) {
-		// don't do events on text and comment nodes
-		if ( elem.nodeType == 3 || elem.nodeType == 8 )
-			return;
-
-		var events = jQuery.data(elem, "events"), ret, index;
-
-		if ( events ) {
-			// Unbind all events for the element
-			if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
-				for ( var type in events )
-					this.remove( elem, type + (types || "") );
-			else {
-				// types is actually an event object here
-				if ( types.type ) {
-					handler = types.handler;
-					types = types.type;
-				}
-
-				// Handle multiple events seperated by a space
-				// jQuery(...).unbind("mouseover mouseout", fn);
-				jQuery.each(types.split(/\s+/), function(index, type){
-					// Namespaced event handlers
-					var parts = type.split(".");
-					type = parts[0];
-
-					if ( events[type] ) {
-						// remove the given handler for the given type
-						if ( handler )
-							delete events[type][handler.guid];
-
-						// remove all handlers for the given type
-						else
-							for ( handler in events[type] )
-								// Handle the removal of namespaced events
-								if ( !parts[1] || events[type][handler].type == parts[1] )
-									delete events[type][handler];
-
-						// remove generic event handler if no more handlers exist
-						for ( ret in events[type] ) break;
-						if ( !ret ) {
-							if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
-								if (elem.removeEventListener)
-									elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
-								else if (elem.detachEvent)
-									elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
-							}
-							ret = null;
-							delete events[type];
-						}
-					}
-				});
-			}
-
-			// Remove the expando if it's no longer used
-			for ( ret in events ) break;
-			if ( !ret ) {
-				var handle = jQuery.data( elem, "handle" );
-				if ( handle ) handle.elem = null;
-				jQuery.removeData( elem, "events" );
-				jQuery.removeData( elem, "handle" );
-			}
-		}
-	},
-
-	trigger: function(type, data, elem, donative, extra) {
-		// Clone the incoming data, if any
-		data = jQuery.makeArray(data);
-
-		if ( type.indexOf("!") >= 0 ) {
-			type = type.slice(0, -1);
-			var exclusive = true;
-		}
-
-		// Handle a global trigger
-		if ( !elem ) {
-			// Only trigger if we've ever bound an event for it
-			if ( this.global[type] )
-				jQuery("*").add([window, document]).trigger(type, data);
-
-		// Handle triggering a single element
-		} else {
-			// don't do events on text and comment nodes
-			if ( elem.nodeType == 3 || elem.nodeType == 8 )
-				return undefined;
-
-			var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
-				// Check to see if we need to provide a fake event, or not
-				event = !data[0] || !data[0].preventDefault;
-
-			// Pass along a fake event
-			if ( event ) {
-				data.unshift({
-					type: type,
-					target: elem,
-					preventDefault: function(){},
-					stopPropagation: function(){},
-					timeStamp: now()
-				});
-				data[0][expando] = true; // no need to fix fake event
-			}
-
-			// Enforce the right trigger type
-			data[0].type = type;
-			if ( exclusive )
-				data[0].exclusive = true;
-
-			// Trigger the event, it is assumed that "handle" is a function
-			var handle = jQuery.data(elem, "handle");
-			if ( handle )
-				val = handle.apply( elem, data );
-
-			// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
-			if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
-				val = false;
-
-			// Extra functions don't get the custom event object
-			if ( event )
-				data.shift();
-
-			// Handle triggering of extra function
-			if ( extra && jQuery.isFunction( extra ) ) {
-				// call the extra function and tack the current return value on the end for possible inspection
-				ret = extra.apply( elem, val == null ? data : data.concat( val ) );
-				// if anything is returned, give it precedence and have it overwrite the previous value
-				if (ret !== undefined)
-					val = ret;
-			}
-
-			// Trigger the native events (except for clicks on links)
-			if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
-				this.triggered = true;
-				try {
-					elem[ type ]();
-				// prevent IE from throwing an error for some hidden elements
-				} catch (e) {}
-			}
-
-			this.triggered = false;
-		}
-
-		return val;
-	},
-
-	handle: function(event) {
-		// returned undefined or false
-		var val, ret, namespace, all, handlers;
-
-		event = arguments[0] = jQuery.event.fix( event || window.event );
-
-		// Namespaced event handlers
-		namespace = event.type.split(".");
-		event.type = namespace[0];
-		namespace = namespace[1];
-		// Cache this now, all = true means, any handler
-		all = !namespace && !event.exclusive;
-
-		handlers = ( jQuery.data(this, "events") || {} )[event.type];
-
-		for ( var j in handlers ) {
-			var handler = handlers[j];
-
-			// Filter the functions by class
-			if ( all || handler.type == namespace ) {
-				// Pass in a reference to the handler function itself
-				// So that we can later remove it
-				event.handler = handler;
-				event.data = handler.data;
-
-				ret = handler.apply( this, arguments );
-
-				if ( val !== false )
-					val = ret;
-
-				if ( ret === false ) {
-					event.preventDefault();
-					event.stopPropagation();
-				}
-			}
-		}
-
-		return val;
-	},
-
-	fix: function(event) {
-		if ( event[expando] == true )
-			return event;
-
-		// store a copy of the original event object
-		// and "clone" to set read-only properties
-		var originalEvent = event;
-		event = { originalEvent: originalEvent };
-		var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
-		for ( var i=props.length; i; i-- )
-			event[ props[i] ] = originalEvent[ props[i] ];
-
-		// Mark it as fixed
-		event[expando] = true;
-
-		// add preventDefault and stopPropagation since
-		// they will not work on the clone
-		event.preventDefault = function() {
-			// if preventDefault exists run it on the original event
-			if (originalEvent.preventDefault)
-				originalEvent.preventDefault();
-			// otherwise set the returnValue property of the original event to false (IE)
-			originalEvent.returnValue = false;
-		};
-		event.stopPropagation = function() {
-			// if stopPropagation exists run it on the original event
-			if (originalEvent.stopPropagation)
-				originalEvent.stopPropagation();
-			// otherwise set the cancelBubble property of the original event to true (IE)
-			originalEvent.cancelBubble = true;
-		};
-
-		// Fix timeStamp
-		event.timeStamp = event.timeStamp || now();
-
-		// Fix target property, if necessary
-		if ( !event.target )
-			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
-
-		// check if target is a textnode (safari)
-		if ( event.target.nodeType == 3 )
-			event.target = event.target.parentNode;
-
-		// Add relatedTarget, if necessary
-		if ( !event.relatedTarget && event.fromElement )
-			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
-
-		// Calculate pageX/Y if missing and clientX/Y available
-		if ( event.pageX == null && event.clientX != null ) {
-			var doc = document.documentElement, body = document.body;
-			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
-			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
-		}
-
-		// Add which for key events
-		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
-			event.which = event.charCode || event.keyCode;
-
-		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
-		if ( !event.metaKey && event.ctrlKey )
-			event.metaKey = event.ctrlKey;
-
-		// Add which for click: 1 == left; 2 == middle; 3 == right
-		// Note: button is not normalized, so don't use it
-		if ( !event.which && event.button )
-			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
-
-		return event;
-	},
-
-	proxy: function( fn, proxy ){
-		// Set the guid of unique handler to the same of original handler, so it can be removed
-		proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
-		// So proxy can be declared as an argument
-		return proxy;
-	},
-
-	special: {
-		ready: {
-			setup: function() {
-				// Make sure the ready event is setup
-				bindReady();
-				return;
-			},
-
-			teardown: function() { return; }
-		},
-
-		mouseenter: {
-			setup: function() {
-				if ( jQuery.browser.msie ) return false;
-				jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
-				return true;
-			},
-
-			teardown: function() {
-				if ( jQuery.browser.msie ) return false;
-				jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
-				return true;
-			},
-
-			handler: function(event) {
-				// If we actually just moused on to a sub-element, ignore it
-				if ( withinElement(event, this) ) return true;
-				// Execute the right handlers by setting the event type to mouseenter
-				event.type = "mouseenter";
-				return jQuery.event.handle.apply(this, arguments);
-			}
-		},
-
-		mouseleave: {
-			setup: function() {
-				if ( jQuery.browser.msie ) return false;
-				jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
-				return true;
-			},
-
-			teardown: function() {
-				if ( jQuery.browser.msie ) return false;
-				jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
-				return true;
-			},
-
-			handler: function(event) {
-				// If we actually just moused on to a sub-element, ignore it
-				if ( withinElement(event, this) ) return true;
-				// Execute the right handlers by setting the event type to mouseleave
-				event.type = "mouseleave";
-				return jQuery.event.handle.apply(this, arguments);
-			}
-		}
-	}
-};
-
-jQuery.fn.extend({
-	bind: function( type, data, fn ) {
-		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
-			jQuery.event.add( this, type, fn || data, fn && data );
-		});
-	},
-
-	one: function( type, data, fn ) {
-		var one = jQuery.event.proxy( fn || data, function(event) {
-			jQuery(this).unbind(event, one);
-			return (fn || data).apply( this, arguments );
-		});
-		return this.each(function(){
-			jQuery.event.add( this, type, one, fn && data);
-		});
-	},
-
-	unbind: function( type, fn ) {
-		return this.each(function(){
-			jQuery.event.remove( this, type, fn );
-		});
-	},
-
-	trigger: function( type, data, fn ) {
-		return this.each(function(){
-			jQuery.event.trigger( type, data, this, true, fn );
-		});
-	},
-
-	triggerHandler: function( type, data, fn ) {
-		return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
-	},
-
-	toggle: function( fn ) {
-		// Save reference to arguments for access in closure
-		var args = arguments, i = 1;
-
-		// link all the functions, so any of them can unbind this click handler
-		while( i < args.length )
-			jQuery.event.proxy( fn, args[i++] );
-
-		return this.click( jQuery.event.proxy( fn, function(event) {
-			// Figure out which function to execute
-			this.lastToggle = ( this.lastToggle || 0 ) % i;
-
-			// Make sure that clicks stop
-			event.preventDefault();
-
-			// and execute the function
-			return args[ this.lastToggle++ ].apply( this, arguments ) || false;
-		}));
-	},
-
-	hover: function(fnOver, fnOut) {
-		return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
-	},
-
-	ready: function(fn) {
-		// Attach the listeners
-		bindReady();
-
-		// If the DOM is already ready
-		if ( jQuery.isReady )
-			// Execute the function immediately
-			fn.call( document, jQuery );
-
-		// Otherwise, remember the function for later
-		else
-			// Add the function to the wait list
-			jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
-
-		return this;
-	}
-});
-
-jQuery.extend({
-	isReady: false,
-	readyList: [],
-	// Handle when the DOM is ready
-	ready: function() {
-		// Make sure that the DOM is not already loaded
-		if ( !jQuery.isReady ) {
-			// Remember that the DOM is ready
-			jQuery.isReady = true;
-
-			// If there are functions bound, to execute
-			if ( jQuery.readyList ) {
-				// Execute all of them
-				jQuery.each( jQuery.readyList, function(){
-					this.call( document );
-				});
-
-				// Reset the list of functions
-				jQuery.readyList = null;
-			}
-
-			// Trigger any bound ready events
-			jQuery(document).triggerHandler("ready");
-		}
-	}
-});
-
-var readyBound = false;
-
-function bindReady(){
-	if ( readyBound ) return;
-	readyBound = true;
-
-	// Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
-	if ( document.addEventListener && !jQuery.browser.opera)
-		// Use the handy event callback
-		document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
-
-	// If IE is used and is not in a frame
-	// Continually check to see if the document is ready
-	if ( jQuery.browser.msie && window == top ) (function(){
-		if (jQuery.isReady) return;
-		try {
-			// If IE is used, use the trick by Diego Perini
-			// http://javascript.nwbox.com/IEContentLoaded/
-			document.documentElement.doScroll("left");
-		} catch( error ) {
-			setTimeout( arguments.callee, 0 );
-			return;
-		}
-		// and execute any waiting functions
-		jQuery.ready();
-	})();
-
-	if ( jQuery.browser.opera )
-		document.addEventListener( "DOMContentLoaded", function () {
-			if (jQuery.isReady) return;
-			for (var i = 0; i < document.styleSheets.length; i++)
-				if (document.styleSheets[i].disabled) {
-					setTimeout( arguments.callee, 0 );
-					return;
-				}
-			// and execute any waiting functions
-			jQuery.ready();
-		}, false);
-
-	if ( jQuery.browser.safari ) {
-		var numStyles;
-		(function(){
-			if (jQuery.isReady) return;
-			if ( document.readyState != "loaded" && document.readyState != "complete" ) {
-				setTimeout( arguments.callee, 0 );
-				return;
-			}
-			if ( numStyles === undefined )
-				numStyles = jQuery("style, link[rel=stylesheet]").length;
-			if ( document.styleSheets.length != numStyles ) {
-				setTimeout( arguments.callee, 0 );
-				return;
-			}
-			// and execute any waiting functions
-			jQuery.ready();
-		})();
-	}
-
-	// A fallback to window.onload, that will always work
-	jQuery.event.add( window, "load", jQuery.ready );
-}
-
-jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
-	"mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
-	"submit,keydown,keypress,keyup,error").split(","), function(i, name){
-
-	// Handle event binding
-	jQuery.fn[name] = function(fn){
-		return fn ? this.bind(name, fn) : this.trigger(name);
-	};
-});
-
-// Checks if an event happened on an element within another element
-// Used in jQuery.event.special.mouseenter and mouseleave handlers
-var withinElement = function(event, elem) {
-	// Check if mouse(over|out) are still within the same parent element
-	var parent = event.relatedTarget;
-	// Traverse up the tree
-	while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
-	// Return true if we actually just moused on to a sub-element
-	return parent == elem;
-};
-
-// Prevent memory leaks in IE
-// And prevent errors on refresh with events like mouseover in other browsers
-// Window isn't included so as not to unbind existing unload events
-jQuery(window).bind("unload", function() {
-	jQuery("*").add(document).unbind();
-});
-jQuery.fn.extend({
-	// Keep a copy of the old load
-	_load: jQuery.fn.load,
-
-	load: function( url, params, callback ) {
-		if ( typeof url != 'string' )
-			return this._load( url );
-
-		var off = url.indexOf(" ");
-		if ( off >= 0 ) {
-			var selector = url.slice(off, url.length);
-			url = url.slice(0, off);
-		}
-
-		callback = callback || function(){};
-
-		// Default to a GET request
-		var type = "GET";
-
-		// If the second parameter was provided
-		if ( params )
-			// If it's a function
-			if ( jQuery.isFunction( params ) ) {
-				// We assume that it's the callback
-				callback = params;
-				params = null;
-
-			// Otherwise, build a param string
-			} else {
-				params = jQuery.param( params );
-				type = "POST";
-			}
-
-		var self = this;
-
-		// Request the remote document
-		jQuery.ajax({
-			url: url,
-			type: type,
-			dataType: "html",
-			data: params,
-			complete: function(res, status){
-				// If successful, inject the HTML into all the matched elements
-				if ( status == "success" || status == "notmodified" )
-					// See if a selector was specified
-					self.html( selector ?
-						// Create a dummy div to hold the results
-						jQuery("<div/>")
-							// inject the contents of the document in, removing the scripts
-							// to avoid any 'Permission Denied' errors in IE
-							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
-
-							// Locate the specified elements
-							.find(selector) :
-
-						// If not, just inject the full result
-						res.responseText );
-
-				self.each( callback, [res.responseText, status, res] );
-			}
-		});
-		return this;
-	},
-
-	serialize: function() {
-		return jQuery.param(this.serializeArray());
-	},
-	serializeArray: function() {
-		return this.map(function(){
-			return jQuery.nodeName(this, "form") ?
-				jQuery.makeArray(this.elements) : this;
-		})
-		.filter(function(){
-			return this.name && !this.disabled &&
-				(this.checked || /select|textarea/i.test(this.nodeName) ||
-					/text|hidden|password/i.test(this.type));
-		})
-		.map(function(i, elem){
-			var val = jQuery(this).val();
-			return val == null ? null :
-				val.constructor == Array ?
-					jQuery.map( val, function(val, i){
-						return {name: elem.name, value: val};
-					}) :
-					{name: elem.name, value: val};
-		}).get();
-	}
-});
-
-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
-	jQuery.fn[o] = function(f){
-		return this.bind(o, f);
-	};
-});
-
-var jsc = now();
-
-jQuery.extend({
-	get: function( url, data, callback, type ) {
-		// shift arguments if data argument was ommited
-		if ( jQuery.isFunction( data ) ) {
-			callback = data;
-			data = null;
-		}
-
-		return jQuery.ajax({
-			type: "GET",
-			url: url,
-			data: data,
-			success: callback,
-			dataType: type
-		});
-	},
-
-	getScript: function( url, callback ) {
-		return jQuery.get(url, null, callback, "script");
-	},
-
-	getJSON: function( url, data, callback ) {
-		return jQuery.get(url, data, callback, "json");
-	},
-
-	post: function( url, data, callback, type ) {
-		if ( jQuery.isFunction( data ) ) {
-			callback = data;
-			data = {};
-		}
-
-		return jQuery.ajax({
-			type: "POST",
-			url: url,
-			data: data,
-			success: callback,
-			dataType: type
-		});
-	},
-
-	ajaxSetup: function( settings ) {
-		jQuery.extend( jQuery.ajaxSettings, settings );
-	},
-
-	ajaxSettings: {
-		url: location.href,
-		global: true,
-		type: "GET",
-		timeout: 0,
-		contentType: "application/x-www-form-urlencoded",
-		processData: true,
-		async: true,
-		data: null,
-		username: null,
-		password: null,
-		accepts: {
-			xml: "application/xml, text/xml",
-			html: "text/html",
-			script: "text/javascript, application/javascript",
-			json: "application/json, text/javascript",
-			text: "text/plain",
-			_default: "*/*"
-		}
-	},
-
-	// Last-Modified header cache for next request
-	lastModified: {},
-
-	ajax: function( s ) {
-		// Extend the settings, but re-extend 's' so that it can be
-		// checked again later (in the test suite, specifically)
-		s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
-
-		var jsonp, jsre = /=\?(&|$)/g, status, data,
-			type = s.type.toUpperCase();
-
-		// convert data if not already a string
-		if ( s.data && s.processData && typeof s.data != "string" )
-			s.data = jQuery.param(s.data);
-
-		// Handle JSONP Parameter Callbacks
-		if ( s.dataType == "jsonp" ) {
-			if ( type == "GET" ) {
-				if ( !s.url.match(jsre) )
-					s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
-			} else if ( !s.data || !s.data.match(jsre) )
-				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
-			s.dataType = "json";
-		}
-
-		// Build temporary JSONP function
-		if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
-			jsonp = "jsonp" + jsc++;
-
-			// Replace the =? sequence both in the query string and the data
-			if ( s.data )
-				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
-			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
-
-			// We need to make sure
-			// that a JSONP style response is executed properly
-			s.dataType = "script";
-
-			// Handle JSONP-style loading
-			window[ jsonp ] = function(tmp){
-				data = tmp;
-				success();
-				complete();
-				// Garbage collect
-				window[ jsonp ] = undefined;
-				try{ delete window[ jsonp ]; } catch(e){}
-				if ( head )
-					head.removeChild( script );
-			};
-		}
-
-		if ( s.dataType == "script" && s.cache == null )
-			s.cache = false;
-
-		if ( s.cache === false && type == "GET" ) {
-			var ts = now();
-			// try replacing _= if it is there
-			var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
-			// if nothing was replaced, add timestamp to the end
-			s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
-		}
-
-		// If data is available, append data to url for get requests
-		if ( s.data && type == "GET" ) {
-			s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
-
-			// IE likes to send both get and post data, prevent this
-			s.data = null;
-		}
-
-		// Watch for a new set of requests
-		if ( s.global && ! jQuery.active++ )
-			jQuery.event.trigger( "ajaxStart" );
-
-		// Matches an absolute URL, and saves the domain
-		var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
-
-		// If we're requesting a remote document
-		// and trying to load JSON or Script with a GET
-		if ( s.dataType == "script" && type == "GET"
-				&& remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
-			var head = document.getElementsByTagName("head")[0];
-			var script = document.createElement("script");
-			script.src = s.url;
-			if (s.scriptCharset)
-				script.charset = s.scriptCharset;
-
-			// Handle Script loading
-			if ( !jsonp ) {
-				var done = false;
-
-				// Attach handlers for all browsers
-				script.onload = script.onreadystatechange = function(){
-					if ( !done && (!this.readyState ||
-							this.readyState == "loaded" || this.readyState == "complete") ) {
-						done = true;
-						success();
-						complete();
-						head.removeChild( script );
-					}
-				};
-			}
-
-			head.appendChild(script);
-
-			// We handle everything using the script element injection
-			return undefined;
-		}
-
-		var requestDone = false;
-
-		// Create the request object; Microsoft failed to properly
-		// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
-		var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
-
-		// Open the socket
-		// Passing null username, generates a login popup on Opera (#2865)
-		if( s.username )
-			xhr.open(type, s.url, s.async, s.username, s.password);
-		else
-			xhr.open(type, s.url, s.async);
-
-		// Need an extra try/catch for cross domain requests in Firefox 3
-		try {
-			// Set the correct header, if data is being sent
-			if ( s.data )
-				xhr.setRequestHeader("Content-Type", s.contentType);
-
-			// Set the If-Modified-Since header, if ifModified mode.
-			if ( s.ifModified )
-				xhr.setRequestHeader("If-Modified-Since",
-					jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
-
-			// Set header so the called script knows that it's an XMLHttpRequest
-			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
-
-			// Set the Accepts header for the server, depending on the dataType
-			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
-				s.accepts[ s.dataType ] + ", */*" :
-				s.accepts._default );
-		} catch(e){}
-
-		// Allow custom headers/mimetypes
-		if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
-			// cleanup active request counter
-			s.global && jQuery.active--;
-			// close opended socket
-			xhr.abort();
-			return false;
-		}
-
-		if ( s.global )
-			jQuery.event.trigger("ajaxSend", [xhr, s]);
-
-		// Wait for a response to come back
-		var onreadystatechange = function(isTimeout){
-			// The transfer is complete and the data is available, or the request timed out
-			if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
-				requestDone = true;
-
-				// clear poll interval
-				if (ival) {
-					clearInterval(ival);
-					ival = null;
-				}
-
-				status = isTimeout == "timeout" && "timeout" ||
-					!jQuery.httpSuccess( xhr ) && "error" ||
-					s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
-					"success";
-
-				if ( status == "success" ) {
-					// Watch for, and catch, XML document parse errors
-					try {
-						// process the data (runs the xml through httpData regardless of callback)
-						data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
-					} catch(e) {
-						status = "parsererror";
-					}
-				}
-
-				// Make sure that the request was successful or notmodified
-				if ( status == "success" ) {
-					// Cache Last-Modified header, if ifModified mode.
-					var modRes;
-					try {
-						modRes = xhr.getResponseHeader("Last-Modified");
-					} catch(e) {} // swallow exception thrown by FF if header is not available
-
-					if ( s.ifModified && modRes )
-						jQuery.lastModified[s.url] = modRes;
-
-					// JSONP handles its own success callback
-					if ( !jsonp )
-						success();
-				} else
-					jQuery.handleError(s, xhr, status);
-
-				// Fire the complete handlers
-				complete();
-
-				// Stop memory leaks
-				if ( s.async )
-					xhr = null;
-			}
-		};
-
-		if ( s.async ) {
-			// don't attach the handler to the request, just poll it instead
-			var ival = setInterval(onreadystatechange, 13);
-
-			// Timeout checker
-			if ( s.timeout > 0 )
-				setTimeout(function(){
-					// Check to see if the request is still happening
-					if ( xhr ) {
-						// Cancel the request
-						xhr.abort();
-
-						if( !requestDone )
-							onreadystatechange( "timeout" );
-					}
-				}, s.timeout);
-		}
-
-		// Send the data
-		try {
-			xhr.send(s.data);
-		} catch(e) {
-			jQuery.handleError(s, xhr, null, e);
-		}
-
-		// firefox 1.5 doesn't fire statechange for sync requests
-		if ( !s.async )
-			onreadystatechange();
-
-		function success(){
-			// If a local callback was specified, fire it and pass it the data
-			if ( s.success )
-				s.success( data, status );
-
-			// Fire the global callback
-			if ( s.global )
-				jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
-		}
-
-		function complete(){
-			// Process result
-			if ( s.complete )
-				s.complete(xhr, status);
-
-			// The request was completed
-			if ( s.global )
-				jQuery.event.trigger( "ajaxComplete", [xhr, s] );
-
-			// Handle the global AJAX counter
-			if ( s.global && ! --jQuery.active )
-				jQuery.event.trigger( "ajaxStop" );
-		}
-
-		// return XMLHttpRequest to allow aborting the request etc.
-		return xhr;
-	},
-
-	handleError: function( s, xhr, status, e ) {
-		// If a local callback was specified, fire it
-		if ( s.error ) s.error( xhr, status, e );
-
-		// Fire the global callback
-		if ( s.global )
-			jQuery.event.trigger( "ajaxError", [xhr, s, e] );
-	},
-
-	// Counter for holding the number of active queries
-	active: 0,
-
-	// Determines if an XMLHttpRequest was successful or not
-	httpSuccess: function( xhr ) {
-		try {
-			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
-			return !xhr.status && location.protocol == "file:" ||
-				( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
-				jQuery.browser.safari && xhr.status == undefined;
-		} catch(e){}
-		return false;
-	},
-
-	// Determines if an XMLHttpRequest returns NotModified
-	httpNotModified: function( xhr, url ) {
-		try {
-			var xhrRes = xhr.getResponseHeader("Last-Modified");
-
-			// Firefox always returns 200. check Last-Modified date
-			return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
-				jQuery.browser.safari && xhr.status == undefined;
-		} catch(e){}
-		return false;
-	},
-
-	httpData: function( xhr, type, filter ) {
-		var ct = xhr.getResponseHeader("content-type"),
-			xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
-			data = xml ? xhr.responseXML : xhr.responseText;
-
-		if ( xml && data.documentElement.tagName == "parsererror" )
-			throw "parsererror";
-			
-		// Allow a pre-filtering function to sanitize the response
-		if( filter )
-			data = filter( data, type );
-
-		// If the type is "script", eval it in global context
-		if ( type == "script" )
-			jQuery.globalEval( data );
-
-		// Get the JavaScript object, if JSON is used.
-		if ( type == "json" )
-			data = eval("(" + data + ")");
-
-		return data;
-	},
-
-	// Serialize an array of form elements or a set of
-	// key/values into a query string
-	param: function( a ) {
-		var s = [];
-
-		// If an array was passed in, assume that it is an array
-		// of form elements
-		if ( a.constructor == Array || a.jquery )
-			// Serialize the form elements
-			jQuery.each( a, function(){
-				s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
-			});
-
-		// Otherwise, assume that it's an object of key/value pairs
-		else
-			// Serialize the key/values
-			for ( var j in a )
-				// If the value is an array then the key names need to be repeated
-				if ( a[j] && a[j].constructor == Array )
-					jQuery.each( a[j], function(){
-						s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
-					});
-				else
-					s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );
-
-		// Return the resulting serialization
-		return s.join("&").replace(/%20/g, "+");
-	}
-
-});
-jQuery.fn.extend({
-	show: function(speed,callback){
-		return speed ?
-			this.animate({
-				height: "show", width: "show", opacity: "show"
-			}, speed, callback) :
-
-			this.filter(":hidden").each(function(){
-				this.style.display = this.oldblock || "";
-				if ( jQuery.css(this,"display") == "none" ) {
-					var elem = jQuery("<" + this.tagName + " />").appendTo("body");
-					this.style.display = elem.css("display");
-					// handle an edge condition where css is - div { display:none; } or similar
-					if (this.style.display == "none")
-						this.style.display = "block";
-					elem.remove();
-				}
-			}).end();
-	},
-
-	hide: function(speed,callback){
-		return speed ?
-			this.animate({
-				height: "hide", width: "hide", opacity: "hide"
-			}, speed, callback) :
-
-			this.filter(":visible").each(function(){
-				this.oldblock = this.oldblock || jQuery.css(this,"display");
-				this.style.display = "none";
-			}).end();
-	},
-
-	// Save the old toggle function
-	_toggle: jQuery.fn.toggle,
-
-	toggle: function( fn, fn2 ){
-		return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
-			this._toggle.apply( this, arguments ) :
-			fn ?
-				this.animate({
-					height: "toggle", width: "toggle", opacity: "toggle"
-				}, fn, fn2) :
-				this.each(function(){
-					jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
-				});
-	},
-
-	slideDown: function(speed,callback){
-		return this.animate({height: "show"}, speed, callback);
-	},
-
-	slideUp: function(speed,callback){
-		return this.animate({height: "hide"}, speed, callback);
-	},
-
-	slideToggle: function(speed, callback){
-		return this.animate({height: "toggle"}, speed, callback);
-	},
-
-	fadeIn: function(speed, callback){
-		return this.animate({opacity: "show"}, speed, callback);
-	},
-
-	fadeOut: function(speed, callback){
-		return this.animate({opacity: "hide"}, speed, callback);
-	},
-
-	fadeTo: function(speed,to,callback){
-		return this.animate({opacity: to}, speed, callback);
-	},
-
-	animate: function( prop, speed, easing, callback ) {
-		var optall = jQuery.speed(speed, easing, callback);
-
-		return this[ optall.queue === false ? "each" : "queue" ](function(){
-			if ( this.nodeType != 1)
-				return false;
-
-			var opt = jQuery.extend({}, optall), p,
-				hidden = jQuery(this).is(":hidden"), self = this;
-
-			for ( p in prop ) {
-				if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
-					return opt.complete.call(this);
-
-				if ( p == "height" || p == "width" ) {
-					// Store display property
-					opt.display = jQuery.css(this, "display");
-
-					// Make sure that nothing sneaks out
-					opt.overflow = this.style.overflow;
-				}
-			}
-
-			if ( opt.overflow != null )
-				this.style.overflow = "hidden";
-
-			opt.curAnim = jQuery.extend({}, prop);
-
-			jQuery.each( prop, function(name, val){
-				var e = new jQuery.fx( self, opt, name );
-
-				if ( /toggle|show|hide/.test(val) )
-					e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
-				else {
-					var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
-						start = e.cur(true) || 0;
-
-					if ( parts ) {
-						var end = parseFloat(parts[2]),
-							unit = parts[3] || "px";
-
-						// We need to compute starting value
-						if ( unit != "px" ) {
-							self.style[ name ] = (end || 1) + unit;
-							start = ((end || 1) / e.cur(true)) * start;
-							self.style[ name ] = start + unit;
-						}
-
-						// If a +=/-= token was provided, we're doing a relative animation
-						if ( parts[1] )
-							end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
-
-						e.custom( start, end, unit );
-					} else
-						e.custom( start, val, "" );
-				}
-			});
-
-			// For JS strict compliance
-			return true;
-		});
-	},
-
-	queue: function(type, fn){
-		if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
-			fn = type;
-			type = "fx";
-		}
-
-		if ( !type || (typeof type == "string" && !fn) )
-			return queue( this[0], type );
-
-		return this.each(function(){
-			if ( fn.constructor == Array )
-				queue(this, type, fn);
-			else {
-				queue(this, type).push( fn );
-
-				if ( queue(this, type).length == 1 )
-					fn.call(this);
-			}
-		});
-	},
-
-	stop: function(clearQueue, gotoEnd){
-		var timers = jQuery.timers;
-
-		if (clearQueue)
-			this.queue([]);
-
-		this.each(function(){
-			// go in reverse order so anything added to the queue during the loop is ignored
-			for ( var i = timers.length - 1; i >= 0; i-- )
-				if ( timers[i].elem == this ) {
-					if (gotoEnd)
-						// force the next step to be the last
-						timers[i](true);
-					timers.splice(i, 1);
-				}
-		});
-
-		// start the next in the queue if the last step wasn't forced
-		if (!gotoEnd)
-			this.dequeue();
-
-		return this;
-	}
-
-});
-
-var queue = function( elem, type, array ) {
-	if ( elem ){
-
-		type = type || "fx";
-
-		var q = jQuery.data( elem, type + "queue" );
-
-		if ( !q || array )
-			q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
-
-	}
-	return q;
-};
-
-jQuery.fn.dequeue = function(type){
-	type = type || "fx";
-
-	return this.each(function(){
-		var q = queue(this, type);
-
-		q.shift();
-
-		if ( q.length )
-			q[0].call( this );
-	});
-};
-
-jQuery.extend({
-
-	speed: function(speed, easing, fn) {
-		var opt = speed && speed.constructor == Object ? speed : {
-			complete: fn || !fn && easing ||
-				jQuery.isFunction( speed ) && speed,
-			duration: speed,
-			easing: fn && easing || easing && easing.constructor != Function && easing
-		};
-
-		opt.duration = (opt.duration && opt.duration.constructor == Number ?
-			opt.duration :
-			jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
-
-		// Queueing
-		opt.old = opt.complete;
-		opt.complete = function(){
-			if ( opt.queue !== false )
-				jQuery(this).dequeue();
-			if ( jQuery.isFunction( opt.old ) )
-				opt.old.call( this );
-		};
-
-		return opt;
-	},
-
-	easing: {
-		linear: function( p, n, firstNum, diff ) {
-			return firstNum + diff * p;
-		},
-		swing: function( p, n, firstNum, diff ) {
-			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
-		}
-	},
-
-	timers: [],
-	timerId: null,
-
-	fx: function( elem, options, prop ){
-		this.options = options;
-		this.elem = elem;
-		this.prop = prop;
-
-		if ( !options.orig )
-			options.orig = {};
-	}
-
-});
-
-jQuery.fx.prototype = {
-
-	// Simple function for setting a style value
-	update: function(){
-		if ( this.options.step )
-			this.options.step.call( this.elem, this.now, this );
-
-		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
-
-		// Set display property to block for height/width animations
-		if ( this.prop == "height" || this.prop == "width" )
-			this.elem.style.display = "block";
-	},
-
-	// Get the current size
-	cur: function(force){
-		if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
-			return this.elem[ this.prop ];
-
-		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
-		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
-	},
-
-	// Start an animation from one number to another
-	custom: function(from, to, unit){
-		this.startTime = now();
-		this.start = from;
-		this.end = to;
-		this.unit = unit || this.unit || "px";
-		this.now = this.start;
-		this.pos = this.state = 0;
-		this.update();
-
-		var self = this;
-		function t(gotoEnd){
-			return self.step(gotoEnd);
-		}
-
-		t.elem = this.elem;
-
-		jQuery.timers.push(t);
-
-		if ( jQuery.timerId == null ) {
-			jQuery.timerId = setInterval(function(){
-				var timers = jQuery.timers;
-
-				for ( var i = 0; i < timers.length; i++ )
-					if ( !timers[i]() )
-						timers.splice(i--, 1);
-
-				if ( !timers.length ) {
-					clearInterval( jQuery.timerId );
-					jQuery.timerId = null;
-				}
-			}, 13);
-		}
-	},
-
-	// Simple 'show' function
-	show: function(){
-		// Remember where we started, so that we can go back to it later
-		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
-		this.options.show = true;
-
-		// Begin the animation
-		this.custom(0, this.cur());
-
-		// Make sure that we start at a small width/height to avoid any
-		// flash of content
-		if ( this.prop == "width" || this.prop == "height" )
-			this.elem.style[this.prop] = "1px";
-
-		// Start by showing the element
-		jQuery(this.elem).show();
-	},
-
-	// Simple 'hide' function
-	hide: function(){
-		// Remember where we started, so that we can go back to it later
-		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
-		this.options.hide = true;
-
-		// Begin the animation
-		this.custom(this.cur(), 0);
-	},
-
-	// Each step of an animation
-	step: function(gotoEnd){
-		var t = now();
-
-		if ( gotoEnd || t > this.options.duration + this.startTime ) {
-			this.now = this.end;
-			this.pos = this.state = 1;
-			this.update();
-
-			this.options.curAnim[ this.prop ] = true;
-
-			var done = true;
-			for ( var i in this.options.curAnim )
-				if ( this.options.curAnim[i] !== true )
-					done = false;
-
-			if ( done ) {
-				if ( this.options.display != null ) {
-					// Reset the overflow
-					this.elem.style.overflow = this.options.overflow;
-
-					// Reset the display
-					this.elem.style.display = this.options.display;
-					if ( jQuery.css(this.elem, "display") == "none" )
-						this.elem.style.display = "block";
-				}
-
-				// Hide the element if the "hide" operation was done
-				if ( this.options.hide )
-					this.elem.style.display = "none";
-
-				// Reset the properties, if the item has been hidden or shown
-				if ( this.options.hide || this.options.show )
-					for ( var p in this.options.curAnim )
-						jQuery.attr(this.elem.style, p, this.options.orig[p]);
-			}
-
-			if ( done )
-				// Execute the complete function
-				this.options.complete.call( this.elem );
-
-			return false;
-		} else {
-			var n = t - this.startTime;
-			this.state = n / this.options.duration;
-
-			// Perform the easing function, defaults to swing
-			this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
-			this.now = this.start + ((this.end - this.start) * this.pos);
-
-			// Perform the next step of the animation
-			this.update();
-		}
-
-		return true;
-	}
-
-};
-
-jQuery.extend( jQuery.fx, {
-	speeds:{
-		slow: 600,
- 		fast: 200,
- 		// Default speed
- 		def: 400
-	},
-	step: {
-		scrollLeft: function(fx){
-			fx.elem.scrollLeft = fx.now;
-		},
-
-		scrollTop: function(fx){
-			fx.elem.scrollTop = fx.now;
-		},
-
-		opacity: function(fx){
-			jQuery.attr(fx.elem.style, "opacity", fx.now);
-		},
-
-		_default: function(fx){
-			fx.elem.style[ fx.prop ] = fx.now + fx.unit;
-		}
-	}
-});
-// The Offset Method
-// Originally By Brandon Aaron, part of the Dimension Plugin
-// http://jquery.com/plugins/project/dimensions
-jQuery.fn.offset = function() {
-	var left = 0, top = 0, elem = this[0], results;
-
-	if ( elem ) with ( jQuery.browser ) {
-		var parent       = elem.parentNode,
-		    offsetChild  = elem,
-		    offsetParent = elem.offsetParent,
-		    doc          = elem.ownerDocument,
-		    safari2      = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
-		    css          = jQuery.curCSS,
-		    fixed        = css(elem, "position") == "fixed";
-
-		// Use getBoundingClientRect if available
-		if ( elem.getBoundingClientRect ) {
-			var box = elem.getBoundingClientRect();
-
-			// Add the document scroll offsets
-			add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
-				box.top  + Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
-
-			// IE adds the HTML element's border, by default it is medium which is 2px
-			// IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
-			// IE 7 standards mode, the border is always 2px
-			// This border/offset is typically represented by the clientLeft and clientTop properties
-			// However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
-			// Therefore this method will be off by 2px in IE while in quirksmode
-			add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
-
-		// Otherwise loop through the offsetParents and parentNodes
-		} else {
-
-			// Initial element offsets
-			add( elem.offsetLeft, elem.offsetTop );
-
-			// Get parent offsets
-			while ( offsetParent ) {
-				// Add offsetParent offsets
-				add( offsetParent.offsetLeft, offsetParent.offsetTop );
-
-				// Mozilla and Safari > 2 does not include the border on offset parents
-				// However Mozilla adds the border for table or table cells
-				if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
-					border( offsetParent );
-
-				// Add the document scroll offsets if position is fixed on any offsetParent
-				if ( !fixed && css(offsetParent, "position") == "fixed" )
-					fixed = true;
-
-				// Set offsetChild to previous offsetParent unless it is the body element
-				offsetChild  = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
-				// Get next offsetParent
-				offsetParent = offsetParent.offsetParent;
-			}
-
-			// Get parent scroll offsets
-			while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
-				// Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
-				if ( !/^inline|table.*$/i.test(css(parent, "display")) )
-					// Subtract parent scroll offsets
-					add( -parent.scrollLeft, -parent.scrollTop );
-
-				// Mozilla does not add the border for a parent that has overflow != visible
-				if ( mozilla && css(parent, "overflow") != "visible" )
-					border( parent );
-
-				// Get next parent
-				parent = parent.parentNode;
-			}
-
-			// Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
-			// Mozilla doubles body offsets with a non-absolutely positioned offsetChild
-			if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
-				(mozilla && css(offsetChild, "position") != "absolute") )
-					add( -doc.body.offsetLeft, -doc.body.offsetTop );
-
-			// Add the document scroll offsets if position is fixed
-			if ( fixed )
-				add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
-					Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
-		}
-
-		// Return an object with top and left properties
-		results = { top: top, left: left };
-	}
-
-	function border(elem) {
-		add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
-	}
-
-	function add(l, t) {
-		left += parseInt(l, 10) || 0;
-		top += parseInt(t, 10) || 0;
-	}
-
-	return results;
-};
-
-
-jQuery.fn.extend({
-	position: function() {
-		var left = 0, top = 0, results;
-
-		if ( this[0] ) {
-			// Get *real* offsetParent
-			var offsetParent = this.offsetParent(),
-
-			// Get correct offsets
-			offset       = this.offset(),
-			parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
-
-			// Subtract element margins
-			// note: when an element has margin: auto the offsetLeft and marginLeft 
-			// are the same in Safari causing offset.left to incorrectly be 0
-			offset.top  -= num( this, 'marginTop' );
-			offset.left -= num( this, 'marginLeft' );
-
-			// Add offsetParent borders
-			parentOffset.top  += num( offsetParent, 'borderTopWidth' );
-			parentOffset.left += num( offsetParent, 'borderLeftWidth' );
-
-			// Subtract the two offsets
-			results = {
-				top:  offset.top  - parentOffset.top,
-				left: offset.left - parentOffset.left
-			};
-		}
-
-		return results;
-	},
-
-	offsetParent: function() {
-		var offsetParent = this[0].offsetParent;
-		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
-			offsetParent = offsetParent.offsetParent;
-		return jQuery(offsetParent);
-	}
-});
-
-
-// Create scrollLeft and scrollTop methods
-jQuery.each( ['Left', 'Top'], function(i, name) {
-	var method = 'scroll' + name;
-	
-	jQuery.fn[ method ] = function(val) {
-		if (!this[0]) return;
-
-		return val != undefined ?
-
-			// Set the scroll offset
-			this.each(function() {
-				this == window || this == document ?
-					window.scrollTo(
-						!i ? val : jQuery(window).scrollLeft(),
-						 i ? val : jQuery(window).scrollTop()
-					) :
-					this[ method ] = val;
-			}) :
-
-			// Return the scroll offset
-			this[0] == window || this[0] == document ?
-				self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
-					jQuery.boxModel && document.documentElement[ method ] ||
-					document.body[ method ] :
-				this[0][ method ];
-	};
-});
-// Create innerHeight, innerWidth, outerHeight and outerWidth methods
-jQuery.each([ "Height", "Width" ], function(i, name){
-
-	var tl = i ? "Left"  : "Top",  // top or left
-		br = i ? "Right" : "Bottom"; // bottom or right
-
-	// innerHeight and innerWidth
-	jQuery.fn["inner" + name] = function(){
-		return this[ name.toLowerCase() ]() +
-			num(this, "padding" + tl) +
-			num(this, "padding" + br);
-	};
-
-	// outerHeight and outerWidth
-	jQuery.fn["outer" + name] = function(margin) {
-		return this["inner" + name]() +
-			num(this, "border" + tl + "Width") +
-			num(this, "border" + br + "Width") +
-			(margin ?
-				num(this, "margin" + tl) + num(this, "margin" + br) : 0);
-	};
-
-});})();

+ 0 - 61
tests/xhprof/xhprof_html/jquery/jquery.autocomplete.css

@@ -1,61 +0,0 @@
-/*
- * Autocomplete - jQuery plugin 1.0.2
- *
- * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
- *
- * Dual licensed under the MIT and GPL licenses:
- *   http://www.opensource.org/licenses/mit-license.php
- *   http://www.gnu.org/licenses/gpl.html
- *
- * Revision: $Id: jquery.autocomplete.css,v 1.1.1.1 2009/03/17 18:35:18 kannan Exp $
- *
- */
-
-.ac_results {
-	padding: 0px;
-	border: 1px solid black;
-	background-color: white;
-	overflow: hidden;
-	z-index: 99999;
-}
-
-.ac_results ul {
-	width: 100%;
-	list-style-position: outside;
-	list-style: none;
-	padding: 0;
-	margin: 0;
-}
-
-.ac_results li {
-	margin: 0px;
-	padding: 2px 5px;
-	cursor: default;
-	display: block;
-	/*
-	if width will be 100% horizontal scrollbar will apear
-	when scroll mode will be used
-	*/
-	/*width: 100%;*/
-	font: menu;
-	font-size: 12px;
-	/*
-	it is very important, if line-height not setted or setted
-	in relative units scroll will be broken in firefox
-	*/
-	line-height: 16px;
-	overflow: hidden;
-}
-
-.ac_loading {
-	background: white url('indicator.gif') right center no-repeat;
-}
-
-.ac_odd {
-	background-color: #eee;
-}
-
-.ac_over {
-	background-color: #0A246A;
-	color: white;
-}

+ 0 - 759
tests/xhprof/xhprof_html/jquery/jquery.autocomplete.js

@@ -1,759 +0,0 @@
-/*
- * Autocomplete - jQuery plugin 1.0.2
- *
- * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
- *
- * Dual licensed under the MIT and GPL licenses:
- *   http://www.opensource.org/licenses/mit-license.php
- *   http://www.gnu.org/licenses/gpl.html
- *
- * Revision: $Id: jquery.autocomplete.js,v 1.1.1.1 2009/03/17 18:35:18 kannan Exp $
- *
- */
-
-;(function($) {
-	
-$.fn.extend({
-	autocomplete: function(urlOrData, options) {
-		var isUrl = typeof urlOrData == "string";
-		options = $.extend({}, $.Autocompleter.defaults, {
-			url: isUrl ? urlOrData : null,
-			data: isUrl ? null : urlOrData,
-			delay: isUrl ? $.Autocompleter.defaults.delay : 10,
-			max: options && !options.scroll ? 10 : 150
-		}, options);
-		
-		// if highlight is set to false, replace it with a do-nothing function
-		options.highlight = options.highlight || function(value) { return value; };
-		
-		// if the formatMatch option is not specified, then use formatItem for backwards compatibility
-		options.formatMatch = options.formatMatch || options.formatItem;
-		
-		return this.each(function() {
-			new $.Autocompleter(this, options);
-		});
-	},
-	result: function(handler) {
-		return this.bind("result", handler);
-	},
-	search: function(handler) {
-		return this.trigger("search", [handler]);
-	},
-	flushCache: function() {
-		return this.trigger("flushCache");
-	},
-	setOptions: function(options){
-		return this.trigger("setOptions", [options]);
-	},
-	unautocomplete: function() {
-		return this.trigger("unautocomplete");
-	}
-});
-
-$.Autocompleter = function(input, options) {
-
-	var KEY = {
-		UP: 38,
-		DOWN: 40,
-		DEL: 46,
-		TAB: 9,
-		RETURN: 13,
-		ESC: 27,
-		COMMA: 188,
-		PAGEUP: 33,
-		PAGEDOWN: 34,
-		BACKSPACE: 8
-	};
-
-	// Create $ object for input element
-	var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
-
-	var timeout;
-	var previousValue = "";
-	var cache = $.Autocompleter.Cache(options);
-	var hasFocus = 0;
-	var lastKeyPressCode;
-	var config = {
-		mouseDownOnSelect: false
-	};
-	var select = $.Autocompleter.Select(options, input, selectCurrent, config);
-	
-	var blockSubmit;
-	
-	// prevent form submit in opera when selecting with return key
-	$.browser.opera && $(input.form).bind("submit.autocomplete", function() {
-		if (blockSubmit) {
-			blockSubmit = false;
-			return false;
-		}
-	});
-	
-	// only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
-	$input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
-		// track last key pressed
-		lastKeyPressCode = event.keyCode;
-		switch(event.keyCode) {
-		
-			case KEY.UP:
-				event.preventDefault();
-				if ( select.visible() ) {
-					select.prev();
-				} else {
-					onChange(0, true);
-				}
-				break;
-				
-			case KEY.DOWN:
-				event.preventDefault();
-				if ( select.visible() ) {
-					select.next();
-				} else {
-					onChange(0, true);
-				}
-				break;
-				
-			case KEY.PAGEUP:
-				event.preventDefault();
-				if ( select.visible() ) {
-					select.pageUp();
-				} else {
-					onChange(0, true);
-				}
-				break;
-				
-			case KEY.PAGEDOWN:
-				event.preventDefault();
-				if ( select.visible() ) {
-					select.pageDown();
-				} else {
-					onChange(0, true);
-				}
-				break;
-			
-			// matches also semicolon
-			case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
-			case KEY.TAB:
-			case KEY.RETURN:
-				if( selectCurrent() ) {
-					// stop default to prevent a form submit, Opera needs special handling
-					event.preventDefault();
-					blockSubmit = true;
-					return false;
-				}
-				break;
-				
-			case KEY.ESC:
-				select.hide();
-				break;
-				
-			default:
-				clearTimeout(timeout);
-				timeout = setTimeout(onChange, options.delay);
-				break;
-		}
-	}).focus(function(){
-		// track whether the field has focus, we shouldn't process any
-		// results if the field no longer has focus
-		hasFocus++;
-	}).blur(function() {
-		hasFocus = 0;
-		if (!config.mouseDownOnSelect) {
-			hideResults();
-		}
-	}).click(function() {
-		// show select when clicking in a focused field
-		if ( hasFocus++ > 1 && !select.visible() ) {
-			onChange(0, true);
-		}
-	}).bind("search", function() {
-		// TODO why not just specifying both arguments?
-		var fn = (arguments.length > 1) ? arguments[1] : null;
-		function findValueCallback(q, data) {
-			var result;
-			if( data && data.length ) {
-				for (var i=0; i < data.length; i++) {
-					if( data[i].result.toLowerCase() == q.toLowerCase() ) {
-						result = data[i];
-						break;
-					}
-				}
-			}
-			if( typeof fn == "function" ) fn(result);
-			else $input.trigger("result", result && [result.data, result.value]);
-		}
-		$.each(trimWords($input.val()), function(i, value) {
-			request(value, findValueCallback, findValueCallback);
-		});
-	}).bind("flushCache", function() {
-		cache.flush();
-	}).bind("setOptions", function() {
-		$.extend(options, arguments[1]);
-		// if we've updated the data, repopulate
-		if ( "data" in arguments[1] )
-			cache.populate();
-	}).bind("unautocomplete", function() {
-		select.unbind();
-		$input.unbind();
-		$(input.form).unbind(".autocomplete");
-	});
-	
-	
-	function selectCurrent() {
-		var selected = select.selected();
-		if( !selected )
-			return false;
-		
-		var v = selected.result;
-		previousValue = v;
-		
-		if ( options.multiple ) {
-			var words = trimWords($input.val());
-			if ( words.length > 1 ) {
-				v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
-			}
-			v += options.multipleSeparator;
-		}
-		
-		$input.val(v);
-		hideResultsNow();
-		$input.trigger("result", [selected.data, selected.value]);
-		return true;
-	}
-	
-	function onChange(crap, skipPrevCheck) {
-		if( lastKeyPressCode == KEY.DEL ) {
-			select.hide();
-			return;
-		}
-		
-		var currentValue = $input.val();
-		
-		if ( !skipPrevCheck && currentValue == previousValue )
-			return;
-		
-		previousValue = currentValue;
-		
-		currentValue = lastWord(currentValue);
-		if ( currentValue.length >= options.minChars) {
-			$input.addClass(options.loadingClass);
-			if (!options.matchCase)
-				currentValue = currentValue.toLowerCase();
-			request(currentValue, receiveData, hideResultsNow);
-		} else {
-			stopLoading();
-			select.hide();
-		}
-	};
-	
-	function trimWords(value) {
-		if ( !value ) {
-			return [""];
-		}
-		var words = value.split( options.multipleSeparator );
-		var result = [];
-		$.each(words, function(i, value) {
-			if ( $.trim(value) )
-				result[i] = $.trim(value);
-		});
-		return result;
-	}
-	
-	function lastWord(value) {
-		if ( !options.multiple )
-			return value;
-		var words = trimWords(value);
-		return words[words.length - 1];
-	}
-	
-	// fills in the input box w/the first match (assumed to be the best match)
-	// q: the term entered
-	// sValue: the first matching result
-	function autoFill(q, sValue){
-		// autofill in the complete box w/the first match as long as the user hasn't entered in more data
-		// if the last user key pressed was backspace, don't autofill
-		if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
-			// fill in the value (keep the case the user has typed)
-			$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
-			// select the portion of the value not typed by the user (so the next character will erase)
-			$.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
-		}
-	};
-
-	function hideResults() {
-		clearTimeout(timeout);
-		timeout = setTimeout(hideResultsNow, 200);
-	};
-
-	function hideResultsNow() {
-		var wasVisible = select.visible();
-		select.hide();
-		clearTimeout(timeout);
-		stopLoading();
-		if (options.mustMatch) {
-			// call search and run callback
-			$input.search(
-				function (result){
-					// if no value found, clear the input box
-					if( !result ) {
-						if (options.multiple) {
-							var words = trimWords($input.val()).slice(0, -1);
-							$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
-						}
-						else
-							$input.val( "" );
-					}
-				}
-			);
-		}
-		if (wasVisible)
-			// position cursor at end of input field
-			$.Autocompleter.Selection(input, input.value.length, input.value.length);
-	};
-
-	function receiveData(q, data) {
-		if ( data && data.length && hasFocus ) {
-			stopLoading();
-			select.display(data, q);
-			autoFill(q, data[0].value);
-			select.show();
-		} else {
-			hideResultsNow();
-		}
-	};
-
-	function request(term, success, failure) {
-		if (!options.matchCase)
-			term = term.toLowerCase();
-		var data = cache.load(term);
-		// recieve the cached data
-		if (data && data.length) {
-			success(term, data);
-		// if an AJAX url has been supplied, try loading the data now
-		} else if( (typeof options.url == "string") && (options.url.length > 0) ){
-			
-			var extraParams = {
-				timestamp: +new Date()
-			};
-			$.each(options.extraParams, function(key, param) {
-				extraParams[key] = typeof param == "function" ? param() : param;
-			});
-			
-			$.ajax({
-				// try to leverage ajaxQueue plugin to abort previous requests
-				mode: "abort",
-				// limit abortion to this input
-				port: "autocomplete" + input.name,
-				dataType: options.dataType,
-				url: options.url,
-				data: $.extend({
-					q: lastWord(term),
-					limit: options.max
-				}, extraParams),
-				success: function(data) {
-					var parsed = options.parse && options.parse(data) || parse(data);
-					cache.add(term, parsed);
-					success(term, parsed);
-				}
-			});
-		} else {
-			// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
-			select.emptyList();
-			failure(term);
-		}
-	};
-	
-	function parse(data) {
-		var parsed = [];
-		var rows = data.split("\n");
-		for (var i=0; i < rows.length; i++) {
-			var row = $.trim(rows[i]);
-			if (row) {
-				row = row.split("|");
-				parsed[parsed.length] = {
-					data: row,
-					value: row[0],
-					result: options.formatResult && options.formatResult(row, row[0]) || row[0]
-				};
-			}
-		}
-		return parsed;
-	};
-
-	function stopLoading() {
-		$input.removeClass(options.loadingClass);
-	};
-
-};
-
-$.Autocompleter.defaults = {
-	inputClass: "ac_input",
-	resultsClass: "ac_results",
-	loadingClass: "ac_loading",
-	minChars: 1,
-	delay: 400,
-	matchCase: false,
-	matchSubset: true,
-	matchContains: false,
-	cacheLength: 10,
-	max: 100,
-	mustMatch: false,
-	extraParams: {},
-	selectFirst: true,
-	formatItem: function(row) { return row[0]; },
-	formatMatch: null,
-	autoFill: false,
-	width: 0,
-	multiple: false,
-	multipleSeparator: ", ",
-	highlight: function(value, term) {
-		return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
-	},
-    scroll: true,
-    scrollHeight: 180
-};
-
-$.Autocompleter.Cache = function(options) {
-
-	var data = {};
-	var length = 0;
-	
-	function matchSubset(s, sub) {
-		if (!options.matchCase) 
-			s = s.toLowerCase();
-		var i = s.indexOf(sub);
-		if (i == -1) return false;
-		return i == 0 || options.matchContains;
-	};
-	
-	function add(q, value) {
-		if (length > options.cacheLength){
-			flush();
-		}
-		if (!data[q]){ 
-			length++;
-		}
-		data[q] = value;
-	}
-	
-	function populate(){
-		if( !options.data ) return false;
-		// track the matches
-		var stMatchSets = {},
-			nullData = 0;
-
-		// no url was specified, we need to adjust the cache length to make sure it fits the local data store
-		if( !options.url ) options.cacheLength = 1;
-		
-		// track all options for minChars = 0
-		stMatchSets[""] = [];
-		
-		// loop through the array and create a lookup structure
-		for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
-			var rawValue = options.data[i];
-			// if rawValue is a string, make an array otherwise just reference the array
-			rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
-			
-			var value = options.formatMatch(rawValue, i+1, options.data.length);
-			if ( value === false )
-				continue;
-				
-			var firstChar = value.charAt(0).toLowerCase();
-			// if no lookup array for this character exists, look it up now
-			if( !stMatchSets[firstChar] ) 
-				stMatchSets[firstChar] = [];
-
-			// if the match is a string
-			var row = {
-				value: value,
-				data: rawValue,
-				result: options.formatResult && options.formatResult(rawValue) || value
-			};
-			
-			// push the current match into the set list
-			stMatchSets[firstChar].push(row);
-
-			// keep track of minChars zero items
-			if ( nullData++ < options.max ) {
-				stMatchSets[""].push(row);
-			}
-		};
-
-		// add the data items to the cache
-		$.each(stMatchSets, function(i, value) {
-			// increase the cache size
-			options.cacheLength++;
-			// add to the cache
-			add(i, value);
-		});
-	}
-	
-	// populate any existing data
-	setTimeout(populate, 25);
-	
-	function flush(){
-		data = {};
-		length = 0;
-	}
-	
-	return {
-		flush: flush,
-		add: add,
-		populate: populate,
-		load: function(q) {
-			if (!options.cacheLength || !length)
-				return null;
-			/* 
-			 * if dealing w/local data and matchContains than we must make sure
-			 * to loop through all the data collections looking for matches
-			 */
-			if( !options.url && options.matchContains ){
-				// track all matches
-				var csub = [];
-				// loop through all the data grids for matches
-				for( var k in data ){
-					// don't search through the stMatchSets[""] (minChars: 0) cache
-					// this prevents duplicates
-					if( k.length > 0 ){
-						var c = data[k];
-						$.each(c, function(i, x) {
-							// if we've got a match, add it to the array
-							if (matchSubset(x.value, q)) {
-								csub.push(x);
-							}
-						});
-					}
-				}				
-				return csub;
-			} else 
-			// if the exact item exists, use it
-			if (data[q]){
-				return data[q];
-			} else
-			if (options.matchSubset) {
-				for (var i = q.length - 1; i >= options.minChars; i--) {
-					var c = data[q.substr(0, i)];
-					if (c) {
-						var csub = [];
-						$.each(c, function(i, x) {
-							if (matchSubset(x.value, q)) {
-								csub[csub.length] = x;
-							}
-						});
-						return csub;
-					}
-				}
-			}
-			return null;
-		}
-	};
-};
-
-$.Autocompleter.Select = function (options, input, select, config) {
-	var CLASSES = {
-		ACTIVE: "ac_over"
-	};
-	
-	var listItems,
-		active = -1,
-		data,
-		term = "",
-		needsInit = true,
-		element,
-		list;
-	
-	// Create results
-	function init() {
-		if (!needsInit)
-			return;
-		element = $("<div/>")
-		.hide()
-		.addClass(options.resultsClass)
-		.css("position", "absolute")
-		.appendTo(document.body);
-	
-		list = $("<ul/>").appendTo(element).mouseover( function(event) {
-			if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
-	            active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
-			    $(target(event)).addClass(CLASSES.ACTIVE);            
-	        }
-		}).click(function(event) {
-			$(target(event)).addClass(CLASSES.ACTIVE);
-			select();
-			// TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
-			input.focus();
-			return false;
-		}).mousedown(function() {
-			config.mouseDownOnSelect = true;
-		}).mouseup(function() {
-			config.mouseDownOnSelect = false;
-		});
-		
-		if( options.width > 0 )
-			element.css("width", options.width);
-			
-		needsInit = false;
-	} 
-	
-	function target(event) {
-		var element = event.target;
-		while(element && element.tagName != "LI")
-			element = element.parentNode;
-		// more fun with IE, sometimes event.target is empty, just ignore it then
-		if(!element)
-			return [];
-		return element;
-	}
-
-	function moveSelect(step) {
-		listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
-		movePosition(step);
-        var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
-        if(options.scroll) {
-            var offset = 0;
-            listItems.slice(0, active).each(function() {
-				offset += this.offsetHeight;
-			});
-            if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
-                list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
-            } else if(offset < list.scrollTop()) {
-                list.scrollTop(offset);
-            }
-        }
-	};
-	
-	function movePosition(step) {
-		active += step;
-		if (active < 0) {
-			active = listItems.size() - 1;
-		} else if (active >= listItems.size()) {
-			active = 0;
-		}
-	}
-	
-	function limitNumberOfItems(available) {
-		return options.max && options.max < available
-			? options.max
-			: available;
-	}
-	
-	function fillList() {
-		list.empty();
-		var max = limitNumberOfItems(data.length);
-		for (var i=0; i < max; i++) {
-			if (!data[i])
-				continue;
-			var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
-			if ( formatted === false )
-				continue;
-			var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
-			$.data(li, "ac_data", data[i]);
-		}
-		listItems = list.find("li");
-		if ( options.selectFirst ) {
-			listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
-			active = 0;
-		}
-		// apply bgiframe if available
-		if ( $.fn.bgiframe )
-			list.bgiframe();
-	}
-	
-	return {
-		display: function(d, q) {
-			init();
-			data = d;
-			term = q;
-			fillList();
-		},
-		next: function() {
-			moveSelect(1);
-		},
-		prev: function() {
-			moveSelect(-1);
-		},
-		pageUp: function() {
-			if (active != 0 && active - 8 < 0) {
-				moveSelect( -active );
-			} else {
-				moveSelect(-8);
-			}
-		},
-		pageDown: function() {
-			if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
-				moveSelect( listItems.size() - 1 - active );
-			} else {
-				moveSelect(8);
-			}
-		},
-		hide: function() {
-			element && element.hide();
-			listItems && listItems.removeClass(CLASSES.ACTIVE);
-			active = -1;
-		},
-		visible : function() {
-			return element && element.is(":visible");
-		},
-		current: function() {
-			return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
-		},
-		show: function() {
-			var offset = $(input).offset();
-			element.css({
-				width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
-				top: offset.top + input.offsetHeight,
-				left: offset.left
-			}).show();
-            if(options.scroll) {
-                list.scrollTop(0);
-                list.css({
-					maxHeight: options.scrollHeight,
-					overflow: 'auto'
-				});
-				
-                if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
-					var listHeight = 0;
-					listItems.each(function() {
-						listHeight += this.offsetHeight;
-					});
-					var scrollbarsVisible = listHeight > options.scrollHeight;
-                    list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
-					if (!scrollbarsVisible) {
-						// IE doesn't recalculate width when scrollbar disappears
-						listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
-					}
-                }
-                
-            }
-		},
-		selected: function() {
-			var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
-			return selected && selected.length && $.data(selected[0], "ac_data");
-		},
-		emptyList: function (){
-			list && list.empty();
-		},
-		unbind: function() {
-			element && element.remove();
-		}
-	};
-};
-
-$.Autocompleter.Selection = function(field, start, end) {
-	if( field.createTextRange ){
-		var selRange = field.createTextRange();
-		selRange.collapse(true);
-		selRange.moveStart("character", start);
-		selRange.moveEnd("character", end);
-		selRange.select();
-	} else if( field.setSelectionRange ){
-		field.setSelectionRange(start, end);
-	} else {
-		if( field.selectionStart ){
-			field.selectionStart = start;
-			field.selectionEnd = end;
-		}
-	}
-	field.focus();
-};
-
-})(jQuery);

+ 0 - 24
tests/xhprof/xhprof_html/jquery/jquery.tooltip.css

@@ -1,24 +0,0 @@
-/*
- * jQuery Tooltip plugin 1.3
- *
- * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
- * http://docs.jquery.com/Plugins/Tooltip
- *
- * Copyright (c) 2006 - 2008 Jörn Zaefferer
- *
- * $Id: jquery.tooltip.css,v 1.1.1.1 2009/03/17 18:35:18 kannan Exp $
- *
- * Dual licensed under the MIT and GPL licenses:
- *   http://www.opensource.org/licenses/mit-license.php
- *   http://www.gnu.org/licenses/gpl.html
- */
-
- #tooltip {
-	position: absolute;
-	z-index: 3000;
-	border: 1px solid #111;
-	background-color: lightyellow;
-	padding: 5px;
-	opacity: 0.9;
-}
-#tooltip h3, #tooltip div { margin: 0; }

+ 0 - 294
tests/xhprof/xhprof_html/jquery/jquery.tooltip.js

@@ -1,294 +0,0 @@
-/*
- * jQuery Tooltip plugin 1.3
- *
- * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
- * http://docs.jquery.com/Plugins/Tooltip
- *
- * Copyright (c) 2006 - 2008 Jörn Zaefferer
- *
- * $Id: jquery.tooltip.js,v 1.1.1.1 2009/03/17 18:35:18 kannan Exp $
- * 
- * Dual licensed under the MIT and GPL licenses:
- *   http://www.opensource.org/licenses/mit-license.php
- *   http://www.gnu.org/licenses/gpl.html
- */
- 
-;(function($) {
-	
-		// the tooltip element
-	var helper = {},
-		// the current tooltipped element
-		current,
-		// the title of the current element, used for restoring
-		title,
-		// timeout id for delayed tooltips
-		tID,
-		// IE 5.5 or 6
-		IE = $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),
-		// flag for mouse tracking
-		track = false;
-	
-	$.tooltip = {
-		blocked: false,
-		defaults: {
-			delay: 200,
-			fade: false,
-			showURL: true,
-			extraClass: "",
-			top: 15,
-			left: 15,
-			id: "tooltip"
-		},
-		block: function() {
-			$.tooltip.blocked = !$.tooltip.blocked;
-		}
-	};
-	
-	$.fn.extend({
-		tooltip: function(settings) {
-			settings = $.extend({}, $.tooltip.defaults, settings);
-			createHelper(settings);
-			return this.each(function() {
-					$.data(this, "tooltip", settings);
-					this.tOpacity = helper.parent.css("opacity");
-					// copy tooltip into its own expando and remove the title
-					this.tooltipText = this.title;
-					$(this).removeAttr("title");
-					// also remove alt attribute to prevent default tooltip in IE
-					this.alt = "";
-				})
-				.mouseover(save)
-				.mouseout(hide)
-				.click(hide);
-		},
-		fixPNG: IE ? function() {
-			return this.each(function () {
-				var image = $(this).css('backgroundImage');
-				if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
-					image = RegExp.$1;
-					$(this).css({
-						'backgroundImage': 'none',
-						'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
-					}).each(function () {
-						var position = $(this).css('position');
-						if (position != 'absolute' && position != 'relative')
-							$(this).css('position', 'relative');
-					});
-				}
-			});
-		} : function() { return this; },
-		unfixPNG: IE ? function() {
-			return this.each(function () {
-				$(this).css({'filter': '', backgroundImage: ''});
-			});
-		} : function() { return this; },
-		hideWhenEmpty: function() {
-			return this.each(function() {
-				$(this)[ $(this).html() ? "show" : "hide" ]();
-			});
-		},
-		url: function() {
-			return this.attr('href') || this.attr('src');
-		}
-	});
-	
-	function createHelper(settings) {
-		// there can be only one tooltip helper
-		if( helper.parent )
-			return;
-		// create the helper, h3 for title, div for url
-		helper.parent = $('<div id="' + settings.id + '"><h3></h3><div class="body"></div><div class="url"></div></div>')
-			// add to document
-			.appendTo(document.body)
-			// hide it at first
-			.hide();
-			
-		// apply bgiframe if available
-		if ( $.fn.bgiframe )
-			helper.parent.bgiframe();
-		
-		// save references to title and url elements
-		helper.title = $('h3', helper.parent);
-		helper.body = $('div.body', helper.parent);
-		helper.url = $('div.url', helper.parent);
-	}
-	
-	function settings(element) {
-		return $.data(element, "tooltip");
-	}
-	
-	// main event handler to start showing tooltips
-	function handle(event) {
-		// show helper, either with timeout or on instant
-		if( settings(this).delay )
-			tID = setTimeout(show, settings(this).delay);
-		else
-			show();
-		
-		// if selected, update the helper position when the mouse moves
-		track = !!settings(this).track;
-		$(document.body).bind('mousemove', update);
-			
-		// update at least once
-		update(event);
-	}
-	
-	// save elements title before the tooltip is displayed
-	function save() {
-		// if this is the current source, or it has no title (occurs with click event), stop
-		if ( $.tooltip.blocked || this == current || (!this.tooltipText && !settings(this).bodyHandler) )
-			return;
-
-		// save current
-		current = this;
-		title = this.tooltipText;
-		
-		if ( settings(this).bodyHandler ) {
-			helper.title.hide();
-			var bodyContent = settings(this).bodyHandler.call(this);
-			if (bodyContent.nodeType || bodyContent.jquery) {
-				helper.body.empty().append(bodyContent)
-			} else {
-				helper.body.html( bodyContent );
-			}
-			helper.body.show();
-		} else if ( settings(this).showBody ) {
-			var parts = title.split(settings(this).showBody);
-			helper.title.html(parts.shift()).show();
-			helper.body.empty();
-			for(var i = 0, part; (part = parts[i]); i++) {
-				if(i > 0)
-					helper.body.append("<br/>");
-				helper.body.append(part);
-			}
-			helper.body.hideWhenEmpty();
-		} else {
-			helper.title.html(title).show();
-			helper.body.hide();
-		}
-		
-		// if element has href or src, add and show it, otherwise hide it
-		if( settings(this).showURL && $(this).url() )
-			helper.url.html( $(this).url().replace('http://', '') ).show();
-		else 
-			helper.url.hide();
-		
-		// add an optional class for this tip
-		helper.parent.addClass(settings(this).extraClass);
-
-		// fix PNG background for IE
-		if (settings(this).fixPNG )
-			helper.parent.fixPNG();
-			
-		handle.apply(this, arguments);
-	}
-	
-	// delete timeout and show helper
-	function show() {
-		tID = null;
-		if ((!IE || !$.fn.bgiframe) && settings(current).fade) {
-			if (helper.parent.is(":animated"))
-				helper.parent.stop().show().fadeTo(settings(current).fade, current.tOpacity);
-			else
-				helper.parent.is(':visible') ? helper.parent.fadeTo(settings(current).fade, current.tOpacity) : helper.parent.fadeIn(settings(current).fade);
-		} else {
-			helper.parent.show();
-		}
-		update();
-	}
-	
-	/**
-	 * callback for mousemove
-	 * updates the helper position
-	 * removes itself when no current element
-	 */
-	function update(event)	{
-		if($.tooltip.blocked)
-			return;
-		
-		if (event && event.target.tagName == "OPTION") {
-			return;
-		}
-		
-		// stop updating when tracking is disabled and the tooltip is visible
-		if ( !track && helper.parent.is(":visible")) {
-			$(document.body).unbind('mousemove', update)
-		}
-		
-		// if no current element is available, remove this listener
-		if( current == null ) {
-			$(document.body).unbind('mousemove', update);
-			return;	
-		}
-		
-		// remove position helper classes
-		helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");
-		
-		var left = helper.parent[0].offsetLeft;
-		var top = helper.parent[0].offsetTop;
-		if (event) {
-			// position the helper 15 pixel to bottom right, starting from mouse position
-			left = event.pageX + settings(current).left;
-			top = event.pageY + settings(current).top;
-			var right='auto';
-			if (settings(current).positionLeft) {
-				right = $(window).width() - left;
-				left = 'auto';
-			}
-			helper.parent.css({
-				left: left,
-				right: right,
-				top: top
-			});
-		}
-		
-		var v = viewport(),
-			h = helper.parent[0];
-		// check horizontal position
-		if (v.x + v.cx < h.offsetLeft + h.offsetWidth) {
-			left -= h.offsetWidth + 20 + settings(current).left;
-			helper.parent.css({left: left + 'px'}).addClass("viewport-right");
-		}
-		// check vertical position
-		if (v.y + v.cy < h.offsetTop + h.offsetHeight) {
-			top -= h.offsetHeight + 20 + settings(current).top;
-			helper.parent.css({top: top + 'px'}).addClass("viewport-bottom");
-		}
-	}
-	
-	function viewport() {
-		return {
-			x: $(window).scrollLeft(),
-			y: $(window).scrollTop(),
-			cx: $(window).width(),
-			cy: $(window).height()
-		};
-	}
-	
-	// hide helper and restore added classes and the title
-	function hide(event) {
-		if($.tooltip.blocked)
-			return;
-		// clear timeout if possible
-		if(tID)
-			clearTimeout(tID);
-		// no more current element
-		current = null;
-		
-		var tsettings = settings(this);
-		function complete() {
-			helper.parent.removeClass( tsettings.extraClass ).hide().css("opacity", "");
-		}
-		if ((!IE || !$.fn.bgiframe) && tsettings.fade) {
-			if (helper.parent.is(':animated'))
-				helper.parent.stop().fadeTo(tsettings.fade, 0, complete);
-			else
-				helper.parent.stop().fadeOut(tsettings.fade, complete);
-		} else
-			complete();
-		
-		if( settings(this).fixPNG )
-			helper.parent.unfixPNG();
-	}
-	
-})(jQuery);

+ 0 - 204
tests/xhprof/xhprof_html/js/xhprof_report.js

@@ -1,204 +0,0 @@
-/*  Copyright (c) 2009 Facebook
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-/**
- * Helper javascript functions for XHProf report tooltips.
- *
- * @author Kannan Muthukkaruppan
- */
-
-// Take a string which is actually a number in comma separated format
-// and return a string representing the absolute value of the number.
-function stringAbs(x) {
-  return x.replace("-", "");
-}
-
-// Takes a number in comma-separated string format, and
-// returns a boolean to indicate if the number is negative
-// or not.
-function isNegative(x) {
-
-  return (x.indexOf("-") == 0);
-
-}
-
-function addCommas(nStr)
-{
-  nStr += '';
-  x = nStr.split('.');
-  x1 = x[0];
-  x2 = x.length > 1 ? '.' + x[1] : '';
-  var rgx = /(\d+)(\d{3})/;
-  while (rgx.test(x1)) {
-    x1 = x1.replace(rgx, '$1' + ',' + '$2');
-  }
-  return x1 + x2;
-}
-
-// Mouseover tips for parent rows in parent/child report..
-function ParentRowToolTip(cell, metric)
-{
-  var metric_val;
-  var parent_metric_val;
-  var parent_metric_pct_val;
-  var col_index;
-  var diff_text;
-
-  row = cell.parentNode;
-  tds = row.getElementsByTagName("td");
-
-  parent_func    = tds[0].innerHTML;  // name
-
-  if (diff_mode) {
-    diff_text = " diff ";
-  } else {
-    diff_text = "";
-  }
-
-  s = '<center>';
-
-  if (metric == "ct") {
-    parent_ct      = tds[1].innerHTML;  // calls
-    parent_ct_pct  = tds[2].innerHTML;
-
-    func_ct = addCommas(func_ct);
-
-    if (diff_mode) {
-      s += 'There are ' + stringAbs(parent_ct) +
-        (isNegative(parent_ct) ? ' fewer ' : ' more ') +
-        ' calls to ' + func_name + ' from ' + parent_func + '<br>';
-
-      text = " of diff in calls ";
-    }  else {
-      text = " of calls ";
-    }
-
-    s += parent_ct_pct + text + '(' + parent_ct + '/' + func_ct + ') to '
-      + func_name + ' are from ' + parent_func + '<br>';
-  } else {
-
-    // help for other metrics such as wall time, user cpu time, memory usage
-    col_index = metrics_col[metric];
-    parent_metric_val     = tds[col_index].innerHTML;
-    parent_metric_pct_val = tds[col_index+1].innerHTML;
-
-    metric_val = addCommas(func_metrics[metric]);
-
-    s += parent_metric_pct_val + '(' + parent_metric_val + '/' + metric_val
-      + ') of ' + metrics_desc[metric] +
-      (diff_mode ? ((isNegative(parent_metric_val) ?
-                    " decrease" : " increase")) : "") +
-      ' in ' + func_name + ' is due to calls from ' + parent_func + '<br>';
-  }
-
-  s += '</center>';
-
-  return s;
-}
-
-// Mouseover tips for child rows in parent/child report..
-function ChildRowToolTip(cell, metric)
-{
-  var metric_val;
-  var child_metric_val;
-  var child_metric_pct_val;
-  var col_index;
-  var diff_text;
-
-  row = cell.parentNode;
-  tds = row.getElementsByTagName("td");
-
-  child_func   = tds[0].innerHTML;  // name
-
-  if (diff_mode) {
-    diff_text = " diff ";
-  } else {
-    diff_text = "";
-  }
-
-  s = '<center>';
-
-  if (metric == "ct") {
-
-    child_ct     = tds[1].innerHTML;  // calls
-    child_ct_pct = tds[2].innerHTML;
-
-    s += func_name + ' called ' + child_func + ' ' + stringAbs(child_ct) +
-      (diff_mode ? (isNegative(child_ct) ? " fewer" : " more") : "" )
-        + ' times.<br>';
-    s += 'This accounts for ' + child_ct_pct + ' (' + child_ct
-        + '/' + total_child_ct
-        + ') of function calls made by '  + func_name + '.';
-
-  } else {
-
-    // help for other metrics such as wall time, user cpu time, memory usage
-    col_index = metrics_col[metric];
-    child_metric_val     = tds[col_index].innerHTML;
-    child_metric_pct_val = tds[col_index+1].innerHTML;
-
-    metric_val = addCommas(func_metrics[metric]);
-
-    if (child_func.indexOf("Exclusive Metrics") != -1) {
-      s += 'The exclusive ' + metrics_desc[metric] + diff_text
-        + ' for ' + func_name
-        + ' is ' + child_metric_val + " <br>";
-
-      s += "which is " + child_metric_pct_val + " of the inclusive "
-        + metrics_desc[metric]
-        + diff_text + " for " + func_name + " (" + metric_val + ").";
-
-    } else {
-
-      s += child_func + ' when called from ' + func_name
-        + ' takes ' + stringAbs(child_metric_val)
-        + (diff_mode ? (isNegative(child_metric_val) ? " less" : " more") : "")
-        + " of " + metrics_desc[metric] + " <br>";
-
-      s += "which is " + child_metric_pct_val + " of the inclusive "
-        + metrics_desc[metric]
-        + diff_text + " for " + func_name + " (" + metric_val + ").";
-    }
-  }
-
-  s += '</center>';
-
-  return s;
-}
-
-$(document).ready(function() {
-  $('td[@metric]').tooltip(
-    { bodyHandler: function() {
-          var type = $(this).attr('type');
-          var metric = $(this).attr('metric');
-          if (type == 'Parent') {
-             return ParentRowToolTip(this, metric);
-          } else if (type == 'Child') {
-             return ChildRowToolTip(this, metric);
-          }
-      },
-      showURL : false
-    });
-  var cur_params = {} ;
-  $.each(location.search.replace('?','').split('&'), function(i, x) {
-    var y = x.split('='); cur_params[y[0]] = y[1];
-  });
-  $('input.function_typeahead')
-    .autocomplete('typeahead.php', { extraParams : cur_params })
-    .result(function(event, item) {
-      cur_params['symbol'] = item;
-      location.search = '?' + jQuery.param(cur_params);
-    });
-});

+ 0 - 32
tests/xhprof/xhprof_html/typeahead.php

@@ -1,32 +0,0 @@
-<?php
-//  Copyright (c) 2009 Facebook
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-/**
- * AJAX endpoint for XHProf function name typeahead.
- *
- * @author(s)  Kannan Muthukkaruppan
- *             Changhao Jiang
- */
-
-// by default assume that xhprof_html & xhprof_lib directories
-// are at the same level.
-$GLOBALS['XHPROF_LIB_ROOT'] = dirname(__FILE__) . '/../xhprof_lib';
-
-include_once $GLOBALS['XHPROF_LIB_ROOT'].'/display/xhprof.php';
-
-$xhprof_runs_impl = new XHProfRuns_Default();
-
-include_once $GLOBALS['XHPROF_LIB_ROOT'].'/display/typeahead_common.php';

+ 0 - 80
tests/xhprof/xhprof_lib/display/typeahead_common.php

@@ -1,80 +0,0 @@
-<?php
-//  Copyright (c) 2009 Facebook
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-/**
- * AJAX endpoint for XHProf function name typeahead is implemented
- * as a thin wrapper around this file. The wrapper must set up
- * the global $xhprof_runs_impl to correspond to an object that
- * implements the iXHProfRuns interface.
- *
- * @author(s)  Kannan Muthukkaruppan
- *             Changhao Jiang
- */
-
-
-include_once $GLOBALS['XHPROF_LIB_ROOT'].'/utils/xhprof_lib.php';
-
-// param name, its type, and default value
-$params = array('q'          => array(XHPROF_STRING_PARAM, ''),
-                'run'        => array(XHPROF_STRING_PARAM, ''),
-                'run1'       => array(XHPROF_STRING_PARAM, ''),
-                'run2'       => array(XHPROF_STRING_PARAM, ''),
-                'source'     => array(XHPROF_STRING_PARAM, 'xhprof'),
-                );
-
-// pull values of these params, and create named globals for each param
-xhprof_param_init($params);
-
-if (!empty($run)) {
-
-  // single run mode
-  $raw_data = $xhprof_runs_impl->get_run($run, $source, $desc_unused);
-  $functions = xhprof_get_matching_functions($q, $raw_data);
-
-} else if (!empty($run1) && !empty($run2)) {
-
-  // diff mode
-  $raw_data = $xhprof_runs_impl->get_run($run1, $source, $desc_unused);
-  $functions1 = xhprof_get_matching_functions($q, $raw_data);
-
-  $raw_data = $xhprof_runs_impl->get_run($run2, $source, $desc_unused);
-  $functions2 = xhprof_get_matching_functions($q, $raw_data);
-
-
-  $functions = array_unique(array_merge($functions1, $functions2));
-  asort($functions);
-} else {
-  xhprof_error("no valid runs specified to typeahead endpoint");
-  $functions = array();
-}
-
-// If exact match is present move it to the front
-if (in_array($q, $functions)) {
-  $old_functions = $functions;
-
-  $functions = array($q);
-  foreach ($old_functions as $f) {
-    // exact match case has already been added to the front
-    if ($f != $q) {
-      $functions[] =$f;
-    }
-  }
-}
-
-foreach ($functions as $f) {
-  echo $f."\n";
-}
-

+ 0 - 1499
tests/xhprof/xhprof_lib/display/xhprof.php

@@ -1,1499 +0,0 @@
-<?php
-//  Copyright (c) 2009 Facebook
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-//
-// XHProf: A Hierarchical Profiler for PHP
-//
-// XHProf has two components:
-//
-//  * This module is the UI/reporting component, used
-//    for viewing results of XHProf runs from a browser.
-//
-//  * Data collection component: This is implemented
-//    as a PHP extension (XHProf).
-//
-// @author Kannan Muthukkaruppan
-//
-
-if (!isset($GLOBALS['XHPROF_LIB_ROOT'])) {
-  // by default, the parent directory is XHPROF lib root
-  $GLOBALS['XHPROF_LIB_ROOT'] = realpath(dirname(__FILE__) . '/..');
-}
-
-require_once $GLOBALS['XHPROF_LIB_ROOT'].'/utils/xhprof_lib.php';
-include_once $GLOBALS['XHPROF_LIB_ROOT'].'/utils/callgraph_utils.php';
-include_once $GLOBALS['XHPROF_LIB_ROOT'].'/utils/xhprof_runs.php';
-
-
-/**
- * Our coding convention disallows relative paths in hrefs.
- * Get the base URL path from the SCRIPT_NAME.
- */
-$base_path = rtrim(dirname($_SERVER['SCRIPT_NAME']), "/");
-
-
-/**
- * Generate references to required stylesheets & javascript.
- *
- * If the calling script (such as index.php) resides in
- * a different location that than 'xhprof_html' directory the
- * caller must provide the URL path to 'xhprof_html' directory
- * so that the correct location of the style sheets/javascript
- * can be specified in the generated HTML.
- *
- */
-function xhprof_include_js_css($ui_dir_url_path = null) {
-
-  if (empty($ui_dir_url_path)) {
-    $ui_dir_url_path = rtrim(dirname($_SERVER['SCRIPT_NAME']), "/");
-  }
-
-  // style sheets
-  echo "<link href='$ui_dir_url_path/css/xhprof.css' rel='stylesheet' ".
-    " type='text/css'></link>";
-  echo "<link href='$ui_dir_url_path/jquery/jquery.tooltip.css' ".
-    " rel='stylesheet' type='text/css'></link>";
-  echo "<link href='$ui_dir_url_path/jquery/jquery.autocomplete.css' ".
-    " rel='stylesheet' type='text/css'></link>";
-
-  // javascript
-  echo "<script src='$ui_dir_url_path/jquery/jquery-1.2.6.js'>".
-       "</script>";
-  echo "<script src='$ui_dir_url_path/jquery/jquery.tooltip.js'>".
-       "</script>";
-  echo "<script src='$ui_dir_url_path/jquery/jquery.autocomplete.js'>"
-       ."</script>";
-  echo "<script src='$ui_dir_url_path/js/xhprof_report.js'></script>";
-}
-
-
-/*
- * Formats call counts for XHProf reports.
- *
- * Description:
- * Call counts in single-run reports are integer values.
- * However, call counts for aggregated reports can be
- * fractional. This function will print integer values
- * without decimal point, but with commas etc.
- *
- *   4000 ==> 4,000
- *
- * It'll round fractional values to decimal precision of 3
- *   4000.1212 ==> 4,000.121
- *   4000.0001 ==> 4,000
- *
- */
-function xhprof_count_format($num) {
-  $num = round($num, 3);
-  if (round($num) == $num) {
-    return number_format($num);
-  } else {
-    return number_format($num, 3);
-  }
-}
-
-function xhprof_percent_format($s, $precision = 1) {
-  return sprintf('%.'.$precision.'f%%', 100*$s);
-}
-
-/**
- * Implodes the text for a bunch of actions (such as links, forms,
- * into a HTML list and returns the text.
- */
-function xhprof_render_actions($actions) {
-  $out = array( );
-
-  if (count($actions)) {
-    $out[] = '<ul class="xhprof_actions">';
-    foreach ($actions as $action) {
-      $out[] = '<li>'.$action.'</li>';
-    }
-    $out[] = '</ul>';
-  }
-
-  return implode('', $out);
-}
-
-
-/**
- * @param html-str $content  the text/image/innerhtml/whatever for the link
- * @param raw-str  $href
- * @param raw-str  $class
- * @param raw-str  $id
- * @param raw-str  $title
- * @param raw-str  $target
- * @param raw-str  $onclick
- * @param raw-str  $style
- * @param raw-str  $access
- * @param raw-str  $onmouseover
- * @param raw-str  $onmouseout
- * @param raw-str  $onmousedown
- * @param raw-str  $dir
- * @param raw-str  $rel
- */
-function xhprof_render_link($content, $href, $class='', $id='', $title='',
-                            $target='',
-                            $onclick='', $style='', $access='', $onmouseover='',
-                            $onmouseout='', $onmousedown='') {
-
-  if (!$content) {
-    return '';
-  }
-
-  if ($href) {
-    $link = '<a href="' . ($href) . '"';
-  } else {
-    $link = '<span';
-  }
-
-  if ($class) {
-    $link .= ' class="' . ($class) . '"';
-  }
-  if ($id) {
-    $link .= ' id="' . ($id) . '"';
-  }
-  if ($title) {
-    $link .= ' title="' . ($title) . '"';
-  }
-  if ($target) {
-    $link .= ' target="' . ($target) . '"';
-  }
-  if ($onclick && $href) {
-    $link .= ' onclick="' . ($onclick) . '"';
-  }
-  if ($style && $href) {
-    $link .= ' style="' . ($style) . '"';
-  }
-  if ($access && $href) {
-    $link .= ' accesskey="' . ($access) . '"';
-  }
-  if ($onmouseover) {
-    $link .= ' onmouseover="' . ($onmouseover) . '"';
-  }
-  if ($onmouseout) {
-    $link .= ' onmouseout="' . ($onmouseout) . '"';
-  }
-  if ($onmousedown) {
-    $link .= ' onmousedown="' . ($onmousedown) . '"';
-  }
-
-  $link .= '>';
-  $link .= $content;
-  if ($href) {
-    $link .= '</a>';
-  } else {
-    $link .= '</span>';
-  }
-
-  return $link;
-}
-
-
-// default column to sort on -- wall time
-$sort_col = "wt";
-
-// default is "single run" report
-$diff_mode = false;
-
-// call count data present?
-$display_calls = true;
-
-// The following column headers are sortable
-$sortable_columns = array("fn" => 1,
-                          "ct" => 1,
-                          "wt" => 1,
-                          "excl_wt" => 1,
-                          "ut" => 1,
-                          "excl_ut" => 1,
-                          "st" => 1,
-                          "excl_st" => 1,
-                          "mu" => 1,
-                          "excl_mu" => 1,
-                          "pmu" => 1,
-                          "excl_pmu" => 1,
-                          "cpu" => 1,
-                          "excl_cpu" => 1,
-                          "samples" => 1,
-                          "excl_samples" => 1
-                          );
-
-// Textual descriptions for column headers in "single run" mode
-$descriptions = array(
-                      "fn" => "Function Name",
-                      "ct" =>  "Calls",
-                      "Calls%" => "Calls%",
-
-                      "wt" => "Incl. Wall Time<br>(microsec)",
-                      "IWall%" => "IWall%",
-                      "excl_wt" => "Excl. Wall Time<br>(microsec)",
-                      "EWall%" => "EWall%",
-
-                      "ut" => "Incl. User<br>(microsecs)",
-                      "IUser%" => "IUser%",
-                      "excl_ut" => "Excl. User<br>(microsec)",
-                      "EUser%" => "EUser%",
-
-                      "st" => "Incl. Sys <br>(microsec)",
-                      "ISys%" => "ISys%",
-                      "excl_st" => "Excl. Sys <br>(microsec)",
-                      "ESys%" => "ESys%",
-
-                      "cpu" => "Incl. CPU<br>(microsecs)",
-                      "ICpu%" => "ICpu%",
-                      "excl_cpu" => "Excl. CPU<br>(microsec)",
-                      "ECpu%" => "ECPU%",
-
-                      "mu" => "Incl.<br>MemUse<br>(bytes)",
-                      "IMUse%" => "IMemUse%",
-                      "excl_mu" => "Excl.<br>MemUse<br>(bytes)",
-                      "EMUse%" => "EMemUse%",
-
-                      "pmu" => "Incl.<br> PeakMemUse<br>(bytes)",
-                      "IPMUse%" => "IPeakMemUse%",
-                      "excl_pmu" => "Excl.<br>PeakMemUse<br>(bytes)",
-                      "EPMUse%" => "EPeakMemUse%",
-
-                      "samples" => "Incl. Samples",
-                      "ISamples%" => "ISamples%",
-                      "excl_samples" => "Excl. Samples",
-                      "ESamples%" => "ESamples%",
-                      );
-
-// Formatting Callback Functions...
-$format_cbk = array(
-                      "fn" => "",
-                      "ct" => "xhprof_count_format",
-                      "Calls%" => "xhprof_percent_format",
-
-                      "wt" => "number_format",
-                      "IWall%" => "xhprof_percent_format",
-                      "excl_wt" => "number_format",
-                      "EWall%" => "xhprof_percent_format",
-
-                      "ut" => "number_format",
-                      "IUser%" => "xhprof_percent_format",
-                      "excl_ut" => "number_format",
-                      "EUser%" => "xhprof_percent_format",
-
-                      "st" => "number_format",
-                      "ISys%" => "xhprof_percent_format",
-                      "excl_st" => "number_format",
-                      "ESys%" => "xhprof_percent_format",
-
-                      "cpu" => "number_format",
-                      "ICpu%" => "xhprof_percent_format",
-                      "excl_cpu" => "number_format",
-                      "ECpu%" => "xhprof_percent_format",
-
-                      "mu" => "number_format",
-                      "IMUse%" => "xhprof_percent_format",
-                      "excl_mu" => "number_format",
-                      "EMUse%" => "xhprof_percent_format",
-
-                      "pmu" => "number_format",
-                      "IPMUse%" => "xhprof_percent_format",
-                      "excl_pmu" => "number_format",
-                      "EPMUse%" => "xhprof_percent_format",
-
-                      "samples" => "number_format",
-                      "ISamples%" => "xhprof_percent_format",
-                      "excl_samples" => "number_format",
-                      "ESamples%" => "xhprof_percent_format",
-                      );
-
-
-// Textual descriptions for column headers in "diff" mode
-$diff_descriptions = array(
-                      "fn" => "Function Name",
-                      "ct" =>  "Calls Diff",
-                      "Calls%" => "Calls<br>Diff%",
-
-                      "wt" => "Incl. Wall<br>Diff<br>(microsec)",
-                      "IWall%" => "IWall<br> Diff%",
-                      "excl_wt" => "Excl. Wall<br>Diff<br>(microsec)",
-                      "EWall%" => "EWall<br>Diff%",
-
-                      "ut" => "Incl. User Diff<br>(microsec)",
-                      "IUser%" => "IUser<br>Diff%",
-                      "excl_ut" => "Excl. User<br>Diff<br>(microsec)",
-                      "EUser%" => "EUser<br>Diff%",
-
-                      "cpu" => "Incl. CPU Diff<br>(microsec)",
-                      "ICpu%" => "ICpu<br>Diff%",
-                      "excl_cpu" => "Excl. CPU<br>Diff<br>(microsec)",
-                      "ECpu%" => "ECpu<br>Diff%",
-
-                      "st" => "Incl. Sys Diff<br>(microsec)",
-                      "ISys%" => "ISys<br>Diff%",
-                      "excl_st" => "Excl. Sys Diff<br>(microsec)",
-                      "ESys%" => "ESys<br>Diff%",
-
-                      "mu" => "Incl.<br>MemUse<br>Diff<br>(bytes)",
-                      "IMUse%" => "IMemUse<br>Diff%",
-                      "excl_mu" => "Excl.<br>MemUse<br>Diff<br>(bytes)",
-                      "EMUse%" => "EMemUse<br>Diff%",
-
-                      "pmu" => "Incl.<br> PeakMemUse<br>Diff<br>(bytes)",
-                      "IPMUse%" => "IPeakMemUse<br>Diff%",
-                      "excl_pmu" => "Excl.<br>PeakMemUse<br>Diff<br>(bytes)",
-                      "EPMUse%" => "EPeakMemUse<br>Diff%",
-
-                      "samples" => "Incl. Samples Diff",
-                      "ISamples%" => "ISamples Diff%",
-                      "excl_samples" => "Excl. Samples Diff",
-                      "ESamples%" => "ESamples Diff%",
-                      );
-
-// columns that'll be displayed in a top-level report
-$stats = array();
-
-// columns that'll be displayed in a function's parent/child report
-$pc_stats = array();
-
-// Various total counts
-$totals = 0;
-$totals_1 = 0;
-$totals_2 = 0;
-
-/*
- * The subset of $possible_metrics that is present in the raw profile data.
- */
-$metrics = null;
-
-/**
- * Callback comparison operator (passed to usort() for sorting array of
- * tuples) that compares array elements based on the sort column
- * specified in $sort_col (global parameter).
- *
- * @author Kannan
- */
-function sort_cbk($a, $b)
-{
-  global $sort_col;
-  global $diff_mode;
-
-  if ($sort_col == "fn") {
-
-    // case insensitive ascending sort for function names
-    $left = strtoupper($a["fn"]);
-    $right = strtoupper($b["fn"]);
-
-    if ($left == $right)
-      return 0;
-    return ($left < $right) ? -1 : 1;
-
-  } else {
-
-    // descending sort for all others
-    $left = $a[$sort_col];
-    $right = $b[$sort_col];
-
-    // if diff mode, sort by absolute value of regression/improvement
-    if ($diff_mode) {
-      $left = abs($left);
-      $right = abs($right);
-    }
-
-    if ($left == $right)
-      return 0;
-    return ($left > $right) ? -1 : 1;
-  }
-}
-
-/**
- * Initialize the metrics we'll display based on the information
- * in the raw data.
- *
- * @author Kannan
- */
-function init_metrics($xhprof_data, $rep_symbol, $sort, $diff_report = false) {
-  global $stats;
-  global $pc_stats;
-  global $metrics;
-  global $diff_mode;
-  global $sortable_columns;
-  global $sort_col;
-  global $display_calls;
-
-  $diff_mode = $diff_report;
-
-  if (!empty($sort)) {
-    if (array_key_exists($sort, $sortable_columns)) {
-      $sort_col = $sort;
-    } else {
-      print("Invalid Sort Key $sort specified in URL");
-    }
-  }
-
-  // For C++ profiler runs, walltime attribute isn't present.
-  // In that case, use "samples" as the default sort column.
-  if (!isset($xhprof_data["main()"]["wt"])) {
-
-    if ($sort_col == "wt") {
-      $sort_col = "samples";
-    }
-
-    // C++ profiler data doesn't have call counts.
-    // ideally we should check to see if "ct" metric
-    // is present for "main()". But currently "ct"
-    // metric is artificially set to 1. So, relying
-    // on absence of "wt" metric instead.
-    $display_calls = false;
-  } else {
-    $display_calls = true;
-  }
-
-  // parent/child report doesn't support exclusive times yet.
-  // So, change sort hyperlinks to closest fit.
-  if (!empty($rep_symbol)) {
-    $sort_col = str_replace("excl_", "", $sort_col);
-  }
-
-  if ($display_calls) {
-    $stats = array("fn", "ct", "Calls%");
-  } else {
-    $stats = array("fn");
-  }
-
-  $pc_stats = $stats;
-
-  $possible_metrics = xhprof_get_possible_metrics($xhprof_data);
-  foreach ($possible_metrics as $metric => $desc) {
-    if (isset($xhprof_data["main()"][$metric])) {
-      $metrics[] = $metric;
-      // flat (top-level reports): we can compute
-      // exclusive metrics reports as well.
-      $stats[] = $metric;
-      $stats[] = "I" . $desc[0] . "%";
-      $stats[] = "excl_" . $metric;
-      $stats[] = "E" . $desc[0] . "%";
-
-      // parent/child report for a function: we can
-      // only breakdown inclusive times correctly.
-      $pc_stats[] = $metric;
-      $pc_stats[] = "I" . $desc[0] . "%";
-    }
-  }
-}
-
-/**
- * Get the appropriate description for a statistic
- * (depending upon whether we are in diff report mode
- * or single run report mode).
- *
- * @author Kannan
- */
-function stat_description($stat) {
-  global $descriptions;
-  global $diff_descriptions;
-  global $diff_mode;
-
-  if ($diff_mode) {
-    return $diff_descriptions[$stat];
-  } else {
-    return $descriptions[$stat];
-  }
-}
-
-
-/**
- * Analyze raw data & generate the profiler report
- * (common for both single run mode and diff mode).
- *
- * @author: Kannan
- */
-function profiler_report ($url_params,
-                          $rep_symbol,
-                          $sort,
-                          $run1,
-                          $run1_desc,
-                          $run1_data,
-                          $run2 = 0,
-                          $run2_desc = "",
-                          $run2_data = array()) {
-  global $totals;
-  global $totals_1;
-  global $totals_2;
-  global $stats;
-  global $pc_stats;
-  global $diff_mode;
-  global $base_path;
-
-  // if we are reporting on a specific function, we can trim down
-  // the report(s) to just stuff that is relevant to this function.
-  // That way compute_flat_info()/compute_diff() etc. do not have
-  // to needlessly work hard on churning irrelevant data.
-  if (!empty($rep_symbol)) {
-    $run1_data = xhprof_trim_run($run1_data, array($rep_symbol));
-    if ($diff_mode) {
-      $run2_data = xhprof_trim_run($run2_data, array($rep_symbol));
-    }
-  }
-
-  if ($diff_mode) {
-    $run_delta = xhprof_compute_diff($run1_data, $run2_data);
-    $symbol_tab  = xhprof_compute_flat_info($run_delta, $totals);
-    $symbol_tab1 = xhprof_compute_flat_info($run1_data, $totals_1);
-    $symbol_tab2 = xhprof_compute_flat_info($run2_data, $totals_2);
-  } else {
-    $symbol_tab = xhprof_compute_flat_info($run1_data, $totals);
-  }
-
-  $run1_txt = sprintf("<b>Run #%s:</b> %s",
-                      $run1, $run1_desc);
-
-  $base_url_params = xhprof_array_unset(xhprof_array_unset($url_params,
-                                                           'symbol'),
-                                        'all');
-
-  $top_link_query_string = "$base_path/?" . http_build_query($base_url_params);
-
-  if ($diff_mode) {
-    $diff_text = "Diff";
-    $base_url_params = xhprof_array_unset($base_url_params, 'run1');
-    $base_url_params = xhprof_array_unset($base_url_params, 'run2');
-    $run1_link = xhprof_render_link('View Run #' . $run1,
-                           "$base_path/?" .
-                           http_build_query(xhprof_array_set($base_url_params,
-                                                      'run',
-                                                      $run1)));
-    $run2_txt = sprintf("<b>Run #%s:</b> %s",
-                        $run2, $run2_desc);
-
-    $run2_link = xhprof_render_link('View Run #' . $run2,
-                                    "$base_path/?" .
-                        http_build_query(xhprof_array_set($base_url_params,
-                                                          'run',
-                                                          $run2)));
-  } else {
-    $diff_text = "Run";
-  }
-
-  // set up the action links for operations that can be done on this report
-  $links = array();
-  $links []=  xhprof_render_link("View Top Level $diff_text Report",
-                                 $top_link_query_string);
-
-  if ($diff_mode) {
-    $inverted_params = $url_params;
-    $inverted_params['run1'] = $url_params['run2'];
-    $inverted_params['run2'] = $url_params['run1'];
-
-    // view the different runs or invert the current diff
-    $links []= $run1_link;
-    $links []= $run2_link;
-    $links []= xhprof_render_link('Invert ' . $diff_text . ' Report',
-                           "$base_path/?".
-                           http_build_query($inverted_params));
-  }
-
-  // lookup function typeahead form
-  $links [] = '<input class="function_typeahead" ' .
-              ' type="input" size="40" maxlength="100" />';
-
-  echo xhprof_render_actions($links);
-
-
-  echo
-    '<dl class=phprof_report_info>' .
-    '  <dt>' . $diff_text . ' Report</dt>' .
-    '  <dd>' . ($diff_mode ?
-                $run1_txt . '<br><b>vs.</b><br>' . $run2_txt :
-                $run1_txt) .
-    '  </dd>' .
-    '  <dt>Tip</dt>' .
-    '  <dd>Click a function name below to drill down.</dd>' .
-    '</dl>' .
-    '<div style="clear: both; margin: 3em 0em;"></div>';
-
-  // data tables
-  if (!empty($rep_symbol)) {
-    if (!isset($symbol_tab[$rep_symbol])) {
-      echo "<hr>Symbol <b>$rep_symbol</b> not found in XHProf run</b><hr>";
-      return;
-    }
-
-    /* single function report with parent/child information */
-    if ($diff_mode) {
-      $info1 = isset($symbol_tab1[$rep_symbol]) ?
-                       $symbol_tab1[$rep_symbol] : null;
-      $info2 = isset($symbol_tab2[$rep_symbol]) ?
-                       $symbol_tab2[$rep_symbol] : null;
-      symbol_report($url_params, $run_delta, $symbol_tab[$rep_symbol],
-                    $sort, $rep_symbol,
-                    $run1, $info1,
-                    $run2, $info2);
-    } else {
-      symbol_report($url_params, $run1_data, $symbol_tab[$rep_symbol],
-                    $sort, $rep_symbol, $run1);
-    }
-  } else {
-    /* flat top-level report of all functions */
-    full_report($url_params, $symbol_tab, $sort, $run1, $run2);
-  }
-}
-
-/**
- * Computes percentage for a pair of values, and returns it
- * in string format.
- */
-function pct($a, $b) {
-  if ($b == 0) {
-    return "N/A";
-  } else {
-    $res = (round(($a * 1000 / $b)) / 10);
-    return $res;
-  }
-}
-
-/**
- * Given a number, returns the td class to use for display.
- *
- * For instance, negative numbers in diff reports comparing two runs (run1 & run2)
- * represent improvement from run1 to run2. We use green to display those deltas,
- * and red for regression deltas.
- */
-function get_print_class($num, $bold) {
-  global $vbar;
-  global $vbbar;
-  global $vrbar;
-  global $vgbar;
-  global $diff_mode;
-
-  if ($bold) {
-    if ($diff_mode) {
-      if ($num <= 0) {
-        $class = $vgbar; // green (improvement)
-      } else {
-        $class = $vrbar; // red (regression)
-      }
-    } else {
-      $class = $vbbar; // blue
-    }
-  }
-  else {
-    $class = $vbar;  // default (black)
-  }
-
-  return $class;
-}
-
-/**
- * Prints a <td> element with a numeric value.
- */
-function print_td_num($num, $fmt_func, $bold=false, $attributes=null) {
-
-  $class = get_print_class($num, $bold);
-
-  if (!empty($fmt_func)) {
-    $num = call_user_func($fmt_func, $num);
-  }
-
-  print("<td $attributes $class>$num</td>\n");
-}
-
-/**
- * Prints a <td> element with a pecentage.
- */
-function print_td_pct($numer, $denom, $bold=false, $attributes=null) {
-  global $vbar;
-  global $vbbar;
-  global $diff_mode;
-
-  $class = get_print_class($numer, $bold);
-
-  if ($denom == 0) {
-    $pct = "N/A%";
-  } else {
-    $pct = xhprof_percent_format($numer / abs($denom));
-  }
-
-  print("<td $attributes $class>$pct</td>\n");
-}
-
-/**
- * Print "flat" data corresponding to one function.
- *
- * @author Kannan
- */
-function print_function_info($url_params, $info, $sort, $run1, $run2) {
-  static $odd_even = 0;
-
-  global $totals;
-  global $sort_col;
-  global $metrics;
-  global $format_cbk;
-  global $display_calls;
-  global $base_path;
-
-  // Toggle $odd_or_even
-  $odd_even = 1 - $odd_even;
-
-  if ($odd_even) {
-    print("<tr>");
-  }
-  else {
-    print('<tr bgcolor="#e5e5e5">');
-  }
-
-  $href = "$base_path/?" .
-           http_build_query(xhprof_array_set($url_params,
-                                             'symbol', $info["fn"]));
-
-  print('<td>');
-  print(xhprof_render_link($info["fn"], $href));
-  print("</td>\n");
-
-  if ($display_calls) {
-    // Call Count..
-    print_td_num($info["ct"], $format_cbk["ct"], ($sort_col == "ct"));
-    print_td_pct($info["ct"], $totals["ct"], ($sort_col == "ct"));
-  }
-
-  // Other metrics..
-  foreach ($metrics as $metric) {
-    // Inclusive metric
-    print_td_num($info[$metric], $format_cbk[$metric],
-                 ($sort_col == $metric));
-    print_td_pct($info[$metric], $totals[$metric],
-                 ($sort_col == $metric));
-
-    // Exclusive Metric
-    print_td_num($info["excl_" . $metric],
-                 $format_cbk["excl_" . $metric],
-                 ($sort_col == "excl_" . $metric));
-    print_td_pct($info["excl_" . $metric],
-                 $totals[$metric],
-                 ($sort_col == "excl_" . $metric));
-  }
-
-  print("</tr>\n");
-}
-
-/**
- * Print non-hierarchical (flat-view) of profiler data.
- *
- * @author Kannan
- */
-function print_flat_data($url_params, $title, $flat_data, $sort, $run1, $run2, $limit) {
-
-  global $stats;
-  global $sortable_columns;
-  global $vwbar;
-  global $base_path;
-
-  $size  = count($flat_data);
-  if (!$limit) {              // no limit
-    $limit = $size;
-    $display_link = "";
-  } else {
-    $display_link = xhprof_render_link(" [ <b class=bubble>display all </b>]",
-                                       "$base_path/?" .
-                                       http_build_query(xhprof_array_set($url_params,
-                                                                         'all', 1)));
-  }
-
-  print("<h3 align=center>$title $display_link</h3><br>");
-
-  print('<table border=1 cellpadding=2 cellspacing=1 width="90%" '
-        .'rules=rows bordercolor="#bdc7d8" align=center>');
-  print('<tr bgcolor="#bdc7d8" align=right>');
-
-  foreach ($stats as $stat) {
-    $desc = stat_description($stat);
-    if (array_key_exists($stat, $sortable_columns)) {
-      $href = "$base_path/?"
-              . http_build_query(xhprof_array_set($url_params, 'sort', $stat));
-      $header = xhprof_render_link($desc, $href);
-    } else {
-      $header = $desc;
-    }
-
-    if ($stat == "fn")
-      print("<th align=left><nobr>$header</th>");
-    else
-      print("<th " . $vwbar . "><nobr>$header</th>");
-  }
-  print("</tr>\n");
-
-  if ($limit >= 0) {
-    $limit = min($size, $limit);
-    for($i=0; $i < $limit; $i++) {
-      print_function_info($url_params, $flat_data[$i], $sort, $run1, $run2);
-    }
-  } else {
-    // if $limit is negative, print abs($limit) items starting from the end
-    $limit = min($size, abs($limit));
-    for($i=0; $i < $limit; $i++) {
-      print_function_info($url_params, $flat_data[$size - $i - 1], $sort, $run1, $run2);
-    }
-  }
-  print("</table>");
-
-  // let's print the display all link at the bottom as well...
-  if ($display_link) {
-    echo '<div style="text-align: left; padding: 2em">' . $display_link . '</div>';
-  }
-
-}
-
-/**
- * Generates a tabular report for all functions. This is the top-level report.
- *
- * @author Kannan
- */
-function full_report($url_params, $symbol_tab, $sort, $run1, $run2) {
-  global $vwbar;
-  global $vbar;
-  global $totals;
-  global $totals_1;
-  global $totals_2;
-  global $metrics;
-  global $diff_mode;
-  global $descriptions;
-  global $sort_col;
-  global $format_cbk;
-  global $display_calls;
-  global $base_path;
-
-  $possible_metrics = xhprof_get_possible_metrics();
-
-  if ($diff_mode) {
-
-    $base_url_params = xhprof_array_unset(xhprof_array_unset($url_params,
-                                                             'run1'),
-                                          'run2');
-    $href1 = "$base_path/?" .
-      http_build_query(xhprof_array_set($base_url_params,
-                                        'run', $run1));
-    $href2 = "$base_path/?" .
-      http_build_query(xhprof_array_set($base_url_params,
-                                        'run', $run2));
-
-    print("<h3><center>Overall Diff Summary</center></h3>");
-    print('<table border=1 cellpadding=2 cellspacing=1 width="30%" '
-          .'rules=rows bordercolor="#bdc7d8" align=center>' . "\n");
-    print('<tr bgcolor="#bdc7d8" align=right>');
-    print("<th></th>");
-    print("<th $vwbar>" . xhprof_render_link("Run #$run1", $href1) . "</th>");
-    print("<th $vwbar>" . xhprof_render_link("Run #$run2", $href2) . "</th>");
-    print("<th $vwbar>Diff</th>");
-    print("<th $vwbar>Diff%</th>");
-    print('</tr>');
-
-    if ($display_calls) {
-      print('<tr>');
-      print("<td>Number of Function Calls</td>");
-      print_td_num($totals_1["ct"], $format_cbk["ct"]);
-      print_td_num($totals_2["ct"], $format_cbk["ct"]);
-      print_td_num($totals_2["ct"] - $totals_1["ct"], $format_cbk["ct"], true);
-      print_td_pct($totals_2["ct"] - $totals_1["ct"], $totals_1["ct"], true);
-      print('</tr>');
-    }
-
-    foreach ($metrics as $metric) {
-      $m = $metric;
-      print('<tr>');
-      print("<td>" . str_replace("<br>", " ", $descriptions[$m]) . "</td>");
-      print_td_num($totals_1[$m], $format_cbk[$m]);
-      print_td_num($totals_2[$m], $format_cbk[$m]);
-      print_td_num($totals_2[$m] - $totals_1[$m], $format_cbk[$m], true);
-      print_td_pct($totals_2[$m] - $totals_1[$m], $totals_1[$m], true);
-      print('<tr>');
-    }
-    print('</table>');
-
-    $callgraph_report_title = '[View Regressions/Improvements using Callgraph Diff]';
-
-  } else {
-    print("<p><center>\n");
-
-    print('<table cellpadding=2 cellspacing=1 width="30%" '
-          .'bgcolor="#bdc7d8" align=center>' . "\n");
-    echo "<tr>";
-    echo "<th style='text-align:right'>Overall Summary</th>";
-    echo "<th'></th>";
-    echo "</tr>";
-
-    foreach ($metrics as $metric) {
-      echo "<tr>";
-      echo "<td style='text-align:right; font-weight:bold'>Total "
-            . str_replace("<br>", " ", stat_description($metric)) . ":</td>";
-      echo "<td>" . number_format($totals[$metric]) .  " "
-           . $possible_metrics[$metric][1] . "</td>";
-      echo "</tr>";
-    }
-
-    if ($display_calls) {
-      echo "<tr>";
-      echo "<td style='text-align:right; font-weight:bold'>Number of Function Calls:</td>";
-      echo "<td>" . number_format($totals['ct']) . "</td>";
-      echo "</tr>";
-    }
-
-    echo "</table>";
-    print("</center></p>\n");
-
-    $callgraph_report_title = '[View Full Callgraph]';
-  }
-
-  print("<center><br><h3>" .
-        xhprof_render_link($callgraph_report_title,
-                    "$base_path/callgraph.php" . "?" . http_build_query($url_params))
-        . "</h3></center>");
-
-
-  $flat_data = array();
-  foreach ($symbol_tab as $symbol => $info) {
-    $tmp = $info;
-    $tmp["fn"] = $symbol;
-    $flat_data[] = $tmp;
-  }
-  usort($flat_data, 'sort_cbk');
-
-  print("<br>");
-
-  if (!empty($url_params['all'])) {
-    $all = true;
-    $limit = 0;    // display all rows
-  } else {
-    $all = false;
-    $limit = 100;  // display only limited number of rows
-  }
-
-  $desc = str_replace("<br>", " ", $descriptions[$sort_col]);
-
-  if ($diff_mode) {
-    if ($all) {
-      $title = "Total Diff Report: '
-               .'Sorted by absolute value of regression/improvement in $desc";
-    } else {
-      $title = "Top 100 <i style='color:red'>Regressions</i>/"
-               . "<i style='color:green'>Improvements</i>: "
-               . "Sorted by $desc Diff";
-    }
-  } else {
-    if ($all) {
-      $title = "Sorted by $desc";
-    } else {
-      $title = "Displaying top $limit functions: Sorted by $desc";
-    }
-  }
-  print_flat_data($url_params, $title, $flat_data, $sort, $run1, $run2, $limit);
-}
-
-
-/**
- * Return attribute names and values to be used by javascript tooltip.
- */
-function get_tooltip_attributes($type, $metric) {
-  return "type='$type' metric='$metric'";
-}
-
-/**
- * Print info for a parent or child function in the
- * parent & children report.
- *
- * @author Kannan
- */
-function pc_info($info, $base_ct, $base_info, $parent) {
-  global $sort_col;
-  global $metrics;
-  global $format_cbk;
-  global $display_calls;
-
-  if ($parent)
-    $type = "Parent";
-  else
-    $type = "Child";
-
-  if ($display_calls) {
-    $mouseoverct = get_tooltip_attributes($type, "ct");
-    /* call count */
-    print_td_num($info["ct"], $format_cbk["ct"], ($sort_col == "ct"), $mouseoverct);
-    print_td_pct($info["ct"], $base_ct, ($sort_col == "ct"), $mouseoverct);
-  }
-
-  /* Inclusive metric values  */
-  foreach ($metrics as $metric) {
-    print_td_num($info[$metric], $format_cbk[$metric],
-                 ($sort_col == $metric),
-                 get_tooltip_attributes($type, $metric));
-    print_td_pct($info[$metric], $base_info[$metric], ($sort_col == $metric),
-                 get_tooltip_attributes($type, $metric));
-  }
-}
-
-function print_pc_array($url_params, $results, $base_ct, $base_info, $parent,
-                        $run1, $run2) {
-  global $base_path;
-
-  // Construct section title
-  if ($parent) {
-    $title = 'Parent function';
-  }
-  else {
-    $title = 'Child function';
-  }
-  if (count($results) > 1) {
-    $title .= 's';
-  }
-
-  print("<tr bgcolor='#e0e0ff'><td>");
-  print("<b><i><center>" . $title . "</center></i></b>");
-  print("</td></tr>");
-
-  $odd_even = 0;
-  foreach ($results as $info) {
-    $href = "$base_path/?" .
-      http_build_query(xhprof_array_set($url_params,
-                                        'symbol', $info["fn"]));
-    $odd_even = 1 - $odd_even;
-
-    if ($odd_even) {
-      print('<tr>');
-    }
-    else {
-      print('<tr bgcolor="#e5e5e5">');
-    }
-
-    print("<td>" . xhprof_render_link($info["fn"], $href) . "</td>");
-    pc_info($info, $base_ct, $base_info, $parent);
-    print("</tr>");
-  }
-}
-
-
-function print_symbol_summary($symbol_info, $stat, $base) {
-
-  $val = $symbol_info[$stat];
-  $desc = str_replace("<br>", " ", stat_description($stat));
-
-  print("$desc: </td>");
-  print(number_format($val));
-  print(" (" . pct($val, $base) . "% of overall)");
-  if (substr($stat, 0, 4) == "excl") {
-    $func_base = $symbol_info[str_replace("excl_", "", $stat)];
-    print(" (" . pct($val, $func_base) . "% of this function)");
-  }
-  print("<br>");
-}
-
-/**
- * Generates a report for a single function/symbol.
- *
- * @author Kannan
- */
-function symbol_report($url_params,
-                       $run_data, $symbol_info, $sort, $rep_symbol,
-                       $run1,
-                       $symbol_info1 = null,
-                       $run2 = 0,
-                       $symbol_info2 = null) {
-  global $vwbar;
-  global $vbar;
-  global $totals;
-  global $pc_stats;
-  global $sortable_columns;
-  global $metrics;
-  global $diff_mode;
-  global $descriptions;
-  global $format_cbk;
-  global $sort_col;
-  global $display_calls;
-  global $base_path;
-
-  $possible_metrics = xhprof_get_possible_metrics();
-
-  if ($diff_mode) {
-    $diff_text = "<b>Diff</b>";
-    $regr_impr = "<i style='color:red'>Regression</i>/<i style='color:green'>Improvement</i>";
-  } else {
-    $diff_text = "";
-    $regr_impr = "";
-  }
-
-  if ($diff_mode) {
-
-    $base_url_params = xhprof_array_unset(xhprof_array_unset($url_params,
-                                                             'run1'),
-                                          'run2');
-    $href1 = "$base_path?"
-      . http_build_query(xhprof_array_set($base_url_params, 'run', $run1));
-    $href2 = "$base_path?"
-      . http_build_query(xhprof_array_set($base_url_params, 'run', $run2));
-
-    print("<h3 align=center>$regr_impr summary for $rep_symbol<br><br></h3>");
-    print('<table border=1 cellpadding=2 cellspacing=1 width="30%" '
-          .'rules=rows bordercolor="#bdc7d8" align=center>' . "\n");
-    print('<tr bgcolor="#bdc7d8" align=right>');
-    print("<th align=left>$rep_symbol</th>");
-    print("<th $vwbar><a href=" . $href1 . ">Run #$run1</a></th>");
-    print("<th $vwbar><a href=" . $href2 . ">Run #$run2</a></th>");
-    print("<th $vwbar>Diff</th>");
-    print("<th $vwbar>Diff%</th>");
-    print('</tr>');
-    print('<tr>');
-
-    if ($display_calls) {
-      print("<td>Number of Function Calls</td>");
-      print_td_num($symbol_info1["ct"], $format_cbk["ct"]);
-      print_td_num($symbol_info2["ct"], $format_cbk["ct"]);
-      print_td_num($symbol_info2["ct"] - $symbol_info1["ct"],
-                   $format_cbk["ct"], true);
-      print_td_pct($symbol_info2["ct"] - $symbol_info1["ct"],
-                   $symbol_info1["ct"], true);
-      print('</tr>');
-    }
-
-
-    foreach ($metrics as $metric) {
-      $m = $metric;
-
-      // Inclusive stat for metric
-      print('<tr>');
-      print("<td>" . str_replace("<br>", " ", $descriptions[$m]) . "</td>");
-      print_td_num($symbol_info1[$m], $format_cbk[$m]);
-      print_td_num($symbol_info2[$m], $format_cbk[$m]);
-      print_td_num($symbol_info2[$m] - $symbol_info1[$m], $format_cbk[$m], true);
-      print_td_pct($symbol_info2[$m] - $symbol_info1[$m], $symbol_info1[$m], true);
-      print('</tr>');
-
-      // AVG (per call) Inclusive stat for metric
-      print('<tr>');
-      print("<td>" . str_replace("<br>", " ", $descriptions[$m]) . " per call </td>");
-      $avg_info1 = 'N/A';
-      $avg_info2 = 'N/A';
-      if ($symbol_info1['ct'] > 0) {
-        $avg_info1 = ($symbol_info1[$m]/$symbol_info1['ct']);
-      }
-      if ($symbol_info2['ct'] > 0) {
-        $avg_info2 = ($symbol_info2[$m]/$symbol_info2['ct']);
-      }
-      print_td_num($avg_info1, $format_cbk[$m]);
-      print_td_num($avg_info2, $format_cbk[$m]);
-      print_td_num($avg_info2 - $avg_info1, $format_cbk[$m], true);
-      print_td_pct($avg_info2 - $avg_info1, $avg_info1, true);
-      print('</tr>');
-
-      // Exclusive stat for metric
-      $m = "excl_" . $metric;
-      print('<tr style="border-bottom: 1px solid black;">');
-      print("<td>" . str_replace("<br>", " ", $descriptions[$m]) . "</td>");
-      print_td_num($symbol_info1[$m], $format_cbk[$m]);
-      print_td_num($symbol_info2[$m], $format_cbk[$m]);
-      print_td_num($symbol_info2[$m] - $symbol_info1[$m], $format_cbk[$m], true);
-      print_td_pct($symbol_info2[$m] - $symbol_info1[$m], $symbol_info1[$m], true);
-      print('</tr>');
-    }
-
-    print('</table>');
-  }
-
-  print("<br><h4><center>");
-  print("Parent/Child $regr_impr report for <b>$rep_symbol</b>");
-
-  $callgraph_href = "$base_path/callgraph.php?"
-    . http_build_query(xhprof_array_set($url_params, 'func', $rep_symbol));
-
-  print(" <a href='$callgraph_href'>[View Callgraph $diff_text]</a><br>");
-
-  print("</center></h4><br>");
-
-  print('<table border=1 cellpadding=2 cellspacing=1 width="90%" '
-        .'rules=rows bordercolor="#bdc7d8" align=center>' . "\n");
-  print('<tr bgcolor="#bdc7d8" align=right>');
-
-  foreach ($pc_stats as $stat) {
-    $desc = stat_description($stat);
-    if (array_key_exists($stat, $sortable_columns)) {
-
-      $href = "$base_path/?" .
-        http_build_query(xhprof_array_set($url_params,
-                                          'sort', $stat));
-      $header = xhprof_render_link($desc, $href);
-    } else {
-      $header = $desc;
-    }
-
-    if ($stat == "fn")
-      print("<th align=left><nobr>$header</th>");
-    else
-      print("<th " . $vwbar . "><nobr>$header</th>");
-  }
-  print("</tr>");
-
-  print("<tr bgcolor='#e0e0ff'><td>");
-  print("<b><i><center>Current Function</center></i></b>");
-  print("</td></tr>");
-
-  print("<tr>");
-  // make this a self-reference to facilitate copy-pasting snippets to e-mails
-  print("<td><a href=''>$rep_symbol</a></td>");
-
-  if ($display_calls) {
-    // Call Count
-    print_td_num($symbol_info["ct"], $format_cbk["ct"]);
-    print_td_pct($symbol_info["ct"], $totals["ct"]);
-  }
-
-  // Inclusive Metrics for current function
-  foreach ($metrics as $metric) {
-    print_td_num($symbol_info[$metric], $format_cbk[$metric], ($sort_col == $metric));
-    print_td_pct($symbol_info[$metric], $totals[$metric], ($sort_col == $metric));
-  }
-  print("</tr>");
-
-  print("<tr bgcolor='#ffffff'>");
-  print("<td style='text-align:right;color:blue'>"
-        ."Exclusive Metrics $diff_text for Current Function</td>");
-
-  if ($display_calls) {
-    // Call Count
-    print("<td $vbar></td>");
-    print("<td $vbar></td>");
-  }
-
-  // Exclusive Metrics for current function
-  foreach ($metrics as $metric) {
-    print_td_num($symbol_info["excl_" . $metric], $format_cbk["excl_" . $metric],
-                 ($sort_col == $metric),
-                 get_tooltip_attributes("Child", $metric));
-    print_td_pct($symbol_info["excl_" . $metric], $symbol_info[$metric],
-                 ($sort_col == $metric),
-                 get_tooltip_attributes("Child", $metric));
-  }
-  print("</tr>");
-
-  // list of callers/parent functions
-  $results = array();
-  if ($display_calls) {
-    $base_ct = $symbol_info["ct"];
-  } else {
-    $base_ct = 0;
-  }
-  foreach ($metrics as $metric) {
-    $base_info[$metric] = $symbol_info[$metric];
-  }
-  foreach ($run_data as $parent_child => $info) {
-    list($parent, $child) = xhprof_parse_parent_child($parent_child);
-    if (($child == $rep_symbol) && ($parent)) {
-      $info_tmp = $info;
-      $info_tmp["fn"] = $parent;
-      $results[] = $info_tmp;
-    }
-  }
-  usort($results, 'sort_cbk');
-
-  if (count($results) > 0) {
-    print_pc_array($url_params, $results, $base_ct, $base_info, true,
-                   $run1, $run2);
-  }
-
-  // list of callees/child functions
-  $results = array();
-  $base_ct = 0;
-  foreach ($run_data as $parent_child => $info) {
-    list($parent, $child) = xhprof_parse_parent_child($parent_child);
-    if ($parent == $rep_symbol) {
-      $info_tmp = $info;
-      $info_tmp["fn"] = $child;
-      $results[] = $info_tmp;
-      if ($display_calls) {
-        $base_ct += $info["ct"];
-      }
-    }
-  }
-  usort($results, 'sort_cbk');
-
-  if (count($results)) {
-    print_pc_array($url_params, $results, $base_ct, $base_info, false,
-                   $run1, $run2);
-  }
-
-  print("</table>");
-
-  // These will be used for pop-up tips/help.
-  // Related javascript code is in: xhprof_report.js
-  print("\n");
-  print('<script language="javascript">' . "\n");
-  print("var func_name = '\"" . $rep_symbol . "\"';\n");
-  print("var total_child_ct  = " . $base_ct . ";\n");
-  if ($display_calls) {
-    print("var func_ct   = " . $symbol_info["ct"] . ";\n" );
-  }
-  print("var func_metrics = new Array();\n");
-  print("var metrics_col  = new Array();\n");
-  print("var metrics_desc  = new Array();\n");
-  if ($diff_mode) {
-    print("var diff_mode = true;\n");
-  } else {
-    print("var diff_mode = false;\n");
-  }
-  $column_index = 3; // First three columns are Func Name, Calls, Calls%
-  foreach ($metrics as $metric) {
-    print("func_metrics[\"" . $metric . "\"] = " . round($symbol_info[$metric]) . ";\n" );
-    print("metrics_col[\"". $metric . "\"] = " . $column_index . ";\n");
-    print("metrics_desc[\"". $metric . "\"] = \"" . $possible_metrics[$metric][2] . "\";\n");
-
-    // each metric has two columns..
-    $column_index += 2;
-  }
-  print('</script>');
-  print("\n");
-
-}
-
-/**
- * Generate the profiler report for a single run.
- *
- * @author Kannan
- */
-function profiler_single_run_report ($url_params,
-                                     $xhprof_data,
-                                     $run_desc,
-                                     $rep_symbol,
-                                     $sort,
-                                     $run) {
-
-  init_metrics($xhprof_data, $rep_symbol, $sort, false);
-
-  profiler_report($url_params, $rep_symbol, $sort, $run, $run_desc,
-                  $xhprof_data);
-}
-
-
-
-/**
- * Generate the profiler report for diff mode (delta between two runs).
- *
- * @author Kannan
- */
-function profiler_diff_report($url_params,
-                              $xhprof_data1,
-                              $run1_desc,
-                              $xhprof_data2,
-                              $run2_desc,
-                              $rep_symbol,
-                              $sort,
-                              $run1,
-                              $run2) {
-
-
-  // Initialize what metrics we'll display based on data in Run2
-  init_metrics($xhprof_data2, $rep_symbol, $sort, true);
-
-  profiler_report($url_params,
-                  $rep_symbol,
-                  $sort,
-                  $run1,
-                  $run1_desc,
-                  $xhprof_data1,
-                  $run2,
-                  $run2_desc,
-                  $xhprof_data2);
-}
-
-
-/**
- * Generate a XHProf Display View given the various URL parameters
- * as arguments. The first argument is an object that implements
- * the iXHProfRuns interface.
- *
- * @param object  $xhprof_runs_impl  An object that implements
- *                                   the iXHProfRuns interface
- *.
- * @param array   $url_params   Array of non-default URL params.
- *
- * @param string  $source       Category/type of the run. The source in
- *                              combination with the run id uniquely
- *                              determines a profiler run.
- *
- * @param string  $run          run id, or comma separated sequence of
- *                              run ids. The latter is used if an aggregate
- *                              report of the runs is desired.
- *
- * @param string  $wts          Comma separate list of integers.
- *                              Represents the weighted ratio in
- *                              which which a set of runs will be
- *                              aggregated. [Used only for aggregate
- *                              reports.]
- *
- * @param string  $symbol       Function symbol. If non-empty then the
- *                              parent/child view of this function is
- *                              displayed. If empty, a flat-profile view
- *                              of the functions is displayed.
- *
- * @param string  $run1         Base run id (for diff reports)
- *
- * @param string  $run2         New run id (for diff reports)
- *
- */
-function displayXHProfReport($xhprof_runs_impl, $url_params, $source,
-                             $run, $wts, $symbol, $sort, $run1, $run2) {
-
-  if ($run) {                              // specific run to display?
-
-    // run may be a single run or a comma separate list of runs
-    // that'll be aggregated. If "wts" (a comma separated list
-    // of integral weights is specified), the runs will be
-    // aggregated in that ratio.
-    //
-    $runs_array = explode(",", $run);
-
-    if (count($runs_array) == 1) {
-      $xhprof_data = $xhprof_runs_impl->get_run($runs_array[0],
-                                                $source,
-                                                $description);
-    } else {
-      if (!empty($wts)) {
-        $wts_array  = explode(",", $wts);
-      } else {
-        $wts_array = null;
-      }
-      $data = xhprof_aggregate_runs($xhprof_runs_impl,
-                                    $runs_array, $wts_array, $source, false);
-      $xhprof_data = $data['raw'];
-      $description = $data['description'];
-    }
-
-
-    profiler_single_run_report($url_params,
-                               $xhprof_data,
-                               $description,
-                               $symbol,
-                               $sort,
-                               $run);
-
-  } else if ($run1 && $run2) {                  // diff report for two runs
-
-    $xhprof_data1 = $xhprof_runs_impl->get_run($run1, $source, $description1);
-    $xhprof_data2 = $xhprof_runs_impl->get_run($run2, $source, $description2);
-
-    profiler_diff_report($url_params,
-                         $xhprof_data1,
-                         $description1,
-                         $xhprof_data2,
-                         $description2,
-                         $symbol,
-                         $sort,
-                         $run1,
-                         $run2);
-
-  } else {
-    echo "No XHProf runs specified in the URL.";
-  }
-}

+ 0 - 476
tests/xhprof/xhprof_lib/utils/callgraph_utils.php

@@ -1,476 +0,0 @@
-<?php
-//  Copyright (c) 2009 Facebook
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-/*
- * This file contains callgraph image generation related XHProf utility
- * functions
- *
- */
-
-// Supported ouput format
-$xhprof_legal_image_types = array(
-    "jpg" => 1,
-    "gif" => 1,
-    "png" => 1,
-    "ps"  => 1,
-    );
-
-/**
- * Send an HTTP header with the response. You MUST use this function instead
- * of header() so that we can debug header issues because they're virtually
- * impossible to debug otherwise. If you try to commit header(), SVN will
- * reject your commit.
- *
- * @param string  HTTP header name, like 'Location'
- * @param string  HTTP header value, like 'http://www.example.com/'
- *
- */
-function xhprof_http_header($name, $value) {
-
-  if (!$name) {
-    xhprof_error('http_header usage');
-    return null;
-  }
-
-  if (!is_string($value)) {
-    xhprof_error('http_header value not a string');
-  }
-
-  header($name.': '.$value, true);
-}
-
-/**
- * Genearte and send MIME header for the output image to client browser.
- *
- * @author cjiang
- */
-function xhprof_generate_mime_header($type, $length) {
-  switch ($type) {
-    case 'jpg':
-      $mime = 'image/jpeg';
-      break;
-    case 'gif':
-      $mime = 'image/gif';
-      break;
-    case 'png':
-      $mime = 'image/png';
-      break;
-    case 'ps':
-      $mime = 'application/postscript';
-    default:
-      $mime = false;
-  }
-
-  if ($mime) {
-    xhprof_http_header('Content-type', $mime);
-    xhprof_http_header('Content-length', (string)$length);
-  }
-}
-
-/**
- * Generate image according to DOT script. This function will spawn a process
- * with "dot" command and pipe the "dot_script" to it and pipe out the
- * generated image content.
- *
- * @param dot_script, string, the script for DOT to generate the image.
- * @param type, one of the supported image types, see
- * $xhprof_legal_image_types.
- * @return binary content of the generated image on success. empty string on
- *           failure.
- *
- * @author cjiang
- */
-function xhprof_generate_image_by_dot($dot_script, $type) {
-  $descriptorspec = array(
-       // stdin is a pipe that the child will read from
-       0 => array("pipe", "r"),
-       // stdout is a pipe that the child will write to
-       1 => array("pipe", "w"),
-       // stderr is a file to write to
-       2 => array("file", "/dev/null", "a")
-       );
-
-  $cmd = " dot -T".$type;
-
-  $process = proc_open($cmd, $descriptorspec, $pipes, "/tmp", array());
-
-  if (is_resource($process)) {
-    fwrite($pipes[0], $dot_script);
-    fclose($pipes[0]);
-
-   $output = stream_get_contents($pipes[1]);
-    fclose($pipes[1]);
-
-    proc_close($process);
-    return $output;
-  }
-  print "failed to shell execute cmd=\"$cmd\"\n";
-  exit();
-}
-
-/*
- * Get the children list of all nodes.
- */
-function xhprof_get_children_table($raw_data) {
-  $children_table = array();
-  foreach ($raw_data as $parent_child => $info) {
-    list($parent, $child) = xhprof_parse_parent_child($parent_child);
-    if (!isset($children_table[$parent])) {
-      $children_table[$parent] = array($child);
-    } else {
-      $children_table[$parent][] = $child;
-    }
-  }
-  return $children_table;
-}
-
-/**
- * Generate DOT script from the given raw phprof data.
- *
- * @param raw_data, phprof profile data.
- * @param threshold, float, the threshold value [0,1). The functions in the
- *                   raw_data whose exclusive wall times ratio are below the
- *                   threshold will be filtered out and won't apprear in the
- *                   generated image.
- * @param page, string(optional), the root node name. This can be used to
- *              replace the 'main()' as the root node.
- * @param func, string, the focus function.
- * @param critical_path, bool, whether or not to display critical path with
- *                             bold lines.
- * @return string, the DOT script to generate image.
- *
- * @author cjiang
- */
-function xhprof_generate_dot_script($raw_data, $threshold, $source, $page,
-                                    $func, $critical_path, $right=null,
-                                    $left=null) {
-
-  $max_width = 5;
-  $max_height = 3.5;
-  $max_fontsize = 35;
-  $max_sizing_ratio = 20;
-
-  $totals;
-
-  if ($left === null) {
-    // init_metrics($raw_data, null, null);
-  }
-  $sym_table = xhprof_compute_flat_info($raw_data, $totals);
-
-  if ($critical_path) {
-    $children_table = xhprof_get_children_table($raw_data);
-    $node = "main()";
-    $path = array();
-    $path_edges = array();
-    $visited = array();
-    while ($node) {
-      $visited[$node] = true;
-      if (isset($children_table[$node])) {
-        $max_child = null;
-        foreach ($children_table[$node] as $child) {
-
-          if (isset($visited[$child])) {
-            continue;
-          }
-          if ($max_child === null ||
-            abs($raw_data[xhprof_build_parent_child_key($node,
-                                                        $child)]["wt"]) >
-            abs($raw_data[xhprof_build_parent_child_key($node,
-                                                        $max_child)]["wt"])) {
-            $max_child = $child;
-          }
-        }
-        if ($max_child !== null) {
-          $path[$max_child] = true;
-          $path_edges[xhprof_build_parent_child_key($node, $max_child)] = true;
-        }
-        $node = $max_child;
-      } else {
-        $node = null;
-      }
-    }
-  }
-
-  // if it is a benchmark callgraph, we make the benchmarked function the root.
- if ($source == "bm" && array_key_exists("main()", $sym_table)) {
-    $total_times = $sym_table["main()"]["ct"];
-    $remove_funcs = array("main()",
-                          "hotprofiler_disable",
-                          "call_user_func_array",
-                          "xhprof_disable");
-
-    foreach ($remove_funcs as $cur_del_func) {
-      if (array_key_exists($cur_del_func, $sym_table) &&
-          $sym_table[$cur_del_func]["ct"] == $total_times) {
-        unset($sym_table[$cur_del_func]);
-      }
-    }
-  }
-
-  // use the function to filter out irrelevant functions.
-  if (!empty($func)) {
-    $interested_funcs = array();
-    foreach ($raw_data as $parent_child => $info) {
-      list($parent, $child) = xhprof_parse_parent_child($parent_child);
-      if ($parent == $func || $child == $func) {
-        $interested_funcs[$parent] = 1;
-        $interested_funcs[$child] = 1;
-      }
-    }
-    foreach ($sym_table as $symbol => $info) {
-      if (!array_key_exists($symbol, $interested_funcs)) {
-        unset($sym_table[$symbol]);
-      }
-    }
-  }
-
-  $result = "digraph call_graph {\n";
-
-  // Filter out functions whose exclusive time ratio is below threshold, and
-  // also assign a unique integer id for each function to be generated. In the
-  // meantime, find the function with the most exclusive time (potentially the
-  // performance bottleneck).
-  $cur_id = 0; $max_wt = 0;
-  foreach ($sym_table as $symbol => $info) {
-    if (empty($func) && abs($info["wt"] / $totals["wt"]) < $threshold) {
-      unset($sym_table[$symbol]);
-      continue;
-    }
-    if ($max_wt == 0 || $max_wt < abs($info["excl_wt"])) {
-      $max_wt = abs($info["excl_wt"]);
-    }
-    $sym_table[$symbol]["id"] = $cur_id;
-    $cur_id ++;
-  }
-
-  // Generate all nodes' information.
-  foreach ($sym_table as $symbol => $info) {
-    if ($info["excl_wt"] == 0) {
-      $sizing_factor = $max_sizing_ratio;
-    } else {
-      $sizing_factor = $max_wt / abs($info["excl_wt"]) ;
-      if ($sizing_factor > $max_sizing_ratio) {
-        $sizing_factor = $max_sizing_ratio;
-      }
-    }
-    $fillcolor = (($sizing_factor < 1.5) ?
-                  ", style=filled, fillcolor=red" : "");
-
-    if ($critical_path) {
-      // highlight nodes along critical path.
-      if (!$fillcolor && array_key_exists($symbol, $path)) {
-        $fillcolor = ", style=filled, fillcolor=yellow";
-      }
-    }
-
-    $fontsize =", fontsize="
-               .(int)($max_fontsize / (($sizing_factor - 1) / 10 + 1));
-
-    $width = ", width=".sprintf("%.1f", $max_width / $sizing_factor);
-    $height = ", height=".sprintf("%.1f", $max_height / $sizing_factor);
-
-    if ($symbol == "main()") {
-      $shape = "octagon";
-      $name ="Total: ".($totals["wt"]/1000.0)." ms\\n";
-      $name .= addslashes(isset($page) ? $page : $symbol);
-    } else {
-      $shape = "box";
-      $name = addslashes($symbol)."\\nInc: ". sprintf("%.3f",$info["wt"]/1000) .
-              " ms (" . sprintf("%.1f%%", 100 * $info["wt"]/$totals["wt"]).")";
-    }
-    if ($left === null) {
-      $label = ", label=\"".$name."\\nExcl: "
-               .(sprintf("%.3f",$info["excl_wt"]/1000.0))." ms ("
-               .sprintf("%.1f%%", 100 * $info["excl_wt"]/$totals["wt"])
-               . ")\\n".$info["ct"]." total calls\"";
-    } else {
-      if (isset($left[$symbol]) && isset($right[$symbol])) {
-         $label = ", label=\"".addslashes($symbol).
-                  "\\nInc: ".(sprintf("%.3f",$left[$symbol]["wt"]/1000.0))
-                  ." ms - "
-                  .(sprintf("%.3f",$right[$symbol]["wt"]/1000.0))." ms = "
-                  .(sprintf("%.3f",$info["wt"]/1000.0))." ms".
-                  "\\nExcl: "
-                  .(sprintf("%.3f",$left[$symbol]["excl_wt"]/1000.0))
-                  ." ms - ".(sprintf("%.3f",$right[$symbol]["excl_wt"]/1000.0))
-                   ." ms = ".(sprintf("%.3f",$info["excl_wt"]/1000.0))." ms".
-                  "\\nCalls: ".(sprintf("%.3f",$left[$symbol]["ct"]))." - "
-                   .(sprintf("%.3f",$right[$symbol]["ct"]))." = "
-                   .(sprintf("%.3f",$info["ct"]))."\"";
-      } else if (isset($left[$symbol])) {
-        $label = ", label=\"".addslashes($symbol).
-                  "\\nInc: ".(sprintf("%.3f",$left[$symbol]["wt"]/1000.0))
-                   ." ms - 0 ms = ".(sprintf("%.3f",$info["wt"]/1000.0))
-                   ." ms"."\\nExcl: "
-                   .(sprintf("%.3f",$left[$symbol]["excl_wt"]/1000.0))
-                   ." ms - 0 ms = "
-                   .(sprintf("%.3f",$info["excl_wt"]/1000.0))." ms".
-                  "\\nCalls: ".(sprintf("%.3f",$left[$symbol]["ct"]))." - 0 = "
-                  .(sprintf("%.3f",$info["ct"]))."\"";
-      } else {
-        $label = ", label=\"".addslashes($symbol).
-                  "\\nInc: 0 ms - "
-                  .(sprintf("%.3f",$right[$symbol]["wt"]/1000.0))
-                  ." ms = ".(sprintf("%.3f",$info["wt"]/1000.0))." ms".
-                  "\\nExcl: 0 ms - "
-                  .(sprintf("%.3f",$right[$symbol]["excl_wt"]/1000.0))
-                  ." ms = ".(sprintf("%.3f",$info["excl_wt"]/1000.0))." ms".
-                  "\\nCalls: 0 - ".(sprintf("%.3f",$right[$symbol]["ct"]))
-                  ." = ".(sprintf("%.3f",$info["ct"]))."\"";
-      }
-    }
-    $result .= "N" . $sym_table[$symbol]["id"];
-    $result .= "[shape=$shape ".$label.$width
-               .$height.$fontsize.$fillcolor."];\n";
-  }
-
-  // Generate all the edges' information.
-  foreach ($raw_data as $parent_child => $info) {
-    list($parent, $child) = xhprof_parse_parent_child($parent_child);
-
-    if (isset($sym_table[$parent]) && isset($sym_table[$child]) &&
-        (empty($func) ||
-         (!empty($func) && ($parent == $func || $child == $func)) )) {
-
-      $label = $info["ct"] == 1 ? $info["ct"]." call" : $info["ct"]." calls";
-
-      $headlabel = $sym_table[$child]["wt"] > 0 ?
-                  sprintf("%.1f%%", 100 * $info["wt"]
-                                    / $sym_table[$child]["wt"])
-                  : "0.0%";
-
-      $taillabel = ($sym_table[$parent]["wt"] > 0) ?
-        sprintf("%.1f%%",
-                100 * $info["wt"] /
-                ($sym_table[$parent]["wt"] - $sym_table["$parent"]["excl_wt"]))
-        : "0.0%";
-
-      $linewidth= 1;
-      $arrow_size = 1;
-
-      if ($critical_path &&
-          isset($path_edges[xhprof_build_parent_child_key($parent, $child)])) {
-        $linewidth = 10; $arrow_size=2;
-      }
-
-      $result .= "N" . $sym_table[$parent]["id"] . " -> N"
-                 . $sym_table[$child]["id"];
-      $result .= "[arrowsize=$arrow_size, style=\"setlinewidth($linewidth)\","
-                 ." label=\""
-                 .$label."\", headlabel=\"".$headlabel
-                 ."\", taillabel=\"".$taillabel."\" ]";
-      $result .= ";\n";
-
-    }
-  }
-  $result = $result . "\n}";
-
-  return $result;
-}
-
-function  xhprof_render_diff_image($xhprof_runs_impl, $run1, $run2,
-                                   $type, $threshold, $source) {
-  $total1;
-  $total2;
-
-  $raw_data1 = $xhprof_runs_impl->get_run($run1, $source, $desc_unused);
-  $raw_data2 = $xhprof_runs_impl->get_run($run2, $source, $desc_unused);
-
-  // init_metrics($raw_data1, null, null);
-  $children_table1 = xhprof_get_children_table($raw_data1);
-  $children_table2 = xhprof_get_children_table($raw_data2);
-  $symbol_tab1 = xhprof_compute_flat_info($raw_data1, $total1);
-  $symbol_tab2 = xhprof_compute_flat_info($raw_data2, $total2);
-  $run_delta = xhprof_compute_diff($raw_data1, $raw_data2);
-  $script = xhprof_generate_dot_script($run_delta, $threshold, $source,
-                                       null, null, true,
-                                       $symbol_tab1, $symbol_tab2);
-  $content = xhprof_generate_image_by_dot($script, $type);
-
-  xhprof_generate_mime_header($type, strlen($content));
-  echo $content;
-}
-
-/**
- * Generate image content from phprof run id.
- *
- * @param object  $xhprof_runs_impl  An object that implements
- *                                   the iXHProfRuns interface
- * @param run_id, integer, the unique id for the phprof run, this is the
- *                primary key for phprof database table.
- * @param type, string, one of the supported image types. See also
- *              $xhprof_legal_image_types.
- * @param threshold, float, the threshold value [0,1). The functions in the
- *                   raw_data whose exclusive wall times ratio are below the
- *                   threshold will be filtered out and won't apprear in the
- *                   generated image.
- * @param func, string, the focus function.
- * @return string, the DOT script to generate image.
- *
- * @author cjiang
- */
-function xhprof_get_content_by_run($xhprof_runs_impl, $run_id, $type,
-                                   $threshold, $func, $source,
-                                   $critical_path) {
-  if (!$run_id)
-    return "";
-
-  $raw_data = $xhprof_runs_impl->get_run($run_id, $source, $description);
-  if (!$raw_data) {
-    xhprof_error("Raw data is empty");
-    return "";
-  }
-
-  $script = xhprof_generate_dot_script($raw_data, $threshold, $source,
-                                       $description, $func, $critical_path);
-
-  $content = xhprof_generate_image_by_dot($script, $type);
-  return $content;
-}
-
-/**
- * Generate image from phprof run id and send it to client.
- *
- * @param object  $xhprof_runs_impl  An object that implements
- *                                   the iXHProfRuns interface
- * @param run_id, integer, the unique id for the phprof run, this is the
- *                primary key for phprof database table.
- * @param type, string, one of the supported image types. See also
- *              $xhprof_legal_image_types.
- * @param threshold, float, the threshold value [0,1). The functions in the
- *                   raw_data whose exclusive wall times ratio are below the
- *                   threshold will be filtered out and won't apprear in the
- *                   generated image.
- * @param func, string, the focus function.
- * @param bool, does this run correspond to a PHProfLive run or a dev run?
- * @author cjiang
- */
-function xhprof_render_image($xhprof_runs_impl, $run_id, $type, $threshold,
-                             $func, $source, $critical_path) {
-
-  $content = xhprof_get_content_by_run($xhprof_runs_impl, $run_id, $type,
-                                       $threshold,
-                                       $func, $source, $critical_path);
-  if (!$content) {
-    print "Error: either we can not find profile data for run_id ".$run_id
-          ." or the threshold ".$threshold." is too small or you do not"
-          ." have 'dot' image generation utility installed.";
-    exit();
-  }
-
-  xhprof_generate_mime_header($type, strlen($content));
-  echo $content;
-}

+ 0 - 865
tests/xhprof/xhprof_lib/utils/xhprof_lib.php

@@ -1,865 +0,0 @@
-<?php
-//  Copyright (c) 2009 Facebook
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-//
-// This file contains various XHProf library (utility) functions.
-// Do not add any display specific code here.
-//
-function xhprof_error($message) {
-  error_log($message);
-}
-
-/*
- * The list of possible metrics collected as part of XHProf that
- * require inclusive/exclusive handling while reporting.
- *
- * @author Kannan
- */
-function xhprof_get_possible_metrics() {
- static $possible_metrics =
-   array("wt" => array("Wall", "microsecs", "walltime" ),
-         "ut" => array("User", "microsecs", "user cpu time" ),
-         "st" => array("Sys", "microsecs", "system cpu time"),
-         "cpu" => array("Cpu", "microsecs", "cpu time"),
-         "mu" => array("MUse", "bytes", "memory usage"),
-         "pmu" => array("PMUse", "bytes", "peak memory usage"),
-         "samples" => array("Samples", "samples", "cpu time"));
- return $possible_metrics;
-}
-
-/*
- * Get the list of metrics present in $xhprof_data as an array.
- *
- * @author Kannan
- */
-function xhprof_get_metrics($xhprof_data) {
-
-  // get list of valid metrics
-  $possible_metrics = xhprof_get_possible_metrics();
-
-  // return those that are present in the raw data.
-  // We'll just look at the root of the subtree for this.
-  $metrics = array();
-  foreach ($possible_metrics as $metric => $desc) {
-    if (isset($xhprof_data["main()"][$metric])) {
-      $metrics[] = $metric;
-    }
-  }
-
-  return $metrics;
-}
-
-/**
- * Takes a parent/child function name encoded as
- * "a==>b" and returns array("a", "b").
- *
- * @author Kannan
- */
-function xhprof_parse_parent_child($parent_child) {
-  $ret = explode("==>", $parent_child);
-
-  // Return if both parent and child are set
-  if (isset($ret[1])) {
-    return $ret;
-  }
-
-  return array(null, $ret[0]);
-}
-
-/**
- * Given parent & child function name, composes the key
- * in the format present in the raw data.
- *
- * @author Kannan
- */
-function xhprof_build_parent_child_key($parent, $child) {
-  if ($parent) {
-    return $parent . "==>" . $child;
-  } else {
-    return $child;
-  }
-}
-
-
-/**
- * Checks if XHProf raw data appears to be valid and not corrupted.
- *
- *  @param   int    $run_id        Run id of run to be pruned.
- *                                 [Used only for reporting errors.]
- *  @param   array  $raw_data      XHProf raw data to be pruned
- *                                 & validated.
- *
- *  @return  bool   true on success, false on failure
- *
- *  @author Kannan
- */
-function xhprof_valid_run($run_id, $raw_data) {
-
-  $main_info = $raw_data["main()"];
-  if (empty($main_info)) {
-    xhprof_error("XHProf: main() missing in raw data for Run ID: $run_id");
-    return false;
-  }
-
-  // raw data should contain either wall time or samples information...
-  if (isset($main_info["wt"])) {
-    $metric = "wt";
-  } else if (isset($main_info["samples"])) {
-    $metric = "samples";
-  } else {
-    xhprof_error("XHProf: Wall Time information missing from Run ID: $run_id");
-    return false;
-  }
-
-  foreach ($raw_data as $info) {
-    $val = $info[$metric];
-
-    // basic sanity checks...
-    if ($val < 0) {
-      xhprof_error("XHProf: $metric should not be negative: Run ID $run_id"
-                   . serialize($info));
-      return false;
-    }
-    if ($val > (86400000000)) {
-      xhprof_error("XHProf: $metric > 1 day found in Run ID: $run_id "
-                   . serialize($info));
-      return false;
-    }
-  }
-  return true;
-}
-
-
-/**
- * Return a trimmed version of the XHProf raw data. Note that the raw
- * data contains one entry for each unique parent/child function
- * combination.The trimmed version of raw data will only contain
- * entries where either the parent or child function is in the list
- * of $functions_to_keep.
- *
- * Note: Function main() is also always kept so that overall totals
- * can still be obtained from the trimmed version.
- *
- * @param  array  XHProf raw data
- * @param  array  array of function names
- *
- * @return array  Trimmed XHProf Report
- *
- * @author Kannan
- */
-function xhprof_trim_run($raw_data, $functions_to_keep) {
-
-  // convert list of functions to a hash with function as the key
-  $function_map = array_fill_keys($functions_to_keep, 1);
-
-  // always keep main() as well so that overall totals can still
-  // be computed if need be.
-  $function_map['main()'] = 1;
-
-  $new_raw_data = array();
-  foreach ($raw_data as $parent_child => $info) {
-    list($parent, $child) = xhprof_parse_parent_child($parent_child);
-
-    if (isset($function_map[$parent]) || isset($function_map[$child])) {
-      $new_raw_data[$parent_child] = $info;
-    }
-  }
-
-  return $new_raw_data;
-}
-
-/**
- * Takes raw XHProf data that was aggregated over "$num_runs" number
- * of runs averages/nomalizes the data. Essentially the various metrics
- * collected are divided by $num_runs.
- *
- * @author Kannan
- */
-function xhprof_normalize_metrics($raw_data, $num_runs) {
-
-  if (empty($raw_data) || ($num_runs == 0)) {
-    return $raw_data;
-  }
-
-  $raw_data_total = array();
-
-  if (isset($raw_data["==>main()"]) && isset($raw_data["main()"])) {
-    xhprof_error("XHProf Error: both ==>main() and main() set in raw data...");
-  }
-
-  foreach ($raw_data as $parent_child => $info) {
-    foreach ($info as $metric => $value) {
-      $raw_data_total[$parent_child][$metric] = ($value / $num_runs);
-    }
-  }
-
-  return $raw_data_total;
-}
-
-
-/**
- * Get raw data corresponding to specified array of runs
- * aggregated by certain weightage.
- *
- * Suppose you have run:5 corresponding to page1.php,
- *                  run:6 corresponding to page2.php,
- *             and  run:7 corresponding to page3.php
- *
- * and you want to accumulate these runs in a 2:4:1 ratio. You
- * can do so by calling:
- *
- *     xhprof_aggregate_runs(array(5, 6, 7), array(2, 4, 1));
- *
- * The above will return raw data for the runs aggregated
- * in 2:4:1 ratio.
- *
- *  @param object  $xhprof_runs_impl  An object that implements
- *                                    the iXHProfRuns interface
- *  @param  array  $runs            run ids of the XHProf runs..
- *  @param  array  $wts             integral (ideally) weights for $runs
- *  @param  string $source          source to fetch raw data for run from
- *  @param  bool   $use_script_name If true, a fake edge from main() to
- *                                  to __script::<scriptname> is introduced
- *                                  in the raw data so that after aggregations
- *                                  the script name is still preserved.
- *
- *  @return array  Return aggregated raw data
- *
- *  @author Kannan
- */
-function xhprof_aggregate_runs($xhprof_runs_impl, $runs,
-                               $wts, $source="phprof",
-                               $use_script_name=false) {
-
-  $raw_data_total = null;
-  $raw_data       = null;
-  $metrics        = array();
-
-  $run_count = count($runs);
-  $wts_count = count($wts);
-
-  if (($run_count == 0) ||
-      (($wts_count > 0) && ($run_count != $wts_count))) {
-    return array('description' => 'Invalid input..',
-                 'raw'  => null);
-  }
-
-  $bad_runs = array();
-  foreach($runs as $idx => $run_id) {
-
-    $raw_data = $xhprof_runs_impl->get_run($run_id, $source, $description);
-
-    // use the first run to derive what metrics to aggregate on.
-    if ($idx == 0) {
-      foreach ($raw_data["main()"] as $metric => $val) {
-        if ($metric != "pmu") {
-          // for now, just to keep data size small, skip "peak" memory usage
-          // data while aggregating.
-          // The "regular" memory usage data will still be tracked.
-          if (isset($val)) {
-            $metrics[] = $metric;
-          }
-        }
-      }
-    }
-
-    if (!xhprof_valid_run($run_id, $raw_data)) {
-      $bad_runs[] = $run_id;
-      continue;
-    }
-
-    if ($use_script_name) {
-      $page = $description;
-
-      // create a fake function '__script::$page', and have and edge from
-      // main() to '__script::$page'. We will also need edges to transfer
-      // all edges originating from main() to now originate from
-      // '__script::$page' to all function called from main().
-      //
-      // We also weight main() ever so slightly higher so that
-      // it shows up above the new entry in reports sorted by
-      // inclusive metrics or call counts.
-      if ($page) {
-        foreach($raw_data["main()"] as $metric => $val) {
-          $fake_edge[$metric] = $val;
-          $new_main[$metric]  = $val + 0.00001;
-        }
-        $raw_data["main()"] = $new_main;
-        $raw_data[xhprof_build_parent_child_key("main()",
-                                                "__script::$page")]
-          = $fake_edge;
-      } else {
-        $use_script_name = false;
-      }
-    }
-
-    // if no weights specified, use 1 as the default weightage..
-    $wt = ($wts_count == 0) ? 1 : $wts[$idx];
-
-    // aggregate $raw_data into $raw_data_total with appropriate weight ($wt)
-    foreach ($raw_data as $parent_child => $info) {
-      if ($use_script_name) {
-        // if this is an old edge originating from main(), it now
-        // needs to be from '__script::$page'
-        if (substr($parent_child, 0, 9) == "main()==>") {
-          $child =substr($parent_child, 9);
-          // ignore the newly added edge from main()
-          if (substr($child, 0, 10) != "__script::") {
-            $parent_child = xhprof_build_parent_child_key("__script::$page",
-                                                          $child);
-          }
-        }
-      }
-
-      if (!isset($raw_data_total[$parent_child])) {
-        foreach ($metrics as $metric) {
-          $raw_data_total[$parent_child][$metric] = ($wt * $info[$metric]);
-        }
-      } else {
-        foreach ($metrics as $metric) {
-          $raw_data_total[$parent_child][$metric] += ($wt * $info[$metric]);
-        }
-      }
-    }
-  }
-
-  $runs_string = implode(",", $runs);
-
-  if (isset($wts)) {
-    $wts_string  = "in the ratio (" . implode(":", $wts) . ")";
-    $normalization_count = array_sum($wts);
-  } else {
-    $wts_string = "";
-    $normalization_count = $run_count;
-  }
-
-  $run_count = $run_count - count($bad_runs);
-
-  $data['description'] = "Aggregated Report for $run_count runs: ".
-                         "$runs_string $wts_string\n";
-  $data['raw'] = xhprof_normalize_metrics($raw_data_total,
-                                          $normalization_count);
-  $data['bad_runs'] = $bad_runs;
-
-  return $data;
-}
-
-
-/**
- * Analyze hierarchical raw data, and compute per-function (flat)
- * inclusive and exclusive metrics.
- *
- * Also, store overall totals in the 2nd argument.
- *
- * @param  array $raw_data          XHProf format raw profiler data.
- * @param  array &$overall_totals   OUT argument for returning
- *                                  overall totals for various
- *                                  metrics.
- * @return array Returns a map from function name to its
- *               call count and inclusive & exclusive metrics
- *               (such as wall time, etc.).
- *
- * @author Kannan Muthukkaruppan
- */
-function xhprof_compute_flat_info($raw_data, &$overall_totals) {
-
-  global $display_calls;
-
-  $metrics = xhprof_get_metrics($raw_data);
-
-  $overall_totals = array( "ct" => 0,
-                           "wt" => 0,
-                           "ut" => 0,
-                           "st" => 0,
-                           "cpu" => 0,
-                           "mu" => 0,
-                           "pmu" => 0,
-                           "samples" => 0
-                           );
-
-  // compute inclusive times for each function
-  $symbol_tab = xhprof_compute_inclusive_times($raw_data);
-
-  /* total metric value is the metric value for "main()" */
-  foreach ($metrics as $metric) {
-    $overall_totals[$metric] = $symbol_tab["main()"][$metric];
-  }
-
-  /*
-   * initialize exclusive (self) metric value to inclusive metric value
-   * to start with.
-   * In the same pass, also add up the total number of function calls.
-   */
-  foreach ($symbol_tab as $symbol => $info) {
-    foreach ($metrics as $metric) {
-      $symbol_tab[$symbol]["excl_" . $metric] = $symbol_tab[$symbol][$metric];
-    }
-    if ($display_calls) {
-      /* keep track of total number of calls */
-      $overall_totals["ct"] += $info["ct"];
-    }
-  }
-
-  /* adjust exclusive times by deducting inclusive time of children */
-  foreach ($raw_data as $parent_child => $info) {
-    list($parent, $child) = xhprof_parse_parent_child($parent_child);
-
-    if ($parent) {
-      foreach ($metrics as $metric) {
-        // make sure the parent exists hasn't been pruned.
-        if (isset($symbol_tab[$parent])) {
-          $symbol_tab[$parent]["excl_" . $metric] -= $info[$metric];
-        }
-      }
-    }
-  }
-
-  return $symbol_tab;
-}
-
-/**
- * Hierarchical diff:
- * Compute and return difference of two call graphs: Run2 - Run1.
- *
- * @author Kannan
- */
-function xhprof_compute_diff($xhprof_data1, $xhprof_data2) {
-  global $display_calls;
-
-  // use the second run to decide what metrics we will do the diff on
-  $metrics = xhprof_get_metrics($xhprof_data2);
-
-  $xhprof_delta = $xhprof_data2;
-
-  foreach ($xhprof_data1 as $parent_child => $info) {
-
-    if (!isset($xhprof_delta[$parent_child])) {
-
-      // this pc combination was not present in run1;
-      // initialize all values to zero.
-      if ($display_calls) {
-        $xhprof_delta[$parent_child] = array("ct" => 0);
-      } else {
-        $xhprof_delta[$parent_child] = array();
-      }
-      foreach ($metrics as $metric) {
-        $xhprof_delta[$parent_child][$metric] = 0;
-      }
-    }
-
-    if ($display_calls) {
-      $xhprof_delta[$parent_child]["ct"] -= $info["ct"];
-    }
-
-    foreach ($metrics as $metric) {
-      $xhprof_delta[$parent_child][$metric] -= $info[$metric];
-    }
-  }
-
-  return $xhprof_delta;
-}
-
-
-/**
- * Compute inclusive metrics for function. This code was factored out
- * of xhprof_compute_flat_info().
- *
- * The raw data contains inclusive metrics of a function for each
- * unique parent function it is called from. The total inclusive metrics
- * for a function is therefore the sum of inclusive metrics for the
- * function across all parents.
- *
- * @return array  Returns a map of function name to total (across all parents)
- *                inclusive metrics for the function.
- *
- * @author Kannan
- */
-function xhprof_compute_inclusive_times($raw_data) {
-  global $display_calls;
-
-  $metrics = xhprof_get_metrics($raw_data);
-
-  $symbol_tab = array();
-
-  /*
-   * First compute inclusive time for each function and total
-   * call count for each function across all parents the
-   * function is called from.
-   */
-  foreach ($raw_data as $parent_child => $info) {
-
-    list($parent, $child) = xhprof_parse_parent_child($parent_child);
-
-    if ($parent == $child) {
-      /*
-       * XHProf PHP extension should never trigger this situation any more.
-       * Recursion is handled in the XHProf PHP extension by giving nested
-       * calls a unique recursion-depth appended name (for example, foo@1).
-       */
-      xhprof_error("Error in Raw Data: parent & child are both: $parent");
-      return;
-    }
-
-    if (!isset($symbol_tab[$child])) {
-
-      if ($display_calls) {
-        $symbol_tab[$child] = array("ct" => $info["ct"]);
-      } else {
-        $symbol_tab[$child] = array();
-      }
-      foreach ($metrics as $metric) {
-        $symbol_tab[$child][$metric] = $info[$metric];
-      }
-    } else {
-      if ($display_calls) {
-        /* increment call count for this child */
-        $symbol_tab[$child]["ct"] += $info["ct"];
-      }
-
-      /* update inclusive times/metric for this child  */
-      foreach ($metrics as $metric) {
-        $symbol_tab[$child][$metric] += $info[$metric];
-      }
-    }
-  }
-
-  return $symbol_tab;
-}
-
-
-/*
- * Prunes XHProf raw data:
- *
- * Any node whose inclusive walltime accounts for less than $prune_percent
- * of total walltime is pruned. [It is possible that a child function isn't
- * pruned, but one or more of its parents get pruned. In such cases, when
- * viewing the child function's hierarchical information, the cost due to
- * the pruned parent(s) will be attributed to a special function/symbol
- * "__pruned__()".]
- *
- *  @param   array  $raw_data      XHProf raw data to be pruned & validated.
- *  @param   double $prune_percent Any edges that account for less than
- *                                 $prune_percent of time will be pruned
- *                                 from the raw data.
- *
- *  @return  array  Returns the pruned raw data.
- *
- *  @author Kannan
- */
-function xhprof_prune_run($raw_data, $prune_percent) {
-
-  $main_info = $raw_data["main()"];
-  if (empty($main_info)) {
-    xhprof_error("XHProf: main() missing in raw data");
-    return false;
-  }
-
-  // raw data should contain either wall time or samples information...
-  if (isset($main_info["wt"])) {
-    $prune_metric = "wt";
-  } else if (isset($main_info["samples"])) {
-    $prune_metric = "samples";
-  } else {
-    xhprof_error("XHProf: for main() we must have either wt "
-                 ."or samples attribute set");
-    return false;
-  }
-
-  // determine the metrics present in the raw data..
-  $metrics = array();
-  foreach ($main_info as $metric => $val) {
-    if (isset($val)) {
-      $metrics[] = $metric;
-    }
-  }
-
-  $prune_threshold = (($main_info[$prune_metric] * $prune_percent) / 100.0);
-
-  init_metrics($raw_data, null, null, false);
-  $flat_info = xhprof_compute_inclusive_times($raw_data);
-
-  foreach ($raw_data as $parent_child => $info) {
-
-    list($parent, $child) = xhprof_parse_parent_child($parent_child);
-
-    // is this child's overall total from all parents less than threshold?
-    if ($flat_info[$child][$prune_metric] < $prune_threshold) {
-      unset($raw_data[$parent_child]); // prune the edge
-    } else if ($parent &&
-               ($parent != "__pruned__()") &&
-               ($flat_info[$parent][$prune_metric] < $prune_threshold)) {
-
-      // Parent's overall inclusive metric is less than a threshold.
-      // All edges to the parent node will get nuked, and this child will
-      // be a dangling child.
-      // So instead change its parent to be a special function __pruned__().
-      $pruned_edge = xhprof_build_parent_child_key("__pruned__()", $child);
-
-      if (isset($raw_data[$pruned_edge])) {
-        foreach ($metrics as $metric) {
-          $raw_data[$pruned_edge][$metric]+=$raw_data[$parent_child][$metric];
-        }
-      } else {
-        $raw_data[$pruned_edge] = $raw_data[$parent_child];
-      }
-
-      unset($raw_data[$parent_child]); // prune the edge
-    }
-  }
-
-  return $raw_data;
-}
-
-
-/**
- * Set one key in an array and return the array
- *
- * @author Kannan
- */
-function xhprof_array_set($arr, $k, $v) {
-  $arr[$k] = $v;
-  return $arr;
-}
-
-/**
- * Removes/unsets one key in an array and return the array
- *
- * @author Kannan
- */
-function xhprof_array_unset($arr, $k) {
-  unset($arr[$k]);
-  return $arr;
-}
-
-/**
- * Type definitions for URL params
- */
-define('XHPROF_STRING_PARAM', 1);
-define('XHPROF_UINT_PARAM',   2);
-define('XHPROF_FLOAT_PARAM',  3);
-define('XHPROF_BOOL_PARAM',   4);
-
-
-/**
- * Internal helper function used by various
- * xhprof_get_param* flavors for various
- * types of parameters.
- *
- * @param string   name of the URL query string param
- *
- * @author Kannan
- */
-function xhprof_get_param_helper($param) {
-  $val = null;
-  if (isset($_GET[$param]))
-    $val = $_GET[$param];
-  else if (isset($_POST[$param])) {
-    $val = $_POST[$param];
-  }
-  return $val;
-}
-
-/**
- * Extracts value for string param $param from query
- * string. If param is not specified, return the
- * $default value.
- *
- * @author Kannan
- */
-function xhprof_get_string_param($param, $default = '') {
-  $val = xhprof_get_param_helper($param);
-
-  if ($val === null)
-    return $default;
-
-  return $val;
-}
-
-/**
- * Extracts value for unsigned integer param $param from
- * query string. If param is not specified, return the
- * $default value.
- *
- * If value is not a valid unsigned integer, logs error
- * and returns null.
- *
- * @author Kannan
- */
-function xhprof_get_uint_param($param, $default = 0) {
-  $val = xhprof_get_param_helper($param);
-
-  if ($val === null)
-    $val = $default;
-
-  // trim leading/trailing whitespace
-  $val = trim($val);
-
-  // if it only contains digits, then ok..
-  if (ctype_digit($val)) {
-    return $val;
-  }
-
-  xhprof_error("$param is $val. It must be an unsigned integer.");
-  return null;
-}
-
-
-/**
- * Extracts value for a float param $param from
- * query string. If param is not specified, return
- * the $default value.
- *
- * If value is not a valid unsigned integer, logs error
- * and returns null.
- *
- * @author Kannan
- */
-function xhprof_get_float_param($param, $default = 0) {
-  $val = xhprof_get_param_helper($param);
-
-  if ($val === null)
-    $val = $default;
-
-  // trim leading/trailing whitespace
-  $val = trim($val);
-
-  // TBD: confirm the value is indeed a float.
-  if (true) // for now..
-    return (float)$val;
-
-  xhprof_error("$param is $val. It must be a float.");
-  return null;
-}
-
-/**
- * Extracts value for a boolean param $param from
- * query string. If param is not specified, return
- * the $default value.
- *
- * If value is not a valid unsigned integer, logs error
- * and returns null.
- *
- * @author Kannan
- */
-function xhprof_get_bool_param($param, $default = false) {
-  $val = xhprof_get_param_helper($param);
-
-  if ($val === null)
-    $val = $default;
-
-  // trim leading/trailing whitespace
-  $val = trim($val);
-
-  switch (strtolower($val)) {
-  case '0':
-  case '1':
-    $val = (bool)$val;
-    break;
-  case 'true':
-  case 'on':
-  case 'yes':
-    $val = true;
-    break;
-  case 'false':
-  case 'off':
-  case 'no':
-    $val = false;
-    break;
-  default:
-    xhprof_error("$param is $val. It must be a valid boolean string.");
-    return null;
-  }
-
-  return $val;
-
-}
-
-/**
- * Initialize params from URL query string. The function
- * creates globals variables for each of the params
- * and if the URL query string doesn't specify a particular
- * param initializes them with the corresponding default
- * value specified in the input.
- *
- * @params array $params An array whose keys are the names
- *                       of URL params who value needs to
- *                       be retrieved from the URL query
- *                       string. PHP globals are created
- *                       with these names. The value is
- *                       itself an array with 2-elems (the
- *                       param type, and its default value).
- *                       If a param is not specified in the
- *                       query string the default value is
- *                       used.
- * @author Kannan
- */
-function xhprof_param_init($params) {
-  /* Create variables specified in $params keys, init defaults */
-  foreach ($params as $k => $v) {
-    switch ($v[0]) {
-    case XHPROF_STRING_PARAM:
-      $p = xhprof_get_string_param($k, $v[1]);
-      break;
-    case XHPROF_UINT_PARAM:
-      $p = xhprof_get_uint_param($k, $v[1]);
-      break;
-    case XHPROF_FLOAT_PARAM:
-      $p = xhprof_get_float_param($k, $v[1]);
-      break;
-    case XHPROF_BOOL_PARAM:
-      $p = xhprof_get_bool_param($k, $v[1]);
-      break;
-    default:
-      xhprof_error("Invalid param type passed to xhprof_param_init: "
-                   . $v[0]);
-      exit();
-    }
-
-    // create a global variable using the parameter name.
-    $GLOBALS[$k] = $p;
-  }
-}
-
-
-/**
- * Given a partial query string $q return matching function names in
- * specified XHProf run. This is used for the type ahead function
- * selector.
- *
- * @author Kannan
- */
-function xhprof_get_matching_functions($q, $xhprof_data) {
-
-  $matches = array();
-
-  foreach ($xhprof_data as $parent_child => $info) {
-    list($parent, $child) = xhprof_parse_parent_child($parent_child);
-    if (stripos($parent, $q) !== false) {
-      $matches[$parent] = 1;
-    }
-    if (stripos($child, $q) !== false) {
-      $matches[$child] = 1;
-    }
-  }
-
-  $res = array_keys($matches);
-
-  // sort it so the answers are in some reliable order...
-  asort($res);
-
-  return ($res);
-}
-

+ 0 - 147
tests/xhprof/xhprof_lib/utils/xhprof_runs.php

@@ -1,147 +0,0 @@
-<?php
-//
-//  Copyright (c) 2009 Facebook
-//
-//  Licensed under the Apache License, Version 2.0 (the "License");
-//  you may not use this file except in compliance with the License.
-//  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-
-//
-// This file defines the interface iXHProfRuns and also provides a default
-// implementation of the interface (class XHProfRuns).
-//
-
-/**
- * iXHProfRuns interface for getting/saving a XHProf run.
- *
- * Clients can either use the default implementation,
- * namely XHProfRuns_Default, of this interface or define
- * their own implementation.
- *
- * @author Kannan
- */
-interface iXHProfRuns {
-
-  /**
-   * Returns XHProf data given a run id ($run) of a given
-   * type ($type).
-   *
-   * Also, a brief description of the run is returned via the
-   * $run_desc out parameter.
-   */
-  public function get_run($run_id, $type, &$run_desc);
-
-  /**
-   * Save XHProf data for a profiler run of specified type
-   * ($type).
-   *
-   * The caller may optionally pass in run_id (which they
-   * promise to be unique). If a run_id is not passed in,
-   * the implementation of this method must generated a
-   * unique run id for this saved XHProf run.
-   *
-   * Returns the run id for the saved XHProf run.
-   *
-   */
-  public function save_run($xhprof_data, $type, $run_id = null);
-}
-
-
-/**
- * XHProfRuns_Default is the default implementation of the
- * iXHProfRuns interface for saving/fetching XHProf runs.
- *
- * It stores/retrieves runs to/from a filesystem directory
- * specified by the "xhprof.output_dir" ini parameter.
- *
- * @author Kannan
- */
-class XHProfRuns_Default implements iXHProfRuns {
-
-  private $dir = '';
-
-  private function gen_run_id($type) {
-    return uniqid();
-  }
-
-  private function file_name($run_id, $type) {
-
-    $file = "$run_id.$type";
-
-    if (!empty($this->dir)) {
-      $file = $this->dir . "/" . $file;
-    }
-    return $file;
-  }
-
-  public function __construct($dir = null) {
-
-    // if user hasn't passed a directory location,
-    // we use the xhprof.output_dir ini setting
-    // if specified, else we default to the directory
-    // in which the error_log file resides.
-
-    if (empty($dir)) {
-      $dir = ini_get("xhprof.output_dir");
-      if (empty($dir)) {
-
-        // some default that at least works on unix...
-        $dir = "/tmp";
-
-        xhprof_error("Warning: Must specify directory location for XHProf runs. ".
-                     "Trying {$dir} as default. You can either pass the " .
-                     "directory location as an argument to the constructor ".
-                     "for XHProfRuns_Default() or set xhprof.output_dir ".
-                     "ini param.");
-      }
-    }
-    $this->dir = $dir;
-  }
-
-  public function get_run($run_id, $type, &$run_desc) {
-    $file_name = $this->file_name($run_id, $type);
-
-    if (!file_exists($file_name)) {
-      xhprof_error("Could not find file $file_name");
-      $run_desc = "Invalid Run Id = $run_id";
-      return null;
-    }
-
-    $contents = file_get_contents($file_name);
-    $run_desc = "XHProf Run (Namespace=$type)";
-    return unserialize($contents);
-  }
-
-  public function save_run($xhprof_data, $type, $run_id = null) {
-
-    // Use PHP serialize function to store the XHProf's
-    // raw profiler data.
-    $xhprof_data = serialize($xhprof_data);
-
-    if ($run_id === null) {
-      $run_id = $this->gen_run_id($type);
-    }
-
-    $file_name = $this->file_name($run_id, $type);
-    $file = fopen($file_name, 'w');
-
-    if ($file) {
-      fwrite($file, $xhprof_data);
-      fclose($file);
-    } else {
-      xhprof_error("Could not open $file_name\n");
-    }
-
-    // echo "Saved run in {$file_name}.\nRun id = {$run_id}.\n";
-    return $run_id;
-  }
-}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 4 - 0
web/assetic/sonata_admin_css.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 13 - 0
web/assetic/sonata_admin_js.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
web/assetic/sonata_formatter_css.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
web/assetic/sonata_formatter_js.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 4 - 0
web/assetic/sonata_front_css.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 13 - 0
web/assetic/sonata_front_js.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 3 - 0
web/assetic/sonata_jqueryui_css.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 10 - 0
web/assetic/sonata_jqueryui_js.js


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است