Safeguard against wrong Beam=BeamContinue on quarters and longer notes

function ProcessScore () {
    //$module(ExportProcessors.mss)
    // processors are a bit like a workflow manager -- they orchestrate the
    // generators, which in turn use the converters to convert specific values from sibelius
    // to MEI.
    score = Self._property:ActiveScore;

    mei = libmei.Mei();
    libmei.setDocumentRoot(mei);

    libmei.AddAttribute(mei, 'xmlns:xlink', 'http://www.w3.org/1999/xlink');
    libmei.AddAttribute(mei, 'xmlns', 'http://www.music-encoding.org/ns/mei');
    libmei.AddAttribute(mei, 'meiversion', '3.0.0');

    header = sibmei2.GenerateMEIHeader();
    libmei.AddChild(mei, header);

    music = sibmei2.GenerateMEIMusic();
    libmei.AddChild(mei, music);

}  //$end

function ProcessBeam (bobj, layer) {
    //$module(ExportProcessors.mss)
    ret = null;

    if (bobj.Duration < 256)
    {
        // if this object is an eighth note but is not beamed, and if the
        // active beam is set, null out the active beam and return null.
        if (bobj.Beam = NoBeam and layer._property:ActiveBeamId != null)
        {
            layer._property:ActiveBeamId = null;
            return ret;
        }

        /*
            It's possible that Sibelius records a 'continue beam' at the start
            of a beamed group. Visually, this doesn't look out of place if the previous
            note was a quarter note or higher.

            The first check we do is if the note has a 'continue beam' attribute and
            the previous note has a duration higher than 256 (quarter) then we probably have
            a false negative (i.e., there is the start of a beam, but it isn't necessarily
            encoded correctly).
        */
        falseNegative = False;
        next_obj = bobj.NextItem(bobj.VoiceNumber, 'NoteRest');

        if ((bobj.Beam = ContinueBeam or bobj.Beam = SingleBeam) and layer._property:ActiveBeamId = null)
        {
            // by all accounts this should be a beamed note, but we'll need to double-check.
            prev_obj = bobj.PreviousItem(bobj.VoiceNumber, 'NoteRest');

            if (prev_obj != null and (prev_obj.Duration >= 256))
            {
                falseNegative = True;
            }
        }

        if (next_obj != null and (bobj.Beam = StartBeam or falseNegative = True) and next_obj.Beam = ContinueBeam and next_obj.Duration < 256)
        {
            // if:
            //  - we're not at the end of the bar
            //  - we have a start beam
            //  - the next note is a continue beam
            //  - the next note is a beamable duration (safeguard against quarter and longer
            //    notes with Beam = ContinueBeam, which for some reason can actually occur)
            beam = libmei.Beam();
            layer._property:ActiveBeamId = beam._id;

            // return the beam so that we can add it to the tree.
            ret = beam;
        }

        if (layer._property:ActiveBeamId != null and (bobj.Beam = ContinueBeam or bobj.Beam = SingleBeam))
        {
            beamid = layer._property:ActiveBeamId;
            beam = libmei.getElementById(beamid);
            ret = beam;
        }
    }
    else
    {
        if (layer._property:ActiveBeamId != null)
        {
            // this is a break in any active beam, so register it as such.
            layer._property:ActiveBeamId = null;
        }
    }

    return ret;
}  //$end

function ProcessTuplet (bobj, meielement, layer) {
    //$module(ExportProcessors.mss)
    if (bobj.ParentTupletIfAny = null)
    {
        return null;
    }

    if (layer._property:ActiveTupletId = null)
    {
        tupletObject = bobj.ParentTupletIfAny;

        tuplet = libmei.Tuplet();

        layer._property:ActiveTupletObject = tupletObject;
        layer._property:ActiveTupletId = tuplet._id;

        if (libmei.GetName(meielement) = 'beam')
        {
            // get the first child
            startid = meielement.children[0];
        }
        else
        {
            startid = meielement._id;
        }

        libmei.AddAttribute(tuplet, 'startid', '#' & startid);
        libmei.AddAttribute(tuplet, 'num', tupletObject.Left);
        libmei.AddAttribute(tuplet, 'numbase', tupletObject.Right);

        tupletStyle = tupletObject.Style;

        switch (tupletStyle)
        {
            case(TupletNoNumber)
            {
                libmei.AddAttribute(tuplet, 'dur.visible', 'false');
            }
            case(TupletLeft)
            {
                libmei.AddAttribute(tuplet, 'num.format', 'count');
            }
            case(TupletLeftRight)
            {
                libmei.AddAttribute(tuplet, 'num.format', 'ratio');
            }
        }

        tupletBracket = tupletObject.Bracket;

        switch(tupletBracket)
        {
            case(TupletBracketOff)
            {
                libmei.AddAttribute(tuplet, 'bracket.visible', 'false');
            }
        }

        return tuplet;
    }
    else
    {
        tid = layer._property:ActiveTupletId;
        t = libmei.getElementById(tid);

        if (IsLastNoteInTuplet(bobj))
        {
            libmei.AddAttribute(t, 'endid', '#' & meielement._id);
            layer._property:ActiveTupletObject = null;
            layer._property:ActiveTupletId = null;
        }

        return t;
    }
}  //$end

function ShiftTupletToTupletSpan (tuplet, layer) {
    //$module(ExportProcessors.mss)
    /*
        Shifts the tuplet object to a tupletSpan object. This is
        useful if we need to define a tuplet outside of a hierarchy;
        for example, if a tuplet is only on part of a beam group.

        A tupletSpan supports many of the same attributes as a tuplet
        object, so we can copy the attributes verbatim. Functionally,
        it should behave the same way as a tuplet, except that it
        takes no child elements and the parent element is the measure,
        not the layer. These two things get handled higher up the
        processing chain, however, so we don't have to worry about them here.
    */

    tupletSpan = libmei.TupletSpan();
    libmei.SetAttributes(tupletSpan, tuplet.attrs);
    tupletSpan._property:AddedToMeasure = False;

    layer._property:ActiveTupletId = tupletSpan._id;

    if (tuplet._parent != null)
    {
        // if the tuplet has already been added to the tree,
        // remove it now. (Unfortunately, we can't delete the object,
        // but disowning it from the tree should be enough to keep it from
        // appearing in the output.)
        pobj = libmei.getElementById(tuplet._parent);
        libmei.RemoveChild(pobj, tuplet);
        tuplet._parent = null;
    }
}  //$end

function ProcessLyric (lyricobj, objectPositions) {
    //$module(ExportProcessors.mss)
    /*
        We need to track initial, medial, and terminal lyrics. Sibelius
        only allows us to know the medial and terminal, so we store all the
        syllables in an array until we reach the end of the word, and then
        attach them to the notes.
    */
    styleparts = MSplitString(lyricobj.StyleId, '.');
    verse_id = styleparts[5];
    verse_id_arr = MSplitString(verse_id, false);
    verse_num = verse_id_arr[5];
    bar_num = lyricobj.ParentBar.BarNumber;
    staff_num = lyricobj.ParentBar.ParentStaff.StaffNum;
    voicenum = lyricobj.VoiceNumber;

    if (voicenum = 0)
    {
        // assign it to the first voice, since we don't have any notes in voice 0.
        voicenum = 1;
        warnings = Self._property:warnings;
        warnings.Push(utils.Format(_ObjectAssignedToAllVoicesWarning, bar_num, voicenum, 'Lyric object'));
    }

    lyricwords = Self._property:LyricWords;

    if (lyricwords.PropertyExists(staff_num) = False)
    {
        lyricwords[staff_num] = CreateDictionary();
    }

    lyricstaff = lyricwords[staff_num];

    if (lyricstaff.PropertyExists(voicenum) = False)
    {
        lyricstaff[voicenum] = CreateDictionary();
    }

    lyricvoice = lyricstaff[voicenum];

    if (lyricvoice.PropertyExists(verse_num) = False)
    {
        lyricvoice[verse_num] = CreateSparseArray();
    }

    if (lyricobj.SyllableType = MiddleOfWord)
    {
        lyricvoice[verse_num].Push(lyricobj);
        // we haven't reached the end of the word yet, so just return
        // and keep going.
        return null;
    }

    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // anything past here is in the EndOfWord condition.
    // this should return a sparse array containing the syllables of the word.
    lyricvoice[verse_num].Push(lyricobj);
    lyric_word = lyricvoice[verse_num];
    objects = objectPositions[voicenum];

    obj_id = null;
    obj = null;

    for j = 0 to lyric_word.Length
    {
        syl = lyric_word[j];

        verse = libmei.Verse();
        libmei.AddAttribute(verse, 'n', verse_num);
        sylel = libmei.Syl();
        libmei.SetText(sylel, syl.Text);
        libmei.AddChild(verse, sylel);

        if (j = 0)
        {
            libmei.AddAttribute(sylel, 'wordpos', 'i'); // 'initial'

            if (lyric_word.Length > 1)
            {
                libmei.AddAttribute(sylel, 'con', 'd');
            }
        }
        else
        {
            if (syl.SyllableType = EndOfWord)
            {
                libmei.AddAttribute(sylel, 'wordpos', 't'); // 'terminal'

                if (syl.NumNotes > 1)
                {
                    libmei.AddAttribute(sylel, 'con', 'u'); // 'underscore'
                }

            }
            else
            {
                libmei.AddAttribute(sylel, 'wordpos', 'm'); // medial
                libmei.AddAttribute(sylel, 'con', 'd');
            }
        }

        obj = GetNoteObjectAtPosition(syl);

        if (obj != null)
        {
            name = libmei.GetName(obj);

            if (name = 'rest')
            {
                warnings = Self._property:warnings;
                warnings.Push(utils.Format(_ObjectIsOnAnIllogicalObject, bar_num, voicenum, 'Lyric', 'rest'));
            }

            if (name = 'chord')
            {
                warnings = Self._property:warnings;
                warnings.Push(utils.Format(_ObjectIsOnAnIllogicalObject, bar_num, voicenum, 'Lyric', 'chord'));
            }

            libmei.AddChild(obj, verse);
        }
    }

    // now reset the syllable array for this voice
    lyricvoice[verse_num] = CreateSparseArray();
}  //$end

