function render()

in modules/ui/init.js [49:341]


    function render(container) {
        container
            .attr('dir', textDirection);

        // setup fullscreen keybindings (no button shown at this time)
        container
            .call(uiFullScreen(context));

        var map = context.map();
        map.redrawEnable(false);  // don't draw until we've set zoom/lat/long

        container
            .append('svg')
            .attr('id', 'defs')
            .call(svgDefs(context));


        var content = container
            .append('div')
            .attr('id', 'content')
            .attr('class', context.history().hasRestorableChanges() ? 'inactive' : 'active');

        // Top toolbar
        content
            .append('div')
            .attr('id', 'bar-wrap')
            .append('div')
            .attr('id', 'bar')
            .attr('class', 'fillD')
            .call(uiTopToolbar(context));

        content
            .append('div')
            .attr('id', 'map')
            .attr('dir', 'ltr')
            .call(map);


        // Map controls
        var controls = content
            .append('div')
            .attr('class', 'map-controls');

        controls
            .append('div')
            .attr('class', 'map-control zoombuttons')
            .call(uiZoom(context));

        controls
            .append('div')
            .attr('class', 'map-control geolocate-control')
            .call(uiGeolocate(context));

        var background = uiBackground(context);
        controls
            .append('div')
            .attr('class', 'map-control background-control')
            .call(background.renderToggleButton);

        var mapData = uiMapData(context);
        controls
            .append('div')
            .attr('class', 'map-control map-data-control')
            .call(mapData.renderToggleButton);

        var issues = uiIssues(context);
        controls
            .append('div')
            .attr('class', 'map-control map-issues-control')
            .call(issues.renderToggleButton);

        var help = uiHelp(context);
        controls
            .append('div')
            .attr('class', 'map-control help-control')
            .call(help.renderToggleButton);

        content
            .append('div')
            .attr('class', 'spinner')
            .call(uiSpinner(context));

        // Add attribution and footer
        var about = content
            .append('div')
            .attr('id', 'about');

        about
            .append('div')
            .attr('id', 'attrib')
            .attr('dir', 'ltr')
            .call(uiAttribution(context));

        about
            .append('div')
            .attr('class', 'api-status')
            .call(uiStatus(context));


        var footer = about
            .append('div')
            .attr('id', 'footer')
            .attr('class', 'fillD');

        footer
            .append('div')
            .attr('id', 'flash-wrap')
            .attr('class', 'footer-hide');

        var footerWrap = footer
            .append('div')
            .attr('id', 'footer-wrap')
            .attr('class', 'footer-show');

        var aboutList = footerWrap
            .append('div')
            .attr('id', 'info-block')
            .append('ul')
            .attr('id', 'about-list');

        if (!context.embed()) {
            aboutList
                .call(uiAccount(context));
        }

        aboutList
            .append('li')
            .attr('class', 'version')
            .call(uiVersion(context));

        var issueLinks = aboutList
            .append('li');

        issueLinks
            .append('a')
            .attr('target', '_blank')
            .attr('href', 'https://github.com/openstreetmap/iD/issues')
            .call(svgIcon('#iD-icon-bug', 'light'))
            .call(tooltip().title(t('report_a_bug')).placement('top'));

        issueLinks
            .append('a')
            .attr('target', '_blank')
            .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating')
            .call(svgIcon('#iD-icon-translate', 'light'))
            .call(tooltip().title(t('help_translate')).placement('top'));

        aboutList
            .append('li')
            .attr('class', 'feature-warning')
            .attr('tabindex', -1)
            .call(uiFeatureInfo(context));

        aboutList
            .append('li')
            .attr('class', 'issues-info')
            .attr('tabindex', -1)
            .call(uiIssuesInfo(context));

        aboutList
            .append('li')
            .attr('class', 'user-list')
            .attr('tabindex', -1)
            .call(uiContributors(context));

        footerWrap
            .append('div')
            .attr('id', 'scale-block')
            .call(uiScale(context));

        // Setup map dimensions and move map to initial center/zoom.
        // This should happen after #content and toolbars exist.
        ui.onResize();
        map.redrawEnable(true);

        ui.hash = behaviorHash(context);
        ui.hash();
        if (!ui.hash.hadHash) {
            map.centerZoom([0, 0], 2);
        }


        var overMap = content
            .append('div')
            .attr('class', 'over-map');

        // Add panes
        // This should happen after map is initialized, as some require surface()
        var panes = overMap
            .append('div')
            .attr('class', 'map-panes');

        panes
            .call(background.renderPane)
            .call(mapData.renderPane)
            .call(issues.renderPane)
            .call(help.renderPane);

        ui.info = uiInfo(context);

        // Add absolutely-positioned elements that sit on top of the map
        // This should happen after the map is ready (center/zoom)
        overMap
            .call(uiMapInMap(context))
            .call(ui.info)
            .call(uiNotice(context));


        overMap
            .append('div')
            .attr('id', 'photoviewer')
            .classed('al', true)       // 'al'=left,  'ar'=right
            .classed('hide', true)
            .call(ui.photoviewer);

        var assistantWrap = overMap
            .append('div')
            .attr('class', 'assistant-wrap');

        ui.assistant = uiAssistant(context);

        assistantWrap
            .call(ui.assistant);


        // Bind events
        window.onbeforeunload = function() {
            return context.save();
        };
        window.onunload = function() {
            context.history().unlock();
        };

        d3_select(window)
            .on('gesturestart.editor', eventCancel)
            .on('gesturechange.editor', eventCancel)
            .on('gestureend.editor', eventCancel)
            .on('resize.editor', ui.onResize);


        var panPixels = 80;
        context.keybinding()
            .on('⌫', function() { d3_event.preventDefault(); })
            .on('←', pan([panPixels, 0]))
            .on('↑', pan([0, panPixels]))
            .on('→', pan([-panPixels, 0]))
            .on('↓', pan([0, -panPixels]))
            .on(['⇧←', uiCmd('⌘←')], pan([map.dimensions()[0], 0]))
            .on(['⇧↑', uiCmd('⌘↑')], pan([0, map.dimensions()[1]]))
            .on(['⇧→', uiCmd('⌘→')], pan([-map.dimensions()[0], 0]))
            .on(['⇧↓', uiCmd('⌘↓')], pan([0, -map.dimensions()[1]]));

        context.enter(modeBrowse(context));

        if (!_initCounter++) {
            context.container()
                .call(uiShortcuts(context));
        }

        var osm = context.connection();
        var auth = uiLoading(context).message(t('loading_auth')).blocking(true);

        if (osm && auth) {
            osm
                .on('authLoading.ui', function() {
                    context.container()
                        .call(auth);
                })
                .on('authDone.ui', function() {
                    auth.close();
                });
        }

        _initCounter++;

        if (ui.hash.startWalkthrough) {
            ui.hash.startWalkthrough = false;
            context.container().call(uiIntro(context));
        }


        function pan(d) {
            return function() {
                if (d3_select('.combobox').size()) return;
                d3_event.preventDefault();
                context.pan(d, 100);
            };
        }

        function eventCancel() {
            d3_event.preventDefault();
        }
    }