[Phpmyadmin-git] [SCM] phpMyAdmin branch, master, updated. RELEASE_3_4_3_1-14706-g9147f30

Marc Delisle lem9 at users.sourceforge.net
Fri Aug 12 20:45:22 CEST 2011


The branch, master has been updated
       via  9147f30dc6b00dc63c998f1d2d3972d1a47e6c57 (commit)
       via  8f7312956d76eefd1fbf9567a3bb18634e8db560 (commit)
       via  1b7e2f6c7be6c7a96d780a7e9870d498f84e7339 (commit)
       via  ae5ef42beff0475de4a841ff18953e4f66880c40 (commit)
       via  67dc02f23db70391220dc0336f2110645a34a9d2 (commit)
       via  557734c57f45e24abae08a031dde25dab73f1a05 (commit)
       via  201331275bff7e3e67e3d5f3fb2bc706e302ad27 (commit)
       via  e3cb99d540a305caaa58f91d71a5f87d96f28e50 (commit)
       via  57af6f950289ce2283ebe0d4d56b68119b75322b (commit)
       via  33ad955596696415c0cfe0422a067f64f95d1d15 (commit)
       via  241caff7818f69531400eecd1ea63849009bffa9 (commit)
       via  e4b676e3567f2992d9b77f623d328af2fa90cef8 (commit)
       via  7880782588e1609dac657a3c2b2f5a3630929859 (commit)
       via  00c420c74b4663fddf0b5fc47ac50fdd15dd23c6 (commit)
       via  df0848fa9c94a100d153cb4500d723566e8c25c0 (commit)
       via  e83f3acd26fbfb51366cae9b184e69e5376ae10d (commit)
       via  32969f3d4211a96575e2fd7e609cc21ddc63bbaf (commit)
       via  9388cd35b643ea65473ffa95cdf21213bcc4785f (commit)
       via  cb63a92b44a3ab1ee38ec66d63d33432a6273f94 (commit)
       via  d9486e259721b812cb0cd56ca057e55359250cc9 (commit)
       via  e09759bef84ae8113f2e468117be66fb43d4b932 (commit)
       via  18a6f0b0701457dd6a33d6517915c89729d1c11c (commit)
       via  6cc3ff46f853960bdc90eb00fd595591e6a26f2e (commit)
       via  95ea722d73fc635b4b27c6731aeedfd430628ce8 (commit)
       via  bedd413217a87770852671c4a2b211ca067df5e0 (commit)
       via  830f2fdaa72a05497448b5b83b6fb961bf2bd7d2 (commit)
       via  7c66a8bed58fffd66becd643c845027e57e43862 (commit)
       via  b6cb93b017ddd35ab7c2083591228a9874eab60d (commit)
       via  1ce7ea6fb0180722ffadd056b565f63eaf215d4f (commit)
       via  36ec09e6ccec0f46ebc1c92b8c8bc5a396b9a136 (commit)
       via  c01e39a716c5ba33d00ff45f1791d3094fe1c777 (commit)
       via  04e82bb1e908e233f1eb619324b84b18312282d7 (commit)
       via  811996e92a9365afc4c2ff8549ae887336ace5ad (commit)
       via  cdf70921a4976d6fbd79793ba7fa2b5c873bbe2b (commit)
       via  d5d9b38af093708d443a01f9172cc97867343796 (commit)
       via  d90a58d06150f27f008d63c9fee8b92e56afaeea (commit)
       via  362a57f7e1663de26149f27abc4ef49144e8f744 (commit)
       via  ea171beebec90c31107b5972d58761100f9cd122 (commit)
       via  c520c098ad1b4728c751d334dc356bead56a4937 (commit)
       via  12c1471c9b7683f150db76082506d4d90f034787 (commit)
       via  57dc8ce4a595498a7de06ee34c7aa5129da7f934 (commit)
       via  41715e512a7eca3bdc83524fb1c1bf8c3f88fa51 (commit)
       via  28b142b5c314204ddf8590eb194eca2efd4061e5 (commit)
       via  03a1a84b7886d7a8170d8520ad9b8948f1403d7a (commit)
       via  602a64a1d2bf596d51de87618d11eba67c8bf1b4 (commit)
       via  78f93fdd3c64dfe84d1f8459c4c16a39fbf61d60 (commit)
       via  2a4c47c0a244366f3bc623a375ce8280c8dfddcd (commit)
       via  543df4c802d7f21dc0443b207390c4353cfacf4f (commit)
       via  eaea0030641c6be215915684bcd40930ae2d61c8 (commit)
       via  fb8a4956a8fb948f3e2a9e6c2ef3debf5797f2ca (commit)
       via  1653fd340c080d2caefb4c6bf1bd21a98443baa9 (commit)
       via  9498f5d4cd59799f6c7753354180952936cd4680 (commit)
       via  64425ccb66a518fe7c38bfd1c5f09d2e35afce3e (commit)
       via  f64dffd44ab787598eedf500bf8718a3e8d448cf (commit)
       via  f939564bfdfafe0960840b8482fd0a35e249c491 (commit)
       via  763fa66d7281930d57f618c1fba6712394d0a05c (commit)
       via  18694f2d7c81110c35aaa56942cbad5e3d7a4904 (commit)
       via  a4fda9e8f9910a7dc7bec484b722a940e5eec8c0 (commit)
       via  af1f872d81ed31e457094a4294fb3bedda826b85 (commit)
       via  70167fed52368079d1cbffd445514480f29d9ff3 (commit)
       via  c7cef3b0ba0de9af03bcd9d733290e69882d5a29 (commit)
       via  e794690417b8ff32824862909a08fd2b9165e391 (commit)
       via  91d372f9bcca4b92e6e63d7354fcf2a81b6b8f18 (commit)
       via  b225436331c6a770914fdd180327690697d3c478 (commit)
       via  459b57ca578ee4bfcfa6839136dbedbbdabb33a2 (commit)
       via  7396fa3aa9544c480b11edc1b3b2d687b1bca5e8 (commit)
       via  ae44636606a9c7b98d9f5d4998486579a4610a83 (commit)
       via  aac58fd425e4ee4064fa5dbbe666304c5e2b6f2c (commit)
       via  699ca1d3904b0324a8d1fe0359ac40a725e6e92f (commit)
      from  b319651b70b95c1c70d084ab8519109dae9e5450 (commit)


- Log -----------------------------------------------------------------
commit 9147f30dc6b00dc63c998f1d2d3972d1a47e6c57
Author: Marc Delisle <marc at infomarc.info>
Date:   Fri Aug 12 14:44:55 2011 -0400

    Zoom-search in table Search

commit 8f7312956d76eefd1fbf9567a3bb18634e8db560
Merge: b319651 1b7e2f6
Author: Marc Delisle <marc at infomarc.info>
Date:   Fri Aug 12 14:40:56 2011 -0400

    Merge commit '1b7e2f6c7be6c7a96d780a7e9870d498f84e7339'

commit 1b7e2f6c7be6c7a96d780a7e9870d498f84e7339
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Aug 12 23:30:21 2011 +0530

    Added: Missing rgbcolor.js file

commit ae5ef42beff0475de4a841ff18953e4f66880c40
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Aug 12 23:15:38 2011 +0530

    Fixed: Timestamp for time associated fields needed extra 19800000 (+5:30) value

commit 67dc02f23db70391220dc0336f2110645a34a9d2
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Aug 12 20:06:27 2011 +0530

    Fixed: false timestamp error

commit 557734c57f45e24abae08a031dde25dab73f1a05
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Aug 12 20:03:03 2011 +0530

    bug fix

commit 201331275bff7e3e67e3d5f3fb2bc706e302ad27
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Aug 12 18:38:53 2011 +0530

    Fixed: yAxis min value determined on plot generation and not 0 by default

commit e3cb99d540a305caaa58f91d71a5f87d96f28e50
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Aug 12 01:39:22 2011 +0530

    Added better support for datetime fields

commit 57af6f950289ce2283ebe0d4d56b68119b75322b
Merge: 33ad955 d585bba
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Aug 12 00:10:17 2011 +0530

    Merge remote branch 'phpmyadmin/master'
    
    Conflicts:
    	js/tbl_select.js

commit 33ad955596696415c0cfe0422a067f64f95d1d15
Merge: 241caff a5394bd
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Sun Aug 7 10:55:41 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 241caff7818f69531400eecd1ea63849009bffa9
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Wed Aug 3 09:17:16 2011 +0530

    Used AJAX to get data row on point select, hence reducing the amount of data to be sent from server initially for plot.

commit e4b676e3567f2992d9b77f623d328af2fa90cef8
Merge: 7880782 54fbcaa
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Wed Aug 3 09:15:29 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 7880782588e1609dac657a3c2b2f5a3630929859
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Mon Aug 1 10:01:42 2011 +0530

    Added 'Max rows to plot' as input criteria

commit 00c420c74b4663fddf0b5fc47ac50fdd15dd23c6
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Sun Jul 31 12:50:24 2011 +0530

    Edit feature with support for string plot. Also made some optimizations to avoid unnecesarry replot

commit df0848fa9c94a100d153cb4500d723566e8c25c0
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Sun Jul 31 12:41:09 2011 +0530

    String plotting: truncated axis labels with length greater than 10.

commit e83f3acd26fbfb51366cae9b184e69e5376ae10d
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Sun Jul 31 12:35:07 2011 +0530

    Added to 'How to use' message content, strings are converted into integers for plotting purpose.

commit 32969f3d4211a96575e2fd7e609cc21ddc63bbaf
Merge: 9388cd3 e3b91b7
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Sun Jul 31 07:14:01 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 9388cd35b643ea65473ffa95cdf21213bcc4785f
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Mon Jul 25 19:50:02 2011 +0530

    Re:Validations for input form submit (missed addidng messages.php file)

commit cb63a92b44a3ab1ee38ec66d63d33432a6273f94
Merge: d9486e2 c63172f
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Mon Jul 25 19:46:55 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit d9486e259721b812cb0cd56ca057e55359250cc9
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Mon Jul 25 19:45:00 2011 +0530

    Validations for input form submit

commit e09759bef84ae8113f2e468117be66fb43d4b932
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Mon Jul 25 04:50:47 2011 +0530

    Added support for ploting strings(char,varchar,enums)

commit 18a6f0b0701457dd6a33d6517915c89729d1c11c
Merge: 6cc3ff4 73ee863
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Mon Jul 25 04:49:22 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 6cc3ff46f853960bdc90eb00fd595591e6a26f2e
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 22 17:53:13 2011 +0530

    Data point content is now displayed as a dialog box which opens on clicking a point and closes on finishing an edit

commit 95ea722d73fc635b4b27c6731aeedfd430628ce8
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 22 17:51:53 2011 +0530

    Fixed redirection issue on tbl_zoom_select.php page

commit bedd413217a87770852671c4a2b211ca067df5e0
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 22 17:50:09 2011 +0530

    Resolved merge conflict

commit 830f2fdaa72a05497448b5b83b6fb961bf2bd7d2
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 22 16:58:52 2011 +0530

    Merge remote tracking branch 'phpmyadmin'

commit 7c66a8bed58fffd66becd643c845027e57e43862
Merge: b6cb93b 8489f41
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 22 16:50:30 2011 +0530

    Merge remote branch 'phpmyadmin/master'
    
    Conflicts:
    	js/highcharts/highcharts.js

commit b6cb93b017ddd35ab7c2083591228a9874eab60d
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 15 20:04:15 2011 +0530

    Default datalabel bugfix (defaulted to display field everytime)

commit 1ce7ea6fb0180722ffadd056b565f63eaf215d4f
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 15 19:39:42 2011 +0530

    Display field is set as the defualt selected item in the datalabel select element

commit 36ec09e6ccec0f46ebc1c92b8c8bc5a396b9a136
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 15 02:18:29 2011 +0530

    Changed 'How to use?' lnk message onClick event function from this.remove() to PMA_ajaxRemoveMessage()

commit c01e39a716c5ba33d00ff45f1791d3094fe1c777
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 15 00:43:41 2011 +0530

    xAxis type changed to linear (earliear it defaulted to timeseries)

commit 04e82bb1e908e233f1eb619324b84b18312282d7
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 15 00:38:51 2011 +0530

    Default data label now taken from table display field

commit 811996e92a9365afc4c2ff8549ae887336ace5ad
Merge: cdf7092 117dd68
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 15 00:38:31 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit cdf70921a4976d6fbd79793ba7fa2b5c873bbe2b
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Tue Jul 12 06:51:20 2011 +0530

    Fixed misfunction of edit mode

commit d5d9b38af093708d443a01f9172cc97867343796
Merge: d90a58d 4bb11fd
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Tue Jul 12 06:50:46 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit d90a58d06150f27f008d63c9fee8b92e56afaeea
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Sun Jul 10 08:37:15 2011 +0530

    Some indentation errors fixed from previous commit

commit 362a57f7e1663de26149f27abc4ef49144e8f744
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Sun Jul 10 08:14:00 2011 +0530

    Functionality for edit data points added (primitive)

commit ea171beebec90c31107b5972d58761100f9cd122
Merge: c520c09 1962e36
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Sun Jul 10 08:13:46 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit c520c098ad1b4728c751d334dc356bead56a4937
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 8 02:34:49 2011 +0530

    On submit of an edit, the data point remains selected in the plot.

commit 12c1471c9b7683f150db76082506d4d90f034787
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 8 02:26:56 2011 +0530

    Changed text for 'How to use?' link 9$js_messages['strDisplayHelp'])

commit 57dc8ce4a595498a7de06ee34c7aa5129da7f934
Merge: 41715e5 5140c38
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Thu Jul 7 21:00:10 2011 +0530

    Merge remote branch 'phpmyadmin/master'
    
    Conflicts:
    	libraries/config.default.php
    	tbl_select.php

commit 41715e512a7eca3bdc83524fb1c1bf8c3f88fa51
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Thu Jul 7 20:53:32 2011 +0530

    Removed mode feature, appended a missing configuration directive and changed help link duration to 10sec

commit 28b142b5c314204ddf8590eb194eca2efd4061e5
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Tue Jul 5 05:22:38 2011 +0530

    Made some changes
      -> Browse Mode makes the dialog fields disabled
      -> New name for max row to plot directive
      -> Show/Hide search criteria
      -> Link for displaying Help

commit 03a1a84b7886d7a8170d8520ad9b8948f1403d7a
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Tue Jul 5 05:21:16 2011 +0530

    Test

commit 602a64a1d2bf596d51de87618d11eba67c8bf1b4
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Mon Jul 4 21:59:17 2011 +0530

    Added the Show/Hide search criteria feature

commit 78f93fdd3c64dfe84d1f8459c4c16a39fbf61d60
Merge: 2a4c47c 064d399
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Mon Jul 4 21:58:47 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 2a4c47c0a244366f3bc623a375ce8280c8dfddcd
Merge: 543df4c 2279fd9
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 1 15:34:39 2011 +0530

    Merge remote branch 'phpmyadmin/master'
    
    Conflicts:
    	tbl_select.php

commit 543df4c802d7f21dc0443b207390c4353cfacf4f
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jul 1 15:31:56 2011 +0530

    Added interface for browsing/editing points

commit eaea0030641c6be215915684bcd40930ae2d61c8
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Tue Jun 21 05:04:00 2011 +0530

    Added some features
     -> Limit on max number of rows retreived(500)
     -> An instruction link regarding how to use
     -> Resize plot by dragging it by the bottom right corner
     -> Two additional search criteria

commit fb8a4956a8fb948f3e2a9e6c2ef3debf5797f2ca
Merge: 1653fd3 d9304ef
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Tue Jun 21 04:35:24 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 1653fd340c080d2caefb4c6bf1bd21a98443baa9
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jun 17 01:31:31 2011 +0530

    Plot functionality using Hihcharts

commit 9498f5d4cd59799f6c7753354180952936cd4680
Merge: 64425cc 4338b70
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jun 17 01:06:38 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 64425ccb66a518fe7c38bfd1c5f09d2e35afce3e
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jun 10 06:58:23 2011 +0530

    Fixed some issues and added support for plotting strings

commit f64dffd44ab787598eedf500bf8718a3e8d448cf
Merge: f939564 cd5cddb
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri Jun 10 06:56:52 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit f939564bfdfafe0960840b8482fd0a35e249c491
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Thu Jun 9 03:03:22 2011 +0530

    Created the SVG based scatter-plot functionality
       -> Created classes corresponding to the plot and data objects, currently only data points
       -> Plots only for numeric fields

commit 763fa66d7281930d57f618c1fba6712394d0a05c
Merge: 18694f2 90099b7
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Thu Jun 9 02:54:33 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 18694f2d7c81110c35aaa56942cbad5e3d7a4904
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Mon Jun 6 04:18:47 2011 +0530

    Added generate plot feature using SVG ( only for numeric fields )

commit a4fda9e8f9910a7dc7bec484b722a940e5eec8c0
Merge: af1f872 8b47a1d
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Mon Jun 6 04:16:55 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit af1f872d81ed31e457094a4294fb3bedda826b85
Merge: 70167fe 75091e5
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Sat Jun 4 13:55:18 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 70167fed52368079d1cbffd445514480f29d9ff3
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Wed Jun 1 01:22:31 2011 +0530

    Made suggested change to tbl_select.php and tbl_zoom_select.php

commit c7cef3b0ba0de9af03bcd9d733290e69882d5a29
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Tue May 31 19:02:50 2011 +0530

    Refactored the tbl_select.php and tbl_zoom_select.php code in libraries/tbl_select.lib.php
    Parts refactored are:
    -> Setting titles
    -> getting fields list
    -> setting sub-tabs
    -> setting table header of QBE display
    -> displaying foreign data
    -> search criteria input elements

commit e794690417b8ff32824862909a08fd2b9165e391
Merge: 91d372f a47ac24
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Tue May 31 18:59:28 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 91d372f9bcca4b92e6e63d7354fcf2a81b6b8f18
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Sun May 29 12:16:13 2011 +0530

    Added a library file for the table-search and zoom-search code
    Contains two functions:
    -> Get Field list and details
    -> Get where clause of query generation process

commit b225436331c6a770914fdd180327690697d3c478
Merge: 459b57c ae0af9e
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Sun May 29 12:14:04 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 459b57ca578ee4bfcfa6839136dbedbbdabb33a2
Merge: 7396fa3 434d233
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Fri May 27 17:46:30 2011 +0530

    Merge remote branch 'phpmyadmin/master'

commit 7396fa3aa9544c480b11edc1b3b2d687b1bca5e8
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Thu May 26 12:22:16 2011 +0530

    Designed the zoom-search form(tbl_zoom_select.php)
    -> User selecte exactly two columns.
    -> Generates two queries, one for each column criteria.

commit ae44636606a9c7b98d9f5d4998486579a4610a83
Author: Ammar Yasir <ammaryasir.88 at gmail.com>
Date:   Mon May 23 21:26:07 2011 +0530

    Made some changes on the tbl_select.php page to add a link for Zoom Search.
    Please dont mind the coding, I just coded very quickly to get back comments. If the flow of the interface is ok I'll code it properly.

commit aac58fd425e4ee4064fa5dbbe666304c5e2b6f2c
Author: root <root at localhost.localdomain>
Date:   Wed May 18 22:40:33 2011 +0530

    testing for push

commit 699ca1d3904b0324a8d1fe0359ac40a725e6e92f
Author: root <root at localhost.localdomain>
Date:   Wed May 18 22:30:26 2011 +0530

    Just testing upload

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                   |    1 +
 config.sample.inc.php                       |    2 +-
 db_structure.php                            |    1 +
 js/canvg/canvg.js                           |  304 +++-----------
 js/canvg/rgbcolor.js                        |  288 +++++++++++++
 js/date.js                                  |  335 +++++++++++++++
 js/messages.php                             |    6 +
 js/tbl_select.js                            |    2 +-
 js/tbl_zoom_plot.js                         |  605 +++++++++++++++++++++++++++
 libraries/common.inc.php                    |    1 +
 libraries/config.default.php                |  425 +++++++++++++++++--
 libraries/svg_plot/pma_scatter_plot.php     |  267 ++++++++++++
 libraries/svg_plot/pma_svg_data_element.php |   50 +++
 libraries/svg_plot/pma_svg_data_point.php   |   86 ++++
 libraries/tbl_select.lib.php                |  390 +++++++++++++++++
 tbl_select.php                              |  280 +++----------
 tbl_zoom_select.php                         |  447 ++++++++++++++++++++
 17 files changed, 2976 insertions(+), 514 deletions(-)
 create mode 100644 js/canvg/rgbcolor.js
 create mode 100644 js/date.js
 create mode 100644 js/tbl_zoom_plot.js
 create mode 100644 libraries/svg_plot/pma_scatter_plot.php
 create mode 100644 libraries/svg_plot/pma_svg_data_element.php
 create mode 100644 libraries/svg_plot/pma_svg_data_point.php
 create mode 100644 libraries/tbl_select.lib.php
 create mode 100644 tbl_zoom_select.php