function ProcessSystemStaff (score) {
    //$module(ExportProcessors.mss)
    systf = score.SystemStaff;

    for each bar in systf
    {
        for each bobj in bar
        {
            switch (bobj.Type)
            {
                case ('SpecialBarline')
                {
                    spclbarlines = Self._property:SpecialBarlines;
                    if (spclbarlines.PropertyExists(bar.BarNumber) = False)
                    {
                        spclbarlines[bar.BarNumber] = CreateSparseArray();
                    }

                    spclbarlines[bar.BarNumber].Push(ConvertBarline(bobj.BarlineInternalType));
                }
                case ('SystemTextItem')
                {
                    if (bobj.OnNthBlankPage < 0)
                    {
                        ProcessFrontMatter(bobj);
                    }

                    systemtext = Self._property:SystemText;

                    if (systemtext.PropertyExists(bar.BarNumber) = False)
                    {
                        systemtext[bar.BarNumber] = CreateSparseArray();
                    }

                    systemtext[bar.BarNumber].Push(bobj);
                }
                case ('Graphic')
                {
                    Log('Found a graphic!');
                    Log('is object? ' & IsObject(bobj));
                }
                case ('RepeatTimeLine')
                {
                    RegisterVolta(bobj);
                }
            }
        }
    }
}  //$end

function ProcessFrontMatter (bobj) {
    //$module(ExportProcessors.mss)
    /*
        For example, if page 2 (0-indexed) is the first page of music,
        then 'OnNthPage' will be 2, but the system staff items for
        the first page of text will be -2, so 2 + (-2) = 0 + 1;
    */
    bar = bobj.ParentBar;
    text = '';

    pnum = (bar.OnNthPage + bobj.OnNthBlankPage) + 1;
    frontmatter = Self._property:FrontMatter;

    if (frontmatter.PropertyExists(pnum) = False)
    {
        pb = libmei.Pb();
        libmei.AddAttribute(pb, 'n', pnum);
        frontmatter[pnum] = CreateSparseArray(pb);
    }
    pagematter = frontmatter[pnum];

    text = GenerateFormattedString(bobj);
    frontmatter[pnum] = pagematter.Concat(text);

}  //$end

function RegisterVolta (bobj) {
    //$module(ExportProcessors.mss)
    voltabars = Self._property:VoltaBars;
    style = MSplitString(bobj.StyleId, '.');

    if (style[2] = 'repeat')
    {
        voltabars[bobj.ParentBar.BarNumber] = bobj;
    }
}  //$end

function ProcessVolta (mnum) {
    //$module(ExportProcessors.mss)
    voltabars = Self._property:VoltaBars;

    if (voltabars.PropertyExists(mnum))
    {
        voltaElement = libmei.Ending();

        Self._property:VoltaElement = voltaElement;

        voltaObject = voltabars[mnum];
        voltainfo = ConvertEndingValues(voltaObject.StyleId);

        libmei.AddAttribute(voltaElement, 'n', voltainfo[0]);
        libmei.AddAttribute(voltaElement, 'label', voltainfo[1]);
        libmei.AddAttribute(voltaElement, 'type', voltainfo[2]);

        if (voltaObject.EndBarNumber != mnum)
        {
            Self._property:ActiveVolta = voltaObject;
        }

        return voltaElement;
    }
    else
    {
        if (Self._property:ActiveVolta != null)
        {
            // we have an unresolved volta, so
            // we'll keep the previous parentElement
            // active.
            activeVolta = Self._property:ActiveVolta;
            voltaElement = Self._property:VoltaElement;

            // if the end bar is the current bar OR if the end
            // bar is the next bar, but the end position is 0, we're escaping the
            // volta the next time around.
            if ((activeVolta.EndBarNumber = mnum) or
                (activeVolta.EndBarNumber = (mnum + 1) and activeVolta.EndPosition = 0))
            {
                Self._property:ActiveVolta = null;
                Self._property:VoltaElement = null;
            }
            return null;
        }
    }

    return null;
}  //$end

function ProcessSymbol (sobj) {
    //$module(ExportProcessors.mss)
    Log('symbol index: ' & sobj.Index & ' name: ' & sobj.Name);
    Log(sobj.VoiceNumber);

    switch (sobj.Index)
    {
        case ('32')
        {
            // trill
            trill = GenerateTrill(sobj);
            mlines = Self._property:MeasureObjects;
            mlines.Push(trill._id);
        }

        case ('36')
        {
            // inverted mordent
            mordent = libmei.Mordent();
            libmei.AddAttribute(mordent, 'form', 'inv');
            mlines = Self._property:MeasureObjects;
            mlines.Push(mordent._id);
        }

        case ('37')
        {
            // mordent
            mordent = libmei.Mordent();
            libmei.AddAttribute(mordent, 'form', 'norm');
            mlines = Self._property:MeasureObjects;
            mlines.Push(mordent._id);
        }

        case ('38')
        {
            // turn
            turn = libmei.Turn();
            libmei.AddAttribute(turn, 'form', 'norm');
            turn = AddBarObjectInfoToElement(sobj, turn);
            mlines = Self._property:MeasureObjects;
            mlines.Push(turn._id);
        }

        case ('39')
        {
            // inverted turn
            turn = libmei.Turn();
            libmei.AddAttribute(turn, 'form', 'inv');
            turn = AddBarObjectInfoToElement(sobj, turn);
            mlines = Self._property:MeasureObjects;
            mlines.Push(turn._id);
        }

        case ('242')
        {
            // triple staccato
            return null;
        }
    }
}  //$end

function ProcessScore () {
    //$module(ExportProcessors.mss)
    // processors are a bit like a workflow manager -- they orchestrate the
    // generators, which in turn use the converters to convert specific values from sibelius
    // to MEI.
    score = Self._property:ActiveScore;

    mei = libmei.Mei();
    libmei.setDocumentRoot(mei);

    libmei.AddAttribute(mei, 'xmlns:xlink', 'http://www.w3.org/1999/xlink');
    libmei.AddAttribute(mei, 'xmlns', 'http://www.music-encoding.org/ns/mei');
    libmei.AddAttribute(mei, 'meiversion', '3.0.0');

    header = sibmei2.GenerateMEIHeader();
    libmei.AddChild(mei, header);

    music = sibmei2.GenerateMEIMusic();
    libmei.AddChild(mei, music);

}  //$end

function ProcessBeam (bobj, layer) {
    //$module(ExportProcessors.mss)
    ret = null;

    if (bobj.Duration < 256)
    {
        // if this object is an eighth note but is not beamed, and if the
        // active beam is set, null out the active beam and return null.
        if (bobj.Beam = NoBeam and layer._property:ActiveBeamId != null)
        {
            layer._property:ActiveBeamId = null;
            return ret;
        }

        /*
            It's possible that Sibelius records a 'continue beam' at the start
            of a beamed group. Visually, this doesn't look out of place if the previous
            note was a quarter note or higher.

            The first check we do is if the note has a 'continue beam' attribute and
            the previous note has a duration higher than 256 (quarter) then we probably have
            a false negative (i.e., there is the start of a beam, but it isn't necessarily
            encoded correctly).
        */
        falseNegative = False;
        next_obj = bobj.NextItem(bobj.VoiceNumber, 'NoteRest');

        if ((bobj.Beam = ContinueBeam or bobj.Beam = SingleBeam) and layer._property:ActiveBeamId = null)
        {
            // by all accounts this should be a beamed note, but we'll need to double-check.
            prev_obj = bobj.PreviousItem(bobj.VoiceNumber, 'NoteRest');

            if (prev_obj != null and (prev_obj.Duration >= 256))
            {
                falseNegative = True;
            }
        }

        if (next_obj != null and (bobj.Beam = StartBeam or falseNegative = True) and next_obj.Beam = ContinueBeam)
        {
            // if:
            //  - we're not at the end of the bar
            //  - we have a start beam
            //  - the next note is a continue beam
            beam = libmei.Beam();
            layer._property:ActiveBeamId = beam._id;

            // return the beam so that we can add it to the tree.
            ret = beam;
        }

        if (layer._property:ActiveBeamId != null and (bobj.Beam = ContinueBeam or bobj.Beam = SingleBeam))
        {
            beamid = layer._property:ActiveBeamId;
            beam = libmei.getElementById(beamid);
            ret = beam;
        }
    }
    else
    {
        if (layer._property:ActiveBeamId != null)
        {
            // this is a break in any active beam, so register it as such.
            layer._property:ActiveBeamId = null;
        }
    }

    return ret;
}  //$end

