├── .env.example ├── .gitconfig ├── .gitignore ├── .hyperdev-assets ├── .subversion ├── README.txt ├── config └── servers ├── README.md ├── TODO.md ├── package.json ├── public ├── css │ ├── custom.css │ └── phantom.css └── js │ └── app.js ├── server.js ├── src ├── controller │ └── index.js └── spreadsheet │ └── importer.js └── views ├── add-forms.html ├── index.handlebars └── layouts └── main.handlebars /.env.example: -------------------------------------------------------------------------------- 1 | # Environment Config 2 | 3 | # store your secrets and config variables in here 4 | # only invited collaborators will be able to see your .env 5 | 6 | # reference these in your code with process.env.CONFIG 7 | 8 | GOOGLE_SPREADSHEET_ID= 9 | PORT=3030 10 | 11 | # note: .env is a shell file so there can't be spaces around '= 12 | -------------------------------------------------------------------------------- /.gitconfig: -------------------------------------------------------------------------------- 1 | [core] 2 | excludesfile = /etc/.gitignore-global 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /.hyperdev-assets: -------------------------------------------------------------------------------- 1 | {"name":"drag-in-files-copy.svg","date":"2016-03-16T18:27:31.021Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files-copy.svg","type":"image/svg+xml","size":6229,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files-copy.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"tkviVwlaQ2RryM4r"} 2 | {"name":"drag-in-files.svg","date":"2016-03-16T18:21:25.984Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"Pr0LH5dpGcRJ2QSU"} 3 | {"name":"click-for-details.svg","date":"2016-03-16T18:21:23.511Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6408,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"nuMndaSEzn2KoNFG"} 4 | {"name":"use-url.svg","date":"2016-03-16T18:21:20.130Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","type":"image/svg+xml","size":6155,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"LiyD5Lxg8FrmZlhz"} 5 | {"name":"click-for-details.svg","date":"2016-03-16T18:20:57.943Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6408,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"04MB8gA2GPoSJ7pp"} 6 | {"name":"drag-in-files.svg","date":"2016-03-16T18:20:56.379Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"q8Au1vYvVFpuGd5b"} 7 | {"name":"use-url.svg","date":"2016-03-16T18:20:52.651Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","type":"image/svg+xml","size":6155,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"9FiKvjvvr4C3oG0i"} 8 | {"name":"1.svg","date":"2016-03-16T18:18:11.204Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F1.svg","type":"image/svg+xml","size":20524,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F1.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"MR02bReHwXODf2iH"} 9 | {"name":"2.svg","date":"2016-03-16T18:18:09.776Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F2.svg","type":"image/svg+xml","size":6597,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F2.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"Q5gjW3biIe5ubDSw"} 10 | {"name":"3.svg","date":"2016-03-16T18:18:08.145Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F3.svg","type":"image/svg+xml","size":6856,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2F3.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"ZtH2QDmOOe11lCXh"} 11 | {"name":"drag-in-files.svg","date":"2016-03-16T18:15:33.737Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"5ZhCFJBZeljgrOsm"} 12 | {"name":"click-for-details.svg","date":"2016-03-16T18:15:31.732Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6408,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"j9DYGSrBdfoh5Qgf"} 13 | {"name":"drag-in-files.svg","date":"2016-03-16T18:13:11.062Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"xs11lHNV40rcZiOr"} 14 | {"name":"click-for-details.svg","date":"2016-03-16T18:13:07.869Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6397,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"oDrtrMLQDzHj3fCi"} 15 | {"name":"drag-in-files.svg","date":"2016-03-16T18:12:09.577Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"QZQEhdAJwQlN15xh"} 16 | {"name":"click-for-details.svg","date":"2016-03-16T18:12:06.958Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6395,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"4DsIsyOkpGM5vhnm"} 17 | {"name":"use-url.svg","date":"2016-03-16T18:12:02.187Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","type":"image/svg+xml","size":6155,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"2D0DVLCP7wUxzaXm"} 18 | {"name":"click-for-details.svg","date":"2016-03-16T18:11:49.564Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":6395,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"ellCYXezSjscGSrr"} 19 | {"name":"drag-in-files.svg","date":"2016-03-16T18:11:44.Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"96WPtGmfDbGjk1Cq"} 20 | {"name":"drag-in-files.svg","date":"2016-03-16T18:11:25.392Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":7990,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"w2iCDrwXU3boaMb0"} 21 | {"uuid":"w2iCDrwXU3boaMb0","deleted":true} 22 | {"uuid":"ellCYXezSjscGSrr","deleted":true} 23 | {"uuid":"96WPtGmfDbGjk1Cq","deleted":true} 24 | {"uuid":"4DsIsyOkpGM5vhnm","deleted":true} 25 | {"uuid":"QZQEhdAJwQlN15xh","deleted":true} 26 | {"uuid":"oDrtrMLQDzHj3fCi","deleted":true} 27 | {"uuid":"xs11lHNV40rcZiOr","deleted":true} 28 | {"uuid":"5ZhCFJBZeljgrOsm","deleted":true} 29 | {"uuid":"j9DYGSrBdfoh5Qgf","deleted":true} 30 | {"uuid":"2D0DVLCP7wUxzaXm","deleted":true} 31 | {"uuid":"04MB8gA2GPoSJ7pp","deleted":true} 32 | {"uuid":"q8Au1vYvVFpuGd5b","deleted":true} 33 | {"uuid":"MR02bReHwXODf2iH","deleted":true} 34 | {"uuid":"9FiKvjvvr4C3oG0i","deleted":true} 35 | {"uuid":"ZtH2QDmOOe11lCXh","deleted":true} 36 | {"uuid":"Q5gjW3biIe5ubDSw","deleted":true} 37 | {"uuid":"Pr0LH5dpGcRJ2QSU","deleted":true} 38 | {"uuid":"tkviVwlaQ2RryM4r","deleted":true} 39 | {"uuid":"LiyD5Lxg8FrmZlhz","deleted":true} 40 | {"uuid":"nuMndaSEzn2KoNFG","deleted":true} 41 | {"name":"use-url.svg","date":"2016-03-29T18:22:42.337Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","type":"image/svg+xml","size":12848,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"BPzdWy4z8l1Yn4EQ"} 42 | {"name":"drag-in-files.svg","date":"2016-03-29T18:22:44.084Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":14823,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"VQVhKMzbgQcBopQk"} 43 | {"uuid":"BPzdWy4z8l1Yn4EQ","deleted":true} 44 | {"uuid":"VQVhKMzbgQcBopQk","deleted":true} 45 | {"name":"click-for-details.svg","date":"2016-03-29T18:22:55.141Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":12623,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"QTRGE6XDqUiSoYO9"} 46 | {"name":"drag-in-files.svg","date":"2016-03-29T18:22:57.596Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":14823,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"RS7rnVaX9eGP4Lri"} 47 | {"uuid":"RS7rnVaX9eGP4Lri","deleted":true} 48 | {"uuid":"QTRGE6XDqUiSoYO9","deleted":true} 49 | {"name":"drag-in-files.svg","date":"2016-03-29T18:23:08.746Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","type":"image/svg+xml","size":14823,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fdrag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(100,156,204)","uuid":"fxoJRXwNdZeThuNz"} 50 | {"name":"click-for-details.svg","date":"2016-03-29T18:23:10.422Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","type":"image/svg+xml","size":12623,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fclick-for-details.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(244,188,188)","uuid":"Lp2si7Cpft2ktNM4"} 51 | {"name":"use-url.svg","date":"2016-03-29T18:23:12.439Z","url":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","type":"image/svg+xml","size":12848,"imageWidth":276,"imageHeight":276,"thumbnail":"https://s3.amazonaws.com/hyperweb-editor-assets/us-east-1%3Ad0d03a8e-22bf-451d-ba15-f08d8f4e99ba%2Fuse-url.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(44,180,188)","uuid":"EjI8Y9wdZ9DEXI17"} 52 | {"name":"dataDashboardGIF.gif","date":"2016-11-17T14:31:15.947Z","url":"https://cdn.hyperdev.com/824edd48-c9bd-4aee-a3fb-561bb97344ed%2FdataDashboardGIF.gif","type":"image/gif","size":102117,"imageWidth":640,"imageHeight":480,"thumbnail":"https://cdn.hyperdev.com/824edd48-c9bd-4aee-a3fb-561bb97344ed%2Fthumbnails%2FdataDashboardGIF.gif","thumbnailWidth":330,"thumbnailHeight":248,"dominantColor":"rgb(252,252,252)","uuid":"sVYa0BdkGGb4R6bD"} 53 | {"name":"logo.svg.webloc","date":"2017-01-31T02:09:39.676Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Flogo.svg.webloc","type":"","size":295,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Flogo.svg.webloc","thumbnailWidth":210,"thumbnailHeight":210,"dominantColor":"rgba(247, 103, 137, 0.60)","uuid":"GEB6H51vv2ouaTmG"} 54 | {"uuid":"sVYa0BdkGGb4R6bD","deleted":true} 55 | {"uuid":"GEB6H51vv2ouaTmG","deleted":true} 56 | {"name":"svg+xml.svg","date":"2017-01-31T02:10:11.684Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fsvg%2Bxml.svg","type":"image/svg+xml","size":1074,"imageWidth":150,"imageHeight":173,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fsvg%2Bxml.svg","thumbnailWidth":150,"thumbnailHeight":173,"dominantColor":null,"uuid":"i32zWnz0cqjKGdWX"} 57 | {"uuid":"fxoJRXwNdZeThuNz","deleted":true} 58 | {"uuid":"Lp2si7Cpft2ktNM4","deleted":true} 59 | {"uuid":"EjI8Y9wdZ9DEXI17","deleted":true} 60 | {"name":"5-calls.png","date":"2017-02-01T03:10:03.888Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2F5-calls.png","type":"image/png","size":9301,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2F5-calls.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"VcriJcrOPh1lal6s"} 61 | {"name":"action-inbox.png","date":"2017-02-01T03:10:04.037Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Faction-inbox.png","type":"image/png","size":23235,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Faction-inbox.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(236,220,204)","uuid":"55QtvAO3co85xISc"} 62 | {"name":"code-for-america.png","date":"2017-02-01T03:10:04.077Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fcode-for-america.png","type":"image/png","size":11716,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fcode-for-america.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"1LbMopGnQAfQY7vi"} 63 | {"name":"beta-nyc.png","date":"2017-02-01T03:10:04.255Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fbeta-nyc.png","type":"image/png","size":8220,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fbeta-nyc.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"y9O7ScyiQZdUKh0C"} 64 | {"name":"dev-progress.png","date":"2017-02-01T03:10:04.283Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fdev-progress.png","type":"image/png","size":8612,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fdev-progress.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"lCzrGQ7bDqDzqWPy"} 65 | {"name":"hillary-bnb.png","date":"2017-02-01T03:10:04.698Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fhillary-bnb.png","type":"image/png","size":7802,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fhillary-bnb.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"NiBRIXt9BVSUTkKd"} 66 | {"name":"more-than-votes.png","date":"2017-02-01T03:10:04.729Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fmore-than-votes.png","type":"image/png","size":22808,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fmore-than-votes.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(4,140,244)","uuid":"BqQWA1Vg6ugQr8vY"} 67 | {"name":"never-again.png","date":"2017-02-01T03:10:05.025Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fnever-again.png","type":"image/png","size":6354,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fnever-again.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(172,172,172)","uuid":"94JspomRdH5o17Yr"} 68 | {"name":"nomad.png","date":"2017-02-01T03:10:05.070Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fnomad.png","type":"image/png","size":6896,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fnomad.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"BBtjyFphWF6Orc02"} 69 | {"name":"progressive-coders-network.png","date":"2017-02-01T03:10:05.379Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fprogressive-coders-network.png","type":"image/png","size":7219,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fprogressive-coders-network.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"8gnfOcOYtLpWrX8J"} 70 | {"name":"resistance-manual.png","date":"2017-02-01T03:10:05.843Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fresistance-manual.png","type":"image/png","size":20494,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fresistance-manual.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(228,228,228)","uuid":"kTeT1LBWVGq912VW"} 71 | {"name":"stay-woke.png","date":"2017-02-01T03:10:05.911Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fstay-woke.png","type":"image/png","size":8564,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fstay-woke.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"NAaxJ1M5Jr6jAClM"} 72 | {"name":"ragtag.png","date":"2017-02-01T03:10:05.985Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fragtag.png","type":"image/png","size":12628,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fragtag.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(52,52,52)","uuid":"u6ULiTdkioMKGXPu"} 73 | {"name":"tech-solidarity.png","date":"2017-02-01T03:10:06.625Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ftech-solidarity.png","type":"image/png","size":5347,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Ftech-solidarity.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"oA1yh51asnijblVY"} 74 | {"name":"swing-left.png","date":"2017-02-01T03:10:06.898Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fswing-left.png","type":"image/png","size":10331,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fswing-left.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"swTWyvpN3KAWHn4G"} 75 | {"name":"arrow.png","date":"2017-02-01T05:30:31.806Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Farrow.png","type":"image/png","size":2812,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Farrow.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"AcRZtPizF1ErEsFf"} 76 | {"name":"codecorpslogo.png","date":"2017-02-01T12:49:03.715Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fcodecorpslogo.png","type":"image/png","size":13227,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fcodecorpslogo.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"BywlkZvXyAT2SIdv"} 77 | {"name":"data-for-democracy.png","date":"2017-02-01T12:59:58.054Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fdata-for-democracy.png","type":"image/png","size":15541,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fdata-for-democracy.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"D1r60kD1YkznD566"} 78 | {"name":"data-refuge.jpg","date":"2017-02-01T13:01:42.929Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fdata-refuge.jpg","type":"image/jpeg","size":54308,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fdata-refuge.jpg","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,244,249)","uuid":"QwxvrsrBk7yz1Ypr"} 79 | {"name":"devprogress.png","date":"2017-02-01T13:02:35.110Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fdevprogress.png","type":"image/png","size":9663,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fdevprogress.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"svTjA2YSOCDSIVLc"} 80 | {"name":"carpool-vote.png","date":"2017-02-01T13:52:37.584Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fcarpool-vote.png","type":"image/png","size":21396,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fcarpool-vote.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"5N8CE7e3KiOhnTqn"} 81 | {"name":"phone-your-rep.jpg","date":"2017-02-01T13:55:13.807Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fphone-your-rep.jpg","type":"image/jpeg","size":25321,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fphone-your-rep.jpg","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(60,68,100)","uuid":"TgmV3t761a0jxhii"} 82 | {"name":"prog-cod.png","date":"2017-02-01T13:56:12.357Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fprog-cod.png","type":"image/png","size":20294,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fprog-cod.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"PYcM36rp5UNORSw1"} 83 | {"uuid":"PYcM36rp5UNORSw1","deleted":true} 84 | {"name":"prog-cod.png","date":"2017-02-01T13:56:50.565Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fprog-cod.png","type":"image/png","size":20291,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fprog-cod.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"ObkQVSJOVvMdK1zS"} 85 | {"name":"first-100-days.jpg","date":"2017-02-01T13:59:15.313Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ffirst-100-days.jpg","type":"image/jpeg","size":60399,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Ffirst-100-days.jpg","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(68,68,69)","uuid":"c6Kmo2soGAlKEsMc"} 86 | {"name":"call-them-in.png","date":"2017-02-01T14:00:41.201Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fcall-them-in.png","type":"image/png","size":13538,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fcall-them-in.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"oaBYvdrG5PYwGoQB"} 87 | {"name":"calls-for-change.png","date":"2017-02-01T14:03:34.950Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fcalls-for-change.png","type":"image/png","size":10787,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fcalls-for-change.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"qJuF5vM2V6mhubH4"} 88 | {"name":"daily-action.jpg","date":"2017-02-01T14:05:00.978Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fdaily-action.jpg","type":"image/jpeg","size":42915,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fdaily-action.jpg","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(172,172,173)","uuid":"uqDox3dPedptJO9P"} 89 | {"name":"drive-the-vote.png","date":"2017-02-01T14:10:39.634Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fdrive-the-vote.png","type":"image/png","size":33935,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fdrive-the-vote.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"F6rH5HvOZmFL6UHW"} 90 | {"name":"indivisible.jpg","date":"2017-02-01T14:12:43.768Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Findivisible.jpg","type":"image/jpeg","size":35119,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Findivisible.jpg","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(212,204,204)","uuid":"lEJSgGkeOqnedNlA"} 91 | {"name":"social-roots.png","date":"2017-02-01T15:00:47.933Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fsocial-roots.png","type":"image/png","size":15478,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fsocial-roots.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(244,252,252)","uuid":"FH62Y4YYLYIq6bmO"} 92 | {"name":"trumpresistance-today.png","date":"2017-02-01T15:07:19.582Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ftrumpresistance-today.png","type":"image/png","size":7669,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Ftrumpresistance-today.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(244,252,252)","uuid":"64WxFTUwu3Me1vmL"} 93 | {"name":"white-house-inc.png","date":"2017-02-01T15:08:53.220Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fwhite-house-inc.png","type":"image/png","size":51351,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fwhite-house-inc.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(28,36,84)","uuid":"UhL9uZRQsQrasqnq"} 94 | {"name":"tech-forward-og.png","date":"2017-02-01T15:12:20.292Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ftech-forward-og.png","type":"image/png","size":34260,"imageWidth":1200,"imageHeight":630,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Ftech-forward-og.png","thumbnailWidth":330,"thumbnailHeight":174,"dominantColor":"rgb(252,252,252)","uuid":"Kpg1O4YX6d0gCqJV"} 95 | {"name":"tech-forward-twitter.png","date":"2017-02-01T15:13:55.828Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ftech-forward-twitter.png","type":"image/png","size":31331,"imageWidth":1024,"imageHeight":512,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Ftech-forward-twitter.png","thumbnailWidth":330,"thumbnailHeight":165,"dominantColor":"rgb(252,252,252)","uuid":"hZgZPYx2H70TTHuj"} 96 | {"uuid":"Kpg1O4YX6d0gCqJV","deleted":true} 97 | {"name":"tech-forward-og.png","date":"2017-02-01T15:17:35.100Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ftech-forward-og.png","type":"image/png","size":31416,"imageWidth":1024,"imageHeight":538,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Ftech-forward-og.png","thumbnailWidth":330,"thumbnailHeight":174,"dominantColor":"rgb(252,252,252)","uuid":"C6WzG463wBiCJaAF"} 98 | {"name":"favicon-32x32.png","date":"2017-02-01T16:08:46.070Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ffavicon-32x32.png","type":"image/png","size":1268,"imageWidth":32,"imageHeight":32,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ffavicon-32x32.png","thumbnailWidth":32,"thumbnailHeight":32,"dominantColor":"rgb(252,252,252)","uuid":"riDK3KdZxl5LYm8u"} 99 | {"name":"favicon-16x16.png","date":"2017-02-01T16:08:46.147Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ffavicon-16x16.png","type":"image/png","size":1000,"imageWidth":16,"imageHeight":16,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ffavicon-16x16.png","thumbnailWidth":16,"thumbnailHeight":16,"dominantColor":"rgb(223,223,223)","uuid":"vUBlJzwiqQhIJxh5"} 100 | {"name":"favicon-96x96.png","date":"2017-02-01T16:08:46.174Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ffavicon-96x96.png","type":"image/png","size":2050,"imageWidth":96,"imageHeight":96,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ffavicon-96x96.png","thumbnailWidth":96,"thumbnailHeight":96,"dominantColor":"rgb(252,252,252)","uuid":"hjyiXj5VlJVimusP"} 101 | {"name":"techForwardGIF.gif","date":"2017-02-01T16:48:45.916Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2FtechForwardGIF.gif","type":"image/gif","size":555500,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2FtechForwardGIF.gif","thumbnailWidth":330,"thumbnailHeight":207,"dominantColor":"rgb(252,252,252)","uuid":"wqU4grzgWSpLT1dc"} 102 | {"uuid":"wqU4grzgWSpLT1dc","deleted":true} 103 | {"name":"techForwardGIF.gif","date":"2017-02-01T16:49:30.828Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2FtechForwardGIF.gif","type":"image/gif","size":507636,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2FtechForwardGIF.gif","thumbnailWidth":330,"thumbnailHeight":207,"dominantColor":"rgb(252,252,252)","uuid":"BdTs23bPk4WMXuwJ"} 104 | {"name":"sister-district.png","date":"2017-02-01T19:51:25.843Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fsister-district.png","type":"image/png","size":40993,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fsister-district.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"O0jdxT37aDj7Cid9"} 105 | {"name":"the-65.png","date":"2017-02-01T21:52:57.576Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthe-65.png","type":"image/png","size":18415,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fthe-65.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"vfX4HySaGUVE28kq"} 106 | {"name":"trans-hack.png","date":"2017-02-02T01:08:30.443Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ftrans-hack.png","type":"image/png","size":8430,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Ftrans-hack.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"PBCEJyvDvXNj4NUw"} 107 | {"name":"countable.png","date":"2017-02-02T04:02:40.466Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fcountable.png","type":"image/png","size":2759,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fcountable.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"EGJtYVNAlG3SXoV6"} 108 | {"name":"postmark.png","date":"2017-02-02T04:04:05.408Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fpostmark.png","type":"image/png","size":11910,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fpostmark.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,228,4)","uuid":"OZjKA91LuzPevc2N"} 109 | {"name":"commonsenserepublic.png","date":"2017-02-10T01:56:18.801Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fcommonsenserepublic.png","type":"image/png","size":17157,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fcommonsenserepublic.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(236,236,236)","uuid":"3IZeWbXEaEhH4w1r"} 110 | {"name":"remindertome.jpg","date":"2017-02-10T02:42:38.591Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fremindertome.jpg","type":"image/jpeg","size":14982,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fremindertome.jpg","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(82,76,84)","uuid":"5eiPpJ5TkASve39M"} 111 | {"name":"tech-congress.png","date":"2017-02-10T02:44:18.650Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ftech-congress.png","type":"image/png","size":28701,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Ftech-congress.png","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"liSXFtQSrtwYXed3"} 112 | {"uuid":"c6Kmo2soGAlKEsMc","deleted":true} 113 | {"name":"first-100-days.jpg","date":"2017-02-10T02:46:00.358Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Ffirst-100-days.jpg","type":"image/jpeg","size":25520,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Ffirst-100-days.jpg","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(64,60,65)","uuid":"AgApKR8bWBiZGuQI"} 114 | {"uuid":"QwxvrsrBk7yz1Ypr","deleted":true} 115 | {"name":"data-refuge.jpg","date":"2017-02-10T02:49:56.014Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fdata-refuge.jpg","type":"image/jpeg","size":11463,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fdata-refuge.jpg","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(248,244,252)","uuid":"PjewA7RmdmoQdYHT"} 116 | {"name":"white-house-inc.jpg","date":"2017-02-10T02:51:02.087Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fwhite-house-inc.jpg","type":"image/jpeg","size":11909,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fwhite-house-inc.jpg","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(28,36,84)","uuid":"VWw57ot0u7F3nls0"} 117 | {"uuid":"uqDox3dPedptJO9P","deleted":true} 118 | {"name":"daily-action.jpg","date":"2017-02-10T02:51:44.417Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fdaily-action.jpg","type":"image/jpeg","size":12327,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fdaily-action.jpg","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(172,172,174)","uuid":"d90nJzqO8HRxqWxg"} 119 | {"name":"sister-district.jpg","date":"2017-02-10T02:52:56.290Z","url":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fsister-district.jpg","type":"image/jpeg","size":12872,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2Fthumbnails%2Fsister-district.jpg","thumbnailWidth":330,"thumbnailHeight":330,"dominantColor":"rgb(252,252,252)","uuid":"VB3iXFVh8xWv33kk"} 120 | -------------------------------------------------------------------------------- /.subversion/README.txt: -------------------------------------------------------------------------------- 1 | This directory holds run-time configuration information for Subversion 2 | clients. The configuration files all share the same syntax, but you 3 | should examine a particular file to learn what configuration 4 | directives are valid for that file. 5 | 6 | The syntax is standard INI format: 7 | 8 | - Empty lines, and lines starting with '#', are ignored. 9 | The first significant line in a file must be a section header. 10 | 11 | - A section starts with a section header, which must start in 12 | the first column: 13 | 14 | [section-name] 15 | 16 | - An option, which must always appear within a section, is a pair 17 | (name, value). There are two valid forms for defining an 18 | option, both of which must start in the first column: 19 | 20 | name: value 21 | name = value 22 | 23 | Whitespace around the separator (:, =) is optional. 24 | 25 | - Section and option names are case-insensitive, but case is 26 | preserved. 27 | 28 | - An option's value may be broken into several lines. The value 29 | continuation lines must start with at least one whitespace. 30 | Trailing whitespace in the previous line, the newline character 31 | and the leading whitespace in the continuation line is compressed 32 | into a single space character. 33 | 34 | - All leading and trailing whitespace around a value is trimmed, 35 | but the whitespace within a value is preserved, with the 36 | exception of whitespace around line continuations, as 37 | described above. 38 | 39 | - When a value is a boolean, any of the following strings are 40 | recognised as truth values (case does not matter): 41 | 42 | true false 43 | yes no 44 | on off 45 | 1 0 46 | 47 | - When a value is a list, it is comma-separated. Again, the 48 | whitespace around each element of the list is trimmed. 49 | 50 | - Option values may be expanded within a value by enclosing the 51 | option name in parentheses, preceded by a percent sign and 52 | followed by an 's': 53 | 54 | %(name)s 55 | 56 | The expansion is performed recursively and on demand, during 57 | svn_option_get. The name is first searched for in the same 58 | section, then in the special [DEFAULT] section. If the name 59 | is not found, the whole '%(name)s' placeholder is left 60 | unchanged. 61 | 62 | Any modifications to the configuration data invalidate all 63 | previously expanded values, so that the next svn_option_get 64 | will take the modifications into account. 65 | 66 | The syntax of the configuration files is a subset of the one used by 67 | Python's ConfigParser module; see 68 | 69 | http://www.python.org/doc/current/lib/module-ConfigParser.html 70 | 71 | Configuration data in the Windows registry 72 | ========================================== 73 | 74 | On Windows, configuration data may also be stored in the registry. The 75 | functions svn_config_read and svn_config_merge will read from the 76 | registry when passed file names of the form: 77 | 78 | REGISTRY:/path/to/config-key 79 | 80 | The REGISTRY: prefix must be in upper case. The part must be 81 | one of: 82 | 83 | HKLM for HKEY_LOCAL_MACHINE 84 | HKCU for HKEY_CURRENT_USER 85 | 86 | The values in config-key represent the options in the [DEFAULT] section. 87 | The keys below config-key represent other sections, and their values 88 | represent the options. Only values of type REG_SZ whose name doesn't 89 | start with a '#' will be used; other values, as well as the keys' 90 | default values, will be ignored. 91 | 92 | 93 | File locations 94 | ============== 95 | 96 | Typically, Subversion uses two config directories, one for site-wide 97 | configuration, 98 | 99 | Unix: 100 | /etc/subversion/servers 101 | /etc/subversion/config 102 | /etc/subversion/hairstyles 103 | Windows: 104 | %ALLUSERSPROFILE%\Application Data\Subversion\servers 105 | %ALLUSERSPROFILE%\Application Data\Subversion\config 106 | %ALLUSERSPROFILE%\Application Data\Subversion\hairstyles 107 | REGISTRY:HKLM\Software\Tigris.org\Subversion\Servers 108 | REGISTRY:HKLM\Software\Tigris.org\Subversion\Config 109 | REGISTRY:HKLM\Software\Tigris.org\Subversion\Hairstyles 110 | 111 | and one for per-user configuration: 112 | 113 | Unix: 114 | ~/.subversion/servers 115 | ~/.subversion/config 116 | ~/.subversion/hairstyles 117 | Windows: 118 | %APPDATA%\Subversion\servers 119 | %APPDATA%\Subversion\config 120 | %APPDATA%\Subversion\hairstyles 121 | REGISTRY:HKCU\Software\Tigris.org\Subversion\Servers 122 | REGISTRY:HKCU\Software\Tigris.org\Subversion\Config 123 | REGISTRY:HKCU\Software\Tigris.org\Subversion\Hairstyles 124 | 125 | -------------------------------------------------------------------------------- /.subversion/config: -------------------------------------------------------------------------------- 1 | ### This file configures various client-side behaviors. 2 | ### 3 | ### The commented-out examples below are intended to demonstrate 4 | ### how to use this file. 5 | 6 | ### Section for authentication and authorization customizations. 7 | [auth] 8 | ### Set password stores used by Subversion. They should be 9 | ### delimited by spaces or commas. The order of values determines 10 | ### the order in which password stores are used. 11 | ### Valid password stores: 12 | ### gnome-keyring (Unix-like systems) 13 | ### kwallet (Unix-like systems) 14 | ### gpg-agent (Unix-like systems) 15 | ### keychain (Mac OS X) 16 | ### windows-cryptoapi (Windows) 17 | # password-stores = gpg-agent,gnome-keyring,kwallet 18 | ### To disable all password stores, use an empty list: 19 | # password-stores = 20 | ### 21 | ### Set KWallet wallet used by Subversion. If empty or unset, 22 | ### then the default network wallet will be used. 23 | # kwallet-wallet = 24 | ### 25 | ### Include PID (Process ID) in Subversion application name when 26 | ### using KWallet. It defaults to 'no'. 27 | # kwallet-svn-application-name-with-pid = yes 28 | ### 29 | ### Set ssl-client-cert-file-prompt to 'yes' to cause the client 30 | ### to prompt for a path to a client cert file when the server 31 | ### requests a client cert but no client cert file is found in the 32 | ### expected place (see the 'ssl-client-cert-file' option in the 33 | ### 'servers' configuration file). Defaults to 'no'. 34 | # ssl-client-cert-file-prompt = no 35 | ### 36 | ### The rest of the [auth] section in this file has been deprecated. 37 | ### Both 'store-passwords' and 'store-auth-creds' can now be 38 | ### specified in the 'servers' file in your config directory 39 | ### and are documented there. Anything specified in this section 40 | ### is overridden by settings specified in the 'servers' file. 41 | # store-passwords = no 42 | # store-auth-creds = no 43 | 44 | ### Section for configuring external helper applications. 45 | [helpers] 46 | ### Set editor-cmd to the command used to invoke your text editor. 47 | ### This will override the environment variables that Subversion 48 | ### examines by default to find this information ($EDITOR, 49 | ### et al). 50 | # editor-cmd = editor (vi, emacs, notepad, etc.) 51 | ### Set diff-cmd to the absolute path of your 'diff' program. 52 | ### This will override the compile-time default, which is to use 53 | ### Subversion's internal diff implementation. 54 | # diff-cmd = diff_program (diff, gdiff, etc.) 55 | ### Diff-extensions are arguments passed to an external diff 56 | ### program or to Subversion's internal diff implementation. 57 | ### Set diff-extensions to override the default arguments ('-u'). 58 | # diff-extensions = -u -p 59 | ### Set diff3-cmd to the absolute path of your 'diff3' program. 60 | ### This will override the compile-time default, which is to use 61 | ### Subversion's internal diff3 implementation. 62 | # diff3-cmd = diff3_program (diff3, gdiff3, etc.) 63 | ### Set diff3-has-program-arg to 'yes' if your 'diff3' program 64 | ### accepts the '--diff-program' option. 65 | # diff3-has-program-arg = [yes | no] 66 | ### Set merge-tool-cmd to the command used to invoke your external 67 | ### merging tool of choice. Subversion will pass 5 arguments to 68 | ### the specified command: base theirs mine merged wcfile 69 | # merge-tool-cmd = merge_command 70 | 71 | ### Section for configuring tunnel agents. 72 | [tunnels] 73 | ### Configure svn protocol tunnel schemes here. By default, only 74 | ### the 'ssh' scheme is defined. You can define other schemes to 75 | ### be used with 'svn+scheme://hostname/path' URLs. A scheme 76 | ### definition is simply a command, optionally prefixed by an 77 | ### environment variable name which can override the command if it 78 | ### is defined. The command (or environment variable) may contain 79 | ### arguments, using standard shell quoting for arguments with 80 | ### spaces. The command will be invoked as: 81 | ### svnserve -t 82 | ### (If the URL includes a username, then the hostname will be 83 | ### passed to the tunnel agent as @.) If the 84 | ### built-in ssh scheme were not predefined, it could be defined 85 | ### as: 86 | # ssh = $SVN_SSH ssh -q -o ControlMaster=no 87 | ### If you wanted to define a new 'rsh' scheme, to be used with 88 | ### 'svn+rsh:' URLs, you could do so as follows: 89 | # rsh = rsh 90 | ### Or, if you wanted to specify a full path and arguments: 91 | # rsh = /path/to/rsh -l myusername 92 | ### On Windows, if you are specifying a full path to a command, 93 | ### use a forward slash (/) or a paired backslash (\\) as the 94 | ### path separator. A single backslash will be treated as an 95 | ### escape for the following character. 96 | 97 | ### Section for configuring miscellaneous Subversion options. 98 | [miscellany] 99 | ### Set global-ignores to a set of whitespace-delimited globs 100 | ### which Subversion will ignore in its 'status' output, and 101 | ### while importing or adding files and directories. 102 | ### '*' matches leading dots, e.g. '*.rej' matches '.foo.rej'. 103 | # global-ignores = *.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo __pycache__ 104 | # *.rej *~ #*# .#* .*.swp .DS_Store [Tt]humbs.db 105 | ### Set log-encoding to the default encoding for log messages 106 | # log-encoding = latin1 107 | ### Set use-commit-times to make checkout/update/switch/revert 108 | ### put last-committed timestamps on every file touched. 109 | # use-commit-times = yes 110 | ### Set no-unlock to prevent 'svn commit' from automatically 111 | ### releasing locks on files. 112 | # no-unlock = yes 113 | ### Set mime-types-file to a MIME type registry file, used to 114 | ### provide hints to Subversion's MIME type auto-detection 115 | ### algorithm. 116 | # mime-types-file = /path/to/mime.types 117 | ### Set preserved-conflict-file-exts to a whitespace-delimited 118 | ### list of patterns matching file extensions which should be 119 | ### preserved in generated conflict file names. By default, 120 | ### conflict files use custom extensions. 121 | # preserved-conflict-file-exts = doc ppt xls od? 122 | ### Set enable-auto-props to 'yes' to enable automatic properties 123 | ### for 'svn add' and 'svn import', it defaults to 'no'. 124 | ### Automatic properties are defined in the section 'auto-props'. 125 | # enable-auto-props = yes 126 | ### Set interactive-conflicts to 'no' to disable interactive 127 | ### conflict resolution prompting. It defaults to 'yes'. 128 | # interactive-conflicts = no 129 | ### Set memory-cache-size to define the size of the memory cache 130 | ### used by the client when accessing a FSFS repository via 131 | ### ra_local (the file:// scheme). The value represents the number 132 | ### of MB used by the cache. 133 | # memory-cache-size = 16 134 | ### Set diff-ignore-content-type to 'yes' to cause 'svn diff' to 135 | ### attempt to show differences of all modified files regardless 136 | ### of their MIME content type. By default, Subversion will only 137 | ### attempt to show differences for files believed to have human- 138 | ### readable (non-binary) content. This option is especially 139 | ### useful when Subversion is configured (via the 'diff-cmd' 140 | ### option) to employ an external differencing tool which is able 141 | ### to show meaningful differences for binary file formats. [New 142 | ### in 1.9] 143 | # diff-ignore-content-type = no 144 | 145 | ### Section for configuring automatic properties. 146 | [auto-props] 147 | ### The format of the entries is: 148 | ### file-name-pattern = propname[=value][;propname[=value]...] 149 | ### The file-name-pattern can contain wildcards (such as '*' and 150 | ### '?'). All entries which match (case-insensitively) will be 151 | ### applied to the file. Note that auto-props functionality 152 | ### must be enabled, which is typically done by setting the 153 | ### 'enable-auto-props' option. 154 | # *.c = svn:eol-style=native 155 | # *.cpp = svn:eol-style=native 156 | # *.h = svn:keywords=Author Date Id Rev URL;svn:eol-style=native 157 | # *.dsp = svn:eol-style=CRLF 158 | # *.dsw = svn:eol-style=CRLF 159 | # *.sh = svn:eol-style=native;svn:executable 160 | # *.txt = svn:eol-style=native;svn:keywords=Author Date Id Rev URL; 161 | # *.png = svn:mime-type=image/png 162 | # *.jpg = svn:mime-type=image/jpeg 163 | # Makefile = svn:eol-style=native 164 | 165 | ### Section for configuring working copies. 166 | [working-copy] 167 | ### Set to a list of the names of specific clients that should use 168 | ### exclusive SQLite locking of working copies. This increases the 169 | ### performance of the client but prevents concurrent access by 170 | ### other clients. Third-party clients may also support this 171 | ### option. 172 | ### Possible values: 173 | ### svn (the command line client) 174 | # exclusive-locking-clients = 175 | ### Set to true to enable exclusive SQLite locking of working 176 | ### copies by all clients using the 1.8 APIs. Enabling this may 177 | ### cause some clients to fail to work properly. This does not have 178 | ### to be set for exclusive-locking-clients to work. 179 | # exclusive-locking = false 180 | ### Set the SQLite busy timeout in milliseconds: the maximum time 181 | ### the client waits to get access to the SQLite database before 182 | ### returning an error. The default is 10000, i.e. 10 seconds. 183 | ### Longer values may be useful when exclusive locking is enabled. 184 | # busy-timeout = 10000 185 | -------------------------------------------------------------------------------- /.subversion/servers: -------------------------------------------------------------------------------- 1 | ### This file specifies server-specific parameters, 2 | ### including HTTP proxy information, HTTP timeout settings, 3 | ### and authentication settings. 4 | ### 5 | ### The currently defined server options are: 6 | ### http-proxy-host Proxy host for HTTP connection 7 | ### http-proxy-port Port number of proxy host service 8 | ### http-proxy-username Username for auth to proxy service 9 | ### http-proxy-password Password for auth to proxy service 10 | ### http-proxy-exceptions List of sites that do not use proxy 11 | ### http-timeout Timeout for HTTP requests in seconds 12 | ### http-compression Whether to compress HTTP requests 13 | ### http-max-connections Maximum number of parallel server 14 | ### connections to use for any given 15 | ### HTTP operation. 16 | ### http-chunked-requests Whether to use chunked transfer 17 | ### encoding for HTTP requests body. 18 | ### neon-debug-mask Debug mask for Neon HTTP library 19 | ### ssl-authority-files List of files, each of a trusted CA 20 | ### ssl-trust-default-ca Trust the system 'default' CAs 21 | ### ssl-client-cert-file PKCS#12 format client certificate file 22 | ### ssl-client-cert-password Client Key password, if needed. 23 | ### ssl-pkcs11-provider Name of PKCS#11 provider to use. 24 | ### http-library Which library to use for http/https 25 | ### connections. 26 | ### http-bulk-updates Whether to request bulk update 27 | ### responses or to fetch each file 28 | ### in an individual request. 29 | ### store-passwords Specifies whether passwords used 30 | ### to authenticate against a 31 | ### Subversion server may be cached 32 | ### to disk in any way. 33 | ### store-plaintext-passwords Specifies whether passwords may 34 | ### be cached on disk unencrypted. 35 | ### store-ssl-client-cert-pp Specifies whether passphrase used 36 | ### to authenticate against a client 37 | ### certificate may be cached to disk 38 | ### in any way 39 | ### store-ssl-client-cert-pp-plaintext 40 | ### Specifies whether client cert 41 | ### passphrases may be cached on disk 42 | ### unencrypted (i.e., as plaintext). 43 | ### store-auth-creds Specifies whether any auth info 44 | ### (passwords, server certs, etc.) 45 | ### may be cached to disk. 46 | ### username Specifies the default username. 47 | ### 48 | ### Set store-passwords to 'no' to avoid storing passwords on disk 49 | ### in any way, including in password stores. It defaults to 50 | ### 'yes', but Subversion will never save your password to disk in 51 | ### plaintext unless explicitly configured to do so. 52 | ### Note that this option only prevents saving of *new* passwords; 53 | ### it doesn't invalidate existing passwords. (To do that, remove 54 | ### the cache files by hand as described in the Subversion book.) 55 | ### 56 | ### Set store-plaintext-passwords to 'no' to avoid storing 57 | ### passwords in unencrypted form in the auth/ area of your config 58 | ### directory. Set it to 'yes' to allow Subversion to store 59 | ### unencrypted passwords in the auth/ area. The default is 60 | ### 'ask', which means that Subversion will ask you before 61 | ### saving a password to disk in unencrypted form. Note that 62 | ### this option has no effect if either 'store-passwords' or 63 | ### 'store-auth-creds' is set to 'no'. 64 | ### 65 | ### Set store-ssl-client-cert-pp to 'no' to avoid storing ssl 66 | ### client certificate passphrases in the auth/ area of your 67 | ### config directory. It defaults to 'yes', but Subversion will 68 | ### never save your passphrase to disk in plaintext unless 69 | ### explicitly configured to do so. 70 | ### 71 | ### Note store-ssl-client-cert-pp only prevents the saving of *new* 72 | ### passphrases; it doesn't invalidate existing passphrases. To do 73 | ### that, remove the cache files by hand as described in the 74 | ### Subversion book at http://svnbook.red-bean.com/nightly/en/\ 75 | ### svn.serverconfig.netmodel.html\ 76 | ### #svn.serverconfig.netmodel.credcache 77 | ### 78 | ### Set store-ssl-client-cert-pp-plaintext to 'no' to avoid storing 79 | ### passphrases in unencrypted form in the auth/ area of your 80 | ### config directory. Set it to 'yes' to allow Subversion to 81 | ### store unencrypted passphrases in the auth/ area. The default 82 | ### is 'ask', which means that Subversion will prompt before 83 | ### saving a passphrase to disk in unencrypted form. Note that 84 | ### this option has no effect if either 'store-auth-creds' or 85 | ### 'store-ssl-client-cert-pp' is set to 'no'. 86 | ### 87 | ### Set store-auth-creds to 'no' to avoid storing any Subversion 88 | ### credentials in the auth/ area of your config directory. 89 | ### Note that this includes SSL server certificates. 90 | ### It defaults to 'yes'. Note that this option only prevents 91 | ### saving of *new* credentials; it doesn't invalidate existing 92 | ### caches. (To do that, remove the cache files by hand.) 93 | ### 94 | ### HTTP timeouts, if given, are specified in seconds. A timeout 95 | ### of 0, i.e. zero, causes a builtin default to be used. 96 | ### 97 | ### Most users will not need to explicitly set the http-library 98 | ### option, but valid values for the option include: 99 | ### 'serf': Serf-based module (Subversion 1.5 - present) 100 | ### 'neon': Neon-based module (Subversion 1.0 - 1.7) 101 | ### Availability of these modules may depend on your specific 102 | ### Subversion distribution. 103 | ### 104 | ### The commented-out examples below are intended only to 105 | ### demonstrate how to use this file; any resemblance to actual 106 | ### servers, living or dead, is entirely coincidental. 107 | 108 | ### In the 'groups' section, the URL of the repository you're 109 | ### trying to access is matched against the patterns on the right. 110 | ### If a match is found, the server options are taken from the 111 | ### section with the corresponding name on the left. 112 | 113 | [groups] 114 | # group1 = *.collab.net 115 | # othergroup = repository.blarggitywhoomph.com 116 | # thirdgroup = *.example.com 117 | 118 | ### Information for the first group: 119 | # [group1] 120 | # http-proxy-host = proxy1.some-domain-name.com 121 | # http-proxy-port = 80 122 | # http-proxy-username = blah 123 | # http-proxy-password = doubleblah 124 | # http-timeout = 60 125 | # neon-debug-mask = 130 126 | # store-plaintext-passwords = no 127 | # username = harry 128 | 129 | ### Information for the second group: 130 | # [othergroup] 131 | # http-proxy-host = proxy2.some-domain-name.com 132 | # http-proxy-port = 9000 133 | # No username and password for the proxy, so use the defaults below. 134 | 135 | ### You can set default parameters in the 'global' section. 136 | ### These parameters apply if no corresponding parameter is set in 137 | ### a specifically matched group as shown above. Thus, if you go 138 | ### through the same proxy server to reach every site on the 139 | ### Internet, you probably just want to put that server's 140 | ### information in the 'global' section and not bother with 141 | ### 'groups' or any other sections. 142 | ### 143 | ### Most people might want to configure password caching 144 | ### parameters here, but you can also configure them per server 145 | ### group (per-group settings override global settings). 146 | ### 147 | ### If you go through a proxy for all but a few sites, you can 148 | ### list those exceptions under 'http-proxy-exceptions'. This only 149 | ### overrides defaults, not explicitly matched server names. 150 | ### 151 | ### 'ssl-authority-files' is a semicolon-delimited list of files, 152 | ### each pointing to a PEM-encoded Certificate Authority (CA) 153 | ### SSL certificate. See details above for overriding security 154 | ### due to SSL. 155 | [global] 156 | # http-proxy-exceptions = *.exception.com, www.internal-site.org 157 | # http-proxy-host = defaultproxy.whatever.com 158 | # http-proxy-port = 7000 159 | # http-proxy-username = defaultusername 160 | # http-proxy-password = defaultpassword 161 | # http-compression = no 162 | # No http-timeout, so just use the builtin default. 163 | # No neon-debug-mask, so neon debugging is disabled. 164 | # ssl-authority-files = /path/to/CAcert.pem;/path/to/CAcert2.pem 165 | # 166 | # Password / passphrase caching parameters: 167 | # store-passwords = no 168 | # store-ssl-client-cert-pp = no 169 | # store-plaintext-passwords = no 170 | # store-ssl-client-cert-pp-plaintext = no 171 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tech Forward 2 | Sharing tech-focused organizations and tools working for social progress. 3 | 4 | Built by @stauffermatt and friends 5 | 6 | ![](https://cdn.gomix.com/16d249c6-c928-4616-a548-3108bce18ead%2FtechForwardGIF.gif) 7 | 8 | ## Getting Started 9 | 10 | 11 | ### On Gomix 12 | - Just [remix](https://gomix.com/#!/remix/tech-forward-2/16d249c6-c928-4616-a548-3108bce18ead) and add your Google Spreadsheet ID to `.env`. 13 | 14 | ### Local development 15 | - `cp .env.example .env` 16 | - Open `.env` in your editor. You may need to fill in some values for your dev. See comments in that file. 17 | - `npm install` 18 | - `npm start` 19 | - `open http://localhost:3030` -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | - [x] Add Data Sources section (e.g. ProPublica Congress API) 2 | - [ ] Resize all images to 200x200 instead of 400x400 3 | - [ ] Move suggestion form URLs to environment variables 4 | - [ ] Write tests around importers 5 | - [ ] For all resources, track whether they're vetted (will they sell your phone number? Is it open source?) 6 | - [ ] Decide hwo to handle mentoring/etc (e.g. ZimpoPy): 7 | - [ ] Add some content or qualifiers for who should be in here 8 | - [ ] Handle multi-location (e.g. Tech Solidarity) 9 | - [ ] Build a "what's best for me" tool (e.g. I care about XXXX and I program in XXXX) 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tech-forward-dashboard", 3 | "version": "0.0.2", 4 | "description": "Tech forward - listing forward-thinking organizations, tools, and resources", 5 | "main": "server.js", 6 | "scripts": { 7 | "start": "node server.js" 8 | }, 9 | "dependencies": { 10 | "async": "^2.1.4", 11 | "dotenv": "^2.0.0", 12 | "express": "^4.14.1", 13 | "express-handlebars": "^3.0.0", 14 | "google-spreadsheets": "^0.5.1", 15 | "lodash": "^4.17.4", 16 | "memory-cache": "^0.1.6", 17 | "promise": "^7.1.1" 18 | }, 19 | "engines": { 20 | "node": "4.4.5" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/mattstauffer/tech-forward-gomix" 25 | }, 26 | "keywords": [ 27 | "node", 28 | "express", 29 | "googlesheets", 30 | "resistance", 31 | "progress" 32 | ], 33 | "author": { 34 | "name": "Matt Stauffer", 35 | "email": "matt@mattstauffer.co", 36 | "url": "https://mattstauffer.co" 37 | }, 38 | "license": "MIT" 39 | } 40 | -------------------------------------------------------------------------------- /public/css/custom.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | color: #111; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 4 | } 5 | 6 | #header .logo { 7 | color: #444; 8 | } 9 | 10 | h1 { 11 | font-size: 1.9em; 12 | } 13 | 14 | @media only screen and (min-width: 737px) { 15 | h1 { 16 | font-size: 2.5em; 17 | } 18 | } 19 | 20 | .page-nav a { 21 | font-weight: bold; 22 | } 23 | 24 | /* Flexbox Media Object */ 25 | .media { 26 | display: -ms-flexbox; 27 | display: flex; 28 | -ms-flex-align: start; 29 | align-items: flex-start; 30 | } 31 | 32 | .media-figure { 33 | margin-right: 1em; 34 | } 35 | 36 | .media-body { 37 | -ms-flex: 1; 38 | flex: 1; 39 | } 40 | /* End Flexbox Media Object */ 41 | 42 | h2 { 43 | font-size: 1.5em; 44 | } 45 | 46 | .media-body h3 { 47 | margin-bottom: 0; 48 | letter-spacing: 0.2em; 49 | } 50 | 51 | .intro, .content { 52 | max-width: 50rem; 53 | margin-left: auto; 54 | margin-right: auto; 55 | } 56 | 57 | .intro { 58 | font-size: 1.25em; 59 | } 60 | 61 | .intro p + p { 62 | margin-top: -1em; 63 | } 64 | 65 | .not-a-technologist { 66 | text-align: center; 67 | } 68 | 69 | .not-a-technologist a { 70 | border-color: #ff5644; 71 | color: #ff5644; 72 | } 73 | 74 | .section-title { 75 | margin-bottom: 0.5em; 76 | } 77 | 78 | .item-logo { 79 | width: 100px; 80 | } 81 | 82 | .item p { 83 | margin-bottom: 0.5em; 84 | } 85 | 86 | .item-container hr { 87 | margin: 1.5em 0; 88 | } 89 | 90 | .copyright { 91 | text-align: center; 92 | } 93 | 94 | .hidden { 95 | display: none; 96 | } 97 | 98 | .section-filter-picker { 99 | color: #666; 100 | margin-top: -1.5em; 101 | text-align: right; 102 | } 103 | .section-filter-picker select { 104 | border: 1px solid #ccc; 105 | border-radius: 5px; 106 | display: inline-block; 107 | height: 2em; 108 | margin-bottom: 2em; 109 | max-width: 100%; 110 | padding: 0 1em; 111 | width: auto; 112 | } 113 | 114 | @media only screen and (min-width: 600px) { 115 | .section-filter-picker select { 116 | margin-left: 1em; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /public/css/phantom.css: -------------------------------------------------------------------------------- 1 | /* 2 | Edited (light) version of Phantom by HTML5 UP 3 | html5up.net | @ajlkn 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | /* Reset */ 7 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { 8 | margin: 0; 9 | padding: 0; 10 | border: 0; 11 | font-size: 100%; 12 | font: inherit; 13 | vertical-align: baseline; } 14 | 15 | article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { 16 | display: block; } 17 | 18 | body { 19 | line-height: 1; } 20 | 21 | ol, ul { 22 | list-style: none; } 23 | 24 | blockquote, q { 25 | quotes: none; } 26 | 27 | blockquote:before, blockquote:after, q:before, q:after { 28 | content: ''; 29 | content: none; } 30 | 31 | table { 32 | border-collapse: collapse; 33 | border-spacing: 0; } 34 | 35 | body { 36 | -webkit-text-size-adjust: none; } 37 | 38 | /* Box Model */ 39 | *, *:before, *:after { 40 | box-sizing: border-box; } 41 | 42 | /* Basic */ 43 | @-ms-viewport { 44 | width: device-width; } 45 | 46 | body { 47 | -ms-overflow-style: scrollbar; } 48 | 49 | @media screen and (max-width: 480px) { 50 | html, body { 51 | min-width: 320px; } } 52 | 53 | body { 54 | background: #fff; } 55 | 56 | /* Type */ 57 | body, input, select, textarea { 58 | color: #585858; 59 | // font-family: "Source Sans Pro", Helvetica, sans-serif; 60 | font-size: 16pt; 61 | font-weight: 300; 62 | line-height: 1.75; } 63 | @media screen and (max-width: 1680px) { 64 | body, input, select, textarea { 65 | font-size: 14pt; } } 66 | @media screen and (max-width: 1280px) { 67 | body, input, select, textarea { 68 | font-size: 12pt; } } 69 | 70 | a { 71 | transition: border-bottom-color 0.2s ease, color 0.2s ease; 72 | text-decoration: none; 73 | color: #585858; 74 | border-bottom: dotted 1px rgba(88, 88, 88, 0.5); } 75 | a:hover { 76 | border-bottom-color: transparent; 77 | color: #f2849e !important; } 78 | 79 | strong, b { 80 | font-weight: 900; } 81 | 82 | em, i { 83 | font-style: italic; } 84 | 85 | p { 86 | margin: 0 0 2em 0; } 87 | 88 | h1 { 89 | font-size: 2.75em; 90 | font-weight: 700; 91 | line-height: 1.3; 92 | margin: 0 0 1em 0; 93 | letter-spacing: -0.035em; } 94 | h1 a { 95 | color: inherit; } 96 | @media screen and (max-width: 736px) { 97 | h1 { 98 | font-size: 2em; 99 | margin: 0 0 1em 0; } } 100 | @media screen and (max-width: 360px) { 101 | h1 { 102 | font-size: 1.75em; } } 103 | 104 | h2, h3, h4, h5, h6 { 105 | font-weight: 900; 106 | line-height: 1.5; 107 | margin: 0 0 2em 0; 108 | text-transform: uppercase; 109 | letter-spacing: 0.35em; } 110 | h2 a, h3 a, h4 a, h5 a, h6 a { 111 | color: inherit; } 112 | 113 | h2 { 114 | font-size: 1.1em; } 115 | 116 | h3 { 117 | font-size: 1em; } 118 | 119 | h4 { 120 | font-size: 0.8em; } 121 | 122 | h5 { 123 | font-size: 0.8em; } 124 | 125 | h6 { 126 | font-size: 0.8em; } 127 | 128 | @media screen and (max-width: 736px) { 129 | h2 { 130 | font-size: 1em; } 131 | h3 { 132 | font-size: 0.8em; } } 133 | 134 | sub { 135 | font-size: 0.8em; 136 | position: relative; 137 | top: 0.5em; } 138 | 139 | sup { 140 | font-size: 0.8em; 141 | position: relative; 142 | top: -0.5em; } 143 | 144 | blockquote { 145 | border-left: solid 4px #c9c9c9; 146 | font-style: italic; 147 | margin: 0 0 2em 0; 148 | padding: 0.5em 0 0.5em 2em; } 149 | 150 | code { 151 | background: rgba(144, 144, 144, 0.075); 152 | border-radius: 4px; 153 | border: solid 1px #c9c9c9; 154 | font-family: "Courier New", monospace; 155 | font-size: 0.9em; 156 | margin: 0 0.25em; 157 | padding: 0.25em 0.65em; } 158 | 159 | pre { 160 | -webkit-overflow-scrolling: touch; 161 | font-family: "Courier New", monospace; 162 | font-size: 0.9em; 163 | margin: 0 0 2em 0; } 164 | pre code { 165 | display: block; 166 | line-height: 1.75; 167 | padding: 1em 1.5em; 168 | overflow-x: auto; } 169 | 170 | hr { 171 | border: 0; 172 | border-bottom: solid 1px #c9c9c9; 173 | margin: 2em 0; } 174 | hr.major { 175 | margin: 3em 0; } 176 | 177 | /* Section/Article */ 178 | section.special, article.special { 179 | text-align: center; } 180 | 181 | header p { 182 | margin-top: -1em; } 183 | 184 | @media screen and (max-width: 736px) { 185 | header p { 186 | margin-top: 0; } } 187 | 188 | /* List */ 189 | ol { 190 | list-style: decimal; 191 | margin: 0 0 2em 0; 192 | padding-left: 1.25em; } 193 | ol li { 194 | padding-left: 0.25em; } 195 | 196 | ul { 197 | list-style: disc; 198 | margin: 0 0 2em 0; 199 | padding-left: 1em; } 200 | ul li { 201 | padding-left: 0.5em; } 202 | 203 | input[type="text"], 204 | input[type="password"], 205 | input[type="email"], 206 | input[type="tel"], 207 | select, 208 | textarea { 209 | -moz-appearance: none; 210 | -webkit-appearance: none; 211 | -ms-appearance: none; 212 | appearance: none; 213 | background-color: transparent; 214 | border: none; 215 | border-radius: 0; 216 | border-bottom: solid 1px #c9c9c9; 217 | color: inherit; 218 | display: block; 219 | outline: 0; 220 | padding: 0; 221 | text-decoration: none; 222 | width: 100%; } 223 | input[type="text"]:invalid, 224 | input[type="password"]:invalid, 225 | input[type="email"]:invalid, 226 | input[type="tel"]:invalid, 227 | select:invalid, 228 | textarea:invalid { 229 | box-shadow: none; } 230 | input[type="text"]:focus, 231 | input[type="password"]:focus, 232 | input[type="email"]:focus, 233 | input[type="tel"]:focus, 234 | select:focus, 235 | textarea:focus { 236 | border-bottom-color: #f2849e; 237 | box-shadow: inset 0 -1px 0 0 #f2849e; } 238 | 239 | /* Button */ 240 | input[type="submit"], 241 | input[type="reset"], 242 | input[type="button"], 243 | button, 244 | .button { 245 | -moz-appearance: none; 246 | -webkit-appearance: none; 247 | -ms-appearance: none; 248 | appearance: none; 249 | transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out, box-shadow 0.2s ease-in-out; 250 | background-color: transparent; 251 | border-radius: 4px; 252 | border: 0; 253 | box-shadow: inset 0 0 0 2px #585858; 254 | color: #585858 !important; 255 | cursor: pointer; 256 | display: inline-block; 257 | font-size: 0.8em; 258 | font-weight: 900; 259 | height: 3.5em; 260 | letter-spacing: 0.35em; 261 | line-height: 3.45em; 262 | overflow: hidden; 263 | padding: 0 1.25em 0 1.6em; 264 | text-align: center; 265 | text-decoration: none; 266 | text-overflow: ellipsis; 267 | text-transform: uppercase; 268 | white-space: nowrap; } 269 | input[type="submit"]:hover, 270 | input[type="reset"]:hover, 271 | input[type="button"]:hover, 272 | button:hover, 273 | .button:hover { 274 | color: #f2849e !important; 275 | box-shadow: inset 0 0 0 2px #f2849e; } 276 | input[type="submit"]:active, 277 | input[type="reset"]:active, 278 | input[type="button"]:active, 279 | button:active, 280 | .button:active { 281 | background-color: rgba(242, 132, 158, 0.1); } 282 | input[type="submit"].small, 283 | input[type="reset"].small, 284 | input[type="button"].small, 285 | button.small, 286 | .button.small { 287 | font-size: 0.6em; } 288 | input[type="submit"].big, 289 | input[type="reset"].big, 290 | input[type="button"].big, 291 | button.big, 292 | .button.big { 293 | font-size: 1em; } 294 | input[type="submit"].special, 295 | input[type="reset"].special, 296 | input[type="button"].special, 297 | button.special, 298 | .button.special { 299 | box-shadow: none; 300 | background-color: #585858; 301 | color: #ffffff !important; } 302 | input[type="submit"].special:hover, 303 | input[type="reset"].special:hover, 304 | input[type="button"].special:hover, 305 | button.special:hover, 306 | .button.special:hover { 307 | background-color: #f2849e; } 308 | input[type="submit"].special:active, 309 | input[type="reset"].special:active, 310 | input[type="button"].special:active, 311 | button.special:active, 312 | .button.special:active { 313 | background-color: #ee5f81; } 314 | input[type="submit"].disabled, input[type="submit"]:disabled, 315 | input[type="reset"].disabled, 316 | input[type="reset"]:disabled, 317 | input[type="button"].disabled, 318 | input[type="button"]:disabled, 319 | button.disabled, 320 | button:disabled, 321 | .button.disabled, 322 | .button:disabled { 323 | -moz-pointer-events: none; 324 | -webkit-pointer-events: none; 325 | -ms-pointer-events: none; 326 | pointer-events: none; 327 | opacity: 0.25; } 328 | 329 | /* Header */ 330 | #header { 331 | padding: 8em 0 0.1em 0 ; } 332 | #header .logo { 333 | display: block; 334 | border-bottom: 0; 335 | color: inherit; 336 | font-weight: 900; 337 | letter-spacing: 0.35em; 338 | margin: 0 0 2.5em 0; 339 | text-decoration: none; 340 | text-transform: uppercase; 341 | display: inline-block; } 342 | #header .logo > * { 343 | display: inline-block; 344 | vertical-align: middle; } 345 | #header .logo .symbol { 346 | margin-right: 0.65em; } 347 | #header .logo .symbol img { 348 | display: block; 349 | width: 2em; 350 | height: 2em; } 351 | 352 | @media screen and (max-width: 736px) { 353 | #header { 354 | padding: 4em 0 0.1em 0 ; } } 355 | 356 | /* Main */ 357 | #main { 358 | padding: 0em 0 6em 0 ; } 359 | @media screen and (max-width: 736px) { 360 | #main { 361 | padding: 0em 0 4em 0 ; } } 362 | 363 | /* Footer */ 364 | #footer { 365 | padding: 5em 0 6em 0 ; 366 | background-color: #f6f6f6; } 367 | #footer > .inner { 368 | display: -moz-flex; 369 | display: -ms-flex; 370 | display: -ms-flexbox; 371 | display: flex; 372 | -ms-flex-wrap: wrap; 373 | flex-wrap: wrap; 374 | -moz-flex-direction: row; 375 | -ms-flex-direction: row; 376 | flex-direction: row; } 377 | #footer > .inner > * > :last-child { 378 | margin-bottom: 0; } 379 | #footer > .inner section:nth-child(1) { 380 | width: calc(66% - 2.5em); 381 | margin-right: 2.5em; } 382 | #footer > .inner section:nth-child(2) { 383 | width: calc(33% - 2.5em); 384 | margin-left: 2.5em; } 385 | #footer > .inner .copyright { 386 | width: 100%; 387 | padding: 0; 388 | margin-top: 5em; 389 | list-style: none; 390 | font-size: 0.8em; 391 | color: rgba(88, 88, 88, 0.5); } 392 | #footer > .inner .copyright a { 393 | color: inherit; } 394 | #footer > .inner .copyright li { 395 | display: inline-block; 396 | border-left: solid 1px rgba(88, 88, 88, 0.15); 397 | line-height: 1; 398 | padding: 0 0 0 1em; 399 | margin: 0 0 0 1em; } 400 | #footer > .inner .copyright li:first-child { 401 | border-left: 0; 402 | padding-left: 0; 403 | margin-left: 0; } 404 | @media screen and (max-width: 1280px) { 405 | #footer { 406 | padding: 5em 0 3em 0 ; } 407 | #footer > .inner section:nth-child(1) { 408 | width: calc(66% - 1.25em); 409 | margin-right: 1.25em; } 410 | #footer > .inner section:nth-child(2) { 411 | width: calc(33% - 1.25em); 412 | margin-left: 1.25em; } } 413 | @media screen and (max-width: 980px) { 414 | #footer > .inner section:nth-child(1) { 415 | width: 66%; 416 | margin-right: 0; } 417 | #footer > .inner section:nth-child(2) { 418 | width: calc(33% - 2.5em); 419 | margin-left: 2.5em; } } 420 | @media screen and (max-width: 736px) { 421 | #footer { 422 | padding: 3em 0 1em 0 ; } 423 | #footer > .inner { 424 | -moz-flex-direction: column; 425 | -ms-flex-direction: column; 426 | flex-direction: column; } 427 | #footer > .inner section:nth-child(1) { 428 | width: 100%; 429 | margin-right: 0; 430 | margin: 3em 0 0 0; } 431 | #footer > .inner section:nth-child(2) { 432 | -moz-order: -1; 433 | -ms-order: -1; 434 | -ms-flex-order: -1; 435 | order: -1; 436 | width: 100%; 437 | margin-left: 0; } 438 | #footer > .inner .copyright { 439 | margin-top: 3em; } } 440 | @media screen and (max-width: 480px) { 441 | #footer > .inner .copyright { 442 | margin-top: 3em; } 443 | #footer > .inner .copyright li { 444 | border-left: 0; 445 | padding-left: 0; 446 | margin: 0.75em 0 0 0; 447 | display: block; 448 | line-height: inherit; } 449 | #footer > .inner .copyright li:first-child { 450 | margin-top: 0; } } 451 | 452 | /* Wrapper */ 453 | #wrapper > * > .inner { 454 | width: 100%; 455 | max-width: 68em; 456 | margin: 0 auto; 457 | padding: 0 2.5em; } 458 | @media screen and (max-width: 736px) { 459 | #wrapper > * > .inner { 460 | padding: 0 1.25em; } } 461 | -------------------------------------------------------------------------------- /public/js/app.js: -------------------------------------------------------------------------------- 1 | /** Build and handle picker for projects */ 2 | const $projects = document.querySelectorAll('[data-skills]') 3 | const $projectsPicker = document.getElementById('project-skill-picker') 4 | 5 | buildSkillOptions() 6 | 7 | $projectsPicker.addEventListener('change', () => { 8 | showProjectsBySkill($projectsPicker.options[$projectsPicker.selectedIndex].value) 9 | }) 10 | 11 | function buildSkillOptions() 12 | { 13 | let skills = [] 14 | 15 | forEach($projects, (project) => { 16 | skills = skills.concat( 17 | $projects[project].getAttribute('data-skills').trim().split(/\s*,\s*/) 18 | ) 19 | }) 20 | 21 | // de-duplicate 22 | skills = skills.filter((elem, index, self) => { 23 | return index == self.indexOf(elem); 24 | }).sort() 25 | 26 | let options = '' 27 | 28 | for (skill in skills) { 29 | options += '' 30 | } 31 | 32 | $projectsPicker.insertAdjacentHTML('beforeend', options) 33 | } 34 | 35 | function showProjectsBySkill(skill) 36 | { 37 | if (skill == '') return removeClass('hidden', $projects) 38 | 39 | addClass('hidden', $projects) 40 | removeClass('hidden', filterBySkill(skill, $projects)) 41 | } 42 | 43 | function filterBySkill(skill, els) 44 | { 45 | let returnEls = [] 46 | 47 | forEach(els, (el) => { 48 | let thisSkills = els[el].getAttribute('data-skills') 49 | if (thisSkills.includes(skill)) returnEls.push(els[el]) 50 | }) 51 | 52 | return returnEls 53 | } 54 | 55 | 56 | /** Build and handle picker for tools */ 57 | const $tools = document.querySelectorAll('[data-tool-category]'); 58 | const $toolsPicker = document.getElementById('tool-category-picker') 59 | 60 | const categoryTranslator = { 61 | 'cta': 'Calls to Action', 62 | 'learn': 'Learn About Politics and Resistance', 63 | 'miscellaneous': 'Miscellaneous', 64 | 'pledge': 'Pledge to Resist', 65 | 'protest': 'Protests and Tools for Protest', 66 | 'access': 'Receiving or Providing Help in Voting', 67 | 'call': 'Tools for Calling Representatives', 68 | 'events': 'Tools for Finding Resistance Events', 69 | 'elections': 'Tools for Understanding and Influencing Elections', 70 | 'legislation': 'Understanding and Influencing Legislation' 71 | } 72 | 73 | buildCategoryOptions() 74 | 75 | $toolsPicker.addEventListener('change', () => { 76 | showToolsByCategory($toolsPicker.options[$toolsPicker.selectedIndex].value) 77 | }) 78 | 79 | function buildCategoryOptions() 80 | { 81 | let options = '' 82 | 83 | for (categorySlug in categoryTranslator) { 84 | options += '' 85 | } 86 | 87 | $toolsPicker.insertAdjacentHTML('beforeend', options) 88 | } 89 | 90 | function translateCategory(categorySlug) 91 | { 92 | if (categorySlug in categoryTranslator) return categoryTranslator[categorySlug] 93 | 94 | return categorySlug 95 | } 96 | 97 | function showToolsByCategory(category) 98 | { 99 | if (category == '') return removeClass('hidden', $tools) 100 | 101 | addClass('hidden', $tools) 102 | removeClass('hidden', filterByCategory(category, $tools)) 103 | } 104 | 105 | function removeClass(theclass, els) 106 | { 107 | forEach(els, (el) => { 108 | els[el].classList.remove(theclass) 109 | }) 110 | } 111 | 112 | function addClass(theclass, els) 113 | { 114 | forEach(els, (el) => { 115 | els[el].classList.add(theclass) 116 | }) 117 | } 118 | 119 | function filterByCategory(category, els) 120 | { 121 | let returnEls = [] 122 | 123 | forEach(els, (el) => { 124 | let thisCat = els[el].getAttribute('data-tool-category') 125 | if (thisCat == category) returnEls.push(els[el]) 126 | }) 127 | 128 | return returnEls 129 | } 130 | 131 | function forEach(array, callback, scope) 132 | { 133 | for (var i = 0; i < array.length; i++) { 134 | callback.call(scope, i, array[i]) 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | // init project 2 | const dotenv = require('dotenv') 3 | dotenv.load() 4 | 5 | const express = require('express') 6 | const app = express() 7 | const exphbs = require('express-handlebars'); 8 | 9 | app.use(express.static('public')) 10 | 11 | app.engine('handlebars', exphbs({defaultLayout: 'main'})); 12 | app.set('view engine', 'handlebars'); 13 | 14 | const index = require('./src/controller/index') 15 | 16 | app.get('/', index.index) 17 | 18 | app.get('/add', function (request, response) { 19 | response.sendFile(__dirname + '/views/add-forms.html') 20 | }) 21 | 22 | // listen for requests :) 23 | const listener = app.listen(process.env.PORT, function () { 24 | console.log('Your app is listening on port ' + listener.address().port) 25 | }) 26 | -------------------------------------------------------------------------------- /src/controller/index.js: -------------------------------------------------------------------------------- 1 | const importer = require('../spreadsheet/importer') 2 | 3 | const index = function index (req, res) { 4 | const orgs = importer.getSheet('orgs') 5 | const projects = importer.getSheet('projects') 6 | const tools = importer.getSheet('tools') 7 | const resources = importer.getSheet('resources') 8 | const dataSources = importer.getSheet('dataSources') 9 | const articles = importer.getSheet('articles') 10 | 11 | Promise.all([orgs, projects, tools, resources, dataSources, articles]).then((output) => { 12 | res.render('index', { 13 | title: 'Index', 14 | // @todo destructuring 15 | orgs: output[0], 16 | projects: output[1], 17 | tools: output[2], 18 | resources: output[3], 19 | dataSources: output[4], 20 | articles: output[5] 21 | }); 22 | }, (reason) => { 23 | res.send('fail: ' + reason) 24 | }) 25 | } 26 | 27 | module.exports = { 28 | index 29 | } 30 | -------------------------------------------------------------------------------- /src/spreadsheet/importer.js: -------------------------------------------------------------------------------- 1 | const GoogleSpreadsheets = require('google-spreadsheets') 2 | const _ = require('lodash') 3 | const Promise = require('promise') 4 | const mcache = require('memory-cache') 5 | 6 | const secondsToCache = 360 7 | 8 | const sheets = { 9 | 'orgs': { 10 | 'number': 0, 11 | 'range': 'R1C1:R99C9' 12 | }, 13 | 'projects': { 14 | 'number': 1, 15 | 'range': 'R1C1:R99C9' 16 | }, 17 | 'tools': { 18 | 'number': 2, 19 | 'range': 'R1C1:R99C6' 20 | }, 21 | 'resources': { 22 | 'number': 3, 23 | 'range': 'R1C1:R99C6' 24 | }, 25 | 'dataSources': { 26 | 'number': 4, 27 | 'range': 'R1C1:R99C5' 28 | }, 29 | 'articles': { 30 | 'number': 5, 31 | 'range': 'R1C1:R99C5' 32 | } 33 | } 34 | 35 | // Get and transform the value of a given sheet 36 | const getSheet = function getSheet(sheetName) { 37 | return new Promise((resolve, reject) => { 38 | if (!(sheetName in sheets)) return reject('Not a valid sheet') 39 | 40 | let cacheKey = 'sheet_' + sheetName 41 | let cacheResponse = mcache.get(cacheKey) 42 | 43 | if (cacheResponse) { 44 | resolve(cacheResponse) 45 | return 46 | } 47 | 48 | GoogleSpreadsheets({ 49 | key: process.env.GOOGLE_SPREADSHEET_ID 50 | }, function(err, spreadsheet) { 51 | if (err) return reject('error loading spreadsheet:' + err) 52 | 53 | const sheet = sheets[sheetName] 54 | 55 | spreadsheet.worksheets[sheet.number].cells({ 56 | range: sheet.range 57 | }, function(err, result) { 58 | let output = transformSheet(result.cells) 59 | mcache.put(cacheKey, output, secondsToCache * 1000) 60 | resolve(output) 61 | }) 62 | }) 63 | }) 64 | } 65 | 66 | // Transform a sheet from Google into a JSON format 67 | function transformSheet(sheetFromGoogle) 68 | { 69 | let headers = _.map(sheetFromGoogle[1], 'value') 70 | delete sheetFromGoogle[1] 71 | 72 | let output = _.map(sheetFromGoogle, (row) => { return makeRow(row, headers) }) 73 | output = _.filter(output, (row) => { return row.approved == 1 }) 74 | output = _.sortBy(output, 'name') 75 | return output 76 | 77 | // for some reason we're getting a lodash wrapper result from this... so temp 78 | // overriding with the return above 79 | return _.chain(sheetFromGoogle) 80 | .map((row) => { return makeRow(row, headers) }) 81 | .filter((row) => { return row.approved == 1 }) 82 | .sortBy('name') 83 | .values() 84 | } 85 | 86 | // Use the headers row to map the values from each row 87 | // to the appropriate JSON object property 88 | function makeRow(row, headers) 89 | { 90 | return decorate(mapRowFromGoogle(row, headers)) 91 | } 92 | 93 | // Map the result from Google sheets to a usable JSON object 94 | function mapRowFromGoogle(row, headers) 95 | { 96 | return _.reduce(headers, (obj, header, index) => { 97 | obj[header] = cell(row, index) 98 | return obj 99 | }, {}) 100 | } 101 | 102 | // Decorate the API result with slug and readable location string 103 | function decorate(row) 104 | { 105 | row.slug = slugify(row.name) 106 | row.location = buildLocationString(row) 107 | 108 | return row 109 | } 110 | 111 | // Convert a string to a slug 112 | function slugify(string) 113 | { 114 | return string.toString().toLowerCase().trim() 115 | .replace(/&/g, '-and-') // Replace & with 'and' 116 | .replace(/[\s\W-]+/g, '-') // Replace spaces, non-word characters and dashes with a single dash (-) 117 | } 118 | 119 | // Get the value of a 1-based cell based on its 0-based index, 120 | // allowing for null values 121 | function cell(row, index) { 122 | return row[index + 1] ? row[index + 1]['value'] : null 123 | } 124 | 125 | // Build a readable location string based on optional location fields 126 | function buildLocationString(item) 127 | { 128 | if (item.locationAddress && item.locationCity && item.locationState) { 129 | return item.locationAddress + ', ' + item.locationCity + ', ' + item.locationState 130 | } 131 | 132 | if (item.locationCity && item.locationState) { 133 | return item.locationCity + ', ' + item.locationState 134 | } 135 | 136 | if (item.locationState) { 137 | return item.locationState 138 | } 139 | 140 | return null 141 | } 142 | 143 | module.exports = { 144 | getSheet 145 | } 146 | -------------------------------------------------------------------------------- /views/add-forms.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tech Forward - Suggest Content 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 | 44 | 45 | 46 |
47 |
48 |

