Climbed Mount Baker

For the last few weeks, some Mountaineer friends, Jenny, and I had been planning to climb Mount Baker, Washington’s 4th highest mountain (if you count Little Tahoma as number 3). The last two weekends, though, we were weathered out.

This weekend, the weather looked great, though. We went up the Coleman-Deming route, starting leisurely on Saturday around 10 AM. We roped up at the top of the Hogsback, at the toe of the glacier. Snow was very soft. We put crampons on, but in retrospect, they weren’t helpful.

We camped at around 6800 feet, not at the Heliotrope Ridge camp (which was unnecessarily high and out of the way) or at the Black Butte High Camp (which had rock fall and, as far as we could tell, no running water). We had running water, but needed to shovel platforms.

Because of the very hot day and soft snow, we got up 11 PM and departed at midnight. We reached the summit around 6:30, but we also went very slowly and didn’t push at all. The snow was perfect styrofoam for cramponing in the morning.

We unroped just above the Colfax col and scrambled up the dirt ridge. Upon reaching the snow slope below the Roman wall, we decided to stay unroped. There were no visible crevasses, and we decided it was safer to not pull someone else down on a possible slip (there were lots of teams making questionable rope decisions, like three climbers with about 3 feet of rope in between climbers…). In the end, it was less steep than it appeared from below. I still think we made the right decision to stay unroped. We roped up again on the descent after the pumice portion, just above Colfax col.

After tearing down camp, we roped up yet again, even though the crevasses were tiny, but we wanted to set a good example. Most of us didn’t put their crampons on again. The snow was too slushy at that time (around 1 PM).

There was new ice fall debris below Colfax peak, and on the way up, my rope team didn’t find the best way through. At around 8320 feet, we headed nearly straight up-slope (south-southeast), when we should have tried to cross the ice fall (southeast). That would have gotten us to a nice flat glacier section again. We found a better way on the descent during daylight.

There were a few crevasses, but most of them were small, less than a foot. They started around 6600 feet. The two biggest ones were below the Colfax col, at around 8800 feet. The lower one was several feet wide but had a huge, solid snow bridge across; the higher one was a little over a foot wide and could be stepped over or jumped. Near the summit rim, a crevasse/bergschrund was starting to form on the climber’s left, but it didn’t reach across yet.

The road to the trailhead was in good condition, for the most part, but there were some rather big potholes, and it’s a one-lane road, so my maximum speed was probably about 20 mph. Still, no problem for my Camry.

Equipment used: poles (to the top of the Hogsback), ice axe (from toe of glacier), crampons (useful midnight to around 10 AM), rope (40 meter per team of 3, interval 10 meter, with 10 meters coiled on both ends), two pickets per team, standard personal glacier gear, GPS.

Hiking up the Hogsback.

Hiking up the Hogsback.

Camp on Saturday at 6800 feet. Photo by Sharon.

Camp on Saturday at 6800 feet. Photo by Sharon.

Summit and sunrise.

Summit and sunrise.

Summit group photo.

Summit group photo.

Rajan descending the snow slope next to the Roman Wall.

Rajan descending the snow slope next to the Roman Wall.

Descending into the ice fall below Colfax Peak. You can clearly see where the cornice broke.

Descending into the ice fall below Colfax Peak. You can clearly see where the cornice broke.

In the ice fall below Colfax Peak. Picture by Vicki.

In the ice fall below Colfax Peak. Picture by Vicki.

Jenny and I in the summit crater of Mount Baker:

Arriving on Grant Peak, the true summit of Mount Baker. Sharon is excited:

Third team on the summit of Mount Baker:

Rajan, Sean, and I heading down towards the ice fall below Colfax Peak:

Here are two links to my trip reports on Peakery and PeakBagger.

Share
Posted in Pictures | Leave a comment

Print This Print This   Email This Email This

Honeymooning on Black Peak

Jenny and I decided not to do an immediate, long honeymoon trip right after our wedding. Instead, we’re going to do a number of trips.

The first one was this past weekend, to Black Peak in the North Cascades. Black Peak is Washington’s 20th highest peak, and we had been talking about climbing it since fall of 2016.

The hike in was quite enjoyable, despite carrying our tent and everything else we needed to camp. The trail to Heather Pass was completely snow-free and easy. After that, our journey was mostly on snow, with a few boulder fields in between. The summer climber’s trail is beginning to melt out, though. I think in a few weeks, getting to Wing Lake will be even easier.

Above Lewis Lake in the North Cascades, on our way to camp below Black Peak.

Above Lewis Lake in the North Cascades, on our way to camp below Black Peak.

We camped right next to Wing Lake, which was still frozen over with a thin layer of ice.

Black Peak, Washington's 20th highest mountain.

Black Peak, Washington’s 20th highest mountain.

Camp at 4 AM for our summit attempt of Black Peak.

Camp at 4 AM for our summit attempt of Black Peak.

The snowfield below Black Peak’s south col was still solid, and at 5 AM, it was perfect styrofoam snow for cramponing.

Jenny climbing the steep, frozen snow to the col south of Black Peak.

Jenny climbing the steep, frozen snow to the col south of Black Peak.

The 900 vertical feet of scrambling were easy for the most part, although we once headed into the wrong gulley and had to downclimb. We were about 50 feet too far to the east.

The crux of the scramble was just below the true summit: A steep, unprotected section of three steps, totaling maybe 10 feet (picture from SummitPost, not by us). The rock was solid, and there were a number of good footholds, but the handholds were all on the side, under an overhanging rock protrusion. There was a lot of loose rock on top of the steps. On the downclimb, it was difficult to see the feet into the holds. We managed to find them, but even if we hadn’t, we could have held on to rock protrusion and ungracefully scraped down the rock face. It was probably less dangerous than it felt.

The view from the top was gorgeous, and we were happy we didn’t push to climb Black Peak on Saturday, when the weather was cloudy.

View from the summit of Black Peak, high above Wing Lake.

View from the summit of Black Peak, high above Wing Lake.

All in all, it took us four easy hours from car to camp, and three hours from camp to summit. We were back at camp before 10 AM, tore down and left camp at 11 AM, and were back at the car at 2:30 PM on Sunday.

