import qualified Data.PQueue.Prio.Min as PQ | |
import qualified Data.HashSet as Set | |
import qualified Data.HashMap.Strict as Map | |
import Data.Hashable (Hashable) | |
import Data.List (foldl') | |
import Data.Maybe (fromJust) | |
astarSearch :: (Eq a, Hashable a) => a -> (a -> Bool) -> (a -> [(a, Int)]) -> (a -> Int) -> Maybe (Int, [a]) | |
astarSearch startNode isGoalNode nextNodeFn heuristic = | |
astar (PQ.singleton (heuristic startNode) (startNode, 0)) |
# rd: print recursive description of entire app window, or of a specified view | |
# | |
# usage: rd [view] | |
# | |
# if no view is specified, prints recursive description of app's keyWindow | |
# | |
command regex rd 's/^[[:space:]]*$/po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]/' 's/^(.+)$/po [%1 recursiveDescription]/' | |
# slow-on: turn slow animations on, for testing on device only, and optionally set the speed | |
# |
The attack detailed below has stopped (for the time being) and almost all network access for almost all customers have been restored. We're keeping this post and the timeline intact for posterity. Unless the attack resumes, we'll post a complete postmortem within 48 hours (so before Wednesday, March 26 at 11:00am central time).
Criminals have laid siege to our networks using what's called a distributed denial-of-service attack (DDoS) starting at 8:46 central time, March 24 2014. The goal is to make Basecamp, and the rest of our services, unavailable by flooding the network with bogus requests, so nothing legitimate can come through. This attack was launched together with a blackmail attempt that sought to have us pay to avoid this assault.
Note that this attack targets the network link between our servers and the internet. All the data is safe and sound, but nobody is able to get to it as long as the attack is being successfully executed. This is like a bunch of people
extension Array { | |
func first() -> Element? { | |
if isEmpty { | |
return nil | |
} | |
return self[0] | |
} | |
func last() -> Element? { |
// | |
// Warnings.xcconfig | |
// | |
// The list of warnings we (don’t) use, and the reasons why. | |
// | |
// :MARK: Warnings in use: | |
// :MARK: -everything | |
// We want the best possible diagnostics, so we simply enable everything that exists, and then opt–out of what doesn’t make sense for us. | |
// | |
// :MARK: - Warnings not to be promoted: |
#!/usr/bin/env ruby | |
device_types_output = `xcrun simctl list devicetypes` | |
device_types = device_types_output.scan /(.*) \((.*)\)/ | |
runtimes_output = `xcrun simctl list runtimes` | |
runtimes = runtimes_output.scan /(.*) \(.*\) \((com.apple[^)]+)\)$/ | |
devices_output = `xcrun simctl list devices` | |
devices = devices_output.scan /\s\s\s\s(.*) \(([^)]+)\) (.*)/ |
/// Observes a run loop to detect any stalling or blocking that occurs. | |
/// | |
/// This class is thread-safe. | |
@interface GHRunLoopWatchdog : NSObject | |
/// Initializes the receiver to watch the specified run loop, using a default | |
/// stalling threshold. | |
- (id)initWithRunLoop:(CFRunLoopRef)runLoop; | |
/// Initializes the receiver to detect when the specified run loop blocks for |
struct Zip3Generator | |
< | |
A: GeneratorType, | |
B: GeneratorType, | |
C: GeneratorType | |
>: GeneratorType { | |
private var first: A | |
private var second: B |
extension UIColor { | |
convenience init(_ hexValue: Int) { | |
let r = (hexValue & 0xFF0000) >> 16 | |
let g = (hexValue & 0x00FF00) >> 8 | |
let b = hexValue & 0x0000FF | |
self.init(red: CGFloat(r)/255, green: CGFloat(g)/255, blue: CGFloat(b)/255, alpha: 1) | |
} | |