function ProcessTuplet (bobj, meielement, layer) {
    //$module(ExportProcessors.mss)
    if (bobj.ParentTupletIfAny = null)
    {
        return null;
    }

    if (layer._property:ActiveTupletId = null)
    {
        tupletObject = bobj.ParentTupletIfAny;

        tuplet = libmei.Tuplet();

        layer._property:ActiveTupletObject = tupletObject;
        layer._property:ActiveTupletId = tuplet._id;

        if (libmei.GetName(meielement) = 'beam')
        {
            // get the first child
            startid = meielement.children[0];
        }
        else
        {
            startid = meielement._id;
        }

        libmei.AddAttribute(tuplet, 'startid', '#' & startid);
        libmei.AddAttribute(tuplet, 'num', tupletObject.Left);
        libmei.AddAttribute(tuplet, 'numbase', tupletObject.Right);

        tupletStyle = tupletObject.Style;

        switch (tupletStyle)
        {
            case(TupletNoNumber)
            {
                libmei.AddAttribute(tuplet, 'dur.visible', 'false');
            }
            case(TupletLeft)
            {
                libmei.AddAttribute(tuplet, 'num.format', 'count');
            }
            case(TupletLeftRight)
            {
                libmei.AddAttribute(tuplet, 'num.format', 'ratio');
            }
        }

        tupletBracket = tupletObject.Bracket;

        switch(tupletBracket)
        {
            case(TupletBracketOff)
            {
                libmei.AddAttribute(tuplet, 'bracket.visible', 'false');
            }
        }

        return tuplet;
    }
    else
    {
        tid = layer._property:ActiveTupletId;
        t = libmei.getElementById(tid);

        if (IsLastNoteInTuplet(bobj))
        {
            libmei.AddAttribute(t, 'endid', '#' & meielement._id);
            layer._property:ActiveTupletObject = null;
            layer._property:ActiveTupletId = null;
        }

        return t;
    }
}  //$end

function ShiftTupletToTupletSpan (tuplet, layer) {
    //$module(ExportProcessors.mss)
    /*
        Shifts the tuplet object to a tupletSpan object. This is
        useful if we need to define a tuplet outside of a hierarchy;
        for example, if a tuplet is only on part of a beam group.

        A tupletSpan supports many of the same attributes as a tuplet
        object, so we can copy the attributes verbatim. Functionally,
        it should behave the same way as a tuplet, except that it
        takes no child elements and the parent element is the measure,
        not the layer. These two things get handled higher up the
        processing chain, however, so we don't have to worry about them here.
    */

    tupletSpan = libmei.TupletSpan();
    libmei.SetAttributes(tupletSpan, tuplet.attrs);
    tupletSpan._property:AddedToMeasure = False;

    layer._property:ActiveTupletId = tupletSpan._id;

    if (tuplet._parent != null)
    {
        // if the tuplet has already been added to the tree,
        // remove it now. (Unfortunately, we can't delete the object,
        // but disowning it from the tree should be enough to keep it from
        // appearing in the output.)
        pobj = libmei.getElementById(tuplet._parent);
        libmei.RemoveChild(pobj, tuplet);
        tuplet._parent = null;
    }
}  //$end

function ProcessLyric (lyricobj, objectPositions) {
    //$module(ExportProcessors.mss)
    /*
        We need to track initial, medial, and terminal lyrics. Sibelius
        only allows us to know the medial and terminal, so we store all the
        syllables in an array until we reach the end of the word, and then
        attach them to the notes.
    */
    styleparts = MSplitString(lyricobj.StyleId, '.');
    verse_id = styleparts[5];
    verse_id_arr = MSplitString(verse_id, false);
    verse_num = verse_id_arr[5];
    bar_num = lyricobj.ParentBar.BarNumber;
    staff_num = lyricobj.ParentBar.ParentStaff.StaffNum;
    voicenum = lyricobj.VoiceNumber;

    if (voicenum = 0)
    {
        // assign it to the first voice, since we don't have any notes in voice 0.
        voicenum = 1;
        warnings = Self._property:warnings;
        warnings.Push(utils.Format(_ObjectAssignedToAllVoicesWarning, bar_num, voicenum, 'Lyric object'));
    }

    lyricwords = Self._property:LyricWords;

    if (lyricwords.PropertyExists(staff_num) = False)
    {
        lyricwords[staff_num] = CreateDictionary();
    }

    lyricstaff = lyricwords[staff_num];

    if (lyricstaff.PropertyExists(voicenum) = False)
    {
        lyricstaff[voicenum] = CreateDictionary();
    }

    lyricvoice = lyricstaff[voicenum];

    if (lyricvoice.PropertyExists(verse_num) = False)
    {
        lyricvoice[verse_num] = CreateSparseArray();
    }

    if (lyricobj.SyllableType = MiddleOfWord)
    {
        lyricvoice[verse_num].Push(lyricobj);
        // we haven't reached the end of the word yet, so just return
        // and keep going.
        return null;
    }

    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // anything past here is in the EndOfWord condition.
    // this should return a sparse array containing the syllables of the word.
    lyricvoice[verse_num].Push(lyricobj);
    lyric_word = lyricvoice[verse_num];
    objects = objectPositions[voicenum];

    obj_id = null;
    obj = null;

    for j = 0 to lyric_word.Length
    {
        syl = lyric_word[j];

        verse = libmei.Verse();
        libmei.AddAttribute(verse, 'n', verse_num);
        sylel = libmei.Syl();
        libmei.SetText(sylel, syl.Text);
        libmei.AddChild(verse, sylel);

        if (j = 0)
        {
            libmei.AddAttribute(sylel, 'wordpos', 'i'); // 'initial'

            if (lyric_word.Length > 1)
            {
                libmei.AddAttribute(sylel, 'con', 'd');
            }
        }
        else
        {
            if (syl.SyllableType = EndOfWord)
            {
                libmei.AddAttribute(sylel, 'wordpos', 't'); // 'terminal'

                if (syl.NumNotes > 1)
                {
                    libmei.AddAttribute(sylel, 'con', 'u'); // 'underscore'
                }

            }
            else
            {
                libmei.AddAttribute(sylel, 'wordpos', 'm'); // medial
                libmei.AddAttribute(sylel, 'con', 'd');
            }
        }

        obj = GetNoteObjectAtPosition(syl);

        if (obj != null)
        {
            name = libmei.GetName(obj);

            if (name = 'rest')
            {
                warnings = Self._property:warnings;
                warnings.Push(utils.Format(_ObjectIsOnAnIllogicalObject, bar_num, voicenum, 'Lyric', 'rest'));
            }

            if (name = 'chord')
            {
                warnings = Self._property:warnings;
                warnings.Push(utils.Format(_ObjectIsOnAnIllogicalObject, bar_num, voicenum, 'Lyric', 'chord'));
            }

            libmei.AddChild(obj, verse);
        }
    }

    // now reset the syllable array for this voice
    lyricvoice[verse_num] = CreateSparseArray();
}  //$end

function ProcessSystemStaff (score) {
    //$module(ExportProcessors.mss)
    systf = score.SystemStaff;

    for each bar in systf
    {
        for each bobj in bar
        {
            switch (bobj.Type)
            {
                case ('SpecialBarline')
                {
                    spclbarlines = Self._property:SpecialBarlines;
                    if (spclbarlines.PropertyExists(bar.BarNumber) = False)
                    {
                        spclbarlines[bar.BarNumber] = CreateSparseArray();
                    }

                    spclbarlines[bar.BarNumber].Push(ConvertBarline(bobj.BarlineInternalType));
                }
                case ('SystemTextItem')
                {
                    if (bobj.OnNthBlankPage < 0)
                    {
                        ProcessFrontMatter(bobj);
                    }

                    systemtext = Self._property:SystemText;

                    if (systemtext.PropertyExists(bar.BarNumber) = False)
                    {
                        systemtext[bar.BarNumber] = CreateSparseArray();
                    }

                    systemtext[bar.BarNumber].Push(bobj);
                }
                case ('Graphic')
                {
                    Log('Found a graphic!');
                    Log('is object? ' & IsObject(bobj));
                }
                case ('RepeatTimeLine')
                {
                    RegisterVolta(bobj);
                }
            }
        }
    }
}  //$end

function ProcessFrontMatter (bobj) {
    //$module(ExportProcessors.mss)
    /*
        For example, if page 2 (0-indexed) is the first page of music,
        then 'OnNthPage' will be 2, but the system staff items for
        the first page of text will be -2, so 2 + (-2) = 0 + 1;
    */
    bar = bobj.ParentBar;
    text = '';

    pnum = (bar.OnNthPage + bobj.OnNthBlankPage) + 1;
    frontmatter = Self._property:FrontMatter;

    if (frontmatter.PropertyExists(pnum) = False)
    {
        pb = libmei.Pb();
        libmei.AddAttribute(pb, 'n', pnum);
        frontmatter[pnum] = CreateSparseArray(pb);
    }
    pagematter = frontmatter[pnum];

    text = GenerateFormattedString(bobj);
    frontmatter[pnum] = pagematter.Concat(text);

}  //$end

function RegisterVolta (bobj) {
    //$module(ExportProcessors.mss)
    voltabars = Self._property:VoltaBars;
    style = MSplitString(bobj.StyleId, '.');

    if (style[2] = 'repeat')
    {
        voltabars[bobj.ParentBar.BarNumber] = bobj;
    }
}  //$end

function ProcessVolta (mnum) {
    //$module(ExportProcessors.mss)
    voltabars = Self._property:VoltaBars;

    if (voltabars.PropertyExists(mnum))
    {
        voltaElement = libmei.Ending();

        Self._property:VoltaElement = voltaElement;

        voltaObject = voltabars[mnum];
        voltainfo = ConvertEndingValues(voltaObject.StyleId);

        libmei.AddAttribute(voltaElement, 'n', voltainfo[0]);
        libmei.AddAttribute(voltaElement, 'label', voltainfo[1]);
        libmei.AddAttribute(voltaElement, 'type', voltainfo[2]);

        if (voltaObject.EndBarNumber != mnum)
        {
            Self._property:ActiveVolta = voltaObject;
        }

        return voltaElement;
    }
    else
    {
        if (Self._property:ActiveVolta != null)
        {
            // we have an unresolved volta, so
            // we'll keep the previous parentElement
            // active.
            activeVolta = Self._property:ActiveVolta;
            voltaElement = Self._property:VoltaElement;

            // if the end bar is the current bar OR if the end
            // bar is the next bar, but the end position is 0, we're escaping the
            // volta the next time around.
            if ((activeVolta.EndBarNumber = mnum) or
                (activeVolta.EndBarNumber = (mnum + 1) and activeVolta.EndPosition = 0))
            {
                Self._property:ActiveVolta = null;
                Self._property:VoltaElement = null;
            }
            return null;
        }
    }

    return null;
}  //$end