Share
Posted in Pictures | Leave a comment

Print This Print This   Email This Email This

Dragontail Peak Climb

It’s been a little harder for me to get out into the mountains this year. It’s already end of May, and I don’t have much under my belt.

That’s why I’m even more excited that Jenny and I climbed Dragontail Peak last Saturday. Dragontail is 26th on the Washington Bulger List of Washington’s highest mountains, and it has been a goal for Jenny and me ever since we first set foot in the Enchantments. Last year, we climbed its neighbor, Colchuck Peak (33rd on the list).

We had permits at Stuart Lake, since I had originally planned to climb Mount Stuart, but for that, I simply wasn’t in good enough shape. So instead, we camped at Stuart Lake, then Saturday morning at 4 AM hiked to Colchuck Lake, around the lake, and then up Aasgard Pass. We were at the top of the pass around 10:30 AM and turned west-southwest towards Dragontail’s key col. From there, it was a simple scramble to 8,845 feet.

I had trouble standing up on the summit, the exposure felt so threatening. Perhaps my fear wasn’t quite unreasonable, considering Dragontail Peak drops 3,300 feet down to the lake, almost vertically.

It was a pretty amazing spot. We could see Rainier, Adams, Baker and Glacier Peak. Just St. Helens was hiding in the clouds to the south of Rainier. I haven’t been to many five-volcano spots before.

We had originally planned to head south and through Pandora’s Box, so we could glissade down the Colchuck glacier, but the snow going up Pandora’s Box was too soft. We decided it was safer, albeit much more annoying, to hike down Aasgard Pass.

We were back at our tent just before 8 PM. It was a strenuous but successful, and even enjoyable, trip of almost 16 hours.

Dragontail Peak from Colchuck Lake.

Dragontail Peak from Colchuck Lake.

Hiking up the lower slopes of Aasgard Pass.

Hiking up the lower slopes of Aasgard Pass.

Scrambling near the top of Aasgard Pass.

Scrambling near the top of Aasgard Pass.

Heading towards Dragontail's key col.

Heading towards Dragontail’s key col.

Looking into the core of the Enchantments.

Looking into the core of the Enchantments.

Aasgard Pass is below in the background.

Aasgard Pass is below in the background.

On the key col, with Rainier and Adams visible.

On the key col, with Rainier and Adams visible.

Looking back at the key col, after just having started the summit scramble.

Looking back at the key col, after just having started the summit scramble.

Looking at Pandora's Box, with Rainier right behind it.

Looking at Pandora’s Box, with Rainier right behind it.

The sharp cliffs on the east side of Dragontail.

The sharp cliffs on the east side of Dragontail.

Jenny enjoying the summit. Glacier Peak in the background.

Jenny enjoying the summit. Glacier Peak in the background.

Looking 3,300 feet down to Colchuck Lake.

Looking 3,300 feet down to Colchuck Lake.

Share
Posted in Pictures | Leave a comment

Print This Print This   Email This Email This

Lombok @Builder with Required Parameters?

I would really like a Lombok @Builder annotation that properly deals with required parameters at compile time.

Here is what I have in mind:

1
2
3
4
5
6
@lombok.Builder
class Foo {
    @lombok.Builder.Required final String name;
    @lombok.Builder.Required final int age;
    final String email;
}

This should generate the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
@lombok.Builder
class Foo {
    @lombok.Builder.Required final String firstName;
    @lombok.Builder.Required final String lastName;
    @lombok.Builder.Required final int age;
    final String email;

    private Foo(String firstName, String lastName, int age, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.email = email;
    }
 
    public static FooBuilder builder() {
        return new FooBuilder();
    }

    private static class FooBuilderBase {
        private String firstName = null;
        private String lastName = null;
        private int age = 0;
        private String email = null;
        private FooBuilderBase() {}
        private FooBuilderBase(String firstName, String lastName, int age, String email) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.age = age;
            this.email = email;
        }
        public FooBuilder email(String email) {
            this.email = email;
            return this;
        }
    }

    // builder with no value fixed

    private static class FooBuilder extends FooBuilderBase {
        private FooBuilder() {}
        public FooBuilderWithFirstName firstName(String firstName) {
            this.firstName = firstName;
            return new FooBuilderWithFirstName(firstName, lastName, age, email);
        }
        public FooBuilderWithLastName lastName(String lastName) {
            this.lastName = lastName;
            return new FooBuilderWithLastName(firstName, lastName, age, email);
        }
        public FooBuilderWithAge age(int age) {
            this.age = age;
            return new FooBuilderWithAge(firstName, lastName, age, email);
        }
        // no build method yet, because the builder doesn't have all the required info
    }

    // builders with one value fixed

    public static class FooBuilderWithFirstName extends FooBuilderBase {
        private FooBuilderWithFirstName(String firstName, String lastName, int age, String email) {
            super(firstName, lastName, age, email);
        }
        // no more firstName method, so the user can't clear it
        public FooBuilderWithFirstName_LastName lastName(String lastName) {
            this.lastName = lastName;
            return new FooBuilderWithFirstName_LastName(firstName, lastName, age, email);
        }
        public FooBuilderWithFirstName_Age age(int age) {
            this.age = age;
            return new FooBuilderWithFirstName_Age(firstName, lastName, age, email);
        }
        // no build method yet, because the builder doesn't have all the required info
    }

    public static class FooBuilderWithLastName extends FooBuilderBase {
        private FooBuilderWithLastName(String firstName, String lastName, int age, String email) {
            super(firstName, lastName, age, email);
        }
        // no more lastName method, so the user can't clear it
        public FooBuilderWithFirstName_LastName firstName(String firstName) {
            this.firstName = firstName;
            return new FooBuilderWithFirstName_LastName(firstName, lastName, age, email);
        }
        public FooBuilderWithLastName_Age age(int age) {
            this.age = age;
            return new FooBuilderWithLastName_Age(firstName, lastName, age, email);
        }
        // no build method yet, because the builder doesn't have all the required info
    }

    public static class FooBuilderWithAge extends FooBuilderBase {
        private FooBuilderWithAge(String firstName, String lastName, int age, String email) {
            super(firstName, lastName, age, email);
        }
        // no more age method, so the user can't clear it
        public FooBuilderWithFirstName_Age firstName(String firstName) {
            this.firstName = firstName;
            return new FooBuilderWithFirstName_Age(firstName, lastName, age, email);
        }
        public FooBuilderWithLastName_Age lastName(String lastName) {
            this.lastName = lastName;
            return new FooBuilderWithLastName_Age(firstName, lastName, age, email);
        }
        // no build method yet, because the builder doesn't have all the required info
    }

    // builders with two values fixed

    public static class FooBuilderWithFirstName_LastName extends FooBuilderBase {
        private FooBuilderWithFirstName_LastName(String firstName, String lastName, int age, String email) {
            super(firstName, lastName, age, email);
        }
        // no more firstName, lastName methods, so the user can't clear it
        public FooBuilderComplete age(int age) {
            this.age = age;
            return new FooBuilderComplete(firstName, lastName, age, email);
        }
        // no build method yet, because the builder doesn't have all the required info
    }

    public static class FooBuilderWithLastName_Age extends FooBuilderBase {
        private FooBuilderWithLastName_Age(String firstName, String lastName, int age, String email) {
            super(firstName, lastName, age, email);
        }
        // no more lastNam, age methods, so the user can't clear it
        public FooBuilderComplete firstName(String firstName) {
            this.firstName = firstName;
            return new FooBuilderComplete(firstName, lastName, age, email);
        }
        // no build method yet, because the builder doesn't have all the required info
    }

    public static class FooBuilderWithFirstName_Age extends FooBuilderBase {
        private FooBuilderWithFirstName_Age(String firstName, String lastName, int age, String email) {
            super(firstName, lastName, age, email);
        }
        // no more firstName, age method, so the user can't clear it
        public FooBuilderComplete lastName(String lastName) {
            this.lastName = lastName;
            return new FooBuilderComplete(firstName, lastName, age, email);
        }
        // no build method yet, because the builder doesn't have all the required info
    }

    // builders with three values fixed

    public static class FooBuilderComplete extends FooBuilderBase {
        private FooBuilderComplete(String firstName, String lastName, int age, String email) {
            super(firstName, lastName, age, email);
        }
        // no more firstName, lastName, age methods, so the user can't clear it
        // but now we have a build method
        public Foo build() {
            return new Foo(firstName, lastName, age, email);
        }
    }
}