diff --git a/ChangeLog b/ChangeLog
index 633d481..e6c1bc4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -43,6 +43,7 @@ phpMyAdmin - ChangeLog
 + AJAX for table Operations copy table
 - bug #3380946 [export] no uid Query result export (Suhosin limit)
 + Grid editing in browse mode (replaces row inline edit)
++ Zoom-search in table Search
 
 3.4.5.0 (not yet released)
 - bug #3375325 [interface] Page list in navigation frame looks odd
diff --git a/config.sample.inc.php b/config.sample.inc.php
index edffd03..778785e 100644
--- a/config.sample.inc.php
+++ b/config.sample.inc.php
@@ -14,7 +14,7 @@
  * This is needed for cookie based authentication to encrypt password in
  * cookie
  */
-$cfg['blowfish_secret'] = ''; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
+$cfg['blowfish_secret'] = 'a8b7c6d'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
 
 /*
  * Servers configuration
diff --git a/db_structure.php b/db_structure.php
index d76bcca..9c2e045 100644
--- a/db_structure.php
+++ b/db_structure.php
@@ -57,6 +57,7 @@ require_once './libraries/db_structure.lib.php';
 $titles = PMA_buildActionTitles();
 
 // 1. No tables
+
 if ($num_tables == 0) {
     echo '<p>' . __('No tables found in database') . '</p>' . "\n";
 
diff --git a/js/canvg/canvg.js b/js/canvg/canvg.js
index 19a47a7..dbc5a9d 100644
--- a/js/canvg/canvg.js
+++ b/js/canvg/canvg.js
@@ -12,6 +12,7 @@ if(!window.console) {
 	window.console.dir = function(str) {};
 }
 
+// <3 IE
 if(!Array.indexOf){
 	Array.prototype.indexOf = function(obj){
 		for(var i=0; i<this.length; i++){
@@ -27,7 +28,7 @@ if(!Array.indexOf){
 	// canvg(target, s)
 	// empty parameters: replace all 'svg' elements on page with 'canvas' elements
 	// target: canvas element or the id of a canvas element
-	// s: svg string, url to svg file, or xml document
+	// s: svg string or url to svg file
 	// opts: optional hash of options
 	//		 ignoreMouse: true => ignore mouse events
 	//		 ignoreAnimation: true => ignore animations
@@ -74,11 +75,7 @@ if(!Array.indexOf){
 		svg.opts = opts;
 		
 		var ctx = target.getContext('2d');
-		if (typeof(s.documentElement) != 'undefined') {
-			// load from xml doc
-			svg.loadXmlDoc(ctx, s);
-		}
-		else if (s.substr(0,1) == '<') {
+		if (s.substr(0,1) == '<') {
 			// load from xml string
 			svg.loadXml(ctx, s);
 		}
@@ -92,7 +89,6 @@ if(!Array.indexOf){
 		var svg = { };
 		
 		svg.FRAMERATE = 30;
-		svg.MAX_VIRTUAL_PIXELS = 30000;
 		
 		// globals
 		svg.init = function(ctx) {
@@ -103,7 +99,6 @@ if(!Array.indexOf){
 			svg.ctx = ctx;
 			svg.ViewPort = new (function () {
 				this.viewPorts = [];
-				this.Clear = function() { this.viewPorts = []; }
 				this.SetCurrent = function(width, height) { this.viewPorts.push({ width: width, height: height }); }
 				this.RemoveCurrent = function() { this.viewPorts.pop(); }
 				this.Current = function() { return this.viewPorts[this.viewPorts.length - 1]; }
@@ -556,7 +551,7 @@ if(!Array.indexOf){
 				}
 			}
 			
-			var data = svg.trim(svg.compressSpaces(v)).split(/\s(?=[a-z])/);
+			var data = v.split(/\s(?=[a-z])/);
 			for (var i=0; i<data.length; i++) {
 				var type = data[i].split('(')[0];
 				var s = data[i].split('(')[1].replace(')','');
@@ -621,7 +616,7 @@ if(!Array.indexOf){
 				return a;
 			}
 			
-			// get or create style, crawls up node tree
+			// get or create style
 			this.style = function(name, createIfNotExists) {
 				var s = this.styles[name];
 				if (s != null) return s;
@@ -630,14 +625,6 @@ if(!Array.indexOf){
 				if (a != null && a.hasValue()) {
 					return a;
 				}
-				
-				var p = this.parent;
-				if (p != null) {
-					var ps = p.style(name);
-					if (ps != null && ps.hasValue()) {
-						return ps;
-					}
-				}
 					
 				s = new svg.Property(name, '');
 				if (createIfNotExists == true) this.styles[name] = s;
@@ -648,9 +635,6 @@ if(!Array.indexOf){
 			this.render = function(ctx) {
 				// don't render display=none
 				if (this.attribute('display').value == 'none') return;
-				
-				// don't render visibility=hidden
-				if (this.attribute('visibility').value == 'hidden') return;
 			
 				ctx.save();
 				this.setContext(ctx);
@@ -697,7 +681,7 @@ if(!Array.indexOf){
 				}
 										
 				// add tag styles
-				var styles = svg.Styles[node.nodeName];
+				var styles = svg.Styles[this.type];
 				if (styles != null) {
 					for (var name in styles) {
 						this.styles[name] = styles[name];
@@ -714,12 +698,6 @@ if(!Array.indexOf){
 								this.styles[name] = styles[name];
 							}
 						}
-						styles = svg.Styles[node.nodeName+'.'+classes[j]];
-						if (styles != null) {
-							for (var name in styles) {
-								this.styles[name] = styles[name];
-							}
-						}
 					}
 				}
 				
@@ -878,7 +856,7 @@ if(!Array.indexOf){
 				
 				var width = svg.ViewPort.width();
 				var height = svg.ViewPort.height();
-				if (typeof(this.root) == 'undefined' && this.attribute('width').hasValue() && this.attribute('height').hasValue()) {
+				if (this.attribute('width').hasValue() && this.attribute('height').hasValue()) {
 					width = this.attribute('width').Length.toPixels('x');
 					height = this.attribute('height').Length.toPixels('y');
 					
@@ -1208,6 +1186,9 @@ if(!Array.indexOf){
 				pp.reset();
 
 				var bb = new svg.BoundingBox();
+				
+				if(this.attribute('visibility').value=='hidden') return;
+				
 				if (ctx != null) ctx.beginPath();
 				while (!pp.isEnd()) {
 					pp.nextCommand();
@@ -1488,37 +1469,6 @@ if(!Array.indexOf){
 				for (var i=0; i<stopsContainer.stops.length; i++) {
 					g.addColorStop(stopsContainer.stops[i].offset, stopsContainer.stops[i].color);
 				}
-				
-				if (this.attribute('gradientTransform').hasValue()) {
-					// render as transformed pattern on temporary canvas
-					var rootView = svg.ViewPort.viewPorts[0];
-					
-					var rect = new svg.Element.rect();
-					rect.attributes['x'] = new svg.Property('x', -svg.MAX_VIRTUAL_PIXELS/3.0);
-					rect.attributes['y'] = new svg.Property('y', -svg.MAX_VIRTUAL_PIXELS/3.0);
-					rect.attributes['width'] = new svg.Property('width', svg.MAX_VIRTUAL_PIXELS);
-					rect.attributes['height'] = new svg.Property('height', svg.MAX_VIRTUAL_PIXELS);
-					
-					var group = new svg.Element.g();
-					group.attributes['transform'] = new svg.Property('transform', this.attribute('gradientTransform').value);
-					group.children = [ rect ];
-					
-					var tempSvg = new svg.Element.svg();
-					tempSvg.attributes['x'] = new svg.Property('x', 0);
-					tempSvg.attributes['y'] = new svg.Property('y', 0);
-					tempSvg.attributes['width'] = new svg.Property('width', rootView.width);
-					tempSvg.attributes['height'] = new svg.Property('height', rootView.height);
-					tempSvg.children = [ group ];
-					
-					var c = document.createElement('canvas');
-					c.width = rootView.width;
-					c.height = rootView.height;
-					var tempCtx = c.getContext('2d');
-					tempCtx.fillStyle = g;
-					tempSvg.render(tempCtx);		
-					return tempCtx.createPattern(c, 'no-repeat');
-				}
-				
 				return g;				
 			}
 		}
@@ -1544,8 +1494,16 @@ if(!Array.indexOf){
 				var y2 = (this.gradientUnits == 'objectBoundingBox' 
 					? bb.y() + bb.height() * this.attribute('y2').numValue()
 					: this.attribute('y2').Length.toPixels('y'));
-
-				return ctx.createLinearGradient(x1, y1, x2, y2);
+				
+				var p1 = new svg.Point(x1, y1);
+				var p2 = new svg.Point(x2, y2);
+				if (this.attribute('gradientTransform').hasValue()) { 
+					var transform = new svg.Transform(this.attribute('gradientTransform').value);
+					transform.applyToPoint(p1);
+					transform.applyToPoint(p2);
+				}
+				
+				return ctx.createLinearGradient(p1.x, p1.y, p2.x, p2.y);
 			}
 		}
 		svg.Element.linearGradient.prototype = new svg.Element.GradientBase;
@@ -1582,7 +1540,22 @@ if(!Array.indexOf){
 					? (bb.width() + bb.height()) / 2.0 * this.attribute('r').numValue()
 					: this.attribute('r').Length.toPixels());
 				
-				return ctx.createRadialGradient(fx, fy, 0, cx, cy, r);
+				var c = new svg.Point(cx, cy);
+				var f = new svg.Point(fx, fy);
+				if (this.attribute('gradientTransform').hasValue()) { 
+					var transform = new svg.Transform(this.attribute('gradientTransform').value);
+					transform.applyToPoint(c);
+					transform.applyToPoint(f);
+					
+					for (var i=0; i<transform.transforms.length; i++) {
+						// average the scaling part of the transform, apply to radius
+						var scale1 = transform.transforms[i].m[0];
+						var scale2 = transform.transforms[i].m[3];
+						r = r * ((scale1 + scale2) / 2.0);
+					}
+				}				
+				
+				return ctx.createRadialGradient(f.x, f.y, 0, c.x, c.y, r);
 			}
 		}
 		svg.Element.radialGradient.prototype = new svg.Element.GradientBase;
@@ -1720,73 +1693,6 @@ if(!Array.indexOf){
 		}
 		svg.Element.animateTransform.prototype = new svg.Element.animate;
 		
-		// font element
-		svg.Element.font = function(node) {
-			this.base = svg.Element.ElementBase;
-			this.base(node);
-
-			this.horizAdvX = this.attribute('horiz-adv-x').numValue();			
-			
-			this.isRTL = false;
-			this.isArabic = false;
-			this.fontFace = null;
-			this.missingGlyph = null;
-			this.glyphs = [];			
-			for (var i=0; i<this.children.length; i++) {
-				var child = this.children[i];
-				if (child.type == 'font-face') {
-					this.fontFace = child;
-					if (child.style('font-family').hasValue()) {
-						svg.Definitions[child.style('font-family').value] = this;
-					}
-				}
-				else if (child.type == 'missing-glyph') this.missingGlyph = child;
-				else if (child.type == 'glyph') {
-					if (child.arabicForm != '') {
-						this.isRTL = true;
-						this.isArabic = true;
-						if (typeof(this.glyphs[child.unicode]) == 'undefined') this.glyphs[child.unicode] = [];
-						this.glyphs[child.unicode][child.arabicForm] = child;
-					}
-					else {
-						this.glyphs[child.unicode] = child;
-					}
-				}
-			}	
-		}
-		svg.Element.font.prototype = new svg.Element.ElementBase;
-		
-		// font-face element
-		svg.Element.fontface = function(node) {
-			this.base = svg.Element.ElementBase;
-			this.base(node);	
-			
-			this.ascent = this.attribute('ascent').value;
-			this.descent = this.attribute('descent').value;
-			this.unitsPerEm = this.attribute('units-per-em').numValue();				
-		}
-		svg.Element.fontface.prototype = new svg.Element.ElementBase;
-		
-		// missing-glyph element
-		svg.Element.missingglyph = function(node) {
-			this.base = svg.Element.path;
-			this.base(node);	
-			
-			this.horizAdvX = 0;
-		}
-		svg.Element.missingglyph.prototype = new svg.Element.path;
-		
-		// glyph element
-		svg.Element.glyph = function(node) {
-			this.base = svg.Element.path;
-			this.base(node);	
-			
-			this.horizAdvX = this.attribute('horiz-adv-x').numValue();
-			this.unicode = this.attribute('unicode').value;
-			this.arabicForm = this.attribute('arabic-form').value;
-		}
-		svg.Element.glyph.prototype = new svg.Element.path;
-		
 		// text element
 		svg.Element.text = function(node) {
 			this.base = svg.Element.RenderedElementBase;
@@ -1809,16 +1715,19 @@ if(!Array.indexOf){
 			this.baseSetContext = this.setContext;
 			this.setContext = function(ctx) {
 				this.baseSetContext(ctx);
-				if (this.style('text-anchor').hasValue()) {
-					var textAnchor = this.style('text-anchor').value;
+				if (this.attribute('text-anchor').hasValue()) {
+					var textAnchor = this.attribute('text-anchor').value;
 					ctx.textAlign = textAnchor == 'middle' ? 'center' : textAnchor;
 				}
 				if (this.attribute('alignment-baseline').hasValue()) ctx.textBaseline = this.attribute('alignment-baseline').value;
 			}
 			
 			this.renderChildren = function(ctx) {
+				if(this.attribute('visibility').value=='hidden') return;
+				
 				var x = this.attribute('x').Length.toPixels('x');
 				var y = this.attribute('y').Length.toPixels('y');
+				
 				for (var i=0; i<this.children.length; i++) {
 					var child = this.children[i];
 				
@@ -1850,63 +1759,8 @@ if(!Array.indexOf){
 			this.base = svg.Element.RenderedElementBase;
 			this.base(node);
 			
-			this.getGlyph = function(font, text, i) {
-				var c = text[i];
-				var glyph = null;
-				if (font.isArabic) {
-					var arabicForm = 'isolated';
-					if ((i==0 || text[i-1]==' ') && i<text.length-2 && text[i+1]!=' ') arabicForm = 'terminal'; 
-					if (i>0 && text[i-1]!=' ' && i<text.length-2 && text[i+1]!=' ') arabicForm = 'medial';
-					if (i>0 && text[i-1]!=' ' && (i == text.length-1 || text[i+1]==' ')) arabicForm = 'initial';
-					if (typeof(font.glyphs[c]) != 'undefined') {
-						glyph = font.glyphs[c][arabicForm];
-						if (glyph == null && font.glyphs[c].type == 'glyph') glyph = font.glyphs[c];
-					}
-				}
-				else {
-					glyph = font.glyphs[c];
-				}
-				if (glyph == null) glyph = font.missingGlyph;
-				return glyph;
-			}
-			
 			this.renderChildren = function(ctx) {
-				var customFont = this.parent.style('font-family').Definition.getDefinition();
-				if (customFont != null) {
-					var fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize);
-					var fontStyle = this.parent.style('font-style').valueOrDefault(svg.Font.Parse(svg.ctx.font).fontStyle);
-					var text = this.getText();
-					if (customFont.isRTL) text = text.split("").reverse().join("");
-					
-					if (this.parent.style('text-anchor').value == 'middle') {
-						this.x = this.x - this.measureText(ctx) / 2.0;
-					}
-					
-					var dx = svg.ToNumberArray(this.parent.attribute('dx').value);
-					for (var i=0; i<text.length; i++) {
-						var glyph = this.getGlyph(customFont, text, i);
-						var scale = fontSize / customFont.fontFace.unitsPerEm;
-						ctx.translate(this.x, this.y);
-						ctx.scale(scale, -scale);
-						var lw = ctx.lineWidth;
-						ctx.lineWidth = ctx.lineWidth * customFont.fontFace.unitsPerEm / fontSize;
-						if (fontStyle == 'italic') ctx.transform(1, 0, .4, 1, 0, 0);
-						glyph.render(ctx);
-						if (fontStyle == 'italic') ctx.transform(1, 0, -.4, 1, 0, 0);
-						ctx.lineWidth = lw;
-						ctx.scale(1/scale, -1/scale);
-						ctx.translate(-this.x, -this.y);	
-						
-						this.x += fontSize * (glyph.horizAdvX || customFont.horizAdvX) / customFont.fontFace.unitsPerEm;
-						if (typeof(dx[i]) != 'undefined' && !isNaN(dx[i])) {
-							this.x += dx[i];
-						}
-					}
-					return;
-				}
-			
-				if (ctx.strokeStyle != '') ctx.strokeText(svg.compressSpaces(this.getText()), this.x, this.y);
-				if (ctx.fillStyle != '') ctx.fillText(svg.compressSpaces(this.getText()), this.x, this.y);
+				ctx.fillText(svg.compressSpaces(this.getText()), this.x, this.y);
 			}
 			
 			this.getText = function() {
@@ -1914,23 +1768,6 @@ if(!Array.indexOf){
 			}
 			
 			this.measureText = function(ctx) {
-				var customFont = this.parent.style('font-family').Definition.getDefinition();
-				if (customFont != null) {
-					var fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize);
-					var measure = 0;
-					var text = this.getText();
-					if (customFont.isRTL) text = text.split("").reverse().join("");
-					var dx = svg.ToNumberArray(this.parent.attribute('dx').value);
-					for (var i=0; i<text.length; i++) {
-						var glyph = this.getGlyph(customFont, text, i);
-						measure += (glyph.horizAdvX || customFont.horizAdvX) * fontSize / customFont.fontFace.unitsPerEm;
-						if (typeof(dx[i]) != 'undefined' && !isNaN(dx[i])) {
-							measure += dx[i];
-						}
-					}
-					return measure;
-				}
-			
 				var textToMeasure = svg.compressSpaces(this.getText());
 				if (!ctx.measureText) return textToMeasure.length * 10;
 				return ctx.measureText(textToMeasure).width;
@@ -1943,9 +1780,8 @@ if(!Array.indexOf){
 			this.base = svg.Element.TextElementBase;
 			this.base(node);
 			
-			this.text = node.nodeType == 3 ? node.nodeValue : // text
-						node.childNodes.length > 0 ? node.childNodes[0].nodeValue : // element
-						node.text;
+			//								 TEXT			  ELEMENT
+			this.text = node.nodeType == 3 ? node.nodeValue : node.childNodes[0].nodeValue;
 			this.getText = function() {
 				return this.text;
 			}
@@ -2095,9 +1931,8 @@ if(!Array.indexOf){
 			this.base = svg.Element.ElementBase;
 			this.base(node);
 			
-			// text, or spaces then CDATA
-			var css = node.childNodes[0].nodeValue + (node.childNodes.length > 1 ? node.childNodes[1].nodeValue : '');
-			css = css.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(^[\s]*\/\/.*)/gm, ''); // remove comments
+			var css = node.childNodes[0].nodeValue;
+			css = css.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(\/\/.*)/gm, ''); // remove comments
 			css = svg.compressSpaces(css); // replace whitespace
 			var cssDefs = css.split('}');
 			for (var i=0; i<cssDefs.length; i++) {
@@ -2110,31 +1945,14 @@ if(!Array.indexOf){
 						if (cssClass != '') {
 							var props = {};
 							for (var k=0; k<cssProps.length; k++) {
-								var prop = cssProps[k].indexOf(':');
-								var name = cssProps[k].substr(0, prop);
-								var value = cssProps[k].substr(prop + 1, cssProps[k].length - prop);
+								var prop = cssProps[k].split(':');
+								var name = prop[0];
+								var value = prop[1];
 								if (name != null && value != null) {
-									props[svg.trim(name)] = new svg.Property(svg.trim(name), svg.trim(value));
+									props[svg.trim(prop[0])] = new svg.Property(svg.trim(prop[0]), svg.trim(prop[1]));
 								}
 							}
 							svg.Styles[cssClass] = props;
-							if (cssClass == '@font-face') {
-								var fontFamily = props['font-family'].value.replace(/"/g,'');
-								var srcs = props['src'].value.split(',');
-								for (var s=0; s<srcs.length; s++) {
-									if (srcs[s].indexOf('format("svg")') > 0) {
-										var urlStart = srcs[s].indexOf('url');
-										var urlEnd = srcs[s].indexOf(')', urlStart);
-										var url = srcs[s].substr(urlStart + 5, urlEnd - urlStart - 6);
-										var doc = svg.parseXml(svg.ajax(url));
-										var fonts = doc.getElementsByTagName('font');
-										for (var f=0; f<fonts.length; f++) {
-											var font = svg.CreateElement(fonts[f]);
-											svg.Definitions[fontFamily] = font;
-										}
-									}
-								}
-							}
 						}
 					}
 				}
@@ -2186,10 +2004,6 @@ if(!Array.indexOf){
 					}
 				}
 			}
-			
-			this.render = function(ctx) {
-				// NO RENDER
-			}
 		}
 		svg.Element.clipPath.prototype = new svg.Element.ElementBase;
 
@@ -2210,8 +2024,7 @@ if(!Array.indexOf){
 		
 		// element factory
 		svg.CreateElement = function(node) {	
-			var className = node.nodeName.replace(/^[^:]+:/,''); // remove namespace
-			className = className.replace(/\-/g,''); // remove dashes
+			var className = node.nodeName.replace(/^[^:]+:/,'');
 			var e = null;
 			if (typeof(svg.Element[className]) != 'undefined') {
 				e = new svg.Element[className](node);
@@ -2231,10 +2044,6 @@ if(!Array.indexOf){
 		
 		// load from xml
 		svg.loadXml = function(ctx, xml) {
-			svg.loadXmlDoc(ctx, svg.parseXml(xml));
-		}
-		
-		svg.loadXmlDoc = function(ctx, dom) {
 			svg.init(ctx);
 			
 			var mapXY = function(p) {
@@ -2261,24 +2070,19 @@ if(!Array.indexOf){
 				};
 			}
 		
+			var dom = svg.parseXml(xml);
 			var e = svg.CreateElement(dom.documentElement);
-			e.root = true;
 					
 			// render loop
 			var isFirstRender = true;
 			var draw = function() {
-				svg.ViewPort.Clear();
-				if (ctx.canvas.parentNode) svg.ViewPort.SetCurrent(ctx.canvas.parentNode.clientWidth, ctx.canvas.parentNode.clientHeight);
-			
 				if (svg.opts == null || svg.opts['ignoreDimensions'] != true) {
 					// set canvas size
 					if (e.style('width').hasValue()) {
-						ctx.canvas.width = e.style('width').Length.toPixels('x');
-						ctx.canvas.style.width = ctx.canvas.width + 'px';
+						ctx.canvas.width = e.style('width').Length.toPixels(ctx.canvas.parentNode.clientWidth);
 					}
 					if (e.style('height').hasValue()) {
-						ctx.canvas.height = e.style('height').Length.toPixels('y');
-						ctx.canvas.style.height = ctx.canvas.height + 'px';
+						ctx.canvas.height = e.style('height').Length.toPixels(ctx.canvas.parentNode.clientHeight);
 					}
 				}
 				svg.ViewPort.SetCurrent(ctx.canvas.clientWidth, ctx.canvas.clientHeight);		
diff --git a/js/canvg/rgbcolor.js b/js/canvg/rgbcolor.js
new file mode 100644
index 0000000..0338a16
--- /dev/null
+++ b/js/canvg/rgbcolor.js
@@ -0,0 +1,288 @@
+/**
+ * A class to parse color values
+ * @author Stoyan Stefanov <sstoo at gmail.com>
+ * @link   http://www.phpied.com/rgb-color-parser-in-javascript/
+ * @license Use it if you like it
+ */
+function RGBColor(color_string)
+{
+    this.ok = false;
+
+    // strip any leading #
+    if (color_string.charAt(0) == '#') { // remove # if any
+        color_string = color_string.substr(1,6);
+    }
+
+    color_string = color_string.replace(/ /g,'');
+    color_string = color_string.toLowerCase();
+
+    // before getting into regexps, try simple matches
+    // and overwrite the input
+    var simple_colors = {
+        aliceblue: 'f0f8ff',
+        antiquewhite: 'faebd7',
+        aqua: '00ffff',
+        aquamarine: '7fffd4',
+        azure: 'f0ffff',
+        beige: 'f5f5dc',
+        bisque: 'ffe4c4',
+        black: '000000',
+        blanchedalmond: 'ffebcd',
+        blue: '0000ff',
+        blueviolet: '8a2be2',
+        brown: 'a52a2a',
+        burlywood: 'deb887',
+        cadetblue: '5f9ea0',
+        chartreuse: '7fff00',
+        chocolate: 'd2691e',
+        coral: 'ff7f50',
+        cornflowerblue: '6495ed',
+        cornsilk: 'fff8dc',
+        crimson: 'dc143c',
+        cyan: '00ffff',
+        darkblue: '00008b',
+        darkcyan: '008b8b',
+        darkgoldenrod: 'b8860b',
+        darkgray: 'a9a9a9',
+        darkgreen: '006400',
+        darkkhaki: 'bdb76b',
+        darkmagenta: '8b008b',
+        darkolivegreen: '556b2f',
+        darkorange: 'ff8c00',
+        darkorchid: '9932cc',
+        darkred: '8b0000',
+        darksalmon: 'e9967a',
+        darkseagreen: '8fbc8f',
+        darkslateblue: '483d8b',
+        darkslategray: '2f4f4f',
+        darkturquoise: '00ced1',
+        darkviolet: '9400d3',
+        deeppink: 'ff1493',
+        deepskyblue: '00bfff',
+        dimgray: '696969',
+        dodgerblue: '1e90ff',
+        feldspar: 'd19275',
+        firebrick: 'b22222',
+        floralwhite: 'fffaf0',
+        forestgreen: '228b22',
+        fuchsia: 'ff00ff',
+        gainsboro: 'dcdcdc',
+        ghostwhite: 'f8f8ff',
+        gold: 'ffd700',
+        goldenrod: 'daa520',
+        gray: '808080',
+        green: '008000',
+        greenyellow: 'adff2f',
+        honeydew: 'f0fff0',
+        hotpink: 'ff69b4',
+        indianred : 'cd5c5c',
+        indigo : '4b0082',
+        ivory: 'fffff0',
+        khaki: 'f0e68c',
+        lavender: 'e6e6fa',
+        lavenderblush: 'fff0f5',
+        lawngreen: '7cfc00',
+        lemonchiffon: 'fffacd',
+        lightblue: 'add8e6',
+        lightcoral: 'f08080',
+        lightcyan: 'e0ffff',
+        lightgoldenrodyellow: 'fafad2',
+        lightgrey: 'd3d3d3',
+        lightgreen: '90ee90',
+        lightpink: 'ffb6c1',
+        lightsalmon: 'ffa07a',
+        lightseagreen: '20b2aa',
+        lightskyblue: '87cefa',
+        lightslateblue: '8470ff',
+        lightslategray: '778899',
+        lightsteelblue: 'b0c4de',
+        lightyellow: 'ffffe0',
+        lime: '00ff00',
+        limegreen: '32cd32',
+        linen: 'faf0e6',
+        magenta: 'ff00ff',
+        maroon: '800000',
+        mediumaquamarine: '66cdaa',
+        mediumblue: '0000cd',
+        mediumorchid: 'ba55d3',
+        mediumpurple: '9370d8',
+        mediumseagreen: '3cb371',
+        mediumslateblue: '7b68ee',
+        mediumspringgreen: '00fa9a',
+        mediumturquoise: '48d1cc',
+        mediumvioletred: 'c71585',
+        midnightblue: '191970',
+        mintcream: 'f5fffa',
+        mistyrose: 'ffe4e1',
+        moccasin: 'ffe4b5',
+        navajowhite: 'ffdead',
+        navy: '000080',
+        oldlace: 'fdf5e6',
+        olive: '808000',
+        olivedrab: '6b8e23',
+        orange: 'ffa500',
+        orangered: 'ff4500',
+        orchid: 'da70d6',
+        palegoldenrod: 'eee8aa',
+        palegreen: '98fb98',
+        paleturquoise: 'afeeee',
+        palevioletred: 'd87093',
+        papayawhip: 'ffefd5',
+        peachpuff: 'ffdab9',
+        peru: 'cd853f',
+        pink: 'ffc0cb',
+        plum: 'dda0dd',
+        powderblue: 'b0e0e6',
+        purple: '800080',
+        red: 'ff0000',
+        rosybrown: 'bc8f8f',
+        royalblue: '4169e1',
+        saddlebrown: '8b4513',
+        salmon: 'fa8072',
+        sandybrown: 'f4a460',
+        seagreen: '2e8b57',
+        seashell: 'fff5ee',
+        sienna: 'a0522d',
+        silver: 'c0c0c0',
+        skyblue: '87ceeb',
+        slateblue: '6a5acd',
+        slategray: '708090',
+        snow: 'fffafa',
+        springgreen: '00ff7f',
+        steelblue: '4682b4',
+        tan: 'd2b48c',
+        teal: '008080',
+        thistle: 'd8bfd8',
+        tomato: 'ff6347',
+        turquoise: '40e0d0',
+        violet: 'ee82ee',
+        violetred: 'd02090',
+        wheat: 'f5deb3',
+        white: 'ffffff',
+        whitesmoke: 'f5f5f5',
+        yellow: 'ffff00',
+        yellowgreen: '9acd32'
+    };
+    for (var key in simple_colors) {
+        if (color_string == key) {
+            color_string = simple_colors[key];
+        }
+    }
+    // emd of simple type-in colors
+
+    // array of color definition objects
+    var color_defs = [
+        {
+            re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
+            example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],
+            process: function (bits){
+                return [
+                    parseInt(bits[1]),
+                    parseInt(bits[2]),
+                    parseInt(bits[3])
+                ];
+            }
+        },
+        {
+            re: /^(\w{2})(\w{2})(\w{2})$/,
+            example: ['#00ff00', '336699'],
+            process: function (bits){
+                return [
+                    parseInt(bits[1], 16),
+                    parseInt(bits[2], 16),
+                    parseInt(bits[3], 16)
+                ];
+            }
+        },
+        {
+            re: /^(\w{1})(\w{1})(\w{1})$/,
+            example: ['#fb0', 'f0f'],
+            process: function (bits){
+                return [
+                    parseInt(bits[1] + bits[1], 16),
+                    parseInt(bits[2] + bits[2], 16),
+                    parseInt(bits[3] + bits[3], 16)
+                ];
+            }
+        }
+    ];
+
+    // search through the definitions to find a match
+    for (var i = 0; i < color_defs.length; i++) {
+        var re = color_defs[i].re;
+        var processor = color_defs[i].process;
+        var bits = re.exec(color_string);
+        if (bits) {
+            channels = processor(bits);
+            this.r = channels[0];
+            this.g = channels[1];
+            this.b = channels[2];
+            this.ok = true;
+        }
+
+    }
+
+    // validate/cleanup values
+    this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);
+    this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);
+    this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);
+
+    // some getters
+    this.toRGB = function () {
+        return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')';
+    }
+    this.toHex = function () {
+        var r = this.r.toString(16);
+        var g = this.g.toString(16);
+        var b = this.b.toString(16);
+        if (r.length == 1) r = '0' + r;
+        if (g.length == 1) g = '0' + g;
+        if (b.length == 1) b = '0' + b;
+        return '#' + r + g + b;
+    }
+
+    // help
+    this.getHelpXML = function () {
+
+        var examples = new Array();
+        // add regexps
+        for (var i = 0; i < color_defs.length; i++) {
+            var example = color_defs[i].example;
+            for (var j = 0; j < example.length; j++) {
+                examples[examples.length] = example[j];
+            }
+        }
+        // add type-in colors
+        for (var sc in simple_colors) {
+            examples[examples.length] = sc;
+        }
+
+        var xml = document.createElement('ul');
+        xml.setAttribute('id', 'rgbcolor-examples');
+        for (var i = 0; i < examples.length; i++) {
+            try {
+                var list_item = document.createElement('li');
+                var list_color = new RGBColor(examples[i]);
+                var example_div = document.createElement('div');
+                example_div.style.cssText =
+                        'margin: 3px; '
+                        + 'border: 1px solid black; '
+                        + 'background:' + list_color.toHex() + '; '
+                        + 'color:' + list_color.toHex()
+                ;
+                example_div.appendChild(document.createTextNode('test'));
+                var list_item_value = document.createTextNode(
+                    ' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex()
+                );
+                list_item.appendChild(example_div);
+                list_item.appendChild(list_item_value);
+                xml.appendChild(list_item);
+
+            } catch(e){}
+        }
+        return xml;
+
+    }
+
+}
+
diff --git a/js/date.js b/js/date.js
new file mode 100644
index 0000000..9a92340
--- /dev/null
+++ b/js/date.js
@@ -0,0 +1,335 @@
+// ===================================================================
+// Author: Matt Kruse <matt at mattkruse.com>
+// WWW: http://www.mattkruse.com/
+//
+// NOTICE: You may use this code for any purpose, commercial or
+// private, without any further permission from the author. You may
+// remove this notice from your final code if you wish, however it is
+// appreciated by the author if at least my web site address is kept.
+//
+// You may *NOT* re-distribute this code in any way except through its
+// use. That means, you can include it in your product, or your web
+// site, or any other form where the code is actually being used. You
+// may not put the plain javascript up on your site for download or
+// include it in your javascript libraries for download. 
+// If you wish to share this code with others, please just point them
+// to the URL instead.
+// Please DO NOT link directly to my .js files from your site. Copy
+// the files to your server and use them there. Thank you.
+// ===================================================================
+
+// HISTORY
+// ------------------------------------------------------------------
+// May 17, 2003: Fixed bug in parseDate() for dates <1970
+// March 11, 2003: Added parseDate() function
+// March 11, 2003: Added "NNN" formatting option. Doesn't match up
+//                 perfectly with SimpleDateFormat formats, but 
+//                 backwards-compatability was required.
+
+// ------------------------------------------------------------------
+// These functions use the same 'format' strings as the 
+// java.text.SimpleDateFormat class, with minor exceptions.
+// The format string consists of the following abbreviations:
+// 
+// Field        | Full Form          | Short Form
+// -------------+--------------------+-----------------------
+// Year         | yyyy (4 digits)    | yy (2 digits), y (2 or 4 digits)
+// Month        | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
+//              | NNN (abbr.)        |
+// Day of Month | dd (2 digits)      | d (1 or 2 digits)
+// Day of Week  | EE (name)          | E (abbr)
+// Hour (1-12)  | hh (2 digits)      | h (1 or 2 digits)
+// Hour (0-23)  | HH (2 digits)      | H (1 or 2 digits)
+// Hour (0-11)  | KK (2 digits)      | K (1 or 2 digits)
+// Hour (1-24)  | kk (2 digits)      | k (1 or 2 digits)
+// Minute       | mm (2 digits)      | m (1 or 2 digits)
+// Second       | ss (2 digits)      | s (1 or 2 digits)
+// AM/PM        | a                  |
+//
+// NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
+// Examples:
+//  "MMM d, y" matches: January 01, 2000
+//                      Dec 1, 1900
+//                      Nov 20, 00
+//  "M/d/yy"   matches: 01/20/00
+//                      9/2/00
+//  "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
+// ------------------------------------------------------------------
+
+var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
+var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
+function LZ(x) {return(x<0||x>9?"":"0")+x}
+
+// ------------------------------------------------------------------
+// isDate ( date_string, format_string )
+// Returns true if date string matches format of format string and
+// is a valid date. Else returns false.
+// It is recommended that you trim whitespace around the value before
+// passing it to this function, as whitespace is NOT ignored!
+// ------------------------------------------------------------------
+function isDate(val,format) {
+	var date=getDateFromFormat(val,format);
+	if (date==0) { return false; }
+	return true;
+	}
+
+// -------------------------------------------------------------------
+// compareDates(date1,date1format,date2,date2format)
+//   Compare two date strings to see which is greater.
+//   Returns:
+//   1 if date1 is greater than date2
+//   0 if date2 is greater than date1 of if they are the same
+//  -1 if either of the dates is in an invalid format
+// -------------------------------------------------------------------
+function compareDates(date1,dateformat1,date2,dateformat2) {
+	var d1=getDateFromFormat(date1,dateformat1);
+	var d2=getDateFromFormat(date2,dateformat2);
+	if (d1==0 || d2==0) {
+		return -1;
+		}
+	else if (d1 > d2) {
+		return 1;
+		}
+	return 0;
+	}
+
+// ------------------------------------------------------------------
+// formatDate (date_object, format)
+// Returns a date in the output format specified.
+// The format string uses the same abbreviations as in getDateFromFormat()
+// ------------------------------------------------------------------
+function formatDate(date,format) {
+	format=format+"";
+	var result="";
+	var i_format=0;
+	var c="";
+	var token="";
+	var y=date.getYear()+"";
+	var M=date.getMonth()+1;
+	var d=date.getDate();
+	var E=date.getDay();
+	var H=date.getHours();
+	var m=date.getMinutes();
+	var s=date.getSeconds();
+	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
+	// Convert real date parts into formatted versions
+	var value=new Object();
+	if (y.length < 4) {y=""+(y-0+1900);}
+	value["y"]=""+y;
+	value["yyyy"]=y;
+	value["yy"]=y.substring(2,4);
+	value["M"]=M;
+	value["MM"]=LZ(M);
+	value["MMM"]=MONTH_NAMES[M-1];
+	value["NNN"]=MONTH_NAMES[M+11];
+	value["d"]=d;
+	value["dd"]=LZ(d);
+	value["E"]=DAY_NAMES[E+7];
+	value["EE"]=DAY_NAMES[E];
+	value["H"]=H;
+	value["HH"]=LZ(H);
+	if (H==0){value["h"]=12;}
+	else if (H>12){value["h"]=H-12;}
+	else {value["h"]=H;}
+	value["hh"]=LZ(value["h"]);
+	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
+	value["k"]=H+1;
+	value["KK"]=LZ(value["K"]);
+	value["kk"]=LZ(value["k"]);
+	if (H > 11) { value["a"]="PM"; }
+	else { value["a"]="AM"; }
+	value["m"]=m;
+	value["mm"]=LZ(m);
+	value["s"]=s;
+	value["ss"]=LZ(s);
+	while (i_format < format.length) {
+		c=format.charAt(i_format);
+		token="";
+		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
+			token += format.charAt(i_format++);
+			}
+		if (value[token] != null) { result=result + value[token]; }
+		else { result=result + token; }
+		}
+	return result;
+	}
+	
+// ------------------------------------------------------------------
+// Utility functions for parsing in getDateFromFormat()
+// ------------------------------------------------------------------
+function _isInteger(val) {
+	var digits="1234567890";
+	for (var i=0; i < val.length; i++) {
+		if (digits.indexOf(val.charAt(i))==-1) { return false; }
+		}
+	return true;
+	}
+function _getInt(str,i,minlength,maxlength) {
+	for (var x=maxlength; x>=minlength; x--) {
+		var token=str.substring(i,i+x);
+		if (token.length < minlength) { return null; }
+		if (_isInteger(token)) { return token; }
+		}
+	return null;
+	}
+	
+// ------------------------------------------------------------------
+// getDateFromFormat( date_string , format_string )
+//
+// This function takes a date string and a format string. It matches
+// If the date string matches the format string, it returns the 
+// getTime() of the date. If it does not match, it returns 0.
+// ------------------------------------------------------------------
+function getDateFromFormat(val,format) {
+	val=val+"";
+	format=format+"";
+	var i_val=0;
+	var i_format=0;
+	var c="";
+	var token="";
+	var token2="";
+	var x,y;
+	var now=new Date();
+	var year=now.getYear();
+	var month=now.getMonth()+1;
+	var date=1;
+	var hh=now.getHours();
+	var mm=now.getMinutes();
+	var ss=now.getSeconds();
+	var ampm="";
+	
+	while (i_format < format.length) {
+		// Get next token from format string
+		c=format.charAt(i_format);
+		token="";
+		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
+			token += format.charAt(i_format++);
+			}
+		// Extract contents of value based on format token
+		if (token=="yyyy" || token=="yy" || token=="y") {
+			if (token=="yyyy") { x=4;y=4; }
+			if (token=="yy")   { x=2;y=2; }
+			if (token=="y")    { x=2;y=4; }
+			year=_getInt(val,i_val,x,y);
+			if (year==null) { return 0; }
+			i_val += year.length;
+			if (year.length==2) {
+				if (year > 70) { year=1900+(year-0); }
+				else { year=2000+(year-0); }
+				}
+			}
+		else if (token=="MMM"||token=="NNN"){
+			month=0;
+			for (var i=0; i<MONTH_NAMES.length; i++) {
+				var month_name=MONTH_NAMES[i];
+				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
+					if (token=="MMM"||(token=="NNN"&&i>11)) {
+						month=i+1;
+						if (month>12) { month -= 12; }
+						i_val += month_name.length;
+						break;
+						}
+					}
+				}
+			if ((month < 1)||(month>12)){return 0;}
+			}
+		else if (token=="EE"||token=="E"){
+			for (var i=0; i<DAY_NAMES.length; i++) {
+				var day_name=DAY_NAMES[i];
+				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
+					i_val += day_name.length;
+					break;
+					}
+				}
+			}
+		else if (token=="MM"||token=="M") {
+			month=_getInt(val,i_val,token.length,2);
+			if(month==null||(month<1)||(month>12)){return 0;}
+			i_val+=month.length;}
+		else if (token=="dd"||token=="d") {
+			date=_getInt(val,i_val,token.length,2);
+			if(date==null||(date<1)||(date>31)){return 0;}
+			i_val+=date.length;}
+		else if (token=="hh"||token=="h") {
+			hh=_getInt(val,i_val,token.length,2);
+			if(hh==null||(hh<1)||(hh>12)){return 0;}
+			i_val+=hh.length;}
+		else if (token=="HH"||token=="H") {
+			hh=_getInt(val,i_val,token.length,2);
+			if(hh==null||(hh<0)||(hh>23)){return 0;}
+			i_val+=hh.length;}
+		else if (token=="KK"||token=="K") {
+			hh=_getInt(val,i_val,token.length,2);
+			if(hh==null||(hh<0)||(hh>11)){return 0;}
+			i_val+=hh.length;}
+		else if (token=="kk"||token=="k") {
+			hh=_getInt(val,i_val,token.length,2);
+			if(hh==null||(hh<1)||(hh>24)){return 0;}
+			i_val+=hh.length;hh--;}
+		else if (token=="mm"||token=="m") {
+			mm=_getInt(val,i_val,token.length,2);
+			if(mm==null||(mm<0)||(mm>59)){return 0;}
+			i_val+=mm.length;}
+		else if (token=="ss"||token=="s") {
+			ss=_getInt(val,i_val,token.length,2);
+			if(ss==null||(ss<0)||(ss>59)){return 0;}
+			i_val+=ss.length;}
+		else if (token=="a") {
+			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
+			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
+			else {return 0;}
+			i_val+=2;}
+		else {
+			if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
+			else {i_val+=token.length;}
+			}
+		}
+	// If there are any trailing characters left in the value, it doesn't match
+	if (i_val != val.length) { return 0; }
+	// Is date valid for month?
+	if (month==2) {
+		// Check for leap year
+		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
+			if (date > 29){ return 0; }
+			}
+		else { if (date > 28) { return 0; } }
+		}
+	if ((month==4)||(month==6)||(month==9)||(month==11)) {
+		if (date > 30) { return 0; }
+		}
+	// Correct hours value
+	if (hh<12 && ampm=="PM") { hh=hh-0+12; }
+	else if (hh>11 && ampm=="AM") { hh-=12; }
+	var newdate=new Date(year,month-1,date,hh,mm,ss);
+	return newdate.getTime();
+	}
+
+// ------------------------------------------------------------------
+// parseDate( date_string [, prefer_euro_format] )
+//
+// This function takes a date string and tries to match it to a
+// number of possible date formats to get the value. It will try to
+// match against the following international formats, in this order:
+// y-M-d   MMM d, y   MMM d,y   y-MMM-d   d-MMM-y  MMM d
+// M/d/y   M-d-y      M.d.y     MMM-d     M/d      M-d
+// d/M/y   d-M-y      d.M.y     d-MMM     d/M      d-M
+// A second argument may be passed to instruct the method to search
+// for formats like d/M/y (european format) before M/d/y (American).
+// Returns a Date object or null if no patterns match.
+// ------------------------------------------------------------------
+function parseDate(val) {
+	var preferEuro=(arguments.length==2)?arguments[1]:false;
+	generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');
+	monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');
+	dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');
+	var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');
+	var d=null;
+	for (var i=0; i<checkList.length; i++) {
+		var l=window[checkList[i]];
+		for (var j=0; j<l.length; j++) {
+			d=getDateFromFormat(val,l[j]);
+			if (d!=0) { return new Date(d); }
+			}
+		}
+	return null;
+	}
diff --git a/js/messages.php b/js/messages.php
index 63fb182..b942a18 100644
--- a/js/messages.php
+++ b/js/messages.php
@@ -258,6 +258,12 @@ $js_messages['strSave'] = __('Save');
 $js_messages['strHideSearchCriteria'] = __('Hide search criteria');
 $js_messages['strShowSearchCriteria'] = __('Show search criteria');
 