function ProcessSymbol (sobj) {
    //$module(ExportProcessors.mss)
    Log('symbol index: ' & sobj.Index & ' name: ' & sobj.Name);
    Log(sobj.VoiceNumber);

    switch (sobj.Index)
    {
        case ('32')
        {
            // trill
            trill = GenerateTrill(sobj);
            mlines = Self._property:MeasureObjects;
            mlines.Push(trill._id);
        }

        case ('36')
        {
            // inverted mordent
            mordent = libmei.Mordent();
            libmei.AddAttribute(mordent, 'form', 'inv');
            mlines = Self._property:MeasureObjects;
            mlines.Push(mordent._id);
        }

        case ('37')
        {
            // mordent
            mordent = libmei.Mordent();
            libmei.AddAttribute(mordent, 'form', 'norm');
            mlines = Self._property:MeasureObjects;
            mlines.Push(mordent._id);
        }

        case ('38')
        {
            // turn
            turn = libmei.Turn();
            libmei.AddAttribute(turn, 'form', 'norm');
            turn = AddBarObjectInfoToElement(sobj, turn);
            mlines = Self._property:MeasureObjects;
            mlines.Push(turn._id);
        }

        case ('39')
        {
            // inverted turn
            turn = libmei.Turn();
            libmei.AddAttribute(turn, 'form', 'inv');
            turn = AddBarObjectInfoToElement(sobj, turn);
            mlines = Self._property:MeasureObjects;
            mlines.Push(turn._id);
        }

        case ('242')
        {
            // triple staccato
            return null;
        }
    }
}  //$end


styling

styling

// NOTE: the current vector tile source for this style will not
// be around for long. Do not use it in other projects - export
// your own version from the 'natural-earth.tm2source' project.

// Common Colors //
@water_fill: #adf;
@water_line: #48d;

Map {
  background-color: #fff;
}

#water {
  polygon-fill: @water_fill;
  line-color: @water_line;
  line-join: round;
  line-width: 0.8;
  [zoom>=4] { line-width: 1; }
  [zoom>=6] { line-width: 1.2; }
}

#admin_0_lines[zoom>=1] {
  line-width: 0.6;
  line-color: #644;
  [class='dispute'] { line-dasharray: 5,3; }
  [class='control'] { line-dasharray: 2,2; }
  [zoom>=2] { line-width: 1; }
  [zoom>=6] { line-width: 1.2; }
}

#admin_1_lines[zoom>=1] {
  line-width: 0.8;
  line-color: #aaa;
  line-dasharray: 3,1;
}

#ice {
  opacity: 0.5;
  polygon-fill: #eff;
  line-color: #8de;
  line-join: round;
  line-dasharray: 5,1;
}

#playas {
  polygon-fill: #f8f8e8;
  line-color: @water_line;
  line-dasharray: 5,3;
  [zoom<=6] {
    line-width: 0.5;
    line-dasharray: 4,2;
  }
}

#urban_areas {
  polygon-fill: #800;
  polygon-opacity: 0.075;
}

#geographic_lines {
  line-color: #fff;
  line-dasharray: 6,2;
}

#roads::ferry[featurecla='Ferry'] {
  line-color: #6be;
  line-dasharray: 5,2;
}

#roads::road[featurecla='Road'] {
  line-color: #fff;
  line-width: 0.75;
  [type='Major Highway'] {
    [zoom>=5] { line-width: 1.2; }
    [zoom>=6] { line-width: 1.5; }
    [zoom>=7] { line-width: 1.8; }
  }
  [type='Secondary Highway'] {
    [zoom>=6] { line-width: 1; }
    [zoom>=7] { line-width: 1.2; }
    [zoom>=8] { line-width: 1.4; }
  }
}

@mix_col: #fff;
@mix_amt: 15;
#country_fill {
  [color=1] { polygon-fill: mix(#D19C44,@mix_col,@mix_amt); }
  [color=2] { polygon-fill: mix(#99AF4D,@mix_col,@mix_amt); }
  [color=3] { polygon-fill: mix(#5AB87B,@mix_col,@mix_amt); }
  [color=4] { polygon-fill: mix(#2CB8B2,@mix_col,@mix_amt); }
  [color=5] { polygon-fill: mix(#BB99CF,@mix_col,@mix_amt); }
  [color=6] { polygon-fill: mix(#EE85A7,@mix_col,@mix_amt); }
  [color=7] { polygon-fill: mix(#F78571,@mix_col,@mix_amt); }
  ::band[zoom>=1] {
    comp-op: overlay;
    line-color: #000;
    line-join: round;
    line-width: 3;
    [zoom>=2] { line-width: 4; }
    [zoom>=4] { line-width: 6; }
    [zoom>=6] { line-width: 8; }
  }
  ::band2[zoom>=1] {
    comp-op: overlay;
    line-color: #000;
    line-join: round;
    line-width: 6;
    [zoom>=2] { line-width: 8; }
    [zoom>=4] { line-width: 12; }
    [zoom>=6] { line-width: 16; }
  }
}

// NOTE: the current vector tile source for this style will not
// be around for long. Do not use it in other projects - export
// your own version from the 'natural-earth.tm2source' project.

// Common Colors //
@water_fill: #ace;
@water_line: #6af;

Map {
  background-color: #fff;
}

#water {
  polygon-fill: @water_fill;
  line-color: @water_line;
}

#admin_0_lines {
  line-width: 1;
  line-color: #644;
  [class='dispute'] { line-dasharray: 5,3; }
  [class='control'] { line-dasharray: 2,2; }
}

#ice {
  polygon-fill: #fff;
}

#playas {
  polygon-fill: #ffc;
  line-color: @water_line;
  line-dasharray: 5,3;
  [zoom<=6] {
    line-width: 0.5;
    line-dasharray: 4,2;
  }
}

#urban_areas {
  polygon-fill: #fff0b0;
}

#geographic_lines {
  line-color: #fff;
  line-dasharray: 6,2;
}

#roads::ferry[featurecla='Ferry'] {
  line-color: #6be;
  line-dasharray: 5,2;
}

#roads::road[featurecla='Road'] {
  line-color: #daa;
  line-width: 0.75;
  [type='Major Highway'] {
    [zoom>=5] { line-width: 1.2; }
    [zoom>=6] { line-width: 1.5; }
    [zoom>=7] { line-width: 1.8; }
  }
  [type='Secondary Highway'] {
    [zoom>=6] { line-width: 1; }
    [zoom>=7] { line-width: 1.2; }
    [zoom>=8] { line-width: 1.4; }
  }
}


update osm id of stamen building

update osm id of stamen building

@color_physical: #000;
@color_physical_bright: #fff;
@color_water: #000;
@color_administrative_dark: #000;
@color_administrative_bright: #fff;
@color_administrative_medium_low: #000;
@color_administrative_medium_high: #000;
@color_administrative_medium_high2: #000;
@color_transport: #000;
@color_transport_casing: #fff;
@color_transport_inline: #fff;
@color_transport_tunnel: #ccc;
@color_transport_minor: #ccc;
@color_transport_rail: #444;
@color_transport_path: #ededed;
@color_building_outline: #000;
@color_building_outline_special: #00aeef;
@color_airport_runways: #eee;
@color_airport_runways_detail: #f2f2f2;

Map {
  background-color: @color_physical;
  font-directory: url("fonts/");
}

/**
 * "shore" is a general class for layers with continents, coastlines, lakes,
 * and other kinds of meeting points between water and land.
 */
.shore {
  line-color: @color_physical;
  line-cap: round;
  line-join: round;
  line-width: 0;
}

#country-shapes-110m {
  line-width: 0.25;
  polygon-fill: @color_administrative_bright;
}

#land-shapes-110m,
#country-shapes-50m,
#country-shapes-10m,
{
  line-width: 0.25;
  polygon-fill: @color_physical_bright;
}

.country-boundary-10m {
  ::whiteout {
    [zoom>=7] {
      line-color: @color_administrative_bright;
      line-width: 2;
    }
  }

  [zoom>=6] {
    line-color: @color_administrative_dark;
    line-width: 1.2;
  }

  [zoom>=7] {
    line-width: 1.2;
    line-dasharray: 3,7;
    line-cap: round;
  }
}

#admin1-lines-50m {
  line-width: 0.35;
  line-color: @color_administrative_dark;
}

#admin1-lines-10m {
  [zoom>=6] {
    line-width: 0.6;
    line-color: @color_administrative_dark;
  }

  [zoom>=7] {
    line-width: 1.5;
    line-color: @color_administrative_medium_low;
    line-dasharray: 1,5;
    line-cap: round;
  }

  [zoom>=8] {
    line-width: 2.0;
    line-color: @color_administrative_medium_high;
  }

  [zoom>=9] {
    line-color: @color_administrative_medium_high2;
  }
}

#lakes-110m[zoom<3][scalerank<1],
#lakes-50m[zoom=3][scalerank<2],
#lakes-50m[zoom=4][scalerank<3],
#lakes-50m[zoom=5][scalerank<5],
#lakes-50m[zoom=6],
#lakes-10m,
{
  line-width: 1;
  polygon-fill: @color_physical;
}

#ne-roads {
  ::casing {
    line-color: @color_transport_casing;
    line-opacity: 0.5;
    line-width: 0;

    [zoom=7][scalerank<=7] {
      line-width: 2.25;
    }

    [zoom=8][scalerank<=8] {
      line-width: 3.25;
    }
  }

  line-color: @color_transport;
  line-width: 0;

  [zoom=6][scalerank>=3][scalerank<=6] {
    line-width: 0.1;
  }

  [zoom=7] {
    [scalerank<=6],
    [scalerank<=7][expressway=1],
    [scalerank<=7][type='Major Highway'],
    [scalerank<=7][type='Secondary Highway'],
    {
      line-width: 0.1;
    }

    [scalerank>=3][scalerank<=5] {
      line-width: 1.5;
    }
  }

  [zoom=8] {
    [scalerank<=8] {
      line-width: 0.1;
    }

    [type='Beltway'],
    [scalerank<=8][expressway=1],
    {
      line-width: 1.5;
    }
  }
}

/**
 * Ocean, lake, and river polygons
 */
#water-bodies-low[zoom=8][area>50000000],
#water-bodies-low[zoom=9][area>10000000],
#water-bodies-low[zoom=10][area>2500000],
#water-bodies-med[zoom=11][area> 800000],
#water-bodies-med[zoom=12][area> 500000],
#water-bodies-med[zoom=13][area>  25000],
#water-bodies-high[zoom=14][area> 10000],
#water-bodies-high[zoom>=15]
{
  polygon-fill: @color_water;
}

/**
 * Water bodies that are parts of rivers
 * should never be filtered
 */
#water-bodies-low[type='riverbank'],
#water-bodies-med[type='riverbank'],
#water-bodies-high[type='riverbank']
{
  polygon-fill: @color_water;
}

#land {
  polygon-fill: @color_physical_bright;
}