So basically, if we have n required parameters, we 2^n builder classes. For each r required parameters that have been set already, we need n-choose-r builders.

In the example above, we have three required parameters. We have one builder that has no required parameters set, three that have one value set, three that have two values set, and one that has all of them set.

Unfortunately, the source code for rewriting the bytecode in response to a @Builder annotation is almost 1000 lines long. Not exactly the best example of well-structured code.

Share
Posted in Uncategorized | Leave a comment

Print This Print This   Email This Email This

Looking for a Replacement for Amazon Music Uploads

Now that Amazon Music is shutting down the ability to upload and play your own songs, what do you use as a replacement?

I have hundreds of CDs that I imported — complete Mike Oldfield, almost complete Depeche Mode, lots of classical music of which I’ve found one performance I prefer.

How will I get those to play on my Amazon Echo devices and my Android phone?

Share
Posted in Uncategorized | Leave a comment

Print This Print This   Email This Email This

Rerun: My favorites pictures of 2017

In preparation for the WTA’s Northwest Exposure photo contest, I was reviewing my favorite pictures from this year, just like I did last year.

But there are just too many this year. I’ve been to so many gorgeous places, gone on so many amazing trips, I just have a really hard time reducing my set of photos to just a top 5. With a lot of heartrending, I think I can manage to cut it to a top 12.

Camp Schurman, in front of Mount Rainier.

Camp Schurman, in front of Mount Rainier.

Climbers on the Emmons route to the summit of Mount Rainier.

Climbers on the Emmons route to the summit of Mount Rainier.

Sunrise at Camp Schurman, Mount Rainier.

Sunrise at Camp Schurman, Mount Rainier.

Mountaineers descending Silver Star Mountain.

Mountaineers descending Silver Star Mountain.

Mount Adams and Mount Hood, seen from Mount Rainier.

Mount Adams and Mount Hood, seen from Mount Rainier.

Mountaineers on the Emmons Glacier of Mount Rainier.

Mountaineers on the Emmons Glacier of Mount Rainier.

Camp near Dome Peak.

Camp near Dome Peak.

View from the "Sidewalk" of Dome Peak, with climbers on the Dome Glacier.

View from the “Sidewalk” of Dome Peak, with climbers on the Dome Glacier.

Mountaineers and penitentes at sunrise on Mount Rainier.

Mountaineers and penitentes at sunrise on Mount Rainier.

On the Winthrop glacier on Mount Rainier.

On the Winthrop glacier on Mount Rainier.

Summit block of Mount Hood at sunrise.

Summit block of Mount Hood at sunrise.

Exploding with sunlight near the summit of Mount Hood.

Exploding with sunlight near the summit of Mount Hood.

Share
Posted in Pictures | Leave a comment

Print This Print This   Email This Email This

Comparison between GPSMAP 64st and InReach Explorer+

We’ve been shopping around for a handheld GPS, since many climbs require the ability to retrace our route. Since I have an InReach SE, it made sense to check out the InReach Explorer+, which combines a satellite messenger with topographic maps. We also tried out the GPSMAP 64st. Both devices are by Garmin.

We took both up on our August climb of Mount Rainier. The InReach Explorer+ is nice, since it means we only have to carry one device, instead of a messenger and something with topographic maps. Unfortunately, in terms of map detail and accuracy, it is quite far behind the GPSMAP 64st.

Here are our tracks, from just before the Disappointment Cleaver to somewhere on the Emmons or Winthrop glaciers, as seen in Google Earth. First, the track recorded by the GPSMAP 64st:

Track recorded by GPSMAP 64st

Track recorded by GPSMAP 64st

And here is the track recorded by the InReach Explorer+:

Track recorded by InReach Explorer+

Track recorded by InReach Explorer+


You can see that the track on the InReach is much less uniform, and there are a few points that are actually quite far away.

In terms of detail that can be discerned on the display, the InReach also can’t compete with the GPSMAP 64st. Here is the topographic map around Camp Muir, first on the GPSMAP 64st:

Topographic map on GPSMAP 64st

Topographic map on GPSMAP 64st

And here is the same map location on the InReach Explorer+:

Topographic map on InReach Explorer+

Topographic map on InReach Explorer+

You can’t even see Muir Peak, to the east of the camp!

I think we’ll return the InReach Explorer+ and keep the GPSMAP 64st. We just have to figure out a way to keep the latter from turning on accidentally and draining the battery.

Share
Posted in Uncategorized | Leave a comment

Print This Print This   Email This Email This

Kaspersky SafeMoney, LastPass, and Yubikey?

I’m using Kaspersky SafeMoney to redirect requests to websites that deserve a bit more security to a sandboxed browser. I don’t have any extensions in it, except for LastPass. I think it makes sense to still get the benefits of a strong master password and different strong passwords for each site that I don’t have to remember.

Unfortunately, when I added Yubikey to the mix, LastPass started asking me for the Yubikey every time the secure browser launches.

The option to “trust this browser for 30 days” doesn’t seem to do anything anymore. Has anyone got this to work?

Share
Posted in Uncategorized | Leave a comment

Print This Print This   Email This Email This

Second Mount Rainier Climb

On August 4 and 5, Jenny and I climbed Mount Rainier again, this time with Tatiana, Daniel, and Ian. I’m going to write a longer trip report again, but here are a couple of 360-degree pictures from the summit, and a 360-degree video from crossing a crevasse using a ladder.

My second time on the crater rim of Mount Rainier:

Dan, Jenny, Tatiana, Ian and I, on the summit of Washington’s highest mountain:

Crossing a crevasse using a ladder:

It was another great trip!

Share
Posted in Pictures | Leave a comment

Print This Print This   Email This Email This

swagger-codegen 2.3.0 Breaks Inheritance?

For a hack day at work, I’ve been trying to integrate our code generator into the online Swagger editor and generator. Of course, I’ve been trying to use the latest version, which appears to be 2.3.0-SNAPSHOT (although I just saw there’s also a 3.0.0 branch).

Unfortunately, it seems like inheritance (which is kind of a big deal for actual software systems) is fundamentally broken in 2.3.0.

Here’s my sample spec in YAML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
swagger: "2.0"
info:
  description: "This is a sample server Petstore server.  You can find out more about     Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).      For this sample, you can use the api key `special-key` to test the authorization     filters."
  version: "1.0.0"
  title: "Swagger Petstore"
  termsOfService: "http://swagger.io/terms/"
  contact:
    email: "apiteam@swagger.io"
  license:
    name: "Apache 2.0"
    url: "http://www.apache.org/licenses/LICENSE-2.0.html"
host: "petstore.swagger.io"
basePath: "/v2"
tags:
- name: "pet"
  description: "Everything about your Pets"
  externalDocs:
    description: "Find out more"
    url: "http://swagger.io"
- name: "store"
  description: "Access to Petstore orders"
- name: "user"
  description: "Operations about user"
  externalDocs:
    description: "Find out more about our store"
    url: "http://swagger.io"
schemes:
- "http"
paths:
  /pet/:
    get:
      tags:
      - "pet"
      summary: "Find pet by ID"
      description: "Returns a single pet"
      operationId: "getPet"
      produces:
      - "application/xml"
      - "application/json"
      responses:
        200:
          description: "successful operation"
          schema:
            $ref: "#/definitions/Pet"
        400:
          description: "Invalid ID supplied"
        404:
          description: "Pet not found"
definitions:
  Pet:
    discriminator: petType
    required:
      - name
      - petType # required for inheritance to work
    properties:
      name:
        type: string
      petType:
        type: string
  Cat:
    allOf:
      - $ref: '#/definitions/Pet' # Cat has all properties of a Pet
      - properties: # extra properties only for cats
          huntingSkill:
            type: string
            default: lazy
            enum:
              - lazy
              - aggressive
  Dog:
    allOf:
      - $ref: '#/definitions/Pet' # Dog has all properties of a Pet
      - properties: # extra properties only for dogs
          packSize:
            description: The size of the pack the dog is from
            type: integer

Cat and Dog extend Pet. Very simple.

The older swagger editor, which reports a version number of 2.10.4 for the swagger-api/swagger-editor GitHub project, understands this and generates the expected code:

swagger-editor 2.10.4 models

swagger-editor 2.10.4 models

1
2
public class Cat extends Pet {
...

The latest editor, unfortunately, does not!

Broken Swagger Editor 2.3.0 models

Broken Swagger Editor 2.3.0 models

1
public class Cat {

You gotta be kidding, right?

Share
Posted in Code Pranger, Programming, Ramblings | Leave a comment

Print This Print This   Email This Email This

The Uneven World of Two-Factor Authentication

I’d like to say I began to adopt two-factor authentication pretty early. I’ve had it enabled for Google for a long time, I jumped on it when Amazon and Dropbox made it available, I enjoy it on several of my banking accounts, of course.

At work, I got a Yubikey a few months ago, a hardware token that is used in combination with a password. It’s the “have” part of the “something you know, something you have, and something you are” philosophy of protecting secrets. A fingerprint or iris scan would be “something you are.”

With all of the recent hacks and ransomware attacks, I decided to beef up security at home as well. I ordered two Yubikeys, a primary one and one to lock away as a backup. As primary Yubikey I chose the Yubikey NEO, which has NFC and can be used with a phone. As backup, I chose the cheap Yubikey FIDO U2F key.

Unfortunately, the results are a mixed bag.

Yubikey for LastPass requires LastPass Premium ($12 a year, plus taxes). I signed up, then found out that LastPass Premium does not seem to support the cheap Yubikey FIDO U2F key. So I couldn’t use that one as a backup for LastPass.

KeePass on Windows has a plug-in that allows a Yubikey to provide one-time pads (OTPs). Again, this doesn’t work on the cheapest key. Also, it’s a bit cumbersome, since it requires at least three presses of the Yubikey button, for three separate OTPs. Initially, I had also configured this for 2nd slot on the Yubikey, which meant I had to hold the button for three seconds, three times (the 2nd slot is triggered by a 3-second press; the first slot is triggered by a simple press of the button).

I also used KeePassDroid on my phone, and that app plain and simply does not support OTPs at all. I could have programmed the NEO for a static password, though.

There is a newer app, KeePass2Android, that does apparently support getting OTPs from a Yubikey NEO, but I haven’t tried it yet.

LastPass on Android does support the NEO, but with NFC, you cannot switch which slot is going to be used. By default, it’s always slot 1. That means I can’t use NFC for both LastPass and KeePass2Android, because both would be using the same slot, and that doesn’t work.

So, I have hardware two-factor authentication in a bunch of places now, but I’m not sure I’ve added that much security. I strengthened some of my most important passwords, though. Maybe that “something you know” part is still most important after all.

Share
Posted in Uncategorized | Leave a comment

Print This Print This   Email This Email This

Mount Rainier Go/No-Go Decision Matrix

This is the matrix we used for making go/no-go decisions for our Mount Rainier summit bids:

Weather Scoring

Weather Scoring

Decision Matrix: 5 or lower means "go," 6 or 7 means "cautious go," and 8 or higher means "no-go" for us.

Decision Matrix: 5 or lower means “go,” 6 or 7 means “cautious go,” and 8 or higher means “no-go” for us.

It’s copied from the excellent route briefs the Mount Rainier climbing rangers have released:

Share
Posted in Uncategorized | Leave a comment

Print This Print This   Email This Email This

Mount Rainier Trip Summary

Trailhead to camp:

  • Leave at trailhead: 6:30 AM @ 5,400 feet
  • Arrive at camp: 12:30 PM @ 10,000 feet
  • 6 hours, 3.9 miles (6.3 km), 4,600 feet gain (1400 m, or about 394 building floors)

Camp to summit:

  • Leave at camp: 1:30 AM @ 10,000 feet
  • Arrive at summit: 8:30 PM @ 14,411 feet
  • 7 hours, 3.3 miles (5.3 km), 4,411 feet gain (1344 m, or about 378 building floors)

Summit to camp:

  • Leave at camp: 9:15 AM
  • Arrive at summit: 14:15 PM
  • 5 hours, 3.3 miles (5.3 km)

Camp to trailhead:

  • Leave at camp: 3:00 PM
  • Arrive at trailhead: 7:00 PM
  • 4 hours, 3.9 miles (6.3 km)

Round-trip:

  • 22 hours, 14.4 miles (23 km), 9,011 feet gain (2747 m, or about 772 building floors)
Share
Posted in Uncategorized | Leave a comment

Print This Print This   Email This Email This

Mount Rainier Trip Report

On June 24 and 25, 2017, Jenny and I and our friend Vicki climbed Mount Rainier.

Jenny and I drove out on Friday afternoon and picked up our wilderness camping permit for Camp Muir. We had dinner at the Paradise visitor center (a first for me), and then drove down to Cougar Rock campground to sleep. We drank half a gallon of water, peed like crazy, but got about 7.5 hours sleep in and felt very hydrated in the morning.

Jenny at our camp site on Friday, excited about her fanny pack.

Jenny at our camp site on Friday, excited about her fanny pack.

At 4 AM, we packed up our tent and drove back to Paradise. Once there, we finished packing our backpacks and waited for Vicki to arrive, who was on time. At 6:30, we started hiking up towards Camp Muir, just as planned.

Jenny says "we go there" on Saturday morning.

Jenny says “we go there” on Saturday morning.

There was snow all the way down to Paradise, and the summer route with the switchbacks past Panorama Point had not been cleared yet, which meant we had to ascend the steep slope just below the toilet at Panorama Point (which actually exists; I had never seen it before, since I had always taken the High Skyline trail). That was the only steep part, though. After that, we were on the long but relatively gentle Muir snowfield. It took us about 6 hours to get to Camp Muir. At around 11, we heard from our three skier companions who were going to make up the second rope team.

Jenny and Vicki on the hike up, still close to Paradise.

Jenny and Vicki on the hike up, still close to Paradise.

Jenny, Vicki, and some other folks heading up the steep slope to Panorama Point.

Jenny, Vicki, and some other folks heading up the steep slope to Panorama Point.

Jenny and Vicki near Pebble Creek, the beginning of the Muir Snowfield.

Jenny and Vicki near Pebble Creek, the beginning of the Muir Snowfield.

Heading to basecamp, with a heavy backpack (picture by Jenny).

Heading to basecamp, with a heavy backpack (picture by Jenny).

At Camp Muir, we set up our tents and were pretty out of breath, due to the thin air. Vicki hadn’t slept much the night before, and took a nap in her tent under the beating sun. Jenny and I spent about 3 hours melting snow for water, producing about 2 gallons. We also received about another gallon in donations from climbers who were departing Camp Muir. In the middle of this task, we also ate some chicken with rice and teriyaki chicken freeze-dried meals. Then we went to sleep. Or tried to. It was hot and loud. Our earplugs were very useful.

Line of tents at Camp Muir. Ours are the second and third from the left.

Line of tents at Camp Muir. Ours are the second and third from the left.

Taking a breather, after having set up our tent (picture by Jenny).

Taking a breather, after having set up our tent (picture by Jenny).

At Camp Muir, melting snow (picture by Vicki).

At Camp Muir, melting snow (picture by Vicki).

We hadn’t heard from the skiers, and we were getting worried that something had happened and that they had turned around, but there wasn’t really anything we could do. Either they’d show up or not. Around 4:30 PM, I believe, I managed to call them on the two-way radio, and around 5 PM, perhaps, they were at our camp and setting up their tents. They weren’t too happy with our plan to get up at 11 PM and start hiking at midnight, so we agreed on an alpine start half an hour later.

Jenny and I got up at 11 PM nonetheless and got our rope and gear ready. I put an alpine butterfly into the middle of my 40-meter rope, two alpine butterflies about 6 or 7 meters to the side from there, and then coiled up the rest of the rope, to be carried by the climbers at both ends. Fortunately, the glacier rope is really light. Vicki, Jenny and I were ready to go at half past midnight, as agreed, but the other team took until a little after 1 AM.

Jenny putting on her gaiters and crampons just before midnight.

Jenny putting on her gaiters and crampons just before midnight.

Ready to go at half past midnight!

Ready to go at half past midnight!

We followed a chain of headlamps in the distance over the Cowlitz Glacier towards the Cathedral Gap, crossed over onto the Ingraham Glacier, and headed up towards the Ingraham Flats. It was dark, our path only lit by our headlamps, and while we were pretty sure there were no crevasses on the boot path, I still swept my gaze left and right while I was in the lead.

Around 11,300 feet, the path turned to the north and towards the Disappointment Cleaver. Some hand lines were attached, but we didn’t really need them. Ahead of us, there was a 3-person rope team that had used the entire length of a 30-meter rope, with 13 meters or so between climbers. They were relatively slow, and occasionally dislodged little rocks.

About half-way up the cleaver, they sat down to adjust their rope spacing. With their headlamps shining straight into my eyes, I had trouble finding the route for a second, and when we spotted it, we realized I had ascended too far. We swapped leads, since Vicki was right around the correct spots, and she lead most of the way to the summit.

Approximate route, from http://mountrainierclimbing.blogspot.com/2017/06/disappointment-cleaver-6252017.html

Approximate route, from http://mountrainierclimbing.blogspot.com/2017/06/disappointment-cleaver-6252017.html

On top of the Disappointment Cleaver, our second rope team told us that, unfortunately, one of the climbers had altitude sickness. We polled every single person if it was okay for Vicki, Jenny and me to continue. I felt a bit bad, but the Disappointment Cleaver route had been pretty simple up to that point, and there were plenty of other climbers around who could help. On the Emmons route, we all would have had to descend, to make sure the second rope team doesn’t get in trouble on the way down (and to make sure we don’t get in trouble by ourselves on the way up).

Mount  Adams from above the Disappointment Cleaver (picture by Phil).

Mount Adams from above the Disappointment Cleaver (picture by Phil).

The three of us continued by ourselves, and at around 12,800 feet arrived at what was arguably the most interesting feature of the route. First, we observed the sunrise, painting the mountain in a warm, orange glow. Then we followed a long detour towards the north to avoid a serac, to a point where we could actually see Mount Ruth, and almost see Camp Schurman. On our left, there was the steep serac; on our right, there were crevasses. We carefully but quickly made our way through this fascinating area (not many pictures of this, but here’s a video of our descent through the same stretch).

Sunrise at 12,800 feet (picture by Jenny).

Sunrise at 12,800 feet (picture by Jenny).

Vicki, leading our rope team at sunrise (picture by Jenny).

Vicki, leading our rope team at sunrise (picture by Jenny).

I was bringing up the rear at this time. Behind me is another team (picture by Jenny).

I was bringing up the rear at this time. Behind me is another team (picture by Jenny).

Icefall above us at about 12,800 feet (picture by Vicki).

Icefall above us at about 12,800 feet (picture by Vicki).

There were pickets and carabiners, but we decided to not use them, since it would slow us down. This was probably a mistake. We either should have clipped into the fixed protection, or we should have unroped. Oh well… we didn’t fall.

After the detour, we steadily headed up on the mountain to about 13,000 feet, at which point the switchbacks became steeper. A bit higher still, maybe at 13,500 feet, we switched leads again, and I lead our team to the crater rim at 14,000 feet.

Jenny and Vicki on a switchback near 13,000 feet.

Jenny and Vicki on a switchback near 13,000 feet.

Re-applying sunscreen. Still got a bit burned (picture by Jenny).

Re-applying sunscreen. Still got a bit burned (picture by Jenny).

It was getting pretty hot. I'm pretty sure the dark peak in the foreground on the left is Mount Ruth.

It was getting pretty hot. I’m pretty sure the dark peak in the foreground on the left is Mount Ruth.

The trail behind us above 13,000 feet.

The trail behind us above 13,000 feet.

Little Tahoma appearing very little from the upper mountain.

Little Tahoma appearing very little from the upper mountain.

Little Tahoma from the upper mountain (picture by Vicky).

Little Tahoma from the upper mountain (picture by Vicky).

Ascending Mount Rainier, at about 13,000 feet:

It was a remarkable sight. The crater was much larger than I had thought, the size of several football fields. There was no wind. It was absolutely tranquil. We dropped our packs and unroped, ate and drank a bit, and then headed across the crater to the Columbia Crest, Mount Rainier’s true summit. We reached it at 8:29 AM, after a bit under seven and a half hours of hiking. 9 AM would have been our turn-around time.

"I made it!" (Picture by Jenny)

“I made it!” (Picture by Jenny)

Vicki, relieved at the crater (picture by Jenny).

Vicki, relieved at the crater (picture by Jenny).

Jenny and I shortly after having reached the crater at 14,000 feet (picture by Vicki).

Jenny and I shortly after having reached the crater at 14,000 feet (picture by Vicki).

In the crater of Mount Rainier, at 14,000 feet:

The views were incredible. We could see the Olympics and Mount Olympus clearly. Baker and Shuksan were there. Glacier Peak. The Stuart range. Mount Adams. Mount Hood and Mount Jefferson. And Mount St. Helens. Absolutely beautiful.

Jenny has reached the Columbia Crest!

Jenny has reached the Columbia Crest!

Mount Adams, as seen from Columbia Crest (picture by Vicki).

Mount Adams, as seen from Columbia Crest (picture by Vicki).

Jenny, Vicki and I on the summit, with Liberty Cap in the background.

Jenny, Vicki and I on the summit, with Liberty Cap in the background.

Vicki, Jenny and I on the Columbia Crest, Mount Rainier's summit.

Vicki, Jenny and I on the Columbia Crest, Mount Rainier’s summit.

On the summit of Mount Rainier.

On the summit of Mount Rainier.

On the Columbia Crest, the summit of Mount Rainier:

We took some pictures and looked for the summit register, but couldn’t find it. We didn’t care too much. We returned to our packs via the south rim and good views of Mount Adams, ate a bit more, and then roped up for our descent.

Jenny and I on the descent, high up on the mountain (picture by Vicki).

Jenny and I on the descent, high up on the mountain (picture by Vicki).

I lead the first half down, right to the top of the Disappointment Cleaver. The snow had got quite soft by now, and our going was slow. Before the cleaver, we switched up our positions, and had Jenny lead, with Vicki in the middle, and myself taking up the rear. The cleaver was a bit tricky, but I must have bad memory, because it was much shorter than I had expected. Good! We cleared the cleaver and the icefall called Icebox quickly and headed back towards Ingraham Flats.

While on the cleaver, our second rope team tried to radio us from camp, but we couldn’t respond, the situation was just too difficult to stop and radio. Once we were back on the Ingraham Glacier, we tried to call back, but they must have already descended towards Paradise.

We hopped over the Cathedral Gap again and were back on the Cowlitz Glacier. At this point, I must admit, I ran a bit out of energy. When we had stopped to snack, I had always spent some time with group tasks, such as looking at maps or trying to reach our second rope team, and I hadn’t eaten enough. I was dead-tired by the time we reached Camp Muir again. It had taken us about four hours to get back to camp.

We ate — the best Snickers bar of my life! — and took a brief nap, then packed up our tents. At 3 PM, we started the hike back down. Unfortunately, glissading didn’t quite work on the upper Muir Snowfield, but we hit a few decent glissades farther down. Just a few minutes after 7 PM, we were back at our cars.

The hike out, with all our gear in our packs again, was long, but we made it.

The hike out, with all our gear in our packs again, was long, but we made it.

Jenny and I ate at the Basecamp Bar and Grill, and reached our home in Seattle at 11 PM. We had been up for 24 hours. 24 amazing hours.

Now, almost three days later, I still haven’t come down the mountain. I’m still high.

Jenny and I will most likely try to go up again later this year, on the Emmons route, if possible. And we’ve already signed up for a three-day climb this next weekend, to Dome Peak, Washington’s 21st highest mountain (according to the Bulger list).

Share
Posted in Uncategorized | Leave a comment

Print This Print This   Email This Email This

We Climbed Mount Rainier

On Sunday, June 25, 2017, our friend Vicki, Jenny, and I summited Mount Rainier, the tallest mountain in Washington state. Mount Rainier is the most prominent mountain in the contiguous US (only Denali in Alaska and Mauna Kea on Hawaii are more prominent), and also the most glaciated mountain in the lower 48.

This has been Jenny’s and my main project for the last four months, or so, and took hours, days, and weeks of organizing, conditioning, and planning. We went to Glacier Basin and Camp Schurman in preparation for it, we climbed Silver Star Mountain and The Fin to get used to double-header weekends, and we summited Colchuck Peak to get used to steep glaciers. I hadn’t written about any of this, because I wasn’t sure that we would reach our goal of scaling Mount Rainier.

But now we have reached Mount Rainier’s summit, at 14,411 feet. Now I’ll start to slowly post more reports and pictures about the last few months.

Ascending Mount Rainier, at about 13,000 feet:

In the crater of Mount Rainier, at 14,000 feet:

On the Columbia Crest, the summit of Mount Rainier:

On the summit of Mount Rainier.

On the summit of Mount Rainier.

Share
Posted in Pictures | 1 Comment

Print This Print This   Email This Email This

Invoking Maven from Java

On one of my work projects right now, I’m adding unit tests to a code generator. The easiest way to make sure the generated code works is to run mvn clean install. Of course, I want to do that from within the unit test and fail the test if the Maven run fails.

Fortunately, there’s Maven Invoker. Here’s how to use it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
   private void invokeMavenInstall(File file) throws MavenInvocationException, CommandLineException {
        InvocationRequest request = new DefaultInvocationRequest();
        request.setPomFile(file);
        request.setBatchMode(true);
        request.setDebug(true);

        // this prevents M2_HOME from being added in MavenCommandLineBuilder.setShellEnvironment, which then fails to
        // start mvn with "Error: Could not find or load main class org.codehaus.plexus.classworlds.launcher.Launcher"
        request.setShellEnvironmentInherited(false);
        request.setGoals(Collections.singletonList("install"));

        Invoker invoker = new DefaultInvoker();
        invoker.setMavenHome(new File(System.getenv("M3_HOME")));
        invoker.setOutputHandler(new SystemOutHandler());
        invoker.setErrorHandler(new SystemOutHandler());
        invoker.setLogger(new PrintStreamLogger(System.out, InvokerLogger.DEBUG));
        InvocationResult result = invoker.execute(request);
        if (result.getExecutionException() != null) {
            throw result.getExecutionException();
        }
        assertEquals(0, result.getExitCode());
    }
}

The interesting bit here is the request.setShellEnvironmentInherited(false); line. Without it, the MavenCommandLineBuilder.setShellEnvironment method adds an environment variable M2_HOME to it, which prevents Maven from starting up.

Share
Posted in Uncategorized | Leave a comment

Print This Print This   Email This Email This

Domain Housekeeping

I’m in the process of doing some housekeeping with my domains. In particular, I will drop the domains concutest.org and superscalar.org, among a few other, less frequently used domains.

superscalar.org used to point to my old personal homepage, but since I hadn’t updated it in a while, I just pointed pointed it to my professional homepage, which had been available at www.ricken.us for years already. superscalar.org will go away, www.ricken.us will stay.

The story for concutest.org is a little more complex. It is the domain for my research project Concutest, but also had a subdomain mint.concutest.org for the Mint multi-stage Java research project I was a part of. There was also blog.concutest.org, which was a synonym for this blog at www.concurrentaffair.org; community.concutest.org, which was part of a community effort to identify concurrency invariants of the Java API, which I ended some time in 2016; and drjava.concutest.org, which hosted an internal DrJava blog, also taken offline in 2016.

I have create two subdomains for Concutest and Mint:

These subdomains are already active. I hope this will not cause too much inconvenience.

Share
Posted in Uncategorized | Leave a comment

Print This Print This   Email This Email This

Query API with startId, endId, and count

I recently had to write a query API for items in a service. Each item has a numerical, consecutively increasing integer as identifier. Therefore, it made sense to allow callers to specify a range. It also makes sense to specify the number of results to be returned, since we don’t want the result to get too big. The numeric identifiers actually provide a natural way of pagination.

Specifying a range using startId and endId is simple. So is startId and count. But endId and count is tricky. We can’t just start at endId - count + 1, because some of the items in that range might get filtered out because of other query settings, and then we’d return fewer than count items.

Okay, so we include all items, filter first, and then return the last count items. That works, but that creates an unnecessarily long temporary list, which may cause memory problems.

I solved this by using a NavigableMap, and when endId and count are used together, I process a reverse view of the Map using NavigableMap.descendingMap(). Then I can simply limit the number of items and after filtering reverse the list again.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
class Store {
  private final NavigableMap<Integer, CachedItem> m_cache;

