static/pngtile/map.js
author Tero Marttila <terom@qmsk.net>
Sat, 04 Oct 2014 03:28:57 +0300
changeset 175 16ab69a5569a
parent 172 73380dd6a816
permissions -rw-r--r--
pngtile: fix multiple bugs with region-link centering
142
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
var map_config;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
var map;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
145
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
     4
L.Control.Link = L.Control.extend({
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
     5
    options: {
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
     6
        position: 'topright',
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
     7
        url: null,
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
     8
    },
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
     9
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    10
    onAdd: function (map) {
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    11
        var container = L.DomUtil.create('div', 'leaflet-control-link');
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    12
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    13
        var link = this.link = L.DomUtil.create('a', 'leaflet-control-link-link', container);
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    14
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    15
        map.on('move', this._update, this);
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    16
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    17
        return container;
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    18
    },
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    19
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    20
    onRemove: function (map) {
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    21
        map.off('move', this._update, this);
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    22
    },
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    23
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    24
    _update: function (e) {
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    25
        var map_center = map.getCenter();
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    26
        var map_zoom = map.getZoom();
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    27
        var size = map.getSize();
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    28
        
175
16ab69a5569a pngtile: fix multiple bugs with region-link centering
Tero Marttila <terom@qmsk.net>
parents: 172
diff changeset
    29
        var x = (+map_center.lng) * Math.pow(2, map_config.tile_zoom);
16ab69a5569a pngtile: fix multiple bugs with region-link centering
Tero Marttila <terom@qmsk.net>
parents: 172
diff changeset
    30
        var y = (-map_center.lat) * Math.pow(2, map_config.tile_zoom);
16ab69a5569a pngtile: fix multiple bugs with region-link centering
Tero Marttila <terom@qmsk.net>
parents: 172
diff changeset
    31
        var zoom = map_config.tile_zoom - map_zoom;
16ab69a5569a pngtile: fix multiple bugs with region-link centering
Tero Marttila <terom@qmsk.net>
parents: 172
diff changeset
    32
145
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    33
        var state = {
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    34
            w: size.x,
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    35
            h: size.y,
175
16ab69a5569a pngtile: fix multiple bugs with region-link centering
Tero Marttila <terom@qmsk.net>
parents: 172
diff changeset
    36
            x: x >> zoom,
16ab69a5569a pngtile: fix multiple bugs with region-link centering
Tero Marttila <terom@qmsk.net>
parents: 172
diff changeset
    37
            y: y >> zoom,
16ab69a5569a pngtile: fix multiple bugs with region-link centering
Tero Marttila <terom@qmsk.net>
parents: 172
diff changeset
    38
            z: zoom
145
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    39
        };
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    40
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    41
        var url = L.Util.template(this.options.url, L.extend(state, this.options));
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    42
        
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    43
        this.link.href = url;
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    44
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    45
        with (state) {
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    46
            this.link.innerHTML = w + 'x' + h + ' @ (' + x + ', ' + y + ') @ ' + z;
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    47
        }
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    48
    },
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    49
});
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    50
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    51
L.control.link = function (options) {
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    52
    return new L.Control.Link(options);
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    53
};
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    54
142
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
function map_init (_config) {
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
    map_config = _config;
143
22efa9fe73c8 pngtile: fix map_bounds
Tero Marttila <terom@paivola.fi>
parents: 142
diff changeset
    57
    
22efa9fe73c8 pngtile: fix map_bounds
Tero Marttila <terom@paivola.fi>
parents: 142
diff changeset
    58
    // pixel coordinates
142
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
    var bounds = L.latLngBounds(
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
        L.latLng(-map_config.image_height, 0),
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
        L.latLng(0, +map_config.image_width)
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
    );
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
    
143
22efa9fe73c8 pngtile: fix map_bounds
Tero Marttila <terom@paivola.fi>
parents: 142
diff changeset
    64
    // in zoom-scaled coordinates
22efa9fe73c8 pngtile: fix map_bounds
Tero Marttila <terom@paivola.fi>
parents: 142
diff changeset
    65
    var map_bounds = [
22efa9fe73c8 pngtile: fix map_bounds
Tero Marttila <terom@paivola.fi>
parents: 142
diff changeset
    66
        [ -(map_config.image_height >> map_config.tile_zoom), 0 ],
22efa9fe73c8 pngtile: fix map_bounds
Tero Marttila <terom@paivola.fi>
parents: 142
diff changeset
    67
        [ 0, +(map_config.image_width >> map_config.tile_zoom) ], 
22efa9fe73c8 pngtile: fix map_bounds
Tero Marttila <terom@paivola.fi>
parents: 142
diff changeset
    68
    ];
22efa9fe73c8 pngtile: fix map_bounds
Tero Marttila <terom@paivola.fi>
parents: 142
diff changeset
    69
142
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
    map = L.map('map', {
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
        crs: L              .CRS.Simple,
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
        minZoom:            0,
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
        maxZoom:            map_config.tile_zoom,
143
22efa9fe73c8 pngtile: fix map_bounds
Tero Marttila <terom@paivola.fi>
parents: 142
diff changeset
    74
        maxBounds:          map_bounds
142
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
    });
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
    map.on('move', map_move);
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    79
    L.tileLayer(map_config.tile_url, {
168
260aa4a05e82 pngtile.image: update for PNGTileApplication
Tero Marttila <terom@qmsk.net>
parents: 153
diff changeset
    80
        tiles_url:          map_config.tiles_url,
172
73380dd6a816 pngtile: include ?t= in tile urls and generate large cache-control max-age's for those that match
Tero Marttila <terom@qmsk.net>
parents: 168
diff changeset
    81
        tiles_mtime:        map_config.tiles_mtime,
142
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
        minZoom:            0,
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
        maxZoom:            map_config.tile_zoom,
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
        tileSize:           map_config.tile_size,
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
        continuousWorld:    true,
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
        noWrap:             true,
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
        zoomReverse:        true,
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
        bounds:             bounds
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
    }).addTo(map);
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
145
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    91
    // controls
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    92
    L.control.link({
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    93
        url:        map_config.image_url,
168
260aa4a05e82 pngtile.image: update for PNGTileApplication
Tero Marttila <terom@qmsk.net>
parents: 153
diff changeset
    94
        tiles_url:  map_config.tiles_url,
172
73380dd6a816 pngtile: include ?t= in tile urls and generate large cache-control max-age's for those that match
Tero Marttila <terom@qmsk.net>
parents: 168
diff changeset
    95
        tiles_mtime:        map_config.tiles_mtime,
145
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    96
    }).addTo(map);
51908b0cc3a1 pngtile.image: render map link
Tero Marttila <terom@paivola.fi>
parents: 143
diff changeset
    97
142
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
    // set position
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
    var x = bounds.getCenter().lng;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100
    var y = -bounds.getCenter().lat;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   101
    var z = 0;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   102
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
    if (document.location.hash) {
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   104
        // parse x:y:z tuple
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   105
        var pt = document.location.hash.substr(1).split(":");
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   106
        
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   107
        // unpack    
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   108
        if (pt.length) x = parseInt(pt.shift()) || x;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   109
        if (pt.length) y = parseInt(pt.shift()) || y;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   110
        if (pt.length) z = parseInt(pt.shift()) || z;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   111
    }
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   112
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   113
    map_center(x, y, z);
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   114
}
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   115
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   116
function map_move () {
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   117
    var map_center = map.getCenter();
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   118
    var map_zoom = map.getZoom();
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   119
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   120
    var x = (+map_center.lng) << map_config.tile_zoom;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   121
    var y = (-map_center.lat) << map_config.tile_zoom;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   122
    var z = map_config.tile_zoom - map_zoom;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   123
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   124
    document.location.hash = x + ":" + y + ":" + z;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   125
}
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   126
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   127
/*
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   128
 * Position map based on pngtile coordinates
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   129
 */
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   130
function map_center (x, y, z) {
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   131
    // translate to lat/lng
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   132
    // leaflet seems to base its latlng coordinates on the max zoom level
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   133
    var map_center = [
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   134
        -(y >> map_config.tile_zoom),
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   135
        +(x >> map_config.tile_zoom),
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   136
    ];
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   137
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   138
    // reversed zoom
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   139
    var map_zoom = map_config.tile_zoom - z;
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   140
    
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   141
    map.setView(map_center, map_zoom);
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   142
}
9b316e83e9e3 pngtile.image: split out javascript and rename js/css to map
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   143