#admin1-lines-osm,
{
  line-width: 2.0;
  line-color: @color_administrative_medium_high2;
  line-dasharray: 1,5;
  line-cap: round;
}

#buildings-med {
  [area>=40000] {
    polygon-pattern-file: url("images/stripe_sm.png");
    line-width: 0.5;
    line-color: @color_building_outline;
  }
}

#buildings-high {
  [zoom>=14] {
    [area>=20000] {
      polygon-pattern-file: url("images/stripe_med.png");
      line-width: 0.5;
      line-color: @color_building_outline;
    }
  }

  [zoom>=16] {
    line-width: 0.5;
  }

  [zoom=15][area>=16000],
  [zoom=16][area>=8000],
  [zoom=17][area>=4000],
  [zoom>=18],
  {
    polygon-pattern-file: url("images/stripe.png");
    polygon-pattern-alignment: global;
    line-width: 0.5;
    line-color: @color_building_outline;
  }

  // Stamen HQ fancy candycane striping
  [zoom>=18] {
    [osm_id=260351411],
    [osm_id=224030635], // Seth's house
    {
      polygon-pattern-file: url("images/stripe_color.png");
      line-width: 1.5;
      line-color: @color_building_outline_special;
    }
  }
}

#green-areas-low[zoom=10][area>5000000],
#green-areas-med[zoom=11][area>1000000],
#green-areas-med[zoom=12][area> 500000],
#green-areas-med[zoom=12][area> 200000],
#green-areas-med[zoom=13][area>  75000],
#green-areas-high[zoom=14][area> 10000],
#green-areas-high[zoom>14],
{
  polygon-pattern-alignment: global;
  polygon-pattern-file: url("images/halftone2.png");

  [type='nature_reserve'] {
      polygon-pattern-file: url("images/halftone2-transparent.png");
  }
}

#brown-areas-low[zoom=10][area>5000000],
#brown-areas-med[zoom=11][area>1000000],
#brown-areas-med[zoom=12][area> 500000],
#brown-areas-med[zoom=12][area> 200000],
#brown-areas-med[zoom=13][area>  75000],
#brown-areas-high[zoom=14][area> 10000],
#brown-areas-high[zoom>14],
{
  polygon-pattern-alignment: global;
  polygon-pattern-file: url("images/halftone2.png");
}

#aeroways {
  line-color: @color_airport_runways;
  line-cap: square;
  line-join: miter;

  [zoom>=15] {
    line-color: @color_airport_runways_detail;
  }

  [type='runway'] {
    [zoom=12] {
      line-width: 2;
    }

    [zoom=13] {
      line-width: 4;
    }

    [zoom=14] {
      line-width: 8;
    }

    [zoom=15] {
      line-width: 16;
    }

    [zoom=16] {
      line-width: 32;
    }

    [zoom=17] {
      line-width: 64;
    }

    [zoom>=18] {
      line-width: 128;
    }
  }

  [type='taxiway'] {
    [zoom=13] {
      line-width: 1;
    }

    [zoom=14] {
      line-width: 2;
    }

    [zoom=15] {
      line-width: 4;
    }

    [zoom=16] {
      line-width: 8;
    }

    [zoom=17] {
      line-width: 16;
    }

    [zoom>=18] {
      line-width: 32;
    }
  }
}

.roads {
  ::casing,
  ::outline,
  {
    line-cap: butt;
    line-width: 0;
    line-color: @color_transport_casing;
  }

  line-join: round;
  line-cap: round;
  line-width: 0;
  line-color: @color_transport;

  [is_tunnel='yes']
  {
    [zoom>=14]
    {
      ::casing {
        line-opacity: 0.5;
      }

      ::outline {
        line-opacity: 0.5;
      }
    }

    [zoom>=15]
    {
      line-opacity: 0; // vs. line-width: 0 to override subsequent styling
    }
  }

  [is_link='yes']
  {
    [zoom>=16]
    {
      ::casing {
        line-width: 8;
      }

      line-width: 4;
    }
  }
}

.roads[kind='highway']
{
  [zoom>=9] {
    ::outline {
      line-width: 4.25;
    }

    line-width: 1.5;
  }

  [zoom>=10] {
    ::outline {
      line-width: 6;
    }

    line-width: 2;
  }

  [zoom>=11] {
    line-width: 2.5;
  }

  [zoom>=12] {
    ::outline {
      line-width: 8;
    }

    line-width: 3;

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 0.5;
    }
  }

  [zoom>=13] {
    ::outline {
      line-width: 8;
    }

    line-width: 3;

    [is_link='yes'] {
      ::outline {
        line-width: 3;
      }

      line-width: 1;

      [is_bridge='yes'] {
        ::outline {
          line-width: 3;
        }
      }
    }
  }

  [zoom>=14] {
    ::outline {
      line-width: 8;
    }

    line-width: 4;

    [is_bridge='yes'] {
      ::casing {
        line-width: 8;
      }
    }

    [is_link='yes'] {
      ::outline {
        line-width: 6;
      }

      line-width: 2.5;

      [is_bridge='yes'] {
        ::casing {
          line-width: 6;
        }
      }
    }
  }

  [zoom>=15] {
    ::casing {
      line-width: 11;
    }

    line-width: 6;

    [is_link='yes'] {
      ::casing {
        line-width: 6.5;
      }

      line-width: 2.25;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 5;
        line-opacity: 0.7;
        line-color: @color_transport_tunnel;
      }

      line-width: 3;
      line-opacity: 0.5;
    }
  }

  [zoom>=16] {
    ::casing {
      line-width: 14;
    }

    line-width: 9;

    [is_link='yes'] {
      ::casing {
        line-width: 7;
      }

      line-width: 2.5;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 7;
        line-opacity: 0.4;
      }

      line-opacity: 0.7;
      line-color: @color_transport_tunnel;

      [is_link='yes'] {
        ::casing {
          line-color: @color_transport_casing;
        }
      }
    }
  }

  [zoom>=17] {
    ::casing {
      line-width: 24;
    }

    line-width: 15;

    [is_link='yes'] {
      ::casing {
        line-width: 9;
      }

      line-width: 5;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 18;
      }

      line-width: 12;

      [is_link='yes'] {
        ::casing {
          line-width: 9;
        }
      }
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 42;
      line-color: @color_transport;
    }

    line-width: 28;
    line-color: @color_transport_inline;

    [is_bridge='yes'] {
      ::casing {
        line-width: 44;
      }
    }

    [is_link='yes'] {
      ::casing {
        line-width: 14;
        line-color: @color_transport;
      }

      line-width: 10;
      line-color: @color_transport_inline;

      [is_bridge='yes'] {
        ::casing {
          line-width: 15;
        }
      }
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 22;
      }

      line-width: 18;
    }
  }

  [zoom>=19] {
    ::casing {
      line-width: 49;
      line-color: @color_transport;
    }

    line-width: 35;
    line-color: @color_transport_casing;

    [is_bridge='yes'] {
      ::casing {
        line-width: 51;
      }
    }

    [is_link='yes'] {
      ::casing {
        line-width: 20;
      }

      line-width: 16;
      line-color: @color_transport_casing;

      [is_bridge='yes'] {
        ::casing {
          line-width: 21;
        }
      }
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 30;
      }

      line-width: 26;

      [is_link='yes'] {
        ::casing {
          line-width: 13;
        }
      }
    }
  }
}