  /**
   * Get a list of items.
   * @param includePredicate predicate that returns true if an item should be included in the list
   * @param reverse true to process the items in reverse order
   * @param maxCount optional maximum size of the result
   * @return list of items
   */

  public List<Item> getItems(Predicate<Item> includePredicate, boolean reverse, Optional<Integer> maxCount) {
    // NOTE: the cache currently holds all items ever created in memory... how could that possibly go wrong?

    Stream<Item> stream = (reverse ? m_cache.descendingMap() : m_cache).values().stream()
            .map(cached -> cached.copyItem())
            .filter(includePredicate);

    if (maxCount.isPresent()) {
      stream = stream.limit(maxCount.get());
    }

    return ImmutableList.copyOf(stream.collect(Collectors.toList()));
  }
}

class Controller {
  @RequestMapping(value="/items", method= RequestMethod.GET)
  public Response queryItems(@PathVariable String apiVersion,
                             @RequestParam(value = "filter", required = false) String[] filter,
                             @RequestParam(value = "start", required = false) @Min(1) Integer start,
                             @RequestParam(value = "end", required = false) @Min(1) Integer end,
                             @RequestParam(value = "count", required = false) Integer count,
                             HttpServletRequest request) {
    Response rval = new Response();

    if (start != null && end != null && count != null) {
      throw new IllegalArgumentException("Cannot use start, end, and count all together");
    }

    Predicate<Item> statusPredicate = getStatusPredicate(filter);
    Predicate<Item> idPredicate = getIdPredicate(Optional.ofNullable(start), Optional.ofNullable(end));

    // if we are using an end value and count, we have to process the list in reverse to make sure we accumulate
    // the correct number of jobs
    boolean reverse = (count != null) && (end != null);

    List<Item> items = m_asyncJobStore.getItems(statusPredicate.and(idPredicate),
                reverse, Optional.ofNullable(count));

    if (reverse) {
      items = Lists.reverse(items);
    }

    ItemsQueryType itemsQuery = new ItemsQueryType();
    itemsQuery.setItems(items);
    rval.setItemsQuery(itemsQuery);

    return rval;
  }