+/* For tbl_zoom_plot.js */
+$js_messages['strZoomSearch'] = __('Zoom Search');
+$js_messages['strDisplayHelp'] =  __('* Each point represents a data row.<br>* Hovering over a point will show its label.<br>* Drag and select an area in the plot to zoom into it.<br>* Click reset zoom link to come back to original state.<br>*  Click a data point to view and possibly edit the data row.<br>* The plot can be resized by dragging it along the bottom right corner.<br>* Strings are converted into integer for plotting');
+$js_messages['strInputNull'] = __('<b>Select two columns</b>');
+$js_messages['strSameInputs'] = __('<b>Select two different columns</b>');
+
 /* For tbl_change.js */
 $js_messages['strIgnore'] = __('Ignore');
 
diff --git a/js/tbl_select.js b/js/tbl_select.js
index 3bc1137..af2242a 100644
--- a/js/tbl_select.js
+++ b/js/tbl_select.js
@@ -66,7 +66,7 @@ $(document).ready(function() {
             if (typeof response == 'string') {
                 // found results
                 $("#sqlqueryresults").html(response);
-                $("#sqlqueryresults").trigger('makegrid');
+                $("#sqlqueryresults").trigger('appendAnchor');
                 $('#tbl_search_form')
                 // work around for bug #3168569 - Issue on toggling the "Hide search criteria" in chrome.
                  .slideToggle()    
diff --git a/js/tbl_zoom_plot.js b/js/tbl_zoom_plot.js
new file mode 100644
index 0000000..b9c0d75
--- /dev/null
+++ b/js/tbl_zoom_plot.js
@@ -0,0 +1,605 @@
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ ** @fileoverview JavaScript functions used on tbl_select.php
+ **
+ ** @requires    jQuery
+ ** @requires    js/functions.js
+ **/
+
+
+/**
+ **  Display Help/Info
+ **/
+function displayHelp() {
+    var msgbox = PMA_ajaxShowMessage(PMA_messages['strDisplayHelp'],10000);
+    msgbox.click(function() {
+        PMA_ajaxRemoveMessage(msgbox);
+    });
+}
+
+/**
+ ** Extend the array object for max function
+ ** @param array
+ **/
+Array.max = function (array) {
+    return Math.max.apply( Math, array );
+}
+
+/**
+ ** Extend the array object for min function
+ ** @param array
+ **/
+Array.min = function (array) {
+    return Math.min.apply( Math, array );
+}
+
+/**
+ ** Checks if a string contains only numeric value
+ ** @param n: String (to be checked) 
+ **/
+function isNumeric(n) {
+    return !isNaN(parseFloat(n)) && isFinite(n);
+}
+
+/**
+ ** Checks if an object is empty
+ ** @param n: Object (to be checked) 
+ **/
+function isEmpty(obj) {
+    var name;
+    for (name in obj) {
+        return false;
+    }
+    return true;
+}
+
+/**
+ ** Converts a timestamp into the format of its field type
+ ** @param val  Integer Timestamp
+ ** @param type String  Field type(datetime/timestamp/time/date)
+ **/
+function getDate(val,type) {
+    if(type.toString().search(/datetime/i) != -1 || type.toString().search(/timestamp/i) != -1) {
+	return Highcharts.dateFormat('%Y-%m-%e %H:%M:%S', val)
+    }	
+    else if(type.toString().search(/time/i) != -1) {
+        return Highcharts.dateFormat('%H:%M:%S', val + 19800000)
+    }	
+    else if (type.toString().search(/date/i) != -1) {
+        return Highcharts.dateFormat('%Y-%m-%e', val)
+    }	
+}
+
+/**
+ ** Converts a date/time into timestamp
+ ** @param val  String Date
+ ** @param type Sring  Field type(datetime/timestamp/time/date)
+ **/
+function getTimeStamp(val,type) {
+    if(type.toString().search(/datetime/i) != -1 || type.toString().search(/timestamp/i) != -1) {
+	return getDateFromFormat(val,'yyyy-MM-dd HH:mm:ss', val)
+    }	
+    else if(type.toString().search(/time/i) != -1) {
+	return getDateFromFormat('1970-01-01 ' + val,'yyyy-MM-dd HH:mm:ss')
+    }	
+    else if (type.toString().search(/date/i) != -1) {
+	return getDateFromFormat(val,'yyyy-MM-dd')
+    }	
+}
+
+/**
+ ** Classifies the field type into numeric,timeseries or text
+ ** @param field: field type (as in database structure)
+ **/ 
+function getType(field) {
+	if(field.toString().search(/int/i) != -1 || field.toString().search(/decimal/i) != -1 || field.toString().search(/year/i) != -1)
+	    return 'numeric';
+	else if(field.toString().search(/time/i) != -1 || field.toString().search(/date/i) != -1)
+	    return 'time';
+	else
+	    return 'text';
+}
+/** 
+ ** Converts a categorical array into numeric array
+ ** @param array categorical values array
+ **/
+function getCord(arr) {
+    var newCord = new Array();
+    var original = $.extend(true,[],arr);
+    var arr = jQuery.unique(arr).sort();
+    $.each(original, function(index,value) {
+        newCord.push(jQuery.inArray(value,arr));
+    });
+    return [newCord,arr,original];
+}
+
+/**
+ ** Scrolls the view to the display section
+ **/
+function scrollToChart() {
+   var x = $('#dataDisplay').offset().top - 100; // 100 provides buffer in viewport
+   $('html,body').animate({scrollTop: x}, 500);
+}
+
+$(document).ready(function() {
+
+   /**
+    ** Set a parameter for all Ajax queries made on this page.  Don't let the
+    ** web server serve cached pages
+    **/
+    $.ajaxSetup({
+        cache: 'false'
+    });
+
+    var cursorMode = ($("input[name='mode']:checked").val() == 'edit') ? 'crosshair' : 'pointer'; 
+    var currentChart = null;
+    var currentData = null;
+    var xLabel = $('#tableid_0').val();
+    var yLabel = $('#tableid_1').val();
+    var xType = $('#types_0').val();
+    var yType = $('#types_1').val();
+    var dataLabel = $('#dataLabel').val();
+
+    // Get query result 
+    var data = jQuery.parseJSON($('#querydata').html());
+
+    /**
+     ** Input form submit on field change
+     **/
+    $('#tableid_0').change(function() {
+          $('#zoom_search_form').submit();
+    })
+
+    $('#tableid_1').change(function() {
+          $('#zoom_search_form').submit();
+    })
+
+    $('#tableid_2').change(function() {
+          $('#zoom_search_form').submit();
+    })
+
+    $('#tableid_3').change(function() {
+          $('#zoom_search_form').submit();
+    })
+
+    /**
+     * Input form validation
+     **/ 
+    $('#inputFormSubmitId').click(function() {
+        if ($('#tableid_0').get(0).selectedIndex == 0 || $('#tableid_1').get(0).selectedIndex == 0)         
+	    PMA_ajaxShowMessage(PMA_messages['strInputNull']);
+	else if (xLabel == yLabel) 
+            PMA_ajaxShowMessage(PMA_messages['strSameInputs']);
+    });
+
+    /**
+      ** Prepare a div containing a link, otherwise it's incorrectly displayed 
+      ** after a couple of clicks
+      **/
+    $('<div id="togglesearchformdiv"><a id="togglesearchformlink"></a></div>')
+    .insertAfter('#zoom_search_form')
+    // don't show it until we have results on-screen
+    .hide();
+
+    $('#togglesearchformlink')
+        .html(PMA_messages['strShowSearchCriteria'])
+        .bind('click', function() {
+            var $link = $(this);
+            $('#zoom_search_form').slideToggle();
+            if ($link.text() == PMA_messages['strHideSearchCriteria']) {
+                $link.text(PMA_messages['strShowSearchCriteria']);
+            } else {
+                $link.text(PMA_messages['strHideSearchCriteria']);
+            }
+	     // avoid default click action
+	    return false;
+	 });
+    
+    /** 
+     ** Set dialog properties for the data display form
+     **/
+    $("#dataDisplay").dialog({
+        autoOpen: false,
+	title: 'Data point content',
+        modal: false, //false otherwise other dialogues like timepicker may not function properly
+        height: $('#dataDisplay').height() + 80,
+        width: $('#dataDisplay').width() + 80
+    });
+
+    /*
+     * Handle submit of zoom_display_form 
+     */
+     
+    $("#submitForm").click(function(event) {
+	
+        //Prevent default submission of form
+        event.preventDefault();
+	
+	//Find changed values by comparing form values with selectedRow Object
+	var newValues = new Array();//Stores the values changed from original
+        var it = 4;
+        var xChange = false;
+        var yChange = false;
+	for (key in selectedRow) {
+	    if (key != 'where_clause'){
+		var oldVal = selectedRow[key];
+		var newVal = ($('#fields_null_id_' + it).attr('checked')) ? null : $('#fieldID_' + it).val();
+		if (oldVal != newVal){
+		    selectedRow[key] = newVal;
+		    newValues[key] = newVal;
+		    if(key == xLabel) {
+			xChange = true;
+		   	data[currentData][xLabel] = newVal;
+		    }
+		    else if(key == yLabel) {
+			yChange = true;
+		   	data[currentData][yLabel] = newVal;
+		    }
+		}
+	    }
+	    it++    
+	}//End data update
+        
+	//Update the chart series and replot
+        if (xChange || yChange) {
+	    var newSeries = new Array();
+	    newSeries[0] = new Object();
+            newSeries[0].marker = {
+                symbol: 'circle'
+            };
+	    //Logic similar to plot generation, replot only if xAxis changes or yAxis changes. Code includes a lot of checks so as to replot only when necessary
+            if(xChange) {
+  	        xCord[currentData] = selectedRow[xLabel];
+		if(xType == 'numeric') {
+		    currentChart.series[0].data[currentData].update({ x : selectedRow[xLabel] });
+		    currentChart.xAxis[0].setExtremes(Array.min(xCord) - 6,Array.max(xCord) + 6);
+                }
+		else if(xType == 'time') {
+		    currentChart.series[0].data[currentData].update({ x : getTimeStamp(selectedRow[xLabel],$('#types_0').val())});
+		}
+		else {
+		    var tempX = getCord(xCord);
+		    var tempY = getCord(yCord);
+		    var i = 0;
+	    	    newSeries[0].data = new Array();
+		    xCord = tempX[2];
+		    yCord = tempY[2];
+
+	    	    $.each(data,function(key,value) {
+                        if(yType != 'text')
+ 			    newSeries[0].data.push({ name: value[dataLabel], x: tempX[0][i], y: value[yLabel], marker: {fillColor: colorCodes[i % 8]} , id: i } );
+			else
+                            newSeries[0].data.push({ name: value[dataLabel], x: tempX[0][i], y: tempY[0][i], marker: {fillColor: colorCodes[i % 8]} , id: i } );
+	                i++;   
+                    });
+		    currentSettings.xAxis.labels = { formatter : function() {
+		        if(tempX[1][this.value] && tempX[1][this.value].length > 10)
+		            return tempX[1][this.value].substring(0,10)
+		        else 
+		            return tempX[1][this.value];    
+                        }
+                    }
+ 		    currentSettings.series = newSeries;
+                    currentChart = PMA_createChart(currentSettings);
+		}
+
+	    }
+            if(yChange) {
+
+  	        yCord[currentData] = selectedRow[yLabel];
+		if(yType == 'numeric') {
+		    currentChart.series[0].data[currentData].update({ y : selectedRow[yLabel] });
+		    currentChart.yAxis[0].setExtremes(Array.min(yCord) - 6,Array.max(yCord) + 6);
+                }
+		else if(yType =='time') {
+		    currentChart.series[0].data[currentData].update({ y : getTimeStamp(selectedRow[yLabel],$('#types_1').val())});
+		}
+		else {
+		    var tempX = getCord(xCord);
+		    var tempY = getCord(yCord);
+		    var i = 0;
+	    	    newSeries[0].data = new Array();
+		    xCord = tempX[2];
+		    yCord = tempY[2];
+
+	    	    $.each(data,function(key,value) {
+			if(xType != 'text' )
+                            newSeries[0].data.push({ name: value[dataLabel], x: value[xLabel], y: tempY[0][i], marker: {fillColor: colorCodes[i % 8]} , id: i } );
+			else
+                            newSeries[0].data.push({ name: value[dataLabel], x: tempX[0][i], y: tempY[0][i], marker: {fillColor: colorCodes[i % 8]} , id: i } );
+	                i++;   
+                    });
+		    currentSettings.yAxis.labels = { formatter : function() {
+		        if(tempY[1][this.value] && tempY[1][this.value].length > 10)
+		            return tempY[1][this.value].substring(0,10)
+		        else 
+		            return tempY[1][this.value];    
+                        }
+                    }
+ 		    currentSettings.series = newSeries;
+                    currentChart = PMA_createChart(currentSettings); 
+		}
+	    }
+	    currentChart.series[0].data[currentData].select();
+        }
+	//End plot update	
+
+	//Generate SQL query for update
+	if (!isEmpty(newValues)) {
+            var sql_query = 'UPDATE `' + window.parent.table + '` SET ';
+	    for (key in newValues) {
+	        if(key != 'where_clause') {
+	            sql_query += '`' + key + '`=' ;
+		    var value = newValues[key];
+		    if(!isNumeric(value) && value != null) 
+		        sql_query += '\'' + value + '\' ,';
+		    else
+		        sql_query += value + ' ,';
+	        }
+	    }
+	    sql_query = sql_query.substring(0, sql_query.length - 1);
+	    sql_query += ' WHERE ' + PMA_urldecode(data[currentData]['where_clause']);
+	    
+	    //Post SQL query to sql.php	
+	    $.post('sql.php', {
+                'token' : window.parent.token,
+                'db' : window.parent.db,
+                'ajax_request' : true,
+                'sql_query' : sql_query,
+	        'inline_edit' : false
+	        }, function(data) {
+	            if(data.success == true) {
+	                $('#sqlqueryresults').html(data.sql_query);
+		        $("#sqlqueryresults").trigger('appendAnchor');
+	            }
+	            else 
+	                PMA_ajaxShowMessage(data.error);
+	    })//End $.post
+	}//End database update
+        $("#dataDisplay").dialog("close");	
+    });//End submit handler 
+
+    /*
+     * Generate plot using Highcharts
+     */ 
+
+    if (data != null) {
+        $('#zoom_search_form')
+         .slideToggle()
+         .hide();
+        $('#togglesearchformlink')
+         .text(PMA_messages['strShowSearchCriteria'])
+	$('#togglesearchformdiv').show();
+        var selectedRow;
+    	var columnNames = new Array();
+    	var colorCodes = ['#FF0000','#00FFFF','#0000FF','#0000A0','#FF0080','#800080','#FFFF00','#00FF00','#FF00FF'];
+    	var series = new Array();
+    	var xCord = new Array();
+    	var yCord = new Array();
+    	var xCat = new Array();
+    	var yCat = new Array();
+	var tempX, tempY;
+    	var it = 0;
+
+        // Set the basic plot settings
+        var currentSettings = {
+            chart: {
+            	renderTo: 'querychart',
+            	type: 'scatter',
+	    	zoomType: 'xy',
+	    	width:$('#resizer').width() -3,
+            	height:$('#resizer').height()-20 
+	    },
+	    credits: {
+                enabled: false 
+            },
+	    exporting: { enabled: false },
+            label: { text: $('#dataLabel').val() },
+	    plotOptions: {
+	        series: {
+	            allowPointSelect: true,
+                    cursor: 'pointer',
+		    showInLegend: false,
+                    dataLabels: {
+                        enabled: false,
+                    },
+	            point: {
+                        events: {
+                            click: function() {
+			        var id = this.id;
+				var fid = 4;
+				currentData = id;
+				// Make AJAX request to tbl_zoom_select.php for getting the complete row info
+				var post_params = {
+                                    'ajax_request' : true,
+                                    'get_data_row' : true,
+                                    'db' : window.parent.db,
+                                    'table' : window.parent.table,
+                                    'where_clause' : data[id]['where_clause'],
+                                    'token' : window.parent.token,
+                                }
+                                $.post('tbl_zoom_select.php', post_params, function(data) {
+				    // Row is contained in data.row_info, now fill the displayResultForm with row values
+				    for ( key in data.row_info) { 
+					if (data.row_info[key] == null)
+					    $('#fields_null_id_' + fid).attr('checked', true);
+					else
+					    $('#fieldID_' + fid).val(data.row_info[key]);
+					fid++;
+				     }
+				     selectedRow = new Object();
+				     selectedRow = data.row_info;
+                                });
+
+			        $("#dataDisplay").dialog("open");	
+                            },
+                        }
+	            }
+	        }
+	    },
+	    tooltip: {
+	        formatter: function() {
+	            return this.point.name;
+	        }
+	    },
+            title: { text: 'Query Results' },
+	    xAxis: {
+	        title: { text: $('#tableid_0').val() },
+            },
+            yAxis: {
+		min: null,
+	        title: { text: $('#tableid_1').val() },
+	    },
+        }
+
+        $('#resizer').resizable({
+            resize: function() {
+                currentChart.setSize(
+                    this.offsetWidth -3,
+                    this.offsetHeight -20,
+                    false
+                );
+            }
+        });
+        
+	// Classify types as either numeric,time,text
+	xType = getType(xType);
+	yType = getType(yType);
+
+	//Set the axis type based on the field
+	currentSettings.xAxis.type = (xType == 'time') ? 'datetime' : 'linear';
+	currentSettings.yAxis.type = (yType == 'time') ? 'datetime' : 'linear';
+
+        // Formulate series data for plot
+        series[0] = new Object();
+        series[0].data = new Array();
+	series[0].marker = {
+            symbol: 'circle'
+        };
+	if (xType != 'text' && yType != 'text') {
+	    $.each(data,function(key,value) {
+		var xVal = (xType == 'numeric') ? value[xLabel] : getTimeStamp(value[xLabel],$('#types_0').val());
+		var yVal = (yType == 'numeric') ? value[yLabel] : getTimeStamp(value[yLabel],$('#types_1').val());
+                series[0].data.push({ name: value[dataLabel], x: xVal, y: yVal, marker: {fillColor: colorCodes[it % 8]} , id: it } );
+		xCord.push(value[xLabel]);
+		yCord.push(value[yLabel]);
+	        it++;   
+            });
+	    if(xType == 'numeric') {
+	        currentSettings.xAxis.max = Array.max(xCord) + 6
+	        currentSettings.xAxis.min = Array.min(xCord) - 6
+	    }
+	    else {
+	        currentSettings.xAxis.labels = { formatter : function() {
+		    return getDate(this.value, $('#types_0').val());
+		}}
+            }
+	    if(yType == 'numeric') {
+	        currentSettings.yAxis.max = Array.max(yCord) + 6
+	        currentSettings.yAxis.min = Array.min(yCord) - 6
+	    }
+	    else {
+	        currentSettings.yAxis.labels = { formatter : function() {
+		    return getDate(this.value, $('#types_1').val());
+		}}
+            }
+
+        }
+	
+	else if (xType =='text' && yType !='text') {
+	    $.each(data,function(key,value) {
+		xCord.push(value[xLabel]);
+		yCord.push(value[yLabel]);
+	    });
+	    
+	    tempX = getCord(xCord);	
+	    $.each(data,function(key,value) {
+		var yVal = (yType == 'numeric') ? value[yLabel] : getTimeStamp(value[yLabel],$('#types_1').val());
+                series[0].data.push({ name: value[dataLabel], x: tempX[0][it], y: yVal, marker: {fillColor: colorCodes[it % 8]} , id: it } );
+	        it++;   
+            });
+	    
+	    currentSettings.xAxis.labels = { formatter : function() {
+		    if(tempX[1][this.value] && tempX[1][this.value].length > 10)
+		        return tempX[1][this.value].substring(0,10)
+		    else 
+			return tempX[1][this.value];
+                } 
+            }
+	    if(yType == 'numeric') {
+	        currentSettings.yAxis.max = Array.max(yCord) + 6
+	        currentSettings.yAxis.min = Array.min(yCord) - 6
+	    }
+	    else {
+	        currentSettings.yAxis.labels = { formatter : function() {
+		    return getDate(this.value, $('#types_1').val());
+		}}
+            }
+	    xCord = tempX[2];
+	}
+	 
+	else if (xType !='text' && yType =='text') {
+	    $.each(data,function(key,value) {
+		xCord.push(value[xLabel]);
+		yCord.push(value[yLabel]);
+	    });
+	    tempY = getCord(yCord);	
+	    $.each(data,function(key,value) {
+		var xVal = (xType == 'numeric') ? value[xLabel] : getTimeStamp(value[xLabel],$('#types_0').val());
+                series[0].data.push({ name: value[dataLabel], y: tempY[0][it], x: xVal, marker: {fillColor: colorCodes[it % 8]} , id: it } );
+	        it++;   
+            });
+	    if(xType == 'numeric') {
+	        currentSettings.xAxis.max = Array.max(xCord) + 6
+	        currentSettings.xAxis.min = Array.min(xCord) - 6
+	    }
+	    else {
+	        currentSettings.xAxis.labels = { formatter : function() {
+		    return getDate(this.value, $('#types_0').val());
+		}}
+            }
+	    currentSettings.yAxis.labels = { formatter : function() {
+		    if(tempY[1][this.value] && tempY[1][this.value].length > 10)
+		        return tempY[1][this.value].substring(0,10)
+		    else 
+	                return tempY[1][this.value];
+	        }
+            }
+	    yCord = tempY[2];
+	}
+	
+	else if (xType =='text' && yType =='text') {
+	    $.each(data,function(key,value) {
+		xCord.push(value[xLabel]);
+		yCord.push(value[yLabel]);
+	    });
+	    tempX = getCord(xCord);	
+	    tempY = getCord(yCord);	
+	    $.each(data,function(key,value) {
+                series[0].data.push({ name: value[dataLabel], x: tempX[0][it], y: tempY[0][it], marker: {fillColor: colorCodes[it % 8]} , id: it } );
+	        it++;   
+            });
+	    currentSettings.xAxis.labels = { formatter : function() {
+		    if(tempX[1][this.value] && tempX[1][this.value].length > 10)
+		        return tempX[1][this.value].substring(0,10)
+		    else 
+	                return tempX[1][this.value];
+	        }
+            }
+	    currentSettings.yAxis.labels = { formatter : function() {
+		    if(tempY[1][this.value] && tempY[1][this.value].length > 10)
+		        return tempY[1][this.value].substring(0,10)
+		    else 
+	                return tempY[1][this.value];
+	        }
+	    }
+	    xCord = tempX[2];
+	    yCord = tempY[2];
+
+	}
+
+	currentSettings.series = series;
+        currentChart = PMA_createChart(currentSettings);
+	scrollToChart();
+    }
+});
diff --git a/libraries/common.inc.php b/libraries/common.inc.php
index c806923..d40cd7b 100644
--- a/libraries/common.inc.php
+++ b/libraries/common.inc.php
@@ -413,6 +413,7 @@ $goto_whitelist = array(
     'tbl_replace.php',
     'tbl_row_action.php',
     'tbl_select.php',
+    'tbl_zoom_select.php',
     //'themes.php',
     'transformation_overview.php',
     'transformation_wrapper.php',
diff --git a/libraries/config.default.php b/libraries/config.default.php
index efb0cbb..d8367e5 100644
--- a/libraries/config.default.php
+++ b/libraries/config.default.php
@@ -1137,7 +1137,6 @@ $cfg['DefaultTabDatabase'] = 'db_structure.php';
  */
 $cfg['DefaultTabTable'] = 'sql.php';
 
-
 /*******************************************************************************
  * Export defaults
  */
@@ -1845,7 +1844,6 @@ $cfg['Export']['xml_export_contents'] = true;
  */
 $cfg['Export']['yaml_structure_or_data'] = 'data';
 
-
 /*******************************************************************************
  * Import defaults
  */
@@ -2443,7 +2441,6 @@ $cfg['UserprefsDisallow'] = array();
  */
 $cfg['UserprefsDeveloperTab'] = false;
 
-
 /*******************************************************************************
  * Window title settings
  */
@@ -2554,9 +2551,7 @@ $cfg['DefaultQueryDatabase'] = '';
 /*******************************************************************************
  * SQL Query box settings
  * These are the links display in all of the SQL Query boxes
- */
-
-/**
+ *
  * @global array $cfg['SQLQuery']
  */
 $cfg['SQLQuery'] = array();
@@ -2628,7 +2623,7 @@ $cfg['SaveDir'] = '';
 $cfg['TempDir'] = '';
 
 
-/*******************************************************************************
+/**
  * Misc. settings
  */
 
@@ -2673,12 +2668,7 @@ $cfg['LinkLengthLimit'] = 1000;
  */
 $cfg['DisableMultiTableMaintenance'] = false;
 
-
 /*******************************************************************************
- * SQL Parser
- */
-
-/**
  * SQL Parser Settings
  *
  * @global array $cfg['SQP']
@@ -2708,10 +2698,6 @@ $cfg['SQP']['fmtIndUnit'] = 'em';
 
 
 /*******************************************************************************
- * SQL Validator
- */
-
-/**
  * If you wish to use the SQL Validator service, you should be aware of the
  * following:
  * All SQL statements are stored anonymously for statistical purposes.
@@ -2746,10 +2732,6 @@ $cfg['SQLValidator']['password'] = '';
 
 /*******************************************************************************
  * Developers ONLY!
- */
-
-/**
- * Debugging settings
  *
  * @global array $cfg['DBG']
  */
@@ -2768,50 +2750,328 @@ $cfg['DBG']['sql'] = false;
  */
 
 /**
- * Column types
- *
- * Fill in this array to overwrite data from data_*.inc.php files
+ * Column types;
+ * VARCHAR, TINYINT, TEXT and DATE are listed first, based on estimated popularity
  *
  * @global array $cfg['ColumnTypes']
  */
-$cfg['ColumnTypes'] = array();
+$cfg['ColumnTypes'] = array(
+    // most used
+    'INT',
+    'VARCHAR',
+    'TEXT',
+    'DATE',
+
+    // numeric
+    'NUMERIC' => array(
+        'TINYINT',
+        'SMALLINT',
+        'MEDIUMINT',
+        'INT',
+        'BIGINT',
+        '-',
+        'DECIMAL',
+        'FLOAT',
+        'DOUBLE',
+        'REAL',
+        '-',
+        'BIT',
+        'BOOLEAN',
+        'SERIAL',
+    ),
+
+
+    // Date/Time
+    'DATE and TIME' => array(
+        'DATE',
+        'DATETIME',
+        'TIMESTAMP',
+        'TIME',
+        'YEAR',
+    ),
+
+    // Text
+    'STRING' => array(
+        'CHAR',
+        'VARCHAR',
+        '-',
+        'TINYTEXT',
+        'TEXT',
+        'MEDIUMTEXT',
+        'LONGTEXT',
+        '-',
+        'BINARY',
+        'VARBINARY',
+        '-',
+        'TINYBLOB',
+        'MEDIUMBLOB',
+        'BLOB',
+        'LONGBLOB',
+        '-',
+        'ENUM',
+        'SET',
+    ),
+
+    'SPATIAL' => array(
+        'GEOMETRY',
+        'POINT',
+        'LINESTRING',
+        'POLYGON',
+        'MULTIPOINT',
+        'MULTILINESTRING',
+        'MULTIPOLYGON',
+        'GEOMETRYCOLLECTION',
+    ),
+);
 
 /**
  * Attributes
  *
- * Fill in this array to overwrite data from data_*.inc.php files
- *
  * @global array $cfg['AttributeTypes']
  */
-$cfg['AttributeTypes'] = array();
+$cfg['AttributeTypes'] = array(
+   '',
+   'BINARY',
+   'UNSIGNED',
+   'UNSIGNED ZEROFILL',
+   'on update CURRENT_TIMESTAMP',
+);
+
 
 if ($cfg['ShowFunctionFields']) {
     /**
      * Available functions
      *
-     * Fill in this array to overwrite data from data_*.inc.php files
-     *
      * @global array $cfg['Functions']
      */
-    $cfg['Functions'] = array();
+    $cfg['Functions'] = array(
+        'ABS',
+        'ACOS',
+        'ASCII',
+        'ASIN',
+        'ATAN',
+        'BIN',
+        'BIT_COUNT',
+        'BIT_LENGTH',
+        'CEILING',
+        'CHAR',
+        'CHAR_LENGTH',
+        'COMPRESS',
+        'COS',
+        'COT',
+        'CRC32',
+        'CURDATE',
+        'CURRENT_USER',
+        'CURTIME',
+        'DATE',
+        'DAYNAME',
+        'DEGREES',
+        'DES_DECRYPT',
+        'DES_ENCRYPT',
+        'ENCRYPT',
+        'EXP',
+        'FLOOR',
+        'FROM_DAYS',
+        'FROM_UNIXTIME',
+        'HEX',
+        'INET_ATON',
+        'INET_NTOA',
+        'LENGTH',
+        'LN',
+        'LOG',
+        'LOG10',
+        'LOG2',
+        'LOWER',
+        'MD5',
+        'NOW',
+        'OCT',
+        'OLD_PASSWORD',
+        'ORD',
+        'PASSWORD',
+        'RADIANS',
+        'RAND',
+        'REVERSE',
+        'ROUND',
+        'SEC_TO_TIME',
+        'SHA1',
+        'SOUNDEX',
+        'SPACE',
+        'SQRT',
+        'STDDEV_POP',
+        'STDDEV_SAMP',
+        'TAN',
+        'TIMESTAMP',
+        'TIME_TO_SEC',
+        'UNCOMPRESS',
+        'UNHEX',
+        'UNIX_TIMESTAMP',
+        'UPPER',
+        'USER',
+        'UTC_DATE',
+        'UTC_TIME',
+        'UTC_TIMESTAMP',
+        'UUID',
+        'VAR_POP',
+        'VAR_SAMP',
+        'YEAR',
+    );
 
     /**
      * Which column types will be mapped to which Group?
      *
-     * Fill in this array to overwrite data from data_*.inc.php files
-     *
      * @global array $cfg['RestrictColumnTypes']
      */
-    $cfg['RestrictColumnTypes'] = array();
+    $cfg['RestrictColumnTypes'] = array(
+        'TINYINT'   => 'FUNC_NUMBER',
+        'SMALLINT'  => 'FUNC_NUMBER',
+        'MEDIUMINT' => 'FUNC_NUMBER',
+        'INT'       => 'FUNC_NUMBER',
+        'BIGINT'    => 'FUNC_NUMBER',
+        'DECIMAL'   => 'FUNC_NUMBER',
+        'FLOAT'     => 'FUNC_NUMBER',
+        'DOUBLE'    => 'FUNC_NUMBER',
+        'REAL'      => 'FUNC_NUMBER',
+        'BIT'       => 'FUNC_NUMBER',
+        'BOOLEAN'   => 'FUNC_NUMBER',
+        'SERIAL'    => 'FUNC_NUMBER',
+
+        'DATE'      => 'FUNC_DATE',
+        'DATETIME'  => 'FUNC_DATE',
+        'TIMESTAMP' => 'FUNC_DATE',
+        'TIME'      => 'FUNC_DATE',
+        'YEAR'      => 'FUNC_DATE',
+
+        'CHAR'          => 'FUNC_CHAR',
+        'VARCHAR'       => 'FUNC_CHAR',
+        'TINYTEXT'      => 'FUNC_CHAR',
+        'TEXT'          => 'FUNC_CHAR',
+        'MEDIUMTEXT'    => 'FUNC_CHAR',
+        'LONGTEXT'      => 'FUNC_CHAR',
+        'BINARY'        => 'FUNC_CHAR',
+        'VARBINARY'     => 'FUNC_CHAR',
+        'TINYBLOB'      => 'FUNC_CHAR',
+        'MEDIUMBLOB'    => 'FUNC_CHAR',
+        'BLOB'          => 'FUNC_CHAR',
+        'LONGBLOB'      => 'FUNC_CHAR',
+        'ENUM'          => '',
+        'SET'           => '',
+
+        'GEOMETRY'              => 'FUNC_SPATIAL',
+        'POINT'                 => 'FUNC_SPATIAL',
+        'LINESTRING'            => 'FUNC_SPATIAL',
+        'POLYGON'               => 'FUNC_SPATIAL',
+        'MULTIPOINT'            => 'FUNC_SPATIAL',
+        'MULTILINESTRING'       => 'FUNC_SPATIAL',
+        'MULTIPOLYGON'          => 'FUNC_SPATIAL',
+        'GEOMETRYCOLLECTION'    => 'FUNC_SPATIAL',
+
+    );
 
     /**
      * Map above defined groups to any function
      *
-     * Fill in this array to overwrite data from data_*.inc.php files
-     *
      * @global array $cfg['RestrictFunctions']
      */
-    $cfg['RestrictFunctions'] = array();
+    $cfg['RestrictFunctions'] = array(
+        'FUNC_CHAR' => array(
+            'BIN',
+            'CHAR',
+            'CURRENT_USER',
+            'COMPRESS',
+            'DAYNAME',
+            'DES_DECRYPT',
+            'DES_ENCRYPT',
+            'ENCRYPT',
+            'HEX',
+            'INET_NTOA',
+            'LOWER',
+            'MD5',
+            'OLD_PASSWORD',
+            'PASSWORD',
+            'REVERSE',
+            'SHA1',
+            'SOUNDEX',
+            'SPACE',
+            'UNCOMPRESS',
+            'UNHEX',
+            'UPPER',
+            'USER',
+            'UUID',
+        ),
+
+        'FUNC_DATE' => array(
+            'CURDATE',
+            'CURTIME',
+            'DATE',
+            'FROM_DAYS',
+            'FROM_UNIXTIME',
+            'NOW',
+            'SEC_TO_TIME',
+            'TIMESTAMP',
+            'UTC_DATE',
+            'UTC_TIME',
+            'UTC_TIMESTAMP',
+            'YEAR',
+        ),
+
+        'FUNC_NUMBER' => array(
+            'ABS',
+            'ACOS',
+            'ASCII',
+            'ASIN',
+            'ATAN',
+            'BIT_LENGTH',
+            'BIT_COUNT',
+            'CEILING',
+            'CHAR_LENGTH',
+            'COS',
+            'COT',
+            'CRC32',
+            'DEGREES',
+            'EXP',
+            'FLOOR',
+            'INET_ATON',
+            'LENGTH',
+            'LN',
+            'LOG',
+            'LOG2',
+            'LOG10',
+            'OCT',
+            'ORD',
+            'RADIANS',
+            'RAND',
+            'ROUND',
+            'SQRT',
+            'STDDEV_POP',
+            'STDDEV_SAMP',
+            'TAN',
+            'TIME_TO_SEC',
+            'UNIX_TIMESTAMP',
+            'VAR_POP',
+            'VAR_SAMP',
+        ),
+
+        'FUNC_SPATIAL' => array(
+            'GeomFromText',
+            'GeomFromWKB',
+
+            'GeomCollFromText',
+            'LineFromText',
+            'MLineFromText',
+            'PointFromText',
+            'MPointFromText',
+            'PolyFromText',
+            'MPolyFromText',
+
+            'GeomCollFromWKB',
+            'LineFromWKB',
+            'MLineFromWKB',
+            'PointFromWKB',
+            'MPointFromWKB',
+            'PolyFromWKB',
+            'MPolyFromWKB',
+        ),
+    );
 
     /**
      * Default functions for above defined groups
@@ -2825,6 +3085,97 @@ if ($cfg['ShowFunctionFields']) {
         'first_timestamp' => 'NOW',
         'pk_char36' => 'UUID',
     );
-}
+
+
+} // end if
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['NumOperators']
+ */
+$cfg['NumOperators'] = array(
+   '=',
+   '>',
+   '>=',
+   '<',
+   '<=',
+   '!=',
+   'LIKE',
+   'NOT LIKE',
+   'IN (...)',
+   'NOT IN (...)',
+   'BETWEEN',
+   'NOT BETWEEN',
+);
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['TextOperators']
+ */
+$cfg['TextOperators'] = array(
+   'LIKE',
+   'LIKE %...%',
+   'NOT LIKE',
+   '=',
+   '!=',
+   'REGEXP',
+   'REGEXP ^...$',
+   'NOT REGEXP',
+   "= ''",
+   "!= ''",
+   'IN (...)',
+   'NOT IN (...)',
+   'BETWEEN',
+   'NOT BETWEEN',
+);
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['EnumOperators']
+ */
+$cfg['EnumOperators'] = array(
+   '=',
+   '!=',
+);
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['SetOperators']
+ */
+$cfg['SetOperators'] = array(
+   'IN',
+   'NOT IN',
+);
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['NullOperators']
+ */
+$cfg['NullOperators'] = array(
+   'IS NULL',
+   'IS NOT NULL',
+);
+
+/**
+ * Search operators
+ *
+ * @global array $cfg['UnaryOperators']
+ */
+$cfg['UnaryOperators'] = array(
+   'IS NULL' => 1,
+   'IS NOT NULL' => 1,
+   "= ''" => 1,
+   "!= ''" => 1
+);
+
+/**
+ * Max rows retreived for zoom search
+ */
+$cfg['maxRowPlotLimit'] = 500;
 
 ?>
diff --git a/libraries/svg_plot/pma_scatter_plot.php b/libraries/svg_plot/pma_scatter_plot.php
new file mode 100644
index 0000000..10c0aea
--- /dev/null
+++ b/libraries/svg_plot/pma_scatter_plot.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ * Generates the SVG needed for the plot
+ *
+ * @package phpMyAdmin
+ */
+
+require_once 'pma_svg_data_point.php';
+
+class PMA_Scatter_Plot
+{
+    /**
+     * @var array   Raw data for the plot
+     */
+    private $_data;
+
+    /**
+     * @var array   Data points of the plot
+     */
+    private $_dataPoints;
+
+    /**
+     * @var array   Set of default settigs values are here.
+     */
+    private $_settings = array(
+
+        // Array of colors to be used for plot.
+        'colors' => array(
+            '#BCE02E',
+            '#E0642E',
+            '#E0D62E',
+            '#2E97E0',
+            '#B02EE0',
+            '#E02E75',
+            '#5CE02E',
+            '#E0B02E',
+            '#000000',
+            '#0022E0',
+            '#726CB1',
+            '#481A36',
+            '#BAC658',
+            '#127224',
+            '#825119',
+            '#238C74',
+            '#4C489B',
+            '#87C9BF',
+        ),
+        // Plot background color.
+        'bgColor' => '#84AD83',
+
+        // The width of the plot.
+        'width' => 520,
+
+         // The height of the plot.
+        'height' => 325,
+
+        // Default X Axis label. If empty, label will be taken from the data.
+        'xLabel' => '',
+
+        // Default Y Axis label. If empty, label will be taken from the data.
+        'yLabel' => '',
+
+        // Data point label. If empty, label will be taken from the data.
+        'dataLabel' => '',
+
+    );
+
+    /**
+     * @var array   Options that the user has specified.
+     */
+    private $_userSpecifiedSettings = null;
+
+    /**
+     * Returns the settings array
+     *
+     * @return the settings array.
+     */
+    public function getSettings()
+    {
+        return $this->_settings;
+    }
+
+    /**
+     * Returns the data array
+     *
+     * @return the data array.
+     */
+    public function getData()
+    {
+        return $this->_data;
+    }
+
+    /**
+     * Constructor. Stores user specified options.
+     *
+     * @param array $data    Data for the visualization
+     * @param array $options Users specified options
+     */
+    public function __construct($data, $options)
+    {
+        $this->_userSpecifiedSettings = $options;
+        $this->_data = $data;
+    }
+
+    /**
+     * All the variable initialization, options handling has to be done here.
+     */
+    protected function init()
+    {
+        $this->_handleOptions();
+    }
+
+    /**
+     * A function which handles passed parameters. Useful if desired
+     * chart needs to be a little bit different from the default one.
+     */
+    private function _handleOptions()
+    {
+        $this->_dataPoints = array();
+        if (! is_null($this->_userSpecifiedSettings)) {
+            foreach (array_keys($this->_userSpecifiedSettings) as $key){
+	        $this->_settings[$key] = $this->_userSpecifiedSettings[$key];	
+ 	    }
+        }
+        if ($this->_settings['dataLabel'] == '') {
+        	$labels = array_keys($this->_data[0]);
+		$this->_settings['dataLabel'] = $labels[0];
+        }
+    }
+
+    /**
+     * Generate the visualization in SVG format.
+     *
+     * @return the generated image resource
+     */
+    private function _svg()
+    {
+        $this->init();
+
+        $output   = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
+        $output  .= '<svg version="1.1" xmlns:svg="http://www.w3.org/2000/svg"'
+            . ' xmlns="http://www.w3.org/2000/svg" width="' . $this->_settings['width'] . '"'
+            . ' height="' . $this->_settings['height'] . '">';
+        $output .= '<g id="groupPanel">';
+        $output .= '<defs>
+		    <path id="myTextPath1"
+                    d="M10,190 L10,50"/>
+                    <path id="myTextPath2"
+                    d="M250,10 L370,10"/>
+                    </defs>';
+        $output .= '<text x="6" y="190"  style="font-family: Arial; font-size  : 54; stroke:none; fill:#000000;" >
+                    <textPath xlink:href="#myTextPath1" >';
+        $output .= $this->_settings['yLabel'];
+        $output .= '</textPath>
+                   </text>';
+
+        $output .= '<text x="250" y="10"  style="font-family: Arial; font-size  : 54; stroke:none; fill:#000000;" >
+                    <textPath xlink:href="#myTextPath2" >';
+        $output .= $this->_settings['xLabel'];
+        $output .= '</textPath>
+                   </text>';
+
+
+        $scale_data = $this->_scaleDataSet($this->_data, $this->_settings['xLabel'], $this->_settings['yLabel']);
+        $output .= $this->_prepareDataSet($this->_data, 0, $scale_data, $this->_settings['dataLabel']);
+
+        $output .= '</g>';
+        $output .= '</svg>';
+
+        return $output;
+    }
+
+    /**
+     * Get the visualization as a SVG.
+     *
+     * @return the visualization as a SVG
+     */
+    public function asSVG()
+    {
+        $output = $this->_svg();
+        return $output;
+    }
+
+    /**
+     * Calculates the scale, horizontal and vertical offset that should be used.
+     *
+     * @param array $data Row data
+     *
+     * @return an array containing the scale, x and y offsets
+     */
+    private function _scaleDataSet($data,$xField,$yField)
+    {
+
+        // Currently assuming only numeric fields are selected 
+        $coordinates = array();
+        foreach ($data as $row) {
+	    $coordinates[0][] = $row[$xField];
+	    $coordinates[1][] = $row[$yField];
+	}
+        for ($i = 0 ; $i < 2 ; $i++) {
+
+            $maxC = ($i == 0) ? 500 : 320;          
+
+            if( !is_numeric($coordinates[$i][0])) {
+                $uniqueC = array_unique($coordinates[$i]);
+                $countC = count(array_unique($coordinates[$i]));
+	        $map = $tmp = array();
+                foreach ($uniqueC as $uc) {
+			$tmp[] = $uc;
+		}
+                for ($j = 0 ; $j < $countC ; $j++) {
+                    $map[$tmp[$j]] = 20 + $j * $maxC / $countC;
+	        }
+		for($j = 0 ; $j < count($coordinates[$i]) ; $j++) {
+     		        $coordinates[$i][$j] = $map[$coordinates[$i][$j]];
+		}
+
+	    }
+            elseif (is_numeric($coordinates[$i][0])) {
+		
+        	$maxC = max($coordinates[$i]);
+		for($j = 0 ; $j < count($coordinates[$i]) ; $j++) {
+		
+		    if ($i == 0)
+     		        $coordinates[$i][$j] = 20 + 500 * $coordinates[$i][$j] / $maxC;
+		    else
+     		        $coordinates[$i][$j] = 20 + 320 * (1 - $coordinates[$i][$j] / $maxC);
+		}
+	    }
+	}
+	return $coordinates;
+    }
+
+    /**
+     * Prepares and return the dataset as needed by the visualization.
+     *
+     * @param array  $data         Raw data
+     * @param int    $color_number Start index to the color array
+     * @param array  $scale_data   Data related to scaling
+     * @param string $label        Label for the data points
+     * @param image  $results      Image object in the case of png
+     *
+     * @return the formatted array of data.
+     */
+    private function _prepareDataSet($data, $color_number, $scale_data, $label)
+    {
+        $result = '';
+        // loop through the rows
+        for($i = 0 ; $i < count($data) ; $i++) {
+
+            $index = $color_number % sizeof($this->_settings['colors']);
+            
+            $data_element = new PMA_SVG_Data_Point($scale_data[0][$i],$scale_data[1][$i],$data[$i][$label],$data[$i]);
+
+            $options = array('color' => $this->_settings['colors'][$index], 'id' => $i);
+            $this->_dataPoints[] = $data_element;
+
+	    $result .= $data_element->prepareRowAsSVG($options);
+            $color_number++;
+        }
+
+
+        return $result;
+    }
+}
+?>
+
diff --git a/libraries/svg_plot/pma_svg_data_element.php b/libraries/svg_plot/pma_svg_data_element.php
new file mode 100644
index 0000000..97f7734
--- /dev/null
+++ b/libraries/svg_plot/pma_svg_data_element.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Base class for the plot data type classes.
+ *
+ * @package phpMyAdmin
+ */
+abstract class PMA_SVG_Data_Element{
+
+    protected $label = '';
+
+    protected $dataRow = array();
+
+    /**
+     * Store user specified label and dataRow
+     * @param string $label users specified label
+     * @param array $dataRow A data row from the query result
+     */
+    function __construct($label,$dataRow)
+    {
+        $this->label = $label;
+        $this->dataRow = $dataRow;
+    }
+
+    /**
+     * Handles the generation of each Data Row/Element as a SVG element
+     * @return the code related to a row in the GIS dataset
+     */
+    public abstract function prepareRowAsSVG($options);
+    
+    public function getLabel()
+    {
+        return $this->label;
+    }
+
+    public function setLabel($label)
+    {
+        $this->label = $label;
+    }
+ 
+    public function getDataRow()
+    {
+        return $this->dataRow;
+    }
+
+    public function setDataRow($dataRow)
+    {
+        $this->dataRow = $dataRow;
+    }
+}
+?>
diff --git a/libraries/svg_plot/pma_svg_data_point.php b/libraries/svg_plot/pma_svg_data_point.php
new file mode 100644
index 0000000..7d01b2b
--- /dev/null
+++ b/libraries/svg_plot/pma_svg_data_point.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Handles the visualization of Data Point objects.
+ *
+ * @package phpMyAdmin
+ */
+
+require_once 'pma_svg_data_element.php';
+
+class PMA_SVG_Data_Point extends PMA_SVG_Data_Element
+{
+    /*
+     * X-Coordinate of the point
+     */
+    private $cx;
+    
+    /*
+     * Y-Coordinate of the point
+     */
+    private $cy;
+
+    /*
+     * A private constructor; prevents direct creation of object.
+     */
+    public function __construct($cx, $cy, $label, $dataRow)
+    {
+        parent::__construct($label,$dataRow);
+	$this->cx = $cx;
+	$this->cy = $cy;
+        
+    }
+
+    public function prepareRowAsSVG($options)
+    {
+         return $this->prepareSvg($options);
+    }
+
+    /**
+     * Prepares and returns the code related to a row in the query result as SVG.
+     *
+     * @param array  $options  Array containing options related to properties of the point
+     *
+     * @return the code related to a row in the query result.
+     */
+    
+    protected function prepareSvg($options)
+    {
+        $point_options = array(
+            'name'        => $this->label . '_' .$options['id'],
+            'id'          => $this->label . 'id' . '_' . $options['id'],
+            'class'       => 'point',
+            'fill'        => 'white',
+            'stroke'      => $options['color'],
+            'stroke-width'=> 2,
+        );
+         
+        $row = '<circle cx="' . $this->cx . '" cy="' . $this->cy . '" r=".1"';
+        foreach ($point_options as $option => $val) {
+            $row .= ' ' . $option . '="' . trim($val) . '"';
+        }
+        $row .= '/>';
+
+        return $row;
+    }
+  
+    public function getCx()
+    {
+        return $this->cx;
+    }
+
+    public function setCx($cx)
+    {
+        $this->cx = $cx;
+    }
+
+    public function getCy()
+    {
+        return $this->cy;
+    }
+
+    public function setCy($cy)
+    {
+        $this->cy = $cy;
+    }
+}
+?>
diff --git a/libraries/tbl_select.lib.php b/libraries/tbl_select.lib.php
new file mode 100644
index 0000000..6384f60
--- /dev/null
+++ b/libraries/tbl_select.lib.php
@@ -0,0 +1,390 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Functions for the table-search page and zoom-search page
+ *
+ * Funtion PMA_tbl_getFields : Returns the fields of a table 
+ * Funtion PMA_tbl_search_getWhereClause : Returns the where clause for query generation 
+ *
+ * @package phpMyAdmin
+ */
+
+require_once 'url_generating.lib.php';
+
+ /**
+ * PMA_tbl_setTitle() sets the title for foreign keys display link
+ * 
+ * @param    $propertiesIconic    Type of icon property
+ * @param    $themeImage          Icon Image
+ * @return   string $str          Value of the Title
+ *
+ */
+
+function PMA_tbl_setTitle($propertiesIconic,$pmaThemeImage){
+    if ($propertiesIconic == true) {
+        $str = '<img class="icon" width="16" height="16" src="' . $pmaThemeImage
+	        .'b_browse.png" alt="' . __('Browse foreign values') . '" title="'
+	        . __('Browse foreign values') . '" />';
+
+	if ($propertiesIconic === 'both') {
+	    $str .= __('Browse foreign values');
+            return $str;
+	    }
+	} else {
+	    return __('Browse foreign values');
+	}
+}
+
+ /**
+ * PMA_tbl_getFields() gets all the fields of a table along with their types,collations and whether null or not.
+ *
+ * @uses     PMA_DBI_query()
+ * @uses     PMA_backquote()
+ * @uses     PMA_DBI_num_rows()
+ * @uses     PMA_DBI_fetch_assoc()
+ * @uses     PMA_DBI_free_result()
+ * @uses     preg_replace()
+ * @uses     str_replace()
+ * @uses     strncasecmp()
+ * @uses     empty()
+ *
+ * @param    $db    								Selected database
+ * @param    $table    								Selected table
+ *
+ * @return   array($fields_list,$fields_type,$fields_collation,$fields_null)    Array containing the field list, field types, collations and null constatint       
+ *
+ */
+
+function PMA_tbl_getFields($table,$db) {
+    
+    // Gets the list and number of fields
+
+    $result     = PMA_DBI_query('SHOW FULL FIELDS FROM ' . PMA_backquote($table) . ' FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE);
+    $fields_cnt = PMA_DBI_num_rows($result);
+    $fields_list = $fields_null = $fields_type = $fields_collation = array();
+    while ($row = PMA_DBI_fetch_assoc($result)) {
+        $fields_list[] = $row['Field'];
+        $type          = $row['Type'];
+        // reformat mysql query output
+        if (strncasecmp($type, 'set', 3) == 0
+            || strncasecmp($type, 'enum', 4) == 0) {
+            $type = str_replace(',', ', ', $type);
+        } else {
+
+            // strip the "BINARY" attribute, except if we find "BINARY(" because
+            // this would be a BINARY or VARBINARY field type
+            if (!preg_match('@BINARY[\(]@i', $type)) {
+                $type = preg_replace('@BINARY at i', '', $type);
+            }
+            $type = preg_replace('@ZEROFILL at i', '', $type);
+            $type = preg_replace('@UNSIGNED at i', '', $type);
+
+            $type = strtolower($type);
+        }
+        if (empty($type)) {
+            $type = ' ';
+        }
+        $fields_null[] = $row['Null'];
+        $fields_type[] = $type;
+        $fields_collation[] = !empty($row['Collation']) && $row['Collation'] != 'NULL'
+                          ? $row['Collation']
+                          : '';
+    } // end while
+    PMA_DBI_free_result($result);
+    unset($result, $type);
+
+    return array($fields_list,$fields_type,$fields_collation,$fields_null);
+   
+}
+
+/* PMA_tbl_setTableHeader() sets the table header for displaying a table in query-by-example format
+ *
+ * @return   HTML content, the tags and content for table header       
+ *
+ */
+
+function PMA_tbl_setTableHeader(){
+
+return '<thead>
+        <tr><th>' .  __('Column') . '</th>
+        <th>' .  __('Type') . '</th>
+        <th>' .  __('Collation') . '</th>
+        <th>' .  __('Operator') . '</th>
+        <th>' .  __('Value') . '</th>
+   	</tr>
+        </thead>';
+
+
+}
+
+/* PMA_tbl_getSubTabs() returns an array with necessary configrations to create sub-tabs(Table Search and Zoom Search) in the table_select page 
+ *
+ * @return   array $subtabs    Array containing configuration (icon,text,link,id,args) of sub-tabs for Table Search and Zoom search       
+ *
+ */
+
+function PMA_tbl_getSubTabs(){
+
+    $subtabs = array();
+
+    $subtabs['search']['icon'] = 'b_search.png';
+    $subtabs['search']['text'] = __('Table Search');
+    $subtabs['search']['link'] = 'tbl_select.php';
+    $subtabs['search']['id'] = 'tbl_search_id';
+    $subtabs['search']['args']['pos'] = 0;
+
+    $subtabs['zoom']['icon'] = 'b_props.png';
+    $subtabs['zoom']['link'] = 'tbl_zoom_select.php';
+    $subtabs['zoom']['text'] = __('Zoom Search');
+    $subtabs['zoom']['id'] = 'zoom_search_id';
+	
+    return $subtabs;
+
+}
+
+
+/* PMA_tbl_getForeignFields_Values() creates the HTML content for: 1) Browsing foreign data for a field. 2) Creating elements for search criteria input on fields.
+ *
+ * @uses     PMA_foreignDropdown
+ * @uses     PMA_generate_common_url
+ * @uses     isset()
+ * @uses     is_array()
+ * @uses     in_array()
+ * @uses     urlencode()
+ * @uses     str_replace()
+ * @uses     stbstr()
+ *
+ * @param    $foreigners          Array of foreign keys
+ * @param    $foreignData         Foreign keys data
+ * @param    $field               Column name
+ * @param    $tbl_fields_type     Column type
+ * @param    $i                   Column index
+ * @param    $db                  Selected database
+ * @param    $table               Selected table
+ * @param    $titles              Selected title
+ * @param    $foreignMaxLimit     Max limit of displaying foreign elements
+ * @param    $fields              Array of search criteria inputs
+ *
+ * @return   string $str    HTML content for viewing foreing data and elements for search criteria input.       
+ *
+ */
+
+function PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i, $db, $table,$titles,$foreignMaxLimit, $fields){
+
+    $str = '';
+
+    if ($foreigners && isset($foreigners[$field]) && is_array($foreignData['disp_row'])) {
+        // f o r e i g n    k e y s
+        $str .=  '            <select name="fields[' . $i . ']" id="fieldID_' . $i .'">' . "\n";
+        // go back to first row
+        // here, the 4th parameter is empty because there is no current
+        // value of data for the dropdown (the search page initial values
+        // are displayed empty)
+        $str .= PMA_foreignDropdown($foreignData['disp_row'],
+                $foreignData['foreign_field'],
+                $foreignData['foreign_display'],
+                '', $foreignMaxLimit);
+        $str .= '            </select>' . "\n";
+    } 
+    elseif ($foreignData['foreign_link'] == true) {
+        if(isset($fields[$i]) && is_string($fields[$i])){
+ 	    $str .= '<input type="text" id="fieldID_' . $i .'"name="fields[' . $i . '] " value="' . $fields[$i] . '"';
+		     'id="field_' . md5($field) . '[' . $i .']" 
+		     class="textfield"/>' ; 
+        }
+        else{
+ 	    $str .= '<input type="text" id="fieldID_' . $i .'"name="fields[' . $i . '] "';
+		     'id="field_' . md5($field) . '[' . $i .']" 
+		     class="textfield" />' ; 
+        }
+ ?>
+	<?php $str .= '<script type="text/javascript">';
+        // <![CDATA[
+	$str .=  <<<EOT
+<a target="_blank" onclick="window.open(this.href, 'foreigners', 'width=640,height=240,scrollbars=yes'); return false" href="browse_foreigners.php? 
+EOT;
+        $str .= '' . PMA_generate_common_url($db, $table) .  '&field=' . urlencode($field) . '&fieldkey=' . $i . '">' . str_replace("'", "\'", $titles['Browse']) . '</a>';
+        // ]]
+        $str .= '</script>';
+        } 
+    elseif (strncasecmp($tbl_fields_type[$i], 'enum', 4) == 0) {
+        // e n u m s
+        $enum_value=explode(', ', str_replace("'", '', substr($tbl_fields_type[$i], 5, -1)));
+        $cnt_enum_value = count($enum_value);
+        $str .= '<select name="fields[' . ($i) . '][]" id="fieldID_' . $i .'"'
+                 .' multiple="multiple" size="' . min(3, $cnt_enum_value) . '">' . "\n";
+                for ($j = 0; $j < $cnt_enum_value; $j++) {
+                    if(isset($fields[$i]) && is_array($fields[$i]) && in_array($enum_value[$j],$fields[$i])){
+                        $str .= '                <option value="' . $enum_value[$j] . '" Selected>'
+                                        . $enum_value[$j] . '</option>';
+                        }
+                        else{
+                                $str .= '                <option value="' . $enum_value[$j] . '">'
+                                        . $enum_value[$j] . '</option>';
+                        }
+                } // end for
+        $str .= '            </select>' . "\n";
+    } 
+    else {
+        // o t h e r   c a s e s
+        $the_class = 'textfield';
+        $type = $tbl_fields_type[$i];
+        if ($type == 'date') {
+            $the_class .= ' datefield';
+        } elseif ($type == 'datetime' || substr($type, 0, 9) == 'timestamp') {
+            $the_class .= ' datetimefield';
+        }
+        if(isset($fields[$i]) && is_string($fields[$i])){
+            $str .= '            <input type="text" name="fields[' . $i . ']" '
+                    .' size="40" class="' . $the_class . '" id="fieldID_' . $i .'" value = "' . $fields[$i] . '"/>' .  "\n";
+        }
+        else{
+            $str .= '            <input type="text" name="fields[' . $i . ']"'
+                    .' size="40" class="' . $the_class . '" id="fieldID_' . $i .'" />' .  "\n";
+        }
+   };
+   return $str;
+
+}
+
+
+/* PMA_tbl_search_getWhereClause() Return the where clause for query generation based on the inputs provided.
+ *
+ * @uses     PMA_backquote
+ * @uses     PMA_sqlAddslashes
+ * @uses     preg_match
+ * @uses     isset()
+ * @uses     in_array()
+ * @uses     str_replace()
+ * @uses     strpos()
+ * @uses     explode()
+ * @uses     trim()
+ *
+ * @param    $fields        Search criteria input
+ * @param    $names         Name of the field(column) on which search criteria is submitted
+ * @param    $types         Type of the field
+ * @param    $collations    Field collation
+ * @param    $func_type     Search fucntion/operator
+ * @param    $unaryFlag     Whether operator unary or not
+ *
+ * @return   string $str    HTML content for viewing foreing data and elements for search criteria input.       
+ *
+ */
+
+function PMA_tbl_search_getWhereClause($fields, $names, $types, $collations, $func_type, $unaryFlag){
+	
+
+    $w = ''; 
+    if($unaryFlag){
+        $fields = '';
+            $w = PMA_backquote($names) . ' ' . $func_type;
+
+    } elseif (strncasecmp($types, 'enum', 4) == 0) {
+        if (!empty($fields)) {
+            if (! is_array($fields)) {
+                $fields = explode(',', $fields);
+            }
+            $enum_selected_count = count($fields);
+            if ($func_type == '=' && $enum_selected_count > 1) {
+                $func_type    = 'IN';
+                $parens_open  = '(';
+                $parens_close = ')';
+
+            } elseif ($func_type == '!=' && $enum_selected_count > 1) {
+                $func_type    = 'NOT IN';
+                $parens_open  = '(';
+                $parens_close = ')';
+
+           } else {
+               $parens_open  = '';
+               $parens_close = '';
+           }
+               $enum_where = '\'' . PMA_sqlAddslashes($fields[0]) . '\'';
+               for ($e = 1; $e < $enum_selected_count; $e++) {
+                   $enum_where .= ', \'' . PMA_sqlAddslashes($fields[$e]) . '\'';
+               }
+
+               $w = PMA_backquote($names) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close;
+        }
+
+    } elseif ($fields != '') {
+        // For these types we quote the value. Even if it's another type (like INT),
+        // for a LIKE we always quote the value. MySQL converts strings to numbers
+        // and numbers to strings as necessary during the comparison
+        if (preg_match('@char|binary|blob|text|set|date|time|year at i', $types) || strpos(' ' . $func_type, 'LIKE')) {
+            $quot = '\'';
+        } else {
+            $quot = '';
+        }
+
+        // LIKE %...%
+        if ($func_type == 'LIKE %...%') {
+            $func_type = 'LIKE';
+            $fields = '%' . $fields . '%';
+        }
+        if ($func_type == 'REGEXP ^...$') {
+            $func_type = 'REGEXP';
+            $fields = '^' . $fields . '$';
+        }
+
+        if ($func_type == 'IN (...)' || $func_type == 'NOT IN (...)' || $func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') {
+            $func_type = str_replace(' (...)', '', $func_type);
+
+        // quote values one by one
+        $values = explode(',', $fields);
+        foreach ($values as &$value)
+            $value = $quot . PMA_sqlAddslashes(trim($value)) . $quot;
+
+            if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN')
+                $w = PMA_backquote($names) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '')  . ' AND ' . (isset($values[1]) ? $values[1] : '');
+            else
+                $w = PMA_backquote($names) . ' ' . $func_type . ' (' . implode(',', $values) . ')';
+        }
+        else {
+            $w = PMA_backquote($names) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddslashes($fields) . $quot;;
+        }
+
+    } // end if
+
+    return $w;
+}
+
+/**
+ * Formats a SVG plot for the query results.
+ *
+ * @param array  $data                   Data for the status chart
+ * @param array  &$settings              Settings used to generate the chart
+ *
+ * @return string HTML and JS code for the SVG plot
+ */
+function PMA_SVG_scatter_plot($data, &$settings)
+{
+    require_once './libraries/svg_plot/pma_scatter_plot.php';
+
+    if (empty($data)) {
+        // empty data
+        return '';
+    } else {
+        $scatter_plot = new PMA_Scatter_Plot($data, $settings);
+
+        if ($settings != null) {
+            foreach ($scatter_plot->getSettings() as $setting => $val) {
+                if (! isset($settings[$setting])) {
+                    $settings[$setting] = $val;
+                }
+            }
+        }
+        return $scatter_plot->asSVG();
+    }
+
+}
+
+
+
+
+
+
+
+
+
+?>
diff --git a/tbl_select.php b/tbl_select.php
index c6b0a35..e9b1eae 100644
--- a/tbl_select.php
+++ b/tbl_select.php
@@ -15,6 +15,7 @@
  */
 require_once './libraries/common.inc.php';
 require_once './libraries/mysql_charsets.lib.php';
+require_once './libraries/tbl_select.lib.php';
 
 $GLOBALS['js_include'][] = 'makegrid.js';
 $GLOBALS['js_include'][] = 'sql.js';
@@ -22,18 +23,8 @@ $GLOBALS['js_include'][] = 'tbl_select.js';
 $GLOBALS['js_include'][] = 'tbl_change.js';
 $GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js';
 $GLOBALS['js_include'][] = 'jquery/timepicker.js';
-if ($GLOBALS['cfg']['PropertiesIconic'] == true) {
-    $titles['Browse'] =
-        '<img class="icon" width="16" height="16" src="' . $pmaThemeImage
-        .'b_browse.png" alt="' . __('Browse foreign values') . '" title="'
-        . __('Browse foreign values') . '" />';
-
-    if ($GLOBALS['cfg']['PropertiesIconic'] === 'both') {
-        $titles['Browse'] .= __('Browse foreign values');
-    }
-} else {
-    $titles['Browse'] = __('Browse foreign values');
-}
+
+$titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage);
 
 /**
  * Not selection yet required -> displays the selection form
@@ -61,45 +52,26 @@ if (! isset($param) || $param[0] == '') {
     $err_url   = $goto . '?' . PMA_generate_common_url($db, $table);
 
     // Gets the list and number of fields
-    $result     = PMA_DBI_query('SHOW FULL FIELDS FROM ' . PMA_backquote($table) . ' FROM ' . PMA_backquote($db) . ';', null, PMA_DBI_QUERY_STORE);
-    $fields_cnt = PMA_DBI_num_rows($result);
-    $fields_list = $fields_null = $fields_type = $fields_collation = array();
-    while ($row = PMA_DBI_fetch_assoc($result)) {
-        $fields_list[] = $row['Field'];
-        $type          = $row['Type'];
-        // reformat mysql query output
-        if (strncasecmp($type, 'set', 3) == 0
-            || strncasecmp($type, 'enum', 4) == 0) {
-            $type = str_replace(',', ', ', $type);
-        } else {
 
-            // strip the "BINARY" attribute, except if we find "BINARY(" because
-            // this would be a BINARY or VARBINARY field type
-            if (!preg_match('@BINARY[\(]@i', $type)) {
-                $type = preg_replace('@BINARY at i', '', $type);
-            }
-            $type = preg_replace('@ZEROFILL at i', '', $type);
-            $type = preg_replace('@UNSIGNED at i', '', $type);
-
-            $type = strtolower($type);
-        }
-        if (empty($type)) {
-            $type = ' ';
-        }
-        $fields_null[] = $row['Null'];
-        $fields_type[] = $type;
-        $fields_collation[] = !empty($row['Collation']) && $row['Collation'] != 'NULL'
-                          ? $row['Collation']
-                          : '';
-    } // end while
-    PMA_DBI_free_result($result);
-    unset($result, $type);
+    list($fields_list, $fields_type, $fields_collation, $fields_null) = PMA_tbl_getFields($table,$db);
+    $fields_cnt = count($fields_list);
 
     // retrieve keys into foreign fields, if any
     // check also foreigners even if relwork is FALSE (to get
     // foreign keys from innodb)
     $foreigners = PMA_getForeigners($db, $table);
     ?>
+
+<fieldset id="fieldset_subtab">
+<?php
+$url_params = array();
+$url_params['db']    = $db;
+$url_params['table'] = $table;
+
+echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params);
+
+?>
+
         <form method="post" action="tbl_select.php" name="insertForm" id="tbl_search_form" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? ' class="ajax"' : ''); ?>>
 <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
 <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
@@ -110,14 +82,7 @@ if (! isset($param) || $param[0] == '') {
 <fieldset id="fieldset_table_qbe">
     <legend><?php echo __('Do a "query by example" (wildcard: "%")') ?></legend>
     <table class="data">
-    <thead>
-    <tr><th><?php echo __('Column'); ?></th>
-        <th><?php echo __('Type'); ?></th>
-        <th><?php echo __('Collation'); ?></th>
-        <th><?php echo __('Operator'); ?></th>
-        <th><?php echo __('Value'); ?></th>
-    </tr>
-    </thead>
+    <?php echo PMA_tbl_setTableHeader(); ?>
     <tbody>
     <?php
     $odd_row = true;
@@ -130,57 +95,31 @@ if (! isset($param) || $param[0] == '') {
             <td><?php echo $fields_collation[$i]; ?></td>
             <td><select name="func[]">
         <?php
-        // determine valid operators
         if (strncasecmp($fields_type[$i], 'enum', 4) == 0) {
-            // enum operators
-            $operators = array(
-                '=',
-                '!=',
-            );
+            foreach ($GLOBALS['cfg']['EnumOperators'] as $fc) {
+                echo "\n" . '                        '
+                   . '<option value="' . htmlspecialchars($fc) . '">'
+                   . htmlspecialchars($fc) . '</option>';
+            }
         } elseif (preg_match('@char|blob|text|set at i', $fields_type[$i])) {
-            // text operators
-            $operators = array(
-               'LIKE',
-               'LIKE %...%',
-               'NOT LIKE',
-               '=',
-               '!=',
-               'REGEXP',
-               'REGEXP ^...$',
-               'NOT REGEXP',
-               "= ''",
-               "!= ''",
-               'IN (...)',
-               'NOT IN (...)',
-               'BETWEEN',
-               'NOT BETWEEN',
-            );
+            foreach ($GLOBALS['cfg']['TextOperators'] as $fc) {
+            echo "\n" . '                        '
+               . '<option value="' . htmlspecialchars($fc) . '">'
+               . htmlspecialchars($fc) . '</option>';
+            }
         } else {
-            // numeric operators
-            $operators = array(
-               '=',
-               '>',
-               '>=',
-               '<',
-               '<=',
-               '!=',
-               'LIKE',
-               'NOT LIKE',
-               'IN (...)',
-               'NOT IN (...)',
-               'BETWEEN',
-               'NOT BETWEEN',
-            );
+            foreach ($GLOBALS['cfg']['NumOperators'] as $fc) {
+                echo "\n" . '                        '
+                   . '<option value="' .  htmlspecialchars($fc) . '">'
+                   . htmlspecialchars($fc) . '</option>';
+            }
         } // end if... else...
-
-        // if field can be NULL, add IS NULL and IS NOT NULL
         if ($fields_null[$i]) {
-            $operators[] = 'IS NULL';
-            $operators[] = 'IS NOT NULL';
-        }
-        foreach ($operators as $op) {
-            echo "\n" . '                        '
-               . '<option value="' .  htmlspecialchars($op) . '">' . htmlspecialchars($op) . '</option>';
+            foreach ($GLOBALS['cfg']['NullOperators'] as $fc) {
+                echo "\n" . '                        '
+                   . '<option value="' .  htmlspecialchars($fc) . '">'
+                   . htmlspecialchars($fc) . '</option>';
+            }
         }
         ?>
 
@@ -192,54 +131,9 @@ if (! isset($param) || $param[0] == '') {
 
         $foreignData = PMA_getForeignData($foreigners, $field, false, '', '');
 
-        if ($foreigners && isset($foreigners[$field]) && is_array($foreignData['disp_row'])) {
-            // f o r e i g n    k e y s
-            echo '            <select name="fields[' . $i . ']">' . "\n";
-            // go back to first row
-
-            // here, the 4th parameter is empty because there is no current
-            // value of data for the dropdown (the search page initial values
-            // are displayed empty)
-            echo PMA_foreignDropdown($foreignData['disp_row'],
-                $foreignData['foreign_field'],
-                $foreignData['foreign_display'],
-                '', $GLOBALS['cfg']['ForeignKeyMaxLimit']);
-            echo '            </select>' . "\n";
-        } elseif ($foreignData['foreign_link'] == true) {
-            ?>
-            <input type="text" name="fields[<?php echo $i; ?>]"
-                id="field_<?php echo md5($field); ?>[<?php echo $i; ?>]"
-                class="textfield" />
-            <script type="text/javascript">
-            // <![CDATA[
-                document.writeln('<a target="_blank" onclick="window.open(this.href, \'foreigners\', \'width=640,height=240,scrollbars=yes\'); return false" href="browse_foreigners.php?<?php echo PMA_generate_common_url($db, $table); ?>&field=<?php echo urlencode($field); ?>&fieldkey=<?php echo $i; ?>"><?php echo str_replace("'", "\'", $titles['Browse']); ?></a>');
-            // ]]>
-            </script>
-            <?php
-        } elseif (strncasecmp($fields_type[$i], 'enum', 4) == 0) {
-            // e n u m s
-            $enum_value=explode(', ', str_replace("'", '', substr($fields_type[$i], 5, -1)));
-            $cnt_enum_value = count($enum_value);
-            echo '            <select name="fields[' . $i . '][]"'
-                .' multiple="multiple" size="' . min(3, $cnt_enum_value) . '">' . "\n";
-            for ($j = 0; $j < $cnt_enum_value; $j++) {
-                echo '                <option value="' . $enum_value[$j] . '">'
-                    . $enum_value[$j] . '</option>';
-            } // end for
-            echo '            </select>' . "\n";
-        } else {
-            // o t h e r   c a s e s
-            $the_class = 'textfield';
-            $type = $fields_type[$i];
-            if ($type == 'date') {
-                $the_class .= ' datefield';
-            } elseif ($type == 'datetime' || substr($type, 0, 9) == 'timestamp') {
-                $the_class .= ' datetimefield';
-            }
-            echo '            <input type="text" name="fields[' . $i . ']"'
-                .' size="40" class="' . $the_class . '" id="field_' . $i . '" />' .  "\n";
-        };
-        ?>
+	echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $fields_type, $i, $db, $table, $titles,$GLOBALS['cfg']['ForeignKeyMaxLimit'], '' );
+        
+	?>
             <input type="hidden" name="names[<?php echo $i; ?>]"
                 value="<?php echo htmlspecialchars($fields_list[$i]); ?>" />
             <input type="hidden" name="types[<?php echo $i; ?>]"
@@ -321,13 +215,20 @@ if (! isset($param) || $param[0] == '') {
 <div id="sqlqueryresults"></div>
     <?php
     require './libraries/footer.inc.php';
+?>
+
+</fieldset>
+
+<?php
 }
 
 
+
 /**
  * Selection criteria have been submitted -> do the work
  */
 else {
+    echo "ZZ";
     // Builds the query
 
     $sql_query = 'SELECT ' . (isset($distinct) ? 'DISTINCT ' : '');
@@ -354,88 +255,18 @@ else {
         $sql_query .= ' WHERE ' . $where;
     } else {
         $w = $charsets = array();
-        $unary_operators = array(
-           'IS NULL' => 1,
-           'IS NOT NULL' => 1,
-           "= ''" => 1,
-           "!= ''" => 1
-        );
         $cnt_func = count($func);
         reset($func);
         while (list($i, $func_type) = each($func)) {
-            list($charsets[$i]) = explode('_', $collations[$i]);
-            if (isset($unary_operators[$func_type])) {
-                $fields[$i] = '';
-                $w[] = PMA_backquote($names[$i]) . ' ' . $func_type;
-
-            } elseif (strncasecmp($types[$i], 'enum', 4) == 0) {
-                if (!empty($fields[$i])) {
-                    if (! is_array($fields[$i])) {
-                        $fields[$i] = explode(',', $fields[$i]);
-                    }
-                    $enum_selected_count = count($fields[$i]);
-                    if ($func_type == '=' && $enum_selected_count > 1) {
-                        $func_type    = $func[$i] = 'IN';
-                        $parens_open  = '(';
-                        $parens_close = ')';
-
-                    } elseif ($func_type == '!=' && $enum_selected_count > 1) {
-                        $func_type    = $func[$i] = 'NOT IN';
-                        $parens_open  = '(';
-                        $parens_close = ')';
-
-                    } else {
-                        $parens_open  = '';
-                        $parens_close = '';
-                    }
-                    $enum_where = '\'' . PMA_sqlAddSlashes($fields[$i][0]) . '\'';
-                    for ($e = 1; $e < $enum_selected_count; $e++) {
-                        $enum_where .= ', \'' . PMA_sqlAddSlashes($fields[$i][$e]) . '\'';
-                    }
-
-                    $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . $parens_open . $enum_where . $parens_close;
-                }
-
-            } elseif ($fields[$i] != '') {
-                // For these types we quote the value. Even if it's another type (like INT),
-                // for a LIKE we always quote the value. MySQL converts strings to numbers
-                // and numbers to strings as necessary during the comparison
-                if (preg_match('@char|binary|blob|text|set|date|time|year at i', $types[$i]) || strpos(' ' . $func_type, 'LIKE')) {
-                    $quot = '\'';
-                } else {
-                    $quot = '';
-                }
-
-                // LIKE %...%
-                if ($func_type == 'LIKE %...%') {
-                    $func_type = 'LIKE';
-                    $fields[$i] = '%' . $fields[$i] . '%';
-                }
-                if ($func_type == 'REGEXP ^...$') {
-                    $func_type = 'REGEXP';
-                    $fields[$i] = '^' . $fields[$i] . '$';
-                }
-
-                if ($func_type == 'IN (...)' || $func_type == 'NOT IN (...)' || $func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN') {
-                    $func_type = str_replace(' (...)', '', $func_type);
-
-                    // quote values one by one
-                    $values = explode(',', $fields[$i]);
-                    foreach ($values as &$value)
-                        $value = $quot . PMA_sqlAddSlashes(trim($value)) . $quot;
-
-                    if ($func_type == 'BETWEEN' || $func_type == 'NOT BETWEEN')
-                        $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . (isset($values[0]) ? $values[0] : '')  . ' AND ' . (isset($values[1]) ? $values[1] : '');
-                    else
-                        $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' (' . implode(',', $values) . ')';
-                }
-                else {
-                    $w[] = PMA_backquote($names[$i]) . ' ' . $func_type . ' ' . $quot . PMA_sqlAddSlashes($fields[$i]) . $quot;;
-                }
-
-            } // end if
+            
+	    list($charsets[$i]) = explode('_', $collations[$i]);
+            $unaryFlag =  (isset($GLOBALS['cfg']['UnaryOperators'][$func_type]) && $GLOBALS['cfg']['UnaryOperators'][$func_type] == 1) ? true : false;
+	    $whereClause = PMA_tbl_search_getWhereClause($fields[$i],$names[$i], $types[$i], $collations[$i], $func_type, $unaryFlag);
+	    if($whereClause)
+		$w[] = $whereClause;
+	
         } // end for
-
+	//print_r($w);
         if ($w) {
             $sql_query .= ' WHERE ' . implode(' AND ', $w);
         }
@@ -444,7 +275,6 @@ else {
     if ($orderField != '--nil--') {
         $sql_query .= ' ORDER BY ' . PMA_backquote($orderField) . ' ' . $order;
     } // end if
-
     require './sql.php';
 }
 
diff --git a/tbl_zoom_select.php b/tbl_zoom_select.php
new file mode 100644
index 0000000..cdb784d
--- /dev/null
+++ b/tbl_zoom_select.php
@@ -0,0 +1,447 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Handles table zoom search tab
+ *
+ * display table zoom search form, create SQL queries from form data
+ *
+ */
+
+/**
+ * Gets some core libraries
+ */
+require_once './libraries/common.inc.php';
+require_once './libraries/mysql_charsets.lib.php';
+require_once './libraries/tbl_select.lib.php';
+require_once './libraries/relation.lib.php';
+require_once './libraries/tbl_info.inc.php';
+
+$GLOBALS['js_include'][] = 'makegrid.js';
+$GLOBALS['js_include'][] = 'sql.js';
+$GLOBALS['js_include'][] = 'functions.js';
+$GLOBALS['js_include'][] = 'tbl_zoom_plot.js';
+$GLOBALS['js_include'][] = 'date.js';
+$GLOBALS['js_include'][] = 'highcharts/highcharts.js';
+/* Files required for chart exporting */
+$GLOBALS['js_include'][] = 'highcharts/exporting.js';
+$GLOBALS['js_include'][] = 'canvg/canvg.js';
+$GLOBALS['js_include'][] = 'canvg/rgbcolor.js';
+$GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js';
+$GLOBALS['js_include'][] = 'jquery/timepicker.js';
+
+
+/** 
+ * Handle AJAX request for data row on point select
+ * @var post_params Object containing parameters for the POST request
+ */
+
+if (isset($_REQUEST['get_data_row']) && $_REQUEST['get_data_row'] == true) {
+    
+    $extra_data = array(); 
+    $row_info_query = 'SELECT * FROM `' . $_REQUEST['db'] . '`.`' . $_REQUEST['table'] . '` WHERE ' .  $_REQUEST['where_clause'];	
+    $result     = PMA_DBI_query( $row_info_query . ";" , null, PMA_DBI_QUERY_STORE);
+    $fields_meta = PMA_DBI_get_fields_meta($result);
+    while ($row = PMA_DBI_fetch_assoc($result)) 
+	$extra_data['row_info'] = $row;
+
+    PMA_ajaxResponse(NULL, true, $extra_data);
+}
+
+$titles['Browse'] = PMA_tbl_setTitle($GLOBALS['cfg']['PropertiesIconic'], $pmaThemeImage);
+/**
+ * Not selection yet required -> displays the selection form
+ */
+
+    // Gets some core libraries
+    require_once './libraries/tbl_common.php';
+    //$err_url   = 'tbl_select.php' . $err_url;
+    $url_query .= '&goto=tbl_select.php&back=tbl_select.php';
+
+    /**
+     * Gets tables informations
+     */
+    require_once './libraries/tbl_info.inc.php';
+
+    /**
+     * Displays top menu links
+     */
+    require_once './libraries/tbl_links.inc.php';
+
+    if (! isset($goto)) {
+        $goto = $GLOBALS['cfg']['DefaultTabTable'];
+    }
+    // Defines the url to return to in case of error in the next sql statement
+    $err_url   = $goto . '?' . PMA_generate_common_url($db, $table);
+
+    // Gets the list and number of fields
+
+    list($fields_list, $fields_type, $fields_collation, $fields_null) = PMA_tbl_getFields($table,$db);
+    $fields_cnt = count($fields_list);
+
+    // retrieve keys into foreign fields, if any
+    // check also foreigners even if relwork is FALSE (to get
+    // foreign keys from innodb)
+    $foreigners = PMA_getForeigners($db, $table);
+    $flag = 1;
+    $tbl_fields_type = $tbl_fields_collation = $tbl_fields_null = array();
+    if(!isset($zoom_submit) && !isset($inputs))
+        $dataLabel = PMA_getDisplayField($db,$table);
+
+    ?>
+
+
+<div id="sqlqueryresults"></div>
+<fieldset id="fieldset_subtab">
+<?php
+$url_params = array();
+$url_params['db']    = $db;
+$url_params['table'] = $table;
+echo PMA_generate_html_tabs(PMA_tbl_getSubTabs(), $url_params);
+
+/**
+ *  Set the field name,type,collation and whether null on select of a coulmn
+ */
+if(isset($inputs) && ($inputs[0] != __('pma_null') || $inputs[1] != __('pma_null')))
+{
+    $flag = 2;
+    for($i = 0 ; $i < 4 ; $i++)
+    {
+        if($inputs[$i] != __('pma_null'))
+        {
+	    $key = array_search($inputs[$i],$fields_list);
+	    $tbl_fields_type[$i] = $fields_type[$key];
+	    $tbl_fields_collation[$i] = $fields_collation[$key];
+	    $tbl_fields_null[$i] = $fields_null[$key];
+	}
+
+    }
+}
+
+
+?>
+
+<?php
+  
+/*
+ * Form for input criteria
+ */
+
+?>
+<form method="post" action="tbl_zoom_select.php" name="zoomInputForm" id="zoom_search_form" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? ' class="ajax"' : ''); ?>>
+<?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
+<input type="hidden" name="goto" value="<?php echo $goto; ?>" />
+<input type="hidden" name="back" value="tbl_zoom_select.php" />
+<input type="hidden" name="flag" id="id_flag" value=<?php echo $flag; ?> />
+
+
+
+
+<fieldset id="inputSection">
+
+<legend><?php echo __('Do a "query by example" (wildcard: "%") for two different columns') ?></legend>
+<table class="data">
+<?php echo PMA_tbl_setTableHeader();?>
+<tbody>
+<?php
+    $odd_row = true;
+   
+for($i = 0 ; $i < 4 ; $i++){
+    
+    if($i == 2){
+	echo "<tr><td>";
+        echo __("Additional search criteria");
+	echo "</td><tr>";
+    }               
+
+?>
+    <tr class="noclick <?php echo $odd_row ? 'odd' : 'even'; $odd_row = ! $odd_row; ?>">
+        <th><select name="inputs[]" id=<?php echo 'tableid_' . $i?> >
+        <option value= <?php echo __('pma_null')?>><?php echo __('None');  ?> </option>
+        <?php
+        for ($j = 0 ; $j < $fields_cnt ; $j++){
+            if(isset($inputs[$i]) && $inputs[$i] == htmlspecialchars($fields_list[$j])){?>
+                <option value=<?php echo htmlspecialchars($fields_list[$j]);?> Selected>  <?php echo htmlspecialchars($fields_list[$j]);?></option>
+        <?php
+            }
+            else{ ?>
+                <option value=<?php echo htmlspecialchars($fields_list[$j]);?> >  <?php echo htmlspecialchars($fields_list[$j]);?></option>
+        <?php
+            }
+        } ?>
+        </select></th>
+        <td><?php if(isset($tbl_fields_type[$i]))echo $tbl_fields_type[$i]; ?></td>
+        <td><?php if(isset($tbl_fields_collation[$i]))echo $tbl_fields_collation[$i]; ?></td>
+	
+	<td>
+	<?php if(isset($inputs) && $inputs[$i] != __('pma_null')){ ?>
+	    <select name="zoomFunc[]">
+            <?php
+
+	        if (strncasecmp($tbl_fields_type[$i], 'enum', 4) == 0) {
+	            foreach ($GLOBALS['cfg']['EnumOperators'] as $fc) {
+			if(isset($zoomFunc[$i]) && $zoomFunc[$i] == htmlspecialchars($fc)){
+		            echo "\n" . '                        '
+		            . '<option value="' . htmlspecialchars($fc) . '" Selected>'
+		            . htmlspecialchars($fc) . '</option>';
+			}
+			else {
+		            echo "\n" . '                        '
+		            . '<option value="' . htmlspecialchars($fc) . '">'
+		            . htmlspecialchars($fc) . '</option>';
+			}
+		    }
+	        } elseif (preg_match('@char|blob|text|set at i', $tbl_fields_type[$i])) {
+	            foreach ($GLOBALS['cfg']['TextOperators'] as $fc) {
+			if(isset($zoomFunc[$i]) && $zoomFunc[$i] == $fc){
+		            echo "\n" . '                        '
+		            . '<option value="' . htmlspecialchars($fc) . '" Selected>'
+		            . htmlspecialchars($fc) . '</option>';
+			}
+			else {
+		            echo "\n" . '                        '
+		            . '<option value="' . htmlspecialchars($fc) . '">'
+		            . htmlspecialchars($fc) . '</option>';
+			}
+		    }
+	    	} else {
+	            foreach ($GLOBALS['cfg']['NumOperators'] as $fc) {
+			if(isset($zoomFunc[$i]) && $zoomFunc[$i] == $fc){
+		            echo "\n" . '                        '
+		    	    . '<option value="' .  htmlspecialchars($fc) . '" Selected>'
+		    	    . htmlspecialchars($fc) . '</option>';
+			}
+			else {
+		            echo "\n" . '                        '
+		    	    . '<option value="' .  htmlspecialchars($fc) . '">'
+		    	    . htmlspecialchars($fc) . '</option>';
+			}
+		    }
+	        } // end if... else...
+	    
+                if ($tbl_fields_null[$i]) {
+	            foreach ($GLOBALS['cfg']['NullOperators'] as $fc) {
+			if(isset($zoomFunc[$i]) && $zoomFunc[$i] == $fc){
+		            echo "\n" . '                        '
+		    	    . '<option value="' .  htmlspecialchars($fc) . '" Selected>'
+		    	    . htmlspecialchars($fc) . '</option>';
+			}
+			else {
+		            echo "\n" . '                        '
+		    	    . '<option value="' .  htmlspecialchars($fc) . '">'
+		    	    . htmlspecialchars($fc) . '</option>';
+			}
+	            }
+	        }
+            ?>
+            </select>
+            </td>
+            <td>
+	    <?php
+	    $field = $inputs[$i];
+	
+            $foreignData = PMA_getForeignData($foreigners, $field, false, '', '');
+	    if (isset($fields))
+	        echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i ,$db, $table, $titles, $GLOBALS['cfg']['ForeignKeyMaxLimit'], $fields);
+	    else
+	        echo PMA_getForeignFields_Values($foreigners, $foreignData, $field, $tbl_fields_type, $i ,$db, $table, $titles, $GLOBALS['cfg']['ForeignKeyMaxLimit'], '');
+	
+        }
+        else{ ?>
+ 
+       </td><td></td>
+
+        <?php } ?>
+
+        </td>
+    </tr>
+
+    <input type="hidden" name="types[<?php echo $i; ?>]" id="types_<?php echo $i; ?>"
+        value="<?php if(isset($tbl_fields_type[$i]))echo $tbl_fields_type[$i]; ?>" />
+    <input type="hidden" name="collations[<?php echo $i; ?>]"
+        value="<?php if(isset($tbl_fields_collation[$i]))echo $tbl_fields_collation[$i]; ?>" />
+
+
+
+<?php
+    }//end for
+?>
+    </table>
+
+    <?php
+    /*
+     * Other inputs like data label and mode go after selection of column criteria
+     */
+
+    //Set default datalabel if not selected
+    if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_null')) {
+        if ($dataLabel == '') 
+	    $dataLabel = PMA_getDisplayField($db,$table);
+    }
+    ?>
+    <table class="data">
+    <tr><td><label for="label"><?php echo __("Data Label"); ?></label>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</td>
+    <td><select name="dataLabel" id='dataLabel' >
+        <option value = ''> <?php echo __('None');  ?> </option>
+        <?php
+        for ($j = 0 ; $j < $fields_cnt ; $j++){
+            if(isset($dataLabel) && $dataLabel == htmlspecialchars($fields_list[$j])){?>
+                <option value=<?php echo htmlspecialchars($fields_list[$j]);?> Selected>  <?php echo htmlspecialchars($fields_list[$j]);?></option>
+        <?php
+            }
+            else{ ?>
+                <option value=<?php echo htmlspecialchars($fields_list[$j]);?> >  <?php echo htmlspecialchars($fields_list[$j]);?></option>
+        <?php
+            }
+        } ?>
+    </select>
+    </td></tr>
+    <tr><td><label for="label"><?php echo __("Maximum rows to plot"); ?></label></td>
+    <td>
+    <?php if(isset($maxPlotLimit)) { ?>
+        <input type="text" name="maxPlotLimit" value="<?php echo $maxPlotLimit; ?>" /></td></tr>
+    <?php
+      }
+      else { ?>
+	<input type="text" name="maxPlotLimit" value="<?php echo $GLOBALS['cfg']['maxRowPlotLimit']; ?>" /></td></tr>
+    <?php
+	} ?> 
+    </table>
+
+</fieldset>
+<fieldset class="tblFooters">
+    <input type="hidden" name="max_number_of_fields"
+        value="<?php echo $fields_cnt; ?>" />
+    <input type="submit" name="zoom_submit" id="inputFormSubmitId" value="<?php echo __('Go'); ?>" />
+</fieldset>
+</form>
+
+<?php 
+
+/*
+ * Handle the input criteria and gerate the query result
+ * Form for displaying query results
+ */
+if(isset($zoom_submit) && $inputs[0] != __('pma_null') && $inputs[1] != __('pma_null') && $inputs[0] != $inputs[1]) {
+
+    /*
+     * Query generation part
+     */
+    $w = $data = array(); 
+    $sql_query = 'SELECT *';
+
+    //Add the table
+	
+    $sql_query .= ' FROM ' . PMA_backquote($table);
+    for($i = 0 ; $i < 4 ; $i++){
+        if($inputs[$i] == __('pma_null'))
+	    continue;
+        $tmp = array();
+        // The where clause
+        $charsets = array();
+        $cnt_func = count($zoomFunc[$i]);
+        $func_type = $zoomFunc[$i];
+        list($charsets[$i]) = explode('_', $collations[$i]);
+        $unaryFlag =  (isset($GLOBALS['cfg']['UnaryOperators'][$func_type]) && $GLOBALS['cfg']['UnaryOperators'][$func_type] == 1) ? true : false;
+        $whereClause = PMA_tbl_search_getWhereClause($fields[$i],$inputs[$i], $types[$i], $collations[$i], $func_type, $unaryFlag);
+        if($whereClause)
+                $w[] = $whereClause;
+
+        } // end for
+        if ($w) {
+            $sql_query .= ' WHERE ' . implode(' AND ', $w);
+        }
+	$sql_query .= ' LIMIT ' . $maxPlotLimit;
+
+    /*
+     * Query execution part
+     */
+    $result     = PMA_DBI_query( $sql_query . ";" , null, PMA_DBI_QUERY_STORE);
+    $fields_meta = PMA_DBI_get_fields_meta($result);
+    while ($row = PMA_DBI_fetch_assoc($result)) {
+        //Need a row with indexes as 0,1,2 for the PMA_getUniqueCondition hence using a temporary array
+	$tmpRow = array();
+	foreach($row as $val)
+	    $tmpRow[] = $val;
+        //Get unique conditon on each row (will be needed for row update)
+	$uniqueCondition = PMA_getUniqueCondition($result, $fields_cnt, $fields_meta, $tmpRow, true);
+
+	//Append it to row array as where_clause
+	$row['where_clause'] = $uniqueCondition[0];
+	if($dataLabel == $inputs[0] || $dataLabel == $inputs[1])
+            $data[] = array($inputs[0] => $row[$inputs[0]], $inputs[1] => $row[$inputs[1]], 'where_clause' => $uniqueCondition[0]);
+	else
+            $data[] = array($inputs[0] => $row[$inputs[0]], $inputs[1] => $row[$inputs[1]], $dataLabel => $row[$dataLabel], 'where_clause' => $uniqueCondition[0]);
+    }	
+
+?>
+
+<?php
+    /*
+     * Form for displaying point data and also the scatter plot
+     */
+?>   
+    <form method="post" action="tbl_zoom_select.php" name="displayResultForm" id="zoom_display_form" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? ' class="ajax"' : ''); ?>>
+    <?php echo PMA_generate_common_hidden_inputs($db, $table); ?>
+    <input type="hidden" name="goto" value="<?php echo $goto; ?>" />
+    <input type="hidden" name="back" value="tbl_zoom_select.php" />
+
+    <fieldset id="displaySection">
+        <legend><?php echo __('Browse/Edit the points') ?></legend>
+	<center>
+        <?php
+            //JSON encode the data(query result)
+            if(isset($zoom_submit) && !empty($data)){ ?>
+                <div id='resizer' style="width:600px;height:400px">
+	        <?php if (isset($data)) ?><center> <a href="#" onClick="displayHelp();"><?php echo __('How to use'); ?></a> </center>
+                <div id="querydata" style="display:none">
+                    <?php if(isset($data)) echo json_encode($data); ?>
+                </div>
+	        <div id="querychart" style="float:right"></div>
+                </div>
+                <?php 
+	    } ?>
+        </center>
+    <fieldset id='dataDisplay' style="display:none">
+        <fieldset>
+        <table class="data">
+            <thead>
+                <tr>
+		<th> <?php echo __('Column'); ?> </th>
+		<th> <?php echo __('Null'); ?> </th>
+                <th> <?php echo __('Value'); ?> </th>
+		</tr>
+            </thead>
+            <tbody>
+            <?php
+                $odd_row = true;
+        	for ($i = 4; $i < $fields_cnt + 4 ; $i++) {
+            	    $tbl_fields_type[$i] = $fields_type[$i - 4];
+            	    $fieldpopup = $fields_list[$i - 4];
+            	    $foreignData = PMA_getForeignData($foreigners, $fieldpopup, false, '', '');
+                    ?>
+                    <tr class="noclick <?php echo $odd_row ? 'odd' : 'even'; $odd_row = ! $odd_row; ?>">
+                        <th><?php echo htmlspecialchars($fields_list[$i - 4]); ?></th>
+		    	<th><?php echo '<input type="checkbox" class="checkbox_null" name="fields_null[ ' . $i . ' ]" id="fields_null_id_' . $i . '" />'; ?></th>
+                        <th><?php echo PMA_getForeignFields_Values($foreigners, $foreignData, $fieldpopup, $tbl_fields_type, $i, $db, $table, $titles,$GLOBALS['cfg']['ForeignKeyMaxLimit'], '' ); ?> </th>
+                    </tr>
+                    <?php 
+		} ?>
+            </tbody>
+        </table>
+        </fieldset>
+        <fieldset class="tblFooters">
+            <input type="submit" id="submitForm" name="edit_point" value="<?php echo __('Submit'); ?>" />
+        </fieldset>
+    </fieldset>
+
+    </fieldset>
+    <input type="hidden" id="queryID" name="sql_query" />
+    </form>
+    </fieldset>
+    <?php 
+}
+?>
+
+    <?php
+    require './libraries/footer.inc.php';
+?>


hooks/post-receive
-- 
phpMyAdmin




More information about the Git mailing list