.roads[kind='major_road']
{
  [zoom<=12] {
    line-color: #000;
  }

  [zoom>=9] {
    line-width: 0.15;
  }

  [zoom>=10] {
    line-width: 0.5;
  }

  [zoom>=11] {
    ::outline {
      line-width: 1.25;
    }

    line-width: 0.7;
  }

  [zoom>=12] {
    ::outline {
      line-width: 5;
    }

    line-width: 1;

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 0.5;
    }
  }

  [zoom>=13] {
    line-width: 1.5;
  }

  [zoom>=14] {
    ::outline {
      line-width: 6;
    }

    line-width: 1.9;

    [is_bridge='yes'] {
      ::casing {
        line-width: 6;
      }
    }

    [is_link='yes'] {
      ::outline {
        line-width: 6;
      }

      line-width: 1.9;

      [is_bridge='yes'] {
        ::casing {
          line-width: 6;
        }
      }
    }
  }

  [zoom>=15] {
    ::casing {
      line-width: 8;
    }

    line-width: 5;

    [is_link='yes'] {
      ::casing {
        line-width: 5.5;
      }

      line-width: 2.25;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 5;
        line-opacity: 0.7;
        line-color: @color_transport_tunnel;
      }

      line-width: 3;
      line-opacity: 0.5;
    }
  }

  [zoom>=16] {
    ::casing {
      line-width: 11;
    }

    line-width: 7;

    [is_link='yes'] {
      ::casing {
        line-width: 7;
      }

      line-width: 2.5;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 7;
        line-opacity: 0.4;
      }

      line-opacity: 0.7;
      line-color: @color_transport_tunnel;

      [is_link='yes'] {
        ::casing {
          line-color: @color_transport_casing;
        }
      }
    }
  }

  [zoom>=17] {
    ::casing {
      line-width: 18;
    }

    line-width: 12;

    [is_link='yes'] {
      ::casing {
        line-width: 8;
      }

      line-width: 4;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 18;
      }

      line-width: 12;

      [is_link='yes'] {
        ::casing {
          line-width: 9;
        }
      }
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 22;
      line-color: @color_transport;
    }

    line-width: 18;
    line-color: @color_transport_inline;

    [is_bridge='yes'] {
      ::casing {
        line-width: 24;
      }
    }

    [is_link='yes'] {
      ::casing {
        line-width: 13;
        line-color: @color_transport;
      }

      line-width: 9;
      line-color: @color_transport_inline;

      [is_bridge='yes'] {
        ::casing {
          line-width: 14;
        }
      }
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 22;
      }

      line-width: 18;
    }
  }

  [zoom>=19] {
    ::casing {
      line-width: 30;
    }

    line-width: 26;
    line-color: @color_transport_casing;

    [is_bridge='yes'] {
      ::casing {
        line-width: 32;
      }
    }

    [is_link='yes'] {
      ::casing {
        line-width: 17;
      }

      line-width: 13;
      line-color: @color_transport_casing;

      [is_bridge='yes'] {
        ::casing {
          line-width: 18;
        }
      }
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 30;
      }

      line-width: 26;

      [is_link='yes'] {
        ::casing {
          line-width: 13;
        }
      }
    }
  }
}

.roads[kind='minor_road']
{
  [zoom<=14] {
    line-color: #999;
  }

  [zoom>=16] {
    line-color: @color_transport_minor;
  }

  [zoom>=10] {
    line-width: 0.2;
  }

  [zoom>=13] {
    line-width: 0.4;
  }

  [zoom>=14] {
    line-width: 0.8;
  }

  [zoom>=15] {
    line-width: 1.5;

    [is_tunnel='yes'] {
      ::casing {
        line-opacity: 0.7;
        line-color: @color_transport_tunnel;
      }

      line-opacity: 0.5;
    }
  }

  [zoom>=16] {
    ::casing {
      line-width: 7;
    }

    line-width: 4;
    line-color: @color_transport;
  }

  [zoom>=17] {
    ::casing {
      line-width: 9;
    }

    line-width: 7;
  }

  [zoom>=18] {
    ::casing {
      line-width: 17;
      line-color: @color_transport;
    }

    line-width: 13;
    line-color: @color_transport_casing;
  }

  [zoom>=19] {
    ::casing {
      line-width: 20;
    }

    line-width: 16;
  }
}

.roads[kind='rail']
{
  ::casing,
  ::outline,
  {
    line-color: @color_transport_rail;
  }

  line-color: @color_transport_rail;

  [zoom>=14] {
    ::casing {
      line-width: 3;
      line-dasharray: 1,3;
    }

    line-width: 1;
  }

  [zoom>=16] {
    ::casing {
      line-width: 5;
      line-dasharray: 1,4;
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 6;
      line-dasharray: 2,6;
    }

    line-width: 2;
  }

  [zoom>=19] {
    ::casing {
      line-width: 9;
      line-dasharray: 4,7;
    }

    line-width: 4;
  }
}

.roads[highway='service']
{
  [zoom>=15]
  {
    line-width: 1.5;
  }

  [zoom>=16] {
    ::casing {
      line-width: 4;
    }

    line-width: 2;
  }

  [zoom>=17] {
    ::casing {
      line-width: 6;
    }

    line-width: 4;
  }
}

.roads[kind='path']
{
  ::casing {
    line-color: @color_transport_path;
  }

  line-color: @color_transport_casing;

  [zoom>=15] {
    ::casing {
      line-width: 4;
    }

    line-width: 1.5;
    line-cap: butt;
  }

  [zoom>=16] {
    ::casing {
      line-width: 5;
    }

    line-width: 2;
  }

  [zoom>=17] {
    line-width: 3;
  }

  [zoom>=19] {
    line-width: 4;
  }
}

@color_physical: #000;
@color_physical_bright: #fff;
@color_water: #000;
@color_administrative_dark: #000;
@color_administrative_bright: #fff;
@color_administrative_medium_low: #000;
@color_administrative_medium_high: #000;
@color_administrative_medium_high2: #000;
@color_transport: #000;
@color_transport_casing: #fff;
@color_transport_inline: #fff;
@color_transport_tunnel: #ccc;
@color_transport_minor: #ccc;
@color_transport_rail: #444;
@color_transport_path: #ededed;
@color_building_outline: #000;
@color_building_outline_special: #00aeef;
@color_airport_runways: #eee;
@color_airport_runways_detail: #f2f2f2;

Map {
  background-color: @color_physical;
  font-directory: url("fonts/");
}

/**
 * "shore" is a general class for layers with continents, coastlines, lakes,
 * and other kinds of meeting points between water and land.
 */
.shore {
  line-color: @color_physical;
  line-cap: round;
  line-join: round;
  line-width: 0;
}

#country-shapes-110m {
  line-width: 0.25;
  polygon-fill: @color_administrative_bright;
}

#land-shapes-110m,
#country-shapes-50m,
#country-shapes-10m,
{
  line-width: 0.25;
  polygon-fill: @color_physical_bright;
}

.country-boundary-10m {
  ::whiteout {
    [zoom>=7] {
      line-color: @color_administrative_bright;
      line-width: 2;
    }
  }

  [zoom>=6] {
    line-color: @color_administrative_dark;
    line-width: 1.2;
  }

  [zoom>=7] {
    line-width: 1.2;
    line-dasharray: 3,7;
    line-cap: round;
  }
}

#admin1-lines-50m {
  line-width: 0.35;
  line-color: @color_administrative_dark;
}

#admin1-lines-10m {
  [zoom>=6] {
    line-width: 0.6;
    line-color: @color_administrative_dark;
  }

  [zoom>=7] {
    line-width: 1.5;
    line-color: @color_administrative_medium_low;
    line-dasharray: 1,5;
    line-cap: round;
  }

  [zoom>=8] {
    line-width: 2.0;
    line-color: @color_administrative_medium_high;
  }

  [zoom>=9] {
    line-color: @color_administrative_medium_high2;
  }
}

#lakes-110m[zoom<3][scalerank<1],
#lakes-50m[zoom=3][scalerank<2],
#lakes-50m[zoom=4][scalerank<3],
#lakes-50m[zoom=5][scalerank<5],
#lakes-50m[zoom=6],
#lakes-10m,
{
  line-width: 1;
  polygon-fill: @color_physical;
}

#ne-roads {
  ::casing {
    line-color: @color_transport_casing;
    line-opacity: 0.5;
    line-width: 0;

    [zoom=7][scalerank<=7] {
      line-width: 2.25;
    }

    [zoom=8][scalerank<=8] {
      line-width: 3.25;
    }
  }

  line-color: @color_transport;
  line-width: 0;

  [zoom=6][scalerank>=3][scalerank<=6] {
    line-width: 0.1;
  }

  [zoom=7] {
    [scalerank<=6],
    [scalerank<=7][expressway=1],
    [scalerank<=7][type='Major Highway'],
    [scalerank<=7][type='Secondary Highway'],
    {
      line-width: 0.1;
    }

    [scalerank>=3][scalerank<=5] {
      line-width: 1.5;
    }
  }

  [zoom=8] {
    [scalerank<=8] {
      line-width: 0.1;
    }

    [type='Beltway'],
    [scalerank<=8][expressway=1],
    {
      line-width: 1.5;
    }
  }
}

/**
 * Ocean, lake, and river polygons
 */
#water-bodies-low[zoom=8][area>50000000],
#water-bodies-low[zoom=9][area>10000000],
#water-bodies-low[zoom=10][area>2500000],
#water-bodies-med[zoom=11][area> 800000],
#water-bodies-med[zoom=12][area> 500000],
#water-bodies-med[zoom=13][area>  25000],
#water-bodies-high[zoom=14][area> 10000],
#water-bodies-high[zoom>=15]
{
  polygon-fill: @color_water;
}

/**
 * Water bodies that are parts of rivers
 * should never be filtered
 */
#water-bodies-low[type='riverbank'],
#water-bodies-med[type='riverbank'],
#water-bodies-high[type='riverbank']
{
  polygon-fill: @color_water;
}

#land {
  polygon-fill: @color_physical_bright;
}

#admin1-lines-osm,
{
  line-width: 2.0;
  line-color: @color_administrative_medium_high2;
  line-dasharray: 1,5;
  line-cap: round;
}

#buildings-med {
  [area>=40000] {
    polygon-pattern-file: url("images/stripe_sm.png");
    line-width: 0.5;
    line-color: @color_building_outline;
  }
}