  @VisibleForTesting
  static Predicate<AsyncJobType> getIdPredicate(Optional<Integer> start, Optional<Integer> end) {
    Predicate<AsyncJobType> idPredicate = asyncJobType -> true;
    if (start.isPresent()) {
      idPredicate = idPredicate.and(asyncJobType -> asyncJobType.getId() >= start.get());
    }
    if (end.isPresent()) {
      idPredicate = idPredicate.and(asyncJobType -> asyncJobType.getId() <= end.get());
    }
    return idPredicate;
  }

  @VisibleForTesting
  static Predicate<AsyncJobType> getStatusPredicate(String[] filter) {
    Predicate<AsyncJobType> statusPredicate;
    if (filter == null || filter.length == 0) {
      statusPredicate = asyncJobType -> true; // include everything
    } else {
      statusPredicate = asyncJobType -> {
        boolean include = false;
        for(String status: filter) {
          if (status.equalsIgnoreCase(asyncJobType.getStatus().name())) {
            include = true;
            break;
          }
        }
        return include;
      };
    }
    return statusPredicate;
  }
}

I’m pretty happy with this solution for returning the right number of items, no matter how the range is specified.

The big problem, however, is that the class already caches everything in memory before I added the query API. Therefore, this query change could be as well-written as possible, and the cache would still blow up the heap at some point.

Unfortunately, many people don’t seem to think at that scale…

Share
Posted in Code Pranger, Programming | Leave a comment

Print This Print This   Email This Email This

Backing Out Changes and Fixing Things

Let’s say we have three people: Adam, Bob, and Charlie.

Adam submits a change, which later turns out to be bad.
Bob submits a somewhat unrelated change.
Charlie realizes that Adam’s change is bad and backs it out.
That, however, breaks Bob’s unit tests, because Bob’s mock expectations are based on Adam’s change.
Therefore, Charlie backs out Bob’s change as well.

Who has to re-do the changes and fix things?

Adam definitely needs to fix his shit, right?

But should Bob have to re-do his work? Or should Adam have to fix that as well? Or maybe Charlie, because in backing out Adam’s change, Charlie broke Bob’s tests?

Sigh… hi, I’m Bob.

Share
Posted in Code Pranger | Leave a comment

Print This Print This   Email This Email This

Hex Mountain on Snowshoes

Jenny coming up the "Ridge from Hell."

Jenny coming up the “Ridge from Hell.”

Happy to be in the snow together!

Happy to be in the snow together!

First clear view of Hex Mountain's summit.

First clear view of Hex Mountain’s summit.

Looking northwest from about 4000 feet.

Looking northwest from about 4000 feet.

Jenny on the last push before the summit.

Jenny on the last push before the summit.

Looking towards Mt. Rainier. My phone's camera couldn't capture it, but I don't think I've ever seen Little Tahoma this clear from that far away.

Looking towards Mt. Rainier. My phone’s camera couldn’t capture it, but I don’t think I’ve ever seen Little Tahoma this clear from that far away.

Looking north towards Mount Stuart, Sherpa Peak, Colchuck Peak, Dragontail Peak, and Little Annapurna.

Looking north towards Mount Stuart, Sherpa Peak, Colchuck Peak, Dragontail Peak, and Little Annapurna.

On the summit of Hex Mountain, with Rainier out!

On the summit of Hex Mountain, with Rainier out!

Approximate route to the summit and back. We went clockwise. The part just west of Point 3501 was the hardest part.

Approximate route to the summit and back. We went clockwise. The part just west of Point 3501 was the hardest part.

Share
Posted in Pictures | Leave a comment

Print This Print This   Email This Email This