Suggest to Tech Forward

49 | 50 | 58 |
59 |
60 |
61 | 62 | 63 | -------------------------------------------------------------------------------- /views/index.handlebars: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |

Tech organizations & tools working for social progress.

6 |
7 |
8 |

(Not a technologist? Check out the list of tools you can use today!)

9 |

You've probably said it. "I'm a technologist. I know I can work for change the same as everyone—call my senator, donate to the causes that matter, protest. But what can I uniquely do?"

10 |

There are dozens of ways you can get involved; organizations to join, tools to contribute to, and resources to take advantage of. Your favorite missing? Let us know.

11 |
12 |
13 |
14 | 15 | 24 | 25 |
26 | 27 |

28 |

Organizations

29 |

Organizations that bring technologists together to create new tech projects to work for progress.

30 |
31 | 32 | {{#each orgs}} 33 |
34 | 35 | {{#if logo}} 36 | 37 | {{else}} 38 | 39 | {{/if}} 40 | 41 | 42 |
43 |

{{ name }}

44 |

{{ description }}

45 | {{#if location}} 46 |

LOCATION: {{ location }}

47 | {{/if}} 48 | 49 | {{#if joinUrl}} 50 | Join 51 | {{else}} 52 | Join 53 | {{/if}} 54 |
55 |
56 | 57 |
58 | 59 | {{/each}} 60 | 61 |
62 | 63 |

64 |

Projects

65 |

Open source projects that technologists can use or contribute to.

66 | 67 |
68 | Filter projects: 71 |
72 | 73 |
74 | {{#each projects}} 75 |
76 | 77 | {{#if logo}} 78 | 79 | {{else}} 80 | 81 | {{/if}} 82 | 83 | 84 |
85 |

{{ name }}

86 |

{{ description }}

87 | {{#if builtByText}} 88 |

BUILT BY: {{ builtByText }}

89 | {{/if}} 90 | {{#if skills}} 91 |

SKILLS NEEDED: {{ skills }}

92 | {{/if}} 93 |
94 |
95 | 96 | 97 |
98 | {{/each}} 99 |
100 | 101 |

102 |

Resources

103 |

Services or agencies that provide free support to activists & progressive tech work.

104 |
105 | {{#each resources}} 106 |
107 | 108 | {{#if logo}} 109 | 110 | {{else}} 111 | 112 | {{/if}} 113 | 114 | 115 |
116 |

{{ name }}

117 |

{{ description }}

118 | {{# if contact}} 119 |

Contact

120 | {{/if}} 121 |
122 |
123 | 124 |
125 | {{/each}} 126 |
127 | 128 |

129 |

Data Sources

130 |

Open sources of data for use in government/activism-focused applications.

131 |
132 | {{#each dataSources}} 133 |
134 | 135 | {{#if logo}} 136 | 137 | {{else}} 138 | 139 | {{/if}} 140 | 141 | 142 |
143 |

{{ name }}

144 |

{{ description }}

145 |
146 |
147 | 148 |
149 | {{/each}} 150 |
151 | 152 |

153 |

Tools

154 |

Web- or phone-based tools—usable by anyone, powered by tech.

155 | 156 |
157 | Filter tools: 160 |
161 | 162 |
163 | {{#each tools}} 164 |
165 | 166 | {{#if logo}} 167 | 168 | {{else}} 169 | 170 | {{/if}} 171 | 172 | 173 |
174 |

{{ name }}

175 |

{{ description }}

176 | {{#if builtBy}} 177 |

BUILT BY: {{ builtBy.text }}

178 | {{/if}} 179 |
180 |
181 | 182 | 183 |
184 | {{/each}} 185 |
186 | 187 |

188 |

Articles

189 |

Articles written by other technologists about the "how" and "why" of our resistance.

190 |
191 | 192 | {{#each articles}} 193 |
194 |

{{ name }}

195 | By: {{ authorName }} 196 |
197 | {{/each}} 198 | 199 |
200 | 201 |
202 |
203 |
204 | -------------------------------------------------------------------------------- /views/layouts/main.handlebars: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tech Forward 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 | 44 | 45 | {{{body}}} 46 | 47 | 48 | 79 |
80 | 81 | 82 | 90 | 91 | 92 | --------------------------------------------------------------------------------