#buildings-high {
  [zoom>=14] {
    [area>=20000] {
      polygon-pattern-file: url("images/stripe_med.png");
      line-width: 0.5;
      line-color: @color_building_outline;
    }
  }

  [zoom>=16] {
    line-width: 0.5;
  }

  [zoom=15][area>=16000],
  [zoom=16][area>=8000],
  [zoom=17][area>=4000],
  [zoom>=18],
  {
    polygon-pattern-file: url("images/stripe.png");
    polygon-pattern-alignment: global;
    line-width: 0.5;
    line-color: @color_building_outline;
  }

  // Stamen HQ fancy candycane striping
  [zoom>=18] {
    [osm_id=45074542],
    [osm_id=224030635], // Seth's house
    {
      polygon-pattern-file: url("images/stripe_color.png");
      line-width: 1.5;
      line-color: @color_building_outline_special;
    }
  }
}

#green-areas-low[zoom=10][area>5000000],
#green-areas-med[zoom=11][area>1000000],
#green-areas-med[zoom=12][area> 500000],
#green-areas-med[zoom=12][area> 200000],
#green-areas-med[zoom=13][area>  75000],
#green-areas-high[zoom=14][area> 10000],
#green-areas-high[zoom>14],
{
  polygon-pattern-alignment: global;
  polygon-pattern-file: url("images/halftone2.png");

  [type='nature_reserve'] {
      polygon-pattern-file: url("images/halftone2-transparent.png");
  }
}

#brown-areas-low[zoom=10][area>5000000],
#brown-areas-med[zoom=11][area>1000000],
#brown-areas-med[zoom=12][area> 500000],
#brown-areas-med[zoom=12][area> 200000],
#brown-areas-med[zoom=13][area>  75000],
#brown-areas-high[zoom=14][area> 10000],
#brown-areas-high[zoom>14],
{
  polygon-pattern-alignment: global;
  polygon-pattern-file: url("images/halftone2.png");
}

#aeroways {
  line-color: @color_airport_runways;
  line-cap: square;
  line-join: miter;

  [zoom>=15] {
    line-color: @color_airport_runways_detail;
  }

  [type='runway'] {
    [zoom=12] {
      line-width: 2;
    }

    [zoom=13] {
      line-width: 4;
    }

    [zoom=14] {
      line-width: 8;
    }

    [zoom=15] {
      line-width: 16;
    }

    [zoom=16] {
      line-width: 32;
    }

    [zoom=17] {
      line-width: 64;
    }

    [zoom>=18] {
      line-width: 128;
    }
  }

  [type='taxiway'] {
    [zoom=13] {
      line-width: 1;
    }

    [zoom=14] {
      line-width: 2;
    }

    [zoom=15] {
      line-width: 4;
    }

    [zoom=16] {
      line-width: 8;
    }

    [zoom=17] {
      line-width: 16;
    }

    [zoom>=18] {
      line-width: 32;
    }
  }
}

.roads {
  ::casing,
  ::outline,
  {
    line-cap: butt;
    line-width: 0;
    line-color: @color_transport_casing;
  }

  line-join: round;
  line-cap: round;
  line-width: 0;
  line-color: @color_transport;

  [is_tunnel='yes']
  {
    [zoom>=14]
    {
      ::casing {
        line-opacity: 0.5;
      }

      ::outline {
        line-opacity: 0.5;
      }
    }

    [zoom>=15]
    {
      line-opacity: 0; // vs. line-width: 0 to override subsequent styling
    }
  }

  [is_link='yes']
  {
    [zoom>=16]
    {
      ::casing {
        line-width: 8;
      }

      line-width: 4;
    }
  }
}

.roads[kind='highway']
{
  [zoom>=9] {
    ::outline {
      line-width: 4.25;
    }

    line-width: 1.5;
  }

  [zoom>=10] {
    ::outline {
      line-width: 6;
    }

    line-width: 2;
  }

  [zoom>=11] {
    line-width: 2.5;
  }

  [zoom>=12] {
    ::outline {
      line-width: 8;
    }

    line-width: 3;

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 0.5;
    }
  }

  [zoom>=13] {
    ::outline {
      line-width: 8;
    }

    line-width: 3;

    [is_link='yes'] {
      ::outline {
        line-width: 3;
      }

      line-width: 1;

      [is_bridge='yes'] {
        ::outline {
          line-width: 3;
        }
      }
    }
  }

  [zoom>=14] {
    ::outline {
      line-width: 8;
    }

    line-width: 4;

    [is_bridge='yes'] {
      ::casing {
        line-width: 8;
      }
    }

    [is_link='yes'] {
      ::outline {
        line-width: 6;
      }

      line-width: 2.5;

      [is_bridge='yes'] {
        ::casing {
          line-width: 6;
        }
      }
    }
  }

  [zoom>=15] {
    ::casing {
      line-width: 11;
    }

    line-width: 6;

    [is_link='yes'] {
      ::casing {
        line-width: 6.5;
      }

      line-width: 2.25;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 5;
        line-opacity: 0.7;
        line-color: @color_transport_tunnel;
      }

      line-width: 3;
      line-opacity: 0.5;
    }
  }

  [zoom>=16] {
    ::casing {
      line-width: 14;
    }

    line-width: 9;

    [is_link='yes'] {
      ::casing {
        line-width: 7;
      }

      line-width: 2.5;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 7;
        line-opacity: 0.4;
      }

      line-opacity: 0.7;
      line-color: @color_transport_tunnel;

      [is_link='yes'] {
        ::casing {
          line-color: @color_transport_casing;
        }
      }
    }
  }

  [zoom>=17] {
    ::casing {
      line-width: 24;
    }

    line-width: 15;

    [is_link='yes'] {
      ::casing {
        line-width: 9;
      }

      line-width: 5;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 18;
      }

      line-width: 12;

      [is_link='yes'] {
        ::casing {
          line-width: 9;
        }
      }
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 42;
      line-color: @color_transport;
    }

    line-width: 28;
    line-color: @color_transport_inline;

    [is_bridge='yes'] {
      ::casing {
        line-width: 44;
      }
    }

    [is_link='yes'] {
      ::casing {
        line-width: 14;
        line-color: @color_transport;
      }

      line-width: 10;
      line-color: @color_transport_inline;

      [is_bridge='yes'] {
        ::casing {
          line-width: 15;
        }
      }
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 22;
      }

      line-width: 18;
    }
  }

  [zoom>=19] {
    ::casing {
      line-width: 49;
      line-color: @color_transport;
    }

    line-width: 35;
    line-color: @color_transport_casing;

    [is_bridge='yes'] {
      ::casing {
        line-width: 51;
      }
    }

    [is_link='yes'] {
      ::casing {
        line-width: 20;
      }

      line-width: 16;
      line-color: @color_transport_casing;

      [is_bridge='yes'] {
        ::casing {
          line-width: 21;
        }
      }
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 30;
      }

      line-width: 26;

      [is_link='yes'] {
        ::casing {
          line-width: 13;
        }
      }
    }
  }
}

.roads[kind='major_road']
{
  [zoom<=12] {
    line-color: #000;
  }

  [zoom>=9] {
    line-width: 0.15;
  }

  [zoom>=10] {
    line-width: 0.5;
  }

  [zoom>=11] {
    ::outline {
      line-width: 1.25;
    }

    line-width: 0.7;
  }

  [zoom>=12] {
    ::outline {
      line-width: 5;
    }

    line-width: 1;

    [is_link='yes'] {
      ::outline {
        line-width: 0;
      }

      line-width: 0.5;
    }
  }

  [zoom>=13] {
    line-width: 1.5;
  }

  [zoom>=14] {
    ::outline {
      line-width: 6;
    }

    line-width: 1.9;

    [is_bridge='yes'] {
      ::casing {
        line-width: 6;
      }
    }

    [is_link='yes'] {
      ::outline {
        line-width: 6;
      }

      line-width: 1.9;

      [is_bridge='yes'] {
        ::casing {
          line-width: 6;
        }
      }
    }
  }

  [zoom>=15] {
    ::casing {
      line-width: 8;
    }

    line-width: 5;

    [is_link='yes'] {
      ::casing {
        line-width: 5.5;
      }

      line-width: 2.25;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 5;
        line-opacity: 0.7;
        line-color: @color_transport_tunnel;
      }

      line-width: 3;
      line-opacity: 0.5;
    }
  }

  [zoom>=16] {
    ::casing {
      line-width: 11;
    }

    line-width: 7;

    [is_link='yes'] {
      ::casing {
        line-width: 7;
      }

      line-width: 2.5;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 7;
        line-opacity: 0.4;
      }

      line-opacity: 0.7;
      line-color: @color_transport_tunnel;

      [is_link='yes'] {
        ::casing {
          line-color: @color_transport_casing;
        }
      }
    }
  }

  [zoom>=17] {
    ::casing {
      line-width: 18;
    }

    line-width: 12;

    [is_link='yes'] {
      ::casing {
        line-width: 8;
      }

      line-width: 4;
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 18;
      }

      line-width: 12;

      [is_link='yes'] {
        ::casing {
          line-width: 9;
        }
      }
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 22;
      line-color: @color_transport;
    }

    line-width: 18;
    line-color: @color_transport_inline;

    [is_bridge='yes'] {
      ::casing {
        line-width: 24;
      }
    }

    [is_link='yes'] {
      ::casing {
        line-width: 13;
        line-color: @color_transport;
      }

      line-width: 9;
      line-color: @color_transport_inline;

      [is_bridge='yes'] {
        ::casing {
          line-width: 14;
        }
      }
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 22;
      }

      line-width: 18;
    }
  }

  [zoom>=19] {
    ::casing {
      line-width: 30;
    }

    line-width: 26;
    line-color: @color_transport_casing;

    [is_bridge='yes'] {
      ::casing {
        line-width: 32;
      }
    }

    [is_link='yes'] {
      ::casing {
        line-width: 17;
      }

      line-width: 13;
      line-color: @color_transport_casing;

      [is_bridge='yes'] {
        ::casing {
          line-width: 18;
        }
      }
    }

    [is_tunnel='yes'] {
      ::casing {
        line-width: 30;
      }

      line-width: 26;

      [is_link='yes'] {
        ::casing {
          line-width: 13;
        }
      }
    }
  }
}

