postrunner 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -3
- data/lib/postrunner/ActivitiesDB.rb +8 -9
- data/lib/postrunner/Activity.rb +7 -1
- data/lib/postrunner/ActivityView.rb +10 -2
- data/lib/postrunner/DataSources.rb +100 -0
- data/lib/postrunner/DeviceList.rb +40 -17
- data/lib/postrunner/Log.rb +25 -0
- data/lib/postrunner/Main.rb +9 -8
- data/lib/postrunner/RuntimeConfig.rb +1 -0
- data/lib/postrunner/TrackView.rb +39 -62
- data/lib/postrunner/version.rb +1 -1
- data/misc/openlayers/ol.css +1 -0
- data/misc/openlayers/ol.js +948 -0
- data/postrunner.gemspec +2 -2
- data/spec/PostRunner_spec.rb +22 -23
- data/spec/spec_helper.rb +34 -4
- metadata +11 -1214
- data/misc/openlayers/.gitignore +0 -7
- data/misc/openlayers/OpenLayers.debug.js +0 -85622
- data/misc/openlayers/OpenLayers.js +0 -1443
- data/misc/openlayers/OpenLayers.light.debug.js +0 -37230
- data/misc/openlayers/OpenLayers.light.js +0 -592
- data/misc/openlayers/OpenLayers.mobile.debug.js +0 -41831
- data/misc/openlayers/OpenLayers.mobile.js +0 -681
- data/misc/openlayers/apidoc_config/Languages.txt +0 -113
- data/misc/openlayers/apidoc_config/Menu.txt +0 -520
- data/misc/openlayers/apidoc_config/OL.css +0 -20
- data/misc/openlayers/apidoc_config/Topics.txt +0 -105
- data/misc/openlayers/art/arrows.svg +0 -127
- data/misc/openlayers/art/layer-switcher-maximize.svg +0 -128
- data/misc/openlayers/art/layer-switcher-minimize.svg +0 -142
- data/misc/openlayers/art/marker.svg +0 -25
- data/misc/openlayers/art/measuring-stick-off.svg +0 -36
- data/misc/openlayers/art/measuring-stick-on.svg +0 -36
- data/misc/openlayers/art/panning-hand-off.svg +0 -44
- data/misc/openlayers/art/panning-hand-on.svg +0 -44
- data/misc/openlayers/art/slider.svg +0 -71
- data/misc/openlayers/art/zoom-world.svg +0 -193
- data/misc/openlayers/art/zoombar.svg +0 -73
- data/misc/openlayers/authors.txt +0 -56
- data/misc/openlayers/build/README.txt +0 -46
- data/misc/openlayers/build/build.py +0 -158
- data/misc/openlayers/build/buildUncompressed.py +0 -25
- data/misc/openlayers/build/closure-compiler/Externs.js +0 -50
- data/misc/openlayers/build/full.cfg +0 -14
- data/misc/openlayers/build/license.txt +0 -57
- data/misc/openlayers/build/light.cfg +0 -32
- data/misc/openlayers/build/lite.cfg +0 -17
- data/misc/openlayers/build/mobile.cfg +0 -36
- data/misc/openlayers/build/tests.cfg +0 -11
- data/misc/openlayers/doc_config/Data/ClassHierarchy.nd +0 -0
- data/misc/openlayers/doc_config/Data/ConfigFileInfo.nd +0 -0
- data/misc/openlayers/doc_config/Data/FileInfo.nd +0 -323
- data/misc/openlayers/doc_config/Data/ImageFileInfo.nd +0 -0
- data/misc/openlayers/doc_config/Data/ImageReferenceTable.nd +0 -0
- data/misc/openlayers/doc_config/Data/IndexInfo.nd +0 -0
- data/misc/openlayers/doc_config/Data/PreviousMenuState.nd +0 -0
- data/misc/openlayers/doc_config/Data/PreviousSettings.nd +0 -0
- data/misc/openlayers/doc_config/Data/SymbolTable.nd +0 -0
- data/misc/openlayers/doc_config/Languages.txt +0 -113
- data/misc/openlayers/doc_config/Menu.txt +0 -520
- data/misc/openlayers/doc_config/OL.css +0 -20
- data/misc/openlayers/doc_config/Topics.txt +0 -102
- data/misc/openlayers/examples/Jugl.js +0 -8
- data/misc/openlayers/examples/KMLParser.html +0 -57
- data/misc/openlayers/examples/SLDSelect.html +0 -202
- data/misc/openlayers/examples/WMSDescribeLayerParser.html +0 -52
- data/misc/openlayers/examples/accelerometer.html +0 -100
- data/misc/openlayers/examples/accessible-click-control.html +0 -69
- data/misc/openlayers/examples/accessible-click-control.js +0 -199
- data/misc/openlayers/examples/accessible-panel.html +0 -130
- data/misc/openlayers/examples/accessible-panel.js +0 -64
- data/misc/openlayers/examples/accessible.html +0 -167
- data/misc/openlayers/examples/all-overlays-google.html +0 -34
- data/misc/openlayers/examples/all-overlays-google.js +0 -19
- data/misc/openlayers/examples/all-overlays.html +0 -76
- data/misc/openlayers/examples/anchor-permalink.html +0 -29
- data/misc/openlayers/examples/anchor-permalink.js +0 -13
- data/misc/openlayers/examples/animated_panning.html +0 -98
- data/misc/openlayers/examples/animator.js +0 -670
- data/misc/openlayers/examples/arcgis93rest.html +0 -69
- data/misc/openlayers/examples/arcgiscache_ags.html +0 -221
- data/misc/openlayers/examples/arcgiscache_direct.html +0 -108
- data/misc/openlayers/examples/arcgiscache_jsonp.html +0 -106
- data/misc/openlayers/examples/arcims-thematic.html +0 -82
- data/misc/openlayers/examples/arcims.html +0 -57
- data/misc/openlayers/examples/attribution.html +0 -60
- data/misc/openlayers/examples/behavior-fixed-http-gml.html +0 -56
- data/misc/openlayers/examples/bing-tiles-restrictedzoom.html +0 -43
- data/misc/openlayers/examples/bing-tiles-restrictedzoom.js +0 -37
- data/misc/openlayers/examples/bing-tiles.html +0 -39
- data/misc/openlayers/examples/bing-tiles.js +0 -31
- data/misc/openlayers/examples/bing.html +0 -64
- data/misc/openlayers/examples/bootstrap.html +0 -81
- data/misc/openlayers/examples/bootstrap.js +0 -31
- data/misc/openlayers/examples/boxes-vector.html +0 -59
- data/misc/openlayers/examples/boxes.html +0 -58
- data/misc/openlayers/examples/browser.html +0 -152
- data/misc/openlayers/examples/browser.js +0 -241
- data/misc/openlayers/examples/buffer.html +0 -54
- data/misc/openlayers/examples/cache-read.html +0 -36
- data/misc/openlayers/examples/cache-read.js +0 -36
- data/misc/openlayers/examples/cache-write.html +0 -37
- data/misc/openlayers/examples/cache-write.js +0 -46
- data/misc/openlayers/examples/canvas-hit-detection.html +0 -31
- data/misc/openlayers/examples/canvas-hit-detection.js +0 -88
- data/misc/openlayers/examples/canvas-inspector.html +0 -53
- data/misc/openlayers/examples/canvas-inspector.js +0 -91
- data/misc/openlayers/examples/canvas.html +0 -35
- data/misc/openlayers/examples/canvas.js +0 -57
- data/misc/openlayers/examples/cartodb-geojson.html +0 -71
- data/misc/openlayers/examples/click-handler.html +0 -232
- data/misc/openlayers/examples/click.html +0 -91
- data/misc/openlayers/examples/clientzoom.html +0 -72
- data/misc/openlayers/examples/clientzoom.js +0 -39
- data/misc/openlayers/examples/controls.html +0 -86
- data/misc/openlayers/examples/cql-format.html +0 -54
- data/misc/openlayers/examples/cql-format.js +0 -61
- data/misc/openlayers/examples/cross-origin-xml.html +0 -32
- data/misc/openlayers/examples/cross-origin-xml.js +0 -25
- data/misc/openlayers/examples/cross-origin.html +0 -36
- data/misc/openlayers/examples/cross-origin.js +0 -39
- data/misc/openlayers/examples/custom-control.html +0 -68
- data/misc/openlayers/examples/custom-style.html +0 -66
- data/misc/openlayers/examples/data/4_m_citylights_lg.gif +0 -0
- data/misc/openlayers/examples/data/line.json +0 -10
- data/misc/openlayers/examples/data/point.json +0 -8
- data/misc/openlayers/examples/data/poly.json +0 -9
- data/misc/openlayers/examples/data/roads.json +0 -349
- data/misc/openlayers/examples/data/tazdem.tiff +0 -0
- data/misc/openlayers/examples/debug.html +0 -77
- data/misc/openlayers/examples/document-drag.html +0 -43
- data/misc/openlayers/examples/donut.html +0 -62
- data/misc/openlayers/examples/donut.js +0 -44
- data/misc/openlayers/examples/drag-feature.html +0 -114
- data/misc/openlayers/examples/draw-feature.html +0 -143
- data/misc/openlayers/examples/draw-undo-redo.html +0 -38
- data/misc/openlayers/examples/draw-undo-redo.js +0 -45
- data/misc/openlayers/examples/dynamic-text-layer.html +0 -101
- data/misc/openlayers/examples/editing-methods.html +0 -58
- data/misc/openlayers/examples/editing-methods.js +0 -83
- data/misc/openlayers/examples/editingtoolbar-outside.html +0 -56
- data/misc/openlayers/examples/editingtoolbar.html +0 -55
- data/misc/openlayers/examples/encoded-polyline.html +0 -47
- data/misc/openlayers/examples/events.html +0 -155
- data/misc/openlayers/examples/example-list.html +0 -302
- data/misc/openlayers/examples/example.html +0 -25
- data/misc/openlayers/examples/example.js +0 -23
- data/misc/openlayers/examples/feature-events.html +0 -46
- data/misc/openlayers/examples/feature-events.js +0 -67
- data/misc/openlayers/examples/filter-strategy.html +0 -54
- data/misc/openlayers/examples/filter-strategy.js +0 -84
- data/misc/openlayers/examples/filter.html +0 -107
- data/misc/openlayers/examples/fractional-zoom.html +0 -72
- data/misc/openlayers/examples/fullScreen.html +0 -53
- data/misc/openlayers/examples/fullScreen.js +0 -20
- data/misc/openlayers/examples/fusiontables.html +0 -35
- data/misc/openlayers/examples/fusiontables.js +0 -51
- data/misc/openlayers/examples/game-accel-ball.html +0 -82
- data/misc/openlayers/examples/geojson-reprojected.html +0 -46
- data/misc/openlayers/examples/geojson-reprojected.js +0 -27
- data/misc/openlayers/examples/geojson-reprojected.json +0 -1
- data/misc/openlayers/examples/geojson.html +0 -77
- data/misc/openlayers/examples/geolocation.html +0 -41
- data/misc/openlayers/examples/geolocation.js +0 -112
- data/misc/openlayers/examples/georss-flickr.html +0 -119
- data/misc/openlayers/examples/georss-markers.html +0 -45
- data/misc/openlayers/examples/georss.html +0 -63
- data/misc/openlayers/examples/georss.xml +0 -378
- data/misc/openlayers/examples/getfeature-wfs.html +0 -84
- data/misc/openlayers/examples/getfeatureinfo-control.html +0 -221
- data/misc/openlayers/examples/getfeatureinfo-popup.html +0 -96
- data/misc/openlayers/examples/gml-layer.html +0 -48
- data/misc/openlayers/examples/gml/line.xml +0 -42
- data/misc/openlayers/examples/gml/multipoint.xml +0 -70
- data/misc/openlayers/examples/gml/multipolygon.xml +0 -106
- data/misc/openlayers/examples/gml/owls.xml +0 -156
- data/misc/openlayers/examples/gml/point.xml +0 -42
- data/misc/openlayers/examples/gml/polygon.xml +0 -89
- data/misc/openlayers/examples/google-static.html +0 -39
- data/misc/openlayers/examples/google-static.js +0 -61
- data/misc/openlayers/examples/google-v3-alloverlays.html +0 -33
- data/misc/openlayers/examples/google-v3-alloverlays.js +0 -35
- data/misc/openlayers/examples/google-v3.html +0 -35
- data/misc/openlayers/examples/google-v3.js +0 -39
- data/misc/openlayers/examples/google.html +0 -69
- data/misc/openlayers/examples/graphic-name.html +0 -42
- data/misc/openlayers/examples/graphic-name.js +0 -67
- data/misc/openlayers/examples/graticule.html +0 -116
- data/misc/openlayers/examples/gutter.html +0 -55
- data/misc/openlayers/examples/highlight-feature.html +0 -88
- data/misc/openlayers/examples/hover-handler.html +0 -216
- data/misc/openlayers/examples/image-layer.html +0 -76
- data/misc/openlayers/examples/img/check-round-green.png +0 -0
- data/misc/openlayers/examples/img/check-round-grey.png +0 -0
- data/misc/openlayers/examples/img/list.png +0 -0
- data/misc/openlayers/examples/img/locate.png +0 -0
- data/misc/openlayers/examples/img/marker_shadow.png +0 -0
- data/misc/openlayers/examples/img/minus1.png +0 -0
- data/misc/openlayers/examples/img/mobile-layers.png +0 -0
- data/misc/openlayers/examples/img/mobile-loc.png +0 -0
- data/misc/openlayers/examples/img/mobile-zoombar.png +0 -0
- data/misc/openlayers/examples/img/openlayers.png +0 -0
- data/misc/openlayers/examples/img/popupMatrix.jpg +0 -0
- data/misc/openlayers/examples/img/small.jpg +0 -0
- data/misc/openlayers/examples/img/thinlong.jpg +0 -0
- data/misc/openlayers/examples/img/widelong.jpg +0 -0
- data/misc/openlayers/examples/img/wideshort.jpg +0 -0
- data/misc/openlayers/examples/intersects.html +0 -193
- data/misc/openlayers/examples/kamap.html +0 -45
- data/misc/openlayers/examples/kamap.txt +0 -508
- data/misc/openlayers/examples/kinetic.html +0 -44
- data/misc/openlayers/examples/kinetic.js +0 -27
- data/misc/openlayers/examples/kml-layer.html +0 -36
- data/misc/openlayers/examples/kml-layer.js +0 -22
- data/misc/openlayers/examples/kml-pointtrack.html +0 -40
- data/misc/openlayers/examples/kml-pointtrack.js +0 -52
- data/misc/openlayers/examples/kml-track.html +0 -42
- data/misc/openlayers/examples/kml-track.js +0 -40
- data/misc/openlayers/examples/kml-track.kml +0 -3359
- data/misc/openlayers/examples/kml/lines.kml +0 -275
- data/misc/openlayers/examples/kml/styles.kml +0 -21
- data/misc/openlayers/examples/kml/sundials.kml +0 -2273
- data/misc/openlayers/examples/label-scale.html +0 -34
- data/misc/openlayers/examples/label-scale.js +0 -72
- data/misc/openlayers/examples/late-render.html +0 -48
- data/misc/openlayers/examples/layer-opacity.html +0 -95
- data/misc/openlayers/examples/layerLoadMonitoring.html +0 -135
- data/misc/openlayers/examples/layerswitcher.html +0 -60
- data/misc/openlayers/examples/light-basic.html +0 -35
- data/misc/openlayers/examples/light-basic.js +0 -67
- data/misc/openlayers/examples/lite.html +0 -39
- data/misc/openlayers/examples/mapbox.html +0 -30
- data/misc/openlayers/examples/mapbox.js +0 -21
- data/misc/openlayers/examples/mapguide.html +0 -155
- data/misc/openlayers/examples/mapquest.html +0 -28
- data/misc/openlayers/examples/mapquest.js +0 -36
- data/misc/openlayers/examples/mapserver.html +0 -41
- data/misc/openlayers/examples/mapserver_untiled.html +0 -43
- data/misc/openlayers/examples/marker-shadow.html +0 -152
- data/misc/openlayers/examples/markerResize.html +0 -60
- data/misc/openlayers/examples/markers.html +0 -59
- data/misc/openlayers/examples/markersTextLayer.html +0 -41
- data/misc/openlayers/examples/measure.html +0 -203
- data/misc/openlayers/examples/mobile-base.js +0 -167
- data/misc/openlayers/examples/mobile-drawing.html +0 -52
- data/misc/openlayers/examples/mobile-drawing.js +0 -71
- data/misc/openlayers/examples/mobile-jq.html +0 -76
- data/misc/openlayers/examples/mobile-jq.js +0 -159
- data/misc/openlayers/examples/mobile-layers.html +0 -62
- data/misc/openlayers/examples/mobile-layers.js +0 -71
- data/misc/openlayers/examples/mobile-navigation.html +0 -52
- data/misc/openlayers/examples/mobile-navigation.js +0 -24
- data/misc/openlayers/examples/mobile-sencha.html +0 -184
- data/misc/openlayers/examples/mobile-sencha.js +0 -198
- data/misc/openlayers/examples/mobile-wmts-vienna.css +0 -205
- data/misc/openlayers/examples/mobile-wmts-vienna.html +0 -27
- data/misc/openlayers/examples/mobile-wmts-vienna.js +0 -281
- data/misc/openlayers/examples/mobile.html +0 -56
- data/misc/openlayers/examples/mobile.js +0 -39
- data/misc/openlayers/examples/modify-feature.html +0 -193
- data/misc/openlayers/examples/mouse-position.html +0 -67
- data/misc/openlayers/examples/mousewheel-interval.html +0 -63
- data/misc/openlayers/examples/multiserver.html +0 -52
- data/misc/openlayers/examples/multitouch.html +0 -28
- data/misc/openlayers/examples/mvs.html +0 -129
- data/misc/openlayers/examples/navigation-control.html +0 -44
- data/misc/openlayers/examples/navigation-history.html +0 -62
- data/misc/openlayers/examples/navtoolbar-alwaysZoom.html +0 -85
- data/misc/openlayers/examples/navtoolbar-outsidemap.html +0 -47
- data/misc/openlayers/examples/navtoolbar.html +0 -46
- data/misc/openlayers/examples/offline-storage.html +0 -44
- data/misc/openlayers/examples/offline-storage.js +0 -199
- data/misc/openlayers/examples/openls.html +0 -88
- data/misc/openlayers/examples/ordering.html +0 -221
- data/misc/openlayers/examples/osm-google.html +0 -32
- data/misc/openlayers/examples/osm-google.js +0 -23
- data/misc/openlayers/examples/osm-grayscale.html +0 -77
- data/misc/openlayers/examples/osm-marker-popup.html +0 -32
- data/misc/openlayers/examples/osm-marker-popup.js +0 -39
- data/misc/openlayers/examples/osm.html +0 -41
- data/misc/openlayers/examples/osm/sutton_coldfield.osm +0 -662
- data/misc/openlayers/examples/overviewmap.html +0 -120
- data/misc/openlayers/examples/pan-zoom-panels.html +0 -97
- data/misc/openlayers/examples/panel.html +0 -99
- data/misc/openlayers/examples/point-grid.html +0 -75
- data/misc/openlayers/examples/point-grid.js +0 -33
- data/misc/openlayers/examples/point-track-markers.html +0 -72
- data/misc/openlayers/examples/polar-projections.html +0 -41
- data/misc/openlayers/examples/polar-projections.js +0 -84
- data/misc/openlayers/examples/popupMatrix.html +0 -652
- data/misc/openlayers/examples/proxy.cgi +0 -81
- data/misc/openlayers/examples/regular-polygons.html +0 -177
- data/misc/openlayers/examples/resize-features.html +0 -101
- data/misc/openlayers/examples/restricted-extent.html +0 -77
- data/misc/openlayers/examples/rotate-features.html +0 -113
- data/misc/openlayers/examples/select-feature-multilayer.html +0 -129
- data/misc/openlayers/examples/select-feature-openpopup.html +0 -106
- data/misc/openlayers/examples/select-feature.html +0 -170
- data/misc/openlayers/examples/setextent.html +0 -39
- data/misc/openlayers/examples/simplify-linestring.html +0 -103
- data/misc/openlayers/examples/simplify-linestring.js +0 -599
- data/misc/openlayers/examples/single-tile.html +0 -33
- data/misc/openlayers/examples/single-tile.js +0 -20
- data/misc/openlayers/examples/sld-parser.html +0 -70
- data/misc/openlayers/examples/sld.html +0 -31
- data/misc/openlayers/examples/sld.js +0 -102
- data/misc/openlayers/examples/snap-grid.html +0 -78
- data/misc/openlayers/examples/snap-grid.js +0 -81
- data/misc/openlayers/examples/snap-split.html +0 -281
- data/misc/openlayers/examples/snapping.html +0 -324
- data/misc/openlayers/examples/sos.html +0 -189
- data/misc/openlayers/examples/spherical-mercator.html +0 -120
- data/misc/openlayers/examples/split-feature.html +0 -116
- data/misc/openlayers/examples/strategy-bbox.html +0 -106
- data/misc/openlayers/examples/strategy-cluster-extended.html +0 -125
- data/misc/openlayers/examples/strategy-cluster-extended.js +0 -247
- data/misc/openlayers/examples/strategy-cluster-threshold.html +0 -149
- data/misc/openlayers/examples/strategy-cluster.html +0 -238
- data/misc/openlayers/examples/strategy-paging.html +0 -115
- data/misc/openlayers/examples/style-rules.html +0 -49
- data/misc/openlayers/examples/style-rules.js +0 -99
- data/misc/openlayers/examples/style.css +0 -143
- data/misc/openlayers/examples/style.mobile-jq.css +0 -62
- data/misc/openlayers/examples/stylemap.html +0 -100
- data/misc/openlayers/examples/styles-context.html +0 -117
- data/misc/openlayers/examples/styles-rotation.html +0 -93
- data/misc/openlayers/examples/styles-unique.html +0 -109
- data/misc/openlayers/examples/sundials-spherical-mercator.html +0 -111
- data/misc/openlayers/examples/sundials.html +0 -107
- data/misc/openlayers/examples/symbolizers-fill-stroke-graphic.html +0 -141
- data/misc/openlayers/examples/tasmania/TasmaniaCities.xml +0 -40
- data/misc/openlayers/examples/tasmania/TasmaniaRoads.xml +0 -204
- data/misc/openlayers/examples/tasmania/TasmaniaStateBoundaries.xml +0 -92
- data/misc/openlayers/examples/tasmania/TasmaniaWaterBodies.xml +0 -162
- data/misc/openlayers/examples/tasmania/sld-tasmania.xml +0 -594
- data/misc/openlayers/examples/teleportation.html +0 -76
- data/misc/openlayers/examples/textfile.txt +0 -4
- data/misc/openlayers/examples/tile-origin.html +0 -38
- data/misc/openlayers/examples/tile-origin.js +0 -16
- data/misc/openlayers/examples/tilecache.html +0 -58
- data/misc/openlayers/examples/tms.html +0 -62
- data/misc/openlayers/examples/transform-feature.html +0 -123
- data/misc/openlayers/examples/transition.html +0 -70
- data/misc/openlayers/examples/using-proj4js.html +0 -109
- data/misc/openlayers/examples/using-proj4js.js +0 -132
- data/misc/openlayers/examples/utfgrid-geography-class.html +0 -51
- data/misc/openlayers/examples/utfgrid-geography-class.js +0 -62
- data/misc/openlayers/examples/utfgrid.html +0 -64
- data/misc/openlayers/examples/utfgrid.js +0 -61
- data/misc/openlayers/examples/utfgrid/bio_utfgrid/1/0/0.json +0 -1
- data/misc/openlayers/examples/utfgrid/bio_utfgrid/1/0/1.json +0 -1
- data/misc/openlayers/examples/utfgrid/bio_utfgrid/1/0/2.json +0 -1
- data/misc/openlayers/examples/utfgrid/bio_utfgrid/1/1/0.json +0 -1
- data/misc/openlayers/examples/utfgrid/bio_utfgrid/1/1/1.json +0 -1
- data/misc/openlayers/examples/utfgrid/bio_utfgrid/1/1/2.json +0 -1
- data/misc/openlayers/examples/utfgrid/bio_utfgrid/1/2/0.json +0 -1
- data/misc/openlayers/examples/utfgrid/bio_utfgrid/1/2/1.json +0 -1
- data/misc/openlayers/examples/utfgrid/bio_utfgrid/1/2/2.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/0/0/0.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/1/0/0.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/1/0/1.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/1/1/0.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/1/1/1.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/0/0.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/0/1.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/0/2.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/0/3.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/1/0.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/1/1.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/1/2.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/1/3.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/2/0.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/2/1.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/2/2.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/2/3.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/3/0.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/3/1.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/3/2.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/geography-class/2/3/3.grid.json +0 -1
- data/misc/openlayers/examples/utfgrid/world_utfgrid/1/0/0.json +0 -1
- data/misc/openlayers/examples/utfgrid/world_utfgrid/1/0/1.json +0 -1
- data/misc/openlayers/examples/utfgrid/world_utfgrid/1/0/2.json +0 -1
- data/misc/openlayers/examples/utfgrid/world_utfgrid/1/1/0.json +0 -1
- data/misc/openlayers/examples/utfgrid/world_utfgrid/1/1/1.json +0 -1
- data/misc/openlayers/examples/utfgrid/world_utfgrid/1/1/2.json +0 -1
- data/misc/openlayers/examples/utfgrid/world_utfgrid/1/2/0.json +0 -1
- data/misc/openlayers/examples/utfgrid/world_utfgrid/1/2/1.json +0 -1
- data/misc/openlayers/examples/utfgrid/world_utfgrid/1/2/2.json +0 -1
- data/misc/openlayers/examples/utfgrid_twogrids.html +0 -51
- data/misc/openlayers/examples/utfgrid_twogrids.js +0 -70
- data/misc/openlayers/examples/vector-features-with-text.html +0 -138
- data/misc/openlayers/examples/vector-features.html +0 -149
- data/misc/openlayers/examples/vector-formats.html +0 -240
- data/misc/openlayers/examples/web-mercator.html +0 -50
- data/misc/openlayers/examples/web-mercator.js +0 -37
- data/misc/openlayers/examples/wfs-filter.html +0 -35
- data/misc/openlayers/examples/wfs-filter.js +0 -48
- data/misc/openlayers/examples/wfs-protocol-transactions.html +0 -104
- data/misc/openlayers/examples/wfs-protocol-transactions.js +0 -106
- data/misc/openlayers/examples/wfs-protocol.html +0 -55
- data/misc/openlayers/examples/wfs-reprojection.html +0 -42
- data/misc/openlayers/examples/wfs-reprojection.js +0 -60
- data/misc/openlayers/examples/wfs-snap-split.html +0 -292
- data/misc/openlayers/examples/wfs-spatial-filter.html +0 -37
- data/misc/openlayers/examples/wfs-spatial-filter.js +0 -36
- data/misc/openlayers/examples/wfs-states.html +0 -34
- data/misc/openlayers/examples/wfs-states.js +0 -35
- data/misc/openlayers/examples/wmc.html +0 -150
- data/misc/openlayers/examples/wms-long-url.html +0 -44
- data/misc/openlayers/examples/wms-long-url.js +0 -26
- data/misc/openlayers/examples/wms-untiled.html +0 -48
- data/misc/openlayers/examples/wms-v13.html +0 -57
- data/misc/openlayers/examples/wms.html +0 -49
- data/misc/openlayers/examples/wmst.html +0 -63
- data/misc/openlayers/examples/wmts-capabilities.html +0 -43
- data/misc/openlayers/examples/wmts-capabilities.js +0 -58
- data/misc/openlayers/examples/wmts-getfeatureinfo.html +0 -74
- data/misc/openlayers/examples/wmts-getfeatureinfo.js +0 -94
- data/misc/openlayers/examples/wmts.html +0 -41
- data/misc/openlayers/examples/wmts.js +0 -35
- data/misc/openlayers/examples/wps-client.html +0 -31
- data/misc/openlayers/examples/wps-client.js +0 -75
- data/misc/openlayers/examples/wps.html +0 -89
- data/misc/openlayers/examples/wps.js +0 -353
- data/misc/openlayers/examples/wrapDateLine.html +0 -73
- data/misc/openlayers/examples/xhtml.html +0 -42
- data/misc/openlayers/examples/xml.html +0 -161
- data/misc/openlayers/examples/xml/features.xml +0 -2
- data/misc/openlayers/examples/xml/georss-flickr.xml +0 -730
- data/misc/openlayers/examples/xml/track1.xml +0 -98
- data/misc/openlayers/examples/xml/wmsdescribelayer.xml +0 -5
- data/misc/openlayers/examples/xyz-esri.html +0 -45
- data/misc/openlayers/examples/yelp-georss.xml +0 -147
- data/misc/openlayers/examples/zoom.html +0 -68
- data/misc/openlayers/examples/zoom.js +0 -34
- data/misc/openlayers/examples/zoomLevels.html +0 -81
- data/misc/openlayers/examples/zoomify.html +0 -70
- data/misc/openlayers/img/blank.gif +0 -0
- data/misc/openlayers/img/cloud-popup-relative.png +0 -0
- data/misc/openlayers/img/drag-rectangle-off.png +0 -0
- data/misc/openlayers/img/drag-rectangle-on.png +0 -0
- data/misc/openlayers/img/east-mini.png +0 -0
- data/misc/openlayers/img/layer-switcher-maximize.png +0 -0
- data/misc/openlayers/img/layer-switcher-minimize.png +0 -0
- data/misc/openlayers/img/marker-blue.png +0 -0
- data/misc/openlayers/img/marker-gold.png +0 -0
- data/misc/openlayers/img/marker-green.png +0 -0
- data/misc/openlayers/img/marker.png +0 -0
- data/misc/openlayers/img/measuring-stick-off.png +0 -0
- data/misc/openlayers/img/measuring-stick-on.png +0 -0
- data/misc/openlayers/img/north-mini.png +0 -0
- data/misc/openlayers/img/panning-hand-off.png +0 -0
- data/misc/openlayers/img/panning-hand-on.png +0 -0
- data/misc/openlayers/img/slider.png +0 -0
- data/misc/openlayers/img/south-mini.png +0 -0
- data/misc/openlayers/img/west-mini.png +0 -0
- data/misc/openlayers/img/zoom-minus-mini.png +0 -0
- data/misc/openlayers/img/zoom-plus-mini.png +0 -0
- data/misc/openlayers/img/zoom-world-mini.png +0 -0
- data/misc/openlayers/img/zoombar.png +0 -0
- data/misc/openlayers/lib/Firebug/errorIcon.png +0 -0
- data/misc/openlayers/lib/Firebug/firebug.css +0 -209
- data/misc/openlayers/lib/Firebug/firebug.html +0 -23
- data/misc/openlayers/lib/Firebug/firebug.js +0 -674
- data/misc/openlayers/lib/Firebug/firebugx.js +0 -10
- data/misc/openlayers/lib/Firebug/infoIcon.png +0 -0
- data/misc/openlayers/lib/Firebug/license.txt +0 -30
- data/misc/openlayers/lib/Firebug/readme.txt +0 -13
- data/misc/openlayers/lib/Firebug/warningIcon.png +0 -0
- data/misc/openlayers/lib/OpenLayers.js +0 -429
- data/misc/openlayers/lib/OpenLayers/Animation.js +0 -102
- data/misc/openlayers/lib/OpenLayers/BaseTypes.js +0 -463
- data/misc/openlayers/lib/OpenLayers/BaseTypes/Bounds.js +0 -837
- data/misc/openlayers/lib/OpenLayers/BaseTypes/Class.js +0 -121
- data/misc/openlayers/lib/OpenLayers/BaseTypes/Date.js +0 -123
- data/misc/openlayers/lib/OpenLayers/BaseTypes/Element.js +0 -189
- data/misc/openlayers/lib/OpenLayers/BaseTypes/LonLat.js +0 -215
- data/misc/openlayers/lib/OpenLayers/BaseTypes/Pixel.js +0 -143
- data/misc/openlayers/lib/OpenLayers/BaseTypes/Size.js +0 -89
- data/misc/openlayers/lib/OpenLayers/Console.js +0 -250
- data/misc/openlayers/lib/OpenLayers/Control.js +0 -371
- data/misc/openlayers/lib/OpenLayers/Control/ArgParser.js +0 -182
- data/misc/openlayers/lib/OpenLayers/Control/Attribution.js +0 -104
- data/misc/openlayers/lib/OpenLayers/Control/Button.js +0 -44
- data/misc/openlayers/lib/OpenLayers/Control/CacheRead.js +0 -156
- data/misc/openlayers/lib/OpenLayers/Control/CacheWrite.js +0 -257
- data/misc/openlayers/lib/OpenLayers/Control/DragFeature.js +0 -366
- data/misc/openlayers/lib/OpenLayers/Control/DragPan.js +0 -156
- data/misc/openlayers/lib/OpenLayers/Control/DrawFeature.js +0 -229
- data/misc/openlayers/lib/OpenLayers/Control/EditingToolbar.js +0 -81
- data/misc/openlayers/lib/OpenLayers/Control/Geolocate.js +0 -192
- data/misc/openlayers/lib/OpenLayers/Control/GetFeature.js +0 -597
- data/misc/openlayers/lib/OpenLayers/Control/Graticule.js +0 -377
- data/misc/openlayers/lib/OpenLayers/Control/KeyboardDefaults.js +0 -142
- data/misc/openlayers/lib/OpenLayers/Control/LayerSwitcher.js +0 -521
- data/misc/openlayers/lib/OpenLayers/Control/Measure.js +0 -379
- data/misc/openlayers/lib/OpenLayers/Control/ModifyFeature.js +0 -835
- data/misc/openlayers/lib/OpenLayers/Control/MousePosition.js +0 -227
- data/misc/openlayers/lib/OpenLayers/Control/NavToolbar.js +0 -57
- data/misc/openlayers/lib/OpenLayers/Control/Navigation.js +0 -345
- data/misc/openlayers/lib/OpenLayers/Control/NavigationHistory.js +0 -423
- data/misc/openlayers/lib/OpenLayers/Control/OverviewMap.js +0 -750
- data/misc/openlayers/lib/OpenLayers/Control/Pan.js +0 -95
- data/misc/openlayers/lib/OpenLayers/Control/PanPanel.js +0 -73
- data/misc/openlayers/lib/OpenLayers/Control/PanZoom.js +0 -233
- data/misc/openlayers/lib/OpenLayers/Control/PanZoomBar.js +0 -408
- data/misc/openlayers/lib/OpenLayers/Control/Panel.js +0 -431
- data/misc/openlayers/lib/OpenLayers/Control/Permalink.js +0 -257
- data/misc/openlayers/lib/OpenLayers/Control/PinchZoom.js +0 -157
- data/misc/openlayers/lib/OpenLayers/Control/SLDSelect.js +0 -567
- data/misc/openlayers/lib/OpenLayers/Control/Scale.js +0 -100
- data/misc/openlayers/lib/OpenLayers/Control/ScaleLine.js +0 -220
- data/misc/openlayers/lib/OpenLayers/Control/SelectFeature.js +0 -643
- data/misc/openlayers/lib/OpenLayers/Control/Snapping.js +0 -560
- data/misc/openlayers/lib/OpenLayers/Control/Split.js +0 -494
- data/misc/openlayers/lib/OpenLayers/Control/TouchNavigation.js +0 -182
- data/misc/openlayers/lib/OpenLayers/Control/TransformFeature.js +0 -624
- data/misc/openlayers/lib/OpenLayers/Control/UTFGrid.js +0 -240
- data/misc/openlayers/lib/OpenLayers/Control/WMSGetFeatureInfo.js +0 -532
- data/misc/openlayers/lib/OpenLayers/Control/WMTSGetFeatureInfo.js +0 -400
- data/misc/openlayers/lib/OpenLayers/Control/Zoom.js +0 -138
- data/misc/openlayers/lib/OpenLayers/Control/ZoomBox.js +0 -129
- data/misc/openlayers/lib/OpenLayers/Control/ZoomIn.js +0 -29
- data/misc/openlayers/lib/OpenLayers/Control/ZoomOut.js +0 -29
- data/misc/openlayers/lib/OpenLayers/Control/ZoomPanel.js +0 -54
- data/misc/openlayers/lib/OpenLayers/Control/ZoomToMaxExtent.js +0 -35
- data/misc/openlayers/lib/OpenLayers/Events.js +0 -1170
- data/misc/openlayers/lib/OpenLayers/Events/buttonclick.js +0 -206
- data/misc/openlayers/lib/OpenLayers/Events/featureclick.js +0 -321
- data/misc/openlayers/lib/OpenLayers/Feature.js +0 -225
- data/misc/openlayers/lib/OpenLayers/Feature/Vector.js +0 -510
- data/misc/openlayers/lib/OpenLayers/Filter.js +0 -87
- data/misc/openlayers/lib/OpenLayers/Filter/Comparison.js +0 -267
- data/misc/openlayers/lib/OpenLayers/Filter/FeatureId.js +0 -87
- data/misc/openlayers/lib/OpenLayers/Filter/Function.js +0 -49
- data/misc/openlayers/lib/OpenLayers/Filter/Logical.js +0 -121
- data/misc/openlayers/lib/OpenLayers/Filter/Spatial.js +0 -122
- data/misc/openlayers/lib/OpenLayers/Format.js +0 -123
- data/misc/openlayers/lib/OpenLayers/Format/ArcXML.js +0 -1028
- data/misc/openlayers/lib/OpenLayers/Format/ArcXML/Features.js +0 -46
- data/misc/openlayers/lib/OpenLayers/Format/Atom.js +0 -712
- data/misc/openlayers/lib/OpenLayers/Format/CQL.js +0 -452
- data/misc/openlayers/lib/OpenLayers/Format/CSWGetDomain.js +0 -34
- data/misc/openlayers/lib/OpenLayers/Format/CSWGetDomain/v2_0_2.js +0 -240
- data/misc/openlayers/lib/OpenLayers/Format/CSWGetRecords.js +0 -34
- data/misc/openlayers/lib/OpenLayers/Format/CSWGetRecords/v2_0_2.js +0 -457
- data/misc/openlayers/lib/OpenLayers/Format/Context.js +0 -334
- data/misc/openlayers/lib/OpenLayers/Format/EncodedPolyline.js +0 -557
- data/misc/openlayers/lib/OpenLayers/Format/Filter.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Format/Filter/v1.js +0 -504
- data/misc/openlayers/lib/OpenLayers/Format/Filter/v1_0_0.js +0 -184
- data/misc/openlayers/lib/OpenLayers/Format/Filter/v1_1_0.js +0 -222
- data/misc/openlayers/lib/OpenLayers/Format/GML.js +0 -923
- data/misc/openlayers/lib/OpenLayers/Format/GML/Base.js +0 -645
- data/misc/openlayers/lib/OpenLayers/Format/GML/v2.js +0 -193
- data/misc/openlayers/lib/OpenLayers/Format/GML/v3.js +0 -477
- data/misc/openlayers/lib/OpenLayers/Format/GPX.js +0 -385
- data/misc/openlayers/lib/OpenLayers/Format/GeoJSON.js +0 -716
- data/misc/openlayers/lib/OpenLayers/Format/GeoRSS.js +0 -409
- data/misc/openlayers/lib/OpenLayers/Format/JSON.js +0 -398
- data/misc/openlayers/lib/OpenLayers/Format/KML.js +0 -1517
- data/misc/openlayers/lib/OpenLayers/Format/OGCExceptionReport.js +0 -108
- data/misc/openlayers/lib/OpenLayers/Format/OSM.js +0 -465
- data/misc/openlayers/lib/OpenLayers/Format/OWSCommon.js +0 -78
- data/misc/openlayers/lib/OpenLayers/Format/OWSCommon/v1.js +0 -318
- data/misc/openlayers/lib/OpenLayers/Format/OWSCommon/v1_0_0.js +0 -62
- data/misc/openlayers/lib/OpenLayers/Format/OWSCommon/v1_1_0.js +0 -116
- data/misc/openlayers/lib/OpenLayers/Format/OWSContext.js +0 -86
- data/misc/openlayers/lib/OpenLayers/Format/OWSContext/v0_3_1.js +0 -595
- data/misc/openlayers/lib/OpenLayers/Format/QueryStringFilter.js +0 -183
- data/misc/openlayers/lib/OpenLayers/Format/SLD.js +0 -81
- data/misc/openlayers/lib/OpenLayers/Format/SLD/v1.js +0 -1309
- data/misc/openlayers/lib/OpenLayers/Format/SLD/v1_0_0.js +0 -46
- data/misc/openlayers/lib/OpenLayers/Format/SLD/v1_0_0_GeoServer.js +0 -149
- data/misc/openlayers/lib/OpenLayers/Format/SOSCapabilities.js +0 -48
- data/misc/openlayers/lib/OpenLayers/Format/SOSCapabilities/v1_0_0.js +0 -158
- data/misc/openlayers/lib/OpenLayers/Format/SOSGetFeatureOfInterest.js +0 -190
- data/misc/openlayers/lib/OpenLayers/Format/SOSGetObservation.js +0 -302
- data/misc/openlayers/lib/OpenLayers/Format/Text.js +0 -151
- data/misc/openlayers/lib/OpenLayers/Format/WCSCapabilities.js +0 -47
- data/misc/openlayers/lib/OpenLayers/Format/WCSCapabilities/v1.js +0 -55
- data/misc/openlayers/lib/OpenLayers/Format/WCSCapabilities/v1_0_0.js +0 -170
- data/misc/openlayers/lib/OpenLayers/Format/WCSCapabilities/v1_1_0.js +0 -109
- data/misc/openlayers/lib/OpenLayers/Format/WCSGetCoverage.js +0 -199
- data/misc/openlayers/lib/OpenLayers/Format/WFS.js +0 -223
- data/misc/openlayers/lib/OpenLayers/Format/WFSCapabilities.js +0 -47
- data/misc/openlayers/lib/OpenLayers/Format/WFSCapabilities/v1.js +0 -129
- data/misc/openlayers/lib/OpenLayers/Format/WFSCapabilities/v1_0_0.js +0 -115
- data/misc/openlayers/lib/OpenLayers/Format/WFSCapabilities/v1_1_0.js +0 -63
- data/misc/openlayers/lib/OpenLayers/Format/WFSDescribeFeatureType.js +0 -234
- data/misc/openlayers/lib/OpenLayers/Format/WFST.js +0 -34
- data/misc/openlayers/lib/OpenLayers/Format/WFST/v1.js +0 -446
- data/misc/openlayers/lib/OpenLayers/Format/WFST/v1_0_0.js +0 -174
- data/misc/openlayers/lib/OpenLayers/Format/WFST/v1_1_0.js +0 -189
- data/misc/openlayers/lib/OpenLayers/Format/WKT.js +0 -392
- data/misc/openlayers/lib/OpenLayers/Format/WMC.js +0 -182
- data/misc/openlayers/lib/OpenLayers/Format/WMC/v1.js +0 -1267
- data/misc/openlayers/lib/OpenLayers/Format/WMC/v1_0_0.js +0 -104
- data/misc/openlayers/lib/OpenLayers/Format/WMC/v1_1_0.js +0 -149
- data/misc/openlayers/lib/OpenLayers/Format/WMSCapabilities.js +0 -56
- data/misc/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1.js +0 -368
- data/misc/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_1.js +0 -122
- data/misc/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_1_0.js +0 -57
- data/misc/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_1_1.js +0 -60
- data/misc/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_1_1_WMSC.js +0 -85
- data/misc/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_3.js +0 -128
- data/misc/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_3_0.js +0 -30
- data/misc/openlayers/lib/OpenLayers/Format/WMSDescribeLayer.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Format/WMSDescribeLayer/v1_1.js +0 -122
- data/misc/openlayers/lib/OpenLayers/Format/WMSGetFeatureInfo.js +0 -296
- data/misc/openlayers/lib/OpenLayers/Format/WMTSCapabilities.js +0 -230
- data/misc/openlayers/lib/OpenLayers/Format/WMTSCapabilities/v1_0_0.js +0 -251
- data/misc/openlayers/lib/OpenLayers/Format/WPSCapabilities.js +0 -48
- data/misc/openlayers/lib/OpenLayers/Format/WPSCapabilities/v1_0_0.js +0 -119
- data/misc/openlayers/lib/OpenLayers/Format/WPSDescribeProcess.js +0 -185
- data/misc/openlayers/lib/OpenLayers/Format/WPSExecute.js +0 -395
- data/misc/openlayers/lib/OpenLayers/Format/XLS.js +0 -68
- data/misc/openlayers/lib/OpenLayers/Format/XLS/v1.js +0 -304
- data/misc/openlayers/lib/OpenLayers/Format/XLS/v1_1_0.js +0 -48
- data/misc/openlayers/lib/OpenLayers/Format/XML.js +0 -897
- data/misc/openlayers/lib/OpenLayers/Format/XML/VersionedOGC.js +0 -212
- data/misc/openlayers/lib/OpenLayers/Geometry.js +0 -500
- data/misc/openlayers/lib/OpenLayers/Geometry/Collection.js +0 -563
- data/misc/openlayers/lib/OpenLayers/Geometry/Curve.js +0 -89
- data/misc/openlayers/lib/OpenLayers/Geometry/LineString.js +0 -646
- data/misc/openlayers/lib/OpenLayers/Geometry/LinearRing.js +0 -433
- data/misc/openlayers/lib/OpenLayers/Geometry/MultiLineString.js +0 -258
- data/misc/openlayers/lib/OpenLayers/Geometry/MultiPoint.js +0 -66
- data/misc/openlayers/lib/OpenLayers/Geometry/MultiPolygon.js +0 -42
- data/misc/openlayers/lib/OpenLayers/Geometry/Point.js +0 -283
- data/misc/openlayers/lib/OpenLayers/Geometry/Polygon.js +0 -255
- data/misc/openlayers/lib/OpenLayers/Handler.js +0 -325
- data/misc/openlayers/lib/OpenLayers/Handler/Box.js +0 -244
- data/misc/openlayers/lib/OpenLayers/Handler/Click.js +0 -505
- data/misc/openlayers/lib/OpenLayers/Handler/Drag.js +0 -547
- data/misc/openlayers/lib/OpenLayers/Handler/Feature.js +0 -434
- data/misc/openlayers/lib/OpenLayers/Handler/Hover.js +0 -180
- data/misc/openlayers/lib/OpenLayers/Handler/Keyboard.js +0 -117
- data/misc/openlayers/lib/OpenLayers/Handler/MouseWheel.js +0 -264
- data/misc/openlayers/lib/OpenLayers/Handler/Path.js +0 -543
- data/misc/openlayers/lib/OpenLayers/Handler/Pinch.js +0 -239
- data/misc/openlayers/lib/OpenLayers/Handler/Point.js +0 -556
- data/misc/openlayers/lib/OpenLayers/Handler/Polygon.js +0 -305
- data/misc/openlayers/lib/OpenLayers/Handler/RegularPolygon.js +0 -429
- data/misc/openlayers/lib/OpenLayers/Icon.js +0 -243
- data/misc/openlayers/lib/OpenLayers/Kinetic.js +0 -178
- data/misc/openlayers/lib/OpenLayers/Lang.js +0 -134
- data/misc/openlayers/lib/OpenLayers/Lang/ar.js +0 -32
- data/misc/openlayers/lib/OpenLayers/Lang/be-tarask.js +0 -54
- data/misc/openlayers/lib/OpenLayers/Lang/bg.js +0 -25
- data/misc/openlayers/lib/OpenLayers/Lang/br.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Lang/ca.js +0 -89
- data/misc/openlayers/lib/OpenLayers/Lang/cs-CZ.js +0 -45
- data/misc/openlayers/lib/OpenLayers/Lang/da-DK.js +0 -80
- data/misc/openlayers/lib/OpenLayers/Lang/de.js +0 -55
- data/misc/openlayers/lib/OpenLayers/Lang/el.js +0 -19
- data/misc/openlayers/lib/OpenLayers/Lang/en-CA.js +0 -21
- data/misc/openlayers/lib/OpenLayers/Lang/en.js +0 -89
- data/misc/openlayers/lib/OpenLayers/Lang/es.js +0 -90
- data/misc/openlayers/lib/OpenLayers/Lang/fi.js +0 -32
- data/misc/openlayers/lib/OpenLayers/Lang/fr.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Lang/fur.js +0 -35
- data/misc/openlayers/lib/OpenLayers/Lang/gl.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Lang/gsw.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Lang/hr.js +0 -37
- data/misc/openlayers/lib/OpenLayers/Lang/hsb.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Lang/hu.js +0 -54
- data/misc/openlayers/lib/OpenLayers/Lang/ia.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Lang/id.js +0 -54
- data/misc/openlayers/lib/OpenLayers/Lang/io.js +0 -19
- data/misc/openlayers/lib/OpenLayers/Lang/is.js +0 -27
- data/misc/openlayers/lib/OpenLayers/Lang/it.js +0 -80
- data/misc/openlayers/lib/OpenLayers/Lang/ja.js +0 -54
- data/misc/openlayers/lib/OpenLayers/Lang/km.js +0 -23
- data/misc/openlayers/lib/OpenLayers/Lang/ksh.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Lang/lt.js +0 -47
- data/misc/openlayers/lib/OpenLayers/Lang/nb.js +0 -82
- data/misc/openlayers/lib/OpenLayers/Lang/nds.js +0 -37
- data/misc/openlayers/lib/OpenLayers/Lang/nl.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Lang/nn.js +0 -19
- data/misc/openlayers/lib/OpenLayers/Lang/oc.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Lang/pl.js +0 -89
- data/misc/openlayers/lib/OpenLayers/Lang/pt-BR.js +0 -54
- data/misc/openlayers/lib/OpenLayers/Lang/pt.js +0 -55
- data/misc/openlayers/lib/OpenLayers/Lang/ro.js +0 -69
- data/misc/openlayers/lib/OpenLayers/Lang/ru.js +0 -56
- data/misc/openlayers/lib/OpenLayers/Lang/sk.js +0 -44
- data/misc/openlayers/lib/OpenLayers/Lang/sv-SE.js +0 -45
- data/misc/openlayers/lib/OpenLayers/Lang/te.js +0 -27
- data/misc/openlayers/lib/OpenLayers/Lang/vi.js +0 -53
- data/misc/openlayers/lib/OpenLayers/Lang/zh-CN.js +0 -80
- data/misc/openlayers/lib/OpenLayers/Lang/zh-TW.js +0 -81
- data/misc/openlayers/lib/OpenLayers/Layer.js +0 -1377
- data/misc/openlayers/lib/OpenLayers/Layer/ArcGIS93Rest.js +0 -225
- data/misc/openlayers/lib/OpenLayers/Layer/ArcGISCache.js +0 -480
- data/misc/openlayers/lib/OpenLayers/Layer/ArcIMS.js +0 -425
- data/misc/openlayers/lib/OpenLayers/Layer/Bing.js +0 -333
- data/misc/openlayers/lib/OpenLayers/Layer/Boxes.js +0 -76
- data/misc/openlayers/lib/OpenLayers/Layer/EventPane.js +0 -441
- data/misc/openlayers/lib/OpenLayers/Layer/FixedZoomLevels.js +0 -319
- data/misc/openlayers/lib/OpenLayers/Layer/GeoRSS.js +0 -265
- data/misc/openlayers/lib/OpenLayers/Layer/Google.js +0 -809
- data/misc/openlayers/lib/OpenLayers/Layer/Google/v3.js +0 -351
- data/misc/openlayers/lib/OpenLayers/Layer/Grid.js +0 -1343
- data/misc/openlayers/lib/OpenLayers/Layer/HTTPRequest.js +0 -230
- data/misc/openlayers/lib/OpenLayers/Layer/Image.js +0 -259
- data/misc/openlayers/lib/OpenLayers/Layer/KaMap.js +0 -192
- data/misc/openlayers/lib/OpenLayers/Layer/KaMapCache.js +0 -143
- data/misc/openlayers/lib/OpenLayers/Layer/MapGuide.js +0 -443
- data/misc/openlayers/lib/OpenLayers/Layer/MapServer.js +0 -181
- data/misc/openlayers/lib/OpenLayers/Layer/Markers.js +0 -187
- data/misc/openlayers/lib/OpenLayers/Layer/OSM.js +0 -123
- data/misc/openlayers/lib/OpenLayers/Layer/PointGrid.js +0 -299
- data/misc/openlayers/lib/OpenLayers/Layer/PointTrack.js +0 -125
- data/misc/openlayers/lib/OpenLayers/Layer/SphericalMercator.js +0 -146
- data/misc/openlayers/lib/OpenLayers/Layer/TMS.js +0 -202
- data/misc/openlayers/lib/OpenLayers/Layer/Text.js +0 -267
- data/misc/openlayers/lib/OpenLayers/Layer/TileCache.js +0 -140
- data/misc/openlayers/lib/OpenLayers/Layer/UTFGrid.js +0 -184
- data/misc/openlayers/lib/OpenLayers/Layer/Vector.js +0 -1007
- data/misc/openlayers/lib/OpenLayers/Layer/Vector/RootContainer.js +0 -154
- data/misc/openlayers/lib/OpenLayers/Layer/WMS.js +0 -267
- data/misc/openlayers/lib/OpenLayers/Layer/WMTS.js +0 -510
- data/misc/openlayers/lib/OpenLayers/Layer/WorldWind.js +0 -105
- data/misc/openlayers/lib/OpenLayers/Layer/XYZ.js +0 -172
- data/misc/openlayers/lib/OpenLayers/Layer/Zoomify.js +0 -260
- data/misc/openlayers/lib/OpenLayers/Map.js +0 -2867
- data/misc/openlayers/lib/OpenLayers/Marker.js +0 -241
- data/misc/openlayers/lib/OpenLayers/Marker/Box.js +0 -120
- data/misc/openlayers/lib/OpenLayers/Popup.js +0 -1065
- data/misc/openlayers/lib/OpenLayers/Popup/Anchored.js +0 -195
- data/misc/openlayers/lib/OpenLayers/Popup/Framed.js +0 -343
- data/misc/openlayers/lib/OpenLayers/Popup/FramedCloud.js +0 -227
- data/misc/openlayers/lib/OpenLayers/Projection.js +0 -322
- data/misc/openlayers/lib/OpenLayers/Protocol.js +0 -291
- data/misc/openlayers/lib/OpenLayers/Protocol/CSW.js +0 -30
- data/misc/openlayers/lib/OpenLayers/Protocol/CSW/v2_0_2.js +0 -127
- data/misc/openlayers/lib/OpenLayers/Protocol/HTTP.js +0 -580
- data/misc/openlayers/lib/OpenLayers/Protocol/SOS.js +0 -33
- data/misc/openlayers/lib/OpenLayers/Protocol/SOS/v1_0_0.js +0 -133
- data/misc/openlayers/lib/OpenLayers/Protocol/Script.js +0 -377
- data/misc/openlayers/lib/OpenLayers/Protocol/WFS.js +0 -86
- data/misc/openlayers/lib/OpenLayers/Protocol/WFS/v1.js +0 -453
- data/misc/openlayers/lib/OpenLayers/Protocol/WFS/v1_0_0.js +0 -44
- data/misc/openlayers/lib/OpenLayers/Protocol/WFS/v1_1_0.js +0 -68
- data/misc/openlayers/lib/OpenLayers/Renderer.js +0 -432
- data/misc/openlayers/lib/OpenLayers/Renderer/Canvas.js +0 -906
- data/misc/openlayers/lib/OpenLayers/Renderer/Elements.js +0 -1053
- data/misc/openlayers/lib/OpenLayers/Renderer/SVG.js +0 -1012
- data/misc/openlayers/lib/OpenLayers/Renderer/VML.js +0 -985
- data/misc/openlayers/lib/OpenLayers/Request.js +0 -429
- data/misc/openlayers/lib/OpenLayers/Request/XMLHttpRequest.js +0 -458
- data/misc/openlayers/lib/OpenLayers/Rule.js +0 -236
- data/misc/openlayers/lib/OpenLayers/SingleFile.js +0 -78
- data/misc/openlayers/lib/OpenLayers/Spherical.js +0 -67
- data/misc/openlayers/lib/OpenLayers/Strategy.js +0 -121
- data/misc/openlayers/lib/OpenLayers/Strategy/BBOX.js +0 -290
- data/misc/openlayers/lib/OpenLayers/Strategy/Cluster.js +0 -283
- data/misc/openlayers/lib/OpenLayers/Strategy/Filter.js +0 -159
- data/misc/openlayers/lib/OpenLayers/Strategy/Fixed.js +0 -135
- data/misc/openlayers/lib/OpenLayers/Strategy/Paging.js +0 -233
- data/misc/openlayers/lib/OpenLayers/Strategy/Refresh.js +0 -141
- data/misc/openlayers/lib/OpenLayers/Strategy/Save.js +0 -231
- data/misc/openlayers/lib/OpenLayers/Style.js +0 -448
- data/misc/openlayers/lib/OpenLayers/Style2.js +0 -112
- data/misc/openlayers/lib/OpenLayers/StyleMap.js +0 -161
- data/misc/openlayers/lib/OpenLayers/Symbolizer.js +0 -55
- data/misc/openlayers/lib/OpenLayers/Symbolizer/Line.js +0 -74
- data/misc/openlayers/lib/OpenLayers/Symbolizer/Point.js +0 -157
- data/misc/openlayers/lib/OpenLayers/Symbolizer/Polygon.js +0 -88
- data/misc/openlayers/lib/OpenLayers/Symbolizer/Raster.js +0 -34
- data/misc/openlayers/lib/OpenLayers/Symbolizer/Text.js +0 -70
- data/misc/openlayers/lib/OpenLayers/Tile.js +0 -292
- data/misc/openlayers/lib/OpenLayers/Tile/Image.js +0 -510
- data/misc/openlayers/lib/OpenLayers/Tile/Image/IFrame.js +0 -233
- data/misc/openlayers/lib/OpenLayers/Tile/UTFGrid.js +0 -252
- data/misc/openlayers/lib/OpenLayers/TileManager.js +0 -462
- data/misc/openlayers/lib/OpenLayers/Tween.js +0 -361
- data/misc/openlayers/lib/OpenLayers/Util.js +0 -1773
- data/misc/openlayers/lib/OpenLayers/Util/vendorPrefix.js +0 -131
- data/misc/openlayers/lib/OpenLayers/WPSClient.js +0 -223
- data/misc/openlayers/lib/OpenLayers/WPSProcess.js +0 -501
- data/misc/openlayers/lib/Rico/Color.js +0 -253
- data/misc/openlayers/lib/Rico/Corner.js +0 -339
- data/misc/openlayers/lib/Rico/license.js +0 -19
- data/misc/openlayers/lib/deprecated.js +0 -5842
- data/misc/openlayers/license.txt +0 -27
- data/misc/openlayers/licenses/APACHE-2.0.txt +0 -202
- data/misc/openlayers/licenses/BSD-LICENSE.txt +0 -28
- data/misc/openlayers/licenses/MIT-LICENSE.txt +0 -18
- data/misc/openlayers/notes/2.12.md +0 -391
- data/misc/openlayers/notes/2.13.md +0 -159
- data/misc/openlayers/readme.md +0 -79
- data/misc/openlayers/tests/Animation.html +0 -96
- data/misc/openlayers/tests/BaseTypes.html +0 -387
- data/misc/openlayers/tests/BaseTypes/Bounds.html +0 -738
- data/misc/openlayers/tests/BaseTypes/Class.html +0 -350
- data/misc/openlayers/tests/BaseTypes/Date.html +0 -191
- data/misc/openlayers/tests/BaseTypes/Element.html +0 -195
- data/misc/openlayers/tests/BaseTypes/LonLat.html +0 -241
- data/misc/openlayers/tests/BaseTypes/Pixel.html +0 -123
- data/misc/openlayers/tests/BaseTypes/Size.html +0 -67
- data/misc/openlayers/tests/Console.html +0 -39
- data/misc/openlayers/tests/Control.html +0 -107
- data/misc/openlayers/tests/Control/ArgParser.html +0 -26
- data/misc/openlayers/tests/Control/Attribution.html +0 -60
- data/misc/openlayers/tests/Control/Button.html +0 -17
- data/misc/openlayers/tests/Control/CacheRead.html +0 -108
- data/misc/openlayers/tests/Control/CacheWrite.html +0 -90
- data/misc/openlayers/tests/Control/DragFeature.html +0 -383
- data/misc/openlayers/tests/Control/DragPan.html +0 -104
- data/misc/openlayers/tests/Control/DrawFeature.html +0 -160
- data/misc/openlayers/tests/Control/EditingToolbar.html +0 -33
- data/misc/openlayers/tests/Control/Geolocate.html +0 -129
- data/misc/openlayers/tests/Control/GetFeature.html +0 -177
- data/misc/openlayers/tests/Control/Graticule.html +0 -66
- data/misc/openlayers/tests/Control/KeyboardDefaults.html +0 -173
- data/misc/openlayers/tests/Control/LayerSwitcher.html +0 -249
- data/misc/openlayers/tests/Control/Measure.html +0 -386
- data/misc/openlayers/tests/Control/ModifyFeature.html +0 -828
- data/misc/openlayers/tests/Control/MousePosition.html +0 -109
- data/misc/openlayers/tests/Control/NavToolbar.html +0 -45
- data/misc/openlayers/tests/Control/Navigation.html +0 -200
- data/misc/openlayers/tests/Control/NavigationHistory.html +0 -245
- data/misc/openlayers/tests/Control/OverviewMap.html +0 -266
- data/misc/openlayers/tests/Control/Pan.html +0 -201
- data/misc/openlayers/tests/Control/PanPanel.html +0 -61
- data/misc/openlayers/tests/Control/PanZoom.html +0 -244
- data/misc/openlayers/tests/Control/PanZoomBar.html +0 -245
- data/misc/openlayers/tests/Control/Panel.html +0 -382
- data/misc/openlayers/tests/Control/Permalink.html +0 -453
- data/misc/openlayers/tests/Control/PinchZoom.html +0 -134
- data/misc/openlayers/tests/Control/SLDSelect.html +0 -239
- data/misc/openlayers/tests/Control/Scale.html +0 -54
- data/misc/openlayers/tests/Control/ScaleLine.html +0 -187
- data/misc/openlayers/tests/Control/SelectFeature.html +0 -632
- data/misc/openlayers/tests/Control/Snapping.html +0 -448
- data/misc/openlayers/tests/Control/Split.html +0 -319
- data/misc/openlayers/tests/Control/TouchNavigation.html +0 -155
- data/misc/openlayers/tests/Control/TransformFeature.html +0 -129
- data/misc/openlayers/tests/Control/UTFGrid.html +0 -120
- data/misc/openlayers/tests/Control/WMSGetFeatureInfo.html +0 -644
- data/misc/openlayers/tests/Control/WMTSGetFeatureInfo.html +0 -334
- data/misc/openlayers/tests/Control/Zoom.html +0 -83
- data/misc/openlayers/tests/Control/ZoomBox.html +0 -54
- data/misc/openlayers/tests/Control/ZoomIn.html +0 -101
- data/misc/openlayers/tests/Control/ZoomOut.html +0 -100
- data/misc/openlayers/tests/Control/ZoomToMaxExtent.html +0 -102
- data/misc/openlayers/tests/Events.html +0 -487
- data/misc/openlayers/tests/Events/buttonclick.html +0 -214
- data/misc/openlayers/tests/Events/featureclick.html +0 -91
- data/misc/openlayers/tests/Extras.html +0 -21
- data/misc/openlayers/tests/Feature.html +0 -205
- data/misc/openlayers/tests/Feature/Vector.html +0 -170
- data/misc/openlayers/tests/Filter.html +0 -31
- data/misc/openlayers/tests/Filter/Comparison.html +0 -373
- data/misc/openlayers/tests/Filter/FeatureId.html +0 -67
- data/misc/openlayers/tests/Filter/Logical.html +0 -144
- data/misc/openlayers/tests/Filter/Spatial.html +0 -112
- data/misc/openlayers/tests/Format.html +0 -23
- data/misc/openlayers/tests/Format/ArcXML.html +0 -277
- data/misc/openlayers/tests/Format/ArcXML/Features.html +0 -69
- data/misc/openlayers/tests/Format/Atom.html +0 -450
- data/misc/openlayers/tests/Format/CQL.html +0 -364
- data/misc/openlayers/tests/Format/CSWGetDomain.html +0 -23
- data/misc/openlayers/tests/Format/CSWGetDomain/v2_0_2.html +0 -56
- data/misc/openlayers/tests/Format/CSWGetDomain/v2_0_2.js +0 -18
- data/misc/openlayers/tests/Format/CSWGetRecords.html +0 -23
- data/misc/openlayers/tests/Format/CSWGetRecords/v2_0_2.html +0 -88
- data/misc/openlayers/tests/Format/CSWGetRecords/v2_0_2.js +0 -50
- data/misc/openlayers/tests/Format/EncodedPolyline.html +0 -372
- data/misc/openlayers/tests/Format/Filter.html +0 -21
- data/misc/openlayers/tests/Format/Filter/v1.html +0 -404
- data/misc/openlayers/tests/Format/Filter/v1_0_0.html +0 -295
- data/misc/openlayers/tests/Format/Filter/v1_1_0.html +0 -402
- data/misc/openlayers/tests/Format/GML.html +0 -462
- data/misc/openlayers/tests/Format/GML/cases.js +0 -232
- data/misc/openlayers/tests/Format/GML/v2.html +0 -684
- data/misc/openlayers/tests/Format/GML/v3.html +0 -828
- data/misc/openlayers/tests/Format/GPX.html +0 -179
- data/misc/openlayers/tests/Format/GeoJSON.html +0 -468
- data/misc/openlayers/tests/Format/GeoRSS.html +0 -122
- data/misc/openlayers/tests/Format/JSON.html +0 -53
- data/misc/openlayers/tests/Format/KML.html +0 -1437
- data/misc/openlayers/tests/Format/OGCExceptionReport.html +0 -100
- data/misc/openlayers/tests/Format/OSM.html +0 -115
- data/misc/openlayers/tests/Format/OWSCommon/v1_0_0.html +0 -34
- data/misc/openlayers/tests/Format/OWSCommon/v1_1_0.html +0 -34
- data/misc/openlayers/tests/Format/OWSContext/v0_3_1.html +0 -278
- data/misc/openlayers/tests/Format/QueryStringFilter.html +0 -306
- data/misc/openlayers/tests/Format/SLD.html +0 -36
- data/misc/openlayers/tests/Format/SLD/v1_0_0.html +0 -1028
- data/misc/openlayers/tests/Format/SLD/v1_0_0_GeoServer.html +0 -228
- data/misc/openlayers/tests/Format/SOSCapabilities/v1_0_0.html +0 -80
- data/misc/openlayers/tests/Format/SOSCapabilities/v1_0_0.js +0 -484
- data/misc/openlayers/tests/Format/SOSGetFeatureOfInterest.html +0 -80
- data/misc/openlayers/tests/Format/SOSGetObservation.html +0 -183
- data/misc/openlayers/tests/Format/Text.html +0 -49
- data/misc/openlayers/tests/Format/WCSCapabilities.html +0 -43
- data/misc/openlayers/tests/Format/WCSCapabilities/v1.html +0 -87
- data/misc/openlayers/tests/Format/WCSGetCoverage.html +0 -80
- data/misc/openlayers/tests/Format/WFS.html +0 -81
- data/misc/openlayers/tests/Format/WFSCapabilities.html +0 -43
- data/misc/openlayers/tests/Format/WFSCapabilities/v1.html +0 -179
- data/misc/openlayers/tests/Format/WFSDescribeFeatureType.html +0 -436
- data/misc/openlayers/tests/Format/WFST.html +0 -23
- data/misc/openlayers/tests/Format/WFST/v1.html +0 -455
- data/misc/openlayers/tests/Format/WFST/v1_0_0.html +0 -135
- data/misc/openlayers/tests/Format/WFST/v1_1_0.html +0 -236
- data/misc/openlayers/tests/Format/WKT.html +0 -297
- data/misc/openlayers/tests/Format/WMC.html +0 -315
- data/misc/openlayers/tests/Format/WMC/v1.html +0 -266
- data/misc/openlayers/tests/Format/WMC/v1_1_0.html +0 -86
- data/misc/openlayers/tests/Format/WMSCapabilities.html +0 -20
- data/misc/openlayers/tests/Format/WMSCapabilities/v1_1_1.html +0 -5209
- data/misc/openlayers/tests/Format/WMSCapabilities/v1_1_1_WMSC.html +0 -348
- data/misc/openlayers/tests/Format/WMSCapabilities/v1_3_0.html +0 -614
- data/misc/openlayers/tests/Format/WMSDescribeLayer.html +0 -65
- data/misc/openlayers/tests/Format/WMSGetFeatureInfo.html +0 -319
- data/misc/openlayers/tests/Format/WMTSCapabilities.html +0 -20
- data/misc/openlayers/tests/Format/WMTSCapabilities/v1_0_0.html +0 -1042
- data/misc/openlayers/tests/Format/WPSCapabilities/v1_0_0.html +0 -30
- data/misc/openlayers/tests/Format/WPSCapabilities/v1_0_0.js +0 -112
- data/misc/openlayers/tests/Format/WPSDescribeProcess.html +0 -206
- data/misc/openlayers/tests/Format/WPSExecute.html +0 -549
- data/misc/openlayers/tests/Format/XLS/v1_1_0.html +0 -98
- data/misc/openlayers/tests/Format/XML.html +0 -900
- data/misc/openlayers/tests/Format/XML/VersionedOGC.html +0 -51
- data/misc/openlayers/tests/Geometry.html +0 -356
- data/misc/openlayers/tests/Geometry/Collection.html +0 -431
- data/misc/openlayers/tests/Geometry/Curve.html +0 -157
- data/misc/openlayers/tests/Geometry/LineString.html +0 -443
- data/misc/openlayers/tests/Geometry/LinearRing.html +0 -362
- data/misc/openlayers/tests/Geometry/MultiLineString.html +0 -267
- data/misc/openlayers/tests/Geometry/MultiPoint.html +0 -130
- data/misc/openlayers/tests/Geometry/MultiPolygon.html +0 -34
- data/misc/openlayers/tests/Geometry/Point.html +0 -244
- data/misc/openlayers/tests/Geometry/Polygon.html +0 -420
- data/misc/openlayers/tests/Handler.html +0 -265
- data/misc/openlayers/tests/Handler/Box.html +0 -106
- data/misc/openlayers/tests/Handler/Click.html +0 -735
- data/misc/openlayers/tests/Handler/Drag.html +0 -603
- data/misc/openlayers/tests/Handler/Feature.html +0 -698
- data/misc/openlayers/tests/Handler/Hover.html +0 -136
- data/misc/openlayers/tests/Handler/Keyboard.html +0 -150
- data/misc/openlayers/tests/Handler/MouseWheel.html +0 -182
- data/misc/openlayers/tests/Handler/Path.html +0 -1464
- data/misc/openlayers/tests/Handler/Pinch.html +0 -285
- data/misc/openlayers/tests/Handler/Point.html +0 -600
- data/misc/openlayers/tests/Handler/Polygon.html +0 -1161
- data/misc/openlayers/tests/Handler/RegularPolygon.html +0 -235
- data/misc/openlayers/tests/Icon.html +0 -68
- data/misc/openlayers/tests/Kinetic.html +0 -132
- data/misc/openlayers/tests/Lang.html +0 -106
- data/misc/openlayers/tests/Layer.html +0 -910
- data/misc/openlayers/tests/Layer/ArcGIS93Rest.html +0 -324
- data/misc/openlayers/tests/Layer/ArcGISCache.html +0 -256
- data/misc/openlayers/tests/Layer/ArcGISCache.json +0 -334
- data/misc/openlayers/tests/Layer/ArcIMS.html +0 -123
- data/misc/openlayers/tests/Layer/Bing.html +0 -200
- data/misc/openlayers/tests/Layer/EventPane.html +0 -172
- data/misc/openlayers/tests/Layer/FixedZoomLevels.html +0 -137
- data/misc/openlayers/tests/Layer/GeoRSS.html +0 -210
- data/misc/openlayers/tests/Layer/Google.html +0 -369
- data/misc/openlayers/tests/Layer/Google/v3.html +0 -337
- data/misc/openlayers/tests/Layer/Grid.html +0 -1593
- data/misc/openlayers/tests/Layer/HTTPRequest.html +0 -229
- data/misc/openlayers/tests/Layer/Image.html +0 -164
- data/misc/openlayers/tests/Layer/KaMap.html +0 -287
- data/misc/openlayers/tests/Layer/MapGuide.html +0 -177
- data/misc/openlayers/tests/Layer/MapServer.html +0 -238
- data/misc/openlayers/tests/Layer/Markers.html +0 -156
- data/misc/openlayers/tests/Layer/OSM.html +0 -16
- data/misc/openlayers/tests/Layer/PointGrid.html +0 -232
- data/misc/openlayers/tests/Layer/PointTrack.html +0 -79
- data/misc/openlayers/tests/Layer/SphericalMercator.html +0 -126
- data/misc/openlayers/tests/Layer/TMS.html +0 -262
- data/misc/openlayers/tests/Layer/Text.html +0 -211
- data/misc/openlayers/tests/Layer/TileCache.html +0 -203
- data/misc/openlayers/tests/Layer/UTFGrid.html +0 -131
- data/misc/openlayers/tests/Layer/Vector.html +0 -879
- data/misc/openlayers/tests/Layer/Vector/RootContainer.html +0 -63
- data/misc/openlayers/tests/Layer/WMS.html +0 -583
- data/misc/openlayers/tests/Layer/WMTS.html +0 -1491
- data/misc/openlayers/tests/Layer/WrapDateLine.html +0 -188
- data/misc/openlayers/tests/Layer/XYZ.html +0 -266
- data/misc/openlayers/tests/Layer/atom-1.0.xml +0 -34
- data/misc/openlayers/tests/Layer/data_Layer_Text_textfile.txt +0 -3
- data/misc/openlayers/tests/Layer/data_Layer_Text_textfile_2.txt +0 -3
- data/misc/openlayers/tests/Layer/data_Layer_Text_textfile_overflow.txt +0 -3
- data/misc/openlayers/tests/Layer/georss.txt +0 -378
- data/misc/openlayers/tests/Map.html +0 -2255
- data/misc/openlayers/tests/Marker.html +0 -163
- data/misc/openlayers/tests/Marker/Box.html +0 -183
- data/misc/openlayers/tests/OLLoader.js +0 -26
- data/misc/openlayers/tests/OpenLayers1.html +0 -18
- data/misc/openlayers/tests/OpenLayers2.html +0 -19
- data/misc/openlayers/tests/OpenLayers3.html +0 -19
- data/misc/openlayers/tests/OpenLayers4.html +0 -18
- data/misc/openlayers/tests/OpenLayersJsFiles.html +0 -27
- data/misc/openlayers/tests/Popup.html +0 -219
- data/misc/openlayers/tests/Popup/Anchored.html +0 -37
- data/misc/openlayers/tests/Popup/FramedCloud.html +0 -18
- data/misc/openlayers/tests/Projection.html +0 -87
- data/misc/openlayers/tests/Protocol.html +0 -63
- data/misc/openlayers/tests/Protocol/CSW.html +0 -90
- data/misc/openlayers/tests/Protocol/HTTP.html +0 -842
- data/misc/openlayers/tests/Protocol/SOS.html +0 -57
- data/misc/openlayers/tests/Protocol/Script.html +0 -282
- data/misc/openlayers/tests/Protocol/WFS.html +0 -471
- data/misc/openlayers/tests/README.txt +0 -16
- data/misc/openlayers/tests/Renderer.html +0 -96
- data/misc/openlayers/tests/Renderer/Canvas.html +0 -501
- data/misc/openlayers/tests/Renderer/Elements.html +0 -651
- data/misc/openlayers/tests/Renderer/SVG.html +0 -441
- data/misc/openlayers/tests/Renderer/VML.html +0 -454
- data/misc/openlayers/tests/Request.html +0 -524
- data/misc/openlayers/tests/Request/XMLHttpRequest.html +0 -59
- data/misc/openlayers/tests/Rule.html +0 -123
- data/misc/openlayers/tests/SingleFile1.html +0 -15
- data/misc/openlayers/tests/SingleFile2.html +0 -15
- data/misc/openlayers/tests/SingleFile3.html +0 -15
- data/misc/openlayers/tests/Strategy.html +0 -94
- data/misc/openlayers/tests/Strategy/BBOX.html +0 -361
- data/misc/openlayers/tests/Strategy/Cluster.html +0 -148
- data/misc/openlayers/tests/Strategy/Filter.html +0 -135
- data/misc/openlayers/tests/Strategy/Fixed.html +0 -253
- data/misc/openlayers/tests/Strategy/Paging.html +0 -113
- data/misc/openlayers/tests/Strategy/Refresh.html +0 -177
- data/misc/openlayers/tests/Strategy/Save.html +0 -127
- data/misc/openlayers/tests/Style.html +0 -426
- data/misc/openlayers/tests/Style2.html +0 -56
- data/misc/openlayers/tests/StyleMap.html +0 -44
- data/misc/openlayers/tests/Symbolizer.html +0 -31
- data/misc/openlayers/tests/Symbolizer/Line.html +0 -42
- data/misc/openlayers/tests/Symbolizer/Point.html +0 -52
- data/misc/openlayers/tests/Symbolizer/Polygon.html +0 -44
- data/misc/openlayers/tests/Symbolizer/Raster.html +0 -32
- data/misc/openlayers/tests/Symbolizer/Text.html +0 -42
- data/misc/openlayers/tests/Test.AnotherWay.baseadditions.js +0 -191
- data/misc/openlayers/tests/Test.AnotherWay.css +0 -243
- data/misc/openlayers/tests/Test.AnotherWay.geom_eq.js +0 -139
- data/misc/openlayers/tests/Test.AnotherWay.js +0 -2498
- data/misc/openlayers/tests/Test.AnotherWay.xml_eq.js +0 -311
- data/misc/openlayers/tests/Tile.html +0 -130
- data/misc/openlayers/tests/Tile/Image.html +0 -490
- data/misc/openlayers/tests/Tile/Image/IFrame.html +0 -183
- data/misc/openlayers/tests/Tile/UTFGrid.html +0 -306
- data/misc/openlayers/tests/TileManager.html +0 -137
- data/misc/openlayers/tests/Tween.html +0 -116
- data/misc/openlayers/tests/Util.html +0 -1180
- data/misc/openlayers/tests/Util/vendorPrefix.html +0 -117
- data/misc/openlayers/tests/Util_common.js +0 -64
- data/misc/openlayers/tests/Util_w3c.html +0 -35
- data/misc/openlayers/tests/WPSClient.html +0 -108
- data/misc/openlayers/tests/WPSProcess.html +0 -188
- data/misc/openlayers/tests/atom-1.0.xml +0 -34
- data/misc/openlayers/tests/auto-tests.html +0 -2447
- data/misc/openlayers/tests/data/geos_wkt_intersects.js +0 -495
- data/misc/openlayers/tests/data/osm.js +0 -14
- data/misc/openlayers/tests/data/utfgrid/bio_utfgrid/1/0/0.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/bio_utfgrid/1/0/1.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/bio_utfgrid/1/0/2.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/bio_utfgrid/1/1/0.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/bio_utfgrid/1/1/1.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/bio_utfgrid/1/1/2.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/bio_utfgrid/1/2/0.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/bio_utfgrid/1/2/1.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/bio_utfgrid/1/2/2.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/demo-1.1.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/world_utfgrid/1/0/0.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/world_utfgrid/1/0/1.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/world_utfgrid/1/0/2.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/world_utfgrid/1/1/0.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/world_utfgrid/1/1/1.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/world_utfgrid/1/1/2.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/world_utfgrid/1/2/0.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/world_utfgrid/1/2/1.json +0 -1
- data/misc/openlayers/tests/data/utfgrid/world_utfgrid/1/2/2.json +0 -1
- data/misc/openlayers/tests/data_Layer_Text_textfile.txt +0 -3
- data/misc/openlayers/tests/data_Layer_Text_textfile_2.txt +0 -3
- data/misc/openlayers/tests/data_Layer_Text_textfile_overflow.txt +0 -3
- data/misc/openlayers/tests/deprecated/Ajax.html +0 -28
- data/misc/openlayers/tests/deprecated/BaseTypes/Class.html +0 -142
- data/misc/openlayers/tests/deprecated/BaseTypes/Element.html +0 -56
- data/misc/openlayers/tests/deprecated/Control/MouseToolbar.html +0 -60
- data/misc/openlayers/tests/deprecated/Geometry/Rectangle.html +0 -77
- data/misc/openlayers/tests/deprecated/Layer/GML.html +0 -61
- data/misc/openlayers/tests/deprecated/Layer/MapServer.html +0 -59
- data/misc/openlayers/tests/deprecated/Layer/MapServer/Untiled.html +0 -158
- data/misc/openlayers/tests/deprecated/Layer/WFS.html +0 -178
- data/misc/openlayers/tests/deprecated/Layer/WMS.html +0 -60
- data/misc/openlayers/tests/deprecated/Layer/WMS/Post.html +0 -89
- data/misc/openlayers/tests/deprecated/Layer/Yahoo.html +0 -121
- data/misc/openlayers/tests/deprecated/Layer/mice.xml +0 -156
- data/misc/openlayers/tests/deprecated/Layer/owls.xml +0 -156
- data/misc/openlayers/tests/deprecated/Popup/AnchoredBubble.html +0 -61
- data/misc/openlayers/tests/deprecated/Protocol/SQL.html +0 -24
- data/misc/openlayers/tests/deprecated/Protocol/SQL/Gears.html +0 -474
- data/misc/openlayers/tests/deprecated/Renderer/SVG2.html +0 -399
- data/misc/openlayers/tests/deprecated/Tile/WFS.html +0 -215
- data/misc/openlayers/tests/deprecated/Util.html +0 -20
- data/misc/openlayers/tests/georss.txt +0 -378
- data/misc/openlayers/tests/grid_inittiles.html +0 -30
- data/misc/openlayers/tests/index.html +0 -6
- data/misc/openlayers/tests/list-tests.html +0 -260
- data/misc/openlayers/tests/manual/ajax.html +0 -49
- data/misc/openlayers/tests/manual/ajax.txt +0 -1
- data/misc/openlayers/tests/manual/alloverlays-mixed.html +0 -55
- data/misc/openlayers/tests/manual/arcims-2117.html +0 -103
- data/misc/openlayers/tests/manual/arkansas.rss +0 -9
- data/misc/openlayers/tests/manual/big-georss.html +0 -33
- data/misc/openlayers/tests/manual/box-quirks.html +0 -52
- data/misc/openlayers/tests/manual/box-strict.html +0 -46
- data/misc/openlayers/tests/manual/clip-features-svg.html +0 -128
- data/misc/openlayers/tests/manual/dateline-sketch.html +0 -66
- data/misc/openlayers/tests/manual/dateline-smallextent.html +0 -61
- data/misc/openlayers/tests/manual/draw-feature.html +0 -73
- data/misc/openlayers/tests/manual/feature-handler.html +0 -126
- data/misc/openlayers/tests/manual/geodesic.html +0 -160
- data/misc/openlayers/tests/manual/geojson-geomcoll-reprojection.html +0 -74
- data/misc/openlayers/tests/manual/google-fullscreen-overlay.html +0 -54
- data/misc/openlayers/tests/manual/google-panning.html +0 -122
- data/misc/openlayers/tests/manual/google-resize.html +0 -55
- data/misc/openlayers/tests/manual/google-tilt.html +0 -37
- data/misc/openlayers/tests/manual/google-v3-resize.html +0 -54
- data/misc/openlayers/tests/manual/loadend.html +0 -73
- data/misc/openlayers/tests/manual/map-events.html +0 -38
- data/misc/openlayers/tests/manual/memory/Marker-2258.html +0 -60
- data/misc/openlayers/tests/manual/memory/PanZoom-2323.html +0 -41
- data/misc/openlayers/tests/manual/memory/RemoveChild-2170.html +0 -56
- data/misc/openlayers/tests/manual/memory/VML-2170.html +0 -49
- data/misc/openlayers/tests/manual/multiple-google-layers.html +0 -135
- data/misc/openlayers/tests/manual/overviewmap-projection.html +0 -70
- data/misc/openlayers/tests/manual/page-position.html +0 -103
- data/misc/openlayers/tests/manual/pan-redraw-svg.html +0 -58
- data/misc/openlayers/tests/manual/popup-keepInMap.html +0 -100
- data/misc/openlayers/tests/manual/reflow.html +0 -59
- data/misc/openlayers/tests/manual/renderedDimensions.html +0 -113
- data/misc/openlayers/tests/manual/select-feature-right-click.html +0 -86
- data/misc/openlayers/tests/manual/select-feature.html +0 -75
- data/misc/openlayers/tests/manual/tiles-loading.html +0 -122
- data/misc/openlayers/tests/manual/tween.html +0 -82
- data/misc/openlayers/tests/manual/vector-features-performance.html +0 -149
- data/misc/openlayers/tests/manual/vector-layer-zindex.html +0 -143
- data/misc/openlayers/tests/mice.xml +0 -156
- data/misc/openlayers/tests/node.js/mockdom.js +0 -104
- data/misc/openlayers/tests/node.js/node-tests.cfg +0 -12
- data/misc/openlayers/tests/node.js/node.js +0 -1
- data/misc/openlayers/tests/node.js/run-test.js +0 -26
- data/misc/openlayers/tests/node.js/run.sh +0 -10
- data/misc/openlayers/tests/owls.xml +0 -156
- data/misc/openlayers/tests/run-tests.html +0 -155
- data/misc/openlayers/tests/selenium/remotecontrol/config.cfg +0 -48
- data/misc/openlayers/tests/selenium/remotecontrol/selenium.py +0 -1846
- data/misc/openlayers/tests/selenium/remotecontrol/setup.txt +0 -8
- data/misc/openlayers/tests/selenium/remotecontrol/test_ol.py +0 -95
- data/misc/openlayers/tests/speed/geometry.html +0 -43
- data/misc/openlayers/tests/speed/string_format.html +0 -29
- data/misc/openlayers/tests/speed/vector-renderers.html +0 -25
- data/misc/openlayers/tests/speed/vector-renderers.js +0 -70
- data/misc/openlayers/tests/speed/wmc_speed.html +0 -30
- data/misc/openlayers/tests/speed/wmscaps.html +0 -52
- data/misc/openlayers/tests/speed/wmscaps.js +0 -4956
- data/misc/openlayers/tests/speed/wmscaps.xml +0 -4954
- data/misc/openlayers/tests/throws.js +0 -82
- data/misc/openlayers/theme/default/google.css +0 -9
- data/misc/openlayers/theme/default/google.tidy.css +0 -1
- data/misc/openlayers/theme/default/ie6-style.css +0 -10
- data/misc/openlayers/theme/default/ie6-style.tidy.css +0 -1
- data/misc/openlayers/theme/default/img/add_point_off.png +0 -0
- data/misc/openlayers/theme/default/img/add_point_on.png +0 -0
- data/misc/openlayers/theme/default/img/blank.gif +0 -0
- data/misc/openlayers/theme/default/img/close.gif +0 -0
- data/misc/openlayers/theme/default/img/drag-rectangle-off.png +0 -0
- data/misc/openlayers/theme/default/img/drag-rectangle-on.png +0 -0
- data/misc/openlayers/theme/default/img/draw_line_off.png +0 -0
- data/misc/openlayers/theme/default/img/draw_line_on.png +0 -0
- data/misc/openlayers/theme/default/img/draw_point_off.png +0 -0
- data/misc/openlayers/theme/default/img/draw_point_on.png +0 -0
- data/misc/openlayers/theme/default/img/draw_polygon_off.png +0 -0
- data/misc/openlayers/theme/default/img/draw_polygon_on.png +0 -0
- data/misc/openlayers/theme/default/img/editing_tool_bar.png +0 -0
- data/misc/openlayers/theme/default/img/move_feature_off.png +0 -0
- data/misc/openlayers/theme/default/img/move_feature_on.png +0 -0
- data/misc/openlayers/theme/default/img/navigation_history.png +0 -0
- data/misc/openlayers/theme/default/img/overview_replacement.gif +0 -0
- data/misc/openlayers/theme/default/img/pan-panel-NOALPHA.png +0 -0
- data/misc/openlayers/theme/default/img/pan-panel.png +0 -0
- data/misc/openlayers/theme/default/img/pan_off.png +0 -0
- data/misc/openlayers/theme/default/img/pan_on.png +0 -0
- data/misc/openlayers/theme/default/img/panning-hand-off.png +0 -0
- data/misc/openlayers/theme/default/img/panning-hand-on.png +0 -0
- data/misc/openlayers/theme/default/img/remove_point_off.png +0 -0
- data/misc/openlayers/theme/default/img/remove_point_on.png +0 -0
- data/misc/openlayers/theme/default/img/ruler.png +0 -0
- data/misc/openlayers/theme/default/img/save_features_off.png +0 -0
- data/misc/openlayers/theme/default/img/save_features_on.png +0 -0
- data/misc/openlayers/theme/default/img/view_next_off.png +0 -0
- data/misc/openlayers/theme/default/img/view_next_on.png +0 -0
- data/misc/openlayers/theme/default/img/view_previous_off.png +0 -0
- data/misc/openlayers/theme/default/img/view_previous_on.png +0 -0
- data/misc/openlayers/theme/default/img/zoom-panel-NOALPHA.png +0 -0
- data/misc/openlayers/theme/default/img/zoom-panel.png +0 -0
- data/misc/openlayers/theme/default/style.css +0 -516
- data/misc/openlayers/theme/default/style.mobile.css +0 -70
- data/misc/openlayers/theme/default/style.mobile.tidy.css +0 -1
- data/misc/openlayers/theme/default/style.tidy.css +0 -1
- data/misc/openlayers/tools/BeautifulSoup.py +0 -1767
- data/misc/openlayers/tools/README.txt +0 -14
- data/misc/openlayers/tools/closure_library_jscompiler.py +0 -71
- data/misc/openlayers/tools/closure_ws.py +0 -28
- data/misc/openlayers/tools/exampleparser.py +0 -251
- data/misc/openlayers/tools/jsmin.c +0 -272
- data/misc/openlayers/tools/jsmin.py +0 -216
- data/misc/openlayers/tools/mergejs.py +0 -287
- data/misc/openlayers/tools/minimize.py +0 -47
- data/misc/openlayers/tools/oldot.py +0 -43
- data/misc/openlayers/tools/release.sh +0 -71
- data/misc/openlayers/tools/shrinksafe.py +0 -54
- data/misc/openlayers/tools/toposort.py +0 -35
- data/misc/openlayers/tools/uglify_js.py +0 -35
- data/misc/openlayers/tools/update_dev_dir.sh +0 -103
@@ -1,70 +0,0 @@
|
|
1
|
-
div.olControlZoom {
|
2
|
-
position: absolute;
|
3
|
-
top: 8px;
|
4
|
-
left: 8px;
|
5
|
-
background: rgba(255,255,255,0.4);
|
6
|
-
border-radius: 4px;
|
7
|
-
padding: 2px;
|
8
|
-
}
|
9
|
-
* {
|
10
|
-
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
11
|
-
}
|
12
|
-
div.olControlZoom a {
|
13
|
-
display: block;
|
14
|
-
margin: 1px;
|
15
|
-
padding: 0;
|
16
|
-
color: white;
|
17
|
-
font-size: 28px;
|
18
|
-
font-family: sans-serif;
|
19
|
-
font-weight: bold;
|
20
|
-
text-decoration: none;
|
21
|
-
text-align: center;
|
22
|
-
height: 32px;
|
23
|
-
width: 32px;
|
24
|
-
line-height: 28px;
|
25
|
-
text-shadow: 0 0 3px rgba(0,0,0,0.8);
|
26
|
-
background: #130085; /* fallback for IE - IE6 requires background shorthand*/
|
27
|
-
background: rgba(0, 60, 136, 0.5);
|
28
|
-
filter: alpha(opacity=80);
|
29
|
-
}
|
30
|
-
a.olControlZoomIn {
|
31
|
-
border-radius: 4px 4px 0 0;
|
32
|
-
}
|
33
|
-
a.olControlZoomOut {
|
34
|
-
border-radius: 0 0 4px 4px;
|
35
|
-
}
|
36
|
-
div.olControlZoom a:hover {
|
37
|
-
background: #130085; /* fallback for IE */
|
38
|
-
background: rgba(0, 60, 136, 0.7);
|
39
|
-
filter: alpha(opacity=100);
|
40
|
-
}
|
41
|
-
@media only screen and (max-width: 600px) {
|
42
|
-
div.olControlZoom a:hover {
|
43
|
-
background: rgba(0, 60, 136, 0.5);
|
44
|
-
}
|
45
|
-
}
|
46
|
-
div.olMapViewport {
|
47
|
-
-ms-touch-action: none;
|
48
|
-
}
|
49
|
-
.olLayerGrid .olTileImage {
|
50
|
-
-webkit-transition: opacity 0.2s linear;
|
51
|
-
-moz-transition: opacity 0.2s linear;
|
52
|
-
-o-transition: opacity 0.2s linear;
|
53
|
-
transition: opacity 0.2s linear;
|
54
|
-
}
|
55
|
-
/* Turn on GPU support where available */
|
56
|
-
.olTileImage {
|
57
|
-
-webkit-transform: translateZ(0);
|
58
|
-
-moz-transform: translateZ(0);
|
59
|
-
-o-transform: translateZ(0);
|
60
|
-
-ms-transform: translateZ(0);
|
61
|
-
transform: translateZ(0);
|
62
|
-
-webkit-backface-visibility: hidden;
|
63
|
-
-moz-backface-visibility: hidden;
|
64
|
-
-ms-backface-visibility: hidden;
|
65
|
-
backface-visibility: hidden;
|
66
|
-
-webkit-perspective: 1000;
|
67
|
-
-moz-perspective: 1000;
|
68
|
-
-ms-perspective: 1000;
|
69
|
-
perspective: 1000;
|
70
|
-
}
|
@@ -1 +0,0 @@
|
|
1
|
-
div.olControlZoom{position:absolute;top:8px;left:8px;background:rgba(255,255,255,0.4);border-radius:4px;padding:2px;}*{-webkit-tap-highlight-color:rgba(0,0,0,0);}div.olControlZoom a{display:block;color:#FFF;font-size:28px;font-family:sans-serif;font-weight:700;text-decoration:none;text-align:center;height:32px;width:32px;line-height:28px;text-shadow:0 0 3px rgba(0,0,0,0.8);background:rgba(0,60,136,0.5);filter:alpha(opacity=80);margin:1px;padding:0;}a.olControlZoomIn{border-radius:4px 4px 0 0;}a.olControlZoomOut{border-radius:0 0 4px 4px;}div.olControlZoom a:hover{background:rgba(0,60,136,0.7);filter:alpha(opacity=100);}div.olMapViewport{-ms-touch-action:none;}.olLayerGrid .olTileImage{-webkit-transition:opacity .2s linear;-moz-transition:opacity .2s linear;-o-transition:opacity .2s linear;transition:opacity .2s linear;}.olTileImage{-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-o-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0);-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;-moz-perspective:1000;-ms-perspective:1000;perspective:1000;}@media only screen and max-width 600px{div.olControlZoom a:hover{background:rgba(0,60,136,0.5);}}
|
@@ -1 +0,0 @@
|
|
1
|
-
div.olMap{z-index:0;cursor:default;margin:0!important;padding:0!important;}div.olMapViewport{text-align:left;-ms-touch-action:none;}.olLayerGoogleCopyright{left:2px;bottom:2px;}.olLayerGoogleV3.olLayerGoogleCopyright{right:auto!important;}.olLayerGooglePoweredBy{left:2px;bottom:15px;}.olLayerGoogleV3.olLayerGooglePoweredBy{bottom:15px!important;}.olForeignContainer{opacity:1!important;}.olControlAttribution{font-size:smaller;right:3px;bottom:4.5em;position:absolute;display:block;}.olControlScale{right:3px;bottom:3em;display:block;position:absolute;font-size:smaller;}.olControlScaleLine{display:block;position:absolute;left:10px;bottom:15px;font-size:xx-small;}.olControlScaleLineBottom{border:solid 2px #000;border-bottom:none;margin-top:-2px;text-align:center;}.olControlScaleLineTop{border:solid 2px #000;border-top:none;text-align:center;}.olControlPermalink{right:3px;bottom:1.5em;display:block;position:absolute;font-size:smaller;}div.olControlMousePosition{bottom:0;right:3px;display:block;position:absolute;font-family:Arial;font-size:smaller;}.olControlOverviewMapContainer{position:absolute;bottom:0;right:0;}.olControlOverviewMapElement{background-color:#00008B;-moz-border-radius:1em 0 0;padding:10px 18px 10px 10px;}.olControlOverviewMapMinimizeButton,.olControlOverviewMapMaximizeButton{height:18px;width:18px;right:0;bottom:80px;cursor:pointer;}.olControlOverviewMapExtentRectangle{overflow:hidden;background-image:url(img/blank.gif);cursor:move;border:2px dotted red;}.olControlOverviewMapRectReplacement{overflow:hidden;cursor:move;background-image:url(img/overview_replacement.gif);background-repeat:no-repeat;background-position:center;}.olLayerGeoRSSDescription{float:left;width:100%;overflow:auto;font-size:1em;}.olLayerGeoRSSClose{float:right;color:gray;font-size:1.2em;margin-right:6px;font-family:sans-serif;}.olLayerGeoRSSTitle{float:left;font-size:1.2em;}.olControlNavigationHistory{background-image:url(img/navigation_history.png);background-repeat:no-repeat;width:24px;height:24px;}.olControlNavigationHistoryPreviousItemActive{background-position:0 0;}.olControlNavigationHistoryPreviousItemInactive{background-position:0 -24px;}.olControlNavigationHistoryNextItemActive{background-position:-24px 0;}.olControlNavigationHistoryNextItemInactive{background-position:-24px -24px;}div.olControlSaveFeaturesItemActive{background-image:url(img/save_features_on.png);background-repeat:no-repeat;background-position:0 1px;}div.olControlSaveFeaturesItemInactive{background-image:url(img/save_features_off.png);background-repeat:no-repeat;background-position:0 1px;}.olHandlerBoxZoomBox{border:2px solid red;position:absolute;background-color:#FFF;opacity:.5;font-size:1px;filter:alpha(opacity=50);}.olHandlerBoxSelectFeature{border:2px solid blue;position:absolute;background-color:#FFF;opacity:.5;font-size:1px;filter:alpha(opacity=50);}.olControlPanPanel{top:10px;left:5px;}.olControlPanPanel div{background-image:url(img/pan-panel.png);height:18px;width:18px;cursor:pointer;position:absolute;}.olControlPanPanel .olControlPanNorthItemInactive{top:0;left:9px;background-position:0 0;}.olControlPanPanel .olControlPanSouthItemInactive{top:36px;left:9px;background-position:18px 0;}.olControlPanPanel .olControlPanWestItemInactive{position:absolute;top:18px;left:0;background-position:0 18px;}.olControlPanPanel .olControlPanEastItemInactive{top:18px;left:18px;background-position:18px 18px;}.olControlZoomPanel{top:71px;left:14px;}.olControlZoomPanel div{background-image:url(img/zoom-panel.png);position:absolute;height:18px;width:18px;cursor:pointer;}.olControlZoomPanel .olControlZoomInItemInactive{top:0;left:0;background-position:0 0;}.olControlZoomPanel .olControlZoomToMaxExtentItemInactive{top:18px;left:0;background-position:0 -18px;}.olControlZoomPanel .olControlZoomOutItemInactive{top:36px;left:0;background-position:0 18px;}.olControlPanZoomBar div{font-size:1px;}.olPopupCloseBox{background:url(img/close.gif) no-repeat;cursor:pointer;}.olImageLoadError{background-color:#FFC0CB;opacity:.5;filter:alpha(opacity=50);}.olCursorWait{cursor:wait;}.olDrawBox{cursor:crosshair;}.olControlDragFeatureActive.olControlDragFeatureOver.olDragDown{cursor:0;}.olControlLayerSwitcher{position:absolute;top:25px;right:0;width:20em;font-family:sans-serif;font-weight:700;margin-top:3px;margin-left:3px;margin-bottom:3px;font-size:smaller;color:#FFF;background-color:transparent;}.olControlLayerSwitcher .layersDiv{background-color:#00008B;padding:5px 10px;}.olControlLayerSwitcher .layersDiv .baseLbl,.olControlLayerSwitcher .layersDiv .dataLbl{margin-top:3px;margin-left:3px;margin-bottom:3px;}.olControlLayerSwitcher .layersDiv .baseLayersDiv,.olControlLayerSwitcher .layersDiv .dataLayersDiv{padding-left:10px;}.olControlLayerSwitcher .maximizeDiv,.olControlLayerSwitcher .minimizeDiv{width:18px;height:18px;top:5px;right:0;cursor:pointer;}.olBingAttribution{color:#DDD;}span.olGoogleAttribution a{color:#77C;}.olControlNavToolbar,.olControlEditingToolbar{margin:5px 5px 0 0;}.olControlNavToolbar div,.olControlEditingToolbar div{background-image:url(img/editing_tool_bar.png);background-repeat:no-repeat;width:24px;height:22px;cursor:pointer;margin:0 0 5px 5px;}.olControlEditingToolbar{right:0;top:0;}.olControlNavToolbar{top:295px;left:9px;}.olControlEditingToolbar div{float:right;}.olControlNavToolbar .olControlNavigationItemInactive,.olControlEditingToolbar .olControlNavigationItemInactive{background-position:-103px -1px;}.olControlNavToolbar .olControlNavigationItemActive,.olControlEditingToolbar .olControlNavigationItemActive{background-position:-103px -24px;}.olControlNavToolbar .olControlZoomBoxItemInactive{background-position:-128px -1px;}.olControlNavToolbar .olControlZoomBoxItemActive{background-position:-128px -24px;}.olControlEditingToolbar .olControlDrawFeaturePointItemInactive{background-position:-77px -1px;}.olControlEditingToolbar .olControlDrawFeaturePointItemActive{background-position:-77px -24px;}.olControlEditingToolbar .olControlDrawFeaturePathItemInactive{background-position:-51px -1px;}.olControlEditingToolbar .olControlDrawFeaturePathItemActive{background-position:-51px -24px;}.olControlEditingToolbar .olControlDrawFeaturePolygonItemInactive{background-position:-26px -1px;}.olControlEditingToolbar .olControlDrawFeaturePolygonItemActive{background-position:-26px -24px;}div.olControlZoom{position:absolute;top:8px;left:8px;background:rgba(255,255,255,0.4);border-radius:4px;padding:2px;}div.olControlZoom a{display:block;color:#FFF;font-size:18px;font-family:'Lucida Grande', Verdana, Geneva, Lucida, Arial, Helvetica, sans-serif;font-weight:700;text-decoration:none;text-align:center;height:22px;width:22px;line-height:19px;background:rgba(0,60,136,0.5);filter:alpha(opacity=80);margin:1px;padding:0;}div.olControlZoom a:hover{background:rgba(0,60,136,0.7);filter:alpha(opacity=100);}a.olControlZoomIn{border-radius:4px 4px 0 0;}a.olControlZoomOut{border-radius:0 0 4px 4px;}.olLayerGrid .olTileImage{-webkit-transition:opacity .2s linear;-moz-transition:opacity .2s linear;-o-transition:opacity .2s linear;transition:opacity .2s linear;}.olTileImage{-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-o-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0);-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;-moz-perspective:1000;-ms-perspective:1000;perspective:1000;}.olTileReplacing{display:none;}img.olTileImage{max-width:none;}div.olLayerDiv,.olControlNoSelect{-khtml-user-select:none;-moz-user-select:none;}.olPopupContent,.olFramedCloudPopupContent{overflow:auto;padding:5px;}.olDragDown,.olControlDragFeatureOver{cursor:move;}.olBingAttribution.road,.olGoogleAttribution{color:#333;}.olGoogleAttribution.hybrid,.olGoogleAttribution.satellite,span.olGoogleAttribution.hybrid a,span.olGoogleAttribution.satellite a{color:#EEE;}@media only screen and max-width 600px{div.olControlZoom a:hover{background:rgba(0,60,136,0.5);}}
|
@@ -1,1767 +0,0 @@
|
|
1
|
-
"""Beautiful Soup
|
2
|
-
Elixir and Tonic
|
3
|
-
"The Screen-Scraper's Friend"
|
4
|
-
http://www.crummy.com/software/BeautifulSoup/
|
5
|
-
|
6
|
-
Beautiful Soup parses a (possibly invalid) XML or HTML document into a
|
7
|
-
tree representation. It provides methods and Pythonic idioms that make
|
8
|
-
it easy to navigate, search, and modify the tree.
|
9
|
-
|
10
|
-
A well-formed XML/HTML document yields a well-formed data
|
11
|
-
structure. An ill-formed XML/HTML document yields a correspondingly
|
12
|
-
ill-formed data structure. If your document is only locally
|
13
|
-
well-formed, you can use this library to find and process the
|
14
|
-
well-formed part of it. The BeautifulSoup class
|
15
|
-
|
16
|
-
Beautiful Soup works with Python 2.2 and up. It has no external
|
17
|
-
dependencies, but you'll have more success at converting data to UTF-8
|
18
|
-
if you also install these three packages:
|
19
|
-
|
20
|
-
* chardet, for auto-detecting character encodings
|
21
|
-
http://chardet.feedparser.org/
|
22
|
-
* cjkcodecs and iconv_codec, which add more encodings to the ones supported
|
23
|
-
by stock Python.
|
24
|
-
http://cjkpython.i18n.org/
|
25
|
-
|
26
|
-
Beautiful Soup defines classes for two main parsing strategies:
|
27
|
-
|
28
|
-
* BeautifulStoneSoup, for parsing XML, SGML, or your domain-specific
|
29
|
-
language that kind of looks like XML.
|
30
|
-
|
31
|
-
* BeautifulSoup, for parsing run-of-the-mill HTML code, be it valid
|
32
|
-
or invalid. This class has web browser-like heuristics for
|
33
|
-
obtaining a sensible parse tree in the face of common HTML errors.
|
34
|
-
|
35
|
-
Beautiful Soup also defines a class (UnicodeDammit) for autodetecting
|
36
|
-
the encoding of an HTML or XML document, and converting it to
|
37
|
-
Unicode. Much of this code is taken from Mark Pilgrim's Universal Feed Parser.
|
38
|
-
|
39
|
-
For more than you ever wanted to know about Beautiful Soup, see the
|
40
|
-
documentation:
|
41
|
-
http://www.crummy.com/software/BeautifulSoup/documentation.html
|
42
|
-
|
43
|
-
"""
|
44
|
-
from __future__ import generators
|
45
|
-
|
46
|
-
__author__ = "Leonard Richardson (leonardr@segfault.org)"
|
47
|
-
__version__ = "3.0.4"
|
48
|
-
__copyright__ = "Copyright (c) 2004-2007 Leonard Richardson"
|
49
|
-
__license__ = "PSF"
|
50
|
-
|
51
|
-
from sgmllib import SGMLParser, SGMLParseError
|
52
|
-
import codecs
|
53
|
-
import types
|
54
|
-
import re
|
55
|
-
import sgmllib
|
56
|
-
try:
|
57
|
-
from htmlentitydefs import name2codepoint
|
58
|
-
except ImportError:
|
59
|
-
name2codepoint = {}
|
60
|
-
|
61
|
-
#This hack makes Beautiful Soup able to parse XML with namespaces
|
62
|
-
sgmllib.tagfind = re.compile('[a-zA-Z][-_.:a-zA-Z0-9]*')
|
63
|
-
|
64
|
-
DEFAULT_OUTPUT_ENCODING = "utf-8"
|
65
|
-
|
66
|
-
# First, the classes that represent markup elements.
|
67
|
-
|
68
|
-
class PageElement:
|
69
|
-
"""Contains the navigational information for some part of the page
|
70
|
-
(either a tag or a piece of text)"""
|
71
|
-
|
72
|
-
def setup(self, parent=None, previous=None):
|
73
|
-
"""Sets up the initial relations between this element and
|
74
|
-
other elements."""
|
75
|
-
self.parent = parent
|
76
|
-
self.previous = previous
|
77
|
-
self.next = None
|
78
|
-
self.previousSibling = None
|
79
|
-
self.nextSibling = None
|
80
|
-
if self.parent and self.parent.contents:
|
81
|
-
self.previousSibling = self.parent.contents[-1]
|
82
|
-
self.previousSibling.nextSibling = self
|
83
|
-
|
84
|
-
def replaceWith(self, replaceWith):
|
85
|
-
oldParent = self.parent
|
86
|
-
myIndex = self.parent.contents.index(self)
|
87
|
-
if hasattr(replaceWith, 'parent') and replaceWith.parent == self.parent:
|
88
|
-
# We're replacing this element with one of its siblings.
|
89
|
-
index = self.parent.contents.index(replaceWith)
|
90
|
-
if index and index < myIndex:
|
91
|
-
# Furthermore, it comes before this element. That
|
92
|
-
# means that when we extract it, the index of this
|
93
|
-
# element will change.
|
94
|
-
myIndex = myIndex - 1
|
95
|
-
self.extract()
|
96
|
-
oldParent.insert(myIndex, replaceWith)
|
97
|
-
|
98
|
-
def extract(self):
|
99
|
-
"""Destructively rips this element out of the tree."""
|
100
|
-
if self.parent:
|
101
|
-
try:
|
102
|
-
self.parent.contents.remove(self)
|
103
|
-
except ValueError:
|
104
|
-
pass
|
105
|
-
|
106
|
-
#Find the two elements that would be next to each other if
|
107
|
-
#this element (and any children) hadn't been parsed. Connect
|
108
|
-
#the two.
|
109
|
-
lastChild = self._lastRecursiveChild()
|
110
|
-
nextElement = lastChild.next
|
111
|
-
|
112
|
-
if self.previous:
|
113
|
-
self.previous.next = nextElement
|
114
|
-
if nextElement:
|
115
|
-
nextElement.previous = self.previous
|
116
|
-
self.previous = None
|
117
|
-
lastChild.next = None
|
118
|
-
|
119
|
-
self.parent = None
|
120
|
-
if self.previousSibling:
|
121
|
-
self.previousSibling.nextSibling = self.nextSibling
|
122
|
-
if self.nextSibling:
|
123
|
-
self.nextSibling.previousSibling = self.previousSibling
|
124
|
-
self.previousSibling = self.nextSibling = None
|
125
|
-
|
126
|
-
def _lastRecursiveChild(self):
|
127
|
-
"Finds the last element beneath this object to be parsed."
|
128
|
-
lastChild = self
|
129
|
-
while hasattr(lastChild, 'contents') and lastChild.contents:
|
130
|
-
lastChild = lastChild.contents[-1]
|
131
|
-
return lastChild
|
132
|
-
|
133
|
-
def insert(self, position, newChild):
|
134
|
-
if (isinstance(newChild, basestring)
|
135
|
-
or isinstance(newChild, unicode)) \
|
136
|
-
and not isinstance(newChild, NavigableString):
|
137
|
-
newChild = NavigableString(newChild)
|
138
|
-
|
139
|
-
position = min(position, len(self.contents))
|
140
|
-
if hasattr(newChild, 'parent') and newChild.parent != None:
|
141
|
-
# We're 'inserting' an element that's already one
|
142
|
-
# of this object's children.
|
143
|
-
if newChild.parent == self:
|
144
|
-
index = self.find(newChild)
|
145
|
-
if index and index < position:
|
146
|
-
# Furthermore we're moving it further down the
|
147
|
-
# list of this object's children. That means that
|
148
|
-
# when we extract this element, our target index
|
149
|
-
# will jump down one.
|
150
|
-
position = position - 1
|
151
|
-
newChild.extract()
|
152
|
-
|
153
|
-
newChild.parent = self
|
154
|
-
previousChild = None
|
155
|
-
if position == 0:
|
156
|
-
newChild.previousSibling = None
|
157
|
-
newChild.previous = self
|
158
|
-
else:
|
159
|
-
previousChild = self.contents[position-1]
|
160
|
-
newChild.previousSibling = previousChild
|
161
|
-
newChild.previousSibling.nextSibling = newChild
|
162
|
-
newChild.previous = previousChild._lastRecursiveChild()
|
163
|
-
if newChild.previous:
|
164
|
-
newChild.previous.next = newChild
|
165
|
-
|
166
|
-
newChildsLastElement = newChild._lastRecursiveChild()
|
167
|
-
|
168
|
-
if position >= len(self.contents):
|
169
|
-
newChild.nextSibling = None
|
170
|
-
|
171
|
-
parent = self
|
172
|
-
parentsNextSibling = None
|
173
|
-
while not parentsNextSibling:
|
174
|
-
parentsNextSibling = parent.nextSibling
|
175
|
-
parent = parent.parent
|
176
|
-
if not parent: # This is the last element in the document.
|
177
|
-
break
|
178
|
-
if parentsNextSibling:
|
179
|
-
newChildsLastElement.next = parentsNextSibling
|
180
|
-
else:
|
181
|
-
newChildsLastElement.next = None
|
182
|
-
else:
|
183
|
-
nextChild = self.contents[position]
|
184
|
-
newChild.nextSibling = nextChild
|
185
|
-
if newChild.nextSibling:
|
186
|
-
newChild.nextSibling.previousSibling = newChild
|
187
|
-
newChildsLastElement.next = nextChild
|
188
|
-
|
189
|
-
if newChildsLastElement.next:
|
190
|
-
newChildsLastElement.next.previous = newChildsLastElement
|
191
|
-
self.contents.insert(position, newChild)
|
192
|
-
|
193
|
-
def findNext(self, name=None, attrs={}, text=None, **kwargs):
|
194
|
-
"""Returns the first item that matches the given criteria and
|
195
|
-
appears after this Tag in the document."""
|
196
|
-
return self._findOne(self.findAllNext, name, attrs, text, **kwargs)
|
197
|
-
|
198
|
-
def findAllNext(self, name=None, attrs={}, text=None, limit=None,
|
199
|
-
**kwargs):
|
200
|
-
"""Returns all items that match the given criteria and appear
|
201
|
-
before after Tag in the document."""
|
202
|
-
return self._findAll(name, attrs, text, limit, self.nextGenerator)
|
203
|
-
|
204
|
-
def findNextSibling(self, name=None, attrs={}, text=None, **kwargs):
|
205
|
-
"""Returns the closest sibling to this Tag that matches the
|
206
|
-
given criteria and appears after this Tag in the document."""
|
207
|
-
return self._findOne(self.findNextSiblings, name, attrs, text,
|
208
|
-
**kwargs)
|
209
|
-
|
210
|
-
def findNextSiblings(self, name=None, attrs={}, text=None, limit=None,
|
211
|
-
**kwargs):
|
212
|
-
"""Returns the siblings of this Tag that match the given
|
213
|
-
criteria and appear after this Tag in the document."""
|
214
|
-
return self._findAll(name, attrs, text, limit,
|
215
|
-
self.nextSiblingGenerator, **kwargs)
|
216
|
-
fetchNextSiblings = findNextSiblings # Compatibility with pre-3.x
|
217
|
-
|
218
|
-
def findPrevious(self, name=None, attrs={}, text=None, **kwargs):
|
219
|
-
"""Returns the first item that matches the given criteria and
|
220
|
-
appears before this Tag in the document."""
|
221
|
-
return self._findOne(self.findAllPrevious, name, attrs, text, **kwargs)
|
222
|
-
|
223
|
-
def findAllPrevious(self, name=None, attrs={}, text=None, limit=None,
|
224
|
-
**kwargs):
|
225
|
-
"""Returns all items that match the given criteria and appear
|
226
|
-
before this Tag in the document."""
|
227
|
-
return self._findAll(name, attrs, text, limit, self.previousGenerator,
|
228
|
-
**kwargs)
|
229
|
-
fetchPrevious = findAllPrevious # Compatibility with pre-3.x
|
230
|
-
|
231
|
-
def findPreviousSibling(self, name=None, attrs={}, text=None, **kwargs):
|
232
|
-
"""Returns the closest sibling to this Tag that matches the
|
233
|
-
given criteria and appears before this Tag in the document."""
|
234
|
-
return self._findOne(self.findPreviousSiblings, name, attrs, text,
|
235
|
-
**kwargs)
|
236
|
-
|
237
|
-
def findPreviousSiblings(self, name=None, attrs={}, text=None,
|
238
|
-
limit=None, **kwargs):
|
239
|
-
"""Returns the siblings of this Tag that match the given
|
240
|
-
criteria and appear before this Tag in the document."""
|
241
|
-
return self._findAll(name, attrs, text, limit,
|
242
|
-
self.previousSiblingGenerator, **kwargs)
|
243
|
-
fetchPreviousSiblings = findPreviousSiblings # Compatibility with pre-3.x
|
244
|
-
|
245
|
-
def findParent(self, name=None, attrs={}, **kwargs):
|
246
|
-
"""Returns the closest parent of this Tag that matches the given
|
247
|
-
criteria."""
|
248
|
-
# NOTE: We can't use _findOne because findParents takes a different
|
249
|
-
# set of arguments.
|
250
|
-
r = None
|
251
|
-
l = self.findParents(name, attrs, 1)
|
252
|
-
if l:
|
253
|
-
r = l[0]
|
254
|
-
return r
|
255
|
-
|
256
|
-
def findParents(self, name=None, attrs={}, limit=None, **kwargs):
|
257
|
-
"""Returns the parents of this Tag that match the given
|
258
|
-
criteria."""
|
259
|
-
|
260
|
-
return self._findAll(name, attrs, None, limit, self.parentGenerator,
|
261
|
-
**kwargs)
|
262
|
-
fetchParents = findParents # Compatibility with pre-3.x
|
263
|
-
|
264
|
-
#These methods do the real heavy lifting.
|
265
|
-
|
266
|
-
def _findOne(self, method, name, attrs, text, **kwargs):
|
267
|
-
r = None
|
268
|
-
l = method(name, attrs, text, 1, **kwargs)
|
269
|
-
if l:
|
270
|
-
r = l[0]
|
271
|
-
return r
|
272
|
-
|
273
|
-
def _findAll(self, name, attrs, text, limit, generator, **kwargs):
|
274
|
-
"Iterates over a generator looking for things that match."
|
275
|
-
|
276
|
-
if isinstance(name, SoupStrainer):
|
277
|
-
strainer = name
|
278
|
-
else:
|
279
|
-
# Build a SoupStrainer
|
280
|
-
strainer = SoupStrainer(name, attrs, text, **kwargs)
|
281
|
-
results = ResultSet(strainer)
|
282
|
-
g = generator()
|
283
|
-
while True:
|
284
|
-
try:
|
285
|
-
i = g.next()
|
286
|
-
except StopIteration:
|
287
|
-
break
|
288
|
-
if i:
|
289
|
-
found = strainer.search(i)
|
290
|
-
if found:
|
291
|
-
results.append(found)
|
292
|
-
if limit and len(results) >= limit:
|
293
|
-
break
|
294
|
-
return results
|
295
|
-
|
296
|
-
#These Generators can be used to navigate starting from both
|
297
|
-
#NavigableStrings and Tags.
|
298
|
-
def nextGenerator(self):
|
299
|
-
i = self
|
300
|
-
while i:
|
301
|
-
i = i.next
|
302
|
-
yield i
|
303
|
-
|
304
|
-
def nextSiblingGenerator(self):
|
305
|
-
i = self
|
306
|
-
while i:
|
307
|
-
i = i.nextSibling
|
308
|
-
yield i
|
309
|
-
|
310
|
-
def previousGenerator(self):
|
311
|
-
i = self
|
312
|
-
while i:
|
313
|
-
i = i.previous
|
314
|
-
yield i
|
315
|
-
|
316
|
-
def previousSiblingGenerator(self):
|
317
|
-
i = self
|
318
|
-
while i:
|
319
|
-
i = i.previousSibling
|
320
|
-
yield i
|
321
|
-
|
322
|
-
def parentGenerator(self):
|
323
|
-
i = self
|
324
|
-
while i:
|
325
|
-
i = i.parent
|
326
|
-
yield i
|
327
|
-
|
328
|
-
# Utility methods
|
329
|
-
def substituteEncoding(self, str, encoding=None):
|
330
|
-
encoding = encoding or "utf-8"
|
331
|
-
return str.replace("%SOUP-ENCODING%", encoding)
|
332
|
-
|
333
|
-
def toEncoding(self, s, encoding=None):
|
334
|
-
"""Encodes an object to a string in some encoding, or to Unicode.
|
335
|
-
."""
|
336
|
-
if isinstance(s, unicode):
|
337
|
-
if encoding:
|
338
|
-
s = s.encode(encoding)
|
339
|
-
elif isinstance(s, str):
|
340
|
-
if encoding:
|
341
|
-
s = s.encode(encoding)
|
342
|
-
else:
|
343
|
-
s = unicode(s)
|
344
|
-
else:
|
345
|
-
if encoding:
|
346
|
-
s = self.toEncoding(str(s), encoding)
|
347
|
-
else:
|
348
|
-
s = unicode(s)
|
349
|
-
return s
|
350
|
-
|
351
|
-
class NavigableString(unicode, PageElement):
|
352
|
-
|
353
|
-
def __getattr__(self, attr):
|
354
|
-
"""text.string gives you text. This is for backwards
|
355
|
-
compatibility for Navigable*String, but for CData* it lets you
|
356
|
-
get the string without the CData wrapper."""
|
357
|
-
if attr == 'string':
|
358
|
-
return self
|
359
|
-
else:
|
360
|
-
raise AttributeError, "'%s' object has no attribute '%s'" % (self.__class__.__name__, attr)
|
361
|
-
|
362
|
-
def __unicode__(self):
|
363
|
-
return self.__str__(None)
|
364
|
-
|
365
|
-
def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING):
|
366
|
-
if encoding:
|
367
|
-
return self.encode(encoding)
|
368
|
-
else:
|
369
|
-
return self
|
370
|
-
|
371
|
-
class CData(NavigableString):
|
372
|
-
|
373
|
-
def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING):
|
374
|
-
return "<![CDATA[%s]]>" % NavigableString.__str__(self, encoding)
|
375
|
-
|
376
|
-
class ProcessingInstruction(NavigableString):
|
377
|
-
def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING):
|
378
|
-
output = self
|
379
|
-
if "%SOUP-ENCODING%" in output:
|
380
|
-
output = self.substituteEncoding(output, encoding)
|
381
|
-
return "<?%s?>" % self.toEncoding(output, encoding)
|
382
|
-
|
383
|
-
class Comment(NavigableString):
|
384
|
-
def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING):
|
385
|
-
return "<!--%s-->" % NavigableString.__str__(self, encoding)
|
386
|
-
|
387
|
-
class Declaration(NavigableString):
|
388
|
-
def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING):
|
389
|
-
return "<!%s>" % NavigableString.__str__(self, encoding)
|
390
|
-
|
391
|
-
class Tag(PageElement):
|
392
|
-
|
393
|
-
"""Represents a found HTML tag with its attributes and contents."""
|
394
|
-
|
395
|
-
XML_SPECIAL_CHARS_TO_ENTITIES = { "'" : "squot",
|
396
|
-
'"' : "quote",
|
397
|
-
"&" : "amp",
|
398
|
-
"<" : "lt",
|
399
|
-
">" : "gt" }
|
400
|
-
|
401
|
-
def __init__(self, parser, name, attrs=None, parent=None,
|
402
|
-
previous=None):
|
403
|
-
"Basic constructor."
|
404
|
-
|
405
|
-
# We don't actually store the parser object: that lets extracted
|
406
|
-
# chunks be garbage-collected
|
407
|
-
self.parserClass = parser.__class__
|
408
|
-
self.isSelfClosing = parser.isSelfClosingTag(name)
|
409
|
-
self.name = name
|
410
|
-
if attrs == None:
|
411
|
-
attrs = []
|
412
|
-
self.attrs = attrs
|
413
|
-
self.contents = []
|
414
|
-
self.setup(parent, previous)
|
415
|
-
self.hidden = False
|
416
|
-
self.containsSubstitutions = False
|
417
|
-
|
418
|
-
def get(self, key, default=None):
|
419
|
-
"""Returns the value of the 'key' attribute for the tag, or
|
420
|
-
the value given for 'default' if it doesn't have that
|
421
|
-
attribute."""
|
422
|
-
return self._getAttrMap().get(key, default)
|
423
|
-
|
424
|
-
def has_key(self, key):
|
425
|
-
return self._getAttrMap().has_key(key)
|
426
|
-
|
427
|
-
def __getitem__(self, key):
|
428
|
-
"""tag[key] returns the value of the 'key' attribute for the tag,
|
429
|
-
and throws an exception if it's not there."""
|
430
|
-
return self._getAttrMap()[key]
|
431
|
-
|
432
|
-
def __iter__(self):
|
433
|
-
"Iterating over a tag iterates over its contents."
|
434
|
-
return iter(self.contents)
|
435
|
-
|
436
|
-
def __len__(self):
|
437
|
-
"The length of a tag is the length of its list of contents."
|
438
|
-
return len(self.contents)
|
439
|
-
|
440
|
-
def __contains__(self, x):
|
441
|
-
return x in self.contents
|
442
|
-
|
443
|
-
def __nonzero__(self):
|
444
|
-
"A tag is non-None even if it has no contents."
|
445
|
-
return True
|
446
|
-
|
447
|
-
def __setitem__(self, key, value):
|
448
|
-
"""Setting tag[key] sets the value of the 'key' attribute for the
|
449
|
-
tag."""
|
450
|
-
self._getAttrMap()
|
451
|
-
self.attrMap[key] = value
|
452
|
-
found = False
|
453
|
-
for i in range(0, len(self.attrs)):
|
454
|
-
if self.attrs[i][0] == key:
|
455
|
-
self.attrs[i] = (key, value)
|
456
|
-
found = True
|
457
|
-
if not found:
|
458
|
-
self.attrs.append((key, value))
|
459
|
-
self._getAttrMap()[key] = value
|
460
|
-
|
461
|
-
def __delitem__(self, key):
|
462
|
-
"Deleting tag[key] deletes all 'key' attributes for the tag."
|
463
|
-
for item in self.attrs:
|
464
|
-
if item[0] == key:
|
465
|
-
self.attrs.remove(item)
|
466
|
-
#We don't break because bad HTML can define the same
|
467
|
-
#attribute multiple times.
|
468
|
-
self._getAttrMap()
|
469
|
-
if self.attrMap.has_key(key):
|
470
|
-
del self.attrMap[key]
|
471
|
-
|
472
|
-
def __call__(self, *args, **kwargs):
|
473
|
-
"""Calling a tag like a function is the same as calling its
|
474
|
-
findAll() method. Eg. tag('a') returns a list of all the A tags
|
475
|
-
found within this tag."""
|
476
|
-
return apply(self.findAll, args, kwargs)
|
477
|
-
|
478
|
-
def __getattr__(self, tag):
|
479
|
-
#print "Getattr %s.%s" % (self.__class__, tag)
|
480
|
-
if len(tag) > 3 and tag.rfind('Tag') == len(tag)-3:
|
481
|
-
return self.find(tag[:-3])
|
482
|
-
elif tag.find('__') != 0:
|
483
|
-
return self.find(tag)
|
484
|
-
|
485
|
-
def __eq__(self, other):
|
486
|
-
"""Returns true iff this tag has the same name, the same attributes,
|
487
|
-
and the same contents (recursively) as the given tag.
|
488
|
-
|
489
|
-
NOTE: right now this will return false if two tags have the
|
490
|
-
same attributes in a different order. Should this be fixed?"""
|
491
|
-
if not hasattr(other, 'name') or not hasattr(other, 'attrs') or not hasattr(other, 'contents') or self.name != other.name or self.attrs != other.attrs or len(self) != len(other):
|
492
|
-
return False
|
493
|
-
for i in range(0, len(self.contents)):
|
494
|
-
if self.contents[i] != other.contents[i]:
|
495
|
-
return False
|
496
|
-
return True
|
497
|
-
|
498
|
-
def __ne__(self, other):
|
499
|
-
"""Returns true iff this tag is not identical to the other tag,
|
500
|
-
as defined in __eq__."""
|
501
|
-
return not self == other
|
502
|
-
|
503
|
-
def __repr__(self, encoding=DEFAULT_OUTPUT_ENCODING):
|
504
|
-
"""Renders this tag as a string."""
|
505
|
-
return self.__str__(encoding)
|
506
|
-
|
507
|
-
def __unicode__(self):
|
508
|
-
return self.__str__(None)
|
509
|
-
|
510
|
-
def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING,
|
511
|
-
prettyPrint=False, indentLevel=0):
|
512
|
-
"""Returns a string or Unicode representation of this tag and
|
513
|
-
its contents. To get Unicode, pass None for encoding.
|
514
|
-
|
515
|
-
NOTE: since Python's HTML parser consumes whitespace, this
|
516
|
-
method is not certain to reproduce the whitespace present in
|
517
|
-
the original string."""
|
518
|
-
|
519
|
-
encodedName = self.toEncoding(self.name, encoding)
|
520
|
-
|
521
|
-
attrs = []
|
522
|
-
if self.attrs:
|
523
|
-
for key, val in self.attrs:
|
524
|
-
fmt = '%s="%s"'
|
525
|
-
if isString(val):
|
526
|
-
if self.containsSubstitutions and '%SOUP-ENCODING%' in val:
|
527
|
-
val = self.substituteEncoding(val, encoding)
|
528
|
-
|
529
|
-
# The attribute value either:
|
530
|
-
#
|
531
|
-
# * Contains no embedded double quotes or single quotes.
|
532
|
-
# No problem: we enclose it in double quotes.
|
533
|
-
# * Contains embedded single quotes. No problem:
|
534
|
-
# double quotes work here too.
|
535
|
-
# * Contains embedded double quotes. No problem:
|
536
|
-
# we enclose it in single quotes.
|
537
|
-
# * Embeds both single _and_ double quotes. This
|
538
|
-
# can't happen naturally, but it can happen if
|
539
|
-
# you modify an attribute value after parsing
|
540
|
-
# the document. Now we have a bit of a
|
541
|
-
# problem. We solve it by enclosing the
|
542
|
-
# attribute in single quotes, and escaping any
|
543
|
-
# embedded single quotes to XML entities.
|
544
|
-
if '"' in val:
|
545
|
-
fmt = "%s='%s'"
|
546
|
-
# This can't happen naturally, but it can happen
|
547
|
-
# if you modify an attribute value after parsing.
|
548
|
-
if "'" in val:
|
549
|
-
val = val.replace("'", "&squot;")
|
550
|
-
|
551
|
-
# Now we're okay w/r/t quotes. But the attribute
|
552
|
-
# value might also contain angle brackets, or
|
553
|
-
# ampersands that aren't part of entities. We need
|
554
|
-
# to escape those to XML entities too.
|
555
|
-
val = re.sub("([<>]|&(?![^\s]+;))",
|
556
|
-
lambda x: "&" + self.XML_SPECIAL_CHARS_TO_ENTITIES[x.group(0)[0]] + ";",
|
557
|
-
val)
|
558
|
-
|
559
|
-
attrs.append(fmt % (self.toEncoding(key, encoding),
|
560
|
-
self.toEncoding(val, encoding)))
|
561
|
-
close = ''
|
562
|
-
closeTag = ''
|
563
|
-
if self.isSelfClosing:
|
564
|
-
close = ' /'
|
565
|
-
else:
|
566
|
-
closeTag = '</%s>' % encodedName
|
567
|
-
|
568
|
-
indentTag, indentContents = 0, 0
|
569
|
-
if prettyPrint:
|
570
|
-
indentTag = indentLevel
|
571
|
-
space = (' ' * (indentTag-1))
|
572
|
-
indentContents = indentTag + 1
|
573
|
-
contents = self.renderContents(encoding, prettyPrint, indentContents)
|
574
|
-
if self.hidden:
|
575
|
-
s = contents
|
576
|
-
else:
|
577
|
-
s = []
|
578
|
-
attributeString = ''
|
579
|
-
if attrs:
|
580
|
-
attributeString = ' ' + ' '.join(attrs)
|
581
|
-
if prettyPrint:
|
582
|
-
s.append(space)
|
583
|
-
s.append('<%s%s%s>' % (encodedName, attributeString, close))
|
584
|
-
if prettyPrint:
|
585
|
-
s.append("\n")
|
586
|
-
s.append(contents)
|
587
|
-
if prettyPrint and contents and contents[-1] != "\n":
|
588
|
-
s.append("\n")
|
589
|
-
if prettyPrint and closeTag:
|
590
|
-
s.append(space)
|
591
|
-
s.append(closeTag)
|
592
|
-
if prettyPrint and closeTag and self.nextSibling:
|
593
|
-
s.append("\n")
|
594
|
-
s = ''.join(s)
|
595
|
-
return s
|
596
|
-
|
597
|
-
def prettify(self, encoding=DEFAULT_OUTPUT_ENCODING):
|
598
|
-
return self.__str__(encoding, True)
|
599
|
-
|
600
|
-
def renderContents(self, encoding=DEFAULT_OUTPUT_ENCODING,
|
601
|
-
prettyPrint=False, indentLevel=0):
|
602
|
-
"""Renders the contents of this tag as a string in the given
|
603
|
-
encoding. If encoding is None, returns a Unicode string.."""
|
604
|
-
s=[]
|
605
|
-
for c in self:
|
606
|
-
text = None
|
607
|
-
if isinstance(c, NavigableString):
|
608
|
-
text = c.__str__(encoding)
|
609
|
-
elif isinstance(c, Tag):
|
610
|
-
s.append(c.__str__(encoding, prettyPrint, indentLevel))
|
611
|
-
if text and prettyPrint:
|
612
|
-
text = text.strip()
|
613
|
-
if text:
|
614
|
-
if prettyPrint:
|
615
|
-
s.append(" " * (indentLevel-1))
|
616
|
-
s.append(text)
|
617
|
-
if prettyPrint:
|
618
|
-
s.append("\n")
|
619
|
-
return ''.join(s)
|
620
|
-
|
621
|
-
#Soup methods
|
622
|
-
|
623
|
-
def find(self, name=None, attrs={}, recursive=True, text=None,
|
624
|
-
**kwargs):
|
625
|
-
"""Return only the first child of this Tag matching the given
|
626
|
-
criteria."""
|
627
|
-
r = None
|
628
|
-
l = self.findAll(name, attrs, recursive, text, 1, **kwargs)
|
629
|
-
if l:
|
630
|
-
r = l[0]
|
631
|
-
return r
|
632
|
-
findChild = find
|
633
|
-
|
634
|
-
def findAll(self, name=None, attrs={}, recursive=True, text=None,
|
635
|
-
limit=None, **kwargs):
|
636
|
-
"""Extracts a list of Tag objects that match the given
|
637
|
-
criteria. You can specify the name of the Tag and any
|
638
|
-
attributes you want the Tag to have.
|
639
|
-
|
640
|
-
The value of a key-value pair in the 'attrs' map can be a
|
641
|
-
string, a list of strings, a regular expression object, or a
|
642
|
-
callable that takes a string and returns whether or not the
|
643
|
-
string matches for some custom definition of 'matches'. The
|
644
|
-
same is true of the tag name."""
|
645
|
-
generator = self.recursiveChildGenerator
|
646
|
-
if not recursive:
|
647
|
-
generator = self.childGenerator
|
648
|
-
return self._findAll(name, attrs, text, limit, generator, **kwargs)
|
649
|
-
findChildren = findAll
|
650
|
-
|
651
|
-
# Pre-3.x compatibility methods
|
652
|
-
first = find
|
653
|
-
fetch = findAll
|
654
|
-
|
655
|
-
def fetchText(self, text=None, recursive=True, limit=None):
|
656
|
-
return self.findAll(text=text, recursive=recursive, limit=limit)
|
657
|
-
|
658
|
-
def firstText(self, text=None, recursive=True):
|
659
|
-
return self.find(text=text, recursive=recursive)
|
660
|
-
|
661
|
-
#Utility methods
|
662
|
-
|
663
|
-
def append(self, tag):
|
664
|
-
"""Appends the given tag to the contents of this tag."""
|
665
|
-
self.contents.append(tag)
|
666
|
-
|
667
|
-
#Private methods
|
668
|
-
|
669
|
-
def _getAttrMap(self):
|
670
|
-
"""Initializes a map representation of this tag's attributes,
|
671
|
-
if not already initialized."""
|
672
|
-
if not getattr(self, 'attrMap'):
|
673
|
-
self.attrMap = {}
|
674
|
-
for (key, value) in self.attrs:
|
675
|
-
self.attrMap[key] = value
|
676
|
-
return self.attrMap
|
677
|
-
|
678
|
-
#Generator methods
|
679
|
-
def childGenerator(self):
|
680
|
-
for i in range(0, len(self.contents)):
|
681
|
-
yield self.contents[i]
|
682
|
-
raise StopIteration
|
683
|
-
|
684
|
-
def recursiveChildGenerator(self):
|
685
|
-
stack = [(self, 0)]
|
686
|
-
while stack:
|
687
|
-
tag, start = stack.pop()
|
688
|
-
if isinstance(tag, Tag):
|
689
|
-
for i in range(start, len(tag.contents)):
|
690
|
-
a = tag.contents[i]
|
691
|
-
yield a
|
692
|
-
if isinstance(a, Tag) and tag.contents:
|
693
|
-
if i < len(tag.contents) - 1:
|
694
|
-
stack.append((tag, i+1))
|
695
|
-
stack.append((a, 0))
|
696
|
-
break
|
697
|
-
raise StopIteration
|
698
|
-
|
699
|
-
# Next, a couple classes to represent queries and their results.
|
700
|
-
class SoupStrainer:
|
701
|
-
"""Encapsulates a number of ways of matching a markup element (tag or
|
702
|
-
text)."""
|
703
|
-
|
704
|
-
def __init__(self, name=None, attrs={}, text=None, **kwargs):
|
705
|
-
self.name = name
|
706
|
-
if isString(attrs):
|
707
|
-
kwargs['class'] = attrs
|
708
|
-
attrs = None
|
709
|
-
if kwargs:
|
710
|
-
if attrs:
|
711
|
-
attrs = attrs.copy()
|
712
|
-
attrs.update(kwargs)
|
713
|
-
else:
|
714
|
-
attrs = kwargs
|
715
|
-
self.attrs = attrs
|
716
|
-
self.text = text
|
717
|
-
|
718
|
-
def __str__(self):
|
719
|
-
if self.text:
|
720
|
-
return self.text
|
721
|
-
else:
|
722
|
-
return "%s|%s" % (self.name, self.attrs)
|
723
|
-
|
724
|
-
def searchTag(self, markupName=None, markupAttrs={}):
|
725
|
-
found = None
|
726
|
-
markup = None
|
727
|
-
if isinstance(markupName, Tag):
|
728
|
-
markup = markupName
|
729
|
-
markupAttrs = markup
|
730
|
-
callFunctionWithTagData = callable(self.name) \
|
731
|
-
and not isinstance(markupName, Tag)
|
732
|
-
|
733
|
-
if (not self.name) \
|
734
|
-
or callFunctionWithTagData \
|
735
|
-
or (markup and self._matches(markup, self.name)) \
|
736
|
-
or (not markup and self._matches(markupName, self.name)):
|
737
|
-
if callFunctionWithTagData:
|
738
|
-
match = self.name(markupName, markupAttrs)
|
739
|
-
else:
|
740
|
-
match = True
|
741
|
-
markupAttrMap = None
|
742
|
-
for attr, matchAgainst in self.attrs.items():
|
743
|
-
if not markupAttrMap:
|
744
|
-
if hasattr(markupAttrs, 'get'):
|
745
|
-
markupAttrMap = markupAttrs
|
746
|
-
else:
|
747
|
-
markupAttrMap = {}
|
748
|
-
for k,v in markupAttrs:
|
749
|
-
markupAttrMap[k] = v
|
750
|
-
attrValue = markupAttrMap.get(attr)
|
751
|
-
if not self._matches(attrValue, matchAgainst):
|
752
|
-
match = False
|
753
|
-
break
|
754
|
-
if match:
|
755
|
-
if markup:
|
756
|
-
found = markup
|
757
|
-
else:
|
758
|
-
found = markupName
|
759
|
-
return found
|
760
|
-
|
761
|
-
def search(self, markup):
|
762
|
-
#print 'looking for %s in %s' % (self, markup)
|
763
|
-
found = None
|
764
|
-
# If given a list of items, scan it for a text element that
|
765
|
-
# matches.
|
766
|
-
if isList(markup) and not isinstance(markup, Tag):
|
767
|
-
for element in markup:
|
768
|
-
if isinstance(element, NavigableString) \
|
769
|
-
and self.search(element):
|
770
|
-
found = element
|
771
|
-
break
|
772
|
-
# If it's a Tag, make sure its name or attributes match.
|
773
|
-
# Don't bother with Tags if we're searching for text.
|
774
|
-
elif isinstance(markup, Tag):
|
775
|
-
if not self.text:
|
776
|
-
found = self.searchTag(markup)
|
777
|
-
# If it's text, make sure the text matches.
|
778
|
-
elif isinstance(markup, NavigableString) or \
|
779
|
-
isString(markup):
|
780
|
-
if self._matches(markup, self.text):
|
781
|
-
found = markup
|
782
|
-
else:
|
783
|
-
raise Exception, "I don't know how to match against a %s" \
|
784
|
-
% markup.__class__
|
785
|
-
return found
|
786
|
-
|
787
|
-
def _matches(self, markup, matchAgainst):
|
788
|
-
#print "Matching %s against %s" % (markup, matchAgainst)
|
789
|
-
result = False
|
790
|
-
if matchAgainst == True and type(matchAgainst) == types.BooleanType:
|
791
|
-
result = markup != None
|
792
|
-
elif callable(matchAgainst):
|
793
|
-
result = matchAgainst(markup)
|
794
|
-
else:
|
795
|
-
#Custom match methods take the tag as an argument, but all
|
796
|
-
#other ways of matching match the tag name as a string.
|
797
|
-
if isinstance(markup, Tag):
|
798
|
-
markup = markup.name
|
799
|
-
if markup and not isString(markup):
|
800
|
-
markup = unicode(markup)
|
801
|
-
#Now we know that chunk is either a string, or None.
|
802
|
-
if hasattr(matchAgainst, 'match'):
|
803
|
-
# It's a regexp object.
|
804
|
-
result = markup and matchAgainst.search(markup)
|
805
|
-
elif isList(matchAgainst):
|
806
|
-
result = markup in matchAgainst
|
807
|
-
elif hasattr(matchAgainst, 'items'):
|
808
|
-
result = markup.has_key(matchAgainst)
|
809
|
-
elif matchAgainst and isString(markup):
|
810
|
-
if isinstance(markup, unicode):
|
811
|
-
matchAgainst = unicode(matchAgainst)
|
812
|
-
else:
|
813
|
-
matchAgainst = str(matchAgainst)
|
814
|
-
|
815
|
-
if not result:
|
816
|
-
result = matchAgainst == markup
|
817
|
-
return result
|
818
|
-
|
819
|
-
class ResultSet(list):
|
820
|
-
"""A ResultSet is just a list that keeps track of the SoupStrainer
|
821
|
-
that created it."""
|
822
|
-
def __init__(self, source):
|
823
|
-
list.__init__([])
|
824
|
-
self.source = source
|
825
|
-
|
826
|
-
# Now, some helper functions.
|
827
|
-
|
828
|
-
def isList(l):
|
829
|
-
"""Convenience method that works with all 2.x versions of Python
|
830
|
-
to determine whether or not something is listlike."""
|
831
|
-
return hasattr(l, '__iter__') \
|
832
|
-
or (type(l) in (types.ListType, types.TupleType))
|
833
|
-
|
834
|
-
def isString(s):
|
835
|
-
"""Convenience method that works with all 2.x versions of Python
|
836
|
-
to determine whether or not something is stringlike."""
|
837
|
-
try:
|
838
|
-
return isinstance(s, unicode) or isintance(s, basestring)
|
839
|
-
except NameError:
|
840
|
-
return isinstance(s, str)
|
841
|
-
|
842
|
-
def buildTagMap(default, *args):
|
843
|
-
"""Turns a list of maps, lists, or scalars into a single map.
|
844
|
-
Used to build the SELF_CLOSING_TAGS, NESTABLE_TAGS, and
|
845
|
-
NESTING_RESET_TAGS maps out of lists and partial maps."""
|
846
|
-
built = {}
|
847
|
-
for portion in args:
|
848
|
-
if hasattr(portion, 'items'):
|
849
|
-
#It's a map. Merge it.
|
850
|
-
for k,v in portion.items():
|
851
|
-
built[k] = v
|
852
|
-
elif isList(portion):
|
853
|
-
#It's a list. Map each item to the default.
|
854
|
-
for k in portion:
|
855
|
-
built[k] = default
|
856
|
-
else:
|
857
|
-
#It's a scalar. Map it to the default.
|
858
|
-
built[portion] = default
|
859
|
-
return built
|
860
|
-
|
861
|
-
# Now, the parser classes.
|
862
|
-
|
863
|
-
class BeautifulStoneSoup(Tag, SGMLParser):
|
864
|
-
|
865
|
-
"""This class contains the basic parser and search code. It defines
|
866
|
-
a parser that knows nothing about tag behavior except for the
|
867
|
-
following:
|
868
|
-
|
869
|
-
You can't close a tag without closing all the tags it encloses.
|
870
|
-
That is, "<foo><bar></foo>" actually means
|
871
|
-
"<foo><bar></bar></foo>".
|
872
|
-
|
873
|
-
[Another possible explanation is "<foo><bar /></foo>", but since
|
874
|
-
this class defines no SELF_CLOSING_TAGS, it will never use that
|
875
|
-
explanation.]
|
876
|
-
|
877
|
-
This class is useful for parsing XML or made-up markup languages,
|
878
|
-
or when BeautifulSoup makes an assumption counter to what you were
|
879
|
-
expecting."""
|
880
|
-
|
881
|
-
XML_ENTITY_LIST = {}
|
882
|
-
for i in Tag.XML_SPECIAL_CHARS_TO_ENTITIES.values():
|
883
|
-
XML_ENTITY_LIST[i] = True
|
884
|
-
|
885
|
-
SELF_CLOSING_TAGS = {}
|
886
|
-
NESTABLE_TAGS = {}
|
887
|
-
RESET_NESTING_TAGS = {}
|
888
|
-
QUOTE_TAGS = {}
|
889
|
-
|
890
|
-
MARKUP_MASSAGE = [(re.compile('(<[^<>]*)/>'),
|
891
|
-
lambda x: x.group(1) + ' />'),
|
892
|
-
(re.compile('<!\s+([^<>]*)>'),
|
893
|
-
lambda x: '<!' + x.group(1) + '>')
|
894
|
-
]
|
895
|
-
|
896
|
-
ROOT_TAG_NAME = u'[document]'
|
897
|
-
|
898
|
-
HTML_ENTITIES = "html"
|
899
|
-
XML_ENTITIES = "xml"
|
900
|
-
|
901
|
-
def __init__(self, markup="", parseOnlyThese=None, fromEncoding=None,
|
902
|
-
markupMassage=True, smartQuotesTo=XML_ENTITIES,
|
903
|
-
convertEntities=None, selfClosingTags=None):
|
904
|
-
"""The Soup object is initialized as the 'root tag', and the
|
905
|
-
provided markup (which can be a string or a file-like object)
|
906
|
-
is fed into the underlying parser.
|
907
|
-
|
908
|
-
sgmllib will process most bad HTML, and the BeautifulSoup
|
909
|
-
class has some tricks for dealing with some HTML that kills
|
910
|
-
sgmllib, but Beautiful Soup can nonetheless choke or lose data
|
911
|
-
if your data uses self-closing tags or declarations
|
912
|
-
incorrectly.
|
913
|
-
|
914
|
-
By default, Beautiful Soup uses regexes to sanitize input,
|
915
|
-
avoiding the vast majority of these problems. If the problems
|
916
|
-
don't apply to you, pass in False for markupMassage, and
|
917
|
-
you'll get better performance.
|
918
|
-
|
919
|
-
The default parser massage techniques fix the two most common
|
920
|
-
instances of invalid HTML that choke sgmllib:
|
921
|
-
|
922
|
-
<br/> (No space between name of closing tag and tag close)
|
923
|
-
<! --Comment--> (Extraneous whitespace in declaration)
|
924
|
-
|
925
|
-
You can pass in a custom list of (RE object, replace method)
|
926
|
-
tuples to get Beautiful Soup to scrub your input the way you
|
927
|
-
want."""
|
928
|
-
|
929
|
-
self.parseOnlyThese = parseOnlyThese
|
930
|
-
self.fromEncoding = fromEncoding
|
931
|
-
self.smartQuotesTo = smartQuotesTo
|
932
|
-
self.convertEntities = convertEntities
|
933
|
-
if self.convertEntities:
|
934
|
-
# It doesn't make sense to convert encoded characters to
|
935
|
-
# entities even while you're converting entities to Unicode.
|
936
|
-
# Just convert it all to Unicode.
|
937
|
-
self.smartQuotesTo = None
|
938
|
-
self.instanceSelfClosingTags = buildTagMap(None, selfClosingTags)
|
939
|
-
SGMLParser.__init__(self)
|
940
|
-
|
941
|
-
if hasattr(markup, 'read'): # It's a file-type object.
|
942
|
-
markup = markup.read()
|
943
|
-
self.markup = markup
|
944
|
-
self.markupMassage = markupMassage
|
945
|
-
try:
|
946
|
-
self._feed()
|
947
|
-
except StopParsing:
|
948
|
-
pass
|
949
|
-
self.markup = None # The markup can now be GCed
|
950
|
-
|
951
|
-
def _feed(self, inDocumentEncoding=None):
|
952
|
-
# Convert the document to Unicode.
|
953
|
-
markup = self.markup
|
954
|
-
if isinstance(markup, unicode):
|
955
|
-
if not hasattr(self, 'originalEncoding'):
|
956
|
-
self.originalEncoding = None
|
957
|
-
else:
|
958
|
-
dammit = UnicodeDammit\
|
959
|
-
(markup, [self.fromEncoding, inDocumentEncoding],
|
960
|
-
smartQuotesTo=self.smartQuotesTo)
|
961
|
-
markup = dammit.unicode
|
962
|
-
self.originalEncoding = dammit.originalEncoding
|
963
|
-
if markup:
|
964
|
-
if self.markupMassage:
|
965
|
-
if not isList(self.markupMassage):
|
966
|
-
self.markupMassage = self.MARKUP_MASSAGE
|
967
|
-
for fix, m in self.markupMassage:
|
968
|
-
markup = fix.sub(m, markup)
|
969
|
-
self.reset()
|
970
|
-
|
971
|
-
SGMLParser.feed(self, markup)
|
972
|
-
# Close out any unfinished strings and close all the open tags.
|
973
|
-
self.endData()
|
974
|
-
while self.currentTag.name != self.ROOT_TAG_NAME:
|
975
|
-
self.popTag()
|
976
|
-
|
977
|
-
def __getattr__(self, methodName):
|
978
|
-
"""This method routes method call requests to either the SGMLParser
|
979
|
-
superclass or the Tag superclass, depending on the method name."""
|
980
|
-
#print "__getattr__ called on %s.%s" % (self.__class__, methodName)
|
981
|
-
|
982
|
-
if methodName.find('start_') == 0 or methodName.find('end_') == 0 \
|
983
|
-
or methodName.find('do_') == 0:
|
984
|
-
return SGMLParser.__getattr__(self, methodName)
|
985
|
-
elif methodName.find('__') != 0:
|
986
|
-
return Tag.__getattr__(self, methodName)
|
987
|
-
else:
|
988
|
-
raise AttributeError
|
989
|
-
|
990
|
-
def isSelfClosingTag(self, name):
|
991
|
-
"""Returns true iff the given string is the name of a
|
992
|
-
self-closing tag according to this parser."""
|
993
|
-
return self.SELF_CLOSING_TAGS.has_key(name) \
|
994
|
-
or self.instanceSelfClosingTags.has_key(name)
|
995
|
-
|
996
|
-
def reset(self):
|
997
|
-
Tag.__init__(self, self, self.ROOT_TAG_NAME)
|
998
|
-
self.hidden = 1
|
999
|
-
SGMLParser.reset(self)
|
1000
|
-
self.currentData = []
|
1001
|
-
self.currentTag = None
|
1002
|
-
self.tagStack = []
|
1003
|
-
self.quoteStack = []
|
1004
|
-
self.pushTag(self)
|
1005
|
-
|
1006
|
-
def popTag(self):
|
1007
|
-
tag = self.tagStack.pop()
|
1008
|
-
# Tags with just one string-owning child get the child as a
|
1009
|
-
# 'string' property, so that soup.tag.string is shorthand for
|
1010
|
-
# soup.tag.contents[0]
|
1011
|
-
if len(self.currentTag.contents) == 1 and \
|
1012
|
-
isinstance(self.currentTag.contents[0], NavigableString):
|
1013
|
-
self.currentTag.string = self.currentTag.contents[0]
|
1014
|
-
|
1015
|
-
#print "Pop", tag.name
|
1016
|
-
if self.tagStack:
|
1017
|
-
self.currentTag = self.tagStack[-1]
|
1018
|
-
return self.currentTag
|
1019
|
-
|
1020
|
-
def pushTag(self, tag):
|
1021
|
-
#print "Push", tag.name
|
1022
|
-
if self.currentTag:
|
1023
|
-
self.currentTag.append(tag)
|
1024
|
-
self.tagStack.append(tag)
|
1025
|
-
self.currentTag = self.tagStack[-1]
|
1026
|
-
|
1027
|
-
def endData(self, containerClass=NavigableString):
|
1028
|
-
if self.currentData:
|
1029
|
-
currentData = ''.join(self.currentData)
|
1030
|
-
if not currentData.strip():
|
1031
|
-
if '\n' in currentData:
|
1032
|
-
currentData = '\n'
|
1033
|
-
else:
|
1034
|
-
currentData = ' '
|
1035
|
-
self.currentData = []
|
1036
|
-
if self.parseOnlyThese and len(self.tagStack) <= 1 and \
|
1037
|
-
(not self.parseOnlyThese.text or \
|
1038
|
-
not self.parseOnlyThese.search(currentData)):
|
1039
|
-
return
|
1040
|
-
o = containerClass(currentData)
|
1041
|
-
o.setup(self.currentTag, self.previous)
|
1042
|
-
if self.previous:
|
1043
|
-
self.previous.next = o
|
1044
|
-
self.previous = o
|
1045
|
-
self.currentTag.contents.append(o)
|
1046
|
-
|
1047
|
-
|
1048
|
-
def _popToTag(self, name, inclusivePop=True):
|
1049
|
-
"""Pops the tag stack up to and including the most recent
|
1050
|
-
instance of the given tag. If inclusivePop is false, pops the tag
|
1051
|
-
stack up to but *not* including the most recent instqance of
|
1052
|
-
the given tag."""
|
1053
|
-
#print "Popping to %s" % name
|
1054
|
-
if name == self.ROOT_TAG_NAME:
|
1055
|
-
return
|
1056
|
-
|
1057
|
-
numPops = 0
|
1058
|
-
mostRecentTag = None
|
1059
|
-
for i in range(len(self.tagStack)-1, 0, -1):
|
1060
|
-
if name == self.tagStack[i].name:
|
1061
|
-
numPops = len(self.tagStack)-i
|
1062
|
-
break
|
1063
|
-
if not inclusivePop:
|
1064
|
-
numPops = numPops - 1
|
1065
|
-
|
1066
|
-
for i in range(0, numPops):
|
1067
|
-
mostRecentTag = self.popTag()
|
1068
|
-
return mostRecentTag
|
1069
|
-
|
1070
|
-
def _smartPop(self, name):
|
1071
|
-
|
1072
|
-
"""We need to pop up to the previous tag of this type, unless
|
1073
|
-
one of this tag's nesting reset triggers comes between this
|
1074
|
-
tag and the previous tag of this type, OR unless this tag is a
|
1075
|
-
generic nesting trigger and another generic nesting trigger
|
1076
|
-
comes between this tag and the previous tag of this type.
|
1077
|
-
|
1078
|
-
Examples:
|
1079
|
-
<p>Foo<b>Bar<p> should pop to 'p', not 'b'.
|
1080
|
-
<p>Foo<table>Bar<p> should pop to 'table', not 'p'.
|
1081
|
-
<p>Foo<table><tr>Bar<p> should pop to 'tr', not 'p'.
|
1082
|
-
<p>Foo<b>Bar<p> should pop to 'p', not 'b'.
|
1083
|
-
|
1084
|
-
<li><ul><li> *<li>* should pop to 'ul', not the first 'li'.
|
1085
|
-
<tr><table><tr> *<tr>* should pop to 'table', not the first 'tr'
|
1086
|
-
<td><tr><td> *<td>* should pop to 'tr', not the first 'td'
|
1087
|
-
"""
|
1088
|
-
|
1089
|
-
nestingResetTriggers = self.NESTABLE_TAGS.get(name)
|
1090
|
-
isNestable = nestingResetTriggers != None
|
1091
|
-
isResetNesting = self.RESET_NESTING_TAGS.has_key(name)
|
1092
|
-
popTo = None
|
1093
|
-
inclusive = True
|
1094
|
-
for i in range(len(self.tagStack)-1, 0, -1):
|
1095
|
-
p = self.tagStack[i]
|
1096
|
-
if (not p or p.name == name) and not isNestable:
|
1097
|
-
#Non-nestable tags get popped to the top or to their
|
1098
|
-
#last occurance.
|
1099
|
-
popTo = name
|
1100
|
-
break
|
1101
|
-
if (nestingResetTriggers != None
|
1102
|
-
and p.name in nestingResetTriggers) \
|
1103
|
-
or (nestingResetTriggers == None and isResetNesting
|
1104
|
-
and self.RESET_NESTING_TAGS.has_key(p.name)):
|
1105
|
-
|
1106
|
-
#If we encounter one of the nesting reset triggers
|
1107
|
-
#peculiar to this tag, or we encounter another tag
|
1108
|
-
#that causes nesting to reset, pop up to but not
|
1109
|
-
#including that tag.
|
1110
|
-
popTo = p.name
|
1111
|
-
inclusive = False
|
1112
|
-
break
|
1113
|
-
p = p.parent
|
1114
|
-
if popTo:
|
1115
|
-
self._popToTag(popTo, inclusive)
|
1116
|
-
|
1117
|
-
def unknown_starttag(self, name, attrs, selfClosing=0):
|
1118
|
-
#print "Start tag %s: %s" % (name, attrs)
|
1119
|
-
if self.quoteStack:
|
1120
|
-
#This is not a real tag.
|
1121
|
-
#print "<%s> is not real!" % name
|
1122
|
-
attrs = ''.join(map(lambda(x, y): ' %s="%s"' % (x, y), attrs))
|
1123
|
-
self.handle_data('<%s%s>' % (name, attrs))
|
1124
|
-
return
|
1125
|
-
self.endData()
|
1126
|
-
|
1127
|
-
if not self.isSelfClosingTag(name) and not selfClosing:
|
1128
|
-
self._smartPop(name)
|
1129
|
-
|
1130
|
-
if self.parseOnlyThese and len(self.tagStack) <= 1 \
|
1131
|
-
and (self.parseOnlyThese.text or not self.parseOnlyThese.searchTag(name, attrs)):
|
1132
|
-
return
|
1133
|
-
|
1134
|
-
tag = Tag(self, name, attrs, self.currentTag, self.previous)
|
1135
|
-
if self.previous:
|
1136
|
-
self.previous.next = tag
|
1137
|
-
self.previous = tag
|
1138
|
-
self.pushTag(tag)
|
1139
|
-
if selfClosing or self.isSelfClosingTag(name):
|
1140
|
-
self.popTag()
|
1141
|
-
if name in self.QUOTE_TAGS:
|
1142
|
-
#print "Beginning quote (%s)" % name
|
1143
|
-
self.quoteStack.append(name)
|
1144
|
-
self.literal = 1
|
1145
|
-
return tag
|
1146
|
-
|
1147
|
-
def unknown_endtag(self, name):
|
1148
|
-
#print "End tag %s" % name
|
1149
|
-
if self.quoteStack and self.quoteStack[-1] != name:
|
1150
|
-
#This is not a real end tag.
|
1151
|
-
#print "</%s> is not real!" % name
|
1152
|
-
self.handle_data('</%s>' % name)
|
1153
|
-
return
|
1154
|
-
self.endData()
|
1155
|
-
self._popToTag(name)
|
1156
|
-
if self.quoteStack and self.quoteStack[-1] == name:
|
1157
|
-
self.quoteStack.pop()
|
1158
|
-
self.literal = (len(self.quoteStack) > 0)
|
1159
|
-
|
1160
|
-
def handle_data(self, data):
|
1161
|
-
self.currentData.append(data)
|
1162
|
-
|
1163
|
-
def _toStringSubclass(self, text, subclass):
|
1164
|
-
"""Adds a certain piece of text to the tree as a NavigableString
|
1165
|
-
subclass."""
|
1166
|
-
self.endData()
|
1167
|
-
self.handle_data(text)
|
1168
|
-
self.endData(subclass)
|
1169
|
-
|
1170
|
-
def handle_pi(self, text):
|
1171
|
-
"""Handle a processing instruction as a ProcessingInstruction
|
1172
|
-
object, possibly one with a %SOUP-ENCODING% slot into which an
|
1173
|
-
encoding will be plugged later."""
|
1174
|
-
if text[:3] == "xml":
|
1175
|
-
text = "xml version='1.0' encoding='%SOUP-ENCODING%'"
|
1176
|
-
self._toStringSubclass(text, ProcessingInstruction)
|
1177
|
-
|
1178
|
-
def handle_comment(self, text):
|
1179
|
-
"Handle comments as Comment objects."
|
1180
|
-
self._toStringSubclass(text, Comment)
|
1181
|
-
|
1182
|
-
def handle_charref(self, ref):
|
1183
|
-
"Handle character references as data."
|
1184
|
-
if self.convertEntities in [self.HTML_ENTITIES,
|
1185
|
-
self.XML_ENTITIES]:
|
1186
|
-
data = unichr(int(ref))
|
1187
|
-
else:
|
1188
|
-
data = '&#%s;' % ref
|
1189
|
-
self.handle_data(data)
|
1190
|
-
|
1191
|
-
def handle_entityref(self, ref):
|
1192
|
-
"""Handle entity references as data, possibly converting known
|
1193
|
-
HTML entity references to the corresponding Unicode
|
1194
|
-
characters."""
|
1195
|
-
data = None
|
1196
|
-
if self.convertEntities == self.HTML_ENTITIES or \
|
1197
|
-
(self.convertEntities == self.XML_ENTITIES and \
|
1198
|
-
self.XML_ENTITY_LIST.get(ref)):
|
1199
|
-
try:
|
1200
|
-
data = unichr(name2codepoint[ref])
|
1201
|
-
except KeyError:
|
1202
|
-
pass
|
1203
|
-
if not data:
|
1204
|
-
data = '&%s;' % ref
|
1205
|
-
self.handle_data(data)
|
1206
|
-
|
1207
|
-
def handle_decl(self, data):
|
1208
|
-
"Handle DOCTYPEs and the like as Declaration objects."
|
1209
|
-
self._toStringSubclass(data, Declaration)
|
1210
|
-
|
1211
|
-
def parse_declaration(self, i):
|
1212
|
-
"""Treat a bogus SGML declaration as raw data. Treat a CDATA
|
1213
|
-
declaration as a CData object."""
|
1214
|
-
j = None
|
1215
|
-
if self.rawdata[i:i+9] == '<![CDATA[':
|
1216
|
-
k = self.rawdata.find(']]>', i)
|
1217
|
-
if k == -1:
|
1218
|
-
k = len(self.rawdata)
|
1219
|
-
data = self.rawdata[i+9:k]
|
1220
|
-
j = k+3
|
1221
|
-
self._toStringSubclass(data, CData)
|
1222
|
-
else:
|
1223
|
-
try:
|
1224
|
-
j = SGMLParser.parse_declaration(self, i)
|
1225
|
-
except SGMLParseError:
|
1226
|
-
toHandle = self.rawdata[i:]
|
1227
|
-
self.handle_data(toHandle)
|
1228
|
-
j = i + len(toHandle)
|
1229
|
-
return j
|
1230
|
-
|
1231
|
-
class BeautifulSoup(BeautifulStoneSoup):
|
1232
|
-
|
1233
|
-
"""This parser knows the following facts about HTML:
|
1234
|
-
|
1235
|
-
* Some tags have no closing tag and should be interpreted as being
|
1236
|
-
closed as soon as they are encountered.
|
1237
|
-
|
1238
|
-
* The text inside some tags (ie. 'script') may contain tags which
|
1239
|
-
are not really part of the document and which should be parsed
|
1240
|
-
as text, not tags. If you want to parse the text as tags, you can
|
1241
|
-
always fetch it and parse it explicitly.
|
1242
|
-
|
1243
|
-
* Tag nesting rules:
|
1244
|
-
|
1245
|
-
Most tags can't be nested at all. For instance, the occurance of
|
1246
|
-
a <p> tag should implicitly close the previous <p> tag.
|
1247
|
-
|
1248
|
-
<p>Para1<p>Para2
|
1249
|
-
should be transformed into:
|
1250
|
-
<p>Para1</p><p>Para2
|
1251
|
-
|
1252
|
-
Some tags can be nested arbitrarily. For instance, the occurance
|
1253
|
-
of a <blockquote> tag should _not_ implicitly close the previous
|
1254
|
-
<blockquote> tag.
|
1255
|
-
|
1256
|
-
Alice said: <blockquote>Bob said: <blockquote>Blah
|
1257
|
-
should NOT be transformed into:
|
1258
|
-
Alice said: <blockquote>Bob said: </blockquote><blockquote>Blah
|
1259
|
-
|
1260
|
-
Some tags can be nested, but the nesting is reset by the
|
1261
|
-
interposition of other tags. For instance, a <tr> tag should
|
1262
|
-
implicitly close the previous <tr> tag within the same <table>,
|
1263
|
-
but not close a <tr> tag in another table.
|
1264
|
-
|
1265
|
-
<table><tr>Blah<tr>Blah
|
1266
|
-
should be transformed into:
|
1267
|
-
<table><tr>Blah</tr><tr>Blah
|
1268
|
-
but,
|
1269
|
-
<tr>Blah<table><tr>Blah
|
1270
|
-
should NOT be transformed into
|
1271
|
-
<tr>Blah<table></tr><tr>Blah
|
1272
|
-
|
1273
|
-
Differing assumptions about tag nesting rules are a major source
|
1274
|
-
of problems with the BeautifulSoup class. If BeautifulSoup is not
|
1275
|
-
treating as nestable a tag your page author treats as nestable,
|
1276
|
-
try ICantBelieveItsBeautifulSoup, MinimalSoup, or
|
1277
|
-
BeautifulStoneSoup before writing your own subclass."""
|
1278
|
-
|
1279
|
-
def __init__(self, *args, **kwargs):
|
1280
|
-
if not kwargs.has_key('smartQuotesTo'):
|
1281
|
-
kwargs['smartQuotesTo'] = self.HTML_ENTITIES
|
1282
|
-
BeautifulStoneSoup.__init__(self, *args, **kwargs)
|
1283
|
-
|
1284
|
-
SELF_CLOSING_TAGS = buildTagMap(None,
|
1285
|
-
['br' , 'hr', 'input', 'img', 'meta',
|
1286
|
-
'spacer', 'link', 'frame', 'base'])
|
1287
|
-
|
1288
|
-
QUOTE_TAGS = {'script': None}
|
1289
|
-
|
1290
|
-
#According to the HTML standard, each of these inline tags can
|
1291
|
-
#contain another tag of the same type. Furthermore, it's common
|
1292
|
-
#to actually use these tags this way.
|
1293
|
-
NESTABLE_INLINE_TAGS = ['span', 'font', 'q', 'object', 'bdo', 'sub', 'sup',
|
1294
|
-
'center']
|
1295
|
-
|
1296
|
-
#According to the HTML standard, these block tags can contain
|
1297
|
-
#another tag of the same type. Furthermore, it's common
|
1298
|
-
#to actually use these tags this way.
|
1299
|
-
NESTABLE_BLOCK_TAGS = ['blockquote', 'div', 'fieldset', 'ins', 'del']
|
1300
|
-
|
1301
|
-
#Lists can contain other lists, but there are restrictions.
|
1302
|
-
NESTABLE_LIST_TAGS = { 'ol' : [],
|
1303
|
-
'ul' : [],
|
1304
|
-
'li' : ['ul', 'ol'],
|
1305
|
-
'dl' : [],
|
1306
|
-
'dd' : ['dl'],
|
1307
|
-
'dt' : ['dl'] }
|
1308
|
-
|
1309
|
-
#Tables can contain other tables, but there are restrictions.
|
1310
|
-
NESTABLE_TABLE_TAGS = {'table' : [],
|
1311
|
-
'tr' : ['table', 'tbody', 'tfoot', 'thead'],
|
1312
|
-
'td' : ['tr'],
|
1313
|
-
'th' : ['tr'],
|
1314
|
-
'thead' : ['table'],
|
1315
|
-
'tbody' : ['table'],
|
1316
|
-
'tfoot' : ['table'],
|
1317
|
-
}
|
1318
|
-
|
1319
|
-
NON_NESTABLE_BLOCK_TAGS = ['address', 'form', 'p', 'pre']
|
1320
|
-
|
1321
|
-
#If one of these tags is encountered, all tags up to the next tag of
|
1322
|
-
#this type are popped.
|
1323
|
-
RESET_NESTING_TAGS = buildTagMap(None, NESTABLE_BLOCK_TAGS, 'noscript',
|
1324
|
-
NON_NESTABLE_BLOCK_TAGS,
|
1325
|
-
NESTABLE_LIST_TAGS,
|
1326
|
-
NESTABLE_TABLE_TAGS)
|
1327
|
-
|
1328
|
-
NESTABLE_TAGS = buildTagMap([], NESTABLE_INLINE_TAGS, NESTABLE_BLOCK_TAGS,
|
1329
|
-
NESTABLE_LIST_TAGS, NESTABLE_TABLE_TAGS)
|
1330
|
-
|
1331
|
-
# Used to detect the charset in a META tag; see start_meta
|
1332
|
-
CHARSET_RE = re.compile("((^|;)\s*charset=)([^;]*)")
|
1333
|
-
|
1334
|
-
def start_meta(self, attrs):
|
1335
|
-
"""Beautiful Soup can detect a charset included in a META tag,
|
1336
|
-
try to convert the document to that charset, and re-parse the
|
1337
|
-
document from the beginning."""
|
1338
|
-
httpEquiv = None
|
1339
|
-
contentType = None
|
1340
|
-
contentTypeIndex = None
|
1341
|
-
tagNeedsEncodingSubstitution = False
|
1342
|
-
|
1343
|
-
for i in range(0, len(attrs)):
|
1344
|
-
key, value = attrs[i]
|
1345
|
-
key = key.lower()
|
1346
|
-
if key == 'http-equiv':
|
1347
|
-
httpEquiv = value
|
1348
|
-
elif key == 'content':
|
1349
|
-
contentType = value
|
1350
|
-
contentTypeIndex = i
|
1351
|
-
|
1352
|
-
if httpEquiv and contentType: # It's an interesting meta tag.
|
1353
|
-
match = self.CHARSET_RE.search(contentType)
|
1354
|
-
if match:
|
1355
|
-
if getattr(self, 'declaredHTMLEncoding') or \
|
1356
|
-
(self.originalEncoding == self.fromEncoding):
|
1357
|
-
# This is our second pass through the document, or
|
1358
|
-
# else an encoding was specified explicitly and it
|
1359
|
-
# worked. Rewrite the meta tag.
|
1360
|
-
newAttr = self.CHARSET_RE.sub\
|
1361
|
-
(lambda(match):match.group(1) +
|
1362
|
-
"%SOUP-ENCODING%", value)
|
1363
|
-
attrs[contentTypeIndex] = (attrs[contentTypeIndex][0],
|
1364
|
-
newAttr)
|
1365
|
-
tagNeedsEncodingSubstitution = True
|
1366
|
-
else:
|
1367
|
-
# This is our first pass through the document.
|
1368
|
-
# Go through it again with the new information.
|
1369
|
-
newCharset = match.group(3)
|
1370
|
-
if newCharset and newCharset != self.originalEncoding:
|
1371
|
-
self.declaredHTMLEncoding = newCharset
|
1372
|
-
self._feed(self.declaredHTMLEncoding)
|
1373
|
-
raise StopParsing
|
1374
|
-
tag = self.unknown_starttag("meta", attrs)
|
1375
|
-
if tag and tagNeedsEncodingSubstitution:
|
1376
|
-
tag.containsSubstitutions = True
|
1377
|
-
|
1378
|
-
class StopParsing(Exception):
|
1379
|
-
pass
|
1380
|
-
|
1381
|
-
class ICantBelieveItsBeautifulSoup(BeautifulSoup):
|
1382
|
-
|
1383
|
-
"""The BeautifulSoup class is oriented towards skipping over
|
1384
|
-
common HTML errors like unclosed tags. However, sometimes it makes
|
1385
|
-
errors of its own. For instance, consider this fragment:
|
1386
|
-
|
1387
|
-
<b>Foo<b>Bar</b></b>
|
1388
|
-
|
1389
|
-
This is perfectly valid (if bizarre) HTML. However, the
|
1390
|
-
BeautifulSoup class will implicitly close the first b tag when it
|
1391
|
-
encounters the second 'b'. It will think the author wrote
|
1392
|
-
"<b>Foo<b>Bar", and didn't close the first 'b' tag, because
|
1393
|
-
there's no real-world reason to bold something that's already
|
1394
|
-
bold. When it encounters '</b></b>' it will close two more 'b'
|
1395
|
-
tags, for a grand total of three tags closed instead of two. This
|
1396
|
-
can throw off the rest of your document structure. The same is
|
1397
|
-
true of a number of other tags, listed below.
|
1398
|
-
|
1399
|
-
It's much more common for someone to forget to close a 'b' tag
|
1400
|
-
than to actually use nested 'b' tags, and the BeautifulSoup class
|
1401
|
-
handles the common case. This class handles the not-co-common
|
1402
|
-
case: where you can't believe someone wrote what they did, but
|
1403
|
-
it's valid HTML and BeautifulSoup screwed up by assuming it
|
1404
|
-
wouldn't be."""
|
1405
|
-
|
1406
|
-
I_CANT_BELIEVE_THEYRE_NESTABLE_INLINE_TAGS = \
|
1407
|
-
['em', 'big', 'i', 'small', 'tt', 'abbr', 'acronym', 'strong',
|
1408
|
-
'cite', 'code', 'dfn', 'kbd', 'samp', 'strong', 'var', 'b',
|
1409
|
-
'big']
|
1410
|
-
|
1411
|
-
I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS = ['noscript']
|
1412
|
-
|
1413
|
-
NESTABLE_TAGS = buildTagMap([], BeautifulSoup.NESTABLE_TAGS,
|
1414
|
-
I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS,
|
1415
|
-
I_CANT_BELIEVE_THEYRE_NESTABLE_INLINE_TAGS)
|
1416
|
-
|
1417
|
-
class MinimalSoup(BeautifulSoup):
|
1418
|
-
"""The MinimalSoup class is for parsing HTML that contains
|
1419
|
-
pathologically bad markup. It makes no assumptions about tag
|
1420
|
-
nesting, but it does know which tags are self-closing, that
|
1421
|
-
<script> tags contain Javascript and should not be parsed, that
|
1422
|
-
META tags may contain encoding information, and so on.
|
1423
|
-
|
1424
|
-
This also makes it better for subclassing than BeautifulStoneSoup
|
1425
|
-
or BeautifulSoup."""
|
1426
|
-
|
1427
|
-
RESET_NESTING_TAGS = buildTagMap('noscript')
|
1428
|
-
NESTABLE_TAGS = {}
|
1429
|
-
|
1430
|
-
class BeautifulSOAP(BeautifulStoneSoup):
|
1431
|
-
"""This class will push a tag with only a single string child into
|
1432
|
-
the tag's parent as an attribute. The attribute's name is the tag
|
1433
|
-
name, and the value is the string child. An example should give
|
1434
|
-
the flavor of the change:
|
1435
|
-
|
1436
|
-
<foo><bar>baz</bar></foo>
|
1437
|
-
=>
|
1438
|
-
<foo bar="baz"><bar>baz</bar></foo>
|
1439
|
-
|
1440
|
-
You can then access fooTag['bar'] instead of fooTag.barTag.string.
|
1441
|
-
|
1442
|
-
This is, of course, useful for scraping structures that tend to
|
1443
|
-
use subelements instead of attributes, such as SOAP messages. Note
|
1444
|
-
that it modifies its input, so don't print the modified version
|
1445
|
-
out.
|
1446
|
-
|
1447
|
-
I'm not sure how many people really want to use this class; let me
|
1448
|
-
know if you do. Mainly I like the name."""
|
1449
|
-
|
1450
|
-
def popTag(self):
|
1451
|
-
if len(self.tagStack) > 1:
|
1452
|
-
tag = self.tagStack[-1]
|
1453
|
-
parent = self.tagStack[-2]
|
1454
|
-
parent._getAttrMap()
|
1455
|
-
if (isinstance(tag, Tag) and len(tag.contents) == 1 and
|
1456
|
-
isinstance(tag.contents[0], NavigableString) and
|
1457
|
-
not parent.attrMap.has_key(tag.name)):
|
1458
|
-
parent[tag.name] = tag.contents[0]
|
1459
|
-
BeautifulStoneSoup.popTag(self)
|
1460
|
-
|
1461
|
-
#Enterprise class names! It has come to our attention that some people
|
1462
|
-
#think the names of the Beautiful Soup parser classes are too silly
|
1463
|
-
#and "unprofessional" for use in enterprise screen-scraping. We feel
|
1464
|
-
#your pain! For such-minded folk, the Beautiful Soup Consortium And
|
1465
|
-
#All-Night Kosher Bakery recommends renaming this file to
|
1466
|
-
#"RobustParser.py" (or, in cases of extreme enterprisness,
|
1467
|
-
#"RobustParserBeanInterface.class") and using the following
|
1468
|
-
#enterprise-friendly class aliases:
|
1469
|
-
class RobustXMLParser(BeautifulStoneSoup):
|
1470
|
-
pass
|
1471
|
-
class RobustHTMLParser(BeautifulSoup):
|
1472
|
-
pass
|
1473
|
-
class RobustWackAssHTMLParser(ICantBelieveItsBeautifulSoup):
|
1474
|
-
pass
|
1475
|
-
class RobustInsanelyWackAssHTMLParser(MinimalSoup):
|
1476
|
-
pass
|
1477
|
-
class SimplifyingSOAPParser(BeautifulSOAP):
|
1478
|
-
pass
|
1479
|
-
|
1480
|
-
######################################################
|
1481
|
-
#
|
1482
|
-
# Bonus library: Unicode, Dammit
|
1483
|
-
#
|
1484
|
-
# This class forces XML data into a standard format (usually to UTF-8
|
1485
|
-
# or Unicode). It is heavily based on code from Mark Pilgrim's
|
1486
|
-
# Universal Feed Parser. It does not rewrite the XML or HTML to
|
1487
|
-
# reflect a new encoding: that happens in BeautifulStoneSoup.handle_pi
|
1488
|
-
# (XML) and BeautifulSoup.start_meta (HTML).
|
1489
|
-
|
1490
|
-
# Autodetects character encodings.
|
1491
|
-
# Download from http://chardet.feedparser.org/
|
1492
|
-
try:
|
1493
|
-
import chardet
|
1494
|
-
# import chardet.constants
|
1495
|
-
# chardet.constants._debug = 1
|
1496
|
-
except:
|
1497
|
-
chardet = None
|
1498
|
-
chardet = None
|
1499
|
-
|
1500
|
-
# cjkcodecs and iconv_codec make Python know about more character encodings.
|
1501
|
-
# Both are available from http://cjkpython.i18n.org/
|
1502
|
-
# They're built in if you use Python 2.4.
|
1503
|
-
try:
|
1504
|
-
import cjkcodecs.aliases
|
1505
|
-
except:
|
1506
|
-
pass
|
1507
|
-
try:
|
1508
|
-
import iconv_codec
|
1509
|
-
except:
|
1510
|
-
pass
|
1511
|
-
|
1512
|
-
class UnicodeDammit:
|
1513
|
-
"""A class for detecting the encoding of a *ML document and
|
1514
|
-
converting it to a Unicode string. If the source encoding is
|
1515
|
-
windows-1252, can replace MS smart quotes with their HTML or XML
|
1516
|
-
equivalents."""
|
1517
|
-
|
1518
|
-
# This dictionary maps commonly seen values for "charset" in HTML
|
1519
|
-
# meta tags to the corresponding Python codec names. It only covers
|
1520
|
-
# values that aren't in Python's aliases and can't be determined
|
1521
|
-
# by the heuristics in find_codec.
|
1522
|
-
CHARSET_ALIASES = { "macintosh" : "mac-roman",
|
1523
|
-
"x-sjis" : "shift-jis" }
|
1524
|
-
|
1525
|
-
def __init__(self, markup, overrideEncodings=[],
|
1526
|
-
smartQuotesTo='xml'):
|
1527
|
-
self.markup, documentEncoding, sniffedEncoding = \
|
1528
|
-
self._detectEncoding(markup)
|
1529
|
-
self.smartQuotesTo = smartQuotesTo
|
1530
|
-
self.triedEncodings = []
|
1531
|
-
if markup == '' or isinstance(markup, unicode):
|
1532
|
-
self.originalEncoding = None
|
1533
|
-
self.unicode = unicode(markup)
|
1534
|
-
return
|
1535
|
-
|
1536
|
-
u = None
|
1537
|
-
for proposedEncoding in overrideEncodings:
|
1538
|
-
u = self._convertFrom(proposedEncoding)
|
1539
|
-
if u: break
|
1540
|
-
if not u:
|
1541
|
-
for proposedEncoding in (documentEncoding, sniffedEncoding):
|
1542
|
-
u = self._convertFrom(proposedEncoding)
|
1543
|
-
if u: break
|
1544
|
-
|
1545
|
-
# If no luck and we have auto-detection library, try that:
|
1546
|
-
if not u and chardet and not isinstance(self.markup, unicode):
|
1547
|
-
u = self._convertFrom(chardet.detect(self.markup)['encoding'])
|
1548
|
-
|
1549
|
-
# As a last resort, try utf-8 and windows-1252:
|
1550
|
-
if not u:
|
1551
|
-
for proposed_encoding in ("utf-8", "windows-1252"):
|
1552
|
-
u = self._convertFrom(proposed_encoding)
|
1553
|
-
if u: break
|
1554
|
-
self.unicode = u
|
1555
|
-
if not u: self.originalEncoding = None
|
1556
|
-
|
1557
|
-
def _subMSChar(self, orig):
|
1558
|
-
"""Changes a MS smart quote character to an XML or HTML
|
1559
|
-
entity."""
|
1560
|
-
sub = self.MS_CHARS.get(orig)
|
1561
|
-
if type(sub) == types.TupleType:
|
1562
|
-
if self.smartQuotesTo == 'xml':
|
1563
|
-
sub = '&#x%s;' % sub[1]
|
1564
|
-
else:
|
1565
|
-
sub = '&%s;' % sub[0]
|
1566
|
-
return sub
|
1567
|
-
|
1568
|
-
def _convertFrom(self, proposed):
|
1569
|
-
proposed = self.find_codec(proposed)
|
1570
|
-
if not proposed or proposed in self.triedEncodings:
|
1571
|
-
return None
|
1572
|
-
self.triedEncodings.append(proposed)
|
1573
|
-
markup = self.markup
|
1574
|
-
|
1575
|
-
# Convert smart quotes to HTML if coming from an encoding
|
1576
|
-
# that might have them.
|
1577
|
-
if self.smartQuotesTo and proposed.lower() in("windows-1252",
|
1578
|
-
"iso-8859-1",
|
1579
|
-
"iso-8859-2"):
|
1580
|
-
markup = re.compile("([\x80-\x9f])").sub \
|
1581
|
-
(lambda(x): self._subMSChar(x.group(1)),
|
1582
|
-
markup)
|
1583
|
-
|
1584
|
-
try:
|
1585
|
-
# print "Trying to convert document to %s" % proposed
|
1586
|
-
u = self._toUnicode(markup, proposed)
|
1587
|
-
self.markup = u
|
1588
|
-
self.originalEncoding = proposed
|
1589
|
-
except Exception, e:
|
1590
|
-
# print "That didn't work!"
|
1591
|
-
# print e
|
1592
|
-
return None
|
1593
|
-
#print "Correct encoding: %s" % proposed
|
1594
|
-
return self.markup
|
1595
|
-
|
1596
|
-
def _toUnicode(self, data, encoding):
|
1597
|
-
'''Given a string and its encoding, decodes the string into Unicode.
|
1598
|
-
%encoding is a string recognized by encodings.aliases'''
|
1599
|
-
|
1600
|
-
# strip Byte Order Mark (if present)
|
1601
|
-
if (len(data) >= 4) and (data[:2] == '\xfe\xff') \
|
1602
|
-
and (data[2:4] != '\x00\x00'):
|
1603
|
-
encoding = 'utf-16be'
|
1604
|
-
data = data[2:]
|
1605
|
-
elif (len(data) >= 4) and (data[:2] == '\xff\xfe') \
|
1606
|
-
and (data[2:4] != '\x00\x00'):
|
1607
|
-
encoding = 'utf-16le'
|
1608
|
-
data = data[2:]
|
1609
|
-
elif data[:3] == '\xef\xbb\xbf':
|
1610
|
-
encoding = 'utf-8'
|
1611
|
-
data = data[3:]
|
1612
|
-
elif data[:4] == '\x00\x00\xfe\xff':
|
1613
|
-
encoding = 'utf-32be'
|
1614
|
-
data = data[4:]
|
1615
|
-
elif data[:4] == '\xff\xfe\x00\x00':
|
1616
|
-
encoding = 'utf-32le'
|
1617
|
-
data = data[4:]
|
1618
|
-
newdata = unicode(data, encoding)
|
1619
|
-
return newdata
|
1620
|
-
|
1621
|
-
def _detectEncoding(self, xml_data):
|
1622
|
-
"""Given a document, tries to detect its XML encoding."""
|
1623
|
-
xml_encoding = sniffed_xml_encoding = None
|
1624
|
-
try:
|
1625
|
-
if xml_data[:4] == '\x4c\x6f\xa7\x94':
|
1626
|
-
# EBCDIC
|
1627
|
-
xml_data = self._ebcdic_to_ascii(xml_data)
|
1628
|
-
elif xml_data[:4] == '\x00\x3c\x00\x3f':
|
1629
|
-
# UTF-16BE
|
1630
|
-
sniffed_xml_encoding = 'utf-16be'
|
1631
|
-
xml_data = unicode(xml_data, 'utf-16be').encode('utf-8')
|
1632
|
-
elif (len(xml_data) >= 4) and (xml_data[:2] == '\xfe\xff') \
|
1633
|
-
and (xml_data[2:4] != '\x00\x00'):
|
1634
|
-
# UTF-16BE with BOM
|
1635
|
-
sniffed_xml_encoding = 'utf-16be'
|
1636
|
-
xml_data = unicode(xml_data[2:], 'utf-16be').encode('utf-8')
|
1637
|
-
elif xml_data[:4] == '\x3c\x00\x3f\x00':
|
1638
|
-
# UTF-16LE
|
1639
|
-
sniffed_xml_encoding = 'utf-16le'
|
1640
|
-
xml_data = unicode(xml_data, 'utf-16le').encode('utf-8')
|
1641
|
-
elif (len(xml_data) >= 4) and (xml_data[:2] == '\xff\xfe') and \
|
1642
|
-
(xml_data[2:4] != '\x00\x00'):
|
1643
|
-
# UTF-16LE with BOM
|
1644
|
-
sniffed_xml_encoding = 'utf-16le'
|
1645
|
-
xml_data = unicode(xml_data[2:], 'utf-16le').encode('utf-8')
|
1646
|
-
elif xml_data[:4] == '\x00\x00\x00\x3c':
|
1647
|
-
# UTF-32BE
|
1648
|
-
sniffed_xml_encoding = 'utf-32be'
|
1649
|
-
xml_data = unicode(xml_data, 'utf-32be').encode('utf-8')
|
1650
|
-
elif xml_data[:4] == '\x3c\x00\x00\x00':
|
1651
|
-
# UTF-32LE
|
1652
|
-
sniffed_xml_encoding = 'utf-32le'
|
1653
|
-
xml_data = unicode(xml_data, 'utf-32le').encode('utf-8')
|
1654
|
-
elif xml_data[:4] == '\x00\x00\xfe\xff':
|
1655
|
-
# UTF-32BE with BOM
|
1656
|
-
sniffed_xml_encoding = 'utf-32be'
|
1657
|
-
xml_data = unicode(xml_data[4:], 'utf-32be').encode('utf-8')
|
1658
|
-
elif xml_data[:4] == '\xff\xfe\x00\x00':
|
1659
|
-
# UTF-32LE with BOM
|
1660
|
-
sniffed_xml_encoding = 'utf-32le'
|
1661
|
-
xml_data = unicode(xml_data[4:], 'utf-32le').encode('utf-8')
|
1662
|
-
elif xml_data[:3] == '\xef\xbb\xbf':
|
1663
|
-
# UTF-8 with BOM
|
1664
|
-
sniffed_xml_encoding = 'utf-8'
|
1665
|
-
xml_data = unicode(xml_data[3:], 'utf-8').encode('utf-8')
|
1666
|
-
else:
|
1667
|
-
sniffed_xml_encoding = 'ascii'
|
1668
|
-
pass
|
1669
|
-
xml_encoding_match = re.compile \
|
1670
|
-
('^<\?.*encoding=[\'"](.*?)[\'"].*\?>')\
|
1671
|
-
.match(xml_data)
|
1672
|
-
except:
|
1673
|
-
xml_encoding_match = None
|
1674
|
-
if xml_encoding_match:
|
1675
|
-
xml_encoding = xml_encoding_match.groups()[0].lower()
|
1676
|
-
if sniffed_xml_encoding and \
|
1677
|
-
(xml_encoding in ('iso-10646-ucs-2', 'ucs-2', 'csunicode',
|
1678
|
-
'iso-10646-ucs-4', 'ucs-4', 'csucs4',
|
1679
|
-
'utf-16', 'utf-32', 'utf_16', 'utf_32',
|
1680
|
-
'utf16', 'u16')):
|
1681
|
-
xml_encoding = sniffed_xml_encoding
|
1682
|
-
return xml_data, xml_encoding, sniffed_xml_encoding
|
1683
|
-
|
1684
|
-
|
1685
|
-
def find_codec(self, charset):
|
1686
|
-
return self._codec(self.CHARSET_ALIASES.get(charset, charset)) \
|
1687
|
-
or (charset and self._codec(charset.replace("-", ""))) \
|
1688
|
-
or (charset and self._codec(charset.replace("-", "_"))) \
|
1689
|
-
or charset
|
1690
|
-
|
1691
|
-
def _codec(self, charset):
|
1692
|
-
if not charset: return charset
|
1693
|
-
codec = None
|
1694
|
-
try:
|
1695
|
-
codecs.lookup(charset)
|
1696
|
-
codec = charset
|
1697
|
-
except LookupError:
|
1698
|
-
pass
|
1699
|
-
return codec
|
1700
|
-
|
1701
|
-
EBCDIC_TO_ASCII_MAP = None
|
1702
|
-
def _ebcdic_to_ascii(self, s):
|
1703
|
-
c = self.__class__
|
1704
|
-
if not c.EBCDIC_TO_ASCII_MAP:
|
1705
|
-
emap = (0,1,2,3,156,9,134,127,151,141,142,11,12,13,14,15,
|
1706
|
-
16,17,18,19,157,133,8,135,24,25,146,143,28,29,30,31,
|
1707
|
-
128,129,130,131,132,10,23,27,136,137,138,139,140,5,6,7,
|
1708
|
-
144,145,22,147,148,149,150,4,152,153,154,155,20,21,158,26,
|
1709
|
-
32,160,161,162,163,164,165,166,167,168,91,46,60,40,43,33,
|
1710
|
-
38,169,170,171,172,173,174,175,176,177,93,36,42,41,59,94,
|
1711
|
-
45,47,178,179,180,181,182,183,184,185,124,44,37,95,62,63,
|
1712
|
-
186,187,188,189,190,191,192,193,194,96,58,35,64,39,61,34,
|
1713
|
-
195,97,98,99,100,101,102,103,104,105,196,197,198,199,200,
|
1714
|
-
201,202,106,107,108,109,110,111,112,113,114,203,204,205,
|
1715
|
-
206,207,208,209,126,115,116,117,118,119,120,121,122,210,
|
1716
|
-
211,212,213,214,215,216,217,218,219,220,221,222,223,224,
|
1717
|
-
225,226,227,228,229,230,231,123,65,66,67,68,69,70,71,72,
|
1718
|
-
73,232,233,234,235,236,237,125,74,75,76,77,78,79,80,81,
|
1719
|
-
82,238,239,240,241,242,243,92,159,83,84,85,86,87,88,89,
|
1720
|
-
90,244,245,246,247,248,249,48,49,50,51,52,53,54,55,56,57,
|
1721
|
-
250,251,252,253,254,255)
|
1722
|
-
import string
|
1723
|
-
c.EBCDIC_TO_ASCII_MAP = string.maketrans( \
|
1724
|
-
''.join(map(chr, range(256))), ''.join(map(chr, emap)))
|
1725
|
-
return s.translate(c.EBCDIC_TO_ASCII_MAP)
|
1726
|
-
|
1727
|
-
MS_CHARS = { '\x80' : ('euro', '20AC'),
|
1728
|
-
'\x81' : ' ',
|
1729
|
-
'\x82' : ('sbquo', '201A'),
|
1730
|
-
'\x83' : ('fnof', '192'),
|
1731
|
-
'\x84' : ('bdquo', '201E'),
|
1732
|
-
'\x85' : ('hellip', '2026'),
|
1733
|
-
'\x86' : ('dagger', '2020'),
|
1734
|
-
'\x87' : ('Dagger', '2021'),
|
1735
|
-
'\x88' : ('circ', '2C6'),
|
1736
|
-
'\x89' : ('permil', '2030'),
|
1737
|
-
'\x8A' : ('Scaron', '160'),
|
1738
|
-
'\x8B' : ('lsaquo', '2039'),
|
1739
|
-
'\x8C' : ('OElig', '152'),
|
1740
|
-
'\x8D' : '?',
|
1741
|
-
'\x8E' : ('#x17D', '17D'),
|
1742
|
-
'\x8F' : '?',
|
1743
|
-
'\x90' : '?',
|
1744
|
-
'\x91' : ('lsquo', '2018'),
|
1745
|
-
'\x92' : ('rsquo', '2019'),
|
1746
|
-
'\x93' : ('ldquo', '201C'),
|
1747
|
-
'\x94' : ('rdquo', '201D'),
|
1748
|
-
'\x95' : ('bull', '2022'),
|
1749
|
-
'\x96' : ('ndash', '2013'),
|
1750
|
-
'\x97' : ('mdash', '2014'),
|
1751
|
-
'\x98' : ('tilde', '2DC'),
|
1752
|
-
'\x99' : ('trade', '2122'),
|
1753
|
-
'\x9a' : ('scaron', '161'),
|
1754
|
-
'\x9b' : ('rsaquo', '203A'),
|
1755
|
-
'\x9c' : ('oelig', '153'),
|
1756
|
-
'\x9d' : '?',
|
1757
|
-
'\x9e' : ('#x17E', '17E'),
|
1758
|
-
'\x9f' : ('Yuml', ''),}
|
1759
|
-
|
1760
|
-
#######################################################################
|
1761
|
-
|
1762
|
-
|
1763
|
-
#By default, act as an HTML pretty-printer.
|
1764
|
-
if __name__ == '__main__':
|
1765
|
-
import sys
|
1766
|
-
soup = BeautifulSoup(sys.stdin.read())
|
1767
|
-
print soup.prettify()
|