.roads[kind='minor_road']
{
  [zoom<=14] {
    line-color: #999;
  }

  [zoom>=16] {
    line-color: @color_transport_minor;
  }

  [zoom>=10] {
    line-width: 0.2;
  }

  [zoom>=13] {
    line-width: 0.4;
  }

  [zoom>=14] {
    line-width: 0.8;
  }

  [zoom>=15] {
    line-width: 1.5;

    [is_tunnel='yes'] {
      ::casing {
        line-opacity: 0.7;
        line-color: @color_transport_tunnel;
      }

      line-opacity: 0.5;
    }
  }

  [zoom>=16] {
    ::casing {
      line-width: 7;
    }

    line-width: 4;
    line-color: @color_transport;
  }

  [zoom>=17] {
    ::casing {
      line-width: 9;
    }

    line-width: 7;
  }

  [zoom>=18] {
    ::casing {
      line-width: 17;
      line-color: @color_transport;
    }

    line-width: 13;
    line-color: @color_transport_casing;
  }

  [zoom>=19] {
    ::casing {
      line-width: 20;
    }

    line-width: 16;
  }
}

.roads[kind='rail']
{
  ::casing,
  ::outline,
  {
    line-color: @color_transport_rail;
  }

  line-color: @color_transport_rail;

  [zoom>=14] {
    ::casing {
      line-width: 3;
      line-dasharray: 1,3;
    }

    line-width: 1;
  }

  [zoom>=16] {
    ::casing {
      line-width: 5;
      line-dasharray: 1,4;
    }
  }

  [zoom>=18] {
    ::casing {
      line-width: 6;
      line-dasharray: 2,6;
    }

    line-width: 2;
  }

  [zoom>=19] {
    ::casing {
      line-width: 9;
      line-dasharray: 4,7;
    }

    line-width: 4;
  }
}

.roads[highway='service']
{
  [zoom>=15]
  {
    line-width: 1.5;
  }

  [zoom>=16] {
    ::casing {
      line-width: 4;
    }

    line-width: 2;
  }

  [zoom>=17] {
    ::casing {
      line-width: 6;
    }

    line-width: 4;
  }
}

.roads[kind='path']
{
  ::casing {
    line-color: @color_transport_path;
  }

  line-color: @color_transport_casing;

  [zoom>=15] {
    ::casing {
      line-width: 4;
    }

    line-width: 1.5;
    line-cap: butt;
  }

  [zoom>=16] {
    ::casing {
      line-width: 5;
    }

    line-width: 2;
  }

  [zoom>=17] {
    line-width: 3;
  }

  [zoom>=19] {
    line-width: 4;
  }
}


canal labels

canal labels

/* water and drainage network and features */

@water: #0900ff;
@water_halo_fill: #243a7a;
@way_opacity: 0.5;

[zoom > 11] {
  #waterway[waterway='stream'],#waterway[waterway='brook'],#waterway[waterway='drain'] {
    line-opacity: @way_opacity;
    line-color: @water;
    line-width: 2;

    [zoom > 17] { line-width: 5; }
    [zoom = 17] { line-width: 3.5; }
    [zoom = 16] { line-width: 2.5; }
    [zoom = 15] { line-width: 1.5; }
    [zoom = 14] { line-width: 1.25; }
    [zoom = 13] { line-width: 0.75; }
    [zoom = 12] { line-width: 0.5; }

    #waterway[int='yes'] {
      line-dasharray: 2,4;
    }
  }
}

#waterway[waterway='river'][zoom > 9] {
  line-opacity: @way_opacity;
  line-color: @water;

  [zoom > 17] { line-width: 10; }
  [zoom = 17] { line-width: 7.5; }
  [zoom = 16] { line-width: 5; }
  [zoom = 15] { line-width: 4; }
  [zoom = 14] { line-width: 3; }
  [zoom = 13] { line-width: 1.5; }
  [zoom = 12] { line-width: 1.25; }
  [zoom = 11] { line-width: 1.0; }
  [zoom = 10] { line-width: 0.75; }
}

#waterway-labels[waterway='river'][zoom > 11] {
  text-name: "[name]";
  text-face-name: "Liberation Sans Regular";
  text-fill: white;
  text-placement: line;
  text-halo-fill: @water_halo_fill;
  text-halo-radius: 2.0;

  [zoom > 21] { text-size: 30; }
  [zoom = 21] { text-size: 25; }
  [zoom = 20] { text-size: 20; }
  [zoom = 19] { text-size: 15; }
  [zoom = 18] { text-size: 14; }
  [zoom = 17] { text-size: 13; }
  [zoom = 16] { text-size: 12; }
  [zoom = 15] { text-size: 11; }
  [zoom = 14] { text-size: 10; }
  [zoom = 13] { text-size: 9; }
  [zoom = 12] { text-size: 8; }
}

[zoom > 12] {
  #waterway-labels[waterway='stream'],#waterway-labels[waterway='brook'],#waterway-labels[waterway='drain'],#waterway-labels[waterway='canal'] {
    text-name: "[name]";
    text-face-name: "Liberation Sans Regular";
    text-fill: white;
    text-placement: line;
    text-halo-fill: @water_halo_fill;
    text-halo-radius: 2.0;

    [zoom > 21] { text-size: 30; }
    [zoom = 21] { text-size: 25; }
    [zoom = 20] { text-size: 20; }
    [zoom = 19] { text-size: 15; }
    [zoom = 18] { text-size: 13; }
    [zoom = 17] { text-size: 12; }
    [zoom = 16] { text-size: 11; }
    [zoom = 15] { text-size: 11; }
    [zoom = 14] { text-size: 10; }
    [zoom = 13] { text-size: 8; }
  }
}

#bay-label[zoom > 13] {
  text-name: "[name]";
  text-face-name: "Liberation Sans Regular";
  text-fill: white;
  text-placement: point;
  text-halo-fill: @water_halo_fill;
  text-halo-radius: 2.0;
  text-transform: uppercase;
  text-wrap-width: 50px;
  text-opacity: 0.75;

  [zoom>14] { text-size: 12px; text-halo-radius: 2.0; }
  [zoom=14] { text-size: 10px; text-halo-radius: 1.0; }
}

/* water and drainage network and features */

@water: #0900ff;
@water_halo_fill: #243a7a;
@way_opacity: 0.5;

[zoom > 11] {
  #waterway[waterway='stream'],#waterway[waterway='brook'],#waterway[waterway='drain'] {
    line-opacity: @way_opacity;
    line-color: @water;
    line-width: 2;

    [zoom > 17] { line-width: 5; }
    [zoom = 17] { line-width: 3.5; }
    [zoom = 16] { line-width: 2.5; }
    [zoom = 15] { line-width: 1.5; }
    [zoom = 14] { line-width: 1.25; }
    [zoom = 13] { line-width: 0.75; }
    [zoom = 12] { line-width: 0.5; }

    #waterway[int='yes'] {
      line-dasharray: 2,4;
    }
  }
}

#waterway[waterway='river'][zoom > 9] {
  line-opacity: @way_opacity;
  line-color: @water;

  [zoom > 17] { line-width: 10; }
  [zoom = 17] { line-width: 7.5; }
  [zoom = 16] { line-width: 5; }
  [zoom = 15] { line-width: 4; }
  [zoom = 14] { line-width: 3; }
  [zoom = 13] { line-width: 1.5; }
  [zoom = 12] { line-width: 1.25; }
  [zoom = 11] { line-width: 1.0; }
  [zoom = 10] { line-width: 0.75; }
}

#waterway-labels[waterway='river'][zoom > 11] {
  text-name: "[name]";
  text-face-name: "Liberation Sans Regular";
  text-fill: white;
  text-placement: line;
  text-halo-fill: @water_halo_fill;
  text-halo-radius: 2.0;

  [zoom > 21] { text-size: 30; }
  [zoom = 21] { text-size: 25; }
  [zoom = 20] { text-size: 20; }
  [zoom = 19] { text-size: 15; }
  [zoom = 18] { text-size: 14; }
  [zoom = 17] { text-size: 13; }
  [zoom = 16] { text-size: 12; }
  [zoom = 15] { text-size: 11; }
  [zoom = 14] { text-size: 10; }
  [zoom = 13] { text-size: 9; }
  [zoom = 12] { text-size: 8; }
}

[zoom > 12] {
  #waterway-labels[waterway='stream'],#waterway-labels[waterway='brook'],#waterway-labels[waterway='drain'] {
    text-name: "[name]";
    text-face-name: "Liberation Sans Regular";
    text-fill: white;
    text-placement: line;
    text-halo-fill: @water_halo_fill;
    text-halo-radius: 2.0;

    [zoom > 21] { text-size: 30; }
    [zoom = 21] { text-size: 25; }
    [zoom = 20] { text-size: 20; }
    [zoom = 19] { text-size: 15; }
    [zoom = 18] { text-size: 13; }
    [zoom = 17] { text-size: 12; }
    [zoom = 16] { text-size: 11; }
    [zoom = 15] { text-size: 11; }
    [zoom = 14] { text-size: 10; }
    [zoom = 13] { text-size: 8; }
  }
}

#bay-label[zoom > 13] {
  text-name: "[name]";
  text-face-name: "Liberation Sans Regular";
  text-fill: white;
  text-placement: point;
  text-halo-fill: @water_halo_fill;
  text-halo-radius: 2.0;
  text-transform: uppercase;
  text-wrap-width: 50px;
  text-opacity: 0.75;

  [zoom>14] { text-size: 12px; text-halo-radius: 2.0; }
  [zoom=14] { text-size: 10px; text-halo-radius: 1.0; }
}